diff --git a/.appveyor.yml b/.appveyor.yml
index 2be67c5492ff3361893db5dedd11242fc9dba440..58563c5093b2278a0d8b3ad950b881510ec1f13b 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -1,4 +1,4 @@
-image: Previous Visual Studio 2017
+image: Visual Studio 2017
 
 matrix:
   fast_finish: true
@@ -8,35 +8,49 @@ platform:
 
 # http://www.appveyor.com/docs/installed-software
 environment:
-  QTDIR: "C:\\Qt\\5.9\\msvc2017_64"
-  MYCONDA: "C:\\Miniconda3-x64;C:\\Miniconda3-x64\\Scripts;C:\\Miniconda3-x64\\Library\\bin"
-  PATH: "%QTDIR%\\bin;C:\\opt\\local_x64\\lib;%MYCONDA%;%PATH%"
-  PYTHONPATH: "C:\\Miniconda3-x64;C:\\Miniconda3-x64\\Lib;C:\\Miniconda3-x64\\Lib\\site-packages;C:\\Miniconda3-x64\\DLLs"
+  APPVEYOR_RDP_PASSWORD: 7bKajQWvq4uhfpvc!
+  BOOSTDIR: C:\Libraries\boost_1_67_0
+  PYTHONDIR: C:\Python36-x64
+  QTDIR: "C:\\Qt\\5.11\\msvc2017_64"
+  PATH: "%QTDIR%\\bin;%PYTHONDIR%;%PYTHONDIR%\\Scripts;%BOOSTDIR%\\lib64-msvc-14.1;%PATH%"
+  PYTHONPATH: "%PYTHONDIR%;%PYTHONDIR%\\Lib;%PYTHONDIR%\\Lib\\site-packages;%PYTHONDIR%\\DLLs"
+  PYEXE: "%PYTHONDIR%\\python.exe"
+  PYLIB: "%PYTHONDIR%\\libs\\python36.lib"
 build:
   parallel: true
 
 init:  
-- echo "BornAgain init"
+- echo "BornAgain init" %CD% 
 - echo %PATH%
 
 install:
-- cmd: git submodule -q update --init
+- git submodule -q update --init
   
 before_build:
-- echo "BornAgain before_build"
-- echo %PATH%
+- echo "BornAgain before_build" %CD% 
+- python -m pip install --upgrade pip
 - python -m pip install numpy
-- C:\cygwin\bin\wget -q http://apps.jcns.fz-juelich.de/redmine/attachments/download/348/local_x64.zip -O %temp%\local_x64.zip
-- 7z x %temp%\local_x64.zip -oC:\opt > null
+- mkdir C:\projects\deps
+- C:\cygwin\bin\wget -q http://apps.jcns.fz-juelich.de/redmine/attachments/download/456/bornagaindeps_v1.zip -O %temp%\bornagaindeps.zip
+- 7z x %temp%\bornagaindeps.zip -oC:\projects\deps > null
+- set CMAKE_URL="https://cmake.org/files/v3.12/cmake-3.12.4-win64-x64.zip"
+- appveyor DownloadFile %CMAKE_URL% -FileName %temp%\cmake.zip
+- 7z x %temp%\cmake.zip -oC:\projects\deps > nul
+- move C:\projects\deps\cmake-* C:\projects\deps\cmake # Move to a version-agnostic directory
+- set PATH=C:\projects\deps\bornagaindeps\lib;C:\projects\deps\cmake\bin;%PATH%
 
 build_script:
+- echo "BornAgain build_script" %CD% 
+- echo %PATH%
+- echo "PYEXE" %PYEXE% "PYLIB" %PYLIB%
 - mkdir build
 - cd build
-- cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_INCLUDE_PATH=C:/opt/local_x64/include ..
+- cmake --version
+- cmake -G "Visual Studio 15 2017 Win64" -DBOOST_ROOT=%BOOSTDIR% -DPYTHON_LIBRARY=%PYLIB% -DPYTHON_EXECUTABLE=%PYEXE% -DCMAKE_INCLUDE_PATH=C:/projects/deps/bornagaindeps/include ..
 - cmake --build . --config Release
 
 test_script:
-- echo "BornAgain test_script"
+- echo "BornAgain test_script" %CD% 
 - echo %PATH%
 - echo %PYTHONPATH%
 - echo %PYTHONHOME%
@@ -50,3 +64,8 @@ test_script:
         throw "tests failed" 
 
     }
+
+on_failure:
+- appveyor PushArtifact Testing/Temporary/LastTest.log
+#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
+    
diff --git a/CHANGELOG b/CHANGELOG
index 2915ae256c1f003f93b29ba8b22d87e0229f0f06..053f25108ad55a57edb60516a3b32a074b612f6e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,71 @@
+BornAgain-1.14.0, released 2018.12.07
+  > No API changes
+  > Summary:
+    1) New instrument: depth probe
+    2) Futher expansion of 3D View
+    3) Import data assistant for 1D data
+    4) Update of fitting tutorials on our documentation website
+    5) Allow fitting of material properties
+    6) Enable linked parameters in GUI ParticleDistribution
+    7) Numerous bugfixes.
+
+  * Bug #2116: Provide valid editing for fit parameters in GUI
+  * Bug #2167: Application crash on attempt to load txt.gz file from GUI
+  * Bug #2173: Inconsistent behavior of dock widgets between sample view and job view
+  * Bug #2179: Saving and loading txt image in GUI causes rotation
+  * Bug #2181: Loading a project file in the GUI overwrites number of threads
+  * Bug #2183: Export to python doesn't add extension to file name
+  * Bug #2184: Tuning widget disappears from simulation when "submit only" option is chosen
+  * Bug #2189: Real time view shows alien tree on jobItem delete
+  * Bug #2198: BornAgain GUI on certain Win10 stays collapsed on taskbar
+  * Bug #2200: Trapezoid distribution generates edge values with zero probability
+  * Bug #2213: Unit tests crashing if user system contains own googletest library in LD_LIBRARY_PATH
+  * Bug #2214: GUI crash when deleting connection
+  * Bug #2217: GUI crash on instrument adjustment for 1D data
+  * Bug #2219: Appveyor build crash during unit text execution
+  * Bug #2228: GUI: 1D data loader does not threat 'fixed width' columns correctly
+  * Bug #2231: Reflectivity: strange behaviour at wavelength distribution
+  * Bug #2235: Restore automatic linking of user data to instrument in Simulation tab
+  * Bug #2236: GUI: Fitting failure on some minimization algorithms
+  * Bug #2237: GUI: stop button in fitting panel does not work
+  * Bug #2239: Crash on load of any saved project
+  * Bug #2243: Instrument id is not updated when it is copied to job item
+  * Bug #2245: Crash when running simulation with missing instrument
+  * Bug #2249: Crash on fitting SpecularInstrument/Beam/Polarization/X, Y, Z
+  * Feature #1019: Extend GUI ParticleDistribution with linked parameters
+  * Feature #2084: 3D view: implement mesocrystal
+  * Feature #2102: GUI: switch fitting in GUI from FitSuite to FitObjective
+  * Feature #2138: 3D view: side/top view switch should take in the account size of the sample
+  * Feature #2141: Allow for SLD fitting in GUI
+  * Feature #2142: Allow material tuning in real time view
+  * Feature #2147: Functionality improvements for the new fitting engine
+  * Feature #2154: Observations made during GISAS 2018 school at Bayreuth
+  * Feature #2156: Implement finite crystals
+  * Feature #2177: Employ PointwiseAxis in the GUI for SpecularSimulations
+  * Feature #2190: Provide download statistic for BornAgain web site
+  * Feature #2193: Import order and priority
+  * Feature #2194: Handle native coordinates and units from imported user data in RealDataItem and during instrument linking
+  * Feature #2195: Necessary amendments to ImportDataAssistant
+  * Feature #2196: Provide proper cleanup of OpenGL resources on parent widget change
+  * Feature #2199: Expand txt-file saving to 1D data
+  * Feature #2201: Remove quotation marks around 'Experimental' in the plotting of fits
+  * Feature #2207: Allow multiplying/dividing data columns by constant factor in CsvImportAssistant
+  * Feature #2208: Update all fitting examples to the new fitting mechanism.
+  * Feature #2218: Find an intelligent way to handle repeating values in the coordinate vector (reflectivity)
+  * Feature #2222: Allow scientific notation in tuning parameter tree
+  * Feature #2224: Investigate and implement azimuthal smearing of peak shapes
+  * Feature #2225: GUI: implement depth probe instrument
+  * Feature #2246: GUI: provide possibility to select intensity and residual function type in Minimizer settings
+  * Feature #2247: Update Yosemite vagrant box
+  * Documentation #2040: Website: update all fitting tutorials and Python examples to the new fitting mechanism.
+  * Documentation #2175: Website: provide date and navigation element for news page
+  * Documentation #2178: Website: add screenshot of 3D view to gallery
+  * Documentation #2186: Correct formula for exponential distribution in manual
+  * Documentation #2233: Update manual before release
+  * Refactoring #1486: GUI: refactor SampleView
+  * Refactoring #2137: Import data assistant minor changes
+  * Testing #2220: Change unit test run order
+
 BornAgain-1.13.0, released 2018.10.05
   > API changes
     1) Python: Switch from FitSuite to FitObjective (FitSuite is deprecated now)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f18b17a893c29f21b0dffad67c0f8f0b4ca7a490..f05c2d9442f54ed940e4ecda71cb6803e5158fbb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,11 +4,6 @@
 
 cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
 
-if(APPLE)
-if(POLICY CMP0025)
-    cmake_policy(SET CMP0025 NEW)
-endif()
-endif()
 
 set(CMAKE_MODULE_PATH
     ${CMAKE_SOURCE_DIR}/cmake/generic/modules
@@ -56,7 +51,6 @@ endif()
 # include CMake macros and functions
 include(GetFilenameComponent) # overwrite CMake command
 include(SearchInstalledSoftware)
-include(ThirdPartyLibUtilities)
 include(CheckCompiler)
 if(ZERO_TOLERANCE)
     if(BORNAGAIN_USE_PYTHON3)
@@ -65,6 +59,7 @@ if(ZERO_TOLERANCE)
     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wfatal-errors")
 endif()
 include(BornAgainConfiguration)
+include(BornAgainPolicy)
 include(GeneratePythonDocs)
 include(PyExamplesLineLength)
 include(CheckCode)
@@ -87,21 +82,29 @@ endif()
 if(BORNAGAIN_MANPAGE)
     add_subdirectory(Doc/man)
 endif()
+
 add_subdirectory(ThirdParty/common)
 add_subdirectory(ThirdParty/Fit)
 add_subdirectory(Fit)
+add_subdirectory(Tests/UnitTests/Fit)
+
 add_subdirectory(ThirdParty/Core)
 add_subdirectory(Core)
+add_subdirectory(Tests/UnitTests/Core)
+add_subdirectory(Tests/UnitTests/Numeric)
+
 if(BORNAGAIN_GUI)
     include(SearchQt)
     add_subdirectory(ThirdParty/GUI)
     add_subdirectory(GUI)
+    add_subdirectory(Tests/UnitTests/GUI)
 endif()
 
-add_subdirectory(Tests/UnitTests)
-add_subdirectory(Tests/Functional) # functional tests (ctest)
+# functional tests (ctest)
+add_subdirectory(Tests/Functional)
 
-add_subdirectory(cmake/bornagain) # trick to print an after-install message
+# after-install message
+add_subdirectory(cmake/bornagain)
 
 # make package targets
 include(BornAgainCPack)
diff --git a/Core/Aggregate/FTDistributions1D.cpp b/Core/Aggregate/FTDistributions1D.cpp
index 29e27983c69a2465a77a991a911261a3f9c64681..1c271153e055876260bd55b8520346c14b2db152 100644
--- a/Core/Aggregate/FTDistributions1D.cpp
+++ b/Core/Aggregate/FTDistributions1D.cpp
@@ -20,6 +20,7 @@
 #include "MathConstants.h"
 #include "RealParameter.h"
 #include <limits>
+#include "Exceptions.h"
 
 void IFTDistribution1D::init_parameters()
 {
@@ -34,6 +35,11 @@ FTDistribution1DCauchy::FTDistribution1DCauchy(double omega)
     init_parameters();
 }
 
+std::unique_ptr<IDistribution1DSampler> FTDistribution1DCauchy::createSampler() const
+{
+    return std::make_unique<Distribution1DCauchySampler>(1/m_omega);
+}
+
 FTDistribution1DCauchy* FTDistribution1DCauchy::clone() const
 {
     return new FTDistribution1DCauchy(m_omega);
@@ -52,6 +58,11 @@ FTDistribution1DGauss::FTDistribution1DGauss(double omega)
     init_parameters();
 }
 
+std::unique_ptr<IDistribution1DSampler> FTDistribution1DGauss::createSampler() const
+{
+    return std::make_unique<Distribution1DGaussSampler>(0.0, m_omega);
+}
+
 FTDistribution1DGauss* FTDistribution1DGauss::clone() const
 {
     return new FTDistribution1DGauss(m_omega);
@@ -70,6 +81,11 @@ FTDistribution1DGate::FTDistribution1DGate(double omega)
     init_parameters();
 }
 
+std::unique_ptr<IDistribution1DSampler> FTDistribution1DGate::createSampler() const
+{
+    return std::make_unique<Distribution1DGateSampler>(-m_omega, m_omega);
+}
+
 FTDistribution1DGate* FTDistribution1DGate::clone() const
 {
     return new FTDistribution1DGate(m_omega);
@@ -87,6 +103,11 @@ FTDistribution1DTriangle::FTDistribution1DTriangle(double omega)
     init_parameters();
 }
 
+std::unique_ptr<IDistribution1DSampler> FTDistribution1DTriangle::createSampler() const
+{
+    return std::make_unique<Distribution1DTriangleSampler>(m_omega);
+}
+
 FTDistribution1DTriangle* FTDistribution1DTriangle::clone() const
 {
     return new FTDistribution1DTriangle(m_omega);
@@ -105,6 +126,11 @@ FTDistribution1DCosine::FTDistribution1DCosine(double omega)
     init_parameters();
 }
 
+std::unique_ptr<IDistribution1DSampler> FTDistribution1DCosine::createSampler() const
+{
+    return std::make_unique<Distribution1DCosineSampler>(m_omega);
+}
+
 FTDistribution1DCosine* FTDistribution1DCosine::clone() const
 {
     return new FTDistribution1DCosine(m_omega);
@@ -127,6 +153,16 @@ FTDistribution1DVoigt::FTDistribution1DVoigt(double omega, double eta)
     registerParameter(BornAgain::Eta, &m_eta);
 }
 
+std::unique_ptr<IDistribution1DSampler> FTDistribution1DVoigt::createSampler() const
+{
+    // TODO Need to implement 1D Voigt
+
+    std::ostringstream ostr;
+    ostr << "FTDistribution1DVoigt::createSampler() -> Error in class initialization";
+    ostr << "\n\n Has not been implemented yet...stay tuned!";
+    throw Exceptions::ClassInitializationException(ostr.str());
+}
+
 FTDistribution1DVoigt* FTDistribution1DVoigt::clone() const
 {
     return new FTDistribution1DVoigt(m_omega, m_eta);
diff --git a/Core/Aggregate/FTDistributions1D.h b/Core/Aggregate/FTDistributions1D.h
index 25bc6f999836e6c5d8f00a87c189cdc07b0e1217..eca6d6c4f7f1c145c88575bff5233da8028c62da 100644
--- a/Core/Aggregate/FTDistributions1D.h
+++ b/Core/Aggregate/FTDistributions1D.h
@@ -17,6 +17,7 @@
 
 #include "ICloneable.h"
 #include "INode.h"
+#include "IDistribution1DSampler.h"
 
 //! Interface for a one-dimensional distribution, with normalization adjusted so that
 //! the Fourier transform evaluate(q) is a decay function that starts at evaluate(0)=1.
@@ -38,6 +39,10 @@ public:
     void setOmega(double omega) { m_omega = omega; }
     double omega() const { return m_omega; }
 
+#ifndef SWIG
+    virtual std::unique_ptr<IDistribution1DSampler> createSampler() const=0;
+#endif
+
 protected:
     void init_parameters();
     double m_omega;
@@ -56,6 +61,9 @@ public:
     FTDistribution1DCauchy* clone() const final;
     void accept(INodeVisitor* visitor) const final { visitor->visit(this); }
     double evaluate(double q) const final;
+#ifndef SWIG
+    std::unique_ptr<IDistribution1DSampler> createSampler() const final;
+#endif
 };
 
 
@@ -71,6 +79,9 @@ public:
     FTDistribution1DGauss* clone() const final;
     void accept(INodeVisitor* visitor) const final { visitor->visit(this); }
     double evaluate(double q) const final;
+#ifndef SWIG
+    std::unique_ptr<IDistribution1DSampler> createSampler() const final;
+#endif
 };
 
 
@@ -86,6 +97,9 @@ public:
     FTDistribution1DGate* clone() const final;
     void accept(INodeVisitor* visitor) const final { visitor->visit(this); }
     double evaluate(double q) const final;
+#ifndef SWIG
+    std::unique_ptr<IDistribution1DSampler> createSampler() const final;
+#endif
 };
 
 
@@ -101,6 +115,9 @@ public:
     FTDistribution1DTriangle* clone() const final;
     void accept(INodeVisitor* visitor) const final { visitor->visit(this); }
     double evaluate(double q) const final;
+#ifndef SWIG
+    std::unique_ptr<IDistribution1DSampler> createSampler() const final;
+#endif
 };
 
 
@@ -117,6 +134,9 @@ public:
     FTDistribution1DCosine* clone() const final;
     void accept(INodeVisitor* visitor) const final { visitor->visit(this); }
     double evaluate(double q) const final;
+#ifndef SWIG
+    std::unique_ptr<IDistribution1DSampler> createSampler() const final;
+#endif
 };
 
 
@@ -136,7 +156,11 @@ public:
     FTDistribution1DVoigt* clone() const final;
     void accept(INodeVisitor* visitor) const final { visitor->visit(this); }
     double evaluate(double q) const final;
-    double eta() const { return m_eta;}
+    double eta() const { return m_eta;}    
+#ifndef SWIG
+    std::unique_ptr<IDistribution1DSampler> createSampler() const final;
+#endif
+
 protected:
     double m_eta;
 };
diff --git a/Core/Aggregate/FTDistributions2D.cpp b/Core/Aggregate/FTDistributions2D.cpp
index c4d91d568533a70785df2127f982ff98784f0eaf..795c515434ea5c4d20896ca48e455c0ada0ca60c 100644
--- a/Core/Aggregate/FTDistributions2D.cpp
+++ b/Core/Aggregate/FTDistributions2D.cpp
@@ -20,6 +20,7 @@
 #include "MathConstants.h"
 #include "RealParameter.h"
 #include <limits>
+#include "Exceptions.h"
 
 //! Constructor of two-dimensional probability distribution.
 //! @param omega_x: half-width of the distribution along its x-axis in nanometers
@@ -71,6 +72,11 @@ double FTDistribution2DCauchy::evaluate(double qx, double qy) const
     return std::pow(1.0 + sumsq(qx, qy), -1.5);
 }
 
+std::unique_ptr<IDistribution2DSampler> FTDistribution2DCauchy::createSampler() const
+{
+    return std::make_unique<Distribution2DCauchySampler>(m_omega_x, m_omega_y);
+}
+
 FTDistribution2DGauss::FTDistribution2DGauss(double omega_x, double omega_y, double gamma)
     : IFTDistribution2D(omega_x, omega_y, gamma)
 {
@@ -88,6 +94,11 @@ double FTDistribution2DGauss::evaluate(double qx, double qy) const
     return std::exp(-sumsq(qx, qy) / 2);
 }
 
+std::unique_ptr<IDistribution2DSampler> FTDistribution2DGauss::createSampler() const
+{
+    return std::make_unique<Distribution2DGaussSampler>(m_omega_x, m_omega_y);
+}
+
 FTDistribution2DGate::FTDistribution2DGate(double omega_x, double omega_y, double gamma)
     : IFTDistribution2D(omega_x, omega_y, gamma)
 {
@@ -106,6 +117,11 @@ double FTDistribution2DGate::evaluate(double qx, double qy) const
     return MathFunctions::Bessel_J1c(scaled_q) * 2.0;
 }
 
+std::unique_ptr<IDistribution2DSampler> FTDistribution2DGate::createSampler() const
+{
+    return std::make_unique<Distribution2DGateSampler>(m_omega_x, m_omega_y);
+}
+
 FTDistribution2DCone::FTDistribution2DCone(double omega_x, double omega_y, double gamma)
     : IFTDistribution2D(omega_x, omega_y, gamma)
 {
@@ -128,6 +144,11 @@ double FTDistribution2DCone::evaluate(double qx, double qy) const
     return 6.0 * (MathFunctions::Bessel_J1c(scaled_q) - integral / scaled_q / scaled_q / scaled_q);
 }
 
+std::unique_ptr<IDistribution2DSampler> FTDistribution2DCone::createSampler() const
+{
+    return std::make_unique<Distribution2DConeSampler>(m_omega_x, m_omega_y);
+}
+
 double FTDistribution2DCone::coneIntegrand2(double value) const
 {
     return value * value * MathFunctions::Bessel_J0(value);
@@ -161,3 +182,13 @@ double FTDistribution2DVoigt::evaluate(double qx, double qy) const
     double sum_sq = sumsq(qx, qy);
     return m_eta * std::exp(-sum_sq / 2) + (1.0 - m_eta) * std::pow(1.0 + sum_sq, -1.5);
 }
+
+std::unique_ptr<IDistribution2DSampler> FTDistribution2DVoigt::createSampler() const
+{
+    // TODO Need to implement 2D Voigt
+
+    std::ostringstream ostr;
+    ostr << "FTDistribution2DVoigt::createSampler() -> Error in class initialization";
+    ostr << "\n\n Has not been implemented yet...stay tuned!";
+    throw Exceptions::ClassInitializationException(ostr.str());
+}
diff --git a/Core/Aggregate/FTDistributions2D.h b/Core/Aggregate/FTDistributions2D.h
index 0930f600d8a9886bf077be8077efbbbec00f6e79..40c9342d2a73a096431f30091e5343f14aa881d8 100644
--- a/Core/Aggregate/FTDistributions2D.h
+++ b/Core/Aggregate/FTDistributions2D.h
@@ -18,6 +18,7 @@
 #include "ICloneable.h"
 #include "INode.h"
 #include "MathConstants.h"
+#include "IDistribution2DSampler.h"
 
 //! Interface for two-dimensional distributions in Fourier space.
 //! @ingroup distribution_internal
@@ -41,6 +42,10 @@ public:
     //! total integral is equal to 1
     virtual double evaluate(double qx, double qy) const=0;
 
+#ifndef SWIG
+    virtual std::unique_ptr<IDistribution2DSampler> createSampler() const=0;
+#endif
+
 protected:
     double sumsq( double qx, double qy) const;
 
@@ -70,6 +75,9 @@ public:
     FTDistribution2DCauchy* clone() const final;
     void accept(INodeVisitor* visitor) const final { visitor->visit(this); }
     double evaluate(double qx, double qy) const final;
+#ifndef SWIG
+    std::unique_ptr<IDistribution2DSampler> createSampler() const final;
+#endif
 };
 
 //! Two-dimensional Gauss distribution in Fourier space;
@@ -85,6 +93,9 @@ public:
     FTDistribution2DGauss* clone() const final;
     void accept(INodeVisitor* visitor) const final { visitor->visit(this); }
     double evaluate(double qx, double qy) const final;
+#ifndef SWIG
+    std::unique_ptr<IDistribution2DSampler> createSampler() const final;
+#endif
 };
 
 //! Two-dimensional gate distribution in Fourier space;
@@ -100,6 +111,9 @@ public:
     FTDistribution2DGate* clone() const final;
     void accept(INodeVisitor* visitor) const final { visitor->visit(this); }
     double evaluate(double qx, double qy) const final;
+#ifndef SWIG
+    std::unique_ptr<IDistribution2DSampler> createSampler() const final;
+#endif
 };
 
 //! Two-dimensional cone distribution in Fourier space;
@@ -115,6 +129,9 @@ public:
     FTDistribution2DCone* clone() const final;
     void accept(INodeVisitor* visitor) const final { visitor->visit(this); }
     double evaluate(double qx, double qy) const final;
+#ifndef SWIG
+    std::unique_ptr<IDistribution2DSampler> createSampler() const final;
+#endif
 
 private:
     //! second part of the integrand:
@@ -135,6 +152,9 @@ public:
     void accept(INodeVisitor* visitor) const final { visitor->visit(this); }
     double evaluate(double qx, double qy) const final;
     double eta() const { return m_eta; }
+#ifndef SWIG
+    std::unique_ptr<IDistribution2DSampler> createSampler() const final;
+#endif
 
 protected:
     double m_eta;
diff --git a/Core/Aggregate/IDistribution1DSampler.cpp b/Core/Aggregate/IDistribution1DSampler.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..67283885f4c4846b37566aa14caaf98ea7e8eb8c
--- /dev/null
+++ b/Core/Aggregate/IDistribution1DSampler.cpp
@@ -0,0 +1,103 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      Core/Aggregate/FTDistributions1D.h
+//! @brief     Defines interface class IFTDistribution1D, and children thereof
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "IDistribution1DSampler.h"
+#include <random>
+
+IDistribution1DSampler::~IDistribution1DSampler() = default;
+
+double Distribution1DCauchySampler::randomSample() const
+{
+    // BornAgain Cauchy Distribution = std library Exponential distribution
+    std::random_device rd;  // random device class instance
+    std::mt19937 gen(rd()); // Standard mersenne_twister_engine seeded with rd()
+    std::exponential_distribution<double> expDist(m_lambda);
+    double value = expDist(gen);
+
+    std::bernoulli_distribution bernoulliDist(0.5);
+    bool sign = bernoulliDist(gen);
+
+    if (sign == true)
+        return value;
+    else
+        return -value;
+}
+
+double Distribution1DGaussSampler::randomSample() const
+{
+    // BornAgain Gauss Distribution = std library Normal distribution
+    std::random_device rd;
+    std::mt19937 gen(rd());
+    std::normal_distribution<double> normalDist(m_mean, m_stddev);
+
+    return normalDist(gen);
+}
+
+double Distribution1DGateSampler::randomSample() const
+{
+    // BornAgain Gate Distribution = std library Uniform distribution
+    std::random_device rd;
+    std::mt19937 gen(rd());
+    std::uniform_real_distribution<double> uniformDist(m_a, m_b);
+
+    return uniformDist(gen);
+}
+
+double Distribution1DTriangleSampler::randomSample() const
+{
+    std::random_device rd;
+    std::mt19937 gen(rd());
+
+    // generate a cdf value between 0 and 1
+    std::uniform_real_distribution<> uniformDist(0.0, 1.0);
+    double cdf_value = uniformDist(gen);
+
+    // solve for x by inverting the cdf of Triangle Distribution
+    if (cdf_value <= 0.5)
+        return (-m_omega + m_omega * std::sqrt(2 * cdf_value));
+    else
+        return (m_omega - m_omega * std::sqrt(2 * (1 - cdf_value)));
+}
+
+double Distribution1DCosineSampler::randomSample() const
+{
+    std::random_device rd;
+    std::mt19937 gen(rd());
+
+    // generate a cdf value between 0 and 1
+    std::uniform_real_distribution<> uniformDist(0.0, 1.0);
+    double cdf_value = uniformDist(gen);
+
+    // solve for x from the cdf of Cosine Distribution using Newton-Raphson method
+    double func = 0.0, funcDeriv = 0.0, x = 0.0;
+
+    // initial guess for x
+    if (cdf_value <= 0.5)
+        x = -m_omega / 2;
+    else
+        x = m_omega / 2;
+
+    bool convergedSoln = false;
+    while (!convergedSoln) {
+        func = x + m_omega / M_PI * std::sin(M_PI * x / m_omega) + m_omega * (1 - 2 * cdf_value);
+        funcDeriv = 1 + std::cos(M_PI * x / m_omega);
+
+        x = x - func / funcDeriv;
+
+        if (std::abs(func / funcDeriv) < 0.001)
+            convergedSoln = true;
+    }
+
+    return x;
+}
diff --git a/Core/Aggregate/IDistribution1DSampler.h b/Core/Aggregate/IDistribution1DSampler.h
new file mode 100644
index 0000000000000000000000000000000000000000..e4b68fe2b9422c6568927f7def8f1aced8f65355
--- /dev/null
+++ b/Core/Aggregate/IDistribution1DSampler.h
@@ -0,0 +1,79 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      Core/Aggregate/FTDistributions1D.h
+//! @brief     Defines interface class IFTDistribution1D, and children thereof
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef IDISTRIBUTION1DSAMPLER_H
+#define IDISTRIBUTION1DSAMPLER_H
+
+#include "WinDllMacros.h"
+
+class BA_CORE_API_ IDistribution1DSampler
+{
+public:
+    IDistribution1DSampler() {}
+    virtual ~IDistribution1DSampler();
+
+    virtual double randomSample() const=0;
+};
+
+class BA_CORE_API_ Distribution1DCauchySampler : public IDistribution1DSampler
+{
+public:
+    Distribution1DCauchySampler(double lambda) : m_lambda(lambda) {}
+    double randomSample() const final;
+
+private:
+    double m_lambda;
+};
+
+class BA_CORE_API_ Distribution1DGaussSampler : public IDistribution1DSampler
+{
+public:
+    Distribution1DGaussSampler(double mean, double stddev) : m_mean(mean), m_stddev(stddev) {}
+    double randomSample() const final;
+
+private:
+    double m_mean, m_stddev;
+};
+
+class BA_CORE_API_ Distribution1DGateSampler : public IDistribution1DSampler
+{
+public:
+    Distribution1DGateSampler(double a, double b) : m_a(a), m_b(b) {}
+    double randomSample() const final;
+
+private:
+    double m_a, m_b; // the left and right limits of the Gate (Uniform) distribution
+};
+
+class BA_CORE_API_ Distribution1DTriangleSampler : public IDistribution1DSampler
+{
+public:
+    Distribution1DTriangleSampler(double omega) : m_omega(omega) {}
+    double randomSample() const final;
+
+private:
+    double m_omega; // half the base of the symmetrical Triangle distribution
+};
+
+class BA_CORE_API_ Distribution1DCosineSampler : public IDistribution1DSampler
+{
+public:
+    Distribution1DCosineSampler(double omega) : m_omega(omega) {}
+    double randomSample() const final;
+
+private:
+    double m_omega;
+};
+
+#endif // IDISTRIBUTION1DSAMPLER_H
diff --git a/Core/Aggregate/IDistribution2DSampler.cpp b/Core/Aggregate/IDistribution2DSampler.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..80942cd4933891d80f03793051a376978069da01
--- /dev/null
+++ b/Core/Aggregate/IDistribution2DSampler.cpp
@@ -0,0 +1,177 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      Core/Aggregate/FTDistributions1D.h
+//! @brief     Defines interface class IFTDistribution1D, and children thereof
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "IDistribution2DSampler.h"
+#include <random>
+
+namespace
+{
+double sigma_scale = 3.0;
+size_t n_boxes = 256; // number of boxes for Ziggurat sampling
+
+struct BA_CORE_API_ ZigguratBox {
+    ZigguratBox(double x_min, double x_max, double y_max, double y_lower)
+        : m_x_min(x_min), m_x_max(x_max), m_y_max(y_max), m_y_lower(y_lower) {}
+
+    double m_x_min; // left edge of the box
+    double m_x_max; // right edge of the box
+    // m_y_min is inherently 0 for every box and hence has not been defined
+    double m_y_max;   // height of box
+    double m_y_lower; // minimum height of the box for which points below that height
+                      // are located below the density function curve in the box
+};
+
+std::pair<double, double> samplingZiggurat(double r, double x_func_max, double (*func_phi)(double))
+{
+    // This sampling is based on vertical boxes instead of the conventional
+    // Ziggurat sampling that is done with horizontal boxes
+
+    std::random_device rd;  // random device class instance
+    std::mt19937 gen(rd()); // Standard mersenne_twister_engine seeded with rd()
+    std::uniform_real_distribution<double> uniformDist(0.0, 1.0);
+
+    double box_width = (x_func_max + r) / n_boxes; // r = rightmost box's right-edge from x_func_max
+    std::vector<ZigguratBox> boxes;
+    std::vector<double> cum_area_vector;
+
+    double x_min = 0, x_max = 0, y_max = 0, y_lower = 0, cum_area_box = 0;
+
+    // Establising vectors of boxes and cumulative area (probability of each box) for Ziggurat
+    // sampling
+    for (size_t i = 0; i < n_boxes; ++i) {
+        if (i != 0)
+            x_min = x_max;
+
+        x_max += box_width;
+
+        if (x_func_max >= x_max) {
+            y_max = func_phi(x_max);
+            y_lower = func_phi(x_min);
+        } else if (x_func_max > x_min && x_func_max <= x_max) {
+            y_max = func_phi(x_func_max);
+            y_lower = std::min(func_phi(x_min), func_phi(x_max));
+        } else {
+            y_max = func_phi(x_min);
+            y_lower = func_phi(x_max);
+        }
+
+        boxes.emplace_back(ZigguratBox(x_min, x_max, y_max, y_lower));
+
+        cum_area_box += box_width * y_max;
+        cum_area_vector.emplace_back(cum_area_box);
+    }
+
+    // Normalizing the cumulative area to 1
+    for (size_t i = 0; i < n_boxes; ++i)
+        cum_area_vector[i] = cum_area_vector[i] / cum_area_vector.back();
+
+    // Sampling a phi value
+    double phi = 0;
+    bool solnFound(false);
+
+    while (!solnFound) {
+        double random_cum_area = uniformDist(gen);
+        for (size_t i = 0; i < n_boxes; ++i) {
+            if (random_cum_area <= cum_area_vector[i]) {
+                double random_y = uniformDist(gen) * boxes[i].m_y_max;
+
+                std::uniform_real_distribution<double> uniformDistAB(boxes[i].m_x_min,
+                                                                     boxes[i].m_x_max);
+                double phi_attempt = uniformDistAB(gen);
+
+                if (random_y <= boxes[i].m_y_lower) {
+                    phi = phi_attempt;
+                    solnFound = true;
+                } else {
+                    if (random_y <= func_phi(phi_attempt)) {
+                        phi = phi_attempt;
+                        solnFound = true;
+                    }
+                }
+                break;
+            }
+        }
+    }
+
+    // Sampling an alpha value
+    double alpha = 2 * M_PI * uniformDist(gen);
+    return std::make_pair(phi, alpha);
+}
+
+double func_phi_Cauchy(double phi)
+{
+    // The independent "phi" density function of the 2D Cauchy distribution
+    return phi * std::exp(-phi);
+}
+
+double func_phi_Cone(double phi)
+{
+    // The independent "phi" density function of the 2D Cone distribution
+    return 6 * (1 - phi) * phi;
+}
+}
+
+IDistribution2DSampler::~IDistribution2DSampler() = default;
+
+std::pair<double, double> Distribution2DCauchySampler::randomSample() const
+{
+    // Use Ziggurat sampling instead of Inverse Transform Sampling (ITS requires numerical solver)
+
+    double phi_max_Cauchy = 1.0;
+    // rightmost box's right-edge from phi_max_Cauchy for Ziggurat Sampling
+    double r = sigma_scale * std::sqrt(2); // standard dev of func_phi_Cauchy is sqrt(2)
+    std::pair<double, double> samples = samplingZiggurat(r, phi_max_Cauchy, func_phi_Cauchy);
+    return std::make_pair(m_omega_x * samples.first * std::cos(samples.second),
+                          m_omega_y * samples.first * std::sin(samples.second));
+}
+
+std::pair<double, double> Distribution2DGaussSampler::randomSample() const
+{
+    std::random_device rd;  // random device class instance
+    std::mt19937 gen(rd()); // Standard mersenne_twister_engine seeded with rd()
+    std::uniform_real_distribution<double> uniformDist(0.0, 1.0);
+
+    double cdf_value_phi = uniformDist(gen);
+
+    // Use ITS and solve for phi from the cdf of radial (phi) distribution
+    double phi = std::sqrt(-2 * std::log(1 - cdf_value_phi));
+    double alpha = 2 * M_PI * uniformDist(gen);
+    return std::make_pair(m_omega_x * phi * std::cos(alpha), m_omega_y * phi * std::sin(alpha));
+}
+
+std::pair<double, double> Distribution2DGateSampler::randomSample() const
+{
+    std::random_device rd;  // random device class instance
+    std::mt19937 gen(rd()); // Standard mersenne_twister_engine seeded with rd()
+    std::uniform_real_distribution<double> uniformDist(0.0, 1.0);
+
+    double cdf_value_phi = uniformDist(gen);
+
+    // Use ITS and solve for phi from the cdf of radial (phi) distribution
+    double phi = std::sqrt(cdf_value_phi);
+    double alpha = 2 * M_PI * uniformDist(gen);
+    return std::make_pair(m_omega_x * phi * std::cos(alpha), m_omega_y * phi * std::sin(alpha));
+}
+
+std::pair<double, double> Distribution2DConeSampler::randomSample() const
+{
+    // Use Ziggurat sampling instead of Inverse Transform Sampling (ITS requires numerical solver)
+
+    double phi_max_Cone = 0.5;
+    // rightmost box's right-edge from phi_max_Cone for Ziggurat Sampling
+    double r = 0.5;
+    std::pair<double, double> samples = samplingZiggurat(r, phi_max_Cone, func_phi_Cone);
+    return std::make_pair(m_omega_x * samples.first * std::cos(samples.second),
+                          m_omega_y * samples.first * std::sin(samples.second));
+}
diff --git a/Core/Aggregate/IDistribution2DSampler.h b/Core/Aggregate/IDistribution2DSampler.h
new file mode 100644
index 0000000000000000000000000000000000000000..1d8fe98119359c936fde3d9d8cbbd1eb71486d63
--- /dev/null
+++ b/Core/Aggregate/IDistribution2DSampler.h
@@ -0,0 +1,74 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      Core/Aggregate/FTDistributions1D.h
+//! @brief     Defines interface class IFTDistribution1D, and children thereof
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef IDISTRIBUTION2DSAMPLER_H
+#define IDISTRIBUTION2DSAMPLER_H
+
+#include "WinDllMacros.h"
+#include <utility>
+
+class BA_CORE_API_ IDistribution2DSampler
+{
+public:
+    IDistribution2DSampler() {}
+    virtual ~IDistribution2DSampler();
+
+    virtual std::pair<double, double> randomSample() const=0;
+};
+
+class BA_CORE_API_ Distribution2DCauchySampler : public IDistribution2DSampler
+{
+public:
+    Distribution2DCauchySampler(double omega_x, double omega_y) :
+        m_omega_x(omega_x), m_omega_y(omega_y) {}
+    std::pair<double, double> randomSample() const final;
+
+private:
+    double m_omega_x, m_omega_y;
+};
+
+class BA_CORE_API_ Distribution2DGaussSampler : public IDistribution2DSampler
+{
+public:
+    Distribution2DGaussSampler(double omega_x, double omega_y) :
+        m_omega_x(omega_x), m_omega_y(omega_y) {}
+    std::pair<double, double> randomSample() const final;
+
+private:
+    double m_omega_x, m_omega_y;
+};
+
+class BA_CORE_API_ Distribution2DGateSampler : public IDistribution2DSampler
+{
+public:
+    Distribution2DGateSampler(double omega_x, double omega_y) :
+        m_omega_x(omega_x), m_omega_y(omega_y) {}
+    std::pair<double, double> randomSample() const final;
+
+private:
+    double m_omega_x, m_omega_y;
+};
+
+class BA_CORE_API_ Distribution2DConeSampler : public IDistribution2DSampler
+{
+public:
+    Distribution2DConeSampler(double omega_x, double omega_y) :
+        m_omega_x(omega_x), m_omega_y(omega_y) {}
+    std::pair<double, double> randomSample() const final;
+
+private:
+    double m_omega_x, m_omega_y;
+};
+
+#endif // IDISTRIBUTION2DSAMPLER_H
diff --git a/Core/Aggregate/IPeakShape.cpp b/Core/Aggregate/IPeakShape.cpp
index 2e2d31d6c63bf3220f25ebb669b1d23a0ff323c0..90f5293c59c28daa74002606c76aba477a8d8859 100644
--- a/Core/Aggregate/IPeakShape.cpp
+++ b/Core/Aggregate/IPeakShape.cpp
@@ -15,27 +15,144 @@
 #include "IPeakShape.h"
 #include "MathConstants.h"
 
+#include <limits>
+
+namespace {
+const double maxkappa = std::log(1.0/std::numeric_limits<double>::epsilon())/2.0;
+double FisherDistribution(double x, double kappa);
+double Gauss3D(double q2, double domainsize);
+double Cauchy3D(double q2, double domainsize);
+}
+
 IPeakShape::~IPeakShape() =default;
 
-GaussPeakShape::GaussPeakShape(double domainsize)
-    : m_domainsize(domainsize)
+IsotropicGaussPeakShape::IsotropicGaussPeakShape(double max_intensity, double domainsize)
+    : m_max_intensity(max_intensity)
+    , m_domainsize(domainsize)
+{}
+
+IsotropicGaussPeakShape::~IsotropicGaussPeakShape() =default;
+
+IsotropicGaussPeakShape* IsotropicGaussPeakShape::clone() const
+{
+    return new IsotropicGaussPeakShape(m_max_intensity, m_domainsize);
+}
+
+double IsotropicGaussPeakShape::evaluate(const kvector_t q) const
+{
+    double q_norm = q.mag2();
+    return m_max_intensity * Gauss3D(q_norm, m_domainsize);
+}
+
+double IsotropicGaussPeakShape::evaluate(const kvector_t q, const kvector_t q_lattice_point) const
+{
+    return evaluate(q - q_lattice_point);
+}
+
+IsotropicLorentzPeakShape::IsotropicLorentzPeakShape(double max_intensity, double domainsize)
+    : m_max_intensity(max_intensity)
+    , m_domainsize(domainsize)
 {}
 
-GaussPeakShape::~GaussPeakShape() =default;
+IsotropicLorentzPeakShape::~IsotropicLorentzPeakShape() =default;
 
-GaussPeakShape* GaussPeakShape::clone() const
+IsotropicLorentzPeakShape* IsotropicLorentzPeakShape::clone() const
 {
-    return new GaussPeakShape(m_domainsize);
+    return new IsotropicLorentzPeakShape(m_max_intensity, m_domainsize);
 }
 
-double GaussPeakShape::evaluate(const kvector_t q) const
+double IsotropicLorentzPeakShape::evaluate(const kvector_t q) const
 {
     double q_norm = q.mag2();
-    double exponent = -q_norm*m_domainsize*m_domainsize/2.0;
-    return m_domainsize * std::sqrt(M_TWOPI) * std::exp(exponent);
+    return m_max_intensity * Cauchy3D(q_norm, m_domainsize);
 }
 
-double GaussPeakShape::thickness_z() const
+double IsotropicLorentzPeakShape::evaluate(const kvector_t q, const kvector_t q_lattice_point) const
+{
+    return evaluate(q - q_lattice_point);
+}
+
+GaussFisherPeakShape::GaussFisherPeakShape(double max_intensity, double radial_size, double kappa)
+    : m_max_intensity(max_intensity)
+    , m_radial_size(radial_size)
+    , m_kappa(kappa)
+{}
+
+GaussFisherPeakShape::~GaussFisherPeakShape() =default;
+
+GaussFisherPeakShape* GaussFisherPeakShape::clone() const
 {
-    return m_domainsize;
+    return new GaussFisherPeakShape(m_max_intensity, m_radial_size, m_kappa);
 }
+
+double GaussFisherPeakShape::evaluate(const kvector_t q, const kvector_t q_lattice_point) const
+{
+    double q_r = q.mag();
+    double q_lat_r = q_lattice_point.mag();
+    double dq2 = (q_r - q_lat_r)*(q_r - q_lat_r);
+    if (q_lat_r == 0.0)
+        return m_max_intensity * Gauss3D(dq2, m_radial_size);
+    double norm_factor = m_radial_size / std::sqrt(M_TWOPI);
+    double radial_part = norm_factor * std::exp(-dq2*m_radial_size*m_radial_size/2.0);
+    double angular_part = 1.0;
+    if (q_r*q_lat_r > 0.0) {
+        double dot_norm = q.dot(q_lattice_point)/q_r/q_lat_r;
+        angular_part = FisherDistribution(dot_norm, m_kappa)/(q_r*q_r);
+    }
+    return m_max_intensity * radial_part * angular_part;
+}
+
+LorentzFisherPeakShape::LorentzFisherPeakShape(double max_intensity, double radial_size, double kappa)
+    : m_max_intensity(max_intensity)
+    , m_radial_size(radial_size)
+    , m_kappa(kappa)
+{}
+
+LorentzFisherPeakShape::~LorentzFisherPeakShape() =default;
+
+LorentzFisherPeakShape* LorentzFisherPeakShape::clone() const
+{
+    return new LorentzFisherPeakShape(m_max_intensity, m_radial_size, m_kappa);
+}
+
+double LorentzFisherPeakShape::evaluate(const kvector_t q, const kvector_t q_lattice_point) const
+{
+    double q_r = q.mag();
+    double q_lat_r = q_lattice_point.mag();
+    double dq2 = (q_r - q_lat_r)*(q_r - q_lat_r);
+    if (q_lat_r == 0.0)
+        return m_max_intensity * Cauchy3D(dq2, m_radial_size);
+    double radial_part = m_radial_size / (1.0 + dq2*m_radial_size*m_radial_size) / M_PI;
+    double angular_part = 1.0;
+    if (q_r*q_lat_r > 0.0) {
+        double dot_norm = q.dot(q_lattice_point)/q_r/q_lat_r;
+        angular_part = FisherDistribution(dot_norm, m_kappa)/(q_r*q_r);
+    }
+    return m_max_intensity * radial_part * angular_part;
+}
+
+namespace {
+double FisherDistribution(double x, double kappa)
+{
+    if (kappa<=0.0) {
+        return 1.0/(4.0*M_PI);
+    }
+    double prefactor = kappa / (4.0*M_PI);
+    if (kappa>maxkappa) {
+        return 2.0*prefactor*std::exp(kappa*(x-1.0));
+    }
+    return prefactor*std::exp(kappa*x)/std::sinh(kappa);
+}
+double Gauss3D(double q2, double domainsize)
+{
+    double norm_factor = std::pow(domainsize / std::sqrt(M_TWOPI), 3.0);
+    double exponent = -q2*domainsize*domainsize/2.0;
+    return norm_factor * std::exp(exponent);
+}
+double Cauchy3D(double q2, double domainsize)
+{
+    double lorentz1 = domainsize / (1.0 + q2*domainsize*domainsize) / M_PI;
+    return domainsize * lorentz1 * lorentz1;
+}
+}
+
diff --git a/Core/Aggregate/IPeakShape.h b/Core/Aggregate/IPeakShape.h
index b502cda00f13d7e0e5ac4477efb83097ce381d8c..3f79eee0ae7d0c98e8684229e4c8bee18bf0c36c 100644
--- a/Core/Aggregate/IPeakShape.h
+++ b/Core/Aggregate/IPeakShape.h
@@ -29,33 +29,103 @@ public:
 
     virtual IPeakShape* clone() const=0;
 
-    //! Evaluates the peak shape at displacement q from the center at 0
-    virtual double evaluate(const kvector_t q) const=0;
+    //! Evaluates the peak shape at q from a reciprocal lattice point at q_lattice_point
+    virtual double evaluate(const kvector_t q, const kvector_t q_lattice_point) const=0;
 
-    //! Returns the thickness in the z-direction
-    virtual double thickness_z() const=0;
+    //! Indicates if the peak shape encodes angular disorder, in which case all peaks in a
+    //! spherical shell are needed
+    virtual bool angularDisorder() const { return false; }
 };
 
 
-//! Class that implements a Gaussian peak shape of a Bragg peak.
+//! Class that implements an isotropic Gaussian peak shape of a Bragg peak.
 //!
 //! @ingroup samples_internal
 
-class BA_CORE_API_ GaussPeakShape : public IPeakShape
+class BA_CORE_API_ IsotropicGaussPeakShape : public IPeakShape
 {
 public:
-    GaussPeakShape(double domainsize);
-    ~GaussPeakShape() override;
+    IsotropicGaussPeakShape(double max_intensity, double domainsize);
+    ~IsotropicGaussPeakShape() override;
 
-    GaussPeakShape* clone() const override;
+    IsotropicGaussPeakShape* clone() const override;
 
     void accept(INodeVisitor* visitor) const override { visitor->visit(this); }
 
-    double evaluate(const kvector_t q) const override;
+    double evaluate(const kvector_t q, const kvector_t q_lattice_point) const override;
+private:
+    double evaluate(const kvector_t q) const;
+    double m_max_intensity;
+    double m_domainsize;
+};
+
+//! Class that implements an isotropic Lorentzian peak shape of a Bragg peak.
+//!
+//! @ingroup samples_internal
+
+class BA_CORE_API_ IsotropicLorentzPeakShape : public IPeakShape
+{
+public:
+    IsotropicLorentzPeakShape(double max_intensity, double domainsize);
+    ~IsotropicLorentzPeakShape() override;
+
+    IsotropicLorentzPeakShape* clone() const override;
 
-    double thickness_z() const override;
+    void accept(INodeVisitor* visitor) const override { visitor->visit(this); }
+
+    double evaluate(const kvector_t q, const kvector_t q_lattice_point) const override;
 private:
+    double evaluate(const kvector_t q) const;
+    double m_max_intensity;
     double m_domainsize;
 };
 
+//! Class that implements a peak shape that is Gaussian in the radial direction and
+//! uses the von Mises-Fisher distribution in the angular direction.
+//!
+//! @ingroup samples_internal
+
+class BA_CORE_API_ GaussFisherPeakShape : public IPeakShape
+{
+public:
+    GaussFisherPeakShape(double max_intensity, double radial_size, double kappa);
+    ~GaussFisherPeakShape() override;
+
+    GaussFisherPeakShape* clone() const override;
+
+    void accept(INodeVisitor* visitor) const override { visitor->visit(this); }
+
+    double evaluate(const kvector_t q, const kvector_t q_lattice_point) const override;
+
+    bool angularDisorder() const override { return true; }
+private:
+    double m_max_intensity;
+    double m_radial_size;
+    double m_kappa;
+};
+
+//! Class that implements a peak shape that is Lorentzian in the radial direction and
+//! uses the von Mises-Fisher distribution in the angular direction.
+//!
+//! @ingroup samples_internal
+
+class BA_CORE_API_ LorentzFisherPeakShape : public IPeakShape
+{
+public:
+    LorentzFisherPeakShape(double max_intensity, double radial_size, double kappa);
+    ~LorentzFisherPeakShape() override;
+
+    LorentzFisherPeakShape* clone() const override;
+
+    void accept(INodeVisitor* visitor) const override { visitor->visit(this); }
+
+    double evaluate(const kvector_t q, const kvector_t q_lattice_point) const override;
+
+    bool angularDisorder() const override { return true; }
+private:
+    double m_max_intensity;
+    double m_radial_size;
+    double m_kappa;
+};
+
 #endif // IPEAKSHAPE_H
diff --git a/Core/Aggregate/InterferenceFunction2DParaCrystal.h b/Core/Aggregate/InterferenceFunction2DParaCrystal.h
index c4f92926c792fb8edb1db5e55f8c75e74b4de8e7..b58645421de1357a360dcb6045124890738e0af5 100644
--- a/Core/Aggregate/InterferenceFunction2DParaCrystal.h
+++ b/Core/Aggregate/InterferenceFunction2DParaCrystal.h
@@ -73,6 +73,16 @@ public:
 
     std::vector<const INode*> getChildren() const;
 
+    const IFTDistribution2D* pdf1() const
+    {
+        return m_pdf1.get();
+    }
+
+    const IFTDistribution2D* pdf2() const
+    {
+        return m_pdf2.get();
+    }
+
 private:
     InterferenceFunction2DParaCrystal(const InterferenceFunction2DParaCrystal& other);
     void setLattice(const Lattice2D& lattice);
diff --git a/Core/Aggregate/InterferenceFunction2DSuperLattice.cpp b/Core/Aggregate/InterferenceFunction2DSuperLattice.cpp
index 7af1dfca0aded1d709120005e82293b93e4a49bd..b77fec8420eaf559f2e284239a353d4c96b65f85 100644
--- a/Core/Aggregate/InterferenceFunction2DSuperLattice.cpp
+++ b/Core/Aggregate/InterferenceFunction2DSuperLattice.cpp
@@ -19,15 +19,12 @@
 #include "InterferenceFunctionNone.h"
 #include "Macros.h"
 #include "MathConstants.h"
+#include "MathFunctions.h"
 #include "RealParameter.h"
 
 #include <limits>
 
-namespace {
-double SinNx_Div_Sinx(double x, unsigned N);
-double DebyeWallerFactor(double variance, double q2);
-}
-
+using MathFunctions::Laue;
 
 InterferenceFunction2DSuperLattice::InterferenceFunction2DSuperLattice(
         const Lattice2D& lattice, unsigned size_1, unsigned size_2)
@@ -163,9 +160,9 @@ double InterferenceFunction2DSuperLattice::interferenceForXi(double xi) const
 
     double qadiv2 = (m_qx*a*std::cos(xi) + m_qy*a*std::sin(xi)) / 2.0;
     double qbdiv2 = (m_qx*b*std::cos(xialpha) + m_qy*b*std::sin(xialpha)) / 2.0;
-    double ampl = SinNx_Div_Sinx(qadiv2, m_size_1)*SinNx_Div_Sinx(qbdiv2, m_size_2);
+    double ampl = Laue(qadiv2, m_size_1)*Laue(qbdiv2, m_size_2);
     double lattice_factor = ampl*ampl / (m_size_1*m_size_2);
-    double DW_factor = DebyeWallerFactor(m_sigma2, m_qx*m_qx + m_qy*m_qy);
+    double DW_factor = std::exp(-m_sigma2*(m_qx*m_qx + m_qy*m_qy)/2.0);
 
     double delta_xi = xi - mP_lattice->rotationAngle();
     kvector_t q = kvector_t(m_qx, m_qy, 0.0).rotatedZ(-delta_xi);
@@ -173,19 +170,3 @@ double InterferenceFunction2DSuperLattice::interferenceForXi(double xi) const
 
     return (1.0 + DW_factor*(lattice_factor - 1.0))*substructure_result;
 }
-
-namespace {
-double SinNx_Div_Sinx(double x, unsigned N) {
-    static const double SQRT6DOUBLE_EPS = std::sqrt(6.0*std::numeric_limits<double>::epsilon());
-    auto nd = static_cast<double>(N);
-    if(std::abs(nd*x) < SQRT6DOUBLE_EPS)
-        return nd;
-    double num = std::sin(nd*x);
-    double den = std::sin(x);
-    return num/den;
-}
-double DebyeWallerFactor(double variance, double q2) {
-    return std::exp(-q2*variance/2.0);
-}
-}
-
diff --git a/Core/Aggregate/InterferenceFunction3DLattice.cpp b/Core/Aggregate/InterferenceFunction3DLattice.cpp
index 03d26970d9c3544a4afd5c501674b371a758cd1e..a1d1ae54f0fd768170c118bb8b92b67b8f871231 100644
--- a/Core/Aggregate/InterferenceFunction3DLattice.cpp
+++ b/Core/Aggregate/InterferenceFunction3DLattice.cpp
@@ -18,11 +18,6 @@
 #include "IPeakShape.h"
 #include <algorithm>
 
-namespace
-{
-double DebyeWallerFactor(const kvector_t& q, double dw_length);
-}  // unnamed namespace
-
 InterferenceFunction3DLattice::InterferenceFunction3DLattice(const Lattice& lattice)
     : m_lattice(lattice)
     , mP_peak_shape(nullptr)
@@ -59,11 +54,21 @@ double InterferenceFunction3DLattice::evaluate(const kvector_t q) const
     if (!mP_peak_shape)
         throw std::runtime_error("InterferenceFunction3DLattice::evaluate: "
                                  "no peak shape defined");
+    kvector_t center = q;
     double radius = 2.1 * m_rec_radius;
-    auto rec_vectors = m_lattice.reciprocalLatticeVectorsWithinRadius(q, radius);
+    double inner_radius = 0.0;
+    if (mP_peak_shape->angularDisorder()) {
+        center = kvector_t(0.0, 0.0, 0.0);
+        inner_radius = std::max(0.0, q.mag()-radius);
+        radius += q.mag();
+    }
+    auto rec_vectors = m_lattice.reciprocalLatticeVectorsWithinRadius(center, radius);
     double result = 0.0;
     for (const auto& q_rec : rec_vectors) {
-        result += mP_peak_shape->evaluate(q - q_rec)*DebyeWallerFactor(q_rec, m_dw_length);
+        if (!(q_rec.mag()<inner_radius)) {
+            double dw_factor = std::exp(-q_rec.mag2()*m_dw_length*m_dw_length/3.0);
+            result += mP_peak_shape->evaluate(q, q_rec)*dw_factor;
+        }
     }
     return result;
 }
@@ -73,15 +78,6 @@ const Lattice&InterferenceFunction3DLattice::lattice() const
     return m_lattice;
 }
 
-double InterferenceFunction3DLattice::getParticleDensity() const
-{
-    double v = m_lattice.volume();
-    if (!mP_peak_shape || v<=0.0)
-        return 0.0;
-    double t = mP_peak_shape->thickness_z();
-    return t/v;
-}
-
 std::vector<const INode*> InterferenceFunction3DLattice::getChildren() const
 {
     return {};
@@ -101,13 +97,3 @@ void InterferenceFunction3DLattice::initRecRadius()
     m_rec_radius = std::max(M_PI / a1.mag(), M_PI / a2.mag());
     m_rec_radius = std::max(m_rec_radius, M_PI / a3.mag());
 }
-
-namespace
-{
-double DebyeWallerFactor(const kvector_t& q, double dw_length)
-{
-    double exponent = -q.mag2()*dw_length*dw_length/3.0;
-    return std::exp(exponent);
-}
-}  // unnamed namespace
-
diff --git a/Core/Aggregate/InterferenceFunction3DLattice.h b/Core/Aggregate/InterferenceFunction3DLattice.h
index 28bf796f0801ee1e4a0e50d7dcbf3a92153727af..78625f8359deea975b4a88e61a04ee2e68aa67d5 100644
--- a/Core/Aggregate/InterferenceFunction3DLattice.h
+++ b/Core/Aggregate/InterferenceFunction3DLattice.h
@@ -41,8 +41,6 @@ public:
 
     const Lattice& lattice() const;
 
-    double getParticleDensity() const final;
-
     bool supportsMultilayer() const override { return false; }
 
     std::vector<const INode*> getChildren() const override;
diff --git a/Core/Aggregate/InterferenceFunctionFinite2DLattice.cpp b/Core/Aggregate/InterferenceFunctionFinite2DLattice.cpp
index 497c108c0c07e1b8cb3a377156613132dc187aa7..04febae47e72a0968ecaed686b078dd31ae2823d 100644
--- a/Core/Aggregate/InterferenceFunctionFinite2DLattice.cpp
+++ b/Core/Aggregate/InterferenceFunctionFinite2DLattice.cpp
@@ -18,39 +18,43 @@
 #include "IntegratorReal.h"
 #include "Macros.h"
 #include "MathConstants.h"
+#include "MathFunctions.h"
 #include "RealParameter.h"
 
 #include <limits>
 
-namespace {
-double SinNx_Div_Sinx(double x, unsigned N);
-double DebyeWallerFactor(double variance, double q2);
-}
+using MathFunctions::Laue;
 
 
+//! Constructor of two-dimensional finite lattice interference function.
+//! @param lattice: object specifying a 2d lattice structure
+//! @param N_1: number of lattice cells in the first lattice direction
+//! @param N_2: number of lattice cells in the second lattice direction
 InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice(
-        const Lattice2D& lattice, unsigned size_1, unsigned size_2)
+        const Lattice2D& lattice, unsigned N_1, unsigned N_2)
     : m_sigma2(0.0)
     , m_integrate_xi(false)
-    , m_size_1(size_1)
-    , m_size_2(size_2)
+    , m_N_1(N_1)
+    , m_N_2(N_2)
 {
     setName(BornAgain::InterferenceFunctionFinite2DLatticeType);
     setLattice(lattice);
     init_parameters();
 }
 
-//! Constructor of two-dimensional interference function.
+//! Constructor of two-dimensional finite lattice interference function.
 //! @param length_1: length of first lattice vector in nanometers
 //! @param length_2: length of second lattice vector  in nanometers
 //! @param alpha: angle between lattice vectors in radians
 //! @param xi: rotation of lattice with respect to x-axis (beam direction) in radians
+//! @param N_1: number of lattice cells in the first lattice direction
+//! @param N_2: number of lattice cells in the second lattice direction
 InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice(
-        double length_1, double length_2, double alpha, double xi, unsigned size_1, unsigned size_2)
+        double length_1, double length_2, double alpha, double xi, unsigned N_1, unsigned N_2)
     : m_sigma2(0.0)
     , m_integrate_xi(false)
-    , m_size_1(size_1)
-    , m_size_2(size_2)
+    , m_N_1(N_1)
+    , m_N_2(N_2)
 {
     setName(BornAgain::InterferenceFunctionFinite2DLatticeType);
     setLattice(BasicLattice(length_1, length_2, alpha, xi));
@@ -67,21 +71,25 @@ InterferenceFunctionFinite2DLattice* InterferenceFunctionFinite2DLattice::clone(
 //! Creates square lattice.
 //! @param lattice_length: length of first and second lattice vectors in nanometers
 //! @param xi: rotation of lattice with respect to x-axis in radians
+//! @param N_1: number of lattice cells in the first lattice direction
+//! @param N_2: number of lattice cells in the second lattice direction
 InterferenceFunctionFinite2DLattice* InterferenceFunctionFinite2DLattice::createSquare(
-    double lattice_length, double xi, unsigned size_1, unsigned size_2)
+    double lattice_length, double xi, unsigned N_1, unsigned N_2)
 {
     return new InterferenceFunctionFinite2DLattice(SquareLattice(lattice_length, xi),
-                                                   size_1, size_2);
+                                                   N_1, N_2);
 }
 
 //! Creates hexagonal lattice.
 //! @param lattice_length: length of first and second lattice vectors in nanometers
 //! @param xi: rotation of lattice with respect to x-axis in radians
+//! @param N_1: number of lattice cells in the first lattice direction
+//! @param N_2: number of lattice cells in the second lattice direction
 InterferenceFunctionFinite2DLattice* InterferenceFunctionFinite2DLattice::createHexagonal(
-    double lattice_length, double xi, unsigned size_1, unsigned size_2)
+    double lattice_length, double xi, unsigned N_1, unsigned N_2)
 {
     return new InterferenceFunctionFinite2DLattice(HexagonalLattice(lattice_length, xi),
-                                                   size_1, size_2);
+                                                   N_1, N_2);
 }
 
 double InterferenceFunctionFinite2DLattice::evaluate(const kvector_t q) const
@@ -89,52 +97,52 @@ double InterferenceFunctionFinite2DLattice::evaluate(const kvector_t q) const
     m_qx = q.x();
     m_qy = q.y();
     if (!m_integrate_xi)
-        return interferenceForXi(m_lattice->rotationAngle());
+        return interferenceForXi(mP_lattice->rotationAngle());
     return mP_integrator->integrate(0.0, M_TWOPI) / M_TWOPI;
 }
 
 void InterferenceFunctionFinite2DLattice::setIntegrationOverXi(bool integrate_xi)
 {
     m_integrate_xi = integrate_xi;
-    m_lattice->setRotationEnabled(!m_integrate_xi); // deregister Xi in the case of integration
+    mP_lattice->setRotationEnabled(!m_integrate_xi); // deregister Xi in the case of integration
 }
 
 const Lattice2D& InterferenceFunctionFinite2DLattice::lattice() const
 {
-    if(!m_lattice)
+    if(!mP_lattice)
         throw std::runtime_error("InterferenceFunctionFinite2DLattice::lattice() -> Error. "
                                  "No lattice defined.");
-    return *m_lattice;
+    return *mP_lattice;
 }
 
 double InterferenceFunctionFinite2DLattice::getParticleDensity() const
 {
-    double area = m_lattice->unitCellArea();
+    double area = mP_lattice->unitCellArea();
     return area == 0.0 ? 0.0 : 1.0/area;
 }
 
 std::vector<const INode*> InterferenceFunctionFinite2DLattice::getChildren() const
 {
-    return std::vector<const INode*>() << m_lattice;
+    return std::vector<const INode*>() << mP_lattice;
 }
 
 InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice(
         const InterferenceFunctionFinite2DLattice& other)
     : m_sigma2(other.m_sigma2)
-    , m_size_1(other.m_size_1)
-    , m_size_2(other.m_size_2)
+    , m_N_1(other.m_N_1)
+    , m_N_2(other.m_N_2)
 {
     setName(other.getName());
-    if(other.m_lattice)
-        setLattice(*other.m_lattice);
+    if(other.mP_lattice)
+        setLattice(*other.mP_lattice);
     setIntegrationOverXi(other.integrationOverXi());
     init_parameters();
 }
 
 void InterferenceFunctionFinite2DLattice::setLattice(const Lattice2D& lattice)
 {
-    m_lattice.reset(lattice.clone());
-    registerChild(m_lattice.get());
+    mP_lattice.reset(lattice.clone());
+    registerChild(mP_lattice.get());
 }
 
 void InterferenceFunctionFinite2DLattice::init_parameters()
@@ -146,31 +154,15 @@ void InterferenceFunctionFinite2DLattice::init_parameters()
 
 double InterferenceFunctionFinite2DLattice::interferenceForXi(double xi) const
 {
-    double a = m_lattice->length1();
-    double b = m_lattice->length2();
-    double xialpha = xi + m_lattice->latticeAngle();
+    double a = mP_lattice->length1();
+    double b = mP_lattice->length2();
+    double xialpha = xi + mP_lattice->latticeAngle();
 
     double qadiv2 = (m_qx*a*std::cos(xi) + m_qy*a*std::sin(xi)) / 2.0;
     double qbdiv2 = (m_qx*b*std::cos(xialpha) + m_qy*b*std::sin(xialpha)) / 2.0;
-    double ampl = SinNx_Div_Sinx(qadiv2, m_size_1)*SinNx_Div_Sinx(qbdiv2, m_size_2);
-    double lattice_factor = ampl*ampl / (m_size_1*m_size_2);
-    double DW_factor = DebyeWallerFactor(m_sigma2, m_qx*m_qx + m_qy*m_qy);
+    double ampl = Laue(qadiv2, m_N_1)*Laue(qbdiv2, m_N_2);
+    double lattice_factor = ampl*ampl / (m_N_1*m_N_2);
+    double DW_factor = std::exp(-m_sigma2*(m_qx*m_qx + m_qy*m_qy)/2.0);
 
     return 1.0 + DW_factor*(lattice_factor - 1.0);
 }
-
-namespace {
-double SinNx_Div_Sinx(double x, unsigned N) {
-    static const double SQRT6DOUBLE_EPS = std::sqrt(6.0*std::numeric_limits<double>::epsilon());
-    auto nd = static_cast<double>(N);
-    if(std::abs(nd*x) < SQRT6DOUBLE_EPS)
-        return nd;
-    double num = std::sin(nd*x);
-    double den = std::sin(x);
-    return num/den;
-}
-double DebyeWallerFactor(double variance, double q2) {
-    return std::exp(-q2*variance/2.0);
-}
-}
-
diff --git a/Core/Aggregate/InterferenceFunctionFinite2DLattice.h b/Core/Aggregate/InterferenceFunctionFinite2DLattice.h
index 5a7026be0e91615e807c76117583b59786aa30e0..28bc6a5cc0334d9de2309859596be080fb175a32 100644
--- a/Core/Aggregate/InterferenceFunctionFinite2DLattice.h
+++ b/Core/Aggregate/InterferenceFunctionFinite2DLattice.h
@@ -26,9 +26,9 @@ template <class T> class IntegratorReal;
 class BA_CORE_API_ InterferenceFunctionFinite2DLattice : public IInterferenceFunction
 {
 public:
-    InterferenceFunctionFinite2DLattice(const Lattice2D& lattice, unsigned size_1, unsigned size_2);
+    InterferenceFunctionFinite2DLattice(const Lattice2D& lattice, unsigned N_1, unsigned N_2);
     InterferenceFunctionFinite2DLattice(double length_1, double length_2, double alpha,
-                                        double xi, unsigned size_1, unsigned size_2);
+                                        double xi, unsigned N_1, unsigned N_2);
     ~InterferenceFunctionFinite2DLattice() final;
 
     InterferenceFunctionFinite2DLattice* clone() const final;
@@ -36,14 +36,14 @@ public:
     void accept(INodeVisitor* visitor) const final { visitor->visit(this); }
 
     static InterferenceFunctionFinite2DLattice* createSquare(
-            double lattice_length, double xi, unsigned size_1, unsigned size_2);
+            double lattice_length, double xi, unsigned N_1, unsigned N_2);
     static InterferenceFunctionFinite2DLattice* createHexagonal(
-            double lattice_length, double xi, unsigned size_1, unsigned size_2);
+            double lattice_length, double xi, unsigned N_1, unsigned N_2);
 
     double evaluate(const kvector_t q) const final;
 
-    unsigned domainSize1() const { return m_size_1; }
-    unsigned domainSize2() const { return m_size_2; }
+    unsigned numberUnitCells1() const { return m_N_1; }
+    unsigned numberUnitCells2() const { return m_N_2; }
 
     void setPositionVariance(double sigma2) { m_sigma2 = sigma2; }
     double positionVariance() const { return m_sigma2; }
@@ -67,8 +67,8 @@ private:
 
     double m_sigma2;
     bool m_integrate_xi; //!< Integrate over the orientation xi
-    std::unique_ptr<Lattice2D> m_lattice;
-    unsigned m_size_1, m_size_2;  //!< Size of the finite lattice in lattice units
+    std::unique_ptr<Lattice2D> mP_lattice;
+    unsigned m_N_1, m_N_2;  //!< Size of the finite lattice in lattice units
     mutable double m_qx;
     mutable double m_qy;
 #ifndef SWIG
diff --git a/Core/Aggregate/InterferenceFunctionFinite3DLattice.cpp b/Core/Aggregate/InterferenceFunctionFinite3DLattice.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e6518d53a9aaffa40df31f568fcd584b889fca40
--- /dev/null
+++ b/Core/Aggregate/InterferenceFunctionFinite3DLattice.cpp
@@ -0,0 +1,80 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      Core/Aggregate/InterferenceFunctionFinite2DLattice.cpp
+//! @brief     Implements class InterferenceFunctionFinite2DLattice.
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "InterferenceFunctionFinite3DLattice.h"
+#include "BornAgainNamespace.h"
+#include "Exceptions.h"
+#include "Macros.h"
+#include "MathConstants.h"
+#include "MathFunctions.h"
+#include "RealParameter.h"
+
+#include <limits>
+
+using MathFunctions::Laue;
+
+//! Constructor of three-dimensional finite lattice interference function.
+//! @param lattice: object specifying a 2d lattice structure
+//! @param N_1: number of lattice cells in the first lattice direction
+//! @param N_2: number of lattice cells in the second lattice direction
+InterferenceFunctionFinite3DLattice::InterferenceFunctionFinite3DLattice(
+        const Lattice& lattice, unsigned N_1, unsigned N_2, unsigned N_3)
+    : m_N_1(N_1), m_N_2(N_2), m_N_3(N_3)
+{
+    setLattice(lattice);
+}
+
+InterferenceFunctionFinite3DLattice::~InterferenceFunctionFinite3DLattice() =default;
+
+InterferenceFunctionFinite3DLattice* InterferenceFunctionFinite3DLattice::clone() const
+{
+    return new InterferenceFunctionFinite3DLattice(*this);
+}
+
+double InterferenceFunctionFinite3DLattice::evaluate(const kvector_t q) const
+{
+    double qadiv2 = q.dot(mP_lattice->getBasisVectorA())/2.0;
+    double qbdiv2 = q.dot(mP_lattice->getBasisVectorB())/2.0;
+    double qcdiv2 = q.dot(mP_lattice->getBasisVectorC())/2.0;
+    double ampl = Laue(qadiv2, m_N_1)*Laue(qbdiv2, m_N_2)*Laue(qcdiv2, m_N_3);
+    return ampl*ampl / (m_N_1*m_N_2*m_N_3);
+}
+
+const Lattice& InterferenceFunctionFinite3DLattice::lattice() const
+{
+    if(!mP_lattice)
+        throw std::runtime_error("InterferenceFunctionFinite3DLattice::lattice() -> Error. "
+                                 "No lattice defined.");
+    return *mP_lattice;
+}
+
+std::vector<const INode*> InterferenceFunctionFinite3DLattice::getChildren() const
+{
+    return std::vector<const INode*>() << mP_lattice;
+}
+
+InterferenceFunctionFinite3DLattice::InterferenceFunctionFinite3DLattice(
+    const InterferenceFunctionFinite3DLattice& other)
+    : m_N_1(other.m_N_1), m_N_2(other.m_N_2), m_N_3(other.m_N_3)
+{
+    setName(other.getName());
+    if(other.mP_lattice)
+        setLattice(*other.mP_lattice);
+}
+
+void InterferenceFunctionFinite3DLattice::setLattice(const Lattice& lattice)
+{
+    mP_lattice.reset(new Lattice(lattice));
+    registerChild(mP_lattice.get());
+}
diff --git a/Core/Aggregate/InterferenceFunctionFinite3DLattice.h b/Core/Aggregate/InterferenceFunctionFinite3DLattice.h
new file mode 100644
index 0000000000000000000000000000000000000000..2071b655296ebfbe6651e78327fb36a0aa5d5eef
--- /dev/null
+++ b/Core/Aggregate/InterferenceFunctionFinite3DLattice.h
@@ -0,0 +1,52 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      Core/Aggregate/InterferenceFunctionFinite3DLattice.h
+//! @brief     Defines class InterferenceFunctionFinite3DLattice.
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef INTERFERENCEFUNCTIONFINITE3DLATTICE_H
+#define INTERFERENCEFUNCTIONFINITE3DLATTICE_H
+
+#include "IInterferenceFunction.h"
+#include "Lattice.h"
+
+//! Interference function of 2D lattice.
+//! @ingroup interference
+
+class BA_CORE_API_ InterferenceFunctionFinite3DLattice : public IInterferenceFunction
+{
+public:
+    InterferenceFunctionFinite3DLattice(const Lattice& lattice, unsigned N_1, unsigned N_2,
+                                        unsigned N_3);
+    ~InterferenceFunctionFinite3DLattice() final;
+
+    InterferenceFunctionFinite3DLattice* clone() const final;
+
+    void accept(INodeVisitor* visitor) const final { visitor->visit(this); }
+
+    double evaluate(const kvector_t q) const final;
+
+    unsigned numberUnitCells1() const { return m_N_1; }
+    unsigned numberUnitCells2() const { return m_N_2; }
+    unsigned numberUnitCells3() const { return m_N_3; }
+
+    const Lattice& lattice() const;
+
+    std::vector<const INode*> getChildren() const override;
+private:
+    InterferenceFunctionFinite3DLattice(const InterferenceFunctionFinite3DLattice& other);
+    void setLattice(const Lattice& lattice);
+
+    std::unique_ptr<Lattice> mP_lattice;
+    unsigned m_N_1, m_N_2, m_N_3;  //!< Size of the finite lattice in lattice units
+};
+
+#endif // INTERFERENCEFUNCTIONFINITE3DLATTICE_H
diff --git a/Core/Aggregate/InterferenceFunctionRadialParaCrystal.h b/Core/Aggregate/InterferenceFunctionRadialParaCrystal.h
index 402a6c45b14da4e6b9302b069776f65d7f031a10..d77dab102848101e1cef96adb6a4dfbbd2ae3560 100644
--- a/Core/Aggregate/InterferenceFunctionRadialParaCrystal.h
+++ b/Core/Aggregate/InterferenceFunctionRadialParaCrystal.h
@@ -49,6 +49,8 @@ public:
 
     std::vector<const INode*> getChildren() const override;
 
+    double randomSample() const { return mP_pdf->createSampler()->randomSample(); }
+
 private:
     void init_parameters();
 
diff --git a/Core/Basics/BornAgainNamespace.h b/Core/Basics/BornAgainNamespace.h
index 05c8707b2781696bd2185cf5bfd841d89d3da651..04058199463afe242d77489adf6964259c915844 100644
--- a/Core/Basics/BornAgainNamespace.h
+++ b/Core/Basics/BornAgainNamespace.h
@@ -95,8 +95,9 @@ const std::string FFFullSphereType = "FullSphere";
 const std::string FFFullSpheroidType = "FullSpheroid";
 const std::string FFGaussType = "FormFactorGauss";
 const std::string FFHemiEllipsoidType = "HemiEllipsoid";
-const std::string FFLongBoxGaussType = "FormFactorLongBoxGauss";
 const std::string FFIcosahedronType = "Icosahedron";
+const std::string FFLongBoxType = "FormFactorLongBox";
+const std::string FFLongBoxGaussType = "FormFactorLongBoxGauss";
 const std::string FFLongBoxLorentzType = "FormFactorLongBoxLorentz";
 const std::string FFLorentzType = "FormFactorLorentz";
 const std::string FFOrnsteinZernikeType = "FormFactorOrnsteinZernike";
diff --git a/Core/Binning/PointwiseAxis.cpp b/Core/Binning/PointwiseAxis.cpp
index b899bf2d8dd0176a654921d93a7a18171160abc6..4fd3e2f5dc4daf919290c750d2b5716ca9e373b9 100644
--- a/Core/Binning/PointwiseAxis.cpp
+++ b/Core/Binning/PointwiseAxis.cpp
@@ -141,5 +141,5 @@ void PointwiseAxis::sanityCheck() const
 
     if (std::adjacent_find(begin, end) != end)
         throw std::runtime_error("Error in PointwiseAxis::PointwiseAxis: passed coordinate vector "
-                                 "containes repeating values");
+                                 "contains repeating values");
 }
diff --git a/Core/CMakeLists.txt b/Core/CMakeLists.txt
index 09d0092f3091b360975bb63575ba1adac26131d9..2d7fd039adb924ef5067b977d481ee022eb02b0b 100644
--- a/Core/CMakeLists.txt
+++ b/Core/CMakeLists.txt
@@ -4,10 +4,6 @@
 
 set(library_name BornAgainCore)
 
-if(POLICY CMP0042)
-    cmake_policy(SET CMP0042 NEW)
-endif()
-
 if(BORNAGAIN_TIDY)
 #    set(CMAKE_CXX_CLANG_TIDY "clang-tidy;-checks=-*,readability-*,-readability-braces-around-statements")
     set(CMAKE_CXX_CLANG_TIDY "clang-tidy;-checks=-*,clang-analyzer-*,readability-*,-readability-braces-around-statements,modernize-*")
@@ -150,14 +146,15 @@ set(${library_name}_LIBRARY ${library_name} PARENT_SCOPE)
 target_link_libraries(${library_name} ${BornAgainFit_LIBRARY} ${CMAKE_THREAD_LIBS_INIT})
 
 if(BORNAGAIN_TIFF_SUPPORT)
-    add_definitions(-DBORNAGAIN_TIFF_SUPPORT)
-    include_directories(${TIFF_INCLUDE_DIR})
+    target_compile_definitions(${library_name} PUBLIC -DBORNAGAIN_TIFF_SUPPORT)
+    target_include_directories(${library_name} PUBLIC ${TIFF_INCLUDE_DIR})
     target_link_libraries(${library_name} ${TIFF_LIBRARIES})
 endif()
 
-include_as_system_directory("${EIGEN3_INCLUDE_DIR}")
-include_directories(${Boost_INCLUDE_DIRS} ${FFTW_INCLUDE_DIR}
-    ${GSL_INCLUDE_DIR} ${Faddeeva_INCLUDE_DIR})
+target_include_directories(${library_name} PUBLIC ${include_dirs})
+target_include_directories(${library_name} SYSTEM PUBLIC ${EIGEN3_INCLUDE_DIR})
+target_include_directories(${library_name} PUBLIC ${Boost_INCLUDE_DIRS} ${FFTW_INCLUDE_DIR}
+    ${GSL_INCLUDE_DIR} PRIVATE ${Faddeeva_INCLUDE_DIR})
 target_link_libraries(${library_name} ${Boost_LIBRARIES} ${FFTW_LIBRARY} ${GSL_LIBRARIES}
     ${Faddeeva_LIBRARY})
 
@@ -168,7 +165,7 @@ if(BORNAGAIN_MPI)
 endif()
 
 if(BORNAGAIN_PYTHON)
-    add_definitions(-DBORNAGAIN_PYTHON)
+    target_compile_definitions(${library_name} PUBLIC -DBORNAGAIN_PYTHON)
     include_directories(${PYTHON_INCLUDE_DIRS} ${NUMPY_INCLUDE_DIR})
     target_link_libraries(${library_name} ${PYTHON_LIBRARIES})
 endif()
diff --git a/Core/Export/PythonFormatting.cpp b/Core/Export/PythonFormatting.cpp
index 7cf9dedc28914a667150d90bf13de5ec45ad0d47..67c9243404d42b63c94b161616ac771d28973384 100644
--- a/Core/Export/PythonFormatting.cpp
+++ b/Core/Export/PythonFormatting.cpp
@@ -23,6 +23,7 @@
 #include "Numeric.h"
 #include "ParameterPool.h"
 #include "ParameterDistribution.h"
+#include "PointwiseAxis.h"
 #include "Polygon.h"
 #include "RealParameter.h"
 #include "Rectangle.h"
@@ -301,7 +302,7 @@ std::string printParameterDistribution(const ParameterDistribution& par_distr,
     return result.str();
 }
 
-std::string printAxis(const IAxis& axis, const std::string& units)
+std::string printAxis(const IAxis& axis, const std::string& units, size_t offset)
 {
     std::ostringstream result;
 
@@ -311,7 +312,17 @@ std::string printAxis(const IAxis& axis, const std::string& units)
                << fixedAxis->size() << ", "
                << printValue(fixedAxis->getMin(), units) << ", "
                << printValue(fixedAxis->getMax(), units) << ")";
-
+    } else if (auto pointwise_axis = dynamic_cast<const PointwiseAxis*>(&axis)) {
+        const std::string py_def_call = "numpy.asarray([";
+        const size_t total_offset = offset + py_def_call.size();
+        result << py_def_call;
+
+        std::vector<double> points = pointwise_axis->getBinCenters();
+        for (auto iter = points.begin(); iter != points.end()-1; ++iter) {
+            result << printValue(*iter, units) << ",\n";
+            result << indent(total_offset);
+        }
+        result << printValue(points.back(), units) << "])";
     } else {
         throw std::runtime_error("PythonFormatting::printAxis() -> Error. Unsupported axis");
     }
@@ -319,4 +330,9 @@ std::string printAxis(const IAxis& axis, const std::string& units)
     return result.str();
 }
 
+std::string indent(size_t width)
+{
+    return std::string(width, ' ');
+}
+
 } // namespace PythonFormatting
diff --git a/Core/Export/PythonFormatting.h b/Core/Export/PythonFormatting.h
index df9879af061370c51e3cc009f7481cd8344e65a4..e639f57f38a4ed5487ec6c8fce9ec5db321bee6f 100644
--- a/Core/Export/PythonFormatting.h
+++ b/Core/Export/PythonFormatting.h
@@ -66,7 +66,13 @@ BA_CORE_API_ std::string printParameterDistribution(const ParameterDistribution&
                                                     const std::string& distVarName,
                                                     const std::string& units = "");
 
-BA_CORE_API_ std::string printAxis(const IAxis& axis, const std::string& units = "");
+//! Prints python-script definition for given axis.
+//! offset is used for alignment and indentation in multiple-line definitions
+BA_CORE_API_ std::string printAxis(const IAxis& axis, const std::string& units, size_t offset);
+
+//! Returns a string of blanks with given width. By default
+//! the width equals standard offset in python files.
+BA_CORE_API_ std::string indent(size_t width = 4u);
 }
 
 #endif // PYTHONFORMATTING_H
diff --git a/Core/Export/SampleToPython.cpp b/Core/Export/SampleToPython.cpp
index 4ecee8a69d51ce6abf3c462938b80cac2bc6c867..11b5c0914a0ecf811ccb60f4d5f91ad6fd2e874b 100644
--- a/Core/Export/SampleToPython.cpp
+++ b/Core/Export/SampleToPython.cpp
@@ -427,7 +427,8 @@ std::string SampleToPython::defineInterferenceFunctions() const
                    << printNm(lattice.length1()) << ", " << printNm(lattice.length2()) << ", "
                    << printDegrees(lattice.latticeAngle()) << ", "
                    << printDegrees(lattice.rotationAngle()) << ", "
-                   << p_lattice_2d->domainSize1() << ", " << p_lattice_2d->domainSize2() << ")\n";
+                   << p_lattice_2d->numberUnitCells1() << ", "
+                   << p_lattice_2d->numberUnitCells2() << ")\n";
 
             if (p_lattice_2d->positionVariance()>0.0) {
                 result << indent() << it->second << ".setPositionVariance("
diff --git a/Core/Export/SimulationToPython.cpp b/Core/Export/SimulationToPython.cpp
index 4d51e8247ad33d6eba2afae6385d33bb2514c1f6..e216f8d5c2db784999fc22d60757da0aafceca70 100644
--- a/Core/Export/SimulationToPython.cpp
+++ b/Core/Export/SimulationToPython.cpp
@@ -270,8 +270,11 @@ std::string SimulationToPython::defineOffSpecBeam(const OffSpecSimulation& simul
     std::ostringstream result;
     const Beam& beam = simulation.getInstrument().getBeam();
 
-    result << indent() << "alpha_i_axis = "
-           << PythonFormatting::printAxis(*simulation.beamAxis(), BornAgain::UnitsRad) << "\n";
+    const std::string axis_def = indent() + "alpha_i_axis = ";
+    result << axis_def
+           << PythonFormatting::printAxis(*simulation.beamAxis(), BornAgain::UnitsRad,
+                                          axis_def.size())
+           << "\n";
 
     result << indent() << "simulation.setBeamParameters(" << printNm(beam.getWavelength()) << ", "
            << "alpha_i_axis, " << printDegrees(beam.getPhi()) << ")\n";
@@ -290,8 +293,11 @@ std::string SimulationToPython::defineSpecularBeam(const SpecularSimulation& sim
     if (footprint)
         result << indent() << "footprint = " << defineFootprint(*footprint);
 
-    result << indent() << "alpha_i_axis = "
-           << PythonFormatting::printAxis(*simulation.getAlphaAxis(), BornAgain::UnitsRad) << "\n";
+    const std::string axis_def = indent() + "alpha_i_axis = ";
+    result << axis_def
+           << PythonFormatting::printAxis(*simulation.getAlphaAxis(), BornAgain::UnitsRad,
+                                          axis_def.size())
+           << "\n";
 
     result << indent() << "simulation.setBeamParameters(" << printNm(beam.getWavelength()) << ", "
            << "alpha_i_axis";
@@ -444,5 +450,3 @@ std::string SimulationToPython::defineMain(SimulationToPython::EMainType mainTyp
     }
     return result;
 }
-
-std::string SimulationToPython::indent() const { return "    "; }
diff --git a/Core/Export/SimulationToPython.h b/Core/Export/SimulationToPython.h
index b00ba7cfd63386233633e08b7c906d9b95f6ce8a..2a377e0b393544f4388ce2cff889793c540cb019 100644
--- a/Core/Export/SimulationToPython.h
+++ b/Core/Export/SimulationToPython.h
@@ -61,8 +61,6 @@ private:
     std::string defineSimulationOptions(const Simulation* simulation) const;
     std::string defineBackground(const Simulation* simulation) const;
     std::string defineMain(EMainType mainType = RUN_SIMULATION);
-
-    std::string indent() const;
 };
 
 #endif // SIMULATIONTOPYTHON_H
diff --git a/Core/Fitting/AdjustMinimizerStrategy.cpp b/Core/Fitting/AdjustMinimizerStrategy.cpp
deleted file mode 100644
index 4747d0cbf82fcd6ed966889b11c3598642d8ae15..0000000000000000000000000000000000000000
--- a/Core/Fitting/AdjustMinimizerStrategy.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Fitting/AdjustMinimizerStrategy.cpp
-//! @brief     Implements class AdjustMinimizerStrategy.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "AdjustMinimizerStrategy.h"
-#include "FitSuiteImpl.h"
-#include "IMinimizer.h"
-#include "MinimizerFactory.h"
-
-AdjustMinimizerStrategy::AdjustMinimizerStrategy()
-    : IFitStrategy("FitStrategy/AdjustMinimizer")
-{
-}
-
-AdjustMinimizerStrategy::AdjustMinimizerStrategy(const std::string &minimizerName,
-                                                       const std::string &algorithmName,
-                                                       const std::string &optionString)
-    : IFitStrategy("FitStrategy/AdjustMinimizer")
-    , m_minimizerName(minimizerName)
-    , m_algorithmName(algorithmName)
-    , m_optionString(optionString)
-{
-    setMinimizer(minimizerName, algorithmName, optionString);
-}
-
-
-AdjustMinimizerStrategy* AdjustMinimizerStrategy::clone() const
-{
-    AdjustMinimizerStrategy* result = new AdjustMinimizerStrategy(*this);
-    return result;
-}
-
-void AdjustMinimizerStrategy::setMinimizer(const std::string &minimizerName,
-                                              const std::string &algorithmName,
-                                              const std::string &optionString)
-{
-    m_minimizerName = minimizerName;
-    m_algorithmName = algorithmName;
-    m_optionString = optionString;
-}
-
-void AdjustMinimizerStrategy::execute()
-{
-    m_kernel->setMinimizer(
-        MinimizerFactory::createMinimizer(m_minimizerName, m_algorithmName, m_optionString));
-    m_kernel->minimize();
-}
-
-std::string AdjustMinimizerStrategy::toString() const
-{
-    std::ostringstream ostr;
-    ostr << "FitStrategy/AdjustMinimizer ("
-         << m_minimizerName << ", "
-         << m_algorithmName << ", "
-         << m_optionString << ")";
-    return ostr.str();
-}
-
-AdjustMinimizerStrategy::AdjustMinimizerStrategy(const AdjustMinimizerStrategy &other)
-    : IFitStrategy(other)
-{
-    m_minimizerName = other.m_minimizerName;
-    m_algorithmName = other.m_algorithmName;
-    m_optionString = other.m_optionString;
-}
diff --git a/Core/Fitting/AdjustMinimizerStrategy.h b/Core/Fitting/AdjustMinimizerStrategy.h
deleted file mode 100644
index ac46c53556c3c3d8558fbae1d72eaefb16800118..0000000000000000000000000000000000000000
--- a/Core/Fitting/AdjustMinimizerStrategy.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Fitting/AdjustMinimizerStrategy.h
-//! @brief     Defines class AdjustMinimizerStrategy
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef ADJUSTMINIMIZERSTRATEGY_H
-#define ADJUSTMINIMIZERSTRATEGY_H
-
-#include "IFitStrategy.h"
-
-//! Strategy modifies mimimizer settings before running minimization round.
-//! @ingroup fitting
-
-class BA_CORE_API_ AdjustMinimizerStrategy : public IFitStrategy
-{
-public:
-    AdjustMinimizerStrategy();
-
-    AdjustMinimizerStrategy(const std::string& minimizerName,
-                               const std::string& algorithmName="",
-                               const std::string& optionString="");
-
-    virtual AdjustMinimizerStrategy* clone() const;
-
-    void setMinimizer(const std::string& minimizerName,
-                      const std::string& algorithmName="",
-                      const std::string& optionString="");
-
-    virtual void execute();
-
-protected:
-    virtual std::string toString() const;
-    AdjustMinimizerStrategy(const AdjustMinimizerStrategy &other);
-
-private:
-    std::string m_minimizerName;
-    std::string m_algorithmName;
-    std::string m_optionString;
-};
-
-#endif // ADJUSTMINIMIZERSTRATEGY_H
diff --git a/Core/Fitting/FitObject.cpp b/Core/Fitting/FitObject.cpp
deleted file mode 100644
index 99009d2b5e8daf1a0c92dd1b421d24928f10bf78..0000000000000000000000000000000000000000
--- a/Core/Fitting/FitObject.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Fitting/FitObject.cpp
-//! @brief     Implements class FitObject.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "FitObject.h"
-#include "BornAgainNamespace.h"
-#include "DetectorFunctions.h"
-#include "FitElement.h"
-#include "IHistogram.h"
-#include "IIntensityNormalizer.h"
-#include "Simulation.h"
-#include "SimulationArea.h"
-#include "UnitConverterUtils.h"
-#include "IntensityDataFunctions.h"
-#include "Numeric.h"
-#include "ArrayUtils.h"
-
-static_assert(std::is_copy_constructible<FitObject>::value == false,
-              "FitObject should not be copy constructable");
-static_assert(std::is_copy_assignable<FitObject>::value == false,
-              "FitObject should not be copy assignable");
-
-FitObject::FitObject(const Simulation& simulation, const OutputData<double>& data, double weight)
-    : m_simulation(simulation.clone()), m_weight(weight), m_fit_elements_count(0)
-
-{
-    init_parameters();
-    m_experimental_data = IntensityDataFunctions::ConvertData(simulation, data, false);
-}
-
-FitObject::FitObject(const Simulation& simulation, const std::vector<std::vector<double>>& data,
-                     double weight)
-    : m_simulation(simulation.clone()), m_weight(weight), m_fit_elements_count(0)
-
-{
-    init_parameters();
-    m_experimental_data = IntensityDataFunctions::ConvertData(simulation, data, false);
-}
-
-FitObject::~FitObject() = default;
-
-std::vector<const INode*> FitObject::getChildren() const
-{
-    return std::vector<const INode*>() << m_simulation;
-}
-
-SimulationResult FitObject::simulationResult() const
-{
-    return m_simulation_result;
-}
-
-SimulationResult FitObject::experimentalData() const
-{
-    return m_experimental_data;
-}
-
-SimulationResult FitObject::relativeDifference() const
-{
-    auto converter = UnitConverterUtils::createConverter(*m_simulation);
-    auto roi_data = UnitConverterUtils::createOutputData(*converter.get(), converter->defaultUnits());
-    auto detector = m_simulation->getInstrument().getDetector();
-
-    detector->iterate([&](IDetector::const_iterator it){
-        const size_t index = it.roiIndex();
-        (*roi_data)[index] = Numeric::get_relative_difference(
-                    m_simulation_result[index], m_experimental_data[index]);
-    });
-
-    return SimulationResult(*roi_data, *converter);
-}
-
-void FitObject::runSimulation()
-{
-    m_simulation->runSimulation();
-    m_simulation_result = m_simulation->result();
-}
-
-std::vector<double> FitObject::experimental_array() const
-{
-    std::vector<double> result;
-    result.reserve(numberOfFitElements());
-
-    auto detector = m_simulation->getInstrument().getDetector();
-    detector->iterate([&](IDetector::const_iterator it){
-        result.push_back(m_experimental_data[it.roiIndex()]);
-    });
-
-    return result;
-}
-
-std::vector<double> FitObject::simulation_array() const
-{
-    std::vector<double> result;
-    result.reserve(numberOfFitElements());
-
-    auto detector = m_simulation->getInstrument().getDetector();
-    detector->iterate([&](IDetector::const_iterator it){
-        result.push_back(m_simulation_result[it.roiIndex()]);
-    });
-
-    return result;
-}
-
-void FitObject::init_parameters()
-{
-    setName("FitObject");
-    m_fit_elements_count = m_simulation->numberOfSimulationElements();
-    registerChild(m_simulation.get());
-    m_simulation_result = m_simulation->result();
-}
-
-size_t FitObject::numberOfFitElements() const { return m_fit_elements_count; }
-
-//! Runs simulation and put results (the real and simulated intensities) into external vector.
-//! Masked channels will be excluded from the vector.
-
-void FitObject::prepareFitElements(std::vector<FitElement>& fit_elements, double weight,
-                                   IIntensityNormalizer* )
-{
-    m_simulation->runSimulation();
-    m_simulation_result = m_simulation->result();
-
-// TODO FIXE Consider normalizer removal. Now FitScaleAndShift example is broken.
-//    if (normalizer)
-//        normalizer->apply(*m_simulation_data.get());
-
-    m_simulation->getInstrument().getDetector()->iterate([&](IDetector::const_iterator it){
-        FitElement element(it.roiIndex(), m_simulation_result[it.roiIndex()],
-                           m_experimental_data[it.roiIndex()], weight);
-        fit_elements.push_back(element);
-    });
-}
diff --git a/Core/Fitting/FitObject.h b/Core/Fitting/FitObject.h
deleted file mode 100644
index 3572704e523ace9d71230a57aa49586fddca5616..0000000000000000000000000000000000000000
--- a/Core/Fitting/FitObject.h
+++ /dev/null
@@ -1,93 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Fitting/FitObject.h
-//! @brief     Defines class FitObject.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef FITOBJECT_H
-#define FITOBJECT_H
-
-#include "INode.h"
-#include "OutputData.h"
-#include "SimulationResult.h"
-#include <memory>
-
-class FitElement;
-class Simulation;
-class IIntensityNormalizer;
-class IHistogram;
-
-//! Holds simulation description and real data to run the fit.
-//! @ingroup fitting_internal
-
-class BA_CORE_API_ FitObject : public INode
-{
-public:
-    //! Constructs simulation/data pair for later fit.
-    //! @param simulation: simulation to run
-    //! @param data: experimental data
-    //! @param weight: weight of dataset in chi2 calculations
-    FitObject(const Simulation& simulation, const OutputData<double>& data, double weight = 1);
-
-    //! Constructs simulation/data pair for later fit.
-    //! @param simulation: simulation to run
-    //! @param data: experimental data
-    //! @param weight: weight of dataset in chi2 calculations
-    FitObject(const Simulation& simulation, const std::vector<std::vector<double>>& data,
-              double weight = 1);
-
-    virtual ~FitObject();
-
-    void accept(INodeVisitor* visitor) const final { visitor->visit(this); }
-
-    //! Returns weight of data set in chi2 calculations.
-    double weight() const { return m_weight; }
-
-    //! Returns the size of the data. It is equal to the number of non-masked detector channels
-    //! which will participate in chi2 calculations.
-    size_t numberOfFitElements() const;
-
-    void prepareFitElements(std::vector<FitElement>& fit_elements, double weight,
-                            IIntensityNormalizer* =0);
-
-    std::vector<const INode*> getChildren() const;
-
-    //! Returns simulation result.
-    SimulationResult simulationResult() const;
-
-    //! Returns experimental data.
-    SimulationResult experimentalData() const;
-
-    //! Returns relative difference between simulation and experimental data.
-    SimulationResult relativeDifference() const;
-
-    //! Runs internal simulation object.
-    void runSimulation();
-
-    //! Returns one dimensional array representing experimental data.
-    //! Masked areas and the area outside of region of interest are not included.
-    std::vector<double> experimental_array() const;
-
-    //! Returns one dimensional array representing simulated intensities data.
-    //! Masked areas and the area outside of region of interest are not included.
-    std::vector<double> simulation_array() const;
-
-private:
-    void init_parameters();
-
-    std::unique_ptr<Simulation> m_simulation;
-    SimulationResult m_simulation_result;
-    SimulationResult m_experimental_data;
-    double m_weight;
-    size_t m_fit_elements_count;
-};
-
-#endif // FITOBJECT_H
diff --git a/Core/Fitting/FitObjective.cpp b/Core/Fitting/FitObjective.cpp
index 65761e80af5267258d068151901e5dd4bf142f6c..13cca0fc5d5b93f5602f8f386674db62295c19d0 100644
--- a/Core/Fitting/FitObjective.cpp
+++ b/Core/Fitting/FitObjective.cpp
@@ -79,11 +79,9 @@ std::vector<double> FitObjective::evaluate_residuals(const Fit::Parameters& para
 
     std::vector<double> result;
 
-    std::vector<double> weights;
-    weights.resize(numberOfFitElements(), 1.0); // FIXME make correct weights
-
     for(size_t i = 0; i<m_simulation_array.size(); ++i)
-        result.push_back(residual(m_simulation_array[i], m_experimental_array[i], weights[i]));
+        result.push_back(residual(m_simulation_array[i], m_experimental_array[i],
+                                  m_weights_array[i]));
 
     double chi2 = evaluate_chi2(result, params);
 
@@ -111,6 +109,11 @@ std::vector<double> FitObjective::simulation_array() const
     return m_simulation_array;
 }
 
+std::vector<double> FitObjective::weights_array() const
+{
+    return m_weights_array;
+}
+
 SimulationResult FitObjective::simulationResult(size_t i_item) const
 {
     return m_fit_objects[check_index(i_item)]->simulationResult();
@@ -126,11 +129,21 @@ SimulationResult FitObjective::relativeDifference(size_t i_item) const
     return m_fit_objects[check_index(i_item)]->relativeDifference();
 }
 
+SimulationResult FitObjective::absoluteDifference(size_t i_item) const
+{
+    return m_fit_objects[check_index(i_item)]->absoluteDifference();
+}
+
 void FitObjective::initPrint(int every_nth)
 {
     m_fit_status->initPrint(every_nth);
 }
 
+void FitObjective::initPlot(int every_nth, fit_observer_t observer)
+{
+    m_fit_status->addObserver(every_nth, observer);
+}
+
 void FitObjective::initPlot(int every_nth, PyObserverCallback& callback)
 {
     fit_observer_t observer = [&](const FitObjective& objective) {
@@ -164,22 +177,47 @@ unsigned FitObjective::fitObjectCount() const
     return static_cast<unsigned>(m_fit_objects.size());
 }
 
+void FitObjective::interruptFitting()
+{
+    m_fit_status->setInterrupted();
+}
+
+bool FitObjective::isInterrupted() const
+{
+    return m_fit_status->isInterrupted();
+}
+
+bool FitObjective::isFirstIteration() const
+{
+    return iterationInfo().iterationCount() == 1;
+}
+
 void FitObjective::run_simulations(const Fit::Parameters& params)
 {
+    if (m_fit_status->isInterrupted())
+        throw std::runtime_error("Fitting was interrupted by the user.");
+
     if (m_fit_objects.empty())
         throw std::runtime_error("FitObjective::run_simulations() -> Error. "
                                  "No simulation/data defined.");
 
     m_simulation_array.clear();
     m_experimental_array.clear();
+    m_weights_array.clear();
 
     for (auto obj : m_fit_objects) {
         obj->runSimulation(params);
         insert_to(m_simulation_array, obj->simulation_array());
         insert_to(m_experimental_array, obj->experimental_array());
+        insert_to(m_weights_array, obj->weights_array());
     }
 }
 
+void FitObjective::setChiSquaredModule(const IChiSquaredModule& module)
+{
+    m_chi2_module.reset(module.clone());
+}
+
 double FitObjective::residual(double a, double b, double weight) const
 {
     return m_chi2_module->residual(a, b, weight);
diff --git a/Core/Fitting/FitObjective.h b/Core/Fitting/FitObjective.h
index 19179ffc33b301664774d9899f252b801a94f764..7604bd36d23e75befea0c56d484421d933d138c5 100644
--- a/Core/Fitting/FitObjective.h
+++ b/Core/Fitting/FitObjective.h
@@ -20,8 +20,8 @@
 #include "SafePointerVector.h"
 #include "SimDataPair.h"
 #include "IterationInfo.h"
+#include "MinimizerResult.h"
 
-namespace Fit { class MinimizerResult; }
 class IChiSquaredModule;
 class PyBuilderCallback;
 class PyObserverCallback;
@@ -70,6 +70,9 @@ public:
     //! Data from different datasets merged together.
     std::vector<double> simulation_array() const;
 
+    //! Returns one dimensional array representing weights of bin intensity for residuals.
+    std::vector<double> weights_array() const;
+
     //! Returns simulation result.
     //! @param i_item: the index of fit pair
     SimulationResult simulationResult(size_t i_item = 0) const;
@@ -82,12 +85,19 @@ public:
     //! @param i_item: the index of fit pair
     SimulationResult relativeDifference(size_t i_item = 0) const;
 
+    //! Returns absolute value of difference between simulation and experimental data.
+    //! @param i_item: the index of fit pair
+    SimulationResult absoluteDifference(size_t i_item = 0) const;
+
     //! Initializes printing to standard output during the fitting.
     //! @param every_nth: Print every n'th iteration.
     void initPrint(int every_nth);
 
     //! Initializes plotting during the fitting using Python callable.
     //! @param every_nth: Called on every n'th iteration.
+#ifndef SWIG
+    void initPlot(int every_nth, fit_observer_t observer);
+#endif
     void initPlot(int every_nth, PyObserverCallback& callback);
 
     bool isCompleted() const;
@@ -101,14 +111,24 @@ public:
 
     unsigned fitObjectCount() const;
 
-private:
+    void interruptFitting();
+
+    bool isInterrupted() const;
+
+    bool isFirstIteration() const;
+
     void run_simulations(const Fit::Parameters& params);
+
+    void setChiSquaredModule(const IChiSquaredModule& module);
+
+private:
     double residual(double a, double b, double weight) const;
     double evaluate_chi2(const std::vector<double>& residuals, const Fit::Parameters& params);
     size_t check_index(size_t index) const;
 
     std::vector<double> m_experimental_array;
     std::vector<double> m_simulation_array;
+    std::vector<double> m_weights_array;
 
     SafePointerVector<SimDataPair> m_fit_objects;
     double m_total_weight;
diff --git a/Core/Fitting/FitParameter.cpp b/Core/Fitting/FitParameter.cpp
deleted file mode 100644
index f6282cb6bad5052040aead03672a546240c660b0..0000000000000000000000000000000000000000
--- a/Core/Fitting/FitParameter.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Fitting/FitParameter.cpp
-//! @brief     Implements class FitParameter.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "FitParameter.h"
-#include "ParameterPool.h"
-#include "RealParameter.h"
-#include <stdexcept>
-#include <algorithm>
-#include <set>
-#include <sstream>
-#include <iterator>
-
-FitParameter::FitParameter(const std::string& pattern, double value,
-                                       const AttLimits& lim, double step)
-    : IFitParameter("", value, lim, step)
-{
-    if(pattern.size())
-        addPattern(pattern);
-}
-
-FitParameter::FitParameter(double value, const AttLimits& lim, double step)
-    : FitParameter("", value, lim, step)
-{
-
-}
-
-FitParameter::~FitParameter()
-{
-    for (auto* par : m_pool_parameters)
-        delete par;
-}
-
-FitParameter* FitParameter::clone() const
-{
-    return new FitParameter(*this);
-}
-
-//! Sets given value for all bound parameters
-
-void FitParameter::setValue(double value)
-{
-    IFitParameter::setValue(value);
-    for (auto* par : m_pool_parameters)
-        par->setValue(value);
-}
-
-//! Adds pattern to the list for later usage in parameter pool matching.
-
-FitParameter& FitParameter::addPattern(const std::string& pattern)
-{
-    if (std::find(m_patterns.begin(), m_patterns.end(), pattern) != m_patterns.end())
-        throw std::runtime_error("FitParameterLinked::addPattern() -> Error. Already contain '"
-                                 + pattern + "'.");
-    m_patterns.push_back(pattern);
-    return *this;
-}
-
-//! Adds real parameter to the collection
-
-void FitParameter::addParameter(const RealParameter& par)
-{
-    if (par.isNull())
-        throw std::runtime_error("FitParameterLinked::addParameter() -> Error. "
-                                 "Attempt to add null parameter.");
-    m_pool_parameters.push_back(par.clone());
-}
-
-//! Adds parameters from pool which match given wildcard
-
-void FitParameter::addMatchedParameters(const ParameterPool& pool)
-{
-    for (auto wildcard : m_patterns) {
-        for (auto par : pool.getMatchedParameters(wildcard)) {
-            if(!isLinked(*par))
-                m_pool_parameters.push_back(par->clone());
-        }
-        if (m_pool_parameters.empty())
-            throw std::runtime_error("FitParameterLinked::addMatchedParameters() -> Error! "
-                                     "Failed to add anything from pool using wildcard '"
-                                     + wildcard + "'");
-    }
-}
-
-std::vector<std::string> FitParameter::patterns() const
-{
-    return m_patterns;
-}
-
-//! Returns vector of strings with names of all matched parameters.
-
-std::vector<std::string> FitParameter::matchedParameterNames() const
-{
-    std::vector<std::string> result;
-    std::transform(m_pool_parameters.begin(), m_pool_parameters.end(), std::back_inserter(result),
-                   [](RealParameter* par){return par->getName();});
-    return result;
-}
-
-//! Returns vector containing patterns existing in both FitParametersLinked.
-
-std::vector<std::string>
-FitParameter::patternIntersection(const FitParameter& other) const
-{
-    std::set<std::string> set1(m_patterns.begin(), m_patterns.end());
-    std::set<std::string> set2(other.m_patterns.begin(), other.m_patterns.end());
-    std::vector<std::string> intersection;
-    std::set_intersection(set1.begin(), set1.end(), set2.begin(), set2.end(),
-                          std::back_inserter(intersection));
-    return intersection;
-}
-
-//! Returns true if two FitParameterLinked are intended to steer same RealParameter.
-
-bool FitParameter::isConflicting(const FitParameter& other) const
-{
-    if(patternIntersection(other).size())
-        return true;
-
-    // analyze two pool of parameters and check if they are conflicting
-    bool isConflicting(false);
-    for (auto par1 : m_pool_parameters) {
-        for_each(other.m_pool_parameters.begin(), other.m_pool_parameters.end(),
-            [&](RealParameter* par2) { if (par1->hasSameData(*par2)) isConflicting = true;});
-    }
-    return isConflicting;
-}
-
-FitParameter::FitParameter(const FitParameter& other)
-    : IFitParameter(other)
-{
-    for (auto par : other.m_pool_parameters)
-        m_pool_parameters.push_back(par->clone());
-    m_patterns = other.m_patterns;
-}
-
-//! Returns true if clone of given RealParameter was already added.
-
-bool FitParameter::isLinked(const RealParameter& newPar)
-{
-    for (auto par : m_pool_parameters) {
-        if(par->getName() == newPar.getName() && par->hasSameData(newPar))
-            return true;
-
-        if(par->getName() != newPar.getName() && par->hasSameData(newPar))
-            throw std::runtime_error("FitParameterLinked::isLinked() -> Error. Different "
-                                     "parameter with same data.");
-
-        if(par->getName() == newPar.getName() && !par->hasSameData(newPar))
-            throw std::runtime_error("FitParameterLinked::isLinked() ->Error. Same parameter "
-                                     "name with different data.");
-    }
-
-    return  false;
-}
diff --git a/Core/Fitting/FitParameter.h b/Core/Fitting/FitParameter.h
deleted file mode 100644
index 60a8ffaf8866239c7d476de88eae7b9e44412e42..0000000000000000000000000000000000000000
--- a/Core/Fitting/FitParameter.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Fitting/FitParameter.h
-//! @brief     Defines class FitParameter.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef FITPARAMETER_H
-#define FITPARAMETER_H
-
-#include "IFitParameter.h"
-#include <vector>
-
-class ParameterPool;
-class RealParameter;
-
-//! Fittable parameter, linked to other parameters from pools.
-//! @ingroup fitting_internal
-
-class BA_CORE_API_ FitParameter : public IFitParameter
-{
-public:
-    FitParameter() {}
-    FitParameter(const std::string& pattern, double value,
-                 const AttLimits& lim = AttLimits::limitless(), double step = 0.0);
-    FitParameter(double value, const AttLimits& lim = AttLimits::limitless(), double step = 0.0);
-    ~FitParameter() final;
-
-    FitParameter* clone() const;
-
-    void setValue(double value) final;
-
-    FitParameter& addPattern(const std::string& pattern);
-
-    void addParameter(const RealParameter& par);
-
-    void addMatchedParameters(const ParameterPool& pool);
-
-    std::vector<std::string> patterns() const;
-
-    std::vector<std::string> matchedParameterNames() const;
-
-    std::vector<std::string> patternIntersection(const FitParameter& other) const;
-
-    bool isConflicting(const FitParameter& other) const;
-
-private:
-    FitParameter(const FitParameter& other);
-    bool isLinked(const RealParameter& newPar);
-    std::vector<RealParameter*> m_pool_parameters; //!< linked parameters from pools
-    std::vector<std::string> m_patterns;           //!< list of patterns to match from pool
-};
-
-#endif // FITPARAMETER_H
diff --git a/Core/Fitting/FitParameterSet.cpp b/Core/Fitting/FitParameterSet.cpp
deleted file mode 100644
index 59799b46258c6b49866e695cf3abaf0ccf2a281d..0000000000000000000000000000000000000000
--- a/Core/Fitting/FitParameterSet.cpp
+++ /dev/null
@@ -1,284 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Fit/Parameters/FitParameterSet.cpp
-//! @brief     Implements class FitParameterSet.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "FitParameterSet.h"
-#include "IFitParameter.h"
-#include "MinimizerUtils.h"
-#include "Parameters.h"
-#include <cmath>
-#include <iostream>
-#include <sstream>
-#include <stdexcept>
-
-FitParameterSet::~FitParameterSet()
-{
-    clear();
-}
-
-//! Clears all defined parameters.
-
-void FitParameterSet::clear()
-{
-    for (auto par: m_parameters)
-        delete par;
-    m_parameters.clear();
-}
-
-//! Returns number of parameters.
-
-size_t FitParameterSet::size() const
-{
-    return m_parameters.size();
-}
-
-//! Container iterators.
-
-FitParameterSet::iterator FitParameterSet::begin()
-{
-    return m_parameters.begin();
-}
-
-FitParameterSet::const_iterator FitParameterSet::begin() const
-{
-    return m_parameters.begin();
-}
-
-FitParameterSet::iterator FitParameterSet::end()
-{
-    return m_parameters.end();
-}
-
-FitParameterSet::const_iterator FitParameterSet::end() const
-{
-    return m_parameters.end();
-}
-
-//! Adds fit parameter.
-
-void FitParameterSet::addFitParameter(IFitParameter* par)
-{
-    for (auto fitPar: m_parameters)
-        if(fitPar == par)
-            throw std::runtime_error("FitParameterSet::addFitParameter() -> Error. Attempt to add "
-                                     "same fit parameter twice.");
-
-    if(par->name().empty())
-        par->setName(suggestParameterName());
-
-    if(isExistingName(par->name()))
-        throw std::runtime_error("FitParameterSet::addFitParameter() -> Error. Parameter with "
-                                 "the name '"+par->name()+"' already exist.");
-
-    m_parameters.push_back(par);
-}
-
-//! Returns fit parameter by given name.
-
-const IFitParameter* FitParameterSet::fitParameter(const std::string& name) const
-{
-    for (auto par: m_parameters)
-        if (par->name() == name)
-            return par;
-    throw std::runtime_error("FitParameterSet::getFitParameter() -> "
-                             "Error. No parameter with name '"+name+"'");
-}
-
-IFitParameter* FitParameterSet::fitParameter(const std::string& name)
-{
-    return const_cast<IFitParameter*>(static_cast<const FitParameterSet*>(this)
-                                      ->fitParameter(name));
-}
-
-//! Indexed access to parameters.
-
-const IFitParameter* FitParameterSet::operator[](const std::string& name) const
-{
-    return fitParameter(name);
-}
-
-IFitParameter* FitParameterSet::operator[](const std::string& name)
-{
-    return const_cast<IFitParameter*>(static_cast<const FitParameterSet*>(this)
-                                      ->operator[](name));
-}
-
-const IFitParameter* FitParameterSet::operator[](size_t index) const
-{
-    return m_parameters[check_index(index)];
-}
-
-IFitParameter* FitParameterSet::operator[](size_t index)
-{
-    return const_cast<IFitParameter*>(static_cast<const FitParameterSet*>(this)
-                                      ->operator[](index));
-}
-
-//! Returns values of all defined parameters.
-
-std::vector<double> FitParameterSet::values() const
-{
-    std::vector<double> result;
-    for (auto par: m_parameters)
-        result.push_back(par->value());
-    return result;
-}
-
-//! Sets values for all defined parameters.
-
-void FitParameterSet::setValues(const std::vector<double>& pars_values)
-{
-    check_array_size(pars_values);
-
-    int index = 0;
-    for (auto par: m_parameters) {
-        if (std::isnan(pars_values[index]))
-            throw std::runtime_error("FitParameterSet::setValues() -> Error."
-                                     " Attempt to set nan '"+par->name() + std::string("'."));
-        if (std::isinf(pars_values[index]))
-            throw std::runtime_error("FitParameterSet::setValues() -> Error. Attempt to set inf '"+
-                                      par->name()  + std::string("'."));
-        par->setValue(pars_values[index]);
-        ++index;
-    }
-}
-
-//! Returns true if parameters already have the given values.
-
-bool FitParameterSet::valuesDifferFrom(const std::vector<double>& pars_values, double tol) const
-{
-    check_array_size(pars_values);
-
-    for (size_t i=0; i<m_parameters.size(); ++i)
-        if (MinimizerUtils::numbersDiffer(m_parameters[i]->value(), pars_values[i], tol))
-            return true;
-    return false;
-}
-
-//! Returns errors of all defined parameters.
-
-std::vector<double> FitParameterSet::errors() const
-{
-    std::vector<double> result;
-    for (auto par: m_parameters)
-        result.push_back(par->error());
-    return result;
-}
-
-//! Sets errors to all parameters.
-
-void FitParameterSet::setErrors(const std::vector<double>& pars_errors)
-{
-    check_array_size(pars_errors);
-
-    for (size_t i=0; i<m_parameters.size(); ++i)
-        m_parameters[i]->setError(pars_errors[i]);
-}
-
-//! Returns number of free parameters.
-
-size_t FitParameterSet::freeFitParameterCount() const
-{
-    size_t result(0);
-    for (auto par: m_parameters)
-        if (!par->limits().isFixed())
-            result++;
-    return result;
-}
-
-//! Fix all parameters.
-
-void FitParameterSet::fixAll()
-{
-    for (auto par: m_parameters)
-        par->limits().setFixed(true);
-}
-
-//! Release all parameters.
-
-void FitParameterSet::releaseAll()
-{
-    for (auto par: m_parameters)
-        par->limits().setFixed(false);
-}
-
-//! Set fixed flag for parameters from the list.
-
-void FitParameterSet::setFixed(const std::vector<std::string>& pars, bool is_fixed)
-{
-    for (auto par: pars)
-        fitParameter(par)->limits().setFixed(is_fixed);
-}
-
-//! Sets resulting correlation matrix.
-
-void FitParameterSet::setCorrelationMatrix(const FitParameterSet::corr_matrix_t& matrix)
-{
-    if(matrix.size() != size())
-        throw std::runtime_error("FitParameterSet::setCorrelationMatrix() -> Error. Wrong "
-                                 "dimension of correlation matrix.");
-    m_corr_matrix = matrix;
-}
-
-//! Refactoring temp: returns set of new fit parameters.
-
-Fit::Parameters FitParameterSet::fitParametersNewKernel() const
-{
-    Fit::Parameters result;
-
-    for (const auto par: m_parameters)
-        result.add(Fit::Parameter(par->name(), par->value(), par->limits(), par->step()));
-
-    return result;
-}
-
-//! Returns true if parameter with such name exists.
-
-bool FitParameterSet::isExistingName(const std::string& name) const
-{
-    for (auto par: m_parameters)
-        if (par->name() == name)
-            return true;
-    return false;
-}
-
-//! Returns parameter name basing on fixed prefix 'par' and number of parameters.
-
-std::string FitParameterSet::suggestParameterName() const
-{
-    return std::string("par")+std::to_string(m_parameters.size());
-}
-
-//! Checks if index corresponds with the number of fit parameters.
-
-size_t FitParameterSet::check_index(size_t index) const
-{
-    if (index >= m_parameters.size())
-        throw std::runtime_error(
-            "FitSuiteParameters::check_index() -> Index out of bounds");
-    return index;
-}
-
-//! Checks if size of input array corresponds to number of fit parameters,
-//! throws an exception if not.
-
-void FitParameterSet::check_array_size(const std::vector<double>& values) const
-{
-    if (values.size() != m_parameters.size()) {
-        std::ostringstream ostr;
-        ostr << "FitParameterSet::check_array_size() -> Error. Size of inpout array "
-             << values.size() << ", doesn't mach number of fit parameters "
-             << m_parameters.size() << std::endl;
-        throw std::runtime_error(ostr.str());
-    }
-}
diff --git a/Core/Fitting/FitParameterSet.h b/Core/Fitting/FitParameterSet.h
deleted file mode 100644
index f1ad2188ec40134fad42a62f1e90b64536637d66..0000000000000000000000000000000000000000
--- a/Core/Fitting/FitParameterSet.h
+++ /dev/null
@@ -1,87 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Fit/Parameters/FitParameterSet.h
-//! @brief     Defines class FitParameterSet.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef FITPARAMETERSET_H
-#define FITPARAMETERSET_H
-
-#include "WinDllMacros.h"
-#include <vector>
-#include <string>
-
-namespace Fit { class Parameters; }
-
-class IFitParameter;
-
-//! The set of fit parameters.
-//! @ingroup fitting_internal
-
-class BA_CORE_API_ FitParameterSet
-{
- public:
-    typedef std::vector<IFitParameter*> container_t;
-    typedef container_t::iterator iterator;
-    typedef container_t::const_iterator const_iterator;
-    typedef std::vector<std::vector<double>> corr_matrix_t;
-
-    FitParameterSet() {}
-    ~FitParameterSet();
-
-    void clear();
-    size_t size() const;
-    iterator begin();
-    const_iterator begin() const;
-    iterator end();
-    const_iterator end() const;
-
-    void addFitParameter(IFitParameter* par);
-
-    // Access fit parameters
-
-    const IFitParameter* fitParameter(const std::string& name) const;
-    IFitParameter* fitParameter(const std::string& name);
-    const IFitParameter* operator[](const std::string& name) const;
-    IFitParameter* operator[](const std::string& name);
-    const IFitParameter* operator[](size_t index) const;
-    IFitParameter* operator[](size_t index);
-
-    // Fit parameter's values and errors
-
-    std::vector<double> values() const;
-    void setValues(const std::vector<double>& pars_values);
-    bool valuesDifferFrom(const std::vector<double>& par_values, double tolerance = 2.0) const;
-    std::vector<double> errors() const;
-    void setErrors(const std::vector<double>& pars_errors);
-
-    // Make parameters fixed and free
-
-    size_t freeFitParameterCount() const;
-    void fixAll();
-    void releaseAll();
-    void setFixed(const std::vector<std::string>& pars, bool is_fixed);
-
-    corr_matrix_t correlationMatrix() const { return m_corr_matrix; }
-    void setCorrelationMatrix(const corr_matrix_t& matrix);
-
-    Fit::Parameters fitParametersNewKernel() const;
-
-private:
-    bool isExistingName(const std::string& name) const;
-    std::string suggestParameterName() const;
-    size_t check_index(size_t index) const;
-    void check_array_size(const std::vector<double>& values) const;
-    container_t m_parameters; //!< collection of fit parameters
-    corr_matrix_t m_corr_matrix; //!< correlation matrix
-};
-
-#endif // FITPARAMETERSET_H
diff --git a/Core/Fitting/FitPrintService.cpp b/Core/Fitting/FitPrintService.cpp
index 4fa13ceab6a15a6fdbd4fdc6122ef7fce70454f8..8374ca8c5936f57cd520b78a2bf14cb987f6114d 100644
--- a/Core/Fitting/FitPrintService.cpp
+++ b/Core/Fitting/FitPrintService.cpp
@@ -41,7 +41,7 @@ void FitPrintService::print(const FitObjective& objective)
 {
     std::ostringstream ostr;
 
-    if (objective.iterationInfo().iterationCount() == 0) {
+    if (objective.isFirstIteration()) {
         m_run_time.start();
         m_last_call_time.start();
     }
diff --git a/Core/Fitting/FitStatus.cpp b/Core/Fitting/FitStatus.cpp
index c967980b11f2e907af57813c005e5051cbe512c1..eed8bb0dfba183aa94c60f6e8bc1879eacf41e2e 100644
--- a/Core/Fitting/FitStatus.cpp
+++ b/Core/Fitting/FitStatus.cpp
@@ -43,7 +43,7 @@ bool FitStatus::isCompleted() const
 
 void FitStatus::update(const Fit::Parameters& params, double chi2)
 {
-    m_fit_status = RUNNING;
+    if (!isInterrupted()) m_fit_status = RUNNING;
 
     m_iterationInfo.update(params, chi2);
 
diff --git a/Core/Fitting/FitStrategyAdjustParameters.cpp b/Core/Fitting/FitStrategyAdjustParameters.cpp
deleted file mode 100644
index 21d1f23e899c44ed048ce24ba43380af6a777ef3..0000000000000000000000000000000000000000
--- a/Core/Fitting/FitStrategyAdjustParameters.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Fitting/FitStrategyAdjustParameters.cpp
-//! @brief     Implements class FitStrategyAdjustParameters.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "FitStrategyAdjustParameters.h"
-#include "FitSuiteImpl.h"
-#include "IFitParameter.h"
-#include "FitParameterSet.h"
-#include "Exceptions.h"
-
-FitStrategyAdjustParameters::FitStrategyAdjustParameters(const FitStrategyAdjustParameters &other)
-    : IFitStrategy(other)
-    , m_fix_all(other.m_fix_all)
-    , m_release_all(other.m_release_all)
-    , m_pars_to_fix(other.m_pars_to_fix)
-    , m_pars_to_release(other.m_pars_to_release)
-    , m_preserve_original_values(other.m_preserve_original_values)
-{
-}
-
-//! strategy which fixes/releases fit parameters and then call minimizer
-void FitStrategyAdjustParameters::execute()
-{
-    if( !m_kernel )
-        throw Exceptions::NullPointerException(
-            "FitSuiteStrategyAdjustParameters::execute() -> FitSuite doesn't exists");
-    FitParameterSet* fitParameters = m_kernel->fitParameters();
-
-    // fixing all parameters at they current values
-    if( m_fix_all ) {
-        for(auto par: *fitParameters)
-            par->limits().setFixed(true);
-    }
-
-    // releasing all parameters
-    if( m_release_all ) {
-        for(auto par: *fitParameters) {
-            par->limits().setFixed(false);
-        }
-    }
-
-    // fixing dedicated list of fit parameters
-    for(auto name: m_pars_to_fix) {
-        fitParameters->fitParameter(name)->limits().setFixed(true);
-    }
-
-    // releasing dedicated list of fit parameters
-    for(auto name: m_pars_to_release) {
-        fitParameters->fitParameter(name)->limits().setFixed(false);
-    }
-
-    // saving original param values
-    std::vector<double> original_param_values = fitParameters->values();
-
-    // calling minimization
-    m_kernel->minimize();
-
-    // returning parameters to original values as they were before minimization
-    if(m_preserve_original_values)
-        fitParameters->setValues(original_param_values);
-}
diff --git a/Core/Fitting/FitStrategyAdjustParameters.h b/Core/Fitting/FitStrategyAdjustParameters.h
deleted file mode 100644
index 4c68feebbbd062868f525e5ae65cd0efecf660d9..0000000000000000000000000000000000000000
--- a/Core/Fitting/FitStrategyAdjustParameters.h
+++ /dev/null
@@ -1,134 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Fitting/FitStrategyAdjustParameters.h
-//! @brief     Defines classes FitStrategyAdjustParameters and related
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef FITSTRATEGYADJUSTPARAMETERS_H
-#define FITSTRATEGYADJUSTPARAMETERS_H
-
-#include "IFitStrategy.h"
-#include <vector>
-
-//! Strategy which fixes/releases fit parameters and call minimizer.
-//! @ingroup fitting
-
-class BA_CORE_API_ FitStrategyAdjustParameters : public IFitStrategy
-{
-public:
-    FitStrategyAdjustParameters(const std::string& name) : IFitStrategy(name) { clear(); }
-
-    FitStrategyAdjustParameters() : IFitStrategy("FitSuiteStrategyAdjustParameters") { clear(); }
-
-    virtual ~FitStrategyAdjustParameters(){}
-
-    virtual FitStrategyAdjustParameters* clone() const {
-        return new FitStrategyAdjustParameters(*this); }
-
-    virtual void execute();
-
-    virtual FitStrategyAdjustParameters& fix_all() {
-        m_fix_all = true; return *this; }
-
-    virtual FitStrategyAdjustParameters& release_all() {
-        m_release_all = true; return *this; }
-
-    virtual FitStrategyAdjustParameters& fix(std::string parname ) {
-        m_pars_to_fix.push_back(parname);
-        return *this; }
-
-    virtual FitStrategyAdjustParameters& release(std::string parname ) {
-        m_pars_to_release.push_back(parname);
-        return *this; }
-
-    virtual void setPreserveOriginalValues(bool preserve_values) {
-        m_preserve_original_values = preserve_values; }
-
-    virtual void clear() {
-        m_fix_all = false;
-        m_release_all = false;
-        m_preserve_original_values = false;
-        m_pars_to_fix.clear();
-        m_pars_to_release.clear(); }
-
-protected:
-    FitStrategyAdjustParameters(const FitStrategyAdjustParameters& other);
-
-    bool m_fix_all;
-    bool m_release_all;
-    std::vector<std::string> m_pars_to_fix;
-    std::vector<std::string> m_pars_to_release;
-    //! if it's true, strategy will set back values of parameters as they were
-    //! before minimization round
-    bool m_preserve_original_values;
-};
-
-
-//! Strategy which fixes certain fit parameters leaving other released.
-//! @ingroup fitting
-
-class BA_CORE_API_ FitStrategyFixParameters : public FitStrategyAdjustParameters
-{
-public:
-    FitStrategyFixParameters() : FitStrategyAdjustParameters("FixStrategyFixParameters") {
-        m_fix_all = false;
-        m_release_all = true; }
-
-    FitStrategyFixParameters(const std::vector<std::string> &pars)
-        : FitStrategyAdjustParameters("FixStrategyFixParameters") {
-        m_fix_all = false;
-        m_release_all = true;
-        setFixed(pars);  }
-
-    virtual ~FitStrategyFixParameters(){}
-    virtual FitStrategyFixParameters *clone() const { return new FitStrategyFixParameters(*this); }
-
-    virtual void clear() {
-        FitStrategyAdjustParameters::clear();
-        m_release_all = true; }
-
-    virtual void setFixed(const std::vector<std::string> &pars) { m_pars_to_fix = pars; }
-
-};
-
-
-//! Strategy which releases certain fit parameters leaving other fixed.
-//! @ingroup fitting
-
-class BA_CORE_API_ FitStrategyReleaseParameters : public FitStrategyAdjustParameters
-{
-public:
-    FitStrategyReleaseParameters()
-        : FitStrategyAdjustParameters("FixStrategyReleaseParameters")
-    {
-        m_fix_all = true;
-        m_release_all = false;
-    }
-
-    FitStrategyReleaseParameters(const std::vector<std::string> &pars)
-        : FitStrategyAdjustParameters("FixStrategyReleaseParameters") {
-        m_fix_all = true;
-        m_release_all = false;
-        setReleased(pars); }
-
-
-    virtual ~FitStrategyReleaseParameters(){}
-    virtual FitStrategyReleaseParameters* clone() const {
-        return new FitStrategyReleaseParameters(*this); }
-
-    virtual void clear() {
-        FitStrategyAdjustParameters::clear();
-        m_fix_all = true; }
-
-    virtual void setReleased(const std::vector<std::string>& pars) { m_pars_to_release = pars; }
-};
-
-#endif // FITSTRATEGYADJUSTPARAMETERS_H
diff --git a/Core/Fitting/FitSuite.cpp b/Core/Fitting/FitSuite.cpp
deleted file mode 100644
index 0c225d88b27781c90ac38fe36556e175422803a5..0000000000000000000000000000000000000000
--- a/Core/Fitting/FitSuite.cpp
+++ /dev/null
@@ -1,224 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Fitting/FitSuite.cpp
-//! @brief     Implements class FitSuite.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "FitSuite.h"
-#include "FitSuiteImpl.h"
-#include "FitSuitePrintObserver.h"
-#include "IHistogram.h"
-#include "MinimizerFactory.h"
-#include "ParameterPool.h"
-#include <iostream>
-
-FitSuite::FitSuite()
-    : m_impl(new FitSuiteImpl(std::bind(&FitSuite::notifyObservers, this)))
-{
-}
-
-FitSuite::~FitSuite()
-{}
-
-void FitSuite::addSimulationAndRealData(const Simulation& simulation,
-                                        const OutputData<double>& real_data, double weight)
-{
-    m_impl->addSimulationAndRealData(simulation, real_data, weight);
-}
-
-void FitSuite::addSimulationAndRealData(const Simulation& simulation,
-                                        const IHistogram& real_data, double weight)
-{
-    const std::unique_ptr<OutputData<double>> data(real_data.createOutputData());
-    m_impl->addSimulationAndRealData(simulation, *data, weight);
-}
-
-void FitSuite::addSimulationAndRealData(const Simulation& simulation,
-                              const std::vector<std::vector<double>>& real_data,
-                              double weight)
-{
-    // TODO: provide a way to construct OutputData<double> right from numpy array
-    std::unique_ptr<IHistogram> data(IHistogram::createFrom(real_data));
-    addSimulationAndRealData(simulation, *data, weight);
-}
-
-void FitSuite::addSimulationAndRealData(const Simulation& simulation,
-                                        const std::vector<double>& real_data,
-                                        double weight)
-{
-    const size_t data_size = real_data.size();
-    if (data_size == 0)
-        throw std::runtime_error("Error in FitSuite::addSimulationAndRealData: real_data array"
-                                 "is of zero size.");
-    std::unique_ptr<OutputData<double>> data_container(new OutputData<double>);
-    data_container->addAxis("x-axis", data_size, 0.0, static_cast<double>(data_size - 1));
-    for (size_t i = 0; i < data_size; ++i)
-        (*data_container)[i] = real_data[i];
-    addSimulationAndRealData(simulation, *data_container, weight);
-}
-
-FitParameter *FitSuite::addFitParameter(const std::string& pattern, double value,
-                               const AttLimits& limits, double step)
-{
-    return m_impl->addFitParameter(pattern, value, limits, step);
-}
-
-FitParameter* FitSuite::addFitParameter(const FitParameter& fitPar)
-{
-    return m_impl->addFitParameter(fitPar);
-}
-
-void FitSuite::setMinimizer(const std::string& minimizer_name, const std::string& algorithm_name,
-                            const std::string& minimizer_options)
-{
-    IMinimizer* minimizer = MinimizerFactory::createMinimizer(minimizer_name, algorithm_name,
-                                                              minimizer_options);
-    m_impl->setMinimizer(minimizer);
-}
-
-void FitSuite::setChiSquaredModule(const IChiSquaredModule& chi2_module)
-{
-    m_impl->fitObjects()->setChiSquaredModule(chi2_module);
-}
-
-void FitSuite::addFitStrategy(const IFitStrategy& strategy)
-{
-    m_impl->addFitStrategy(strategy);
-}
-
-void FitSuite::setMinimizer(IMinimizer* minimizer)
-{
-    m_impl->setMinimizer(minimizer);
-}
-
-std::string FitSuite::minimizerName() const
-{
-    // FIXME
-    return std::string("FIXME");
-}
-
-//const IMinimizer *FitSuite::minimizer() const
-//{
-//    return m_impl->kernel()->minimizer();
-//}
-
-void FitSuite::initPrint(int print_every_nth)
-{
-    std::shared_ptr<FitSuitePrintObserver> observer(new FitSuitePrintObserver(print_every_nth));
-    attachObserver(observer);
-}
-
-void FitSuite::runFit()
-{
-    m_impl->runFit();
-}
-
-size_t FitSuite::numberOfFitObjects() const
-{
-    return m_impl->fitObjects()->size();
-}
-
-std::string FitSuite::parametersToString() const
-{
-    return m_impl->fitObjects()->parametersToString();
-}
-
-std::string FitSuite::treeToString() const
-{
-    return m_impl->fitObjects()->treeToString();
-}
-
-std::string FitSuite::setupToString()
-{
-    return m_impl->setupToString();
-}
-
-FitSuiteObjects* FitSuite::fitObjects()
-{
-    return m_impl->fitObjects();
-}
-
-FitParameterSet* FitSuite::fitParameters()
-{
-    return m_impl->fitParameters();
-}
-
-FitSuiteStrategies* FitSuite::fitStrategies()
-{
-    return m_impl->fitStrategies();
-}
-
-bool FitSuite::isFirstIteration() const
-{
-    // FIXME temporary method: before refactoring first iteration had index 0
-    return m_impl->numberOfIterations() == 1;
-}
-
-bool FitSuite::isLastIteration() const
-{
-    return m_impl->isLastIteration();
-}
-
-size_t FitSuite::numberOfIterations() const
-{
-    return m_impl->numberOfIterations();
-}
-
-size_t FitSuite::currentStrategyIndex() const
-{
-    return m_impl->currentStrategyIndex();
-}
-
-void FitSuite::printResults() const
-{
-    std::cout <<reportResults() << std::endl;
-}
-
-std::string FitSuite::reportResults() const
-{
-    return m_impl->reportResults();
-}
-
-double FitSuite::getChi2() const
-{
-    return m_impl->fitObjects()->getChiSquaredValue();
-}
-
-void FitSuite::interruptFitting()
-{
-    m_impl->interruptFitting();
-}
-
-void FitSuite::resetInterrupt()
-{
-    m_impl->resetInterrupt();
-}
-
-bool FitSuite::isInterrupted()
-{
-    return m_impl->isInterrupted();
-}
-
-SimulationResult FitSuite::simulationResult(size_t i_item) const
-{
-    return m_impl->fitObjects()->simulationResult(i_item);
-}
-
-SimulationResult FitSuite::experimentalData(size_t i_item) const
-{
-    return m_impl->fitObjects()->experimentalData(i_item);
-}
-
-SimulationResult FitSuite::relativeDifference(size_t i_item) const
-{
-    return m_impl->fitObjects()->relativeDifference(i_item);
-}
-
diff --git a/Core/Fitting/FitSuite.h b/Core/Fitting/FitSuite.h
deleted file mode 100644
index c2661c52fbcc9a4efda0caf3be5386e1c7725d66..0000000000000000000000000000000000000000
--- a/Core/Fitting/FitSuite.h
+++ /dev/null
@@ -1,180 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Fitting/FitSuite.h
-//! @brief     Defines class FitSuite.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef FITSUITE_H
-#define FITSUITE_H
-
-#include "IObserver.h"
-#include "OutputData.h"
-#include "AttLimits.h"
-#include "SimulationResult.h"
-#include <vector>
-
-class Simulation;
-class IHistogram;
-class IChiSquaredModule;
-class IFitStrategy;
-class FitSuiteObjects;
-class FitParameterSet;
-class FitSuiteStrategies;
-class FitOptions;
-class FitSuiteImpl;
-class IMinimizer;
-class FitParameter;
-
-//! @brief User interface class that wraps all fit methods.
-//! @ingroup fitting
-
-class BA_CORE_API_ FitSuite : public IObservable
-{
-public:
-    FitSuite();
-    FitSuite(const FitSuite&) = delete;
-    FitSuite& operator=(const FitSuite&) = delete;
-    ~FitSuite();
-
-    // ------------------------------------------------------------------------
-    // Fitting setup
-    // ------------------------------------------------------------------------
-
-    //! Assigns pair of (simulation, real data) for fitting. More than one pair can be added.
-    void addSimulationAndRealData(const Simulation& simulation,
-                                  const OutputData<double>& real_data, double weight=1);
-
-    //! Assigns pair of (simulation, real data) for fitting. More than one pair can be added.
-    void addSimulationAndRealData(const Simulation& simulation,
-                                  const IHistogram& real_data, double weight=1);
-
-    //! Assigns pair of (simulation, real data) for fitting. A version for the _real_data_
-    //! represented as a two-dimensional numpy array. Simulation output must agree in dimensions
-    //! with _real_data_.
-    void addSimulationAndRealData(const Simulation& simulation,
-                                  const std::vector<std::vector<double>>& real_data,
-                                  double weight=1);
-
-    //! Assigns pair of (simulation, real_data) for fitting. A version for the _real_data_
-    //! represented as a one-dimensional numpy array. Simulation output must agree in dimensions
-    //! with _real_data_.
-    void addSimulationAndRealData(const Simulation& simulation,
-                                  const std::vector<double>& real_data,
-                                  double weight = 1);
-
-    //! Adds fit parameter
-    //! @param name The name of sample parameter(s) to fit (may contain wildcards).
-    //! @param value Parameter's starting value
-    //! @param limits Limits attribute
-    //! @param step Initial parameter's step (some minimizers don't use it)
-    FitParameter* addFitParameter(const std::string& pattern, double value,
-                         const AttLimits& limits=AttLimits::limitless(), double step = 0.0);
-
-    //! Adds fit parameter
-    //! @param fitPar Fully constructed fit parameter.
-    FitParameter* addFitParameter(const FitParameter& fitPar);
-
-    //! Sets minimizer with given name and algorithm type
-    //! @param minimizer_name The name of the minimizer
-    //! @param algorithm_name Optional name of the minimizer's algorithm
-    //! @param minimizer_options Optional string with additional minimizer settings
-    void setMinimizer(const std::string& minimizer_name,
-                      const std::string& algorithm_name = std::string(),
-                      const std::string& minimizer_options=std::string());
-
-    //! Replaces default ChiSquaredModule with new one
-    void setChiSquaredModule(const IChiSquaredModule& chi2_module);
-
-    //! Adds fit strategy
-    void addFitStrategy(const IFitStrategy& strategy);
-
-    //! Sets minimizer
-    void setMinimizer(IMinimizer* minimizer);
-
-    //! Returns minimizer.
-//    const IMinimizer *minimizer() const;
-    std::string minimizerName() const;
-
-    //! Initializes printing to standard output during the fitting.
-    //! Prints also the summary when completed.
-    //! @param print_every_nth Print every n'th iteration
-    void initPrint(int print_every_nth);
-
-    //! main method to run the fitting
-    void runFit();
-
-    // ------------------------------------------------------------------------
-    // Access to the data
-    // ------------------------------------------------------------------------
-
-    //! Returns number of fit objects, where fit object stands for (real, simulated) pair.
-    size_t numberOfFitObjects() const;
-
-    //! returns FitObject (pair of simulation/real data)
-    FitSuiteObjects* fitObjects();
-
-    //! Returns reference to fit parameters
-    FitParameterSet* fitParameters();
-
-    //! Returns reference to fit parameters
-    FitSuiteStrategies* fitStrategies();
-
-    //! temporary method to check if it is first iteration
-    bool isFirstIteration() const;
-
-    //! if the last iteration is done (used by observers to print summary)
-    bool isLastIteration() const;
-
-    //! Returns current number of minimization function calls
-    size_t numberOfIterations() const;
-
-    //! Returns the number of current strategy
-    size_t currentStrategyIndex() const;
-
-    //! Prints results of the minimization to the standard output.
-    void printResults() const;
-
-    //! Reports results of minimization in the form of multi-line string.
-    std::string reportResults() const;
-
-    //! Returns minimum chi squared value found
-    double getChi2() const;
-
-    void interruptFitting();
-    void resetInterrupt();
-    bool isInterrupted();
-
-    //! Returns multiline string representing possible fit parameters.
-    std::string parametersToString() const;
-
-    //! Returns multiline string representing tree structure of fit components.
-    std::string treeToString() const;
-
-    //! Returns multiline string representing fit setup
-    std::string setupToString();
-
-    //! Returns simulation result.
-    //! @param i_item: the index of fit pair
-    SimulationResult simulationResult(size_t i_item = 0) const;
-
-    //! Returns experimental data.
-    //! @param i_item: the index of fit pair
-    SimulationResult experimentalData(size_t i_item = 0) const;
-
-    //! Returns relative difference between simulation and experimental data.
-    //! @param i_item: the index of fit pair
-    SimulationResult relativeDifference(size_t i_item = 0) const;
-
-private:
-    std::unique_ptr<FitSuiteImpl> m_impl;
-};
-
-#endif // FITSUITE_H
diff --git a/Core/Fitting/FitSuiteImpl.cpp b/Core/Fitting/FitSuiteImpl.cpp
deleted file mode 100644
index 97d4f4691ec1e99b315c4d1fa4c6e772c568f39b..0000000000000000000000000000000000000000
--- a/Core/Fitting/FitSuiteImpl.cpp
+++ /dev/null
@@ -1,227 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Fitting/FitSuiteImpl.cpp
-//! @brief     Implements class FitSuiteImpl.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "FitSuiteImpl.h"
-#include "RealLimits.h"
-#include "FitParameter.h"
-#include "MinimizerFactory.h"
-#include "ParameterPool.h"
-#include "IMinimizer.h"
-#include "FitSuiteUtils.h"
-#include "Minimizer.h"
-#include "MinimizerConstants.h"
-#include <stdexcept>
-
-
-FitSuiteImpl::FitSuiteImpl(const std::function<void()>& notifyObservers)
-    : m_is_last_iteration(false)
-    , m_is_interrupted(false)
-    , m_notifyObservers(notifyObservers)
-    , m_new_kernel(new Fit::Minimizer)
-    , m_iteration_count(0)
-    , m_is_gradient_based(false)
-{
-    m_fit_strategies.init(this);
-}
-
-FitSuiteImpl::~FitSuiteImpl()
-{
-    clear();
-}
-
-//! Clears all data.
-void FitSuiteImpl::clear()
-{
-    m_fit_objects.clear();
-    m_fit_strategies.clear();
-    m_is_last_iteration = false;
-    m_is_interrupted = false;
-}
-
-//! Adds pair of (simulation, real data) for consecutive simulation
-FitObject* FitSuiteImpl::addSimulationAndRealData(const Simulation& simulation,
-                                         const OutputData<double>& real_data, double weight)
-{
-    return m_fit_objects.add(simulation, real_data, weight);
-}
-
-//! Adds fit parameter, step is calculated from initial parameter value
-FitParameter* FitSuiteImpl::addFitParameter(const std::string& pattern, double value,
-                                  const AttLimits& limits, double step)
-{
-    if(step <=0.0)
-        step = value * getOptions().stepFactor();
-
-    FitParameter* result = new FitParameter(pattern, value, limits, step);
-    fitParameters()->addFitParameter(result);
-    return result;
-}
-
-FitParameter* FitSuiteImpl::addFitParameter(const FitParameter& fitPar)
-{
-    FitParameter* result = fitPar.clone();
-    if(result->step() <= 0.0)
-        result->setStep(result->value() * getOptions().stepFactor());
-
-    fitParameters()->addFitParameter(result);
-    return result;
-}
-
-void FitSuiteImpl::addFitStrategy(const IFitStrategy& strategy)
-{
-    m_fit_strategies.addStrategy(strategy);
-}
-
-void FitSuiteImpl::setMinimizer(IMinimizer* minimizer)
-{
-    if (minimizer->algorithmName() == AlgorithmNames::Fumili)
-        m_is_gradient_based = true;
-
-    if (minimizer->minimizerName() == MinimizerNames::GSLLMA)
-        m_is_gradient_based = true;
-
-    m_new_kernel->setMinimizer(minimizer);
-}
-
-void FitSuiteImpl::runFit()
-{
-    // check if all prerequisites are fullfilled before starting minimization
-    check_prerequisites();
-
-    m_is_last_iteration = false;
-
-    // link fit parameters with parameters defined in the simulation
-    link_fit_parameters();
-
-    // run minimization using strategies
-    m_fit_strategies.minimize();
-
-    // call observers to let them to get results
-    m_is_last_iteration = true;
-    notifyObservers();
-}
-
-void FitSuiteImpl::minimize()
-{
-    fcn_scalar_t scalar_fcn =
-        [&] (const Fit::Parameters& pars) {return scalar_func_new_kernel(pars);};
-
-    fcn_residual_t residual_fcn =
-            [&] (const Fit::Parameters& pars) {return residual_func_new_kernel(pars);};
-
-    m_fit_objects.setNfreeParameters((int)fitParameters()->freeFitParameterCount());
-
-    Fit::Parameters pars = fitParameters()->fitParametersNewKernel();
-
-    if (m_is_gradient_based)
-        m_minimizerResult = m_new_kernel->minimize(residual_fcn, pars);
-    else
-        m_minimizerResult = m_new_kernel->minimize(scalar_fcn, pars);
-
-    m_fit_parameters.setValues(m_minimizerResult.parameters().values());
-}
-
-
-FitParameterSet* FitSuiteImpl::fitParameters() {
-    return &m_fit_parameters;
-}
-
-// get current number of minimization function calls
-size_t FitSuiteImpl::numberOfIterations() const
-{
-    return m_iteration_count;
-}
-
-size_t FitSuiteImpl::currentStrategyIndex() const
-{
-    return m_fit_strategies.currentStrategyIndex();
-}
-
-std::string FitSuiteImpl::reportResults() const
-{
-    return m_minimizerResult.toString();
-}
-
-// method is not const because we have to link fit parameters with the sample,
-// to know what is going to be fitted
-std::string FitSuiteImpl::setupToString()
-{
-    check_prerequisites();
-    link_fit_parameters();
-    std::stringstream result;
-    result << FitSuiteUtils::fitParameterSettingsToString(*fitParameters());
-    return result.str();
-}
-
-bool FitSuiteImpl::check_prerequisites() const
-{
-    if( !m_fit_objects.size() ) throw Exceptions::LogicErrorException(
-        "FitSuite::check_prerequisites() -> Error! No simulation/data description defined");
-    if( m_fit_objects.getSizeOfDataSet() == 0) throw Exceptions::LogicErrorException(
-        "FitSuite::check_prerequisites() -> Error! No elements to fit. "
-        "Looks like whole detector is masked.");
-    return true;
-}
-
-//! link FitMultiParameters with simulation parameters
-void FitSuiteImpl::link_fit_parameters()
-{
-    std::unique_ptr<ParameterPool> pool(m_fit_objects.createParameterTree());
-    auto parameters = FitSuiteUtils::linkedParameters(*fitParameters());
-
-    if(parameters.empty())
-        throw Exceptions::RuntimeErrorException("No fit Parameters defined.");
-
-    for (auto par: parameters)
-        par->addMatchedParameters(*pool);
-
-    if(FitSuiteUtils::hasConflicts(*fitParameters())) {
-        std::ostringstream message;
-        message << "FitSuite::runFit() -> Error. Fit parameters are conflicting with each other, "
-                << "meaning that one sample parameter can be controlled by "
-                << "two different fit parameters.\n";
-        message << FitSuiteUtils::fitParameterSettingsToString(*fitParameters());
-        throw Exceptions::RuntimeErrorException(message.str());
-    }
-
-}
-
-//! Refactoring temp: new minimizer's objective functions.
-
-double FitSuiteImpl::scalar_func_new_kernel(const Fit::Parameters& fit_pars)
-{
-    if (isInterrupted())
-        throw std::runtime_error("Fitting was interrupted by the user.");
-
-    ++m_iteration_count;
-    fitParameters()->setValues(fit_pars.values());
-    fitObjects()->runSimulations();
-    double chi_squared = fitObjects()->getChiSquaredValue();
-    notifyObservers();
-    return chi_squared;
-}
-
-std::vector<double> FitSuiteImpl::residual_func_new_kernel(const Fit::Parameters& fit_pars)
-{
-    if (isInterrupted())
-        throw std::runtime_error("Fitting was interrupted by the user.");
-
-    ++m_iteration_count;
-
-    fitParameters()->setValues(fit_pars.values());
-    fitObjects()->runSimulations();
-    notifyObservers();
-
-    return fitObjects()->residuals();
-}
diff --git a/Core/Fitting/FitSuiteImpl.h b/Core/Fitting/FitSuiteImpl.h
deleted file mode 100644
index 9b8aa80a4b4a41782d38ab2309de9ddd08470c0d..0000000000000000000000000000000000000000
--- a/Core/Fitting/FitSuiteImpl.h
+++ /dev/null
@@ -1,135 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Fitting/FitSuiteImpl.h
-//! @brief     Defines class FitSuiteImpl.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef FITSUITEIMPL_H
-#define FITSUITEIMPL_H
-
-#include "FitOptions.h"
-#include "FitSuiteObjects.h"
-#include "FitParameterSet.h"
-#include "FitSuiteStrategies.h"
-#include "KernelTypes.h"
-#include "Parameters.h"
-#include "MinimizerResult.h"
-#include <functional>
-#ifndef SWIG
-#include <atomic>
-#endif
-
-class AttLimits;
-class Simulation;
-class IMinimizer;
-class FitParameter;
-
-namespace Fit { class Minimizer; }
-
-//! Fitting kernel for FitSuite.
-//! @ingroup fitting_internal
-
-class BA_CORE_API_ FitSuiteImpl
-{
- public:
-    FitSuiteImpl(const std::function<void()>& notifyObservers);
-    FitSuiteImpl& operator=(const FitSuiteImpl&) = delete;
-    FitSuiteImpl(const FitSuiteImpl&) = delete;
-    virtual ~FitSuiteImpl();
-
-    //! Resets most state variables, to get prepared for the next fit
-    void clear();
-
-    //! Adds pair of (simulation, real data) for consecutive simulation
-    FitObject* addSimulationAndRealData(const Simulation& simulation,
-                                  const OutputData<double>& real_data,
-                                  double weight);
-
-    //! Adds fit parameter
-    FitParameter* addFitParameter(const std::string& pattern, double value,
-                                        const AttLimits& limits, double step = 0.0);
-
-    //! Adds fit parameter
-    FitParameter* addFitParameter(const FitParameter& fitPar);
-
-    //! Adds fit strategy
-    void addFitStrategy(const IFitStrategy& strategy);
-
-    //! Sets minimizer
-    void setMinimizer(IMinimizer* minimizer);
-
-    //! Runs a fit, which may consist of several minimization rounds
-    virtual void runFit();
-
-    //! Runs a single minimization round (called by FitSuiteStrategy)
-    void minimize();
-
-    //! Returns reference to the kit with data
-    FitSuiteObjects* fitObjects() { return &m_fit_objects; }
-    const FitSuiteObjects* fitObjects() const { return &m_fit_objects; }
-
-    //! Returns reference to fit parameters
-    FitParameterSet* fitParameters();
-
-    //! Returns reference to fit parameters
-    FitSuiteStrategies* fitStrategies() { return &m_fit_strategies; }
-
-    //! Returns true if the last iteration is done (used by observers to print summary)
-    bool isLastIteration() const { return m_is_last_iteration; }
-
-    //! Returns current number of minimization function calls
-    size_t numberOfIterations() const;
-
-    //! Returns the number of current strategy
-    size_t currentStrategyIndex() const;
-
-    //! Reports results of minimization in the form of multi-line string.
-    std::string reportResults() const;
-
-    //! Returns current fit options
-    FitOptions& getOptions() { return m_fit_options; }
-
-    //! Sets fit options
-    void setOptions(const FitOptions& fit_options) { m_fit_options = fit_options; }
-
-    void notifyObservers() { m_notifyObservers(); }
-
-    void interruptFitting() { m_is_interrupted = true; }
-    void resetInterrupt() { m_is_interrupted = false; }
-    bool isInterrupted() const { return m_is_interrupted; }
-
-    //! Returns multiline string representing fit setup
-    std::string setupToString();
-
-private:
-    bool check_prerequisites() const;
-    void link_fit_parameters();
-
-    double scalar_func_new_kernel(const Fit::Parameters& fit_pars);
-    std::vector<double> residual_func_new_kernel(const Fit::Parameters& fit_pars);
-
-    FitOptions m_fit_options;
-    FitSuiteObjects m_fit_objects;
-    FitSuiteStrategies m_fit_strategies;
-    bool m_is_last_iteration;
-#ifndef SWIG
-    std::atomic<bool> m_is_interrupted;
-#endif
-    std::function<void()> m_notifyObservers;
-    std::unique_ptr<Fit::Minimizer> m_new_kernel;
-    size_t m_iteration_count;
-    Fit::MinimizerResult m_minimizerResult;
-    FitParameterSet m_fit_parameters;
-    bool m_is_gradient_based;
-
-};
-
-#endif // FITSUITEIMPL_H
diff --git a/Core/Fitting/FitSuiteObjects.cpp b/Core/Fitting/FitSuiteObjects.cpp
deleted file mode 100644
index ffe803df94d780dbe596fbf7b365a78cc74d76c1..0000000000000000000000000000000000000000
--- a/Core/Fitting/FitSuiteObjects.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Fitting/FitSuiteObjects.cpp
-//! @brief     Implements class FitSuiteObjects.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "FitSuiteObjects.h"
-#include "ChiSquaredModule.h"
-#include "Histogram2D.h"
-#include "Numeric.h"
-
-static_assert(std::is_copy_constructible<FitSuiteObjects>::value == false,
-    "FitSuiteObjects should not be copy constructable");
-static_assert(std::is_copy_assignable<FitSuiteObjects>::value == false,
-    "FitSuiteObjects should not be copy assignable");
-
-FitSuiteObjects::FitSuiteObjects()
-  : m_total_weight(0)
-   ,m_nfree_parameters(0)
-  , m_chi_squared_value(0)
-  , m_chi2_module(new ChiSquaredModule())
-  , m_fit_elements_count(0)
-{
-    setName("FitSuite"); // deliberately made as in FitSuite
-    init_parameters();
-}
-
-FitSuiteObjects::~FitSuiteObjects()
-{
-}
-
-FitObject* FitSuiteObjects::add(
-    const Simulation& simulation, const OutputData<double>& real_data, double weight)
-{
-    m_total_weight += weight;
-    FitObject *result = new FitObject(simulation, real_data, weight);
-    registerChild(result);
-    m_fit_elements_count += result->numberOfFitElements();
-    m_fit_objects.push_back(result);
-    return result;
-}
-
-//! Returns total number of data points
-size_t FitSuiteObjects::getSizeOfDataSet() const
-{
-    return m_fit_elements_count;
-}
-
-void FitSuiteObjects::setChiSquaredModule(const IChiSquaredModule& chi2_module)
-{
-    m_chi2_module.reset(chi2_module.clone());
-}
-
-SimulationResult FitSuiteObjects::simulationResult(size_t i_item) const
-{
-    return m_fit_objects[check_index(i_item)]->simulationResult();
-}
-
-SimulationResult FitSuiteObjects::experimentalData(size_t i_item) const
-{
-    return m_fit_objects[check_index(i_item)]->experimentalData();
-}
-
-SimulationResult FitSuiteObjects::relativeDifference(size_t i_item) const
-{
-    return m_fit_objects[check_index(i_item)]->relativeDifference();
-}
-
-//! loop through all defined simulations and run them
-void FitSuiteObjects::runSimulations()
-{
-    if(getSizeOfDataSet() == 0) {
-        std::ostringstream message;
-        message << "FitSuiteObjects::runSimulations() -> Error. Zero size of dataset.";
-        throw Exceptions::LogicErrorException(message.str());
-    }
-
-    m_fit_elements.clear();
-    m_fit_elements.reserve(getSizeOfDataSet());
-
-    for(auto it = m_fit_objects.begin(); it!= m_fit_objects.end(); ++it)
-        (*it)->prepareFitElements(m_fit_elements, (*it)->weight()/m_total_weight,
-                                  m_chi2_module->getIntensityNormalizer());
-
-    if(m_fit_elements.size() != getSizeOfDataSet()) {
-        std::ostringstream message;
-        message << "FitSuiteObjects::runSimulations() -> Error. Dataset size mismatch. "
-                << " m_fit_elements.size():" << m_fit_elements.size()
-                << " getSizeOfDataset():" << getSizeOfDataSet() << std::endl;
-        throw Exceptions::LogicErrorException(message.str());
-    }
-
-    m_chi_squared_value = calculateChiSquaredValue();
-}
-
-double FitSuiteObjects::getResidualValue(size_t global_index)
-{
-    if(global_index >= m_fit_elements.size())
-        throw Exceptions::LogicErrorException(
-            "FitSuiteObjects::getResidualValue() -> Error. Index exceeds size of dataset.");
-    return m_fit_elements[global_index].getResidual();
-}
-
-std::vector<double> FitSuiteObjects::residuals() const
-{
-    std::vector<double> result;
-    result.resize(m_fit_elements.size());
-    size_t index(0);
-    for(const auto& element: m_fit_elements) {
-        result[index] = element.getResidual();
-        ++index;
-    }
-
-    return result;
-}
-
-void FitSuiteObjects::clear()
-{
-    m_fit_objects.clear();
-    m_fit_elements.clear();
-}
-
-std::vector<const INode*> FitSuiteObjects::getChildren() const
-{
-    std::vector<const INode*> result;
-    for(auto fitObject : m_fit_objects)
-        result.push_back(fitObject);
-
-    if(m_chi2_module) {
-        const IIntensityNormalizer* data_normalizer = m_chi2_module->getIntensityNormalizer();
-        if(data_normalizer)
-            result.push_back(data_normalizer);
-    }
-
-    return result;
-}
-
-double FitSuiteObjects::calculateChiSquaredValue()
-{
-    m_chi2_module->processFitElements(m_fit_elements.begin(), m_fit_elements.end());
-
-    double result(0);
-    for (auto it = m_fit_elements.begin(); it != m_fit_elements.end(); ++it)
-        result += it->getSquaredDifference();
-
-    int fnorm = static_cast<int>(m_fit_elements.size()) - m_nfree_parameters;
-    if (fnorm <= 0)
-        throw Exceptions::LogicErrorException(
-            "FitSuiteObjects::calculateChiSquaredValue() -> Error. Normalization is 0");
-    return result / fnorm;
-}
-
-size_t FitSuiteObjects::check_index(size_t index) const
-{
-    if( index >= m_fit_objects.size() )
-        throw Exceptions::OutOfBoundsException("FitSuiteKit::check() -> Index outside of range");
-    return index;
-}
-
-//! Returns iterator pointing to the begin of FitObject with given i_item index.
-
-std::vector<FitElement>::const_iterator FitSuiteObjects::getStart(size_t i_item) const
-{
-    check_index(i_item);
-
-    int istart(0);
-    for(size_t i=0; i<i_item; ++i)
-        istart += m_fit_objects[i]->numberOfFitElements();
-
-    return m_fit_elements.begin() + istart;
-}
-
-std::vector<FitElement>::const_iterator FitSuiteObjects::getEnd(size_t i_item) const
-{
-    return getStart(i_item) + static_cast<int>(m_fit_objects[i_item]->numberOfFitElements());
-}
diff --git a/Core/Fitting/FitSuiteObjects.h b/Core/Fitting/FitSuiteObjects.h
deleted file mode 100644
index 5b476d2a3c7b3a20ed716f109397bd745bc5bb09..0000000000000000000000000000000000000000
--- a/Core/Fitting/FitSuiteObjects.h
+++ /dev/null
@@ -1,103 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Fitting/FitSuiteObjects.h
-//! @brief     Defines class FitSuiteObjects.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef FITSUITEOBJECTS_H
-#define FITSUITEOBJECTS_H
-
-#include "FitObject.h"
-
-class IChiSquaredModule;
-class IHistogram;
-
-//! Holds vector of FitObject's (simulation and real data) to fit
-//! @ingroup fitting_internal
-
-class BA_CORE_API_ FitSuiteObjects : public INode
-{
-public:
-    typedef SafePointerVector<FitObject> FitObjects_t;
-    typedef FitObjects_t::iterator iterator;
-
-    FitSuiteObjects();
-    virtual ~FitSuiteObjects();
-
-    void accept(INodeVisitor* visitor) const final { visitor->visit(this); }
-
-    //! Adds to kit pair of (simulation, real data) for consecutive simulation
-    FitObject* add(const Simulation& simulation, const OutputData<double>& real_data,
-             double weight = 1.0);
-
-    //! Returns total number of data points (number of all non-masked channels in all fit objects)
-    size_t getSizeOfDataSet() const;
-
-    //! Replaces default ChiSquaredModule with new one
-    void setChiSquaredModule(const IChiSquaredModule &chi2_module);
-
-    //! Returns simulation result.
-    //! @param i_item: the index of fit pair
-    SimulationResult simulationResult(size_t i_item = 0) const;
-
-    //! Returns experimental data.
-    //! @param i_item: the index of fit pair
-    SimulationResult experimentalData(size_t i_item = 0) const;
-
-    //! Returns relative difference between simulation and experimental data.
-    //! @param i_item: the index of fit pair
-    SimulationResult relativeDifference(size_t i_item = 0) const;
-
-    //! run all simulation defined in fit pairs
-    void runSimulations();
-
-    //! Returns chi2 calculated over whole dataset
-    double getChiSquaredValue() const { return m_chi_squared_value; }
-
-    //! Returns residuals for single data element
-    //! @param global_index index across all element in FitElement vector
-    double getResidualValue(size_t global_index);
-
-    std::vector<double> residuals() const;
-
-    void setNfreeParameters(int nfree_parameters) { m_nfree_parameters = nfree_parameters; }
-
-    //! clear all data
-    void clear();
-
-    size_t size() const { return m_fit_objects.size(); }
-    iterator begin() { return m_fit_objects.begin(); }
-    iterator end() { return m_fit_objects.end(); }
-
-    std::vector<const INode*> getChildren() const;
-
-protected:
-    //! Registers some class members for later access via parameter pool
-    void init_parameters() {}
-
-    double calculateChiSquaredValue();
-
-private:
-    inline size_t check_index(size_t index) const;
-
-    std::vector<FitElement>::const_iterator getStart(size_t i_item) const;
-    std::vector<FitElement>::const_iterator getEnd(size_t i_item) const;
-
-    FitObjects_t m_fit_objects;
-    double m_total_weight;
-    int m_nfree_parameters;
-    double m_chi_squared_value;
-    std::vector<FitElement> m_fit_elements;
-    std::unique_ptr<IChiSquaredModule> m_chi2_module;
-    size_t m_fit_elements_count;
-};
-
-#endif // FITSUITEOBJECTS_H
diff --git a/Core/Fitting/FitSuitePrintObserver.cpp b/Core/Fitting/FitSuitePrintObserver.cpp
deleted file mode 100644
index e51d99b5396b789be2017cad3f5645416a79357c..0000000000000000000000000000000000000000
--- a/Core/Fitting/FitSuitePrintObserver.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Fitting/FitSuitePrintObserver.cpp
-//! @brief     Implements class FitSuitePrintObserver.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "FitSuitePrintObserver.h"
-#include "FitSuite.h"
-#include "FitParameterSet.h"
-#include "FitSuiteStrategies.h"
-#include "MinimizerUtils.h"
-#include "IFitParameter.h"
-#include "FitSuiteUtils.h"
-#include <iostream>
-#include <iomanip>
-
-FitSuitePrintObserver::FitSuitePrintObserver(int print_every_nth)
-    : IFitObserver(print_every_nth)
-    , m_fit_suite(0)
-{
-}
-
-void FitSuitePrintObserver::update(FitSuite* fit_suite)
-{
-    m_fit_suite = fit_suite;
-
-    if(fit_suite->numberOfIterations() == 0) {
-        m_run_time.start();
-        m_last_call_time.start();
-        printFitSuiteHeader();
-    }
-
-    if(m_strategy_has_changed) {
-        std::cout << MinimizerUtils::sectionString() << "\n";
-        std::cout << (*m_fit_suite->fitStrategies()->currentStrategy()) << std::endl;
-        std::cout << MinimizerUtils::sectionString() << "\n";
-    }
-
-    printIterationHeader();
-    printWallTime();
-    printParameters();
-
-    if(fit_suite->isLastIteration())
-        printFitResults();
-}
-
-void FitSuitePrintObserver::printFitSuiteHeader()
-{
-    std::cout << MinimizerUtils::sectionString("Fit parameter settings");
-    std::cout << FitSuiteUtils::fitParameterSettingsToString(*m_fit_suite->fitParameters());
-    std::cout << MinimizerUtils::sectionString();
-}
-
-void FitSuitePrintObserver::printIterationHeader()
-{
-    std::cout << "FitPrintObserver::update() -> Info."
-              << " NCall:" << m_fit_suite->numberOfIterations()
-              << " NStrategy:" << m_fit_suite->currentStrategyIndex()
-              << " Chi2:" << std::scientific << std::setprecision(8)
-              << m_fit_suite->getChi2() << std::endl;
-}
-
-void FitSuitePrintObserver::printWallTime()
-{
-    m_last_call_time.stop();
-    std::cout << "Wall time since last call:" << std::fixed << std::setprecision(2)
-              << m_last_call_time.runTime() << std::endl;
-    m_last_call_time.start();
-}
-
-void FitSuitePrintObserver::printParameters()
-{
-    for(auto par : *m_fit_suite->fitParameters())
-        std::cout << "   # " << par->toString() << "\n";
-}
-
-void FitSuitePrintObserver::printFitResults()
-{
-    std::cout << "This was the last iteration." << std::endl;
-    m_run_time.stop();
-    m_fit_suite->printResults();
-    std::cout << "Total time spend: " << std::fixed << std::setprecision(2)
-              << m_run_time.runTime() << " sec." <<std::endl;
-    std::cout << std::endl;
-}
diff --git a/Core/Fitting/FitSuitePrintObserver.h b/Core/Fitting/FitSuitePrintObserver.h
deleted file mode 100644
index bbe1716fcf3b5e6226733f1cf376ced31ccb2cb8..0000000000000000000000000000000000000000
--- a/Core/Fitting/FitSuitePrintObserver.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Fitting/FitSuitePrintObserver.h
-//! @brief     Defines class FitSuitePrintObserver.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef FITSUITEPRINTOBSERVER_H
-#define FITSUITEPRINTOBSERVER_H
-
-#include "IFitObserver.h"
-#include "TimeInterval.h"
-
-//! Prints fit progress at the end of each FitSuite's iteration.
-//! @ingroup fitting_internal
-
-class BA_CORE_API_ FitSuitePrintObserver : public IFitObserver
-{
-public:
-    FitSuitePrintObserver(int print_every_nth = 1);
-    virtual ~FitSuitePrintObserver() {}
-
-    void update(FitSuite* fit_suite);
-
-protected:
-    void printFitSuiteHeader();
-    void printIterationHeader();
-    void printWallTime();
-    void printParameters();
-    void printFitResults();
-
-    FitSuite* m_fit_suite;
-    TimeInterval m_run_time;
-    TimeInterval m_last_call_time;
-};
-
-#endif // FITSUITEPRINTOBSERVER_H
diff --git a/Core/Fitting/FitSuiteStrategies.cpp b/Core/Fitting/FitSuiteStrategies.cpp
deleted file mode 100644
index 4a120343fcf0fc4be7a6b2b82453010f846ec3c3..0000000000000000000000000000000000000000
--- a/Core/Fitting/FitSuiteStrategies.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Fitting/FitSuiteStrategies.cpp
-//! @brief     Implements class FitSuiteStrategies.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "FitSuiteStrategies.h"
-#include "FitSuiteImpl.h"
-#include <stdexcept>
-
-FitSuiteStrategies::FitSuiteStrategies()
-    : m_kernel(nullptr), m_current_strategy_index(0)
-{
-}
-
-FitSuiteStrategies::~FitSuiteStrategies()
-{
-    clear();
-}
-
-void FitSuiteStrategies::clear()
-{
-    m_strategies.clear();
-    m_current_strategy_index = 0;
-}
-
-IFitStrategy *FitSuiteStrategies::currentStrategy()
-{
-    if(m_current_strategy_index >= m_strategies.size())
-        throw std::runtime_error("FitSuiteStrategies::currentStrategy() -> Error in index.");
-
-    return m_strategies[m_current_strategy_index];
-}
-
-void FitSuiteStrategies::addStrategy(const IFitStrategy &strategy)
-{
-    IFitStrategy *clone = strategy.clone();
-    clone->init(m_kernel);
-    m_strategies.push_back(clone);
-}
-
-void FitSuiteStrategies::minimize()
-{
-    m_current_strategy_index = 0;
-    if( m_strategies.empty() ) {
-         m_kernel->minimize();
-    } else {
-        for(auto it=m_strategies.begin(); it!=m_strategies.end(); ++it) {
-            (*it)->execute();
-            ++m_current_strategy_index;
-        }
-        --m_current_strategy_index;
-    }
-}
diff --git a/Core/Fitting/FitSuiteStrategies.h b/Core/Fitting/FitSuiteStrategies.h
deleted file mode 100644
index 00a41cac3c748978fb31c1e5281c74e5d23a1214..0000000000000000000000000000000000000000
--- a/Core/Fitting/FitSuiteStrategies.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Fitting/FitSuiteStrategies.h
-//! @brief     Defines class FitSuiteStrategies.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef FITSUITESTRATEGIES_H
-#define FITSUITESTRATEGIES_H
-
-#include "IFitStrategy.h"
-#include "SafePointerVector.h"
-
-//! Collection of strategies to fit.
-//! @ingroup fitting_internal
-
-class BA_CORE_API_ FitSuiteStrategies
-{
-public:
-    FitSuiteStrategies();
-    virtual ~FitSuiteStrategies();
-    FitSuiteStrategies(const FitSuiteStrategies &other) = delete;
-    FitSuiteStrategies& operator=(const FitSuiteStrategies &other) = delete;
-
-    void init(FitSuiteImpl* fit_suite) { m_kernel = fit_suite; }
-
-    void addStrategy(const IFitStrategy& strategy);
-
-    void minimize();
-
-    size_t currentStrategyIndex() const { return m_current_strategy_index; }
-
-    size_t size() const { return m_strategies.size(); }
-
-    void clear();
-
-    IFitStrategy* currentStrategy();
-
-private:
-    SafePointerVector<IFitStrategy> m_strategies;
-    FitSuiteImpl* m_kernel;
-    size_t m_current_strategy_index;
-};
-
-#endif // FITSUITESTRATEGIES_H
diff --git a/Core/Fitting/FitSuiteUtils.cpp b/Core/Fitting/FitSuiteUtils.cpp
deleted file mode 100644
index 1fa92507334d4c1d92bcd3b853783784c1f7da7c..0000000000000000000000000000000000000000
--- a/Core/Fitting/FitSuiteUtils.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Fitting/FitSuiteUtils.cpp
-//! @brief     Implements utility functions for FitSuite.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "FitSuiteUtils.h"
-#include "FitParameter.h"
-#include "FitParameterSet.h"
-#include <boost/format.hpp>
-#include <sstream>
-
-std::vector<FitParameter*>
-FitSuiteUtils::linkedParameters(const FitParameterSet& fitParameters)
-{
-    std::vector<FitParameter*> result;
-    for(auto par : fitParameters) {
-        if(FitParameter *linked = dynamic_cast<FitParameter*>(par))
-            result.push_back(linked);
-        else
-            throw std::runtime_error("FitSuiteUtils::linkedParameters() -> Error. Can't cast");
-    }
-
-    return result;
-}
-
-std::string FitSuiteUtils::linkToString(const FitParameter& par)
-{
-    std::ostringstream result;
-
-    result << boost::format("%-10s : '%-s'\n") % "name" % par.name();
-    result << boost::format("%-10s : startValue=%-7.4f, currentValue=%-7.4f, step=%-6.3f\n")
-              % "value" % par.startValue() % par.value()% par.step();
-    result << boost::format("%-10s : %-s\n") % "limits" % par.limits().toString();
-    result << boost::format("%-10s : ") % "pattern";
-    size_t index(0);
-    for(auto pattern : par.patterns()) {
-        result << "'" << pattern << "'";
-        ++index;
-        if(index!= par.patterns().size())
-            result << ", ";
-    }
-    result << std::endl;
-
-
-    for(auto link : par.matchedParameterNames())
-        result << boost::format("%-10s : '%s'\n") % "linked to" % link;
-
-    return result.str();
-}
-
-std::string FitSuiteUtils::fitParameterSettingsToString(const FitParameterSet& fitParameters)
-{
-    std::ostringstream result;
-    size_t index(0);
-    auto parameters = FitSuiteUtils::linkedParameters(fitParameters);
-    for(auto par : parameters) {
-        result << FitSuiteUtils::linkToString(*par);
-        ++index;
-        if(index != parameters.size())
-            result << std::endl;
-    }
-
-    return result.str();
-}
-
-bool FitSuiteUtils::hasConflicts(const FitParameterSet& fitParameters)
-{
-    std::vector<FitParameter*> parameters = FitSuiteUtils::linkedParameters(fitParameters);
-    for(auto par1 : parameters) {
-        for(auto par2 : parameters) {
-            if(par1 != par2)
-                if(par1->isConflicting(*par2))
-                    return true;
-        }
-    }
-
-    return false;
-}
diff --git a/Core/Fitting/FitSuiteUtils.h b/Core/Fitting/FitSuiteUtils.h
deleted file mode 100644
index 5835a119c84fb0439577ab8eade34f35380d3751..0000000000000000000000000000000000000000
--- a/Core/Fitting/FitSuiteUtils.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Fitting/FitSuiteUtils.h
-//! @brief     Defines namespace with utility functions for FitSuite.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef FITSUITEUTILS_H
-#define FITSUITEUTILS_H
-
-#include "WinDllMacros.h"
-#include <string>
-#include <vector>
-
-class FitParameter;
-class FitParameterSet;
-
-namespace FitSuiteUtils {
-
-//! Returns vector of linked parameters.
-BA_CORE_API_ std::vector<FitParameter*> linkedParameters(const FitParameterSet& fitParameters);
-
-//! Returns multiline string representing linked sample parameters.
-BA_CORE_API_ std::string linkToString(const FitParameter& par);
-
-//! Returns multiline string representing fit parameter definition.
-BA_CORE_API_ std::string fitParameterSettingsToString(const FitParameterSet& fitParameters);
-
-//! Validates all fit parameters for conflicts (steering same sample parameters).
-BA_CORE_API_ bool hasConflicts(const FitParameterSet& fitParameters);
-
-
-}
-
-#endif
diff --git a/Core/Fitting/IFitObserver.cpp b/Core/Fitting/IFitObserver.cpp
deleted file mode 100644
index df746fbd145de0581ed78f36d8f441fc1daedeca..0000000000000000000000000000000000000000
--- a/Core/Fitting/IFitObserver.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Fitting/IFitObserver.cpp
-//! @brief     Implements class IFitObserver.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "IFitObserver.h"
-#include "FitSuite.h"
-#include "FitSuiteStrategies.h"
-
-
-IFitObserver::IFitObserver(int update_every_nth)
-    : m_update_every_nth(update_every_nth)
-    , m_current_strategy_index(-1)
-    , m_strategy_has_changed(false)
-{
-}
-
-void IFitObserver::notify(IObservable* subject)
-{
-    FitSuite* fit_suite = dynamic_cast<FitSuite*>(subject);
-    if( !fit_suite )
-        throw Exceptions::NullPointerException(
-            "IFitObserver::update() -> Error! Can't access FitSuite");
-
-    bool needs_update(false);
-
-    if(fit_suite->fitStrategies()->size() &&
-            m_current_strategy_index != (int)fit_suite->currentStrategyIndex()) {
-        needs_update = true;
-        m_current_strategy_index = static_cast<int>(fit_suite->currentStrategyIndex());
-        m_strategy_has_changed = true;
-    } else {
-        m_strategy_has_changed = false;
-    }
-
-    if( fit_suite->numberOfIterations() == 0 )
-        needs_update = true;  // first iteration
-    if( fit_suite->isLastIteration() )
-        needs_update = true; // last iteration
-    if( fit_suite->numberOfIterations() % m_update_every_nth == 0 )
-        needs_update = true; // every n'th iteration
-
-    if(needs_update)
-        update(fit_suite);
-}
-
-void IFitObserver::update(FitSuite*)
-{
-    throw Exceptions::NotImplementedException(
-        "IFitObserver::update(IObservable *subject) -> Error. Not implemented.");
-}
diff --git a/Core/Fitting/IFitObserver.h b/Core/Fitting/IFitObserver.h
deleted file mode 100644
index a803eb3ad8f80752761d67fd1368215c8109d93e..0000000000000000000000000000000000000000
--- a/Core/Fitting/IFitObserver.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Fitting/IFitObserver.h
-//! @brief     Defines class IFitObserver.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef IFITOBSERVER_H
-#define IFITOBSERVER_H
-
-#include "IObserver.h"
-class FitSuite;
-
-//! Base class for all fit observers. Calls update method in following cases:
-//! first iteration, every n-th iteration, last iteration and when fit strategy has changed.
-//! @ingroup fitting_internal
-
-class BA_CORE_API_ IFitObserver : public IObserver
-{
-public:
-    IFitObserver(int update_every_nth);
-
-    //! The method used by Ovservable when he wants to be observed by this
-    virtual void notify(IObservable* subject);
-
-    //! Here Onserver will do actuall job when he thinks that it is a right moment
-    virtual void update(FitSuite* fit_suite);
-
-protected:
-    int m_update_every_nth;
-    int m_current_strategy_index;
-    bool m_strategy_has_changed;
-};
-
-
-#endif // IFITOBSERVER_H
diff --git a/Core/Fitting/IFitParameter.cpp b/Core/Fitting/IFitParameter.cpp
deleted file mode 100644
index 9a7d34c40460896bd3f6d2ffc2520f2558d4913e..0000000000000000000000000000000000000000
--- a/Core/Fitting/IFitParameter.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Fit/Parameters/FitParameter.cpp
-//! @brief     Implements class FitParameter.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "IFitParameter.h"
-#include <iomanip>
-#include <sstream>
-#include <stdexcept>
-
-IFitParameter::IFitParameter()
-    : m_start_value(0.0)
-    , m_value(0.0)
-    , m_step(0.0)
-    , m_error(0.0)
-{
-
-}
-
-IFitParameter::IFitParameter(const std::string &name, double value, const AttLimits &limits,
-                                 double step)
-    : m_name(name)
-    , m_start_value(value)
-    , m_value(value)
-    , m_step(step)
-    , m_error(0.0)
-    , m_limits(limits)
-{
-
-}
-
-IFitParameter *IFitParameter::clone() const
-{
-    return new IFitParameter(*this);
-}
-
-std::string IFitParameter::name() const { return m_name; }
-
-IFitParameter& IFitParameter::setName(const std::string& name)
-{
-    m_name = name;
-    return *this;
-}
-
-double IFitParameter::startValue() const { return m_start_value; }
-
-void IFitParameter::setStartValue(double value)
-{
-    m_start_value = value;
-    setValue(value);
-}
-
-double IFitParameter::value() const { return m_value; }
-
-void IFitParameter::setValue(double value) { m_value = value; }
-
-// non-elegant way to provide chain of setters for derived FitParameter
-IFitParameter& IFitParameter::addPattern(const std::string& /*pattern*/)
-{
-    throw std::runtime_error("IFitParameter::addPattern() -> Error. Not implemented");
-}
-
-double IFitParameter::step() const { return m_step; }
-
-IFitParameter &IFitParameter::setStep(double value)
-{
-    m_step = value;
-    return *this;
-}
-
-double IFitParameter::error() const { return m_error; }
-
-void IFitParameter::setError(double value) { m_error = value; }
-
-const AttLimits &IFitParameter::limits() const { return m_limits;}
-
-AttLimits &IFitParameter::limits() { return m_limits;}
-
-IFitParameter& IFitParameter::setLimits(const AttLimits &limits)
-{
-    m_limits = limits;
-    return *this;
-}
-
-IFitParameter &IFitParameter::setLowerLimited(double bound_value)
-{
-    m_limits = AttLimits::lowerLimited(bound_value);
-    return *this;
-}
-
-IFitParameter &IFitParameter::setPositive()
-{
-    m_limits = AttLimits::positive();
-    return *this;
-}
-
-IFitParameter &IFitParameter::setNonnegative()
-{
-    m_limits = AttLimits::nonnegative();
-    return *this;
-}
-
-IFitParameter &IFitParameter::setUpperLimited(double bound_value)
-{
-    m_limits = AttLimits::upperLimited(bound_value);
-    return *this;
-}
-
-IFitParameter &IFitParameter::setLimited(double left_bound_value, double right_bound_value)
-{
-    m_limits = AttLimits::limited(left_bound_value, right_bound_value);
-    return *this;
-}
-
-IFitParameter &IFitParameter::setFixed()
-{
-    m_limits = AttLimits::fixed();
-    return *this;
-}
-
-std::string IFitParameter::toString() const
-{
-    std::ostringstream ostr;
-
-    const int max_length_of_name(10);
-    std::string adjusted_name = m_name;
-    adjusted_name.resize(max_length_of_name,' ');
-    ostr << adjusted_name << std::scientific << std::setprecision(8) << m_value << "  ";
-    ostr << m_limits.toString();
-    return ostr.str();
-}
-
-IFitParameter::IFitParameter(const IFitParameter &other)
-{
-    m_name = other.m_name;
-    m_start_value = other.m_start_value;
-    m_value = other.m_value;
-    m_step = other.m_step;
-    m_error = other.m_error;
-    m_limits = other.m_limits;
-}
diff --git a/Core/Fitting/IFitParameter.h b/Core/Fitting/IFitParameter.h
deleted file mode 100644
index 20f9bff13f533e89c8b3e100c2baeaa25bd12767..0000000000000000000000000000000000000000
--- a/Core/Fitting/IFitParameter.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Fit/Parameters/FitParameter.h
-//! @brief     Defines class FitParameter.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef IFITPARAMETER_H
-#define IFITPARAMETER_H
-
-#include "WinDllMacros.h"
-#include "AttLimits.h"
-#include <string>
-
-//! A fittable parameter with value, error, step, and limits.
-//! @ingroup fitting
-
-class BA_CORE_API_ IFitParameter
-{
-public:
-    IFitParameter();
-    IFitParameter(const std::string& name, double value,
-                 const AttLimits& limits=AttLimits::limitless(), double step=0.0);
-    IFitParameter& operator=(const IFitParameter&) = delete;
-    virtual ~IFitParameter(){}
-
-    IFitParameter* clone() const;
-
-    std::string name() const;
-    IFitParameter& setName(const std::string& name);
-
-    double startValue() const;
-    void setStartValue(double value);
-
-    double value() const;
-    virtual void setValue(double value);
-
-    virtual IFitParameter& addPattern(const std::string& pattern);
-
-    double step() const;
-    IFitParameter& setStep(double value);
-
-    double error() const;
-    void setError(double value);
-
-    const AttLimits& limits() const;
-    AttLimits& limits();
-
-    IFitParameter& setLimits(const AttLimits& limits);
-    IFitParameter& setLowerLimited(double bound_value);
-    IFitParameter& setPositive();
-    IFitParameter& setNonnegative();
-    IFitParameter& setUpperLimited(double bound_value);
-    IFitParameter& setLimited(double left_bound_value, double right_bound_value);
-    IFitParameter& setFixed();
-
-    virtual std::string toString() const;
-
-protected:
-    IFitParameter(const IFitParameter& other);
-
-private:
-    std::string m_name;
-    double m_start_value;
-    double m_value;
-    double m_step;
-    double m_error;
-    AttLimits m_limits;
-};
-
-#endif // IFITPARAMETER_H
diff --git a/Core/Fitting/IFitStrategy.cpp b/Core/Fitting/IFitStrategy.cpp
deleted file mode 100644
index 0374ce83153aa256b441c548ba0d9a2956714f15..0000000000000000000000000000000000000000
--- a/Core/Fitting/IFitStrategy.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Fitting/IFitStrategy.cpp
-//! @brief     Implements classes IFitStrategy and FitStrategyDefault
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "IFitStrategy.h"
-#include "FitSuiteImpl.h"
-#include <stdexcept>
-
-IFitStrategy::IFitStrategy(const std::string &name)
-    : INamed(name), m_kernel(nullptr)
-{
-}
-
-void IFitStrategy::init(FitSuiteImpl* fit_suite)
-{
-    m_kernel = fit_suite;
-}
-
-std::string IFitStrategy::toString() const
-{
-    return getName();
-}
-
-IFitStrategy::IFitStrategy(const IFitStrategy &other)
-    : INamed(other)
-{
-    m_kernel = other.m_kernel;
-}
-
-// ----------------------------------------------------------------------------
-
-FitStrategyDefault::FitStrategyDefault()
-    : IFitStrategy("DefaultFitStrategy")
-{
-}
-
-FitStrategyDefault *FitStrategyDefault::clone() const
-{
-    return new FitStrategyDefault(*this);
-}
-
-void FitStrategyDefault::execute()
-{
-    if( !m_kernel )
-        throw std::runtime_error("FitStrategyDefault::execute() -> FitSuite doesn't exists");
-
-    m_kernel->minimize();
-}
-
-FitStrategyDefault::FitStrategyDefault(const FitStrategyDefault &other)
-    : IFitStrategy(other)
-{
-
-}
diff --git a/Core/Fitting/IFitStrategy.h b/Core/Fitting/IFitStrategy.h
deleted file mode 100644
index 4bb6a3998cf04ac363104517161c11fb788eb8f4..0000000000000000000000000000000000000000
--- a/Core/Fitting/IFitStrategy.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Fitting/IFitStrategy.h
-//! @brief     Defines interface class IFitStrategy, and class FitStrategyDefault
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef IFITSTRATEGY_H
-#define IFITSTRATEGY_H
-
-#include "INamed.h"
-
-class FitSuiteImpl;
-
-//! Interface to concrete fit strategy.
-//! Concrete implementation should manipulate with fit parameters/data and then call minimizer.
-//! @ingroup fitting_internal
-
-class BA_CORE_API_ IFitStrategy : public INamed
-{
-public:
-    explicit IFitStrategy(const std::string& name);
-    IFitStrategy& operator=(const IFitStrategy &other) = delete;
-    virtual ~IFitStrategy() {}
-
-    virtual IFitStrategy* clone() const =0;
-
-    virtual void init(FitSuiteImpl* fit_suite);
-    virtual void execute() =0;
-
-    friend std::ostream &operator<<(std::ostream &ostr, const IFitStrategy &m) {
-        ostr << m.toString(); return ostr; }
-
-protected:
-    IFitStrategy(const IFitStrategy &other);
-
-    virtual std::string toString() const;
-    FitSuiteImpl* m_kernel;
-};
-
-
-//! Default fit strategy just let FitSuite to run it's minimization round.
-//! @ingroup fitting
-
-class BA_CORE_API_ FitStrategyDefault : public IFitStrategy
-{
-public:
-    FitStrategyDefault();
-    virtual FitStrategyDefault* clone() const;
-    virtual void execute();
-
-protected:
-    FitStrategyDefault(const FitStrategyDefault &other);
-};
-
-#endif // IFITSTRATEGY_H
diff --git a/Core/Fitting/SimDataPair.cpp b/Core/Fitting/SimDataPair.cpp
index 85b799093980bd1c90b228d1f2427d78408a31ab..76998634b6f4a8ebeba33afb67e60fa20977bfc5 100644
--- a/Core/Fitting/SimDataPair.cpp
+++ b/Core/Fitting/SimDataPair.cpp
@@ -87,6 +87,20 @@ SimulationResult SimDataPair::relativeDifference() const
     return SimulationResult(*roi_data, *converter);
 }
 
+SimulationResult SimDataPair::absoluteDifference() const
+{
+    auto converter = UnitConverterUtils::createConverter(*m_simulation);
+    auto roi_data = UnitConverterUtils::createOutputData(*converter.get(), converter->defaultUnits());
+    auto detector = m_simulation->getInstrument().getDetector();
+
+    detector->iterate([&](IDetector::const_iterator it){
+        const size_t index = it.roiIndex();
+        (*roi_data)[index] = std::abs(m_simulation_result[index] - m_experimental_data[index]);
+    });
+
+    return SimulationResult(*roi_data, *converter);
+}
+
 SimDataPair::~SimDataPair() = default;
 
 void SimDataPair::runSimulation(const Fit::Parameters& params)
@@ -120,6 +134,11 @@ std::vector<double> SimDataPair::simulation_array() const
     return m_simulation_array;
 }
 
+std::vector<double> SimDataPair::weights_array() const
+{
+    return m_weights_array;
+}
+
 //! Creates new simulation for given set of fit parameters.
 //! If it is first call, save number of fit elements (supposed to stay the same during the fit),
 //! and converts raw user data to SimulationResult.
@@ -135,9 +154,13 @@ void SimDataPair::create_simulation(const Fit::Parameters& params)
         m_experimental_array.clear();
         m_experimental_array.reserve(numberOfFitElements());
 
+        m_weights_array.clear();
+        m_weights_array.reserve(numberOfFitElements());
+
         auto detector = m_simulation->getInstrument().getDetector();
         detector->iterate([&](IDetector::const_iterator it){
             m_experimental_array.push_back(m_experimental_data[it.roiIndex()]);
+            m_weights_array.push_back(m_weight);
         });
     }
 }
diff --git a/Core/Fitting/SimDataPair.h b/Core/Fitting/SimDataPair.h
index ee903fbb7c777a3b70058d3708d8708b72334509..94a9eafdb3907e0629bdad3e3b9dbffef523c934 100644
--- a/Core/Fitting/SimDataPair.h
+++ b/Core/Fitting/SimDataPair.h
@@ -41,12 +41,16 @@ public:
 
     SimulationResult relativeDifference() const;
 
+    SimulationResult absoluteDifference() const;
+
     void runSimulation(const Fit::Parameters& params);
 
     std::vector<double> experimental_array() const;
 
     std::vector<double> simulation_array() const;
 
+    std::vector<double> weights_array() const;
+
 private:
     void create_simulation(const Fit::Parameters& params);
 
@@ -61,6 +65,8 @@ private:
     std::vector<double> m_simulation_array;
     //!< Experimental data in the form of flat array (masked areas excluded, ROI only).
     std::vector<double> m_experimental_array;
+    //!< Weight of detector bin in residual calculations
+    std::vector<double> m_weights_array;
 
     //!< Simulation builder from the user to construct simulation for given set of parameters.
     simulation_builder_t m_simulation_builder;
diff --git a/Core/HardParticle/FormFactorLongBox.cpp b/Core/HardParticle/FormFactorLongBox.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ed32b36b338ed1117440ae65dcb76000fe72896b
--- /dev/null
+++ b/Core/HardParticle/FormFactorLongBox.cpp
@@ -0,0 +1,53 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      Core/HardParticle/FormFactorLongBox.cpp
+//! @brief     Implements class FormFactorLongBox.
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "FormFactorLongBox.h"
+#include "BornAgainNamespace.h"
+#include "Box.h"
+#include "MathFunctions.h"
+#include "RealParameter.h"
+
+FormFactorLongBox::FormFactorLongBox(double length, double width, double height)
+    : m_length(length), m_width(width), m_height(height)
+{
+    setName(BornAgain::FFLongBoxType);
+    registerParameter(BornAgain::Length, &m_length).setUnit(BornAgain::UnitsNm).setNonnegative();
+    registerParameter(BornAgain::Width, &m_width).setUnit(BornAgain::UnitsNm).setNonnegative();
+    registerParameter(BornAgain::Height, &m_height).setUnit(BornAgain::UnitsNm).setNonnegative();
+    onChange();
+}
+
+complex_t FormFactorLongBox::evaluate_for_q(cvector_t q) const
+{
+    complex_t qxL2 = std::pow(m_length * q.x() / 2.0, 2);
+    complex_t qyWdiv2 = m_width * q.y() / 2.0;
+    complex_t qzHdiv2 = m_height * q.z() / 2.0;
+
+    return m_height * m_length * m_width * exp_I(qzHdiv2)
+            * MathFunctions::sinc(qyWdiv2) * MathFunctions::sinc(qzHdiv2)
+            / std::sqrt(1.0 + qxL2);
+}
+
+IFormFactor* FormFactorLongBox::sliceFormFactor(ZLimits limits, const IRotation& rot,
+                                                     kvector_t translation) const
+{
+    auto effects = computeSlicingEffects(limits, translation, m_height);
+    FormFactorLongBox slicedff(m_length, m_width, m_height - effects.dz_bottom - effects.dz_top);
+    return CreateTransformedFormFactor(slicedff, rot, effects.position);
+}
+
+void FormFactorLongBox::onChange()
+{
+    mP_shape.reset(new Box(m_length, m_width, m_height));
+}
diff --git a/Core/HardParticle/FormFactorLongBox.h b/Core/HardParticle/FormFactorLongBox.h
new file mode 100644
index 0000000000000000000000000000000000000000..24323725eef27d50a0977f164d68a100f20ec13c
--- /dev/null
+++ b/Core/HardParticle/FormFactorLongBox.h
@@ -0,0 +1,56 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      Core/HardParticle/FormFactorLongBox.h
+//! @brief     Defines class FormFactorLongBox.
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef FORMFACTORLONGBOX_H
+#define FORMFACTORLONGBOX_H
+
+#include "IFormFactorBorn.h"
+
+//! The formfactor for a long rectangular box.
+//! Approximates the rapidly oscillating sinc function by the square root of a Lorentzian
+//! @ingroup legacyGrating
+
+class BA_CORE_API_ FormFactorLongBox : public IFormFactorBorn
+{
+public:
+    //! @brief Box constructor
+    //! @param length of Box's base
+    //! @param width of Box's base
+    //! @param height of Box
+    FormFactorLongBox( double length, double width, double height);
+
+    FormFactorLongBox *clone() const override final {
+        return new FormFactorLongBox(m_length, m_width, m_height); }
+    void accept(INodeVisitor *visitor) const override final { visitor->visit(this); }
+
+    double getLength() const { return m_length; }
+    double getHeight() const { return m_height; }
+    double getWidth() const { return m_width; }
+    double radialExtension() const override final{ return m_length/2.0; }
+
+    complex_t evaluate_for_q(cvector_t q) const override final;
+
+protected:
+    IFormFactor* sliceFormFactor(ZLimits limits, const IRotation& rot,
+                                 kvector_t translation) const override final;
+
+    void onChange() override final;
+
+private:
+    double m_length;
+    double m_width;
+    double m_height;
+};
+
+#endif // FORMFACTORLONGBOX_H
diff --git a/Core/InputOutput/OutputDataReadStrategy.cpp b/Core/InputOutput/OutputDataReadStrategy.cpp
index e96b2ba0dd59ca6f3801996ffe57200291cc4cf2..082c23aec5ba5f67a0cb018dfd2d8537b51a531a 100644
--- a/Core/InputOutput/OutputDataReadStrategy.cpp
+++ b/Core/InputOutput/OutputDataReadStrategy.cpp
@@ -15,6 +15,7 @@
 #include "OutputDataReadStrategy.h"
 #include "OutputData.h"
 #include "DataFormatUtils.h"
+#include "ArrayUtils.h"
 #include "TiffHandler.h"
 #include <stdexcept> // need overlooked by g++ 5.4
 
@@ -55,33 +56,35 @@ OutputData<double>* OutputDataReadNumpyTXTStrategy::readOutputData(std::istream&
 
     if (ncols == 0)
         throw std::runtime_error("OutputDataReadNumpyTXTStrategy::readOutputData() -> Error. "
-                                 "Can't parse file");
+                                     "Can't parse file");
 
     for(size_t row=0; row<nrows; row++) {
         if(data[row].size() != ncols)
             throw std::runtime_error("OutputDataReadNumpyTXTStrategy::readOutputData() -> Error. "
-                                     "Number of elements is different from row to row.");
+                                         "Number of elements is different from row to row.");
     }
-    OutputData<double>* result = new OutputData<double>;
-    result->addAxis("x", ncols, 0.0, double(ncols));
-    result->addAxis("y", nrows, 0.0, double(nrows));
-    std::vector<unsigned> axes_indices(2);
-    for(unsigned row=0; row<nrows; row++) {
-        for(unsigned col=0; col<ncols; col++) {
-            axes_indices[0] = col;
-            axes_indices[1] = static_cast<unsigned>(nrows) - 1 - row;
-            size_t global_index = result->toGlobalIndex(axes_indices);
-            (*result)[global_index] = data[row][col];
+
+    if(nrows < 2){
+        return ArrayUtils::createData1D(std::move(data[0])).release();
+    }
+    else if(ncols < 2){
+        const size_t size = data.size();
+        std::vector<double> vector1d(size);
+        for(size_t i = 0; i < size; ++i){
+            vector1d[i] = data[i][0];
         }
+        return ArrayUtils::createData1D(std::move(vector1d)).release();
+    }
+    else{
+        return ArrayUtils::createData2D(data).release();
     }
-    return result;
 }
 
 
 #ifdef BORNAGAIN_TIFF_SUPPORT
 
 OutputDataReadTiffStrategy::OutputDataReadTiffStrategy()
-    : m_d(new TiffHandler)
+        : m_d(new TiffHandler)
 {}
 
 OutputDataReadTiffStrategy::~OutputDataReadTiffStrategy()
diff --git a/Core/InputOutput/OutputDataReadStrategy.h b/Core/InputOutput/OutputDataReadStrategy.h
index 21811f7d9b178b23001a52939a65ee99d49d4d6f..0482d09f4c00244d0d1ab570834fc4a2f8b25a61 100644
--- a/Core/InputOutput/OutputDataReadStrategy.h
+++ b/Core/InputOutput/OutputDataReadStrategy.h
@@ -33,7 +33,7 @@ public:
 //! Strategy to read BornAgain native IntensityData from ASCII file.
 //! @ingroup input_output_internal
 
-class OutputDataReadINTStrategy : public IOutputDataReadStrategy
+class BA_CORE_API_ OutputDataReadINTStrategy : public IOutputDataReadStrategy
 {
 public:
     OutputData<double>* readOutputData(std::istream& input_stream);
@@ -42,7 +42,7 @@ public:
 //! Strategy to read OutputData from simple ASCII file with the layout as in numpy.savetxt.
 //! @ingroup input_output_internal
 
-class OutputDataReadNumpyTXTStrategy : public IOutputDataReadStrategy
+class BA_CORE_API_ OutputDataReadNumpyTXTStrategy : public IOutputDataReadStrategy
 {
 public:
     OutputData<double>* readOutputData(std::istream& input_stream);
diff --git a/Core/InputOutput/OutputDataWriteStrategy.cpp b/Core/InputOutput/OutputDataWriteStrategy.cpp
index e0a85506bf2bc1709bc3b389a01c997e0ff6adf9..b32dac208e20a994c298458d857d2d9e131a62d0 100644
--- a/Core/InputOutput/OutputDataWriteStrategy.cpp
+++ b/Core/InputOutput/OutputDataWriteStrategy.cpp
@@ -13,52 +13,87 @@
 // ************************************************************************** //
 
 #include "OutputDataWriteStrategy.h"
+#include "ArrayUtils.h"
 #include "BornAgainNamespace.h"
 #include "OutputData.h" // needed by some compilers
 #include "TiffHandler.h"
 #include <cmath>
 #include <iomanip>
 
-namespace {
-    const int precision { 12 };
+namespace
+{
+const int precision{12};
 
-    double IgnoreDenormalized(double value)
-    {
-        if (std::fpclassify(value)==FP_SUBNORMAL)
-            return 0.0;
-        return value;
-    }
+double IgnoreDenormalized(double value)
+{
+    if (std::fpclassify(value) == FP_SUBNORMAL)
+        return 0.0;
+    return value;
+}
+
+void Write2DRepresentation(const OutputData<double>& data, std::ostream& output_stream)
+{
+    const size_t nrows = data.getAxis(BornAgain::Y_AXIS_INDEX).size();
+    const size_t ncols = data.getAxis(BornAgain::X_AXIS_INDEX).size();
+
+    output_stream << "# [nrows=" << nrows << ", ncols=" << ncols << "]" << std::endl;
 
-    void WriteOutputDataDoubles(
-        const OutputData<double>& data, std::ostream& output_stream, size_t n_columns)
-    {
-        OutputData<double>::const_iterator it = data.begin();
-        output_stream.imbue(std::locale::classic());
-        output_stream << std::scientific << std::setprecision(precision);
-        size_t ncol(0);
-        while (it != data.end()) {
-            ncol++;
-            double z_value = *it++;
+    std::vector<std::vector<double>> dataArray = ArrayUtils::createVector2D(data);
+    output_stream.imbue(std::locale::classic());
+    output_stream << std::scientific << std::setprecision(precision);
+
+    for (size_t i = 0; i < nrows; i++) {
+        for (size_t j = 0; j < ncols; j++) {
+            double z_value = dataArray[i][j];
             output_stream << IgnoreDenormalized(z_value) << "    ";
-            if(ncol == n_columns) {
-                output_stream << std::endl;
-                ncol = 0;
-            }
         }
+        output_stream << std::endl;
     }
+}
 
+void WriteOutputDataDoubles(const OutputData<double>& data, std::ostream& output_stream,
+                            size_t n_columns)
+{
+
+    OutputData<double>::const_iterator it = data.begin();
+    output_stream.imbue(std::locale::classic());
+    output_stream << std::scientific << std::setprecision(precision);
+    size_t ncol(0);
+    while (it != data.end()) {
+        ncol++;
+        double z_value = *it++;
+        output_stream << IgnoreDenormalized(z_value) << "    ";
+        if (ncol == n_columns) {
+            output_stream << std::endl;
+            ncol = 0;
+        }
+    }
+}
+
+void Write1DRepresentation(const OutputData<double>& data, std::ostream& output_stream)
+{
+    output_stream << "# coordinates         intensities" << std::endl;
+    output_stream.imbue(std::locale::classic());
+    output_stream << std::scientific << std::setprecision(precision);
+
+    const std::vector<double> axis_values = data.getAxis(BornAgain::X_AXIS_INDEX).getBinCenters();
+
+    // printing coordinate and associated intensity
+    for (size_t i = 0, nrows = axis_values.size(); i < nrows; ++i)
+        output_stream << axis_values[i] << "    " << IgnoreDenormalized(data[i]) << std::endl;
+}
 } // namespace
 
 // ----------------------------------------------------------------------------
 // class OutputDataWriteINTStrategy
 // ----------------------------------------------------------------------------
 
-void OutputDataWriteINTStrategy::writeOutputData(
-    const OutputData<double>& data, std::ostream& output_stream)
+void OutputDataWriteINTStrategy::writeOutputData(const OutputData<double>& data,
+                                                 std::ostream& output_stream)
 {
     output_stream << "# BornAgain Intensity Data\n\n";
 
-    for(size_t i=0; i<data.getRank(); ++i) {
+    for (size_t i = 0; i < data.getRank(); ++i) {
         std::string axis_name = std::string("axis") + std::to_string(i);
         std::unique_ptr<IAxis> P_axis(data.getAxis(i).clone());
         P_axis->setName(axis_name);
@@ -66,7 +101,7 @@ void OutputDataWriteINTStrategy::writeOutputData(
         output_stream << "# axis-" << i << "\n";
         output_stream << (*P_axis) << "\n";
     }
-    size_t n_columns = data.getAxis(data.getRank()-1).size();
+    size_t n_columns = data.getAxis(data.getRank() - 1).size();
 
     output_stream << "\n# data\n";
     WriteOutputDataDoubles(data, output_stream, n_columns);
@@ -77,24 +112,24 @@ void OutputDataWriteINTStrategy::writeOutputData(
 // class OutputDataWriteNumpyTXTStrategy
 // ----------------------------------------------------------------------------
 
-void OutputDataWriteNumpyTXTStrategy::writeOutputData(
-    const OutputData<double>& data, std::ostream& output_stream)
+void OutputDataWriteNumpyTXTStrategy::writeOutputData(const OutputData<double>& data,
+                                                      std::ostream& output_stream)
 {
-    if(data.getRank() != 2)
-        throw Exceptions::LogicErrorException(
-            "OutputDataWriteNumpyTXTStrategy::writeOutputData -> Error. "
-            "Only 2-dim arrays supported");
-
     output_stream << "# BornAgain Intensity Data" << std::endl;
-    output_stream << "# Simple 2D array suitable for numpy, matlab etc." << std::endl;
-
-    size_t nrows = data.getAxis(BornAgain::Y_AXIS_INDEX).size();
-    size_t ncols = data.getAxis(BornAgain::X_AXIS_INDEX).size();
-
-    output_stream << "# [nrows=" << nrows
-                  << ", ncols=" << ncols << "]" << std::endl;
-
-    WriteOutputDataDoubles(data,output_stream, ncols);
+    output_stream << "# Simple array suitable for numpy, matlab etc." << std::endl;
+
+    const size_t dim = data.getRank();
+    switch (dim) {
+    case 1:
+        Write1DRepresentation(data, output_stream);
+        break;
+    case 2:
+        Write2DRepresentation(data, output_stream);
+        break;
+    default:
+        throw std::runtime_error("Error in OutputDataWriteNumpyTXTStrategy::writeOutputData: data "
+                                 "of unsupported dimensions");
+    }
 }
 
 // ----------------------------------------------------------------------------
@@ -103,17 +138,15 @@ void OutputDataWriteNumpyTXTStrategy::writeOutputData(
 
 #ifdef BORNAGAIN_TIFF_SUPPORT
 
-OutputDataWriteTiffStrategy::OutputDataWriteTiffStrategy()
-    : m_d(new TiffHandler)
-{}
+OutputDataWriteTiffStrategy::OutputDataWriteTiffStrategy() : m_d(new TiffHandler) {}
 
 OutputDataWriteTiffStrategy::~OutputDataWriteTiffStrategy()
 {
     delete m_d;
 }
 
-void OutputDataWriteTiffStrategy::writeOutputData(
-    const OutputData<double>& data, std::ostream& output_stream)
+void OutputDataWriteTiffStrategy::writeOutputData(const OutputData<double>& data,
+                                                  std::ostream& output_stream)
 {
     m_d->write(data, output_stream);
 }
diff --git a/Core/InputOutput/OutputDataWriteStrategy.h b/Core/InputOutput/OutputDataWriteStrategy.h
index be3ae9769f801ce583aab3cfdab72b23a4d35809..2061d6193f55d433e10db1b901860a3c7cdd4699 100644
--- a/Core/InputOutput/OutputDataWriteStrategy.h
+++ b/Core/InputOutput/OutputDataWriteStrategy.h
@@ -35,7 +35,7 @@ public:
 //! Strategy to write OutputData to special BornAgain ASCII format
 //! @ingroup input_output_internal
 
-class OutputDataWriteINTStrategy : public IOutputDataWriteStrategy
+class BA_CORE_API_ OutputDataWriteINTStrategy : public IOutputDataWriteStrategy
 {
 public:
     virtual void writeOutputData(const OutputData<double>& data, std::ostream& output_stream);
@@ -44,7 +44,7 @@ public:
 //! Strategy to write OutputData to simple ASCII file with the layout as in numpy.savetxt
 //! @ingroup input_output_internal
 
-class OutputDataWriteNumpyTXTStrategy : public IOutputDataWriteStrategy
+class BA_CORE_API_ OutputDataWriteNumpyTXTStrategy : public IOutputDataWriteStrategy
 {
 public:
     virtual void writeOutputData(const OutputData<double>& data, std::ostream& output_stream);
@@ -57,7 +57,7 @@ class TiffHandler;
 //! Strategy to write OutputData to tiff files
 //! @ingroup input_output_internal
 
-class OutputDataWriteTiffStrategy : public IOutputDataWriteStrategy
+class BA_CORE_API_ OutputDataWriteTiffStrategy : public IOutputDataWriteStrategy
 {
 public:
     OutputDataWriteTiffStrategy();
diff --git a/Core/InputOutput/TiffHandler.cpp b/Core/InputOutput/TiffHandler.cpp
index 6e2a40482dcfb7d948a52745632656719c9eb040..dfe4fe95ee35447f05c8af18c1a296a06dd3f717 100644
--- a/Core/InputOutput/TiffHandler.cpp
+++ b/Core/InputOutput/TiffHandler.cpp
@@ -47,10 +47,14 @@ const OutputData<double> *TiffHandler::getOutputData() const
 
 void TiffHandler::write(const OutputData<double> &data, std::ostream &output_stream)
 {
-    m_tiff = TIFFStreamOpen("MemTIFF", &output_stream);
     m_data.reset(data.clone());
+    if(m_data->getRank() != 2)
+        throw Exceptions::LogicErrorException(
+            "TiffHandler::write -> Error. "
+            "Only 2-dim arrays supported");
+    m_tiff = TIFFStreamOpen("MemTIFF", &output_stream);
     m_width = m_data->getAxis(BornAgain::X_AXIS_INDEX).size();
-    m_height = m_data->getAxis(BornAgain::Y_AXIS_INDEX).size();
+    m_height = m_data->getAxis(BornAgain::Y_AXIS_INDEX).size(); //this does not exist for 1d data
     write_header();
     write_data();
     close();
diff --git a/Core/Instrument/ArrayUtils.cpp b/Core/Instrument/ArrayUtils.cpp
index 20295801679422c827e4f9730386fad9e5733d6f..0bcee2916bde5581c4f1e28d6e29c0cc7754a32b 100644
--- a/Core/Instrument/ArrayUtils.cpp
+++ b/Core/Instrument/ArrayUtils.cpp
@@ -12,13 +12,11 @@
 //
 // ************************************************************************** //
 
-#include "Exceptions.h"
-#include "ArrayUtils.h"
-
 #ifdef BORNAGAIN_PYTHON
-#define PY_ARRAY_UNIQUE_SYMBOL BORNAGAIN_PYTHONAPI_ARRAY
-#define NO_IMPORT_ARRAY
-#include <numpy/arrayobject.h>
+
+#include "ArrayUtils.h"
+#include "Exceptions.h"
+#include "PythonCore.h"
 
 PyObject* ArrayUtils::createNumpyArray(const std::vector<double>& data)
 {
diff --git a/Core/Instrument/ArrayUtils.h b/Core/Instrument/ArrayUtils.h
index 0fa33c760964c476c8c22fa1fb616f50367c63cf..5c2749690f5a77380102eb6d9fdc87bd2902f12a 100644
--- a/Core/Instrument/ArrayUtils.h
+++ b/Core/Instrument/ArrayUtils.h
@@ -17,7 +17,6 @@
 
 #include <vector>
 #include "WinDllMacros.h"
-#include "PythonCore.h"
 #include "OutputData.h"
 #include <stdexcept>
 #include <memory>
diff --git a/Core/Instrument/AxisNames.h b/Core/Instrument/AxisNames.h
index 7d4935d8cf907a319dcbc51dfd6698b4fb1f86df..c83db5e222c63bb2d102007e9ad47f60f582b840 100644
--- a/Core/Instrument/AxisNames.h
+++ b/Core/Instrument/AxisNames.h
@@ -24,14 +24,14 @@
 
 namespace AxisNames
 {
-std::map<AxesUnits, std::string> InitSphericalAxis0();
-std::map<AxesUnits, std::string> InitSphericalAxis1();
-std::map<AxesUnits, std::string> InitRectangularAxis0();
-std::map<AxesUnits, std::string> InitRectangularAxis1();
-std::map<AxesUnits, std::string> InitOffSpecAxis0();
-std::map<AxesUnits, std::string> InitOffSpecAxis1();
-std::map<AxesUnits, std::string> InitSpecAxis();
-std::map<AxesUnits, std::string> InitSampleDepthAxis();
+BA_CORE_API_ std::map<AxesUnits, std::string> InitSphericalAxis0();
+BA_CORE_API_ std::map<AxesUnits, std::string> InitSphericalAxis1();
+BA_CORE_API_ std::map<AxesUnits, std::string> InitRectangularAxis0();
+BA_CORE_API_ std::map<AxesUnits, std::string> InitRectangularAxis1();
+BA_CORE_API_ std::map<AxesUnits, std::string> InitOffSpecAxis0();
+BA_CORE_API_ std::map<AxesUnits, std::string> InitOffSpecAxis1();
+BA_CORE_API_ std::map<AxesUnits, std::string> InitSpecAxis();
+BA_CORE_API_ std::map<AxesUnits, std::string> InitSampleDepthAxis();
 }
 
 #endif // AXISNAMES_H
diff --git a/Core/Instrument/ChiSquaredModule.cpp b/Core/Instrument/ChiSquaredModule.cpp
index 8dedd45ee306d0254e5c9d7247c2d64e312335a0..89c019d0bcab71bdb81b874283cadc5960bf3240 100644
--- a/Core/Instrument/ChiSquaredModule.cpp
+++ b/Core/Instrument/ChiSquaredModule.cpp
@@ -13,35 +13,11 @@
 // ************************************************************************** //
 
 #include "ChiSquaredModule.h"
+#include "IIntensityFunction.h"
+#include "VarianceFunctions.h"
 #include <cassert>
-
-void ChiSquaredModule::processFitElements(std::vector<FitElement>::iterator first,
-                                          std::vector<FitElement>::iterator last)
-{
-    assert(mp_squared_function);
-
-    for (std::vector<FitElement>::iterator it = first; it != last; ++it) {
-        double value_simu = it->getSimulValue();
-        double value_real = it->getRealValue();
-        double weight = it->getWeight();
-
-        if(mp_intensity_function) {
-            value_simu = mp_intensity_function->evaluate(value_simu);
-            value_real = mp_intensity_function->evaluate(value_real);
-        }
-
-        double squared_difference =
-            mp_squared_function->calculateSquaredDifference(
-                value_real, value_simu)*weight;
-
-        it->setSquaredDifference(squared_difference);
-
-        double squared_error = mp_squared_function->calculateSquaredError(value_real, value_simu);
-        double residual = std::sqrt(weight)*(value_simu - value_real)/std::sqrt(squared_error);
-
-        it->setResidual(residual);
-    }
-}
+#include <limits>
+#include <cmath>
 
 double ChiSquaredModule::residual(double a, double b, double weight)
 {
@@ -53,8 +29,8 @@ double ChiSquaredModule::residual(double a, double b, double weight)
         value_real = mp_intensity_function->evaluate(value_real);
     }
 
-    double squared_error = mp_squared_function->calculateSquaredError(value_real, value_simu);
+    double variance = m_variance_function->variance(value_real, value_simu);
+    double normalize = variance <=0 ? std::numeric_limits<double>::min() : std::sqrt(variance);
 
-    double residual = std::sqrt(weight)*(value_simu - value_real)/std::sqrt(squared_error);
-    return residual;
+    return std::sqrt(weight)*(value_simu - value_real)/normalize;
 }
diff --git a/Core/Instrument/ChiSquaredModule.h b/Core/Instrument/ChiSquaredModule.h
index b258091df8c1b3090bab86600e3b922d67729f52..c51f1f637e96200026dec72aaf1da57606a931c1 100644
--- a/Core/Instrument/ChiSquaredModule.h
+++ b/Core/Instrument/ChiSquaredModule.h
@@ -30,9 +30,6 @@ public:
 
     virtual ChiSquaredModule *clone() const { return new ChiSquaredModule(*this); }
 
-    virtual void processFitElements(std::vector<FitElement>::iterator first,
-                                    std::vector<FitElement>::iterator last);
-
     virtual double residual(double a, double b, double weight);
 };
 
diff --git a/Core/Instrument/FitElement.cpp b/Core/Instrument/FitElement.cpp
deleted file mode 100644
index 056cfc9bd221136623f54f24e6ca944fe4ec175c..0000000000000000000000000000000000000000
--- a/Core/Instrument/FitElement.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Instrument/FitElement.cpp
-//! @brief     Implements class FitElement.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "FitElement.h"
-#include <algorithm>
-
-FitElement::FitElement()
-    : m_index(0)
-    , m_simul_value(0.0)
-    , m_real_value(0.0)
-    , m_weight(1.0)
-    , m_squared_difference(0.0)
-    , m_residual(0.0)
-{
-}
-
-FitElement::FitElement(size_t index, double simul_value, double real_value, double weight)
-    : m_index(index)
-    , m_simul_value(simul_value)
-    , m_real_value(real_value)
-    , m_weight(weight)
-    , m_squared_difference(0.0)
-    , m_residual(0.0)
-{
-}
-
-
-FitElement::FitElement(const FitElement &other)
-    : m_index(other.m_index)
-    , m_simul_value(other.m_simul_value)
-    , m_real_value(other.m_real_value)
-    , m_weight(other.m_weight)
-    , m_squared_difference(other.m_squared_difference)
-    , m_residual(other.m_residual)
-{
-
-}
-
-FitElement &FitElement::operator=(const FitElement &other)
-{
-    if (this != &other) {
-        FitElement tmp(other);
-        tmp.swapContent(*this);
-    }
-    return *this;
-}
-
-
-void FitElement::swapContent(FitElement &other)
-{
-    std::swap(this->m_index, other.m_index);
-    std::swap(this->m_simul_value, other.m_simul_value);
-    std::swap(this->m_real_value, other.m_real_value);
-    std::swap(this->m_weight, other.m_weight);
-    std::swap(this->m_squared_difference, other.m_squared_difference);
-    std::swap(this->m_residual, other.m_residual);
-}
-
diff --git a/Core/Instrument/FitElement.h b/Core/Instrument/FitElement.h
deleted file mode 100644
index 90a6d66ef52503a86eb50132b4391685afda2586..0000000000000000000000000000000000000000
--- a/Core/Instrument/FitElement.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Instrument/FitElement.h
-//! @brief     Defines class FitElement.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef FITELEMENT_H
-#define FITELEMENT_H
-
-#include "WinDllMacros.h"
-#include <cstddef>
-
-//! Measured ("real") and simulated scattering intensity value for one detector cell.
-//! Used for chi2/residual calculations.
-//! @ingroup fitting_internal
-
-class BA_CORE_API_ FitElement
-{
-public:
-    FitElement();
-    FitElement(size_t index, double simul_value, double real_value, double weight = 1.0);
-    FitElement(const FitElement& other);
-    FitElement& operator=(const FitElement& other);
-
-    size_t getIndex() const {  return m_index; }
-    double getSimulValue() const { return m_simul_value; }
-    double getRealValue() const { return m_real_value; }
-    double getWeight() const { return m_weight; }
-    double getSquaredDifference() const { return m_squared_difference; }
-    void setSquaredDifference(double value) { m_squared_difference = value; }
-    double getResidual() const { return m_residual; }
-    void setResidual(double value) { m_residual = value; }
-
-private:
-    void swapContent(FitElement& other);
-    size_t m_index; // roiIndex
-    double m_simul_value;
-    double m_real_value;
-    double m_weight;
-    double m_squared_difference;
-    double m_residual;
-};
-
-#endif // FITELEMENT_H
diff --git a/Core/Instrument/IChiSquaredModule.cpp b/Core/Instrument/IChiSquaredModule.cpp
index 42107d4a59b1210414b540ac222b6d5ef95ad37a..adacdc5810f6cebc09030f23e666f6d9d32ce040 100644
--- a/Core/Instrument/IChiSquaredModule.cpp
+++ b/Core/Instrument/IChiSquaredModule.cpp
@@ -13,52 +13,42 @@
 // ************************************************************************** //
 
 #include "IChiSquaredModule.h"
+#include "IIntensityFunction.h"
+#include <VarianceFunctions.h>
 
 IChiSquaredModule::IChiSquaredModule()
-    : mp_squared_function(0)
-    , mp_data_normalizer(0)
-    , mp_intensity_function(0)
+    : m_variance_function(new VarianceSimFunction)
 {
-    mp_squared_function = new SquaredFunctionDefault();
 }
 
-IChiSquaredModule::IChiSquaredModule(const IChiSquaredModule& other)
-    : ICloneable()
-    , mp_squared_function(0)
-    , mp_data_normalizer(0)
-    , mp_intensity_function(0)
+const IVarianceFunction* IChiSquaredModule::varianceFunction() const
 {
-    if(other.mp_squared_function) mp_squared_function = other.mp_squared_function->clone();
-    if(other.mp_data_normalizer) mp_data_normalizer = other.mp_data_normalizer->clone();
-    if(other.mp_intensity_function) mp_intensity_function = other.mp_intensity_function->clone();
+    return m_variance_function.get();
 }
 
-IChiSquaredModule::~IChiSquaredModule()
+IChiSquaredModule::IChiSquaredModule(const IChiSquaredModule& other)
+    : ICloneable()
 {
-    delete mp_squared_function;
-    delete mp_data_normalizer;
-    delete mp_intensity_function;
-}
+    if(other.m_variance_function)
+        m_variance_function.reset(other.m_variance_function->clone());
 
-void IChiSquaredModule::setChiSquaredFunction(ISquaredFunction *squared_function)
-{
-    delete mp_squared_function;
-    mp_squared_function = squared_function;
+    if(other.mp_intensity_function)
+        mp_intensity_function.reset(other.mp_intensity_function->clone());
 }
 
-void IChiSquaredModule::setChiSquaredFunction(const ISquaredFunction& squared_function)
+IChiSquaredModule::~IChiSquaredModule() = default;
+
+void IChiSquaredModule::setVarianceFunction(const IVarianceFunction& variance_function)
 {
-    setChiSquaredFunction(squared_function.clone());
+    m_variance_function.reset(variance_function.clone());
 }
 
-void IChiSquaredModule::setIntensityNormalizer(const IIntensityNormalizer& data_normalizer)
+const IIntensityFunction* IChiSquaredModule::getIntensityFunction() const
 {
-    delete mp_data_normalizer;
-    mp_data_normalizer = data_normalizer.clone();
+    return mp_intensity_function.get();
 }
 
 void IChiSquaredModule::setIntensityFunction(const IIntensityFunction& intensity_function)
 {
-    delete mp_intensity_function;
-    mp_intensity_function = intensity_function.clone();
+    mp_intensity_function.reset(intensity_function.clone());
 }
diff --git a/Core/Instrument/IChiSquaredModule.h b/Core/Instrument/IChiSquaredModule.h
index ea3577713fd0cda293f4c397ddc9a0605d404bee..06a00d52c0ca3c4dfb10d7a0c8d7e37d86565dc4 100644
--- a/Core/Instrument/IChiSquaredModule.h
+++ b/Core/Instrument/IChiSquaredModule.h
@@ -15,15 +15,15 @@
 #ifndef ICHISQUAREDMODULE_H
 #define ICHISQUAREDMODULE_H
 
-#include "FitElement.h"
-#include "IIntensityFunction.h"
-#include "IIntensityNormalizer.h"
-#include "ISquaredFunction.h"
 #include "ICloneable.h"
+#include <memory>
 
-//! Interface for ChiSquaredModule for chi2 calculations.
+class IVarianceFunction;
+class IIntensityNormalizer;
+class IIntensityFunction;
+
+//! Interface residual calculations.
 //! @ingroup fitting_internal
-//! Until BornAgain-1.1, there was another child, ChiSquaredFrequency.
 
 class BA_CORE_API_ IChiSquaredModule : public ICloneable
 {
@@ -35,39 +35,24 @@ public:
     virtual IChiSquaredModule* clone() const = 0;
 
     //! Returns squared function
-    const ISquaredFunction* getSquaredFunction() const { return mp_squared_function; }
-
-    //! Sets squared function // TODO: merge these two functions (SWIG warning 509)
-    void setChiSquaredFunction(ISquaredFunction* squared_function);
-    void setChiSquaredFunction(const ISquaredFunction& squared_function);
-
-    //! Returns data normalizer.
-    virtual const IIntensityNormalizer* getIntensityNormalizer() const {
-        return mp_data_normalizer; }
+    const IVarianceFunction* varianceFunction() const;
 
-    //! Returns data normalizer, non-const version needed to set internals.
-    virtual IIntensityNormalizer* getIntensityNormalizer() {  return mp_data_normalizer; }
-
-    //! Sets data normalizer
-    virtual void setIntensityNormalizer(const IIntensityNormalizer& data_normalizer);
+    //! Sets squared function
+    void setVarianceFunction(const IVarianceFunction& variance_function);
 
     //! Returns data rescaler.
-    virtual const IIntensityFunction* getIntensityFunction() const { return mp_intensity_function; }
+    virtual const IIntensityFunction* getIntensityFunction() const;
 
     //! Sets data rescaler.
     virtual void setIntensityFunction(const IIntensityFunction& intensity_function);
 
-    virtual void processFitElements(std::vector<FitElement>::iterator,
-                                    std::vector<FitElement>::iterator){}
-
     virtual double residual(double a, double b, double weight) = 0;
 
 protected:
     IChiSquaredModule(const IChiSquaredModule& other);
 
-    ISquaredFunction* mp_squared_function;
-    IIntensityNormalizer* mp_data_normalizer;
-    IIntensityFunction* mp_intensity_function;
+    std::unique_ptr<IVarianceFunction> m_variance_function;
+    std::unique_ptr<IIntensityFunction> mp_intensity_function;
 };
 
 #endif // ICHISQUAREDMODULE_H
diff --git a/Core/Instrument/IIntensityFunction.cpp b/Core/Instrument/IIntensityFunction.cpp
index b7e524ec8128cada14dda1572cd96c3c85a1fc03..1e230274b93b793e3ffcba58b0cbc39a0395dc31 100644
--- a/Core/Instrument/IIntensityFunction.cpp
+++ b/Core/Instrument/IIntensityFunction.cpp
@@ -14,13 +14,21 @@
 
 #include "IIntensityFunction.h"
 #include <cmath>
+#include <limits>
+
+IIntensityFunction::~IIntensityFunction() = default;
+
+IntensityFunctionLog* IntensityFunctionLog::clone() const { return new IntensityFunctionLog; }
 
 double IntensityFunctionLog::evaluate(double value) const
 {
-    return value > 0 ? std::log(value) : 0;
+    return value > 0 ? std::log(value) : std::numeric_limits<double>::lowest();
 }
 
+IntensityFunctionSqrt* IntensityFunctionSqrt::clone() const { return new IntensityFunctionSqrt; }
+
 double IntensityFunctionSqrt::evaluate(double value) const
 {
-    return value > 0 ? std::sqrt(value) : 0;
+    return value > 0 ? std::sqrt(value) : std::numeric_limits<double>::lowest();
 }
+
diff --git a/Core/Instrument/IIntensityFunction.h b/Core/Instrument/IIntensityFunction.h
index d001d5c03e381fe9f7ef41c8b7ae1eb526373aea..711c13f96233ae91b39c2a6dbdb680cbbe0272ef 100644
--- a/Core/Instrument/IIntensityFunction.h
+++ b/Core/Instrument/IIntensityFunction.h
@@ -24,7 +24,7 @@
 class BA_CORE_API_ IIntensityFunction
 {
 public:
-    virtual ~IIntensityFunction() {}
+    virtual ~IIntensityFunction();
     virtual IIntensityFunction *clone() const =0;
     virtual double evaluate(double value) const =0;
 };
@@ -36,8 +36,7 @@ public:
 class BA_CORE_API_ IntensityFunctionLog : public IIntensityFunction
 {
 public:
-    virtual ~IntensityFunctionLog() {}
-    virtual IntensityFunctionLog *clone() const { return new IntensityFunctionLog(); }
+    virtual IntensityFunctionLog *clone() const;
     virtual double evaluate(double value) const;
 };
 
@@ -48,8 +47,7 @@ public:
 class BA_CORE_API_ IntensityFunctionSqrt : public IIntensityFunction
 {
 public:
-    virtual ~IntensityFunctionSqrt() {}
-    virtual IntensityFunctionSqrt *clone() const { return new IntensityFunctionSqrt(); }
+    virtual IntensityFunctionSqrt *clone() const;
     virtual double evaluate(double value) const;
 };
 
diff --git a/Core/Instrument/ISquaredFunction.cpp b/Core/Instrument/ISquaredFunction.cpp
deleted file mode 100644
index 56d2cf28d88cca3465a52188498c0c02660454db..0000000000000000000000000000000000000000
--- a/Core/Instrument/ISquaredFunction.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Instrument/ISquaredFunction.cpp
-//! @brief     Implements classes ISquaredFunction, SquaredFunctionDefault, ...
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "ISquaredFunction.h"
-#include "Numeric.h"
-#include <algorithm>
-#include <cmath>
-
-SquaredFunctionDefault* SquaredFunctionDefault::clone() const
-{
-    return new SquaredFunctionDefault();
-}
-
-double SquaredFunctionDefault::calculateSquaredDifference(
-        double real_value, double simulated_value) const
-{
-    if (Numeric::areAlmostEqual(real_value, simulated_value))
-        return 0.;
-    double diff_squared = (simulated_value-real_value)*(simulated_value-real_value);
-    double normalization = calculateSquaredError(real_value);
-    return diff_squared/normalization;
-}
-
-double SquaredFunctionDefault::calculateSquaredError(
-        double real_value, double simulated_value) const
-{
-    (void) simulated_value;
-    return std::max(real_value,1.0);
-}
-
-// ************************************************************************** //
-
-SquaredFunctionSimError* SquaredFunctionSimError::clone() const
-{
-    return new SquaredFunctionSimError();
-}
-
-double SquaredFunctionSimError::calculateSquaredDifference(
-        double real_value, double simulated_value) const
-{
-    if (Numeric::areAlmostEqual(real_value, simulated_value))
-        return 0.0;
-    double diff_squared = (simulated_value-real_value)*(simulated_value-real_value);
-    double normalization = calculateSquaredError(real_value, simulated_value);
-    return diff_squared/normalization;
-}
-
-double SquaredFunctionSimError::calculateSquaredError(double, double simulated_value) const
-{
-    return std::max(simulated_value,1.0);
-}
-
-// ************************************************************************** //
-
-SquaredFunctionMeanSquaredError* SquaredFunctionMeanSquaredError::clone() const
-{
-    return new SquaredFunctionMeanSquaredError();
-}
-
-double SquaredFunctionMeanSquaredError::calculateSquaredDifference(
-        double real_value, double simulated_value) const
-{
-    if (Numeric::areAlmostEqual(real_value, simulated_value)) return 0.0;
-    double diff_squared = (simulated_value-real_value)*(simulated_value-real_value);
-    double normalization = calculateSquaredError(real_value, simulated_value);
-    return diff_squared/normalization;
-}
-
-double SquaredFunctionMeanSquaredError::calculateSquaredError(
-        double real_value, double simulated_value) const
-{
-    (void) simulated_value;
-    double sigma1 = std::max(real_value,1.0);
-    double sigma2 = std::max(simulated_value,1.0);
-    return std::sqrt(sigma1*sigma1 + sigma2*sigma2);
-}
-
-// ************************************************************************** //
-
-SquaredFunctionSystematicError* SquaredFunctionSystematicError::clone() const
-{
-    return new SquaredFunctionSystematicError(m_epsilon);
-}
-
-double SquaredFunctionSystematicError::calculateSquaredDifference(
-        double real_value, double simulated_value) const
-{
-    double diff_squared = (simulated_value-real_value)*(simulated_value-real_value);
-    double normalization = calculateSquaredError(real_value, simulated_value);
-    return diff_squared/normalization;
-}
-
-double SquaredFunctionSystematicError::calculateSquaredError(double real_value, double) const
-{
-    return std::max(std::abs(real_value) + (m_epsilon*real_value)*(m_epsilon*real_value),1.0);
-}
-
-// ************************************************************************** //
-
-SquaredFunctionGaussianError*SquaredFunctionGaussianError::clone() const
-{
-    return new SquaredFunctionGaussianError(m_sigma);
-}
-
-double SquaredFunctionGaussianError::calculateSquaredDifference(
-        double real_value, double simulated_value) const
-{
-    double diff_squared = (simulated_value-real_value)*(simulated_value-real_value);
-    double sigma_squared = m_sigma*m_sigma;
-    return diff_squared/sigma_squared;
-}
-
-double SquaredFunctionGaussianError::calculateSquaredError(double, double) const
-{
-    return m_sigma*m_sigma;
-}
diff --git a/Core/Instrument/ISquaredFunction.h b/Core/Instrument/ISquaredFunction.h
deleted file mode 100644
index 37541fb47d482084828e3b4b75624f41bf00c879..0000000000000000000000000000000000000000
--- a/Core/Instrument/ISquaredFunction.h
+++ /dev/null
@@ -1,119 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Instrument/ISquaredFunction.h
-//! @brief     Defines classes ISquaredFunction, SquaredFunctionDefault, ...
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef ISQUAREDFUNCTION_H
-#define ISQUAREDFUNCTION_H
-
-#include "WinDllMacros.h"
-
-//! Interface providing measures for deviation between two values.
-//! Used By ChiSquaredModule for chi2 calculations.
-//! @ingroup fitting_internal
-
-class BA_CORE_API_ ISquaredFunction
-{
-public:
-    ISquaredFunction() {}
-    virtual ~ISquaredFunction() {}
-    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 =0;
-
-    ISquaredFunction(const ISquaredFunction& ) = delete;
-    ISquaredFunction& operator=(const ISquaredFunction& ) = delete;
-};
-
-
-//! Squared difference between two values.
-//! value = (a-b)*(a-b)/norm, where norm = max(b, 1.0), a = simulated values, b = real_values.
-//! @ingroup fitting
-
-class BA_CORE_API_ SquaredFunctionDefault : public ISquaredFunction
-{
-public:
-    SquaredFunctionDefault() {}
-    ~SquaredFunctionDefault() {}
-    SquaredFunctionDefault* clone() const override;
-    double calculateSquaredDifference(double real_value, double simulated_value) const override;
-    double calculateSquaredError(double real_value, double simulated_value = 0) const override;
-};
-
-
-//! Squared difference between two values.
-//! value = (a-b)*(a-b)/norm, where norm = max(a, 1.0), a = simulated values, b = real_values.
-//! @ingroup fitting
-
-class BA_CORE_API_ SquaredFunctionSimError : public ISquaredFunction
-{
-public:
-    SquaredFunctionSimError() {}
-    ~SquaredFunctionSimError() {}
-    SquaredFunctionSimError *clone() const override;
-    double calculateSquaredDifference(double real_value, double simulated_value) const override;
-    double calculateSquaredError(double real_value, double simulated_value) const override;
-};
-
-
-//! Squared difference between two values normalized by mean squared error.
-//! value = (a-b)*(a-b)/norm, where norm = sqrt(sigma1*sigma1 + sigma2*sigma2),
-//! sigma1=max(a, 1.0), sigma2=max(b,1.0)
-//! @ingroup fitting
-
-class BA_CORE_API_ SquaredFunctionMeanSquaredError : public ISquaredFunction
-{
-public:
-    SquaredFunctionMeanSquaredError() {}
-    ~SquaredFunctionMeanSquaredError() {}
-    SquaredFunctionMeanSquaredError* clone() const override;
-    double calculateSquaredDifference(double real_value, double simulated_value) const override;
-    double calculateSquaredError(double real_value, double simulated_value) const override;
-};
-
-
-//! Squared difference between two values normalized by systematic error.
-//! value = (a-b)*(a-b)/norm, where norm = max(error, 1.0), error = b + (epsilon*b)**2.
-//! @ingroup fitting
-
-class BA_CORE_API_ SquaredFunctionSystematicError : public ISquaredFunction
-{
-public:
-    SquaredFunctionSystematicError(double epsilon = 0.08) : m_epsilon(epsilon){}
-    ~SquaredFunctionSystematicError() {}
-    SquaredFunctionSystematicError *clone() const override;
-    double calculateSquaredDifference(double real_value, double simulated_value) const override;
-    double calculateSquaredError(double real_value, double simulated_value) const override;
-private:
-    double m_epsilon;
-};
-
-
-//! Squared difference between two values with gaussian error.
-//! value = (a-b)*(a-b)/norm, where norm = sigma*sigma; sigma is set by user.
-//! @ingroup fitting
-
-class BA_CORE_API_ SquaredFunctionGaussianError : public ISquaredFunction
-{
-public:
-    SquaredFunctionGaussianError(double sigma = 0.01) : m_sigma(sigma){}
-    ~SquaredFunctionGaussianError() {}
-    SquaredFunctionGaussianError *clone() const override;
-    double calculateSquaredDifference(double real_value, double simulated_value) const override;
-    double calculateSquaredError(double real_value, double simulated_value) const override;
-private:
-    double m_sigma;
-};
-
-#endif // ISQUAREDFUNCTION_H
diff --git a/Core/Instrument/UnitConverter1D.cpp b/Core/Instrument/UnitConverter1D.cpp
index d9037f83440401298eb6f738339a52f8ea33686d..15df3e30fda0bf2b64f82622c8f76929f9d6a9dc 100644
--- a/Core/Instrument/UnitConverter1D.cpp
+++ b/Core/Instrument/UnitConverter1D.cpp
@@ -21,17 +21,20 @@
 #include "UnitConverterUtils.h"
 #include "Units.h"
 
-namespace {
-double getQ(double wavelength, double angle)
+namespace
 {
-    return 4.0 * M_PI * std::sin(angle) / wavelength;
-}
-}
+double getQ(double wavelength, double angle);
+
+double getInvQ(double wavelength, double q);
 
-UnitConverter1D::UnitConverter1D(const Beam& beam, const IAxis& axis)
+std::unique_ptr<PointwiseAxis>
+createTranslatedAxis(const IAxis& axis, std::function<double(double)> translator, std::string name);
+} // namespace
+
+UnitConverter1D::UnitConverter1D(const Beam& beam, const IAxis& axis, AxesUnits axis_units)
     : m_wavelength(beam.getWavelength())
-    , m_axis(axis.clone())
 {
+    m_axis = createTranslatedAxis(axis, getTraslatorFrom(axis_units), axisName(0, axis_units));
     if (m_axis->getMin() < 0 || m_axis->getMax() > M_PI_2)
         throw std::runtime_error("Error in UnitConverter1D: input axis range is out of bounds");
 }
@@ -54,7 +57,7 @@ double UnitConverter1D::calculateMin(size_t i_axis, AxesUnits units_type) const
     units_type = UnitConverterUtils::substituteDefaultUnits(*this, units_type);
     if (units_type == AxesUnits::NBINS)
         return 0.0;
-    auto translator = getTranslator(units_type);
+    auto translator = getTraslatorTo(units_type);
     return translator(m_axis->getBinCenter(0));
 }
 
@@ -64,7 +67,7 @@ double UnitConverter1D::calculateMax(size_t i_axis, AxesUnits units_type) const
     units_type = UnitConverterUtils::substituteDefaultUnits(*this, units_type);
     if (units_type == AxesUnits::NBINS)
         return static_cast<double>(m_axis->size());
-    auto translator = getTranslator(units_type);
+    auto translator = getTraslatorTo(units_type);
     return translator(m_axis->getBinCenter(m_axis->size() - 1));
 }
 
@@ -91,13 +94,7 @@ std::unique_ptr<IAxis> UnitConverter1D::createConvertedAxis(size_t i_axis, AxesU
     if (units == AxesUnits::NBINS)
         return std::make_unique<FixedBinAxis>(axisName(0, units), m_axis->size(),
                                               calculateMin(0, units), calculateMax(0, units));
-
-    auto coordinates = m_axis->getBinCenters();
-    auto translator = getTranslator(units);
-    for (size_t i = 0, size = coordinates.size(); i < size; ++i)
-        coordinates[i] = translator(coordinates[i]);
-    const auto& name = axisName(0, units);
-    return std::make_unique<PointwiseAxis>(name, coordinates);
+    return createTranslatedAxis(*m_axis, getTraslatorTo(units), axisName(0, units));
 }
 
 UnitConverter1D::UnitConverter1D(const UnitConverter1D& other)
@@ -106,9 +103,24 @@ UnitConverter1D::UnitConverter1D(const UnitConverter1D& other)
 {
 }
 
-std::function<double (double)> UnitConverter1D::getTranslator(AxesUnits units_type) const
+std::function<double(double)> UnitConverter1D::getTraslatorFrom(AxesUnits units_type) const
+{
+    switch (units_type) {
+    case AxesUnits::RADIANS:
+        return [](double value) { return value; };
+    case AxesUnits::DEGREES:
+        return [](double value) { return Units::deg2rad(value); };
+    case AxesUnits::QSPACE:
+        return [this](double value) { return getInvQ(m_wavelength, value); };
+    default:
+        throw std::runtime_error(
+            "Error in UnitConverter1D::getTranslatorFrom: unexpected units type");
+    }
+}
+
+std::function<double(double)> UnitConverter1D::getTraslatorTo(AxesUnits units_type) const
 {
-    switch(units_type) {
+    switch (units_type) {
     case AxesUnits::RADIANS:
         return [](double value) { return value; };
     case AxesUnits::DEGREES:
@@ -116,9 +128,8 @@ std::function<double (double)> UnitConverter1D::getTranslator(AxesUnits units_ty
     case AxesUnits::QSPACE:
         return [this](double value) { return getQ(m_wavelength, value); };
     default:
-        throw std::runtime_error("Error in SpecularConverter::calculateValue: "
-                                 "target units not available: "
-                                 + std::to_string(static_cast<int>(units_type)));
+        throw std::runtime_error(
+            "Error in UnitConverter1D::getTranslatorTo: unexpected units type");
     }
 }
 
@@ -128,3 +139,26 @@ std::vector<std::map<AxesUnits, std::string>> UnitConverter1D::createNameMaps()
     result.push_back(AxisNames::InitSpecAxis());
     return result;
 }
+
+namespace
+{
+double getQ(double wavelength, double angle)
+{
+    return 4.0 * M_PI * std::sin(angle) / wavelength;
+}
+
+double getInvQ(double wavelength, double q)
+{
+    double sin_angle = q * wavelength / (4.0 * M_PI);
+    return std::asin(sin_angle);
+}
+
+std::unique_ptr<PointwiseAxis>
+createTranslatedAxis(const IAxis& axis, std::function<double(double)> translator, std::string name)
+{
+    auto coordinates = axis.getBinCenters();
+    for (size_t i = 0, size = coordinates.size(); i < size; ++i)
+        coordinates[i] = translator(coordinates[i]);
+    return std::make_unique<PointwiseAxis>(name, coordinates);
+}
+} // namespace
diff --git a/Core/Instrument/UnitConverter1D.h b/Core/Instrument/UnitConverter1D.h
index cc47f3f4e7f6241924512d9228e7f2a76862c2c5..1c608878e26f2adeb71b846a2a1cf5be02341fbd 100644
--- a/Core/Instrument/UnitConverter1D.h
+++ b/Core/Instrument/UnitConverter1D.h
@@ -29,7 +29,7 @@ class BA_CORE_API_ UnitConverter1D : public IUnitConverter
 public:
     //! Constructs the object for unit conversion. Input axis
     //! is in radians.
-    UnitConverter1D(const Beam& beam, const IAxis& axis);
+    UnitConverter1D(const Beam& beam, const IAxis& axis, AxesUnits axis_units = AxesUnits::RADIANS);
     ~UnitConverter1D() override;
 
     UnitConverter1D* clone() const override;
@@ -58,13 +58,16 @@ public:
 private:
     UnitConverter1D(const UnitConverter1D& other);
 
+    //! Returns translating functional (input units --> rads)
+    std::function<double(double)> getTraslatorFrom(AxesUnits units_type) const;
+
     //! Returns translating functional (rads --> desired units)
-    std::function<double (double)> getTranslator(AxesUnits units_type) const;
+    std::function<double(double)> getTraslatorTo(AxesUnits units_type) const;
 
     //! Creates name map for axis in various units
     std::vector<std::map<AxesUnits, std::string>> createNameMaps() const override;
 
-    double m_wavelength; //!< basic wavelength in nm (for translation to q-space).
+    double m_wavelength;           //!< basic wavelength in nm (for translation to q-space).
     std::unique_ptr<IAxis> m_axis; //!< basic inclination angles (in rads).
 };
 
diff --git a/Core/Instrument/UnitConverterUtils.cpp b/Core/Instrument/UnitConverterUtils.cpp
index 6a4d45517fa6323675d90e049ad1e26e0cbfbea5..bf8a90178feda2755bd111d07be4729d4cac4825 100644
--- a/Core/Instrument/UnitConverterUtils.cpp
+++ b/Core/Instrument/UnitConverterUtils.cpp
@@ -22,6 +22,7 @@
 #include "GISASSimulation.h"
 #include "OffSpecSimulation.h"
 #include "SpecularSimulation.h"
+#include "DepthProbeSimulation.h"
 
 std::unique_ptr<OutputData<double>>
 UnitConverterUtils::createOutputData(const IUnitConverter& converter, AxesUnits units)
@@ -56,6 +57,9 @@ std::unique_ptr<IUnitConverter> UnitConverterUtils::createConverter(const Simula
         return std::make_unique<UnitConverter1D>(spec->getInstrument().getBeam(),
                                                  *spec->getAlphaAxis());
 
+    } else if (auto probe = dynamic_cast<const DepthProbeSimulation*>(&simulation)) {
+        return probe->createUnitConverter();
+
     } else {
         throw std::runtime_error("UnitConverterUtils::createConverter -> "
                                  "Not implemented simulation.");
diff --git a/Core/Instrument/VarianceFunctions.cpp b/Core/Instrument/VarianceFunctions.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..16e3565957ddc0d9b7f209b0b1a8506460c57bdc
--- /dev/null
+++ b/Core/Instrument/VarianceFunctions.cpp
@@ -0,0 +1,43 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      Core/Instrument/VarianceFunctions.cpp
+//! @brief     Implements IVarianceFunction classes
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "VarianceFunctions.h"
+#include <algorithm>
+
+IVarianceFunction::IVarianceFunction() = default;
+IVarianceFunction::~IVarianceFunction() = default;
+
+VarianceConstantFunction* VarianceConstantFunction::clone() const
+{
+    return new VarianceConstantFunction();
+}
+
+double VarianceConstantFunction::variance(double, double) const
+{
+    return 1.0;
+}
+
+VarianceSimFunction::VarianceSimFunction(double epsilon) : m_epsilon(epsilon)
+{
+}
+
+VarianceSimFunction* VarianceSimFunction::clone() const
+{
+    return new VarianceSimFunction(m_epsilon);
+}
+
+double VarianceSimFunction::variance(double /*exp*/, double sim) const
+{
+    return std::max(sim, m_epsilon);
+}
diff --git a/Core/Instrument/VarianceFunctions.h b/Core/Instrument/VarianceFunctions.h
new file mode 100644
index 0000000000000000000000000000000000000000..cf28128ea351e50e9c88f8430620b0354a7fa49e
--- /dev/null
+++ b/Core/Instrument/VarianceFunctions.h
@@ -0,0 +1,59 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      Core/Instrument/VarianceFunctions.h
+//! @brief     Defines IVarianceFunction classes
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef VARIANCEFUNCTIONS_H
+#define VARIANCEFUNCTIONS_H
+
+#include "WinDllMacros.h"
+
+//! Variance function interface.
+//! @ingroup fitting_internal
+
+class BA_CORE_API_ IVarianceFunction
+{
+public:
+    IVarianceFunction();
+    virtual ~IVarianceFunction();
+    virtual IVarianceFunction* clone() const = 0;
+    virtual double variance(double real_value, double simulated_value) const = 0;
+
+    IVarianceFunction(const IVarianceFunction&) = delete;
+    IVarianceFunction& operator=(const IVarianceFunction&) = delete;
+};
+
+//! Returns 1.0 as variance value
+//! @ingroup fitting
+
+class BA_CORE_API_ VarianceConstantFunction : public IVarianceFunction
+{
+public:
+    VarianceConstantFunction* clone() const override;
+    double variance(double, double) const override;
+};
+
+//! Returns max(sim, epsilon)
+//! @ingroup fitting
+
+class BA_CORE_API_ VarianceSimFunction : public IVarianceFunction
+{
+public:
+    explicit VarianceSimFunction(double epsilon = 1.0);
+    VarianceSimFunction* clone() const override;
+    double variance(double exp, double sim) const override;
+
+private:
+    double m_epsilon;
+};
+
+#endif // VARIANCEFUNCTIONS_H
diff --git a/Core/Lattice/ILatticeOrientation.cpp b/Core/Lattice/ILatticeOrientation.cpp
index 74da92e3fbe9694746ac4cf718f193ae114e1815..bee6baa1832e01d2afd8591fccc605a0639b9729 100644
--- a/Core/Lattice/ILatticeOrientation.cpp
+++ b/Core/Lattice/ILatticeOrientation.cpp
@@ -30,7 +30,7 @@ void FillVectorInRow(Eigen::Matrix3d& matrix, kvector_t vec,
 
 ILatticeOrientation::~ILatticeOrientation() =default;
 
-MillerIndex::MillerIndex(int h_, int k_, int l_)
+MillerIndex::MillerIndex(double h_, double k_, double l_)
     : h(h_), k(k_), l(l_)
 {}
 
@@ -91,20 +91,20 @@ bool MillerIndexOrientation::checkAlignment() const
 namespace {
 bool ValidMillerIndex(MillerIndex index)
 {
-    return (index.h != 0 || index.k != 0 || index.l != 0);
+    return (index.h != 0.0 || index.k != 0.0 || index.l != 0.0);
 }
 bool ParallelMillerIndices(MillerIndex index1,
                            MillerIndex index2)
 {
-    int ratio = 0;
-    if (index2.h != 0) {
+    double ratio = 0.0;
+    if (index2.h != 0.0) {
         ratio = index1.h / index2.h;
-    } else if (index2.k != 0) {
+    } else if (index2.k != 0.0) {
         ratio = index1.k / index2.k;
-    } else if (index2.l != 0) {
+    } else if (index2.l != 0.0) {
         ratio = index1.l / index2.l;
     }
-    if (ratio == 0) return false;
+    if (ratio == 0.0) return false;
     return (index1.h == ratio*index2.h && index1.k == ratio*index2.k && index1.l == ratio*index2.l);
 }
 double SignForCrossProduct(MillerIndexOrientation::QComponent q1,
diff --git a/Core/Lattice/ILatticeOrientation.h b/Core/Lattice/ILatticeOrientation.h
index 23ee4717ef30bcacba8db412f75f153d6aef4e5a..6ec53738dd9b25c1d6c362ce8d56e2a6a5a6a810 100644
--- a/Core/Lattice/ILatticeOrientation.h
+++ b/Core/Lattice/ILatticeOrientation.h
@@ -30,9 +30,11 @@ public:
     virtual Transform3D transformationMatrix() const=0;
 };
 
+//! MillerIndex represents arbitrary directions in reciprocal space by allowing floating point
+//! index values
 struct BA_CORE_API_ MillerIndex {
-    MillerIndex(int h_, int k_, int l_);
-    int h, k, l;
+    MillerIndex(double h_, double k_, double l_);
+    double h, k, l;
 };
 
 class BA_CORE_API_ MillerIndexOrientation : public ILatticeOrientation
diff --git a/Core/Lattice/Lattice.cpp b/Core/Lattice/Lattice.cpp
index 775fa83ff133e10f14854a98259fd348c18d2bb9..c28f79775c3bef2439f4cbdca3d2707578a1f951 100644
--- a/Core/Lattice/Lattice.cpp
+++ b/Core/Lattice/Lattice.cpp
@@ -86,7 +86,7 @@ void Lattice::resetBasis(const kvector_t a1, const kvector_t a2, const kvector_t
     onChange();
 }
 
-kvector_t Lattice::getMillerDirection(int h, int k, int l) const
+kvector_t Lattice::getMillerDirection(double h, double k, double l) const
 {
     kvector_t b1, b2, b3;
     getReciprocalLatticeBasis(b1, b2, b3);
diff --git a/Core/Lattice/Lattice.h b/Core/Lattice/Lattice.h
index b7e087e46cd071039e1dffd659ebb69226002bef..a9527c8a17f4a638cec9b1276e3e11ffdab426d1 100644
--- a/Core/Lattice/Lattice.h
+++ b/Core/Lattice/Lattice.h
@@ -54,7 +54,7 @@ public:
     void resetBasis(const kvector_t a1, const kvector_t a2, const kvector_t a3);
 
     //! Returns normalized direction corresponding to the given Miller indices
-    kvector_t getMillerDirection(int h, int k, int l) const;
+    kvector_t getMillerDirection(double h, double k, double l) const;
 
     //! Returns the volume of the unit cell
     double volume() const;
diff --git a/Core/Parametrization/DistributionHandler.cpp b/Core/Parametrization/DistributionHandler.cpp
index 1f992a2fdc8148fd334155dd0e0c2916f7413379..ea2d9f83866b3556cd6103f99e74be0578ae2ae9 100644
--- a/Core/Parametrization/DistributionHandler.cpp
+++ b/Core/Parametrization/DistributionHandler.cpp
@@ -13,6 +13,7 @@
 // ************************************************************************** //
 
 #include "DistributionHandler.h"
+#include "Distributions.h"
 #include "Exceptions.h"
 #include "ParameterPool.h"
 #include "ParameterSample.h"
@@ -68,6 +69,18 @@ double DistributionHandler::setParameterValues(ParameterPool* p_parameter_pool,
     return weight;
 }
 
+void DistributionHandler::setParameterToMeans(ParameterPool* p_parameter_pool) const
+{
+    for (auto& distribution : m_distributions) {
+        const std::string par_name = distribution.getMainParameterName();
+        const double mean_val = distribution.getDistribution()->getMean();
+        if (p_parameter_pool->setMatchedParametersValue(par_name, mean_val) != 1)
+            throw std::runtime_error("Error in DistributionHandler::setParameterToMeans: parameter "
+                                     "name matches nothing or more than "
+                                     "one parameter");
+    }
+}
+
 const DistributionHandler::Distributions_t& DistributionHandler::getDistributions() const
 {
     return m_distributions;
diff --git a/Core/Parametrization/DistributionHandler.h b/Core/Parametrization/DistributionHandler.h
index ae2bd88d896934f3c32526ff8465e2a14f711365..78d3d0261c13ab68879314318e2f7de122115c12 100644
--- a/Core/Parametrization/DistributionHandler.h
+++ b/Core/Parametrization/DistributionHandler.h
@@ -46,7 +46,11 @@ public:
     //! associated with this combination of parameter values
     double setParameterValues(ParameterPool *p_parameter_pool, size_t index);
 
+    //! Sets mean distribution values to the parameter pool.
+    void setParameterToMeans(ParameterPool* p_parameter_pool) const;
+
     const Distributions_t& getDistributions() const;
+
 private:
     size_t m_nbr_combinations;
     Distributions_t m_distributions;
diff --git a/Core/Parametrization/Distributions.cpp b/Core/Parametrization/Distributions.cpp
index 7212c349d3beac8843df05984d9312ce4d94e2fe..a4d289928d141cbd46f082c2ea1ab7b6b7f094a3 100644
--- a/Core/Parametrization/Distributions.cpp
+++ b/Core/Parametrization/Distributions.cpp
@@ -16,12 +16,17 @@
 #include "BornAgainNamespace.h"
 #include "Exceptions.h"
 #include "MathConstants.h"
-#include "ParameterSample.h"
 #include "ParameterPool.h"
+#include "ParameterSample.h"
 #include "RealParameter.h"
+#include <algorithm>
 #include <cmath>
+#include <limits>
 #include <sstream>
 
+namespace {
+bool DoubleEqual(double a, double b);
+}
 
 // ************************************************************************** //
 // class IDistribution1D
@@ -29,65 +34,66 @@
 
 //! Returns equidistant samples, using intrinsic parameters, weighted with probabilityDensity().
 
-std::vector<ParameterSample> IDistribution1D::equidistantSamples(
-    size_t nbr_samples, double sigma_factor, const RealLimits& limits) const
+std::vector<ParameterSample> IDistribution1D::equidistantSamples(size_t nbr_samples,
+                                                                 double sigma_factor,
+                                                                 const RealLimits& limits) const
 {
     if (nbr_samples == 0)
         throw Exceptions::OutOfBoundsException(
             "IDistribution1D::generateSamples: "
             "number of generated samples must be bigger than zero");
     if (isDelta())
-        return { ParameterSample(getMean()) };
-    return generateSamplesFromValues( equidistantPoints( nbr_samples, sigma_factor, limits) );
+        return {ParameterSample(getMean())};
+    return generateSamplesFromValues(equidistantPoints(nbr_samples, sigma_factor, limits));
 }
 
 //! Returns equidistant samples from xmin to xmax, weighted with probabilityDensity().
 
-std::vector<ParameterSample> IDistribution1D::equidistantSamplesInRange(
-    size_t nbr_samples, double xmin, double xmax) const
+std::vector<ParameterSample>
+IDistribution1D::equidistantSamplesInRange(size_t nbr_samples, double xmin, double xmax) const
 {
     if (nbr_samples == 0)
         throw Exceptions::OutOfBoundsException(
             "IDistribution1D::generateSamples: "
             "number of generated samples must be bigger than zero");
     if (isDelta())
-        return { ParameterSample(getMean()) };
-    return generateSamplesFromValues( equidistantPointsInRange(nbr_samples, xmin, xmax) );
+        return {ParameterSample(getMean())};
+    return generateSamplesFromValues(equidistantPointsInRange(nbr_samples, xmin, xmax));
 }
 
 //! Returns equidistant interpolation points from xmin to xmax.
 
-std::vector<double> IDistribution1D::equidistantPointsInRange(
-    size_t nbr_samples, double xmin, double xmax) const
+std::vector<double> IDistribution1D::equidistantPointsInRange(size_t nbr_samples, double xmin,
+                                                              double xmax) const
 {
-    if (nbr_samples < 2 || xmin == xmax)
-        return { getMean() };
+    if (nbr_samples < 2 || DoubleEqual(xmin, xmax))
+        return {getMean()};
     std::vector<double> result(nbr_samples);
-    for (size_t i=0; i<nbr_samples; ++i)
-        result[i] = xmin + i*(xmax-xmin)/(nbr_samples-1.0);
+    for (size_t i = 0; i < nbr_samples; ++i)
+        result[i] = xmin + i * (xmax - xmin) / (nbr_samples - 1.0);
     return result;
 }
 
 void IDistribution1D::setUnits(const std::string& units)
 {
-    for(auto* par: parameterPool()->parameters())
+    for (auto* par : parameterPool()->parameters())
         par->setUnit(units);
 }
 
 void IDistribution1D::SignalBadInitialization(std::string distribution_name)
 {
-    throw Exceptions::ClassInitializationException(
-        distribution_name +": not correctly initialized");
+    throw Exceptions::ClassInitializationException(distribution_name
+                                                   + ": not correctly initialized");
 }
 
-void IDistribution1D::adjustMinMaxForLimits(
-    double& xmin, double& xmax, const RealLimits& limits) const
+void IDistribution1D::adjustMinMaxForLimits(double& xmin, double& xmax,
+                                            const RealLimits& limits) const
 {
-    if(limits.hasLowerLimit() && xmin < limits.lowerLimit())
+    if (limits.hasLowerLimit() && xmin < limits.lowerLimit())
         xmin = limits.lowerLimit();
-    if(limits.hasUpperLimit() && xmax > limits.upperLimit())
+    if (limits.hasUpperLimit() && xmax > limits.upperLimit())
         xmax = limits.upperLimit();
-    if(xmin > xmax) {
+    if (xmin > xmax) {
         std::ostringstream ostr;
         ostr << "IDistribution1D::adjustMinMaxForLimits() -> Error. Can't' adjust ";
         ostr << "xmin:" << xmin << " xmax:" << xmax << " for given limits " << limits << std::endl;
@@ -97,26 +103,24 @@ void IDistribution1D::adjustMinMaxForLimits(
 
 //! Returns weighted samples from given interpolation points and probabilityDensity().
 
-std::vector<ParameterSample> IDistribution1D::generateSamplesFromValues(
-    const std::vector<double>& sample_values) const
+std::vector<ParameterSample>
+IDistribution1D::generateSamplesFromValues(const std::vector<double>& sample_values) const
 {
     std::vector<ParameterSample> result;
     double norm_factor = 0.0;
-    for (double value: sample_values) {
+    for (double value : sample_values) {
         double pdf = probabilityDensity(value);
-        result.push_back( ParameterSample(value, pdf) );
+        result.push_back(ParameterSample(value, pdf));
         norm_factor += pdf;
     }
     if (norm_factor <= 0.0)
-        throw Exceptions::RuntimeErrorException(
-            "IDistribution1D::generateSamples: "
-            "total probability must be bigger than zero");
-    for (ParameterSample& sample: result)
+        throw Exceptions::RuntimeErrorException("IDistribution1D::generateSamples: "
+                                                "total probability must be bigger than zero");
+    for (ParameterSample& sample : result)
         sample.weight /= norm_factor;
     return result;
 }
 
-
 // ************************************************************************** //
 // class DistributionGate
 // ************************************************************************** //
@@ -130,13 +134,15 @@ DistributionGate::DistributionGate(double min, double max) : m_min(min), m_max(m
 
 double DistributionGate::probabilityDensity(double x) const
 {
-    if (x < m_min || x > m_max) return 0.0;
-    if (m_min == m_max) return 1.0;
-    return 1.0/(m_max-m_min);
+    if (x < m_min || x > m_max)
+        return 0.0;
+    if (DoubleEqual(m_min, m_max))
+        return 1.0;
+    return 1.0 / (m_max - m_min);
 }
 
-std::vector<double> DistributionGate::equidistantPoints(
-    size_t nbr_samples, double sigma_factor, const RealLimits& limits) const
+std::vector<double> DistributionGate::equidistantPoints(size_t nbr_samples, double sigma_factor,
+                                                        const RealLimits& limits) const
 {
     (void)sigma_factor;
     double xmin = m_min;
@@ -153,19 +159,17 @@ void DistributionGate::init_parameters()
 
 bool DistributionGate::isDelta() const
 {
-    return m_max == m_min;
+    return DoubleEqual(m_min, m_max);
 }
 
 bool DistributionGate::checkInitialization() const
 {
     if (m_max < m_min) {
         SignalBadInitialization(BornAgain::DistributionGateType);
-        return false;
     }
     return true;
 }
 
-
 // ************************************************************************** //
 // class DistributionLorentz
 // ************************************************************************** //
@@ -180,17 +184,17 @@ DistributionLorentz::DistributionLorentz(double mean, double hwhm) : m_mean(mean
 double DistributionLorentz::probabilityDensity(double x) const
 {
     if (m_hwhm == 0.0)
-        return x==m_mean ? 1.0 : 0.0;
-    return m_hwhm/(m_hwhm*m_hwhm + (x-m_mean)*(x-m_mean))/M_PI;
+        return DoubleEqual(x, m_mean) ? 1.0 : 0.0;
+    return m_hwhm / (m_hwhm * m_hwhm + (x - m_mean) * (x - m_mean)) / M_PI;
 }
 
-std::vector<double> DistributionLorentz::equidistantPoints(
-    size_t nbr_samples, double sigma_factor, const RealLimits& limits) const
+std::vector<double> DistributionLorentz::equidistantPoints(size_t nbr_samples, double sigma_factor,
+                                                           const RealLimits& limits) const
 {
     if (sigma_factor <= 0.0)
         sigma_factor = 2.0;
-    double xmin = m_mean - sigma_factor*m_hwhm;
-    double xmax = m_mean + sigma_factor*m_hwhm;
+    double xmin = m_mean - sigma_factor * m_hwhm;
+    double xmax = m_mean + sigma_factor * m_hwhm;
     adjustMinMaxForLimits(xmin, xmax, limits);
     return equidistantPointsInRange(nbr_samples, xmin, xmax);
 }
@@ -210,19 +214,16 @@ bool DistributionLorentz::checkInitialization() const
 {
     if (m_hwhm < 0.0) {
         SignalBadInitialization(BornAgain::DistributionLorentzType);
-        return false;
     }
     return true;
 }
 
-
 // ************************************************************************** //
 // class DistributionGaussian
 // ************************************************************************** //
 
 DistributionGaussian::DistributionGaussian(double mean, double std_dev)
-    : m_mean(mean)
-    , m_std_dev(std_dev)
+    : m_mean(mean), m_std_dev(std_dev)
 {
     setName(BornAgain::DistributionGaussianType);
     checkInitialization();
@@ -232,18 +233,18 @@ DistributionGaussian::DistributionGaussian(double mean, double std_dev)
 double DistributionGaussian::probabilityDensity(double x) const
 {
     if (m_std_dev == 0.0)
-        return x==m_mean ? 1.0 : 0.0;
-    double exponential = std::exp(-(x-m_mean)*(x-m_mean) / (2.0*m_std_dev*m_std_dev));
-    return exponential/m_std_dev/std::sqrt(M_TWOPI);
+        return DoubleEqual(x, m_mean) ? 1.0 : 0.0;
+    double exponential = std::exp(-(x - m_mean) * (x - m_mean) / (2.0 * m_std_dev * m_std_dev));
+    return exponential / m_std_dev / std::sqrt(M_TWOPI);
 }
 
-std::vector<double> DistributionGaussian::equidistantPoints(
-    size_t nbr_samples, double sigma_factor, const RealLimits& limits) const
+std::vector<double> DistributionGaussian::equidistantPoints(size_t nbr_samples, double sigma_factor,
+                                                            const RealLimits& limits) const
 {
     if (sigma_factor <= 0.0)
         sigma_factor = 2.0;
-    double xmin = m_mean - sigma_factor*m_std_dev;
-    double xmax = m_mean + sigma_factor*m_std_dev;
+    double xmin = m_mean - sigma_factor * m_std_dev;
+    double xmax = m_mean + sigma_factor * m_std_dev;
     adjustMinMaxForLimits(xmin, xmax, limits);
     return equidistantPointsInRange(nbr_samples, xmin, xmax);
 }
@@ -263,19 +264,16 @@ bool DistributionGaussian::checkInitialization() const
 {
     if (m_std_dev < 0.0) {
         SignalBadInitialization(BornAgain::DistributionGaussianType);
-        return false;
     }
     return true;
 }
 
-
 // ************************************************************************** //
 // class DistributionLogNormal
 // ************************************************************************** //
 
 DistributionLogNormal::DistributionLogNormal(double median, double scale_param)
-    : m_median(median)
-    , m_scale_param(scale_param)
+    : m_median(median), m_scale_param(scale_param)
 {
     setName(BornAgain::DistributionLogNormalType);
     checkInitialization();
@@ -284,30 +282,31 @@ DistributionLogNormal::DistributionLogNormal(double median, double scale_param)
 
 double DistributionLogNormal::probabilityDensity(double x) const
 {
-    if (m_scale_param==0.0)
-        return x==m_median ? 1.0 : 0.0;
-    double t = std::log(x/m_median)/m_scale_param;
-    return std::exp(-t*t/2.0)/(x*m_scale_param*std::sqrt(M_TWOPI));
+    if (m_scale_param == 0.0)
+        return DoubleEqual(x, m_median)  ? 1.0 : 0.0;
+    double t = std::log(x / m_median) / m_scale_param;
+    return std::exp(-t * t / 2.0) / (x * m_scale_param * std::sqrt(M_TWOPI));
 }
 
 double DistributionLogNormal::getMean() const
 {
-    double exponent = m_scale_param*m_scale_param/2.0;
-    return m_median*std::exp(exponent);
+    double exponent = m_scale_param * m_scale_param / 2.0;
+    return m_median * std::exp(exponent);
 }
 
-std::vector<double> DistributionLogNormal::equidistantPoints(
-    size_t nbr_samples, double sigma_factor, const RealLimits& limits) const
+std::vector<double> DistributionLogNormal::equidistantPoints(size_t nbr_samples,
+                                                             double sigma_factor,
+                                                             const RealLimits& limits) const
 {
-    if(nbr_samples < 2) {
+    if (nbr_samples < 2) {
         std::vector<double> result;
         result.push_back(m_median);
         return result;
     }
     if (sigma_factor <= 0.0)
         sigma_factor = 2.0;
-    double xmin = m_median*std::exp(-sigma_factor*m_scale_param);
-    double xmax = m_median*std::exp(sigma_factor*m_scale_param);
+    double xmin = m_median * std::exp(-sigma_factor * m_scale_param);
+    double xmax = m_median * std::exp(sigma_factor * m_scale_param);
     adjustMinMaxForLimits(xmin, xmax, limits);
     return equidistantPointsInRange(nbr_samples, xmin, xmax);
 }
@@ -333,19 +332,15 @@ bool DistributionLogNormal::checkInitialization() const
 {
     if (m_scale_param < 0.0 || m_median <= 0.0) {
         SignalBadInitialization(BornAgain::DistributionLogNormalType);
-        return false;
     }
     return true;
 }
 
-
 // ************************************************************************** //
 // class DistributionCosine
 // ************************************************************************** //
 
-DistributionCosine::DistributionCosine(double mean, double sigma)
-    : m_mean(mean)
-    , m_sigma(sigma)
+DistributionCosine::DistributionCosine(double mean, double sigma) : m_mean(mean), m_sigma(sigma)
 {
     setName(BornAgain::DistributionCosineType);
     checkInitialization();
@@ -355,19 +350,19 @@ DistributionCosine::DistributionCosine(double mean, double sigma)
 double DistributionCosine::probabilityDensity(double x) const
 {
     if (m_sigma == 0.0)
-        return x==m_mean ? 1.0 : 0.0;
-    if (std::abs(x-m_mean)>M_PI*m_sigma)
+        return DoubleEqual(x, m_mean) ? 1.0 : 0.0;
+    if (std::abs(x - m_mean) > M_PI * m_sigma)
         return 0.0;
-    return (1.0 + std::cos((x-m_mean)/m_sigma))/(m_sigma*M_TWOPI);
+    return (1.0 + std::cos((x - m_mean) / m_sigma)) / (m_sigma * M_TWOPI);
 }
 
-std::vector<double> DistributionCosine::equidistantPoints(
-    size_t nbr_samples, double sigma_factor, const RealLimits& limits) const
+std::vector<double> DistributionCosine::equidistantPoints(size_t nbr_samples, double sigma_factor,
+                                                          const RealLimits& limits) const
 {
     if (sigma_factor <= 0.0 || sigma_factor > 2.0)
         sigma_factor = 2.0;
-    double xmin = m_mean - sigma_factor*m_sigma*M_PI_2;
-    double xmax = m_mean + sigma_factor*m_sigma*M_PI_2;
+    double xmin = m_mean - sigma_factor * m_sigma * M_PI_2;
+    double xmax = m_mean + sigma_factor * m_sigma * M_PI_2;
     adjustMinMaxForLimits(xmin, xmax, limits);
     return equidistantPointsInRange(nbr_samples, xmin, xmax);
 }
@@ -387,7 +382,6 @@ bool DistributionCosine::checkInitialization() const
 {
     if (m_sigma < 0.0) {
         SignalBadInitialization(BornAgain::DistributionCosineType);
-        return false;
     }
     return true;
 }
@@ -396,12 +390,9 @@ bool DistributionCosine::checkInitialization() const
 // class DistributionTrapezoidal
 // ************************************************************************** //
 
-DistributionTrapezoid::DistributionTrapezoid(double center, double left_width,
-                                             double middle_width, double right_width)
-    : m_center(center)
-    , m_left(left_width)
-    , m_middle(middle_width)
-    , m_right(right_width)
+DistributionTrapezoid::DistributionTrapezoid(double center, double left_width, double middle_width,
+                                             double right_width)
+    : m_center(center), m_left(left_width), m_middle(middle_width), m_right(right_width)
 {
     setName(BornAgain::DistributionTrapezoidType);
     checkInitialization();
@@ -410,29 +401,33 @@ DistributionTrapezoid::DistributionTrapezoid(double center, double left_width,
 
 double DistributionTrapezoid::probabilityDensity(double x) const
 {
-    double height = 2.0/(m_left + 2.0*m_middle + m_right);
-    double min = m_center - m_middle/2.0 - m_left;
-    if (x < min) return 0.0;
-    if (x < min + m_left) return (x - min)*height/m_left;
-    if (x < min + m_left + m_middle) return height;
+    double height = 2.0 / (m_left + 2.0 * m_middle + m_right);
+    double min = m_center - m_middle / 2.0 - m_left;
+    if (x < min)
+        return 0.0;
+    if (x < min + m_left)
+        return (x - min) * height / m_left;
+    if (x < min + m_left + m_middle)
+        return height;
     if (x < min + m_left + m_middle + m_right) {
-        return height - (x - min -m_left - m_middle)*height/m_right;
+        return height - (x - min - m_left - m_middle) * height / m_right;
     }
     return 0.0;
 }
 
-std::vector<double> DistributionTrapezoid::equidistantPoints(
-        size_t nbr_samples, double, const RealLimits& limits) const
+std::vector<double> DistributionTrapezoid::equidistantPoints(size_t nbr_samples, double,
+                                                             const RealLimits& limits) const
 {
-    double xmin = m_center - m_middle/2.0 - m_left;
+    double xmin = m_center - m_middle / 2.0 - m_left;
     double xmax = xmin + m_left + m_middle + m_right;
+    adjustLimitsToNonZeroSamples(xmin, xmax, nbr_samples);
     adjustMinMaxForLimits(xmin, xmax, limits);
     return equidistantPointsInRange(nbr_samples, xmin, xmax);
 }
 
 bool DistributionTrapezoid::isDelta() const
 {
-    return (m_left + m_middle +m_right)==0.0;
+    return (m_left + m_middle + m_right) == 0.0;
 }
 
 void DistributionTrapezoid::init_parameters()
@@ -445,9 +440,36 @@ void DistributionTrapezoid::init_parameters()
 
 bool DistributionTrapezoid::checkInitialization() const
 {
-    if (m_left< 0.0 || m_middle < 0.0 || m_right < 0.0) {
+    if (m_left < 0.0 || m_middle < 0.0 || m_right < 0.0) {
         SignalBadInitialization(BornAgain::DistributionTrapezoidType);
-        return false;
     }
     return true;
 }
+
+void DistributionTrapezoid::adjustLimitsToNonZeroSamples(double& min, double& max,
+                                                         size_t nbr_samples) const
+{
+    if (nbr_samples <= 1)
+        return;
+    size_t N = nbr_samples;
+    if (m_left > 0.0)
+        ++N;
+    if (m_right > 0.0)
+        ++N;
+    if (N == nbr_samples)
+        return;
+    double step = (max - min) / (N - 1);
+    if (m_left > 0.0)
+        min += step;
+    if (m_right > 0.0)
+        max -= step;
+}
+
+namespace {
+bool DoubleEqual(double a, double b)
+{
+    double eps = 10.0 * std::max(std::abs(a)*std::numeric_limits<double>::epsilon(),
+                                 std::numeric_limits<double>::min());
+    return std::abs(a-b) < eps;
+}
+}
diff --git a/Core/Parametrization/Distributions.h b/Core/Parametrization/Distributions.h
index 4b15b99dcbd20cb2004c6f7d8593ff2166a41d5b..32f63f9dd9df2e0131336d8082fe5444080283e7 100644
--- a/Core/Parametrization/Distributions.h
+++ b/Core/Parametrization/Distributions.h
@@ -67,8 +67,10 @@ public:
     virtual void setUnits(const std::string& units);
 
 protected:
+#ifndef SWIG
     //! this function is called during bad initialization of a subclass
-    static void SignalBadInitialization(std::string distribution_name);
+    [[noreturn]] static void SignalBadInitialization(std::string distribution_name);
+#endif
 
     //! modifies xmin and xmax if they are outside of limits
     void adjustMinMaxForLimits(double& xmin, double& xmax, const RealLimits& limits) const;
@@ -303,6 +305,7 @@ protected:
 private:
     //! check initialization
     bool checkInitialization() const;
+    void adjustLimitsToNonZeroSamples(double& min, double& max, size_t nbr_samples) const;
     double m_center;
     double m_left;
     double m_middle;
diff --git a/Core/Parametrization/INodeVisitor.h b/Core/Parametrization/INodeVisitor.h
index 81eb7b48acbb889eded17a4326f23d960c317bd9..8706250f4f2095349ca4a1c24e1cf96f416afceb 100644
--- a/Core/Parametrization/INodeVisitor.h
+++ b/Core/Parametrization/INodeVisitor.h
@@ -28,8 +28,6 @@ class DistributionGaussian;
 class DistributionLogNormal;
 class DistributionLorentz;
 class DistributionTrapezoid;
-class FitObject;
-class FitSuiteObjects;
 class FootprintFactorGaussian;
 class FootprintFactorSquare;
 class FormFactorAnisoPyramid;
@@ -53,6 +51,7 @@ class FormFactorFullSpheroid;
 class FormFactorGauss;
 class FormFactorHemiEllipsoid;
 class FormFactorIcosahedron;
+class FormFactorLongBox;
 class FormFactorLongBoxGauss;
 class FormFactorLongBoxLorentz;
 class FormFactorLorentz;
@@ -103,12 +102,13 @@ class IntensityNormalizer;
 class IntensityScaleAndShiftNormalizer;
 class InterferenceFunction1DLattice;
 class InterferenceFunction2DLattice;
-class InterferenceFunction3DLattice;
+class InterferenceFunction2DParaCrystal;
 class InterferenceFunction2DSuperLattice;
+class InterferenceFunction3DLattice;
 class InterferenceFunctionFinite2DLattice;
-class InterferenceFunction2DParaCrystal;
-class InterferenceFunctionNone;
+class InterferenceFunctionFinite3DLattice;
 class InterferenceFunctionRadialParaCrystal;
+class InterferenceFunctionNone;
 class IParticle;
 class IPeakShape;
 class IRotation;
@@ -159,8 +159,6 @@ public:
     virtual void visit(const DistributionLogNormal*) {}
     virtual void visit(const DistributionLorentz*) {}
     virtual void visit(const DistributionTrapezoid*) {}
-    virtual void visit(const FitObject*) {}
-    virtual void visit(const FitSuiteObjects*) {}
     virtual void visit(const FootprintFactorGaussian*) {}
     virtual void visit(const FootprintFactorSquare*) {}
     virtual void visit(const FormFactorAnisoPyramid*) {}
@@ -184,6 +182,7 @@ public:
     virtual void visit(const FormFactorGauss*) {}
     virtual void visit(const FormFactorHemiEllipsoid*) {}
     virtual void visit(const FormFactorIcosahedron*) {}
+    virtual void visit(const FormFactorLongBox*) {}
     virtual void visit(const FormFactorLongBoxGauss*) {}
     virtual void visit(const FormFactorLongBoxLorentz*) {}
     virtual void visit(const FormFactorLorentz*) {}
@@ -234,12 +233,13 @@ public:
     virtual void visit(const IntensityScaleAndShiftNormalizer*) {}
     virtual void visit(const InterferenceFunction1DLattice*) {}
     virtual void visit(const InterferenceFunction2DLattice*) {}
-    virtual void visit(const InterferenceFunction3DLattice*) {}
+    virtual void visit(const InterferenceFunction2DParaCrystal*) {}
     virtual void visit(const InterferenceFunction2DSuperLattice*) {}
+    virtual void visit(const InterferenceFunction3DLattice*) {}
     virtual void visit(const InterferenceFunctionFinite2DLattice*) {}
-    virtual void visit(const InterferenceFunction2DParaCrystal*) {}
-    virtual void visit(const InterferenceFunctionNone*) {}
+    virtual void visit(const InterferenceFunctionFinite3DLattice*) {}
     virtual void visit(const InterferenceFunctionRadialParaCrystal*) {}
+    virtual void visit(const InterferenceFunctionNone*) {}
     virtual void visit(const IParticle*) {}
     virtual void visit(const IPeakShape*) {}
     virtual void visit(const IRotation*) {}
diff --git a/Core/Simulation/DepthProbeSimulation.cpp b/Core/Simulation/DepthProbeSimulation.cpp
index 0921c837204a13b23ae49d51baaf0bae5338be68..b5d1ab339b1e945e93bc3a2301e686e0aac98b52 100644
--- a/Core/Simulation/DepthProbeSimulation.cpp
+++ b/Core/Simulation/DepthProbeSimulation.cpp
@@ -66,8 +66,7 @@ SimulationResult DepthProbeSimulation::result() const
 {
     validityCheck();
     auto data = createIntensityData();
-    DepthProbeConverter converter(m_instrument.getBeam(), *m_alpha_axis, *m_z_axis);
-    return SimulationResult(*data, converter);
+    return SimulationResult(*data, *createUnitConverter().get());
 }
 
 void DepthProbeSimulation::setBeamParameters(double lambda, int nbins, double alpha_i_min,
@@ -101,6 +100,11 @@ const IAxis* DepthProbeSimulation::getZAxis() const
     return m_z_axis.get();
 }
 
+std::unique_ptr<IUnitConverter> DepthProbeSimulation::createUnitConverter() const
+{
+    return std::make_unique<DepthProbeConverter>(m_instrument.getBeam(), *m_alpha_axis, *m_z_axis);
+}
+
 DepthProbeSimulation::DepthProbeSimulation(const DepthProbeSimulation& other)
     : Simulation(other)
     , m_sim_elements(other.m_sim_elements)
diff --git a/Core/Simulation/DepthProbeSimulation.h b/Core/Simulation/DepthProbeSimulation.h
index fea81232513400cfef1b333a656bda5359456c57..86a7207267473f9574dc85b4d880a8dc5f571c49 100644
--- a/Core/Simulation/DepthProbeSimulation.h
+++ b/Core/Simulation/DepthProbeSimulation.h
@@ -15,6 +15,7 @@ class ISample;
 class IMultiLayerBuilder;
 class MultiLayer;
 class Histogram1D;
+class IUnitConverter;
 
 class BA_CORE_API_ DepthProbeSimulation : public Simulation
 {
@@ -48,6 +49,10 @@ public:
     //! Returns a pointer to z-position axis.
     const IAxis* getZAxis() const;
 
+#ifndef SWIG
+    std::unique_ptr<IUnitConverter> createUnitConverter() const;
+#endif
+
 private:
     DepthProbeSimulation(const DepthProbeSimulation& other);
 
diff --git a/Core/Simulation/Simulation.cpp b/Core/Simulation/Simulation.cpp
index 309aadd535efeddeae74ddd80796f2e93dac6c8b..903e069b95ec6772915475bb24d488c3a6a729d6 100644
--- a/Core/Simulation/Simulation.cpp
+++ b/Core/Simulation/Simulation.cpp
@@ -145,6 +145,7 @@ void Simulation::runSimulation()
         double weight = m_distribution_handler.setParameterValues(P_param_pool.get(), index);
         runSingleSimulation(batch_start, batch_size, weight);
     }
+    m_distribution_handler.setParameterToMeans(P_param_pool.get());
     moveDataFromCache();
     transferResultsToIntensityMap();
 }
diff --git a/Core/Simulation/SpecularSimulation.cpp b/Core/Simulation/SpecularSimulation.cpp
index 2806ca6f2ac3e8b0fe1f730f7b35c80e96c84a69..c9dd33a8fb87c262e66d3d5ec17c04496639ba9b 100644
--- a/Core/Simulation/SpecularSimulation.cpp
+++ b/Core/Simulation/SpecularSimulation.cpp
@@ -65,6 +65,10 @@ void SpecularSimulation::prepareSimulation()
                                  "not properly configured.");
     getInstrument().initDetector();
     Simulation::prepareSimulation();
+    const MultiLayer* sample = m_sample_provider.sample();
+    if (sample->containsMagneticMaterial() || sample->externalField() != kvector_t{})
+        throw std::runtime_error("Error in SpecularSimulation::prepareSimulation: magnetized "
+                                 "samples are not currently handled.");
 }
 
 size_t SpecularSimulation::numberOfSimulationElements() const
diff --git a/Core/StandardSamples/ParticleDistributionsBuilder.cpp b/Core/StandardSamples/ParticleDistributionsBuilder.cpp
index 8ee5bc737f7a5f394708f0e81e09dbbd830f8815..a9ac28c8ac3b814a4bab5db0e07c710f79780c19 100644
--- a/Core/StandardSamples/ParticleDistributionsBuilder.cpp
+++ b/Core/StandardSamples/ParticleDistributionsBuilder.cpp
@@ -29,6 +29,7 @@
 #include "FormFactorCone.h"
 #include "Units.h"
 #include "ParameterSample.h"
+#include "FormFactorBox.h"
 
 CylindersWithSizeDistributionBuilder::CylindersWithSizeDistributionBuilder()
     : m_height(5*Units::nanometer)
@@ -56,7 +57,8 @@ MultiLayer* CylindersWithSizeDistributionBuilder::buildSample() const
     DistributionGaussian gauss(m_radius, sigma);
     ParameterPattern pattern;
     pattern.add(BornAgain::ParticleType).add(BornAgain::FFCylinderType).add(BornAgain::Radius);
-    ParameterDistribution par_distr(pattern.toStdString(), gauss, n_samples, n_sigma);
+    ParameterDistribution par_distr(pattern.toStdString(), gauss, static_cast<size_t>(n_samples),
+                                    n_sigma);
     ParticleDistribution particle_collection(nano_particle, par_distr);
     particle_layout.addParticle(particle_collection);
 
@@ -115,7 +117,8 @@ MultiLayer* TwoTypesCylindersDistributionBuilder::buildSample() const
     particle_layout.addParticle(particle_collection1, 0.95);
     ParameterPattern pattern2;
     pattern2.add(BornAgain::ParticleType).add(BornAgain::FFCylinderType).add(BornAgain::Radius);
-    ParameterDistribution par_distr2(pattern2.toStdString(), gauss2, nbins, n_sigma);
+    ParameterDistribution par_distr2(pattern2.toStdString(), gauss2, static_cast<size_t>(nbins),
+                                     n_sigma);
     ParticleDistribution particle_collection2(cylinder2, par_distr2);
     particle_layout.addParticle(particle_collection2, 0.05);
 
@@ -237,3 +240,38 @@ MultiLayer* ConesWithLimitsDistributionBuilder::buildSample() const
 
     return multi_layer;
 }
+
+MultiLayer* LinkedBoxDistributionBuilder::buildSample() const
+{
+    Material air_material = HomogeneousMaterial("Air", 0.0, 0.0);
+    Material substrate_material = HomogeneousMaterial("Substrate", 6e-6, 2e-8);
+    Material particle_material = HomogeneousMaterial("Particle", 6e-4, 2e-8);
+
+    // particle
+    FormFactorBox ff(40.0*Units::nm, 30.0*Units::nm, 10.0*Units::nm);
+    Particle box(particle_material, ff);
+
+    // particle collection
+    DistributionGate gate(10.0*Units::nm, 70.0*Units::nm);
+    ParameterDistribution parameter_distr("/Particle/Box/Length", gate, 3, 0.0,
+                                          RealLimits::limited(1.0*Units::nm, 200.0*Units::nm));
+    parameter_distr.linkParameter("/Particle/Box/Width").linkParameter("/Particle/Box/Height");
+
+    ParticleDistribution collection(box, parameter_distr);
+
+    ParticleLayout particle_layout;
+    particle_layout.addParticle(collection);
+    particle_layout.setTotalParticleSurfaceDensity(1e-4);
+
+    // Multi layer
+    Layer air_layer(air_material);
+    Layer substrate_layer(substrate_material);
+
+    air_layer.addLayout(particle_layout);
+
+    MultiLayer* multi_layer = new MultiLayer();
+    multi_layer->addLayer(air_layer);
+    multi_layer->addLayer(substrate_layer);
+
+    return multi_layer;
+}
diff --git a/Core/StandardSamples/ParticleDistributionsBuilder.h b/Core/StandardSamples/ParticleDistributionsBuilder.h
index 8f591a3f430222fddd5788564f2400dbfa3e8c61..e8b5b4be50e88cbc90e90ad352df85cfd6f64c6c 100644
--- a/Core/StandardSamples/ParticleDistributionsBuilder.h
+++ b/Core/StandardSamples/ParticleDistributionsBuilder.h
@@ -86,5 +86,15 @@ public:
     MultiLayer* buildSample() const;
 };
 
+//! Distribution of boxes with main parameter and two linked parameters.
+//! @ingroup standard_samples
+
+class LinkedBoxDistributionBuilder : public IMultiLayerBuilder
+{
+public:
+    LinkedBoxDistributionBuilder() = default;
+    MultiLayer* buildSample() const;
+};
+
 
 #endif // PARTICLEDISTRIBUTIONSBUILDER_H
diff --git a/Core/StandardSamples/SampleBuilderFactory.cpp b/Core/StandardSamples/SampleBuilderFactory.cpp
index 70fa1d25515c03d180e49e4519096b48034e1b3f..da574a32374dced07d98e37dc20de4c224353de4 100644
--- a/Core/StandardSamples/SampleBuilderFactory.cpp
+++ b/Core/StandardSamples/SampleBuilderFactory.cpp
@@ -308,6 +308,11 @@ SampleBuilderFactory::SampleBuilderFactory()
         create_new<ConesWithLimitsDistributionBuilder>,
         "Cones with the distribution applied to the angle and RealLimits defined.");
 
+    registerItem(
+        "LinkedBoxDistributionBuilder",
+        create_new<LinkedBoxDistributionBuilder>,
+        "Distribution of boxes with main parameter and two linked parameters.");
+
     registerItem(
         "HomogeneousMultilayerBuilder",
         create_new<HomogeneousMultilayerBuilder>,
diff --git a/Core/StandardSamples/SimulationFactory.cpp b/Core/StandardSamples/SimulationFactory.cpp
index 90f180c0aa919447d75bcefbf0514aac8dc2355e..f0ca3dd21211a70ea10388e23452b8c6e565685e 100644
--- a/Core/StandardSamples/SimulationFactory.cpp
+++ b/Core/StandardSamples/SimulationFactory.cpp
@@ -158,4 +158,9 @@ SimulationFactory::SimulationFactory()
     registerItem("BasicDepthProbe",
                  StandardSimulations::BasicDepthProbe,
                  "Basic 20x20 depth probe simulation with [0, 1] deg angle and [-100, 100] z span");
+
+    registerItem("MiniGISASFit",
+                 StandardSimulations::MiniGISASFit,
+                 "GISAS simulation with small 25x25 detector and phi[-2,2], theta[0,2]. "
+                 "Beam intensity is set");
 }
diff --git a/Core/StandardSamples/StandardSimulations.cpp b/Core/StandardSamples/StandardSimulations.cpp
index 46e5fd15907fc151ff3f7062ccf414884e694a86..912619ccb7ac0980615e7167aaf26018d5d24825 100644
--- a/Core/StandardSamples/StandardSimulations.cpp
+++ b/Core/StandardSamples/StandardSimulations.cpp
@@ -488,3 +488,15 @@ DepthProbeSimulation* StandardSimulations::BasicDepthProbe()
 
     return result.release();
 }
+
+//! Simulation with fitting.
+//! Beam intensity set to provide reasonably large values in detector channels.
+GISASSimulation* StandardSimulations::MiniGISASFit()
+{
+    GISASSimulation* result = new GISASSimulation();
+    result->setDetectorParameters(25, -2.0*Units::degree, 2.0*Units::degree,
+                                  25, 0.0*Units::degree, 2.0*Units::degree);
+    result->setBeamParameters(1.0*Units::angstrom, 0.2*Units::degree, 0.0*Units::degree);
+    result->setBeamIntensity(1e6);
+    return result;
+}
diff --git a/Core/StandardSamples/StandardSimulations.h b/Core/StandardSamples/StandardSimulations.h
index 796827f7eda0f41a0ee7fb203eda54d9bc2a3421..eee58aa282feda4719a209862479cf1a6262428a 100644
--- a/Core/StandardSamples/StandardSimulations.h
+++ b/Core/StandardSamples/StandardSimulations.h
@@ -54,6 +54,7 @@ BA_CORE_API_ GISASSimulation* MiniGISASMonteCarlo();
 BA_CORE_API_ GISASSimulation* SphericalDetWithRoi();
 BA_CORE_API_ GISASSimulation* RectDetWithRoi();
 BA_CORE_API_ GISASSimulation* ConstantBackgroundGISAS();
+BA_CORE_API_ GISASSimulation* MiniGISASFit();
 
 // Specular simulation tests:
 BA_CORE_API_ SpecularSimulation* BasicSpecular();
diff --git a/Core/Tools/MathFunctions.cpp b/Core/Tools/MathFunctions.cpp
index 86a3fe2adce09d0ba38a3318cb31ceebc638446a..05e3a97ecb9497468b89d0d2a15e6e0ce9d016d3 100644
--- a/Core/Tools/MathFunctions.cpp
+++ b/Core/Tools/MathFunctions.cpp
@@ -79,13 +79,15 @@ complex_t MathFunctions::tanhc(const complex_t z)  // tanh(x)/x
     return std::tanh(z)/z;
 }
 
-complex_t MathFunctions::Laue(const complex_t z, size_t N) // Exp(iNx/2)*Sin((N+1)x)/Sin(x)
+double MathFunctions::Laue(const double x, size_t N)
 {
-    if (N==0)
-        return 1.0;
-    if(std::abs(z)<std::numeric_limits<double>::epsilon())
-        return N+1.0;
-    return exp_I(N/2.0*z)*std::sin(z*(N+1.0)/2.0)/std::sin(z/2.0);
+    static const double SQRT6DOUBLE_EPS = std::sqrt(6.0*std::numeric_limits<double>::epsilon());
+    auto nd = static_cast<double>(N);
+    if(std::abs(nd*x) < SQRT6DOUBLE_EPS)
+        return nd;
+    double num = std::sin(nd*x);
+    double den = std::sin(x);
+    return num/den;
 }
 
 double MathFunctions::erf(double arg)
@@ -106,7 +108,7 @@ namespace MathFunctions
 //! Computes complex Bessel function J0(z), using power series and asymptotic expansion
     BA_CORE_API_ complex_t Bessel_J0_PowSer(const complex_t z);
 
-//! Computes complex Bessel function J0(z), using power series and asymptotic expansion
+    //! Computes complex Bessel function J0(z), using power series and asymptotic expansion
     BA_CORE_API_ complex_t Bessel_J1_PowSer(const complex_t z);
 }
 
diff --git a/Core/Tools/MathFunctions.h b/Core/Tools/MathFunctions.h
index 845cffab2020e695d52219adfd5f2f850ae06d6a..df965ac753f0b2b5777dacad232953eb1444a9b7 100644
--- a/Core/Tools/MathFunctions.h
+++ b/Core/Tools/MathFunctions.h
@@ -47,9 +47,10 @@ namespace MathFunctions
 //! Complex tanhc function: \f$tanhc(x)\equiv\tanh(x)/x\f$
     BA_CORE_API_ complex_t tanhc(const complex_t z);
 
-    BA_CORE_API_ complex_t Laue(const complex_t z, size_t N);
+//! Real Laue function: \f$Laue(x,N)\equiv\sin(Nx)/sin(x)\f$
+    BA_CORE_API_ double Laue(const double x, size_t N);
 
-    //! Error function of real-valued argument
+//! Error function of real-valued argument
     BA_CORE_API_ double erf(double arg);
 
 
diff --git a/Core/Tools/PyEmbeddedUtils.cpp b/Core/Tools/PyEmbeddedUtils.cpp
index f602f537ee7f4a2cf9993089f62916cf9770ffd8..c715bb0db8de86b084a3705ec08c91d5c9bb173c 100644
--- a/Core/Tools/PyEmbeddedUtils.cpp
+++ b/Core/Tools/PyEmbeddedUtils.cpp
@@ -13,6 +13,7 @@
 // ************************************************************************** //
 
 #include "PyEmbeddedUtils.h"
+#include "PythonCore.h"
 #include "PythonFormatting.h"
 #include "MultiLayer.h"
 #include "SysUtils.h"
diff --git a/Core/Tools/PyEmbeddedUtils.h b/Core/Tools/PyEmbeddedUtils.h
index 485507f01f715a4a0b9403aa2f7434b1115df93e..9e79eaaf64a4a12e8ed1c915c2b2fad0d2dd236f 100644
--- a/Core/Tools/PyEmbeddedUtils.h
+++ b/Core/Tools/PyEmbeddedUtils.h
@@ -15,9 +15,8 @@
 #ifndef PYEMBEDDEDUTILS_H
 #define PYEMBEDDEDUTILS_H
 
-#include "PythonCore.h"
-#include "swig_runtime.h"
 #include "WinDllMacros.h"
+#include "PyObject.h"
 #include <string>
 #include <vector>
 #include <memory>
diff --git a/Core/Tools/PyImport.cpp b/Core/Tools/PyImport.cpp
index 9e1ef95c955183a968ecf34e43904a0cde49cb39..a142501dc82c4486797cd8d5c2f880762648807b 100644
--- a/Core/Tools/PyImport.cpp
+++ b/Core/Tools/PyImport.cpp
@@ -13,6 +13,7 @@
 // ************************************************************************** //
 
 #include "PyImport.h"
+#include "PythonCore.h"
 #include "PyEmbeddedUtils.h"
 #include "MultiLayer.h"
 
diff --git a/Core/Tools/PyObject.h b/Core/Tools/PyObject.h
index 4aa9f4914ba891e3ec554be246fc082f15644609..4e012aa491e664d49d0c6addd5c2441d483b2f3b 100644
--- a/Core/Tools/PyObject.h
+++ b/Core/Tools/PyObject.h
@@ -13,6 +13,7 @@
 // ************************************************************************** //
 
 #ifndef PYOBJECT_H
+#define PYOBJECT_H
 
 #ifdef BORNAGAIN_PYTHON
 #ifndef PyObject_HEAD
diff --git a/Core/Tools/PythonCore.h b/Core/Tools/PythonCore.h
index afaba94d535e991fec71e51674dbb3adaecea660..9103f90ef2fac42dcc36cfbdd586b2ba9831cc3d 100644
--- a/Core/Tools/PythonCore.h
+++ b/Core/Tools/PythonCore.h
@@ -13,6 +13,7 @@
 // ************************************************************************** //
 
 #ifndef PYTHONCORE_H
+#define PYTHONCORE_H
 
 #ifdef BORNAGAIN_PYTHON
 
@@ -27,8 +28,10 @@
 #define NO_IMPORT_ARRAY
 #include <numpy/arrayobject.h>
 
+#include "swig_runtime.h"
+
 #endif // BORNAGAIN_PYTHON
 
+#endif // PYTHONCORE_H
 
-#endif
 
diff --git a/Core/includeIncludes/HardParticles.h b/Core/includeIncludes/HardParticles.h
index f68eeb2e52b37a73b94c429049068c04ec3f8214..624e61da1117d7af994d4eaca061cf0ddaf55f3f 100644
--- a/Core/includeIncludes/HardParticles.h
+++ b/Core/includeIncludes/HardParticles.h
@@ -28,6 +28,7 @@
 #include "FormFactorFullSpheroid.h"
 #include "FormFactorHemiEllipsoid.h"
 #include "FormFactorIcosahedron.h"
+#include "FormFactorLongBox.h"
 #include "FormFactorLongBoxGauss.h"
 #include "FormFactorLongBoxLorentz.h"
 #include "FormFactorPrism3.h"
diff --git a/Core/includeIncludes/InterferenceFunctions.h b/Core/includeIncludes/InterferenceFunctions.h
index ce3c2dc2895a6a83b2d4c4e26ba279f58b43cc96..3669bfd27c53980a31cc32ff4696f96631f9af89 100644
--- a/Core/includeIncludes/InterferenceFunctions.h
+++ b/Core/includeIncludes/InterferenceFunctions.h
@@ -17,10 +17,11 @@
 
 #include "InterferenceFunction1DLattice.h"
 #include "InterferenceFunction2DLattice.h"
-#include "InterferenceFunction3DLattice.h"
-#include "InterferenceFunctionFinite2DLattice.h"
 #include "InterferenceFunction2DParaCrystal.h"
 #include "InterferenceFunction2DSuperLattice.h"
+#include "InterferenceFunction3DLattice.h"
+#include "InterferenceFunctionFinite2DLattice.h"
+#include "InterferenceFunctionFinite3DLattice.h"
 #include "InterferenceFunctionNone.h"
 #include "InterferenceFunctionRadialParaCrystal.h"
 
diff --git a/Doc/Doxygen/Doxyfile b/Doc/Doxygen/Doxyfile
index 53c2ba6a1f0ca0012dacec3055f474e610b0acd3..bfd6118f9dc56c46b6c464c1ca1ee56874acea6b 100644
--- a/Doc/Doxygen/Doxyfile
+++ b/Doc/Doxygen/Doxyfile
@@ -38,7 +38,7 @@ PROJECT_NAME           = "BornAgain"
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 1.13.0
+PROJECT_NUMBER         = 1.14.0
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
diff --git a/Doc/UserManual/Assemblies.tex b/Doc/UserManual/Assemblies.tex
index b4970f0463272c83b1c1d296f87998cdb53efaf2..2f68dca018b8d518a976539958f2c2fb7bcaa1ba 100644
--- a/Doc/UserManual/Assemblies.tex
+++ b/Doc/UserManual/Assemblies.tex
@@ -638,7 +638,7 @@ In \BornAgain, the following one-dimensional distribution functions for $p(x)$ a
     \hline
     \text{Name} & p(x) & P(q_x) \\
     \hline
-    \text{Cauchy} & \frac{1}{2\omega} \exp(-|x|/2\omega) & \frac{1}{1+q_x^2\omega^2} \\
+    \text{Cauchy} & \frac{1}{2\omega} \exp(-|x|/\omega) & \frac{1}{1+q_x^2\omega^2} \\
     \hline
     \text{Gauss} & \frac{1}{\omega\sqrt{2\pi}} \exp(-x^2/2\omega^2) & \exp(-q_x^2\omega^2/2) \\
     \hline
diff --git a/Doc/UserManual/BornAgainManual.tex b/Doc/UserManual/BornAgainManual.tex
index 5b40a1e4d7f645c993f90f1d1e01f6f64eabff2e..4f72a09e04e8bc641fbcb3b595375881095fd22d 100644
--- a/Doc/UserManual/BornAgainManual.tex
+++ b/Doc/UserManual/BornAgainManual.tex
@@ -32,7 +32,7 @@
 
 \def\authors{Jan Burle, Céline Durniak, Jonathan M.\ Fisher, Marina Ganeva, Gennady Pospelov,
 Walter Van Herck, Joachim Wuttke}
-\def\version{1.7.1}
+\def\version{1.7.2}
 
 \input{Setup}
 
diff --git a/Doc/UserManual/Introduction.tex b/Doc/UserManual/Introduction.tex
index d6db8340a59e2230eb03d3cb3f9cdfb69e3739fe..875297529df104e42ad76f3c53c2a59d8d84c33f 100644
--- a/Doc/UserManual/Introduction.tex
+++ b/Doc/UserManual/Introduction.tex
@@ -144,7 +144,7 @@ It does not duplicate information that is more conveniently read online.
 The online documentation covers in particular
 how to download and install \BornAgain.
 
-This User Manual containes of two parts:
+This User Manual contains two parts:
 \Cref{PPHYS} provides physics background
 on the scattering theory and on the sample models implemented in \BornAgain.
 \cref{PREF} is a partial reference of the C$++$ and Python interfaces;
diff --git a/Examples/python/fitting/README b/Examples/python/fitting/README
deleted file mode 100644
index 58a9e24236cc0fd59858e65dec2b5db10f56cf9c..0000000000000000000000000000000000000000
--- a/Examples/python/fitting/README
+++ /dev/null
@@ -1,59 +0,0 @@
-BornAgain fitting examples.
-
-In this directory one can find examples of complete applications
-used for fitting.
-
---- ex01_SampleParametersIntro ---
-    This example shows how to create a sample with fixed parameters and then
-    change this parameters on the fly during runtime.
-    The example doesn't contain any fitting and serve as a gentle introduction
-    to other fitting examples.
-
---- ex02_FitBasics ---
-    FitCylindersAndPrisms.py - shows minimal fitting example
-    FitCylindersAndPrisms_detailed.py - is more detailed version + some graphical output
-    FitCylindersInSquareLattice.py - demonstrates how to fit many sample parameters with one fit parameter
-
---- ex03_FitSpheresInHexLattice ---
-    Two parameter fit of spheres in a hex lattice.
-    FitSpheresInHexLattice.py - demonstrate standard approach
-    FitSpheresInHexLattice_builder.py - shows advanced way using sample builder, which might be useful for complex
-    samples
-
---- ex04_FitScaleAndShift ---
-    FitScaleAndShift.py - in this example we are trying to fit the data representing cylinders without interference
-    on top of substrate. Real data contains some "unknown" background and scale factors.
-    In four parameters fit we are looking for cylinder's height, radius and for background and scale factors.
-
---- ex05_FitWithMasks ---
-    FitWithMasks.py - two parameter fit of cylinders without interference.
-    Real data contains various masks to simulate and fit only the area outside the masks.
-
---- ex06_FitStrategies ---
-    FitStrategyAdjustMinimizer.py - in this example we are trying to find cylinder's height and radius using chain
-    of minimizers. During the first fit round Genetic minimizer will be used. It will roughly look for possible
-    minimas. After it is done, the second Minuit2 minimizer will continue to find the precise location of global
-    minima.
-
---- ex07_FitAlongSlices ---
-    FitAlongSlices.py - here we demonstrate how to fit along slices.
-    The basic idea is to mask all detector except thin lines, one vertical and one horizontal, representing slices.
-    This will make simulation and fitting to go along slices only.
-
---- ex08_SimultaneousFitOfTwoDatasets ---
-    SimultaneousFitOfTwoDatasets.py - simultaneous fit of two datasets.
-    Suppose that we have same sample measured for two different incident angles. We are going to fit both datasets
-    simultaneously to find unknown sample parameters.
-    To do this, we define one dataset ( a pair of real_data and simulation model) for the first incidence angle
-    and another pair of (real_data, simulation model) for the second incidence angle.
-    We add both pairs to the FitSuite and run fitting as usual.
-
---- ex09_FitSpecular
-    This directory containes examples for fitting specular data
-    FitSpecularBasics.py - basic demosntration of fitting specular data with BornAgain. GENX simulation results are
-                           used as reference data.
-    XRDFitting.py - fitting live data from XRD reflectometer with BornAgain
-    XRDSampleBuilder - auxiliary file for XRDFitting
-
---- ex10_FitGALAXIData
-    This directory contains an example of fitting data from real detector (GALAXI)
diff --git a/Examples/python/fitting/README.md b/Examples/python/fitting/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..688806f03d84d08dcfee3752c13fc5ea5931e3f5
--- /dev/null
+++ b/Examples/python/fitting/README.md
@@ -0,0 +1,30 @@
+# BornAgain fitting examples.
+
+In this directory one can find examples of complete applications
+used for fitting.
+
+## ex01_BasicExamples
+
+Includes collection of basic fitting examples.
+
++ Basic fitting tutorial
++ Running fitting consequitively
++ More about minimizer settings
+
+## ex02_AdvancedExamples
+
+Includes collection of advanced fitting examples.
+
++ How to fit experimental background.
++ How to fit along slices.
++ How to masks areas on experimental image.
++ How to fit two datasets simultaneously.
+
+## ex03_ExtendedExamples
+
++ One experiment on GALAXI instrument.
++ How to use external minimizers to fit BornAgain simulations.
++ Fitting specular data.
+  + Basic demonstration of fitting specular data with BornAgain. GENX simulation results are used as reference data.
+  + Fitting live data from XRD reflectometer with BornAgain.
+  
\ No newline at end of file
diff --git a/Examples/python/fitting/ex02_FitBasics/FitCylindersPrisms_detailed_new.py b/Examples/python/fitting/ex01_BasicExamples/basic_fitting_tutorial.py
similarity index 70%
rename from Examples/python/fitting/ex02_FitBasics/FitCylindersPrisms_detailed_new.py
rename to Examples/python/fitting/ex01_BasicExamples/basic_fitting_tutorial.py
index aa715fc5f90a2f6e5fe082b5400dd37b30e63f69..2f18deac69a6fb1ffffbb5d1a4fdc25e4e92eb98 100644
--- a/Examples/python/fitting/ex02_FitBasics/FitCylindersPrisms_detailed_new.py
+++ b/Examples/python/fitting/ex01_BasicExamples/basic_fitting_tutorial.py
@@ -1,17 +1,12 @@
 """
-Fitting example: 4 parameters fit with simple output
-This is more detailed version of ba.FitCylindersPrisms.py.
-We show how to generate "real" data and how to draw fit progress.
-Please take a note, that performance here is determined
-by poor performance of matplotlib drawing routines.
+Fitting example: 4 parameters fit for mixture of cylinders and prisms on top
+of substrate.
 """
 
-import math
-import random
 import bornagain as ba
+from bornagain import deg, angstrom, nm
 import numpy as np
 from matplotlib import pyplot as plt
-from bornagain import deg, angstrom, nm
 
 
 def get_sample(params):
@@ -33,15 +28,13 @@ def get_sample(params):
     cylinder = ba.Particle(m_particle, cylinder_ff)
     prism_ff = ba.FormFactorPrism3(prism_base_edge, prism_height)
     prism = ba.Particle(m_particle, prism_ff)
-    particle_layout = ba.ParticleLayout()
-    particle_layout.addParticle(cylinder, 0.5)
-    particle_layout.addParticle(prism, 0.5)
-    interference = ba.InterferenceFunctionNone()
-    particle_layout.setInterferenceFunction(interference)
+    layout = ba.ParticleLayout()
+    layout.addParticle(cylinder, 0.5)
+    layout.addParticle(prism, 0.5)
 
     # air layer with particles and substrate form multi layer
     air_layer = ba.Layer(m_air)
-    air_layer.addLayout(particle_layout)
+    air_layer.addLayout(layout)
     substrate_layer = ba.Layer(m_substrate, 0)
     multi_layer = ba.MultiLayer()
     multi_layer.addLayer(air_layer)
@@ -49,21 +42,32 @@ def get_sample(params):
     return multi_layer
 
 
+def get_simulation(params):
+    """
+    Returns a GISAXS simulation with beam and detector defined
+    """
+    simulation = ba.GISASSimulation()
+    simulation.setDetectorParameters(100, -1.0*deg, 1.0*deg,
+                                     100, 0.0*deg, 2.0*deg)
+    simulation.setBeamParameters(1.0*angstrom, 0.2*deg, 0.0*deg)
+    simulation.setBeamIntensity(1e+08)
+    simulation.setSample(get_sample(params))
+    return simulation
+
+
 def create_real_data():
     """
-    Generating "real" data by adding noise to the simulated data.
-    This function has been used once to generate refdata_fitcylinderprisms.int
-    located in same directory.
+    Generating "experimental" data by running simulation with certain parameters.
+    The data is saved on disk in the form of numpy array.
     """
-    # creating sample with set of parameters we will later try to find during the fit
 
+    # default sample parameters
     params = {'cylinder_height': 5.0*nm, 'cylinder_radius': 5.0*nm,
               'prism_height': 5.0*nm, 'prism_base_edge': 5.0*nm}
 
+    # retrieving simulated data in the form of numpy array
     simulation = get_simulation(params)
     simulation.runSimulation()
-
-    # retrieving simulated data in the form of numpy array
     real_data = simulation.result().array()
 
     # spoiling simulated data with noise to produce "real" data
@@ -71,20 +75,15 @@ def create_real_data():
     noise_factor = 0.1
     noisy = np.random.normal(real_data, noise_factor*np.sqrt(real_data))
     noisy[noisy < 0.1] = 0.1
-    return noisy
 
+    np.savetxt("basic_fitting_tutorial_data.txt.gz", real_data)
 
-def get_simulation(params):
+
+def load_real_data():
     """
-    Returns a GISAXS simulation with beam and detector defined
+    Loads experimental data from file
     """
-    simulation = ba.GISASSimulation()
-    simulation.setDetectorParameters(100, -1.0*deg, 1.0*deg,
-                                     100, 0.0*deg, 2.0*deg)
-    simulation.setBeamParameters(1.0*angstrom, 0.2*deg, 0.0*deg)
-    simulation.setBeamIntensity(1e+08)
-    simulation.setSample(get_sample(params))
-    return simulation
+    return np.loadtxt("basic_fitting_tutorial_data.txt.gz", dtype=float)
 
 
 def run_fitting():
@@ -92,16 +91,15 @@ def run_fitting():
     Setup simulation and fit
     """
 
-    real_data = create_real_data()
+    real_data = load_real_data()
 
     fit_objective = ba.FitObjective()
-    fit_objective.addSimulationAndData(get_simulation, real_data, 1.0)
-
-    # fit_suite.setMinimizer("Minuit2", "Migrad")  # ba.Default
-    # fit_suite.setMinimizer("Minuit2", "Fumili")
-    # fit_suite.setMinimizer("GSLLMA")
+    fit_objective.addSimulationAndData(get_simulation, real_data)
 
+    # Print fit progress on every n-th iteration.
     fit_objective.initPrint(10)
+
+    # Plot fit progress on every n-th iteration. Will slow down fit.
     fit_objective.initPlot(10)
 
     params = ba.Parameters()
@@ -115,7 +113,18 @@ def run_fitting():
 
     fit_objective.finalize(result)
 
+    print("Fitting completed.")
+    print("chi2:", result.minValue())
+    for fitPar in result.parameters():
+        print(fitPar.name(), fitPar.value, fitPar.error)
+
+    # saving simulation image corresponding to the best fit parameters
+    # np.savetxt("data.txt", fit_objective.simulationResult().array())
+
 
 if __name__ == '__main__':
+    # uncomment line below to regenerate "experimental" data file
+    # create_real_data()
+
     run_fitting()
     plt.show()
diff --git a/Examples/python/fitting/ex01_BasicExamples/basic_fitting_tutorial_data.txt.gz b/Examples/python/fitting/ex01_BasicExamples/basic_fitting_tutorial_data.txt.gz
new file mode 100644
index 0000000000000000000000000000000000000000..1b61d389a79725e1e4ba60ed73f880b0540d3fd0
Binary files /dev/null and b/Examples/python/fitting/ex01_BasicExamples/basic_fitting_tutorial_data.txt.gz differ
diff --git a/Examples/python/fitting/ex06_FitStrategies/FitStrategyAdjustMinimizer_new.py b/Examples/python/fitting/ex01_BasicExamples/consecutive_fitting.py
similarity index 85%
rename from Examples/python/fitting/ex06_FitStrategies/FitStrategyAdjustMinimizer_new.py
rename to Examples/python/fitting/ex01_BasicExamples/consecutive_fitting.py
index 76e2a229de1b222f836931004a8f0af4f21d5b8f..63f41d7e6b5fb910b7e85fa1e8f9e5ab53fc0542 100644
--- a/Examples/python/fitting/ex06_FitStrategies/FitStrategyAdjustMinimizer_new.py
+++ b/Examples/python/fitting/ex01_BasicExamples/consecutive_fitting.py
@@ -1,12 +1,9 @@
 """
-Two parameter fit of cylinders.
-In this example we are trying to find cylinder's height and radius
-using chain of minimizers.
-
-During the first fit round Genetic minimizer will be used.
-It will roughly look for possible local minimas.
-After it is done, the second Minuit2 minimizer will continue
-to find the precise location of best minima found on previous step.
+Fitting example: running one fit after another using different minimizers.
+
+During the first fit Genetic minimizer will be used to scan large parameter
+space and roughly find local minimum. The second Minuit2 minimizer will continue
+after that to find precise minimum location.
 """
 
 import numpy as np
@@ -29,11 +26,11 @@ def get_sample(params):
     cylinder_ff = ba.FormFactorCylinder(radius, height)
     cylinder = ba.Particle(m_particle, cylinder_ff)
 
-    particle_layout = ba.ParticleLayout()
-    particle_layout.addParticle(cylinder)
+    layout = ba.ParticleLayout()
+    layout.addParticle(cylinder)
 
     air_layer = ba.Layer(m_air)
-    air_layer.addLayout(particle_layout)
+    air_layer.addLayout(layout)
 
     substrate_layer = ba.Layer(m_substrate, 0)
     multi_layer = ba.MultiLayer()
@@ -97,7 +94,7 @@ def run_fitting():
     """
     Now we run first minimization round using the Genetic minimizer.
     The Genetic minimizer is able to explore large parameter space
-    without being trapped by some local minima.
+    without being trapped by some local minimum.
     """
     minimizer = ba.Minimizer()
     minimizer.setMinimizer("Genetic", "", "MaxIterations=2;RandomSeed=1")
diff --git a/Examples/python/fitting/ex01_BasicExamples/minimal_fit_example.py b/Examples/python/fitting/ex01_BasicExamples/minimal_fit_example.py
new file mode 100644
index 0000000000000000000000000000000000000000..ffea9b27fdef52e85797b9732123359f65735f63
--- /dev/null
+++ b/Examples/python/fitting/ex01_BasicExamples/minimal_fit_example.py
@@ -0,0 +1,57 @@
+"""
+Minimal working fit examples: finds radius of sphere in Born approximation.
+"""
+import bornagain as ba
+from bornagain import deg, angstrom, nm
+
+
+def get_simulation(params):
+    """
+    Returns GISAS simulation for given set of parameters.
+    """
+    radius = params["radius"]
+
+    sphere = ba.Particle(ba.HomogeneousMaterial("Particle", 6e-4, 2e-8),
+                         ba.FormFactorFullSphere(radius))
+
+    layer = ba.Layer(ba.HomogeneousMaterial("Air", 0.0, 0.0))
+    layer.addLayout(ba.ParticleLayout(sphere))
+    multi_layer = ba.MultiLayer()
+    multi_layer.addLayer(layer)
+
+    simulation = ba.GISASSimulation()
+    simulation.setDetectorParameters(100, -1.0*deg, 1.0*deg,
+                                     100, 0.0*deg, 2.0*deg)
+    simulation.setBeamParameters(1.0*angstrom, 0.2*deg, 0.0*deg)
+    simulation.setSample(multi_layer)
+
+    return simulation
+
+
+def real_data():
+    """
+    Generating "experimental" data by running simulation with default parameters.
+    """
+    simulation = get_simulation({'radius': 5.0*nm})
+    simulation.runSimulation()
+    return simulation.result().array()
+
+
+def run_fitting():
+    """
+    Setups and runs fit.
+    """
+    fit_objective = ba.FitObjective()
+    fit_objective.addSimulationAndData(get_simulation, real_data())
+    fit_objective.initPrint(10)
+
+    params = ba.Parameters()
+    params.add("radius", 4.*nm, min=0.01)
+
+    minimizer = ba.Minimizer()
+    result = minimizer.minimize(fit_objective.evaluate, params)
+    fit_objective.finalize(result)
+
+
+if __name__ == '__main__':
+    run_fitting()
diff --git a/Examples/python/fitting/ex02_FitBasics/MinimizerOptions_new.py b/Examples/python/fitting/ex01_BasicExamples/minimizer_settings.py
similarity index 85%
rename from Examples/python/fitting/ex02_FitBasics/MinimizerOptions_new.py
rename to Examples/python/fitting/ex01_BasicExamples/minimizer_settings.py
index 80c42e5077c81a7485f1dd7e50e90b1569345e91..2419a6f1a84bdaedf2f4112186e889ad01ae33fc 100644
--- a/Examples/python/fitting/ex02_FitBasics/MinimizerOptions_new.py
+++ b/Examples/python/fitting/ex01_BasicExamples/minimizer_settings.py
@@ -24,15 +24,15 @@ def get_sample(params):
     cylinder = ba.Particle(m_particle, cylinder_ff)
     prism_ff = ba.FormFactorPrism3(prism_base_edge, prism_height)
     prism = ba.Particle(m_particle, prism_ff)
-    particle_layout = ba.ParticleLayout()
-    particle_layout.addParticle(cylinder, 0.5)
-    particle_layout.addParticle(prism, 0.5)
+    layout = ba.ParticleLayout()
+    layout.addParticle(cylinder, 0.5)
+    layout.addParticle(prism, 0.5)
     interference = ba.InterferenceFunctionNone()
-    particle_layout.setInterferenceFunction(interference)
+    layout.setInterferenceFunction(interference)
 
     # air layer with particles and substrate form multi layer
     air_layer = ba.Layer(m_air)
-    air_layer.addLayout(particle_layout)
+    air_layer.addLayout(layout)
     substrate_layer = ba.Layer(m_substrate, 0)
     multi_layer = ba.MultiLayer()
     multi_layer.addLayer(air_layer)
@@ -53,20 +53,33 @@ def get_simulation(params):
     return simulation
 
 
+def create_real_data():
+    """
+    Generating "real" data from simulated image with default parameters.
+    """
+
+    params = {'cylinder_height': 5.0*nm, 'cylinder_radius': 5.0*nm,
+              'prism_height': 5.0*nm, 'prism_base_edge': 5.0*nm}
+
+    simulation = get_simulation(params)
+    simulation.runSimulation()
+
+    return simulation.result().array()
+
+
 def run_fitting():
     """
     main function to run fitting
     """
 
+    real_data = create_real_data()
+
     # prints info about available minimizers
     print(ba.MinimizerFactory().catalogueToString())
 
     # prints detailed info about available minimizers and their options
     print(ba.MinimizerFactory().catalogueDetailsToString())
 
-    real_data = ba.IntensityDataIOFactory.readIntensityData(
-        'refdata_fitcylinderprisms.int.gz').array()
-
     fit_objective = ba.FitObjective()
     fit_objective.addSimulationAndData(get_simulation, real_data, 1.0)
     fit_objective.initPrint(10)
diff --git a/Examples/python/fitting/ex01_SampleParametersIntro/SampleParametersIntro.py b/Examples/python/fitting/ex01_SampleParametersIntro/SampleParametersIntro.py
deleted file mode 100644
index 84dea5a63da37ef739810491085081db51bcba53..0000000000000000000000000000000000000000
--- a/Examples/python/fitting/ex01_SampleParametersIntro/SampleParametersIntro.py
+++ /dev/null
@@ -1,123 +0,0 @@
-"""
-Working with sample parameters.
-
-This example shows how to create a sample with fixed parameters, and then change
-these parameters on the fly during runtime. The example doesn't contain any
-fitting; it serves as a gentle introduction to other fitting examples.
-"""
-
-from __future__ import print_function
-import bornagain as ba
-from bornagain import deg, angstrom, nm
-
-
-def get_sample():
-    """
-    Returns a sample with uncorrelated cylinders and prisms on a substrate.
-    Parameter set is fixed.
-    """
-    # defining materials
-    m_air = ba.HomogeneousMaterial("Air", 0.0, 0.0)
-    m_substrate = ba.HomogeneousMaterial("Substrate", 6e-6, 2e-8)
-    m_particle = ba.HomogeneousMaterial("Particle", 6e-4, 2e-8)
-
-    # collection of particles
-    cylinder_ff = ba.FormFactorCylinder(5*nm, 5*nm)
-    cylinder = ba.Particle(m_particle, cylinder_ff)
-    prism_ff = ba.FormFactorPrism3(5*nm, 5*nm)
-    prism = ba.Particle(m_particle, prism_ff)
-    particle_layout = ba.ParticleLayout()
-    particle_layout.addParticle(cylinder, 0.5)
-    particle_layout.addParticle(prism, 0.5)
-    interference = ba.InterferenceFunctionNone()
-    particle_layout.setInterferenceFunction(interference)
-
-    # air layer with particles and substrate form multi layer
-    air_layer = ba.Layer(m_air)
-    air_layer.addLayout(particle_layout)
-    substrate_layer = ba.Layer(m_substrate, 0)
-    multi_layer = ba.MultiLayer()
-    multi_layer.addLayer(air_layer)
-    multi_layer.addLayer(substrate_layer)
-    return multi_layer
-
-
-def get_simulation():
-    """
-    Create and return GISAXS simulation with beam and detector defined
-    """
-    simulation = ba.GISASSimulation()
-    simulation.setDetectorParameters(100, -1.0*deg, 1.0*deg,
-                                     100, 0.0*deg, 2.0*deg)
-    simulation.setBeamParameters(1.0*angstrom, 0.2*deg, 0.0*deg)
-    return simulation
-
-
-def run_simulation():
-    """
-    Runs simulations for the sample with different sample parameters.
-    """
-
-    sample = get_sample()
-    print("The tree structure of the sample")
-    print(sample.treeToString())
-
-    print("The sample contains following parameters ('name':value)")
-    print(sample.parametersToString())
-
-    simulation = get_simulation()
-
-    results = {}
-
-    # simulation #1
-    # initial sample is used
-    simulation.setSample(sample)
-    simulation.runSimulation()
-    results[0] = simulation.result()
-
-    # simulation #2
-    # one sample parameter (cylinder height) is changed using exact parameter name
-    sample.setParameterValue(
-        "/MultiLayer/Layer0/ParticleLayout/Particle0/Cylinder/Height",
-        10.0*nm)
-
-    simulation.setSample(sample)
-    simulation.runSimulation()
-    results[1] = simulation.result()
-
-    # simulation #3
-    # all parameters matching criteria will be changed (cylinder height in this case)
-    sample.setParameterValue("*/Cylinder/Height", 100.0*nm)
-    simulation.setSample(sample)
-    simulation.runSimulation()
-    results[2] = simulation.result()
-
-    # simulation #4
-    # all parameters which are matching criteria will be changed
-    sample.setParameterValue("*/Cylinder/Height", 10.0*nm)
-    sample.setParameterValue("*/Prism3/*", 10.0*nm)
-    simulation.setSample(sample)
-    simulation.runSimulation()
-    results[3] = simulation.result()
-
-    return results
-
-
-def plot(results):
-    """
-    Draw results of several simulations on canvas
-    """
-
-    from matplotlib import pyplot as plt
-    plt.figure(figsize=(12.80, 10.24))
-
-    for nplot, result in results.items():
-        plt.subplot(2, 2, nplot+1)
-        ba.plot_colormap(result, zlabel="")
-    plt.tight_layout()
-    plt.show()
-
-
-if __name__ == '__main__':
-    results = run_simulation()
-    plot(results)
diff --git a/Examples/python/fitting/ex02_AdvancedExamples/find_background.py b/Examples/python/fitting/ex02_AdvancedExamples/find_background.py
new file mode 100644
index 0000000000000000000000000000000000000000..21a6e3b554bd8a94dbc5295458314308e6fa84b3
--- /dev/null
+++ b/Examples/python/fitting/ex02_AdvancedExamples/find_background.py
@@ -0,0 +1,103 @@
+"""
+Fitting example: looking for background and scale factors.
+
+Real data contains some "unknown" background and scale factor.
+In the fit we are trying to find cylinder radius and height,
+scale and background factors.
+"""
+
+import numpy as np
+from matplotlib import pyplot as plt
+import bornagain as ba
+from bornagain import deg, angstrom, nm
+
+
+def get_sample(params):
+    """
+    Build the sample representing cylinders on top of substrate without interference.
+    """
+    radius = params["radius"]
+    height = params["height"]
+
+    m_air = ba.HomogeneousMaterial("Air", 0.0, 0.0)
+    m_substrate = ba.HomogeneousMaterial("Substrate", 6e-6, 2e-8)
+    m_particle = ba.HomogeneousMaterial("Particle", 6e-4, 2e-8)
+
+    cylinder_ff = ba.FormFactorCylinder(radius, height)
+    cylinder = ba.Particle(m_particle, cylinder_ff)
+
+    layout = ba.ParticleLayout()
+    layout.addParticle(cylinder)
+
+    air_layer = ba.Layer(m_air)
+    air_layer.addLayout(layout)
+
+    substrate_layer = ba.Layer(m_substrate, 0)
+    multi_layer = ba.MultiLayer()
+    multi_layer.addLayer(air_layer)
+    multi_layer.addLayer(substrate_layer)
+    return multi_layer
+
+
+def get_simulation(params):
+    """
+    Create and return GISAXS simulation with beam and detector defined
+    """
+    background = params["background"]
+    scale = params["scale"]
+
+    simulation = ba.GISASSimulation()
+    simulation.setDetectorParameters(100, -1.0*deg, 1.0*deg,
+                                     100, 0.0*deg, 2.0*deg)
+    simulation.setBeamParameters(1.0*angstrom, 0.2*deg, 0.0*deg)
+    simulation.setBeamIntensity(1e12*scale)
+    simulation.setBackground(ba.ConstantBackground(background))
+    simulation.setSample(get_sample(params))
+
+    return simulation
+
+
+def create_real_data():
+    """
+    Generating "real" data by adding noise, background and scale
+    to the simulated data.
+    Cylinder radius is set to 5nm, cylinder height to 10nm.
+    During the fit we will try to find cylinder height and radius and
+    scale, background factors.
+    """
+
+    params = {'radius': 5.0*nm, 'height': 10.0*nm, 'scale': 2.0, 'background': 1000}
+
+    simulation = get_simulation(params)
+    simulation.runSimulation()
+
+    # retrieving simulated data in the form of numpy array
+    return simulation.result().array()
+
+
+def run_fitting():
+    """
+    main function to run fitting
+    """
+    real_data = create_real_data()
+
+    fit_objective = ba.FitObjective()
+    fit_objective.addSimulationAndData(get_simulation, real_data, 1.0)
+
+    fit_objective.initPrint(10)
+    fit_objective.initPlot(10)
+
+    params = ba.Parameters()
+    params.add("radius", 5.*nm, vary=False)
+    params.add("height", 9.*nm, min=8.*nm, max=12.*nm)
+    params.add("scale", 1.5, min=1.0, max=3.0)
+    params.add("background", 200, min=100.0, max=2000.0, step=100.0)
+
+    minimizer = ba.Minimizer()
+    result = minimizer.minimize(fit_objective.evaluate, params)
+    fit_objective.finalize(result)
+
+
+if __name__ == '__main__':
+    run_fitting()
+    plt.show()
diff --git a/Examples/python/fitting/ex07_FitAlongSlices/FitAlongSlices_new.py b/Examples/python/fitting/ex02_AdvancedExamples/fit_along_slices.py
similarity index 72%
rename from Examples/python/fitting/ex07_FitAlongSlices/FitAlongSlices_new.py
rename to Examples/python/fitting/ex02_AdvancedExamples/fit_along_slices.py
index 3cee6114950e2782df406f2d4225e8daeda1b444..c1d64db3f78d3fec6996870e84e4af74ee826a51 100644
--- a/Examples/python/fitting/ex07_FitAlongSlices/FitAlongSlices_new.py
+++ b/Examples/python/fitting/ex02_AdvancedExamples/fit_along_slices.py
@@ -2,7 +2,6 @@
 Fitting example: fit along slices
 """
 
-import numpy as np
 from matplotlib import pyplot as plt
 import bornagain as ba
 from bornagain import deg, angstrom, nm
@@ -25,11 +24,11 @@ def get_sample(params):
     cylinder_ff = ba.FormFactorCylinder(radius, height)
     cylinder = ba.Particle(m_particle, cylinder_ff)
 
-    particle_layout = ba.ParticleLayout()
-    particle_layout.addParticle(cylinder)
+    layout = ba.ParticleLayout()
+    layout.addParticle(cylinder)
 
     air_layer = ba.Layer(m_air)
-    air_layer.addLayout(particle_layout)
+    air_layer.addLayout(layout)
 
     substrate_layer = ba.Layer(m_substrate, 0)
     multi_layer = ba.MultiLayer()
@@ -43,15 +42,16 @@ def get_simulation(params, add_masks=True):
     Create and return GISAXS simulation with beam and detector defined
     """
     simulation = ba.GISASSimulation()
-    simulation.setDetectorParameters(100, -1.0*deg, 1.0*deg,
-                                     100, 0.0*deg, 2.0*deg)
+    simulation.setDetectorParameters(100, -1.0*deg, 1.0*deg, 100, 0.0*deg, 2.0*deg)
     simulation.setBeamParameters(1.0*angstrom, 0.2*deg, 0.0*deg)
     simulation.setBeamIntensity(1e+08)
     simulation.setSample(get_sample(params))
     if add_masks:
-        # At this point we mask all the detector and then unmask two areas
-        # corresponding to the vertical and horizontal lines. This will make
-        # simulation/fitting to be performed along slices only.
+        """
+        At this point we mask all the detector and then unmask two areas
+        corresponding to the vertical and horizontal lines. This will make
+        simulation/fitting to be performed along slices only.
+        """
         simulation.maskAll()
         simulation.addMask(ba.HorizontalLine(alpha_slice_value*deg), False)
         simulation.addMask(ba.VerticalLine(phi_slice_value*deg), False)
@@ -62,22 +62,18 @@ def create_real_data():
     """
     Generating "real" data by adding noise to the simulated data.
     """
+    # initial values which we will have to find later during the fit
     params = {'radius': 5.0*nm, 'height': 10.0*nm}
 
+    # retrieving simulated data in the form of numpy array
     simulation = get_simulation(params, add_masks=False)
+    simulation.setBackground(ba.PoissonNoiseBackground())
     simulation.runSimulation()
 
-    # retrieving simulated data in the form of numpy array
-    real_data = simulation.result().array()
-
-    # spoiling simulated data with the noise to produce "real" data
-    noise_factor = 0.1
-    noisy = np.random.normal(real_data, noise_factor*np.sqrt(real_data))
-    noisy[noisy < 0.1] = 0.1
-    return noisy
+    return simulation.result().array()
 
 
-class PlotObserver():
+class PlotObserver:
     """
     Draws fit progress every nth iteration. Here we plot slices along real
     and simulated images to see fit progress.
@@ -87,8 +83,15 @@ class PlotObserver():
         self.fig = plt.figure(figsize=(10.25, 7.69))
         self.fig.canvas.draw()
 
-    def plot_real_data(self, data, nplot):
-        plt.subplot(2, 2, nplot)
+    def __call__(self, fit_objective):
+        self.update(fit_objective)
+
+    @staticmethod
+    def plot_real_data(data):
+        """
+        Plot experimental data as colormap with horizontal/vertical lines
+        representing slices on top.
+        """
         plt.subplots_adjust(wspace=0.2, hspace=0.2)
         ba.plot_histogram(data, title="Experimental data")
         # line representing vertical slice
@@ -100,8 +103,11 @@ class PlotObserver():
                  [alpha_slice_value, alpha_slice_value],
                  color='gray', linestyle='-', linewidth=1)
 
-    def plot_slices(self, slices, title, nplot):
-        plt.subplot(2, 2, nplot)
+    @staticmethod
+    def plot_slices(slices, title):
+        """
+        Plots vertical and horizontal projections.
+        """
         plt.subplots_adjust(wspace=0.2, hspace=0.3)
         for label, slice in slices:
             plt.semilogy(slice.getBinCenters(),
@@ -111,8 +117,11 @@ class PlotObserver():
         plt.legend(loc='upper right')
         plt.title(title)
 
-    def display_fit_parameters(self, fit_objective, nplot):
-        plt.subplot(2, 2, nplot)
+    @staticmethod
+    def display_fit_parameters(fit_objective):
+        """
+        Displays fit parameters, chi and iteration number.
+        """
         plt.title('Parameters')
         plt.axis('off')
 
@@ -121,45 +130,49 @@ class PlotObserver():
         plt.text(0.01, 0.85, "Iterations  " + '{:d}'.
                  format(iteration_info.iterationCount()))
         plt.text(0.01, 0.75, "Chi2       " + '{:8.4f}'.format(iteration_info.chi2()))
-        index = 0
-        params = iteration_info.parameterMap()
-        for key in params:
+        for index, params in enumerate(iteration_info.parameters()):
             plt.text(0.01, 0.55 - index * 0.1,
-                     '{:30.30s}: {:6.3f}'.format(key, params[key]))
-            index = index + 1
+                     '{:30.30s}: {:6.3f}'.format(params.name(), params.value))
+
 
         plt.tight_layout()
         plt.draw()
         plt.pause(0.01)
 
     def update(self, fit_objective):
+        """
+        Callback to access fit_objective on every n'th iteration.
+        """
         self.fig.clf()
 
         real_data = fit_objective.experimentalData().histogram2d()
         simul_data = fit_objective.simulationResult().histogram2d()
 
         # plot real data
-        self.plot_real_data(real_data, nplot=1)
+        plt.subplot(2, 2, 1)
+        self.plot_real_data(real_data)
 
         # horizontal slices
-        slices =[
+        slices = [
             ("real", real_data.projectionX(alpha_slice_value)),
             ("simul", simul_data.projectionX(alpha_slice_value))
             ]
-        title = ( "Horizontal slice at alpha =" +
-                  '{:3.1f}'.format(alpha_slice_value) )
-        self.plot_slices(slices, title, nplot=2)
+        title = ("Horizontal slice at alpha =" + '{:3.1f}'.format(alpha_slice_value))
+        plt.subplot(2, 2, 2)
+        self.plot_slices(slices, title)
 
         # vertical slices
-        slices =[
+        slices = [
             ("real", real_data.projectionY(phi_slice_value)),
             ("simul", simul_data.projectionY(phi_slice_value))
             ]
         title = "Vertical slice at phi =" + '{:3.1f}'.format(phi_slice_value)
-        self.plot_slices(slices, title, nplot=3)
+        plt.subplot(2, 2, 3)
+        self.plot_slices(slices, title)
 
         # display fit parameters
-        self.display_fit_parameters(fit_objective, nplot=4)
+        plt.subplot(2, 2, 4)
+        self.display_fit_parameters(fit_objective)
 
 
 def run_fitting():
@@ -175,7 +188,7 @@ def run_fitting():
 
     # creating custom observer which will draw fit progress
     plotter = PlotObserver()
-    fit_objective.initPlot(10, plotter.update)
+    fit_objective.initPlot(10, plotter)
 
     params = ba.Parameters()
     params.add("radius", 6.*nm, min=4.0, max=8.0)
diff --git a/Examples/python/fitting/ex05_FitWithMasks/FitWithMasks_new.py b/Examples/python/fitting/ex02_AdvancedExamples/fit_with_masks.py
similarity index 95%
rename from Examples/python/fitting/ex05_FitWithMasks/FitWithMasks_new.py
rename to Examples/python/fitting/ex02_AdvancedExamples/fit_with_masks.py
index ef9079cca7911346828365391b34be481d4fae26..ae0cc0dea9d7288323c0d2eb97d0825fadab4b9c 100644
--- a/Examples/python/fitting/ex05_FitWithMasks/FitWithMasks_new.py
+++ b/Examples/python/fitting/ex02_AdvancedExamples/fit_with_masks.py
@@ -23,11 +23,11 @@ def get_sample(params):
     cylinder_ff = ba.FormFactorCylinder(radius, height)
     cylinder = ba.Particle(m_particle, cylinder_ff)
 
-    particle_layout = ba.ParticleLayout()
-    particle_layout.addParticle(cylinder)
+    layout = ba.ParticleLayout()
+    layout.addParticle(cylinder)
 
     air_layer = ba.Layer(m_air)
-    air_layer.addLayout(particle_layout)
+    air_layer.addLayout(layout)
 
     substrate_layer = ba.Layer(m_substrate, 0)
     multi_layer = ba.MultiLayer()
@@ -59,10 +59,9 @@ def create_real_data():
     """
     params = {'radius': 5.0*nm, 'height': 10.0*nm}
 
+    # retrieving simulated data in the form of numpy array
     simulation = get_simulation(params, add_masks=False)
     simulation.runSimulation()
-
-    # retrieving simulated data in the form of numpy array
     real_data = simulation.result().array()
 
     # spoiling simulated data with the noise to produce "real" data
@@ -81,7 +80,7 @@ def add_mask_to_simulation(simulation):
     with the mask value either "True" (detector bin is excluded from the simulation)
     or False (will be simulated).
 
-    Every subsequent mask override previously defined masks in this area.
+    Every subsequent mask overrides previously defined mask in this area.
 
     In the code below we put masks in such way that simulated image will look like
     a Pac-Man from ancient arcade game.
diff --git a/Examples/python/fitting/ex08_SimultaneousFitOfTwoDatasets/SimultaneousFitOfTwoDatasets_new.py b/Examples/python/fitting/ex02_AdvancedExamples/multiple_datasets.py
similarity index 72%
rename from Examples/python/fitting/ex08_SimultaneousFitOfTwoDatasets/SimultaneousFitOfTwoDatasets_new.py
rename to Examples/python/fitting/ex02_AdvancedExamples/multiple_datasets.py
index af6c93d9eca9c1552a96125dfdff5acb642fa744..2ac100cc72d715e635560c7d78001cbb118ab357 100644
--- a/Examples/python/fitting/ex08_SimultaneousFitOfTwoDatasets/SimultaneousFitOfTwoDatasets_new.py
+++ b/Examples/python/fitting/ex02_AdvancedExamples/multiple_datasets.py
@@ -1,5 +1,5 @@
 """
-Fitting example: demonstrates how to fit two datasets simultaneously.
+Fitting example: simultaneous fit of two datasets
 """
 
 import numpy as np
@@ -21,16 +21,16 @@ def get_sample(params):
     m_substrate = ba.HomogeneousMaterial("Substrate", 6e-6, 2e-8)
     m_particle = ba.HomogeneousMaterial("Particle", 6e-4, 2e-8)
 
-    formFactor = ba.FormFactorHemiEllipsoid(radius_a, radius_b, height)
-    hemiEllipsoid = ba.Particle(m_particle, formFactor)
+    formfactor = ba.FormFactorHemiEllipsoid(radius_a, radius_b, height)
+    particle = ba.Particle(m_particle, formfactor)
 
-    particle_layout = ba.ParticleLayout()
-    particle_layout.addParticle(hemiEllipsoid)
+    layout = ba.ParticleLayout()
+    layout.addParticle(particle)
 
     air_layer = ba.Layer(m_air)
-    air_layer.addLayout(particle_layout)
+    air_layer.addLayout(layout)
 
-    substrate_layer = ba.Layer(m_substrate, 0)
+    substrate_layer = ba.Layer(m_substrate)
     multi_layer = ba.MultiLayer()
     multi_layer.addLayer(air_layer)
     multi_layer.addLayer(substrate_layer)
@@ -87,11 +87,15 @@ class PlotObserver():
     Draws fit progress every nth iteration. Real data, simulated data
     and chi2 map will be shown for both datasets.
     """
-    def __init__(self, draw_every_nth=10):
+    def __init__(self):
         self.fig = plt.figure(figsize=(12.8, 10.24))
         self.fig.canvas.draw()
 
-    def plot_datasets(self, fit_objective, canvas):
+    def __call__(self, fit_objective):
+        self.update(fit_objective)
+
+    @staticmethod
+    def plot_dataset(fit_objective, canvas):
         for i_dataset in range(0, fit_objective.fitObjectCount()):
             real_data = fit_objective.experimentalData(i_dataset)
             simul_data = fit_objective.simulationResult(i_dataset)
@@ -101,17 +105,36 @@ class PlotObserver():
 
             plt.subplot(canvas[i_dataset*3])
             ba.plot_colormap(real_data, title="\"Real\" data - #"+str(i_dataset+1),
-                               zmin=1.0, zmax=zmax, zlabel="")
+                             zmin=1.0, zmax=zmax, zlabel="")
             plt.subplot(canvas[1+i_dataset*3])
             ba.plot_colormap(simul_data, title="Simulated data - #"+str(i_dataset+1),
-                               zmin=1.0, zmax=zmax, zlabel="")
+                             zmin=1.0, zmax=zmax, zlabel="")
             plt.subplot(canvas[2+i_dataset*3])
             ba.plot_colormap(chi2_map, title="Chi2 map - #"+str(i_dataset+1),
-                               zmin=0.001, zmax=10.0, zlabel="")
+                             zmin=0.001, zmax=10.0, zlabel="")
+
+    @staticmethod
+    def display_fit_parameters(fit_objective):
+        """
+        Displays fit parameters, chi and iteration number.
+        """
+        plt.title('Parameters')
+        plt.axis('off')
 
-    def plot_fit_parameters(self, fit_objective, canvas):
-        # fit parameters
-        plt.subplot(canvas[6:])
+        iteration_info = fit_objective.iterationInfo()
+
+        plt.text(0.01, 0.85, "Iterations  " + '{:d}'.
+                 format(iteration_info.iterationCount()))
+        plt.text(0.01, 0.75, "Chi2       " + '{:8.4f}'.format(iteration_info.chi2()))
+        for index, params in enumerate(iteration_info.parameters()):
+            plt.text(0.01, 0.55 - index * 0.1,
+                     '{:30.30s}: {:6.3f}'.format(params.name(), params.value))
+
+    @staticmethod
+    def plot_fit_parameters(fit_objective):
+        """
+        Displays fit parameters, chi and iteration number.
+        """
         plt.axis('off')
 
         iteration_info = fit_objective.iterationInfo()
@@ -119,15 +142,11 @@ class PlotObserver():
         plt.text(0.01, 0.95, "Iterations  " + '{:d}'.
                  format(iteration_info.iterationCount()))
         plt.text(0.01, 0.70, "Chi2       " + '{:8.4f}'.format(iteration_info.chi2()))
-        index = 0
-        params = iteration_info.parameterMap()
-        for key in params:
+        for index, params in enumerate(iteration_info.parameters()):
             plt.text(0.01, 0.30 - index * 0.3,
-                     '{:30.30s}: {:6.3f}'.format(key, params[key]))
-            index = index + 1
-
+                     '{:30.30s}: {:6.3f}'.format(params.name(), params.value))
 
-    def update(self, fit_suite):
+    def update(self, fit_objective):
         self.fig.clf()
 
         # we divide figure to have 3x3 subplots, with two first rows occupying
@@ -136,14 +155,14 @@ class PlotObserver():
             3, 3, width_ratios=[1, 1, 1], height_ratios=[4, 4, 1])
         canvas.update(left=0.05, right=0.95, hspace=0.5, wspace=0.2)
 
-        self.plot_datasets(fit_suite, canvas)
-        self.plot_fit_parameters(fit_suite, canvas)
+        self.plot_dataset(fit_objective, canvas)
+        plt.subplot(canvas[6:])
+        self.plot_fit_parameters(fit_objective)
 
         plt.draw()
         plt.pause(0.01)
 
 
-
 def run_fitting():
     """
     main function to run fitting
@@ -166,7 +185,6 @@ def run_fitting():
     params.add("radius_b", 6.*nm, vary=False)
     params.add("height", 4.*nm, min=2.0, max=10.0)
 
-    print("begin")
     minimizer = ba.Minimizer()
     result = minimizer.minimize(fit_objective.evaluate, params)
     fit_objective.finalize(result)
diff --git a/Examples/python/fitting/ex02_FitBasics/FitCylindersInSquareLattice.py b/Examples/python/fitting/ex02_FitBasics/FitCylindersInSquareLattice.py
deleted file mode 100644
index 7b8a1105315b37e9037235f27cb7d9068fbdb331..0000000000000000000000000000000000000000
--- a/Examples/python/fitting/ex02_FitBasics/FitCylindersInSquareLattice.py
+++ /dev/null
@@ -1,133 +0,0 @@
-"""
-Example demonstrates how to fit several sample parameters with one fit parameter.
-Our sample represents cylindrical particles in rectangular lattice. We are going
-to fit the data, assuming that cylinder radius, height and both lattice lengths
-are the same.
-
-"Real data" was generated for
-cylinder_radius = cylinder_height = lattice_length1 = lattice_length2 = 8*nm
-
-Then we create a fit setup, where one fit parameter will steer all corresponding
-sample parameters, namely
-
-/MultiLayer/Layer0/ParticleLayout/Interference2DLattice/BasicLattice/LatticeLength1
-/MultiLayer/Layer0/ParticleLayout/Interference2DLattice/BasicLattice/LatticeLength2
-/MultiLayer/Layer0/ParticleLayout/Particle/Cylinder/Radius
-/MultiLayer/Layer0/ParticleLayout/Particle/Cylinder/Height
-"""
-
-import numpy as np
-from matplotlib import pyplot as plt
-import bornagain as ba
-from bornagain import deg, angstrom, nm
-
-
-def get_sample(radius=5.0*nm, height=5.0*nm, lattice_constant=10.0*nm):
-    """
-    Returns a sample with cylinders on a substrate,
-    forming a rectangular lattice.
-    """
-    m_air = ba.HomogeneousMaterial("Air", 0.0, 0.0)
-    m_substrate = ba.HomogeneousMaterial("Substrate", 6e-6, 2e-8)
-    m_particle = ba.HomogeneousMaterial("Particle", 6e-4, 2e-8)
-
-    ff = ba.FormFactorCylinder(radius, height)
-    cylinder = ba.Particle(m_particle, ff)
-    particle_layout = ba.ParticleLayout()
-    particle_layout.addParticle(cylinder)
-
-    interference = ba.InterferenceFunction2DLattice(
-        lattice_constant, lattice_constant, 90.0*deg)
-    pdf = ba.FTDecayFunction2DCauchy(50*nm, 50*nm)
-    interference.setDecayFunction(pdf)
-
-    particle_layout.setInterferenceFunction(interference)
-
-    air_layer = ba.Layer(m_air)
-    air_layer.addLayout(particle_layout)
-    substrate_layer = ba.Layer(m_substrate, 0)
-    multi_layer = ba.MultiLayer()
-    multi_layer.addLayer(air_layer)
-    multi_layer.addLayer(substrate_layer)
-    return multi_layer
-
-
-def get_simulation():
-    """
-    Create and return GISAXS simulation with beam and detector defined
-    """
-    simulation = ba.GISASSimulation()
-    simulation.setDetectorParameters(100, -1.0*deg, 1.0*deg,
-                                     100, 0.0*deg, 2.0*deg)
-    simulation.setBeamParameters(1.0*angstrom, 0.2*deg, 0.0*deg)
-    simulation.setBeamIntensity(1e+08)
-    return simulation
-
-
-def create_real_data():
-    """
-    Generating "real" data by adding noise to the simulated data.
-    """
-    sample = get_sample(8.0*nm, 8.0*nm, 8.0*nm)
-    simulation = get_simulation()
-    simulation.setSample(sample)
-    simulation.runSimulation()
-
-    # retrieving simulated data in the form of numpy array
-    real_data = simulation.result().array()
-
-    # spoiling simulated data with the noise to produce "real" data
-    noise_factor = 0.1
-    noisy = np.random.normal(real_data, noise_factor*np.sqrt(real_data))
-    noisy[noisy < 0.1] = 0.1
-    return noisy
-
-
-def run_fitting():
-    """
-    main function to run fitting
-    """
-    simulation = get_simulation()
-    sample = get_sample()
-    simulation.setSample(sample)
-
-    print(simulation.treeToString())
-    print(simulation.parametersToString())
-
-    real_data = create_real_data()
-
-    fit_suite = ba.FitSuite()
-    fit_suite.addSimulationAndRealData(simulation, real_data)
-    fit_suite.initPrint(10)
-
-    draw_observer = ba.DefaultFitObserver(draw_every_nth=10)
-    fit_suite.attachObserver(draw_observer)
-
-    # this fit parameter fits 4 sample parameter with one value
-    fit_suite.addFitParameter("*Lattice/LatticeLength*", 9.*nm).\
-        setLimited(6., 10.).addPattern("*Cylinder/Radius").\
-        addPattern("*Cylinder/Height").setName("custom_length")
-
-    # alternatively, following syntax is possible
-    # fitPar = ba.FitParameter(10.*nm, ba.AttLimits.limited(4., 12.))
-    # fitPar.setName("custom_length")
-    # fitPar.addPattern("*Lattice/LatticeLength*")
-    # fitPar.addPattern("*Cylinder/Radius").addPattern("*Cylinder/Height")
-    # fit_suite.addFitParameter(fitPar)
-
-    # prints defined fit parameters and their relation to instrument parameters
-    print(fit_suite.setupToString())
-
-    # running fit
-    print("Starting the fitting")
-    fit_suite.runFit()
-
-    print("Fitting completed.")
-    print("chi2:", fit_suite.getChi2())
-    for fitPar in fit_suite.fitParameters():
-        print(fitPar.name(), fitPar.value(), fitPar.error())
-
-
-if __name__ == '__main__':
-    run_fitting()
-    plt.show()
diff --git a/Examples/python/fitting/ex02_FitBasics/FitCylindersInSquareLattice_new.py b/Examples/python/fitting/ex02_FitBasics/FitCylindersInSquareLattice_new.py
deleted file mode 100644
index abb6e33d09e1e42a90e212892cca16051cd8bee0..0000000000000000000000000000000000000000
--- a/Examples/python/fitting/ex02_FitBasics/FitCylindersInSquareLattice_new.py
+++ /dev/null
@@ -1,118 +0,0 @@
-"""
-Example demonstrates how to fit several sample parameters with one fit parameter.
-Our sample represents cylindrical particles in rectangular lattice. We are going
-to fit the data, assuming that cylinder radius, height and both lattice lengths
-are the same.
-
-"Real data" was generated for
-cylinder_radius = cylinder_height = lattice_length1 = lattice_length2 = 8*nm
-
-Then we create a fit setup, where one fit parameter will steer all corresponding
-sample parameters, namely
-
-/MultiLayer/Layer0/ParticleLayout/Interference2DLattice/BasicLattice/LatticeLength1
-/MultiLayer/Layer0/ParticleLayout/Interference2DLattice/BasicLattice/LatticeLength2
-/MultiLayer/Layer0/ParticleLayout/Particle/Cylinder/Radius
-/MultiLayer/Layer0/ParticleLayout/Particle/Cylinder/Height
-"""
-
-import numpy as np
-from matplotlib import pyplot as plt
-import bornagain as ba
-from bornagain import deg, angstrom, nm
-
-
-def get_sample(params):
-    """
-    Returns a sample with cylinders on a substrate,
-    forming a rectangular lattice.
-    """
-    radius = params["custom_length"]
-    height = params["custom_length"]
-    lattice_constant = params["custom_length"]
-
-    m_air = ba.HomogeneousMaterial("Air", 0.0, 0.0)
-    m_substrate = ba.HomogeneousMaterial("Substrate", 6e-6, 2e-8)
-    m_particle = ba.HomogeneousMaterial("Particle", 6e-4, 2e-8)
-
-    ff = ba.FormFactorCylinder(radius, height)
-    cylinder = ba.Particle(m_particle, ff)
-    particle_layout = ba.ParticleLayout()
-    particle_layout.addParticle(cylinder)
-
-    interference = ba.InterferenceFunction2DLattice(
-        lattice_constant, lattice_constant, 90.0*deg)
-    pdf = ba.FTDecayFunction2DCauchy(50*nm, 50*nm)
-    interference.setDecayFunction(pdf)
-
-    particle_layout.setInterferenceFunction(interference)
-
-    air_layer = ba.Layer(m_air)
-    air_layer.addLayout(particle_layout)
-    substrate_layer = ba.Layer(m_substrate, 0)
-    multi_layer = ba.MultiLayer()
-    multi_layer.addLayer(air_layer)
-    multi_layer.addLayer(substrate_layer)
-    return multi_layer
-
-
-def get_simulation(params):
-    """
-    Create and return GISAXS simulation with beam and detector defined
-    """
-    simulation = ba.GISASSimulation()
-    simulation.setDetectorParameters(100, -1.0*deg, 1.0*deg,
-                                     100, 0.0*deg, 2.0*deg)
-    simulation.setBeamParameters(1.0*angstrom, 0.2*deg, 0.0*deg)
-    simulation.setBeamIntensity(1e+08)
-    simulation.setSample(get_sample(params))
-    return simulation
-
-
-def create_real_data():
-    """
-    Generating "real" data by adding noise to the simulated data.
-    """
-    params = {'custom_length': 8.0*nm}
-
-    simulation = get_simulation(params)
-    simulation.runSimulation()
-
-    # retrieving simulated data in the form of numpy array
-    real_data = simulation.result().array()
-
-    # spoiling simulated data with the noise to produce "real" data
-    noise_factor = 0.1
-    noisy = np.random.normal(real_data, noise_factor*np.sqrt(real_data))
-    noisy[noisy < 0.1] = 0.1
-    return noisy
-
-
-def run_fitting():
-    """
-    main function to run fitting
-    """
-    real_data = create_real_data()
-
-    fit_objective = ba.FitObjective()
-    fit_objective.addSimulationAndData(get_simulation, real_data, 1.0)
-    fit_objective.initPrint(10)
-    fit_objective.initPlot(10)
-
-    params = ba.Parameters()
-    params.add("custom_length", 9.0*nm, min=6.0*nm, max=10.0*nm)
-
-    minimizer = ba.Minimizer()
-    result = minimizer.minimize(fit_objective.evaluate, params)
-
-    fit_objective.finalize(result)
-
-    print("Fitting completed.")
-    print("chi2:", result.minValue())
-    for fitPar in result.parameters():
-        print(fitPar.name(), fitPar.value, fitPar.error)
-
-
-if __name__ == '__main__':
-    run_fitting()
-    plt.show()
diff --git a/Examples/python/fitting/ex02_FitBasics/FitCylindersPrisms.py b/Examples/python/fitting/ex02_FitBasics/FitCylindersPrisms.py
deleted file mode 100644
index 4977ae6cea5112fa77fc8d34ddc26d6e5f3c2a10..0000000000000000000000000000000000000000
--- a/Examples/python/fitting/ex02_FitBasics/FitCylindersPrisms.py
+++ /dev/null
@@ -1,81 +0,0 @@
-"""
-Fitting example: 4 parameters fit with simple output
-"""
-import bornagain as ba
-from bornagain import deg, angstrom, nm
-
-
-def get_sample(cylinder_height=5.0*nm, cylinder_radius=5.0*nm,
-               prism_length=5.0*nm, prism_height=5.0*nm):
-    """
-    Returns a sample with uncorrelated cylinders and prisms on a substrate.
-    """
-    # defining materials
-    m_air = ba.HomogeneousMaterial("Air", 0.0, 0.0)
-    m_substrate = ba.HomogeneousMaterial("Substrate", 6e-6, 2e-8)
-    m_particle = ba.HomogeneousMaterial("Particle", 6e-4, 2e-8)
-
-    # collection of particles
-    cylinder_ff = ba.FormFactorCylinder(cylinder_radius, cylinder_height)
-    cylinder = ba.Particle(m_particle, cylinder_ff)
-    prism_ff = ba.FormFactorPrism3(prism_length, prism_height)
-    prism = ba.Particle(m_particle, prism_ff)
-    particle_layout = ba.ParticleLayout()
-    particle_layout.addParticle(cylinder, 0.5)
-    particle_layout.addParticle(prism, 0.5)
-    interference = ba.InterferenceFunctionNone()
-    particle_layout.setInterferenceFunction(interference)
-
-    # air layer with particles and substrate form multi layer
-    air_layer = ba.Layer(m_air)
-    air_layer.addLayout(particle_layout)
-    substrate_layer = ba.Layer(m_substrate, 0)
-    multi_layer = ba.MultiLayer()
-    multi_layer.addLayer(air_layer)
-    multi_layer.addLayer(substrate_layer)
-    return multi_layer
-
-
-def get_simulation():
-    """
-    Returns a GISAXS simulation with beam and detector defined
-    """
-    simulation = ba.GISASSimulation()
-    simulation.setDetectorParameters(100, -1.0*deg, 1.0*deg,
-                                     100, 0.0*deg, 2.0*deg)
-    simulation.setBeamParameters(1.0*angstrom, 0.2*deg, 0.0*deg)
-    simulation.setBeamIntensity(1e+08)
-    return simulation
-
-
-def run_fitting():
-    """
-    run fitting
-    """
-    sample = get_sample()
-    simulation = get_simulation()
-    simulation.setSample(sample)
-
-    real_data = ba.IntensityDataIOFactory.readIntensityData(
-        'refdata_fitcylinderprisms.int.gz')
-
-    fit_suite = ba.FitSuite()
-    fit_suite.addSimulationAndRealData(simulation, real_data)
-    fit_suite.initPrint(10)
-
-    # setting fitting parameters with starting values
-    fit_suite.addFitParameter("*Cylinder/Height", 4.*nm).setLowerLimited(0.01)
-    fit_suite.addFitParameter("*Cylinder/Radius", 6.*nm).setLowerLimited(0.01)
-    fit_suite.addFitParameter("*Prism3/Height", 4.*nm).setLowerLimited(0.01)
-    fit_suite.addFitParameter("*Prism3/BaseEdge", 12.*nm).setLowerLimited(0.01)
-
-    # running fit
-    fit_suite.runFit()
-
-    print("Fitting completed.")
-    print("chi2:", fit_suite.getChi2())
-    for par in fit_suite.fitParameters():
-        print(par.name(), par.value(), par.error())
-
-if __name__ == '__main__':
-    run_fitting()
diff --git a/Examples/python/fitting/ex02_FitBasics/FitCylindersPrisms_detailed.py b/Examples/python/fitting/ex02_FitBasics/FitCylindersPrisms_detailed.py
deleted file mode 100644
index 48f834553771a954188042703406d8ec9bea8ec1..0000000000000000000000000000000000000000
--- a/Examples/python/fitting/ex02_FitBasics/FitCylindersPrisms_detailed.py
+++ /dev/null
@@ -1,123 +0,0 @@
-"""
-Fitting example: 4 parameters fit with simple output
-This is more detailed version of ba.FitCylindersPrisms.py.
-We show how to generate "real" data and how to draw fit progress.
-Please take a note, that performance here is determined
-by poor performance of matplotlib drawing routines.
-"""
-
-import math
-import random
-import bornagain as ba
-import numpy as np
-from matplotlib import pyplot as plt
-from bornagain import deg, angstrom, nm
-
-
-def get_sample(cylinder_height=1.0*nm, cylinder_radius=1.0*nm,
-               prism_length=2.0*nm, prism_height=1.0*nm):
-    """
-    Returns a sample with uncorrelated cylinders and prisms on a substrate.
-    """
-    # defining materials
-    m_air = ba.HomogeneousMaterial("Air", 0.0, 0.0)
-    m_substrate = ba.HomogeneousMaterial("Substrate", 6e-6, 2e-8)
-    m_particle = ba.HomogeneousMaterial("Particle", 6e-4, 2e-8)
-
-    # collection of particles
-    cylinder_ff = ba.FormFactorCylinder(cylinder_radius, cylinder_height)
-    cylinder = ba.Particle(m_particle, cylinder_ff)
-    prism_ff = ba.FormFactorPrism3(prism_length, prism_height)
-    prism = ba.Particle(m_particle, prism_ff)
-    particle_layout = ba.ParticleLayout()
-    particle_layout.addParticle(cylinder, 0.5)
-    particle_layout.addParticle(prism, 0.5)
-    interference = ba.InterferenceFunctionNone()
-    particle_layout.setInterferenceFunction(interference)
-
-    # air layer with particles and substrate form multi layer
-    air_layer = ba.Layer(m_air)
-    air_layer.addLayout(particle_layout)
-    substrate_layer = ba.Layer(m_substrate, 0)
-    multi_layer = ba.MultiLayer()
-    multi_layer.addLayer(air_layer)
-    multi_layer.addLayer(substrate_layer)
-    return multi_layer
-
-
-def create_real_data():
-    """
-    Generating "real" data by adding noise to the simulated data.
-    This function has been used once to generate refdata_fitcylinderprisms.int
-    located in same directory.
-    """
-    # creating sample with set of parameters we will later try to find during the fit
-    sample = get_sample(5.0*nm, 5.0*nm, 5.0*nm, 5.0*nm)
-    simulation = get_simulation()
-    simulation.setSample(sample)
-    simulation.runSimulation()
-
-    # retrieving simulated data in the form of numpy array
-    real_data = simulation.result().array()
-
-    # spoiling simulated data with noise to produce "real" data
-    np.random.seed(0)
-    noise_factor = 0.1
-    noisy = np.random.normal(real_data, noise_factor*np.sqrt(real_data))
-    noisy[noisy < 0.1] = 0.1
-    return noisy
-
-
-def get_simulation():
-    """
-    Returns a GISAXS simulation with beam and detector defined
-    """
-    simulation = ba.GISASSimulation()
-    simulation.setDetectorParameters(100, -1.0*deg, 1.0*deg,
-                                     100, 0.0*deg, 2.0*deg)
-    simulation.setBeamParameters(1.0*angstrom, 0.2*deg, 0.0*deg)
-    simulation.setBeamIntensity(1e+08)
-    return simulation
-
-
-def run_fitting():
-    """
-    Setup simulation and fit
-    """
-
-    sample = get_sample()
-    simulation = get_simulation()
-    simulation.setSample(sample)
-
-    real_data = create_real_data()
-
-    fit_suite = ba.FitSuite()
-    fit_suite.addSimulationAndRealData(simulation, real_data)
-
-    # fit_suite.setMinimizer("Minuit2", "Migrad")  # ba.Default
-    # fit_suite.setMinimizer("Minuit2", "Fumili")
-    # fit_suite.setMinimizer("GSLLMA")
-
-    fit_suite.initPrint(10)
-
-    # setting fitting parameters with starting values
-    fit_suite.addFitParameter("*Cylinder/Height", 4.*nm).setLowerLimited(0.01)
-    fit_suite.addFitParameter("*Cylinder/Radius", 6.*nm).setLowerLimited(0.01)
-    fit_suite.addFitParameter("*Prism3/Height", 4.*nm).setLowerLimited(0.01)
-    fit_suite.addFitParameter("*Prism3/BaseEdge", 12.*nm).setLowerLimited(0.01)
-
-    draw_observer = ba.DefaultFitObserver(draw_every_nth=10)
-    fit_suite.attachObserver(draw_observer)
-
-    fit_suite.runFit()
-    print("Fitting completed.")
-    print("chi2:", fit_suite.getChi2())
-    for fitPar in fit_suite.fitParameters():
-        print(fitPar.name(), fitPar.value(), fitPar.error())
-
-    return fit_suite
-
-
-if __name__ == '__main__':
-    run_fitting()
-    plt.show()
diff --git a/Examples/python/fitting/ex02_FitBasics/FitCylindersPrisms_new.py b/Examples/python/fitting/ex02_FitBasics/FitCylindersPrisms_new.py
deleted file mode 100644
index bc7d908eebb5752d54f987fe9094081bf748bfeb..0000000000000000000000000000000000000000
--- a/Examples/python/fitting/ex02_FitBasics/FitCylindersPrisms_new.py
+++ /dev/null
@@ -1,80 +0,0 @@
-"""
-Fitting example: 4 parameters fit with simple output
-"""
-import bornagain as ba
-from bornagain import deg, angstrom, nm
-
-
-def get_sample(params):
-    """
-    Returns a sample with uncorrelated cylinders and prisms on a substrate.
-    """
-    cylinder_height = params["cylinder_height"]
-    cylinder_radius = params["cylinder_radius"]
-    prism_height = params["prism_height"]
-    prism_base_edge = params["prism_base_edge"]
-
-    # defining materials
-    m_air = ba.HomogeneousMaterial("Air", 0.0, 0.0)
-    m_substrate = ba.HomogeneousMaterial("Substrate", 6e-6, 2e-8)
-    m_particle = ba.HomogeneousMaterial("Particle", 6e-4, 2e-8)
-
-    # collection of particles
-    cylinder_ff = ba.FormFactorCylinder(cylinder_radius, cylinder_height)
-    cylinder = ba.Particle(m_particle, cylinder_ff)
-    prism_ff = ba.FormFactorPrism3(prism_base_edge, prism_height)
-    prism = ba.Particle(m_particle, prism_ff)
-    particle_layout = ba.ParticleLayout()
-    particle_layout.addParticle(cylinder, 0.5)
-    particle_layout.addParticle(prism, 0.5)
-    interference = ba.InterferenceFunctionNone()
-    particle_layout.setInterferenceFunction(interference)
-
-    # air layer with particles and substrate form multi layer
-    air_layer = ba.Layer(m_air)
-    air_layer.addLayout(particle_layout)
-    substrate_layer = ba.Layer(m_substrate, 0)
-    multi_layer = ba.MultiLayer()
-    multi_layer.addLayer(air_layer)
-    multi_layer.addLayer(substrate_layer)
-    return multi_layer
-
-
-def get_simulation(params):
-    """
-    Returns a GISAXS simulation with beam and detector defined
-    """
-    simulation = ba.GISASSimulation()
-    simulation.setDetectorParameters(100, -1.0*deg, 1.0*deg,
-                                     100, 0.0*deg, 2.0*deg)
-    simulation.setBeamParameters(1.0*angstrom, 0.2*deg, 0.0*deg)
-    simulation.setBeamIntensity(1e+08)
-    simulation.setSample(get_sample(params))
-    return simulation
-
-
-def run_fitting():
-    """
-    run fitting
-    """
-    real_data = ba.IntensityDataIOFactory.readIntensityData(
-        'refdata_fitcylinderprisms.int.gz')
-
-    fit_objective = ba.FitObjective()
-    fit_objective.addSimulationAndData(get_simulation, real_data.array(), 1.0)
-    fit_objective.initPrint(10)
-
-    params = ba.Parameters()
-    params.add("cylinder_height", 4.*nm, min=0.01)
-    params.add("cylinder_radius", 6.*nm, min=0.01)
-    params.add("prism_height", 4.*nm, min=0.01)
-    params.add("prism_base_edge", 12.*nm, min=0.01)
-
-    minimizer = ba.Minimizer()
-    result = minimizer.minimize(fit_objective.evaluate, params)
-
-    fit_objective.finalize(result)
-
-
-if __name__ == '__main__':
-    run_fitting()
diff --git a/Examples/python/fitting/ex02_FitBasics/MinimizerOptions.py b/Examples/python/fitting/ex02_FitBasics/MinimizerOptions.py
deleted file mode 100644
index 802231921d7e627af5bf767f2f491155558a0fc4..0000000000000000000000000000000000000000
--- a/Examples/python/fitting/ex02_FitBasics/MinimizerOptions.py
+++ /dev/null
@@ -1,114 +0,0 @@
-"""
-Fitting example: running same fit using various minimizer and their settings.
-"""
-import bornagain as ba
-from bornagain import deg, angstrom, nm
-
-
-def get_sample(cylinder_height=5.0*nm, cylinder_radius=5.0*nm,
-               prism_length=5.0*nm, prism_height=5.0*nm):
-    """
-    Returns a sample with uncorrelated cylinders and prisms on a substrate.
-    """
-    # defining materials
-    m_air = ba.HomogeneousMaterial("Air", 0.0, 0.0)
-    m_substrate = ba.HomogeneousMaterial("Substrate", 6e-6, 2e-8)
-    m_particle = ba.HomogeneousMaterial("Particle", 6e-4, 2e-8)
-
-    # collection of particles
-    cylinder_ff = ba.FormFactorCylinder(cylinder_radius, cylinder_height)
-    cylinder = ba.Particle(m_particle, cylinder_ff)
-    prism_ff = ba.FormFactorPrism3(prism_length, prism_height)
-    prism = ba.Particle(m_particle, prism_ff)
-    particle_layout = ba.ParticleLayout()
-    particle_layout.addParticle(cylinder, 0.5)
-    particle_layout.addParticle(prism, 0.5)
-    interference = ba.InterferenceFunctionNone()
-    particle_layout.setInterferenceFunction(interference)
-
-    # air layer with particles and substrate form multi layer
-    air_layer = ba.Layer(m_air)
-    air_layer.addLayout(particle_layout)
-    substrate_layer = ba.Layer(m_substrate, 0)
-    multi_layer = ba.MultiLayer()
-    multi_layer.addLayer(air_layer)
-    multi_layer.addLayer(substrate_layer)
-    return multi_layer
-
-
-def get_simulation():
-    """
-    Returns a GISAXS simulation with beam and detector defined
-    """
-    simulation = ba.GISASSimulation()
-    simulation.setDetectorParameters(100, -1.0*deg, 1.0*deg,
-                                     100, 0.0*deg, 2.0*deg)
-    simulation.setBeamParameters(1.0*angstrom, 0.2*deg, 0.0*deg)
-    simulation.setBeamIntensity(1e+08)
-    return simulation
-
-
-def run_fitting():
-    """
-    run fitting
-    """
-
-    # prints info about available minimizers
-    print(ba.MinimizerFactory().catalogueToString())
-
-    # prints detailed info about available minimizers and their options
-    print(ba.MinimizerFactory().catalogueDetailsToString())
-
-    sample = get_sample()
-    simulation = get_simulation()
-    simulation.setSample(sample)
-
-    real_data = ba.IntensityDataIOFactory.readIntensityData(
-        'refdata_fitcylinderprisms.int.gz')
-
-    fit_suite = ba.FitSuite()
-    fit_suite.addSimulationAndRealData(simulation, real_data)
-    fit_suite.initPrint(10)
-
-    # setting fitting parameters with starting values
-    fit_suite.addFitParameter("*Cylinder/Height", 4.*nm).setLowerLimited(0.01)
-    fit_suite.addFitParameter("*Cylinder/Radius", 6.*nm).setLowerLimited(0.01)
-    fit_suite.addFitParameter("*Prism3/Height", 4.*nm).setLowerLimited(0.01)
-    fit_suite.addFitParameter("*Prism3/BaseEdge", 12.*nm).setLowerLimited(0.01)
-
-    # Uncomment one of the line below to adjust minimizer settings
-
-    # setting Minuit2 minimizer with Migrad algorithm, limiting number of iterations
-    # Minimization will try to respect MaxFunctionCalls value
-    # fit_suite.setMinimizer("Minuit2", "Migrad", "MaxFunctionCalls=100")
-
-    # Setting two options at once.
-    # Strategy=2 promises more accurate fit.
-    # fit_suite.setMinimizer("Minuit2", "Simplex", "MaxFunctionCalls=100;Strategy=2")
-
-    # setting Minuit2 minimizer with Fumili algorithm
-    # fit_suite.setMinimizer("Minuit2", "Fumili")
-
-    # Setting Levenberg-Marquardt algorithm
-    # fit_suite.setMinimizer("GSLLMA")
-
-    # Setting Genetic algorithm.It requires all parameters
-    # to be limited, so we recreate parameters with min and max defined
-    # fit_suite.fitParameters().clear()
-    # fit_suite.addFitParameter("*Cylinder/Height", 4.*nm).setLimited(3.0, 8.0)
-    # fit_suite.addFitParameter("*Cylinder/Radius", 6.*nm).setLimited(3.0, 8.0)
-    # fit_suite.addFitParameter("*Prism3/Height", 4.*nm).setLimited(3.0, 8.0)
-    # fit_suite.addFitParameter("*Prism3/BaseEdge", 4.*nm).setLimited(3.0, 8.0)
-    # fit_suite.setMinimizer("Genetic", "Default",
-    # "MaxIterations=2;PopSize=200;RandomSeed=1")
-
-    # running fit with default minimizer
-    fit_suite.runFit()
-
-    print("Fitting completed.")
-    print("chi2:", fit_suite.getChi2())
-    for par in fit_suite.fitParameters():
-        print(par.name(), par.value(), par.error())
-
-if __name__ == '__main__':
-    run_fitting()
diff --git a/Examples/python/fitting/ex02_FitBasics/refdata_fitcylinderprisms.int.gz b/Examples/python/fitting/ex02_FitBasics/refdata_fitcylinderprisms.int.gz
deleted file mode 100644
index 2354afde99750a02b4ac4b19bea1237c2683d05f..0000000000000000000000000000000000000000
Binary files a/Examples/python/fitting/ex02_FitBasics/refdata_fitcylinderprisms.int.gz and /dev/null differ
diff --git a/Examples/python/fitting/ex03_FitSpheresInHexLattice/FitSpheresInHexLattice.py b/Examples/python/fitting/ex03_ExtendedExamples/custom_objective_function/custom_objective_function.py
similarity index 56%
rename from Examples/python/fitting/ex03_FitSpheresInHexLattice/FitSpheresInHexLattice.py
rename to Examples/python/fitting/ex03_ExtendedExamples/custom_objective_function/custom_objective_function.py
index 9e8e86c8809d0171ad9aa563ed980d734ba66e7f..af6e8e1dc024e7efa2c23d766dca0fdc679f9dd8 100644
--- a/Examples/python/fitting/ex03_FitSpheresInHexLattice/FitSpheresInHexLattice.py
+++ b/Examples/python/fitting/ex03_ExtendedExamples/custom_objective_function/custom_objective_function.py
@@ -1,7 +1,8 @@
 """
-Two parameter fit of spheres in a hex lattice.
-See FitSpheresInHexLattice_builder.py example which performs same fitting task
-using advanced sample construction techniques.
+Using custom objective function to fit GISAS data.
+
+In this example objective function returns vector of residuals computed from
+the data and simulation after applying sqrt() to intensity values.
 """
 
 import numpy as np
@@ -10,11 +11,37 @@ import bornagain as ba
 from bornagain import deg, angstrom, nm
 
 
-def get_sample(radius=5.0*nm, lattice_constant=10.0*nm):
+class MyObjective(ba.FitObjective):
+    """
+    FitObjective extension for custom fitting metric.
+    """
+    def __init__(self):
+        super(MyObjective, self).__init__()
+
+    def evaluate_residuals(self, params):
+        """
+        Provides custom calculation of vector of residuals
+        """
+        # calling parent's evaluate functions to run simulations
+        super(MyObjective, self).evaluate(params)
+
+        # accessing simulated and experimental data as flat numpy arrays
+        # applying sqrt to every element
+        sim = np.sqrt(np.asarray(self.simulation_array()))
+        exp = np.sqrt(np.asarray(self.experimental_array()))
+
+        # return vector of residuals
+        return sim - exp
+
+
+def get_sample(params):
     """
     Returns a sample with cylinders and pyramids on a substrate,
     forming a hexagonal lattice.
     """
+    radius = params['radius']
+    lattice_length = params['length']
+
     m_air = ba.HomogeneousMaterial("Air", 0.0, 0.0)
     m_substrate = ba.HomogeneousMaterial("Substrate", 6e-6, 2e-8)
     m_particle = ba.HomogeneousMaterial("Particle", 6e-4, 2e-8)
@@ -24,7 +51,7 @@ def get_sample(radius=5.0*nm, lattice_constant=10.0*nm):
     particle_layout = ba.ParticleLayout()
     particle_layout.addParticle(sphere)
 
-    interference = ba.InterferenceFunction2DLattice.createHexagonal(lattice_constant)
+    interference = ba.InterferenceFunction2DLattice.createHexagonal(lattice_length)
     pdf = ba.FTDecayFunction2DCauchy(10*nm, 10*nm)
     interference.setDecayFunction(pdf)
 
@@ -39,15 +66,16 @@ def get_sample(radius=5.0*nm, lattice_constant=10.0*nm):
     return multi_layer
 
 
-def get_simulation():
+def get_simulation(params):
     """
-    Create and return GISAXS simulation with beam and detector defined
+    Create and return GISAXS simulation with beam and detector defined.
     """
     simulation = ba.GISASSimulation()
     simulation.setDetectorParameters(100, -1.0*deg, 1.0*deg,
                                      100, 0.0*deg, 2.0*deg)
     simulation.setBeamParameters(1.0*angstrom, 0.2*deg, 0.0*deg)
     simulation.setBeamIntensity(1e+08)
+    simulation.setSample(get_sample(params))
     return simulation
 
 
@@ -55,16 +83,14 @@ def create_real_data():
     """
     Generating "real" data by adding noise to the simulated data.
     """
-    sample = get_sample(5.0*nm, 10.0*nm)
-    simulation = get_simulation()
-    simulation.setSample(sample)
+    params = {'radius': 6*nm, 'length': 12*nm}
+    simulation = get_simulation(params)
     simulation.runSimulation()
 
     # retrieving simulated data in the form of numpy array
     real_data = simulation.result().array()
 
     # spoiling simulated data with noise to produce "real" data
-    # random seed made as in FitSPheresInHexLattice_builder.py example
     np.random.seed(0)
     noise_factor = 0.1
     noisy = np.random.normal(real_data, noise_factor*np.sqrt(real_data))
@@ -74,37 +100,21 @@ def create_real_data():
 
 def run_fitting():
     """
-    main function to run fitting
+    Runs fitting.
     """
-    simulation = get_simulation()
-    sample = get_sample()
-    simulation.setSample(sample)
-
     real_data = create_real_data()
 
-    fit_suite = ba.FitSuite()
-    #fit_suite.setMinimizer("GSLLMA")
-    fit_suite.addSimulationAndRealData(simulation, real_data)
-    fit_suite.initPrint(10)
-
-    draw_observer = ba.DefaultFitObserver(draw_every_nth=10)
-    fit_suite.attachObserver(draw_observer)
-
-    fit_suite.addFitParameter(
-        "*/FullSphere/Radius", 8.*nm, ba.AttLimits.limited(4., 12.))
-    fit_suite.addFitParameter(
-        "*HexagonalLattice/LatticeLength", 8.*nm, ba.AttLimits.limited(4., 12.))
-
-    print(fit_suite.treeToString())
-    print(fit_suite.parametersToString())
+    objective = MyObjective()
+    objective.addSimulationAndData(get_simulation, real_data, 1.0)
+    objective.initPrint(10)
 
-    # running fit
-    fit_suite.runFit()
+    params = ba.Parameters()
+    params.add('radius', value=7*nm, min=5*nm, max=8*nm)
+    params.add('length', value=10*nm, min=8*nm, max=14*nm)
 
-    print("Fitting completed.")
-    print("chi2:", fit_suite.getChi2())
-    for fitPar in fit_suite.fitParameters():
-        print(fitPar.name(), fitPar.value(), fitPar.error())
+    minimizer = ba.Minimizer()
+    result = minimizer.minimize(objective.evaluate_residuals, params)
+    objective.finalize(result)
 
 
 if __name__ == '__main__':
diff --git a/Examples/python/fitting/ex10_FitGALAXIData/FitGALAXIData_new.py b/Examples/python/fitting/ex03_ExtendedExamples/experiment_at_galaxi/fit_galaxi_data.py
similarity index 71%
rename from Examples/python/fitting/ex10_FitGALAXIData/FitGALAXIData_new.py
rename to Examples/python/fitting/ex03_ExtendedExamples/experiment_at_galaxi/fit_galaxi_data.py
index c68f50e9cfad9a4c1892742d182e8991bcd6bbed..a60048f30cbc7fe34d23ddd7f37c3dbd769c6263 100644
--- a/Examples/python/fitting/ex10_FitGALAXIData/FitGALAXIData_new.py
+++ b/Examples/python/fitting/ex03_ExtendedExamples/experiment_at_galaxi/fit_galaxi_data.py
@@ -1,12 +1,10 @@
 """
-Real life example: experiment at GALAXY
+Fitting experimental data: spherical nanoparticles with size distribution
+in 3 layers system (experiment at GALAXI).
 """
-import matplotlib
-from matplotlib import pyplot as plt
-import numpy
 import bornagain as ba
 from bornagain import nm as nm
-from SampleBuilder_new import MySampleBuilder
+from sample_builder import SampleBuilder
 
 wavelength = 1.34*ba.angstrom
 alpha_i = 0.463*ba.deg
@@ -39,17 +37,9 @@ def create_simulation(params):
     simulation.setBeamParameters(wavelength, alpha_i, 0.0)
     simulation.setBeamIntensity(1.2e7)
     simulation.setRegionOfInterest(85.0, 70.0, 120.0, 92.)
-    # mask on reflected beam
-    simulation.addMask(ba.Rectangle(101.9, 82.1, 103.7, 85.2), True)
-    # detector resolution function
-    # simulation.setDetectorResolutionFunction(
-    #   ba.ResolutionFunction2DGaussian(0.5*pilatus_pixel_size,
-    #      0.5*pilatus_pixel_size))
-    # beam divergence
-    # alpha_distr = ba.DistributionGaussian(alpha_i, 0.02*ba.deg)
-    # simulation.addParameterDistribution("*/Beam/Alpha", alpha_distr, 5)
-
-    sample_builder = MySampleBuilder()
+    simulation.addMask(ba.Rectangle(101.9, 82.1, 103.7, 85.2), True)  # mask on reflected beam
+
+    sample_builder = SampleBuilder()
     sample = sample_builder.create_sample(params)
     simulation.setSample(sample)
 
@@ -58,11 +48,9 @@ def create_simulation(params):
 
 def load_real_data(filename="galaxi_data.tif.gz"):
     """
-    Fill histogram representing our detector with intensity data from tif file.
-    Returns cropped version of it, which represent the area we are interested in.
+    Loads experimental data and returns numpy array.
     """
-    hist = ba.IHistogram.createFrom(filename).array()
-    return hist
+    return ba.IntensityDataIOFactory.readIntensityData(filename).array()
 
 
 def run_fitting():
diff --git a/Examples/python/fitting/ex10_FitGALAXIData/galaxi_data.tif.gz b/Examples/python/fitting/ex03_ExtendedExamples/experiment_at_galaxi/galaxi_data.tif.gz
similarity index 100%
rename from Examples/python/fitting/ex10_FitGALAXIData/galaxi_data.tif.gz
rename to Examples/python/fitting/ex03_ExtendedExamples/experiment_at_galaxi/galaxi_data.tif.gz
diff --git a/Examples/python/fitting/ex10_FitGALAXIData/SampleBuilder_new.py b/Examples/python/fitting/ex03_ExtendedExamples/experiment_at_galaxi/sample_builder.py
similarity index 73%
rename from Examples/python/fitting/ex10_FitGALAXIData/SampleBuilder_new.py
rename to Examples/python/fitting/ex03_ExtendedExamples/experiment_at_galaxi/sample_builder.py
index 7cb141e5f99df8505c0845ce32e0b6d2498b5cd8..78d811461fa8611cc40b167dc9104b8e820ed035 100644
--- a/Examples/python/fitting/ex10_FitGALAXIData/SampleBuilder_new.py
+++ b/Examples/python/fitting/ex03_ExtendedExamples/experiment_at_galaxi/sample_builder.py
@@ -1,16 +1,18 @@
 """
 3 layers system (substrate, teflon, air).
-Air layer is populated with spheres with some size distribution.
+Air layer is populated with spheres with size distribution.
 """
 import bornagain as ba
 
 
-class MySampleBuilder():
+class SampleBuilder:
     """
-
+    Builds complex sample from set of parameters.
     """
     def __init__(self):
-        # parameters describing the sample
+        """
+        Init SampleBuilder with default sample parameters.
+        """
         self.radius = 5.75*ba.nm
         self.sigma = 0.4
         self.distance = 53.6*ba.nm
@@ -20,13 +22,25 @@ class MySampleBuilder():
         self.hmdso_thickness = 18.5*ba.nm
 
     def create_sample(self, params):
+        """
+        Create sample from given set of parameters.
+
+        Args:
+            params: A dictionary containing parameter map.
+
+        Returns:
+            A multi layer.
+        """
         self.radius = params["radius"]
         self.sigma = params["sigma"]
         self.distance = params["distance"]
         return self.multilayer()
 
-    # constructs the sample for current values of parameters
     def multilayer(self):
+        """
+        Constructs the sample from current parameter values.
+        """
+
         # defining materials
         m_air = ba.HomogeneousMaterial("Air", 0.0, 0.0)
         m_Si = ba.HomogeneousMaterial("Si", 5.78164736e-6, 1.02294578e-7)
@@ -38,20 +52,14 @@ class MySampleBuilder():
         nparticles = 20
         nfwhm = 2.0
         sphere_ff = ba.FormFactorFullSphere(self.radius)
-        # sphere_ff = ba.FormFactorTruncatedSphere(
-        #    self.radius, self.radius*1.5)
 
         sphere = ba.Particle(m_Ag, sphere_ff)
-        position = ba.kvector_t(0*ba.nm, 0*ba.nm,
-                                -1.0*self.hmdso_thickness)
+        position = ba.kvector_t(0*ba.nm, 0*ba.nm,-1.0*self.hmdso_thickness)
         sphere.setPosition(position)
         ln_distr = ba.DistributionLogNormal(self.radius, self.sigma)
         par_distr = ba.ParameterDistribution(
             "/Particle/FullSphere/Radius", ln_distr, nparticles, nfwhm,
             ba.RealLimits.limited(0.0, self.hmdso_thickness/2.0))
-        # par_distr = ba.ParameterDistribution(
-        #    "/Particle/TruncatedSphere/Radius", ln_distr, nparticles, nfwhm)
-        # par_distr.linkParameter("/Particle/TruncatedSphere/Height")
         part_coll = ba.ParticleDistribution(sphere, par_distr)
 
         # interference function
@@ -63,11 +71,11 @@ class MySampleBuilder():
         interference.setProbabilityDistribution(pdf)
 
         # assembling particle layout
-        particle_layout = ba.ParticleLayout()
-        particle_layout.addParticle(part_coll, 1.0)
-        particle_layout.setInterferenceFunction(interference)
-        particle_layout.setApproximation(ba.ILayout.SSCA)
-        particle_layout.setTotalParticleSurfaceDensity(1)
+        layout = ba.ParticleLayout()
+        layout.addParticle(part_coll, 1.0)
+        layout.setInterferenceFunction(interference)
+        layout.setApproximation(ba.ILayout.SSCA)
+        layout.setTotalParticleSurfaceDensity(1)
 
         # roughness
         r_ptfe = ba.LayerRoughness(2.3*ba.nm, 0.3, 5.0*ba.nm)
@@ -76,7 +84,7 @@ class MySampleBuilder():
         # layers
         air_layer = ba.Layer(m_air)
         hmdso_layer = ba.Layer(m_HMDSO, self.hmdso_thickness)
-        hmdso_layer.addLayout(particle_layout)
+        hmdso_layer.addLayout(layout)
         ptfe_layer = ba.Layer(m_PTFE, self.ptfe_thickness)
         substrate_layer = ba.Layer(m_Si)
 
diff --git a/Examples/python/fitting/ex11_ExternalMinimizer/lmfit_basics_new.py b/Examples/python/fitting/ex03_ExtendedExamples/external_minimizer/lmfit_basics.py
similarity index 90%
rename from Examples/python/fitting/ex11_ExternalMinimizer/lmfit_basics_new.py
rename to Examples/python/fitting/ex03_ExtendedExamples/external_minimizer/lmfit_basics.py
index df420ccb1f56f1157c755504ccaf601ed8444b2b..c50bd2ab6a4f7147fd7bba3743bb2eb3f5620629 100644
--- a/Examples/python/fitting/ex11_ExternalMinimizer/lmfit_basics_new.py
+++ b/Examples/python/fitting/ex03_ExtendedExamples/external_minimizer/lmfit_basics.py
@@ -1,5 +1,5 @@
 """
-Example of using external minimizer to fit typical BornAgain simulation
+External minimize: using lmfit minimizers for BornAgain fits.
 """
 import numpy as np
 from matplotlib import pyplot as plt
@@ -7,8 +7,6 @@ import bornagain as ba
 from bornagain import deg, angstrom, nm
 import lmfit
 
-real_data = None
-
 
 def get_sample(params):
     """
@@ -59,7 +57,7 @@ def create_real_data():
     """
     Generating "real" data by adding noise to the simulated data.
     """
-    params = {'radius': 5*nm, 'length': 5*nm}
+    params = {'radius': 6*nm, 'length': 12*nm}
     simulation = get_simulation(params)
     simulation.runSimulation()
 
@@ -78,7 +76,6 @@ def run_fitting():
     """
     main function to run fitting
     """
-    global real_data
     real_data = create_real_data()
 
     fit_objective = ba.FitObjective()
@@ -86,16 +83,16 @@ def run_fitting():
     fit_objective.initPrint(10)
 
     params = lmfit.Parameters()
-    params.add('radius', value=8*nm)
-    params.add('length', value=8*nm)
+    params.add('radius', value=7*nm, min=5*nm, max=8*nm)
+    params.add('length', value=10*nm, min=8*nm, max=14*nm)
 
     result = lmfit.minimize(fit_objective.evaluate_residuals, params)
-
     fit_objective.finalize(result)
+
+    print(result.params.pretty_print())
     print(lmfit.fit_report(result))
 
+
 if __name__ == '__main__':
     run_fitting()
     plt.show()
-
-
diff --git a/Examples/python/fitting/ex11_ExternalMinimizer/lmfit_basics.py b/Examples/python/fitting/ex03_ExtendedExamples/external_minimizer/lmfit_with_plotting.py
similarity index 65%
rename from Examples/python/fitting/ex11_ExternalMinimizer/lmfit_basics.py
rename to Examples/python/fitting/ex03_ExtendedExamples/external_minimizer/lmfit_with_plotting.py
index 1beb6d9cdbe36cabc500c1de8fc0ac4cf9fc7c10..70cf8515e04be6a58caf60baf2e2375b78191d4c 100644
--- a/Examples/python/fitting/ex11_ExternalMinimizer/lmfit_basics.py
+++ b/Examples/python/fitting/ex03_ExtendedExamples/external_minimizer/lmfit_with_plotting.py
@@ -1,5 +1,6 @@
 """
-Example of using external minimizer to fit typical BornAgain simulation
+External minimize: using lmfit minimizers for BornAgain fits.
+Fit progress is plotted using lmfit iteration calbback function.
 """
 import numpy as np
 from matplotlib import pyplot as plt
@@ -8,11 +9,14 @@ from bornagain import deg, angstrom, nm
 import lmfit
 
 
-def get_sample(radius=5.0*nm, lattice_length=10.0*nm):
+def get_sample(params):
     """
     Returns a sample with cylinders and pyramids on a substrate,
     forming a hexagonal lattice.
     """
+    radius = params['radius']
+    lattice_length = params['length']
+
     m_air = ba.HomogeneousMaterial("Air", 0.0, 0.0)
     m_substrate = ba.HomogeneousMaterial("Substrate", 6e-6, 2e-8)
     m_particle = ba.HomogeneousMaterial("Particle", 6e-4, 2e-8)
@@ -37,7 +41,7 @@ def get_sample(radius=5.0*nm, lattice_length=10.0*nm):
     return multi_layer
 
 
-def get_simulation():
+def get_simulation(params):
     """
     Create and return GISAXS simulation with beam and detector defined
     """
@@ -46,6 +50,7 @@ def get_simulation():
                                      100, 0.0*deg, 2.0*deg)
     simulation.setBeamParameters(1.0*angstrom, 0.2*deg, 0.0*deg)
     simulation.setBeamIntensity(1e+08)
+    simulation.setSample(get_sample(params))
     return simulation
 
 
@@ -53,9 +58,8 @@ def create_real_data():
     """
     Generating "real" data by adding noise to the simulated data.
     """
-    sample = get_sample(5.0*nm, 10.0*nm)
-    simulation = get_simulation()
-    simulation.setSample(sample)
+    params = {'radius': 6*nm, 'length': 12*nm}
+    simulation = get_simulation(params)
     simulation.runSimulation()
 
     # retrieving simulated data in the form of numpy array
@@ -69,41 +73,41 @@ def create_real_data():
     return noisy
 
 
-def residual(params, simulation, data):
-    radius = params['radius'].value
-    length = params['length'].value
-    print(radius, length)
-    sample = get_sample(radius=radius, lattice_length=length)
-    simulation.setSample(sample)
-    simulation.runSimulation()
-    result = simulation.result().array().flatten()
-    exp = data.flatten()
-    res = result-exp
-    return res
+class Plotter:
+    """
+    Adapts standard plotter for lmfit minimizer.
+    """
+    def __init__(self, fit_objective, every_nth = 10):
+        self.fit_objective = fit_objective
+        self.plotter_gisas = ba.PlotterGISAS()
+        self.every_nth = every_nth
+
+    def __call__(self, params, iter, resid):
+        if iter%self.every_nth == 0:
+            self.plotter_gisas.plot(self.fit_objective)
 
 
 def run_fitting():
     """
     main function to run fitting
     """
-    simulation = get_simulation()
-    sample = get_sample()
-    simulation.setSample(sample)
-
     real_data = create_real_data()
 
+    fit_objective = ba.FitObjective()
+    fit_objective.addSimulationAndData(get_simulation, real_data, 1.0)
+    fit_objective.initPrint(10)
+
     params = lmfit.Parameters()
-    params.add('radius', value=8*nm)
-    params.add('length', value=8*nm)
+    params.add('radius', value=7*nm, min=5*nm, max=8*nm)
+    params.add('length', value=10*nm, min=8*nm, max=14*nm)
 
-    result = lmfit.minimize(residual, params, args=(simulation, real_data))
+    plotter = Plotter(fit_objective)
+    result = lmfit.minimize(fit_objective.evaluate_residuals, params, iter_cb=plotter)
+    fit_objective.finalize(result)
 
     result.params.pretty_print()
     print(lmfit.fit_report(result))
 
-
 if __name__ == '__main__':
     run_fitting()
     plt.show()
-
-
diff --git a/Examples/python/fitting/ex09_FitSpecular/FitSpecularBasics.py b/Examples/python/fitting/ex03_ExtendedExamples/specular/FitSpecularBasics.py
similarity index 100%
rename from Examples/python/fitting/ex09_FitSpecular/FitSpecularBasics.py
rename to Examples/python/fitting/ex03_ExtendedExamples/specular/FitSpecularBasics.py
diff --git a/Examples/python/fitting/ex09_FitSpecular/RealLifeReflectometryFitting.py b/Examples/python/fitting/ex03_ExtendedExamples/specular/RealLifeReflectometryFitting.py
similarity index 100%
rename from Examples/python/fitting/ex09_FitSpecular/RealLifeReflectometryFitting.py
rename to Examples/python/fitting/ex03_ExtendedExamples/specular/RealLifeReflectometryFitting.py
diff --git a/Examples/python/fitting/ex09_FitSpecular/genx_interchanging_layers.dat.gz b/Examples/python/fitting/ex03_ExtendedExamples/specular/genx_interchanging_layers.dat.gz
similarity index 100%
rename from Examples/python/fitting/ex09_FitSpecular/genx_interchanging_layers.dat.gz
rename to Examples/python/fitting/ex03_ExtendedExamples/specular/genx_interchanging_layers.dat.gz
diff --git a/Examples/python/fitting/ex09_FitSpecular/mg6a_Merged.txt.gz b/Examples/python/fitting/ex03_ExtendedExamples/specular/mg6a_Merged.txt.gz
similarity index 100%
rename from Examples/python/fitting/ex09_FitSpecular/mg6a_Merged.txt.gz
rename to Examples/python/fitting/ex03_ExtendedExamples/specular/mg6a_Merged.txt.gz
diff --git a/Examples/python/fitting/ex03_FitSpheresInHexLattice/FitSpheresInHexLattice_builder.py b/Examples/python/fitting/ex03_FitSpheresInHexLattice/FitSpheresInHexLattice_builder.py
deleted file mode 100644
index 9f2e6724095a16fa0bb158ff21194edd9882f693..0000000000000000000000000000000000000000
--- a/Examples/python/fitting/ex03_FitSpheresInHexLattice/FitSpheresInHexLattice_builder.py
+++ /dev/null
@@ -1,130 +0,0 @@
-"""
-Two parameter fit of spheres in a hex lattice.
-Sample builder approach is used.
-"""
-
-import numpy as np
-import ctypes
-import bornagain as ba
-from matplotlib import pyplot as plt
-from bornagain import deg, angstrom, nm
-
-
-class MySampleBuilder(ba.IMultiLayerBuilder):
-    """
-    Sample builder is used to build complex samples from set of parameters.
-    Given builder produces the sample representing spheres at hex lattice
-    using two parameters as an input:
-    radius - radius of spheres
-    lattice_constant - hexagonal lattice constant
-    """
-    def __init__(self):
-        ba.IMultiLayerBuilder.__init__(self)
-        self.sample = None
-        # parameters describing the sample
-        self.radius = ctypes.c_double(5.0*nm)
-        self.lattice_constant = ctypes.c_double(10.0*nm)
-        # register parameters
-        self.registerParameter("radius", ctypes.addressof(self.radius))
-        self.registerParameter("lattice_constant",
-                               ctypes.addressof(self.lattice_constant))
-
-    # constructs the sample for current values of parameters
-    def buildSample(self):
-        m_air = ba.HomogeneousMaterial("Air", 0.0, 0.0)
-        m_substrate = ba.HomogeneousMaterial("Substrate", 6e-6, 2e-8)
-        m_particle = ba.HomogeneousMaterial("Particle", 6e-4, 2e-8)
-
-        sphere_ff = ba.FormFactorFullSphere(self.radius.value)
-        sphere = ba.Particle(m_particle, sphere_ff)
-        particle_layout = ba.ParticleLayout()
-        particle_layout.addParticle(sphere)
-
-        interference = ba.InterferenceFunction2DLattice.createHexagonal(
-            self.lattice_constant.value)
-        pdf = ba.FTDecayFunction2DCauchy(10*nm, 10*nm)
-        interference.setDecayFunction(pdf)
-
-        particle_layout.setInterferenceFunction(interference)
-
-        air_layer = ba.Layer(m_air)
-        air_layer.addLayout(particle_layout)
-        substrate_layer = ba.Layer(m_substrate, 0)
-        multi_layer = ba.MultiLayer()
-        multi_layer.addLayer(air_layer)
-        multi_layer.addLayer(substrate_layer)
-        return multi_layer
-
-
-def get_simulation():
-    """
-    Returns a GISAXS simulation with beam and detector defined.
-    """
-    simulation = ba.GISASSimulation()
-    simulation.setDetectorParameters(100, -1.0*deg, 1.0*deg,
-                                     100, 0.0*deg, 2.0*deg)
-    simulation.setBeamParameters(1.0*angstrom, 0.2*deg, 0.0*deg)
-    simulation.setBeamIntensity(1e+08)
-
-    return simulation
-
-
-def create_real_data():
-    """
-    Generating "real" data by adding noise to the simulated data.
-    """
-    sample_builder = MySampleBuilder()
-    sample_builder.setParameterValue("radius", 5.0*nm)
-    sample_builder.setParameterValue("lattice_constant", 10.0*nm)
-    simulation = get_simulation()
-    simulation.setSampleBuilder(sample_builder)
-    simulation.runSimulation()
-
-    # retrieving simulated data in the form of numpy array
-    real_data = simulation.result().array()
-
-    # spoiling simulated data with the noise to produce "real" data
-    # random seed made as in FitSPheresInHexLattice.py example
-    np.random.seed(0)
-    noise_factor = 0.1
-    noisy = np.random.normal(real_data, noise_factor*np.sqrt(real_data))
-    noisy[noisy < 0.1] = 0.1
-    return noisy
-
-
-def run_fitting():
-    """
-    main function to run fitting
-    """
-    simulation = get_simulation()
-    simulation.setSampleBuilder(MySampleBuilder())
-
-    real_data = create_real_data()
-
-    fit_suite = ba.FitSuite()
-    fit_suite.addSimulationAndRealData(simulation, real_data)
-    fit_suite.initPrint(10)
-
-    draw_observer = ba.DefaultFitObserver(draw_every_nth=10)
-    fit_suite.attachObserver(draw_observer)
-
-    # setting fitting parameters with starting values
-    fit_suite.addFitParameter("*radius", 8.*nm, ba.AttLimits.limited(4., 12.))
-    fit_suite.addFitParameter("*lattice_constant",
-                              8.*nm, ba.AttLimits.limited(4., 12.))
-
-    print(fit_suite.treeToString())
-    print(fit_suite.parametersToString())
-
-    # running fit
-    fit_suite.runFit()
-
-    print("Fitting completed.")
-    print("chi2:", fit_suite.getChi2())
-    for fitPar in fit_suite.fitParameters():
-        print(fitPar.name(), fitPar.value(), fitPar.error())
-
-
-if __name__ == '__main__':
-    run_fitting()
-    plt.show()
diff --git a/Examples/python/fitting/ex04_FitScaleAndShift/FitScaleAndShift.py b/Examples/python/fitting/ex04_FitScaleAndShift/FitScaleAndShift.py
deleted file mode 100644
index 03e9416e17515cc4fe49ad5daf6bfdd115b7012c..0000000000000000000000000000000000000000
--- a/Examples/python/fitting/ex04_FitScaleAndShift/FitScaleAndShift.py
+++ /dev/null
@@ -1,124 +0,0 @@
-"""
-Fitting example: looking for background and scale factors.
-
-Real data contains some "unknown" background and scale factors.
-In the fit we are trying to find cylinder radius and height,
-scale and background factors.
-"""
-
-import numpy as np
-from matplotlib import pyplot as plt
-import bornagain as ba
-from bornagain import deg, angstrom, nm
-
-
-def get_sample(radius=5.0*nm, height=10.0*nm):
-    """
-    Build the sample representing cylinders on top of substrate without interference.
-    """
-    m_air = ba.HomogeneousMaterial("Air", 0.0, 0.0)
-    m_substrate = ba.HomogeneousMaterial("Substrate", 6e-6, 2e-8)
-    m_particle = ba.HomogeneousMaterial("Particle", 6e-4, 2e-8)
-
-    cylinder_ff = ba.FormFactorCylinder(radius, height)
-    cylinder = ba.Particle(m_particle, cylinder_ff)
-
-    particle_layout = ba.ParticleLayout()
-    particle_layout.addParticle(cylinder)
-
-    air_layer = ba.Layer(m_air)
-    air_layer.addLayout(particle_layout)
-
-    substrate_layer = ba.Layer(m_substrate, 0)
-    multi_layer = ba.MultiLayer()
-    multi_layer.addLayer(air_layer)
-    multi_layer.addLayer(substrate_layer)
-    return multi_layer
-
-
-def get_simulation():
-    """
-    Create and return GISAXS simulation with beam and detector defined
-    """
-    simulation = ba.GISASSimulation()
-    simulation.setDetectorParameters(100, -1.0*deg, 1.0*deg,
-                                     100, 0.0*deg, 2.0*deg)
-    simulation.setBeamParameters(1.0*angstrom, 0.2*deg, 0.0*deg)
-    simulation.setBeamIntensity(1e12)
-    return simulation
-
-
-def create_real_data():
-    """
-    Generating "real" data by adding noise, background and scale
-    to the simulated data.
-    Cylinder radius is set to 5nm, cylinder height to 10nm.
-    During the fit we will try to find cylinder height and radius and
-    scale, background factors.
-    """
-    sample = get_sample(5.0*nm, 10.0*nm)
-    simulation = get_simulation()
-    simulation.setSample(sample)
-    simulation.runSimulation()
-
-    # retrieving simulated data in the form of numpy array
-    real_data = simulation.result().array()
-
-    scale = 2.0
-    background = 100
-
-    # spoiling simulated data with the noise to produce "real" data
-    real_data *= scale
-    noise_factor = 0.1
-    noisy = background + np.random.normal(real_data, noise_factor*np.sqrt(real_data))
-    return noisy
-
-
-def run_fitting():
-    """
-    main function to run fitting
-    """
-    simulation = get_simulation()
-    sample = get_sample()
-
-    simulation.setSample(sample)
-
-    real_data = create_real_data()
-
-    fit_suite = ba.FitSuite()
-    fit_suite.addSimulationAndRealData(simulation, real_data)
-
-    chiModule = ba.ChiSquaredModule()
-    chiModule.setIntensityNormalizer(ba.IntensityScaleAndShiftNormalizer())
-    fit_suite.setChiSquaredModule(chiModule)
-
-    fit_suite.initPrint(10)
-
-    draw_observer = ba.DefaultFitObserver(draw_every_nth=10)
-    fit_suite.attachObserver(draw_observer)
-
-    # print all defined parameters for sample and simulation
-    print(fit_suite.parametersToString())
-
-    # setting fitting parameters with starting values
-    fit_suite.addFitParameter("*/Cylinder/Radius", 6.*nm,
-                              ba.AttLimits.limited(4., 8.))
-    fit_suite.addFitParameter("*/Cylinder/Height", 9.*nm,
-                              ba.AttLimits.limited(8., 12.))
-    fit_suite.addFitParameter("*/Normalizer/scale", 1.5,
-                              ba.AttLimits.limited(1.0, 3.0))
-    fit_suite.addFitParameter("*/Normalizer/shift", 50.,
-                              ba.AttLimits.limited(1, 500.))
-
-    # running fit
-    fit_suite.runFit()
-
-    print("Fitting completed.")
-    print("chi2:", fit_suite.getChi2())
-    for fitPar in fit_suite.fitParameters():
-        print(fitPar.name(), fitPar.value(), fitPar.error())
-
-
-if __name__ == '__main__':
-    run_fitting()
-    plt.show()
diff --git a/Examples/python/fitting/ex05_FitWithMasks/FitWithMasks.py b/Examples/python/fitting/ex05_FitWithMasks/FitWithMasks.py
deleted file mode 100644
index d97f1dbe4cbf5feb86d16cdf75d31c26c27f46cb..0000000000000000000000000000000000000000
--- a/Examples/python/fitting/ex05_FitWithMasks/FitWithMasks.py
+++ /dev/null
@@ -1,151 +0,0 @@
-"""
-Fitting example: fit with masks
-"""
-
-import numpy as np
-from matplotlib import pyplot as plt
-import bornagain as ba
-from bornagain import deg, angstrom, nm
-
-
-def get_sample(radius=5.0*nm, height=10.0*nm):
-    """
-    Build the sample representing cylinders on top of
-    substrate without interference.
-    """
-    m_air = ba.HomogeneousMaterial("Air", 0.0, 0.0)
-    m_substrate = ba.HomogeneousMaterial("Substrate", 6e-6, 2e-8)
-    m_particle = ba.HomogeneousMaterial("Particle", 6e-4, 2e-8)
-
-    cylinder_ff = ba.FormFactorCylinder(radius, height)
-    cylinder = ba.Particle(m_particle, cylinder_ff)
-
-    particle_layout = ba.ParticleLayout()
-    particle_layout.addParticle(cylinder)
-
-    air_layer = ba.Layer(m_air)
-    air_layer.addLayout(particle_layout)
-
-    substrate_layer = ba.Layer(m_substrate, 0)
-    multi_layer = ba.MultiLayer()
-    multi_layer.addLayer(air_layer)
-    multi_layer.addLayer(substrate_layer)
-    return multi_layer
-
-
-def get_simulation():
-    """
-    Create and return GISAXS simulation with beam and detector defined
-    """
-    simulation = ba.GISASSimulation()
-    simulation.setDetectorParameters(100, -1.0*deg, 1.0*deg,
-                                     100, 0.0*deg, 2.0*deg)
-    simulation.setBeamParameters(1.0*angstrom, 0.2*deg, 0.0*deg)
-    simulation.setBeamIntensity(1e+08)
-    return simulation
-
-
-def create_real_data():
-    """
-    Generating "real" data by adding noise to the simulated data.
-    """
-    sample = get_sample(5.0*nm, 10.0*nm)
-    simulation = get_simulation()
-    simulation.setSample(sample)
-    simulation.runSimulation()
-
-    # retrieving simulated data in the form of numpy array
-    real_data = simulation.result().array()
-
-    # spoiling simulated data with the noise to produce "real" data
-    noise_factor = 0.1
-    noisy = np.random.normal(real_data, noise_factor*np.sqrt(real_data))
-    noisy[noisy < 0.1] = 0.1
-    return noisy
-
-
-def add_mask_to_simulation(simulation):
-    """
-    Here we demonstrate how to add masks to the simulation.
-    Only unmasked areas will be simulated and then used during the fit.
-
-    Masks can have different geometrical shapes (ba.Rectangle, ba.Ellipse, Line)
-    with the mask value either "True" (detector bin is excluded from the simulation)
-    or False (will be simulated).
-
-    Every subsequent mask override previously defined masks in this area.
-
-    In the code below we put masks in such way that simulated image will look like
-    a Pac-Man from ancient arcade game.
-    """
-    # mask all detector (put mask=True to all detector channels)
-    simulation.maskAll()
-
-    # set mask to simulate pacman's head
-    simulation.addMask(
-        ba.Ellipse(0.0*deg, 1.0*deg, 0.5*deg, 0.5*deg), False)
-
-    # set mask for pacman's eye
-    simulation.addMask(
-        ba.Ellipse(0.11*deg, 1.25*deg, 0.05*deg, 0.05*deg), True)
-
-    # set mask for pacman's mouth
-    points = [[0.0*deg, 1.0*deg], [0.5*deg, 1.2*deg],
-              [0.5*deg, 0.8*deg], [0.0*deg, 1.0*deg]]
-    simulation.addMask(ba.Polygon(points), True)
-
-    # giving pacman something to eat
-    simulation.addMask(
-        ba.Rectangle(0.45*deg, 0.95*deg, 0.55*deg, 1.05*deg), False)
-    simulation.addMask(
-        ba.Rectangle(0.61*deg, 0.95*deg, 0.71*deg, 1.05*deg), False)
-    simulation.addMask(
-        ba.Rectangle(0.75*deg, 0.95*deg, 0.85*deg, 1.05*deg), False)
-
-    # other mask's shapes are possible too
-    # simulation.removeMasks()
-    # # rotated ellipse:
-    # simulation.addMask(ba.Ellipse(0.11*deg, 1.25*deg,
-    #                    1.0*deg, 0.5*deg, 45.0*deg), True)
-    # simulation.addMask(Line(-1.0*deg, 0.0*deg, 1.0*deg, 2.0*deg), True)
-    # simulation.addMask(ba.HorizontalLine(1.0*deg), False)
-    # simulation.addMask(ba.VerticalLine(0.0*deg), False)
-
-
-def run_fitting():
-    """
-    main function to run fitting
-    """
-    simulation = get_simulation()
-    sample = get_sample()
-    simulation.setSample(sample)
-
-    # the core method of this example which adds masks to the simulation
-    add_mask_to_simulation(simulation)
-
-    real_data = create_real_data()
-
-    fit_suite = ba.FitSuite()
-    fit_suite.addSimulationAndRealData(simulation, real_data)
-    fit_suite.initPrint(10)
-    draw_observer = ba.DefaultFitObserver(draw_every_nth=10)
-    fit_suite.attachObserver(draw_observer)
-
-    # setting fitting parameters with starting values
-    fit_suite.addFitParameter("*/Cylinder/Radius", 6.*nm).setLimited(4., 8.)
-    fit_suite.addFitParameter("*/Cylinder/Height", 9.*nm).setLimited(8., 12.)
-
-    # running fit
-    fit_suite.runFit()
-
-    print("Fitting completed.")
-    fit_suite.printResults()
-    print("chi2:", fit_suite.getChi2())
-    print("chi2:", fit_suite.getChi2())
-    for fitPar in fit_suite.fitParameters():
-        print(fitPar.name(), fitPar.value(), fitPar.error())
-
-
-if __name__ == '__main__':
-    run_fitting()
-    plt.show()
diff --git a/Examples/python/fitting/ex06_FitStrategies/FitStrategyAdjustMinimizer.py b/Examples/python/fitting/ex06_FitStrategies/FitStrategyAdjustMinimizer.py
deleted file mode 100644
index d4cd0f43fc48f955d0603ac988e0a263ef07cc8c..0000000000000000000000000000000000000000
--- a/Examples/python/fitting/ex06_FitStrategies/FitStrategyAdjustMinimizer.py
+++ /dev/null
@@ -1,123 +0,0 @@
-"""
-Two parameter fit of cylinders.
-In this example we are trying to find cylinder's height and radius
-using chain of minimizers.
-
-During the first fit round Genetic minimizer will be used.
-It will roughly look for possible local minimas.
-After it is done, the second Minuit2 minimizer will continue
-to find the precise location of best minima found on previous step.
-"""
-
-import numpy as np
-from matplotlib import pyplot as plt
-import bornagain as ba
-from bornagain import deg, angstrom, nm
-
-
-def get_sample(radius=5.0*nm, height=5.0*nm):
-    """
-    Returns a sample with uncorrelated cylinders and pyramids on a substrate.
-    """
-    m_air = ba.HomogeneousMaterial("Air", 0.0, 0.0)
-    m_substrate = ba.HomogeneousMaterial("Substrate", 6e-6, 2e-8)
-    m_particle = ba.HomogeneousMaterial("Particle", 6e-4, 2e-8)
-
-    cylinder_ff = ba.FormFactorCylinder(radius, height)
-    cylinder = ba.Particle(m_particle, cylinder_ff)
-
-    particle_layout = ba.ParticleLayout()
-    particle_layout.addParticle(cylinder)
-
-    air_layer = ba.Layer(m_air)
-    air_layer.addLayout(particle_layout)
-
-    substrate_layer = ba.Layer(m_substrate, 0)
-    multi_layer = ba.MultiLayer()
-    multi_layer.addLayer(air_layer)
-    multi_layer.addLayer(substrate_layer)
-    return multi_layer
-
-
-def get_simulation():
-    """
-    Returns a GISAXS simulation with beam and detector defined.
-    """
-    simulation = ba.GISASSimulation()
-    simulation.setDetectorParameters(100, 0.0*deg, 2.0*deg,
-                                     100, 0.0*deg, 2.0*deg)
-    simulation.setBeamParameters(1.0*angstrom, 0.2*deg, 0.0*deg)
-    simulation.setBeamIntensity(1e+08)
-    return simulation
-
-
-def create_real_data():
-    """
-    Generating "real" data by adding noise to the simulated data.
-    """
-    sample = get_sample(5.0*nm, 5.0*nm)
-    simulation = get_simulation()
-    simulation.setSample(sample)
-    simulation.runSimulation()
-
-    # retrieving simulated data in the form of numpy array
-    real_data = simulation.result().array()
-
-    # spoiling simulated data with the noise to produce "real" data
-    noise_factor = 0.1
-    noisy = np.random.normal(real_data, noise_factor*np.sqrt(real_data))
-    noisy[noisy < 0.1] = 0.1
-    return noisy
-
-
-def run_fitting():
-    """
-    main function to run fitting
-    """
-    simulation = get_simulation()
-    sample = get_sample()
-    simulation.setSample(sample)
-
-    real_data = create_real_data()
-
-    fit_suite = ba.FitSuite()
-    fit_suite.addSimulationAndRealData(simulation, real_data)
-    fit_suite.initPrint(10)
-
-    draw_observer = ba.DefaultFitObserver(draw_every_nth=10)
-    fit_suite.attachObserver(draw_observer)
-
-    # setting fitting parameters with starting values
-    # Here we select starting values being quite far from true values
-    # to puzzle our minimizer's as much as possible
-    fit_suite.addFitParameter("*Height", 1.*nm).setLimited(0.01, 30.)\
-        .setStep(0.05*nm)
-    fit_suite.addFitParameter("*Radius", 20.*nm).setLimited(0.01, 30.)\
-        .setStep(0.05*nm)
-
-    # Now we create first fig strategy which will run first minimization round
-    # using the Genetic minimizer.
-    # The Genetic minimizer is able to explore large parameter space
-    # without being trapped by some local minima.
-    strategy1 = ba.AdjustMinimizerStrategy("Genetic", "",
-                                           "MaxIterations=2;RandomSeed=1")
-    fit_suite.addFitStrategy(strategy1)
-
-    # Second fit strategy will use another minimizer.
-    # It starts from best parameters found in previous minimization
-    # and then continues until fit converges.
-    strategy2 = ba.AdjustMinimizerStrategy("Minuit2", "Migrad")
-    fit_suite.addFitStrategy(strategy2)
-
-    # running fit
-    fit_suite.runFit()
-
-    print("Fitting completed.")
-    print("chi2:", fit_suite.getChi2())
-    for fitPar in fit_suite.fitParameters():
-        print(fitPar.name(), fitPar.value(), fitPar.error())
-
-
-if __name__ == '__main__':
-    run_fitting()
-    plt.show()
diff --git a/Examples/python/fitting/ex07_FitAlongSlices/FitAlongSlices.py b/Examples/python/fitting/ex07_FitAlongSlices/FitAlongSlices.py
deleted file mode 100644
index b473d43d013961058160901fb55a1b9bff0e8e9a..0000000000000000000000000000000000000000
--- a/Examples/python/fitting/ex07_FitAlongSlices/FitAlongSlices.py
+++ /dev/null
@@ -1,195 +0,0 @@
-"""
-Fitting example: fit along slices
-"""
-
-import numpy as np
-import matplotlib
-from matplotlib import pyplot as plt
-import bornagain as ba
-from bornagain import deg, angstrom, nm
-
-phi_slice_value = 0.0  # position of vertical slice in deg
-alpha_slice_value = 0.2  # position of horizontal slice in deg
-
-
-def get_sample(radius=5.0*nm, height=10.0*nm):
-    """
-    Returns a sample with uncorrelated cylinders on a substrate.
-    """
-    m_air = ba.HomogeneousMaterial("Air", 0.0, 0.0)
-    m_substrate = ba.HomogeneousMaterial("Substrate", 6e-6, 2e-8)
-    m_particle = ba.HomogeneousMaterial("Particle", 6e-4, 2e-8)
-
-    cylinder_ff = ba.FormFactorCylinder(radius, height)
-    cylinder = ba.Particle(m_particle, cylinder_ff)
-
-    particle_layout = ba.ParticleLayout()
-    particle_layout.addParticle(cylinder)
-
-    air_layer = ba.Layer(m_air)
-    air_layer.addLayout(particle_layout)
-
-    substrate_layer = ba.Layer(m_substrate, 0)
-    multi_layer = ba.MultiLayer()
-    multi_layer.addLayer(air_layer)
-    multi_layer.addLayer(substrate_layer)
-    return multi_layer
-
-
-def get_simulation():
-    """
-    Create and return GISAXS simulation with beam and detector defined
-    """
-    simulation = ba.GISASSimulation()
-    simulation.setDetectorParameters(100, -1.0*deg, 1.0*deg,
-                                     100, 0.0*deg, 2.0*deg)
-    simulation.setBeamParameters(1.0*angstrom, 0.2*deg, 0.0*deg)
-    simulation.setBeamIntensity(1e+08)
-    return simulation
-
-
-def create_real_data():
-    """
-    Generating "real" data by adding noise to the simulated data.
-    """
-    sample = get_sample(5.0*nm, 10.0*nm)
-    simulation = get_simulation()
-    simulation.setSample(sample)
-    simulation.runSimulation()
-
-    # retrieving simulated data in the form of numpy array
-    real_data = simulation.result().array()
-
-    # spoiling simulated data with the noise to produce "real" data
-    noise_factor = 0.1
-    noisy = np.random.normal(real_data, noise_factor*np.sqrt(real_data))
-    noisy[noisy < 0.1] = 0.1
-    return noisy
-
-
-class DrawObserver(ba.IFitObserver):
-    """
-    Draws fit progress every nth iteration. Here we plot slices along real
-    and simulated images to see fit progress.
-    """
-
-    def __init__(self, draw_every_nth=10):
-        ba.IFitObserver.__init__(self, draw_every_nth)
-        self.fig = plt.figure(figsize=(10.25, 7.69))
-        self.fig.canvas.draw()
-        plt.ion()
-
-    def plot_real_data(self, data, nplot):
-        plt.subplot(2, 2, nplot)
-        plt.subplots_adjust(wspace=0.2, hspace=0.2)
-        ba.plot_histogram(data, title="Experimental data")
-        # line representing vertical slice
-        plt.plot([phi_slice_value, phi_slice_value],
-                 [data.getYmin(), data.getYmax()],
-                 color='gray', linestyle='-', linewidth=1)
-        # line representing horizontal slice
-        plt.plot([data.getXmin(), data.getXmax()],
-                 [alpha_slice_value, alpha_slice_value],
-                 color='gray', linestyle='-', linewidth=1)
-
-    def plot_slices(self, slices, title, nplot):
-        plt.subplot(2, 2, nplot)
-        plt.subplots_adjust(wspace=0.2, hspace=0.3)
-        for label, slice in slices:
-            plt.semilogy(slice.getBinCenters(),
-                         slice.getBinValues(), label=label)
-            plt.xlim(slice.getXmin(), slice.getXmax())
-            plt.ylim(1.0, slice.getMaximum()*10.0)
-        plt.legend(loc='upper right')
-        plt.title(title)
-
-    def display_fit_parameters(self, fit_suite, nplot):
-        plt.subplot(2, 2, nplot)
-        plt.title('Parameters')
-        plt.axis('off')
-        plt.text(0.01, 0.85, "Iteration  " + '{:d}     {:s}'.
-                 format(fit_suite.numberOfIterations(),
-                        fit_suite.minimizerName()))
-        plt.text(0.01, 0.75, "Chi2       " + '{:8.4f}'.format(fit_suite.getChi2()))
-        for index, fitPar in enumerate(fit_suite.fitParameters()):
-            plt.text(0.01, 0.55 - index*0.1,
-                     '{:30.30s}: {:6.3f}'.format(fitPar.name(), fitPar.value()))
-
-        plt.tight_layout()
-        plt.draw()
-        plt.pause(0.01)
-
-    def update(self, fit_suite):
-        self.fig.clf()
-
-        real_data = fit_suite.experimentalData().histogram2d()
-        simul_data = fit_suite.simulationResult().histogram2d()
-
-        # plot real data
-        self.plot_real_data(real_data, nplot=1)
-
-        # horizontal slices
-        slices =[
-            ("real", real_data.projectionX(alpha_slice_value)),
-            ("simul", simul_data.projectionX(alpha_slice_value))
-            ]
-        title = ( "Horizontal slice at alpha =" +
-                  '{:3.1f}'.format(alpha_slice_value) )
-        self.plot_slices(slices, title, nplot=2)
-
-        # vertical slices
-        slices =[
-            ("real", real_data.projectionY(phi_slice_value)),
-            ("simul", simul_data.projectionY(phi_slice_value))
-            ]
-        title = "Vertical slice at phi =" + '{:3.1f}'.format(phi_slice_value)
-        self.plot_slices(slices, title, nplot=3)
-
-        # display fit parameters
-        self.display_fit_parameters(fit_suite, nplot=4)
-
-        if fit_suite.isLastIteration():
-            plt.ioff()
-
-
-def run_fitting():
-    """
-    main function to run fitting
-    """
-
-    real_data = create_real_data()
-
-    sample = get_sample()
-    simulation = get_simulation()
-    simulation.setSample(sample)
-
-    # At this point we mask all the detector and then unmask two areas
-    # corresponding to the vertical and horizontal lines. This will make
-    # simulation/fitting to be performed along slices only.
-    simulation.maskAll()
-    simulation.addMask(ba.HorizontalLine(alpha_slice_value*deg), False)
-    simulation.addMask(ba.VerticalLine(phi_slice_value*deg), False)
-
-    fit_suite = ba.FitSuite()
-    fit_suite.addSimulationAndRealData(simulation, real_data)
-    fit_suite.initPrint(5)
-
-    draw_observer = DrawObserver(draw_every_nth=5)
-    fit_suite.attachObserver(draw_observer)
-
-    # setting fitting parameters with starting values
-    fit_suite.addFitParameter("*/Cylinder/Radius", 6.*nm).setLimited(4., 8.)
-    fit_suite.addFitParameter("*/Cylinder/Height", 9.*nm).setLimited(8., 12.)
-
-    # running fit
-    fit_suite.runFit()
-
-    print("Fitting completed.")
-    print("chi2:", fit_suite.getChi2())
-    for fitPar in fit_suite.fitParameters():
-        print(fitPar.name(), fitPar.value(), fitPar.error())
-
-
-if __name__ == '__main__':
-    run_fitting()
-    plt.show()
diff --git a/Examples/python/fitting/ex08_SimultaneousFitOfTwoDatasets/SimultaneousFitOfTwoDatasets.py b/Examples/python/fitting/ex08_SimultaneousFitOfTwoDatasets/SimultaneousFitOfTwoDatasets.py
deleted file mode 100644
index b197d0eab50a95e103b76e5bc8dcea83f19c82db..0000000000000000000000000000000000000000
--- a/Examples/python/fitting/ex08_SimultaneousFitOfTwoDatasets/SimultaneousFitOfTwoDatasets.py
+++ /dev/null
@@ -1,169 +0,0 @@
-"""
-Fitting example: demonstrates how to fit two datasets simultaneously.
-"""
-
-import numpy as np
-import matplotlib
-from matplotlib import pyplot as plt
-import bornagain as ba
-from bornagain import deg, angstrom, nm
-
-
-def get_sample(radius_a=4.0*nm, radius_b=4.0*nm, height=4.0*nm):
-    """
-    Returns a sample with uncorrelated cylinders and pyramids.
-    """
-    m_air = ba.HomogeneousMaterial("Air", 0.0, 0.0)
-    m_substrate = ba.HomogeneousMaterial("Substrate", 6e-6, 2e-8)
-    m_particle = ba.HomogeneousMaterial("Particle", 6e-4, 2e-8)
-
-    formFactor = ba.FormFactorHemiEllipsoid(radius_a, radius_b, height)
-    hemiEllipsoid = ba.Particle(m_particle, formFactor)
-
-    particle_layout = ba.ParticleLayout()
-    particle_layout.addParticle(hemiEllipsoid)
-
-    air_layer = ba.Layer(m_air)
-    air_layer.addLayout(particle_layout)
-
-    substrate_layer = ba.Layer(m_substrate, 0)
-    multi_layer = ba.MultiLayer()
-    multi_layer.addLayer(air_layer)
-    multi_layer.addLayer(substrate_layer)
-    return multi_layer
-
-
-def get_simulation(incident_alpha=0.2):
-    """
-    Returns a GISAXS simulation with beam and detector defined.
-    """
-    simulation = ba.GISASSimulation()
-    simulation.setDetectorParameters(50, -1.5*deg, 1.5*deg,
-                                     50, 0.0*deg, 2.0*deg)
-    simulation.setBeamParameters(1.0*angstrom, incident_alpha, 0.0*deg)
-    simulation.setBeamIntensity(1e+08)
-    return simulation
-
-
-def create_real_data(incident_alpha):
-    """
-    Generating "real" data by adding noise to the simulated data.
-    """
-    sample = get_sample(
-        radius_a=5.0*nm, radius_b=6.0*nm, height=8.0*nm)
-    simulation = get_simulation(incident_alpha)
-    simulation.setSample(sample)
-    simulation.runSimulation()
-
-    # retrieving simulated data in the form of numpy array
-    real_data = simulation.result().array()
-
-    # spoiling simulated data with the noise to produce "real" data
-    noise_factor = 0.1
-    noisy = np.random.normal(real_data, noise_factor*np.sqrt(real_data))
-    noisy[noisy < 0.1] = 0.1
-    return noisy
-
-
-class DrawObserver(ba.IFitObserver):
-    """
-    Draws fit progress every nth iteration. Real data, simulated data
-    and chi2 map will be shown for both datasets.
-    """
-    def __init__(self, draw_every_nth=10):
-        import matplotlib
-        from matplotlib import pyplot as plt
-        global matplotlib, plt
-
-        ba.IFitObserver.__init__(self, draw_every_nth)
-        self.fig = plt.figure(figsize=(12.8, 10.24))
-        self.fig.canvas.draw()
-        plt.ion()
-
-    def plot_datasets(self, fit_suite, canvas):
-        for i_dataset in range(0, fit_suite.numberOfFitObjects()):
-            real_data = fit_suite.experimentalData(i_dataset)
-            simul_data = fit_suite.simulationResult(i_dataset)
-            chi2_map = fit_suite.relativeDifference(i_dataset)
-
-            zmax = real_data.histogram2d().getMaximum()
-
-            plt.subplot(canvas[i_dataset*3])
-            ba.plot_colormap(real_data, title="\"Real\" data - #"+str(i_dataset+1),
-                               zmin=1.0, zmax=zmax, zlabel="")
-            plt.subplot(canvas[1+i_dataset*3])
-            ba.plot_colormap(simul_data, title="Simulated data - #"+str(i_dataset+1),
-                               zmin=1.0, zmax=zmax, zlabel="")
-            plt.subplot(canvas[2+i_dataset*3])
-            ba.plot_colormap(chi2_map, title="Chi2 map - #"+str(i_dataset+1),
-                               zmin=0.001, zmax=10.0, zlabel="")
-
-    def plot_fit_parameters(self, fit_suite, canvas):
-        # fit parameters
-        plt.subplot(canvas[6:])
-        plt.axis('off')
-        plt.text(0.01, 0.95, "Iterations  " + '{:d}   '.
-                 format(fit_suite.numberOfIterations()))
-        plt.text(0.01, 0.70, "Chi2       " + '{:8.4f}'.format(fit_suite.getChi2()))
-        for index, fitPar in enumerate(fit_suite.fitParameters()):
-            plt.text(0.01, 0.30 - index*0.3,
-                     '{:40.40s}: {:6.3f}'.format(fitPar.name(), fitPar.value()))
-
-    def update(self, fit_suite):
-        self.fig.clf()
-
-        # we divide figure to have 3x3 subplots, with two first rows occupying
-        # most of the space
-        canvas = matplotlib.gridspec.GridSpec(
-            3, 3, width_ratios=[1, 1, 1], height_ratios=[4, 4, 1])
-        canvas.update(left=0.05, right=0.95, hspace=0.5, wspace=0.2)
-
-        self.plot_datasets(fit_suite, canvas)
-        self.plot_fit_parameters(fit_suite, canvas)
-
-        plt.draw()
-        plt.pause(0.01)
-
-        if fit_suite.isLastIteration():
-            plt.ioff()
-
-
-def run_fitting():
-    """
-    main function to run fitting
-    """
-
-    incident_alpha_angles = [0.1*deg, 0.4*deg]
-    fit_suite = ba.FitSuite()
-    sample = get_sample()
-
-    for alpha in incident_alpha_angles:
-        real_data = create_real_data(incident_alpha=alpha)
-        simulation = get_simulation(incident_alpha=alpha)
-        simulation.setSample(sample)
-        fit_suite.addSimulationAndRealData(simulation, real_data)
-
-    fit_suite.initPrint(10)
-    draw_observer = DrawObserver(draw_every_nth=10)
-    fit_suite.attachObserver(draw_observer)
-
-    # setting fitting parameters with starting values
-    fit_suite.addFitParameter("*/HemiEllipsoid/RadiusX", 4.*nm).setLimited(2., 10.)
-    fit_suite.addFitParameter("*/HemiEllipsoid/RadiusY", 6.*nm).setFixed()
-    fit_suite.addFitParameter("*/HemiEllipsoid/Height", 4.*nm).setLimited(2., 10.)
-
-    print(fit_suite.treeToString())
-    print(fit_suite.parametersToString())
-
-    # running fit
-    fit_suite.runFit()
-
-    print("Fitting completed.")
-    print("chi2:", fit_suite.getChi2())
-    for fitPar in fit_suite.fitParameters():
-        print(fitPar.name(), fitPar.value(), fitPar.error())
-
-
-if __name__ == '__main__':
-    run_fitting()
-    plt.show()
diff --git a/Examples/python/fitting/ex10_FitGALAXIData/FitGALAXIData.py b/Examples/python/fitting/ex10_FitGALAXIData/FitGALAXIData.py
deleted file mode 100644
index a9d158af52deb5eb00275a4dfe18b984e032268e..0000000000000000000000000000000000000000
--- a/Examples/python/fitting/ex10_FitGALAXIData/FitGALAXIData.py
+++ /dev/null
@@ -1,101 +0,0 @@
-"""
-Real life example: experiment at GALAXY
-"""
-import matplotlib
-from matplotlib import pyplot as plt
-import numpy
-import bornagain as ba
-from SampleBuilder import MySampleBuilder
-
-wavelength = 1.34*ba.angstrom
-alpha_i = 0.463*ba.deg
-
-# detector setup as given from instrument responsible
-pilatus_npx, pilatus_npy = 981, 1043
-pilatus_pixel_size = 0.172  # in mm
-detector_distance = 1730.0  # in mm
-beam_xpos, beam_ypos = 597.1, 323.4  # in pixels
-
-
-def create_detector():
-    """
-    Returns a model of the GALAXY detector
-    """
-    u0 = beam_xpos*pilatus_pixel_size  # in mm
-    v0 = beam_ypos*pilatus_pixel_size  # in mm
-    detector = ba.RectangularDetector(pilatus_npx, pilatus_npx*pilatus_pixel_size,
-                                      pilatus_npy, pilatus_npy*pilatus_pixel_size)
-    detector.setPerpendicularToDirectBeam(detector_distance, u0, v0)
-    return detector
-
-
-def create_simulation():
-    """
-    Creates and returns GISAS simulation with beam and detector defined
-    """
-    simulation = ba.GISASSimulation()
-    simulation.setDetector(create_detector())
-    simulation.setBeamParameters(wavelength, alpha_i, 0.0)
-    simulation.setBeamIntensity(1.2e7)
-    simulation.setRegionOfInterest(85.0, 70.0, 120.0, 92.)
-    # mask on reflected beam
-    simulation.addMask(ba.Rectangle(101.9, 82.1, 103.7, 85.2), True)
-    # detector resolution function
-    # simulation.setDetectorResolutionFunction(
-    #   ba.ResolutionFunction2DGaussian(0.5*pilatus_pixel_size,
-    #      0.5*pilatus_pixel_size))
-    # beam divergence
-    # alpha_distr = ba.DistributionGaussian(alpha_i, 0.02*ba.deg)
-    # simulation.addParameterDistribution("*/Beam/Alpha", alpha_distr, 5)
-    return simulation
-
-
-def load_real_data(filename="galaxi_data.tif.gz"):
-    """
-    Fill histogram representing our detector with intensity data from tif file.
-    Returns cropped version of it, which represent the area we are interested in.
-    """
-    hist = ba.IHistogram.createFrom(filename)
-    return hist
-
-
-def run_fitting():
-    simulation = create_simulation()
-    sample_builder = MySampleBuilder()
-    simulation.setSampleBuilder(sample_builder)
-
-    real_data = load_real_data()
-
-    fit_suite = ba.FitSuite()
-    draw_observer = ba.DefaultFitObserver(draw_every_nth=10)
-    fit_suite.attachObserver(draw_observer)
-    fit_suite.initPrint(10)
-    fit_suite.addSimulationAndRealData(simulation, real_data)
-
-    # setting fitting parameters with starting values
-    fit_suite.addFitParameter(
-        "*radius", 5.0*ba.nm, ba.AttLimits.limited(4.0, 6.0),
-        0.1*ba.nm)
-    fit_suite.addFitParameter(
-        "*sigma", 0.55, ba.AttLimits.limited(0.2, 0.8), 0.01*ba.nm)
-    fit_suite.addFitParameter(
-        "*distance", 27.*ba.nm, ba.AttLimits.limited(20, 70),
-        0.1*ba.nm)
-
-    use_two_minimizers_strategy = False
-    if use_two_minimizers_strategy:
-        strategy1 = ba.AdjustMinimizerStrategy("Genetic")
-        fit_suite.addFitStrategy(strategy1)
-
-        # Second fit strategy will use another algorithm.
-        # It will use best parameters found from previous minimization round.
-        strategy2 = ba.AdjustMinimizerStrategy("Minuit2", "Migrad")
-        fit_suite.addFitStrategy(strategy2)
-
-    # running fit
-    fit_suite.runFit()
-
-    plt.show()
-
-if __name__ == '__main__':
-    run_fitting()
diff --git a/Examples/python/fitting/ex10_FitGALAXIData/SampleBuilder.py b/Examples/python/fitting/ex10_FitGALAXIData/SampleBuilder.py
deleted file mode 100644
index 4561e114cb4ad1245f096b13a20c3e26da34d234..0000000000000000000000000000000000000000
--- a/Examples/python/fitting/ex10_FitGALAXIData/SampleBuilder.py
+++ /dev/null
@@ -1,97 +0,0 @@
-"""
-3 layers system (substrate, teflon, air).
-Air layer is populated with spheres with some size distribution.
-"""
-import bornagain as ba
-import ctypes
-
-
-class MySampleBuilder(ba.IMultiLayerBuilder):
-    """
-
-    """
-    def __init__(self):
-        ba.IMultiLayerBuilder.__init__(self)
-        self.sample = None
-
-        # parameters describing the sample
-        self.radius = ctypes.c_double(5.75*ba.nm)
-        self.sigma = ctypes.c_double(0.4)
-        self.distance = ctypes.c_double(53.6*ba.nm)
-        self.disorder = ctypes.c_double(10.5*ba.nm)
-        self.kappa = ctypes.c_double(17.5)
-        self.ptfe_thickness = ctypes.c_double(22.1*ba.nm)
-        self.hmdso_thickness = ctypes.c_double(18.5*ba.nm)
-
-        # register parameters
-        self.registerParameter("radius", ctypes.addressof(self.radius))
-        self.registerParameter("sigma", ctypes.addressof(self.sigma))
-        self.registerParameter("distance", ctypes.addressof(self.distance))
-        self.registerParameter("disorder", ctypes.addressof(self.disorder))
-        self.registerParameter("kappa", ctypes.addressof(self.kappa))
-        self.registerParameter("tptfe", ctypes.addressof(self.ptfe_thickness))
-        self.registerParameter("thmdso", ctypes.addressof(self.hmdso_thickness))
-
-    # constructs the sample for current values of parameters
-    def buildSample(self):
-        # defining materials
-        m_air = ba.HomogeneousMaterial("Air", 0.0, 0.0)
-        m_Si = ba.HomogeneousMaterial("Si", 5.78164736e-6, 1.02294578e-7)
-        m_Ag = ba.HomogeneousMaterial("Ag", 2.24749529E-5, 1.61528396E-6)
-        m_PTFE = ba.HomogeneousMaterial("PTFE", 5.20508729E-6, 1.96944292E-8)
-        m_HMDSO = ba.HomogeneousMaterial("HMDSO", 2.0888308E-6, 1.32605651E-8)
-
-        # collection of particles with size distribution
-        nparticles = 20
-        nfwhm = 2.0
-        sphere_ff = ba.FormFactorFullSphere(self.radius.value)
-        # sphere_ff = ba.FormFactorTruncatedSphere(
-        #    self.radius.value, self.radius.value*1.5)
-
-        sphere = ba.Particle(m_Ag, sphere_ff)
-        position = ba.kvector_t(0*ba.nm, 0*ba.nm,
-                                -1.0*self.hmdso_thickness.value)
-        sphere.setPosition(position)
-        ln_distr = ba.DistributionLogNormal(self.radius.value, self.sigma.value)
-        par_distr = ba.ParameterDistribution(
-            "/Particle/FullSphere/Radius", ln_distr, nparticles, nfwhm,
-            ba.RealLimits.limited(0.0, self.hmdso_thickness.value/2.0))
-        # par_distr = ba.ParameterDistribution(
-        #    "/Particle/TruncatedSphere/Radius", ln_distr, nparticles, nfwhm)
-        # par_distr.linkParameter("/Particle/TruncatedSphere/Height")
-        part_coll = ba.ParticleDistribution(sphere, par_distr)
-
-        # interference function
-        interference = ba.InterferenceFunctionRadialParaCrystal(
-            self.distance.value, 1e6*ba.nm)
-        interference.setKappa(self.kappa.value)
-        interference.setDomainSize(20000.0)
-        pdf = ba.FTDistribution1DGauss(self.disorder.value)
-        interference.setProbabilityDistribution(pdf)
-
-        # assembling particle layout
-        particle_layout = ba.ParticleLayout()
-        particle_layout.addParticle(part_coll, 1.0)
-        particle_layout.setInterferenceFunction(interference)
-        particle_layout.setApproximation(ba.ILayout.SSCA)
-        particle_layout.setTotalParticleSurfaceDensity(1)
-
-        # roughness
-        r_ptfe = ba.LayerRoughness(2.3*ba.nm, 0.3, 5.0*ba.nm)
-        r_hmdso = ba.LayerRoughness(1.1*ba.nm, 0.3, 5.0*ba.nm)
-
-        # layers
-        air_layer = ba.Layer(m_air)
-        hmdso_layer = ba.Layer(m_HMDSO, self.hmdso_thickness.value)
-        hmdso_layer.addLayout(particle_layout)
-        ptfe_layer = ba.Layer(m_PTFE, self.ptfe_thickness.value)
-        substrate_layer = ba.Layer(m_Si)
-
-        # assembling multilayer
-        multi_layer = ba.MultiLayer()
-        multi_layer.addLayer(air_layer)
-        multi_layer.addLayerWithTopRoughness(hmdso_layer, r_hmdso)
-        multi_layer.addLayerWithTopRoughness(ptfe_layer, r_ptfe)
-        multi_layer.addLayer(substrate_layer)
-
-        return multi_layer
diff --git a/Examples/python/fitting/ex11_ExternalMinimizer/fit_objects.py b/Examples/python/fitting/ex11_ExternalMinimizer/fit_objects.py
deleted file mode 100644
index 3dfbadefc188de6af1750852cacf6cd6b45b3318..0000000000000000000000000000000000000000
--- a/Examples/python/fitting/ex11_ExternalMinimizer/fit_objects.py
+++ /dev/null
@@ -1,38 +0,0 @@
-"""
-Prototype of new FitObject
-"""
-import bornagain as ba
-import numpy as np
-
-
-class FitObject:
-    def __init__(self):
-        self.m_simulation_builder = None
-        self.m_experimental_data = None
-        self.m_fit_object = None
-        pass
-
-    def set_data(self, simulation_builder, real_data):
-        self.m_simulation_builder = simulation_builder
-        self.m_experimental_data = real_data
-
-    def evaluate(self, params):
-        simulation = self.m_simulation_builder.build_simulation(params)
-
-        self.m_fit_object = ba.FitObject(simulation, self.m_experimental_data)
-        self.m_fit_object.runSimulation()
-
-        result = np.asarray(self.m_fit_object.simulation_array())
-        exp = np.asarray(self.m_fit_object.experimental_array())
-
-        res = result-exp
-        return res
-
-    def simulationResult(self):
-        return self.m_fit_object.simulationResult()
-
-    def experimentalData(self):
-        return self.m_fit_object.experimentalData()
-
-    def relativeDifference(self):
-        return self.m_fit_object.relativeDifference()
\ No newline at end of file
diff --git a/Examples/python/fitting/ex11_ExternalMinimizer/fit_with_builder.py b/Examples/python/fitting/ex11_ExternalMinimizer/fit_with_builder.py
deleted file mode 100644
index ea4d6b80eb34533fa820118f09a3c7f40e7f0168..0000000000000000000000000000000000000000
--- a/Examples/python/fitting/ex11_ExternalMinimizer/fit_with_builder.py
+++ /dev/null
@@ -1,47 +0,0 @@
-"""
-Prototype of SimulationBuilder and FitObject to work together with
-external minimizer.
-"""
-import bornagain as ba
-from bornagain import nm, deg, angstrom
-import numpy as np
-import lmfit
-from simulation_builder import SimulationBuilder
-from fit_objects import FitObject
-
-
-def create_experimental_data():
-    """
-    Generating "real" data by adding noise to the simulated data.
-    """
-    simulation = SimulationBuilder().build_simulation()
-    simulation.runSimulation()
-
-    # retrieving simulated data in the form of numpy array
-    real_data = simulation.result().array()
-
-    # spoiling simulated data with noise to produce "real" data
-    np.random.seed(0)
-    noise_factor = 0.1
-    noisy = np.random.normal(real_data, noise_factor*np.sqrt(real_data))
-    noisy[noisy < 0.1] = 0.1
-    return noisy
-
-
-def run_fitting():
-    real_data = create_experimental_data()
-
-    fit_object = FitObject()
-    fit_object.set_data(SimulationBuilder(), real_data)
-
-    params = lmfit.Parameters()
-    params.add('radius', value=8*nm)
-    params.add('length', value=8*nm)
-
-    result = lmfit.minimize(fit_object.evaluate, params)
-
-    result.params.pretty_print()
-
-
-if __name__ == '__main__':
-    run_fitting()
diff --git a/Examples/python/fitting/ex11_ExternalMinimizer/fit_with_roi.py b/Examples/python/fitting/ex11_ExternalMinimizer/fit_with_roi.py
deleted file mode 100644
index 7cc9450fc4ce1ad337dc444134992b7913bc08a6..0000000000000000000000000000000000000000
--- a/Examples/python/fitting/ex11_ExternalMinimizer/fit_with_roi.py
+++ /dev/null
@@ -1,114 +0,0 @@
-"""
-Prototype of SimulationBuilder and FitObject to work together with
-external minimizer.
-"""
-import bornagain as ba
-from bornagain import nm, deg, angstrom
-import numpy as np
-import lmfit
-from simulation_builder import SimulationBuilder
-from fit_objects import FitObject
-from matplotlib import pyplot as plt
-
-
-class Plotter:
-    def __init__(self, fit_object):
-
-        self.m_fit_object = fit_object
-        self._fig = plt.figure(figsize=(10.25, 7.69))
-        self._fig.canvas.draw()
-
-    def make_subplot(self, nplot):
-        plt.subplot(2, 2, nplot)
-        plt.subplots_adjust(wspace=0.2, hspace=0.2)
-
-    def reset(self):
-        self._fig.clf()
-
-    def plot(self, params, iter, residual):
-        self.reset()
-
-        sim_data = self.m_fit_object.simulationResult()
-        real_data = self.m_fit_object.experimentalData()
-        diff = self.m_fit_object.relativeDifference()
-
-        # same limits for both plots
-        arr = real_data.array()
-        zmax = np.amax(arr)
-        zmin = zmax * 1e-6
-
-        self.make_subplot(1)
-        ba.plot_colormap(real_data, title="Real data",
-                          zmin=zmin, zmax=zmax, zlabel='')
-
-        self.make_subplot(2)
-        ba.plot_colormap(sim_data, title="Simulated data",
-                          zmin=zmin, zmax=zmax, zlabel='')
-
-        self.make_subplot(3)
-        ba.plot_colormap(diff, title="Relative difference",
-                          zmin=1e-03, zmax=10, zlabel='')
-
-        self.make_subplot(4)
-        plt.title('Parameters')
-        plt.axis('off')
-        plt.text(0.01, 0.85, "Iterations  {:d}". format(iter))
-        for index, p in enumerate(params):
-            print(index, p)
-            plt.text(0.01, 0.55 - index * 0.1,
-                     '{:30.30s}: {:6.3f}'.format(p, params[p].value))
-
-        plt.tight_layout()
-        plt.pause(0.03)
-
-
-
-class SimulationROIBuilder(SimulationBuilder):
-    def __init__(self):
-        super(SimulationROIBuilder, self).__init__()
-
-    def build_simulation(self, params=None):
-        sim = super(SimulationROIBuilder, self).build_simulation(params)
-        sim.setRegionOfInterest(-0.5*deg, 0.2*deg, 0.5*deg, 1.8*deg)
-
-        return sim
-
-
-def create_experimental_data():
-    """
-    Generating "real" data by adding noise to the simulated data.
-    """
-    simulation = SimulationROIBuilder().build_simulation()
-    simulation.runSimulation()
-
-    # retrieving simulated data in the form of numpy array
-    real_data = simulation.result().array()
-
-    # spoiling simulated data with noise to produce "real" data
-    np.random.seed(0)
-    noise_factor = 0.1
-    noisy = np.random.normal(real_data, noise_factor*np.sqrt(real_data))
-    noisy[noisy < 0.1] = 0.1
-    return noisy
-
-
-def run_fitting():
-    real_data = create_experimental_data()
-
-    fit_object = FitObject()
-    fit_object.set_data(SimulationROIBuilder(), real_data)
-
-    params = lmfit.Parameters()
-    params.add('radius', value=8*nm)
-    params.add('length', value=8*nm)
-
-    plotter = Plotter(fit_object)
-
-    result = lmfit.minimize(fit_object.evaluate, params, iter_cb=plotter.plot)
-
-    result.params.pretty_print()
-
-
-if __name__ == '__main__':
-    run_fitting()
-    plt.show()
diff --git a/Examples/python/fitting/ex11_ExternalMinimizer/lmfit_with_plotting.py b/Examples/python/fitting/ex11_ExternalMinimizer/lmfit_with_plotting.py
deleted file mode 100644
index 650d20fe6dfdc6ff6af83419d2443824d1536c36..0000000000000000000000000000000000000000
--- a/Examples/python/fitting/ex11_ExternalMinimizer/lmfit_with_plotting.py
+++ /dev/null
@@ -1,172 +0,0 @@
-"""
-Example of using external minimizer to fit typical BornAgain simulation
-"""
-import numpy as np
-from matplotlib import colors
-from matplotlib import pyplot as plt
-import bornagain as ba
-from bornagain import deg, angstrom, nm
-import lmfit
-
-
-def get_sample(radius=5.0*nm, lattice_length=10.0*nm):
-    """
-    Returns a sample with cylinders and pyramids on a substrate,
-    forming a hexagonal lattice.
-    """
-    m_air = ba.HomogeneousMaterial("Air", 0.0, 0.0)
-    m_substrate = ba.HomogeneousMaterial("Substrate", 6e-6, 2e-8)
-    m_particle = ba.HomogeneousMaterial("Particle", 6e-4, 2e-8)
-
-    sphere_ff = ba.FormFactorFullSphere(radius)
-    sphere = ba.Particle(m_particle, sphere_ff)
-    particle_layout = ba.ParticleLayout()
-    particle_layout.addParticle(sphere)
-
-    interference = ba.InterferenceFunction2DLattice.createHexagonal(lattice_length)
-    pdf = ba.FTDecayFunction2DCauchy(10*nm, 10*nm)
-    interference.setDecayFunction(pdf)
-
-    particle_layout.setInterferenceFunction(interference)
-
-    air_layer = ba.Layer(m_air)
-    air_layer.addLayout(particle_layout)
-    substrate_layer = ba.Layer(m_substrate, 0)
-    multi_layer = ba.MultiLayer()
-    multi_layer.addLayer(air_layer)
-    multi_layer.addLayer(substrate_layer)
-    return multi_layer
-
-
-def get_simulation():
-    """
-    Create and return GISAXS simulation with beam and detector defined
-    """
-    simulation = ba.GISASSimulation()
-    simulation.setDetectorParameters(100, -1.0*deg, 1.0*deg,
-                                     100, 0.0*deg, 2.0*deg)
-    simulation.setBeamParameters(1.0*angstrom, 0.2*deg, 0.0*deg)
-    simulation.setBeamIntensity(1e+08)
-    return simulation
-
-
-def create_real_data():
-    """
-    Generating "real" data by adding noise to the simulated data.
-    """
-    sample = get_sample(5.0*nm, 10.0*nm)
-    simulation = get_simulation()
-    simulation.setSample(sample)
-    simulation.runSimulation()
-
-    # retrieving simulated data in the form of numpy array
-    real_data = simulation.result().array()
-
-    # spoiling simulated data with noise to produce "real" data
-    np.random.seed(0)
-    noise_factor = 0.1
-    noisy = np.random.normal(real_data, noise_factor*np.sqrt(real_data))
-    noisy[noisy < 0.1] = 0.1
-    return noisy
-
-
-def residual(params, simulation, data):
-    radius = params['radius'].value
-    length = params['length'].value
-    print(radius, length)
-    sample = get_sample(radius=radius, lattice_length=length)
-    simulation.setSample(sample)
-    simulation.runSimulation()
-    result = simulation.result().array().flatten()
-    exp = data.flatten()
-    res = result-exp
-    return res
-
-
-class Plotter:
-    def __init__(self):
-
-        self._fig = plt.figure(figsize=(10.25, 7.69))
-        self._fig.canvas.draw()
-
-    def make_subplot(self, nplot):
-        plt.subplot(2, 2, nplot)
-        plt.subplots_adjust(wspace=0.2, hspace=0.2)
-
-    def reset(self):
-        self._fig.clf()
-
-    def plot(self, params, iter, simulation, data):
-        self.reset()
-
-        sim_data = simulation.result().histogram2d()
-
-        real_data = simulation.result().histogram2d()
-        real_data.setContent(data)
-
-        zmax = real_data.getMaximum()
-        zmin = zmax*1e-6
-
-        self.make_subplot(1)
-        ba.plot_histogram(real_data, title="Real data",
-                          zmin=zmin, zmax=zmax, zlabel='')
-
-        self.make_subplot(2)
-        ba.plot_histogram(sim_data, title="Simulated data",
-                          zmin=zmin, zmax=zmax, zlabel='')
-
-        self.make_subplot(3)
-        sim_array = sim_data.array()
-        exp_array = real_data.array()
-
-        rel_diff = 2.0 * np.abs(sim_array - exp_array) / (sim_array + exp_array)
-        im = plt.imshow(rel_diff, norm=colors.LogNorm(1e-6, 1.0), aspect='auto')
-        cb = plt.colorbar(im, pad=0.025)
-        plt.xlabel('X, bins', fontsize=14)
-        plt.ylabel('Y, bins', fontsize=14)
-        plt.title("Relative difference")
-
-        self.make_subplot(4)
-        plt.title('Parameters')
-        plt.axis('off')
-        plt.text(0.01, 0.85, "Iterations  {:d}". format(iter))
-        for index, p in enumerate(params):
-            print(index, p)
-            plt.text(0.01, 0.55 - index * 0.1,
-                     '{:30.30s}: {:6.3f}'.format(p, params[p].value))
-
-        plt.tight_layout()
-        plt.pause(0.03)
-
-    def iter_cb(self, params, iter, resid, simulation, data):
-        self.plot(params, iter, simulation, data)
-
-
-def run_fitting():
-    """
-    main function to run fitting
-    """
-    simulation = get_simulation()
-    sample = get_sample()
-    simulation.setSample(sample)
-
-    real_data = create_real_data()
-
-    params = lmfit.Parameters()
-    params.add('radius', value=8*nm, min=0.01, max=12)
-    params.add('length', value=8*nm, min=0.01, max=12)
-
-    plotter = Plotter()
-
-    result = lmfit.minimize(residual, params, iter_cb=plotter.iter_cb,
-                            args=(simulation, real_data))
-
-    result.params.pretty_print()
-    print(lmfit.fit_report(result))
-
-
-if __name__ == '__main__':
-    run_fitting()
-    plt.show()
-
-
diff --git a/Examples/python/fitting/ex11_ExternalMinimizer/simulation_builder.py b/Examples/python/fitting/ex11_ExternalMinimizer/simulation_builder.py
deleted file mode 100644
index fb575e5e7dd5b9ade32c9100055ccf84e507d314..0000000000000000000000000000000000000000
--- a/Examples/python/fitting/ex11_ExternalMinimizer/simulation_builder.py
+++ /dev/null
@@ -1,50 +0,0 @@
-import bornagain as ba
-from bornagain import nm, deg, angstrom
-
-
-class SimulationBuilder:
-    def __init__(self):
-        self.radius = 5.0*nm
-        self.lattice_length = 10.0*nm
-
-    def build_simulation(self, params=None):
-        if params:
-            self.radius = params["radius"].value
-            self.lattice_length = params["length"].value
-
-        print("radius: {:6.3f} length:{:6.3f}".format(
-            self.radius, self.lattice_length))
-
-        simulation = ba.GISASSimulation()
-        simulation.setDetectorParameters(100, -1.0 * deg, 1.0 * deg,
-                                         100, 0.0 * deg, 2.0 * deg)
-        simulation.setBeamParameters(1.0 * angstrom, 0.2 * deg, 0.0 * deg)
-        simulation.setBeamIntensity(1e+08)
-        simulation.setSample(self.build_sample())
-        return simulation
-
-    def build_sample(self):
-        m_air = ba.HomogeneousMaterial("Air", 0.0, 0.0)
-        m_substrate = ba.HomogeneousMaterial("Substrate", 6e-6, 2e-8)
-        m_particle = ba.HomogeneousMaterial("Particle", 6e-4, 2e-8)
-
-        sphere_ff = ba.FormFactorFullSphere(self.radius)
-        sphere = ba.Particle(m_particle, sphere_ff)
-        particle_layout = ba.ParticleLayout()
-        particle_layout.addParticle(sphere)
-
-        interference = ba.InterferenceFunction2DLattice.createHexagonal(
-            self.lattice_length)
-        pdf = ba.FTDecayFunction2DCauchy(10 * nm, 10 * nm)
-        interference.setDecayFunction(pdf)
-
-        particle_layout.setInterferenceFunction(interference)
-
-        air_layer = ba.Layer(m_air)
-        air_layer.addLayout(particle_layout)
-        substrate_layer = ba.Layer(m_substrate, 0)
-        multi_layer = ba.MultiLayer()
-        multi_layer.addLayer(air_layer)
-        multi_layer.addLayer(substrate_layer)
-        return multi_layer
-
diff --git a/Examples/python/fitting/ex01_SampleParametersIntro/SampleParametersIntro_v2.py b/Examples/python/simulation/ex07_Miscellaneous/SimulationParameters.py
similarity index 90%
rename from Examples/python/fitting/ex01_SampleParametersIntro/SampleParametersIntro_v2.py
rename to Examples/python/simulation/ex07_Miscellaneous/SimulationParameters.py
index fc3329e7b0b534615219b8d5a8829bac8515b125..5393b0008d29737534ee1551e08222b5cd4d4e1b 100644
--- a/Examples/python/fitting/ex01_SampleParametersIntro/SampleParametersIntro_v2.py
+++ b/Examples/python/simulation/ex07_Miscellaneous/SimulationParameters.py
@@ -1,8 +1,8 @@
 """
 Working with sample parameters.
 
-Variation of SampleParameterIntro.py with the difference that parameter change
-is going via top level simulation object.
+This example shows how to create a simulation with fixed parameters, and then change
+these parameters on the fly during runtime.
 """
 
 from __future__ import print_function
@@ -25,15 +25,16 @@ def get_sample():
     cylinder = ba.Particle(m_particle, cylinder_ff)
     prism_ff = ba.FormFactorPrism3(5*nm, 5*nm)
     prism = ba.Particle(m_particle, prism_ff)
-    particle_layout = ba.ParticleLayout()
-    particle_layout.addParticle(cylinder, 0.5)
-    particle_layout.addParticle(prism, 0.5)
+
+    layout = ba.ParticleLayout()
+    layout.addParticle(cylinder, 0.5)
+    layout.addParticle(prism, 0.5)
     interference = ba.InterferenceFunctionNone()
-    particle_layout.setInterferenceFunction(interference)
+    layout.setInterferenceFunction(interference)
 
     # air layer with particles and substrate form multi layer
     air_layer = ba.Layer(m_air)
-    air_layer.addLayout(particle_layout)
+    air_layer.addLayout(layout)
     substrate_layer = ba.Layer(m_substrate, 0)
     multi_layer = ba.MultiLayer()
     multi_layer.addLayer(air_layer)
diff --git a/Fit/CMakeLists.txt b/Fit/CMakeLists.txt
index 396a45a41d5fb84c6ad5540f0dd4e5cd3437d85d..4b0af5985bea92f8ef08327ca292014322ef6122 100644
--- a/Fit/CMakeLists.txt
+++ b/Fit/CMakeLists.txt
@@ -4,10 +4,6 @@
 
 set(library_name BornAgainFit)
 
-if(POLICY CMP0042)
-    cmake_policy(SET CMP0042 NEW)
-endif()
-
 # --- source and include files ------
 set(FIT_SOURCE_DIRS
     ${CMAKE_CURRENT_SOURCE_DIR}/Kernel
@@ -108,19 +104,9 @@ set(${library_name}_INCLUDE_DIRS ${include_dirs} PARENT_SCOPE)
 set(${library_name}_LIBRARY ${library_name} PARENT_SCOPE)
 
 # --- dependencies ---------
-include_as_system_directory("${EIGEN3_INCLUDE_DIR}")
-include_directories(
-    ${Boost_INCLUDE_DIRS}
-    ${RootMinimizers_INCLUDE_DIRS}
-    ${GSL_INCLUDE_DIR}
-    )
-
-target_link_libraries(
-    ${library_name}
-    ${Boost_LIBRARIES}
-    ${RootMinimizers_LIBRARY}
-    ${GSL_LIBRARIES}
-    )
+target_include_directories(${library_name} PUBLIC ${RootMinimizers_INCLUDE_DIRS})
+target_include_directories(${library_name} PUBLIC ${include_dirs})
+target_link_libraries(${library_name} ${RootMinimizers_LIBRARY}  ${Boost_LIBRARIES})
 
 if(BORNAGAIN_PYTHON)
     include_directories(${PYTHON_INCLUDE_DIRS} ${NUMPY_INCLUDE_DIR})
diff --git a/Fit/Minimizer/TestMinimizer.cpp b/Fit/Minimizer/TestMinimizer.cpp
index fa36b5bd7af9ba285d6351065e27dddf5b997ba3..c34a8d9ee5f8063139ee7debb10bd8ef7db6a5b0 100644
--- a/Fit/Minimizer/TestMinimizer.cpp
+++ b/Fit/Minimizer/TestMinimizer.cpp
@@ -19,7 +19,7 @@
 
 using namespace Fit;
 
-TestMinimizer::TestMinimizer() : m_min_value(0) {}
+TestMinimizer::TestMinimizer() {}
 
 TestMinimizer::~TestMinimizer() = default;
 
diff --git a/Fit/Minimizer/TestMinimizer.h b/Fit/Minimizer/TestMinimizer.h
index 7696df3294d88b5d896bf907810d7cc6854cad85..dc32d106c81ac2e8a65d87b09703a73fc5e8bdb9 100644
--- a/Fit/Minimizer/TestMinimizer.h
+++ b/Fit/Minimizer/TestMinimizer.h
@@ -23,7 +23,7 @@ class BA_CORE_API_ TestMinimizer : public IMinimizer
 {
  public:
     TestMinimizer();
-    ~TestMinimizer();
+    ~TestMinimizer() override;
 
     std::string minimizerName() const final;
     std::string algorithmName() const final { return ""; }
@@ -31,7 +31,6 @@ class BA_CORE_API_ TestMinimizer : public IMinimizer
     Fit::MinimizerResult minimize_scalar(fcn_scalar_t fcn, Fit::Parameters parameters) override;
 
  private:
-    double m_min_value;
     std::vector<double> m_parameter_values;
     scalar_function_t m_fcn;
 };
diff --git a/Fit/RootAdapter/GSLLevenbergMarquardtMinimizer.cpp b/Fit/RootAdapter/GSLLevenbergMarquardtMinimizer.cpp
index c54656bd3657fbec45a6942b15a19673b307f0ad..218245fc8999be6af134b359ece6c1bb1322127d 100644
--- a/Fit/RootAdapter/GSLLevenbergMarquardtMinimizer.cpp
+++ b/Fit/RootAdapter/GSLLevenbergMarquardtMinimizer.cpp
@@ -16,6 +16,8 @@
 #include "GSLMultiMinimizer.h"
 #include "MinimizerUtils.h"
 #include "StringUtils.h"
+#include "AttLimits.h"
+#include <stdexcept>
 
 #ifdef _WIN32
 #pragma warning(push)
@@ -111,3 +113,12 @@ const RootMinimizerAdapter::root_minimizer_t* GSLLevenbergMarquardtMinimizer::ro
 {
     return m_gsl_minimizer.get();
 }
+
+void GSLLevenbergMarquardtMinimizer::setParameter(unsigned int index, const Fit::Parameter& par)
+{
+    auto limits = par.limits();
+    if (!limits.isLimitless() && !limits.isFixed() )
+        throw std::runtime_error("GSLLMA minimizer can't handle limited parameters."
+                                 "Please make them free");
+    RootMinimizerAdapter::setParameter(index, par);
+}
diff --git a/Fit/RootAdapter/GSLLevenbergMarquardtMinimizer.h b/Fit/RootAdapter/GSLLevenbergMarquardtMinimizer.h
index 7b14c87a5c986d2ae0cf2d182fa3dad8d5620344..9fb2d2e93f29591bf2e02d887aa54526241b4343 100644
--- a/Fit/RootAdapter/GSLLevenbergMarquardtMinimizer.h
+++ b/Fit/RootAdapter/GSLLevenbergMarquardtMinimizer.h
@@ -51,6 +51,7 @@ protected:
     virtual bool isGradientBasedAgorithm() override;
     void propagateOptions() override;
     const root_minimizer_t* rootMinimizer() const override;
+    void setParameter(unsigned int index, const Fit::Parameter& par) override;
 
 private:
     std::unique_ptr<ROOT::Math::GSLNLSMinimizer> m_gsl_minimizer;
diff --git a/Fit/RootAdapter/MinimizerResultUtils.cpp b/Fit/RootAdapter/MinimizerResultUtils.cpp
index edcb4607b45030e4733e4ec0716053034b51170e..1543cc21857f6daa05793b8cdc0a1dd0afb05079 100644
--- a/Fit/RootAdapter/MinimizerResultUtils.cpp
+++ b/Fit/RootAdapter/MinimizerResultUtils.cpp
@@ -58,10 +58,11 @@ std::string MinimizerResultUtils::reportParameters(const Fit::Parameters& parame
 
     result << MinimizerUtils::sectionString("FitParameters");
 
-    result << "Name       StartValue  Limits                FitValue  Error" << std::endl;
+    result << "Name       StartValue  Limits                        FitValue     Error"
+           << std::endl;
 
     for (const auto& par : parameters) {
-        result << boost::format("# %-8s %-7.4f     %-20s  %-6.4f    %5.4f \n") % par.name()
+        result << boost::format("# %-8s %-8.3e   %-28s  %-8.3e    %8.3e \n") % par.name()
                       % par.startValue() % par.limits().toString() % par.value() % par.error();
     }
 
diff --git a/Fit/RootAdapter/RootMinimizerAdapter.h b/Fit/RootAdapter/RootMinimizerAdapter.h
index 40e2051b90985db9b2ac3870eba84e3cc80c8ced..4318c8acd89ab815f6326648e6df6b1aeed34f98 100644
--- a/Fit/RootAdapter/RootMinimizerAdapter.h
+++ b/Fit/RootAdapter/RootMinimizerAdapter.h
@@ -35,7 +35,7 @@ class BA_CORE_API_ RootMinimizerAdapter : public IMinimizer
 public:
     typedef ROOT::Math::Minimizer root_minimizer_t;
 
-    virtual ~RootMinimizerAdapter();
+    virtual ~RootMinimizerAdapter() override;
 
     Fit::MinimizerResult minimize_scalar(fcn_scalar_t fcn, Fit::Parameters parameters) override;
     Fit::MinimizerResult minimize_residual(fcn_residual_t fcn, Fit::Parameters parameters) override;
diff --git a/Fit/Tools/AttLimits.cpp b/Fit/Tools/AttLimits.cpp
index fbf15ea9f848df93e702874ab410302a070eddea..cd474d2297b08aa9f5fd6c329029e9c9ae6b752c 100644
--- a/Fit/Tools/AttLimits.cpp
+++ b/Fit/Tools/AttLimits.cpp
@@ -111,12 +111,12 @@ std::string AttLimits::toString() const
     else if (isLimitless())
         result << "free";
     else if (isLowerLimited())
-        result << "lowerLimited(" << std::fixed << std::setprecision(2) << lowerLimit() << ")";
+        result << "lowerLimited(" << std::scientific << std::setprecision(2) << lowerLimit() << ")";
     else if (isUpperLimited())
-        result << "upperLimited(" << std::fixed << std::setprecision(2) << upperLimit() << ")";
+        result << "upperLimited(" << std::scientific << std::setprecision(2) << upperLimit() << ")";
     else if (isLimited())
-        result << "limited(" << std::fixed << std::setprecision(2) << lowerLimit() << ","
-               << std::fixed << std::setprecision(2) << upperLimit() << ")";
+        result << "limited(" << std::scientific << std::setprecision(2) << lowerLimit() << ","
+               << std::scientific << std::setprecision(2) << upperLimit() << ")";
 
     return result.str();
 }
diff --git a/GUI/CMakeLists.txt b/GUI/CMakeLists.txt
index 5d100b25a449e22146ec42636f6690b315ff044a..69f3895f40cde4f38bfdc76bf5ab4e385fe5e225 100644
--- a/GUI/CMakeLists.txt
+++ b/GUI/CMakeLists.txt
@@ -1,18 +1,11 @@
 ############################################################################
 # CMakeLists.txt file for building BornAgain/GUI libraries and executable
 ############################################################################
-if(POLICY CMP0020)
-    cmake_policy(SET CMP0020 NEW)
-endif()
-if(POLICY CMP0043)
-    cmake_policy(SET CMP0043 NEW)
-endif()
 
 message(STATUS "Configuring BornAgain GUI")
 
 if(BORNAGAIN_OPENGL)
     message(STATUS "Configuring BornAgain OpenGL")
-    add_definitions(-DBORNAGAIN_OPENGL)
     add_subdirectory(ba3d)
 endif()
 
diff --git a/GUI/ba3d/ba3d/CMakeLists.txt b/GUI/ba3d/ba3d/CMakeLists.txt
index 26daacea80769cab7e209b9ef28e4d112dc5e61c..271d8a613d9641ce6e54d7745d7e2256653ec58c 100644
--- a/GUI/ba3d/ba3d/CMakeLists.txt
+++ b/GUI/ba3d/ba3d/CMakeLists.txt
@@ -14,3 +14,4 @@ add_library (${lib} STATIC ${source_files} ${include_files} ${RC_SHADERS})
 target_link_libraries (${lib}
   Qt5::Core Qt5::Widgets Qt5::OpenGL
 )
+
diff --git a/GUI/ba3d/ba3d/model/geometry.cpp b/GUI/ba3d/ba3d/model/geometry.cpp
index 88d0e09be69b3af26cdd8fe96ea3af7eb3f94620..6f95ee384eaabc8b1c835583e2c207c585b78d2d 100644
--- a/GUI/ba3d/ba3d/model/geometry.cpp
+++ b/GUI/ba3d/ba3d/model/geometry.cpp
@@ -81,7 +81,7 @@ Geometry::Geometry(GeometricID::Key key_) : m_key(key_)
         m_mesh = meshBox();
         break;
     case BaseShape::Sphere:
-        m_mesh = meshSphere(m_key.p1, m_key.p2);
+        m_mesh = meshSphere(m_key.p1, m_key.p2, m_key.p3);
         break;
     case BaseShape::Column:
         m_mesh = meshColumn(m_key.p1, m_key.p2);
diff --git a/GUI/ba3d/ba3d/model/geometry.h b/GUI/ba3d/ba3d/model/geometry.h
index 914f9f11a27f2f982d0c4fbfd4424f568346c0b2..ffe7a66b69bf25e4443c253a06084ab9572f16e3 100644
--- a/GUI/ba3d/ba3d/model/geometry.h
+++ b/GUI/ba3d/ba3d/model/geometry.h
@@ -81,7 +81,7 @@ private:
 
     static Mesh meshPlane();
     static Mesh meshBox();
-    static Mesh meshSphere(float cut, float baseShift = 0.0f);
+    static Mesh meshSphere(float cut, float baseShift = 0.0f, float removedTop = 0.0f);
     static Mesh meshColumn(float ratio_Rt_Rb, float numSides);
     static Mesh meshIcosahedron();
     static Mesh meshDodecahedron();
diff --git a/GUI/ba3d/ba3d/model/geometry/column.cpp b/GUI/ba3d/ba3d/model/geometry/column.cpp
index d63759105731f9d203181349a11dab47e63de9ef..549dd6d229dd8e72d6df06cf0757a0270e7c9121 100644
--- a/GUI/ba3d/ba3d/model/geometry/column.cpp
+++ b/GUI/ba3d/ba3d/model/geometry/column.cpp
@@ -29,7 +29,7 @@ Geometry::Mesh Geometry::meshColumn(float ratio_Rt_Rb, float numSides)
     float const R = .5f;
     float Rb = R, Rt = Rb * ratio_Rt_Rb, H = 2 * R;
 
-    // mesh of vertices (bottom and top) and normals (bottom to top)
+    // mesh of vertices (bottom and top) and normals
     Vertices vb(slices), vt(slices), nbt(slices);
     float const nz = (1 - Rt / Rb) * H;
 
diff --git a/GUI/ba3d/ba3d/model/geometry/sphere.cpp b/GUI/ba3d/ba3d/model/geometry/sphere.cpp
index f3e53836c4dc36c8501f288d7af877e6ad3287a9..fe93b356cae5444a54f825209511ac7e9e899d06 100644
--- a/GUI/ba3d/ba3d/model/geometry/sphere.cpp
+++ b/GUI/ba3d/ba3d/model/geometry/sphere.cpp
@@ -18,30 +18,41 @@
 namespace RealSpace
 {
 
-// cut: 0..1 - how much is cut off off the bottom
-Geometry::Mesh Geometry::meshSphere(float cut, float baseShift)
+// cut: 0..1 - how much is cut off from the bottom
+// removedTop - how much fraction of the radius is removed from the top
+Geometry::Mesh Geometry::meshSphere(float cut, float baseShift, float removedTop)
 {
     if (1 <= cut)
         return Mesh();
     cut = qMax(0.f, cut);
     Q_ASSERT(0 <= cut && cut < 1);
 
-    // 'rings' is 1 less than actual rings (due to poles)
+    // 'rings' are the # of horizontal cross-sections ranging from bottom to top of the sphere
+    // 'slices' are the # of vertices in a given ring
     int rings, slices = SLICES;
-    float minPh, phRge;
+    float minPh, maxPh, phRge;
 
-    if (cut > 0) {
+    if (cut > 0) // South pole absent
+    {
         minPh = asinf(2 * cut - 1);
-        phRge = float(M_PI_2) - minPh;
-        rings = qMax(1, qCeil(qreal(RINGS * phRge) / M_PI));
-    } else {
-        rings = RINGS - 1;
-        minPh = float(M_PI) / rings - float(M_PI_2);
-        phRge = float(M_PI_2) - minPh;
+        if (removedTop > 0) // North pole absent
+            maxPh = asinf(1-2*removedTop);
+        else // North pole present
+            maxPh = float(M_PI_2) - float(M_PI) / RINGS;
     }
+    else // South pole present
+    {
+        minPh =  - float(M_PI_2) + float(M_PI) / RINGS;
+        if (removedTop > 0) // North pole absent
+            maxPh = asinf(1-removedTop);
+        else // North pole present
+            maxPh = float(M_PI_2) - float(M_PI) / RINGS;
+    }
+    phRge = maxPh - minPh;
+    rings = qMax(2, qCeil(qreal(RINGS * phRge) / M_PI)); // At least 2 rings (incl. lowest ring)
 
     Q_ASSERT(qAbs(minPh) < float(M_PI_2));
-    Q_ASSERT(1 <= rings && 2 <= slices);
+    Q_ASSERT(2 <= rings && 2 <= slices);
 
     // meshes of vertices and normals, without poles, _[ring][slice]
     QVector<Vertices> vs_(rings), ns_(rings);
@@ -53,7 +64,7 @@ Geometry::Mesh Geometry::meshSphere(float cut, float baseShift)
     float const R = .5f;
 
     for (int r = 0; r < rings; ++r) {
-        float ph = minPh + phRge * r / rings;
+        float ph = minPh + phRge * r / (rings-1);
         float cp = cosf(ph), sp = sinf(ph);
 
         for (int s = 0; s < slices; ++s) {
@@ -67,7 +78,7 @@ Geometry::Mesh Geometry::meshSphere(float cut, float baseShift)
     }
 
     // make into triangles
-    int const nv = 6 * (rings)*slices;
+    int const nv = 6*(rings)*slices;
     Vertices vs;
     vs.reserve(nv);
     Vertices ns;
@@ -82,12 +93,12 @@ Geometry::Mesh Geometry::meshSphere(float cut, float baseShift)
             auto &v0 = vr.at(s0), &v1 = vr.at(s1);
             auto &n0 = nr.at(s0), &n1 = nr.at(s1);
 
-            if (r == 0) { // south pole
+            if (r == 0) { // bottom most ring
                 Vector3D vp, n0, n1, np(-Vector3D::_z);
-                if (cut > 0) {
+                if (cut > 0) { // South pole absent
                     vp = Vector3D(0, 0, v0.z);
                     n0 = n1 = np;
-                } else {
+                } else { // South pole present
                     vp = Vector3D(0, 0, -R + baseShift);
                     n0 = nr.at(s0);
                     n1 = nr.at(s1);
@@ -96,11 +107,20 @@ Geometry::Mesh Geometry::meshSphere(float cut, float baseShift)
                 ns.addTriangle(n0, np, n1);
             }
 
-            if (r + 1 == rings) { // north pole
-                Vector3D vp(0, 0, +R + baseShift), np(Vector3D::_z);
+            if (r + 1 == rings) { // top most ring
+                Vector3D vp, n0, n1, np(Vector3D::_z);
+                if (removedTop > 0) { // North pole absent
+                    vp = Vector3D(0, 0, v0.z);
+                    n0 = n1 = np;
+                } else { // North pole present
+                    vp = Vector3D(0, 0, +R + baseShift);
+                    n0 = nr.at(s0);
+                    n1 = nr.at(s1);
+                }
                 vs.addTriangle(v0, v1, vp);
                 ns.addTriangle(n0, n1, np);
-            } else if (1 < rings) { // in between poles
+            }
+            else { // in between poles
                 auto &vr1 = vs_.at(r + 1), &nr1 = ns_.at(r + 1);
                 auto &n2 = nr1.at(s1), &n3 = nr1.at(s0);
                 vs.addQuad(v0, v1, vr1.at(s1), vr1.at(s0));
diff --git a/GUI/ba3d/ba3d/model/object.cpp b/GUI/ba3d/ba3d/model/object.cpp
index 2600e7e8df19ef344d50f2353e659b4598127c28..3a8af19ef89a504eb66270643f4dca0392b1ded6 100644
--- a/GUI/ba3d/ba3d/model/object.cpp
+++ b/GUI/ba3d/ba3d/model/object.cpp
@@ -16,11 +16,12 @@
 #include "model.h"
 #include "geometry.h"
 #include "../view/canvas.h"
-
 #include <cmath>
 
 namespace {
 QQuaternion EulerToQuaternion(const RealSpace::Vector3D& euler);
+
+RealSpace::Vector3D QuaternionToEuler(const QQuaternion &q);
 }
 
 namespace RealSpace {
@@ -69,6 +70,27 @@ void Object::transform(Vector3D turn, Vector3D scale, Vector3D rotate, Vector3D
     mat.rotate(EulerToQuaternion(turn));
 }
 
+// This method allows the addition of an extrinsic global rotation to an object i.e.
+// it rotates the object about the global origin of the coordinate system
+void Object::addExtrinsicRotation(Vector3D turn, Vector3D scale,
+                                  Vector3D &rotate, Vector3D rotateExtrinsic,
+                                  Vector3D &translate)
+{
+    mat.setToIdentity();
+    mat.rotate(EulerToQuaternion(rotateExtrinsic));
+    mat.translate(translate);
+    mat.rotate(EulerToQuaternion(rotate));
+    mat.scale(scale);
+    mat.rotate(EulerToQuaternion(turn));
+
+    // first apply the particle's intrinsic and then extrinsic rotations
+    QQuaternion q = EulerToQuaternion(rotateExtrinsic)*EulerToQuaternion(rotate);
+    rotate = QuaternionToEuler(q);
+
+    // translate the object to the extrinsically rotated translation vector
+    translate = EulerToQuaternion(rotateExtrinsic).rotatedVector(translate);
+}
+
 void Object::releaseGeometry()
 {
     geo.reset();
@@ -101,5 +123,29 @@ QQuaternion EulerToQuaternion(const RealSpace::Vector3D& euler)
     auto d = cphi2*cth2*spsi2 + cth2*cpsi2*sphi2;
     return QQuaternion{a, b, c, d};
 }
+
+RealSpace::Vector3D QuaternionToEuler(const QQuaternion& q)
+{
+    auto qvec = q.toVector4D();
+
+    float a = qvec.w(); // scalar part of quaternion
+    float b = qvec.x();
+    float c = qvec.y();
+    float d = qvec.z();
+
+    float term1 = std::atan(d/a);
+    float term2 = 0;
+
+    if (b == 0)
+       term2 = static_cast<float>(M_PI_2);
+    else
+       term2 = std::atan(c/b);
+
+    float x = term1 + term2;
+    float y = 2*std::atan(std::sqrt((b*b+c*c)/(a*a+d*d)));
+    float z = term1 - term2;
+
+    return RealSpace::Vector3D(x, y, z);
+}
 }
 
diff --git a/GUI/ba3d/ba3d/model/object.h b/GUI/ba3d/ba3d/model/object.h
index a2174d541e5fb380e0b835ce86d5fce6874567cb..18d397ceb873813f799d5efa254fa7bec2a67142 100644
--- a/GUI/ba3d/ba3d/model/object.h
+++ b/GUI/ba3d/ba3d/model/object.h
@@ -38,6 +38,10 @@ public:
     void transform(Vector3D scale, QQuaternion, Vector3D translate);
     void transform(Vector3D turn, Vector3D scale, Vector3D rotate, Vector3D translate);
 
+    void addExtrinsicRotation(Vector3D turn, Vector3D scale,
+                              Vector3D &rotate, Vector3D rotateExtrinsic,
+                              Vector3D &translate);
+
 protected:
     bool isNull;
 
diff --git a/GUI/ba3d/ba3d/model/particles.cpp b/GUI/ba3d/ba3d/model/particles.cpp
index 93fc8ca2170dcb739e8b2561e033e86acd1d7dc3..d7362a8fbc9f8b22a42e672060c2cba98b3e4448 100644
--- a/GUI/ba3d/ba3d/model/particles.cpp
+++ b/GUI/ba3d/ba3d/model/particles.cpp
@@ -84,6 +84,11 @@ void Particle::addTranslation(Vector3D translate_)
     Object::transform(turn, scale, rotate, offset + (translate = translate + translate_));
 }
 
+void Particle::addExtrinsicRotation(Vector3D rotateExtrinsic)
+{
+    Object::addExtrinsicRotation(turn, scale, rotate, rotateExtrinsic , (translate = offset + translate));
+}
+
 //------------------------------------------------------------------------------
 
 static float const pi = float(M_PI);
@@ -210,7 +215,7 @@ Icosahedron::Icosahedron(float L) : Particle(Key(BaseShape::Icosahedron))
 Prism3::Prism3(float L, float H) : Particle(Key(BaseShape::Column, 1.0f, 3))
 {
     isNull = (L <= 0 || H <= 0);
-    float D = L * 2 / sqrt3f;
+    float D = L / sqrt3f;
     scale = Vector3D(D * 2, D * 2, H);
     offset = Vector3D(0, 0, 0);
     set();
@@ -273,8 +278,8 @@ TruncatedCube::TruncatedCube(float L, float t) : Particle(Key(BaseShape::Truncat
     set();
 }
 
-TruncatedSphere::TruncatedSphere(float R, float H)
-    : Particle(Key(BaseShape::Sphere, 1 - H / R / 2, (H - R) / R / 2))
+TruncatedSphere::TruncatedSphere(float R, float H, float deltaH)
+    : Particle(Key(BaseShape::Sphere, 1 - H / R / 2, (H - R) / R / 2, deltaH/ R / 2))
 {
     isNull = (R <= 0 || H <= 0);
     scale = Vector3D(R * 2);
@@ -282,8 +287,9 @@ TruncatedSphere::TruncatedSphere(float R, float H)
     set();
 }
 
-TruncatedSpheroid::TruncatedSpheroid(float R, float H, float fp)
-    : Particle(Key(BaseShape::Sphere, 1 - H / fp / R / 2, (H - fp * R) / fp / R / 2))
+TruncatedSpheroid::TruncatedSpheroid(float R, float H, float fp, float deltaH)
+    : Particle(Key(BaseShape::Sphere, 1 - H / fp / R / 2, (H - fp * R) / fp / R / 2,
+                   deltaH / fp / R / 2))
 {
     isNull = (R <= 0 || H <= 0 || fp <= 0);
     scale = Vector3D(R * 2, R * 2, fp * R * 2);
diff --git a/GUI/ba3d/ba3d/model/particles.h b/GUI/ba3d/ba3d/model/particles.h
index f1fa4df78115f8ce2dfac2da71fa3cfc50c20180..eb0365dd36908a4bb9e7f83edd2916f356935ff3 100644
--- a/GUI/ba3d/ba3d/model/particles.h
+++ b/GUI/ba3d/ba3d/model/particles.h
@@ -72,6 +72,7 @@ public:
 
     void addTransform(Vector3D rotate, Vector3D translate);
     void addTranslation(Vector3D translate_);
+    void addExtrinsicRotation(Vector3D rotateExtrinsic);
 };
 
 //------------------------------------------------------------------------------
@@ -98,13 +99,13 @@ public:
 class TruncatedSphere : public Particle
 {
 public:
-    TruncatedSphere(float R, float H);
+    TruncatedSphere(float R, float H, float deltaH=0.0f);
 };
 
 class TruncatedSpheroid : public Particle
 {
 public:
-    TruncatedSpheroid(float R, float H, float fp);
+    TruncatedSpheroid(float R, float H, float fp, float deltaH=0.0f);
 };
 
 class Cone : public Particle
diff --git a/GUI/ba3d/ba3d/view/canvas.cpp b/GUI/ba3d/ba3d/view/canvas.cpp
index e2ff23c0505a08969dc74ed2d14c4a597cd73129..214770f58fc60ad48823c1ee8d5802654b2c2e87 100644
--- a/GUI/ba3d/ba3d/view/canvas.cpp
+++ b/GUI/ba3d/ba3d/view/canvas.cpp
@@ -52,14 +52,14 @@ namespace RealSpace
 
 Canvas::Canvas()
     : aspectRatio(1), colorBgR(1), colorBgG(1), colorBgB(1), currentZoomLevel(0), camera(nullptr),
-      program(nullptr), model(nullptr)
+      program(nullptr), model(nullptr), m_isInitializedGL(false)
 {
     connect(&geometryStore(), &GeometryStore::deletingGeometry, this, &Canvas::releaseBuffer);
 }
 
 Canvas::~Canvas()
 {
-    releaseBuffers();
+    cleanup();
 }
 
 void Canvas::setBgColor(QColor const& c)
@@ -98,6 +98,8 @@ void Canvas::setModel(Model* m)
     });
 
     setCamera();
+    //connect(camera, &RealSpace::Camera::updated, model, &Model::cameraUpdated);
+    camera->set();
 }
 
 Model* Canvas::getModel()
@@ -118,9 +120,15 @@ void Canvas::setCamera(bool full)
 
 void Canvas::initializeGL()
 {
+    setCamera((camera = new Camera));
+    setProgram((program = new Program));
+
+    connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &Canvas::cleanup);
+
     initializeOpenGLFunctions();
     glEnable(GL_DEPTH_TEST);
     glEnable(GL_CULL_FACE);
+    m_isInitializedGL = true;
 }
 
 void Canvas::resizeGL(int w, int h)
@@ -279,10 +287,30 @@ void Canvas::draw(QColor const& color, QMatrix4x4 const& mat, Geometry const& ge
     buf->draw();
 }
 
+void Canvas::cleanup()
+{
+    makeCurrent();
+
+    releaseBuffers();
+
+    delete camera;
+    camera = nullptr;
+    delete program;
+    program = nullptr;
+
+    m_isInitializedGL = false;
+    doneCurrent();
+}
+
+bool Canvas::isInitialized() const
+{
+    return m_isInitializedGL && model != nullptr;
+}
+
 void Canvas::defaultView()
 {
     // Default view
-    if (model) {
+    if (isInitialized()) {
         RealSpace::Camera::Position defPos(
             RealSpace::Vector3D(0, cameraDefaultPosY, cameraDefaultPosZ), // eye
             RealSpace::Vector3D(0, 0, 0),                                 // center
@@ -301,7 +329,7 @@ void Canvas::defaultView()
 void Canvas::sideView()
 {
     // Side view at current zoom level
-    if (model) {
+    if (isInitialized()) {
         RealSpace::Vector3D eye(0, cameraDefaultPosY, 0);
 
         // Side view 3D axes is zoom scale independent
@@ -327,7 +355,7 @@ void Canvas::sideView()
 void Canvas::topView()
 {
     // Top view at current zoom level
-    if (model) {
+    if (isInitialized()) {
         // Setting a tiny offset in y value of eye such that eye and up vectors are not parallel
         RealSpace::Vector3D eye(0, -0.5, -cameraDefaultPosY);
 
@@ -353,7 +381,7 @@ void Canvas::topView()
 
 void Canvas::horizontalCameraTurn(float angle)
 {
-    if (model) {
+    if (isInitialized()) {
 
         float theta = angle * static_cast<float>(M_PI / 180.0); // in radians
 
@@ -399,7 +427,7 @@ void Canvas::horizontalCameraTurn(float angle)
 
 void Canvas::verticalCameraTurn(float angle)
 {
-    if (model) {
+    if (isInitialized()) {
 
         float theta = angle * static_cast<float>(M_PI / 180.0); // in radians
 
diff --git a/GUI/ba3d/ba3d/view/canvas.h b/GUI/ba3d/ba3d/view/canvas.h
index 2303c93d6a90bef5fbe0f512dad94438cd449583..2c433a3f1ebe38b636ecb5247e95cf8a978983fa 100644
--- a/GUI/ba3d/ba3d/view/canvas.h
+++ b/GUI/ba3d/ba3d/view/canvas.h
@@ -58,6 +58,8 @@ public:
     void horizontalCameraTurn(float angle);
     void verticalCameraTurn(float angle);
 
+    Camera* cam() { return camera; }
+
 private:
     QRect viewport;
     float aspectRatio, colorBgR, colorBgG, colorBgB;
@@ -90,6 +92,11 @@ private:
     void releaseBuffers();
 
     void draw(QColor const&, QMatrix4x4 const&, Geometry const&);
+
+    void cleanup();
+    bool isInitialized() const;
+
+    bool m_isInitializedGL;
 };
 
 } // namespace RealSpace
diff --git a/GUI/ba3d/ba3d/widget.cpp b/GUI/ba3d/ba3d/widget.cpp
index 668f49ac5dd60d44502cc4d38512aa3437650c37..cc1616035be4933b340ce00f224c9815c5e64a80 100644
--- a/GUI/ba3d/ba3d/widget.cpp
+++ b/GUI/ba3d/ba3d/widget.cpp
@@ -23,29 +23,25 @@
 namespace RealSpace {
 //------------------------------------------------------------------------------
 
-Widget3D::Widget3D() : canvas(nullptr), camera(nullptr), program(nullptr) {
+Widget3D::Widget3D() : canvas(nullptr) {
   auto box = new QHBoxLayout;
   setLayout(box);
   box->setMargin(0);
   box->addWidget((canvas = new Canvas));
 
-  canvas->setCamera((camera = new Camera));
-  canvas->setProgram((program = new Program));
 }
 
 Widget3D::~Widget3D() {
-  delete program;
-  delete camera;
 }
 
+Camera& Widget3D::cam() { return *canvas->cam(); }
+
 void Widget3D::setBackground(QColor const& color) {
   canvas->setBgColor(color);
 }
 
 void Widget3D::setModel(Model* model) {
   canvas->setModel(model);
-  connect(camera, &RealSpace::Camera::updated, model, &Model::cameraUpdated);
-  camera->set();
 }
 
 void Widget3D::defaultView()
diff --git a/GUI/ba3d/ba3d/widget.h b/GUI/ba3d/ba3d/widget.h
index c70f3356c0d39c4c253f185d345322407136784d..a521adfb1908a0408780700729f2b7a8c06a32d1 100644
--- a/GUI/ba3d/ba3d/widget.h
+++ b/GUI/ba3d/ba3d/widget.h
@@ -33,7 +33,7 @@ public:
   Widget3D();
  ~Widget3D();
 
-  Camera& cam() { return *camera; }
+  Camera& cam();
 
   void setBackground(QColor const&);
   void setModel(Model*); // model owned elsewhere, may be nullptr
@@ -46,8 +46,6 @@ public:
 
 private:
   Canvas  *canvas;
-  Camera  *camera;
-  Program *program;
 };
 
 //------------------------------------------------------------------------------
diff --git a/GUI/coregui/CMakeLists.txt b/GUI/coregui/CMakeLists.txt
index afe7f67270072833d0806ee03528ee03c5afa25e..5caa7bf421ce708ca372795b8644f7c427d61716 100644
--- a/GUI/coregui/CMakeLists.txt
+++ b/GUI/coregui/CMakeLists.txt
@@ -1,22 +1,6 @@
 ############################################################################
 # CMakeLists.txt file for building libBornAgainGUI library
 ############################################################################
-if(POLICY CMP0020)
-    cmake_policy(SET CMP0020 NEW)
-endif()
-if(POLICY CMP0043)
-    cmake_policy(SET CMP0043 NEW)
-endif()
-if(POLICY CMP0042)
-    cmake_policy(SET CMP0042 NEW)
-endif()
-if(POLICY CMP0028)
-    cmake_policy(SET CMP0028 NEW)
-endif()
-if(POLICY CMP0071)
-  cmake_policy(SET CMP0071 NEW)
-endif()
-
 set(library_name BornAgainGUI)
 
 # --- source and include files ---
@@ -37,6 +21,7 @@ set(include_dirs
     ${CMAKE_CURRENT_SOURCE_DIR}/Views/MaskWidgets
     ${CMAKE_CURRENT_SOURCE_DIR}/Views/AccordionWidget
     ${CMAKE_CURRENT_SOURCE_DIR}/Views/ImportDataWidgets
+    ${CMAKE_CURRENT_SOURCE_DIR}/Views/ImportDataWidgets/CsvImportAssistant
     ${CMAKE_CURRENT_SOURCE_DIR}/Views/CommonWidgets
     ${CMAKE_CURRENT_SOURCE_DIR}/Views/SpecularDataWidgets
 )
@@ -75,7 +60,6 @@ endif()
 list(APPEND include_files ${include_widgetbox})
 
 list(APPEND include_dirs ${CMAKE_CURRENT_SOURCE_DIR}/Views/widgetbox)
-include_directories(${include_dirs})
 
 set(resource_files
     "coregui.qrc"
@@ -95,10 +79,6 @@ if(BORNAGAIN_CRASHHANDLER)
     add_definitions(-DBORNAGAIN_CRASHHANDLER)
 endif()
 
-if(BORNAGAIN_TIFF_SUPPORT)
-    add_definitions(-DBORNAGAIN_TIFF_SUPPORT)
-endif()
-
 if(WIN32)
     SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBA_CORE_BUILD_DLL")
 endif()
@@ -111,7 +91,7 @@ add_library(
     SHARED
     ${source_files} ${RC_SRCS} ${include_files}
 )
-set_Target_properties(${library_name} PROPERTIES PREFIX ${libprefix} SUFFIX ${libsuffix})
+set_target_properties(${library_name} PROPERTIES PREFIX ${libprefix} SUFFIX ${libsuffix})
 set(${library_name}_LIBRARY_TYPE SHARED)
 # exposing library name and list of include directories outside
 set(${library_name}_INCLUDE_DIRS ${include_dirs} PARENT_SCOPE)
@@ -119,26 +99,12 @@ set(${library_name}_LIBRARY ${library_name} PARENT_SCOPE)
 
 
 # --- dependencies ---------
-include_as_system_directory("${EIGEN3_INCLUDE_DIR}")
-include_directories(
-    ${QtAddOn_INCLUDE_DIRS}
-    ${Boost_INCLUDE_DIRS}
-    ${GSL_INCLUDE_DIR}
-    ${BornAgainCore_INCLUDE_DIRS}
-    ${BornAgainFit_INCLUDE_DIRS}
-    ${PYTHON_INCLUDE_DIRS}
-    ${ba3d_INCLUDE_DIRS}
-)
-
-target_link_libraries(${library_name}
-    ${QtAddOn_LIBRARIES}
-    ${PYTHON_LIBRARIES}
-    ${Boost_LIBRARIES}
-    ${BornAgainFit_LIBRARY}
-    ${BornAgainCore_LIBRARY}
-    ${ba3d_LIBRARY}
-)
-
+if(BORNAGAIN_OPENGL)
+target_compile_definitions(${library_name} PUBLIC -DBORNAGAIN_OPENGL)
+endif()
+target_include_directories(${library_name} PUBLIC ${QtAddOn_INCLUDE_DIRS} ${ba3d_INCLUDE_DIRS})
+target_include_directories(${library_name} PUBLIC ${include_dirs})
+target_link_libraries(${library_name} ${QtAddOn_LIBRARIES} ${BornAgainCore_LIBRARY} ${ba3d_LIBRARY})
 target_link_libraries(${library_name}
     Qt5::Widgets
     Qt5::Core
@@ -148,7 +114,6 @@ target_link_libraries(${library_name}
     Qt5::Network
 )
 
-
 # --- Installation ---------
 install (TARGETS ${library_name} DESTINATION ${destination_lib} COMPONENT Libraries)
 
diff --git a/GUI/coregui/Models/ApplicationModels.cpp b/GUI/coregui/Models/ApplicationModels.cpp
index db6a92d8633d4d2b8003144382325b1d7e234531..347a315e15d76fa4862ca0bc4f7f0bb483fdaf94 100644
--- a/GUI/coregui/Models/ApplicationModels.cpp
+++ b/GUI/coregui/Models/ApplicationModels.cpp
@@ -231,8 +231,9 @@ QList<SessionModel*> ApplicationModels::modelList()
 
 QVector<SessionItem*> ApplicationModels::nonXMLData() const
 {
-    Q_ASSERT(m_realDataModel && m_jobModel);
-    return QVector<SessionItem*>() << m_realDataModel->nonXMLData() << m_jobModel->nonXMLData();
+    Q_ASSERT(m_realDataModel && m_jobModel && m_instrumentModel);
+    return QVector<SessionItem*>() << m_realDataModel->nonXMLData() << m_jobModel->nonXMLData()
+                                   << m_instrumentModel->nonXMLData();
 }
 
 void ApplicationModels::disconnectModel(SessionModel* model)
diff --git a/GUI/coregui/Models/AxesItems.h b/GUI/coregui/Models/AxesItems.h
index 2bf684500dc817be43632cdee02bd9b3191261f8..4fbe131d222f03124fab25dd74c0676a0f222235 100644
--- a/GUI/coregui/Models/AxesItems.h
+++ b/GUI/coregui/Models/AxesItems.h
@@ -33,7 +33,7 @@ public:
     explicit BasicAxisItem(const QString& type = Constants::BasicAxisType);
     virtual ~BasicAxisItem();
 
-    std::unique_ptr<IAxis> createAxis(double scale = 1.0) const;
+    virtual std::unique_ptr<IAxis> createAxis(double scale) const;
 
 protected:
     void register_basic_properties();
diff --git a/GUI/coregui/Models/BeamAngleItems.cpp b/GUI/coregui/Models/BeamAngleItems.cpp
index 2dbd09c70bbf7bd363b0260d82294bdd90680133..284299c43118d8d9da5a66c7018cef87ba4e0654 100644
--- a/GUI/coregui/Models/BeamAngleItems.cpp
+++ b/GUI/coregui/Models/BeamAngleItems.cpp
@@ -20,7 +20,7 @@ BeamAzimuthalAngleItem::BeamAzimuthalAngleItem()
 {
     register_distribution_group(Constants::DistributionExtendedGroup);
 
-    SessionItem *valueItem = getGroupItem(P_DISTRIBUTION)->getItem(DistributionNoneItem::P_VALUE);
+    SessionItem *valueItem = getGroupItem(P_DISTRIBUTION)->getItem(DistributionNoneItem::P_MEAN);
     valueItem->setLimits(RealLimits::limited(-90.0, 90.0));
     valueItem->setDecimals(3);
     valueItem->setValue(0.0);
@@ -47,7 +47,7 @@ BeamInclinationAngleItem::BeamInclinationAngleItem()
 {
     register_distribution_group(Constants::DistributionExtendedGroup);
 
-    SessionItem *valueItem = getGroupItem(P_DISTRIBUTION)->getItem(DistributionNoneItem::P_VALUE);
+    SessionItem *valueItem = getGroupItem(P_DISTRIBUTION)->getItem(DistributionNoneItem::P_MEAN);
     valueItem->setLimits(RealLimits::limited(0.0, 90.0));
     valueItem->setDecimals(3);
     valueItem->setValue(0.2);
diff --git a/GUI/coregui/Models/BeamDistributionItem.cpp b/GUI/coregui/Models/BeamDistributionItem.cpp
index dc0a7ee257361c1c8d26012e6af5cc9f4f420f82..7759eb6925cd6f2d7095f51ba75f285141befd31 100644
--- a/GUI/coregui/Models/BeamDistributionItem.cpp
+++ b/GUI/coregui/Models/BeamDistributionItem.cpp
@@ -84,7 +84,10 @@ void BeamDistributionItem::initDistributionItem(bool show_mean)
 
     if (!distributionNone)
         return;
-    const RealLimits limits = distributionNone->getItem(DistributionNoneItem::P_VALUE)->limits();
+
+    const RealLimits limits = distributionNone->getItem(DistributionNoneItem::P_MEAN)->limits();
+    const QString editor_type =
+        distributionNone->getItem(DistributionNoneItem::P_MEAN)->editorType();
 
     for (auto item : groupItem->getItems(GroupItem::T_ITEMS)) {
         DistributionItem* distrItem = dynamic_cast<DistributionItem*>(item);
@@ -94,7 +97,11 @@ void BeamDistributionItem::initDistributionItem(bool show_mean)
             continue;
 
         distrItem->init_parameters(
-            distributionNone->getItemValue(DistributionNoneItem::P_VALUE).toDouble(), limits);
+            distributionNone->getItemValue(DistributionNoneItem::P_MEAN).toDouble(), limits);
+        if (auto symmetric_distr = dynamic_cast<SymmetricDistributionItem*>(distrItem))
+            symmetric_distr->getItem(SymmetricDistributionItem::P_MEAN)
+                ->setEditorType(editor_type)
+                .setLimits(limits);
 
         // hiding limits from the editor
         if (distrItem->isTag(DistributionItem::P_LIMITS))
@@ -110,7 +117,7 @@ double BeamDistributionItem::meanValue() const
     if (domainDistr)
         return domainDistr->getMean()/scaleFactor();
     else
-        return getGroupItem(P_DISTRIBUTION)->getItemValue(DistributionNoneItem::P_VALUE).toDouble();
+        return getGroupItem(P_DISTRIBUTION)->getItemValue(DistributionNoneItem::P_MEAN).toDouble();
 }
 
 void BeamDistributionItem::resetToValue(double value)
@@ -118,7 +125,7 @@ void BeamDistributionItem::resetToValue(double value)
     SessionItem* distributionItem = setGroupProperty(
         BeamDistributionItem::P_DISTRIBUTION, Constants::DistributionNoneType);
     Q_ASSERT(distributionItem);
-    distributionItem->setItemValue(DistributionNoneItem::P_VALUE, value);
+    distributionItem->setItemValue(DistributionNoneItem::P_MEAN, value);
 }
 
 //! Scales the values provided by distribution (to perform deg->rad conversion in the case
@@ -132,7 +139,7 @@ double BeamDistributionItem::scaleFactor() const
 void BeamDistributionItem::register_distribution_group(const QString& group_type)
 {
     Q_ASSERT(group_type == Constants::DistributionExtendedGroup
-             || group_type == Constants::DistributionWithZeroAverageGroup);
+             || group_type == Constants::SymmetricDistributionGroup);
     addGroupProperty(P_DISTRIBUTION, group_type);
 }
 
diff --git a/GUI/coregui/Models/BeamItems.cpp b/GUI/coregui/Models/BeamItems.cpp
index fd3aab175c902407a2e0d94f16ad6b91de1d1e42..f1c09dbf2f28c944d7a24bccce722fd6c8e36114 100644
--- a/GUI/coregui/Models/BeamItems.cpp
+++ b/GUI/coregui/Models/BeamItems.cpp
@@ -20,17 +20,24 @@
 #include "BeamWavelengthItem.h"
 #include "BornAgainNamespace.h"
 #include "FootprintItems.h"
+#include "GroupItem.h"
 #include "GUIHelpers.h"
+#include "IAxis.h"
 #include "ParameterTranslators.h"
+#include "PointwiseAxisItem.h"
 #include "SessionItemUtils.h"
 #include "SpecularBeamInclinationItem.h"
 #include "Units.h"
+#include <cmath>
 
 using SessionItemUtils::GetVectorItem;
 
 namespace
 {
 const QString polarization_tooltip = "Polarization of the beam, given as the Bloch vector";
+
+// defines wavelength limits according to given maximum q value
+RealLimits getLimits(double max_q);
 }
 
 const QString BeamItem::P_INTENSITY = QString::fromStdString(BornAgain::Intensity);
@@ -46,7 +53,6 @@ BeamItem::BeamItem(const QString& beam_model) : SessionItem(beam_model)
         .setToolTip("Beam intensity in neutrons (or gammas) per sec.")
         .setEditorType(Constants::ScientificEditorType);
 
-    addGroupProperty(P_WAVELENGTH, Constants::BeamWavelengthType);
     addGroupProperty(P_AZIMUTHAL_ANGLE, Constants::BeamAzimuthalAngleType);
     addGroupProperty(P_POLARIZATION, Constants::VectorType)->setToolTip(polarization_tooltip);
 
@@ -120,6 +126,11 @@ void BeamItem::setInclinationProperty(const QString& inclination_type)
     addGroupProperty(P_INCLINATION_ANGLE, inclination_type);
 }
 
+void BeamItem::setWavelengthProperty(const QString& wavelength_type)
+{
+    addGroupProperty(P_WAVELENGTH, wavelength_type);
+}
+
 // Specular beam item
 /* ------------------------------------------------------------------------- */
 
@@ -130,19 +141,33 @@ const QString footprint_group_label("Type");
 SpecularBeamItem::SpecularBeamItem() : BeamItem(Constants::SpecularBeamType)
 {
     setInclinationProperty(Constants::SpecularBeamInclinationType);
+    setWavelengthProperty(Constants::SpecularBeamWavelengthType);
+
+    getItem(P_AZIMUTHAL_ANGLE)->setVisible(false);
+    getItem(P_POLARIZATION)->setVisible(false);
 
     auto item = addGroupProperty(P_FOOPTPRINT, Constants::FootprintGroup);
     item->setDisplayName(footprint_group_label);
     item->setToolTip("Footprint type");
+
+    getItem(P_WAVELENGTH)
+        ->mapper()
+        ->setOnChildPropertyChange(
+            [this](SessionItem*, QString property) {
+                if (property != SymmetricDistributionItem::P_MEAN)
+                    return;
+                if (auto axis_item = dynamic_cast<PointwiseAxisItem*>(currentInclinationAxisItem()))
+                    axis_item->updateIndicators();
+            },
+            this);
+
+    inclinationAxisGroup()->mapper()->setOnValueChange([this]() { updateWavelength(); }, this);
 }
 
 SpecularBeamItem::~SpecularBeamItem() = default;
 
 double SpecularBeamItem::getInclinationAngle() const
 {
-    Q_ASSERT(
-        dynamic_cast<BeamDistributionItem*>(getItem(P_INCLINATION_ANGLE))->meanValue()
-        == 0.0);
     return 0.0;
 }
 
@@ -153,10 +178,15 @@ void SpecularBeamItem::setInclinationAngle(double value)
     BeamItem::setInclinationAngle(value);
 }
 
-BasicAxisItem& SpecularBeamItem::getInclinationAngleAxis()
+GroupItem* SpecularBeamItem::inclinationAxisGroup()
 {
-    return getItem(BeamItem::P_INCLINATION_ANGLE)
-        ->item<BasicAxisItem>(SpecularBeamInclinationItem::P_ALPHA_AXIS);
+    return dynamic_cast<GroupItem*>(
+        getItem(P_INCLINATION_ANGLE)->getItem(SpecularBeamInclinationItem::P_ALPHA_AXIS));
+}
+
+BasicAxisItem* SpecularBeamItem::currentInclinationAxisItem()
+{
+    return dynamic_cast<BasicAxisItem*>(inclinationAxisGroup()->currentItem());
 }
 
 FootprintItem* SpecularBeamItem::currentFootprintItem() const
@@ -164,12 +194,47 @@ FootprintItem* SpecularBeamItem::currentFootprintItem() const
     return &groupItem<FootprintItem>(P_FOOPTPRINT);
 }
 
+void SpecularBeamItem::updateFileName(const QString& filename)
+{
+    item<SpecularBeamInclinationItem>(BeamItem::P_INCLINATION_ANGLE).updateFileName(filename);
+}
+
+void SpecularBeamItem::updateToData(const IAxis& axis, QString units)
+{
+    if (units == Constants::UnitsNbins) {
+        inclinationAxisGroup()->setCurrentType(Constants::BasicAxisType);
+        auto axis_item = currentInclinationAxisItem();
+        axis_item->setItemValue(BasicAxisItem::P_NBINS, static_cast<int>(axis.size()));
+        return;
+    }
+
+    auto axis_group = inclinationAxisGroup();
+    auto axis_item =
+        static_cast<PointwiseAxisItem*>(axis_group->getChildOfType(Constants::PointwiseAxisType));
+    axis_item->init(axis, units);
+    axis_group->setCurrentType(Constants::PointwiseAxisType); // calls updateWavelength()
+    axis_item->updateIndicators();
+}
+
+void SpecularBeamItem::updateWavelength()
+{
+    auto item = inclinationAxisGroup()->currentItem();
+    auto wl_item = static_cast<SpecularBeamWavelengthItem*>(getItem(P_WAVELENGTH));
+    if (auto axis_item = dynamic_cast<PointwiseAxisItem*>(item)) {
+        auto axis = axis_item->getAxis();
+        if (axis && axis_item->getUnitsLabel() == Constants::UnitsQyQz)
+            wl_item->setToRange(getLimits(axis->getMax()));
+    } else
+        wl_item->setToRange(RealLimits::positive());
+}
+
 // GISAS beam item
 /* ------------------------------------------------------------------------- */
 
 GISASBeamItem::GISASBeamItem() : BeamItem(Constants::GISASBeamType)
 {
     setInclinationProperty(Constants::BeamInclinationAngleType);
+    setWavelengthProperty(Constants::BeamWavelengthType);
 }
 
 GISASBeamItem::~GISASBeamItem() = default;
@@ -181,3 +246,14 @@ double GISASBeamItem::getInclinationAngle() const
     Q_ASSERT(inclination);
     return inclination->inclinationAngle();
 }
+
+namespace
+{
+RealLimits getLimits(double max_q)
+{
+    double upper_lim = std::nextafter(4.0 * M_PI / max_q, 0.0);
+    RealLimits result = RealLimits::positive();
+    result.setUpperLimit(upper_lim);
+    return result;
+}
+}
diff --git a/GUI/coregui/Models/BeamItems.h b/GUI/coregui/Models/BeamItems.h
index 6af8d8a8012a04b0a20dc39afa770896513b4ba0..e3605f487354770568318c49932a74a3d4b1e531 100644
--- a/GUI/coregui/Models/BeamItems.h
+++ b/GUI/coregui/Models/BeamItems.h
@@ -20,6 +20,8 @@
 class BasicAxisItem;
 class Beam;
 class FootprintItem;
+class GroupItem;
+class IAxis;
 
 class BA_CORE_API_ BeamItem : public SessionItem
 {
@@ -50,6 +52,7 @@ protected:
     explicit BeamItem(const QString& beam_model);
 
     void setInclinationProperty(const QString& inclination_type);
+    void setWavelengthProperty(const QString& wavelength_type);
 };
 
 class BA_CORE_API_ SpecularBeamItem : public BeamItem
@@ -63,8 +66,15 @@ public:
     double getInclinationAngle() const override;
     void setInclinationAngle(double value) override;
 
-    BasicAxisItem& getInclinationAngleAxis();
+    GroupItem* inclinationAxisGroup();
+    BasicAxisItem* currentInclinationAxisItem();
     FootprintItem* currentFootprintItem() const;
+
+    void updateFileName(const QString& filename);
+    void updateToData(const IAxis& axis, QString units);
+
+private:
+    void updateWavelength();
 };
 
 class BA_CORE_API_ GISASBeamItem : public BeamItem
diff --git a/GUI/coregui/Models/BeamWavelengthItem.cpp b/GUI/coregui/Models/BeamWavelengthItem.cpp
index 8e9ee464d26c9dc99e20f44e9b541185879e61ef..cb0ce9614205028e9eedb33921a9262cd8f77026 100644
--- a/GUI/coregui/Models/BeamWavelengthItem.cpp
+++ b/GUI/coregui/Models/BeamWavelengthItem.cpp
@@ -14,15 +14,20 @@
 
 #include "BeamWavelengthItem.h"
 
-BeamWavelengthItem::BeamWavelengthItem()
-    : BeamDistributionItem(Constants::BeamWavelengthType, m_show_mean)
+namespace {
+const double default_wl = 0.1;
+}
+
+BeamWavelengthItem::BeamWavelengthItem(const QString& model_type,const QString& distribution_group)
+    : BeamDistributionItem(model_type, m_show_mean)
 {
-    register_distribution_group(Constants::DistributionExtendedGroup);
+    register_distribution_group(distribution_group);
 
-    SessionItem *valueItem = getGroupItem(P_DISTRIBUTION)->getItem(DistributionNoneItem::P_VALUE);
+    SessionItem *valueItem = getGroupItem(P_DISTRIBUTION)->getItem(DistributionNoneItem::P_MEAN);
     valueItem->setLimits(RealLimits::positive());
     valueItem->setDecimals(4);
-    valueItem->setValue(0.1);
+    valueItem->setValue(default_wl);
+    valueItem->setEditorType(Constants::ScientificSpinBoxType);
 
     initDistributionItem(m_show_mean);
 }
@@ -33,3 +38,21 @@ double BeamWavelengthItem::wavelength() const
 {
     return BeamDistributionItem::meanValue();
 }
+
+SpecularBeamWavelengthItem::SpecularBeamWavelengthItem()
+    : BeamWavelengthItem(Constants::SpecularBeamWavelengthType,
+                         Constants::SymmetricDistributionGroup)
+{}
+
+void SpecularBeamWavelengthItem::setToRange(const RealLimits& limits)
+{
+    SessionItem* valueItem =
+        getGroupItem(P_DISTRIBUTION)->getItem(SymmetricDistributionItem::P_MEAN);
+    if (!limits.isInRange(wavelength())) {
+        const double new_value = limits.isLimited()
+                ? (limits.upperLimit() - limits.lowerLimit()) / 2.
+                : default_wl;
+        valueItem->setValue(new_value);
+    }
+    valueItem->setLimits(limits);
+}
diff --git a/GUI/coregui/Models/BeamWavelengthItem.h b/GUI/coregui/Models/BeamWavelengthItem.h
index 6471daf5f294013b63376f38d3e3461b712bdbe5..687225180d96531f718a069ff4689b33355d48f3 100644
--- a/GUI/coregui/Models/BeamWavelengthItem.h
+++ b/GUI/coregui/Models/BeamWavelengthItem.h
@@ -20,7 +20,8 @@
 class BA_CORE_API_ BeamWavelengthItem : public BeamDistributionItem
 {
 public:
-    BeamWavelengthItem();
+    BeamWavelengthItem(const QString& model_type = Constants::BeamWavelengthType,
+                       const QString& distribution_group = Constants::DistributionExtendedGroup);
 
     double wavelength() const;
 
@@ -28,4 +29,11 @@ private:
     static const bool m_show_mean = true;
 };
 
+class BA_CORE_API_ SpecularBeamWavelengthItem : public BeamWavelengthItem
+{
+public:
+    SpecularBeamWavelengthItem();
+    void setToRange(const RealLimits& limits);
+};
+
 #endif // BEAMWAVELENGTHITEM_H
diff --git a/GUI/coregui/Models/ComboProperty.cpp b/GUI/coregui/Models/ComboProperty.cpp
index d04d103c469178f4959eb894868ac76068a5fe48..c9d8a3f49a71718e82e66000caeb4e3622b2d1ec 100644
--- a/GUI/coregui/Models/ComboProperty.cpp
+++ b/GUI/coregui/Models/ComboProperty.cpp
@@ -15,22 +15,32 @@
 #include "ComboProperty.h"
 #include "GUIHelpers.h"
 
-ComboProperty::ComboProperty()
-    : m_current_index(-1)
-{}
+namespace {
+const QString value_separator = ";";
+const QString selection_separator = ",";
+}
+
+ComboProperty::ComboProperty() = default;
 
-ComboProperty::ComboProperty(const QStringList& values, const QString& current_value)
-    : m_values(values), m_current_index(-1)
+ComboProperty::ComboProperty(QStringList values)
+    : m_values(std::move(values))
 {
-    if (!m_values.contains(current_value))
-        throw GUIHelpers::Error("ComboProperty::ComboProperty() -> Error. Attempt to construct "
-                                "property with initial values not from the list.");
-    m_current_index = m_values.indexOf((current_value));
+
+}
+
+ComboProperty ComboProperty::fromList(const QStringList& values, const QString& current_value)
+{
+    ComboProperty result(values);
+
+    if (!current_value.isEmpty())
+        result.setValue(current_value);
+
+    return result;
 }
 
 QString ComboProperty::getValue() const
 {
-    return m_current_index < 0 ? QString() : m_values.at(m_current_index);
+    return currentIndex() < 0 ? QString() : m_values.at(currentIndex());
 }
 
 void ComboProperty::setValue(const QString& name)
@@ -38,7 +48,7 @@ void ComboProperty::setValue(const QString& name)
     if (!m_values.contains(name))
         throw GUIHelpers::Error("ComboProperty::setValue() -> Error. Combo doesn't contain "
                                 "value " + name);
-    m_current_index = m_values.indexOf(name);
+    setCurrentIndex(m_values.indexOf(name));
 }
 
 QStringList ComboProperty::getValues() const
@@ -53,7 +63,7 @@ void ComboProperty::setValues(const QStringList& values)
     Q_ASSERT(values.size());
     QString current = getValue();
     m_values = values;
-    m_current_index = m_values.contains(current) ? m_values.indexOf(current) : 0;
+   setCurrentIndex(m_values.contains(current) ? m_values.indexOf(current) : 0);
 }
 
 //! returns list of tool tips for all values
@@ -69,36 +79,37 @@ void ComboProperty::setToolTips(const QStringList& tooltips)
 
 int ComboProperty::currentIndex() const
 {
-    return m_current_index;
+    return m_selected_indices.empty() ? -1 : m_selected_indices.at(0);
 }
 
 void ComboProperty::setCurrentIndex(int index)
 {
-    if(index <0 || index >= m_values.size())
+    if (index < 0 || index >= m_values.size())
         throw GUIHelpers::Error("ComboProperty::setCurrentIndex(int index) -> Error. "
                                 "Invalid index");
-    m_current_index = index;
+    m_selected_indices.clear();
+    m_selected_indices.push_back(index);
 }
 
-ComboProperty&ComboProperty::operator<<(const QString& str)
+ComboProperty& ComboProperty::operator<<(const QString& str)
 {
     m_values.append(str);
     if (m_values.size())
-        m_current_index = 0;
+        setCurrentIndex(0);
     return *this;
 }
 
-ComboProperty&ComboProperty::operator<<(const QStringList& str)
+ComboProperty& ComboProperty::operator<<(const QStringList& str)
 {
     m_values.append(str);
     if (m_values.size())
-        m_current_index = 0;
+        setCurrentIndex(0);
     return *this;
 }
 
 bool ComboProperty::operator==(const ComboProperty& other) const
 {
-    if (m_current_index != other.m_current_index)
+    if (m_selected_indices != other.m_selected_indices)
         return false;
     if (m_values != other.m_values)
         return false;
@@ -112,14 +123,14 @@ bool ComboProperty::operator!=(const ComboProperty& other) const
 
 bool ComboProperty::operator<(const ComboProperty& other) const
 {
-    return m_current_index < other.m_current_index && m_values.size() < other.m_values.size();
+    return m_selected_indices.size() < other.m_selected_indices.size() && m_values.size() < other.m_values.size();
 }
 
 //! Returns a single string containing values delimited with ';'.
 
 QString ComboProperty::stringOfValues() const
 {
-    return m_values.join(QStringLiteral(";"));
+    return m_values.join(value_separator);
 }
 
 //! Sets values from the string containing delimeter ';'.
@@ -127,13 +138,94 @@ QString ComboProperty::stringOfValues() const
 void ComboProperty::setStringOfValues(const QString& values)
 {
     QString current = getValue();
-    m_values = values.split(QStringLiteral(";"));
-    m_current_index = m_values.contains(current) ? m_values.indexOf(current) : 0;
+    m_values = values.split(value_separator);
+    setCurrentIndex(m_values.contains(current) ? m_values.indexOf(current) : 0);
 }
 
+//! Constructs variant enclosing given ComboProperty.
+
 QVariant ComboProperty::variant() const
 {
     QVariant result;
     result.setValue(*this);
     return result;
 }
+
+//! Returns vector of selected indices.
+
+QVector<int> ComboProperty::selectedIndices() const
+{
+    return m_selected_indices;
+}
+
+//! Returns list of string with selected values;
+
+QStringList ComboProperty::selectedValues() const
+{
+    QStringList result;
+    for (auto index : m_selected_indices)
+        result.append(m_values.at(index));
+    return result;
+}
+
+//! Sets given index selection flag.
+//! If false, index will be excluded from selection.
+
+void ComboProperty::setSelected(int index, bool value)
+{
+    if (index < 0 || index >= m_values.size())
+        return;
+
+    if (value) {
+        if (!m_selected_indices.contains(index))
+            m_selected_indices.push_back(index);
+    } else {
+        m_selected_indices.removeAll(index);
+    }
+    std::sort(m_selected_indices.begin(), m_selected_indices.end());
+}
+
+void ComboProperty::setSelected(const QString& name, bool value)
+{
+    setSelected(m_values.indexOf(name), value);
+}
+
+//! Return string with coma separated list of selected indices.
+
+QString ComboProperty::stringOfSelections() const
+{
+    QStringList text;
+    for (auto  index : m_selected_indices)
+        text.append(QString::number(index));
+    return text.join(selection_separator);
+}
+
+//! Sets selected indices from string.
+
+void ComboProperty::setStringOfSelections(const QString& values)
+{
+    m_selected_indices.clear();
+    if (values.isEmpty())
+        return;
+
+    for (auto str : values.split(selection_separator)) {
+        bool success(false);
+        int num = str.toInt(&success);
+        if (success)
+            setSelected(num, true);
+    }
+}
+
+//! Returns the label to show
+
+QString ComboProperty::label() const
+{
+    if (m_selected_indices.size() >1) {
+        return QStringLiteral("Multiple");
+    } else if (m_selected_indices.size() == 1) {
+        return getValue();
+    } else {
+        return QStringLiteral("None");
+    }
+}
+
diff --git a/GUI/coregui/Models/ComboProperty.h b/GUI/coregui/Models/ComboProperty.h
index 54373741cc719c4e31926ffb16ef7bf6722b6534..28ded10735e0bee0b25d517f2122c4b4f9084642 100644
--- a/GUI/coregui/Models/ComboProperty.h
+++ b/GUI/coregui/Models/ComboProperty.h
@@ -18,14 +18,18 @@
 #include "WinDllMacros.h"
 #include <QStringList>
 #include <QVariant>
+#include <QVector>
 
-//! The ComboProperty defines SessionItem's property with a value from predefined list.
+//! Custom property to define list of string values with multiple selections.
+//! Intended for QVariant.
 
 class BA_CORE_API_ ComboProperty
 {
 public:
     ComboProperty();
-    ComboProperty(const QStringList& values, const QString& current_value);
+
+    static ComboProperty fromList(const QStringList& values,
+                                  const QString& current_value = QString());
 
     QString getValue() const;
     void setValue(const QString& name);
@@ -50,10 +54,23 @@ public:
 
     QVariant variant() const;
 
+    QVector<int> selectedIndices() const;
+    QStringList selectedValues() const;
+
+    void setSelected(int index, bool value = true);
+    void setSelected(const QString& name, bool value = true);
+
+    QString stringOfSelections() const;
+    void setStringOfSelections(const QString& values);
+
+    QString label() const;
+
 private:
+    ComboProperty(QStringList values);
+
     QStringList m_values;
     QStringList m_tooltips;
-    int m_current_index;
+    QVector<int> m_selected_indices;
 };
 
 Q_DECLARE_METATYPE(ComboProperty)
diff --git a/GUI/coregui/Models/DataItem.cpp b/GUI/coregui/Models/DataItem.cpp
index 82da59fd5d3f59a14b552c3ff3398db4f3bdcc82..ae6e468af5f932526d9bc8e40b9cf5bdae412465 100644
--- a/GUI/coregui/Models/DataItem.cpp
+++ b/GUI/coregui/Models/DataItem.cpp
@@ -16,6 +16,7 @@
 #include "BornAgainNamespace.h"
 #include "ComboProperty.h"
 #include "GUIHelpers.h"
+#include "ImportDataInfo.h"
 #include "IntensityDataIOFactory.h"
 
 const QString DataItem::P_FILE_NAME = "FileName";
@@ -37,10 +38,9 @@ void DataItem::setRawDataVector(std::vector<double> data)
     emitDataChanged();
 }
 
-QString DataItem::fileName(const QString& projectDir) const
+QString DataItem::fileName() const
 {
-    QString filename = getItemValue(DataItem::P_FILE_NAME).toString();
-    return projectDir.isEmpty() ? filename : projectDir + QStringLiteral("/") + filename;
+    return getItemValue(DataItem::P_FILE_NAME).toString();
 }
 
 QDateTime DataItem::lastModified() const
@@ -48,34 +48,42 @@ QDateTime DataItem::lastModified() const
     return m_last_modified;
 }
 
-void DataItem::setLastModified(const QDateTime& dtime)
+bool DataItem::containsNonXMLData() const
 {
-    m_last_modified = dtime;
+    return static_cast<bool>(m_data);
 }
 
-QString DataItem::selectedAxesUnits() const
+bool DataItem::load(const QString &projectDir)
 {
-    ComboProperty combo = getItemValue(DataItem::P_AXES_UNITS).value<ComboProperty>();
-    return combo.getValue();
+    QString filename = fileName(projectDir);
+    auto data = IntensityDataIOFactory::readOutputData(filename.toStdString());
+    if (!data)
+        return false;
+    setOutputData(data);
+    return true;
 }
 
-void DataItem::saveData(const QString& projectDir)
+bool DataItem::save(const QString& projectDir)
 {
-    if (!getOutputData())
-        return;
+    if (!containsNonXMLData())
+        return false;
 
     std::unique_lock<std::mutex> lock(m_update_data_mutex);
     std::unique_ptr<OutputData<double>> clone(getOutputData()->clone());
     lock.unlock();
-    IntensityDataIOFactory::writeOutputData(*clone,
-                                            fileName(projectDir).toStdString());
+    IntensityDataIOFactory::writeOutputData(*clone, fileName(projectDir).toStdString());
+    return true;
 }
 
-void DataItem::resetToDefault()
+void DataItem::setLastModified(const QDateTime& dtime)
 {
-    ComboProperty combo = ComboProperty() << Constants::UnitsNbins;
-    setItemValue(DataItem::P_AXES_UNITS, combo.variant());
-    getItem(DataItem::P_AXES_UNITS)->setVisible(true);
+    m_last_modified = dtime;
+}
+
+QString DataItem::selectedAxesUnits() const
+{
+    ComboProperty combo = getItemValue(DataItem::P_AXES_UNITS).value<ComboProperty>();
+    return combo.getValue();
 }
 
 DataItem::DataItem(const QString& modelType) : SessionItem(modelType)
diff --git a/GUI/coregui/Models/DataItem.h b/GUI/coregui/Models/DataItem.h
index d8ea6b9c4f7592dddcaf05a57d2b740e829db16e..532d40765b96a64a5416771473ccbc146a6f6e64 100644
--- a/GUI/coregui/Models/DataItem.h
+++ b/GUI/coregui/Models/DataItem.h
@@ -15,16 +15,18 @@
 #ifndef DATAITEM_H
 #define DATAITEM_H
 
+#include "SaveLoadInterface.h"
 #include "SessionItem.h"
 #include "OutputData.h"
 #include <QDateTime>
 #include <mutex>
 
+class ImportDataInfo;
 class InstrumentItem;
 
 //! Provides common functionality for IntensityDataItem and SpecularDataItem
 
-class BA_CORE_API_ DataItem : public SessionItem
+class BA_CORE_API_ DataItem : public SessionItem, public SaveLoadInterface
 {
 public:
     static const QString P_FILE_NAME;
@@ -39,9 +41,13 @@ public:
     //! no dimension checks are applied.
     void setRawDataVector(std::vector<double> data);
 
-    QString fileName(const QString& projectDir = QString()) const;
+    using SaveLoadInterface::fileName;
+    QString fileName() const override;
+    QDateTime lastModified() const override;
+    bool containsNonXMLData() const override;
+    bool load(const QString& projectDir) override;
+    bool save(const QString& projectDir) override;
 
-    QDateTime lastModified() const;
     void setLastModified(const QDateTime& dtime);
 
     QString selectedAxesUnits() const;
@@ -52,10 +58,9 @@ public:
     virtual void updateAxesUnits(const InstrumentItem* instrument) = 0;
     virtual std::vector<int> shape() const = 0;
 
-    //! Returns data to default state (no dimensional units, default axes' names)
-    virtual void resetToDefault() = 0;
-
-    void saveData(const QString& projectDir);
+    //! Returns data to the state defined by user (imported)
+    //! data.
+    virtual void reset(ImportDataInfo data) = 0;
 
 protected:
     DataItem(const QString& modelType);
diff --git a/GUI/coregui/Models/DataViewUtils.cpp b/GUI/coregui/Models/DataViewUtils.cpp
index cbe30c9cdf32bcf85175572a6e0c73efcf6e7fc2..5ad35437dd75c3630551782a4ff09ca86ac37731 100644
--- a/GUI/coregui/Models/DataViewUtils.cpp
+++ b/GUI/coregui/Models/DataViewUtils.cpp
@@ -1,31 +1,13 @@
 #include "DataViewUtils.h"
-#include "ComboProperty.h"
 #include "DataItem.h"
 #include "Data1DViewItem.h"
 #include "DomainObjectBuilder.h"
-#include "GUIHelpers.h"
-#include "InstrumentItems.h"
-#include "IUnitConverter.h"
 #include "JobItem.h"
-#include "OutputData.h"
+#include "JobItemUtils.h"
 #include "DataPropertyContainer.h"
-#include "RealDataItem.h"
-#include "SessionModel.h"
 #include "UnitConverterUtils.h"
 
 namespace {
-const QMap<QString, AxesUnits> units_from_names{{Constants::UnitsNbins, AxesUnits::NBINS},
-                                                {Constants::UnitsRadians, AxesUnits::RADIANS},
-                                                {Constants::UnitsDegrees, AxesUnits::DEGREES},
-                                                {Constants::UnitsMm, AxesUnits::MM},
-                                                {Constants::UnitsQyQz, AxesUnits::QSPACE}};
-
-const QMap<AxesUnits, QString> names_from_units{{AxesUnits::NBINS, Constants::UnitsNbins},
-                                                {AxesUnits::RADIANS, Constants::UnitsRadians},
-                                                {AxesUnits::MM, Constants::UnitsMm},
-                                                {AxesUnits::QSPACE, Constants::UnitsQyQz},
-                                                {AxesUnits::DEGREES, Constants::UnitsDegrees}};
-
 std::unique_ptr<IUnitConverter> getConverter(Data1DViewItem* view_item)
 {
     auto job_item = view_item->jobItem();
@@ -38,51 +20,15 @@ AxesUnits selectedUnits(Data1DViewItem* view_item)
 {
     auto current_unit_name
         = view_item->getItemValue(Data1DViewItem::P_AXES_UNITS).value<ComboProperty>().getValue();
-    return units_from_names[current_unit_name];
-}
-
-ComboProperty availableUnits(const IUnitConverter* converter)
-{
-    assert(converter);
-
-    ComboProperty result;
-    for (auto units : converter->availableUnits())
-        result << names_from_units[units];
-
-    result.setValue(names_from_units[converter->defaultUnits()]);
-    return result;
+    return JobItemUtils::axesUnitsFromName(current_unit_name);
 }
 }
 
-void DataViewUtils::initDataView(JobItem* job_item)
-{
-    assert(job_item && job_item->isValidForFitting());
-    assert(job_item->instrumentItem()
-           && job_item->instrumentItem()->modelType() == Constants::SpecularInstrumentType);
-    assert(!job_item->getItem(JobItem::T_DATAVIEW));
-
-    SessionModel* model = job_item->model();
-    auto view_item = dynamic_cast<Data1DViewItem*>(model->insertNewItem(
-        Constants::Data1DViewItemType, job_item->index(), -1, JobItem::T_DATAVIEW));
-    assert(view_item);
-
-    auto property_container = dynamic_cast<DataPropertyContainer*>(model->insertNewItem(
-        Constants::DataPropertyContainerType, view_item->index(), -1, Data1DViewItem::T_DATA_PROPERTIES));
-    assert(property_container);
-
-    property_container->addItem(job_item->realDataItem()->dataItem());
-    property_container->addItem(job_item->dataItem());
-
-    // also triggers Data1DViewItem::setAxesRangeToData and DataViewUtils::updateAxesTitle by
-    // setting new value of P_AXES_UNITS.
-    auto converter = DomainObjectBuilder::createUnitConverter(job_item->instrumentItem());
-    view_item->setItemValue(Data1DViewItem::P_AXES_UNITS,
-                            availableUnits(converter.get()).variant());
-}
-
 void DataViewUtils::updateAxesTitle(Data1DViewItem* view_item)
 {
     auto converter = getConverter(view_item);
+    if (!converter)
+        return;
     auto current_units = selectedUnits(view_item);
     view_item->setXaxisTitle(QString::fromStdString(converter->axisName(0, current_units)));
     if (converter->dimension() > 1)
diff --git a/GUI/coregui/Models/DataViewUtils.h b/GUI/coregui/Models/DataViewUtils.h
index 019f01b8c30493f6aad2daeeb26bf2c9833cecdf..229c5300bcca889d8de7a282f379ab73c62042ed 100644
--- a/GUI/coregui/Models/DataViewUtils.h
+++ b/GUI/coregui/Models/DataViewUtils.h
@@ -15,6 +15,8 @@
 #ifndef DATAVIEWUTILS_H
 #define DATAVIEWUTILS_H
 
+#include "IUnitConverter.h"
+#include <QString>
 #include <memory>
 
 class DataItem;
@@ -24,9 +26,6 @@ template<class T> class OutputData;
 
 namespace DataViewUtils
 {
-//! Initializes Data1DViewItem and assigns it to the passed JobItem
-void initDataView(JobItem* jobItem);
-
 void updateAxesTitle(Data1DViewItem* view_item);
 
 std::unique_ptr<OutputData<double>> getTranslatedData(Data1DViewItem* view_item,
diff --git a/GUI/coregui/Models/DepthProbeInstrumentItem.cpp b/GUI/coregui/Models/DepthProbeInstrumentItem.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..24b71b99352f213ee5a8c9a74e5a2ad56289916e
--- /dev/null
+++ b/GUI/coregui/Models/DepthProbeInstrumentItem.cpp
@@ -0,0 +1,100 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Models/DepthProbeInstrumentItem.cpp
+//! @brief     Implements DepthProbeInstrumentItem class
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "DepthProbeInstrumentItem.h"
+#include "AxesItems.h"
+#include "BeamDistributionItem.h"
+#include "BeamWavelengthItem.h"
+#include "DepthProbeSimulation.h"
+#include "SimpleUnitConverters.h"
+#include "SpecularBeamInclinationItem.h"
+#include "TransformToDomain.h"
+#include "Units.h"
+
+const QString DepthProbeInstrumentItem::P_BEAM = "Beam";
+const QString DepthProbeInstrumentItem::P_ZAXIS = "Z axis";
+
+DepthProbeInstrumentItem::DepthProbeInstrumentItem()
+    : InstrumentItem(Constants::DepthProbeInstrumentType)
+{
+    setItemName(Constants::DepthProbeInstrumentType);
+
+    addGroupProperty(P_BEAM, Constants::SpecularBeamType);
+
+    auto axisItem = beamItem()->currentInclinationAxisItem();
+    axisItem->setItemValue(BasicAxisItem::P_MIN, 0.0);
+    axisItem->setItemValue(BasicAxisItem::P_MAX, 1.0);
+    axisItem->setItemValue(BasicAxisItem::P_NBINS, 500);
+
+    auto axis = addGroupProperty(P_ZAXIS, Constants::BasicAxisType);
+    axis->getItem(BasicAxisItem::P_TITLE)->setVisible(false);
+    axis->setItemValue(BasicAxisItem::P_MIN, -100.0);
+    axis->setItemValue(BasicAxisItem::P_MAX, 100.0);
+    axis->getItem(BasicAxisItem::P_NBINS)
+        ->setToolTip("Number of points in scan across sample bulk");
+    axis->getItem(BasicAxisItem::P_MIN)->setToolTip("Starting value below sample horizont in nm");
+    axis->getItem(BasicAxisItem::P_MAX)->setToolTip("Ending value above sample horizont in nm");
+}
+
+SpecularBeamItem* DepthProbeInstrumentItem::beamItem() const
+{
+    return &item<SpecularBeamItem>(P_BEAM);
+}
+
+std::unique_ptr<Instrument> DepthProbeInstrumentItem::createInstrument() const
+{
+    throw std::runtime_error("DepthProbeInstrumentItem::createInstrument()");
+}
+
+std::vector<int> DepthProbeInstrumentItem::shape() const
+{
+    return std::vector<int>(); // no certain shape to avoid linking to real data
+}
+
+void DepthProbeInstrumentItem::updateToRealData(const RealDataItem*)
+{
+    throw std::runtime_error("DepthProbeInstrumentItem::updateToRealData()");
+}
+
+std::unique_ptr<DepthProbeSimulation> DepthProbeInstrumentItem::createSimulation() const
+{
+    std::unique_ptr<DepthProbeSimulation> simulation = std::make_unique<DepthProbeSimulation>();
+
+    const auto axis_item = beamItem()->currentInclinationAxisItem();
+
+    auto axis = axis_item->createAxis(Units::degree);
+
+    simulation->setBeamParameters(beamItem()->getWavelength(), static_cast<int>(axis->size()),
+                                  axis->getMin(), axis->getMax());
+
+    auto depthAxisItem = dynamic_cast<BasicAxisItem*>(getItem(P_ZAXIS));
+    auto depthAxis = depthAxisItem->createAxis(1.0);
+    simulation->setZSpan(depthAxis->size(), depthAxis->getMin(), depthAxis->getMax());
+
+    TransformToDomain::setBeamDistribution(
+        BornAgain::Wavelength, beamItem()->item<BeamWavelengthItem>(SpecularBeamItem::P_WAVELENGTH),
+        *simulation.get());
+
+    TransformToDomain::setBeamDistribution(
+        BornAgain::Inclination,
+        beamItem()->item<SpecularBeamInclinationItem>(SpecularBeamItem::P_INCLINATION_ANGLE),
+        *simulation.get());
+
+    return simulation;
+}
+
+std::unique_ptr<IUnitConverter> DepthProbeInstrumentItem::createUnitConverter() const
+{
+    return createSimulation()->createUnitConverter();
+}
diff --git a/GUI/coregui/Models/DepthProbeInstrumentItem.h b/GUI/coregui/Models/DepthProbeInstrumentItem.h
new file mode 100644
index 0000000000000000000000000000000000000000..13a63d9109ad12a11c88053e2443d94cc0731b93
--- /dev/null
+++ b/GUI/coregui/Models/DepthProbeInstrumentItem.h
@@ -0,0 +1,45 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Models/DepthProbeInstrumentItem.h
+//! @brief     Defines DepthProbeInstrumentItem class
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef DEPTHPROBEINSTRUMENTITEM_H
+#define DEPTHPROBEINSTRUMENTITEM_H
+
+#include "InstrumentItems.h"
+
+class DepthProbeSimulation;
+
+//! Depth probe instrument.
+
+class BA_CORE_API_ DepthProbeInstrumentItem : public InstrumentItem
+{
+public:
+    static const QString P_BEAM;
+    static const QString P_ZAXIS;
+
+    DepthProbeInstrumentItem();
+
+    SpecularBeamItem* beamItem() const override;
+
+    std::unique_ptr<Instrument> createInstrument() const override;
+    std::vector<int> shape() const override;
+    void updateToRealData(const RealDataItem* item) override;
+
+    // FIXME switch to base Simulation class after InstrumentItem refactoring and
+    // after Simulation gets createUnitConverter method
+    std::unique_ptr<DepthProbeSimulation> createSimulation() const;
+
+    std::unique_ptr<IUnitConverter> createUnitConverter() const;
+};
+
+#endif
diff --git a/GUI/coregui/Models/DistributionItems.cpp b/GUI/coregui/Models/DistributionItems.cpp
index b8e422e0f84b253611e53deb5bf91fc97a911069..418961a28b738cbc9451792e26e71d470e70bf1a 100644
--- a/GUI/coregui/Models/DistributionItems.cpp
+++ b/GUI/coregui/Models/DistributionItems.cpp
@@ -88,12 +88,25 @@ void DistributionItem::register_limits()
 
 // --------------------------------------------------------------------------------------------- //
 
-const QString DistributionNoneItem::P_VALUE = "Value";
+const QString SymmetricDistributionItem::P_MEAN = QString::fromStdString(BornAgain::Mean);
 
-DistributionNoneItem::DistributionNoneItem() : DistributionItem(Constants::DistributionNoneType)
+SymmetricDistributionItem::SymmetricDistributionItem(const QString& name)
+    :DistributionItem(name)
 {
-    addProperty(P_VALUE, 0.1)->setLimits(RealLimits::limitless());
-    getItem(P_VALUE)->setDecimals(4);
+}
+
+void SymmetricDistributionItem::showMean(bool flag)
+{
+    getItem(P_MEAN)->setVisible(flag);
+}
+
+// --------------------------------------------------------------------------------------------- //
+
+DistributionNoneItem::DistributionNoneItem()
+    : SymmetricDistributionItem(Constants::DistributionNoneType)
+{
+    addProperty(P_MEAN, 0.1)->setLimits(RealLimits::limitless()).setDisplayName("Value");
+    getItem(P_MEAN)->setDecimals(4);
 }
 
 std::unique_ptr<IDistribution1D> DistributionNoneItem::createDistribution(double scale) const
@@ -104,12 +117,7 @@ std::unique_ptr<IDistribution1D> DistributionNoneItem::createDistribution(double
 
 void DistributionNoneItem::init_distribution(double value)
 {
-    setItemValue(DistributionNoneItem::P_VALUE, value);
-}
-
-void DistributionNoneItem::showMean(bool flag)
-{
-    getItem(P_VALUE)->setVisible(flag);
+    setItemValue(DistributionNoneItem::P_MEAN, value);
 }
 
 // --------------------------------------------------------------------------------------------- //
@@ -144,11 +152,10 @@ void DistributionGateItem::init_distribution(double value)
 
 // --------------------------------------------------------------------------------------------- //
 
-const QString DistributionLorentzItem::P_MEAN = QString::fromStdString(BornAgain::Mean);
 const QString DistributionLorentzItem::P_HWHM = QString::fromStdString(BornAgain::HWHM);
 
 DistributionLorentzItem::DistributionLorentzItem()
-    : DistributionItem(Constants::DistributionLorentzType)
+    : SymmetricDistributionItem(Constants::DistributionLorentzType)
 {
     addProperty(P_MEAN, 1.0)->setLimits(RealLimits::limitless());
     addProperty(P_HWHM, 1.0);
@@ -175,18 +182,12 @@ void DistributionLorentzItem::init_distribution(double value)
     getItem(P_HWHM)->setLimits(RealLimits::lowerLimited(0.0));
 }
 
-void DistributionLorentzItem::showMean(bool flag)
-{
-    getItem(P_MEAN)->setVisible(flag);
-}
-
 // --------------------------------------------------------------------------------------------- //
 
-const QString DistributionGaussianItem::P_MEAN = QString::fromStdString(BornAgain::Mean);
 const QString DistributionGaussianItem::P_STD_DEV = QString::fromStdString(BornAgain::StdDeviation);
 
 DistributionGaussianItem::DistributionGaussianItem()
-    : DistributionItem(Constants::DistributionGaussianType)
+    : SymmetricDistributionItem(Constants::DistributionGaussianType)
 {
     addProperty(P_MEAN, 1.0)->setLimits(RealLimits::limitless());
     addProperty(P_STD_DEV, 1.0);
@@ -213,11 +214,6 @@ void DistributionGaussianItem::init_distribution(double value)
     getItem(P_STD_DEV)->setLimits(RealLimits::lowerLimited(0.0));
 }
 
-void DistributionGaussianItem::showMean(bool flag)
-{
-    getItem(P_MEAN)->setVisible(flag);
-}
-
 // --------------------------------------------------------------------------------------------- //
 
 const QString DistributionLogNormalItem::P_MEDIAN = QString::fromStdString(BornAgain::Median);
@@ -259,11 +255,10 @@ void DistributionLogNormalItem::showMean(bool flag)
 
 // --------------------------------------------------------------------------------------------- //
 
-const QString DistributionCosineItem::P_MEAN = QString::fromStdString(BornAgain::Mean);
 const QString DistributionCosineItem::P_SIGMA = QString::fromStdString(BornAgain::Sigma);
 
 DistributionCosineItem::DistributionCosineItem()
-    : DistributionItem(Constants::DistributionCosineType)
+    : SymmetricDistributionItem(Constants::DistributionCosineType)
 {
     addProperty(P_MEAN, 1.0)->setLimits(RealLimits::limitless());
     addProperty(P_SIGMA, 1.0);
@@ -290,11 +285,6 @@ void DistributionCosineItem::init_distribution(double value)
     getItem(P_SIGMA)->setLimits(RealLimits::lowerLimited(0.0));
 }
 
-void DistributionCosineItem::showMean(bool flag)
-{
-    getItem(P_MEAN)->setVisible(flag);
-}
-
 // --------------------------------------------------------------------------------------------- //
 
 const QString DistributionTrapezoidItem::P_CENTER = QString::fromStdString(BornAgain::Center);
diff --git a/GUI/coregui/Models/DistributionItems.h b/GUI/coregui/Models/DistributionItems.h
index 12304a952e8751c762c9a5a4f97c417837e6bbfc..3e6101d42758c41d306af05b4175bcb65a5dce36 100644
--- a/GUI/coregui/Models/DistributionItems.h
+++ b/GUI/coregui/Models/DistributionItems.h
@@ -31,7 +31,7 @@ public:
     virtual std::unique_ptr<IDistribution1D> createDistribution(double scale = 1.0) const = 0;
     void init_parameters(double value, const RealLimits& limits=RealLimits::limitless());
     void init_limits_group(const RealLimits& limits, double factor = 1.0);
-    virtual void showMean(bool) {}
+    virtual void showMean(bool) = 0;
 
 protected:
     virtual void init_distribution(double){}
@@ -40,16 +40,23 @@ protected:
     void register_limits();
 };
 
-class BA_CORE_API_ DistributionNoneItem : public DistributionItem
+class BA_CORE_API_ SymmetricDistributionItem: public DistributionItem
+{
+public:
+    static const QString P_MEAN;
+
+    explicit SymmetricDistributionItem(const QString& name);
+    void showMean(bool flag) override;
+};
+
+class BA_CORE_API_ DistributionNoneItem : public SymmetricDistributionItem
 {
 
 public:
-    static const QString P_VALUE;
     DistributionNoneItem();
 
     std::unique_ptr<IDistribution1D> createDistribution(double scale = 1.0) const override;
     void init_distribution(double value) override;
-    void showMean(bool flag) override;
 };
 
 class BA_CORE_API_ DistributionGateItem : public DistributionItem
@@ -61,31 +68,28 @@ public:
 
     std::unique_ptr<IDistribution1D> createDistribution(double scale = 1.0) const override;
     void init_distribution(double value) override;
+    void showMean(bool) override {}
 };
 
 
-class BA_CORE_API_ DistributionLorentzItem : public DistributionItem
+class BA_CORE_API_ DistributionLorentzItem : public SymmetricDistributionItem
 {
 public:
-    static const QString P_MEAN;
     static const QString P_HWHM;
     DistributionLorentzItem();
 
     std::unique_ptr<IDistribution1D> createDistribution(double scale = 1.0) const override;
     void init_distribution(double value) override;
-    void showMean(bool flag) override;
 };
 
-class BA_CORE_API_ DistributionGaussianItem : public DistributionItem
+class BA_CORE_API_ DistributionGaussianItem : public SymmetricDistributionItem
 {
 public:
-    static const QString P_MEAN;
     static const QString P_STD_DEV;
     DistributionGaussianItem();
 
     std::unique_ptr<IDistribution1D> createDistribution(double scale = 1.0) const override;
     void init_distribution(double value) override;
-    void showMean(bool flag) override;
 };
 
 class BA_CORE_API_ DistributionLogNormalItem : public DistributionItem
@@ -102,16 +106,14 @@ public:
 };
 
 
-class BA_CORE_API_ DistributionCosineItem : public DistributionItem
+class BA_CORE_API_ DistributionCosineItem : public SymmetricDistributionItem
 {
 public:
-    static const QString P_MEAN;
     static const QString P_SIGMA;
     DistributionCosineItem();
 
     std::unique_ptr<IDistribution1D> createDistribution(double scale = 1.0) const override;
     void init_distribution(double value) override;
-    void showMean(bool flag) override;
 };
 
 class BA_CORE_API_ DistributionTrapezoidItem : public DistributionItem
diff --git a/GUI/coregui/Models/DomainFittingBuilder.cpp b/GUI/coregui/Models/DomainFittingBuilder.cpp
deleted file mode 100644
index eaab7f7a1bad12610e6f0e14d36ad4aaaeacb078..0000000000000000000000000000000000000000
--- a/GUI/coregui/Models/DomainFittingBuilder.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      GUI/coregui/Models/DomainFittingBuilder.cpp
-//! @brief     Implements class DomainFittingBuilder
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "DomainFittingBuilder.h"
-#include "DataItem.h"
-#include "DomainSimulationBuilder.h"
-#include "FitParameterItems.h"
-#include "FitSuite.h"
-#include "FitSuiteItem.h"
-#include "GISASSimulation.h"
-#include "GUIHelpers.h"
-#include "IMinimizer.h"
-#include "JobItem.h"
-#include "MinimizerItem.h"
-#include "RealDataItem.h"
-#include "FitParameter.h"
-#include "InstrumentItems.h"
-
-std::shared_ptr<FitSuite> DomainFittingBuilder::createFitSuite(JobItem *jobItem)
-{
-    std::shared_ptr<FitSuite> result(new FitSuite);
-
-    FitSuiteItem *fitSuiteItem = jobItem->fitSuiteItem();
-    Q_ASSERT(fitSuiteItem);
-
-    result->setMinimizer(fitSuiteItem->minimizerContainerItem()->createMinimizer().release());
-
-    FitParameterContainerItem *container = fitSuiteItem->fitParameterContainerItem();
-    Q_ASSERT(container);
-
-    for(auto parItem : container->fitParameterItems()) {
-        if(auto fitPar = parItem->createFitParameter())
-            result->addFitParameter(*fitPar);
-    }
-
-    const auto simulation = DomainSimulationBuilder::createSimulation(jobItem->multiLayerItem(),
-            jobItem->instrumentItem(), jobItem->simulationOptionsItem());
-
-    RealDataItem *realDataItem = jobItem->realDataItem();
-    if(!realDataItem)
-        throw GUIHelpers::Error("DomainFittingBuilder::createFitSuite() -> No Real Data defined.");
-
-    const DataItem* intensity_item = realDataItem->dataItem();
-    Q_ASSERT(intensity_item);
-    Q_ASSERT(intensity_item->getOutputData());
-
-    result->addSimulationAndRealData(*simulation.get(), *intensity_item->getOutputData());
-
-    return result;
-}
diff --git a/GUI/coregui/Models/DomainFittingBuilder.h b/GUI/coregui/Models/DomainFittingBuilder.h
deleted file mode 100644
index b684a559df8d6e8d53405bdce0605a9a3b9c440c..0000000000000000000000000000000000000000
--- a/GUI/coregui/Models/DomainFittingBuilder.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      GUI/coregui/Models/DomainFittingBuilder.h
-//! @brief     Defines DomainFittingBuilder namespace
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef DOMAINFITTINGBUILDER_H
-#define DOMAINFITTINGBUILDER_H
-
-#include "WinDllMacros.h"
-#include <memory>
-
-class JobItem;
-class FitSuite;
-
-//! The DomainFittingBuilder namespace
-
-namespace DomainFittingBuilder {
-
-    //! Creates domain's fitSuite from JobItem
-    BA_CORE_API_ std::shared_ptr<FitSuite> createFitSuite(JobItem *jobItem);
-
-}
-
-#endif // DOMAINFITTINGBUILDER_H
diff --git a/GUI/coregui/Models/DomainObjectBuilder.cpp b/GUI/coregui/Models/DomainObjectBuilder.cpp
index 010387c6ce6a0f91698bfa75c9a99bef797a5802..1b526225494baad7dc673c985b86d885d8175035 100644
--- a/GUI/coregui/Models/DomainObjectBuilder.cpp
+++ b/GUI/coregui/Models/DomainObjectBuilder.cpp
@@ -29,6 +29,7 @@
 #include "UnitConverter1D.h"
 #include "UnitConverterUtils.h"
 #include "Units.h"
+#include "DepthProbeInstrumentItem.h"
 
 std::unique_ptr<MultiLayer> DomainObjectBuilder::buildMultiLayer(const SessionItem& multilayer_item)
 {
@@ -134,22 +135,17 @@ DomainObjectBuilder::buildInstrument(const InstrumentItem& instrumentItem)
 std::unique_ptr<IUnitConverter>
 DomainObjectBuilder::createUnitConverter(const InstrumentItem* instrumentItem)
 {
+    if (auto specular_instrument = dynamic_cast<const SpecularInstrumentItem*>(instrumentItem))
+        return specular_instrument->createUnitConverter();
+    else if(auto depth_instrument = dynamic_cast<const DepthProbeInstrumentItem*>(instrumentItem))
+        return depth_instrument->createUnitConverter();
+
     const auto instrument = instrumentItem->createInstrument();
     instrument->initDetector();
 
     if (instrumentItem->modelType() == Constants::GISASInstrumentType)
         return UnitConverterUtils::createConverterForGISAS(*instrument);
 
-    if (instrumentItem->modelType() == Constants::SpecularInstrumentType)
-    {
-        auto axis_item = dynamic_cast<BasicAxisItem*>(
-            instrumentItem->beamItem()
-                ->getItem(SpecularBeamItem::P_INCLINATION_ANGLE)
-                ->getItem(SpecularBeamInclinationItem::P_ALPHA_AXIS));
-        return std::make_unique<UnitConverter1D>(instrument->getBeam(),
-                                                 *axis_item->createAxis(Units::degree));
-    }
-
     if (instrumentItem->modelType() == Constants::OffSpecInstrumentType) {
         auto axis_item = dynamic_cast<BasicAxisItem*>(
             instrumentItem->getItem(OffSpecInstrumentItem::P_ALPHA_AXIS));
diff --git a/GUI/coregui/Models/DomainSimulationBuilder.cpp b/GUI/coregui/Models/DomainSimulationBuilder.cpp
index 3d57ea3d69bbb53ce512737f525c21236b7b16f4..26263fc8ef29b47a10d0ca96349bfc925621765f 100644
--- a/GUI/coregui/Models/DomainSimulationBuilder.cpp
+++ b/GUI/coregui/Models/DomainSimulationBuilder.cpp
@@ -31,6 +31,8 @@
 #include "SpecularSimulation.h"
 #include "SpecularBeamInclinationItem.h"
 #include "TransformToDomain.h"
+#include "DepthProbeSimulation.h"
+#include "DepthProbeInstrumentItem.h"
 #include "Units.h"
 
 namespace {
@@ -49,6 +51,12 @@ std::unique_ptr<SpecularSimulation>
 createSpecularSimulation(std::unique_ptr<MultiLayer> P_multilayer,
                          const SpecularInstrumentItem* specular_instrument,
                          const SimulationOptionsItem* options_item);
+
+std::unique_ptr<DepthProbeSimulation>
+createDepthProbeSimulation(std::unique_ptr<MultiLayer> P_multilayer,
+                         const DepthProbeInstrumentItem* instrument,
+                         const SimulationOptionsItem* options_item);
+
 }
 
 std::unique_ptr<Simulation>
@@ -70,6 +78,8 @@ DomainSimulationBuilder::createSimulation(const MultiLayerItem* sampleItem,
         return createOffSpecSimulation(std::move(P_multilayer), offspecInstrument, optionsItem);
     else if (auto specular_instrument = dynamic_cast<const SpecularInstrumentItem*>(instrumentItem))
         return createSpecularSimulation(std::move(P_multilayer), specular_instrument, optionsItem);
+    else if (auto penetrator = dynamic_cast<const DepthProbeInstrumentItem*>(instrumentItem))
+        return createDepthProbeSimulation(std::move(P_multilayer), penetrator, optionsItem);
 
     throw GUIHelpers::Error(
         "DomainSimulationBuilder::createSimulation() -> Error. Not yet implemented");
@@ -141,9 +151,7 @@ createSpecularSimulation(std::unique_ptr<MultiLayer> P_multilayer,
         = std::make_unique<SpecularSimulation>(*P_multilayer);
 
     auto beam_item = specular_instrument->beamItem();
-    const auto axis_item
-        = dynamic_cast<BasicAxisItem*>(beam_item->getItem(SpecularBeamItem::P_INCLINATION_ANGLE)
-                                           ->getItem(SpecularBeamInclinationItem::P_ALPHA_AXIS));
+    const auto axis_item = beam_item->currentInclinationAxisItem();
     const auto footprint = beam_item->currentFootprintItem();
 
     specular_simulation->setBeamIntensity(beam_item->getIntensity());
@@ -162,4 +170,20 @@ createSpecularSimulation(std::unique_ptr<MultiLayer> P_multilayer,
 
     return specular_simulation;
 }
+
+
+std::unique_ptr<DepthProbeSimulation>
+createDepthProbeSimulation(std::unique_ptr<MultiLayer> P_multilayer,
+                         const DepthProbeInstrumentItem* instrument,
+                         const SimulationOptionsItem* options_item)
+{
+    std::unique_ptr<DepthProbeSimulation> simulation = instrument->createSimulation();
+    simulation->setSample(*P_multilayer.get());
+
+    if (options_item)
+        TransformToDomain::setSimulationOptions(simulation.get(), *options_item);
+
+    return simulation;
+}
+
 }
diff --git a/GUI/coregui/Models/FitParameterItems.cpp b/GUI/coregui/Models/FitParameterItems.cpp
index db2c96d27e18ad34989a83ced0d43b767055755e..13734dcc369ff22ffc0eaa7e9fb378aca7cc8ac0 100644
--- a/GUI/coregui/Models/FitParameterItems.cpp
+++ b/GUI/coregui/Models/FitParameterItems.cpp
@@ -16,9 +16,10 @@
 #include "ComboProperty.h"
 #include "GUIHelpers.h"
 #include "ModelPath.h"
-#include "FitParameter.h"
 #include "ParameterTreeItems.h"
 #include "JobItem.h"
+#include "Parameters.h"
+#include "Parameter.h"
 #include <cmath>
 
 namespace
@@ -66,12 +67,16 @@ const QString FitParameterItem::T_LINK = "Link tag";
 FitParameterItem::FitParameterItem() : SessionItem(Constants::FitParameterType)
 {
     addProperty(P_TYPE, fitParameterTypeCombo().variant());
-    addProperty(P_START_VALUE, 0.0);
-    addProperty(P_MIN, 0.0);
-    addProperty(P_MAX, 0.0)->setEnabled(false);
+    addProperty(P_START_VALUE, 0.0)->setEditorType(Constants::ScientificSpinBoxType);
+    addProperty(P_MIN, 0.0)->setEditorType(Constants::ScientificSpinBoxType);
+    addProperty(P_MAX, 0.0)->setEditorType(Constants::ScientificSpinBoxType).setEnabled(false);
     registerTag(T_LINK, 0, -1, QStringList() << Constants::FitParameterLinkType);
     setDefaultTag(T_LINK);
 
+    getItem(P_START_VALUE)->setLimits(RealLimits::limitless());
+    getItem(P_MIN)->setLimits(RealLimits::limitless());
+    getItem(P_MAX)->setLimits(RealLimits::limitless());
+
     mapper()->setOnPropertyChange([this](const QString& name) {
         if (name == P_TYPE)
             onTypeChange();
@@ -93,49 +98,21 @@ void FitParameterItem::initMinMaxValues(const RealLimits& limits)
         dr = std::abs(value) * range_factor;
     }
 
-    if (isLimited()) {
-        double min = value - dr;
-        double max = value + dr;
-
-        if (limits.hasLowerLimit() && min < limits.lowerLimit())
-            min = limits.lowerLimit();
-
-        if (limits.hasUpperLimit() && max > limits.upperLimit())
-            max = limits.upperLimit();
-
-        setItemValue(P_MIN, min);
-        setItemValue(P_MAX, max);
-    }
-}
-
-//! Creates domain's FitParameter.
+    double min = value - dr;
+    double max = value + dr;
 
-std::unique_ptr<FitParameter> FitParameterItem::createFitParameter() const
-{
-    if (getItems(FitParameterItem::T_LINK).empty())
-        return std::unique_ptr<FitParameter>();
-
-    std::unique_ptr<FitParameter> result(new FitParameter);
-    result->setStartValue(getItemValue(FitParameterItem::P_START_VALUE).toDouble());
-    result->setLimits(attLimits());
-
-    const JobItem* jobItem = dynamic_cast<const JobItem*>(ModelPath::ancestor(this, Constants::JobItemType));
-    Q_ASSERT(jobItem);
-
-    for(auto linkItem : getItems(FitParameterItem::T_LINK)) {
-        QString link = linkItem->getItemValue(FitParameterLinkItem::P_LINK).toString();
+    if (limits.hasLowerLimit() && min < limits.lowerLimit())
+        min = limits.lowerLimit();
 
-        ParameterItem *parItem = dynamic_cast<ParameterItem*>(
-                    ModelPath::getItemFromPath(link, jobItem->parameterContainerItem()));
-        Q_ASSERT(parItem);
+    if (limits.hasUpperLimit() && max > limits.upperLimit())
+        max = limits.upperLimit();
 
-        QString translation = "*/" + ModelPath::itemPathTranslation(*parItem->linkedItem(), jobItem);
-        parItem->setItemValue(ParameterItem::P_DOMAIN, translation);
+    setItemValue(P_MIN, min);
+    getItem(P_MIN)->setLimits(limits);
+    setItemValue(P_MAX, max);
+    getItem(P_MAX)->setLimits(limits);
 
-        result->addPattern(translation.toStdString());
-    }
-
-    return result;
+    getItem(P_START_VALUE)->setLimits(limits);
 }
 
 //! Constructs Limits correspodning to current GUI settings.
@@ -167,6 +144,22 @@ AttLimits FitParameterItem::attLimits() const
     }
 }
 
+bool FitParameterItem::isValid() const
+{
+    if (isFixed() || isFree())
+        return true;
+
+    double value = getItemValue(P_START_VALUE).toDouble();
+    double min = getItemValue(P_MIN).toDouble();
+    double max = getItemValue(P_MAX).toDouble();
+
+    if (isLowerLimited())
+        return min <= value;
+    if (isUpperLimited())
+        return value <= max;
+    return min <= value && value <= max;
+}
+
 QString FitParameterItem::parameterType() const
 {
     ComboProperty partype = getItemValue(P_TYPE).value<ComboProperty>();
@@ -301,3 +294,28 @@ void FitParameterContainerItem::setValuesInParameterContainer(
         index++;
     }
 }
+
+Fit::Parameters FitParameterContainerItem::createParameters() const
+{
+    Fit::Parameters result;
+
+    int index(0);
+    for(auto item : getItems(FitParameterContainerItem::T_FIT_PARAMETERS)) {
+        auto fitPar = dynamic_cast<FitParameterItem*>(item);
+        if (!fitPar->isValid()) {
+            std::stringstream ss;
+            ss << "FitParameterContainerItem::createParameters(): invalid starting value "
+                  "or (min, max) range in fitting parameter par"
+               << index;
+            std::string message = ss.str();
+            throw GUIHelpers::Error(QString::fromStdString(ss.str()));
+        }
+        double startValue = fitPar->getItemValue(FitParameterItem::P_START_VALUE).toDouble();
+        AttLimits limits = fitPar->attLimits();
+        QString name = QString("par%1").arg(index);
+        result.add(Fit::Parameter(name.toStdString(), startValue, limits));
+        ++index;
+    }
+
+    return result;
+}
diff --git a/GUI/coregui/Models/FitParameterItems.h b/GUI/coregui/Models/FitParameterItems.h
index 1f6b1d5d46993d580b09f1ceadb5002749a795e2..f02ed686cc31643c33ddbfeb6218de0186ca312b 100644
--- a/GUI/coregui/Models/FitParameterItems.h
+++ b/GUI/coregui/Models/FitParameterItems.h
@@ -18,8 +18,6 @@
 #include "SessionItem.h"
 #include "AttLimits.h"
 
-class FitParameter;
-
 //! FitParameterItems is a collection of items to define fit parameters in GUI.
 
 //! The FitParameterLinkItem class holds a link to ParameterItem in tuning tree.
@@ -49,10 +47,11 @@ public:
 
     void initMinMaxValues(const RealLimits &limits);
 
-    std::unique_ptr<FitParameter> createFitParameter() const;
+    AttLimits attLimits() const;
+
+    bool isValid() const;
 
 private:
-    AttLimits attLimits() const;
     QString parameterType() const;
     void onTypeChange();
     void setLimitEnabled(const QString &name, bool enabled);
@@ -65,6 +64,8 @@ private:
 
 //! The FitParameterContainerItem class is a collection of all defined fit parameters in JobItem.
 
+namespace Fit { class Parameters; }
+
 class BA_CORE_API_ FitParameterContainerItem : public SessionItem
 {
 
@@ -76,6 +77,8 @@ public:
     bool isEmpty();
     void setValuesInParameterContainer(const QVector<double> &values,
                                        class ParameterContainerItem *parameterContainer);
+    Fit::Parameters createParameters() const;
+
 };
 
 #endif // FITPARAMETERITEMS_H
diff --git a/GUI/coregui/Models/FitSuiteItem.h b/GUI/coregui/Models/FitSuiteItem.h
index 06c4c3b86e2a6157e54d241bfff87f944c1ed9ee..b4b0e6c4c0839339a0763e845e790cb033b94898 100644
--- a/GUI/coregui/Models/FitSuiteItem.h
+++ b/GUI/coregui/Models/FitSuiteItem.h
@@ -33,7 +33,6 @@ public:
 
     FitParameterContainerItem *fitParameterContainerItem();
     MinimizerContainerItem *minimizerContainerItem();
-//    std::unique_ptr<FitSuite> createFitSuite();
 };
 
 #endif // FITSUITEITEM_H
diff --git a/GUI/coregui/Models/GroupInfoCatalogue.cpp b/GUI/coregui/Models/GroupInfoCatalogue.cpp
index f3361ffd274b1cb1be3c25fda7c01d1c8b0c5dd6..90ef58ed4f3c23441ead2a0d1485814c5a8edc36 100644
--- a/GUI/coregui/Models/GroupInfoCatalogue.cpp
+++ b/GUI/coregui/Models/GroupInfoCatalogue.cpp
@@ -85,7 +85,7 @@ GroupInfoCatalogue::GroupInfoCatalogue()
     info.setDefaultType(Constants::DistributionNoneType);
     addInfo(info);
 
-    info = GroupInfo(Constants::DistributionWithZeroAverageGroup);
+    info = GroupInfo(Constants::SymmetricDistributionGroup);
     info.add(Constants::DistributionNoneType, "None");
     info.add(Constants::DistributionLorentzType, "Lorentz");
     info.add(Constants::DistributionGaussianType, "Gaussian");
@@ -179,6 +179,18 @@ GroupInfoCatalogue::GroupInfoCatalogue()
     info.add(Constants::FootprintSquareType, "Square footprint");
     info.setDefaultType(Constants::FootprintNoneType);
     addInfo(info);
+
+    info = GroupInfo(Constants::AxesGroup);
+    info.add(Constants::BasicAxisType, "Uniform axis");
+    info.add(Constants::PointwiseAxisType, "Non-uniform axis");
+    info.setDefaultType(Constants::BasicAxisType);
+    addInfo(info);
+
+    info = GroupInfo(Constants::VarianceFunctionGroup);
+    info.add(Constants::VarianceSimFunctionType, "Simulation value based");
+    info.add(Constants::VarianceConstantFunctionType, "Constant");
+    info.setDefaultType(Constants::VarianceSimFunctionType);
+    addInfo(info);
 }
 
 GroupInfo GroupInfoCatalogue::groupInfo(const QString& groupType) const
diff --git a/GUI/coregui/Models/InstrumentItems.cpp b/GUI/coregui/Models/InstrumentItems.cpp
index a44b096329b96251b9dac45cacda9896d69d874d..75e20b1b488623c5aef1efd92fb2f1bda84b13b7 100644
--- a/GUI/coregui/Models/InstrumentItems.cpp
+++ b/GUI/coregui/Models/InstrumentItems.cpp
@@ -16,11 +16,17 @@
 #include "AxesItems.h"
 #include "BackgroundItems.h"
 #include "BeamItems.h"
+#include "DataItem.h"
 #include "DetectorItems.h"
 #include "GroupItem.h"
 #include "GUIHelpers.h"
 #include "IDetector2D.h"
 #include "Instrument.h"
+#include "ItemFileNameUtils.h"
+#include "JobItemUtils.h"
+#include "PointwiseAxisItem.h"
+#include "RealDataItem.h"
+#include "UnitConverter1D.h"
 #include "MaskItems.h"
 #include "SessionModel.h"
 
@@ -65,6 +71,11 @@ GroupItem* InstrumentItem::backgroundGroup()
     return &item<GroupItem>(P_BACKGROUND);
 }
 
+bool InstrumentItem::alignedWith(const RealDataItem* item) const
+{
+    return shape() == item->shape();
+}
+
 std::unique_ptr<Instrument> InstrumentItem::createInstrument() const
 {
     std::unique_ptr<Instrument> result(new Instrument);
@@ -80,10 +91,6 @@ InstrumentItem::InstrumentItem(const QString& modelType)
 {
     setItemName(modelType);
     addProperty(P_IDENTIFIER, GUIHelpers::createUuid())->setVisible(false);
-
-    auto item = addGroupProperty(P_BACKGROUND, Constants::BackgroundGroup);
-    item->setDisplayName(background_group_label);
-    item->setToolTip("Background type");
 }
 
 void InstrumentItem::initBeamGroup(const QString& beam_model)
@@ -91,10 +98,19 @@ void InstrumentItem::initBeamGroup(const QString& beam_model)
     addGroupProperty(P_BEAM, beam_model);
 }
 
+void InstrumentItem::initBackgroundGroup()
+{
+    auto item = addGroupProperty(P_BACKGROUND, Constants::BackgroundGroup);
+    item->setDisplayName(background_group_label);
+    item->setToolTip("Background type");
+}
+
 SpecularInstrumentItem::SpecularInstrumentItem()
     : InstrumentItem(Constants::SpecularInstrumentType)
 {
     initBeamGroup(Constants::SpecularBeamType);
+    initBackgroundGroup();
+    item<SpecularBeamItem>(P_BEAM).updateFileName(ItemFileNameUtils::instrumentDataFileName(*this));
 }
 
 SpecularBeamItem* SpecularInstrumentItem::beamItem() const
@@ -111,17 +127,57 @@ std::unique_ptr<Instrument> SpecularInstrumentItem::createInstrument() const
 
 std::vector<int> SpecularInstrumentItem::shape() const
 {
-    const auto& axis_item = beamItem()->getInclinationAngleAxis();
-    return {axis_item.getItemValue(BasicAxisItem::P_NBINS).toInt()};
+    const auto axis_item = beamItem()->currentInclinationAxisItem();
+    return {axis_item->getItemValue(BasicAxisItem::P_NBINS).toInt()};
 }
 
-void SpecularInstrumentItem::setShape(const std::vector<int>& data_shape)
+void SpecularInstrumentItem::updateToRealData(const RealDataItem* item)
 {
-    if (shape().size() != data_shape.size())
-        throw GUIHelpers::Error("Error in SpecularInstrumentItem::setShape: The type of "
-                                "instrument is incompatible with passed data shape.");
-    auto& axis_item = beamItem()->getInclinationAngleAxis();
-    axis_item.setItemValue(BasicAxisItem::P_NBINS, data_shape[0]);
+    if (shape().size() != item->shape().size())
+        throw GUIHelpers::Error("Error in SpecularInstrumentItem::updateToRealData: The type "
+                                "of instrument is incompatible with passed data shape.");
+
+    QString units = item->getItemValue(RealDataItem::P_NATIVE_UNITS).toString();
+    const auto& data = item->nativeData()->getOutputData()->getAxis(0);
+    beamItem()->updateToData(data, units);
+}
+
+bool SpecularInstrumentItem::alignedWith(const RealDataItem* item) const
+{
+    const QString native_units = item->getItemValue(RealDataItem::P_NATIVE_UNITS).toString();
+    if (native_units == Constants::UnitsNbins) {
+        return beamItem()->currentInclinationAxisItem()->modelType() == Constants::BasicAxisType
+               && shape() == item->shape();
+    } else {
+        auto axis_item =
+            dynamic_cast<PointwiseAxisItem*>(beamItem()->currentInclinationAxisItem());
+        if (!axis_item)
+            return false;
+        if (axis_item->getUnitsLabel() != native_units)
+            return false;
+
+        auto instrument_axis = axis_item->getAxis();
+        if (!instrument_axis)
+            return false;
+
+        const auto& native_axis = item->nativeData()->getOutputData()->getAxis(0);
+        return *instrument_axis == native_axis;
+;    }
+}
+
+std::unique_ptr<IUnitConverter> SpecularInstrumentItem::createUnitConverter() const
+{
+    const auto instrument = createInstrument();
+    auto axis_item = beamItem()->currentInclinationAxisItem();
+    if (auto pointwise_axis = dynamic_cast<PointwiseAxisItem*>(axis_item)) {
+        if (!pointwise_axis->containsNonXMLData()) // workaround for loading project
+            return nullptr;
+        AxesUnits native_units = JobItemUtils::axesUnitsFromName(pointwise_axis->getUnitsLabel());
+        return std::make_unique<UnitConverter1D>(instrument->getBeam(), *pointwise_axis->getAxis(),
+                                                 native_units);
+    } else
+        return std::make_unique<UnitConverter1D>(instrument->getBeam(), *axis_item->createAxis(1.0),
+                                                 AxesUnits::DEGREES);
 }
 
 const QString Instrument2DItem::P_DETECTOR = "Detector";
@@ -131,6 +187,7 @@ Instrument2DItem::Instrument2DItem(const QString& modelType)
 {
     initBeamGroup(Constants::GISASBeamType);
     addGroupProperty(P_DETECTOR, Constants::DetectorGroup);
+    initBackgroundGroup();
 
     setDefaultTag(P_DETECTOR);
 }
@@ -183,10 +240,14 @@ std::vector<int> GISASInstrumentItem::shape() const
     return {detector_item->xSize(), detector_item->ySize()};
 }
 
-void GISASInstrumentItem::setShape(const std::vector<int>& data_shape)
+void GISASInstrumentItem::updateToRealData(const RealDataItem* item)
 {
+    if (!item)
+        return;
+
+    const auto data_shape = item->shape();
     if (shape().size() != data_shape.size())
-        throw GUIHelpers::Error("Error in GISASInstrumentItem::setShape: The type of "
+        throw GUIHelpers::Error("Error in GISASInstrumentItem::updateToRealData: The type of "
                                 "instrument is incompatible with passed data shape.");
     detectorItem()->setXSize(data_shape[0]);
     detectorItem()->setYSize(data_shape[1]);
@@ -207,10 +268,14 @@ std::vector<int> OffSpecInstrumentItem::shape() const
     return {x_size, detector_item->ySize()};
 }
 
-void OffSpecInstrumentItem::setShape(const std::vector<int>& data_shape)
+void OffSpecInstrumentItem::updateToRealData(const RealDataItem* item)
 {
+    if (!item)
+        return;
+
+    const auto data_shape = item->shape();
     if (shape().size() != data_shape.size())
-        throw GUIHelpers::Error("Error in OffSpecInstrumentItem::setShape: The type of "
+        throw GUIHelpers::Error("Error in OffSpecInstrumentItem::updateToRealData: The type of "
                                 "instrument is incompatible with passed data shape.");
     getItem(OffSpecInstrumentItem::P_ALPHA_AXIS)
         ->setItemValue(BasicAxisItem::P_NBINS, data_shape[0]);
diff --git a/GUI/coregui/Models/InstrumentItems.h b/GUI/coregui/Models/InstrumentItems.h
index fa177c4ab51d6ab4cccd5a5ebaab9b71275489e0..39e04562ea276598f003abbbe490cf58846befaa 100644
--- a/GUI/coregui/Models/InstrumentItems.h
+++ b/GUI/coregui/Models/InstrumentItems.h
@@ -22,7 +22,9 @@ class DataItem;
 class DetectorItem;
 class GroupItem;
 class Instrument;
+class IUnitConverter;
 class MaskContainerItem;
+class RealDataItem;
 
 class BA_CORE_API_ InstrumentItem : public SessionItem
 {
@@ -39,14 +41,16 @@ public:
 
     virtual std::unique_ptr<Instrument> createInstrument() const = 0;
     virtual std::vector<int> shape() const = 0;
-    virtual void setShape(const std::vector<int>& shape) = 0;
     virtual void clearMasks() {}
     virtual void importMasks(const MaskContainerItem*) {}
+    virtual void updateToRealData(const RealDataItem* item) = 0;
+    virtual bool alignedWith(const RealDataItem* item) const;
 
 protected:
     explicit InstrumentItem(const QString& modelType);
 
     void initBeamGroup(const QString& beam_model);
+    void initBackgroundGroup();
 };
 
 class BA_CORE_API_ SpecularInstrumentItem : public InstrumentItem
@@ -59,7 +63,10 @@ public:
 
     std::unique_ptr<Instrument> createInstrument() const override;
     std::vector<int> shape() const override;
-    void setShape(const std::vector<int>& shape) override;
+    void updateToRealData(const RealDataItem* item) override;
+    bool alignedWith(const RealDataItem* item) const override;
+
+    std::unique_ptr<IUnitConverter> createUnitConverter() const;
 };
 
 class BA_CORE_API_ Instrument2DItem : public InstrumentItem
@@ -88,7 +95,7 @@ class BA_CORE_API_ GISASInstrumentItem : public Instrument2DItem
 public:
     GISASInstrumentItem();
     std::vector<int> shape() const override;
-    void setShape(const std::vector<int>& data_shape) override;
+    void updateToRealData(const RealDataItem* item) override;
 };
 
 class BA_CORE_API_ OffSpecInstrumentItem : public Instrument2DItem
@@ -98,7 +105,7 @@ public:
 
     OffSpecInstrumentItem();
     std::vector<int> shape() const override;
-    void setShape(const std::vector<int>& data_shape) override;
+    void updateToRealData(const RealDataItem* item) override;
 };
 
 #endif // INSTRUMENTITEMS_H
diff --git a/GUI/coregui/Models/InstrumentModel.cpp b/GUI/coregui/Models/InstrumentModel.cpp
index d8f6d717a4d0c6b2f4c222e13906aee40b92c3df..7dc1f68bf2cdab70aa8c030435ad3dcc7380c4d7 100644
--- a/GUI/coregui/Models/InstrumentModel.cpp
+++ b/GUI/coregui/Models/InstrumentModel.cpp
@@ -14,6 +14,7 @@
 
 #include "InstrumentModel.h"
 #include "InstrumentItems.h"
+#include "SpecularBeamInclinationItem.h"
 
 InstrumentModel::InstrumentModel(QObject *parent)
     : SessionModel(SessionXML::InstrumentModelTag, parent)
@@ -21,6 +22,7 @@ InstrumentModel::InstrumentModel(QObject *parent)
     setObjectName(SessionXML::InstrumentModelTag);
 }
 
+InstrumentModel::~InstrumentModel() = default;
 
 InstrumentModel *InstrumentModel::createCopy(SessionItem *parent)
 {
@@ -29,6 +31,22 @@ InstrumentModel *InstrumentModel::createCopy(SessionItem *parent)
     return result;
 }
 
+QVector<SessionItem *> InstrumentModel::nonXMLData() const
+{
+    QVector<SessionItem*> result;
+
+    for (auto instrument_item : topItems<SpecularInstrumentItem>()) {
+        auto axis_group = instrument_item->beamItem()
+                              ->getItem(BeamItem::P_INCLINATION_ANGLE)
+                              ->getItem(SpecularBeamInclinationItem::P_ALPHA_AXIS);
+
+        if (auto pointwise_axis = axis_group->getChildOfType(Constants::PointwiseAxisType))
+            result.push_back(pointwise_axis);
+    }
+
+    return result;
+}
+
 InstrumentItem* InstrumentModel::instrumentItem()
 {
     return topItem<InstrumentItem>();
diff --git a/GUI/coregui/Models/InstrumentModel.h b/GUI/coregui/Models/InstrumentModel.h
index 4488fbb218cc3de5e03438448a228b0b8c31514b..64ceab657be8884ddc047b67155b2558d28b21e1 100644
--- a/GUI/coregui/Models/InstrumentModel.h
+++ b/GUI/coregui/Models/InstrumentModel.h
@@ -24,10 +24,11 @@ class BA_CORE_API_ InstrumentModel : public SessionModel
     Q_OBJECT
 
 public:
-    explicit InstrumentModel(QObject *parent = 0);
-    virtual ~InstrumentModel(){}
+    explicit InstrumentModel(QObject *parent = nullptr);
+    ~InstrumentModel() override;
 
-    virtual InstrumentModel *createCopy(SessionItem *parent=0);
+    InstrumentModel* createCopy(SessionItem* parent = nullptr) override;
+    QVector<SessionItem*> nonXMLData() const override;
 
     InstrumentItem *instrumentItem();
 };
diff --git a/GUI/coregui/Models/IntensityDataItem.cpp b/GUI/coregui/Models/IntensityDataItem.cpp
index 2917a1b481ce4d5f9eaf910e3b89332a58b05b28..24886315210037bf88bd2b86a9b392927257bca5 100644
--- a/GUI/coregui/Models/IntensityDataItem.cpp
+++ b/GUI/coregui/Models/IntensityDataItem.cpp
@@ -225,18 +225,18 @@ std::vector<int> IntensityDataItem::shape() const
     return {getNbinsX(), getNbinsY()};
 }
 
-void IntensityDataItem::resetToDefault()
+void IntensityDataItem::reset(ImportDataInfo data)
 {
-    assert(getOutputData()
-           && "IntensityDataItem::resetToDefault assertion failed: associated output data should "
-              "not be empty");
-    DataItem::resetToDefault();
+    assert(data.unitsLabel() == Constants::UnitsNbins);
+    ComboProperty combo = ComboProperty() << data.unitsLabel();
+    setItemValue(IntensityDataItem::P_AXES_UNITS, combo.variant());
+    getItem(IntensityDataItem::P_AXES_UNITS)->setVisible(true);
 
-    setXaxisTitle(x_axis_default_name);
-    setYaxisTitle(y_axis_default_name);
+    setXaxisTitle(data.axisLabel(0));
+    setYaxisTitle(data.axisLabel(1));
     MaskUnitsConverter converter;
     converter.convertToNbins(this);
-    setOutputData(ImportDataUtils::CreateSimplifiedOutputData(*getOutputData()).release());
+    setOutputData(std::move(data).intensityData().release());
     setAxesRangeToData();
     converter.convertFromNbins(this);
 }
diff --git a/GUI/coregui/Models/IntensityDataItem.h b/GUI/coregui/Models/IntensityDataItem.h
index 7435487e4551a3f24ea4d8f9d157ebd9e15524c6..fd1e81b98f107b0a0ec11fe370dbd39d46536979 100644
--- a/GUI/coregui/Models/IntensityDataItem.h
+++ b/GUI/coregui/Models/IntensityDataItem.h
@@ -95,8 +95,9 @@ public:
     void updateAxesUnits(const InstrumentItem* instrument) override;
     std::vector<int> shape() const override;
 
-    //! Returns data to default state (no dimensional units, default axes' names)
-    void resetToDefault() override;
+    //! Returns data to the state defined by user (imported)
+    //! data.
+    void reset(ImportDataInfo data) override;
 
 public slots:
     void setLowerX(double xmin);
diff --git a/GUI/coregui/Models/ItemCatalogue.cpp b/GUI/coregui/Models/ItemCatalogue.cpp
index d8dbf9397251e9dee723c706948fad179f72c015..3185aca0dbfe813c47e58e92b8a5498dfcbedff8 100644
--- a/GUI/coregui/Models/ItemCatalogue.cpp
+++ b/GUI/coregui/Models/ItemCatalogue.cpp
@@ -39,6 +39,7 @@
 #include "LayerRoughnessItems.h"
 #include "MaskItems.h"
 #include "MaterialDataItems.h"
+#include "MaterialItemContainer.h"
 #include "MaterialItem.h"
 #include "MesoCrystalItem.h"
 #include "MinimizerItem.h"
@@ -49,6 +50,7 @@
 #include "ParticleDistributionItem.h"
 #include "ParticleItem.h"
 #include "ParticleLayoutItem.h"
+#include "PointwiseAxisItem.h"
 #include "ProjectionItems.h"
 #include "PropertyItem.h"
 #include "RealDataItem.h"
@@ -62,6 +64,8 @@
 #include "SphericalDetectorItem.h"
 #include "TransformationItem.h"
 #include "VectorItem.h"
+#include "DepthProbeInstrumentItem.h"
+#include "VarianceFunctionItems.h"
 
 ItemCatalogue::ItemCatalogue()
 {
@@ -169,6 +173,7 @@ ItemCatalogue::ItemCatalogue()
     add(Constants::HexagonalLatticeType, create_new<HexagonalLatticeItem>);
 
     add(Constants::MaterialType, create_new<MaterialItem>);
+    add(Constants::MaterialContainerType, create_new<MaterialItemContainer>);
 
     add(Constants::MaterialRefractiveDataType, create_new<MaterialRefractiveDataItem>);
     add(Constants::MaterialSLDDataType, create_new<MaterialSLDDataItem>);
@@ -182,12 +187,14 @@ ItemCatalogue::ItemCatalogue()
     add(Constants::DataItem1DPropertiesType, create_new<Data1DProperties>);
 
     add(Constants::BasicAxisType, create_new<BasicAxisItem>);
+    add(Constants::PointwiseAxisType, create_new<PointwiseAxisItem>);
     add(Constants::AmplitudeAxisType, create_new<AmplitudeAxisItem>);
 
     add(Constants::BeamWavelengthType, create_new<BeamWavelengthItem>);
     add(Constants::BeamAzimuthalAngleType, create_new<BeamAzimuthalAngleItem>);
     add(Constants::BeamInclinationAngleType, create_new<BeamInclinationAngleItem>);
     add(Constants::SpecularBeamInclinationType, create_new<SpecularBeamInclinationItem>);
+    add(Constants::SpecularBeamWavelengthType, create_new<SpecularBeamWavelengthItem>);
 
     add(Constants::ResolutionFunctionNoneType, create_new<ResolutionFunctionNoneItem>);
     add(Constants::ResolutionFunction2DGaussianType, create_new<ResolutionFunction2DGaussianItem>);
@@ -234,6 +241,11 @@ ItemCatalogue::ItemCatalogue()
     add(Constants::RealLimitsLimitedType, create_new<LimitedItem>);
 
     add(Constants::ProjectionContainerType, create_new<ProjectionContainerItem>);
+
+    add(Constants::DepthProbeInstrumentType, create_new<DepthProbeInstrumentItem>);
+
+    add(Constants::VarianceConstantFunctionType, create_new<VarianceConstantFunctionItem>);
+    add(Constants::VarianceSimFunctionType, create_new<VarianceSimFunctionItem>);
 }
 
 bool ItemCatalogue::contains(const QString& modelType) const { return m_data.contains(modelType); }
diff --git a/GUI/coregui/Models/ItemFileNameUtils.cpp b/GUI/coregui/Models/ItemFileNameUtils.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3638647a5b1781019e1177f9828b304e54d44109
--- /dev/null
+++ b/GUI/coregui/Models/ItemFileNameUtils.cpp
@@ -0,0 +1,91 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Models/ItemFileNameUtils.cpp
+//! @brief     Defines auxiliary functions in ItemFileNameUtils namespace.
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "ItemFileNameUtils.h"
+#include "GUIHelpers.h"
+#include "InstrumentItems.h"
+#include "JobItem.h"
+#include "RealDataItem.h"
+#include "item_constants.h"
+
+namespace
+{
+const QString jobdata_file_prefix = "jobdata";
+const QString refdata_file_prefix = "refdata";
+const QString realdata_file_prefix = "realdata";
+const QString instrument_file_prefix = "instrdata";
+const QString nativedata_file_prefix = "nativedata";
+
+//! Constructs the name of the file for intensity data.
+QString intensityDataFileName(const QString& itemName, const QString& prefix);
+} // namespace
+
+//! Constructs the name of the file with simulated intensities.
+
+QString ItemFileNameUtils::jobResultsFileName(const JobItem& jobItem)
+{
+    return intensityDataFileName(jobItem.itemName(), jobdata_file_prefix);
+}
+
+//! Constructs the name of the file with reference data.
+
+QString ItemFileNameUtils::jobReferenceFileName(const JobItem& jobItem)
+{
+    return intensityDataFileName(jobItem.itemName(), refdata_file_prefix);
+}
+
+QString ItemFileNameUtils::jobNativeDataFileName(const JobItem& jobItem)
+{
+    return intensityDataFileName(jobItem.getIdentifier(), nativedata_file_prefix);
+}
+
+//! Constructs the name of the intensity file belonging to real data item.
+
+QString ItemFileNameUtils::realDataFileName(const RealDataItem& realDataItem)
+{
+    return intensityDataFileName(realDataItem.itemName(), realdata_file_prefix);
+}
+
+QString ItemFileNameUtils::nativeDataFileName(const RealDataItem& realDataItem)
+{
+    return intensityDataFileName(realDataItem.itemName(), nativedata_file_prefix);
+}
+
+QString ItemFileNameUtils::instrumentDataFileName(const InstrumentItem& instrumentItem)
+{
+    auto instrument_id = instrumentItem.getItemValue(InstrumentItem::P_IDENTIFIER).toString();
+    return intensityDataFileName(instrument_id, instrument_file_prefix);
+}
+
+//! Returns list of fileName filters related to nonXML data stored by JobModel and RealDataModel.
+
+QStringList ItemFileNameUtils::nonXMLFileNameFilters()
+{
+    QStringList result = QStringList() << QString(jobdata_file_prefix + "_*.int.gz")
+                                       << QString(refdata_file_prefix + "_*.int.gz")
+                                       << QString(realdata_file_prefix + "_*.int.gz")
+                                       << QString(nativedata_file_prefix + "_*.int.gz")
+                                       << QString(instrument_file_prefix + "_*.int.gz");
+
+    return result;
+}
+
+namespace
+{
+QString intensityDataFileName(const QString& itemName, const QString& prefix)
+{
+    QString bodyName = GUIHelpers::getValidFileName(itemName);
+    return QString("%1_%2_0.int.gz").arg(prefix).arg(bodyName);
+}
+} // namespace
diff --git a/GUI/coregui/Models/JobItemFunctions.h b/GUI/coregui/Models/ItemFileNameUtils.h
similarity index 70%
rename from GUI/coregui/Models/JobItemFunctions.h
rename to GUI/coregui/Models/ItemFileNameUtils.h
index 109d8c012045d865152384405724c8af36015deb..6f1f83b5fbe94b665109efd3d403abaef8cce728 100644
--- a/GUI/coregui/Models/JobItemFunctions.h
+++ b/GUI/coregui/Models/ItemFileNameUtils.h
@@ -2,8 +2,8 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      GUI/coregui/Models/JobItemFunctions.h
-//! @brief     Defines auxiliary functions in JobItemFunctions namespace.
+//! @file      GUI/coregui/Models/ItemFileNameUtils.h
+//! @brief     Defines auxiliary functions in ItemFileNameUtils namespace.
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -18,20 +18,27 @@
 #include "WinDllMacros.h"
 #include <QString>
 
+class InstrumentItem;
 class JobItem;
 class RealDataItem;
 
 //! Contains set of convenience methods for JobItem and its children.
 
-namespace JobItemFunctions
+namespace ItemFileNameUtils
 {
 
 BA_CORE_API_ QString jobResultsFileName(const JobItem& jobItem);
 
 BA_CORE_API_ QString jobReferenceFileName(const JobItem& jobItem);
 
+BA_CORE_API_ QString jobNativeDataFileName(const JobItem& jobItem);
+
 BA_CORE_API_ QString realDataFileName(const RealDataItem& realDataItem);
 
+BA_CORE_API_ QString nativeDataFileName(const RealDataItem& realDataItem);
+
+BA_CORE_API_ QString instrumentDataFileName(const InstrumentItem& instrumentItem);
+
 BA_CORE_API_ QStringList nonXMLFileNameFilters();
 
 }
diff --git a/GUI/coregui/Models/JobItem.cpp b/GUI/coregui/Models/JobItem.cpp
index 2fcb20409d7bcf8e606296ae47eba105faae669c..e818f850ac130a37f1c51bb63422029a13bd3a80 100644
--- a/GUI/coregui/Models/JobItem.cpp
+++ b/GUI/coregui/Models/JobItem.cpp
@@ -19,8 +19,9 @@
 #include "GUIHelpers.h"
 #include "InstrumentItems.h"
 #include "IntensityDataItem.h"
-#include "JobItemFunctions.h"
+#include "ItemFileNameUtils.h"
 #include "JobItemUtils.h"
+#include "MaterialItemContainer.h"
 #include "MaskUnitsConverter.h"
 #include "MultiLayerItem.h"
 #include "ParameterTreeItems.h"
@@ -41,6 +42,7 @@ const QString JobItem::P_COMMENTS = "Comments";
 const QString JobItem::P_PROGRESS = "Progress";
 const QString JobItem::P_PRESENTATION_TYPE = "Presentation Type";
 const QString JobItem::T_SAMPLE = "Sample Tag";
+const QString JobItem::T_MATERIAL_CONTAINER = "Material Container";
 const QString JobItem::T_INSTRUMENT = "Instrument Tag";
 const QString JobItem::T_OUTPUT = "Output Tag";
 const QString JobItem::T_REALDATA = "Real Data Tag";
@@ -71,10 +73,12 @@ JobItem::JobItem() : SessionItem(Constants::JobItemType)
     addProperty(P_PRESENTATION_TYPE, QVariant::Type::Invalid)->setVisible(false);
 
     registerTag(T_SAMPLE, 1, 1, QStringList() << Constants::MultiLayerType);
+    registerTag(T_MATERIAL_CONTAINER, 1, 1, QStringList{Constants::MaterialContainerType});
     registerTag(T_INSTRUMENT, 1, 1,
                 QStringList() << Constants::GISASInstrumentType
                               << Constants::OffSpecInstrumentType
-                              << Constants::SpecularInstrumentType);
+                              << Constants::SpecularInstrumentType
+                              << Constants::DepthProbeInstrumentType);
     registerTag(T_OUTPUT, 1, 1, QStringList() << Constants::IntensityDataType
                 << Constants::SpecularDataType);
     registerTag(T_REALDATA, 1, 1, QStringList() << Constants::RealDataType);
@@ -225,7 +229,7 @@ InstrumentItem* JobItem::instrumentItem()
 
 void JobItem::setResults(const Simulation* simulation)
 {
-    JobItemUtils::setResults(this, simulation);
+    JobItemUtils::setResults(dataItem(), simulation);
     updateIntensityDataFileName();
 }
 
@@ -258,6 +262,11 @@ RealDataItem* JobItem::realDataItem()
     return dynamic_cast<RealDataItem*>(getItem(JobItem::T_REALDATA));
 }
 
+const MaterialItemContainer* JobItem::materialContainerItem() const
+{
+    return static_cast<MaterialItemContainer*>(getItem(JobItem::T_MATERIAL_CONTAINER));
+}
+
 Data1DViewItem* JobItem::dataItemView()
 {
     return dynamic_cast<Data1DViewItem*>(getItem(JobItem::T_DATAVIEW));
@@ -269,12 +278,17 @@ void JobItem::updateIntensityDataFileName()
 {
     if (DataItem* item = dataItem())
         item->setItemValue(DataItem::P_FILE_NAME,
-                           JobItemFunctions::jobResultsFileName(*this));
+                           ItemFileNameUtils::jobResultsFileName(*this));
 
-    if (RealDataItem* realItem = realDataItem())
+    if (RealDataItem* realItem = realDataItem()) {
         if (DataItem* item = realItem->dataItem())
             item->setItemValue(DataItem::P_FILE_NAME,
-                               JobItemFunctions::jobReferenceFileName(*this));
+                               ItemFileNameUtils::jobReferenceFileName(*this));
+
+        if (DataItem* item = realItem->nativeData())
+            item->setItemValue(DataItem::P_FILE_NAME,
+                               ItemFileNameUtils::jobNativeDataFileName(*this));
+    }
 }
 
 SimulationOptionsItem* JobItem::simulationOptionsItem()
diff --git a/GUI/coregui/Models/JobItem.h b/GUI/coregui/Models/JobItem.h
index 3201716c4dc31dcfd76ff5e8cd9d404bae6aea9d..07652cd4db88c4067e92bcec1d2f1f13f1c2a87a 100644
--- a/GUI/coregui/Models/JobItem.h
+++ b/GUI/coregui/Models/JobItem.h
@@ -23,6 +23,7 @@ class FitParameterContainerItem;
 class FitSuiteItem;
 class InstrumentItem;
 class IntensityDataItem;
+class MaterialItemContainer;
 class MultiLayerItem;
 class ParameterContainerItem;
 class RealDataItem;
@@ -45,6 +46,7 @@ public:
     static const QString P_PROGRESS;
     static const QString P_PRESENTATION_TYPE;
     static const QString T_SAMPLE;
+    static const QString T_MATERIAL_CONTAINER;
     static const QString T_INSTRUMENT;
     static const QString T_OUTPUT;
     static const QString T_REALDATA;
@@ -101,6 +103,8 @@ public:
     FitParameterContainerItem* fitParameterContainerItem();
     RealDataItem* realDataItem();
 
+    const MaterialItemContainer* materialContainerItem() const;
+
     Data1DViewItem* dataItemView();
 
 private:
diff --git a/GUI/coregui/Models/JobItemFunctions.cpp b/GUI/coregui/Models/JobItemFunctions.cpp
deleted file mode 100644
index 635f81c4b83b7edadb37c55013b269eb64332748..0000000000000000000000000000000000000000
--- a/GUI/coregui/Models/JobItemFunctions.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      GUI/coregui/Models/JobItemFunctions.cpp
-//! @brief     Defines auxiliary functions in JobItemFunctions namespace.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "JobItemFunctions.h"
-#include "GUIHelpers.h"
-#include "JobItem.h"
-#include "RealDataItem.h"
-#include "item_constants.h"
-
-namespace JobItemFunctions
-{
-const QString jobdata_file_prefix = "jobdata";
-const QString refdata_file_prefix = "refdata";
-const QString realdata_file_prefix = "realdata";
-
-QString intensityDataFileName(const QString& itemName, const QString& prefix);
-}
-
-//! Constructs the name of the file for intensity data.
-
-QString JobItemFunctions::intensityDataFileName(const QString& itemName, const QString& prefix)
-{
-    QString bodyName = GUIHelpers::getValidFileName(itemName);
-    return QString("%1_%2_0.int.gz").arg(prefix).arg(bodyName);
-}
-
-//! Constructs the name of the file with simulated intensities.
-
-QString JobItemFunctions::jobResultsFileName(const JobItem& jobItem)
-{
-    return JobItemFunctions::intensityDataFileName(jobItem.itemName(), jobdata_file_prefix);
-}
-
-//! Constructs the name of the file with reference data.
-
-QString JobItemFunctions::jobReferenceFileName(const JobItem& jobItem)
-{
-    return JobItemFunctions::intensityDataFileName(jobItem.itemName(), refdata_file_prefix);
-}
-
-//! Constructs the name of the intensity file belonging to real data item.
-
-QString JobItemFunctions::realDataFileName(const RealDataItem& realDataItem)
-{
-    return JobItemFunctions::intensityDataFileName(realDataItem.itemName(), realdata_file_prefix);
-}
-
-//! Returns list of fileName filters related to nonXML data stored by JobModel and RealDataModel.
-
-QStringList JobItemFunctions::nonXMLFileNameFilters()
-{
-    QStringList result = QStringList()
-        << QString(jobdata_file_prefix+"_*.int.gz")
-        << QString(refdata_file_prefix+"_*.int.gz")
-        << QString(realdata_file_prefix+"_*.int.gz");
-
-    return result;
-}
-
diff --git a/GUI/coregui/Models/JobItemUtils.cpp b/GUI/coregui/Models/JobItemUtils.cpp
index b3c981e0d53e65225db8725b3452c2b01092d52c..5b4e408f748e6d2007dfef52afd7c0fdcba8c7b6 100644
--- a/GUI/coregui/Models/JobItemUtils.cpp
+++ b/GUI/coregui/Models/JobItemUtils.cpp
@@ -17,7 +17,6 @@
 #include "DomainObjectBuilder.h"
 #include "GUIHelpers.h"
 #include "InstrumentItems.h"
-#include "IntensityDataIOFactory.h"
 #include "DataItem.h"
 #include "JobItem.h"
 #include "RealDataItem.h"
@@ -28,48 +27,22 @@
 
 namespace
 {
-QMap<QString, AxesUnits> init_units_to_description_map()
-{
-    QMap<QString, AxesUnits> result;
-    result[Constants::UnitsNbins] = AxesUnits::NBINS;
-    result[Constants::UnitsRadians] = AxesUnits::RADIANS;
-    result[Constants::UnitsDegrees] = AxesUnits::DEGREES;
-    result[Constants::UnitsMm] = AxesUnits::MM;
-    result[Constants::UnitsQyQz] = AxesUnits::QSPACE;
-    return result;
-}
-
-QMap<AxesUnits, QString> init_description_to_units_map()
-{
-    QMap<AxesUnits, QString> result;
-    result[AxesUnits::NBINS] = Constants::UnitsNbins;
-    result[AxesUnits::RADIANS] = Constants::UnitsRadians;
-    result[AxesUnits::DEGREES] = Constants::UnitsDegrees;
-    result[AxesUnits::MM] = Constants::UnitsMm;
-    result[AxesUnits::QSPACE] = Constants::UnitsQyQz;
-    return result;
-}
-
-//! Sets simulation results into the DataItem
-void setResultsToDataItem(DataItem* intensityItem, const Simulation* simulation);
+const std::map<QString, AxesUnits> units_from_names{{Constants::UnitsNbins, AxesUnits::NBINS},
+                                                    {Constants::UnitsRadians, AxesUnits::RADIANS},
+                                                    {Constants::UnitsDegrees, AxesUnits::DEGREES},
+                                                    {Constants::UnitsMm, AxesUnits::MM},
+                                                    {Constants::UnitsQyQz, AxesUnits::QSPACE}};
+
+const std::map<AxesUnits, QString> names_from_units{{AxesUnits::NBINS, Constants::UnitsNbins},
+                                                    {AxesUnits::RADIANS, Constants::UnitsRadians},
+                                                    {AxesUnits::MM, Constants::UnitsMm},
+                                                    {AxesUnits::QSPACE, Constants::UnitsQyQz},
+                                                    {AxesUnits::DEGREES, Constants::UnitsDegrees}};
 
 //! Updates axes' titles
 void updateAxesTitle(DataItem* intensityItem, const IUnitConverter& converter, AxesUnits units);
 }
 
-void JobItemUtils::setResults(JobItem* jobItem, const Simulation* simulation)
-{
-    auto dataItem = jobItem->dataItem();
-    Q_ASSERT(dataItem);
-
-    if (dataItem->modelType() == Constants::IntensityDataType
-        || dataItem->modelType() == Constants::SpecularDataType) {
-        setResultsToDataItem(dataItem, simulation);
-    } else {
-        throw GUIHelpers::Error("JobItemUtils::setResults() -> Error. Unsupported data item.");
-    }
-}
-
 //! Updates axes of OutputData in IntensityData item to correspond with ::P_AXES_UNITS selection.
 //! InstrumentItem is used to get domain's detector map for given units.
 
@@ -100,41 +73,18 @@ void JobItemUtils::updateDataAxes(DataItem* intensityItem,
     updateAxesTitle(intensityItem, *converter, requested_units);
 }
 
-//! loads intensity data from project directory
-
-void JobItemUtils::loadIntensityData(DataItem *intensityItem, const QString &projectDir)
-{
-    QString filename = intensityItem->fileName(projectDir);
-    auto data = IntensityDataIOFactory::readOutputData(filename.toStdString());
-    if (data)
-        intensityItem->setOutputData(data);
-}
-
-
-//! Saves intensityData in project directory
-
-void JobItemUtils::saveIntensityData(DataItem* intensityItem, const QString& projectDir)
-{
-    if (!intensityItem)
-        return;
-
-    intensityItem->saveData(projectDir);
-}
-
 //! Correspondance of domain detector axes types to their gui counterpart.
 
 QString JobItemUtils::nameFromAxesUnits(AxesUnits units)
 {
-    static QMap<AxesUnits, QString> units_to_name = init_description_to_units_map();
-    return units_to_name[units];
+    return names_from_units.at(units);
 }
 
 //! Correspondance of GUI axes units names to their domain counterpart.
 
 AxesUnits JobItemUtils::axesUnitsFromName(const QString& name)
 {
-    static QMap<QString, AxesUnits> name_to_units = init_units_to_description_map();
-    return name_to_units[name];
+    return units_from_names.at(name);
 }
 
 //! Sets axes units suitable for given instrument.
@@ -142,25 +92,16 @@ AxesUnits JobItemUtils::axesUnitsFromName(const QString& name)
 void JobItemUtils::setIntensityItemAxesUnits(DataItem* intensityItem,
                                               const InstrumentItem* instrumentItem)
 {
-    if (!instrumentItem) {
-        intensityItem->resetToDefault();
-        return;
-    }
     const auto converter = DomainObjectBuilder::createUnitConverter(instrumentItem);
+    if (!converter)
+        return;
     setIntensityItemAxesUnits(intensityItem, *converter);
 }
 
 void JobItemUtils::setIntensityItemAxesUnits(DataItem *intensityItem,
                                              const IUnitConverter& converter)
 {
-    ComboProperty combo;
-
-    for (auto units : converter.availableUnits())
-        combo << nameFromAxesUnits(units);
-
-    AxesUnits preferrable_units = converter.defaultUnits();
-
-    combo.setValue(nameFromAxesUnits(preferrable_units));
+    ComboProperty combo = availableUnits(converter);
     intensityItem->setItemValue(DataItem::P_AXES_UNITS, combo.variant());
 }
 
@@ -174,9 +115,7 @@ void JobItemUtils::createDefaultDetectorMap(DataItem* intensityItem,
     updateAxesTitle(intensityItem, *converter, converter->defaultUnits());
 }
 
-namespace
-{
-void setResultsToDataItem(DataItem* intensityItem, const Simulation* simulation)
+void JobItemUtils::setResults(DataItem* intensityItem, const Simulation* simulation)
 {
     const auto sim_result = simulation->result();
     if (intensityItem->getOutputData() == nullptr) {
@@ -189,6 +128,18 @@ void setResultsToDataItem(DataItem* intensityItem, const Simulation* simulation)
     intensityItem->setOutputData(data.release());
 }
 
+ComboProperty JobItemUtils::availableUnits(const IUnitConverter& converter)
+{
+    ComboProperty result;
+    for (auto units : converter.availableUnits())
+        result << nameFromAxesUnits(units);
+
+    result.setValue(nameFromAxesUnits(converter.defaultUnits()));
+    return result;
+}
+
+namespace
+{
 void updateAxesTitle(DataItem* intensityItem, const IUnitConverter& converter,
                      AxesUnits units)
 {
diff --git a/GUI/coregui/Models/JobItemUtils.h b/GUI/coregui/Models/JobItemUtils.h
index 0d717ba43f5f4a3e0e4c4f5652a1eca428570645..d517b755dab61042f6e8e6fc6a4e39d8a8f142fb 100644
--- a/GUI/coregui/Models/JobItemUtils.h
+++ b/GUI/coregui/Models/JobItemUtils.h
@@ -15,6 +15,7 @@
 #ifndef JOBITEMUTILS_H
 #define JOBITEMUTILS_H
 
+#include "ComboProperty.h"
 #include "IDetector.h"
 #include <QMap>
 
@@ -28,20 +29,10 @@ class Simulation;
 
 namespace JobItemUtils
 {
-
-//! Sets simulation results to the JobItem.
-BA_CORE_API_ void setResults(JobItem* jobItem, const Simulation* simulation);
-
 //! updates axes of OutputData in IntensityData item
 BA_CORE_API_ void updateDataAxes(DataItem* intensityItem,
                                  const InstrumentItem* instrumentItem);
 
-//! loads intensity data from project directory
-BA_CORE_API_ void loadIntensityData(DataItem* intensityItem, const QString& projectDir);
-
-//! saves intensity data into project directory
-BA_CORE_API_ void saveIntensityData(DataItem* intensityItem, const QString& projectDir);
-
 //! returns axes units names from their domain counterpart
 BA_CORE_API_ QString nameFromAxesUnits(AxesUnits units);
 
@@ -56,6 +47,11 @@ BA_CORE_API_ void setIntensityItemAxesUnits(DataItem* intensityItem,
 
 BA_CORE_API_ void createDefaultDetectorMap(DataItem* intensityItem,
                                            const InstrumentItem* instrumentItem);
+
+//! Sets simulation results into the DataItem
+BA_CORE_API_ void setResults(DataItem* intensityItem, const Simulation* simulation);
+
+BA_CORE_API_ ComboProperty availableUnits(const IUnitConverter& converter);
 }
 
 #endif // JOBITEMUTILS_H
diff --git a/GUI/coregui/Models/JobModel.cpp b/GUI/coregui/Models/JobModel.cpp
index 90996aa5812a88497435baccead3577a7f913534..b9a55c51c11d96b4a050970450874ce56d3558ef 100644
--- a/GUI/coregui/Models/JobModel.cpp
+++ b/GUI/coregui/Models/JobModel.cpp
@@ -13,7 +13,9 @@
 // ************************************************************************** //
 
 #include "JobModel.h"
+#include "AxesItems.h"
 #include "FitSuiteItem.h"
+#include "GroupItem.h"
 #include "GUIHelpers.h"
 #include "InstrumentItems.h"
 #include "IntensityDataItem.h"
@@ -29,7 +31,7 @@
 
 JobModel::JobModel(QObject *parent)
     : SessionModel(SessionXML::JobModelTag, parent)
-    , m_queue_data(0)
+    , m_queue_data(nullptr)
 {
     m_queue_data = new JobQueueData(this);
     connect(m_queue_data, SIGNAL(focusRequest(JobItem *)), this, SIGNAL(focusRequest(JobItem *)));
@@ -64,7 +66,7 @@ JobItem *JobModel::getJobItemForIdentifier(const QString &identifier)
         JobItem *jobItem = getJobItemForIndex(itemIndex);
         if(jobItem->getIdentifier() == identifier) return jobItem;
     }
-    return 0;
+    return nullptr;
 }
 
 
@@ -82,14 +84,15 @@ JobItem *JobModel::addJob(const MultiLayerItem *multiLayerItem,
     jobItem->setItemName(generateJobName());
     jobItem->setIdentifier(GUIHelpers::createUuid());
 
-    SessionItem *multilayer = copyItem(multiLayerItem, jobItem, JobItem::T_SAMPLE);
-    multilayer->setItemName(Constants::MultiLayerType);
-    SessionItem *instrument = copyItem(instrumentItem, jobItem, JobItem::T_INSTRUMENT);
-    instrument->setItemName(instrumentItem->modelType());
+    JobModelFunctions::setupJobItemSampleData(jobItem, multiLayerItem);
+    JobModelFunctions::setupJobItemInstrument(jobItem, instrumentItem);
+
+    // TODO: remove when specular instrument is ready for magnetization
+    if (instrumentItem->modelType() == Constants::SpecularInstrumentType)
+        JobModelFunctions::muteMagnetizationData(jobItem);
     copyItem(optionItem, jobItem, JobItem::T_SIMULATION_OPTIONS);
 
     jobItem->getItem(JobItem::P_SAMPLE_NAME)->setValue(multiLayerItem->itemName());
-    jobItem->getItem(JobItem::P_INSTRUMENT_NAME)->setValue(instrumentItem->itemName());
 
     ParameterTreeUtils::createParameterTree(jobItem);
 
@@ -137,6 +140,15 @@ QVector<SessionItem *> JobModel::nonXMLData() const
         if (auto real_data = dynamic_cast<RealDataItem*>(jobItem->getItem(JobItem::T_REALDATA))) {
             if (auto data_item = real_data->dataItem())
                 result.push_back(data_item);
+            if (auto native_data = real_data->nativeData())
+                result.push_back(native_data);
+        }
+
+        auto instrument =
+            dynamic_cast<SpecularInstrumentItem*>(jobItem->getItem(JobItem::T_INSTRUMENT));
+        if (instrument) {
+            auto axis_group = instrument->beamItem()->inclinationAxisGroup();
+            result.push_back(axis_group->getChildOfType(Constants::PointwiseAxisType));
         }
     }
 
diff --git a/GUI/coregui/Models/JobModelFunctions.cpp b/GUI/coregui/Models/JobModelFunctions.cpp
index 04b1e39ffcd57900cb3459e5b83c7823454843f4..a12cb6cd5551d8141ec897590620c98f27a4fdc6 100644
--- a/GUI/coregui/Models/JobModelFunctions.cpp
+++ b/GUI/coregui/Models/JobModelFunctions.cpp
@@ -13,32 +13,130 @@
 // ************************************************************************** //
 
 #include "JobModelFunctions.h"
-#include "DataViewUtils.h"
+#include "Data1DViewItem.h"
+#include "DataPropertyContainer.h"
 #include "DetectorFunctions.h"
 #include "DetectorItems.h"
 #include "DomainObjectBuilder.h"
 #include "FitSuiteItem.h"
+#include "GroupItem.h"
 #include "GUIHelpers.h"
 #include "IDetector2D.h"
 #include "Instrument.h"
 #include "InstrumentItems.h"
 #include "IntensityDataItem.h"
 #include "JobItem.h"
-#include "JobItemFunctions.h"
+#include "ItemFileNameUtils.h"
 #include "JobItemUtils.h"
 #include "JobModel.h"
+#include "MaterialItemContainer.h"
+#include "MaterialItemUtils.h"
 #include "MaskItems.h"
 #include "MaskUnitsConverter.h"
+#include "MultiLayerItem.h"
+#include "PointwiseAxisItem.h"
 #include "RealDataItem.h"
+#include <map>
 
-namespace JobModelFunctions
+namespace
 {
-void copyRealDataItem(JobItem* jobItem, const RealDataItem* realDataItem);
+//! Links RealDataItem to the JobItem's instrument.
+// (re-)Linking is necessary because of following reason
+// 1) Copying of RealDataItem from RealDataModel on board of JobItem requires relink to the copied
+//    insturment
+// 2) During relink all masks (if exists) will be converted to the default units of current detector
 void processInstrumentLink(JobItem* jobItem);
+
+//! Copies masks and ROI from RealDataItem on board of instrument.
 void copyMasksToInstrument(JobItem* jobItem);
+
+//! Crops RealDataItem to the region of interest.
 void cropRealData(JobItem* jobItem);
+
+//! Creates necessary fit containers for jobItem intended for fitting.
 void createFitContainers(JobItem* jobItem);
-void initDataView(JobItem* jobItem);
+
+PointwiseAxisItem* getPointwiseAxisItem(const SpecularInstrumentItem* instrument);
+} // namespace
+
+void JobModelFunctions::initDataView(JobItem* job_item)
+{
+    assert(job_item && job_item->isValidForFitting());
+    assert(job_item->instrumentItem()
+           && job_item->instrumentItem()->modelType() == Constants::SpecularInstrumentType);
+    assert(!job_item->getItem(JobItem::T_DATAVIEW));
+
+    SessionModel* model = job_item->model();
+    auto view_item = dynamic_cast<Data1DViewItem*>(model->insertNewItem(
+        Constants::Data1DViewItemType, job_item->index(), -1, JobItem::T_DATAVIEW));
+    assert(view_item);
+
+    auto property_container = dynamic_cast<DataPropertyContainer*>(model->insertNewItem(
+        Constants::DataPropertyContainerType, view_item->index(), -1, Data1DViewItem::T_DATA_PROPERTIES));
+    assert(property_container);
+
+    property_container->addItem(job_item->realDataItem()->dataItem());
+    property_container->addItem(job_item->dataItem());
+
+    // also triggers Data1DViewItem::setAxesRangeToData and DataViewUtils::updateAxesTitle by
+    // setting new value of P_AXES_UNITS.
+    auto converter = DomainObjectBuilder::createUnitConverter(job_item->instrumentItem());
+    view_item->setItemValue(Data1DViewItem::P_AXES_UNITS,
+                            JobItemUtils::availableUnits(*converter).variant());
+}
+
+void JobModelFunctions::setupJobItemSampleData(JobItem* jobItem, const MultiLayerItem* sampleItem)
+{
+    auto model = jobItem->model();
+    MultiLayerItem* multilayer =
+        static_cast<MultiLayerItem*>(model->copyItem(sampleItem, jobItem, JobItem::T_SAMPLE));
+    multilayer->setItemName(Constants::MultiLayerType);
+
+    // copying materials
+    auto container = static_cast<MaterialItemContainer*>(jobItem->model()->insertNewItem(
+        Constants::MaterialContainerType, jobItem->index(), -1, JobItem::T_MATERIAL_CONTAINER));
+
+    std::map<MaterialItem*, QString> materials;
+    for (auto property_item: multilayer->materialPropertyItems()) {
+        auto material_property = property_item->value().value<ExternalProperty>();
+        auto material = MaterialItemUtils::findMaterial(material_property);
+
+        auto iter = materials.find(material);
+        if (iter == materials.end()) {
+            auto material_copy = container->insertCopy(material);
+            materials.insert({material, material_copy->identifier()});
+            material_property.setIdentifier(material_copy->identifier());
+        } else
+            material_property.setIdentifier(iter->second);
+        property_item->setValue(material_property.variant());
+    }
+}
+
+void JobModelFunctions::setupJobItemInstrument(JobItem* jobItem,
+                                               const InstrumentItem* from)
+{
+    auto model = jobItem->model();
+    SessionItem* to = model->copyItem(from, jobItem, JobItem::T_INSTRUMENT);
+    to->setItemName(from->modelType());
+    to->setItemValue(InstrumentItem::P_IDENTIFIER, GUIHelpers::createUuid());
+    jobItem->getItem(JobItem::P_INSTRUMENT_NAME)->setValue(from->itemName());
+
+    auto spec_to = dynamic_cast<SpecularInstrumentItem*>(to);
+    if (!spec_to)
+        return;
+
+    // updating filename
+    const auto filename = ItemFileNameUtils::instrumentDataFileName(*spec_to);
+    spec_to->beamItem()->updateFileName(filename);
+
+    // copying axis data
+    auto spec_from = static_cast<const SpecularInstrumentItem*>(from);
+    auto axis_origin = getPointwiseAxisItem(spec_from);
+    const QString current_axis_type= spec_from->beamItem()->inclinationAxisGroup()->currentType();
+    if (current_axis_type == Constants::PointwiseAxisType)
+        spec_to->beamItem()->updateToData(*axis_origin->getAxis(), axis_origin->getUnitsLabel());
+    else if(axis_origin->containsNonXMLData())
+        getPointwiseAxisItem(spec_to)->init(*axis_origin->getAxis(), axis_origin->getUnitsLabel());
 }
 
 //! Setup items intended for storing results of the job.
@@ -53,7 +151,8 @@ void JobModelFunctions::setupJobItemOutput(JobItem* jobItem)
                              JobItem::T_OUTPUT);
 
     } else if (instrumentType == Constants::GISASInstrumentType
-               || instrumentType == Constants::OffSpecInstrumentType) {
+               || instrumentType == Constants::OffSpecInstrumentType
+               || instrumentType == Constants::DepthProbeInstrumentType ) {
         model->insertNewItem(Constants::IntensityDataType, model->indexOfItem(jobItem), -1,
                              JobItem::T_OUTPUT);
 
@@ -71,20 +170,29 @@ void JobModelFunctions::setupJobItemForFit(JobItem* jobItem, const RealDataItem*
         throw GUIHelpers::Error("JobModelFunctions::processInstrumentLink() -> Error. "
                                 "No instrument.");
 
-    JobModelFunctions::copyRealDataItem(jobItem, realDataItem);
-    JobModelFunctions::processInstrumentLink(jobItem);
-    JobModelFunctions::copyMasksToInstrument(jobItem);
+    copyRealDataItem(jobItem, realDataItem);
+    processInstrumentLink(jobItem);
+    copyMasksToInstrument(jobItem);
 
     // TODO: remove if when other simulation types are ready for roi & masks
     if (jobItem->instrumentItem()->modelType() == Constants::GISASInstrumentType)
-        JobModelFunctions::cropRealData(jobItem);
+        cropRealData(jobItem);
     if (jobItem->instrumentItem()->modelType() == Constants::SpecularInstrumentType)
-        DataViewUtils::initDataView(jobItem);
+        initDataView(jobItem);
 
-    JobModelFunctions::createFitContainers(jobItem);
+    createFitContainers(jobItem);
 }
 
-//! Copy RealDataItem to jobItem intended for fitting.
+void JobModelFunctions::muteMagnetizationData(JobItem* jobItem)
+{
+    auto container =
+        static_cast<MaterialItemContainer*>(jobItem->getItem(JobItem::T_MATERIAL_CONTAINER));
+    for (auto item : container->getItems(MaterialItemContainer::T_MATERIALS))
+        item->getItem(MaterialItem::P_MAGNETIZATION)->setVisible(false);
+
+    auto sample = static_cast<MultiLayerItem*>(jobItem->getItem(JobItem::T_SAMPLE));
+    sample->getItem(MultiLayerItem::P_EXTERNAL_FIELD)->setVisible(false);
+}
 
 void JobModelFunctions::copyRealDataItem(JobItem* jobItem, const RealDataItem* realDataItem)
 {
@@ -101,16 +209,26 @@ void JobModelFunctions::copyRealDataItem(JobItem* jobItem, const RealDataItem* r
 
     // adapting the name to job name
     realDataItemCopy->dataItem()->setItemValue(DataItem::P_FILE_NAME,
-                                               JobItemFunctions::jobReferenceFileName(*jobItem));
+                                               ItemFileNameUtils::jobReferenceFileName(*jobItem));
+
+    if (!realDataItem->nativeData())
+        return;
+
+    realDataItemCopy->nativeData()->setOutputData(
+        realDataItem->nativeData()->getOutputData()->clone());
+    realDataItemCopy->nativeData()->setItemValue(
+        DataItem::P_FILE_NAME, ItemFileNameUtils::jobNativeDataFileName(*jobItem));
 }
 
-//! Links RealDataItem to the JobItem's instrument.
-// (re-)Linking is necessary because of following reason
-// 1) Copying of RealDataItem from RealDataModel on board of JobItem requires relink to the copied
-//    insturment
-// 2) During relink all masks (if exists) will be converted to the default units of current detector
+const JobItem* JobModelFunctions::findJobItem(const SessionItem* item)
+{
+    while (item && item->modelType() != Constants::JobItemType)
+        item = item->parent();
+    return static_cast<const JobItem*>(item);
+}
 
-void JobModelFunctions::processInstrumentLink(JobItem* jobItem)
+namespace {
+void processInstrumentLink(JobItem* jobItem)
 {
     RealDataItem* realData = jobItem->realDataItem();
     if (!realData)
@@ -119,17 +237,13 @@ void JobModelFunctions::processInstrumentLink(JobItem* jobItem)
     realData->linkToInstrument(jobItem->instrumentItem());
 }
 
-//! Copies masks and ROI from RealDataItem on board of instrument.
-
-void JobModelFunctions::copyMasksToInstrument(JobItem* jobItem)
+void copyMasksToInstrument(JobItem* jobItem)
 {
     auto mask_container = jobItem->realDataItem()->maskContainerItem();
     jobItem->instrumentItem()->importMasks(mask_container);
 }
 
-//! Crops RealDataItem to the region of interest.
-
-void JobModelFunctions::cropRealData(JobItem* jobItem)
+void cropRealData(JobItem* jobItem)
 {
     RealDataItem* realData = jobItem->realDataItem();
 
@@ -151,9 +265,7 @@ void JobModelFunctions::cropRealData(JobItem* jobItem)
     intensityItem->updateDataRange();
 }
 
-//! Creates necessary fit containers for jobItem intended for fitting.
-
-void JobModelFunctions::createFitContainers(JobItem* jobItem)
+void createFitContainers(JobItem* jobItem)
 {
     SessionModel* model = jobItem->model();
 
@@ -186,3 +298,11 @@ void JobModelFunctions::createFitContainers(JobItem* jobItem)
     minimizerContainerItem = model->insertNewItem(
         Constants::MinimizerContainerType, fitSuiteItem->index(), -1, FitSuiteItem::T_MINIMIZER);
 }
+
+PointwiseAxisItem* getPointwiseAxisItem(const SpecularInstrumentItem* instrument)
+{
+    return dynamic_cast<PointwiseAxisItem*>(
+        instrument->beamItem()->inclinationAxisGroup()->getChildOfType(
+            Constants::PointwiseAxisType));
+}
+} // namespace
diff --git a/GUI/coregui/Models/JobModelFunctions.h b/GUI/coregui/Models/JobModelFunctions.h
index 724e2cfb36f93026552a46554d222295301ef821..41eca32ccaa306fdc5098d8d2b9da434aa1b439b 100644
--- a/GUI/coregui/Models/JobModelFunctions.h
+++ b/GUI/coregui/Models/JobModelFunctions.h
@@ -17,17 +17,39 @@
 
 #include "WinDllMacros.h"
 
+class InstrumentItem;
 class JobItem;
+class MultiLayerItem;
 class RealDataItem;
+class SessionItem;
 
 //! Contains set of functions to extend JobModel functionality.
 //! Handles setup of JobItem in fitting context.
 
 namespace JobModelFunctions
 {
+//! Initializes Data1DViewItem and assigns it to the passed JobItem
+BA_CORE_API_ void initDataView(JobItem* jobItem);
+
+//! Properly copies sample and materials into JobItem
+BA_CORE_API_ void setupJobItemSampleData(JobItem* jobItem, const MultiLayerItem* sampleItem);
+
+//! Properly copies instrument into job item
+BA_CORE_API_ void setupJobItemInstrument(JobItem* jobItem, const InstrumentItem* from);
+
 BA_CORE_API_ void setupJobItemOutput(JobItem* jobItem);
 
 BA_CORE_API_ void setupJobItemForFit(JobItem* jobItem, const RealDataItem* realDataItem);
+
+BA_CORE_API_ void muteMagnetizationData(JobItem* jobItem);
+
+//! Copy RealDataItem to jobItem intended for fitting.
+BA_CORE_API_ void copyRealDataItem(JobItem* jobItem, const RealDataItem* realDataItem);
+
+//! Determines parenting JobItem of a given SessionItem. Returns nullptr, if there
+//! is no parent of JobItem type
+
+BA_CORE_API_ const JobItem* findJobItem(const SessionItem* item);
 }
 
 #endif // JOBMODELFUNCTIONS_H
diff --git a/GUI/coregui/Models/LayerItem.cpp b/GUI/coregui/Models/LayerItem.cpp
index 97581d3d54aa4c3522664f550d13a378cb528a3e..750cd16b744d9d3534e3cededba4476d1c7e8c37 100644
--- a/GUI/coregui/Models/LayerItem.cpp
+++ b/GUI/coregui/Models/LayerItem.cpp
@@ -57,6 +57,16 @@ LayerItem::LayerItem()
 
 }
 
+QVector<SessionItem*> LayerItem::materialPropertyItems()
+{
+    QVector<SessionItem*> result;
+    if (auto property = getItem(LayerItem::P_MATERIAL))
+        result.push_back(property);
+    for (auto layout : getItems(LayerItem::T_LAYOUTS))
+        result.append(MaterialItemUtils::materialPropertyItems(layout));
+    return result;
+}
+
 void LayerItem::updateAppearance(SessionItem* new_parent)
 {
     if (!new_parent) {
diff --git a/GUI/coregui/Models/LayerItem.h b/GUI/coregui/Models/LayerItem.h
index 918b3b7efddc55c7e0aaa86308b1fa47e2744f4f..619d4334c239af2ed2bbe1d3ab661648747f9ccd 100644
--- a/GUI/coregui/Models/LayerItem.h
+++ b/GUI/coregui/Models/LayerItem.h
@@ -27,6 +27,8 @@ public:
     static const QString T_LAYOUTS;
     LayerItem();
 
+    QVector<SessionItem*> materialPropertyItems();
+
 private:
     void updateAppearance(SessionItem* new_parent);
 };
diff --git a/GUI/coregui/Models/MaterialItemContainer.cpp b/GUI/coregui/Models/MaterialItemContainer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f6b2661a4fbcf9e2439b922aaf7ce0167b94e2ee
--- /dev/null
+++ b/GUI/coregui/Models/MaterialItemContainer.cpp
@@ -0,0 +1,53 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Models/MaterialItemContainer.cpp
+//! @brief     Implements class MaterialItemContainer
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "MaterialItemContainer.h"
+#include "GUIHelpers.h"
+#include "MaterialItem.h"
+#include "SessionModel.h"
+
+const QString MaterialItemContainer::T_MATERIALS = "MaterialVector";
+
+MaterialItemContainer::MaterialItemContainer()
+    :SessionItem(Constants::MaterialContainerType)
+{
+    setItemName("Materials");
+    registerTag(T_MATERIALS, 0, -1, QStringList{Constants::MaterialType});
+}
+
+MaterialItem* MaterialItemContainer::insertCopy(MaterialItem* material_item)
+{
+    MaterialItem* item_copy =
+        dynamic_cast<MaterialItem*>(model()->copyItem(material_item, this, T_MATERIALS));
+    item_copy->setItemValue(MaterialItem::P_IDENTIFIER, GUIHelpers::createUuid());
+
+    return item_copy;
+}
+
+MaterialItem* MaterialItemContainer::findMaterialById(QString id)
+{
+    return const_cast<MaterialItem*>(
+        static_cast<const MaterialItemContainer*>(this)->findMaterialById(id));
+}
+
+const MaterialItem* MaterialItemContainer::findMaterialById(QString id) const
+{
+    auto materials = getItems(T_MATERIALS);
+    for (auto item: materials) {
+        auto material = dynamic_cast<MaterialItem*>(item);
+        if (material->identifier() == id)
+            return material;
+    }
+    return nullptr;
+}
diff --git a/GUI/coregui/Models/MaterialItemContainer.h b/GUI/coregui/Models/MaterialItemContainer.h
new file mode 100644
index 0000000000000000000000000000000000000000..2f3c906da22fd5c105c1ea3860addf43ce8842ab
--- /dev/null
+++ b/GUI/coregui/Models/MaterialItemContainer.h
@@ -0,0 +1,37 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Models/MaterialItemContainer.h
+//! @brief     Defines class MaterialItemContainer
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef MATERIALITEMCONTAINER_H
+#define MATERIALITEMCONTAINER_H
+
+#include "SessionItem.h"
+
+class MaterialItem;
+
+class MaterialItemContainer : public SessionItem
+{
+public:
+    static const QString T_MATERIALS;
+
+    MaterialItemContainer();
+
+    //! Copies MaterialItem, inserts it into the container
+    //! and returns a pointer to the copy.
+    MaterialItem* insertCopy(MaterialItem* material_item);
+
+    const MaterialItem* findMaterialById(QString id) const;
+    MaterialItem* findMaterialById(QString id);
+};
+
+#endif // MATERIALITEMCONTAINER_H
diff --git a/GUI/coregui/Models/MesoCrystalItem.h b/GUI/coregui/Models/MesoCrystalItem.h
index e33acd0184bcd777f4af5c5e48f375e5c5ef3a09..bfafa510598cc38b2915defaa97c76cd20f68a31 100644
--- a/GUI/coregui/Models/MesoCrystalItem.h
+++ b/GUI/coregui/Models/MesoCrystalItem.h
@@ -38,7 +38,6 @@ public:
 
     QStringList translateList(const QStringList& list) const override;
 
-private:
     Lattice getLattice() const;
     std::unique_ptr<IParticle> getBasis() const;
     std::unique_ptr<IFormFactor> getOuterShape() const;
diff --git a/GUI/coregui/Models/MinimizerItem.cpp b/GUI/coregui/Models/MinimizerItem.cpp
index 80555c23fb3cb4811e9ba8f62b58514cb6fa00d4..11e130ac802eba9e64f9128d1f1c50b60b3d4a9b 100644
--- a/GUI/coregui/Models/MinimizerItem.cpp
+++ b/GUI/coregui/Models/MinimizerItem.cpp
@@ -21,6 +21,15 @@
 #include "GSLLevenbergMarquardtMinimizer.h"
 #include "SimAnMinimizer.h"
 #include "TestMinimizer.h"
+#include "IIntensityFunction.h"
+#include "VarianceFunctions.h"
+#include "VarianceFunctionItems.h"
+
+namespace  {
+const QString none_fun = "None";
+const QString sqrt_fun = "sqrt";
+const QString log10_fun = "log";
+}
 
 // ----------------------------------------------------------------------------
 
@@ -31,11 +40,22 @@ MinimizerItem::MinimizerItem(const QString &model_type) : SessionItem(model_type
 // ----------------------------------------------------------------------------
 
 const QString MinimizerContainerItem::P_MINIMIZERS = "Minimizer";
+const QString MinimizerContainerItem::P_INTENSITY_FUNCTION = "Intensity function";
+const QString MinimizerContainerItem::P_VARIANCE_FUNCTIONS = "Variance";
 
 MinimizerContainerItem::MinimizerContainerItem() : MinimizerItem(Constants::MinimizerContainerType)
 {
     addGroupProperty(P_MINIMIZERS, Constants::MinimizerLibraryGroup)
         ->setToolTip(QStringLiteral("Minimizer library"));
+
+    ComboProperty combo = ComboProperty() << none_fun << sqrt_fun << log10_fun;
+    addProperty(P_INTENSITY_FUNCTION, combo.variant())->setToolTip(
+                "Function to apply for both simulated and experimental intensities \n"
+                "before calculating the value of residual.");
+
+    addGroupProperty(P_VARIANCE_FUNCTIONS, Constants::VarianceFunctionGroup)
+        ->setToolTip(QStringLiteral("Variance functions for residual normalization"));
+
 }
 
 std::unique_ptr<IMinimizer> MinimizerContainerItem::createMinimizer() const
@@ -43,6 +63,25 @@ std::unique_ptr<IMinimizer> MinimizerContainerItem::createMinimizer() const
     return groupItem<MinimizerItem>(P_MINIMIZERS).createMinimizer();
 }
 
+std::unique_ptr<IIntensityFunction> MinimizerContainerItem::createIntensityFunction() const
+{
+    QString value = getItemValue(P_INTENSITY_FUNCTION).value<ComboProperty>().getValue();
+
+    if (value == sqrt_fun) {
+        return std::make_unique<IntensityFunctionSqrt>();
+    } else if(value == log10_fun) {
+        return std::make_unique<IntensityFunctionLog>();
+    } else {
+        return std::unique_ptr<IIntensityFunction>();
+    }
+}
+
+std::unique_ptr<IVarianceFunction> MinimizerContainerItem::createVarianceFunction() const
+{
+    auto& variance_item = groupItem<IVarianceFunctionItem>(P_VARIANCE_FUNCTIONS);
+    return variance_item.createVarianceFunction();
+}
+
 // ----------------------------------------------------------------------------
 
 const QString MinuitMinimizerItem::P_ALGORITHMS = "Algorithms";
diff --git a/GUI/coregui/Models/MinimizerItem.h b/GUI/coregui/Models/MinimizerItem.h
index 9c919b5324658c330421b6b227a49b8638cc2c66..d78e681555f0e59b9fdb4f702f51be87398de10d 100644
--- a/GUI/coregui/Models/MinimizerItem.h
+++ b/GUI/coregui/Models/MinimizerItem.h
@@ -18,6 +18,8 @@
 #include "SessionItem.h"
 
 class IMinimizer;
+class IIntensityFunction;
+class IVarianceFunction;
 
 //! The MinimizerItem class is the base item to hold minimizer settings.
 
@@ -34,9 +36,13 @@ class BA_CORE_API_ MinimizerContainerItem : public MinimizerItem
 {
 public:
     static const QString P_MINIMIZERS;
+    static const QString P_INTENSITY_FUNCTION;
+    static const QString P_VARIANCE_FUNCTIONS;
     MinimizerContainerItem();
 
     std::unique_ptr<IMinimizer> createMinimizer() const;
+    std::unique_ptr<IIntensityFunction> createIntensityFunction() const;
+    std::unique_ptr<IVarianceFunction> createVarianceFunction() const;
 };
 
 //! The MinuitMinimizerItem class represents settings for ROOT Minuit2 minimizer.
diff --git a/GUI/coregui/Models/MultiLayerItem.cpp b/GUI/coregui/Models/MultiLayerItem.cpp
index 51b72e01f5ca81204f1e7cfef695c45703abbc64..09efd918e68d25afa5f037e2e01ee48b806dba93 100644
--- a/GUI/coregui/Models/MultiLayerItem.cpp
+++ b/GUI/coregui/Models/MultiLayerItem.cpp
@@ -51,6 +51,14 @@ MultiLayerItem::MultiLayerItem()
     });
 }
 
+QVector<SessionItem*> MultiLayerItem::materialPropertyItems()
+{
+    QVector<SessionItem*> result;
+    for (auto layer_item : getItems(T_LAYERS))
+        result.append(static_cast<LayerItem*>(layer_item)->materialPropertyItems());
+    return result;
+}
+
 void MultiLayerItem::updateLayers()
 {
     QVector<SessionItem*> list = getChildrenOfType(Constants::LayerType);
diff --git a/GUI/coregui/Models/MultiLayerItem.h b/GUI/coregui/Models/MultiLayerItem.h
index 22e0906b647b3196699a5988c23599f615c6edbe..5bc01cc56e3a89c972aa72bf9df126898f3284bf 100644
--- a/GUI/coregui/Models/MultiLayerItem.h
+++ b/GUI/coregui/Models/MultiLayerItem.h
@@ -25,6 +25,8 @@ public:
     static const QString T_LAYERS;
     MultiLayerItem();
 
+    QVector<SessionItem*> materialPropertyItems();
+
 private:
     void updateLayers();
 };
diff --git a/GUI/coregui/Models/ParameterTreeItems.cpp b/GUI/coregui/Models/ParameterTreeItems.cpp
index 43577a148f9a9316ae5f2782801ca3815dd4d1eb..c38c30d812d3ac4874ee260e1d4b63ac100eae02 100644
--- a/GUI/coregui/Models/ParameterTreeItems.cpp
+++ b/GUI/coregui/Models/ParameterTreeItems.cpp
@@ -13,18 +13,9 @@
 // ************************************************************************** //
 
 #include "ParameterTreeItems.h"
-#include "BeamItems.h"
-#include "DistributionItems.h"
 #include "FitParameterHelper.h"
-#include "InstrumentItems.h"
 #include "ModelPath.h"
-#include "RectangularDetectorItem.h"
 #include "SessionModel.h"
-#include "SphericalDetectorItem.h"
-
-namespace {
-bool containsNames(const QString& text, const QStringList& names);
-}
 
 // ----------------------------------------------------------------------------
 
@@ -81,66 +72,6 @@ void ParameterItem::restoreFromBackup()
     propagateValueToLink(newValue);
 }
 
-//! Returns true if item can be used to drag-and-drop to FitParameterContainer.
-//! In other words, if translation to domain name is implemented and valid.
-
-bool ParameterItem::isFittable() const
-{
-    static const QVector<QPair<QStringList, QStringList>> black_list {
-        {// Global scope
-            {
-                QString()
-            },
-            {
-                Constants::DistributionSigmaFactor
-            }
-        },
-        {// Instrument scope
-            {
-                Constants::GISASInstrumentType,
-                Constants::OffSpecInstrumentType,
-                Constants::SpecularInstrumentType
-            },
-            {// Distribution types
-                Constants::DistributionGateType, Constants::DistributionLorentzType,
-                Constants::DistributionGaussianType, Constants::DistributionLogNormalType,
-                Constants::DistributionCosineType, Constants::DistributionTrapezoidType,
-
-                // Detector axes
-                SphericalDetectorItem::P_PHI_AXIS, SphericalDetectorItem::P_ALPHA_AXIS,
-                RectangularDetectorItem::P_X_AXIS, RectangularDetectorItem::P_Y_AXIS,
-                OffSpecInstrumentItem::P_ALPHA_AXIS,
-
-                // Rectangular detector positioning
-                RectangularDetectorItem::P_ALIGNMENT, RectangularDetectorItem::P_NORMAL,
-                RectangularDetectorItem::P_DIRECTION, RectangularDetectorItem::P_U0,
-                RectangularDetectorItem::P_V0, RectangularDetectorItem::P_DBEAM_U0,
-                RectangularDetectorItem::P_DBEAM_V0, RectangularDetectorItem::P_DISTANCE,
-
-                // Detector resolution
-                Constants::ResolutionFunction2DGaussianType,
-
-                // Beam angle parameters
-                BeamItem::P_INCLINATION_ANGLE, BeamItem::P_AZIMUTHAL_ANGLE
-            }
-        }
-    };
-    Q_ASSERT(ModelPath::ancestor(this, Constants::JobItemType));
-
-    const QString& par_path = FitParameterHelper::getParameterItemPath(this);
-
-    for (const auto& item : black_list) {
-        if (item.first.size() == 1 && item.first[0].isNull()) { // checking global scope
-            if (containsNames(par_path, item.second))
-                return false;
-        } else { // checking everything else
-            if (containsNames(par_path, item.first) && containsNames(par_path, item.second))
-                return false;
-        }
-    }
-    return true;
-}
-
 // ----------------------------------------------------------------------------
 
 ParameterContainerItem::ParameterContainerItem()
@@ -150,13 +81,3 @@ ParameterContainerItem::ParameterContainerItem()
     registerTag(T_CHILDREN, 0, -1, QStringList() << Constants::ParameterLabelType);
     setDefaultTag(T_CHILDREN);
 }
-
-namespace {
-bool containsNames(const QString& text, const QStringList& names)
-{
-    for (const auto& name : names)
-        if (text.contains(name))
-            return true;
-    return false;
-}
-}
diff --git a/GUI/coregui/Models/ParameterTreeItems.h b/GUI/coregui/Models/ParameterTreeItems.h
index 3981df38da16869cf54bb99c774a781ca262bac3..b603068700a1e443fc1a2b9100667f9d0ca47122 100644
--- a/GUI/coregui/Models/ParameterTreeItems.h
+++ b/GUI/coregui/Models/ParameterTreeItems.h
@@ -43,8 +43,6 @@ public:
     SessionItem *linkedItem();
 
     void restoreFromBackup();
-
-    bool isFittable() const;
 };
 
 //! The ParameterContainerItem is a top item to hold all ParameterItem, represents an entry
diff --git a/GUI/coregui/Models/ParameterTreeUtils.cpp b/GUI/coregui/Models/ParameterTreeUtils.cpp
index 079197f256bed7a374f3427146be13d37cd0dd90..a85d1265b9c0bf552d1d071e6ed83c01588dfda3 100644
--- a/GUI/coregui/Models/ParameterTreeUtils.cpp
+++ b/GUI/coregui/Models/ParameterTreeUtils.cpp
@@ -61,6 +61,8 @@ void ParameterTreeUtils::createParameterTree(JobItem* jobItem)
     SessionItem* container = jobItem->model()->insertNewItem(Constants::ParameterContainerType,
         jobItem->index(), -1, JobItem::T_PARAMETER_TREE);
 
+    populateParameterContainer(container, jobItem->getItem(JobItem::T_MATERIAL_CONTAINER));
+
     populateParameterContainer(container, jobItem->getItem(JobItem::T_SAMPLE));
 
     populateParameterContainer(container, jobItem->getItem(JobItem::T_INSTRUMENT));
diff --git a/GUI/coregui/Models/ParameterTuningModel.cpp b/GUI/coregui/Models/ParameterTuningModel.cpp
index cc048053128748427dfc8e755ef827406e0ce2f9..7bdc4a411b32660b1b515c7d12c4850a636fba55 100644
--- a/GUI/coregui/Models/ParameterTuningModel.cpp
+++ b/GUI/coregui/Models/ParameterTuningModel.cpp
@@ -31,12 +31,8 @@ Qt::ItemFlags ParameterTuningModel::flags(const QModelIndex &proxyIndex) const
         if (sourceIndex.column() == SessionFlags::ITEM_VALUE) result |= Qt::ItemIsEditable;
 
         const QString modelType = sourceIndex.data(SessionFlags::ModelTypeRole).toString();
-        if(modelType == Constants::ParameterType) {
-            if(ParameterItem *parameterItem = getParameterItem(proxyIndex)) {
-                if(parameterItem->isFittable())
-                    result |= Qt::ItemIsDragEnabled;
-            }
-        }
+        if (modelType == Constants::ParameterType && getParameterItem(proxyIndex))
+            result |= Qt::ItemIsDragEnabled;
     }
     return result;
 }
diff --git a/GUI/coregui/Models/ParticleCoreShellItem.cpp b/GUI/coregui/Models/ParticleCoreShellItem.cpp
index 39deb9832376519f0ac3f4764b4cd9c68640e571..11431f74d235174a6bcf4ae3785bb1036b7396cb 100644
--- a/GUI/coregui/Models/ParticleCoreShellItem.cpp
+++ b/GUI/coregui/Models/ParticleCoreShellItem.cpp
@@ -84,3 +84,15 @@ std::unique_ptr<ParticleCoreShell> ParticleCoreShellItem::createParticleCoreShel
     TransformToDomain::setTransformationInfo(P_coreshell.get(), *this);
     return P_coreshell;
 }
+
+QVector<SessionItem*> ParticleCoreShellItem::materialPropertyItems()
+{
+    QVector<SessionItem*> result;
+    if (auto core = static_cast<ParticleItem*>(getItem(T_CORE)))
+        result.append(core->materialPropertyItems());
+
+    if (auto shell = static_cast<ParticleItem*>(getItem(T_SHELL)))
+        result.append(shell->materialPropertyItems());
+
+    return result;
+}
diff --git a/GUI/coregui/Models/ParticleCoreShellItem.h b/GUI/coregui/Models/ParticleCoreShellItem.h
index 64f41e4ff55b2204467ebdc56605b9535d514a34..00cab30f884fb85ccb14bfabfe048dd0f58cf775 100644
--- a/GUI/coregui/Models/ParticleCoreShellItem.h
+++ b/GUI/coregui/Models/ParticleCoreShellItem.h
@@ -26,6 +26,7 @@ public:
     const static QString T_SHELL;
     ParticleCoreShellItem();
     std::unique_ptr<ParticleCoreShell> createParticleCoreShell() const;
+    QVector<SessionItem*> materialPropertyItems();
 };
 
 #endif // PARTICLECORESHELLITEM_H
diff --git a/GUI/coregui/Models/ParticleDistributionItem.cpp b/GUI/coregui/Models/ParticleDistributionItem.cpp
index 61983b483dc5525584e21ef03b07693e94d5f92a..dea600ab3419ca3bf2dc67b4ac3b12e25bda11c1 100644
--- a/GUI/coregui/Models/ParticleDistributionItem.cpp
+++ b/GUI/coregui/Models/ParticleDistributionItem.cpp
@@ -17,21 +17,22 @@
 #include "DistributionItems.h"
 #include "Distributions.h"
 #include "GUIHelpers.h"
+#include "ParameterTreeUtils.h"
+#include "ParameterUtils.h"
 #include "ParticleItem.h"
+#include "RealLimitsItems.h"
 #include "TransformFromDomain.h"
 #include "TransformToDomain.h"
-#include "ParameterTreeUtils.h"
-#include "RealLimitsItems.h"
-#include "ParameterUtils.h"
 #include "Units.h"
 
-namespace {
-const QString abundance_tooltip =
-    "Proportion of this type of particles normalized to the \n"
-    "total number of particles in the layout";
+namespace
+{
+const QString abundance_tooltip = "Proportion of this type of particles normalized to the \n"
+                                  "total number of particles in the layout";
 }
 
 const QString ParticleDistributionItem::P_DISTRIBUTED_PARAMETER = "Distributed parameter";
+const QString ParticleDistributionItem::P_LINKED_PARAMETER = "Linked parameter";
 const QString ParticleDistributionItem::P_DISTRIBUTION = "Distribution";
 const QString ParticleDistributionItem::NO_SELECTION = "None";
 const QString ParticleDistributionItem::T_PARTICLES = "Particle Tag";
@@ -42,29 +43,41 @@ ParticleDistributionItem::ParticleDistributionItem()
     setToolTip(QStringLiteral("Collection of particles obtained via parametric distribution "
                               "of particle prototype"));
 
-    addProperty(ParticleItem::P_ABUNDANCE, 1.0)->setLimits(RealLimits::limited(0.0, 1.0))
-        .setDecimals(3).setToolTip(abundance_tooltip);
+    addProperty(ParticleItem::P_ABUNDANCE, 1.0)
+        ->setLimits(RealLimits::limited(0.0, 1.0))
+        .setDecimals(3)
+        .setToolTip(abundance_tooltip);
 
-    addGroupProperty(P_DISTRIBUTION, Constants::DistributionGroup)->setToolTip(
-        QStringLiteral("Distribution to apply to the specified parameter"));
+    addGroupProperty(P_DISTRIBUTION, Constants::DistributionGroup)
+        ->setToolTip(QStringLiteral("Distribution to apply to the specified parameter"));
 
-    registerTag(T_PARTICLES, 0, 1, QStringList() << Constants::ParticleType
-                                                 << Constants::ParticleCoreShellType
-                                                 << Constants::ParticleCompositionType
-                                                 << Constants::MesoCrystalType);
+    registerTag(T_PARTICLES, 0, 1,
+                QStringList() << Constants::ParticleType << Constants::ParticleCoreShellType
+                              << Constants::ParticleCompositionType << Constants::MesoCrystalType);
     setDefaultTag(T_PARTICLES);
 
     ComboProperty par_prop;
-    addProperty(P_DISTRIBUTED_PARAMETER, par_prop.variant())->setToolTip(
-        QStringLiteral("Parameter to distribute"));
+    addProperty(P_DISTRIBUTED_PARAMETER, par_prop.variant())
+        ->setToolTip(QStringLiteral("Parameter to distribute"));
+
+    addProperty(P_LINKED_PARAMETER, par_prop.variant())
+        ->setToolTip(QStringLiteral("Linked parameter"))
+        .setEditorType(Constants::MultiSelectionComboEditorType);
+
+    updateMainParameterList();
 
-    updateParameterList();
     mapper()->setOnAnyChildChange([this](SessionItem* item) {
         // prevent infinit loop when item changes its own properties
         if (item && item->modelType() == Constants::PropertyType && item->parent() == this)
             return;
-        updateParameterList();
+        updateMainParameterList();
+    });
+
+    mapper()->setOnPropertyChange([this](const QString& name) {
+        if (name == P_DISTRIBUTED_PARAMETER)
+            updateLinkedParameterList();
     });
+
 }
 
 std::unique_ptr<ParticleDistribution> ParticleDistributionItem::createParticleDistribution() const
@@ -77,84 +90,111 @@ std::unique_ptr<ParticleDistribution> ParticleDistributionItem::createParticleDi
                                 " -> Error! No correct particle defined");
     auto& distr_item = groupItem<DistributionItem>(ParticleDistributionItem::P_DISTRIBUTION);
 
-    auto prop
-        = getItemValue(ParticleDistributionItem::P_DISTRIBUTED_PARAMETER).value<ComboProperty>();
-    QString par_name = prop.getValue();
-
-    std::string domain_par
-        = ParameterTreeUtils::parameterNameToDomainName(par_name, childParticle()).toStdString();
+    std::string domain_par = domainMainParameter();
 
     double scale = ParameterUtils::isAngleRelated(domain_par) ? Units::degree : 1.0;
     auto P_distribution = distr_item.createDistribution(scale);
 
     RealLimits limits = RealLimits::limitless();
-    if(distr_item.isTag(DistributionItem::P_LIMITS)) {
+    if (distr_item.isTag(DistributionItem::P_LIMITS)) {
         auto& limitsItem = distr_item.groupItem<RealLimitsItem>(DistributionItem::P_LIMITS);
         limits = limitsItem.createRealLimits(scale);
     }
 
     int nbr_samples = distr_item.getItemValue(DistributionItem::P_NUMBER_OF_SAMPLES).toInt();
-    double sigma_factor = distr_item.isTag(DistributionItem::P_SIGMA_FACTOR) ?
-                          distr_item.getItemValue(DistributionItem::P_SIGMA_FACTOR).toDouble() :
-                          0.0;
-    ParameterDistribution par_distr(domain_par, *P_distribution, nbr_samples, sigma_factor, limits);
+    double sigma_factor = distr_item.isTag(DistributionItem::P_SIGMA_FACTOR)
+                              ? distr_item.getItemValue(DistributionItem::P_SIGMA_FACTOR).toDouble()
+                              : 0.0;
+    ParameterDistribution par_distr(domain_par, *P_distribution, static_cast<size_t>(nbr_samples),
+                                    sigma_factor, limits);
+
+    for (auto name : domainLinkedParameters())
+        par_distr.linkParameter(name);
+
     auto result = std::make_unique<ParticleDistribution>(*P_particle, par_distr);
     double abundance = getItemValue(ParticleItem::P_ABUNDANCE).toDouble();
     result->setAbundance(abundance);
     return result;
 }
 
-void ParticleDistributionItem::setDomainCacheName(const QString& name)
+void ParticleDistributionItem::setDomainCacheNames(const QString& name, const QStringList& linked)
 {
     m_domain_cache_name = name;
+    m_linked_names = linked;
 }
 
-void ParticleDistributionItem::updateParameterList()
+void ParticleDistributionItem::updateMainParameterList()
 {
     if (!isTag(P_DISTRIBUTED_PARAMETER))
         return;
 
-    ComboProperty prop = getItemValue(P_DISTRIBUTED_PARAMETER).value<ComboProperty>();
-    QString currentValue = prop.getValue();
-
-    QStringList par_names = QStringList() << NO_SELECTION << childParameterNames();
-    par_names.removeAll(ParticleItem::P_ABUNDANCE);
-    ComboProperty newProp = ComboProperty(par_names, NO_SELECTION);
+    QString currentValue = getItemValue(P_DISTRIBUTED_PARAMETER).value<ComboProperty>().getValue();
 
-    bool make_cache_clear(false);
-    if (!m_domain_cache_name.isEmpty()) {
+    if (!m_domain_cache_name.isEmpty() && childParticle()) {
         QString guiName = translateParameterNameToGUI(m_domain_cache_name);
         if (!guiName.isEmpty()) { // might be empty because item was not fully constructed yet
             currentValue = guiName;
-            make_cache_clear = true;
+            m_domain_cache_name.clear();
         }
     }
 
+    QStringList par_names = QStringList() << NO_SELECTION << childParameterNames();
+    ComboProperty newProp = ComboProperty::fromList(par_names, NO_SELECTION);
+
     if (newProp.getValues().contains(currentValue))
         newProp.setValue(currentValue);
 
-    // we first set parameter, and then clear the cache name, to not to allow
-    // initDistributionItem to override limits obtained from the domain
-    if(prop != newProp)
-        setItemValue(P_DISTRIBUTED_PARAMETER, newProp.variant());
+    setItemValue(P_DISTRIBUTED_PARAMETER, newProp.variant());
+}
 
-    if(make_cache_clear)
-        m_domain_cache_name.clear();
+void ParticleDistributionItem::updateLinkedParameterList()
+{
+    if (!isTag(P_LINKED_PARAMETER) || !isTag(P_DISTRIBUTED_PARAMETER))
+        return;
+
+    QString mainValue = getItemValue(P_DISTRIBUTED_PARAMETER).value<ComboProperty>().getValue();
+
+    QStringList par_names = childParameterNames();
+    par_names.removeAll(mainValue);
+
+    ComboProperty linkedProp = getItemValue(P_LINKED_PARAMETER).value<ComboProperty>();
+    QStringList currentValues = linkedProp.selectedValues();
+
+    if (!m_linked_names.isEmpty() && childParticle()) {
+        QStringList domainValues;
+        for (auto par : m_linked_names) {
+            QString guiName = translateParameterNameToGUI(par);
+            if (!guiName.isEmpty())
+                domainValues.append(guiName);
+        }
+        if (!domainValues.isEmpty()) {
+            currentValues = domainValues;
+            m_linked_names.clear();
+        }
+    }
+
+    ComboProperty newProp = ComboProperty::fromList(par_names);
+    for (auto name : currentValues)
+        newProp.setSelected(name, true);
+
+    setItemValue(P_LINKED_PARAMETER, newProp.variant());
 }
 
 QStringList ParticleDistributionItem::childParameterNames() const
 {
-    if(auto child = childParticle())
-        return ParameterTreeUtils::parameterTreeNames(child);
+    if (auto child = childParticle()) {
+        auto result = ParameterTreeUtils::parameterTreeNames(child);
+        result.removeAll(ParticleItem::P_ABUNDANCE);
+        return result;
+    }
 
     return {};
 }
 
 QString ParticleDistributionItem::translateParameterNameToGUI(const QString& domainName)
 {
-    if(auto child = childParticle())
+    if (auto child = childParticle())
         return ParameterTreeUtils::domainNameToParameterName(domainName, child);
-
     return {};
 }
 
@@ -166,3 +206,21 @@ const SessionItem* ParticleDistributionItem::childParticle() const
     Q_ASSERT(getItems(T_PARTICLES).size() == 1);
     return getItems(T_PARTICLES).front();
 }
+
+std::string ParticleDistributionItem::domainMainParameter() const
+{
+    auto par_name = getItemValue(P_DISTRIBUTED_PARAMETER).value<ComboProperty>().getValue();
+    return ParameterTreeUtils::parameterNameToDomainName(par_name, childParticle()).toStdString();
+}
+
+std::vector<std::string> ParticleDistributionItem::domainLinkedParameters() const
+{
+    std::vector<std::string> result;
+    auto linked_names = getItemValue(P_LINKED_PARAMETER).value<ComboProperty>().selectedValues();
+    for (auto name : linked_names) {
+        auto translated = ParameterTreeUtils::parameterNameToDomainName(name, childParticle());
+        if (!translated.isEmpty())
+            result.push_back(translated.toStdString());
+    }
+    return result;
+}
diff --git a/GUI/coregui/Models/ParticleDistributionItem.h b/GUI/coregui/Models/ParticleDistributionItem.h
index ac9d80993feafdedd26488437635e93b7b816bee..53774f331a8c708ed0223adc02d4e442cd97aade 100644
--- a/GUI/coregui/Models/ParticleDistributionItem.h
+++ b/GUI/coregui/Models/ParticleDistributionItem.h
@@ -17,11 +17,14 @@
 
 #include "SessionGraphicsItem.h"
 #include "ParticleDistribution.h"
+#include <string>
+#include <vector>
 
 class BA_CORE_API_ ParticleDistributionItem : public SessionGraphicsItem
 {
 public:
     static const QString P_DISTRIBUTED_PARAMETER;
+    static const QString P_LINKED_PARAMETER;
     static const QString P_DISTRIBUTION;
     static const QString NO_SELECTION;
     static const QString T_PARTICLES;
@@ -29,15 +32,20 @@ public:
 
     std::unique_ptr<ParticleDistribution> createParticleDistribution() const;
 
-    void setDomainCacheName(const QString& name);
+    void setDomainCacheNames(const QString& name, const QStringList& linked);
 
 private:
-    void updateParameterList();
-    void initDistributionItem();
+    void updateMainParameterList();
+    void updateLinkedParameterList();
     QStringList childParameterNames() const;
     QString translateParameterNameToGUI(const QString& domainName);
     const SessionItem* childParticle() const;
+
+    std::string domainMainParameter() const;
+    std::vector<std::string> domainLinkedParameters() const;
+
     QString m_domain_cache_name;
+    QStringList m_linked_names;
 };
 
 #endif // PARTICLEDISTRIBUTIONITEM_H
diff --git a/GUI/coregui/Models/ParticleItem.cpp b/GUI/coregui/Models/ParticleItem.cpp
index c09477766c51e96e439a6fc2f7809b6260e89d1c..437c3cc468a36b576d54683a515b484b13601df5 100644
--- a/GUI/coregui/Models/ParticleItem.cpp
+++ b/GUI/coregui/Models/ParticleItem.cpp
@@ -80,6 +80,14 @@ std::unique_ptr<Particle> ParticleItem::createParticle() const
     return P_particle;
 }
 
+QVector<SessionItem*> ParticleItem::materialPropertyItems()
+{
+    auto item = getItem(P_MATERIAL);
+    if (!item)
+        return {};
+    return {item};
+}
+
 //! Updates enabled/disabled for particle position and particle abundance depending on context.
 
 void ParticleItem::updatePropertiesAppearance(SessionItem* newParent)
diff --git a/GUI/coregui/Models/ParticleItem.h b/GUI/coregui/Models/ParticleItem.h
index be554ab766890d7d551eeea75afbc305dd414d09..0481d14b4b82905adbd9133459cf1a0ad7759ca1 100644
--- a/GUI/coregui/Models/ParticleItem.h
+++ b/GUI/coregui/Models/ParticleItem.h
@@ -31,6 +31,7 @@ public:
     ParticleItem();
 
     std::unique_ptr<Particle> createParticle() const;
+    QVector<SessionItem*> materialPropertyItems();
 
 private:
     void updatePropertiesAppearance(SessionItem* newParent);
diff --git a/GUI/coregui/Models/PointwiseAxisItem.cpp b/GUI/coregui/Models/PointwiseAxisItem.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..907e7459daa82865073a86c27c473dd3c6d19576
--- /dev/null
+++ b/GUI/coregui/Models/PointwiseAxisItem.cpp
@@ -0,0 +1,157 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Models/PointwiseAxisItem.cpp
+//! @brief     Implements pointwise axis item
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "PointwiseAxisItem.h"
+#include "InstrumentItems.h"
+#include "IntensityDataIOFactory.h"
+#include "IUnitConverter.h"
+#include "OutputData.h"
+#include "PointwiseAxis.h"
+
+namespace {
+std::unique_ptr<OutputData<double>> makeOutputData(const IAxis& axis);
+}
+
+const QString PointwiseAxisItem::P_NATIVE_UNITS = "NativeUnits";
+const QString PointwiseAxisItem::P_FILE_NAME = "FileName";
+
+PointwiseAxisItem::PointwiseAxisItem()
+    : BasicAxisItem(Constants::PointwiseAxisType)
+    , m_instrument(nullptr)
+{
+    getItem(P_MIN)->setEnabled(false);
+    getItem(P_NBINS)->setEnabled(false);
+    getItem(P_MAX)->setEnabled(false);
+    addProperty(P_FILE_NAME, QStringLiteral("undefined"))->setVisible(false);
+    addProperty(P_NATIVE_UNITS, Constants::UnitsNbins)->setVisible(false);
+
+    setLastModified(QDateTime::currentDateTime());
+    mapper()->setOnPropertyChange([this](const QString& name) {
+        if (name == P_FILE_NAME)
+            setLastModified(QDateTime::currentDateTime());
+    });
+}
+
+PointwiseAxisItem::~PointwiseAxisItem() = default;
+
+void PointwiseAxisItem::init(const IAxis& axis, const QString& units_label)
+{
+    setLastModified(QDateTime::currentDateTime());
+    m_axis = std::unique_ptr<IAxis>(axis.clone());
+    setItemValue(P_NATIVE_UNITS, units_label);
+    findInstrument();
+}
+
+const IAxis* PointwiseAxisItem::getAxis() const
+{
+    return m_axis.get();
+}
+
+const QString PointwiseAxisItem::getUnitsLabel() const
+{
+    return getItemValue(P_NATIVE_UNITS).toString();
+}
+
+std::unique_ptr<IAxis> PointwiseAxisItem::createAxis(double scale) const
+{
+    if (!checkValidity())
+        return nullptr;
+
+    const auto converter = m_instrument->createUnitConverter();
+    const auto converted_axis = converter->createConvertedAxis(0, AxesUnits::DEGREES);
+
+    //applying scaling
+    std::vector<double> centers = converted_axis->getBinCenters();
+    std::for_each(centers.begin(), centers.end(), [scale](double& value) { value *= scale; });
+
+    return std::make_unique<PointwiseAxis>(converted_axis->getName(), std::move(centers));
+}
+
+bool PointwiseAxisItem::load(const QString& projectDir)
+{
+    QString filename = SaveLoadInterface::fileName(projectDir);
+    auto data = IntensityDataIOFactory::readOutputData(filename.toStdString());
+    if (!data)
+        return false;
+
+    m_axis = std::unique_ptr<IAxis>(data->getAxis(0).clone());
+    findInstrument();
+    setLastModified(QDateTime::currentDateTime());
+    return true;
+}
+
+bool PointwiseAxisItem::save(const QString& projectDir)
+{
+    if (!containsNonXMLData())
+        return false;
+
+    IntensityDataIOFactory::writeOutputData(*makeOutputData(*m_axis),
+                                            SaveLoadInterface::fileName(projectDir).toStdString());
+    return true;
+}
+
+bool PointwiseAxisItem::containsNonXMLData() const
+{
+    return static_cast<bool>(m_axis);
+}
+
+QDateTime PointwiseAxisItem::lastModified() const
+{
+    return m_last_modified;
+}
+
+QString PointwiseAxisItem::fileName() const
+{
+    return getItemValue(PointwiseAxisItem::P_FILE_NAME).toString();
+}
+
+void PointwiseAxisItem::setLastModified(const QDateTime& dtime)
+{
+    m_last_modified = dtime;
+}
+
+bool PointwiseAxisItem::checkValidity() const
+{
+    return m_axis && m_instrument && getUnitsLabel() != Constants::UnitsNbins;
+}
+
+void PointwiseAxisItem::findInstrument()
+{
+    SessionItem* parent_item = parent();
+    while (parent_item && parent_item->modelType() != Constants::SpecularInstrumentType)
+        parent_item = parent_item->parent();
+    m_instrument = static_cast<SpecularInstrumentItem*>(parent_item);
+}
+
+void PointwiseAxisItem::updateIndicators()
+{
+    if (!checkValidity())
+        return;
+
+    const auto converter = m_instrument->createUnitConverter();
+    getItem(P_MIN)->setValue(converter->calculateMin(0, AxesUnits::DEGREES));
+    getItem(P_MAX)->setValue(converter->calculateMax(0, AxesUnits::DEGREES));
+    getItem(P_NBINS)->setValue(static_cast<int>(m_axis->size()));
+
+    emitDataChanged();
+}
+
+namespace {
+std::unique_ptr<OutputData<double>> makeOutputData(const IAxis& axis)
+{
+    std::unique_ptr<OutputData<double>> result(new OutputData<double>);
+    result->addAxis(axis);
+    return result;
+}
+}
diff --git a/GUI/coregui/Models/PointwiseAxisItem.h b/GUI/coregui/Models/PointwiseAxisItem.h
new file mode 100644
index 0000000000000000000000000000000000000000..e3d6b57ba4061bd24407038c6b843285412c86c7
--- /dev/null
+++ b/GUI/coregui/Models/PointwiseAxisItem.h
@@ -0,0 +1,60 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Models/PointwiseAxisItem.h
+//! @brief     Defines pointwise axis item
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef POINTWISEAXISITEM_H
+#define POINTWISEAXISITEM_H
+
+#include "AxesItems.h"
+#include "SaveLoadInterface.h"
+
+class PointwiseAxis;
+class SpecularInstrumentItem;
+
+//! Item for non-uniform axis with specified coordinates.
+class BA_CORE_API_ PointwiseAxisItem : public BasicAxisItem, public SaveLoadInterface
+{
+    static const QString P_NATIVE_UNITS;
+public:
+    static const QString P_FILE_NAME;
+
+    explicit PointwiseAxisItem();
+    ~PointwiseAxisItem() override;
+
+    // setters, getters
+    void init(const IAxis& axis, const QString& units_label);
+    const IAxis* getAxis() const;
+    const QString getUnitsLabel() const;
+
+    // virtual function overloads
+    bool containsNonXMLData() const override;
+    QDateTime lastModified() const override;
+    QString fileName() const override;
+    std::unique_ptr<IAxis> createAxis(double scale) const override;
+
+    void updateIndicators();
+
+private:
+    bool load(const QString& projectDir) override;
+    bool save(const QString& projectDir) override;
+    void setLastModified(const QDateTime& dtime);
+
+    bool checkValidity() const;
+    void findInstrument();
+
+    const SpecularInstrumentItem* m_instrument;
+    std::unique_ptr<IAxis> m_axis;
+    QDateTime m_last_modified;
+};
+
+#endif // POINTWISEAXISITEM_H
diff --git a/GUI/coregui/Models/RealDataItem.cpp b/GUI/coregui/Models/RealDataItem.cpp
index 1c2836c20dfd5309bb11a75aa9ec355670dc18f5..1f28d5000456013683563b6633d38779adb51598 100644
--- a/GUI/coregui/Models/RealDataItem.cpp
+++ b/GUI/coregui/Models/RealDataItem.cpp
@@ -14,17 +14,19 @@
 
 #include "RealDataItem.h"
 #include "GUIHelpers.h"
-#include "ImportDataUtils.h"
 #include "IntensityDataItem.h"
 #include "InstrumentItems.h"
-#include "JobItemFunctions.h"
+#include "ItemFileNameUtils.h"
 #include "JobItemUtils.h"
 #include "SessionModel.h"
 #include "SpecularDataItem.h"
+#include "ImportDataInfo.h"
 
 const QString RealDataItem::P_INSTRUMENT_ID = "Instrument Id";
 const QString RealDataItem::P_INSTRUMENT_NAME = "Instrument";
 const QString RealDataItem::T_INTENSITY_DATA = "Intensity data";
+const QString RealDataItem::T_NATIVE_DATA = "Native user data axis";
+const QString RealDataItem::P_NATIVE_UNITS = "Native user data units";
 
 RealDataItem::RealDataItem()
     : SessionItem(Constants::RealDataType)
@@ -35,22 +37,23 @@ RealDataItem::RealDataItem()
     // Registering this tag even without actual data item to avoid troubles in copying RealDataItem
     registerTag(T_INTENSITY_DATA, 1, 1,
                 QStringList() << Constants::IntensityDataType << Constants::SpecularDataType);
-
-    // TODO: allows to access underlying data item, should be removed. But it is not clear,
-    // what happens if default tag is not present.
     setDefaultTag(T_INTENSITY_DATA);
 
     addProperty(P_INSTRUMENT_ID, QString());
     addProperty(P_INSTRUMENT_NAME, QString());
 
+    registerTag(T_NATIVE_DATA, 1, 1,
+                QStringList() << Constants::IntensityDataType << Constants::SpecularDataType);
+    addProperty(P_NATIVE_UNITS, Constants::UnitsNbins)->setVisible(false);
+
     mapper()->setOnPropertyChange([this](const QString& name) {
-        if (name == P_NAME && getItem(T_INTENSITY_DATA))
-            updateIntensityDataFileName();
+        if (name == P_NAME)
+            updateNonXMLDataFileNames();
     });
 
     mapper()->setOnChildrenChange([this](SessionItem* item) {
         if (dynamic_cast<DataItem*>(item))
-            updateIntensityDataFileName();
+            updateNonXMLDataFileNames();
     });
 
     mapper()->setOnChildPropertyChange([this](SessionItem* item, const QString& name) {
@@ -82,11 +85,17 @@ DataItem* RealDataItem::dataItem()
 
 const DataItem* RealDataItem::dataItem() const
 {
-    const DataItem* result = dynamic_cast<const DataItem*>(getItem(T_INTENSITY_DATA));
-    if (!result)
-        throw GUIHelpers::Error(
-            "Error in RealDataItem::dataItem: underlying data item was not set.");
-    return result;
+    return dynamic_cast<const DataItem*>(getItem(T_INTENSITY_DATA));
+}
+
+DataItem* RealDataItem::nativeData()
+{
+    return const_cast<DataItem*>(static_cast<const RealDataItem*>(this)->nativeData());
+}
+
+const DataItem* RealDataItem::nativeData() const
+{
+    return dynamic_cast<const DataItem*>(getItem(T_NATIVE_DATA));
 }
 
 //! Sets OutputData to underlying item. Creates it, if not exists.
@@ -111,6 +120,40 @@ void RealDataItem::setOutputData(OutputData<double>* data)
     dataItem()->setOutputData(data);
 }
 
+void RealDataItem::initDataItem(size_t data_rank, const QString& tag)
+{
+    assert(data_rank <=2 && data_rank > 0);
+    const QString& target_model_type =
+        data_rank == 2 ? Constants::IntensityDataType : Constants::SpecularDataType;
+    auto data_item = getItem(tag);
+    if (data_item && data_item->modelType() != target_model_type)
+        throw GUIHelpers::Error("Error in RealDataItem::initDataItem: trying to set data "
+                                "incompatible with underlying data item");
+    if (!data_item)
+        this->model()->insertNewItem(target_model_type, this->index(), 0, tag);
+}
+
+void RealDataItem::setImportData(ImportDataInfo data) {
+    if (!data)
+        return;
+
+    const size_t data_rank = data.dataRank();
+    initDataItem(data_rank, T_INTENSITY_DATA);
+    initDataItem(data_rank, T_NATIVE_DATA);
+
+    QString units_name = data.unitsLabel();
+    auto output_data = data.intensityData();
+
+    dataItem()->reset(std::move(data));
+    getItem(P_NATIVE_UNITS)->setValue(units_name);
+    item<DataItem>(T_NATIVE_DATA).setOutputData(output_data.release());
+}
+
+bool RealDataItem::holdsDimensionalData() const
+{
+    return getItemValue(P_NATIVE_UNITS).toString() != Constants::UnitsNbins;
+}
+
 void RealDataItem::linkToInstrument(const InstrumentItem *instrument, bool make_update)
 {
     m_linkedInstrument = instrument;
@@ -142,14 +185,29 @@ MaskContainerItem* RealDataItem::maskContainerItem()
 
 //! Updates the name of file to store intensity data.
 
-void RealDataItem::updateIntensityDataFileName()
+void RealDataItem::updateNonXMLDataFileNames()
 {
     if (DataItem* item = dataItem())
-        item->setItemValue(DataItem::P_FILE_NAME, JobItemFunctions::realDataFileName(*this));
+        item->setItemValue(DataItem::P_FILE_NAME, ItemFileNameUtils::realDataFileName(*this));
+    if (DataItem* item = nativeData())
+        item->setItemValue(DataItem::P_FILE_NAME, ItemFileNameUtils::nativeDataFileName(*this));
 }
 
 void RealDataItem::updateToInstrument()
 {
-    if (DataItem* item = dataItem())
-        JobItemUtils::setIntensityItemAxesUnits(item, m_linkedInstrument);
+    DataItem* data_item = dataItem();
+    if (!data_item)
+        return;
+
+    if (m_linkedInstrument) {
+        JobItemUtils::setIntensityItemAxesUnits(data_item, m_linkedInstrument);
+        return;
+    }
+
+    auto native_data_item = nativeData();
+    auto data_source = native_data_item ? native_data_item : data_item;
+
+    std::unique_ptr<OutputData<double>> native_data(data_source->getOutputData()->clone());
+    const QString units_label = getItemValue(P_NATIVE_UNITS).toString();
+    data_item->reset(ImportDataInfo(std::move(native_data), units_label));
 }
diff --git a/GUI/coregui/Models/RealDataItem.h b/GUI/coregui/Models/RealDataItem.h
index 0d2570d380bb71adc495b8e3ced60f0217535719..a043dedf67667de7c7d03ec27a3d7828bce36396 100644
--- a/GUI/coregui/Models/RealDataItem.h
+++ b/GUI/coregui/Models/RealDataItem.h
@@ -22,6 +22,7 @@ class InstrumentItem;
 class IntensityDataItem;
 class MaskContainerItem;
 template <class T> class OutputData;
+class ImportDataInfo;
 
 //! The RealDataItem class represents intensity data imported from file and intended for fitting.
 
@@ -31,6 +32,9 @@ public:
     static const QString T_INTENSITY_DATA;
     static const QString P_INSTRUMENT_ID;
     static const QString P_INSTRUMENT_NAME;
+    static const QString T_NATIVE_DATA;
+    static const QString P_NATIVE_UNITS;
+
     RealDataItem();
 
     IntensityDataItem* intensityDataItem();
@@ -39,7 +43,12 @@ public:
     DataItem* dataItem();
     const DataItem* dataItem() const;
 
+    DataItem* nativeData();
+    const DataItem* nativeData() const;
+
     void setOutputData(OutputData<double>* data);
+    void setImportData(ImportDataInfo data);
+    bool holdsDimensionalData() const;
 
     void linkToInstrument(const InstrumentItem* instrument, bool make_update = true);
 
@@ -53,7 +62,8 @@ public:
     MaskContainerItem* maskContainerItem();
 
 private:
-    void updateIntensityDataFileName();
+    void initDataItem(size_t data_rank, const QString& tag);
+    void updateNonXMLDataFileNames();
     void updateToInstrument();
     const InstrumentItem* m_linkedInstrument;
 };
diff --git a/GUI/coregui/Models/RealDataModel.cpp b/GUI/coregui/Models/RealDataModel.cpp
index 6585e1785b99123045e0a8fb448fd79e8817a8c5..c5e3a925094cbbcbd6486642f17417455eeaa542 100644
--- a/GUI/coregui/Models/RealDataModel.cpp
+++ b/GUI/coregui/Models/RealDataModel.cpp
@@ -37,6 +37,8 @@ QVector<SessionItem *> RealDataModel::nonXMLData() const
     for (auto realData : topItems<RealDataItem>()) {
         if (auto intensityItem = realData->dataItem())
             result.push_back(intensityItem);
+        if (auto native_data_item = realData->nativeData())
+            result.push_back(native_data_item);
     }
 
     return result;
diff --git a/GUI/coregui/Models/SessionDecorationModel.cpp b/GUI/coregui/Models/SessionDecorationModel.cpp
index 2dd12b358e1da4ab01300b8c0290f097dd9719c0..78cd4aa5b14534e355621a3410006b1b4280eac1 100644
--- a/GUI/coregui/Models/SessionDecorationModel.cpp
+++ b/GUI/coregui/Models/SessionDecorationModel.cpp
@@ -26,6 +26,7 @@ struct IconCatalogue {
     QIcon gisasIcon;
     QIcon offspecIcon;
     QIcon specularIcon;
+    QIcon depthIcon;
 
     IconCatalogue()
     {
@@ -35,6 +36,8 @@ struct IconCatalogue {
         offspecIcon.addPixmap(QPixmap(":/images/offspec_instrument_shaded.svg"), QIcon::Normal);
         specularIcon.addPixmap(QPixmap(":/images/specular_instrument.svg"), QIcon::Selected);
         specularIcon.addPixmap(QPixmap(":/images/specular_instrument_shaded.svg"), QIcon::Normal);
+        depthIcon.addPixmap(QPixmap(":/images/depth_instrument.svg"), QIcon::Selected);
+        depthIcon.addPixmap(QPixmap(":/images/depth_instrument_shaded.svg"), QIcon::Normal);
     }
 };
 
@@ -70,6 +73,9 @@ QVariant itemIcon(const SessionItem* item)
     } else if (modelType == Constants::SpecularInstrumentType) {
         return QVariant(icons.specularIcon);
 
+    } else if (modelType == Constants::DepthProbeInstrumentType) {
+        return QVariant(icons.depthIcon);
+
     } else if (modelType == Constants::MaterialType) {
         auto materialItem = dynamic_cast<const MaterialItem*>(item);
         return QVariant(materialIcon(materialItem->color()));
diff --git a/GUI/coregui/Models/SessionItemUtils.cpp b/GUI/coregui/Models/SessionItemUtils.cpp
index 7a8c0e670657bace9b227020b43663010391ad3d..b5fbc41fd45f0807ddbaf4431da48ea7c996e30e 100644
--- a/GUI/coregui/Models/SessionItemUtils.cpp
+++ b/GUI/coregui/Models/SessionItemUtils.cpp
@@ -19,6 +19,7 @@
 #include "ExternalProperty.h"
 #include "GroupInfoCatalogue.h"
 #include "GUIHelpers.h"
+#include "SessionGraphicsItem.h"
 #include <QColor>
 #include <QIcon>
 #include <QPixmap>
@@ -152,3 +153,13 @@ bool SessionItemUtils::IsTheSame(const QVariant& var1, const QVariant& var2)
     // standard variants (based on double, int, etc) are compared by value they are holding
     return var1 == var2;
 }
+
+bool SessionItemUtils::IsPositionRelated(const SessionItem& item)
+{
+    if (item.modelType() == Constants::PropertyType &&
+            (item.displayName() == SessionGraphicsItem::P_XPOS
+                          || item.displayName() == SessionGraphicsItem::P_YPOS))
+        return true;
+
+    return false;
+}
diff --git a/GUI/coregui/Models/SessionItemUtils.h b/GUI/coregui/Models/SessionItemUtils.h
index 0043f84c614866e64a78c8287e93577f26de27fa..abe78b81d39c0f49dc68287e2eabbfcd9f644b23 100644
--- a/GUI/coregui/Models/SessionItemUtils.h
+++ b/GUI/coregui/Models/SessionItemUtils.h
@@ -68,6 +68,9 @@ BA_CORE_API_ bool CompatibleVariantTypes(const QVariant& oldValue, const QVarian
 
 BA_CORE_API_ bool IsTheSame(const QVariant& var1, const QVariant& var2);
 
+//! Returns true if current item is related to the position on sample editor canvas.
+BA_CORE_API_ bool IsPositionRelated(const SessionItem& item);
+
 }  // namespace SessionItemUtils
 
 #endif // SESSIONITEMUTILS_H
diff --git a/GUI/coregui/Models/SessionModelDelegate.cpp b/GUI/coregui/Models/SessionModelDelegate.cpp
index 0cd701708b9a5ed9386e4f6e390d78a78b0420fd..3506acd2efb0f04efc22c58030bddb17a698da5f 100644
--- a/GUI/coregui/Models/SessionModelDelegate.cpp
+++ b/GUI/coregui/Models/SessionModelDelegate.cpp
@@ -13,43 +13,14 @@
 // ************************************************************************** //
 
 #include "SessionModelDelegate.h"
-#include "SessionItem.h"
-#include "PropertyEditorFactory.h"
 #include "CustomEditors.h"
-#include "SessionFlags.h"
 #include "CustomEventFilters.h"
+#include "PropertyEditorFactory.h"
+#include "SessionItem.h"
 #include <QApplication>
-#include <QLocale>
 
 namespace {
-
-bool isDoubleProperty(const QModelIndex& index)
-{
-    return index.data().type() == QVariant::Double;
-}
-
-//! Returns text representation of double value depending on user defined editor type.
-QString doubleToString(const SessionItem& item)
-{
-    QString result;
-
-    Q_ASSERT(item.value().type() == QVariant::Double);
-    if (item.editorType() == Constants::ScientificEditorType) {
-        result = QString::number(item.value().toDouble(), 'g');
-    } else {
-        auto locale = QLocale::system();
-        result = locale.toString(item.value().toDouble(), 'f', item.decimals());
-    }
-    return result;
-}
-
-QWidget* createEditorFromIndex(const QModelIndex& index, QWidget* parent) {
-    if (index.column() == SessionFlags::ITEM_VALUE && index.internalPointer()) {
-        auto item = static_cast<SessionItem*>(index.internalPointer());
-        return PropertyEditorFactory::CreateEditor(*item, parent);
-    }
-    return nullptr;
-}
+QWidget* createEditorFromIndex(const QModelIndex& index, QWidget* parent);
 }  // unnamed namespace
 
 SessionModelDelegate::SessionModelDelegate(QObject* parent)
@@ -60,15 +31,11 @@ SessionModelDelegate::SessionModelDelegate(QObject* parent)
 void SessionModelDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,
                                  const QModelIndex& index) const
 {
-    if (PropertyEditorFactory::IsCustomVariant(index.data())) {
-        QString text = PropertyEditorFactory::ToString(index.data());
+    if (PropertyEditorFactory::hasStringRepresentation(index)) {
+        QString text = PropertyEditorFactory::toString(index);
         paintCustomLabel(painter, option, index, text);
-    } else if (isDoubleProperty(index)) {
-        auto item = static_cast<SessionItem*>(index.internalPointer());
-        paintCustomLabel(painter, option, index, doubleToString(*item));
-    } else {
+    } else
         QStyledItemDelegate::paint(painter, option, index);
-    }
 }
 
 QWidget* SessionModelDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option,
@@ -76,16 +43,15 @@ QWidget* SessionModelDelegate::createEditor(QWidget* parent, const QStyleOptionV
 {
     auto result = createEditorFromIndex(index, parent);
 
-    if (result) {
-        new TabFromFocusProxy(result);
-        if(auto customEditor = dynamic_cast<CustomEditor*>(result)) {
-            customEditor->setData(index.data());
-            connect(customEditor, &CustomEditor::dataChanged,
-                    this, &SessionModelDelegate::onCustomEditorDataChanged);
-        }
-    } else {
-        result = QStyledItemDelegate::createEditor(parent, option, index);
+    if (auto customEditor = dynamic_cast<CustomEditor*>(result)) {
+        new TabFromFocusProxy(customEditor);
+        connect(customEditor, &CustomEditor::dataChanged, this,
+                &SessionModelDelegate::onCustomEditorDataChanged);
     }
+
+    if (!result) //falling back to default behaviour
+        result = QStyledItemDelegate::createEditor(parent, option, index);
+
     return result;
 }
 
@@ -94,8 +60,10 @@ QWidget* SessionModelDelegate::createEditor(QWidget* parent, const QStyleOptionV
 void SessionModelDelegate::setModelData(QWidget* editor, QAbstractItemModel* model,
                                         const QModelIndex& index) const
 {
-    auto customEditor = qobject_cast<CustomEditor*>(editor);
-    if (index.column() == SessionFlags::ITEM_VALUE && customEditor)
+    if (!index.isValid())
+        return;
+
+    if (auto customEditor = dynamic_cast<CustomEditor*>(editor))
         model->setData(index, customEditor->editorData());
     else
         QStyledItemDelegate::setModelData(editor, model, index);
@@ -105,8 +73,10 @@ void SessionModelDelegate::setModelData(QWidget* editor, QAbstractItemModel* mod
 
 void SessionModelDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
 {
-    auto customEditor = dynamic_cast<CustomEditor*>(editor);
-    if (index.column() == SessionFlags::ITEM_VALUE && customEditor)
+    if (!index.isValid())
+        return;
+
+    if (auto customEditor = dynamic_cast<CustomEditor*>(editor))
         customEditor->setData(index.data());
     else
         QStyledItemDelegate::setEditorData(editor, index);
@@ -154,3 +124,13 @@ void SessionModelDelegate::paintCustomLabel(QPainter* painter, const QStyleOptio
     QStyle* style = widget ? widget->style() : QApplication::style();
     style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget);
 }
+
+namespace {
+QWidget* createEditorFromIndex(const QModelIndex& index, QWidget* parent) {
+    if (index.internalPointer()) {
+        auto item = static_cast<SessionItem*>(index.internalPointer());
+        return PropertyEditorFactory::CreateEditor(*item, parent);
+    }
+    return nullptr;
+}
+}  // unnamed namespace
diff --git a/GUI/coregui/Models/SessionXML.cpp b/GUI/coregui/Models/SessionXML.cpp
index 448be369697eb005d061bdf9f63b465c1b2c3325..6fdd7feec3d0789a66d42b2a4027f9d7ed0652c8 100644
--- a/GUI/coregui/Models/SessionXML.cpp
+++ b/GUI/coregui/Models/SessionXML.cpp
@@ -104,11 +104,11 @@ void SessionXML::writeVariant(QXmlStreamWriter* writer, QVariant variant, int ro
             writer->writeAttribute(SessionXML::ExternalPropertyIdentifierAtt, prop.identifier());
         }
         else if (type_name == Constants::ComboPropertyType) {
-            int currentIndex = variant.value<ComboProperty>().currentIndex();
+            ComboProperty combo = variant.value<ComboProperty>();
             writer->writeAttribute(SessionXML::ParameterValueAttribute,
-                                   QString::number(currentIndex));
+                                   combo.stringOfSelections());
             writer->writeAttribute(SessionXML::ParameterExtAttribute,
-                                   variant.value<ComboProperty>().stringOfValues());
+                                   combo.stringOfValues());
 
         }
         else {
@@ -220,14 +220,14 @@ QString SessionXML::readProperty(QXmlStreamReader* reader, SessionItem* item,
         variant = property.variant();
     }
     else if (parameter_type == Constants::ComboPropertyType) {
-        int parameter_value
-            = reader->attributes().value(SessionXML::ParameterValueAttribute).toInt();
-        QString parameterExt
+        QString selections
+            = reader->attributes().value(SessionXML::ParameterValueAttribute).toString();
+        QString values
             = reader->attributes().value(SessionXML::ParameterExtAttribute).toString();
 
         ComboProperty combo_property;
-        combo_property.setStringOfValues(parameterExt);
-        combo_property.setCurrentIndex(parameter_value);
+        combo_property.setStringOfValues(values);
+        combo_property.setStringOfSelections(selections);
 
         variant = combo_property.variant();
     }
diff --git a/GUI/coregui/Models/SimulationOptionsItem.cpp b/GUI/coregui/Models/SimulationOptionsItem.cpp
index d0acf19bee8456fbb0152c95dcc1c5164051aaab..05fd0f0fca877a07a1c70bf5d0e788b5a0b28fc4 100644
--- a/GUI/coregui/Models/SimulationOptionsItem.cpp
+++ b/GUI/coregui/Models/SimulationOptionsItem.cpp
@@ -12,9 +12,9 @@
 //
 // ************************************************************************** //
 
-#include <thread>
 #include "SimulationOptionsItem.h"
 #include "ComboProperty.h"
+#include <thread>
 
 namespace
 {
@@ -22,42 +22,38 @@ namespace
 QStringList getRunPolicyTooltips()
 {
     QStringList result;
-    result.append(QStringLiteral("Start simulation immediately, switch to Jobs view automatically when completed"));
-    result.append(QStringLiteral("Start simulation immediately, do not switch to Jobs view when completed"));
-    result.append(QStringLiteral("Only submit simulation for consequent execution,"
-                " has to be started from Jobs view explicitely"));
+    result.append(QStringLiteral(
+        "Start simulation immediately, switch to Jobs view automatically when completed"));
+    result.append(
+        QStringLiteral("Start simulation immediately, do not switch to Jobs view when completed"));
     return result;
 }
 
 const QString tooltip_runpolicy = "Defines run policy for the simulation";
 const QString tooltip_nthreads = "Defines number of threads to use for the simulation.";
 const QString tooltip_computation =
-        "Defines computation method (analytical or Monte-Carlo integration)";
+    "Defines computation method (analytical or Monte-Carlo integration)";
 const QString tooltip_ambientmaterial =
-        "Define if the material used for Fresnel calculations should be the ambient layer "
-        "material or the average material of the layer and the particles it contains";
+    "Define if the material used for Fresnel calculations should be the ambient layer "
+    "material or the average material of the layer and the particles it contains";
 const QString tooltip_specularpeak =
-        "Defines if the specular peak should be included in the simulation result";
-
-}
+    "Defines if the specular peak should be included in the simulation result";
 
+} // namespace
 
 const QString SimulationOptionsItem::P_RUN_POLICY = "Run Policy";
 const QString SimulationOptionsItem::P_NTHREADS = "Number of Threads";
 const QString SimulationOptionsItem::P_COMPUTATION_METHOD = "Computation method";
 const QString SimulationOptionsItem::P_MC_POINTS = "Number of MC points";
 const QString SimulationOptionsItem::P_FRESNEL_MATERIAL_METHOD =
-        "Material for Fresnel calculations";
+    "Material for Fresnel calculations";
 const QString SimulationOptionsItem::P_INCLUDE_SPECULAR_PEAK = "Include specular peak";
 
-SimulationOptionsItem::SimulationOptionsItem()
-    : SessionItem(Constants::SimulationOptionsType)
+SimulationOptionsItem::SimulationOptionsItem() : SessionItem(Constants::SimulationOptionsType)
 {
 
     ComboProperty policy;
-    policy << Constants::JOB_RUN_IMMEDIATELY
-           << Constants::JOB_RUN_IN_BACKGROUND
-           << Constants::JOB_RUN_SUBMIT_ONLY;
+    policy << getRunPolicyNames();
     policy.setToolTips(getRunPolicyTooltips());
     addProperty(P_RUN_POLICY, policy.variant())->setToolTip(tooltip_runpolicy);
 
@@ -67,40 +63,42 @@ SimulationOptionsItem::SimulationOptionsItem()
 
     ComboProperty computationMethod;
     computationMethod << Constants::SIMULATION_ANALYTICAL << Constants::SIMULATION_MONTECARLO;
-    addProperty(P_COMPUTATION_METHOD,
-                computationMethod.variant())->setToolTip(tooltip_computation);
+    addProperty(P_COMPUTATION_METHOD, computationMethod.variant())->setToolTip(tooltip_computation);
 
     addProperty(P_MC_POINTS, 100)->setEnabled(false);
 
     ComboProperty averageLayerMaterials;
-    averageLayerMaterials <<Constants::AMBIENT_LAYER_MATERIAL << Constants::AVERAGE_LAYER_MATERIAL;
-    addProperty(P_FRESNEL_MATERIAL_METHOD,
-                averageLayerMaterials.variant())->setToolTip(tooltip_ambientmaterial);
+    averageLayerMaterials << Constants::AMBIENT_LAYER_MATERIAL << Constants::AVERAGE_LAYER_MATERIAL;
+    addProperty(P_FRESNEL_MATERIAL_METHOD, averageLayerMaterials.variant())
+        ->setToolTip(tooltip_ambientmaterial);
 
     ComboProperty includeSpecularPeak;
     includeSpecularPeak << Constants::No << Constants::Yes;
-    addProperty(P_INCLUDE_SPECULAR_PEAK,
-                includeSpecularPeak.variant())->setToolTip(tooltip_specularpeak);
+    addProperty(P_INCLUDE_SPECULAR_PEAK, includeSpecularPeak.variant())
+        ->setToolTip(tooltip_specularpeak);
 
-    mapper()->setOnPropertyChange(
-        [this](const QString &name) {
-            if(name == P_COMPUTATION_METHOD && isTag(P_MC_POINTS)) {
-                ComboProperty combo = getItemValue(P_COMPUTATION_METHOD).value<ComboProperty>();
+    mapper()->setOnPropertyChange([this](const QString& name) {
+        if (name == P_COMPUTATION_METHOD && isTag(P_MC_POINTS)) {
+            ComboProperty combo = getItemValue(P_COMPUTATION_METHOD).value<ComboProperty>();
 
-                if(combo.getValue() == Constants::SIMULATION_ANALYTICAL) {
-                    getItem(P_MC_POINTS)->setEnabled(false);
+            if (combo.getValue() == Constants::SIMULATION_ANALYTICAL) {
+                getItem(P_MC_POINTS)->setEnabled(false);
 
-                } else {
-                    getItem(P_MC_POINTS)->setEnabled(true);
-                }
+            } else {
+                getItem(P_MC_POINTS)->setEnabled(true);
             }
+        } else if (name == P_NTHREADS) {
+            updateComboItem(P_NTHREADS, getCPUUsageOptions());
+        } else if (name == P_RUN_POLICY) {
+            updateComboItem(P_RUN_POLICY, getRunPolicyNames());
+        }
     });
 }
 
 int SimulationOptionsItem::getNumberOfThreads() const
 {
     ComboProperty combo = getItemValue(P_NTHREADS).value<ComboProperty>();
-	return m_text_to_nthreads[combo.getValue()];
+    return m_text_to_nthreads[combo.getValue()];
 }
 
 bool SimulationOptionsItem::runImmediately() const
@@ -113,14 +111,14 @@ bool SimulationOptionsItem::runInBackground() const
     return runPolicy() == Constants::JOB_RUN_IN_BACKGROUND;
 }
 
-void SimulationOptionsItem::setRunPolicy(const QString &policy)
+void SimulationOptionsItem::setRunPolicy(const QString& policy)
 {
     ComboProperty combo = getItemValue(P_RUN_POLICY).value<ComboProperty>();
     combo.setValue(policy);
     setItemValue(P_RUN_POLICY, combo.variant());
 }
 
-void SimulationOptionsItem::setComputationMethod(const QString &name)
+void SimulationOptionsItem::setComputationMethod(const QString& name)
 {
     ComboProperty combo = getItemValue(P_COMPUTATION_METHOD).value<ComboProperty>();
     combo.setValue(name);
@@ -178,20 +176,41 @@ QString SimulationOptionsItem::runPolicy() const
 //! returns list with number of threads to select
 QStringList SimulationOptionsItem::getCPUUsageOptions()
 {
-	m_text_to_nthreads.clear();
+    m_text_to_nthreads.clear();
     QStringList result;
-    int nthreads = std::thread::hardware_concurrency();
-    for(int i = nthreads; i>0; i--){
-		QString str;
-        if(i == nthreads) {
+    int nthreads = static_cast<int>(std::thread::hardware_concurrency());
+    for (int i = nthreads; i > 0; i--) {
+        QString str;
+        if (i == nthreads) {
             str = QString("Max (%1 threads)").arg(QString::number(i));
-        } else if(i == 1) {
+        } else if (i == 1) {
             str = QString("%1 thread").arg(QString::number(i));
         } else {
             str = QString("%1 threads").arg(QString::number(i));
         }
-		result.append(str);
-		m_text_to_nthreads[str] = i;
+        result.append(str);
+        m_text_to_nthreads[str] = i;
+    }
+    return result;
+}
+
+QStringList SimulationOptionsItem::getRunPolicyNames()
+{
+    QStringList result;
+    result << Constants::JOB_RUN_IMMEDIATELY << Constants::JOB_RUN_IN_BACKGROUND;
+    return result;
+}
+
+void SimulationOptionsItem::updateComboItem(QString name, QStringList option_names)
+{
+    ComboProperty combo = getItemValue(name).value<ComboProperty>();
+    if (combo.getValues().size() != option_names.size()) {
+        auto p_item = getItem(name);
+        auto selected_value = combo.getValue();
+        ComboProperty new_combo;
+        new_combo << option_names;
+        if (new_combo.getValues().contains(selected_value))
+            new_combo.setValue(selected_value);
+        p_item->setValue(new_combo.variant());
     }
-    return result;  
 }
diff --git a/GUI/coregui/Models/SimulationOptionsItem.h b/GUI/coregui/Models/SimulationOptionsItem.h
index 82ac199c3481bed63da2d67dd1b2b6952f3435d9..fb9fa603f23a3ae4dab2d0262c403d13c2c528d6 100644
--- a/GUI/coregui/Models/SimulationOptionsItem.h
+++ b/GUI/coregui/Models/SimulationOptionsItem.h
@@ -55,7 +55,9 @@ public:
 private:
     QString runPolicy() const;
     QStringList getCPUUsageOptions();
-	QMap<QString, int> m_text_to_nthreads;
+    QStringList getRunPolicyNames();
+    void updateComboItem(QString name, QStringList option_names);
+    QMap<QString, int> m_text_to_nthreads;
 };
 
 #endif // SIMULATIONOPTIONSITEM_H
diff --git a/GUI/coregui/Models/SpecularBeamInclinationItem.cpp b/GUI/coregui/Models/SpecularBeamInclinationItem.cpp
index b4d69c7b479274876668f094ef38d38b002b8037..556d27b476243d4d1a712599590b73a2110bd563 100644
--- a/GUI/coregui/Models/SpecularBeamInclinationItem.cpp
+++ b/GUI/coregui/Models/SpecularBeamInclinationItem.cpp
@@ -14,12 +14,14 @@
 
 #include "SpecularBeamInclinationItem.h"
 #include "AxesItems.h"
+#include "GroupItem.h"
+#include "PointwiseAxisItem.h"
 #include "Units.h"
 
 namespace
 {
-void addAxisGroupProperty(SessionItem* parent, const QString& tag);
 void setupDistributionMean(SessionItem* distribution);
+void setAxisPresentationDefaults(SessionItem* axis_item, const QString& type);
 }
 
 const QString SpecularBeamInclinationItem::P_ALPHA_AXIS = "Alpha axis";
@@ -27,8 +29,8 @@ const QString SpecularBeamInclinationItem::P_ALPHA_AXIS = "Alpha axis";
 SpecularBeamInclinationItem::SpecularBeamInclinationItem()
     : BeamDistributionItem(Constants::SpecularBeamInclinationType, m_show_mean)
 {
-    register_distribution_group(Constants::DistributionWithZeroAverageGroup);
-    addAxisGroupProperty(this, P_ALPHA_AXIS);
+    register_distribution_group(Constants::SymmetricDistributionGroup);
+    setupAxisGroup();
     setupDistributionMean(getGroupItem(P_DISTRIBUTION));
 
     initDistributionItem(m_show_mean);
@@ -41,32 +43,70 @@ double SpecularBeamInclinationItem::scaleFactor() const
     return Units::degree;
 }
 
-namespace
+void SpecularBeamInclinationItem::updateFileName(const QString& filename)
 {
-void addAxisGroupProperty(SessionItem* parent, const QString& tag)
+    auto& group_item = item<GroupItem>(P_ALPHA_AXIS);
+    auto axis_item = group_item.getChildOfType(Constants::PointwiseAxisType);
+    axis_item->setItemValue(PointwiseAxisItem::P_FILE_NAME, filename);
+}
+
+void SpecularBeamInclinationItem::setupAxisGroup()
 {
-    auto item = parent->addGroupProperty(tag, Constants::BasicAxisType);
-    item->setToolTip("Inclination angle range [deg]");
-    item->getItem(BasicAxisItem::P_TITLE)->setVisible(false);
-    item->getItem(BasicAxisItem::P_NBINS)->setToolTip("Number of points in scan");
-    item->getItem(BasicAxisItem::P_MIN)->setToolTip("Starting value [deg]");
-    item->getItem(BasicAxisItem::P_MAX)->setToolTip("Ending value [deg]");
-
-    item->setItemValue(BasicAxisItem::P_TITLE, "alpha_i");
-    item->setItemValue(BasicAxisItem::P_MIN, 0.0);
-    item->setItemValue(BasicAxisItem::P_MAX, 3.0);
-    item->setItemValue(BasicAxisItem::P_NBINS, 500);
+    auto group_item =
+        dynamic_cast<GroupItem*>(this->addGroupProperty(P_ALPHA_AXIS, Constants::AxesGroup));
+
+    // Both underlying axis items are created, since it
+    // strongly simplifies their representation and state
+    // handling (no signal emulation required).
+    // Basic axis item is the default one.
+
+    group_item->setCurrentType(Constants::PointwiseAxisType);
+    setAxisPresentationDefaults(group_item->currentItem(), group_item->currentType());
+
+    group_item->setCurrentType(Constants::BasicAxisType);
+    setAxisPresentationDefaults(group_item->currentItem(), group_item->currentType());
+
+    group_item->setToolTip("Axis type selected");
+    group_item->setDisplayName("Axis type");
+    group_item->setEnabled(false);
+    group_item->mapper()->setOnValueChange(
+        [group_item]() {
+            if (group_item->currentItem()->modelType() == Constants::PointwiseAxisType)
+                group_item->setEnabled(true);
+        },
+        this);
 }
 
+namespace
+{
 void setupDistributionMean(SessionItem* distribution)
 {
     Q_ASSERT(distribution);
 
-    SessionItem* valueItem = distribution->getItem(DistributionNoneItem::P_VALUE);
+    SessionItem* valueItem = distribution->getItem(DistributionNoneItem::P_MEAN);
     Q_ASSERT(valueItem);
 
     valueItem->setLimits(RealLimits::limited(-90.0, 90.0));
     valueItem->setDecimals(3);
     valueItem->setValue(0.0);
 }
+
+void setAxisPresentationDefaults(SessionItem* axis_item, const QString& type)
+{
+    axis_item->getItem(BasicAxisItem::P_TITLE)->setVisible(false);
+    axis_item->setItemValue(BasicAxisItem::P_TITLE, "alpha_i");
+    axis_item->getItem(BasicAxisItem::P_NBINS)->setToolTip("Number of points in scan");
+    axis_item->getItem(BasicAxisItem::P_MIN)->setToolTip("Starting value [deg]");
+    axis_item->getItem(BasicAxisItem::P_MAX)->setToolTip("Ending value [deg]");
+
+    if (type == Constants::BasicAxisType) {
+        axis_item->setItemValue(BasicAxisItem::P_MIN, 0.0);
+        axis_item->setItemValue(BasicAxisItem::P_MAX, 3.0);
+        axis_item->setItemValue(BasicAxisItem::P_NBINS, 500);
+    } else if (type == Constants::PointwiseAxisType) {
+        axis_item->getItem(BasicAxisItem::P_MIN)->setEnabled(false);
+        axis_item->getItem(BasicAxisItem::P_MAX)->setEnabled(false);
+        axis_item->getItem(BasicAxisItem::P_NBINS)->setEnabled(false);
+    }
+}
 } // namespace
diff --git a/GUI/coregui/Models/SpecularBeamInclinationItem.h b/GUI/coregui/Models/SpecularBeamInclinationItem.h
index 3a8e2aa000c74824622126a401b6fe8c820ae56c..9fa1c04ecb299c70edb0f83ba975d140bec11866 100644
--- a/GUI/coregui/Models/SpecularBeamInclinationItem.h
+++ b/GUI/coregui/Models/SpecularBeamInclinationItem.h
@@ -28,11 +28,14 @@ public:
     static const QString P_ALPHA_AXIS;
 
     SpecularBeamInclinationItem();
-    virtual ~SpecularBeamInclinationItem();
+    ~SpecularBeamInclinationItem() override;
 
     double scaleFactor() const override;
 
+    void updateFileName(const QString& filename);
+
 private:
+    void setupAxisGroup();
     static const bool m_show_mean = false;
 };
 
diff --git a/GUI/coregui/Models/SpecularDataItem.cpp b/GUI/coregui/Models/SpecularDataItem.cpp
index c674ade5430de164ca10acff57dd849202643d88..f1a2f83a97dde70ced21895bb725c8af995c5875 100644
--- a/GUI/coregui/Models/SpecularDataItem.cpp
+++ b/GUI/coregui/Models/SpecularDataItem.cpp
@@ -20,8 +20,6 @@
 #include "ImportDataUtils.h"
 #include "JobItemUtils.h"
 
-const QString x_axis_default_name = "X [nbins]";
-const QString y_axis_default_name = "Signal [a.u.]";
 
 const QString SpecularDataItem::P_TITLE = "Title";
 const QString SpecularDataItem::P_XAXIS = "x-axis";
@@ -42,8 +40,8 @@ SpecularDataItem::SpecularDataItem() : DataItem(Constants::SpecularDataType)
     item->setValue(true);
     item->setVisible(false);
 
-    setXaxisTitle(x_axis_default_name);
-    setYaxisTitle(y_axis_default_name);
+    setXaxisTitle(SpecularDataAxesNames::x_axis_default_name);
+    setYaxisTitle(SpecularDataAxesNames::y_axis_default_name);
 }
 
 void SpecularDataItem::setOutputData(OutputData<double>* data)
@@ -150,16 +148,15 @@ std::vector<int> SpecularDataItem::shape() const
     return {getNbins()};
 }
 
-void SpecularDataItem::resetToDefault()
+void SpecularDataItem::reset(ImportDataInfo data)
 {
-    assert(getOutputData()
-           && "SpecularDataItem::resetToDefault assertion failed: associated output data should "
-              "not be empty");
-    DataItem::resetToDefault();
+    ComboProperty combo = ComboProperty() << data.unitsLabel();
+    setItemValue(SpecularDataItem::P_AXES_UNITS, combo.variant());
+    getItem(SpecularDataItem::P_AXES_UNITS)->setVisible(true);
 
-    setXaxisTitle(x_axis_default_name);
-    setYaxisTitle(y_axis_default_name);
-    setOutputData(ImportDataUtils::CreateSimplifiedOutputData(*getOutputData()).release());
+    setXaxisTitle(data.axisLabel(0));
+    setYaxisTitle(data.axisLabel(1));
+    setOutputData(std::move(data).intensityData().release());
     setAxesRangeToData();
 }
 
diff --git a/GUI/coregui/Models/SpecularDataItem.h b/GUI/coregui/Models/SpecularDataItem.h
index f23a4442cf934d49e31e8ce00ce11190df6fc792..ffde1fca90812700670524f5e342296b6ce07d05 100644
--- a/GUI/coregui/Models/SpecularDataItem.h
+++ b/GUI/coregui/Models/SpecularDataItem.h
@@ -20,6 +20,11 @@
 class AmplitudeAxisItem;
 class BasicAxisItem;
 
+namespace SpecularDataAxesNames{
+const QString x_axis_default_name = "X [nbins]";
+const QString y_axis_default_name = "Signal [a.u.]";
+}
+
 class BA_CORE_API_ SpecularDataItem : public DataItem
 {
 public:
@@ -68,8 +73,9 @@ public:
     void updateAxesUnits(const InstrumentItem* instrument) override;
     std::vector<int> shape() const override;
 
-    //! Returns data to default state (no dimensional units, default axes' names)
-    void resetToDefault() override;
+    //! Returns data to the state defined by user (imported)
+    //! data.
+    void reset(ImportDataInfo data) override;
 
 public slots:
     void setLowerX(double xmin);
diff --git a/GUI/coregui/Models/TransformFromDomain.cpp b/GUI/coregui/Models/TransformFromDomain.cpp
index c2b6b1fa85af1dd110f6b49d0bb31191d8020582..8c02b4f2aee187dfd19ffba46bdad5cdf46151dc 100644
--- a/GUI/coregui/Models/TransformFromDomain.cpp
+++ b/GUI/coregui/Models/TransformFromDomain.cpp
@@ -158,9 +158,9 @@ void TransformFromDomain::set2DLatticeItem(SessionItem* item,
     set2DLatticeParameters(item, sample.lattice());
 
     item->setItemValue(InterferenceFunctionFinite2DLatticeItem::P_DOMAIN_SIZE_1,
-                       sample.domainSize1());
+                       sample.numberUnitCells1());
     item->setItemValue(InterferenceFunctionFinite2DLatticeItem::P_DOMAIN_SIZE_2,
-                       sample.domainSize2());
+                       sample.numberUnitCells2());
     item->setItemValue(InterferenceFunctionFinite2DLatticeItem::P_POSITION_VARIANCE,
                        sample.positionVariance());
     item->setItemValue(InterferenceFunctionFinite2DLatticeItem::P_XI_INTEGRATION,
@@ -203,8 +203,9 @@ void TransformFromDomain::setParticleDistributionItem(SessionItem* item,
 
     ParameterDistribution par_distr = sample.parameterDistribution();
     QString main_distr_par_name = QString::fromStdString(par_distr.getMainParameterName());
+    QStringList linked_pars = GUIHelpers::fromStdStrings(par_distr.getLinkedParameterNames());
 
-    distItem->setDomainCacheName(main_distr_par_name);
+    distItem->setDomainCacheNames(main_distr_par_name, linked_pars);
 
     double unit_factor(1.0);
     if (ParameterUtils::mainParUnits(sample) == BornAgain::UnitsRad)
@@ -272,8 +273,7 @@ void TransformFromDomain::setSpecularBeamItem(SpecularBeamItem* beam_item,
     beam_item->setInclinationAngle(0.0); // inclination angle is hardcoded
     beam_item->setAzimuthalAngle(0.0); // azimuthal angle is hardcoded
 
-    auto axis_item = beam_item->getItem(SpecularBeamItem::P_INCLINATION_ANGLE)
-                         ->getItem(SpecularBeamInclinationItem::P_ALPHA_AXIS);
+    auto axis_item = beam_item->currentInclinationAxisItem();
     TransformFromDomain::setAxisItem(axis_item, *simulation.getAlphaAxis(), 1. / Units::deg);
 
     // distribution parameters
diff --git a/GUI/coregui/Models/TransformToDomain.cpp b/GUI/coregui/Models/TransformToDomain.cpp
index 5cdeaabfe9c4311e16a3cac7a52d906b04d8b17c..caf611e60dacd679fc72cb94d7e3c887a9e18cce 100644
--- a/GUI/coregui/Models/TransformToDomain.cpp
+++ b/GUI/coregui/Models/TransformToDomain.cpp
@@ -31,6 +31,8 @@
 #include "InterferenceFunction2DParaCrystal.h"
 #include "InterferenceFunctionItems.h"
 #include "InterferenceFunctionRadialParaCrystal.h"
+#include "JobItem.h"
+#include "JobModelFunctions.h"
 #include "Lattice2DItems.h"
 #include "LayerItem.h"
 #include "LayerRoughnessItems.h"
@@ -65,11 +67,16 @@ void setParameterDistributionToSimulation(const std::string& parameter_name,
                                           const SessionItem* item, Simulation& simulation);
 }
 
-std::unique_ptr<Material> TransformToDomain::createDomainMaterial(const SessionItem& item)
+std::unique_ptr<Material>
+TransformToDomain::createDomainMaterial(const SessionItem& item)
 {
+    auto parent_job = JobModelFunctions::findJobItem(&item);
+    const MaterialItemContainer* container =
+        parent_job ? parent_job->materialContainerItem() : nullptr;
     QString tag = MaterialItemUtils::materialTag(item);
     ExternalProperty property = item.getItemValue(tag).value<ExternalProperty>();
-    return MaterialItemUtils::createDomainMaterial(property);
+    return container ? MaterialItemUtils::createDomainMaterial(property, *container)
+                     : MaterialItemUtils::createDomainMaterial(property);
 }
 
 std::unique_ptr<MultiLayer> TransformToDomain::createMultiLayer(const SessionItem& item)
@@ -185,6 +192,21 @@ void TransformToDomain::addDistributionParametersToSimulation(const SessionItem&
         simulation);
 }
 
+// TODO Consider removal addDistributionParametersToSimulation and
+// template <class T> void setParameterDistributionToSimulation in the favor
+// of setBeamDistribution.
+
+void TransformToDomain::setBeamDistribution(const std::string& parameter_name,
+                              const BeamDistributionItem& item, Simulation& simulation)
+{
+    ParameterPattern parameter_pattern;
+    parameter_pattern.beginsWith("*").add(BornAgain::BeamType).add(parameter_name);
+
+    auto P_par_distr = item.getParameterDistributionForName(parameter_pattern.toStdString());
+    if (P_par_distr)
+        simulation.addParameterDistribution(*P_par_distr);
+}
+
 void TransformToDomain::setSimulationOptions(Simulation* simulation,
                                              const SessionItem& item)
 {
diff --git a/GUI/coregui/Models/TransformToDomain.h b/GUI/coregui/Models/TransformToDomain.h
index 0b62ee9b7f61941c32b6210670b552e0ac662003..a80d964b75f5f3a71bee11ffb254263165c6480a 100644
--- a/GUI/coregui/Models/TransformToDomain.h
+++ b/GUI/coregui/Models/TransformToDomain.h
@@ -27,11 +27,13 @@
 #include "ParticleLayout.h"
 #include <memory>
 
-class GISASSimulation;
-class Simulation;
-class SessionItem;
 class DetectorItem;
+class GISASSimulation;
 class Material;
+class MaterialItemContainer;
+class SessionItem;
+class Simulation;
+class BeamDistributionItem;
 
 namespace TransformToDomain
 {
@@ -48,6 +50,10 @@ BA_CORE_API_ void addDistributionParametersToSimulation(
     const SessionItem& beam_item, GISASSimulation& simulation);
 BA_CORE_API_ void addDistributionParametersToSimulation(
     const SessionItem& beam_item, SpecularSimulation& simulation);
+
+BA_CORE_API_ void setBeamDistribution(const std::string& parameter_name,
+        const BeamDistributionItem& item, Simulation& simulation);
+
 BA_CORE_API_ void setSimulationOptions(Simulation* simulation, const SessionItem& item);
 BA_CORE_API_ void setTransformationInfo(IParticle* result, const SessionItem& item);
 BA_CORE_API_ void setPositionInfo(IParticle* result, const SessionItem& item);
diff --git a/GUI/coregui/Models/VarianceFunctionItems.cpp b/GUI/coregui/Models/VarianceFunctionItems.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3e30be9db50e836af1a2adb5cfaeeb9e93a88ee5
--- /dev/null
+++ b/GUI/coregui/Models/VarianceFunctionItems.cpp
@@ -0,0 +1,50 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Models/VarianceFunctionItems.cpp
+//! @brief     Implements classes VarianceFunctionItems
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "VarianceFunctionItems.h"
+#include "item_constants.h"
+#include "VarianceFunctions.h"
+
+IVarianceFunctionItem::IVarianceFunctionItem(const QString& model_type)
+    : SessionItem(model_type)
+{
+
+}
+
+VarianceConstantFunctionItem::VarianceConstantFunctionItem()
+    : IVarianceFunctionItem(Constants::VarianceConstantFunctionType)
+{
+    setToolTip("Leaves residual value unnormalized");
+
+}
+
+std::unique_ptr<IVarianceFunction> VarianceConstantFunctionItem::createVarianceFunction() const
+{
+    return std::make_unique<VarianceConstantFunction>();
+}
+
+const QString VarianceSimFunctionItem::P_EPSILON = "epsilon";
+
+VarianceSimFunctionItem::VarianceSimFunctionItem()
+    : IVarianceFunctionItem(Constants::VarianceSimFunctionType)
+{
+    setToolTip("Normalizes residual on max(sim, epsilon)");
+    addProperty(P_EPSILON, 1.0)->setToolTip(QStringLiteral(
+            "Defines threshold on simulated amplitude in max(sim, epsilon)"));
+}
+
+std::unique_ptr<IVarianceFunction> VarianceSimFunctionItem::createVarianceFunction() const
+{
+    return std::make_unique<VarianceSimFunction>(getItemValue(P_EPSILON).toDouble());
+}
diff --git a/GUI/coregui/Models/VarianceFunctionItems.h b/GUI/coregui/Models/VarianceFunctionItems.h
new file mode 100644
index 0000000000000000000000000000000000000000..1f1df68a629b2d37c0acac7cd806b5f7c349543f
--- /dev/null
+++ b/GUI/coregui/Models/VarianceFunctionItems.h
@@ -0,0 +1,51 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Models/VarianceFunctionItems.h
+//! @brief     Defines classes VarianceFunctionItems
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef VARIANTFUNCTIONITEMS_H
+#define VARIANTFUNCTIONITEMS_H
+
+#include "SessionItem.h"
+#include <QString>
+#include <memory>
+
+class IVarianceFunction;
+
+//! Base class for variance in Minimizer's residual settings.
+
+class BA_CORE_API_ IVarianceFunctionItem : public SessionItem
+{
+public:
+    virtual std::unique_ptr<IVarianceFunction> createVarianceFunction() const = 0;
+protected:
+    IVarianceFunctionItem(const QString& model_type);
+};
+
+class BA_CORE_API_ VarianceConstantFunctionItem : public IVarianceFunctionItem
+{
+public:
+    VarianceConstantFunctionItem();
+
+    std::unique_ptr<IVarianceFunction> createVarianceFunction() const;
+};
+
+class BA_CORE_API_ VarianceSimFunctionItem : public IVarianceFunctionItem
+{
+public:
+    static const QString P_EPSILON;
+    VarianceSimFunctionItem();
+
+    std::unique_ptr<IVarianceFunction> createVarianceFunction() const;
+};
+
+#endif // VARIANTFUNCTIONITEMS_H
diff --git a/GUI/coregui/Models/item_constants.h b/GUI/coregui/Models/item_constants.h
index 64ed397d3c0215ef5cf58eb10e666772957b56ca..d77692a5846d2f7263f1944ecfcb6346a6e55750 100644
--- a/GUI/coregui/Models/item_constants.h
+++ b/GUI/coregui/Models/item_constants.h
@@ -45,6 +45,7 @@ const ModelType InterferenceFunctionFinite2DLatticeType = "InterferenceFinite2DL
 const ModelType GISASInstrumentType = "GISASInstrument";
 const ModelType OffSpecInstrumentType = "OffSpecInstrument";
 const ModelType SpecularInstrumentType = "SpecularInstrument";
+const ModelType DepthProbeInstrumentType = "DepthProbeInstrument";
 const ModelType GISASBeamType = "GISASBeam";
 const ModelType SpecularBeamType = "SpecularBeam";
 
@@ -122,6 +123,7 @@ const ModelType SquareLatticeType = "SquareLattice";
 const ModelType HexagonalLatticeType = "HexagonalLattice";
 
 const ModelType MaterialType = "Material";
+const ModelType MaterialContainerType = "MaterialContainer";
 
 const ModelType MaterialRefractiveDataType = "MaterialRefractiveData";
 const ModelType MaterialSLDDataType = "MaterialSLDData";
@@ -145,6 +147,7 @@ const ModelType DataPropertyContainerType = "DataPropertyContainer";
 const ModelType DataItem1DPropertiesType = "DataItem1DProperties";
 
 const ModelType BasicAxisType = "BasicAxis";
+const ModelType PointwiseAxisType = "PointwiseAxis";
 const ModelType AmplitudeAxisType = "AmplitudeAxis";
 
 const ModelType BeamDistributionType = "BeamDistribution";
@@ -152,6 +155,7 @@ const ModelType BeamWavelengthType = "BeamWavelength";
 const ModelType BeamAzimuthalAngleType = "BeamAzimuthalAngle";
 const ModelType BeamInclinationAngleType = "BeamInclinationAngle";
 const ModelType SpecularBeamInclinationType = "SpecularBeamInclinationAxis";
+const ModelType SpecularBeamWavelengthType = "SpecularBeamWavelength";
 
 const ModelType ResolutionFunctionNoneType = "ResolutionFunctionNone";
 const ModelType ResolutionFunction2DGaussianType = "ResolutionFunction2DGaussian";
@@ -196,6 +200,9 @@ const ModelType FootprintNoneType = "NoFootprint";
 const ModelType FootprintGaussianType = "GaussianFootrpint";
 const ModelType FootprintSquareType = "SquareFootprint";
 
+const ModelType VarianceConstantFunctionType= "VarianceConstantFunction";
+const ModelType VarianceSimFunctionType = "VarianceSimFunction";
+
 // --- Groups ------------------------------------------------------------------
 
 const ModelType FormFactorGroup = "Form Factor";
@@ -204,7 +211,7 @@ const ModelType LayerRoughnessGroup = "Roughness";
 const ModelType DetectorGroup = "Detector group";
 const ModelType DistributionGroup = "Distribution group";
 const ModelType DistributionExtendedGroup = "Distribution extended group";
-const ModelType DistributionWithZeroAverageGroup = "Distribution with zero average group";
+const ModelType SymmetricDistributionGroup = "Symmetric distribution group";
 const ModelType FTDistribution1DGroup = "PDF 1D";
 const ModelType FTDistribution2DGroup = "PDF 2D";
 const ModelType FTDecayFunction1DGroup = "Decay function 1D";
@@ -217,6 +224,8 @@ const ModelType RealLimitsGroup = "RealLimits group";
 const ModelType BackgroundGroup = "Background group";
 const ModelType MaterialDataGroup = "Material data group";
 const ModelType FootprintGroup = "Footprint group";
+const ModelType AxesGroup = "Axes group";
+const ModelType VarianceFunctionGroup = "Variance group";
 
 // --- Units&Constants----------------------------------------------------------
 
@@ -248,7 +257,6 @@ const ModelType GRADIENT_HUES = "Hues";
 
 const ModelType JOB_RUN_IMMEDIATELY = "Immediately";
 const ModelType JOB_RUN_IN_BACKGROUND = "In background";
-const ModelType JOB_RUN_SUBMIT_ONLY = "Submit only";
 const ModelType JOB_BACKUP = "_backup";
 
 const ModelType SIMULATION_ANALYTICAL = "Analytical";
@@ -291,8 +299,10 @@ const ModelType ComboPropertyType = "ComboProperty";
 // --- Custom editors for variant propertues ---
 const ModelType DefaultEditorType = "Default";
 const ModelType ScientificEditorType = "SceintificDouble";
+const ModelType ScientificSpinBoxType = "ScientificSpinBox";
 const ModelType MaterialEditorExternalType = "ExtMaterialEditor";
 const ModelType ColorEditorExternalType = "ExtColorEditor";
+const ModelType MultiSelectionComboEditorType = "MultiSelectionComboEditor";
 }
 
 #endif // ITEM_CONSTANTS_H
diff --git a/GUI/coregui/Views/CommonWidgets/DocksController.cpp b/GUI/coregui/Views/CommonWidgets/DocksController.cpp
index a61b62319d695ea1cb88c87d9d02b1dbe60d4aae..dc0614783607d3d68f202b29ada42f014c8dc003 100644
--- a/GUI/coregui/Views/CommonWidgets/DocksController.cpp
+++ b/GUI/coregui/Views/CommonWidgets/DocksController.cpp
@@ -142,6 +142,11 @@ void DocksController::onWidgetCloseRequest()
     dock->toggleViewAction()->trigger();
 }
 
+Manhattan::FancyMainWindow* DocksController::mainWindow()
+{
+    return m_mainWindow;
+}
+
 DockWidgetInfo DocksController::get_info(int id)
 {
     if (m_docks.find(id) == m_docks.end())
diff --git a/GUI/coregui/Views/CommonWidgets/DocksController.h b/GUI/coregui/Views/CommonWidgets/DocksController.h
index b50a45b2a8c96ec1f3efa5f1430c5b608c21abfe..78ff4e22abfe789e5af9ed1c9527670c85f5a04a 100644
--- a/GUI/coregui/Views/CommonWidgets/DocksController.h
+++ b/GUI/coregui/Views/CommonWidgets/DocksController.h
@@ -47,6 +47,9 @@ public slots:
     void dockToMinMaxSizes();
     void onWidgetCloseRequest();
 
+protected:
+    Manhattan::FancyMainWindow* mainWindow();
+
 private:
     struct DockSizeInfo {
         DockSizeInfo() : m_dock(nullptr) {}
diff --git a/GUI/coregui/Views/CommonWidgets/InfoPanel.cpp b/GUI/coregui/Views/CommonWidgets/InfoPanel.cpp
index d44454655d63b45509745739468d0836f9228b6d..e37c94be366c6a1d3996501ef296c103b6a9571b 100644
--- a/GUI/coregui/Views/CommonWidgets/InfoPanel.cpp
+++ b/GUI/coregui/Views/CommonWidgets/InfoPanel.cpp
@@ -18,19 +18,18 @@
 #include <QResizeEvent>
 #include <QStackedWidget>
 
-namespace {
+namespace
+{
 const int minimum_widget_height = 25; // height of toolbar
 const int minimum_height_before_collapse = 50;
 const int default_height = 200;
 }
 
-InfoPanel::InfoPanel(QWidget *parent)
-    : QFrame(parent)
-    , m_toolBar(new InfoPanelToolBar)
-    , m_stackedWidget(new QStackedWidget)
-    , m_cached_height(default_height)
+InfoPanel::InfoPanel(QWidget* parent)
+    : QFrame(parent), m_toolBar(new InfoPanelToolBar), m_stackedWidget(new QStackedWidget),
+      m_cached_height(default_height)
 {
-    QVBoxLayout *mainLayout = new QVBoxLayout;
+    auto mainLayout = new QVBoxLayout;
     mainLayout->addWidget(m_toolBar);
     mainLayout->addWidget(m_stackedWidget);
 
@@ -40,20 +39,23 @@ InfoPanel::InfoPanel(QWidget *parent)
 
     setLayout(mainLayout);
 
-    connect(m_toolBar, SIGNAL(expandButtonClicked()), this, SLOT(onExpandButtonClicked()));
-    connect(m_toolBar, SIGNAL(closeButtonClicked()), this, SLOT(onCloseButtonClicked()));
+    connect(m_toolBar, &InfoPanelToolBar::expandButtonClicked,
+            this, &InfoPanel::onExpandButtonClicked);
+    connect(m_toolBar, &InfoPanelToolBar::closeButtonClicked,
+            this, &InfoPanel::onCloseButtonClicked);
 }
 
 QSize InfoPanel::sizeHint() const
 {
     QSize result = m_toolBar->sizeHint();
 
-    if(QWidget *widget = m_stackedWidget->currentWidget()) {
-        if(widget->isVisible())
-            result.setHeight(widget->height() + m_toolBar->height() );
+    if (QWidget* widget = m_stackedWidget->currentWidget()) {
+        if (widget->isVisible())
+            result.setHeight(widget->height() + m_toolBar->height());
     } else {
-        result.setHeight(m_toolBar->height() );
+        result.setHeight(m_toolBar->height());
     }
+
     return result;
 }
 
@@ -75,50 +77,45 @@ void InfoPanel::onCloseButtonClicked()
 void InfoPanel::setContentVisible(bool editor_status, bool dock_notify)
 {
     m_toolBar->setExpandStatus(editor_status);
-    if(editor_status) {
-        if(m_cached_height)
-            if(dock_notify) emit widgetHeightRequest(m_cached_height);
+    if (editor_status) {
+        if (m_cached_height)
+            if (dock_notify)
+                emit widgetHeightRequest(m_cached_height);
 
-        if(m_stackedWidget->currentWidget())
+        if (m_stackedWidget->currentWidget())
             m_stackedWidget->currentWidget()->show();
 
     } else {
         m_cached_height = (height() < minimum_height_before_collapse ? default_height : height());
-//        m_cached_height = height();
-        if(m_stackedWidget->currentWidget())
+        if (m_stackedWidget->currentWidget())
             m_stackedWidget->currentWidget()->hide();
 
-        if(dock_notify) emit widgetHeightRequest(minimum_widget_height);
+        if (dock_notify)
+            emit widgetHeightRequest(minimum_widget_height);
     }
-
-//    m_stackedWidget->setVisible(editor_status);
 }
 
 bool InfoPanel::isContentVisible()
 {
-    if(m_stackedWidget->currentWidget())
+    if (m_stackedWidget->currentWidget())
         return m_stackedWidget->currentWidget()->isVisible();
 
     return false;
 }
 
-void InfoPanel::resizeEvent(QResizeEvent *event)
+void InfoPanel::resizeEvent(QResizeEvent* event)
 {
     // widget is schrinking in height
-    if(event->oldSize().height() > event->size().height()) {
-        if(event->size().height() <= minimum_height_before_collapse && isContentVisible()) {
+    if (event->oldSize().height() > event->size().height()) {
+        if (event->size().height() <= minimum_height_before_collapse && isContentVisible())
             setContentVisible(false);
-        }
     }
 
     // widget is growing in height
-    if(event->oldSize().height() < event->size().height()) {
-        if(event->size().height() > minimum_height_before_collapse && !isContentVisible()) {
+    if (event->oldSize().height() < event->size().height()) {
+        if (event->size().height() > minimum_height_before_collapse && !isContentVisible())
             setContentVisible(true);
-        }
     }
 
     QWidget::resizeEvent(event);
-
 }
-
diff --git a/GUI/coregui/Views/CommonWidgets/InfoPanel.h b/GUI/coregui/Views/CommonWidgets/InfoPanel.h
index fce926c13f5d090617775877be83ca1809ad9813..4aca10ca2790b3755a992dbd05e2c60452a8b038 100644
--- a/GUI/coregui/Views/CommonWidgets/InfoPanel.h
+++ b/GUI/coregui/Views/CommonWidgets/InfoPanel.h
@@ -22,9 +22,8 @@ class QStackedWidget;
 class InfoPanelToolBar;
 class QResizeEvent;
 
-//! The InfoPanel class serves as a widget container with tool bar on top, with
-//! collapse/expand button functionality. Intended for QDockWindow, to be able to quickly
-//! minimize/maximize its appearance.
+//! Frame for widgets with tool bar on top and collapse/expand button functionality.
+//! Intended for QDockWindow, to be able to quickly minimize/maximize its appearance.
 
 //! Used in JobMessagePanel.
 
@@ -32,7 +31,7 @@ class BA_CORE_API_ InfoPanel : public QFrame
 {
     Q_OBJECT
 public:
-    explicit InfoPanel(QWidget *parent);
+    explicit InfoPanel(QWidget* parent);
 
     QSize sizeHint() const;
     QSize minimumSizeHint() const;
@@ -48,10 +47,10 @@ protected slots:
 
 protected:
     bool isContentVisible();
-    void resizeEvent(QResizeEvent *event);
+    void resizeEvent(QResizeEvent* event);
 
-    InfoPanelToolBar *m_toolBar;
-    QStackedWidget *m_stackedWidget;
+    InfoPanelToolBar* m_toolBar;
+    QStackedWidget* m_stackedWidget;
     int m_cached_height;
 };
 
diff --git a/GUI/coregui/Views/CommonWidgets/InfoPanelToolBar.cpp b/GUI/coregui/Views/CommonWidgets/InfoPanelToolBar.cpp
index 04582bcdc239cb9db0eb6dcbafa5c9916db6e861..bf91c612838417cf2108edf3ee953bc9cb78e524 100644
--- a/GUI/coregui/Views/CommonWidgets/InfoPanelToolBar.cpp
+++ b/GUI/coregui/Views/CommonWidgets/InfoPanelToolBar.cpp
@@ -15,42 +15,50 @@
 #include "InfoPanelToolBar.h"
 #include <QHBoxLayout>
 #include <QToolButton>
+#include <QAction>
 
-namespace {
+namespace
+{
 const int minimum_size = 25;
+const QString icon_up = ":/images/dark-angle-up.svg";
+const QString icon_down = ":/images/dark-angle-down.svg";
+const QString icon_close = ":/images/dark-close.svg";
+const QString expand_text = "Collapse/expand view";
+const QString close_text = "Close view";
 }
 
-InfoPanelToolBar::InfoPanelToolBar(QWidget *parent)
-    : StyledToolBar(parent)
-    , m_expandButton(new QToolButton)
-    , m_closeButton(new QToolButton)
+InfoPanelToolBar::InfoPanelToolBar(QWidget* parent)
+    : QToolBar(parent)
+    , m_expandAction(new QAction(expand_text, this))
+    , m_closeAction(new QAction(close_text, this))
     , m_expanded(false)
 {
     setMinimumSize(minimum_size, minimum_size);
+    setProperty("_q_custom_style_disabled", QVariant(true));
 
-    m_expandButton->setIcon(QIcon(":/images/darkarrowup.png"));
-    m_expandButton->setToolTip("Collapse/expand view");
-    connect(m_expandButton, SIGNAL(clicked()), this, SLOT(onExpandButtonClicked()));
+    m_expandAction->setIcon(QIcon(icon_up));
+    m_expandAction->setToolTip(expand_text);
+    connect(m_expandAction, &QAction::triggered, this, &InfoPanelToolBar::onExpandButtonClicked);
 
-    m_closeButton->setIcon(QIcon(":/images/darkclosebutton.png"));
-    m_closeButton->setToolTip("Close viewe");
-    connect(m_closeButton, SIGNAL(clicked()), this, SIGNAL(closeButtonClicked()));
+    m_closeAction->setIcon(QIcon(icon_close));
+    m_closeAction->setToolTip(close_text);
+    connect(m_closeAction, &QAction::triggered, this, &InfoPanelToolBar::closeButtonClicked);
 
-    addStyledExpand();
-    addWidget(m_expandButton);
-    addWidget(m_closeButton);
+    auto empty = new QWidget();
+    empty->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+    addWidget(empty);
 
-    setStyleSheet("QToolBar {border-bottom: 1px solid gray}");
+    addAction(m_expandAction);
+    addAction(m_closeAction);
 }
 
 void InfoPanelToolBar::setExpandStatus(bool status)
 {
     m_expanded = status;
-    if(m_expanded) {
-        m_expandButton->setIcon(QIcon(":/images/darkarrowdown.png"));
-    } else {
-        m_expandButton->setIcon(QIcon(":/images/darkarrowup.png"));
-    }
+    if (m_expanded)
+        m_expandAction->setIcon(QIcon(icon_down));
+    else
+        m_expandAction->setIcon(QIcon(icon_up));
 }
 
 void InfoPanelToolBar::onExpandButtonClicked()
@@ -59,4 +67,3 @@ void InfoPanelToolBar::onExpandButtonClicked()
     setExpandStatus(m_expanded);
     emit expandButtonClicked();
 }
-
diff --git a/GUI/coregui/Views/CommonWidgets/InfoPanelToolBar.h b/GUI/coregui/Views/CommonWidgets/InfoPanelToolBar.h
index 57888e6ef9b2f6b777cc6370014b35a737e586bb..c714d31fb52c031129d8ff592a680787b3fd6c1e 100644
--- a/GUI/coregui/Views/CommonWidgets/InfoPanelToolBar.h
+++ b/GUI/coregui/Views/CommonWidgets/InfoPanelToolBar.h
@@ -17,16 +17,16 @@
 
 #include "StyledToolBar.h"
 
-class QToolButton;
+class QAction;
 
-//! The InfoPanelToolBar class represents a toolbar for InfoPanel
+//! Toolbar for InfoPanel with collapse/expand buttons.
 
-class BA_CORE_API_ InfoPanelToolBar : public StyledToolBar
+class BA_CORE_API_ InfoPanelToolBar : public QToolBar
 {
     Q_OBJECT
 
 public:
-    explicit InfoPanelToolBar(QWidget *parent = 0);
+    explicit InfoPanelToolBar(QWidget* parent = nullptr);
 
 signals:
     void expandButtonClicked();
@@ -39,10 +39,9 @@ protected slots:
     void onExpandButtonClicked();
 
 private:
-    QToolButton *m_expandButton;
-    QToolButton *m_closeButton;
+    QAction* m_expandAction;
+    QAction* m_closeAction;
     bool m_expanded;
 };
 
-
 #endif // INFOPANELTOOLBAR_H
diff --git a/GUI/coregui/Views/FitWidgets/FitActivityPanel.cpp b/GUI/coregui/Views/FitWidgets/FitActivityPanel.cpp
index bd907c284275547353d3de7b4645f04356c07444..d4c0d71a4085867e513ac28b228754da75bfaaab 100644
--- a/GUI/coregui/Views/FitWidgets/FitActivityPanel.cpp
+++ b/GUI/coregui/Views/FitWidgets/FitActivityPanel.cpp
@@ -36,6 +36,7 @@ FitActivityPanel::FitActivityPanel(JobModel *jobModel, QWidget *parent)
     , m_fitSessionManager(new FitSessionManager(this))
 {
     setWindowTitle(Constants::JobFitPanelName);
+    setObjectName("FitActivityPanel");
     setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
 
     auto mainLayout = new QVBoxLayout;
diff --git a/GUI/coregui/Views/FitWidgets/FitObjectiveBuilder.cpp b/GUI/coregui/Views/FitWidgets/FitObjectiveBuilder.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1d0a8456d059f982a02bd8b0213ddd25606b73b5
--- /dev/null
+++ b/GUI/coregui/Views/FitWidgets/FitObjectiveBuilder.cpp
@@ -0,0 +1,148 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/FitWidgets/SimulationBuilder.cpp
+//! @brief     Implements class SimulationBuilder
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "FitObjectiveBuilder.h"
+#include "JobItem.h"
+#include "Parameters.h"
+#include "KernelTypes.h"
+#include "FitObjective.h"
+#include "Simulation.h"
+#include "MultiLayer.h"
+#include "FitParameterItems.h"
+#include "RealDataItem.h"
+#include "GUIHelpers.h"
+#include "DataItem.h"
+#include "OutputData.h"
+#include "DomainSimulationBuilder.h"
+#include "FitSuiteItem.h"
+#include "MinimizerItem.h"
+#include "IMinimizer.h"
+#include "Minimizer.h"
+#include "GUIFitObserver.h"
+#include "ChiSquaredModule.h"
+#include "IIntensityFunction.h"
+#include "VarianceFunctions.h"
+
+FitObjectiveBuilder::FitObjectiveBuilder(JobItem* jobItem)
+    : m_jobItem(jobItem)
+{
+    Q_ASSERT(m_jobItem->fitSuiteItem());
+}
+
+FitObjectiveBuilder::~FitObjectiveBuilder() = default;
+
+void FitObjectiveBuilder::runFit()
+{
+    m_fit_objective = createFitObjective();
+
+    auto module = createChiSquaredModule();
+    m_fit_objective->setChiSquaredModule(*module);
+
+    fcn_residual_t residual_func = [&](const Fit::Parameters& params) {
+        return m_fit_objective->evaluate_residuals(params);
+    };
+
+    if (m_observer) {
+        fit_observer_t plot_observer = [&](const FitObjective& obj) {
+            m_observer->update(&obj);
+        };
+        m_fit_objective->initPlot(1, plot_observer);
+    }
+
+    Fit::Minimizer minimizer;
+    minimizer.setMinimizer(createMinimizer().release());
+
+    auto result = minimizer.minimize(residual_func, createParameters());
+    m_fit_objective->finalize(result);
+}
+
+std::unique_ptr<FitObjective> FitObjectiveBuilder::createFitObjective() const
+{
+    std::unique_ptr<FitObjective> result(new FitObjective);
+
+    simulation_builder_t builder = [&](const Fit::Parameters& params) {
+        return buildSimulation(params);
+    };
+
+    result->addSimulationAndData(builder, *createOutputData(), 1.0);
+
+    return result;
+}
+
+std::unique_ptr<IMinimizer> FitObjectiveBuilder::createMinimizer() const
+{
+    auto fitSuiteItem = m_jobItem->fitSuiteItem();
+    return fitSuiteItem->minimizerContainerItem()->createMinimizer();
+}
+
+std::unique_ptr<IChiSquaredModule> FitObjectiveBuilder::createChiSquaredModule() const
+{
+    std::unique_ptr<IChiSquaredModule> result = std::make_unique<ChiSquaredModule>();
+
+    auto fitSuiteItem = m_jobItem->fitSuiteItem();
+    auto intensityFunction = fitSuiteItem->minimizerContainerItem()->createIntensityFunction();
+    if (intensityFunction)
+        result->setIntensityFunction(*intensityFunction);
+    auto variaceFunction = fitSuiteItem->minimizerContainerItem()->createVarianceFunction();
+    result->setVarianceFunction(*variaceFunction);
+    return result;
+}
+
+Fit::Parameters FitObjectiveBuilder::createParameters() const
+{
+    auto fitSuiteItem = m_jobItem->fitSuiteItem();
+    return fitSuiteItem->fitParameterContainerItem()->createParameters();
+}
+
+void FitObjectiveBuilder::attachObserver(std::shared_ptr<GUIFitObserver> observer)
+{
+    m_observer = observer;
+}
+
+void FitObjectiveBuilder::interruptFitting()
+{
+    m_fit_objective->interruptFitting();
+}
+
+std::unique_ptr<Simulation> FitObjectiveBuilder::buildSimulation(const Fit::Parameters& params) const
+{
+    static std::mutex build_simulation_mutex;
+    std::unique_lock<std::mutex> lock(build_simulation_mutex);
+
+    update_fit_parameters(params);
+    return DomainSimulationBuilder::createSimulation(m_jobItem->multiLayerItem(),
+            m_jobItem->instrumentItem(), m_jobItem->simulationOptionsItem());
+}
+
+std::unique_ptr<OutputData<double> > FitObjectiveBuilder::createOutputData() const
+{
+    auto realDataItem = m_jobItem->realDataItem();
+    if(!realDataItem)
+        throw GUIHelpers::Error("FitObjectiveBuilder::createOutputData() -> No Real Data defined.");
+
+    const DataItem* intensity_item = realDataItem->dataItem();
+    Q_ASSERT(intensity_item);
+    Q_ASSERT(intensity_item->getOutputData());
+
+    return std::unique_ptr<OutputData<double>>(intensity_item->getOutputData()->clone());
+}
+
+
+void FitObjectiveBuilder::update_fit_parameters(const Fit::Parameters& params) const
+{
+    QVector<double> values = GUIHelpers::fromStdVector(params.values());
+
+    auto fitParContainer = m_jobItem->fitParameterContainerItem();
+    fitParContainer->setValuesInParameterContainer(values, m_jobItem->parameterContainerItem());
+}
diff --git a/GUI/coregui/Views/FitWidgets/FitObjectiveBuilder.h b/GUI/coregui/Views/FitWidgets/FitObjectiveBuilder.h
new file mode 100644
index 0000000000000000000000000000000000000000..58e2a7cc6501269f4a74104023d1be51d0a16b10
--- /dev/null
+++ b/GUI/coregui/Views/FitWidgets/FitObjectiveBuilder.h
@@ -0,0 +1,59 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/FitWidgets/FitObjectiveBuilder.h
+//! @brief     Defines class FitObjectiveBuilder
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef FITOBJECTIVEBUILDER_H
+#define FITOBJECTIVEBUILDER_H
+
+#include "WinDllMacros.h"
+#include <memory>
+
+class JobItem;
+class FitObjective;
+class Simulation;
+namespace Fit { class Parameters; }
+template<class T> class OutputData;
+class IMinimizer;
+class GUIFitObserver;
+class IChiSquaredModule;
+
+class BA_CORE_API_ FitObjectiveBuilder
+{
+public:
+    FitObjectiveBuilder(JobItem* jobItem);
+    ~FitObjectiveBuilder();
+
+    void runFit();
+
+    std::unique_ptr<FitObjective> createFitObjective() const;
+    std::unique_ptr<IMinimizer> createMinimizer() const;
+    std::unique_ptr<IChiSquaredModule> createChiSquaredModule() const;
+
+    Fit::Parameters createParameters() const;
+
+    void attachObserver(std::shared_ptr<GUIFitObserver> observer);
+
+    void interruptFitting();
+private:
+    JobItem* m_jobItem;
+
+    std::unique_ptr<Simulation> buildSimulation(const Fit::Parameters& params) const;
+    std::unique_ptr<OutputData<double>> createOutputData() const;
+
+    void update_fit_parameters(const Fit::Parameters& params) const;
+
+    std::shared_ptr<GUIFitObserver> m_observer;
+    std::unique_ptr<FitObjective> m_fit_objective;
+};
+
+#endif
diff --git a/GUI/coregui/Views/FitWidgets/FitSessionController.cpp b/GUI/coregui/Views/FitWidgets/FitSessionController.cpp
index 38dcfaa1a2236c030e2257f37a2232be5dbbe921..9d4f5145261f4ba564f4cfd1b023a9f27d6a8beb 100644
--- a/GUI/coregui/Views/FitWidgets/FitSessionController.cpp
+++ b/GUI/coregui/Views/FitWidgets/FitSessionController.cpp
@@ -17,14 +17,17 @@
 #include "GUIFitObserver.h"
 #include "JobItem.h"
 #include "FitSuiteItem.h"
-#include "DomainFittingBuilder.h"
 #include "FitProgressInfo.h"
-#include "FitSuite.h"
 #include "IntensityDataItem.h"
 #include "FitParameterItems.h"
 #include "GUIHelpers.h"
+#include "FitObjectiveBuilder.h"
 #include "FitLog.h"
 
+namespace  {
+const bool use_fit_objective = true;
+}
+
 FitSessionController::FitSessionController(QObject* parent)
     : QObject(parent)
     , m_jobItem(nullptr)
@@ -74,12 +77,13 @@ void FitSessionController::onStartFittingRequest()
         return;
 
     try {
+        m_objectiveBuilder.reset(new FitObjectiveBuilder(m_jobItem));
         m_observer->setInterval(
             m_jobItem->fitSuiteItem()->getItemValue(FitSuiteItem::P_UPDATE_INTERVAL).toInt());
-        std::shared_ptr<FitSuite> fitSuite(DomainFittingBuilder::createFitSuite(m_jobItem));
-        fitSuite->attachObserver(m_observer);
+        m_objectiveBuilder->attachObserver(m_observer);
         m_observer->finishedPlotting();
-        m_runFitManager->runFitting(fitSuite);
+        m_runFitManager->runFitting(m_objectiveBuilder);
+
     } catch (std::exception& e) {
         m_jobItem->setStatus(Constants::STATUS_FAILED);
         m_fitlog->append(e.what(), FitLogFlags::ERROR);
@@ -103,7 +107,10 @@ void FitSessionController::onObserverUpdate()
     m_jobItem->dataItem()->setRawDataVector(progressInfo.simValues());
 
     updateIterationCount(progressInfo);
-    updateFitParameterValues(progressInfo);
+
+    if (!use_fit_objective)
+        updateFitParameterValues(progressInfo);
+
     updateLog(progressInfo);
 
     if(!progressInfo.logInfo().empty())
diff --git a/GUI/coregui/Views/FitWidgets/FitSessionController.h b/GUI/coregui/Views/FitWidgets/FitSessionController.h
index 84795203b97a62cf2463f35cb32c56196fa63e12..4255e81cbd64bac8185b92cb29c785373d7d1cdf 100644
--- a/GUI/coregui/Views/FitWidgets/FitSessionController.h
+++ b/GUI/coregui/Views/FitWidgets/FitSessionController.h
@@ -24,6 +24,7 @@ class FitWorkerLauncher;
 class GUIFitObserver;
 class FitProgressInfo;
 class FitLog;
+class FitObjectiveBuilder;
 
 //! Controls all activity related to the single fitting task for JobItem.
 //! Provides interaction between FitSessionWidget and fit observers.
@@ -62,6 +63,7 @@ private:
     FitWorkerLauncher* m_runFitManager;
     std::shared_ptr<GUIFitObserver> m_observer;
     std::unique_ptr<FitLog> m_fitlog;
+    std::shared_ptr<FitObjectiveBuilder> m_objectiveBuilder;
     bool m_block_progress_update;
 };
 
diff --git a/GUI/coregui/Views/FitWidgets/FitWorker.cpp b/GUI/coregui/Views/FitWidgets/FitWorker.cpp
index f711ff879364d6042bb93616662fd4a2078fcfb1..a0ef768407058b48962e47dde0acffc8f176ab44 100644
--- a/GUI/coregui/Views/FitWidgets/FitWorker.cpp
+++ b/GUI/coregui/Views/FitWidgets/FitWorker.cpp
@@ -13,7 +13,7 @@
 // ************************************************************************** //
 
 #include "FitWorker.h"
-#include "FitSuite.h"
+#include "FitObjectiveBuilder.h"
 #include <QDateTime>
 
 void FitWorker::startFit()
@@ -21,10 +21,9 @@ void FitWorker::startFit()
     int duration(0);
     QDateTime beginTime = QDateTime::currentDateTime();
 
-    m_fitsuite->resetInterrupt();
     emit started();
     try {
-        m_fitsuite->runFit();
+        m_fit_objective->runFit();
         duration = durationSince(beginTime);
 
     } catch (const std::exception& ex) {
@@ -34,10 +33,11 @@ void FitWorker::startFit()
     emit finished(duration);
 }
 
+
 void FitWorker::interruptFitting()
 {
-    if (m_fitsuite)
-        m_fitsuite->interruptFitting();
+    if (m_fit_objective)
+        m_fit_objective->interruptFitting();
 }
 
 int FitWorker::durationSince(const QDateTime& since)
diff --git a/GUI/coregui/Views/FitWidgets/FitWorker.h b/GUI/coregui/Views/FitWidgets/FitWorker.h
index 29dcfc08536dac3e1dd78192b57865153b649c6a..5f2dde9cec6edbf901fa9d8300db88e233b67fba 100644
--- a/GUI/coregui/Views/FitWidgets/FitWorker.h
+++ b/GUI/coregui/Views/FitWidgets/FitWorker.h
@@ -19,14 +19,14 @@
 #include <QObject>
 #include <memory>
 
-class FitSuite;
+class FitObjectiveBuilder;
 
 class BA_CORE_API_ FitWorker : public QObject
 {
     Q_OBJECT
 
 public:
-    FitWorker(std::shared_ptr<FitSuite> suite) { m_fitsuite = suite; }
+    FitWorker(std::shared_ptr<FitObjectiveBuilder> suite) { m_fit_objective = suite; }
 
 public slots:
 
@@ -44,7 +44,7 @@ signals:
 
 private:
     int durationSince(const class QDateTime& since);
-    std::shared_ptr<FitSuite> m_fitsuite;
+    std::shared_ptr<FitObjectiveBuilder> m_fit_objective;
 };
 
 #endif // FITWORKER_H
diff --git a/GUI/coregui/Views/FitWidgets/FitWorkerLauncher.cpp b/GUI/coregui/Views/FitWidgets/FitWorkerLauncher.cpp
index 69921b5122371763ef738f0312255108fc0f5090..6feb18e7fa8732d8287e62a02461170a31c25220 100644
--- a/GUI/coregui/Views/FitWidgets/FitWorkerLauncher.cpp
+++ b/GUI/coregui/Views/FitWidgets/FitWorkerLauncher.cpp
@@ -13,7 +13,6 @@
 // ************************************************************************** //
 
 #include "FitWorkerLauncher.h"
-#include "FitSuite.h"
 #include "FitWorker.h"
 #include <QThread>
 
@@ -24,8 +23,7 @@ FitWorkerLauncher::FitWorkerLauncher(QObject* parent)
 {
 }
 
-// start fitting in separate thread
-void FitWorkerLauncher::runFitting(std::shared_ptr<FitSuite> suite)
+void FitWorkerLauncher::runFitting(std::shared_ptr<FitObjectiveBuilder> suite)
 {
     if (!suite || m_is_fit_running)
         return;
diff --git a/GUI/coregui/Views/FitWidgets/FitWorkerLauncher.h b/GUI/coregui/Views/FitWidgets/FitWorkerLauncher.h
index b5bcc9ab9031b57e2fe09905d4b3dcb06a69ef76..b0225f7d4bd54d1304920d50a9fdd569304dba91 100644
--- a/GUI/coregui/Views/FitWidgets/FitWorkerLauncher.h
+++ b/GUI/coregui/Views/FitWidgets/FitWorkerLauncher.h
@@ -20,7 +20,7 @@
 #include <atomic>
 #include <memory>
 
-class FitSuite;
+class FitObjectiveBuilder;
 
 class BA_CORE_API_ FitWorkerLauncher : public QObject
 {
@@ -29,7 +29,7 @@ class BA_CORE_API_ FitWorkerLauncher : public QObject
 public:
     FitWorkerLauncher(QObject* parent);
 
-    void runFitting(std::shared_ptr<FitSuite> suite);
+    void runFitting(std::shared_ptr<FitObjectiveBuilder> suite);
 
     int getDuration();
 
diff --git a/GUI/coregui/Views/FitWidgets/GUIFitObserver.cpp b/GUI/coregui/Views/FitWidgets/GUIFitObserver.cpp
index acd7aaf88ec16292137a51ab9762eea2aa6a6e01..3f05ef2b60b7f1be69b3b31d73dc89935a245ee4 100644
--- a/GUI/coregui/Views/FitWidgets/GUIFitObserver.cpp
+++ b/GUI/coregui/Views/FitWidgets/GUIFitObserver.cpp
@@ -13,15 +13,14 @@
 // ************************************************************************** //
 
 #include "GUIFitObserver.h"
-#include "FitParameterSet.h"
 #include "FitProgressInfo.h"
-#include "FitSuite.h"
 #include "GUIHelpers.h"
 #include "MinimizerUtils.h"
+#include "FitObjective.h"
+#include "MinimizerResult.h"
 
 GUIFitObserver::GUIFitObserver(QObject* parent)
     : QObject(parent)
-    , IFitObserver(1)
     , m_block_update_plots(false)
     , m_update_interval(1)
 {
@@ -31,7 +30,8 @@ GUIFitObserver::~GUIFitObserver()
 {
 }
 
-void GUIFitObserver::update(FitSuite* subject)
+
+void GUIFitObserver::update(const FitObjective* subject)
 {
     if (!is_suitable_iteration(subject))
         return;
@@ -44,41 +44,39 @@ void GUIFitObserver::update(FitSuite* subject)
         m_on_finish_notifier.wait(lock, [this]() { return m_block_update_plots; });
 
     FitProgressInfo info;
-    info.m_chi2 = subject->getChi2();
-    info.m_iteration_count = static_cast<int>(subject->numberOfIterations());
-    info.m_values = subject->fitParameters()->values();
-
-    if (subject->isFirstIteration())
-        info.m_log_info = subject->setupToString();
+    info.m_chi2 = subject->iterationInfo().chi2();
+    info.m_iteration_count = static_cast<int>(subject->iterationInfo().iterationCount());
+    info.m_values = subject->iterationInfo().parameters().values();
 
-    if (subject->isLastIteration())
-        info.m_log_info = reportToString(subject);
+    if (subject->isCompleted())
+        info.m_log_info = subject->minimizerResult().toString();
 
     std::unique_ptr<OutputData<double>> data(subject->simulationResult().data());
     info.m_sim_values = data->getRawDataVector();
 
     m_iteration_info = info;
     emit updateReady();
+
 }
 
 //! Returns true if data could be plotted, when there are resources for it.
 
-bool GUIFitObserver::is_suitable_iteration(FitSuite* fitSuite)
+bool GUIFitObserver::is_suitable_iteration(const FitObjective* fitSuite) const
 {
     if (fitSuite->isInterrupted())
         return false;
 
-    int n_iter = static_cast<int>(fitSuite->numberOfIterations());
-    return n_iter == fitSuite->isFirstIteration() ||
+    int n_iter = static_cast<int>(fitSuite->iterationInfo().iterationCount());
+    return fitSuite->isFirstIteration() ||
            n_iter % m_update_interval == 0 ||
-           fitSuite->isLastIteration();
+           fitSuite->isCompleted();
 }
 
 //! Returns true if given iteration should be obligary plotted.
 
-bool GUIFitObserver::is_obligatory_iteration(FitSuite* fitSuite)
+bool GUIFitObserver::is_obligatory_iteration(const FitObjective* fitSuite) const
 {
-    return fitSuite->isLastIteration();
+    return fitSuite->isCompleted();
 }
 
 void GUIFitObserver::setInterval(int val)
@@ -86,16 +84,6 @@ void GUIFitObserver::setInterval(int val)
     m_update_interval = val;
 }
 
-//! Return string representing results of the minimization.
-
-std::string GUIFitObserver::reportToString(FitSuite* fitSuite)
-{
-    std::string result = MinimizerUtils::sectionString("Fit parameter setup");
-    result += fitSuite->setupToString();
-    result += fitSuite->reportResults();
-    return result;
-}
-
 //! Informs observer that FitSuiteWidget has finished plotting and is ready for next plot
 
 void GUIFitObserver::finishedPlotting()
diff --git a/GUI/coregui/Views/FitWidgets/GUIFitObserver.h b/GUI/coregui/Views/FitWidgets/GUIFitObserver.h
index 701f9c736f9b20c05a1b71c4be9f19f19171d864..8b9e0b6032302bf5c5a40fe4539c9c1e58eca926 100644
--- a/GUI/coregui/Views/FitWidgets/GUIFitObserver.h
+++ b/GUI/coregui/Views/FitWidgets/GUIFitObserver.h
@@ -15,20 +15,19 @@
 #ifndef GUIFITOBSERVER_H
 #define GUIFITOBSERVER_H
 
-#include "IFitObserver.h"
 #include "FitProgressInfo.h"
 #include <QObject>
 #include <condition_variable>
 #include <mutex>
 
 template <class T> class OutputData;
-class FitSuite;
 class IntensityDataItem;
+class FitObjective;
 
-//! The GUIFitObserver class is a intermediate between FitSuite and the GUI.
-//! It is called at the end of each iterations and sends (messages, data) to the rest of the GUI.
+//! Serves as observer for FitObjective and saves fit iteration data for later display
+//! in GUI widgets.
 
-class BA_CORE_API_ GUIFitObserver : public QObject, public IFitObserver
+class BA_CORE_API_ GUIFitObserver : public QObject
 {
     Q_OBJECT
 
@@ -36,7 +35,7 @@ public:
     GUIFitObserver(QObject* parent = nullptr);
     ~GUIFitObserver();
 
-    void update(FitSuite* subject);
+    void update(const FitObjective* subject);
 
     void finishedPlotting();
 
@@ -49,9 +48,8 @@ signals:
     void updateReady();
 
 private:
-    bool is_suitable_iteration(FitSuite* fitSuite);
-    bool is_obligatory_iteration(FitSuite* fitSuite);
-    std::string reportToString(FitSuite* fitSuite);
+    bool is_suitable_iteration(const FitObjective* fitSuite) const;
+    bool is_obligatory_iteration(const FitObjective* fitSuite) const;
 
     bool m_block_update_plots;
     std::mutex m_update_plot_mutex;
diff --git a/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant.cpp b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant.cpp
deleted file mode 100644
index 8e16448256b70e38d89c68fd122d088d5cadbc96..0000000000000000000000000000000000000000
--- a/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant.cpp
+++ /dev/null
@@ -1,709 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant.cpp
-//! @brief     Implements class CsvImportAssistant
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "DataFormatUtils.cpp"
-#include "CsvImportAssistant.h"
-#include "mainwindow_constants.h"
-#include "StyleUtils.h"
-#include <QAction>
-#include <QPushButton>
-#include <QTableWidget>
-#include <QSettings>
-#include <QVBoxLayout>
-#include <QFileDialog>
-#include <QMessageBox>
-#include <QMenu>
-
-namespace
-{
-const QSize default_dialog_size(300, 400);
-}
-
-CsvImportAssistant::CsvImportAssistant(QString& dir, QString& file, QWidget* parent):
-    QDialog(parent),
-    m_dirName(dir),
-    m_fileName(file),
-    m_lastDataRow(0),
-    m_intensityCol(0),
-    m_coordinateCol(0),
-    m_singleCol(0),
-    m_tableWidget(nullptr),
-    m_separatorField(nullptr),
-    m_firstDataRowSpinBox(nullptr),
-    m_singleDataColSpinBox(nullptr),
-    m_importButton(nullptr)
-{
-    setWindowTitle("Data Importer");
-    setMinimumSize(128, 128);
-    resize(600, 800);
-    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
-
-    auto layout = new QVBoxLayout;
-    layout->setContentsMargins(0, 0, 0, 0);
-    layout->addLayout(createLayout());
-
-    setLayout(layout);
-
-    StyleUtils::setResizable(this);
-
-    if(!m_fileName.isEmpty())
-        CsvImportAssistant::Reload();
-}
-
-
-
-QBoxLayout* CsvImportAssistant::createLayout()
-{
-    auto result = new QVBoxLayout;
-    auto preresult = new QHBoxLayout;
-
-    m_importButton = new QPushButton("Import");
-    m_importButton->setDefault(true);
-    connect(m_importButton, &QPushButton::clicked, this, &CsvImportAssistant::onImportButton);
-
-    auto rejectButton = new QPushButton("Cancel");
-    connect(rejectButton, &QPushButton::clicked, this, &CsvImportAssistant::onRejectButton);
-
-
-    m_tableWidget = new QTableWidget();
-
-    preresult->setMargin(10);
-
-    preresult->addWidget(rejectButton);
-    preresult->addWidget(m_importButton);
-
-
-    result->setMargin(10);
-    result->addWidget(new QLabel("Right click on the table or use the controls below to modify what will be imported"));
-    result->addWidget(m_tableWidget);
-    result->addLayout(CsvImportAssistant::createFileDetailsLayout());
-
-    result->addLayout(preresult);
-
-    m_tableWidget->setContextMenuPolicy(Qt::CustomContextMenu);
-    m_tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
-    connect(m_tableWidget, &QTableWidget::cellClicked, this, &CsvImportAssistant::OnColumnClicked);
-    connect(m_tableWidget, &QTableWidget::customContextMenuRequested, this, &CsvImportAssistant::onColumnRightClick);
-    return result;
-}
-
-QBoxLayout* CsvImportAssistant::createFileDetailsLayout(){
-    auto result = new QHBoxLayout;
-    result->setMargin(10);
-
-    auto labelSeparator = new QLabel("Separator: ");
-    m_separatorField = new QLineEdit(QString(guessSeparator()));
-    m_separatorField->setMaxLength(1);
-    m_separatorField->setMaximumWidth(50);
-    auto lay2 = new QVBoxLayout;
-    lay2->addWidget(labelSeparator);
-    lay2->addWidget(m_separatorField);
-    //result->addLayout(lay2);
-    connect(m_separatorField, &QLineEdit::editingFinished, this, &CsvImportAssistant::Reload);
-
-
-    auto lay3 = new QVBoxLayout;
-    auto labelFirstDataRow = new QLabel("First data row: ");
-    m_firstDataRowSpinBox = new QSpinBox();
-    m_firstDataRowSpinBox->setMinimum(1);
-    m_firstDataRowSpinBox->setMaximum(1);
-    m_firstDataRowSpinBox->setValue(1);
-    m_firstDataRowSpinBox->setMaximumWidth(50);
-    lay3->addWidget(labelFirstDataRow);
-    lay3->addWidget(m_firstDataRowSpinBox);
-
-    connect(m_firstDataRowSpinBox, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged),
-        [this](){ Reload(); });
-
-    auto lay4 = new QVBoxLayout;
-    auto labelSingleColImport = new QLabel("Import Single Column (zero to import all): ");
-    m_singleDataColSpinBox = new QSpinBox();
-    m_singleDataColSpinBox->setMinimum(0);
-    m_singleDataColSpinBox->setMaximum(0);
-    m_singleDataColSpinBox->setValue(0);
-    m_singleDataColSpinBox->setMaximumWidth(50);
-    lay4->addWidget(labelSingleColImport);
-    lay4->addWidget(m_singleDataColSpinBox);
-    connect(m_singleDataColSpinBox, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged),
-        [this](int i){ m_singleCol = unsigned(i); Reload(); });
-
-
-
-    result->addLayout(lay2);
-    result->addSpacing(20);
-    result->addLayout(lay3);
-    result->addSpacing(20);
-    result->addLayout(lay4);
-
-    return result;
-}
-
-void CsvImportAssistant::Reload()
-{
-    std::ifstream f(m_fileName.toStdString());
-    if(f.good()){
-        generate_table();
-    }else{
-        QMessageBox msgBox;
-        std::string message = "There was a problem opening the file \"" + m_fileName.toStdString() + "\"";
-        message += "\n Check for any errors in the path and try again.";
-        msgBox.setText(QString::fromStdString(message));
-        msgBox.setIcon(msgBox.Critical);
-        msgBox.exec();
-    }
-}
-
-void CsvImportAssistant::onRejectButton(){
-    reject();
-}
-
-
-void CsvImportAssistant::onImportButton()
-{
-    try {
-        auto data = getData();
-        accept();
-    } catch(...){
-        QString message = QString("Unable to import, check that the table contains only numerical values");
-        QMessageBox::warning(nullptr, "Wrong data format", message);
-    }
-}
-
-
-std::unique_ptr<OutputData<double>> CsvImportAssistant::getData()
-{
-    int nTableRows = m_tableWidget->rowCount();
-    int nTableCols = m_tableWidget->columnCount();
-    std::vector<std::vector<std::string>> StringVectorVector;
-    std::vector<std::string> StringVector;
-
-    //save the values of the array
-    size_t nDataCols = 0;
-    size_t nDataRows = 0;
-    for(int i = 0; i < nTableRows; i++){
-        StringVector.clear();
-        nDataCols = 0;
-        for(int j = 0; j < nTableCols; j++){
-            auto tableElement = m_tableWidget->item(i,j);
-            if(tableElement != nullptr){
-                StringVector.push_back(tableElement->text().toStdString());
-                nDataCols++;
-            }
-        }
-        StringVectorVector.push_back(StringVector);
-        nDataRows++;
-    }
-
-    std::unique_ptr<OutputData<double>> result;
-    result = std::make_unique<OutputData<double>>();
-
-    if( (nDataCols < 2) || (nDataRows < 2) ){
-        size_t nElem = std::max(nDataCols,nDataRows);
-        result->addAxis("intensity", nElem, 0.0, double(nElem));
-        std::vector<unsigned> axes_indices(1);
-        unsigned item = 0;
-        for(unsigned row=0; row<nDataRows; row++) {
-            for(unsigned col=0; col<nDataCols; col++) {
-                axes_indices[0] = item;
-                size_t global_index = result->toGlobalIndex(axes_indices);
-                std::string string_to_parse;
-                std::vector<double> parsed_doubles;
-                string_to_parse = StringVectorVector[row][col];
-                parsed_doubles = DataFormatUtils::parse_doubles(string_to_parse);
-                (*result)[global_index] = parsed_doubles[0];
-                item++;
-            }
-        }
-    }
-    else if(m_coordinateName != ""){
-        //Fill intensity values and coordinate values:
-        size_t intensityCol = 1;
-        size_t coordinateCol = 0;
-        std::vector<double> coordValues;
-        std::vector<double> intensityValues;
-        for(unsigned row=0; row < nDataRows; row++) {
-            std::string string_to_parse;
-            std::vector<double> parsed_doubles;
-
-            string_to_parse = StringVectorVector[row][coordinateCol];
-            parsed_doubles = DataFormatUtils::parse_doubles(string_to_parse);
-            coordValues.push_back(parsed_doubles[0]);
-
-            string_to_parse = StringVectorVector[row][intensityCol];
-            parsed_doubles = DataFormatUtils::parse_doubles(string_to_parse);
-            intensityValues.push_back(parsed_doubles[0]);
-        }
-        auto axisName = m_coordinateName.toStdString();
-        PointwiseAxis coordAxis(axisName, coordValues);
-        result->addAxis(coordAxis);
-
-        for(unsigned i = 0; i < intensityValues.size(); i++)
-            (*result)[i] = intensityValues[i];
-    }
-    else{
-        result->addAxis("x", nDataCols, 0.0, double(nDataCols));
-        result->addAxis("y", nDataRows, 0.0, double(nDataRows));
-        std::vector<unsigned> axes_indices(2);
-        for(unsigned row=0; row<nDataRows; row++) {
-            for(unsigned col=0; col<nDataCols; col++) {
-                axes_indices[0] = col;
-                axes_indices[1] = static_cast<unsigned>(nDataRows) - 1 - row;
-                size_t global_index = result->toGlobalIndex(axes_indices);
-                std::string string_to_parse;
-                std::vector<double> parsed_doubles;
-                string_to_parse = StringVectorVector[row][col];
-                parsed_doubles = DataFormatUtils::parse_doubles(string_to_parse);
-                (*result)[global_index] = parsed_doubles[0];
-            }
-        }
-    }
-    return result;
-}
-
-
-void CsvImportAssistant::generate_table() {
-    std::unique_ptr<CSVFile> csvFile;
-    try {
-        csvFile = std::make_unique<CSVFile>(m_fileName.toStdString(), separator());
-    }
-    catch (...) {
-        QMessageBox msgBox;
-        std::string message = "There was a problem opening the file \"" + m_fileName.toStdString() + "\"";
-        msgBox.setText(QString::fromStdString(message));
-        msgBox.setIcon(msgBox.Critical);
-        msgBox.exec();
-        return;
-    }
-    m_firstDataRowSpinBox->setMaximum(int(csvFile->NumberOfRows()));
-    m_singleDataColSpinBox->setMaximum(int(csvFile->NumberOfColumns()));
-    m_lastDataRow = unsigned(int(csvFile->NumberOfRows()));
-    std::vector<std::vector<std::string>> csvArray = csvFile->asArray();
-
-    if (m_lastDataRow < 1) {
-        m_importButton->setDisabled(true);
-        return;
-    }
-
-
-    //Remove empty lines at the end automatically:
-    while(QString::fromStdString(accumulate(csvArray[m_lastDataRow-1].begin(), csvArray[m_lastDataRow-1].end(), std::string(""))).trimmed() == ""){
-        m_lastDataRow--;
-        m_firstDataRowSpinBox->setMaximum(int(m_lastDataRow));
-        if (m_lastDataRow < 1) {
-            m_importButton->setDisabled(true);
-            return;
-        }
-    }
-
-    std::vector<std::vector<std::string>> dataArray( csvArray.begin() + firstLine()-1, csvArray.begin() + m_lastDataRow );
-
-    removeBlankColumns(dataArray);
-
-    extractDesiredColumns(dataArray);
-
-    set_table_data(dataArray);
-
-    setRowNumbering();
-}
-
-void CsvImportAssistant::set_table_data(std::vector<std::vector<std::string>> dataArray){
-
-    if(dataArray.empty()){
-        m_tableWidget->clearContents();
-        m_tableWidget->setRowCount(0);
-        return;
-    }
-
-    size_t nRows = dataArray.size();
-    size_t nCols = dataArray[0].size();
-    m_tableWidget->clearContents();
-    m_tableWidget->setColumnCount(int(nCols));
-    m_tableWidget->setRowCount(0);
-
-    for(unsigned i = 0; i < nRows ; i++){
-        m_tableWidget->insertRow(m_tableWidget->rowCount());
-        unsigned I = unsigned(m_tableWidget->rowCount()) - 1;
-        for(unsigned j = 0; j < dataArray[i].size(); j++){
-            m_tableWidget->setItem(int(I),int(j),new QTableWidgetItem(QString::fromStdString(dataArray[i][j])));
-        }
-    }
-}
-
-
-void CsvImportAssistant::removeBlankColumns(std::vector<std::vector<std::string> > &dataArray){
-
-    if(dataArray.empty())
-        return;
-
-    std::vector<std::vector<std::string>> buffer2d;
-    std::vector<std::string> buffer1d;
-    std::vector<int> to_be_removed;
-
-    size_t nRows = dataArray.size();
-    size_t nCols = dataArray[0].size();
-
-    if(!hasEqualLengthLines(dataArray)){
-        throw Exceptions::NotImplementedException("All inner vectors should have the same length already.");
-    }
-
-    //traverse the array columnwise -- this may be inneficient.
-    for(size_t j = 0; j < nCols; j++){
-        buffer1d.clear();
-        for(size_t i = 0; i < nRows; i++){
-            buffer1d.push_back(dataArray[i][j]);
-        }
-        if(QString::fromStdString(accumulate(buffer1d.begin(), buffer1d.end(), std::string(""))).trimmed() == "")
-            continue;
-
-        buffer2d.push_back(buffer1d);
-    }
-
-    if(buffer2d.empty()){
-        dataArray.clear();
-        return;
-    }
-
-    //now buffer2d has the original array, without blank columns, transposed.
-    nCols = buffer2d.size();
-    nRows = buffer2d[0].size();
-
-    //Save the modified array --i.e. transpose buffer2d
-    dataArray.clear();
-    for(size_t i = 0; i < nRows; i++){
-        buffer1d.clear();
-        for(size_t j = 0; j < nCols; j++){
-            buffer1d.push_back(buffer2d[j][i]);
-        }
-        dataArray.push_back(buffer1d);
-    }
-}
-
-void CsvImportAssistant::setRowNumbering(){
-
-    unsigned firstDataLine = firstLine();
-    unsigned lastDataLine = lastLine();
-
-
-    QStringList displayRowNumbers;
-    for(unsigned i = firstDataLine; i <= lastDataLine; i++)
-        displayRowNumbers << QString::number(i);
-
-    m_tableWidget->setVerticalHeaderLabels(displayRowNumbers);
-}
-
-
-char CsvImportAssistant::separator() const{
-    char separator;
-    QString tmpstr = m_separatorField->text();
-    if(tmpstr.size() < 1){
-        separator = guessSeparator();
-        QMessageBox msgBox;
-        msgBox.setText("There was a problem with the separator given.\n Replacing it by ' ' [space]");
-        msgBox.setIcon(msgBox.Information);
-        msgBox.exec();
-        m_separatorField->setText(QString(QChar::fromLatin1(separator)));
-    }
-    else{
-        separator = tmpstr.at(0).toLatin1();
-    }
-    return separator;
-}
-
-char CsvImportAssistant::guessSeparator() const{
-    int frequencies[127] = {0};
-
-    //The actual characters that may be realistically
-    //used as separators are only a handfull...
-    //And this list seems already exagerated.
-    std::vector<char> preferredSeparators;
-    preferredSeparators.push_back(' ');
-    preferredSeparators.push_back(',');
-    preferredSeparators.push_back(';');
-    preferredSeparators.push_back('|');
-    preferredSeparators.push_back(':');
-    preferredSeparators.push_back('\t');
-    preferredSeparators.push_back('/');
-    preferredSeparators.push_back('\\');
-    preferredSeparators.push_back('_');
-    preferredSeparators.push_back('\'');
-    preferredSeparators.push_back('\"');
-
-
-    //count number of occurences of each char in the file:
-    char c;
-    std::ifstream is(m_fileName.toStdString());
-    while (is.get(c)){
-        if(unsigned(c) < 127)
-            frequencies[unsigned(c)]++;
-    }
-    is.close();
-
-    //set the guessed separator as the most frequent among the
-    //preferred separators. -- Some unavoidable hieararchy is
-    //present: characters with lower ascii code are preferred.
-    char guessedSep = ' ';
-    int freq = 0;
-    for(char i = 0; i< 127 ; i++){
-        if( std::find(preferredSeparators.begin(), preferredSeparators.end(), i) != preferredSeparators.end())
-            if(frequencies[int(i)] > freq){
-                freq = frequencies[int(i)];
-                guessedSep = i;
-            }
-    }
-
-    //We don't like tabs, as we cannot write them in the GUI.
-    //The rest of the CsvImportAssistant and CsvReader should be already aware of this.
-    if(guessedSep == '\t')
-        guessedSep = ' ';
-
-    return guessedSep;
-}
-
-void CsvImportAssistant::setHeaders(){
-   //Reset header labels
-   QStringList headers;
-
-   for(int j = 0; j < m_tableWidget->columnCount(); j++)
-       headers.append(QString::number(j + 1));
-
-   m_tableWidget->setHorizontalHeaderLabels(headers);
-}
-
-unsigned CsvImportAssistant::firstLine() const{
-    return unsigned(m_firstDataRowSpinBox->value());
-}
-
-unsigned CsvImportAssistant::lastLine() const{
-    return m_lastDataRow;
-}
-
-void CsvImportAssistant::OnColumnClicked(int row, int column)
-{
-    if(column < -1) return;
-    if(row < -1) return;
-
-    //m_tableWidget->clearSelection();
-    //m_tableWidget->selectionModel()->select
-//    QModelIndex left   = m_tableWidget->model()->index(row, 0);
- //   QModelIndex right  = m_tableWidget->model()->index(row, m_tableWidget->columnCount() - 1);
-  //  QModelIndex top    = m_tableWidget->model()->index(0, column);
-   // QModelIndex bottom = m_tableWidget->model()->index(m_tableWidget->rowCount() - 1, column);
-
-//    QItemSelection selection(left, right);
-//    selection.merge(QItemSelection(top, bottom), QItemSelectionModel::Select);
-//    m_tableWidget->selectionModel()->select(selection, QItemSelectionModel::Select);
-}
-
-void CsvImportAssistant::onColumnRightClick(const QPoint position)
-{
-    auto item = m_tableWidget->itemAt(position);
-    if(!item) return;
-    auto row = item->row();
-    auto col = item->column();
-
-    if(row*col < 0) return;
-
-    OnColumnClicked(row,col);
-    QMenu menu;
-
-
-    //Use single column
-    QAction onlyThisColumn("Use single column as intensity bins",nullptr);
-    onlyThisColumn.setDisabled(m_coordinateCol+m_intensityCol > 0 || m_singleCol > 0);
-    menu.addAction(&onlyThisColumn);
-    connect(&onlyThisColumn,&QAction::triggered,this,
-            [this](int col){
-            m_intensityCol = 0;
-            m_coordinateCol = 0;
-            m_coordinateName = "";
-            m_singleCol = unsigned(col+1);
-            m_singleDataColSpinBox->setValue(col+1);
-            m_tableWidget->setHorizontalHeaderItem(0, new QTableWidgetItem( relevantHeaders[_intensity_]) );
-        }
-    );
-
-    //Action "select from this row"
-    QAction selectFromThisRowOn("Ignore preceding rows",nullptr);
-    menu.addAction(&selectFromThisRowOn);
-    connect(&selectFromThisRowOn,&QAction::triggered,this,
-            [this](int row){m_firstDataRowSpinBox->setValue(m_tableWidget->verticalHeaderItem(row)->text().toInt());}
-    );
-
-
-    menu.addSeparator();
-
-
-    //Set column as "Intensity"
-    QAction setAsIntensity("Set as " + relevantHeaders[_intensity_] + " column", nullptr);
-    setAsIntensity.setDisabled(m_intensityCol>0 || m_singleCol > 0);
-    menu.addAction(&setAsIntensity);
-    connect(&setAsIntensity,&QAction::triggered,this,
-    [this](int col) {
-        m_tableWidget->setHorizontalHeaderItem(col, new QTableWidgetItem(relevantHeaders[_intensity_]));
-        m_intensityCol = unsigned(col+1);
-        if (m_coordinateCol == m_intensityCol) {
-            m_coordinateCol = 0;
-            return;
-        }
-        if (m_coordinateCol > 0){
-            Reload();
-            m_tableWidget->setHorizontalHeaderItem(0, new QTableWidgetItem(m_coordinateName));
-            m_tableWidget->setHorizontalHeaderItem(1, new QTableWidgetItem(relevantHeaders[_intensity_]));
-        }
-    }
-    );
-
-    QMenu *coordMenu = menu.addMenu("Set as coordinate column");
-    coordMenu->setDisabled(m_coordinateCol>0 || m_singleCol > 0);
-
-
-    //Set column as "Theta"
-    QAction setAsTheta("Set as " + relevantHeaders[_theta_],nullptr);
-    coordMenu->addAction(&setAsTheta);
-    connect(&setAsTheta,&QAction::triggered,this,
-    [this](int col){
-        m_tableWidget->setHorizontalHeaderItem( col, new QTableWidgetItem( relevantHeaders[_theta_]) );
-        m_coordinateCol = unsigned(col+1);
-        m_coordinateName = m_tableWidget->horizontalHeaderItem(col)->text();
-        if(m_coordinateCol == m_intensityCol){
-            m_intensityCol=0;
-            return;
-        }
-        if(m_intensityCol > 0){
-            Reload();
-            m_tableWidget->setHorizontalHeaderItem( 0, new QTableWidgetItem( relevantHeaders[_theta_]) );
-            m_tableWidget->setHorizontalHeaderItem( 1, new QTableWidgetItem( relevantHeaders[_intensity_]) );
-        }
-    }
-    );
-
-
-    //Set column as "2Theta"
-    QAction setAs2Theta("Set as " + relevantHeaders[_2theta_] + " column",nullptr);
-    coordMenu->addAction(&setAs2Theta);
-    connect(&setAs2Theta,&QAction::triggered,this,
-    [this](int col){
-        m_tableWidget->setHorizontalHeaderItem( col, new QTableWidgetItem( relevantHeaders[_2theta_]) );
-        m_coordinateCol = unsigned(col+1);
-        m_coordinateName = m_tableWidget->horizontalHeaderItem(col)->text();
-        if(m_coordinateCol == m_intensityCol){
-            m_intensityCol=0;
-            return;
-        }
-        if(m_intensityCol > 0){
-            Reload();
-            m_tableWidget->setHorizontalHeaderItem( 0, new QTableWidgetItem( relevantHeaders[_2theta_]) );
-            m_tableWidget->setHorizontalHeaderItem( 1, new QTableWidgetItem( relevantHeaders[_intensity_]) );
-        }
-    }
-    );
-
-
-    //Set column as "qvector"
-    QAction setAsQvector("Set as " + relevantHeaders[_q_] + " column",nullptr);
-    coordMenu->addAction(&setAsQvector);
-    connect(&setAsQvector,&QAction::triggered,this,
-    [this](int col){
-        m_tableWidget->setHorizontalHeaderItem( col, new QTableWidgetItem( relevantHeaders[_q_]) );
-        m_coordinateCol = unsigned(col+1);
-        m_coordinateName = m_tableWidget->horizontalHeaderItem(col)->text();
-        if(m_coordinateCol == m_intensityCol){
-            m_intensityCol=0;
-            return;
-        }
-        if(m_intensityCol > 0){
-            Reload();
-            m_tableWidget->setHorizontalHeaderItem( 0, new QTableWidgetItem( relevantHeaders[_q_]) );
-            m_tableWidget->setHorizontalHeaderItem( 1, new QTableWidgetItem( relevantHeaders[_intensity_]) );
-        }
-    }
-    );
-
-
-
-    menu.addSeparator();
-
-    //Action "reset"
-    QAction reset("reset",nullptr);
-    menu.addAction(&reset);
-    connect(&reset,&QAction::triggered,
-            [this](){
-                m_intensityCol = 0;
-                m_coordinateCol = 0;
-                m_coordinateName = "";
-                m_singleCol = 0;
-                m_firstDataRowSpinBox->setValue(0);
-                m_singleDataColSpinBox->setValue(0);
-                setHeaders();
-                Reload();
-            }
-    );
-
-    menu.exec(m_tableWidget->mapToGlobal(position));
-}
-
-
-bool CsvImportAssistant::hasEqualLengthLines(std::vector<std::vector<std::string>> &dataArray){
-   auto tf =  all_of( begin(dataArray), end(dataArray), [dataArray](const std::vector<std::string>& x) {
-       return x.size() == dataArray.front().size();
-   });
-   return tf;
-}
-
-void CsvImportAssistant::extractDesiredColumns(std::vector<std::vector<std::string>> &dataArray) {
-
-    if (dataArray.empty()) {
-        m_tableWidget->clearContents();
-        m_tableWidget->setRowCount(0);
-        return;
-    }
-
-    if ((m_coordinateCol * m_intensityCol < 1) && (m_singleCol < 1))
-        return;
-
-    std::vector<std::string> buffer1d;
-    std::vector<std::vector<std::string>> buffer2d;
-    auto nRows = dataArray.size();
-    auto nCols = dataArray[0].size();
-
-    if (m_singleCol > 0) {
-        for (unsigned i = 0; i < nRows; i++) {
-            buffer1d.clear();
-            for (unsigned j = 0; j < nCols; j++) {
-                if (j + 1 == m_singleCol)
-                    buffer1d.push_back(dataArray[i][j]);
-            }
-            buffer2d.push_back(buffer1d);
-        }
-    }
-    else {
-        for (unsigned i = 0; i < nRows; i++) {
-            buffer1d.clear();
-            //No matter what, we want coordinate column first
-            for (unsigned j = 0; j < nCols; j++) {
-                if (j + 1 == m_coordinateCol)
-                    buffer1d.push_back(dataArray[i][j]);
-            }
-            //Intensity columns comes next
-            for (unsigned j = 0; j < nCols; j++) {
-                if (j + 1 == m_intensityCol)
-                    buffer1d.push_back(dataArray[i][j]);
-            }
-            buffer2d.push_back(buffer1d);
-        }
-    }
-
-    dataArray.clear();
-    swap(buffer2d,dataArray);
-}
diff --git a/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant.h b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant.h
deleted file mode 100644
index c502046654ef9e2514d30dbd3d84efb3785d9f73..0000000000000000000000000000000000000000
--- a/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant.h
-//! @brief     Defines class CsvImportAssistant
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef CSVIMPORTASSISTANT_H
-#define CSVIMPORTASSISTANT_H
-
-#include "WinDllMacros.h"
-#include "CsvReader.h"
-#include "OutputData.h"
-#include <QDialog>
-#include <QTableWidget>
-#include <QLineEdit>
-#include <QLabel>
-#include <QSpinBox>
-#include <memory>
-
-class QBoxLayout;
-
-//! Dialog to hold ImportAssistant.
-
-class BA_CORE_API_ CsvImportAssistant : public QDialog
-{
-    Q_OBJECT
-
-public:
-    CsvImportAssistant(QString& dir, QString& file, QWidget* parent = nullptr);
-    char separator() const;
-    void setHeaders();
-    unsigned firstLine() const;
-    unsigned lastLine() const;
-    void Reload();
-    std::unique_ptr<OutputData<double>> getData();
-    QStringList relevantHeaders = {"Intensity","theta","2theta","q"};
-    enum relevantColumns {_intensity_,_theta_,_2theta_,_q_};
-
-public slots:
-    void onImportButton();
-    void onRejectButton();
-    void OnColumnClicked(int row, int column);
-    void onColumnRightClick(QPoint position);
-
-private:
-    QBoxLayout* createLayout();
-    QBoxLayout* createFileDetailsLayout();
-
-    char guessSeparator() const;
-    void generate_table();
-    void set_table_data(std::vector<std::vector<std::string>> dataArray);
-    void removeBlankColumns(std::vector<std::vector<std::string>> &dataArray);
-    void extractDesiredColumns(std::vector<std::vector<std::string>> &dataArray);
-    bool hasEqualLengthLines(std::vector<std::vector<std::string> > &dataArray);
-    void setRowNumbering();
-
-
-
-    QString m_dirName;
-    QString m_fileName;
-    unsigned m_lastDataRow;
-    unsigned m_intensityCol;
-    unsigned m_coordinateCol;
-    QString  m_coordinateName;
-    unsigned m_singleCol;
-
-    QTableWidget* m_tableWidget;
-    QLineEdit* m_separatorField;
-    QSpinBox* m_firstDataRowSpinBox;
-    QSpinBox* m_singleDataColSpinBox;
-    QPushButton* m_importButton;
-
-};
-
-#endif // CSVIMPORTASSISTANT_H
diff --git a/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvDataColumn.cpp b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvDataColumn.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..082251f9d56fe0e6db4f38d5ab4f9aa913bc2a6f
--- /dev/null
+++ b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvDataColumn.cpp
@@ -0,0 +1,119 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvDataColumn.cpp
+//! @brief     Implements classes CsvIntensityColumn and CsvCoordinateColumn
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "CsvDataColumn.h"
+
+/*Csv Intensity Column*/
+
+// Constructors:
+CsvIntensityColumn::CsvIntensityColumn() : m_colNum(-1), m_multiplier(1.0), m_values({})
+{
+}
+
+CsvIntensityColumn::CsvIntensityColumn(const CsvIntensityColumn& toCopy)
+    : m_colNum(toCopy.columnNumber()), m_multiplier(toCopy.multiplier()), m_values(toCopy.values())
+{
+}
+
+CsvIntensityColumn::CsvIntensityColumn(int colNum, double multiplier, csv::DataColumn values)
+    : m_colNum(colNum), m_multiplier(multiplier), m_values(values)
+{
+}
+
+// Getters:
+int CsvIntensityColumn::columnNumber() const
+{
+    return m_colNum;
+}
+double CsvIntensityColumn::multiplier() const
+{
+    return m_multiplier;
+}
+csv::DataColumn CsvIntensityColumn::values() const
+{
+    return m_values;
+}
+
+// Setters:
+void CsvIntensityColumn::setColNum(int const colNum)
+{
+    m_colNum = colNum;
+}
+void CsvIntensityColumn::setMultiplier(double const multiplier)
+{
+    m_multiplier = multiplier;
+}
+void CsvIntensityColumn::setValues(csv::DataColumn const values)
+{
+    m_values = std::move(values);
+}
+void CsvIntensityColumn::resetColumn(int colNum, double multiplier, csv::DataColumn values)
+{
+    m_colNum = colNum;
+    m_multiplier = multiplier;
+    m_values = std::move(values);
+}
+CsvIntensityColumn& CsvIntensityColumn::operator=(const CsvIntensityColumn colToRep)
+{
+    m_colNum = colToRep.columnNumber();
+    m_multiplier = colToRep.multiplier();
+    m_values = colToRep.values();
+    return *this;
+}
+
+/*Csv Coordinate Column*/
+
+// Constructors:
+CsvCoordinateColumn::CsvCoordinateColumn() : CsvIntensityColumn(), m_units(AxesUnits::NBINS)
+{
+}
+
+CsvCoordinateColumn::CsvCoordinateColumn(const CsvCoordinateColumn& toCopy)
+    : CsvIntensityColumn(toCopy), m_units(toCopy.units())
+{
+}
+
+CsvCoordinateColumn::CsvCoordinateColumn(int colNum, double multiplier, csv::DataColumn values,
+                                         AxesUnits units)
+
+    : CsvIntensityColumn(colNum, multiplier, values), m_units(units)
+{
+}
+// Getters:
+AxesUnits CsvCoordinateColumn::units() const
+{
+    return m_units;
+}
+// Setters:
+void CsvCoordinateColumn::setUnits(AxesUnits const units)
+{
+    m_units = units;
+}
+void CsvCoordinateColumn::setName(csv::ColumnType const name)
+{
+    m_name = name;
+}
+void CsvCoordinateColumn::resetColumn(int colNum, double multiplier, csv::DataColumn values,
+                                      AxesUnits units, csv::ColumnType name)
+{
+    CsvIntensityColumn::resetColumn(colNum, multiplier, values);
+    m_units = units;
+    m_name = name;
+}
+CsvCoordinateColumn& CsvCoordinateColumn::operator=(const CsvCoordinateColumn colToRep)
+{
+    m_units = colToRep.units();
+    m_name = colToRep.name();
+    return *this;
+}
diff --git a/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvDataColumn.h b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvDataColumn.h
new file mode 100644
index 0000000000000000000000000000000000000000..ccb2b6deb53cc55220647cf3466f419ded652126
--- /dev/null
+++ b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvDataColumn.h
@@ -0,0 +1,71 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvDataColumn.h
+//! @brief     Defines classes CsvIntensityColumn and CsvCoordinateColumn
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef CSVDATACOLUMN_H
+#define CSVDATACOLUMN_H
+
+#include "CsvNamespace.h"
+#include "IUnitConverter.h"
+
+class CsvIntensityColumn
+{
+public:
+    // Constructors:
+    CsvIntensityColumn();
+    CsvIntensityColumn(const CsvIntensityColumn& toCopy);
+    CsvIntensityColumn(int colNum, double multiplier, csv::DataColumn values);
+
+    // Getters:
+    int columnNumber() const;
+    double multiplier() const;
+    csv::DataColumn values() const;
+
+    // Setters:
+    void setColNum(int const colNum);
+    void setMultiplier(double const multiplier);
+    void setValues(csv::DataColumn const values);
+    void resetColumn(int colNum = -1, double multiplier = 1., csv::DataColumn values = {});
+    CsvIntensityColumn& operator=(const CsvIntensityColumn colToRep);
+
+private:
+    int m_colNum;
+    double m_multiplier;
+    csv::DataColumn m_values;
+};
+
+class CsvCoordinateColumn : public CsvIntensityColumn
+{
+public:
+    // Constructors:
+    CsvCoordinateColumn();
+    CsvCoordinateColumn(const CsvCoordinateColumn& toCopy);
+    CsvCoordinateColumn(int colNum, double multiplier, csv::DataColumn values, AxesUnits units);
+
+    // Getters:
+    AxesUnits units() const;
+    csv::ColumnType name() const { return m_name; }
+
+    // Setters:
+    void setUnits(AxesUnits const units);
+    void setName(csv::ColumnType const name);
+    void resetColumn(int colNum = -1, double multiplier = 1., csv::DataColumn values = {},
+                     AxesUnits units = AxesUnits::NBINS, csv::ColumnType name = csv::_intensity_);
+    CsvCoordinateColumn& operator=(const CsvCoordinateColumn colToRep);
+
+private:
+    AxesUnits m_units;
+    csv::ColumnType m_name;
+};
+
+#endif // CSVDATACOLUMN_H
diff --git a/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvImportAssistant.cpp b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvImportAssistant.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..15d629b5f546a5fd3008cc03d69ad893689cadd9
--- /dev/null
+++ b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvImportAssistant.cpp
@@ -0,0 +1,381 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvImportAssistant.cpp
+//! @brief     Implements class CsvImportAssistant
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "CsvImportAssistant.h"
+#include "DataFormatUtils.cpp"
+#include "DataSelector.h"
+#include "ImportDataInfo.h"
+#include "StyleUtils.h"
+#include "mainwindow_constants.h"
+#include <QFileDialog>
+#include <QFormLayout>
+#include <QMenu>
+#include <QMessageBox>
+#include <QPushButton>
+#include <QSettings>
+#include <QTableWidget>
+#include <QVBoxLayout>
+#include <algorithm>
+
+CsvImportAssistant::CsvImportAssistant(const QString& file, const bool useGUI, QWidget* parent)
+    : m_fileName(file), m_csvFile(nullptr), m_csvArray(), m_separator('\0'), m_intensityColNum(-1),
+      m_intensityMultiplier(1.0), m_coordinateColNum(-1), m_coordinateMultiplier(1.0),
+      m_firstRow(-1), m_lastRow(-1), m_units(AxesUnits::NBINS), m_dataAvailable(false)
+{
+    if (!loadCsvFile()) {
+        return;
+    }
+
+    if (useGUI) {
+        runDataSelector(parent);
+    } else {
+        m_intensityColNum = 0;
+        m_coordinateColNum = -1;
+        m_units = AxesUnits::NBINS;
+        m_firstRow = 0;
+        m_lastRow = int(m_csvFile->NumberOfRows() - 1);
+        m_dataAvailable = true;
+    }
+}
+
+void CsvImportAssistant::runDataSelector(QWidget* parent)
+{
+    DataSelector selector(m_csvArray, parent);
+    m_separator = guessSeparator();
+    selector.setSeparator(guessSeparator());
+    connect(&selector, &DataSelector::separatorChanged, this, [this, &selector](char newSep) {
+        if (newSep != m_separator) {
+            m_separator = newSep;
+            loadCsvFile();
+            selector.setDataArray(m_csvArray);
+            selector.setSeparator(newSep);
+        }
+    });
+
+    int res = selector.exec();
+
+    if (res == selector.Accepted) {
+        m_intensityColNum = selector.intensityColumn();
+        m_intensityMultiplier = selector.intensityMultiplier();
+        m_coordinateColNum = selector.coordinateColumn();
+        m_coordinateMultiplier = selector.coordinateMultiplier();
+        m_units = selector.units();
+        m_firstRow = int(selector.firstLine() - 1);
+        m_lastRow = int(selector.lastLine() - 1);
+        m_rowsToDiscard = selector.rowsToDiscard();
+        m_dataAvailable = true;
+    } else if (res == selector.Rejected) {
+        m_dataAvailable = false;
+        return;
+    }
+}
+
+void CsvImportAssistant::setIntensityColumn(int iCol, double multiplier)
+{
+    m_intensityColNum = iCol - 1;
+    m_intensityMultiplier = multiplier;
+}
+void CsvImportAssistant::setCoordinateColumn(int iCol, AxesUnits units, double multiplier)
+{
+    m_coordinateColNum = iCol - 1;
+    m_units = units;
+    m_coordinateMultiplier = multiplier;
+}
+void CsvImportAssistant::setFirstRow(int iRow)
+{
+    m_firstRow = iRow - 1;
+}
+void CsvImportAssistant::setLastRow(int iRow)
+{
+    m_lastRow = iRow - 1;
+}
+
+bool CsvImportAssistant::loadCsvFile()
+{
+
+    try {
+        if (m_separator == '\0')
+            m_separator = guessSeparator();
+        m_csvFile = std::make_unique<CSVFile>(m_fileName.toStdString(), m_separator);
+    } catch (...) {
+        showErrorMessage("There was a problem opening the file \"" + m_fileName.toStdString()
+                         + "\"");
+        return false;
+    }
+
+    size_t lastRow = m_csvFile->NumberOfRows();
+
+    if (lastRow < 1) {
+        CsvImportAssistant::showErrorMessage("The file exist but it seems to be empty");
+        return false;
+    }
+
+    auto csvArray = m_csvFile->asArray();
+
+    // Automatically ignore empty lines at the end:
+    while (QString::fromStdString(accumulate(csvArray[lastRow - 1].begin(),
+                                             csvArray[lastRow - 1].end(), std::string("")))
+               .trimmed()
+           == "") {
+        lastRow--;
+        if (lastRow < 1) {
+            CsvImportAssistant::showErrorMessage("The file exist but it seems to be empty");
+            return false;
+        }
+    }
+
+    // TODO: If separator is white space, ignore consecutive spaces...
+    // {
+    // }
+
+    csv::DataArray tmp(csvArray.begin(), csvArray.begin() + int(lastRow));
+    m_csvArray.swap(tmp);
+    removeBlankColumns();
+    if (m_separator == ' ')
+        removeMultipleWhiteSpaces();
+
+    return true;
+}
+
+void CsvImportAssistant::resetAssistant()
+{
+    resetSelection();
+    loadCsvFile();
+}
+
+ImportDataInfo CsvImportAssistant::fillData()
+{
+    // In case a 2d import is needed in the future
+    // Use ArrayUtils::Create2dData(vector<vector<double>>)
+    // ArrayUtils::Create2d
+    std::unique_ptr<OutputData<double>> resultOutputData;
+    resultOutputData = std::make_unique<OutputData<double>>();
+    std::vector<double> intensityValues;
+    std::vector<double> coordinateValues;
+
+    getValuesFromColumns(intensityValues,coordinateValues);
+
+    auto axisName = csv::UnitsLabels[m_units].toStdString();
+    PointwiseAxis coordAxis(axisName, coordinateValues);
+    resultOutputData->addAxis(coordAxis);
+    resultOutputData->setRawDataVector(intensityValues);
+
+    ImportDataInfo result(std::move(resultOutputData), m_units);
+    return result;
+}
+
+void CsvImportAssistant::getValuesFromColumns(std::vector<double>& intensityValues,
+                                              std::vector<double>& coordinateValues)
+{
+    bool intensityOk = true;
+    bool coordinateOk = true;
+    auto firstRow = size_t(m_firstRow);
+    auto lastRow = size_t(m_lastRow) + 1;
+    bool isCoordinateNeeded = m_coordinateColNum > -1;
+    double intensityValue = 0.;
+    double coordinateValue = 0.;
+
+    for (size_t row = firstRow; row < lastRow; row++) {
+        if (std::find(m_rowsToDiscard.begin(), m_rowsToDiscard.end(), int(row))
+            == m_rowsToDiscard.end()) {
+            // Intensity Values:
+            QString intensityText =
+                QString::fromStdString(m_csvArray[row][size_t(m_intensityColNum)]);
+            intensityValue = intensityText.toDouble(&intensityOk);
+
+            // Coordinate Values:
+            if (isCoordinateNeeded) {
+                QString coordinateText =
+                    QString::fromStdString(m_csvArray[row][size_t(m_coordinateColNum)]);
+                coordinateValue = coordinateText.toDouble(&coordinateOk);
+            } else {
+                coordinateValue = row - firstRow;
+            }
+
+            // Add them if they are both ok:
+            if (intensityOk && coordinateOk) {
+                intensityValues.push_back(m_intensityMultiplier * intensityValue);
+                coordinateValues.push_back(m_coordinateMultiplier * coordinateValue);
+            }
+        }
+    }
+}
+
+void CsvImportAssistant::removeMultipleWhiteSpaces()
+{
+    if (m_csvArray.empty())
+        return;
+
+    csv::DataArray buffer2d;
+    csv::DataRow buffer1d;
+    size_t nRows = m_csvArray.size();
+    size_t nCols = m_csvArray[0].size();
+    size_t newNcols = 0;
+
+    for (size_t i = 0; i < nRows; i++) {
+        buffer1d.clear();
+        for (size_t j = 0; j < nCols; j++) {
+            QString text = QString::fromStdString(m_csvArray[i][j]).trimmed();
+            if (text != "")
+                buffer1d.push_back(text.toStdString());
+        }
+        newNcols = std::max(buffer1d.size(), newNcols);
+        buffer2d.push_back(buffer1d);
+    }
+
+    if (buffer2d.empty()) {
+        m_csvArray.clear();
+        return;
+    }
+
+    for (size_t i = 0; i < nRows; i++)
+        while (buffer2d[i].size() < newNcols)
+            buffer2d[i].push_back("");
+
+    // now buffer2d has the original array, without empty cells
+    nRows = buffer2d.size();
+    nCols = buffer2d[0].size();
+
+    m_csvArray.swap(buffer2d);
+}
+
+void CsvImportAssistant::removeBlankColumns()
+{
+
+    if (m_csvArray.empty())
+        return;
+
+    csv::DataArray buffer2d;
+    csv::DataRow buffer1d;
+    std::vector<int> to_be_removed;
+
+    size_t nRows = m_csvArray.size();
+    size_t nCols = m_csvArray[0].size();
+
+    if (!hasEqualLengthLines(m_csvArray)) {
+        throw Exceptions::NotImplementedException(
+            "All inner vectors should have the same length already.");
+    }
+
+    // traverse the array columnwise -- this may be inneficient.
+    for (size_t j = 0; j < nCols; j++) {
+        buffer1d.clear();
+        for (size_t i = 0; i < nRows; i++) {
+            buffer1d.push_back(m_csvArray[i][j]);
+        }
+        if (QString::fromStdString(accumulate(buffer1d.begin(), buffer1d.end(), std::string("")))
+                .trimmed()
+            == "")
+            continue;
+
+        buffer2d.push_back(buffer1d);
+    }
+
+    if (buffer2d.empty()) {
+        m_csvArray.clear();
+        return;
+    }
+
+    // now buffer2d has the original array, without blank columns, transposed.
+    nCols = buffer2d.size();
+    nRows = buffer2d[0].size();
+
+    // Save the modified array --i.e. transpose buffer2d
+    m_csvArray.clear();
+    for (size_t i = 0; i < nRows; i++) {
+        buffer1d.clear();
+        for (size_t j = 0; j < nCols; j++) {
+            buffer1d.push_back(buffer2d[j][i]);
+        }
+        m_csvArray.push_back(buffer1d);
+    }
+}
+
+char CsvImportAssistant::guessSeparator() const
+{
+    int frequencies[127] = {0};
+
+    // The actual characters that may be realistically
+    // used as separators are only a handfull...
+    // And this list seems already exagerated.
+    std::vector<char> preferredSeparators;
+    preferredSeparators.push_back(' ');
+    preferredSeparators.push_back(',');
+    preferredSeparators.push_back(';');
+    preferredSeparators.push_back('|');
+    preferredSeparators.push_back(':');
+    preferredSeparators.push_back('\t');
+    // preferredSeparators.push_back('/');
+    // preferredSeparators.push_back('\\');
+    // preferredSeparators.push_back('_');
+    preferredSeparators.push_back('\'');
+    preferredSeparators.push_back('\"');
+
+    // count number of occurences of each char in the file:
+    char c;
+    std::ifstream is(m_fileName.toStdString());
+    while (is.get(c)) {
+        if (size_t(c) < 127)
+            frequencies[size_t(c)]++;
+    }
+    is.close();
+
+    // set the guessed separator as the most frequent among the
+    // preferred separators. -- Some unavoidable hieararchy is
+    // present: characters with lower ascii code are preferred.
+    char guessedSep = ' ';
+    int freq = 0;
+    for (char i = 0; i < 127; i++) {
+        if (std::find(preferredSeparators.begin(), preferredSeparators.end(), i)
+            != preferredSeparators.end())
+            if (frequencies[int(i)] > freq) {
+                freq = frequencies[int(i)];
+                guessedSep = i;
+            }
+    }
+
+    // We don't like tabs, as we cannot write them in the GUI.
+    // The rest of the CsvImportAssistant and CsvReader should be already aware of this.
+    if (guessedSep == '\t')
+        guessedSep = ' ';
+
+    return guessedSep;
+}
+
+bool CsvImportAssistant::hasEqualLengthLines(csv::DataArray& dataArray)
+{
+    auto tf = all_of(begin(dataArray), end(dataArray), [dataArray](const csv::DataRow& x) {
+        return x.size() == dataArray.front().size();
+    });
+    return tf;
+}
+
+void CsvImportAssistant::showErrorMessage(std::string message)
+{
+    QMessageBox msgBox;
+    msgBox.setText(QString::fromStdString(message));
+    msgBox.setIcon(msgBox.Critical);
+    msgBox.exec();
+}
+
+void CsvImportAssistant::resetSelection()
+{
+    m_csvArray.clear();
+    m_intensityColNum = -1;
+    m_coordinateColNum = -1;
+    m_firstRow = -1;
+    m_lastRow = -1;
+    m_units = AxesUnits::NBINS;
+    m_dataAvailable = false;
+}
diff --git a/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvImportAssistant.h b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvImportAssistant.h
new file mode 100644
index 0000000000000000000000000000000000000000..e30101798706ef45cac6f1b7cc860ff88d53f751
--- /dev/null
+++ b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvImportAssistant.h
@@ -0,0 +1,90 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvImportAssistant.h
+//! @brief     Defines class CsvImportAssistant
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef CSVIMPORTASSISTANT_H
+#define CSVIMPORTASSISTANT_H
+
+#include "CsvDataColumn.h"
+#include "CsvReader.h"
+#include "DataFormatUtils.h"
+#include "ImportDataInfo.h"
+#include "WinDllMacros.h"
+#include <QStringList>
+#include <QWidget>
+#include <memory>
+#include <set>
+
+class csvSelectionState
+{
+public:
+    csvSelectionState()
+        : m_intensityColNum(-1), m_intensityMultiplier(1.), m_coordinateColNum(-1),
+          m_coordinateMultiplier(1.), m_firstRow(-1), m_lastRow(-1), m_units(AxesUnits::NBINS)
+    {
+    }
+
+    int m_intensityColNum;
+    double m_intensityMultiplier;
+    int m_coordinateColNum;
+    double m_coordinateMultiplier;
+    int m_firstRow;
+    int m_lastRow;
+    AxesUnits m_units;
+
+    bool availableData() { return m_intensityColNum > -1; }
+};
+
+//! Logic for importing intensity data from csv files
+class BA_CORE_API_ CsvImportAssistant : public QObject
+{
+    Q_OBJECT
+public:
+    CsvImportAssistant(const QString& file, const bool useGUI = false, QWidget* parent = nullptr);
+    ImportDataInfo getData() { return m_dataAvailable ? fillData() : ImportDataInfo(); }
+    static void showErrorMessage(std::string message);
+    void setIntensityColumn(int iCol, double multiplier = 1.0);
+    void setCoordinateColumn(int iCol, AxesUnits units, double multiplier = 1.0);
+    void setFirstRow(int iRow);
+    void setLastRow(int iRow);
+    size_t columnCount() { return m_csvArray[0].size(); }
+    char separator() { return m_separator; }
+
+private:
+    bool loadCsvFile();
+    ImportDataInfo fillData();
+    bool hasEqualLengthLines(csv::DataArray& dataArray);
+    char guessSeparator() const;
+    void removeBlankColumns();
+    void removeMultipleWhiteSpaces();
+    void runDataSelector(QWidget* parent);
+    void getValuesFromColumns(std::vector<double>& intensityVals,
+                                            std::vector<double>& coordVals);
+    void resetSelection();
+    void resetAssistant();
+
+    QString m_fileName;
+    std::unique_ptr<CSVFile> m_csvFile;
+    csv::DataArray m_csvArray;
+    char m_separator;
+    int m_intensityColNum;
+    double m_intensityMultiplier;
+    int m_coordinateColNum;
+    double m_coordinateMultiplier;
+    int m_firstRow;
+    int m_lastRow;
+    std::set<int> m_rowsToDiscard;
+    AxesUnits m_units;
+    bool m_dataAvailable;
+};
+#endif // CSVIMPORTASSISTANT_H
diff --git a/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvImportTable.cpp b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvImportTable.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..12d8524ba596321db5bd50f52134ac9523ccd625
--- /dev/null
+++ b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvImportTable.cpp
@@ -0,0 +1,397 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvImportTable.cpp
+//! @brief     Implements class CsvImportTable
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "CsvImportTable.h"
+
+CsvImportTable::CsvImportTable(QWidget* parent) : QTableWidget(parent)
+{
+    m_coordinateCol = std::make_unique<CsvCoordinateColumn>();
+    m_intensityCol = std::make_unique<CsvCoordinateColumn>();
+    m_firstRow = 0;
+    m_lastRow = 0;
+    m_dataLooksGood = false;
+}
+
+int CsvImportTable::selectedRow() const
+{
+    auto selectedRanges = this->selectedRanges();
+    if (selectedRanges.empty())
+        return -1;
+    auto front = selectedRanges.front();
+    auto row = front.topRow();
+    return row - rowOffset();
+}
+
+std::set<int> CsvImportTable::selectedRows() const
+{
+    std::set<int> accumulator;
+
+    auto selection = selectedRanges();
+    if (selection.empty())
+        return {};
+
+    int size = selection.size();
+    for (int rangenumber = 0; rangenumber < size; ++rangenumber) {
+        int row0 = selectedRanges()[rangenumber].topRow() - rowOffset();
+        int rowN = selectedRanges()[rangenumber].bottomRow() - rowOffset();
+        for (int r = row0; r <= rowN; ++r) {
+            accumulator.insert(r);
+        }
+    }
+    return accumulator;
+}
+
+int CsvImportTable::selectedColumn() const
+{
+    auto selectedRanges = this->selectedRanges();
+    if (selectedRanges.empty())
+        return -1;
+    auto front = selectedRanges.front();
+    auto col = front.leftColumn();
+    return col;
+}
+
+void CsvImportTable::setHeaders()
+{
+    // Reset header labels
+    QStringList headers;
+
+    for (int j = 0; j < this->columnCount(); j++)
+        headers.append(QString::number(j + 1));
+
+    this->setHorizontalHeaderLabels(headers);
+
+    if (m_intensityCol->columnNumber() > -1) {
+        int intCol = int(m_intensityCol->columnNumber());
+        this->setHorizontalHeaderItem(intCol,
+                                      new QTableWidgetItem(csv::HeaderLabels[csv::_intensity_]));
+    }
+    if (m_coordinateCol->columnNumber() > -1) {
+        QString label = csv::HeaderLabels[m_coordinateCol->name()];
+        int coordCol = int(m_coordinateCol->columnNumber());
+        this->setHorizontalHeaderItem(coordCol, new QTableWidgetItem(label));
+    }
+}
+
+void CsvImportTable::setMultiplierFields()
+{
+    auto ncols = this->columnCount();
+    auto intCol = m_intensityCol->columnNumber();
+    auto intMult = m_intensityCol->multiplier();
+    auto coordCol = m_coordinateCol->columnNumber();
+    auto coordMult = m_coordinateCol->multiplier();
+
+    for (int n = 0; n < ncols; ++n) {
+        CsvMultiplierField* currentField;
+        if (n == intCol) {
+            currentField = new CsvMultiplierField(intMult, true);
+            connect(currentField, &CsvMultiplierField::editingFinished, this,
+                    [this, currentField]() {
+                        m_intensityCol->setMultiplier(currentField->value());
+                        updateSelection();
+                    });
+        } else if (n == coordCol) {
+            currentField = new CsvMultiplierField(coordMult, true);
+            connect(currentField, &CsvMultiplierField::editingFinished, this,
+                    [this, currentField]() {
+                        m_coordinateCol->setMultiplier(currentField->value());
+                        updateSelection();
+                    });
+        } else {
+            currentField = new CsvMultiplierField();
+        }
+        this->setCellWidget(0, n, currentField);
+    }
+
+    int nRows = this->rowCount();
+
+    QStringList vhlabels;
+    vhlabels << "Multiplier: ";
+    for (int i = rowOffset(); i < nRows; i++)
+        vhlabels << QString::number(i);
+
+    this->setVerticalHeaderLabels(vhlabels);
+}
+
+void CsvImportTable::setData(const csv::DataArray data)
+{
+    if (data.empty()) {
+        this->clearContents();
+        this->setRowCount(0);
+        return;
+    }
+
+    size_t nRows = data.size();
+    size_t nCols = data[0].size();
+    this->clearContents();
+    this->setColumnCount(int(nCols));
+    this->setRowCount(0);
+
+    this->insertRow(this->rowCount());
+
+    for (size_t i = 0; i < nRows; i++) {
+        this->insertRow(this->rowCount());
+        size_t I = size_t(this->rowCount()) - 1;
+        for (size_t j = 0; j < data[i].size(); j++) {
+            this->setItem(int(I), int(j), new QTableWidgetItem(QString::fromStdString(data[i][j])));
+        }
+    }
+
+    setMultiplierFields();
+}
+
+void CsvImportTable::setFirstRow(size_t row)
+{
+    if (row != m_firstRow) {
+        m_firstRow = row;
+        updateSelection();
+    }
+}
+
+void CsvImportTable::setLastRow(size_t row)
+{
+    if (m_lastRow != row) {
+        m_lastRow = row;
+        updateSelection();
+    }
+}
+
+void CsvImportTable::discardRows(std::set<int> rows)
+{
+    if (rows.empty()) {
+        m_rowsToDiscard.clear();
+    } else {
+        for (auto row : rows) {
+            if (isRowDiscarded(row)) {
+                m_rowsToDiscard.erase(row);
+            } else {
+                m_rowsToDiscard.insert(row);
+            }
+        }
+    }
+    updateSelection();
+}
+
+void CsvImportTable::updateSelection()
+{
+    setHeaders();
+    setMultiplierFields();
+    applyMultipliers();
+    greyoutDataToDiscard();
+    runSanityChecks();
+}
+
+void CsvImportTable::restoreColumnValues(int col, csv::DataColumn colvals)
+{
+    for (size_t i = 0; i < colvals.size(); i++) {
+        QString originalText = QString::fromStdString(colvals[i]);
+        setItem(int(i) + rowOffset(), int(col), new QTableWidgetItem(originalText));
+    }
+}
+
+void CsvImportTable::greyoutDataToDiscard()
+{
+    int nRows = this->rowCount();
+    int nCols = this->columnCount();
+
+    // Grey out columns
+    for (int i = rowOffset(); i < nRows; i++)
+        for (int j = 0; j < nCols; j++)
+            greyoutCell(i, j, needsGreyout(i, j));
+}
+
+void CsvImportTable::runSanityChecks()
+{
+    bool intensitiesLookGood = runIntensitySanityChecks();
+    bool coordinatesLookGood = runCoordinateSanityChecks();
+    bool dataLooksGood = intensitiesLookGood && coordinatesLookGood;
+    if (dataLooksGood != m_dataLooksGood) {
+        m_dataLooksGood = dataLooksGood;
+        emit dataSanityChanged();
+    }
+}
+
+bool CsvImportTable::runCoordinateSanityChecks()
+{
+    bool dataLooksGood = true;
+    int jCol = m_coordinateCol->columnNumber();
+    csv::DataRow values = m_coordinateCol->values();
+    size_t size = m_coordinateCol->values().size();
+    double greatestNumber = 0;
+
+    for (int i = 0; i < int(size) - 1; i++) {
+        bool userDiscard = isRowDiscarded(i);
+        if (i < firstRow() - rowOffset() || i > lastRow() || userDiscard)
+            continue;
+
+        size_t I = size_t(i);
+        auto cellText = QString::fromStdString(values[I]);
+        auto nextCellText = QString::fromStdString(values[I + 1]);
+        bool correctDoubleFormat;
+        double number = cellText.toDouble(&correctDoubleFormat);
+        greatestNumber = std::max(number, greatestNumber);
+
+        // if two consecutive values are non-increasing:
+        if (!correctDoubleFormat || (number - greatestNumber < 0)) {
+            bool alreadyDiscarded = needsGreyout(i + rowOffset(), jCol);
+            greyoutCell(i + rowOffset(), jCol, alreadyDiscarded, Qt::red);
+            if (!alreadyDiscarded)
+                dataLooksGood = false;
+        }
+
+        double nextNumber = nextCellText.toDouble(&correctDoubleFormat);
+        if (!correctDoubleFormat || (nextNumber - number < 1e-14)) {
+            bool alreadyDiscarded = needsGreyout(i + 1 + rowOffset(), jCol);
+            greyoutCell(i + 1 + rowOffset(), jCol, alreadyDiscarded, Qt::red);
+            if (!alreadyDiscarded)
+                dataLooksGood = false;
+        }
+    }
+    return dataLooksGood;
+}
+
+bool CsvImportTable::runIntensitySanityChecks()
+{
+    bool dataLooksGood = true;
+    int jCol = m_intensityCol->columnNumber();
+    csv::DataRow values = m_intensityCol->values();
+    size_t size = m_intensityCol->values().size();
+
+    for (int i = 0; i < int(size) - 1; i++) {
+        bool userDiscard = isRowDiscarded(i);
+        if (i < firstRow() - rowOffset() || i > lastRow() || userDiscard)
+            continue;
+
+        size_t I = size_t(i);
+        auto cellText = QString::fromStdString(values[I]);
+        bool correctDoubleFormat;
+        cellText.toDouble(&correctDoubleFormat);
+        // if two consecutive values are non-increasing:
+        if (!correctDoubleFormat) {
+            bool alreadyDiscarded = needsGreyout(i + rowOffset(), jCol);
+            greyoutCell(i + rowOffset(), jCol, alreadyDiscarded, Qt::red);
+            if (!alreadyDiscarded)
+                dataLooksGood = false;
+        }
+    }
+    return dataLooksGood;
+}
+
+void CsvImportTable::greyoutCell(int i, int j, bool yes, Qt::GlobalColor color)
+{
+    if (yes) {
+        QFont italicFont;
+        italicFont.setItalic(true);
+        italicFont.setStrikeOut(true);
+        item(i, j)->setBackground(Qt::gray);
+        item(i, j)->setFont(italicFont);
+    } else {
+        QFont standardFont;
+        standardFont.setItalic(false);
+        standardFont.setStrikeOut(false);
+        item(i, j)->setBackground(color);
+        item(i, j)->setFont(standardFont);
+    }
+}
+
+bool CsvImportTable::needsGreyout(const int iRow, const int jCol) const
+{
+    int vecRow = iRow - rowOffset();
+    bool userDiscard = isRowDiscarded(vecRow);
+    bool greyTop = vecRow < int(m_firstRow);
+    bool greyBott = vecRow > int(m_lastRow);
+    bool greyCol = jCol != int(m_coordinateCol->columnNumber())
+                   && jCol != int(m_intensityCol->columnNumber())
+                   && int(m_intensityCol->columnNumber()) > 0;
+
+    return greyTop || greyBott || greyCol || userDiscard;
+}
+
+void CsvImportTable::applyMultipliers()
+{
+    if (m_intensityCol->columnNumber() > -1) {
+        multiplyColumn(*m_intensityCol);
+    }
+
+    if (m_coordinateCol->columnNumber() > -1) {
+        multiplyColumn(*m_coordinateCol);
+    }
+}
+
+void CsvImportTable::multiplyColumn(const CsvIntensityColumn& col)
+{
+    auto colNum = col.columnNumber();
+    if (colNum < 0)
+        return;
+
+    double multiplier = col.multiplier();
+    csv::DataColumn values = col.values();
+    size_t size = col.values().size();
+    int idx0 = rowOffset();
+    for (size_t i = 0; i < size; i++) {
+        auto currentText = QString::fromStdString(values[i]);
+        double number = multiplier * currentText.toDouble();
+        QString textToWrite = 0.0 == number ? currentText : QString::number(number);
+        this->setItem(int(i) + idx0, colNum, new QTableWidgetItem(textToWrite));
+    }
+}
+
+void CsvImportTable::setColumnAs(int col, csv::ColumnType coordOrInt, double multiplier)
+{
+    csv::DataColumn buffer = valuesFromColumn(col);
+    if (coordOrInt == csv::_intensity_) {
+        restoreColumnValues(m_intensityCol->columnNumber(), m_intensityCol->values());
+        m_intensityCol->setColNum(col);
+        m_intensityCol->setMultiplier(multiplier);
+        m_intensityCol->setValues(buffer);
+        if (col == m_coordinateCol->columnNumber())
+            m_coordinateCol->resetColumn();
+    } else {
+        restoreColumnValues(m_coordinateCol->columnNumber(), m_coordinateCol->values());
+        m_coordinateCol->setColNum(col);
+        m_coordinateCol->setMultiplier(multiplier);
+        m_coordinateCol->setValues(buffer);
+        m_coordinateCol->setName(coordOrInt);
+        if (col == m_intensityCol->columnNumber())
+            m_intensityCol->resetColumn();
+    }
+    updateSelection();
+}
+
+csv::DataColumn CsvImportTable::valuesFromColumn(int col)
+{
+    if (col < 0) {
+        return {};
+    } else if (m_intensityCol->columnNumber() == col) {
+        return m_intensityCol->values();
+    } else if (m_coordinateCol->columnNumber() == col) {
+        return m_coordinateCol->values();
+    } else {
+        csv::DataColumn result;
+        size_t rowCount = size_t(this->rowCount() - rowOffset());
+        result = csv::DataColumn(rowCount);
+        int idx0 = rowOffset();
+        for (size_t i = 0; i < rowCount; ++i) {
+            int I = int(i) + idx0;
+            auto currentText = this->item(I, int(col))->text();
+            result[i] = currentText.toStdString();
+        }
+        return result;
+    }
+}
+
+bool CsvImportTable::isRowDiscarded(const int row) const
+{
+    return std::find(m_rowsToDiscard.begin(), m_rowsToDiscard.end(), row) != m_rowsToDiscard.end();
+}
diff --git a/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvImportTable.h b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvImportTable.h
new file mode 100644
index 0000000000000000000000000000000000000000..014e2eacabef64ddd89bd405a603175ac0f3cbbc
--- /dev/null
+++ b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvImportTable.h
@@ -0,0 +1,109 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvImportTable.h
+//! @brief     Defines class CsvImportTable
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef CSVIMPORTTABLE_H
+#define CSVIMPORTTABLE_H
+
+#include "CsvDataColumn.h"
+#include "CsvNamespace.h"
+#include "IUnitConverter.h"
+#include <QDoubleSpinBox>
+#include "ScientificSpinBox.h"
+#include <QMenu>
+#include <QStringList>
+#include <QTableWidget>
+#include <set>
+
+class CsvImportTable : public QTableWidget
+{
+    Q_OBJECT
+public:
+    CsvImportTable(QWidget* parent = nullptr);
+
+    int selectedRow() const;
+    std::set<int> selectedRows() const;
+    int selectedColumn() const;
+    int intensityColumn() const { return m_intensityCol->columnNumber(); }
+    int coordinateColumn() const { return m_coordinateCol->columnNumber(); }
+    int firstRow() { return int(m_firstRow) + rowOffset(); }
+    int lastRow() { return int(m_lastRow) + rowOffset(); }
+    double intensityMultiplier() const { return m_intensityCol->multiplier(); }
+    double coordinateMultiplier() const { return m_coordinateCol->multiplier(); }
+    std::set<int> rowsToDiscard() const { return m_rowsToDiscard; }
+    csv::ColumnType coordinateName() const { return m_coordinateCol->name(); }
+    AxesUnits coordinateUnits() const { return m_coordinateCol->units(); }
+    bool dataLooksGood() const { return m_dataLooksGood; }
+
+    void setData(const csv::DataArray data);
+    void updateSelection();
+    void applyMultipliers();
+    void setColumnAs(int col, csv::ColumnType CoordOrInt, double multiplier = 1.0);
+    void setFirstRow(size_t row);
+    void setLastRow(size_t row);
+    void discardRows(std::set<int> rows);
+    void setCoordinateName(const csv::ColumnType coordName)
+    {
+        m_coordinateCol->setName(coordName);
+        setHeaders();
+    }
+    void setMultiplierFields();
+
+signals:
+    void dataSanityChanged();
+
+private:
+    bool isRowDiscarded(const int row) const ;
+    void runSanityChecks();
+    bool runIntensitySanityChecks();
+    bool runCoordinateSanityChecks();
+    void greyoutDataToDiscard();
+    void greyoutCell(int i, int j, bool yes, Qt::GlobalColor color = Qt::white);
+    bool needsGreyout(const int iRow, const int jCol) const;
+    void multiplyColumn(const CsvIntensityColumn& col);
+    void restoreColumnValues(int col, csv::DataColumn colvals);
+    csv::DataColumn valuesFromColumn(int col);
+    void setHeaders();
+    int rowOffset() const { return 1; } // this comes from the multipliers in the first row
+
+    std::unique_ptr<CsvIntensityColumn> m_intensityCol;
+    std::unique_ptr<CsvCoordinateColumn> m_coordinateCol;
+    size_t m_firstRow;
+    size_t m_lastRow;
+    std::set<int> m_rowsToDiscard;
+    bool m_dataLooksGood;
+};
+
+class CsvMultiplierField : public ScientificSpinBox
+{
+    Q_OBJECT
+public:
+    CsvMultiplierField(double multiplier = 1.0, bool enabled = false, QWidget* parent = nullptr)
+        : ScientificSpinBox(parent)
+    {
+        if (enabled) {
+            setMaximum(1e10);
+            setMinimum(1e-10);
+            setDecimals(10);
+            setValue(multiplier);
+        } else {
+            setMaximum(1);
+            setMinimum(1);
+            setDecimals(1);
+            setValue(multiplier);
+        }
+        setEnabled(enabled);
+    }
+};
+
+#endif // CSVIMPORTTABLE_H
diff --git a/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvNamespace.cpp b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvNamespace.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..64a6e293ddee5137ae80068c47becc640af05ab9
--- /dev/null
+++ b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvNamespace.cpp
@@ -0,0 +1,38 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvNamespace.cpp
+//! @brief     Implements functions of namespace csv
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "CsvNamespace.h"
+#include <fstream>
+#include <sstream>
+
+bool csv::isAscii(QString filename)
+{
+    return true;
+    // TODO
+    // This function needs to be defined properly (if at all)
+    // motivation: ° and Å characters are problematic.
+    char c;
+    size_t count = 0;
+    size_t count_bad = 0;
+    std::ifstream is(filename.toStdString());
+    while (is.get(c) && count < 1000) {
+        count++;
+        if (size_t(c) > 255)
+            count_bad++;
+    }
+    is.close();
+    double acceptance_threshold = 0.1 * double(count);
+    // std::cout << count << "; " << count_bad << std::endl;
+    return static_cast<double>(count_bad) <= acceptance_threshold;
+}
diff --git a/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvNamespace.h b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvNamespace.h
new file mode 100644
index 0000000000000000000000000000000000000000..2778473827174e094dd824af5f9e2b2dccdc6f12
--- /dev/null
+++ b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvNamespace.h
@@ -0,0 +1,33 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvNamespace.h
+//! @brief     Defines namespace csv
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef CSVNAMESPACE_H
+#define CSVNAMESPACE_H
+
+#include <QString>
+#include <QStringList>
+#include <vector>
+
+namespace csv
+{
+enum ColumnType { _intensity_, _theta_, _q_ };
+const QStringList HeaderLabels{"Intensity", "theta", "q"};
+const QStringList UnitsLabels{"default", "bin", "rad", "deg", "mm", "1/nm"};
+typedef std::vector<std::vector<std::string>> DataArray;
+typedef std::vector<std::string> DataRow;
+typedef std::vector<std::string> DataColumn;
+bool isAscii(QString filename);
+}
+
+#endif // CSVNAMESPACE_H
diff --git a/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvReader.cpp b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvReader.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..289de6a512dd00f35ae1beffa22d3a5d69436e0f
--- /dev/null
+++ b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvReader.cpp
@@ -0,0 +1,137 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvReader.cpp
+//! @brief     Implements class CsvReader
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "CsvReader.h"
+#include <fstream>
+#include <iostream>
+
+std::string const& CSVRow::operator[](unsigned index) const
+{
+    return m_data[index];
+}
+
+unsigned long CSVRow::size() const
+{
+    return static_cast<unsigned long>(m_data.size());
+}
+
+void CSVRow::readNextRow(std::istream& str)
+{
+    std::string line;
+    std::getline(str, line);
+    std::replace(std::begin(line), std::end(line), '\t', ' ');
+    std::stringstream lineStream(line);
+    std::string cell;
+
+    m_data.clear();
+
+    while (std::getline(lineStream, cell, separator)) {
+        addCell(cell);
+    }
+    // This checks for a trailing comma with no data after it.
+    if (!lineStream && cell.empty()) {
+        // If there was a trailing comma then add an empty element.
+        addCell("");
+    }
+}
+
+void CSVRow::setSeparator(char sep)
+{
+    this->separator = sep;
+    return;
+}
+
+char CSVRow::getSeparator()
+{
+    return this->separator;
+}
+
+void CSVRow::addCell(std::string str)
+{
+    m_data.push_back(str);
+}
+
+void CSVFile::Init()
+{
+    Read();
+    EqualizeRowLengths();
+}
+
+void CSVFile::Read()
+{
+    std::ifstream file(filepath);
+    if (!file.is_open()) {
+        throw std::ios_base::failure("Unable to open file \"" + filepath + "\"");
+    }
+    for (CSVIterator loop(file, separator); loop != CSVIterator(); ++loop) {
+        rows.push_back((*loop));
+        numberOfColumns =
+            (*loop).size() > numberOfColumns ? unsigned((*loop).size()) : numberOfColumns;
+    }
+}
+
+void CSVFile::EqualizeRowLengths()
+{
+    for (unsigned i = 0; i < NumberOfRows(); i++) {
+        while (rows[i].size() < NumberOfColumns()) {
+            rows[i].addCell("");
+        }
+    }
+    for (unsigned i = 0; i < NumberOfRows(); i++) {
+        m_data.push_back(rows[i].dataVector());
+    }
+}
+
+std::vector<std::string> const CSVFile::operator[](unsigned index_i) const
+{
+    return m_data[index_i];
+}
+
+unsigned long CSVFile::NumberOfRows() const
+{
+    return static_cast<unsigned long>(rows.size());
+}
+
+unsigned long CSVFile::NumberOfColumns() const
+{
+    return this->numberOfColumns;
+}
+
+void CSVFile::set_separator(char sep)
+{
+    this->separator = sep;
+    return;
+}
+
+char CSVFile::get_separator()
+{
+    return this->separator;
+}
+
+CSVRow CSVFile::get_headers()
+{
+    if (headersRow > 0) {
+        return this->rows[headersRow - 1];
+    } else {
+        CSVRow dummy;
+        while (dummy.size() < NumberOfColumns())
+            dummy.addCell("");
+        return dummy;
+    }
+}
+
+CSVRow CSVFile::get_row(unsigned i)
+{
+    return this->rows[i];
+}
diff --git a/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvReader.h b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvReader.h
new file mode 100644
index 0000000000000000000000000000000000000000..749ca2a2cd9fbb829d5eb191995dcb98c4dbf595
--- /dev/null
+++ b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvReader.h
@@ -0,0 +1,127 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvReader.h
+//! @brief     Defines class CsvReader
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef CSVREADER_H
+#define CSVREADER_H
+
+#include <algorithm>
+#include <fstream>
+#include <iostream>
+#include <iterator>
+#include <sstream>
+#include <vector>
+
+class CSVRow
+{
+public:
+    std::string const& operator[](unsigned index) const;
+    unsigned long size() const;
+    void readNextRow(std::istream& str);
+    void setSeparator(char sep);
+    char getSeparator();
+    void addCell(std::string str);
+    std::vector<std::string> dataVector() { return m_data; }
+
+private:
+    std::vector<std::string> m_data;
+    char separator = '-';
+};
+
+inline std::istream& operator>>(std::istream& str, CSVRow& data)
+{
+    data.readNextRow(str);
+    return str;
+}
+
+class CSVIterator
+{
+public:
+    typedef std::input_iterator_tag iterator_category;
+    typedef CSVRow value_type;
+    typedef unsigned long difference_type;
+    typedef CSVRow* pointer;
+    typedef CSVRow& reference;
+
+    CSVIterator(std::istream& str, char sep) : m_str(str.good() ? &str : nullptr)
+    {
+        m_sep = sep;
+        ++(*this);
+    }
+    CSVIterator() : m_str(nullptr) {}
+
+    // Pre Increment
+    CSVIterator& operator++()
+    {
+        if (m_str) {
+            m_row.setSeparator(m_sep);
+            if (!((*m_str) >> m_row)) {
+                m_str = nullptr;
+            }
+        }
+        return *this;
+    }
+    // Post increment
+    CSVIterator operator++(int)
+    {
+        CSVIterator tmp(*this);
+        ++(*this);
+        return tmp;
+    }
+    CSVRow const& operator*() const { return m_row; }
+    CSVRow const* operator->() const { return &m_row; }
+    bool operator==(CSVIterator const& rhs)
+    {
+        return ((this == &rhs) || ((this->m_str == nullptr) && (rhs.m_str == nullptr)));
+    }
+    bool operator!=(CSVIterator const& rhs) { return !((*this) == rhs); }
+
+private:
+    std::istream* m_str;
+    CSVRow m_row;
+    char m_sep;
+};
+
+class CSVFile
+{
+public:
+    CSVFile(std::string path_to_file) : filepath(path_to_file) { Init(); }
+    CSVFile(std::string path_to_file, char sep) : filepath(path_to_file), separator(sep) { Init(); }
+    CSVFile(std::string path_to_file, char sep, unsigned headRow)
+        : filepath(path_to_file), separator(sep), headersRow(headRow)
+    {
+        Init();
+    }
+
+    void Init();
+    void Read();
+    void EqualizeRowLengths();
+    std::vector<std::string> const operator[](unsigned index_i) const;
+    unsigned long NumberOfRows() const;
+    unsigned long NumberOfColumns() const;
+    void set_separator(char sep);
+    char get_separator();
+    CSVRow get_headers();
+    CSVRow get_row(unsigned i);
+    std::vector<std::vector<std::string>> asArray() { return m_data; }
+
+private:
+    std::string filepath;
+    char separator = '-';
+    unsigned headersRow = 0;
+    unsigned numberOfColumns = 0;
+    std::vector<CSVRow> rows;
+    std::vector<std::vector<std::string>> m_data;
+};
+
+#endif // CSVREADER_H
diff --git a/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/DataSelector.cpp b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/DataSelector.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9c649b60eefcfa492789f04f6a655f297915c157
--- /dev/null
+++ b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/DataSelector.cpp
@@ -0,0 +1,394 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/DataSelector.cpp
+//! @brief     Implements class DataSelector
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "DataSelector.h"
+#include "CsvImportTable.h"
+#include "ImportDataInfo.h"
+#include "StyleUtils.h"
+#include "TableContextMenu.h"
+#include "mainwindow_constants.h"
+#include <QFileDialog>
+#include <QFormLayout>
+#include <QGroupBox>
+#include <QMenu>
+#include <QMessageBox>
+#include <QPushButton>
+#include <QSettings>
+#include <QTableWidget>
+#include <QVBoxLayout>
+#include <locale>
+#include <sstream>
+
+namespace
+{
+const QSize default_dialog_size(300, 400);
+}
+
+DataSelector::DataSelector(csv::DataArray csvArray, QWidget* parent)
+    : QDialog(parent), m_data(csvArray), m_tableWidget(nullptr), m_separatorField(nullptr),
+      m_firstDataRowSpinBox(nullptr), m_lastDataRowSpinBox(nullptr),
+      m_coordinateUnitsComboBox(nullptr), m_importButton(nullptr), m_cancelButton(nullptr),
+      m_errorLabel(nullptr)
+{
+    setWindowTitle("Data Importer");
+    setMinimumSize(default_dialog_size);
+    resize(600, 600);
+    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+    StyleUtils::setResizable(this);
+    setLayout(createLayout());
+
+    if (!updateData())
+        return;
+}
+
+bool DataSelector::updateData()
+{
+    size_t lastRow = m_data.size();
+
+    if (lastRow < 1) {
+        m_importButton->setDisabled(true);
+        CsvImportAssistant::showErrorMessage("There is no data to show");
+        return false;
+    }
+
+    m_tableWidget->setData(m_data);
+    m_firstDataRowSpinBox->setMaximum(int(lastRow));
+    m_lastDataRowSpinBox->setMaximum(int(lastRow));
+    m_lastDataRowSpinBox->setValue(int(lastRow));
+
+    return true;
+}
+
+void DataSelector::setColumnSlot(csv::ColumnType ct)
+{
+    setColumnAs(ct);
+}
+
+bool DataSelector::isInsideTable(const QPoint position)
+{
+    auto item = m_tableWidget->itemAt(position);
+
+    if (!item)
+        return false;
+
+    auto row = item->row();
+    auto col = item->column();
+    if (row * col < 0)
+        return false;
+
+    return true;
+}
+
+void DataSelector::onColumnRightClick(const QPoint& position)
+{
+    if (!isInsideTable(position))
+        return;
+
+    auto globalPos = m_tableWidget->mapToGlobal(position);
+
+    TableContextMenu contextMenu(this);
+    connect(&contextMenu, &TableContextMenu::setFirstRow, this, [this]() { setFirstRow(); });
+    connect(&contextMenu, &TableContextMenu::setLastRow, this, [this]() { setLastRow(); });
+    connect(&contextMenu, &TableContextMenu::setColumnAs, this, &DataSelector::setColumnSlot);
+    connect(&contextMenu, &TableContextMenu::discardRow, this, [this]() { discardRow(); });
+    connect(&contextMenu, &TableContextMenu::resetTable, this, [this]() {
+        resetSelection();
+        updateSelection();
+    });
+    contextMenu.exec(globalPos);
+}
+
+void DataSelector::updateSelection()
+{
+    m_importButton->setEnabled(false);
+    m_coordinateUnitsComboBox->setEnabled(false);
+    m_tableWidget->setFirstRow(firstLine() - 1);
+    m_tableWidget->setLastRow(lastLine() - 1);
+
+    if (!m_tableWidget->dataLooksGood()) {
+        m_errorLabel->setText(
+            "\n\n"
+            "Data selected for importing does not look good!\n\n"
+            "Make sure that:\n"
+            "    1. There are no repeated values in the coordinate column.\n"
+            "    2. The coordinate values are ascendingly sorted.\n"
+            "    3. Intensity and coordinate values are valid numbers.\n\n"
+            "Use the context menu of the table to manually discard some rows;\n"
+            "Alternatively, modify the file in an external editor.");
+    } else {
+        m_errorLabel->clear();
+    }
+
+    // Enable import button only if the user has selected its columns for 1d
+    if (m_tableWidget->intensityColumn() > -1)
+        if (m_tableWidget->dataLooksGood())
+            m_importButton->setEnabled(true);
+
+    // Enable Coordinate Selector
+    if (m_tableWidget->coordinateColumn() > -1) {
+        m_coordinateUnitsComboBox->setEnabled(true);
+    } else {
+        m_coordinateUnitsComboBox->clear();
+        m_coordinateUnitsComboBox->addItem(csv::UnitsLabels[AxesUnits::NBINS]);
+    }
+}
+
+void DataSelector::setColumnAs(int col, csv::ColumnType coordOrInt)
+{
+    m_tableWidget->setColumnAs(col, coordOrInt);
+    populateUnitsComboBox();
+    updateSelection();
+}
+
+void DataSelector::populateUnitsComboBox()
+{
+    csv::ColumnType coord = m_tableWidget->coordinateName();
+    m_coordinateUnitsComboBox->clear();
+    switch (coord) {
+
+    case csv::_theta_:
+        m_coordinateUnitsComboBox->addItem(csv::UnitsLabels[AxesUnits::DEGREES]);
+        m_coordinateUnitsComboBox->addItem(csv::UnitsLabels[AxesUnits::RADIANS]);
+        break;
+
+    case csv::_q_:
+        m_coordinateUnitsComboBox->addItem(csv::UnitsLabels[AxesUnits::QSPACE]);
+        break;
+
+    default:
+        m_coordinateUnitsComboBox->addItem(csv::UnitsLabels[AxesUnits::NBINS]);
+        break;
+    }
+}
+
+void DataSelector::setColumnAs(csv::ColumnType coordOrInt)
+{
+    auto col = m_tableWidget->selectedColumn();
+    if (col < 0)
+        return;
+
+    setColumnAs(col, coordOrInt);
+}
+
+void DataSelector::setFirstRow()
+{
+    auto row = m_tableWidget->selectedRow();
+    if (row < 0)
+        return;
+
+    auto currentMax = m_firstDataRowSpinBox->maximum();
+    auto desiredVal = row + 1;
+    auto newMax = std::max(currentMax, desiredVal);
+    m_firstDataRowSpinBox->setMaximum(newMax);
+    m_firstDataRowSpinBox->setValue(desiredVal);
+    m_tableWidget->setFirstRow(size_t(row));
+}
+
+void DataSelector::setLastRow()
+{
+    auto row = m_tableWidget->selectedRow();
+    if (row < 0)
+        return;
+
+    auto currentMin = m_firstDataRowSpinBox->minimum();
+    auto desiredVal = row + 1;
+    auto newMin = std::min(currentMin, desiredVal);
+    m_lastDataRowSpinBox->setMinimum(newMin);
+    m_lastDataRowSpinBox->setValue(desiredVal);
+    m_tableWidget->setLastRow(size_t(row));
+}
+
+void DataSelector::discardRow()
+{
+    std::set<int> selection = m_tableWidget->selectedRows();
+    m_tableWidget->discardRows(selection);
+}
+
+void DataSelector::resetSelection()
+{
+    setColumnAs(-1, csv::_theta_);
+    setColumnAs(-1, csv::_q_);
+    setColumnAs(-1, csv::_intensity_);
+
+    m_firstDataRowSpinBox->setValue(0);
+    m_lastDataRowSpinBox->setValue(int(maxLines()));
+    m_tableWidget->discardRows({});
+}
+
+size_t DataSelector::firstLine() const
+{
+    return size_t(m_firstDataRowSpinBox->value());
+}
+
+size_t DataSelector::lastLine() const
+{
+    return size_t(m_lastDataRowSpinBox->value());
+}
+
+size_t DataSelector::maxLines() const
+{
+    return size_t(m_lastDataRowSpinBox->maximum());
+}
+
+AxesUnits DataSelector::units() const
+{
+    AxesUnits defaultUnits = AxesUnits::NBINS;
+    for (int i = 0; i < csv::UnitsLabels.size(); i++)
+        if (m_coordinateUnitsComboBox->currentText() == csv::UnitsLabels[i])
+            return AxesUnits(i);
+    return defaultUnits;
+}
+
+char DataSelector::separator() const
+{
+    char separator;
+    QString tmpstr = m_separatorField->text();
+    if (tmpstr.size() < 1) {
+        separator = '\0';
+    } else {
+        separator = tmpstr.at(0).toLatin1();
+    }
+    return separator;
+}
+
+void DataSelector::onCancelButton()
+{
+    reject();
+}
+
+void DataSelector::onImportButton()
+{
+    //We shouldn't be here if the data is
+    //not previously sanitised.
+        accept();
+}
+
+QBoxLayout* DataSelector::createLayout()
+{
+    // table Widget
+    m_tableWidget = new CsvImportTable();
+    m_tableWidget->setContextMenuPolicy(Qt::CustomContextMenu);
+    m_tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
+    connect(m_tableWidget, &QTableWidget::customContextMenuRequested, this,
+            &DataSelector::onColumnRightClick);
+    connect(m_tableWidget, &CsvImportTable::dataSanityChanged, this,
+            [this]() { updateSelection(); });
+
+    // Error label
+    m_errorLabel = new QLabel();
+    m_errorLabel->setStyleSheet("QLabel { color : red; }");
+    m_errorLabel->setText("");
+
+    // Import button
+    m_importButton = new QPushButton("Import");
+    m_importButton->setDefault(false);
+    m_importButton->setAutoDefault(false);
+    connect(m_importButton, &QPushButton::clicked, this, &DataSelector::onImportButton);
+
+    // Reject button
+    m_cancelButton = new QPushButton("Cancel");
+    m_cancelButton->setDefault(false);
+    m_cancelButton->setAutoDefault(false);
+    connect(m_cancelButton, &QPushButton::clicked, this, [this]() { reject(); });
+
+    // Separator field -- This needs to communicate with importAssistant
+    m_separatorField = new QLineEdit(QString(""));
+    m_separatorField->setMaxLength(1);
+    m_separatorField->setMaximumWidth(70);
+    m_separatorField->setMinimumWidth(70);
+    connect(m_separatorField, &QLineEdit::editingFinished, this,
+            [this]() { emit separatorChanged(separator()); });
+
+    // First Row SpinBox
+    m_firstDataRowSpinBox = new QSpinBox();
+    m_firstDataRowSpinBox->setMinimum(1);
+    m_firstDataRowSpinBox->setMaximum(1);
+    m_firstDataRowSpinBox->setValue(1);
+    m_firstDataRowSpinBox->setMaximumWidth(70);
+    m_firstDataRowSpinBox->setMinimumWidth(70);
+    connect(m_firstDataRowSpinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
+            this, [this]() {
+                m_lastDataRowSpinBox->setMinimum(m_firstDataRowSpinBox->value());
+                updateSelection();
+            });
+
+    // Last Row SpinBox
+    m_lastDataRowSpinBox = new QSpinBox();
+    m_lastDataRowSpinBox->setMinimum(1);
+    m_lastDataRowSpinBox->setMaximum(1);
+    m_lastDataRowSpinBox->setValue(1);
+    m_lastDataRowSpinBox->setMaximumWidth(70);
+    m_lastDataRowSpinBox->setMinimumWidth(70);
+    connect(m_lastDataRowSpinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
+            this, [this]() {
+                m_firstDataRowSpinBox->setMaximum(m_lastDataRowSpinBox->value());
+                updateSelection();
+            });
+
+    // Coordinate units selector:
+    m_coordinateUnitsComboBox = new QComboBox();
+    m_coordinateUnitsComboBox->setMaximumWidth(70);
+    m_coordinateUnitsComboBox->setMinimumWidth(70);
+    m_coordinateUnitsComboBox->addItem(csv::UnitsLabels[AxesUnits::NBINS]);
+
+    auto layout = new QVBoxLayout;
+    layout->setContentsMargins(0, 0, 0, 0);
+
+    // Separator:
+    auto separatorFieldLayout = new QFormLayout;
+    separatorFieldLayout->addRow(tr("&Separator: "), m_separatorField);
+
+    // Place table Widget:
+    auto tableLayout = new QVBoxLayout;
+    tableLayout->setMargin(10);
+    tableLayout->addWidget(new QLabel("Right click on the table to select what will be imported"));
+    tableLayout->addWidget(m_tableWidget);
+    tableLayout->addLayout(separatorFieldLayout);
+    tableLayout->addLayout(separatorFieldLayout);
+    tableLayout->addWidget(m_errorLabel);
+
+    // First and last data rows:
+    auto rowControlsLayout = new QFormLayout;
+    auto* rowControlsGroupBox = new QGroupBox;
+    rowControlsLayout->addRow(tr("&From row: "), m_firstDataRowSpinBox);
+    rowControlsLayout->addRow(tr("&To row: "), m_lastDataRowSpinBox);
+    rowControlsLayout->setMargin(10);
+    rowControlsGroupBox->setTitle(tr("&Data rows:"));
+    rowControlsGroupBox->setLayout(rowControlsLayout);
+
+    // Unit selector
+    auto unitSelectionLayout = new QFormLayout;
+    unitSelectionLayout->addRow(tr("&Coordinate units: "), m_coordinateUnitsComboBox);
+    unitSelectionLayout->setMargin(10);
+
+    // buttons layout
+    auto buttonsLayout = new QHBoxLayout;
+    buttonsLayout->addWidget(m_importButton);
+    buttonsLayout->addWidget(m_cancelButton);
+
+    // place controls and import/reject buttons
+    auto controlsAndButtonsGrid = new QGridLayout;
+    controlsAndButtonsGrid->setMargin(10);
+    controlsAndButtonsGrid->addItem(new QSpacerItem(10000, 1), 1, 1, 2, 1);
+    controlsAndButtonsGrid->addWidget(rowControlsGroupBox, 1, 2, 1, 1, Qt::AlignRight);
+    controlsAndButtonsGrid->addLayout(unitSelectionLayout, 2, 2, Qt::AlignRight);
+    controlsAndButtonsGrid->addLayout(buttonsLayout, 3, 2, 1, 1, Qt::AlignRight);
+
+    // build all the layout
+    layout->addLayout(separatorFieldLayout);
+    layout->addLayout(tableLayout);
+    layout->addLayout(controlsAndButtonsGrid);
+
+    return layout;
+}
diff --git a/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/DataSelector.h b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/DataSelector.h
new file mode 100644
index 0000000000000000000000000000000000000000..1266cb722578f9e2aeeca327a2440fa438ef45cc
--- /dev/null
+++ b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/DataSelector.h
@@ -0,0 +1,95 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/DataSelector.h
+//! @brief     Defines class DataSelector
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef DATASELECTOR_H
+#define DATASELECTOR_H
+
+#include "CsvDataColumn.h"
+#include "CsvImportAssistant.h"
+#include "CsvImportTable.h"
+#include "CsvNamespace.h"
+#include "ImportDataInfo.h"
+#include "WinDllMacros.h"
+#include <QAction>
+#include <QComboBox>
+#include <QDialog>
+#include <QLabel>
+#include <QLineEdit>
+#include <QSpinBox>
+#include <QTableWidget>
+#include <memory>
+
+class QBoxLayout;
+
+//! Dialog to hold DataSelector.
+class DataSelector : public QDialog
+{
+    Q_OBJECT
+public:
+    DataSelector(csv::DataArray csvArray, QWidget* parent = nullptr);
+    size_t firstLine() const;
+    size_t lastLine() const;
+    int intensityColumn() const { return m_tableWidget->intensityColumn(); }
+    int coordinateColumn() const { return m_tableWidget->coordinateColumn(); }
+    double intensityMultiplier() const { return m_tableWidget->intensityMultiplier(); }
+    double coordinateMultiplier() const { return m_tableWidget->coordinateMultiplier(); }
+    std::set<int> rowsToDiscard() const { return m_tableWidget->rowsToDiscard(); }
+    AxesUnits units() const;
+    void setDataArray(csv::DataArray csvArray)
+    {
+        m_data = std::move(csvArray);
+        updateData();
+        resetSelection();
+    }
+    void setSeparator(char newSeparator)
+    {
+        m_separatorField->setText(QString(QChar(newSeparator)));
+    }
+
+public slots:
+    void onImportButton();
+    void onCancelButton();
+    void onColumnRightClick(const QPoint& position);
+    void setColumnSlot(csv::ColumnType ct);
+
+signals:
+    void separatorChanged(char newSeparator);
+
+private:
+    size_t maxLines() const;
+    char separator() const;
+    void setColumnAs(csv::ColumnType coordOrInt);
+    void setColumnAs(int col, csv::ColumnType coordOrInt);
+    void setFirstRow();
+    void setLastRow();
+    void discardRow();
+    void resetSelection();
+    void updateSelection();
+    bool updateData();
+    QBoxLayout* createLayout();
+    void populateUnitsComboBox();
+    bool isInsideTable(QPoint point);
+    bool dataLooksGood();
+
+    csv::DataArray m_data;
+    CsvImportTable* m_tableWidget;
+    QLineEdit* m_separatorField;
+    QSpinBox* m_firstDataRowSpinBox;
+    QSpinBox* m_lastDataRowSpinBox;
+    QComboBox* m_coordinateUnitsComboBox;
+    QPushButton* m_importButton;
+    QPushButton* m_cancelButton;
+    QLabel* m_errorLabel;
+};
+#endif // DATASELECTOR_H
diff --git a/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/TableContextMenu.cpp b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/TableContextMenu.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6bb7173fa5df66910c3f50c323278ab88d9d39be
--- /dev/null
+++ b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/TableContextMenu.cpp
@@ -0,0 +1,50 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/TableContextMenu.cpp
+//! @brief     Implements class TableContextMenu
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "TableContextMenu.h"
+
+TableContextMenu::TableContextMenu(QWidget* parent)
+    : QMenu(parent), m_coordSubMenu(this),
+      m_selectFromThisRowOn(new QAction("Set As First Data Row", this)),
+      m_selectUntilThisRow(new QAction("Set As Last Data Row", this)),
+      m_resetAction(new QAction("Reset", this)),
+      m_setAsTheta(new QAction(csv::HeaderLabels[csv::_theta_], this)),
+      m_setAsQ(new QAction(csv::HeaderLabels[csv::_q_], this)),
+      m_setAsIntensity(
+          new QAction("Set As " + csv::HeaderLabels[csv::_intensity_] + " Column", this)),
+      m_discardRow(new QAction("Toogle Discard Selected Rows", this))
+{
+    this->addAction(m_selectFromThisRowOn);
+    this->addAction(m_selectUntilThisRow);
+    this->addAction(m_discardRow);
+
+    this->addSeparator();
+    this->addAction(m_setAsIntensity);
+
+    m_coordSubMenu = this->addMenu("Set As Coordinate Column...");
+    m_coordSubMenu->addAction(m_setAsTheta);
+    m_coordSubMenu->addAction(m_setAsQ);
+
+    this->addSeparator();
+    this->addAction(m_resetAction);
+
+    connect(m_selectFromThisRowOn, &QAction::triggered, this, [this]() { emit setFirstRow(); });
+    connect(m_selectUntilThisRow, &QAction::triggered, this, [this]() { emit setLastRow(); });
+    connect(m_setAsIntensity, &QAction::triggered, this,
+            [this]() { emit setColumnAs(csv::_intensity_); });
+    connect(m_setAsTheta, &QAction::triggered, this, [this]() { emit setColumnAs(csv::_theta_); });
+    connect(m_setAsQ, &QAction::triggered, this, [this]() { emit setColumnAs(csv::_q_); });
+    connect(m_resetAction, &QAction::triggered, this, [this]() { emit resetTable(); });
+    connect(m_discardRow, &QAction::triggered,this,[this](){emit discardRow();});
+}
diff --git a/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/TableContextMenu.h b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/TableContextMenu.h
new file mode 100644
index 0000000000000000000000000000000000000000..784649bb4c344c4613d0ab0dc8ee736e3f1a0526
--- /dev/null
+++ b/GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/TableContextMenu.h
@@ -0,0 +1,50 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/TableContextMenu.h
+//! @brief     Defines class TableContextMenu
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef TABLECONTEXTMENU_H
+#define TABLECONTEXTMENU_H
+
+#include "CsvNamespace.h"
+#include "IUnitConverter.h"
+#include <QMenu>
+#include <QStringList>
+#include <QTableWidget>
+
+class TableContextMenu : public QMenu
+{
+    Q_OBJECT
+public:
+    TableContextMenu(QWidget* parent = nullptr);
+
+signals:
+    void setFirstRow();
+    void setLastRow();
+    void setColumnAs(csv::ColumnType);
+    void resetTable();
+    void discardRow();
+
+private:
+    int m_row;
+    int m_col;
+    QMenu* m_coordSubMenu;
+    QAction* m_selectFromThisRowOn;
+    QAction* m_selectUntilThisRow;
+    QAction* m_resetAction;
+    QAction* m_setAsTheta;
+    QAction* m_setAsQ;
+    QAction* m_setAsIntensity;
+    QAction* m_discardRow;
+};
+
+#endif // TABLECONTEXTMENU_H
diff --git a/GUI/coregui/Views/ImportDataWidgets/CsvReader.cpp b/GUI/coregui/Views/ImportDataWidgets/CsvReader.cpp
deleted file mode 100644
index 4915aead35bbf497014cec3254f24130d2175d0a..0000000000000000000000000000000000000000
--- a/GUI/coregui/Views/ImportDataWidgets/CsvReader.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-#include "CsvReader.h"
-#include <fstream>
-#include <iostream>
-
-std::string const& CSVRow::operator[](unsigned index) const
-{
-    return m_data[index];
-}
-
-unsigned long CSVRow::size() const
-{
-    return m_data.size();
-}
-
-void CSVRow::readNextRow(std::istream& str)
-{
-    std::string         line;
-    std::getline(str, line);
-    std::replace(std::begin(line),std::end(line),'\t',' ');
-
-    std::stringstream   lineStream(line);
-    std::string         cell;
-
-    m_data.clear();
-    while(std::getline(lineStream, cell, separator))
-    {
-        m_data.push_back(cell);
-    }
-    // This checks for a trailing comma with no data after it.
-    if (!lineStream && cell.empty())
-    {
-        // If there was a trailing comma then add an empty element.
-        m_data.push_back("");
-    }
-}
-
-void CSVRow::setSeparator(char sep){
-    this->separator = sep;
-    return;
-}
-
-char CSVRow::getSeparator(){
-    return this->separator;
-}
-
-void CSVRow::addCell(std::string str){
-    m_data.push_back(str);
-}
-
-void CSVFile::Init()
-{
-    Read();
-    EqualizeRowLengths();
-}
-
-void CSVFile::Read()
-{
-    std::ifstream file(filepath);
-    if(!file.is_open()){throw std::ios_base::failure("Unable to open file \"" + filepath + "\"");}
-    for(CSVIterator loop(file, separator); loop != CSVIterator(); ++loop){
-        rows.push_back((*loop));
-        numberOfColumns = (*loop).size() > numberOfColumns ? unsigned((*loop).size()) : numberOfColumns;
-    }
-}
-
-void CSVFile::EqualizeRowLengths()
-{
-    for(unsigned i = 0; i < NumberOfRows(); i++){
-        while(rows[i].size() < NumberOfColumns()) {
-            rows[i].addCell("");
-        }
-    }
-    for(unsigned i = 0; i < NumberOfRows(); i++){
-        m_data.push_back(rows[i].dataVector());
-    }
-}
-
-
-std::vector<std::string> const CSVFile::operator[](unsigned index_i) const
-{
-    return m_data[index_i];
-}
-
-unsigned long CSVFile::NumberOfRows() const
-{
-    return rows.size();
-}
-
-unsigned long CSVFile::NumberOfColumns() const
-{
-    return this->numberOfColumns;
-}
-
-void CSVFile::set_separator(char sep){
-    this->separator = sep;
-    return;
-}
-
-char CSVFile::get_separator(){
-    return this->separator;
-}
-
-CSVRow CSVFile::get_headers(){
-    if(headersRow > 0){
-        return this->rows[headersRow-1];
-    }else{
-        CSVRow dummy;
-        while (dummy.size() < NumberOfColumns())
-            dummy.addCell("");
-        return dummy;
-    }
-}
-
-CSVRow CSVFile::get_row(unsigned i){
-    return this->rows[i];
-}
diff --git a/GUI/coregui/Views/ImportDataWidgets/CsvReader.h b/GUI/coregui/Views/ImportDataWidgets/CsvReader.h
deleted file mode 100644
index 1fb2b45ee241d8ce482ff851be19c7fc1fc7ba3a..0000000000000000000000000000000000000000
--- a/GUI/coregui/Views/ImportDataWidgets/CsvReader.h
+++ /dev/null
@@ -1,112 +0,0 @@
-#ifndef CSVREADER_H
-#define CSVREADER_H
-
-#include <iterator>
-#include <iostream>
-#include <fstream>
-#include <sstream>
-#include <vector>
-#include <algorithm>
-
-class CSVRow
-{
-    public:
-        std::string const& operator[](unsigned index) const;
-
-        unsigned long size() const;
-
-        void readNextRow(std::istream& str);
-
-
-        void setSeparator(char sep);
-
-        char getSeparator();
-
-        void addCell(std::string str);
-
-        std::vector<std::string> dataVector(){return m_data;}
-
-    private:
-        std::vector<std::string>    m_data;
-        char separator = '-';
-};
-
-inline std::istream& operator>>(std::istream& str, CSVRow& data)
-{
-    data.readNextRow(str);
-    return str;
-}
-
-class CSVIterator
-{
-    public:
-        typedef std::input_iterator_tag     iterator_category;
-        typedef CSVRow                      value_type;
-        typedef unsigned long                difference_type;
-        typedef CSVRow*                     pointer;
-        typedef CSVRow&                     reference;
-
-        CSVIterator(std::istream& str, char sep)  :m_str( str.good() ? &str : nullptr ) {m_sep=sep; ++(*this); }
-        CSVIterator()                   :m_str(nullptr) {}
-
-        // Pre Increment
-        CSVIterator& operator++()               {if (m_str) { m_row.setSeparator(m_sep); if (!((*m_str) >> m_row)){m_str = nullptr;}}return *this;}
-        // Post increment
-        CSVIterator operator++(int)             {CSVIterator    tmp(*this);++(*this);return tmp;}
-        CSVRow const& operator*()   const       {return m_row;}
-        CSVRow const* operator->()  const       {return &m_row;}
-
-        bool operator==(CSVIterator const& rhs) {return ((this == &rhs) || ((this->m_str == nullptr) && (rhs.m_str == nullptr)));}
-        bool operator!=(CSVIterator const& rhs) {return !((*this) == rhs);}
-
-
-
-    private:
-        std::istream*       m_str;
-        CSVRow              m_row;
-        char                m_sep;
-};
-
-class CSVFile
-{
-    public:
-        CSVFile(std::string path_to_file): filepath(path_to_file) {Init();}
-        CSVFile(std::string path_to_file, char sep): filepath(path_to_file), separator(sep) {Init();}
-        CSVFile(std::string path_to_file, char sep, unsigned headRow): filepath(path_to_file), separator(sep), headersRow(headRow) {Init();}
-
-
-        void Init();
-
-        void Read();
-
-
-        void EqualizeRowLengths();
-
-
-        std::vector<std::string> const operator[](unsigned index_i) const;
-
-        unsigned long NumberOfRows() const;
-
-        unsigned long NumberOfColumns() const;
-
-        void set_separator(char sep);
-
-        char get_separator();
-
-        CSVRow get_headers();
-
-        CSVRow get_row(unsigned i);
-
-        std::vector<std::vector<std::string>> asArray(){return m_data;}
-
-    private:
-        std::string filepath;
-        char separator = '-';
-        unsigned headersRow = 0;
-        unsigned numberOfColumns = 0;
-        std::vector<CSVRow>    rows;
-        std::vector<std::vector<std::string>>    m_data;
-
-};
-
-#endif // CSVREADER_H
diff --git a/GUI/coregui/Views/ImportDataWidgets/ImportDataUtils.cpp b/GUI/coregui/Views/ImportDataWidgets/ImportDataUtils.cpp
index 7ee22166b9217f82c9f95da9cb8a145bdeebb84f..8a2afc483f826c7ea3d2cfd367665d851a286f97 100644
--- a/GUI/coregui/Views/ImportDataWidgets/ImportDataUtils.cpp
+++ b/GUI/coregui/Views/ImportDataWidgets/ImportDataUtils.cpp
@@ -21,6 +21,7 @@
 #include "IntensityDataIOFactory.h"
 #include "IntensityDataItem.h"
 #include "RealDataItem.h"
+#include "CsvImportAssistant.h"
 #include "projectmanager.h"
 #include <QFileDialog>
 #include <QFileInfo>
@@ -28,8 +29,10 @@
 
 namespace
 {
-const QString filter_string = "Intensity File (*.int *.gz *.tif *.tiff *.txt);;"
-                              "Other (*)";
+const QString filter_string_ba = "Intensity File (*.int *.gz *.tif *.tiff *.txt *.csv);;"
+                              "Other (*.*)";
+const QString filter_string_ascii = "Intensity File (*.int *.int.gz *.txt *.csv *.dat *.ascii);;"
+                              "Ascii column-wise data (*.*)";
 
 int getRank(const RealDataItem& item)
 {
@@ -41,38 +44,98 @@ int getRank(const InstrumentItem& item) {
 }
 }
 
-std::unique_ptr<OutputData<double>> ImportDataUtils::ImportData(QString& baseNameOfLoadedFile)
+std::unique_ptr<OutputData<double>> ImportDataUtils::ImportKnownData(QString& fileName){
+    //Try to use the canonical tools for importing data
+    std::unique_ptr<OutputData<double>> result;
+    try {
+        std::unique_ptr<OutputData<double>> data(
+                    IntensityDataIOFactory::readOutputData(fileName.toStdString()));
+        result = CreateSimplifiedOutputData(*data);
+    } catch(std::exception& ex)
+    {
+        QString message = QString("Error while trying to read file\n\n'%1'\n\n%2")
+                .arg(fileName)
+                .arg(QString::fromStdString(std::string(ex.what())));
+        QMessageBox::warning(nullptr, "IO Problem", message);
+    }
+    return result;
+
+}
+
+std::unique_ptr<OutputData<double>> ImportDataUtils::Import2dData(QString& baseNameOfLoadedFile)
 {
     QString dirname = AppSvc::projectManager()->userImportDir();
-    QString fileName = QFileDialog::getOpenFileName(0, QStringLiteral("Open Intensity File"),
-                                                    dirname, filter_string);
+    QString fileName = QFileDialog::getOpenFileName(Q_NULLPTR, QStringLiteral("Open Intensity File"),
+                                                    dirname, filter_string_ba);
 
     if (fileName.isEmpty())
         return nullptr;
 
+
+    QString newImportDir = GUIHelpers::fileDir(fileName);
+    if (newImportDir != dirname)
+        AppSvc::projectManager()->setImportDir(newImportDir);
+
     QFileInfo info(fileName);
     baseNameOfLoadedFile = info.baseName();
 
+    return ImportKnownData(fileName);
+
+}
+
+ImportDataInfo ImportDataUtils::Import1dData(QString& baseNameOfLoadedFile)
+{
+    QString dirname = AppSvc::projectManager()->userImportDir();
+    QString fileName = QFileDialog::getOpenFileName(nullptr, QStringLiteral("Open Intensity File"),
+                                                    dirname, filter_string_ascii);
+
+    if (fileName.isEmpty())
+        return ImportDataInfo();
+
     QString newImportDir = GUIHelpers::fileDir(fileName);
     if (newImportDir != dirname)
         AppSvc::projectManager()->setImportDir(newImportDir);
 
-    std::unique_ptr<OutputData<double>> result;
+    QFileInfo info(fileName);
+    baseNameOfLoadedFile = info.baseName();
 
-    try {
-        std::unique_ptr<OutputData<double>> data(
-            IntensityDataIOFactory::readOutputData(fileName.toStdString()));
-        result = CreateSimplifiedOutputData(*data.get());
-    } catch (std::exception& ex) {
-        QString message = QString("Error while trying to read file\n\n'%1'\n\n%2")
-                              .arg(fileName)
-                              .arg(QString::fromStdString(std::string(ex.what())));
-        QMessageBox::warning(0, "IO Problem", message);
+    if(DataFormatUtils::isCompressed(fileName.toStdString()) ||
+                    DataFormatUtils::isIntFile(fileName.toStdString()) ||
+                    DataFormatUtils::isTiffFile(fileName.toStdString())
+                    ){
+        try{
+            return ImportDataInfo(ImportKnownData(fileName), AxesUnits::NBINS);
+        }
+        catch(...){
+            return getFromImportAssistant(fileName);
+        }
     }
+    return getFromImportAssistant(fileName);
+}
 
-    return result;
+
+
+ImportDataInfo ImportDataUtils::getFromImportAssistant(QString& fileName){
+    if(!csv::isAscii(fileName)){
+        QString message = QString("There was a problem while trying to import data from file:\n\n'%1'\n--\n%2\n--\n")
+                        .arg(fileName)
+                        .arg("The file seems to contain binary data");
+        QMessageBox::warning(nullptr, "Unable to read.", message);
+        return ImportDataInfo();
+    }
+    try{
+        CsvImportAssistant assistant(fileName,true);
+        return assistant.getData();
+    }catch(std::exception& e){
+        QString message = QString("There was a problem while trying to import data from file:\n\n'%1'\n--\n%2\n--\n")
+                        .arg(fileName)
+                        .arg(QString::fromStdString(std::string(e.what())));
+        QMessageBox::warning(nullptr, "IO Problem", message);
+    }
+    return ImportDataInfo();
 }
 
+
 bool ImportDataUtils::Compatible(const InstrumentItem& instrumentItem,
                                  const RealDataItem& realDataItem)
 {
diff --git a/GUI/coregui/Views/ImportDataWidgets/ImportDataUtils.h b/GUI/coregui/Views/ImportDataWidgets/ImportDataUtils.h
index 489a8622006d6f8dc15dba0052e08253080fe890..88e4a8add2bc6991fb6fb652b649c2c268f91842 100644
--- a/GUI/coregui/Views/ImportDataWidgets/ImportDataUtils.h
+++ b/GUI/coregui/Views/ImportDataWidgets/ImportDataUtils.h
@@ -16,6 +16,7 @@
 #define IMPORTDATAUTILS_H
 
 #include "WinDllMacros.h"
+#include "ImportDataInfo.h"
 #include <QString>
 #include <memory>
 #include <vector>
@@ -29,8 +30,11 @@ class GISASInstrumentItem;
 
 namespace ImportDataUtils
 {
+BA_CORE_API_ std::unique_ptr<OutputData<double>> Import2dData(QString& baseNameOfLoadedFile);
+BA_CORE_API_ ImportDataInfo Import1dData(QString& baseNameOfLoadedFile);
+BA_CORE_API_ std::unique_ptr<OutputData<double>> ImportKnownData(QString& baseNameOfLoadedFile);
+BA_CORE_API_ ImportDataInfo getFromImportAssistant(QString& fileName);
 
-BA_CORE_API_ std::unique_ptr<OutputData<double>> ImportData(QString& baseNameOfLoadedFile);
 
 //! Creates OutputData with bin-valued axes.
 BA_CORE_API_ std::unique_ptr<OutputData<double>>
diff --git a/GUI/coregui/Views/ImportDataWidgets/LinkInstrumentManager.cpp b/GUI/coregui/Views/ImportDataWidgets/LinkInstrumentManager.cpp
index 778d4c5dbd77c9eaa4f418df33df93d703014fe7..9bbbfe81074d2d1daf9f55b3d7bf44030ad54a83 100644
--- a/GUI/coregui/Views/ImportDataWidgets/LinkInstrumentManager.cpp
+++ b/GUI/coregui/Views/ImportDataWidgets/LinkInstrumentManager.cpp
@@ -107,20 +107,21 @@ bool LinkInstrumentManager::canLinkDataToInstrument(const RealDataItem* realData
 
     if (!ImportDataUtils::Compatible(*instrumentItem, *realDataItem)) {
         QMessageBox::warning(nullptr, "Can't link to instrument",
-                             "Can't link, data is uncompatible with the instrument.");
-
+                             "Can't link, data is incompatible with the instrument.");
         return false;
     }
 
-    if (instrumentItem->shape() == realDataItem->shape())
+    if (instrumentItem->alignedWith(realDataItem))
         return true;
 
-    QString message
-        = ImportDataUtils::printShapeMessage(instrumentItem->shape(), realDataItem->shape());
+    QString message =
+        realDataItem->holdsDimensionalData()
+            ? "Experimental data carries information on the range/points of measurement."
+            : ImportDataUtils::printShapeMessage(instrumentItem->shape(), realDataItem->shape());
     if (!QuestionOnInstrumentReshaping(message))
         return false;
 
-    instrumentItem->setShape(realDataItem->shape());
+    instrumentItem->updateToRealData(realDataItem);
     return true;
 }
 
@@ -154,11 +155,7 @@ void LinkInstrumentManager::onInstrumentChildChange(InstrumentItem* instrument,
     if (child == nullptr)
         return;
 
-    if (child->itemName() == BasicAxisItem::P_NBINS
-        || child->parent()->modelType() == Constants::GroupItemType)
-        onInstrumentBinningChange(instrument);
-    else
-        onInstrumentLayoutChange(instrument);
+    onInstrumentLayoutChange(instrument);
 }
 
 //! Updates map of instruments on insert/remove InstrumentItem event.
@@ -247,22 +244,16 @@ void LinkInstrumentManager::updateRealDataMap()
     }
 }
 
-//! Runs through all RealDataItem and break the link, if instrument binning doesn't match the data.
-
-void LinkInstrumentManager::onInstrumentBinningChange(InstrumentItem* changedInstrument)
-{
-    for(auto realDataItem : linkedItems(changedInstrument))
-        if (changedInstrument->shape() != realDataItem->shape())
-            realDataItem->setItemValue(RealDataItem::P_INSTRUMENT_ID, QString());
-}
-
 //! Runs through all RealDataItem and refresh linking to match possible change in detector
 //! axes definition.
 
 void LinkInstrumentManager::onInstrumentLayoutChange(InstrumentItem* changedInstrument)
 {
     for (auto realDataItem : linkedItems(changedInstrument))
-        realDataItem->linkToInstrument(changedInstrument);
+        if (!changedInstrument->alignedWith(realDataItem))
+            realDataItem->setItemValue(RealDataItem::P_INSTRUMENT_ID, QString());
+        else
+            realDataItem->linkToInstrument(changedInstrument);
 }
 
 //! Returns list of RealDataItem's linked to given instrument.
@@ -328,12 +319,12 @@ namespace {
 bool QuestionOnInstrumentReshaping(const QString& message)
 {
     QMessageBox msgBox;
-    msgBox.setText("The shape of data and instrument differs.");
+    msgBox.setText("Instrument description conflicts with the experimental data.");
 
     QString informative;
     informative.append(message);
     informative.append(
-        "\n\nDo you want to modify instrument so it matches shape of real data?\n\n");
+        "\n\nDo you want to adjust the instrument to the experimental data?\n\n");
     msgBox.setInformativeText(informative);
 
     QPushButton* modifyInstrumentButton
diff --git a/GUI/coregui/Views/ImportDataWidgets/LinkInstrumentManager.h b/GUI/coregui/Views/ImportDataWidgets/LinkInstrumentManager.h
index 1a5f5c5369c5e751a4cb2ad8a2c857b3efde3f9e..0ab1b5ef36416e4f7f95257b433fb5f80fb691a6 100644
--- a/GUI/coregui/Views/ImportDataWidgets/LinkInstrumentManager.h
+++ b/GUI/coregui/Views/ImportDataWidgets/LinkInstrumentManager.h
@@ -46,7 +46,7 @@ public:
         InstrumentItem* m_instrument;
     };
 
-    explicit LinkInstrumentManager(QObject* parent = 0);
+    explicit LinkInstrumentManager(QObject* parent = nullptr);
 
     void setModels(InstrumentModel* instrumentModel, RealDataModel* realDataModel);
 
@@ -71,7 +71,6 @@ private slots:
     void updateLinks();
     void updateInstrumentMap();
     void updateRealDataMap();
-    void onInstrumentBinningChange(InstrumentItem* changedInstrument);
     void onInstrumentLayoutChange(InstrumentItem* changedInstrument);
 
 private:
diff --git a/GUI/coregui/Views/ImportDataWidgets/RealDataSelectorActions.cpp b/GUI/coregui/Views/ImportDataWidgets/RealDataSelectorActions.cpp
index 2de755d85bf7e51c7206270420ae6c24a39c31d5..f1d22f7dd4a12f28c88a75fdbf68dddf137a8d6c 100644
--- a/GUI/coregui/Views/ImportDataWidgets/RealDataSelectorActions.cpp
+++ b/GUI/coregui/Views/ImportDataWidgets/RealDataSelectorActions.cpp
@@ -14,6 +14,7 @@
 
 #include "RealDataSelectorActions.h"
 #include "GUIHelpers.h"
+#include "ImportDataInfo.h"
 #include "ImportDataUtils.h"
 #include "IntensityDataFunctions.h"
 #include "IntensityDataItem.h"
@@ -75,17 +76,24 @@ void resetSetup(IntensityDataItem& intensityItem) {
 
 RealDataSelectorActions::RealDataSelectorActions(QObject* parent)
     : QObject(parent)
-    , m_importDataAction(nullptr)
+    , m_import2dDataAction(nullptr)
+    , m_import1dDataAction(nullptr)
     , m_removeDataAction(nullptr)
     , m_rotateDataAction(new QAction(this))
     , m_realDataModel(nullptr)
     , m_selectionModel(nullptr)
 {
-    m_importDataAction = new QAction(QStringLiteral("Import data"), parent);
-    m_importDataAction->setIcon(QIcon(":/images/toolbar16dark_newitem.svg"));
-    m_importDataAction->setToolTip(QStringLiteral("Import data"));
-    connect(m_importDataAction, &QAction::triggered,
-            this, &RealDataSelectorActions::onImportDataAction);
+    m_import2dDataAction = new QAction(QStringLiteral("Import 2D data"), parent);
+    m_import2dDataAction->setIcon(QIcon(":/images/toolbar16dark_newitem.svg"));
+    m_import2dDataAction->setToolTip(QStringLiteral("Import 2D data"));
+    connect(m_import2dDataAction, &QAction::triggered,
+            this, &RealDataSelectorActions::onImport2dDataAction);
+
+    m_import1dDataAction = new QAction(QStringLiteral("Import 1D data"), parent);
+    m_import1dDataAction->setIcon(QIcon(":/images/toolbar16dark_newitem.svg"));
+    m_import1dDataAction->setToolTip(QStringLiteral("Import 1D data"));
+    connect(m_import1dDataAction, &QAction::triggered,
+            this, &RealDataSelectorActions::onImport1dDataAction);
 
     m_removeDataAction = new QAction(QStringLiteral("Remove this data"), parent);
     m_removeDataAction->setIcon(QIcon(":/images/toolbar16dark_recycle.svg"));
@@ -111,13 +119,13 @@ void RealDataSelectorActions::setSelectionModel(QItemSelectionModel* selectionMo
 
 }
 
-void RealDataSelectorActions::onImportDataAction()
+void RealDataSelectorActions::onImport2dDataAction()
 {
     Q_ASSERT(m_realDataModel);
     Q_ASSERT(m_selectionModel);
     QString baseNameOfImportedFile;
 
-    std::unique_ptr<OutputData<double>> data = ImportDataUtils::ImportData(baseNameOfImportedFile);
+    std::unique_ptr<OutputData<double>> data = ImportDataUtils::Import2dData(baseNameOfImportedFile);
     if (data) {
         RealDataItem* realDataItem
             = dynamic_cast<RealDataItem*>(m_realDataModel->insertNewItem(Constants::RealDataType));
@@ -128,6 +136,23 @@ void RealDataSelectorActions::onImportDataAction()
     }
 }
 
+void RealDataSelectorActions::onImport1dDataAction()
+{
+    Q_ASSERT(m_realDataModel);
+    Q_ASSERT(m_selectionModel);
+    QString baseNameOfImportedFile;
+
+    auto data = ImportDataUtils::Import1dData(baseNameOfImportedFile);
+    if (data) {
+        RealDataItem* realDataItem
+            = dynamic_cast<RealDataItem*>(m_realDataModel->insertNewItem(Constants::RealDataType));
+        realDataItem->setItemName(baseNameOfImportedFile);
+        realDataItem->setImportData(std::move(data));
+        m_selectionModel->clearSelection();
+        m_selectionModel->select(realDataItem->index(), QItemSelectionModel::Select);
+    }
+}
+
 void RealDataSelectorActions::onRemoveDataAction()
 {
     QModelIndex currentIndex = m_selectionModel->currentIndex();
@@ -174,18 +199,21 @@ void RealDataSelectorActions::onContextMenuRequest(const QPoint& point,
 
     setAllActionsEnabled(indexAtPoint.isValid());
 
-    m_importDataAction->setEnabled(true);
+    m_import2dDataAction->setEnabled(true);
+    m_import1dDataAction->setEnabled(true);
 
     menu.addAction(m_removeDataAction);
     menu.addAction(m_rotateDataAction);
     menu.addSeparator();
-    menu.addAction(m_importDataAction);
+    menu.addAction(m_import2dDataAction);
+    menu.addAction(m_import1dDataAction);
     menu.exec(point);
 }
 
 void RealDataSelectorActions::setAllActionsEnabled(bool value)
 {
-    m_importDataAction->setEnabled(value);
+    m_import2dDataAction->setEnabled(value);
+    m_import1dDataAction->setEnabled(value);
     m_rotateDataAction->setEnabled(value);
     m_removeDataAction->setEnabled(value);
 }
diff --git a/GUI/coregui/Views/ImportDataWidgets/RealDataSelectorActions.h b/GUI/coregui/Views/ImportDataWidgets/RealDataSelectorActions.h
index 1dc3e6b6f02179ebb5547576b4fa4b8013b8e7ce..0439e0cc92de9d89c36add9934506f824afa6664 100644
--- a/GUI/coregui/Views/ImportDataWidgets/RealDataSelectorActions.h
+++ b/GUI/coregui/Views/ImportDataWidgets/RealDataSelectorActions.h
@@ -34,7 +34,8 @@ public:
     void setSelectionModel(QItemSelectionModel* selectionModel);
 
 public slots:
-    void onImportDataAction();
+    void onImport1dDataAction();
+    void onImport2dDataAction();
     void onRemoveDataAction();
     void onRotateDataRequest();
     void onContextMenuRequest(const QPoint &point, const QModelIndex &indexAtPoint);
@@ -43,7 +44,8 @@ private:
     void setAllActionsEnabled(bool value);
     void updateSelection();
 
-    QAction* m_importDataAction;
+    QAction* m_import2dDataAction;
+    QAction* m_import1dDataAction;
     QAction* m_removeDataAction;
     QAction* m_rotateDataAction;
     RealDataModel* m_realDataModel;
diff --git a/GUI/coregui/Views/ImportDataWidgets/RealDataSelectorToolBar.cpp b/GUI/coregui/Views/ImportDataWidgets/RealDataSelectorToolBar.cpp
index 463eb54a86e5b149974c58d18fff9fb7dde04dc9..d34c27b5cdfbdbf7d1dabf6a11a59a76b7df9be7 100644
--- a/GUI/coregui/Views/ImportDataWidgets/RealDataSelectorToolBar.cpp
+++ b/GUI/coregui/Views/ImportDataWidgets/RealDataSelectorToolBar.cpp
@@ -18,16 +18,23 @@
 
 RealDataSelectorToolBar::RealDataSelectorToolBar(RealDataSelectorActions* actions, QWidget* parent)
     : StyledToolBar(parent)
-    , m_importDataButton(new QToolButton)
+    , m_import2dDataButton(new QToolButton)
+    , m_import1dDataButton(new QToolButton)
     , m_removeDataButton(new QToolButton)
 {
     setMinimumSize(minimumHeight(), minimumHeight());
 
-    m_importDataButton->setText(QStringLiteral("Import"));
-    m_importDataButton->setIcon(QIcon(":/images/toolbar16light_newitem.svg"));
-    m_importDataButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
-    m_importDataButton->setToolTip("Import data");
-    addWidget(m_importDataButton);
+    m_import2dDataButton->setText(QStringLiteral("Import 2D"));
+    m_import2dDataButton->setIcon(QIcon(":/images/toolbar16light_newitem.svg"));
+    m_import2dDataButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+    m_import2dDataButton->setToolTip("Automatic import of 2D data formats.");
+    addWidget(m_import2dDataButton);
+
+    m_import1dDataButton->setText(QStringLiteral("Import 1D"));
+    m_import1dDataButton->setIcon(QIcon(":/images/toolbar16light_newitem.svg"));
+    m_import1dDataButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+    m_import1dDataButton->setToolTip("Import columnwise ascii files.");
+    addWidget(m_import1dDataButton);
 
     m_removeDataButton->setText("Remove");
     m_removeDataButton->setIcon(QIcon(":/images/toolbar16light_recycle.svg"));
@@ -35,8 +42,10 @@ RealDataSelectorToolBar::RealDataSelectorToolBar(RealDataSelectorActions* action
     m_removeDataButton->setToolTip("Remove selected data.");
     addWidget(m_removeDataButton);
 
-    connect(m_importDataButton, &QToolButton::clicked, actions,
-            &RealDataSelectorActions::onImportDataAction);
+    connect(m_import2dDataButton, &QToolButton::clicked, actions,
+            &RealDataSelectorActions::onImport2dDataAction);
+    connect(m_import1dDataButton, &QToolButton::clicked, actions,
+            &RealDataSelectorActions::onImport1dDataAction);
     connect(m_removeDataButton, &QToolButton::clicked, actions,
             &RealDataSelectorActions::onRemoveDataAction);
 }
diff --git a/GUI/coregui/Views/ImportDataWidgets/RealDataSelectorToolBar.h b/GUI/coregui/Views/ImportDataWidgets/RealDataSelectorToolBar.h
index 3222844a5e174096e926a1dfa371baf33f56bf22..1c202e322fbca346d886310979d62d739b4f8b45 100644
--- a/GUI/coregui/Views/ImportDataWidgets/RealDataSelectorToolBar.h
+++ b/GUI/coregui/Views/ImportDataWidgets/RealDataSelectorToolBar.h
@@ -27,10 +27,11 @@ class BA_CORE_API_ RealDataSelectorToolBar : public StyledToolBar
 {
     Q_OBJECT
 public:
-    RealDataSelectorToolBar(RealDataSelectorActions* actions, QWidget* parent = 0);
+    RealDataSelectorToolBar(RealDataSelectorActions* actions, QWidget* parent = nullptr);
 
 private:
-    QToolButton* m_importDataButton;
+    QToolButton* m_import2dDataButton;
+    QToolButton* m_import1dDataButton;
     QToolButton* m_removeDataButton;
 };
 
diff --git a/GUI/coregui/Views/InfoWidgets/DistributionWidget.cpp b/GUI/coregui/Views/InfoWidgets/DistributionWidget.cpp
index e171b89ebe17e9c9c958d5927e392641b85b16fe..07416e34f4fa7c5456f76afd4adf3598177c6024 100644
--- a/GUI/coregui/Views/InfoWidgets/DistributionWidget.cpp
+++ b/GUI/coregui/Views/InfoWidgets/DistributionWidget.cpp
@@ -188,7 +188,7 @@ void DistributionWidget::plot_single_value()
 {
     Q_ASSERT(m_item->displayName() == Constants::DistributionNoneType);
 
-    double value = m_item->getItemValue(DistributionNoneItem::P_VALUE).toDouble();
+    double value = m_item->getItemValue(DistributionNoneItem::P_MEAN).toDouble();
 
     QVector<double> xPos = QVector<double>() << value;
     QVector<double> yPos = QVector<double>() << 1.0;
diff --git a/GUI/coregui/Views/InfoWidgets/InfoToolBar.cpp b/GUI/coregui/Views/InfoWidgets/InfoToolBar.cpp
deleted file mode 100644
index 3854c3f2b5ca595f4e621a503d579a94933b45e0..0000000000000000000000000000000000000000
--- a/GUI/coregui/Views/InfoWidgets/InfoToolBar.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      GUI/coregui/Views/InfoWidgets/InfoToolBar.cpp
-//! @brief     Implements class InfoToolBar
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "InfoToolBar.h"
-#include <QHBoxLayout>
-#include <QToolButton>
-
-InfoToolBar::InfoToolBar(QWidget *parent)
-    : StyledToolBar(parent)
-    , m_expandButton(new QToolButton)
-    , m_closeButton(new QToolButton)
-    , m_expanded(false)
-{
-    setMinimumSize(25, 25);
-
-    m_expandButton->setIcon(QIcon(":/images/darkarrowup.png"));
-    m_expandButton->setToolTip("Collapse/expand view");
-    connect(m_expandButton, SIGNAL(clicked()), this, SLOT(onExpandButtonClicked()));
-
-    m_closeButton->setIcon(QIcon(":/images/darkclosebutton.png"));
-    m_closeButton->setToolTip("Close viewer");
-    connect(m_closeButton, SIGNAL(clicked()), this, SIGNAL(closeButtonClicked()));
-
-    QWidget* empty = new QWidget();
-    empty->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
-    addWidget(empty);
-
-    addWidget(m_expandButton);
-    addWidget(m_closeButton);
-
-    setStyleSheet("QToolBar {border-bottom: 1px solid gray}");
-}
-
-void InfoToolBar::setExpandStatus(bool status)
-{
-    m_expanded = status;
-    if(m_expanded) {
-        m_expandButton->setIcon(QIcon(":/images/darkarrowdown.png"));
-    } else {
-        m_expandButton->setIcon(QIcon(":/images/darkarrowup.png"));
-    }
-}
-
-void InfoToolBar::onExpandButtonClicked()
-{
-    m_expanded = !m_expanded;
-    setExpandStatus(m_expanded);
-    emit expandButtonClicked();
-}
-
diff --git a/GUI/coregui/Views/InfoWidgets/InfoToolBar.h b/GUI/coregui/Views/InfoWidgets/InfoToolBar.h
deleted file mode 100644
index 5cd3ecbf656d0e75d4b53f9a2b2a91e1c282f63b..0000000000000000000000000000000000000000
--- a/GUI/coregui/Views/InfoWidgets/InfoToolBar.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      GUI/coregui/Views/InfoWidgets/InfoToolBar.h
-//! @brief     Defines class InfoToolBar
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef INFOTOOLBAR_H
-#define INFOTOOLBAR_H
-
-#include "StyledToolBar.h"
-
-class QToolButton;
-
-//! The InfoToolBar class represents a toolbar for InfoWidget
-
-class BA_CORE_API_ InfoToolBar : public StyledToolBar
-{
-    Q_OBJECT
-
-public:
-    explicit InfoToolBar(QWidget *parent = 0);
-
-signals:
-    void expandButtonClicked();
-    void closeButtonClicked();
-
-public slots:
-    void setExpandStatus(bool status);
-
-protected slots:
-    void onExpandButtonClicked();
-
-private:
-    QToolButton *m_expandButton;
-    QToolButton *m_closeButton;
-    bool m_expanded;
-};
-
-#endif // INFOTOOLBAR_H
diff --git a/GUI/coregui/Views/InfoWidgets/InfoWidget.cpp b/GUI/coregui/Views/InfoWidgets/InfoWidget.cpp
deleted file mode 100644
index 28a7b745cb935d9b09ed3a0fdce5fef6f5687845..0000000000000000000000000000000000000000
--- a/GUI/coregui/Views/InfoWidgets/InfoWidget.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      GUI/coregui/Views/InfoWidgets/InfoWidget.cpp
-//! @brief     Implements class InfoWidget
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "InfoWidget.h"
-#include "InfoToolBar.h"
-#include "PySampleWidget.h"
-#include <QResizeEvent>
-#include <QVBoxLayout>
-
-namespace {
-const int minimum_widget_height = 25; // height of toolbar
-const int minimum_height_before_collapse = 40;
-}
-
-InfoWidget::InfoWidget(QWidget *parent)
-    : QWidget(parent)
-    , m_infoToolBar(new InfoToolBar(this))
-    , m_pySampleWidget(new PySampleWidget(this))
-    , m_placeHolder(new QWidget(this))
-    , m_cached_height(200)
-{
-    setWindowTitle("Python Script Viewer");
-    setObjectName("PythonScriptViewer");
-
-    QVBoxLayout *mainLayout = new QVBoxLayout;
-    mainLayout->addWidget(m_infoToolBar);
-    mainLayout->addWidget(m_placeHolder);
-    mainLayout->addWidget(m_pySampleWidget);
-
-    m_placeHolder->show();
-    m_pySampleWidget->hide();
-
-    mainLayout->setContentsMargins(0, 0, 0, 0);
-    mainLayout->setMargin(0);
-    mainLayout->setSpacing(0);
-
-    setLayout(mainLayout);
-
-    connect(m_infoToolBar, SIGNAL(expandButtonClicked()), this, SLOT(onExpandButtonClicked()));
-    connect(m_infoToolBar, SIGNAL(closeButtonClicked()), this, SIGNAL(widgetCloseRequest()));
-
-}
-
-void InfoWidget::setSampleModel(SampleModel *sampleModel)
-{
-    Q_ASSERT(m_pySampleWidget);
-    m_pySampleWidget->setSampleModel(sampleModel);
-}
-
-void InfoWidget::setInstrumentModel(InstrumentModel *instrumentModel)
-{
-    Q_ASSERT(m_pySampleWidget);
-    m_pySampleWidget->setInstrumentModel(instrumentModel);
-}
-
-QSize InfoWidget::sizeHint() const
-{
-    QSize result = m_infoToolBar->sizeHint();
-    if(m_pySampleWidget->isHidden()) {
-        result.setHeight(m_infoToolBar->height() );
-    } else {
-        result.setHeight(m_pySampleWidget->height() + m_infoToolBar->height() );
-    }
-    return result;
-}
-
-QSize InfoWidget::minimumSizeHint() const
-{
-    return QSize(minimum_widget_height, minimum_widget_height);
-}
-
-void InfoWidget::onDockVisibilityChange(bool is_visible)
-{
-    Q_ASSERT(m_pySampleWidget);
-    if(isEditorVisible()) {
-        if(!is_visible)
-            m_pySampleWidget->setEditorConnected(false);
-        else
-            m_pySampleWidget->setEditorConnected(true);
-    }
-}
-
-void InfoWidget::onExpandButtonClicked()
-{
-    setEditorVisible(!isEditorVisible(), true);
-}
-
-//! sets the editor to be visible or not.
-//! @param dock_notify is used to inform parent QDockWidget about necessary adjustments
-//! in its own height
-void InfoWidget::setEditorVisible(bool editor_status, bool dock_notify)
-{
-    m_infoToolBar->setExpandStatus(editor_status);
-    if(editor_status) {
-        if(m_cached_height) {
-            if(dock_notify) emit widgetHeightRequest(m_cached_height);
-        }
-        m_placeHolder->hide();
-        m_pySampleWidget->show();
-        m_pySampleWidget->setEditorConnected(true);
-    } else {
-        m_cached_height = height();
-        m_pySampleWidget->hide();
-        m_pySampleWidget->setEditorConnected(false);
-        m_placeHolder->show();
-        if(dock_notify) emit widgetHeightRequest(minimum_widget_height);
-    }
-}
-
-//! Method watches over the height of the widget (which is triggered from outside, i.e. from
-//! DockWindow splitter) and if height becomes too small, disables python editor.
-//! Similarly, if widget is growing in height, the editor will be enabled back again
-void InfoWidget::resizeEvent(QResizeEvent *event)
-{
-    // widget is schrinking in height
-    if(event->oldSize().height() > event->size().height()) {
-        if(event->size().height() <= minimum_height_before_collapse && isEditorVisible()) {
-            setEditorVisible(false);
-        }
-    }
-
-    // widget is growing in height
-    if(event->oldSize().height() < event->size().height()) {
-        if(event->size().height() > minimum_height_before_collapse && !isEditorVisible()) {
-            setEditorVisible(true);
-        }
-    }
-
-    QWidget::resizeEvent(event);
-}
-
-bool InfoWidget::isEditorVisible()
-{
-    return m_pySampleWidget->isVisible();
-}
diff --git a/GUI/coregui/Views/InfoWidgets/InfoWidget.h b/GUI/coregui/Views/InfoWidgets/InfoWidget.h
deleted file mode 100644
index 62f246ce53139f6c96cbecbb450d10eaaef6b661..0000000000000000000000000000000000000000
--- a/GUI/coregui/Views/InfoWidgets/InfoWidget.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      GUI/coregui/Views/InfoWidgets/InfoWidget.h
-//! @brief     Defines class InfoWidget
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef INFOWIDGET_H
-#define INFOWIDGET_H
-
-#include "WinDllMacros.h"
-#include <QWidget>
-
-class InfoToolBar;
-class SampleModel;
-class InstrumentModel;
-class PySampleWidget;
-
-//! The InfoWidget resides at the bottom of SampleView and displays a Python script
-class BA_CORE_API_ InfoWidget : public QWidget
-{
-    Q_OBJECT
-
-public:
-    explicit InfoWidget(QWidget *parent = 0);
-
-    void setSampleModel(SampleModel *sampleModel);
-    void setInstrumentModel(InstrumentModel *instrumentModel);
-
-    QSize sizeHint() const;
-    QSize minimumSizeHint() const;
-
-signals:
-    void widgetHeightRequest(int);
-    void widgetCloseRequest();
-
-public slots:
-    void onDockVisibilityChange(bool is_visible);
-
-private slots:
-    void onExpandButtonClicked();
-
-    void setEditorVisible(bool editor_status, bool dock_notify = false);
-
-protected:
-    void resizeEvent(QResizeEvent *);
-    bool isEditorVisible();
-
-private:
-    InfoToolBar *m_infoToolBar;
-    PySampleWidget *m_pySampleWidget;
-    QWidget *m_placeHolder;
-    int m_cached_height;
-};
-
-#endif // INFOWIDGET_H
diff --git a/GUI/coregui/Views/InfoWidgets/PySampleWidget.cpp b/GUI/coregui/Views/InfoWidgets/PySampleWidget.cpp
index d083af21877061669db562d69f4ae43955242b1c..02a165efd59d76e5023a2923bcefdf1441aa3217 100644
--- a/GUI/coregui/Views/InfoWidgets/PySampleWidget.cpp
+++ b/GUI/coregui/Views/InfoWidgets/PySampleWidget.cpp
@@ -15,72 +15,45 @@
 #include "PySampleWidget.h"
 #include "DesignerHelper.h"
 #include "DomainObjectBuilder.h"
-#include "MultiLayer.h"
 #include "ExportToPython.h"
+#include "MultiLayer.h"
+#include "MultiLayerItem.h"
 #include "PythonSyntaxHighlighter.h"
 #include "SampleModel.h"
-#include "WarningSign.h"
 #include "UpdateTimer.h"
-#include "MultiLayerItem.h"
+#include "WarningSign.h"
+#include "SessionItemUtils.h"
 #include <QScrollBar>
 #include <QTextEdit>
 #include <QVBoxLayout>
 
-namespace {
+namespace
+{
 const int accumulate_updates_during_msec = 20.;
-
-const QString welcome_message =
-"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">"
-"<html><head><meta name=\"qrichtext\" content=\"1\" /><meta http-equiv=\"Content-Type\" "
-"content=\"text/html; charset=UTF-8\" /><title>QTextEdit Example</title><style type=\"text/css\">"
-"p, li { white-space: pre-wrap; }</style></head><body style=\" font-family:'Helvetica';"
-" font-size:10pt; font-weight:400; font-style:normal;\"><p align=\"center\" style=\""
-" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0;"
-" text-indent:0px;\"><span style=\" font-size:14pt;\">Sample Script View</span></p>"
-"<p align=\"justify\" style=\" margin-top:12px; margin-bottom:12px; margin-left:0px;"
-" margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:10pt;\">"
-"The Sample Script View displays Python code corresponding to the sample being constructed."
-" Start building a multilayer and corresponding code snippet will start appear in this window."
-"</span></p>"
-"<ul type=\"circle\" style=\"margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right:"
-" 0px; -qt-list-indent: 1;\"><li style=\" font-size:10pt;\" align=\"justify\" style=\""
-" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0;"
-" text-indent:0px;\">This is an experimental feature and is provided as tech preview only</li>"
-"<li style=\" font-size:10pt;\" align=\"justify\" style=\" margin-top:12px; margin-bottom:12px;"
-" margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">"
-"Only items which are connected to the multilayer will be translated</li></ul>"
-"<p style=\"-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px;"
-" margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt;\"><br /></p></body></html>";
 }
 
-PySampleWidget::PySampleWidget(QWidget *parent)
-    : QWidget(parent)
-    , m_textEdit(new QTextEdit)
-    , m_sampleModel(0)
-    , m_instrumentModel(0)
-    , m_highlighter(0)
+PySampleWidget::PySampleWidget(QWidget* parent)
+    : QWidget(parent), m_textEdit(new QTextEdit)
+    , m_sampleModel(nullptr), m_instrumentModel(nullptr), m_highlighter(nullptr)
     , m_updateTimer(new UpdateTimer(accumulate_updates_during_msec, this))
     , m_warningSign(new WarningSign(m_textEdit))
 {
     m_textEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
 
-    QVBoxLayout *mainLayout = new QVBoxLayout;
+    auto mainLayout = new QVBoxLayout;
     mainLayout->setContentsMargins(0, 0, 0, 0);
     mainLayout->addWidget(m_textEdit);
 
     setLayout(mainLayout);
 
-    m_textEdit->setHtml(welcomeMessage());
     m_textEdit->setReadOnly(true);
     QFont textFont("Monospace");
     m_textEdit->setFont(textFont);
     m_textEdit->setFontPointSize(DesignerHelper::getPythonEditorFontSize());
-
 }
 
 void PySampleWidget::setSampleModel(SampleModel* sampleModel)
 {
-    Q_ASSERT(sampleModel);
     if (sampleModel != m_sampleModel) {
         if (m_sampleModel)
             setEditorConnected(false);
@@ -90,7 +63,6 @@ void PySampleWidget::setSampleModel(SampleModel* sampleModel)
 
 void PySampleWidget::setInstrumentModel(InstrumentModel* instrumentModel)
 {
-    Q_ASSERT(instrumentModel);
     m_instrumentModel = instrumentModel;
 }
 
@@ -99,9 +71,14 @@ void PySampleWidget::onModifiedRow(const QModelIndex&, int, int)
     m_updateTimer->scheduleUpdate();
 }
 
-void PySampleWidget::onDataChanged(const QModelIndex&, const QModelIndex&)
+void PySampleWidget::onDataChanged(const QModelIndex& index, const QModelIndex&)
 {
-    m_updateTimer->scheduleUpdate();
+    auto item = m_sampleModel->itemForIndex(index);
+    if (!item)
+        return;
+
+    if (!SessionItemUtils::IsPositionRelated(*item))
+        m_updateTimer->scheduleUpdate();
 }
 
 //! Update the editor with the script content
@@ -127,33 +104,45 @@ void PySampleWidget::updateEditor()
 void PySampleWidget::setEditorConnected(bool isConnected)
 {
     if (isConnected) {
-        connect(m_sampleModel, SIGNAL(rowsInserted(QModelIndex, int, int)), this,
-                SLOT(onModifiedRow(QModelIndex, int, int)), Qt::UniqueConnection);
-        connect(m_sampleModel, SIGNAL(rowsRemoved(QModelIndex, int, int)), this,
-                SLOT(onModifiedRow(QModelIndex, int, int)), Qt::UniqueConnection);
-        connect(m_sampleModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this,
-                SLOT(onDataChanged(QModelIndex, QModelIndex)), Qt::UniqueConnection);
-        connect(m_sampleModel, SIGNAL(modelReset()), this, SLOT(updateEditor()),
-                Qt::UniqueConnection);
-
-        connect(m_updateTimer, SIGNAL(timeToUpdate()), this, SLOT(updateEditor()),
-                Qt::UniqueConnection);
+        connect(m_sampleModel, &SampleModel::rowsInserted,
+                this, &PySampleWidget::onModifiedRow, Qt::UniqueConnection);
+        connect(m_sampleModel, &SampleModel::rowsRemoved,
+                this, &PySampleWidget::onModifiedRow, Qt::UniqueConnection);
+        connect(m_sampleModel, &SampleModel::dataChanged,
+                this, &PySampleWidget::onDataChanged, Qt::UniqueConnection);
+        connect(m_sampleModel, &SampleModel::modelReset, this,
+                &PySampleWidget::updateEditor, Qt::UniqueConnection);
+
+        connect(m_updateTimer, &UpdateTimer::timeToUpdate,
+                this, &PySampleWidget::updateEditor, Qt::UniqueConnection);
 
         m_updateTimer->scheduleUpdate();
 
     } else {
-        disconnect(m_sampleModel, SIGNAL(rowsInserted(QModelIndex, int, int)), this,
-                   SLOT(onModifiedRow(QModelIndex, int, int)));
-        disconnect(m_sampleModel, SIGNAL(rowsRemoved(QModelIndex, int, int)), this,
-                   SLOT(onModifiedRow(QModelIndex, int, int)));
-        disconnect(m_sampleModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this,
-                   SLOT(onDataChanged(QModelIndex, QModelIndex)));
-        disconnect(m_sampleModel, SIGNAL(modelReset()), this, SLOT(updateEditor()));
-
-        disconnect(m_updateTimer, SIGNAL(timeToUpdate()), this, SLOT(updateEditor()));
+        disconnect(m_sampleModel, &SampleModel::rowsInserted,
+                   this, &PySampleWidget::onModifiedRow);
+        disconnect(m_sampleModel, &SampleModel::rowsRemoved,
+                   this, &PySampleWidget::onModifiedRow);
+        disconnect(m_sampleModel, &SampleModel::dataChanged,
+                   this, &PySampleWidget::onDataChanged);
+        disconnect(m_sampleModel, &SampleModel::modelReset, this,
+                   &PySampleWidget::updateEditor);
+
+        disconnect(m_updateTimer, &UpdateTimer::timeToUpdate,
+                   this, &PySampleWidget::updateEditor);
     }
 }
 
+void PySampleWidget::showEvent(QShowEvent*)
+{
+    setEditorConnected(isVisible());
+}
+
+void PySampleWidget::hideEvent(QHideEvent*)
+{
+    setEditorConnected(isVisible());
+}
+
 //! generates string representing code snippet for all multi layers in the model
 
 QString PySampleWidget::generateCodeSnippet()
@@ -161,19 +150,17 @@ QString PySampleWidget::generateCodeSnippet()
     m_warningSign->clear();
     QString result;
 
-    for(const MultiLayerItem* sampleItem : m_sampleModel->topItems<MultiLayerItem>()) {
+    for (const MultiLayerItem* sampleItem : m_sampleModel->topItems<MultiLayerItem>()) {
         try {
             auto multilayer = DomainObjectBuilder::buildMultiLayer(*sampleItem);
             if (!result.isEmpty())
                 result.append("\n");
-            result.append(QString::fromStdString(
-                          ExportToPython::generateSampleCode(*multilayer)));
+            result.append(QString::fromStdString(ExportToPython::generateSampleCode(*multilayer)));
         } catch (const std::exception& ex) {
             QString message
                 = QString("Generation of Python Script failed. Code is not complete.\n\n"
                           "It can happen if sample requires further assembling or some of sample "
-                          "parameters "
-                          "are not valid. See details below.\n\n%1")
+                          "parameters are not valid. See details below.\n\n%1")
                       .arg(QString::fromStdString(ex.what()));
 
             m_warningSign->setWarningMessage(message);
@@ -182,18 +169,3 @@ QString PySampleWidget::generateCodeSnippet()
 
     return result;
 }
-
-//! returns welcome message with fonts adjusted to the system
-
-QString PySampleWidget::welcomeMessage()
-{
-    QString result = welcome_message;
-
-    result.replace("font-size:10pt;",
-                   QString("font-size:%1pt;").arg(DesignerHelper::getPythonEditorFontSize()));
-
-    result.replace("font-size:14pt;",
-                   QString("font-size:%1pt;").arg(DesignerHelper::getPythonEditorFontSize() + 2));
-
-    return result;
-}
diff --git a/GUI/coregui/Views/InfoWidgets/PySampleWidget.h b/GUI/coregui/Views/InfoWidgets/PySampleWidget.h
index 4be3c82b4822b724e7b864413dcda7a9cf9541cf..17cd03001b365036594e50ca27b76393150c65c3 100644
--- a/GUI/coregui/Views/InfoWidgets/PySampleWidget.h
+++ b/GUI/coregui/Views/InfoWidgets/PySampleWidget.h
@@ -25,15 +25,17 @@ class QModelIndex;
 class PythonSyntaxHighlighter;
 class UpdateTimer;
 class WarningSign;
+class QShowEvent;
+class QHideEvent;
+
+//! Displays Python script representing a MultiLayer at the bottom of SampleView.
 
-//! The PySampleWidget displays Python script representing a MultiLayer at the bottom of SampleView
-//! Belongs to InfoWidget
 class BA_CORE_API_ PySampleWidget : public QWidget
 {
     Q_OBJECT
 
 public:
-    PySampleWidget(QWidget* parent = 0);
+    PySampleWidget(QWidget* parent = nullptr);
 
     void setSampleModel(SampleModel* sampleModel);
     void setInstrumentModel(InstrumentModel* instrumentModel);
@@ -45,9 +47,12 @@ public slots:
     void updateEditor();
     void setEditorConnected(bool isConnected);
 
+protected:
+    void showEvent(QShowEvent*);
+    void hideEvent(QHideEvent*);
+
 private:
     QString generateCodeSnippet();
-    QString welcomeMessage();
 
     QTextEdit* m_textEdit;
     SampleModel* m_sampleModel;
diff --git a/GUI/coregui/Views/InstrumentWidgets/DepthProbeInstrumentEditor.cpp b/GUI/coregui/Views/InstrumentWidgets/DepthProbeInstrumentEditor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1a6c2d4d199acc54feac3f8f5e8af8b3a152b60d
--- /dev/null
+++ b/GUI/coregui/Views/InstrumentWidgets/DepthProbeInstrumentEditor.cpp
@@ -0,0 +1,93 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/InstrumentWidgets/DepthProbeInstrumentEditor.cpp
+//! @brief     Implements class DepthProbeInstrumentEditor
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "DepthProbeInstrumentEditor.h"
+#include "ComponentEditor.h"
+#include "LayoutUtils.h"
+#include "StyleUtils.h"
+#include "DepthProbeInstrumentItem.h"
+#include "BeamDistributionItem.h"
+#include "BeamItems.h"
+#include "SpecularBeamInclinationItem.h"
+#include "StyleUtils.h"
+#include "DistributionDialog.h"
+#include <QVBoxLayout>
+#include <QGridLayout>
+
+namespace
+{
+const QString wavelength_title("Wavelength [nm]");
+const QString inclination_title("Inclination angles [deg]");
+const QString depth_axis_title("Depth axis [nm]");
+}
+
+DepthProbeInstrumentEditor::DepthProbeInstrumentEditor(QWidget* parent)
+    : SessionItemWidget(parent)
+    , m_wavelengthEditor(new ComponentEditor(ComponentEditor::InfoWidget, wavelength_title))
+    , m_inclinationEditor(new ComponentEditor(ComponentEditor::InfoWidget, inclination_title))
+    , m_depthAxisEditor(new ComponentEditor(ComponentEditor::InfoWidget, depth_axis_title))
+    , m_gridLayout(new QGridLayout)
+{
+    m_gridLayout->addWidget(m_wavelengthEditor, 1, 0);
+    m_gridLayout->addWidget(m_inclinationEditor, 1, 1);
+    m_gridLayout->addWidget(m_depthAxisEditor, 1, 2);
+
+    auto mainLayout = new QVBoxLayout;
+    mainLayout->addWidget(StyleUtils::createDetailsWidget(m_gridLayout, "Parameters"));
+    mainLayout->addStretch();
+    setLayout(mainLayout);
+
+    connect(m_wavelengthEditor, &ComponentEditor::dialogRequest,
+            this, &DepthProbeInstrumentEditor::onDialogRequest);
+    connect(m_inclinationEditor, &ComponentEditor::dialogRequest,
+            this, &DepthProbeInstrumentEditor::onDialogRequest);
+}
+
+void DepthProbeInstrumentEditor::subscribeToItem()
+{
+    const auto beam_item = instrumentItem()->getItem(DepthProbeInstrumentItem::P_BEAM);
+
+
+    auto wavelengthItem = beam_item->getItem(SpecularBeamItem::P_WAVELENGTH);
+    m_wavelengthEditor->setItem(wavelengthItem->getItem(BeamDistributionItem::P_DISTRIBUTION));
+
+    auto inclinationItem = beam_item->getItem(SpecularBeamItem::P_INCLINATION_ANGLE);
+    m_inclinationEditor->setItem(
+        inclinationItem->getItem(SpecularBeamInclinationItem::P_DISTRIBUTION));
+    m_inclinationEditor->addItem(
+                inclinationItem->getItem(SpecularBeamInclinationItem::P_ALPHA_AXIS));
+    m_depthAxisEditor->setItem(instrumentItem()->getItem(DepthProbeInstrumentItem::P_ZAXIS));
+}
+
+void DepthProbeInstrumentEditor::unsubscribeFromItem()
+{
+    m_wavelengthEditor->clearEditor();
+    m_inclinationEditor->clearEditor();
+}
+
+DepthProbeInstrumentItem* DepthProbeInstrumentEditor::instrumentItem()
+{
+    return dynamic_cast<DepthProbeInstrumentItem*>(currentItem());
+}
+
+void DepthProbeInstrumentEditor::onDialogRequest(SessionItem* item, const QString& name)
+{
+    if(!item)
+        return;
+
+    auto dialog = new DistributionDialog(this);
+    dialog->setItem(item);
+    dialog->setNameOfEditor(name);
+    dialog->show();
+}
diff --git a/GUI/coregui/Views/InstrumentWidgets/DepthProbeInstrumentEditor.h b/GUI/coregui/Views/InstrumentWidgets/DepthProbeInstrumentEditor.h
new file mode 100644
index 0000000000000000000000000000000000000000..2c74a670a78c62903e38ce694033850cb6d77d2d
--- /dev/null
+++ b/GUI/coregui/Views/InstrumentWidgets/DepthProbeInstrumentEditor.h
@@ -0,0 +1,46 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/InstrumentWidgets/DepthProbeInstrumentEditor.h
+//! @brief     Defines class DepthProbeInstrumentEditor
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef DEPTHPROBEINSTRUMENTEDITOR_H
+#define DEPTHPROBEINSTRUMENTEDITOR_H
+
+#include "SessionItemWidget.h"
+
+class ComponentEditor;
+class QGridLayout;
+class DepthProbeInstrumentItem;
+
+class BA_CORE_API_ DepthProbeInstrumentEditor : public SessionItemWidget
+{
+    Q_OBJECT
+
+public:
+    DepthProbeInstrumentEditor(QWidget* parent = nullptr);
+
+protected:
+    void subscribeToItem();
+    void unsubscribeFromItem();
+
+private:
+    DepthProbeInstrumentItem* instrumentItem();
+    void onDialogRequest(SessionItem* item, const QString& name);
+
+    ComponentEditor* m_wavelengthEditor;
+    ComponentEditor* m_inclinationEditor;
+    ComponentEditor* m_depthAxisEditor;
+    QGridLayout* m_gridLayout;
+};
+
+
+#endif
diff --git a/GUI/coregui/Views/InstrumentWidgets/GISASInstrumentEditor.cpp b/GUI/coregui/Views/InstrumentWidgets/GISASInstrumentEditor.cpp
index 1bf968d1e024176ee2c3f90fdbd69bf518a22aee..2d1c9c92e0d3483d09b28a06e12dff9ca073b6b2 100644
--- a/GUI/coregui/Views/InstrumentWidgets/GISASInstrumentEditor.cpp
+++ b/GUI/coregui/Views/InstrumentWidgets/GISASInstrumentEditor.cpp
@@ -13,30 +13,29 @@
 // ************************************************************************** //
 
 #include "GISASInstrumentEditor.h"
+#include "ColumnResizer.h"
+#include "EnvironmentEditor.h"
 #include "GISASBeamEditor.h"
 #include "GISASDetectorEditor.h"
-#include "EnvironmentEditor.h"
-#include "PolarizationAnalysisEditor.h"
 #include "InstrumentItems.h"
-#include "detailswidget.h"
-#include "ColumnResizer.h"
+#include "PolarizationAnalysisEditor.h"
+#include "StyleUtils.h"
 #include <QVBoxLayout>
 
 GISASInstrumentEditor::GISASInstrumentEditor(QWidget* parent)
-    : SessionItemWidget(parent)
-    , m_columnResizer(new ColumnResizer(this))
-    , m_beamEditor(new GISASBeamEditor(m_columnResizer))
-    , m_detectorEditor(new GISASDetectorEditor)
-    , m_environmentEditor(new EnvironmentEditor(m_columnResizer))
-    , m_polarizationAnalysisEditor(new PolarizationAnalysisEditor(m_columnResizer))
+    : SessionItemWidget(parent), m_columnResizer(new ColumnResizer(this)),
+      m_beamEditor(new GISASBeamEditor(m_columnResizer)), m_detectorEditor(new GISASDetectorEditor),
+      m_environmentEditor(new EnvironmentEditor(m_columnResizer)),
+      m_polarizationAnalysisEditor(new PolarizationAnalysisEditor(m_columnResizer))
 {
     auto mainLayout = new QVBoxLayout;
 
-    addEditor(mainLayout, m_beamEditor, "Beam parameters");
-    addEditor(mainLayout, m_detectorEditor, "Detector parameters");
-    addEditor(mainLayout, m_polarizationAnalysisEditor, "Polarization analysis", /*expanded*/false);
-    addEditor(mainLayout, m_environmentEditor, "Environment", /*expanded*/false);
-
+    mainLayout->addWidget(StyleUtils::createDetailsWidget(m_beamEditor, "Beam parameters"));
+    mainLayout->addWidget(StyleUtils::createDetailsWidget(m_detectorEditor, "Detector parameters"));
+    mainLayout->addWidget(StyleUtils::createDetailsWidget(
+        m_polarizationAnalysisEditor, "Polarization analysis", /*expanded*/ false));
+    mainLayout->addWidget(
+        StyleUtils::createDetailsWidget(m_environmentEditor, "Environment", /*expanded*/ false));
     mainLayout->addStretch();
 
     setLayout(mainLayout);
@@ -50,18 +49,6 @@ void GISASInstrumentEditor::subscribeToItem()
     m_polarizationAnalysisEditor->setItem(instrumentItem());
 }
 
-void GISASInstrumentEditor::addEditor(QVBoxLayout* layout, QWidget* widget, const QString& name,
-                                      bool expanded)
-{
-    auto detailsWidget = new Utils::DetailsWidget;
-    detailsWidget->setSummaryText(name);
-    detailsWidget->setSummaryFontBold(true);
-    detailsWidget->setWidget(widget);
-    if (expanded)
-        detailsWidget->setState(Utils::DetailsWidget::Expanded);
-    layout->addWidget(detailsWidget);
-}
-
 GISASInstrumentItem* GISASInstrumentEditor::instrumentItem()
 {
     auto result = dynamic_cast<GISASInstrumentItem*>(currentItem());
diff --git a/GUI/coregui/Views/InstrumentWidgets/GISASInstrumentEditor.h b/GUI/coregui/Views/InstrumentWidgets/GISASInstrumentEditor.h
index a0a9fd9afcfebe157ef950c6152fd9fab278786e..7eb7255033fdc1a53957bfeec9dbe8365a15e162 100644
--- a/GUI/coregui/Views/InstrumentWidgets/GISASInstrumentEditor.h
+++ b/GUI/coregui/Views/InstrumentWidgets/GISASInstrumentEditor.h
@@ -23,7 +23,6 @@ class GISASDetectorEditor;
 class EnvironmentEditor;
 class PolarizationAnalysisEditor;
 class ColumnResizer;
-class QVBoxLayout;
 
 class BA_CORE_API_ GISASInstrumentEditor : public SessionItemWidget
 {
@@ -36,8 +35,6 @@ protected:
     void subscribeToItem();
 
 private:
-    void addEditor(QVBoxLayout* layout, QWidget* widget, const QString& name, bool expanded=true);
-
     GISASInstrumentItem* instrumentItem();
     ColumnResizer* m_columnResizer;
     GISASBeamEditor* m_beamEditor;
diff --git a/GUI/coregui/Views/InstrumentWidgets/InstrumentPresenter.cpp b/GUI/coregui/Views/InstrumentWidgets/InstrumentPresenter.cpp
index b8e72fdf7a33421e7db24bbd20914ad1dea76154..982b874053d9f8b2a3ef3b70bce2617c4221dfbc 100644
--- a/GUI/coregui/Views/InstrumentWidgets/InstrumentPresenter.cpp
+++ b/GUI/coregui/Views/InstrumentWidgets/InstrumentPresenter.cpp
@@ -17,6 +17,7 @@
 #include "GISASInstrumentEditor.h"
 #include "OffSpecInstrumentEditor.h"
 #include "SpecularInstrumentEditor.h"
+#include "DepthProbeInstrumentEditor.h"
 #include "GUIHelpers.h"
 #include "SessionItem.h"
 
@@ -24,6 +25,7 @@ namespace {
 const QString GISASPresentation = "GISAS";
 const QString OffSpecPresentation = "OffSpec";
 const QString SpecularPresentation = "Specular";
+const QString DepthProbePresentation = "DepthProbe";
 }
 
 InstrumentPresenter::InstrumentPresenter(QWidget* parent)
@@ -32,6 +34,7 @@ InstrumentPresenter::InstrumentPresenter(QWidget* parent)
     registerWidget(GISASPresentation, create_new<GISASInstrumentEditor>);
     registerWidget(OffSpecPresentation, create_new<OffSpecInstrumentEditor>);
     registerWidget(SpecularPresentation, create_new<SpecularInstrumentEditor>);
+    registerWidget(DepthProbePresentation, create_new<DepthProbeInstrumentEditor>);
     setToolBarVisible(false);
 }
 
@@ -45,7 +48,9 @@ QString InstrumentPresenter::itemPresentation() const
     else if (currentItem()->modelType() == Constants::OffSpecInstrumentType)
         return OffSpecPresentation;
     else if (currentItem()->modelType() == Constants::SpecularInstrumentType)
-	return SpecularPresentation;
+        return SpecularPresentation;
+    else if (currentItem()->modelType() == Constants::DepthProbeInstrumentType)
+        return DepthProbePresentation;
     else
         throw GUIHelpers::Error("InstrumentPresenter::itemPresentation() -> Error. Wrong item "
                                 "type '"+currentItem()->modelType()+"'");
@@ -54,5 +59,6 @@ QString InstrumentPresenter::itemPresentation() const
 QStringList InstrumentPresenter::activePresentationList(SessionItem* item)
 {
     Q_UNUSED(item);
-    return QStringList() << GISASPresentation << OffSpecPresentation << SpecularPresentation;
+    return QStringList() << GISASPresentation << OffSpecPresentation << SpecularPresentation
+                         << DepthProbePresentation;
 }
diff --git a/GUI/coregui/Views/InstrumentWidgets/InstrumentViewActions.cpp b/GUI/coregui/Views/InstrumentWidgets/InstrumentViewActions.cpp
index 34ea058883670a174920c849cd9abe24ab0977b4..431d5cbf6f9148229925234936dd46a837acc6c6 100644
--- a/GUI/coregui/Views/InstrumentWidgets/InstrumentViewActions.cpp
+++ b/GUI/coregui/Views/InstrumentWidgets/InstrumentViewActions.cpp
@@ -13,7 +13,9 @@
 // ************************************************************************** //
 
 #include "InstrumentViewActions.h"
+#include "GroupItem.h"
 #include "InstrumentItems.h"
+#include "PointwiseAxisItem.h"
 #include "SessionModel.h"
 #include "ModelUtils.h"
 #include <QAction>
@@ -85,6 +87,9 @@ void InstrumentViewActions::onAddInstrument()
     } else if (instrumentType == Constants::SpecularInstrumentType) {
         auto instrument = m_model->insertNewItem(instrumentType);
         instrument->setItemName(suggestInstrumentName("Specular"));
+    } else if (instrumentType == Constants::DepthProbeInstrumentType) {
+        auto instrument = m_model->insertNewItem(instrumentType);
+        instrument->setItemName(suggestInstrumentName("DepthProbe"));
     } else {
         qInfo() << "InstrumentViewActions::onAddInstrument() -> Not supported instrument type"
                 << instrumentType;
@@ -125,6 +130,23 @@ void InstrumentViewActions::onCloneInstrument()
             m_model->copyItem(child, clone, tag);
         }
         clone->setItemName(nameOfClone);
+
+        // copying non-uniform axis data
+        if (auto instrument = dynamic_cast<SpecularInstrumentItem*>(item)) {
+            auto axis_group = instrument->beamItem()->inclinationAxisGroup();
+
+            auto donor_axis = dynamic_cast<PointwiseAxisItem*>(
+                axis_group->getItemOfType(Constants::PointwiseAxisType));
+            if (!donor_axis->containsNonXMLData())
+                return;
+
+            auto acceptor_axis =
+                dynamic_cast<PointwiseAxisItem*>(dynamic_cast<SpecularInstrumentItem*>(clone)
+                                                     ->beamItem()
+                                                     ->inclinationAxisGroup()
+                                                     ->getItemOfType(Constants::PointwiseAxisType));
+            acceptor_axis->init(*donor_axis->getAxis(), donor_axis->getUnitsLabel());
+        }
     }
 }
 
@@ -212,4 +234,9 @@ void InstrumentViewActions::initAddInstrumentMenu()
     action->setData(QVariant::fromValue(Constants::SpecularInstrumentType));
     action->setToolTip("Add Specular instrument with default settings");
     connect(action, &QAction::triggered, this, &InstrumentViewActions::onAddInstrument);
+
+    action = m_addInstrumentMenu->addAction("DepthProbe");
+    action->setData(QVariant::fromValue(Constants::DepthProbeInstrumentType));
+    action->setToolTip("Add DepthProbe instrument with default settings");
+    connect(action, &QAction::triggered, this, &InstrumentViewActions::onAddInstrument);
 }
diff --git a/GUI/coregui/Views/InstrumentWidgets/OffSpecInstrumentEditor.cpp b/GUI/coregui/Views/InstrumentWidgets/OffSpecInstrumentEditor.cpp
index cd2a93c0f003789c4b73b345331575d66fa68c99..4f353e7453e4e541cd875a9e93a43ff53077f6d8 100644
--- a/GUI/coregui/Views/InstrumentWidgets/OffSpecInstrumentEditor.cpp
+++ b/GUI/coregui/Views/InstrumentWidgets/OffSpecInstrumentEditor.cpp
@@ -18,8 +18,8 @@
 #include "EnvironmentEditor.h"
 #include "PolarizationAnalysisEditor.h"
 #include "InstrumentItems.h"
-#include "detailswidget.h"
 #include "ColumnResizer.h"
+#include "StyleUtils.h"
 #include <QVBoxLayout>
 
 OffSpecInstrumentEditor::OffSpecInstrumentEditor(QWidget* parent)
@@ -35,11 +35,8 @@ OffSpecInstrumentEditor::OffSpecInstrumentEditor(QWidget* parent)
 {
     auto mainLayout = new QVBoxLayout;
 
-    addEditor(mainLayout, m_beamEditor, "Beam parameters");
-    addEditor(mainLayout, m_detectorEditor, "Detector parameters");
-//    addEditor(mainLayout, m_polarizationAnalysisEditor, "Polarization analysis", /*expanded*/false);
-//    addEditor(mainLayout, m_environmentEditor, "Environment", /*expanded*/false);
-
+    mainLayout->addWidget(StyleUtils::createDetailsWidget(m_beamEditor, "Beam parameters"));
+    mainLayout->addWidget(StyleUtils::createDetailsWidget(m_detectorEditor, "Detector parameters"));
     mainLayout->addStretch();
 
     setLayout(mainLayout);
@@ -53,18 +50,6 @@ void OffSpecInstrumentEditor::subscribeToItem()
 //    m_polarizationAnalysisEditor->setItem(instrumentItem());
 }
 
-void OffSpecInstrumentEditor::addEditor(QVBoxLayout* layout, QWidget* widget, const QString& name,
-                                      bool expanded)
-{
-    auto detailsWidget = new Utils::DetailsWidget;
-    detailsWidget->setSummaryText(name);
-    detailsWidget->setSummaryFontBold(true);
-    detailsWidget->setWidget(widget);
-    if (expanded)
-        detailsWidget->setState(Utils::DetailsWidget::Expanded);
-    layout->addWidget(detailsWidget);
-}
-
 OffSpecInstrumentItem* OffSpecInstrumentEditor::instrumentItem()
 {
     auto result = dynamic_cast<OffSpecInstrumentItem*>(currentItem());
diff --git a/GUI/coregui/Views/InstrumentWidgets/OffSpecInstrumentEditor.h b/GUI/coregui/Views/InstrumentWidgets/OffSpecInstrumentEditor.h
index 1ee426a1efa6c13ac7c3c761e6abcef3482821d4..8ef7fa8c76e8365b8ad56896b255cee45116f90f 100644
--- a/GUI/coregui/Views/InstrumentWidgets/OffSpecInstrumentEditor.h
+++ b/GUI/coregui/Views/InstrumentWidgets/OffSpecInstrumentEditor.h
@@ -23,7 +23,6 @@ class GISASDetectorEditor;
 class EnvironmentEditor;
 class PolarizationAnalysisEditor;
 class ColumnResizer;
-class QVBoxLayout;
 
 class BA_CORE_API_ OffSpecInstrumentEditor : public SessionItemWidget
 {
@@ -36,8 +35,6 @@ protected:
     void subscribeToItem();
 
 private:
-    void addEditor(QVBoxLayout* layout, QWidget* widget, const QString& name, bool expanded=true);
-
     OffSpecInstrumentItem* instrumentItem();
     ColumnResizer* m_columnResizer;
     OffSpecBeamEditor* m_beamEditor;
diff --git a/GUI/coregui/Views/InstrumentWidgets/SpecularBeamEditor.cpp b/GUI/coregui/Views/InstrumentWidgets/SpecularBeamEditor.cpp
index 2afd8cd3f44dbe9e89d3ccde6db6eebde2043699..183cf78d18a8fe1c70ed68bfba67594b3c4743d8 100644
--- a/GUI/coregui/Views/InstrumentWidgets/SpecularBeamEditor.cpp
+++ b/GUI/coregui/Views/InstrumentWidgets/SpecularBeamEditor.cpp
@@ -74,9 +74,9 @@ void SpecularBeamEditor::subscribeToItem()
 
     auto inclinationItem = beam_item->getItem(SpecularBeamItem::P_INCLINATION_ANGLE);
     m_inclinationEditor->setItem(
-        inclinationItem->getItem(SpecularBeamInclinationItem::P_ALPHA_AXIS));
-    m_inclinationEditor->addItem(
         inclinationItem->getItem(SpecularBeamInclinationItem::P_DISTRIBUTION));
+    m_inclinationEditor->addItem(
+        inclinationItem->getItem(SpecularBeamInclinationItem::P_ALPHA_AXIS));
 
     m_footprint_editor->setItem(beam_item->getItem(SpecularBeamItem::P_FOOPTPRINT));
 }
@@ -102,10 +102,7 @@ void SpecularBeamEditor::onDialogRequest(SessionItem* item, const QString& name)
         return;
 
     auto dialog = new DistributionDialog(this);
-    auto item_to_set = item->modelType() == Constants::SpecularBeamInclinationType
-                           ? item->getItem(SpecularBeamInclinationItem::P_DISTRIBUTION)
-                           : item;
-    dialog->setItem(item_to_set);
+    dialog->setItem(item);
     dialog->setNameOfEditor(name);
     dialog->show();
 }
diff --git a/GUI/coregui/Views/InstrumentWidgets/SpecularInstrumentEditor.cpp b/GUI/coregui/Views/InstrumentWidgets/SpecularInstrumentEditor.cpp
index dbf1b9ffda46c444876bfffb1672800cf08d3e8c..b755ef773ebc27541becb04108e9a3ccd4f5fc5f 100644
--- a/GUI/coregui/Views/InstrumentWidgets/SpecularInstrumentEditor.cpp
+++ b/GUI/coregui/Views/InstrumentWidgets/SpecularInstrumentEditor.cpp
@@ -3,8 +3,8 @@
 #include "EnvironmentEditor.h"
 #include "PolarizationAnalysisEditor.h"
 #include "InstrumentItems.h"
-#include "detailswidget.h"
 #include "ColumnResizer.h"
+#include "StyleUtils.h"
 #include <QVBoxLayout>
 
 SpecularInstrumentEditor::SpecularInstrumentEditor(QWidget* parent)
@@ -16,10 +16,9 @@ SpecularInstrumentEditor::SpecularInstrumentEditor(QWidget* parent)
 {
     auto mainLayout = new QVBoxLayout;
 
-    addEditor(mainLayout, m_beamEditor, "Beam parameters");
-//    addEditor(mainLayout, m_polarizationAnalysisEditor, "Polarization analysis", /*expanded*/false);
-    addEditor(mainLayout, m_environmentEditor, "Environment", /*expanded*/false);
-
+    mainLayout->addWidget(StyleUtils::createDetailsWidget(m_beamEditor, "Beam parameters"));
+    mainLayout->addWidget(StyleUtils::createDetailsWidget(m_environmentEditor, "Environment",
+                                                          /*expanded*/false));
     mainLayout->addStretch();
 
     setLayout(mainLayout);
@@ -32,18 +31,6 @@ void SpecularInstrumentEditor::subscribeToItem()
 //    m_polarizationAnalysisEditor->setItem(instrumentItem());
 }
 
-void SpecularInstrumentEditor::addEditor(QVBoxLayout* layout, QWidget* widget, const QString& name,
-                                         bool expanded)
-{
-    auto detailsWidget = new Utils::DetailsWidget;
-    detailsWidget->setSummaryText(name);
-    detailsWidget->setSummaryFontBold(true);
-    detailsWidget->setWidget(widget);
-    if (expanded)
-        detailsWidget->setState(Utils::DetailsWidget::Expanded);
-    layout->addWidget(detailsWidget);
-}
-
 SpecularInstrumentItem* SpecularInstrumentEditor::instrumentItem()
 {
     auto result = dynamic_cast<SpecularInstrumentItem*>(currentItem());
diff --git a/GUI/coregui/Views/InstrumentWidgets/SpecularInstrumentEditor.h b/GUI/coregui/Views/InstrumentWidgets/SpecularInstrumentEditor.h
index cc3a8340a43f1e1934a15aa70a8e605dd88e9abd..79870e86e0b26d2cad94226ccadb33f3efbf728a 100644
--- a/GUI/coregui/Views/InstrumentWidgets/SpecularInstrumentEditor.h
+++ b/GUI/coregui/Views/InstrumentWidgets/SpecularInstrumentEditor.h
@@ -35,8 +35,6 @@ protected:
     void subscribeToItem();
 
 private:
-    void addEditor(QVBoxLayout* layout, QWidget* widget, const QString& name, bool expanded=true);
-
     SpecularInstrumentItem* instrumentItem();
     ColumnResizer* m_columnResizer;
     SpecularBeamEditor* m_beamEditor;
diff --git a/GUI/coregui/Views/IntensityDataWidgets/Plot1D.cpp b/GUI/coregui/Views/IntensityDataWidgets/Plot1D.cpp
index 2ed985b07779df89db0c0fe9c79d5217eac73c0d..5db1047437fe8c38ef8a595209908f3f3a53cfb7 100644
--- a/GUI/coregui/Views/IntensityDataWidgets/Plot1D.cpp
+++ b/GUI/coregui/Views/IntensityDataWidgets/Plot1D.cpp
@@ -32,8 +32,10 @@ int getBin(double x, const QCPGraph* graph);
 }
 
 Plot1D::Plot1D(QWidget* parent)
-    : ScientificPlot(parent, PLOT_TYPE::Plot1D), m_custom_plot(new QCustomPlot),
-      m_update_timer(new UpdateTimer(replot_update_interval, this)), m_block_update(true)
+    : ScientificPlot(parent, PLOT_TYPE::Plot1D)
+    , m_custom_plot(new QCustomPlot)
+    , m_update_timer(new UpdateTimer(replot_update_interval, this))
+    , m_block_update(false)
 {
     QVBoxLayout* vlayout = new QVBoxLayout(this);
     vlayout->setContentsMargins(0, 0, 0, 0);
@@ -126,7 +128,7 @@ void Plot1D::subscribeToItem()
     std::for_each(m_graph_map.begin(), m_graph_map.end(), [caller=this](auto pair) {
         auto property_item = pair.first;
         property_item->dataItem()->mapper()->setOnValueChange(
-            [caller, property_item]() { caller->refreshPlotData(property_item); }, caller);
+            [caller]() { caller->refreshPlotData(); }, caller);
     });
 
     setConnected(true);
@@ -194,30 +196,17 @@ void Plot1D::setUpdateTimerConnected(bool isConnected)
 
 void Plot1D::refreshPlotData()
 {
-    auto view_item = viewItem();
-    assert(view_item);
+    if (m_block_update)
+        return;
 
     m_block_update = true;
 
-    setAxesRangeFromItem(view_item);
-    setAxesLabelsFromItem(view_item);
-    updateAllGraphs();
-
-    replot();
-
-    m_block_update = false;
-}
-
-void Plot1D::refreshPlotData(Data1DProperties* item)
-{
     auto view_item = viewItem();
-    assert(view_item && item);
-
-    m_block_update = true;
+    assert(view_item);
 
     setAxesRangeFromItem(view_item);
     setAxesLabelsFromItem(view_item);
-    updateGraph(item);
+    updateAllGraphs();
 
     replot();
 
diff --git a/GUI/coregui/Views/IntensityDataWidgets/Plot1D.h b/GUI/coregui/Views/IntensityDataWidgets/Plot1D.h
index 087198903af24bc9666bf85287586becf3f38679..c93c6992ec9a6628d0874d6c157fc11e8a27fa17 100644
--- a/GUI/coregui/Views/IntensityDataWidgets/Plot1D.h
+++ b/GUI/coregui/Views/IntensityDataWidgets/Plot1D.h
@@ -81,7 +81,6 @@ private:
 
     //! Refresh axes' labels, range and graph data.
     void refreshPlotData();
-    void refreshPlotData(Data1DProperties* item);
 
     //! Sets (xmin,xmax) and (ymin,ymax) of SpecularPlot from specular item.
     //! Also sets logarithmic scale on y-axis if necessary.
diff --git a/GUI/coregui/Views/JobView.cpp b/GUI/coregui/Views/JobView.cpp
index 8316f0c7fa95b549e09fb07aebb02416b80dcd0e..9bbb3b7e09ebe9f9d921e503342a15d31fe062e0 100644
--- a/GUI/coregui/Views/JobView.cpp
+++ b/GUI/coregui/Views/JobView.cpp
@@ -13,7 +13,7 @@
 // ************************************************************************** //
 
 #include "JobView.h"
-#include "JobActivityStatusBar.h"
+#include "JobViewStatusBar.h"
 #include "JobItem.h"
 #include "JobModel.h"
 #include "JobOutputDataWidget.h"
@@ -26,7 +26,7 @@
 
 JobView::JobView(MainWindow *mainWindow)
     : m_docks(new JobViewDocks(this))
-    , m_jobActivityStatusBar(new JobActivityStatusBar(mainWindow))
+    , m_statusBar(new JobViewStatusBar(mainWindow))
     , m_progressAssistant(new JobProgressAssistant(mainWindow))
     , m_currentItem(nullptr)
     , m_mainWindow(mainWindow)
@@ -72,16 +72,20 @@ void JobView::onSelectionChanged(JobItem* jobItem) {
     m_docks->setItem(jobItem);
 }
 
-void JobView::showEvent(QShowEvent*)
+void JobView::showEvent(QShowEvent* event)
 {
     if (isVisible())
-        m_jobActivityStatusBar->show();
+        m_statusBar->show();
+
+    Manhattan::FancyMainWindow::showEvent(event);
 }
 
-void JobView::hideEvent(QHideEvent*)
+void JobView::hideEvent(QHideEvent* event)
 {
     if (isHidden())
-        m_jobActivityStatusBar->hide();
+        m_statusBar->hide();
+
+    Manhattan::FancyMainWindow::hideEvent(event);
 }
 
 void JobView::connectSignals()
@@ -95,13 +99,13 @@ void JobView::connectSignals()
 
 void JobView::connectActivityRelated()
 {
-    // Change activity requests: JobActivityStatusBar -> this
-    connect(m_jobActivityStatusBar, &JobActivityStatusBar::changeActivityRequest,
+    // Change activity requests: JobViewStatusBar -> this
+    connect(m_statusBar, &JobViewStatusBar::changeActivityRequest,
             this, &JobView::setActivity);
 
-    // Activity was changed: this -> JobActivityStatusBar
+    // Activity was changed: this -> JobViewStatusBar
     connect(this, &JobView::activityChanged,
-            m_jobActivityStatusBar, &JobActivityStatusBar::onActivityChanged);
+            m_statusBar, &JobViewStatusBar::onActivityChanged);
 
     // Activity was changed: this -> JobOutputDataWidget
     connect(this, &JobView::activityChanged,
@@ -114,12 +118,12 @@ void JobView::connectLayoutRelated()
 {
     connect(this, &JobView::resetLayout, m_docks, &JobViewDocks::onResetLayout);
 
-    // Toggling of JobSelector request: JobActivityStatusBar -> this
-    connect(m_jobActivityStatusBar, &JobActivityStatusBar::toggleJobSelectorRequest,
+    // Toggling of JobSelector request: JobViewStatusBar -> this
+    connect(m_statusBar, &JobViewStatusBar::toggleJobSelectorRequest,
             m_docks, &JobViewDocks::onToggleJobSelector);
 
-    // Dock menu request: JobActivityStatusBar -> this
-    connect(m_jobActivityStatusBar, &JobActivityStatusBar::dockMenuRequest,
+    // Dock menu request: JobViewStatusBar -> this
+    connect(m_statusBar, &JobViewStatusBar::dockMenuRequest,
             this, &JobView::onDockMenuRequest);
 }
 
diff --git a/GUI/coregui/Views/JobView.h b/GUI/coregui/Views/JobView.h
index 5822ea005469c203a0300023b3fc4b5c732f6325..172156025d6aefdc1529dde57652549a1bd2ee90 100644
--- a/GUI/coregui/Views/JobView.h
+++ b/GUI/coregui/Views/JobView.h
@@ -20,7 +20,7 @@
 
 class MainWindow;
 class JobViewDocks;
-class JobActivityStatusBar;
+class JobViewStatusBar;
 class JobProgressAssistant;
 class JobItem;
 
@@ -45,8 +45,8 @@ public slots:
     void onSelectionChanged(JobItem* jobItem);
 
 protected:
-    virtual void showEvent(QShowEvent*);
-    virtual void hideEvent(QHideEvent*);
+    virtual void showEvent(QShowEvent* event);
+    virtual void hideEvent(QHideEvent* event);
 
 private:
     void connectSignals();
@@ -57,7 +57,7 @@ private:
     void setAppropriateActivityForJob(JobItem* jobItem);
 
     JobViewDocks* m_docks;
-    JobActivityStatusBar* m_jobActivityStatusBar;
+    JobViewStatusBar* m_statusBar;
     JobProgressAssistant* m_progressAssistant;
     JobItem* m_currentItem;
     MainWindow* m_mainWindow;
diff --git a/GUI/coregui/Views/JobWidgets/JobListViewDelegate.cpp b/GUI/coregui/Views/JobWidgets/JobListViewDelegate.cpp
index 37e9bba70cd45a78b74a9a419ac603eccde2190d..9beac64922923c6d7d83d5be05220b9c8af0c0b4 100644
--- a/GUI/coregui/Views/JobWidgets/JobListViewDelegate.cpp
+++ b/GUI/coregui/Views/JobWidgets/JobListViewDelegate.cpp
@@ -61,7 +61,7 @@ void JobListViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &o
         QStyleOptionButton button;
         button.rect = getButtonRect(option.rect);
         button.state = m_buttonState | QStyle::State_Enabled;
-        button.icon = QIcon(":/images/darkclosebutton.png");
+        button.icon = QIcon(":/images/dark-close.svg");
         button.iconSize = QSize(12,12);
 
         QApplication::style()->drawControl (QStyle::CE_PushButton, &button, painter);
diff --git a/GUI/coregui/Views/JobWidgets/JobMessagePanel.cpp b/GUI/coregui/Views/JobWidgets/JobMessagePanel.cpp
index 29d951cba4f0ae79003b9d90a80d292faf51970c..6a5f5197f6c9843ae395b5e6d0d8996c3b7626bc 100644
--- a/GUI/coregui/Views/JobWidgets/JobMessagePanel.cpp
+++ b/GUI/coregui/Views/JobWidgets/JobMessagePanel.cpp
@@ -24,6 +24,7 @@ JobMessagePanel::JobMessagePanel(QWidget *parent)
     , m_plainLog(new QTextEdit)
 {
     setWindowTitle(Constants::JobMessagePanelName);
+    setObjectName("JobMessagePanel");
 
     m_plainLog->setReadOnly(true);
 //    m_plainLog->setMaximumBlockCount(100000);
diff --git a/GUI/coregui/Views/JobWidgets/JobOutputDataWidget.cpp b/GUI/coregui/Views/JobWidgets/JobOutputDataWidget.cpp
index b91b2ad460af0b5b4941403ffc9cb1a8dd6eb743..6981e9e094489f3aa32cb3b373a75dc2c730608b 100644
--- a/GUI/coregui/Views/JobWidgets/JobOutputDataWidget.cpp
+++ b/GUI/coregui/Views/JobWidgets/JobOutputDataWidget.cpp
@@ -29,6 +29,7 @@ JobOutputDataWidget::JobOutputDataWidget(JobModel *jobModel, QWidget *parent)
     , m_stackedWidget(new ItemStackPresenter<JobResultsPresenter>(reuse_widget))
 {
     setWindowTitle(QLatin1String("Job OutputData"));
+    setObjectName("JobOutputDataWidget");
 
     setMinimumSize(400, 400);
     setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
diff --git a/GUI/coregui/Views/JobWidgets/JobRealTimeWidget.cpp b/GUI/coregui/Views/JobWidgets/JobRealTimeWidget.cpp
index 1b0038c652725f70935b8824273e0adf3556612e..7387e57b623952dbc326522f325ca77344e53897 100644
--- a/GUI/coregui/Views/JobWidgets/JobRealTimeWidget.cpp
+++ b/GUI/coregui/Views/JobWidgets/JobRealTimeWidget.cpp
@@ -20,7 +20,7 @@
 #include <QVBoxLayout>
 
 namespace {
-const bool reuse_widget = false;
+const bool reuse_widget = true;
 }
 
 JobRealTimeWidget::JobRealTimeWidget(JobModel* jobModel, QWidget* parent)
@@ -28,6 +28,7 @@ JobRealTimeWidget::JobRealTimeWidget(JobModel* jobModel, QWidget* parent)
     , m_stackedWidget(new ItemStackPresenter<ParameterTuningWidget>(reuse_widget))
 {
     setWindowTitle(Constants::JobRealTimeWidgetName);
+    setObjectName("JobRealTimeWidget");
     setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
 
     auto mainLayout = new QVBoxLayout;
diff --git a/GUI/coregui/Views/JobWidgets/JobResultsPresenter.cpp b/GUI/coregui/Views/JobWidgets/JobResultsPresenter.cpp
index a62ce1fdf816e1118142708fdb080af5d6da4f69..5d761df973cce540aac98332b19f3a696a3c153e 100644
--- a/GUI/coregui/Views/JobWidgets/JobResultsPresenter.cpp
+++ b/GUI/coregui/Views/JobWidgets/JobResultsPresenter.cpp
@@ -28,7 +28,8 @@ const bool use_job_last_presentation = true;
 const std::map<QString, QString> instrument_to_default_presentaion{
     {Constants::SpecularInstrumentType, Constants::SpecularDataPresentation},
     {Constants::GISASInstrumentType, Constants::IntensityDataPresentation},
-    {Constants::OffSpecInstrumentType, Constants::IntensityDataPresentation}};
+    {Constants::OffSpecInstrumentType, Constants::IntensityDataPresentation},
+    {Constants::DepthProbeInstrumentType, Constants::IntensityDataPresentation}};
 
 const std::map<QString, QString> instrument_to_fit_presentaion{
     {Constants::SpecularInstrumentType, Constants::FitComparisonPresentation1D},
@@ -42,17 +43,17 @@ const std::map<JobViewFlags::EActivities, std::map<QString, QString>> activity_t
 
 const std::map<QString, QStringList> default_active_presentation_list{
     {Constants::SpecularInstrumentType, {Constants::SpecularDataPresentation}},
-    {{Constants::GISASInstrumentType},
-     {Constants::IntensityDataPresentation, Constants::IntensityProjectionsPresentation}},
-    {{Constants::OffSpecInstrumentType},
-     {Constants::IntensityDataPresentation, Constants::IntensityProjectionsPresentation}}};
+    {{Constants::GISASInstrumentType}, {Constants::IntensityDataPresentation, Constants::IntensityProjectionsPresentation}},
+    {{Constants::OffSpecInstrumentType},{Constants::IntensityDataPresentation, Constants::IntensityProjectionsPresentation}},
+    {{Constants::DepthProbeInstrumentType},{Constants::IntensityDataPresentation, Constants::IntensityProjectionsPresentation}}
+};
 
 template<class QStringObj>
 QStringObj getPresentations(const SessionItem* job_item, const std::map<QString, QStringObj>& presentation_map) {
     const QString& instrument_type = job_item->getItem(JobItem::T_INSTRUMENT)->modelType();
     const auto list_iter = presentation_map.find(instrument_type);
     if (list_iter == presentation_map.cend())
-        throw GUIHelpers::Error("Error in JobResultsPresenter::getPresentations: unknown instrument");
+        return QStringObj();
     return list_iter->second;
 }
 }
@@ -119,7 +120,9 @@ QStringList JobResultsPresenter::activePresentationList(SessionItem* item)
 QStringList JobResultsPresenter::presentationList(SessionItem* item)
 {
     auto result = getPresentations(item, default_active_presentation_list);
-    result << getPresentations(item, instrument_to_fit_presentaion);
+    auto addon = getPresentations(item, instrument_to_fit_presentaion);
+    if (!addon.isEmpty())
+        result << addon;
 
     return result;
 }
diff --git a/GUI/coregui/Views/JobWidgets/JobSelectorWidget.cpp b/GUI/coregui/Views/JobWidgets/JobSelectorWidget.cpp
index e665b1bb41ab2a94c56f6ae149b74e2325b19389..1c23430fccd68a2c5ff1f3ea1cdb8c129727ae16 100644
--- a/GUI/coregui/Views/JobWidgets/JobSelectorWidget.cpp
+++ b/GUI/coregui/Views/JobWidgets/JobSelectorWidget.cpp
@@ -33,11 +33,13 @@ JobSelectorWidget::JobSelectorWidget(JobModel* jobModel, QWidget* parent)
     , m_jobProperties(new JobPropertiesWidget)
     , m_jobModel(nullptr)
 {
-    setModel(jobModel);
+    setWindowTitle(Constants::JobSelectorWidgetName);
+    setObjectName("JobSelectorWidget");
 
     setMinimumSize(128, 600);
     setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
-    setWindowTitle(Constants::JobSelectorWidgetName);
+
+    setModel(jobModel);
 
     m_splitter->setOrientation(Qt::Vertical);
     m_splitter->addWidget(m_jobListWidget);
diff --git a/GUI/coregui/Views/JobWidgets/JobViewDocks.h b/GUI/coregui/Views/JobWidgets/JobViewDocks.h
index 4e178ba4cf18e67439f752a414bfed5fc1d61308..67514c3c31e672e536c6682b28df50741f40fb37 100644
--- a/GUI/coregui/Views/JobWidgets/JobViewDocks.h
+++ b/GUI/coregui/Views/JobWidgets/JobViewDocks.h
@@ -24,6 +24,7 @@ class JobRealTimeWidget;
 class FitActivityPanel;
 class JobMessagePanel;
 class JobModel;
+class JobItem;
 
 //! The JobViewDocks class assists JobView in holding all main job widgets and corresponding
 //! dock containers.
@@ -47,7 +48,7 @@ public:
     JobMessagePanel* jobMessagePanel();
 
     void setActivity(int activity);
-    void setItem(class JobItem* jobItem);
+    void setItem(JobItem* jobItem);
 
 public slots:
     void onResetLayout() override;
diff --git a/GUI/coregui/Views/JobWidgets/JobActivityStatusBar.cpp b/GUI/coregui/Views/JobWidgets/JobViewStatusBar.cpp
similarity index 61%
rename from GUI/coregui/Views/JobWidgets/JobActivityStatusBar.cpp
rename to GUI/coregui/Views/JobWidgets/JobViewStatusBar.cpp
index 30f5d63f68962ea6d61d72a619947a142585fed9..77bf472f1a49187c5ba9e707752470bfe789689a 100644
--- a/GUI/coregui/Views/JobWidgets/JobActivityStatusBar.cpp
+++ b/GUI/coregui/Views/JobWidgets/JobViewStatusBar.cpp
@@ -2,8 +2,8 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      GUI/coregui/Views/JobWidgets/JobActivityStatusBar.cpp
-//! @brief     Implements class JobActivityStatusBar
+//! @file      GUI/coregui/Views/JobWidgets/JobViewStatusBar.cpp
+//! @brief     Implements class JobViewStatusBar
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -12,7 +12,7 @@
 //
 // ************************************************************************** //
 
-#include "JobActivityStatusBar.h"
+#include "JobViewStatusBar.h"
 #include "JobViewActivities.h"
 #include "mainwindow.h"
 #include <QComboBox>
@@ -20,16 +20,14 @@
 #include <QStatusBar>
 #include <QToolButton>
 
-JobActivityStatusBar::JobActivityStatusBar(MainWindow *mainWindow)
-    : QWidget(mainWindow)
-    , m_toggleJobListButton(0)
-    , m_activityCombo(0)
-    , m_dockMenuButton(0)
+JobViewStatusBar::JobViewStatusBar(MainWindow* mainWindow)
+    : QWidget(mainWindow), m_toggleJobListButton(nullptr)
+    , m_activityCombo(nullptr), m_dockMenuButton(nullptr)
     , m_mainWindow(mainWindow)
 {
     setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
 
-    QHBoxLayout *layout = new QHBoxLayout;
+    auto layout = new QHBoxLayout;
     layout->setSpacing(0);
     layout->setMargin(0);
 
@@ -38,18 +36,20 @@ JobActivityStatusBar::JobActivityStatusBar(MainWindow *mainWindow)
     m_toggleJobListButton->setIcon(QIcon(":/images/statusbar_joblist.svg"));
     m_toggleJobListButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
     m_toggleJobListButton->setToolTip("Toggle job list view");
-    connect(m_toggleJobListButton, SIGNAL(clicked()), this, SIGNAL(toggleJobSelectorRequest()));
+    connect(m_toggleJobListButton, &QToolButton::clicked,
+            this, &JobViewStatusBar::toggleJobSelectorRequest);
 
     m_activityCombo = new QComboBox();
     m_activityCombo->setToolTip("Main Activity Selector");
     m_activityCombo->addItems(JobViewActivities::activityList());
-    connect(m_activityCombo, SIGNAL(currentIndexChanged(int)),
-            this, SIGNAL(changeActivityRequest(int)));
+    connect(m_activityCombo, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
+            this, &JobViewStatusBar::changeActivityRequest);
 
     m_dockMenuButton = new QToolButton;
     m_dockMenuButton->setIcon(QIcon(":/images/statusbar_dockmenu.svg"));
     m_dockMenuButton->setToolTip("Docks layout menu");
-    connect(m_dockMenuButton, SIGNAL(clicked()), this, SIGNAL(dockMenuRequest()));
+    connect(m_dockMenuButton, &QToolButton::clicked,
+            this, &JobViewStatusBar::dockMenuRequest);
 
     layout->addWidget(m_toggleJobListButton);
     layout->addStretch();
@@ -60,20 +60,20 @@ JobActivityStatusBar::JobActivityStatusBar(MainWindow *mainWindow)
     initAppearance();
 }
 
-void JobActivityStatusBar::onActivityChanged(int activity)
+void JobViewStatusBar::onActivityChanged(int activity)
 {
-    disconnect(m_activityCombo, SIGNAL(currentIndexChanged(int)),
-            this, SIGNAL(changeActivityRequest(int)));
+    disconnect(m_activityCombo, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
+            this, &JobViewStatusBar::changeActivityRequest);
 
     m_activityCombo->setCurrentIndex(activity);
 
-    connect(m_activityCombo, SIGNAL(currentIndexChanged(int)),
-            this, SIGNAL(changeActivityRequest(int)));
+    connect(m_activityCombo, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
+            this, &JobViewStatusBar::changeActivityRequest);
 }
 
 //! Init appearance of MainWindow's statusBar.
 
-void JobActivityStatusBar::initAppearance()
+void JobViewStatusBar::initAppearance()
 {
     Q_ASSERT(m_mainWindow);
     m_mainWindow->statusBar()->addWidget(this, 1);
diff --git a/GUI/coregui/Views/JobWidgets/JobActivityStatusBar.h b/GUI/coregui/Views/JobWidgets/JobViewStatusBar.h
similarity index 56%
rename from GUI/coregui/Views/JobWidgets/JobActivityStatusBar.h
rename to GUI/coregui/Views/JobWidgets/JobViewStatusBar.h
index 8f0e60a1390ef5a03f25cb350f08d52355b3720c..b10c19962fb1b5a44aabc78560cfc4301efd653c 100644
--- a/GUI/coregui/Views/JobWidgets/JobActivityStatusBar.h
+++ b/GUI/coregui/Views/JobWidgets/JobViewStatusBar.h
@@ -2,8 +2,8 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      GUI/coregui/Views/JobWidgets/JobActivityStatusBar.h
-//! @brief     Defines class JobActivityStatusBar
+//! @file      GUI/coregui/Views/JobWidgets/JobViewStatusBar.h
+//! @brief     Defines class JobViewStatusBar
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -12,8 +12,8 @@
 //
 // ************************************************************************** //
 
-#ifndef JOBACTIVITYSTATUSBAR_H
-#define JOBACTIVITYSTATUSBAR_H
+#ifndef JOBVIEWSTATUSBAR_H
+#define JOBVIEWSTATUSBAR_H
 
 #include "WinDllMacros.h"
 #include <QWidget>
@@ -22,14 +22,14 @@ class MainWindow;
 class QToolButton;
 class QComboBox;
 
-//! The JobActivityStatusBar class is a narrow status bar at very bottom of JobView to switch
-//! between activities. Added to the status bar of MainWindow when JobView is shown.
+//! Narrow status bar at very bottom of JobView to switch between activities.
+//! Added to the status bar of MainWindow when JobView is shown.
 
-class BA_CORE_API_ JobActivityStatusBar : public QWidget
+class BA_CORE_API_ JobViewStatusBar : public QWidget
 {
     Q_OBJECT
 public:
-    JobActivityStatusBar(MainWindow *mainWindow = 0);
+    JobViewStatusBar(MainWindow* mainWindow);
 
 signals:
     void toggleJobSelectorRequest();
@@ -42,10 +42,10 @@ public slots:
 private:
     void initAppearance();
 
-    QToolButton *m_toggleJobListButton;
-    QComboBox *m_activityCombo;
-    QToolButton *m_dockMenuButton;
-    MainWindow *m_mainWindow;
+    QToolButton* m_toggleJobListButton;
+    QComboBox* m_activityCombo;
+    QToolButton* m_dockMenuButton;
+    MainWindow* m_mainWindow;
 };
 
-#endif // JOBACTIVITYSTATUSBAR_H
+#endif // JOBVIEWSTATUSBAR_H
diff --git a/GUI/coregui/Views/JobWidgets/ParameterTuningDelegate.cpp b/GUI/coregui/Views/JobWidgets/ParameterTuningDelegate.cpp
index ee11db5d4c2fbcb428d87016546d49543a4fcf16..98c830424bb36f167b713160c642efc9f7a5bfd9 100644
--- a/GUI/coregui/Views/JobWidgets/ParameterTuningDelegate.cpp
+++ b/GUI/coregui/Views/JobWidgets/ParameterTuningDelegate.cpp
@@ -16,11 +16,11 @@
 #include "ModelPath.h"
 #include "ParameterTreeItems.h"
 #include "ParameterTuningModel.h"
-#include "SessionModel.h"
+#include "ScientificSpinBox.h"
 #include "SessionItemUtils.h"
+#include "SessionModel.h"
 #include <QAbstractItemModel>
 #include <QApplication>
-#include <QDoubleSpinBox>
 #include <QHBoxLayout>
 #include <QItemSelectionModel>
 #include <QMouseEvent>
@@ -33,92 +33,81 @@
 #include <iostream>
 #include <limits>
 
-
-namespace {
+namespace
+{
 const double maximum_doublespin_value = std::numeric_limits<double>::max();
 const double minimum_doublespin_value = std::numeric_limits<double>::lowest();
-}
+} // namespace
 
-ParameterTuningDelegate::SliderData::SliderData()
-    : m_smin(0)
-    , m_smax(100)
-    , m_rmin(0.0)
-    , m_rmax(0.0)
-    , m_range_factor(100.0)
+ParameterTuningDelegate::TuningData::TuningData()
+    : m_smin(0), m_smax(100), m_rmin(0.0), m_rmax(0.0), m_range_factor(100.0)
 {
-
 }
 
-void ParameterTuningDelegate::SliderData::setRangeFactor(double range_factor)
+void ParameterTuningDelegate::TuningData::setRangeFactor(double range_factor)
 {
     m_range_factor = range_factor;
 }
 
-void ParameterTuningDelegate::SliderData::setItemLimits(const RealLimits &item_limits)
+void ParameterTuningDelegate::TuningData::setItemLimits(const RealLimits& item_limits)
 {
     m_item_limits = item_limits;
 }
 
-int ParameterTuningDelegate::SliderData::value_to_slider(double value)
+int ParameterTuningDelegate::TuningData::value_to_slider(double value)
 {
     double dr(0);
-    if(value == 0.0) {
-        dr = 1.0*m_range_factor/100.;
+    if (value == 0.0) {
+        dr = 1.0 * m_range_factor / 100.;
     } else {
-        dr = std::abs(value)*m_range_factor/100.;
+        dr = std::abs(value) * m_range_factor / 100.;
     }
     m_rmin = value - dr;
     m_rmax = value + dr;
 
-    if(m_item_limits.hasLowerLimit() && m_rmin < m_item_limits.lowerLimit())
+    if (m_item_limits.hasLowerLimit() && m_rmin < m_item_limits.lowerLimit())
         m_rmin = m_item_limits.lowerLimit();
 
-    if(m_item_limits.hasUpperLimit() && m_rmax > m_item_limits.upperLimit())
+    if (m_item_limits.hasUpperLimit() && m_rmax > m_item_limits.upperLimit())
         m_rmax = m_item_limits.upperLimit();
 
-    return m_smin + (value - m_rmin)*(m_smax-m_smin)/(m_rmax-m_rmin);
+    double result = m_smin + (value - m_rmin) * (m_smax - m_smin) / (m_rmax - m_rmin);
+    return static_cast<int>(result);
 }
 
-double ParameterTuningDelegate::SliderData::slider_to_value(int slider)
+double ParameterTuningDelegate::TuningData::slider_to_value(int slider)
 {
-    return m_rmin + (slider - m_smin)*(m_rmax-m_rmin)/(m_smax - m_smin);
+    return m_rmin + (slider - m_smin) * (m_rmax - m_rmin) / (m_smax - m_smin);
 }
 
-
-ParameterTuningDelegate::ParameterTuningDelegate(QObject *parent)
-    : QItemDelegate(parent)
-    , m_valueColumn(1)
-    , m_slider(0)
-    , m_valueBox(0)
-    , m_contentWidget(0)
-    , m_contentLayout(0)
-    , m_currentItem(0)
-    , m_isReadOnly(false)
+double ParameterTuningDelegate::TuningData::step() const
 {
-
+    return (m_rmax - m_rmin) / (m_smax - m_smin);
 }
 
-ParameterTuningDelegate::~ParameterTuningDelegate()
+ParameterTuningDelegate::ParameterTuningDelegate(QObject* parent)
+    : QItemDelegate(parent), m_valueColumn(1), m_slider(nullptr), m_valueBox(nullptr),
+      m_contentWidget(nullptr), m_contentLayout(nullptr), m_currentItem(nullptr),
+      m_isReadOnly(false)
 {
-//    if(m_currentItem)
-//        m_currentItem->mapper()->unsubscribe(this);
-
 }
 
-void ParameterTuningDelegate::paint(QPainter *painter,
-                                const QStyleOptionViewItem &option,
-                                const QModelIndex &index) const
+ParameterTuningDelegate::~ParameterTuningDelegate() {}
+
+void ParameterTuningDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,
+                                    const QModelIndex& index) const
 {
     if (index.column() == m_valueColumn) {
 
-        if(!index.parent().isValid()) return;
+        if (!index.parent().isValid())
+            return;
 
         QVariant prop_value = index.model()->data(index, Qt::EditRole);
-        if(prop_value.isValid()) {
+        if (prop_value.isValid()) {
             int type = SessionItemUtils::VariantType(prop_value);
             if (type == QVariant::Double) {
                 double value = prop_value.toDouble();
-                QString text(QString::number(value));
+                QString text = ScientificSpinBox::toString(value, 3);
 
                 QStyleOptionViewItem myOption = option;
                 myOption.displayAlignment = Qt::AlignLeft | Qt::AlignVCenter;
@@ -132,49 +121,52 @@ void ParameterTuningDelegate::paint(QPainter *painter,
     QItemDelegate::paint(painter, option, index);
 }
 
-
-QWidget *ParameterTuningDelegate::createEditor(QWidget *parent,
-                                           const QStyleOptionViewItem &option,
-                                           const QModelIndex &index) const
+QWidget* ParameterTuningDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option,
+                                               const QModelIndex& index) const
 {
-    if(m_isReadOnly)
+    if (m_isReadOnly)
         return nullptr;
 
     if (index.column() == m_valueColumn) {
-        if(index.parent().isValid() == false) return nullptr;
+        if (index.parent().isValid() == false)
+            return nullptr;
 
         QVariant data = index.model()->data(index, Qt::EditRole);
-        if(!data.isValid()) return nullptr;
-
-        double value = data.toDouble();
+        if (!data.isValid())
+            return nullptr;
 
-        m_currentItem = static_cast<ParameterItem*>(ParameterTuningModel::toSourceIndex(index).internalPointer());
-        if(!m_currentItem)
+        m_currentItem = static_cast<ParameterItem*>(
+            ParameterTuningModel::toSourceIndex(index).internalPointer());
+        if (!m_currentItem)
             return nullptr;
 
+        double value = data.toDouble();
         RealLimits limits = m_currentItem->linkedItem()->limits();
+        m_tuning_info.setItemLimits(limits);
+        m_tuning_info.value_to_slider(value);
 
         // initializing value box
-        m_valueBox = new QDoubleSpinBox();
+        m_valueBox = new ScientificSpinBox();
         m_valueBox->setKeyboardTracking(false);
-        m_valueBox->setFixedWidth(80);
+        m_valueBox->setFixedWidth(105);
         m_valueBox->setDecimals(m_currentItem->linkedItem()->decimals());
-        m_valueBox->setSingleStep(1./std::pow(10.,m_currentItem->linkedItem()->decimals()-1));
+        m_valueBox->setSingleStep(m_tuning_info.step());
 
-        if(limits.hasLowerLimit()) {
+        if (limits.hasLowerLimit()) {
             m_valueBox->setMinimum(limits.lowerLimit());
         } else {
             m_valueBox->setMinimum(minimum_doublespin_value);
         }
 
-        if(limits.hasUpperLimit()) {
-           m_valueBox->setMaximum(limits.upperLimit());
+        if (limits.hasUpperLimit()) {
+            m_valueBox->setMaximum(limits.upperLimit());
         } else {
             m_valueBox->setMaximum(maximum_doublespin_value);
         }
 
         m_valueBox->setValue(value);
-        connect(m_valueBox, SIGNAL(valueChanged(double)),this, SLOT(editorValueChanged(double)));
+        connect(m_valueBox, &ScientificSpinBox::valueChanged, this,
+                &ParameterTuningDelegate::editorValueChanged);
 
         // initializing slider
         m_slider = new QSlider(Qt::Horizontal);
@@ -182,8 +174,7 @@ QWidget *ParameterTuningDelegate::createEditor(QWidget *parent,
         m_slider->setTickPosition(QSlider::NoTicks);
         m_slider->setTickInterval(1);
         m_slider->setSingleStep(1);
-        m_slider_data.setItemLimits(limits);
-        m_slider->setRange(m_slider_data.m_smin, m_slider_data.m_smax);
+        m_slider->setRange(m_tuning_info.m_smin, m_tuning_info.m_smax);
 
         updateSlider(value);
 
@@ -195,16 +186,16 @@ QWidget *ParameterTuningDelegate::createEditor(QWidget *parent,
         m_contentLayout->addWidget(m_slider);
 
         // FIXME there is an issue with time of life of editor .vs. item
-//        m_currentItem->mapper()->setOnValueChange(
-//                      [this](){
-//            if(m_valueBox && m_currentItem)
-//              m_valueBox->setValue(m_currentItem->value().toDouble());
-//        }, this);
+        //        m_currentItem->mapper()->setOnValueChange(
+        //                      [this](){
+        //            if(m_valueBox && m_currentItem)
+        //              m_valueBox->setValue(m_currentItem->value().toDouble());
+        //        }, this);
 
-//        m_currentItem->mapper()->setOnItemDestroy(
-//                    [this](SessionItem *) {
-//            m_currentItem = 0;
-//        }, this);
+        //        m_currentItem->mapper()->setOnItemDestroy(
+        //                    [this](SessionItem *) {
+        //            m_currentItem = 0;
+        //        }, this);
 
         m_contentWidget->setLayout(m_contentLayout);
 
@@ -214,54 +205,53 @@ QWidget *ParameterTuningDelegate::createEditor(QWidget *parent,
     }
 }
 
-
 void ParameterTuningDelegate::updateSlider(double value) const
 {
-    disconnect(m_slider, SIGNAL(valueChanged(int)),this, SLOT(sliderValueChanged(int)));
+    disconnect(m_slider, &QSlider::valueChanged, this,
+               &ParameterTuningDelegate::sliderValueChanged);
 
-    m_slider->setValue(m_slider_data.value_to_slider(value));
+    m_slider->setValue(m_tuning_info.value_to_slider(value));
 
-    connect(m_slider, SIGNAL(valueChanged(int)),this, SLOT(sliderValueChanged(int)));
+    connect(m_slider, &QSlider::valueChanged, this,
+            &ParameterTuningDelegate::sliderValueChanged);
 }
 
-
 void ParameterTuningDelegate::sliderValueChanged(int position)
 {
-    disconnect(m_valueBox, SIGNAL(valueChanged(double)),this, SLOT(editorValueChanged(double)));
+    disconnect(m_valueBox, &ScientificSpinBox::valueChanged, this,
+               &ParameterTuningDelegate::editorValueChanged);
 
-    double value = m_slider_data.slider_to_value(position);
+    double value = m_tuning_info.slider_to_value(position);
     m_valueBox->setValue(value);
 
-    connect(m_valueBox, SIGNAL(valueChanged(double)),this, SLOT(editorValueChanged(double)));
+    connect(m_valueBox, &ScientificSpinBox::valueChanged, this,
+            &ParameterTuningDelegate::editorValueChanged);
     emitSignals(value);
 }
 
-
 void ParameterTuningDelegate::editorValueChanged(double value)
 {
-    disconnect(m_slider, SIGNAL(valueChanged(int)),this, SLOT(sliderValueChanged(int)));
+    disconnect(m_slider, &QSlider::valueChanged, this,
+               &ParameterTuningDelegate::sliderValueChanged);
 
     updateSlider(value);
 
-    connect(m_slider, SIGNAL(valueChanged(int)),this, SLOT(sliderValueChanged(int)));
+    connect(m_slider, &QSlider::valueChanged, this,
+            &ParameterTuningDelegate::sliderValueChanged);
     emitSignals(value);
 }
 
-
-void ParameterTuningDelegate::setEditorData(QWidget *editor,
-                                        const QModelIndex &index) const
+void ParameterTuningDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
 {
     if (index.column() == m_valueColumn) {
-        //as using custom widget, doing nothing here
+        // as using custom widget, doing nothing here
     } else {
         QItemDelegate::setEditorData(editor, index);
     }
 }
 
-
-void ParameterTuningDelegate::setModelData(QWidget *editor,
-                                       QAbstractItemModel *model,
-                                       const QModelIndex &index) const
+void ParameterTuningDelegate::setModelData(QWidget* editor, QAbstractItemModel* model,
+                                           const QModelIndex& index) const
 {
     if (index.column() == m_valueColumn) {
 
@@ -272,10 +262,9 @@ void ParameterTuningDelegate::setModelData(QWidget *editor,
     }
 }
 
-
 void ParameterTuningDelegate::emitSignals(double value)
 {
-    if(m_currentItem) {
+    if (m_currentItem) {
         m_currentItem->propagateValueToLink(value);
         emit currentLinkChanged(m_currentItem);
     }
@@ -283,7 +272,7 @@ void ParameterTuningDelegate::emitSignals(double value)
 
 void ParameterTuningDelegate::setSliderRangeFactor(double value)
 {
-    m_slider_data.setRangeFactor(value);
+    m_tuning_info.setRangeFactor(value);
 }
 
 void ParameterTuningDelegate::setReadOnly(bool isReadOnly)
diff --git a/GUI/coregui/Views/JobWidgets/ParameterTuningDelegate.h b/GUI/coregui/Views/JobWidgets/ParameterTuningDelegate.h
index 9458d75d6a96abbf338224bdfba69acc6b32e2dc..641b97c7c495c5b4cc511ec657f01863c8d02527 100644
--- a/GUI/coregui/Views/JobWidgets/ParameterTuningDelegate.h
+++ b/GUI/coregui/Views/JobWidgets/ParameterTuningDelegate.h
@@ -22,6 +22,7 @@
 class QDoubleSpinBox;
 class QHBoxLayout;
 class ParameterItem;
+class ScientificSpinBox;
 class SessionItem;
 
 class BA_CORE_API_ ParameterTuningDelegate : public QItemDelegate
@@ -29,13 +30,14 @@ class BA_CORE_API_ ParameterTuningDelegate : public QItemDelegate
     Q_OBJECT
 
 public:
-    class SliderData {
+    class TuningData {
     public:
-        SliderData();
+        TuningData();
         void setRangeFactor(double range_factor);
         void setItemLimits(const RealLimits &item_limits);
         int value_to_slider(double value);
         double slider_to_value(int slider);
+        double step() const;
         int m_smin;
         int m_smax;
         double m_rmin;
@@ -80,11 +82,11 @@ private:
 
     int m_valueColumn;
     mutable QSlider *m_slider;
-    mutable QDoubleSpinBox *m_valueBox;
+    mutable ScientificSpinBox* m_valueBox;
     mutable QWidget *m_contentWidget;
     mutable QHBoxLayout * m_contentLayout;
     mutable ParameterItem *m_currentItem;
-    mutable SliderData m_slider_data;
+    mutable TuningData m_tuning_info;
     bool m_isReadOnly;
 };
 
diff --git a/GUI/coregui/Views/JobWidgets/ScientificSpinBox.cpp b/GUI/coregui/Views/JobWidgets/ScientificSpinBox.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2f2ed6b4f2037e35b494d18e160991b7f3cb07ce
--- /dev/null
+++ b/GUI/coregui/Views/JobWidgets/ScientificSpinBox.cpp
@@ -0,0 +1,175 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/JobWidgets/ScientificSpinBox.cpp
+//! @brief     Implements class ScientificSpinBox
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "ScientificSpinBox.h"
+#include <cmath>
+#include <QLineEdit>
+
+namespace
+{
+const double upper_switch = 100;
+const double lower_switch = 0.1;
+const double min_val = std::numeric_limits<double>::min();
+const double max_val = std::numeric_limits<double>::max();
+
+bool useExponentialNotation(double val);
+} // namespace
+
+ScientificSpinBox::ScientificSpinBox(QWidget* parent)
+    : QAbstractSpinBox(parent)
+    , m_value(0.0)
+    , m_min(-max_val)
+    , m_max(max_val)
+    , m_step(1.0)
+    , m_decimals(3)
+{
+    QLocale locale;
+    locale.setNumberOptions(QLocale::RejectGroupSeparator);
+    m_validator.setLocale(locale);
+    m_validator.setNotation(QDoubleValidator::ScientificNotation);
+
+    connect(this, &QAbstractSpinBox::editingFinished, this, &ScientificSpinBox::updateValue);
+}
+
+ScientificSpinBox::~ScientificSpinBox() = default;
+
+double ScientificSpinBox::value() const
+{
+    return m_value;
+}
+
+void ScientificSpinBox::setValue(double val)
+{
+    double old_val = m_value;
+    m_value = round(val, m_decimals);
+    updateText();
+    if(std::abs(old_val - m_value) > min_val)
+        emit valueChanged(m_value);
+}
+
+void ScientificSpinBox::updateValue()
+{
+    double new_val = toDouble(text(), m_validator, m_min, m_max, m_value);
+    setValue(new_val);
+}
+
+double ScientificSpinBox::singleStep() const
+{
+    return m_step;
+}
+
+void ScientificSpinBox::setSingleStep(double step)
+{
+    m_step = step;
+}
+
+double ScientificSpinBox::minimum() const
+{
+    return m_min;
+}
+
+void ScientificSpinBox::setMinimum(double min)
+{
+    m_min = min;
+    if (m_value < m_min)
+        setValue(m_min);
+}
+
+double ScientificSpinBox::maximum() const
+{
+    return m_max;
+}
+
+void ScientificSpinBox::setMaximum(double max)
+{
+    m_max = max;
+    if (m_value > m_max)
+        setValue(m_max);
+}
+
+void ScientificSpinBox::setDecimals(int val)
+{
+    if (val <= 0)
+        return;
+    m_decimals = val;
+    setValue(m_value);
+}
+
+int ScientificSpinBox::decimals() const
+{
+    return m_decimals;
+}
+
+void ScientificSpinBox::stepBy(int steps)
+{
+    double new_val = round(m_value + m_step * steps, m_decimals);
+    if (inRange(new_val))
+        setValue(new_val);
+}
+
+QString ScientificSpinBox::toString(double val, int decimal_points)
+{
+    QString result = useExponentialNotation(val) ? QString::number(val, 'e', decimal_points)
+                                                 : QString::number(val, 'f', decimal_points);
+
+    return result.replace(QRegExp("(\\.?0+)?((e{1}[\\+|-]{1})(0+)?([1-9]{1}.*))?$"), "\\3\\5");
+}
+
+double ScientificSpinBox::toDouble(QString text, const QDoubleValidator& validator,
+                                   double min, double max, double default_value)
+{
+    int pos = 0;
+    if (validator.validate(text, pos) == QValidator::Acceptable) {
+        double new_val = validator.locale().toDouble(text);
+        if (std::abs(new_val) < min_val)
+            new_val = 0.0;
+        return new_val >= min && new_val <= max ? new_val : default_value;
+    }
+    return default_value;
+}
+
+double ScientificSpinBox::round(double val, int decimals)
+{
+    return QString::number(val, 'e', decimals).toDouble();
+}
+
+QAbstractSpinBox::StepEnabled ScientificSpinBox::stepEnabled() const
+{
+    return isReadOnly() ? StepNone : StepUpEnabled | StepDownEnabled;
+}
+
+void ScientificSpinBox::updateText()
+{
+    QString new_text = toString(m_value, m_decimals);
+    if (new_text != text())
+        lineEdit()->setText(new_text);
+}
+
+bool ScientificSpinBox::inRange(double val) const
+{
+    return val >= m_min && val <= m_max;
+}
+
+namespace
+{
+bool useExponentialNotation(double val)
+{
+    const double abs_val = std::abs(val);
+
+    if (abs_val <= min_val)
+        return false;
+
+    return abs_val >= upper_switch || abs_val < lower_switch;
+}
+} // namespace
diff --git a/GUI/coregui/Views/JobWidgets/ScientificSpinBox.h b/GUI/coregui/Views/JobWidgets/ScientificSpinBox.h
new file mode 100644
index 0000000000000000000000000000000000000000..e014abd4c51ceb34771be9506692860190b03417
--- /dev/null
+++ b/GUI/coregui/Views/JobWidgets/ScientificSpinBox.h
@@ -0,0 +1,72 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/JobWidgets/ScientificSpinBox.h
+//! @brief     Defines class ScientificSpinBox
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef SCIENTIFICSPINBOX_H
+#define SCIENTIFICSPINBOX_H
+
+#include "WinDllMacros.h"
+#include <QAbstractSpinBox>
+
+class BA_CORE_API_ ScientificSpinBox : public QAbstractSpinBox
+{
+    Q_OBJECT
+
+    Q_PROPERTY(double value MEMBER m_value READ value WRITE setValue NOTIFY valueChanged USER true)
+public:
+    ScientificSpinBox(QWidget* parent = nullptr);
+    ~ScientificSpinBox() override;
+
+    double value() const;
+    void setValue(double val);
+
+    double singleStep() const;
+    void setSingleStep(double step);
+
+    double minimum() const;
+    void setMinimum(double min);
+
+    double maximum() const;
+    void setMaximum(double max);
+
+    void setDecimals(int);
+    int decimals() const;
+
+    void stepBy(int steps) override;
+    QValidator::State validate(QString&, int&) const override {return QValidator::Acceptable;}
+    void fixup(QString&) const override {}
+
+
+    static QString toString(double val, int decimal_points);
+    static double toDouble(QString text, const QDoubleValidator& validator,
+                           double min, double max, double default_value);
+    static double round(double val, int decimals);
+
+signals:
+    void valueChanged(double value);
+
+protected:
+    QAbstractSpinBox::StepEnabled stepEnabled() const override;
+
+private:
+    void updateValue();
+    void updateText();
+    bool inRange(double val) const;
+
+    double m_value, m_min, m_max;
+    double m_step;
+    int m_decimals;
+    QDoubleValidator m_validator;
+};
+
+#endif // SCIENTIFICSPINBOX_H
diff --git a/GUI/coregui/Views/MaterialEditor/MaterialItemUtils.cpp b/GUI/coregui/Views/MaterialEditor/MaterialItemUtils.cpp
index 2c6bf138cdeeeb39c623abce11bd869d6caa830d..fb9d14fba6618144d1a3a5256291861fafdf4dd4 100644
--- a/GUI/coregui/Views/MaterialEditor/MaterialItemUtils.cpp
+++ b/GUI/coregui/Views/MaterialEditor/MaterialItemUtils.cpp
@@ -13,19 +13,33 @@
 // ************************************************************************** //
 
 #include "MaterialItemUtils.h"
-#include "MaterialDataItems.h"
+#include "AppSvc.h"
 #include "ComboProperty.h"
 #include "DesignerHelper.h"
 #include "GUIHelpers.h"
-#include "Material.h"
-#include "MaterialModel.h"
-#include "ParticleItem.h"
 #include "LayerItem.h"
+#include "Material.h"
+#include "MaterialDataItems.h"
 #include "MaterialEditorDialog.h"
-#include "AppSvc.h"
 #include "MaterialItem.h"
+#include "MaterialItemContainer.h"
+#include "MaterialModel.h"
+#include "MesoCrystalItem.h"
+#include "ParticleCompositionItem.h"
+#include "ParticleCoreShellItem.h"
+#include "ParticleDistributionItem.h"
+#include "ParticleItem.h"
+#include "ParticleLayoutItem.h"
 #include <QColorDialog>
 
+namespace
+{
+const std::map<QString, QString> tag_map = {
+    {Constants::ParticleCompositionType, ParticleCompositionItem::T_PARTICLES},
+    {Constants::ParticleDistributionType, ParticleDistributionItem::T_PARTICLES},
+    {Constants::ParticleLayoutType, ParticleLayoutItem::T_PARTICLES},
+    {Constants::MesoCrystalType, MesoCrystalItem::T_BASIS_PARTICLE}};
+}
 
 QColor MaterialItemUtils::suggestMaterialColor(const QString &name)
 {
@@ -60,19 +74,35 @@ ExternalProperty MaterialItemUtils::defaultMaterialProperty()
 
 std::unique_ptr<Material>
 MaterialItemUtils::createDomainMaterial(const ExternalProperty &material_property)
+{
+    MaterialItem* materialItem = findMaterial(material_property);
+    return materialItem->createMaterial();
+}
+
+std::unique_ptr<Material>
+MaterialItemUtils::createDomainMaterial(const ExternalProperty& material_property,
+                                        const MaterialItemContainer& container)
+{
+    const MaterialItem* material_item = container.findMaterialById(material_property.identifier());
+    if (!material_item)
+        throw GUIHelpers::Error("MaterialUtils::createDomainMaterial() -> Error. Can't find "
+                                "material with name '"
+                                + material_property.text() + "'.");
+    return material_item->createMaterial();
+}
+
+MaterialItem* MaterialItemUtils::findMaterial(const ExternalProperty& material_property)
 {
     if (!AppSvc::materialModel())
-        throw GUIHelpers::Error("MaterialItemUtils::createDomainMaterial() -> Error. "
+        throw GUIHelpers::Error("MaterialItemUtils::findMaterial() -> Error. "
                                 "Attempt to access non-existing material model");
 
-    MaterialItem *materialItem
-        = AppSvc::materialModel()->materialFromIdentifier(material_property.identifier());
+    auto material = AppSvc::materialModel()->materialFromIdentifier(material_property.identifier());
 
-    if(!materialItem)
-        throw GUIHelpers::Error("MaterialUtils::createDomainMaterial() -> Error. Can't create "
+    if(!material)
+        throw GUIHelpers::Error("MaterialUtils::findMaterial() -> Error. Can't find "
                                 "material with name '"+material_property.text()+"'.");
-
-    return materialItem->createMaterial();
+    return material;
 }
 
 //! Returns material tag for given item. Returns empty string, if item doesn't have materials.
@@ -142,3 +172,31 @@ ExternalProperty MaterialItemUtils::selectColorProperty(const ExternalProperty&
 
     return result;
 }
+
+QVector<SessionItem*> MaterialItemUtils::materialPropertyItems(SessionItem* item)
+{
+    QVector<SessionItem*> materials;
+    QList<SessionItem*> particle_holders{item};
+    while (!particle_holders.isEmpty()) {
+        auto item = particle_holders.takeFirst();
+        if (!item)
+            continue;
+
+        const QString model_type = item->modelType();
+        auto iter = tag_map.find(model_type);
+        if (iter != tag_map.end()) {
+            particle_holders.append(QList<SessionItem*>::fromVector(item->getItems(iter->second)));
+            continue;
+        }
+
+        if (model_type == Constants::ParticleType)
+            materials.append(static_cast<ParticleItem*>(item)->materialPropertyItems());
+        else if (model_type == Constants::ParticleCoreShellType)
+            materials.append(static_cast<ParticleCoreShellItem*>(item)->materialPropertyItems());
+        else
+            throw GUIHelpers::Error(
+                "Error in MaterialItemUtils::materialProperties: cannot handle passed model type '"
+                + model_type + "'");
+    }
+    return materials;
+}
diff --git a/GUI/coregui/Views/MaterialEditor/MaterialItemUtils.h b/GUI/coregui/Views/MaterialEditor/MaterialItemUtils.h
index ac948a215a7c0d0bf2bdbf6cc5d4447ebccb5356..8f07c149e0c3f5861bfc8718126c8c537fb22191 100644
--- a/GUI/coregui/Views/MaterialEditor/MaterialItemUtils.h
+++ b/GUI/coregui/Views/MaterialEditor/MaterialItemUtils.h
@@ -22,14 +22,20 @@
 #include <memory>
 
 class Material;
+class MaterialItemContainer;
 
 namespace MaterialItemUtils
 {
 
 BA_CORE_API_ QColor suggestMaterialColor(const QString &name);
 BA_CORE_API_ ExternalProperty defaultMaterialProperty();
-BA_CORE_API_ std::unique_ptr<Material> createDomainMaterial(
-        const ExternalProperty &material_property);
+
+BA_CORE_API_ std::unique_ptr<Material>
+createDomainMaterial(const ExternalProperty& material_property);
+BA_CORE_API_ std::unique_ptr<Material>
+createDomainMaterial(const ExternalProperty& material_property,
+                     const MaterialItemContainer& container);
+BA_CORE_API_ MaterialItem* findMaterial(const ExternalProperty& material_property);
 
 BA_CORE_API_ QString materialTag(const SessionItem &item);
 BA_CORE_API_ QStringList materialRelatedModelTypes();
@@ -46,6 +52,8 @@ BA_CORE_API_ ExternalProperty selectMaterialProperty(const ExternalProperty &pre
 //! Calls color selector dialog.
 BA_CORE_API_ ExternalProperty selectColorProperty(const ExternalProperty &previous=ExternalProperty());
 
+//! Gather material property items from a given item
+BA_CORE_API_ QVector<SessionItem*> materialPropertyItems(SessionItem* item);
 }
 
 
diff --git a/GUI/coregui/Views/PropertyEditor/ComponentEditor.cpp b/GUI/coregui/Views/PropertyEditor/ComponentEditor.cpp
index 24312bddfe1587cd20a5d24869f6af5202059c38..fe363a1412e7351568b48b23152e90b06e14e76d 100644
--- a/GUI/coregui/Views/PropertyEditor/ComponentEditor.cpp
+++ b/GUI/coregui/Views/PropertyEditor/ComponentEditor.cpp
@@ -79,7 +79,8 @@ void ComponentEditor::clearEditor()
 
 void ComponentEditor::addItem(SessionItem* item)
 {
-    m_item = item;
+    if (!m_item)
+        m_item = item;
     m_componentView->addItem(item);
 }
 
diff --git a/GUI/coregui/Views/PropertyEditor/CustomEditors.cpp b/GUI/coregui/Views/PropertyEditor/CustomEditors.cpp
index 8c8c0f9a0478eff44f7b0a7bd45de38254f2dca3..784380884ce8359694573de2671d5614f34ae25b 100644
--- a/GUI/coregui/Views/PropertyEditor/CustomEditors.cpp
+++ b/GUI/coregui/Views/PropertyEditor/CustomEditors.cpp
@@ -188,7 +188,8 @@ void ComboPropertyEditor::initEditor()
 
 QStringList ComboPropertyEditor::internLabels()
 {
-    Q_ASSERT(m_data.canConvert<ComboProperty>());
+    if (!m_data.canConvert<ComboProperty>())
+        return {};
     ComboProperty comboProperty = m_data.value<ComboProperty>();
     return comboProperty.getValues();
 }
@@ -197,7 +198,8 @@ QStringList ComboPropertyEditor::internLabels()
 
 int ComboPropertyEditor::internIndex()
 {
-    Q_ASSERT(m_data.canConvert<ComboProperty>());
+    if (!m_data.canConvert<ComboProperty>())
+        return 0;
     ComboProperty comboProperty = m_data.value<ComboProperty>();
     return comboProperty.currentIndex();
 }
@@ -360,7 +362,8 @@ void IntEditor::onEditingFinished()
 
 void IntEditor::initEditor()
 {
-    Q_ASSERT(m_data.type() == QVariant::Int);
+    if (!m_data.isValid() || m_data.type() != QVariant::Int)
+        return;
     m_intEditor->setValue(m_data.toInt());
 }
 
diff --git a/GUI/coregui/Views/PropertyEditor/MultiComboPropertyEditor.cpp b/GUI/coregui/Views/PropertyEditor/MultiComboPropertyEditor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c30dcbc6fd08c17b8bc5e9c60ffdf63354ff6b7a
--- /dev/null
+++ b/GUI/coregui/Views/PropertyEditor/MultiComboPropertyEditor.cpp
@@ -0,0 +1,195 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/PropertyEditor/MultiComboPropertyEditor.h
+//! @brief     Defines MultiComboPropertyEditor class
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "MultiComboPropertyEditor.h"
+#include "ComboProperty.h"
+#include "CustomEventFilters.h"
+#include <QComboBox>
+#include <QEvent>
+#include <QLineEdit>
+#include <QListView>
+#include <QMouseEvent>
+#include <QStandardItem>
+#include <QStandardItemModel>
+#include <QVBoxLayout>
+
+QCheckListStyledItemDelegate::QCheckListStyledItemDelegate(QObject* parent)
+    : QStyledItemDelegate(parent)
+{
+}
+
+void QCheckListStyledItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,
+                                         const QModelIndex& index) const
+{
+    QStyleOptionViewItem& styleOption = const_cast<QStyleOptionViewItem&>(option);
+    styleOption.showDecorationSelected = false;
+    QStyledItemDelegate::paint(painter, styleOption, index);
+}
+
+// ----------------------------------------------------------------------------
+// https://stackoverflow.com/questions/8422760/combobox-of-checkboxes
+// https://stackoverflow.com/questions/21186779/catch-mouse-button-pressed-signal-from-qcombobox-popup-menu
+// https://gist.github.com/mistic100/c3b7f3eabc65309687153fe3e0a9a720
+// ----------------------------------------------------------------------------
+
+MultiComboPropertyEditor::MultiComboPropertyEditor(QWidget* parent)
+    : CustomEditor(parent), m_box(new QComboBox), m_wheel_event_filter(new WheelEventEater(this)),
+      m_model(new QStandardItemModel(this))
+{
+    setAutoFillBackground(true);
+    setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+
+    m_box->installEventFilter(m_wheel_event_filter);
+    m_box->view()->viewport()->installEventFilter(this);
+
+    // Editable mode will be used to have None/Multiple labels on top
+    m_box->setEditable(true);
+    m_box->lineEdit()->setReadOnly(true);
+    m_box->lineEdit()->installEventFilter(this);
+    connect(m_box->lineEdit(), &QLineEdit::selectionChanged, m_box->lineEdit(),
+            &QLineEdit::deselect);
+
+    // transforms ordinary combo box into check list
+    m_box->setItemDelegate(new QCheckListStyledItemDelegate(this));
+    m_box->setModel(m_model);
+
+    auto layout = new QVBoxLayout;
+    layout->setMargin(0);
+    layout->setSpacing(0);
+    layout->addWidget(m_box);
+    setLayout(layout);
+    setConnected(true);
+}
+
+QSize MultiComboPropertyEditor::sizeHint() const
+{
+    return m_box->sizeHint();
+}
+
+QSize MultiComboPropertyEditor::minimumSizeHint() const
+{
+    return m_box->minimumSizeHint();
+}
+
+//! Propagate check state from the model to ComboProperty.
+
+void MultiComboPropertyEditor::onModelDataChanged(const QModelIndex& topLeft, const QModelIndex&,
+                                                  const QVector<int>&)
+{
+    // on Qt 5.9 roles remains empty for checked state. It will stop working if uncomment.
+    //    if (!roles.contains(Qt::CheckStateRole))
+    //        return;
+
+    auto item = m_model->itemFromIndex(topLeft);
+    if (!item)
+        return;
+
+    ComboProperty comboProperty = m_data.value<ComboProperty>();
+    auto state = item->checkState() == Qt::Checked ? true : false;
+    comboProperty.setSelected(topLeft.row(), state);
+
+    updateBoxLabel();
+    setDataIntern(QVariant::fromValue<ComboProperty>(comboProperty));
+}
+
+//! Processes press event in QComboBox's underlying list view.
+
+void MultiComboPropertyEditor::onClickedList(const QModelIndex& index)
+{
+    if (auto item = m_model->itemFromIndex(index)) {
+        auto state = item->checkState() == Qt::Checked ? Qt::Unchecked : Qt::Checked;
+        item->setCheckState(state);
+    }
+}
+
+//! Handles mouse clicks on QComboBox elements.
+
+bool MultiComboPropertyEditor::eventFilter(QObject* obj, QEvent* event)
+{
+    if (isClickToSelect(obj, event)) {
+        // Handles mouse clicks on QListView when it is expanded from QComboBox
+        // 1) Prevents list from closing while selecting items.
+        // 2) Correctly calculates underlying model index when mouse is over check box style
+        // element.
+        const auto mouseEvent = static_cast<const QMouseEvent*>(event);
+        auto index = m_box->view()->indexAt(mouseEvent->pos());
+        onClickedList(index);
+        return true;
+
+    } else if (isClickToExpand(obj, event)) {
+        // Expands box when clicking on None/Multiple label
+        m_box->showPopup();
+        return true;
+
+    } else {
+        // Propagate to the parent class.
+        return QObject::eventFilter(obj, event);
+    }
+}
+
+void MultiComboPropertyEditor::initEditor()
+{
+    if (!m_data.canConvert<ComboProperty>())
+        return;
+
+    ComboProperty property = m_data.value<ComboProperty>();
+
+    setConnected(false);
+    m_model->clear();
+
+    auto labels = property.getValues();
+    auto selectedIndices = property.selectedIndices();
+
+    for (int i = 0; i < labels.size(); ++i) {
+        auto item = new QStandardItem(labels[i]);
+        m_model->invisibleRootItem()->appendRow(item);
+        item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
+        item->setCheckable(true);
+
+        auto state = selectedIndices.contains(i) ? Qt::Checked : Qt::Unchecked;
+        item->setData(state, Qt::CheckStateRole);
+    }
+
+    setConnected(true);
+    updateBoxLabel();
+}
+
+void MultiComboPropertyEditor::setConnected(bool isConnected)
+{
+    if (isConnected) {
+        connect(m_model, &QStandardItemModel::dataChanged, this,
+                &MultiComboPropertyEditor::onModelDataChanged);
+    } else {
+        disconnect(m_model, &QStandardItemModel::dataChanged, this,
+                   &MultiComboPropertyEditor::onModelDataChanged);
+    }
+}
+
+//! Update text on QComboBox with the label provided by combo property.
+
+void MultiComboPropertyEditor::updateBoxLabel()
+{
+    ComboProperty combo = m_data.value<ComboProperty>();
+    m_box->setCurrentText(combo.label());
+}
+
+bool MultiComboPropertyEditor::isClickToSelect(QObject* obj, QEvent* event) const
+{
+    return obj == m_box->view()->viewport() && event->type() == QEvent::MouseButtonRelease;
+}
+
+bool MultiComboPropertyEditor::isClickToExpand(QObject* obj, QEvent* event) const
+{
+    return obj == m_box->lineEdit() && event->type() == QEvent::MouseButtonRelease;
+}
diff --git a/GUI/coregui/Views/PropertyEditor/MultiComboPropertyEditor.h b/GUI/coregui/Views/PropertyEditor/MultiComboPropertyEditor.h
new file mode 100644
index 0000000000000000000000000000000000000000..2015f271e0c0c40e3d022eccc81ddc85435d1deb
--- /dev/null
+++ b/GUI/coregui/Views/PropertyEditor/MultiComboPropertyEditor.h
@@ -0,0 +1,69 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/PropertyEditor/MultiComboPropertyEditor.h
+//! @brief     Defines MultiComboPropertyEditor class
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef MULTICOMBOPROPERTYEDITOR_H
+#define MULTICOMBOPROPERTYEDITOR_H
+
+#include "CustomEditors.h"
+#include <QStyledItemDelegate>
+#include <memory>
+
+class QStandardItemModel;
+class QModelIndex;
+class QStyleOptionViewItem;
+
+//! Provides custom editor for ComboProperty with multi-select option.
+
+class BA_CORE_API_ MultiComboPropertyEditor : public CustomEditor
+{
+    Q_OBJECT
+public:
+    explicit MultiComboPropertyEditor(QWidget* parent = nullptr);
+
+    QSize sizeHint() const;
+    QSize minimumSizeHint() const;
+
+protected slots:
+    void onModelDataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&);
+
+    void onClickedList(const QModelIndex& index);
+
+protected:
+    void initEditor();
+
+private:
+    bool eventFilter(QObject* obj, QEvent* event);
+    void setConnected(bool isConnected);
+    void updateBoxLabel();
+
+    bool isClickToSelect(QObject* obj, QEvent* event) const;
+    bool isClickToExpand(QObject* obj, QEvent* event) const;
+
+    QComboBox* m_box;
+    class WheelEventEater* m_wheel_event_filter;
+    QStandardItemModel* m_model;
+};
+
+//! Provides custom style delegate for QComboBox to allow checkboxes.
+
+class QCheckListStyledItemDelegate : public QStyledItemDelegate
+{
+public:
+    QCheckListStyledItemDelegate(QObject* parent = nullptr);
+
+    void paint(QPainter* painter, const QStyleOptionViewItem& option,
+               const QModelIndex& index) const;
+};
+
+#endif
diff --git a/GUI/coregui/Views/PropertyEditor/PropertyEditorFactory.cpp b/GUI/coregui/Views/PropertyEditor/PropertyEditorFactory.cpp
index 222ebe6b18f61ca63643beede08e35b9ed8a3ba6..5781cdcbe88c1039f59e5f1f6f93eb676e1c59c9 100644
--- a/GUI/coregui/Views/PropertyEditor/PropertyEditorFactory.cpp
+++ b/GUI/coregui/Views/PropertyEditor/PropertyEditorFactory.cpp
@@ -13,21 +13,23 @@
 // ************************************************************************** //
 
 #include "PropertyEditorFactory.h"
-#include "SessionItem.h"
-#include "RealLimits.h"
-#include "ExternalProperty.h"
-#include "GroupItemController.h"
-#include "CustomEditors.h"
 #include "ComboProperty.h"
+#include "CustomEditors.h"
 #include "CustomEventFilters.h"
-#include <QDoubleSpinBox>
-#include <QSpinBox>
-#include <QLineEdit>
+#include "ExternalProperty.h"
+#include "GroupItemController.h"
+#include "MultiComboPropertyEditor.h"
+#include "RealLimits.h"
+#include "ScientificSpinBox.h"
+#include "SessionItem.h"
 #include <QLabel>
+#include <QLineEdit>
+#include <QSpinBox>
 #include <limits>
 
 namespace {
 QWidget* createCustomStringEditor(const SessionItem& item);
+double getStep(double val);
 
 bool isDoubleProperty(const QVariant& variant)
 {
@@ -61,27 +63,40 @@ bool isBoolProperty(const QVariant& variant)
 
 }
 
-bool PropertyEditorFactory::IsCustomVariant(const QVariant& variant)
+bool PropertyEditorFactory::hasStringRepresentation(const QModelIndex& index)
 {
+    auto variant = index.data();
     if (isExternalProperty(variant))
         return true;
     if (isComboProperty(variant))
         return true;
     if (isBoolProperty(variant))
         return true;
+    if (isDoubleProperty(variant) && index.internalPointer())
+        return true;
 
     return false;
 }
 
-QString PropertyEditorFactory::ToString(const QVariant& variant)
+QString PropertyEditorFactory::toString(const QModelIndex& index)
 {
+    auto variant = index.data();
     if (isExternalProperty(variant))
         return variant.value<ExternalProperty>().text();
     if (isComboProperty(variant))
-        return variant.value<ComboProperty>().getValue();
+        return variant.value<ComboProperty>().label();
     if (isBoolProperty(variant))
         return variant.toBool() ? "True" : "False";
 
+    if (isDoubleProperty(variant) && index.internalPointer()) {
+        auto item = static_cast<SessionItem*>(index.internalPointer());
+        return item->editorType() == Constants::ScientificEditorType
+                  ? QString::number(item->value().toDouble(), 'g')
+                  : item->editorType() == Constants::ScientificSpinBoxType
+                  ? ScientificSpinBox::toString(item->value().toDouble(), item->decimals())
+                  : QString::number(item->value().toDouble(), 'f', item->decimals());
+    }
+
     return QString();
 }
 
@@ -95,25 +110,31 @@ QWidget* PropertyEditorFactory::CreateEditor(const SessionItem& item, QWidget* p
             auto editor = new ScientificDoublePropertyEditor;
             auto limits = item.limits();
             editor->setLimits(limits);
-            editor->setData(item.value());
+            result = editor;
+        } else if (item.editorType() == Constants::ScientificSpinBoxType) {
+            auto editor = new ScientificSpinBox;
+            auto limits = item.limits();
+            if (limits.hasLowerLimit())
+                editor->setMinimum(limits.lowerLimit());
+            if (limits.hasUpperLimit())
+                editor->setMaximum(limits.upperLimit());
+            editor->setDecimals(item.decimals());
+            editor->setSingleStep(getStep(item.data(Qt::EditRole).toDouble()));
             result = editor;
         } else {
             auto editor = new DoubleEditor;
             editor->setLimits(item.limits());
             editor->setDecimals(item.decimals());
-            editor->setData(item.value());
             result = editor;
         }
     }
     else if(isIntProperty(item.value())) {
         auto editor = new IntEditor;
         editor->setLimits(item.limits());
-        editor->setData(item.value());
         result = editor;
     }
     else if(isBoolProperty(item.value())) {
         auto editor = new BoolEditor;
-        editor->setData(item.value());
         result = editor;
     }
     else if(isStringProperty(item.value())) {
@@ -121,15 +142,18 @@ QWidget* PropertyEditorFactory::CreateEditor(const SessionItem& item, QWidget* p
     }
     else if(isExternalProperty(item.value())) {
         auto editor = new ExternalPropertyEditor;
-        editor->setData(item.value());
         if (item.editorType() != Constants::DefaultEditorType)
             editor->setExternalDialogType(item.editorType());
         result = editor;
     }
     else if(isComboProperty(item.value())) {
-        auto editor = new ComboPropertyEditor;
-        editor->setData(item.value());
-        result = editor;
+        if (item.editorType() == Constants::DefaultEditorType) {
+            auto editor = new ComboPropertyEditor;
+            result = editor;
+        } else if (item.editorType() == Constants::MultiSelectionComboEditorType) {
+            auto editor = new MultiComboPropertyEditor;
+            result = editor;
+        }
     }
     if (parent && result)
         result->setParent(parent);
@@ -158,5 +182,10 @@ QWidget* createCustomStringEditor(const SessionItem& item)
     return result;
 }
 
+double getStep(double val)
+{
+    return val == 0.0 ? 1.0 : val / 100.;
+}
+
 }
 
diff --git a/GUI/coregui/Views/PropertyEditor/PropertyEditorFactory.h b/GUI/coregui/Views/PropertyEditor/PropertyEditorFactory.h
index a72adc782c78a2be0012d4d9291a549b8d1d5fcd..bde0536ce164ff2f380cf63affae7fae7cce28e1 100644
--- a/GUI/coregui/Views/PropertyEditor/PropertyEditorFactory.h
+++ b/GUI/coregui/Views/PropertyEditor/PropertyEditorFactory.h
@@ -18,6 +18,7 @@
 #include "WinDllMacros.h"
 #include <QString>
 
+class QModelIndex;
 class QWidget;
 class SessionItem;
 class QVariant;
@@ -27,11 +28,11 @@ class QVariant;
 namespace PropertyEditorFactory
 {
 
-//! Returns true if the variant is one of our custom ones.
-BA_CORE_API_ bool IsCustomVariant(const QVariant& variant);
+//! Returns true if the index data has known (custom) convertion to string.
+BA_CORE_API_ bool hasStringRepresentation(const QModelIndex& index);
 
-//! Converts custom variant to string representation.
-BA_CORE_API_ QString ToString(const QVariant& variant);
+//! Provides string representation of index data.
+BA_CORE_API_ QString toString(const QModelIndex& index);
 
 //! Creates an editor suitable for editing of item.value()
 BA_CORE_API_ QWidget* CreateEditor(const SessionItem& item, QWidget* parent = nullptr);
diff --git a/GUI/coregui/Views/PropertyEditor/PropertyWidgetItem.cpp b/GUI/coregui/Views/PropertyEditor/PropertyWidgetItem.cpp
index 2ec96e3db31dc543f38b326a856b9abbdb3f862c..278653fdd6bf380df17021c5256c6d7a53b8b6e4 100644
--- a/GUI/coregui/Views/PropertyEditor/PropertyWidgetItem.cpp
+++ b/GUI/coregui/Views/PropertyEditor/PropertyWidgetItem.cpp
@@ -63,6 +63,10 @@ void PropertyWidgetItem::setItemEditor(const SessionItem* item, QWidget* editor)
     m_dataMapper->addMapping(m_editor, 1);
     m_dataMapper->setItemDelegate(m_delegate);
 
+    QModelIndex valueIndex = item->index().sibling(item->index().row(), 1);
+    if (valueIndex.isValid())
+        m_delegate->setEditorData(editor, valueIndex);
+
     connectEditor(editor);
 
     updateItemRoles();
diff --git a/GUI/coregui/Views/RealSpaceWidgets/RealSpace2DParacrystalUtils.cpp b/GUI/coregui/Views/RealSpaceWidgets/RealSpace2DParacrystalUtils.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..36cb464bbf84c610af280bdfacef60d546d9aca8
--- /dev/null
+++ b/GUI/coregui/Views/RealSpaceWidgets/RealSpace2DParacrystalUtils.cpp
@@ -0,0 +1,232 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/RealSpaceWidgets/RealSpaceBuilderUtils.h
+//! @brief     Defines RealSpaceBuilderUtils namespace
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "RealSpace2DParacrystalUtils.h"
+#include "FTDistributions2D.h"
+#include "InterferenceFunction2DParaCrystal.h"
+#include "Lattice2D.h"
+#include "RealSpaceCanvas.h"
+
+namespace
+{
+void resizeLatticePositions(std::vector<std::vector<double>>& lattice_positions, double l1,
+                            double l2, double layer_size)
+{
+    // Estimate the limit n1 and n2 of the integer multiple j and i of the lattice vectors l1 and l2
+    // required for populating particles correctly within the 3D model's boundaries
+    int n1 = 0, n2 = 0;
+    n1 = l1 == 0.0 ? 2 : static_cast<int>(layer_size * 2 / l1);
+    n2 = l2 == 0.0 ? 2 : static_cast<int>(layer_size * 2 / l2);
+
+    n1 = std::max(n1, n2);
+
+    lattice_positions.resize(static_cast<size_t>((2 * n1 + 1) * (2 * n1 + 1)));
+    for (auto& it : lattice_positions) {
+        it.resize(2);
+    }
+
+    lattice_positions[0][0] = 0.0; // x coordinate of reference particle - at the origin
+    lattice_positions[0][1] = 0.0; // y coordinate of reference particle - at the origin
+}
+
+void findLatticePositionsIndex(size_t& index, size_t& index_prev, int i, int j, int size,
+                               double l_alpha)
+{
+    index = static_cast<size_t>(i * (2 * size + 1) + j);
+
+    if (std::sin(l_alpha) == 0) // along l1
+    {
+        // particles along +l1 stored every odd iter (e.g. 1,3,5...) index of lattice_positions
+        // particles along -l1 stored every even iter (e.g. 2,4,6...) index of lattice_positions
+        index_prev = static_cast<size_t>(i * (2 * size + 1));
+        if (j - 2 > 0)
+            index_prev = index - 2;
+    } else // along l2
+    {
+        // particles along +l2/-l2 stored every (odd/even iter)*(2*n1+1) index of lattice_positions
+        index_prev = static_cast<size_t>(j);
+        if (i - 2 > 0)
+            index_prev = index - static_cast<size_t>(2 * (2 * size + 1));
+    }
+}
+
+std::pair<double, double> computePositionAlongPositiveLatticeVector(
+    const size_t index_prev, std::vector<std::vector<double>>& lattice_positions,
+    const IFTDistribution2D* pdf, double l, double l_xi, double l_alpha)
+{
+    double gamma_pdf = pdf->gamma();
+    std::pair<double, double> sampleXYpdf = pdf->createSampler()->randomSample();
+
+    double offset_x_pdf = sampleXYpdf.first;
+    double offset_y_pdf = sampleXYpdf.second;
+
+    double x = lattice_positions[index_prev][0] + l * std::cos(l_xi + l_alpha)
+               + offset_x_pdf * std::cos(gamma_pdf + l_xi)
+               + offset_y_pdf * std::cos(M_PI_2 + gamma_pdf + l_xi); // x coordinate
+    double y = lattice_positions[index_prev][1] + l * std::sin(l_xi + l_alpha)
+               + offset_x_pdf * std::sin(gamma_pdf + l_xi)
+               + offset_y_pdf * std::sin(M_PI_2 + gamma_pdf + l_xi); // y coordinate
+
+    return std::make_pair(x, y);
+}
+
+std::pair<double, double> computePositionAlongNegativeLatticeVector(
+    const size_t index_prev, std::vector<std::vector<double>>& lattice_positions,
+    const IFTDistribution2D* pdf, double l, double l_xi, double l_alpha)
+{
+    double gamma_pdf = pdf->gamma();
+    std::pair<double, double> sampleXYpdf = pdf->createSampler()->randomSample();
+
+    double offset_x_pdf = sampleXYpdf.first;
+    double offset_y_pdf = sampleXYpdf.second;
+
+    double x = lattice_positions[index_prev][0] - l * std::cos(l_xi + l_alpha)
+               + offset_x_pdf * std::cos(gamma_pdf + l_xi)
+               + offset_y_pdf * std::cos(M_PI_2 + gamma_pdf + l_xi); // x coordinate
+    double y = lattice_positions[index_prev][1] - l * std::sin(l_xi + l_alpha)
+               + offset_x_pdf * std::sin(gamma_pdf + l_xi)
+               + offset_y_pdf * std::sin(M_PI_2 + gamma_pdf + l_xi); // y coordinate
+
+    return std::make_pair(x, y);
+}
+
+std::pair<double, double>
+computeLatticePosition(const size_t index_prev, int i, int j,
+                       std::vector<std::vector<double>>& lattice_positions,
+                       const IFTDistribution2D* pdf, double l, double l_xi, double l_alpha)
+{
+    if (std::sin(l_alpha) == 0) {
+        if (!(j % 2 == 0)) // along +l1
+            return computePositionAlongPositiveLatticeVector(index_prev, lattice_positions, pdf, l,
+                                                             l_xi, 0);
+        else // along -l1
+            return computePositionAlongNegativeLatticeVector(index_prev, lattice_positions, pdf, l,
+                                                             l_xi, 0);
+    } else {
+        if (!(i % 2 == 0)) // along +l2
+            return computePositionAlongPositiveLatticeVector(index_prev, lattice_positions, pdf, l,
+                                                             l_xi, l_alpha);
+        else // along -l2
+            return computePositionAlongNegativeLatticeVector(index_prev, lattice_positions, pdf, l,
+                                                             l_xi, l_alpha);
+    }
+}
+
+void computePositionsAlongLatticeVectorAxes(std::vector<std::vector<double>>& lattice_positions,
+                                            const IFTDistribution2D* pdf, double l, double l_xi,
+                                            double l_alpha)
+{
+    int n = static_cast<int>((std::sqrt(lattice_positions.size()) - 1) / 2);
+
+    size_t index = 0;      // lattice_positions index for current particle
+    size_t index_prev = 0; // lattice_positions index for previous particle
+
+    std::pair<double, double> xy;
+
+    for (int iter = 1; iter <= 2 * n; ++iter) {
+
+        int iterl1, iterl2;
+
+        if (std::sin(l_alpha) == 0) {
+            iterl1 = iter;
+            iterl2 = 0;
+        } else {
+            iterl1 = 0;
+            iterl2 = iter;
+        }
+
+        // The 2*n+1 particles that are situated ONLY along the l1 axis (both +/- axes)
+        // are stored in i = 1,2,3,...2*n1 indices of lattice_positions
+
+        // The 2*n+1 particles that are situated ONLY along the l2 axis (both +/- axes)
+        // are stored every i*(2*n1+1) index of lattice_positions
+
+        findLatticePositionsIndex(index, index_prev, iterl2, iterl1, n, l_alpha);
+        xy = computeLatticePosition(index_prev, iterl2, iterl1, lattice_positions, pdf, l, l_xi,
+                                    l_alpha);
+
+        lattice_positions[index][0] = xy.first;  // x coordinate
+        lattice_positions[index][1] = xy.second; // y coordinate
+    }
+}
+
+void computePositionsInsideLatticeQuadrants(std::vector<std::vector<double>>& lattice_positions,
+                                            const IFTDistribution2D* pdf1,
+                                            const IFTDistribution2D* pdf2, double l1, double l2,
+                                            double l_xi, double l_alpha)
+{
+    int n = static_cast<int>((std::sqrt(lattice_positions.size()) - 1) / 2);
+
+    size_t index = 0;      // lattice_positions index for current particle
+    size_t index_prev = 0; // lattice_positions index for previous particle
+
+    std::pair<double, double> xy_l1, xy_l2;
+
+    for (int i = 1; i <= 2 * n; ++i) {
+        for (int j = 1; j <= 2 * n; ++j) {
+            findLatticePositionsIndex(index, index_prev, i, j, n, 0);
+            xy_l1 = computeLatticePosition(index_prev, i, j, lattice_positions, pdf1, l1, l_xi, 0);
+
+            findLatticePositionsIndex(index, index_prev, i, j, n, l_alpha);
+            xy_l2 = computeLatticePosition(index_prev, i, j, lattice_positions, pdf2, l2, l_xi,
+                                           l_alpha);
+
+            lattice_positions[index][0] = (xy_l1.first + xy_l2.first) / 2;
+            lattice_positions[index][1] = (xy_l1.second + xy_l2.second) / 2;
+        }
+    }
+}
+}
+
+RealSpace2DParacrystalUtils::RealSpace2DParacrystalUtils()
+    : m_interference2DParacrystal(nullptr), m_sceneGeometry(nullptr)
+{
+}
+
+RealSpace2DParacrystalUtils::~RealSpace2DParacrystalUtils()
+{
+}
+
+RealSpace2DParacrystalUtils::RealSpace2DParacrystalUtils(
+    const InterferenceFunction2DParaCrystal* interference2DParacrystal,
+    const SceneGeometry* sceneGeometry)
+{
+    m_interference2DParacrystal = interference2DParacrystal;
+    m_sceneGeometry = sceneGeometry;
+}
+
+std::vector<std::vector<double>> RealSpace2DParacrystalUtils::compute2DParacrystalLatticePositions()
+{
+    double l1 = m_interference2DParacrystal->lattice().length1(); // 1st lattice vector length
+    double l2 = m_interference2DParacrystal->lattice().length2(); // 2nd lattice vector length
+    double l_alpha = m_interference2DParacrystal->lattice().latticeAngle(); // angle between l1, l2
+    double l_xi
+        = m_interference2DParacrystal->lattice().rotationAngle(); // angle between l1, x axis
+    double layer_size = m_sceneGeometry->layer_size();
+
+    std::vector<std::vector<double>> lattice_positions;
+    resizeLatticePositions(lattice_positions, l1, l2, layer_size);
+
+    computePositionsAlongLatticeVectorAxes(lattice_positions, m_interference2DParacrystal->pdf1(),
+                                           l1, l_xi, 0);
+
+    computePositionsAlongLatticeVectorAxes(lattice_positions, m_interference2DParacrystal->pdf2(),
+                                           l2, l_xi, l_alpha);
+
+    computePositionsInsideLatticeQuadrants(lattice_positions, m_interference2DParacrystal->pdf1(),
+                                           m_interference2DParacrystal->pdf2(), l1, l2, l_xi,
+                                           l_alpha);
+
+    return lattice_positions;
+}
diff --git a/GUI/coregui/Views/RealSpaceWidgets/RealSpace2DParacrystalUtils.h b/GUI/coregui/Views/RealSpaceWidgets/RealSpace2DParacrystalUtils.h
new file mode 100644
index 0000000000000000000000000000000000000000..b0df6e2c232a86ed5d02f1ec6d0d878d6619fd73
--- /dev/null
+++ b/GUI/coregui/Views/RealSpaceWidgets/RealSpace2DParacrystalUtils.h
@@ -0,0 +1,40 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/RealSpaceWidgets/RealSpaceBuilderUtils.h
+//! @brief     Defines RealSpaceBuilderUtils namespace
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef REALSPACE2DPARACRYSTALUTILS_H
+#define REALSPACE2DPARACRYSTALUTILS_H
+
+#include "WinDllMacros.h"
+#include <vector>
+
+class InterferenceFunction2DParaCrystal;
+class SceneGeometry;
+
+class RealSpace2DParacrystalUtils
+{
+public:
+    RealSpace2DParacrystalUtils();
+    ~RealSpace2DParacrystalUtils();
+
+    RealSpace2DParacrystalUtils(const InterferenceFunction2DParaCrystal*,
+                                const SceneGeometry*);
+
+    std::vector<std::vector<double>> compute2DParacrystalLatticePositions();
+
+private:
+    const InterferenceFunction2DParaCrystal* m_interference2DParacrystal;
+    const SceneGeometry* m_sceneGeometry;
+};
+
+#endif // REALSPACE2DPARACRYSTALUTILS_H
diff --git a/GUI/coregui/Views/RealSpaceWidgets/RealSpaceBuilder.cpp b/GUI/coregui/Views/RealSpaceWidgets/RealSpaceBuilder.cpp
index 1f1ddbaba50c044ac10439efe5499680c932b82a..fbb0646d651cae832cbdade723fc019b7ce78a21 100644
--- a/GUI/coregui/Views/RealSpaceWidgets/RealSpaceBuilder.cpp
+++ b/GUI/coregui/Views/RealSpaceWidgets/RealSpaceBuilder.cpp
@@ -18,6 +18,7 @@
 #include "InterferenceFunctionItems.h"
 #include "Lattice2DItems.h"
 #include "LayerItem.h"
+#include "MesoCrystalItem.h"
 #include "MultiLayerItem.h"
 #include "Particle.h"
 #include "Particle3DContainer.h"
@@ -73,6 +74,9 @@ void RealSpaceBuilder::populate(RealSpaceModel* model, const SessionItem& item,
 
     else if (item.modelType() == Constants::ParticleDistributionType)
         populateParticleFromParticleItem(model, item);
+
+    else if (item.modelType() == Constants::MesoCrystalType)
+        populateParticleFromParticleItem(model, item);
 }
 
 void RealSpaceBuilder::populateMultiLayer(RealSpaceModel* model, const SessionItem& item,
@@ -151,19 +155,16 @@ void RealSpaceBuilder::populateInterference(
         RealSpaceBuilderUtils::populateInterference1DLatticeType(
             interference.get(), model, particle3DContainer_vector, sceneGeometry, this);
 
-    /*
-    // If interference type is 2D ParaCrystal
-    else if (interferenceLattice->modelType() == Constants::InterferenceFunction2DParaCrystalType)
-    {
-    }
-
     // If interference type is Radial ParaCrystal
-    else if (interferenceLattice->modelType() ==
-    Constants::InterferenceFunctionRadialParaCrystalType)
-    {
-    }
+    else if (interferenceLattice->modelType()
+             == Constants::InterferenceFunctionRadialParaCrystalType)
+        RealSpaceBuilderUtils::populateRadialParacrystalType(
+            interference.get(), model, particle3DContainer_vector, sceneGeometry, this);
 
-    */
+    // If interference type is 2D ParaCrystal
+    else if (interferenceLattice->modelType() == Constants::InterferenceFunction2DParaCrystalType)
+        RealSpaceBuilderUtils::populate2DParacrystalType(
+            interference.get(), model, particle3DContainer_vector, sceneGeometry, this);
 }
 
 void RealSpaceBuilder::populateParticleFromParticleItem(RealSpaceModel* model,
@@ -197,8 +198,13 @@ void RealSpaceBuilder::populateParticleFromParticleItem(RealSpaceModel* model,
         // If there is no particle to populate inside ParticleDistributionItem
         if (!particleDistributionItem->getItem(ParticleDistributionItem::T_PARTICLES))
             return;
-
         // show nothing when ParticleDistributionItem is selected
+    } else if (particleItem.modelType() == Constants::MesoCrystalType) {
+        auto mesoCrystalItem = dynamic_cast<const MesoCrystalItem*>(&particleItem);
+        // If there is no particle to populate inside MesoCrystalItem
+        if (!mesoCrystalItem->getItem(MesoCrystalItem::T_BASIS_PARTICLE))
+            return;
+        particle3DContainer = RealSpaceBuilderUtils::mesoCrystal3DContainer(*mesoCrystalItem);
     }
 
     populateParticleFromParticle3DContainer(model, particle3DContainer);
diff --git a/GUI/coregui/Views/RealSpaceWidgets/RealSpaceBuilderUtils.cpp b/GUI/coregui/Views/RealSpaceWidgets/RealSpaceBuilderUtils.cpp
index 830f6c2097b81c33541ee2f840df3dadc51902a3..20b811ae42863093164ed7c5b9d2887e27765b92 100644
--- a/GUI/coregui/Views/RealSpaceWidgets/RealSpaceBuilderUtils.cpp
+++ b/GUI/coregui/Views/RealSpaceWidgets/RealSpaceBuilderUtils.cpp
@@ -13,6 +13,7 @@
 // ************************************************************************** //
 
 #include "RealSpaceBuilderUtils.h"
+#include "FormFactorCrystal.h"
 #include "IFormFactorDecorator.h"
 #include "IParticle.h"
 #include "InterferenceFunctionItems.h"
@@ -21,6 +22,7 @@
 #include "LayerItem.h"
 #include "MaterialItem.h"
 #include "MaterialModel.h"
+#include "MesoCrystalItem.h"
 #include "MultiLayerItem.h"
 #include "Particle.h"
 #include "Particle3DContainer.h"
@@ -31,8 +33,10 @@
 #include "ParticleDistributionItem.h"
 #include "ParticleItem.h"
 #include "ParticleLayoutItem.h"
+#include "RealSpace2DParacrystalUtils.h"
 #include "RealSpaceBuilder.h"
 #include "RealSpaceCanvas.h"
+#include "RealSpaceMesoCrystalUtils.h"
 #include "RealSpaceModel.h"
 #include "RotationItems.h"
 #include "Rotations.h"
@@ -229,8 +233,103 @@ void RealSpaceBuilderUtils::populateInterference1DLatticeType(
                                         sceneGeometry, builder3D);
 }
 
+void RealSpaceBuilderUtils::populateRadialParacrystalType(
+    const IInterferenceFunction* interference, RealSpaceModel* model,
+    const std::vector<Particle3DContainer>& particle3DContainer_vector,
+    const SceneGeometry& sceneGeometry, const RealSpaceBuilder* builder3D)
+{
+    auto interferenceRadialParacrystal
+        = dynamic_cast<const InterferenceFunctionRadialParaCrystal*>(interference);
+    auto peakDistance = interferenceRadialParacrystal->peakDistance();
+
+    double layer_size = sceneGeometry.layer_size();
+    std::vector<std::vector<double>> lattice_positions;
+
+    // Estimate the limit n of the integer multiple i of the peakDistance required
+    // for populating particles correctly within the 3D model's boundaries
+    int n = static_cast<int>(layer_size * 2) / static_cast<int>(peakDistance);
+
+    lattice_positions.resize(static_cast<size_t>(2 * n + 1));
+    for (auto& it : lattice_positions) {
+        it.resize(2);
+    }
+
+    lattice_positions[0][0] = 0.0; // x coordinate of reference particle - at the origin
+    lattice_positions[0][1] = 0.0; // y coordinate of reference particle - at the origin
+
+    for (int i = 1; i <= 2 * n; ++i) {
+        // positions of particles located along +x (store every odd index of lattice_positions)
+        size_t k1 = 0;
+        if (i - 2 > 0)
+            k1 = static_cast<size_t>(i - 2);
+
+        double offset = interferenceRadialParacrystal->randomSample();
+        lattice_positions[static_cast<size_t>(i)][0]
+            = lattice_positions[k1][0] + peakDistance + offset; // x coordinate
+        lattice_positions[static_cast<size_t>(i)][1] = 0.0;     // y coordinate
+
+        // positions of particles located along -x (store every even index of lattice_positions)
+        ++i;
+
+        size_t k2 = 0;
+        if (i - 2 > 0)
+            k2 = static_cast<size_t>(i - 2);
+
+        offset = interferenceRadialParacrystal->randomSample();
+        lattice_positions[static_cast<size_t>(i)][0]
+            = lattice_positions[k2][0] - peakDistance + offset; // x coordinate
+        lattice_positions[static_cast<size_t>(i)][1] = 0.0;     // y coordinate
+    }
+
+    populateParticlesAtLatticePositions(lattice_positions, particle3DContainer_vector, model,
+                                        sceneGeometry, builder3D);
+}
+
+void RealSpaceBuilderUtils::populate2DParacrystalType(
+    const IInterferenceFunction* interference, RealSpaceModel* model,
+    const std::vector<Particle3DContainer>& particle3DContainer_vector,
+    const SceneGeometry& sceneGeometry, const RealSpaceBuilder* builder3D)
+{
+    auto interference2DParacrystal
+        = dynamic_cast<const InterferenceFunction2DParaCrystal*>(interference);
+
+    RealSpace2DParacrystalUtils paracrystal2D(interference2DParacrystal, &sceneGeometry);
+
+    std::vector<std::vector<double>> lattice_positions
+        = paracrystal2D.compute2DParacrystalLatticePositions();
+
+    populateParticlesAtLatticePositions(lattice_positions, particle3DContainer_vector, model,
+                                        sceneGeometry, builder3D);
+}
+
+//// Implement Rotation of a 3D particle using parameters from IRotation Object
+// QVector3D RealSpaceBuilderUtils::implementParticleRotationfromIRotation(const IRotation*&
+// rotation)
+//{
+//    double alpha = 0.0;
+//    double beta = 0.0;
+//    double gamma = 0.0;
+
+//    if (auto rotX = dynamic_cast<const RotationX*>(rotation)) {
+//        beta = rotX->getAngle(); // about x-axis
+//    } else if (auto rotY = dynamic_cast<const RotationY*>(rotation)) {
+//        alpha = Units::deg2rad(90.0);
+//        beta = rotY->getAngle(); // about y-axis
+//        gamma = Units::deg2rad(-90.0);
+//    } else if (auto rotZ = dynamic_cast<const RotationZ*>(rotation)) {
+//        alpha = rotZ->getAngle(); // about z-axis
+//    } else if (auto rotEuler = dynamic_cast<const RotationEuler*>(rotation)) {
+//        alpha = rotEuler->getAlpha();
+//        beta = rotEuler->getBeta();
+//        gamma = rotEuler->getGamma();
+//    }
+//    return QVector3D(static_cast<float>(alpha), static_cast<float>(beta),
+//                     static_cast<float>(gamma));
+//}
+
 // Implement Rotation of a 3D particle using parameters from IRotation Object
-QVector3D RealSpaceBuilderUtils::implementParticleRotationfromIRotation(const IRotation*& rotation)
+RealSpace::Vector3D
+RealSpaceBuilderUtils::implementParticleRotationfromIRotation(const IRotation*& rotation)
 {
     double alpha = 0.0;
     double beta = 0.0;
@@ -249,13 +348,13 @@ QVector3D RealSpaceBuilderUtils::implementParticleRotationfromIRotation(const IR
         beta = rotEuler->getBeta();
         gamma = rotEuler->getGamma();
     }
-    return QVector3D(static_cast<float>(alpha), static_cast<float>(beta),
-                     static_cast<float>(gamma));
+    return RealSpace::Vector3D(static_cast<float>(alpha), static_cast<float>(beta),
+                               static_cast<float>(gamma));
 }
 
 void RealSpaceBuilderUtils::applyParticleTransformations(const Particle& particle,
                                                          RealSpace::Particles::Particle& particle3D,
-                                                         const QVector3D& origin)
+                                                         const kvector_t& origin)
 {
     // rotation
     RealSpace::Vector3D particle_rotate;
@@ -268,7 +367,9 @@ void RealSpaceBuilderUtils::applyParticleTransformations(const Particle& particl
     float x = static_cast<float>(particle.position().x());
     float y = static_cast<float>(particle.position().y());
     float z = static_cast<float>(particle.position().z());
-    RealSpace::Vector3D position(x + origin.x(), y + origin.y(), z + origin.z());
+    RealSpace::Vector3D position(x + static_cast<float>(origin.x()),
+                                 y + static_cast<float>(origin.y()),
+                                 z + static_cast<float>(origin.z()));
 
     // If the particle belongs to a particle composition, along with the particle's
     // intrinsic transformations, position() and rotation() methods also account for the
@@ -280,7 +381,7 @@ void RealSpaceBuilderUtils::applyParticleTransformations(const Particle& particl
 
 void RealSpaceBuilderUtils::applyParticleCoreShellTransformations(
     const Particle& particle, RealSpace::Particles::Particle& particle3D,
-    const ParticleCoreShell& particleCoreShell, const QVector3D& origin)
+    const ParticleCoreShell& particleCoreShell, const kvector_t& origin)
 {
     std::unique_ptr<Particle> P_clone(particle.clone()); // clone of the current particle
 
@@ -301,9 +402,9 @@ void RealSpaceBuilderUtils::applyParticleCoreShellTransformations(
 
     P_clone->translate(positionCoreShell);
 
-    RealSpace::Vector3D position(static_cast<float>(P_clone->position().x()) + origin.x(),
-                                 static_cast<float>(P_clone->position().y()) + origin.y(),
-                                 static_cast<float>(P_clone->position().z()) + origin.z());
+    RealSpace::Vector3D position(static_cast<float>(P_clone->position().x() + origin.x()),
+                                 static_cast<float>(P_clone->position().y() + origin.y()),
+                                 static_cast<float>(P_clone->position().z() + origin.z()));
 
     particle3D.transform(particle_rotate, position);
 }
@@ -370,7 +471,15 @@ RealSpaceBuilderUtils::particle3DContainerVector(const SessionItem& layoutItem)
                 particle3DContainer_vector.emplace_back(std::move(pd_ContainerVector[i]));
             }
             continue;
+        } else if (particleItem->modelType() == Constants::MesoCrystalType) {
+            auto mesoCrystalItem = dynamic_cast<const MesoCrystalItem*>(particleItem);
+            // If there is no particle to populate inside MesoCrystalItem
+            if (!mesoCrystalItem->getItem(MesoCrystalItem::T_BASIS_PARTICLE))
+                continue;
+            particle3DContainer
+                = RealSpaceBuilderUtils::mesoCrystal3DContainer(*mesoCrystalItem, total_abundance);
         }
+
         cumulative_abundance += particle3DContainer.cumulativeAbundance();
         particle3DContainer.setCumulativeAbundance(cumulative_abundance);
         particle3DContainer_vector.emplace_back(std::move(particle3DContainer));
@@ -379,32 +488,44 @@ RealSpaceBuilderUtils::particle3DContainerVector(const SessionItem& layoutItem)
     return particle3DContainer_vector;
 }
 
-Particle3DContainer RealSpaceBuilderUtils::singleParticle3DContainer(const Particle& particle,
-                                                                     double total_abundance)
+Particle3DContainer
+RealSpaceBuilderUtils::singleParticle3DContainer(const Particle& particle, double total_abundance,
+                                                 const IRotation* extra_rotation,
+                                                 kvector_t extra_translation)
 {
-    std::unique_ptr<const IFormFactor> particleff(particle.createFormFactor());
+    std::unique_ptr<Particle> P_clone(particle.clone()); // clone of the particle
+    P_clone->rotate(*extra_rotation);
+    P_clone->translate(extra_translation);
+
+    std::unique_ptr<const IFormFactor> particleff(P_clone->createFormFactor());
     auto ff = getUnderlyingFormFactor(particleff.get());
 
     auto particle3D = TransformTo3D::createParticlefromIFormFactor(ff);
-    applyParticleTransformations(particle, *particle3D);
-    applyParticleColor(particle, *particle3D);
+    applyParticleTransformations(*P_clone, *particle3D);
+    applyParticleColor(*P_clone, *particle3D);
 
     Particle3DContainer singleParticle3DContainer;
     singleParticle3DContainer.addParticle(particle3D.release(), false);
-    singleParticle3DContainer.setCumulativeAbundance(particle.abundance() / total_abundance);
+    singleParticle3DContainer.setCumulativeAbundance(P_clone->abundance() / total_abundance);
     singleParticle3DContainer.setParticleType(Constants::ParticleType);
 
     return singleParticle3DContainer;
 }
 
-Particle3DContainer
-RealSpaceBuilderUtils::particleCoreShell3DContainer(const ParticleCoreShell& particleCoreShell,
-                                                    double total_abundance)
+Particle3DContainer RealSpaceBuilderUtils::particleCoreShell3DContainer(
+    const ParticleCoreShell& particleCoreShell, double total_abundance,
+    const IRotation* extra_rotation, kvector_t extra_translation)
 {
+    // clone of the particleCoreShell
+    std::unique_ptr<ParticleCoreShell> PCS_clone(particleCoreShell.clone());
+
+    PCS_clone->rotate(*extra_rotation);
+    PCS_clone->translate(extra_translation);
+
     std::unique_ptr<const IFormFactor> coreParticleff(
-        particleCoreShell.coreParticle()->createFormFactor());
+        PCS_clone->coreParticle()->createFormFactor());
     std::unique_ptr<const IFormFactor> shellParticleff(
-        particleCoreShell.shellParticle()->createFormFactor());
+        PCS_clone->shellParticle()->createFormFactor());
 
     auto coreff = getUnderlyingFormFactor(coreParticleff.get());
     auto shellff = getUnderlyingFormFactor(shellParticleff.get());
@@ -413,35 +534,38 @@ RealSpaceBuilderUtils::particleCoreShell3DContainer(const ParticleCoreShell& par
     auto shellParticle3D = TransformTo3D::createParticlefromIFormFactor(shellff);
 
     // core
-    applyParticleCoreShellTransformations(*particleCoreShell.coreParticle(), *coreParticle3D,
-                                          particleCoreShell);
-    applyParticleColor(*particleCoreShell.coreParticle(), *coreParticle3D);
+    applyParticleCoreShellTransformations(*PCS_clone->coreParticle(), *coreParticle3D, *PCS_clone);
+    applyParticleColor(*PCS_clone->coreParticle(), *coreParticle3D);
 
     // shell (set an alpha value of 0.5 for transparency)
-    applyParticleCoreShellTransformations(*particleCoreShell.shellParticle(), *shellParticle3D,
-                                          particleCoreShell);
-    applyParticleColor(*particleCoreShell.shellParticle(), *shellParticle3D, 0.5);
+    applyParticleCoreShellTransformations(*PCS_clone->shellParticle(), *shellParticle3D,
+                                          *PCS_clone);
+    applyParticleColor(*PCS_clone->shellParticle(), *shellParticle3D, 0.5);
 
     Particle3DContainer particleCoreShell3DContainer;
 
     particleCoreShell3DContainer.addParticle(coreParticle3D.release(), false); // index 0
     particleCoreShell3DContainer.addParticle(shellParticle3D.release(), true); // index 1
-    particleCoreShell3DContainer.setCumulativeAbundance(particleCoreShell.abundance()
-                                                        / total_abundance);
+    particleCoreShell3DContainer.setCumulativeAbundance(PCS_clone->abundance() / total_abundance);
     particleCoreShell3DContainer.setParticleType(Constants::ParticleCoreShellType);
 
     return particleCoreShell3DContainer;
 }
 
 Particle3DContainer RealSpaceBuilderUtils::particleComposition3DContainer(
-    const ParticleComposition& particleComposition, double total_abundance)
+    const ParticleComposition& particleComposition, double total_abundance,
+    const IRotation* extra_rotation, kvector_t extra_translation)
 {
-    SafePointerVector<IParticle> pc_vector = particleComposition.decompose();
+    // clone of the particleComposition
+    std::unique_ptr<ParticleComposition> PC_clone(particleComposition.clone());
+    PC_clone->rotate(*extra_rotation);
+    PC_clone->translate(extra_translation);
+
+    SafePointerVector<IParticle> pc_vector = PC_clone->decompose();
 
     Particle3DContainer particleComposition3DContainer;
 
     for (const IParticle* pc_particle : pc_vector) {
-
         Particle3DContainer particle3DContainer;
         // no abundances are associated with the individual components of ParticleComposition
         if (dynamic_cast<const ParticleCoreShell*>(pc_particle)) {
@@ -459,8 +583,7 @@ Particle3DContainer RealSpaceBuilderUtils::particleComposition3DContainer(
         }
     }
     // set the correct abundance for the entire ParticleComposition
-    particleComposition3DContainer.setCumulativeAbundance(particleComposition.abundance()
-                                                          / total_abundance);
+    particleComposition3DContainer.setCumulativeAbundance(PC_clone->abundance() / total_abundance);
     particleComposition3DContainer.setParticleType(Constants::ParticleCompositionType);
     return particleComposition3DContainer;
 }
@@ -489,3 +612,15 @@ std::vector<Particle3DContainer> RealSpaceBuilderUtils::particleDistribution3DCo
     }
     return particleDistribution3DContainer_vector;
 }
+
+Particle3DContainer RealSpaceBuilderUtils::mesoCrystal3DContainer(
+    const MesoCrystalItem& mesoCrystalItem, double total_abundance, const IRotation* extra_rotation,
+    kvector_t extra_translation)
+{
+    RealSpaceMesoCrystal mesoCrystalUtils(&mesoCrystalItem, total_abundance);
+
+    Particle3DContainer mesoCrystal3DContainer
+        = mesoCrystalUtils.populateMesoCrystal(extra_rotation, extra_translation);
+
+    return mesoCrystal3DContainer;
+}
diff --git a/GUI/coregui/Views/RealSpaceWidgets/RealSpaceBuilderUtils.h b/GUI/coregui/Views/RealSpaceWidgets/RealSpaceBuilderUtils.h
index e95a8ecf2e901c380636d5bd7caf388006537f6d..de165b4fa9e9b7d3a3f78cc85ad5fe8c05a55264 100644
--- a/GUI/coregui/Views/RealSpaceWidgets/RealSpaceBuilderUtils.h
+++ b/GUI/coregui/Views/RealSpaceWidgets/RealSpaceBuilderUtils.h
@@ -15,8 +15,10 @@
 #ifndef REALSPACEBUILDERUTILS_H
 #define REALSPACEBUILDERUTILS_H
 
+#include "Rotations.h"
 #include "WinDllMacros.h"
 #include <QVector3D>
+#include <Vectors3D.h>
 #include <memory>
 
 class RealSpaceModel;
@@ -24,14 +26,17 @@ class SessionItem;
 class SceneGeometry;
 class RealSpaceBuilder;
 class IRotation;
+class MesoCrystalItem;
 class Particle;
 class ParticleComposition;
 class ParticleCoreShell;
 class ParticleDistribution;
 class IInterferenceFunction;
 class Particle3DContainer;
+class InterferenceFunction2DParaCrystal;
 namespace RealSpace
 {
+struct Vector3D;
 namespace Particles
 {
 class Particle;
@@ -74,20 +79,34 @@ BA_CORE_API_ void populateInterference1DLatticeType(
     const std::vector<Particle3DContainer>& particle3DContainer_vector,
     const SceneGeometry& sceneGeometry, const RealSpaceBuilder* builder3D);
 
+// InterferenceFunctionRadialParacrystalType
+BA_CORE_API_ void
+populateRadialParacrystalType(const IInterferenceFunction* interference, RealSpaceModel* model,
+                              const std::vector<Particle3DContainer>& particle3DContainer_vector,
+                              const SceneGeometry& sceneGeometry,
+                              const RealSpaceBuilder* builder3D);
+
+// InterferenceFunction2DParacrystalType
+BA_CORE_API_ void
+populate2DParacrystalType(const IInterferenceFunction* interference, RealSpaceModel* model,
+                          const std::vector<Particle3DContainer>& particle3DContainer_vector,
+                          const SceneGeometry& sceneGeometry, const RealSpaceBuilder* builder3D);
+
 // Implement Rotation of a 3D particle using parameters from IRotation Object
-BA_CORE_API_ QVector3D implementParticleRotationfromIRotation(const IRotation*& rotation);
+BA_CORE_API_ RealSpace::Vector3D implementParticleRotationfromIRotation(const IRotation*& rotation);
 
 //! Apply transformations (translation, rotation) to a 3D Particle
 //! or to a particle belonging to a ParticleComposition
 BA_CORE_API_ void applyParticleTransformations(const Particle& particle,
                                                RealSpace::Particles::Particle& particle3D,
-                                               const QVector3D& origin = QVector3D());
+                                               const kvector_t& origin = kvector_t(0, 0, 0));
 
 //! Apply transformations (translation, rotation) to a particle (core/shell) in a ParticleCoreShell
 BA_CORE_API_ void applyParticleCoreShellTransformations(const Particle& particle,
                                                         RealSpace::Particles::Particle& particle3D,
                                                         const ParticleCoreShell& particleCoreShell,
-                                                        const QVector3D& origin = QVector3D());
+                                                        const kvector_t& origin
+                                                        = kvector_t(0, 0, 0));
 
 // Apply color to a 3D particle
 BA_CORE_API_ void applyParticleColor(const Particle& particle,
@@ -96,19 +115,30 @@ BA_CORE_API_ void applyParticleColor(const Particle& particle,
 BA_CORE_API_ std::vector<Particle3DContainer>
 particle3DContainerVector(const SessionItem& layoutItem);
 
-BA_CORE_API_ Particle3DContainer singleParticle3DContainer(const Particle& particle,
-                                                           double total_abundance = 1.0);
+BA_CORE_API_ Particle3DContainer
+singleParticle3DContainer(const Particle& particle, double total_abundance = 1.0,
+                          const IRotation* extra_rotation = IRotation::createIdentity(),
+                          kvector_t extra_translation = kvector_t(0, 0, 0));
 
 BA_CORE_API_ Particle3DContainer particleCoreShell3DContainer(
-    const ParticleCoreShell& particleCoreShell, double total_abundance = 1.0);
+    const ParticleCoreShell& particleCoreShell, double total_abundance = 1.0,
+    const IRotation* extra_rotation = IRotation::createIdentity(),
+    kvector_t extra_translation = kvector_t(0, 0, 0));
 
 BA_CORE_API_ Particle3DContainer particleComposition3DContainer(
-    const ParticleComposition& particleComposition3DContainer, double total_abundance = 1.0);
+    const ParticleComposition& particleComposition3DContainer, double total_abundance = 1.0,
+    const IRotation* extra_rotation = IRotation::createIdentity(),
+    kvector_t extra_translation = kvector_t(0, 0, 0));
 
 BA_CORE_API_ std::vector<Particle3DContainer>
 particleDistribution3DContainer(const ParticleDistribution& particleDistribution,
                                 double total_abundance = 1.0);
 
+BA_CORE_API_ Particle3DContainer
+mesoCrystal3DContainer(const MesoCrystalItem& mesoCrystalItem, double total_abundance = 1.0,
+                       const IRotation* extra_rotation = IRotation::createIdentity(),
+                       kvector_t extra_translation = kvector_t(0, 0, 0));
+
 } // namespace RealSpaceBuilderUtils
 
 #endif // REALSPACEBUILDERUTILS_H
diff --git a/GUI/coregui/Views/RealSpaceWidgets/RealSpaceCanvas.cpp b/GUI/coregui/Views/RealSpaceWidgets/RealSpaceCanvas.cpp
index 0d524b93e83507496966ad01673ba0e948bba523..225710b66e16983448d5cb355d36456431fba0d6 100644
--- a/GUI/coregui/Views/RealSpaceWidgets/RealSpaceCanvas.cpp
+++ b/GUI/coregui/Views/RealSpaceWidgets/RealSpaceCanvas.cpp
@@ -17,30 +17,24 @@
 #include "RealSpaceModel.h"
 #include "RealSpaceView.h"
 #include "SampleModel.h"
-#include "SessionGraphicsItem.h"
+#include "SessionItemUtils.h"
 #include "WarningSign.h"
-#include <FilterPropertyProxy.h>
+#include "FilterPropertyProxy.h"
 #include <QApplication>
 #include <QVBoxLayout>
 
 RealSpaceCanvas::RealSpaceCanvas(QWidget* parent)
-    : QWidget(parent), m_sampleModel(nullptr), m_view(new RealSpaceView), m_view_locked(false),
-      m_sceneGeometry(new SceneGeometry), m_warningSign(new WarningSign(this))
+    : QWidget(parent), m_sampleModel(nullptr), m_view(new RealSpaceView), m_selectionModel(nullptr),
+      m_view_locked(false), m_sceneGeometry(new SceneGeometry), m_warningSign(new WarningSign(this))
 {
-    QVBoxLayout* layout = new QVBoxLayout;
+    auto layout = new QVBoxLayout;
     layout->setMargin(0);
     layout->setSpacing(0);
     layout->addWidget(m_view);
     setLayout(layout);
-
-    // listening whether Lock View box in RealSpaceToolBar has been unchecked or not
-    // in order to display the current selection as soon as the box is unchecked
-    connect(this, &RealSpaceCanvas::lockViewUnchecked, this, &RealSpaceCanvas::updateToSelection);
 }
 
-RealSpaceCanvas::~RealSpaceCanvas()
-{
-}
+RealSpaceCanvas::~RealSpaceCanvas() = default;
 
 void RealSpaceCanvas::setModel(SampleModel* sampleModel, QItemSelectionModel* selectionModel)
 {
@@ -51,33 +45,37 @@ void RealSpaceCanvas::setModel(SampleModel* sampleModel, QItemSelectionModel* se
 
         m_sampleModel = sampleModel;
 
+        if (m_sampleModel)
+            setConnected(m_sampleModel, true);
+    }
+
+    if (selectionModel != m_selectionModel) {
+        if (m_selectionModel)
+            disconnect(m_selectionModel, &QItemSelectionModel::selectionChanged,
+                       this, &RealSpaceCanvas::onSelectionChanged);
+
         m_selectionModel = selectionModel;
 
-        if (m_sampleModel && !isHidden()) {
-            setConnected(m_sampleModel, true);
-            if (selectionModel != nullptr) {
-                QModelIndexList indices = m_selectionModel->selection().indexes();
-                if (indices.size())
-                    m_currentSelection = FilterPropertyProxy::toSourceIndex(indices.back());
-            }
-
-            if (!m_view_locked)
-                updateScene();
-        }
+        if (m_selectionModel)
+            connect(m_selectionModel, &QItemSelectionModel::selectionChanged,
+                    this, &RealSpaceCanvas::onSelectionChanged);
     }
+
+    updateToSelection();
 }
 
-void RealSpaceCanvas::onSelectionChanged(const QItemSelection& selection /* selection */,
-                                         const QItemSelection& /* deselection */)
+void RealSpaceCanvas::onSelectionChanged(const QItemSelection&, const QItemSelection&)
 {
-    // propagate selection from selectionChanged() signal to updateToSelection() method
-    updateToSelection(selection);
+    updateToSelection();
 }
 
-void RealSpaceCanvas::updateToSelection(const QItemSelection& selection)
+void RealSpaceCanvas::updateToSelection()
 {
+    if (!m_selectionModel)
+        return;
+
     if (!m_view_locked) {
-        QModelIndexList indices = selection.indexes();
+        QModelIndexList indices = m_selectionModel->selection().indexes();
 
         if (indices.size())
             m_currentSelection = FilterPropertyProxy::toSourceIndex(indices.back());
@@ -106,13 +104,10 @@ void RealSpaceCanvas::onTopViewAction()
 
 void RealSpaceCanvas::onLockViewAction(bool view_locked)
 {
-    // if Lock View box is unchecked i.e. previously it was checked (true) and now it's
-    // unchecked (false), then emit a signal to display the current selection on the canvas
-    if (m_view_locked && !view_locked) {
-        m_view_locked = view_locked;
-        emit lockViewUnchecked(m_selectionModel->selection());
-    } else
+    if (m_view_locked != view_locked) {
         m_view_locked = view_locked;
+        updateToSelection();
+    }
 }
 
 void RealSpaceCanvas::onChangeLayerSizeAction(double layerSizeChangeScale)
@@ -131,24 +126,18 @@ void RealSpaceCanvas::onDataChanged(const QModelIndex& index)
     if (!item)
         return;
 
-    if (!(item->modelType() == Constants::PropertyType
-          && (item->displayName() == SessionGraphicsItem::P_XPOS
-              || item->displayName() == SessionGraphicsItem::P_YPOS)))
+    if (!SessionItemUtils::IsPositionRelated(*item))
         updateScene();
 }
 
 void RealSpaceCanvas::updateScene()
 {
-    if (!m_currentSelection.isValid())
-        return;
-
     QApplication::setOverrideCursor(Qt::WaitCursor);
 
     m_realSpaceModel.reset(new RealSpaceModel);
-
-    SessionItem* item = m_sampleModel->itemForIndex(m_currentSelection);
-
-    Q_ASSERT(item);
+    auto item = m_sampleModel->itemForIndex(m_currentSelection);
+    if (!item)
+        return;
 
     RealSpaceBuilder builder3D;
 
@@ -195,17 +184,6 @@ void RealSpaceCanvas::topView()
     m_view->topView();
 }
 
-void RealSpaceCanvas::showEvent(QShowEvent*)
-{
-    setConnected(m_sampleModel, true);
-    updateScene();
-}
-
-void RealSpaceCanvas::hideEvent(QHideEvent*)
-{
-    setConnected(m_sampleModel, false);
-}
-
 void RealSpaceCanvas::setConnected(SampleModel* model, bool makeConnected)
 {
     if (!model)
@@ -220,8 +198,8 @@ void RealSpaceCanvas::setConnected(SampleModel* model, bool makeConnected)
                 Qt::UniqueConnection);
         connect(model, &SampleModel::modelReset, this, &RealSpaceCanvas::resetScene,
                 Qt::UniqueConnection);
-        connect(model, &SampleModel::modelAboutToBeReset, this, [&](){ m_currentSelection = QModelIndex();},
-                Qt::UniqueConnection);
+        connect(model, &SampleModel::modelAboutToBeReset, this,
+                [&]() { m_currentSelection = QModelIndex(); }, Qt::UniqueConnection);
 
     } else {
         disconnect(model, &SampleModel::rowsInserted, this, &RealSpaceCanvas::updateScene);
diff --git a/GUI/coregui/Views/RealSpaceWidgets/RealSpaceCanvas.h b/GUI/coregui/Views/RealSpaceWidgets/RealSpaceCanvas.h
index 66fee97bcba77172b90046575c769c1fbf0a2b5e..16ed6aa0c308ea9829c0c84af47e27008721ee00 100644
--- a/GUI/coregui/Views/RealSpaceWidgets/RealSpaceCanvas.h
+++ b/GUI/coregui/Views/RealSpaceWidgets/RealSpaceCanvas.h
@@ -88,12 +88,9 @@ public:
     void setModel(SampleModel* sampleModel = nullptr,
                   QItemSelectionModel* selectionModel = nullptr);
 
-signals:
-    void lockViewUnchecked(const QItemSelection&);
-
 public slots:
-    void onSelectionChanged(const QItemSelection& selection, const QItemSelection&);
-    void updateToSelection(const QItemSelection& selection);
+    void onSelectionChanged(const QItemSelection&, const QItemSelection&);
+    void updateToSelection();
 
     void onDefaultViewAction();
     void onSideViewAction();
@@ -110,10 +107,6 @@ private slots:
     void sideView();
     void topView();
 
-protected:
-    virtual void showEvent(QShowEvent*);
-    virtual void hideEvent(QHideEvent*);
-
 private:
     void setConnected(SampleModel* model, bool makeConnected);
 
diff --git a/GUI/coregui/Views/RealSpaceWidgets/RealSpaceDialog.cpp b/GUI/coregui/Views/RealSpaceWidgets/RealSpaceDialog.cpp
deleted file mode 100644
index f541b948d0c5945e57e49de3925e8faa83729398..0000000000000000000000000000000000000000
--- a/GUI/coregui/Views/RealSpaceWidgets/RealSpaceDialog.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      GUI/coregui/Views/RealSpaceWidgets/RealSpaceDialog.cpp
-//! @brief     Implements class RealSpaceDialog
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "RealSpaceDialog.h"
-#include "RealSpaceWidget.h"
-#include "StyleUtils.h"
-#include <QAction>
-#include <QPushButton>
-#include <QSettings>
-#include <QVBoxLayout>
-#include "mainwindow_constants.h"
-
-namespace
-{
-    const QSize minimum_dialog_size(400, 250);
-    const QSize default_dialog_size(500, 400);
-}
-
-RealSpaceDialog::RealSpaceDialog(SampleModel *sampleModel,
-                                             QItemSelectionModel* selectionModel, QWidget *parent)
-    : QWidget(parent)
-    , m_sampleModel(sampleModel)
-    , m_selectionModel(selectionModel)
-{
-    setWindowTitle("Real Space Viewer");
-    setMinimumSize(minimum_dialog_size);
-    resize(default_dialog_size);
-    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
-    setWindowFlags(windowFlags() | Qt::Window | Qt::WindowStaysOnTopHint);
-
-    // read the user's last persistent settings (size and position) of the dialog box
-    readSettings();
-
-    QVBoxLayout *layout = new QVBoxLayout;
-    layout->setMargin(0);
-    layout->setSpacing(0);
-    //layout->setContentsMargins(0, 0, 0, 0);
-
-    #ifdef BORNAGAIN_OPENGL
-    RealSpaceWidget* widget = new RealSpaceWidget(m_sampleModel, m_selectionModel);
-    widget->setModel(m_sampleModel, m_selectionModel);
-    layout->addWidget(widget);
-    #endif
-
-    setLayout(layout);
-    setAttribute(Qt::WA_DeleteOnClose, true);
-}
-
-void RealSpaceDialog::closeEvent(QCloseEvent *)
-{
-    // on close event, remember the settings (size and position) of the dialog box as persistent
-    writeSettings();
-}
-
-void RealSpaceDialog::readSettings()
-{
-    QSettings settings;
-    if (settings.childGroups().contains(Constants::S_REALSPACEDIALOG)) {
-        settings.beginGroup(Constants::S_REALSPACEDIALOG);
-        resize(settings.value(Constants::S_WINDOWSIZE, default_dialog_size).toSize());
-        if (settings.contains(Constants::S_WINDOWPOSITION)) {
-            move(settings.value(Constants::S_WINDOWPOSITION).toPoint());
-        }
-    } else {
-        resize(default_dialog_size);
-    }
-}
-
-void RealSpaceDialog::writeSettings()
-{
-    QSettings settings;
-    settings.beginGroup(Constants::S_REALSPACEDIALOG);
-    settings.setValue(Constants::S_WINDOWSIZE, this->size());
-    settings.setValue(Constants::S_WINDOWPOSITION, this->pos());
-    settings.endGroup();
-}
diff --git a/GUI/coregui/Views/RealSpaceWidgets/RealSpaceDialog.h b/GUI/coregui/Views/RealSpaceWidgets/RealSpaceDialog.h
deleted file mode 100644
index 03e4eb86b65bfb470327b9f5914b5f86a2c7f40f..0000000000000000000000000000000000000000
--- a/GUI/coregui/Views/RealSpaceWidgets/RealSpaceDialog.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      GUI/coregui/Views/RealSpaceWidgets/RealSpaceDialog.h
-//! @brief     Implements class RealSpaceDialog
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef REALSPACEDIALOG_H
-#define REALSPACEDIALOG_H
-
-#include "WinDllMacros.h"
-#include <QDialog>
-#include <memory>
-#include <SampleModel.h>
-#include <QTreeView>
-
-class MaterialModel;
-class MaterialEditor;
-class ExternalProperty;
-class QBoxLayout;
-
-//! Dialog to hold RealSpaceWidget.
-
-class BA_CORE_API_ RealSpaceDialog : public QWidget
-{
-    Q_OBJECT
-
-public:
-    RealSpaceDialog(SampleModel* sampleModel = nullptr,
-                          QItemSelectionModel* selectionModel = nullptr,
-                          QWidget *parent = nullptr);
-
-public slots:
-    void closeEvent(QCloseEvent*);
-
-private:
-    void readSettings();
-    void writeSettings();
-
-    SampleModel *m_sampleModel;
-    QItemSelectionModel *m_selectionModel;
-};
-
-
-#endif // REALSPACEDIALOG_H
diff --git a/GUI/coregui/Views/RealSpaceWidgets/RealSpaceMesoCrystalUtils.cpp b/GUI/coregui/Views/RealSpaceWidgets/RealSpaceMesoCrystalUtils.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4f57173783e46763d4d826577e62a5cb222dcb4d
--- /dev/null
+++ b/GUI/coregui/Views/RealSpaceWidgets/RealSpaceMesoCrystalUtils.cpp
@@ -0,0 +1,409 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/RealSpaceWidgets/RealSpaceBuilderUtils.h
+//! @brief     Defines RealSpaceBuilderUtils namespace
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "RealSpaceMesoCrystalUtils.h"
+#include "Exceptions.h"
+#include "HardParticles.h"
+#include "IFormFactor.h"
+#include "IParticle.h"
+#include "Lattice2DItems.h"
+#include "MesoCrystal.h"
+#include "MesoCrystalItem.h"
+#include "Particle.h"
+#include "Particle3DContainer.h"
+#include "ParticleCompositionItem.h"
+#include "ParticleCoreShell.h"
+#include "ParticleCoreShellItem.h"
+#include "ParticleDistribution.h"
+#include "ParticleDistributionItem.h"
+#include "RealSpaceBuilderUtils.h"
+#include "TransformTo3D.h"
+#include "Units.h"
+#include <ba3d/model/particles.h>
+
+namespace
+{
+const int n = 10; // TODO: Adjust this parameter based on the size of the mesocrystal
+
+bool isPositionInsideMesoCrystal(const IFormFactor* outerShape, kvector_t positionInside)
+{
+    bool check(false);
+    if (auto ff_AnisoPyramid = dynamic_cast<const FormFactorAnisoPyramid*>(outerShape)) {
+        double L = ff_AnisoPyramid->getLength();
+        double W = ff_AnisoPyramid->getWidth();
+        double H = ff_AnisoPyramid->getHeight();
+        double alpha = ff_AnisoPyramid->getAlpha();
+
+        double l_z
+            = L / 2
+              - positionInside.z() / std::tan(alpha); // half-length of rectangle at a given height
+        double w_z
+            = W / 2
+              - positionInside.z() / std::tan(alpha); // half-width of rectangle at a given height
+        if (std::abs(positionInside.x()) <= l_z && std::abs(positionInside.y()) <= w_z
+            && (positionInside.z() >= 0 && positionInside.z() <= H))
+            check = true;
+    } else if (auto ff_Box = dynamic_cast<const FormFactorBox*>(outerShape)) {
+        double L = ff_Box->getLength();
+        double W = ff_Box->getWidth();
+        double H = ff_Box->getHeight();
+
+        if (std::abs(positionInside.x()) <= L / 2 && std::abs(positionInside.y()) <= W / 2
+            && (positionInside.z() >= 0 && positionInside.z() <= H))
+            check = true;
+    } else if (auto ff_Cone = dynamic_cast<const FormFactorCone*>(outerShape)) {
+        double R = ff_Cone->getRadius();
+        double H = ff_Cone->getHeight();
+        double alpha = ff_Cone->getAlpha();
+
+        if (std::abs(positionInside.x()) > R || std::abs(positionInside.y()) > R
+            || positionInside.z() < 0 || positionInside.z() > H)
+            return check;
+
+        double R_z = R - positionInside.z() / std::tan(alpha);
+        if (std::pow(positionInside.x() / R_z, 2) + std::pow(positionInside.y() / R_z, 2) <= 1)
+            check = true;
+    } else if (auto ff_Cone6 = dynamic_cast<const FormFactorCone6*>(outerShape)) {
+        double B = ff_Cone6->getBaseEdge();
+        double H = ff_Cone6->getHeight();
+        double alpha = ff_Cone6->getAlpha();
+
+        if (std::abs(positionInside.x()) > B || std::abs(positionInside.y()) > B
+            || positionInside.z() < 0 || positionInside.z() > H)
+            return check;
+
+        double l_z = B - positionInside.z() / std::tan(alpha); // edge of hexagon at a given height
+        double theta_prime = 0; // angle between positionInside & x-axis in positionInside.z() plane
+        if (positionInside.x() != 0 || positionInside.y() != 0)
+            theta_prime = Units::rad2deg(std::asin(
+                std::abs(positionInside.y())
+                / std::sqrt(std::pow(positionInside.x(), 2) + std::pow(positionInside.y(), 2))));
+        int c = static_cast<int>(theta_prime / 60); // multiplication constant
+        double theta = Units::deg2rad(theta_prime - c * 60);
+        double k_z = l_z / (std::cos(theta) + std::sin(theta) / std::tan(M_PI / 3));
+
+        if (std::pow(positionInside.x(), 2) + std::pow(positionInside.y(), 2) <= std::pow(k_z, 2))
+            check = true;
+    } else if (auto ff_Cuboctahedron = dynamic_cast<const FormFactorCuboctahedron*>(outerShape)) {
+        double L = ff_Cuboctahedron->getLength();
+        double H = ff_Cuboctahedron->getHeight();
+        double rH = ff_Cuboctahedron->getHeightRatio();
+        double alpha = ff_Cuboctahedron->getAlpha();
+
+        double total_Height = H + rH * H;
+
+        if (std::abs(positionInside.x()) > L / 2 || std::abs(positionInside.y()) > L / 2
+            || positionInside.z() < 0 || positionInside.z() > total_Height)
+            return check;
+
+        // half-length of square (i.e. horizontal cross-section of Cuboctahedron) at a given height
+        double l_z = L / 2 - std::abs(H - positionInside.z()) / std::tan(alpha);
+        if (std::abs(positionInside.x()) <= l_z && std::abs(positionInside.y()) <= l_z)
+            check = true;
+    } else if (auto ff_Cylinder = dynamic_cast<const FormFactorCylinder*>(outerShape)) {
+        double R = ff_Cylinder->getRadius();
+        double H = ff_Cylinder->getHeight();
+
+        if (std::abs(positionInside.x()) > R || std::abs(positionInside.y()) > R
+            || positionInside.z() < 0 || positionInside.z() > H)
+            return check;
+
+        if (std::pow(positionInside.x() / R, 2) + std::pow(positionInside.y() / R, 2) <= 1)
+            check = true;
+    } else if (dynamic_cast<const FormFactorDodecahedron*>(outerShape)) {
+        // TODO: Implement Dodecahedron
+        std::ostringstream ostr;
+        ostr << "Sorry, outer shape Dodecahedron not yet implemented for Mesocrystal";
+        ostr << "\n\nStay tuned!";
+        throw Exceptions::ClassInitializationException(ostr.str());
+    } else if (dynamic_cast<const FormFactorDot*>(outerShape)) {
+        std::ostringstream ostr;
+        ostr << "Cannot display particles inside the Mesocrystal!";
+        ostr << "\n\nOuter shape is a Dot!";
+        throw Exceptions::ClassInitializationException(ostr.str());
+    } else if (auto ff_EllipsoidalCylinder
+               = dynamic_cast<const FormFactorEllipsoidalCylinder*>(outerShape)) {
+        double a = ff_EllipsoidalCylinder->getRadiusX(); // semi-axis length along x
+        double b = ff_EllipsoidalCylinder->getRadiusY(); // semi-axis length along y
+        double H = ff_EllipsoidalCylinder->getHeight();
+
+        if (std::abs(positionInside.x()) > a || std::abs(positionInside.y()) > b
+            || positionInside.z() < 0 || positionInside.z() > H)
+            return check;
+
+        if (std::pow(positionInside.x() / a, 2) + std::pow(positionInside.y() / b, 2) <= 1)
+            check = true;
+    } else if (auto ff_FullSphere = dynamic_cast<const FormFactorFullSphere*>(outerShape)) {
+        double R = ff_FullSphere->getRadius();
+
+        if (std::abs(positionInside.x()) > R || std::abs(positionInside.y()) > R
+            || positionInside.z() < 0 || positionInside.z() > 2 * R)
+            return check;
+
+        if (std::pow(positionInside.x() / R, 2) + std::pow(positionInside.y() / R, 2)
+                + std::pow((positionInside.z() - R) / R, 2)
+            <= 1)
+            check = true;
+    } else if (auto ff_FullSpheroid = dynamic_cast<const FormFactorFullSpheroid*>(outerShape)) {
+        double a = ff_FullSpheroid->getRadius(); // semi-axis length along x and y
+        double H = ff_FullSpheroid->getHeight();
+        double c = H / 2; // semi-axis length along z
+
+        if (std::abs(positionInside.x()) > a || std::abs(positionInside.y()) > a
+            || positionInside.z() < 0 || positionInside.z() > H)
+            return check;
+
+        if (std::pow(positionInside.x() / a, 2) + std::pow(positionInside.y() / a, 2)
+                + std::pow((positionInside.z() - c) / c, 2)
+            <= 1)
+            check = true;
+    } else if (auto ff_HemiEllipsoid = dynamic_cast<const FormFactorHemiEllipsoid*>(outerShape)) {
+        double a = ff_HemiEllipsoid->getRadiusX(); // semi-axis length along x
+        double b = ff_HemiEllipsoid->getRadiusY(); // semi-axis length along y
+        double c = ff_HemiEllipsoid->getHeight();  // semi-axis length along z
+
+        if (std::abs(positionInside.x()) > a || std::abs(positionInside.y()) > b
+            || positionInside.z() < 0 || positionInside.z() > c)
+            return check;
+
+        if (std::pow(positionInside.x() / a, 2) + std::pow(positionInside.y() / b, 2)
+                + std::pow(positionInside.z() / c, 2)
+            <= 1)
+            check = true;
+    } else if (dynamic_cast<const FormFactorIcosahedron*>(outerShape)) {
+        // TODO: Implement Icosahedron
+        std::ostringstream ostr;
+        ostr << "Sorry, outer shape Icosahedron not yet implemented for Mesocrystal";
+        ostr << "\n\nStay tuned!";
+        throw Exceptions::ClassInitializationException(ostr.str());
+    } else if (auto ff_Prism3 = dynamic_cast<const FormFactorPrism3*>(outerShape)) {
+        double B = ff_Prism3->getBaseEdge();
+        double H = ff_Prism3->getHeight();
+
+        double l = B * std::sin(M_PI / 3);
+        double x_shift = B / 2 * std::tan(M_PI / 6);
+
+        if (positionInside.x() + x_shift < 0 || positionInside.x() + x_shift > l
+            || std::abs(positionInside.y()) > B / 2 || positionInside.z() < 0
+            || positionInside.z() > H)
+            return check;
+
+        double theta = 0; // angle between positionInside & x-axis in positionInside.z() plane
+        if (positionInside.x() + x_shift != 0 || positionInside.y() != 0)
+            theta = std::asin(std::abs(positionInside.y())
+                              / std::sqrt(std::pow(positionInside.x() + x_shift, 2)
+                                          + std::pow(positionInside.y(), 2)));
+
+        double k = l / (std::sin(theta) / std::tan(M_PI / 6) + std::cos(theta));
+
+        if (std::pow(positionInside.x() + x_shift, 2) + std::pow(positionInside.y(), 2)
+            <= std::pow(k, 2))
+            check = true;
+    } else if (auto ff_Prism6 = dynamic_cast<const FormFactorPrism6*>(outerShape)) {
+        double B = ff_Prism6->getBaseEdge();
+        double H = ff_Prism6->getHeight();
+
+        if (std::abs(positionInside.x()) > B || std::abs(positionInside.y()) > B
+            || positionInside.z() < 0 || positionInside.z() > H)
+            return check;
+
+        double theta_prime = 0; // angle between positionInside & x-axis in positionInside.z() plane
+        if (positionInside.x() != 0 || positionInside.y() != 0)
+            theta_prime = Units::rad2deg(std::asin(
+                std::abs(positionInside.y())
+                / std::sqrt(std::pow(positionInside.x(), 2) + std::pow(positionInside.y(), 2))));
+        int c = static_cast<int>(theta_prime / 60); // multiplicative constant
+        double theta = Units::deg2rad(theta_prime - c * 60);
+        double k_z = B / (std::cos(theta) + std::sin(theta) / std::tan(M_PI / 3));
+
+        if (std::pow(positionInside.x(), 2) + std::pow(positionInside.y(), 2) <= std::pow(k_z, 2))
+            check = true;
+    } else if (auto ff_Pyramid = dynamic_cast<const FormFactorPyramid*>(outerShape)) {
+        double B = ff_Pyramid->getBaseEdge();
+        double H = ff_Pyramid->getHeight();
+        double alpha = ff_Pyramid->getAlpha();
+
+        double l_z
+            = B / 2
+              - positionInside.z() / std::tan(alpha); // half-length of square at a given height
+        if (std::abs(positionInside.x()) <= l_z && std::abs(positionInside.y()) <= l_z
+            && (positionInside.z() >= 0 && positionInside.z() <= H))
+            check = true;
+    } else if (dynamic_cast<const FormFactorRipple1*>(outerShape)) {
+        // TODO: Implement Ripple1
+        std::ostringstream ostr;
+        ostr << "Sorry, outer shape Ripple1 not yet implemented for Mesocrystal";
+        ostr << "\n\nStay tuned!";
+        throw Exceptions::ClassInitializationException(ostr.str());
+    } else if (dynamic_cast<const FormFactorRipple2*>(outerShape)) {
+        // TODO: Implement Ripple2
+        std::ostringstream ostr;
+        ostr << "Sorry, outer shape Ripple2 not yet implemented for Mesocrystal";
+        ostr << "\n\nStay tuned!";
+        throw Exceptions::ClassInitializationException(ostr.str());
+    } else if (auto ff_Tetrahedron = dynamic_cast<const FormFactorTetrahedron*>(outerShape)) {
+        double B = ff_Tetrahedron->getBaseEdge();
+        double H = ff_Tetrahedron->getHeight();
+        double alpha = ff_Tetrahedron->getAlpha();
+
+        double B_z
+            = B - positionInside.z() * 2 / std::tan(alpha); // edge of triangle at a given height
+
+        double l = B_z * std::sin(M_PI / 3);
+        double x_shift = B_z / 2 * std::tan(M_PI / 6);
+
+        if (positionInside.x() + x_shift < 0 || positionInside.x() + x_shift > l
+            || std::abs(positionInside.y()) > B_z / 2 || positionInside.z() < 0
+            || positionInside.z() > H)
+            return check;
+
+        double theta = 0; // angle between positionInside & x-axis in positionInside.z() plane
+        if (positionInside.x() + x_shift != 0 || positionInside.y() != 0)
+            theta = std::asin(std::abs(positionInside.y())
+                              / std::sqrt(std::pow(positionInside.x() + x_shift, 2)
+                                          + std::pow(positionInside.y(), 2)));
+
+        double k = l / (std::sin(theta) / std::tan(M_PI / 6) + std::cos(theta));
+
+        if (std::pow(positionInside.x() + x_shift, 2) + std::pow(positionInside.y(), 2)
+            <= std::pow(k, 2))
+            check = true;
+    } else if (dynamic_cast<const FormFactorTruncatedCube*>(outerShape)) {
+        // TODO: Implement Truncated cube
+        std::ostringstream ostr;
+        ostr << "Sorry, outer shape Truncated cube not yet implemented for Mesocrystal";
+        ostr << "\n\nStay tuned!";
+        throw Exceptions::ClassInitializationException(ostr.str());
+    } else if (auto ff_TruncatedSphere
+               = dynamic_cast<const FormFactorTruncatedSphere*>(outerShape)) {
+        double R = ff_TruncatedSphere->getRadius();
+        double H = ff_TruncatedSphere->getHeight();
+        double deltaH = ff_TruncatedSphere->getRemovedTop();
+        if (std::abs(positionInside.x()) > R || std::abs(positionInside.y()) > R ||
+                positionInside.z() < 0 || positionInside.z() > (H-deltaH))
+            return check;
+
+        if (std::pow(positionInside.x() / R, 2) + std::pow(positionInside.y() / R, 2)
+                + std::pow((positionInside.z() - (H - R)) / R, 2) <= 1)
+            check = true;
+    } else if (dynamic_cast<const FormFactorTruncatedSpheroid*>(outerShape)) {
+        // TODO: Implement Truncated spheroid
+        std::ostringstream ostr;
+        ostr << "Sorry, outer shape Truncated spheroid not yet implemented for Mesocrystal";
+        ostr << "\n\nStay tuned!";
+        throw Exceptions::ClassInitializationException(ostr.str());
+    }
+    return check;
+}
+}
+
+RealSpaceMesoCrystal::~RealSpaceMesoCrystal()
+{
+}
+
+RealSpaceMesoCrystal::RealSpaceMesoCrystal(const MesoCrystalItem* mesoCrystalItem,
+                                           double total_abundance)
+{
+    m_mesoCrystalItem = mesoCrystalItem;
+    m_total_abundance = total_abundance;
+}
+
+Particle3DContainer RealSpaceMesoCrystal::populateMesoCrystal(const IRotation* extra_rotation,
+                                                              kvector_t extra_translation)
+{
+    auto mesoCrystal = m_mesoCrystalItem->createMesoCrystal();
+
+    std::unique_ptr<MesoCrystal> M_clone(mesoCrystal->clone()); // clone of the mesoCrystal
+    M_clone->rotate(*extra_rotation);
+    M_clone->translate(extra_translation);
+
+    // These methods DO NOT add rotation/tranlation of the mesoCrystal to its children
+    // and hence they need to be added manually
+    auto lattice = m_mesoCrystalItem->getLattice();
+    auto particleBasis = m_mesoCrystalItem->getBasis();
+    auto outerShapeff = m_mesoCrystalItem->getOuterShape();
+
+    auto mesoCrystal_rotation = M_clone->rotation();
+    auto mesoCrystal_translation = M_clone->position();
+    if (!mesoCrystal_rotation)
+        mesoCrystal_rotation = IRotation::createIdentity();
+
+    Particle3DContainer mesoCrystalBasis3DContainer;
+
+    if (dynamic_cast<const ParticleComposition*>(particleBasis.get())) {
+        auto particleComposition = dynamic_cast<const ParticleComposition*>(particleBasis.get());
+        mesoCrystalBasis3DContainer
+            = RealSpaceBuilderUtils::particleComposition3DContainer(*particleComposition);
+    } else if (dynamic_cast<const ParticleCoreShell*>(particleBasis.get())) {
+        auto particleCoreShell = dynamic_cast<const ParticleCoreShell*>(particleBasis.get());
+        mesoCrystalBasis3DContainer
+            = RealSpaceBuilderUtils::particleCoreShell3DContainer(*particleCoreShell);
+    } else {
+        auto particle = dynamic_cast<const Particle*>(particleBasis.get());
+        mesoCrystalBasis3DContainer = RealSpaceBuilderUtils::singleParticle3DContainer(*particle);
+    }
+
+    Particle3DContainer mesoCrystal3DContainer;
+
+    for (int k = -n; k <= n; k++) {
+        for (int j = -n; j <= n; j++) {
+            for (int i = -n; i <= n; i++) {
+                auto positionInside = i * lattice.getBasisVectorA() + j * lattice.getBasisVectorB()
+                                      + k * lattice.getBasisVectorC();
+
+                if (isPositionInsideMesoCrystal(outerShapeff.get(), positionInside)) {
+                    for (size_t it = 0; it < mesoCrystalBasis3DContainer.containerSize(); ++it) {
+                        auto particle3D = mesoCrystalBasis3DContainer.createParticle(it);
+                        particle3D->addTranslation(
+                            QVector3D(static_cast<float>(positionInside.x()),
+                                      static_cast<float>(positionInside.y()),
+                                      static_cast<float>(positionInside.z())));
+
+                        particle3D->addExtrinsicRotation(
+                            RealSpaceBuilderUtils::implementParticleRotationfromIRotation(
+                                mesoCrystal_rotation));
+
+                        particle3D->addTranslation(
+                            QVector3D(static_cast<float>(mesoCrystal_translation.x()),
+                                      static_cast<float>(mesoCrystal_translation.y()),
+                                      static_cast<float>(mesoCrystal_translation.z())));
+
+                        mesoCrystal3DContainer.addParticle(
+                            particle3D.release(), mesoCrystalBasis3DContainer.particle3DBlend(it));
+                    }
+                }
+            }
+        }
+    }
+
+    // Add outer shape for visualisation
+    auto outerShape3D = TransformTo3D::createParticlefromIFormFactor(outerShapeff.get());
+    outerShape3D->addTransform(
+        RealSpaceBuilderUtils::implementParticleRotationfromIRotation(mesoCrystal_rotation),
+        QVector3D(static_cast<float>(mesoCrystal_translation.x()),
+                  static_cast<float>(mesoCrystal_translation.y()),
+                  static_cast<float>(mesoCrystal_translation.z())));
+
+    // assign grey (default) color to the outer shape
+    QColor color = QColor();
+    color.setAlphaF(0.3);
+    outerShape3D->color = color;
+    mesoCrystal3DContainer.addParticle(outerShape3D.release(), true);
+
+    // set the correct abundance for the MesoCrystal
+    mesoCrystal3DContainer.setCumulativeAbundance(M_clone->abundance() / m_total_abundance);
+    mesoCrystal3DContainer.setParticleType(Constants::MesoCrystalType);
+
+    return mesoCrystal3DContainer;
+}
diff --git a/GUI/coregui/Views/RealSpaceWidgets/RealSpaceMesoCrystalUtils.h b/GUI/coregui/Views/RealSpaceWidgets/RealSpaceMesoCrystalUtils.h
new file mode 100644
index 0000000000000000000000000000000000000000..229e4d02c38829f9eec2c617622b518b9e19789a
--- /dev/null
+++ b/GUI/coregui/Views/RealSpaceWidgets/RealSpaceMesoCrystalUtils.h
@@ -0,0 +1,43 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/RealSpaceWidgets/RealSpaceBuilderUtils.h
+//! @brief     Defines RealSpaceBuilderUtils namespace
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef REALSPACEMESOCRYSTALUTILS_H
+#define REALSPACEMESOCRYSTALUTILS_H
+
+#include "Rotations.h"
+#include "WinDllMacros.h"
+#include <QVector3D>
+
+class Particle;
+class MesoCrystal;
+class MesoCrystalItem;
+class Particle3DContainer;
+
+class RealSpaceMesoCrystal
+{
+public:
+    ~RealSpaceMesoCrystal();
+
+    RealSpaceMesoCrystal(const MesoCrystalItem* mesoCrystalItem, double total_abundance);
+
+    Particle3DContainer populateMesoCrystal(const IRotation* extra_rotation
+                                            = IRotation::createIdentity(),
+                                            kvector_t extra_translation = kvector_t(0, 0, 0));
+
+private:
+    const MesoCrystalItem* m_mesoCrystalItem;
+    double m_total_abundance;
+};
+
+#endif // REALSPACEMESOCRYSTALUTILS_H
diff --git a/GUI/coregui/Views/RealSpaceWidgets/RealSpacePanel.cpp b/GUI/coregui/Views/RealSpaceWidgets/RealSpacePanel.cpp
deleted file mode 100644
index bc95324a0bb7f7675d94fd933d25e1edd2aab3fb..0000000000000000000000000000000000000000
--- a/GUI/coregui/Views/RealSpaceWidgets/RealSpacePanel.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      GUI/coregui/Views/RealSpaceWidgets/RealSpacePanel.cpp
-//! @brief     Implements class RealSpacePanel
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "RealSpacePanel.h"
-#include "mainwindow_constants.h"
-#include "ComponentEditor.h"
-#include "FilterPropertyProxy.h"
-#include "SampleModel.h"
-#include <QTreeView>
-#include <QItemSelectionModel>
-#include <QVBoxLayout>
-#include <QDebug>
-
-RealSpacePanel::RealSpacePanel(QWidget* parent)
-    : QWidget(parent)
-    , m_treeView(new QTreeView)
-    , m_componentEditor(new ComponentEditor)
-    , m_model(nullptr)
-    , m_proxy(nullptr)
-{
-    setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
-
-    QVBoxLayout* layout = new QVBoxLayout;
-    layout->setMargin(0);
-    layout->setSpacing(0);
-    layout->setContentsMargins(0, 0, 0, 0);
-
-    layout->addWidget(m_treeView);
-    layout->addWidget(m_componentEditor);
-
-    setLayout(layout);
-}
-
-void RealSpacePanel::setModel(SampleModel* model)
-{
-    m_model = model;
-
-    delete m_proxy;
-    m_proxy = new FilterPropertyProxy(1, this);
-    m_proxy->setSourceModel(model);
-    m_treeView->setModel(m_proxy);
-    m_treeView->setAttribute(Qt::WA_MacShowFocusRect, false);
-
-    m_treeView->expandAll();
-
-    connect(m_model, &SampleModel::rowsInserted, this, [=](){m_treeView->expandAll();});
-
-    connect(m_treeView->selectionModel(), &QItemSelectionModel::selectionChanged,
-            this, &RealSpacePanel::onSelectionChanged, Qt::UniqueConnection);
-}
-
-QSize RealSpacePanel::sizeHint() const
-{
-    return QSize(static_cast<int>(Constants::hint_panel_width*1.3), 256);
-
-}
-
-QSize RealSpacePanel::minimumSizeHint() const
-{
-    return QSize(static_cast<int>(Constants::hint_panel_width*1.3), 63);
-}
-
-void RealSpacePanel::onSelectionChanged(const QItemSelection& selected, const QItemSelection&)
-{
-    qDebug() << "RealSpacePanel::onSelectionChanged";
-    Q_ASSERT(m_proxy);
-    Q_ASSERT(m_model);
-    QModelIndexList indices = selected.indexes();
-
-    if(indices.size()) {
-        QModelIndex index = m_proxy->mapToSource(indices.back());
-        SessionItem* item = m_model->itemForIndex(index);
-        Q_ASSERT(item);
-        m_componentEditor->setItem(item);
-        emit selectionChanged(index);
-    } else {
-        m_componentEditor->setItem(nullptr);
-        emit selectionChanged(QModelIndex());
-    }
-}
diff --git a/GUI/coregui/Views/RealSpaceWidgets/RealSpaceToolBar.h b/GUI/coregui/Views/RealSpaceWidgets/RealSpaceToolBar.h
index 8761b36b1276793a10affaa984e8bec79212009f..127f63ed2c10ddf6f049860d9986609672c9bad4 100644
--- a/GUI/coregui/Views/RealSpaceWidgets/RealSpaceToolBar.h
+++ b/GUI/coregui/Views/RealSpaceWidgets/RealSpaceToolBar.h
@@ -27,7 +27,7 @@ class BA_CORE_API_ RealSpaceToolBar : public StyledToolBar
     Q_OBJECT
 
 public:
-    RealSpaceToolBar(QWidget* parent = 0);
+    RealSpaceToolBar(QWidget* parent = nullptr);
 
 signals:
     void defaultViewAction();
@@ -37,13 +37,13 @@ signals:
     void changeLayerSizeAction(double);
 
 private:
-    QToolButton *m_defaultViewButton;
-    QToolButton *m_sideViewButton;
-    QToolButton *m_topViewButton;
-    QCheckBox *m_lockViewCheckBox;
+    QToolButton* m_defaultViewButton;
+    QToolButton* m_sideViewButton;
+    QToolButton* m_topViewButton;
+    QCheckBox* m_lockViewCheckBox;
 
-    QToolButton *m_increaseLayerSizeButton;
-    QToolButton *m_decreaseLayerSizeButton;
+    QToolButton* m_increaseLayerSizeButton;
+    QToolButton* m_decreaseLayerSizeButton;
 };
 
 #endif // REALSPACETOOLBAR_H
diff --git a/GUI/coregui/Views/RealSpaceWidgets/RealSpaceWidget.cpp b/GUI/coregui/Views/RealSpaceWidgets/RealSpaceWidget.cpp
index 66932ceaacd8defb36aaf30dc1771abc9d390dcb..9fec4f73029540ff3385eebc285557d825b57434 100644
--- a/GUI/coregui/Views/RealSpaceWidgets/RealSpaceWidget.cpp
+++ b/GUI/coregui/Views/RealSpaceWidgets/RealSpaceWidget.cpp
@@ -18,7 +18,6 @@
 #include "RealSpaceActions.h"
 #include <QVBoxLayout>
 #include <QLabel>
-#include <QDebug>
 
 RealSpaceWidget::RealSpaceWidget(SampleModel *sampleModel,
                                  QItemSelectionModel* selectionModel, QWidget* parent)
@@ -29,13 +28,13 @@ RealSpaceWidget::RealSpaceWidget(SampleModel *sampleModel,
     , m_sampleModel(sampleModel)
     , m_selectionModel(selectionModel)
 {
-    QHBoxLayout* hlayout = new QHBoxLayout;
+    auto hlayout = new QHBoxLayout;
     hlayout->setMargin(0);
     hlayout->setSpacing(0);
     hlayout->setContentsMargins(0, 0, 0, 0);
     hlayout->addWidget(m_canvas);
 
-    QVBoxLayout *mainLayout = new QVBoxLayout;
+    auto *mainLayout = new QVBoxLayout;
     mainLayout->setMargin(0);
     mainLayout->setSpacing(0);
     mainLayout->setContentsMargins(0,0,0,0);
@@ -44,9 +43,6 @@ RealSpaceWidget::RealSpaceWidget(SampleModel *sampleModel,
 
     setLayout(mainLayout);
 
-    connect(m_selectionModel, &QItemSelectionModel::selectionChanged,
-            m_canvas, &RealSpaceCanvas::onSelectionChanged);
-
     connect(m_toolBar, &RealSpaceToolBar::defaultViewAction,
             m_canvas, &RealSpaceCanvas::onDefaultViewAction);
 
@@ -61,11 +57,15 @@ RealSpaceWidget::RealSpaceWidget(SampleModel *sampleModel,
 
     connect(m_toolBar, &RealSpaceToolBar::changeLayerSizeAction,
             m_canvas, &RealSpaceCanvas::onChangeLayerSizeAction);
+
 }
 
-void RealSpaceWidget::setModel(SampleModel* sampleModel, QItemSelectionModel *selectionModel)
+void RealSpaceWidget::showEvent(QShowEvent*)
 {
-    m_sampleModel = sampleModel;
-    m_selectionModel = selectionModel;
     m_canvas->setModel(m_sampleModel, m_selectionModel);
 }
+
+void RealSpaceWidget::hideEvent(QHideEvent*)
+{
+    m_canvas->setModel(nullptr, nullptr);
+}
diff --git a/GUI/coregui/Views/RealSpaceWidgets/RealSpaceWidget.h b/GUI/coregui/Views/RealSpaceWidgets/RealSpaceWidget.h
index 87e0ab9564fe160a255c72941e02b10b35a716cd..5b876e212179a4f076d9388ffe85c032f34ed4c5 100644
--- a/GUI/coregui/Views/RealSpaceWidgets/RealSpaceWidget.h
+++ b/GUI/coregui/Views/RealSpaceWidgets/RealSpaceWidget.h
@@ -35,7 +35,9 @@ public:
     RealSpaceWidget(SampleModel* sampleModel = nullptr,
                     QItemSelectionModel* selectionModel = nullptr, QWidget* parent = nullptr);
 
-    void setModel(SampleModel* model, QItemSelectionModel* selectionModel);
+protected:
+    void showEvent(QShowEvent*) override;
+    void hideEvent(QHideEvent*) override;
 
 private:
     RealSpaceActions* m_actions;
diff --git a/GUI/coregui/Views/RealSpaceWidgets/TransformTo3D.cpp b/GUI/coregui/Views/RealSpaceWidgets/TransformTo3D.cpp
index 92763a620eea187820d7e4a3e4fd72c13a977aee..2825eaa5e23e728d5498116a420b1fb51cfd2423 100644
--- a/GUI/coregui/Views/RealSpaceWidgets/TransformTo3D.cpp
+++ b/GUI/coregui/Views/RealSpaceWidgets/TransformTo3D.cpp
@@ -22,11 +22,9 @@
 #include "SessionItem.h"
 #include "Units.h"
 #include "VectorItem.h"
-
 #include "GUIDomainSampleVisitor.h"
 #include "ParticleComposition.h"
 #include "ParticleCompositionItem.h"
-
 #include "HardParticles.h"
 
 namespace
@@ -156,7 +154,6 @@ TransformTo3D::createParticlefromIFormFactor(const IFormFactor* ff)
         double radius = ff_FullSphere->getRadius();
         result = std::make_unique<RealSpace::Particles::FullSphere>(radius);
     }
-
     else if (auto ff_FullSpheroid = dynamic_cast<const FormFactorFullSpheroid*>(ff)) {
         double radius = ff_FullSpheroid->getRadius();
         double height = ff_FullSpheroid->getHeight();
@@ -170,7 +167,6 @@ TransformTo3D::createParticlefromIFormFactor(const IFormFactor* ff)
         double edge = ff_Icosahedron->getEdge();
         result = std::make_unique<RealSpace::Particles::Icosahedron>(edge);
     }
-
     else if (auto ff_Prism3 = dynamic_cast<const FormFactorPrism3*>(ff)) {
         double baseedge = ff_Prism3->getBaseEdge();
         double height = ff_Prism3->getHeight();
@@ -207,14 +203,14 @@ TransformTo3D::createParticlefromIFormFactor(const IFormFactor* ff)
     } else if (auto ff_TruncatedSphere = dynamic_cast<const FormFactorTruncatedSphere*>(ff)) {
         double radius = ff_TruncatedSphere->getRadius();
         double height = ff_TruncatedSphere->getHeight();
-        // double removed_top = ff_TruncatedSphere->getRemovedTop();
-        result = std::make_unique<RealSpace::Particles::TruncatedSphere>(radius, height);
+        double deltaH = ff_TruncatedSphere->getRemovedTop();
+        result = std::make_unique<RealSpace::Particles::TruncatedSphere>(radius, height, deltaH);
     } else if (auto ff_TruncatedSpheroid = dynamic_cast<const FormFactorTruncatedSpheroid*>(ff)) {
         double radius = ff_TruncatedSpheroid->getRadius();
         double height = ff_TruncatedSpheroid->getHeight();
         double hfc = ff_TruncatedSpheroid->getHeightFlattening();
-        // double removed_top = ff_TruncatedSpheroid->getRemovedTop();
-        result = std::make_unique<RealSpace::Particles::TruncatedSpheroid>(radius, height, hfc);
+        double deltaH = ff_TruncatedSpheroid->getRemovedTop();
+        result = std::make_unique<RealSpace::Particles::TruncatedSpheroid>(radius, height, hfc, deltaH);
     }
 
     return result;
diff --git a/GUI/coregui/Views/SampleDesigner/NodeEditorPort.cpp b/GUI/coregui/Views/SampleDesigner/NodeEditorPort.cpp
index ee11ff7cf296791edbe5078da0f9bc5ae15d6f15..36d1d1c99c01091a14299bf9c5de583d07fca0ea 100644
--- a/GUI/coregui/Views/SampleDesigner/NodeEditorPort.cpp
+++ b/GUI/coregui/Views/SampleDesigner/NodeEditorPort.cpp
@@ -52,7 +52,8 @@ NodeEditorPort::NodeEditorPort(QGraphicsItem *parent, const QString &name,
 
 NodeEditorPort::~NodeEditorPort()
 {
-    for(auto conn : m_connections) {
+    while (m_connections.size()>0) {
+        auto conn = m_connections.last();
         conn->setSelected(false);
         delete conn;
     }
@@ -93,22 +94,16 @@ QColor NodeEditorPort::getPortTypeColor(NodeEditorPort::EPortType port_type)
     switch (port_type) {
     case DEFAULT:
         return QColor(Qt::gray);
-        break;
     case INTERFERENCE:
         return QColor(Qt::yellow);
-        break;
     case PARTICLE_LAYOUT:
         return QColor(Qt::green);
-        break;
     case FORM_FACTOR:
         return QColor(Qt::blue);
-        break;
     case TRANSFORMATION:
         return QColor(Qt::magenta);
-        break;
     default:
         return QColor(Qt::red);
-        break;
     }
 }
 
diff --git a/GUI/coregui/Views/SampleDesigner/RealSpacePanel.cpp b/GUI/coregui/Views/SampleDesigner/RealSpacePanel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9d52ca570c9bc927ca2638b09a53ca4f04ff93dc
--- /dev/null
+++ b/GUI/coregui/Views/SampleDesigner/RealSpacePanel.cpp
@@ -0,0 +1,45 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/SampleDesigner/RealSpacePanel.cpp
+//! @brief     Implements class RealSpacePanel
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "RealSpacePanel.h"
+#ifdef BORNAGAIN_OPENGL
+#include "RealSpaceWidget.h"
+#endif
+#include <QVBoxLayout>
+
+RealSpacePanel::RealSpacePanel(SampleModel* sampleModel, QItemSelectionModel* selectionModel,
+                               QWidget* parent)
+    : QWidget(parent)
+    , m_realSpaceWidget(nullptr)
+{
+    setWindowTitle("Real Space");
+    setObjectName("Sample3DPanel");
+
+    auto layout = new QVBoxLayout;
+    layout->setMargin(0);
+    layout->setSpacing(0);
+    layout->setContentsMargins(0, 0, 0, 0);
+
+#ifdef BORNAGAIN_OPENGL
+    m_realSpaceWidget = new RealSpaceWidget(sampleModel, selectionModel, this);
+    layout->addWidget(m_realSpaceWidget);
+#endif
+
+    setLayout(layout);
+}
+
+QSize RealSpacePanel::sizeHint() const
+{
+    return QSize(300, 300);
+}
diff --git a/GUI/coregui/Views/RealSpaceWidgets/RealSpacePanel.h b/GUI/coregui/Views/SampleDesigner/RealSpacePanel.h
similarity index 58%
rename from GUI/coregui/Views/RealSpaceWidgets/RealSpacePanel.h
rename to GUI/coregui/Views/SampleDesigner/RealSpacePanel.h
index a9874d5b5d494ab0bf353eb7f73a03f138e4b809..c1fb3fd9f2fba049fe1d3a3536f5322929620e18 100644
--- a/GUI/coregui/Views/RealSpaceWidgets/RealSpacePanel.h
+++ b/GUI/coregui/Views/SampleDesigner/RealSpacePanel.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      GUI/coregui/Views/RealSpaceWidgets/RealSpacePanel.h
+//! @file      GUI/coregui/Views/SampleDesigner/RealSpacePanel.h
 //! @brief     Defines class RealSpacePanel
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -18,11 +18,9 @@
 #include "WinDllMacros.h"
 #include <QWidget>
 
-class QTreeView;
-class ComponentEditor;
 class SampleModel;
-class FilterPropertyProxy;
-class QItemSelection;
+class QItemSelectionModel;
+class RealSpaceWidget;
 
 //! Panel with item selector, property editor on the right side of RealSpaceWidget.
 
@@ -31,24 +29,12 @@ class BA_CORE_API_ RealSpacePanel : public QWidget
     Q_OBJECT
 
 public:
-    RealSpacePanel(QWidget* parent = nullptr);
+    RealSpacePanel(SampleModel* sampleModel, QItemSelectionModel* selectionModel, QWidget* parent);
 
-    void setModel(SampleModel* model);
-
-    QSize sizeHint() const;
-    QSize minimumSizeHint() const;
-
-signals:
-    void selectionChanged(const QModelIndex& index);
-
-public slots:
-    void onSelectionChanged(const QItemSelection& selected, const QItemSelection&);
+    QSize sizeHint() const override;
 
 private:
-    QTreeView* m_treeView;
-    ComponentEditor* m_componentEditor;
-    SampleModel* m_model;
-    FilterPropertyProxy* m_proxy;
+    RealSpaceWidget* m_realSpaceWidget;
 };
 
 #endif // REALSPACEPANEL_H
diff --git a/GUI/coregui/Views/SampleDesigner/SampleDesigner.cpp b/GUI/coregui/Views/SampleDesigner/SampleDesigner.cpp
index 2bac054706c2643ddf11ada4eb7a37422a1596bc..c956afd333153541ed54e7216285704ded7cacc8 100644
--- a/GUI/coregui/Views/SampleDesigner/SampleDesigner.cpp
+++ b/GUI/coregui/Views/SampleDesigner/SampleDesigner.cpp
@@ -45,9 +45,3 @@ void SampleDesigner::setSelectionModel(QItemSelectionModel *model, FilterPropert
 {
     if(model) m_designerScene->setSelectionModel(model, proxy);
 }
-
-
-void SampleDesigner::onSmartAlign()
-{
-    m_designerScene->onSmartAlign();
-}
diff --git a/GUI/coregui/Views/SampleDesigner/SampleDesigner.h b/GUI/coregui/Views/SampleDesigner/SampleDesigner.h
index aa2e56bee95dca275683ff3931ab577d855479f7..efec5c3f86ffc4e3a84e7a3d58623c0526e8c0b5 100644
--- a/GUI/coregui/Views/SampleDesigner/SampleDesigner.h
+++ b/GUI/coregui/Views/SampleDesigner/SampleDesigner.h
@@ -59,9 +59,6 @@ public:
     void setModels(ApplicationModels* models);
     void setSelectionModel(QItemSelectionModel *model, FilterPropertyProxy *proxy);
 
-public slots:
-    void onSmartAlign();
-
 private:
     DesignerScene *m_designerScene; //! scene which holds all objects
     DesignerView *m_designerView;   //! graphical representation of scene with object
diff --git a/GUI/coregui/Views/SampleDesigner/SampleDesigner.qrc b/GUI/coregui/Views/SampleDesigner/SampleDesigner.qrc
index 860e0f9a68fa1e102abf8c758730681e8b789f20..a81e6a68ab2b0be20ebb4dfb4ce42be7323f0ab6 100644
--- a/GUI/coregui/Views/SampleDesigner/SampleDesigner.qrc
+++ b/GUI/coregui/Views/SampleDesigner/SampleDesigner.qrc
@@ -5,8 +5,5 @@
         <file>images/toolbar_materialeditor.png</file>
         <file>images/toolbar_recycle.png</file>
         <file>images/toolbar_center.png</file>
-        <file>images/toolbar_redo.png</file>
-        <file>images/toolbar_unddo.png</file>
-        <file>images/toolbar_align.png</file>
     </qresource>
 </RCC>
diff --git a/GUI/coregui/Views/SampleDesigner/SampleToolBar.cpp b/GUI/coregui/Views/SampleDesigner/SampleToolBar.cpp
index 45807de1a75e08c93617ca7b5e3e2984ff37b303..ec32b5326ad70878a129233e4d6c66241d7070fb 100644
--- a/GUI/coregui/Views/SampleDesigner/SampleToolBar.cpp
+++ b/GUI/coregui/Views/SampleDesigner/SampleToolBar.cpp
@@ -15,6 +15,7 @@
 #include "SampleToolBar.h"
 #include "DesignerView.h"
 #include "MaterialItemUtils.h"
+#include "SampleViewActions.h"
 #include <QAction>
 #include <QButtonGroup>
 #include <QComboBox>
@@ -24,24 +25,20 @@
 #include <QPushButton>
 #include <QToolButton>
 
-#include <RealSpaceDialog.h>
-
 //! main tool bar on top of SampleView window
-SampleToolBar::SampleToolBar(SampleModel *sampleModel, QItemSelectionModel* selectionModel,
-                             QWidget *parent)
+SampleToolBar::SampleToolBar(SampleViewActions* sampleActions,
+                             QWidget* parent)
     : StyledToolBar(parent)
-    , m_sampleModel(sampleModel)
-    , m_selectionModel(selectionModel)
-    , m_dialog(nullptr)
-    , m_dialog_on(false)
+    , m_sampleViewActions(sampleActions)
 {
     // Select & Pan
-    QToolButton *selectionPointerButton = new QToolButton;
+    auto selectionPointerButton = new QToolButton;
     selectionPointerButton->setCheckable(true);
     selectionPointerButton->setChecked(true);
     selectionPointerButton->setIcon(QIcon(":/SampleDesigner/images/toolbar_pointer.png"));
     selectionPointerButton->setToolTip("Edit mode.");
-    QToolButton *handPointerButton = new QToolButton;
+
+    auto handPointerButton = new QToolButton;
     handPointerButton->setCheckable(true);
     handPointerButton->setIcon(QIcon(":/SampleDesigner/images/toolbar_hand.png"));
     handPointerButton->setToolTip("Pan mode (space).");
@@ -49,65 +46,45 @@ SampleToolBar::SampleToolBar(SampleModel *sampleModel, QItemSelectionModel* sele
     m_pointerModeGroup = new QButtonGroup(this);
     m_pointerModeGroup->addButton(selectionPointerButton, DesignerView::RUBBER_SELECTION);
     m_pointerModeGroup->addButton(handPointerButton, DesignerView::HAND_DRAG);
-    connect(m_pointerModeGroup, SIGNAL(buttonClicked(int)),
-            this, SIGNAL(selectionMode(int)));
+    connect(m_pointerModeGroup,
+            static_cast<void(QButtonGroup::*)(int)>(&QButtonGroup::buttonClicked),
+            this, &SampleToolBar::selectionMode);
     addWidget(selectionPointerButton);
     addWidget(handPointerButton);
 
     addStyledSeparator();
 
-    // unddo redo
-    QToolButton *unddoButton = new QToolButton;
-    unddoButton->setIcon(QIcon(":/SampleDesigner/images/toolbar_unddo.png"));
-    unddoButton->setToolTip("Unddo last action (not implemented yet).");
-    addWidget(unddoButton);
-    QToolButton *redoButton = new QToolButton;
-    redoButton->setIcon(QIcon(":/SampleDesigner/images/toolbar_redo.png"));
-    redoButton->setToolTip("Do again the last undone action (not implemented yet).");
-    addWidget(redoButton);
-
-    addStyledSeparator();
-
     // Remove item
     m_removeButton = new QToolButton;
     m_removeButton->setText("Remove item");
     m_removeButton->setIcon(QIcon(":/SampleDesigner/images/toolbar_recycle.png"));
     m_removeButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
     m_removeButton->setToolTip("Remove selected items and they child items (del).");
-    connect(m_removeButton, SIGNAL(clicked()), this, SIGNAL(deleteItems()));
+    connect(m_removeButton, &QToolButton::clicked, this, &SampleToolBar::deleteItems);
     addWidget(m_removeButton);
 
     addStyledSeparator();
 
     // Center view
-
     m_centerViewButton = new QToolButton;
     m_centerViewButton->setIcon(QIcon(":/SampleDesigner/images/toolbar_center.png"));
     m_centerViewButton->setToolTip("Center view.");
     addWidget(m_centerViewButton);
-    connect(m_centerViewButton, SIGNAL(clicked()), this, SIGNAL(centerView()));
-
-    // align sample
-    m_alignItemsButton = new QToolButton;
-    m_alignItemsButton->setIcon(QIcon(":/SampleDesigner/images/toolbar_align.png"));
-    m_alignItemsButton->setToolTip("Try to align items.");
-    connect(m_alignItemsButton, SIGNAL(clicked()), this, SIGNAL(smartAlign()));
-    addWidget(m_alignItemsButton);
+    connect(m_centerViewButton, &QToolButton::clicked, this, &SampleToolBar::centerView);
 
     // Zoom
     addWidget(new QLabel(" "));
     addSeparator();
     addWidget(new QLabel(" Zoom "));
     m_scaleCombo = new QComboBox;
-    QStringList scales;
-    scales << "25%"<< "50%" << "75%" << "100%" << "125%" << "150%";
+    QStringList scales = QStringList() << "25%" << "50%" << "75%" << "100%" << "125%" << "150%";
     m_scaleCombo->addItems(scales);
     m_scaleCombo->setCurrentIndex(3);
-    connect(m_scaleCombo, SIGNAL(currentIndexChanged(QString)),
-            this, SLOT(onScaleComboChanged(QString)));
+    connect(m_scaleCombo,
+            static_cast<void(QComboBox::*)(const QString &)>(&QComboBox::currentIndexChanged),
+            this, &SampleToolBar::onScaleComboChanged);
     addWidget(m_scaleCombo);
 
-
     // MaterialEditor
     addWidget(new QLabel(" "));
     m_materialEditorButton = new QToolButton;
@@ -116,40 +93,42 @@ SampleToolBar::SampleToolBar(SampleModel *sampleModel, QItemSelectionModel* sele
     m_materialEditorButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
     m_materialEditorButton->setToolTip("Open material editor (m).");
     m_materialEditorButton->setShortcut(Qt::Key_M);
-    connect(m_materialEditorButton, SIGNAL(clicked()), this, SLOT(onMaterialEditorCall()));
+    connect(m_materialEditorButton, &QToolButton::clicked,
+            this, &SampleToolBar::onMaterialEditorCall);
     addWidget(m_materialEditorButton);
 
     addStyledSeparator();
 
     // RealSpace 3D Viewer
     addWidget(new QLabel(" "));
+    addWidget(new QLabel(" "));
     m_RealSpaceViewerButton = new QToolButton;
-    m_RealSpaceViewerButton->setText("Real Space Viewer");
-    //m_RealSpaceViewerButton->setIcon(QIcon(":/SampleDesigner/images/toolbar_materialeditor.png"));
+    m_RealSpaceViewerButton->setText("3D Viewer");
     m_RealSpaceViewerButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
     m_RealSpaceViewerButton->setToolTip("Open real space 3D viewer.");
-    connect(m_RealSpaceViewerButton, SIGNAL(clicked()), this, SLOT(onRealSpaceViewerCall()));
+    connect(m_RealSpaceViewerButton, &QToolButton::clicked,
+            m_sampleViewActions, &SampleViewActions::onToggleRealSpaceView);
     addWidget(m_RealSpaceViewerButton);
 
     // Additional actions
     m_zoomOutAction = new QAction(this);
     m_zoomOutAction->setShortcut(QKeySequence(Qt::Key_Minus));
-    connect(m_zoomOutAction, SIGNAL(triggered()), this, SIGNAL(zoomOut()));
+    connect(m_zoomOutAction, &QAction::triggered, this, &SampleToolBar::zoomOut);
     addAction(m_zoomOutAction);
 
     m_zoomInAction = new QAction(this);
     m_zoomInAction->setShortcut(QKeySequence(Qt::Key_Equal));
-    connect(m_zoomInAction, SIGNAL(triggered()), this, SIGNAL(zoomIn()));
+    connect(m_zoomInAction, &QAction::triggered, this, &SampleToolBar::zoomIn);
     addAction(m_zoomInAction);
 }
 
 void SampleToolBar::onViewSelectionMode(int mode)
 {
-    if(mode == DesignerView::RUBBER_SELECTION || mode == DesignerView::HAND_DRAG)
+    if (mode == DesignerView::RUBBER_SELECTION || mode == DesignerView::HAND_DRAG)
         m_pointerModeGroup->button(mode)->setChecked(true);
 }
 
-void SampleToolBar::onScaleComboChanged(const QString &scale_string)
+void SampleToolBar::onScaleComboChanged(const QString& scale_string)
 {
     double scale = scale_string.left(scale_string.indexOf("%")).toDouble() / 100.0;
     emit changeScale(scale);
@@ -159,17 +138,3 @@ void SampleToolBar::onMaterialEditorCall()
 {
     ExternalProperty mp = MaterialItemUtils::selectMaterialProperty();
 }
-
-void SampleToolBar::onRealSpaceViewerCall()
-{
-    // keep only one instance of dialog alive using a boolean flag
-    if(!m_dialog_on)
-    {
-        m_dialog_on = true;
-        m_dialog = new RealSpaceDialog(m_sampleModel, m_selectionModel, this);
-        m_dialog->show();
-
-        // undo the flag when the dialog is destroyed on close event
-        connect(m_dialog, &QAction::destroyed, this, [&](){m_dialog_on = false;} );
-    }
-}
diff --git a/GUI/coregui/Views/SampleDesigner/SampleToolBar.h b/GUI/coregui/Views/SampleDesigner/SampleToolBar.h
index fcb64b093d64b6bab9d8056e237e10ce92554286..d33c8e0b8e2e84be9ba124eca090cfe02f8a9b02 100644
--- a/GUI/coregui/Views/SampleDesigner/SampleToolBar.h
+++ b/GUI/coregui/Views/SampleDesigner/SampleToolBar.h
@@ -16,10 +16,7 @@
 #define SAMPLETOOLBAR_H
 
 #include "StyledToolBar.h"
-
-#include "SampleModel.h"
 #include <QTreeView>
-#include "RealSpaceDialog.h"
 
 class QAction;
 class QToolButton;
@@ -27,6 +24,8 @@ class QToolBar;
 class QComboBox;
 class QString;
 class QButtonGroup;
+class SampleModel;
+class SampleViewActions;
 
 //! The SampleToolBar class represents a main toolbar on top of SampleView window
 
@@ -35,9 +34,8 @@ class BA_CORE_API_ SampleToolBar : public StyledToolBar
     Q_OBJECT
 
 public:
-    explicit SampleToolBar(SampleModel* sampleModel = nullptr,
-                           QItemSelectionModel* selectionModel = nullptr,
-                           QWidget *parent = 0);
+    explicit SampleToolBar(SampleViewActions* sampleActions = nullptr,
+                           QWidget* parent = nullptr);
 
 signals:
     void deleteItems();
@@ -50,27 +48,19 @@ signals:
 
 public slots:
     void onViewSelectionMode(int);
-    void onScaleComboChanged(const QString &);
+    void onScaleComboChanged(const QString&);
     void onMaterialEditorCall();
 
-    void onRealSpaceViewerCall();
-
 private:
-    QButtonGroup *m_pointerModeGroup;
-    QToolButton *m_removeButton;
-    QToolButton *m_centerViewButton;
-    QToolButton *m_alignItemsButton;
-    QComboBox *m_scaleCombo;
-    QToolButton *m_materialEditorButton;
-    QAction *m_zoomInAction;
-    QAction *m_zoomOutAction;
-
-    QToolButton *m_RealSpaceViewerButton;
-    SampleModel *m_sampleModel;
-    QItemSelectionModel *m_selectionModel;
-    RealSpaceDialog *m_dialog;
-
-    bool m_dialog_on;
+    QButtonGroup* m_pointerModeGroup;
+    QToolButton* m_removeButton;
+    QToolButton* m_centerViewButton;
+    QComboBox* m_scaleCombo;
+    QToolButton* m_materialEditorButton;
+    QAction* m_zoomInAction;
+    QAction* m_zoomOutAction;
+    QToolButton* m_RealSpaceViewerButton;
+    SampleViewActions* m_sampleViewActions;
 };
 
 #endif // SAMPLETOOLBAR_H
diff --git a/GUI/coregui/Views/SampleDesigner/SampleTreeWidget.cpp b/GUI/coregui/Views/SampleDesigner/SampleTreeWidget.cpp
index 88aeed921265e10868af3d05ad531c2333478403..845dcb951d4e0b5fbaa89a60b0e3832b6d895cde 100644
--- a/GUI/coregui/Views/SampleDesigner/SampleTreeWidget.cpp
+++ b/GUI/coregui/Views/SampleDesigner/SampleTreeWidget.cpp
@@ -26,7 +26,8 @@ SampleTreeWidget::SampleTreeWidget(QWidget* parent, SampleModel* model)
     , m_treeView(new ItemTreeView)
     , m_sampleModel(model)
 {
-    setWindowTitle(QString("Sample Tree View"));
+    setWindowTitle(QString("Sample Tree"));
+    setObjectName(QLatin1String("SampleTreeWidget"));
 
     auto mainLayout = new QVBoxLayout;
     mainLayout->setMargin(0);
diff --git a/GUI/coregui/Views/SampleDesigner/SampleViewActions.cpp b/GUI/coregui/Views/SampleDesigner/SampleViewActions.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3567ab39832a350fa1ba24822976a48e36723c93
--- /dev/null
+++ b/GUI/coregui/Views/SampleDesigner/SampleViewActions.cpp
@@ -0,0 +1,48 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/SampleViewActions.h
+//! @brief     Implements class SampleViewActions
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "SampleViewActions.h"
+#include "SampleView.h"
+#include "SampleViewDocks.h"
+#include <QDockWidget>
+#include <QAction>
+
+SampleViewActions::SampleViewActions(SampleModel* model, SampleView* parent)
+    : QObject(parent)
+    , m_model(model)
+    , m_sampleView(parent)
+    , m_selection_model(nullptr)
+{
+
+}
+
+void SampleViewActions::setSelectionModel(QItemSelectionModel* selection_model)
+{
+    m_selection_model = selection_model;
+}
+
+SampleModel* SampleViewActions::sampleModel()
+{
+    return m_model;
+}
+
+QItemSelectionModel* SampleViewActions::selectionModel()
+{
+    return m_selection_model;
+}
+
+void SampleViewActions::onToggleRealSpaceView()
+{
+    m_sampleView->docks()->togleDock(SampleViewDocks::REALSPACEPANEL);
+}
diff --git a/GUI/coregui/Views/SampleDesigner/SampleViewActions.h b/GUI/coregui/Views/SampleDesigner/SampleViewActions.h
new file mode 100644
index 0000000000000000000000000000000000000000..3302371d838ee30e6bea1240e4a4e04f2b76f90b
--- /dev/null
+++ b/GUI/coregui/Views/SampleDesigner/SampleViewActions.h
@@ -0,0 +1,48 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/SampleViewActions.h
+//! @brief     Defines class SampleViewActions
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef SAMPLEVIEWACTIONS_H
+#define SAMPLEVIEWACTIONS_H
+
+#include "WinDllMacros.h"
+#include <QObject>
+
+class SampleModel;
+class QItemSelectionModel;
+class SampleView;
+
+//! Holds all actions of SampleView.
+
+class SampleViewActions : public QObject
+{
+    Q_OBJECT
+public:
+    SampleViewActions(SampleModel* model, SampleView* parent);
+
+    void setSelectionModel(QItemSelectionModel* selection_model);
+
+    SampleModel* sampleModel();
+
+    QItemSelectionModel* selectionModel();
+
+public slots:
+    void onToggleRealSpaceView();
+
+private:
+    SampleModel* m_model;
+    SampleView* m_sampleView;
+    QItemSelectionModel* m_selection_model;
+};
+
+#endif
diff --git a/GUI/coregui/Views/SampleDesigner/SampleViewDocks.cpp b/GUI/coregui/Views/SampleDesigner/SampleViewDocks.cpp
index bcec3aafdecfdd1a578516e320d0e77348c95e3a..ca0f2e9b79b1b172f6dd5b59acae2e524f986282 100644
--- a/GUI/coregui/Views/SampleDesigner/SampleViewDocks.cpp
+++ b/GUI/coregui/Views/SampleDesigner/SampleViewDocks.cpp
@@ -15,37 +15,40 @@
 #include "SampleViewDocks.h"
 #include "ApplicationModels.h"
 #include "FilterPropertyProxy.h"
-#include "InfoWidget.h"
+#include "ScriptPanel.h"
 #include "SampleDesigner.h"
 #include "SamplePropertyWidget.h"
 #include "SampleTreeWidget.h"
 #include "SampleView.h"
 #include "SampleWidgetBox.h"
+#include "RealSpacePanel.h"
 #include <QDockWidget>
 #include <QTreeView>
+#include <QAction>
 
 SampleViewDocks::SampleViewDocks(SampleView* parent)
     : DocksController(parent), m_sampleDesigner(new SampleDesigner(parent)),
       m_widgetBox(new SampleWidgetBox(sampleDesigner(), parent)),
       m_treeWidget(new SampleTreeWidget(parent, parent->models()->sampleModel())),
       m_propertyWidget(
-          new SamplePropertyWidget(m_treeWidget->treeView()->selectionModel(), parent)),
-      m_infoWidget(new InfoWidget(parent))
+          new SamplePropertyWidget(m_treeWidget->treeView()->selectionModel(), parent))
+    , m_scriptPanel(new ScriptPanel(parent))
+    , m_realSpacePanel(new RealSpacePanel(parent->models()->sampleModel(),
+                                         m_treeWidget->treeView()->selectionModel(), parent))
 {
     addWidget(WIDGET_BOX, m_widgetBox, Qt::LeftDockWidgetArea);
     addWidget(SAMPLE_TREE, m_treeWidget, Qt::RightDockWidgetArea);
     addWidget(PROPERTY_EDITOR, m_propertyWidget, Qt::RightDockWidgetArea);
-    addWidget(INFO, m_infoWidget, Qt::BottomDockWidgetArea);
+    addWidget(INFO, m_scriptPanel, Qt::BottomDockWidgetArea);
+    addWidget(REALSPACEPANEL, m_realSpacePanel, Qt::BottomDockWidgetArea);
 
-    connect(m_infoWidget, SIGNAL(widgetHeightRequest(int)), this,
-            SLOT(setDockHeightForWidget(int)));
-    connect(m_infoWidget, SIGNAL(widgetCloseRequest()), this, SLOT(onWidgetCloseRequest()));
+    connect(m_scriptPanel, &ScriptPanel::widgetHeightRequest, this,
+            &DocksController::setDockHeightForWidget);
+    connect(m_scriptPanel, &ScriptPanel::widgetCloseRequest, this,
+            &SampleViewDocks::onWidgetCloseRequest);
 
-    connect(findDock(m_infoWidget), SIGNAL(visibilityChanged(bool)), this,
-            SLOT(onDockVisibilityChangeV2(bool)));
-
-    m_infoWidget->setSampleModel(parent->models()->sampleModel());
-    m_infoWidget->setInstrumentModel(parent->models()->instrumentModel());
+    m_scriptPanel->setSampleModel(parent->models()->sampleModel());
+    m_scriptPanel->setInstrumentModel(parent->models()->instrumentModel());
 
     m_sampleDesigner->setModels(parent->models());
     m_sampleDesigner->setSelectionModel(
@@ -72,17 +75,23 @@ SamplePropertyWidget* SampleViewDocks::propertyWidget()
     return m_propertyWidget;
 }
 
-SampleDesigner* SampleViewDocks::sampleDesigner()
+void SampleViewDocks::onResetLayout()
 {
-    return m_sampleDesigner;
+    DocksController::onResetLayout();
+    mainWindow()->tabifyDockWidget(findDock(REALSPACEPANEL), findDock(INFO));
+    findDock(REALSPACEPANEL)->raise(); // makes first tab active
+
+    findDock(REALSPACEPANEL)->hide();
+    findDock(INFO)->hide();
 }
 
-InfoWidget* SampleViewDocks::infoWidget()
+void SampleViewDocks::togleDock(int id)
 {
-    return m_infoWidget;
+    auto dock = findDock(id);
+    dock->setHidden(!dock->isHidden());
 }
 
-void SampleViewDocks::onDockVisibilityChangeV2(bool status)
+SampleDesigner* SampleViewDocks::sampleDesigner()
 {
-    m_infoWidget->onDockVisibilityChange(status);
+    return m_sampleDesigner;
 }
diff --git a/GUI/coregui/Views/SampleDesigner/SampleViewDocks.h b/GUI/coregui/Views/SampleDesigner/SampleViewDocks.h
index 4da8c95d5a235d2c25d8afcd72edf6fd6ffebc64..9680b9bbdacd8af71b4655bdeb7c80770c0f0fb0 100644
--- a/GUI/coregui/Views/SampleDesigner/SampleViewDocks.h
+++ b/GUI/coregui/Views/SampleDesigner/SampleViewDocks.h
@@ -22,7 +22,9 @@ class SampleWidgetBox;
 class SampleTreeWidget;
 class SamplePropertyWidget;
 class SampleDesigner;
-class InfoWidget;
+class ScriptPanel;
+class RealSpacePanel;
+class QAction;
 
 //! Holds all docked widgets for SampleView.
 
@@ -31,25 +33,27 @@ class BA_CORE_API_ SampleViewDocks : public DocksController
     Q_OBJECT
 
 public:
+    enum ESubWindows { WIDGET_BOX, SAMPLE_TREE, PROPERTY_EDITOR, INFO, REALSPACEPANEL,
+                       NUMBER_OF_SUB_WINDOWS };
+
     SampleViewDocks(SampleView* parent = nullptr);
 
     SampleDesigner* sampleDesigner();
     SampleWidgetBox* widgetBox();
     SampleTreeWidget* treeWidget();
     SamplePropertyWidget* propertyWidget();
-    InfoWidget* infoWidget();
 
-protected slots:
-    void onDockVisibilityChangeV2(bool status);
+    void onResetLayout() override;
 
-private:
-    enum ESubWindows { WIDGET_BOX, SAMPLE_TREE, PROPERTY_EDITOR, INFO, NUMBER_OF_SUB_WINDOWS };
+    void togleDock(int id);
 
+private:
     SampleDesigner* m_sampleDesigner;
     SampleWidgetBox* m_widgetBox;
     SampleTreeWidget* m_treeWidget;
     SamplePropertyWidget* m_propertyWidget;
-    InfoWidget* m_infoWidget;
+    ScriptPanel* m_scriptPanel;
+    RealSpacePanel* m_realSpacePanel;
 };
 
 #endif
diff --git a/GUI/coregui/Views/SampleDesigner/SampleViewStatusBar.cpp b/GUI/coregui/Views/SampleDesigner/SampleViewStatusBar.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..db98e0c815cb33e1fcd7d0d0dab1041ae657a226
--- /dev/null
+++ b/GUI/coregui/Views/SampleDesigner/SampleViewStatusBar.cpp
@@ -0,0 +1,52 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/SampleDesigner/SampleViewActivityStatusBar.cpp
+//! @brief     Implements class SampleViewActivityStatusBar
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "SampleViewStatusBar.h"
+#include "mainwindow.h"
+#include <QHBoxLayout>
+#include <QStatusBar>
+#include <QToolButton>
+
+SampleViewStatusBar::SampleViewStatusBar(MainWindow* mainWindow)
+    : QWidget(mainWindow), m_dockMenuButton(nullptr)
+    , m_mainWindow(mainWindow)
+{
+    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+    auto layout = new QHBoxLayout;
+    layout->setSpacing(0);
+    layout->setMargin(0);
+
+    m_dockMenuButton = new QToolButton;
+    m_dockMenuButton->setIcon(QIcon(":/images/statusbar_dockmenu.svg"));
+    m_dockMenuButton->setToolTip("Docks layout menu");
+    connect(m_dockMenuButton, &QToolButton::clicked,
+            this, &SampleViewStatusBar::dockMenuRequest);
+
+    layout->addStretch();
+    layout->addWidget(m_dockMenuButton);
+
+    setLayout(layout);
+    initAppearance();
+}
+
+//! Init appearance of MainWindow's statusBar.
+
+void SampleViewStatusBar::initAppearance()
+{
+    Q_ASSERT(m_mainWindow);
+    m_mainWindow->statusBar()->addWidget(this, 1);
+    m_mainWindow->statusBar()->setSizeGripEnabled(false);
+    this->hide();
+}
diff --git a/GUI/coregui/Views/SampleDesigner/SampleViewStatusBar.h b/GUI/coregui/Views/SampleDesigner/SampleViewStatusBar.h
new file mode 100644
index 0000000000000000000000000000000000000000..9578ff37f2a2c90d31a2e4f788f975c24720cf7f
--- /dev/null
+++ b/GUI/coregui/Views/SampleDesigner/SampleViewStatusBar.h
@@ -0,0 +1,43 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/SampleDesigner/SampleViewStatusBar.h
+//! @brief     Defines class SampleViewStatusBar
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef SAMPLEVIEWSTATUSBAR_H
+#define SAMPLEVIEWSTATUSBAR_H
+
+#include "WinDllMacros.h"
+#include <QWidget>
+
+class MainWindow;
+class QToolButton;
+class QComboBox;
+
+//! Narrow status bar at very bottom of SampleView to access dock menu.
+
+class BA_CORE_API_ SampleViewStatusBar : public QWidget
+{
+    Q_OBJECT
+public:
+    SampleViewStatusBar(MainWindow* mainWindow);
+
+signals:
+    void dockMenuRequest();
+
+private:
+    void initAppearance();
+
+    QToolButton* m_dockMenuButton;
+    MainWindow* m_mainWindow;
+};
+
+#endif
diff --git a/GUI/coregui/Views/SampleDesigner/SampleWidgetBox.cpp b/GUI/coregui/Views/SampleDesigner/SampleWidgetBox.cpp
index fa5750c44a83a27ed431e556d3a2e53f7cadd7b8..2b28a06ab9424685e3ea61f211a733b478b8e956 100644
--- a/GUI/coregui/Views/SampleDesigner/SampleWidgetBox.cpp
+++ b/GUI/coregui/Views/SampleDesigner/SampleWidgetBox.cpp
@@ -27,6 +27,8 @@ SampleWidgetBox::SampleWidgetBox(SampleDesignerInterface *core, QWidget *parent)
     , m_core(core)
     , m_widgetBox(0)
 {
+    setWindowTitle(QLatin1String("Widget Box"));
+    setObjectName(QLatin1String("WidgetBox"));
     //Manhattan::StyledBar *bar = new Manhattan::StyledBar(this);
 
     setWindowTitle("Items Toolbox");
@@ -34,9 +36,6 @@ SampleWidgetBox::SampleWidgetBox(SampleDesignerInterface *core, QWidget *parent)
     m_widgetBox = new qdesigner_internal::WidgetBox(m_core, this);
     m_widgetBox->setFileName(QStringLiteral(":/widgetbox/widgetbox.xml"));
     m_widgetBox->load();
-    m_widgetBox->setWindowTitle(QLatin1String("Widget Box"));
-    m_widgetBox->setObjectName(QLatin1String("WidgetBox"));
-
 
     QVBoxLayout *layout = new QVBoxLayout;
     layout->setMargin(0);
diff --git a/GUI/coregui/Views/SampleDesigner/ScriptPanel.cpp b/GUI/coregui/Views/SampleDesigner/ScriptPanel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d6d7e301e93fc66af0ef24123df562cbfda5939c
--- /dev/null
+++ b/GUI/coregui/Views/SampleDesigner/ScriptPanel.cpp
@@ -0,0 +1,42 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/SampleDesigner/ScriptPanel.cpp
+//! @brief     Implements class ScriptPanel
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "ScriptPanel.h"
+#include "PySampleWidget.h"
+#include "InfoPanelToolBar.h"
+#include <QResizeEvent>
+#include <QStackedWidget>
+
+ScriptPanel::ScriptPanel(QWidget *parent)
+    : InfoPanel(parent)
+    , m_pySampleWidget(new PySampleWidget(this))
+{
+    setWindowTitle("Python Script");
+    setObjectName("ScriptPanel");
+
+    m_stackedWidget->addWidget(m_pySampleWidget);
+
+    setContentVisible(false);
+    m_toolBar->hide();
+}
+
+void ScriptPanel::setSampleModel(SampleModel *sampleModel)
+{
+    m_pySampleWidget->setSampleModel(sampleModel);
+}
+
+void ScriptPanel::setInstrumentModel(InstrumentModel *instrumentModel)
+{
+    m_pySampleWidget->setInstrumentModel(instrumentModel);
+}
diff --git a/GUI/coregui/Views/SampleDesigner/ScriptPanel.h b/GUI/coregui/Views/SampleDesigner/ScriptPanel.h
new file mode 100644
index 0000000000000000000000000000000000000000..5bb61c3b263d93a8e9a741ffd7637dfd7a1e3664
--- /dev/null
+++ b/GUI/coregui/Views/SampleDesigner/ScriptPanel.h
@@ -0,0 +1,40 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/Views/SampleDesigner/ScriptPanel.h
+//! @brief     Defines class SampleDesigner
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef SCRIPTPANEL_H
+#define SCRIPTPANEL_H
+
+#include "InfoPanel.h"
+
+class SampleModel;
+class InstrumentModel;
+class PySampleWidget;
+
+//! Resides at the bottom of SampleView and displays a Python script.
+
+class BA_CORE_API_ ScriptPanel : public InfoPanel
+{
+    Q_OBJECT
+
+public:
+    explicit ScriptPanel(QWidget* parent = nullptr);
+
+    void setSampleModel(SampleModel* sampleModel);
+    void setInstrumentModel(InstrumentModel* instrumentModel);
+
+private:
+    PySampleWidget* m_pySampleWidget;
+};
+
+#endif // SCRIPTPANEL_H
diff --git a/GUI/coregui/Views/SampleDesigner/images/toolbar_align.png b/GUI/coregui/Views/SampleDesigner/images/toolbar_align.png
deleted file mode 100644
index a225d358768c2803f2639887f51b7fde60283c48..0000000000000000000000000000000000000000
Binary files a/GUI/coregui/Views/SampleDesigner/images/toolbar_align.png and /dev/null differ
diff --git a/GUI/coregui/Views/SampleDesigner/images/toolbar_redo.png b/GUI/coregui/Views/SampleDesigner/images/toolbar_redo.png
deleted file mode 100644
index 821a11806a597a3c979bc10c02861feff75ff9f0..0000000000000000000000000000000000000000
Binary files a/GUI/coregui/Views/SampleDesigner/images/toolbar_redo.png and /dev/null differ
diff --git a/GUI/coregui/Views/SampleDesigner/images/toolbar_unddo.png b/GUI/coregui/Views/SampleDesigner/images/toolbar_unddo.png
deleted file mode 100644
index 78d8cb24e151c4096d908682a8d9c90764569aeb..0000000000000000000000000000000000000000
Binary files a/GUI/coregui/Views/SampleDesigner/images/toolbar_unddo.png and /dev/null differ
diff --git a/GUI/coregui/Views/SampleView.cpp b/GUI/coregui/Views/SampleView.cpp
index 7f80d02534e4735f647e91b2e08f8c9f1c951ec1..914f6037540adb6c69ed732beea937466468b91d 100644
--- a/GUI/coregui/Views/SampleView.cpp
+++ b/GUI/coregui/Views/SampleView.cpp
@@ -19,23 +19,59 @@
 #include "SampleTreeWidget.h"
 #include "SampleViewDocks.h"
 #include "mainwindow.h"
+#include "SampleViewActions.h"
+#include "SampleViewStatusBar.h"
+#include <QMenu>
+#include <memory>
 
 SampleView::SampleView(MainWindow* mainWindow)
-    : Manhattan::FancyMainWindow(mainWindow), m_models(mainWindow->models()),
-      m_docks(new SampleViewDocks(this)), m_toolBar(nullptr)
+    : Manhattan::FancyMainWindow(mainWindow), m_models(mainWindow->models())
+    , m_docks(new SampleViewDocks(this))
+    , m_actions(new SampleViewActions(mainWindow->models()->sampleModel(), this))
+    , m_toolBar(nullptr)
+    , m_statusBar(new SampleViewStatusBar(mainWindow))
 {
     setObjectName("SampleView");
+    m_actions->setSelectionModel(selectionModel());
+
     connectSignals();
 }
 
 ApplicationModels* SampleView::models() { return m_models; }
 
+SampleViewDocks* SampleView::docks()
+{
+    return m_docks;
+}
+
+void SampleView::onDockMenuRequest()
+{
+    std::unique_ptr<QMenu> menu(createPopupMenu());
+    menu->exec(QCursor::pos());
+}
+
+void SampleView::showEvent(QShowEvent*event)
+{
+    if (isVisible())
+        m_statusBar->show();
+    Manhattan::FancyMainWindow::showEvent(event);
+}
+
+void SampleView::hideEvent(QHideEvent* event)
+{
+    if (isHidden())
+        m_statusBar->hide();
+    Manhattan::FancyMainWindow::hideEvent(event);
+}
+
 void SampleView::connectSignals()
 {
     connect(this, &SampleView::resetLayout, m_docks, &SampleViewDocks::onResetLayout);
+    connect(m_statusBar, &SampleViewStatusBar::dockMenuRequest,
+            this, &SampleView::onDockMenuRequest);
 
     // toolBar should be initialized after MaterialBrowser
-    m_toolBar = new SampleToolBar(models()->sampleModel(), selectionModel(), this);
+    m_toolBar = new SampleToolBar(m_actions, this);
     connect(m_toolBar, SIGNAL(deleteItems()), sampleDesigner()->getView(),
             SLOT(deleteSelectedItems()));
     connect(m_toolBar, SIGNAL(selectionMode(int)), sampleDesigner()->getView(),
@@ -43,7 +79,6 @@ void SampleView::connectSignals()
     connect(sampleDesigner()->getView(), SIGNAL(selectionModeChanged(int)), m_toolBar,
             SLOT(onViewSelectionMode(int)));
     connect(m_toolBar, SIGNAL(centerView()), sampleDesigner()->getView(), SLOT(onCenterView()));
-    connect(m_toolBar, SIGNAL(smartAlign()), sampleDesigner(), SLOT(onSmartAlign()));
     connect(m_toolBar, SIGNAL(changeScale(double)), sampleDesigner()->getView(),
             SLOT(onChangeScale(double)));
 
diff --git a/GUI/coregui/Views/SampleView.h b/GUI/coregui/Views/SampleView.h
index e1c1b40b1560d431d0cc0d2f99520d27bb55af22..dda0ef646f8a3fb63e8c5842061c5fd20d110cac 100644
--- a/GUI/coregui/Views/SampleView.h
+++ b/GUI/coregui/Views/SampleView.h
@@ -24,6 +24,10 @@ class SampleDesigner;
 class SampleToolBar;
 class ApplicationModels;
 class QItemSelectionModel;
+class SampleViewStatusBar;
+class QShowEvent;
+class QHideEvent;
+class SampleViewActions;
 
 class BA_CORE_API_ SampleView : public Manhattan::FancyMainWindow
 {
@@ -34,6 +38,15 @@ public:
 
     ApplicationModels* models();
 
+    SampleViewDocks* docks();
+
+public slots:
+    void onDockMenuRequest();
+
+protected:
+    virtual void showEvent(QShowEvent* event);
+    virtual void hideEvent(QHideEvent* event);
+
 private:
     void connectSignals();
 
@@ -45,7 +58,11 @@ private:
 
     SampleDesigner* sampleDesigner();
 
+    SampleViewActions* m_actions;
+
     SampleToolBar* m_toolBar;
+
+    SampleViewStatusBar* m_statusBar;
 };
 
 #endif // SAMPLEVIEW_H
diff --git a/GUI/coregui/Views/SimulationWidgets/PythonScriptWidget.cpp b/GUI/coregui/Views/SimulationWidgets/PythonScriptWidget.cpp
index 6fb846219174905b1ffbed214c6f67c6ae97d732..f95f7ff5da35145fd909191199f5091fcc750903 100644
--- a/GUI/coregui/Views/SimulationWidgets/PythonScriptWidget.cpp
+++ b/GUI/coregui/Views/SimulationWidgets/PythonScriptWidget.cpp
@@ -34,7 +34,7 @@
 
 PythonScriptWidget::PythonScriptWidget(QWidget *parent)
     : QDialog(parent)
-    , m_toolBar(0)
+    , m_toolBar(nullptr)
     , m_textEdit(new QTextEdit)
     , m_warningSign(new WarningSign(m_textEdit))
 {
@@ -104,19 +104,28 @@ void PythonScriptWidget::generatePythonScript(const MultiLayerItem *sampleItem,
     }
 }
 
+
+
 void PythonScriptWidget::onExportToFileButton()
 {
     QString dirname(m_outputDir);
     if (dirname.isEmpty())
         dirname = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
 
-    QString file_name = QFileDialog::getSaveFileName(
-        this, "Select file", dirname, "Python scipts (*.py)", 0, QFileDialog::DontResolveSymlinks);
+    QString filters("Python scripts (*.py)");
+    QString defaultFilter("Python scripts (*.py)");
+    QString defaultName = dirname + QString("/untitled");
 
-    if (file_name.isEmpty())
+    QString fileName = QFileDialog::getSaveFileName(nullptr, "Save file", defaultName,
+        filters, &defaultFilter);
+
+    if (fileName.isEmpty())
         return;
 
-    QFile file(file_name);
+    if(!fileName.endsWith(".py"))
+        fileName += ".py";
+
+    QFile file(fileName);
     if (!file.open(QIODevice::WriteOnly)) {
         QMessageBox warning_dialog(this);
         warning_dialog.setIcon(QMessageBox::Warning);
diff --git a/GUI/coregui/Views/SimulationWidgets/SimulationSetupAssistant.cpp b/GUI/coregui/Views/SimulationWidgets/SimulationSetupAssistant.cpp
index 2ef69122f16906cb4354dc29fd0a1682bb8146bd..084637ec2740ebd50892bf8c118312268154fae1 100644
--- a/GUI/coregui/Views/SimulationWidgets/SimulationSetupAssistant.cpp
+++ b/GUI/coregui/Views/SimulationWidgets/SimulationSetupAssistant.cpp
@@ -38,7 +38,7 @@ bool SimulationSetupAssistant::isValidSimulationSetup(const MultiLayerItem *mult
     checkFittingSetup(instrumentItem, realData);
 
     if(!m_isValid)
-        QMessageBox::warning(0, QStringLiteral("Can't run the job"), composeMessage());
+        QMessageBox::warning(nullptr, QStringLiteral("Can't run the job"), composeMessage());
 
     return m_isValid;
 }
@@ -77,13 +77,12 @@ void SimulationSetupAssistant::checkInstrumentItem(const InstrumentItem* instrum
 void SimulationSetupAssistant::checkFittingSetup(const InstrumentItem* instrumentItem,
                                                  const RealDataItem* realData)
 {
-    if(!realData || instrumentItem->shape() == realData->shape())
+    if (!realData || !instrumentItem || instrumentItem->alignedWith(realData))
         return;
 
     m_isValid = false;
-    QString message
-        = ImportDataUtils::printShapeMessage(instrumentItem->shape(), realData->shape());
-    m_messages.append("The RealData doesn't match selected instrument: " + message);
+    m_messages.append("The experimental data does not fit in the selected instrument. Try linking "
+                      "them in Import Tab.");
 }
 
 //! Composes the error message for message box.
diff --git a/GUI/coregui/Views/SpecularDataWidgets/SpecularPlot.cpp b/GUI/coregui/Views/SpecularDataWidgets/SpecularPlot.cpp
index 83532d9e8d007a048dfcd0b66951e45d32f3ac78..4cd6d2212772bdaad3bd0368cd3cff118d64cbb4 100644
--- a/GUI/coregui/Views/SpecularDataWidgets/SpecularPlot.cpp
+++ b/GUI/coregui/Views/SpecularDataWidgets/SpecularPlot.cpp
@@ -226,7 +226,6 @@ void SpecularPlot::setDataFromItem(SpecularDataItem* item)
 {
     Q_ASSERT(item);
     auto data = item->getOutputData();
-    Q_ASSERT(data);
     if (!data)
         return;
 
diff --git a/GUI/coregui/Views/TestView.cpp b/GUI/coregui/Views/TestView.cpp
index 6e09826c6f4ea8b95a1254eee1066fd25ff4236c..8c1a1da0eeb24ae84fd0d892880696ee86ed784f 100644
--- a/GUI/coregui/Views/TestView.cpp
+++ b/GUI/coregui/Views/TestView.cpp
@@ -181,7 +181,6 @@ void TestView::test_ba3d()
     layout->setSpacing(0);
 #ifdef BORNAGAIN_OPENGL
     RealSpaceWidget* widget = new RealSpaceWidget(m_mainWindow->sampleModel());
-    widget->setModel(m_mainWindow->sampleModel(), nullptr);
     layout->addWidget(widget);
 #endif
     setLayout(layout);
diff --git a/GUI/coregui/Views/WelcomeView.cpp b/GUI/coregui/Views/WelcomeView.cpp
index 47cb3e8d0aa06e3b689a869f7f1334caad28de3c..82c9dceab123cd4295bbfbde486641c3d2030a3e 100644
--- a/GUI/coregui/Views/WelcomeView.cpp
+++ b/GUI/coregui/Views/WelcomeView.cpp
@@ -22,6 +22,7 @@
 #include "qstringutils.h"
 #include "LayoutUtils.h"
 #include "StyleUtils.h"
+#include "UpdateNotifierWidget.h"
 #include <QCommandLinkButton>
 #include <QDesktopServices>
 #include <QUrl>
@@ -43,7 +44,7 @@ WelcomeView::WelcomeView(MainWindow* parent)
     , m_newUsertButton(nullptr)
     , m_currentProjectLabel(nullptr)
     , m_recentProjectLayout(nullptr)
-    , m_updateNotification(nullptr)
+    , m_notifierWidget(new UpdateNotifierWidget(parent->updateNotifier()))
 {
     QPalette palette;
     palette.setColor(QPalette::Background, QColor(240, 240, 240, 255));
@@ -53,7 +54,7 @@ WelcomeView::WelcomeView(MainWindow* parent)
     auto centralWidgetLayout = new QVBoxLayout;
     centralWidgetLayout->setMargin(0);
     centralWidgetLayout->addWidget(createProjectWidget());
-    centralWidgetLayout->addWidget(createNotificationLabel());
+    centralWidgetLayout->addWidget(m_notifierWidget);
     centralWidgetLayout->addStretch(1);
 
     auto centralWidget = new QWidget;
@@ -145,11 +146,6 @@ void WelcomeView::updateRecentProjectPanel()
     update();
 }
 
-void WelcomeView::setNotificationText(const QString& text)
-{
-    m_updateNotification->setText(text);
-}
-
 void WelcomeView::showEvent(QShowEvent*)
 {
     updateRecentProjectPanel();
@@ -235,17 +231,6 @@ QBoxLayout* WelcomeView::createProjectLayout()
     return result;
 }
 
-QLabel* WelcomeView::createNotificationLabel()
-{
-    m_updateNotification = new QLabel(this);
-    m_updateNotification->setText("");
-    m_updateNotification->setContentsMargins(40, 10, 0, 0);
-    m_updateNotification->setOpenExternalLinks(true);
-    m_updateNotification->setTextInteractionFlags(Qt::TextBrowserInteraction);
-    m_updateNotification->setTextFormat(Qt::RichText);
-    return m_updateNotification;
-}
-
 QFrame* WelcomeView::createSeparationFrame()
 {
     auto result = new QFrame;
diff --git a/GUI/coregui/Views/WelcomeView.h b/GUI/coregui/Views/WelcomeView.h
index cd1291c6173bb8ffdacf83de35d742b6e8d1f1dd..86eb751e442f23529e4b1f3bbe5d441781693a00 100644
--- a/GUI/coregui/Views/WelcomeView.h
+++ b/GUI/coregui/Views/WelcomeView.h
@@ -16,7 +16,7 @@
 #define WELCOMEVIEW_H
 
 #include "WinDllMacros.h"
-#include <QLabel>
+#include <QWidget>
 
 class QPushButton;
 class MainWindow;
@@ -24,6 +24,9 @@ class ProjectManager;
 class QVBoxLayout;
 class FancyLabel;
 class QBoxLayout;
+class UpdateNotifierWidget;
+class QLabel;
+class QFrame;
 
 class BA_CORE_API_ WelcomeView : public QWidget
 {
@@ -35,7 +38,6 @@ public slots:
     void onWebLinkClicked(const QUrl& url);
     void onNewUser();
     void updateRecentProjectPanel();
-    void setNotificationText(const QString& text);
 
 protected:
     void showEvent(QShowEvent*);
@@ -60,7 +62,7 @@ private:
     QPushButton* m_newUsertButton;
     FancyLabel* m_currentProjectLabel;
     QVBoxLayout* m_recentProjectLayout;
-    QLabel* m_updateNotification;
+    UpdateNotifierWidget* m_notifierWidget;
 };
 
 #endif // WELCOMEVIEW_H
diff --git a/GUI/coregui/coregui.qrc b/GUI/coregui/coregui.qrc
index 2e746df3365a1416860ced7a4f6b44f7024b7b6b..96b780b55dea84a31dcdba114c51969e8c1bf7f4 100644
--- a/GUI/coregui/coregui.qrc
+++ b/GUI/coregui/coregui.qrc
@@ -1,9 +1,7 @@
 <RCC>
     <qresource prefix="/">
         <file>images/mode_script.png</file>
-        <file>images/closebutton.png</file>
         <file>images/reset.png</file>
-        <file>images/darkclosebutton.png</file>
         <file>mainwindow/tooltips.xml</file>
         <file>images/treeview-branch-closed.png</file>
         <file>images/treeview-branch-end.png</file>
@@ -15,9 +13,6 @@
         <file>images/expand_arrow.png</file>
         <file>images/splashscreen.png</file>
         <file>images/about_icon.png</file>
-        <file>images/darkarrowdown.png</file>
-        <file>images/darkarrowup.png</file>
-        <file>images/darkclose.png</file>
         <file>images/warning@2x.png</file>
         <file>images/magnifier.png</file>
         <file>images/warning_64x64.png</file>
@@ -58,5 +53,10 @@
         <file>images/offspec_instrument_shaded.svg</file>
         <file>images/specular_instrument.svg</file>
         <file>images/specular_instrument_shaded.svg</file>
+        <file>images/dark-angle-up.svg</file>
+        <file>images/dark-angle-down.svg</file>
+        <file>images/dark-close.svg</file>
+        <file>images/depth_instrument.svg</file>
+        <file>images/depth_instrument_shaded.svg</file>
     </qresource>
 </RCC>
diff --git a/GUI/coregui/images/closebutton.png b/GUI/coregui/images/closebutton.png
deleted file mode 100644
index c978cf51aaaf35cf4bf3939f3ba84eabce4837e8..0000000000000000000000000000000000000000
Binary files a/GUI/coregui/images/closebutton.png and /dev/null differ
diff --git a/GUI/coregui/images/dark-angle-down.svg b/GUI/coregui/images/dark-angle-down.svg
new file mode 100644
index 0000000000000000000000000000000000000000..373fac35c8514fb426c7961d4ff5245c142b7a82
--- /dev/null
+++ b/GUI/coregui/images/dark-angle-down.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1395 736q0 13-10 23l-466 466q-10 10-23 10t-23-10l-466-466q-10-10-10-23t10-23l50-50q10-10 23-10t23 10l393 393 393-393q10-10 23-10t23 10l50 50q10 10 10 23z"/></svg>
\ No newline at end of file
diff --git a/GUI/coregui/images/dark-angle-up.svg b/GUI/coregui/images/dark-angle-up.svg
new file mode 100644
index 0000000000000000000000000000000000000000..6ae24d476defc9fc0f1ffd3aebb59f2e60ef7c57
--- /dev/null
+++ b/GUI/coregui/images/dark-angle-up.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1395 1184q0 13-10 23l-50 50q-10 10-23 10t-23-10l-393-393-393 393q-10 10-23 10t-23-10l-50-50q-10-10-10-23t10-23l466-466q10-10 23-10t23 10l466 466q10 10 10 23z"/></svg>
\ No newline at end of file
diff --git a/GUI/coregui/images/dark-close.svg b/GUI/coregui/images/dark-close.svg
new file mode 100644
index 0000000000000000000000000000000000000000..bc2c38bed391fefcad569d694dfc83cd93b5ac20
--- /dev/null
+++ b/GUI/coregui/images/dark-close.svg
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   data-name="Layer 1"
+   viewBox="0 0 1400 1400"
+   x="0px"
+   y="0px"
+   version="1.1"
+   id="svg10"
+   sodipodi:docname="noun_Close_1983622_mod.svg"
+   width="1400"
+   height="1400"
+   inkscape:version="0.92.2 5c3e80d, 2017-08-06">
+  <metadata
+     id="metadata16">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title>icon-01</dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs14" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="3734"
+     inkscape:window-height="2053"
+     id="namedview12"
+     showgrid="false"
+     inkscape:zoom="0.52149125"
+     inkscape:cx="149.57781"
+     inkscape:cy="504.40678"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg10" />
+  <title
+     id="title2">icon-01</title>
+  <path
+     d="m 771.35999,699.99996 375.29601,-375.296 c 18.944,-18.944 18.944,-50.176 0,-69.12 l -2.048,-2.048 c -18.944,-18.944 -50.176,-18.944 -69.12,0 l -375.29601,375.80801 -375.296,-375.808 c -18.944,-18.944 -50.176,-18.944 -69.12,0 l -2.048,2.048 c -19.456,18.944 -19.456,50.176 0,69.12 l 375.296,375.29599 -375.296,375.29604 c -18.944,18.944 -18.944,50.176 0,69.12 l 2.048,2.048 c 18.944,18.944 50.176,18.944 69.12,0 L 700.19199,771.16796 1075.488,1146.464 c 18.944,18.944 50.176,18.944 69.12,0 l 2.048,-2.048 c 18.944,-18.944 18.944,-50.176 0,-69.12 z"
+     id="path4"
+     inkscape:connector-curvature="0"
+     style="fill:#000000" />
+</svg>
diff --git a/GUI/coregui/images/darkarrowdown.png b/GUI/coregui/images/darkarrowdown.png
deleted file mode 100644
index 3b07da15ffbdb11622ae8d109d2e8a058d477393..0000000000000000000000000000000000000000
Binary files a/GUI/coregui/images/darkarrowdown.png and /dev/null differ
diff --git a/GUI/coregui/images/darkarrowup.png b/GUI/coregui/images/darkarrowup.png
deleted file mode 100644
index 3d751f9a1a03919d59b1e1ab71715905f12f2bda..0000000000000000000000000000000000000000
Binary files a/GUI/coregui/images/darkarrowup.png and /dev/null differ
diff --git a/GUI/coregui/images/darkclose.png b/GUI/coregui/images/darkclose.png
deleted file mode 100644
index 365fdb8ed7c11d118960cc56e3b2b16c91079cca..0000000000000000000000000000000000000000
Binary files a/GUI/coregui/images/darkclose.png and /dev/null differ
diff --git a/GUI/coregui/images/darkclosebutton.png b/GUI/coregui/images/darkclosebutton.png
deleted file mode 100644
index 5cc547750591d01bf48a7060940b7786e0315766..0000000000000000000000000000000000000000
Binary files a/GUI/coregui/images/darkclosebutton.png and /dev/null differ
diff --git a/GUI/coregui/images/depth_instrument.svg b/GUI/coregui/images/depth_instrument.svg
new file mode 100644
index 0000000000000000000000000000000000000000..ce1691a95c0f38cf55262c8e13539b2de8510d42
--- /dev/null
+++ b/GUI/coregui/images/depth_instrument.svg
@@ -0,0 +1,231 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="120mm"
+   height="100mm"
+   viewBox="0 0 425.19685 354.33071"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.92.2 5c3e80d, 2017-08-06"
+   sodipodi:docname="depth_instrument.svg">
+  <defs
+     id="defs4">
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient8154">
+      <stop
+         style="stop-color:#2e708e;stop-opacity:1;"
+         offset="0"
+         id="stop8156" />
+      <stop
+         style="stop-color:#2e708e;stop-opacity:0;"
+         offset="1"
+         id="stop8158" />
+    </linearGradient>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="marker8100"
+       style="overflow:visible;"
+       inkscape:isstock="true">
+      <path
+         id="path8102"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#666666;fill-opacity:1"
+         d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
+         transform="scale(0.6) rotate(180) translate(0,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="marker7614"
+       style="overflow:visible;"
+       inkscape:isstock="true">
+      <path
+         id="path7616"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#808080;fill-opacity:1"
+         d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
+         transform="scale(0.6) rotate(180) translate(0,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow2Mend"
+       style="overflow:visible;"
+       inkscape:isstock="true">
+      <path
+         id="path4215"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
+         d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
+         transform="scale(0.6) rotate(180) translate(0,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Lend"
+       style="overflow:visible;"
+       inkscape:isstock="true">
+      <path
+         id="path4191"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+         transform="scale(0.8) rotate(180) translate(12.5,0)" />
+    </marker>
+    <linearGradient
+       id="linearGradient3926">
+      <stop
+         style="stop-color:#c3c3c3;stop-opacity:1;"
+         offset="0"
+         id="stop3928" />
+      <stop
+         style="stop-color:#f9f9f9;stop-opacity:1;"
+         offset="1"
+         id="stop3930" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient4824"
+       osb:paint="gradient">
+      <stop
+         id="stop4826"
+         offset="0"
+         style="stop-color:#0f0f0f;stop-opacity:1;" />
+      <stop
+         id="stop4828"
+         offset="1"
+         style="stop-color:#ffffff;stop-opacity:1;" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient8154"
+       id="radialGradient8160"
+       cx="212.61386"
+       cy="980.53461"
+       fx="212.61386"
+       fy="980.53461"
+       r="88.193645"
+       gradientTransform="matrix(1.6097682,-0.09850357,0.05509362,0.90035282,-179.99872,95.95872)"
+       gradientUnits="userSpaceOnUse" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="2.8284271"
+     inkscape:cx="149.52061"
+     inkscape:cy="214.87681"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     inkscape:window-width="3734"
+     inkscape:window-height="2053"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1">
+    <inkscape:grid
+       type="xygrid"
+       id="grid4136"
+       units="mm"
+       spacingx="3.5433072"
+       spacingy="3.543307" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-698.0315)">
+    <path
+       style="fill:url(#radialGradient8160);fill-opacity:1;fill-rule:nonzero;stroke:#2e708e;stroke-width:3.54330707;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.55502391"
+       d="M 333.19322,955.75053 A 121.19404,43.683304 0 0 1 211.99918,999.43385 121.19404,43.683304 0 0 1 90.805141,955.75053 121.19404,43.683304 0 0 1 211.99918,912.06723 121.19404,43.683304 0 0 1 333.19322,955.75053 Z"
+       id="path4180"
+       inkscape:connector-curvature="0" />
+    <g
+       id="g10049"
+       style="stroke-width:3.54330707;stroke-miterlimit:4;stroke-dasharray:none"
+       transform="translate(0.1397892,-16.56685)">
+      <path
+         style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.54330707;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         d="m 17.779297,971.33594 v 7.08594 H 397.30664 v -7.08594 z"
+         inkscape:connector-curvature="0"
+         id="path25" />
+      <path
+         d="m 360.23636,957.7274 46.45648,17.08322 -46.45648,17.08322 c 7.4218,-10.08592 7.37904,-23.88522 0,-34.16644 z"
+         style="fill:#808080;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:3.54330707;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         id="path10053"
+         inkscape:connector-curvature="0" />
+    </g>
+    <g
+       id="g10029"
+       style="stroke-width:3.54330707;stroke-miterlimit:4;stroke-dasharray:none"
+       transform="translate(-7.3602108,-16.06685)">
+      <path
+         style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.54330707;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         d="m 216.41602,810.83789 v 161.92188 h 7.08593 V 810.83789 Z"
+         id="path8098"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 202.80761,847.90816 17.08322,-46.45649 17.08323,46.45649 c -10.08593,-7.4218 -23.88523,-7.37904 -34.16645,0 z"
+         style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:3.54330707;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         id="path10035"
+         inkscape:connector-curvature="0" />
+    </g>
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#b00000;stroke-width:3.5433073;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 49.794197,869.58845 212.92633,955.97472"
+       id="path8186"
+       inkscape:connector-curvature="0" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#cb0000;stroke-width:3.54330683;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="m 212.92718,955.6176 38.78742,62.4612"
+       id="path8188"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <text
+       xml:space="preserve"
+       style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       x="0.3129921"
+       y="768.31104"
+       id="text9903"><tspan
+         sodipodi:role="line"
+         id="tspan9905"
+         x="0.3129921"
+         y="768.31104"
+         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:50px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#666666">Depth</tspan></text>
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e708e;fill-opacity:0.55502391;fill-rule:nonzero;stroke:none;stroke-width:3.5433073;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 92.323785,972.92573 c -1.984429,3.2663 -3.076172,6.7153 -3.076172,10.3015 -7e-6,6.69552 3.772438,12.91972 10.147701,18.35257 6.375276,5.433 15.419876,10.2004 26.521006,14.2017 22.20225,8.0026 52.66006,12.9016 86.29943,12.9016 33.63939,0 64.09353,-4.899 86.29578,-12.9016 11.10111,-4.0013 20.14572,-8.7687 26.52099,-14.2017 6.37527,-5.43285 10.14771,-11.65705 10.14771,-18.35257 0,-2.3587 -0.4773,-4.6572 -1.3623,-6.8848 -0.73771,1.2145 -1.59644,2.4041 -2.57447,3.5651 0.25703,1.1015 0.39367,2.2085 0.39367,3.3197 0,5.36732 -3.01234,10.63422 -8.90258,15.65372 -5.89023,5.01955 -14.59352,9.66605 -25.42419,13.56985 -21.66138,7.8077 -51.80034,12.6892 -85.09461,12.6892 -33.29426,0 -63.43689,-4.8815 -85.09826,-12.6892 -10.83069,-3.9038 -19.53397,-8.5503 -25.42419,-13.56985 -5.890242,-5.0195 -8.902601,-10.2864 -8.902597,-15.65372 1e-6,-2.1796 0.50603,-4.343 1.490479,-6.4801 -0.789665,-1.2473 -1.441374,-2.522 -1.957397,-3.8214 z"
+       id="path4180-5"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>
diff --git a/GUI/coregui/images/depth_instrument_shaded.svg b/GUI/coregui/images/depth_instrument_shaded.svg
new file mode 100644
index 0000000000000000000000000000000000000000..e5034d8382f505567ba9a6b632df4b3e1d61103f
--- /dev/null
+++ b/GUI/coregui/images/depth_instrument_shaded.svg
@@ -0,0 +1,217 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="120mm"
+   height="100mm"
+   viewBox="0 0 425.19685 354.33071"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.92.2 5c3e80d, 2017-08-06"
+   sodipodi:docname="depth_instrument_shaded.svg">
+  <defs
+     id="defs4">
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="marker8100"
+       style="overflow:visible;"
+       inkscape:isstock="true">
+      <path
+         id="path8102"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#666666;fill-opacity:1"
+         d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
+         transform="scale(0.6) rotate(180) translate(0,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="marker7614"
+       style="overflow:visible;"
+       inkscape:isstock="true">
+      <path
+         id="path7616"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#808080;fill-opacity:1"
+         d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
+         transform="scale(0.6) rotate(180) translate(0,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow2Mend"
+       style="overflow:visible;"
+       inkscape:isstock="true">
+      <path
+         id="path4215"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
+         d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
+         transform="scale(0.6) rotate(180) translate(0,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Lend"
+       style="overflow:visible;"
+       inkscape:isstock="true">
+      <path
+         id="path4191"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+         transform="scale(0.8) rotate(180) translate(12.5,0)" />
+    </marker>
+    <linearGradient
+       id="linearGradient3926">
+      <stop
+         style="stop-color:#c3c3c3;stop-opacity:1;"
+         offset="0"
+         id="stop3928" />
+      <stop
+         style="stop-color:#f9f9f9;stop-opacity:1;"
+         offset="1"
+         id="stop3930" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient4824"
+       osb:paint="gradient">
+      <stop
+         id="stop4826"
+         offset="0"
+         style="stop-color:#0f0f0f;stop-opacity:1;" />
+      <stop
+         id="stop4828"
+         offset="1"
+         style="stop-color:#ffffff;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3926"
+       id="linearGradient899"
+       x1="89.033485"
+       y1="955.75055"
+       x2="334.96487"
+       y2="955.75055"
+       gradientUnits="userSpaceOnUse" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="2.8284271"
+     inkscape:cx="82.345465"
+     inkscape:cy="214.87681"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     inkscape:window-width="3734"
+     inkscape:window-height="2053"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1">
+    <inkscape:grid
+       type="xygrid"
+       id="grid4136"
+       units="mm"
+       spacingx="3.5433072"
+       spacingy="3.543307" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-698.0315)">
+    <path
+       style="fill:url(#linearGradient899);fill-opacity:1;fill-rule:nonzero;stroke:#2e708e;stroke-width:3.54330707;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.27160493"
+       d="M 333.19322,955.75053 A 121.19404,43.683304 0 0 1 211.99918,999.43385 121.19404,43.683304 0 0 1 90.805141,955.75053 121.19404,43.683304 0 0 1 211.99918,912.06723 121.19404,43.683304 0 0 1 333.19322,955.75053 Z"
+       id="path4180"
+       inkscape:connector-curvature="0" />
+    <g
+       id="g10049"
+       style="stroke-width:3.54330707;stroke-miterlimit:4;stroke-dasharray:none;stroke:#c8c8c8;stroke-opacity:0.19607843;fill:#000000;fill-opacity:0.19607843"
+       transform="translate(0.1397892,-16.56685)">
+      <path
+         style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:0.19607843;fill-rule:evenodd;stroke:#c8c8c8;stroke-width:3.54330707;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.19607843;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         d="m 17.779297,971.33594 v 7.08594 H 397.30664 v -7.08594 z"
+         inkscape:connector-curvature="0"
+         id="path25" />
+      <path
+         d="m 360.23636,957.7274 46.45648,17.08322 -46.45648,17.08322 c 7.4218,-10.08592 7.37904,-23.88522 0,-34.16644 z"
+         style="fill:#000000;fill-opacity:0.19607843;fill-rule:evenodd;stroke:#c8c8c8;stroke-width:3.54330707;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.19607843"
+         id="path10053"
+         inkscape:connector-curvature="0" />
+    </g>
+    <g
+       id="g10029"
+       style="stroke-width:3.54330707;stroke-miterlimit:4;stroke-dasharray:none;fill:#000000;fill-opacity:0.19607843;stroke:#c8c8c8;stroke-opacity:0.19607843"
+       transform="translate(-7.3602108,-16.06685)">
+      <path
+         style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:0.19607843;fill-rule:evenodd;stroke:#c8c8c8;stroke-width:3.54330707;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.19607843;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         d="m 216.41602,810.83789 v 161.92188 h 7.08593 V 810.83789 Z"
+         id="path8098"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 202.80761,847.90816 17.08322,-46.45649 17.08323,46.45649 c -10.08593,-7.4218 -23.88523,-7.37904 -34.16645,0 z"
+         style="fill:#000000;fill-opacity:0.19607843;fill-rule:evenodd;stroke:#c8c8c8;stroke-width:3.54330707;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.19607843"
+         id="path10035"
+         inkscape:connector-curvature="0" />
+    </g>
+    <path
+       style="fill:#2e708e;fill-rule:evenodd;stroke:#b00000;stroke-width:3.5433073;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.20987654;fill-opacity:0.2345679"
+       d="M 49.794197,869.58845 212.92633,955.97472"
+       id="path8186"
+       inkscape:connector-curvature="0" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#cb0000;stroke-width:3.54330683;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.20576131"
+       d="m 212.92718,955.6176 38.78742,62.4612"
+       id="path8188"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <text
+       xml:space="preserve"
+       style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:0.19607843;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;"
+       x="0.3129921"
+       y="768.31104"
+       id="text9903"><tspan
+         sodipodi:role="line"
+         id="tspan9905"
+         x="0.3129921"
+         y="768.31104"
+         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:50px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#000000;fill-opacity:0.19607843;">Depth</tspan></text>
+    <path
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e708e;fill-opacity:0.05349794;fill-rule:nonzero;stroke:#2e708e;stroke-width:3.5433073;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.22633745;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 92.323785,972.92573 c -1.984429,3.2663 -3.076172,6.7153 -3.076172,10.3015 -7e-6,6.69552 3.772438,12.91972 10.147701,18.35257 6.375276,5.433 15.419876,10.2004 26.521006,14.2017 22.20225,8.0026 52.66006,12.9016 86.29943,12.9016 33.63939,0 64.09353,-4.899 86.29578,-12.9016 11.10111,-4.0013 20.14572,-8.7687 26.52099,-14.2017 6.37527,-5.43285 10.14771,-11.65705 10.14771,-18.35257 0,-2.3587 -0.4773,-4.6572 -1.3623,-6.8848 -0.73771,1.2145 -1.59644,2.4041 -2.57447,3.5651 0.25703,1.1015 0.39367,2.2085 0.39367,3.3197 0,5.36732 -3.01234,10.63422 -8.90258,15.65372 -5.89023,5.01955 -14.59352,9.66605 -25.42419,13.56985 -21.66138,7.8077 -51.80034,12.6892 -85.09461,12.6892 -33.29426,0 -63.43689,-4.8815 -85.09826,-12.6892 -10.83069,-3.9038 -19.53397,-8.5503 -25.42419,-13.56985 -5.890242,-5.0195 -8.902601,-10.2864 -8.902597,-15.65372 1e-6,-2.1796 0.50603,-4.343 1.490479,-6.4801 -0.789665,-1.2473 -1.441374,-2.522 -1.957397,-3.8214 z"
+       id="path4180-5"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>
diff --git a/GUI/coregui/mainwindow/OutputDataIOHistory.cpp b/GUI/coregui/mainwindow/OutputDataIOHistory.cpp
index c913ad20545c7681f01f3cf28a6520ec4e1604cd..ab56bd305675fc7e5974ea46d9181467976cda17 100644
--- a/GUI/coregui/mainwindow/OutputDataIOHistory.cpp
+++ b/GUI/coregui/mainwindow/OutputDataIOHistory.cpp
@@ -14,15 +14,16 @@
 
 #include "OutputDataIOHistory.h"
 #include "GUIHelpers.h"
+#include "SaveLoadInterface.h"
 
-//! Static method to create info for just saved IntensityDataItem.
+//! Static method to create info for just saved item.
 
-OutputDataSaveInfo OutputDataSaveInfo::createSaved(const DataItem *item)
+OutputDataSaveInfo OutputDataSaveInfo::createSaved(const SaveLoadInterface* item)
 {
     Q_ASSERT(item);
 
     OutputDataSaveInfo result;
-    result.m_dataItem = item;
+    result.m_data = item;
     result.m_file_name = item->fileName();
     result.m_last_saved = QDateTime::currentDateTime();
     return result;
@@ -30,7 +31,7 @@ OutputDataSaveInfo OutputDataSaveInfo::createSaved(const DataItem *item)
 
 bool OutputDataSaveInfo::wasModifiedSinceLastSave() const
 {
-    return wasSavedBefore(m_dataItem->lastModified());
+    return wasSavedBefore(m_data->lastModified());
 }
 
 //! Returns true if IntensityDataItem was saved before given time.
@@ -43,31 +44,31 @@ bool OutputDataSaveInfo::wasSavedBefore(const QDateTime& dtime) const
 
 //-----------------------------------------------------------------------------
 
-void OutputDataDirHistory::markAsSaved(const DataItem *item)
+void OutputDataDirHistory::markAsSaved(const SaveLoadInterface *item)
 {
     if (contains(item))
         throw GUIHelpers::Error("OutputDataDirHistory::markAsSaved() -> Error. "
                                 "Already existing item.");
-    // Don't create any history info for empty DataItems
-    if (item->getOutputData())
+    // Don't create any history info for empty items
+    if (item->containsNonXMLData())
         m_history.push_back(OutputDataSaveInfo::createSaved(item));
 }
 
-bool OutputDataDirHistory::wasModifiedSinceLastSave(const DataItem *item)
+bool OutputDataDirHistory::wasModifiedSinceLastSave(const SaveLoadInterface* item)
 {
     // non existing item is treated as modified since last save
     return contains(item) ? itemInfo(item).wasModifiedSinceLastSave() : true;
 }
 
-bool OutputDataDirHistory::contains(const DataItem *item) {
+bool OutputDataDirHistory::contains(const SaveLoadInterface* item) {
     for(auto& info : m_history)
-        if(info.dataItem() == item)
+        if(info.item() == item)
             return true;
 
     return false;
 }
 
-//! Returns list of file names used to save all IntensityDataItem in a history.
+//! Returns list of file names used to save all items in a history.
 
 QStringList OutputDataDirHistory::savedFileNames() const
 {
@@ -79,10 +80,10 @@ QStringList OutputDataDirHistory::savedFileNames() const
     return result;
 }
 
-OutputDataSaveInfo OutputDataDirHistory::itemInfo(const DataItem* item) const
+OutputDataSaveInfo OutputDataDirHistory::itemInfo(const SaveLoadInterface* item) const
 {
     for(auto& info : m_history) {
-        if (info.dataItem() == item)
+        if (info.item() == item)
             return info;
     }
 
@@ -97,7 +98,7 @@ bool OutputDataIOHistory::hasHistory(const QString& dirname) const
 }
 
 bool OutputDataIOHistory::wasModifiedSinceLastSave(const QString& dirname,
-                                                   const DataItem *item)
+                                                   const SaveLoadInterface* item)
 {
     if (!hasHistory(dirname))
         throw GUIHelpers::Error("OutputDataIOHistory::wasModifiedSinceLastSave() -> Error. "
diff --git a/GUI/coregui/mainwindow/OutputDataIOHistory.h b/GUI/coregui/mainwindow/OutputDataIOHistory.h
index 2bc9cd7fa8d2efa9f8018ee55a59197f5dc20f17..39ec3b6cbabc065adf4c0a2c6d9113169dc1bd88 100644
--- a/GUI/coregui/mainwindow/OutputDataIOHistory.h
+++ b/GUI/coregui/mainwindow/OutputDataIOHistory.h
@@ -16,22 +16,22 @@
 #define OUTPUTDATAIOHISTORY_H
 
 #include "WinDllMacros.h"
-#include "DataItem.h"
+#include <QMap>
 #include <QVector>
 #include <QDateTime>
 
-class IntensityDataItem;
+class SaveLoadInterface;
 
-//! Holds information about last save for IntensityDataItem.
+//! Holds information about last save for items with non-XML data.
 
 class BA_CORE_API_ OutputDataSaveInfo
 {
 public:
-    OutputDataSaveInfo() : m_dataItem(nullptr) {}
+    OutputDataSaveInfo() : m_data(nullptr) {}
 
-    static OutputDataSaveInfo createSaved(const DataItem* item);
+    static OutputDataSaveInfo createSaved(const SaveLoadInterface* item);
 
-    const DataItem* dataItem() const { return m_dataItem; }
+    const SaveLoadInterface* item() const { return m_data; }
 
     QString fileName() const { return m_file_name; }
 
@@ -42,25 +42,25 @@ private:
 
     QDateTime m_last_saved;
     QString m_file_name;
-    const DataItem* m_dataItem;
+    const SaveLoadInterface* m_data;
 };
 
-//! Save history information for collection of IntensityDataItems.
+//! Save history information for collection of items with non-XML data.
 
 class BA_CORE_API_ OutputDataDirHistory {
 public:
     OutputDataDirHistory() {}
 
-    void markAsSaved(const DataItem* item);
+    void markAsSaved(const SaveLoadInterface* item);
 
-    bool wasModifiedSinceLastSave(const DataItem* item);
+    bool wasModifiedSinceLastSave(const SaveLoadInterface* item);
 
-    bool contains(const DataItem* item);
+    bool contains(const SaveLoadInterface* item);
 
     QStringList savedFileNames() const;
 
 private:
-    OutputDataSaveInfo itemInfo(const DataItem* item) const;
+    OutputDataSaveInfo itemInfo(const SaveLoadInterface* item) const;
 
     QVector<OutputDataSaveInfo> m_history;
 };
@@ -71,7 +71,7 @@ class BA_CORE_API_ OutputDataIOHistory {
 public:
     bool hasHistory(const QString& dirname) const;
 
-    bool wasModifiedSinceLastSave(const QString& dirname, const DataItem* item);
+    bool wasModifiedSinceLastSave(const QString& dirname, const SaveLoadInterface* item);
 
     void setHistory(const QString& dirname, const OutputDataDirHistory& history);
 
diff --git a/GUI/coregui/mainwindow/OutputDataIOService.cpp b/GUI/coregui/mainwindow/OutputDataIOService.cpp
index 44e2c76fbb1740a6e965b0b0fbfe956eb45d0d85..139e37a0bd1a1fb20044cafd14db92f811781a8a 100644
--- a/GUI/coregui/mainwindow/OutputDataIOService.cpp
+++ b/GUI/coregui/mainwindow/OutputDataIOService.cpp
@@ -14,24 +14,18 @@
 
 #include "OutputDataIOService.h"
 #include "ApplicationModels.h"
-#include "DataItem.h"
-#include "JobItemUtils.h"
+#include "IntensityDataIOFactory.h"
 #include "ProjectUtils.h"
 #include "MessageService.h"
 #include "JobItem.h"
 #include "ModelPath.h"
+#include "SaveLoadInterface.h"
 #include "item_constants.h"
 
-namespace {
-
-BA_CORE_API_ JobItem* parentJobItem(DataItem* dataItem)
+namespace
 {
-    auto jobItem = dynamic_cast<const JobItem*>(
-                ModelPath::ancestor(dataItem, Constants::JobItemType));
-    return const_cast<JobItem*>(jobItem);
-}
-
-}
+JobItem* parentJobItem(SaveLoadInterface* item);
+} // namespace
 
 OutputDataIOService::OutputDataIOService(QObject* parent)
     : QObject(parent), m_applicationModels(nullptr)
@@ -58,11 +52,9 @@ void OutputDataIOService::save(const QString& projectDir)
 
     OutputDataDirHistory newHistory;
 
-    for (auto item : dataItems()) {
-
+    for (auto item : nonXMLItems()) {
         if (m_history.wasModifiedSinceLastSave(projectDir, item))
-            JobItemUtils::saveIntensityData(item, projectDir);
-
+            item->save(projectDir);
         newHistory.markAsSaved(item);
     }
 
@@ -71,7 +63,7 @@ void OutputDataIOService::save(const QString& projectDir)
     QStringList newFiles = newHistory.savedFileNames();
     cleanOldFiles(projectDir, oldFiles, newFiles);
 
-    // if oldHistory contained some deleted IntensityDataItems, that info will be dropped here
+    // if oldHistory contained some deleted items, that info will be dropped here
     m_history.setHistory(projectDir, newHistory);
 }
 
@@ -79,9 +71,9 @@ void OutputDataIOService::load(const QString& projectDir, MessageService* messag
 {
     OutputDataDirHistory newHistory;
 
-    for (auto item : dataItems()) {
+    for (auto item : nonXMLItems()) {
         try {
-            JobItemUtils::loadIntensityData(item, projectDir);
+            item->load(projectDir);
             newHistory.markAsSaved(item);
             // handling crash of GUI during job run and non-existing file
             if (auto jobItem = parentJobItem(item)) {
@@ -106,18 +98,18 @@ void OutputDataIOService::load(const QString& projectDir, MessageService* messag
     m_history.setHistory(projectDir, newHistory);
 }
 
-//! Returns all IntensityDataItems available for save/load.
+//! Returns all non-XML items available for save/load.
 
-QVector<DataItem*> OutputDataIOService::dataItems() const
+QVector<SaveLoadInterface*> OutputDataIOService::nonXMLItems() const
 {
-    QVector<DataItem*> result;
+    QVector<SaveLoadInterface*> result;
 
     if (!m_applicationModels)
         return result;
 
     for (auto item : m_applicationModels->nonXMLData())
-        if (auto data_item = dynamic_cast<DataItem*>(item))
-            result.push_back(data_item);
+        if (auto non_xml_item = dynamic_cast<SaveLoadInterface*>(item))
+            result.push_back(non_xml_item);
 
     return result;
 }
@@ -131,3 +123,14 @@ void OutputDataIOService::cleanOldFiles(const QString& projectDir, const QString
     QStringList to_remove = ProjectUtils::substract(oldSaves, newSaves);
     ProjectUtils::removeFiles(projectDir, to_remove);
 }
+
+namespace
+{
+JobItem* parentJobItem(SaveLoadInterface* item)
+{
+    auto session_item = dynamic_cast<SessionItem*>(item); //sidecast
+    auto jobItem =
+        dynamic_cast<const JobItem*>(ModelPath::ancestor(session_item, Constants::JobItemType));
+    return const_cast<JobItem*>(jobItem);
+}
+} // namespace
diff --git a/GUI/coregui/mainwindow/OutputDataIOService.h b/GUI/coregui/mainwindow/OutputDataIOService.h
index 554017de9f66db05fbbc6702c50c5f48e8b01578..7c94086db8a258ec281887feffa0d92ade4eeeea 100644
--- a/GUI/coregui/mainwindow/OutputDataIOService.h
+++ b/GUI/coregui/mainwindow/OutputDataIOService.h
@@ -20,28 +20,28 @@
 #include <QObject>
 
 class ApplicationModels;
-class DataItem;
 class MessageService;
+class SaveLoadInterface;
 
 //! Provide read/write of heavy data files in a separate thread.
 //!
-//! Listens all models and keep tracks of changes in IntensityDataItem. Provides logic to
+//! Listens all models and keep tracks of changes in items. Provides logic to
 //! not to re-save already saved data.
 
 class BA_CORE_API_ OutputDataIOService : public QObject
 {
     Q_OBJECT
 public:
-    explicit OutputDataIOService(QObject* parent = 0);
-    explicit OutputDataIOService(ApplicationModels* models, QObject* parent = 0);
+    explicit OutputDataIOService(QObject* parent = nullptr);
+    explicit OutputDataIOService(ApplicationModels* models, QObject* parent = nullptr);
 
     void setApplicationModels(ApplicationModels* models);
 
     void save(const QString& projectDir);
 
-    void load(const QString& projectDir, MessageService* messageService=nullptr);
+    void load(const QString& projectDir, MessageService* messageService = nullptr);
 
-    QVector<DataItem* > dataItems() const;
+    QVector<SaveLoadInterface* > nonXMLItems() const;
 
 private:
     void cleanOldFiles(const QString& projectDir, const QStringList& oldSaves,
diff --git a/GUI/coregui/mainwindow/ProjectUtils.cpp b/GUI/coregui/mainwindow/ProjectUtils.cpp
index 17e2afb8014f4e797a24fbbe17c1563a56186c8a..9dafdfce19f7d0441301b185eda2d09cbfcfe4e7 100644
--- a/GUI/coregui/mainwindow/ProjectUtils.cpp
+++ b/GUI/coregui/mainwindow/ProjectUtils.cpp
@@ -15,7 +15,7 @@
 #include "ProjectUtils.h"
 #include "projectdocument.h"
 #include "GUIHelpers.h"
-#include "JobItemFunctions.h"
+#include "ItemFileNameUtils.h"
 #include "AppSvc.h"
 #include "projectmanager.h"
 #include <QFileInfo>
@@ -81,7 +81,7 @@ QStringList ProjectUtils::nonXMLDataInDir(const QString &dirname)
         throw GUIHelpers::Error("ProjectUtils::nonXMLDataInDir() -> Error. Non existing "
                                 "directory '"+dirname+"'.");
 
-    return dir.entryList(JobItemFunctions::nonXMLFileNameFilters());
+    return dir.entryList(ItemFileNameUtils::nonXMLFileNameFilters());
 }
 
 bool ProjectUtils::removeRecursively(const QString &dirname)
diff --git a/Tests/Functional/Fit/FitSuite/main.cpp b/GUI/coregui/mainwindow/SaveLoadInterface.cpp
similarity index 55%
rename from Tests/Functional/Fit/FitSuite/main.cpp
rename to GUI/coregui/mainwindow/SaveLoadInterface.cpp
index 60c76ef3f28910fe96fa9db80d8d8ad12e70d325..716a34e4f836200bab65baf7355028e24d4ebe26 100644
--- a/Tests/Functional/Fit/FitSuite/main.cpp
+++ b/GUI/coregui/mainwindow/SaveLoadInterface.cpp
@@ -2,8 +2,8 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Tests/Functional/Fit/main.cpp
-//! @brief     Implements program FitTest to run fit functional tests
+//! @file      GUI/coregui/mainwindow/SaveLoadInterface.cpp
+//! @brief     Impelments save/load interface.
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -12,12 +12,12 @@
 //
 // ************************************************************************** //
 
-#include "TestService.h"
-#include "StandardFitsFactory.h"
+#include "SaveLoadInterface.h"
 
-//! Runs functional tests.
+SaveLoadInterface::~SaveLoadInterface() = default;
 
-int main(int argc, char **argv)
+QString SaveLoadInterface::fileName(const QString& projectDir) const
 {
-    return TestService<StandardFitsFactory>().execute(argc, argv) ? 0 : 1;
+    const auto filename = fileName();
+    return projectDir.isEmpty() ? filename : projectDir + QStringLiteral("/") + filename;
 }
diff --git a/GUI/coregui/mainwindow/SaveLoadInterface.h b/GUI/coregui/mainwindow/SaveLoadInterface.h
new file mode 100644
index 0000000000000000000000000000000000000000..e5ccf78b6b551d1b8283ce374fa581fb3da864ea
--- /dev/null
+++ b/GUI/coregui/mainwindow/SaveLoadInterface.h
@@ -0,0 +1,52 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/mainwindow/SaveLoadInterface.h
+//! @brief     Defines save/load interface.
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef SAVELOADINTERFACE_H
+#define SAVELOADINTERFACE_H
+
+#include "WinDllMacros.h"
+
+#include <QString>
+#include <QDateTime>
+
+//! Purely virtual interface to handle non-XML
+//! data save and load.
+
+class BA_CORE_API_ SaveLoadInterface {
+public:
+    virtual ~SaveLoadInterface();
+
+    //! Loads non-XML data from _projectDir_ and returns
+    //! success flag.
+    virtual bool load(const QString& projectDir) = 0;
+
+    //! Saves non-XML data in _projectDir_ and returns
+    //! success flag.
+    virtual bool save(const QString& projectDir) = 0;
+
+    //! Checks if object owns non-XML data
+    virtual bool containsNonXMLData() const = 0;
+
+    //! Indicates last modification timepoint.
+    virtual QDateTime lastModified() const = 0;
+
+    //! Reports file name to save/load non-XML data.
+    virtual QString fileName() const = 0;
+
+    //! Reports file name to save/load non-XML data with directory
+    //! name attached.
+    QString fileName(const QString& projectDir) const;
+};
+
+#endif // SAVELOADINTERFACE_H
diff --git a/GUI/coregui/mainwindow/UpdateNotifier.cpp b/GUI/coregui/mainwindow/UpdateNotifier.cpp
index 94128f8f27ceb0844792363fcd8f7161255ae29e..fbf16a1a82f26ac3cf78a0fbb8a7e4dde5bc37fb 100644
--- a/GUI/coregui/mainwindow/UpdateNotifier.cpp
+++ b/GUI/coregui/mainwindow/UpdateNotifier.cpp
@@ -15,35 +15,35 @@
 #include "UpdateNotifier.h"
 #include "GUIHelpers.h"
 #include "mainwindow_constants.h"
-#include <QMessageBox>
 #include <QtNetwork>
 
-UpdateNotifier::UpdateNotifier(QObject *parent)
+UpdateNotifier::UpdateNotifier(QObject* parent)
     : QObject(parent), m_networkAccessManager(new QNetworkAccessManager(parent))
 {
-    connect(m_networkAccessManager, SIGNAL(finished(QNetworkReply *)), this,
-            SLOT(replyFinished(QNetworkReply *)));
+    connect(m_networkAccessManager, &QNetworkAccessManager::finished,
+            this, &UpdateNotifier::replyFinished);
 }
 
 void UpdateNotifier::checkForUpdates()
 {
-    QSettings settings;
-    if (settings.childGroups().contains(Constants::S_UPDATES)) {
-        settings.beginGroup(Constants::S_UPDATES);
-        if (settings.value(Constants::S_CHECKFORUPDATES).toBool()) {
+    if (hasDefinedUpdatesFlag()) {
+        if (updatesFlag()) {
             QString address(Constants::S_VERSION_URL);
             QUrl url(address);
             QNetworkRequest networkRequest(url);
-            networkRequest.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork);
-            QString text = QString("Mozilla/5.0 (BornAgainGUI-%1)").arg(GUIHelpers::getBornAgainVersionString());
+            networkRequest.setAttribute(QNetworkRequest::CacheLoadControlAttribute,
+                                        QNetworkRequest::AlwaysNetwork);
+            QString text = QString("Mozilla/5.0 (BornAgainGUI-%1)")
+                               .arg(GUIHelpers::getBornAgainVersionString());
             networkRequest.setRawHeader(QByteArray("User-Agent"), text.toLatin1());
             m_networkAccessManager->get(networkRequest);
-        } else
+        } else {
             emit onUpdateNotification(QString(""));
+        }
     }
 }
 
-void UpdateNotifier::replyFinished(QNetworkReply *reply)
+void UpdateNotifier::replyFinished(QNetworkReply* reply)
 {
     QString replyString;
     if (reply->error() == QNetworkReply::NoError) {
@@ -56,7 +56,7 @@ void UpdateNotifier::replyFinished(QNetworkReply *reply)
             QString myVersion = GUIHelpers::getBornAgainVersionString();
 
             // Testwise degrade version
-            // QString myVersion = QString("1.3.0");
+            // myVersion = QString("1.1.0");
 
             if (GUIHelpers::versionCode(versionString) > GUIHelpers::versionCode(myVersion)) {
                 QString message("New version is available: <a href=\"");
@@ -65,26 +65,38 @@ void UpdateNotifier::replyFinished(QNetworkReply *reply)
                 message.append(replyString);
                 message.append("</a>");
                 emit onUpdateNotification(message);
+            } else {
+                emit onUpdateNotification(QString(""));
             }
         }
     };
     reply->deleteLater();
 }
 
-void UpdateNotifier::askForUpdates()
+void UpdateNotifier::setCheckUpdatesFlag(bool flag)
 {
     QSettings settings;
-    if (!settings.childGroups().contains(Constants::S_UPDATES)) {
-        QMessageBox msgBox;
-        msgBox.setWindowTitle("Updates");
-        msgBox.setText("Should BornAgain check for updates automatically?\n"
-                       "This setting can be changed later in the main window Settings menu.");
-        msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
-        msgBox.setDefaultButton(QMessageBox::Yes);
-        int ret = msgBox.exec();
+    settings.beginGroup(Constants::S_UPDATES);
+    settings.setValue(Constants::S_CHECKFORUPDATES, flag);
+    settings.endGroup();
+}
+
+//! Returns true if there is defined flag requiring check for updates.
+
+bool UpdateNotifier::updatesFlag() const
+{
+    QSettings settings;
+    if (settings.childGroups().contains(Constants::S_UPDATES)) {
         settings.beginGroup(Constants::S_UPDATES);
-        settings.setValue(Constants::S_CHECKFORUPDATES, ret == QMessageBox::Yes);
-        settings.endGroup();
+        return settings.value(Constants::S_CHECKFORUPDATES).toBool();
     }
-    this->checkForUpdates();
+    return false;
+}
+
+//! Returns true if settings contain record about user choice for updates.
+
+bool UpdateNotifier::hasDefinedUpdatesFlag() const
+{
+    QSettings settings;
+    return settings.childGroups().contains(Constants::S_UPDATES);
 }
diff --git a/GUI/coregui/mainwindow/UpdateNotifier.h b/GUI/coregui/mainwindow/UpdateNotifier.h
index 601021ee2a9a235463f4aa0d3826656d4001cca6..4f41fce554560995beeeb54e4ebd20318a98a166 100644
--- a/GUI/coregui/mainwindow/UpdateNotifier.h
+++ b/GUI/coregui/mainwindow/UpdateNotifier.h
@@ -30,7 +30,12 @@ public:
 
 public slots:
     void replyFinished(QNetworkReply *reply);
-    void askForUpdates();
+
+    void setCheckUpdatesFlag(bool flag);
+
+    bool updatesFlag() const;
+
+    bool hasDefinedUpdatesFlag() const;
 
 signals:
     void onUpdateNotification(const QString &text);
diff --git a/GUI/coregui/mainwindow/UpdateNotifierWidget.cpp b/GUI/coregui/mainwindow/UpdateNotifierWidget.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2e7b38434a7d0011e64ca4aa3f11f25cac42b49a
--- /dev/null
+++ b/GUI/coregui/mainwindow/UpdateNotifierWidget.cpp
@@ -0,0 +1,101 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/mainwindow/UpdateNotifierWidget.cpp
+//! @brief     Implements class UpdateNotifierWidget
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "UpdateNotifierWidget.h"
+#include "UpdateNotifier.h"
+#include <QHBoxLayout>
+#include <QLabel>
+#include <QTimer>
+#include <QSettings>
+#include <QDesktopServices>
+#include <QUrl>
+#include <QDebug>
+
+
+namespace {
+const QString yes = "yes";
+const QString no = "no";
+
+QString update_question()
+{
+    QString result = QString("Should BornAgain check for updates automatically? - "
+                             " <a href=\"%1\">yes</a> /"
+                             " <a href=\"%2\">no</a>").arg(yes, no);
+    return result;
+}
+}
+
+UpdateNotifierWidget::UpdateNotifierWidget(UpdateNotifier* updateNotifier, QWidget* parent)
+    : QWidget(parent)
+    , m_updateNotifier(updateNotifier)
+    , m_updateLabel(new QLabel)
+    , m_check_for_updates(true)
+{
+    auto layout = new QHBoxLayout();
+    layout->addWidget(m_updateLabel);
+    setLayout(layout);
+
+    m_updateLabel->setContentsMargins(30, 10, 0, 0);
+    m_updateLabel->setOpenExternalLinks(false);
+    m_updateLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
+    m_updateLabel->setTextFormat(Qt::RichText);
+    m_updateLabel->setText("");
+
+    m_updateNotifier = updateNotifier;
+    connect(m_updateNotifier, &UpdateNotifier::onUpdateNotification,
+            this, &UpdateNotifierWidget::onUpdateNotification);
+
+    connect(m_updateLabel, &QLabel::linkActivated, this, &UpdateNotifierWidget::onLinkActivated);
+
+    if (!m_updateNotifier->hasDefinedUpdatesFlag()) {
+        m_updateLabel->setText(update_question());
+        m_updateLabel->setToolTip("This setting can be changed later in the main window "
+                                  "Settings menu.");
+    }
+}
+
+//! Schedule check for updates if it was not done yet.
+
+void UpdateNotifierWidget::showEvent(QShowEvent* event)
+{
+    QWidget::showEvent(event);
+    if (m_check_for_updates) {
+        m_check_for_updates = false;
+        QTimer::singleShot(1000, this, [&](){
+            m_updateNotifier->checkForUpdates();
+        });
+    }
+}
+
+//! Updates label when notification is coming.
+
+void UpdateNotifierWidget::onUpdateNotification(const QString& text)
+{
+    m_updateLabel->setText(text);
+}
+
+//! Processes mouse click on update notification label.
+
+void UpdateNotifierWidget::onLinkActivated(const QString& text)
+{
+    if (text == yes ) {
+        m_updateNotifier->setCheckUpdatesFlag(true);
+        m_updateNotifier->checkForUpdates();
+    } else if (text == no ) {
+        m_updateNotifier->setCheckUpdatesFlag(false);
+        QTimer::singleShot(200, this, [&](){m_updateLabel->setText("");});
+    } else {
+        QDesktopServices::openUrl(QUrl(text));
+    }
+}
diff --git a/GUI/coregui/mainwindow/UpdateNotifierWidget.h b/GUI/coregui/mainwindow/UpdateNotifierWidget.h
new file mode 100644
index 0000000000000000000000000000000000000000..cb561056c15c5130c9f2f3030327dafa756dd647
--- /dev/null
+++ b/GUI/coregui/mainwindow/UpdateNotifierWidget.h
@@ -0,0 +1,47 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/mainwindow/UpdateNotifierWidget.h
+//! @brief     Defines class UpdateNotifierWidget
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef UPDATENOTIFIERWIDGET_H
+#define UPDATENOTIFIERWIDGET_H
+
+#include "WinDllMacros.h"
+#include <QWidget>
+
+class UpdateNotifier;
+class QLabel;
+class QShowEvent;
+
+//! Small on WelcomeView for notofications about updates.
+
+class BA_CORE_API_ UpdateNotifierWidget : public QWidget
+{
+    Q_OBJECT
+public:
+    explicit UpdateNotifierWidget(UpdateNotifier* updateNotifier, QWidget* parent = nullptr);
+
+protected:
+    void showEvent(QShowEvent* event);
+
+private slots:
+    void onUpdateNotification(const QString& text);
+    void onLinkActivated(const QString& text);
+
+private:
+    UpdateNotifier* m_updateNotifier;
+    QLabel* m_updateLabel;
+    bool m_check_for_updates;
+};
+
+
+#endif
diff --git a/GUI/coregui/mainwindow/actionmanager.cpp b/GUI/coregui/mainwindow/actionmanager.cpp
index c613b7b7c8ea419dbbd06c08e842c639b611dc6f..7de1d38d9090e9c546b1b23fad10ac6f444b6c87 100644
--- a/GUI/coregui/mainwindow/actionmanager.cpp
+++ b/GUI/coregui/mainwindow/actionmanager.cpp
@@ -205,10 +205,7 @@ void ActionManager::aboutToShowSettings()
 
 void ActionManager::toggleCheckForUpdates(bool status)
 {
-    QSettings settings;
-    settings.beginGroup(Constants::S_UPDATES);
-    settings.setValue(Constants::S_CHECKFORUPDATES, status);
-    settings.endGroup();
+    m_mainWindow->updateNotifier()->setCheckUpdatesFlag(status);
     m_mainWindow->updateNotifier()->checkForUpdates();
 }
 
diff --git a/GUI/coregui/mainwindow/mainwindow.cpp b/GUI/coregui/mainwindow/mainwindow.cpp
index b67d255d2c2211b7a1c8a3447daa8cd4eb03989f..c78e4dd7354422a9fa9897ae362a56df784c4174 100644
--- a/GUI/coregui/mainwindow/mainwindow.cpp
+++ b/GUI/coregui/mainwindow/mainwindow.cpp
@@ -154,11 +154,6 @@ void MainWindow::onSessionModelViewActive(bool isActive)
     }
 }
 
-void MainWindow::checkUpdates()
-{
-    m_updateNotifier->askForUpdates();
-}
-
 void MainWindow::closeEvent(QCloseEvent* event)
 {
     if (jobModel()->hasUnfinishedJobs()) {
@@ -271,6 +266,4 @@ void MainWindow::writeSettings()
 void MainWindow::initConnections()
 {
     connect(m_jobView, &JobView::focusRequest, this, &MainWindow::onFocusRequest);
-    connect(m_updateNotifier, &UpdateNotifier::onUpdateNotification,
-            m_welcomeView, &WelcomeView::setNotificationText);
 }
diff --git a/GUI/coregui/mainwindow/mainwindow.h b/GUI/coregui/mainwindow/mainwindow.h
index 428ad70d8bcc70927bb3c49a4a662e838342ae5a..f6b1f2bc7ecd6b791b4e9e4d5561535c4b7f7b52 100644
--- a/GUI/coregui/mainwindow/mainwindow.h
+++ b/GUI/coregui/mainwindow/mainwindow.h
@@ -70,7 +70,6 @@ public slots:
     void openRecentProject();
     void onRunSimulationShortcut();
     void onSessionModelViewActive(bool isActive);
-    void checkUpdates();
 
 protected:
     void closeEvent(QCloseEvent* event);
diff --git a/GUI/coregui/mainwindow/mainwindow_constants.h b/GUI/coregui/mainwindow/mainwindow_constants.h
index 901d45dfd0345c46f0f248ab6b9420258d46ffdf..37afc0d337c2d5ddf692c426a85d3e09f97e4fe9 100644
--- a/GUI/coregui/mainwindow/mainwindow_constants.h
+++ b/GUI/coregui/mainwindow/mainwindow_constants.h
@@ -29,7 +29,6 @@ const char S_MASKEDITOR[]          = "MaskEditor";
 const char S_UPDATES[]             = "Updates";
 const char S_MATERIALEDITOR[]      = "MaterialEditor";
 const char S_SESSIONMODELVIEW[]    = "SessionModelView";
-const char S_REALSPACEDIALOG[]    = "RealSpaceDialog";
 
 // Settings keys
 const char S_WINDOWSIZE[]          = "size";
diff --git a/GUI/coregui/mainwindow/projectdocument.cpp b/GUI/coregui/mainwindow/projectdocument.cpp
index 328b154c73c6e3325468ef12aa4d11770d71e92d..c72a775eb19c3eff61355a7e0a6390a8c9ea5d31 100644
--- a/GUI/coregui/mainwindow/projectdocument.cpp
+++ b/GUI/coregui/mainwindow/projectdocument.cpp
@@ -206,7 +206,7 @@ bool ProjectDocument::hasErrors() const
 
 bool ProjectDocument::hasData() const
 {
-    return !m_dataService->dataItems().isEmpty();
+    return !m_dataService->nonXMLItems().isEmpty();
 }
 
 QString ProjectDocument::documentVersion() const
diff --git a/GUI/coregui/utils/ImportDataInfo.cpp b/GUI/coregui/utils/ImportDataInfo.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..056aa0c194adb5d6fbf5fb56f7687a3bc9868521
--- /dev/null
+++ b/GUI/coregui/utils/ImportDataInfo.cpp
@@ -0,0 +1,124 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/utils/ImportDataInfo.cpp
+//! @brief     Implements ImportDataInfo helper struct
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "ImportDataInfo.h"
+#include "AxisNames.h"
+#include "GUIHelpers.h"
+#include "ImportDataUtils.h"
+#include "JobItemUtils.h"
+#include "OutputData.h"
+
+namespace {
+std::vector<AxesUnits> specularUnits()
+{
+    std::vector<AxesUnits> result;
+    const auto units_map = AxisNames::InitSpecAxis();
+    for (auto& pair: units_map)
+        result.push_back(pair.first);
+    return result;
+}
+
+// map: data rank --> available units
+std::map<size_t, std::vector<AxesUnits>> available_units = {{1u, specularUnits()},
+                                                            {2u, {AxesUnits::NBINS}}};
+}
+
+ImportDataInfo::ImportDataInfo()
+{
+}
+
+ImportDataInfo::ImportDataInfo(ImportDataInfo&& other)
+    : m_data(std::move(other.m_data))
+    , m_units(other.m_units)
+{
+}
+
+ImportDataInfo::ImportDataInfo(std::unique_ptr<OutputData<double>> data, AxesUnits units)
+    : m_data(units == AxesUnits::NBINS && data
+                 ? ImportDataUtils::CreateSimplifiedOutputData(*data)
+                 : std::move(data))
+    , m_units(units)
+{
+    checkValidity();
+}
+
+ImportDataInfo::ImportDataInfo(std::unique_ptr<OutputData<double>> data, const QString& units_label)
+    : m_data(std::move(data))
+    , m_units(JobItemUtils::axesUnitsFromName(units_label))
+{
+    checkValidity();
+}
+
+ImportDataInfo::~ImportDataInfo() = default;
+
+ImportDataInfo::operator bool() const
+{
+    return static_cast<bool>(m_data);
+}
+
+std::unique_ptr<OutputData<double> > ImportDataInfo::intensityData() const &
+{
+    if (!m_data)
+        return nullptr;
+    return std::unique_ptr<OutputData<double>>(m_data->clone());
+}
+
+std::unique_ptr<OutputData<double> > ImportDataInfo::intensityData() &&
+{
+    return std::move(m_data);
+}
+
+size_t ImportDataInfo::dataRank() const
+{
+    if (!m_data)
+        return 0;
+    return m_data->getRank();
+}
+
+QString ImportDataInfo::unitsLabel() const
+{
+    return JobItemUtils::nameFromAxesUnits(m_units);
+}
+
+QString ImportDataInfo::axisLabel(size_t axis_index) const
+{
+    if (!m_data)
+        return "";
+
+    const size_t rank = m_data->getRank();
+    if (rank == 2)
+        return axis_index == 0 ? "X [nbins]" : "Y [nbins]";
+    else if (rank == 1) {
+        if (axis_index > 0)
+            return "Signal [a.u.]";
+
+        auto label_map = AxisNames::InitSpecAxis();
+        return QString::fromStdString(label_map[m_units]);
+    }
+    throw GUIHelpers::Error("Error in ImportDataInfo::axisLabel: unsupported data type");
+}
+
+void ImportDataInfo::checkValidity()
+{
+    if (!m_data)
+        return;
+    auto iter = available_units.find(m_data->getRank());
+    if (iter == available_units.end())
+        throw GUIHelpers::Error("Error in ImportDataInfo constructor: unsupported data type");
+    for (auto& value: iter->second)
+        if (m_units == value)
+            return;
+
+    throw GUIHelpers::Error("Error in ImportDataInfo constructor: inacceptable units passed.");
+}
diff --git a/GUI/coregui/utils/ImportDataInfo.h b/GUI/coregui/utils/ImportDataInfo.h
new file mode 100644
index 0000000000000000000000000000000000000000..b3c2926de2f232d40adfc31dcb84d5cb846dd750
--- /dev/null
+++ b/GUI/coregui/utils/ImportDataInfo.h
@@ -0,0 +1,50 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      GUI/coregui/utils/ImportDataInfo.h
+//! @brief     Defines ImportDataInfo helper struct
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef IMPORTDATAINFO_H
+#define IMPORTDATAINFO_H
+
+#include "WinDllMacros.h"
+#include "IUnitConverter.h"
+#include <QString>
+#include <memory>
+
+template<class T> class OutputData;
+
+//! Carries information about loaded data.
+
+class BA_CORE_API_ ImportDataInfo
+{
+public:
+    ImportDataInfo();
+    ImportDataInfo(ImportDataInfo&& other);
+    ImportDataInfo(std::unique_ptr<OutputData<double>> data, AxesUnits units);
+    ImportDataInfo(std::unique_ptr<OutputData<double>> data, const QString& units);
+    ~ImportDataInfo();
+
+    operator bool() const;
+
+    std::unique_ptr<OutputData<double>> intensityData() const &;
+    std::unique_ptr<OutputData<double>> intensityData() &&;
+    size_t dataRank() const;
+    QString unitsLabel() const;
+    QString axisLabel(size_t axis_index) const;
+
+private:
+    void checkValidity();
+    std::unique_ptr<OutputData<double>> m_data;
+    AxesUnits m_units;
+};
+
+#endif // IMPORTDATAINFO_H
diff --git a/GUI/coregui/utils/StyleUtils.cpp b/GUI/coregui/utils/StyleUtils.cpp
index 19be4c4bc5ea15b6252a8a4aeda75c357aea1237..37be3ff39d50038909d28da6f0072e6c8f7c28d8 100644
--- a/GUI/coregui/utils/StyleUtils.cpp
+++ b/GUI/coregui/utils/StyleUtils.cpp
@@ -15,8 +15,14 @@
 #include "StyleUtils.h"
 #include "DesignerHelper.h"
 #include "hostosinfo.h"
+#include "detailswidget.h"
 #include <QDialog>
 #include <QTreeView>
+#include <QBoxLayout>
+
+namespace {
+Utils::DetailsWidget* createEmptyDetailsWidget(const QString& name, bool expanded);
+}
 
 void StyleUtils::setPropertyStyle(QTreeView* tree)
 {
@@ -96,3 +102,32 @@ void StyleUtils::setResizable(QDialog* dialog)
                                | Qt::Window);
     }
 }
+
+QWidget* StyleUtils::createDetailsWidget(QWidget* content, const QString& name, bool expanded)
+{
+    auto result = createEmptyDetailsWidget(name, expanded);
+    result->setWidget(content);
+    return result;
+}
+
+QWidget* StyleUtils::createDetailsWidget(QLayout* layout, const QString& name, bool expanded)
+{
+    auto placeholder = new QWidget();
+    placeholder->setLayout(layout);
+    return createDetailsWidget(placeholder, name, expanded);
+}
+
+
+namespace {
+
+Utils::DetailsWidget* createEmptyDetailsWidget(const QString& name, bool expanded)
+{
+    auto result = new Utils::DetailsWidget;
+    result->setSummaryText(name);
+    result->setSummaryFontBold(true);
+    if (expanded)
+        result->setState(Utils::DetailsWidget::Expanded);
+    return result;
+}
+
+}
diff --git a/GUI/coregui/utils/StyleUtils.h b/GUI/coregui/utils/StyleUtils.h
index 47a48e9dbd5cd8ed35cf3e5d0483327b3152e58b..f8256cfb96cddcd1b2d017baa05fcc7274f5d0b5 100644
--- a/GUI/coregui/utils/StyleUtils.h
+++ b/GUI/coregui/utils/StyleUtils.h
@@ -21,6 +21,7 @@
 
 class QTreeView;
 class QWidget;
+class QLayout;
 
 namespace StyleUtils
 {
@@ -43,6 +44,14 @@ BA_CORE_API_ QFont labelFont(bool bold = false);
 //! Make modal dialog resizable.
 BA_CORE_API_ void setResizable(QDialog* dialog);
 
+//! Creates details widget holding user content inside.
+BA_CORE_API_ QWidget* createDetailsWidget(QWidget* content, const QString& name,
+                                          bool expanded=true);
+
+//! Creates details widget holding user layout inside.
+BA_CORE_API_ QWidget* createDetailsWidget(QLayout* content, const QString& name,
+                                          bool expanded=true);
+
 }
 
 #endif
diff --git a/GUI/main/CMakeLists.txt b/GUI/main/CMakeLists.txt
index d4c32802812e13df60aad7c3fc6a68da449b521c..94efc3a46c2db2fb00166ed9b1170f6b7869b169 100644
--- a/GUI/main/CMakeLists.txt
+++ b/GUI/main/CMakeLists.txt
@@ -3,28 +3,15 @@
 ###############################################################################
 set(executable_name BornAgain)
 
-# -----------------------------------------------------------------------------
-# source files
-# -----------------------------------------------------------------------------
-include_directories(
-    ${CMAKE_SOURCE_DIR}/Wrap
-    ${Boost_INCLUDE_DIRS}
-    ${BornAgainGUI_INCLUDE_DIRS}
-    ${QtAddOn_INCLUDE_DIRS}
-    ${GSL_INCLUDE_DIR}
-    ${CMAKE_SOURCE_DIR}/Core/Basics
-)
 set(source_files main.cpp appoptions.cpp)
 set(include_files appoptions.h)
 
-
 # -----------------------------------------------------------------------------
 # Qt configuration
 # -----------------------------------------------------------------------------
 set(CMAKE_INCLUDE_CURRENT_DIR ON)
 set(CMAKE_AUTOMOC ON)
 
-
 # -----------------------------------------------------------------------------
 # executable icons
 # -----------------------------------------------------------------------------
diff --git a/GUI/main/main.cpp b/GUI/main/main.cpp
index 01640ddd0b2bb593ca45b70c28c510af077b5c16..28fbd9815a97d81ebe963b9719ff1519e439342b 100644
--- a/GUI/main/main.cpp
+++ b/GUI/main/main.cpp
@@ -54,7 +54,5 @@ int main(int argc, char* argv[])
     if (splash)
         splash->finish(&win);
 
-    win.checkUpdates();
-
     return app.exec();
 }
diff --git a/Tests/Functional/CMakeLists.txt b/Tests/Functional/CMakeLists.txt
index 3a2842d172f329ecff34d5ddc6bab015d9477344..05fcf8d4bc049562ed0e32bf344b0cfed50c00f2 100644
--- a/Tests/Functional/CMakeLists.txt
+++ b/Tests/Functional/CMakeLists.txt
@@ -2,21 +2,13 @@
 # Tests/Functional/CMakeLists.txt (called from top-level CMakeLists.txt)
 ############################################################################
 
-include_as_system_directory("${EIGEN3_INCLUDE_DIR}")
-include_directories(
-    ${Boost_INCLUDE_DIRS}
-    ${GSL_INCLUDE_DIR}
-    ${BornAgainCore_INCLUDE_DIRS}
-    ${BornAgainFit_INCLUDE_DIRS}
-    ${CMAKE_SOURCE_DIR}/Tests/Functional/TestMachinery
-)
+include_directories(${CMAKE_SOURCE_DIR}/Tests/Functional/TestMachinery)
 
 add_subdirectory(TestMachinery)
 add_subdirectory(Core)
 add_subdirectory(Fit)
 
 if(BORNAGAIN_PYTHON)
-    add_definitions(-DBORNAGAIN_PYTHON)
     add_subdirectory(Python)
 endif()
 
diff --git a/Tests/Functional/Core/CoreStandardTest/CMakeLists.txt b/Tests/Functional/Core/CoreStandardTest/CMakeLists.txt
index 2353910909ccbe7a340e9a4ab515e2533737f563..bb58de9b8b09375277261f5642a672d9d7c5d0dc 100644
--- a/Tests/Functional/Core/CoreStandardTest/CMakeLists.txt
+++ b/Tests/Functional/Core/CoreStandardTest/CMakeLists.txt
@@ -65,6 +65,7 @@ set(test_cases
     RotatedPyramidsDistribution
     SpheresWithLimitsDistribution
     ConesWithLimitsDistribution
+    LinkedBoxDistribution
     HomogeneousTiNiSample
     HomogeneousTiNiSampleWithAbsorption
     RoughnessInSpecular
diff --git a/Tests/Functional/Fit/CMakeLists.txt b/Tests/Functional/Fit/CMakeLists.txt
index 965a08a1790b79e868df0a2aa9bc1f5af918fc3a..bb84a497b99efb51f9681d0fc275bc44ae37af5f 100644
--- a/Tests/Functional/Fit/CMakeLists.txt
+++ b/Tests/Functional/Fit/CMakeLists.txt
@@ -2,9 +2,6 @@
 # Tests/Functional/Core/CMakeLists.txt
 ############################################################################
 
-# testing fitting via FitSuite
-add_subdirectory(FitSuite)
-
 # testing fitting via FitObjective
 add_subdirectory(FitObjective)
 
diff --git a/Tests/Functional/Fit/FitObjective/AdjustMinimizerPlan.cpp b/Tests/Functional/Fit/FitObjective/AdjustMinimizerPlan.cpp
index 6e0d93964be0650c3dce78946041e42393b7c51a..d61a0406dd4c19dc122503bb0a2e718f5b0b42e8 100644
--- a/Tests/Functional/Fit/FitObjective/AdjustMinimizerPlan.cpp
+++ b/Tests/Functional/Fit/FitObjective/AdjustMinimizerPlan.cpp
@@ -30,7 +30,7 @@ AdjustMinimizerPlan::AdjustMinimizerPlan()
     : FitPlan("AdjustMinimizerPlan")
 {
     setBuilderName("CylindersInBABuilder");
-    setSimulationName("MiniGISAS");
+    setSimulationName("MiniGISASFit");
     addParameter(Parameter("height", 2.0*nm, AttLimits::limited(0.01, 30.0), 0.05), 5.0*nm);
     addParameter(Parameter("radius", 10.0*nm, AttLimits::limited(0.01, 30.0), 0.05), 5.0*nm);
 }
diff --git a/Tests/Functional/Fit/FitObjective/CMakeLists.txt b/Tests/Functional/Fit/FitObjective/CMakeLists.txt
index ed4b88b927ef29ae09ec2ae5fb4c7f17ddc7ca48..a12c7327bf03c0f6b6987e58f28bb20bcde77c32 100644
--- a/Tests/Functional/Fit/FitObjective/CMakeLists.txt
+++ b/Tests/Functional/Fit/FitObjective/CMakeLists.txt
@@ -2,8 +2,19 @@ set(test TestFitObjective)
 
 set(test_cases
     MigradCylindersInBA
+    MigradResidualCylindersInBA
     SpecularFitTest
-    MultipleSpecFittingTest
+    MultipleSpecFittingTest    
+    FumuliCylindersInBA
+    LevenbergMarquardtCylindersInBA
+    MultiPatternFit
+    RectDetectorFit
+    # --- slow, but still converging ---
+    # SimAnCylindersInBA
+    # GeneticCylindersInBA
+    # SteepestDescentCylindersInBA
+    # AdjustMinimizerFit
+    # BfgsCylindersInBA
 )
 
 include_directories(${RootMinimizers_INCLUDE_DIRS})
diff --git a/Tests/Functional/Fit/FitObjective/FitObjectiveTestCases.cpp b/Tests/Functional/Fit/FitObjective/FitObjectiveTestCases.cpp
index fcaab6609d740c29e32820e45a2bfaf1cc7399fa..59002767e3330c063c9ed0c935b600b02f3721e2 100644
--- a/Tests/Functional/Fit/FitObjective/FitObjectiveTestCases.cpp
+++ b/Tests/Functional/Fit/FitObjective/FitObjectiveTestCases.cpp
@@ -17,11 +17,14 @@
 MigradCylindersInBA::MigradCylindersInBA()
     : FitObjectiveTest("Minuit2", "Migrad", "CylindersInBAPlan") {}
 
+MigradResidualCylindersInBA::MigradResidualCylindersInBA()
+    : FitObjectiveTest("Minuit2", "Migrad", "CylindersInBAResidualPlan") {}
+
 BfgsCylindersInBA::BfgsCylindersInBA()
-    : FitObjectiveTest("GSLMultiMin", "BFGS", "CylindersInBAPlan") {}
+    : FitObjectiveTest("GSLMultiMin", "BFGS2", "CylindersInBAEasyPlan") {}
 
 SteepestDescentCylindersInBA::SteepestDescentCylindersInBA()
-    : FitObjectiveTest("GSLMultiMin", "SteepestDescent", "CylindersInBAPlan") {}
+    : FitObjectiveTest("GSLMultiMin", "SteepestDescent", "CylindersInBAEasyPlan") {}
 
 FumuliCylindersInBA::FumuliCylindersInBA()
     : FitObjectiveTest("Minuit2", "Fumili", "CylindersInBAResidualPlan") {}
@@ -42,13 +45,16 @@ GeneticCylindersInBA::GeneticCylindersInBA()
 }
 
 RectDetectorFit::RectDetectorFit()
-    : FitObjectiveTest("Minuit2", "Migrad", "RectDetPlan") {}
+    : FitObjectiveTest("Minuit2", "Migrad", "RectDetPlan")
+{
+    setMinimizerOptions("Strategy=2");
+}
 
 AdjustMinimizerFit::AdjustMinimizerFit()
     : FitObjectiveTest("Genetic", "", "AdjustMinimizerPlan") {}
 
 MultiPatternFit::MultiPatternFit()
-    : FitObjectiveTest("GSLLMA", "", "MultiPatternPlan") {}
+    : FitObjectiveTest("Minuit2", "Fumili", "MultiPatternPlan") {}
 
 SpecularFitTest::SpecularFitTest()
     : FitObjectiveTest("Minuit2", "Migrad", "SpecularPlan") {}
diff --git a/Tests/Functional/Fit/FitObjective/FitObjectiveTestCases.h b/Tests/Functional/Fit/FitObjective/FitObjectiveTestCases.h
index 037bc0ca49fc284a2a629114822c40ad8cb2cb34..c7da432c5fc578e19833bb03ccf1e151b131357c 100644
--- a/Tests/Functional/Fit/FitObjective/FitObjectiveTestCases.h
+++ b/Tests/Functional/Fit/FitObjective/FitObjectiveTestCases.h
@@ -25,6 +25,12 @@ public:
     MigradCylindersInBA();
 };
 
+class MigradResidualCylindersInBA : public FitObjectiveTest
+{
+public:
+    MigradResidualCylindersInBA();
+};
+
 class BfgsCylindersInBA : public FitObjectiveTest
 {
 public:
diff --git a/Tests/Functional/Fit/FitObjective/FitObjectiveTestFactory.cpp b/Tests/Functional/Fit/FitObjective/FitObjectiveTestFactory.cpp
index 984121d7ec4c5eb33407317fee5ffc8b4384fa93..684162325c570415941e96778d0f2979b906cc7f 100644
--- a/Tests/Functional/Fit/FitObjective/FitObjectiveTestFactory.cpp
+++ b/Tests/Functional/Fit/FitObjective/FitObjectiveTestFactory.cpp
@@ -19,6 +19,8 @@ FitObjectiveTestFactory::FitObjectiveTestFactory()
 {
     registerItem("MigradCylindersInBA", create_new<MigradCylindersInBA>,
                  "Minuit + CylindersInBA");
+    registerItem("MigradResidualCylindersInBA", create_new<MigradResidualCylindersInBA>,
+                 "Minuit + ResidualCylindersInBA");
     registerItem("BfgsCylindersInBA", create_new<BfgsCylindersInBA>,
                  "BFGS + CylindersInBA");
     registerItem("SteepestDescentCylindersInBA", create_new<SteepestDescentCylindersInBA>,
diff --git a/Tests/Functional/Fit/FitObjective/FitPlanCases.cpp b/Tests/Functional/Fit/FitObjective/FitPlanCases.cpp
index 1b17eb037cffa0231b0cda6be9a1425c6d7e1e4c..812d0a4ecb41ddbd41caa5740d88f3be639cec12 100644
--- a/Tests/Functional/Fit/FitObjective/FitPlanCases.cpp
+++ b/Tests/Functional/Fit/FitObjective/FitPlanCases.cpp
@@ -44,14 +44,14 @@ CylindersInBAPlan::CylindersInBAPlan()
 }
 
 CylindersInBAEasyPlan::CylindersInBAEasyPlan()
-    : FitPlan("CylindersInBAPlan")
+    : FitPlan("CylindersInBAEasyPlan")
 {
     setBuilderName("CylindersInBABuilder");
-    setSimulationName("MiniGISAS");
+    setSimulationName("MiniGISASFit");
     const double tolerance = 0.1;
-    addParameter(Parameter("height", 4.5*nm, AttLimits::limited(4.0, 6.0), 0.01),
+    addParameter(Parameter("height", 4.5*nm, AttLimits::limited(4.0, 6.0), 0.1),
                  5.0*nm, tolerance);
-    addParameter(Parameter("radius", 5.5*nm, AttLimits::limited(4.0, 6.0), 0.01),
+    addParameter(Parameter("radius", 5.5*nm, AttLimits::limited(4.0, 6.0), 0.1),
                  5.0*nm, tolerance);
 }
 
@@ -60,8 +60,8 @@ CylindersInBAResidualPlan::CylindersInBAResidualPlan()
 {
     setBuilderName("CylindersInBABuilder");
     setSimulationName("MiniGISAS");
-    addParameter(Parameter("height", 4.5*nm, AttLimits::lowerLimited(0.01), 0.01), 5.0*nm);
-    addParameter(Parameter("radius", 5.5*nm, AttLimits::lowerLimited(0.01), 0.01), 5.0*nm);
+    addParameter(Parameter("height", 4.5*nm, AttLimits::limitless(), 0.01), 5.0*nm);
+    addParameter(Parameter("radius", 5.5*nm, AttLimits::limitless(), 0.01), 5.0*nm);
 }
 
 // ----------------------------------------------------------------------------
@@ -70,8 +70,8 @@ RectDetPlan::RectDetPlan()
     : FitPlan("RectDetPlan")
 {
     setBuilderName("CylindersInBABuilder");
-    addParameter(Parameter("height", 4.5*nm, AttLimits::lowerLimited(0.01), 0.01), 5.0*nm);
-    addParameter(Parameter("radius", 5.5*nm, AttLimits::lowerLimited(0.01), 0.01), 5.0*nm);
+    addParameter(Parameter("height", 4.5*nm, AttLimits::limited(4.0, 6.0), 0.01), 5.0*nm);
+    addParameter(Parameter("radius", 5.5*nm, AttLimits::limited(4.0, 6.0), 0.01), 5.0*nm);
 }
 
 RectDetPlan::~RectDetPlan() = default;
@@ -87,8 +87,8 @@ std::unique_ptr<Simulation> RectDetPlan::createSimulation(const Parameters&) con
 
     result->setBeamParameters(1.0*Units::angstrom, 0.2*Units::degree, 0.0*Units::degree);
     result->setDetector(detector);
-    result->setRegionOfInterest(6.0, 6.0, 14.0, 12.0);
-    result->addMask(Rectangle(8.0, 8.0, 10.0, 10.0), true);
+    result->setRegionOfInterest(5.0, 6.0, 15.0, 12.0);
+    result->addMask(Rectangle(0.0, 0.0, 2.0, 2.0), true);
     return std::unique_ptr<Simulation>(result.release());
 }
 
diff --git a/Tests/Functional/Fit/FitSuite/AdjustMinimizerStrategyTest.cpp b/Tests/Functional/Fit/FitSuite/AdjustMinimizerStrategyTest.cpp
deleted file mode 100644
index 39bb3ab8d83e98e308eb57597cb4a6e3c28231a2..0000000000000000000000000000000000000000
--- a/Tests/Functional/Fit/FitSuite/AdjustMinimizerStrategyTest.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Tests/Functional/Fit/AdjustMinimizerStrategyTest.cpp
-//! @brief     Implements class AdjustMinimizerStrategyTest.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "AdjustMinimizerStrategyTest.h"
-#include "Units.h"
-#include "FitSuite.h"
-#include "MinimizerFactory.h"
-#include "AdjustMinimizerStrategy.h"
-#include "MinimizerConstants.h"
-
-
-AdjustMinimizerStrategyTest::AdjustMinimizerStrategyTest()
-    : IObsoleteMinimizerTest("undefined", "undefined")
-{}
-
-void AdjustMinimizerStrategyTest::initParameterPlan()
-{
-    m_parplans.clear();
-    m_parplans.push_back(std::make_unique<FitParameterPlan>("*Height", 2.0 * Units::nanometer,
-                                                            5.0 * Units::nanometer,
-                                                            AttLimits::limited(0.01, 30.0), 0.05));
-    m_parplans.push_back(std::make_unique<FitParameterPlan>("*Radius", 10.0 * Units::nanometer,
-                                                            5.0 * Units::nanometer,
-                                                            AttLimits::limited(0.01, 30.0), 0.05));
-}
-
-std::unique_ptr<FitSuite> AdjustMinimizerStrategyTest::createFitSuite() {
-  std::unique_ptr<FitSuite> result(new FitSuite());
-  result->initPrint(50);
-
-  result->addFitStrategy(AdjustMinimizerStrategy(
-      MinimizerNames::Genetic, std::string(), "MaxIterations=2;RandomSeed=1"));
-
-  result->addFitStrategy(AdjustMinimizerStrategy(MinimizerNames::Minuit2,
-                                                 AlgorithmNames::Migrad));
-
-  for (size_t i = 0; i < m_parplans.size(); ++i)
-    result->addFitParameter(m_parplans[i]->fitParameter());
-  return result;
-}
diff --git a/Tests/Functional/Fit/FitSuite/AdjustMinimizerStrategyTest.h b/Tests/Functional/Fit/FitSuite/AdjustMinimizerStrategyTest.h
deleted file mode 100644
index 089fca5c40525e941430fb5090ebf4d348583bab..0000000000000000000000000000000000000000
--- a/Tests/Functional/Fit/FitSuite/AdjustMinimizerStrategyTest.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Tests/Functional/Fit/AdjustMinimizerStrategyTest.h
-//! @brief     Declares class MinimizerStrategyTest.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef ADJUSTMINIMIZERSTRATEGYTEST_H
-#define ADJUSTMINIMIZERSTRATEGYTEST_H
-
-#include "IObsoleteMinimizerTest.h"
-
-//! @class AdjustMinimizerStrategyTest
-//! @ingroup standard_samples
-//! @brief The AdjustMinimizerStrategyTest verifies fitting with the chain of minimizers.
-
-class AdjustMinimizerStrategyTest : public IObsoleteMinimizerTest
-{
-public:
-    AdjustMinimizerStrategyTest();
-
-protected:
-    void initParameterPlan() override;
-    std::unique_ptr<FitSuite> createFitSuite() override;
-};
-
-#endif // ADJUSTMINIMIZERSTRATEGYTEST_H
diff --git a/Tests/Functional/Fit/FitSuite/CMakeLists.txt b/Tests/Functional/Fit/FitSuite/CMakeLists.txt
deleted file mode 100644
index 2676d592ec3a1a2984c9c03738291881a09584fa..0000000000000000000000000000000000000000
--- a/Tests/Functional/Fit/FitSuite/CMakeLists.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-set(test TestFitSuite)
-
-set(test_cases
-    GSLLevenbergMarquardt
-    GSLMultiMinBFGS
-    GSLMultiMinSteepestDescent
-    GSLSimulatedAnnealing
-    GeneticMinimizer
-    Minuit2_Fumili
-    Minuit2_Migrad
-    RectDetectorFit
-    AdjustMinimizerStrategy
-    MultiPatternFit
-)
-
-include_directories(${RootMinimizers_INCLUDE_DIRS})
-
-file(GLOB source_files "*.cpp")
-file(GLOB include_files "*.h")
-
-add_executable(${test} ${include_files} ${source_files})
-target_link_libraries(${test} BornAgainCore BornAgainTestMachinery)
-
-foreach(test_case ${test_cases})
-    add_test(${test}/${test_case} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${test} ${test_case})
-endforeach()
diff --git a/Tests/Functional/Fit/FitSuite/FitParameterPlan.cpp b/Tests/Functional/Fit/FitSuite/FitParameterPlan.cpp
deleted file mode 100644
index cbf4bba6d38574fd7851c8b3992bd8c598ef3603..0000000000000000000000000000000000000000
--- a/Tests/Functional/Fit/FitSuite/FitParameterPlan.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Tests/Functional/Fit/FitParameterPlan.cpp
-//! @brief     Declares class FitParameterPlan.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "FitParameterPlan.h"
-
-FitParameterPlan::FitParameterPlan(const std::string &name, double start_value,
-                                   double expected_value,
-                                   const AttLimits &limits, double step)
-    : m_expected_value(expected_value)
-    , m_tolerance(0.01)
-{
-    m_parameter.reset(new FitParameter(name, start_value, limits, step));
-    m_parameter->setName(name);
-}
-
-FitParameterPlan::FitParameterPlan(const FitParameter& param, double expected_value,
-                                   double tolerance)
-    : m_expected_value(expected_value)
-    , m_tolerance(tolerance)
-    , m_parameter(param.clone())
-{
-
-}
-
-const FitParameter& FitParameterPlan::fitParameter() const
-{
-    return *m_parameter;
-}
diff --git a/Tests/Functional/Fit/FitSuite/FitParameterPlan.h b/Tests/Functional/Fit/FitSuite/FitParameterPlan.h
deleted file mode 100644
index a818f891d3488763e9ac3a37c811e49570451e84..0000000000000000000000000000000000000000
--- a/Tests/Functional/Fit/FitSuite/FitParameterPlan.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Tests/Functional/Fit/FitParameterPlan.h
-//! @brief     Declares class FitParameterPlan.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef FITPARAMETERPLAN_H
-#define FITPARAMETERPLAN_H
-
-#include "AttLimits.h"
-#include "FitParameter.h"
-#include <memory>
-
-//! @class FitParameterPlan
-//! @ingroup standard_samples
-//! @brief The FitParameterPlan defines fit parameter settings and the value which has to be found
-//! in the course of minimization.
-
-class FitParameterPlan
-{
-public:
-    FitParameterPlan(const std::string &name, double start_value, double expected_value,
-                     const AttLimits &limits, double step);
-    FitParameterPlan(const FitParameter& param, double expected_value, double tolerance = 0.01);
-
-    FitParameterPlan(const FitParameterPlan& other) = delete;
-    FitParameterPlan& operator=(const FitParameterPlan& other) = delete;
-
-    const FitParameter& fitParameter() const;
-
-    double expectedValue() const { return m_expected_value; }
-
-    double tolerance() const { return m_tolerance; }
-    void setTolerance(double tolerance) { m_tolerance = tolerance; }
-
-private:
-    double m_expected_value; //!< expected value to find in the fit
-    double m_tolerance; //!< tolerance on found value wrt expected value
-    std::unique_ptr<FitParameter> m_parameter;
-};
-
-#endif // FITPARAMETERPLAN_H
diff --git a/Tests/Functional/Fit/FitSuite/IObsoleteFittingTest.cpp b/Tests/Functional/Fit/FitSuite/IObsoleteFittingTest.cpp
deleted file mode 100644
index b9f7aa9a71261af1137f4436fbb763751f068183..0000000000000000000000000000000000000000
--- a/Tests/Functional/Fit/FitSuite/IObsoleteFittingTest.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Tests/Functional/Fit/IObsoleteFittingTest.cpp
-//! @brief     Implements class IObsoleteFittingTest.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "IObsoleteFittingTest.h"
-#include "FitSuite.h"
-#include "Simulation.h"
-#include "MultiLayer.h"
-#include "MinimizerFactory.h"
-#include "SampleBuilderFactory.h"
-#include "SimulationFactory.h"
-#include "FitParameterSet.h"
-#include <boost/format.hpp>
-
-namespace {
-    const double default_parameter_tolerance = 0.01;
-}
-
-IObsoleteFittingTest::IObsoleteFittingTest(const std::string& minimizer_name,
-                           const std::string& minimizer_algorithm,
-                           const std::string& simulation_name,
-                           const std::string& builder_name)
-    : m_minimizer_name(minimizer_name), m_minimizer_algorithm(minimizer_algorithm),
-      m_simulation_name(simulation_name), m_sample_builder_name(builder_name)
-{
-}
-
-IObsoleteFittingTest::~IObsoleteFittingTest() = default;
-
-
-bool IObsoleteFittingTest::runTest()
-{
-    initParameterPlan();
-
-    std::unique_ptr<MultiLayer> sample(createSample());
-
-    std::unique_ptr<Simulation> simulation(createSimulation());
-    simulation->setSample(*sample.get());
-    simulation->runSimulation();
-
-    std::unique_ptr<OutputData<double> > real_data(createOutputData(simulation.get()));
-
-    std::unique_ptr<FitSuite> fitSuite(createFitSuite());
-    fitSuite->addSimulationAndRealData(*simulation.get(), *real_data.get());
-
-    // run fit
-    std::cout << fitSuite->treeToString() << std::endl;
-    std::cout << fitSuite->parametersToString() << std::endl;
-    std::cout << fitSuite->setupToString() << std::endl;
-    fitSuite->runFit();
-
-    const bool success = analyzeResults(*fitSuite);
-    return success;
-}
-
-void IObsoleteFittingTest::initParameterPlan() {
-  for(auto& plan : m_parplans)
-      plan->setTolerance(default_parameter_tolerance);
-}
-
-std::unique_ptr<FitSuite> IObsoleteFittingTest::createFitSuite()
-{
-    std::unique_ptr<FitSuite> result(new FitSuite());
-    result->initPrint(10);
-    IMinimizer* minimizer = MinimizerFactory::createMinimizer(
-                m_minimizer_name, m_minimizer_algorithm);
-    result->setMinimizer(minimizer);
-
-    for(auto& plan : m_parplans)
-        result->addFitParameter(plan->fitParameter());
-
-    return result;
-}
-
-std::unique_ptr<MultiLayer> IObsoleteFittingTest::createSample()
-{
-    SampleBuilderFactory builderFactory;
-    std::unique_ptr<MultiLayer> result(builderFactory.createSample(m_sample_builder_name));
-    for(auto& plan : m_parplans)
-        for(auto pattern : plan->fitParameter().patterns())
-            result->setParameterValue(pattern, plan->expectedValue());
-    return result;
-}
-
-std::unique_ptr<Simulation> IObsoleteFittingTest::createSimulation()
-{
-    SimulationFactory simRegistry;
-    auto P_sim = simRegistry.create(m_simulation_name);
-    P_sim->setBeamIntensity(1e2);
-    return P_sim;
-}
-
-std::unique_ptr<OutputData<double> > IObsoleteFittingTest::createOutputData(
-    const Simulation* simulation)
-{
-    auto sim_result = simulation->result();
-    return std::unique_ptr<OutputData<double>>(sim_result.data());
-}
-
-bool IObsoleteFittingTest::analyzeResults(FitSuite& fit_suite) const
-{
-    const std::vector<double>& actual = fit_suite.fitParameters()->values();
-    std::vector<bool> result(actual.size(), true);
-    for(size_t i = 0; i < m_parplans.size(); ++i) {
-        const double expected = m_parplans[i]->expectedValue();
-        const double diff = std::abs(actual[i] - expected) / expected;
-        result[i] = diff <= m_parplans[i]->tolerance();
-        std::cout << boost::format("%|12t| %-10s : %-6.4f (diff %6.4g) %s\n") %
-            ("par"+std::to_string(i)) % actual[i] % diff % (result[i] ? "OK" : "FAILED");
-    }
-    return std::accumulate(result.cbegin(), result.cend(), true, std::logical_and<>());
-}
diff --git a/Tests/Functional/Fit/FitSuite/IObsoleteFittingTest.h b/Tests/Functional/Fit/FitSuite/IObsoleteFittingTest.h
deleted file mode 100644
index d3340dfa75fc11f8d2b4b8f441737258982f0873..0000000000000000000000000000000000000000
--- a/Tests/Functional/Fit/FitSuite/IObsoleteFittingTest.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Tests/Functional/Fit/IObsoleteFittingTest.h
-//! @brief     Defines class IObsoleteFittingTest.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef IOBSOLETEFITTINGTEST_H_
-#define IOBSOLETEFITTINGTEST_H_
-
-#include "IFunctionalTest.h"
-#include "FitParameterPlan.h"
-#include <memory>
-
-class FitSuite;
-class MultiLayer;
-template<class T> class OutputData;
-class Simulation;
-
-
-//! @class IFittingTest
-//! @ingroup standard_samples
-//! @brief Basic class for all fitting functional tests
-
-class IObsoleteFittingTest : public IFunctionalTest
-{
-public:
-    IObsoleteFittingTest(const std::string& minimizer_name, const std::string& minimizer_algorithm,
-                 const std::string& simulation_name, const std::string& builder_name);
-    virtual ~IObsoleteFittingTest();
-
-    bool runTest() override;
-
-protected:
-    virtual void initParameterPlan() = 0;
-    virtual std::unique_ptr<FitSuite> createFitSuite();
-    virtual std::unique_ptr<MultiLayer> createSample();
-    virtual std::unique_ptr<Simulation> createSimulation();
-    virtual std::unique_ptr<OutputData<double>> createOutputData(const Simulation* simulation);
-
-    bool analyzeResults(FitSuite& fit_suite) const;
-
-    std::vector<std::unique_ptr<FitParameterPlan>> m_parplans;
-    std::string m_minimizer_name;
-    std::string m_minimizer_algorithm;
-    std::string m_simulation_name;
-    std::string m_sample_builder_name;
-};
-
-
-#endif /* IOBSOLETEFITTINGTEST_H_ */
diff --git a/Tests/Functional/Fit/FitSuite/IObsoleteMinimizerTest.cpp b/Tests/Functional/Fit/FitSuite/IObsoleteMinimizerTest.cpp
deleted file mode 100644
index 2ee7761b84887743ce617e10867bb76cec444c94..0000000000000000000000000000000000000000
--- a/Tests/Functional/Fit/FitSuite/IObsoleteMinimizerTest.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Tests/Functional/Fit/IMinimizerTest.cpp
-//! @brief     Implements class IMinimizerTest.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "IObsoleteMinimizerTest.h"
-#include "Units.h"
-
-IObsoleteMinimizerTest::IObsoleteMinimizerTest(const std::string& minimizer_name,
-                               const std::string& minimizer_algorithm)
-    : IObsoleteFittingTest(minimizer_name, minimizer_algorithm, "MiniGISAS", "CylindersInBABuilder")
-{
-}
-
-IObsoleteMinimizerTest::~IObsoleteMinimizerTest() = default;
-
-//! Creates plan with initial/real values of fit parameters.
-
-void IObsoleteMinimizerTest::initParameterPlan() {
-  m_parplans.clear();
-  m_parplans.push_back(std::make_unique<FitParameterPlan>("*Height", 4.5 * Units::nanometer,
-                                          5.0 * Units::nanometer,
-                                          AttLimits::lowerLimited(0.01), 0.01));
-  m_parplans.push_back(std::make_unique<FitParameterPlan>("*Radius", 5.5 * Units::nanometer,
-                                          5.0 * Units::nanometer,
-                                          AttLimits::lowerLimited(0.01), 0.01));
-
-  IObsoleteFittingTest::initParameterPlan();
-}
diff --git a/Tests/Functional/Fit/FitSuite/IObsoleteMinimizerTest.h b/Tests/Functional/Fit/FitSuite/IObsoleteMinimizerTest.h
deleted file mode 100644
index 0d9dc05c5a09db66db5a19726bafdd57bb3125b4..0000000000000000000000000000000000000000
--- a/Tests/Functional/Fit/FitSuite/IObsoleteMinimizerTest.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Tests/Functional/Fit/IObsoleteMinimizerTest.h
-//! @brief     Defines class IObsoleteMinimizerTest.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef IOBSOLETEMINIMIZERTEST_H
-#define IOBSOLETEMINIMIZERTEST_H
-
-#include "IObsoleteFittingTest.h"
-
-//! @class IMinimizerTest
-//! @ingroup standard_samples
-//! @brief Basic class for all minimizer functional tests
-
-class IObsoleteMinimizerTest : public IObsoleteFittingTest
-{
-public:
-    IObsoleteMinimizerTest(const std::string &minimizer_name,
-                   const std::string &minimizer_algorithm = std::string());
-    virtual ~IObsoleteMinimizerTest();
-
-protected:
-    void initParameterPlan() override;
-};
-
-#endif // IOBSOLETEMINIMIZERTEST_H
diff --git a/Tests/Functional/Fit/FitSuite/MinimizerTests.cpp b/Tests/Functional/Fit/FitSuite/MinimizerTests.cpp
deleted file mode 100644
index 9fb781e029d934cc77e46c4fb077ecbd9df35713..0000000000000000000000000000000000000000
--- a/Tests/Functional/Fit/FitSuite/MinimizerTests.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Tests/Functional/Fit/MinimizerTests.cpp
-//! @brief     Implements classes MinimizerTests.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "MinimizerTests.h"
-#include "FitSuite.h"
-#include "MinimizerFactory.h"
-#include "SimAnMinimizer.h"
-#include "GeneticMinimizer.h"
-
-Minuit2MigradTest::Minuit2MigradTest()
-    : IObsoleteMinimizerTest("Minuit2", "Migrad")
-{}
-
-Minuit2FumiliTest::Minuit2FumiliTest()
-    : IObsoleteMinimizerTest("Minuit2", "Fumili")
-{}
-
-GSLLevenbergMarquardtTest::GSLLevenbergMarquardtTest()
-    : IObsoleteMinimizerTest("GSLLMA")
-{}
-
-
-GSLMultiMinBFGSTest::GSLMultiMinBFGSTest()
-    : IObsoleteMinimizerTest("GSLMultiMin", "BFGS")
-{}
-
-
-GSLMultiMinSteepestDescentTest::GSLMultiMinSteepestDescentTest()
-    : IObsoleteMinimizerTest("GSLMultiMin", "SteepestDescent")
-{}
-
-
-GSLSimulatedAnnealingTest::GSLSimulatedAnnealingTest()
-    : IObsoleteMinimizerTest("GSLSimAn")
-{}
-
-std::unique_ptr<FitSuite> GSLSimulatedAnnealingTest::createFitSuite()
-{
-    std::unique_ptr<FitSuite> result(new FitSuite());
-    result->initPrint(200);
-
-    SimAnMinimizer *minimizer = dynamic_cast<SimAnMinimizer *>
-            (MinimizerFactory::createMinimizer(m_minimizer_name, m_minimizer_algorithm));
-    assert(minimizer);
-    minimizer->setIterationsAtEachTemp(5);
-    minimizer->setMaxIterations(10);
-    minimizer->setBoltzmannMinTemp(1.0);
-
-    result->setMinimizer(minimizer);
-    for (auto& par: m_parplans) {
-        par->setTolerance(0.1);
-        result->addFitParameter(par->fitParameter());
-    }
-    return result;
-}
-
-
-GeneticTest::GeneticTest()
-    : IObsoleteMinimizerTest("Genetic")
-{}
-
-std::unique_ptr<FitSuite> GeneticTest::createFitSuite()
-{
-    std::unique_ptr<FitSuite> result(new FitSuite());
-    result->initPrint(200);
-
-    GeneticMinimizer *minimizer = dynamic_cast<GeneticMinimizer *>
-            (MinimizerFactory::createMinimizer(m_minimizer_name, m_minimizer_algorithm));
-    assert(minimizer);
-    minimizer->setMaxIterations(1);
-    minimizer->setRandomSeed(1);
-
-    result->setMinimizer(minimizer);
-    for (auto& par: m_parplans) {
-        par->setTolerance(0.1);
-        result->addFitParameter(par->fitParameter())->setLimits(AttLimits::limited(4.0, 6.0));
-    }
-    return result;
-}
diff --git a/Tests/Functional/Fit/FitSuite/MinimizerTests.h b/Tests/Functional/Fit/FitSuite/MinimizerTests.h
deleted file mode 100644
index ef4c9b8267be33dfde583bc662e3904c13e9d663..0000000000000000000000000000000000000000
--- a/Tests/Functional/Fit/FitSuite/MinimizerTests.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Tests/Functional/Fit/MinimizerTests.h
-//! @brief     Defines classes MinimizerTests.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef MINIMIZERTESTS_H
-#define MINIMIZERTESTS_H
-
-#include "IObsoleteMinimizerTest.h"
-
-//! basic test of Minuit2/Migrad minimizer
-class Minuit2MigradTest : public IObsoleteMinimizerTest
-{
-public:
-    Minuit2MigradTest();
-};
-
-//! basic test of Minuit2/Fumili minimizer
-class Minuit2FumiliTest : public IObsoleteMinimizerTest
-{
-public:
-    Minuit2FumiliTest();
-};
-
-//! basic test of GSL/LMA minimizer
-class GSLLevenbergMarquardtTest : public IObsoleteMinimizerTest
-{
-public:
-    GSLLevenbergMarquardtTest();
-};
-
-//! basic test of GSL/BFGS minimizer
-class GSLMultiMinBFGSTest : public IObsoleteMinimizerTest
-{
-public:
-    GSLMultiMinBFGSTest();
-};
-
-//! basic test of GSL/SteepestDescent minimizer
-class GSLMultiMinSteepestDescentTest : public IObsoleteMinimizerTest
-{
-public:
-    GSLMultiMinSteepestDescentTest();
-};
-
-//! basic test of GSL/SimulatedAnnealing minimizer
-class GSLSimulatedAnnealingTest : public IObsoleteMinimizerTest
-{
-public:
-    GSLSimulatedAnnealingTest();
-protected:
-    std::unique_ptr<FitSuite> createFitSuite();
-};
-
-//! basic test of Genetic minimizer
-class GeneticTest : public IObsoleteMinimizerTest
-{
-public:
-    GeneticTest();
-protected:
-    std::unique_ptr<FitSuite> createFitSuite();
-};
-
-#endif // MINIMIZERTESTS_H
-
-
diff --git a/Tests/Functional/Fit/FitSuite/MultiPatternFitTest.cpp b/Tests/Functional/Fit/FitSuite/MultiPatternFitTest.cpp
deleted file mode 100644
index d8967b5d44bd3771fd78ab7e449ca219c4ebdc6c..0000000000000000000000000000000000000000
--- a/Tests/Functional/Fit/FitSuite/MultiPatternFitTest.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Tests/Functional/Fit/MultiPatternFitTest.h
-//! @brief     Defines class MultiPatternFitTest.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "MultiPatternFitTest.h"
-#include "Units.h"
-#include "MultiLayer.h"
-#include "Layer.h"
-#include "MaterialFactoryFuncs.h"
-#include "Particle.h"
-#include "ParticleLayout.h"
-#include "FormFactorCylinder.h"
-#include "InterferenceFunction2DLattice.h"
-#include "GISASSimulation.h"
-
-namespace {
-    const double expected_value = 8.0*Units::nanometer;
-}
-
-MultiPatternFitTest::MultiPatternFitTest()
-    : IObsoleteMinimizerTest("GSLLMA")
-{
-
-}
-
-void MultiPatternFitTest::initParameterPlan()
-{
-    m_parplans.clear();
-
-    FitParameter par("*2DLattice/SquareLattice/LatticeLength*", 8.5*Units::nanometer);
-    par.setLimited(4., 12.).addPattern("*Cylinder/Radius").addPattern("*Cylinder/Height");
-
-    const double tolerance(0.01);
-    m_parplans.push_back(std::make_unique<FitParameterPlan>(par, expected_value, tolerance));
-}
-
-std::unique_ptr<MultiLayer> MultiPatternFitTest::createSample()
-{
-    std::unique_ptr<MultiLayer> result(new MultiLayer);
-
-    Particle cylinder(HomogeneousMaterial("Particle", 6e-4, 2e-8),
-                      FormFactorCylinder(expected_value, expected_value));
-    ParticleLayout layout(cylinder);
-
-    std::unique_ptr<InterferenceFunction2DLattice> interference(
-                InterferenceFunction2DLattice::createSquare(expected_value));
-    interference->setDecayFunction(FTDecayFunction2DCauchy(50.0*Units::nm, 50.0*Units::nm));
-
-    layout.setInterferenceFunction(*interference);
-
-    Layer air_layer(HomogeneousMaterial("Air", 0.0, 0.0));
-    air_layer.addLayout(layout);
-    Layer substrate_layer(HomogeneousMaterial("Substrate", 6e-6, 2e-8));
-
-    result->addLayer(air_layer);
-    result->addLayer(substrate_layer);
-    return result;
-}
-
diff --git a/Tests/Functional/Fit/FitSuite/MultiPatternFitTest.h b/Tests/Functional/Fit/FitSuite/MultiPatternFitTest.h
deleted file mode 100644
index 47c6b9a9fbfcebde1def9290fac2a03048ef5dee..0000000000000000000000000000000000000000
--- a/Tests/Functional/Fit/FitSuite/MultiPatternFitTest.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Tests/Functional/Fit/MultiPatternFitTest.h
-//! @brief     Defines class MultiPatternFitTest.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef MULTIPATTERNFITTEST_H
-#define MULTIPATTERNFITTEST_H
-
-#include "IObsoleteMinimizerTest.h"
-
-//! @class MultiPatternFitTest
-//! @ingroup standard_samples
-//! @brief Fit with one fit parameter steering few sample parameters via multiple pattern mechanism.
-
-class MultiPatternFitTest : public IObsoleteMinimizerTest
-{
-public:
-    MultiPatternFitTest();
-
-protected:
-    virtual void initParameterPlan();
-    virtual std::unique_ptr<MultiLayer> createSample();
-};
-
-#endif // MULTIPATTERNFITTEST_H
diff --git a/Tests/Functional/Fit/FitSuite/README b/Tests/Functional/Fit/FitSuite/README
deleted file mode 100644
index d70f72e65e512828b422fcae3cb33fc2abf510eb..0000000000000000000000000000000000000000
--- a/Tests/Functional/Fit/FitSuite/README
+++ /dev/null
@@ -1,9 +0,0 @@
-Collection of functional tests (C++)
-
-Collection of fitting tests for various geometries, number of fit parameters, variety of minimizers
-and minimization strategies.
-
-Tests are compiled and executed automatically when user builds
-the whole project with 'check' target cmake; make check
-
-One can run tests manually by running in the build directory ./bin/FitSuite
diff --git a/Tests/Functional/Fit/FitSuite/RectDetectorFitTest.cpp b/Tests/Functional/Fit/FitSuite/RectDetectorFitTest.cpp
deleted file mode 100644
index c8abf7f11cf6bf4dbcaa9cfa3a12e039f8151eab..0000000000000000000000000000000000000000
--- a/Tests/Functional/Fit/FitSuite/RectDetectorFitTest.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Tests/Functional/Fit/RectDetectorFitTest.cpp
-//! @brief     Implements class RectDetectorFitTest.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "RectDetectorFitTest.h"
-#include "GISASSimulation.h"
-#include "Histogram2D.h"
-#include "Rectangle.h"
-#include "RectangularDetector.h"
-#include "Units.h"
-
-RectDetectorFitTest::RectDetectorFitTest()
-    : IObsoleteMinimizerTest("Minuit2", "Migrad")
-{
-}
-
-std::unique_ptr<Simulation> RectDetectorFitTest::createSimulation()
-{
-    std::unique_ptr<GISASSimulation> result(new GISASSimulation());
-
-    double detector_distance(500.0);
-    double width(20.0), height(18.0);
-    RectangularDetector detector(20u, width, 18u, height);
-//    RectangularDetector detector(500, width, 450, height);
-    detector.setPerpendicularToSampleX(detector_distance, width/2., 0.0);
-
-    result->setBeamParameters(1.0*Units::angstrom, 0.2*Units::degree, 0.0*Units::degree);
-    result->setBeamIntensity(1e2);
-    result->setDetector(detector);
-    result->setRegionOfInterest(6.0, 6.0, 14.0, 12.0);
-    result->addMask(Rectangle(8.0, 8.0, 10.0, 10.0), true);
-
-    return std::move(result);
-}
-
-//! Creates cropped output data using histogram machinery
-std::unique_ptr<OutputData<double>>
-RectDetectorFitTest::createOutputData(const Simulation* simulation)
-{
-    std::unique_ptr<Simulation> simWithRoi(simulation->clone());
-    simWithRoi->getInstrument().getDetector()->resetRegionOfInterest();
-    simWithRoi->runSimulation();
-    auto sim_result = simWithRoi->result();
-    std::unique_ptr<OutputData<double>> result(sim_result.data());
-    return result;
-}
diff --git a/Tests/Functional/Fit/FitSuite/RectDetectorFitTest.h b/Tests/Functional/Fit/FitSuite/RectDetectorFitTest.h
deleted file mode 100644
index b8e69c67ec47f6fee645911df021a1fb515d21a6..0000000000000000000000000000000000000000
--- a/Tests/Functional/Fit/FitSuite/RectDetectorFitTest.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Tests/Functional/Fit/RectDetectorFitTest.h
-//! @brief     Defines class RectDetectorFitTest.
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef RECTDETECTORFITTEST_H
-#define RECTDETECTORFITTEST_H
-
-#include "IObsoleteMinimizerTest.h"
-
-
-//! @class RectDetectorFitTest
-//! @ingroup standard_samples
-//! @brief Fit of simulation with rectangular detector. The detector is cropped, masks are applied.
-
-class RectDetectorFitTest : public IObsoleteMinimizerTest
-{
-public:
-    RectDetectorFitTest();
-
-protected:
-    std::unique_ptr<Simulation> createSimulation() override;
-    std::unique_ptr<OutputData<double>> createOutputData(const Simulation* simulation) override;
-};
-
-#endif // RECTDETECTORFITTEST_H
diff --git a/Tests/Functional/Fit/FitSuite/StandardFitsFactory.cpp b/Tests/Functional/Fit/FitSuite/StandardFitsFactory.cpp
deleted file mode 100644
index 670d583c6d259e9760d081fac4186e68fecdc94e..0000000000000000000000000000000000000000
--- a/Tests/Functional/Fit/FitSuite/StandardFitsFactory.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Tests/Functional/Fit/StandardFitsFactory.cpp
-//! @brief     Implements class StandardFitsFactory
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#include "StandardFitsFactory.h"
-#include "AdjustMinimizerStrategyTest.h"
-#include "MinimizerTests.h"
-#include "MultiPatternFitTest.h"
-#include "RectDetectorFitTest.h"
-
-StandardFitsFactory::StandardFitsFactory()
-{
-    registerItem(
-        "Minuit2_Migrad",
-        create_new<Minuit2MigradTest>,
-        "Functional test of Minuit2/Migrad minimizer");
-
-    registerItem(
-        "Minuit2_Fumili",
-        create_new<Minuit2FumiliTest>,
-        "Functional test of Minuit2/Fumili minimizer");
-
-    registerItem(
-        "GSLLevenbergMarquardt",
-        create_new<GSLLevenbergMarquardtTest>,
-        "Functional test of GSL's LevenbergMarquardt minimizer");
-
-    registerItem(
-        "GSLMultiMinBFGS",
-        create_new<GSLMultiMinBFGSTest>,
-        "Functional test of GSL's MultiMin/BFGS minimizer");
-
-    registerItem(
-        "GSLMultiMinSteepestDescent",
-        create_new<GSLMultiMinSteepestDescentTest>,
-        "Functional test of GSL's MultiMin/SteepestDescent minimizer");
-
-    registerItem(
-        "GSLSimulatedAnnealing",
-        create_new<GSLSimulatedAnnealingTest>,
-        "Functional test of GSL's Simulated Annealing minimizer");
-
-    registerItem(
-        "GeneticMinimizer",
-        create_new<GeneticTest>,
-        "Functional test of TMVA's Genetic minimizer");
-
-    registerItem(
-        "RectDetectorFit",
-        create_new<RectDetectorFitTest>,
-        "Fit of rectangular detector, with crop and masks applied");
-
-    registerItem(
-        "AdjustMinimizerStrategy",
-        create_new<AdjustMinimizerStrategyTest>,
-        "Test of minimizer chain: genetic -> minuit2");
-
-    registerItem(
-        "MultiPatternFit",
-        create_new<MultiPatternFitTest>,
-        "Test of multipattern fit");
-}
diff --git a/Tests/Functional/Fit/FitSuite/StandardFitsFactory.h b/Tests/Functional/Fit/FitSuite/StandardFitsFactory.h
deleted file mode 100644
index 366f243b31eea415569c81c4648bd56a6c0a83c4..0000000000000000000000000000000000000000
--- a/Tests/Functional/Fit/FitSuite/StandardFitsFactory.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Tests/Functional/Fit/StandardFitsFactory.h
-//! @brief     Defines class StandardFitsFactory
-//!
-//! @homepage  http://www.bornagainproject.org
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2018
-//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
-//
-// ************************************************************************** //
-
-#ifndef STANDARDFITSFACTORY_H
-#define STANDARDFITSFACTORY_H
-
-#include "FunctionalTestFactory.h"
-
-//! @class StandardFitsFactory
-//! @ingroup standard_samples
-//! @brief Factory to create predefined functional fit tests
-
-class StandardFitsFactory : public FunctionalTestFactory
-{
-public:
-    StandardFitsFactory();
-};
-
-#endif // STANDARDFITSFACTORY_H
diff --git a/Tests/Functional/Fit/Minimizer/FunctionTestPlanCases.cpp b/Tests/Functional/Fit/Minimizer/FunctionTestPlanCases.cpp
index cae9fdee77f7d550a97ea2eef475cb44b9c48ef1..1a4a0d9e06956ae7d38d7c12c720801dc7a23787 100644
--- a/Tests/Functional/Fit/Minimizer/FunctionTestPlanCases.cpp
+++ b/Tests/Functional/Fit/Minimizer/FunctionTestPlanCases.cpp
@@ -77,6 +77,15 @@ DecayingSinPlan::DecayingSinPlan()
     addParameter(Parameter("decay", 0.1, AttLimits::nonnegative()), 0.05);
 }
 
+DecayingSinPlanV2::DecayingSinPlanV2()
+    : ResidualTestPlan("DecayingSinPlanV2", TestFunctions::DecayingSin)
+{
+    addParameter(Parameter("amp", 1.0, AttLimits::limitless()), 2.0);
+    addParameter(Parameter("frequency", 1.0, AttLimits::limitless()), 2.0);
+    addParameter(Parameter("phase", 1.0, AttLimits::fixed()), 1.0);
+    addParameter(Parameter("decay", 0.05, AttLimits::fixed()), 0.05);
+}
+
 TestMinimizerPlan::TestMinimizerPlan()
     : ScalarTestPlan("TestMinimizerPlan", TestFunctions::RosenBrock, 0.0)
 {
diff --git a/Tests/Functional/Fit/Minimizer/FunctionTestPlanCases.h b/Tests/Functional/Fit/Minimizer/FunctionTestPlanCases.h
index 4b3a5cc2fd2bf2eb141d500905ebb8e5987e9f35..a4c1e088cd12954be629db943f525903a10339b1 100644
--- a/Tests/Functional/Fit/Minimizer/FunctionTestPlanCases.h
+++ b/Tests/Functional/Fit/Minimizer/FunctionTestPlanCases.h
@@ -61,6 +61,14 @@ public:
     DecayingSinPlan();
 };
 
+//! Same as DecayingSinPlan with fewer fit parameters
+
+class DecayingSinPlanV2 : public ResidualTestPlan
+{
+public:
+    DecayingSinPlanV2();
+};
+
 //! Special plan to test TestMinimizer.
 
 class TestMinimizerPlan : public ScalarTestPlan
diff --git a/Tests/Functional/Fit/Minimizer/FunctionTestPlanFactory.cpp b/Tests/Functional/Fit/Minimizer/FunctionTestPlanFactory.cpp
index 6c1b750e2df6e537f873d766d8cbbe6354c1fd47..6adef044adf35c90a7c4a291dd79924d21fc9f6f 100644
--- a/Tests/Functional/Fit/Minimizer/FunctionTestPlanFactory.cpp
+++ b/Tests/Functional/Fit/Minimizer/FunctionTestPlanFactory.cpp
@@ -22,5 +22,6 @@ FunctionTestPlanFactory::FunctionTestPlanFactory()
     registerItem("WoodFourPlan", create_new<WoodFourPlan>);
     registerItem("EasyWoodFourPlan", create_new<EasyWoodFourPlan>);
     registerItem("DecayingSinPlan", create_new<DecayingSinPlan>);
+    registerItem("DecayingSinPlanV2", create_new<DecayingSinPlanV2>);
     registerItem("TestMinimizerPlan", create_new<TestMinimizerPlan>);
 }
diff --git a/Tests/Functional/Fit/Minimizer/MinimizerTestCases.cpp b/Tests/Functional/Fit/Minimizer/MinimizerTestCases.cpp
index 552c1d3881e0246831fa45de5d8888d813c68a9a..1f0d529df85baea9be0c310e7af6b4238d9f8638 100644
--- a/Tests/Functional/Fit/Minimizer/MinimizerTestCases.cpp
+++ b/Tests/Functional/Fit/Minimizer/MinimizerTestCases.cpp
@@ -78,7 +78,7 @@ FumiliTestV3::FumiliTestV3()
 }
 
 LevenbergMarquardtV3::LevenbergMarquardtV3()
-    : MinimizerTest("GSLLMA", "Default", "DecayingSinPlan") {}
+    : MinimizerTest("GSLLMA", "Default", "DecayingSinPlanV2") {}
 
 
 TestMinimizerV1::TestMinimizerV1()
diff --git a/Tests/Functional/Fit/Minimizer/MinimizerTestFactory.cpp b/Tests/Functional/Fit/Minimizer/MinimizerTestFactory.cpp
index 195e08fbc1c996234f07ab20692801f415207352..9be1e56bfe66f45ba893e3c6f836e48a50c6c481 100644
--- a/Tests/Functional/Fit/Minimizer/MinimizerTestFactory.cpp
+++ b/Tests/Functional/Fit/Minimizer/MinimizerTestFactory.cpp
@@ -63,7 +63,7 @@ MinimizerTestFactory::MinimizerTestFactory()
                  "Minuit + Fumili + DecayingSinPlan");
 
     registerItem("LevenbergMarquardtV3", create_new<LevenbergMarquardtV3>,
-                 "LevenbergMarquardt + DecayingSinPlan");
+                 "LevenbergMarquardt + DecayingSinPlanV2");
 
     registerItem("TestMinimizerV1", create_new<TestMinimizerV1>,
                  "Test minimizer");
diff --git a/Tests/Functional/GUI/CMakeLists.txt b/Tests/Functional/GUI/CMakeLists.txt
index fdfa5f0fa40b43c676a771cde6f7d8e8bfda9a5a..c0a7bdb20fa5256e9707be9c00d66761c32682aa 100644
--- a/Tests/Functional/GUI/CMakeLists.txt
+++ b/Tests/Functional/GUI/CMakeLists.txt
@@ -1,12 +1,4 @@
-if(POLICY CMP0020)
-    cmake_policy(SET CMP0020 NEW)
-endif()
-if(POLICY CMP0043)
-    cmake_policy(SET CMP0043 NEW)
-endif()
-
 find_package(Qt5Widgets REQUIRED)
-include_directories(${BornAgainGUI_INCLUDE_DIRS})
 
 add_subdirectory(GUIStandardTest)
 add_subdirectory(GUISpecial)
diff --git a/Tests/Functional/GUI/GUISpecial/CMakeLists.txt b/Tests/Functional/GUI/GUISpecial/CMakeLists.txt
index fef977c43ae479ef40e6e30c3b6d828e240885d5..df65d8268dcf1c756e60623dc7e6a4e30a77fff7 100644
--- a/Tests/Functional/GUI/GUISpecial/CMakeLists.txt
+++ b/Tests/Functional/GUI/GUISpecial/CMakeLists.txt
@@ -17,7 +17,10 @@ set(test_cases
     RoughnessTranslation
     TwoLayerRoughnessTranslation
     SaveLoadProject
-#    GUIPerformanceTest  # too heavy, call manually when necessary
+# Performance tests are not part of the functional test suite.
+# They need to be run manually when needed.
+#    CsvImportAssistantPerformanceTest
+#    GUIPerformanceTest
 )
 
 file(GLOB source_files "*.cpp")
diff --git a/Tests/Functional/GUI/GUISpecial/CsvImportAssistantPerformanceTest.cpp b/Tests/Functional/GUI/GUISpecial/CsvImportAssistantPerformanceTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..89479b044c3789d87328fc376df794ee1a219417
--- /dev/null
+++ b/Tests/Functional/GUI/GUISpecial/CsvImportAssistantPerformanceTest.cpp
@@ -0,0 +1,95 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      Tests/Functional/GUI/GUIPerformanceTest/GUIPerformanceTest.cpp
+//! @brief     Implements GUI performance functional test.
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#include "CsvImportAssistantPerformanceTest.h"
+#include "ArrayUtils.h"
+#include "CsvImportAssistant.h"
+#include "OutputDataReadFactory.h"
+#include "OutputDataWriteFactory.h"
+#include <ctime>
+#include <iostream>
+
+CsvImportAssistantPerformanceTest::CsvImportAssistantPerformanceTest() {}
+
+CsvImportAssistantPerformanceTest::~CsvImportAssistantPerformanceTest() {}
+
+void CsvImportAssistantPerformanceTest::writeTestFile()
+{
+    remove(m_testFilename.c_str());
+    OutputDataWriter* writer = OutputDataWriteFactory::getWriter(m_testFilename);
+    OutputData<double>* data = ArrayUtils::createData2D(m_testVector).release();
+    writer->writeOutputData(*data);
+}
+
+void CsvImportAssistantPerformanceTest::writeTestFile(size_t nRows, size_t nCols)
+{
+    remove(m_testFilename.c_str());
+    std::ofstream myfile;
+    myfile.open(m_testFilename);
+    for (size_t i = 0; i < nRows; i++) {
+        for (size_t j = 0; j < nCols; j++) {
+            myfile << nCols * i + j << " ";
+        }
+        myfile << "\n";
+    }
+    myfile.close();
+}
+
+OutputData<double>* CsvImportAssistantPerformanceTest::readTestFile()
+{
+    OutputDataReader* reader = OutputDataReadFactory::getReader(m_testFilename);
+    OutputData<double>* data = reader->getOutputData();
+    return data;
+}
+
+bool CsvImportAssistantPerformanceTest::runTest()
+{
+    std::cout << "CsvImportAssistantPerformanceTest -> Running ..." << std::endl;
+    size_t maxRows = 1000;
+    size_t maxCols = 1000;
+
+    for (size_t nRows = 10; nRows <= maxRows; nRows *= 10) {
+        for (size_t nCols = 10; nCols <= maxCols; nCols *= 10) {
+
+            // Write test file
+            writeTestFile(nRows, nCols);
+
+            // Time the process of reading and importing data:
+            std::clock_t c_start = std::clock();
+
+            // Reading and setting data to import:
+            CsvImportAssistant assistant(testFilename());
+            assistant.setIntensityColumn(1);
+            assistant.setCoordinateColumn(9, AxesUnits::DEGREES);
+            assistant.setFirstRow(1);
+            assistant.setLastRow(int(nRows));
+
+            // Importing of data:
+            // If something goes wrong, this line may make the test fail or even crash.
+            // The correctness of the reading is tested in test_readFile.
+            std::vector<double> RawDataVec =
+                assistant.getData().intensityData()->getRawDataVector();
+            if (RawDataVec.size() != nRows)
+                return false;
+
+            // Report on the test time:
+            std::clock_t c_end = std::clock();
+            double_t time_spent = 1000.0 * double_t(c_end - c_start) / double_t(CLOCKS_PER_SEC);
+            std::cout << "nRows: " << nRows << "; nCols: " << nCols << "; time: " << time_spent
+                      << " ms\n"
+                      << std::flush;
+        }
+    }
+    return true;
+}
diff --git a/Tests/Functional/GUI/GUISpecial/CsvImportAssistantPerformanceTest.h b/Tests/Functional/GUI/GUISpecial/CsvImportAssistantPerformanceTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..b4bc09795b50596bfb4a77635b50695e585992cd
--- /dev/null
+++ b/Tests/Functional/GUI/GUISpecial/CsvImportAssistantPerformanceTest.h
@@ -0,0 +1,45 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      Tests/Functional/GUI/GUIPerformanceTest/GUIPerformanceTest.h
+//! @brief     Defines GUI performance functional test.
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2018
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+// ************************************************************************** //
+
+#ifndef CSVIMPORTASSISTANTPERFORMANCETEST_H
+#define CSVIMPORTASSISTANTPERFORMANCETEST_H
+
+#include "IFunctionalTest.h"
+#include "SpecularDataItem.h"
+#include <QString>
+#include <memory>
+
+//! Functional test to measure performance of CsvImportAssistant by loading files of different sizes
+class CsvImportAssistantPerformanceTest : public IFunctionalTest
+{
+public:
+    CsvImportAssistantPerformanceTest();
+    ~CsvImportAssistantPerformanceTest();
+
+protected:
+    const QString testFilename() { return QString::fromStdString(m_testFilename); }
+    void writeTestFile();
+    void writeTestFile(size_t nRows, size_t nCols);
+    OutputData<double>* readTestFile();
+    bool runTest();
+
+    const std::string m_testFilename = "tmp_TestCsvImportAssistant.txt";
+    const std::vector<std::vector<double>> m_testVector = {
+        {0.0, 1.0, 2.0, 3.0},     {4.0, 5.0, 6.0, 7.0},     {8.0, 9.0, 10.0, 11.0},
+        {12.0, 13.0, 14.0, 15.0}, {16.0, 17.0, 18.0, 19.0}, {20.0, 21.0, 22.0, 23.0}};
+
+private:
+};
+
+#endif // CSVIMPORTASSISTANTPERFORMANCETEST_H
diff --git a/Tests/Functional/GUI/GUISpecial/GUISpecialTestFactory.cpp b/Tests/Functional/GUI/GUISpecial/GUISpecialTestFactory.cpp
index 92b150fc13b1f0d58334cf070e9c0a839c1f8b62..c1b6e99f0725c8c413a0d7aa78f0aea23860baaf 100644
--- a/Tests/Functional/GUI/GUISpecial/GUISpecialTestFactory.cpp
+++ b/Tests/Functional/GUI/GUISpecial/GUISpecialTestFactory.cpp
@@ -13,6 +13,7 @@
 // ************************************************************************** //
 
 #include "GUISpecialTestFactory.h"
+#include "CsvImportAssistantPerformanceTest.h"
 #include "TranslationCases.h"
 #include "GUIPerformanceTest.h"
 #include "GUISaveLoadProject.h"
@@ -86,4 +87,7 @@ GUISpecialTestFactory::GUISpecialTestFactory()
     registerItem("SaveLoadProject",
                  create_new<GUISaveLoadProject>,
                  "Save/load project test");
+    registerItem("CsvImportAssistantPerformanceTest",
+                 create_new<CsvImportAssistantPerformanceTest>,
+                 "Measuring performance of loading ascii files");
 }
diff --git a/Tests/Functional/GUI/GUISpecial/GUITranslationTest.cpp b/Tests/Functional/GUI/GUISpecial/GUITranslationTest.cpp
index de9e9bddec9d418bf50f4bb2958e906700c1c583..bc58b9d741214436cb06e019a672b35fa1069a02 100644
--- a/Tests/Functional/GUI/GUISpecial/GUITranslationTest.cpp
+++ b/Tests/Functional/GUI/GUISpecial/GUITranslationTest.cpp
@@ -24,24 +24,32 @@
 #include "InstrumentItems.h"
 #include "JobItem.h"
 #include "JobModel.h"
+#include "MaterialItem.h"
 #include "ModelPath.h"
 #include "MultiLayer.h"
 #include "MultiLayerItem.h"
 #include "ParameterPool.h"
 #include "ParameterTreeItems.h"
 #include "ParameterTreeUtils.h"
+#include "RectangularDetectorItem.h"
 #include "SampleBuilderFactory.h"
 #include "SampleModel.h"
 #include "SimulationFactory.h"
+#include "SphericalDetectorItem.h"
 #include "StringUtils.h"
 #include <QStack>
 
 namespace {
     std::string header(size_t width=80) { return std::string(width, '-'); }
+
+    //! Returns true, if it makes sence to look for GUI translation for given domain name.
+    //! Intended to supress warnings about not-yet implemented translations.
+    bool requiresTranslation(ParameterItem* parItem);
+    bool containsNames(const QString& text, const QStringList& names);
 }
 
 GUITranslationTest::GUITranslationTest(const std::string& simName, const std::string& sampleName)
-    : m_models(new ApplicationModels(0))
+    : m_models(new ApplicationModels(nullptr))
     , m_simulationName(simName)
     , m_sampleName(sampleName)
 {
@@ -92,13 +100,13 @@ void GUITranslationTest::processParameterTree()
     JobItem *jobItem = m_models->jobModel()->addJob(
                 m_models->sampleModel()->multiLayerItem(),
                 m_models->instrumentModel()->instrumentItem(),
-                0,
+                nullptr,
                 m_models->documentModel()->simulationOptionsItem());
 
     SessionItem *container = jobItem->parameterContainerItem();
 
     ParameterTreeUtils::visitParameterContainer(container, [&](ParameterItem *parItem){
-        if(parItem->isFittable()) {
+        if(requiresTranslation(parItem)) {
             std::string sampleParLink =
                     parItem->getItemValue(ParameterItem::P_LINK).toString().toStdString();
 
@@ -140,9 +148,6 @@ std::string GUITranslationTest::translationResultsToString() const
     return ostr.str();
 }
 
-//! Returns true, if it makes sence to look for GUI translation for given domain name.
-//! Intended to supress warnings about not-yet implemented translations.
-
 bool GUITranslationTest::isValidDomainName(const std::string& domainName) const
 {
     std::vector<std::string> invalidNames {
@@ -249,3 +254,75 @@ bool GUITranslationTest::checkMissedTranslations()
     bool isSuccess = (missedNames.empty() ? true : false);
     return isSuccess;
 }
+
+namespace {
+const QVector<QPair<QStringList, QStringList>> black_list {
+    {// Global scope
+        {
+            QString()
+        },
+        {
+            Constants::DistributionSigmaFactor,
+            Constants::MaterialRefractiveDataType,
+            Constants::MaterialSLDDataType,
+            MaterialItem::P_MAGNETIZATION
+        }
+    },
+    {// Instrument scope
+        {
+            Constants::GISASInstrumentType,
+            Constants::OffSpecInstrumentType,
+            Constants::SpecularInstrumentType
+        },
+        {// Distribution types
+            Constants::DistributionGateType, Constants::DistributionLorentzType,
+            Constants::DistributionGaussianType, Constants::DistributionLogNormalType,
+            Constants::DistributionCosineType, Constants::DistributionTrapezoidType,
+
+            // Detector axes
+            SphericalDetectorItem::P_PHI_AXIS, SphericalDetectorItem::P_ALPHA_AXIS,
+            RectangularDetectorItem::P_X_AXIS, RectangularDetectorItem::P_Y_AXIS,
+            OffSpecInstrumentItem::P_ALPHA_AXIS,
+
+            // Rectangular detector positioning
+            RectangularDetectorItem::P_ALIGNMENT, RectangularDetectorItem::P_NORMAL,
+            RectangularDetectorItem::P_DIRECTION, RectangularDetectorItem::P_U0,
+            RectangularDetectorItem::P_V0, RectangularDetectorItem::P_DBEAM_U0,
+            RectangularDetectorItem::P_DBEAM_V0, RectangularDetectorItem::P_DISTANCE,
+
+            // Detector resolution
+            Constants::ResolutionFunction2DGaussianType,
+
+            // Beam angle parameters
+            BeamItem::P_INCLINATION_ANGLE, BeamItem::P_AZIMUTHAL_ANGLE
+        }
+    }
+};
+
+bool requiresTranslation(ParameterItem* parItem)
+{
+    if (!parItem)
+        return false;
+
+    const QString& par_path = FitParameterHelper::getParameterItemPath(parItem);
+
+    for (const auto& item : black_list) {
+        if (item.first.size() == 1 && item.first[0].isNull()) { // checking global scope
+            if (containsNames(par_path, item.second))
+                return false;
+        } else { // checking everything else
+            if (containsNames(par_path, item.first) && containsNames(par_path, item.second))
+                return false;
+        }
+    }
+    return true;
+}
+
+bool containsNames(const QString& text, const QStringList& names)
+{
+    for (const auto& name : names)
+        if (text.contains(name))
+            return true;
+    return false;
+}
+}
diff --git a/Tests/Functional/GUI/GUIStandardTest/CMakeLists.txt b/Tests/Functional/GUI/GUIStandardTest/CMakeLists.txt
index 75555f519cf195969993a0b83f3fdaff1ba93776..e06b5814572dc8df7fb7586a5828d189494c01b3 100644
--- a/Tests/Functional/GUI/GUIStandardTest/CMakeLists.txt
+++ b/Tests/Functional/GUI/GUIStandardTest/CMakeLists.txt
@@ -22,6 +22,7 @@ set(test_cases
     CoreShellParticle
     CosineRipple
     CylindersAndPrisms
+    CylindersInSSCA
     CylindersWithSizeDistribution
     DetectorResolution
     FormFactors
@@ -57,6 +58,7 @@ set(test_cases
     RotatedPyramidsDistribution
     SpheresWithLimitsDistribution
     ConesWithLimitsDistribution
+    LinkedBoxDistribution
     OffSpecularResonator
     SquareBeamFootprint
     GaussianBeamFootprint
diff --git a/Tests/Functional/Python/PyCore/fitobject.py b/Tests/Functional/Python/PyCore/fitobject.py
deleted file mode 100644
index d91dc9b4af9b5f57671c463462ddbd8182f773a1..0000000000000000000000000000000000000000
--- a/Tests/Functional/Python/PyCore/fitobject.py
+++ /dev/null
@@ -1,77 +0,0 @@
-import unittest
-import numpy as np
-import sys
-
-sys.path.append("@CMAKE_LIBRARY_OUTPUT_DIRECTORY@")
-import bornagain as ba
-
-from bornagain import deg
-
-
-class FitObjectTest(unittest.TestCase):
-
-    def test_constructFromOutputData(self):
-        """
-        Check construction from OutputData
-        """
-        nx, ny = 4, 3
-        xmin, xmax = -1.0*deg, 3.0*deg
-        ymin, ymax = 0.0*deg, 3.0*deg
-
-        # preparing simulation and OutputData
-        simulation = ba.GISASSimulation()
-        simulation.setDetectorParameters(nx, xmin, xmax, ny, ymin, ymax)
-
-        data = ba.IntensityData()
-        data.addAxis(ba.FixedBinAxis("phi", nx, xmin, xmax))
-        data.addAxis(ba.FixedBinAxis("alpha", ny, ymin, ymax))
-        buff = np.linspace(0, 12, num=12, endpoint=False)
-        buff = np.asarray(buff, dtype=np.float64)
-        data.setRawDataVector(buff)
-
-        # constructing FitObject
-        fit_object = ba.FitObject(simulation, data)
-
-        # accessing experimental data as flat array
-        self.assertEqual(list(fit_object.experimental_array()), buff.tolist())
-
-        # accessing experimental data via SimulationResult mechanism
-        expected = np.array([[2.0,  5.0,  8.0, 11.0],
-                             [1.0,  4.0,  7.0, 10.0],
-                             [0.0,  3.0,  6.0,  9.0]], dtype=np.float64)
-
-        for (x, y), element in np.ndenumerate(expected):
-            self.assertEqual(element, fit_object.experimentalData().array()[x][y])
-
-
-    def test_constructFromNumpyDouble(self):
-        """
-        Check construction from OutputData
-        """
-        nx, ny = 4, 3
-        xmin, xmax = -1.0*deg, 3.0*deg
-        ymin, ymax = 0.0*deg, 3.0*deg
-
-        # preparing simulation and experimental data as numpy array
-
-        simulation = ba.GISASSimulation()
-        simulation.setDetectorParameters(nx, xmin, xmax, ny, ymin, ymax)
-
-        exp_data = np.array([[0,  1,  2,  3],
-                             [4,  5,  6,  7],
-                             [8,  9, 10, 11]], np.float64)
-
-        # constructing FitObject
-        fit_object = ba.FitObject(simulation, exp_data)
-
-        # accessing experimental data as flat array
-        expected = [8.0, 4.0,  0.0, 9.0, 5.0, 1.0, 10.0, 6.0, 2.0, 11.0, 7.0, 3.0]
-        self.assertEqual(list(fit_object.experimental_array()), expected)
-
-        # accessing experimental data via SimulationResult mechanism
-        for (x, y), element in np.ndenumerate(exp_data):
-            self.assertEqual(element, fit_object.experimentalData().array()[x][y])
-
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/Tests/Functional/Python/PyCore/intensitydata_io.py b/Tests/Functional/Python/PyCore/intensitydata_io.py
index 30bb1c31ea0c01096208c28e9cfad81dd2c67611..8036314dfba8c89fe059094df920117391ef834f 100644
--- a/Tests/Functional/Python/PyCore/intensitydata_io.py
+++ b/Tests/Functional/Python/PyCore/intensitydata_io.py
@@ -135,5 +135,48 @@ class OutputDataIOTest(unittest.TestCase):
         newdata = ba.IntensityDataIOFactory.readOutputData("tmp.int.bz2")
         self.assertTrue(is_the_same_data(data, newdata))
 
+    def test_SaveToTXT(self):
+        data = ba.IntensityData()
+        data.addAxis(ba.FixedBinAxis("axis0", 10, 0.0, 10.0))
+        data.addAxis(ba.FixedBinAxis("axis1", 5, 0.0, 5.0))
+        fill_data(data)
+
+        ba.IntensityDataIOFactory.writeOutputData(data, "tmp.txt")
+        newdata = ba.IntensityDataIOFactory.readOutputData("tmp.txt")
+        self.assertTrue(is_the_same_data(data, newdata))
+
+    def test_SaveNumpyArray_ReadOutputData(self):
+        arr = numpy.array([
+            [0.0, 1.0, 2.0,  3.0],
+            [4.0, 5.0, 6.0,  7.0],
+            [8.0, 9.0, 10.0, 11.0]
+        ])
+        numpy.savetxt('tmp.txt', arr)
+        newdata = ba.IntensityDataIOFactory.readOutputData("tmp.txt")
+        self.assertTrue(numpy.array_equal(newdata.getArray(),arr))
+
+    def test_SaveNumpyArray_ReadRawDataVector(self):
+        arr = numpy.array([
+            [0.0, 1.0, 2.0,  3.0],
+            [4.0, 5.0, 6.0,  7.0],
+            [8.0, 9.0, 10.0, 11.0]
+        ])
+        numpy.savetxt('tmp.txt', arr)
+        newdata = numpy.array(ba.IntensityDataIOFactory.readOutputData("tmp.txt").getRawDataVector())
+        expected = numpy.array([8.,4.,0.,9.,5.,1.,10.,6.,2.,11.,7.,3.])
+        self.assertTrue(numpy.array_equal(newdata,expected))
+
+    def test_SaveOutputData_ReadNumpyArray(self):
+        data = ba.IntensityData()
+        data.addAxis(ba.FixedBinAxis("axis0", 10, 0.0, 10.0))
+        data.addAxis(ba.FixedBinAxis("axis1", 5, 0.0, 5.0))
+        fill_data(data)
+
+        ba.IntensityDataIOFactory.writeOutputData(data, "tmp.txt")
+        arr = numpy.loadtxt("tmp.txt")
+
+        self.assertTrue(numpy.array_equal(data.getArray(),arr))
+
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/Tests/Functional/Python/PyEmbedded/TestCases.cpp b/Tests/Functional/Python/PyEmbedded/TestCases.cpp
index b4764bbe8c291ff32adf4ce53cd8733319c880b9..6ea4de2c56ce72eeb484578144336d661ffedc29 100644
--- a/Tests/Functional/Python/PyEmbedded/TestCases.cpp
+++ b/Tests/Functional/Python/PyEmbedded/TestCases.cpp
@@ -13,6 +13,7 @@
 // ************************************************************************** //
 
 #include "TestCases.h"
+#include "PythonCore.h"
 #include "PyEmbeddedUtils.h"
 #include "PyImport.h"
 #include "BornAgainNamespace.h"
diff --git a/Tests/Functional/Python/PyFit/CMakeLists.txt b/Tests/Functional/Python/PyFit/CMakeLists.txt
index bb2e0553167170d2230b52ca08d00dd6a20be134..72a470992ebe8c391eb29ee86a18376b94720f8c 100644
--- a/Tests/Functional/Python/PyFit/CMakeLists.txt
+++ b/Tests/Functional/Python/PyFit/CMakeLists.txt
@@ -12,15 +12,9 @@ foreach(_src ${sources})
 endforeach()
 
 set(tests
-    "testfit_UsingBuilder.py"
-    "fitsuite_api.py"
     "minimizer_api.py"
     "standalone_fits.py"
     "fitobjective_api.py"
-#    "testfit_GSLLMA.py"
-#    "testfit_GSLMultiMin.py"
-#    "testfit_GSLSimAn.py"
-#    "testfit_Minuit2.py"
 )
 
 foreach(_test ${tests})
diff --git a/Tests/Functional/Python/PyFit/fitsuite_api.py b/Tests/Functional/Python/PyFit/fitsuite_api.py
deleted file mode 100644
index 5f46cb6b607947de247c60c9068615b73aaa4d10..0000000000000000000000000000000000000000
--- a/Tests/Functional/Python/PyFit/fitsuite_api.py
+++ /dev/null
@@ -1,73 +0,0 @@
-"""
-Testing of python specific FitSuite API.
-"""
-import sys
-import os
-import unittest
-
-sys.path.append("@CMAKE_LIBRARY_OUTPUT_DIRECTORY@")
-import bornagain as ba
-
-class FitSuiteAPITest(unittest.TestCase):
-
-    def test_FitParameterSetIterator(self):
-        """
-        Testing of python iterator over defined fit parameters.
-        """
-        fitSuite = ba.FitSuite()
-        names = ["par0", "par1", "par2"]
-        values = [1.0, 2.0, 3.0]
-        for name, value in zip(names, values):
-            fitSuite.addFitParameter(name, value)
-
-        nn = 0
-        for par in fitSuite.fitParameters():
-            self.assertTrue(par.name() == names[nn])
-            self.assertTrue(par.value() == values[nn])
-            nn = nn+1
-
-        self.assertTrue(nn == 3)
-
-    def test_addFitParameter(self):
-        fitSuite = ba.FitSuite()
-        fitSuite.addFitParameter("pattern0", 1.0)
-        fitSuite.addFitParameter("pattern1", 2.0, ba.AttLimits.limited(10.0, 20.0), 0.02)
-        fitSuite.addFitParameter("pattern2", 3.0).setLowerLimited(30.0).setStep(0.03)
-        fitSuite.addFitParameter("pattern3", 4.0).setStep(0.04).setUpperLimited(40.0)
-        fitSuite.addFitParameter("pattern4", 5.0).setFixed()
-
-        par = fitSuite.fitParameters()[0]
-        self.assertEqual(par.name(), "par0")
-        self.assertEqual(par.value(), 1.0)
-        self.assertEqual(par.step(), 0.01)  # default step is 1% in FitSuite
-        self.assertTrue(par.limits().isLimitless())
-
-        par = fitSuite.fitParameters()[1]
-        self.assertEqual(par.name(), "par1")
-        self.assertEqual(par.value(), 2.0)
-        self.assertEqual(par.step(), 0.02)
-        self.assertTrue(par.limits().isLimited())
-        self.assertEqual(par.limits().lowerLimit(), 10.0)
-        self.assertEqual(par.limits().upperLimit(), 20.0)
-
-        par = fitSuite.fitParameters()[2]
-        self.assertEqual(par.name(), "par2")
-        self.assertEqual(par.value(), 3.0)
-        self.assertEqual(par.step(), 0.03)
-        self.assertTrue(par.limits().isLowerLimited())
-        self.assertEqual(par.limits().lowerLimit(), 30.0)
-
-        par = fitSuite.fitParameters()[3]
-        self.assertEqual(par.name(), "par3")
-        self.assertEqual(par.value(), 4.0)
-        self.assertEqual(par.step(), 0.04)
-        self.assertTrue(par.limits().isUpperLimited())
-        self.assertEqual(par.limits().upperLimit(), 40.0)
-
-        par = fitSuite.fitParameters()[4]
-        self.assertEqual(par.name(), "par4")
-        self.assertEqual(par.value(), 5.0)
-        self.assertTrue(par.limits().isFixed())
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/Tests/Functional/Python/PyFit/fitting_utils.py b/Tests/Functional/Python/PyFit/fitting_utils.py
deleted file mode 100644
index 8ee1285fd347afad24dea69a65ad1f6cc6f639c8..0000000000000000000000000000000000000000
--- a/Tests/Functional/Python/PyFit/fitting_utils.py
+++ /dev/null
@@ -1,89 +0,0 @@
-import sys
-import os
-from __future__ import print_function
-
-sys.path.append(os.path.abspath(
-                os.path.join(os.path.split(__file__)[0], '..', '..', '..', 'lib')))
-
-from libBornAgainCore import *
-from libBornAgainFit import *
-
-
-CYLINDER_HEIGHT = 5.0
-CYLINDER_RADIUS = 5.0
-
-def getReferenceParameters():
-    return [CYLINDER_HEIGHT, CYLINDER_RADIUS]
-
-
-def get_sample():
-    """
-    Returns test sample
-    """
-    global CYLINDER_HEIGHT
-    global CYLINDER_RADIUS
-    cylinder_ff = FormFactorCylinder(CYLINDER_HEIGHT, CYLINDER_RADIUS)
-    mParticle = HomogeneousMaterial("Particle", 6e-4, 2e-8)
-    cylinder = Particle(mParticle, cylinder_ff)
-    particle_layout = ParticleLayout()
-    particle_layout.addParticle(cylinder)
-    mAmbience = HomogeneousMaterial("Air", 0.0, 0.0)
-    air_layer = Layer(mAmbience)
-    air_layer.addLayout(particle_layout)
-    multi_layer = MultiLayer()
-    multi_layer.addLayer(air_layer)
-    return multi_layer
-
-
-def get_simulation():
-    """
-    Returns test simulation
-    """
-    simulation = GISASSimulation()
-    simulation.setDetectorParameters(50, 0.0*degree, 2.0*degree, 50, 0.0*degree, 2.0*degree)
-    simulation.setBeamParameters(1.0*angstrom, 0.2*degree, 0.0*degree)
-    simulation.setBeamIntensity(1e10)
-    simulation.setSample(get_sample())
-    return simulation
-
-
-def get_real_data():
-    """
-    Returns 'real' data
-    """
-    simulation = get_simulation()
-    simulation.runSimulation()
-    return simulation.result()
-
-
-def get_fit_suite(minimizer, algorithm):
-    """
-    Creates FitSuite fully ready for minimization
-    """
-    fit_suite = FitSuite()
-    fit_suite.addFitParameter("*Height", 4.*nanometer, 0.04*nanometer, Limits.limited(2.0, 8.0))
-    fit_suite.addFitParameter("*Radius", 6.*nanometer, 0.06*nanometer, Limits.limited(2.0, 8.0))
-    fit_suite.addSimulationAndRealData(get_simulation(), get_real_data().array())
-    fit_suite.setMinimizer(MinimizerFactory.createMinimizer(minimizer, algorithm))
-    return fit_suite
-
-
-def print_fit_results(fit_suite):
-    fitpars = fit_suite.getFitParameters()
-    refpars = getReferenceParameters()
-    print("-"*30)
-    print("RealTime  :", fit_suite.getMinimizer().getMinimizerName(),
-          fit_suite.getMinimizer().getAlgorithmName())
-    print("RealTime  : {0:.3f} sec".format(fit_suite.getRunTime()))
-    print("NCalls    : {0:<5d}".format(fit_suite.getNCalls()))
-    for i in range(0, fitpars.size()):
-        print('par{0:2d}     : {1:.4f} ({2:.3g}) '.format(
-            i, fitpars[0].getValue(), fitpars[i].getValue() - refpars[i]))
-
-
-def run_fit_suite(minimizer, algorithm=""):
-    fit_suite = get_fit_suite(minimizer, algorithm)
-    fit_suite.initPrint(100 )
-    fit_suite.runFit()
-    print_fit_results(fit_suite)
-    return fit_suite.getFitParameters().getValues(), getReferenceParameters()
diff --git a/Tests/Functional/Python/PyFit/testfit_GSLLMA.py b/Tests/Functional/Python/PyFit/testfit_GSLLMA.py
deleted file mode 100644
index c86cb2a2daf53f84853e942a45b3b9b4c18cd7e9..0000000000000000000000000000000000000000
--- a/Tests/Functional/Python/PyFit/testfit_GSLLMA.py
+++ /dev/null
@@ -1,22 +0,0 @@
-import sys
-import os
-import fitting_utils
-import unittest
-
-sys.path.append(os.path.abspath(
-                os.path.join(os.path.split(__file__)[0],
-                '..', '..', '..', 'lib')))
-
-from libBornAgainCore import *
-from libBornAgainFit import *
-
-
-class MinimizersTest_GSLLMA(unittest.TestCase):
-    def test_GSLLMA(self):
-        fitpars, refpars = fitting_utils.run_fit_suite("GSLLMA")
-        for i in range(0, len(fitpars)):
-            self.assertAlmostEqual(fitpars[i], refpars[i], delta=1e-3)
-
-
-if __name__ == '__main__':
-    unittest.main()
\ No newline at end of file
diff --git a/Tests/Functional/Python/PyFit/testfit_GSLMultiMin.py b/Tests/Functional/Python/PyFit/testfit_GSLMultiMin.py
deleted file mode 100644
index 85d2986403f7f6f0ae3e1e41312a8118bf55f3c9..0000000000000000000000000000000000000000
--- a/Tests/Functional/Python/PyFit/testfit_GSLMultiMin.py
+++ /dev/null
@@ -1,28 +0,0 @@
-import sys
-import os
-import fitting_utils
-import unittest
-
-sys.path.append(os.path.abspath(
-                os.path.join(os.path.split(__file__)[0],
-                '..', '..', '..', 'lib')))
-
-from libBornAgainCore import *
-from libBornAgainFit import *
-
-
-class MinimizersTest_GSLMultiMin(unittest.TestCase):
-
-    def test_GSLMultiMin_BFGS(self):
-        fitpars, refpars = fitting_utils.run_fit_suite("GSLMultiMin", "BFGS")
-        for i in range(0, len(fitpars)):
-            self.assertAlmostEqual(fitpars[i], refpars[i], delta=1e-3)
-
-    #def test_GSLMultiMin_SteepestDescent(self):
-    #    fitpars, refpars = fitting_utils.run_fit_suite("GSLMultiMin", "SteepestDescent")
-    #    for i in range(0, len(fitpars)):
-    #        self.assertAlmostEqual(fitpars[i], refpars[i], delta=1e-3)
-
-
-if __name__ == '__main__':
-    unittest.main()
\ No newline at end of file
diff --git a/Tests/Functional/Python/PyFit/testfit_GSLSimAn.py b/Tests/Functional/Python/PyFit/testfit_GSLSimAn.py
deleted file mode 100644
index 09c785c76ed2cee49b409c4681d522d598b593e6..0000000000000000000000000000000000000000
--- a/Tests/Functional/Python/PyFit/testfit_GSLSimAn.py
+++ /dev/null
@@ -1,23 +0,0 @@
-import sys
-import os
-import fitting_utils
-import unittest
-
-sys.path.append(os.path.abspath(
-                os.path.join(os.path.split(__file__)[0],
-                '..', '..', '..', 'lib')))
-
-from libBornAgainCore import *
-from libBornAgainFit import *
-
-
-class MinimizersTest_GSLSimAn(unittest.TestCase):
-
-    def test_GSLSimAn(self):
-        fitpars, refpars = fitting_utils.run_fit_suite("GSLSimAn")
-        for i in range(0, len(fitpars)):
-            self.assertAlmostEqual(fitpars[i], refpars[i], delta=0.2)
-
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/Tests/Functional/Python/PyFit/testfit_Genetic.py b/Tests/Functional/Python/PyFit/testfit_Genetic.py
deleted file mode 100644
index ec5af0533fb68f362b1fbaca0ec27ed66e886b2e..0000000000000000000000000000000000000000
--- a/Tests/Functional/Python/PyFit/testfit_Genetic.py
+++ /dev/null
@@ -1,33 +0,0 @@
-import sys
-import os
-import fitting_utils
-import unittest
-
-sys.path.append(os.path.abspath(
-                os.path.join(os.path.split(__file__)[0],
-                '..', '..', '..', 'lib')))
-
-from libBornAgainCore import *
-from libBornAgainFit import *
-
-
-
-class MinimizersTest_Genetic(unittest.TestCase):
-
-    def test_Genetic(self):
-        fit_suite = fitting_utils.get_fit_suite("Genetic","")
-        fit_suite.getMinimizer().getOptions().setMaxIterations(5)
-
-        fit_suite.initPrint(100 )
-        fit_suite.runFit()
-        fitting_utils.print_fit_results(fit_suite)
-
-        fitpars = fit_suite.getFitParameters().getValues()
-        refpars = fitting_utils.getReferenceParameters()
-
-        for i in range(0, len(fitpars)):
-            self.assertAlmostEqual(fitpars[i], refpars[i], delta=0.1)
-
-
-if __name__ == '__main__':
-    unittest.main()
\ No newline at end of file
diff --git a/Tests/Functional/Python/PyFit/testfit_Minuit2.py b/Tests/Functional/Python/PyFit/testfit_Minuit2.py
deleted file mode 100644
index 27582021820b2913612d287897adf32707526155..0000000000000000000000000000000000000000
--- a/Tests/Functional/Python/PyFit/testfit_Minuit2.py
+++ /dev/null
@@ -1,28 +0,0 @@
-import sys
-import os
-import fitting_utils
-import unittest
-
-sys.path.append(os.path.abspath(
-                os.path.join(os.path.split(__file__)[0],
-                '..', '..', '..', 'lib')))
-
-from libBornAgainCore import *
-from libBornAgainFit import *
-
-
-class MinimizersTest_Minuit2(unittest.TestCase):
-
-    def test_minuit2_migrad(self):
-        fitpars, refpars = fitting_utils.run_fit_suite("Minuit2", "Migrad")
-        for i in range(0, len(fitpars)):
-            self.assertAlmostEqual(fitpars[i], refpars[i], delta=1e-3)
-
-    def test_minuit2_fumili(self):
-        fitpars, refpars = fitting_utils.run_fit_suite("Minuit2", "Fumili")
-        for i in range(0, len(fitpars)):
-            self.assertAlmostEqual(fitpars[i], refpars[i], delta=1e-3)
-
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/Tests/Functional/Python/PyFit/testfit_UsingBuilder.py b/Tests/Functional/Python/PyFit/testfit_UsingBuilder.py
deleted file mode 100644
index fa1d762510a85d2c772e5f36410018fc24215966..0000000000000000000000000000000000000000
--- a/Tests/Functional/Python/PyFit/testfit_UsingBuilder.py
+++ /dev/null
@@ -1,158 +0,0 @@
-# functional test: fitting using sample builder
-#
-# This test shows how to use SampleBuilder class for constructing the sample
-# and running fitting.
-
-from __future__ import print_function
-import numpy as np
-import sys
-import ctypes
-import math
-
-sys.path.append("@CMAKE_LIBRARY_OUTPUT_DIRECTORY@")
-from bornagain import *
-
-# values we want to find
-cylinder_height = 5.0*nanometer
-cylinder_radius = 5.0*nanometer
-prism3_half_side = 5.0*nanometer
-prism3_height = 5.0*nanometer
-cylinder_ratio = 0.2
-
-
-def runTest():
-    """
-    run minimization using sample builder
-    """
-
-    # setting sample builder to initial values
-    sample_builder = MySampleBuilder()
-    sample_builder.setParameterValue("cylinder_height", cylinder_height)
-    sample_builder.setParameterValue("cylinder_radius", cylinder_radius)
-    sample_builder.setParameterValue("prism3_half_side", prism3_half_side)
-    sample_builder.setParameterValue("prism3_height", prism3_height)
-    sample_builder.setParameterValue("cylinder_ratio", cylinder_ratio)
-
-    simulation = createSimulation()
-    simulation.setSampleBuilder(sample_builder)
-
-    real_data = createRealData(simulation)
-
-    # setting up fitting
-    fitSuite = FitSuite()
-    fitSuite.setMinimizer("Minuit2", "Combined")
-    fitSuite.initPrint(10)
-    fitSuite.addFitParameter(
-        "*SampleBuilder/cylinder_height",  4*nanometer,  AttLimits.lowerLimited(0.01))
-    fitSuite.addFitParameter(
-        "*SampleBuilder/cylinder_radius",  6*nanometer,  AttLimits.lowerLimited(0.01))
-    fitSuite.addFitParameter(
-        "*SampleBuilder/prism3_half_side", 4*nanometer,  AttLimits.lowerLimited(0.01))
-    fitSuite.addFitParameter(
-        "*SampleBuilder/prism3_height",    6*nanometer,  AttLimits.lowerLimited(0.01))
-    fitSuite.addFitParameter(
-        "*SampleBuilder/cylinder_ratio", 0.2, AttLimits.fixed())
-
-    # chiModule = ChiSquaredModule()
-    # chiModule.setChiSquaredFunction( SquaredFunctionMeanSquaredError() )
-
-    # fitSuite.addSimulationAndRealData(simulation, real_data, chiModule)
-    fitSuite.addSimulationAndRealData(simulation, real_data)
-    fitSuite.runFit()
-
-    # analysing fit results
-    initialParameters = [ cylinder_height, cylinder_radius,
-                          prism3_half_side, prism3_height, cylinder_ratio]
-    results = fitSuite.fitParameters().values()
-    threshold = 1.0e-02
-    status = "OK"
-    for i in range(0, len(initialParameters)):
-        diff = abs(results[i] - initialParameters[i])/initialParameters[i]
-        if(diff > threshold): status = "FAILED"
-
-    return "TestFit02", "Fitting using sample builder.", status
-
-
-# create simulation
-def createSimulation():
-    simulation = GISASSimulation()
-    simulation.setDetectorParameters(50, 0.0*degree, 2.0*degree, 50, 0.0*degree, 2.0*degree)
-    simulation.setBeamParameters(1.0*angstrom, 0.2*degree, 0.0*degree)
-    simulation.setBeamIntensity(1e10);
-    return simulation
-
-
-# generating "real" data by adding noise to the simulated data
-def createRealData(simulation):
-    simulation.runSimulation()
-
-    # retrieving simulated data in the form of numpy array
-    real_data = simulation.result().array()
-
-    # spoiling simulated data with noise to produce "real" data
-    # random seed made as in FitSPheresInHexLattice_builder.py example
-    np.random.seed(0)
-    noise_factor = 0.1
-    noisy = np.random.normal(real_data, noise_factor*np.sqrt(real_data))
-    noisy[noisy < 0.1] = 0.1
-    return noisy
-
-
-# ----------------------------------------------------------------------------
-# Sample builder to build mixture of cylinders and prisms on top of substrate
-# 5 parameters
-# ----------------------------------------------------------------------------
-class MySampleBuilder(IMultiLayerBuilder):
-    def __init__(self):
-        IMultiLayerBuilder.__init__(self)
-        print("MySampleBuilder ctor")
-        self.sample = None
-        # parameters describing the sample
-        self.cylinder_height = ctypes.c_double(5.0*nanometer)
-        self.cylinder_radius = ctypes.c_double(5.0*nanometer)
-        self.prism3_half_side = ctypes.c_double(5.0*nanometer)
-        self.prism3_height = ctypes.c_double(5.0*nanometer)
-        self.cylinder_ratio = ctypes.c_double(0.2)
-        # register parameters
-        self.registerParameter("cylinder_height", ctypes.addressof(self.cylinder_height)).\
-            setUnit("nm").setNonnegative()
-        self.registerParameter("cylinder_radius", ctypes.addressof(self.cylinder_radius)).\
-            setUnit("nm").setNonnegative()
-        self.registerParameter("prism3_half_side", ctypes.addressof(self.prism3_half_side)).\
-            setUnit("nm").setNonnegative()
-        self.registerParameter("prism3_height", ctypes.addressof(self.prism3_height)).\
-            setUnit("nm").setNonnegative()
-        self.registerParameter("cylinder_ratio", ctypes.addressof(self.cylinder_ratio)).\
-            setNonnegative()
-
-    # constructs the sample for current values of parameters
-    def buildSample(self):
-        multi_layer = MultiLayer()
-        air_material = HomogeneousMaterial("Air", 0.0, 0.0)
-        substrate_material = HomogeneousMaterial("Substrate", 6e-6, 2e-8)
-        mParticle = HomogeneousMaterial("Particle", 6e-4, 2e-8)
-        air_layer = Layer(air_material)
-        substrate_layer = Layer(substrate_material)
-
-        cylinder_ff = FormFactorCylinder(self.cylinder_height.value, self.cylinder_radius.value)
-        prism_ff = FormFactorPrism3(self.prism3_height.value, self.prism3_half_side.value)
-        cylinder = Particle(mParticle, cylinder_ff)
-        prism = Particle(mParticle, prism_ff)
-        interference = InterferenceFunctionNone()
-
-        particle_layout = ParticleLayout()
-        particle_layout.addParticle(cylinder, self.cylinder_ratio.value)
-        particle_layout.addParticle(prism, 1.0 - self.cylinder_ratio.value)
-        particle_layout.setInterferenceFunction(interference)
-
-        air_layer.addLayout(particle_layout)
-        multi_layer.addLayer(air_layer)
-        multi_layer.addLayer(substrate_layer)
-        return multi_layer
-
-
-if __name__ == '__main__':
-    name, description, status = runTest()
-    print(name, description, status)
-    if "FAILED" in status:
-        exit(1)
diff --git a/Tests/Functional/Python/PyPersistence/CMakeLists.txt b/Tests/Functional/Python/PyPersistence/CMakeLists.txt
index 48f340e77a09cc06a937731f52a9f76734ba0ae0..18c2b8530fcd7f6877124ea7c5511f2c24327d2c 100644
--- a/Tests/Functional/Python/PyPersistence/CMakeLists.txt
+++ b/Tests/Functional/Python/PyPersistence/CMakeLists.txt
@@ -65,4 +65,4 @@ test_example("simulation/ex07_Miscellaneous/DepthProbe" 2e-10)
 test_example("simulation/ex07_Miscellaneous/HalfSpheresInAverageTopLayer" 2e-10)
 test_example("simulation/ex07_Miscellaneous/MagneticSpheres" 2e-10)
 
-test_example("fitting/ex01_SampleParametersIntro/SampleParametersIntro" 2e-10)
+test_example("simulation/ex07_Miscellaneous/SimulationParameters" 2e-10)
diff --git a/Tests/Functional/Python/PyStandard/CMakeLists.txt b/Tests/Functional/Python/PyStandard/CMakeLists.txt
index ece25045316541ae5c21d58e88e6aebe96ecb010..0306e430ba0a567158de3ac909a649e6a76d5dc4 100644
--- a/Tests/Functional/Python/PyStandard/CMakeLists.txt
+++ b/Tests/Functional/Python/PyStandard/CMakeLists.txt
@@ -60,6 +60,7 @@ set(test_cases
     RotatedPyramidsDistribution
     SpheresWithLimitsDistribution
     ConesWithLimitsDistribution
+    LinkedBoxDistribution
     OffSpecularResonator
     GaussianBeamFootprint
     SpecularDivergentBeam
diff --git a/Tests/Functional/TestMachinery/CMakeLists.txt b/Tests/Functional/TestMachinery/CMakeLists.txt
index ba4b66229fa85b2145b0a4a5739ef97deeadd19a..9bf0b1c4db669fed61d2b7b09667c180a74339bf 100644
--- a/Tests/Functional/TestMachinery/CMakeLists.txt
+++ b/Tests/Functional/TestMachinery/CMakeLists.txt
@@ -4,10 +4,6 @@
 
 set(library_name BornAgainTestMachinery)
 
-if(POLICY CMP0042)
-    cmake_policy(SET CMP0042 NEW)
-endif()
-
 file(GLOB source_files "*.cpp")
 file(GLOB include_files "*.h")
 
@@ -41,8 +37,3 @@ if(APPLE AND BORNAGAIN_APPLE_BUNDLE)
     set(link_flags "-Wl,-rpath,@loader_path/../../Frameworks")
     set_target_properties(${library_name} PROPERTIES LINK_FLAGS ${link_flags})
 endif()
-
-# --- installation ---------
-
-#install (TARGETS ${library_name} DESTINATION ${destination_lib} COMPONENT Libraries)
-#install (FILES ${include_files} DESTINATION ${destination_include} COMPONENT Headers)
diff --git a/Tests/Functional/TestMachinery/MinimizerTestPlan.cpp b/Tests/Functional/TestMachinery/MinimizerTestPlan.cpp
index f3edde60666cf46f99dabebeff70dd37d46c7f36..1383e2587163aaea338a59707763d9500e9f2aef 100644
--- a/Tests/Functional/TestMachinery/MinimizerTestPlan.cpp
+++ b/Tests/Functional/TestMachinery/MinimizerTestPlan.cpp
@@ -67,12 +67,16 @@ bool MinimizerTestPlan::valuesAsExpected(const std::vector<double>& values) cons
     std::ostringstream text;
     for (const auto& plan : m_parameter_plan) {
         double diff = Numeric::get_relative_difference(values[index], plan.expectedValue());
+
+        bool diff_ok(true);
         if (diff > plan.tolerance())
-            success = false;
+            diff_ok = false;
 
         text << plan.fitParameter().name() << " found:" << values[index]
              << " expected:" << plan.expectedValue() << " diff:" << diff << " "
-             << (success ? "OK" : "FAILED") << "\n";
+             << (diff_ok ? "OK" : "FAILED") << "\n";
+
+        success &= diff_ok;
 
         ++index;
     }
diff --git a/Tests/Functional/TestMachinery/StandardTestCatalogue.cpp b/Tests/Functional/TestMachinery/StandardTestCatalogue.cpp
index 529ef77b69e65fc164b286c8b7e5576c8d5fd7f3..9697d9dc102fec163ab37087d5f7bff2664aeb76 100644
--- a/Tests/Functional/TestMachinery/StandardTestCatalogue.cpp
+++ b/Tests/Functional/TestMachinery/StandardTestCatalogue.cpp
@@ -200,6 +200,12 @@ StandardTestCatalogue::StandardTestCatalogue()
         "ConesWithLimitsDistributionBuilder",
         2e-10);
 
+    add("LinkedBoxDistribution",
+        "Distribution of boxes with main parameter and two linked parameters.",
+        "MiniGISAS",
+        "LinkedBoxDistributionBuilder",
+        2e-10);
+
     // ---
 
     add("BeamDivergence",
diff --git a/Tests/ReferenceData/Core/LinkedBoxDistribution.int.gz b/Tests/ReferenceData/Core/LinkedBoxDistribution.int.gz
new file mode 100644
index 0000000000000000000000000000000000000000..72f3ae36e335feff2f23f9f24576767e03c256fe
Binary files /dev/null and b/Tests/ReferenceData/Core/LinkedBoxDistribution.int.gz differ
diff --git a/Tests/ReferenceData/Python/SampleParametersIntro.0.ref.int.gz b/Tests/ReferenceData/Python/SimulationParameters.0.ref.int.gz
similarity index 100%
rename from Tests/ReferenceData/Python/SampleParametersIntro.0.ref.int.gz
rename to Tests/ReferenceData/Python/SimulationParameters.0.ref.int.gz
diff --git a/Tests/ReferenceData/Python/SampleParametersIntro.1.ref.int.gz b/Tests/ReferenceData/Python/SimulationParameters.1.ref.int.gz
similarity index 100%
rename from Tests/ReferenceData/Python/SampleParametersIntro.1.ref.int.gz
rename to Tests/ReferenceData/Python/SimulationParameters.1.ref.int.gz
diff --git a/Tests/ReferenceData/Python/SampleParametersIntro.2.ref.int.gz b/Tests/ReferenceData/Python/SimulationParameters.2.ref.int.gz
similarity index 100%
rename from Tests/ReferenceData/Python/SampleParametersIntro.2.ref.int.gz
rename to Tests/ReferenceData/Python/SimulationParameters.2.ref.int.gz
diff --git a/Tests/ReferenceData/Python/SampleParametersIntro.3.ref.int.gz b/Tests/ReferenceData/Python/SimulationParameters.3.ref.int.gz
similarity index 100%
rename from Tests/ReferenceData/Python/SampleParametersIntro.3.ref.int.gz
rename to Tests/ReferenceData/Python/SimulationParameters.3.ref.int.gz
diff --git a/Tests/UnitTests/CMakeLists.txt b/Tests/UnitTests/CMakeLists.txt
deleted file mode 100644
index e07058eccc32d6b2096755cdc0f8215f4dbaca31..0000000000000000000000000000000000000000
--- a/Tests/UnitTests/CMakeLists.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-############################################################################
-# Unit tests
-############################################################################
-
-include(AddGTest)
-
-include_as_system_directory("${EIGEN3_INCLUDE_DIR}")
-include_directories(
-    ${CMAKE_SOURCE_DIR}/Tests/UnitTests/utilities
-    ${BornAgainCore_INCLUDE_DIRS}
-    ${Boost_INCLUDE_DIRS}
-    ${GSL_INCLUDE_DIR}
-    ${gtest_SOURCE_DIR}
-    ${gtest_SOURCE_DIR}/include
-    )
-
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGTEST_LINKED_AS_SHARED_LIBRARY=1")
-
-add_subdirectory(Core)
-add_subdirectory(Fit)
-
-if(BORNAGAIN_GUI)
-    add_subdirectory(GUI)
-endif()
-
-# to show directory in Qt creator project tree
-FILE(GLOB_RECURSE UtilityFiles "utilities/*.*")
-add_custom_target(UnitTestUtilities SOURCES ${UtilityFiles})
diff --git a/Tests/UnitTests/Core/Axes/CVectorTest.h b/Tests/UnitTests/Core/Axes/CVectorTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Axes/CVectorTest.h
rename to Tests/UnitTests/Core/Axes/CVectorTest.cpp
diff --git a/Tests/UnitTests/Core/Axes/ConstKBinAxisTest.h b/Tests/UnitTests/Core/Axes/ConstKBinAxisTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Axes/ConstKBinAxisTest.h
rename to Tests/UnitTests/Core/Axes/ConstKBinAxisTest.cpp
diff --git a/Tests/UnitTests/Core/Axes/CustomBinAxisTest.h b/Tests/UnitTests/Core/Axes/CustomBinAxisTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Axes/CustomBinAxisTest.h
rename to Tests/UnitTests/Core/Axes/CustomBinAxisTest.cpp
diff --git a/Tests/UnitTests/Core/Axes/DepthProbeConverterTest.h b/Tests/UnitTests/Core/Axes/DepthProbeConverterTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Axes/DepthProbeConverterTest.h
rename to Tests/UnitTests/Core/Axes/DepthProbeConverterTest.cpp
diff --git a/Tests/UnitTests/Core/Axes/FixedBinAxisTest.h b/Tests/UnitTests/Core/Axes/FixedBinAxisTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Axes/FixedBinAxisTest.h
rename to Tests/UnitTests/Core/Axes/FixedBinAxisTest.cpp
diff --git a/Tests/UnitTests/Core/Axes/Histogram1DTest.h b/Tests/UnitTests/Core/Axes/Histogram1DTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Axes/Histogram1DTest.h
rename to Tests/UnitTests/Core/Axes/Histogram1DTest.cpp
diff --git a/Tests/UnitTests/Core/Axes/Histogram2DTest.h b/Tests/UnitTests/Core/Axes/Histogram2DTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Axes/Histogram2DTest.h
rename to Tests/UnitTests/Core/Axes/Histogram2DTest.cpp
diff --git a/Tests/UnitTests/Core/Axes/KVectorTest.h b/Tests/UnitTests/Core/Axes/KVectorTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Axes/KVectorTest.h
rename to Tests/UnitTests/Core/Axes/KVectorTest.cpp
diff --git a/Tests/UnitTests/Core/Axes/PointwiseAxisTest.h b/Tests/UnitTests/Core/Axes/PointwiseAxisTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Axes/PointwiseAxisTest.h
rename to Tests/UnitTests/Core/Axes/PointwiseAxisTest.cpp
diff --git a/Tests/UnitTests/Core/Axes/UnitConverter1DTest.h b/Tests/UnitTests/Core/Axes/UnitConverter1DTest.cpp
similarity index 80%
rename from Tests/UnitTests/Core/Axes/UnitConverter1DTest.h
rename to Tests/UnitTests/Core/Axes/UnitConverter1DTest.cpp
index 35cbe7d0570dcdd002cb632fc342d980200cad42..91bb7135c9ac9b4b6ef4ca02485a18dce0cae731 100644
--- a/Tests/UnitTests/Core/Axes/UnitConverter1DTest.h
+++ b/Tests/UnitTests/Core/Axes/UnitConverter1DTest.cpp
@@ -106,3 +106,28 @@ TEST_F(UnitConverter1DTest, UnitConverter1DClone)
     std::unique_ptr<UnitConverter1D> converter_clone(converter.clone());
     checkMainFunctionality(*converter_clone);
 }
+
+TEST_F(UnitConverter1DTest, NonDefaultUnitsInInput)
+{
+    PointwiseAxis axis("x", std::vector<double>{0.0, 0.5, 1.0});
+
+    EXPECT_THROW(UnitConverter1D(m_beam, axis, AxesUnits::NBINS),
+                 std::runtime_error);
+
+    UnitConverter1D converter(m_beam, axis, AxesUnits::DEGREES);
+    auto axis_deg_output = converter.createConvertedAxis(0, AxesUnits::DEGREES);
+    EXPECT_TRUE(axis.size() == axis_deg_output->size());
+    EXPECT_DOUBLE_EQ(axis[0], (*axis_deg_output)[0]);
+    EXPECT_DOUBLE_EQ(axis[1], (*axis_deg_output)[1]);
+    EXPECT_DOUBLE_EQ(axis[2], (*axis_deg_output)[2]);
+
+    auto values = axis.getBinCenters();
+    std::for_each(values.begin(), values.end(), [this](double& value){value = getQ(value);});
+    PointwiseAxis q_axis("q", values);
+    UnitConverter1D converter2(m_beam, q_axis, AxesUnits::QSPACE);
+    auto axis_rad_output = converter2.createConvertedAxis(0, AxesUnits::RADIANS);
+    EXPECT_TRUE(axis.size() == axis_rad_output->size());
+    EXPECT_DOUBLE_EQ(axis[0], (*axis_rad_output)[0]);
+    EXPECT_DOUBLE_EQ(axis[1], (*axis_rad_output)[1]);
+    EXPECT_DOUBLE_EQ(axis[2], (*axis_rad_output)[2]);
+}
diff --git a/Tests/UnitTests/Core/Axes/VariableBinAxisTest.h b/Tests/UnitTests/Core/Axes/VariableBinAxisTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Axes/VariableBinAxisTest.h
rename to Tests/UnitTests/Core/Axes/VariableBinAxisTest.cpp
diff --git a/Tests/UnitTests/Core/Axes/testlist.h b/Tests/UnitTests/Core/Axes/testlist.h
deleted file mode 100644
index d957aa9830aa1ac85ad5096508fc2c273e1a2a72..0000000000000000000000000000000000000000
--- a/Tests/UnitTests/Core/Axes/testlist.h
+++ /dev/null
@@ -1,13 +0,0 @@
-// To renew this file, run /G/ba/dev-tools/code-tools/update-gtestlist.py <directory>
-
-#include "CustomBinAxisTest.h"
-#include "DepthProbeConverterTest.h"
-#include "Histogram1DTest.h"
-#include "VariableBinAxisTest.h"
-#include "Histogram2DTest.h"
-#include "KVectorTest.h"
-#include "ConstKBinAxisTest.h"
-#include "FixedBinAxisTest.h"
-#include "CVectorTest.h"
-#include "UnitConverter1DTest.h"
-#include "PointwiseAxisTest.h"
diff --git a/Tests/UnitTests/Core/CMakeLists.txt b/Tests/UnitTests/Core/CMakeLists.txt
index 4801071c1f5cd1a34e8a47c83c522ebd2894b49d..070f4f29d48bf9c08acf3b81f380f20653209a20 100644
--- a/Tests/UnitTests/Core/CMakeLists.txt
+++ b/Tests/UnitTests/Core/CMakeLists.txt
@@ -3,18 +3,13 @@
 ############################################################################
 set(test UnitTestCore)
 
-set(libs BornAgainCore)
+include_directories(${CMAKE_SOURCE_DIR}/Tests/UnitTests/utilities)
 
-ADD_GTEST(${test} "Axes" ${libs} 0)
-ADD_GTEST(${test} "Sample" ${libs} 0)
-ADD_GTEST(${test} "Fresnel" ${libs} 0)
-ADD_GTEST(${test} "Detector" ${libs} 0)
-ADD_GTEST(${test} "ExportToPython" ${libs} 0)
-ADD_GTEST(${test} "Parameters" ${libs} 0)
-ADD_GTEST(${test} "DataStructure" ${libs} 0)
-ADD_GTEST(${test} "Other" ${libs} 0)
-ADD_GTEST(${test} "SimulationElement" ${libs} 0)
-ADD_GTEST(${test} "Fitting" ${libs} 0)
-ADD_GTEST(${test} "Numeric0" ${libs} 2)
-ADD_GTEST(${test} "Numeric1" ${libs} 2)
+file(GLOB source_files "*/*.cpp" "../utilities/TestAll.cpp")
+file(GLOB include_files "*/*.h")
 
+add_executable(${test} ${source_files} ${include_files})
+target_link_libraries(${test} ${BornAgainCore_LIBRARY} gtest)
+
+# add execution of TestCore just after compilation
+add_custom_target(${test}_run ALL DEPENDS ${test} COMMAND ${test})
diff --git a/Tests/UnitTests/Core/DataStructure/ArrayUtilsTest.h b/Tests/UnitTests/Core/DataStructure/ArrayUtilsTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/DataStructure/ArrayUtilsTest.h
rename to Tests/UnitTests/Core/DataStructure/ArrayUtilsTest.cpp
diff --git a/Tests/UnitTests/Core/DataStructure/IOStrategyTest.cpp b/Tests/UnitTests/Core/DataStructure/IOStrategyTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b82fddae0ecf1ad23e3421dba39d9da674768212
--- /dev/null
+++ b/Tests/UnitTests/Core/DataStructure/IOStrategyTest.cpp
@@ -0,0 +1,80 @@
+#include "google_test.h"
+#include "FixedBinAxis.h"
+#include "OutputData.h"
+#include "OutputDataWriteStrategy.h"
+#include "OutputDataReadStrategy.h"
+
+class IOStrategyTest : public ::testing::Test
+{
+protected:
+    IOStrategyTest();
+    ~IOStrategyTest() override;
+
+    OutputData<double> m_model_data;
+};
+
+IOStrategyTest::~IOStrategyTest() = default;
+
+IOStrategyTest::IOStrategyTest()
+{
+    FixedBinAxis axis1("x", 5, 1.0, 5.0);
+    FixedBinAxis axis2("y", 10, 6.0, 7.0);
+    m_model_data.addAxis(axis1);
+    m_model_data.addAxis(axis2);
+    for(size_t i = 0, size = m_model_data.getAllocatedSize(); i < size; ++i)
+        m_model_data[i] = static_cast<double>(i);
+}
+
+TEST_F(IOStrategyTest, TestINTStrategies)
+{
+    std::stringstream ss;
+    OutputDataWriteINTStrategy write_int_strategy;
+    write_int_strategy.writeOutputData(m_model_data, ss);
+    OutputDataReadINTStrategy read_int_strategy;
+    auto result = std::unique_ptr<OutputData<double>>(read_int_strategy.readOutputData(ss));
+
+    auto compare_axis = [this, &result](size_t index) {
+        EXPECT_EQ(m_model_data.getAxis(index).size(), result->getAxis(index).size());
+        EXPECT_EQ(m_model_data.getAxis(index).getMin(), result->getAxis(index).getMin());
+        EXPECT_EQ(m_model_data.getAxis(index).getMax(), result->getAxis(index).getMax());
+    };
+
+    EXPECT_EQ(m_model_data.getRank(), result->getRank());
+    EXPECT_EQ(m_model_data.getAllSizes(), result->getAllSizes());
+    compare_axis(0);
+    compare_axis(1);
+    for (size_t i = 0, size = m_model_data.getAllocatedSize(); i < size ;++i)
+        EXPECT_EQ(m_model_data[i], (*result)[i]);
+}
+
+TEST_F(IOStrategyTest, TestNumpyTXTStrategies)
+{
+    std::stringstream ss;
+    OutputDataWriteNumpyTXTStrategy write_txt_strategy;
+    write_txt_strategy.writeOutputData(m_model_data, ss);
+
+    OutputDataReadNumpyTXTStrategy read_txt_strategy;
+    auto result = std::unique_ptr<OutputData<double>>(read_txt_strategy.readOutputData(ss));
+    EXPECT_EQ(m_model_data.getRank(), result->getRank());
+    EXPECT_EQ(m_model_data.getAllSizes(), result->getAllSizes());
+    for (size_t i = 0, size = m_model_data.getAllocatedSize(); i < size ;++i)
+        EXPECT_EQ(m_model_data[i], (*result)[i]);
+}
+
+#ifdef BORNAGAIN_TIFF_SUPPORT
+
+TEST_F(IOStrategyTest, TestTIFFStrategies)
+{
+    std::stringstream ss;
+    OutputDataWriteTiffStrategy write_tiff_strategy;
+    write_tiff_strategy.writeOutputData(m_model_data, ss);
+
+    OutputDataReadTiffStrategy read_tiff_strategy;
+    auto result = std::unique_ptr<OutputData<double>>(read_tiff_strategy.readOutputData(ss));
+    EXPECT_EQ(m_model_data.getRank(), result->getRank());
+    EXPECT_EQ(m_model_data.getAllSizes(), result->getAllSizes());
+    for (size_t i = 0, size = m_model_data.getAllocatedSize(); i < size ;++i)
+        EXPECT_EQ(m_model_data[i], (*result)[i]);
+}
+
+#endif // BORNAGAIN_TIFF_SUPPORT
diff --git a/Tests/UnitTests/Core/DataStructure/IntensityDataFunctionsTest.h b/Tests/UnitTests/Core/DataStructure/IntensityDataFunctionsTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/DataStructure/IntensityDataFunctionsTest.h
rename to Tests/UnitTests/Core/DataStructure/IntensityDataFunctionsTest.cpp
diff --git a/Tests/UnitTests/Core/DataStructure/LLDataTest.h b/Tests/UnitTests/Core/DataStructure/LLDataTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/DataStructure/LLDataTest.h
rename to Tests/UnitTests/Core/DataStructure/LLDataTest.cpp
diff --git a/Tests/UnitTests/Core/DataStructure/OutputDataIteratorTest.h b/Tests/UnitTests/Core/DataStructure/OutputDataIteratorTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/DataStructure/OutputDataIteratorTest.h
rename to Tests/UnitTests/Core/DataStructure/OutputDataIteratorTest.cpp
diff --git a/Tests/UnitTests/Core/DataStructure/OutputDataTest.h b/Tests/UnitTests/Core/DataStructure/OutputDataTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/DataStructure/OutputDataTest.h
rename to Tests/UnitTests/Core/DataStructure/OutputDataTest.cpp
diff --git a/Tests/UnitTests/Core/DataStructure/testlist.h b/Tests/UnitTests/Core/DataStructure/testlist.h
deleted file mode 100644
index abf1c0e613496ace4ca82168ad24ed4a19929552..0000000000000000000000000000000000000000
--- a/Tests/UnitTests/Core/DataStructure/testlist.h
+++ /dev/null
@@ -1,7 +0,0 @@
-// To renew this file, run /G/ba/dev-tools/code-tools/update-gtestlist.py <directory>
-
-#include "IntensityDataFunctionsTest.h"
-#include "OutputDataTest.h"
-#include "OutputDataIteratorTest.h"
-#include "LLDataTest.h"
-#include "ArrayUtilsTest.h"
diff --git a/Tests/UnitTests/Core/Detector/DetectorMaskTest.h b/Tests/UnitTests/Core/Detector/DetectorMaskTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Detector/DetectorMaskTest.h
rename to Tests/UnitTests/Core/Detector/DetectorMaskTest.cpp
diff --git a/Tests/UnitTests/Core/Detector/OffSpecularConverterTest.h b/Tests/UnitTests/Core/Detector/OffSpecularConverterTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Detector/OffSpecularConverterTest.h
rename to Tests/UnitTests/Core/Detector/OffSpecularConverterTest.cpp
diff --git a/Tests/UnitTests/Core/Detector/PolygonTest.h b/Tests/UnitTests/Core/Detector/PolygonTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Detector/PolygonTest.h
rename to Tests/UnitTests/Core/Detector/PolygonTest.cpp
diff --git a/Tests/UnitTests/Core/Detector/PrecomputedTest.h b/Tests/UnitTests/Core/Detector/PrecomputedTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Detector/PrecomputedTest.h
rename to Tests/UnitTests/Core/Detector/PrecomputedTest.cpp
diff --git a/Tests/UnitTests/Core/Detector/RectangularConverterTest.h b/Tests/UnitTests/Core/Detector/RectangularConverterTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Detector/RectangularConverterTest.h
rename to Tests/UnitTests/Core/Detector/RectangularConverterTest.cpp
diff --git a/Tests/UnitTests/Core/Detector/RectangularDetectorTest.h b/Tests/UnitTests/Core/Detector/RectangularDetectorTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Detector/RectangularDetectorTest.h
rename to Tests/UnitTests/Core/Detector/RectangularDetectorTest.cpp
diff --git a/Tests/UnitTests/Core/Detector/RegionOfInterestTest.h b/Tests/UnitTests/Core/Detector/RegionOfInterestTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Detector/RegionOfInterestTest.h
rename to Tests/UnitTests/Core/Detector/RegionOfInterestTest.cpp
diff --git a/Tests/UnitTests/Core/Detector/SimulationAreaTest.h b/Tests/UnitTests/Core/Detector/SimulationAreaTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Detector/SimulationAreaTest.h
rename to Tests/UnitTests/Core/Detector/SimulationAreaTest.cpp
diff --git a/Tests/UnitTests/Core/Detector/SpecialFunctionsTest.h b/Tests/UnitTests/Core/Detector/SpecialFunctionsTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Detector/SpecialFunctionsTest.h
rename to Tests/UnitTests/Core/Detector/SpecialFunctionsTest.cpp
diff --git a/Tests/UnitTests/Core/Detector/SpecularDetector1DTest.h b/Tests/UnitTests/Core/Detector/SpecularDetector1DTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Detector/SpecularDetector1DTest.h
rename to Tests/UnitTests/Core/Detector/SpecularDetector1DTest.cpp
diff --git a/Tests/UnitTests/Core/Detector/SphericalConverterTest.h b/Tests/UnitTests/Core/Detector/SphericalConverterTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Detector/SphericalConverterTest.h
rename to Tests/UnitTests/Core/Detector/SphericalConverterTest.cpp
diff --git a/Tests/UnitTests/Core/Detector/SphericalDetectorTest.h b/Tests/UnitTests/Core/Detector/SphericalDetectorTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Detector/SphericalDetectorTest.h
rename to Tests/UnitTests/Core/Detector/SphericalDetectorTest.cpp
diff --git a/Tests/UnitTests/Core/Detector/testlist.h b/Tests/UnitTests/Core/Detector/testlist.h
deleted file mode 100644
index 818c8115f6fb67cef957619036834c4175acb3be..0000000000000000000000000000000000000000
--- a/Tests/UnitTests/Core/Detector/testlist.h
+++ /dev/null
@@ -1,14 +0,0 @@
-// To renew this file, run ./dev-tools/code-tools/update-gtestlist.py <directory>
-
-#include "SphericalDetectorTest.h"
-#include "DetectorMaskTest.h"
-#include "PrecomputedTest.h"
-#include "RectangularDetectorTest.h"
-#include "SpecularDetector1DTest.h"
-#include "SpecialFunctionsTest.h"
-#include "RegionOfInterestTest.h"
-#include "PolygonTest.h"
-#include "SphericalConverterTest.h"
-#include "RectangularConverterTest.h"
-#include "OffSpecularConverterTest.h"
-#include "SimulationAreaTest.h"
diff --git a/Tests/UnitTests/Core/ExportToPython/PythonFormattingTest.h b/Tests/UnitTests/Core/ExportToPython/PythonFormattingTest.cpp
similarity index 91%
rename from Tests/UnitTests/Core/ExportToPython/PythonFormattingTest.h
rename to Tests/UnitTests/Core/ExportToPython/PythonFormattingTest.cpp
index b44c527d57b697da052590823b5dd00ac4c0db50..7fd2e25c9ee459bfdc7d85fa3de638d2e5321600 100644
--- a/Tests/UnitTests/Core/ExportToPython/PythonFormattingTest.h
+++ b/Tests/UnitTests/Core/ExportToPython/PythonFormattingTest.cpp
@@ -2,6 +2,7 @@
 #include "BornAgainNamespace.h"
 #include "Distributions.h"
 #include "ParameterDistribution.h"
+#include "PointwiseAxis.h"
 #include "PythonFormatting.h"
 #include "RealLimits.h"
 #include "Units.h"
@@ -111,9 +112,16 @@ TEST_F(PythonFormattingTest, printParameterDistribution)
 TEST_F(PythonFormattingTest, printAxis)
 {
     FixedBinAxis axis1("axis0", 10, -1.0, 2.0);
-    EXPECT_EQ(PythonFormatting::printAxis(axis1), "ba.FixedBinAxis(\"axis0\", 10, -1.0, 2.0)");
+    EXPECT_EQ(PythonFormatting::printAxis(axis1, "", 0), "ba.FixedBinAxis(\"axis0\", 10, -1.0, 2.0)");
 
     FixedBinAxis axis2("axis0", 10, -1.0*Units::deg, 2.0*Units::deg);
-    EXPECT_EQ(PythonFormatting::printAxis(axis2, BornAgain::UnitsRad),
+    EXPECT_EQ(PythonFormatting::printAxis(axis2, BornAgain::UnitsRad, 0),
               "ba.FixedBinAxis(\"axis0\", 10, -1.0*deg, 2.0*deg)");
+
+    PointwiseAxis axis3("axis3",
+                        std::vector<double>{1.0 * Units::deg, 2.0 * Units::deg, 3.0 * Units::deg});
+    EXPECT_EQ(PythonFormatting::printAxis(axis3, BornAgain::UnitsRad, 0),
+              "numpy.asarray([1.0*deg,\n"
+              "               2.0*deg,\n"
+              "               3.0*deg])");
 }
diff --git a/Tests/UnitTests/Core/ExportToPython/testlist.h b/Tests/UnitTests/Core/ExportToPython/testlist.h
deleted file mode 100644
index 9273387bccdbb7e7616e93a03f23fc698084c141..0000000000000000000000000000000000000000
--- a/Tests/UnitTests/Core/ExportToPython/testlist.h
+++ /dev/null
@@ -1,3 +0,0 @@
-// To renew this file, run /G/ba/dev-tools/code-tools/update-gtestlist.py <directory>
-
-#include "PythonFormattingTest.h"
diff --git a/Tests/UnitTests/Core/Fitting/FitObjectiveTest.h b/Tests/UnitTests/Core/Fitting/FitObjectiveTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Fitting/FitObjectiveTest.h
rename to Tests/UnitTests/Core/Fitting/FitObjectiveTest.cpp
diff --git a/Tests/UnitTests/Core/Fitting/FitObserverTest.h b/Tests/UnitTests/Core/Fitting/FitObserverTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Fitting/FitObserverTest.h
rename to Tests/UnitTests/Core/Fitting/FitObserverTest.cpp
diff --git a/Tests/UnitTests/Core/Fitting/SimDataPairTest.h b/Tests/UnitTests/Core/Fitting/SimDataPairTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Fitting/SimDataPairTest.h
rename to Tests/UnitTests/Core/Fitting/SimDataPairTest.cpp
diff --git a/Tests/UnitTests/Core/Fitting/testlist.h b/Tests/UnitTests/Core/Fitting/testlist.h
deleted file mode 100644
index 9499e1dcbaa71f1aa0935d910554f79f83978b1e..0000000000000000000000000000000000000000
--- a/Tests/UnitTests/Core/Fitting/testlist.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#include "SimDataPairTest.h"
-#include "FitObjectiveTest.h"
-#include "FitObserverTest.h"
-
diff --git a/Tests/UnitTests/Core/Fresnel/DepthProbeSimulationTest.h b/Tests/UnitTests/Core/Fresnel/DepthProbeSimulationTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Fresnel/DepthProbeSimulationTest.h
rename to Tests/UnitTests/Core/Fresnel/DepthProbeSimulationTest.cpp
diff --git a/Tests/UnitTests/Core/Fresnel/MatrixRTCoefficientsTest.h b/Tests/UnitTests/Core/Fresnel/MatrixRTCoefficientsTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Fresnel/MatrixRTCoefficientsTest.h
rename to Tests/UnitTests/Core/Fresnel/MatrixRTCoefficientsTest.cpp
diff --git a/Tests/UnitTests/Core/Fresnel/ScalarRTCoefficientsTest.h b/Tests/UnitTests/Core/Fresnel/ScalarRTCoefficientsTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Fresnel/ScalarRTCoefficientsTest.h
rename to Tests/UnitTests/Core/Fresnel/ScalarRTCoefficientsTest.cpp
diff --git a/Tests/UnitTests/Core/Fresnel/SpecularMagneticTest.h b/Tests/UnitTests/Core/Fresnel/SpecularMagneticTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Fresnel/SpecularMagneticTest.h
rename to Tests/UnitTests/Core/Fresnel/SpecularMagneticTest.cpp
diff --git a/Tests/UnitTests/Core/Fresnel/SpecularMatrixTest.h b/Tests/UnitTests/Core/Fresnel/SpecularMatrixTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Fresnel/SpecularMatrixTest.h
rename to Tests/UnitTests/Core/Fresnel/SpecularMatrixTest.cpp
diff --git a/Tests/UnitTests/Core/Fresnel/SpecularSimulationTest.h b/Tests/UnitTests/Core/Fresnel/SpecularSimulationTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Fresnel/SpecularSimulationTest.h
rename to Tests/UnitTests/Core/Fresnel/SpecularSimulationTest.cpp
diff --git a/Tests/UnitTests/Core/Fresnel/testlist.h b/Tests/UnitTests/Core/Fresnel/testlist.h
deleted file mode 100644
index 7a89b5700badad87a60d159b067e9487511f01c4..0000000000000000000000000000000000000000
--- a/Tests/UnitTests/Core/Fresnel/testlist.h
+++ /dev/null
@@ -1,10 +0,0 @@
-// To renew this file, run /G/ba/dev-tools/code-tools/update-gtestlist.py <directory>
-
-//#include "ScalarSpecularInfoMapTest.h"
-//#include "MatrixSpecularInfoMapTest.h"
-#include "ScalarRTCoefficientsTest.h"
-#include "MatrixRTCoefficientsTest.h"
-#include "DepthProbeSimulationTest.h"
-#include "SpecularSimulationTest.h"
-#include "SpecularMatrixTest.h"
-#include "SpecularMagneticTest.h"
diff --git a/Tests/UnitTests/Core/Numeric0/testlist.h b/Tests/UnitTests/Core/Numeric0/testlist.h
deleted file mode 100644
index 6afe17994500c147c393504aad7f593f58537e35..0000000000000000000000000000000000000000
--- a/Tests/UnitTests/Core/Numeric0/testlist.h
+++ /dev/null
@@ -1,3 +0,0 @@
-// To renew this file, run /G/ba/dev-tools/code-tools/update-gtestlist.py <directory>
-
-#include "FormFactorSpecializationTest.h"
diff --git a/Tests/UnitTests/Core/Numeric1/testlist.h b/Tests/UnitTests/Core/Numeric1/testlist.h
deleted file mode 100644
index b7b4f983c36b3deacfa81336180291946c18fd70..0000000000000000000000000000000000000000
--- a/Tests/UnitTests/Core/Numeric1/testlist.h
+++ /dev/null
@@ -1,4 +0,0 @@
-// To renew this file, run /G/ba/dev-tools/code-tools/update-gtestlist.py <directory>
-
-#include "FormFactorSymmetryTest.h"
-
diff --git a/Tests/UnitTests/Core/Other/BeamFootprintTest.h b/Tests/UnitTests/Core/Other/BeamFootprintTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Other/BeamFootprintTest.h
rename to Tests/UnitTests/Core/Other/BeamFootprintTest.cpp
diff --git a/Tests/UnitTests/Core/Other/BeamTest.h b/Tests/UnitTests/Core/Other/BeamTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Other/BeamTest.h
rename to Tests/UnitTests/Core/Other/BeamTest.cpp
diff --git a/Tests/UnitTests/Core/Other/ChiSquaredModuleTest.h b/Tests/UnitTests/Core/Other/ChiSquaredModuleTest.cpp
similarity index 66%
rename from Tests/UnitTests/Core/Other/ChiSquaredModuleTest.h
rename to Tests/UnitTests/Core/Other/ChiSquaredModuleTest.cpp
index d1b3ba6feda09bf9c9f13b955dbc466fb59b7836..4379a1706c1453c62b772212bb3ba719d7266fb2 100644
--- a/Tests/UnitTests/Core/Other/ChiSquaredModuleTest.h
+++ b/Tests/UnitTests/Core/Other/ChiSquaredModuleTest.cpp
@@ -1,7 +1,8 @@
 #include "google_test.h"
 #include "BornAgainNamespace.h"
 #include "ChiSquaredModule.h"
-#include "ISquaredFunction.h"
+#include "VarianceFunctions.h"
+#include "OutputData.h"
 
 // TODO revise test
 
@@ -20,16 +21,14 @@ ChiSquaredModuleTest::~ChiSquaredModuleTest() = default;
 
 TEST_F(ChiSquaredModuleTest, InitialState)
 {
-    EXPECT_TRUE(dynamic_cast<const SquaredFunctionDefault*>(m_chi_empty.getSquaredFunction()));
-    EXPECT_EQ(nullptr, m_chi_empty.getIntensityNormalizer());
+    EXPECT_TRUE(dynamic_cast<const VarianceSimFunction*>(m_chi_empty.varianceFunction()));
     EXPECT_EQ(nullptr, m_chi_empty.getIntensityFunction());
 }
 
 TEST_F(ChiSquaredModuleTest, CloneOfEmpty)
 {
     ChiSquaredModule* clone_of_empty = m_chi_empty.clone();
-    EXPECT_TRUE(dynamic_cast<const SquaredFunctionDefault*>(clone_of_empty->getSquaredFunction()));
-    EXPECT_EQ(nullptr, clone_of_empty->getIntensityNormalizer());
+    EXPECT_TRUE(dynamic_cast<const VarianceSimFunction*>(clone_of_empty->varianceFunction()));
     EXPECT_EQ(nullptr, clone_of_empty->getIntensityFunction());
     delete clone_of_empty;
 }
diff --git a/Tests/UnitTests/Core/Other/CumulativeValueTest.h b/Tests/UnitTests/Core/Other/CumulativeValueTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Other/CumulativeValueTest.h
rename to Tests/UnitTests/Core/Other/CumulativeValueTest.cpp
diff --git a/Tests/UnitTests/Core/Other/FileSystemUtilsTest.h b/Tests/UnitTests/Core/Other/FileSystemUtilsTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Other/FileSystemUtilsTest.h
rename to Tests/UnitTests/Core/Other/FileSystemUtilsTest.cpp
diff --git a/Tests/UnitTests/Core/Other/FourierTransformTest.h b/Tests/UnitTests/Core/Other/FourierTransformTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Other/FourierTransformTest.h
rename to Tests/UnitTests/Core/Other/FourierTransformTest.cpp
diff --git a/Tests/UnitTests/Core/Other/GISASSimulationTest.h b/Tests/UnitTests/Core/Other/GISASSimulationTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Other/GISASSimulationTest.h
rename to Tests/UnitTests/Core/Other/GISASSimulationTest.cpp
diff --git a/Tests/UnitTests/Core/Other/InstrumentTest.h b/Tests/UnitTests/Core/Other/InstrumentTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Other/InstrumentTest.h
rename to Tests/UnitTests/Core/Other/InstrumentTest.cpp
diff --git a/Tests/UnitTests/Core/Other/LayerFillLimitsTest.h b/Tests/UnitTests/Core/Other/LayerFillLimitsTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Other/LayerFillLimitsTest.h
rename to Tests/UnitTests/Core/Other/LayerFillLimitsTest.cpp
diff --git a/Tests/UnitTests/Core/Other/MaterialTest.h b/Tests/UnitTests/Core/Other/MaterialTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Other/MaterialTest.h
rename to Tests/UnitTests/Core/Other/MaterialTest.cpp
diff --git a/Tests/UnitTests/Core/Other/OrderedMapTest.h b/Tests/UnitTests/Core/Other/OrderedMapTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Other/OrderedMapTest.h
rename to Tests/UnitTests/Core/Other/OrderedMapTest.cpp
diff --git a/Tests/UnitTests/Core/Other/RelDiffTest.h b/Tests/UnitTests/Core/Other/RelDiffTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Other/RelDiffTest.h
rename to Tests/UnitTests/Core/Other/RelDiffTest.cpp
diff --git a/Tests/UnitTests/Core/Other/RotationTest.h b/Tests/UnitTests/Core/Other/RotationTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Other/RotationTest.h
rename to Tests/UnitTests/Core/Other/RotationTest.cpp
diff --git a/Tests/UnitTests/Core/Other/SampleBuilderNoteTest.h b/Tests/UnitTests/Core/Other/SampleBuilderNoteTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Other/SampleBuilderNoteTest.h
rename to Tests/UnitTests/Core/Other/SampleBuilderNoteTest.cpp
diff --git a/Tests/UnitTests/Core/Other/SampleProviderTest.h b/Tests/UnitTests/Core/Other/SampleProviderTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Other/SampleProviderTest.h
rename to Tests/UnitTests/Core/Other/SampleProviderTest.cpp
diff --git a/Tests/UnitTests/Core/Other/Shape2DTest.h b/Tests/UnitTests/Core/Other/Shape2DTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Other/Shape2DTest.h
rename to Tests/UnitTests/Core/Other/Shape2DTest.cpp
diff --git a/Tests/UnitTests/Core/Other/SimulationResultTest.h b/Tests/UnitTests/Core/Other/SimulationResultTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Other/SimulationResultTest.h
rename to Tests/UnitTests/Core/Other/SimulationResultTest.cpp
diff --git a/Tests/UnitTests/Core/Other/TRangeTest.h b/Tests/UnitTests/Core/Other/TRangeTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Other/TRangeTest.h
rename to Tests/UnitTests/Core/Other/TRangeTest.cpp
diff --git a/Tests/UnitTests/Core/Other/ThreadInfoTest.h b/Tests/UnitTests/Core/Other/ThreadInfoTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Other/ThreadInfoTest.h
rename to Tests/UnitTests/Core/Other/ThreadInfoTest.cpp
diff --git a/Tests/UnitTests/Core/Other/ZLimitsTest.h b/Tests/UnitTests/Core/Other/ZLimitsTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Other/ZLimitsTest.h
rename to Tests/UnitTests/Core/Other/ZLimitsTest.cpp
diff --git a/Tests/UnitTests/Core/Other/testlist.h b/Tests/UnitTests/Core/Other/testlist.h
deleted file mode 100644
index def09abf7d8ee0b325c207c3b91e633e73b606bf..0000000000000000000000000000000000000000
--- a/Tests/UnitTests/Core/Other/testlist.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// To renew this file, run ./dev-tools/code-tools/update-gtestlist.py <directory>
-
-#include "LayerFillLimitsTest.h"
-#include "RelDiffTest.h"
-#include "TRangeTest.h"
-#include "Shape2DTest.h"
-#include "MaterialTest.h"
-#include "GISASSimulationTest.h"
-#include "ZLimitsTest.h"
-#include "ThreadInfoTest.h"
-#include "InstrumentTest.h"
-#include "CumulativeValueTest.h"
-#include "ChiSquaredModuleTest.h"
-#include "BeamTest.h"
-#include "OrderedMapTest.h"
-#include "SampleBuilderNoteTest.h"
-#include "SampleProviderTest.h"
-#include "FourierTransformTest.h"
-#include "BeamFootprintTest.h"
-#include "FileSystemUtilsTest.h"
-#include "SimulationResultTest.h"
-#include "RotationTest.h"
-
diff --git a/Tests/UnitTests/Core/Parameters/DistributionHandlerTest.h b/Tests/UnitTests/Core/Parameters/DistributionHandlerTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Parameters/DistributionHandlerTest.h
rename to Tests/UnitTests/Core/Parameters/DistributionHandlerTest.cpp
diff --git a/Tests/UnitTests/Core/Parameters/DistributionsTest.h b/Tests/UnitTests/Core/Parameters/DistributionsTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Parameters/DistributionsTest.h
rename to Tests/UnitTests/Core/Parameters/DistributionsTest.cpp
diff --git a/Tests/UnitTests/Core/Parameters/FTDistributionsTest.h b/Tests/UnitTests/Core/Parameters/FTDistributionsTest.cpp
similarity index 99%
rename from Tests/UnitTests/Core/Parameters/FTDistributionsTest.h
rename to Tests/UnitTests/Core/Parameters/FTDistributionsTest.cpp
index 4e8d9a74c90f95ff27dd5bb422f4ec5d46756860..c8d28c04fcf8245b368c98b9e9c88cbc55868c96 100644
--- a/Tests/UnitTests/Core/Parameters/FTDistributionsTest.h
+++ b/Tests/UnitTests/Core/Parameters/FTDistributionsTest.cpp
@@ -3,6 +3,7 @@
 #include "FTDistributions1D.h"
 #include "FTDistributions2D.h"
 #include "MathConstants.h"
+#include "RealParameter.h"
 #include <memory>
 
 class FTDistributionsTest : public ::testing::Test
diff --git a/Tests/UnitTests/Core/Parameters/IParameterizedTest.h b/Tests/UnitTests/Core/Parameters/IParameterizedTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Parameters/IParameterizedTest.h
rename to Tests/UnitTests/Core/Parameters/IParameterizedTest.cpp
diff --git a/Tests/UnitTests/Core/Parameters/ParameterDistributionTest.h b/Tests/UnitTests/Core/Parameters/ParameterDistributionTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Parameters/ParameterDistributionTest.h
rename to Tests/UnitTests/Core/Parameters/ParameterDistributionTest.cpp
diff --git a/Tests/UnitTests/Core/Parameters/ParameterPatternTest.h b/Tests/UnitTests/Core/Parameters/ParameterPatternTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Parameters/ParameterPatternTest.h
rename to Tests/UnitTests/Core/Parameters/ParameterPatternTest.cpp
diff --git a/Tests/UnitTests/Core/Parameters/ParameterPoolTest.h b/Tests/UnitTests/Core/Parameters/ParameterPoolTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Parameters/ParameterPoolTest.h
rename to Tests/UnitTests/Core/Parameters/ParameterPoolTest.cpp
diff --git a/Tests/UnitTests/Core/Parameters/RealParameterTest.h b/Tests/UnitTests/Core/Parameters/RealParameterTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Parameters/RealParameterTest.h
rename to Tests/UnitTests/Core/Parameters/RealParameterTest.cpp
diff --git a/Tests/UnitTests/Core/Parameters/testlist.h b/Tests/UnitTests/Core/Parameters/testlist.h
deleted file mode 100644
index e1e8bb8b502bfe145e45f3ef1b23682e0225b94e..0000000000000000000000000000000000000000
--- a/Tests/UnitTests/Core/Parameters/testlist.h
+++ /dev/null
@@ -1,10 +0,0 @@
-// To renew this file, run /G/ba/dev-tools/code-tools/update-gtestlist.py <directory>
-
-#include "IParameterizedTest.h"
-#include "ParameterDistributionTest.h"
-#include "DistributionHandlerTest.h"
-#include "DistributionsTest.h"
-#include "FTDistributionsTest.h"
-#include "ParameterPoolTest.h"
-#include "RealParameterTest.h"
-#include "ParameterPatternTest.h"
diff --git a/Tests/UnitTests/Core/Sample/CrystalTest.h b/Tests/UnitTests/Core/Sample/CrystalTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Sample/CrystalTest.h
rename to Tests/UnitTests/Core/Sample/CrystalTest.cpp
diff --git a/Tests/UnitTests/Core/Sample/FormFactorBasicTest.h b/Tests/UnitTests/Core/Sample/FormFactorBasicTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Sample/FormFactorBasicTest.h
rename to Tests/UnitTests/Core/Sample/FormFactorBasicTest.cpp
diff --git a/Tests/UnitTests/Core/Sample/FormFactorCoherentSumTest.h b/Tests/UnitTests/Core/Sample/FormFactorCoherentSumTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Sample/FormFactorCoherentSumTest.h
rename to Tests/UnitTests/Core/Sample/FormFactorCoherentSumTest.cpp
diff --git a/Tests/UnitTests/Core/Sample/FormFactorSoftParticleTest.h b/Tests/UnitTests/Core/Sample/FormFactorSoftParticleTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Sample/FormFactorSoftParticleTest.h
rename to Tests/UnitTests/Core/Sample/FormFactorSoftParticleTest.cpp
diff --git a/Tests/UnitTests/Core/Sample/INodeTest.h b/Tests/UnitTests/Core/Sample/INodeTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Sample/INodeTest.h
rename to Tests/UnitTests/Core/Sample/INodeTest.cpp
diff --git a/Tests/UnitTests/Core/Sample/Lattice2DTest.h b/Tests/UnitTests/Core/Sample/Lattice2DTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Sample/Lattice2DTest.h
rename to Tests/UnitTests/Core/Sample/Lattice2DTest.cpp
diff --git a/Tests/UnitTests/Core/Sample/LatticeTest.h b/Tests/UnitTests/Core/Sample/LatticeTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Sample/LatticeTest.h
rename to Tests/UnitTests/Core/Sample/LatticeTest.cpp
diff --git a/Tests/UnitTests/Core/Sample/LatticeUtilsTest.h b/Tests/UnitTests/Core/Sample/LatticeUtilsTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Sample/LatticeUtilsTest.h
rename to Tests/UnitTests/Core/Sample/LatticeUtilsTest.cpp
diff --git a/Tests/UnitTests/Core/Sample/LayerInterfaceTest.h b/Tests/UnitTests/Core/Sample/LayerInterfaceTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Sample/LayerInterfaceTest.h
rename to Tests/UnitTests/Core/Sample/LayerInterfaceTest.cpp
diff --git a/Tests/UnitTests/Core/Sample/LayerRoughnessTest.h b/Tests/UnitTests/Core/Sample/LayerRoughnessTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Sample/LayerRoughnessTest.h
rename to Tests/UnitTests/Core/Sample/LayerRoughnessTest.cpp
diff --git a/Tests/UnitTests/Core/Sample/LayerTest.h b/Tests/UnitTests/Core/Sample/LayerTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Sample/LayerTest.h
rename to Tests/UnitTests/Core/Sample/LayerTest.cpp
diff --git a/Tests/UnitTests/Core/Sample/MesoCrystalTest.h b/Tests/UnitTests/Core/Sample/MesoCrystalTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Sample/MesoCrystalTest.h
rename to Tests/UnitTests/Core/Sample/MesoCrystalTest.cpp
diff --git a/Tests/UnitTests/Core/Sample/MultiLayerTest.h b/Tests/UnitTests/Core/Sample/MultiLayerTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Sample/MultiLayerTest.h
rename to Tests/UnitTests/Core/Sample/MultiLayerTest.cpp
diff --git a/Tests/UnitTests/Core/Sample/ParticleCompositionTest.h b/Tests/UnitTests/Core/Sample/ParticleCompositionTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Sample/ParticleCompositionTest.h
rename to Tests/UnitTests/Core/Sample/ParticleCompositionTest.cpp
diff --git a/Tests/UnitTests/Core/Sample/ParticleCoreShellTest.h b/Tests/UnitTests/Core/Sample/ParticleCoreShellTest.cpp
similarity index 99%
rename from Tests/UnitTests/Core/Sample/ParticleCoreShellTest.h
rename to Tests/UnitTests/Core/Sample/ParticleCoreShellTest.cpp
index 312ec38d29260764afc51498a6560439150719c2..6bb783a4c6d24a8af7f615a248928e38844b7e5a 100644
--- a/Tests/UnitTests/Core/Sample/ParticleCoreShellTest.h
+++ b/Tests/UnitTests/Core/Sample/ParticleCoreShellTest.cpp
@@ -6,6 +6,7 @@
 #include "Particle.h"
 #include "ParticleCoreShell.h"
 #include "Rotations.h"
+#include "Units.h"
 
 class ParticleCoreShellTest : public ::testing::Test
 {
diff --git a/Tests/UnitTests/Core/Sample/ParticleDistributionTest.h b/Tests/UnitTests/Core/Sample/ParticleDistributionTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Sample/ParticleDistributionTest.h
rename to Tests/UnitTests/Core/Sample/ParticleDistributionTest.cpp
diff --git a/Tests/UnitTests/Core/Sample/ParticleLayoutTest.h b/Tests/UnitTests/Core/Sample/ParticleLayoutTest.cpp
similarity index 99%
rename from Tests/UnitTests/Core/Sample/ParticleLayoutTest.h
rename to Tests/UnitTests/Core/Sample/ParticleLayoutTest.cpp
index 4538e3edd512511e6aa2c5f73ab5a8fc57157828..38281eadd2cfe4869bbd91326c1b898659131975 100644
--- a/Tests/UnitTests/Core/Sample/ParticleLayoutTest.h
+++ b/Tests/UnitTests/Core/Sample/ParticleLayoutTest.cpp
@@ -6,6 +6,8 @@
 #include "InterferenceFunctionNone.h"
 #include "ParticleLayout.h"
 #include "Particle.h"
+#include "Units.h"
+#include "MaterialFactoryFuncs.h"
 
 class ParticleLayoutTest : public ::testing::Test
 {
diff --git a/Tests/UnitTests/Core/Sample/ParticleTest.h b/Tests/UnitTests/Core/Sample/ParticleTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Sample/ParticleTest.h
rename to Tests/UnitTests/Core/Sample/ParticleTest.cpp
diff --git a/Tests/UnitTests/Core/Sample/RTTest.h b/Tests/UnitTests/Core/Sample/RTTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Sample/RTTest.h
rename to Tests/UnitTests/Core/Sample/RTTest.cpp
diff --git a/Tests/UnitTests/Core/Sample/testlist.h b/Tests/UnitTests/Core/Sample/testlist.h
deleted file mode 100644
index 87915a10116b9b512997454a1cede67b770502d0..0000000000000000000000000000000000000000
--- a/Tests/UnitTests/Core/Sample/testlist.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// To renew this file, run /G/ba/dev-tools/code-tools/update-gtestlist.py <directory>
-
-#include "FormFactorBasicTest.h"
-#include "FormFactorCoherentSumTest.h"
-#include "FormFactorSoftParticleTest.h"
-#include "LayerTest.h"
-#include "MultiLayerTest.h"
-#include "RTTest.h"
-#include "ParticleCoreShellTest.h"
-#include "LayerRoughnessTest.h"
-#include "ParticleTest.h"
-#include "ParticleCompositionTest.h"
-#include "ParticleLayoutTest.h"
-#include "LayerInterfaceTest.h"
-#include "ParticleDistributionTest.h"
-#include "CrystalTest.h"
-#include "MesoCrystalTest.h"
-#include "INodeTest.h"
-#include "Lattice2DTest.h"
-#include "LatticeTest.h"
-#include "LatticeUtilsTest.h"
-
diff --git a/Tests/UnitTests/Core/SimulationElement/DepthProbeElementTest.h b/Tests/UnitTests/Core/SimulationElement/DepthProbeElementTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/SimulationElement/DepthProbeElementTest.h
rename to Tests/UnitTests/Core/SimulationElement/DepthProbeElementTest.cpp
diff --git a/Tests/UnitTests/Core/SimulationElement/PolarizationHandlerTest.h b/Tests/UnitTests/Core/SimulationElement/PolarizationHandlerTest.cpp
similarity index 92%
rename from Tests/UnitTests/Core/SimulationElement/PolarizationHandlerTest.h
rename to Tests/UnitTests/Core/SimulationElement/PolarizationHandlerTest.cpp
index cf315d84249c2a2bb7ec0c0d345b01c8eed93679..a90f707ac7edb5544c5ea6b0580449aeb815ed1a 100644
--- a/Tests/UnitTests/Core/SimulationElement/PolarizationHandlerTest.h
+++ b/Tests/UnitTests/Core/SimulationElement/PolarizationHandlerTest.cpp
@@ -95,14 +95,10 @@ TEST_F(PolarizationHandlerTest, CopyMoveAssign)
 
     EXPECT_EQ(test_matrix, handler4.getPolarization());
     EXPECT_EQ(test_matrix, handler4.getAnalyzerOperator());
-    EXPECT_NE(test_matrix, handler.getPolarization());
-    EXPECT_NE(test_matrix, handler.getAnalyzerOperator());
 
     PolarizationHandler handler5;
     handler5 = std::move(handler2);
 
     EXPECT_EQ(test_matrix, handler5.getPolarization());
     EXPECT_EQ(test_matrix, handler5.getAnalyzerOperator());
-    EXPECT_NE(test_matrix, handler2.getPolarization());
-    EXPECT_NE(test_matrix, handler2.getAnalyzerOperator());
 }
diff --git a/Tests/UnitTests/Core/SimulationElement/SpecularSimulationElementTest.h b/Tests/UnitTests/Core/SimulationElement/SpecularSimulationElementTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/SimulationElement/SpecularSimulationElementTest.h
rename to Tests/UnitTests/Core/SimulationElement/SpecularSimulationElementTest.cpp
diff --git a/Tests/UnitTests/Core/SimulationElement/testlist.h b/Tests/UnitTests/Core/SimulationElement/testlist.h
deleted file mode 100644
index 1ba77c3674145ef3075b62d229dc438321c76555..0000000000000000000000000000000000000000
--- a/Tests/UnitTests/Core/SimulationElement/testlist.h
+++ /dev/null
@@ -1,6 +0,0 @@
-// To renew this file, run /dev-tools/code-tools/update-gtestlist.py <directory>
-// from BornAgain project directory
-
-#include "PolarizationHandler.h"
-#include "SpecularSimulationElementTest.h"
-#include "DepthProbeElementTest.h"
diff --git a/Tests/UnitTests/Fit/Kernel/AttLimitsTest.h b/Tests/UnitTests/Fit/AttLimitsTest.cpp
similarity index 100%
rename from Tests/UnitTests/Fit/Kernel/AttLimitsTest.h
rename to Tests/UnitTests/Fit/AttLimitsTest.cpp
diff --git a/Tests/UnitTests/Fit/CMakeLists.txt b/Tests/UnitTests/Fit/CMakeLists.txt
index 4cf832bfe6b88941300617b7e32a9e49c3a40ffb..2cd1c801d2a9777ece16e386986fb63e435bc140 100644
--- a/Tests/UnitTests/Fit/CMakeLists.txt
+++ b/Tests/UnitTests/Fit/CMakeLists.txt
@@ -3,7 +3,14 @@
 ############################################################################
 
 set(test UnitTestFit)
-set(libs BornAgainCore BornAgainFit)
 
-ADD_GTEST(${test} "Kernel" "${libs}" 0)
+include_directories(${CMAKE_SOURCE_DIR}/Tests/UnitTests/utilities)
 
+file(GLOB source_files "*.cpp" "../utilities/TestAll.cpp")
+file(GLOB include_files "*.h")
+
+add_executable(${test} ${source_files} ${include_files})
+target_link_libraries(${test} ${BornAgainFit_LIBRARY} gtest)
+
+# add execution of TestCore just after compilation
+add_custom_target(${test}_run ALL DEPENDS ${test} COMMAND ${test})
diff --git a/Tests/UnitTests/Fit/Kernel/FitObjectTest.h b/Tests/UnitTests/Fit/Kernel/FitObjectTest.h
deleted file mode 100644
index cea2f2a17cff813beebbf4aa5bc4ed831b11039c..0000000000000000000000000000000000000000
--- a/Tests/UnitTests/Fit/Kernel/FitObjectTest.h
+++ /dev/null
@@ -1,179 +0,0 @@
-#include "google_test.h"
-#include "BornAgainNamespace.h"
-#include "FitObject.h"
-#include "GISASSimulation.h"
-#include "Units.h"
-
-class FitObjectTest : public ::testing::Test
-{
-protected:
-    ~FitObjectTest();
-};
-
-FitObjectTest::~FitObjectTest() = default;
-
-TEST_F(FitObjectTest, StandardPair)
-{
-    const size_t nx(5), ny(4);
-    const double xmin(-1.0*Units::deg), xmax(4.0*Units::deg);
-    const double ymin(0.0*Units::deg), ymax(4.0*Units::deg);
-
-    // creating simulation and real data
-    GISASSimulation simulation;
-    simulation.setDetectorParameters(nx, xmin, xmax, ny, ymin, ymax);
-
-    OutputData<double> data;
-    // data limits made intentionally arbitrary, they will be set as in simulation
-    // on the way from SimulationResult
-    const double data_xmin(-1.0*Units::deg), data_xmax(4.0*Units::deg);
-    const double data_ymin(0.0*Units::deg), data_ymax(4.0*Units::deg);
-    data.addAxis(FixedBinAxis(BornAgain::PHI_AXIS_NAME, nx, data_xmin, data_xmax));
-    data.addAxis(FixedBinAxis(BornAgain::ALPHA_AXIS_NAME, ny, data_ymin, data_ymax));
-    double intensity(10.0);
-    data.setAllTo(intensity);
-
-    // creating fit object
-    double weight(0.5);
-    FitObject obj(simulation, data, weight);
-
-    EXPECT_EQ(obj.weight(), weight);
-    EXPECT_EQ(obj.numberOfFitElements(), size_t(nx * ny));
-
-    // access to simulation result
-    auto sim_result = obj.simulationResult();
-    EXPECT_EQ(sim_result.size(), nx*ny);
-
-    // access to experimental data
-    auto exp_data = obj.experimentalData();
-    EXPECT_EQ(exp_data.size(), nx*ny);
-
-    std::unique_ptr<OutputData<double>> retrieved_exp(exp_data.data());
-    EXPECT_EQ(retrieved_exp->getAxis(0).size(), nx);
-    EXPECT_EQ(retrieved_exp->getAxis(1).size(), ny);
-    EXPECT_DOUBLE_EQ(retrieved_exp->getAxis(0).getMin(), Units::rad2deg(xmin));
-    EXPECT_DOUBLE_EQ(retrieved_exp->getAxis(0).getMax(), Units::rad2deg(xmax));
-    EXPECT_DOUBLE_EQ(retrieved_exp->getAxis(1).getMin(), Units::rad2deg(ymin));
-    EXPECT_DOUBLE_EQ(retrieved_exp->getAxis(1).getMax(), Units::rad2deg(xmax));
-    EXPECT_EQ(retrieved_exp->totalSum(), intensity * nx * ny);
-}
-
-//! Test of the case when simulation has ROI.
-
-TEST_F(FitObjectTest, RoiPair)
-{
-    const size_t nx(5), ny(4);
-    const double xmin(-1.0*Units::deg), xmax(4.0*Units::deg);
-    const double ymin(0.0*Units::deg), ymax(4.0*Units::deg);
-
-    const double roi_xmin(0.1*Units::deg), roi_xmax(2.9*Units::deg);
-    const double roi_ymin(1.1*Units::deg), roi_ymax(3.9*Units::deg);
-    const size_t expected_roi_nx(3), expected_roi_ny(3);
-
-    const double expected_roi_xmin(0.0*Units::deg), expected_roi_xmax(3.0*Units::deg);
-    const double expected_roi_ymin(1.0*Units::deg), expected_roi_ymax(4.0*Units::deg);
-
-    // creating simulation and real data, setting ROI
-    GISASSimulation simulation;
-    simulation.setDetectorParameters(nx, xmin, xmax, ny, ymin, ymax);
-    simulation.setRegionOfInterest(roi_xmin, roi_ymin, roi_xmax, roi_ymax);
-
-    OutputData<double> data;
-    // data limits made intentionally arbitrary, they will be set as in simulation
-    // on the way from SimulationResult
-    const double data_xmin(-1.0*Units::deg), data_xmax(4.0*Units::deg);
-    const double data_ymin(0.0*Units::deg), data_ymax(4.0*Units::deg);
-    data.addAxis(FixedBinAxis(BornAgain::PHI_AXIS_NAME, nx, data_xmin, data_xmax));
-    data.addAxis(FixedBinAxis(BornAgain::ALPHA_AXIS_NAME, ny, data_ymin, data_ymax));
-    for (size_t i=0; i<data.getAllocatedSize(); ++i) {
-        data[i] = static_cast<double>(i);
-    }
-
-    // creating fit object
-    double weight(0.5);
-    FitObject obj(simulation, data, weight);
-
-    EXPECT_EQ(obj.weight(), weight);
-    EXPECT_EQ(obj.numberOfFitElements(), expected_roi_nx*expected_roi_ny);
-
-    // access to simulation result
-    auto sim_result = obj.simulationResult();
-    EXPECT_EQ(sim_result.size(), expected_roi_nx*expected_roi_ny);
-
-    // access to experimental data
-    auto exp_data = obj.experimentalData();
-    EXPECT_EQ(exp_data.size(), expected_roi_nx*expected_roi_ny);
-
-    std::unique_ptr<OutputData<double>> retrieved_exp(exp_data.data());
-    EXPECT_EQ(retrieved_exp->getAxis(0).size(), expected_roi_nx);
-    EXPECT_EQ(retrieved_exp->getAxis(1).size(), expected_roi_nx);
-    EXPECT_DOUBLE_EQ(retrieved_exp->getAxis(0).getMin(), Units::rad2deg(expected_roi_xmin));
-    EXPECT_DOUBLE_EQ(retrieved_exp->getAxis(0).getMax(), Units::rad2deg(expected_roi_xmax));
-    EXPECT_DOUBLE_EQ(retrieved_exp->getAxis(1).getMin(), Units::rad2deg(expected_roi_ymin));
-    EXPECT_DOUBLE_EQ(retrieved_exp->getAxis(1).getMax(), Units::rad2deg(expected_roi_ymax));
-
-    std::vector<double> expected_amp = {5.0, 6.0, 7.0, 9.0, 10.0, 11.0, 13.0, 14.0, 15.0};
-    EXPECT_EQ(retrieved_exp->getRawDataVector(), expected_amp);
-}
-
-//! Testing FitObject when real data already clipped to ROI.
-
-TEST_F(FitObjectTest, WhenExpDataIsClipped)
-{
-    const size_t nx(5), ny(4);
-    const double xmin(-1.0*Units::deg), xmax(4.0*Units::deg);
-    const double ymin(0.0*Units::deg), ymax(4.0*Units::deg);
-
-    const double roi_xmin(0.1*Units::deg), roi_xmax(2.9*Units::deg);
-    const double roi_ymin(1.1*Units::deg), roi_ymax(3.9*Units::deg);
-
-    const double expected_roi_xmin(0.0*Units::deg), expected_roi_xmax(3.0*Units::deg);
-    const double expected_roi_ymin(1.0*Units::deg), expected_roi_ymax(4.0*Units::deg);
-
-    // creating simulation
-    GISASSimulation simulation;
-    simulation.setDetectorParameters(nx, xmin, xmax, ny, ymin, ymax);
-    simulation.setRegionOfInterest(roi_xmin, roi_ymin, roi_xmax, roi_ymax);
-
-    // creating cropped experimental data
-    OutputData<double> data;
-    data.addAxis(FixedBinAxis(BornAgain::PHI_AXIS_NAME, 3, 42.0, 42.1));
-    data.addAxis(FixedBinAxis(BornAgain::ALPHA_AXIS_NAME, 3, 42.2, 42.3));
-
-    for (size_t i=0; i<data.getAllocatedSize(); ++i) {
-        data[i] = static_cast<double>(i);
-    }
-    std::vector<double> expectedData = data.getRawDataVector();
-
-    FitObject obj(simulation, data);
-
-    // access to experimental data
-    std::unique_ptr<OutputData<double>> retrieved_exp(obj.experimentalData().data());
-
-    EXPECT_DOUBLE_EQ(retrieved_exp->getAxis(0).getMin(), Units::rad2deg(expected_roi_xmin));
-    EXPECT_DOUBLE_EQ(retrieved_exp->getAxis(0).getMax(), Units::rad2deg(expected_roi_xmax));
-    EXPECT_DOUBLE_EQ(retrieved_exp->getAxis(1).getMin(), Units::rad2deg(expected_roi_ymin));
-    EXPECT_DOUBLE_EQ(retrieved_exp->getAxis(1).getMax(), Units::rad2deg(expected_roi_ymax));
-    EXPECT_EQ(retrieved_exp->getRawDataVector(), expectedData);
-}
-
-// Attempt to assign experimental which doesn't fit neither detector or ROI.
-
-TEST_F(FitObjectTest, AssignWrongExpData)
-{
-    const size_t nx(5), ny(4);
-    const double xmin(-1.0*Units::deg), xmax(4.0*Units::deg);
-    const double ymin(0.0*Units::deg), ymax(4.0*Units::deg);
-
-    const double roi_xmin(0.1*Units::deg), roi_xmax(2.9*Units::deg);
-    const double roi_ymin(1.1*Units::deg), roi_ymax(3.9*Units::deg);
-
-    OutputData<double> data;
-    data.addAxis(FixedBinAxis(BornAgain::PHI_AXIS_NAME, 4, 42.0, 42.1));
-    data.addAxis(FixedBinAxis(BornAgain::ALPHA_AXIS_NAME, 3, 42.2, 42.3));
-
-    GISASSimulation simulation;
-    simulation.setDetectorParameters(nx, xmin, xmax, ny, ymin, ymax);
-    simulation.setRegionOfInterest(roi_xmin, roi_ymin, roi_xmax, roi_ymax);
-
-    EXPECT_THROW(FitObject(simulation, data), std::runtime_error);
-}
diff --git a/Tests/UnitTests/Fit/Kernel/FitParameterSetTest.h b/Tests/UnitTests/Fit/Kernel/FitParameterSetTest.h
deleted file mode 100644
index 549d2f7405248e18a0dc3d5b950a49e6258eb65b..0000000000000000000000000000000000000000
--- a/Tests/UnitTests/Fit/Kernel/FitParameterSetTest.h
+++ /dev/null
@@ -1,127 +0,0 @@
-#include "google_test.h"
-#include "FitParameterSet.h"
-#include "IFitParameter.h"
-
-class FitParameterSetTest : public ::testing::Test
-{
-protected:
-    ~FitParameterSetTest();
-};
-
-FitParameterSetTest::~FitParameterSetTest() = default;
-
-TEST_F(FitParameterSetTest, addFitParameter)
-{
-    FitParameterSet parameters;
-
-    IFitParameter* par = new IFitParameter("pattern1", 1.0);
-    parameters.addFitParameter(par);
-    EXPECT_EQ(parameters.size(), 1u);
-    EXPECT_EQ(par->name(), "pattern1");
-
-    // attempt to add same fit parameter twice
-    EXPECT_THROW(parameters.addFitParameter(par), std::runtime_error);
-
-    IFitParameter* par2 = new IFitParameter("pattern2", 1.0);
-    parameters.addFitParameter(par2);
-    EXPECT_EQ(parameters.size(), 2u);
-    EXPECT_EQ(par2->name(), "pattern2");
-
-    parameters.clear();
-    EXPECT_EQ(parameters.size(), 0u);
-}
-
-TEST_F(FitParameterSetTest, getFitParameter)
-{
-    FitParameterSet parameters;
-
-    IFitParameter* par1 = new IFitParameter("pattern1", 1.0);
-    parameters.addFitParameter(par1);
-    IFitParameter* par2 = new IFitParameter("pattern2", 1.0);
-    parameters.addFitParameter(par2);
-
-    EXPECT_EQ(parameters.fitParameter("pattern1"), par1);
-    EXPECT_EQ(parameters.fitParameter("pattern2"), par2);
-    EXPECT_EQ(parameters["pattern1"], par1);
-    EXPECT_EQ(parameters["pattern2"], par2);
-    EXPECT_EQ(parameters[0], par1);
-    EXPECT_EQ(parameters[1], par2);
-
-    EXPECT_THROW(parameters.fitParameter("par3"), std::runtime_error);
-    EXPECT_THROW(parameters["par3"], std::runtime_error);
-    EXPECT_THROW(parameters[2], std::runtime_error);
-}
-
-TEST_F(FitParameterSetTest, parameterValues)
-{
-    FitParameterSet parameters;
-    parameters.addFitParameter(new IFitParameter("pattern1", 1.0));
-    parameters.addFitParameter(new IFitParameter("pattern2", 2.0));
-    parameters.addFitParameter(new IFitParameter("pattern3", 3.0));
-    std::vector<double> values{1.0, 2.0, 3.0};
-    EXPECT_EQ(parameters.values(), values);
-
-    std::vector<double> new_values{4.0, 5.0, 6.0};
-    parameters.setValues(new_values);
-    EXPECT_EQ(parameters.values(), new_values);
-
-    // are values different?
-    EXPECT_FALSE(parameters.valuesDifferFrom(new_values));
-    new_values = {4.0, 5.1, 6.0};
-    EXPECT_TRUE(parameters.valuesDifferFrom(new_values));
-
-    // attempt to set vector of wrong size
-    new_values = {4.0, 5.0, 6.0, 7.0};
-    EXPECT_THROW(parameters.setValues(new_values), std::runtime_error);
-}
-
-TEST_F(FitParameterSetTest, parameterErrors)
-{
-    FitParameterSet parameters;
-    IFitParameter* par1 = new IFitParameter("pattern1", 1.0, AttLimits::limitless(), 0.01);
-    IFitParameter* par2 = new IFitParameter("pattern2", 1.0, AttLimits::limitless(), 0.01);
-
-    parameters.addFitParameter(par1);
-    parameters.addFitParameter(par2);
-    par1->setError(1.0);
-    par2->setError(2.0);
-
-    std::vector<double> errors{1.0, 2.0};
-    EXPECT_EQ(parameters.errors(), errors);
-
-    parameters.setErrors(std::vector<double>() = {4.0, 5.0});
-    EXPECT_EQ(par1->error(), 4.0);
-    EXPECT_EQ(par2->error(), 5.0);
-}
-
-TEST_F(FitParameterSetTest, fixRelease)
-{
-    FitParameterSet parameters;
-    IFitParameter* par1 = new IFitParameter("pattern1", 1.0, AttLimits::limitless(), 0.01);
-    IFitParameter* par2 = new IFitParameter("pattern2", 1.0, AttLimits::limitless(), 0.01);
-    IFitParameter* par3 = new IFitParameter("pattern3", 1.0, AttLimits::limitless(), 0.01);
-
-    parameters.addFitParameter(par1);
-    parameters.addFitParameter(par2);
-    parameters.addFitParameter(par3);
-
-    EXPECT_EQ(parameters.freeFitParameterCount(), 3u);
-
-    par1->limits().setFixed(true);
-    EXPECT_EQ(parameters.freeFitParameterCount(), 2u);
-    par2->limits().setFixed(true);
-    EXPECT_EQ(parameters.freeFitParameterCount(), 1u);
-
-    parameters.fixAll();
-    EXPECT_EQ(parameters.freeFitParameterCount(), 0u);
-
-    parameters.releaseAll();
-    EXPECT_EQ(parameters.freeFitParameterCount(), 3u);
-
-    std::vector<std::string> names_to_fix = {"pattern1", "pattern3"};
-    parameters.setFixed(names_to_fix, true);
-    EXPECT_EQ(parameters.freeFitParameterCount(), 1u);
-    EXPECT_TRUE(par1->limits().isFixed());
-    EXPECT_FALSE(par2->limits().isFixed());
-    EXPECT_TRUE(par3->limits().isFixed());
-}
diff --git a/Tests/UnitTests/Fit/Kernel/FitParameterTest.h b/Tests/UnitTests/Fit/Kernel/FitParameterTest.h
deleted file mode 100644
index a78cb27d59e001fe49b78f40d15a116b80bd0da0..0000000000000000000000000000000000000000
--- a/Tests/UnitTests/Fit/Kernel/FitParameterTest.h
+++ /dev/null
@@ -1,251 +0,0 @@
-#include "google_test.h"
-#include "FitParameter.h"
-#include "IParameterized.h"
-#include "ParameterPool.h"
-#include "RealParameter.h"
-#include <string>
-
-class FitParameterTest : public ::testing::Test
-{
-protected:
-    ~FitParameterTest();
-};
-
-FitParameterTest::~FitParameterTest() = default;
-
-TEST_F(FitParameterTest, defaultConstructor)
-{
-    FitParameter fitParameterLinked;
-
-    EXPECT_EQ("", fitParameterLinked.name());
-    EXPECT_EQ(0.0, fitParameterLinked.value());
-    EXPECT_EQ(0.0, fitParameterLinked.step());
-    EXPECT_EQ(0.0, fitParameterLinked.error());
-
-    EXPECT_FALSE(fitParameterLinked.limits().isLowerLimited());
-    EXPECT_FALSE(fitParameterLinked.limits().isUpperLimited());
-    EXPECT_FALSE(fitParameterLinked.limits().isLimited());
-    EXPECT_FALSE(fitParameterLinked.limits().isFixed());
-}
-
-TEST_F(FitParameterTest, fullConstructor)
-{
-    AttLimits limits = AttLimits::limited(-10.0, 2.0);
-    FitParameter fitParameter("FitPL", 2.0, limits, 0.2);
-
-    EXPECT_EQ("", fitParameter.name());
-    EXPECT_EQ(2.0, fitParameter.value());
-    EXPECT_EQ(0.2, fitParameter.step());
-    EXPECT_EQ(-10.0, fitParameter.limits().lowerLimit());
-    EXPECT_EQ(2.0, fitParameter.limits().upperLimit());
-}
-
-TEST_F(FitParameterTest, addParameter)
-{
-    class ParametrizedObject : public IParameterized
-    {
-    public:
-        ParametrizedObject(double p1, double p2) : m_par1(p1), m_par2(p2)
-        {
-            registerParameter("par1", &m_par1);
-            registerParameter("par2", &m_par2);
-        }
-        virtual void onChange() final {}
-        double m_par1, m_par2;
-    };
-    ParametrizedObject obj1(1., 2.);
-    ParametrizedObject obj2(3., 4.);
-
-    const RealParameter* par11 = obj1.parameter("par1");
-    const RealParameter* par21 = obj2.parameter("par2");
-
-    FitParameter linked;
-    linked.addParameter(*par11);
-    linked.addParameter(*par21);
-
-    const double newValue(11.2);
-    linked.setValue(newValue);
-    EXPECT_EQ(linked.value(), newValue);
-
-    EXPECT_EQ(obj1.parameter("par1")->value(), newValue);
-    EXPECT_EQ(obj1.m_par1, newValue);
-    EXPECT_EQ(obj1.parameter("par2")->value(), 2.0);
-    EXPECT_EQ(obj1.m_par2, 2.0);
-
-    EXPECT_EQ(obj2.parameter("par1")->value(), 3.0);
-    EXPECT_EQ(obj2.m_par1, 3.0);
-    EXPECT_EQ(obj2.parameter("par2")->value(), newValue);
-    EXPECT_EQ(obj2.m_par2, newValue);
-}
-
-TEST_F(FitParameterTest, addMatchedParameters)
-{
-    ParameterPool pool;
-    double par1(0.0), par2(0.0), par3(0.0);
-
-    pool.addParameter(new RealParameter("/MultiLayer/Layer/Particle/height", &par1));
-    pool.addParameter(new RealParameter("/MultiLayer/Layer/Particle/width", &par2));
-    pool.addParameter(new RealParameter("/MultiLayer/Layer/thickness", &par3));
-
-    double newValue(42.0);
-    FitParameter link1("/MultiLayer/Layer/thickness", 0.0, AttLimits::limitless());
-    link1.addMatchedParameters(pool);
-    link1.setValue(newValue);
-    EXPECT_EQ(link1.value(), newValue);
-    EXPECT_EQ(par1, 0.0);
-    EXPECT_EQ(par2, 0.0);
-    EXPECT_EQ(par3, newValue);
-
-    newValue = 100.0;
-    par1 = par2 = par3 = 0.0;
-    FitParameter link2("*/Particle/*", 0.0, AttLimits::limitless());
-    link2.addMatchedParameters(pool);
-    link2.setValue(newValue);
-    EXPECT_EQ(link2.value(), newValue);
-    EXPECT_EQ(par1, newValue);
-    EXPECT_EQ(par2, newValue);
-    EXPECT_EQ(par3, 0.0);
-}
-
-TEST_F(FitParameterTest, clone)
-{
-    ParameterPool pool;
-    double par1(0.0), par2(0.0), par3(0.0);
-
-    pool.addParameter(new RealParameter("/MultiLayer/Layer/Particle/height", &par1));
-    pool.addParameter(new RealParameter("/MultiLayer/Layer/Particle/width", &par2));
-    pool.addParameter(new RealParameter("/MultiLayer/Layer/thickness", &par3));
-
-    const double value(1.0), step(0.1), lim1(0.2), lim2(10.0);
-    const std::string pattern("*/Particle/*");
-    FitParameter* link = new FitParameter(pattern, value, AttLimits::limited(lim1, lim2), step);
-    link->addMatchedParameters(pool);
-    link->setValue(value);
-    link->setName("link");
-
-    // deleting original and checking that clone is pointing to the same real parameters
-    std::unique_ptr<FitParameter> clone(link->clone());
-    delete link;
-
-    EXPECT_EQ(clone->name(), "link");
-    EXPECT_EQ(clone->value(), value);
-    EXPECT_EQ(clone->startValue(), value);
-    EXPECT_EQ(clone->step(), step);
-    EXPECT_EQ(clone->error(), 0.0);
-
-    // checking setValue for clone
-    const double newValue(42.0);
-    clone->setValue(newValue);
-    EXPECT_EQ(clone->value(), newValue);
-    EXPECT_EQ(par1, newValue);
-    EXPECT_EQ(par2, newValue);
-    EXPECT_EQ(par3, 0.0);
-}
-
-//! Tests adding of multiple patterns to a single FitParameterLinked
-
-TEST_F(FitParameterTest, addPattern)
-{
-    ParameterPool pool;
-    double par1(0.0), par2(0.0), par3(0.0), par4(0.0);
-
-    pool.addParameter(new RealParameter("/MultiLayer/Layer/Particle/height", &par1));
-    pool.addParameter(new RealParameter("/MultiLayer/Layer/Particle/width", &par2));
-    pool.addParameter(new RealParameter("/MultiLayer/Layer/thickness", &par3));
-    pool.addParameter(new RealParameter("/Something/thickness", &par4));
-
-    FitParameter* link = new FitParameter("/Something/thickness", 1.0, AttLimits::limitless());
-
-    // adding second pattern
-    link->addPattern("*/Particle/*").setName("par1");
-    EXPECT_THROW(link->addPattern("*/Particle/*"), std::runtime_error);
-    EXPECT_EQ(link->name(), std::string("par1"));
-
-    // linking with pool and cheking that corresponding parameters change their values
-    link->addMatchedParameters(pool);
-    const double newValue(42.0);
-    link->setValue(newValue);
-
-    std::vector<std::string> expected{"/Something/thickness", "/MultiLayer/Layer/Particle/height",
-                                      "/MultiLayer/Layer/Particle/width"};
-    EXPECT_EQ(link->matchedParameterNames(), expected);
-
-    EXPECT_EQ(link->value(), newValue);
-    EXPECT_EQ(par1, newValue);
-    EXPECT_EQ(par2, newValue);
-    EXPECT_EQ(par3, 0.0);
-    EXPECT_EQ(par4, newValue);
-}
-
-//! Checking repetitive match. We match parameter with the pool, change pattern, and match again.
-//! Test checks that RealParameter are not added twice.
-
-TEST_F(FitParameterTest, repetitiveMatch)
-{
-    ParameterPool pool;
-    double par1(0.0), par2(0.0), par3(0.0), par4(0.0);
-
-    pool.addParameter(new RealParameter("/MultiLayer/Layer/Particle/height", &par1));
-    pool.addParameter(new RealParameter("/MultiLayer/Layer/Particle/width", &par2));
-    pool.addParameter(new RealParameter("/MultiLayer/Layer/thickness", &par3));
-    pool.addParameter(new RealParameter("/Something/thickness", &par4));
-
-    FitParameter link("/Something/thickness", 1.0, AttLimits::limitless());
-    link.addMatchedParameters(pool);
-
-    link.addPattern("*/Particle/*");
-    link.addMatchedParameters(pool);
-
-    std::vector<std::string> expected{"/Something/thickness", "/MultiLayer/Layer/Particle/height",
-                                      "/MultiLayer/Layer/Particle/width"};
-    EXPECT_EQ(link.matchedParameterNames(), expected);
-}
-
-//! Checks if two FitParameterLinked have intersection in their fit patterns.
-
-TEST_F(FitParameterTest, patternIntersection)
-{
-    FitParameter link1;
-    link1.addPattern("pattern3").addPattern("pattern2").addPattern("pattern1");
-
-    FitParameter link2;
-    link1.addPattern("pattern4");
-
-    auto patternIntersection = link1.patternIntersection(link2);
-    EXPECT_EQ(patternIntersection.size(), 0u);
-
-    link2.addPattern("pattern1").addPattern("pattern3");
-    patternIntersection = link1.patternIntersection(link2);
-    EXPECT_EQ(patternIntersection.size(), 2u);
-    std::vector<std::string> expected{"pattern1", "pattern3"};
-    EXPECT_EQ(patternIntersection, expected);
-}
-
-//! Creating parameter pool, matching fit parameters to it and checking conflicts.
-
-TEST_F(FitParameterTest, isConflicting)
-{
-    ParameterPool pool;
-    double par1(0.0), par2(0.0), par3(0.0), par4(0.0);
-
-    pool.addParameter(new RealParameter("/MultiLayer/Layer/Particle/height", &par1));
-    pool.addParameter(new RealParameter("/MultiLayer/Layer/Particle/width", &par2));
-    pool.addParameter(new RealParameter("/MultiLayer/Layer/thickness", &par3));
-    pool.addParameter(new RealParameter("/Something/thickness", &par4));
-
-    // creating first FitParameterLink
-    FitParameter link1("*/Particle/*", 1.0, AttLimits::limitless());
-    link1.addMatchedParameters(pool);
-
-    // creating second FitParameterLink (without conflict)
-    FitParameter link2("/Something/thickness", 1.0, AttLimits::limitless());
-    link2.addMatchedParameters(pool);
-
-    EXPECT_FALSE(link1.isConflicting(link2));
-
-    // creating third conflicting FitParameterLink
-    FitParameter link3("*height", 1.0, AttLimits::limitless());
-    link3.addMatchedParameters(pool);
-
-    EXPECT_TRUE(link1.isConflicting(link3));
-}
diff --git a/Tests/UnitTests/Fit/Kernel/FitSuiteTest.h b/Tests/UnitTests/Fit/Kernel/FitSuiteTest.h
deleted file mode 100644
index 0a967ae891b683a14e7e5e52972ba1ee96312b63..0000000000000000000000000000000000000000
--- a/Tests/UnitTests/Fit/Kernel/FitSuiteTest.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#include "google_test.h"
-#include "FitSuite.h"
-#include "IFitParameter.h"
-#include "FitParameter.h"
-#include <memory>
-
-class FitSuiteTest : public ::testing::Test
-{
- protected:
-    FitSuiteTest(){}
-    ~FitSuiteTest();
-};
-
-FitSuiteTest::~FitSuiteTest() = default;
-
-TEST_F(FitSuiteTest, addFitParameter)
-{
-    std::unique_ptr<FitSuite> fitSuite(new FitSuite);
-
-    IFitParameter *par = fitSuite->addFitParameter("pattern1", 1.0);
-    EXPECT_EQ("par0", par->name());
-    EXPECT_EQ(1.0, par->value());
-    EXPECT_EQ(0.0, par->error());
-    EXPECT_EQ(0.01, par->step()); // default step invented by FitSuite
-    EXPECT_TRUE(par->limits().isLimitless());
-
-    par = fitSuite->addFitParameter("pattern2", 2.0, AttLimits::limited(10.0, 20.0), 0.02);
-    EXPECT_EQ("par1", par->name());
-    EXPECT_EQ(2.0, par->value());
-    EXPECT_EQ(0.0, par->error());
-    EXPECT_EQ(0.02, par->step());
-    EXPECT_TRUE(par->limits().isLimited());
-    EXPECT_EQ(10.0, par->limits().lowerLimit());
-    EXPECT_EQ(20.0, par->limits().upperLimit());
-
-    IFitParameter &par2 = fitSuite->addFitParameter("pattern3", 3.0)->
-            setStep(0.03).setLowerLimited(30.0);
-    EXPECT_EQ("par2", par2.name());
-    EXPECT_EQ(3.0, par2.value());
-    EXPECT_EQ(0.0, par2.error());
-    EXPECT_EQ(0.03, par2.step());
-    EXPECT_TRUE(par2.limits().isLowerLimited());
-    EXPECT_EQ(30.0, par2.limits().lowerLimit());
-
-    IFitParameter &par3 = fitSuite->addFitParameter("pattern4", 4.0)->setFixed();
-    EXPECT_EQ("par3", par3.name());
-    EXPECT_EQ(4.0, par3.value());
-    EXPECT_TRUE(par3.limits().isFixed());
-}
-
-TEST_F(FitSuiteTest, addConstructedFitParameter)
-{
-    std::unique_ptr<FitSuite> fitSuite(new FitSuite);
-
-    FitParameter par("pattern1", 1.0, AttLimits::limited(0.0, 2.0));
-
-    FitParameter *clone = fitSuite->addFitParameter(par);
-    EXPECT_EQ(clone->value(), 1.0);
-    EXPECT_EQ(clone->startValue(), 1.0);
-    EXPECT_EQ(clone->limits(), AttLimits::limited(0.0, 2.0));
-    EXPECT_EQ(clone->step(), 0.01); // step invented by FitSuite
-    EXPECT_EQ(clone->patterns(), std::vector<std::string>() = {"pattern1"});
-}
diff --git a/Tests/UnitTests/Fit/Kernel/IFitParameterTest.h b/Tests/UnitTests/Fit/Kernel/IFitParameterTest.h
deleted file mode 100644
index 6821b1e812c1588c6668978e04b078d8efe67007..0000000000000000000000000000000000000000
--- a/Tests/UnitTests/Fit/Kernel/IFitParameterTest.h
+++ /dev/null
@@ -1,120 +0,0 @@
-#include "google_test.h"
-#include "IFitParameter.h"
-#include <memory>
-
-class IFitParameterTest : public ::testing::Test
-{
-protected:
-    ~IFitParameterTest();
-};
-
-IFitParameterTest::~IFitParameterTest() = default;
-
-TEST_F(IFitParameterTest, Initial)
-{
-    IFitParameter par;
-    EXPECT_EQ(std::string(), par.name());
-    EXPECT_EQ(0.0, par.value());
-    EXPECT_EQ(0.0, par.startValue());
-    EXPECT_EQ(0.0, par.step());
-    EXPECT_EQ(0.0, par.error());
-    EXPECT_TRUE(par.limits().isLimitless());
-}
-
-TEST_F(IFitParameterTest, Constructors)
-{
-    const std::string name("name");
-    const double value(1.0);
-
-    IFitParameter par(name, value);
-    EXPECT_EQ(name, par.name());
-    EXPECT_EQ(value, par.value());
-    EXPECT_EQ(value, par.startValue());
-    EXPECT_EQ(0.0, par.step());
-    EXPECT_EQ(0.0, par.error());
-    EXPECT_TRUE(par.limits().isLimitless());
-
-    const AttLimits limits = AttLimits::limited(1.0, 2.0);
-    const double step(0.01);
-
-    IFitParameter par2(name, value, limits, step);
-    EXPECT_EQ(name, par2.name());
-    EXPECT_EQ(value, par2.value());
-    EXPECT_EQ(value, par2.startValue());
-    EXPECT_EQ(step, par2.step());
-    EXPECT_EQ(0.0, par2.error());
-    EXPECT_EQ(limits, par2.limits());
-}
-
-TEST_F(IFitParameterTest, Setters)
-{
-    const std::string name("name");
-    const double start_value(1.0);
-    const double value(2.0);
-    const AttLimits limits = AttLimits::limited(1.0, 2.0);
-    const double error(0.02);
-    const double step(0.01);
-
-    IFitParameter par(name, start_value);
-    par.setValue(value);
-
-    EXPECT_EQ(value, par.value());
-    EXPECT_EQ(start_value, par.startValue());
-
-    par.setError(error);
-    EXPECT_EQ(error, par.error());
-
-    par.setLimits(limits);
-    EXPECT_EQ(limits, par.limits());
-
-    par.setStep(step);
-    EXPECT_EQ(step, par.step());
-}
-
-TEST_F(IFitParameterTest, CompoundSetters)
-{
-    const std::string name("name");
-    const double start_value(1.0);
-    const double step(0.1);
-    const double lim1(1.0), lim2(2.0);
-
-    IFitParameter par(name, start_value);
-
-    par.setStep(step).setLowerLimited(lim1);
-    EXPECT_EQ(step, par.step());
-    EXPECT_TRUE(par.limits().isLowerLimited());
-    EXPECT_EQ(par.limits().lowerLimit(), lim1);
-    EXPECT_EQ(par.limits().upperLimit(), 0.0);
-
-    par.setStep(step).setUpperLimited(lim2);
-    EXPECT_TRUE(par.limits().isUpperLimited());
-    EXPECT_EQ(par.limits().lowerLimit(), 0.0);
-    EXPECT_EQ(par.limits().upperLimit(), lim2);
-
-    par.setStep(step).setLimited(lim1, lim2);
-    EXPECT_TRUE(par.limits().isLimited());
-    EXPECT_EQ(par.limits().lowerLimit(), lim1);
-    EXPECT_EQ(par.limits().upperLimit(), lim2);
-
-    par.setStep(step).setFixed();
-    EXPECT_TRUE(par.limits().isFixed());
-    EXPECT_EQ(par.limits().lowerLimit(), 0.0);
-    EXPECT_EQ(par.limits().upperLimit(), 0.0);
-}
-
-TEST_F(IFitParameterTest, Clone)
-{
-    const double start_value(1.0), value(2.0), error(0.1), step(0.01), lim1(10.0), lim2(10.0);
-    IFitParameter par("par1", start_value, AttLimits::limited(lim1, lim2), step);
-    par.setValue(value);
-    par.setError(error);
-    std::unique_ptr<IFitParameter> clone(par.clone());
-
-    EXPECT_EQ("par1", clone->name());
-    EXPECT_EQ(start_value, clone->startValue());
-    EXPECT_EQ(value, clone->value());
-    EXPECT_EQ(error, clone->error());
-    EXPECT_EQ(step, clone->step());
-    EXPECT_EQ(lim1, clone->limits().lowerLimit());
-    EXPECT_EQ(lim2, clone->limits().upperLimit());
-}
diff --git a/Tests/UnitTests/Fit/Kernel/testlist.h b/Tests/UnitTests/Fit/Kernel/testlist.h
deleted file mode 100644
index ddbab325cfe16e6b7195eea18883732cb69613f3..0000000000000000000000000000000000000000
--- a/Tests/UnitTests/Fit/Kernel/testlist.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// To renew this file, run /G/ba/dev-tools/code-tools/update-gtestlist.py <directory>
-
-#include "AttLimitsTest.h"
-#include "FitObjectTest.h"
-#include "IFitParameterTest.h"
-#include "FitParameterTest.h"
-#include "FitParameterSetTest.h"
-#include "FitSuiteTest.h"
-#include "MinimizerOptionsTest.h"
-#include "MultiOptionTest.h"
-#include "OptionContainerTest.h"
-#include "RealLimitsTest.h"
-#include "StringUtilsTest.h"
-#include "ParameterTest.h"
-#include "ParametersTest.h"
-
diff --git a/Tests/UnitTests/Fit/Kernel/MinimizerOptionsTest.h b/Tests/UnitTests/Fit/MinimizerOptionsTest.cpp
similarity index 100%
rename from Tests/UnitTests/Fit/Kernel/MinimizerOptionsTest.h
rename to Tests/UnitTests/Fit/MinimizerOptionsTest.cpp
diff --git a/Tests/UnitTests/Fit/Kernel/MultiOptionTest.h b/Tests/UnitTests/Fit/MultiOptionTest.cpp
similarity index 100%
rename from Tests/UnitTests/Fit/Kernel/MultiOptionTest.h
rename to Tests/UnitTests/Fit/MultiOptionTest.cpp
diff --git a/Tests/UnitTests/Fit/Kernel/OptionContainerTest.h b/Tests/UnitTests/Fit/OptionContainerTest.cpp
similarity index 100%
rename from Tests/UnitTests/Fit/Kernel/OptionContainerTest.h
rename to Tests/UnitTests/Fit/OptionContainerTest.cpp
diff --git a/Tests/UnitTests/Fit/Kernel/ParameterTest.h b/Tests/UnitTests/Fit/ParameterTest.cpp
similarity index 100%
rename from Tests/UnitTests/Fit/Kernel/ParameterTest.h
rename to Tests/UnitTests/Fit/ParameterTest.cpp
diff --git a/Tests/UnitTests/Fit/Kernel/ParametersTest.h b/Tests/UnitTests/Fit/ParametersTest.cpp
similarity index 100%
rename from Tests/UnitTests/Fit/Kernel/ParametersTest.h
rename to Tests/UnitTests/Fit/ParametersTest.cpp
diff --git a/Tests/UnitTests/Fit/Kernel/RealLimitsTest.h b/Tests/UnitTests/Fit/RealLimitsTest.cpp
similarity index 100%
rename from Tests/UnitTests/Fit/Kernel/RealLimitsTest.h
rename to Tests/UnitTests/Fit/RealLimitsTest.cpp
diff --git a/Tests/UnitTests/Fit/Kernel/StringUtilsTest.h b/Tests/UnitTests/Fit/StringUtilsTest.cpp
similarity index 100%
rename from Tests/UnitTests/Fit/Kernel/StringUtilsTest.h
rename to Tests/UnitTests/Fit/StringUtilsTest.cpp
diff --git a/Tests/UnitTests/GUI/CMakeLists.txt b/Tests/UnitTests/GUI/CMakeLists.txt
index 0f77e50f7a50712a2b951c94062e0cb858e4532d..a40e9e5d68c534bd8d36cbe728dae475878a2e79 100644
--- a/Tests/UnitTests/GUI/CMakeLists.txt
+++ b/Tests/UnitTests/GUI/CMakeLists.txt
@@ -4,25 +4,17 @@
 
 set(test UnitTestGUI)
 
-if(POLICY CMP0020)
-    cmake_policy(SET CMP0020 NEW)
-endif()
-
-if(POLICY CMP0043)
-    cmake_policy(SET CMP0043 NEW)
-endif()
-
 file(GLOB source_files "*.cpp")
 file(GLOB include_files "*.h")
 
 find_package(Qt5Core REQUIRED)
 find_package(Qt5Test REQUIRED)
 
-include_directories(${ba3d_INCLUDE_DIRS} ${BornAgainGUI_INCLUDE_DIRS})
+include_directories(${CMAKE_SOURCE_DIR}/Tests/UnitTests/utilities)
 
 set(CMAKE_AUTOMOC ON)
 add_executable(${test} ${source_files} ${include_files})
-target_link_libraries(${test} ${BornAgainGUI_LIBRARY} ${ba3d_LIBRARY} gtest)
+target_link_libraries(${test} ${BornAgainGUI_LIBRARY} gtest)
 target_link_libraries(${test} Qt5::Core Qt5::Test)
 
 # add execution of TestCore just after compilation
diff --git a/Tests/UnitTests/GUI/TestAxesItems.h b/Tests/UnitTests/GUI/TestAxesItems.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestAxesItems.h
rename to Tests/UnitTests/GUI/TestAxesItems.cpp
diff --git a/Tests/UnitTests/GUI/TestComboProperty.cpp b/Tests/UnitTests/GUI/TestComboProperty.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0da27aef57f592e72ca1b0dbf09cdc53f6c7e2f2
--- /dev/null
+++ b/Tests/UnitTests/GUI/TestComboProperty.cpp
@@ -0,0 +1,269 @@
+#include "google_test.h"
+#include "ComboProperty.h"
+#include "Comparators.h"
+#include "test_utils.h"
+
+class TestComboProperty : public ::testing::Test
+{
+public:
+    ~TestComboProperty();
+    ComboProperty propertyFromXML(const QString& buffer)
+    {
+        return TestUtils::propertyFromXML<ComboProperty>(buffer);
+    }
+};
+
+TestComboProperty::~TestComboProperty() = default;
+
+TEST_F(TestComboProperty, initialState)
+{
+    ComboProperty combo;
+    EXPECT_EQ(combo.getValue(), "");
+    EXPECT_EQ(combo.getValues(), QStringList());
+    EXPECT_EQ(combo.toolTips(), QStringList());
+    EXPECT_EQ(combo.currentIndex(), -1);
+    EXPECT_EQ(combo.stringOfValues(), "");
+    EXPECT_EQ(combo.selectedIndices(), QVector<int>());
+}
+
+TEST_F(TestComboProperty, factoryMethods)
+{
+    // initialization from list sets values only, no index selected
+    QStringList expected = QStringList() << "a1" << "a2";
+    ComboProperty combo = ComboProperty::fromList(expected);
+    EXPECT_EQ(combo.getValues(), expected);
+    EXPECT_EQ(combo.currentIndex(), -1);
+    EXPECT_EQ(combo.getValue(), "");
+    EXPECT_EQ(combo.selectedIndices(), QVector<int>());
+}
+
+TEST_F(TestComboProperty, setValues)
+{
+    // seting values through stream
+    QStringList expectedValues = QStringList() << "a1" << "a2";
+    ComboProperty combo = ComboProperty() << expectedValues;
+    EXPECT_EQ(combo.getValues(), expectedValues);
+    EXPECT_EQ(combo.getValue(), QString("a1"));
+    EXPECT_EQ(combo.currentIndex(), 0);
+    EXPECT_EQ(combo.selectedIndices(), QVector<int>({0}));
+
+    // setting values from setter, old values have to be overriden
+    QStringList newValues = QStringList() << "b1" << "b2" << "b3";
+    combo.setValues(newValues);
+    EXPECT_EQ(combo.getValue(), QString("b1"));
+    EXPECT_EQ(combo.getValues(), newValues);
+    EXPECT_EQ(combo.currentIndex(), 0);
+    EXPECT_EQ(combo.selectedIndices(), QVector<int>({0}));
+
+    // setting new/old values through setter, old value should be preserved
+    newValues = QStringList() << "c1" << "b1" << "c2";
+    combo.setValues(newValues);
+    EXPECT_EQ(combo.getValue(), QString("b1"));
+    EXPECT_EQ(combo.getValues(), newValues);
+    EXPECT_EQ(combo.currentIndex(), 1);
+    EXPECT_EQ(combo.selectedIndices(), QVector<int>({1}));
+}
+
+TEST_F(TestComboProperty, setCurrentIndex)
+{
+    ComboProperty combo;
+    EXPECT_EQ(combo.currentIndex(), -1);
+
+    combo << "c1" << "c2";
+    EXPECT_EQ(combo.currentIndex(), 0);
+    EXPECT_EQ(combo.selectedIndices(), QVector<int>({0}));
+
+    combo.setValue("c2");
+    EXPECT_EQ(combo.currentIndex(), 1);
+    EXPECT_EQ(combo.selectedIndices(), QVector<int>({1}));
+
+    combo.setCurrentIndex(0);
+    EXPECT_EQ(combo.getValue(), QString("c1"));
+    EXPECT_EQ(combo.selectedIndices(), QVector<int>({0}));
+}
+
+TEST_F(TestComboProperty, stringOfValues)
+{
+    QStringList expectedValues = QStringList() << "a1" << "a2";
+    ComboProperty combo = ComboProperty() << expectedValues;
+
+    EXPECT_EQ(combo.stringOfValues(), QString("a1;a2"));
+    EXPECT_EQ(combo.getValue(), QString("a1"));
+    EXPECT_EQ(combo.currentIndex(), 0);
+    EXPECT_EQ(combo.selectedIndices(), QVector<int>({0}));
+
+    // setting string of values, current value should change
+    QString stringOfValues("b1;b2;b3");
+    combo.setStringOfValues(stringOfValues);
+    EXPECT_EQ(combo.stringOfValues(), stringOfValues);
+    EXPECT_EQ(combo.getValue(), QString("b1"));
+    EXPECT_EQ(combo.currentIndex(), 0);
+    EXPECT_EQ(combo.selectedIndices(), QVector<int>({0}));
+
+    // setting new string of values, containing current value. Current values should remain.
+    stringOfValues = QString("c1;b1;c3");
+    combo.setStringOfValues(stringOfValues);
+    EXPECT_EQ(combo.stringOfValues(), stringOfValues);
+    EXPECT_EQ(combo.getValue(), QString("b1"));
+    EXPECT_EQ(combo.currentIndex(), 1);
+    EXPECT_EQ(combo.selectedIndices(), QVector<int>({1}));
+}
+
+TEST_F(TestComboProperty, selectedIndices)
+{
+    QStringList expectedValues = QStringList() << "a1" << "a2" << "a3";
+    ComboProperty combo = ComboProperty() << expectedValues;
+
+    EXPECT_EQ(combo.currentIndex(), 0);
+    EXPECT_EQ(combo.getValue(), "a1");
+    EXPECT_EQ(combo.selectedIndices(), QVector<int>({0}));
+    EXPECT_EQ(combo.selectedValues(), QStringList({"a1"}));
+
+    // selecting already selected element, nothing should change
+    combo.setSelected(0);
+    EXPECT_EQ(combo.currentIndex(), 0);
+    EXPECT_EQ(combo.getValue(), "a1");
+    EXPECT_EQ(combo.selectedIndices(), QVector<int>({0}));
+    EXPECT_EQ(combo.selectedValues(), QStringList({"a1"}));
+
+    // deselecting index
+    combo.setSelected(0, false);
+    EXPECT_EQ(combo.currentIndex(), -1);
+    EXPECT_EQ(combo.getValue(), "");
+    EXPECT_EQ(combo.selectedIndices(), QVector<int>());
+    EXPECT_EQ(combo.selectedValues(), QStringList());
+
+    // selecting two indeces
+    combo.setSelected(1, true);
+    combo.setSelected(2, true);
+    EXPECT_EQ(combo.currentIndex(), 1);
+    EXPECT_EQ(combo.getValue(), "a2");
+    EXPECT_EQ(combo.selectedIndices(), QVector<int>({1, 2}));
+    EXPECT_EQ(combo.selectedValues(), QStringList({"a2", "a3"}));
+
+    // selecting by name
+    combo.setSelected("a2", false);
+    combo.setSelected("a1", true);
+    EXPECT_EQ(combo.currentIndex(), 0);
+    EXPECT_EQ(combo.getValue(), "a1");
+    EXPECT_EQ(combo.selectedIndices(), QVector<int>({0, 2}));
+    EXPECT_EQ(combo.selectedValues(), QStringList({"a1", "a3"}));
+}
+
+TEST_F(TestComboProperty, stringOfSelections)
+{
+    ComboProperty combo;
+    EXPECT_EQ(combo.stringOfSelections(), "");
+
+    // checking the content of stringOfSelections
+    combo.setValues(QStringList({"a1","a2","a3"}));
+    EXPECT_EQ(combo.selectedIndices(), QVector<int>({0}));
+    EXPECT_EQ(combo.currentIndex(), 0);
+    EXPECT_EQ(combo.stringOfSelections(), "0");
+
+    combo.setSelected(2, true);
+    EXPECT_EQ(combo.selectedIndices(), QVector<int>({0, 2}));
+    EXPECT_EQ(combo.currentIndex(), 0);
+    EXPECT_EQ(combo.stringOfSelections(), "0,2");
+
+    // setting string of selections
+    combo.setStringOfSelections("");
+    EXPECT_EQ(combo.selectedIndices(), QVector<int>({}));
+    EXPECT_EQ(combo.currentIndex(), -1);
+    EXPECT_EQ(combo.stringOfSelections(), "");
+
+    combo.setStringOfSelections("1,2");
+    EXPECT_EQ(combo.selectedIndices(), QVector<int>({1, 2}));
+    EXPECT_EQ(combo.currentIndex(), 1);
+    EXPECT_EQ(combo.stringOfSelections(), "1,2");
+
+    combo.setStringOfSelections("0,42");
+    EXPECT_EQ(combo.selectedIndices(), QVector<int>({0}));
+    EXPECT_EQ(combo.currentIndex(), 0);
+    EXPECT_EQ(combo.stringOfSelections(), "0");
+}
+
+TEST_F(TestComboProperty, comboEquality)
+{
+    ComboProperty c1;
+    ComboProperty c2;
+    EXPECT_TRUE(c1 == c2);
+
+    c1 << "a1" << "a2";
+    c2 << "a1" << "a2";
+    EXPECT_TRUE(c1 == c2);
+    EXPECT_FALSE(c1 != c2);
+
+    c2 << "a3";
+    EXPECT_TRUE(c1 != c2);
+    EXPECT_FALSE(c1 == c2);
+    c2.setValue("a2");
+    EXPECT_TRUE(c1 != c2);
+    EXPECT_FALSE(c1 == c2);
+
+    c1 << "a3";
+    c1.setValue("a2");
+    EXPECT_TRUE(c1 == c2);
+    EXPECT_FALSE(c1 != c2);
+
+    // with selection indices
+    c1 = ComboProperty() << "a1" << "a2" << "a3";
+    c2 = ComboProperty() << "a1" << "a2" << "a3";
+    EXPECT_TRUE(c1 == c2);
+
+    c2.setSelected(0, false);
+    c2.setSelected(2, true);
+    EXPECT_TRUE(c1 != c2);
+
+    c1.setStringOfSelections("2");
+    c2.setStringOfSelections("2");
+    EXPECT_TRUE(c1 == c2);
+}
+
+//! Check equality of ComboPeroperty's variants.
+//! If comparators are not registered, the behavior is undefined.
+
+TEST_F(TestComboProperty, variantEquality)
+{
+    ComboProperty c1 = ComboProperty() << "a1" << "a2";
+    ComboProperty c2 = ComboProperty() << "a1" << "a2";
+
+    if (Comparators::registered()) {
+        EXPECT_TRUE(c1.variant() == c2.variant());
+
+        c2 << "a3";
+        c2.setValue("a2");
+
+        EXPECT_TRUE(c1.variant() != c2.variant());
+        EXPECT_FALSE(c1.variant() == c2.variant());
+
+        c1 << "a3";
+        c1.setValue("a2");
+
+        EXPECT_TRUE(c1.variant() == c2.variant());
+        EXPECT_FALSE(c1.variant() != c2.variant());
+
+        c1.setStringOfSelections("0");
+        c2.setStringOfSelections("1");
+        EXPECT_TRUE(c1.variant() != c2.variant());
+        EXPECT_FALSE(c1.variant() == c2.variant());
+    }
+}
+
+TEST_F(TestComboProperty, comboXML)
+{
+    // Writing combo to XML
+    ComboProperty combo = ComboProperty() << "a1" << "a2" << "a3";
+    combo.setStringOfSelections("0,2");
+
+    QString expected = "<Parameter ParType=\"ComboProperty\" ParRole=\"0\" ParValue=\"0,2\" "
+                       "ParExt=\"a1;a2;a3\"/>";
+    EXPECT_EQ(TestUtils::propertyToXML(combo), expected);
+
+    // reading from XML
+    ComboProperty combo_property = propertyFromXML(expected);
+    EXPECT_EQ(combo_property.getValue(), QString("a1"));
+    EXPECT_EQ(combo_property.stringOfValues(), QString("a1;a2;a3"));
+    EXPECT_EQ(combo_property.stringOfSelections(), QString("0,2"));
+    EXPECT_TRUE(combo_property == combo);
+}
diff --git a/Tests/UnitTests/GUI/TestComboProperty.h b/Tests/UnitTests/GUI/TestComboProperty.h
deleted file mode 100644
index 06836b4e1e4c34d83eaa3667d084cc908f610fa6..0000000000000000000000000000000000000000
--- a/Tests/UnitTests/GUI/TestComboProperty.h
+++ /dev/null
@@ -1,136 +0,0 @@
-#include "google_test.h"
-#include "ComboProperty.h"
-#include "Comparators.h"
-#include "test_utils.h"
-
-class TestComboProperty :  public ::testing::Test
-{
-public:
-    ~TestComboProperty();
-    ComboProperty propertyFromXML(const QString& buffer) {
-        return TestUtils::propertyFromXML<ComboProperty>(buffer);
-    }
-
-};
-
-TestComboProperty::~TestComboProperty() = default;
-
-TEST_F(TestComboProperty, test_ComboEquality)
-{
-    EXPECT_EQ(1, 1);
-        ComboProperty c1;
-        ComboProperty c2;
-        EXPECT_TRUE(c1 == c2);
-
-        c1 << "a1" << "a2";
-        c2 << "a1" << "a2";
-        EXPECT_TRUE(c1 == c2);
-
-        c2 << "a3";
-        EXPECT_TRUE(c1 != c2);
-        c2.setValue("a2");
-        EXPECT_TRUE(c1 != c2);
-
-        c1 << "a3";
-        c1.setValue("a2");
-        EXPECT_TRUE(c1 == c2);
-}
-
-//! Check equality of ComboPeroperty's variants.
-//! If comparators are not registered, the behavior is undefined.
-
-TEST_F(TestComboProperty, test_VariantEquality)
-{
-    QVariant v1(1.0);
-    QVariant v2(2.0);
-    QVariant v3(2.0);
-    EXPECT_TRUE(v1 != v2);
-    EXPECT_TRUE(v2 == v3);
-
-    ComboProperty c1 = ComboProperty() << "a1" << "a2";
-    ComboProperty c2 = ComboProperty() << "a1" << "a2";
-
-    if (Comparators::registered()) {
-        EXPECT_TRUE(c1.variant() == c2.variant());
-
-        c2 << "a3";
-        c2.setValue("a2");
-
-        EXPECT_TRUE(c1.variant() != c2.variant());
-        EXPECT_FALSE(c1.variant() == c2.variant());
-
-        c1 << "a3";
-        c1.setValue("a2");
-
-        EXPECT_TRUE(c1.variant() == c2.variant());
-        EXPECT_FALSE(c1.variant() != c2.variant());
-    }
-}
-
-TEST_F(TestComboProperty, test_setValue)
-{
-    QStringList expectedValues = QStringList() << "a1" << "a2";
-    ComboProperty combo = ComboProperty() << expectedValues;
-
-    EXPECT_EQ(combo.getValue(), QString("a1"));
-
-    QStringList newValues = QStringList() << "b1" << "b2" << "b3";
-    combo.setValues(newValues);
-    EXPECT_EQ(combo.getValue(), QString("b1"));
-    EXPECT_EQ(combo.getValues(), newValues);
-
-    // checking that old value is preserved
-    newValues = QStringList() << "c1" << "b1" << "c2";
-    combo.setValues(newValues);
-    EXPECT_EQ(combo.getValue(), QString("b1"));
-    EXPECT_EQ(combo.getValues(), newValues);
-}
-
-TEST_F(TestComboProperty, test_currentIndex)
-{
-    ComboProperty combo;
-    EXPECT_EQ(combo.currentIndex(), -1);
-    combo << "c1" << "c2";
-    EXPECT_EQ(combo.currentIndex(), 0);
-    combo.setValue("c2");
-    EXPECT_EQ(combo.currentIndex(), 1);
-
-    combo.setCurrentIndex(0);
-    EXPECT_EQ(combo.getValue(), QString("c1"));
-}
-
-TEST_F(TestComboProperty, test_stringOfValues)
-{
-    QStringList expectedValues = QStringList() << "a1" << "a2";
-    ComboProperty combo = ComboProperty() << expectedValues;
-
-    EXPECT_EQ(combo.stringOfValues(), QString("a1;a2"));
-
-    // setting string of values, current value should change
-    QString stringOfValues("b1;b2;b3");
-    combo.setStringOfValues(stringOfValues);
-    EXPECT_EQ(combo.stringOfValues(), stringOfValues);
-    EXPECT_EQ(combo.getValue(), QString("b1"));
-
-    // setting new string of values, containing current value. Current values should remain.
-    stringOfValues = QString("c1;b1;c3");
-    combo.setStringOfValues(stringOfValues);
-    EXPECT_EQ(combo.stringOfValues(), stringOfValues);
-    EXPECT_EQ(combo.getValue(), QString("b1"));
-}
-
-TEST_F(TestComboProperty, test_comboXML)
-{
-    // Writing combo to XML
-    ComboProperty combo = ComboProperty() << "a1" << "a2" << "a3";
-
-    QString expected = "<Parameter ParType=\"ComboProperty\" ParRole=\"0\" ParValue=\"0\" "
-                       "ParExt=\"a1;a2;a3\"/>";
-    EXPECT_EQ(TestUtils::propertyToXML(combo), expected);
-
-    // reading from XML
-    ComboProperty combo_property = propertyFromXML(expected);
-    EXPECT_EQ(combo_property.getValue(), QString("a1"));
-    EXPECT_EQ(combo_property.stringOfValues(), QString("a1;a2;a3"));
-    EXPECT_TRUE(combo_property == combo);
-}
diff --git a/Tests/UnitTests/GUI/TestComponentProxyModel.h b/Tests/UnitTests/GUI/TestComponentProxyModel.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestComponentProxyModel.h
rename to Tests/UnitTests/GUI/TestComponentProxyModel.cpp
diff --git a/Tests/UnitTests/GUI/TestComponentUtils.h b/Tests/UnitTests/GUI/TestComponentUtils.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestComponentUtils.h
rename to Tests/UnitTests/GUI/TestComponentUtils.cpp
diff --git a/Tests/UnitTests/GUI/TestCsvImportAssistant.cpp b/Tests/UnitTests/GUI/TestCsvImportAssistant.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dd779d385497af9f0eb2fa709e7b8534dc3aafce
--- /dev/null
+++ b/Tests/UnitTests/GUI/TestCsvImportAssistant.cpp
@@ -0,0 +1,105 @@
+#include "ArrayUtils.h"
+#include "AxisNames.h"
+#include "CsvImportAssistant.h"
+#include "JobItemUtils.h"
+#include "OutputDataReadFactory.h"
+#include "OutputDataWriteFactory.h"
+#include "SpecularDataItem.h"
+#include "google_test.h"
+#include <vector>
+
+class TestCsvImportAssistant : public ::testing::Test
+{
+protected:
+    ~TestCsvImportAssistant();
+
+    const std::string m_testFilename = "tmp_TestCsvImportAssistant.txt";
+    const std::vector<std::vector<double>> m_testVector = {
+        {0.0, 1.0, 2.0, 3.0},     {4.0, 5.0, 6.0, 7.0},     {8.0, 9.0, 10.0, 11.0},
+        {12.0, 13.0, 14.0, 15.0}, {16.0, 17.0, 18.0, 19.0}, {20.0, 21.0, 22.0, 23.0}};
+
+    const QString testFilename() { return QString::fromStdString(m_testFilename); }
+
+    void writeTestFile()
+    {
+        remove(m_testFilename.c_str());
+        OutputDataWriter* writer = OutputDataWriteFactory::getWriter(m_testFilename);
+        OutputData<double>* data = ArrayUtils::createData2D(m_testVector).release();
+        writer->writeOutputData(*data);
+    }
+
+    void writeTestFile(size_t nRows, size_t nCols)
+    {
+        remove(m_testFilename.c_str());
+        std::ofstream myfile;
+        myfile.open(m_testFilename);
+        for (size_t i = 0; i < nRows; i++) {
+            for (size_t j = 0; j < nCols; j++) {
+                myfile << nCols * i + j << " ";
+            }
+            myfile << "\n";
+        }
+        myfile.close();
+    }
+
+    OutputData<double>* readTestFile()
+    {
+        OutputDataReader* reader = OutputDataReadFactory::getReader(m_testFilename);
+        OutputData<double>* data = reader->getOutputData();
+        return data;
+    }
+};
+
+TestCsvImportAssistant::~TestCsvImportAssistant() = default;
+
+//! Testing component items of particle item.
+TEST_F(TestCsvImportAssistant, test_readFile)
+{
+    /*
+     * The file to read looks like this ['-' symbols added to clarify what is going on].
+     * It has originaly ten columns, not four (The separator is a space).
+     * When the separator is a space, repeated spaces will be merged into one.
+     * Thus, the ImportAssistant will read this file as a four-column file.
+    # - BornAgain - Intensity - Data -  -  -  -  -  -  -
+    # - Simple - 2D - array - suitable - for - numpy, - matlab - etc. -  -
+    # - [nrows=6, - ncols=4] -  -  -  -  -  -  -  -
+    0.000000000000e+00 -  -  -  - 1.000000000000e+00 -  -  -  - 2.000000000000e+00 -
+    3.000000000000e+00 -
+    4.000000000000e+00 -  -  -  - 5.000000000000e+00 -  -  -  - 6.000000000000e+00 -
+    7.000000000000e+00 -
+    8.000000000000e+00 -  -  -  - 9.000000000000e+00 -  -  -  - 1.000000000000e+01 -
+    1.100000000000e+01 -
+    1.200000000000e+01 -  -  -  - 1.300000000000e+01 -  -  -  - 1.400000000000e+01 -
+    1.500000000000e+01 -
+    1.600000000000e+01 -  -  -  - 1.700000000000e+01 -  -  -  - 1.800000000000e+01 -
+    1.900000000000e+01 -
+    2.000000000000e+01 -  -  -  - 2.100000000000e+01 -  -  -  - 2.200000000000e+01 -
+    2.300000000000e+01 -
+    Number of Columns: 10
+    Separator: >>> <<<
+    */
+    writeTestFile();
+
+    CsvImportAssistant assistant(testFilename());
+
+    assistant.setIntensityColumn(1);
+    assistant.setCoordinateColumn(3, AxesUnits::DEGREES);
+    assistant.setFirstRow(5);
+    assistant.setLastRow(7);
+
+    auto DataRank = assistant.getData().dataRank();
+    auto AllocSize = assistant.getData().intensityData()->getAllocatedSize();
+    auto RawDataVec = assistant.getData().intensityData()->getRawDataVector();
+    auto UnitsLabel = assistant.getData().unitsLabel();
+    auto AxisLabel0 = assistant.getData().axisLabel(0);
+    auto AxisLabel1 = assistant.getData().axisLabel(1);
+
+    const std::vector<double> expected = {4.0, 8.0, 12.0};
+
+    EXPECT_EQ(DataRank, 1u);
+    EXPECT_EQ(AllocSize, 3u);
+    EXPECT_EQ(RawDataVec, expected);
+    EXPECT_EQ(UnitsLabel, JobItemUtils::nameFromAxesUnits(AxesUnits::DEGREES));
+    EXPECT_EQ(AxisLabel0, QString::fromStdString(AxisNames::InitSpecAxis()[AxesUnits::DEGREES]));
+    EXPECT_EQ(AxisLabel1, SpecularDataAxesNames::y_axis_default_name);
+}
diff --git a/Tests/UnitTests/GUI/TestDataItemViews.h b/Tests/UnitTests/GUI/TestDataItemViews.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestDataItemViews.h
rename to Tests/UnitTests/GUI/TestDataItemViews.cpp
diff --git a/Tests/UnitTests/GUI/TestDataItems.h b/Tests/UnitTests/GUI/TestDataItems.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestDataItems.h
rename to Tests/UnitTests/GUI/TestDataItems.cpp
diff --git a/Tests/UnitTests/GUI/TestDetectorItems.h b/Tests/UnitTests/GUI/TestDetectorItems.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestDetectorItems.h
rename to Tests/UnitTests/GUI/TestDetectorItems.cpp
diff --git a/Tests/UnitTests/GUI/TestExternalProperty.h b/Tests/UnitTests/GUI/TestExternalProperty.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestExternalProperty.h
rename to Tests/UnitTests/GUI/TestExternalProperty.cpp
diff --git a/Tests/UnitTests/GUI/TestFTDistributionItems.h b/Tests/UnitTests/GUI/TestFTDistributionItems.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestFTDistributionItems.h
rename to Tests/UnitTests/GUI/TestFTDistributionItems.cpp
diff --git a/Tests/UnitTests/GUI/TestFitParameterModel.h b/Tests/UnitTests/GUI/TestFitParameterModel.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestFitParameterModel.h
rename to Tests/UnitTests/GUI/TestFitParameterModel.cpp
diff --git a/Tests/UnitTests/GUI/TestFormFactorItems.h b/Tests/UnitTests/GUI/TestFormFactorItems.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestFormFactorItems.h
rename to Tests/UnitTests/GUI/TestFormFactorItems.cpp
diff --git a/Tests/UnitTests/GUI/TestGUI.cpp b/Tests/UnitTests/GUI/TestGUI.cpp
index 035ddc97c671867790735546d33f16dcebdce58f..c4123e504fcb5e4192de110fec5fc83b19bb5d06 100644
--- a/Tests/UnitTests/GUI/TestGUI.cpp
+++ b/Tests/UnitTests/GUI/TestGUI.cpp
@@ -1,62 +1,15 @@
 #include "google_test.h"
-#include <QString>
 #include <QCoreApplication>
 #include <QAbstractItemModel>
 #include "Comparators.h"
 
-#include "TestComboProperty.h"
-#include "TestComponentProxyModel.h"
-#include "TestComponentUtils.h"
-#include "TestDataItems.h"
-#include "TestDataItemViews.h"
-#include "TestDetectorItems.h"
-#include "TestExternalProperty.h"
-#include "TestFitParameterModel.h"
-#include "TestFormFactorItems.h"
-#include "TestFTDistributionItems.h"
-#include "TestGroupItem.h"
-#include "TestGUICoreObjectCorrespondence.h"
-#include "TestGUIHelpers.h"
-#include "TestLayerItems.h"
-#include "TestLayerRoughnessItems.h"
-#include "TestLinkInstrument.h"
-#include "TestMapperCases.h"
-#include "TestMapperForItem.h"
-#include "TestMaterialModel.h"
-#include "TestMaterialPropertyController.h"
-#include "TestModelUtils.h"
-#include "TestOutputDataIOService.h"
-#include "TestParaCrystalItems.h"
-#include "TestParameterTreeUtils.h"
-#include "TestParticleCoreShell.h"
-#include "TestParticleDistributionItem.h"
-#include "TestParticleItem.h"
-#include "TestProjectDocument.h"
-#include "TestProjectUtils.h"
-#include "TestPropertyRepeater.h"
-#include "TestProxyModelStrategy.h"
-#include "TestRealSpaceBuilderUtils.h"
-#include "TestSaveService.h"
-#include "TestSessionItemController.h"
-#include "TestSessionItem.h"
-#include "TestSessionItemUtils.h"
-#include "TestSessionModel.h"
-#include "TestSessionXML.h"
-#include "TestTranslations.h"
-#include "TestUpdateTimer.h"
-#include "TestSessionItemData.h"
-#include "TestSessionItemTags.h"
-#include "TestMessageService.h"
-#include "TestParticleLayoutItem.h"
-#include "TestAxesItems.h"
-#include "TestMultiLayerItem.h"
-
 int main(int argc, char** argv) {
     QCoreApplication app(argc, argv);
     Q_UNUSED(app);
 
     Comparators::registerComparators();
     qRegisterMetaType<QAbstractItemModel::LayoutChangeHint>("LayoutChangeHint");
+    qRegisterMetaType<QList<QPersistentModelIndex>>("QList<QPersistentModelIndex>");
 
     ::testing::InitGoogleTest(&argc, argv);
 
diff --git a/Tests/UnitTests/GUI/TestGUICoreObjectCorrespondence.h b/Tests/UnitTests/GUI/TestGUICoreObjectCorrespondence.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestGUICoreObjectCorrespondence.h
rename to Tests/UnitTests/GUI/TestGUICoreObjectCorrespondence.cpp
diff --git a/Tests/UnitTests/GUI/TestGUIHelpers.h b/Tests/UnitTests/GUI/TestGUIHelpers.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestGUIHelpers.h
rename to Tests/UnitTests/GUI/TestGUIHelpers.cpp
diff --git a/Tests/UnitTests/GUI/TestGroupItem.h b/Tests/UnitTests/GUI/TestGroupItem.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestGroupItem.h
rename to Tests/UnitTests/GUI/TestGroupItem.cpp
diff --git a/Tests/UnitTests/GUI/TestLayerItems.h b/Tests/UnitTests/GUI/TestLayerItems.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestLayerItems.h
rename to Tests/UnitTests/GUI/TestLayerItems.cpp
diff --git a/Tests/UnitTests/GUI/TestLayerRoughnessItems.h b/Tests/UnitTests/GUI/TestLayerRoughnessItems.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestLayerRoughnessItems.h
rename to Tests/UnitTests/GUI/TestLayerRoughnessItems.cpp
diff --git a/Tests/UnitTests/GUI/TestLinkInstrument.h b/Tests/UnitTests/GUI/TestLinkInstrument.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestLinkInstrument.h
rename to Tests/UnitTests/GUI/TestLinkInstrument.cpp
diff --git a/Tests/UnitTests/GUI/TestMapperCases.h b/Tests/UnitTests/GUI/TestMapperCases.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestMapperCases.h
rename to Tests/UnitTests/GUI/TestMapperCases.cpp
diff --git a/Tests/UnitTests/GUI/TestMapperForItem.h b/Tests/UnitTests/GUI/TestMapperForItem.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestMapperForItem.h
rename to Tests/UnitTests/GUI/TestMapperForItem.cpp
diff --git a/Tests/UnitTests/GUI/TestMaterialModel.h b/Tests/UnitTests/GUI/TestMaterialModel.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestMaterialModel.h
rename to Tests/UnitTests/GUI/TestMaterialModel.cpp
diff --git a/Tests/UnitTests/GUI/TestMaterialPropertyController.h b/Tests/UnitTests/GUI/TestMaterialPropertyController.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestMaterialPropertyController.h
rename to Tests/UnitTests/GUI/TestMaterialPropertyController.cpp
diff --git a/Tests/UnitTests/GUI/TestMessageService.h b/Tests/UnitTests/GUI/TestMessageService.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestMessageService.h
rename to Tests/UnitTests/GUI/TestMessageService.cpp
diff --git a/Tests/UnitTests/GUI/TestModelUtils.h b/Tests/UnitTests/GUI/TestModelUtils.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestModelUtils.h
rename to Tests/UnitTests/GUI/TestModelUtils.cpp
diff --git a/Tests/UnitTests/GUI/TestMultiLayerItem.h b/Tests/UnitTests/GUI/TestMultiLayerItem.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestMultiLayerItem.h
rename to Tests/UnitTests/GUI/TestMultiLayerItem.cpp
diff --git a/Tests/UnitTests/GUI/TestOutputDataIOService.h b/Tests/UnitTests/GUI/TestOutputDataIOService.cpp
similarity index 68%
rename from Tests/UnitTests/GUI/TestOutputDataIOService.h
rename to Tests/UnitTests/GUI/TestOutputDataIOService.cpp
index 494f0aeb1f5774a92f6aea13ff5f06437b7210d3..152cd0f8d4d6a4b0c32a427891740efe71378bab 100644
--- a/Tests/UnitTests/GUI/TestOutputDataIOService.h
+++ b/Tests/UnitTests/GUI/TestOutputDataIOService.cpp
@@ -1,26 +1,22 @@
 #include "google_test.h"
-#include <memory>
 #include "ApplicationModels.h"
 #include "DataItem.h"
-#include "OutputDataIOService.h"
-#include "RealDataItem.h"
+#include "GUIHelpers.h"
+#include "ImportDataInfo.h"
+#include "IntensityDataIOFactory.h"
 #include "JobModel.h"
+#include "JobModelFunctions.h"
 #include "JobItem.h"
 #include "JobItemUtils.h"
-#include "OutputDataIOHistory.h"
-#include "GUIHelpers.h"
 #include "OutputData.h"
+#include "OutputDataIOHistory.h"
+#include "OutputDataIOService.h"
 #include "ProjectUtils.h"
-#include "IntensityDataIOFactory.h"
-#include "IntensityDataFunctions.h"
+#include "RealDataItem.h"
 #include "RealDataModel.h"
 #include "test_utils.h"
 #include <QTest>
-
-namespace {
-const int nxsize = 5;
-const int nysize = 10;
-}
+#include <memory>
 
 class TestOutputDataIOService : public ::testing::Test
 {
@@ -28,20 +24,6 @@ public:
     TestOutputDataIOService();
     ~TestOutputDataIOService();
 
-    //! Helper function to test if data are the same.
-    bool isTheSame(const OutputData<double>& data1, const OutputData<double>& data2)
-    {
-        double diff = IntensityDataFunctions::getRelativeDifference(data1, data2);
-        return diff < 1e-10;
-    }
-
-    //! Helper function to check if file on disk represents same data.
-    bool isTheSame(const QString& fileName, const OutputData<double>& data)
-    {
-        std::unique_ptr<OutputData<double>> dataOnDisk(
-            IntensityDataIOFactory::readOutputData(fileName.toStdString()));
-        return isTheSame(*dataOnDisk, data);
-    }
 protected:
     OutputData<double> m_data;
 };
@@ -70,7 +52,7 @@ TEST_F(TestOutputDataIOService, test_nonXMLData)
     // adding RealDataItem
     RealDataItem* realData = dynamic_cast<RealDataItem*>(
         models.realDataModel()->insertNewItem(Constants::RealDataType));
-    EXPECT_THROW(models.realDataModel()->nonXMLData().size(), GUIHelpers::Error);
+    EXPECT_EQ(models.realDataModel()->nonXMLData().size(), 0);
     realData->setOutputData(TestUtils::createData().release());
     EXPECT_EQ(models.realDataModel()->nonXMLData().size(), 1);
 
@@ -83,13 +65,13 @@ TEST_F(TestOutputDataIOService, test_nonXMLData)
     // adding RealDataItem to jobItem
     RealDataItem* realData2 = dynamic_cast<RealDataItem*>(models.jobModel()->insertNewItem(
         Constants::RealDataType, jobItem->index(), -1, JobItem::T_REALDATA));
-    EXPECT_THROW(models.jobModel()->nonXMLData().size(), GUIHelpers::Error);
+    EXPECT_EQ(models.jobModel()->nonXMLData().size(), 1);
     realData2->setOutputData(TestUtils::createData(0.0, TestUtils::DIM::D1).release());
     EXPECT_EQ(models.jobModel()->nonXMLData().size(), 2);
 
     // checking data items of OutputDataIOService
     OutputDataIOService service(&models);
-    EXPECT_EQ(service.dataItems().size(), 3);
+    EXPECT_EQ(service.nonXMLItems().size(), 3);
 
     // checking data items of ApplicationModels
     dataItems = models.nonXMLData();
@@ -237,19 +219,19 @@ TEST_F(TestOutputDataIOService, test_OutputDataIOService)
         IntensityDataIOFactory::readOutputData(fname1.toStdString()));
     std::unique_ptr<OutputData<double>> dataOnDisk2(
         IntensityDataIOFactory::readOutputData(fname2.toStdString()));
-    EXPECT_TRUE(isTheSame(*dataOnDisk1, *realData1->dataItem()->getOutputData()));
-    EXPECT_TRUE(isTheSame(*dataOnDisk2, *realData2->dataItem()->getOutputData()));
+    EXPECT_TRUE(TestUtils::isTheSame(*dataOnDisk1, *realData1->dataItem()->getOutputData()));
+    EXPECT_TRUE(TestUtils::isTheSame(*dataOnDisk2, *realData2->dataItem()->getOutputData()));
 
     // Modifying data and saving the project.
     realData2->setOutputData(TestUtils::createData(value3).release());
     service.save(projectDir);
     QTest::qSleep(10);
 
-    EXPECT_TRUE(isTheSame(*dataOnDisk1, *realData1->dataItem()->getOutputData()));
-    EXPECT_TRUE(isTheSame(*dataOnDisk2, *realData2->dataItem()->getOutputData()) == false);
+    EXPECT_TRUE(TestUtils::isTheSame(*dataOnDisk1, *realData1->dataItem()->getOutputData()));
+    EXPECT_TRUE(TestUtils::isTheSame(*dataOnDisk2, *realData2->dataItem()->getOutputData()) == false);
     // checking that data on disk has changed
     dataOnDisk2.reset(IntensityDataIOFactory::readOutputData(fname2.toStdString()));
-    EXPECT_TRUE(isTheSame(*dataOnDisk2, *realData2->dataItem()->getOutputData()));
+    EXPECT_TRUE(TestUtils::isTheSame(*dataOnDisk2, *realData2->dataItem()->getOutputData()));
 
     // Renaming RealData and check that file on disk changed the name
     realData2->setItemName("data2new");
@@ -258,8 +240,84 @@ TEST_F(TestOutputDataIOService, test_OutputDataIOService)
 
     QString fname2new = "./" + projectDir + "/" + "realdata_data2new_0.int.gz";
     EXPECT_TRUE(ProjectUtils::exists(fname2new));
-    EXPECT_TRUE(isTheSame(fname2new, *realData2->dataItem()->getOutputData()));
+    EXPECT_TRUE(TestUtils::isTheSame(fname2new, *realData2->dataItem()->getOutputData()));
 
     // Check that file with old name was removed.
     EXPECT_TRUE(ProjectUtils::exists(fname2) == false);
 }
+
+TEST_F(TestOutputDataIOService, test_RealDataItemWithNativeData)
+{
+    ApplicationModels models;
+
+    // initial state
+    auto dataItems = models.nonXMLData();
+    EXPECT_EQ(dataItems.size(), 0);
+
+    // adding RealDataItem
+    RealDataItem* realData = dynamic_cast<RealDataItem*>(
+        models.realDataModel()->insertNewItem(Constants::RealDataType));
+    EXPECT_EQ(models.realDataModel()->nonXMLData().size(), 0);
+
+    ImportDataInfo import_data(std::unique_ptr<OutputData<double>>(m_data.clone()),
+                               Constants::UnitsNbins);
+    realData->setImportData(std::move(import_data));
+
+    EXPECT_EQ(models.realDataModel()->nonXMLData().size(), 2);
+    realData->setItemValue(RealDataItem::P_NAME, QString("RealData"));
+
+    // adding JobItem
+    JobItem* jobItem =
+        dynamic_cast<JobItem*>(models.jobModel()->insertNewItem(Constants::JobItemType));
+    jobItem->setIdentifier(GUIHelpers::createUuid());
+    models.jobModel()->insertNewItem(Constants::IntensityDataType, jobItem->index(), -1,
+                                     JobItem::T_OUTPUT);
+    EXPECT_EQ(models.jobModel()->nonXMLData().size(), 1);
+
+    // copying RealDataItem to JobItem
+    JobModelFunctions::copyRealDataItem(jobItem, realData);
+    EXPECT_EQ(models.jobModel()->nonXMLData().size(), 3);
+
+    // checking data items of OutputDataIOService
+    OutputDataIOService service(&models);
+    EXPECT_EQ(service.nonXMLItems().size(), 5);
+
+    const QString projectDir("test_NativeData");
+    TestUtils::create_dir(projectDir);
+
+    // Saving
+    service.save(projectDir);
+    QTest::qSleep(10);
+
+    // Checking existance of data on disk
+    auto data1 = realData->dataItem();
+    auto data2 = realData->nativeData();
+    auto data3 = jobItem->realDataItem()->dataItem();
+    auto data4 = jobItem->realDataItem()->nativeData();
+
+    QString fname1 = "./" + projectDir + "/" + data1->fileName();
+    QString fname2 = "./" + projectDir + "/" + data2->fileName();
+    QString fname3 = "./" + projectDir + "/" + data3->fileName();
+    QString fname4 = "./" + projectDir + "/" + data4->fileName();
+
+    EXPECT_TRUE(ProjectUtils::exists(fname1));
+    EXPECT_TRUE(ProjectUtils::exists(fname2));
+    EXPECT_TRUE(ProjectUtils::exists(fname3));
+    EXPECT_TRUE(ProjectUtils::exists(fname4));
+
+    auto readData =
+        [](const QString& filename) {
+            return std::unique_ptr<OutputData<double>>(
+                IntensityDataIOFactory::readOutputData(filename.toStdString()));
+        };
+
+    // Reading data from disk, checking it is the same
+    auto dataOnDisk1 = readData(fname1);
+    auto dataOnDisk2 = readData(fname2);
+    auto dataOnDisk3 = readData(fname3);
+    auto dataOnDisk4 = readData(fname4);
+    EXPECT_TRUE(TestUtils::isTheSame(*dataOnDisk1, *data1->getOutputData()));
+    EXPECT_TRUE(TestUtils::isTheSame(*dataOnDisk2, *data2->getOutputData()));
+    EXPECT_TRUE(TestUtils::isTheSame(*dataOnDisk3, *data3->getOutputData()));
+    EXPECT_TRUE(TestUtils::isTheSame(*dataOnDisk4, *data4->getOutputData()));
+}
diff --git a/Tests/UnitTests/GUI/TestParaCrystalItems.h b/Tests/UnitTests/GUI/TestParaCrystalItems.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestParaCrystalItems.h
rename to Tests/UnitTests/GUI/TestParaCrystalItems.cpp
diff --git a/Tests/UnitTests/GUI/TestParameterTreeUtils.h b/Tests/UnitTests/GUI/TestParameterTreeUtils.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestParameterTreeUtils.h
rename to Tests/UnitTests/GUI/TestParameterTreeUtils.cpp
diff --git a/Tests/UnitTests/GUI/TestParticleCoreShell.h b/Tests/UnitTests/GUI/TestParticleCoreShell.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestParticleCoreShell.h
rename to Tests/UnitTests/GUI/TestParticleCoreShell.cpp
diff --git a/Tests/UnitTests/GUI/TestParticleDistributionItem.h b/Tests/UnitTests/GUI/TestParticleDistributionItem.cpp
similarity index 53%
rename from Tests/UnitTests/GUI/TestParticleDistributionItem.h
rename to Tests/UnitTests/GUI/TestParticleDistributionItem.cpp
index 59ad3b1b744b7c43009cc5242e6fbd6056a0a1da..1a54c0ec565fb3832df6eeb0a7ff9293d241e8b5 100644
--- a/Tests/UnitTests/GUI/TestParticleDistributionItem.h
+++ b/Tests/UnitTests/GUI/TestParticleDistributionItem.cpp
@@ -50,7 +50,7 @@ TEST_F(TestParticleDistributionItem, test_InitialState)
     EXPECT_EQ(distItem->displayName(), distItem->itemName());
 
     // xpos, ypos, P_ABUNDANCE, P_DISTRIBUTION, P_DISTRIBUTED_PARAMETER
-    EXPECT_EQ(distItem->children().size(), 5);
+    EXPECT_EQ(distItem->children().size(), 6);
 
     EXPECT_EQ(distItem->defaultTag(), ParticleDistributionItem::T_PARTICLES);
 
@@ -59,10 +59,17 @@ TEST_F(TestParticleDistributionItem, test_InitialState)
                                  << Constants::ParticleCompositionType
                                  << Constants::MesoCrystalType);
 
+    // main parameter
     ComboProperty prop = distItem->getItemValue(ParticleDistributionItem::P_DISTRIBUTED_PARAMETER)
                              .value<ComboProperty>();
     EXPECT_EQ(prop.getValues(), QStringList() << ParticleDistributionItem::NO_SELECTION);
     EXPECT_EQ(prop.getValue(), ParticleDistributionItem::NO_SELECTION);
+
+    // linked parameter
+    prop = distItem->getItemValue(ParticleDistributionItem::P_LINKED_PARAMETER)
+                             .value<ComboProperty>();
+    EXPECT_EQ(prop.getValues(), QStringList());
+    EXPECT_EQ(prop.getValue(), "");
 }
 
 TEST_F(TestParticleDistributionItem, test_AddParticle)
@@ -81,6 +88,15 @@ TEST_F(TestParticleDistributionItem, test_AddParticle)
     EXPECT_EQ(prop.getValues(), expectedCylinderParams);
     EXPECT_EQ(prop.getValue(), ParticleDistributionItem::NO_SELECTION);
 
+    // linked parameter
+    prop = dist->getItemValue(ParticleDistributionItem::P_LINKED_PARAMETER)
+                             .value<ComboProperty>();
+
+    QStringList expectedLinked = expectedCylinderParams;
+    expectedLinked.removeAll(ParticleDistributionItem::NO_SELECTION);
+    EXPECT_EQ(prop.getValues(), expectedLinked);
+    EXPECT_EQ(prop.getValue(), "");
+
     // changing formfactor of the particle
     particle->setGroupProperty(ParticleItem::P_FORM_FACTOR, Constants::BoxType);
 
@@ -89,6 +105,79 @@ TEST_F(TestParticleDistributionItem, test_AddParticle)
 
     EXPECT_EQ(prop.getValues(), expectedBoxParams);
     EXPECT_EQ(prop.getValue(), ParticleDistributionItem::NO_SELECTION);
+
+    // cheking linked
+    prop = dist->getItemValue(ParticleDistributionItem::P_LINKED_PARAMETER)
+                             .value<ComboProperty>();
+
+    expectedLinked = expectedBoxParams;
+    expectedLinked.removeAll(ParticleDistributionItem::NO_SELECTION);
+    EXPECT_EQ(prop.getValues(), expectedLinked);
+    EXPECT_EQ(prop.getValue(), "");
+    EXPECT_EQ(prop.selectedValues(), QStringList());
+}
+
+//! Values available for linking should depend on main parameter.
+
+TEST_F(TestParticleDistributionItem, test_MainLinkedCorrelation)
+{
+    SampleModel model;
+    SessionItem* dist = model.insertNewItem(Constants::ParticleDistributionType);
+    model.insertNewItem(Constants::ParticleType, dist->index());
+
+    ComboProperty mainCombo = dist->getItemValue(ParticleDistributionItem::P_DISTRIBUTED_PARAMETER)
+                             .value<ComboProperty>();
+
+    EXPECT_EQ(mainCombo.getValues(), expectedCylinderParams);
+    EXPECT_EQ(mainCombo.getValue(), ParticleDistributionItem::NO_SELECTION);
+
+    // linked parameter
+    ComboProperty linkedCombo = dist->getItemValue(ParticleDistributionItem::P_LINKED_PARAMETER)
+                             .value<ComboProperty>();
+
+    QStringList expectedLinked = expectedCylinderParams;
+    expectedLinked.removeAll(ParticleDistributionItem::NO_SELECTION);
+    EXPECT_EQ(linkedCombo.getValues(), expectedLinked);
+    EXPECT_EQ(linkedCombo.getValue(), "");
+    EXPECT_EQ(linkedCombo.selectedValues(), QStringList());
+
+    // selecting main parameter
+    QString mainPar("Particle/Cylinder/Radius");
+    mainCombo.setValue(mainPar);
+    dist->setItemValue(ParticleDistributionItem::P_DISTRIBUTED_PARAMETER, mainCombo.variant());
+
+    // linked parameter shouldn't have main parameter in the list
+    expectedLinked = expectedCylinderParams;
+    expectedLinked.removeAll(ParticleDistributionItem::NO_SELECTION);
+    expectedLinked.removeAll(mainPar);
+
+    linkedCombo = dist->getItemValue(ParticleDistributionItem::P_LINKED_PARAMETER)
+                             .value<ComboProperty>();
+    EXPECT_EQ(linkedCombo.getValues(), expectedLinked);
+    EXPECT_EQ(linkedCombo.getValue(), "");
+    EXPECT_EQ(linkedCombo.selectedValues(), QStringList());
+
+    // --- Scenario 2
+
+    // selecting linked parameter
+    linkedCombo.setSelected("Particle/Cylinder/Height");
+    dist->setItemValue(ParticleDistributionItem::P_LINKED_PARAMETER, linkedCombo.variant());
+
+    // selecting another main parameter
+    mainPar = "Particle/Position Offset/X";
+    mainCombo.setValue(mainPar);
+    dist->setItemValue(ParticleDistributionItem::P_DISTRIBUTED_PARAMETER, mainCombo.variant());
+
+    // checking linked
+    linkedCombo = dist->getItemValue(ParticleDistributionItem::P_LINKED_PARAMETER)
+                             .value<ComboProperty>();
+    expectedLinked = expectedCylinderParams;
+    expectedLinked.removeAll(ParticleDistributionItem::NO_SELECTION);
+    expectedLinked.removeAll(mainPar);
+
+    EXPECT_EQ(linkedCombo.getValues(), expectedLinked);
+    EXPECT_EQ(linkedCombo.getValue(), "Particle/Cylinder/Height");
+    EXPECT_EQ(linkedCombo.selectedValues(), QStringList("Particle/Cylinder/Height"));
 }
 
 TEST_F(TestParticleDistributionItem, test_FromDomain)
@@ -126,6 +215,54 @@ TEST_F(TestParticleDistributionItem, test_FromDomain)
     EXPECT_EQ(prop.getValue(), QString("Particle/Cylinder/Radius"));
 }
 
+//! Constructing from domain distribution with linked parameter defined
+
+TEST_F(TestParticleDistributionItem, test_FromDomainLinked)
+{
+    const std::string pattern("/Particle/Cylinder/Radius");
+    const std::string linked("/Particle/Cylinder/Height");
+
+    // creating domain distribution
+    FormFactorCylinder cylinder(1.0, 2.0);
+    Particle particle(HomogeneousMaterial("Particle", 6e-4, 2e-8), cylinder);
+    DistributionGaussian gauss(1.0, 0.1);
+    ParameterDistribution par_distr(pattern, gauss, 100, 3.0);
+    par_distr.linkParameter(linked);
+
+    ParticleDistribution particle_collection(particle, par_distr);
+
+    // creating GUI distribution
+    SampleModel model;
+    SessionItem* distItem = model.insertNewItem(Constants::ParticleDistributionType);
+    SessionItem* particleItem = model.insertNewItem(Constants::ParticleType, distItem->index());
+
+    particleItem->setGroupProperty(ParticleItem::P_FORM_FACTOR, Constants::AnisoPyramidType);
+
+    // Sets it from domain
+    TransformFromDomain::setParticleDistributionItem(distItem, particle_collection);
+
+    ComboProperty prop = distItem->getItemValue(ParticleDistributionItem::P_DISTRIBUTED_PARAMETER)
+                             .value<ComboProperty>();
+    EXPECT_EQ(prop.getValue(), ParticleDistributionItem::NO_SELECTION);
+
+    ComboProperty linkedProp = distItem->getItemValue(ParticleDistributionItem::P_LINKED_PARAMETER)
+                             .value<ComboProperty>();
+    EXPECT_EQ(linkedProp.getValue(), "");
+
+    // changing particle type and check that distribution picked up domain name
+    particleItem->setGroupProperty(ParticleItem::P_FORM_FACTOR, Constants::CylinderType);
+
+    prop = distItem->getItemValue(ParticleDistributionItem::P_DISTRIBUTED_PARAMETER)
+               .value<ComboProperty>();
+    EXPECT_EQ(prop.getValue(), QString("Particle/Cylinder/Radius"));
+
+    linkedProp = distItem->getItemValue(ParticleDistributionItem::P_LINKED_PARAMETER)
+               .value<ComboProperty>();
+    QStringList expectedLinked = QStringList() << QString("Particle/Cylinder/Height");
+    EXPECT_EQ(linkedProp.selectedValues(), expectedLinked);
+    EXPECT_EQ(linkedProp.getValue(), expectedLinked.at(0));
+}
+
 TEST_F(TestParticleDistributionItem, test_FromDomainWithLimits)
 {
     const std::string pattern("/Particle/Cylinder/Radius");
@@ -145,7 +282,7 @@ TEST_F(TestParticleDistributionItem, test_FromDomainWithLimits)
     SessionItem* partDistItem = model.insertNewItem(Constants::ParticleDistributionType);
     model.insertNewItem(Constants::ParticleType, partDistItem->index());
 
-    //    // Sets it from domain
+    // Sets it from domain
     TransformFromDomain::setParticleDistributionItem(partDistItem, particle_collection);
 
     SessionItem* distItem = partDistItem->getGroupItem(ParticleDistributionItem::P_DISTRIBUTION);
diff --git a/Tests/UnitTests/GUI/TestParticleItem.h b/Tests/UnitTests/GUI/TestParticleItem.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestParticleItem.h
rename to Tests/UnitTests/GUI/TestParticleItem.cpp
diff --git a/Tests/UnitTests/GUI/TestProjectDocument.h b/Tests/UnitTests/GUI/TestProjectDocument.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestProjectDocument.h
rename to Tests/UnitTests/GUI/TestProjectDocument.cpp
diff --git a/Tests/UnitTests/GUI/TestProjectUtils.h b/Tests/UnitTests/GUI/TestProjectUtils.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestProjectUtils.h
rename to Tests/UnitTests/GUI/TestProjectUtils.cpp
diff --git a/Tests/UnitTests/GUI/TestPropertyRepeater.h b/Tests/UnitTests/GUI/TestPropertyRepeater.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestPropertyRepeater.h
rename to Tests/UnitTests/GUI/TestPropertyRepeater.cpp
diff --git a/Tests/UnitTests/GUI/TestProxyModelStrategy.h b/Tests/UnitTests/GUI/TestProxyModelStrategy.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestProxyModelStrategy.h
rename to Tests/UnitTests/GUI/TestProxyModelStrategy.cpp
diff --git a/Tests/UnitTests/GUI/TestRealSpaceBuilderUtils.h b/Tests/UnitTests/GUI/TestRealSpaceBuilderUtils.cpp
similarity index 99%
rename from Tests/UnitTests/GUI/TestRealSpaceBuilderUtils.h
rename to Tests/UnitTests/GUI/TestRealSpaceBuilderUtils.cpp
index 66585f61eb78489bfe00bc8d1ce1096bf5090d8f..187d88e520220b0dd8a03a24fa375013090634d2 100644
--- a/Tests/UnitTests/GUI/TestRealSpaceBuilderUtils.h
+++ b/Tests/UnitTests/GUI/TestRealSpaceBuilderUtils.cpp
@@ -1,6 +1,8 @@
 #ifndef TESTREALSPACEBUILDERUTILS_H
 #define TESTREALSPACEBUILDERUTILS_H
 
+#ifdef BORNAGAIN_OPENGL
+
 #include "ApplicationModels.h"
 #include "IFormFactor.h"
 #include "IFormFactorDecorator.h"
@@ -246,4 +248,6 @@ TEST_F(TestRealSpaceBuilderUtils, test_particle3DContainerVector)
     EXPECT_EQ(particle3DContainer_vector.at(2).particleType(), Constants::ParticleType);
 }
 
+#endif // BORNAGAIN_OPENGL
+
 #endif // TESTREALSPACEBUILDERUTILS_H
diff --git a/Tests/UnitTests/GUI/TestSaveService.h b/Tests/UnitTests/GUI/TestSaveService.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestSaveService.h
rename to Tests/UnitTests/GUI/TestSaveService.cpp
diff --git a/Tests/UnitTests/GUI/TestSavingSpecularData.cpp b/Tests/UnitTests/GUI/TestSavingSpecularData.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e346d61c82dc5c4c238302a63869e668f005285d
--- /dev/null
+++ b/Tests/UnitTests/GUI/TestSavingSpecularData.cpp
@@ -0,0 +1,302 @@
+#include "google_test.h"
+#include "ApplicationModels.h"
+#include "DataItem.h"
+#include "GroupItem.h"
+#include "GUIHelpers.h"
+#include "InstrumentItems.h"
+#include "InstrumentModel.h"
+#include "IntensityDataIOFactory.h"
+#include "ItemFileNameUtils.h"
+#include "JobModel.h"
+#include "JobModelFunctions.h"
+#include "JobItem.h"
+#include "OutputData.h"
+#include "OutputDataIOService.h"
+#include "PointwiseAxis.h"
+#include "PointwiseAxisItem.h"
+#include "ProjectUtils.h"
+#include "SpecularBeamInclinationItem.h"
+#include "test_utils.h"
+#include <QTest>
+
+class TestSavingSpecularData : public ::testing::Test
+{
+public:
+    TestSavingSpecularData();
+    ~TestSavingSpecularData();
+
+protected:
+    SpecularInstrumentItem* createSpecularInstrument(ApplicationModels& models);
+    PointwiseAxisItem* createPointwiseAxisItem(SessionModel& model);
+    GroupItem* getAxisGroup(SpecularInstrumentItem* instrument);
+    bool isSame(const QString& filename, const IAxis* axis);
+
+    std::unique_ptr<PointwiseAxis> m_axis;
+};
+
+TestSavingSpecularData::TestSavingSpecularData()
+    : m_axis(new PointwiseAxis("x", std::vector<double>{0.1, 0.2, 1.0}))
+{
+}
+
+TestSavingSpecularData::~TestSavingSpecularData() = default;
+
+SpecularInstrumentItem* TestSavingSpecularData::createSpecularInstrument(ApplicationModels& models)
+{
+    return dynamic_cast<SpecularInstrumentItem*>(
+        models.instrumentModel()->insertNewItem(Constants::SpecularInstrumentType));
+}
+
+PointwiseAxisItem* TestSavingSpecularData::createPointwiseAxisItem(SessionModel& model)
+{
+    auto instrument_item = dynamic_cast<SpecularInstrumentItem*>(
+        model.insertNewItem(Constants::SpecularInstrumentType));
+    return dynamic_cast<PointwiseAxisItem*>(
+        getAxisGroup(instrument_item)->getChildOfType(Constants::PointwiseAxisType));
+}
+
+GroupItem* TestSavingSpecularData::getAxisGroup(SpecularInstrumentItem* instrument)
+{
+    auto axis_item = instrument->getItem(SpecularInstrumentItem::P_BEAM)
+                         ->getItem(BeamItem::P_INCLINATION_ANGLE)
+                         ->getItem(SpecularBeamInclinationItem::P_ALPHA_AXIS);
+    return dynamic_cast<GroupItem*>(axis_item);
+}
+
+bool TestSavingSpecularData::isSame(const QString& filename, const IAxis* axis)
+{
+    std::unique_ptr<OutputData<double>> dataOnDisk(
+        IntensityDataIOFactory::readOutputData(filename.toStdString()));
+    OutputData<double> refData;
+    refData.addAxis(*axis);
+    return TestUtils::isTheSame(*dataOnDisk, refData);
+}
+
+TEST_F(TestSavingSpecularData, test_SpecularInsturment)
+{
+    ApplicationModels models;
+
+    // initial state
+    auto dataItems = models.nonXMLData();
+    EXPECT_EQ(dataItems.size(), 0);
+
+    // adding instrument
+    auto instrument = createSpecularInstrument(models);
+
+    // instrument contains hidden pointwise axis item
+    EXPECT_EQ(models.instrumentModel()->nonXMLData().size(), 1);
+
+    // explicitly switching to pointwise axis item
+    auto axis_group = getAxisGroup(instrument);
+    axis_group->setCurrentType(Constants::PointwiseAxisType);
+    EXPECT_EQ(models.instrumentModel()->nonXMLData().size(), 1);
+
+    // hiding pointwise axis item back
+    axis_group->setCurrentType(Constants::BasicAxisType);
+    EXPECT_EQ(models.instrumentModel()->nonXMLData().size(), 1);
+
+    // checking data items of OutputDataIOService
+    OutputDataIOService service(&models);
+    EXPECT_EQ(service.nonXMLItems().size(), 1);
+
+    // checking data items of ApplicationModels
+    dataItems = models.nonXMLData();
+    EXPECT_EQ(dataItems.size(), 1);
+}
+
+TEST_F(TestSavingSpecularData, test_InstrumentInJobItem)
+{
+    ApplicationModels models;
+
+    // adding JobItem
+    SessionItem* jobItem = models.jobModel()->insertNewItem(Constants::JobItemType);
+    SessionItem* dataItem = models.jobModel()->insertNewItem(
+        Constants::IntensityDataType, jobItem->index(), -1, JobItem::T_OUTPUT);
+    EXPECT_EQ(models.jobModel()->nonXMLData().size(), 1);
+
+    // adding instrument
+    auto instrument = dynamic_cast<SpecularInstrumentItem*>(models.jobModel()->insertNewItem(
+        Constants::SpecularInstrumentType, jobItem->index(), -1, JobItem::T_INSTRUMENT));
+    // instrument contains hidden pointwise axis item
+    EXPECT_EQ(models.jobModel()->nonXMLData().size(), 2);
+
+    // explicitly switching to pointwise axis item
+    auto axis_group = getAxisGroup(instrument);
+    axis_group->setCurrentType(Constants::PointwiseAxisType);
+    EXPECT_EQ(models.jobModel()->nonXMLData().size(), 2);
+
+    OutputDataIOService service(&models);
+    EXPECT_EQ(service.nonXMLItems().size(), 2);
+
+    auto dataItems = models.nonXMLData();
+    EXPECT_EQ(dataItems.size(), 2);
+    EXPECT_EQ(dataItems.indexOf(dataItem), 0);
+
+    // hiding pointwise axis, should be saved anyway
+    axis_group->setCurrentType(Constants::BasicAxisType);
+    EXPECT_EQ(models.jobModel()->nonXMLData().size(), 2);
+    EXPECT_EQ(service.nonXMLItems().size(), 2);
+    dataItems = models.nonXMLData();
+    EXPECT_EQ(dataItems.size(), 2);
+    EXPECT_EQ(dataItems.indexOf(dataItem), 0);
+}
+
+TEST_F(TestSavingSpecularData, test_setLastModified)
+{
+    SessionModel model("TempModel");
+    auto item = createPointwiseAxisItem(model);
+
+    const int nap_time(10);
+    QTest::qSleep(nap_time);
+
+    OutputDataSaveInfo info = OutputDataSaveInfo::createSaved(item);
+    EXPECT_FALSE(info.wasModifiedSinceLastSave());
+
+    QTest::qSleep(nap_time);
+    item->init(*m_axis.get(), Constants::UnitsDegrees);
+    EXPECT_TRUE(info.wasModifiedSinceLastSave());
+
+    info = OutputDataSaveInfo::createSaved(item);
+    QTest::qSleep(nap_time);
+    item->setItemValue(PointwiseAxisItem::P_FILE_NAME, QString("new_value"));
+    EXPECT_TRUE(info.wasModifiedSinceLastSave());
+}
+
+TEST_F(TestSavingSpecularData, test_DirHistory)
+{
+    SessionModel model("TempModel");
+    auto item1 = createPointwiseAxisItem(model);
+    item1->init(*m_axis, Constants::UnitsDegrees);
+
+    auto item2 = createPointwiseAxisItem(model);
+
+    // empty history
+    OutputDataDirHistory history;
+    EXPECT_FALSE(history.contains(item1));
+    // non-existing item is treated as modified
+    EXPECT_TRUE(history.wasModifiedSinceLastSave(item1));
+
+    // Saving item in a history
+    history.markAsSaved(item1);
+    history.markAsSaved(item2);
+
+    EXPECT_TRUE(history.contains(item1));
+    // Empty DataItems are not added to history:
+    EXPECT_FALSE(history.contains(item2));
+    EXPECT_FALSE(history.wasModifiedSinceLastSave(item1));
+
+    // Attempt to save same item second time
+    EXPECT_THROW(history.markAsSaved(item1), GUIHelpers::Error);
+
+    // Modifying item
+    QTest::qSleep(10);
+    item1->init(*m_axis, Constants::UnitsDegrees);
+
+    EXPECT_TRUE(history.wasModifiedSinceLastSave(item1));
+}
+
+//! Testing saving abilities of OutputDataIOService class.
+TEST_F(TestSavingSpecularData, test_OutputDataIOService)
+{
+    const QString projectDir("test_SpecularDataSave");
+    TestUtils::create_dir(projectDir);
+
+    // setting up items and data
+
+    ApplicationModels models;
+    auto instrument1 = createSpecularInstrument(models);
+    auto instrument2 = createSpecularInstrument(models);
+
+    auto axis_group1 = getAxisGroup(instrument1);
+    auto pointwise_axis_item1 =
+        dynamic_cast<PointwiseAxisItem*>(axis_group1->getChildOfType(Constants::PointwiseAxisType));
+    pointwise_axis_item1->init(*m_axis, Constants::UnitsDegrees);
+
+    auto axis_group2 = getAxisGroup(instrument2);
+    auto pointwise_axis_item2 =
+        dynamic_cast<PointwiseAxisItem*>(axis_group2->getChildOfType(Constants::PointwiseAxisType));
+    PointwiseAxis tmp("y", std::vector<double>{1.0, 2.0, 3.0});
+    pointwise_axis_item2->init(tmp, Constants::UnitsRadians);
+
+    // Saving first time
+    OutputDataIOService service(&models);
+    service.save(projectDir);
+    QTest::qSleep(10);
+
+    // Checking existance of data on disk
+    QString fname1 = "./" + projectDir + "/" + pointwise_axis_item1->fileName();
+    QString fname2 = "./" + projectDir + "/" + pointwise_axis_item2->fileName();
+    EXPECT_TRUE(ProjectUtils::exists(fname1));
+    EXPECT_TRUE(ProjectUtils::exists(fname2));
+
+    // Reading data from disk, checking it is the same
+    EXPECT_TRUE(isSame(fname1, pointwise_axis_item1->getAxis()));
+    EXPECT_TRUE(isSame(fname2, pointwise_axis_item2->getAxis()));;
+
+    // Modifying data and saving the project.
+    PointwiseAxis tmp2("z", std::vector<double>{2.0, 3.0, 4.0});
+    pointwise_axis_item2->init(tmp2, Constants::UnitsRadians);
+    service.save(projectDir);
+    QTest::qSleep(10);
+
+    EXPECT_TRUE(isSame(fname1, pointwise_axis_item1->getAxis()));
+    EXPECT_TRUE(isSame(fname2, pointwise_axis_item2->getAxis()));
+
+    // Renaming RealData and check that file on disk changed the name
+    pointwise_axis_item2->setItemValue(PointwiseAxisItem::P_FILE_NAME, "data2new.int.gz");
+    service.save(projectDir);
+    QTest::qSleep(10);
+
+    QString fname2new = "./" + projectDir + "/" + pointwise_axis_item2->fileName();
+    EXPECT_TRUE(ProjectUtils::exists(fname2new));
+    EXPECT_TRUE(isSame(fname2new, pointwise_axis_item2->getAxis()));
+
+    // Check that file with old name was removed.
+    EXPECT_FALSE(ProjectUtils::exists(fname2));
+}
+
+TEST_F(TestSavingSpecularData, test_CopyInstrumentToJobItem)
+{
+    const QString projectDir("test_SpecularDataSave2");
+    TestUtils::create_dir(projectDir);
+
+    ApplicationModels models;
+
+    // adding instrument and initializing pointwise axis
+    auto instrument = createSpecularInstrument(models);
+    auto axis_group = getAxisGroup(instrument);
+    auto pointwise_axis_item =
+        dynamic_cast<PointwiseAxisItem*>(axis_group->getChildOfType(Constants::PointwiseAxisType));
+    pointwise_axis_item->init(*m_axis, Constants::UnitsQyQz);
+
+    // adding JobItem and copying instrument
+    auto jobItem =
+        dynamic_cast<JobItem*>(models.jobModel()->insertNewItem(Constants::JobItemType));
+    JobModelFunctions::setupJobItemInstrument(jobItem, instrument);
+    auto job_instrument =
+        dynamic_cast<SpecularInstrumentItem*>(jobItem->getItem(JobItem::T_INSTRUMENT));
+    auto job_axis_item = dynamic_cast<PointwiseAxisItem*>(
+        getAxisGroup(job_instrument)->getChildOfType(Constants::PointwiseAxisType));
+
+    // checking filenames
+    EXPECT_EQ(pointwise_axis_item->fileName(),
+              ItemFileNameUtils::instrumentDataFileName(*instrument));
+    EXPECT_EQ(job_axis_item->fileName(),
+              ItemFileNameUtils::instrumentDataFileName(*job_instrument));
+
+    // Saving
+    OutputDataIOService service(&models);
+    service.save(projectDir);
+    QTest::qSleep(10);
+
+    // Checking existance of data on disk
+    QString fname1 = "./" + projectDir + "/" + pointwise_axis_item->fileName();
+    QString fname2 = "./" + projectDir + "/" + job_axis_item->fileName();
+    EXPECT_FALSE(fname1 == fname2);
+    EXPECT_TRUE(ProjectUtils::exists(fname1));
+    EXPECT_TRUE(ProjectUtils::exists(fname2));
+
+    // Reading data from disk, checking it is the same
+    EXPECT_TRUE(isSame(fname1, pointwise_axis_item->getAxis()));
+    EXPECT_TRUE(isSame(fname2, job_axis_item->getAxis()));
+}
diff --git a/Tests/UnitTests/GUI/TestScientificSpinBox.cpp b/Tests/UnitTests/GUI/TestScientificSpinBox.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..02ac6103a50453f9bcbebb5b5c7897b4945b3005
--- /dev/null
+++ b/Tests/UnitTests/GUI/TestScientificSpinBox.cpp
@@ -0,0 +1,119 @@
+#include "google_test.h"
+#include "ScientificSpinBox.h"
+#include <limits>
+
+class TestScientificSpinBox : public ::testing::Test
+{
+public:
+    TestScientificSpinBox();
+    ~TestScientificSpinBox() override;
+};
+
+TestScientificSpinBox::TestScientificSpinBox()
+{
+}
+
+TestScientificSpinBox::~TestScientificSpinBox() = default;
+
+TEST_F(TestScientificSpinBox, testValueFromText)
+{
+    QLocale locale(QLocale::C);
+    locale.setNumberOptions(QLocale::RejectGroupSeparator);
+
+    QDoubleValidator validator;
+    validator.setLocale(locale);
+    validator.setNotation(QDoubleValidator::ScientificNotation);
+
+    auto to_value = [&validator](QString text) {
+        return ScientificSpinBox::toDouble(text, validator, std::numeric_limits<double>::lowest(),
+                                           std::numeric_limits<double>::max(), 0.1);
+    };
+
+    // translation fails
+    EXPECT_EQ(0.1, to_value(QString("abcd")));
+    EXPECT_EQ(0.1, to_value(QString("1,2")));
+    EXPECT_EQ(0.1, to_value(QString("100,000,000.2")));
+    EXPECT_EQ(0.1, to_value(QString("100.000.000.2")));
+    EXPECT_EQ(0.1, to_value(QString("1e+2345")));
+    EXPECT_EQ(0.1, to_value(QString("-1e+2345")));
+    EXPECT_EQ(0.1, to_value(QString("1e-2345")));
+    EXPECT_EQ(0.1, to_value(QString("-1e-2345")));
+    EXPECT_EQ(0.1, to_value(QString("--0.1")));
+    EXPECT_EQ(0.1, to_value(QString("-.e-12")));
+    EXPECT_EQ(0.1, to_value(QString()));
+
+    auto to_value_2 = [&validator](QString text) {
+        return ScientificSpinBox::toDouble(text, validator, -0.1,
+                                           1e+7, 0.1);
+    };
+
+    // translation fails due to out-of-bounds condition
+    EXPECT_EQ(0.1, to_value_2(QString("-0.2")));
+    EXPECT_EQ(0.1, to_value_2(QString("-0.1e+1")));
+    EXPECT_EQ(0.1, to_value_2(QString("1e+8")));
+
+    // legitimate values
+    EXPECT_EQ(-0.0999, to_value_2(QString("-0.0999")));
+    EXPECT_EQ(-1e-13, to_value_2(QString("-.1e-12")));
+    EXPECT_EQ(0.0, to_value_2(QString("0")));
+    EXPECT_EQ(0.123, to_value_2(QString("0.123")));
+    EXPECT_EQ(1e+6, to_value_2(QString("1e+6")));
+    EXPECT_EQ(1.1e+6, to_value_2(QString("1.1e+6")));
+    EXPECT_EQ(0.012, to_value_2(QString("0.012")));
+}
+
+TEST_F(TestScientificSpinBox, testTextFromValue)
+{
+    int decimals = 3;
+    auto to_string = [&decimals](double val){return ScientificSpinBox::toString(val, decimals);};
+
+    EXPECT_EQ(std::string("-1.235e+2"), to_string(-123.45).toStdString());
+    EXPECT_EQ(std::string("-100"), to_string(-99.9999).toStdString());
+    EXPECT_EQ(std::string("-99.999"), to_string(-99.9994).toStdString());
+    EXPECT_EQ(std::string("-10.123"), to_string(-10.12345).toStdString());
+    EXPECT_EQ(std::string("-1"), to_string(-1.).toStdString());
+    EXPECT_EQ(std::string("-0.1"), to_string(-0.1).toStdString());
+    EXPECT_EQ(std::string("-0.1"), to_string(-0.1).toStdString());
+    EXPECT_EQ(std::string("-9.99e-2"), to_string(-9.99e-2).toStdString());
+    EXPECT_EQ(std::string("-1.266e-12"), to_string(-1.26555e-12).toStdString());
+    EXPECT_EQ(std::string("0"), to_string(-0.0).toStdString());
+    EXPECT_EQ(std::string("0"), to_string(0.0).toStdString());
+    EXPECT_EQ(std::string("1e-12"), to_string(1.e-12).toStdString());
+    EXPECT_EQ(std::string("1.23e-12"), to_string(1.23e-12).toStdString());
+    EXPECT_EQ(std::string("1e-2"), to_string(1.e-2).toStdString());
+    EXPECT_EQ(std::string("1.5e-2"), to_string(1.5e-2).toStdString());
+    EXPECT_EQ(std::string("1.523e-2"), to_string(1.5234e-2).toStdString());
+    EXPECT_EQ(std::string("9.99e-2"), to_string(9.99e-2).toStdString());
+    EXPECT_EQ(std::string("1e-1"), to_string(9.9999e-2).toStdString());
+    EXPECT_EQ(std::string("0.1"), to_string(0.1).toStdString());
+    EXPECT_EQ(std::string("1"), to_string(1.).toStdString());
+    EXPECT_EQ(std::string("1.1"), to_string(1.1).toStdString());
+    EXPECT_EQ(std::string("1.123"), to_string(1.12345).toStdString());
+    EXPECT_EQ(std::string("10.123"), to_string(10.12345).toStdString());
+    EXPECT_EQ(std::string("99.9"), to_string(99.9).toStdString());
+    EXPECT_EQ(std::string("99.999"), to_string(99.9994).toStdString());
+    EXPECT_EQ(std::string("100"), to_string(99.9999).toStdString());
+    EXPECT_EQ(std::string("1.235e+2"), to_string(123.45).toStdString());
+    EXPECT_EQ(std::string("1e+4"), to_string(1.e+4).toStdString());
+    EXPECT_EQ(std::string("1.265e+12"), to_string(1.265e+12).toStdString());
+    EXPECT_EQ(std::string("1.266e+12"), to_string(1.26555e+12).toStdString());
+
+    decimals = 5;
+    EXPECT_EQ(std::string("1.23e-12"), to_string(1.23e-12).toStdString());
+    EXPECT_EQ(std::string("1.52346e-2"), to_string(1.523456e-2).toStdString());
+    EXPECT_EQ(std::string("1e-1"), to_string(9.999999e-2).toStdString());
+    EXPECT_EQ(std::string("1.12346"), to_string(1.123455).toStdString());
+    EXPECT_EQ(std::string("10.12346"), to_string(10.123456).toStdString());
+    EXPECT_EQ(std::string("99.9"), to_string(99.9).toStdString());
+    EXPECT_EQ(std::string("100"), to_string(99.999999).toStdString());
+    EXPECT_EQ(std::string("1.2345e+2"), to_string(123.45).toStdString());
+    EXPECT_EQ(std::string("1.26556e+12"), to_string(1.265556e+12).toStdString());
+}
+
+TEST_F(TestScientificSpinBox, testRound)
+{
+    auto round_3 = [](double val){return ScientificSpinBox::round(val, 3);};
+    EXPECT_DOUBLE_EQ(1.232e-12, round_3(1.2323e-12));
+    EXPECT_DOUBLE_EQ(0.1232, round_3(0.12323));
+    EXPECT_DOUBLE_EQ(1.002e+2, round_3(100.23));
+}
diff --git a/Tests/UnitTests/GUI/TestSessionItem.h b/Tests/UnitTests/GUI/TestSessionItem.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestSessionItem.h
rename to Tests/UnitTests/GUI/TestSessionItem.cpp
diff --git a/Tests/UnitTests/GUI/TestSessionItemController.h b/Tests/UnitTests/GUI/TestSessionItemController.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestSessionItemController.h
rename to Tests/UnitTests/GUI/TestSessionItemController.cpp
diff --git a/Tests/UnitTests/GUI/TestSessionItemData.h b/Tests/UnitTests/GUI/TestSessionItemData.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestSessionItemData.h
rename to Tests/UnitTests/GUI/TestSessionItemData.cpp
diff --git a/Tests/UnitTests/GUI/TestSessionItemTags.h b/Tests/UnitTests/GUI/TestSessionItemTags.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestSessionItemTags.h
rename to Tests/UnitTests/GUI/TestSessionItemTags.cpp
diff --git a/Tests/UnitTests/GUI/TestSessionItemUtils.h b/Tests/UnitTests/GUI/TestSessionItemUtils.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestSessionItemUtils.h
rename to Tests/UnitTests/GUI/TestSessionItemUtils.cpp
diff --git a/Tests/UnitTests/GUI/TestSessionModel.h b/Tests/UnitTests/GUI/TestSessionModel.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestSessionModel.h
rename to Tests/UnitTests/GUI/TestSessionModel.cpp
diff --git a/Tests/UnitTests/GUI/TestSessionXML.h b/Tests/UnitTests/GUI/TestSessionXML.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestSessionXML.h
rename to Tests/UnitTests/GUI/TestSessionXML.cpp
diff --git a/Tests/UnitTests/GUI/TestTranslations.h b/Tests/UnitTests/GUI/TestTranslations.cpp
similarity index 97%
rename from Tests/UnitTests/GUI/TestTranslations.h
rename to Tests/UnitTests/GUI/TestTranslations.cpp
index 51490aebcdd44eabbd897e23db0dde4d5f0eb0d2..42e6ae2d0bc784cf9f183596cba1ed812972626a 100644
--- a/Tests/UnitTests/GUI/TestTranslations.h
+++ b/Tests/UnitTests/GUI/TestTranslations.cpp
@@ -62,14 +62,14 @@ TEST_F(TestTranslations, test_BeamDistributionNone)
 
     SessionItem* distr = wavelength->getGroupItem(BeamDistributionItem::P_DISTRIBUTION);
     EXPECT_EQ(distr->modelType(), Constants::DistributionNoneType);
-    SessionItem* value = distr->getItem(DistributionNoneItem::P_VALUE);
+    SessionItem* value = distr->getItem(DistributionNoneItem::P_MEAN);
 
     EXPECT_EQ(ModelPath::itemPathTranslation(*value, instrument->parent()),
               QString("Instrument/Beam/Wavelength"));
 
     SessionItem* inclinationAngle = beam->getItem(BeamItem::P_INCLINATION_ANGLE);
     distr = inclinationAngle->getGroupItem(BeamDistributionItem::P_DISTRIBUTION);
-    value = distr->getItem(DistributionNoneItem::P_VALUE);
+    value = distr->getItem(DistributionNoneItem::P_MEAN);
 
     EXPECT_EQ(ModelPath::itemPathTranslation(*value, instrument->parent()),
               QString("Instrument/Beam/InclinationAngle"));
diff --git a/Tests/UnitTests/GUI/TestUpdateTimer.h b/Tests/UnitTests/GUI/TestUpdateTimer.cpp
similarity index 100%
rename from Tests/UnitTests/GUI/TestUpdateTimer.h
rename to Tests/UnitTests/GUI/TestUpdateTimer.cpp
diff --git a/Tests/UnitTests/GUI/test_utils.cpp b/Tests/UnitTests/GUI/test_utils.cpp
index 06c9a3ba72467cee072ad3c3461580743c8c97de..bc30e5e069bb9f16a27c1754edceb2a499ed514c 100644
--- a/Tests/UnitTests/GUI/test_utils.cpp
+++ b/Tests/UnitTests/GUI/test_utils.cpp
@@ -15,6 +15,8 @@
 
 #include "test_utils.h"
 #include "GUIHelpers.h"
+#include "IntensityDataIOFactory.h"
+#include "IntensityDataFunctions.h"
 #include "OutputData.h"
 #include "ProjectUtils.h"
 #include "RealDataItem.h"
@@ -52,3 +54,16 @@ RealDataItem* TestUtils::createRealData(const QString& name, SessionModel& model
     result->setItemValue(SessionItem::P_NAME, name);
     return result;
 }
+
+bool TestUtils::isTheSame(const OutputData<double>& data1, const OutputData<double>& data2)
+{
+    double diff = IntensityDataFunctions::getRelativeDifference(data1, data2);
+    return diff < 1e-10;
+}
+
+bool TestUtils::isTheSame(const QString& fileName, const OutputData<double>& data)
+{
+    std::unique_ptr<OutputData<double>> dataOnDisk(
+        IntensityDataIOFactory::readOutputData(fileName.toStdString()));
+    return isTheSame(*dataOnDisk, data);
+}
diff --git a/Tests/UnitTests/GUI/test_utils.h b/Tests/UnitTests/GUI/test_utils.h
index e406c814471de70b4fcee2d686c4690d551293d0..3bbde0ace1254e81f88cb2c907bec6f4e1852d66 100644
--- a/Tests/UnitTests/GUI/test_utils.h
+++ b/Tests/UnitTests/GUI/test_utils.h
@@ -67,6 +67,12 @@ T propertyFromXML(const QString& buffer) {
     return item->value().value<T>();
 }
 
+//! Helper function to test if data are the same.
+bool isTheSame(const OutputData<double>& data1, const OutputData<double>& data2);
+
+//! Helper function to check if file on disk represents same data.
+bool isTheSame(const QString& fileName, const OutputData<double>& data);
+
 }
 
 #endif // TEST_UTILS
diff --git a/Tests/UnitTests/Numeric/CMakeLists.txt b/Tests/UnitTests/Numeric/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f3fc2bb9fd801dcf94f0314f45ba362ba5564db1
--- /dev/null
+++ b/Tests/UnitTests/Numeric/CMakeLists.txt
@@ -0,0 +1,20 @@
+############################################################################
+# Core unit tests
+############################################################################
+set(test UnitTestNumeric)
+
+if(MSVC)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGTEST_LINKED_AS_SHARED_LIBRARY=1")
+endif()
+
+include_directories(${CMAKE_SOURCE_DIR}/Tests/UnitTests/utilities)
+
+file(GLOB source_files "*.cpp" "../utilities/TestAll.cpp")
+file(GLOB include_files "*.h")
+
+add_executable(${test} ${source_files} ${include_files})
+target_link_libraries(${test} ${BornAgainCore_LIBRARY} gtest)
+
+# Registering in ctest section
+add_test(${test} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${test})
+set_tests_properties(${test} PROPERTIES LABELS "Fullcheck")
diff --git a/Tests/UnitTests/Core/Numeric0/FormFactorSpecializationTest.h b/Tests/UnitTests/Numeric/FormFactorSpecializationTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Numeric0/FormFactorSpecializationTest.h
rename to Tests/UnitTests/Numeric/FormFactorSpecializationTest.cpp
diff --git a/Tests/UnitTests/Core/Numeric1/FormFactorSymmetryTest.h b/Tests/UnitTests/Numeric/FormFactorSymmetryTest.cpp
similarity index 100%
rename from Tests/UnitTests/Core/Numeric1/FormFactorSymmetryTest.h
rename to Tests/UnitTests/Numeric/FormFactorSymmetryTest.cpp
diff --git a/Tests/UnitTests/utilities/FormFactorTest.h b/Tests/UnitTests/Numeric/FormFactorTest.cpp
similarity index 52%
rename from Tests/UnitTests/utilities/FormFactorTest.h
rename to Tests/UnitTests/Numeric/FormFactorTest.cpp
index 9d6369a78b8735391d7b7cdb631a61b0c5a8c607..f74a7c0b2e57aff3e447b640eb2ddb3938130135 100644
--- a/Tests/UnitTests/utilities/FormFactorTest.h
+++ b/Tests/UnitTests/Numeric/FormFactorTest.cpp
@@ -1,12 +1,4 @@
-#include "google_test.h"
-#include "Vectors3D.h"
-#include "Complex.h"
-#include "gtest/internal/gtest-param-util.h"
-#include "HardParticles.h"
-
-using ::testing::Values;
-using ::testing::internal::ParamGenerator;
-using ::testing::Combine;
+#include "FormFactorTest.h"
 
 namespace TestData{
 
@@ -44,34 +36,5 @@ auto qlist = testing::Combine(
 
 }
 
-class FormFactorTest : public ::testing::Test
-{
-protected:
-    ~FormFactorTest();
-
-    template<typename T>
-    void test_all(double qmag1, double qmag2, T fun) {
-        for (auto it : gen) {
-            cvector_t qdir = std::get<0>(it);
-            cvector_t qdev = std::get<1>(it);
-            double    qmag = std::get<2>(it);
-            complex_t qeps = std::get<3>(it);
-            m_q = qmag * (qdir + qeps*qdev).unit();
-
-            if (skip_q(qmag1, qmag2))
-                continue;
-
-            fun();
-        }
-    }
-
-    bool skip_q( double qmag_begin=1e-99, double qmag_end=1e99 ) {
-        return m_q.mag()<=qmag_begin || m_q.mag()>=qmag_end;
-    }
-
-    cvector_t m_q;
-    static ParamGenerator<std::tuple<cvector_t, cvector_t, double, complex_t>> gen;
-};
-
 FormFactorTest::~FormFactorTest() = default;
 ParamGenerator<std::tuple<cvector_t, cvector_t, double, complex_t>> FormFactorTest::gen = TestData::qlist;
diff --git a/Tests/UnitTests/Numeric/FormFactorTest.h b/Tests/UnitTests/Numeric/FormFactorTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..9e048e49e8bb50e2ddec00eecbbbd56bc82c5551
--- /dev/null
+++ b/Tests/UnitTests/Numeric/FormFactorTest.h
@@ -0,0 +1,38 @@
+#include "google_test.h"
+#include "Vectors3D.h"
+#include "Complex.h"
+#include "gtest/internal/gtest-param-util.h"
+#include "HardParticles.h"
+
+using ::testing::Values;
+using ::testing::internal::ParamGenerator;
+using ::testing::Combine;
+
+class FormFactorTest : public ::testing::Test
+{
+protected:
+    ~FormFactorTest();
+
+    template<typename T>
+    void test_all(double qmag1, double qmag2, T fun) {
+        for (auto it : gen) {
+            cvector_t qdir = std::get<0>(it);
+            cvector_t qdev = std::get<1>(it);
+            double    qmag = std::get<2>(it);
+            complex_t qeps = std::get<3>(it);
+            m_q = qmag * (qdir + qeps*qdev).unit();
+
+            if (skip_q(qmag1, qmag2))
+                continue;
+
+            fun();
+        }
+    }
+
+    bool skip_q( double qmag_begin=1e-99, double qmag_end=1e99 ) {
+        return m_q.mag()<=qmag_begin || m_q.mag()>=qmag_end;
+    }
+
+    cvector_t m_q;
+    static ParamGenerator<std::tuple<cvector_t, cvector_t, double, complex_t>> gen;
+};
diff --git a/Tests/UnitTests/utilities/main_testlist.cpp b/Tests/UnitTests/utilities/TestAll.cpp
similarity index 88%
rename from Tests/UnitTests/utilities/main_testlist.cpp
rename to Tests/UnitTests/utilities/TestAll.cpp
index a960ffb96c807707c9a60a48995ce0d5e6bc6814..46186b6aa12e578df9818aaf867d09ebcd0f5848 100644
--- a/Tests/UnitTests/utilities/main_testlist.cpp
+++ b/Tests/UnitTests/utilities/TestAll.cpp
@@ -1,5 +1,4 @@
 #include "google_test.h"
-#include "testlist.h"
 
 int main(int argc, char** argv)
 {
diff --git a/Tests/UnitTests/utilities/google_test.h b/Tests/UnitTests/utilities/google_test.h
index a0757d8afa7edbf9b75291170006e9d79c956eb3..abbc51a3adc43dda6479d5d1bceb07d26a1a190d 100644
--- a/Tests/UnitTests/utilities/google_test.h
+++ b/Tests/UnitTests/utilities/google_test.h
@@ -14,5 +14,7 @@
 #include <gtest/gtest.h>
 #endif
 
+#include <memory>
+
 #endif
 
diff --git a/ThirdParty/Fit/RootMinimizers/CMakeLists.txt b/ThirdParty/Fit/RootMinimizers/CMakeLists.txt
index 3fc5047b640cecb615888b1b48a8ed75a38729f1..d61e64d209ba77978af1c41054e11c93291a149b 100644
--- a/ThirdParty/Fit/RootMinimizers/CMakeLists.txt
+++ b/ThirdParty/Fit/RootMinimizers/CMakeLists.txt
@@ -10,8 +10,6 @@ set(include_dirs
     ${CMAKE_CURRENT_SOURCE_DIR}/mathcore
 )
 
-include_directories(${include_dirs})
-
 file(GLOB source_files
     "Minuit2/*.cxx"
     "mathcore/*.cxx"
@@ -46,7 +44,6 @@ set(${library_name}_INCLUDE_DIRS ${include_dirs} CACHE INTERNAL "")
 set(${library_name}_LIBRARY ${library_name} CACHE INTERNAL "")
 
 # --- external dependencies ---
-include_directories(${GSL_INCLUDE_DIR})
-target_link_libraries(${library_name} ${GSL_LIBRARIES})
-
-include_directories(${Boost_INCLUDE_DIRS})
+target_include_directories(${library_name} PUBLIC ${GSL_INCLUDE_DIR} ${Boost_INCLUDE_DIRS})
+target_link_libraries(${library_name} ${GSL_LIBRARIES} ${Boost_LIBRARIES})
+target_include_directories(${library_name} PUBLIC ${include_dirs})
diff --git a/ThirdParty/Fit/RootMinimizers/TMVA/MsgLogger.h b/ThirdParty/Fit/RootMinimizers/TMVA/MsgLogger.h
index c9b1ccae3edb6d297a48e225bdbf6ccdf20b0389..d76a9f39b37adc156ca7905bb8a1aa81cf096466 100644
--- a/ThirdParty/Fit/RootMinimizers/TMVA/MsgLogger.h
+++ b/ThirdParty/Fit/RootMinimizers/TMVA/MsgLogger.h
@@ -43,8 +43,8 @@ class MsgLogger : public std::ostringstream, public TObject
 {
 
 public:
-    MsgLogger(const std::string& source, EMsgType minType = kINFO)
-        : fStrSource(source), fminType(minType)
+    MsgLogger(const std::string& source)
+        : fStrSource(source)
     {
     }
 
@@ -64,7 +64,6 @@ public:
 
 private:
     std::string fStrSource;
-    EMsgType fminType;
 };
 
 inline MsgLogger& MsgLogger::operator<<(MsgLogger& (*_f)(MsgLogger&)) { return (_f)(*this); }
diff --git a/ThirdParty/GUI/qcustomplot/CMakeLists.txt b/ThirdParty/GUI/qcustomplot/CMakeLists.txt
index 1d73689015f7e7f852627ad6639c72e95eb6e202..21d5d4ac20e076464d6ebd751b7b61c9520b468f 100644
--- a/ThirdParty/GUI/qcustomplot/CMakeLists.txt
+++ b/ThirdParty/GUI/qcustomplot/CMakeLists.txt
@@ -1,12 +1,6 @@
 ############################################################################
 # CMakeLists.txt file for building qcustomplot static library
 ############################################################################
-if(POLICY CMP0020)
-    cmake_policy(SET CMP0020 NEW)
-endif()
-if(POLICY CMP0043)
-    cmake_policy(SET CMP0043 NEW)
-endif()
 set(library_name qcustomplot)
 
 set(source_files qcustomplot.h qcustomplot.cpp)
diff --git a/ThirdParty/GUI/qt-manhattan-style/CMakeLists.txt b/ThirdParty/GUI/qt-manhattan-style/CMakeLists.txt
index 9ec5be50c29a7cbe60900e9ec51c68e96ff625a8..24fdaa55cc42db28d661d829f9951025b73c0a8e 100644
--- a/ThirdParty/GUI/qt-manhattan-style/CMakeLists.txt
+++ b/ThirdParty/GUI/qt-manhattan-style/CMakeLists.txt
@@ -1,16 +1,6 @@
 ############################################################################
 # CMakeLists.txt file for building libManhattanStyle
 ############################################################################
-if(POLICY CMP0020)
-    cmake_policy(SET CMP0020 NEW)
-endif()
-if(POLICY CMP0043)
-    cmake_policy(SET CMP0043 NEW)
-endif()
-if(POLICY CMP0071)
-  cmake_policy(SET CMP0071 NEW)
-endif()
-
 set(library_name ManhattanStyle)
 
 set(SRCS
diff --git a/ThirdParty/GUI/qt-manhattan-style/fancymainwindow.cpp b/ThirdParty/GUI/qt-manhattan-style/fancymainwindow.cpp
index eec96e4f63d2ec17a93d76bc30643f149307147b..67e112bbc90479095dda7abe73dec4f4556442f7 100644
--- a/ThirdParty/GUI/qt-manhattan-style/fancymainwindow.cpp
+++ b/ThirdParty/GUI/qt-manhattan-style/fancymainwindow.cpp
@@ -1,7 +1,7 @@
 /****************************************************************************
 **
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
 **
 ** This file is part of Qt Creator.
 **
@@ -9,21 +9,17 @@
 ** Licensees holding valid commercial Qt licenses may use this file in
 ** accordance with the commercial license agreement provided with the
 ** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia.  For licensing terms and
-** conditions see http://qt.digia.com/licensing.  For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
 **
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights.  These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
 **
 ****************************************************************************/
 
@@ -31,67 +27,372 @@
 
 #include "qtcassert.h"
 
-#include <QList>
-#include <QHash>
-
-#include <QAction>
+#include <QAbstractButton>
+#include <QApplication>
 #include <QContextMenuEvent>
-#include <QMenu>
 #include <QDockWidget>
+#include <QHBoxLayout>
+#include <QLabel>
+#include <QMenu>
+#include <QPainter>
 #include <QSettings>
+#include <QStyle>
+#include <QStyleOption>
+#include <QTimer>
+#include <QToolButton>
+#include <algorithm>
+
+static const char AutoHideTitleBarsKey[] = "AutoHideTitleBars";
+static const char ShowCentralWidgetKey[] = "ShowCentralWidget";
+static const char StateKey[] = "State";
 
-static const char lockedKeyC[] = "Locked";
-static const char stateKeyC[] = "State";
 static const int settingsVersion = 2;
 static const char dockWidgetActiveState[] = "DockWidgetActiveState";
 
-namespace Manhattan {
-
-/*! \class Manhattan::FancyMainWindow
+namespace {
+QString stripAccelerator(const QString &text)
+{
+    QString res = text;
+    for (int index = res.indexOf('&'); index != -1; index = res.indexOf('&', index + 1))
+        res.remove(index, 1);
+    return res;
+}
+}
 
-    \brief MainWindow with dock widgets and additional "lock" functionality
-    (locking the dock widgets in place) and "reset layout" functionality.
+namespace Manhattan {
 
-    The dock actions and the additional actions should be accessible
-    in a Window-menu.
-*/
+class TitleBarWidget;
 
 struct FancyMainWindowPrivate
 {
-    FancyMainWindowPrivate();
+    FancyMainWindowPrivate(FancyMainWindow *parent);
 
-    bool m_locked;
-    bool m_handleDockVisibilityChanges;
+    FancyMainWindow *q;
 
+    bool m_handleDockVisibilityChanges;
+    QAction m_showCentralWidget;
     QAction m_menuSeparator1;
-    QAction m_toggleLockedAction;
     QAction m_menuSeparator2;
     QAction m_resetLayoutAction;
-    QDockWidget *m_toolBarDockWidget;
+    QAction m_autoHideTitleBars;
 };
 
-FancyMainWindowPrivate::FancyMainWindowPrivate() :
-    m_locked(true),
+class DockWidget : public QDockWidget
+{
+public:
+    DockWidget(QWidget *inner, FancyMainWindow *parent, bool immutable = false);
+
+    bool eventFilter(QObject *, QEvent *event) override;
+    void enterEvent(QEvent *event) override;
+    void leaveEvent(QEvent *event) override;
+    void handleMouseTimeout();
+    void handleToplevelChanged(bool floating);
+
+    FancyMainWindow *q;
+
+private:
+    QPoint m_startPos;
+    TitleBarWidget *m_titleBar;
+    QTimer m_timer;
+    bool m_immutable = false;
+};
+
+// Stolen from QDockWidgetTitleButton
+class DockWidgetTitleButton : public QAbstractButton
+{
+public:
+    DockWidgetTitleButton(QWidget *parent)
+        : QAbstractButton(parent)
+    {
+        setFocusPolicy(Qt::NoFocus);
+    }
+
+    QSize sizeHint() const override
+    {
+        ensurePolished();
+
+        int size = 2*style()->pixelMetric(QStyle::PM_DockWidgetTitleBarButtonMargin, nullptr, this);
+        if (!icon().isNull()) {
+            int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize, nullptr, this);
+            QSize sz = icon().actualSize(QSize(iconSize, iconSize));
+            size += qMax(sz.width(), sz.height());
+        }
+
+        return QSize(size, size);
+    }
+
+    QSize minimumSizeHint() const override { return sizeHint(); }
+
+    void enterEvent(QEvent *event) override
+    {
+        if (isEnabled())
+            update();
+        QAbstractButton::enterEvent(event);
+    }
+
+    void leaveEvent(QEvent *event) override
+    {
+        if (isEnabled())
+            update();
+        QAbstractButton::leaveEvent(event);
+    }
+
+    void paintEvent(QPaintEvent *event) override;
+};
+
+void DockWidgetTitleButton::paintEvent(QPaintEvent *)
+{
+    QPainter p(this);
+
+    QStyleOptionToolButton opt;
+    opt.init(this);
+    opt.state |= QStyle::State_AutoRaise;
+    opt.icon = icon();
+    opt.subControls = nullptr;
+    opt.activeSubControls = nullptr;
+    opt.features = QStyleOptionToolButton::None;
+    opt.arrowType = Qt::NoArrow;
+    int size = style()->pixelMetric(QStyle::PM_SmallIconSize, nullptr, this);
+    opt.iconSize = QSize(size, size);
+    style()->drawComplexControl(QStyle::CC_ToolButton, &opt, &p, this);
+}
+
+class TitleBarWidget : public QWidget
+{
+public:
+    TitleBarWidget(DockWidget *parent, const QStyleOptionDockWidget &opt)
+      : QWidget(parent), q(parent), m_active(true)
+    {
+        m_titleLabel = new QLabel(this);
+
+        m_floatButton = new DockWidgetTitleButton(this);
+        m_floatButton->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarNormalButton, &opt, q));
+        m_floatButton->setToolTip("Undocks and re-attaches the dock widget");
+
+        m_closeButton = new DockWidgetTitleButton(this);
+        m_closeButton->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarCloseButton, &opt, q));
+        m_closeButton->setToolTip("Closes the dock widget");
+
+#ifndef QT_NO_ACCESSIBILITY
+        m_floatButton->setAccessibleName(QDockWidget::tr("Float"));
+        m_floatButton->setAccessibleDescription(QDockWidget::tr("Undocks and re-attaches the dock widget"));
+        m_closeButton->setAccessibleName(QDockWidget::tr("Close"));
+        m_closeButton->setAccessibleDescription(QDockWidget::tr("Closes the dock widget"));
+#endif
+
+        setActive(false);
+
+        const int minWidth = 10;
+        const int maxWidth = 10000;
+        const int inactiveHeight = 0;
+        const int activeHeight = m_closeButton->sizeHint().height() + 2;
+
+        m_minimumInactiveSize = QSize(minWidth, inactiveHeight);
+        m_maximumInactiveSize = QSize(maxWidth, inactiveHeight);
+        m_minimumActiveSize   = QSize(minWidth, activeHeight);
+        m_maximumActiveSize   = QSize(maxWidth, activeHeight);
+
+        auto layout = new QHBoxLayout(this);
+        layout->setMargin(0);
+        layout->setSpacing(0);
+        layout->setContentsMargins(4, 0, 0, 0);
+        layout->addWidget(m_titleLabel);
+        layout->addStretch();
+        layout->addWidget(m_floatButton);
+        layout->addWidget(m_closeButton);
+        setLayout(layout);
+
+        setProperty("managed_titlebar", 1);
+    }
+
+    void enterEvent(QEvent *event) override
+    {
+        setActive(true);
+        QWidget::enterEvent(event);
+    }
+
+    void setActive(bool on)
+    {
+        m_active = on;
+        updateChildren();
+    }
+
+    void updateChildren()
+    {
+        bool clickable = isClickable();
+        m_titleLabel->setVisible(clickable);
+        m_floatButton->setVisible(clickable);
+        m_closeButton->setVisible(clickable);
+    }
+
+    bool isClickable() const
+    {
+        return m_active || !q->q->autoHideTitleBars();
+    }
+
+    QSize sizeHint() const override
+    {
+        ensurePolished();
+        return isClickable() ? m_maximumActiveSize : m_maximumInactiveSize;
+    }
+
+    QSize minimumSizeHint() const override
+    {
+        ensurePolished();
+        return isClickable() ? m_minimumActiveSize : m_minimumInactiveSize;
+    }
+
+private:
+    DockWidget *q;
+    bool m_active;
+    QSize m_minimumActiveSize;
+    QSize m_maximumActiveSize;
+    QSize m_minimumInactiveSize;
+    QSize m_maximumInactiveSize;
+
+public:
+    QLabel *m_titleLabel;
+    DockWidgetTitleButton *m_floatButton;
+    DockWidgetTitleButton *m_closeButton;
+};
+
+DockWidget::DockWidget(QWidget *inner, FancyMainWindow *parent, bool immutable)
+    : QDockWidget(parent), q(parent), m_immutable(immutable)
+{
+    setWidget(inner);
+    setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable);
+    setObjectName(inner->objectName() + QLatin1String("DockWidget"));
+    setMouseTracking(true);
+
+    QString title = inner->windowTitle();
+    toggleViewAction()->setProperty("original_title", title);
+    title = stripAccelerator(title);
+    setWindowTitle(title);
+
+    QStyleOptionDockWidget opt;
+    initStyleOption(&opt);
+    m_titleBar = new TitleBarWidget(this, opt);
+    m_titleBar->m_titleLabel->setText(title);
+    setTitleBarWidget(m_titleBar);
+
+    if (immutable)
+        return;
+
+    m_timer.setSingleShot(true);
+    m_timer.setInterval(500);
+
+    connect(&m_timer, &QTimer::timeout, this, &DockWidget::handleMouseTimeout);
+
+    connect(this, &QDockWidget::topLevelChanged, this, &DockWidget::handleToplevelChanged);
+
+    connect(toggleViewAction(), &QAction::triggered,
+            [this]() {
+                if (isVisible())
+                    raise();
+            });
+
+    auto origFloatButton = findChild<QAbstractButton *>(QLatin1String("qt_dockwidget_floatbutton"));
+    connect(m_titleBar->m_floatButton, &QAbstractButton::clicked,
+            origFloatButton, &QAbstractButton::clicked);
+
+    auto origCloseButton = findChild<QAbstractButton *>(QLatin1String("qt_dockwidget_closebutton"));
+    connect(m_titleBar->m_closeButton, &QAbstractButton::clicked,
+            origCloseButton, &QAbstractButton::clicked);
+}
+
+bool DockWidget::eventFilter(QObject *, QEvent *event)
+{
+    if (!m_immutable && event->type() == QEvent::MouseMove && q->autoHideTitleBars()) {
+        auto me = static_cast<QMouseEvent *>(event);
+        int y = me->pos().y();
+        int x = me->pos().x();
+        int h = qMin(8, m_titleBar->m_floatButton->height());
+        if (!isFloating() && widget() && 0 <= x && x < widget()->width() && 0 <= y && y <= h) {
+            m_timer.start();
+            m_startPos = mapToGlobal(me->pos());
+        }
+    }
+    return false;
+}
+
+void DockWidget::enterEvent(QEvent *event)
+{
+    if (!m_immutable)
+        QApplication::instance()->installEventFilter(this);
+    QDockWidget::enterEvent(event);
+}
+
+void DockWidget::leaveEvent(QEvent *event)
+{
+    if (!m_immutable) {
+        if (!isFloating()) {
+            m_timer.stop();
+            m_titleBar->setActive(false);
+        }
+        QApplication::instance()->removeEventFilter(this);
+    }
+    QDockWidget::leaveEvent(event);
+}
+
+void DockWidget::handleMouseTimeout()
+{
+    QPoint dist = m_startPos - QCursor::pos();
+    if (!isFloating() && dist.manhattanLength() < 4)
+        m_titleBar->setActive(true);
+}
+
+void DockWidget::handleToplevelChanged(bool floating)
+{
+    m_titleBar->setActive(floating);
+}
+
+
+
+/*! \class Utils::FancyMainWindow
+
+    \brief The FancyMainWindow class is a MainWindow with dock widgets and
+    additional "lock" functionality
+    (locking the dock widgets in place) and "reset layout" functionality.
+
+    The dock actions and the additional actions should be accessible
+    in a Window-menu.
+*/
+
+FancyMainWindowPrivate::FancyMainWindowPrivate(FancyMainWindow *parent) :
+    q(parent),
     m_handleDockVisibilityChanges(true),
-    m_menuSeparator1(0),
-    m_toggleLockedAction(FancyMainWindow::tr("Locked"), 0),
-    m_menuSeparator2(0),
-    m_resetLayoutAction(FancyMainWindow::tr("Reset to Default Layout"), 0),
-    m_toolBarDockWidget(0)
-{
-    m_toggleLockedAction.setCheckable(true);
-    m_toggleLockedAction.setChecked(m_locked);
+    m_showCentralWidget(FancyMainWindow::tr("Central Widget"), nullptr),
+    m_menuSeparator1(nullptr),
+    m_menuSeparator2(nullptr),
+    m_resetLayoutAction(FancyMainWindow::tr("Reset to Default Layout"), nullptr),
+    m_autoHideTitleBars(FancyMainWindow::tr("Automatically Hide View Title Bars"), nullptr)
+{
+    m_showCentralWidget.setCheckable(true);
+    m_showCentralWidget.setChecked(true);
+
     m_menuSeparator1.setSeparator(true);
     m_menuSeparator2.setSeparator(true);
+
+    m_autoHideTitleBars.setCheckable(true);
+    m_autoHideTitleBars.setChecked(true);
+
+    QObject::connect(&m_autoHideTitleBars, &QAction::toggled, q, [this](bool) {
+        for (QDockWidget *dock : q->dockWidgets()) {
+            if (auto titleBar = dynamic_cast<TitleBarWidget *>(dock->titleBarWidget()))
+                titleBar->updateChildren();
+        }
+    });
+
+    QObject::connect(&m_showCentralWidget, &QAction::toggled, q, [this](bool visible) {
+        q->centralWidget()->setVisible(visible);
+    });
 }
 
 FancyMainWindow::FancyMainWindow(QWidget *parent) :
-    QMainWindow(parent), d(new FancyMainWindowPrivate)
+    QMainWindow(parent), d(new FancyMainWindowPrivate(this))
 {
-    connect(&d->m_toggleLockedAction, SIGNAL(toggled(bool)),
-            this, SLOT(setLocked(bool)));
-    connect(&d->m_resetLayoutAction, SIGNAL(triggered()),
-            this, SIGNAL(resetLayout()));
+    connect(&d->m_resetLayoutAction, &QAction::triggered,
+            this, &FancyMainWindow::resetLayout);
 }
 
 FancyMainWindow::~FancyMainWindow()
@@ -99,90 +400,51 @@ FancyMainWindow::~FancyMainWindow()
     delete d;
 }
 
-QDockWidget *FancyMainWindow::addDockForWidget(QWidget *widget)
+QDockWidget *FancyMainWindow::addDockForWidget(QWidget *widget, bool immutable)
 {
-    QDockWidget *dockWidget = new QDockWidget(widget->windowTitle(), this);
-    dockWidget->setWidget(widget);
-    // Set an object name to be used in settings, derive from widget name
-    const QString objectName = widget->objectName();
-    if (objectName.isEmpty()) {
-        dockWidget->setObjectName(QLatin1String("dockWidget")
-                                  + QString::number(dockWidgets().size() + 1));
-    } else {
-        dockWidget->setObjectName(objectName + QLatin1String("DockWidget"));
-    }
-    connect(dockWidget->toggleViewAction(), SIGNAL(triggered()),
-        this, SLOT(onDockActionTriggered()), Qt::QueuedConnection);
-    connect(dockWidget, SIGNAL(visibilityChanged(bool)),
-            this, SLOT(onDockVisibilityChange(bool)));
-    connect(dockWidget, SIGNAL(topLevelChanged(bool)),
-            this, SLOT(onTopLevelChanged()));
-    dockWidget->setProperty(dockWidgetActiveState, true);
-    updateDockWidget(dockWidget);
-    return dockWidget;
-}
+    QTC_ASSERT(widget, return nullptr);
+    QTC_CHECK(widget->objectName().size());
+    QTC_CHECK(widget->windowTitle().size());
 
-void FancyMainWindow::updateDockWidget(QDockWidget *dockWidget)
-{
-    const QDockWidget::DockWidgetFeatures features =
-            (d->m_locked) ?
-            QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable :
-            QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetClosable
-                | QDockWidget::DockWidgetFloatable;
-    // for the debugger tool bar
-    if (dockWidget->property("managed_dockwidget").isNull()) {
-        QWidget *titleBarWidget = dockWidget->titleBarWidget();
-        if (d->m_locked && !titleBarWidget && !dockWidget->isFloating())
-            titleBarWidget = new QWidget(dockWidget);
-        else if ((!d->m_locked || dockWidget->isFloating()) && titleBarWidget) {
-            delete titleBarWidget;
-            titleBarWidget = 0;
-        }
-        dockWidget->setTitleBarWidget(titleBarWidget);
+    auto dockWidget = new DockWidget(widget, this, immutable);
+
+    if (!immutable) {
+        connect(dockWidget, &QDockWidget::visibilityChanged,
+            [this, dockWidget](bool visible) {
+                if (d->m_handleDockVisibilityChanges)
+                    dockWidget->setProperty(dockWidgetActiveState, visible);
+            });
+
+        connect(dockWidget->toggleViewAction(), &QAction::triggered,
+                this, &FancyMainWindow::onDockActionTriggered,
+                Qt::QueuedConnection);
+
+        dockWidget->setProperty(dockWidgetActiveState, true);
     }
-    dockWidget->setFeatures(features);
+
+    return dockWidget;
 }
 
 void FancyMainWindow::onDockActionTriggered()
 {
-    QDockWidget *dw = qobject_cast<QDockWidget *>(sender()->parent());
+    auto dw = qobject_cast<QDockWidget *>(sender()->parent());
     if (dw) {
         if (dw->isVisible())
             dw->raise();
     }
 }
 
-void FancyMainWindow::onDockVisibilityChange(bool visible)
-{
-    if (d->m_handleDockVisibilityChanges)
-        sender()->setProperty(dockWidgetActiveState, visible);
-}
-
-void FancyMainWindow::onTopLevelChanged()
-{
-    updateDockWidget(qobject_cast<QDockWidget*>(sender()));
-}
-
 void FancyMainWindow::setTrackingEnabled(bool enabled)
 {
     if (enabled) {
         d->m_handleDockVisibilityChanges = true;
-        foreach (QDockWidget *dockWidget, dockWidgets())
-            dockWidget->setProperty(dockWidgetActiveState,
-                                    dockWidget->isVisible());
+        for (QDockWidget *dockWidget : dockWidgets())
+            dockWidget->setProperty(dockWidgetActiveState, dockWidget->isVisible());
     } else {
         d->m_handleDockVisibilityChanges = false;
     }
 }
 
-void FancyMainWindow::setLocked(bool locked)
-{
-    d->m_locked = locked;
-    foreach (QDockWidget *dockWidget, dockWidgets()) {
-        updateDockWidget(dockWidget);
-    }
-}
-
 void FancyMainWindow::hideEvent(QHideEvent *event)
 {
     Q_UNUSED(event)
@@ -197,15 +459,15 @@ void FancyMainWindow::showEvent(QShowEvent *event)
 
 void FancyMainWindow::contextMenuEvent(QContextMenuEvent *event)
 {
-    QMenu *menu = createPopupMenu();
-    menu->exec(event->globalPos());
-    delete menu;
+    QMenu menu;
+    addDockActionsToMenu(&menu);
+    menu.exec(event->globalPos());
 }
 
 void FancyMainWindow::handleVisibilityChanged(bool visible)
 {
     d->m_handleDockVisibilityChanges = false;
-    foreach (QDockWidget *dockWidget, dockWidgets()) {
+    for (QDockWidget *dockWidget : dockWidgets()) {
         if (dockWidget->isFloating()) {
             dockWidget->setVisible(visible
                 && dockWidget->property(dockWidgetActiveState).toBool());
@@ -237,9 +499,11 @@ void FancyMainWindow::restoreSettings(const QSettings *settings)
 QHash<QString, QVariant> FancyMainWindow::saveSettings() const
 {
     QHash<QString, QVariant> settings;
-    settings.insert(QLatin1String(stateKeyC), saveState(settingsVersion));
-    settings.insert(QLatin1String(lockedKeyC), d->m_locked);
-    foreach (QDockWidget *dockWidget, dockWidgets()) {
+    settings.insert(QLatin1String(StateKey), saveState(settingsVersion));
+    settings.insert(QLatin1String(AutoHideTitleBarsKey),
+        d->m_autoHideTitleBars.isChecked());
+    settings.insert(ShowCentralWidgetKey, d->m_showCentralWidget.isChecked());
+    for (QDockWidget *dockWidget : dockWidgets()) {
         settings.insert(dockWidget->objectName(),
                 dockWidget->property(dockWidgetActiveState));
     }
@@ -248,55 +512,60 @@ QHash<QString, QVariant> FancyMainWindow::saveSettings() const
 
 void FancyMainWindow::restoreSettings(const QHash<QString, QVariant> &settings)
 {
-    QByteArray ba = settings.value(QLatin1String(stateKeyC),
-                                   QByteArray()).toByteArray();
+    QByteArray ba = settings.value(QLatin1String(StateKey), QByteArray()).toByteArray();
     if (!ba.isEmpty())
         restoreState(ba, settingsVersion);
-    d->m_locked = settings.value(QLatin1String("Locked"), true).toBool();
-    d->m_toggleLockedAction.setChecked(d->m_locked);
-    foreach (QDockWidget *widget, dockWidgets()) {
+    bool on = settings.value(QLatin1String(AutoHideTitleBarsKey), true).toBool();
+    d->m_autoHideTitleBars.setChecked(on);
+    d->m_showCentralWidget.setChecked(settings.value(ShowCentralWidgetKey, true).toBool());
+    for (QDockWidget *widget : dockWidgets()) {
         widget->setProperty(dockWidgetActiveState,
             settings.value(widget->objectName(), false));
     }
 }
 
-QList<QDockWidget *> FancyMainWindow::dockWidgets() const
+const QList<QDockWidget *> FancyMainWindow::dockWidgets() const
 {
-    return this->findChildren<QDockWidget *>();
+    return findChildren<QDockWidget *>();
 }
 
-bool FancyMainWindow::isLocked() const
+bool FancyMainWindow::autoHideTitleBars() const
 {
-    return d->m_locked;
+    return d->m_autoHideTitleBars.isChecked();
 }
 
-static bool actionLessThan(const QAction *action1, const QAction *action2)
+QMenu* FancyMainWindow::createPopupMenu()
 {
-    QTC_ASSERT(action1, return true);
-    QTC_ASSERT(action2, return false);
-    return action1->text().toLower() < action2->text().toLower();
+    QMenu *menu = new QMenu(this);
+    addDockActionsToMenu(menu);
+    return menu;
 }
 
-QMenu *FancyMainWindow::createPopupMenu()
+void FancyMainWindow::addDockActionsToMenu(QMenu *menu)
 {
     QList<QAction *> actions;
-    QList<QDockWidget *> dockwidgets = this->findChildren<QDockWidget *>();
+    QList<QDockWidget *> dockwidgets = findChildren<QDockWidget *>();
     for (int i = 0; i < dockwidgets.size(); ++i) {
         QDockWidget *dockWidget = dockwidgets.at(i);
         if (dockWidget->property("managed_dockwidget").isNull()
                 && dockWidget->parentWidget() == this) {
-            actions.append(dockwidgets.at(i)->toggleViewAction());
+            QAction *action = dockWidget->toggleViewAction();
+            action->setText(action->property("original_title").toString());
+            actions.append(action);
         }
     }
-    qSort(actions.begin(), actions.end(), actionLessThan);
-    QMenu *menu = new QMenu(this);
+    std::sort(actions.begin(), actions.end(), [](const QAction *action1, const QAction *action2) {
+        QTC_ASSERT(action1, return true);
+        QTC_ASSERT(action2, return false);
+        return stripAccelerator(action1->text()).toLower() < stripAccelerator(action2->text()).toLower();
+    });
     foreach (QAction *action, actions)
         menu->addAction(action);
+    menu->addAction(&d->m_showCentralWidget);
     menu->addAction(&d->m_menuSeparator1);
-    menu->addAction(&d->m_toggleLockedAction);
+    menu->addAction(&d->m_autoHideTitleBars);
     menu->addAction(&d->m_menuSeparator2);
     menu->addAction(&d->m_resetLayoutAction);
-    return menu;
 }
 
 QAction *FancyMainWindow::menuSeparator1() const
@@ -304,9 +573,9 @@ QAction *FancyMainWindow::menuSeparator1() const
     return &d->m_menuSeparator1;
 }
 
-QAction *FancyMainWindow::toggleLockedAction() const
+QAction *FancyMainWindow::autoHideTitleBarsAction() const
 {
-    return &d->m_toggleLockedAction;
+    return &d->m_autoHideTitleBars;
 }
 
 QAction *FancyMainWindow::menuSeparator2() const
@@ -319,24 +588,20 @@ QAction *FancyMainWindow::resetLayoutAction() const
     return &d->m_resetLayoutAction;
 }
 
+QAction *FancyMainWindow::showCentralWidgetAction() const
+{
+    return &d->m_showCentralWidget;
+}
+
 void FancyMainWindow::setDockActionsVisible(bool v)
 {
-    foreach (const QDockWidget *dockWidget, dockWidgets())
+    for (const QDockWidget *dockWidget : dockWidgets())
         dockWidget->toggleViewAction()->setVisible(v);
-    d->m_toggleLockedAction.setVisible(v);
+    d->m_showCentralWidget.setVisible(v);
+    d->m_autoHideTitleBars.setVisible(v);
     d->m_menuSeparator1.setVisible(v);
     d->m_menuSeparator2.setVisible(v);
     d->m_resetLayoutAction.setVisible(v);
 }
 
-QDockWidget *FancyMainWindow::toolBarDockWidget() const
-{
-    return d->m_toolBarDockWidget;
-}
-
-void FancyMainWindow::setToolBarDockWidget(QDockWidget *dock)
-{
-    d->m_toolBarDockWidget = dock;
-}
-
-} // namespace Manhattan
+} // namespace Utils
diff --git a/ThirdParty/GUI/qt-manhattan-style/fancymainwindow.h b/ThirdParty/GUI/qt-manhattan-style/fancymainwindow.h
index 4c284489d6f1c856e69a90d68e6e8e665418ab08..3d2f3bbffd5623764a2f695865efade501670e86 100644
--- a/ThirdParty/GUI/qt-manhattan-style/fancymainwindow.h
+++ b/ThirdParty/GUI/qt-manhattan-style/fancymainwindow.h
@@ -1,7 +1,7 @@
 /****************************************************************************
 **
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
 **
 ** This file is part of Qt Creator.
 **
@@ -9,21 +9,17 @@
 ** Licensees holding valid commercial Qt licenses may use this file in
 ** accordance with the commercial license agreement provided with the
 ** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia.  For licensing terms and
-** conditions see http://qt.digia.com/licensing.  For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
 **
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights.  These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
 **
 ****************************************************************************/
 
@@ -47,16 +43,15 @@ class QTMANHATTANSTYLESHARED_EXPORT FancyMainWindow : public QMainWindow
     Q_OBJECT
 
 public:
-    explicit FancyMainWindow(QWidget *parent = 0);
-    virtual ~FancyMainWindow();
+    explicit FancyMainWindow(QWidget *parent = nullptr);
+    ~FancyMainWindow() override;
 
     /* The widget passed in should have an objectname set
      * which will then be used as key for QSettings. */
-    QDockWidget *addDockForWidget(QWidget *widget);
-    QList<QDockWidget *> dockWidgets() const;
+    QDockWidget *addDockForWidget(QWidget *widget, bool immutable = false);
+    const QList<QDockWidget *> dockWidgets() const;
 
     void setTrackingEnabled(bool enabled);
-    bool isLocked() const;
 
     void saveSettings(QSettings *settings) const;
     void restoreSettings(const QSettings *settings);
@@ -65,16 +60,15 @@ public:
 
     // Additional context menu actions
     QAction *menuSeparator1() const;
-    QAction *toggleLockedAction() const;
+    QAction *autoHideTitleBarsAction() const;
     QAction *menuSeparator2() const;
     QAction *resetLayoutAction() const;
+    QAction *showCentralWidgetAction() const;
+    void addDockActionsToMenu(QMenu *menu);
 
-    // Overwritten to add locked/reset.
-    virtual QMenu *createPopupMenu();
-
+    bool autoHideTitleBars() const;
 
-    QDockWidget *toolBarDockWidget() const;
-    void setToolBarDockWidget(QDockWidget *dock);
+    QMenu *createPopupMenu() override;
 
 signals:
     // Emitted by resetLayoutAction(). Connect to a slot
@@ -82,25 +76,21 @@ signals:
     void resetLayout();
 
 public slots:
-    void setLocked(bool locked);
     void setDockActionsVisible(bool v);
 
 protected:
-    void hideEvent(QHideEvent *event);
-    void showEvent(QShowEvent *event);
-    void contextMenuEvent(QContextMenuEvent *event);
-private slots:
-    void onDockActionTriggered();
-    void onDockVisibilityChange(bool);
-    void onTopLevelChanged();
+    void hideEvent(QHideEvent *event) override;
+    void showEvent(QShowEvent *event) override;
+    void contextMenuEvent(QContextMenuEvent *event) override;
 
 private:
-    void updateDockWidget(QDockWidget *dockWidget);
+    void onDockActionTriggered();
+
     void handleVisibilityChanged(bool visible);
 
     FancyMainWindowPrivate *d;
 };
 
-} // namespace Manhattan
+} // namespace Utils
 
-#endif // FANCYMAINWINDOW_H
+#endif
diff --git a/ThirdParty/common/gtest/CMakeLists.txt b/ThirdParty/common/gtest/CMakeLists.txt
index 61ea39b6f5c36d4968e68821df7f3bfa42d60b40..3d7abaf296c0efc829b55ff87de479f74a637df5 100644
--- a/ThirdParty/common/gtest/CMakeLists.txt
+++ b/ThirdParty/common/gtest/CMakeLists.txt
@@ -1,12 +1,10 @@
 ############################################################################
 # CMakeLists.txt file for building gtest library
 ############################################################################
-if(POLICY CMP0042)
-    cmake_policy(SET CMP0042 NEW)
-endif()
-
-if(MSVC)
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_VARIADIC_MAX=10 /wd4100 /wd4275")
+# instructs CMake to consider libgtest.so as our project library (inspite of the fact, that
+# it is not installed) and to provide @rpath instead of hardcoded links.
+if(APPLE)
+   set(CMAKE_MACOSX_RPATH 1)
 endif()
 
 option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." ON)
diff --git a/VERSION.cmake b/VERSION.cmake
index 01979d50857f757d038f60fe57695fb28d70d2fc..d1245c21a4681e0134db57c29452a720800f1512 100644
--- a/VERSION.cmake
+++ b/VERSION.cmake
@@ -1,3 +1,3 @@
 set(BornAgain_VERSION_MAJOR 1)
-set(BornAgain_VERSION_MINOR 13)
+set(BornAgain_VERSION_MINOR 14)
 set(BornAgain_VERSION_PATCH 0)
diff --git a/Wrap/python/plot_utils.py b/Wrap/python/plot_utils.py
index 5f07dc7f45a512a169409f593e74cee61d73cd04..b1d0fba48c4f3ca5ee44b31492b9fffe397a0aaa 100644
--- a/Wrap/python/plot_utils.py
+++ b/Wrap/python/plot_utils.py
@@ -15,7 +15,6 @@
 from __future__ import print_function
 import bornagain as ba
 from bornagain import deg as deg
-from bornagain import IFitObserver as IFitObserver
 try:  # workaround for build servers
     import numpy as np
     from matplotlib import pyplot as plt
@@ -84,12 +83,13 @@ def get_axes_labels(result, units):
 
 
 def plot_array(array, zmin=None, zmax=None, xlabel=None, ylabel=None, zlabel=None,
-               title=None, axes_limits=None):
+               title=None, axes_limits=None, aspect=None):
     """
     Plots numpy array as a colormap in log scale.
     """
 
     zlabel = "Intensity" if zlabel is None else zlabel
+    aspect = 'auto' if aspect is None else aspect
 
     zmax = np.amax(array) if zmax is None else zmax
     zmin = 1e-6*zmax if zmin is None else zmin
@@ -99,7 +99,7 @@ def plot_array(array, zmin=None, zmax=None, xlabel=None, ylabel=None, zlabel=Non
     else:
         norm = colors.LogNorm(zmin, zmax)
 
-    im = plt.imshow(array, norm=norm, extent=axes_limits, aspect='auto')
+    im = plt.imshow(array, norm=norm, extent=axes_limits, aspect=aspect)
     cb = plt.colorbar(im, pad=0.025)
 
     if xlabel:
@@ -116,12 +116,13 @@ def plot_array(array, zmin=None, zmax=None, xlabel=None, ylabel=None, zlabel=Non
 
 
 def plot_histogram(hist, zmin=None, zmax=None, xlabel=None, ylabel=None, zlabel=None,
-                  title=None):
+                  title=None, aspect=None):
     """
     Plots intensity data as color map
     :param intensity: Histogram2D object obtained from GISASSimulation
     :param zmin: Min value on amplitude's color bar
     :param zmax: Max value on amplitude's color bar
+    :param aspect: 'auto' (default) or 'equal'
     """
 
     if not xlabel:
@@ -134,12 +135,12 @@ def plot_histogram(hist, zmin=None, zmax=None, xlabel=None, ylabel=None, zlabel=
                    hist.getYmin(), hist.getYmax()]
 
     plot_array(hist.array(), zmin=zmin, zmax=zmax, xlabel=xlabel, ylabel=ylabel,
-               zlabel=zlabel, title=title, axes_limits=axes_limits)
+               zlabel=zlabel, title=title, axes_limits=axes_limits, aspect=aspect)
 
 
 def plot_colormap(result, zmin=None, zmax=None, units=ba.AxesUnits.DEFAULT,
                   xlabel=None, ylabel=None, zlabel=None,
-                  title=None):
+                  title=None, aspect=None):
     """
     Plots intensity data as color map
     :param result: SimulationResult from GISAS/OffSpecSimulation
@@ -153,7 +154,7 @@ def plot_colormap(result, zmin=None, zmax=None, units=ba.AxesUnits.DEFAULT,
     ylabel = axes_labels[1] if ylabel is None else ylabel
 
     plot_array(result.array(), zmin=zmin, zmax=zmax, xlabel=xlabel, ylabel=ylabel,
-               zlabel=zlabel, title=title, axes_limits=axes_limits)
+               zlabel=zlabel, title=title, axes_limits=axes_limits, aspect=aspect)
 
 
 def plot_specular_simulation_result(result, ymin=None, ymax=None, units=ba.AxesUnits.DEFAULT,
@@ -190,7 +191,7 @@ def plot_specular_simulation_result(result, ymin=None, ymax=None, units=ba.AxesU
 
 
 def plot_simulation_result(result, intensity_min=None, intensity_max=None, units=ba.AxesUnits.DEFAULT,
-                           postpone_show=False):
+                           xlabel=None, ylabel=None, postpone_show=False, title=None, aspect=None):
     """
     Draws simulation result and (optionally) shows the plot.
     :param result_: SimulationResult object obtained from GISAS/OffSpec/SpecularSimulation
@@ -198,21 +199,30 @@ def plot_simulation_result(result, intensity_min=None, intensity_max=None, units
     :param intensity_max: Max value on amplitude's axis or color bar
     :param units: units for plot axes
     :param postpone_show: postpone showing the plot for later tuning (False by default)
+    :param aspect: aspect ratio, 'auto' (default) or 'equal'
     """
     if len(result.array().shape) == 1:  # 1D data, specular simulation assumed
         plot_specular_simulation_result(result, intensity_min, intensity_max, units)
     else:
-        plot_colormap(result, intensity_min, intensity_max, units)
+        plot_colormap(result, intensity_min, intensity_max, units, xlabel, ylabel,
+                      title=title, aspect=aspect)
     plt.tight_layout()
     if not postpone_show:
         plt.show()
 
 
 class Plotter:
-    def __init__(self):
+    def __init__(self, zmin=None, zmax=None, xlabel=None, ylabel=None,
+                 units=ba.AxesUnits.DEFAULT, aspect=None):
 
         self._fig = plt.figure(figsize=(10.25, 7.69))
         self._fig.canvas.draw()
+        self._zmin = zmin
+        self._zmax = zmax
+        self._xlabel = xlabel
+        self._ylabel = ylabel
+        self._units = units
+        self._aspect = aspect
 
     def reset(self):
         self._fig.clf()
@@ -223,54 +233,9 @@ class Plotter:
 
 
 class PlotterGISAS(Plotter):
-    def __init__(self):
-        Plotter.__init__(self)
-
-    @staticmethod
-    def make_subplot(nplot):
-        plt.subplot(2, 2, nplot)
-        plt.subplots_adjust(wspace=0.2, hspace=0.2)
-
-    def plot(self, fit_suite):
-        Plotter.reset(self)
-
-        real_data = fit_suite.experimentalData()
-        sim_data = fit_suite.simulationResult()
-        diff = fit_suite.relativeDifference()
-
-        self.make_subplot(1)
-
-        # same limits for both plots
-        arr = real_data.array()
-        zmax = np.amax(arr)
-        zmin = zmax*1e-6
-
-        plot_colormap(real_data, title="\"Experimental\" data", zmin=zmin, zmax=zmax,
-                      xlabel='', ylabel='', zlabel='')
-
-        self.make_subplot(2)
-        plot_colormap(sim_data, title="Simulated data", zmin=zmin, zmax=zmax,
-                      xlabel='', ylabel='', zlabel='')
-
-        self.make_subplot(3)
-        plot_colormap(diff, title="Relative difference", zmin=0.001, zmax=10.0,
-                       xlabel='', ylabel='', zlabel='')
-
-        self.make_subplot(4)
-        plt.title('Parameters')
-        plt.axis('off')
-        plt.text(0.01, 0.85, "Iterations  " + '{:d}     {:s}'.
-                 format(fit_suite.numberOfIterations(), fit_suite.minimizerName()))
-        plt.text(0.01, 0.75, "Chi2       " + '{:8.4f}'.format(fit_suite.getChi2()))
-        for index, fitPar in enumerate(fit_suite.fitParameters()):
-            plt.text(0.01, 0.55 - index * 0.1, '{:30.30s}: {:6.3f}'.format(fitPar.name(), fitPar.value()))
-
-        Plotter.plot(self)
-
-
-class PlotterGISASV2(Plotter):
-    def __init__(self):
-        Plotter.__init__(self)
+    def __init__(self, zmin=None, zmax=None, xlabel=None, ylabel=None,
+                 units=ba.AxesUnits.DEFAULT, aspect=None):
+        Plotter.__init__(self, zmin, zmax, xlabel, ylabel, units, aspect)
 
     @staticmethod
     def make_subplot(nplot):
@@ -288,19 +253,22 @@ class PlotterGISASV2(Plotter):
 
         # same limits for both plots
         arr = real_data.array()
-        zmax = np.amax(arr)
-        zmin = zmax*1e-6
+        zmax = np.amax(arr) if self._zmax is None else self._zmax
+        zmin = zmax*1e-6 if self._zmin is None else self._zmin
 
-        ba.plot_colormap(real_data, title="\"Experimental\" data", zmin=zmin, zmax=zmax,
-                      xlabel='', ylabel='', zlabel='')
+        ba.plot_colormap(real_data, title="Experimental data", zmin=zmin, zmax=zmax,
+                         units=self._units, xlabel=self._xlabel, ylabel=self._ylabel,
+                         zlabel='', aspect=self._aspect)
 
         self.make_subplot(2)
         ba.plot_colormap(sim_data, title="Simulated data", zmin=zmin, zmax=zmax,
-                      xlabel='', ylabel='', zlabel='')
+                         units=self._units, xlabel=self._xlabel, ylabel=self._ylabel,
+                         zlabel='', aspect=self._aspect)
 
         self.make_subplot(3)
         ba.plot_colormap(diff, title="Relative difference", zmin=0.001, zmax=10.0,
-                       xlabel='', ylabel='', zlabel='')
+                         units=self._units, xlabel=self._xlabel, ylabel=self._ylabel,
+                         zlabel='', aspect=self._aspect)
 
         self.make_subplot(4)
         plt.title('Parameters')
@@ -518,36 +486,3 @@ class PlotterSpecular(Plotter):
         self.plot_table(fit_objective)
 
         Plotter.plot(self)
-
-
-class DefaultFitObserver(IFitObserver):
-    """
-    Draws fit progress every nth iteration. This class has to be attached to
-    FitSuite via attachObserver method.
-    FitSuite kernel will call DrawObserver's update() method every n'th iteration.
-    It is up to the user what to do here.
-    """
-    import sys
-    import traceback
-
-    def __init__(self, draw_every_nth=10, SimulationType='GISAS'):
-        """
-        Initializes observer
-        :param draw_every_nth: specifies when to output data, defaults to each 10th iteration
-        :param SimulationType: simulation type underlying fitting:
-            'GISAS' - GISAS simulation, default
-
-            'Specular' - specular simulation
-
-        """
-        IFitObserver.__init__(self, draw_every_nth)
-        if SimulationType is 'GISAS':
-            self._plotter = PlotterGISAS()
-        elif SimulationType is 'Specular':
-            self._plotter = PlotterSpecular_old()
-        else:
-            raise Exception("Unknown simulation type {:s}.".format(SimulationType))
-
-    def update(self, fit_suite):
-        self._plotter.plot(fit_suite)
-
diff --git a/Wrap/swig/directors.i b/Wrap/swig/directors.i
index 9480dd16475e4627d3365077c0f3929d99025ec9..9d072519b13f71cbdd894ea161b767d660a6109f 100644
--- a/Wrap/swig/directors.i
+++ b/Wrap/swig/directors.i
@@ -8,12 +8,11 @@
 %feature("director") ISample;
 %feature("director") IFormFactor;
 %feature("director") IFormFactorBorn;
-%feature("director") IFitObserver;
-%feature("director") IObservable;
 %feature("director") IInterferenceFunction;
 %feature("director") PyCallback;
 %feature("director") PyBuilderCallback;
 %feature("director") PyObserverCallback;
+%feature("director") FitObjective;
 
 // Propagate python exceptions
 // taken from
diff --git a/Wrap/swig/extendCore.i b/Wrap/swig/extendCore.i
index 4750bb011534b5af9131a172f34d77c9b29b7cfe..b12f6be1ce6f7217715ae598db73a9182a4df968 100644
--- a/Wrap/swig/extendCore.i
+++ b/Wrap/swig/extendCore.i
@@ -106,48 +106,6 @@ class ParameterPoolIterator(object):
 }
 };
 
-
-// FitParameterSet iterator
-
-%pythoncode %{
-class FitParameterSetIterator(object):
-
-    def __init__(self, fitParameters):
-        self.fitParameters = fitParameters
-        self.index = -1
-
-    def __iter__(self):
-        return self
-
-    def next(self):
-        self.index += 1
-        if self.index < self.fitParameters.size():
-            return self.fitParameters[self.index]
-        else:
-            raise StopIteration
-
-    def __next__(self):
-        return self.next()
-%}
-
-// FitParameterSet accessors
-
-%extend FitParameterSet {
-    const IFitParameter* __getitem__(std::string name) const
-    {
-        return (*($self))[name];
-    }
-    const IFitParameter* __getitem__(size_t index) const
-    {
-        return (*($self))[index];
-    }
-
-%pythoncode {
-    def __iter__(self):
-        return FitParameterSetIterator(self)
-}
-};
-
 %pythoncode %{
 class SimulationBuilderWrapper(PyBuilderCallback):
     def __init__(self, f):
@@ -182,7 +140,7 @@ class ObserverCallbackWrapper(PyObserverCallback):
 
 %extend FitObjective {
 %pythoncode %{
-    def addSimulationAndData(self, callback, data, weight):
+    def addSimulationAndData(self, callback, data, weight = 1.0):
         if not hasattr(self, 'callback_container'):
             self.callback_container = []
         wrp = SimulationBuilderWrapper(callback)
@@ -223,7 +181,7 @@ class ObserverCallbackWrapper(PyObserverCallback):
 
     def create_default_plotter(self):
         import plot_utils
-        self.m_plotter = plot_utils.PlotterGISASV2()
+        self.m_plotter = plot_utils.PlotterGISAS()
         return self.m_plotter.plot
 
     def initPlot(self, every_nth, callback = None):
diff --git a/Wrap/swig/ignores.i b/Wrap/swig/ignores.i
index bc91496a77cb48e53905173acdccb45e13fc43be..1263c43fdf48d68a52e41ff02e314684b2d96c20 100644
--- a/Wrap/swig/ignores.i
+++ b/Wrap/swig/ignores.i
@@ -41,11 +41,6 @@
 // ignored to avoid error (todo: check whether this is really necessary)
 %ignore Crystal::getTransformedLattice(const IRotation*) const;
 
-// taken from dev-tools/python-bindings/settings_fit.py
-%ignore FitSuite::setOptions(const FitOptions&);
-%ignore FitSuite::getOptions();
-
-
 // extra ignores for types and methods that shouldn't be visible in Python
 %ignore FormFactorDWBAPol;
 %ignore ISampleVisitor::visit(const FormFactorDWBAPol*);
diff --git a/Wrap/swig/libBornAgainCore.i b/Wrap/swig/libBornAgainCore.i
index 908b8d384915171264394b58a932eeac79017c6d..99e4406d9bbfc60c53f374b8316fa3148fcfb605 100644
--- a/Wrap/swig/libBornAgainCore.i
+++ b/Wrap/swig/libBornAgainCore.i
@@ -90,14 +90,7 @@
 #include "FTDecayFunctions.h"
 #include "FTDistributions1D.h"
 #include "FTDistributions2D.h"
-#include "FitObject.h"
 #include "FitOptions.h"
-#include "IFitParameter.h"
-#include "FitParameterSet.h"
-#include "FitParameter.h"
-#include "FitSuite.h"
-#include "FitSuiteImpl.h"
-#include "FitSuiteObjects.h"
 #include "PyFittingCallbacks.h"
 #include "FitObjective.h"
 #include "FixedBinAxis.h"
@@ -120,6 +113,7 @@
 #include "FormFactorGauss.h"
 #include "FormFactorHemiEllipsoid.h"
 #include "FormFactorIcosahedron.h"
+#include "FormFactorLongBox.h"
 #include "FormFactorLongBoxGauss.h"
 #include "FormFactorLongBoxLorentz.h"
 #include "FormFactorLongRipple1Gauss.h"
@@ -152,8 +146,6 @@
 #include "IClusteredParticles.h"
 #include "IDetector2D.h"
 #include "IDetectorResolution.h"
-#include "IFitObserver.h"
-#include "IFitStrategy.h"
 #include "IFormFactorDecorator.h"
 #include "IHistogram.h"
 #include "IIntensityFunction.h"
@@ -177,10 +169,11 @@
 #include "IntensityDataIOFactory.h"
 #include "InterferenceFunction1DLattice.h"
 #include "InterferenceFunction2DLattice.h"
-#include "InterferenceFunction3DLattice.h"
-#include "InterferenceFunctionFinite2DLattice.h"
 #include "InterferenceFunction2DParaCrystal.h"
 #include "InterferenceFunction2DSuperLattice.h"
+#include "InterferenceFunction3DLattice.h"
+#include "InterferenceFunctionFinite2DLattice.h"
+#include "InterferenceFunctionFinite3DLattice.h"
 #include "InterferenceFunctionNone.h"
 #include "InterferenceFunctionRadialParaCrystal.h"
 #include "IsGISAXSDetector.h"
@@ -233,8 +226,7 @@
 #include "IChiSquaredModule.h"
 #include "IIntensityFunction.h"
 #include "IIntensityNormalizer.h"
-#include "ISquaredFunction.h"
-#include "AdjustMinimizerStrategy.h"
+#include "VarianceFunctions.h"
 #include "IterationInfo.h"
 %}
 
@@ -317,23 +309,14 @@
 %include "ISample.h"
 %include "IChiSquaredModule.h"
 %include "IObserver.h"
-%include "IFitObserver.h"
-%include "IFitStrategy.h"
 %include "IIntensityFunction.h"
 %include "IIntensityNormalizer.h"
-%include "ISquaredFunction.h"
+%include "VarianceFunctions.h"
 %include "ChiSquaredModule.h"
-%include "FitObject.h"
 %include "FitOptions.h"
-%include "IFitParameter.h"
-%include "FitParameterSet.h"
-%include "FitParameter.h"
-%include "FitSuite.h"
-%include "FitSuiteObjects.h"
 %include "PyFittingCallbacks.h"
 %include "FitObjective.h"
 %include "MathFunctions.h"
-%include "AdjustMinimizerStrategy.h"
 %include "IFactory.h"
 %include "IMultiLayerBuilder.h"
 %include "INodeVisitor.h"
@@ -369,6 +352,7 @@
 %include "FormFactorGauss.h"
 %include "FormFactorHemiEllipsoid.h"
 %include "FormFactorIcosahedron.h"
+%include "FormFactorLongBox.h"
 %include "FormFactorLongBoxGauss.h"
 %include "FormFactorLongBoxLorentz.h"
 %include "FormFactorLongRipple1Gauss.h"
@@ -426,13 +410,14 @@
 %include "IntensityDataFunctions.h"
 %include "IntensityDataIOFactory.h"
 %include "InterferenceFunction1DLattice.h"
-%include "InterferenceFunctionRadialParaCrystal.h"
 %include "InterferenceFunction2DLattice.h"
+%include "InterferenceFunction2DParaCrystal.h"
+%include "InterferenceFunction2DSuperLattice.h"
 %include "InterferenceFunction3DLattice.h"
 %include "InterferenceFunctionFinite2DLattice.h"
-%include "InterferenceFunction2DSuperLattice.h"
-%include "InterferenceFunction2DParaCrystal.h"
+%include "InterferenceFunctionFinite3DLattice.h"
 %include "InterferenceFunctionNone.h"
+%include "InterferenceFunctionRadialParaCrystal.h"
 %include "IPixel.h"
 %include "SphericalDetector.h"
 %include "IsGISAXSDetector.h"
diff --git a/Wrap/swig/libBornAgainFit.i b/Wrap/swig/libBornAgainFit.i
index 46356fdaa08e7ba1ef723ab9597e8df6ac19edf3..876f6e1bf791c0f7afb1c1487f9b174da5483260 100644
--- a/Wrap/swig/libBornAgainFit.i
+++ b/Wrap/swig/libBornAgainFit.i
@@ -75,11 +75,6 @@ import_array();
 #include "Minimizer.h"
 %}
 
-// ownership
-%newobject FitSuite::getRealData(size_t i_item = 0) const;
-%newobject FitSuite::getSimulationData(size_t i_item = 0) const;
-%newobject FitSuite::getChiSquaredMap(size_t i_item = 0) const;
-
 // The following goes verbatim from libBornAgainFit.i to libBornAgainFit_wrap.cxx.
 // Note that the order matters, as base classes must be included before derived classes.
 
diff --git a/Wrap/swig/shared_pointers.i b/Wrap/swig/shared_pointers.i
index 601e8977400239b6700c72b6cbdc1474f8caa71b..6eadc5df4007214526c664c108eaac98edfbecb7 100644
--- a/Wrap/swig/shared_pointers.i
+++ b/Wrap/swig/shared_pointers.i
@@ -1,3 +1 @@
 %shared_ptr(IMultiLayerBuilder)
-%shared_ptr(IObserver)
-%shared_ptr(IFitObserver)
diff --git a/auto/Wrap/doxygen_core.i b/auto/Wrap/doxygen_core.i
index fa2a7d3a6bd3a60f1c7426827c18077916f58a9a..3ff68fafeb765b0905d2ce4d29574f02272ba298 100644
--- a/auto/Wrap/doxygen_core.i
+++ b/auto/Wrap/doxygen_core.i
@@ -1,30 +1,6 @@
 
 // File: index.xml
 
-// File: classAdjustMinimizerStrategy.xml
-%feature("docstring") AdjustMinimizerStrategy "
-
-Strategy modifies mimimizer settings before running minimization round.
-
-C++ includes: AdjustMinimizerStrategy.h
-";
-
-%feature("docstring")  AdjustMinimizerStrategy::AdjustMinimizerStrategy "AdjustMinimizerStrategy::AdjustMinimizerStrategy()
-";
-
-%feature("docstring")  AdjustMinimizerStrategy::AdjustMinimizerStrategy "AdjustMinimizerStrategy::AdjustMinimizerStrategy(const std::string &minimizerName, const std::string &algorithmName=\"\", const std::string &optionString=\"\")
-";
-
-%feature("docstring")  AdjustMinimizerStrategy::clone "AdjustMinimizerStrategy * AdjustMinimizerStrategy::clone() const
-";
-
-%feature("docstring")  AdjustMinimizerStrategy::setMinimizer "void AdjustMinimizerStrategy::setMinimizer(const std::string &minimizerName, const std::string &algorithmName=\"\", const std::string &optionString=\"\")
-";
-
-%feature("docstring")  AdjustMinimizerStrategy::execute "void AdjustMinimizerStrategy::execute()
-";
-
-
 // File: classAnisoPyramid.xml
 %feature("docstring") AnisoPyramid "";
 
@@ -642,21 +618,21 @@ C++ includes: BoxCompositionBuilder.h
 ";
 
 
-// File: structIntegratorMCMiser_1_1CallBackHolder.xml
-%feature("docstring") IntegratorMCMiser::CallBackHolder "
+// File: structIntegratorReal_1_1CallBackHolder.xml
+%feature("docstring") IntegratorReal::CallBackHolder "
 
 structure holding the object and possible extra parameters
 
-C++ includes: IntegratorMCMiser.h
+C++ includes: IntegratorReal.h
 ";
 
 
-// File: structIntegratorReal_1_1CallBackHolder.xml
-%feature("docstring") IntegratorReal::CallBackHolder "
+// File: structIntegratorMCMiser_1_1CallBackHolder.xml
+%feature("docstring") IntegratorMCMiser::CallBackHolder "
 
 structure holding the object and possible extra parameters
 
-C++ includes: IntegratorReal.h
+C++ includes: IntegratorMCMiser.h
 ";
 
 
@@ -697,9 +673,6 @@ C++ includes: ChiSquaredModule.h
 clone method 
 ";
 
-%feature("docstring")  ChiSquaredModule::processFitElements "void ChiSquaredModule::processFitElements(std::vector< FitElement >::iterator first, std::vector< FitElement >::iterator last)
-";
-
 %feature("docstring")  ChiSquaredModule::residual "double ChiSquaredModule::residual(double a, double b, double weight)
 ";
 
@@ -1369,6 +1342,9 @@ Returns a pointer to incident angle axis.
 Returns a pointer to z-position axis. 
 ";
 
+%feature("docstring")  DepthProbeSimulation::createUnitConverter "std::unique_ptr< IUnitConverter > DepthProbeSimulation::createUnitConverter() const
+";
+
 
 // File: classDetectionProperties.xml
 %feature("docstring") DetectionProperties "
@@ -1509,6 +1485,96 @@ returns true if has masks
 ";
 
 
+// File: classDistribution1DCauchySampler.xml
+%feature("docstring") Distribution1DCauchySampler "";
+
+%feature("docstring")  Distribution1DCauchySampler::Distribution1DCauchySampler "Distribution1DCauchySampler::Distribution1DCauchySampler(double lambda)
+";
+
+%feature("docstring")  Distribution1DCauchySampler::randomSample "double Distribution1DCauchySampler::randomSample() const final
+";
+
+
+// File: classDistribution1DCosineSampler.xml
+%feature("docstring") Distribution1DCosineSampler "";
+
+%feature("docstring")  Distribution1DCosineSampler::Distribution1DCosineSampler "Distribution1DCosineSampler::Distribution1DCosineSampler(double omega)
+";
+
+%feature("docstring")  Distribution1DCosineSampler::randomSample "double Distribution1DCosineSampler::randomSample() const final
+";
+
+
+// File: classDistribution1DGateSampler.xml
+%feature("docstring") Distribution1DGateSampler "";
+
+%feature("docstring")  Distribution1DGateSampler::Distribution1DGateSampler "Distribution1DGateSampler::Distribution1DGateSampler(double a, double b)
+";
+
+%feature("docstring")  Distribution1DGateSampler::randomSample "double Distribution1DGateSampler::randomSample() const final
+";
+
+
+// File: classDistribution1DGaussSampler.xml
+%feature("docstring") Distribution1DGaussSampler "";
+
+%feature("docstring")  Distribution1DGaussSampler::Distribution1DGaussSampler "Distribution1DGaussSampler::Distribution1DGaussSampler(double mean, double stddev)
+";
+
+%feature("docstring")  Distribution1DGaussSampler::randomSample "double Distribution1DGaussSampler::randomSample() const final
+";
+
+
+// File: classDistribution1DTriangleSampler.xml
+%feature("docstring") Distribution1DTriangleSampler "";
+
+%feature("docstring")  Distribution1DTriangleSampler::Distribution1DTriangleSampler "Distribution1DTriangleSampler::Distribution1DTriangleSampler(double omega)
+";
+
+%feature("docstring")  Distribution1DTriangleSampler::randomSample "double Distribution1DTriangleSampler::randomSample() const final
+";
+
+
+// File: classDistribution2DCauchySampler.xml
+%feature("docstring") Distribution2DCauchySampler "";
+
+%feature("docstring")  Distribution2DCauchySampler::Distribution2DCauchySampler "Distribution2DCauchySampler::Distribution2DCauchySampler(double omega_x, double omega_y)
+";
+
+%feature("docstring")  Distribution2DCauchySampler::randomSample "std::pair< double, double > Distribution2DCauchySampler::randomSample() const final
+";
+
+
+// File: classDistribution2DConeSampler.xml
+%feature("docstring") Distribution2DConeSampler "";
+
+%feature("docstring")  Distribution2DConeSampler::Distribution2DConeSampler "Distribution2DConeSampler::Distribution2DConeSampler(double omega_x, double omega_y)
+";
+
+%feature("docstring")  Distribution2DConeSampler::randomSample "std::pair< double, double > Distribution2DConeSampler::randomSample() const final
+";
+
+
+// File: classDistribution2DGateSampler.xml
+%feature("docstring") Distribution2DGateSampler "";
+
+%feature("docstring")  Distribution2DGateSampler::Distribution2DGateSampler "Distribution2DGateSampler::Distribution2DGateSampler(double omega_x, double omega_y)
+";
+
+%feature("docstring")  Distribution2DGateSampler::randomSample "std::pair< double, double > Distribution2DGateSampler::randomSample() const final
+";
+
+
+// File: classDistribution2DGaussSampler.xml
+%feature("docstring") Distribution2DGaussSampler "";
+
+%feature("docstring")  Distribution2DGaussSampler::Distribution2DGaussSampler "Distribution2DGaussSampler::Distribution2DGaussSampler(double omega_x, double omega_y)
+";
+
+%feature("docstring")  Distribution2DGaussSampler::randomSample "std::pair< double, double > Distribution2DGaussSampler::randomSample() const final
+";
+
+
 // File: classDistributionCosine.xml
 %feature("docstring") DistributionCosine "
 
@@ -1691,6 +1757,11 @@ get the total number of parameter value combinations (product of the individual
 set the parameter values of the simulation object to a specific combination of values, determined by the index (which must be smaller than the total number of combinations) and returns the weight associated with this combination of parameter values 
 ";
 
+%feature("docstring")  DistributionHandler::setParameterToMeans "void DistributionHandler::setParameterToMeans(ParameterPool *p_parameter_pool) const
+
+Sets mean distribution values to the parameter pool. 
+";
+
 %feature("docstring")  DistributionHandler::getDistributions "const DistributionHandler::Distributions_t & DistributionHandler::getDistributions() const
 ";
 
@@ -1930,1184 +2001,189 @@ C++ includes: DWBASingleComputation.h
 %feature("docstring")  DWBASingleComputation::DWBASingleComputation "DWBASingleComputation::DWBASingleComputation()
 ";
 
-%feature("docstring")  DWBASingleComputation::~DWBASingleComputation "DWBASingleComputation::~DWBASingleComputation()
-";
-
-%feature("docstring")  DWBASingleComputation::DWBASingleComputation "DWBASingleComputation::DWBASingleComputation(DWBASingleComputation &&other)
-";
-
-%feature("docstring")  DWBASingleComputation::setProgressHandler "void DWBASingleComputation::setProgressHandler(ProgressHandler *p_progress)
-";
-
-%feature("docstring")  DWBASingleComputation::addLayoutComputation "void DWBASingleComputation::addLayoutComputation(ParticleLayoutComputation *p_layout_comp)
-";
-
-%feature("docstring")  DWBASingleComputation::setRoughnessComputation "void DWBASingleComputation::setRoughnessComputation(RoughMultiLayerComputation *p_roughness_comp)
-";
-
-%feature("docstring")  DWBASingleComputation::setSpecularBinComputation "void DWBASingleComputation::setSpecularBinComputation(GISASSpecularComputation *p_spec_comp)
-";
-
-%feature("docstring")  DWBASingleComputation::compute "void DWBASingleComputation::compute(SimulationElement &elem) const
-";
-
-%feature("docstring")  DWBASingleComputation::regionMap "const std::map< size_t, std::vector< HomogeneousRegion > > & DWBASingleComputation::regionMap() const
-
-Retrieves a map of regions for the calculation of averaged layers. 
-";
-
-
-// File: classEllipse.xml
-%feature("docstring") Ellipse "
-
-Ellipse shape.
-
-C++ includes: Ellipse.h
-";
-
-%feature("docstring")  Ellipse::Ellipse "Ellipse::Ellipse(double xcenter, double ycenter, double xradius, double yradius, double theta=0.0)
-
-Parameters:
------------
-
-xcenter: 
-x-coordinate of  Ellipse's center
-
-ycenter: 
-y-coordinate of  Ellipse's center
-
-xradius: 
-Radius along x-axis
-
-yradius: 
-Radius along y-axis
-
-theta: 
-Angle of  Ellipse rotation in radians 
-";
-
-%feature("docstring")  Ellipse::clone "Ellipse* Ellipse::clone() const
-";
-
-%feature("docstring")  Ellipse::contains "bool Ellipse::contains(double x, double y) const
-
-Returns true if point with given coordinates is inside or on border of the shape. 
-";
-
-%feature("docstring")  Ellipse::contains "bool Ellipse::contains(const Bin1D &binx, const Bin1D &biny) const
-
-Returns true if area defined by two bins is inside or on border of ellipse; more precisely, if mid point of two bins satisfy this condition. 
-";
-
-%feature("docstring")  Ellipse::getCenterX "double Ellipse::getCenterX() const
-";
-
-%feature("docstring")  Ellipse::getCenterY "double Ellipse::getCenterY() const
-";
-
-%feature("docstring")  Ellipse::getRadiusX "double Ellipse::getRadiusX() const
-";
-
-%feature("docstring")  Ellipse::getRadiusY "double Ellipse::getRadiusY() const
-";
-
-%feature("docstring")  Ellipse::getTheta "double Ellipse::getTheta() const
-";
-
-
-// File: classExceptions_1_1ExistingClassRegistrationException.xml
-%feature("docstring") Exceptions::ExistingClassRegistrationException "";
-
-%feature("docstring")  Exceptions::ExistingClassRegistrationException::ExistingClassRegistrationException "Exceptions::ExistingClassRegistrationException::ExistingClassRegistrationException(const std::string &message)
-";
-
-
-// File: classExceptions_1_1FileIsBadException.xml
-%feature("docstring") Exceptions::FileIsBadException "";
-
-%feature("docstring")  Exceptions::FileIsBadException::FileIsBadException "Exceptions::FileIsBadException::FileIsBadException(const std::string &message)
-";
-
-
-// File: classExceptions_1_1FileNotIsOpenException.xml
-%feature("docstring") Exceptions::FileNotIsOpenException "";
-
-%feature("docstring")  Exceptions::FileNotIsOpenException::FileNotIsOpenException "Exceptions::FileNotIsOpenException::FileNotIsOpenException(const std::string &message)
-";
-
-
-// File: classFiniteSquareLatticeBuilder.xml
-%feature("docstring") FiniteSquareLatticeBuilder "
-
-Builds sample: 2D finite lattice with thermal disorder.
-
-C++ includes: TwoDimLatticeBuilder.h
-";
-
-%feature("docstring")  FiniteSquareLatticeBuilder::FiniteSquareLatticeBuilder "FiniteSquareLatticeBuilder::FiniteSquareLatticeBuilder()
-";
-
-%feature("docstring")  FiniteSquareLatticeBuilder::buildSample "MultiLayer * FiniteSquareLatticeBuilder::buildSample() const
-";
-
-
-// File: classFitElement.xml
-%feature("docstring") FitElement "
-
-Measured (\"real\") and simulated scattering intensity value for one detector cell. Used for chi2/residual calculations.
-
-C++ includes: FitElement.h
-";
-
-%feature("docstring")  FitElement::FitElement "FitElement::FitElement()
-";
-
-%feature("docstring")  FitElement::FitElement "FitElement::FitElement(size_t index, double simul_value, double real_value, double weight=1.0)
-";
-
-%feature("docstring")  FitElement::FitElement "FitElement::FitElement(const FitElement &other)
-";
-
-%feature("docstring")  FitElement::getIndex "size_t FitElement::getIndex() const
-";
-
-%feature("docstring")  FitElement::getSimulValue "double FitElement::getSimulValue() const
-";
-
-%feature("docstring")  FitElement::getRealValue "double FitElement::getRealValue() const
-";
-
-%feature("docstring")  FitElement::getWeight "double FitElement::getWeight() const
-";
-
-%feature("docstring")  FitElement::getSquaredDifference "double FitElement::getSquaredDifference() const
-";
-
-%feature("docstring")  FitElement::setSquaredDifference "void FitElement::setSquaredDifference(double value)
-";
-
-%feature("docstring")  FitElement::getResidual "double FitElement::getResidual() const
-";
-
-%feature("docstring")  FitElement::setResidual "void FitElement::setResidual(double value)
-";
-
-
-// File: classFitObject.xml
-%feature("docstring") FitObject "
-
-Holds simulation description and real data to run the fit.
-
-C++ includes: FitObject.h
-";
-
-%feature("docstring")  FitObject::FitObject "FitObject::FitObject(const Simulation &simulation, const OutputData< double > &data, double weight=1)
-
-Constructs simulation/data pair for later fit.
-
-Parameters:
------------
-
-simulation: 
-simulation to run
-
-data: 
-experimental data
-
-weight: 
-weight of dataset in chi2 calculations 
-";
-
-%feature("docstring")  FitObject::FitObject "FitObject::FitObject(const Simulation &simulation, const std::vector< std::vector< double >> &data, double weight=1)
-
-Constructs simulation/data pair for later fit.
-
-Parameters:
------------
-
-simulation: 
-simulation to run
-
-data: 
-experimental data
-
-weight: 
-weight of dataset in chi2 calculations 
-";
-
-%feature("docstring")  FitObject::~FitObject "FitObject::~FitObject()
-";
-
-%feature("docstring")  FitObject::accept "void FitObject::accept(INodeVisitor *visitor) const final
-
-Calls the  INodeVisitor's visit method. 
-";
-
-%feature("docstring")  FitObject::weight "double FitObject::weight() const
-
-Returns weight of data set in chi2 calculations. 
-";
-
-%feature("docstring")  FitObject::numberOfFitElements "size_t FitObject::numberOfFitElements() const
-
-Returns the size of the data. It is equal to the number of non-masked detector channels which will participate in chi2 calculations. 
-";
-
-%feature("docstring")  FitObject::prepareFitElements "void FitObject::prepareFitElements(std::vector< FitElement > &fit_elements, double weight, IIntensityNormalizer *=0)
-
-Runs simulation and put results (the real and simulated intensities) into external vector. Masked channels will be excluded from the vector. 
-";
-
-%feature("docstring")  FitObject::getChildren "std::vector< const INode * > FitObject::getChildren() const
-
-Returns a vector of children (const). 
-";
-
-%feature("docstring")  FitObject::simulationResult "SimulationResult FitObject::simulationResult() const
-
-Returns simulation result. 
-";
-
-%feature("docstring")  FitObject::experimentalData "SimulationResult FitObject::experimentalData() const
-
-Returns experimental data. 
-";
-
-%feature("docstring")  FitObject::relativeDifference "SimulationResult FitObject::relativeDifference() const
-
-Returns relative difference between simulation and experimental data. 
-";
-
-%feature("docstring")  FitObject::runSimulation "void FitObject::runSimulation()
-
-Runs internal simulation object. 
-";
-
-%feature("docstring")  FitObject::experimental_array "std::vector< double > FitObject::experimental_array() const
-
-Returns one dimensional array representing experimental data. Masked areas and the area outside of region of interest are not included. 
-";
-
-%feature("docstring")  FitObject::simulation_array "std::vector< double > FitObject::simulation_array() const
-
-Returns one dimensional array representing simulated intensities data. Masked areas and the area outside of region of interest are not included. 
-";
-
-
-// File: classFitObjective.xml
-%feature("docstring") FitObjective "
-
-Main class to hold pairs of simulation Holds vector of  FitObject's (simulation and real data) to fit
-
-C++ includes: FitObjective.h
-";
-
-%feature("docstring")  FitObjective::FitObjective "FitObjective::FitObjective()
-";
-
-%feature("docstring")  FitObjective::~FitObjective "FitObjective::~FitObjective()
-";
-
-%feature("docstring")  FitObjective::addSimulationAndData "void FitObjective::addSimulationAndData(simulation_builder_t builder, const OutputData< double > &data, double weight=1.0)
-
-Constructs simulation/data pair for later fit.
-
-Parameters:
------------
-
-simulation: 
-simulation builder capable of producing simulations
-
-data: 
-experimental data
-
-weight: 
-weight of dataset in chi2 calculations 
-";
-
-%feature("docstring")  FitObjective::addSimulationAndData "void FitObjective::addSimulationAndData(PyBuilderCallback &callback, const std::vector< double > &data, double weight=1.0)
-";
-
-%feature("docstring")  FitObjective::addSimulationAndData "void FitObjective::addSimulationAndData(PyBuilderCallback &callback, const std::vector< std::vector< double >> &data, double weight=1.0)
-";
-
-%feature("docstring")  FitObjective::evaluate "double FitObjective::evaluate(const Fit::Parameters &params)
-";
-
-%feature("docstring")  FitObjective::evaluate_residuals "std::vector< double > FitObjective::evaluate_residuals(const Fit::Parameters &params)
-";
-
-%feature("docstring")  FitObjective::numberOfFitElements "size_t FitObjective::numberOfFitElements() const
-";
-
-%feature("docstring")  FitObjective::experimental_array "std::vector< double > FitObjective::experimental_array() const
-
-Returns one dimensional array representing experimental data. Masked areas and the area outside of region of interest are not included. Data from different datasets merged together. 
-";
-
-%feature("docstring")  FitObjective::simulation_array "std::vector< double > FitObjective::simulation_array() const
-
-Returns one dimensional array representing simulated intensities data. Masked areas and the area outside of region of interest are not included. Data from different datasets merged together. 
-";
-
-%feature("docstring")  FitObjective::simulationResult "SimulationResult FitObjective::simulationResult(size_t i_item=0) const
-
-Returns simulation result.
-
-Parameters:
------------
-
-i_item: 
-the index of fit pair 
-";
-
-%feature("docstring")  FitObjective::experimentalData "SimulationResult FitObjective::experimentalData(size_t i_item=0) const
-
-Returns experimental data.
-
-Parameters:
------------
-
-i_item: 
-the index of fit pair 
-";
-
-%feature("docstring")  FitObjective::relativeDifference "SimulationResult FitObjective::relativeDifference(size_t i_item=0) const
-
-Returns relative difference between simulation and experimental data.
-
-Parameters:
------------
-
-i_item: 
-the index of fit pair 
-";
-
-%feature("docstring")  FitObjective::initPrint "void FitObjective::initPrint(int every_nth)
-
-Initializes printing to standard output during the fitting.
-
-Parameters:
------------
-
-every_nth: 
-Print every n'th iteration. 
-";
-
-%feature("docstring")  FitObjective::initPlot "void FitObjective::initPlot(int every_nth, PyObserverCallback &callback)
-
-Initializes plotting during the fitting using Python callable.
-
-Parameters:
------------
-
-every_nth: 
-Called on every n'th iteration. 
-";
-
-%feature("docstring")  FitObjective::isCompleted "bool FitObjective::isCompleted() const
-";
-
-%feature("docstring")  FitObjective::iterationInfo "IterationInfo FitObjective::iterationInfo() const
-";
-
-%feature("docstring")  FitObjective::minimizerResult "Fit::MinimizerResult FitObjective::minimizerResult() const
-";
-
-%feature("docstring")  FitObjective::finalize "void FitObjective::finalize(const Fit::MinimizerResult &result)
-
-Should be explicitely called on last iteration to notify all observers. 
-";
-
-%feature("docstring")  FitObjective::fitObjectCount "unsigned FitObjective::fitObjectCount() const
-";
-
-
-// File: classFitObserver.xml
-%feature("docstring") FitObserver "
-
-Contains collection of observers and call them at specified intervals. Each observer will be called at first iteration and every-nth iterations.
-
-C++ includes: FitObserver.h
-";
-
-%feature("docstring")  FitObserver::FitObserver "FitObserver< T >::FitObserver()
-";
-
-%feature("docstring")  FitObserver::addObserver "void FitObserver< T >::addObserver(int every_nth, observer_t observer)
-
-Adds observer to the list.
-
-Parameters:
------------
-
-every_nth: 
-An observer function will be called every_nth iterations.
-
-observer: 
-Observer function to be called. 
-";
-
-%feature("docstring")  FitObserver::notify "void FitObserver< T >::notify(const T &data)
-
-Notifies all observers at their personally specified intervals.
-
-Parameters:
------------
-
-data: 
-The data which will be passed to the observer. 
-";
-
-%feature("docstring")  FitObserver::notify_all "void FitObserver< T >::notify_all(const T &data)
-";
-
-
-// File: classFitParameter.xml
-%feature("docstring") FitParameter "
-
-Fittable parameter, linked to other parameters from pools.
-
-C++ includes: FitParameter.h
-";
-
-%feature("docstring")  FitParameter::FitParameter "FitParameter::FitParameter()
-";
-
-%feature("docstring")  FitParameter::FitParameter "FitParameter::FitParameter(const std::string &pattern, double value, const AttLimits &lim=AttLimits::limitless(), double step=0.0)
-";
-
-%feature("docstring")  FitParameter::FitParameter "FitParameter::FitParameter(double value, const AttLimits &lim=AttLimits::limitless(), double step=0.0)
-";
-
-%feature("docstring")  FitParameter::~FitParameter "FitParameter::~FitParameter() final
-";
-
-%feature("docstring")  FitParameter::clone "FitParameter * FitParameter::clone() const
-";
-
-%feature("docstring")  FitParameter::setValue "void FitParameter::setValue(double value) final
-
-Sets given value for all bound parameters. 
-";
-
-%feature("docstring")  FitParameter::addPattern "FitParameter & FitParameter::addPattern(const std::string &pattern)
-
-Adds pattern to the list for later usage in parameter pool matching. 
-";
-
-%feature("docstring")  FitParameter::addParameter "void FitParameter::addParameter(const RealParameter &par)
-
-Adds real parameter to the collection. 
-";
-
-%feature("docstring")  FitParameter::addMatchedParameters "void FitParameter::addMatchedParameters(const ParameterPool &pool)
-
-Adds parameters from pool which match given wildcard. 
-";
-
-%feature("docstring")  FitParameter::patterns "std::vector< std::string > FitParameter::patterns() const
-";
-
-%feature("docstring")  FitParameter::matchedParameterNames "std::vector< std::string > FitParameter::matchedParameterNames() const
-
-Returns vector of strings with names of all matched parameters. 
-";
-
-%feature("docstring")  FitParameter::patternIntersection "std::vector< std::string > FitParameter::patternIntersection(const FitParameter &other) const
-
-Returns vector containing patterns existing in both FitParametersLinked. 
-";
-
-%feature("docstring")  FitParameter::isConflicting "bool FitParameter::isConflicting(const FitParameter &other) const
-
-Returns true if two FitParameterLinked are intended to steer same  RealParameter. 
-";
-
-
-// File: classFitParameterSet.xml
-%feature("docstring") FitParameterSet "
-
-The set of fit parameters.
-
-C++ includes: FitParameterSet.h
-";
-
-%feature("docstring")  FitParameterSet::FitParameterSet "FitParameterSet::FitParameterSet()
-";
-
-%feature("docstring")  FitParameterSet::~FitParameterSet "FitParameterSet::~FitParameterSet()
-";
-
-%feature("docstring")  FitParameterSet::clear "void FitParameterSet::clear()
-
-Clears all defined parameters. 
-";
-
-%feature("docstring")  FitParameterSet::size "size_t FitParameterSet::size() const
-
-Returns number of parameters. 
-";
-
-%feature("docstring")  FitParameterSet::begin "FitParameterSet::iterator FitParameterSet::begin()
-
-Container iterators. 
-";
-
-%feature("docstring")  FitParameterSet::begin "FitParameterSet::const_iterator FitParameterSet::begin() const
-";
-
-%feature("docstring")  FitParameterSet::end "FitParameterSet::iterator FitParameterSet::end()
-";
-
-%feature("docstring")  FitParameterSet::end "FitParameterSet::const_iterator FitParameterSet::end() const
-";
-
-%feature("docstring")  FitParameterSet::addFitParameter "void FitParameterSet::addFitParameter(IFitParameter *par)
-
-Adds fit parameter. 
-";
-
-%feature("docstring")  FitParameterSet::fitParameter "const IFitParameter * FitParameterSet::fitParameter(const std::string &name) const
-
-Returns fit parameter by given name. 
-";
-
-%feature("docstring")  FitParameterSet::fitParameter "IFitParameter * FitParameterSet::fitParameter(const std::string &name)
-";
-
-%feature("docstring")  FitParameterSet::values "std::vector< double > FitParameterSet::values() const
-
-Returns values of all defined parameters. 
-";
-
-%feature("docstring")  FitParameterSet::setValues "void FitParameterSet::setValues(const std::vector< double > &pars_values)
-
-Sets values for all defined parameters. 
-";
-
-%feature("docstring")  FitParameterSet::valuesDifferFrom "bool FitParameterSet::valuesDifferFrom(const std::vector< double > &par_values, double tolerance=2.0) const
-
-Returns true if parameters already have the given values. 
-";
-
-%feature("docstring")  FitParameterSet::errors "std::vector< double > FitParameterSet::errors() const
-
-Returns errors of all defined parameters. 
-";
-
-%feature("docstring")  FitParameterSet::setErrors "void FitParameterSet::setErrors(const std::vector< double > &pars_errors)
-
-Sets errors to all parameters. 
-";
-
-%feature("docstring")  FitParameterSet::freeFitParameterCount "size_t FitParameterSet::freeFitParameterCount() const
-
-Returns number of free parameters. 
-";
-
-%feature("docstring")  FitParameterSet::fixAll "void FitParameterSet::fixAll()
-
-Fix all parameters. 
-";
-
-%feature("docstring")  FitParameterSet::releaseAll "void FitParameterSet::releaseAll()
-
-Release all parameters. 
-";
-
-%feature("docstring")  FitParameterSet::setFixed "void FitParameterSet::setFixed(const std::vector< std::string > &pars, bool is_fixed)
-
-Set fixed flag for parameters from the list. 
-";
-
-%feature("docstring")  FitParameterSet::correlationMatrix "corr_matrix_t FitParameterSet::correlationMatrix() const
-";
-
-%feature("docstring")  FitParameterSet::setCorrelationMatrix "void FitParameterSet::setCorrelationMatrix(const corr_matrix_t &matrix)
-
-Sets resulting correlation matrix. 
-";
-
-%feature("docstring")  FitParameterSet::fitParametersNewKernel "Fit::Parameters FitParameterSet::fitParametersNewKernel() const
-
-Refactoring temp: returns set of new fit parameters. 
-";
-
-
-// File: classFitPrintService.xml
-%feature("docstring") FitPrintService "
-
-Prints fit statistics to standard output during minimizer iterations.
-
-C++ includes: FitPrintService.h
-";
-
-%feature("docstring")  FitPrintService::FitPrintService "FitPrintService::FitPrintService()
-";
-
-%feature("docstring")  FitPrintService::print "void FitPrintService::print(const FitObjective &objective)
-";
-
-
-// File: classFitStatus.xml
-%feature("docstring") FitStatus "
-
-Contains status of the fitting (running, interupted etc) and all intermediate information which has to be collected during the fit. Owned by  FitObjective.
-
-C++ includes: FitStatus.h
-";
-
-%feature("docstring")  FitStatus::FitStatus "FitStatus::FitStatus(const FitObjective *fit_objective)
-";
-
-%feature("docstring")  FitStatus::~FitStatus "FitStatus::~FitStatus()
-";
-
-%feature("docstring")  FitStatus::setInterrupted "void FitStatus::setInterrupted()
-";
-
-%feature("docstring")  FitStatus::isInterrupted "bool FitStatus::isInterrupted() const
-";
-
-%feature("docstring")  FitStatus::isCompleted "bool FitStatus::isCompleted() const
-";
-
-%feature("docstring")  FitStatus::update "void FitStatus::update(const Fit::Parameters &params, double chi2)
-";
-
-%feature("docstring")  FitStatus::initPrint "void FitStatus::initPrint(int every_nth)
-";
-
-%feature("docstring")  FitStatus::addObserver "void FitStatus::addObserver(int every_nth, fit_observer_t)
-";
-
-%feature("docstring")  FitStatus::iterationInfo "IterationInfo FitStatus::iterationInfo() const
-";
-
-%feature("docstring")  FitStatus::minimizerResult "Fit::MinimizerResult FitStatus::minimizerResult() const
-";
-
-%feature("docstring")  FitStatus::finalize "void FitStatus::finalize(const Fit::MinimizerResult &result)
-
-Should be explicitely called on last iteration to notify all observers. 
-";
-
-
-// File: classFitStrategyAdjustParameters.xml
-%feature("docstring") FitStrategyAdjustParameters "
-
-Strategy which fixes/releases fit parameters and call minimizer.
-
-C++ includes: FitStrategyAdjustParameters.h
-";
-
-%feature("docstring")  FitStrategyAdjustParameters::FitStrategyAdjustParameters "FitStrategyAdjustParameters::FitStrategyAdjustParameters(const std::string &name)
-";
-
-%feature("docstring")  FitStrategyAdjustParameters::FitStrategyAdjustParameters "FitStrategyAdjustParameters::FitStrategyAdjustParameters()
-";
-
-%feature("docstring")  FitStrategyAdjustParameters::~FitStrategyAdjustParameters "virtual FitStrategyAdjustParameters::~FitStrategyAdjustParameters()
-";
-
-%feature("docstring")  FitStrategyAdjustParameters::clone "virtual FitStrategyAdjustParameters* FitStrategyAdjustParameters::clone() const
-";
-
-%feature("docstring")  FitStrategyAdjustParameters::execute "void FitStrategyAdjustParameters::execute()
-
-strategy which fixes/releases fit parameters and then call minimizer 
-";
-
-%feature("docstring")  FitStrategyAdjustParameters::fix_all "virtual FitStrategyAdjustParameters& FitStrategyAdjustParameters::fix_all()
-";
-
-%feature("docstring")  FitStrategyAdjustParameters::release_all "virtual FitStrategyAdjustParameters& FitStrategyAdjustParameters::release_all()
-";
-
-%feature("docstring")  FitStrategyAdjustParameters::fix "virtual FitStrategyAdjustParameters& FitStrategyAdjustParameters::fix(std::string parname)
-";
-
-%feature("docstring")  FitStrategyAdjustParameters::release "virtual FitStrategyAdjustParameters& FitStrategyAdjustParameters::release(std::string parname)
-";
-
-%feature("docstring")  FitStrategyAdjustParameters::setPreserveOriginalValues "virtual void FitStrategyAdjustParameters::setPreserveOriginalValues(bool preserve_values)
-";
-
-%feature("docstring")  FitStrategyAdjustParameters::clear "virtual void FitStrategyAdjustParameters::clear()
-";
-
-
-// File: classFitStrategyDefault.xml
-%feature("docstring") FitStrategyDefault "
-
-Default fit strategy just let  FitSuite to run it's minimization round.
-
-C++ includes: IFitStrategy.h
-";
-
-%feature("docstring")  FitStrategyDefault::FitStrategyDefault "FitStrategyDefault::FitStrategyDefault()
-";
-
-%feature("docstring")  FitStrategyDefault::clone "FitStrategyDefault * FitStrategyDefault::clone() const
-";
-
-%feature("docstring")  FitStrategyDefault::execute "void FitStrategyDefault::execute()
-";
-
-
-// File: classFitStrategyFixParameters.xml
-%feature("docstring") FitStrategyFixParameters "
-
-Strategy which fixes certain fit parameters leaving other released.
-
-C++ includes: FitStrategyAdjustParameters.h
-";
-
-%feature("docstring")  FitStrategyFixParameters::FitStrategyFixParameters "FitStrategyFixParameters::FitStrategyFixParameters()
-";
-
-%feature("docstring")  FitStrategyFixParameters::FitStrategyFixParameters "FitStrategyFixParameters::FitStrategyFixParameters(const std::vector< std::string > &pars)
-";
-
-%feature("docstring")  FitStrategyFixParameters::~FitStrategyFixParameters "virtual FitStrategyFixParameters::~FitStrategyFixParameters()
-";
-
-%feature("docstring")  FitStrategyFixParameters::clone "virtual FitStrategyFixParameters* FitStrategyFixParameters::clone() const
-";
-
-%feature("docstring")  FitStrategyFixParameters::clear "virtual void FitStrategyFixParameters::clear()
-";
-
-%feature("docstring")  FitStrategyFixParameters::setFixed "virtual void FitStrategyFixParameters::setFixed(const std::vector< std::string > &pars)
-";
-
-
-// File: classFitStrategyReleaseParameters.xml
-%feature("docstring") FitStrategyReleaseParameters "
-
-Strategy which releases certain fit parameters leaving other fixed.
-
-C++ includes: FitStrategyAdjustParameters.h
-";
-
-%feature("docstring")  FitStrategyReleaseParameters::FitStrategyReleaseParameters "FitStrategyReleaseParameters::FitStrategyReleaseParameters()
-";
-
-%feature("docstring")  FitStrategyReleaseParameters::FitStrategyReleaseParameters "FitStrategyReleaseParameters::FitStrategyReleaseParameters(const std::vector< std::string > &pars)
-";
-
-%feature("docstring")  FitStrategyReleaseParameters::~FitStrategyReleaseParameters "virtual FitStrategyReleaseParameters::~FitStrategyReleaseParameters()
-";
-
-%feature("docstring")  FitStrategyReleaseParameters::clone "virtual FitStrategyReleaseParameters* FitStrategyReleaseParameters::clone() const
-";
-
-%feature("docstring")  FitStrategyReleaseParameters::clear "virtual void FitStrategyReleaseParameters::clear()
-";
-
-%feature("docstring")  FitStrategyReleaseParameters::setReleased "virtual void FitStrategyReleaseParameters::setReleased(const std::vector< std::string > &pars)
-";
-
-
-// File: classFitSuite.xml
-%feature("docstring") FitSuite "
-
-User interface class that wraps all fit methods.
-
-C++ includes: FitSuite.h
-";
-
-%feature("docstring")  FitSuite::FitSuite "FitSuite::FitSuite()
-";
-
-%feature("docstring")  FitSuite::FitSuite "FitSuite::FitSuite(const FitSuite &)=delete
-";
-
-%feature("docstring")  FitSuite::~FitSuite "FitSuite::~FitSuite()
-";
-
-%feature("docstring")  FitSuite::addSimulationAndRealData "void FitSuite::addSimulationAndRealData(const Simulation &simulation, const OutputData< double > &real_data, double weight=1)
-
-Assigns pair of (simulation, real data) for fitting. More than one pair can be added. 
-";
-
-%feature("docstring")  FitSuite::addSimulationAndRealData "void FitSuite::addSimulationAndRealData(const Simulation &simulation, const IHistogram &real_data, double weight=1)
-
-Assigns pair of (simulation, real data) for fitting. More than one pair can be added. 
-";
-
-%feature("docstring")  FitSuite::addSimulationAndRealData "void FitSuite::addSimulationAndRealData(const Simulation &simulation, const std::vector< std::vector< double >> &real_data, double weight=1)
-
-Assigns pair of (simulation, real data) for fitting. A version for the  real_data represented as a two-dimensional numpy array.  Simulation output must agree in dimensions with  real_data. 
-";
-
-%feature("docstring")  FitSuite::addSimulationAndRealData "void FitSuite::addSimulationAndRealData(const Simulation &simulation, const std::vector< double > &real_data, double weight=1)
-
-Assigns pair of (simulation, real_data) for fitting. A version for the  real_data represented as a one-dimensional numpy array.  Simulation output must agree in dimensions with  real_data. 
-";
-
-%feature("docstring")  FitSuite::addFitParameter "FitParameter * FitSuite::addFitParameter(const std::string &pattern, double value, const AttLimits &limits=AttLimits::limitless(), double step=0.0)
-
-Adds fit parameter
-
-Parameters:
------------
-
-name: 
-The name of sample parameter(s) to fit (may contain wildcards).
-
-value: 
-Parameter's starting value
-
-limits: 
-Limits attribute
-
-step: 
-Initial parameter's step (some minimizers don't use it) 
-";
-
-%feature("docstring")  FitSuite::addFitParameter "FitParameter * FitSuite::addFitParameter(const FitParameter &fitPar)
-
-Adds fit parameter
-
-Parameters:
------------
-
-fitPar: 
-Fully constructed fit parameter. 
-";
-
-%feature("docstring")  FitSuite::setMinimizer "void FitSuite::setMinimizer(const std::string &minimizer_name, const std::string &algorithm_name=std::string(), const std::string &minimizer_options=std::string())
-
-Sets minimizer with given name and algorithm type
-
-Parameters:
------------
-
-minimizer_name: 
-The name of the minimizer
-
-algorithm_name: 
-Optional name of the minimizer's algorithm
-
-minimizer_options: 
-Optional string with additional minimizer settings 
-";
-
-%feature("docstring")  FitSuite::setChiSquaredModule "void FitSuite::setChiSquaredModule(const IChiSquaredModule &chi2_module)
-
-Replaces default  ChiSquaredModule with new one. 
-";
-
-%feature("docstring")  FitSuite::addFitStrategy "void FitSuite::addFitStrategy(const IFitStrategy &strategy)
-
-Adds fit strategy. 
-";
-
-%feature("docstring")  FitSuite::setMinimizer "void FitSuite::setMinimizer(IMinimizer *minimizer)
-
-Sets minimizer. 
-";
-
-%feature("docstring")  FitSuite::minimizerName "std::string FitSuite::minimizerName() const
-
-Returns minimizer. 
-";
-
-%feature("docstring")  FitSuite::initPrint "void FitSuite::initPrint(int print_every_nth)
-
-Initializes printing to standard output during the fitting. Prints also the summary when completed.
-
-Parameters:
------------
-
-print_every_nth: 
-Print every n'th iteration 
-";
-
-%feature("docstring")  FitSuite::runFit "void FitSuite::runFit()
-
-main method to run the fitting 
-";
-
-%feature("docstring")  FitSuite::numberOfFitObjects "size_t FitSuite::numberOfFitObjects() const
-
-Returns number of fit objects, where fit object stands for (real, simulated) pair. 
-";
-
-%feature("docstring")  FitSuite::fitObjects "FitSuiteObjects * FitSuite::fitObjects()
-
-returns  FitObject (pair of simulation/real data) 
-";
-
-%feature("docstring")  FitSuite::fitParameters "FitParameterSet * FitSuite::fitParameters()
-
-Returns reference to fit parameters. 
-";
-
-%feature("docstring")  FitSuite::fitStrategies "FitSuiteStrategies * FitSuite::fitStrategies()
-
-Returns reference to fit parameters. 
-";
-
-%feature("docstring")  FitSuite::isFirstIteration "bool FitSuite::isFirstIteration() const
-
-temporary method to check if it is first iteration 
-";
-
-%feature("docstring")  FitSuite::isLastIteration "bool FitSuite::isLastIteration() const
-
-if the last iteration is done (used by observers to print summary) 
-";
-
-%feature("docstring")  FitSuite::numberOfIterations "size_t FitSuite::numberOfIterations() const
-
-Returns current number of minimization function calls. 
-";
-
-%feature("docstring")  FitSuite::currentStrategyIndex "size_t FitSuite::currentStrategyIndex() const
-
-Returns the number of current strategy. 
-";
-
-%feature("docstring")  FitSuite::printResults "void FitSuite::printResults() const
-
-Prints results of the minimization to the standard output. 
-";
-
-%feature("docstring")  FitSuite::reportResults "std::string FitSuite::reportResults() const
-
-Reports results of minimization in the form of multi-line string. 
-";
-
-%feature("docstring")  FitSuite::getChi2 "double FitSuite::getChi2() const
-
-Returns minimum chi squared value found. 
-";
-
-%feature("docstring")  FitSuite::interruptFitting "void FitSuite::interruptFitting()
-";
-
-%feature("docstring")  FitSuite::resetInterrupt "void FitSuite::resetInterrupt()
-";
-
-%feature("docstring")  FitSuite::isInterrupted "bool FitSuite::isInterrupted()
-";
-
-%feature("docstring")  FitSuite::parametersToString "std::string FitSuite::parametersToString() const
-
-Returns multiline string representing possible fit parameters. 
-";
-
-%feature("docstring")  FitSuite::treeToString "std::string FitSuite::treeToString() const
-
-Returns multiline string representing tree structure of fit components. 
-";
-
-%feature("docstring")  FitSuite::setupToString "std::string FitSuite::setupToString()
-
-Returns multiline string representing fit setup. 
-";
-
-%feature("docstring")  FitSuite::simulationResult "SimulationResult FitSuite::simulationResult(size_t i_item=0) const
-
-Returns simulation result.
-
-Parameters:
------------
-
-i_item: 
-the index of fit pair 
-";
-
-%feature("docstring")  FitSuite::experimentalData "SimulationResult FitSuite::experimentalData(size_t i_item=0) const
-
-Returns experimental data.
-
-Parameters:
------------
-
-i_item: 
-the index of fit pair 
-";
-
-%feature("docstring")  FitSuite::relativeDifference "SimulationResult FitSuite::relativeDifference(size_t i_item=0) const
-
-Returns relative difference between simulation and experimental data.
-
-Parameters:
------------
-
-i_item: 
-the index of fit pair 
-";
-
-
-// File: classFitSuiteImpl.xml
-%feature("docstring") FitSuiteImpl "
+%feature("docstring")  DWBASingleComputation::~DWBASingleComputation "DWBASingleComputation::~DWBASingleComputation()
+";
 
-Fitting kernel for  FitSuite.
+%feature("docstring")  DWBASingleComputation::DWBASingleComputation "DWBASingleComputation::DWBASingleComputation(DWBASingleComputation &&other)
+";
 
-C++ includes: FitSuiteImpl.h
+%feature("docstring")  DWBASingleComputation::setProgressHandler "void DWBASingleComputation::setProgressHandler(ProgressHandler *p_progress)
 ";
 
-%feature("docstring")  FitSuiteImpl::FitSuiteImpl "FitSuiteImpl::FitSuiteImpl(const std::function< void()> &notifyObservers)
+%feature("docstring")  DWBASingleComputation::addLayoutComputation "void DWBASingleComputation::addLayoutComputation(ParticleLayoutComputation *p_layout_comp)
 ";
 
-%feature("docstring")  FitSuiteImpl::FitSuiteImpl "FitSuiteImpl::FitSuiteImpl(const FitSuiteImpl &)=delete
+%feature("docstring")  DWBASingleComputation::setRoughnessComputation "void DWBASingleComputation::setRoughnessComputation(RoughMultiLayerComputation *p_roughness_comp)
 ";
 
-%feature("docstring")  FitSuiteImpl::~FitSuiteImpl "FitSuiteImpl::~FitSuiteImpl()
+%feature("docstring")  DWBASingleComputation::setSpecularBinComputation "void DWBASingleComputation::setSpecularBinComputation(GISASSpecularComputation *p_spec_comp)
 ";
 
-%feature("docstring")  FitSuiteImpl::clear "void FitSuiteImpl::clear()
+%feature("docstring")  DWBASingleComputation::compute "void DWBASingleComputation::compute(SimulationElement &elem) const
+";
 
-Resets most state variables, to get prepared for the next fit.
+%feature("docstring")  DWBASingleComputation::regionMap "const std::map< size_t, std::vector< HomogeneousRegion > > & DWBASingleComputation::regionMap() const
 
-Clears all data. 
+Retrieves a map of regions for the calculation of averaged layers. 
 ";
 
-%feature("docstring")  FitSuiteImpl::addSimulationAndRealData "FitObject * FitSuiteImpl::addSimulationAndRealData(const Simulation &simulation, const OutputData< double > &real_data, double weight)
 
-Adds pair of (simulation, real data) for consecutive simulation. 
+// File: classEllipse.xml
+%feature("docstring") Ellipse "
+
+Ellipse shape.
+
+C++ includes: Ellipse.h
 ";
 
-%feature("docstring")  FitSuiteImpl::addFitParameter "FitParameter * FitSuiteImpl::addFitParameter(const std::string &pattern, double value, const AttLimits &limits, double step=0.0)
+%feature("docstring")  Ellipse::Ellipse "Ellipse::Ellipse(double xcenter, double ycenter, double xradius, double yradius, double theta=0.0)
 
-Adds fit parameter.
+Parameters:
+-----------
 
-Adds fit parameter, step is calculated from initial parameter value. 
-";
+xcenter: 
+x-coordinate of  Ellipse's center
 
-%feature("docstring")  FitSuiteImpl::addFitParameter "FitParameter * FitSuiteImpl::addFitParameter(const FitParameter &fitPar)
+ycenter: 
+y-coordinate of  Ellipse's center
 
-Adds fit parameter. 
-";
+xradius: 
+Radius along x-axis
 
-%feature("docstring")  FitSuiteImpl::addFitStrategy "void FitSuiteImpl::addFitStrategy(const IFitStrategy &strategy)
+yradius: 
+Radius along y-axis
 
-Adds fit strategy. 
+theta: 
+Angle of  Ellipse rotation in radians 
 ";
 
-%feature("docstring")  FitSuiteImpl::setMinimizer "void FitSuiteImpl::setMinimizer(IMinimizer *minimizer)
-
-Sets minimizer. 
+%feature("docstring")  Ellipse::clone "Ellipse* Ellipse::clone() const
 ";
 
-%feature("docstring")  FitSuiteImpl::runFit "void FitSuiteImpl::runFit()
+%feature("docstring")  Ellipse::contains "bool Ellipse::contains(double x, double y) const
 
-Runs a fit, which may consist of several minimization rounds. 
+Returns true if point with given coordinates is inside or on border of the shape. 
 ";
 
-%feature("docstring")  FitSuiteImpl::minimize "void FitSuiteImpl::minimize()
+%feature("docstring")  Ellipse::contains "bool Ellipse::contains(const Bin1D &binx, const Bin1D &biny) const
 
-Runs a single minimization round (called by FitSuiteStrategy) 
+Returns true if area defined by two bins is inside or on border of ellipse; more precisely, if mid point of two bins satisfy this condition. 
 ";
 
-%feature("docstring")  FitSuiteImpl::fitObjects "FitSuiteObjects* FitSuiteImpl::fitObjects()
+%feature("docstring")  Ellipse::getCenterX "double Ellipse::getCenterX() const
+";
 
-Returns reference to the kit with data. 
+%feature("docstring")  Ellipse::getCenterY "double Ellipse::getCenterY() const
 ";
 
-%feature("docstring")  FitSuiteImpl::fitObjects "const FitSuiteObjects* FitSuiteImpl::fitObjects() const
+%feature("docstring")  Ellipse::getRadiusX "double Ellipse::getRadiusX() const
 ";
 
-%feature("docstring")  FitSuiteImpl::fitParameters "FitParameterSet * FitSuiteImpl::fitParameters()
+%feature("docstring")  Ellipse::getRadiusY "double Ellipse::getRadiusY() const
+";
 
-Returns reference to fit parameters. 
+%feature("docstring")  Ellipse::getTheta "double Ellipse::getTheta() const
 ";
 
-%feature("docstring")  FitSuiteImpl::fitStrategies "FitSuiteStrategies* FitSuiteImpl::fitStrategies()
 
-Returns reference to fit parameters. 
+// File: classExceptions_1_1ExistingClassRegistrationException.xml
+%feature("docstring") Exceptions::ExistingClassRegistrationException "";
+
+%feature("docstring")  Exceptions::ExistingClassRegistrationException::ExistingClassRegistrationException "Exceptions::ExistingClassRegistrationException::ExistingClassRegistrationException(const std::string &message)
 ";
 
-%feature("docstring")  FitSuiteImpl::isLastIteration "bool FitSuiteImpl::isLastIteration() const
 
-Returns true if the last iteration is done (used by observers to print summary) 
+// File: classExceptions_1_1FileIsBadException.xml
+%feature("docstring") Exceptions::FileIsBadException "";
+
+%feature("docstring")  Exceptions::FileIsBadException::FileIsBadException "Exceptions::FileIsBadException::FileIsBadException(const std::string &message)
 ";
 
-%feature("docstring")  FitSuiteImpl::numberOfIterations "size_t FitSuiteImpl::numberOfIterations() const
 
-Returns current number of minimization function calls. 
+// File: classExceptions_1_1FileNotIsOpenException.xml
+%feature("docstring") Exceptions::FileNotIsOpenException "";
+
+%feature("docstring")  Exceptions::FileNotIsOpenException::FileNotIsOpenException "Exceptions::FileNotIsOpenException::FileNotIsOpenException(const std::string &message)
 ";
 
-%feature("docstring")  FitSuiteImpl::currentStrategyIndex "size_t FitSuiteImpl::currentStrategyIndex() const
 
-Returns the number of current strategy. 
-";
+// File: classFiniteSquareLatticeBuilder.xml
+%feature("docstring") FiniteSquareLatticeBuilder "
 
-%feature("docstring")  FitSuiteImpl::reportResults "std::string FitSuiteImpl::reportResults() const
+Builds sample: 2D finite lattice with thermal disorder.
 
-Reports results of minimization in the form of multi-line string. 
+C++ includes: TwoDimLatticeBuilder.h
 ";
 
-%feature("docstring")  FitSuiteImpl::getOptions "FitOptions& FitSuiteImpl::getOptions()
+%feature("docstring")  FiniteSquareLatticeBuilder::FiniteSquareLatticeBuilder "FiniteSquareLatticeBuilder::FiniteSquareLatticeBuilder()
+";
 
-Returns current fit options. 
+%feature("docstring")  FiniteSquareLatticeBuilder::buildSample "MultiLayer * FiniteSquareLatticeBuilder::buildSample() const
 ";
 
-%feature("docstring")  FitSuiteImpl::setOptions "void FitSuiteImpl::setOptions(const FitOptions &fit_options)
 
-Sets fit options. 
-";
+// File: classFitObjective.xml
+%feature("docstring") FitObjective "
 
-%feature("docstring")  FitSuiteImpl::notifyObservers "void FitSuiteImpl::notifyObservers()
-";
+Main class to hold pairs of simulation Holds vector of FitObject's (simulation and real data) to fit
 
-%feature("docstring")  FitSuiteImpl::interruptFitting "void FitSuiteImpl::interruptFitting()
+C++ includes: FitObjective.h
 ";
 
-%feature("docstring")  FitSuiteImpl::resetInterrupt "void FitSuiteImpl::resetInterrupt()
+%feature("docstring")  FitObjective::FitObjective "FitObjective::FitObjective()
 ";
 
-%feature("docstring")  FitSuiteImpl::isInterrupted "bool FitSuiteImpl::isInterrupted() const
+%feature("docstring")  FitObjective::~FitObjective "FitObjective::~FitObjective()
 ";
 
-%feature("docstring")  FitSuiteImpl::setupToString "std::string FitSuiteImpl::setupToString()
+%feature("docstring")  FitObjective::addSimulationAndData "void FitObjective::addSimulationAndData(simulation_builder_t builder, const OutputData< double > &data, double weight=1.0)
 
-Returns multiline string representing fit setup. 
-";
+Constructs simulation/data pair for later fit.
 
+Parameters:
+-----------
 
-// File: classFitSuiteObjects.xml
-%feature("docstring") FitSuiteObjects "
+simulation: 
+simulation builder capable of producing simulations
 
-Holds vector of  FitObject's (simulation and real data) to fit
+data: 
+experimental data
 
-C++ includes: FitSuiteObjects.h
+weight: 
+weight of dataset in chi2 calculations 
 ";
 
-%feature("docstring")  FitSuiteObjects::FitSuiteObjects "FitSuiteObjects::FitSuiteObjects()
+%feature("docstring")  FitObjective::addSimulationAndData "void FitObjective::addSimulationAndData(PyBuilderCallback &callback, const std::vector< double > &data, double weight=1.0)
 ";
 
-%feature("docstring")  FitSuiteObjects::~FitSuiteObjects "FitSuiteObjects::~FitSuiteObjects()
+%feature("docstring")  FitObjective::addSimulationAndData "void FitObjective::addSimulationAndData(PyBuilderCallback &callback, const std::vector< std::vector< double >> &data, double weight=1.0)
 ";
 
-%feature("docstring")  FitSuiteObjects::accept "void FitSuiteObjects::accept(INodeVisitor *visitor) const final
-
-Calls the  INodeVisitor's visit method. 
+%feature("docstring")  FitObjective::evaluate "double FitObjective::evaluate(const Fit::Parameters &params)
 ";
 
-%feature("docstring")  FitSuiteObjects::add "FitObject * FitSuiteObjects::add(const Simulation &simulation, const OutputData< double > &real_data, double weight=1.0)
+%feature("docstring")  FitObjective::evaluate_residuals "std::vector< double > FitObjective::evaluate_residuals(const Fit::Parameters &params)
+";
 
-Adds to kit pair of (simulation, real data) for consecutive simulation. 
+%feature("docstring")  FitObjective::numberOfFitElements "size_t FitObjective::numberOfFitElements() const
 ";
 
-%feature("docstring")  FitSuiteObjects::getSizeOfDataSet "size_t FitSuiteObjects::getSizeOfDataSet() const
+%feature("docstring")  FitObjective::experimental_array "std::vector< double > FitObjective::experimental_array() const
+
+Returns one dimensional array representing experimental data. Masked areas and the area outside of region of interest are not included. Data from different datasets merged together. 
+";
 
-Returns total number of data points (number of all non-masked channels in all fit objects)
+%feature("docstring")  FitObjective::simulation_array "std::vector< double > FitObjective::simulation_array() const
 
-Returns total number of data points. 
+Returns one dimensional array representing simulated intensities data. Masked areas and the area outside of region of interest are not included. Data from different datasets merged together. 
 ";
 
-%feature("docstring")  FitSuiteObjects::setChiSquaredModule "void FitSuiteObjects::setChiSquaredModule(const IChiSquaredModule &chi2_module)
+%feature("docstring")  FitObjective::weights_array "std::vector< double > FitObjective::weights_array() const
 
-Replaces default  ChiSquaredModule with new one. 
+Returns one dimensional array representing weights of bin intensity for residuals. 
 ";
 
-%feature("docstring")  FitSuiteObjects::simulationResult "SimulationResult FitSuiteObjects::simulationResult(size_t i_item=0) const
+%feature("docstring")  FitObjective::simulationResult "SimulationResult FitObjective::simulationResult(size_t i_item=0) const
 
 Returns simulation result.
 
@@ -3118,7 +2194,7 @@ i_item:
 the index of fit pair 
 ";
 
-%feature("docstring")  FitSuiteObjects::experimentalData "SimulationResult FitSuiteObjects::experimentalData(size_t i_item=0) const
+%feature("docstring")  FitObjective::experimentalData "SimulationResult FitObjective::experimentalData(size_t i_item=0) const
 
 Returns experimental data.
 
@@ -3129,7 +2205,7 @@ i_item:
 the index of fit pair 
 ";
 
-%feature("docstring")  FitSuiteObjects::relativeDifference "SimulationResult FitSuiteObjects::relativeDifference(size_t i_item=0) const
+%feature("docstring")  FitObjective::relativeDifference "SimulationResult FitObjective::relativeDifference(size_t i_item=0) const
 
 Returns relative difference between simulation and experimental data.
 
@@ -3140,111 +2216,171 @@ i_item:
 the index of fit pair 
 ";
 
-%feature("docstring")  FitSuiteObjects::runSimulations "void FitSuiteObjects::runSimulations()
+%feature("docstring")  FitObjective::absoluteDifference "SimulationResult FitObjective::absoluteDifference(size_t i_item=0) const
 
-run all simulation defined in fit pairs
+Returns absolute value of difference between simulation and experimental data.
+
+Parameters:
+-----------
 
-loop through all defined simulations and run them 
+i_item: 
+the index of fit pair 
 ";
 
-%feature("docstring")  FitSuiteObjects::getChiSquaredValue "double FitSuiteObjects::getChiSquaredValue() const
+%feature("docstring")  FitObjective::initPrint "void FitObjective::initPrint(int every_nth)
+
+Initializes printing to standard output during the fitting.
+
+Parameters:
+-----------
 
-Returns chi2 calculated over whole dataset. 
+every_nth: 
+Print every n'th iteration. 
 ";
 
-%feature("docstring")  FitSuiteObjects::getResidualValue "double FitSuiteObjects::getResidualValue(size_t global_index)
+%feature("docstring")  FitObjective::initPlot "void FitObjective::initPlot(int every_nth, fit_observer_t observer)
 
-Returns residuals for single data element
+Initializes plotting during the fitting using Python callable.
 
 Parameters:
 -----------
 
-global_index: 
-index across all element in  FitElement vector 
+every_nth: 
+Called on every n'th iteration. 
+";
+
+%feature("docstring")  FitObjective::initPlot "void FitObjective::initPlot(int every_nth, PyObserverCallback &callback)
+";
+
+%feature("docstring")  FitObjective::isCompleted "bool FitObjective::isCompleted() const
+";
+
+%feature("docstring")  FitObjective::iterationInfo "IterationInfo FitObjective::iterationInfo() const
 ";
 
-%feature("docstring")  FitSuiteObjects::residuals "std::vector< double > FitSuiteObjects::residuals() const
+%feature("docstring")  FitObjective::minimizerResult "Fit::MinimizerResult FitObjective::minimizerResult() const
 ";
 
-%feature("docstring")  FitSuiteObjects::setNfreeParameters "void FitSuiteObjects::setNfreeParameters(int nfree_parameters)
+%feature("docstring")  FitObjective::finalize "void FitObjective::finalize(const Fit::MinimizerResult &result)
+
+Should be explicitely called on last iteration to notify all observers. 
 ";
 
-%feature("docstring")  FitSuiteObjects::clear "void FitSuiteObjects::clear()
+%feature("docstring")  FitObjective::fitObjectCount "unsigned FitObjective::fitObjectCount() const
+";
 
-clear all data 
+%feature("docstring")  FitObjective::interruptFitting "void FitObjective::interruptFitting()
 ";
 
-%feature("docstring")  FitSuiteObjects::size "size_t FitSuiteObjects::size() const
+%feature("docstring")  FitObjective::isInterrupted "bool FitObjective::isInterrupted() const
 ";
 
-%feature("docstring")  FitSuiteObjects::begin "iterator FitSuiteObjects::begin()
+%feature("docstring")  FitObjective::isFirstIteration "bool FitObjective::isFirstIteration() const
 ";
 
-%feature("docstring")  FitSuiteObjects::end "iterator FitSuiteObjects::end()
+%feature("docstring")  FitObjective::run_simulations "void FitObjective::run_simulations(const Fit::Parameters &params)
 ";
 
-%feature("docstring")  FitSuiteObjects::getChildren "std::vector< const INode * > FitSuiteObjects::getChildren() const
+%feature("docstring")  FitObjective::setChiSquaredModule "void FitObjective::setChiSquaredModule(const IChiSquaredModule &module)
+";
 
-Returns a vector of children (const). 
+
+// File: classFitObserver.xml
+%feature("docstring") FitObserver "
+
+Contains collection of observers and call them at specified intervals. Each observer will be called at first iteration and every-nth iterations.
+
+C++ includes: FitObserver.h
+";
+
+%feature("docstring")  FitObserver::FitObserver "FitObserver< T >::FitObserver()
+";
+
+%feature("docstring")  FitObserver::addObserver "void FitObserver< T >::addObserver(int every_nth, observer_t observer)
+
+Adds observer to the list.
+
+Parameters:
+-----------
+
+every_nth: 
+An observer function will be called every_nth iterations.
+
+observer: 
+Observer function to be called. 
 ";
 
+%feature("docstring")  FitObserver::notify "void FitObserver< T >::notify(const T &data)
 
-// File: classFitSuitePrintObserver.xml
-%feature("docstring") FitSuitePrintObserver "
+Notifies all observers at their personally specified intervals.
 
-Prints fit progress at the end of each  FitSuite's iteration.
+Parameters:
+-----------
 
-C++ includes: FitSuitePrintObserver.h
+data: 
+The data which will be passed to the observer. 
 ";
 
-%feature("docstring")  FitSuitePrintObserver::FitSuitePrintObserver "FitSuitePrintObserver::FitSuitePrintObserver(int print_every_nth=1)
+%feature("docstring")  FitObserver::notify_all "void FitObserver< T >::notify_all(const T &data)
 ";
 
-%feature("docstring")  FitSuitePrintObserver::~FitSuitePrintObserver "virtual FitSuitePrintObserver::~FitSuitePrintObserver()
+
+// File: classFitPrintService.xml
+%feature("docstring") FitPrintService "
+
+Prints fit statistics to standard output during minimizer iterations.
+
+C++ includes: FitPrintService.h
 ";
 
-%feature("docstring")  FitSuitePrintObserver::update "void FitSuitePrintObserver::update(FitSuite *fit_suite)
+%feature("docstring")  FitPrintService::FitPrintService "FitPrintService::FitPrintService()
+";
 
-Here Onserver will do actuall job when he thinks that it is a right moment. 
+%feature("docstring")  FitPrintService::print "void FitPrintService::print(const FitObjective &objective)
 ";
 
 
-// File: classFitSuiteStrategies.xml
-%feature("docstring") FitSuiteStrategies "
+// File: classFitStatus.xml
+%feature("docstring") FitStatus "
+
+Contains status of the fitting (running, interupted etc) and all intermediate information which has to be collected during the fit. Owned by  FitObjective.
 
-Collection of strategies to fit.
+C++ includes: FitStatus.h
+";
 
-C++ includes: FitSuiteStrategies.h
+%feature("docstring")  FitStatus::FitStatus "FitStatus::FitStatus(const FitObjective *fit_objective)
 ";
 
-%feature("docstring")  FitSuiteStrategies::FitSuiteStrategies "FitSuiteStrategies::FitSuiteStrategies()
+%feature("docstring")  FitStatus::~FitStatus "FitStatus::~FitStatus()
 ";
 
-%feature("docstring")  FitSuiteStrategies::~FitSuiteStrategies "FitSuiteStrategies::~FitSuiteStrategies()
+%feature("docstring")  FitStatus::setInterrupted "void FitStatus::setInterrupted()
 ";
 
-%feature("docstring")  FitSuiteStrategies::FitSuiteStrategies "FitSuiteStrategies::FitSuiteStrategies(const FitSuiteStrategies &other)=delete
+%feature("docstring")  FitStatus::isInterrupted "bool FitStatus::isInterrupted() const
 ";
 
-%feature("docstring")  FitSuiteStrategies::init "void FitSuiteStrategies::init(FitSuiteImpl *fit_suite)
+%feature("docstring")  FitStatus::isCompleted "bool FitStatus::isCompleted() const
 ";
 
-%feature("docstring")  FitSuiteStrategies::addStrategy "void FitSuiteStrategies::addStrategy(const IFitStrategy &strategy)
+%feature("docstring")  FitStatus::update "void FitStatus::update(const Fit::Parameters &params, double chi2)
 ";
 
-%feature("docstring")  FitSuiteStrategies::minimize "void FitSuiteStrategies::minimize()
+%feature("docstring")  FitStatus::initPrint "void FitStatus::initPrint(int every_nth)
 ";
 
-%feature("docstring")  FitSuiteStrategies::currentStrategyIndex "size_t FitSuiteStrategies::currentStrategyIndex() const
+%feature("docstring")  FitStatus::addObserver "void FitStatus::addObserver(int every_nth, fit_observer_t)
 ";
 
-%feature("docstring")  FitSuiteStrategies::size "size_t FitSuiteStrategies::size() const
+%feature("docstring")  FitStatus::iterationInfo "IterationInfo FitStatus::iterationInfo() const
 ";
 
-%feature("docstring")  FitSuiteStrategies::clear "void FitSuiteStrategies::clear()
+%feature("docstring")  FitStatus::minimizerResult "Fit::MinimizerResult FitStatus::minimizerResult() const
 ";
 
-%feature("docstring")  FitSuiteStrategies::currentStrategy "IFitStrategy * FitSuiteStrategies::currentStrategy()
+%feature("docstring")  FitStatus::finalize "void FitStatus::finalize(const Fit::MinimizerResult &result)
+
+Should be explicitely called on last iteration to notify all observers. 
 ";
 
 
@@ -4574,6 +3710,61 @@ Calls the  INodeVisitor's visit method.
 ";
 
 
+// File: classFormFactorLongBox.xml
+%feature("docstring") FormFactorLongBox "
+
+The formfactor for a long rectangular box. Approximates the rapidly oscillating sinc function by the square root of a Lorentzian
+
+C++ includes: FormFactorLongBox.h
+";
+
+%feature("docstring")  FormFactorLongBox::FormFactorLongBox "FormFactorLongBox::FormFactorLongBox(double length, double width, double height)
+
+Box constructor.
+
+Parameters:
+-----------
+
+length: 
+of  Box's base
+
+width: 
+of  Box's base
+
+height: 
+of  Box
+";
+
+%feature("docstring")  FormFactorLongBox::clone "FormFactorLongBox* FormFactorLongBox::clone() const override final
+
+Returns a clone of this  ISample object. 
+";
+
+%feature("docstring")  FormFactorLongBox::accept "void FormFactorLongBox::accept(INodeVisitor *visitor) const override final
+
+Calls the  INodeVisitor's visit method. 
+";
+
+%feature("docstring")  FormFactorLongBox::getLength "double FormFactorLongBox::getLength() const
+";
+
+%feature("docstring")  FormFactorLongBox::getHeight "double FormFactorLongBox::getHeight() const
+";
+
+%feature("docstring")  FormFactorLongBox::getWidth "double FormFactorLongBox::getWidth() const
+";
+
+%feature("docstring")  FormFactorLongBox::radialExtension "double FormFactorLongBox::radialExtension() const override final
+
+Returns the (approximate in some cases) radial size of the particle of this form factor's shape. This is used for SSCA calculations 
+";
+
+%feature("docstring")  FormFactorLongBox::evaluate_for_q "complex_t FormFactorLongBox::evaluate_for_q(cvector_t q) const override final
+
+Returns scattering amplitude for complex scattering wavevector q=k_i-k_f. This method is public only for convenience of plotting form factors in Python. 
+";
+
+
 // File: classFormFactorLongBoxGauss.xml
 %feature("docstring") FormFactorLongBoxGauss "
 
@@ -5961,6 +5152,9 @@ Calls the  INodeVisitor's visit method.
 Returns Fourier transform of this distribution; is a decay function starting at evaluate(0)=1. 
 ";
 
+%feature("docstring")  FTDistribution1DCauchy::createSampler "std::unique_ptr< IDistribution1DSampler > FTDistribution1DCauchy::createSampler() const final
+";
+
 
 // File: classFTDistribution1DCosine.xml
 %feature("docstring") FTDistribution1DCosine "
@@ -5986,6 +5180,9 @@ Calls the  INodeVisitor's visit method.
 Returns Fourier transform of this distribution; is a decay function starting at evaluate(0)=1. 
 ";
 
+%feature("docstring")  FTDistribution1DCosine::createSampler "std::unique_ptr< IDistribution1DSampler > FTDistribution1DCosine::createSampler() const final
+";
+
 
 // File: classFTDistribution1DGate.xml
 %feature("docstring") FTDistribution1DGate "
@@ -6011,6 +5208,9 @@ Calls the  INodeVisitor's visit method.
 Returns Fourier transform of this distribution; is a decay function starting at evaluate(0)=1. 
 ";
 
+%feature("docstring")  FTDistribution1DGate::createSampler "std::unique_ptr< IDistribution1DSampler > FTDistribution1DGate::createSampler() const final
+";
+
 
 // File: classFTDistribution1DGauss.xml
 %feature("docstring") FTDistribution1DGauss "
@@ -6036,6 +5236,9 @@ Calls the  INodeVisitor's visit method.
 Returns Fourier transform of this distribution; is a decay function starting at evaluate(0)=1. 
 ";
 
+%feature("docstring")  FTDistribution1DGauss::createSampler "std::unique_ptr< IDistribution1DSampler > FTDistribution1DGauss::createSampler() const final
+";
+
 
 // File: classFTDistribution1DTriangle.xml
 %feature("docstring") FTDistribution1DTriangle "
@@ -6061,6 +5264,9 @@ Calls the  INodeVisitor's visit method.
 Returns Fourier transform of this distribution; is a decay function starting at evaluate(0)=1. 
 ";
 
+%feature("docstring")  FTDistribution1DTriangle::createSampler "std::unique_ptr< IDistribution1DSampler > FTDistribution1DTriangle::createSampler() const final
+";
+
 
 // File: classFTDistribution1DVoigt.xml
 %feature("docstring") FTDistribution1DVoigt "
@@ -6100,6 +5306,9 @@ Returns Fourier transform of this distribution; is a decay function starting at
 %feature("docstring")  FTDistribution1DVoigt::eta "double FTDistribution1DVoigt::eta() const
 ";
 
+%feature("docstring")  FTDistribution1DVoigt::createSampler "std::unique_ptr< IDistribution1DSampler > FTDistribution1DVoigt::createSampler() const final
+";
+
 
 // File: classFTDistribution2DCauchy.xml
 %feature("docstring") FTDistribution2DCauchy "
@@ -6125,6 +5334,9 @@ Calls the  INodeVisitor's visit method.
 evaluate Fourier transformed distribution for q in X,Y coordinates the original distribution (in real space) is assumed to be normalized: total integral is equal to 1 
 ";
 
+%feature("docstring")  FTDistribution2DCauchy::createSampler "std::unique_ptr< IDistribution2DSampler > FTDistribution2DCauchy::createSampler() const final
+";
+
 
 // File: classFTDistribution2DComponents.xml
 %feature("docstring") FTDistribution2DComponents "
@@ -6159,7 +5371,10 @@ Calls the  INodeVisitor's visit method.
 
 %feature("docstring")  FTDistribution2DCone::evaluate "double FTDistribution2DCone::evaluate(double qx, double qy) const final
 
-evaluate Fourier transformed distribution for q in X,Y coordinates the original distribution (in real space) is assumed to be normalized: total integral is equal to 1 
+evaluate Fourier transformed distribution for q in X,Y coordinates the original distribution (in real space) is assumed to be normalized: total integral is equal to 1 
+";
+
+%feature("docstring")  FTDistribution2DCone::createSampler "std::unique_ptr< IDistribution2DSampler > FTDistribution2DCone::createSampler() const final
 ";
 
 
@@ -6187,6 +5402,9 @@ Calls the  INodeVisitor's visit method.
 evaluate Fourier transformed distribution for q in X,Y coordinates the original distribution (in real space) is assumed to be normalized: total integral is equal to 1 
 ";
 
+%feature("docstring")  FTDistribution2DGate::createSampler "std::unique_ptr< IDistribution2DSampler > FTDistribution2DGate::createSampler() const final
+";
+
 
 // File: classFTDistribution2DGauss.xml
 %feature("docstring") FTDistribution2DGauss "
@@ -6212,6 +5430,9 @@ Calls the  INodeVisitor's visit method.
 evaluate Fourier transformed distribution for q in X,Y coordinates the original distribution (in real space) is assumed to be normalized: total integral is equal to 1 
 ";
 
+%feature("docstring")  FTDistribution2DGauss::createSampler "std::unique_ptr< IDistribution2DSampler > FTDistribution2DGauss::createSampler() const final
+";
+
 
 // File: classFTDistribution2DVoigt.xml
 %feature("docstring") FTDistribution2DVoigt "
@@ -6257,39 +5478,42 @@ evaluate Fourier transformed distribution for q in X,Y coordinates the original
 %feature("docstring")  FTDistribution2DVoigt::eta "double FTDistribution2DVoigt::eta() const
 ";
 
+%feature("docstring")  FTDistribution2DVoigt::createSampler "std::unique_ptr< IDistribution2DSampler > FTDistribution2DVoigt::createSampler() const final
+";
+
 
-// File: classGaussPeakShape.xml
-%feature("docstring") GaussPeakShape "
+// File: classGaussFisherPeakShape.xml
+%feature("docstring") GaussFisherPeakShape "
 
-Class that implements a Gaussian peak shape of a Bragg peak.
+Class that implements a peak shape that is Gaussian in the radial direction and uses the von Mises-Fisher distribution in the angular direction.
 
 C++ includes: IPeakShape.h
 ";
 
-%feature("docstring")  GaussPeakShape::GaussPeakShape "GaussPeakShape::GaussPeakShape(double domainsize)
+%feature("docstring")  GaussFisherPeakShape::GaussFisherPeakShape "GaussFisherPeakShape::GaussFisherPeakShape(double max_intensity, double radial_size, double kappa)
 ";
 
-%feature("docstring")  GaussPeakShape::~GaussPeakShape "GaussPeakShape::~GaussPeakShape() override
+%feature("docstring")  GaussFisherPeakShape::~GaussFisherPeakShape "GaussFisherPeakShape::~GaussFisherPeakShape() override
 ";
 
-%feature("docstring")  GaussPeakShape::clone "GaussPeakShape * GaussPeakShape::clone() const override
+%feature("docstring")  GaussFisherPeakShape::clone "GaussFisherPeakShape * GaussFisherPeakShape::clone() const override
 
 Returns a clone of this  ISample object. 
 ";
 
-%feature("docstring")  GaussPeakShape::accept "void GaussPeakShape::accept(INodeVisitor *visitor) const override
+%feature("docstring")  GaussFisherPeakShape::accept "void GaussFisherPeakShape::accept(INodeVisitor *visitor) const override
 
 Calls the  INodeVisitor's visit method. 
 ";
 
-%feature("docstring")  GaussPeakShape::evaluate "double GaussPeakShape::evaluate(const kvector_t q) const override
+%feature("docstring")  GaussFisherPeakShape::evaluate "double GaussFisherPeakShape::evaluate(const kvector_t q, const kvector_t q_lattice_point) const override
 
-Evaluates the peak shape at displacement q from the center at 0. 
+Evaluates the peak shape at q from a reciprocal lattice point at q_lattice_point. 
 ";
 
-%feature("docstring")  GaussPeakShape::thickness_z "double GaussPeakShape::thickness_z() const override
+%feature("docstring")  GaussFisherPeakShape::angularDisorder "bool GaussFisherPeakShape::angularDisorder() const override
 
-Returns the thickness in the z-direction. 
+Indicates if the peak shape encodes angular disorder, in which case all peaks in a spherical shell are needed 
 ";
 
 
@@ -6881,9 +6105,7 @@ C++ includes: IBackground.h
 // File: classIChiSquaredModule.xml
 %feature("docstring") IChiSquaredModule "
 
-Interface for  ChiSquaredModule for chi2 calculations.
-
-Until BornAgain-1.1, there was another child, ChiSquaredFrequency.
+Interface residual calculations.
 
 C++ includes: IChiSquaredModule.h
 ";
@@ -6899,35 +6121,17 @@ C++ includes: IChiSquaredModule.h
 clone method 
 ";
 
-%feature("docstring")  IChiSquaredModule::getSquaredFunction "const ISquaredFunction* IChiSquaredModule::getSquaredFunction() const
+%feature("docstring")  IChiSquaredModule::varianceFunction "const IVarianceFunction * IChiSquaredModule::varianceFunction() const
 
 Returns squared function. 
 ";
 
-%feature("docstring")  IChiSquaredModule::setChiSquaredFunction "void IChiSquaredModule::setChiSquaredFunction(ISquaredFunction *squared_function)
-
-Sets squared function // TODO: merge these two functions (SWIG warning 509) 
-";
-
-%feature("docstring")  IChiSquaredModule::setChiSquaredFunction "void IChiSquaredModule::setChiSquaredFunction(const ISquaredFunction &squared_function)
-";
-
-%feature("docstring")  IChiSquaredModule::getIntensityNormalizer "virtual const IIntensityNormalizer* IChiSquaredModule::getIntensityNormalizer() const
-
-Returns data normalizer. 
-";
-
-%feature("docstring")  IChiSquaredModule::getIntensityNormalizer "virtual IIntensityNormalizer* IChiSquaredModule::getIntensityNormalizer()
+%feature("docstring")  IChiSquaredModule::setVarianceFunction "void IChiSquaredModule::setVarianceFunction(const IVarianceFunction &variance_function)
 
-Returns data normalizer, non-const version needed to set internals. 
+Sets squared function. 
 ";
 
-%feature("docstring")  IChiSquaredModule::setIntensityNormalizer "void IChiSquaredModule::setIntensityNormalizer(const IIntensityNormalizer &data_normalizer)
-
-Sets data normalizer. 
-";
-
-%feature("docstring")  IChiSquaredModule::getIntensityFunction "virtual const IIntensityFunction* IChiSquaredModule::getIntensityFunction() const
+%feature("docstring")  IChiSquaredModule::getIntensityFunction "const IIntensityFunction * IChiSquaredModule::getIntensityFunction() const
 
 Returns data rescaler. 
 ";
@@ -6937,9 +6141,6 @@ Returns data rescaler.
 Sets data rescaler. 
 ";
 
-%feature("docstring")  IChiSquaredModule::processFitElements "virtual void IChiSquaredModule::processFitElements(std::vector< FitElement >::iterator, std::vector< FitElement >::iterator)
-";
-
 %feature("docstring")  IChiSquaredModule::residual "virtual double IChiSquaredModule::residual(double a, double b, double weight)=0
 ";
 
@@ -7357,175 +6558,71 @@ Sets distribution units.
 ";
 
 
-// File: classIFactory.xml
-%feature("docstring") IFactory "
-
-Base class for all factories.
-
-C++ includes: IFactory.h
-";
-
-%feature("docstring")  IFactory::IFactory "IFactory< Key, AbstractProduct >::IFactory()
-";
-
-%feature("docstring")  IFactory::createItem "AbstractProduct* IFactory< Key, AbstractProduct >::createItem(const Key &item_key)
-
-Creates object by calling creation function corresponded to given identifier. 
-";
-
-%feature("docstring")  IFactory::create "std::unique_ptr<AbstractProduct> IFactory< Key, AbstractProduct >::create(const Key &item_key) const
-";
-
-%feature("docstring")  IFactory::registerItem "bool IFactory< Key, AbstractProduct >::registerItem(const Key &item_key, CreateItemCallback CreateFn, const std::string &itemDescription=\"\")
-
-Registers object's creation function and store object description. 
-";
-
-%feature("docstring")  IFactory::contains "bool IFactory< Key, AbstractProduct >::contains(const Key &item_key) const
-";
-
-%feature("docstring")  IFactory::~IFactory "IFactory< Key, AbstractProduct >::~IFactory()
-";
-
-%feature("docstring")  IFactory::size "size_t IFactory< Key, AbstractProduct >::size() const
-
-Returns number of registered objects. 
-";
-
-%feature("docstring")  IFactory::begin "const_iterator IFactory< Key, AbstractProduct >::begin() const
-";
-
-%feature("docstring")  IFactory::end "const_iterator IFactory< Key, AbstractProduct >::end() const
-";
-
-
-// File: classIFitObserver.xml
-%feature("docstring") IFitObserver "
-
-Base class for all fit observers. Calls update method in following cases: first iteration, every n-th iteration, last iteration and when fit strategy has changed.
-
-C++ includes: IFitObserver.h
-";
-
-%feature("docstring")  IFitObserver::IFitObserver "IFitObserver::IFitObserver(int update_every_nth)
-";
-
-%feature("docstring")  IFitObserver::notify "void IFitObserver::notify(IObservable *subject)
-
-The method used by Ovservable when he wants to be observed by this. 
-";
-
-%feature("docstring")  IFitObserver::update "void IFitObserver::update(FitSuite *fit_suite)
-
-Here Onserver will do actuall job when he thinks that it is a right moment. 
-";
-
-
-// File: classIFitParameter.xml
-%feature("docstring") IFitParameter "
-
-A fittable parameter with value, error, step, and limits.
-
-C++ includes: IFitParameter.h
-";
-
-%feature("docstring")  IFitParameter::IFitParameter "IFitParameter::IFitParameter()
-";
-
-%feature("docstring")  IFitParameter::IFitParameter "IFitParameter::IFitParameter(const std::string &name, double value, const AttLimits &limits=AttLimits::limitless(), double step=0.0)
-";
-
-%feature("docstring")  IFitParameter::~IFitParameter "virtual IFitParameter::~IFitParameter()
-";
-
-%feature("docstring")  IFitParameter::clone "IFitParameter * IFitParameter::clone() const
-";
-
-%feature("docstring")  IFitParameter::name "std::string IFitParameter::name() const
-";
-
-%feature("docstring")  IFitParameter::setName "IFitParameter & IFitParameter::setName(const std::string &name)
-";
-
-%feature("docstring")  IFitParameter::startValue "double IFitParameter::startValue() const
-";
+// File: classIDistribution1DSampler.xml
+%feature("docstring") IDistribution1DSampler "";
 
-%feature("docstring")  IFitParameter::setStartValue "void IFitParameter::setStartValue(double value)
+%feature("docstring")  IDistribution1DSampler::IDistribution1DSampler "IDistribution1DSampler::IDistribution1DSampler()
 ";
 
-%feature("docstring")  IFitParameter::value "double IFitParameter::value() const
+%feature("docstring")  IDistribution1DSampler::~IDistribution1DSampler "IDistribution1DSampler::~IDistribution1DSampler()
 ";
 
-%feature("docstring")  IFitParameter::setValue "void IFitParameter::setValue(double value)
+%feature("docstring")  IDistribution1DSampler::randomSample "virtual double IDistribution1DSampler::randomSample() const =0
 ";
 
-%feature("docstring")  IFitParameter::addPattern "IFitParameter & IFitParameter::addPattern(const std::string &pattern)
-";
 
-%feature("docstring")  IFitParameter::step "double IFitParameter::step() const
-";
+// File: classIDistribution2DSampler.xml
+%feature("docstring") IDistribution2DSampler "";
 
-%feature("docstring")  IFitParameter::setStep "IFitParameter & IFitParameter::setStep(double value)
+%feature("docstring")  IDistribution2DSampler::IDistribution2DSampler "IDistribution2DSampler::IDistribution2DSampler()
 ";
 
-%feature("docstring")  IFitParameter::error "double IFitParameter::error() const
+%feature("docstring")  IDistribution2DSampler::~IDistribution2DSampler "IDistribution2DSampler::~IDistribution2DSampler()
 ";
 
-%feature("docstring")  IFitParameter::setError "void IFitParameter::setError(double value)
+%feature("docstring")  IDistribution2DSampler::randomSample "virtual std::pair<double, double> IDistribution2DSampler::randomSample() const =0
 ";
 
-%feature("docstring")  IFitParameter::limits "const AttLimits & IFitParameter::limits() const
-";
 
-%feature("docstring")  IFitParameter::limits "AttLimits & IFitParameter::limits()
-";
+// File: classIFactory.xml
+%feature("docstring") IFactory "
 
-%feature("docstring")  IFitParameter::setLimits "IFitParameter & IFitParameter::setLimits(const AttLimits &limits)
-";
+Base class for all factories.
 
-%feature("docstring")  IFitParameter::setLowerLimited "IFitParameter & IFitParameter::setLowerLimited(double bound_value)
+C++ includes: IFactory.h
 ";
 
-%feature("docstring")  IFitParameter::setPositive "IFitParameter & IFitParameter::setPositive()
+%feature("docstring")  IFactory::IFactory "IFactory< Key, AbstractProduct >::IFactory()
 ";
 
-%feature("docstring")  IFitParameter::setNonnegative "IFitParameter & IFitParameter::setNonnegative()
-";
+%feature("docstring")  IFactory::createItem "AbstractProduct* IFactory< Key, AbstractProduct >::createItem(const Key &item_key)
 
-%feature("docstring")  IFitParameter::setUpperLimited "IFitParameter & IFitParameter::setUpperLimited(double bound_value)
+Creates object by calling creation function corresponded to given identifier. 
 ";
 
-%feature("docstring")  IFitParameter::setLimited "IFitParameter & IFitParameter::setLimited(double left_bound_value, double right_bound_value)
+%feature("docstring")  IFactory::create "std::unique_ptr<AbstractProduct> IFactory< Key, AbstractProduct >::create(const Key &item_key) const
 ";
 
-%feature("docstring")  IFitParameter::setFixed "IFitParameter & IFitParameter::setFixed()
-";
+%feature("docstring")  IFactory::registerItem "bool IFactory< Key, AbstractProduct >::registerItem(const Key &item_key, CreateItemCallback CreateFn, const std::string &itemDescription=\"\")
 
-%feature("docstring")  IFitParameter::toString "std::string IFitParameter::toString() const
+Registers object's creation function and store object description. 
 ";
 
-
-// File: classIFitStrategy.xml
-%feature("docstring") IFitStrategy "
-
-Interface to concrete fit strategy. Concrete implementation should manipulate with fit parameters/data and then call minimizer.
-
-C++ includes: IFitStrategy.h
+%feature("docstring")  IFactory::contains "bool IFactory< Key, AbstractProduct >::contains(const Key &item_key) const
 ";
 
-%feature("docstring")  IFitStrategy::IFitStrategy "IFitStrategy::IFitStrategy(const std::string &name)
+%feature("docstring")  IFactory::~IFactory "IFactory< Key, AbstractProduct >::~IFactory()
 ";
 
-%feature("docstring")  IFitStrategy::~IFitStrategy "virtual IFitStrategy::~IFitStrategy()
-";
+%feature("docstring")  IFactory::size "size_t IFactory< Key, AbstractProduct >::size() const
 
-%feature("docstring")  IFitStrategy::clone "virtual IFitStrategy* IFitStrategy::clone() const =0
+Returns number of registered objects. 
 ";
 
-%feature("docstring")  IFitStrategy::init "void IFitStrategy::init(FitSuiteImpl *fit_suite)
+%feature("docstring")  IFactory::begin "const_iterator IFactory< Key, AbstractProduct >::begin() const
 ";
 
-%feature("docstring")  IFitStrategy::execute "virtual void IFitStrategy::execute()=0
+%feature("docstring")  IFactory::end "const_iterator IFactory< Key, AbstractProduct >::end() const
 ";
 
 
@@ -7895,6 +6992,9 @@ Returns Fourier transform of this distribution; is a decay function starting at
 %feature("docstring")  IFTDistribution1D::omega "double IFTDistribution1D::omega() const
 ";
 
+%feature("docstring")  IFTDistribution1D::createSampler "virtual std::unique_ptr<IDistribution1DSampler> IFTDistribution1D::createSampler() const =0
+";
+
 
 // File: classIFTDistribution2D.xml
 %feature("docstring") IFTDistribution2D "
@@ -7944,6 +7044,9 @@ angle in direct space between first lattice vector and x-axis of the distributio
 evaluate Fourier transformed distribution for q in X,Y coordinates the original distribution (in real space) is assumed to be normalized: total integral is equal to 1 
 ";
 
+%feature("docstring")  IFTDistribution2D::createSampler "virtual std::unique_ptr<IDistribution2DSampler> IFTDistribution2D::createSampler() const =0
+";
+
 
 // File: classIHistogram.xml
 %feature("docstring") IHistogram "
@@ -8251,7 +7354,7 @@ Interface for applying arbitrary function to the measured intensity.
 C++ includes: IIntensityFunction.h
 ";
 
-%feature("docstring")  IIntensityFunction::~IIntensityFunction "virtual IIntensityFunction::~IIntensityFunction()
+%feature("docstring")  IIntensityFunction::~IIntensityFunction "IIntensityFunction::~IIntensityFunction()
 ";
 
 %feature("docstring")  IIntensityFunction::clone "virtual IIntensityFunction* IIntensityFunction::clone() const =0
@@ -8663,12 +7766,6 @@ C++ includes: INodeVisitor.h
 %feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const DistributionTrapezoid *)
 ";
 
-%feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const FitObject *)
-";
-
-%feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const FitSuiteObjects *)
-";
-
 %feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const FootprintFactorGaussian *)
 ";
 
@@ -8738,6 +7835,9 @@ C++ includes: INodeVisitor.h
 %feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const FormFactorIcosahedron *)
 ";
 
+%feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const FormFactorLongBox *)
+";
+
 %feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const FormFactorLongBoxGauss *)
 ";
 
@@ -8888,24 +7988,27 @@ C++ includes: INodeVisitor.h
 %feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const InterferenceFunction2DLattice *)
 ";
 
-%feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const InterferenceFunction3DLattice *)
+%feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const InterferenceFunction2DParaCrystal *)
 ";
 
 %feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const InterferenceFunction2DSuperLattice *)
 ";
 
-%feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const InterferenceFunctionFinite2DLattice *)
+%feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const InterferenceFunction3DLattice *)
 ";
 
-%feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const InterferenceFunction2DParaCrystal *)
+%feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const InterferenceFunctionFinite2DLattice *)
 ";
 
-%feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const InterferenceFunctionNone *)
+%feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const InterferenceFunctionFinite3DLattice *)
 ";
 
 %feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const InterferenceFunctionRadialParaCrystal *)
 ";
 
+%feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const InterferenceFunctionNone *)
+";
+
 %feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const IParticle *)
 ";
 
@@ -9195,7 +8298,9 @@ perform the actual integration over the range [lmin, lmax]
 // File: classIntensityDataIOFactory.xml
 %feature("docstring") IntensityDataIOFactory "
 
-Provides users with possibility to read and write IntensityData from/to files in different format. Type of the file will be deduced from file name. *.txt - ASCII file with 2D array [nrow][ncol], layout as in numpy. *.int -  BornAgain internal ASCII format. *.tif - 32-bits tiff file. If file name ends woth \"*.gz\" or \"*.bz2\" the file will be zipped on the fly using appropriate algorithm. Usage:
+Provides users with possibility to read and write IntensityData from/to files in different format. Type of the file will be deduced from file name. *.txt - ASCII file with 2D array [nrow][ncol], layout as in numpy. *.int -  BornAgain internal ASCII format. *.tif - 32-bits tiff file. If file name ends woth \"*.gz\" or \"*.bz2\" the file will be zipped on the fly using appropriate algorithm.
+
+Usage:
 
 C++ includes: IntensityDataIOFactory.h
 ";
@@ -9209,10 +8314,7 @@ Algorithm for applying log function to the measured intensity.
 C++ includes: IIntensityFunction.h
 ";
 
-%feature("docstring")  IntensityFunctionLog::~IntensityFunctionLog "virtual IntensityFunctionLog::~IntensityFunctionLog()
-";
-
-%feature("docstring")  IntensityFunctionLog::clone "virtual IntensityFunctionLog* IntensityFunctionLog::clone() const
+%feature("docstring")  IntensityFunctionLog::clone "IntensityFunctionLog * IntensityFunctionLog::clone() const
 ";
 
 %feature("docstring")  IntensityFunctionLog::evaluate "double IntensityFunctionLog::evaluate(double value) const
@@ -9227,10 +8329,7 @@ Algorithm for applying sqrt function to the measured intensity.
 C++ includes: IIntensityFunction.h
 ";
 
-%feature("docstring")  IntensityFunctionSqrt::~IntensityFunctionSqrt "virtual IntensityFunctionSqrt::~IntensityFunctionSqrt()
-";
-
-%feature("docstring")  IntensityFunctionSqrt::clone "virtual IntensityFunctionSqrt* IntensityFunctionSqrt::clone() const
+%feature("docstring")  IntensityFunctionSqrt::clone "IntensityFunctionSqrt * IntensityFunctionSqrt::clone() const
 ";
 
 %feature("docstring")  IntensityFunctionSqrt::evaluate "double IntensityFunctionSqrt::evaluate(double value) const
@@ -9564,6 +8663,12 @@ If defined by this interference function's parameters, returns the particle dens
 Returns a vector of children (const). 
 ";
 
+%feature("docstring")  InterferenceFunction2DParaCrystal::pdf1 "const IFTDistribution2D* InterferenceFunction2DParaCrystal::pdf1() const
+";
+
+%feature("docstring")  InterferenceFunction2DParaCrystal::pdf2 "const IFTDistribution2D* InterferenceFunction2DParaCrystal::pdf2() const
+";
+
 
 // File: classInterferenceFunction2DSuperLattice.xml
 %feature("docstring") InterferenceFunction2DSuperLattice "
@@ -9685,11 +8790,6 @@ Evaluates the interference function for a given wavevector transfer (only the re
 %feature("docstring")  InterferenceFunction3DLattice::lattice "const Lattice & InterferenceFunction3DLattice::lattice() const
 ";
 
-%feature("docstring")  InterferenceFunction3DLattice::getParticleDensity "double InterferenceFunction3DLattice::getParticleDensity() const final
-
-If defined by this interference function's parameters, returns the particle density (per area). Otherwise, returns zero or a user-defined value 
-";
-
 %feature("docstring")  InterferenceFunction3DLattice::supportsMultilayer "bool InterferenceFunction3DLattice::supportsMultilayer() const override
 
 Indicates if this interference function can be used with a multilayer (DWBA mode) 
@@ -9714,12 +8814,26 @@ Interference function of 2D lattice.
 C++ includes: InterferenceFunctionFinite2DLattice.h
 ";
 
-%feature("docstring")  InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice "InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice(const Lattice2D &lattice, unsigned size_1, unsigned size_2)
+%feature("docstring")  InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice "InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice(const Lattice2D &lattice, unsigned N_1, unsigned N_2)
+
+Constructor of two-dimensional finite lattice interference function.
+
+Parameters:
+-----------
+
+lattice: 
+object specifying a 2d lattice structure
+
+N_1: 
+number of lattice cells in the first lattice direction
+
+N_2: 
+number of lattice cells in the second lattice direction 
 ";
 
-%feature("docstring")  InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice "InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice(double length_1, double length_2, double alpha, double xi, unsigned size_1, unsigned size_2)
+%feature("docstring")  InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice "InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice(double length_1, double length_2, double alpha, double xi, unsigned N_1, unsigned N_2)
 
-Constructor of two-dimensional interference function.
+Constructor of two-dimensional finite lattice interference function.
 
 Parameters:
 -----------
@@ -9734,7 +8848,13 @@ alpha:
 angle between lattice vectors in radians
 
 xi: 
-rotation of lattice with respect to x-axis (beam direction) in radians 
+rotation of lattice with respect to x-axis (beam direction) in radians
+
+N_1: 
+number of lattice cells in the first lattice direction
+
+N_2: 
+number of lattice cells in the second lattice direction 
 ";
 
 %feature("docstring")  InterferenceFunctionFinite2DLattice::~InterferenceFunctionFinite2DLattice "InterferenceFunctionFinite2DLattice::~InterferenceFunctionFinite2DLattice() final
@@ -9755,10 +8875,10 @@ Calls the  INodeVisitor's visit method.
 Evaluates the interference function for a given wavevector transfer (only the real x and y components are relevant) 
 ";
 
-%feature("docstring")  InterferenceFunctionFinite2DLattice::domainSize1 "unsigned InterferenceFunctionFinite2DLattice::domainSize1() const
+%feature("docstring")  InterferenceFunctionFinite2DLattice::numberUnitCells1 "unsigned InterferenceFunctionFinite2DLattice::numberUnitCells1() const
 ";
 
-%feature("docstring")  InterferenceFunctionFinite2DLattice::domainSize2 "unsigned InterferenceFunctionFinite2DLattice::domainSize2() const
+%feature("docstring")  InterferenceFunctionFinite2DLattice::numberUnitCells2 "unsigned InterferenceFunctionFinite2DLattice::numberUnitCells2() const
 ";
 
 %feature("docstring")  InterferenceFunctionFinite2DLattice::setPositionVariance "void InterferenceFunctionFinite2DLattice::setPositionVariance(double sigma2)
@@ -9787,6 +8907,67 @@ Returns a vector of children (const).
 ";
 
 
+// File: classInterferenceFunctionFinite3DLattice.xml
+%feature("docstring") InterferenceFunctionFinite3DLattice "
+
+Interference function of 2D lattice.
+
+C++ includes: InterferenceFunctionFinite3DLattice.h
+";
+
+%feature("docstring")  InterferenceFunctionFinite3DLattice::InterferenceFunctionFinite3DLattice "InterferenceFunctionFinite3DLattice::InterferenceFunctionFinite3DLattice(const Lattice &lattice, unsigned N_1, unsigned N_2, unsigned N_3)
+
+Constructor of three-dimensional finite lattice interference function.
+
+Parameters:
+-----------
+
+lattice: 
+object specifying a 2d lattice structure
+
+N_1: 
+number of lattice cells in the first lattice direction
+
+N_2: 
+number of lattice cells in the second lattice direction 
+";
+
+%feature("docstring")  InterferenceFunctionFinite3DLattice::~InterferenceFunctionFinite3DLattice "InterferenceFunctionFinite3DLattice::~InterferenceFunctionFinite3DLattice() final
+";
+
+%feature("docstring")  InterferenceFunctionFinite3DLattice::clone "InterferenceFunctionFinite3DLattice * InterferenceFunctionFinite3DLattice::clone() const final
+
+Returns a clone of this  ISample object. 
+";
+
+%feature("docstring")  InterferenceFunctionFinite3DLattice::accept "void InterferenceFunctionFinite3DLattice::accept(INodeVisitor *visitor) const final
+
+Calls the  INodeVisitor's visit method. 
+";
+
+%feature("docstring")  InterferenceFunctionFinite3DLattice::evaluate "double InterferenceFunctionFinite3DLattice::evaluate(const kvector_t q) const final
+
+Evaluates the interference function for a given wavevector transfer (only the real x and y components are relevant) 
+";
+
+%feature("docstring")  InterferenceFunctionFinite3DLattice::numberUnitCells1 "unsigned InterferenceFunctionFinite3DLattice::numberUnitCells1() const
+";
+
+%feature("docstring")  InterferenceFunctionFinite3DLattice::numberUnitCells2 "unsigned InterferenceFunctionFinite3DLattice::numberUnitCells2() const
+";
+
+%feature("docstring")  InterferenceFunctionFinite3DLattice::numberUnitCells3 "unsigned InterferenceFunctionFinite3DLattice::numberUnitCells3() const
+";
+
+%feature("docstring")  InterferenceFunctionFinite3DLattice::lattice "const Lattice & InterferenceFunctionFinite3DLattice::lattice() const
+";
+
+%feature("docstring")  InterferenceFunctionFinite3DLattice::getChildren "std::vector< const INode * > InterferenceFunctionFinite3DLattice::getChildren() const override
+
+Returns a vector of children (const). 
+";
+
+
 // File: classInterferenceFunctionNone.xml
 %feature("docstring") InterferenceFunctionNone "
 
@@ -9904,6 +9085,9 @@ probability distribution (Fourier transform of probability density)
 Returns a vector of children (const). 
 ";
 
+%feature("docstring")  InterferenceFunctionRadialParaCrystal::randomSample "double InterferenceFunctionRadialParaCrystal::randomSample() const
+";
+
 
 // File: classIObservable.xml
 %feature("docstring") IObservable "
@@ -10196,14 +9380,14 @@ C++ includes: IPeakShape.h
 Returns a clone of this  ISample object. 
 ";
 
-%feature("docstring")  IPeakShape::evaluate "virtual double IPeakShape::evaluate(const kvector_t q) const =0
+%feature("docstring")  IPeakShape::evaluate "virtual double IPeakShape::evaluate(const kvector_t q, const kvector_t q_lattice_point) const =0
 
-Evaluates the peak shape at displacement q from the center at 0. 
+Evaluates the peak shape at q from a reciprocal lattice point at q_lattice_point. 
 ";
 
-%feature("docstring")  IPeakShape::thickness_z "virtual double IPeakShape::thickness_z() const =0
+%feature("docstring")  IPeakShape::angularDisorder "virtual bool IPeakShape::angularDisorder() const
 
-Returns the thickness in the z-direction. 
+Indicates if the peak shape encodes angular disorder, in which case all peaks in a spherical shell are needed 
 ";
 
 
@@ -10431,30 +9615,63 @@ C++ includes: ISingleton.h
 ";
 
 
-// File: classISquaredFunction.xml
-%feature("docstring") ISquaredFunction "
+// File: classIsotropicGaussPeakShape.xml
+%feature("docstring") IsotropicGaussPeakShape "
+
+Class that implements an isotropic Gaussian peak shape of a Bragg peak.
+
+C++ includes: IPeakShape.h
+";
+
+%feature("docstring")  IsotropicGaussPeakShape::IsotropicGaussPeakShape "IsotropicGaussPeakShape::IsotropicGaussPeakShape(double max_intensity, double domainsize)
+";
+
+%feature("docstring")  IsotropicGaussPeakShape::~IsotropicGaussPeakShape "IsotropicGaussPeakShape::~IsotropicGaussPeakShape() override
+";
+
+%feature("docstring")  IsotropicGaussPeakShape::clone "IsotropicGaussPeakShape * IsotropicGaussPeakShape::clone() const override
+
+Returns a clone of this  ISample object. 
+";
+
+%feature("docstring")  IsotropicGaussPeakShape::accept "void IsotropicGaussPeakShape::accept(INodeVisitor *visitor) const override
+
+Calls the  INodeVisitor's visit method. 
+";
 
-Interface providing measures for deviation between two values. Used By  ChiSquaredModule for chi2 calculations.
+%feature("docstring")  IsotropicGaussPeakShape::evaluate "double IsotropicGaussPeakShape::evaluate(const kvector_t q, const kvector_t q_lattice_point) const override
 
-C++ includes: ISquaredFunction.h
+Evaluates the peak shape at q from a reciprocal lattice point at q_lattice_point. 
 ";
 
-%feature("docstring")  ISquaredFunction::ISquaredFunction "ISquaredFunction::ISquaredFunction()
+
+// File: classIsotropicLorentzPeakShape.xml
+%feature("docstring") IsotropicLorentzPeakShape "
+
+Class that implements an isotropic Lorentzian peak shape of a Bragg peak.
+
+C++ includes: IPeakShape.h
 ";
 
-%feature("docstring")  ISquaredFunction::~ISquaredFunction "virtual ISquaredFunction::~ISquaredFunction()
+%feature("docstring")  IsotropicLorentzPeakShape::IsotropicLorentzPeakShape "IsotropicLorentzPeakShape::IsotropicLorentzPeakShape(double max_intensity, double domainsize)
 ";
 
-%feature("docstring")  ISquaredFunction::clone "virtual ISquaredFunction* ISquaredFunction::clone() const =0
+%feature("docstring")  IsotropicLorentzPeakShape::~IsotropicLorentzPeakShape "IsotropicLorentzPeakShape::~IsotropicLorentzPeakShape() override
 ";
 
-%feature("docstring")  ISquaredFunction::calculateSquaredDifference "virtual double ISquaredFunction::calculateSquaredDifference(double real_value, double simulated_value) const =0
+%feature("docstring")  IsotropicLorentzPeakShape::clone "IsotropicLorentzPeakShape * IsotropicLorentzPeakShape::clone() const override
+
+Returns a clone of this  ISample object. 
 ";
 
-%feature("docstring")  ISquaredFunction::calculateSquaredError "virtual double ISquaredFunction::calculateSquaredError(double real_value, double simulated_value=0.0) const =0
+%feature("docstring")  IsotropicLorentzPeakShape::accept "void IsotropicLorentzPeakShape::accept(INodeVisitor *visitor) const override
+
+Calls the  INodeVisitor's visit method. 
 ";
 
-%feature("docstring")  ISquaredFunction::ISquaredFunction "ISquaredFunction::ISquaredFunction(const ISquaredFunction &)=delete
+%feature("docstring")  IsotropicLorentzPeakShape::evaluate "double IsotropicLorentzPeakShape::evaluate(const kvector_t q, const kvector_t q_lattice_point) const override
+
+Evaluates the peak shape at q from a reciprocal lattice point at q_lattice_point. 
 ";
 
 
@@ -10591,25 +9808,49 @@ C++ includes: IUnitConverter.h
 %feature("docstring")  IUnitConverter::dimension "virtual size_t IUnitConverter::dimension() const =0
 ";
 
-%feature("docstring")  IUnitConverter::calculateMin "virtual double IUnitConverter::calculateMin(size_t i_axis, AxesUnits units_type) const =0
-";
+%feature("docstring")  IUnitConverter::calculateMin "virtual double IUnitConverter::calculateMin(size_t i_axis, AxesUnits units_type) const =0
+";
+
+%feature("docstring")  IUnitConverter::calculateMax "virtual double IUnitConverter::calculateMax(size_t i_axis, AxesUnits units_type) const =0
+";
+
+%feature("docstring")  IUnitConverter::axisSize "virtual size_t IUnitConverter::axisSize(size_t i_axis) const =0
+";
+
+%feature("docstring")  IUnitConverter::axisName "std::string IUnitConverter::axisName(size_t i_axis, AxesUnits units_type=AxesUnits::DEFAULT) const
+";
+
+%feature("docstring")  IUnitConverter::availableUnits "virtual std::vector<AxesUnits> IUnitConverter::availableUnits() const =0
+";
+
+%feature("docstring")  IUnitConverter::defaultUnits "virtual AxesUnits IUnitConverter::defaultUnits() const =0
+";
+
+%feature("docstring")  IUnitConverter::createConvertedAxis "virtual std::unique_ptr<IAxis> IUnitConverter::createConvertedAxis(size_t i_axis, AxesUnits units) const =0
+";
+
+
+// File: classIVarianceFunction.xml
+%feature("docstring") IVarianceFunction "
+
+Variance function interface.
 
-%feature("docstring")  IUnitConverter::calculateMax "virtual double IUnitConverter::calculateMax(size_t i_axis, AxesUnits units_type) const =0
+C++ includes: VarianceFunctions.h
 ";
 
-%feature("docstring")  IUnitConverter::axisSize "virtual size_t IUnitConverter::axisSize(size_t i_axis) const =0
+%feature("docstring")  IVarianceFunction::IVarianceFunction "IVarianceFunction::IVarianceFunction()
 ";
 
-%feature("docstring")  IUnitConverter::axisName "std::string IUnitConverter::axisName(size_t i_axis, AxesUnits units_type=AxesUnits::DEFAULT) const
+%feature("docstring")  IVarianceFunction::~IVarianceFunction "IVarianceFunction::~IVarianceFunction()
 ";
 
-%feature("docstring")  IUnitConverter::availableUnits "virtual std::vector<AxesUnits> IUnitConverter::availableUnits() const =0
+%feature("docstring")  IVarianceFunction::clone "virtual IVarianceFunction* IVarianceFunction::clone() const =0
 ";
 
-%feature("docstring")  IUnitConverter::defaultUnits "virtual AxesUnits IUnitConverter::defaultUnits() const =0
+%feature("docstring")  IVarianceFunction::variance "virtual double IVarianceFunction::variance(double real_value, double simulated_value) const =0
 ";
 
-%feature("docstring")  IUnitConverter::createConvertedAxis "virtual std::unique_ptr<IAxis> IUnitConverter::createConvertedAxis(size_t i_axis, AxesUnits units) const =0
+%feature("docstring")  IVarianceFunction::IVarianceFunction "IVarianceFunction::IVarianceFunction(const IVarianceFunction &)=delete
 ";
 
 
@@ -10687,7 +9928,7 @@ Returns basis vector c.
 Resets the basis vectors. 
 ";
 
-%feature("docstring")  Lattice::getMillerDirection "kvector_t Lattice::getMillerDirection(int h, int k, int l) const
+%feature("docstring")  Lattice::getMillerDirection "kvector_t Lattice::getMillerDirection(double h, double k, double l) const
 
 Returns normalized direction corresponding to the given Miller indices. 
 ";
@@ -11134,6 +10375,21 @@ Returns true if area defined by two bins is inside or on border of polygon (more
 ";
 
 
+// File: classLinkedBoxDistributionBuilder.xml
+%feature("docstring") LinkedBoxDistributionBuilder "
+
+Distribution of boxes with main parameter and two linked parameters.
+
+C++ includes: ParticleDistributionsBuilder.h
+";
+
+%feature("docstring")  LinkedBoxDistributionBuilder::LinkedBoxDistributionBuilder "LinkedBoxDistributionBuilder::LinkedBoxDistributionBuilder()=default
+";
+
+%feature("docstring")  LinkedBoxDistributionBuilder::buildSample "MultiLayer * LinkedBoxDistributionBuilder::buildSample() const
+";
+
+
 // File: classLLData.xml
 %feature("docstring") LLData "
 
@@ -11186,6 +10442,41 @@ C++ includes: LLData.h
 ";
 
 
+// File: classLorentzFisherPeakShape.xml
+%feature("docstring") LorentzFisherPeakShape "
+
+Class that implements a peak shape that is Lorentzian in the radial direction and uses the von Mises-Fisher distribution in the angular direction.
+
+C++ includes: IPeakShape.h
+";
+
+%feature("docstring")  LorentzFisherPeakShape::LorentzFisherPeakShape "LorentzFisherPeakShape::LorentzFisherPeakShape(double max_intensity, double radial_size, double kappa)
+";
+
+%feature("docstring")  LorentzFisherPeakShape::~LorentzFisherPeakShape "LorentzFisherPeakShape::~LorentzFisherPeakShape() override
+";
+
+%feature("docstring")  LorentzFisherPeakShape::clone "LorentzFisherPeakShape * LorentzFisherPeakShape::clone() const override
+
+Returns a clone of this  ISample object. 
+";
+
+%feature("docstring")  LorentzFisherPeakShape::accept "void LorentzFisherPeakShape::accept(INodeVisitor *visitor) const override
+
+Calls the  INodeVisitor's visit method. 
+";
+
+%feature("docstring")  LorentzFisherPeakShape::evaluate "double LorentzFisherPeakShape::evaluate(const kvector_t q, const kvector_t q_lattice_point) const override
+
+Evaluates the peak shape at q from a reciprocal lattice point at q_lattice_point. 
+";
+
+%feature("docstring")  LorentzFisherPeakShape::angularDisorder "bool LorentzFisherPeakShape::angularDisorder() const override
+
+Indicates if the peak shape encodes angular disorder, in which case all peaks in a spherical shell are needed 
+";
+
+
 // File: classMagneticCylindersBuilder.xml
 %feature("docstring") MagneticCylindersBuilder "
 
@@ -11574,9 +10865,14 @@ C++ includes: MesoCrystalBuilder.h
 
 
 // File: structMillerIndex.xml
-%feature("docstring") MillerIndex "";
+%feature("docstring") MillerIndex "
+
+MillerIndex represents arbitrary directions in reciprocal space by allowing floating point index values
+
+C++ includes: ILatticeOrientation.h
+";
 
-%feature("docstring")  MillerIndex::MillerIndex "MillerIndex::MillerIndex(int h_, int k_, int l_)
+%feature("docstring")  MillerIndex::MillerIndex "MillerIndex::MillerIndex(double h_, double k_, double l_)
 ";
 
 
@@ -12594,7 +11890,7 @@ Returns number of parameters in the pool.
 
 Adds parameter to the pool, and returns reference to the input pointer.
 
-Returning the input pointer allows us to concatenate function calls like pool->addParameter( new  RealParameter(...) ).setLimits(-1,+1).setFixed().setUnit(\"nm\") 
+Returning the input pointer allows us to concatenate function calls like pool->addParameter( new RealParameter(...) ).setLimits(-1,+1).setFixed().setUnit(\"nm\") 
 ";
 
 %feature("docstring")  ParameterPool::parameter "RealParameter * ParameterPool::parameter(const std::string &name)
@@ -13273,10 +12569,7 @@ Parameters:
 -----------
 
 V: 
-oriented vertex list
-
-_sym_S2: 
-true if face has a perpedicular two-fold symmetry axis 
+oriented vertex list 
 ";
 
 %feature("docstring")  PolyhedralFace::area "double PolyhedralFace::area() const
@@ -14630,6 +13923,9 @@ Returns experimental data.
 Returns relative difference between simulation and experimental data. 
 ";
 
+%feature("docstring")  SimDataPair::absoluteDifference "SimulationResult SimDataPair::absoluteDifference() const
+";
+
 %feature("docstring")  SimDataPair::runSimulation "void SimDataPair::runSimulation(const Fit::Parameters &params)
 ";
 
@@ -14643,6 +13939,9 @@ Returns one dimensional array representing experimental data. Masked areas and t
 Returns one dimensional array representing simulated intensities data. Masked areas and the area outside of region of interest are not included. 
 ";
 
+%feature("docstring")  SimDataPair::weights_array "std::vector< double > SimDataPair::weights_array() const
+";
+
 
 // File: classSimpleSelectionRule.xml
 %feature("docstring") SimpleSelectionRule "
@@ -15649,126 +14948,6 @@ return default axes units
 ";
 
 
-// File: classSquaredFunctionDefault.xml
-%feature("docstring") SquaredFunctionDefault "
-
-Squared difference between two values. value = (a-b)*(a-b)/norm, where norm = max(b, 1.0), a = simulated values, b = real_values.
-
-C++ includes: ISquaredFunction.h
-";
-
-%feature("docstring")  SquaredFunctionDefault::SquaredFunctionDefault "SquaredFunctionDefault::SquaredFunctionDefault()
-";
-
-%feature("docstring")  SquaredFunctionDefault::~SquaredFunctionDefault "SquaredFunctionDefault::~SquaredFunctionDefault()
-";
-
-%feature("docstring")  SquaredFunctionDefault::clone "SquaredFunctionDefault * SquaredFunctionDefault::clone() const override
-";
-
-%feature("docstring")  SquaredFunctionDefault::calculateSquaredDifference "double SquaredFunctionDefault::calculateSquaredDifference(double real_value, double simulated_value) const override
-";
-
-%feature("docstring")  SquaredFunctionDefault::calculateSquaredError "double SquaredFunctionDefault::calculateSquaredError(double real_value, double simulated_value=0) const override
-";
-
-
-// File: classSquaredFunctionGaussianError.xml
-%feature("docstring") SquaredFunctionGaussianError "
-
-Squared difference between two values with gaussian error. value = (a-b)*(a-b)/norm, where norm = sigma*sigma; sigma is set by user.
-
-C++ includes: ISquaredFunction.h
-";
-
-%feature("docstring")  SquaredFunctionGaussianError::SquaredFunctionGaussianError "SquaredFunctionGaussianError::SquaredFunctionGaussianError(double sigma=0.01)
-";
-
-%feature("docstring")  SquaredFunctionGaussianError::~SquaredFunctionGaussianError "SquaredFunctionGaussianError::~SquaredFunctionGaussianError()
-";
-
-%feature("docstring")  SquaredFunctionGaussianError::clone "SquaredFunctionGaussianError * SquaredFunctionGaussianError::clone() const override
-";
-
-%feature("docstring")  SquaredFunctionGaussianError::calculateSquaredDifference "double SquaredFunctionGaussianError::calculateSquaredDifference(double real_value, double simulated_value) const override
-";
-
-%feature("docstring")  SquaredFunctionGaussianError::calculateSquaredError "double SquaredFunctionGaussianError::calculateSquaredError(double real_value, double simulated_value) const override
-";
-
-
-// File: classSquaredFunctionMeanSquaredError.xml
-%feature("docstring") SquaredFunctionMeanSquaredError "
-
-Squared difference between two values normalized by mean squared error. value = (a-b)*(a-b)/norm, where norm = sqrt(sigma1*sigma1 + sigma2*sigma2), sigma1=max(a, 1.0), sigma2=max(b,1.0)
-
-C++ includes: ISquaredFunction.h
-";
-
-%feature("docstring")  SquaredFunctionMeanSquaredError::SquaredFunctionMeanSquaredError "SquaredFunctionMeanSquaredError::SquaredFunctionMeanSquaredError()
-";
-
-%feature("docstring")  SquaredFunctionMeanSquaredError::~SquaredFunctionMeanSquaredError "SquaredFunctionMeanSquaredError::~SquaredFunctionMeanSquaredError()
-";
-
-%feature("docstring")  SquaredFunctionMeanSquaredError::clone "SquaredFunctionMeanSquaredError * SquaredFunctionMeanSquaredError::clone() const override
-";
-
-%feature("docstring")  SquaredFunctionMeanSquaredError::calculateSquaredDifference "double SquaredFunctionMeanSquaredError::calculateSquaredDifference(double real_value, double simulated_value) const override
-";
-
-%feature("docstring")  SquaredFunctionMeanSquaredError::calculateSquaredError "double SquaredFunctionMeanSquaredError::calculateSquaredError(double real_value, double simulated_value) const override
-";
-
-
-// File: classSquaredFunctionSimError.xml
-%feature("docstring") SquaredFunctionSimError "
-
-Squared difference between two values. value = (a-b)*(a-b)/norm, where norm = max(a, 1.0), a = simulated values, b = real_values.
-
-C++ includes: ISquaredFunction.h
-";
-
-%feature("docstring")  SquaredFunctionSimError::SquaredFunctionSimError "SquaredFunctionSimError::SquaredFunctionSimError()
-";
-
-%feature("docstring")  SquaredFunctionSimError::~SquaredFunctionSimError "SquaredFunctionSimError::~SquaredFunctionSimError()
-";
-
-%feature("docstring")  SquaredFunctionSimError::clone "SquaredFunctionSimError * SquaredFunctionSimError::clone() const override
-";
-
-%feature("docstring")  SquaredFunctionSimError::calculateSquaredDifference "double SquaredFunctionSimError::calculateSquaredDifference(double real_value, double simulated_value) const override
-";
-
-%feature("docstring")  SquaredFunctionSimError::calculateSquaredError "double SquaredFunctionSimError::calculateSquaredError(double real_value, double simulated_value) const override
-";
-
-
-// File: classSquaredFunctionSystematicError.xml
-%feature("docstring") SquaredFunctionSystematicError "
-
-Squared difference between two values normalized by systematic error. value = (a-b)*(a-b)/norm, where norm = max(error, 1.0), error = b + (epsilon*b)**2.
-
-C++ includes: ISquaredFunction.h
-";
-
-%feature("docstring")  SquaredFunctionSystematicError::SquaredFunctionSystematicError "SquaredFunctionSystematicError::SquaredFunctionSystematicError(double epsilon=0.08)
-";
-
-%feature("docstring")  SquaredFunctionSystematicError::~SquaredFunctionSystematicError "SquaredFunctionSystematicError::~SquaredFunctionSystematicError()
-";
-
-%feature("docstring")  SquaredFunctionSystematicError::clone "SquaredFunctionSystematicError * SquaredFunctionSystematicError::clone() const override
-";
-
-%feature("docstring")  SquaredFunctionSystematicError::calculateSquaredDifference "double SquaredFunctionSystematicError::calculateSquaredDifference(double real_value, double simulated_value) const override
-";
-
-%feature("docstring")  SquaredFunctionSystematicError::calculateSquaredError "double SquaredFunctionSystematicError::calculateSquaredError(double real_value, double simulated_value) const override
-";
-
-
 // File: classSquareLattice.xml
 %feature("docstring") SquareLattice "";
 
@@ -16126,7 +15305,7 @@ Conversion of axis units for the case of 1D simulation result (specular simulati
 C++ includes: UnitConverter1D.h
 ";
 
-%feature("docstring")  UnitConverter1D::UnitConverter1D "UnitConverter1D::UnitConverter1D(const Beam &beam, const IAxis &axis)
+%feature("docstring")  UnitConverter1D::UnitConverter1D "UnitConverter1D::UnitConverter1D(const Beam &beam, const IAxis &axis, AxesUnits axis_units=AxesUnits::RADIANS)
 
 Constructs the object for unit conversion. Input axis is in radians. 
 ";
@@ -16288,6 +15467,39 @@ Creates a new clipped axis.
 ";
 
 
+// File: classVarianceConstantFunction.xml
+%feature("docstring") VarianceConstantFunction "
+
+Returns 1.0 as variance value
+
+C++ includes: VarianceFunctions.h
+";
+
+%feature("docstring")  VarianceConstantFunction::clone "VarianceConstantFunction * VarianceConstantFunction::clone() const override
+";
+
+%feature("docstring")  VarianceConstantFunction::variance "double VarianceConstantFunction::variance(double, double) const override
+";
+
+
+// File: classVarianceSimFunction.xml
+%feature("docstring") VarianceSimFunction "
+
+Returns max(sim, epsilon)
+
+C++ includes: VarianceFunctions.h
+";
+
+%feature("docstring")  VarianceSimFunction::VarianceSimFunction "VarianceSimFunction::VarianceSimFunction(double epsilon=1.0)
+";
+
+%feature("docstring")  VarianceSimFunction::clone "VarianceSimFunction * VarianceSimFunction::clone() const override
+";
+
+%feature("docstring")  VarianceSimFunction::variance "double VarianceSimFunction::variance(double exp, double sim) const override
+";
+
+
 // File: classVerticalLine.xml
 %feature("docstring") VerticalLine "
 
@@ -16385,124 +15597,124 @@ C++ includes: ZLimits.h
 ";
 
 
-// File: namespace_0D112.xml
+// File: namespace_0D103.xml
 
 
-// File: namespace_0D121.xml
+// File: namespace_0D118.xml
 
 
-// File: namespace_0D127.xml
+// File: namespace_0D12.xml
 
 
-// File: namespace_0D134.xml
+// File: namespace_0D127.xml
 
 
-// File: namespace_0D14.xml
+// File: namespace_0D129.xml
 
 
-// File: namespace_0D16.xml
+// File: namespace_0D132.xml
 
 
-// File: namespace_0D20.xml
+// File: namespace_0D18.xml
 
 
-// File: namespace_0D205.xml
+// File: namespace_0D185.xml
 
 
-// File: namespace_0D22.xml
+// File: namespace_0D20.xml
 
 
-// File: namespace_0D232.xml
+// File: namespace_0D212.xml
 
 
-// File: namespace_0D234.xml
+// File: namespace_0D214.xml
 
 
-// File: namespace_0D24.xml
+// File: namespace_0D226.xml
 
 
-// File: namespace_0D246.xml
+// File: namespace_0D291.xml
 
 
-// File: namespace_0D315.xml
+// File: namespace_0D295.xml
 
 
-// File: namespace_0D319.xml
+// File: namespace_0D307.xml
 
 
-// File: namespace_0D32.xml
+// File: namespace_0D313.xml
 
 
-// File: namespace_0D331.xml
+// File: namespace_0D334.xml
 
 
-// File: namespace_0D335.xml
+// File: namespace_0D338.xml
 
 
-// File: namespace_0D356.xml
+// File: namespace_0D340.xml
 
 
-// File: namespace_0D360.xml
+// File: namespace_0D342.xml
 
 
-// File: namespace_0D362.xml
+// File: namespace_0D350.xml
 
 
-// File: namespace_0D364.xml
+// File: namespace_0D36.xml
 
 
-// File: namespace_0D372.xml
+// File: namespace_0D367.xml
 
 
-// File: namespace_0D389.xml
+// File: namespace_0D375.xml
 
 
-// File: namespace_0D397.xml
+// File: namespace_0D38.xml
 
 
-// File: namespace_0D403.xml
+// File: namespace_0D381.xml
 
 
-// File: namespace_0D406.xml
+// File: namespace_0D384.xml
 
 
-// File: namespace_0D408.xml
+// File: namespace_0D386.xml
 
 
-// File: namespace_0D429.xml
+// File: namespace_0D394.xml
 
 
-// File: namespace_0D438.xml
+// File: namespace_0D407.xml
 
 
-// File: namespace_0D472.xml
+// File: namespace_0D416.xml
 
 
-// File: namespace_0D479.xml
+// File: namespace_0D450.xml
 
 
-// File: namespace_0D517.xml
+// File: namespace_0D457.xml
 
 
-// File: namespace_0D525.xml
+// File: namespace_0D495.xml
 
 
-// File: namespace_0D527.xml
+// File: namespace_0D503.xml
 
 
-// File: namespace_0D529.xml
+// File: namespace_0D505.xml
 
 
-// File: namespace_0D611.xml
+// File: namespace_0D507.xml
 
 
-// File: namespace_0D633.xml
+// File: namespace_0D589.xml
 
 
-// File: namespace_0D88.xml
+// File: namespace_0D611.xml
 
 
-// File: namespace_0D97.xml
+// File: namespace_0D94.xml
 
 
 // File: namespaceArrayUtils.xml
@@ -16568,28 +15780,28 @@ vector<vector<double>>
 
 
 // File: namespaceAxisNames.xml
-%feature("docstring")  AxisNames::InitSphericalAxis0 "std::map< AxesUnits, std::string > AxisNames::InitSphericalAxis0()
+%feature("docstring")  AxisNames::InitSphericalAxis0 "BA_CORE_API_ std::map< AxesUnits, std::string > AxisNames::InitSphericalAxis0()
 ";
 
-%feature("docstring")  AxisNames::InitSphericalAxis1 "std::map< AxesUnits, std::string > AxisNames::InitSphericalAxis1()
+%feature("docstring")  AxisNames::InitSphericalAxis1 "BA_CORE_API_ std::map< AxesUnits, std::string > AxisNames::InitSphericalAxis1()
 ";
 
-%feature("docstring")  AxisNames::InitRectangularAxis0 "std::map< AxesUnits, std::string > AxisNames::InitRectangularAxis0()
+%feature("docstring")  AxisNames::InitRectangularAxis0 "BA_CORE_API_ std::map< AxesUnits, std::string > AxisNames::InitRectangularAxis0()
 ";
 
-%feature("docstring")  AxisNames::InitRectangularAxis1 "std::map< AxesUnits, std::string > AxisNames::InitRectangularAxis1()
+%feature("docstring")  AxisNames::InitRectangularAxis1 "BA_CORE_API_ std::map< AxesUnits, std::string > AxisNames::InitRectangularAxis1()
 ";
 
-%feature("docstring")  AxisNames::InitOffSpecAxis0 "std::map< AxesUnits, std::string > AxisNames::InitOffSpecAxis0()
+%feature("docstring")  AxisNames::InitOffSpecAxis0 "BA_CORE_API_ std::map< AxesUnits, std::string > AxisNames::InitOffSpecAxis0()
 ";
 
-%feature("docstring")  AxisNames::InitOffSpecAxis1 "std::map< AxesUnits, std::string > AxisNames::InitOffSpecAxis1()
+%feature("docstring")  AxisNames::InitOffSpecAxis1 "BA_CORE_API_ std::map< AxesUnits, std::string > AxisNames::InitOffSpecAxis1()
 ";
 
-%feature("docstring")  AxisNames::InitSpecAxis "std::map< AxesUnits, std::string > AxisNames::InitSpecAxis()
+%feature("docstring")  AxisNames::InitSpecAxis "BA_CORE_API_ std::map< AxesUnits, std::string > AxisNames::InitSpecAxis()
 ";
 
-%feature("docstring")  AxisNames::InitSampleDepthAxis "std::map< AxesUnits, std::string > AxisNames::InitSampleDepthAxis()
+%feature("docstring")  AxisNames::InitSampleDepthAxis "BA_CORE_API_ std::map< AxesUnits, std::string > AxisNames::InitSampleDepthAxis()
 ";
 
 
@@ -16751,28 +15963,6 @@ Returns file names that agree with a regex glob pattern.
 // File: namespaceFit.xml
 
 
-// File: namespaceFitSuiteUtils.xml
-%feature("docstring")  FitSuiteUtils::linkedParameters "std::vector< FitParameter * > FitSuiteUtils::linkedParameters(const FitParameterSet &fitParameters)
-
-Returns vector of linked parameters. 
-";
-
-%feature("docstring")  FitSuiteUtils::linkToString "std::string FitSuiteUtils::linkToString(const FitParameter &par)
-
-Returns multiline string representing linked sample parameters. 
-";
-
-%feature("docstring")  FitSuiteUtils::fitParameterSettingsToString "std::string FitSuiteUtils::fitParameterSettingsToString(const FitParameterSet &fitParameters)
-
-Returns multiline string representing fit parameter definition. 
-";
-
-%feature("docstring")  FitSuiteUtils::hasConflicts "bool FitSuiteUtils::hasConflicts(const FitParameterSet &fitParameters)
-
-Validates all fit parameters for conflicts (steering same sample parameters). 
-";
-
-
 // File: namespaceIComputationUtils.xml
 %feature("docstring")  IComputationUtils::CreateFresnelMap "std::unique_ptr< IFresnelMap > IComputationUtils::CreateFresnelMap(const MultiLayer &multilayer, const SimulationOptions &sim_options)
 ";
@@ -16988,7 +16178,9 @@ Complex sinc function:  $sinc(x)\\\\equiv\\\\sin(x)/x$.
 Complex tanhc function:  $tanhc(x)\\\\equiv\\\\tanh(x)/x$. 
 ";
 
-%feature("docstring")  MathFunctions::Laue "complex_t MathFunctions::Laue(const complex_t z, size_t N)
+%feature("docstring")  MathFunctions::Laue "double MathFunctions::Laue(const double x, size_t N)
+
+Real Laue function:  $Laue(x,N)\\\\equiv\\\\sin(Nx)/sin(x)$. 
 ";
 
 %feature("docstring")  MathFunctions::erf "double MathFunctions::erf(double arg)
@@ -17261,7 +16453,14 @@ Prints  ParameterDistribution. distVarName is a string representing  IDistributi
 ba.ParameterDistribution(\"/Particle/Height\", distr_1, 10, 0.0, ba.RealLimits.limited(1*nm,2*nm)) 
 ";
 
-%feature("docstring")  PythonFormatting::printAxis "BA_CORE_API_ std::string PythonFormatting::printAxis(const IAxis &axis, const std::string &units)
+%feature("docstring")  PythonFormatting::printAxis "BA_CORE_API_ std::string PythonFormatting::printAxis(const IAxis &axis, const std::string &units, size_t offset)
+
+Prints python-script definition for given axis. offset is used for alignment and indentation in multiple-line definitions 
+";
+
+%feature("docstring")  PythonFormatting::indent "BA_CORE_API_ std::string PythonFormatting::indent(size_t width)
+
+Returns a string of blanks with given width. By default the width equals standard offset in python files. 
 ";
 
 %feature("docstring")  PythonFormatting::printInt "BA_CORE_API_ std::string PythonFormatting::printInt(int value)
@@ -17386,6 +16585,11 @@ GISAS simulation with rectangular detector, region of interest and mask.
 %feature("docstring")  StandardSimulations::ConstantBackgroundGISAS "GISASSimulation * StandardSimulations::ConstantBackgroundGISAS()
 ";
 
+%feature("docstring")  StandardSimulations::MiniGISASFit "GISASSimulation * StandardSimulations::MiniGISASFit()
+
+Simulation with fitting.  Beam intensity set to provide reasonably large values in detector channels. 
+";
+
 %feature("docstring")  StandardSimulations::BasicSpecular "SpecularSimulation * StandardSimulations::BasicSpecular()
 ";
 
@@ -17483,6 +16687,18 @@ Helper factory function to use in  GISASSimulation. Depending on the type of det
 // File: FTDistributions2D_8h.xml
 
 
+// File: IDistribution1DSampler_8cpp.xml
+
+
+// File: IDistribution1DSampler_8h.xml
+
+
+// File: IDistribution2DSampler_8cpp.xml
+
+
+// File: IDistribution2DSampler_8h.xml
+
+
 // File: IInterferenceFunction_8cpp.xml
 
 
@@ -17531,6 +16747,12 @@ Helper factory function to use in  GISASSimulation. Depending on the type of det
 // File: InterferenceFunctionFinite2DLattice_8h.xml
 
 
+// File: InterferenceFunctionFinite3DLattice_8cpp.xml
+
+
+// File: InterferenceFunctionFinite3DLattice_8h.xml
+
+
 // File: InterferenceFunctionNone_8cpp.xml
 
 
@@ -17843,18 +17065,6 @@ global helper function for comparison of axes
 // File: SimulationToPython_8h.xml
 
 
-// File: AdjustMinimizerStrategy_8cpp.xml
-
-
-// File: AdjustMinimizerStrategy_8h.xml
-
-
-// File: FitObject_8cpp.xml
-
-
-// File: FitObject_8h.xml
-
-
 // File: FitObjective_8cpp.xml
 
 
@@ -17864,18 +17074,6 @@ global helper function for comparison of axes
 // File: FitObserver_8h.xml
 
 
-// File: FitParameter_8cpp.xml
-
-
-// File: FitParameter_8h.xml
-
-
-// File: FitParameterSet_8cpp.xml
-
-
-// File: FitParameterSet_8h.xml
-
-
 // File: FitPrintService_8cpp.xml
 
 
@@ -17888,69 +17086,9 @@ global helper function for comparison of axes
 // File: FitStatus_8h.xml
 
 
-// File: FitStrategyAdjustParameters_8cpp.xml
-
-
-// File: FitStrategyAdjustParameters_8h.xml
-
-
-// File: FitSuite_8cpp.xml
-
-
-// File: FitSuite_8h.xml
-
-
-// File: FitSuiteImpl_8cpp.xml
-
-
-// File: FitSuiteImpl_8h.xml
-
-
-// File: FitSuiteObjects_8cpp.xml
-
-
-// File: FitSuiteObjects_8h.xml
-
-
-// File: FitSuitePrintObserver_8cpp.xml
-
-
-// File: FitSuitePrintObserver_8h.xml
-
-
-// File: FitSuiteStrategies_8cpp.xml
-
-
-// File: FitSuiteStrategies_8h.xml
-
-
-// File: FitSuiteUtils_8cpp.xml
-
-
-// File: FitSuiteUtils_8h.xml
-
-
 // File: FitTypes_8h.xml
 
 
-// File: IFitObserver_8cpp.xml
-
-
-// File: IFitObserver_8h.xml
-
-
-// File: IFitParameter_8cpp.xml
-
-
-// File: IFitParameter_8h.xml
-
-
-// File: IFitStrategy_8cpp.xml
-
-
-// File: IFitStrategy_8h.xml
-
-
 // File: IObserver_8cpp.xml
 
 
@@ -18053,6 +17191,12 @@ global helper function for comparison of axes
 // File: FormFactorIcosahedron_8h.xml
 
 
+// File: FormFactorLongBox_8cpp.xml
+
+
+// File: FormFactorLongBox_8h.xml
+
+
 // File: FormFactorLongBoxGauss_8cpp.xml
 
 
@@ -18284,12 +17428,6 @@ global helper function for comparison of axes
 // File: DetectorMask_8h.xml
 
 
-// File: FitElement_8cpp.xml
-
-
-// File: FitElement_8h.xml
-
-
 // File: FourierTransform_8cpp.xml
 
 
@@ -18368,12 +17506,6 @@ global helper function for comparison of axes
 // File: IsGISAXSDetector_8h.xml
 
 
-// File: ISquaredFunction_8cpp.xml
-
-
-// File: ISquaredFunction_8h.xml
-
-
 // File: IUnitConverter_8cpp.xml
 
 
@@ -18485,6 +17617,12 @@ make Swappable
 // File: UnitConverterUtils_8h.xml
 
 
+// File: VarianceFunctions_8cpp.xml
+
+
+// File: VarianceFunctions_8h.xml
+
+
 // File: ILatticeOrientation_8cpp.xml
 
 
diff --git a/auto/Wrap/doxygen_fit.i b/auto/Wrap/doxygen_fit.i
index 4e9c9e16ac76de4163682ddeaa78f450b1ba13da..0739b4fb73afff084d6b95cff6a194711389bb32 100644
--- a/auto/Wrap/doxygen_fit.i
+++ b/auto/Wrap/doxygen_fit.i
@@ -989,7 +989,7 @@ Pure virtual interface that adapts the CERN ROOT minimizer to our  IMinimizer.
 C++ includes: RootMinimizerAdapter.h
 ";
 
-%feature("docstring")  RootMinimizerAdapter::~RootMinimizerAdapter "RootMinimizerAdapter::~RootMinimizerAdapter()
+%feature("docstring")  RootMinimizerAdapter::~RootMinimizerAdapter "RootMinimizerAdapter::~RootMinimizerAdapter() override
 ";
 
 %feature("docstring")  RootMinimizerAdapter::minimize_scalar "MinimizerResult RootMinimizerAdapter::minimize_scalar(fcn_scalar_t fcn, Fit::Parameters parameters) override
@@ -1225,7 +1225,7 @@ C++ includes: TestMinimizer.h
 %feature("docstring")  TestMinimizer::TestMinimizer "TestMinimizer::TestMinimizer()
 ";
 
-%feature("docstring")  TestMinimizer::~TestMinimizer "TestMinimizer::~TestMinimizer()
+%feature("docstring")  TestMinimizer::~TestMinimizer "TestMinimizer::~TestMinimizer() override
 ";
 
 %feature("docstring")  TestMinimizer::minimizerName "std::string TestMinimizer::minimizerName() const final
diff --git a/auto/Wrap/libBornAgainCore.py b/auto/Wrap/libBornAgainCore.py
index 4737eb203da5db5f04920f2b7a68c6c10f95278e..6eb2770156541e79a23b9edac4bbe5301de7524d 100644
--- a/auto/Wrap/libBornAgainCore.py
+++ b/auto/Wrap/libBornAgainCore.py
@@ -5177,9 +5177,7 @@ class IChiSquaredModule(ICloneable):
     """
 
 
-    Interface for  ChiSquaredModule for chi2 calculations.
-
-    Until BornAgain-1.1, there was another child, ChiSquaredFrequency.
+    Interface residual calculations.
 
     C++ includes: IChiSquaredModule.h
 
@@ -5212,59 +5210,35 @@ class IChiSquaredModule(ICloneable):
         return _libBornAgainCore.IChiSquaredModule_clone(self)
 
 
-    def getSquaredFunction(self):
+    def varianceFunction(self):
         """
-        getSquaredFunction(IChiSquaredModule self) -> ISquaredFunction
+        varianceFunction(IChiSquaredModule self) -> IVarianceFunction
 
-        const ISquaredFunction* IChiSquaredModule::getSquaredFunction() const
+        const IVarianceFunction * IChiSquaredModule::varianceFunction() const
 
         Returns squared function. 
 
         """
-        return _libBornAgainCore.IChiSquaredModule_getSquaredFunction(self)
-
-
-    def setChiSquaredFunction(self, *args):
-        """
-        setChiSquaredFunction(IChiSquaredModule self, ISquaredFunction squared_function)
-        setChiSquaredFunction(IChiSquaredModule self, ISquaredFunction squared_function)
-
-        void IChiSquaredModule::setChiSquaredFunction(const ISquaredFunction &squared_function)
-
-        """
-        return _libBornAgainCore.IChiSquaredModule_setChiSquaredFunction(self, *args)
-
-
-    def getIntensityNormalizer(self, *args):
-        """
-        getIntensityNormalizer(IChiSquaredModule self) -> IIntensityNormalizer
-        getIntensityNormalizer(IChiSquaredModule self) -> IIntensityNormalizer
-
-        virtual IIntensityNormalizer* IChiSquaredModule::getIntensityNormalizer()
-
-        Returns data normalizer, non-const version needed to set internals. 
-
-        """
-        return _libBornAgainCore.IChiSquaredModule_getIntensityNormalizer(self, *args)
+        return _libBornAgainCore.IChiSquaredModule_varianceFunction(self)
 
 
-    def setIntensityNormalizer(self, data_normalizer):
+    def setVarianceFunction(self, variance_function):
         """
-        setIntensityNormalizer(IChiSquaredModule self, IIntensityNormalizer data_normalizer)
+        setVarianceFunction(IChiSquaredModule self, IVarianceFunction variance_function)
 
-        void IChiSquaredModule::setIntensityNormalizer(const IIntensityNormalizer &data_normalizer)
+        void IChiSquaredModule::setVarianceFunction(const IVarianceFunction &variance_function)
 
-        Sets data normalizer. 
+        Sets squared function. 
 
         """
-        return _libBornAgainCore.IChiSquaredModule_setIntensityNormalizer(self, data_normalizer)
+        return _libBornAgainCore.IChiSquaredModule_setVarianceFunction(self, variance_function)
 
 
     def getIntensityFunction(self):
         """
         getIntensityFunction(IChiSquaredModule self) -> IIntensityFunction
 
-        virtual const IIntensityFunction* IChiSquaredModule::getIntensityFunction() const
+        const IIntensityFunction * IChiSquaredModule::getIntensityFunction() const
 
         Returns data rescaler. 
 
@@ -5284,16 +5258,6 @@ class IChiSquaredModule(ICloneable):
         return _libBornAgainCore.IChiSquaredModule_setIntensityFunction(self, intensity_function)
 
 
-    def processFitElements(self, arg2, arg3):
-        """
-        processFitElements(IChiSquaredModule self, std::vector< FitElement,std::allocator< FitElement > >::iterator arg2, std::vector< FitElement,std::allocator< FitElement > >::iterator arg3)
-
-        virtual void IChiSquaredModule::processFitElements(std::vector< FitElement >::iterator, std::vector< FitElement >::iterator)
-
-        """
-        return _libBornAgainCore.IChiSquaredModule_processFitElements(self, arg2, arg3)
-
-
     def residual(self, a, b, weight):
         """
         residual(IChiSquaredModule self, double a, double b, double weight) -> double
@@ -5394,205 +5358,14 @@ class IObservable(_object):
         C++ includes: IObserver.h
 
         """
-        if self.__class__ == IObservable:
-            _self = None
-        else:
-            _self = self
-        this = _libBornAgainCore.new_IObservable(_self, )
+        this = _libBornAgainCore.new_IObservable()
         try:
             self.this.append(this)
         except __builtin__.Exception:
             self.this = this
-    def __disown__(self):
-        self.this.disown()
-        _libBornAgainCore.disown_IObservable(self)
-        return weakref_proxy(self)
 IObservable_swigregister = _libBornAgainCore.IObservable_swigregister
 IObservable_swigregister(IObservable)
 
-class IFitObserver(IObserver):
-    """
-
-
-    Base class for all fit observers. Calls update method in following cases: first iteration, every n-th iteration, last iteration and when fit strategy has changed.
-
-    C++ includes: IFitObserver.h
-
-    """
-
-    __swig_setmethods__ = {}
-    for _s in [IObserver]:
-        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
-    __setattr__ = lambda self, name, value: _swig_setattr(self, IFitObserver, name, value)
-    __swig_getmethods__ = {}
-    for _s in [IObserver]:
-        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
-    __getattr__ = lambda self, name: _swig_getattr(self, IFitObserver, name)
-    __repr__ = _swig_repr
-
-    def __init__(self, update_every_nth):
-        """
-        __init__(IFitObserver self, int update_every_nth) -> IFitObserver
-
-        IFitObserver::IFitObserver(int update_every_nth)
-
-        """
-        if self.__class__ == IFitObserver:
-            _self = None
-        else:
-            _self = self
-        this = _libBornAgainCore.new_IFitObserver(_self, update_every_nth)
-        try:
-            self.this.append(this)
-        except __builtin__.Exception:
-            self.this = this
-
-    def notify(self, subject):
-        """
-        notify(IFitObserver self, IObservable subject)
-
-        void IFitObserver::notify(IObservable *subject)
-
-        The method used by Ovservable when he wants to be observed by this. 
-
-        """
-        return _libBornAgainCore.IFitObserver_notify(self, subject)
-
-
-    def update(self, fit_suite):
-        """
-        update(IFitObserver self, FitSuite fit_suite)
-
-        void IFitObserver::update(FitSuite *fit_suite)
-
-        Here Onserver will do actuall job when he thinks that it is a right moment. 
-
-        """
-        return _libBornAgainCore.IFitObserver_update(self, fit_suite)
-
-    __swig_destroy__ = _libBornAgainCore.delete_IFitObserver
-    __del__ = lambda self: None
-    def __disown__(self):
-        self.this.disown()
-        _libBornAgainCore.disown_IFitObserver(self)
-        return weakref_proxy(self)
-IFitObserver_swigregister = _libBornAgainCore.IFitObserver_swigregister
-IFitObserver_swigregister(IFitObserver)
-
-class IFitStrategy(INamed):
-    """
-
-
-    Interface to concrete fit strategy. Concrete implementation should manipulate with fit parameters/data and then call minimizer.
-
-    C++ includes: IFitStrategy.h
-
-    """
-
-    __swig_setmethods__ = {}
-    for _s in [INamed]:
-        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
-    __setattr__ = lambda self, name, value: _swig_setattr(self, IFitStrategy, name, value)
-    __swig_getmethods__ = {}
-    for _s in [INamed]:
-        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
-    __getattr__ = lambda self, name: _swig_getattr(self, IFitStrategy, name)
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined - class is abstract")
-    __repr__ = _swig_repr
-    __swig_destroy__ = _libBornAgainCore.delete_IFitStrategy
-    __del__ = lambda self: None
-
-    def clone(self):
-        """
-        clone(IFitStrategy self) -> IFitStrategy
-
-        virtual IFitStrategy* IFitStrategy::clone() const =0
-
-        """
-        return _libBornAgainCore.IFitStrategy_clone(self)
-
-
-    def init(self, fit_suite):
-        """
-        init(IFitStrategy self, FitSuiteImpl * fit_suite)
-
-        void IFitStrategy::init(FitSuiteImpl *fit_suite)
-
-        """
-        return _libBornAgainCore.IFitStrategy_init(self, fit_suite)
-
-
-    def execute(self):
-        """
-        execute(IFitStrategy self)
-
-        virtual void IFitStrategy::execute()=0
-
-        """
-        return _libBornAgainCore.IFitStrategy_execute(self)
-
-IFitStrategy_swigregister = _libBornAgainCore.IFitStrategy_swigregister
-IFitStrategy_swigregister(IFitStrategy)
-
-class FitStrategyDefault(IFitStrategy):
-    """
-
-
-    Default fit strategy just let  FitSuite to run it's minimization round.
-
-    C++ includes: IFitStrategy.h
-
-    """
-
-    __swig_setmethods__ = {}
-    for _s in [IFitStrategy]:
-        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
-    __setattr__ = lambda self, name, value: _swig_setattr(self, FitStrategyDefault, name, value)
-    __swig_getmethods__ = {}
-    for _s in [IFitStrategy]:
-        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
-    __getattr__ = lambda self, name: _swig_getattr(self, FitStrategyDefault, name)
-    __repr__ = _swig_repr
-
-    def __init__(self):
-        """
-        __init__(FitStrategyDefault self) -> FitStrategyDefault
-
-        FitStrategyDefault::FitStrategyDefault()
-
-        """
-        this = _libBornAgainCore.new_FitStrategyDefault()
-        try:
-            self.this.append(this)
-        except __builtin__.Exception:
-            self.this = this
-
-    def clone(self):
-        """
-        clone(FitStrategyDefault self) -> FitStrategyDefault
-
-        FitStrategyDefault * FitStrategyDefault::clone() const
-
-        """
-        return _libBornAgainCore.FitStrategyDefault_clone(self)
-
-
-    def execute(self):
-        """
-        execute(FitStrategyDefault self)
-
-        void FitStrategyDefault::execute()
-
-        """
-        return _libBornAgainCore.FitStrategyDefault_execute(self)
-
-    __swig_destroy__ = _libBornAgainCore.delete_FitStrategyDefault
-    __del__ = lambda self: None
-FitStrategyDefault_swigregister = _libBornAgainCore.FitStrategyDefault_swigregister
-FitStrategyDefault_swigregister(FitStrategyDefault)
-
 class IIntensityFunction(_object):
     """
 
@@ -5655,14 +5428,12 @@ class IntensityFunctionLog(IIntensityFunction):
         __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
     __getattr__ = lambda self, name: _swig_getattr(self, IntensityFunctionLog, name)
     __repr__ = _swig_repr
-    __swig_destroy__ = _libBornAgainCore.delete_IntensityFunctionLog
-    __del__ = lambda self: None
 
     def clone(self):
         """
         clone(IntensityFunctionLog self) -> IntensityFunctionLog
 
-        virtual IntensityFunctionLog* IntensityFunctionLog::clone() const
+        IntensityFunctionLog * IntensityFunctionLog::clone() const
 
         """
         return _libBornAgainCore.IntensityFunctionLog_clone(self)
@@ -5694,6 +5465,8 @@ class IntensityFunctionLog(IIntensityFunction):
             self.this.append(this)
         except __builtin__.Exception:
             self.this = this
+    __swig_destroy__ = _libBornAgainCore.delete_IntensityFunctionLog
+    __del__ = lambda self: None
 IntensityFunctionLog_swigregister = _libBornAgainCore.IntensityFunctionLog_swigregister
 IntensityFunctionLog_swigregister(IntensityFunctionLog)
 
@@ -5716,14 +5489,12 @@ class IntensityFunctionSqrt(IIntensityFunction):
         __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
     __getattr__ = lambda self, name: _swig_getattr(self, IntensityFunctionSqrt, name)
     __repr__ = _swig_repr
-    __swig_destroy__ = _libBornAgainCore.delete_IntensityFunctionSqrt
-    __del__ = lambda self: None
 
     def clone(self):
         """
         clone(IntensityFunctionSqrt self) -> IntensityFunctionSqrt
 
-        virtual IntensityFunctionSqrt* IntensityFunctionSqrt::clone() const
+        IntensityFunctionSqrt * IntensityFunctionSqrt::clone() const
 
         """
         return _libBornAgainCore.IntensityFunctionSqrt_clone(self)
@@ -5755,6 +5526,8 @@ class IntensityFunctionSqrt(IIntensityFunction):
             self.this.append(this)
         except __builtin__.Exception:
             self.this = this
+    __swig_destroy__ = _libBornAgainCore.delete_IntensityFunctionSqrt
+    __del__ = lambda self: None
 IntensityFunctionSqrt_swigregister = _libBornAgainCore.IntensityFunctionSqrt_swigregister
 IntensityFunctionSqrt_swigregister(IntensityFunctionSqrt)
 
@@ -5987,2540 +5760,911 @@ class IntensityScaleAndShiftNormalizer(IntensityNormalizer):
 IntensityScaleAndShiftNormalizer_swigregister = _libBornAgainCore.IntensityScaleAndShiftNormalizer_swigregister
 IntensityScaleAndShiftNormalizer_swigregister(IntensityScaleAndShiftNormalizer)
 
-class ISquaredFunction(_object):
+class IVarianceFunction(_object):
     """
 
 
-    Interface providing measures for deviation between two values. Used By  ChiSquaredModule for chi2 calculations.
+    Variance function interface.
 
-    C++ includes: ISquaredFunction.h
+    C++ includes: VarianceFunctions.h
 
     """
 
     __swig_setmethods__ = {}
-    __setattr__ = lambda self, name, value: _swig_setattr(self, ISquaredFunction, name, value)
+    __setattr__ = lambda self, name, value: _swig_setattr(self, IVarianceFunction, name, value)
     __swig_getmethods__ = {}
-    __getattr__ = lambda self, name: _swig_getattr(self, ISquaredFunction, name)
+    __getattr__ = lambda self, name: _swig_getattr(self, IVarianceFunction, name)
 
     def __init__(self, *args, **kwargs):
         raise AttributeError("No constructor defined - class is abstract")
     __repr__ = _swig_repr
-    __swig_destroy__ = _libBornAgainCore.delete_ISquaredFunction
+    __swig_destroy__ = _libBornAgainCore.delete_IVarianceFunction
     __del__ = lambda self: None
 
     def clone(self):
         """
-        clone(ISquaredFunction self) -> ISquaredFunction
-
-        virtual ISquaredFunction* ISquaredFunction::clone() const =0
-
-        """
-        return _libBornAgainCore.ISquaredFunction_clone(self)
+        clone(IVarianceFunction self) -> IVarianceFunction
 
+        virtual IVarianceFunction* IVarianceFunction::clone() const =0
 
-    def calculateSquaredDifference(self, real_value, simulated_value):
         """
-        calculateSquaredDifference(ISquaredFunction self, double real_value, double simulated_value) -> double
+        return _libBornAgainCore.IVarianceFunction_clone(self)
 
-        virtual double ISquaredFunction::calculateSquaredDifference(double real_value, double simulated_value) const =0
 
+    def variance(self, real_value, simulated_value):
         """
-        return _libBornAgainCore.ISquaredFunction_calculateSquaredDifference(self, real_value, simulated_value)
+        variance(IVarianceFunction self, double real_value, double simulated_value) -> double
 
+        virtual double IVarianceFunction::variance(double real_value, double simulated_value) const =0
 
-    def calculateSquaredError(self, real_value, simulated_value=0.0):
         """
-        calculateSquaredError(ISquaredFunction self, double real_value, double simulated_value=0.0) -> double
-        calculateSquaredError(ISquaredFunction self, double real_value) -> double
+        return _libBornAgainCore.IVarianceFunction_variance(self, real_value, simulated_value)
 
-        virtual double ISquaredFunction::calculateSquaredError(double real_value, double simulated_value=0.0) const =0
+IVarianceFunction_swigregister = _libBornAgainCore.IVarianceFunction_swigregister
+IVarianceFunction_swigregister(IVarianceFunction)
 
-        """
-        return _libBornAgainCore.ISquaredFunction_calculateSquaredError(self, real_value, simulated_value)
-
-ISquaredFunction_swigregister = _libBornAgainCore.ISquaredFunction_swigregister
-ISquaredFunction_swigregister(ISquaredFunction)
-
-class SquaredFunctionDefault(ISquaredFunction):
+class VarianceConstantFunction(IVarianceFunction):
     """
 
 
-    Squared difference between two values. value = (a-b)*(a-b)/norm, where norm = max(b, 1.0), a = simulated values, b = real_values.
+    Returns 1.0 as variance value
 
-    C++ includes: ISquaredFunction.h
+    C++ includes: VarianceFunctions.h
 
     """
 
     __swig_setmethods__ = {}
-    for _s in [ISquaredFunction]:
+    for _s in [IVarianceFunction]:
         __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
-    __setattr__ = lambda self, name, value: _swig_setattr(self, SquaredFunctionDefault, name, value)
+    __setattr__ = lambda self, name, value: _swig_setattr(self, VarianceConstantFunction, name, value)
     __swig_getmethods__ = {}
-    for _s in [ISquaredFunction]:
+    for _s in [IVarianceFunction]:
         __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
-    __getattr__ = lambda self, name: _swig_getattr(self, SquaredFunctionDefault, name)
+    __getattr__ = lambda self, name: _swig_getattr(self, VarianceConstantFunction, name)
     __repr__ = _swig_repr
 
-    def __init__(self):
+    def clone(self):
         """
-        __init__(SquaredFunctionDefault self) -> SquaredFunctionDefault
-
-        SquaredFunctionDefault::SquaredFunctionDefault()
+        clone(VarianceConstantFunction self) -> VarianceConstantFunction
 
-        """
-        this = _libBornAgainCore.new_SquaredFunctionDefault()
-        try:
-            self.this.append(this)
-        except __builtin__.Exception:
-            self.this = this
-    __swig_destroy__ = _libBornAgainCore.delete_SquaredFunctionDefault
-    __del__ = lambda self: None
+        VarianceConstantFunction * VarianceConstantFunction::clone() const override
 
-    def clone(self):
         """
-        clone(SquaredFunctionDefault self) -> SquaredFunctionDefault
+        return _libBornAgainCore.VarianceConstantFunction_clone(self)
 
-        SquaredFunctionDefault * SquaredFunctionDefault::clone() const override
 
+    def variance(self, arg2, arg3):
         """
-        return _libBornAgainCore.SquaredFunctionDefault_clone(self)
+        variance(VarianceConstantFunction self, double arg2, double arg3) -> double
 
+        double VarianceConstantFunction::variance(double, double) const override
 
-    def calculateSquaredDifference(self, real_value, simulated_value):
         """
-        calculateSquaredDifference(SquaredFunctionDefault self, double real_value, double simulated_value) -> double
+        return _libBornAgainCore.VarianceConstantFunction_variance(self, arg2, arg3)
 
-        double SquaredFunctionDefault::calculateSquaredDifference(double real_value, double simulated_value) const override
 
+    def __init__(self):
         """
-        return _libBornAgainCore.SquaredFunctionDefault_calculateSquaredDifference(self, real_value, simulated_value)
+        __init__(VarianceConstantFunction self) -> VarianceConstantFunction
 
 
-    def calculateSquaredError(self, real_value, simulated_value=0):
-        """
-        calculateSquaredError(SquaredFunctionDefault self, double real_value, double simulated_value=0) -> double
-        calculateSquaredError(SquaredFunctionDefault self, double real_value) -> double
 
-        double SquaredFunctionDefault::calculateSquaredError(double real_value, double simulated_value=0) const override
+        Returns 1.0 as variance value
 
-        """
-        return _libBornAgainCore.SquaredFunctionDefault_calculateSquaredError(self, real_value, simulated_value)
+        C++ includes: VarianceFunctions.h
 
-SquaredFunctionDefault_swigregister = _libBornAgainCore.SquaredFunctionDefault_swigregister
-SquaredFunctionDefault_swigregister(SquaredFunctionDefault)
+        """
+        this = _libBornAgainCore.new_VarianceConstantFunction()
+        try:
+            self.this.append(this)
+        except __builtin__.Exception:
+            self.this = this
+    __swig_destroy__ = _libBornAgainCore.delete_VarianceConstantFunction
+    __del__ = lambda self: None
+VarianceConstantFunction_swigregister = _libBornAgainCore.VarianceConstantFunction_swigregister
+VarianceConstantFunction_swigregister(VarianceConstantFunction)
 
-class SquaredFunctionSimError(ISquaredFunction):
+class VarianceSimFunction(IVarianceFunction):
     """
 
 
-    Squared difference between two values. value = (a-b)*(a-b)/norm, where norm = max(a, 1.0), a = simulated values, b = real_values.
+    Returns max(sim, epsilon)
 
-    C++ includes: ISquaredFunction.h
+    C++ includes: VarianceFunctions.h
 
     """
 
     __swig_setmethods__ = {}
-    for _s in [ISquaredFunction]:
+    for _s in [IVarianceFunction]:
         __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
-    __setattr__ = lambda self, name, value: _swig_setattr(self, SquaredFunctionSimError, name, value)
+    __setattr__ = lambda self, name, value: _swig_setattr(self, VarianceSimFunction, name, value)
     __swig_getmethods__ = {}
-    for _s in [ISquaredFunction]:
+    for _s in [IVarianceFunction]:
         __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
-    __getattr__ = lambda self, name: _swig_getattr(self, SquaredFunctionSimError, name)
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined - class is abstract")
+    __getattr__ = lambda self, name: _swig_getattr(self, VarianceSimFunction, name)
     __repr__ = _swig_repr
-    __swig_destroy__ = _libBornAgainCore.delete_SquaredFunctionSimError
-    __del__ = lambda self: None
 
-    def clone(self):
+    def __init__(self, epsilon=1.0):
         """
-        clone(SquaredFunctionSimError self) -> SquaredFunctionSimError
+        __init__(VarianceSimFunction self, double epsilon=1.0) -> VarianceSimFunction
+        __init__(VarianceSimFunction self) -> VarianceSimFunction
 
-        SquaredFunctionSimError * SquaredFunctionSimError::clone() const override
+        VarianceSimFunction::VarianceSimFunction(double epsilon=1.0)
 
         """
-        return _libBornAgainCore.SquaredFunctionSimError_clone(self)
-
+        this = _libBornAgainCore.new_VarianceSimFunction(epsilon)
+        try:
+            self.this.append(this)
+        except __builtin__.Exception:
+            self.this = this
 
-    def calculateSquaredDifference(self, real_value, simulated_value):
+    def clone(self):
         """
-        calculateSquaredDifference(SquaredFunctionSimError self, double real_value, double simulated_value) -> double
+        clone(VarianceSimFunction self) -> VarianceSimFunction
 
-        double SquaredFunctionSimError::calculateSquaredDifference(double real_value, double simulated_value) const override
+        VarianceSimFunction * VarianceSimFunction::clone() const override
 
         """
-        return _libBornAgainCore.SquaredFunctionSimError_calculateSquaredDifference(self, real_value, simulated_value)
+        return _libBornAgainCore.VarianceSimFunction_clone(self)
 
 
-    def calculateSquaredError(self, real_value, simulated_value):
+    def variance(self, exp, sim):
         """
-        calculateSquaredError(SquaredFunctionSimError self, double real_value, double simulated_value) -> double
+        variance(VarianceSimFunction self, double exp, double sim) -> double
 
-        double SquaredFunctionSimError::calculateSquaredError(double real_value, double simulated_value) const override
+        double VarianceSimFunction::variance(double exp, double sim) const override
 
         """
-        return _libBornAgainCore.SquaredFunctionSimError_calculateSquaredError(self, real_value, simulated_value)
+        return _libBornAgainCore.VarianceSimFunction_variance(self, exp, sim)
 
-SquaredFunctionSimError_swigregister = _libBornAgainCore.SquaredFunctionSimError_swigregister
-SquaredFunctionSimError_swigregister(SquaredFunctionSimError)
+    __swig_destroy__ = _libBornAgainCore.delete_VarianceSimFunction
+    __del__ = lambda self: None
+VarianceSimFunction_swigregister = _libBornAgainCore.VarianceSimFunction_swigregister
+VarianceSimFunction_swigregister(VarianceSimFunction)
 
-class SquaredFunctionMeanSquaredError(ISquaredFunction):
+class ChiSquaredModule(IChiSquaredModule):
     """
 
 
-    Squared difference between two values normalized by mean squared error. value = (a-b)*(a-b)/norm, where norm = sqrt(sigma1*sigma1 + sigma2*sigma2), sigma1=max(a, 1.0), sigma2=max(b,1.0)
+    Calculation of chi2 between two data sets.
 
-    C++ includes: ISquaredFunction.h
+    C++ includes: ChiSquaredModule.h
 
     """
 
     __swig_setmethods__ = {}
-    for _s in [ISquaredFunction]:
+    for _s in [IChiSquaredModule]:
         __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
-    __setattr__ = lambda self, name, value: _swig_setattr(self, SquaredFunctionMeanSquaredError, name, value)
+    __setattr__ = lambda self, name, value: _swig_setattr(self, ChiSquaredModule, name, value)
     __swig_getmethods__ = {}
-    for _s in [ISquaredFunction]:
+    for _s in [IChiSquaredModule]:
         __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
-    __getattr__ = lambda self, name: _swig_getattr(self, SquaredFunctionMeanSquaredError, name)
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined - class is abstract")
+    __getattr__ = lambda self, name: _swig_getattr(self, ChiSquaredModule, name)
     __repr__ = _swig_repr
-    __swig_destroy__ = _libBornAgainCore.delete_SquaredFunctionMeanSquaredError
-    __del__ = lambda self: None
 
-    def clone(self):
+    def __init__(self, *args):
         """
-        clone(SquaredFunctionMeanSquaredError self) -> SquaredFunctionMeanSquaredError
+        __init__(ChiSquaredModule self) -> ChiSquaredModule
+        __init__(ChiSquaredModule self, ChiSquaredModule other) -> ChiSquaredModule
 
-        SquaredFunctionMeanSquaredError * SquaredFunctionMeanSquaredError::clone() const override
+        ChiSquaredModule::ChiSquaredModule(const ChiSquaredModule &other)
 
         """
-        return _libBornAgainCore.SquaredFunctionMeanSquaredError_clone(self)
-
+        this = _libBornAgainCore.new_ChiSquaredModule(*args)
+        try:
+            self.this.append(this)
+        except __builtin__.Exception:
+            self.this = this
+    __swig_destroy__ = _libBornAgainCore.delete_ChiSquaredModule
+    __del__ = lambda self: None
 
-    def calculateSquaredDifference(self, real_value, simulated_value):
+    def clone(self):
         """
-        calculateSquaredDifference(SquaredFunctionMeanSquaredError self, double real_value, double simulated_value) -> double
-
-        double SquaredFunctionMeanSquaredError::calculateSquaredDifference(double real_value, double simulated_value) const override
+        clone(ChiSquaredModule self) -> ChiSquaredModule
 
-        """
-        return _libBornAgainCore.SquaredFunctionMeanSquaredError_calculateSquaredDifference(self, real_value, simulated_value)
+        virtual ChiSquaredModule* ChiSquaredModule::clone() const
 
+        clone method 
 
-    def calculateSquaredError(self, real_value, simulated_value):
         """
-        calculateSquaredError(SquaredFunctionMeanSquaredError self, double real_value, double simulated_value) -> double
+        return _libBornAgainCore.ChiSquaredModule_clone(self)
 
-        double SquaredFunctionMeanSquaredError::calculateSquaredError(double real_value, double simulated_value) const override
 
+    def residual(self, a, b, weight):
         """
-        return _libBornAgainCore.SquaredFunctionMeanSquaredError_calculateSquaredError(self, real_value, simulated_value)
-
-SquaredFunctionMeanSquaredError_swigregister = _libBornAgainCore.SquaredFunctionMeanSquaredError_swigregister
-SquaredFunctionMeanSquaredError_swigregister(SquaredFunctionMeanSquaredError)
-
-class SquaredFunctionSystematicError(ISquaredFunction):
-    """
+        residual(ChiSquaredModule self, double a, double b, double weight) -> double
 
+        double ChiSquaredModule::residual(double a, double b, double weight)
 
-    Squared difference between two values normalized by systematic error. value = (a-b)*(a-b)/norm, where norm = max(error, 1.0), error = b + (epsilon*b)**2.
+        """
+        return _libBornAgainCore.ChiSquaredModule_residual(self, a, b, weight)
 
-    C++ includes: ISquaredFunction.h
+ChiSquaredModule_swigregister = _libBornAgainCore.ChiSquaredModule_swigregister
+ChiSquaredModule_swigregister(ChiSquaredModule)
 
-    """
+class FitOptions(_object):
+    """Proxy of C++ FitOptions class."""
 
     __swig_setmethods__ = {}
-    for _s in [ISquaredFunction]:
-        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
-    __setattr__ = lambda self, name, value: _swig_setattr(self, SquaredFunctionSystematicError, name, value)
+    __setattr__ = lambda self, name, value: _swig_setattr(self, FitOptions, name, value)
     __swig_getmethods__ = {}
-    for _s in [ISquaredFunction]:
-        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
-    __getattr__ = lambda self, name: _swig_getattr(self, SquaredFunctionSystematicError, name)
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined - class is abstract")
+    __getattr__ = lambda self, name: _swig_getattr(self, FitOptions, name)
     __repr__ = _swig_repr
-    __swig_destroy__ = _libBornAgainCore.delete_SquaredFunctionSystematicError
-    __del__ = lambda self: None
-
-    def clone(self):
-        """
-        clone(SquaredFunctionSystematicError self) -> SquaredFunctionSystematicError
 
-        SquaredFunctionSystematicError * SquaredFunctionSystematicError::clone() const override
+    def __init__(self):
+        """__init__(FitOptions self) -> FitOptions"""
+        this = _libBornAgainCore.new_FitOptions()
+        try:
+            self.this.append(this)
+        except __builtin__.Exception:
+            self.this = this
 
-        """
-        return _libBornAgainCore.SquaredFunctionSystematicError_clone(self)
+    def derivEpsilon(self):
+        """derivEpsilon(FitOptions self) -> double"""
+        return _libBornAgainCore.FitOptions_derivEpsilon(self)
 
 
-    def calculateSquaredDifference(self, real_value, simulated_value):
-        """
-        calculateSquaredDifference(SquaredFunctionSystematicError self, double real_value, double simulated_value) -> double
-
-        double SquaredFunctionSystematicError::calculateSquaredDifference(double real_value, double simulated_value) const override
-
-        """
-        return _libBornAgainCore.SquaredFunctionSystematicError_calculateSquaredDifference(self, real_value, simulated_value)
+    def setDerivEpsilon(self, deriv_epsilon):
+        """setDerivEpsilon(FitOptions self, double deriv_epsilon)"""
+        return _libBornAgainCore.FitOptions_setDerivEpsilon(self, deriv_epsilon)
 
 
-    def calculateSquaredError(self, real_value, simulated_value):
-        """
-        calculateSquaredError(SquaredFunctionSystematicError self, double real_value, double simulated_value) -> double
+    def stepFactor(self):
+        """stepFactor(FitOptions self) -> double"""
+        return _libBornAgainCore.FitOptions_stepFactor(self)
 
-        double SquaredFunctionSystematicError::calculateSquaredError(double real_value, double simulated_value) const override
 
-        """
-        return _libBornAgainCore.SquaredFunctionSystematicError_calculateSquaredError(self, real_value, simulated_value)
+    def setStepFactor(self, step_factor):
+        """setStepFactor(FitOptions self, double step_factor)"""
+        return _libBornAgainCore.FitOptions_setStepFactor(self, step_factor)
 
-SquaredFunctionSystematicError_swigregister = _libBornAgainCore.SquaredFunctionSystematicError_swigregister
-SquaredFunctionSystematicError_swigregister(SquaredFunctionSystematicError)
+    __swig_destroy__ = _libBornAgainCore.delete_FitOptions
+    __del__ = lambda self: None
+FitOptions_swigregister = _libBornAgainCore.FitOptions_swigregister
+FitOptions_swigregister(FitOptions)
 
-class SquaredFunctionGaussianError(ISquaredFunction):
+class PyBuilderCallback(_object):
     """
 
 
-    Squared difference between two values with gaussian error. value = (a-b)*(a-b)/norm, where norm = sigma*sigma; sigma is set by user.
+    Builds simulation object using a Python callable. Base class to wrap Python callable and pass it to C++. Used in swig interface file, intended to be overloaded from Python.
 
-    C++ includes: ISquaredFunction.h
+    C++ includes: PyFittingCallbacks.h
 
     """
 
     __swig_setmethods__ = {}
-    for _s in [ISquaredFunction]:
-        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
-    __setattr__ = lambda self, name, value: _swig_setattr(self, SquaredFunctionGaussianError, name, value)
+    __setattr__ = lambda self, name, value: _swig_setattr(self, PyBuilderCallback, name, value)
     __swig_getmethods__ = {}
-    for _s in [ISquaredFunction]:
-        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
-    __getattr__ = lambda self, name: _swig_getattr(self, SquaredFunctionGaussianError, name)
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined - class is abstract")
+    __getattr__ = lambda self, name: _swig_getattr(self, PyBuilderCallback, name)
     __repr__ = _swig_repr
-    __swig_destroy__ = _libBornAgainCore.delete_SquaredFunctionGaussianError
-    __del__ = lambda self: None
-
-    def clone(self):
-        """
-        clone(SquaredFunctionGaussianError self) -> SquaredFunctionGaussianError
-
-        SquaredFunctionGaussianError * SquaredFunctionGaussianError::clone() const override
-
-        """
-        return _libBornAgainCore.SquaredFunctionGaussianError_clone(self)
 
-
-    def calculateSquaredDifference(self, real_value, simulated_value):
+    def __init__(self):
         """
-        calculateSquaredDifference(SquaredFunctionGaussianError self, double real_value, double simulated_value) -> double
+        __init__(PyBuilderCallback self) -> PyBuilderCallback
 
-        double SquaredFunctionGaussianError::calculateSquaredDifference(double real_value, double simulated_value) const override
+        PyBuilderCallback::PyBuilderCallback()
 
         """
-        return _libBornAgainCore.SquaredFunctionGaussianError_calculateSquaredDifference(self, real_value, simulated_value)
-
+        if self.__class__ == PyBuilderCallback:
+            _self = None
+        else:
+            _self = self
+        this = _libBornAgainCore.new_PyBuilderCallback(_self, )
+        try:
+            self.this.append(this)
+        except __builtin__.Exception:
+            self.this = this
+    __swig_destroy__ = _libBornAgainCore.delete_PyBuilderCallback
+    __del__ = lambda self: None
 
-    def calculateSquaredError(self, real_value, simulated_value):
+    def build_simulation(self, arg0):
         """
-        calculateSquaredError(SquaredFunctionGaussianError self, double real_value, double simulated_value) -> double
+        build_simulation(PyBuilderCallback self, Parameters arg0) -> Simulation
 
-        double SquaredFunctionGaussianError::calculateSquaredError(double real_value, double simulated_value) const override
+        Simulation * PyBuilderCallback::build_simulation(Fit::Parameters)
 
         """
-        return _libBornAgainCore.SquaredFunctionGaussianError_calculateSquaredError(self, real_value, simulated_value)
+        return _libBornAgainCore.PyBuilderCallback_build_simulation(self, arg0)
 
-SquaredFunctionGaussianError_swigregister = _libBornAgainCore.SquaredFunctionGaussianError_swigregister
-SquaredFunctionGaussianError_swigregister(SquaredFunctionGaussianError)
+    def __disown__(self):
+        self.this.disown()
+        _libBornAgainCore.disown_PyBuilderCallback(self)
+        return weakref_proxy(self)
+PyBuilderCallback_swigregister = _libBornAgainCore.PyBuilderCallback_swigregister
+PyBuilderCallback_swigregister(PyBuilderCallback)
 
-class ChiSquaredModule(IChiSquaredModule):
+class PyObserverCallback(_object):
     """
 
 
-    Calculation of chi2 between two data sets.
+    Observer for  FitObjective based on Python callable. Base class to wrap Python callable and pass it to C++. Used in swig interface file, intended to be overloaded from Python.
 
-    C++ includes: ChiSquaredModule.h
+    C++ includes: PyFittingCallbacks.h
 
     """
 
     __swig_setmethods__ = {}
-    for _s in [IChiSquaredModule]:
-        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
-    __setattr__ = lambda self, name, value: _swig_setattr(self, ChiSquaredModule, name, value)
+    __setattr__ = lambda self, name, value: _swig_setattr(self, PyObserverCallback, name, value)
     __swig_getmethods__ = {}
-    for _s in [IChiSquaredModule]:
-        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
-    __getattr__ = lambda self, name: _swig_getattr(self, ChiSquaredModule, name)
+    __getattr__ = lambda self, name: _swig_getattr(self, PyObserverCallback, name)
     __repr__ = _swig_repr
 
-    def __init__(self, *args):
+    def __init__(self):
         """
-        __init__(ChiSquaredModule self) -> ChiSquaredModule
-        __init__(ChiSquaredModule self, ChiSquaredModule other) -> ChiSquaredModule
+        __init__(PyObserverCallback self) -> PyObserverCallback
 
-        ChiSquaredModule::ChiSquaredModule(const ChiSquaredModule &other)
+        PyObserverCallback::PyObserverCallback()
 
         """
-        this = _libBornAgainCore.new_ChiSquaredModule(*args)
+        if self.__class__ == PyObserverCallback:
+            _self = None
+        else:
+            _self = self
+        this = _libBornAgainCore.new_PyObserverCallback(_self, )
         try:
             self.this.append(this)
         except __builtin__.Exception:
             self.this = this
-    __swig_destroy__ = _libBornAgainCore.delete_ChiSquaredModule
+    __swig_destroy__ = _libBornAgainCore.delete_PyObserverCallback
     __del__ = lambda self: None
 
-    def clone(self):
-        """
-        clone(ChiSquaredModule self) -> ChiSquaredModule
-
-        virtual ChiSquaredModule* ChiSquaredModule::clone() const
-
-        clone method 
-
-        """
-        return _libBornAgainCore.ChiSquaredModule_clone(self)
-
-
-    def processFitElements(self, first, last):
-        """
-        processFitElements(ChiSquaredModule self, std::vector< FitElement,std::allocator< FitElement > >::iterator first, std::vector< FitElement,std::allocator< FitElement > >::iterator last)
-
-        void ChiSquaredModule::processFitElements(std::vector< FitElement >::iterator first, std::vector< FitElement >::iterator last)
-
-        """
-        return _libBornAgainCore.ChiSquaredModule_processFitElements(self, first, last)
-
-
-    def residual(self, a, b, weight):
+    def update(self, arg0):
         """
-        residual(ChiSquaredModule self, double a, double b, double weight) -> double
+        update(PyObserverCallback self, FitObjective arg0)
 
-        double ChiSquaredModule::residual(double a, double b, double weight)
+        void PyObserverCallback::update(const FitObjective &)
 
         """
-        return _libBornAgainCore.ChiSquaredModule_residual(self, a, b, weight)
+        return _libBornAgainCore.PyObserverCallback_update(self, arg0)
 
-ChiSquaredModule_swigregister = _libBornAgainCore.ChiSquaredModule_swigregister
-ChiSquaredModule_swigregister(ChiSquaredModule)
+    def __disown__(self):
+        self.this.disown()
+        _libBornAgainCore.disown_PyObserverCallback(self)
+        return weakref_proxy(self)
+PyObserverCallback_swigregister = _libBornAgainCore.PyObserverCallback_swigregister
+PyObserverCallback_swigregister(PyObserverCallback)
 
-class FitObject(INode):
+class FitObjective(_object):
     """
 
 
-    Holds simulation description and real data to run the fit.
+    Main class to hold pairs of simulation Holds vector of FitObject's (simulation and real data) to fit
 
-    C++ includes: FitObject.h
+    C++ includes: FitObjective.h
 
     """
 
     __swig_setmethods__ = {}
-    for _s in [INode]:
-        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
-    __setattr__ = lambda self, name, value: _swig_setattr(self, FitObject, name, value)
+    __setattr__ = lambda self, name, value: _swig_setattr(self, FitObjective, name, value)
     __swig_getmethods__ = {}
-    for _s in [INode]:
-        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
-    __getattr__ = lambda self, name: _swig_getattr(self, FitObject, name)
+    __getattr__ = lambda self, name: _swig_getattr(self, FitObjective, name)
     __repr__ = _swig_repr
 
-    def __init__(self, *args):
+    def __init__(self):
         """
-        __init__(FitObject self, Simulation simulation, IntensityData data, double weight=1) -> FitObject
-        __init__(FitObject self, Simulation simulation, IntensityData data) -> FitObject
-        __init__(FitObject self, Simulation simulation, vdouble2d_t data, double weight=1) -> FitObject
-        __init__(FitObject self, Simulation simulation, vdouble2d_t data) -> FitObject
-
-        FitObject::FitObject(const Simulation &simulation, const std::vector< std::vector< double >> &data, double weight=1)
-
-        Constructs simulation/data pair for later fit.
-
-        Parameters:
-        -----------
-
-        simulation: 
-        simulation to run
-
-        data: 
-        experimental data
+        __init__(FitObjective self) -> FitObjective
 
-        weight: 
-        weight of dataset in chi2 calculations 
+        FitObjective::FitObjective()
 
         """
-        this = _libBornAgainCore.new_FitObject(*args)
+        if self.__class__ == FitObjective:
+            _self = None
+        else:
+            _self = self
+        this = _libBornAgainCore.new_FitObjective(_self, )
         try:
             self.this.append(this)
         except __builtin__.Exception:
             self.this = this
-    __swig_destroy__ = _libBornAgainCore.delete_FitObject
+    __swig_destroy__ = _libBornAgainCore.delete_FitObjective
     __del__ = lambda self: None
 
-    def accept(self, visitor):
+    def addSimulationAndData_cpp(self, *args):
         """
-        accept(FitObject self, INodeVisitor visitor)
+        addSimulationAndData_cpp(FitObjective self, PyBuilderCallback callback, vdouble1d_t data, double weight=1.0)
+        addSimulationAndData_cpp(FitObjective self, PyBuilderCallback callback, vdouble1d_t data)
+        addSimulationAndData_cpp(FitObjective self, PyBuilderCallback callback, vdouble2d_t data, double weight=1.0)
+        addSimulationAndData_cpp(FitObjective self, PyBuilderCallback callback, vdouble2d_t data)
 
-        void FitObject::accept(INodeVisitor *visitor) const final
+        void FitObjective::addSimulationAndData(PyBuilderCallback &callback, const std::vector< std::vector< double >> &data, double weight=1.0)
 
-        Calls the  INodeVisitor's visit method. 
+        """
+        return _libBornAgainCore.FitObjective_addSimulationAndData_cpp(self, *args)
 
+
+    def evaluate_cpp(self, params):
         """
-        return _libBornAgainCore.FitObject_accept(self, visitor)
+        evaluate_cpp(FitObjective self, Parameters params) -> double
 
+        double FitObjective::evaluate(const Fit::Parameters &params)
 
-    def weight(self):
         """
-        weight(FitObject self) -> double
+        return _libBornAgainCore.FitObjective_evaluate_cpp(self, params)
 
-        double FitObject::weight() const
 
-        Returns weight of data set in chi2 calculations. 
+    def evaluate_residuals_cpp(self, params):
+        """
+        evaluate_residuals_cpp(FitObjective self, Parameters params) -> vdouble1d_t
+
+        std::vector< double > FitObjective::evaluate_residuals(const Fit::Parameters &params)
 
         """
-        return _libBornAgainCore.FitObject_weight(self)
+        return _libBornAgainCore.FitObjective_evaluate_residuals_cpp(self, params)
 
 
     def numberOfFitElements(self):
         """
-        numberOfFitElements(FitObject self) -> size_t
-
-        size_t FitObject::numberOfFitElements() const
+        numberOfFitElements(FitObjective self) -> size_t
 
-        Returns the size of the data. It is equal to the number of non-masked detector channels which will participate in chi2 calculations. 
+        size_t FitObjective::numberOfFitElements() const
 
         """
-        return _libBornAgainCore.FitObject_numberOfFitElements(self)
+        return _libBornAgainCore.FitObjective_numberOfFitElements(self)
 
 
-    def prepareFitElements(self, fit_elements, weight, arg4=None):
+    def experimental_array(self):
         """
-        prepareFitElements(FitObject self, std::vector< FitElement,std::allocator< FitElement > > & fit_elements, double weight, IIntensityNormalizer arg4=None)
-        prepareFitElements(FitObject self, std::vector< FitElement,std::allocator< FitElement > > & fit_elements, double weight)
+        experimental_array(FitObjective self) -> vdouble1d_t
 
-        void FitObject::prepareFitElements(std::vector< FitElement > &fit_elements, double weight, IIntensityNormalizer *=0)
+        std::vector< double > FitObjective::experimental_array() const
 
-        Runs simulation and put results (the real and simulated intensities) into external vector. Masked channels will be excluded from the vector. 
+        Returns one dimensional array representing experimental data. Masked areas and the area outside of region of interest are not included. Data from different datasets merged together. 
 
         """
-        return _libBornAgainCore.FitObject_prepareFitElements(self, fit_elements, weight, arg4)
+        return _libBornAgainCore.FitObjective_experimental_array(self)
 
 
-    def getChildren(self):
+    def simulation_array(self):
         """
-        getChildren(FitObject self) -> swig_dummy_type_const_inode_vector
+        simulation_array(FitObjective self) -> vdouble1d_t
 
-        std::vector< const INode * > FitObject::getChildren() const
+        std::vector< double > FitObjective::simulation_array() const
 
-        Returns a vector of children (const). 
+        Returns one dimensional array representing simulated intensities data. Masked areas and the area outside of region of interest are not included. Data from different datasets merged together. 
 
         """
-        return _libBornAgainCore.FitObject_getChildren(self)
+        return _libBornAgainCore.FitObjective_simulation_array(self)
 
 
-    def simulationResult(self):
+    def weights_array(self):
         """
-        simulationResult(FitObject self) -> SimulationResult
+        weights_array(FitObjective self) -> vdouble1d_t
 
-        SimulationResult FitObject::simulationResult() const
+        std::vector< double > FitObjective::weights_array() const
 
-        Returns simulation result. 
+        Returns one dimensional array representing weights of bin intensity for residuals. 
 
         """
-        return _libBornAgainCore.FitObject_simulationResult(self)
+        return _libBornAgainCore.FitObjective_weights_array(self)
 
 
-    def experimentalData(self):
+    def simulationResult(self, i_item=0):
         """
-        experimentalData(FitObject self) -> SimulationResult
+        simulationResult(FitObjective self, size_t i_item=0) -> SimulationResult
+        simulationResult(FitObjective self) -> SimulationResult
 
-        SimulationResult FitObject::experimentalData() const
+        SimulationResult FitObjective::simulationResult(size_t i_item=0) const
 
-        Returns experimental data. 
+        Returns simulation result.
 
-        """
-        return _libBornAgainCore.FitObject_experimentalData(self)
+        Parameters:
+        -----------
 
+        i_item: 
+        the index of fit pair 
 
-    def relativeDifference(self):
         """
-        relativeDifference(FitObject self) -> SimulationResult
-
-        SimulationResult FitObject::relativeDifference() const
+        return _libBornAgainCore.FitObjective_simulationResult(self, i_item)
 
-        Returns relative difference between simulation and experimental data. 
 
+    def experimentalData(self, i_item=0):
         """
-        return _libBornAgainCore.FitObject_relativeDifference(self)
+        experimentalData(FitObjective self, size_t i_item=0) -> SimulationResult
+        experimentalData(FitObjective self) -> SimulationResult
 
+        SimulationResult FitObjective::experimentalData(size_t i_item=0) const
 
-    def runSimulation(self):
-        """
-        runSimulation(FitObject self)
+        Returns experimental data.
 
-        void FitObject::runSimulation()
+        Parameters:
+        -----------
 
-        Runs internal simulation object. 
+        i_item: 
+        the index of fit pair 
 
         """
-        return _libBornAgainCore.FitObject_runSimulation(self)
+        return _libBornAgainCore.FitObjective_experimentalData(self, i_item)
 
 
-    def experimental_array(self):
+    def relativeDifference(self, i_item=0):
         """
-        experimental_array(FitObject self) -> vdouble1d_t
+        relativeDifference(FitObjective self, size_t i_item=0) -> SimulationResult
+        relativeDifference(FitObjective self) -> SimulationResult
 
-        std::vector< double > FitObject::experimental_array() const
+        SimulationResult FitObjective::relativeDifference(size_t i_item=0) const
 
-        Returns one dimensional array representing experimental data. Masked areas and the area outside of region of interest are not included. 
+        Returns relative difference between simulation and experimental data.
 
-        """
-        return _libBornAgainCore.FitObject_experimental_array(self)
+        Parameters:
+        -----------
 
+        i_item: 
+        the index of fit pair 
 
-    def simulation_array(self):
         """
-        simulation_array(FitObject self) -> vdouble1d_t
-
-        std::vector< double > FitObject::simulation_array() const
+        return _libBornAgainCore.FitObjective_relativeDifference(self, i_item)
 
-        Returns one dimensional array representing simulated intensities data. Masked areas and the area outside of region of interest are not included. 
 
+    def absoluteDifference(self, i_item=0):
         """
-        return _libBornAgainCore.FitObject_simulation_array(self)
+        absoluteDifference(FitObjective self, size_t i_item=0) -> SimulationResult
+        absoluteDifference(FitObjective self) -> SimulationResult
 
-FitObject_swigregister = _libBornAgainCore.FitObject_swigregister
-FitObject_swigregister(FitObject)
+        SimulationResult FitObjective::absoluteDifference(size_t i_item=0) const
 
-class FitOptions(_object):
-    """Proxy of C++ FitOptions class."""
+        Returns absolute value of difference between simulation and experimental data.
 
-    __swig_setmethods__ = {}
-    __setattr__ = lambda self, name, value: _swig_setattr(self, FitOptions, name, value)
-    __swig_getmethods__ = {}
-    __getattr__ = lambda self, name: _swig_getattr(self, FitOptions, name)
-    __repr__ = _swig_repr
+        Parameters:
+        -----------
 
-    def __init__(self):
-        """__init__(FitOptions self) -> FitOptions"""
-        this = _libBornAgainCore.new_FitOptions()
-        try:
-            self.this.append(this)
-        except __builtin__.Exception:
-            self.this = this
+        i_item: 
+        the index of fit pair 
 
-    def derivEpsilon(self):
-        """derivEpsilon(FitOptions self) -> double"""
-        return _libBornAgainCore.FitOptions_derivEpsilon(self)
+        """
+        return _libBornAgainCore.FitObjective_absoluteDifference(self, i_item)
 
 
-    def setDerivEpsilon(self, deriv_epsilon):
-        """setDerivEpsilon(FitOptions self, double deriv_epsilon)"""
-        return _libBornAgainCore.FitOptions_setDerivEpsilon(self, deriv_epsilon)
+    def initPrint(self, every_nth):
+        """
+        initPrint(FitObjective self, int every_nth)
 
+        void FitObjective::initPrint(int every_nth)
 
-    def stepFactor(self):
-        """stepFactor(FitOptions self) -> double"""
-        return _libBornAgainCore.FitOptions_stepFactor(self)
-
-
-    def setStepFactor(self, step_factor):
-        """setStepFactor(FitOptions self, double step_factor)"""
-        return _libBornAgainCore.FitOptions_setStepFactor(self, step_factor)
-
-    __swig_destroy__ = _libBornAgainCore.delete_FitOptions
-    __del__ = lambda self: None
-FitOptions_swigregister = _libBornAgainCore.FitOptions_swigregister
-FitOptions_swigregister(FitOptions)
-
-class IFitParameter(_object):
-    """
-
-
-    A fittable parameter with value, error, step, and limits.
-
-    C++ includes: IFitParameter.h
+        Initializes printing to standard output during the fitting.
 
-    """
+        Parameters:
+        -----------
 
-    __swig_setmethods__ = {}
-    __setattr__ = lambda self, name, value: _swig_setattr(self, IFitParameter, name, value)
-    __swig_getmethods__ = {}
-    __getattr__ = lambda self, name: _swig_getattr(self, IFitParameter, name)
-    __repr__ = _swig_repr
+        every_nth: 
+        Print every n'th iteration. 
 
-    def __init__(self, *args):
         """
-        __init__(IFitParameter self) -> IFitParameter
-        __init__(IFitParameter self, std::string const & name, double value, AttLimits limits, double step=0.0) -> IFitParameter
-        __init__(IFitParameter self, std::string const & name, double value, AttLimits limits) -> IFitParameter
-        __init__(IFitParameter self, std::string const & name, double value) -> IFitParameter
-
-        IFitParameter::IFitParameter(const std::string &name, double value, const AttLimits &limits=AttLimits::limitless(), double step=0.0)
+        return _libBornAgainCore.FitObjective_initPrint(self, every_nth)
 
-        """
-        this = _libBornAgainCore.new_IFitParameter(*args)
-        try:
-            self.this.append(this)
-        except __builtin__.Exception:
-            self.this = this
-    __swig_destroy__ = _libBornAgainCore.delete_IFitParameter
-    __del__ = lambda self: None
 
-    def clone(self):
+    def initPlot_cpp(self, every_nth, callback):
         """
-        clone(IFitParameter self) -> IFitParameter
+        initPlot_cpp(FitObjective self, int every_nth, PyObserverCallback callback)
 
-        IFitParameter * IFitParameter::clone() const
+        void FitObjective::initPlot(int every_nth, PyObserverCallback &callback)
 
         """
-        return _libBornAgainCore.IFitParameter_clone(self)
+        return _libBornAgainCore.FitObjective_initPlot_cpp(self, every_nth, callback)
 
 
-    def name(self):
+    def isCompleted(self):
         """
-        name(IFitParameter self) -> std::string
+        isCompleted(FitObjective self) -> bool
 
-        std::string IFitParameter::name() const
+        bool FitObjective::isCompleted() const
 
         """
-        return _libBornAgainCore.IFitParameter_name(self)
+        return _libBornAgainCore.FitObjective_isCompleted(self)
 
 
-    def setName(self, name):
+    def iterationInfo(self):
         """
-        setName(IFitParameter self, std::string const & name) -> IFitParameter
+        iterationInfo(FitObjective self) -> IterationInfo
 
-        IFitParameter & IFitParameter::setName(const std::string &name)
+        IterationInfo FitObjective::iterationInfo() const
 
         """
-        return _libBornAgainCore.IFitParameter_setName(self, name)
+        return _libBornAgainCore.FitObjective_iterationInfo(self)
 
 
-    def startValue(self):
+    def minimizerResult(self):
         """
-        startValue(IFitParameter self) -> double
+        minimizerResult(FitObjective self) -> Fit::MinimizerResult
 
-        double IFitParameter::startValue() const
+        Fit::MinimizerResult FitObjective::minimizerResult() const
 
         """
-        return _libBornAgainCore.IFitParameter_startValue(self)
+        return _libBornAgainCore.FitObjective_minimizerResult(self)
 
 
-    def setStartValue(self, value):
+    def finalize_cpp(self, result):
         """
-        setStartValue(IFitParameter self, double value)
-
-        void IFitParameter::setStartValue(double value)
+        finalize_cpp(FitObjective self, Fit::MinimizerResult const & result)
 
-        """
-        return _libBornAgainCore.IFitParameter_setStartValue(self, value)
+        void FitObjective::finalize(const Fit::MinimizerResult &result)
 
+        Should be explicitely called on last iteration to notify all observers. 
 
-    def value(self):
         """
-        value(IFitParameter self) -> double
+        return _libBornAgainCore.FitObjective_finalize_cpp(self, result)
 
-        double IFitParameter::value() const
 
+    def fitObjectCount(self):
         """
-        return _libBornAgainCore.IFitParameter_value(self)
+        fitObjectCount(FitObjective self) -> unsigned int
 
+        unsigned FitObjective::fitObjectCount() const
 
-    def setValue(self, value):
         """
-        setValue(IFitParameter self, double value)
+        return _libBornAgainCore.FitObjective_fitObjectCount(self)
 
-        void IFitParameter::setValue(double value)
 
+    def interruptFitting(self):
         """
-        return _libBornAgainCore.IFitParameter_setValue(self, value)
+        interruptFitting(FitObjective self)
 
+        void FitObjective::interruptFitting()
 
-    def addPattern(self, pattern):
         """
-        addPattern(IFitParameter self, std::string const & pattern) -> IFitParameter
+        return _libBornAgainCore.FitObjective_interruptFitting(self)
 
-        IFitParameter & IFitParameter::addPattern(const std::string &pattern)
 
+    def isInterrupted(self):
         """
-        return _libBornAgainCore.IFitParameter_addPattern(self, pattern)
+        isInterrupted(FitObjective self) -> bool
 
+        bool FitObjective::isInterrupted() const
 
-    def step(self):
         """
-        step(IFitParameter self) -> double
+        return _libBornAgainCore.FitObjective_isInterrupted(self)
 
-        double IFitParameter::step() const
 
+    def isFirstIteration(self):
         """
-        return _libBornAgainCore.IFitParameter_step(self)
+        isFirstIteration(FitObjective self) -> bool
 
+        bool FitObjective::isFirstIteration() const
 
-    def setStep(self, value):
         """
-        setStep(IFitParameter self, double value) -> IFitParameter
+        return _libBornAgainCore.FitObjective_isFirstIteration(self)
 
-        IFitParameter & IFitParameter::setStep(double value)
 
+    def run_simulations(self, params):
         """
-        return _libBornAgainCore.IFitParameter_setStep(self, value)
+        run_simulations(FitObjective self, Parameters params)
 
+        void FitObjective::run_simulations(const Fit::Parameters &params)
 
-    def error(self):
         """
-        error(IFitParameter self) -> double
+        return _libBornAgainCore.FitObjective_run_simulations(self, params)
 
-        double IFitParameter::error() const
 
+    def setChiSquaredModule(self, module):
         """
-        return _libBornAgainCore.IFitParameter_error(self)
+        setChiSquaredModule(FitObjective self, IChiSquaredModule module)
 
+        void FitObjective::setChiSquaredModule(const IChiSquaredModule &module)
 
-    def setError(self, value):
         """
-        setError(IFitParameter self, double value)
-
-        void IFitParameter::setError(double value)
+        return _libBornAgainCore.FitObjective_setChiSquaredModule(self, module)
 
-        """
-        return _libBornAgainCore.IFitParameter_setError(self, value)
 
+    def addSimulationAndData(self, callback, data, weight = 1.0):
+        if not hasattr(self, 'callback_container'):
+            self.callback_container = []
+        wrp = SimulationBuilderWrapper(callback)
+        self.callback_container.append(wrp)
+        return self.addSimulationAndData_cpp(wrp, data, weight)
 
-    def limits(self, *args):
+    def convert_params(self, params):
         """
-        limits(IFitParameter self) -> AttLimits
-        limits(IFitParameter self) -> AttLimits
-
-        AttLimits & IFitParameter::limits()
-
+        Converts parameters to what FitObjective::evaluate expects
         """
-        return _libBornAgainCore.IFitParameter_limits(self, *args)
 
+        if str(params.__module__) == "lmfit.parameter":
+            bapars = libBornAgainFit.Parameters()
+            for p in params:
+                bapars.add(p, params[p].value)
+            return bapars
+        else:
+            return params
 
-    def setLimits(self, limits):
-        """
-        setLimits(IFitParameter self, AttLimits limits) -> IFitParameter
+    def evaluate_residuals(self, params):
+        return self.evaluate_residuals_cpp(self.convert_params(params))
 
-        IFitParameter & IFitParameter::setLimits(const AttLimits &limits)
+    def evaluate(self, params):
+        return self.evaluate_cpp(self.convert_params(params))
 
+    def convert_result(self, minim_result):
         """
-        return _libBornAgainCore.IFitParameter_setLimits(self, limits)
-
-
-    def setLowerLimited(self, bound_value):
+        Converts result reported by arbitrary minimizer to ba.MinimizerResult
         """
-        setLowerLimited(IFitParameter self, double bound_value) -> IFitParameter
 
-        IFitParameter & IFitParameter::setLowerLimited(double bound_value)
+        if str(minim_result.__module__) == "lmfit.minimizer":
+            return libBornAgainFit.MinimizerResult()
+        else:
+            return minim_result
 
-        """
-        return _libBornAgainCore.IFitParameter_setLowerLimited(self, bound_value)
+    def finalize(self, minimizer_result):
+        return self.finalize_cpp(self.convert_result(minimizer_result))
 
+    def create_default_plotter(self):
+        import plot_utils
+        self.m_plotter = plot_utils.PlotterGISAS()
+        return self.m_plotter.plot
 
-    def setPositive(self):
-        """
-        setPositive(IFitParameter self) -> IFitParameter
+    def initPlot(self, every_nth, callback = None):
+        if not callback:
+            callback = self.create_default_plotter()
 
-        IFitParameter & IFitParameter::setPositive()
+        self.wrp_plot_observer = ObserverCallbackWrapper(callback)
+        return self.initPlot_cpp(every_nth, self.wrp_plot_observer)
 
-        """
-        return _libBornAgainCore.IFitParameter_setPositive(self)
 
+    def __disown__(self):
+        self.this.disown()
+        _libBornAgainCore.disown_FitObjective(self)
+        return weakref_proxy(self)
+FitObjective_swigregister = _libBornAgainCore.FitObjective_swigregister
+FitObjective_swigregister(FitObjective)
 
-    def setNonnegative(self):
-        """
-        setNonnegative(IFitParameter self) -> IFitParameter
 
-        IFitParameter & IFitParameter::setNonnegative()
+def StandardNormal(x):
+    """
+    StandardNormal(double x) -> double
 
-        """
-        return _libBornAgainCore.IFitParameter_setNonnegative(self)
+    double MathFunctions::StandardNormal(double x)
 
+    """
+    return _libBornAgainCore.StandardNormal(x)
 
-    def setUpperLimited(self, bound_value):
-        """
-        setUpperLimited(IFitParameter self, double bound_value) -> IFitParameter
+def Gaussian(x, average, std_dev):
+    """
+    Gaussian(double x, double average, double std_dev) -> double
 
-        IFitParameter & IFitParameter::setUpperLimited(double bound_value)
+    double MathFunctions::Gaussian(double x, double average, double std_dev)
 
-        """
-        return _libBornAgainCore.IFitParameter_setUpperLimited(self, bound_value)
+    """
+    return _libBornAgainCore.Gaussian(x, average, std_dev)
 
+def IntegratedGaussian(x, average, std_dev):
+    """
+    IntegratedGaussian(double x, double average, double std_dev) -> double
 
-    def setLimited(self, left_bound_value, right_bound_value):
-        """
-        setLimited(IFitParameter self, double left_bound_value, double right_bound_value) -> IFitParameter
+    double MathFunctions::IntegratedGaussian(double x, double average, double std_dev)
 
-        IFitParameter & IFitParameter::setLimited(double left_bound_value, double right_bound_value)
+    """
+    return _libBornAgainCore.IntegratedGaussian(x, average, std_dev)
 
-        """
-        return _libBornAgainCore.IFitParameter_setLimited(self, left_bound_value, right_bound_value)
+def cot(x):
+    """
+    cot(double x) -> double
 
+    double MathFunctions::cot(double x)
 
-    def setFixed(self):
-        """
-        setFixed(IFitParameter self) -> IFitParameter
+    cotangent function:  $cot(x)\\equiv1/tan(x)$
 
-        IFitParameter & IFitParameter::setFixed()
+    """
+    return _libBornAgainCore.cot(x)
 
-        """
-        return _libBornAgainCore.IFitParameter_setFixed(self)
+def Si(x):
+    """
+    Si(double x) -> double
+
+    double MathFunctions::Si(double x)
 
+    Sine integral function:  $Si(x)\\equiv\\int_0^x du \\sin(u)/u$. 
 
-    def toString(self):
-        """
-        toString(IFitParameter self) -> std::string
+    """
+    return _libBornAgainCore.Si(x)
 
-        std::string IFitParameter::toString() const
+def sinc(*args):
+    """
+    sinc(double x) -> double
+    sinc(complex_t const z) -> complex_t
 
-        """
-        return _libBornAgainCore.IFitParameter_toString(self)
+    complex_t MathFunctions::sinc(const complex_t z)
 
-IFitParameter_swigregister = _libBornAgainCore.IFitParameter_swigregister
-IFitParameter_swigregister(IFitParameter)
+    Complex sinc function:  $sinc(x)\\equiv\\sin(x)/x$. 
 
-class FitParameterSet(_object):
     """
+    return _libBornAgainCore.sinc(*args)
 
+def tanhc(z):
+    """
+    tanhc(complex_t const z) -> complex_t
 
-    The set of fit parameters.
+    complex_t MathFunctions::tanhc(const complex_t z)
 
-    C++ includes: FitParameterSet.h
+    Complex tanhc function:  $tanhc(x)\\equiv\\tanh(x)/x$. 
 
     """
+    return _libBornAgainCore.tanhc(z)
 
-    __swig_setmethods__ = {}
-    __setattr__ = lambda self, name, value: _swig_setattr(self, FitParameterSet, name, value)
-    __swig_getmethods__ = {}
-    __getattr__ = lambda self, name: _swig_getattr(self, FitParameterSet, name)
-    __repr__ = _swig_repr
+def Laue(x, N):
+    """
+    Laue(double const x, size_t N) -> double
 
-    def __init__(self):
-        """
-        __init__(FitParameterSet self) -> FitParameterSet
+    double MathFunctions::Laue(const double x, size_t N)
 
-        FitParameterSet::FitParameterSet()
+    Real Laue function:  $Laue(x,N)\\equiv\\sin(Nx)/sin(x)$. 
 
-        """
-        this = _libBornAgainCore.new_FitParameterSet()
-        try:
-            self.this.append(this)
-        except __builtin__.Exception:
-            self.this = this
-    __swig_destroy__ = _libBornAgainCore.delete_FitParameterSet
-    __del__ = lambda self: None
+    """
+    return _libBornAgainCore.Laue(x, N)
 
-    def clear(self):
-        """
-        clear(FitParameterSet self)
+def erf(arg):
+    """
+    erf(double arg) -> double
 
-        void FitParameterSet::clear()
+    double MathFunctions::erf(double arg)
 
-        Clears all defined parameters. 
+    Error function of real-valued argument. 
 
-        """
-        return _libBornAgainCore.FitParameterSet_clear(self)
+    """
+    return _libBornAgainCore.erf(arg)
 
+def Bessel_J0(*args):
+    """
+    Bessel_J0(double x) -> double
+    Bessel_J0(complex_t const z) -> complex_t
 
-    def size(self):
-        """
-        size(FitParameterSet self) -> size_t
+    complex_t MathFunctions::Bessel_J0(const complex_t z)
 
-        size_t FitParameterSet::size() const
+    Complex Bessel function of the first kind and order 0. 
 
-        Returns number of parameters. 
+    """
+    return _libBornAgainCore.Bessel_J0(*args)
 
-        """
-        return _libBornAgainCore.FitParameterSet_size(self)
+def Bessel_J1(*args):
+    """
+    Bessel_J1(double x) -> double
+    Bessel_J1(complex_t const z) -> complex_t
 
+    complex_t MathFunctions::Bessel_J1(const complex_t z)
 
-    def begin(self, *args):
-        """
-        begin(FitParameterSet self) -> FitParameterSet::iterator
-        begin(FitParameterSet self) -> FitParameterSet::const_iterator
+    Complex Bessel function of the first kind and order 1. 
 
-        FitParameterSet::const_iterator FitParameterSet::begin() const
+    """
+    return _libBornAgainCore.Bessel_J1(*args)
 
-        """
-        return _libBornAgainCore.FitParameterSet_begin(self, *args)
+def Bessel_J1c(*args):
+    """
+    Bessel_J1c(double x) -> double
+    Bessel_J1c(complex_t const z) -> complex_t
 
+    complex_t MathFunctions::Bessel_J1c(const complex_t z)
 
-    def end(self, *args):
-        """
-        end(FitParameterSet self) -> FitParameterSet::iterator
-        end(FitParameterSet self) -> FitParameterSet::const_iterator
+    Complex Bessel function Bessel_J1(x)/x. 
 
-        FitParameterSet::const_iterator FitParameterSet::end() const
+    """
+    return _libBornAgainCore.Bessel_J1c(*args)
+FORWARD_FFT = _libBornAgainCore.FORWARD_FFT
+BACKWARD_FFT = _libBornAgainCore.BACKWARD_FFT
 
-        """
-        return _libBornAgainCore.FitParameterSet_end(self, *args)
+def FastFourierTransform(*args):
+    """
+    FastFourierTransform(vector_complex_t data, MathFunctions::EFFTDirection tcase) -> vector_complex_t
+    FastFourierTransform(vdouble1d_t data, MathFunctions::EFFTDirection tcase) -> vector_complex_t
 
+    std::vector< complex_t > MathFunctions::FastFourierTransform(const std::vector< double > &data, EFFTDirection tcase)
 
-    def addFitParameter(self, par):
-        """
-        addFitParameter(FitParameterSet self, IFitParameter par)
+    simple (and unoptimized) wrapper function for the discrete fast Fourier transformation library (fftw3); transforms real to complex 
 
-        void FitParameterSet::addFitParameter(IFitParameter *par)
+    """
+    return _libBornAgainCore.FastFourierTransform(*args)
 
-        Adds fit parameter. 
+def ConvolveFFT(signal, resfunc):
+    """
+    ConvolveFFT(vdouble1d_t signal, vdouble1d_t resfunc) -> vector_complex_t
 
-        """
-        return _libBornAgainCore.FitParameterSet_addFitParameter(self, par)
+    std::vector< complex_t > MathFunctions::ConvolveFFT(const std::vector< double > &signal, const std::vector< double > &resfunc)
 
+    convolution of two real vectors of equal size 
 
-    def fitParameter(self, *args):
-        """
-        fitParameter(FitParameterSet self, std::string const & name) -> IFitParameter
-        fitParameter(FitParameterSet self, std::string const & name) -> IFitParameter
+    """
+    return _libBornAgainCore.ConvolveFFT(signal, resfunc)
 
-        IFitParameter * FitParameterSet::fitParameter(const std::string &name)
+def GenerateUniformRandom():
+    """
+    GenerateUniformRandom() -> double
 
-        """
-        return _libBornAgainCore.FitParameterSet_fitParameter(self, *args)
-
-
-    def values(self):
-        """
-        values(FitParameterSet self) -> vdouble1d_t
-
-        std::vector< double > FitParameterSet::values() const
-
-        Returns values of all defined parameters. 
-
-        """
-        return _libBornAgainCore.FitParameterSet_values(self)
-
-
-    def setValues(self, pars_values):
-        """
-        setValues(FitParameterSet self, vdouble1d_t pars_values)
-
-        void FitParameterSet::setValues(const std::vector< double > &pars_values)
-
-        Sets values for all defined parameters. 
-
-        """
-        return _libBornAgainCore.FitParameterSet_setValues(self, pars_values)
-
-
-    def valuesDifferFrom(self, par_values, tolerance=2.0):
-        """
-        valuesDifferFrom(FitParameterSet self, vdouble1d_t par_values, double tolerance=2.0) -> bool
-        valuesDifferFrom(FitParameterSet self, vdouble1d_t par_values) -> bool
-
-        bool FitParameterSet::valuesDifferFrom(const std::vector< double > &par_values, double tolerance=2.0) const
-
-        Returns true if parameters already have the given values. 
-
-        """
-        return _libBornAgainCore.FitParameterSet_valuesDifferFrom(self, par_values, tolerance)
-
-
-    def errors(self):
-        """
-        errors(FitParameterSet self) -> vdouble1d_t
-
-        std::vector< double > FitParameterSet::errors() const
-
-        Returns errors of all defined parameters. 
-
-        """
-        return _libBornAgainCore.FitParameterSet_errors(self)
-
-
-    def setErrors(self, pars_errors):
-        """
-        setErrors(FitParameterSet self, vdouble1d_t pars_errors)
-
-        void FitParameterSet::setErrors(const std::vector< double > &pars_errors)
-
-        Sets errors to all parameters. 
-
-        """
-        return _libBornAgainCore.FitParameterSet_setErrors(self, pars_errors)
-
-
-    def freeFitParameterCount(self):
-        """
-        freeFitParameterCount(FitParameterSet self) -> size_t
-
-        size_t FitParameterSet::freeFitParameterCount() const
-
-        Returns number of free parameters. 
-
-        """
-        return _libBornAgainCore.FitParameterSet_freeFitParameterCount(self)
-
-
-    def fixAll(self):
-        """
-        fixAll(FitParameterSet self)
-
-        void FitParameterSet::fixAll()
-
-        Fix all parameters. 
-
-        """
-        return _libBornAgainCore.FitParameterSet_fixAll(self)
-
-
-    def releaseAll(self):
-        """
-        releaseAll(FitParameterSet self)
-
-        void FitParameterSet::releaseAll()
-
-        Release all parameters. 
-
-        """
-        return _libBornAgainCore.FitParameterSet_releaseAll(self)
-
-
-    def setFixed(self, pars, is_fixed):
-        """
-        setFixed(FitParameterSet self, vector_string_t pars, bool is_fixed)
-
-        void FitParameterSet::setFixed(const std::vector< std::string > &pars, bool is_fixed)
-
-        Set fixed flag for parameters from the list. 
-
-        """
-        return _libBornAgainCore.FitParameterSet_setFixed(self, pars, is_fixed)
-
-
-    def correlationMatrix(self):
-        """
-        correlationMatrix(FitParameterSet self) -> vdouble2d_t
-
-        corr_matrix_t FitParameterSet::correlationMatrix() const
-
-        """
-        return _libBornAgainCore.FitParameterSet_correlationMatrix(self)
-
-
-    def setCorrelationMatrix(self, matrix):
-        """
-        setCorrelationMatrix(FitParameterSet self, vdouble2d_t matrix)
-
-        void FitParameterSet::setCorrelationMatrix(const corr_matrix_t &matrix)
-
-        Sets resulting correlation matrix. 
-
-        """
-        return _libBornAgainCore.FitParameterSet_setCorrelationMatrix(self, matrix)
-
-
-    def fitParametersNewKernel(self):
-        """
-        fitParametersNewKernel(FitParameterSet self) -> Parameters
-
-        Fit::Parameters FitParameterSet::fitParametersNewKernel() const
-
-        Refactoring temp: returns set of new fit parameters. 
-
-        """
-        return _libBornAgainCore.FitParameterSet_fitParametersNewKernel(self)
-
-
-    def __getitem__(self, *args):
-        """
-        __getitem__(FitParameterSet self, std::string name) -> IFitParameter
-        __getitem__(FitParameterSet self, size_t index) -> IFitParameter
-        """
-        return _libBornAgainCore.FitParameterSet___getitem__(self, *args)
-
-
-    def __iter__(self):
-        return FitParameterSetIterator(self)
-
-FitParameterSet_swigregister = _libBornAgainCore.FitParameterSet_swigregister
-FitParameterSet_swigregister(FitParameterSet)
-
-class FitParameter(IFitParameter):
-    """
-
-
-    Fittable parameter, linked to other parameters from pools.
-
-    C++ includes: FitParameter.h
-
-    """
-
-    __swig_setmethods__ = {}
-    for _s in [IFitParameter]:
-        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
-    __setattr__ = lambda self, name, value: _swig_setattr(self, FitParameter, name, value)
-    __swig_getmethods__ = {}
-    for _s in [IFitParameter]:
-        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
-    __getattr__ = lambda self, name: _swig_getattr(self, FitParameter, name)
-    __repr__ = _swig_repr
-
-    def __init__(self, *args):
-        """
-        __init__(FitParameter self) -> FitParameter
-        __init__(FitParameter self, std::string const & pattern, double value, AttLimits lim, double step=0.0) -> FitParameter
-        __init__(FitParameter self, std::string const & pattern, double value, AttLimits lim) -> FitParameter
-        __init__(FitParameter self, std::string const & pattern, double value) -> FitParameter
-        __init__(FitParameter self, double value, AttLimits lim, double step=0.0) -> FitParameter
-        __init__(FitParameter self, double value, AttLimits lim) -> FitParameter
-        __init__(FitParameter self, double value) -> FitParameter
-
-        FitParameter::FitParameter(double value, const AttLimits &lim=AttLimits::limitless(), double step=0.0)
-
-        """
-        this = _libBornAgainCore.new_FitParameter(*args)
-        try:
-            self.this.append(this)
-        except __builtin__.Exception:
-            self.this = this
-    __swig_destroy__ = _libBornAgainCore.delete_FitParameter
-    __del__ = lambda self: None
-
-    def clone(self):
-        """
-        clone(FitParameter self) -> FitParameter
-
-        FitParameter * FitParameter::clone() const
-
-        """
-        return _libBornAgainCore.FitParameter_clone(self)
-
-
-    def setValue(self, value):
-        """
-        setValue(FitParameter self, double value)
-
-        void FitParameter::setValue(double value) final
-
-        Sets given value for all bound parameters. 
-
-        """
-        return _libBornAgainCore.FitParameter_setValue(self, value)
-
-
-    def addPattern(self, pattern):
-        """
-        addPattern(FitParameter self, std::string const & pattern) -> FitParameter
-
-        FitParameter & FitParameter::addPattern(const std::string &pattern)
-
-        Adds pattern to the list for later usage in parameter pool matching. 
-
-        """
-        return _libBornAgainCore.FitParameter_addPattern(self, pattern)
-
-
-    def addParameter(self, par):
-        """
-        addParameter(FitParameter self, RealParameter par)
-
-        void FitParameter::addParameter(const RealParameter &par)
-
-        Adds real parameter to the collection. 
-
-        """
-        return _libBornAgainCore.FitParameter_addParameter(self, par)
-
-
-    def addMatchedParameters(self, pool):
-        """
-        addMatchedParameters(FitParameter self, ParameterPool pool)
-
-        void FitParameter::addMatchedParameters(const ParameterPool &pool)
-
-        Adds parameters from pool which match given wildcard. 
-
-        """
-        return _libBornAgainCore.FitParameter_addMatchedParameters(self, pool)
-
-
-    def patterns(self):
-        """
-        patterns(FitParameter self) -> vector_string_t
-
-        std::vector< std::string > FitParameter::patterns() const
-
-        """
-        return _libBornAgainCore.FitParameter_patterns(self)
-
-
-    def matchedParameterNames(self):
-        """
-        matchedParameterNames(FitParameter self) -> vector_string_t
-
-        std::vector< std::string > FitParameter::matchedParameterNames() const
-
-        Returns vector of strings with names of all matched parameters. 
-
-        """
-        return _libBornAgainCore.FitParameter_matchedParameterNames(self)
-
-
-    def patternIntersection(self, other):
-        """
-        patternIntersection(FitParameter self, FitParameter other) -> vector_string_t
-
-        std::vector< std::string > FitParameter::patternIntersection(const FitParameter &other) const
-
-        Returns vector containing patterns existing in both FitParametersLinked. 
-
-        """
-        return _libBornAgainCore.FitParameter_patternIntersection(self, other)
-
-
-    def isConflicting(self, other):
-        """
-        isConflicting(FitParameter self, FitParameter other) -> bool
-
-        bool FitParameter::isConflicting(const FitParameter &other) const
-
-        Returns true if two FitParameterLinked are intended to steer same  RealParameter. 
-
-        """
-        return _libBornAgainCore.FitParameter_isConflicting(self, other)
-
-FitParameter_swigregister = _libBornAgainCore.FitParameter_swigregister
-FitParameter_swigregister(FitParameter)
-
-class FitSuite(IObservable):
-    """
-
-
-    User interface class that wraps all fit methods.
-
-    C++ includes: FitSuite.h
-
-    """
-
-    __swig_setmethods__ = {}
-    for _s in [IObservable]:
-        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
-    __setattr__ = lambda self, name, value: _swig_setattr(self, FitSuite, name, value)
-    __swig_getmethods__ = {}
-    for _s in [IObservable]:
-        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
-    __getattr__ = lambda self, name: _swig_getattr(self, FitSuite, name)
-    __repr__ = _swig_repr
-
-    def __init__(self):
-        """
-        __init__(FitSuite self) -> FitSuite
-
-        FitSuite::FitSuite(const FitSuite &)=delete
-
-        """
-        this = _libBornAgainCore.new_FitSuite()
-        try:
-            self.this.append(this)
-        except __builtin__.Exception:
-            self.this = this
-    __swig_destroy__ = _libBornAgainCore.delete_FitSuite
-    __del__ = lambda self: None
-
-    def addSimulationAndRealData(self, *args):
-        """
-        addSimulationAndRealData(FitSuite self, Simulation simulation, IntensityData real_data, double weight=1)
-        addSimulationAndRealData(FitSuite self, Simulation simulation, IntensityData real_data)
-        addSimulationAndRealData(FitSuite self, Simulation simulation, IHistogram real_data, double weight=1)
-        addSimulationAndRealData(FitSuite self, Simulation simulation, IHistogram real_data)
-        addSimulationAndRealData(FitSuite self, Simulation simulation, vdouble2d_t real_data, double weight=1)
-        addSimulationAndRealData(FitSuite self, Simulation simulation, vdouble2d_t real_data)
-        addSimulationAndRealData(FitSuite self, Simulation simulation, vdouble1d_t real_data, double weight=1)
-        addSimulationAndRealData(FitSuite self, Simulation simulation, vdouble1d_t real_data)
-
-        void FitSuite::addSimulationAndRealData(const Simulation &simulation, const std::vector< double > &real_data, double weight=1)
-
-        Assigns pair of (simulation, real_data) for fitting. A version for the  real_data represented as a one-dimensional numpy array.  Simulation output must agree in dimensions with  real_data. 
-
-        """
-        return _libBornAgainCore.FitSuite_addSimulationAndRealData(self, *args)
-
-
-    def addFitParameter(self, *args):
-        """
-        addFitParameter(FitSuite self, std::string const & pattern, double value, AttLimits limits, double step=0.0) -> FitParameter
-        addFitParameter(FitSuite self, std::string const & pattern, double value, AttLimits limits) -> FitParameter
-        addFitParameter(FitSuite self, std::string const & pattern, double value) -> FitParameter
-        addFitParameter(FitSuite self, FitParameter fitPar) -> FitParameter
-
-        FitParameter * FitSuite::addFitParameter(const FitParameter &fitPar)
-
-        Adds fit parameter
-
-        Parameters:
-        -----------
-
-        fitPar: 
-        Fully constructed fit parameter. 
-
-        """
-        return _libBornAgainCore.FitSuite_addFitParameter(self, *args)
-
-
-    def setChiSquaredModule(self, chi2_module):
-        """
-        setChiSquaredModule(FitSuite self, IChiSquaredModule chi2_module)
-
-        void FitSuite::setChiSquaredModule(const IChiSquaredModule &chi2_module)
-
-        Replaces default  ChiSquaredModule with new one. 
-
-        """
-        return _libBornAgainCore.FitSuite_setChiSquaredModule(self, chi2_module)
-
-
-    def addFitStrategy(self, strategy):
-        """
-        addFitStrategy(FitSuite self, IFitStrategy strategy)
-
-        void FitSuite::addFitStrategy(const IFitStrategy &strategy)
-
-        Adds fit strategy. 
-
-        """
-        return _libBornAgainCore.FitSuite_addFitStrategy(self, strategy)
-
-
-    def setMinimizer(self, *args):
-        """
-        setMinimizer(FitSuite self, std::string const & minimizer_name, std::string const & algorithm_name, std::string const & minimizer_options)
-        setMinimizer(FitSuite self, std::string const & minimizer_name, std::string const & algorithm_name)
-        setMinimizer(FitSuite self, std::string const & minimizer_name)
-        setMinimizer(FitSuite self, IMinimizer * minimizer)
-
-        void FitSuite::setMinimizer(IMinimizer *minimizer)
-
-        Sets minimizer. 
-
-        """
-        return _libBornAgainCore.FitSuite_setMinimizer(self, *args)
-
-
-    def minimizerName(self):
-        """
-        minimizerName(FitSuite self) -> std::string
-
-        std::string FitSuite::minimizerName() const
-
-        Returns minimizer. 
-
-        """
-        return _libBornAgainCore.FitSuite_minimizerName(self)
-
-
-    def initPrint(self, print_every_nth):
-        """
-        initPrint(FitSuite self, int print_every_nth)
-
-        void FitSuite::initPrint(int print_every_nth)
-
-        Initializes printing to standard output during the fitting. Prints also the summary when completed.
-
-        Parameters:
-        -----------
-
-        print_every_nth: 
-        Print every n'th iteration 
-
-        """
-        return _libBornAgainCore.FitSuite_initPrint(self, print_every_nth)
-
-
-    def runFit(self):
-        """
-        runFit(FitSuite self)
-
-        void FitSuite::runFit()
-
-        main method to run the fitting 
-
-        """
-        return _libBornAgainCore.FitSuite_runFit(self)
-
-
-    def numberOfFitObjects(self):
-        """
-        numberOfFitObjects(FitSuite self) -> size_t
-
-        size_t FitSuite::numberOfFitObjects() const
-
-        Returns number of fit objects, where fit object stands for (real, simulated) pair. 
-
-        """
-        return _libBornAgainCore.FitSuite_numberOfFitObjects(self)
-
-
-    def fitObjects(self):
-        """
-        fitObjects(FitSuite self) -> FitSuiteObjects
-
-        FitSuiteObjects * FitSuite::fitObjects()
-
-        returns  FitObject (pair of simulation/real data) 
-
-        """
-        return _libBornAgainCore.FitSuite_fitObjects(self)
-
-
-    def fitParameters(self):
-        """
-        fitParameters(FitSuite self) -> FitParameterSet
-
-        FitParameterSet * FitSuite::fitParameters()
-
-        Returns reference to fit parameters. 
-
-        """
-        return _libBornAgainCore.FitSuite_fitParameters(self)
-
-
-    def fitStrategies(self):
-        """
-        fitStrategies(FitSuite self) -> FitSuiteStrategies *
-
-        FitSuiteStrategies * FitSuite::fitStrategies()
-
-        Returns reference to fit parameters. 
-
-        """
-        return _libBornAgainCore.FitSuite_fitStrategies(self)
-
-
-    def isFirstIteration(self):
-        """
-        isFirstIteration(FitSuite self) -> bool
-
-        bool FitSuite::isFirstIteration() const
-
-        temporary method to check if it is first iteration 
-
-        """
-        return _libBornAgainCore.FitSuite_isFirstIteration(self)
-
-
-    def isLastIteration(self):
-        """
-        isLastIteration(FitSuite self) -> bool
-
-        bool FitSuite::isLastIteration() const
-
-        if the last iteration is done (used by observers to print summary) 
-
-        """
-        return _libBornAgainCore.FitSuite_isLastIteration(self)
-
-
-    def numberOfIterations(self):
-        """
-        numberOfIterations(FitSuite self) -> size_t
-
-        size_t FitSuite::numberOfIterations() const
-
-        Returns current number of minimization function calls. 
-
-        """
-        return _libBornAgainCore.FitSuite_numberOfIterations(self)
-
-
-    def currentStrategyIndex(self):
-        """
-        currentStrategyIndex(FitSuite self) -> size_t
-
-        size_t FitSuite::currentStrategyIndex() const
-
-        Returns the number of current strategy. 
-
-        """
-        return _libBornAgainCore.FitSuite_currentStrategyIndex(self)
-
-
-    def printResults(self):
-        """
-        printResults(FitSuite self)
-
-        void FitSuite::printResults() const
-
-        Prints results of the minimization to the standard output. 
-
-        """
-        return _libBornAgainCore.FitSuite_printResults(self)
-
-
-    def reportResults(self):
-        """
-        reportResults(FitSuite self) -> std::string
-
-        std::string FitSuite::reportResults() const
-
-        Reports results of minimization in the form of multi-line string. 
-
-        """
-        return _libBornAgainCore.FitSuite_reportResults(self)
-
-
-    def getChi2(self):
-        """
-        getChi2(FitSuite self) -> double
-
-        double FitSuite::getChi2() const
-
-        Returns minimum chi squared value found. 
-
-        """
-        return _libBornAgainCore.FitSuite_getChi2(self)
-
-
-    def interruptFitting(self):
-        """
-        interruptFitting(FitSuite self)
-
-        void FitSuite::interruptFitting()
-
-        """
-        return _libBornAgainCore.FitSuite_interruptFitting(self)
-
-
-    def resetInterrupt(self):
-        """
-        resetInterrupt(FitSuite self)
-
-        void FitSuite::resetInterrupt()
-
-        """
-        return _libBornAgainCore.FitSuite_resetInterrupt(self)
-
-
-    def isInterrupted(self):
-        """
-        isInterrupted(FitSuite self) -> bool
-
-        bool FitSuite::isInterrupted()
-
-        """
-        return _libBornAgainCore.FitSuite_isInterrupted(self)
-
-
-    def parametersToString(self):
-        """
-        parametersToString(FitSuite self) -> std::string
-
-        std::string FitSuite::parametersToString() const
-
-        Returns multiline string representing possible fit parameters. 
-
-        """
-        return _libBornAgainCore.FitSuite_parametersToString(self)
-
-
-    def treeToString(self):
-        """
-        treeToString(FitSuite self) -> std::string
-
-        std::string FitSuite::treeToString() const
-
-        Returns multiline string representing tree structure of fit components. 
-
-        """
-        return _libBornAgainCore.FitSuite_treeToString(self)
-
-
-    def setupToString(self):
-        """
-        setupToString(FitSuite self) -> std::string
-
-        std::string FitSuite::setupToString()
-
-        Returns multiline string representing fit setup. 
-
-        """
-        return _libBornAgainCore.FitSuite_setupToString(self)
-
-
-    def simulationResult(self, i_item=0):
-        """
-        simulationResult(FitSuite self, size_t i_item=0) -> SimulationResult
-        simulationResult(FitSuite self) -> SimulationResult
-
-        SimulationResult FitSuite::simulationResult(size_t i_item=0) const
-
-        Returns simulation result.
-
-        Parameters:
-        -----------
-
-        i_item: 
-        the index of fit pair 
-
-        """
-        return _libBornAgainCore.FitSuite_simulationResult(self, i_item)
-
-
-    def experimentalData(self, i_item=0):
-        """
-        experimentalData(FitSuite self, size_t i_item=0) -> SimulationResult
-        experimentalData(FitSuite self) -> SimulationResult
-
-        SimulationResult FitSuite::experimentalData(size_t i_item=0) const
-
-        Returns experimental data.
-
-        Parameters:
-        -----------
-
-        i_item: 
-        the index of fit pair 
-
-        """
-        return _libBornAgainCore.FitSuite_experimentalData(self, i_item)
-
-
-    def relativeDifference(self, i_item=0):
-        """
-        relativeDifference(FitSuite self, size_t i_item=0) -> SimulationResult
-        relativeDifference(FitSuite self) -> SimulationResult
-
-        SimulationResult FitSuite::relativeDifference(size_t i_item=0) const
-
-        Returns relative difference between simulation and experimental data.
-
-        Parameters:
-        -----------
-
-        i_item: 
-        the index of fit pair 
-
-        """
-        return _libBornAgainCore.FitSuite_relativeDifference(self, i_item)
-
-FitSuite_swigregister = _libBornAgainCore.FitSuite_swigregister
-FitSuite_swigregister(FitSuite)
-
-class FitSuiteObjects(INode):
-    """
-
-
-    Holds vector of  FitObject's (simulation and real data) to fit
-
-    C++ includes: FitSuiteObjects.h
-
-    """
-
-    __swig_setmethods__ = {}
-    for _s in [INode]:
-        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
-    __setattr__ = lambda self, name, value: _swig_setattr(self, FitSuiteObjects, name, value)
-    __swig_getmethods__ = {}
-    for _s in [INode]:
-        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
-    __getattr__ = lambda self, name: _swig_getattr(self, FitSuiteObjects, name)
-    __repr__ = _swig_repr
-
-    def __init__(self):
-        """
-        __init__(FitSuiteObjects self) -> FitSuiteObjects
-
-        FitSuiteObjects::FitSuiteObjects()
-
-        """
-        this = _libBornAgainCore.new_FitSuiteObjects()
-        try:
-            self.this.append(this)
-        except __builtin__.Exception:
-            self.this = this
-    __swig_destroy__ = _libBornAgainCore.delete_FitSuiteObjects
-    __del__ = lambda self: None
-
-    def accept(self, visitor):
-        """
-        accept(FitSuiteObjects self, INodeVisitor visitor)
-
-        void FitSuiteObjects::accept(INodeVisitor *visitor) const final
-
-        Calls the  INodeVisitor's visit method. 
-
-        """
-        return _libBornAgainCore.FitSuiteObjects_accept(self, visitor)
-
-
-    def add(self, simulation, real_data, weight=1.0):
-        """
-        add(FitSuiteObjects self, Simulation simulation, IntensityData real_data, double weight=1.0) -> FitObject
-        add(FitSuiteObjects self, Simulation simulation, IntensityData real_data) -> FitObject
-
-        FitObject * FitSuiteObjects::add(const Simulation &simulation, const OutputData< double > &real_data, double weight=1.0)
-
-        Adds to kit pair of (simulation, real data) for consecutive simulation. 
-
-        """
-        return _libBornAgainCore.FitSuiteObjects_add(self, simulation, real_data, weight)
-
-
-    def getSizeOfDataSet(self):
-        """
-        getSizeOfDataSet(FitSuiteObjects self) -> size_t
-
-        size_t FitSuiteObjects::getSizeOfDataSet() const
-
-        Returns total number of data points (number of all non-masked channels in all fit objects)
-
-        Returns total number of data points. 
-
-        """
-        return _libBornAgainCore.FitSuiteObjects_getSizeOfDataSet(self)
-
-
-    def setChiSquaredModule(self, chi2_module):
-        """
-        setChiSquaredModule(FitSuiteObjects self, IChiSquaredModule chi2_module)
-
-        void FitSuiteObjects::setChiSquaredModule(const IChiSquaredModule &chi2_module)
-
-        Replaces default  ChiSquaredModule with new one. 
-
-        """
-        return _libBornAgainCore.FitSuiteObjects_setChiSquaredModule(self, chi2_module)
-
-
-    def simulationResult(self, i_item=0):
-        """
-        simulationResult(FitSuiteObjects self, size_t i_item=0) -> SimulationResult
-        simulationResult(FitSuiteObjects self) -> SimulationResult
-
-        SimulationResult FitSuiteObjects::simulationResult(size_t i_item=0) const
-
-        Returns simulation result.
-
-        Parameters:
-        -----------
-
-        i_item: 
-        the index of fit pair 
-
-        """
-        return _libBornAgainCore.FitSuiteObjects_simulationResult(self, i_item)
-
-
-    def experimentalData(self, i_item=0):
-        """
-        experimentalData(FitSuiteObjects self, size_t i_item=0) -> SimulationResult
-        experimentalData(FitSuiteObjects self) -> SimulationResult
-
-        SimulationResult FitSuiteObjects::experimentalData(size_t i_item=0) const
-
-        Returns experimental data.
-
-        Parameters:
-        -----------
-
-        i_item: 
-        the index of fit pair 
-
-        """
-        return _libBornAgainCore.FitSuiteObjects_experimentalData(self, i_item)
-
-
-    def relativeDifference(self, i_item=0):
-        """
-        relativeDifference(FitSuiteObjects self, size_t i_item=0) -> SimulationResult
-        relativeDifference(FitSuiteObjects self) -> SimulationResult
-
-        SimulationResult FitSuiteObjects::relativeDifference(size_t i_item=0) const
-
-        Returns relative difference between simulation and experimental data.
-
-        Parameters:
-        -----------
-
-        i_item: 
-        the index of fit pair 
-
-        """
-        return _libBornAgainCore.FitSuiteObjects_relativeDifference(self, i_item)
-
-
-    def runSimulations(self):
-        """
-        runSimulations(FitSuiteObjects self)
-
-        void FitSuiteObjects::runSimulations()
-
-        run all simulation defined in fit pairs
-
-        loop through all defined simulations and run them 
-
-        """
-        return _libBornAgainCore.FitSuiteObjects_runSimulations(self)
-
-
-    def getChiSquaredValue(self):
-        """
-        getChiSquaredValue(FitSuiteObjects self) -> double
-
-        double FitSuiteObjects::getChiSquaredValue() const
-
-        Returns chi2 calculated over whole dataset. 
-
-        """
-        return _libBornAgainCore.FitSuiteObjects_getChiSquaredValue(self)
-
-
-    def getResidualValue(self, global_index):
-        """
-        getResidualValue(FitSuiteObjects self, size_t global_index) -> double
-
-        double FitSuiteObjects::getResidualValue(size_t global_index)
-
-        Returns residuals for single data element
-
-        Parameters:
-        -----------
-
-        global_index: 
-        index across all element in  FitElement vector 
-
-        """
-        return _libBornAgainCore.FitSuiteObjects_getResidualValue(self, global_index)
-
-
-    def residuals(self):
-        """
-        residuals(FitSuiteObjects self) -> vdouble1d_t
-
-        std::vector< double > FitSuiteObjects::residuals() const
-
-        """
-        return _libBornAgainCore.FitSuiteObjects_residuals(self)
-
-
-    def setNfreeParameters(self, nfree_parameters):
-        """
-        setNfreeParameters(FitSuiteObjects self, int nfree_parameters)
-
-        void FitSuiteObjects::setNfreeParameters(int nfree_parameters)
-
-        """
-        return _libBornAgainCore.FitSuiteObjects_setNfreeParameters(self, nfree_parameters)
-
-
-    def clear(self):
-        """
-        clear(FitSuiteObjects self)
-
-        void FitSuiteObjects::clear()
-
-        clear all data 
-
-        """
-        return _libBornAgainCore.FitSuiteObjects_clear(self)
-
-
-    def size(self):
-        """
-        size(FitSuiteObjects self) -> size_t
-
-        size_t FitSuiteObjects::size() const
-
-        """
-        return _libBornAgainCore.FitSuiteObjects_size(self)
-
-
-    def begin(self):
-        """
-        begin(FitSuiteObjects self) -> FitSuiteObjects::iterator
-
-        iterator FitSuiteObjects::begin()
-
-        """
-        return _libBornAgainCore.FitSuiteObjects_begin(self)
-
-
-    def end(self):
-        """
-        end(FitSuiteObjects self) -> FitSuiteObjects::iterator
-
-        iterator FitSuiteObjects::end()
-
-        """
-        return _libBornAgainCore.FitSuiteObjects_end(self)
-
-
-    def getChildren(self):
-        """
-        getChildren(FitSuiteObjects self) -> swig_dummy_type_const_inode_vector
-
-        std::vector< const INode * > FitSuiteObjects::getChildren() const
-
-        Returns a vector of children (const). 
-
-        """
-        return _libBornAgainCore.FitSuiteObjects_getChildren(self)
-
-FitSuiteObjects_swigregister = _libBornAgainCore.FitSuiteObjects_swigregister
-FitSuiteObjects_swigregister(FitSuiteObjects)
-
-class PyBuilderCallback(_object):
-    """
-
-
-    Builds simulation object using a Python callable. Base class to wrap Python callable and pass it to C++. Used in swig interface file, intended to be overloaded from Python.
-
-    C++ includes: PyFittingCallbacks.h
-
-    """
-
-    __swig_setmethods__ = {}
-    __setattr__ = lambda self, name, value: _swig_setattr(self, PyBuilderCallback, name, value)
-    __swig_getmethods__ = {}
-    __getattr__ = lambda self, name: _swig_getattr(self, PyBuilderCallback, name)
-    __repr__ = _swig_repr
-
-    def __init__(self):
-        """
-        __init__(PyBuilderCallback self) -> PyBuilderCallback
-
-        PyBuilderCallback::PyBuilderCallback()
-
-        """
-        if self.__class__ == PyBuilderCallback:
-            _self = None
-        else:
-            _self = self
-        this = _libBornAgainCore.new_PyBuilderCallback(_self, )
-        try:
-            self.this.append(this)
-        except __builtin__.Exception:
-            self.this = this
-    __swig_destroy__ = _libBornAgainCore.delete_PyBuilderCallback
-    __del__ = lambda self: None
-
-    def build_simulation(self, arg0):
-        """
-        build_simulation(PyBuilderCallback self, Parameters arg0) -> Simulation
-
-        Simulation * PyBuilderCallback::build_simulation(Fit::Parameters)
-
-        """
-        return _libBornAgainCore.PyBuilderCallback_build_simulation(self, arg0)
-
-    def __disown__(self):
-        self.this.disown()
-        _libBornAgainCore.disown_PyBuilderCallback(self)
-        return weakref_proxy(self)
-PyBuilderCallback_swigregister = _libBornAgainCore.PyBuilderCallback_swigregister
-PyBuilderCallback_swigregister(PyBuilderCallback)
-
-class PyObserverCallback(_object):
-    """
-
-
-    Observer for  FitObjective based on Python callable. Base class to wrap Python callable and pass it to C++. Used in swig interface file, intended to be overloaded from Python.
-
-    C++ includes: PyFittingCallbacks.h
-
-    """
-
-    __swig_setmethods__ = {}
-    __setattr__ = lambda self, name, value: _swig_setattr(self, PyObserverCallback, name, value)
-    __swig_getmethods__ = {}
-    __getattr__ = lambda self, name: _swig_getattr(self, PyObserverCallback, name)
-    __repr__ = _swig_repr
-
-    def __init__(self):
-        """
-        __init__(PyObserverCallback self) -> PyObserverCallback
-
-        PyObserverCallback::PyObserverCallback()
-
-        """
-        if self.__class__ == PyObserverCallback:
-            _self = None
-        else:
-            _self = self
-        this = _libBornAgainCore.new_PyObserverCallback(_self, )
-        try:
-            self.this.append(this)
-        except __builtin__.Exception:
-            self.this = this
-    __swig_destroy__ = _libBornAgainCore.delete_PyObserverCallback
-    __del__ = lambda self: None
-
-    def update(self, arg0):
-        """
-        update(PyObserverCallback self, FitObjective arg0)
-
-        void PyObserverCallback::update(const FitObjective &)
-
-        """
-        return _libBornAgainCore.PyObserverCallback_update(self, arg0)
-
-    def __disown__(self):
-        self.this.disown()
-        _libBornAgainCore.disown_PyObserverCallback(self)
-        return weakref_proxy(self)
-PyObserverCallback_swigregister = _libBornAgainCore.PyObserverCallback_swigregister
-PyObserverCallback_swigregister(PyObserverCallback)
-
-class FitObjective(_object):
-    """
-
-
-    Main class to hold pairs of simulation Holds vector of  FitObject's (simulation and real data) to fit
-
-    C++ includes: FitObjective.h
-
-    """
-
-    __swig_setmethods__ = {}
-    __setattr__ = lambda self, name, value: _swig_setattr(self, FitObjective, name, value)
-    __swig_getmethods__ = {}
-    __getattr__ = lambda self, name: _swig_getattr(self, FitObjective, name)
-    __repr__ = _swig_repr
-
-    def __init__(self):
-        """
-        __init__(FitObjective self) -> FitObjective
-
-        FitObjective::FitObjective()
-
-        """
-        this = _libBornAgainCore.new_FitObjective()
-        try:
-            self.this.append(this)
-        except __builtin__.Exception:
-            self.this = this
-    __swig_destroy__ = _libBornAgainCore.delete_FitObjective
-    __del__ = lambda self: None
-
-    def addSimulationAndData_cpp(self, *args):
-        """
-        addSimulationAndData_cpp(FitObjective self, PyBuilderCallback callback, vdouble1d_t data, double weight=1.0)
-        addSimulationAndData_cpp(FitObjective self, PyBuilderCallback callback, vdouble1d_t data)
-        addSimulationAndData_cpp(FitObjective self, PyBuilderCallback callback, vdouble2d_t data, double weight=1.0)
-        addSimulationAndData_cpp(FitObjective self, PyBuilderCallback callback, vdouble2d_t data)
-
-        void FitObjective::addSimulationAndData(PyBuilderCallback &callback, const std::vector< std::vector< double >> &data, double weight=1.0)
-
-        """
-        return _libBornAgainCore.FitObjective_addSimulationAndData_cpp(self, *args)
-
-
-    def evaluate_cpp(self, params):
-        """
-        evaluate_cpp(FitObjective self, Parameters params) -> double
-
-        double FitObjective::evaluate(const Fit::Parameters &params)
-
-        """
-        return _libBornAgainCore.FitObjective_evaluate_cpp(self, params)
-
-
-    def evaluate_residuals_cpp(self, params):
-        """
-        evaluate_residuals_cpp(FitObjective self, Parameters params) -> vdouble1d_t
-
-        std::vector< double > FitObjective::evaluate_residuals(const Fit::Parameters &params)
-
-        """
-        return _libBornAgainCore.FitObjective_evaluate_residuals_cpp(self, params)
-
-
-    def numberOfFitElements(self):
-        """
-        numberOfFitElements(FitObjective self) -> size_t
-
-        size_t FitObjective::numberOfFitElements() const
-
-        """
-        return _libBornAgainCore.FitObjective_numberOfFitElements(self)
-
-
-    def experimental_array(self):
-        """
-        experimental_array(FitObjective self) -> vdouble1d_t
-
-        std::vector< double > FitObjective::experimental_array() const
-
-        Returns one dimensional array representing experimental data. Masked areas and the area outside of region of interest are not included. Data from different datasets merged together. 
-
-        """
-        return _libBornAgainCore.FitObjective_experimental_array(self)
-
-
-    def simulation_array(self):
-        """
-        simulation_array(FitObjective self) -> vdouble1d_t
-
-        std::vector< double > FitObjective::simulation_array() const
-
-        Returns one dimensional array representing simulated intensities data. Masked areas and the area outside of region of interest are not included. Data from different datasets merged together. 
-
-        """
-        return _libBornAgainCore.FitObjective_simulation_array(self)
-
-
-    def simulationResult(self, i_item=0):
-        """
-        simulationResult(FitObjective self, size_t i_item=0) -> SimulationResult
-        simulationResult(FitObjective self) -> SimulationResult
-
-        SimulationResult FitObjective::simulationResult(size_t i_item=0) const
-
-        Returns simulation result.
-
-        Parameters:
-        -----------
-
-        i_item: 
-        the index of fit pair 
-
-        """
-        return _libBornAgainCore.FitObjective_simulationResult(self, i_item)
-
-
-    def experimentalData(self, i_item=0):
-        """
-        experimentalData(FitObjective self, size_t i_item=0) -> SimulationResult
-        experimentalData(FitObjective self) -> SimulationResult
-
-        SimulationResult FitObjective::experimentalData(size_t i_item=0) const
-
-        Returns experimental data.
-
-        Parameters:
-        -----------
-
-        i_item: 
-        the index of fit pair 
-
-        """
-        return _libBornAgainCore.FitObjective_experimentalData(self, i_item)
-
-
-    def relativeDifference(self, i_item=0):
-        """
-        relativeDifference(FitObjective self, size_t i_item=0) -> SimulationResult
-        relativeDifference(FitObjective self) -> SimulationResult
-
-        SimulationResult FitObjective::relativeDifference(size_t i_item=0) const
-
-        Returns relative difference between simulation and experimental data.
-
-        Parameters:
-        -----------
-
-        i_item: 
-        the index of fit pair 
-
-        """
-        return _libBornAgainCore.FitObjective_relativeDifference(self, i_item)
-
-
-    def initPrint(self, every_nth):
-        """
-        initPrint(FitObjective self, int every_nth)
-
-        void FitObjective::initPrint(int every_nth)
-
-        Initializes printing to standard output during the fitting.
-
-        Parameters:
-        -----------
-
-        every_nth: 
-        Print every n'th iteration. 
-
-        """
-        return _libBornAgainCore.FitObjective_initPrint(self, every_nth)
-
-
-    def initPlot_cpp(self, every_nth, callback):
-        """
-        initPlot_cpp(FitObjective self, int every_nth, PyObserverCallback callback)
-
-        void FitObjective::initPlot(int every_nth, PyObserverCallback &callback)
-
-        Initializes plotting during the fitting using Python callable.
-
-        Parameters:
-        -----------
-
-        every_nth: 
-        Called on every n'th iteration. 
-
-        """
-        return _libBornAgainCore.FitObjective_initPlot_cpp(self, every_nth, callback)
-
-
-    def isCompleted(self):
-        """
-        isCompleted(FitObjective self) -> bool
-
-        bool FitObjective::isCompleted() const
-
-        """
-        return _libBornAgainCore.FitObjective_isCompleted(self)
-
-
-    def iterationInfo(self):
-        """
-        iterationInfo(FitObjective self) -> IterationInfo
-
-        IterationInfo FitObjective::iterationInfo() const
-
-        """
-        return _libBornAgainCore.FitObjective_iterationInfo(self)
-
-
-    def minimizerResult(self):
-        """
-        minimizerResult(FitObjective self) -> Fit::MinimizerResult
-
-        Fit::MinimizerResult FitObjective::minimizerResult() const
-
-        """
-        return _libBornAgainCore.FitObjective_minimizerResult(self)
-
-
-    def finalize_cpp(self, result):
-        """
-        finalize_cpp(FitObjective self, Fit::MinimizerResult const & result)
-
-        void FitObjective::finalize(const Fit::MinimizerResult &result)
-
-        Should be explicitely called on last iteration to notify all observers. 
-
-        """
-        return _libBornAgainCore.FitObjective_finalize_cpp(self, result)
-
-
-    def fitObjectCount(self):
-        """
-        fitObjectCount(FitObjective self) -> unsigned int
-
-        unsigned FitObjective::fitObjectCount() const
-
-        """
-        return _libBornAgainCore.FitObjective_fitObjectCount(self)
-
-
-    def addSimulationAndData(self, callback, data, weight):
-        if not hasattr(self, 'callback_container'):
-            self.callback_container = []
-        wrp = SimulationBuilderWrapper(callback)
-        self.callback_container.append(wrp)
-        return self.addSimulationAndData_cpp(wrp, data, weight)
-
-    def convert_params(self, params):
-        """
-        Converts parameters to what FitObjective::evaluate expects
-        """
-
-        if str(params.__module__) == "lmfit.parameter":
-            bapars = libBornAgainFit.Parameters()
-            for p in params:
-                bapars.add(p, params[p].value)
-            return bapars
-        else:
-            return params
-
-    def evaluate_residuals(self, params):
-        return self.evaluate_residuals_cpp(self.convert_params(params))
-
-    def evaluate(self, params):
-        return self.evaluate_cpp(self.convert_params(params))
-
-    def convert_result(self, minim_result):
-        """
-        Converts result reported by arbitrary minimizer to ba.MinimizerResult
-        """
-
-        if str(minim_result.__module__) == "lmfit.minimizer":
-            return libBornAgainFit.MinimizerResult()
-        else:
-            return minim_result
-
-    def finalize(self, minimizer_result):
-        return self.finalize_cpp(self.convert_result(minimizer_result))
-
-    def create_default_plotter(self):
-        import plot_utils
-        self.m_plotter = plot_utils.PlotterGISASV2()
-        return self.m_plotter.plot
-
-    def initPlot(self, every_nth, callback = None):
-        if not callback:
-            callback = self.create_default_plotter()
-
-        self.wrp_plot_observer = ObserverCallbackWrapper(callback)
-        return self.initPlot_cpp(every_nth, self.wrp_plot_observer)
-
-
-FitObjective_swigregister = _libBornAgainCore.FitObjective_swigregister
-FitObjective_swigregister(FitObjective)
-
-
-def StandardNormal(x):
-    """
-    StandardNormal(double x) -> double
-
-    double MathFunctions::StandardNormal(double x)
-
-    """
-    return _libBornAgainCore.StandardNormal(x)
-
-def Gaussian(x, average, std_dev):
-    """
-    Gaussian(double x, double average, double std_dev) -> double
-
-    double MathFunctions::Gaussian(double x, double average, double std_dev)
-
-    """
-    return _libBornAgainCore.Gaussian(x, average, std_dev)
-
-def IntegratedGaussian(x, average, std_dev):
-    """
-    IntegratedGaussian(double x, double average, double std_dev) -> double
-
-    double MathFunctions::IntegratedGaussian(double x, double average, double std_dev)
-
-    """
-    return _libBornAgainCore.IntegratedGaussian(x, average, std_dev)
-
-def cot(x):
-    """
-    cot(double x) -> double
-
-    double MathFunctions::cot(double x)
-
-    cotangent function:  $cot(x)\\equiv1/tan(x)$
-
-    """
-    return _libBornAgainCore.cot(x)
-
-def Si(x):
-    """
-    Si(double x) -> double
-
-    double MathFunctions::Si(double x)
-
-    Sine integral function:  $Si(x)\\equiv\\int_0^x du \\sin(u)/u$. 
-
-    """
-    return _libBornAgainCore.Si(x)
-
-def sinc(*args):
-    """
-    sinc(double x) -> double
-    sinc(complex_t const z) -> complex_t
-
-    complex_t MathFunctions::sinc(const complex_t z)
-
-    Complex sinc function:  $sinc(x)\\equiv\\sin(x)/x$. 
-
-    """
-    return _libBornAgainCore.sinc(*args)
-
-def tanhc(z):
-    """
-    tanhc(complex_t const z) -> complex_t
-
-    complex_t MathFunctions::tanhc(const complex_t z)
-
-    Complex tanhc function:  $tanhc(x)\\equiv\\tanh(x)/x$. 
-
-    """
-    return _libBornAgainCore.tanhc(z)
-
-def Laue(z, N):
-    """
-    Laue(complex_t const z, size_t N) -> complex_t
-
-    complex_t MathFunctions::Laue(const complex_t z, size_t N)
-
-    """
-    return _libBornAgainCore.Laue(z, N)
-
-def erf(arg):
-    """
-    erf(double arg) -> double
-
-    double MathFunctions::erf(double arg)
-
-    Error function of real-valued argument. 
-
-    """
-    return _libBornAgainCore.erf(arg)
-
-def Bessel_J0(*args):
-    """
-    Bessel_J0(double x) -> double
-    Bessel_J0(complex_t const z) -> complex_t
-
-    complex_t MathFunctions::Bessel_J0(const complex_t z)
-
-    Complex Bessel function of the first kind and order 0. 
-
-    """
-    return _libBornAgainCore.Bessel_J0(*args)
-
-def Bessel_J1(*args):
-    """
-    Bessel_J1(double x) -> double
-    Bessel_J1(complex_t const z) -> complex_t
-
-    complex_t MathFunctions::Bessel_J1(const complex_t z)
-
-    Complex Bessel function of the first kind and order 1. 
-
-    """
-    return _libBornAgainCore.Bessel_J1(*args)
-
-def Bessel_J1c(*args):
-    """
-    Bessel_J1c(double x) -> double
-    Bessel_J1c(complex_t const z) -> complex_t
-
-    complex_t MathFunctions::Bessel_J1c(const complex_t z)
-
-    Complex Bessel function Bessel_J1(x)/x. 
-
-    """
-    return _libBornAgainCore.Bessel_J1c(*args)
-FORWARD_FFT = _libBornAgainCore.FORWARD_FFT
-BACKWARD_FFT = _libBornAgainCore.BACKWARD_FFT
-
-def FastFourierTransform(*args):
-    """
-    FastFourierTransform(vector_complex_t data, MathFunctions::EFFTDirection tcase) -> vector_complex_t
-    FastFourierTransform(vdouble1d_t data, MathFunctions::EFFTDirection tcase) -> vector_complex_t
-
-    std::vector< complex_t > MathFunctions::FastFourierTransform(const std::vector< double > &data, EFFTDirection tcase)
-
-    simple (and unoptimized) wrapper function for the discrete fast Fourier transformation library (fftw3); transforms real to complex 
-
-    """
-    return _libBornAgainCore.FastFourierTransform(*args)
-
-def ConvolveFFT(signal, resfunc):
-    """
-    ConvolveFFT(vdouble1d_t signal, vdouble1d_t resfunc) -> vector_complex_t
-
-    std::vector< complex_t > MathFunctions::ConvolveFFT(const std::vector< double > &signal, const std::vector< double > &resfunc)
-
-    convolution of two real vectors of equal size 
-
-    """
-    return _libBornAgainCore.ConvolveFFT(signal, resfunc)
-
-def GenerateUniformRandom():
-    """
-    GenerateUniformRandom() -> double
-
-    double MathFunctions::GenerateUniformRandom()
+    double MathFunctions::GenerateUniformRandom()
 
     """
     return _libBornAgainCore.GenerateUniformRandom()
@@ -8551,78 +6695,6 @@ def GeneratePoissonRandom(average):
 
     """
     return _libBornAgainCore.GeneratePoissonRandom(average)
-class AdjustMinimizerStrategy(IFitStrategy):
-    """
-
-
-    Strategy modifies mimimizer settings before running minimization round.
-
-    C++ includes: AdjustMinimizerStrategy.h
-
-    """
-
-    __swig_setmethods__ = {}
-    for _s in [IFitStrategy]:
-        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
-    __setattr__ = lambda self, name, value: _swig_setattr(self, AdjustMinimizerStrategy, name, value)
-    __swig_getmethods__ = {}
-    for _s in [IFitStrategy]:
-        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
-    __getattr__ = lambda self, name: _swig_getattr(self, AdjustMinimizerStrategy, name)
-    __repr__ = _swig_repr
-
-    def __init__(self, *args):
-        """
-        __init__(AdjustMinimizerStrategy self) -> AdjustMinimizerStrategy
-        __init__(AdjustMinimizerStrategy self, std::string const & minimizerName, std::string const & algorithmName, std::string const & optionString) -> AdjustMinimizerStrategy
-        __init__(AdjustMinimizerStrategy self, std::string const & minimizerName, std::string const & algorithmName) -> AdjustMinimizerStrategy
-        __init__(AdjustMinimizerStrategy self, std::string const & minimizerName) -> AdjustMinimizerStrategy
-
-        AdjustMinimizerStrategy::AdjustMinimizerStrategy(const std::string &minimizerName, const std::string &algorithmName="", const std::string &optionString="")
-
-        """
-        this = _libBornAgainCore.new_AdjustMinimizerStrategy(*args)
-        try:
-            self.this.append(this)
-        except __builtin__.Exception:
-            self.this = this
-
-    def clone(self):
-        """
-        clone(AdjustMinimizerStrategy self) -> AdjustMinimizerStrategy
-
-        AdjustMinimizerStrategy * AdjustMinimizerStrategy::clone() const
-
-        """
-        return _libBornAgainCore.AdjustMinimizerStrategy_clone(self)
-
-
-    def setMinimizer(self, *args):
-        """
-        setMinimizer(AdjustMinimizerStrategy self, std::string const & minimizerName, std::string const & algorithmName, std::string const & optionString)
-        setMinimizer(AdjustMinimizerStrategy self, std::string const & minimizerName, std::string const & algorithmName)
-        setMinimizer(AdjustMinimizerStrategy self, std::string const & minimizerName)
-
-        void AdjustMinimizerStrategy::setMinimizer(const std::string &minimizerName, const std::string &algorithmName="", const std::string &optionString="")
-
-        """
-        return _libBornAgainCore.AdjustMinimizerStrategy_setMinimizer(self, *args)
-
-
-    def execute(self):
-        """
-        execute(AdjustMinimizerStrategy self)
-
-        void AdjustMinimizerStrategy::execute()
-
-        """
-        return _libBornAgainCore.AdjustMinimizerStrategy_execute(self)
-
-    __swig_destroy__ = _libBornAgainCore.delete_AdjustMinimizerStrategy
-    __del__ = lambda self: None
-AdjustMinimizerStrategy_swigregister = _libBornAgainCore.AdjustMinimizerStrategy_swigregister
-AdjustMinimizerStrategy_swigregister(AdjustMinimizerStrategy)
-
 class IMultiLayerBuilder(IParameterized):
     """
 
@@ -8813,8 +6885,6 @@ class INodeVisitor(_object):
         visit(INodeVisitor self, DistributionLogNormal arg2)
         visit(INodeVisitor self, DistributionLorentz arg2)
         visit(INodeVisitor self, DistributionTrapezoid arg2)
-        visit(INodeVisitor self, FitObject arg2)
-        visit(INodeVisitor self, FitSuiteObjects arg2)
         visit(INodeVisitor self, FootprintFactorGaussian arg2)
         visit(INodeVisitor self, FootprintFactorSquare arg2)
         visit(INodeVisitor self, FormFactorAnisoPyramid arg2)
@@ -8838,6 +6908,7 @@ class INodeVisitor(_object):
         visit(INodeVisitor self, FormFactorGauss arg2)
         visit(INodeVisitor self, FormFactorHemiEllipsoid arg2)
         visit(INodeVisitor self, FormFactorIcosahedron arg2)
+        visit(INodeVisitor self, FormFactorLongBox arg2)
         visit(INodeVisitor self, FormFactorLongBoxGauss arg2)
         visit(INodeVisitor self, FormFactorLongBoxLorentz arg2)
         visit(INodeVisitor self, FormFactorLorentz arg2)
@@ -8888,12 +6959,13 @@ class INodeVisitor(_object):
         visit(INodeVisitor self, IntensityScaleAndShiftNormalizer arg2)
         visit(INodeVisitor self, InterferenceFunction1DLattice arg2)
         visit(INodeVisitor self, InterferenceFunction2DLattice arg2)
-        visit(INodeVisitor self, InterferenceFunction3DLattice arg2)
+        visit(INodeVisitor self, InterferenceFunction2DParaCrystal arg2)
         visit(INodeVisitor self, InterferenceFunction2DSuperLattice arg2)
+        visit(INodeVisitor self, InterferenceFunction3DLattice arg2)
         visit(INodeVisitor self, InterferenceFunctionFinite2DLattice arg2)
-        visit(INodeVisitor self, InterferenceFunction2DParaCrystal arg2)
-        visit(INodeVisitor self, InterferenceFunctionNone arg2)
+        visit(INodeVisitor self, InterferenceFunctionFinite3DLattice arg2)
         visit(INodeVisitor self, InterferenceFunctionRadialParaCrystal arg2)
+        visit(INodeVisitor self, InterferenceFunctionNone arg2)
         visit(INodeVisitor self, IParticle arg2)
         visit(INodeVisitor self, IPeakShape arg2)
         visit(INodeVisitor self, IRotation arg2)
@@ -13117,10 +11189,7 @@ class PolyhedralFace(_object):
         -----------
 
         V: 
-        oriented vertex list
-
-        _sym_S2: 
-        true if face has a perpedicular two-fold symmetry axis 
+        oriented vertex list 
 
         """
         this = _libBornAgainCore.new_PolyhedralFace(*args)
@@ -15235,56 +13304,141 @@ class FormFactorHemiEllipsoid(IFormFactorBorn):
         return _libBornAgainCore.FormFactorHemiEllipsoid_radialExtension(self)
 
 
-    def evaluate_for_q(self, q):
+    def evaluate_for_q(self, q):
+        """
+        evaluate_for_q(FormFactorHemiEllipsoid self, cvector_t q) -> complex_t
+
+        complex_t FormFactorHemiEllipsoid::evaluate_for_q(cvector_t q) const override final
+
+        Returns scattering amplitude for complex scattering wavevector q=k_i-k_f. This method is public only for convenience of plotting form factors in Python. 
+
+        """
+        return _libBornAgainCore.FormFactorHemiEllipsoid_evaluate_for_q(self, q)
+
+FormFactorHemiEllipsoid_swigregister = _libBornAgainCore.FormFactorHemiEllipsoid_swigregister
+FormFactorHemiEllipsoid_swigregister(FormFactorHemiEllipsoid)
+
+class FormFactorIcosahedron(FormFactorPolyhedron):
+    """
+
+
+    A regular icosahedron.
+
+    C++ includes: FormFactorIcosahedron.h
+
+    """
+
+    __swig_setmethods__ = {}
+    for _s in [FormFactorPolyhedron]:
+        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
+    __setattr__ = lambda self, name, value: _swig_setattr(self, FormFactorIcosahedron, name, value)
+    __swig_getmethods__ = {}
+    for _s in [FormFactorPolyhedron]:
+        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
+    __getattr__ = lambda self, name: _swig_getattr(self, FormFactorIcosahedron, name)
+    __repr__ = _swig_repr
+
+    def __init__(self, edge):
+        """
+        __init__(FormFactorIcosahedron self, double edge) -> FormFactorIcosahedron
+
+        FormFactorIcosahedron::FormFactorIcosahedron(double edge)
+
+        Constructor of a icosahedron.
+
+        Parameters:
+        -----------
+
+        edge: 
+        length of the edge in nanometers 
+
+        """
+        this = _libBornAgainCore.new_FormFactorIcosahedron(edge)
+        try:
+            self.this.append(this)
+        except __builtin__.Exception:
+            self.this = this
+
+    def clone(self):
+        """
+        clone(FormFactorIcosahedron self) -> FormFactorIcosahedron
+
+        FormFactorIcosahedron* FormFactorIcosahedron::clone() const override final
+
+        Returns a clone of this  ISample object. 
+
+        """
+        return _libBornAgainCore.FormFactorIcosahedron_clone(self)
+
+
+    def accept(self, visitor):
+        """
+        accept(FormFactorIcosahedron self, INodeVisitor visitor)
+
+        void FormFactorIcosahedron::accept(INodeVisitor *visitor) const override final
+
+        Calls the  INodeVisitor's visit method. 
+
+        """
+        return _libBornAgainCore.FormFactorIcosahedron_accept(self, visitor)
+
+
+    def getEdge(self):
         """
-        evaluate_for_q(FormFactorHemiEllipsoid self, cvector_t q) -> complex_t
-
-        complex_t FormFactorHemiEllipsoid::evaluate_for_q(cvector_t q) const override final
+        getEdge(FormFactorIcosahedron self) -> double
 
-        Returns scattering amplitude for complex scattering wavevector q=k_i-k_f. This method is public only for convenience of plotting form factors in Python. 
+        double FormFactorIcosahedron::getEdge() const
 
         """
-        return _libBornAgainCore.FormFactorHemiEllipsoid_evaluate_for_q(self, q)
+        return _libBornAgainCore.FormFactorIcosahedron_getEdge(self)
 
-FormFactorHemiEllipsoid_swigregister = _libBornAgainCore.FormFactorHemiEllipsoid_swigregister
-FormFactorHemiEllipsoid_swigregister(FormFactorHemiEllipsoid)
+    __swig_destroy__ = _libBornAgainCore.delete_FormFactorIcosahedron
+    __del__ = lambda self: None
+FormFactorIcosahedron_swigregister = _libBornAgainCore.FormFactorIcosahedron_swigregister
+FormFactorIcosahedron_swigregister(FormFactorIcosahedron)
 
-class FormFactorIcosahedron(FormFactorPolyhedron):
+class FormFactorLongBox(IFormFactorBorn):
     """
 
 
-    A regular icosahedron.
+    The formfactor for a long rectangular box. Approximates the rapidly oscillating sinc function by the square root of a Lorentzian
 
-    C++ includes: FormFactorIcosahedron.h
+    C++ includes: FormFactorLongBox.h
 
     """
 
     __swig_setmethods__ = {}
-    for _s in [FormFactorPolyhedron]:
+    for _s in [IFormFactorBorn]:
         __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
-    __setattr__ = lambda self, name, value: _swig_setattr(self, FormFactorIcosahedron, name, value)
+    __setattr__ = lambda self, name, value: _swig_setattr(self, FormFactorLongBox, name, value)
     __swig_getmethods__ = {}
-    for _s in [FormFactorPolyhedron]:
+    for _s in [IFormFactorBorn]:
         __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
-    __getattr__ = lambda self, name: _swig_getattr(self, FormFactorIcosahedron, name)
+    __getattr__ = lambda self, name: _swig_getattr(self, FormFactorLongBox, name)
     __repr__ = _swig_repr
 
-    def __init__(self, edge):
+    def __init__(self, length, width, height):
         """
-        __init__(FormFactorIcosahedron self, double edge) -> FormFactorIcosahedron
+        __init__(FormFactorLongBox self, double length, double width, double height) -> FormFactorLongBox
 
-        FormFactorIcosahedron::FormFactorIcosahedron(double edge)
+        FormFactorLongBox::FormFactorLongBox(double length, double width, double height)
 
-        Constructor of a icosahedron.
+        Box constructor.
 
         Parameters:
         -----------
 
-        edge: 
-        length of the edge in nanometers 
+        length: 
+        of  Box's base
+
+        width: 
+        of  Box's base
+
+        height: 
+        of  Box
 
         """
-        this = _libBornAgainCore.new_FormFactorIcosahedron(edge)
+        this = _libBornAgainCore.new_FormFactorLongBox(length, width, height)
         try:
             self.this.append(this)
         except __builtin__.Exception:
@@ -15292,41 +13446,85 @@ class FormFactorIcosahedron(FormFactorPolyhedron):
 
     def clone(self):
         """
-        clone(FormFactorIcosahedron self) -> FormFactorIcosahedron
+        clone(FormFactorLongBox self) -> FormFactorLongBox
 
-        FormFactorIcosahedron* FormFactorIcosahedron::clone() const override final
+        FormFactorLongBox* FormFactorLongBox::clone() const override final
 
         Returns a clone of this  ISample object. 
 
         """
-        return _libBornAgainCore.FormFactorIcosahedron_clone(self)
+        return _libBornAgainCore.FormFactorLongBox_clone(self)
 
 
     def accept(self, visitor):
         """
-        accept(FormFactorIcosahedron self, INodeVisitor visitor)
+        accept(FormFactorLongBox self, INodeVisitor visitor)
 
-        void FormFactorIcosahedron::accept(INodeVisitor *visitor) const override final
+        void FormFactorLongBox::accept(INodeVisitor *visitor) const override final
 
         Calls the  INodeVisitor's visit method. 
 
         """
-        return _libBornAgainCore.FormFactorIcosahedron_accept(self, visitor)
+        return _libBornAgainCore.FormFactorLongBox_accept(self, visitor)
 
 
-    def getEdge(self):
+    def getLength(self):
         """
-        getEdge(FormFactorIcosahedron self) -> double
+        getLength(FormFactorLongBox self) -> double
 
-        double FormFactorIcosahedron::getEdge() const
+        double FormFactorLongBox::getLength() const
 
         """
-        return _libBornAgainCore.FormFactorIcosahedron_getEdge(self)
+        return _libBornAgainCore.FormFactorLongBox_getLength(self)
 
-    __swig_destroy__ = _libBornAgainCore.delete_FormFactorIcosahedron
+
+    def getHeight(self):
+        """
+        getHeight(FormFactorLongBox self) -> double
+
+        double FormFactorLongBox::getHeight() const
+
+        """
+        return _libBornAgainCore.FormFactorLongBox_getHeight(self)
+
+
+    def getWidth(self):
+        """
+        getWidth(FormFactorLongBox self) -> double
+
+        double FormFactorLongBox::getWidth() const
+
+        """
+        return _libBornAgainCore.FormFactorLongBox_getWidth(self)
+
+
+    def radialExtension(self):
+        """
+        radialExtension(FormFactorLongBox self) -> double
+
+        double FormFactorLongBox::radialExtension() const override final
+
+        Returns the (approximate in some cases) radial size of the particle of this form factor's shape. This is used for SSCA calculations 
+
+        """
+        return _libBornAgainCore.FormFactorLongBox_radialExtension(self)
+
+
+    def evaluate_for_q(self, q):
+        """
+        evaluate_for_q(FormFactorLongBox self, cvector_t q) -> complex_t
+
+        complex_t FormFactorLongBox::evaluate_for_q(cvector_t q) const override final
+
+        Returns scattering amplitude for complex scattering wavevector q=k_i-k_f. This method is public only for convenience of plotting form factors in Python. 
+
+        """
+        return _libBornAgainCore.FormFactorLongBox_evaluate_for_q(self, q)
+
+    __swig_destroy__ = _libBornAgainCore.delete_FormFactorLongBox
     __del__ = lambda self: None
-FormFactorIcosahedron_swigregister = _libBornAgainCore.FormFactorIcosahedron_swigregister
-FormFactorIcosahedron_swigregister(FormFactorIcosahedron)
+FormFactorLongBox_swigregister = _libBornAgainCore.FormFactorLongBox_swigregister
+FormFactorLongBox_swigregister(FormFactorLongBox)
 
 class FormFactorLongBoxGauss(IFormFactorBorn):
     """
@@ -21051,108 +19249,339 @@ class IParticle(IAbstractParticle):
         registerPosition(IParticle self, bool make_registered=True)
         registerPosition(IParticle self)
 
-        void IParticle::registerPosition(bool make_registered=true)
+        void IParticle::registerPosition(bool make_registered=true)
+
+        Registers the three components of its position. 
+
+        """
+        return _libBornAgainCore.IParticle_registerPosition(self, make_registered)
+
+
+    def decompose(self):
+        """
+        decompose(IParticle self) -> SafePointerVector< IParticle >
+
+        SafePointerVector< IParticle > IParticle::decompose() const
+
+        Decompose in constituent  IParticle objects. 
+
+        """
+        return _libBornAgainCore.IParticle_decompose(self)
+
+
+    def bottomTopZ(self):
+        """
+        bottomTopZ(IParticle self) -> ParticleLimits
+
+        ParticleLimits IParticle::bottomTopZ() const
+
+        Top and bottom z-coordinate. 
+
+        """
+        return _libBornAgainCore.IParticle_bottomTopZ(self)
+
+IParticle_swigregister = _libBornAgainCore.IParticle_swigregister
+IParticle_swigregister(IParticle)
+
+class IPeakShape(ISample):
+    """
+
+
+    Pure virtual interface class that defines the peak shape of a Bragg peak.
+
+    C++ includes: IPeakShape.h
+
+    """
+
+    __swig_setmethods__ = {}
+    for _s in [ISample]:
+        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
+    __setattr__ = lambda self, name, value: _swig_setattr(self, IPeakShape, name, value)
+    __swig_getmethods__ = {}
+    for _s in [ISample]:
+        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
+    __getattr__ = lambda self, name: _swig_getattr(self, IPeakShape, name)
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+    __repr__ = _swig_repr
+    __swig_destroy__ = _libBornAgainCore.delete_IPeakShape
+    __del__ = lambda self: None
+
+    def clone(self):
+        """
+        clone(IPeakShape self) -> IPeakShape
+
+        virtual IPeakShape* IPeakShape::clone() const =0
+
+        Returns a clone of this  ISample object. 
+
+        """
+        return _libBornAgainCore.IPeakShape_clone(self)
+
+
+    def evaluate(self, q, q_lattice_point):
+        """
+        evaluate(IPeakShape self, kvector_t q, kvector_t q_lattice_point) -> double
+
+        virtual double IPeakShape::evaluate(const kvector_t q, const kvector_t q_lattice_point) const =0
+
+        Evaluates the peak shape at q from a reciprocal lattice point at q_lattice_point. 
+
+        """
+        return _libBornAgainCore.IPeakShape_evaluate(self, q, q_lattice_point)
+
+
+    def angularDisorder(self):
+        """
+        angularDisorder(IPeakShape self) -> bool
+
+        virtual bool IPeakShape::angularDisorder() const
+
+        Indicates if the peak shape encodes angular disorder, in which case all peaks in a spherical shell are needed 
+
+        """
+        return _libBornAgainCore.IPeakShape_angularDisorder(self)
+
+IPeakShape_swigregister = _libBornAgainCore.IPeakShape_swigregister
+IPeakShape_swigregister(IPeakShape)
+
+class IsotropicGaussPeakShape(IPeakShape):
+    """
+
+
+    Class that implements an isotropic Gaussian peak shape of a Bragg peak.
+
+    C++ includes: IPeakShape.h
+
+    """
+
+    __swig_setmethods__ = {}
+    for _s in [IPeakShape]:
+        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
+    __setattr__ = lambda self, name, value: _swig_setattr(self, IsotropicGaussPeakShape, name, value)
+    __swig_getmethods__ = {}
+    for _s in [IPeakShape]:
+        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
+    __getattr__ = lambda self, name: _swig_getattr(self, IsotropicGaussPeakShape, name)
+    __repr__ = _swig_repr
+
+    def __init__(self, max_intensity, domainsize):
+        """
+        __init__(IsotropicGaussPeakShape self, double max_intensity, double domainsize) -> IsotropicGaussPeakShape
+
+        IsotropicGaussPeakShape::IsotropicGaussPeakShape(double max_intensity, double domainsize)
+
+        """
+        this = _libBornAgainCore.new_IsotropicGaussPeakShape(max_intensity, domainsize)
+        try:
+            self.this.append(this)
+        except __builtin__.Exception:
+            self.this = this
+    __swig_destroy__ = _libBornAgainCore.delete_IsotropicGaussPeakShape
+    __del__ = lambda self: None
+
+    def clone(self):
+        """
+        clone(IsotropicGaussPeakShape self) -> IsotropicGaussPeakShape
+
+        IsotropicGaussPeakShape * IsotropicGaussPeakShape::clone() const override
+
+        Returns a clone of this  ISample object. 
+
+        """
+        return _libBornAgainCore.IsotropicGaussPeakShape_clone(self)
+
+
+    def accept(self, visitor):
+        """
+        accept(IsotropicGaussPeakShape self, INodeVisitor visitor)
+
+        void IsotropicGaussPeakShape::accept(INodeVisitor *visitor) const override
+
+        Calls the  INodeVisitor's visit method. 
+
+        """
+        return _libBornAgainCore.IsotropicGaussPeakShape_accept(self, visitor)
+
+
+    def evaluate(self, q, q_lattice_point):
+        """
+        evaluate(IsotropicGaussPeakShape self, kvector_t q, kvector_t q_lattice_point) -> double
+
+        double IsotropicGaussPeakShape::evaluate(const kvector_t q, const kvector_t q_lattice_point) const override
+
+        Evaluates the peak shape at q from a reciprocal lattice point at q_lattice_point. 
+
+        """
+        return _libBornAgainCore.IsotropicGaussPeakShape_evaluate(self, q, q_lattice_point)
+
+IsotropicGaussPeakShape_swigregister = _libBornAgainCore.IsotropicGaussPeakShape_swigregister
+IsotropicGaussPeakShape_swigregister(IsotropicGaussPeakShape)
+
+class IsotropicLorentzPeakShape(IPeakShape):
+    """
+
+
+    Class that implements an isotropic Lorentzian peak shape of a Bragg peak.
+
+    C++ includes: IPeakShape.h
+
+    """
+
+    __swig_setmethods__ = {}
+    for _s in [IPeakShape]:
+        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
+    __setattr__ = lambda self, name, value: _swig_setattr(self, IsotropicLorentzPeakShape, name, value)
+    __swig_getmethods__ = {}
+    for _s in [IPeakShape]:
+        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
+    __getattr__ = lambda self, name: _swig_getattr(self, IsotropicLorentzPeakShape, name)
+    __repr__ = _swig_repr
+
+    def __init__(self, max_intensity, domainsize):
+        """
+        __init__(IsotropicLorentzPeakShape self, double max_intensity, double domainsize) -> IsotropicLorentzPeakShape
+
+        IsotropicLorentzPeakShape::IsotropicLorentzPeakShape(double max_intensity, double domainsize)
+
+        """
+        this = _libBornAgainCore.new_IsotropicLorentzPeakShape(max_intensity, domainsize)
+        try:
+            self.this.append(this)
+        except __builtin__.Exception:
+            self.this = this
+    __swig_destroy__ = _libBornAgainCore.delete_IsotropicLorentzPeakShape
+    __del__ = lambda self: None
+
+    def clone(self):
+        """
+        clone(IsotropicLorentzPeakShape self) -> IsotropicLorentzPeakShape
+
+        IsotropicLorentzPeakShape * IsotropicLorentzPeakShape::clone() const override
 
-        Registers the three components of its position. 
+        Returns a clone of this  ISample object. 
 
         """
-        return _libBornAgainCore.IParticle_registerPosition(self, make_registered)
+        return _libBornAgainCore.IsotropicLorentzPeakShape_clone(self)
 
 
-    def decompose(self):
+    def accept(self, visitor):
         """
-        decompose(IParticle self) -> SafePointerVector< IParticle >
+        accept(IsotropicLorentzPeakShape self, INodeVisitor visitor)
 
-        SafePointerVector< IParticle > IParticle::decompose() const
+        void IsotropicLorentzPeakShape::accept(INodeVisitor *visitor) const override
 
-        Decompose in constituent  IParticle objects. 
+        Calls the  INodeVisitor's visit method. 
 
         """
-        return _libBornAgainCore.IParticle_decompose(self)
+        return _libBornAgainCore.IsotropicLorentzPeakShape_accept(self, visitor)
 
 
-    def bottomTopZ(self):
+    def evaluate(self, q, q_lattice_point):
         """
-        bottomTopZ(IParticle self) -> ParticleLimits
+        evaluate(IsotropicLorentzPeakShape self, kvector_t q, kvector_t q_lattice_point) -> double
 
-        ParticleLimits IParticle::bottomTopZ() const
+        double IsotropicLorentzPeakShape::evaluate(const kvector_t q, const kvector_t q_lattice_point) const override
 
-        Top and bottom z-coordinate. 
+        Evaluates the peak shape at q from a reciprocal lattice point at q_lattice_point. 
 
         """
-        return _libBornAgainCore.IParticle_bottomTopZ(self)
+        return _libBornAgainCore.IsotropicLorentzPeakShape_evaluate(self, q, q_lattice_point)
 
-IParticle_swigregister = _libBornAgainCore.IParticle_swigregister
-IParticle_swigregister(IParticle)
+IsotropicLorentzPeakShape_swigregister = _libBornAgainCore.IsotropicLorentzPeakShape_swigregister
+IsotropicLorentzPeakShape_swigregister(IsotropicLorentzPeakShape)
 
-class IPeakShape(ISample):
+class GaussFisherPeakShape(IPeakShape):
     """
 
 
-    Pure virtual interface class that defines the peak shape of a Bragg peak.
+    Class that implements a peak shape that is Gaussian in the radial direction and uses the von Mises-Fisher distribution in the angular direction.
 
     C++ includes: IPeakShape.h
 
     """
 
     __swig_setmethods__ = {}
-    for _s in [ISample]:
+    for _s in [IPeakShape]:
         __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
-    __setattr__ = lambda self, name, value: _swig_setattr(self, IPeakShape, name, value)
+    __setattr__ = lambda self, name, value: _swig_setattr(self, GaussFisherPeakShape, name, value)
     __swig_getmethods__ = {}
-    for _s in [ISample]:
+    for _s in [IPeakShape]:
         __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
-    __getattr__ = lambda self, name: _swig_getattr(self, IPeakShape, name)
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined - class is abstract")
+    __getattr__ = lambda self, name: _swig_getattr(self, GaussFisherPeakShape, name)
     __repr__ = _swig_repr
-    __swig_destroy__ = _libBornAgainCore.delete_IPeakShape
+
+    def __init__(self, max_intensity, radial_size, kappa):
+        """
+        __init__(GaussFisherPeakShape self, double max_intensity, double radial_size, double kappa) -> GaussFisherPeakShape
+
+        GaussFisherPeakShape::GaussFisherPeakShape(double max_intensity, double radial_size, double kappa)
+
+        """
+        this = _libBornAgainCore.new_GaussFisherPeakShape(max_intensity, radial_size, kappa)
+        try:
+            self.this.append(this)
+        except __builtin__.Exception:
+            self.this = this
+    __swig_destroy__ = _libBornAgainCore.delete_GaussFisherPeakShape
     __del__ = lambda self: None
 
     def clone(self):
         """
-        clone(IPeakShape self) -> IPeakShape
+        clone(GaussFisherPeakShape self) -> GaussFisherPeakShape
 
-        virtual IPeakShape* IPeakShape::clone() const =0
+        GaussFisherPeakShape * GaussFisherPeakShape::clone() const override
 
         Returns a clone of this  ISample object. 
 
         """
-        return _libBornAgainCore.IPeakShape_clone(self)
+        return _libBornAgainCore.GaussFisherPeakShape_clone(self)
 
 
-    def evaluate(self, q):
+    def accept(self, visitor):
         """
-        evaluate(IPeakShape self, kvector_t q) -> double
+        accept(GaussFisherPeakShape self, INodeVisitor visitor)
 
-        virtual double IPeakShape::evaluate(const kvector_t q) const =0
+        void GaussFisherPeakShape::accept(INodeVisitor *visitor) const override
 
-        Evaluates the peak shape at displacement q from the center at 0. 
+        Calls the  INodeVisitor's visit method. 
 
         """
-        return _libBornAgainCore.IPeakShape_evaluate(self, q)
+        return _libBornAgainCore.GaussFisherPeakShape_accept(self, visitor)
 
 
-    def thickness_z(self):
+    def evaluate(self, q, q_lattice_point):
         """
-        thickness_z(IPeakShape self) -> double
+        evaluate(GaussFisherPeakShape self, kvector_t q, kvector_t q_lattice_point) -> double
 
-        virtual double IPeakShape::thickness_z() const =0
+        double GaussFisherPeakShape::evaluate(const kvector_t q, const kvector_t q_lattice_point) const override
 
-        Returns the thickness in the z-direction. 
+        Evaluates the peak shape at q from a reciprocal lattice point at q_lattice_point. 
 
         """
-        return _libBornAgainCore.IPeakShape_thickness_z(self)
+        return _libBornAgainCore.GaussFisherPeakShape_evaluate(self, q, q_lattice_point)
 
-IPeakShape_swigregister = _libBornAgainCore.IPeakShape_swigregister
-IPeakShape_swigregister(IPeakShape)
 
-class GaussPeakShape(IPeakShape):
+    def angularDisorder(self):
+        """
+        angularDisorder(GaussFisherPeakShape self) -> bool
+
+        bool GaussFisherPeakShape::angularDisorder() const override
+
+        Indicates if the peak shape encodes angular disorder, in which case all peaks in a spherical shell are needed 
+
+        """
+        return _libBornAgainCore.GaussFisherPeakShape_angularDisorder(self)
+
+GaussFisherPeakShape_swigregister = _libBornAgainCore.GaussFisherPeakShape_swigregister
+GaussFisherPeakShape_swigregister(GaussFisherPeakShape)
+
+class LorentzFisherPeakShape(IPeakShape):
     """
 
 
-    Class that implements a Gaussian peak shape of a Bragg peak.
+    Class that implements a peak shape that is Lorentzian in the radial direction and uses the von Mises-Fisher distribution in the angular direction.
 
     C++ includes: IPeakShape.h
 
@@ -21161,77 +19590,77 @@ class GaussPeakShape(IPeakShape):
     __swig_setmethods__ = {}
     for _s in [IPeakShape]:
         __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
-    __setattr__ = lambda self, name, value: _swig_setattr(self, GaussPeakShape, name, value)
+    __setattr__ = lambda self, name, value: _swig_setattr(self, LorentzFisherPeakShape, name, value)
     __swig_getmethods__ = {}
     for _s in [IPeakShape]:
         __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
-    __getattr__ = lambda self, name: _swig_getattr(self, GaussPeakShape, name)
+    __getattr__ = lambda self, name: _swig_getattr(self, LorentzFisherPeakShape, name)
     __repr__ = _swig_repr
 
-    def __init__(self, domainsize):
+    def __init__(self, max_intensity, radial_size, kappa):
         """
-        __init__(GaussPeakShape self, double domainsize) -> GaussPeakShape
+        __init__(LorentzFisherPeakShape self, double max_intensity, double radial_size, double kappa) -> LorentzFisherPeakShape
 
-        GaussPeakShape::GaussPeakShape(double domainsize)
+        LorentzFisherPeakShape::LorentzFisherPeakShape(double max_intensity, double radial_size, double kappa)
 
         """
-        this = _libBornAgainCore.new_GaussPeakShape(domainsize)
+        this = _libBornAgainCore.new_LorentzFisherPeakShape(max_intensity, radial_size, kappa)
         try:
             self.this.append(this)
         except __builtin__.Exception:
             self.this = this
-    __swig_destroy__ = _libBornAgainCore.delete_GaussPeakShape
+    __swig_destroy__ = _libBornAgainCore.delete_LorentzFisherPeakShape
     __del__ = lambda self: None
 
     def clone(self):
         """
-        clone(GaussPeakShape self) -> GaussPeakShape
+        clone(LorentzFisherPeakShape self) -> LorentzFisherPeakShape
 
-        GaussPeakShape * GaussPeakShape::clone() const override
+        LorentzFisherPeakShape * LorentzFisherPeakShape::clone() const override
 
         Returns a clone of this  ISample object. 
 
         """
-        return _libBornAgainCore.GaussPeakShape_clone(self)
+        return _libBornAgainCore.LorentzFisherPeakShape_clone(self)
 
 
     def accept(self, visitor):
         """
-        accept(GaussPeakShape self, INodeVisitor visitor)
+        accept(LorentzFisherPeakShape self, INodeVisitor visitor)
 
-        void GaussPeakShape::accept(INodeVisitor *visitor) const override
+        void LorentzFisherPeakShape::accept(INodeVisitor *visitor) const override
 
         Calls the  INodeVisitor's visit method. 
 
         """
-        return _libBornAgainCore.GaussPeakShape_accept(self, visitor)
+        return _libBornAgainCore.LorentzFisherPeakShape_accept(self, visitor)
 
 
-    def evaluate(self, q):
+    def evaluate(self, q, q_lattice_point):
         """
-        evaluate(GaussPeakShape self, kvector_t q) -> double
+        evaluate(LorentzFisherPeakShape self, kvector_t q, kvector_t q_lattice_point) -> double
 
-        double GaussPeakShape::evaluate(const kvector_t q) const override
+        double LorentzFisherPeakShape::evaluate(const kvector_t q, const kvector_t q_lattice_point) const override
 
-        Evaluates the peak shape at displacement q from the center at 0. 
+        Evaluates the peak shape at q from a reciprocal lattice point at q_lattice_point. 
 
         """
-        return _libBornAgainCore.GaussPeakShape_evaluate(self, q)
+        return _libBornAgainCore.LorentzFisherPeakShape_evaluate(self, q, q_lattice_point)
 
 
-    def thickness_z(self):
+    def angularDisorder(self):
         """
-        thickness_z(GaussPeakShape self) -> double
+        angularDisorder(LorentzFisherPeakShape self) -> bool
 
-        double GaussPeakShape::thickness_z() const override
+        bool LorentzFisherPeakShape::angularDisorder() const override
 
-        Returns the thickness in the z-direction. 
+        Indicates if the peak shape encodes angular disorder, in which case all peaks in a spherical shell are needed 
 
         """
-        return _libBornAgainCore.GaussPeakShape_thickness_z(self)
+        return _libBornAgainCore.LorentzFisherPeakShape_angularDisorder(self)
 
-GaussPeakShape_swigregister = _libBornAgainCore.GaussPeakShape_swigregister
-GaussPeakShape_swigregister(GaussPeakShape)
+LorentzFisherPeakShape_swigregister = _libBornAgainCore.LorentzFisherPeakShape_swigregister
+LorentzFisherPeakShape_swigregister(LorentzFisherPeakShape)
 
 class IResolutionFunction2D(ICloneable, INode):
     """
@@ -22353,7 +20782,9 @@ class IntensityDataIOFactory(_object):
     """
 
 
-    Provides users with possibility to read and write IntensityData from/to files in different format. Type of the file will be deduced from file name. *.txt - ASCII file with 2D array [nrow][ncol], layout as in numpy. *.int -  BornAgain internal ASCII format. *.tif - 32-bits tiff file. If file name ends woth "*.gz" or "*.bz2" the file will be zipped on the fly using appropriate algorithm. Usage:
+    Provides users with possibility to read and write IntensityData from/to files in different format. Type of the file will be deduced from file name. *.txt - ASCII file with 2D array [nrow][ncol], layout as in numpy. *.int -  BornAgain internal ASCII format. *.tif - 32-bits tiff file. If file name ends woth "*.gz" or "*.bz2" the file will be zipped on the fly using appropriate algorithm.
+
+    Usage:
 
     C++ includes: IntensityDataIOFactory.h
 
@@ -22401,7 +20832,9 @@ class IntensityDataIOFactory(_object):
 
 
 
-        Provides users with possibility to read and write IntensityData from/to files in different format. Type of the file will be deduced from file name. *.txt - ASCII file with 2D array [nrow][ncol], layout as in numpy. *.int -  BornAgain internal ASCII format. *.tif - 32-bits tiff file. If file name ends woth "*.gz" or "*.bz2" the file will be zipped on the fly using appropriate algorithm. Usage:
+        Provides users with possibility to read and write IntensityData from/to files in different format. Type of the file will be deduced from file name. *.txt - ASCII file with 2D array [nrow][ncol], layout as in numpy. *.int -  BornAgain internal ASCII format. *.tif - 32-bits tiff file. If file name ends woth "*.gz" or "*.bz2" the file will be zipped on the fly using appropriate algorithm.
+
+        Usage:
 
         C++ includes: IntensityDataIOFactory.h
 
@@ -22467,327 +20900,634 @@ class InterferenceFunction1DLattice(IInterferenceFunction):
         Parameters:
         -----------
 
-        length: 
-        lattice constant in nanometers
-
-        xi: 
-        rotation of lattice with respect to x-axis in radians 
+        length: 
+        lattice constant in nanometers
+
+        xi: 
+        rotation of lattice with respect to x-axis in radians 
+
+        """
+        this = _libBornAgainCore.new_InterferenceFunction1DLattice(length, xi)
+        try:
+            self.this.append(this)
+        except __builtin__.Exception:
+            self.this = this
+    __swig_destroy__ = _libBornAgainCore.delete_InterferenceFunction1DLattice
+    __del__ = lambda self: None
+
+    def clone(self):
+        """
+        clone(InterferenceFunction1DLattice self) -> InterferenceFunction1DLattice
+
+        InterferenceFunction1DLattice * InterferenceFunction1DLattice::clone() const final
+
+        Returns a clone of this  ISample object. 
+
+        """
+        return _libBornAgainCore.InterferenceFunction1DLattice_clone(self)
+
+
+    def accept(self, visitor):
+        """
+        accept(InterferenceFunction1DLattice self, INodeVisitor visitor)
+
+        void InterferenceFunction1DLattice::accept(INodeVisitor *visitor) const final
+
+        Calls the  INodeVisitor's visit method. 
+
+        """
+        return _libBornAgainCore.InterferenceFunction1DLattice_accept(self, visitor)
+
+
+    def setDecayFunction(self, decay):
+        """
+        setDecayFunction(InterferenceFunction1DLattice self, IFTDecayFunction1D decay)
+
+        void InterferenceFunction1DLattice::setDecayFunction(const IFTDecayFunction1D &decay)
+
+        Sets one-dimensional decay function.
+
+        Parameters:
+        -----------
+
+        decay: 
+        one-dimensional decay function in reciprocal space 
+
+        """
+        return _libBornAgainCore.InterferenceFunction1DLattice_setDecayFunction(self, decay)
+
+
+    def getLatticeParameters(self):
+        """
+        getLatticeParameters(InterferenceFunction1DLattice self) -> Lattice1DParameters
+
+        Lattice1DParameters InterferenceFunction1DLattice::getLatticeParameters() const
+
+        """
+        return _libBornAgainCore.InterferenceFunction1DLattice_getLatticeParameters(self)
+
+
+    def evaluate(self, q):
+        """
+        evaluate(InterferenceFunction1DLattice self, kvector_t q) -> double
+
+        double InterferenceFunction1DLattice::evaluate(const kvector_t q) const final
+
+        Evaluates the interference function for a given wavevector transfer (only the real x and y components are relevant) 
+
+        """
+        return _libBornAgainCore.InterferenceFunction1DLattice_evaluate(self, q)
+
+
+    def getChildren(self):
+        """
+        getChildren(InterferenceFunction1DLattice self) -> swig_dummy_type_const_inode_vector
+
+        std::vector< const INode * > InterferenceFunction1DLattice::getChildren() const override
+
+        Returns a vector of children (const). 
+
+        """
+        return _libBornAgainCore.InterferenceFunction1DLattice_getChildren(self)
+
+InterferenceFunction1DLattice_swigregister = _libBornAgainCore.InterferenceFunction1DLattice_swigregister
+InterferenceFunction1DLattice_swigregister(InterferenceFunction1DLattice)
+
+class InterferenceFunction2DLattice(IInterferenceFunction):
+    """
+
+
+    Interference function of 2D lattice.
+
+    C++ includes: InterferenceFunction2DLattice.h
+
+    """
+
+    __swig_setmethods__ = {}
+    for _s in [IInterferenceFunction]:
+        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
+    __setattr__ = lambda self, name, value: _swig_setattr(self, InterferenceFunction2DLattice, name, value)
+    __swig_getmethods__ = {}
+    for _s in [IInterferenceFunction]:
+        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
+    __getattr__ = lambda self, name: _swig_getattr(self, InterferenceFunction2DLattice, name)
+    __repr__ = _swig_repr
+
+    def __init__(self, *args):
+        """
+        __init__(InterferenceFunction2DLattice self, Lattice2D lattice) -> InterferenceFunction2DLattice
+        __init__(InterferenceFunction2DLattice self, double length_1, double length_2, double alpha, double xi=0.0) -> InterferenceFunction2DLattice
+        __init__(InterferenceFunction2DLattice self, double length_1, double length_2, double alpha) -> InterferenceFunction2DLattice
+
+        InterferenceFunction2DLattice::InterferenceFunction2DLattice(double length_1, double length_2, double alpha, double xi=0.0)
+
+        Constructor of two-dimensional interference function.
+
+        Parameters:
+        -----------
+
+        length_1: 
+        length of the first basis vector in nanometers
+
+        length_2: 
+        length of the second basis vector in nanometers
+
+        alpha: 
+        angle between the basis vectors in radians
+
+        xi: 
+        rotation of the lattice with respect to the x-axis (beam direction) in radians 
+
+        """
+        this = _libBornAgainCore.new_InterferenceFunction2DLattice(*args)
+        try:
+            self.this.append(this)
+        except __builtin__.Exception:
+            self.this = this
+    __swig_destroy__ = _libBornAgainCore.delete_InterferenceFunction2DLattice
+    __del__ = lambda self: None
+
+    def clone(self):
+        """
+        clone(InterferenceFunction2DLattice self) -> InterferenceFunction2DLattice
+
+        InterferenceFunction2DLattice * InterferenceFunction2DLattice::clone() const final
+
+        Returns a clone of this  ISample object. 
+
+        """
+        return _libBornAgainCore.InterferenceFunction2DLattice_clone(self)
+
+
+    def accept(self, visitor):
+        """
+        accept(InterferenceFunction2DLattice self, INodeVisitor visitor)
+
+        void InterferenceFunction2DLattice::accept(INodeVisitor *visitor) const final
+
+        Calls the  INodeVisitor's visit method. 
+
+        """
+        return _libBornAgainCore.InterferenceFunction2DLattice_accept(self, visitor)
+
+
+    def createSquare(lattice_length, xi=0.0):
+        """
+        createSquare(double lattice_length, double xi=0.0) -> InterferenceFunction2DLattice
+        createSquare(double lattice_length) -> InterferenceFunction2DLattice
+        """
+        return _libBornAgainCore.InterferenceFunction2DLattice_createSquare(lattice_length, xi)
+
+    createSquare = staticmethod(createSquare)
+
+    def createHexagonal(lattice_length, xi=0.0):
+        """
+        createHexagonal(double lattice_length, double xi=0.0) -> InterferenceFunction2DLattice
+        createHexagonal(double lattice_length) -> InterferenceFunction2DLattice
+        """
+        return _libBornAgainCore.InterferenceFunction2DLattice_createHexagonal(lattice_length, xi)
+
+    createHexagonal = staticmethod(createHexagonal)
+
+    def setDecayFunction(self, decay):
+        """
+        setDecayFunction(InterferenceFunction2DLattice self, IFTDecayFunction2D decay)
+
+        void InterferenceFunction2DLattice::setDecayFunction(const IFTDecayFunction2D &decay)
+
+        Sets two-dimensional decay function.
+
+        Parameters:
+        -----------
+
+        decay: 
+        two-dimensional decay function in reciprocal space 
 
         """
-        this = _libBornAgainCore.new_InterferenceFunction1DLattice(length, xi)
-        try:
-            self.this.append(this)
-        except __builtin__.Exception:
-            self.this = this
-    __swig_destroy__ = _libBornAgainCore.delete_InterferenceFunction1DLattice
-    __del__ = lambda self: None
+        return _libBornAgainCore.InterferenceFunction2DLattice_setDecayFunction(self, decay)
 
-    def clone(self):
+
+    def evaluate(self, q):
         """
-        clone(InterferenceFunction1DLattice self) -> InterferenceFunction1DLattice
+        evaluate(InterferenceFunction2DLattice self, kvector_t q) -> double
 
-        InterferenceFunction1DLattice * InterferenceFunction1DLattice::clone() const final
+        double InterferenceFunction2DLattice::evaluate(const kvector_t q) const final
 
-        Returns a clone of this  ISample object. 
+        Evaluates the interference function for a given wavevector transfer (only the real x and y components are relevant) 
 
         """
-        return _libBornAgainCore.InterferenceFunction1DLattice_clone(self)
+        return _libBornAgainCore.InterferenceFunction2DLattice_evaluate(self, q)
 
 
-    def accept(self, visitor):
+    def setIntegrationOverXi(self, integrate_xi):
         """
-        accept(InterferenceFunction1DLattice self, INodeVisitor visitor)
-
-        void InterferenceFunction1DLattice::accept(INodeVisitor *visitor) const final
+        setIntegrationOverXi(InterferenceFunction2DLattice self, bool integrate_xi)
 
-        Calls the  INodeVisitor's visit method. 
+        void InterferenceFunction2DLattice::setIntegrationOverXi(bool integrate_xi)
 
         """
-        return _libBornAgainCore.InterferenceFunction1DLattice_accept(self, visitor)
+        return _libBornAgainCore.InterferenceFunction2DLattice_setIntegrationOverXi(self, integrate_xi)
 
 
-    def setDecayFunction(self, decay):
+    def integrationOverXi(self):
         """
-        setDecayFunction(InterferenceFunction1DLattice self, IFTDecayFunction1D decay)
+        integrationOverXi(InterferenceFunction2DLattice self) -> bool
 
-        void InterferenceFunction1DLattice::setDecayFunction(const IFTDecayFunction1D &decay)
+        bool InterferenceFunction2DLattice::integrationOverXi() const
 
-        Sets one-dimensional decay function.
+        """
+        return _libBornAgainCore.InterferenceFunction2DLattice_integrationOverXi(self)
 
-        Parameters:
-        -----------
 
-        decay: 
-        one-dimensional decay function in reciprocal space 
+    def lattice(self):
+        """
+        lattice(InterferenceFunction2DLattice self) -> Lattice2D
+
+        const Lattice2D & InterferenceFunction2DLattice::lattice() const
 
         """
-        return _libBornAgainCore.InterferenceFunction1DLattice_setDecayFunction(self, decay)
+        return _libBornAgainCore.InterferenceFunction2DLattice_lattice(self)
 
 
-    def getLatticeParameters(self):
+    def getParticleDensity(self):
         """
-        getLatticeParameters(InterferenceFunction1DLattice self) -> Lattice1DParameters
+        getParticleDensity(InterferenceFunction2DLattice self) -> double
 
-        Lattice1DParameters InterferenceFunction1DLattice::getLatticeParameters() const
+        double InterferenceFunction2DLattice::getParticleDensity() const final
+
+        Returns the particle density associated with this 2d lattice. 
 
         """
-        return _libBornAgainCore.InterferenceFunction1DLattice_getLatticeParameters(self)
+        return _libBornAgainCore.InterferenceFunction2DLattice_getParticleDensity(self)
 
 
-    def evaluate(self, q):
+    def getChildren(self):
         """
-        evaluate(InterferenceFunction1DLattice self, kvector_t q) -> double
+        getChildren(InterferenceFunction2DLattice self) -> swig_dummy_type_const_inode_vector
 
-        double InterferenceFunction1DLattice::evaluate(const kvector_t q) const final
+        std::vector< const INode * > InterferenceFunction2DLattice::getChildren() const override
 
-        Evaluates the interference function for a given wavevector transfer (only the real x and y components are relevant) 
+        Returns a vector of children (const). 
 
         """
-        return _libBornAgainCore.InterferenceFunction1DLattice_evaluate(self, q)
+        return _libBornAgainCore.InterferenceFunction2DLattice_getChildren(self)
 
 
-    def getChildren(self):
+    def onChange(self):
         """
-        getChildren(InterferenceFunction1DLattice self) -> swig_dummy_type_const_inode_vector
+        onChange(InterferenceFunction2DLattice self)
 
-        std::vector< const INode * > InterferenceFunction1DLattice::getChildren() const override
+        void InterferenceFunction2DLattice::onChange() override final
 
-        Returns a vector of children (const). 
+        Action to be taken in inherited class when a parameter has changed. 
 
         """
-        return _libBornAgainCore.InterferenceFunction1DLattice_getChildren(self)
+        return _libBornAgainCore.InterferenceFunction2DLattice_onChange(self)
 
-InterferenceFunction1DLattice_swigregister = _libBornAgainCore.InterferenceFunction1DLattice_swigregister
-InterferenceFunction1DLattice_swigregister(InterferenceFunction1DLattice)
+InterferenceFunction2DLattice_swigregister = _libBornAgainCore.InterferenceFunction2DLattice_swigregister
+InterferenceFunction2DLattice_swigregister(InterferenceFunction2DLattice)
 
-class InterferenceFunctionRadialParaCrystal(IInterferenceFunction):
+def InterferenceFunction2DLattice_createSquare(lattice_length, xi=0.0):
+    """
+    createSquare(double lattice_length, double xi=0.0) -> InterferenceFunction2DLattice
+    InterferenceFunction2DLattice_createSquare(double lattice_length) -> InterferenceFunction2DLattice
     """
+    return _libBornAgainCore.InterferenceFunction2DLattice_createSquare(lattice_length, xi)
 
+def InterferenceFunction2DLattice_createHexagonal(lattice_length, xi=0.0):
+    """
+    createHexagonal(double lattice_length, double xi=0.0) -> InterferenceFunction2DLattice
+    InterferenceFunction2DLattice_createHexagonal(double lattice_length) -> InterferenceFunction2DLattice
+    """
+    return _libBornAgainCore.InterferenceFunction2DLattice_createHexagonal(lattice_length, xi)
 
-    Interference function of radial paracrystal.
+class InterferenceFunction2DParaCrystal(IInterferenceFunction):
+    """
 
-    C++ includes: InterferenceFunctionRadialParaCrystal.h
+
+    Interference function of 2D paracrystal.
+
+    C++ includes: InterferenceFunction2DParaCrystal.h
 
     """
 
     __swig_setmethods__ = {}
     for _s in [IInterferenceFunction]:
         __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
-    __setattr__ = lambda self, name, value: _swig_setattr(self, InterferenceFunctionRadialParaCrystal, name, value)
+    __setattr__ = lambda self, name, value: _swig_setattr(self, InterferenceFunction2DParaCrystal, name, value)
     __swig_getmethods__ = {}
     for _s in [IInterferenceFunction]:
         __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
-    __getattr__ = lambda self, name: _swig_getattr(self, InterferenceFunctionRadialParaCrystal, name)
+    __getattr__ = lambda self, name: _swig_getattr(self, InterferenceFunction2DParaCrystal, name)
     __repr__ = _swig_repr
 
-    def __init__(self, peak_distance, damping_length=0.0):
+    def __init__(self, *args):
         """
-        __init__(InterferenceFunctionRadialParaCrystal self, double peak_distance, double damping_length=0.0) -> InterferenceFunctionRadialParaCrystal
-        __init__(InterferenceFunctionRadialParaCrystal self, double peak_distance) -> InterferenceFunctionRadialParaCrystal
+        __init__(InterferenceFunction2DParaCrystal self, Lattice2D lattice, double damping_length=0.0, double domain_size_1=0.0, double domain_size_2=0.0) -> InterferenceFunction2DParaCrystal
+        __init__(InterferenceFunction2DParaCrystal self, Lattice2D lattice, double damping_length=0.0, double domain_size_1=0.0) -> InterferenceFunction2DParaCrystal
+        __init__(InterferenceFunction2DParaCrystal self, Lattice2D lattice, double damping_length=0.0) -> InterferenceFunction2DParaCrystal
+        __init__(InterferenceFunction2DParaCrystal self, Lattice2D lattice) -> InterferenceFunction2DParaCrystal
+        __init__(InterferenceFunction2DParaCrystal self, double length_1, double length_2, double alpha, double xi=0.0, double damping_length=0.0) -> InterferenceFunction2DParaCrystal
+        __init__(InterferenceFunction2DParaCrystal self, double length_1, double length_2, double alpha, double xi=0.0) -> InterferenceFunction2DParaCrystal
+        __init__(InterferenceFunction2DParaCrystal self, double length_1, double length_2, double alpha) -> InterferenceFunction2DParaCrystal
 
-        InterferenceFunctionRadialParaCrystal::InterferenceFunctionRadialParaCrystal(double peak_distance, double damping_length=0.0)
+        InterferenceFunction2DParaCrystal::InterferenceFunction2DParaCrystal(double length_1, double length_2, double alpha, double xi=0.0, double damping_length=0.0)
 
-        Constructor of interference function of radial paracrystal.
+        Constructor of interference function of two-dimensional paracrystal.
 
         Parameters:
         -----------
 
-        peak_distance: 
-        average distance to the next neighbor in nanometers
+        length_1: 
+        length of first lattice vector in nanometers
+
+        length_2: 
+        length of second lattice vector in nanometers
+
+        alpha: 
+        angle between lattice vectors in radians
+
+        xi: 
+        rotation of lattice with respect to x-axis (beam direction) in radians
 
         damping_length: 
         the damping (coherence) length of the paracrystal in nanometers 
 
         """
-        this = _libBornAgainCore.new_InterferenceFunctionRadialParaCrystal(peak_distance, damping_length)
+        this = _libBornAgainCore.new_InterferenceFunction2DParaCrystal(*args)
         try:
             self.this.append(this)
         except __builtin__.Exception:
             self.this = this
+    __swig_destroy__ = _libBornAgainCore.delete_InterferenceFunction2DParaCrystal
+    __del__ = lambda self: None
 
     def clone(self):
         """
-        clone(InterferenceFunctionRadialParaCrystal self) -> InterferenceFunctionRadialParaCrystal
+        clone(InterferenceFunction2DParaCrystal self) -> InterferenceFunction2DParaCrystal
 
-        InterferenceFunctionRadialParaCrystal * InterferenceFunctionRadialParaCrystal::clone() const final
+        InterferenceFunction2DParaCrystal * InterferenceFunction2DParaCrystal::clone() const final
 
         Returns a clone of this  ISample object. 
 
         """
-        return _libBornAgainCore.InterferenceFunctionRadialParaCrystal_clone(self)
+        return _libBornAgainCore.InterferenceFunction2DParaCrystal_clone(self)
 
 
     def accept(self, visitor):
         """
-        accept(InterferenceFunctionRadialParaCrystal self, INodeVisitor visitor)
+        accept(InterferenceFunction2DParaCrystal self, INodeVisitor visitor)
 
-        void InterferenceFunctionRadialParaCrystal::accept(INodeVisitor *visitor) const final
+        void InterferenceFunction2DParaCrystal::accept(INodeVisitor *visitor) const final
 
         Calls the  INodeVisitor's visit method. 
 
         """
-        return _libBornAgainCore.InterferenceFunctionRadialParaCrystal_accept(self, visitor)
+        return _libBornAgainCore.InterferenceFunction2DParaCrystal_accept(self, visitor)
 
 
-    def setKappa(self, kappa):
+    def createSquare(lattice_length, damping_length=0.0, domain_size_1=0.0, domain_size_2=0.0):
         """
-        setKappa(InterferenceFunctionRadialParaCrystal self, double kappa)
+        createSquare(double lattice_length, double damping_length=0.0, double domain_size_1=0.0, double domain_size_2=0.0) -> InterferenceFunction2DParaCrystal
+        createSquare(double lattice_length, double damping_length=0.0, double domain_size_1=0.0) -> InterferenceFunction2DParaCrystal
+        createSquare(double lattice_length, double damping_length=0.0) -> InterferenceFunction2DParaCrystal
+        createSquare(double lattice_length) -> InterferenceFunction2DParaCrystal
+        """
+        return _libBornAgainCore.InterferenceFunction2DParaCrystal_createSquare(lattice_length, damping_length, domain_size_1, domain_size_2)
 
-        void InterferenceFunctionRadialParaCrystal::setKappa(double kappa)
+    createSquare = staticmethod(createSquare)
 
-        Sets size spacing coupling parameter of the Size Spacing Correlation Approximation.
+    def createHexagonal(lattice_length, damping_length=0.0, domain_size_1=0.0, domain_size_2=0.0):
+        """
+        createHexagonal(double lattice_length, double damping_length=0.0, double domain_size_1=0.0, double domain_size_2=0.0) -> InterferenceFunction2DParaCrystal
+        createHexagonal(double lattice_length, double damping_length=0.0, double domain_size_1=0.0) -> InterferenceFunction2DParaCrystal
+        createHexagonal(double lattice_length, double damping_length=0.0) -> InterferenceFunction2DParaCrystal
+        createHexagonal(double lattice_length) -> InterferenceFunction2DParaCrystal
+        """
+        return _libBornAgainCore.InterferenceFunction2DParaCrystal_createHexagonal(lattice_length, damping_length, domain_size_1, domain_size_2)
+
+    createHexagonal = staticmethod(createHexagonal)
+
+    def setDomainSizes(self, size_1, size_2):
+        """
+        setDomainSizes(InterferenceFunction2DParaCrystal self, double size_1, double size_2)
+
+        void InterferenceFunction2DParaCrystal::setDomainSizes(double size_1, double size_2)
+
+        Sets the sizes of coherence domains.
 
         Parameters:
         -----------
 
-        size: 
-        spacing coupling parameter 
+        size_1: 
+        coherence domain size along the first basis vector in nanometers
+
+        size_2: 
+        coherence domain size along the second basis vector in nanometers 
 
         """
-        return _libBornAgainCore.InterferenceFunctionRadialParaCrystal_setKappa(self, kappa)
+        return _libBornAgainCore.InterferenceFunction2DParaCrystal_setDomainSizes(self, size_1, size_2)
 
 
-    def kappa(self):
+    def setProbabilityDistributions(self, pdf_1, pdf_2):
         """
-        kappa(InterferenceFunctionRadialParaCrystal self) -> double
+        setProbabilityDistributions(InterferenceFunction2DParaCrystal self, IFTDistribution2D pdf_1, IFTDistribution2D pdf_2)
 
-        double InterferenceFunctionRadialParaCrystal::kappa() const
+        void InterferenceFunction2DParaCrystal::setProbabilityDistributions(const IFTDistribution2D &pdf_1, const IFTDistribution2D &pdf_2)
+
+        Sets the probability distributions (Fourier transformed) for the two lattice directions.
+
+        Parameters:
+        -----------
+
+        pdf_1: 
+        probability distribution in first lattice direction
+
+        pdf_2: 
+        probability distribution in second lattice direction 
 
         """
-        return _libBornAgainCore.InterferenceFunctionRadialParaCrystal_kappa(self)
+        return _libBornAgainCore.InterferenceFunction2DParaCrystal_setProbabilityDistributions(self, pdf_1, pdf_2)
+
+
+    def setDampingLength(self, damping_length):
+        """
+        setDampingLength(InterferenceFunction2DParaCrystal self, double damping_length)
+
+        void InterferenceFunction2DParaCrystal::setDampingLength(double damping_length)
+
+        Sets the damping length.
+
+        Parameters:
+        -----------
+
+        damping_length: 
+        the damping (coherence) length of the paracrystal in nanometers 
+
+        """
+        return _libBornAgainCore.InterferenceFunction2DParaCrystal_setDampingLength(self, damping_length)
+
+
+    def evaluate(self, q):
+        """
+        evaluate(InterferenceFunction2DParaCrystal self, kvector_t q) -> double
+
+        double InterferenceFunction2DParaCrystal::evaluate(const kvector_t q) const final
+
+        Evaluates the interference function for a given wavevector transfer (only the real x and y components are relevant) 
+
+        """
+        return _libBornAgainCore.InterferenceFunction2DParaCrystal_evaluate(self, q)
+
+
+    def domainSizes(self):
+        """
+        domainSizes(InterferenceFunction2DParaCrystal self) -> vdouble1d_t
+
+        std::vector< double > InterferenceFunction2DParaCrystal::domainSizes() const
+
+        """
+        return _libBornAgainCore.InterferenceFunction2DParaCrystal_domainSizes(self)
 
 
-    def setDomainSize(self, size):
+    def setIntegrationOverXi(self, integrate_xi):
         """
-        setDomainSize(InterferenceFunctionRadialParaCrystal self, double size)
+        setIntegrationOverXi(InterferenceFunction2DParaCrystal self, bool integrate_xi)
 
-        void InterferenceFunctionRadialParaCrystal::setDomainSize(double size)
+        void InterferenceFunction2DParaCrystal::setIntegrationOverXi(bool integrate_xi)
 
-        Sets domain size (finite size corrections).
+        Enables/disables averaging over the lattice rotation angle.
 
         Parameters:
         -----------
 
-        size: 
-        size of coherence domain along the lattice main axis in nanometers 
+        integrate_xi: 
+        integration flag 
 
         """
-        return _libBornAgainCore.InterferenceFunctionRadialParaCrystal_setDomainSize(self, size)
+        return _libBornAgainCore.InterferenceFunction2DParaCrystal_setIntegrationOverXi(self, integrate_xi)
 
 
-    def domainSize(self):
+    def integrationOverXi(self):
         """
-        domainSize(InterferenceFunctionRadialParaCrystal self) -> double
+        integrationOverXi(InterferenceFunction2DParaCrystal self) -> bool
 
-        double InterferenceFunctionRadialParaCrystal::domainSize() const
+        bool InterferenceFunction2DParaCrystal::integrationOverXi() const
 
         """
-        return _libBornAgainCore.InterferenceFunctionRadialParaCrystal_domainSize(self)
+        return _libBornAgainCore.InterferenceFunction2DParaCrystal_integrationOverXi(self)
 
 
-    def evaluate(self, q):
+    def dampingLength(self):
         """
-        evaluate(InterferenceFunctionRadialParaCrystal self, kvector_t q) -> double
-
-        double InterferenceFunctionRadialParaCrystal::evaluate(const kvector_t q) const final
+        dampingLength(InterferenceFunction2DParaCrystal self) -> double
 
-        Evaluates the interference function for a given wavevector transfer (only the real x and y components are relevant) 
+        double InterferenceFunction2DParaCrystal::dampingLength() const
 
         """
-        return _libBornAgainCore.InterferenceFunctionRadialParaCrystal_evaluate(self, q)
+        return _libBornAgainCore.InterferenceFunction2DParaCrystal_dampingLength(self)
 
 
-    def FTPDF(self, qpar):
+    def lattice(self):
         """
-        FTPDF(InterferenceFunctionRadialParaCrystal self, double qpar) -> complex_t
+        lattice(InterferenceFunction2DParaCrystal self) -> Lattice2D
 
-        complex_t InterferenceFunctionRadialParaCrystal::FTPDF(double qpar) const
+        const Lattice2D & InterferenceFunction2DParaCrystal::lattice() const
 
         """
-        return _libBornAgainCore.InterferenceFunctionRadialParaCrystal_FTPDF(self, qpar)
+        return _libBornAgainCore.InterferenceFunction2DParaCrystal_lattice(self)
 
 
-    def setProbabilityDistribution(self, pdf):
+    def getParticleDensity(self):
         """
-        setProbabilityDistribution(InterferenceFunctionRadialParaCrystal self, IFTDistribution1D pdf)
+        getParticleDensity(InterferenceFunction2DParaCrystal self) -> double
 
-        void InterferenceFunctionRadialParaCrystal::setProbabilityDistribution(const IFTDistribution1D &pdf)
+        double InterferenceFunction2DParaCrystal::getParticleDensity() const final
 
-        Sets one-dimensional probability distribution.
+        If defined by this interference function's parameters, returns the particle density (per area). Otherwise, returns zero or a user-defined value 
 
-        Parameters:
-        -----------
+        """
+        return _libBornAgainCore.InterferenceFunction2DParaCrystal_getParticleDensity(self)
 
-        pdf: 
-        probability distribution (Fourier transform of probability density) 
 
+    def getChildren(self):
         """
-        return _libBornAgainCore.InterferenceFunctionRadialParaCrystal_setProbabilityDistribution(self, pdf)
+        getChildren(InterferenceFunction2DParaCrystal self) -> swig_dummy_type_const_inode_vector
 
+        std::vector< const INode * > InterferenceFunction2DParaCrystal::getChildren() const
+
+        Returns a vector of children (const). 
 
-    def peakDistance(self):
         """
-        peakDistance(InterferenceFunctionRadialParaCrystal self) -> double
+        return _libBornAgainCore.InterferenceFunction2DParaCrystal_getChildren(self)
 
-        double InterferenceFunctionRadialParaCrystal::peakDistance() const
 
+    def pdf1(self):
         """
-        return _libBornAgainCore.InterferenceFunctionRadialParaCrystal_peakDistance(self)
+        pdf1(InterferenceFunction2DParaCrystal self) -> IFTDistribution2D
 
+        const IFTDistribution2D* InterferenceFunction2DParaCrystal::pdf1() const
 
-    def dampingLength(self):
         """
-        dampingLength(InterferenceFunctionRadialParaCrystal self) -> double
+        return _libBornAgainCore.InterferenceFunction2DParaCrystal_pdf1(self)
 
-        double InterferenceFunctionRadialParaCrystal::dampingLength() const
 
+    def pdf2(self):
         """
-        return _libBornAgainCore.InterferenceFunctionRadialParaCrystal_dampingLength(self)
+        pdf2(InterferenceFunction2DParaCrystal self) -> IFTDistribution2D
 
+        const IFTDistribution2D* InterferenceFunction2DParaCrystal::pdf2() const
 
-    def getChildren(self):
         """
-        getChildren(InterferenceFunctionRadialParaCrystal self) -> swig_dummy_type_const_inode_vector
+        return _libBornAgainCore.InterferenceFunction2DParaCrystal_pdf2(self)
 
-        std::vector< const INode * > InterferenceFunctionRadialParaCrystal::getChildren() const override
-
-        Returns a vector of children (const). 
+InterferenceFunction2DParaCrystal_swigregister = _libBornAgainCore.InterferenceFunction2DParaCrystal_swigregister
+InterferenceFunction2DParaCrystal_swigregister(InterferenceFunction2DParaCrystal)
 
-        """
-        return _libBornAgainCore.InterferenceFunctionRadialParaCrystal_getChildren(self)
+def InterferenceFunction2DParaCrystal_createSquare(lattice_length, damping_length=0.0, domain_size_1=0.0, domain_size_2=0.0):
+    """
+    createSquare(double lattice_length, double damping_length=0.0, double domain_size_1=0.0, double domain_size_2=0.0) -> InterferenceFunction2DParaCrystal
+    createSquare(double lattice_length, double damping_length=0.0, double domain_size_1=0.0) -> InterferenceFunction2DParaCrystal
+    createSquare(double lattice_length, double damping_length=0.0) -> InterferenceFunction2DParaCrystal
+    InterferenceFunction2DParaCrystal_createSquare(double lattice_length) -> InterferenceFunction2DParaCrystal
+    """
+    return _libBornAgainCore.InterferenceFunction2DParaCrystal_createSquare(lattice_length, damping_length, domain_size_1, domain_size_2)
 
-    __swig_destroy__ = _libBornAgainCore.delete_InterferenceFunctionRadialParaCrystal
-    __del__ = lambda self: None
-InterferenceFunctionRadialParaCrystal_swigregister = _libBornAgainCore.InterferenceFunctionRadialParaCrystal_swigregister
-InterferenceFunctionRadialParaCrystal_swigregister(InterferenceFunctionRadialParaCrystal)
+def InterferenceFunction2DParaCrystal_createHexagonal(lattice_length, damping_length=0.0, domain_size_1=0.0, domain_size_2=0.0):
+    """
+    createHexagonal(double lattice_length, double damping_length=0.0, double domain_size_1=0.0, double domain_size_2=0.0) -> InterferenceFunction2DParaCrystal
+    createHexagonal(double lattice_length, double damping_length=0.0, double domain_size_1=0.0) -> InterferenceFunction2DParaCrystal
+    createHexagonal(double lattice_length, double damping_length=0.0) -> InterferenceFunction2DParaCrystal
+    InterferenceFunction2DParaCrystal_createHexagonal(double lattice_length) -> InterferenceFunction2DParaCrystal
+    """
+    return _libBornAgainCore.InterferenceFunction2DParaCrystal_createHexagonal(lattice_length, damping_length, domain_size_1, domain_size_2)
 
-class InterferenceFunction2DLattice(IInterferenceFunction):
+class InterferenceFunction2DSuperLattice(IInterferenceFunction):
     """
 
 
-    Interference function of 2D lattice.
+    Interference function of 2D superlattice with a configurable interference function for each lattice site.
 
-    C++ includes: InterferenceFunction2DLattice.h
+    C++ includes: InterferenceFunction2DSuperLattice.h
 
     """
 
     __swig_setmethods__ = {}
     for _s in [IInterferenceFunction]:
         __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
-    __setattr__ = lambda self, name, value: _swig_setattr(self, InterferenceFunction2DLattice, name, value)
+    __setattr__ = lambda self, name, value: _swig_setattr(self, InterferenceFunction2DSuperLattice, name, value)
     __swig_getmethods__ = {}
     for _s in [IInterferenceFunction]:
         __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
-    __getattr__ = lambda self, name: _swig_getattr(self, InterferenceFunction2DLattice, name)
+    __getattr__ = lambda self, name: _swig_getattr(self, InterferenceFunction2DSuperLattice, name)
     __repr__ = _swig_repr
 
     def __init__(self, *args):
         """
-        __init__(InterferenceFunction2DLattice self, Lattice2D lattice) -> InterferenceFunction2DLattice
-        __init__(InterferenceFunction2DLattice self, double length_1, double length_2, double alpha, double xi=0.0) -> InterferenceFunction2DLattice
-        __init__(InterferenceFunction2DLattice self, double length_1, double length_2, double alpha) -> InterferenceFunction2DLattice
+        __init__(InterferenceFunction2DSuperLattice self, Lattice2D lattice, unsigned int size_1, unsigned int size_2) -> InterferenceFunction2DSuperLattice
+        __init__(InterferenceFunction2DSuperLattice self, double length_1, double length_2, double alpha, double xi, unsigned int size_1, unsigned int size_2) -> InterferenceFunction2DSuperLattice
 
-        InterferenceFunction2DLattice::InterferenceFunction2DLattice(double length_1, double length_2, double alpha, double xi=0.0)
+        InterferenceFunction2DSuperLattice::InterferenceFunction2DSuperLattice(double length_1, double length_2, double alpha, double xi, unsigned size_1, unsigned size_2)
 
         Constructor of two-dimensional interference function.
 
@@ -22795,179 +21535,185 @@ class InterferenceFunction2DLattice(IInterferenceFunction):
         -----------
 
         length_1: 
-        length of the first basis vector in nanometers
+        length of first lattice vector in nanometers
 
         length_2: 
-        length of the second basis vector in nanometers
+        length of second lattice vector in nanometers
 
         alpha: 
-        angle between the basis vectors in radians
+        angle between lattice vectors in radians
 
         xi: 
-        rotation of the lattice with respect to the x-axis (beam direction) in radians 
+        rotation of lattice with respect to x-axis (beam direction) in radians 
 
         """
-        this = _libBornAgainCore.new_InterferenceFunction2DLattice(*args)
+        this = _libBornAgainCore.new_InterferenceFunction2DSuperLattice(*args)
         try:
             self.this.append(this)
         except __builtin__.Exception:
             self.this = this
-    __swig_destroy__ = _libBornAgainCore.delete_InterferenceFunction2DLattice
+    __swig_destroy__ = _libBornAgainCore.delete_InterferenceFunction2DSuperLattice
     __del__ = lambda self: None
 
     def clone(self):
         """
-        clone(InterferenceFunction2DLattice self) -> InterferenceFunction2DLattice
+        clone(InterferenceFunction2DSuperLattice self) -> InterferenceFunction2DSuperLattice
 
-        InterferenceFunction2DLattice * InterferenceFunction2DLattice::clone() const final
+        InterferenceFunction2DSuperLattice * InterferenceFunction2DSuperLattice::clone() const final
 
         Returns a clone of this  ISample object. 
 
         """
-        return _libBornAgainCore.InterferenceFunction2DLattice_clone(self)
+        return _libBornAgainCore.InterferenceFunction2DSuperLattice_clone(self)
 
 
     def accept(self, visitor):
         """
-        accept(InterferenceFunction2DLattice self, INodeVisitor visitor)
+        accept(InterferenceFunction2DSuperLattice self, INodeVisitor visitor)
 
-        void InterferenceFunction2DLattice::accept(INodeVisitor *visitor) const final
+        void InterferenceFunction2DSuperLattice::accept(INodeVisitor *visitor) const final
 
         Calls the  INodeVisitor's visit method. 
 
         """
-        return _libBornAgainCore.InterferenceFunction2DLattice_accept(self, visitor)
+        return _libBornAgainCore.InterferenceFunction2DSuperLattice_accept(self, visitor)
 
 
-    def createSquare(lattice_length, xi=0.0):
-        """
-        createSquare(double lattice_length, double xi=0.0) -> InterferenceFunction2DLattice
-        createSquare(double lattice_length) -> InterferenceFunction2DLattice
+    def setSubstructureIFF(self, sub_iff):
         """
-        return _libBornAgainCore.InterferenceFunction2DLattice_createSquare(lattice_length, xi)
+        setSubstructureIFF(InterferenceFunction2DSuperLattice self, IInterferenceFunction sub_iff)
 
-    createSquare = staticmethod(createSquare)
+        void InterferenceFunction2DSuperLattice::setSubstructureIFF(const IInterferenceFunction &sub_iff)
 
-    def createHexagonal(lattice_length, xi=0.0):
-        """
-        createHexagonal(double lattice_length, double xi=0.0) -> InterferenceFunction2DLattice
-        createHexagonal(double lattice_length) -> InterferenceFunction2DLattice
         """
-        return _libBornAgainCore.InterferenceFunction2DLattice_createHexagonal(lattice_length, xi)
+        return _libBornAgainCore.InterferenceFunction2DSuperLattice_setSubstructureIFF(self, sub_iff)
 
-    createHexagonal = staticmethod(createHexagonal)
 
-    def setDecayFunction(self, decay):
+    def substructureIFF(self):
         """
-        setDecayFunction(InterferenceFunction2DLattice self, IFTDecayFunction2D decay)
+        substructureIFF(InterferenceFunction2DSuperLattice self) -> IInterferenceFunction
 
-        void InterferenceFunction2DLattice::setDecayFunction(const IFTDecayFunction2D &decay)
+        const IInterferenceFunction & InterferenceFunction2DSuperLattice::substructureIFF() const
 
-        Sets two-dimensional decay function.
+        """
+        return _libBornAgainCore.InterferenceFunction2DSuperLattice_substructureIFF(self)
 
-        Parameters:
-        -----------
 
-        decay: 
-        two-dimensional decay function in reciprocal space 
+    def createSquare(lattice_length, xi, size_1, size_2):
+        """createSquare(double lattice_length, double xi, unsigned int size_1, unsigned int size_2) -> InterferenceFunction2DSuperLattice"""
+        return _libBornAgainCore.InterferenceFunction2DSuperLattice_createSquare(lattice_length, xi, size_1, size_2)
 
-        """
-        return _libBornAgainCore.InterferenceFunction2DLattice_setDecayFunction(self, decay)
+    createSquare = staticmethod(createSquare)
+
+    def createHexagonal(lattice_length, xi, size_1, size_2):
+        """createHexagonal(double lattice_length, double xi, unsigned int size_1, unsigned int size_2) -> InterferenceFunction2DSuperLattice"""
+        return _libBornAgainCore.InterferenceFunction2DSuperLattice_createHexagonal(lattice_length, xi, size_1, size_2)
 
+    createHexagonal = staticmethod(createHexagonal)
 
     def evaluate(self, q):
         """
-        evaluate(InterferenceFunction2DLattice self, kvector_t q) -> double
+        evaluate(InterferenceFunction2DSuperLattice self, kvector_t q) -> double
 
-        double InterferenceFunction2DLattice::evaluate(const kvector_t q) const final
+        double InterferenceFunction2DSuperLattice::evaluate(const kvector_t q) const final
 
         Evaluates the interference function for a given wavevector transfer (only the real x and y components are relevant) 
 
         """
-        return _libBornAgainCore.InterferenceFunction2DLattice_evaluate(self, q)
+        return _libBornAgainCore.InterferenceFunction2DSuperLattice_evaluate(self, q)
 
 
-    def setIntegrationOverXi(self, integrate_xi):
+    def domainSize1(self):
         """
-        setIntegrationOverXi(InterferenceFunction2DLattice self, bool integrate_xi)
+        domainSize1(InterferenceFunction2DSuperLattice self) -> unsigned int
 
-        void InterferenceFunction2DLattice::setIntegrationOverXi(bool integrate_xi)
+        unsigned InterferenceFunction2DSuperLattice::domainSize1() const
 
         """
-        return _libBornAgainCore.InterferenceFunction2DLattice_setIntegrationOverXi(self, integrate_xi)
+        return _libBornAgainCore.InterferenceFunction2DSuperLattice_domainSize1(self)
 
 
-    def integrationOverXi(self):
+    def domainSize2(self):
         """
-        integrationOverXi(InterferenceFunction2DLattice self) -> bool
+        domainSize2(InterferenceFunction2DSuperLattice self) -> unsigned int
 
-        bool InterferenceFunction2DLattice::integrationOverXi() const
+        unsigned InterferenceFunction2DSuperLattice::domainSize2() const
 
         """
-        return _libBornAgainCore.InterferenceFunction2DLattice_integrationOverXi(self)
+        return _libBornAgainCore.InterferenceFunction2DSuperLattice_domainSize2(self)
 
 
-    def lattice(self):
+    def setPositionVariance(self, sigma2):
         """
-        lattice(InterferenceFunction2DLattice self) -> Lattice2D
+        setPositionVariance(InterferenceFunction2DSuperLattice self, double sigma2)
 
-        const Lattice2D & InterferenceFunction2DLattice::lattice() const
+        void InterferenceFunction2DSuperLattice::setPositionVariance(double sigma2)
 
         """
-        return _libBornAgainCore.InterferenceFunction2DLattice_lattice(self)
+        return _libBornAgainCore.InterferenceFunction2DSuperLattice_setPositionVariance(self, sigma2)
 
 
-    def getParticleDensity(self):
+    def positionVariance(self):
         """
-        getParticleDensity(InterferenceFunction2DLattice self) -> double
+        positionVariance(InterferenceFunction2DSuperLattice self) -> double
 
-        double InterferenceFunction2DLattice::getParticleDensity() const final
+        double InterferenceFunction2DSuperLattice::positionVariance() const
+
+        """
+        return _libBornAgainCore.InterferenceFunction2DSuperLattice_positionVariance(self)
 
-        Returns the particle density associated with this 2d lattice. 
 
+    def setIntegrationOverXi(self, integrate_xi):
         """
-        return _libBornAgainCore.InterferenceFunction2DLattice_getParticleDensity(self)
+        setIntegrationOverXi(InterferenceFunction2DSuperLattice self, bool integrate_xi)
+
+        void InterferenceFunction2DSuperLattice::setIntegrationOverXi(bool integrate_xi)
 
+        """
+        return _libBornAgainCore.InterferenceFunction2DSuperLattice_setIntegrationOverXi(self, integrate_xi)
 
-    def getChildren(self):
+
+    def integrationOverXi(self):
         """
-        getChildren(InterferenceFunction2DLattice self) -> swig_dummy_type_const_inode_vector
+        integrationOverXi(InterferenceFunction2DSuperLattice self) -> bool
 
-        std::vector< const INode * > InterferenceFunction2DLattice::getChildren() const override
+        bool InterferenceFunction2DSuperLattice::integrationOverXi() const
+
+        """
+        return _libBornAgainCore.InterferenceFunction2DSuperLattice_integrationOverXi(self)
 
-        Returns a vector of children (const). 
 
+    def lattice(self):
         """
-        return _libBornAgainCore.InterferenceFunction2DLattice_getChildren(self)
+        lattice(InterferenceFunction2DSuperLattice self) -> Lattice2D
 
+        const Lattice2D & InterferenceFunction2DSuperLattice::lattice() const
 
-    def onChange(self):
         """
-        onChange(InterferenceFunction2DLattice self)
+        return _libBornAgainCore.InterferenceFunction2DSuperLattice_lattice(self)
 
-        void InterferenceFunction2DLattice::onChange() override final
 
-        Action to be taken in inherited class when a parameter has changed. 
+    def getChildren(self):
+        """
+        getChildren(InterferenceFunction2DSuperLattice self) -> swig_dummy_type_const_inode_vector
+
+        std::vector< const INode * > InterferenceFunction2DSuperLattice::getChildren() const override
+
+        Returns a vector of children (const). 
 
         """
-        return _libBornAgainCore.InterferenceFunction2DLattice_onChange(self)
+        return _libBornAgainCore.InterferenceFunction2DSuperLattice_getChildren(self)
 
-InterferenceFunction2DLattice_swigregister = _libBornAgainCore.InterferenceFunction2DLattice_swigregister
-InterferenceFunction2DLattice_swigregister(InterferenceFunction2DLattice)
+InterferenceFunction2DSuperLattice_swigregister = _libBornAgainCore.InterferenceFunction2DSuperLattice_swigregister
+InterferenceFunction2DSuperLattice_swigregister(InterferenceFunction2DSuperLattice)
 
-def InterferenceFunction2DLattice_createSquare(lattice_length, xi=0.0):
-    """
-    createSquare(double lattice_length, double xi=0.0) -> InterferenceFunction2DLattice
-    InterferenceFunction2DLattice_createSquare(double lattice_length) -> InterferenceFunction2DLattice
-    """
-    return _libBornAgainCore.InterferenceFunction2DLattice_createSquare(lattice_length, xi)
+def InterferenceFunction2DSuperLattice_createSquare(lattice_length, xi, size_1, size_2):
+    """InterferenceFunction2DSuperLattice_createSquare(double lattice_length, double xi, unsigned int size_1, unsigned int size_2) -> InterferenceFunction2DSuperLattice"""
+    return _libBornAgainCore.InterferenceFunction2DSuperLattice_createSquare(lattice_length, xi, size_1, size_2)
 
-def InterferenceFunction2DLattice_createHexagonal(lattice_length, xi=0.0):
-    """
-    createHexagonal(double lattice_length, double xi=0.0) -> InterferenceFunction2DLattice
-    InterferenceFunction2DLattice_createHexagonal(double lattice_length) -> InterferenceFunction2DLattice
-    """
-    return _libBornAgainCore.InterferenceFunction2DLattice_createHexagonal(lattice_length, xi)
+def InterferenceFunction2DSuperLattice_createHexagonal(lattice_length, xi, size_1, size_2):
+    """InterferenceFunction2DSuperLattice_createHexagonal(double lattice_length, double xi, unsigned int size_1, unsigned int size_2) -> InterferenceFunction2DSuperLattice"""
+    return _libBornAgainCore.InterferenceFunction2DSuperLattice_createHexagonal(lattice_length, xi, size_1, size_2)
 
 class InterferenceFunction3DLattice(IInterferenceFunction):
     """
@@ -23070,18 +21816,6 @@ class InterferenceFunction3DLattice(IInterferenceFunction):
         return _libBornAgainCore.InterferenceFunction3DLattice_lattice(self)
 
 
-    def getParticleDensity(self):
-        """
-        getParticleDensity(InterferenceFunction3DLattice self) -> double
-
-        double InterferenceFunction3DLattice::getParticleDensity() const final
-
-        If defined by this interference function's parameters, returns the particle density (per area). Otherwise, returns zero or a user-defined value 
-
-        """
-        return _libBornAgainCore.InterferenceFunction3DLattice_getParticleDensity(self)
-
-
     def supportsMultilayer(self):
         """
         supportsMultilayer(InterferenceFunction3DLattice self) -> bool
@@ -23142,12 +21876,12 @@ class InterferenceFunctionFinite2DLattice(IInterferenceFunction):
 
     def __init__(self, *args):
         """
-        __init__(InterferenceFunctionFinite2DLattice self, Lattice2D lattice, unsigned int size_1, unsigned int size_2) -> InterferenceFunctionFinite2DLattice
-        __init__(InterferenceFunctionFinite2DLattice self, double length_1, double length_2, double alpha, double xi, unsigned int size_1, unsigned int size_2) -> InterferenceFunctionFinite2DLattice
+        __init__(InterferenceFunctionFinite2DLattice self, Lattice2D lattice, unsigned int N_1, unsigned int N_2) -> InterferenceFunctionFinite2DLattice
+        __init__(InterferenceFunctionFinite2DLattice self, double length_1, double length_2, double alpha, double xi, unsigned int N_1, unsigned int N_2) -> InterferenceFunctionFinite2DLattice
 
-        InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice(double length_1, double length_2, double alpha, double xi, unsigned size_1, unsigned size_2)
+        InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice(double length_1, double length_2, double alpha, double xi, unsigned N_1, unsigned N_2)
 
-        Constructor of two-dimensional interference function.
+        Constructor of two-dimensional finite lattice interference function.
 
         Parameters:
         -----------
@@ -23162,7 +21896,13 @@ class InterferenceFunctionFinite2DLattice(IInterferenceFunction):
         angle between lattice vectors in radians
 
         xi: 
-        rotation of lattice with respect to x-axis (beam direction) in radians 
+        rotation of lattice with respect to x-axis (beam direction) in radians
+
+        N_1: 
+        number of lattice cells in the first lattice direction
+
+        N_2: 
+        number of lattice cells in the second lattice direction 
 
         """
         this = _libBornAgainCore.new_InterferenceFunctionFinite2DLattice(*args)
@@ -23197,15 +21937,15 @@ class InterferenceFunctionFinite2DLattice(IInterferenceFunction):
         return _libBornAgainCore.InterferenceFunctionFinite2DLattice_accept(self, visitor)
 
 
-    def createSquare(lattice_length, xi, size_1, size_2):
-        """createSquare(double lattice_length, double xi, unsigned int size_1, unsigned int size_2) -> InterferenceFunctionFinite2DLattice"""
-        return _libBornAgainCore.InterferenceFunctionFinite2DLattice_createSquare(lattice_length, xi, size_1, size_2)
+    def createSquare(lattice_length, xi, N_1, N_2):
+        """createSquare(double lattice_length, double xi, unsigned int N_1, unsigned int N_2) -> InterferenceFunctionFinite2DLattice"""
+        return _libBornAgainCore.InterferenceFunctionFinite2DLattice_createSquare(lattice_length, xi, N_1, N_2)
 
     createSquare = staticmethod(createSquare)
 
-    def createHexagonal(lattice_length, xi, size_1, size_2):
-        """createHexagonal(double lattice_length, double xi, unsigned int size_1, unsigned int size_2) -> InterferenceFunctionFinite2DLattice"""
-        return _libBornAgainCore.InterferenceFunctionFinite2DLattice_createHexagonal(lattice_length, xi, size_1, size_2)
+    def createHexagonal(lattice_length, xi, N_1, N_2):
+        """createHexagonal(double lattice_length, double xi, unsigned int N_1, unsigned int N_2) -> InterferenceFunctionFinite2DLattice"""
+        return _libBornAgainCore.InterferenceFunctionFinite2DLattice_createHexagonal(lattice_length, xi, N_1, N_2)
 
     createHexagonal = staticmethod(createHexagonal)
 
@@ -23221,24 +21961,24 @@ class InterferenceFunctionFinite2DLattice(IInterferenceFunction):
         return _libBornAgainCore.InterferenceFunctionFinite2DLattice_evaluate(self, q)
 
 
-    def domainSize1(self):
+    def numberUnitCells1(self):
         """
-        domainSize1(InterferenceFunctionFinite2DLattice self) -> unsigned int
+        numberUnitCells1(InterferenceFunctionFinite2DLattice self) -> unsigned int
 
-        unsigned InterferenceFunctionFinite2DLattice::domainSize1() const
+        unsigned InterferenceFunctionFinite2DLattice::numberUnitCells1() const
 
         """
-        return _libBornAgainCore.InterferenceFunctionFinite2DLattice_domainSize1(self)
+        return _libBornAgainCore.InterferenceFunctionFinite2DLattice_numberUnitCells1(self)
 
 
-    def domainSize2(self):
+    def numberUnitCells2(self):
         """
-        domainSize2(InterferenceFunctionFinite2DLattice self) -> unsigned int
+        numberUnitCells2(InterferenceFunctionFinite2DLattice self) -> unsigned int
 
-        unsigned InterferenceFunctionFinite2DLattice::domainSize2() const
+        unsigned InterferenceFunctionFinite2DLattice::numberUnitCells2() const
 
         """
-        return _libBornAgainCore.InterferenceFunctionFinite2DLattice_domainSize2(self)
+        return _libBornAgainCore.InterferenceFunctionFinite2DLattice_numberUnitCells2(self)
 
 
     def setPositionVariance(self, sigma2):
@@ -23317,580 +22057,436 @@ class InterferenceFunctionFinite2DLattice(IInterferenceFunction):
 InterferenceFunctionFinite2DLattice_swigregister = _libBornAgainCore.InterferenceFunctionFinite2DLattice_swigregister
 InterferenceFunctionFinite2DLattice_swigregister(InterferenceFunctionFinite2DLattice)
 
-def InterferenceFunctionFinite2DLattice_createSquare(lattice_length, xi, size_1, size_2):
-    """InterferenceFunctionFinite2DLattice_createSquare(double lattice_length, double xi, unsigned int size_1, unsigned int size_2) -> InterferenceFunctionFinite2DLattice"""
-    return _libBornAgainCore.InterferenceFunctionFinite2DLattice_createSquare(lattice_length, xi, size_1, size_2)
+def InterferenceFunctionFinite2DLattice_createSquare(lattice_length, xi, N_1, N_2):
+    """InterferenceFunctionFinite2DLattice_createSquare(double lattice_length, double xi, unsigned int N_1, unsigned int N_2) -> InterferenceFunctionFinite2DLattice"""
+    return _libBornAgainCore.InterferenceFunctionFinite2DLattice_createSquare(lattice_length, xi, N_1, N_2)
 
-def InterferenceFunctionFinite2DLattice_createHexagonal(lattice_length, xi, size_1, size_2):
-    """InterferenceFunctionFinite2DLattice_createHexagonal(double lattice_length, double xi, unsigned int size_1, unsigned int size_2) -> InterferenceFunctionFinite2DLattice"""
-    return _libBornAgainCore.InterferenceFunctionFinite2DLattice_createHexagonal(lattice_length, xi, size_1, size_2)
+def InterferenceFunctionFinite2DLattice_createHexagonal(lattice_length, xi, N_1, N_2):
+    """InterferenceFunctionFinite2DLattice_createHexagonal(double lattice_length, double xi, unsigned int N_1, unsigned int N_2) -> InterferenceFunctionFinite2DLattice"""
+    return _libBornAgainCore.InterferenceFunctionFinite2DLattice_createHexagonal(lattice_length, xi, N_1, N_2)
 
-class InterferenceFunction2DSuperLattice(IInterferenceFunction):
+class InterferenceFunctionFinite3DLattice(IInterferenceFunction):
     """
 
 
-    Interference function of 2D superlattice with a configurable interference function for each lattice site.
+    Interference function of 2D lattice.
 
-    C++ includes: InterferenceFunction2DSuperLattice.h
+    C++ includes: InterferenceFunctionFinite3DLattice.h
 
     """
 
     __swig_setmethods__ = {}
     for _s in [IInterferenceFunction]:
         __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
-    __setattr__ = lambda self, name, value: _swig_setattr(self, InterferenceFunction2DSuperLattice, name, value)
+    __setattr__ = lambda self, name, value: _swig_setattr(self, InterferenceFunctionFinite3DLattice, name, value)
     __swig_getmethods__ = {}
     for _s in [IInterferenceFunction]:
         __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
-    __getattr__ = lambda self, name: _swig_getattr(self, InterferenceFunction2DSuperLattice, name)
+    __getattr__ = lambda self, name: _swig_getattr(self, InterferenceFunctionFinite3DLattice, name)
     __repr__ = _swig_repr
 
-    def __init__(self, *args):
+    def __init__(self, lattice, N_1, N_2, N_3):
         """
-        __init__(InterferenceFunction2DSuperLattice self, Lattice2D lattice, unsigned int size_1, unsigned int size_2) -> InterferenceFunction2DSuperLattice
-        __init__(InterferenceFunction2DSuperLattice self, double length_1, double length_2, double alpha, double xi, unsigned int size_1, unsigned int size_2) -> InterferenceFunction2DSuperLattice
+        __init__(InterferenceFunctionFinite3DLattice self, Lattice lattice, unsigned int N_1, unsigned int N_2, unsigned int N_3) -> InterferenceFunctionFinite3DLattice
 
-        InterferenceFunction2DSuperLattice::InterferenceFunction2DSuperLattice(double length_1, double length_2, double alpha, double xi, unsigned size_1, unsigned size_2)
+        InterferenceFunctionFinite3DLattice::InterferenceFunctionFinite3DLattice(const Lattice &lattice, unsigned N_1, unsigned N_2, unsigned N_3)
 
-        Constructor of two-dimensional interference function.
+        Constructor of three-dimensional finite lattice interference function.
 
         Parameters:
         -----------
 
-        length_1: 
-        length of first lattice vector in nanometers
-
-        length_2: 
-        length of second lattice vector in nanometers
+        lattice: 
+        object specifying a 2d lattice structure
 
-        alpha: 
-        angle between lattice vectors in radians
+        N_1: 
+        number of lattice cells in the first lattice direction
 
-        xi: 
-        rotation of lattice with respect to x-axis (beam direction) in radians 
+        N_2: 
+        number of lattice cells in the second lattice direction 
 
         """
-        this = _libBornAgainCore.new_InterferenceFunction2DSuperLattice(*args)
+        this = _libBornAgainCore.new_InterferenceFunctionFinite3DLattice(lattice, N_1, N_2, N_3)
         try:
             self.this.append(this)
         except __builtin__.Exception:
             self.this = this
-    __swig_destroy__ = _libBornAgainCore.delete_InterferenceFunction2DSuperLattice
+    __swig_destroy__ = _libBornAgainCore.delete_InterferenceFunctionFinite3DLattice
     __del__ = lambda self: None
 
     def clone(self):
         """
-        clone(InterferenceFunction2DSuperLattice self) -> InterferenceFunction2DSuperLattice
+        clone(InterferenceFunctionFinite3DLattice self) -> InterferenceFunctionFinite3DLattice
 
-        InterferenceFunction2DSuperLattice * InterferenceFunction2DSuperLattice::clone() const final
+        InterferenceFunctionFinite3DLattice * InterferenceFunctionFinite3DLattice::clone() const final
 
         Returns a clone of this  ISample object. 
 
         """
-        return _libBornAgainCore.InterferenceFunction2DSuperLattice_clone(self)
+        return _libBornAgainCore.InterferenceFunctionFinite3DLattice_clone(self)
 
 
     def accept(self, visitor):
         """
-        accept(InterferenceFunction2DSuperLattice self, INodeVisitor visitor)
+        accept(InterferenceFunctionFinite3DLattice self, INodeVisitor visitor)
 
-        void InterferenceFunction2DSuperLattice::accept(INodeVisitor *visitor) const final
+        void InterferenceFunctionFinite3DLattice::accept(INodeVisitor *visitor) const final
 
         Calls the  INodeVisitor's visit method. 
 
         """
-        return _libBornAgainCore.InterferenceFunction2DSuperLattice_accept(self, visitor)
-
-
-    def setSubstructureIFF(self, sub_iff):
-        """
-        setSubstructureIFF(InterferenceFunction2DSuperLattice self, IInterferenceFunction sub_iff)
-
-        void InterferenceFunction2DSuperLattice::setSubstructureIFF(const IInterferenceFunction &sub_iff)
-
-        """
-        return _libBornAgainCore.InterferenceFunction2DSuperLattice_setSubstructureIFF(self, sub_iff)
-
-
-    def substructureIFF(self):
-        """
-        substructureIFF(InterferenceFunction2DSuperLattice self) -> IInterferenceFunction
-
-        const IInterferenceFunction & InterferenceFunction2DSuperLattice::substructureIFF() const
-
-        """
-        return _libBornAgainCore.InterferenceFunction2DSuperLattice_substructureIFF(self)
-
-
-    def createSquare(lattice_length, xi, size_1, size_2):
-        """createSquare(double lattice_length, double xi, unsigned int size_1, unsigned int size_2) -> InterferenceFunction2DSuperLattice"""
-        return _libBornAgainCore.InterferenceFunction2DSuperLattice_createSquare(lattice_length, xi, size_1, size_2)
-
-    createSquare = staticmethod(createSquare)
-
-    def createHexagonal(lattice_length, xi, size_1, size_2):
-        """createHexagonal(double lattice_length, double xi, unsigned int size_1, unsigned int size_2) -> InterferenceFunction2DSuperLattice"""
-        return _libBornAgainCore.InterferenceFunction2DSuperLattice_createHexagonal(lattice_length, xi, size_1, size_2)
+        return _libBornAgainCore.InterferenceFunctionFinite3DLattice_accept(self, visitor)
 
-    createHexagonal = staticmethod(createHexagonal)
 
     def evaluate(self, q):
         """
-        evaluate(InterferenceFunction2DSuperLattice self, kvector_t q) -> double
+        evaluate(InterferenceFunctionFinite3DLattice self, kvector_t q) -> double
 
-        double InterferenceFunction2DSuperLattice::evaluate(const kvector_t q) const final
+        double InterferenceFunctionFinite3DLattice::evaluate(const kvector_t q) const final
 
         Evaluates the interference function for a given wavevector transfer (only the real x and y components are relevant) 
 
         """
-        return _libBornAgainCore.InterferenceFunction2DSuperLattice_evaluate(self, q)
-
-
-    def domainSize1(self):
-        """
-        domainSize1(InterferenceFunction2DSuperLattice self) -> unsigned int
-
-        unsigned InterferenceFunction2DSuperLattice::domainSize1() const
-
-        """
-        return _libBornAgainCore.InterferenceFunction2DSuperLattice_domainSize1(self)
-
-
-    def domainSize2(self):
-        """
-        domainSize2(InterferenceFunction2DSuperLattice self) -> unsigned int
-
-        unsigned InterferenceFunction2DSuperLattice::domainSize2() const
-
-        """
-        return _libBornAgainCore.InterferenceFunction2DSuperLattice_domainSize2(self)
-
-
-    def setPositionVariance(self, sigma2):
-        """
-        setPositionVariance(InterferenceFunction2DSuperLattice self, double sigma2)
-
-        void InterferenceFunction2DSuperLattice::setPositionVariance(double sigma2)
-
-        """
-        return _libBornAgainCore.InterferenceFunction2DSuperLattice_setPositionVariance(self, sigma2)
+        return _libBornAgainCore.InterferenceFunctionFinite3DLattice_evaluate(self, q)
 
 
-    def positionVariance(self):
+    def numberUnitCells1(self):
         """
-        positionVariance(InterferenceFunction2DSuperLattice self) -> double
+        numberUnitCells1(InterferenceFunctionFinite3DLattice self) -> unsigned int
 
-        double InterferenceFunction2DSuperLattice::positionVariance() const
+        unsigned InterferenceFunctionFinite3DLattice::numberUnitCells1() const
 
         """
-        return _libBornAgainCore.InterferenceFunction2DSuperLattice_positionVariance(self)
+        return _libBornAgainCore.InterferenceFunctionFinite3DLattice_numberUnitCells1(self)
 
 
-    def setIntegrationOverXi(self, integrate_xi):
+    def numberUnitCells2(self):
         """
-        setIntegrationOverXi(InterferenceFunction2DSuperLattice self, bool integrate_xi)
+        numberUnitCells2(InterferenceFunctionFinite3DLattice self) -> unsigned int
 
-        void InterferenceFunction2DSuperLattice::setIntegrationOverXi(bool integrate_xi)
+        unsigned InterferenceFunctionFinite3DLattice::numberUnitCells2() const
 
         """
-        return _libBornAgainCore.InterferenceFunction2DSuperLattice_setIntegrationOverXi(self, integrate_xi)
+        return _libBornAgainCore.InterferenceFunctionFinite3DLattice_numberUnitCells2(self)
 
 
-    def integrationOverXi(self):
+    def numberUnitCells3(self):
         """
-        integrationOverXi(InterferenceFunction2DSuperLattice self) -> bool
+        numberUnitCells3(InterferenceFunctionFinite3DLattice self) -> unsigned int
 
-        bool InterferenceFunction2DSuperLattice::integrationOverXi() const
+        unsigned InterferenceFunctionFinite3DLattice::numberUnitCells3() const
 
         """
-        return _libBornAgainCore.InterferenceFunction2DSuperLattice_integrationOverXi(self)
+        return _libBornAgainCore.InterferenceFunctionFinite3DLattice_numberUnitCells3(self)
 
 
     def lattice(self):
         """
-        lattice(InterferenceFunction2DSuperLattice self) -> Lattice2D
+        lattice(InterferenceFunctionFinite3DLattice self) -> Lattice
 
-        const Lattice2D & InterferenceFunction2DSuperLattice::lattice() const
+        const Lattice & InterferenceFunctionFinite3DLattice::lattice() const
 
         """
-        return _libBornAgainCore.InterferenceFunction2DSuperLattice_lattice(self)
+        return _libBornAgainCore.InterferenceFunctionFinite3DLattice_lattice(self)
 
 
     def getChildren(self):
         """
-        getChildren(InterferenceFunction2DSuperLattice self) -> swig_dummy_type_const_inode_vector
+        getChildren(InterferenceFunctionFinite3DLattice self) -> swig_dummy_type_const_inode_vector
 
-        std::vector< const INode * > InterferenceFunction2DSuperLattice::getChildren() const override
+        std::vector< const INode * > InterferenceFunctionFinite3DLattice::getChildren() const override
 
         Returns a vector of children (const). 
 
         """
-        return _libBornAgainCore.InterferenceFunction2DSuperLattice_getChildren(self)
-
-InterferenceFunction2DSuperLattice_swigregister = _libBornAgainCore.InterferenceFunction2DSuperLattice_swigregister
-InterferenceFunction2DSuperLattice_swigregister(InterferenceFunction2DSuperLattice)
-
-def InterferenceFunction2DSuperLattice_createSquare(lattice_length, xi, size_1, size_2):
-    """InterferenceFunction2DSuperLattice_createSquare(double lattice_length, double xi, unsigned int size_1, unsigned int size_2) -> InterferenceFunction2DSuperLattice"""
-    return _libBornAgainCore.InterferenceFunction2DSuperLattice_createSquare(lattice_length, xi, size_1, size_2)
+        return _libBornAgainCore.InterferenceFunctionFinite3DLattice_getChildren(self)
 
-def InterferenceFunction2DSuperLattice_createHexagonal(lattice_length, xi, size_1, size_2):
-    """InterferenceFunction2DSuperLattice_createHexagonal(double lattice_length, double xi, unsigned int size_1, unsigned int size_2) -> InterferenceFunction2DSuperLattice"""
-    return _libBornAgainCore.InterferenceFunction2DSuperLattice_createHexagonal(lattice_length, xi, size_1, size_2)
+InterferenceFunctionFinite3DLattice_swigregister = _libBornAgainCore.InterferenceFunctionFinite3DLattice_swigregister
+InterferenceFunctionFinite3DLattice_swigregister(InterferenceFunctionFinite3DLattice)
 
-class InterferenceFunction2DParaCrystal(IInterferenceFunction):
+class InterferenceFunctionNone(IInterferenceFunction):
     """
 
 
-    Interference function of 2D paracrystal.
+    Default interference function (i.e. absence of any interference).
 
-    C++ includes: InterferenceFunction2DParaCrystal.h
+    C++ includes: InterferenceFunctionNone.h
 
     """
 
     __swig_setmethods__ = {}
     for _s in [IInterferenceFunction]:
         __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
-    __setattr__ = lambda self, name, value: _swig_setattr(self, InterferenceFunction2DParaCrystal, name, value)
+    __setattr__ = lambda self, name, value: _swig_setattr(self, InterferenceFunctionNone, name, value)
     __swig_getmethods__ = {}
     for _s in [IInterferenceFunction]:
         __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
-    __getattr__ = lambda self, name: _swig_getattr(self, InterferenceFunction2DParaCrystal, name)
+    __getattr__ = lambda self, name: _swig_getattr(self, InterferenceFunctionNone, name)
     __repr__ = _swig_repr
 
-    def __init__(self, *args):
+    def __init__(self):
         """
-        __init__(InterferenceFunction2DParaCrystal self, Lattice2D lattice, double damping_length=0.0, double domain_size_1=0.0, double domain_size_2=0.0) -> InterferenceFunction2DParaCrystal
-        __init__(InterferenceFunction2DParaCrystal self, Lattice2D lattice, double damping_length=0.0, double domain_size_1=0.0) -> InterferenceFunction2DParaCrystal
-        __init__(InterferenceFunction2DParaCrystal self, Lattice2D lattice, double damping_length=0.0) -> InterferenceFunction2DParaCrystal
-        __init__(InterferenceFunction2DParaCrystal self, Lattice2D lattice) -> InterferenceFunction2DParaCrystal
-        __init__(InterferenceFunction2DParaCrystal self, double length_1, double length_2, double alpha, double xi=0.0, double damping_length=0.0) -> InterferenceFunction2DParaCrystal
-        __init__(InterferenceFunction2DParaCrystal self, double length_1, double length_2, double alpha, double xi=0.0) -> InterferenceFunction2DParaCrystal
-        __init__(InterferenceFunction2DParaCrystal self, double length_1, double length_2, double alpha) -> InterferenceFunction2DParaCrystal
-
-        InterferenceFunction2DParaCrystal::InterferenceFunction2DParaCrystal(double length_1, double length_2, double alpha, double xi=0.0, double damping_length=0.0)
-
-        Constructor of interference function of two-dimensional paracrystal.
-
-        Parameters:
-        -----------
-
-        length_1: 
-        length of first lattice vector in nanometers
-
-        length_2: 
-        length of second lattice vector in nanometers
-
-        alpha: 
-        angle between lattice vectors in radians
-
-        xi: 
-        rotation of lattice with respect to x-axis (beam direction) in radians
+        __init__(InterferenceFunctionNone self) -> InterferenceFunctionNone
 
-        damping_length: 
-        the damping (coherence) length of the paracrystal in nanometers 
+        InterferenceFunctionNone::InterferenceFunctionNone()
 
         """
-        this = _libBornAgainCore.new_InterferenceFunction2DParaCrystal(*args)
+        this = _libBornAgainCore.new_InterferenceFunctionNone()
         try:
             self.this.append(this)
         except __builtin__.Exception:
             self.this = this
-    __swig_destroy__ = _libBornAgainCore.delete_InterferenceFunction2DParaCrystal
-    __del__ = lambda self: None
 
     def clone(self):
         """
-        clone(InterferenceFunction2DParaCrystal self) -> InterferenceFunction2DParaCrystal
+        clone(InterferenceFunctionNone self) -> InterferenceFunctionNone
 
-        InterferenceFunction2DParaCrystal * InterferenceFunction2DParaCrystal::clone() const final
+        InterferenceFunctionNone* InterferenceFunctionNone::clone() const final
 
         Returns a clone of this  ISample object. 
 
         """
-        return _libBornAgainCore.InterferenceFunction2DParaCrystal_clone(self)
+        return _libBornAgainCore.InterferenceFunctionNone_clone(self)
 
 
     def accept(self, visitor):
         """
-        accept(InterferenceFunction2DParaCrystal self, INodeVisitor visitor)
+        accept(InterferenceFunctionNone self, INodeVisitor visitor)
 
-        void InterferenceFunction2DParaCrystal::accept(INodeVisitor *visitor) const final
+        void InterferenceFunctionNone::accept(INodeVisitor *visitor) const final
 
         Calls the  INodeVisitor's visit method. 
 
-        """
-        return _libBornAgainCore.InterferenceFunction2DParaCrystal_accept(self, visitor)
-
-
-    def createSquare(lattice_length, damping_length=0.0, domain_size_1=0.0, domain_size_2=0.0):
-        """
-        createSquare(double lattice_length, double damping_length=0.0, double domain_size_1=0.0, double domain_size_2=0.0) -> InterferenceFunction2DParaCrystal
-        createSquare(double lattice_length, double damping_length=0.0, double domain_size_1=0.0) -> InterferenceFunction2DParaCrystal
-        createSquare(double lattice_length, double damping_length=0.0) -> InterferenceFunction2DParaCrystal
-        createSquare(double lattice_length) -> InterferenceFunction2DParaCrystal
-        """
-        return _libBornAgainCore.InterferenceFunction2DParaCrystal_createSquare(lattice_length, damping_length, domain_size_1, domain_size_2)
-
-    createSquare = staticmethod(createSquare)
-
-    def createHexagonal(lattice_length, damping_length=0.0, domain_size_1=0.0, domain_size_2=0.0):
-        """
-        createHexagonal(double lattice_length, double damping_length=0.0, double domain_size_1=0.0, double domain_size_2=0.0) -> InterferenceFunction2DParaCrystal
-        createHexagonal(double lattice_length, double damping_length=0.0, double domain_size_1=0.0) -> InterferenceFunction2DParaCrystal
-        createHexagonal(double lattice_length, double damping_length=0.0) -> InterferenceFunction2DParaCrystal
-        createHexagonal(double lattice_length) -> InterferenceFunction2DParaCrystal
-        """
-        return _libBornAgainCore.InterferenceFunction2DParaCrystal_createHexagonal(lattice_length, damping_length, domain_size_1, domain_size_2)
-
-    createHexagonal = staticmethod(createHexagonal)
-
-    def setDomainSizes(self, size_1, size_2):
-        """
-        setDomainSizes(InterferenceFunction2DParaCrystal self, double size_1, double size_2)
-
-        void InterferenceFunction2DParaCrystal::setDomainSizes(double size_1, double size_2)
-
-        Sets the sizes of coherence domains.
-
-        Parameters:
-        -----------
-
-        size_1: 
-        coherence domain size along the first basis vector in nanometers
+        """
+        return _libBornAgainCore.InterferenceFunctionNone_accept(self, visitor)
 
-        size_2: 
-        coherence domain size along the second basis vector in nanometers 
 
+    def evaluate(self, arg2):
         """
-        return _libBornAgainCore.InterferenceFunction2DParaCrystal_setDomainSizes(self, size_1, size_2)
+        evaluate(InterferenceFunctionNone self, kvector_t arg2) -> double
+
+        double InterferenceFunctionNone::evaluate(const kvector_t) const final
 
+        Evaluates the interference function for a given wavevector transfer (only the real x and y components are relevant) 
 
-    def setProbabilityDistributions(self, pdf_1, pdf_2):
         """
-        setProbabilityDistributions(InterferenceFunction2DParaCrystal self, IFTDistribution2D pdf_1, IFTDistribution2D pdf_2)
+        return _libBornAgainCore.InterferenceFunctionNone_evaluate(self, arg2)
 
-        void InterferenceFunction2DParaCrystal::setProbabilityDistributions(const IFTDistribution2D &pdf_1, const IFTDistribution2D &pdf_2)
+    __swig_destroy__ = _libBornAgainCore.delete_InterferenceFunctionNone
+    __del__ = lambda self: None
+InterferenceFunctionNone_swigregister = _libBornAgainCore.InterferenceFunctionNone_swigregister
+InterferenceFunctionNone_swigregister(InterferenceFunctionNone)
 
-        Sets the probability distributions (Fourier transformed) for the two lattice directions.
+class InterferenceFunctionRadialParaCrystal(IInterferenceFunction):
+    """
 
-        Parameters:
-        -----------
 
-        pdf_1: 
-        probability distribution in first lattice direction
+    Interference function of radial paracrystal.
 
-        pdf_2: 
-        probability distribution in second lattice direction 
+    C++ includes: InterferenceFunctionRadialParaCrystal.h
 
-        """
-        return _libBornAgainCore.InterferenceFunction2DParaCrystal_setProbabilityDistributions(self, pdf_1, pdf_2)
+    """
 
+    __swig_setmethods__ = {}
+    for _s in [IInterferenceFunction]:
+        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
+    __setattr__ = lambda self, name, value: _swig_setattr(self, InterferenceFunctionRadialParaCrystal, name, value)
+    __swig_getmethods__ = {}
+    for _s in [IInterferenceFunction]:
+        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
+    __getattr__ = lambda self, name: _swig_getattr(self, InterferenceFunctionRadialParaCrystal, name)
+    __repr__ = _swig_repr
 
-    def setDampingLength(self, damping_length):
+    def __init__(self, peak_distance, damping_length=0.0):
         """
-        setDampingLength(InterferenceFunction2DParaCrystal self, double damping_length)
+        __init__(InterferenceFunctionRadialParaCrystal self, double peak_distance, double damping_length=0.0) -> InterferenceFunctionRadialParaCrystal
+        __init__(InterferenceFunctionRadialParaCrystal self, double peak_distance) -> InterferenceFunctionRadialParaCrystal
 
-        void InterferenceFunction2DParaCrystal::setDampingLength(double damping_length)
+        InterferenceFunctionRadialParaCrystal::InterferenceFunctionRadialParaCrystal(double peak_distance, double damping_length=0.0)
 
-        Sets the damping length.
+        Constructor of interference function of radial paracrystal.
 
         Parameters:
         -----------
 
+        peak_distance: 
+        average distance to the next neighbor in nanometers
+
         damping_length: 
         the damping (coherence) length of the paracrystal in nanometers 
 
         """
-        return _libBornAgainCore.InterferenceFunction2DParaCrystal_setDampingLength(self, damping_length)
-
+        this = _libBornAgainCore.new_InterferenceFunctionRadialParaCrystal(peak_distance, damping_length)
+        try:
+            self.this.append(this)
+        except __builtin__.Exception:
+            self.this = this
 
-    def evaluate(self, q):
+    def clone(self):
         """
-        evaluate(InterferenceFunction2DParaCrystal self, kvector_t q) -> double
+        clone(InterferenceFunctionRadialParaCrystal self) -> InterferenceFunctionRadialParaCrystal
 
-        double InterferenceFunction2DParaCrystal::evaluate(const kvector_t q) const final
+        InterferenceFunctionRadialParaCrystal * InterferenceFunctionRadialParaCrystal::clone() const final
 
-        Evaluates the interference function for a given wavevector transfer (only the real x and y components are relevant) 
+        Returns a clone of this  ISample object. 
 
         """
-        return _libBornAgainCore.InterferenceFunction2DParaCrystal_evaluate(self, q)
+        return _libBornAgainCore.InterferenceFunctionRadialParaCrystal_clone(self)
 
 
-    def domainSizes(self):
+    def accept(self, visitor):
         """
-        domainSizes(InterferenceFunction2DParaCrystal self) -> vdouble1d_t
+        accept(InterferenceFunctionRadialParaCrystal self, INodeVisitor visitor)
 
-        std::vector< double > InterferenceFunction2DParaCrystal::domainSizes() const
+        void InterferenceFunctionRadialParaCrystal::accept(INodeVisitor *visitor) const final
+
+        Calls the  INodeVisitor's visit method. 
 
         """
-        return _libBornAgainCore.InterferenceFunction2DParaCrystal_domainSizes(self)
+        return _libBornAgainCore.InterferenceFunctionRadialParaCrystal_accept(self, visitor)
 
 
-    def setIntegrationOverXi(self, integrate_xi):
+    def setKappa(self, kappa):
         """
-        setIntegrationOverXi(InterferenceFunction2DParaCrystal self, bool integrate_xi)
+        setKappa(InterferenceFunctionRadialParaCrystal self, double kappa)
 
-        void InterferenceFunction2DParaCrystal::setIntegrationOverXi(bool integrate_xi)
+        void InterferenceFunctionRadialParaCrystal::setKappa(double kappa)
 
-        Enables/disables averaging over the lattice rotation angle.
+        Sets size spacing coupling parameter of the Size Spacing Correlation Approximation.
 
         Parameters:
         -----------
 
-        integrate_xi: 
-        integration flag 
+        size: 
+        spacing coupling parameter 
 
         """
-        return _libBornAgainCore.InterferenceFunction2DParaCrystal_setIntegrationOverXi(self, integrate_xi)
+        return _libBornAgainCore.InterferenceFunctionRadialParaCrystal_setKappa(self, kappa)
 
 
-    def integrationOverXi(self):
+    def kappa(self):
         """
-        integrationOverXi(InterferenceFunction2DParaCrystal self) -> bool
+        kappa(InterferenceFunctionRadialParaCrystal self) -> double
 
-        bool InterferenceFunction2DParaCrystal::integrationOverXi() const
+        double InterferenceFunctionRadialParaCrystal::kappa() const
 
         """
-        return _libBornAgainCore.InterferenceFunction2DParaCrystal_integrationOverXi(self)
+        return _libBornAgainCore.InterferenceFunctionRadialParaCrystal_kappa(self)
 
 
-    def dampingLength(self):
+    def setDomainSize(self, size):
         """
-        dampingLength(InterferenceFunction2DParaCrystal self) -> double
+        setDomainSize(InterferenceFunctionRadialParaCrystal self, double size)
 
-        double InterferenceFunction2DParaCrystal::dampingLength() const
+        void InterferenceFunctionRadialParaCrystal::setDomainSize(double size)
+
+        Sets domain size (finite size corrections).
+
+        Parameters:
+        -----------
+
+        size: 
+        size of coherence domain along the lattice main axis in nanometers 
 
         """
-        return _libBornAgainCore.InterferenceFunction2DParaCrystal_dampingLength(self)
+        return _libBornAgainCore.InterferenceFunctionRadialParaCrystal_setDomainSize(self, size)
 
 
-    def lattice(self):
+    def domainSize(self):
         """
-        lattice(InterferenceFunction2DParaCrystal self) -> Lattice2D
+        domainSize(InterferenceFunctionRadialParaCrystal self) -> double
 
-        const Lattice2D & InterferenceFunction2DParaCrystal::lattice() const
+        double InterferenceFunctionRadialParaCrystal::domainSize() const
 
         """
-        return _libBornAgainCore.InterferenceFunction2DParaCrystal_lattice(self)
+        return _libBornAgainCore.InterferenceFunctionRadialParaCrystal_domainSize(self)
 
 
-    def getParticleDensity(self):
+    def evaluate(self, q):
         """
-        getParticleDensity(InterferenceFunction2DParaCrystal self) -> double
+        evaluate(InterferenceFunctionRadialParaCrystal self, kvector_t q) -> double
 
-        double InterferenceFunction2DParaCrystal::getParticleDensity() const final
+        double InterferenceFunctionRadialParaCrystal::evaluate(const kvector_t q) const final
 
-        If defined by this interference function's parameters, returns the particle density (per area). Otherwise, returns zero or a user-defined value 
+        Evaluates the interference function for a given wavevector transfer (only the real x and y components are relevant) 
 
         """
-        return _libBornAgainCore.InterferenceFunction2DParaCrystal_getParticleDensity(self)
+        return _libBornAgainCore.InterferenceFunctionRadialParaCrystal_evaluate(self, q)
 
 
-    def getChildren(self):
+    def FTPDF(self, qpar):
         """
-        getChildren(InterferenceFunction2DParaCrystal self) -> swig_dummy_type_const_inode_vector
-
-        std::vector< const INode * > InterferenceFunction2DParaCrystal::getChildren() const
+        FTPDF(InterferenceFunctionRadialParaCrystal self, double qpar) -> complex_t
 
-        Returns a vector of children (const). 
+        complex_t InterferenceFunctionRadialParaCrystal::FTPDF(double qpar) const
 
         """
-        return _libBornAgainCore.InterferenceFunction2DParaCrystal_getChildren(self)
-
-InterferenceFunction2DParaCrystal_swigregister = _libBornAgainCore.InterferenceFunction2DParaCrystal_swigregister
-InterferenceFunction2DParaCrystal_swigregister(InterferenceFunction2DParaCrystal)
+        return _libBornAgainCore.InterferenceFunctionRadialParaCrystal_FTPDF(self, qpar)
 
-def InterferenceFunction2DParaCrystal_createSquare(lattice_length, damping_length=0.0, domain_size_1=0.0, domain_size_2=0.0):
-    """
-    createSquare(double lattice_length, double damping_length=0.0, double domain_size_1=0.0, double domain_size_2=0.0) -> InterferenceFunction2DParaCrystal
-    createSquare(double lattice_length, double damping_length=0.0, double domain_size_1=0.0) -> InterferenceFunction2DParaCrystal
-    createSquare(double lattice_length, double damping_length=0.0) -> InterferenceFunction2DParaCrystal
-    InterferenceFunction2DParaCrystal_createSquare(double lattice_length) -> InterferenceFunction2DParaCrystal
-    """
-    return _libBornAgainCore.InterferenceFunction2DParaCrystal_createSquare(lattice_length, damping_length, domain_size_1, domain_size_2)
 
-def InterferenceFunction2DParaCrystal_createHexagonal(lattice_length, damping_length=0.0, domain_size_1=0.0, domain_size_2=0.0):
-    """
-    createHexagonal(double lattice_length, double damping_length=0.0, double domain_size_1=0.0, double domain_size_2=0.0) -> InterferenceFunction2DParaCrystal
-    createHexagonal(double lattice_length, double damping_length=0.0, double domain_size_1=0.0) -> InterferenceFunction2DParaCrystal
-    createHexagonal(double lattice_length, double damping_length=0.0) -> InterferenceFunction2DParaCrystal
-    InterferenceFunction2DParaCrystal_createHexagonal(double lattice_length) -> InterferenceFunction2DParaCrystal
-    """
-    return _libBornAgainCore.InterferenceFunction2DParaCrystal_createHexagonal(lattice_length, damping_length, domain_size_1, domain_size_2)
+    def setProbabilityDistribution(self, pdf):
+        """
+        setProbabilityDistribution(InterferenceFunctionRadialParaCrystal self, IFTDistribution1D pdf)
 
-class InterferenceFunctionNone(IInterferenceFunction):
-    """
+        void InterferenceFunctionRadialParaCrystal::setProbabilityDistribution(const IFTDistribution1D &pdf)
 
+        Sets one-dimensional probability distribution.
 
-    Default interference function (i.e. absence of any interference).
+        Parameters:
+        -----------
 
-    C++ includes: InterferenceFunctionNone.h
+        pdf: 
+        probability distribution (Fourier transform of probability density) 
 
-    """
+        """
+        return _libBornAgainCore.InterferenceFunctionRadialParaCrystal_setProbabilityDistribution(self, pdf)
 
-    __swig_setmethods__ = {}
-    for _s in [IInterferenceFunction]:
-        __swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
-    __setattr__ = lambda self, name, value: _swig_setattr(self, InterferenceFunctionNone, name, value)
-    __swig_getmethods__ = {}
-    for _s in [IInterferenceFunction]:
-        __swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
-    __getattr__ = lambda self, name: _swig_getattr(self, InterferenceFunctionNone, name)
-    __repr__ = _swig_repr
 
-    def __init__(self):
+    def peakDistance(self):
         """
-        __init__(InterferenceFunctionNone self) -> InterferenceFunctionNone
+        peakDistance(InterferenceFunctionRadialParaCrystal self) -> double
 
-        InterferenceFunctionNone::InterferenceFunctionNone()
+        double InterferenceFunctionRadialParaCrystal::peakDistance() const
 
         """
-        this = _libBornAgainCore.new_InterferenceFunctionNone()
-        try:
-            self.this.append(this)
-        except __builtin__.Exception:
-            self.this = this
+        return _libBornAgainCore.InterferenceFunctionRadialParaCrystal_peakDistance(self)
 
-    def clone(self):
-        """
-        clone(InterferenceFunctionNone self) -> InterferenceFunctionNone
 
-        InterferenceFunctionNone* InterferenceFunctionNone::clone() const final
+    def dampingLength(self):
+        """
+        dampingLength(InterferenceFunctionRadialParaCrystal self) -> double
 
-        Returns a clone of this  ISample object. 
+        double InterferenceFunctionRadialParaCrystal::dampingLength() const
 
         """
-        return _libBornAgainCore.InterferenceFunctionNone_clone(self)
+        return _libBornAgainCore.InterferenceFunctionRadialParaCrystal_dampingLength(self)
 
 
-    def accept(self, visitor):
+    def getChildren(self):
         """
-        accept(InterferenceFunctionNone self, INodeVisitor visitor)
+        getChildren(InterferenceFunctionRadialParaCrystal self) -> swig_dummy_type_const_inode_vector
 
-        void InterferenceFunctionNone::accept(INodeVisitor *visitor) const final
+        std::vector< const INode * > InterferenceFunctionRadialParaCrystal::getChildren() const override
 
-        Calls the  INodeVisitor's visit method. 
+        Returns a vector of children (const). 
 
         """
-        return _libBornAgainCore.InterferenceFunctionNone_accept(self, visitor)
+        return _libBornAgainCore.InterferenceFunctionRadialParaCrystal_getChildren(self)
 
 
-    def evaluate(self, arg2):
+    def randomSample(self):
         """
-        evaluate(InterferenceFunctionNone self, kvector_t arg2) -> double
-
-        double InterferenceFunctionNone::evaluate(const kvector_t) const final
+        randomSample(InterferenceFunctionRadialParaCrystal self) -> double
 
-        Evaluates the interference function for a given wavevector transfer (only the real x and y components are relevant) 
+        double InterferenceFunctionRadialParaCrystal::randomSample() const
 
         """
-        return _libBornAgainCore.InterferenceFunctionNone_evaluate(self, arg2)
+        return _libBornAgainCore.InterferenceFunctionRadialParaCrystal_randomSample(self)
 
-    __swig_destroy__ = _libBornAgainCore.delete_InterferenceFunctionNone
+    __swig_destroy__ = _libBornAgainCore.delete_InterferenceFunctionRadialParaCrystal
     __del__ = lambda self: None
-InterferenceFunctionNone_swigregister = _libBornAgainCore.InterferenceFunctionNone_swigregister
-InterferenceFunctionNone_swigregister(InterferenceFunctionNone)
+InterferenceFunctionRadialParaCrystal_swigregister = _libBornAgainCore.InterferenceFunctionRadialParaCrystal_swigregister
+InterferenceFunctionRadialParaCrystal_swigregister(InterferenceFunctionRadialParaCrystal)
 
 class IPixel(_object):
     """
@@ -24226,7 +22822,14 @@ ILatticeOrientation_swigregister = _libBornAgainCore.ILatticeOrientation_swigreg
 ILatticeOrientation_swigregister(ILatticeOrientation)
 
 class MillerIndex(_object):
-    """Proxy of C++ MillerIndex class."""
+    """
+
+
+    MillerIndex represents arbitrary directions in reciprocal space by allowing floating point index values
+
+    C++ includes: ILatticeOrientation.h
+
+    """
 
     __swig_setmethods__ = {}
     __setattr__ = lambda self, name, value: _swig_setattr(self, MillerIndex, name, value)
@@ -24236,9 +22839,9 @@ class MillerIndex(_object):
 
     def __init__(self, h_, k_, l_):
         """
-        __init__(MillerIndex self, int h_, int k_, int l_) -> MillerIndex
+        __init__(MillerIndex self, double h_, double k_, double l_) -> MillerIndex
 
-        MillerIndex::MillerIndex(int h_, int k_, int l_)
+        MillerIndex::MillerIndex(double h_, double k_, double l_)
 
         """
         this = _libBornAgainCore.new_MillerIndex(h_, k_, l_)
@@ -24449,9 +23052,9 @@ class Lattice(INode):
 
     def getMillerDirection(self, h, k, l):
         """
-        getMillerDirection(Lattice self, int h, int k, int l) -> kvector_t
+        getMillerDirection(Lattice self, double h, double k, double l) -> kvector_t
 
-        kvector_t Lattice::getMillerDirection(int h, int k, int l) const
+        kvector_t Lattice::getMillerDirection(double h, double k, double l) const
 
         Returns normalized direction corresponding to the given Miller indices. 
 
@@ -27239,7 +25842,7 @@ class ParameterPool(ICloneable):
 
         Adds parameter to the pool, and returns reference to the input pointer.
 
-        Returning the input pointer allows us to concatenate function calls like pool->addParameter( new  RealParameter(...) ).setLimits(-1,+1).setFixed().setUnit("nm") 
+        Returning the input pointer allows us to concatenate function calls like pool->addParameter( new RealParameter(...) ).setLimits(-1,+1).setFixed().setUnit("nm") 
 
         """
         return _libBornAgainCore.ParameterPool_addParameter(self, newPar)
@@ -30016,26 +28619,6 @@ class ParameterPoolIterator(object):
         return self.next()
 
 
-class FitParameterSetIterator(object):
-
-    def __init__(self, fitParameters):
-        self.fitParameters = fitParameters
-        self.index = -1
-
-    def __iter__(self):
-        return self
-
-    def next(self):
-        self.index += 1
-        if self.index < self.fitParameters.size():
-            return self.fitParameters[self.index]
-        else:
-            raise StopIteration
-
-    def __next__(self):
-        return self.next()
-
-
 class SimulationBuilderWrapper(PyBuilderCallback):
     def __init__(self, f):
         super(SimulationBuilderWrapper, self).__init__()
diff --git a/auto/Wrap/libBornAgainCore_wrap.cpp b/auto/Wrap/libBornAgainCore_wrap.cpp
index 6ad1007f4e5b9ddea68641d5ae60db218f31a53d..5aba5af3c40105e54e4da97190d10586ad12440d 100644
--- a/auto/Wrap/libBornAgainCore_wrap.cpp
+++ b/auto/Wrap/libBornAgainCore_wrap.cpp
@@ -3451,353 +3451,333 @@ namespace Swig {
 
 /* -------- TYPES TABLE (BEGIN) -------- */
 
-#define SWIGTYPE_p_AdjustMinimizerStrategy swig_types[0]
-#define SWIGTYPE_p_AttLimits swig_types[1]
-#define SWIGTYPE_p_Attributes swig_types[2]
-#define SWIGTYPE_p_AxesUnitsWrap swig_types[3]
-#define SWIGTYPE_p_AxesUnitsWrap__AxesUnits swig_types[4]
-#define SWIGTYPE_p_AxisInfo swig_types[5]
-#define SWIGTYPE_p_BasicLattice swig_types[6]
-#define SWIGTYPE_p_BasicVector3DT_double_t swig_types[7]
-#define SWIGTYPE_p_BasicVector3DT_int_t swig_types[8]
-#define SWIGTYPE_p_BasicVector3DT_std__complexT_double_t_t swig_types[9]
-#define SWIGTYPE_p_Beam swig_types[10]
-#define SWIGTYPE_p_Bin1D swig_types[11]
-#define SWIGTYPE_p_Bin1DCVector swig_types[12]
-#define SWIGTYPE_p_Bin1DKVector swig_types[13]
-#define SWIGTYPE_p_CallbackMap_t swig_types[14]
-#define SWIGTYPE_p_ChiSquaredModule swig_types[15]
-#define SWIGTYPE_p_ConstKBinAxis swig_types[16]
-#define SWIGTYPE_p_ConstantBackground swig_types[17]
-#define SWIGTYPE_p_ConvolutionDetectorResolution swig_types[18]
-#define SWIGTYPE_p_CreateItemCallback swig_types[19]
-#define SWIGTYPE_p_Crystal swig_types[20]
-#define SWIGTYPE_p_CustomBinAxis swig_types[21]
-#define SWIGTYPE_p_DepthProbeSimulation swig_types[22]
-#define SWIGTYPE_p_DescriptionMap_t swig_types[23]
-#define SWIGTYPE_p_DetectionProperties swig_types[24]
-#define SWIGTYPE_p_DetectorMask swig_types[25]
-#define SWIGTYPE_p_DistributionCosine swig_types[26]
-#define SWIGTYPE_p_DistributionGate swig_types[27]
-#define SWIGTYPE_p_DistributionGaussian swig_types[28]
-#define SWIGTYPE_p_DistributionHandler swig_types[29]
-#define SWIGTYPE_p_DistributionLogNormal swig_types[30]
-#define SWIGTYPE_p_DistributionLorentz swig_types[31]
-#define SWIGTYPE_p_DistributionTrapezoid swig_types[32]
-#define SWIGTYPE_p_Ellipse swig_types[33]
-#define SWIGTYPE_p_FTDecayFunction1DCauchy swig_types[34]
-#define SWIGTYPE_p_FTDecayFunction1DGauss swig_types[35]
-#define SWIGTYPE_p_FTDecayFunction1DTriangle swig_types[36]
-#define SWIGTYPE_p_FTDecayFunction1DVoigt swig_types[37]
-#define SWIGTYPE_p_FTDecayFunction2DCauchy swig_types[38]
-#define SWIGTYPE_p_FTDecayFunction2DGauss swig_types[39]
-#define SWIGTYPE_p_FTDecayFunction2DVoigt swig_types[40]
-#define SWIGTYPE_p_FTDistribution1DCauchy swig_types[41]
-#define SWIGTYPE_p_FTDistribution1DCosine swig_types[42]
-#define SWIGTYPE_p_FTDistribution1DGate swig_types[43]
-#define SWIGTYPE_p_FTDistribution1DGauss swig_types[44]
-#define SWIGTYPE_p_FTDistribution1DTriangle swig_types[45]
-#define SWIGTYPE_p_FTDistribution1DVoigt swig_types[46]
-#define SWIGTYPE_p_FTDistribution2DCauchy swig_types[47]
-#define SWIGTYPE_p_FTDistribution2DCone swig_types[48]
-#define SWIGTYPE_p_FTDistribution2DGate swig_types[49]
-#define SWIGTYPE_p_FTDistribution2DGauss swig_types[50]
-#define SWIGTYPE_p_FTDistribution2DVoigt swig_types[51]
-#define SWIGTYPE_p_FitObject swig_types[52]
-#define SWIGTYPE_p_FitObjective swig_types[53]
-#define SWIGTYPE_p_FitObjects_t swig_types[54]
-#define SWIGTYPE_p_FitOptions swig_types[55]
-#define SWIGTYPE_p_FitParameter swig_types[56]
-#define SWIGTYPE_p_FitParameterSet swig_types[57]
-#define SWIGTYPE_p_FitStrategyDefault swig_types[58]
-#define SWIGTYPE_p_FitSuite swig_types[59]
-#define SWIGTYPE_p_FitSuiteImpl swig_types[60]
-#define SWIGTYPE_p_FitSuiteObjects swig_types[61]
-#define SWIGTYPE_p_FitSuiteStrategies swig_types[62]
-#define SWIGTYPE_p_Fit__MinimizerResult swig_types[63]
-#define SWIGTYPE_p_Fit__Parameters swig_types[64]
-#define SWIGTYPE_p_FixedBinAxis swig_types[65]
-#define SWIGTYPE_p_FootprintFactorGaussian swig_types[66]
-#define SWIGTYPE_p_FootprintFactorSquare swig_types[67]
-#define SWIGTYPE_p_FormFactorAnisoPyramid swig_types[68]
-#define SWIGTYPE_p_FormFactorBox swig_types[69]
-#define SWIGTYPE_p_FormFactorCone swig_types[70]
-#define SWIGTYPE_p_FormFactorCone6 swig_types[71]
-#define SWIGTYPE_p_FormFactorCoreShell swig_types[72]
-#define SWIGTYPE_p_FormFactorCrystal swig_types[73]
-#define SWIGTYPE_p_FormFactorCuboctahedron swig_types[74]
-#define SWIGTYPE_p_FormFactorCylinder swig_types[75]
-#define SWIGTYPE_p_FormFactorDWBA swig_types[76]
-#define SWIGTYPE_p_FormFactorDWBAPol swig_types[77]
-#define SWIGTYPE_p_FormFactorDebyeBueche swig_types[78]
-#define SWIGTYPE_p_FormFactorDecoratorDebyeWaller swig_types[79]
-#define SWIGTYPE_p_FormFactorDecoratorMaterial swig_types[80]
-#define SWIGTYPE_p_FormFactorDecoratorPositionFactor swig_types[81]
-#define SWIGTYPE_p_FormFactorDecoratorRotation swig_types[82]
-#define SWIGTYPE_p_FormFactorDodecahedron swig_types[83]
-#define SWIGTYPE_p_FormFactorDot swig_types[84]
-#define SWIGTYPE_p_FormFactorEllipsoidalCylinder swig_types[85]
-#define SWIGTYPE_p_FormFactorFullSphere swig_types[86]
-#define SWIGTYPE_p_FormFactorFullSpheroid swig_types[87]
-#define SWIGTYPE_p_FormFactorGauss swig_types[88]
-#define SWIGTYPE_p_FormFactorHemiEllipsoid swig_types[89]
-#define SWIGTYPE_p_FormFactorIcosahedron swig_types[90]
-#define SWIGTYPE_p_FormFactorLongBoxGauss swig_types[91]
-#define SWIGTYPE_p_FormFactorLongBoxLorentz swig_types[92]
-#define SWIGTYPE_p_FormFactorLongRipple1Gauss swig_types[93]
-#define SWIGTYPE_p_FormFactorLongRipple1Lorentz swig_types[94]
-#define SWIGTYPE_p_FormFactorLongRipple2Gauss swig_types[95]
-#define SWIGTYPE_p_FormFactorLongRipple2Lorentz swig_types[96]
-#define SWIGTYPE_p_FormFactorLorentz swig_types[97]
-#define SWIGTYPE_p_FormFactorOrnsteinZernike swig_types[98]
-#define SWIGTYPE_p_FormFactorPolygonalPrism swig_types[99]
-#define SWIGTYPE_p_FormFactorPolygonalSurface swig_types[100]
-#define SWIGTYPE_p_FormFactorPolyhedron swig_types[101]
-#define SWIGTYPE_p_FormFactorPrism3 swig_types[102]
-#define SWIGTYPE_p_FormFactorPrism6 swig_types[103]
-#define SWIGTYPE_p_FormFactorPyramid swig_types[104]
-#define SWIGTYPE_p_FormFactorRipple1 swig_types[105]
-#define SWIGTYPE_p_FormFactorRipple2 swig_types[106]
-#define SWIGTYPE_p_FormFactorSphereGaussianRadius swig_types[107]
-#define SWIGTYPE_p_FormFactorSphereLogNormalRadius swig_types[108]
-#define SWIGTYPE_p_FormFactorSphereUniformRadius swig_types[109]
-#define SWIGTYPE_p_FormFactorTetrahedron swig_types[110]
-#define SWIGTYPE_p_FormFactorTruncatedCube swig_types[111]
-#define SWIGTYPE_p_FormFactorTruncatedSphere swig_types[112]
-#define SWIGTYPE_p_FormFactorTruncatedSpheroid swig_types[113]
-#define SWIGTYPE_p_FormFactorWeighted swig_types[114]
-#define SWIGTYPE_p_GISASSimulation swig_types[115]
-#define SWIGTYPE_p_GaussPeakShape swig_types[116]
-#define SWIGTYPE_p_HexagonalLattice swig_types[117]
-#define SWIGTYPE_p_Histogram1D swig_types[118]
-#define SWIGTYPE_p_Histogram2D swig_types[119]
-#define SWIGTYPE_p_HorizontalLine swig_types[120]
-#define SWIGTYPE_p_IAbstractParticle swig_types[121]
-#define SWIGTYPE_p_IAxis swig_types[122]
-#define SWIGTYPE_p_IBackground swig_types[123]
-#define SWIGTYPE_p_IChiSquaredModule swig_types[124]
-#define SWIGTYPE_p_ICloneable swig_types[125]
-#define SWIGTYPE_p_IClusteredParticles swig_types[126]
-#define SWIGTYPE_p_IDetector swig_types[127]
-#define SWIGTYPE_p_IDetector2D swig_types[128]
-#define SWIGTYPE_p_IDetectorResolution swig_types[129]
-#define SWIGTYPE_p_IDistribution1D swig_types[130]
-#define SWIGTYPE_p_IFTDecayFunction1D swig_types[131]
-#define SWIGTYPE_p_IFTDecayFunction2D swig_types[132]
-#define SWIGTYPE_p_IFTDistribution1D swig_types[133]
-#define SWIGTYPE_p_IFTDistribution2D swig_types[134]
-#define SWIGTYPE_p_IFactoryT_std__string_IMultiLayerBuilder_t swig_types[135]
-#define SWIGTYPE_p_IFactoryT_std__string_Simulation_t swig_types[136]
-#define SWIGTYPE_p_IFitObserver swig_types[137]
-#define SWIGTYPE_p_IFitParameter swig_types[138]
-#define SWIGTYPE_p_IFitStrategy swig_types[139]
-#define SWIGTYPE_p_IFootprintFactor swig_types[140]
-#define SWIGTYPE_p_IFormFactor swig_types[141]
-#define SWIGTYPE_p_IFormFactorBorn swig_types[142]
-#define SWIGTYPE_p_IFormFactorDecorator swig_types[143]
-#define SWIGTYPE_p_IHistogram swig_types[144]
-#define SWIGTYPE_p_IIntensityFunction swig_types[145]
-#define SWIGTYPE_p_IIntensityNormalizer swig_types[146]
-#define SWIGTYPE_p_IInterferenceFunction swig_types[147]
-#define SWIGTYPE_p_ILatticeOrientation swig_types[148]
-#define SWIGTYPE_p_ILayout swig_types[149]
-#define SWIGTYPE_p_IMinimizer swig_types[150]
-#define SWIGTYPE_p_IMultiLayerBuilder swig_types[151]
-#define SWIGTYPE_p_INamed swig_types[152]
-#define SWIGTYPE_p_INode swig_types[153]
-#define SWIGTYPE_p_INodeVisitor swig_types[154]
-#define SWIGTYPE_p_IObservable swig_types[155]
-#define SWIGTYPE_p_IObserver swig_types[156]
-#define SWIGTYPE_p_IParameterT_double_t swig_types[157]
-#define SWIGTYPE_p_IParameterized swig_types[158]
-#define SWIGTYPE_p_IParticle swig_types[159]
-#define SWIGTYPE_p_IPeakShape swig_types[160]
-#define SWIGTYPE_p_IPixel swig_types[161]
-#define SWIGTYPE_p_IResolutionFunction2D swig_types[162]
-#define SWIGTYPE_p_IRotation swig_types[163]
-#define SWIGTYPE_p_ISample swig_types[164]
-#define SWIGTYPE_p_ISelectionRule swig_types[165]
-#define SWIGTYPE_p_IShape2D swig_types[166]
-#define SWIGTYPE_p_ISquaredFunction swig_types[167]
-#define SWIGTYPE_p_IUnitConverter swig_types[168]
-#define SWIGTYPE_p_IdentityRotation swig_types[169]
-#define SWIGTYPE_p_Instrument swig_types[170]
-#define SWIGTYPE_p_IntensityDataIOFactory swig_types[171]
-#define SWIGTYPE_p_IntensityFunctionLog swig_types[172]
-#define SWIGTYPE_p_IntensityFunctionSqrt swig_types[173]
-#define SWIGTYPE_p_IntensityNormalizer swig_types[174]
-#define SWIGTYPE_p_IntensityScaleAndShiftNormalizer swig_types[175]
-#define SWIGTYPE_p_InterferenceFunction1DLattice swig_types[176]
-#define SWIGTYPE_p_InterferenceFunction2DLattice swig_types[177]
-#define SWIGTYPE_p_InterferenceFunction2DParaCrystal swig_types[178]
-#define SWIGTYPE_p_InterferenceFunction2DSuperLattice swig_types[179]
-#define SWIGTYPE_p_InterferenceFunction3DLattice swig_types[180]
-#define SWIGTYPE_p_InterferenceFunctionFinite2DLattice swig_types[181]
-#define SWIGTYPE_p_InterferenceFunctionNone swig_types[182]
-#define SWIGTYPE_p_InterferenceFunctionRadialParaCrystal swig_types[183]
-#define SWIGTYPE_p_IsGISAXSDetector swig_types[184]
-#define SWIGTYPE_p_IterationInfo swig_types[185]
-#define SWIGTYPE_p_Lattice swig_types[186]
-#define SWIGTYPE_p_Lattice1DParameters swig_types[187]
-#define SWIGTYPE_p_Lattice2D swig_types[188]
-#define SWIGTYPE_p_Lattice2D__ReciprocalBases swig_types[189]
-#define SWIGTYPE_p_Layer swig_types[190]
-#define SWIGTYPE_p_LayerInterface swig_types[191]
-#define SWIGTYPE_p_LayerRoughness swig_types[192]
-#define SWIGTYPE_p_Line swig_types[193]
-#define SWIGTYPE_p_Material swig_types[194]
-#define SWIGTYPE_p_MesoCrystal swig_types[195]
-#define SWIGTYPE_p_MillerIndex swig_types[196]
-#define SWIGTYPE_p_MillerIndexOrientation swig_types[197]
-#define SWIGTYPE_p_MultiLayer swig_types[198]
-#define SWIGTYPE_p_OffSpecSimulation swig_types[199]
-#define SWIGTYPE_p_OutputDataIteratorT_double_OutputDataT_double_t_t swig_types[200]
-#define SWIGTYPE_p_OutputDataIteratorT_double_const_OutputDataT_double_t_const_t swig_types[201]
-#define SWIGTYPE_p_OutputDataT_CumulativeValue_t swig_types[202]
-#define SWIGTYPE_p_OutputDataT_bool_t swig_types[203]
-#define SWIGTYPE_p_OutputDataT_double_t swig_types[204]
-#define SWIGTYPE_p_ParameterDistribution swig_types[205]
-#define SWIGTYPE_p_ParameterPool swig_types[206]
-#define SWIGTYPE_p_ParameterSample swig_types[207]
-#define SWIGTYPE_p_Particle swig_types[208]
-#define SWIGTYPE_p_ParticleComposition swig_types[209]
-#define SWIGTYPE_p_ParticleCoreShell swig_types[210]
-#define SWIGTYPE_p_ParticleDistribution swig_types[211]
-#define SWIGTYPE_p_ParticleLayout swig_types[212]
-#define SWIGTYPE_p_ParticleLimits swig_types[213]
-#define SWIGTYPE_p_PoissonNoiseBackground swig_types[214]
-#define SWIGTYPE_p_Polygon swig_types[215]
-#define SWIGTYPE_p_PolygonPrivate swig_types[216]
-#define SWIGTYPE_p_PolygonalTopology swig_types[217]
-#define SWIGTYPE_p_PolyhedralEdge swig_types[218]
-#define SWIGTYPE_p_PolyhedralFace swig_types[219]
-#define SWIGTYPE_p_PolyhedralTopology swig_types[220]
-#define SWIGTYPE_p_ProgressHandler__Callback_t swig_types[221]
-#define SWIGTYPE_p_PyBuilderCallback swig_types[222]
-#define SWIGTYPE_p_PyObserverCallback swig_types[223]
-#define SWIGTYPE_p_RealLimits swig_types[224]
-#define SWIGTYPE_p_RealParameter swig_types[225]
-#define SWIGTYPE_p_Rectangle swig_types[226]
-#define SWIGTYPE_p_RectangularDetector swig_types[227]
-#define SWIGTYPE_p_RectangularPixel swig_types[228]
-#define SWIGTYPE_p_RegionOfInterest swig_types[229]
-#define SWIGTYPE_p_ResolutionFunction2DGaussian swig_types[230]
-#define SWIGTYPE_p_RotationEuler swig_types[231]
-#define SWIGTYPE_p_RotationX swig_types[232]
-#define SWIGTYPE_p_RotationY swig_types[233]
-#define SWIGTYPE_p_RotationZ swig_types[234]
-#define SWIGTYPE_p_SafePointerVectorT_FitObject_t__iterator swig_types[235]
-#define SWIGTYPE_p_SafePointerVectorT_IParticle_t swig_types[236]
-#define SWIGTYPE_p_SafePointerVectorT_Layer_t swig_types[237]
-#define SWIGTYPE_p_SampleBuilderFactory swig_types[238]
-#define SWIGTYPE_p_SimpleSelectionRule swig_types[239]
-#define SWIGTYPE_p_Simulation swig_types[240]
-#define SWIGTYPE_p_Simulation2D swig_types[241]
-#define SWIGTYPE_p_SimulationFactory swig_types[242]
-#define SWIGTYPE_p_SimulationOptions swig_types[243]
-#define SWIGTYPE_p_SimulationResult swig_types[244]
-#define SWIGTYPE_p_SlicedParticle swig_types[245]
-#define SWIGTYPE_p_SlicingEffects swig_types[246]
-#define SWIGTYPE_p_SpecularDetector1D swig_types[247]
-#define SWIGTYPE_p_SpecularSimulation swig_types[248]
-#define SWIGTYPE_p_SphericalDetector swig_types[249]
-#define SWIGTYPE_p_SphericalPixel swig_types[250]
-#define SWIGTYPE_p_SquareLattice swig_types[251]
-#define SWIGTYPE_p_SquaredFunctionDefault swig_types[252]
-#define SWIGTYPE_p_SquaredFunctionGaussianError swig_types[253]
-#define SWIGTYPE_p_SquaredFunctionMeanSquaredError swig_types[254]
-#define SWIGTYPE_p_SquaredFunctionSimError swig_types[255]
-#define SWIGTYPE_p_SquaredFunctionSystematicError swig_types[256]
-#define SWIGTYPE_p_ThreadInfo swig_types[257]
-#define SWIGTYPE_p_Transform3D swig_types[258]
-#define SWIGTYPE_p_VariableBinAxis swig_types[259]
-#define SWIGTYPE_p_VerticalLine swig_types[260]
-#define SWIGTYPE_p_WavevectorInfo swig_types[261]
-#define SWIGTYPE_p_ZLimits swig_types[262]
-#define SWIGTYPE_p_allocator_type swig_types[263]
-#define SWIGTYPE_p_bool swig_types[264]
-#define SWIGTYPE_p_char swig_types[265]
-#define SWIGTYPE_p_const_iterator swig_types[266]
-#define SWIGTYPE_p_const_reference swig_types[267]
-#define SWIGTYPE_p_container_t swig_types[268]
-#define SWIGTYPE_p_corr_matrix_t swig_types[269]
-#define SWIGTYPE_p_difference_type swig_types[270]
-#define SWIGTYPE_p_double swig_types[271]
-#define SWIGTYPE_p_int swig_types[272]
-#define SWIGTYPE_p_iterator swig_types[273]
-#define SWIGTYPE_p_key_type swig_types[274]
-#define SWIGTYPE_p_long_long swig_types[275]
-#define SWIGTYPE_p_mapped_type swig_types[276]
-#define SWIGTYPE_p_observer_t swig_types[277]
-#define SWIGTYPE_p_p_PyObject swig_types[278]
-#define SWIGTYPE_p_parameters_t swig_types[279]
-#define SWIGTYPE_p_reference swig_types[280]
-#define SWIGTYPE_p_short swig_types[281]
-#define SWIGTYPE_p_signed_char swig_types[282]
-#define SWIGTYPE_p_size_type swig_types[283]
-#define SWIGTYPE_p_std__allocatorT_AxisInfo_t swig_types[284]
-#define SWIGTYPE_p_std__allocatorT_BasicVector3DT_double_t_t swig_types[285]
-#define SWIGTYPE_p_std__allocatorT_BasicVector3DT_std__complexT_double_t_t_t swig_types[286]
-#define SWIGTYPE_p_std__allocatorT_IFormFactor_p_t swig_types[287]
-#define SWIGTYPE_p_std__allocatorT_INode_const_p_t swig_types[288]
-#define SWIGTYPE_p_std__allocatorT_INode_p_t swig_types[289]
-#define SWIGTYPE_p_std__allocatorT_ParameterSample_t swig_types[290]
-#define SWIGTYPE_p_std__allocatorT_double_t swig_types[291]
-#define SWIGTYPE_p_std__allocatorT_int_t swig_types[292]
-#define SWIGTYPE_p_std__allocatorT_std__complexT_double_t_t swig_types[293]
-#define SWIGTYPE_p_std__allocatorT_std__pairT_std__string_const_double_t_t swig_types[294]
-#define SWIGTYPE_p_std__allocatorT_std__string_t swig_types[295]
-#define SWIGTYPE_p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t swig_types[296]
-#define SWIGTYPE_p_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t swig_types[297]
-#define SWIGTYPE_p_std__allocatorT_unsigned_long_t swig_types[298]
-#define SWIGTYPE_p_std__complexT_double_t swig_types[299]
-#define SWIGTYPE_p_std__functionT_IMultiLayerBuilder_pfF_t swig_types[300]
-#define SWIGTYPE_p_std__functionT_Simulation_pfF_t swig_types[301]
-#define SWIGTYPE_p_std__functionT_void_fF_t swig_types[302]
-#define SWIGTYPE_p_std__functionT_void_fSimulationAreaIterator_const_RF_t swig_types[303]
-#define SWIGTYPE_p_std__invalid_argument swig_types[304]
-#define SWIGTYPE_p_std__lessT_std__string_t swig_types[305]
-#define SWIGTYPE_p_std__mapT_std__string_double_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_double_t_t_t swig_types[306]
-#define SWIGTYPE_p_std__mapT_std__string_std__string_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_std__string_t_t_t__const_iterator swig_types[307]
-#define SWIGTYPE_p_std__pairT_double_double_t swig_types[308]
-#define SWIGTYPE_p_std__shared_ptrT_IFitObserver_t swig_types[309]
-#define SWIGTYPE_p_std__shared_ptrT_IMultiLayerBuilder_t swig_types[310]
-#define SWIGTYPE_p_std__shared_ptrT_IObserver_t swig_types[311]
-#define SWIGTYPE_p_std__vectorT_AxesUnitsWrap__AxesUnits_std__allocatorT_AxesUnitsWrap__AxesUnits_t_t swig_types[312]
-#define SWIGTYPE_p_std__vectorT_AxisInfo_std__allocatorT_AxisInfo_t_t swig_types[313]
-#define SWIGTYPE_p_std__vectorT_BasicVector3DT_double_t_std__allocatorT_BasicVector3DT_double_t_t_t swig_types[314]
-#define SWIGTYPE_p_std__vectorT_BasicVector3DT_std__complexT_double_t_t_std__allocatorT_BasicVector3DT_std__complexT_double_t_t_t_t swig_types[315]
-#define SWIGTYPE_p_std__vectorT_FitElement_std__allocatorT_FitElement_t_t swig_types[316]
-#define SWIGTYPE_p_std__vectorT_FitElement_std__allocatorT_FitElement_t_t__iterator swig_types[317]
-#define SWIGTYPE_p_std__vectorT_HomogeneousRegion_std__allocatorT_HomogeneousRegion_t_t swig_types[318]
-#define SWIGTYPE_p_std__vectorT_IFitParameter_p_std__allocatorT_IFitParameter_p_t_t__const_iterator swig_types[319]
-#define SWIGTYPE_p_std__vectorT_IFitParameter_p_std__allocatorT_IFitParameter_p_t_t__iterator swig_types[320]
-#define SWIGTYPE_p_std__vectorT_IFormFactor_p_std__allocatorT_IFormFactor_p_t_t swig_types[321]
-#define SWIGTYPE_p_std__vectorT_ILayout_const_p_std__allocatorT_ILayout_const_p_t_t swig_types[322]
-#define SWIGTYPE_p_std__vectorT_INode_const_p_std__allocatorT_INode_const_p_t_t swig_types[323]
-#define SWIGTYPE_p_std__vectorT_INode_p_std__allocatorT_INode_p_t_t swig_types[324]
-#define SWIGTYPE_p_std__vectorT_Material_const_p_std__allocatorT_Material_const_p_t_t swig_types[325]
-#define SWIGTYPE_p_std__vectorT_ParameterSample_std__allocatorT_ParameterSample_t_t swig_types[326]
-#define SWIGTYPE_p_std__vectorT_PolygonalTopology_std__allocatorT_PolygonalTopology_t_t swig_types[327]
-#define SWIGTYPE_p_std__vectorT_RealParameter_p_std__allocatorT_RealParameter_p_t_t swig_types[328]
-#define SWIGTYPE_p_std__vectorT_SimulationElement_std__allocatorT_SimulationElement_t_t swig_types[329]
-#define SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t swig_types[330]
-#define SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t swig_types[331]
-#define SWIGTYPE_p_std__vectorT_size_t_std__allocatorT_size_t_t_t swig_types[332]
-#define SWIGTYPE_p_std__vectorT_std__complexT_double_t_std__allocatorT_std__complexT_double_t_t_t swig_types[333]
-#define SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t swig_types[334]
-#define SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t swig_types[335]
-#define SWIGTYPE_p_std__vectorT_std__vectorT_int_std__allocatorT_int_t_t_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t_t swig_types[336]
-#define SWIGTYPE_p_std__vectorT_unsigned_int_std__allocatorT_unsigned_int_t_t swig_types[337]
-#define SWIGTYPE_p_std__vectorT_unsigned_long_std__allocatorT_unsigned_long_t_t swig_types[338]
-#define SWIGTYPE_p_swig__SwigPyIterator swig_types[339]
-#define SWIGTYPE_p_unsigned_char swig_types[340]
-#define SWIGTYPE_p_unsigned_int swig_types[341]
-#define SWIGTYPE_p_unsigned_long_long swig_types[342]
-#define SWIGTYPE_p_unsigned_short swig_types[343]
-#define SWIGTYPE_p_value_type swig_types[344]
-static swig_type_info *swig_types[346];
-static swig_module_info swig_module = {swig_types, 345, 0, 0, 0, 0};
+#define SWIGTYPE_p_Attributes swig_types[0]
+#define SWIGTYPE_p_AxesUnitsWrap swig_types[1]
+#define SWIGTYPE_p_AxesUnitsWrap__AxesUnits swig_types[2]
+#define SWIGTYPE_p_AxisInfo swig_types[3]
+#define SWIGTYPE_p_BasicLattice swig_types[4]
+#define SWIGTYPE_p_BasicVector3DT_double_t swig_types[5]
+#define SWIGTYPE_p_BasicVector3DT_int_t swig_types[6]
+#define SWIGTYPE_p_BasicVector3DT_std__complexT_double_t_t swig_types[7]
+#define SWIGTYPE_p_Beam swig_types[8]
+#define SWIGTYPE_p_Bin1D swig_types[9]
+#define SWIGTYPE_p_Bin1DCVector swig_types[10]
+#define SWIGTYPE_p_Bin1DKVector swig_types[11]
+#define SWIGTYPE_p_CallbackMap_t swig_types[12]
+#define SWIGTYPE_p_ChiSquaredModule swig_types[13]
+#define SWIGTYPE_p_ConstKBinAxis swig_types[14]
+#define SWIGTYPE_p_ConstantBackground swig_types[15]
+#define SWIGTYPE_p_ConvolutionDetectorResolution swig_types[16]
+#define SWIGTYPE_p_CreateItemCallback swig_types[17]
+#define SWIGTYPE_p_Crystal swig_types[18]
+#define SWIGTYPE_p_CustomBinAxis swig_types[19]
+#define SWIGTYPE_p_DepthProbeSimulation swig_types[20]
+#define SWIGTYPE_p_DescriptionMap_t swig_types[21]
+#define SWIGTYPE_p_DetectionProperties swig_types[22]
+#define SWIGTYPE_p_DetectorMask swig_types[23]
+#define SWIGTYPE_p_DistributionCosine swig_types[24]
+#define SWIGTYPE_p_DistributionGate swig_types[25]
+#define SWIGTYPE_p_DistributionGaussian swig_types[26]
+#define SWIGTYPE_p_DistributionHandler swig_types[27]
+#define SWIGTYPE_p_DistributionLogNormal swig_types[28]
+#define SWIGTYPE_p_DistributionLorentz swig_types[29]
+#define SWIGTYPE_p_DistributionTrapezoid swig_types[30]
+#define SWIGTYPE_p_Ellipse swig_types[31]
+#define SWIGTYPE_p_FTDecayFunction1DCauchy swig_types[32]
+#define SWIGTYPE_p_FTDecayFunction1DGauss swig_types[33]
+#define SWIGTYPE_p_FTDecayFunction1DTriangle swig_types[34]
+#define SWIGTYPE_p_FTDecayFunction1DVoigt swig_types[35]
+#define SWIGTYPE_p_FTDecayFunction2DCauchy swig_types[36]
+#define SWIGTYPE_p_FTDecayFunction2DGauss swig_types[37]
+#define SWIGTYPE_p_FTDecayFunction2DVoigt swig_types[38]
+#define SWIGTYPE_p_FTDistribution1DCauchy swig_types[39]
+#define SWIGTYPE_p_FTDistribution1DCosine swig_types[40]
+#define SWIGTYPE_p_FTDistribution1DGate swig_types[41]
+#define SWIGTYPE_p_FTDistribution1DGauss swig_types[42]
+#define SWIGTYPE_p_FTDistribution1DTriangle swig_types[43]
+#define SWIGTYPE_p_FTDistribution1DVoigt swig_types[44]
+#define SWIGTYPE_p_FTDistribution2DCauchy swig_types[45]
+#define SWIGTYPE_p_FTDistribution2DCone swig_types[46]
+#define SWIGTYPE_p_FTDistribution2DGate swig_types[47]
+#define SWIGTYPE_p_FTDistribution2DGauss swig_types[48]
+#define SWIGTYPE_p_FTDistribution2DVoigt swig_types[49]
+#define SWIGTYPE_p_FitObjective swig_types[50]
+#define SWIGTYPE_p_FitOptions swig_types[51]
+#define SWIGTYPE_p_Fit__MinimizerResult swig_types[52]
+#define SWIGTYPE_p_Fit__Parameters swig_types[53]
+#define SWIGTYPE_p_FixedBinAxis swig_types[54]
+#define SWIGTYPE_p_FootprintFactorGaussian swig_types[55]
+#define SWIGTYPE_p_FootprintFactorSquare swig_types[56]
+#define SWIGTYPE_p_FormFactorAnisoPyramid swig_types[57]
+#define SWIGTYPE_p_FormFactorBox swig_types[58]
+#define SWIGTYPE_p_FormFactorCone swig_types[59]
+#define SWIGTYPE_p_FormFactorCone6 swig_types[60]
+#define SWIGTYPE_p_FormFactorCoreShell swig_types[61]
+#define SWIGTYPE_p_FormFactorCrystal swig_types[62]
+#define SWIGTYPE_p_FormFactorCuboctahedron swig_types[63]
+#define SWIGTYPE_p_FormFactorCylinder swig_types[64]
+#define SWIGTYPE_p_FormFactorDWBA swig_types[65]
+#define SWIGTYPE_p_FormFactorDWBAPol swig_types[66]
+#define SWIGTYPE_p_FormFactorDebyeBueche swig_types[67]
+#define SWIGTYPE_p_FormFactorDecoratorDebyeWaller swig_types[68]
+#define SWIGTYPE_p_FormFactorDecoratorMaterial swig_types[69]
+#define SWIGTYPE_p_FormFactorDecoratorPositionFactor swig_types[70]
+#define SWIGTYPE_p_FormFactorDecoratorRotation swig_types[71]
+#define SWIGTYPE_p_FormFactorDodecahedron swig_types[72]
+#define SWIGTYPE_p_FormFactorDot swig_types[73]
+#define SWIGTYPE_p_FormFactorEllipsoidalCylinder swig_types[74]
+#define SWIGTYPE_p_FormFactorFullSphere swig_types[75]
+#define SWIGTYPE_p_FormFactorFullSpheroid swig_types[76]
+#define SWIGTYPE_p_FormFactorGauss swig_types[77]
+#define SWIGTYPE_p_FormFactorHemiEllipsoid swig_types[78]
+#define SWIGTYPE_p_FormFactorIcosahedron swig_types[79]
+#define SWIGTYPE_p_FormFactorLongBox swig_types[80]
+#define SWIGTYPE_p_FormFactorLongBoxGauss swig_types[81]
+#define SWIGTYPE_p_FormFactorLongBoxLorentz swig_types[82]
+#define SWIGTYPE_p_FormFactorLongRipple1Gauss swig_types[83]
+#define SWIGTYPE_p_FormFactorLongRipple1Lorentz swig_types[84]
+#define SWIGTYPE_p_FormFactorLongRipple2Gauss swig_types[85]
+#define SWIGTYPE_p_FormFactorLongRipple2Lorentz swig_types[86]
+#define SWIGTYPE_p_FormFactorLorentz swig_types[87]
+#define SWIGTYPE_p_FormFactorOrnsteinZernike swig_types[88]
+#define SWIGTYPE_p_FormFactorPolygonalPrism swig_types[89]
+#define SWIGTYPE_p_FormFactorPolygonalSurface swig_types[90]
+#define SWIGTYPE_p_FormFactorPolyhedron swig_types[91]
+#define SWIGTYPE_p_FormFactorPrism3 swig_types[92]
+#define SWIGTYPE_p_FormFactorPrism6 swig_types[93]
+#define SWIGTYPE_p_FormFactorPyramid swig_types[94]
+#define SWIGTYPE_p_FormFactorRipple1 swig_types[95]
+#define SWIGTYPE_p_FormFactorRipple2 swig_types[96]
+#define SWIGTYPE_p_FormFactorSphereGaussianRadius swig_types[97]
+#define SWIGTYPE_p_FormFactorSphereLogNormalRadius swig_types[98]
+#define SWIGTYPE_p_FormFactorSphereUniformRadius swig_types[99]
+#define SWIGTYPE_p_FormFactorTetrahedron swig_types[100]
+#define SWIGTYPE_p_FormFactorTruncatedCube swig_types[101]
+#define SWIGTYPE_p_FormFactorTruncatedSphere swig_types[102]
+#define SWIGTYPE_p_FormFactorTruncatedSpheroid swig_types[103]
+#define SWIGTYPE_p_FormFactorWeighted swig_types[104]
+#define SWIGTYPE_p_GISASSimulation swig_types[105]
+#define SWIGTYPE_p_GaussFisherPeakShape swig_types[106]
+#define SWIGTYPE_p_HexagonalLattice swig_types[107]
+#define SWIGTYPE_p_Histogram1D swig_types[108]
+#define SWIGTYPE_p_Histogram2D swig_types[109]
+#define SWIGTYPE_p_HorizontalLine swig_types[110]
+#define SWIGTYPE_p_IAbstractParticle swig_types[111]
+#define SWIGTYPE_p_IAxis swig_types[112]
+#define SWIGTYPE_p_IBackground swig_types[113]
+#define SWIGTYPE_p_IChiSquaredModule swig_types[114]
+#define SWIGTYPE_p_ICloneable swig_types[115]
+#define SWIGTYPE_p_IClusteredParticles swig_types[116]
+#define SWIGTYPE_p_IDetector swig_types[117]
+#define SWIGTYPE_p_IDetector2D swig_types[118]
+#define SWIGTYPE_p_IDetectorResolution swig_types[119]
+#define SWIGTYPE_p_IDistribution1D swig_types[120]
+#define SWIGTYPE_p_IFTDecayFunction1D swig_types[121]
+#define SWIGTYPE_p_IFTDecayFunction2D swig_types[122]
+#define SWIGTYPE_p_IFTDistribution1D swig_types[123]
+#define SWIGTYPE_p_IFTDistribution2D swig_types[124]
+#define SWIGTYPE_p_IFactoryT_std__string_IMultiLayerBuilder_t swig_types[125]
+#define SWIGTYPE_p_IFactoryT_std__string_Simulation_t swig_types[126]
+#define SWIGTYPE_p_IFootprintFactor swig_types[127]
+#define SWIGTYPE_p_IFormFactor swig_types[128]
+#define SWIGTYPE_p_IFormFactorBorn swig_types[129]
+#define SWIGTYPE_p_IFormFactorDecorator swig_types[130]
+#define SWIGTYPE_p_IHistogram swig_types[131]
+#define SWIGTYPE_p_IIntensityFunction swig_types[132]
+#define SWIGTYPE_p_IIntensityNormalizer swig_types[133]
+#define SWIGTYPE_p_IInterferenceFunction swig_types[134]
+#define SWIGTYPE_p_ILatticeOrientation swig_types[135]
+#define SWIGTYPE_p_ILayout swig_types[136]
+#define SWIGTYPE_p_IMultiLayerBuilder swig_types[137]
+#define SWIGTYPE_p_INamed swig_types[138]
+#define SWIGTYPE_p_INode swig_types[139]
+#define SWIGTYPE_p_INodeVisitor swig_types[140]
+#define SWIGTYPE_p_IObservable swig_types[141]
+#define SWIGTYPE_p_IObserver swig_types[142]
+#define SWIGTYPE_p_IParameterT_double_t swig_types[143]
+#define SWIGTYPE_p_IParameterized swig_types[144]
+#define SWIGTYPE_p_IParticle swig_types[145]
+#define SWIGTYPE_p_IPeakShape swig_types[146]
+#define SWIGTYPE_p_IPixel swig_types[147]
+#define SWIGTYPE_p_IResolutionFunction2D swig_types[148]
+#define SWIGTYPE_p_IRotation swig_types[149]
+#define SWIGTYPE_p_ISample swig_types[150]
+#define SWIGTYPE_p_ISelectionRule swig_types[151]
+#define SWIGTYPE_p_IShape2D swig_types[152]
+#define SWIGTYPE_p_IUnitConverter swig_types[153]
+#define SWIGTYPE_p_IVarianceFunction swig_types[154]
+#define SWIGTYPE_p_IdentityRotation swig_types[155]
+#define SWIGTYPE_p_Instrument swig_types[156]
+#define SWIGTYPE_p_IntensityDataIOFactory swig_types[157]
+#define SWIGTYPE_p_IntensityFunctionLog swig_types[158]
+#define SWIGTYPE_p_IntensityFunctionSqrt swig_types[159]
+#define SWIGTYPE_p_IntensityNormalizer swig_types[160]
+#define SWIGTYPE_p_IntensityScaleAndShiftNormalizer swig_types[161]
+#define SWIGTYPE_p_InterferenceFunction1DLattice swig_types[162]
+#define SWIGTYPE_p_InterferenceFunction2DLattice swig_types[163]
+#define SWIGTYPE_p_InterferenceFunction2DParaCrystal swig_types[164]
+#define SWIGTYPE_p_InterferenceFunction2DSuperLattice swig_types[165]
+#define SWIGTYPE_p_InterferenceFunction3DLattice swig_types[166]
+#define SWIGTYPE_p_InterferenceFunctionFinite2DLattice swig_types[167]
+#define SWIGTYPE_p_InterferenceFunctionFinite3DLattice swig_types[168]
+#define SWIGTYPE_p_InterferenceFunctionNone swig_types[169]
+#define SWIGTYPE_p_InterferenceFunctionRadialParaCrystal swig_types[170]
+#define SWIGTYPE_p_IsGISAXSDetector swig_types[171]
+#define SWIGTYPE_p_IsotropicGaussPeakShape swig_types[172]
+#define SWIGTYPE_p_IsotropicLorentzPeakShape swig_types[173]
+#define SWIGTYPE_p_IterationInfo swig_types[174]
+#define SWIGTYPE_p_Lattice swig_types[175]
+#define SWIGTYPE_p_Lattice1DParameters swig_types[176]
+#define SWIGTYPE_p_Lattice2D swig_types[177]
+#define SWIGTYPE_p_Lattice2D__ReciprocalBases swig_types[178]
+#define SWIGTYPE_p_Layer swig_types[179]
+#define SWIGTYPE_p_LayerInterface swig_types[180]
+#define SWIGTYPE_p_LayerRoughness swig_types[181]
+#define SWIGTYPE_p_Line swig_types[182]
+#define SWIGTYPE_p_LorentzFisherPeakShape swig_types[183]
+#define SWIGTYPE_p_Material swig_types[184]
+#define SWIGTYPE_p_MesoCrystal swig_types[185]
+#define SWIGTYPE_p_MillerIndex swig_types[186]
+#define SWIGTYPE_p_MillerIndexOrientation swig_types[187]
+#define SWIGTYPE_p_MultiLayer swig_types[188]
+#define SWIGTYPE_p_OffSpecSimulation swig_types[189]
+#define SWIGTYPE_p_OutputDataIteratorT_double_OutputDataT_double_t_t swig_types[190]
+#define SWIGTYPE_p_OutputDataIteratorT_double_const_OutputDataT_double_t_const_t swig_types[191]
+#define SWIGTYPE_p_OutputDataT_CumulativeValue_t swig_types[192]
+#define SWIGTYPE_p_OutputDataT_bool_t swig_types[193]
+#define SWIGTYPE_p_OutputDataT_double_t swig_types[194]
+#define SWIGTYPE_p_ParameterDistribution swig_types[195]
+#define SWIGTYPE_p_ParameterPool swig_types[196]
+#define SWIGTYPE_p_ParameterSample swig_types[197]
+#define SWIGTYPE_p_Particle swig_types[198]
+#define SWIGTYPE_p_ParticleComposition swig_types[199]
+#define SWIGTYPE_p_ParticleCoreShell swig_types[200]
+#define SWIGTYPE_p_ParticleDistribution swig_types[201]
+#define SWIGTYPE_p_ParticleLayout swig_types[202]
+#define SWIGTYPE_p_ParticleLimits swig_types[203]
+#define SWIGTYPE_p_PoissonNoiseBackground swig_types[204]
+#define SWIGTYPE_p_Polygon swig_types[205]
+#define SWIGTYPE_p_PolygonPrivate swig_types[206]
+#define SWIGTYPE_p_PolygonalTopology swig_types[207]
+#define SWIGTYPE_p_PolyhedralEdge swig_types[208]
+#define SWIGTYPE_p_PolyhedralFace swig_types[209]
+#define SWIGTYPE_p_PolyhedralTopology swig_types[210]
+#define SWIGTYPE_p_ProgressHandler__Callback_t swig_types[211]
+#define SWIGTYPE_p_PyBuilderCallback swig_types[212]
+#define SWIGTYPE_p_PyObserverCallback swig_types[213]
+#define SWIGTYPE_p_RealLimits swig_types[214]
+#define SWIGTYPE_p_RealParameter swig_types[215]
+#define SWIGTYPE_p_Rectangle swig_types[216]
+#define SWIGTYPE_p_RectangularDetector swig_types[217]
+#define SWIGTYPE_p_RectangularPixel swig_types[218]
+#define SWIGTYPE_p_RegionOfInterest swig_types[219]
+#define SWIGTYPE_p_ResolutionFunction2DGaussian swig_types[220]
+#define SWIGTYPE_p_RotationEuler swig_types[221]
+#define SWIGTYPE_p_RotationX swig_types[222]
+#define SWIGTYPE_p_RotationY swig_types[223]
+#define SWIGTYPE_p_RotationZ swig_types[224]
+#define SWIGTYPE_p_SafePointerVectorT_IParticle_t swig_types[225]
+#define SWIGTYPE_p_SafePointerVectorT_Layer_t swig_types[226]
+#define SWIGTYPE_p_SampleBuilderFactory swig_types[227]
+#define SWIGTYPE_p_SimpleSelectionRule swig_types[228]
+#define SWIGTYPE_p_Simulation swig_types[229]
+#define SWIGTYPE_p_Simulation2D swig_types[230]
+#define SWIGTYPE_p_SimulationFactory swig_types[231]
+#define SWIGTYPE_p_SimulationOptions swig_types[232]
+#define SWIGTYPE_p_SimulationResult swig_types[233]
+#define SWIGTYPE_p_SlicedParticle swig_types[234]
+#define SWIGTYPE_p_SlicingEffects swig_types[235]
+#define SWIGTYPE_p_SpecularDetector1D swig_types[236]
+#define SWIGTYPE_p_SpecularSimulation swig_types[237]
+#define SWIGTYPE_p_SphericalDetector swig_types[238]
+#define SWIGTYPE_p_SphericalPixel swig_types[239]
+#define SWIGTYPE_p_SquareLattice swig_types[240]
+#define SWIGTYPE_p_ThreadInfo swig_types[241]
+#define SWIGTYPE_p_Transform3D swig_types[242]
+#define SWIGTYPE_p_VariableBinAxis swig_types[243]
+#define SWIGTYPE_p_VarianceConstantFunction swig_types[244]
+#define SWIGTYPE_p_VarianceSimFunction swig_types[245]
+#define SWIGTYPE_p_VerticalLine swig_types[246]
+#define SWIGTYPE_p_WavevectorInfo swig_types[247]
+#define SWIGTYPE_p_ZLimits swig_types[248]
+#define SWIGTYPE_p_allocator_type swig_types[249]
+#define SWIGTYPE_p_bool swig_types[250]
+#define SWIGTYPE_p_char swig_types[251]
+#define SWIGTYPE_p_const_iterator swig_types[252]
+#define SWIGTYPE_p_const_reference swig_types[253]
+#define SWIGTYPE_p_corr_matrix_t swig_types[254]
+#define SWIGTYPE_p_difference_type swig_types[255]
+#define SWIGTYPE_p_double swig_types[256]
+#define SWIGTYPE_p_int swig_types[257]
+#define SWIGTYPE_p_iterator swig_types[258]
+#define SWIGTYPE_p_key_type swig_types[259]
+#define SWIGTYPE_p_long_long swig_types[260]
+#define SWIGTYPE_p_mapped_type swig_types[261]
+#define SWIGTYPE_p_observer_t swig_types[262]
+#define SWIGTYPE_p_p_PyObject swig_types[263]
+#define SWIGTYPE_p_parameters_t swig_types[264]
+#define SWIGTYPE_p_reference swig_types[265]
+#define SWIGTYPE_p_short swig_types[266]
+#define SWIGTYPE_p_signed_char swig_types[267]
+#define SWIGTYPE_p_size_type swig_types[268]
+#define SWIGTYPE_p_std__allocatorT_AxisInfo_t swig_types[269]
+#define SWIGTYPE_p_std__allocatorT_BasicVector3DT_double_t_t swig_types[270]
+#define SWIGTYPE_p_std__allocatorT_BasicVector3DT_std__complexT_double_t_t_t swig_types[271]
+#define SWIGTYPE_p_std__allocatorT_IFormFactor_p_t swig_types[272]
+#define SWIGTYPE_p_std__allocatorT_INode_const_p_t swig_types[273]
+#define SWIGTYPE_p_std__allocatorT_INode_p_t swig_types[274]
+#define SWIGTYPE_p_std__allocatorT_ParameterSample_t swig_types[275]
+#define SWIGTYPE_p_std__allocatorT_double_t swig_types[276]
+#define SWIGTYPE_p_std__allocatorT_int_t swig_types[277]
+#define SWIGTYPE_p_std__allocatorT_std__complexT_double_t_t swig_types[278]
+#define SWIGTYPE_p_std__allocatorT_std__pairT_std__string_const_double_t_t swig_types[279]
+#define SWIGTYPE_p_std__allocatorT_std__string_t swig_types[280]
+#define SWIGTYPE_p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t swig_types[281]
+#define SWIGTYPE_p_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t swig_types[282]
+#define SWIGTYPE_p_std__allocatorT_unsigned_long_t swig_types[283]
+#define SWIGTYPE_p_std__complexT_double_t swig_types[284]
+#define SWIGTYPE_p_std__functionT_IMultiLayerBuilder_pfF_t swig_types[285]
+#define SWIGTYPE_p_std__functionT_Simulation_pfF_t swig_types[286]
+#define SWIGTYPE_p_std__functionT_void_fF_t swig_types[287]
+#define SWIGTYPE_p_std__functionT_void_fSimulationAreaIterator_const_RF_t swig_types[288]
+#define SWIGTYPE_p_std__invalid_argument swig_types[289]
+#define SWIGTYPE_p_std__lessT_std__string_t swig_types[290]
+#define SWIGTYPE_p_std__mapT_std__string_double_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_double_t_t_t swig_types[291]
+#define SWIGTYPE_p_std__mapT_std__string_std__string_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_std__string_t_t_t__const_iterator swig_types[292]
+#define SWIGTYPE_p_std__pairT_double_double_t swig_types[293]
+#define SWIGTYPE_p_std__shared_ptrT_IMultiLayerBuilder_t swig_types[294]
+#define SWIGTYPE_p_std__shared_ptrT_IObserver_t swig_types[295]
+#define SWIGTYPE_p_std__vectorT_AxesUnitsWrap__AxesUnits_std__allocatorT_AxesUnitsWrap__AxesUnits_t_t swig_types[296]
+#define SWIGTYPE_p_std__vectorT_AxisInfo_std__allocatorT_AxisInfo_t_t swig_types[297]
+#define SWIGTYPE_p_std__vectorT_BasicVector3DT_double_t_std__allocatorT_BasicVector3DT_double_t_t_t swig_types[298]
+#define SWIGTYPE_p_std__vectorT_BasicVector3DT_std__complexT_double_t_t_std__allocatorT_BasicVector3DT_std__complexT_double_t_t_t_t swig_types[299]
+#define SWIGTYPE_p_std__vectorT_HomogeneousRegion_std__allocatorT_HomogeneousRegion_t_t swig_types[300]
+#define SWIGTYPE_p_std__vectorT_IFormFactor_p_std__allocatorT_IFormFactor_p_t_t swig_types[301]
+#define SWIGTYPE_p_std__vectorT_ILayout_const_p_std__allocatorT_ILayout_const_p_t_t swig_types[302]
+#define SWIGTYPE_p_std__vectorT_INode_const_p_std__allocatorT_INode_const_p_t_t swig_types[303]
+#define SWIGTYPE_p_std__vectorT_INode_p_std__allocatorT_INode_p_t_t swig_types[304]
+#define SWIGTYPE_p_std__vectorT_Material_const_p_std__allocatorT_Material_const_p_t_t swig_types[305]
+#define SWIGTYPE_p_std__vectorT_ParameterSample_std__allocatorT_ParameterSample_t_t swig_types[306]
+#define SWIGTYPE_p_std__vectorT_PolygonalTopology_std__allocatorT_PolygonalTopology_t_t swig_types[307]
+#define SWIGTYPE_p_std__vectorT_RealParameter_p_std__allocatorT_RealParameter_p_t_t swig_types[308]
+#define SWIGTYPE_p_std__vectorT_SimulationElement_std__allocatorT_SimulationElement_t_t swig_types[309]
+#define SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t swig_types[310]
+#define SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t swig_types[311]
+#define SWIGTYPE_p_std__vectorT_size_t_std__allocatorT_size_t_t_t swig_types[312]
+#define SWIGTYPE_p_std__vectorT_std__complexT_double_t_std__allocatorT_std__complexT_double_t_t_t swig_types[313]
+#define SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t swig_types[314]
+#define SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t swig_types[315]
+#define SWIGTYPE_p_std__vectorT_std__vectorT_int_std__allocatorT_int_t_t_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t_t swig_types[316]
+#define SWIGTYPE_p_std__vectorT_unsigned_int_std__allocatorT_unsigned_int_t_t swig_types[317]
+#define SWIGTYPE_p_std__vectorT_unsigned_long_std__allocatorT_unsigned_long_t_t swig_types[318]
+#define SWIGTYPE_p_swig__SwigPyIterator swig_types[319]
+#define SWIGTYPE_p_unsigned_char swig_types[320]
+#define SWIGTYPE_p_unsigned_int swig_types[321]
+#define SWIGTYPE_p_unsigned_long_long swig_types[322]
+#define SWIGTYPE_p_unsigned_short swig_types[323]
+#define SWIGTYPE_p_value_type swig_types[324]
+static swig_type_info *swig_types[326];
+static swig_module_info swig_module = {swig_types, 325, 0, 0, 0, 0};
 #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
 #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
 
@@ -7121,14 +7101,7 @@ SWIGINTERN void std_map_Sl_std_string_Sc_double_Sg__erase__SWIG_2(std::map< std:
 #include "FTDecayFunctions.h"
 #include "FTDistributions1D.h"
 #include "FTDistributions2D.h"
-#include "FitObject.h"
 #include "FitOptions.h"
-#include "IFitParameter.h"
-#include "FitParameterSet.h"
-#include "FitParameter.h"
-#include "FitSuite.h"
-#include "FitSuiteImpl.h"
-#include "FitSuiteObjects.h"
 #include "PyFittingCallbacks.h"
 #include "FitObjective.h"
 #include "FixedBinAxis.h"
@@ -7151,6 +7124,7 @@ SWIGINTERN void std_map_Sl_std_string_Sc_double_Sg__erase__SWIG_2(std::map< std:
 #include "FormFactorGauss.h"
 #include "FormFactorHemiEllipsoid.h"
 #include "FormFactorIcosahedron.h"
+#include "FormFactorLongBox.h"
 #include "FormFactorLongBoxGauss.h"
 #include "FormFactorLongBoxLorentz.h"
 #include "FormFactorLongRipple1Gauss.h"
@@ -7183,8 +7157,6 @@ SWIGINTERN void std_map_Sl_std_string_Sc_double_Sg__erase__SWIG_2(std::map< std:
 #include "IClusteredParticles.h"
 #include "IDetector2D.h"
 #include "IDetectorResolution.h"
-#include "IFitObserver.h"
-#include "IFitStrategy.h"
 #include "IFormFactorDecorator.h"
 #include "IHistogram.h"
 #include "IIntensityFunction.h"
@@ -7208,10 +7180,11 @@ SWIGINTERN void std_map_Sl_std_string_Sc_double_Sg__erase__SWIG_2(std::map< std:
 #include "IntensityDataIOFactory.h"
 #include "InterferenceFunction1DLattice.h"
 #include "InterferenceFunction2DLattice.h"
-#include "InterferenceFunction3DLattice.h"
-#include "InterferenceFunctionFinite2DLattice.h"
 #include "InterferenceFunction2DParaCrystal.h"
 #include "InterferenceFunction2DSuperLattice.h"
+#include "InterferenceFunction3DLattice.h"
+#include "InterferenceFunctionFinite2DLattice.h"
+#include "InterferenceFunctionFinite3DLattice.h"
 #include "InterferenceFunctionNone.h"
 #include "InterferenceFunctionRadialParaCrystal.h"
 #include "IsGISAXSDetector.h"
@@ -7264,8 +7237,7 @@ SWIGINTERN void std_map_Sl_std_string_Sc_double_Sg__erase__SWIG_2(std::map< std:
 #include "IChiSquaredModule.h"
 #include "IIntensityFunction.h"
 #include "IIntensityNormalizer.h"
-#include "ISquaredFunction.h"
-#include "AdjustMinimizerStrategy.h"
+#include "VarianceFunctions.h"
 #include "IterationInfo.h"
 
 
@@ -7831,6 +7803,13 @@ SWIG_AsVal_unsigned_SS_int (PyObject * obj, unsigned int *val)
 
 SWIGINTERN double VariableBinAxis___getitem__(VariableBinAxis *self,unsigned int i){ return (*(self))[i]; }
 
+SWIGINTERNINLINE PyObject*
+  SWIG_From_unsigned_SS_int  (unsigned int value)
+{
+  return PyInt_FromSize_t((size_t) value);
+}
+
+
 struct SWIG_null_deleter {
   void operator() (void const *) const {
   }
@@ -7843,33 +7822,6 @@ struct SWIG_null_deleter {
 
 #define SWIG_NO_NULL_DELETER_SWIG_BUILTIN_INIT
 
-
-SWIGINTERN int
-SWIG_AsVal_bool (PyObject *obj, bool *val)
-{
-  int r;
-  if (!PyBool_Check(obj))
-    return SWIG_ERROR;
-  r = PyObject_IsTrue(obj);
-  if (r == -1)
-    return SWIG_ERROR;
-  if (val) *val = r ? true : false;
-  return SWIG_OK;
-}
-
-SWIGINTERN IFitParameter const *FitParameterSet___getitem____SWIG_0(FitParameterSet const *self,std::string name){
-        return (*(self))[name];
-    }
-SWIGINTERN IFitParameter const *FitParameterSet___getitem____SWIG_1(FitParameterSet const *self,size_t index){
-        return (*(self))[index];
-    }
-
-SWIGINTERNINLINE PyObject*
-  SWIG_From_unsigned_SS_int  (unsigned int value)
-{
-  return PyInt_FromSize_t((size_t) value);
-}
-
 SWIGINTERN RealParameter *IMultiLayerBuilder_registerParameter(IMultiLayerBuilder *self,std::string const &name,int64_t parpointer){
         return &((self)->IParameterized::registerParameter(name, (double*)parpointer)); }
 SWIGINTERN void IMultiLayerBuilder_setParameterValue(IMultiLayerBuilder *self,std::string const &name,double value){
@@ -7886,6 +7838,20 @@ SWIGINTERN ParameterPool *IMultiLayerBuilder_parameterPool(IMultiLayerBuilder co
 SWIGINTERN void IMultiLayerBuilder_onChange(IMultiLayerBuilder *self){
         return (self)->IParameterized::onChange();
     }
+
+SWIGINTERN int
+SWIG_AsVal_bool (PyObject *obj, bool *val)
+{
+  int r;
+  if (!PyBool_Check(obj))
+    return SWIG_ERROR;
+  r = PyObject_IsTrue(obj);
+  if (r == -1)
+    return SWIG_ERROR;
+  if (val) *val = r ? true : false;
+  return SWIG_OK;
+}
+
 SWIGINTERN double FixedBinAxis___getitem__(FixedBinAxis *self,unsigned int i){ return (*(self))[i]; }
 
   namespace swig {
@@ -8740,29 +8706,34 @@ Material const *SwigDirector_ISample::material() const {
 }
 
 
-SwigDirector_IObservable::SwigDirector_IObservable(PyObject *self): IObservable(), Swig::Director(self) {
-  SWIG_DIRECTOR_RGTR((IObservable *)this, this); 
+SwigDirector_PyBuilderCallback::SwigDirector_PyBuilderCallback(PyObject *self): PyBuilderCallback(), Swig::Director(self) {
+  SWIG_DIRECTOR_RGTR((PyBuilderCallback *)this, this); 
 }
 
 
 
 
-SwigDirector_IObservable::~SwigDirector_IObservable() {
+SwigDirector_PyBuilderCallback::~SwigDirector_PyBuilderCallback() {
 }
 
-void SwigDirector_IObservable::attachObserver(IObservable::observer_t obj) {
+Simulation *SwigDirector_PyBuilderCallback::build_simulation(Fit::Parameters arg0) {
+  void *swig_argp ;
+  int swig_res ;
+  swig_owntype own ;
+  
+  Simulation *c_result;
   swig::SwigVar_PyObject obj0;
-  obj0 = SWIG_NewPointerObj(SWIG_as_voidptr(new IObservable::observer_t((const IObservable::observer_t &)obj)), SWIGTYPE_p_std__shared_ptrT_IObserver_t, SWIG_POINTER_OWN |  0 );
+  obj0 = SWIG_NewPointerObj(SWIG_as_voidptr(new Fit::Parameters((const Fit::Parameters &)arg0)), SWIGTYPE_p_Fit__Parameters, SWIG_POINTER_OWN |  0 );
   if (!swig_get_self()) {
-    Swig::DirectorException::raise("'self' uninitialized, maybe you forgot to call IObservable.__init__.");
+    Swig::DirectorException::raise("'self' uninitialized, maybe you forgot to call PyBuilderCallback.__init__.");
   }
 #if defined(SWIG_PYTHON_DIRECTOR_VTABLE)
   const size_t swig_method_index = 0;
-  const char *const swig_method_name = "attachObserver";
+  const char *const swig_method_name = "build_simulation";
   PyObject *method = swig_get_method(swig_method_index, swig_method_name);
   swig::SwigVar_PyObject result = PyObject_CallFunction(method, (char *)"(O)" ,(PyObject *)obj0);
 #else
-  swig::SwigVar_PyObject result = PyObject_CallMethod(swig_get_self(), (char *)"attachObserver", (char *)"(O)" ,(PyObject *)obj0);
+  swig::SwigVar_PyObject result = PyObject_CallMethod(swig_get_self(), (char *)"build_simulation", (char *)"(O)" ,(PyObject *)obj0);
 #endif
   if (!result) {
     PyObject *error = PyErr_Occurred();
@@ -8776,83 +8747,34 @@ void SwigDirector_IObservable::attachObserver(IObservable::observer_t obj) {
       }
     }
   }
-}
-
-
-void SwigDirector_IObservable::notifyObservers() {
-  if (!swig_get_self()) {
-    Swig::DirectorException::raise("'self' uninitialized, maybe you forgot to call IObservable.__init__.");
-  }
-#if defined(SWIG_PYTHON_DIRECTOR_VTABLE)
-  const size_t swig_method_index = 1;
-  const char *const swig_method_name = "notifyObservers";
-  PyObject *method = swig_get_method(swig_method_index, swig_method_name);
-  swig::SwigVar_PyObject result = PyObject_CallFunction(method, NULL, NULL);
-#else
-  swig::SwigVar_PyObject result = PyObject_CallMethod(swig_get_self(), (char *) "notifyObservers", NULL);
-#endif
-  if (!result) {
-    PyObject *error = PyErr_Occurred();
-    {
-      if( error != NULL ) {
-        PyObject *ptype, *pvalue, *ptraceback;
-        PyErr_Fetch( &ptype, &pvalue, &ptraceback );
-        PyErr_Restore( ptype, pvalue, ptraceback );
-        PyErr_Print();
-        Py_Exit(1);
-      }
-    }
+  swig_res = SWIG_ConvertPtrAndOwn(result, &swig_argp, SWIGTYPE_p_Simulation,  0  | SWIG_POINTER_DISOWN, &own);
+  if (!SWIG_IsOK(swig_res)) {
+    Swig::DirectorTypeMismatchException::raise(SWIG_ErrorType(SWIG_ArgError(swig_res)), "in output value of type '""Simulation *""'");
   }
+  c_result = reinterpret_cast< Simulation * >(swig_argp);
+  swig_acquire_ownership_obj(SWIG_as_voidptr(c_result), own /* & TODO: SWIG_POINTER_OWN */);
+  return (Simulation *) c_result;
 }
 
 
-SwigDirector_IFitObserver::SwigDirector_IFitObserver(PyObject *self, int update_every_nth): IFitObserver(update_every_nth), Swig::Director(self) {
-  SWIG_DIRECTOR_RGTR((IFitObserver *)this, this); 
+SwigDirector_PyObserverCallback::SwigDirector_PyObserverCallback(PyObject *self): PyObserverCallback(), Swig::Director(self) {
+  SWIG_DIRECTOR_RGTR((PyObserverCallback *)this, this); 
 }
 
 
 
 
-SwigDirector_IFitObserver::~SwigDirector_IFitObserver() {
+SwigDirector_PyObserverCallback::~SwigDirector_PyObserverCallback() {
 }
 
-void SwigDirector_IFitObserver::notify(IObservable *subject) {
+void SwigDirector_PyObserverCallback::update(FitObjective const &arg0) {
   swig::SwigVar_PyObject obj0;
-  obj0 = SWIG_NewPointerObj(SWIG_as_voidptr(subject), SWIGTYPE_p_IObservable,  0 );
+  obj0 = SWIG_NewPointerObj(SWIG_as_voidptr(&arg0), SWIGTYPE_p_FitObjective,  0 );
   if (!swig_get_self()) {
-    Swig::DirectorException::raise("'self' uninitialized, maybe you forgot to call IFitObserver.__init__.");
+    Swig::DirectorException::raise("'self' uninitialized, maybe you forgot to call PyObserverCallback.__init__.");
   }
 #if defined(SWIG_PYTHON_DIRECTOR_VTABLE)
   const size_t swig_method_index = 0;
-  const char *const swig_method_name = "notify";
-  PyObject *method = swig_get_method(swig_method_index, swig_method_name);
-  swig::SwigVar_PyObject result = PyObject_CallFunction(method, (char *)"(O)" ,(PyObject *)obj0);
-#else
-  swig::SwigVar_PyObject result = PyObject_CallMethod(swig_get_self(), (char *)"notify", (char *)"(O)" ,(PyObject *)obj0);
-#endif
-  if (!result) {
-    PyObject *error = PyErr_Occurred();
-    {
-      if( error != NULL ) {
-        PyObject *ptype, *pvalue, *ptraceback;
-        PyErr_Fetch( &ptype, &pvalue, &ptraceback );
-        PyErr_Restore( ptype, pvalue, ptraceback );
-        PyErr_Print();
-        Py_Exit(1);
-      }
-    }
-  }
-}
-
-
-void SwigDirector_IFitObserver::update(FitSuite *fit_suite) {
-  swig::SwigVar_PyObject obj0;
-  obj0 = SWIG_NewPointerObj(SWIG_as_voidptr(fit_suite), SWIGTYPE_p_FitSuite,  0 );
-  if (!swig_get_self()) {
-    Swig::DirectorException::raise("'self' uninitialized, maybe you forgot to call IFitObserver.__init__.");
-  }
-#if defined(SWIG_PYTHON_DIRECTOR_VTABLE)
-  const size_t swig_method_index = 1;
   const char *const swig_method_name = "update";
   PyObject *method = swig_get_method(swig_method_index, swig_method_name);
   swig::SwigVar_PyObject result = PyObject_CallFunction(method, (char *)"(O)" ,(PyObject *)obj0);
@@ -8874,34 +8796,30 @@ void SwigDirector_IFitObserver::update(FitSuite *fit_suite) {
 }
 
 
-SwigDirector_PyBuilderCallback::SwigDirector_PyBuilderCallback(PyObject *self): PyBuilderCallback(), Swig::Director(self) {
-  SWIG_DIRECTOR_RGTR((PyBuilderCallback *)this, this); 
+SwigDirector_FitObjective::SwigDirector_FitObjective(PyObject *self): FitObjective(), Swig::Director(self) {
+  SWIG_DIRECTOR_RGTR((FitObjective *)this, this); 
 }
 
 
 
 
-SwigDirector_PyBuilderCallback::~SwigDirector_PyBuilderCallback() {
+SwigDirector_FitObjective::~SwigDirector_FitObjective() {
 }
 
-Simulation *SwigDirector_PyBuilderCallback::build_simulation(Fit::Parameters arg0) {
-  void *swig_argp ;
-  int swig_res ;
-  swig_owntype own ;
-  
-  Simulation *c_result;
+double SwigDirector_FitObjective::evaluate(Fit::Parameters const &params) {
+  double c_result;
   swig::SwigVar_PyObject obj0;
-  obj0 = SWIG_NewPointerObj(SWIG_as_voidptr(new Fit::Parameters((const Fit::Parameters &)arg0)), SWIGTYPE_p_Fit__Parameters, SWIG_POINTER_OWN |  0 );
+  obj0 = SWIG_NewPointerObj(SWIG_as_voidptr(&params), SWIGTYPE_p_Fit__Parameters,  0 );
   if (!swig_get_self()) {
-    Swig::DirectorException::raise("'self' uninitialized, maybe you forgot to call PyBuilderCallback.__init__.");
+    Swig::DirectorException::raise("'self' uninitialized, maybe you forgot to call FitObjective.__init__.");
   }
 #if defined(SWIG_PYTHON_DIRECTOR_VTABLE)
   const size_t swig_method_index = 0;
-  const char *const swig_method_name = "build_simulation";
+  const char *const swig_method_name = "evaluate_cpp";
   PyObject *method = swig_get_method(swig_method_index, swig_method_name);
   swig::SwigVar_PyObject result = PyObject_CallFunction(method, (char *)"(O)" ,(PyObject *)obj0);
 #else
-  swig::SwigVar_PyObject result = PyObject_CallMethod(swig_get_self(), (char *)"build_simulation", (char *)"(O)" ,(PyObject *)obj0);
+  swig::SwigVar_PyObject result = PyObject_CallMethod(swig_get_self(), (char *)"evaluate_cpp", (char *)"(O)" ,(PyObject *)obj0);
 #endif
   if (!result) {
     PyObject *error = PyErr_Occurred();
@@ -8915,39 +8833,30 @@ Simulation *SwigDirector_PyBuilderCallback::build_simulation(Fit::Parameters arg
       }
     }
   }
-  swig_res = SWIG_ConvertPtrAndOwn(result, &swig_argp, SWIGTYPE_p_Simulation,  0  | SWIG_POINTER_DISOWN, &own);
+  double swig_val;
+  int swig_res = SWIG_AsVal_double(result, &swig_val);
   if (!SWIG_IsOK(swig_res)) {
-    Swig::DirectorTypeMismatchException::raise(SWIG_ErrorType(SWIG_ArgError(swig_res)), "in output value of type '""Simulation *""'");
+    Swig::DirectorTypeMismatchException::raise(SWIG_ErrorType(SWIG_ArgError(swig_res)), "in output value of type '""double""'");
   }
-  c_result = reinterpret_cast< Simulation * >(swig_argp);
-  swig_acquire_ownership_obj(SWIG_as_voidptr(c_result), own /* & TODO: SWIG_POINTER_OWN */);
-  return (Simulation *) c_result;
-}
-
-
-SwigDirector_PyObserverCallback::SwigDirector_PyObserverCallback(PyObject *self): PyObserverCallback(), Swig::Director(self) {
-  SWIG_DIRECTOR_RGTR((PyObserverCallback *)this, this); 
+  c_result = static_cast< double >(swig_val);
+  return (double) c_result;
 }
 
 
-
-
-SwigDirector_PyObserverCallback::~SwigDirector_PyObserverCallback() {
-}
-
-void SwigDirector_PyObserverCallback::update(FitObjective const &arg0) {
+std::vector< double,std::allocator< double > > SwigDirector_FitObjective::evaluate_residuals(Fit::Parameters const &params) {
+  std::vector< double,std::allocator< double > > c_result;
   swig::SwigVar_PyObject obj0;
-  obj0 = SWIG_NewPointerObj(SWIG_as_voidptr(&arg0), SWIGTYPE_p_FitObjective,  0 );
+  obj0 = SWIG_NewPointerObj(SWIG_as_voidptr(&params), SWIGTYPE_p_Fit__Parameters,  0 );
   if (!swig_get_self()) {
-    Swig::DirectorException::raise("'self' uninitialized, maybe you forgot to call PyObserverCallback.__init__.");
+    Swig::DirectorException::raise("'self' uninitialized, maybe you forgot to call FitObjective.__init__.");
   }
 #if defined(SWIG_PYTHON_DIRECTOR_VTABLE)
-  const size_t swig_method_index = 0;
-  const char *const swig_method_name = "update";
+  const size_t swig_method_index = 1;
+  const char *const swig_method_name = "evaluate_residuals_cpp";
   PyObject *method = swig_get_method(swig_method_index, swig_method_name);
   swig::SwigVar_PyObject result = PyObject_CallFunction(method, (char *)"(O)" ,(PyObject *)obj0);
 #else
-  swig::SwigVar_PyObject result = PyObject_CallMethod(swig_get_self(), (char *)"update", (char *)"(O)" ,(PyObject *)obj0);
+  swig::SwigVar_PyObject result = PyObject_CallMethod(swig_get_self(), (char *)"evaluate_residuals_cpp", (char *)"(O)" ,(PyObject *)obj0);
 #endif
   if (!result) {
     PyObject *error = PyErr_Occurred();
@@ -8961,6 +8870,14 @@ void SwigDirector_PyObserverCallback::update(FitObjective const &arg0) {
       }
     }
   }
+  std::vector< double,std::allocator< double > > *swig_optr = 0;
+  int swig_ores = swig::asptr(result, &swig_optr);
+  if (!SWIG_IsOK(swig_ores) || !swig_optr) {
+    Swig::DirectorTypeMismatchException::raise(SWIG_ErrorType(SWIG_ArgError((swig_optr ? swig_ores : SWIG_TypeError))), "in output value of type '""std::vector< double,std::allocator< double > >""'");
+  }
+  c_result = *swig_optr;
+  if (SWIG_IsNewObj(swig_ores)) delete swig_optr;
+  return (std::vector< double,std::allocator< double > >) c_result;
 }
 
 
@@ -42721,228 +42638,32 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_IChiSquaredModule_getSquaredFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IChiSquaredModule *arg1 = (IChiSquaredModule *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  ISquaredFunction *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:IChiSquaredModule_getSquaredFunction",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IChiSquaredModule, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IChiSquaredModule_getSquaredFunction" "', argument " "1"" of type '" "IChiSquaredModule const *""'"); 
-  }
-  arg1 = reinterpret_cast< IChiSquaredModule * >(argp1);
-  result = (ISquaredFunction *)((IChiSquaredModule const *)arg1)->getSquaredFunction();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ISquaredFunction, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IChiSquaredModule_setChiSquaredFunction__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IChiSquaredModule *arg1 = (IChiSquaredModule *) 0 ;
-  ISquaredFunction *arg2 = (ISquaredFunction *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:IChiSquaredModule_setChiSquaredFunction",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IChiSquaredModule, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IChiSquaredModule_setChiSquaredFunction" "', argument " "1"" of type '" "IChiSquaredModule *""'"); 
-  }
-  arg1 = reinterpret_cast< IChiSquaredModule * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_ISquaredFunction, 0 |  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IChiSquaredModule_setChiSquaredFunction" "', argument " "2"" of type '" "ISquaredFunction *""'"); 
-  }
-  arg2 = reinterpret_cast< ISquaredFunction * >(argp2);
-  (arg1)->setChiSquaredFunction(arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IChiSquaredModule_setChiSquaredFunction__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_IChiSquaredModule_varianceFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   IChiSquaredModule *arg1 = (IChiSquaredModule *) 0 ;
-  ISquaredFunction *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  IVarianceFunction *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:IChiSquaredModule_setChiSquaredFunction",&obj0,&obj1)) SWIG_fail;
+  if (!PyArg_ParseTuple(args,(char *)"O:IChiSquaredModule_varianceFunction",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IChiSquaredModule, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IChiSquaredModule_setChiSquaredFunction" "', argument " "1"" of type '" "IChiSquaredModule *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IChiSquaredModule_varianceFunction" "', argument " "1"" of type '" "IChiSquaredModule const *""'"); 
   }
   arg1 = reinterpret_cast< IChiSquaredModule * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_ISquaredFunction,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IChiSquaredModule_setChiSquaredFunction" "', argument " "2"" of type '" "ISquaredFunction const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IChiSquaredModule_setChiSquaredFunction" "', argument " "2"" of type '" "ISquaredFunction const &""'"); 
-  }
-  arg2 = reinterpret_cast< ISquaredFunction * >(argp2);
-  (arg1)->setChiSquaredFunction((ISquaredFunction const &)*arg2);
-  resultobj = SWIG_Py_Void();
+  result = (IVarianceFunction *)((IChiSquaredModule const *)arg1)->varianceFunction();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IVarianceFunction, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_IChiSquaredModule_setChiSquaredFunction(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[3] = {
-    0
-  };
-  Py_ssize_t ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 2) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_IChiSquaredModule, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_ISquaredFunction, 0);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        return _wrap_IChiSquaredModule_setChiSquaredFunction__SWIG_0(self, args);
-      }
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_IChiSquaredModule, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_ISquaredFunction, 0);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        return _wrap_IChiSquaredModule_setChiSquaredFunction__SWIG_1(self, args);
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'IChiSquaredModule_setChiSquaredFunction'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    IChiSquaredModule::setChiSquaredFunction(ISquaredFunction *)\n"
-    "    IChiSquaredModule::setChiSquaredFunction(ISquaredFunction const &)\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_IChiSquaredModule_getIntensityNormalizer__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IChiSquaredModule *arg1 = (IChiSquaredModule *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  IIntensityNormalizer *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:IChiSquaredModule_getIntensityNormalizer",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IChiSquaredModule, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IChiSquaredModule_getIntensityNormalizer" "', argument " "1"" of type '" "IChiSquaredModule const *""'"); 
-  }
-  arg1 = reinterpret_cast< IChiSquaredModule * >(argp1);
-  result = (IIntensityNormalizer *)((IChiSquaredModule const *)arg1)->getIntensityNormalizer();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IIntensityNormalizer, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IChiSquaredModule_getIntensityNormalizer__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IChiSquaredModule *arg1 = (IChiSquaredModule *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  IIntensityNormalizer *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:IChiSquaredModule_getIntensityNormalizer",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IChiSquaredModule, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IChiSquaredModule_getIntensityNormalizer" "', argument " "1"" of type '" "IChiSquaredModule *""'"); 
-  }
-  arg1 = reinterpret_cast< IChiSquaredModule * >(argp1);
-  result = (IIntensityNormalizer *)(arg1)->getIntensityNormalizer();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IIntensityNormalizer, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IChiSquaredModule_getIntensityNormalizer(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[2] = {
-    0
-  };
-  Py_ssize_t ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 1) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_IChiSquaredModule, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_IChiSquaredModule_getIntensityNormalizer__SWIG_1(self, args);
-    }
-  }
-  if (argc == 1) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_IChiSquaredModule, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_IChiSquaredModule_getIntensityNormalizer__SWIG_0(self, args);
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'IChiSquaredModule_getIntensityNormalizer'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    IChiSquaredModule::getIntensityNormalizer() const\n"
-    "    IChiSquaredModule::getIntensityNormalizer()\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_IChiSquaredModule_setIntensityNormalizer(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_IChiSquaredModule_setVarianceFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   IChiSquaredModule *arg1 = (IChiSquaredModule *) 0 ;
-  IIntensityNormalizer *arg2 = 0 ;
+  IVarianceFunction *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
@@ -42950,21 +42671,21 @@ SWIGINTERN PyObject *_wrap_IChiSquaredModule_setIntensityNormalizer(PyObject *SW
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:IChiSquaredModule_setIntensityNormalizer",&obj0,&obj1)) SWIG_fail;
+  if (!PyArg_ParseTuple(args,(char *)"OO:IChiSquaredModule_setVarianceFunction",&obj0,&obj1)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IChiSquaredModule, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IChiSquaredModule_setIntensityNormalizer" "', argument " "1"" of type '" "IChiSquaredModule *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IChiSquaredModule_setVarianceFunction" "', argument " "1"" of type '" "IChiSquaredModule *""'"); 
   }
   arg1 = reinterpret_cast< IChiSquaredModule * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_IIntensityNormalizer,  0  | 0);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_IVarianceFunction,  0  | 0);
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IChiSquaredModule_setIntensityNormalizer" "', argument " "2"" of type '" "IIntensityNormalizer const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IChiSquaredModule_setVarianceFunction" "', argument " "2"" of type '" "IVarianceFunction const &""'"); 
   }
   if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IChiSquaredModule_setIntensityNormalizer" "', argument " "2"" of type '" "IIntensityNormalizer const &""'"); 
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IChiSquaredModule_setVarianceFunction" "', argument " "2"" of type '" "IVarianceFunction const &""'"); 
   }
-  arg2 = reinterpret_cast< IIntensityNormalizer * >(argp2);
-  (arg1)->setIntensityNormalizer((IIntensityNormalizer const &)*arg2);
+  arg2 = reinterpret_cast< IVarianceFunction * >(argp2);
+  (arg1)->setVarianceFunction((IVarianceFunction const &)*arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -43027,61 +42748,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_IChiSquaredModule_processFitElements(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IChiSquaredModule *arg1 = (IChiSquaredModule *) 0 ;
-  SwigValueWrapper< std::vector< FitElement,std::allocator< FitElement > >::iterator > arg2 ;
-  SwigValueWrapper< std::vector< FitElement,std::allocator< FitElement > >::iterator > arg3 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 ;
-  int res2 = 0 ;
-  void *argp3 ;
-  int res3 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOO:IChiSquaredModule_processFitElements",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IChiSquaredModule, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IChiSquaredModule_processFitElements" "', argument " "1"" of type '" "IChiSquaredModule *""'"); 
-  }
-  arg1 = reinterpret_cast< IChiSquaredModule * >(argp1);
-  {
-    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__vectorT_FitElement_std__allocatorT_FitElement_t_t__iterator,  0  | 0);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IChiSquaredModule_processFitElements" "', argument " "2"" of type '" "std::vector< FitElement,std::allocator< FitElement > >::iterator""'"); 
-    }  
-    if (!argp2) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IChiSquaredModule_processFitElements" "', argument " "2"" of type '" "std::vector< FitElement,std::allocator< FitElement > >::iterator""'");
-    } else {
-      std::vector< FitElement,std::allocator< FitElement > >::iterator * temp = reinterpret_cast< std::vector< FitElement,std::allocator< FitElement > >::iterator * >(argp2);
-      arg2 = *temp;
-      if (SWIG_IsNewObj(res2)) delete temp;
-    }
-  }
-  {
-    res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_std__vectorT_FitElement_std__allocatorT_FitElement_t_t__iterator,  0  | 0);
-    if (!SWIG_IsOK(res3)) {
-      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "IChiSquaredModule_processFitElements" "', argument " "3"" of type '" "std::vector< FitElement,std::allocator< FitElement > >::iterator""'"); 
-    }  
-    if (!argp3) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IChiSquaredModule_processFitElements" "', argument " "3"" of type '" "std::vector< FitElement,std::allocator< FitElement > >::iterator""'");
-    } else {
-      std::vector< FitElement,std::allocator< FitElement > >::iterator * temp = reinterpret_cast< std::vector< FitElement,std::allocator< FitElement > >::iterator * >(argp3);
-      arg3 = *temp;
-      if (SWIG_IsNewObj(res3)) delete temp;
-    }
-  }
-  (arg1)->processFitElements(arg2,arg3);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_IChiSquaredModule_residual(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   IChiSquaredModule *arg1 = (IChiSquaredModule *) 0 ;
@@ -43143,27 +42809,15 @@ SWIGINTERN PyObject *_wrap_delete_IObserver(PyObject *SWIGUNUSEDPARM(self), PyOb
   IObserver *arg1 = (IObserver *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::shared_ptr< IObserver > tempshared1 ;
-  std::shared_ptr< IObserver > *smartarg1 = 0 ;
   PyObject * obj0 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:delete_IObserver",&obj0)) SWIG_fail;
-  {
-    int newmem = 0;
-    res1 = SWIG_ConvertPtrAndOwn(obj0, &argp1, SWIGTYPE_p_std__shared_ptrT_IObserver_t, 0 |  0 , &newmem);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IObserver" "', argument " "1"" of type '" "IObserver *""'"); 
-    }
-    if (newmem & SWIG_CAST_NEW_MEMORY) {
-      tempshared1 = *reinterpret_cast< std::shared_ptr<  IObserver > * >(argp1);
-      delete reinterpret_cast< std::shared_ptr<  IObserver > * >(argp1);
-      arg1 = const_cast< IObserver * >(tempshared1.get());
-    } else {
-      smartarg1 = reinterpret_cast< std::shared_ptr<  IObserver > * >(argp1);
-      arg1 = const_cast< IObserver * >((smartarg1 ? smartarg1->get() : 0));
-    }
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IObserver, SWIG_POINTER_DISOWN |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IObserver" "', argument " "1"" of type '" "IObserver *""'"); 
   }
-  (void)arg1; delete smartarg1;
+  arg1 = reinterpret_cast< IObserver * >(argp1);
+  delete arg1;
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -43177,29 +42831,17 @@ SWIGINTERN PyObject *_wrap_IObserver_notify(PyObject *SWIGUNUSEDPARM(self), PyOb
   IObservable *arg2 = (IObservable *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::shared_ptr< IObserver > tempshared1 ;
-  std::shared_ptr< IObserver > *smartarg1 = 0 ;
   void *argp2 = 0 ;
   int res2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OO:IObserver_notify",&obj0,&obj1)) SWIG_fail;
-  {
-    int newmem = 0;
-    res1 = SWIG_ConvertPtrAndOwn(obj0, &argp1, SWIGTYPE_p_std__shared_ptrT_IObserver_t, 0 |  0 , &newmem);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IObserver_notify" "', argument " "1"" of type '" "IObserver *""'"); 
-    }
-    if (newmem & SWIG_CAST_NEW_MEMORY) {
-      tempshared1 = *reinterpret_cast< std::shared_ptr<  IObserver > * >(argp1);
-      delete reinterpret_cast< std::shared_ptr<  IObserver > * >(argp1);
-      arg1 = const_cast< IObserver * >(tempshared1.get());
-    } else {
-      smartarg1 = reinterpret_cast< std::shared_ptr<  IObserver > * >(argp1);
-      arg1 = const_cast< IObserver * >((smartarg1 ? smartarg1->get() : 0));
-    }
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IObserver, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IObserver_notify" "', argument " "1"" of type '" "IObserver *""'"); 
   }
+  arg1 = reinterpret_cast< IObserver * >(argp1);
   res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_IObservable, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
     SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IObserver_notify" "', argument " "2"" of type '" "IObservable *""'"); 
@@ -43216,7 +42858,7 @@ fail:
 SWIGINTERN PyObject *IObserver_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
   if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_IObserver_t, SWIG_NewClientData(obj));
+  SWIG_TypeNewClientData(SWIGTYPE_p_IObserver, SWIG_NewClientData(obj));
   return SWIG_Py_Void();
 }
 
@@ -43244,15 +42886,13 @@ fail:
 SWIGINTERN PyObject *_wrap_IObservable_attachObserver(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   IObservable *arg1 = (IObservable *) 0 ;
-  IObservable::observer_t arg2 ;
+  SwigValueWrapper< std::shared_ptr< IObserver > > arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 ;
   int res2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  Swig::Director *director = 0;
-  bool upcall = false;
   
   if (!PyArg_ParseTuple(args,(char *)"OO:IObservable_attachObserver",&obj0,&obj1)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IObservable, 0 |  0 );
@@ -43261,25 +42901,19 @@ SWIGINTERN PyObject *_wrap_IObservable_attachObserver(PyObject *SWIGUNUSEDPARM(s
   }
   arg1 = reinterpret_cast< IObservable * >(argp1);
   {
-    int newmem = 0;
-    res2 = SWIG_ConvertPtrAndOwn(obj1, &argp2, SWIGTYPE_p_std__shared_ptrT_IObserver_t,  0 , &newmem);
+    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__shared_ptrT_IObserver_t,  0  | 0);
     if (!SWIG_IsOK(res2)) {
       SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IObservable_attachObserver" "', argument " "2"" of type '" "IObservable::observer_t""'"); 
-    }
-    if (argp2) arg2 = *(reinterpret_cast< IObservable::observer_t * >(argp2));
-    if (newmem & SWIG_CAST_NEW_MEMORY) delete reinterpret_cast< IObservable::observer_t * >(argp2);
-  }
-  director = SWIG_DIRECTOR_CAST(arg1);
-  upcall = (director && (director->swig_get_self()==obj0));
-  try {
-    if (upcall) {
-      (arg1)->IObservable::attachObserver(arg2);
+    }  
+    if (!argp2) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IObservable_attachObserver" "', argument " "2"" of type '" "IObservable::observer_t""'");
     } else {
-      (arg1)->attachObserver(arg2);
+      IObservable::observer_t * temp = reinterpret_cast< IObservable::observer_t * >(argp2);
+      arg2 = *temp;
+      if (SWIG_IsNewObj(res2)) delete temp;
     }
-  } catch (Swig::DirectorException&) {
-    SWIG_fail;
   }
+  (arg1)->attachObserver(arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -43293,8 +42927,6 @@ SWIGINTERN PyObject *_wrap_IObservable_notifyObservers(PyObject *SWIGUNUSEDPARM(
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  Swig::Director *director = 0;
-  bool upcall = false;
   
   if (!PyArg_ParseTuple(args,(char *)"O:IObservable_notifyObservers",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IObservable, 0 |  0 );
@@ -43302,17 +42934,7 @@ SWIGINTERN PyObject *_wrap_IObservable_notifyObservers(PyObject *SWIGUNUSEDPARM(
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IObservable_notifyObservers" "', argument " "1"" of type '" "IObservable *""'"); 
   }
   arg1 = reinterpret_cast< IObservable * >(argp1);
-  director = SWIG_DIRECTOR_CAST(arg1);
-  upcall = (director && (director->swig_get_self()==obj0));
-  try {
-    if (upcall) {
-      (arg1)->IObservable::notifyObservers();
-    } else {
-      (arg1)->notifyObservers();
-    }
-  } catch (Swig::DirectorException&) {
-    SWIG_fail;
-  }
+  (arg1)->notifyObservers();
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -43322,19 +42944,10 @@ fail:
 
 SWIGINTERN PyObject *_wrap_new_IObservable(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  PyObject *arg1 = (PyObject *) 0 ;
-  PyObject * obj0 = 0 ;
   IObservable *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:new_IObservable",&obj0)) SWIG_fail;
-  arg1 = obj0;
-  if ( arg1 != Py_None ) {
-    /* subclassed */
-    result = (IObservable *)new SwigDirector_IObservable(arg1); 
-  } else {
-    result = (IObservable *)new IObservable(); 
-  }
-  
+  if (!PyArg_ParseTuple(args,(char *)":new_IObservable")) SWIG_fail;
+  result = (IObservable *)new IObservable();
   resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IObservable, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
@@ -43342,31 +42955,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_disown_IObservable(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IObservable *arg1 = (IObservable *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:disown_IObservable",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IObservable, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "disown_IObservable" "', argument " "1"" of type '" "IObservable *""'"); 
-  }
-  arg1 = reinterpret_cast< IObservable * >(argp1);
-  {
-    Swig::Director *director = SWIG_DIRECTOR_CAST(arg1);
-    if (director) director->swig_disown();
-  }
-  
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *IObservable_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
   if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
@@ -43374,410 +42962,6 @@ SWIGINTERN PyObject *IObservable_swigregister(PyObject *SWIGUNUSEDPARM(self), Py
   return SWIG_Py_Void();
 }
 
-SWIGINTERN PyObject *_wrap_new_IFitObserver(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  PyObject *arg1 = (PyObject *) 0 ;
-  int arg2 ;
-  int val2 ;
-  int ecode2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  IFitObserver *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:new_IFitObserver",&obj0,&obj1)) SWIG_fail;
-  arg1 = obj0;
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_IFitObserver" "', argument " "2"" of type '" "int""'");
-  } 
-  arg2 = static_cast< int >(val2);
-  if ( arg1 != Py_None ) {
-    /* subclassed */
-    result = (IFitObserver *)new SwigDirector_IFitObserver(arg1,arg2); 
-  } else {
-    result = (IFitObserver *)new IFitObserver(arg2); 
-  }
-  
-  {
-    std::shared_ptr<  IFitObserver > *smartresult = result ? new std::shared_ptr<  IFitObserver >(result SWIG_NO_NULL_DELETER_SWIG_POINTER_NEW) : 0;
-    resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_std__shared_ptrT_IFitObserver_t, SWIG_POINTER_NEW | SWIG_POINTER_OWN);
-  }
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IFitObserver_notify(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IFitObserver *arg1 = (IFitObserver *) 0 ;
-  IObservable *arg2 = (IObservable *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  std::shared_ptr< IFitObserver > tempshared1 ;
-  std::shared_ptr< IFitObserver > *smartarg1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  Swig::Director *director = 0;
-  bool upcall = false;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:IFitObserver_notify",&obj0,&obj1)) SWIG_fail;
-  {
-    int newmem = 0;
-    res1 = SWIG_ConvertPtrAndOwn(obj0, &argp1, SWIGTYPE_p_std__shared_ptrT_IFitObserver_t, 0 |  0 , &newmem);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFitObserver_notify" "', argument " "1"" of type '" "IFitObserver *""'"); 
-    }
-    if (newmem & SWIG_CAST_NEW_MEMORY) {
-      tempshared1 = *reinterpret_cast< std::shared_ptr<  IFitObserver > * >(argp1);
-      delete reinterpret_cast< std::shared_ptr<  IFitObserver > * >(argp1);
-      arg1 = const_cast< IFitObserver * >(tempshared1.get());
-    } else {
-      smartarg1 = reinterpret_cast< std::shared_ptr<  IFitObserver > * >(argp1);
-      arg1 = const_cast< IFitObserver * >((smartarg1 ? smartarg1->get() : 0));
-    }
-  }
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_IObservable, 0 |  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IFitObserver_notify" "', argument " "2"" of type '" "IObservable *""'"); 
-  }
-  arg2 = reinterpret_cast< IObservable * >(argp2);
-  director = SWIG_DIRECTOR_CAST(arg1);
-  upcall = (director && (director->swig_get_self()==obj0));
-  try {
-    if (upcall) {
-      (arg1)->IFitObserver::notify(arg2);
-    } else {
-      (arg1)->notify(arg2);
-    }
-  } catch (Swig::DirectorException&) {
-    SWIG_fail;
-  }
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IFitObserver_update(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IFitObserver *arg1 = (IFitObserver *) 0 ;
-  FitSuite *arg2 = (FitSuite *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  std::shared_ptr< IFitObserver > tempshared1 ;
-  std::shared_ptr< IFitObserver > *smartarg1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  Swig::Director *director = 0;
-  bool upcall = false;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:IFitObserver_update",&obj0,&obj1)) SWIG_fail;
-  {
-    int newmem = 0;
-    res1 = SWIG_ConvertPtrAndOwn(obj0, &argp1, SWIGTYPE_p_std__shared_ptrT_IFitObserver_t, 0 |  0 , &newmem);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFitObserver_update" "', argument " "1"" of type '" "IFitObserver *""'"); 
-    }
-    if (newmem & SWIG_CAST_NEW_MEMORY) {
-      tempshared1 = *reinterpret_cast< std::shared_ptr<  IFitObserver > * >(argp1);
-      delete reinterpret_cast< std::shared_ptr<  IFitObserver > * >(argp1);
-      arg1 = const_cast< IFitObserver * >(tempshared1.get());
-    } else {
-      smartarg1 = reinterpret_cast< std::shared_ptr<  IFitObserver > * >(argp1);
-      arg1 = const_cast< IFitObserver * >((smartarg1 ? smartarg1->get() : 0));
-    }
-  }
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IFitObserver_update" "', argument " "2"" of type '" "FitSuite *""'"); 
-  }
-  arg2 = reinterpret_cast< FitSuite * >(argp2);
-  director = SWIG_DIRECTOR_CAST(arg1);
-  upcall = (director && (director->swig_get_self()==obj0));
-  try {
-    if (upcall) {
-      (arg1)->IFitObserver::update(arg2);
-    } else {
-      (arg1)->update(arg2);
-    }
-  } catch (Swig::DirectorException&) {
-    SWIG_fail;
-  }
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_delete_IFitObserver(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IFitObserver *arg1 = (IFitObserver *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  std::shared_ptr< IFitObserver > tempshared1 ;
-  std::shared_ptr< IFitObserver > *smartarg1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_IFitObserver",&obj0)) SWIG_fail;
-  {
-    int newmem = 0;
-    res1 = SWIG_ConvertPtrAndOwn(obj0, &argp1, SWIGTYPE_p_std__shared_ptrT_IFitObserver_t, 0 |  0 , &newmem);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IFitObserver" "', argument " "1"" of type '" "IFitObserver *""'"); 
-    }
-    if (newmem & SWIG_CAST_NEW_MEMORY) {
-      tempshared1 = *reinterpret_cast< std::shared_ptr<  IFitObserver > * >(argp1);
-      delete reinterpret_cast< std::shared_ptr<  IFitObserver > * >(argp1);
-      arg1 = const_cast< IFitObserver * >(tempshared1.get());
-    } else {
-      smartarg1 = reinterpret_cast< std::shared_ptr<  IFitObserver > * >(argp1);
-      arg1 = const_cast< IFitObserver * >((smartarg1 ? smartarg1->get() : 0));
-    }
-  }
-  (void)arg1; delete smartarg1;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_disown_IFitObserver(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IFitObserver *arg1 = (IFitObserver *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  std::shared_ptr< IFitObserver > tempshared1 ;
-  std::shared_ptr< IFitObserver > *smartarg1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:disown_IFitObserver",&obj0)) SWIG_fail;
-  {
-    int newmem = 0;
-    res1 = SWIG_ConvertPtrAndOwn(obj0, &argp1, SWIGTYPE_p_std__shared_ptrT_IFitObserver_t, 0 |  0 , &newmem);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "disown_IFitObserver" "', argument " "1"" of type '" "IFitObserver *""'"); 
-    }
-    if (newmem & SWIG_CAST_NEW_MEMORY) {
-      tempshared1 = *reinterpret_cast< std::shared_ptr<  IFitObserver > * >(argp1);
-      delete reinterpret_cast< std::shared_ptr<  IFitObserver > * >(argp1);
-      arg1 = const_cast< IFitObserver * >(tempshared1.get());
-    } else {
-      smartarg1 = reinterpret_cast< std::shared_ptr<  IFitObserver > * >(argp1);
-      arg1 = const_cast< IFitObserver * >((smartarg1 ? smartarg1->get() : 0));
-    }
-  }
-  {
-    Swig::Director *director = SWIG_DIRECTOR_CAST(arg1);
-    if (director) director->swig_disown();
-  }
-  
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *IFitObserver_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_std__shared_ptrT_IFitObserver_t, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *_wrap_delete_IFitStrategy(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IFitStrategy *arg1 = (IFitStrategy *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_IFitStrategy",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IFitStrategy, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IFitStrategy" "', argument " "1"" of type '" "IFitStrategy *""'"); 
-  }
-  arg1 = reinterpret_cast< IFitStrategy * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IFitStrategy_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IFitStrategy *arg1 = (IFitStrategy *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  IFitStrategy *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:IFitStrategy_clone",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IFitStrategy, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFitStrategy_clone" "', argument " "1"" of type '" "IFitStrategy const *""'"); 
-  }
-  arg1 = reinterpret_cast< IFitStrategy * >(argp1);
-  result = (IFitStrategy *)((IFitStrategy const *)arg1)->clone();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IFitStrategy, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IFitStrategy_init(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IFitStrategy *arg1 = (IFitStrategy *) 0 ;
-  FitSuiteImpl *arg2 = (FitSuiteImpl *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:IFitStrategy_init",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IFitStrategy, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFitStrategy_init" "', argument " "1"" of type '" "IFitStrategy *""'"); 
-  }
-  arg1 = reinterpret_cast< IFitStrategy * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_FitSuiteImpl, 0 |  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IFitStrategy_init" "', argument " "2"" of type '" "FitSuiteImpl *""'"); 
-  }
-  arg2 = reinterpret_cast< FitSuiteImpl * >(argp2);
-  (arg1)->init(arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IFitStrategy_execute(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IFitStrategy *arg1 = (IFitStrategy *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:IFitStrategy_execute",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IFitStrategy, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFitStrategy_execute" "', argument " "1"" of type '" "IFitStrategy *""'"); 
-  }
-  arg1 = reinterpret_cast< IFitStrategy * >(argp1);
-  (arg1)->execute();
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *IFitStrategy_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_IFitStrategy, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *_wrap_new_FitStrategyDefault(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitStrategyDefault *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)":new_FitStrategyDefault")) SWIG_fail;
-  result = (FitStrategyDefault *)new FitStrategyDefault();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitStrategyDefault, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitStrategyDefault_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitStrategyDefault *arg1 = (FitStrategyDefault *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  FitStrategyDefault *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitStrategyDefault_clone",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitStrategyDefault, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitStrategyDefault_clone" "', argument " "1"" of type '" "FitStrategyDefault const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitStrategyDefault * >(argp1);
-  result = (FitStrategyDefault *)((FitStrategyDefault const *)arg1)->clone();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitStrategyDefault, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitStrategyDefault_execute(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitStrategyDefault *arg1 = (FitStrategyDefault *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitStrategyDefault_execute",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitStrategyDefault, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitStrategyDefault_execute" "', argument " "1"" of type '" "FitStrategyDefault *""'"); 
-  }
-  arg1 = reinterpret_cast< FitStrategyDefault * >(argp1);
-  (arg1)->execute();
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_delete_FitStrategyDefault(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitStrategyDefault *arg1 = (FitStrategyDefault *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_FitStrategyDefault",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitStrategyDefault, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_FitStrategyDefault" "', argument " "1"" of type '" "FitStrategyDefault *""'"); 
-  }
-  arg1 = reinterpret_cast< FitStrategyDefault * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *FitStrategyDefault_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_FitStrategyDefault, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
 SWIGINTERN PyObject *_wrap_delete_IIntensityFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   IIntensityFunction *arg1 = (IIntensityFunction *) 0 ;
@@ -43859,27 +43043,6 @@ SWIGINTERN PyObject *IIntensityFunction_swigregister(PyObject *SWIGUNUSEDPARM(se
   return SWIG_Py_Void();
 }
 
-SWIGINTERN PyObject *_wrap_delete_IntensityFunctionLog(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IntensityFunctionLog *arg1 = (IntensityFunctionLog *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_IntensityFunctionLog",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IntensityFunctionLog, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IntensityFunctionLog" "', argument " "1"" of type '" "IntensityFunctionLog *""'"); 
-  }
-  arg1 = reinterpret_cast< IntensityFunctionLog * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_IntensityFunctionLog_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   IntensityFunctionLog *arg1 = (IntensityFunctionLog *) 0 ;
@@ -43946,26 +43109,19 @@ fail:
 }
 
 
-SWIGINTERN PyObject *IntensityFunctionLog_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_IntensityFunctionLog, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *_wrap_delete_IntensityFunctionSqrt(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_delete_IntensityFunctionLog(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  IntensityFunctionSqrt *arg1 = (IntensityFunctionSqrt *) 0 ;
+  IntensityFunctionLog *arg1 = (IntensityFunctionLog *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_IntensityFunctionSqrt",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IntensityFunctionSqrt, SWIG_POINTER_DISOWN |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:delete_IntensityFunctionLog",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IntensityFunctionLog, SWIG_POINTER_DISOWN |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IntensityFunctionSqrt" "', argument " "1"" of type '" "IntensityFunctionSqrt *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IntensityFunctionLog" "', argument " "1"" of type '" "IntensityFunctionLog *""'"); 
   }
-  arg1 = reinterpret_cast< IntensityFunctionSqrt * >(argp1);
+  arg1 = reinterpret_cast< IntensityFunctionLog * >(argp1);
   delete arg1;
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -43974,6 +43130,13 @@ fail:
 }
 
 
+SWIGINTERN PyObject *IntensityFunctionLog_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *obj;
+  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_IntensityFunctionLog, SWIG_NewClientData(obj));
+  return SWIG_Py_Void();
+}
+
 SWIGINTERN PyObject *_wrap_IntensityFunctionSqrt_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   IntensityFunctionSqrt *arg1 = (IntensityFunctionSqrt *) 0 ;
@@ -44040,6 +43203,27 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_delete_IntensityFunctionSqrt(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IntensityFunctionSqrt *arg1 = (IntensityFunctionSqrt *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:delete_IntensityFunctionSqrt",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IntensityFunctionSqrt, SWIG_POINTER_DISOWN |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IntensityFunctionSqrt" "', argument " "1"" of type '" "IntensityFunctionSqrt *""'"); 
+  }
+  arg1 = reinterpret_cast< IntensityFunctionSqrt * >(argp1);
+  delete arg1;
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *IntensityFunctionSqrt_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
   if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
@@ -44717,19 +43901,19 @@ SWIGINTERN PyObject *IntensityScaleAndShiftNormalizer_swigregister(PyObject *SWI
   return SWIG_Py_Void();
 }
 
-SWIGINTERN PyObject *_wrap_delete_ISquaredFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_delete_IVarianceFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  ISquaredFunction *arg1 = (ISquaredFunction *) 0 ;
+  IVarianceFunction *arg1 = (IVarianceFunction *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_ISquaredFunction",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ISquaredFunction, SWIG_POINTER_DISOWN |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:delete_IVarianceFunction",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IVarianceFunction, SWIG_POINTER_DISOWN |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_ISquaredFunction" "', argument " "1"" of type '" "ISquaredFunction *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IVarianceFunction" "', argument " "1"" of type '" "IVarianceFunction *""'"); 
   }
-  arg1 = reinterpret_cast< ISquaredFunction * >(argp1);
+  arg1 = reinterpret_cast< IVarianceFunction * >(argp1);
   delete arg1;
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -44738,31 +43922,31 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_ISquaredFunction_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_IVarianceFunction_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  ISquaredFunction *arg1 = (ISquaredFunction *) 0 ;
+  IVarianceFunction *arg1 = (IVarianceFunction *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  ISquaredFunction *result = 0 ;
+  IVarianceFunction *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:ISquaredFunction_clone",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ISquaredFunction, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:IVarianceFunction_clone",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IVarianceFunction, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ISquaredFunction_clone" "', argument " "1"" of type '" "ISquaredFunction const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IVarianceFunction_clone" "', argument " "1"" of type '" "IVarianceFunction const *""'"); 
   }
-  arg1 = reinterpret_cast< ISquaredFunction * >(argp1);
-  result = (ISquaredFunction *)((ISquaredFunction const *)arg1)->clone();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ISquaredFunction, 0 |  0 );
+  arg1 = reinterpret_cast< IVarianceFunction * >(argp1);
+  result = (IVarianceFunction *)((IVarianceFunction const *)arg1)->clone();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IVarianceFunction, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ISquaredFunction_calculateSquaredDifference(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_IVarianceFunction_variance(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  ISquaredFunction *arg1 = (ISquaredFunction *) 0 ;
+  IVarianceFunction *arg1 = (IVarianceFunction *) 0 ;
   double arg2 ;
   double arg3 ;
   void *argp1 = 0 ;
@@ -44776,23 +43960,23 @@ SWIGINTERN PyObject *_wrap_ISquaredFunction_calculateSquaredDifference(PyObject
   PyObject * obj2 = 0 ;
   double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:ISquaredFunction_calculateSquaredDifference",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ISquaredFunction, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:IVarianceFunction_variance",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IVarianceFunction, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ISquaredFunction_calculateSquaredDifference" "', argument " "1"" of type '" "ISquaredFunction const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IVarianceFunction_variance" "', argument " "1"" of type '" "IVarianceFunction const *""'"); 
   }
-  arg1 = reinterpret_cast< ISquaredFunction * >(argp1);
+  arg1 = reinterpret_cast< IVarianceFunction * >(argp1);
   ecode2 = SWIG_AsVal_double(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ISquaredFunction_calculateSquaredDifference" "', argument " "2"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IVarianceFunction_variance" "', argument " "2"" of type '" "double""'");
   } 
   arg2 = static_cast< double >(val2);
   ecode3 = SWIG_AsVal_double(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ISquaredFunction_calculateSquaredDifference" "', argument " "3"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IVarianceFunction_variance" "', argument " "3"" of type '" "double""'");
   } 
   arg3 = static_cast< double >(val3);
-  result = (double)((ISquaredFunction const *)arg1)->calculateSquaredDifference(arg2,arg3);
+  result = (double)((IVarianceFunction const *)arg1)->variance(arg2,arg3);
   resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
@@ -44800,9 +43984,38 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_ISquaredFunction_calculateSquaredError__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *IVarianceFunction_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *obj;
+  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_IVarianceFunction, SWIG_NewClientData(obj));
+  return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *_wrap_VarianceConstantFunction_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  VarianceConstantFunction *arg1 = (VarianceConstantFunction *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  VarianceConstantFunction *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:VarianceConstantFunction_clone",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_VarianceConstantFunction, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarianceConstantFunction_clone" "', argument " "1"" of type '" "VarianceConstantFunction const *""'"); 
+  }
+  arg1 = reinterpret_cast< VarianceConstantFunction * >(argp1);
+  result = (VarianceConstantFunction *)((VarianceConstantFunction const *)arg1)->clone();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_VarianceConstantFunction, 0 |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_VarianceConstantFunction_variance(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  ISquaredFunction *arg1 = (ISquaredFunction *) 0 ;
+  VarianceConstantFunction *arg1 = (VarianceConstantFunction *) 0 ;
   double arg2 ;
   double arg3 ;
   void *argp1 = 0 ;
@@ -44816,23 +44029,23 @@ SWIGINTERN PyObject *_wrap_ISquaredFunction_calculateSquaredError__SWIG_0(PyObje
   PyObject * obj2 = 0 ;
   double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:ISquaredFunction_calculateSquaredError",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ISquaredFunction, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:VarianceConstantFunction_variance",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_VarianceConstantFunction, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ISquaredFunction_calculateSquaredError" "', argument " "1"" of type '" "ISquaredFunction const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarianceConstantFunction_variance" "', argument " "1"" of type '" "VarianceConstantFunction const *""'"); 
   }
-  arg1 = reinterpret_cast< ISquaredFunction * >(argp1);
+  arg1 = reinterpret_cast< VarianceConstantFunction * >(argp1);
   ecode2 = SWIG_AsVal_double(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ISquaredFunction_calculateSquaredError" "', argument " "2"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarianceConstantFunction_variance" "', argument " "2"" of type '" "double""'");
   } 
   arg2 = static_cast< double >(val2);
   ecode3 = SWIG_AsVal_double(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ISquaredFunction_calculateSquaredError" "', argument " "3"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VarianceConstantFunction_variance" "', argument " "3"" of type '" "double""'");
   } 
   arg3 = static_cast< double >(val3);
-  result = (double)((ISquaredFunction const *)arg1)->calculateSquaredError(arg2,arg3);
+  result = (double)((VarianceConstantFunction const *)arg1)->variance(arg2,arg3);
   resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
@@ -44840,161 +44053,142 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_ISquaredFunction_calculateSquaredError__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_VarianceConstantFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  ISquaredFunction *arg1 = (ISquaredFunction *) 0 ;
-  double arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  double result;
+  VarianceConstantFunction *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:ISquaredFunction_calculateSquaredError",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ISquaredFunction, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ISquaredFunction_calculateSquaredError" "', argument " "1"" of type '" "ISquaredFunction const *""'"); 
-  }
-  arg1 = reinterpret_cast< ISquaredFunction * >(argp1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ISquaredFunction_calculateSquaredError" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  result = (double)((ISquaredFunction const *)arg1)->calculateSquaredError(arg2);
-  resultobj = SWIG_From_double(static_cast< double >(result));
+  if (!PyArg_ParseTuple(args,(char *)":new_VarianceConstantFunction")) SWIG_fail;
+  result = (VarianceConstantFunction *)new VarianceConstantFunction();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_VarianceConstantFunction, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ISquaredFunction_calculateSquaredError(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[4] = {
-    0
-  };
-  Py_ssize_t ii;
+SWIGINTERN PyObject *_wrap_delete_VarianceConstantFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  VarianceConstantFunction *arg1 = (VarianceConstantFunction *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 2) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_ISquaredFunction, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_double(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_ISquaredFunction_calculateSquaredError__SWIG_1(self, args);
-      }
-    }
-  }
-  if (argc == 3) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_ISquaredFunction, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_double(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        {
-          int res = SWIG_AsVal_double(argv[2], NULL);
-          _v = SWIG_CheckState(res);
-        }
-        if (_v) {
-          return _wrap_ISquaredFunction_calculateSquaredError__SWIG_0(self, args);
-        }
-      }
-    }
+  if (!PyArg_ParseTuple(args,(char *)"O:delete_VarianceConstantFunction",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_VarianceConstantFunction, SWIG_POINTER_DISOWN |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_VarianceConstantFunction" "', argument " "1"" of type '" "VarianceConstantFunction *""'"); 
   }
-  
+  arg1 = reinterpret_cast< VarianceConstantFunction * >(argp1);
+  delete arg1;
+  resultobj = SWIG_Py_Void();
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'ISquaredFunction_calculateSquaredError'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    ISquaredFunction::calculateSquaredError(double,double) const\n"
-    "    ISquaredFunction::calculateSquaredError(double) const\n");
-  return 0;
+  return NULL;
 }
 
 
-SWIGINTERN PyObject *ISquaredFunction_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *VarianceConstantFunction_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
   if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_ISquaredFunction, SWIG_NewClientData(obj));
+  SWIG_TypeNewClientData(SWIGTYPE_p_VarianceConstantFunction, SWIG_NewClientData(obj));
   return SWIG_Py_Void();
 }
 
-SWIGINTERN PyObject *_wrap_new_SquaredFunctionDefault(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_VarianceSimFunction__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  SquaredFunctionDefault *result = 0 ;
+  double arg1 ;
+  double val1 ;
+  int ecode1 = 0 ;
+  PyObject * obj0 = 0 ;
+  VarianceSimFunction *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)":new_SquaredFunctionDefault")) SWIG_fail;
-  result = (SquaredFunctionDefault *)new SquaredFunctionDefault();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_SquaredFunctionDefault, SWIG_POINTER_NEW |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:new_VarianceSimFunction",&obj0)) SWIG_fail;
+  ecode1 = SWIG_AsVal_double(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_VarianceSimFunction" "', argument " "1"" of type '" "double""'");
+  } 
+  arg1 = static_cast< double >(val1);
+  result = (VarianceSimFunction *)new VarianceSimFunction(arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_VarianceSimFunction, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_delete_SquaredFunctionDefault(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_VarianceSimFunction__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  SquaredFunctionDefault *arg1 = (SquaredFunctionDefault *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
+  VarianceSimFunction *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_SquaredFunctionDefault",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SquaredFunctionDefault, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SquaredFunctionDefault" "', argument " "1"" of type '" "SquaredFunctionDefault *""'"); 
-  }
-  arg1 = reinterpret_cast< SquaredFunctionDefault * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
+  if (!PyArg_ParseTuple(args,(char *)":new_VarianceSimFunction")) SWIG_fail;
+  result = (VarianceSimFunction *)new VarianceSimFunction();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_VarianceSimFunction, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_SquaredFunctionDefault_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_VarianceSimFunction(PyObject *self, PyObject *args) {
+  Py_ssize_t argc;
+  PyObject *argv[2] = {
+    0
+  };
+  Py_ssize_t ii;
+  
+  if (!PyTuple_Check(args)) SWIG_fail;
+  argc = args ? PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 1) && (ii < argc); ii++) {
+    argv[ii] = PyTuple_GET_ITEM(args,ii);
+  }
+  if (argc == 0) {
+    return _wrap_new_VarianceSimFunction__SWIG_1(self, args);
+  }
+  if (argc == 1) {
+    int _v;
+    {
+      int res = SWIG_AsVal_double(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      return _wrap_new_VarianceSimFunction__SWIG_0(self, args);
+    }
+  }
+  
+fail:
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_VarianceSimFunction'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    VarianceSimFunction::VarianceSimFunction(double)\n"
+    "    VarianceSimFunction::VarianceSimFunction()\n");
+  return 0;
+}
+
+
+SWIGINTERN PyObject *_wrap_VarianceSimFunction_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  SquaredFunctionDefault *arg1 = (SquaredFunctionDefault *) 0 ;
+  VarianceSimFunction *arg1 = (VarianceSimFunction *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  SquaredFunctionDefault *result = 0 ;
+  VarianceSimFunction *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:SquaredFunctionDefault_clone",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SquaredFunctionDefault, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarianceSimFunction_clone",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_VarianceSimFunction, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SquaredFunctionDefault_clone" "', argument " "1"" of type '" "SquaredFunctionDefault const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarianceSimFunction_clone" "', argument " "1"" of type '" "VarianceSimFunction const *""'"); 
   }
-  arg1 = reinterpret_cast< SquaredFunctionDefault * >(argp1);
-  result = (SquaredFunctionDefault *)((SquaredFunctionDefault const *)arg1)->clone();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_SquaredFunctionDefault, 0 |  0 );
+  arg1 = reinterpret_cast< VarianceSimFunction * >(argp1);
+  result = (VarianceSimFunction *)((VarianceSimFunction const *)arg1)->clone();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_VarianceSimFunction, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_SquaredFunctionDefault_calculateSquaredDifference(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarianceSimFunction_variance(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  SquaredFunctionDefault *arg1 = (SquaredFunctionDefault *) 0 ;
+  VarianceSimFunction *arg1 = (VarianceSimFunction *) 0 ;
   double arg2 ;
   double arg3 ;
   void *argp1 = 0 ;
@@ -45008,23 +44202,23 @@ SWIGINTERN PyObject *_wrap_SquaredFunctionDefault_calculateSquaredDifference(PyO
   PyObject * obj2 = 0 ;
   double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:SquaredFunctionDefault_calculateSquaredDifference",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SquaredFunctionDefault, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:VarianceSimFunction_variance",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_VarianceSimFunction, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SquaredFunctionDefault_calculateSquaredDifference" "', argument " "1"" of type '" "SquaredFunctionDefault const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarianceSimFunction_variance" "', argument " "1"" of type '" "VarianceSimFunction const *""'"); 
   }
-  arg1 = reinterpret_cast< SquaredFunctionDefault * >(argp1);
+  arg1 = reinterpret_cast< VarianceSimFunction * >(argp1);
   ecode2 = SWIG_AsVal_double(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SquaredFunctionDefault_calculateSquaredDifference" "', argument " "2"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarianceSimFunction_variance" "', argument " "2"" of type '" "double""'");
   } 
   arg2 = static_cast< double >(val2);
   ecode3 = SWIG_AsVal_double(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "SquaredFunctionDefault_calculateSquaredDifference" "', argument " "3"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VarianceSimFunction_variance" "', argument " "3"" of type '" "double""'");
   } 
   arg3 = static_cast< double >(val3);
-  result = (double)((SquaredFunctionDefault const *)arg1)->calculateSquaredDifference(arg2,arg3);
+  result = (double)((VarianceSimFunction const *)arg1)->variance(arg2,arg3);
   resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
@@ -45032,155 +44226,118 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_SquaredFunctionDefault_calculateSquaredError__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_delete_VarianceSimFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  SquaredFunctionDefault *arg1 = (SquaredFunctionDefault *) 0 ;
-  double arg2 ;
-  double arg3 ;
+  VarianceSimFunction *arg1 = (VarianceSimFunction *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:SquaredFunctionDefault_calculateSquaredError",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SquaredFunctionDefault, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:delete_VarianceSimFunction",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_VarianceSimFunction, SWIG_POINTER_DISOWN |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SquaredFunctionDefault_calculateSquaredError" "', argument " "1"" of type '" "SquaredFunctionDefault const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_VarianceSimFunction" "', argument " "1"" of type '" "VarianceSimFunction *""'"); 
   }
-  arg1 = reinterpret_cast< SquaredFunctionDefault * >(argp1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SquaredFunctionDefault_calculateSquaredError" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "SquaredFunctionDefault_calculateSquaredError" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  result = (double)((SquaredFunctionDefault const *)arg1)->calculateSquaredError(arg2,arg3);
-  resultobj = SWIG_From_double(static_cast< double >(result));
+  arg1 = reinterpret_cast< VarianceSimFunction * >(argp1);
+  delete arg1;
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_SquaredFunctionDefault_calculateSquaredError__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *VarianceSimFunction_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *obj;
+  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_VarianceSimFunction, SWIG_NewClientData(obj));
+  return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *_wrap_new_ChiSquaredModule__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  SquaredFunctionDefault *arg1 = (SquaredFunctionDefault *) 0 ;
-  double arg2 ;
+  ChiSquaredModule *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)":new_ChiSquaredModule")) SWIG_fail;
+  result = (ChiSquaredModule *)new ChiSquaredModule();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ChiSquaredModule, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_new_ChiSquaredModule__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  ChiSquaredModule *arg1 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  double result;
+  ChiSquaredModule *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:SquaredFunctionDefault_calculateSquaredError",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SquaredFunctionDefault, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:new_ChiSquaredModule",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_ChiSquaredModule,  0  | 0);
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SquaredFunctionDefault_calculateSquaredError" "', argument " "1"" of type '" "SquaredFunctionDefault const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_ChiSquaredModule" "', argument " "1"" of type '" "ChiSquaredModule const &""'"); 
   }
-  arg1 = reinterpret_cast< SquaredFunctionDefault * >(argp1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SquaredFunctionDefault_calculateSquaredError" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  result = (double)((SquaredFunctionDefault const *)arg1)->calculateSquaredError(arg2);
-  resultobj = SWIG_From_double(static_cast< double >(result));
+  if (!argp1) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_ChiSquaredModule" "', argument " "1"" of type '" "ChiSquaredModule const &""'"); 
+  }
+  arg1 = reinterpret_cast< ChiSquaredModule * >(argp1);
+  result = (ChiSquaredModule *)new ChiSquaredModule((ChiSquaredModule const &)*arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ChiSquaredModule, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_SquaredFunctionDefault_calculateSquaredError(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_ChiSquaredModule(PyObject *self, PyObject *args) {
   Py_ssize_t argc;
-  PyObject *argv[4] = {
+  PyObject *argv[2] = {
     0
   };
   Py_ssize_t ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
   argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
+  for (ii = 0; (ii < 1) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  if (argc == 2) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_SquaredFunctionDefault, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_double(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_SquaredFunctionDefault_calculateSquaredError__SWIG_1(self, args);
-      }
-    }
+  if (argc == 0) {
+    return _wrap_new_ChiSquaredModule__SWIG_0(self, args);
   }
-  if (argc == 3) {
+  if (argc == 1) {
     int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_SquaredFunctionDefault, 0);
+    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_ChiSquaredModule, 0);
     _v = SWIG_CheckState(res);
     if (_v) {
-      {
-        int res = SWIG_AsVal_double(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        {
-          int res = SWIG_AsVal_double(argv[2], NULL);
-          _v = SWIG_CheckState(res);
-        }
-        if (_v) {
-          return _wrap_SquaredFunctionDefault_calculateSquaredError__SWIG_0(self, args);
-        }
-      }
+      return _wrap_new_ChiSquaredModule__SWIG_1(self, args);
     }
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'SquaredFunctionDefault_calculateSquaredError'.\n"
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_ChiSquaredModule'.\n"
     "  Possible C/C++ prototypes are:\n"
-    "    SquaredFunctionDefault::calculateSquaredError(double,double) const\n"
-    "    SquaredFunctionDefault::calculateSquaredError(double) const\n");
+    "    ChiSquaredModule::ChiSquaredModule()\n"
+    "    ChiSquaredModule::ChiSquaredModule(ChiSquaredModule const &)\n");
   return 0;
 }
 
 
-SWIGINTERN PyObject *SquaredFunctionDefault_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_SquaredFunctionDefault, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *_wrap_delete_SquaredFunctionSimError(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_delete_ChiSquaredModule(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  SquaredFunctionSimError *arg1 = (SquaredFunctionSimError *) 0 ;
+  ChiSquaredModule *arg1 = (ChiSquaredModule *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_SquaredFunctionSimError",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SquaredFunctionSimError, SWIG_POINTER_DISOWN |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:delete_ChiSquaredModule",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ChiSquaredModule, SWIG_POINTER_DISOWN |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SquaredFunctionSimError" "', argument " "1"" of type '" "SquaredFunctionSimError *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_ChiSquaredModule" "', argument " "1"" of type '" "ChiSquaredModule *""'"); 
   }
-  arg1 = reinterpret_cast< SquaredFunctionSimError * >(argp1);
+  arg1 = reinterpret_cast< ChiSquaredModule * >(argp1);
   delete arg1;
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -45189,101 +44346,70 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_SquaredFunctionSimError_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ChiSquaredModule_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  SquaredFunctionSimError *arg1 = (SquaredFunctionSimError *) 0 ;
+  ChiSquaredModule *arg1 = (ChiSquaredModule *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  SquaredFunctionSimError *result = 0 ;
+  ChiSquaredModule *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:SquaredFunctionSimError_clone",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SquaredFunctionSimError, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:ChiSquaredModule_clone",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ChiSquaredModule, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SquaredFunctionSimError_clone" "', argument " "1"" of type '" "SquaredFunctionSimError const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ChiSquaredModule_clone" "', argument " "1"" of type '" "ChiSquaredModule const *""'"); 
   }
-  arg1 = reinterpret_cast< SquaredFunctionSimError * >(argp1);
-  result = (SquaredFunctionSimError *)((SquaredFunctionSimError const *)arg1)->clone();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_SquaredFunctionSimError, 0 |  0 );
+  arg1 = reinterpret_cast< ChiSquaredModule * >(argp1);
+  result = (ChiSquaredModule *)((ChiSquaredModule const *)arg1)->clone();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ChiSquaredModule, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_SquaredFunctionSimError_calculateSquaredDifference(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ChiSquaredModule_residual(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  SquaredFunctionSimError *arg1 = (SquaredFunctionSimError *) 0 ;
+  ChiSquaredModule *arg1 = (ChiSquaredModule *) 0 ;
   double arg2 ;
   double arg3 ;
+  double arg4 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   double val2 ;
   int ecode2 = 0 ;
   double val3 ;
   int ecode3 = 0 ;
+  double val4 ;
+  int ecode4 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
   double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:SquaredFunctionSimError_calculateSquaredDifference",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SquaredFunctionSimError, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOOO:ChiSquaredModule_residual",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ChiSquaredModule, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SquaredFunctionSimError_calculateSquaredDifference" "', argument " "1"" of type '" "SquaredFunctionSimError const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ChiSquaredModule_residual" "', argument " "1"" of type '" "ChiSquaredModule *""'"); 
   }
-  arg1 = reinterpret_cast< SquaredFunctionSimError * >(argp1);
+  arg1 = reinterpret_cast< ChiSquaredModule * >(argp1);
   ecode2 = SWIG_AsVal_double(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SquaredFunctionSimError_calculateSquaredDifference" "', argument " "2"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ChiSquaredModule_residual" "', argument " "2"" of type '" "double""'");
   } 
   arg2 = static_cast< double >(val2);
   ecode3 = SWIG_AsVal_double(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "SquaredFunctionSimError_calculateSquaredDifference" "', argument " "3"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ChiSquaredModule_residual" "', argument " "3"" of type '" "double""'");
   } 
   arg3 = static_cast< double >(val3);
-  result = (double)((SquaredFunctionSimError const *)arg1)->calculateSquaredDifference(arg2,arg3);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_SquaredFunctionSimError_calculateSquaredError(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  SquaredFunctionSimError *arg1 = (SquaredFunctionSimError *) 0 ;
-  double arg2 ;
-  double arg3 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  double result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOO:SquaredFunctionSimError_calculateSquaredError",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SquaredFunctionSimError, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SquaredFunctionSimError_calculateSquaredError" "', argument " "1"" of type '" "SquaredFunctionSimError const *""'"); 
-  }
-  arg1 = reinterpret_cast< SquaredFunctionSimError * >(argp1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SquaredFunctionSimError_calculateSquaredError" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "SquaredFunctionSimError_calculateSquaredError" "', argument " "3"" of type '" "double""'");
+  ecode4 = SWIG_AsVal_double(obj3, &val4);
+  if (!SWIG_IsOK(ecode4)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "ChiSquaredModule_residual" "', argument " "4"" of type '" "double""'");
   } 
-  arg3 = static_cast< double >(val3);
-  result = (double)((SquaredFunctionSimError const *)arg1)->calculateSquaredError(arg2,arg3);
+  arg4 = static_cast< double >(val4);
+  result = (double)(arg1)->residual(arg2,arg3,arg4);
   resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
@@ -45291,89 +44417,41 @@ fail:
 }
 
 
-SWIGINTERN PyObject *SquaredFunctionSimError_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *ChiSquaredModule_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
   if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_SquaredFunctionSimError, SWIG_NewClientData(obj));
+  SWIG_TypeNewClientData(SWIGTYPE_p_ChiSquaredModule, SWIG_NewClientData(obj));
   return SWIG_Py_Void();
 }
 
-SWIGINTERN PyObject *_wrap_delete_SquaredFunctionMeanSquaredError(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  SquaredFunctionMeanSquaredError *arg1 = (SquaredFunctionMeanSquaredError *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_SquaredFunctionMeanSquaredError",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SquaredFunctionMeanSquaredError, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SquaredFunctionMeanSquaredError" "', argument " "1"" of type '" "SquaredFunctionMeanSquaredError *""'"); 
-  }
-  arg1 = reinterpret_cast< SquaredFunctionMeanSquaredError * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_SquaredFunctionMeanSquaredError_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_FitOptions(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  SquaredFunctionMeanSquaredError *arg1 = (SquaredFunctionMeanSquaredError *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  SquaredFunctionMeanSquaredError *result = 0 ;
+  FitOptions *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:SquaredFunctionMeanSquaredError_clone",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SquaredFunctionMeanSquaredError, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SquaredFunctionMeanSquaredError_clone" "', argument " "1"" of type '" "SquaredFunctionMeanSquaredError const *""'"); 
-  }
-  arg1 = reinterpret_cast< SquaredFunctionMeanSquaredError * >(argp1);
-  result = (SquaredFunctionMeanSquaredError *)((SquaredFunctionMeanSquaredError const *)arg1)->clone();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_SquaredFunctionMeanSquaredError, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)":new_FitOptions")) SWIG_fail;
+  result = (FitOptions *)new FitOptions();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitOptions, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_SquaredFunctionMeanSquaredError_calculateSquaredDifference(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitOptions_derivEpsilon(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  SquaredFunctionMeanSquaredError *arg1 = (SquaredFunctionMeanSquaredError *) 0 ;
-  double arg2 ;
-  double arg3 ;
+  FitOptions *arg1 = (FitOptions *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
   double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:SquaredFunctionMeanSquaredError_calculateSquaredDifference",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SquaredFunctionMeanSquaredError, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:FitOptions_derivEpsilon",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitOptions, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SquaredFunctionMeanSquaredError_calculateSquaredDifference" "', argument " "1"" of type '" "SquaredFunctionMeanSquaredError const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitOptions_derivEpsilon" "', argument " "1"" of type '" "FitOptions const *""'"); 
   }
-  arg1 = reinterpret_cast< SquaredFunctionMeanSquaredError * >(argp1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SquaredFunctionMeanSquaredError_calculateSquaredDifference" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "SquaredFunctionMeanSquaredError_calculateSquaredDifference" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  result = (double)((SquaredFunctionMeanSquaredError const *)arg1)->calculateSquaredDifference(arg2,arg3);
+  arg1 = reinterpret_cast< FitOptions * >(argp1);
+  result = (double)((FitOptions const *)arg1)->derivEpsilon();
   resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
@@ -45381,67 +44459,29 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_SquaredFunctionMeanSquaredError_calculateSquaredError(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitOptions_setDerivEpsilon(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  SquaredFunctionMeanSquaredError *arg1 = (SquaredFunctionMeanSquaredError *) 0 ;
+  FitOptions *arg1 = (FitOptions *) 0 ;
   double arg2 ;
-  double arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   double val2 ;
   int ecode2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:SquaredFunctionMeanSquaredError_calculateSquaredError",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SquaredFunctionMeanSquaredError, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:FitOptions_setDerivEpsilon",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitOptions, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SquaredFunctionMeanSquaredError_calculateSquaredError" "', argument " "1"" of type '" "SquaredFunctionMeanSquaredError const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitOptions_setDerivEpsilon" "', argument " "1"" of type '" "FitOptions *""'"); 
   }
-  arg1 = reinterpret_cast< SquaredFunctionMeanSquaredError * >(argp1);
+  arg1 = reinterpret_cast< FitOptions * >(argp1);
   ecode2 = SWIG_AsVal_double(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SquaredFunctionMeanSquaredError_calculateSquaredError" "', argument " "2"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitOptions_setDerivEpsilon" "', argument " "2"" of type '" "double""'");
   } 
   arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "SquaredFunctionMeanSquaredError_calculateSquaredError" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  result = (double)((SquaredFunctionMeanSquaredError const *)arg1)->calculateSquaredError(arg2,arg3);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *SquaredFunctionMeanSquaredError_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_SquaredFunctionMeanSquaredError, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *_wrap_delete_SquaredFunctionSystematicError(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  SquaredFunctionSystematicError *arg1 = (SquaredFunctionSystematicError *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_SquaredFunctionSystematicError",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SquaredFunctionSystematicError, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SquaredFunctionSystematicError" "', argument " "1"" of type '" "SquaredFunctionSystematicError *""'"); 
-  }
-  arg1 = reinterpret_cast< SquaredFunctionSystematicError * >(argp1);
-  delete arg1;
+  (arg1)->setDerivEpsilon(arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -45449,330 +44489,321 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_SquaredFunctionSystematicError_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitOptions_stepFactor(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  SquaredFunctionSystematicError *arg1 = (SquaredFunctionSystematicError *) 0 ;
+  FitOptions *arg1 = (FitOptions *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  SquaredFunctionSystematicError *result = 0 ;
+  double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:SquaredFunctionSystematicError_clone",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SquaredFunctionSystematicError, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:FitOptions_stepFactor",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitOptions, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SquaredFunctionSystematicError_clone" "', argument " "1"" of type '" "SquaredFunctionSystematicError const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitOptions_stepFactor" "', argument " "1"" of type '" "FitOptions const *""'"); 
   }
-  arg1 = reinterpret_cast< SquaredFunctionSystematicError * >(argp1);
-  result = (SquaredFunctionSystematicError *)((SquaredFunctionSystematicError const *)arg1)->clone();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_SquaredFunctionSystematicError, 0 |  0 );
+  arg1 = reinterpret_cast< FitOptions * >(argp1);
+  result = (double)((FitOptions const *)arg1)->stepFactor();
+  resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_SquaredFunctionSystematicError_calculateSquaredDifference(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitOptions_setStepFactor(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  SquaredFunctionSystematicError *arg1 = (SquaredFunctionSystematicError *) 0 ;
+  FitOptions *arg1 = (FitOptions *) 0 ;
   double arg2 ;
-  double arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   double val2 ;
   int ecode2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:SquaredFunctionSystematicError_calculateSquaredDifference",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SquaredFunctionSystematicError, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:FitOptions_setStepFactor",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitOptions, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SquaredFunctionSystematicError_calculateSquaredDifference" "', argument " "1"" of type '" "SquaredFunctionSystematicError const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitOptions_setStepFactor" "', argument " "1"" of type '" "FitOptions *""'"); 
   }
-  arg1 = reinterpret_cast< SquaredFunctionSystematicError * >(argp1);
+  arg1 = reinterpret_cast< FitOptions * >(argp1);
   ecode2 = SWIG_AsVal_double(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SquaredFunctionSystematicError_calculateSquaredDifference" "', argument " "2"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitOptions_setStepFactor" "', argument " "2"" of type '" "double""'");
   } 
   arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "SquaredFunctionSystematicError_calculateSquaredDifference" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  result = (double)((SquaredFunctionSystematicError const *)arg1)->calculateSquaredDifference(arg2,arg3);
-  resultobj = SWIG_From_double(static_cast< double >(result));
+  (arg1)->setStepFactor(arg2);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_SquaredFunctionSystematicError_calculateSquaredError(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_delete_FitOptions(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  SquaredFunctionSystematicError *arg1 = (SquaredFunctionSystematicError *) 0 ;
-  double arg2 ;
-  double arg3 ;
+  FitOptions *arg1 = (FitOptions *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:SquaredFunctionSystematicError_calculateSquaredError",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SquaredFunctionSystematicError, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:delete_FitOptions",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitOptions, SWIG_POINTER_DISOWN |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SquaredFunctionSystematicError_calculateSquaredError" "', argument " "1"" of type '" "SquaredFunctionSystematicError const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_FitOptions" "', argument " "1"" of type '" "FitOptions *""'"); 
   }
-  arg1 = reinterpret_cast< SquaredFunctionSystematicError * >(argp1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SquaredFunctionSystematicError_calculateSquaredError" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "SquaredFunctionSystematicError_calculateSquaredError" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  result = (double)((SquaredFunctionSystematicError const *)arg1)->calculateSquaredError(arg2,arg3);
-  resultobj = SWIG_From_double(static_cast< double >(result));
+  arg1 = reinterpret_cast< FitOptions * >(argp1);
+  delete arg1;
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *SquaredFunctionSystematicError_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *FitOptions_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
   if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_SquaredFunctionSystematicError, SWIG_NewClientData(obj));
+  SWIG_TypeNewClientData(SWIGTYPE_p_FitOptions, SWIG_NewClientData(obj));
   return SWIG_Py_Void();
 }
 
-SWIGINTERN PyObject *_wrap_delete_SquaredFunctionGaussianError(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_PyBuilderCallback(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  SquaredFunctionGaussianError *arg1 = (SquaredFunctionGaussianError *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
+  PyObject *arg1 = (PyObject *) 0 ;
   PyObject * obj0 = 0 ;
+  PyBuilderCallback *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_SquaredFunctionGaussianError",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SquaredFunctionGaussianError, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SquaredFunctionGaussianError" "', argument " "1"" of type '" "SquaredFunctionGaussianError *""'"); 
+  if (!PyArg_ParseTuple(args,(char *)"O:new_PyBuilderCallback",&obj0)) SWIG_fail;
+  arg1 = obj0;
+  if ( arg1 != Py_None ) {
+    /* subclassed */
+    result = (PyBuilderCallback *)new SwigDirector_PyBuilderCallback(arg1); 
+  } else {
+    result = (PyBuilderCallback *)new PyBuilderCallback(); 
   }
-  arg1 = reinterpret_cast< SquaredFunctionGaussianError * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
+  
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_PyBuilderCallback, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_SquaredFunctionGaussianError_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_delete_PyBuilderCallback(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  SquaredFunctionGaussianError *arg1 = (SquaredFunctionGaussianError *) 0 ;
+  PyBuilderCallback *arg1 = (PyBuilderCallback *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  SquaredFunctionGaussianError *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:SquaredFunctionGaussianError_clone",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SquaredFunctionGaussianError, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:delete_PyBuilderCallback",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_PyBuilderCallback, SWIG_POINTER_DISOWN |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SquaredFunctionGaussianError_clone" "', argument " "1"" of type '" "SquaredFunctionGaussianError const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_PyBuilderCallback" "', argument " "1"" of type '" "PyBuilderCallback *""'"); 
   }
-  arg1 = reinterpret_cast< SquaredFunctionGaussianError * >(argp1);
-  result = (SquaredFunctionGaussianError *)((SquaredFunctionGaussianError const *)arg1)->clone();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_SquaredFunctionGaussianError, 0 |  0 );
+  arg1 = reinterpret_cast< PyBuilderCallback * >(argp1);
+  delete arg1;
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_SquaredFunctionGaussianError_calculateSquaredDifference(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_PyBuilderCallback_build_simulation(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  SquaredFunctionGaussianError *arg1 = (SquaredFunctionGaussianError *) 0 ;
-  double arg2 ;
-  double arg3 ;
+  PyBuilderCallback *arg1 = (PyBuilderCallback *) 0 ;
+  Fit::Parameters arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
+  void *argp2 ;
+  int res2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  double result;
+  Swig::Director *director = 0;
+  bool upcall = false;
+  Simulation *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:SquaredFunctionGaussianError_calculateSquaredDifference",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SquaredFunctionGaussianError, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:PyBuilderCallback_build_simulation",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_PyBuilderCallback, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SquaredFunctionGaussianError_calculateSquaredDifference" "', argument " "1"" of type '" "SquaredFunctionGaussianError const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PyBuilderCallback_build_simulation" "', argument " "1"" of type '" "PyBuilderCallback *""'"); 
+  }
+  arg1 = reinterpret_cast< PyBuilderCallback * >(argp1);
+  {
+    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_Fit__Parameters,  0  | 0);
+    if (!SWIG_IsOK(res2)) {
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "PyBuilderCallback_build_simulation" "', argument " "2"" of type '" "Fit::Parameters""'"); 
+    }  
+    if (!argp2) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "PyBuilderCallback_build_simulation" "', argument " "2"" of type '" "Fit::Parameters""'");
+    } else {
+      Fit::Parameters * temp = reinterpret_cast< Fit::Parameters * >(argp2);
+      arg2 = *temp;
+      if (SWIG_IsNewObj(res2)) delete temp;
+    }
+  }
+  director = SWIG_DIRECTOR_CAST(arg1);
+  upcall = (director && (director->swig_get_self()==obj0));
+  try {
+    if (upcall) {
+      result = (Simulation *)(arg1)->PyBuilderCallback::build_simulation(arg2);
+    } else {
+      result = (Simulation *)(arg1)->build_simulation(arg2);
+    }
+  } catch (Swig::DirectorException&) {
+    SWIG_fail;
+  }
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Simulation, 0 |  0 );
+  if (director) {
+    SWIG_AcquirePtr(resultobj, director->swig_release_ownership(SWIG_as_voidptr(result)));
   }
-  arg1 = reinterpret_cast< SquaredFunctionGaussianError * >(argp1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SquaredFunctionGaussianError_calculateSquaredDifference" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "SquaredFunctionGaussianError_calculateSquaredDifference" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  result = (double)((SquaredFunctionGaussianError const *)arg1)->calculateSquaredDifference(arg2,arg3);
-  resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_SquaredFunctionGaussianError_calculateSquaredError(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_disown_PyBuilderCallback(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  SquaredFunctionGaussianError *arg1 = (SquaredFunctionGaussianError *) 0 ;
-  double arg2 ;
-  double arg3 ;
+  PyBuilderCallback *arg1 = (PyBuilderCallback *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:SquaredFunctionGaussianError_calculateSquaredError",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_SquaredFunctionGaussianError, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:disown_PyBuilderCallback",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_PyBuilderCallback, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SquaredFunctionGaussianError_calculateSquaredError" "', argument " "1"" of type '" "SquaredFunctionGaussianError const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "disown_PyBuilderCallback" "', argument " "1"" of type '" "PyBuilderCallback *""'"); 
   }
-  arg1 = reinterpret_cast< SquaredFunctionGaussianError * >(argp1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SquaredFunctionGaussianError_calculateSquaredError" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "SquaredFunctionGaussianError_calculateSquaredError" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  result = (double)((SquaredFunctionGaussianError const *)arg1)->calculateSquaredError(arg2,arg3);
-  resultobj = SWIG_From_double(static_cast< double >(result));
+  arg1 = reinterpret_cast< PyBuilderCallback * >(argp1);
+  {
+    Swig::Director *director = SWIG_DIRECTOR_CAST(arg1);
+    if (director) director->swig_disown();
+  }
+  
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *SquaredFunctionGaussianError_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *PyBuilderCallback_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
   if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_SquaredFunctionGaussianError, SWIG_NewClientData(obj));
+  SWIG_TypeNewClientData(SWIGTYPE_p_PyBuilderCallback, SWIG_NewClientData(obj));
   return SWIG_Py_Void();
 }
 
-SWIGINTERN PyObject *_wrap_new_ChiSquaredModule__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_PyObserverCallback(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  ChiSquaredModule *result = 0 ;
+  PyObject *arg1 = (PyObject *) 0 ;
+  PyObject * obj0 = 0 ;
+  PyObserverCallback *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)":new_ChiSquaredModule")) SWIG_fail;
-  result = (ChiSquaredModule *)new ChiSquaredModule();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ChiSquaredModule, SWIG_POINTER_NEW |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:new_PyObserverCallback",&obj0)) SWIG_fail;
+  arg1 = obj0;
+  if ( arg1 != Py_None ) {
+    /* subclassed */
+    result = (PyObserverCallback *)new SwigDirector_PyObserverCallback(arg1); 
+  } else {
+    result = (PyObserverCallback *)new PyObserverCallback(); 
+  }
+  
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_PyObserverCallback, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_new_ChiSquaredModule__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_delete_PyObserverCallback(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  ChiSquaredModule *arg1 = 0 ;
+  PyObserverCallback *arg1 = (PyObserverCallback *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  ChiSquaredModule *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:new_ChiSquaredModule",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_ChiSquaredModule,  0  | 0);
+  if (!PyArg_ParseTuple(args,(char *)"O:delete_PyObserverCallback",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_PyObserverCallback, SWIG_POINTER_DISOWN |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_ChiSquaredModule" "', argument " "1"" of type '" "ChiSquaredModule const &""'"); 
-  }
-  if (!argp1) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_ChiSquaredModule" "', argument " "1"" of type '" "ChiSquaredModule const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_PyObserverCallback" "', argument " "1"" of type '" "PyObserverCallback *""'"); 
   }
-  arg1 = reinterpret_cast< ChiSquaredModule * >(argp1);
-  result = (ChiSquaredModule *)new ChiSquaredModule((ChiSquaredModule const &)*arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ChiSquaredModule, SWIG_POINTER_NEW |  0 );
+  arg1 = reinterpret_cast< PyObserverCallback * >(argp1);
+  delete arg1;
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_new_ChiSquaredModule(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[2] = {
-    0
-  };
-  Py_ssize_t ii;
+SWIGINTERN PyObject *_wrap_PyObserverCallback_update(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  PyObserverCallback *arg1 = (PyObserverCallback *) 0 ;
+  FitObjective *arg2 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  Swig::Director *director = 0;
+  bool upcall = false;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 1) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
+  if (!PyArg_ParseTuple(args,(char *)"OO:PyObserverCallback_update",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_PyObserverCallback, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PyObserverCallback_update" "', argument " "1"" of type '" "PyObserverCallback *""'"); 
   }
-  if (argc == 0) {
-    return _wrap_new_ChiSquaredModule__SWIG_0(self, args);
+  arg1 = reinterpret_cast< PyObserverCallback * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_FitObjective,  0  | 0);
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "PyObserverCallback_update" "', argument " "2"" of type '" "FitObjective const &""'"); 
   }
-  if (argc == 1) {
-    int _v;
-    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_ChiSquaredModule, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_new_ChiSquaredModule__SWIG_1(self, args);
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "PyObserverCallback_update" "', argument " "2"" of type '" "FitObjective const &""'"); 
+  }
+  arg2 = reinterpret_cast< FitObjective * >(argp2);
+  director = SWIG_DIRECTOR_CAST(arg1);
+  upcall = (director && (director->swig_get_self()==obj0));
+  try {
+    if (upcall) {
+      (arg1)->PyObserverCallback::update((FitObjective const &)*arg2);
+    } else {
+      (arg1)->update((FitObjective const &)*arg2);
     }
+  } catch (Swig::DirectorException&) {
+    SWIG_fail;
   }
-  
+  resultobj = SWIG_Py_Void();
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_ChiSquaredModule'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    ChiSquaredModule::ChiSquaredModule()\n"
-    "    ChiSquaredModule::ChiSquaredModule(ChiSquaredModule const &)\n");
-  return 0;
+  return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_delete_ChiSquaredModule(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_disown_PyObserverCallback(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  ChiSquaredModule *arg1 = (ChiSquaredModule *) 0 ;
+  PyObserverCallback *arg1 = (PyObserverCallback *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_ChiSquaredModule",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ChiSquaredModule, SWIG_POINTER_DISOWN |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:disown_PyObserverCallback",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_PyObserverCallback, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_ChiSquaredModule" "', argument " "1"" of type '" "ChiSquaredModule *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "disown_PyObserverCallback" "', argument " "1"" of type '" "PyObserverCallback *""'"); 
   }
-  arg1 = reinterpret_cast< ChiSquaredModule * >(argp1);
-  delete arg1;
+  arg1 = reinterpret_cast< PyObserverCallback * >(argp1);
+  {
+    Swig::Director *director = SWIG_DIRECTOR_CAST(arg1);
+    if (director) director->swig_disown();
+  }
+  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -45780,76 +44811,49 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_ChiSquaredModule_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *PyObserverCallback_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *obj;
+  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_PyObserverCallback, SWIG_NewClientData(obj));
+  return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *_wrap_new_FitObjective(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  ChiSquaredModule *arg1 = (ChiSquaredModule *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
+  PyObject *arg1 = (PyObject *) 0 ;
   PyObject * obj0 = 0 ;
-  ChiSquaredModule *result = 0 ;
+  FitObjective *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:ChiSquaredModule_clone",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ChiSquaredModule, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ChiSquaredModule_clone" "', argument " "1"" of type '" "ChiSquaredModule const *""'"); 
+  if (!PyArg_ParseTuple(args,(char *)"O:new_FitObjective",&obj0)) SWIG_fail;
+  arg1 = obj0;
+  if ( arg1 != Py_None ) {
+    /* subclassed */
+    result = (FitObjective *)new SwigDirector_FitObjective(arg1); 
+  } else {
+    result = (FitObjective *)new FitObjective(); 
   }
-  arg1 = reinterpret_cast< ChiSquaredModule * >(argp1);
-  result = (ChiSquaredModule *)((ChiSquaredModule const *)arg1)->clone();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ChiSquaredModule, 0 |  0 );
+  
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitObjective, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ChiSquaredModule_processFitElements(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_delete_FitObjective(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  ChiSquaredModule *arg1 = (ChiSquaredModule *) 0 ;
-  SwigValueWrapper< std::vector< FitElement,std::allocator< FitElement > >::iterator > arg2 ;
-  SwigValueWrapper< std::vector< FitElement,std::allocator< FitElement > >::iterator > arg3 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  void *argp2 ;
-  int res2 = 0 ;
-  void *argp3 ;
-  int res3 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:ChiSquaredModule_processFitElements",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ChiSquaredModule, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:delete_FitObjective",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, SWIG_POINTER_DISOWN |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ChiSquaredModule_processFitElements" "', argument " "1"" of type '" "ChiSquaredModule *""'"); 
-  }
-  arg1 = reinterpret_cast< ChiSquaredModule * >(argp1);
-  {
-    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__vectorT_FitElement_std__allocatorT_FitElement_t_t__iterator,  0  | 0);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ChiSquaredModule_processFitElements" "', argument " "2"" of type '" "std::vector< FitElement,std::allocator< FitElement > >::iterator""'"); 
-    }  
-    if (!argp2) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "ChiSquaredModule_processFitElements" "', argument " "2"" of type '" "std::vector< FitElement,std::allocator< FitElement > >::iterator""'");
-    } else {
-      std::vector< FitElement,std::allocator< FitElement > >::iterator * temp = reinterpret_cast< std::vector< FitElement,std::allocator< FitElement > >::iterator * >(argp2);
-      arg2 = *temp;
-      if (SWIG_IsNewObj(res2)) delete temp;
-    }
-  }
-  {
-    res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_std__vectorT_FitElement_std__allocatorT_FitElement_t_t__iterator,  0  | 0);
-    if (!SWIG_IsOK(res3)) {
-      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "ChiSquaredModule_processFitElements" "', argument " "3"" of type '" "std::vector< FitElement,std::allocator< FitElement > >::iterator""'"); 
-    }  
-    if (!argp3) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "ChiSquaredModule_processFitElements" "', argument " "3"" of type '" "std::vector< FitElement,std::allocator< FitElement > >::iterator""'");
-    } else {
-      std::vector< FitElement,std::allocator< FitElement > >::iterator * temp = reinterpret_cast< std::vector< FitElement,std::allocator< FitElement > >::iterator * >(argp3);
-      arg3 = *temp;
-      if (SWIG_IsNewObj(res3)) delete temp;
-    }
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_FitObjective" "', argument " "1"" of type '" "FitObjective *""'"); 
   }
-  (arg1)->processFitElements(arg2,arg3);
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  delete arg1;
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -45857,612 +44861,653 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_ChiSquaredModule_residual(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_addSimulationAndData_cpp__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  ChiSquaredModule *arg1 = (ChiSquaredModule *) 0 ;
-  double arg2 ;
-  double arg3 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
+  PyBuilderCallback *arg2 = 0 ;
+  std::vector< double,std::allocator< double > > *arg3 = 0 ;
   double arg4 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  int res3 = SWIG_OLDOBJ ;
   double val4 ;
   int ecode4 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
   PyObject * obj3 = 0 ;
-  double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOOO:ChiSquaredModule_residual",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ChiSquaredModule, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOOO:FitObjective_addSimulationAndData_cpp",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ChiSquaredModule_residual" "', argument " "1"" of type '" "ChiSquaredModule *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "1"" of type '" "FitObjective *""'"); 
+  }
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_PyBuilderCallback,  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "2"" of type '" "PyBuilderCallback &""'"); 
+  }
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "2"" of type '" "PyBuilderCallback &""'"); 
+  }
+  arg2 = reinterpret_cast< PyBuilderCallback * >(argp2);
+  {
+    std::vector< double,std::allocator< double > > *ptr = (std::vector< double,std::allocator< double > > *)0;
+    res3 = swig::asptr(obj2, &ptr);
+    if (!SWIG_IsOK(res3)) {
+      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "3"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "3"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
+    }
+    arg3 = ptr;
   }
-  arg1 = reinterpret_cast< ChiSquaredModule * >(argp1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ChiSquaredModule_residual" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ChiSquaredModule_residual" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
   ecode4 = SWIG_AsVal_double(obj3, &val4);
   if (!SWIG_IsOK(ecode4)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "ChiSquaredModule_residual" "', argument " "4"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "4"" of type '" "double""'");
   } 
   arg4 = static_cast< double >(val4);
-  result = (double)(arg1)->residual(arg2,arg3,arg4);
-  resultobj = SWIG_From_double(static_cast< double >(result));
+  (arg1)->addSimulationAndData(*arg2,(std::vector< double,std::allocator< double > > const &)*arg3,arg4);
+  resultobj = SWIG_Py_Void();
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return resultobj;
 fail:
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *ChiSquaredModule_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_ChiSquaredModule, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *_wrap_new_FitObject__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_addSimulationAndData_cpp__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  Simulation *arg1 = 0 ;
-  OutputData< double > *arg2 = 0 ;
-  double arg3 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
+  PyBuilderCallback *arg2 = 0 ;
+  std::vector< double,std::allocator< double > > *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
   int res2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
+  int res3 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
-  FitObject *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:new_FitObject",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_Simulation,  0  | 0);
+  if (!PyArg_ParseTuple(args,(char *)"OOO:FitObjective_addSimulationAndData_cpp",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_FitObject" "', argument " "1"" of type '" "Simulation const &""'"); 
-  }
-  if (!argp1) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_FitObject" "', argument " "1"" of type '" "Simulation const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "1"" of type '" "FitObjective *""'"); 
   }
-  arg1 = reinterpret_cast< Simulation * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_OutputDataT_double_t,  0  | 0);
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_PyBuilderCallback,  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "new_FitObject" "', argument " "2"" of type '" "OutputData< double > const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "2"" of type '" "PyBuilderCallback &""'"); 
   }
   if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_FitObject" "', argument " "2"" of type '" "OutputData< double > const &""'"); 
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "2"" of type '" "PyBuilderCallback &""'"); 
   }
-  arg2 = reinterpret_cast< OutputData< double > * >(argp2);
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_FitObject" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  result = (FitObject *)new FitObject((Simulation const &)*arg1,(OutputData< double > const &)*arg2,arg3);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitObject, SWIG_POINTER_NEW |  0 );
+  arg2 = reinterpret_cast< PyBuilderCallback * >(argp2);
+  {
+    std::vector< double,std::allocator< double > > *ptr = (std::vector< double,std::allocator< double > > *)0;
+    res3 = swig::asptr(obj2, &ptr);
+    if (!SWIG_IsOK(res3)) {
+      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "3"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "3"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
+    }
+    arg3 = ptr;
+  }
+  (arg1)->addSimulationAndData(*arg2,(std::vector< double,std::allocator< double > > const &)*arg3);
+  resultobj = SWIG_Py_Void();
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return resultobj;
 fail:
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_new_FitObject__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_addSimulationAndData_cpp__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  Simulation *arg1 = 0 ;
-  OutputData< double > *arg2 = 0 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
+  PyBuilderCallback *arg2 = 0 ;
+  std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *arg3 = 0 ;
+  double arg4 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
   int res2 = 0 ;
+  int res3 = SWIG_OLDOBJ ;
+  double val4 ;
+  int ecode4 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  FitObject *result = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:new_FitObject",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_Simulation,  0  | 0);
+  if (!PyArg_ParseTuple(args,(char *)"OOOO:FitObjective_addSimulationAndData_cpp",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_FitObject" "', argument " "1"" of type '" "Simulation const &""'"); 
-  }
-  if (!argp1) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_FitObject" "', argument " "1"" of type '" "Simulation const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "1"" of type '" "FitObjective *""'"); 
   }
-  arg1 = reinterpret_cast< Simulation * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_OutputDataT_double_t,  0  | 0);
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_PyBuilderCallback,  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "new_FitObject" "', argument " "2"" of type '" "OutputData< double > const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "2"" of type '" "PyBuilderCallback &""'"); 
   }
   if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_FitObject" "', argument " "2"" of type '" "OutputData< double > const &""'"); 
-  }
-  arg2 = reinterpret_cast< OutputData< double > * >(argp2);
-  result = (FitObject *)new FitObject((Simulation const &)*arg1,(OutputData< double > const &)*arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitObject, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_FitObject__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  Simulation *arg1 = 0 ;
-  std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *arg2 = 0 ;
-  double arg3 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
-  double val3 ;
-  int ecode3 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  FitObject *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOO:new_FitObject",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_Simulation,  0  | 0);
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_FitObject" "', argument " "1"" of type '" "Simulation const &""'"); 
-  }
-  if (!argp1) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_FitObject" "', argument " "1"" of type '" "Simulation const &""'"); 
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "2"" of type '" "PyBuilderCallback &""'"); 
   }
-  arg1 = reinterpret_cast< Simulation * >(argp1);
+  arg2 = reinterpret_cast< PyBuilderCallback * >(argp2);
   {
     std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *ptr = (std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *)0;
-    res2 = swig::asptr(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "new_FitObject" "', argument " "2"" of type '" "std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &""'"); 
+    res3 = swig::asptr(obj2, &ptr);
+    if (!SWIG_IsOK(res3)) {
+      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "3"" of type '" "std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &""'"); 
     }
     if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_FitObject" "', argument " "2"" of type '" "std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &""'"); 
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "3"" of type '" "std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &""'"); 
     }
-    arg2 = ptr;
+    arg3 = ptr;
   }
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_FitObject" "', argument " "3"" of type '" "double""'");
+  ecode4 = SWIG_AsVal_double(obj3, &val4);
+  if (!SWIG_IsOK(ecode4)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "4"" of type '" "double""'");
   } 
-  arg3 = static_cast< double >(val3);
-  result = (FitObject *)new FitObject((Simulation const &)*arg1,(std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &)*arg2,arg3);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitObject, SWIG_POINTER_NEW |  0 );
-  if (SWIG_IsNewObj(res2)) delete arg2;
+  arg4 = static_cast< double >(val4);
+  (arg1)->addSimulationAndData(*arg2,(std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &)*arg3,arg4);
+  resultobj = SWIG_Py_Void();
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_new_FitObject__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_addSimulationAndData_cpp__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  Simulation *arg1 = 0 ;
-  std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *arg2 = 0 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
+  PyBuilderCallback *arg2 = 0 ;
+  std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  int res3 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  FitObject *result = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:new_FitObject",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_Simulation,  0  | 0);
+  if (!PyArg_ParseTuple(args,(char *)"OOO:FitObjective_addSimulationAndData_cpp",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_FitObject" "', argument " "1"" of type '" "Simulation const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "1"" of type '" "FitObjective *""'"); 
   }
-  if (!argp1) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_FitObject" "', argument " "1"" of type '" "Simulation const &""'"); 
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_PyBuilderCallback,  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "2"" of type '" "PyBuilderCallback &""'"); 
   }
-  arg1 = reinterpret_cast< Simulation * >(argp1);
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "2"" of type '" "PyBuilderCallback &""'"); 
+  }
+  arg2 = reinterpret_cast< PyBuilderCallback * >(argp2);
   {
     std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *ptr = (std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *)0;
-    res2 = swig::asptr(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "new_FitObject" "', argument " "2"" of type '" "std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &""'"); 
+    res3 = swig::asptr(obj2, &ptr);
+    if (!SWIG_IsOK(res3)) {
+      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "3"" of type '" "std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &""'"); 
     }
     if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_FitObject" "', argument " "2"" of type '" "std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &""'"); 
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "3"" of type '" "std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &""'"); 
     }
-    arg2 = ptr;
+    arg3 = ptr;
   }
-  result = (FitObject *)new FitObject((Simulation const &)*arg1,(std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &)*arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitObject, SWIG_POINTER_NEW |  0 );
-  if (SWIG_IsNewObj(res2)) delete arg2;
+  (arg1)->addSimulationAndData(*arg2,(std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &)*arg3);
+  resultobj = SWIG_Py_Void();
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_new_FitObject(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_addSimulationAndData_cpp(PyObject *self, PyObject *args) {
   Py_ssize_t argc;
-  PyObject *argv[4] = {
+  PyObject *argv[5] = {
     0
   };
   Py_ssize_t ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
   argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
+  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  if (argc == 2) {
+  if (argc == 3) {
     int _v;
-    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_Simulation, 0);
+    void *vptr = 0;
+    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0);
     _v = SWIG_CheckState(res);
     if (_v) {
-      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_OutputDataT_double_t, 0);
+      void *vptr = 0;
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_PyBuilderCallback, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_new_FitObject__SWIG_1(self, args);
+        int res = swig::asptr(argv[2], (std::vector< double,std::allocator< double > >**)(0));
+        _v = SWIG_CheckState(res);
+        if (_v) {
+          return _wrap_FitObjective_addSimulationAndData_cpp__SWIG_1(self, args);
+        }
       }
     }
   }
-  if (argc == 2) {
+  if (argc == 3) {
     int _v;
-    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_Simulation, 0);
+    void *vptr = 0;
+    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0);
     _v = SWIG_CheckState(res);
     if (_v) {
-      int res = swig::asptr(argv[1], (std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >**)(0));
+      void *vptr = 0;
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_PyBuilderCallback, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_new_FitObject__SWIG_3(self, args);
+        int res = swig::asptr(argv[2], (std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >**)(0));
+        _v = SWIG_CheckState(res);
+        if (_v) {
+          return _wrap_FitObjective_addSimulationAndData_cpp__SWIG_3(self, args);
+        }
       }
     }
   }
-  if (argc == 3) {
+  if (argc == 4) {
     int _v;
-    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_Simulation, 0);
+    void *vptr = 0;
+    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0);
     _v = SWIG_CheckState(res);
     if (_v) {
-      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_OutputDataT_double_t, 0);
+      void *vptr = 0;
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_PyBuilderCallback, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        {
-          int res = SWIG_AsVal_double(argv[2], NULL);
-          _v = SWIG_CheckState(res);
-        }
+        int res = swig::asptr(argv[2], (std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >**)(0));
+        _v = SWIG_CheckState(res);
         if (_v) {
-          return _wrap_new_FitObject__SWIG_0(self, args);
+          {
+            int res = SWIG_AsVal_double(argv[3], NULL);
+            _v = SWIG_CheckState(res);
+          }
+          if (_v) {
+            return _wrap_FitObjective_addSimulationAndData_cpp__SWIG_2(self, args);
+          }
         }
       }
     }
   }
-  if (argc == 3) {
+  if (argc == 4) {
     int _v;
-    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_Simulation, 0);
+    void *vptr = 0;
+    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0);
     _v = SWIG_CheckState(res);
     if (_v) {
-      int res = swig::asptr(argv[1], (std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >**)(0));
+      void *vptr = 0;
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_PyBuilderCallback, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        {
-          int res = SWIG_AsVal_double(argv[2], NULL);
-          _v = SWIG_CheckState(res);
-        }
+        int res = swig::asptr(argv[2], (std::vector< double,std::allocator< double > >**)(0));
+        _v = SWIG_CheckState(res);
         if (_v) {
-          return _wrap_new_FitObject__SWIG_2(self, args);
-        }
-      }
-    }
-  }
+          {
+            int res = SWIG_AsVal_double(argv[3], NULL);
+            _v = SWIG_CheckState(res);
+          }
+          if (_v) {
+            return _wrap_FitObjective_addSimulationAndData_cpp__SWIG_0(self, args);
+          }
+        }
+      }
+    }
+  }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_FitObject'.\n"
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitObjective_addSimulationAndData_cpp'.\n"
     "  Possible C/C++ prototypes are:\n"
-    "    FitObject::FitObject(Simulation const &,OutputData< double > const &,double)\n"
-    "    FitObject::FitObject(Simulation const &,OutputData< double > const &)\n"
-    "    FitObject::FitObject(Simulation const &,std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &,double)\n"
-    "    FitObject::FitObject(Simulation const &,std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &)\n");
+    "    FitObjective::addSimulationAndData(PyBuilderCallback &,std::vector< double,std::allocator< double > > const &,double)\n"
+    "    FitObjective::addSimulationAndData(PyBuilderCallback &,std::vector< double,std::allocator< double > > const &)\n"
+    "    FitObjective::addSimulationAndData(PyBuilderCallback &,std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &,double)\n"
+    "    FitObjective::addSimulationAndData(PyBuilderCallback &,std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &)\n");
   return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_delete_FitObject(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_evaluate_cpp(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  FitObject *arg1 = (FitObject *) 0 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
+  Fit::Parameters *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  Swig::Director *director = 0;
+  bool upcall = false;
+  double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_FitObject",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObject, SWIG_POINTER_DISOWN |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:FitObjective_evaluate_cpp",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_FitObject" "', argument " "1"" of type '" "FitObject *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_evaluate_cpp" "', argument " "1"" of type '" "FitObjective *""'"); 
   }
-  arg1 = reinterpret_cast< FitObject * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_Fit__Parameters,  0  | 0);
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitObjective_evaluate_cpp" "', argument " "2"" of type '" "Fit::Parameters const &""'"); 
+  }
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObjective_evaluate_cpp" "', argument " "2"" of type '" "Fit::Parameters const &""'"); 
+  }
+  arg2 = reinterpret_cast< Fit::Parameters * >(argp2);
+  director = SWIG_DIRECTOR_CAST(arg1);
+  upcall = (director && (director->swig_get_self()==obj0));
+  try {
+    if (upcall) {
+      result = (double)(arg1)->FitObjective::evaluate((Fit::Parameters const &)*arg2);
+    } else {
+      result = (double)(arg1)->evaluate((Fit::Parameters const &)*arg2);
+    }
+  } catch (Swig::DirectorException&) {
+    SWIG_fail;
+  }
+  resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_FitObject_accept(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_evaluate_residuals_cpp(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  FitObject *arg1 = (FitObject *) 0 ;
-  INodeVisitor *arg2 = (INodeVisitor *) 0 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
+  Fit::Parameters *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
   int res2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  Swig::Director *director = 0;
+  bool upcall = false;
+  std::vector< double,std::allocator< double > > result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitObject_accept",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObject, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:FitObjective_evaluate_residuals_cpp",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObject_accept" "', argument " "1"" of type '" "FitObject const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_evaluate_residuals_cpp" "', argument " "1"" of type '" "FitObjective *""'"); 
   }
-  arg1 = reinterpret_cast< FitObject * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_INodeVisitor, 0 |  0 );
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_Fit__Parameters,  0  | 0);
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitObject_accept" "', argument " "2"" of type '" "INodeVisitor *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitObjective_evaluate_residuals_cpp" "', argument " "2"" of type '" "Fit::Parameters const &""'"); 
   }
-  arg2 = reinterpret_cast< INodeVisitor * >(argp2);
-  ((FitObject const *)arg1)->accept(arg2);
-  resultobj = SWIG_Py_Void();
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObjective_evaluate_residuals_cpp" "', argument " "2"" of type '" "Fit::Parameters const &""'"); 
+  }
+  arg2 = reinterpret_cast< Fit::Parameters * >(argp2);
+  director = SWIG_DIRECTOR_CAST(arg1);
+  upcall = (director && (director->swig_get_self()==obj0));
+  try {
+    if (upcall) {
+      result = (arg1)->FitObjective::evaluate_residuals((Fit::Parameters const &)*arg2);
+    } else {
+      result = (arg1)->evaluate_residuals((Fit::Parameters const &)*arg2);
+    }
+  } catch (Swig::DirectorException&) {
+    SWIG_fail;
+  }
+  resultobj = swig::from(static_cast< std::vector< double,std::allocator< double > > >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_FitObject_weight(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_numberOfFitElements(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  FitObject *arg1 = (FitObject *) 0 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  double result;
+  size_t result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:FitObject_weight",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObject, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_numberOfFitElements",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObject_weight" "', argument " "1"" of type '" "FitObject const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_numberOfFitElements" "', argument " "1"" of type '" "FitObjective const *""'"); 
   }
-  arg1 = reinterpret_cast< FitObject * >(argp1);
-  result = (double)((FitObject const *)arg1)->weight();
-  resultobj = SWIG_From_double(static_cast< double >(result));
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  result = ((FitObjective const *)arg1)->numberOfFitElements();
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_FitObject_numberOfFitElements(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_experimental_array(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  FitObject *arg1 = (FitObject *) 0 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  size_t result;
+  std::vector< double,std::allocator< double > > result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:FitObject_numberOfFitElements",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObject, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_experimental_array",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObject_numberOfFitElements" "', argument " "1"" of type '" "FitObject const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_experimental_array" "', argument " "1"" of type '" "FitObjective const *""'"); 
   }
-  arg1 = reinterpret_cast< FitObject * >(argp1);
-  result = ((FitObject const *)arg1)->numberOfFitElements();
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  result = ((FitObjective const *)arg1)->experimental_array();
+  resultobj = swig::from(static_cast< std::vector< double,std::allocator< double > > >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_FitObject_prepareFitElements__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_simulation_array(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  FitObject *arg1 = (FitObject *) 0 ;
-  std::vector< FitElement,std::allocator< FitElement > > *arg2 = 0 ;
-  double arg3 ;
-  IIntensityNormalizer *arg4 = (IIntensityNormalizer *) 0 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
-  void *argp4 = 0 ;
-  int res4 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  PyObject * obj3 = 0 ;
+  std::vector< double,std::allocator< double > > result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOOO:FitObject_prepareFitElements",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObject, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_simulation_array",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObject_prepareFitElements" "', argument " "1"" of type '" "FitObject *""'"); 
-  }
-  arg1 = reinterpret_cast< FitObject * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__vectorT_FitElement_std__allocatorT_FitElement_t_t,  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitObject_prepareFitElements" "', argument " "2"" of type '" "std::vector< FitElement,std::allocator< FitElement > > &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObject_prepareFitElements" "', argument " "2"" of type '" "std::vector< FitElement,std::allocator< FitElement > > &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_simulation_array" "', argument " "1"" of type '" "FitObjective const *""'"); 
   }
-  arg2 = reinterpret_cast< std::vector< FitElement,std::allocator< FitElement > > * >(argp2);
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "FitObject_prepareFitElements" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  res4 = SWIG_ConvertPtr(obj3, &argp4,SWIGTYPE_p_IIntensityNormalizer, 0 |  0 );
-  if (!SWIG_IsOK(res4)) {
-    SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "FitObject_prepareFitElements" "', argument " "4"" of type '" "IIntensityNormalizer *""'"); 
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  result = ((FitObjective const *)arg1)->simulation_array();
+  resultobj = swig::from(static_cast< std::vector< double,std::allocator< double > > >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_FitObjective_weights_array(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  FitObjective *arg1 = (FitObjective *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::vector< double,std::allocator< double > > result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_weights_array",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_weights_array" "', argument " "1"" of type '" "FitObjective const *""'"); 
   }
-  arg4 = reinterpret_cast< IIntensityNormalizer * >(argp4);
-  (arg1)->prepareFitElements(*arg2,arg3,arg4);
-  resultobj = SWIG_Py_Void();
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  result = ((FitObjective const *)arg1)->weights_array();
+  resultobj = swig::from(static_cast< std::vector< double,std::allocator< double > > >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_FitObject_prepareFitElements__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_simulationResult__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  FitObject *arg1 = (FitObject *) 0 ;
-  std::vector< FitElement,std::allocator< FitElement > > *arg2 = 0 ;
-  double arg3 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
+  size_t arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
+  size_t val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
+  SimulationResult result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:FitObject_prepareFitElements",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObject, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:FitObjective_simulationResult",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObject_prepareFitElements" "', argument " "1"" of type '" "FitObject *""'"); 
-  }
-  arg1 = reinterpret_cast< FitObject * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__vectorT_FitElement_std__allocatorT_FitElement_t_t,  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitObject_prepareFitElements" "', argument " "2"" of type '" "std::vector< FitElement,std::allocator< FitElement > > &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObject_prepareFitElements" "', argument " "2"" of type '" "std::vector< FitElement,std::allocator< FitElement > > &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_simulationResult" "', argument " "1"" of type '" "FitObjective const *""'"); 
   }
-  arg2 = reinterpret_cast< std::vector< FitElement,std::allocator< FitElement > > * >(argp2);
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "FitObject_prepareFitElements" "', argument " "3"" of type '" "double""'");
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitObjective_simulationResult" "', argument " "2"" of type '" "size_t""'");
   } 
-  arg3 = static_cast< double >(val3);
-  (arg1)->prepareFitElements(*arg2,arg3);
-  resultobj = SWIG_Py_Void();
+  arg2 = static_cast< size_t >(val2);
+  result = ((FitObjective const *)arg1)->simulationResult(arg2);
+  resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_FitObjective_simulationResult__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  FitObjective *arg1 = (FitObjective *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  SimulationResult result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_simulationResult",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_simulationResult" "', argument " "1"" of type '" "FitObjective const *""'"); 
+  }
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  result = ((FitObjective const *)arg1)->simulationResult();
+  resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_FitObject_prepareFitElements(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_simulationResult(PyObject *self, PyObject *args) {
   Py_ssize_t argc;
-  PyObject *argv[5] = {
+  PyObject *argv[3] = {
     0
   };
   Py_ssize_t ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
   argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
+  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  if (argc == 3) {
+  if (argc == 1) {
     int _v;
     void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObject, 0);
+    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0);
     _v = SWIG_CheckState(res);
     if (_v) {
-      void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_std__vectorT_FitElement_std__allocatorT_FitElement_t_t, 0);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        {
-          int res = SWIG_AsVal_double(argv[2], NULL);
-          _v = SWIG_CheckState(res);
-        }
-        if (_v) {
-          return _wrap_FitObject_prepareFitElements__SWIG_1(self, args);
-        }
-      }
+      return _wrap_FitObjective_simulationResult__SWIG_1(self, args);
     }
   }
-  if (argc == 4) {
+  if (argc == 2) {
     int _v;
     void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObject, 0);
+    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0);
     _v = SWIG_CheckState(res);
     if (_v) {
-      void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_std__vectorT_FitElement_std__allocatorT_FitElement_t_t, 0);
-      _v = SWIG_CheckState(res);
+      {
+        int res = SWIG_AsVal_size_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
       if (_v) {
-        {
-          int res = SWIG_AsVal_double(argv[2], NULL);
-          _v = SWIG_CheckState(res);
-        }
-        if (_v) {
-          void *vptr = 0;
-          int res = SWIG_ConvertPtr(argv[3], &vptr, SWIGTYPE_p_IIntensityNormalizer, 0);
-          _v = SWIG_CheckState(res);
-          if (_v) {
-            return _wrap_FitObject_prepareFitElements__SWIG_0(self, args);
-          }
-        }
+        return _wrap_FitObjective_simulationResult__SWIG_0(self, args);
       }
     }
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitObject_prepareFitElements'.\n"
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitObjective_simulationResult'.\n"
     "  Possible C/C++ prototypes are:\n"
-    "    FitObject::prepareFitElements(std::vector< FitElement,std::allocator< FitElement > > &,double,IIntensityNormalizer *)\n"
-    "    FitObject::prepareFitElements(std::vector< FitElement,std::allocator< FitElement > > &,double)\n");
+    "    FitObjective::simulationResult(size_t) const\n"
+    "    FitObjective::simulationResult() const\n");
   return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_FitObject_getChildren(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_experimentalData__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  FitObject *arg1 = (FitObject *) 0 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
+  size_t arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  size_t val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  std::vector< INode const *,std::allocator< INode const * > > result;
+  PyObject * obj1 = 0 ;
+  SimulationResult result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:FitObject_getChildren",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObject, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:FitObjective_experimentalData",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObject_getChildren" "', argument " "1"" of type '" "FitObject const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_experimentalData" "', argument " "1"" of type '" "FitObjective const *""'"); 
   }
-  arg1 = reinterpret_cast< FitObject * >(argp1);
-  result = ((FitObject const *)arg1)->getChildren();
-  resultobj = swig::from(static_cast< std::vector< INode const*,std::allocator< INode const * > > >(result));
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitObjective_experimentalData" "', argument " "2"" of type '" "size_t""'");
+  } 
+  arg2 = static_cast< size_t >(val2);
+  result = ((FitObjective const *)arg1)->experimentalData(arg2);
+  resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_FitObject_simulationResult(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_experimentalData__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  FitObject *arg1 = (FitObject *) 0 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
   SimulationResult result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:FitObject_simulationResult",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObject, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_experimentalData",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObject_simulationResult" "', argument " "1"" of type '" "FitObject const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_experimentalData" "', argument " "1"" of type '" "FitObjective const *""'"); 
   }
-  arg1 = reinterpret_cast< FitObject * >(argp1);
-  result = ((FitObject const *)arg1)->simulationResult();
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  result = ((FitObjective const *)arg1)->experimentalData();
   resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
@@ -46470,43 +45515,76 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_FitObject_experimentalData(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitObject *arg1 = (FitObject *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  SimulationResult result;
+SWIGINTERN PyObject *_wrap_FitObjective_experimentalData(PyObject *self, PyObject *args) {
+  Py_ssize_t argc;
+  PyObject *argv[3] = {
+    0
+  };
+  Py_ssize_t ii;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:FitObject_experimentalData",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObject, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObject_experimentalData" "', argument " "1"" of type '" "FitObject const *""'"); 
+  if (!PyTuple_Check(args)) SWIG_fail;
+  argc = args ? PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
+    argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  arg1 = reinterpret_cast< FitObject * >(argp1);
-  result = ((FitObject const *)arg1)->experimentalData();
-  resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
-  return resultobj;
+  if (argc == 1) {
+    int _v;
+    void *vptr = 0;
+    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0);
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      return _wrap_FitObjective_experimentalData__SWIG_1(self, args);
+    }
+  }
+  if (argc == 2) {
+    int _v;
+    void *vptr = 0;
+    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0);
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        int res = SWIG_AsVal_size_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        return _wrap_FitObjective_experimentalData__SWIG_0(self, args);
+      }
+    }
+  }
+  
 fail:
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitObjective_experimentalData'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    FitObjective::experimentalData(size_t) const\n"
+    "    FitObjective::experimentalData() const\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_FitObject_relativeDifference(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_relativeDifference__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  FitObject *arg1 = (FitObject *) 0 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
+  size_t arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  size_t val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
   SimulationResult result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:FitObject_relativeDifference",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObject, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:FitObjective_relativeDifference",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObject_relativeDifference" "', argument " "1"" of type '" "FitObject const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_relativeDifference" "', argument " "1"" of type '" "FitObjective const *""'"); 
   }
-  arg1 = reinterpret_cast< FitObject * >(argp1);
-  result = ((FitObject const *)arg1)->relativeDifference();
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitObjective_relativeDifference" "', argument " "2"" of type '" "size_t""'");
+  } 
+  arg2 = static_cast< size_t >(val2);
+  result = ((FitObjective const *)arg1)->relativeDifference(arg2);
   resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
@@ -46514,188 +45592,196 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_FitObject_runSimulation(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_relativeDifference__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  FitObject *arg1 = (FitObject *) 0 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  SimulationResult result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:FitObject_runSimulation",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObject, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_relativeDifference",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObject_runSimulation" "', argument " "1"" of type '" "FitObject *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_relativeDifference" "', argument " "1"" of type '" "FitObjective const *""'"); 
   }
-  arg1 = reinterpret_cast< FitObject * >(argp1);
-  (arg1)->runSimulation();
-  resultobj = SWIG_Py_Void();
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  result = ((FitObjective const *)arg1)->relativeDifference();
+  resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_FitObject_experimental_array(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitObject *arg1 = (FitObject *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  std::vector< double,std::allocator< double > > result;
+SWIGINTERN PyObject *_wrap_FitObjective_relativeDifference(PyObject *self, PyObject *args) {
+  Py_ssize_t argc;
+  PyObject *argv[3] = {
+    0
+  };
+  Py_ssize_t ii;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:FitObject_experimental_array",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObject, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObject_experimental_array" "', argument " "1"" of type '" "FitObject const *""'"); 
+  if (!PyTuple_Check(args)) SWIG_fail;
+  argc = args ? PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
+    argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  arg1 = reinterpret_cast< FitObject * >(argp1);
-  result = ((FitObject const *)arg1)->experimental_array();
-  resultobj = swig::from(static_cast< std::vector< double,std::allocator< double > > >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitObject_simulation_array(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitObject *arg1 = (FitObject *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  std::vector< double,std::allocator< double > > result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitObject_simulation_array",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObject, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObject_simulation_array" "', argument " "1"" of type '" "FitObject const *""'"); 
+  if (argc == 1) {
+    int _v;
+    void *vptr = 0;
+    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0);
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      return _wrap_FitObjective_relativeDifference__SWIG_1(self, args);
+    }
+  }
+  if (argc == 2) {
+    int _v;
+    void *vptr = 0;
+    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0);
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        int res = SWIG_AsVal_size_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        return _wrap_FitObjective_relativeDifference__SWIG_0(self, args);
+      }
+    }
   }
-  arg1 = reinterpret_cast< FitObject * >(argp1);
-  result = ((FitObject const *)arg1)->simulation_array();
-  resultobj = swig::from(static_cast< std::vector< double,std::allocator< double > > >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *FitObject_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_FitObject, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *_wrap_new_FitOptions(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitOptions *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)":new_FitOptions")) SWIG_fail;
-  result = (FitOptions *)new FitOptions();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitOptions, SWIG_POINTER_NEW |  0 );
-  return resultobj;
 fail:
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitObjective_relativeDifference'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    FitObjective::relativeDifference(size_t) const\n"
+    "    FitObjective::relativeDifference() const\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_FitOptions_derivEpsilon(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_absoluteDifference__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  FitOptions *arg1 = (FitOptions *) 0 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
+  size_t arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  size_t val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  double result;
+  PyObject * obj1 = 0 ;
+  SimulationResult result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:FitOptions_derivEpsilon",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitOptions, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:FitObjective_absoluteDifference",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitOptions_derivEpsilon" "', argument " "1"" of type '" "FitOptions const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_absoluteDifference" "', argument " "1"" of type '" "FitObjective const *""'"); 
   }
-  arg1 = reinterpret_cast< FitOptions * >(argp1);
-  result = (double)((FitOptions const *)arg1)->derivEpsilon();
-  resultobj = SWIG_From_double(static_cast< double >(result));
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitObjective_absoluteDifference" "', argument " "2"" of type '" "size_t""'");
+  } 
+  arg2 = static_cast< size_t >(val2);
+  result = ((FitObjective const *)arg1)->absoluteDifference(arg2);
+  resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_FitOptions_setDerivEpsilon(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_absoluteDifference__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  FitOptions *arg1 = (FitOptions *) 0 ;
-  double arg2 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  SimulationResult result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitOptions_setDerivEpsilon",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitOptions, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_absoluteDifference",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitOptions_setDerivEpsilon" "', argument " "1"" of type '" "FitOptions *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_absoluteDifference" "', argument " "1"" of type '" "FitObjective const *""'"); 
   }
-  arg1 = reinterpret_cast< FitOptions * >(argp1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitOptions_setDerivEpsilon" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  (arg1)->setDerivEpsilon(arg2);
-  resultobj = SWIG_Py_Void();
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  result = ((FitObjective const *)arg1)->absoluteDifference();
+  resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_FitOptions_stepFactor(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitOptions *arg1 = (FitOptions *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  double result;
+SWIGINTERN PyObject *_wrap_FitObjective_absoluteDifference(PyObject *self, PyObject *args) {
+  Py_ssize_t argc;
+  PyObject *argv[3] = {
+    0
+  };
+  Py_ssize_t ii;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:FitOptions_stepFactor",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitOptions, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitOptions_stepFactor" "', argument " "1"" of type '" "FitOptions const *""'"); 
+  if (!PyTuple_Check(args)) SWIG_fail;
+  argc = args ? PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
+    argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  arg1 = reinterpret_cast< FitOptions * >(argp1);
-  result = (double)((FitOptions const *)arg1)->stepFactor();
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
+  if (argc == 1) {
+    int _v;
+    void *vptr = 0;
+    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0);
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      return _wrap_FitObjective_absoluteDifference__SWIG_1(self, args);
+    }
+  }
+  if (argc == 2) {
+    int _v;
+    void *vptr = 0;
+    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0);
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        int res = SWIG_AsVal_size_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        return _wrap_FitObjective_absoluteDifference__SWIG_0(self, args);
+      }
+    }
+  }
+  
 fail:
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitObjective_absoluteDifference'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    FitObjective::absoluteDifference(size_t) const\n"
+    "    FitObjective::absoluteDifference() const\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_FitOptions_setStepFactor(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_initPrint(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  FitOptions *arg1 = (FitOptions *) 0 ;
-  double arg2 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
+  int arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  double val2 ;
+  int val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitOptions_setStepFactor",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitOptions, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:FitObjective_initPrint",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitOptions_setStepFactor" "', argument " "1"" of type '" "FitOptions *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_initPrint" "', argument " "1"" of type '" "FitObjective *""'"); 
   }
-  arg1 = reinterpret_cast< FitOptions * >(argp1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitOptions_setStepFactor" "', argument " "2"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitObjective_initPrint" "', argument " "2"" of type '" "int""'");
   } 
-  arg2 = static_cast< double >(val2);
-  (arg1)->setStepFactor(arg2);
+  arg2 = static_cast< int >(val2);
+  (arg1)->initPrint(arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -46703,477 +45789,293 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_delete_FitOptions(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_initPlot_cpp(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  FitOptions *arg1 = (FitOptions *) 0 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
+  int arg2 ;
+  PyObserverCallback *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_FitOptions",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitOptions, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_FitOptions" "', argument " "1"" of type '" "FitOptions *""'"); 
-  }
-  arg1 = reinterpret_cast< FitOptions * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *FitOptions_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_FitOptions, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *_wrap_new_IFitParameter__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IFitParameter *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)":new_IFitParameter")) SWIG_fail;
-  result = (IFitParameter *)new IFitParameter();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IFitParameter, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_IFitParameter__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::string *arg1 = 0 ;
-  double arg2 ;
-  AttLimits *arg3 = 0 ;
-  double arg4 ;
-  int res1 = SWIG_OLDOBJ ;
-  double val2 ;
+  int val2 ;
   int ecode2 = 0 ;
   void *argp3 = 0 ;
   int res3 = 0 ;
-  double val4 ;
-  int ecode4 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
-  PyObject * obj3 = 0 ;
-  IFitParameter *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOOO:new_IFitParameter",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  {
-    std::string *ptr = (std::string *)0;
-    res1 = SWIG_AsPtr_std_string(obj0, &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_IFitParameter" "', argument " "1"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_IFitParameter" "', argument " "1"" of type '" "std::string const &""'"); 
-    }
-    arg1 = ptr;
+  if (!PyArg_ParseTuple(args,(char *)"OOO:FitObjective_initPlot_cpp",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_initPlot_cpp" "', argument " "1"" of type '" "FitObjective *""'"); 
   }
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_IFitParameter" "', argument " "2"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitObjective_initPlot_cpp" "', argument " "2"" of type '" "int""'");
   } 
-  arg2 = static_cast< double >(val2);
-  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_AttLimits,  0  | 0);
+  arg2 = static_cast< int >(val2);
+  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_PyObserverCallback,  0 );
   if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "new_IFitParameter" "', argument " "3"" of type '" "AttLimits const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "FitObjective_initPlot_cpp" "', argument " "3"" of type '" "PyObserverCallback &""'"); 
   }
   if (!argp3) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_IFitParameter" "', argument " "3"" of type '" "AttLimits const &""'"); 
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObjective_initPlot_cpp" "', argument " "3"" of type '" "PyObserverCallback &""'"); 
   }
-  arg3 = reinterpret_cast< AttLimits * >(argp3);
-  ecode4 = SWIG_AsVal_double(obj3, &val4);
-  if (!SWIG_IsOK(ecode4)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "new_IFitParameter" "', argument " "4"" of type '" "double""'");
-  } 
-  arg4 = static_cast< double >(val4);
-  result = (IFitParameter *)new IFitParameter((std::string const &)*arg1,arg2,(AttLimits const &)*arg3,arg4);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IFitParameter, SWIG_POINTER_NEW |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
+  arg3 = reinterpret_cast< PyObserverCallback * >(argp3);
+  (arg1)->initPlot(arg2,*arg3);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_new_IFitParameter__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_isCompleted(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::string *arg1 = 0 ;
-  double arg2 ;
-  AttLimits *arg3 = 0 ;
-  int res1 = SWIG_OLDOBJ ;
-  double val2 ;
-  int ecode2 = 0 ;
-  void *argp3 = 0 ;
-  int res3 = 0 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  IFitParameter *result = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:new_IFitParameter",&obj0,&obj1,&obj2)) SWIG_fail;
-  {
-    std::string *ptr = (std::string *)0;
-    res1 = SWIG_AsPtr_std_string(obj0, &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_IFitParameter" "', argument " "1"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_IFitParameter" "', argument " "1"" of type '" "std::string const &""'"); 
-    }
-    arg1 = ptr;
-  }
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_IFitParameter" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_AttLimits,  0  | 0);
-  if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "new_IFitParameter" "', argument " "3"" of type '" "AttLimits const &""'"); 
-  }
-  if (!argp3) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_IFitParameter" "', argument " "3"" of type '" "AttLimits const &""'"); 
+  if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_isCompleted",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_isCompleted" "', argument " "1"" of type '" "FitObjective const *""'"); 
   }
-  arg3 = reinterpret_cast< AttLimits * >(argp3);
-  result = (IFitParameter *)new IFitParameter((std::string const &)*arg1,arg2,(AttLimits const &)*arg3);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IFitParameter, SWIG_POINTER_NEW |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  result = (bool)((FitObjective const *)arg1)->isCompleted();
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_new_IFitParameter__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_iterationInfo(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::string *arg1 = 0 ;
-  double arg2 ;
-  int res1 = SWIG_OLDOBJ ;
-  double val2 ;
-  int ecode2 = 0 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  IFitParameter *result = 0 ;
+  IterationInfo result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:new_IFitParameter",&obj0,&obj1)) SWIG_fail;
-  {
-    std::string *ptr = (std::string *)0;
-    res1 = SWIG_AsPtr_std_string(obj0, &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_IFitParameter" "', argument " "1"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_IFitParameter" "', argument " "1"" of type '" "std::string const &""'"); 
-    }
-    arg1 = ptr;
+  if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_iterationInfo",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_iterationInfo" "', argument " "1"" of type '" "FitObjective const *""'"); 
   }
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_IFitParameter" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  result = (IFitParameter *)new IFitParameter((std::string const &)*arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IFitParameter, SWIG_POINTER_NEW |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  result = ((FitObjective const *)arg1)->iterationInfo();
+  resultobj = SWIG_NewPointerObj((new IterationInfo(static_cast< const IterationInfo& >(result))), SWIGTYPE_p_IterationInfo, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_new_IFitParameter(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[5] = {
-    0
-  };
-  Py_ssize_t ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 0) {
-    return _wrap_new_IFitParameter__SWIG_0(self, args);
-  }
-  if (argc == 2) {
-    int _v;
-    int res = SWIG_AsPtr_std_string(argv[0], (std::string**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_double(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_new_IFitParameter__SWIG_3(self, args);
-      }
-    }
-  }
-  if (argc == 3) {
-    int _v;
-    int res = SWIG_AsPtr_std_string(argv[0], (std::string**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_double(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_AttLimits, 0);
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          return _wrap_new_IFitParameter__SWIG_2(self, args);
-        }
-      }
-    }
-  }
-  if (argc == 4) {
-    int _v;
-    int res = SWIG_AsPtr_std_string(argv[0], (std::string**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_double(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_AttLimits, 0);
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          {
-            int res = SWIG_AsVal_double(argv[3], NULL);
-            _v = SWIG_CheckState(res);
-          }
-          if (_v) {
-            return _wrap_new_IFitParameter__SWIG_1(self, args);
-          }
-        }
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_IFitParameter'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    IFitParameter::IFitParameter()\n"
-    "    IFitParameter::IFitParameter(std::string const &,double,AttLimits const &,double)\n"
-    "    IFitParameter::IFitParameter(std::string const &,double,AttLimits const &)\n"
-    "    IFitParameter::IFitParameter(std::string const &,double)\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_delete_IFitParameter(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_minimizerResult(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  IFitParameter *arg1 = (IFitParameter *) 0 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  Fit::MinimizerResult result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_IFitParameter",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IFitParameter, SWIG_POINTER_DISOWN |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_minimizerResult",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IFitParameter" "', argument " "1"" of type '" "IFitParameter *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_minimizerResult" "', argument " "1"" of type '" "FitObjective const *""'"); 
   }
-  arg1 = reinterpret_cast< IFitParameter * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  result = ((FitObjective const *)arg1)->minimizerResult();
+  resultobj = SWIG_NewPointerObj((new Fit::MinimizerResult(static_cast< const Fit::MinimizerResult& >(result))), SWIGTYPE_p_Fit__MinimizerResult, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_IFitParameter_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_finalize_cpp(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  IFitParameter *arg1 = (IFitParameter *) 0 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
+  Fit::MinimizerResult *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
   PyObject * obj0 = 0 ;
-  IFitParameter *result = 0 ;
+  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:IFitParameter_clone",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IFitParameter, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:FitObjective_finalize_cpp",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFitParameter_clone" "', argument " "1"" of type '" "IFitParameter const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_finalize_cpp" "', argument " "1"" of type '" "FitObjective *""'"); 
+  }
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_Fit__MinimizerResult,  0  | 0);
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitObjective_finalize_cpp" "', argument " "2"" of type '" "Fit::MinimizerResult const &""'"); 
   }
-  arg1 = reinterpret_cast< IFitParameter * >(argp1);
-  result = (IFitParameter *)((IFitParameter const *)arg1)->clone();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IFitParameter, 0 |  0 );
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObjective_finalize_cpp" "', argument " "2"" of type '" "Fit::MinimizerResult const &""'"); 
+  }
+  arg2 = reinterpret_cast< Fit::MinimizerResult * >(argp2);
+  (arg1)->finalize((Fit::MinimizerResult const &)*arg2);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_IFitParameter_name(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_fitObjectCount(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  IFitParameter *arg1 = (IFitParameter *) 0 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  std::string result;
+  unsigned int result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:IFitParameter_name",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IFitParameter, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_fitObjectCount",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFitParameter_name" "', argument " "1"" of type '" "IFitParameter const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_fitObjectCount" "', argument " "1"" of type '" "FitObjective const *""'"); 
   }
-  arg1 = reinterpret_cast< IFitParameter * >(argp1);
-  result = ((IFitParameter const *)arg1)->name();
-  resultobj = SWIG_From_std_string(static_cast< std::string >(result));
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  result = (unsigned int)((FitObjective const *)arg1)->fitObjectCount();
+  resultobj = SWIG_From_unsigned_SS_int(static_cast< unsigned int >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_IFitParameter_setName(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_interruptFitting(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  IFitParameter *arg1 = (IFitParameter *) 0 ;
-  std::string *arg2 = 0 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  IFitParameter *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:IFitParameter_setName",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IFitParameter, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_interruptFitting",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFitParameter_setName" "', argument " "1"" of type '" "IFitParameter *""'"); 
-  }
-  arg1 = reinterpret_cast< IFitParameter * >(argp1);
-  {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IFitParameter_setName" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IFitParameter_setName" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    arg2 = ptr;
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_interruptFitting" "', argument " "1"" of type '" "FitObjective *""'"); 
   }
-  result = (IFitParameter *) &(arg1)->setName((std::string const &)*arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IFitParameter, 0 |  0 );
-  if (SWIG_IsNewObj(res2)) delete arg2;
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  (arg1)->interruptFitting();
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_IFitParameter_startValue(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_isInterrupted(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  IFitParameter *arg1 = (IFitParameter *) 0 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  double result;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:IFitParameter_startValue",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IFitParameter, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_isInterrupted",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFitParameter_startValue" "', argument " "1"" of type '" "IFitParameter const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_isInterrupted" "', argument " "1"" of type '" "FitObjective const *""'"); 
   }
-  arg1 = reinterpret_cast< IFitParameter * >(argp1);
-  result = (double)((IFitParameter const *)arg1)->startValue();
-  resultobj = SWIG_From_double(static_cast< double >(result));
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  result = (bool)((FitObjective const *)arg1)->isInterrupted();
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_IFitParameter_setStartValue(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_isFirstIteration(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  IFitParameter *arg1 = (IFitParameter *) 0 ;
-  double arg2 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:IFitParameter_setStartValue",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IFitParameter, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_isFirstIteration",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFitParameter_setStartValue" "', argument " "1"" of type '" "IFitParameter *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_isFirstIteration" "', argument " "1"" of type '" "FitObjective const *""'"); 
   }
-  arg1 = reinterpret_cast< IFitParameter * >(argp1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IFitParameter_setStartValue" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  (arg1)->setStartValue(arg2);
-  resultobj = SWIG_Py_Void();
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  result = (bool)((FitObjective const *)arg1)->isFirstIteration();
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_IFitParameter_value(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_run_simulations(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  IFitParameter *arg1 = (IFitParameter *) 0 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
+  Fit::Parameters *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
   PyObject * obj0 = 0 ;
-  double result;
+  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:IFitParameter_value",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IFitParameter, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:FitObjective_run_simulations",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFitParameter_value" "', argument " "1"" of type '" "IFitParameter const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_run_simulations" "', argument " "1"" of type '" "FitObjective *""'"); 
   }
-  arg1 = reinterpret_cast< IFitParameter * >(argp1);
-  result = (double)((IFitParameter const *)arg1)->value();
-  resultobj = SWIG_From_double(static_cast< double >(result));
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_Fit__Parameters,  0  | 0);
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitObjective_run_simulations" "', argument " "2"" of type '" "Fit::Parameters const &""'"); 
+  }
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObjective_run_simulations" "', argument " "2"" of type '" "Fit::Parameters const &""'"); 
+  }
+  arg2 = reinterpret_cast< Fit::Parameters * >(argp2);
+  (arg1)->run_simulations((Fit::Parameters const &)*arg2);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_IFitParameter_setValue(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_FitObjective_setChiSquaredModule(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  IFitParameter *arg1 = (IFitParameter *) 0 ;
-  double arg2 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
+  IChiSquaredModule *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:IFitParameter_setValue",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IFitParameter, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:FitObjective_setChiSquaredModule",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFitParameter_setValue" "', argument " "1"" of type '" "IFitParameter *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_setChiSquaredModule" "', argument " "1"" of type '" "FitObjective *""'"); 
   }
-  arg1 = reinterpret_cast< IFitParameter * >(argp1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IFitParameter_setValue" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  (arg1)->setValue(arg2);
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_IChiSquaredModule,  0  | 0);
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitObjective_setChiSquaredModule" "', argument " "2"" of type '" "IChiSquaredModule const &""'"); 
+  }
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObjective_setChiSquaredModule" "', argument " "2"" of type '" "IChiSquaredModule const &""'"); 
+  }
+  arg2 = reinterpret_cast< IChiSquaredModule * >(argp2);
+  (arg1)->setChiSquaredModule((IChiSquaredModule const &)*arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -47181,59 +46083,53 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_IFitParameter_addPattern(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_disown_FitObjective(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  IFitParameter *arg1 = (IFitParameter *) 0 ;
-  std::string *arg2 = 0 ;
+  FitObjective *arg1 = (FitObjective *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  IFitParameter *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:IFitParameter_addPattern",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IFitParameter, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:disown_FitObjective",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFitParameter_addPattern" "', argument " "1"" of type '" "IFitParameter *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "disown_FitObjective" "', argument " "1"" of type '" "FitObjective *""'"); 
   }
-  arg1 = reinterpret_cast< IFitParameter * >(argp1);
+  arg1 = reinterpret_cast< FitObjective * >(argp1);
   {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IFitParameter_addPattern" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IFitParameter_addPattern" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    arg2 = ptr;
+    Swig::Director *director = SWIG_DIRECTOR_CAST(arg1);
+    if (director) director->swig_disown();
   }
-  result = (IFitParameter *) &(arg1)->addPattern((std::string const &)*arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IFitParameter, 0 |  0 );
-  if (SWIG_IsNewObj(res2)) delete arg2;
+  
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_IFitParameter_step(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *FitObjective_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *obj;
+  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_FitObjective, SWIG_NewClientData(obj));
+  return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *_wrap_StandardNormal(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  IFitParameter *arg1 = (IFitParameter *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
+  double arg1 ;
+  double val1 ;
+  int ecode1 = 0 ;
   PyObject * obj0 = 0 ;
   double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:IFitParameter_step",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IFitParameter, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFitParameter_step" "', argument " "1"" of type '" "IFitParameter const *""'"); 
-  }
-  arg1 = reinterpret_cast< IFitParameter * >(argp1);
-  result = (double)((IFitParameter const *)arg1)->step();
+  if (!PyArg_ParseTuple(args,(char *)"O:StandardNormal",&obj0)) SWIG_fail;
+  ecode1 = SWIG_AsVal_double(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "StandardNormal" "', argument " "1"" of type '" "double""'");
+  } 
+  arg1 = static_cast< double >(val1);
+  result = (double)MathFunctions::StandardNormal(arg1);
   resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
@@ -47241,52 +46137,39 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_IFitParameter_setStep(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_Gaussian(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  IFitParameter *arg1 = (IFitParameter *) 0 ;
+  double arg1 ;
   double arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
+  double arg3 ;
+  double val1 ;
+  int ecode1 = 0 ;
   double val2 ;
   int ecode2 = 0 ;
+  double val3 ;
+  int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  IFitParameter *result = 0 ;
+  PyObject * obj2 = 0 ;
+  double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:IFitParameter_setStep",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IFitParameter, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFitParameter_setStep" "', argument " "1"" of type '" "IFitParameter *""'"); 
-  }
-  arg1 = reinterpret_cast< IFitParameter * >(argp1);
+  if (!PyArg_ParseTuple(args,(char *)"OOO:Gaussian",&obj0,&obj1,&obj2)) SWIG_fail;
+  ecode1 = SWIG_AsVal_double(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "Gaussian" "', argument " "1"" of type '" "double""'");
+  } 
+  arg1 = static_cast< double >(val1);
   ecode2 = SWIG_AsVal_double(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IFitParameter_setStep" "', argument " "2"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Gaussian" "', argument " "2"" of type '" "double""'");
   } 
   arg2 = static_cast< double >(val2);
-  result = (IFitParameter *) &(arg1)->setStep(arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IFitParameter, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IFitParameter_error(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IFitParameter *arg1 = (IFitParameter *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  double result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:IFitParameter_error",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IFitParameter, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFitParameter_error" "', argument " "1"" of type '" "IFitParameter const *""'"); 
-  }
-  arg1 = reinterpret_cast< IFitParameter * >(argp1);
-  result = (double)((IFitParameter const *)arg1)->error();
+  ecode3 = SWIG_AsVal_double(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Gaussian" "', argument " "3"" of type '" "double""'");
+  } 
+  arg3 = static_cast< double >(val3);
+  result = (double)MathFunctions::Gaussian(arg1,arg2,arg3);
   resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
@@ -47294,6243 +46177,84 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_IFitParameter_setError(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_IntegratedGaussian(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  IFitParameter *arg1 = (IFitParameter *) 0 ;
+  double arg1 ;
   double arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
+  double arg3 ;
+  double val1 ;
+  int ecode1 = 0 ;
   double val2 ;
   int ecode2 = 0 ;
+  double val3 ;
+  int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:IFitParameter_setError",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IFitParameter, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFitParameter_setError" "', argument " "1"" of type '" "IFitParameter *""'"); 
-  }
-  arg1 = reinterpret_cast< IFitParameter * >(argp1);
+  if (!PyArg_ParseTuple(args,(char *)"OOO:IntegratedGaussian",&obj0,&obj1,&obj2)) SWIG_fail;
+  ecode1 = SWIG_AsVal_double(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "IntegratedGaussian" "', argument " "1"" of type '" "double""'");
+  } 
+  arg1 = static_cast< double >(val1);
   ecode2 = SWIG_AsVal_double(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IFitParameter_setError" "', argument " "2"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntegratedGaussian" "', argument " "2"" of type '" "double""'");
   } 
   arg2 = static_cast< double >(val2);
-  (arg1)->setError(arg2);
-  resultobj = SWIG_Py_Void();
+  ecode3 = SWIG_AsVal_double(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntegratedGaussian" "', argument " "3"" of type '" "double""'");
+  } 
+  arg3 = static_cast< double >(val3);
+  result = (double)MathFunctions::IntegratedGaussian(arg1,arg2,arg3);
+  resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_IFitParameter_limits__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_cot(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  IFitParameter *arg1 = (IFitParameter *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
+  double arg1 ;
+  double val1 ;
+  int ecode1 = 0 ;
   PyObject * obj0 = 0 ;
-  AttLimits *result = 0 ;
+  double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:IFitParameter_limits",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IFitParameter, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFitParameter_limits" "', argument " "1"" of type '" "IFitParameter const *""'"); 
-  }
-  arg1 = reinterpret_cast< IFitParameter * >(argp1);
-  result = (AttLimits *) &((IFitParameter const *)arg1)->limits();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_AttLimits, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:cot",&obj0)) SWIG_fail;
+  ecode1 = SWIG_AsVal_double(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "cot" "', argument " "1"" of type '" "double""'");
+  } 
+  arg1 = static_cast< double >(val1);
+  result = (double)MathFunctions::cot(arg1);
+  resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_IFitParameter_limits__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_Si(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  IFitParameter *arg1 = (IFitParameter *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
+  double arg1 ;
+  double val1 ;
+  int ecode1 = 0 ;
   PyObject * obj0 = 0 ;
-  AttLimits *result = 0 ;
+  double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:IFitParameter_limits",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IFitParameter, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFitParameter_limits" "', argument " "1"" of type '" "IFitParameter *""'"); 
-  }
-  arg1 = reinterpret_cast< IFitParameter * >(argp1);
-  result = (AttLimits *) &(arg1)->limits();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_AttLimits, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IFitParameter_limits(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[2] = {
-    0
-  };
-  Py_ssize_t ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 1) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_IFitParameter, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_IFitParameter_limits__SWIG_1(self, args);
-    }
-  }
-  if (argc == 1) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_IFitParameter, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_IFitParameter_limits__SWIG_0(self, args);
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'IFitParameter_limits'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    IFitParameter::limits() const\n"
-    "    IFitParameter::limits()\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_IFitParameter_setLimits(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IFitParameter *arg1 = (IFitParameter *) 0 ;
-  AttLimits *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  IFitParameter *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:IFitParameter_setLimits",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IFitParameter, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFitParameter_setLimits" "', argument " "1"" of type '" "IFitParameter *""'"); 
-  }
-  arg1 = reinterpret_cast< IFitParameter * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_AttLimits,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IFitParameter_setLimits" "', argument " "2"" of type '" "AttLimits const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IFitParameter_setLimits" "', argument " "2"" of type '" "AttLimits const &""'"); 
-  }
-  arg2 = reinterpret_cast< AttLimits * >(argp2);
-  result = (IFitParameter *) &(arg1)->setLimits((AttLimits const &)*arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IFitParameter, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IFitParameter_setLowerLimited(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IFitParameter *arg1 = (IFitParameter *) 0 ;
-  double arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  IFitParameter *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:IFitParameter_setLowerLimited",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IFitParameter, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFitParameter_setLowerLimited" "', argument " "1"" of type '" "IFitParameter *""'"); 
-  }
-  arg1 = reinterpret_cast< IFitParameter * >(argp1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IFitParameter_setLowerLimited" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  result = (IFitParameter *) &(arg1)->setLowerLimited(arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IFitParameter, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IFitParameter_setPositive(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IFitParameter *arg1 = (IFitParameter *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  IFitParameter *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:IFitParameter_setPositive",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IFitParameter, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFitParameter_setPositive" "', argument " "1"" of type '" "IFitParameter *""'"); 
-  }
-  arg1 = reinterpret_cast< IFitParameter * >(argp1);
-  result = (IFitParameter *) &(arg1)->setPositive();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IFitParameter, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IFitParameter_setNonnegative(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IFitParameter *arg1 = (IFitParameter *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  IFitParameter *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:IFitParameter_setNonnegative",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IFitParameter, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFitParameter_setNonnegative" "', argument " "1"" of type '" "IFitParameter *""'"); 
-  }
-  arg1 = reinterpret_cast< IFitParameter * >(argp1);
-  result = (IFitParameter *) &(arg1)->setNonnegative();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IFitParameter, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IFitParameter_setUpperLimited(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IFitParameter *arg1 = (IFitParameter *) 0 ;
-  double arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  IFitParameter *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:IFitParameter_setUpperLimited",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IFitParameter, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFitParameter_setUpperLimited" "', argument " "1"" of type '" "IFitParameter *""'"); 
-  }
-  arg1 = reinterpret_cast< IFitParameter * >(argp1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IFitParameter_setUpperLimited" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  result = (IFitParameter *) &(arg1)->setUpperLimited(arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IFitParameter, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IFitParameter_setLimited(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IFitParameter *arg1 = (IFitParameter *) 0 ;
-  double arg2 ;
-  double arg3 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  IFitParameter *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOO:IFitParameter_setLimited",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IFitParameter, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFitParameter_setLimited" "', argument " "1"" of type '" "IFitParameter *""'"); 
-  }
-  arg1 = reinterpret_cast< IFitParameter * >(argp1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IFitParameter_setLimited" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IFitParameter_setLimited" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  result = (IFitParameter *) &(arg1)->setLimited(arg2,arg3);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IFitParameter, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IFitParameter_setFixed(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IFitParameter *arg1 = (IFitParameter *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  IFitParameter *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:IFitParameter_setFixed",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IFitParameter, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFitParameter_setFixed" "', argument " "1"" of type '" "IFitParameter *""'"); 
-  }
-  arg1 = reinterpret_cast< IFitParameter * >(argp1);
-  result = (IFitParameter *) &(arg1)->setFixed();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IFitParameter, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IFitParameter_toString(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IFitParameter *arg1 = (IFitParameter *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  std::string result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:IFitParameter_toString",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IFitParameter, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IFitParameter_toString" "', argument " "1"" of type '" "IFitParameter const *""'"); 
-  }
-  arg1 = reinterpret_cast< IFitParameter * >(argp1);
-  result = ((IFitParameter const *)arg1)->toString();
-  resultobj = SWIG_From_std_string(static_cast< std::string >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *IFitParameter_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_IFitParameter, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *_wrap_new_FitParameterSet(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameterSet *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)":new_FitParameterSet")) SWIG_fail;
-  result = (FitParameterSet *)new FitParameterSet();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitParameterSet, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_delete_FitParameterSet(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameterSet *arg1 = (FitParameterSet *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_FitParameterSet",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameterSet, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_FitParameterSet" "', argument " "1"" of type '" "FitParameterSet *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameterSet * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet_clear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameterSet *arg1 = (FitParameterSet *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitParameterSet_clear",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameterSet, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameterSet_clear" "', argument " "1"" of type '" "FitParameterSet *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameterSet * >(argp1);
-  (arg1)->clear();
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameterSet *arg1 = (FitParameterSet *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  size_t result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitParameterSet_size",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameterSet, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameterSet_size" "', argument " "1"" of type '" "FitParameterSet const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameterSet * >(argp1);
-  result = ((FitParameterSet const *)arg1)->size();
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet_begin__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameterSet *arg1 = (FitParameterSet *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  SwigValueWrapper< std::vector< IFitParameter *,std::allocator< IFitParameter * > >::iterator > result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitParameterSet_begin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameterSet, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameterSet_begin" "', argument " "1"" of type '" "FitParameterSet *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameterSet * >(argp1);
-  result = (arg1)->begin();
-  resultobj = SWIG_NewPointerObj((new FitParameterSet::iterator(static_cast< const FitParameterSet::iterator& >(result))), SWIGTYPE_p_std__vectorT_IFitParameter_p_std__allocatorT_IFitParameter_p_t_t__iterator, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet_begin__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameterSet *arg1 = (FitParameterSet *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  SwigValueWrapper< std::vector< IFitParameter *,std::allocator< IFitParameter * > >::const_iterator > result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitParameterSet_begin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameterSet, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameterSet_begin" "', argument " "1"" of type '" "FitParameterSet const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameterSet * >(argp1);
-  result = ((FitParameterSet const *)arg1)->begin();
-  resultobj = SWIG_NewPointerObj((new FitParameterSet::const_iterator(static_cast< const FitParameterSet::const_iterator& >(result))), SWIGTYPE_p_std__vectorT_IFitParameter_p_std__allocatorT_IFitParameter_p_t_t__const_iterator, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet_begin(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[2] = {
-    0
-  };
-  Py_ssize_t ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 1) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitParameterSet, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_FitParameterSet_begin__SWIG_0(self, args);
-    }
-  }
-  if (argc == 1) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitParameterSet, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_FitParameterSet_begin__SWIG_1(self, args);
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitParameterSet_begin'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    FitParameterSet::begin()\n"
-    "    FitParameterSet::begin() const\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet_end__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameterSet *arg1 = (FitParameterSet *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  SwigValueWrapper< std::vector< IFitParameter *,std::allocator< IFitParameter * > >::iterator > result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitParameterSet_end",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameterSet, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameterSet_end" "', argument " "1"" of type '" "FitParameterSet *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameterSet * >(argp1);
-  result = (arg1)->end();
-  resultobj = SWIG_NewPointerObj((new FitParameterSet::iterator(static_cast< const FitParameterSet::iterator& >(result))), SWIGTYPE_p_std__vectorT_IFitParameter_p_std__allocatorT_IFitParameter_p_t_t__iterator, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet_end__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameterSet *arg1 = (FitParameterSet *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  SwigValueWrapper< std::vector< IFitParameter *,std::allocator< IFitParameter * > >::const_iterator > result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitParameterSet_end",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameterSet, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameterSet_end" "', argument " "1"" of type '" "FitParameterSet const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameterSet * >(argp1);
-  result = ((FitParameterSet const *)arg1)->end();
-  resultobj = SWIG_NewPointerObj((new FitParameterSet::const_iterator(static_cast< const FitParameterSet::const_iterator& >(result))), SWIGTYPE_p_std__vectorT_IFitParameter_p_std__allocatorT_IFitParameter_p_t_t__const_iterator, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet_end(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[2] = {
-    0
-  };
-  Py_ssize_t ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 1) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitParameterSet, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_FitParameterSet_end__SWIG_0(self, args);
-    }
-  }
-  if (argc == 1) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitParameterSet, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_FitParameterSet_end__SWIG_1(self, args);
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitParameterSet_end'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    FitParameterSet::end()\n"
-    "    FitParameterSet::end() const\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet_addFitParameter(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameterSet *arg1 = (FitParameterSet *) 0 ;
-  IFitParameter *arg2 = (IFitParameter *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitParameterSet_addFitParameter",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameterSet, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameterSet_addFitParameter" "', argument " "1"" of type '" "FitParameterSet *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameterSet * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_IFitParameter, 0 |  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitParameterSet_addFitParameter" "', argument " "2"" of type '" "IFitParameter *""'"); 
-  }
-  arg2 = reinterpret_cast< IFitParameter * >(argp2);
-  (arg1)->addFitParameter(arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet_fitParameter__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameterSet *arg1 = (FitParameterSet *) 0 ;
-  std::string *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  IFitParameter *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitParameterSet_fitParameter",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameterSet, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameterSet_fitParameter" "', argument " "1"" of type '" "FitParameterSet const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameterSet * >(argp1);
-  {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitParameterSet_fitParameter" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitParameterSet_fitParameter" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    arg2 = ptr;
-  }
-  result = (IFitParameter *)((FitParameterSet const *)arg1)->fitParameter((std::string const &)*arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IFitParameter, 0 |  0 );
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet_fitParameter__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameterSet *arg1 = (FitParameterSet *) 0 ;
-  std::string *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  IFitParameter *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitParameterSet_fitParameter",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameterSet, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameterSet_fitParameter" "', argument " "1"" of type '" "FitParameterSet *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameterSet * >(argp1);
-  {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitParameterSet_fitParameter" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitParameterSet_fitParameter" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    arg2 = ptr;
-  }
-  result = (IFitParameter *)(arg1)->fitParameter((std::string const &)*arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IFitParameter, 0 |  0 );
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet_fitParameter(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[3] = {
-    0
-  };
-  Py_ssize_t ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 2) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitParameterSet, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_AsPtr_std_string(argv[1], (std::string**)(0));
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        return _wrap_FitParameterSet_fitParameter__SWIG_1(self, args);
-      }
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitParameterSet, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_AsPtr_std_string(argv[1], (std::string**)(0));
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        return _wrap_FitParameterSet_fitParameter__SWIG_0(self, args);
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitParameterSet_fitParameter'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    FitParameterSet::fitParameter(std::string const &) const\n"
-    "    FitParameterSet::fitParameter(std::string const &)\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet_values(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameterSet *arg1 = (FitParameterSet *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  std::vector< double,std::allocator< double > > result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitParameterSet_values",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameterSet, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameterSet_values" "', argument " "1"" of type '" "FitParameterSet const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameterSet * >(argp1);
-  result = ((FitParameterSet const *)arg1)->values();
-  resultobj = swig::from(static_cast< std::vector< double,std::allocator< double > > >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet_setValues(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameterSet *arg1 = (FitParameterSet *) 0 ;
-  std::vector< double,std::allocator< double > > *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitParameterSet_setValues",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameterSet, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameterSet_setValues" "', argument " "1"" of type '" "FitParameterSet *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameterSet * >(argp1);
-  {
-    std::vector< double,std::allocator< double > > *ptr = (std::vector< double,std::allocator< double > > *)0;
-    res2 = swig::asptr(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitParameterSet_setValues" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitParameterSet_setValues" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
-    }
-    arg2 = ptr;
-  }
-  (arg1)->setValues((std::vector< double,std::allocator< double > > const &)*arg2);
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet_valuesDifferFrom__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameterSet *arg1 = (FitParameterSet *) 0 ;
-  std::vector< double,std::allocator< double > > *arg2 = 0 ;
-  double arg3 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
-  double val3 ;
-  int ecode3 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  bool result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOO:FitParameterSet_valuesDifferFrom",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameterSet, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameterSet_valuesDifferFrom" "', argument " "1"" of type '" "FitParameterSet const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameterSet * >(argp1);
-  {
-    std::vector< double,std::allocator< double > > *ptr = (std::vector< double,std::allocator< double > > *)0;
-    res2 = swig::asptr(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitParameterSet_valuesDifferFrom" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitParameterSet_valuesDifferFrom" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
-    }
-    arg2 = ptr;
-  }
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "FitParameterSet_valuesDifferFrom" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  result = (bool)((FitParameterSet const *)arg1)->valuesDifferFrom((std::vector< double,std::allocator< double > > const &)*arg2,arg3);
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet_valuesDifferFrom__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameterSet *arg1 = (FitParameterSet *) 0 ;
-  std::vector< double,std::allocator< double > > *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  bool result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitParameterSet_valuesDifferFrom",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameterSet, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameterSet_valuesDifferFrom" "', argument " "1"" of type '" "FitParameterSet const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameterSet * >(argp1);
-  {
-    std::vector< double,std::allocator< double > > *ptr = (std::vector< double,std::allocator< double > > *)0;
-    res2 = swig::asptr(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitParameterSet_valuesDifferFrom" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitParameterSet_valuesDifferFrom" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
-    }
-    arg2 = ptr;
-  }
-  result = (bool)((FitParameterSet const *)arg1)->valuesDifferFrom((std::vector< double,std::allocator< double > > const &)*arg2);
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet_valuesDifferFrom(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[4] = {
-    0
-  };
-  Py_ssize_t ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 2) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitParameterSet, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = swig::asptr(argv[1], (std::vector< double,std::allocator< double > >**)(0));
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        return _wrap_FitParameterSet_valuesDifferFrom__SWIG_1(self, args);
-      }
-    }
-  }
-  if (argc == 3) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitParameterSet, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = swig::asptr(argv[1], (std::vector< double,std::allocator< double > >**)(0));
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        {
-          int res = SWIG_AsVal_double(argv[2], NULL);
-          _v = SWIG_CheckState(res);
-        }
-        if (_v) {
-          return _wrap_FitParameterSet_valuesDifferFrom__SWIG_0(self, args);
-        }
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitParameterSet_valuesDifferFrom'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    FitParameterSet::valuesDifferFrom(std::vector< double,std::allocator< double > > const &,double) const\n"
-    "    FitParameterSet::valuesDifferFrom(std::vector< double,std::allocator< double > > const &) const\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet_errors(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameterSet *arg1 = (FitParameterSet *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  std::vector< double,std::allocator< double > > result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitParameterSet_errors",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameterSet, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameterSet_errors" "', argument " "1"" of type '" "FitParameterSet const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameterSet * >(argp1);
-  result = ((FitParameterSet const *)arg1)->errors();
-  resultobj = swig::from(static_cast< std::vector< double,std::allocator< double > > >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet_setErrors(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameterSet *arg1 = (FitParameterSet *) 0 ;
-  std::vector< double,std::allocator< double > > *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitParameterSet_setErrors",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameterSet, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameterSet_setErrors" "', argument " "1"" of type '" "FitParameterSet *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameterSet * >(argp1);
-  {
-    std::vector< double,std::allocator< double > > *ptr = (std::vector< double,std::allocator< double > > *)0;
-    res2 = swig::asptr(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitParameterSet_setErrors" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitParameterSet_setErrors" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
-    }
-    arg2 = ptr;
-  }
-  (arg1)->setErrors((std::vector< double,std::allocator< double > > const &)*arg2);
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet_freeFitParameterCount(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameterSet *arg1 = (FitParameterSet *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  size_t result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitParameterSet_freeFitParameterCount",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameterSet, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameterSet_freeFitParameterCount" "', argument " "1"" of type '" "FitParameterSet const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameterSet * >(argp1);
-  result = ((FitParameterSet const *)arg1)->freeFitParameterCount();
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet_fixAll(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameterSet *arg1 = (FitParameterSet *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitParameterSet_fixAll",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameterSet, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameterSet_fixAll" "', argument " "1"" of type '" "FitParameterSet *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameterSet * >(argp1);
-  (arg1)->fixAll();
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet_releaseAll(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameterSet *arg1 = (FitParameterSet *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitParameterSet_releaseAll",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameterSet, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameterSet_releaseAll" "', argument " "1"" of type '" "FitParameterSet *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameterSet * >(argp1);
-  (arg1)->releaseAll();
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet_setFixed(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameterSet *arg1 = (FitParameterSet *) 0 ;
-  std::vector< std::string,std::allocator< std::string > > *arg2 = 0 ;
-  bool arg3 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
-  bool val3 ;
-  int ecode3 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOO:FitParameterSet_setFixed",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameterSet, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameterSet_setFixed" "', argument " "1"" of type '" "FitParameterSet *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameterSet * >(argp1);
-  {
-    std::vector< std::string,std::allocator< std::string > > *ptr = (std::vector< std::string,std::allocator< std::string > > *)0;
-    res2 = swig::asptr(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitParameterSet_setFixed" "', argument " "2"" of type '" "std::vector< std::string,std::allocator< std::string > > const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitParameterSet_setFixed" "', argument " "2"" of type '" "std::vector< std::string,std::allocator< std::string > > const &""'"); 
-    }
-    arg2 = ptr;
-  }
-  ecode3 = SWIG_AsVal_bool(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "FitParameterSet_setFixed" "', argument " "3"" of type '" "bool""'");
-  } 
-  arg3 = static_cast< bool >(val3);
-  (arg1)->setFixed((std::vector< std::string,std::allocator< std::string > > const &)*arg2,arg3);
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet_correlationMatrix(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameterSet *arg1 = (FitParameterSet *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  FitParameterSet::corr_matrix_t result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitParameterSet_correlationMatrix",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameterSet, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameterSet_correlationMatrix" "', argument " "1"" of type '" "FitParameterSet const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameterSet * >(argp1);
-  result = ((FitParameterSet const *)arg1)->correlationMatrix();
-  resultobj = swig::from(static_cast< std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet_setCorrelationMatrix(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameterSet *arg1 = (FitParameterSet *) 0 ;
-  FitParameterSet::corr_matrix_t *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitParameterSet_setCorrelationMatrix",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameterSet, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameterSet_setCorrelationMatrix" "', argument " "1"" of type '" "FitParameterSet *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameterSet * >(argp1);
-  {
-    std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *ptr = (std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *)0;
-    res2 = swig::asptr(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitParameterSet_setCorrelationMatrix" "', argument " "2"" of type '" "FitParameterSet::corr_matrix_t const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitParameterSet_setCorrelationMatrix" "', argument " "2"" of type '" "FitParameterSet::corr_matrix_t const &""'"); 
-    }
-    arg2 = ptr;
-  }
-  (arg1)->setCorrelationMatrix((FitParameterSet::corr_matrix_t const &)*arg2);
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet_fitParametersNewKernel(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameterSet *arg1 = (FitParameterSet *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  Fit::Parameters result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitParameterSet_fitParametersNewKernel",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameterSet, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameterSet_fitParametersNewKernel" "', argument " "1"" of type '" "FitParameterSet const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameterSet * >(argp1);
-  result = ((FitParameterSet const *)arg1)->fitParametersNewKernel();
-  resultobj = SWIG_NewPointerObj((new Fit::Parameters(static_cast< const Fit::Parameters& >(result))), SWIGTYPE_p_Fit__Parameters, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet___getitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameterSet *arg1 = (FitParameterSet *) 0 ;
-  std::string arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  IFitParameter *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitParameterSet___getitem__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameterSet, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameterSet___getitem__" "', argument " "1"" of type '" "FitParameterSet const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameterSet * >(argp1);
-  {
-    std::string *ptr = (std::string *)0;
-    int res = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res) || !ptr) {
-      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "FitParameterSet___getitem__" "', argument " "2"" of type '" "std::string""'"); 
-    }
-    arg2 = *ptr;
-    if (SWIG_IsNewObj(res)) delete ptr;
-  }
-  result = (IFitParameter *)FitParameterSet___getitem____SWIG_0((FitParameterSet const *)arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IFitParameter, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet___getitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameterSet *arg1 = (FitParameterSet *) 0 ;
-  size_t arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  size_t val2 ;
-  int ecode2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  IFitParameter *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitParameterSet___getitem__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameterSet, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameterSet___getitem__" "', argument " "1"" of type '" "FitParameterSet const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameterSet * >(argp1);
-  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitParameterSet___getitem__" "', argument " "2"" of type '" "size_t""'");
-  } 
-  arg2 = static_cast< size_t >(val2);
-  result = (IFitParameter *)FitParameterSet___getitem____SWIG_1((FitParameterSet const *)arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IFitParameter, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameterSet___getitem__(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[3] = {
-    0
-  };
-  Py_ssize_t ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 2) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitParameterSet, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_size_t(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_FitParameterSet___getitem____SWIG_1(self, args);
-      }
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitParameterSet, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_AsPtr_std_string(argv[1], (std::string**)(0));
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        return _wrap_FitParameterSet___getitem____SWIG_0(self, args);
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitParameterSet___getitem__'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    FitParameterSet::__getitem__(std::string) const\n"
-    "    FitParameterSet::__getitem__(size_t) const\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *FitParameterSet_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_FitParameterSet, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *_wrap_new_FitParameter__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameter *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)":new_FitParameter")) SWIG_fail;
-  result = (FitParameter *)new FitParameter();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitParameter, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_FitParameter__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::string *arg1 = 0 ;
-  double arg2 ;
-  AttLimits *arg3 = 0 ;
-  double arg4 ;
-  int res1 = SWIG_OLDOBJ ;
-  double val2 ;
-  int ecode2 = 0 ;
-  void *argp3 = 0 ;
-  int res3 = 0 ;
-  double val4 ;
-  int ecode4 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  PyObject * obj3 = 0 ;
-  FitParameter *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOOO:new_FitParameter",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  {
-    std::string *ptr = (std::string *)0;
-    res1 = SWIG_AsPtr_std_string(obj0, &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_FitParameter" "', argument " "1"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_FitParameter" "', argument " "1"" of type '" "std::string const &""'"); 
-    }
-    arg1 = ptr;
-  }
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_FitParameter" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_AttLimits,  0  | 0);
-  if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "new_FitParameter" "', argument " "3"" of type '" "AttLimits const &""'"); 
-  }
-  if (!argp3) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_FitParameter" "', argument " "3"" of type '" "AttLimits const &""'"); 
-  }
-  arg3 = reinterpret_cast< AttLimits * >(argp3);
-  ecode4 = SWIG_AsVal_double(obj3, &val4);
-  if (!SWIG_IsOK(ecode4)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "new_FitParameter" "', argument " "4"" of type '" "double""'");
-  } 
-  arg4 = static_cast< double >(val4);
-  result = (FitParameter *)new FitParameter((std::string const &)*arg1,arg2,(AttLimits const &)*arg3,arg4);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitParameter, SWIG_POINTER_NEW |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_FitParameter__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::string *arg1 = 0 ;
-  double arg2 ;
-  AttLimits *arg3 = 0 ;
-  int res1 = SWIG_OLDOBJ ;
-  double val2 ;
-  int ecode2 = 0 ;
-  void *argp3 = 0 ;
-  int res3 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  FitParameter *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOO:new_FitParameter",&obj0,&obj1,&obj2)) SWIG_fail;
-  {
-    std::string *ptr = (std::string *)0;
-    res1 = SWIG_AsPtr_std_string(obj0, &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_FitParameter" "', argument " "1"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_FitParameter" "', argument " "1"" of type '" "std::string const &""'"); 
-    }
-    arg1 = ptr;
-  }
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_FitParameter" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_AttLimits,  0  | 0);
-  if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "new_FitParameter" "', argument " "3"" of type '" "AttLimits const &""'"); 
-  }
-  if (!argp3) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_FitParameter" "', argument " "3"" of type '" "AttLimits const &""'"); 
-  }
-  arg3 = reinterpret_cast< AttLimits * >(argp3);
-  result = (FitParameter *)new FitParameter((std::string const &)*arg1,arg2,(AttLimits const &)*arg3);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitParameter, SWIG_POINTER_NEW |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_FitParameter__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::string *arg1 = 0 ;
-  double arg2 ;
-  int res1 = SWIG_OLDOBJ ;
-  double val2 ;
-  int ecode2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  FitParameter *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:new_FitParameter",&obj0,&obj1)) SWIG_fail;
-  {
-    std::string *ptr = (std::string *)0;
-    res1 = SWIG_AsPtr_std_string(obj0, &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_FitParameter" "', argument " "1"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_FitParameter" "', argument " "1"" of type '" "std::string const &""'"); 
-    }
-    arg1 = ptr;
-  }
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_FitParameter" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  result = (FitParameter *)new FitParameter((std::string const &)*arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitParameter, SWIG_POINTER_NEW |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_FitParameter__SWIG_4(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  double arg1 ;
-  AttLimits *arg2 = 0 ;
-  double arg3 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  FitParameter *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOO:new_FitParameter",&obj0,&obj1,&obj2)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(obj0, &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_FitParameter" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_AttLimits,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "new_FitParameter" "', argument " "2"" of type '" "AttLimits const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_FitParameter" "', argument " "2"" of type '" "AttLimits const &""'"); 
-  }
-  arg2 = reinterpret_cast< AttLimits * >(argp2);
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_FitParameter" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  result = (FitParameter *)new FitParameter(arg1,(AttLimits const &)*arg2,arg3);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitParameter, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_FitParameter__SWIG_5(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  double arg1 ;
-  AttLimits *arg2 = 0 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  FitParameter *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:new_FitParameter",&obj0,&obj1)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(obj0, &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_FitParameter" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_AttLimits,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "new_FitParameter" "', argument " "2"" of type '" "AttLimits const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_FitParameter" "', argument " "2"" of type '" "AttLimits const &""'"); 
-  }
-  arg2 = reinterpret_cast< AttLimits * >(argp2);
-  result = (FitParameter *)new FitParameter(arg1,(AttLimits const &)*arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitParameter, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_FitParameter__SWIG_6(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  double arg1 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  PyObject * obj0 = 0 ;
-  FitParameter *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:new_FitParameter",&obj0)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(obj0, &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_FitParameter" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  result = (FitParameter *)new FitParameter(arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitParameter, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_FitParameter(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[5] = {
-    0
-  };
-  Py_ssize_t ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 0) {
-    return _wrap_new_FitParameter__SWIG_0(self, args);
-  }
-  if (argc == 1) {
-    int _v;
-    {
-      int res = SWIG_AsVal_double(argv[0], NULL);
-      _v = SWIG_CheckState(res);
-    }
-    if (_v) {
-      return _wrap_new_FitParameter__SWIG_6(self, args);
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    {
-      int res = SWIG_AsVal_double(argv[0], NULL);
-      _v = SWIG_CheckState(res);
-    }
-    if (_v) {
-      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_AttLimits, 0);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        return _wrap_new_FitParameter__SWIG_5(self, args);
-      }
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    int res = SWIG_AsPtr_std_string(argv[0], (std::string**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_double(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_new_FitParameter__SWIG_3(self, args);
-      }
-    }
-  }
-  if (argc == 3) {
-    int _v;
-    {
-      int res = SWIG_AsVal_double(argv[0], NULL);
-      _v = SWIG_CheckState(res);
-    }
-    if (_v) {
-      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_AttLimits, 0);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        {
-          int res = SWIG_AsVal_double(argv[2], NULL);
-          _v = SWIG_CheckState(res);
-        }
-        if (_v) {
-          return _wrap_new_FitParameter__SWIG_4(self, args);
-        }
-      }
-    }
-  }
-  if (argc == 3) {
-    int _v;
-    int res = SWIG_AsPtr_std_string(argv[0], (std::string**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_double(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_AttLimits, 0);
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          return _wrap_new_FitParameter__SWIG_2(self, args);
-        }
-      }
-    }
-  }
-  if (argc == 4) {
-    int _v;
-    int res = SWIG_AsPtr_std_string(argv[0], (std::string**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_double(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_AttLimits, 0);
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          {
-            int res = SWIG_AsVal_double(argv[3], NULL);
-            _v = SWIG_CheckState(res);
-          }
-          if (_v) {
-            return _wrap_new_FitParameter__SWIG_1(self, args);
-          }
-        }
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_FitParameter'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    FitParameter::FitParameter()\n"
-    "    FitParameter::FitParameter(std::string const &,double,AttLimits const &,double)\n"
-    "    FitParameter::FitParameter(std::string const &,double,AttLimits const &)\n"
-    "    FitParameter::FitParameter(std::string const &,double)\n"
-    "    FitParameter::FitParameter(double,AttLimits const &,double)\n"
-    "    FitParameter::FitParameter(double,AttLimits const &)\n"
-    "    FitParameter::FitParameter(double)\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_delete_FitParameter(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameter *arg1 = (FitParameter *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_FitParameter",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameter, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_FitParameter" "', argument " "1"" of type '" "FitParameter *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameter * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameter_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameter *arg1 = (FitParameter *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  FitParameter *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitParameter_clone",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameter, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameter_clone" "', argument " "1"" of type '" "FitParameter const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameter * >(argp1);
-  result = (FitParameter *)((FitParameter const *)arg1)->clone();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitParameter, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameter_setValue(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameter *arg1 = (FitParameter *) 0 ;
-  double arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitParameter_setValue",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameter, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameter_setValue" "', argument " "1"" of type '" "FitParameter *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameter * >(argp1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitParameter_setValue" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  (arg1)->setValue(arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameter_addPattern(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameter *arg1 = (FitParameter *) 0 ;
-  std::string *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  FitParameter *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitParameter_addPattern",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameter, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameter_addPattern" "', argument " "1"" of type '" "FitParameter *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameter * >(argp1);
-  {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitParameter_addPattern" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitParameter_addPattern" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    arg2 = ptr;
-  }
-  result = (FitParameter *) &(arg1)->addPattern((std::string const &)*arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitParameter, 0 |  0 );
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameter_addParameter(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameter *arg1 = (FitParameter *) 0 ;
-  RealParameter *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitParameter_addParameter",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameter, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameter_addParameter" "', argument " "1"" of type '" "FitParameter *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameter * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_RealParameter,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitParameter_addParameter" "', argument " "2"" of type '" "RealParameter const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitParameter_addParameter" "', argument " "2"" of type '" "RealParameter const &""'"); 
-  }
-  arg2 = reinterpret_cast< RealParameter * >(argp2);
-  (arg1)->addParameter((RealParameter const &)*arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameter_addMatchedParameters(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameter *arg1 = (FitParameter *) 0 ;
-  ParameterPool *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitParameter_addMatchedParameters",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameter, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameter_addMatchedParameters" "', argument " "1"" of type '" "FitParameter *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameter * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_ParameterPool,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitParameter_addMatchedParameters" "', argument " "2"" of type '" "ParameterPool const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitParameter_addMatchedParameters" "', argument " "2"" of type '" "ParameterPool const &""'"); 
-  }
-  arg2 = reinterpret_cast< ParameterPool * >(argp2);
-  (arg1)->addMatchedParameters((ParameterPool const &)*arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameter_patterns(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameter *arg1 = (FitParameter *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  std::vector< std::string,std::allocator< std::string > > result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitParameter_patterns",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameter, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameter_patterns" "', argument " "1"" of type '" "FitParameter const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameter * >(argp1);
-  result = ((FitParameter const *)arg1)->patterns();
-  resultobj = swig::from(static_cast< std::vector< std::string,std::allocator< std::string > > >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameter_matchedParameterNames(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameter *arg1 = (FitParameter *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  std::vector< std::string,std::allocator< std::string > > result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitParameter_matchedParameterNames",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameter, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameter_matchedParameterNames" "', argument " "1"" of type '" "FitParameter const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameter * >(argp1);
-  result = ((FitParameter const *)arg1)->matchedParameterNames();
-  resultobj = swig::from(static_cast< std::vector< std::string,std::allocator< std::string > > >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameter_patternIntersection(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameter *arg1 = (FitParameter *) 0 ;
-  FitParameter *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  std::vector< std::string,std::allocator< std::string > > result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitParameter_patternIntersection",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameter, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameter_patternIntersection" "', argument " "1"" of type '" "FitParameter const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameter * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_FitParameter,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitParameter_patternIntersection" "', argument " "2"" of type '" "FitParameter const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitParameter_patternIntersection" "', argument " "2"" of type '" "FitParameter const &""'"); 
-  }
-  arg2 = reinterpret_cast< FitParameter * >(argp2);
-  result = ((FitParameter const *)arg1)->patternIntersection((FitParameter const &)*arg2);
-  resultobj = swig::from(static_cast< std::vector< std::string,std::allocator< std::string > > >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitParameter_isConflicting(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitParameter *arg1 = (FitParameter *) 0 ;
-  FitParameter *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  bool result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitParameter_isConflicting",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitParameter, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitParameter_isConflicting" "', argument " "1"" of type '" "FitParameter const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitParameter * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_FitParameter,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitParameter_isConflicting" "', argument " "2"" of type '" "FitParameter const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitParameter_isConflicting" "', argument " "2"" of type '" "FitParameter const &""'"); 
-  }
-  arg2 = reinterpret_cast< FitParameter * >(argp2);
-  result = (bool)((FitParameter const *)arg1)->isConflicting((FitParameter const &)*arg2);
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *FitParameter_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_FitParameter, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *_wrap_new_FitSuite(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)":new_FitSuite")) SWIG_fail;
-  result = (FitSuite *)new FitSuite();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitSuite, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_delete_FitSuite(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_FitSuite",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_FitSuite" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_addSimulationAndRealData__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  Simulation *arg2 = 0 ;
-  OutputData< double > *arg3 = 0 ;
-  double arg4 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  void *argp3 = 0 ;
-  int res3 = 0 ;
-  double val4 ;
-  int ecode4 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  PyObject * obj3 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOOO:FitSuite_addSimulationAndRealData",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_Simulation,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "2"" of type '" "Simulation const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_addSimulationAndRealData" "', argument " "2"" of type '" "Simulation const &""'"); 
-  }
-  arg2 = reinterpret_cast< Simulation * >(argp2);
-  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_OutputDataT_double_t,  0  | 0);
-  if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "3"" of type '" "OutputData< double > const &""'"); 
-  }
-  if (!argp3) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_addSimulationAndRealData" "', argument " "3"" of type '" "OutputData< double > const &""'"); 
-  }
-  arg3 = reinterpret_cast< OutputData< double > * >(argp3);
-  ecode4 = SWIG_AsVal_double(obj3, &val4);
-  if (!SWIG_IsOK(ecode4)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "4"" of type '" "double""'");
-  } 
-  arg4 = static_cast< double >(val4);
-  (arg1)->addSimulationAndRealData((Simulation const &)*arg2,(OutputData< double > const &)*arg3,arg4);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_addSimulationAndRealData__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  Simulation *arg2 = 0 ;
-  OutputData< double > *arg3 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  void *argp3 = 0 ;
-  int res3 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOO:FitSuite_addSimulationAndRealData",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_Simulation,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "2"" of type '" "Simulation const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_addSimulationAndRealData" "', argument " "2"" of type '" "Simulation const &""'"); 
-  }
-  arg2 = reinterpret_cast< Simulation * >(argp2);
-  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_OutputDataT_double_t,  0  | 0);
-  if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "3"" of type '" "OutputData< double > const &""'"); 
-  }
-  if (!argp3) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_addSimulationAndRealData" "', argument " "3"" of type '" "OutputData< double > const &""'"); 
-  }
-  arg3 = reinterpret_cast< OutputData< double > * >(argp3);
-  (arg1)->addSimulationAndRealData((Simulation const &)*arg2,(OutputData< double > const &)*arg3);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_addSimulationAndRealData__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  Simulation *arg2 = 0 ;
-  IHistogram *arg3 = 0 ;
-  double arg4 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  void *argp3 = 0 ;
-  int res3 = 0 ;
-  double val4 ;
-  int ecode4 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  PyObject * obj3 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOOO:FitSuite_addSimulationAndRealData",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_Simulation,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "2"" of type '" "Simulation const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_addSimulationAndRealData" "', argument " "2"" of type '" "Simulation const &""'"); 
-  }
-  arg2 = reinterpret_cast< Simulation * >(argp2);
-  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_IHistogram,  0  | 0);
-  if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "3"" of type '" "IHistogram const &""'"); 
-  }
-  if (!argp3) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_addSimulationAndRealData" "', argument " "3"" of type '" "IHistogram const &""'"); 
-  }
-  arg3 = reinterpret_cast< IHistogram * >(argp3);
-  ecode4 = SWIG_AsVal_double(obj3, &val4);
-  if (!SWIG_IsOK(ecode4)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "4"" of type '" "double""'");
-  } 
-  arg4 = static_cast< double >(val4);
-  (arg1)->addSimulationAndRealData((Simulation const &)*arg2,(IHistogram const &)*arg3,arg4);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_addSimulationAndRealData__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  Simulation *arg2 = 0 ;
-  IHistogram *arg3 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  void *argp3 = 0 ;
-  int res3 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOO:FitSuite_addSimulationAndRealData",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_Simulation,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "2"" of type '" "Simulation const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_addSimulationAndRealData" "', argument " "2"" of type '" "Simulation const &""'"); 
-  }
-  arg2 = reinterpret_cast< Simulation * >(argp2);
-  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_IHistogram,  0  | 0);
-  if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "3"" of type '" "IHistogram const &""'"); 
-  }
-  if (!argp3) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_addSimulationAndRealData" "', argument " "3"" of type '" "IHistogram const &""'"); 
-  }
-  arg3 = reinterpret_cast< IHistogram * >(argp3);
-  (arg1)->addSimulationAndRealData((Simulation const &)*arg2,(IHistogram const &)*arg3);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_addSimulationAndRealData__SWIG_4(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  Simulation *arg2 = 0 ;
-  std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *arg3 = 0 ;
-  double arg4 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  int res3 = SWIG_OLDOBJ ;
-  double val4 ;
-  int ecode4 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  PyObject * obj3 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOOO:FitSuite_addSimulationAndRealData",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_Simulation,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "2"" of type '" "Simulation const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_addSimulationAndRealData" "', argument " "2"" of type '" "Simulation const &""'"); 
-  }
-  arg2 = reinterpret_cast< Simulation * >(argp2);
-  {
-    std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *ptr = (std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *)0;
-    res3 = swig::asptr(obj2, &ptr);
-    if (!SWIG_IsOK(res3)) {
-      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "3"" of type '" "std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_addSimulationAndRealData" "', argument " "3"" of type '" "std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &""'"); 
-    }
-    arg3 = ptr;
-  }
-  ecode4 = SWIG_AsVal_double(obj3, &val4);
-  if (!SWIG_IsOK(ecode4)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "4"" of type '" "double""'");
-  } 
-  arg4 = static_cast< double >(val4);
-  (arg1)->addSimulationAndRealData((Simulation const &)*arg2,(std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &)*arg3,arg4);
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_addSimulationAndRealData__SWIG_5(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  Simulation *arg2 = 0 ;
-  std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *arg3 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  int res3 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOO:FitSuite_addSimulationAndRealData",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_Simulation,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "2"" of type '" "Simulation const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_addSimulationAndRealData" "', argument " "2"" of type '" "Simulation const &""'"); 
-  }
-  arg2 = reinterpret_cast< Simulation * >(argp2);
-  {
-    std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *ptr = (std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *)0;
-    res3 = swig::asptr(obj2, &ptr);
-    if (!SWIG_IsOK(res3)) {
-      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "3"" of type '" "std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_addSimulationAndRealData" "', argument " "3"" of type '" "std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &""'"); 
-    }
-    arg3 = ptr;
-  }
-  (arg1)->addSimulationAndRealData((Simulation const &)*arg2,(std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &)*arg3);
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_addSimulationAndRealData__SWIG_6(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  Simulation *arg2 = 0 ;
-  std::vector< double,std::allocator< double > > *arg3 = 0 ;
-  double arg4 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  int res3 = SWIG_OLDOBJ ;
-  double val4 ;
-  int ecode4 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  PyObject * obj3 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOOO:FitSuite_addSimulationAndRealData",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_Simulation,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "2"" of type '" "Simulation const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_addSimulationAndRealData" "', argument " "2"" of type '" "Simulation const &""'"); 
-  }
-  arg2 = reinterpret_cast< Simulation * >(argp2);
-  {
-    std::vector< double,std::allocator< double > > *ptr = (std::vector< double,std::allocator< double > > *)0;
-    res3 = swig::asptr(obj2, &ptr);
-    if (!SWIG_IsOK(res3)) {
-      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "3"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_addSimulationAndRealData" "', argument " "3"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
-    }
-    arg3 = ptr;
-  }
-  ecode4 = SWIG_AsVal_double(obj3, &val4);
-  if (!SWIG_IsOK(ecode4)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "4"" of type '" "double""'");
-  } 
-  arg4 = static_cast< double >(val4);
-  (arg1)->addSimulationAndRealData((Simulation const &)*arg2,(std::vector< double,std::allocator< double > > const &)*arg3,arg4);
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_addSimulationAndRealData__SWIG_7(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  Simulation *arg2 = 0 ;
-  std::vector< double,std::allocator< double > > *arg3 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  int res3 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOO:FitSuite_addSimulationAndRealData",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_Simulation,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "2"" of type '" "Simulation const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_addSimulationAndRealData" "', argument " "2"" of type '" "Simulation const &""'"); 
-  }
-  arg2 = reinterpret_cast< Simulation * >(argp2);
-  {
-    std::vector< double,std::allocator< double > > *ptr = (std::vector< double,std::allocator< double > > *)0;
-    res3 = swig::asptr(obj2, &ptr);
-    if (!SWIG_IsOK(res3)) {
-      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "FitSuite_addSimulationAndRealData" "', argument " "3"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_addSimulationAndRealData" "', argument " "3"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
-    }
-    arg3 = ptr;
-  }
-  (arg1)->addSimulationAndRealData((Simulation const &)*arg2,(std::vector< double,std::allocator< double > > const &)*arg3);
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_addSimulationAndRealData(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[5] = {
-    0
-  };
-  Py_ssize_t ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 3) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuite, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_Simulation, 0);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_OutputDataT_double_t, 0);
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          return _wrap_FitSuite_addSimulationAndRealData__SWIG_1(self, args);
-        }
-      }
-    }
-  }
-  if (argc == 3) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuite, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_Simulation, 0);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_IHistogram, 0);
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          return _wrap_FitSuite_addSimulationAndRealData__SWIG_3(self, args);
-        }
-      }
-    }
-  }
-  if (argc == 3) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuite, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_Simulation, 0);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        int res = swig::asptr(argv[2], (std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >**)(0));
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          return _wrap_FitSuite_addSimulationAndRealData__SWIG_5(self, args);
-        }
-      }
-    }
-  }
-  if (argc == 3) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuite, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_Simulation, 0);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        int res = swig::asptr(argv[2], (std::vector< double,std::allocator< double > >**)(0));
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          return _wrap_FitSuite_addSimulationAndRealData__SWIG_7(self, args);
-        }
-      }
-    }
-  }
-  if (argc == 4) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuite, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_Simulation, 0);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_IHistogram, 0);
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          {
-            int res = SWIG_AsVal_double(argv[3], NULL);
-            _v = SWIG_CheckState(res);
-          }
-          if (_v) {
-            return _wrap_FitSuite_addSimulationAndRealData__SWIG_2(self, args);
-          }
-        }
-      }
-    }
-  }
-  if (argc == 4) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuite, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_Simulation, 0);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_OutputDataT_double_t, 0);
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          {
-            int res = SWIG_AsVal_double(argv[3], NULL);
-            _v = SWIG_CheckState(res);
-          }
-          if (_v) {
-            return _wrap_FitSuite_addSimulationAndRealData__SWIG_0(self, args);
-          }
-        }
-      }
-    }
-  }
-  if (argc == 4) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuite, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_Simulation, 0);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        int res = swig::asptr(argv[2], (std::vector< double,std::allocator< double > >**)(0));
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          {
-            int res = SWIG_AsVal_double(argv[3], NULL);
-            _v = SWIG_CheckState(res);
-          }
-          if (_v) {
-            return _wrap_FitSuite_addSimulationAndRealData__SWIG_6(self, args);
-          }
-        }
-      }
-    }
-  }
-  if (argc == 4) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuite, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_Simulation, 0);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        int res = swig::asptr(argv[2], (std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >**)(0));
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          {
-            int res = SWIG_AsVal_double(argv[3], NULL);
-            _v = SWIG_CheckState(res);
-          }
-          if (_v) {
-            return _wrap_FitSuite_addSimulationAndRealData__SWIG_4(self, args);
-          }
-        }
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitSuite_addSimulationAndRealData'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    FitSuite::addSimulationAndRealData(Simulation const &,OutputData< double > const &,double)\n"
-    "    FitSuite::addSimulationAndRealData(Simulation const &,OutputData< double > const &)\n"
-    "    FitSuite::addSimulationAndRealData(Simulation const &,IHistogram const &,double)\n"
-    "    FitSuite::addSimulationAndRealData(Simulation const &,IHistogram const &)\n"
-    "    FitSuite::addSimulationAndRealData(Simulation const &,std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &,double)\n"
-    "    FitSuite::addSimulationAndRealData(Simulation const &,std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &)\n"
-    "    FitSuite::addSimulationAndRealData(Simulation const &,std::vector< double,std::allocator< double > > const &,double)\n"
-    "    FitSuite::addSimulationAndRealData(Simulation const &,std::vector< double,std::allocator< double > > const &)\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_addFitParameter__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  std::string *arg2 = 0 ;
-  double arg3 ;
-  AttLimits *arg4 = 0 ;
-  double arg5 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
-  double val3 ;
-  int ecode3 = 0 ;
-  void *argp4 = 0 ;
-  int res4 = 0 ;
-  double val5 ;
-  int ecode5 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  PyObject * obj3 = 0 ;
-  PyObject * obj4 = 0 ;
-  FitParameter *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOOOO:FitSuite_addFitParameter",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_addFitParameter" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitSuite_addFitParameter" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_addFitParameter" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    arg2 = ptr;
-  }
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "FitSuite_addFitParameter" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  res4 = SWIG_ConvertPtr(obj3, &argp4, SWIGTYPE_p_AttLimits,  0  | 0);
-  if (!SWIG_IsOK(res4)) {
-    SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "FitSuite_addFitParameter" "', argument " "4"" of type '" "AttLimits const &""'"); 
-  }
-  if (!argp4) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_addFitParameter" "', argument " "4"" of type '" "AttLimits const &""'"); 
-  }
-  arg4 = reinterpret_cast< AttLimits * >(argp4);
-  ecode5 = SWIG_AsVal_double(obj4, &val5);
-  if (!SWIG_IsOK(ecode5)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "FitSuite_addFitParameter" "', argument " "5"" of type '" "double""'");
-  } 
-  arg5 = static_cast< double >(val5);
-  result = (FitParameter *)(arg1)->addFitParameter((std::string const &)*arg2,arg3,(AttLimits const &)*arg4,arg5);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitParameter, 0 |  0 );
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_addFitParameter__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  std::string *arg2 = 0 ;
-  double arg3 ;
-  AttLimits *arg4 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
-  double val3 ;
-  int ecode3 = 0 ;
-  void *argp4 = 0 ;
-  int res4 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  PyObject * obj3 = 0 ;
-  FitParameter *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOOO:FitSuite_addFitParameter",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_addFitParameter" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitSuite_addFitParameter" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_addFitParameter" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    arg2 = ptr;
-  }
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "FitSuite_addFitParameter" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  res4 = SWIG_ConvertPtr(obj3, &argp4, SWIGTYPE_p_AttLimits,  0  | 0);
-  if (!SWIG_IsOK(res4)) {
-    SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "FitSuite_addFitParameter" "', argument " "4"" of type '" "AttLimits const &""'"); 
-  }
-  if (!argp4) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_addFitParameter" "', argument " "4"" of type '" "AttLimits const &""'"); 
-  }
-  arg4 = reinterpret_cast< AttLimits * >(argp4);
-  result = (FitParameter *)(arg1)->addFitParameter((std::string const &)*arg2,arg3,(AttLimits const &)*arg4);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitParameter, 0 |  0 );
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_addFitParameter__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  std::string *arg2 = 0 ;
-  double arg3 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
-  double val3 ;
-  int ecode3 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  FitParameter *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOO:FitSuite_addFitParameter",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_addFitParameter" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitSuite_addFitParameter" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_addFitParameter" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    arg2 = ptr;
-  }
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "FitSuite_addFitParameter" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  result = (FitParameter *)(arg1)->addFitParameter((std::string const &)*arg2,arg3);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitParameter, 0 |  0 );
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_addFitParameter__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  FitParameter *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  FitParameter *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitSuite_addFitParameter",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_addFitParameter" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_FitParameter,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitSuite_addFitParameter" "', argument " "2"" of type '" "FitParameter const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_addFitParameter" "', argument " "2"" of type '" "FitParameter const &""'"); 
-  }
-  arg2 = reinterpret_cast< FitParameter * >(argp2);
-  result = (FitParameter *)(arg1)->addFitParameter((FitParameter const &)*arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitParameter, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_addFitParameter(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[6] = {
-    0
-  };
-  Py_ssize_t ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 5) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 2) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuite, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_FitParameter, 0);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        return _wrap_FitSuite_addFitParameter__SWIG_3(self, args);
-      }
-    }
-  }
-  if (argc == 3) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuite, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_AsPtr_std_string(argv[1], (std::string**)(0));
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        {
-          int res = SWIG_AsVal_double(argv[2], NULL);
-          _v = SWIG_CheckState(res);
-        }
-        if (_v) {
-          return _wrap_FitSuite_addFitParameter__SWIG_2(self, args);
-        }
-      }
-    }
-  }
-  if (argc == 4) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuite, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_AsPtr_std_string(argv[1], (std::string**)(0));
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        {
-          int res = SWIG_AsVal_double(argv[2], NULL);
-          _v = SWIG_CheckState(res);
-        }
-        if (_v) {
-          int res = SWIG_ConvertPtr(argv[3], 0, SWIGTYPE_p_AttLimits, 0);
-          _v = SWIG_CheckState(res);
-          if (_v) {
-            return _wrap_FitSuite_addFitParameter__SWIG_1(self, args);
-          }
-        }
-      }
-    }
-  }
-  if (argc == 5) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuite, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_AsPtr_std_string(argv[1], (std::string**)(0));
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        {
-          int res = SWIG_AsVal_double(argv[2], NULL);
-          _v = SWIG_CheckState(res);
-        }
-        if (_v) {
-          int res = SWIG_ConvertPtr(argv[3], 0, SWIGTYPE_p_AttLimits, 0);
-          _v = SWIG_CheckState(res);
-          if (_v) {
-            {
-              int res = SWIG_AsVal_double(argv[4], NULL);
-              _v = SWIG_CheckState(res);
-            }
-            if (_v) {
-              return _wrap_FitSuite_addFitParameter__SWIG_0(self, args);
-            }
-          }
-        }
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitSuite_addFitParameter'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    FitSuite::addFitParameter(std::string const &,double,AttLimits const &,double)\n"
-    "    FitSuite::addFitParameter(std::string const &,double,AttLimits const &)\n"
-    "    FitSuite::addFitParameter(std::string const &,double)\n"
-    "    FitSuite::addFitParameter(FitParameter const &)\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_setMinimizer__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  std::string *arg2 = 0 ;
-  std::string *arg3 = 0 ;
-  std::string *arg4 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
-  int res3 = SWIG_OLDOBJ ;
-  int res4 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  PyObject * obj3 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOOO:FitSuite_setMinimizer",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_setMinimizer" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitSuite_setMinimizer" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_setMinimizer" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    arg2 = ptr;
-  }
-  {
-    std::string *ptr = (std::string *)0;
-    res3 = SWIG_AsPtr_std_string(obj2, &ptr);
-    if (!SWIG_IsOK(res3)) {
-      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "FitSuite_setMinimizer" "', argument " "3"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_setMinimizer" "', argument " "3"" of type '" "std::string const &""'"); 
-    }
-    arg3 = ptr;
-  }
-  {
-    std::string *ptr = (std::string *)0;
-    res4 = SWIG_AsPtr_std_string(obj3, &ptr);
-    if (!SWIG_IsOK(res4)) {
-      SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "FitSuite_setMinimizer" "', argument " "4"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_setMinimizer" "', argument " "4"" of type '" "std::string const &""'"); 
-    }
-    arg4 = ptr;
-  }
-  (arg1)->setMinimizer((std::string const &)*arg2,(std::string const &)*arg3,(std::string const &)*arg4);
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  if (SWIG_IsNewObj(res4)) delete arg4;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  if (SWIG_IsNewObj(res4)) delete arg4;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_setMinimizer__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  std::string *arg2 = 0 ;
-  std::string *arg3 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
-  int res3 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOO:FitSuite_setMinimizer",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_setMinimizer" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitSuite_setMinimizer" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_setMinimizer" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    arg2 = ptr;
-  }
-  {
-    std::string *ptr = (std::string *)0;
-    res3 = SWIG_AsPtr_std_string(obj2, &ptr);
-    if (!SWIG_IsOK(res3)) {
-      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "FitSuite_setMinimizer" "', argument " "3"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_setMinimizer" "', argument " "3"" of type '" "std::string const &""'"); 
-    }
-    arg3 = ptr;
-  }
-  (arg1)->setMinimizer((std::string const &)*arg2,(std::string const &)*arg3);
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_setMinimizer__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  std::string *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitSuite_setMinimizer",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_setMinimizer" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitSuite_setMinimizer" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_setMinimizer" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    arg2 = ptr;
-  }
-  (arg1)->setMinimizer((std::string const &)*arg2);
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_setChiSquaredModule(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  IChiSquaredModule *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitSuite_setChiSquaredModule",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_setChiSquaredModule" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_IChiSquaredModule,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitSuite_setChiSquaredModule" "', argument " "2"" of type '" "IChiSquaredModule const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_setChiSquaredModule" "', argument " "2"" of type '" "IChiSquaredModule const &""'"); 
-  }
-  arg2 = reinterpret_cast< IChiSquaredModule * >(argp2);
-  (arg1)->setChiSquaredModule((IChiSquaredModule const &)*arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_addFitStrategy(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  IFitStrategy *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitSuite_addFitStrategy",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_addFitStrategy" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_IFitStrategy,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitSuite_addFitStrategy" "', argument " "2"" of type '" "IFitStrategy const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuite_addFitStrategy" "', argument " "2"" of type '" "IFitStrategy const &""'"); 
-  }
-  arg2 = reinterpret_cast< IFitStrategy * >(argp2);
-  (arg1)->addFitStrategy((IFitStrategy const &)*arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_setMinimizer__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  IMinimizer *arg2 = (IMinimizer *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitSuite_setMinimizer",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_setMinimizer" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_IMinimizer, 0 |  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitSuite_setMinimizer" "', argument " "2"" of type '" "IMinimizer *""'"); 
-  }
-  arg2 = reinterpret_cast< IMinimizer * >(argp2);
-  (arg1)->setMinimizer(arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_setMinimizer(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[5] = {
-    0
-  };
-  Py_ssize_t ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 2) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuite, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_IMinimizer, 0);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        return _wrap_FitSuite_setMinimizer__SWIG_3(self, args);
-      }
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuite, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_AsPtr_std_string(argv[1], (std::string**)(0));
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        return _wrap_FitSuite_setMinimizer__SWIG_2(self, args);
-      }
-    }
-  }
-  if (argc == 3) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuite, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_AsPtr_std_string(argv[1], (std::string**)(0));
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        int res = SWIG_AsPtr_std_string(argv[2], (std::string**)(0));
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          return _wrap_FitSuite_setMinimizer__SWIG_1(self, args);
-        }
-      }
-    }
-  }
-  if (argc == 4) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuite, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_AsPtr_std_string(argv[1], (std::string**)(0));
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        int res = SWIG_AsPtr_std_string(argv[2], (std::string**)(0));
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          int res = SWIG_AsPtr_std_string(argv[3], (std::string**)(0));
-          _v = SWIG_CheckState(res);
-          if (_v) {
-            return _wrap_FitSuite_setMinimizer__SWIG_0(self, args);
-          }
-        }
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitSuite_setMinimizer'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    FitSuite::setMinimizer(std::string const &,std::string const &,std::string const &)\n"
-    "    FitSuite::setMinimizer(std::string const &,std::string const &)\n"
-    "    FitSuite::setMinimizer(std::string const &)\n"
-    "    FitSuite::setMinimizer(IMinimizer *)\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_minimizerName(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  std::string result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuite_minimizerName",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_minimizerName" "', argument " "1"" of type '" "FitSuite const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  result = ((FitSuite const *)arg1)->minimizerName();
-  resultobj = SWIG_From_std_string(static_cast< std::string >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_initPrint(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  int arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int val2 ;
-  int ecode2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitSuite_initPrint",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_initPrint" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitSuite_initPrint" "', argument " "2"" of type '" "int""'");
-  } 
-  arg2 = static_cast< int >(val2);
-  (arg1)->initPrint(arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_runFit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuite_runFit",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_runFit" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  (arg1)->runFit();
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_numberOfFitObjects(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  size_t result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuite_numberOfFitObjects",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_numberOfFitObjects" "', argument " "1"" of type '" "FitSuite const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  result = ((FitSuite const *)arg1)->numberOfFitObjects();
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_fitObjects(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  FitSuiteObjects *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuite_fitObjects",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_fitObjects" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  result = (FitSuiteObjects *)(arg1)->fitObjects();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitSuiteObjects, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_fitParameters(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  FitParameterSet *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuite_fitParameters",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_fitParameters" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  result = (FitParameterSet *)(arg1)->fitParameters();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitParameterSet, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_fitStrategies(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  FitSuiteStrategies *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuite_fitStrategies",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_fitStrategies" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  result = (FitSuiteStrategies *)(arg1)->fitStrategies();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitSuiteStrategies, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_isFirstIteration(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  bool result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuite_isFirstIteration",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_isFirstIteration" "', argument " "1"" of type '" "FitSuite const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  result = (bool)((FitSuite const *)arg1)->isFirstIteration();
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_isLastIteration(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  bool result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuite_isLastIteration",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_isLastIteration" "', argument " "1"" of type '" "FitSuite const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  result = (bool)((FitSuite const *)arg1)->isLastIteration();
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_numberOfIterations(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  size_t result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuite_numberOfIterations",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_numberOfIterations" "', argument " "1"" of type '" "FitSuite const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  result = ((FitSuite const *)arg1)->numberOfIterations();
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_currentStrategyIndex(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  size_t result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuite_currentStrategyIndex",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_currentStrategyIndex" "', argument " "1"" of type '" "FitSuite const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  result = ((FitSuite const *)arg1)->currentStrategyIndex();
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_printResults(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuite_printResults",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_printResults" "', argument " "1"" of type '" "FitSuite const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  ((FitSuite const *)arg1)->printResults();
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_reportResults(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  std::string result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuite_reportResults",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_reportResults" "', argument " "1"" of type '" "FitSuite const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  result = ((FitSuite const *)arg1)->reportResults();
-  resultobj = SWIG_From_std_string(static_cast< std::string >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_getChi2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  double result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuite_getChi2",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_getChi2" "', argument " "1"" of type '" "FitSuite const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  result = (double)((FitSuite const *)arg1)->getChi2();
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_interruptFitting(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuite_interruptFitting",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_interruptFitting" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  (arg1)->interruptFitting();
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_resetInterrupt(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuite_resetInterrupt",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_resetInterrupt" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  (arg1)->resetInterrupt();
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_isInterrupted(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  bool result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuite_isInterrupted",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_isInterrupted" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  result = (bool)(arg1)->isInterrupted();
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_parametersToString(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  std::string result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuite_parametersToString",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_parametersToString" "', argument " "1"" of type '" "FitSuite const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  result = ((FitSuite const *)arg1)->parametersToString();
-  resultobj = SWIG_From_std_string(static_cast< std::string >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_treeToString(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  std::string result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuite_treeToString",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_treeToString" "', argument " "1"" of type '" "FitSuite const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  result = ((FitSuite const *)arg1)->treeToString();
-  resultobj = SWIG_From_std_string(static_cast< std::string >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_setupToString(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  std::string result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuite_setupToString",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_setupToString" "', argument " "1"" of type '" "FitSuite *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  result = (arg1)->setupToString();
-  resultobj = SWIG_From_std_string(static_cast< std::string >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_simulationResult__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  size_t arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  size_t val2 ;
-  int ecode2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  SimulationResult result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitSuite_simulationResult",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_simulationResult" "', argument " "1"" of type '" "FitSuite const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitSuite_simulationResult" "', argument " "2"" of type '" "size_t""'");
-  } 
-  arg2 = static_cast< size_t >(val2);
-  result = ((FitSuite const *)arg1)->simulationResult(arg2);
-  resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_simulationResult__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  SimulationResult result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuite_simulationResult",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_simulationResult" "', argument " "1"" of type '" "FitSuite const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  result = ((FitSuite const *)arg1)->simulationResult();
-  resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_simulationResult(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[3] = {
-    0
-  };
-  Py_ssize_t ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuite, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_FitSuite_simulationResult__SWIG_1(self, args);
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuite, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_size_t(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_FitSuite_simulationResult__SWIG_0(self, args);
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitSuite_simulationResult'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    FitSuite::simulationResult(size_t) const\n"
-    "    FitSuite::simulationResult() const\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_experimentalData__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  size_t arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  size_t val2 ;
-  int ecode2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  SimulationResult result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitSuite_experimentalData",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_experimentalData" "', argument " "1"" of type '" "FitSuite const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitSuite_experimentalData" "', argument " "2"" of type '" "size_t""'");
-  } 
-  arg2 = static_cast< size_t >(val2);
-  result = ((FitSuite const *)arg1)->experimentalData(arg2);
-  resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_experimentalData__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  SimulationResult result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuite_experimentalData",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_experimentalData" "', argument " "1"" of type '" "FitSuite const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  result = ((FitSuite const *)arg1)->experimentalData();
-  resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_experimentalData(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[3] = {
-    0
-  };
-  Py_ssize_t ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuite, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_FitSuite_experimentalData__SWIG_1(self, args);
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuite, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_size_t(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_FitSuite_experimentalData__SWIG_0(self, args);
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitSuite_experimentalData'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    FitSuite::experimentalData(size_t) const\n"
-    "    FitSuite::experimentalData() const\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_relativeDifference__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  size_t arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  size_t val2 ;
-  int ecode2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  SimulationResult result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitSuite_relativeDifference",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_relativeDifference" "', argument " "1"" of type '" "FitSuite const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitSuite_relativeDifference" "', argument " "2"" of type '" "size_t""'");
-  } 
-  arg2 = static_cast< size_t >(val2);
-  result = ((FitSuite const *)arg1)->relativeDifference(arg2);
-  resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_relativeDifference__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuite *arg1 = (FitSuite *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  SimulationResult result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuite_relativeDifference",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuite, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuite_relativeDifference" "', argument " "1"" of type '" "FitSuite const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuite * >(argp1);
-  result = ((FitSuite const *)arg1)->relativeDifference();
-  resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuite_relativeDifference(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[3] = {
-    0
-  };
-  Py_ssize_t ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuite, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_FitSuite_relativeDifference__SWIG_1(self, args);
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuite, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_size_t(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_FitSuite_relativeDifference__SWIG_0(self, args);
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitSuite_relativeDifference'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    FitSuite::relativeDifference(size_t) const\n"
-    "    FitSuite::relativeDifference() const\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *FitSuite_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_FitSuite, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *_wrap_new_FitSuiteObjects(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuiteObjects *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)":new_FitSuiteObjects")) SWIG_fail;
-  result = (FitSuiteObjects *)new FitSuiteObjects();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitSuiteObjects, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_delete_FitSuiteObjects(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuiteObjects *arg1 = (FitSuiteObjects *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_FitSuiteObjects",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuiteObjects, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_FitSuiteObjects" "', argument " "1"" of type '" "FitSuiteObjects *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuiteObjects * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuiteObjects_accept(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuiteObjects *arg1 = (FitSuiteObjects *) 0 ;
-  INodeVisitor *arg2 = (INodeVisitor *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitSuiteObjects_accept",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuiteObjects, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuiteObjects_accept" "', argument " "1"" of type '" "FitSuiteObjects const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuiteObjects * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_INodeVisitor, 0 |  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitSuiteObjects_accept" "', argument " "2"" of type '" "INodeVisitor *""'"); 
-  }
-  arg2 = reinterpret_cast< INodeVisitor * >(argp2);
-  ((FitSuiteObjects const *)arg1)->accept(arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuiteObjects_add__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuiteObjects *arg1 = (FitSuiteObjects *) 0 ;
-  Simulation *arg2 = 0 ;
-  OutputData< double > *arg3 = 0 ;
-  double arg4 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  void *argp3 = 0 ;
-  int res3 = 0 ;
-  double val4 ;
-  int ecode4 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  PyObject * obj3 = 0 ;
-  FitObject *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOOO:FitSuiteObjects_add",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuiteObjects, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuiteObjects_add" "', argument " "1"" of type '" "FitSuiteObjects *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuiteObjects * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_Simulation,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitSuiteObjects_add" "', argument " "2"" of type '" "Simulation const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuiteObjects_add" "', argument " "2"" of type '" "Simulation const &""'"); 
-  }
-  arg2 = reinterpret_cast< Simulation * >(argp2);
-  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_OutputDataT_double_t,  0  | 0);
-  if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "FitSuiteObjects_add" "', argument " "3"" of type '" "OutputData< double > const &""'"); 
-  }
-  if (!argp3) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuiteObjects_add" "', argument " "3"" of type '" "OutputData< double > const &""'"); 
-  }
-  arg3 = reinterpret_cast< OutputData< double > * >(argp3);
-  ecode4 = SWIG_AsVal_double(obj3, &val4);
-  if (!SWIG_IsOK(ecode4)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "FitSuiteObjects_add" "', argument " "4"" of type '" "double""'");
-  } 
-  arg4 = static_cast< double >(val4);
-  result = (FitObject *)(arg1)->add((Simulation const &)*arg2,(OutputData< double > const &)*arg3,arg4);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitObject, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuiteObjects_add__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuiteObjects *arg1 = (FitSuiteObjects *) 0 ;
-  Simulation *arg2 = 0 ;
-  OutputData< double > *arg3 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  void *argp3 = 0 ;
-  int res3 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  FitObject *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOO:FitSuiteObjects_add",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuiteObjects, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuiteObjects_add" "', argument " "1"" of type '" "FitSuiteObjects *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuiteObjects * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_Simulation,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitSuiteObjects_add" "', argument " "2"" of type '" "Simulation const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuiteObjects_add" "', argument " "2"" of type '" "Simulation const &""'"); 
-  }
-  arg2 = reinterpret_cast< Simulation * >(argp2);
-  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_OutputDataT_double_t,  0  | 0);
-  if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "FitSuiteObjects_add" "', argument " "3"" of type '" "OutputData< double > const &""'"); 
-  }
-  if (!argp3) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuiteObjects_add" "', argument " "3"" of type '" "OutputData< double > const &""'"); 
-  }
-  arg3 = reinterpret_cast< OutputData< double > * >(argp3);
-  result = (FitObject *)(arg1)->add((Simulation const &)*arg2,(OutputData< double > const &)*arg3);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitObject, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuiteObjects_add(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[5] = {
-    0
-  };
-  Py_ssize_t ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 3) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuiteObjects, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_Simulation, 0);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_OutputDataT_double_t, 0);
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          return _wrap_FitSuiteObjects_add__SWIG_1(self, args);
-        }
-      }
-    }
-  }
-  if (argc == 4) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuiteObjects, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_Simulation, 0);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_OutputDataT_double_t, 0);
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          {
-            int res = SWIG_AsVal_double(argv[3], NULL);
-            _v = SWIG_CheckState(res);
-          }
-          if (_v) {
-            return _wrap_FitSuiteObjects_add__SWIG_0(self, args);
-          }
-        }
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitSuiteObjects_add'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    FitSuiteObjects::add(Simulation const &,OutputData< double > const &,double)\n"
-    "    FitSuiteObjects::add(Simulation const &,OutputData< double > const &)\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuiteObjects_getSizeOfDataSet(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuiteObjects *arg1 = (FitSuiteObjects *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  size_t result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuiteObjects_getSizeOfDataSet",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuiteObjects, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuiteObjects_getSizeOfDataSet" "', argument " "1"" of type '" "FitSuiteObjects const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuiteObjects * >(argp1);
-  result = ((FitSuiteObjects const *)arg1)->getSizeOfDataSet();
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuiteObjects_setChiSquaredModule(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuiteObjects *arg1 = (FitSuiteObjects *) 0 ;
-  IChiSquaredModule *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitSuiteObjects_setChiSquaredModule",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuiteObjects, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuiteObjects_setChiSquaredModule" "', argument " "1"" of type '" "FitSuiteObjects *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuiteObjects * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_IChiSquaredModule,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitSuiteObjects_setChiSquaredModule" "', argument " "2"" of type '" "IChiSquaredModule const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitSuiteObjects_setChiSquaredModule" "', argument " "2"" of type '" "IChiSquaredModule const &""'"); 
-  }
-  arg2 = reinterpret_cast< IChiSquaredModule * >(argp2);
-  (arg1)->setChiSquaredModule((IChiSquaredModule const &)*arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuiteObjects_simulationResult__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuiteObjects *arg1 = (FitSuiteObjects *) 0 ;
-  size_t arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  size_t val2 ;
-  int ecode2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  SimulationResult result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitSuiteObjects_simulationResult",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuiteObjects, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuiteObjects_simulationResult" "', argument " "1"" of type '" "FitSuiteObjects const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuiteObjects * >(argp1);
-  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitSuiteObjects_simulationResult" "', argument " "2"" of type '" "size_t""'");
-  } 
-  arg2 = static_cast< size_t >(val2);
-  result = ((FitSuiteObjects const *)arg1)->simulationResult(arg2);
-  resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuiteObjects_simulationResult__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuiteObjects *arg1 = (FitSuiteObjects *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  SimulationResult result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuiteObjects_simulationResult",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuiteObjects, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuiteObjects_simulationResult" "', argument " "1"" of type '" "FitSuiteObjects const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuiteObjects * >(argp1);
-  result = ((FitSuiteObjects const *)arg1)->simulationResult();
-  resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuiteObjects_simulationResult(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[3] = {
-    0
-  };
-  Py_ssize_t ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuiteObjects, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_FitSuiteObjects_simulationResult__SWIG_1(self, args);
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuiteObjects, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_size_t(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_FitSuiteObjects_simulationResult__SWIG_0(self, args);
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitSuiteObjects_simulationResult'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    FitSuiteObjects::simulationResult(size_t) const\n"
-    "    FitSuiteObjects::simulationResult() const\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuiteObjects_experimentalData__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuiteObjects *arg1 = (FitSuiteObjects *) 0 ;
-  size_t arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  size_t val2 ;
-  int ecode2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  SimulationResult result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitSuiteObjects_experimentalData",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuiteObjects, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuiteObjects_experimentalData" "', argument " "1"" of type '" "FitSuiteObjects const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuiteObjects * >(argp1);
-  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitSuiteObjects_experimentalData" "', argument " "2"" of type '" "size_t""'");
-  } 
-  arg2 = static_cast< size_t >(val2);
-  result = ((FitSuiteObjects const *)arg1)->experimentalData(arg2);
-  resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuiteObjects_experimentalData__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuiteObjects *arg1 = (FitSuiteObjects *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  SimulationResult result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuiteObjects_experimentalData",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuiteObjects, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuiteObjects_experimentalData" "', argument " "1"" of type '" "FitSuiteObjects const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuiteObjects * >(argp1);
-  result = ((FitSuiteObjects const *)arg1)->experimentalData();
-  resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuiteObjects_experimentalData(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[3] = {
-    0
-  };
-  Py_ssize_t ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuiteObjects, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_FitSuiteObjects_experimentalData__SWIG_1(self, args);
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuiteObjects, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_size_t(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_FitSuiteObjects_experimentalData__SWIG_0(self, args);
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitSuiteObjects_experimentalData'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    FitSuiteObjects::experimentalData(size_t) const\n"
-    "    FitSuiteObjects::experimentalData() const\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuiteObjects_relativeDifference__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuiteObjects *arg1 = (FitSuiteObjects *) 0 ;
-  size_t arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  size_t val2 ;
-  int ecode2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  SimulationResult result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitSuiteObjects_relativeDifference",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuiteObjects, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuiteObjects_relativeDifference" "', argument " "1"" of type '" "FitSuiteObjects const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuiteObjects * >(argp1);
-  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitSuiteObjects_relativeDifference" "', argument " "2"" of type '" "size_t""'");
-  } 
-  arg2 = static_cast< size_t >(val2);
-  result = ((FitSuiteObjects const *)arg1)->relativeDifference(arg2);
-  resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuiteObjects_relativeDifference__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuiteObjects *arg1 = (FitSuiteObjects *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  SimulationResult result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuiteObjects_relativeDifference",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuiteObjects, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuiteObjects_relativeDifference" "', argument " "1"" of type '" "FitSuiteObjects const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuiteObjects * >(argp1);
-  result = ((FitSuiteObjects const *)arg1)->relativeDifference();
-  resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuiteObjects_relativeDifference(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[3] = {
-    0
-  };
-  Py_ssize_t ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuiteObjects, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_FitSuiteObjects_relativeDifference__SWIG_1(self, args);
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitSuiteObjects, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_size_t(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_FitSuiteObjects_relativeDifference__SWIG_0(self, args);
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitSuiteObjects_relativeDifference'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    FitSuiteObjects::relativeDifference(size_t) const\n"
-    "    FitSuiteObjects::relativeDifference() const\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuiteObjects_runSimulations(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuiteObjects *arg1 = (FitSuiteObjects *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuiteObjects_runSimulations",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuiteObjects, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuiteObjects_runSimulations" "', argument " "1"" of type '" "FitSuiteObjects *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuiteObjects * >(argp1);
-  (arg1)->runSimulations();
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuiteObjects_getChiSquaredValue(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuiteObjects *arg1 = (FitSuiteObjects *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  double result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuiteObjects_getChiSquaredValue",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuiteObjects, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuiteObjects_getChiSquaredValue" "', argument " "1"" of type '" "FitSuiteObjects const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuiteObjects * >(argp1);
-  result = (double)((FitSuiteObjects const *)arg1)->getChiSquaredValue();
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuiteObjects_getResidualValue(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuiteObjects *arg1 = (FitSuiteObjects *) 0 ;
-  size_t arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  size_t val2 ;
-  int ecode2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  double result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitSuiteObjects_getResidualValue",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuiteObjects, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuiteObjects_getResidualValue" "', argument " "1"" of type '" "FitSuiteObjects *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuiteObjects * >(argp1);
-  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitSuiteObjects_getResidualValue" "', argument " "2"" of type '" "size_t""'");
-  } 
-  arg2 = static_cast< size_t >(val2);
-  result = (double)(arg1)->getResidualValue(arg2);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuiteObjects_residuals(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuiteObjects *arg1 = (FitSuiteObjects *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  std::vector< double,std::allocator< double > > result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuiteObjects_residuals",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuiteObjects, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuiteObjects_residuals" "', argument " "1"" of type '" "FitSuiteObjects const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuiteObjects * >(argp1);
-  result = ((FitSuiteObjects const *)arg1)->residuals();
-  resultobj = swig::from(static_cast< std::vector< double,std::allocator< double > > >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuiteObjects_setNfreeParameters(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuiteObjects *arg1 = (FitSuiteObjects *) 0 ;
-  int arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int val2 ;
-  int ecode2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitSuiteObjects_setNfreeParameters",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuiteObjects, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuiteObjects_setNfreeParameters" "', argument " "1"" of type '" "FitSuiteObjects *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuiteObjects * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitSuiteObjects_setNfreeParameters" "', argument " "2"" of type '" "int""'");
-  } 
-  arg2 = static_cast< int >(val2);
-  (arg1)->setNfreeParameters(arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuiteObjects_clear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuiteObjects *arg1 = (FitSuiteObjects *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuiteObjects_clear",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuiteObjects, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuiteObjects_clear" "', argument " "1"" of type '" "FitSuiteObjects *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuiteObjects * >(argp1);
-  (arg1)->clear();
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuiteObjects_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuiteObjects *arg1 = (FitSuiteObjects *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  size_t result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuiteObjects_size",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuiteObjects, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuiteObjects_size" "', argument " "1"" of type '" "FitSuiteObjects const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuiteObjects * >(argp1);
-  result = ((FitSuiteObjects const *)arg1)->size();
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuiteObjects_begin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuiteObjects *arg1 = (FitSuiteObjects *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  SwigValueWrapper< SafePointerVector< FitObject >::iterator > result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuiteObjects_begin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuiteObjects, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuiteObjects_begin" "', argument " "1"" of type '" "FitSuiteObjects *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuiteObjects * >(argp1);
-  result = (arg1)->begin();
-  resultobj = SWIG_NewPointerObj((new FitSuiteObjects::iterator(static_cast< const FitSuiteObjects::iterator& >(result))), SWIGTYPE_p_SafePointerVectorT_FitObject_t__iterator, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuiteObjects_end(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuiteObjects *arg1 = (FitSuiteObjects *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  SwigValueWrapper< SafePointerVector< FitObject >::iterator > result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuiteObjects_end",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuiteObjects, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuiteObjects_end" "', argument " "1"" of type '" "FitSuiteObjects *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuiteObjects * >(argp1);
-  result = (arg1)->end();
-  resultobj = SWIG_NewPointerObj((new FitSuiteObjects::iterator(static_cast< const FitSuiteObjects::iterator& >(result))), SWIGTYPE_p_SafePointerVectorT_FitObject_t__iterator, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitSuiteObjects_getChildren(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitSuiteObjects *arg1 = (FitSuiteObjects *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  std::vector< INode const *,std::allocator< INode const * > > result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitSuiteObjects_getChildren",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitSuiteObjects, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitSuiteObjects_getChildren" "', argument " "1"" of type '" "FitSuiteObjects const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitSuiteObjects * >(argp1);
-  result = ((FitSuiteObjects const *)arg1)->getChildren();
-  resultobj = swig::from(static_cast< std::vector< INode const*,std::allocator< INode const * > > >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *FitSuiteObjects_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_FitSuiteObjects, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *_wrap_new_PyBuilderCallback(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  PyObject *arg1 = (PyObject *) 0 ;
-  PyObject * obj0 = 0 ;
-  PyBuilderCallback *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:new_PyBuilderCallback",&obj0)) SWIG_fail;
-  arg1 = obj0;
-  if ( arg1 != Py_None ) {
-    /* subclassed */
-    result = (PyBuilderCallback *)new SwigDirector_PyBuilderCallback(arg1); 
-  } else {
-    result = (PyBuilderCallback *)new PyBuilderCallback(); 
-  }
-  
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_PyBuilderCallback, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_delete_PyBuilderCallback(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  PyBuilderCallback *arg1 = (PyBuilderCallback *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_PyBuilderCallback",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_PyBuilderCallback, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_PyBuilderCallback" "', argument " "1"" of type '" "PyBuilderCallback *""'"); 
-  }
-  arg1 = reinterpret_cast< PyBuilderCallback * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_PyBuilderCallback_build_simulation(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  PyBuilderCallback *arg1 = (PyBuilderCallback *) 0 ;
-  Fit::Parameters arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  Swig::Director *director = 0;
-  bool upcall = false;
-  Simulation *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:PyBuilderCallback_build_simulation",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_PyBuilderCallback, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PyBuilderCallback_build_simulation" "', argument " "1"" of type '" "PyBuilderCallback *""'"); 
-  }
-  arg1 = reinterpret_cast< PyBuilderCallback * >(argp1);
-  {
-    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_Fit__Parameters,  0  | 0);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "PyBuilderCallback_build_simulation" "', argument " "2"" of type '" "Fit::Parameters""'"); 
-    }  
-    if (!argp2) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "PyBuilderCallback_build_simulation" "', argument " "2"" of type '" "Fit::Parameters""'");
-    } else {
-      Fit::Parameters * temp = reinterpret_cast< Fit::Parameters * >(argp2);
-      arg2 = *temp;
-      if (SWIG_IsNewObj(res2)) delete temp;
-    }
-  }
-  director = SWIG_DIRECTOR_CAST(arg1);
-  upcall = (director && (director->swig_get_self()==obj0));
-  try {
-    if (upcall) {
-      result = (Simulation *)(arg1)->PyBuilderCallback::build_simulation(arg2);
-    } else {
-      result = (Simulation *)(arg1)->build_simulation(arg2);
-    }
-  } catch (Swig::DirectorException&) {
-    SWIG_fail;
-  }
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Simulation, 0 |  0 );
-  if (director) {
-    SWIG_AcquirePtr(resultobj, director->swig_release_ownership(SWIG_as_voidptr(result)));
-  }
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_disown_PyBuilderCallback(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  PyBuilderCallback *arg1 = (PyBuilderCallback *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:disown_PyBuilderCallback",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_PyBuilderCallback, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "disown_PyBuilderCallback" "', argument " "1"" of type '" "PyBuilderCallback *""'"); 
-  }
-  arg1 = reinterpret_cast< PyBuilderCallback * >(argp1);
-  {
-    Swig::Director *director = SWIG_DIRECTOR_CAST(arg1);
-    if (director) director->swig_disown();
-  }
-  
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *PyBuilderCallback_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_PyBuilderCallback, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *_wrap_new_PyObserverCallback(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  PyObject *arg1 = (PyObject *) 0 ;
-  PyObject * obj0 = 0 ;
-  PyObserverCallback *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:new_PyObserverCallback",&obj0)) SWIG_fail;
-  arg1 = obj0;
-  if ( arg1 != Py_None ) {
-    /* subclassed */
-    result = (PyObserverCallback *)new SwigDirector_PyObserverCallback(arg1); 
-  } else {
-    result = (PyObserverCallback *)new PyObserverCallback(); 
-  }
-  
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_PyObserverCallback, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_delete_PyObserverCallback(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  PyObserverCallback *arg1 = (PyObserverCallback *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_PyObserverCallback",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_PyObserverCallback, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_PyObserverCallback" "', argument " "1"" of type '" "PyObserverCallback *""'"); 
-  }
-  arg1 = reinterpret_cast< PyObserverCallback * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_PyObserverCallback_update(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  PyObserverCallback *arg1 = (PyObserverCallback *) 0 ;
-  FitObjective *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  Swig::Director *director = 0;
-  bool upcall = false;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:PyObserverCallback_update",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_PyObserverCallback, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PyObserverCallback_update" "', argument " "1"" of type '" "PyObserverCallback *""'"); 
-  }
-  arg1 = reinterpret_cast< PyObserverCallback * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_FitObjective,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "PyObserverCallback_update" "', argument " "2"" of type '" "FitObjective const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "PyObserverCallback_update" "', argument " "2"" of type '" "FitObjective const &""'"); 
-  }
-  arg2 = reinterpret_cast< FitObjective * >(argp2);
-  director = SWIG_DIRECTOR_CAST(arg1);
-  upcall = (director && (director->swig_get_self()==obj0));
-  try {
-    if (upcall) {
-      (arg1)->PyObserverCallback::update((FitObjective const &)*arg2);
-    } else {
-      (arg1)->update((FitObjective const &)*arg2);
-    }
-  } catch (Swig::DirectorException&) {
-    SWIG_fail;
-  }
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_disown_PyObserverCallback(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  PyObserverCallback *arg1 = (PyObserverCallback *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:disown_PyObserverCallback",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_PyObserverCallback, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "disown_PyObserverCallback" "', argument " "1"" of type '" "PyObserverCallback *""'"); 
-  }
-  arg1 = reinterpret_cast< PyObserverCallback * >(argp1);
-  {
-    Swig::Director *director = SWIG_DIRECTOR_CAST(arg1);
-    if (director) director->swig_disown();
-  }
-  
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *PyObserverCallback_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_PyObserverCallback, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *_wrap_new_FitObjective(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitObjective *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)":new_FitObjective")) SWIG_fail;
-  result = (FitObjective *)new FitObjective();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FitObjective, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_delete_FitObjective(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitObjective *arg1 = (FitObjective *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_FitObjective",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_FitObjective" "', argument " "1"" of type '" "FitObjective *""'"); 
-  }
-  arg1 = reinterpret_cast< FitObjective * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitObjective_addSimulationAndData_cpp__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitObjective *arg1 = (FitObjective *) 0 ;
-  PyBuilderCallback *arg2 = 0 ;
-  std::vector< double,std::allocator< double > > *arg3 = 0 ;
-  double arg4 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  int res3 = SWIG_OLDOBJ ;
-  double val4 ;
-  int ecode4 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  PyObject * obj3 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOOO:FitObjective_addSimulationAndData_cpp",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "1"" of type '" "FitObjective *""'"); 
-  }
-  arg1 = reinterpret_cast< FitObjective * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_PyBuilderCallback,  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "2"" of type '" "PyBuilderCallback &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "2"" of type '" "PyBuilderCallback &""'"); 
-  }
-  arg2 = reinterpret_cast< PyBuilderCallback * >(argp2);
-  {
-    std::vector< double,std::allocator< double > > *ptr = (std::vector< double,std::allocator< double > > *)0;
-    res3 = swig::asptr(obj2, &ptr);
-    if (!SWIG_IsOK(res3)) {
-      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "3"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "3"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
-    }
-    arg3 = ptr;
-  }
-  ecode4 = SWIG_AsVal_double(obj3, &val4);
-  if (!SWIG_IsOK(ecode4)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "4"" of type '" "double""'");
-  } 
-  arg4 = static_cast< double >(val4);
-  (arg1)->addSimulationAndData(*arg2,(std::vector< double,std::allocator< double > > const &)*arg3,arg4);
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitObjective_addSimulationAndData_cpp__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitObjective *arg1 = (FitObjective *) 0 ;
-  PyBuilderCallback *arg2 = 0 ;
-  std::vector< double,std::allocator< double > > *arg3 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  int res3 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOO:FitObjective_addSimulationAndData_cpp",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "1"" of type '" "FitObjective *""'"); 
-  }
-  arg1 = reinterpret_cast< FitObjective * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_PyBuilderCallback,  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "2"" of type '" "PyBuilderCallback &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "2"" of type '" "PyBuilderCallback &""'"); 
-  }
-  arg2 = reinterpret_cast< PyBuilderCallback * >(argp2);
-  {
-    std::vector< double,std::allocator< double > > *ptr = (std::vector< double,std::allocator< double > > *)0;
-    res3 = swig::asptr(obj2, &ptr);
-    if (!SWIG_IsOK(res3)) {
-      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "3"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "3"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
-    }
-    arg3 = ptr;
-  }
-  (arg1)->addSimulationAndData(*arg2,(std::vector< double,std::allocator< double > > const &)*arg3);
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitObjective_addSimulationAndData_cpp__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitObjective *arg1 = (FitObjective *) 0 ;
-  PyBuilderCallback *arg2 = 0 ;
-  std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *arg3 = 0 ;
-  double arg4 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  int res3 = SWIG_OLDOBJ ;
-  double val4 ;
-  int ecode4 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  PyObject * obj3 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOOO:FitObjective_addSimulationAndData_cpp",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "1"" of type '" "FitObjective *""'"); 
-  }
-  arg1 = reinterpret_cast< FitObjective * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_PyBuilderCallback,  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "2"" of type '" "PyBuilderCallback &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "2"" of type '" "PyBuilderCallback &""'"); 
-  }
-  arg2 = reinterpret_cast< PyBuilderCallback * >(argp2);
-  {
-    std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *ptr = (std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *)0;
-    res3 = swig::asptr(obj2, &ptr);
-    if (!SWIG_IsOK(res3)) {
-      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "3"" of type '" "std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "3"" of type '" "std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &""'"); 
-    }
-    arg3 = ptr;
-  }
-  ecode4 = SWIG_AsVal_double(obj3, &val4);
-  if (!SWIG_IsOK(ecode4)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "4"" of type '" "double""'");
-  } 
-  arg4 = static_cast< double >(val4);
-  (arg1)->addSimulationAndData(*arg2,(std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &)*arg3,arg4);
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitObjective_addSimulationAndData_cpp__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitObjective *arg1 = (FitObjective *) 0 ;
-  PyBuilderCallback *arg2 = 0 ;
-  std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *arg3 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  int res3 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOO:FitObjective_addSimulationAndData_cpp",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "1"" of type '" "FitObjective *""'"); 
-  }
-  arg1 = reinterpret_cast< FitObjective * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_PyBuilderCallback,  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "2"" of type '" "PyBuilderCallback &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "2"" of type '" "PyBuilderCallback &""'"); 
-  }
-  arg2 = reinterpret_cast< PyBuilderCallback * >(argp2);
-  {
-    std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *ptr = (std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *)0;
-    res3 = swig::asptr(obj2, &ptr);
-    if (!SWIG_IsOK(res3)) {
-      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "3"" of type '" "std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObjective_addSimulationAndData_cpp" "', argument " "3"" of type '" "std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &""'"); 
-    }
-    arg3 = ptr;
-  }
-  (arg1)->addSimulationAndData(*arg2,(std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &)*arg3);
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitObjective_addSimulationAndData_cpp(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[5] = {
-    0
-  };
-  Py_ssize_t ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 3) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_PyBuilderCallback, 0);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        int res = swig::asptr(argv[2], (std::vector< double,std::allocator< double > >**)(0));
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          return _wrap_FitObjective_addSimulationAndData_cpp__SWIG_1(self, args);
-        }
-      }
-    }
-  }
-  if (argc == 3) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_PyBuilderCallback, 0);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        int res = swig::asptr(argv[2], (std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >**)(0));
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          return _wrap_FitObjective_addSimulationAndData_cpp__SWIG_3(self, args);
-        }
-      }
-    }
-  }
-  if (argc == 4) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_PyBuilderCallback, 0);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        int res = swig::asptr(argv[2], (std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >**)(0));
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          {
-            int res = SWIG_AsVal_double(argv[3], NULL);
-            _v = SWIG_CheckState(res);
-          }
-          if (_v) {
-            return _wrap_FitObjective_addSimulationAndData_cpp__SWIG_2(self, args);
-          }
-        }
-      }
-    }
-  }
-  if (argc == 4) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_PyBuilderCallback, 0);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        int res = swig::asptr(argv[2], (std::vector< double,std::allocator< double > >**)(0));
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          {
-            int res = SWIG_AsVal_double(argv[3], NULL);
-            _v = SWIG_CheckState(res);
-          }
-          if (_v) {
-            return _wrap_FitObjective_addSimulationAndData_cpp__SWIG_0(self, args);
-          }
-        }
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitObjective_addSimulationAndData_cpp'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    FitObjective::addSimulationAndData(PyBuilderCallback &,std::vector< double,std::allocator< double > > const &,double)\n"
-    "    FitObjective::addSimulationAndData(PyBuilderCallback &,std::vector< double,std::allocator< double > > const &)\n"
-    "    FitObjective::addSimulationAndData(PyBuilderCallback &,std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &,double)\n"
-    "    FitObjective::addSimulationAndData(PyBuilderCallback &,std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &)\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitObjective_evaluate_cpp(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitObjective *arg1 = (FitObjective *) 0 ;
-  Fit::Parameters *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  double result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitObjective_evaluate_cpp",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_evaluate_cpp" "', argument " "1"" of type '" "FitObjective *""'"); 
-  }
-  arg1 = reinterpret_cast< FitObjective * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_Fit__Parameters,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitObjective_evaluate_cpp" "', argument " "2"" of type '" "Fit::Parameters const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObjective_evaluate_cpp" "', argument " "2"" of type '" "Fit::Parameters const &""'"); 
-  }
-  arg2 = reinterpret_cast< Fit::Parameters * >(argp2);
-  result = (double)(arg1)->evaluate((Fit::Parameters const &)*arg2);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitObjective_evaluate_residuals_cpp(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitObjective *arg1 = (FitObjective *) 0 ;
-  Fit::Parameters *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  std::vector< double,std::allocator< double > > result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitObjective_evaluate_residuals_cpp",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_evaluate_residuals_cpp" "', argument " "1"" of type '" "FitObjective *""'"); 
-  }
-  arg1 = reinterpret_cast< FitObjective * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_Fit__Parameters,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitObjective_evaluate_residuals_cpp" "', argument " "2"" of type '" "Fit::Parameters const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObjective_evaluate_residuals_cpp" "', argument " "2"" of type '" "Fit::Parameters const &""'"); 
-  }
-  arg2 = reinterpret_cast< Fit::Parameters * >(argp2);
-  result = (arg1)->evaluate_residuals((Fit::Parameters const &)*arg2);
-  resultobj = swig::from(static_cast< std::vector< double,std::allocator< double > > >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitObjective_numberOfFitElements(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitObjective *arg1 = (FitObjective *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  size_t result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_numberOfFitElements",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_numberOfFitElements" "', argument " "1"" of type '" "FitObjective const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitObjective * >(argp1);
-  result = ((FitObjective const *)arg1)->numberOfFitElements();
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitObjective_experimental_array(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitObjective *arg1 = (FitObjective *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  std::vector< double,std::allocator< double > > result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_experimental_array",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_experimental_array" "', argument " "1"" of type '" "FitObjective const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitObjective * >(argp1);
-  result = ((FitObjective const *)arg1)->experimental_array();
-  resultobj = swig::from(static_cast< std::vector< double,std::allocator< double > > >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitObjective_simulation_array(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitObjective *arg1 = (FitObjective *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  std::vector< double,std::allocator< double > > result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_simulation_array",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_simulation_array" "', argument " "1"" of type '" "FitObjective const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitObjective * >(argp1);
-  result = ((FitObjective const *)arg1)->simulation_array();
-  resultobj = swig::from(static_cast< std::vector< double,std::allocator< double > > >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitObjective_simulationResult__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitObjective *arg1 = (FitObjective *) 0 ;
-  size_t arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  size_t val2 ;
-  int ecode2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  SimulationResult result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitObjective_simulationResult",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_simulationResult" "', argument " "1"" of type '" "FitObjective const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitObjective * >(argp1);
-  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitObjective_simulationResult" "', argument " "2"" of type '" "size_t""'");
-  } 
-  arg2 = static_cast< size_t >(val2);
-  result = ((FitObjective const *)arg1)->simulationResult(arg2);
-  resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitObjective_simulationResult__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitObjective *arg1 = (FitObjective *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  SimulationResult result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_simulationResult",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_simulationResult" "', argument " "1"" of type '" "FitObjective const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitObjective * >(argp1);
-  result = ((FitObjective const *)arg1)->simulationResult();
-  resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitObjective_simulationResult(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[3] = {
-    0
-  };
-  Py_ssize_t ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_FitObjective_simulationResult__SWIG_1(self, args);
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_size_t(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_FitObjective_simulationResult__SWIG_0(self, args);
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitObjective_simulationResult'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    FitObjective::simulationResult(size_t) const\n"
-    "    FitObjective::simulationResult() const\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitObjective_experimentalData__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitObjective *arg1 = (FitObjective *) 0 ;
-  size_t arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  size_t val2 ;
-  int ecode2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  SimulationResult result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitObjective_experimentalData",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_experimentalData" "', argument " "1"" of type '" "FitObjective const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitObjective * >(argp1);
-  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitObjective_experimentalData" "', argument " "2"" of type '" "size_t""'");
-  } 
-  arg2 = static_cast< size_t >(val2);
-  result = ((FitObjective const *)arg1)->experimentalData(arg2);
-  resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitObjective_experimentalData__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitObjective *arg1 = (FitObjective *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  SimulationResult result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_experimentalData",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_experimentalData" "', argument " "1"" of type '" "FitObjective const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitObjective * >(argp1);
-  result = ((FitObjective const *)arg1)->experimentalData();
-  resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitObjective_experimentalData(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[3] = {
-    0
-  };
-  Py_ssize_t ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_FitObjective_experimentalData__SWIG_1(self, args);
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_size_t(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_FitObjective_experimentalData__SWIG_0(self, args);
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitObjective_experimentalData'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    FitObjective::experimentalData(size_t) const\n"
-    "    FitObjective::experimentalData() const\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitObjective_relativeDifference__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitObjective *arg1 = (FitObjective *) 0 ;
-  size_t arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  size_t val2 ;
-  int ecode2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  SimulationResult result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitObjective_relativeDifference",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_relativeDifference" "', argument " "1"" of type '" "FitObjective const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitObjective * >(argp1);
-  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitObjective_relativeDifference" "', argument " "2"" of type '" "size_t""'");
-  } 
-  arg2 = static_cast< size_t >(val2);
-  result = ((FitObjective const *)arg1)->relativeDifference(arg2);
-  resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitObjective_relativeDifference__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitObjective *arg1 = (FitObjective *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  SimulationResult result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_relativeDifference",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_relativeDifference" "', argument " "1"" of type '" "FitObjective const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitObjective * >(argp1);
-  result = ((FitObjective const *)arg1)->relativeDifference();
-  resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitObjective_relativeDifference(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[3] = {
-    0
-  };
-  Py_ssize_t ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_FitObjective_relativeDifference__SWIG_1(self, args);
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_FitObjective, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_size_t(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_FitObjective_relativeDifference__SWIG_0(self, args);
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'FitObjective_relativeDifference'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    FitObjective::relativeDifference(size_t) const\n"
-    "    FitObjective::relativeDifference() const\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitObjective_initPrint(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitObjective *arg1 = (FitObjective *) 0 ;
-  int arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int val2 ;
-  int ecode2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitObjective_initPrint",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_initPrint" "', argument " "1"" of type '" "FitObjective *""'"); 
-  }
-  arg1 = reinterpret_cast< FitObjective * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitObjective_initPrint" "', argument " "2"" of type '" "int""'");
-  } 
-  arg2 = static_cast< int >(val2);
-  (arg1)->initPrint(arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitObjective_initPlot_cpp(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitObjective *arg1 = (FitObjective *) 0 ;
-  int arg2 ;
-  PyObserverCallback *arg3 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int val2 ;
-  int ecode2 = 0 ;
-  void *argp3 = 0 ;
-  int res3 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOO:FitObjective_initPlot_cpp",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_initPlot_cpp" "', argument " "1"" of type '" "FitObjective *""'"); 
-  }
-  arg1 = reinterpret_cast< FitObjective * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FitObjective_initPlot_cpp" "', argument " "2"" of type '" "int""'");
-  } 
-  arg2 = static_cast< int >(val2);
-  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_PyObserverCallback,  0 );
-  if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "FitObjective_initPlot_cpp" "', argument " "3"" of type '" "PyObserverCallback &""'"); 
-  }
-  if (!argp3) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObjective_initPlot_cpp" "', argument " "3"" of type '" "PyObserverCallback &""'"); 
-  }
-  arg3 = reinterpret_cast< PyObserverCallback * >(argp3);
-  (arg1)->initPlot(arg2,*arg3);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitObjective_isCompleted(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitObjective *arg1 = (FitObjective *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  bool result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_isCompleted",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_isCompleted" "', argument " "1"" of type '" "FitObjective const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitObjective * >(argp1);
-  result = (bool)((FitObjective const *)arg1)->isCompleted();
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitObjective_iterationInfo(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitObjective *arg1 = (FitObjective *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  IterationInfo result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_iterationInfo",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_iterationInfo" "', argument " "1"" of type '" "FitObjective const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitObjective * >(argp1);
-  result = ((FitObjective const *)arg1)->iterationInfo();
-  resultobj = SWIG_NewPointerObj((new IterationInfo(static_cast< const IterationInfo& >(result))), SWIGTYPE_p_IterationInfo, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitObjective_minimizerResult(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitObjective *arg1 = (FitObjective *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  Fit::MinimizerResult result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_minimizerResult",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_minimizerResult" "', argument " "1"" of type '" "FitObjective const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitObjective * >(argp1);
-  result = ((FitObjective const *)arg1)->minimizerResult();
-  resultobj = SWIG_NewPointerObj((new Fit::MinimizerResult(static_cast< const Fit::MinimizerResult& >(result))), SWIGTYPE_p_Fit__MinimizerResult, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitObjective_finalize_cpp(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitObjective *arg1 = (FitObjective *) 0 ;
-  Fit::MinimizerResult *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:FitObjective_finalize_cpp",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_finalize_cpp" "', argument " "1"" of type '" "FitObjective *""'"); 
-  }
-  arg1 = reinterpret_cast< FitObjective * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_Fit__MinimizerResult,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FitObjective_finalize_cpp" "', argument " "2"" of type '" "Fit::MinimizerResult const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FitObjective_finalize_cpp" "', argument " "2"" of type '" "Fit::MinimizerResult const &""'"); 
-  }
-  arg2 = reinterpret_cast< Fit::MinimizerResult * >(argp2);
-  (arg1)->finalize((Fit::MinimizerResult const &)*arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FitObjective_fitObjectCount(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  FitObjective *arg1 = (FitObjective *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  unsigned int result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:FitObjective_fitObjectCount",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FitObjective, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FitObjective_fitObjectCount" "', argument " "1"" of type '" "FitObjective const *""'"); 
-  }
-  arg1 = reinterpret_cast< FitObjective * >(argp1);
-  result = (unsigned int)((FitObjective const *)arg1)->fitObjectCount();
-  resultobj = SWIG_From_unsigned_SS_int(static_cast< unsigned int >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *FitObjective_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_FitObjective, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *_wrap_StandardNormal(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  double arg1 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  PyObject * obj0 = 0 ;
-  double result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:StandardNormal",&obj0)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(obj0, &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "StandardNormal" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  result = (double)MathFunctions::StandardNormal(arg1);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_Gaussian(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  double arg1 ;
-  double arg2 ;
-  double arg3 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  double result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOO:Gaussian",&obj0,&obj1,&obj2)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(obj0, &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "Gaussian" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Gaussian" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Gaussian" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  result = (double)MathFunctions::Gaussian(arg1,arg2,arg3);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IntegratedGaussian(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  double arg1 ;
-  double arg2 ;
-  double arg3 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  double result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOO:IntegratedGaussian",&obj0,&obj1,&obj2)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(obj0, &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "IntegratedGaussian" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntegratedGaussian" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntegratedGaussian" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  result = (double)MathFunctions::IntegratedGaussian(arg1,arg2,arg3);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_cot(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  double arg1 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  PyObject * obj0 = 0 ;
-  double result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:cot",&obj0)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(obj0, &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "cot" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  result = (double)MathFunctions::cot(arg1);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_Si(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  double arg1 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  PyObject * obj0 = 0 ;
-  double result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:Si",&obj0)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(obj0, &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "Si" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  result = (double)MathFunctions::Si(arg1);
-  resultobj = SWIG_From_double(static_cast< double >(result));
+  if (!PyArg_ParseTuple(args,(char *)"O:Si",&obj0)) SWIG_fail;
+  ecode1 = SWIG_AsVal_double(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "Si" "', argument " "1"" of type '" "double""'");
+  } 
+  arg1 = static_cast< double >(val1);
+  result = (double)MathFunctions::Si(arg1);
+  resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
   return NULL;
@@ -53647,29 +46371,29 @@ fail:
 
 SWIGINTERN PyObject *_wrap_Laue(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  complex_t arg1 ;
+  double arg1 ;
   size_t arg2 ;
-  std::complex< double > val1 ;
+  double val1 ;
   int ecode1 = 0 ;
   size_t val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  complex_t result;
+  double result;
   
   if (!PyArg_ParseTuple(args,(char *)"OO:Laue",&obj0,&obj1)) SWIG_fail;
-  ecode1 = SWIG_AsVal_std_complex_Sl_double_Sg_(obj0, &val1);
+  ecode1 = SWIG_AsVal_double(obj0, &val1);
   if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "Laue" "', argument " "1"" of type '" "complex_t""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "Laue" "', argument " "1"" of type '" "double""'");
   } 
-  arg1 = static_cast< complex_t >(val1);
+  arg1 = static_cast< double >(val1);
   ecode2 = SWIG_AsVal_size_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
     SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Laue" "', argument " "2"" of type '" "size_t""'");
   } 
   arg2 = static_cast< size_t >(val2);
-  result = MathFunctions::Laue(arg1,arg2);
-  resultobj = SWIG_From_std_complex_Sl_double_Sg_(static_cast< std::complex<double> >(result));
+  result = (double)MathFunctions::Laue(arg1,arg2);
+  resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
   return NULL;
@@ -54206,521 +46930,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_new_AdjustMinimizerStrategy__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  AdjustMinimizerStrategy *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)":new_AdjustMinimizerStrategy")) SWIG_fail;
-  result = (AdjustMinimizerStrategy *)new AdjustMinimizerStrategy();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_AdjustMinimizerStrategy, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_AdjustMinimizerStrategy__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::string *arg1 = 0 ;
-  std::string *arg2 = 0 ;
-  std::string *arg3 = 0 ;
-  int res1 = SWIG_OLDOBJ ;
-  int res2 = SWIG_OLDOBJ ;
-  int res3 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  AdjustMinimizerStrategy *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOO:new_AdjustMinimizerStrategy",&obj0,&obj1,&obj2)) SWIG_fail;
-  {
-    std::string *ptr = (std::string *)0;
-    res1 = SWIG_AsPtr_std_string(obj0, &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_AdjustMinimizerStrategy" "', argument " "1"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_AdjustMinimizerStrategy" "', argument " "1"" of type '" "std::string const &""'"); 
-    }
-    arg1 = ptr;
-  }
-  {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "new_AdjustMinimizerStrategy" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_AdjustMinimizerStrategy" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    arg2 = ptr;
-  }
-  {
-    std::string *ptr = (std::string *)0;
-    res3 = SWIG_AsPtr_std_string(obj2, &ptr);
-    if (!SWIG_IsOK(res3)) {
-      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "new_AdjustMinimizerStrategy" "', argument " "3"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_AdjustMinimizerStrategy" "', argument " "3"" of type '" "std::string const &""'"); 
-    }
-    arg3 = ptr;
-  }
-  result = (AdjustMinimizerStrategy *)new AdjustMinimizerStrategy((std::string const &)*arg1,(std::string const &)*arg2,(std::string const &)*arg3);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_AdjustMinimizerStrategy, SWIG_POINTER_NEW |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_AdjustMinimizerStrategy__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::string *arg1 = 0 ;
-  std::string *arg2 = 0 ;
-  int res1 = SWIG_OLDOBJ ;
-  int res2 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  AdjustMinimizerStrategy *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:new_AdjustMinimizerStrategy",&obj0,&obj1)) SWIG_fail;
-  {
-    std::string *ptr = (std::string *)0;
-    res1 = SWIG_AsPtr_std_string(obj0, &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_AdjustMinimizerStrategy" "', argument " "1"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_AdjustMinimizerStrategy" "', argument " "1"" of type '" "std::string const &""'"); 
-    }
-    arg1 = ptr;
-  }
-  {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "new_AdjustMinimizerStrategy" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_AdjustMinimizerStrategy" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    arg2 = ptr;
-  }
-  result = (AdjustMinimizerStrategy *)new AdjustMinimizerStrategy((std::string const &)*arg1,(std::string const &)*arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_AdjustMinimizerStrategy, SWIG_POINTER_NEW |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_AdjustMinimizerStrategy__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::string *arg1 = 0 ;
-  int res1 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  AdjustMinimizerStrategy *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:new_AdjustMinimizerStrategy",&obj0)) SWIG_fail;
-  {
-    std::string *ptr = (std::string *)0;
-    res1 = SWIG_AsPtr_std_string(obj0, &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_AdjustMinimizerStrategy" "', argument " "1"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_AdjustMinimizerStrategy" "', argument " "1"" of type '" "std::string const &""'"); 
-    }
-    arg1 = ptr;
-  }
-  result = (AdjustMinimizerStrategy *)new AdjustMinimizerStrategy((std::string const &)*arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_AdjustMinimizerStrategy, SWIG_POINTER_NEW |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_AdjustMinimizerStrategy(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[4] = {
-    0
-  };
-  Py_ssize_t ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 0) {
-    return _wrap_new_AdjustMinimizerStrategy__SWIG_0(self, args);
-  }
-  if (argc == 1) {
-    int _v;
-    int res = SWIG_AsPtr_std_string(argv[0], (std::string**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_new_AdjustMinimizerStrategy__SWIG_3(self, args);
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    int res = SWIG_AsPtr_std_string(argv[0], (std::string**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_AsPtr_std_string(argv[1], (std::string**)(0));
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        return _wrap_new_AdjustMinimizerStrategy__SWIG_2(self, args);
-      }
-    }
-  }
-  if (argc == 3) {
-    int _v;
-    int res = SWIG_AsPtr_std_string(argv[0], (std::string**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_AsPtr_std_string(argv[1], (std::string**)(0));
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        int res = SWIG_AsPtr_std_string(argv[2], (std::string**)(0));
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          return _wrap_new_AdjustMinimizerStrategy__SWIG_1(self, args);
-        }
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_AdjustMinimizerStrategy'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    AdjustMinimizerStrategy::AdjustMinimizerStrategy()\n"
-    "    AdjustMinimizerStrategy::AdjustMinimizerStrategy(std::string const &,std::string const &,std::string const &)\n"
-    "    AdjustMinimizerStrategy::AdjustMinimizerStrategy(std::string const &,std::string const &)\n"
-    "    AdjustMinimizerStrategy::AdjustMinimizerStrategy(std::string const &)\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_AdjustMinimizerStrategy_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  AdjustMinimizerStrategy *arg1 = (AdjustMinimizerStrategy *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  AdjustMinimizerStrategy *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:AdjustMinimizerStrategy_clone",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_AdjustMinimizerStrategy, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "AdjustMinimizerStrategy_clone" "', argument " "1"" of type '" "AdjustMinimizerStrategy const *""'"); 
-  }
-  arg1 = reinterpret_cast< AdjustMinimizerStrategy * >(argp1);
-  result = (AdjustMinimizerStrategy *)((AdjustMinimizerStrategy const *)arg1)->clone();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_AdjustMinimizerStrategy, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_AdjustMinimizerStrategy_setMinimizer__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  AdjustMinimizerStrategy *arg1 = (AdjustMinimizerStrategy *) 0 ;
-  std::string *arg2 = 0 ;
-  std::string *arg3 = 0 ;
-  std::string *arg4 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
-  int res3 = SWIG_OLDOBJ ;
-  int res4 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  PyObject * obj3 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOOO:AdjustMinimizerStrategy_setMinimizer",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_AdjustMinimizerStrategy, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "AdjustMinimizerStrategy_setMinimizer" "', argument " "1"" of type '" "AdjustMinimizerStrategy *""'"); 
-  }
-  arg1 = reinterpret_cast< AdjustMinimizerStrategy * >(argp1);
-  {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "AdjustMinimizerStrategy_setMinimizer" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "AdjustMinimizerStrategy_setMinimizer" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    arg2 = ptr;
-  }
-  {
-    std::string *ptr = (std::string *)0;
-    res3 = SWIG_AsPtr_std_string(obj2, &ptr);
-    if (!SWIG_IsOK(res3)) {
-      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "AdjustMinimizerStrategy_setMinimizer" "', argument " "3"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "AdjustMinimizerStrategy_setMinimizer" "', argument " "3"" of type '" "std::string const &""'"); 
-    }
-    arg3 = ptr;
-  }
-  {
-    std::string *ptr = (std::string *)0;
-    res4 = SWIG_AsPtr_std_string(obj3, &ptr);
-    if (!SWIG_IsOK(res4)) {
-      SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "AdjustMinimizerStrategy_setMinimizer" "', argument " "4"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "AdjustMinimizerStrategy_setMinimizer" "', argument " "4"" of type '" "std::string const &""'"); 
-    }
-    arg4 = ptr;
-  }
-  (arg1)->setMinimizer((std::string const &)*arg2,(std::string const &)*arg3,(std::string const &)*arg4);
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  if (SWIG_IsNewObj(res4)) delete arg4;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  if (SWIG_IsNewObj(res4)) delete arg4;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_AdjustMinimizerStrategy_setMinimizer__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  AdjustMinimizerStrategy *arg1 = (AdjustMinimizerStrategy *) 0 ;
-  std::string *arg2 = 0 ;
-  std::string *arg3 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
-  int res3 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOO:AdjustMinimizerStrategy_setMinimizer",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_AdjustMinimizerStrategy, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "AdjustMinimizerStrategy_setMinimizer" "', argument " "1"" of type '" "AdjustMinimizerStrategy *""'"); 
-  }
-  arg1 = reinterpret_cast< AdjustMinimizerStrategy * >(argp1);
-  {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "AdjustMinimizerStrategy_setMinimizer" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "AdjustMinimizerStrategy_setMinimizer" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    arg2 = ptr;
-  }
-  {
-    std::string *ptr = (std::string *)0;
-    res3 = SWIG_AsPtr_std_string(obj2, &ptr);
-    if (!SWIG_IsOK(res3)) {
-      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "AdjustMinimizerStrategy_setMinimizer" "', argument " "3"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "AdjustMinimizerStrategy_setMinimizer" "', argument " "3"" of type '" "std::string const &""'"); 
-    }
-    arg3 = ptr;
-  }
-  (arg1)->setMinimizer((std::string const &)*arg2,(std::string const &)*arg3);
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_AdjustMinimizerStrategy_setMinimizer__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  AdjustMinimizerStrategy *arg1 = (AdjustMinimizerStrategy *) 0 ;
-  std::string *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:AdjustMinimizerStrategy_setMinimizer",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_AdjustMinimizerStrategy, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "AdjustMinimizerStrategy_setMinimizer" "', argument " "1"" of type '" "AdjustMinimizerStrategy *""'"); 
-  }
-  arg1 = reinterpret_cast< AdjustMinimizerStrategy * >(argp1);
-  {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "AdjustMinimizerStrategy_setMinimizer" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "AdjustMinimizerStrategy_setMinimizer" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    arg2 = ptr;
-  }
-  (arg1)->setMinimizer((std::string const &)*arg2);
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_AdjustMinimizerStrategy_setMinimizer(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[5] = {
-    0
-  };
-  Py_ssize_t ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 2) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_AdjustMinimizerStrategy, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_AsPtr_std_string(argv[1], (std::string**)(0));
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        return _wrap_AdjustMinimizerStrategy_setMinimizer__SWIG_2(self, args);
-      }
-    }
-  }
-  if (argc == 3) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_AdjustMinimizerStrategy, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_AsPtr_std_string(argv[1], (std::string**)(0));
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        int res = SWIG_AsPtr_std_string(argv[2], (std::string**)(0));
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          return _wrap_AdjustMinimizerStrategy_setMinimizer__SWIG_1(self, args);
-        }
-      }
-    }
-  }
-  if (argc == 4) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_AdjustMinimizerStrategy, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_AsPtr_std_string(argv[1], (std::string**)(0));
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        int res = SWIG_AsPtr_std_string(argv[2], (std::string**)(0));
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          int res = SWIG_AsPtr_std_string(argv[3], (std::string**)(0));
-          _v = SWIG_CheckState(res);
-          if (_v) {
-            return _wrap_AdjustMinimizerStrategy_setMinimizer__SWIG_0(self, args);
-          }
-        }
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'AdjustMinimizerStrategy_setMinimizer'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    AdjustMinimizerStrategy::setMinimizer(std::string const &,std::string const &,std::string const &)\n"
-    "    AdjustMinimizerStrategy::setMinimizer(std::string const &,std::string const &)\n"
-    "    AdjustMinimizerStrategy::setMinimizer(std::string const &)\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_AdjustMinimizerStrategy_execute(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  AdjustMinimizerStrategy *arg1 = (AdjustMinimizerStrategy *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:AdjustMinimizerStrategy_execute",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_AdjustMinimizerStrategy, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "AdjustMinimizerStrategy_execute" "', argument " "1"" of type '" "AdjustMinimizerStrategy *""'"); 
-  }
-  arg1 = reinterpret_cast< AdjustMinimizerStrategy * >(argp1);
-  (arg1)->execute();
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_delete_AdjustMinimizerStrategy(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  AdjustMinimizerStrategy *arg1 = (AdjustMinimizerStrategy *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_AdjustMinimizerStrategy",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_AdjustMinimizerStrategy, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_AdjustMinimizerStrategy" "', argument " "1"" of type '" "AdjustMinimizerStrategy *""'"); 
-  }
-  arg1 = reinterpret_cast< AdjustMinimizerStrategy * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *AdjustMinimizerStrategy_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_AdjustMinimizerStrategy, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
 SWIGINTERN PyObject *_wrap_new_IMultiLayerBuilder(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   PyObject *arg1 = (PyObject *) 0 ;
@@ -55687,66 +47896,6 @@ fail:
 
 
 SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_11(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  INodeVisitor *arg1 = (INodeVisitor *) 0 ;
-  FitObject *arg2 = (FitObject *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:INodeVisitor_visit",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_INodeVisitor, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "INodeVisitor_visit" "', argument " "1"" of type '" "INodeVisitor *""'"); 
-  }
-  arg1 = reinterpret_cast< INodeVisitor * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_FitObject, 0 |  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "INodeVisitor_visit" "', argument " "2"" of type '" "FitObject const *""'"); 
-  }
-  arg2 = reinterpret_cast< FitObject * >(argp2);
-  (arg1)->visit((FitObject const *)arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_12(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  INodeVisitor *arg1 = (INodeVisitor *) 0 ;
-  FitSuiteObjects *arg2 = (FitSuiteObjects *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:INodeVisitor_visit",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_INodeVisitor, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "INodeVisitor_visit" "', argument " "1"" of type '" "INodeVisitor *""'"); 
-  }
-  arg1 = reinterpret_cast< INodeVisitor * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_FitSuiteObjects, 0 |  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "INodeVisitor_visit" "', argument " "2"" of type '" "FitSuiteObjects const *""'"); 
-  }
-  arg2 = reinterpret_cast< FitSuiteObjects * >(argp2);
-  (arg1)->visit((FitSuiteObjects const *)arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_13(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FootprintFactorGaussian *arg2 = (FootprintFactorGaussian *) 0 ;
@@ -55776,7 +47925,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_14(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_12(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FootprintFactorSquare *arg2 = (FootprintFactorSquare *) 0 ;
@@ -55806,7 +47955,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_15(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_13(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorAnisoPyramid *arg2 = (FormFactorAnisoPyramid *) 0 ;
@@ -55836,7 +47985,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_16(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_14(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorBox *arg2 = (FormFactorBox *) 0 ;
@@ -55866,7 +48015,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_17(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_15(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorCone *arg2 = (FormFactorCone *) 0 ;
@@ -55896,7 +48045,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_18(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_16(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorCone6 *arg2 = (FormFactorCone6 *) 0 ;
@@ -55926,7 +48075,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_19(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_17(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorCoreShell *arg2 = (FormFactorCoreShell *) 0 ;
@@ -55956,7 +48105,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_20(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_18(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorCrystal *arg2 = (FormFactorCrystal *) 0 ;
@@ -55986,7 +48135,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_21(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_19(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorCuboctahedron *arg2 = (FormFactorCuboctahedron *) 0 ;
@@ -56016,7 +48165,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_22(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_20(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorCylinder *arg2 = (FormFactorCylinder *) 0 ;
@@ -56046,7 +48195,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_23(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_21(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorDecoratorDebyeWaller *arg2 = (FormFactorDecoratorDebyeWaller *) 0 ;
@@ -56076,7 +48225,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_24(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_22(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorDecoratorMaterial *arg2 = (FormFactorDecoratorMaterial *) 0 ;
@@ -56106,7 +48255,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_25(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_23(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorDecoratorPositionFactor *arg2 = (FormFactorDecoratorPositionFactor *) 0 ;
@@ -56136,7 +48285,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_26(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_24(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorDecoratorRotation *arg2 = (FormFactorDecoratorRotation *) 0 ;
@@ -56166,7 +48315,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_27(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_25(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorDodecahedron *arg2 = (FormFactorDodecahedron *) 0 ;
@@ -56196,7 +48345,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_28(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_26(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorDWBA *arg2 = (FormFactorDWBA *) 0 ;
@@ -56226,7 +48375,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_29(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_27(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorDWBAPol *arg2 = (FormFactorDWBAPol *) 0 ;
@@ -56256,7 +48405,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_30(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_28(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorEllipsoidalCylinder *arg2 = (FormFactorEllipsoidalCylinder *) 0 ;
@@ -56286,7 +48435,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_31(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_29(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorFullSphere *arg2 = (FormFactorFullSphere *) 0 ;
@@ -56316,7 +48465,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_32(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_30(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorFullSpheroid *arg2 = (FormFactorFullSpheroid *) 0 ;
@@ -56346,7 +48495,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_33(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_31(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorGauss *arg2 = (FormFactorGauss *) 0 ;
@@ -56376,7 +48525,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_34(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_32(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorHemiEllipsoid *arg2 = (FormFactorHemiEllipsoid *) 0 ;
@@ -56406,7 +48555,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_35(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_33(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorIcosahedron *arg2 = (FormFactorIcosahedron *) 0 ;
@@ -56436,7 +48585,37 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_36(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_34(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  INodeVisitor *arg1 = (INodeVisitor *) 0 ;
+  FormFactorLongBox *arg2 = (FormFactorLongBox *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OO:INodeVisitor_visit",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_INodeVisitor, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "INodeVisitor_visit" "', argument " "1"" of type '" "INodeVisitor *""'"); 
+  }
+  arg1 = reinterpret_cast< INodeVisitor * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_FormFactorLongBox, 0 |  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "INodeVisitor_visit" "', argument " "2"" of type '" "FormFactorLongBox const *""'"); 
+  }
+  arg2 = reinterpret_cast< FormFactorLongBox * >(argp2);
+  (arg1)->visit((FormFactorLongBox const *)arg2);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_35(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorLongBoxGauss *arg2 = (FormFactorLongBoxGauss *) 0 ;
@@ -56466,7 +48645,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_37(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_36(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorLongBoxLorentz *arg2 = (FormFactorLongBoxLorentz *) 0 ;
@@ -56496,7 +48675,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_38(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_37(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorLorentz *arg2 = (FormFactorLorentz *) 0 ;
@@ -56526,7 +48705,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_39(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_38(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorPrism3 *arg2 = (FormFactorPrism3 *) 0 ;
@@ -56556,7 +48735,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_40(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_39(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorPrism6 *arg2 = (FormFactorPrism6 *) 0 ;
@@ -56586,7 +48765,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_41(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_40(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorPyramid *arg2 = (FormFactorPyramid *) 0 ;
@@ -56616,7 +48795,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_42(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_41(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorRipple1 *arg2 = (FormFactorRipple1 *) 0 ;
@@ -56646,7 +48825,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_43(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_42(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorRipple2 *arg2 = (FormFactorRipple2 *) 0 ;
@@ -56676,7 +48855,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_44(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_43(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorSphereGaussianRadius *arg2 = (FormFactorSphereGaussianRadius *) 0 ;
@@ -56706,7 +48885,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_45(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_44(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorSphereLogNormalRadius *arg2 = (FormFactorSphereLogNormalRadius *) 0 ;
@@ -56736,7 +48915,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_46(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_45(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorTetrahedron *arg2 = (FormFactorTetrahedron *) 0 ;
@@ -56766,7 +48945,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_47(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_46(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorDot *arg2 = (FormFactorDot *) 0 ;
@@ -56796,7 +48975,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_48(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_47(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorTruncatedCube *arg2 = (FormFactorTruncatedCube *) 0 ;
@@ -56826,7 +49005,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_49(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_48(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorTruncatedSphere *arg2 = (FormFactorTruncatedSphere *) 0 ;
@@ -56856,7 +49035,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_50(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_49(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorTruncatedSpheroid *arg2 = (FormFactorTruncatedSpheroid *) 0 ;
@@ -56886,7 +49065,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_51(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_50(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FormFactorWeighted *arg2 = (FormFactorWeighted *) 0 ;
@@ -56916,7 +49095,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_52(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_51(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FTDecayFunction1DCauchy *arg2 = (FTDecayFunction1DCauchy *) 0 ;
@@ -56946,7 +49125,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_53(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_52(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FTDecayFunction1DGauss *arg2 = (FTDecayFunction1DGauss *) 0 ;
@@ -56976,7 +49155,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_54(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_53(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FTDecayFunction1DTriangle *arg2 = (FTDecayFunction1DTriangle *) 0 ;
@@ -57006,7 +49185,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_55(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_54(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FTDecayFunction1DVoigt *arg2 = (FTDecayFunction1DVoigt *) 0 ;
@@ -57036,7 +49215,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_56(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_55(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FTDecayFunction2DCauchy *arg2 = (FTDecayFunction2DCauchy *) 0 ;
@@ -57066,7 +49245,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_57(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_56(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FTDecayFunction2DGauss *arg2 = (FTDecayFunction2DGauss *) 0 ;
@@ -57096,7 +49275,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_58(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_57(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FTDecayFunction2DVoigt *arg2 = (FTDecayFunction2DVoigt *) 0 ;
@@ -57126,7 +49305,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_59(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_58(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FTDistribution1DCauchy *arg2 = (FTDistribution1DCauchy *) 0 ;
@@ -57156,7 +49335,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_60(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_59(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FTDistribution1DCosine *arg2 = (FTDistribution1DCosine *) 0 ;
@@ -57186,7 +49365,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_61(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_60(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FTDistribution1DGate *arg2 = (FTDistribution1DGate *) 0 ;
@@ -57216,7 +49395,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_62(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_61(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FTDistribution1DGauss *arg2 = (FTDistribution1DGauss *) 0 ;
@@ -57246,7 +49425,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_63(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_62(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FTDistribution1DTriangle *arg2 = (FTDistribution1DTriangle *) 0 ;
@@ -57276,7 +49455,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_64(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_63(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FTDistribution1DVoigt *arg2 = (FTDistribution1DVoigt *) 0 ;
@@ -57306,7 +49485,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_65(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_64(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FTDistribution2DCauchy *arg2 = (FTDistribution2DCauchy *) 0 ;
@@ -57336,7 +49515,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_66(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_65(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FTDistribution2DCone *arg2 = (FTDistribution2DCone *) 0 ;
@@ -57366,7 +49545,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_67(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_66(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FTDistribution2DGate *arg2 = (FTDistribution2DGate *) 0 ;
@@ -57396,7 +49575,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_68(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_67(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FTDistribution2DGauss *arg2 = (FTDistribution2DGauss *) 0 ;
@@ -57426,7 +49605,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_69(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_68(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   FTDistribution2DVoigt *arg2 = (FTDistribution2DVoigt *) 0 ;
@@ -57456,7 +49635,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_70(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_69(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   GISASSimulation *arg2 = (GISASSimulation *) 0 ;
@@ -57486,7 +49665,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_71(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_70(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   HexagonalLattice *arg2 = (HexagonalLattice *) 0 ;
@@ -57516,7 +49695,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_72(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_71(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   IAbstractParticle *arg2 = (IAbstractParticle *) 0 ;
@@ -57546,7 +49725,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_73(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_72(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   IClusteredParticles *arg2 = (IClusteredParticles *) 0 ;
@@ -57576,7 +49755,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_74(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_73(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   IdentityRotation *arg2 = (IdentityRotation *) 0 ;
@@ -57606,7 +49785,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_75(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_74(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   IFormFactor *arg2 = (IFormFactor *) 0 ;
@@ -57636,7 +49815,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_76(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_75(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   IFormFactorBorn *arg2 = (IFormFactorBorn *) 0 ;
@@ -57666,7 +49845,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_77(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_76(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   IFormFactorDecorator *arg2 = (IFormFactorDecorator *) 0 ;
@@ -57696,7 +49875,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_78(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_77(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   IInterferenceFunction *arg2 = (IInterferenceFunction *) 0 ;
@@ -57726,7 +49905,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_79(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_78(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   ILayout *arg2 = (ILayout *) 0 ;
@@ -57756,7 +49935,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_80(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_79(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   INode *arg2 = (INode *) 0 ;
@@ -57786,7 +49965,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_81(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_80(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   Instrument *arg2 = (Instrument *) 0 ;
@@ -57816,7 +49995,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_82(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_81(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   IntensityNormalizer *arg2 = (IntensityNormalizer *) 0 ;
@@ -57846,7 +50025,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_83(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_82(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   IntensityScaleAndShiftNormalizer *arg2 = (IntensityScaleAndShiftNormalizer *) 0 ;
@@ -57876,7 +50055,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_84(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_83(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   InterferenceFunction1DLattice *arg2 = (InterferenceFunction1DLattice *) 0 ;
@@ -57906,7 +50085,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_85(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_84(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   InterferenceFunction2DLattice *arg2 = (InterferenceFunction2DLattice *) 0 ;
@@ -57936,10 +50115,10 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_86(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_85(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
-  InterferenceFunction3DLattice *arg2 = (InterferenceFunction3DLattice *) 0 ;
+  InterferenceFunction2DParaCrystal *arg2 = (InterferenceFunction2DParaCrystal *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
@@ -57953,12 +50132,12 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_86(PyObject *SWIGUNUSEDPARM(
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "INodeVisitor_visit" "', argument " "1"" of type '" "INodeVisitor *""'"); 
   }
   arg1 = reinterpret_cast< INodeVisitor * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_InterferenceFunction3DLattice, 0 |  0 );
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "INodeVisitor_visit" "', argument " "2"" of type '" "InterferenceFunction3DLattice const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "INodeVisitor_visit" "', argument " "2"" of type '" "InterferenceFunction2DParaCrystal const *""'"); 
   }
-  arg2 = reinterpret_cast< InterferenceFunction3DLattice * >(argp2);
-  (arg1)->visit((InterferenceFunction3DLattice const *)arg2);
+  arg2 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp2);
+  (arg1)->visit((InterferenceFunction2DParaCrystal const *)arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -57966,7 +50145,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_87(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_86(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
   InterferenceFunction2DSuperLattice *arg2 = (InterferenceFunction2DSuperLattice *) 0 ;
@@ -57996,6 +50175,36 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_87(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  INodeVisitor *arg1 = (INodeVisitor *) 0 ;
+  InterferenceFunction3DLattice *arg2 = (InterferenceFunction3DLattice *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OO:INodeVisitor_visit",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_INodeVisitor, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "INodeVisitor_visit" "', argument " "1"" of type '" "INodeVisitor *""'"); 
+  }
+  arg1 = reinterpret_cast< INodeVisitor * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_InterferenceFunction3DLattice, 0 |  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "INodeVisitor_visit" "', argument " "2"" of type '" "InterferenceFunction3DLattice const *""'"); 
+  }
+  arg2 = reinterpret_cast< InterferenceFunction3DLattice * >(argp2);
+  (arg1)->visit((InterferenceFunction3DLattice const *)arg2);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_88(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
@@ -58029,7 +50238,7 @@ fail:
 SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_89(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
-  InterferenceFunction2DParaCrystal *arg2 = (InterferenceFunction2DParaCrystal *) 0 ;
+  InterferenceFunctionFinite3DLattice *arg2 = (InterferenceFunctionFinite3DLattice *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
@@ -58043,12 +50252,12 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_89(PyObject *SWIGUNUSEDPARM(
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "INodeVisitor_visit" "', argument " "1"" of type '" "INodeVisitor *""'"); 
   }
   arg1 = reinterpret_cast< INodeVisitor * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_InterferenceFunctionFinite3DLattice, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "INodeVisitor_visit" "', argument " "2"" of type '" "InterferenceFunction2DParaCrystal const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "INodeVisitor_visit" "', argument " "2"" of type '" "InterferenceFunctionFinite3DLattice const *""'"); 
   }
-  arg2 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp2);
-  (arg1)->visit((InterferenceFunction2DParaCrystal const *)arg2);
+  arg2 = reinterpret_cast< InterferenceFunctionFinite3DLattice * >(argp2);
+  (arg1)->visit((InterferenceFunctionFinite3DLattice const *)arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -58059,7 +50268,7 @@ fail:
 SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_90(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
-  InterferenceFunctionNone *arg2 = (InterferenceFunctionNone *) 0 ;
+  InterferenceFunctionRadialParaCrystal *arg2 = (InterferenceFunctionRadialParaCrystal *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
@@ -58073,12 +50282,12 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_90(PyObject *SWIGUNUSEDPARM(
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "INodeVisitor_visit" "', argument " "1"" of type '" "INodeVisitor *""'"); 
   }
   arg1 = reinterpret_cast< INodeVisitor * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_InterferenceFunctionNone, 0 |  0 );
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "INodeVisitor_visit" "', argument " "2"" of type '" "InterferenceFunctionNone const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "INodeVisitor_visit" "', argument " "2"" of type '" "InterferenceFunctionRadialParaCrystal const *""'"); 
   }
-  arg2 = reinterpret_cast< InterferenceFunctionNone * >(argp2);
-  (arg1)->visit((InterferenceFunctionNone const *)arg2);
+  arg2 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp2);
+  (arg1)->visit((InterferenceFunctionRadialParaCrystal const *)arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -58089,7 +50298,7 @@ fail:
 SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_91(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
-  InterferenceFunctionRadialParaCrystal *arg2 = (InterferenceFunctionRadialParaCrystal *) 0 ;
+  InterferenceFunctionNone *arg2 = (InterferenceFunctionNone *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
@@ -58103,12 +50312,12 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_91(PyObject *SWIGUNUSEDPARM(
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "INodeVisitor_visit" "', argument " "1"" of type '" "INodeVisitor *""'"); 
   }
   arg1 = reinterpret_cast< INodeVisitor * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_InterferenceFunctionNone, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "INodeVisitor_visit" "', argument " "2"" of type '" "InterferenceFunctionRadialParaCrystal const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "INodeVisitor_visit" "', argument " "2"" of type '" "InterferenceFunctionNone const *""'"); 
   }
-  arg2 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp2);
-  (arg1)->visit((InterferenceFunctionRadialParaCrystal const *)arg2);
+  arg2 = reinterpret_cast< InterferenceFunctionNone * >(argp2);
+  (arg1)->visit((InterferenceFunctionNone const *)arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -59099,7 +51308,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FitObject, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FootprintFactorGaussian, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_11(self, args);
@@ -59113,7 +51322,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FitSuiteObjects, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FootprintFactorSquare, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_12(self, args);
@@ -59127,7 +51336,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FootprintFactorGaussian, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorAnisoPyramid, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_13(self, args);
@@ -59141,7 +51350,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FootprintFactorSquare, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorBox, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_14(self, args);
@@ -59155,7 +51364,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorAnisoPyramid, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorCone, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_15(self, args);
@@ -59169,7 +51378,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorBox, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorCone6, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_16(self, args);
@@ -59183,7 +51392,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorCone, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorCoreShell, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_17(self, args);
@@ -59197,7 +51406,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorCone6, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorCrystal, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_18(self, args);
@@ -59211,7 +51420,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorCoreShell, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorCuboctahedron, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_19(self, args);
@@ -59225,7 +51434,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorCrystal, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorCylinder, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_20(self, args);
@@ -59239,7 +51448,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorCuboctahedron, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorDecoratorDebyeWaller, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_21(self, args);
@@ -59253,7 +51462,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorCylinder, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorDecoratorMaterial, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_22(self, args);
@@ -59267,7 +51476,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorDecoratorDebyeWaller, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorDecoratorPositionFactor, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_23(self, args);
@@ -59281,7 +51490,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorDecoratorMaterial, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorDecoratorRotation, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_24(self, args);
@@ -59295,7 +51504,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorDecoratorPositionFactor, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorDodecahedron, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_25(self, args);
@@ -59309,7 +51518,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorDecoratorRotation, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorDWBA, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_26(self, args);
@@ -59323,7 +51532,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorDodecahedron, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorDWBAPol, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_27(self, args);
@@ -59337,7 +51546,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorDWBA, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorEllipsoidalCylinder, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_28(self, args);
@@ -59351,7 +51560,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorDWBAPol, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorFullSphere, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_29(self, args);
@@ -59365,7 +51574,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorEllipsoidalCylinder, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorFullSpheroid, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_30(self, args);
@@ -59379,7 +51588,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorFullSphere, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorGauss, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_31(self, args);
@@ -59393,7 +51602,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorFullSpheroid, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorHemiEllipsoid, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_32(self, args);
@@ -59407,7 +51616,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorGauss, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorIcosahedron, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_33(self, args);
@@ -59421,27 +51630,13 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorHemiEllipsoid, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorLongBox, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_34(self, args);
       }
     }
   }
-  if (argc == 2) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_INodeVisitor, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorIcosahedron, 0);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_35(self, args);
-      }
-    }
-  }
   if (argc == 2) {
     int _v;
     void *vptr = 0;
@@ -59452,7 +51647,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorLongBoxGauss, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_36(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_35(self, args);
       }
     }
   }
@@ -59466,7 +51661,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorLongBoxLorentz, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_37(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_36(self, args);
       }
     }
   }
@@ -59480,7 +51675,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorLorentz, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_38(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_37(self, args);
       }
     }
   }
@@ -59494,7 +51689,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorPrism3, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_39(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_38(self, args);
       }
     }
   }
@@ -59508,7 +51703,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorPrism6, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_40(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_39(self, args);
       }
     }
   }
@@ -59522,7 +51717,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorPyramid, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_41(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_40(self, args);
       }
     }
   }
@@ -59536,7 +51731,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorRipple1, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_42(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_41(self, args);
       }
     }
   }
@@ -59550,7 +51745,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorRipple2, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_43(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_42(self, args);
       }
     }
   }
@@ -59564,7 +51759,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorSphereGaussianRadius, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_44(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_43(self, args);
       }
     }
   }
@@ -59578,7 +51773,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorSphereLogNormalRadius, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_45(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_44(self, args);
       }
     }
   }
@@ -59592,7 +51787,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorTetrahedron, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_46(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_45(self, args);
       }
     }
   }
@@ -59606,7 +51801,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorDot, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_47(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_46(self, args);
       }
     }
   }
@@ -59620,7 +51815,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorTruncatedCube, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_48(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_47(self, args);
       }
     }
   }
@@ -59634,7 +51829,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorTruncatedSphere, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_49(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_48(self, args);
       }
     }
   }
@@ -59648,7 +51843,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorTruncatedSpheroid, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_50(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_49(self, args);
       }
     }
   }
@@ -59662,7 +51857,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FormFactorWeighted, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_51(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_50(self, args);
       }
     }
   }
@@ -59676,7 +51871,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FTDecayFunction1DCauchy, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_52(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_51(self, args);
       }
     }
   }
@@ -59690,7 +51885,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FTDecayFunction1DGauss, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_53(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_52(self, args);
       }
     }
   }
@@ -59704,7 +51899,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FTDecayFunction1DTriangle, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_54(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_53(self, args);
       }
     }
   }
@@ -59718,7 +51913,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FTDecayFunction1DVoigt, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_55(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_54(self, args);
       }
     }
   }
@@ -59732,7 +51927,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FTDecayFunction2DCauchy, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_56(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_55(self, args);
       }
     }
   }
@@ -59746,7 +51941,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FTDecayFunction2DGauss, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_57(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_56(self, args);
       }
     }
   }
@@ -59760,7 +51955,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FTDecayFunction2DVoigt, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_58(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_57(self, args);
       }
     }
   }
@@ -59774,7 +51969,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FTDistribution1DCauchy, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_59(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_58(self, args);
       }
     }
   }
@@ -59788,7 +51983,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FTDistribution1DCosine, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_60(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_59(self, args);
       }
     }
   }
@@ -59802,7 +51997,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FTDistribution1DGate, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_61(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_60(self, args);
       }
     }
   }
@@ -59816,7 +52011,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FTDistribution1DGauss, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_62(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_61(self, args);
       }
     }
   }
@@ -59830,7 +52025,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FTDistribution1DTriangle, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_63(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_62(self, args);
       }
     }
   }
@@ -59844,7 +52039,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FTDistribution1DVoigt, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_64(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_63(self, args);
       }
     }
   }
@@ -59858,7 +52053,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FTDistribution2DCauchy, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_65(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_64(self, args);
       }
     }
   }
@@ -59872,7 +52067,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FTDistribution2DCone, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_66(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_65(self, args);
       }
     }
   }
@@ -59886,7 +52081,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FTDistribution2DGate, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_67(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_66(self, args);
       }
     }
   }
@@ -59900,7 +52095,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FTDistribution2DGauss, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_68(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_67(self, args);
       }
     }
   }
@@ -59914,7 +52109,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_FTDistribution2DVoigt, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_69(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_68(self, args);
       }
     }
   }
@@ -59928,7 +52123,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_GISASSimulation, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_70(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_69(self, args);
       }
     }
   }
@@ -59942,7 +52137,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_HexagonalLattice, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_71(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_70(self, args);
       }
     }
   }
@@ -59970,7 +52165,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_IClusteredParticles, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_73(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_72(self, args);
       }
     }
   }
@@ -59984,7 +52179,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_IdentityRotation, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_74(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_73(self, args);
       }
     }
   }
@@ -59998,7 +52193,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_IFormFactorBorn, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_76(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_75(self, args);
       }
     }
   }
@@ -60012,7 +52207,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_IFormFactorDecorator, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_77(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_76(self, args);
       }
     }
   }
@@ -60026,7 +52221,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_IFormFactor, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_75(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_74(self, args);
       }
     }
   }
@@ -60040,7 +52235,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_InterferenceFunction1DLattice, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_84(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_83(self, args);
       }
     }
   }
@@ -60068,7 +52263,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_Instrument, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_81(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_80(self, args);
       }
     }
   }
@@ -60082,7 +52277,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_IntensityScaleAndShiftNormalizer, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_83(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_82(self, args);
       }
     }
   }
@@ -60096,7 +52291,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_IntensityNormalizer, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_82(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_81(self, args);
       }
     }
   }
@@ -60109,6 +52304,20 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       void *vptr = 0;
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_InterferenceFunction2DLattice, 0);
       _v = SWIG_CheckState(res);
+      if (_v) {
+        return _wrap_INodeVisitor_visit__SWIG_84(self, args);
+      }
+    }
+  }
+  if (argc == 2) {
+    int _v;
+    void *vptr = 0;
+    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_INodeVisitor, 0);
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      void *vptr = 0;
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0);
+      _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_85(self, args);
       }
@@ -60121,7 +52330,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_InterferenceFunction3DLattice, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_InterferenceFunction2DSuperLattice, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_86(self, args);
@@ -60135,7 +52344,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_InterferenceFunction2DSuperLattice, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_InterferenceFunction3DLattice, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_87(self, args);
@@ -60163,7 +52372,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_InterferenceFunctionFinite3DLattice, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_89(self, args);
@@ -60177,7 +52386,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_InterferenceFunctionNone, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_90(self, args);
@@ -60191,7 +52400,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
     _v = SWIG_CheckState(res);
     if (_v) {
       void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_InterferenceFunctionNone, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_91(self, args);
@@ -60208,7 +52417,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_IInterferenceFunction, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_78(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_77(self, args);
       }
     }
   }
@@ -60404,7 +52613,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_IAbstractParticle, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_72(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_71(self, args);
       }
     }
   }
@@ -60418,7 +52627,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_ILayout, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_79(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_78(self, args);
       }
     }
   }
@@ -60600,7 +52809,7 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit(PyObject *self, PyObject *args) {
       int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_INode, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_INodeVisitor_visit__SWIG_80(self, args);
+        return _wrap_INodeVisitor_visit__SWIG_79(self, args);
       }
     }
   }
@@ -60619,8 +52828,6 @@ fail:
     "    INodeVisitor::visit(DistributionLogNormal const *)\n"
     "    INodeVisitor::visit(DistributionLorentz const *)\n"
     "    INodeVisitor::visit(DistributionTrapezoid const *)\n"
-    "    INodeVisitor::visit(FitObject const *)\n"
-    "    INodeVisitor::visit(FitSuiteObjects const *)\n"
     "    INodeVisitor::visit(FootprintFactorGaussian const *)\n"
     "    INodeVisitor::visit(FootprintFactorSquare const *)\n"
     "    INodeVisitor::visit(FormFactorAnisoPyramid const *)\n"
@@ -60644,6 +52851,7 @@ fail:
     "    INodeVisitor::visit(FormFactorGauss const *)\n"
     "    INodeVisitor::visit(FormFactorHemiEllipsoid const *)\n"
     "    INodeVisitor::visit(FormFactorIcosahedron const *)\n"
+    "    INodeVisitor::visit(FormFactorLongBox const *)\n"
     "    INodeVisitor::visit(FormFactorLongBoxGauss const *)\n"
     "    INodeVisitor::visit(FormFactorLongBoxLorentz const *)\n"
     "    INodeVisitor::visit(FormFactorLorentz const *)\n"
@@ -60694,12 +52902,13 @@ fail:
     "    INodeVisitor::visit(IntensityScaleAndShiftNormalizer const *)\n"
     "    INodeVisitor::visit(InterferenceFunction1DLattice const *)\n"
     "    INodeVisitor::visit(InterferenceFunction2DLattice const *)\n"
-    "    INodeVisitor::visit(InterferenceFunction3DLattice const *)\n"
+    "    INodeVisitor::visit(InterferenceFunction2DParaCrystal const *)\n"
     "    INodeVisitor::visit(InterferenceFunction2DSuperLattice const *)\n"
+    "    INodeVisitor::visit(InterferenceFunction3DLattice const *)\n"
     "    INodeVisitor::visit(InterferenceFunctionFinite2DLattice const *)\n"
-    "    INodeVisitor::visit(InterferenceFunction2DParaCrystal const *)\n"
-    "    INodeVisitor::visit(InterferenceFunctionNone const *)\n"
+    "    INodeVisitor::visit(InterferenceFunctionFinite3DLattice const *)\n"
     "    INodeVisitor::visit(InterferenceFunctionRadialParaCrystal const *)\n"
+    "    INodeVisitor::visit(InterferenceFunctionNone const *)\n"
     "    INodeVisitor::visit(IParticle const *)\n"
     "    INodeVisitor::visit(IPeakShape const *)\n"
     "    INodeVisitor::visit(IRotation const *)\n"
@@ -78971,6 +71180,253 @@ SWIGINTERN PyObject *FormFactorIcosahedron_swigregister(PyObject *SWIGUNUSEDPARM
   return SWIG_Py_Void();
 }
 
+SWIGINTERN PyObject *_wrap_new_FormFactorLongBox(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  double arg1 ;
+  double arg2 ;
+  double arg3 ;
+  double val1 ;
+  int ecode1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  double val3 ;
+  int ecode3 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  FormFactorLongBox *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOO:new_FormFactorLongBox",&obj0,&obj1,&obj2)) SWIG_fail;
+  ecode1 = SWIG_AsVal_double(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_FormFactorLongBox" "', argument " "1"" of type '" "double""'");
+  } 
+  arg1 = static_cast< double >(val1);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_FormFactorLongBox" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  ecode3 = SWIG_AsVal_double(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_FormFactorLongBox" "', argument " "3"" of type '" "double""'");
+  } 
+  arg3 = static_cast< double >(val3);
+  result = (FormFactorLongBox *)new FormFactorLongBox(arg1,arg2,arg3);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FormFactorLongBox, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_FormFactorLongBox_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  FormFactorLongBox *arg1 = (FormFactorLongBox *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  FormFactorLongBox *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:FormFactorLongBox_clone",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FormFactorLongBox, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FormFactorLongBox_clone" "', argument " "1"" of type '" "FormFactorLongBox const *""'"); 
+  }
+  arg1 = reinterpret_cast< FormFactorLongBox * >(argp1);
+  result = (FormFactorLongBox *)((FormFactorLongBox const *)arg1)->clone();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_FormFactorLongBox, 0 |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_FormFactorLongBox_accept(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  FormFactorLongBox *arg1 = (FormFactorLongBox *) 0 ;
+  INodeVisitor *arg2 = (INodeVisitor *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OO:FormFactorLongBox_accept",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FormFactorLongBox, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FormFactorLongBox_accept" "', argument " "1"" of type '" "FormFactorLongBox const *""'"); 
+  }
+  arg1 = reinterpret_cast< FormFactorLongBox * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_INodeVisitor, 0 |  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FormFactorLongBox_accept" "', argument " "2"" of type '" "INodeVisitor *""'"); 
+  }
+  arg2 = reinterpret_cast< INodeVisitor * >(argp2);
+  ((FormFactorLongBox const *)arg1)->accept(arg2);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_FormFactorLongBox_getLength(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  FormFactorLongBox *arg1 = (FormFactorLongBox *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  double result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:FormFactorLongBox_getLength",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FormFactorLongBox, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FormFactorLongBox_getLength" "', argument " "1"" of type '" "FormFactorLongBox const *""'"); 
+  }
+  arg1 = reinterpret_cast< FormFactorLongBox * >(argp1);
+  result = (double)((FormFactorLongBox const *)arg1)->getLength();
+  resultobj = SWIG_From_double(static_cast< double >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_FormFactorLongBox_getHeight(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  FormFactorLongBox *arg1 = (FormFactorLongBox *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  double result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:FormFactorLongBox_getHeight",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FormFactorLongBox, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FormFactorLongBox_getHeight" "', argument " "1"" of type '" "FormFactorLongBox const *""'"); 
+  }
+  arg1 = reinterpret_cast< FormFactorLongBox * >(argp1);
+  result = (double)((FormFactorLongBox const *)arg1)->getHeight();
+  resultobj = SWIG_From_double(static_cast< double >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_FormFactorLongBox_getWidth(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  FormFactorLongBox *arg1 = (FormFactorLongBox *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  double result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:FormFactorLongBox_getWidth",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FormFactorLongBox, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FormFactorLongBox_getWidth" "', argument " "1"" of type '" "FormFactorLongBox const *""'"); 
+  }
+  arg1 = reinterpret_cast< FormFactorLongBox * >(argp1);
+  result = (double)((FormFactorLongBox const *)arg1)->getWidth();
+  resultobj = SWIG_From_double(static_cast< double >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_FormFactorLongBox_radialExtension(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  FormFactorLongBox *arg1 = (FormFactorLongBox *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  double result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:FormFactorLongBox_radialExtension",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FormFactorLongBox, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FormFactorLongBox_radialExtension" "', argument " "1"" of type '" "FormFactorLongBox const *""'"); 
+  }
+  arg1 = reinterpret_cast< FormFactorLongBox * >(argp1);
+  result = (double)((FormFactorLongBox const *)arg1)->radialExtension();
+  resultobj = SWIG_From_double(static_cast< double >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_FormFactorLongBox_evaluate_for_q(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  FormFactorLongBox *arg1 = (FormFactorLongBox *) 0 ;
+  cvector_t arg2 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 ;
+  int res2 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  complex_t result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OO:FormFactorLongBox_evaluate_for_q",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FormFactorLongBox, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FormFactorLongBox_evaluate_for_q" "', argument " "1"" of type '" "FormFactorLongBox const *""'"); 
+  }
+  arg1 = reinterpret_cast< FormFactorLongBox * >(argp1);
+  {
+    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_BasicVector3DT_std__complexT_double_t_t,  0  | 0);
+    if (!SWIG_IsOK(res2)) {
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "FormFactorLongBox_evaluate_for_q" "', argument " "2"" of type '" "cvector_t""'"); 
+    }  
+    if (!argp2) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FormFactorLongBox_evaluate_for_q" "', argument " "2"" of type '" "cvector_t""'");
+    } else {
+      cvector_t * temp = reinterpret_cast< cvector_t * >(argp2);
+      arg2 = *temp;
+      if (SWIG_IsNewObj(res2)) delete temp;
+    }
+  }
+  result = ((FormFactorLongBox const *)arg1)->evaluate_for_q(arg2);
+  resultobj = SWIG_From_std_complex_Sl_double_Sg_(static_cast< std::complex<double> >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_delete_FormFactorLongBox(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  FormFactorLongBox *arg1 = (FormFactorLongBox *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:delete_FormFactorLongBox",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_FormFactorLongBox, SWIG_POINTER_DISOWN |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_FormFactorLongBox" "', argument " "1"" of type '" "FormFactorLongBox *""'"); 
+  }
+  arg1 = reinterpret_cast< FormFactorLongBox * >(argp1);
+  delete arg1;
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *FormFactorLongBox_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *obj;
+  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_FormFactorLongBox, SWIG_NewClientData(obj));
+  return SWIG_Py_Void();
+}
+
 SWIGINTERN PyObject *_wrap_new_FormFactorLongBoxGauss(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   double arg1 ;
@@ -94708,15 +87164,19 @@ SWIGINTERN PyObject *_wrap_IPeakShape_evaluate(PyObject *SWIGUNUSEDPARM(self), P
   PyObject *resultobj = 0;
   IPeakShape *arg1 = (IPeakShape *) 0 ;
   kvector_t arg2 ;
+  kvector_t arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 ;
   int res2 = 0 ;
+  void *argp3 ;
+  int res3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:IPeakShape_evaluate",&obj0,&obj1)) SWIG_fail;
+  if (!PyArg_ParseTuple(args,(char *)"OOO:IPeakShape_evaluate",&obj0,&obj1,&obj2)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IPeakShape, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IPeakShape_evaluate" "', argument " "1"" of type '" "IPeakShape const *""'"); 
@@ -94735,7 +87195,20 @@ SWIGINTERN PyObject *_wrap_IPeakShape_evaluate(PyObject *SWIGUNUSEDPARM(self), P
       if (SWIG_IsNewObj(res2)) delete temp;
     }
   }
-  result = (double)((IPeakShape const *)arg1)->evaluate(arg2);
+  {
+    res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_BasicVector3DT_double_t,  0  | 0);
+    if (!SWIG_IsOK(res3)) {
+      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "IPeakShape_evaluate" "', argument " "3"" of type '" "kvector_t const""'"); 
+    }  
+    if (!argp3) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IPeakShape_evaluate" "', argument " "3"" of type '" "kvector_t const""'");
+    } else {
+      kvector_t * temp = reinterpret_cast< kvector_t * >(argp3);
+      arg3 = *temp;
+      if (SWIG_IsNewObj(res3)) delete temp;
+    }
+  }
+  result = (double)((IPeakShape const *)arg1)->evaluate(arg2,arg3);
   resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
@@ -94743,22 +87216,22 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_IPeakShape_thickness_z(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_IPeakShape_angularDisorder(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   IPeakShape *arg1 = (IPeakShape *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  double result;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:IPeakShape_thickness_z",&obj0)) SWIG_fail;
+  if (!PyArg_ParseTuple(args,(char *)"O:IPeakShape_angularDisorder",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IPeakShape, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IPeakShape_thickness_z" "', argument " "1"" of type '" "IPeakShape const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IPeakShape_angularDisorder" "', argument " "1"" of type '" "IPeakShape const *""'"); 
   }
   arg1 = reinterpret_cast< IPeakShape * >(argp1);
-  result = (double)((IPeakShape const *)arg1)->thickness_z();
-  resultobj = SWIG_From_double(static_cast< double >(result));
+  result = (bool)((IPeakShape const *)arg1)->angularDisorder();
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
@@ -94772,41 +87245,50 @@ SWIGINTERN PyObject *IPeakShape_swigregister(PyObject *SWIGUNUSEDPARM(self), PyO
   return SWIG_Py_Void();
 }
 
-SWIGINTERN PyObject *_wrap_new_GaussPeakShape(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_IsotropicGaussPeakShape(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   double arg1 ;
+  double arg2 ;
   double val1 ;
   int ecode1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  GaussPeakShape *result = 0 ;
+  PyObject * obj1 = 0 ;
+  IsotropicGaussPeakShape *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:new_GaussPeakShape",&obj0)) SWIG_fail;
+  if (!PyArg_ParseTuple(args,(char *)"OO:new_IsotropicGaussPeakShape",&obj0,&obj1)) SWIG_fail;
   ecode1 = SWIG_AsVal_double(obj0, &val1);
   if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_GaussPeakShape" "', argument " "1"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_IsotropicGaussPeakShape" "', argument " "1"" of type '" "double""'");
   } 
   arg1 = static_cast< double >(val1);
-  result = (GaussPeakShape *)new GaussPeakShape(arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_GaussPeakShape, SWIG_POINTER_NEW |  0 );
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_IsotropicGaussPeakShape" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  result = (IsotropicGaussPeakShape *)new IsotropicGaussPeakShape(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IsotropicGaussPeakShape, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_delete_GaussPeakShape(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_delete_IsotropicGaussPeakShape(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  GaussPeakShape *arg1 = (GaussPeakShape *) 0 ;
+  IsotropicGaussPeakShape *arg1 = (IsotropicGaussPeakShape *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_GaussPeakShape",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_GaussPeakShape, SWIG_POINTER_DISOWN |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:delete_IsotropicGaussPeakShape",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IsotropicGaussPeakShape, SWIG_POINTER_DISOWN |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_GaussPeakShape" "', argument " "1"" of type '" "GaussPeakShape *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IsotropicGaussPeakShape" "', argument " "1"" of type '" "IsotropicGaussPeakShape *""'"); 
   }
-  arg1 = reinterpret_cast< GaussPeakShape * >(argp1);
+  arg1 = reinterpret_cast< IsotropicGaussPeakShape * >(argp1);
   delete arg1;
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -94815,31 +87297,31 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_GaussPeakShape_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_IsotropicGaussPeakShape_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  GaussPeakShape *arg1 = (GaussPeakShape *) 0 ;
+  IsotropicGaussPeakShape *arg1 = (IsotropicGaussPeakShape *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  GaussPeakShape *result = 0 ;
+  IsotropicGaussPeakShape *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:GaussPeakShape_clone",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_GaussPeakShape, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:IsotropicGaussPeakShape_clone",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IsotropicGaussPeakShape, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GaussPeakShape_clone" "', argument " "1"" of type '" "GaussPeakShape const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IsotropicGaussPeakShape_clone" "', argument " "1"" of type '" "IsotropicGaussPeakShape const *""'"); 
   }
-  arg1 = reinterpret_cast< GaussPeakShape * >(argp1);
-  result = (GaussPeakShape *)((GaussPeakShape const *)arg1)->clone();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_GaussPeakShape, 0 |  0 );
+  arg1 = reinterpret_cast< IsotropicGaussPeakShape * >(argp1);
+  result = (IsotropicGaussPeakShape *)((IsotropicGaussPeakShape const *)arg1)->clone();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IsotropicGaussPeakShape, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GaussPeakShape_accept(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_IsotropicGaussPeakShape_accept(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  GaussPeakShape *arg1 = (GaussPeakShape *) 0 ;
+  IsotropicGaussPeakShape *arg1 = (IsotropicGaussPeakShape *) 0 ;
   INodeVisitor *arg2 = (INodeVisitor *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
@@ -94848,18 +87330,18 @@ SWIGINTERN PyObject *_wrap_GaussPeakShape_accept(PyObject *SWIGUNUSEDPARM(self),
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:GaussPeakShape_accept",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_GaussPeakShape, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:IsotropicGaussPeakShape_accept",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IsotropicGaussPeakShape, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GaussPeakShape_accept" "', argument " "1"" of type '" "GaussPeakShape const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IsotropicGaussPeakShape_accept" "', argument " "1"" of type '" "IsotropicGaussPeakShape const *""'"); 
   }
-  arg1 = reinterpret_cast< GaussPeakShape * >(argp1);
+  arg1 = reinterpret_cast< IsotropicGaussPeakShape * >(argp1);
   res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_INodeVisitor, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "GaussPeakShape_accept" "', argument " "2"" of type '" "INodeVisitor *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IsotropicGaussPeakShape_accept" "', argument " "2"" of type '" "INodeVisitor *""'"); 
   }
   arg2 = reinterpret_cast< INodeVisitor * >(argp2);
-  ((GaussPeakShape const *)arg1)->accept(arg2);
+  ((IsotropicGaussPeakShape const *)arg1)->accept(arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -94867,38 +87349,55 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_GaussPeakShape_evaluate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_IsotropicGaussPeakShape_evaluate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  GaussPeakShape *arg1 = (GaussPeakShape *) 0 ;
+  IsotropicGaussPeakShape *arg1 = (IsotropicGaussPeakShape *) 0 ;
   kvector_t arg2 ;
+  kvector_t arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 ;
   int res2 = 0 ;
+  void *argp3 ;
+  int res3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:GaussPeakShape_evaluate",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_GaussPeakShape, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:IsotropicGaussPeakShape_evaluate",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IsotropicGaussPeakShape, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GaussPeakShape_evaluate" "', argument " "1"" of type '" "GaussPeakShape const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IsotropicGaussPeakShape_evaluate" "', argument " "1"" of type '" "IsotropicGaussPeakShape const *""'"); 
   }
-  arg1 = reinterpret_cast< GaussPeakShape * >(argp1);
+  arg1 = reinterpret_cast< IsotropicGaussPeakShape * >(argp1);
   {
     res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_BasicVector3DT_double_t,  0  | 0);
     if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "GaussPeakShape_evaluate" "', argument " "2"" of type '" "kvector_t const""'"); 
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IsotropicGaussPeakShape_evaluate" "', argument " "2"" of type '" "kvector_t const""'"); 
     }  
     if (!argp2) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "GaussPeakShape_evaluate" "', argument " "2"" of type '" "kvector_t const""'");
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IsotropicGaussPeakShape_evaluate" "', argument " "2"" of type '" "kvector_t const""'");
     } else {
       kvector_t * temp = reinterpret_cast< kvector_t * >(argp2);
       arg2 = *temp;
       if (SWIG_IsNewObj(res2)) delete temp;
     }
   }
-  result = (double)((GaussPeakShape const *)arg1)->evaluate(arg2);
+  {
+    res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_BasicVector3DT_double_t,  0  | 0);
+    if (!SWIG_IsOK(res3)) {
+      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "IsotropicGaussPeakShape_evaluate" "', argument " "3"" of type '" "kvector_t const""'"); 
+    }  
+    if (!argp3) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IsotropicGaussPeakShape_evaluate" "', argument " "3"" of type '" "kvector_t const""'");
+    } else {
+      kvector_t * temp = reinterpret_cast< kvector_t * >(argp3);
+      arg3 = *temp;
+      if (SWIG_IsNewObj(res3)) delete temp;
+    }
+  }
+  result = (double)((IsotropicGaussPeakShape const *)arg1)->evaluate(arg2,arg3);
   resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
@@ -94906,21 +87405,166 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_GaussPeakShape_thickness_z(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *IsotropicGaussPeakShape_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *obj;
+  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_IsotropicGaussPeakShape, SWIG_NewClientData(obj));
+  return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *_wrap_new_IsotropicLorentzPeakShape(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  double arg1 ;
+  double arg2 ;
+  double val1 ;
+  int ecode1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  IsotropicLorentzPeakShape *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OO:new_IsotropicLorentzPeakShape",&obj0,&obj1)) SWIG_fail;
+  ecode1 = SWIG_AsVal_double(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_IsotropicLorentzPeakShape" "', argument " "1"" of type '" "double""'");
+  } 
+  arg1 = static_cast< double >(val1);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_IsotropicLorentzPeakShape" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  result = (IsotropicLorentzPeakShape *)new IsotropicLorentzPeakShape(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IsotropicLorentzPeakShape, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_delete_IsotropicLorentzPeakShape(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IsotropicLorentzPeakShape *arg1 = (IsotropicLorentzPeakShape *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:delete_IsotropicLorentzPeakShape",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IsotropicLorentzPeakShape, SWIG_POINTER_DISOWN |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IsotropicLorentzPeakShape" "', argument " "1"" of type '" "IsotropicLorentzPeakShape *""'"); 
+  }
+  arg1 = reinterpret_cast< IsotropicLorentzPeakShape * >(argp1);
+  delete arg1;
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_IsotropicLorentzPeakShape_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IsotropicLorentzPeakShape *arg1 = (IsotropicLorentzPeakShape *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  IsotropicLorentzPeakShape *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:IsotropicLorentzPeakShape_clone",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IsotropicLorentzPeakShape, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IsotropicLorentzPeakShape_clone" "', argument " "1"" of type '" "IsotropicLorentzPeakShape const *""'"); 
+  }
+  arg1 = reinterpret_cast< IsotropicLorentzPeakShape * >(argp1);
+  result = (IsotropicLorentzPeakShape *)((IsotropicLorentzPeakShape const *)arg1)->clone();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IsotropicLorentzPeakShape, 0 |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_IsotropicLorentzPeakShape_accept(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  GaussPeakShape *arg1 = (GaussPeakShape *) 0 ;
+  IsotropicLorentzPeakShape *arg1 = (IsotropicLorentzPeakShape *) 0 ;
+  INodeVisitor *arg2 = (INodeVisitor *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OO:IsotropicLorentzPeakShape_accept",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IsotropicLorentzPeakShape, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IsotropicLorentzPeakShape_accept" "', argument " "1"" of type '" "IsotropicLorentzPeakShape const *""'"); 
+  }
+  arg1 = reinterpret_cast< IsotropicLorentzPeakShape * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_INodeVisitor, 0 |  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IsotropicLorentzPeakShape_accept" "', argument " "2"" of type '" "INodeVisitor *""'"); 
+  }
+  arg2 = reinterpret_cast< INodeVisitor * >(argp2);
+  ((IsotropicLorentzPeakShape const *)arg1)->accept(arg2);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_IsotropicLorentzPeakShape_evaluate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IsotropicLorentzPeakShape *arg1 = (IsotropicLorentzPeakShape *) 0 ;
+  kvector_t arg2 ;
+  kvector_t arg3 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 ;
+  int res2 = 0 ;
+  void *argp3 ;
+  int res3 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:GaussPeakShape_thickness_z",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_GaussPeakShape, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:IsotropicLorentzPeakShape_evaluate",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_IsotropicLorentzPeakShape, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GaussPeakShape_thickness_z" "', argument " "1"" of type '" "GaussPeakShape const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IsotropicLorentzPeakShape_evaluate" "', argument " "1"" of type '" "IsotropicLorentzPeakShape const *""'"); 
+  }
+  arg1 = reinterpret_cast< IsotropicLorentzPeakShape * >(argp1);
+  {
+    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_BasicVector3DT_double_t,  0  | 0);
+    if (!SWIG_IsOK(res2)) {
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IsotropicLorentzPeakShape_evaluate" "', argument " "2"" of type '" "kvector_t const""'"); 
+    }  
+    if (!argp2) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IsotropicLorentzPeakShape_evaluate" "', argument " "2"" of type '" "kvector_t const""'");
+    } else {
+      kvector_t * temp = reinterpret_cast< kvector_t * >(argp2);
+      arg2 = *temp;
+      if (SWIG_IsNewObj(res2)) delete temp;
+    }
   }
-  arg1 = reinterpret_cast< GaussPeakShape * >(argp1);
-  result = (double)((GaussPeakShape const *)arg1)->thickness_z();
+  {
+    res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_BasicVector3DT_double_t,  0  | 0);
+    if (!SWIG_IsOK(res3)) {
+      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "IsotropicLorentzPeakShape_evaluate" "', argument " "3"" of type '" "kvector_t const""'"); 
+    }  
+    if (!argp3) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IsotropicLorentzPeakShape_evaluate" "', argument " "3"" of type '" "kvector_t const""'");
+    } else {
+      kvector_t * temp = reinterpret_cast< kvector_t * >(argp3);
+      arg3 = *temp;
+      if (SWIG_IsNewObj(res3)) delete temp;
+    }
+  }
+  result = (double)((IsotropicLorentzPeakShape const *)arg1)->evaluate(arg2,arg3);
   resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
@@ -94928,10 +87572,406 @@ fail:
 }
 
 
-SWIGINTERN PyObject *GaussPeakShape_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *IsotropicLorentzPeakShape_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *obj;
+  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_IsotropicLorentzPeakShape, SWIG_NewClientData(obj));
+  return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *_wrap_new_GaussFisherPeakShape(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  double arg1 ;
+  double arg2 ;
+  double arg3 ;
+  double val1 ;
+  int ecode1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  double val3 ;
+  int ecode3 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  GaussFisherPeakShape *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOO:new_GaussFisherPeakShape",&obj0,&obj1,&obj2)) SWIG_fail;
+  ecode1 = SWIG_AsVal_double(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_GaussFisherPeakShape" "', argument " "1"" of type '" "double""'");
+  } 
+  arg1 = static_cast< double >(val1);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_GaussFisherPeakShape" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  ecode3 = SWIG_AsVal_double(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_GaussFisherPeakShape" "', argument " "3"" of type '" "double""'");
+  } 
+  arg3 = static_cast< double >(val3);
+  result = (GaussFisherPeakShape *)new GaussFisherPeakShape(arg1,arg2,arg3);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_GaussFisherPeakShape, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_delete_GaussFisherPeakShape(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  GaussFisherPeakShape *arg1 = (GaussFisherPeakShape *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:delete_GaussFisherPeakShape",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_GaussFisherPeakShape, SWIG_POINTER_DISOWN |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_GaussFisherPeakShape" "', argument " "1"" of type '" "GaussFisherPeakShape *""'"); 
+  }
+  arg1 = reinterpret_cast< GaussFisherPeakShape * >(argp1);
+  delete arg1;
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_GaussFisherPeakShape_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  GaussFisherPeakShape *arg1 = (GaussFisherPeakShape *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  GaussFisherPeakShape *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:GaussFisherPeakShape_clone",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_GaussFisherPeakShape, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GaussFisherPeakShape_clone" "', argument " "1"" of type '" "GaussFisherPeakShape const *""'"); 
+  }
+  arg1 = reinterpret_cast< GaussFisherPeakShape * >(argp1);
+  result = (GaussFisherPeakShape *)((GaussFisherPeakShape const *)arg1)->clone();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_GaussFisherPeakShape, 0 |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_GaussFisherPeakShape_accept(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  GaussFisherPeakShape *arg1 = (GaussFisherPeakShape *) 0 ;
+  INodeVisitor *arg2 = (INodeVisitor *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OO:GaussFisherPeakShape_accept",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_GaussFisherPeakShape, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GaussFisherPeakShape_accept" "', argument " "1"" of type '" "GaussFisherPeakShape const *""'"); 
+  }
+  arg1 = reinterpret_cast< GaussFisherPeakShape * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_INodeVisitor, 0 |  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "GaussFisherPeakShape_accept" "', argument " "2"" of type '" "INodeVisitor *""'"); 
+  }
+  arg2 = reinterpret_cast< INodeVisitor * >(argp2);
+  ((GaussFisherPeakShape const *)arg1)->accept(arg2);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_GaussFisherPeakShape_evaluate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  GaussFisherPeakShape *arg1 = (GaussFisherPeakShape *) 0 ;
+  kvector_t arg2 ;
+  kvector_t arg3 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 ;
+  int res2 = 0 ;
+  void *argp3 ;
+  int res3 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  double result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOO:GaussFisherPeakShape_evaluate",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_GaussFisherPeakShape, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GaussFisherPeakShape_evaluate" "', argument " "1"" of type '" "GaussFisherPeakShape const *""'"); 
+  }
+  arg1 = reinterpret_cast< GaussFisherPeakShape * >(argp1);
+  {
+    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_BasicVector3DT_double_t,  0  | 0);
+    if (!SWIG_IsOK(res2)) {
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "GaussFisherPeakShape_evaluate" "', argument " "2"" of type '" "kvector_t const""'"); 
+    }  
+    if (!argp2) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "GaussFisherPeakShape_evaluate" "', argument " "2"" of type '" "kvector_t const""'");
+    } else {
+      kvector_t * temp = reinterpret_cast< kvector_t * >(argp2);
+      arg2 = *temp;
+      if (SWIG_IsNewObj(res2)) delete temp;
+    }
+  }
+  {
+    res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_BasicVector3DT_double_t,  0  | 0);
+    if (!SWIG_IsOK(res3)) {
+      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "GaussFisherPeakShape_evaluate" "', argument " "3"" of type '" "kvector_t const""'"); 
+    }  
+    if (!argp3) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "GaussFisherPeakShape_evaluate" "', argument " "3"" of type '" "kvector_t const""'");
+    } else {
+      kvector_t * temp = reinterpret_cast< kvector_t * >(argp3);
+      arg3 = *temp;
+      if (SWIG_IsNewObj(res3)) delete temp;
+    }
+  }
+  result = (double)((GaussFisherPeakShape const *)arg1)->evaluate(arg2,arg3);
+  resultobj = SWIG_From_double(static_cast< double >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_GaussFisherPeakShape_angularDisorder(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  GaussFisherPeakShape *arg1 = (GaussFisherPeakShape *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  bool result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:GaussFisherPeakShape_angularDisorder",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_GaussFisherPeakShape, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GaussFisherPeakShape_angularDisorder" "', argument " "1"" of type '" "GaussFisherPeakShape const *""'"); 
+  }
+  arg1 = reinterpret_cast< GaussFisherPeakShape * >(argp1);
+  result = (bool)((GaussFisherPeakShape const *)arg1)->angularDisorder();
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *GaussFisherPeakShape_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *obj;
+  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_GaussFisherPeakShape, SWIG_NewClientData(obj));
+  return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *_wrap_new_LorentzFisherPeakShape(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  double arg1 ;
+  double arg2 ;
+  double arg3 ;
+  double val1 ;
+  int ecode1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  double val3 ;
+  int ecode3 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  LorentzFisherPeakShape *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOO:new_LorentzFisherPeakShape",&obj0,&obj1,&obj2)) SWIG_fail;
+  ecode1 = SWIG_AsVal_double(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_LorentzFisherPeakShape" "', argument " "1"" of type '" "double""'");
+  } 
+  arg1 = static_cast< double >(val1);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_LorentzFisherPeakShape" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  ecode3 = SWIG_AsVal_double(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_LorentzFisherPeakShape" "', argument " "3"" of type '" "double""'");
+  } 
+  arg3 = static_cast< double >(val3);
+  result = (LorentzFisherPeakShape *)new LorentzFisherPeakShape(arg1,arg2,arg3);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_LorentzFisherPeakShape, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_delete_LorentzFisherPeakShape(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  LorentzFisherPeakShape *arg1 = (LorentzFisherPeakShape *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:delete_LorentzFisherPeakShape",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_LorentzFisherPeakShape, SWIG_POINTER_DISOWN |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_LorentzFisherPeakShape" "', argument " "1"" of type '" "LorentzFisherPeakShape *""'"); 
+  }
+  arg1 = reinterpret_cast< LorentzFisherPeakShape * >(argp1);
+  delete arg1;
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_LorentzFisherPeakShape_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  LorentzFisherPeakShape *arg1 = (LorentzFisherPeakShape *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  LorentzFisherPeakShape *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:LorentzFisherPeakShape_clone",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_LorentzFisherPeakShape, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "LorentzFisherPeakShape_clone" "', argument " "1"" of type '" "LorentzFisherPeakShape const *""'"); 
+  }
+  arg1 = reinterpret_cast< LorentzFisherPeakShape * >(argp1);
+  result = (LorentzFisherPeakShape *)((LorentzFisherPeakShape const *)arg1)->clone();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_LorentzFisherPeakShape, 0 |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_LorentzFisherPeakShape_accept(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  LorentzFisherPeakShape *arg1 = (LorentzFisherPeakShape *) 0 ;
+  INodeVisitor *arg2 = (INodeVisitor *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OO:LorentzFisherPeakShape_accept",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_LorentzFisherPeakShape, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "LorentzFisherPeakShape_accept" "', argument " "1"" of type '" "LorentzFisherPeakShape const *""'"); 
+  }
+  arg1 = reinterpret_cast< LorentzFisherPeakShape * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_INodeVisitor, 0 |  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "LorentzFisherPeakShape_accept" "', argument " "2"" of type '" "INodeVisitor *""'"); 
+  }
+  arg2 = reinterpret_cast< INodeVisitor * >(argp2);
+  ((LorentzFisherPeakShape const *)arg1)->accept(arg2);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_LorentzFisherPeakShape_evaluate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  LorentzFisherPeakShape *arg1 = (LorentzFisherPeakShape *) 0 ;
+  kvector_t arg2 ;
+  kvector_t arg3 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 ;
+  int res2 = 0 ;
+  void *argp3 ;
+  int res3 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  double result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOO:LorentzFisherPeakShape_evaluate",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_LorentzFisherPeakShape, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "LorentzFisherPeakShape_evaluate" "', argument " "1"" of type '" "LorentzFisherPeakShape const *""'"); 
+  }
+  arg1 = reinterpret_cast< LorentzFisherPeakShape * >(argp1);
+  {
+    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_BasicVector3DT_double_t,  0  | 0);
+    if (!SWIG_IsOK(res2)) {
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "LorentzFisherPeakShape_evaluate" "', argument " "2"" of type '" "kvector_t const""'"); 
+    }  
+    if (!argp2) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "LorentzFisherPeakShape_evaluate" "', argument " "2"" of type '" "kvector_t const""'");
+    } else {
+      kvector_t * temp = reinterpret_cast< kvector_t * >(argp2);
+      arg2 = *temp;
+      if (SWIG_IsNewObj(res2)) delete temp;
+    }
+  }
+  {
+    res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_BasicVector3DT_double_t,  0  | 0);
+    if (!SWIG_IsOK(res3)) {
+      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "LorentzFisherPeakShape_evaluate" "', argument " "3"" of type '" "kvector_t const""'"); 
+    }  
+    if (!argp3) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "LorentzFisherPeakShape_evaluate" "', argument " "3"" of type '" "kvector_t const""'");
+    } else {
+      kvector_t * temp = reinterpret_cast< kvector_t * >(argp3);
+      arg3 = *temp;
+      if (SWIG_IsNewObj(res3)) delete temp;
+    }
+  }
+  result = (double)((LorentzFisherPeakShape const *)arg1)->evaluate(arg2,arg3);
+  resultobj = SWIG_From_double(static_cast< double >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_LorentzFisherPeakShape_angularDisorder(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  LorentzFisherPeakShape *arg1 = (LorentzFisherPeakShape *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  bool result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:LorentzFisherPeakShape_angularDisorder",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_LorentzFisherPeakShape, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "LorentzFisherPeakShape_angularDisorder" "', argument " "1"" of type '" "LorentzFisherPeakShape const *""'"); 
+  }
+  arg1 = reinterpret_cast< LorentzFisherPeakShape * >(argp1);
+  result = (bool)((LorentzFisherPeakShape const *)arg1)->angularDisorder();
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *LorentzFisherPeakShape_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
   if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_GaussPeakShape, SWIG_NewClientData(obj));
+  SWIG_TypeNewClientData(SWIGTYPE_p_LorentzFisherPeakShape, SWIG_NewClientData(obj));
   return SWIG_Py_Void();
 }
 
@@ -98409,460 +91449,6 @@ SWIGINTERN PyObject *InterferenceFunction1DLattice_swigregister(PyObject *SWIGUN
   return SWIG_Py_Void();
 }
 
-SWIGINTERN PyObject *_wrap_new_InterferenceFunctionRadialParaCrystal__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  double arg1 ;
-  double arg2 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  InterferenceFunctionRadialParaCrystal *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:new_InterferenceFunctionRadialParaCrystal",&obj0,&obj1)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(obj0, &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_InterferenceFunctionRadialParaCrystal" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_InterferenceFunctionRadialParaCrystal" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  result = (InterferenceFunctionRadialParaCrystal *)new InterferenceFunctionRadialParaCrystal(arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_InterferenceFunctionRadialParaCrystal__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  double arg1 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  PyObject * obj0 = 0 ;
-  InterferenceFunctionRadialParaCrystal *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:new_InterferenceFunctionRadialParaCrystal",&obj0)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(obj0, &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_InterferenceFunctionRadialParaCrystal" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  result = (InterferenceFunctionRadialParaCrystal *)new InterferenceFunctionRadialParaCrystal(arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_InterferenceFunctionRadialParaCrystal(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[3] = {
-    0
-  };
-  Py_ssize_t ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    {
-      int res = SWIG_AsVal_double(argv[0], NULL);
-      _v = SWIG_CheckState(res);
-    }
-    if (_v) {
-      return _wrap_new_InterferenceFunctionRadialParaCrystal__SWIG_1(self, args);
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    {
-      int res = SWIG_AsVal_double(argv[0], NULL);
-      _v = SWIG_CheckState(res);
-    }
-    if (_v) {
-      {
-        int res = SWIG_AsVal_double(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_new_InterferenceFunctionRadialParaCrystal__SWIG_0(self, args);
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_InterferenceFunctionRadialParaCrystal'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    InterferenceFunctionRadialParaCrystal::InterferenceFunctionRadialParaCrystal(double,double)\n"
-    "    InterferenceFunctionRadialParaCrystal::InterferenceFunctionRadialParaCrystal(double)\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_InterferenceFunctionRadialParaCrystal_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  InterferenceFunctionRadialParaCrystal *arg1 = (InterferenceFunctionRadialParaCrystal *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  InterferenceFunctionRadialParaCrystal *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionRadialParaCrystal_clone",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionRadialParaCrystal_clone" "', argument " "1"" of type '" "InterferenceFunctionRadialParaCrystal const *""'"); 
-  }
-  arg1 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp1);
-  result = (InterferenceFunctionRadialParaCrystal *)((InterferenceFunctionRadialParaCrystal const *)arg1)->clone();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_InterferenceFunctionRadialParaCrystal_accept(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  InterferenceFunctionRadialParaCrystal *arg1 = (InterferenceFunctionRadialParaCrystal *) 0 ;
-  INodeVisitor *arg2 = (INodeVisitor *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunctionRadialParaCrystal_accept",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionRadialParaCrystal_accept" "', argument " "1"" of type '" "InterferenceFunctionRadialParaCrystal const *""'"); 
-  }
-  arg1 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_INodeVisitor, 0 |  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "InterferenceFunctionRadialParaCrystal_accept" "', argument " "2"" of type '" "INodeVisitor *""'"); 
-  }
-  arg2 = reinterpret_cast< INodeVisitor * >(argp2);
-  ((InterferenceFunctionRadialParaCrystal const *)arg1)->accept(arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_InterferenceFunctionRadialParaCrystal_setKappa(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  InterferenceFunctionRadialParaCrystal *arg1 = (InterferenceFunctionRadialParaCrystal *) 0 ;
-  double arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunctionRadialParaCrystal_setKappa",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionRadialParaCrystal_setKappa" "', argument " "1"" of type '" "InterferenceFunctionRadialParaCrystal *""'"); 
-  }
-  arg1 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunctionRadialParaCrystal_setKappa" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  (arg1)->setKappa(arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_InterferenceFunctionRadialParaCrystal_kappa(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  InterferenceFunctionRadialParaCrystal *arg1 = (InterferenceFunctionRadialParaCrystal *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  double result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionRadialParaCrystal_kappa",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionRadialParaCrystal_kappa" "', argument " "1"" of type '" "InterferenceFunctionRadialParaCrystal const *""'"); 
-  }
-  arg1 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp1);
-  result = (double)((InterferenceFunctionRadialParaCrystal const *)arg1)->kappa();
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_InterferenceFunctionRadialParaCrystal_setDomainSize(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  InterferenceFunctionRadialParaCrystal *arg1 = (InterferenceFunctionRadialParaCrystal *) 0 ;
-  double arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunctionRadialParaCrystal_setDomainSize",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionRadialParaCrystal_setDomainSize" "', argument " "1"" of type '" "InterferenceFunctionRadialParaCrystal *""'"); 
-  }
-  arg1 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunctionRadialParaCrystal_setDomainSize" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  (arg1)->setDomainSize(arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_InterferenceFunctionRadialParaCrystal_domainSize(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  InterferenceFunctionRadialParaCrystal *arg1 = (InterferenceFunctionRadialParaCrystal *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  double result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionRadialParaCrystal_domainSize",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionRadialParaCrystal_domainSize" "', argument " "1"" of type '" "InterferenceFunctionRadialParaCrystal const *""'"); 
-  }
-  arg1 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp1);
-  result = (double)((InterferenceFunctionRadialParaCrystal const *)arg1)->domainSize();
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_InterferenceFunctionRadialParaCrystal_evaluate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  InterferenceFunctionRadialParaCrystal *arg1 = (InterferenceFunctionRadialParaCrystal *) 0 ;
-  kvector_t arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  double result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunctionRadialParaCrystal_evaluate",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionRadialParaCrystal_evaluate" "', argument " "1"" of type '" "InterferenceFunctionRadialParaCrystal const *""'"); 
-  }
-  arg1 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp1);
-  {
-    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_BasicVector3DT_double_t,  0  | 0);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "InterferenceFunctionRadialParaCrystal_evaluate" "', argument " "2"" of type '" "kvector_t const""'"); 
-    }  
-    if (!argp2) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "InterferenceFunctionRadialParaCrystal_evaluate" "', argument " "2"" of type '" "kvector_t const""'");
-    } else {
-      kvector_t * temp = reinterpret_cast< kvector_t * >(argp2);
-      arg2 = *temp;
-      if (SWIG_IsNewObj(res2)) delete temp;
-    }
-  }
-  result = (double)((InterferenceFunctionRadialParaCrystal const *)arg1)->evaluate(arg2);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_InterferenceFunctionRadialParaCrystal_FTPDF(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  InterferenceFunctionRadialParaCrystal *arg1 = (InterferenceFunctionRadialParaCrystal *) 0 ;
-  double arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  complex_t result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunctionRadialParaCrystal_FTPDF",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionRadialParaCrystal_FTPDF" "', argument " "1"" of type '" "InterferenceFunctionRadialParaCrystal const *""'"); 
-  }
-  arg1 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunctionRadialParaCrystal_FTPDF" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  result = ((InterferenceFunctionRadialParaCrystal const *)arg1)->FTPDF(arg2);
-  resultobj = SWIG_From_std_complex_Sl_double_Sg_(static_cast< std::complex<double> >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_InterferenceFunctionRadialParaCrystal_setProbabilityDistribution(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  InterferenceFunctionRadialParaCrystal *arg1 = (InterferenceFunctionRadialParaCrystal *) 0 ;
-  IFTDistribution1D *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunctionRadialParaCrystal_setProbabilityDistribution",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionRadialParaCrystal_setProbabilityDistribution" "', argument " "1"" of type '" "InterferenceFunctionRadialParaCrystal *""'"); 
-  }
-  arg1 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_IFTDistribution1D,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "InterferenceFunctionRadialParaCrystal_setProbabilityDistribution" "', argument " "2"" of type '" "IFTDistribution1D const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "InterferenceFunctionRadialParaCrystal_setProbabilityDistribution" "', argument " "2"" of type '" "IFTDistribution1D const &""'"); 
-  }
-  arg2 = reinterpret_cast< IFTDistribution1D * >(argp2);
-  (arg1)->setProbabilityDistribution((IFTDistribution1D const &)*arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_InterferenceFunctionRadialParaCrystal_peakDistance(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  InterferenceFunctionRadialParaCrystal *arg1 = (InterferenceFunctionRadialParaCrystal *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  double result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionRadialParaCrystal_peakDistance",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionRadialParaCrystal_peakDistance" "', argument " "1"" of type '" "InterferenceFunctionRadialParaCrystal const *""'"); 
-  }
-  arg1 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp1);
-  result = (double)((InterferenceFunctionRadialParaCrystal const *)arg1)->peakDistance();
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_InterferenceFunctionRadialParaCrystal_dampingLength(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  InterferenceFunctionRadialParaCrystal *arg1 = (InterferenceFunctionRadialParaCrystal *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  double result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionRadialParaCrystal_dampingLength",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionRadialParaCrystal_dampingLength" "', argument " "1"" of type '" "InterferenceFunctionRadialParaCrystal const *""'"); 
-  }
-  arg1 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp1);
-  result = (double)((InterferenceFunctionRadialParaCrystal const *)arg1)->dampingLength();
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_InterferenceFunctionRadialParaCrystal_getChildren(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  InterferenceFunctionRadialParaCrystal *arg1 = (InterferenceFunctionRadialParaCrystal *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  std::vector< INode const *,std::allocator< INode const * > > result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionRadialParaCrystal_getChildren",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionRadialParaCrystal_getChildren" "', argument " "1"" of type '" "InterferenceFunctionRadialParaCrystal const *""'"); 
-  }
-  arg1 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp1);
-  result = ((InterferenceFunctionRadialParaCrystal const *)arg1)->getChildren();
-  resultobj = swig::from(static_cast< std::vector< INode const*,std::allocator< INode const * > > >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_delete_InterferenceFunctionRadialParaCrystal(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  InterferenceFunctionRadialParaCrystal *arg1 = (InterferenceFunctionRadialParaCrystal *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_InterferenceFunctionRadialParaCrystal",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_InterferenceFunctionRadialParaCrystal" "', argument " "1"" of type '" "InterferenceFunctionRadialParaCrystal *""'"); 
-  }
-  arg1 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *InterferenceFunctionRadialParaCrystal_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
 SWIGINTERN PyObject *_wrap_new_InterferenceFunction2DLattice__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Lattice2D *arg1 = 0 ;
@@ -99551,44 +92137,499 @@ SWIGINTERN PyObject *InterferenceFunction2DLattice_swigregister(PyObject *SWIGUN
   return SWIG_Py_Void();
 }
 
-SWIGINTERN PyObject *_wrap_new_InterferenceFunction3DLattice(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_InterferenceFunction2DParaCrystal__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  Lattice *arg1 = 0 ;
+  Lattice2D *arg1 = 0 ;
+  double arg2 ;
+  double arg3 ;
+  double arg4 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  double val3 ;
+  int ecode3 = 0 ;
+  double val4 ;
+  int ecode4 = 0 ;
   PyObject * obj0 = 0 ;
-  InterferenceFunction3DLattice *result = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  InterferenceFunction2DParaCrystal *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:new_InterferenceFunction3DLattice",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_Lattice,  0  | 0);
+  if (!PyArg_ParseTuple(args,(char *)"OOOO:new_InterferenceFunction2DParaCrystal",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_Lattice2D,  0  | 0);
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_InterferenceFunction3DLattice" "', argument " "1"" of type '" "Lattice const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "1"" of type '" "Lattice2D const &""'"); 
   }
   if (!argp1) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_InterferenceFunction3DLattice" "', argument " "1"" of type '" "Lattice const &""'"); 
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "1"" of type '" "Lattice2D const &""'"); 
+  }
+  arg1 = reinterpret_cast< Lattice2D * >(argp1);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  ecode3 = SWIG_AsVal_double(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "3"" of type '" "double""'");
+  } 
+  arg3 = static_cast< double >(val3);
+  ecode4 = SWIG_AsVal_double(obj3, &val4);
+  if (!SWIG_IsOK(ecode4)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "4"" of type '" "double""'");
+  } 
+  arg4 = static_cast< double >(val4);
+  result = (InterferenceFunction2DParaCrystal *)new InterferenceFunction2DParaCrystal((Lattice2D const &)*arg1,arg2,arg3,arg4);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_new_InterferenceFunction2DParaCrystal__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Lattice2D *arg1 = 0 ;
+  double arg2 ;
+  double arg3 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  double val3 ;
+  int ecode3 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  InterferenceFunction2DParaCrystal *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOO:new_InterferenceFunction2DParaCrystal",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_Lattice2D,  0  | 0);
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "1"" of type '" "Lattice2D const &""'"); 
+  }
+  if (!argp1) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "1"" of type '" "Lattice2D const &""'"); 
+  }
+  arg1 = reinterpret_cast< Lattice2D * >(argp1);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  ecode3 = SWIG_AsVal_double(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "3"" of type '" "double""'");
+  } 
+  arg3 = static_cast< double >(val3);
+  result = (InterferenceFunction2DParaCrystal *)new InterferenceFunction2DParaCrystal((Lattice2D const &)*arg1,arg2,arg3);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_new_InterferenceFunction2DParaCrystal__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Lattice2D *arg1 = 0 ;
+  double arg2 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  InterferenceFunction2DParaCrystal *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OO:new_InterferenceFunction2DParaCrystal",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_Lattice2D,  0  | 0);
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "1"" of type '" "Lattice2D const &""'"); 
+  }
+  if (!argp1) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "1"" of type '" "Lattice2D const &""'"); 
+  }
+  arg1 = reinterpret_cast< Lattice2D * >(argp1);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  result = (InterferenceFunction2DParaCrystal *)new InterferenceFunction2DParaCrystal((Lattice2D const &)*arg1,arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_new_InterferenceFunction2DParaCrystal__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Lattice2D *arg1 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  InterferenceFunction2DParaCrystal *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:new_InterferenceFunction2DParaCrystal",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_Lattice2D,  0  | 0);
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "1"" of type '" "Lattice2D const &""'"); 
+  }
+  if (!argp1) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "1"" of type '" "Lattice2D const &""'"); 
+  }
+  arg1 = reinterpret_cast< Lattice2D * >(argp1);
+  result = (InterferenceFunction2DParaCrystal *)new InterferenceFunction2DParaCrystal((Lattice2D const &)*arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_new_InterferenceFunction2DParaCrystal__SWIG_4(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  double arg1 ;
+  double arg2 ;
+  double arg3 ;
+  double arg4 ;
+  double arg5 ;
+  double val1 ;
+  int ecode1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  double val3 ;
+  int ecode3 = 0 ;
+  double val4 ;
+  int ecode4 = 0 ;
+  double val5 ;
+  int ecode5 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  PyObject * obj4 = 0 ;
+  InterferenceFunction2DParaCrystal *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOOOO:new_InterferenceFunction2DParaCrystal",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
+  ecode1 = SWIG_AsVal_double(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "1"" of type '" "double""'");
+  } 
+  arg1 = static_cast< double >(val1);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  ecode3 = SWIG_AsVal_double(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "3"" of type '" "double""'");
+  } 
+  arg3 = static_cast< double >(val3);
+  ecode4 = SWIG_AsVal_double(obj3, &val4);
+  if (!SWIG_IsOK(ecode4)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "4"" of type '" "double""'");
+  } 
+  arg4 = static_cast< double >(val4);
+  ecode5 = SWIG_AsVal_double(obj4, &val5);
+  if (!SWIG_IsOK(ecode5)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "5"" of type '" "double""'");
+  } 
+  arg5 = static_cast< double >(val5);
+  result = (InterferenceFunction2DParaCrystal *)new InterferenceFunction2DParaCrystal(arg1,arg2,arg3,arg4,arg5);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_new_InterferenceFunction2DParaCrystal__SWIG_5(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  double arg1 ;
+  double arg2 ;
+  double arg3 ;
+  double arg4 ;
+  double val1 ;
+  int ecode1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  double val3 ;
+  int ecode3 = 0 ;
+  double val4 ;
+  int ecode4 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  InterferenceFunction2DParaCrystal *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOOO:new_InterferenceFunction2DParaCrystal",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+  ecode1 = SWIG_AsVal_double(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "1"" of type '" "double""'");
+  } 
+  arg1 = static_cast< double >(val1);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  ecode3 = SWIG_AsVal_double(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "3"" of type '" "double""'");
+  } 
+  arg3 = static_cast< double >(val3);
+  ecode4 = SWIG_AsVal_double(obj3, &val4);
+  if (!SWIG_IsOK(ecode4)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "4"" of type '" "double""'");
+  } 
+  arg4 = static_cast< double >(val4);
+  result = (InterferenceFunction2DParaCrystal *)new InterferenceFunction2DParaCrystal(arg1,arg2,arg3,arg4);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_new_InterferenceFunction2DParaCrystal__SWIG_6(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  double arg1 ;
+  double arg2 ;
+  double arg3 ;
+  double val1 ;
+  int ecode1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  double val3 ;
+  int ecode3 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  InterferenceFunction2DParaCrystal *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OOO:new_InterferenceFunction2DParaCrystal",&obj0,&obj1,&obj2)) SWIG_fail;
+  ecode1 = SWIG_AsVal_double(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "1"" of type '" "double""'");
+  } 
+  arg1 = static_cast< double >(val1);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  ecode3 = SWIG_AsVal_double(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "3"" of type '" "double""'");
+  } 
+  arg3 = static_cast< double >(val3);
+  result = (InterferenceFunction2DParaCrystal *)new InterferenceFunction2DParaCrystal(arg1,arg2,arg3);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_new_InterferenceFunction2DParaCrystal(PyObject *self, PyObject *args) {
+  Py_ssize_t argc;
+  PyObject *argv[6] = {
+    0
+  };
+  Py_ssize_t ii;
+  
+  if (!PyTuple_Check(args)) SWIG_fail;
+  argc = args ? PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 5) && (ii < argc); ii++) {
+    argv[ii] = PyTuple_GET_ITEM(args,ii);
+  }
+  if (argc == 1) {
+    int _v;
+    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_Lattice2D, 0);
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      return _wrap_new_InterferenceFunction2DParaCrystal__SWIG_3(self, args);
+    }
+  }
+  if (argc == 2) {
+    int _v;
+    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_Lattice2D, 0);
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        int res = SWIG_AsVal_double(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        return _wrap_new_InterferenceFunction2DParaCrystal__SWIG_2(self, args);
+      }
+    }
+  }
+  if (argc == 3) {
+    int _v;
+    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_Lattice2D, 0);
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        int res = SWIG_AsVal_double(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          int res = SWIG_AsVal_double(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          return _wrap_new_InterferenceFunction2DParaCrystal__SWIG_1(self, args);
+        }
+      }
+    }
+  }
+  if (argc == 3) {
+    int _v;
+    {
+      int res = SWIG_AsVal_double(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      {
+        int res = SWIG_AsVal_double(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          int res = SWIG_AsVal_double(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          return _wrap_new_InterferenceFunction2DParaCrystal__SWIG_6(self, args);
+        }
+      }
+    }
+  }
+  if (argc == 4) {
+    int _v;
+    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_Lattice2D, 0);
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        int res = SWIG_AsVal_double(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          int res = SWIG_AsVal_double(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          {
+            int res = SWIG_AsVal_double(argv[3], NULL);
+            _v = SWIG_CheckState(res);
+          }
+          if (_v) {
+            return _wrap_new_InterferenceFunction2DParaCrystal__SWIG_0(self, args);
+          }
+        }
+      }
+    }
+  }
+  if (argc == 4) {
+    int _v;
+    {
+      int res = SWIG_AsVal_double(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      {
+        int res = SWIG_AsVal_double(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          int res = SWIG_AsVal_double(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          {
+            int res = SWIG_AsVal_double(argv[3], NULL);
+            _v = SWIG_CheckState(res);
+          }
+          if (_v) {
+            return _wrap_new_InterferenceFunction2DParaCrystal__SWIG_5(self, args);
+          }
+        }
+      }
+    }
+  }
+  if (argc == 5) {
+    int _v;
+    {
+      int res = SWIG_AsVal_double(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      {
+        int res = SWIG_AsVal_double(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          int res = SWIG_AsVal_double(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          {
+            int res = SWIG_AsVal_double(argv[3], NULL);
+            _v = SWIG_CheckState(res);
+          }
+          if (_v) {
+            {
+              int res = SWIG_AsVal_double(argv[4], NULL);
+              _v = SWIG_CheckState(res);
+            }
+            if (_v) {
+              return _wrap_new_InterferenceFunction2DParaCrystal__SWIG_4(self, args);
+            }
+          }
+        }
+      }
+    }
   }
-  arg1 = reinterpret_cast< Lattice * >(argp1);
-  result = (InterferenceFunction3DLattice *)new InterferenceFunction3DLattice((Lattice const &)*arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction3DLattice, SWIG_POINTER_NEW |  0 );
-  return resultobj;
+  
 fail:
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_InterferenceFunction2DParaCrystal'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    InterferenceFunction2DParaCrystal::InterferenceFunction2DParaCrystal(Lattice2D const &,double,double,double)\n"
+    "    InterferenceFunction2DParaCrystal::InterferenceFunction2DParaCrystal(Lattice2D const &,double,double)\n"
+    "    InterferenceFunction2DParaCrystal::InterferenceFunction2DParaCrystal(Lattice2D const &,double)\n"
+    "    InterferenceFunction2DParaCrystal::InterferenceFunction2DParaCrystal(Lattice2D const &)\n"
+    "    InterferenceFunction2DParaCrystal::InterferenceFunction2DParaCrystal(double,double,double,double,double)\n"
+    "    InterferenceFunction2DParaCrystal::InterferenceFunction2DParaCrystal(double,double,double,double)\n"
+    "    InterferenceFunction2DParaCrystal::InterferenceFunction2DParaCrystal(double,double,double)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_delete_InterferenceFunction3DLattice(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_delete_InterferenceFunction2DParaCrystal(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunction3DLattice *arg1 = (InterferenceFunction3DLattice *) 0 ;
+  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_InterferenceFunction3DLattice",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction3DLattice, SWIG_POINTER_DISOWN |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:delete_InterferenceFunction2DParaCrystal",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, SWIG_POINTER_DISOWN |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_InterferenceFunction3DLattice" "', argument " "1"" of type '" "InterferenceFunction3DLattice *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_InterferenceFunction2DParaCrystal" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal *""'"); 
   }
-  arg1 = reinterpret_cast< InterferenceFunction3DLattice * >(argp1);
+  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
   delete arg1;
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -99597,31 +92638,31 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction3DLattice_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunction3DLattice *arg1 = (InterferenceFunction3DLattice *) 0 ;
+  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  InterferenceFunction3DLattice *result = 0 ;
+  InterferenceFunction2DParaCrystal *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction3DLattice_clone",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction3DLattice, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction2DParaCrystal_clone",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction3DLattice_clone" "', argument " "1"" of type '" "InterferenceFunction3DLattice const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_clone" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal const *""'"); 
   }
-  arg1 = reinterpret_cast< InterferenceFunction3DLattice * >(argp1);
-  result = (InterferenceFunction3DLattice *)((InterferenceFunction3DLattice const *)arg1)->clone();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction3DLattice, 0 |  0 );
+  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
+  result = (InterferenceFunction2DParaCrystal *)((InterferenceFunction2DParaCrystal const *)arg1)->clone();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction3DLattice_accept(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_accept(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunction3DLattice *arg1 = (InterferenceFunction3DLattice *) 0 ;
+  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
   INodeVisitor *arg2 = (INodeVisitor *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
@@ -99630,18 +92671,18 @@ SWIGINTERN PyObject *_wrap_InterferenceFunction3DLattice_accept(PyObject *SWIGUN
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunction3DLattice_accept",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction3DLattice, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunction2DParaCrystal_accept",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction3DLattice_accept" "', argument " "1"" of type '" "InterferenceFunction3DLattice const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_accept" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal const *""'"); 
   }
-  arg1 = reinterpret_cast< InterferenceFunction3DLattice * >(argp1);
+  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
   res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_INodeVisitor, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "InterferenceFunction3DLattice_accept" "', argument " "2"" of type '" "INodeVisitor *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "InterferenceFunction2DParaCrystal_accept" "', argument " "2"" of type '" "INodeVisitor *""'"); 
   }
   arg2 = reinterpret_cast< INodeVisitor * >(argp2);
-  ((InterferenceFunction3DLattice const *)arg1)->accept(arg2);
+  ((InterferenceFunction2DParaCrystal const *)arg1)->accept(arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -99649,367 +92690,451 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction3DLattice_setPeakShape(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_createSquare__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunction3DLattice *arg1 = (InterferenceFunction3DLattice *) 0 ;
-  IPeakShape *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
+  double arg1 ;
+  double arg2 ;
+  double arg3 ;
+  double arg4 ;
+  double val1 ;
+  int ecode1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  double val3 ;
+  int ecode3 = 0 ;
+  double val4 ;
+  int ecode4 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  InterferenceFunction2DParaCrystal *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunction3DLattice_setPeakShape",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction3DLattice, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction3DLattice_setPeakShape" "', argument " "1"" of type '" "InterferenceFunction3DLattice *""'"); 
-  }
-  arg1 = reinterpret_cast< InterferenceFunction3DLattice * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_IPeakShape,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "InterferenceFunction3DLattice_setPeakShape" "', argument " "2"" of type '" "IPeakShape const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "InterferenceFunction3DLattice_setPeakShape" "', argument " "2"" of type '" "IPeakShape const &""'"); 
-  }
-  arg2 = reinterpret_cast< IPeakShape * >(argp2);
-  (arg1)->setPeakShape((IPeakShape const &)*arg2);
-  resultobj = SWIG_Py_Void();
+  if (!PyArg_ParseTuple(args,(char *)"OOOO:InterferenceFunction2DParaCrystal_createSquare",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+  ecode1 = SWIG_AsVal_double(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "InterferenceFunction2DParaCrystal_createSquare" "', argument " "1"" of type '" "double""'");
+  } 
+  arg1 = static_cast< double >(val1);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunction2DParaCrystal_createSquare" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  ecode3 = SWIG_AsVal_double(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "InterferenceFunction2DParaCrystal_createSquare" "', argument " "3"" of type '" "double""'");
+  } 
+  arg3 = static_cast< double >(val3);
+  ecode4 = SWIG_AsVal_double(obj3, &val4);
+  if (!SWIG_IsOK(ecode4)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "InterferenceFunction2DParaCrystal_createSquare" "', argument " "4"" of type '" "double""'");
+  } 
+  arg4 = static_cast< double >(val4);
+  result = (InterferenceFunction2DParaCrystal *)InterferenceFunction2DParaCrystal::createSquare(arg1,arg2,arg3,arg4);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction3DLattice_setDebyeWallerFactor(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_createSquare__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunction3DLattice *arg1 = (InterferenceFunction3DLattice *) 0 ;
+  double arg1 ;
   double arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
+  double arg3 ;
+  double val1 ;
+  int ecode1 = 0 ;
   double val2 ;
   int ecode2 = 0 ;
+  double val3 ;
+  int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  InterferenceFunction2DParaCrystal *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunction3DLattice_setDebyeWallerFactor",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction3DLattice, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction3DLattice_setDebyeWallerFactor" "', argument " "1"" of type '" "InterferenceFunction3DLattice *""'"); 
-  }
-  arg1 = reinterpret_cast< InterferenceFunction3DLattice * >(argp1);
+  if (!PyArg_ParseTuple(args,(char *)"OOO:InterferenceFunction2DParaCrystal_createSquare",&obj0,&obj1,&obj2)) SWIG_fail;
+  ecode1 = SWIG_AsVal_double(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "InterferenceFunction2DParaCrystal_createSquare" "', argument " "1"" of type '" "double""'");
+  } 
+  arg1 = static_cast< double >(val1);
   ecode2 = SWIG_AsVal_double(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunction3DLattice_setDebyeWallerFactor" "', argument " "2"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunction2DParaCrystal_createSquare" "', argument " "2"" of type '" "double""'");
   } 
   arg2 = static_cast< double >(val2);
-  (arg1)->setDebyeWallerFactor(arg2);
-  resultobj = SWIG_Py_Void();
+  ecode3 = SWIG_AsVal_double(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "InterferenceFunction2DParaCrystal_createSquare" "', argument " "3"" of type '" "double""'");
+  } 
+  arg3 = static_cast< double >(val3);
+  result = (InterferenceFunction2DParaCrystal *)InterferenceFunction2DParaCrystal::createSquare(arg1,arg2,arg3);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction3DLattice_evaluate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_createSquare__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunction3DLattice *arg1 = (InterferenceFunction3DLattice *) 0 ;
-  kvector_t arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 ;
-  int res2 = 0 ;
+  double arg1 ;
+  double arg2 ;
+  double val1 ;
+  int ecode1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  double result;
+  InterferenceFunction2DParaCrystal *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunction3DLattice_evaluate",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction3DLattice, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction3DLattice_evaluate" "', argument " "1"" of type '" "InterferenceFunction3DLattice const *""'"); 
-  }
-  arg1 = reinterpret_cast< InterferenceFunction3DLattice * >(argp1);
-  {
-    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_BasicVector3DT_double_t,  0  | 0);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "InterferenceFunction3DLattice_evaluate" "', argument " "2"" of type '" "kvector_t const""'"); 
-    }  
-    if (!argp2) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "InterferenceFunction3DLattice_evaluate" "', argument " "2"" of type '" "kvector_t const""'");
-    } else {
-      kvector_t * temp = reinterpret_cast< kvector_t * >(argp2);
-      arg2 = *temp;
-      if (SWIG_IsNewObj(res2)) delete temp;
-    }
-  }
-  result = (double)((InterferenceFunction3DLattice const *)arg1)->evaluate(arg2);
-  resultobj = SWIG_From_double(static_cast< double >(result));
+  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunction2DParaCrystal_createSquare",&obj0,&obj1)) SWIG_fail;
+  ecode1 = SWIG_AsVal_double(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "InterferenceFunction2DParaCrystal_createSquare" "', argument " "1"" of type '" "double""'");
+  } 
+  arg1 = static_cast< double >(val1);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunction2DParaCrystal_createSquare" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  result = (InterferenceFunction2DParaCrystal *)InterferenceFunction2DParaCrystal::createSquare(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction3DLattice_lattice(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_createSquare__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunction3DLattice *arg1 = (InterferenceFunction3DLattice *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
+  double arg1 ;
+  double val1 ;
+  int ecode1 = 0 ;
   PyObject * obj0 = 0 ;
-  Lattice *result = 0 ;
+  InterferenceFunction2DParaCrystal *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction3DLattice_lattice",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction3DLattice, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction3DLattice_lattice" "', argument " "1"" of type '" "InterferenceFunction3DLattice const *""'"); 
-  }
-  arg1 = reinterpret_cast< InterferenceFunction3DLattice * >(argp1);
-  result = (Lattice *) &((InterferenceFunction3DLattice const *)arg1)->lattice();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Lattice, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction2DParaCrystal_createSquare",&obj0)) SWIG_fail;
+  ecode1 = SWIG_AsVal_double(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "InterferenceFunction2DParaCrystal_createSquare" "', argument " "1"" of type '" "double""'");
+  } 
+  arg1 = static_cast< double >(val1);
+  result = (InterferenceFunction2DParaCrystal *)InterferenceFunction2DParaCrystal::createSquare(arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction3DLattice_getParticleDensity(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  InterferenceFunction3DLattice *arg1 = (InterferenceFunction3DLattice *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  double result;
+SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_createSquare(PyObject *self, PyObject *args) {
+  Py_ssize_t argc;
+  PyObject *argv[5] = {
+    0
+  };
+  Py_ssize_t ii;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction3DLattice_getParticleDensity",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction3DLattice, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction3DLattice_getParticleDensity" "', argument " "1"" of type '" "InterferenceFunction3DLattice const *""'"); 
+  if (!PyTuple_Check(args)) SWIG_fail;
+  argc = args ? PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
+    argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  arg1 = reinterpret_cast< InterferenceFunction3DLattice * >(argp1);
-  result = (double)((InterferenceFunction3DLattice const *)arg1)->getParticleDensity();
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_InterferenceFunction3DLattice_supportsMultilayer(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  InterferenceFunction3DLattice *arg1 = (InterferenceFunction3DLattice *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  bool result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction3DLattice_supportsMultilayer",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction3DLattice, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction3DLattice_supportsMultilayer" "', argument " "1"" of type '" "InterferenceFunction3DLattice const *""'"); 
+  if (argc == 1) {
+    int _v;
+    {
+      int res = SWIG_AsVal_double(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      return _wrap_InterferenceFunction2DParaCrystal_createSquare__SWIG_3(self, args);
+    }
   }
-  arg1 = reinterpret_cast< InterferenceFunction3DLattice * >(argp1);
-  result = (bool)((InterferenceFunction3DLattice const *)arg1)->supportsMultilayer();
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_InterferenceFunction3DLattice_getChildren(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  InterferenceFunction3DLattice *arg1 = (InterferenceFunction3DLattice *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  std::vector< INode const *,std::allocator< INode const * > > result;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction3DLattice_getChildren",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction3DLattice, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction3DLattice_getChildren" "', argument " "1"" of type '" "InterferenceFunction3DLattice const *""'"); 
+  if (argc == 2) {
+    int _v;
+    {
+      int res = SWIG_AsVal_double(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      {
+        int res = SWIG_AsVal_double(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        return _wrap_InterferenceFunction2DParaCrystal_createSquare__SWIG_2(self, args);
+      }
+    }
   }
-  arg1 = reinterpret_cast< InterferenceFunction3DLattice * >(argp1);
-  result = ((InterferenceFunction3DLattice const *)arg1)->getChildren();
-  resultobj = swig::from(static_cast< std::vector< INode const*,std::allocator< INode const * > > >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_InterferenceFunction3DLattice_onChange(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  InterferenceFunction3DLattice *arg1 = (InterferenceFunction3DLattice *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction3DLattice_onChange",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction3DLattice, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction3DLattice_onChange" "', argument " "1"" of type '" "InterferenceFunction3DLattice *""'"); 
+  if (argc == 3) {
+    int _v;
+    {
+      int res = SWIG_AsVal_double(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      {
+        int res = SWIG_AsVal_double(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          int res = SWIG_AsVal_double(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          return _wrap_InterferenceFunction2DParaCrystal_createSquare__SWIG_1(self, args);
+        }
+      }
+    }
   }
-  arg1 = reinterpret_cast< InterferenceFunction3DLattice * >(argp1);
-  (arg1)->onChange();
-  resultobj = SWIG_Py_Void();
-  return resultobj;
+  if (argc == 4) {
+    int _v;
+    {
+      int res = SWIG_AsVal_double(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      {
+        int res = SWIG_AsVal_double(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          int res = SWIG_AsVal_double(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          {
+            int res = SWIG_AsVal_double(argv[3], NULL);
+            _v = SWIG_CheckState(res);
+          }
+          if (_v) {
+            return _wrap_InterferenceFunction2DParaCrystal_createSquare__SWIG_0(self, args);
+          }
+        }
+      }
+    }
+  }
+  
 fail:
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'InterferenceFunction2DParaCrystal_createSquare'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    InterferenceFunction2DParaCrystal::createSquare(double,double,double,double)\n"
+    "    InterferenceFunction2DParaCrystal::createSquare(double,double,double)\n"
+    "    InterferenceFunction2DParaCrystal::createSquare(double,double)\n"
+    "    InterferenceFunction2DParaCrystal::createSquare(double)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *InterferenceFunction3DLattice_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_InterferenceFunction3DLattice, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *_wrap_new_InterferenceFunctionFinite2DLattice__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_createHexagonal__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  Lattice2D *arg1 = 0 ;
-  unsigned int arg2 ;
-  unsigned int arg3 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  unsigned int val2 ;
+  double arg1 ;
+  double arg2 ;
+  double arg3 ;
+  double arg4 ;
+  double val1 ;
+  int ecode1 = 0 ;
+  double val2 ;
   int ecode2 = 0 ;
-  unsigned int val3 ;
+  double val3 ;
   int ecode3 = 0 ;
+  double val4 ;
+  int ecode4 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
-  InterferenceFunctionFinite2DLattice *result = 0 ;
+  PyObject * obj3 = 0 ;
+  InterferenceFunction2DParaCrystal *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:new_InterferenceFunctionFinite2DLattice",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_Lattice2D,  0  | 0);
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_InterferenceFunctionFinite2DLattice" "', argument " "1"" of type '" "Lattice2D const &""'"); 
-  }
-  if (!argp1) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_InterferenceFunctionFinite2DLattice" "', argument " "1"" of type '" "Lattice2D const &""'"); 
-  }
-  arg1 = reinterpret_cast< Lattice2D * >(argp1);
-  ecode2 = SWIG_AsVal_unsigned_SS_int(obj1, &val2);
+  if (!PyArg_ParseTuple(args,(char *)"OOOO:InterferenceFunction2DParaCrystal_createHexagonal",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+  ecode1 = SWIG_AsVal_double(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "InterferenceFunction2DParaCrystal_createHexagonal" "', argument " "1"" of type '" "double""'");
+  } 
+  arg1 = static_cast< double >(val1);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_InterferenceFunctionFinite2DLattice" "', argument " "2"" of type '" "unsigned int""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunction2DParaCrystal_createHexagonal" "', argument " "2"" of type '" "double""'");
   } 
-  arg2 = static_cast< unsigned int >(val2);
-  ecode3 = SWIG_AsVal_unsigned_SS_int(obj2, &val3);
+  arg2 = static_cast< double >(val2);
+  ecode3 = SWIG_AsVal_double(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_InterferenceFunctionFinite2DLattice" "', argument " "3"" of type '" "unsigned int""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "InterferenceFunction2DParaCrystal_createHexagonal" "', argument " "3"" of type '" "double""'");
   } 
-  arg3 = static_cast< unsigned int >(val3);
-  result = (InterferenceFunctionFinite2DLattice *)new InterferenceFunctionFinite2DLattice((Lattice2D const &)*arg1,arg2,arg3);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunctionFinite2DLattice, SWIG_POINTER_NEW |  0 );
+  arg3 = static_cast< double >(val3);
+  ecode4 = SWIG_AsVal_double(obj3, &val4);
+  if (!SWIG_IsOK(ecode4)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "InterferenceFunction2DParaCrystal_createHexagonal" "', argument " "4"" of type '" "double""'");
+  } 
+  arg4 = static_cast< double >(val4);
+  result = (InterferenceFunction2DParaCrystal *)InterferenceFunction2DParaCrystal::createHexagonal(arg1,arg2,arg3,arg4);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_new_InterferenceFunctionFinite2DLattice__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_createHexagonal__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   double arg1 ;
   double arg2 ;
   double arg3 ;
-  double arg4 ;
-  unsigned int arg5 ;
-  unsigned int arg6 ;
   double val1 ;
   int ecode1 = 0 ;
   double val2 ;
   int ecode2 = 0 ;
   double val3 ;
   int ecode3 = 0 ;
-  double val4 ;
-  int ecode4 = 0 ;
-  unsigned int val5 ;
-  int ecode5 = 0 ;
-  unsigned int val6 ;
-  int ecode6 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
-  PyObject * obj3 = 0 ;
-  PyObject * obj4 = 0 ;
-  PyObject * obj5 = 0 ;
-  InterferenceFunctionFinite2DLattice *result = 0 ;
+  InterferenceFunction2DParaCrystal *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOOOOO:new_InterferenceFunctionFinite2DLattice",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5)) SWIG_fail;
+  if (!PyArg_ParseTuple(args,(char *)"OOO:InterferenceFunction2DParaCrystal_createHexagonal",&obj0,&obj1,&obj2)) SWIG_fail;
   ecode1 = SWIG_AsVal_double(obj0, &val1);
   if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_InterferenceFunctionFinite2DLattice" "', argument " "1"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "InterferenceFunction2DParaCrystal_createHexagonal" "', argument " "1"" of type '" "double""'");
   } 
   arg1 = static_cast< double >(val1);
   ecode2 = SWIG_AsVal_double(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_InterferenceFunctionFinite2DLattice" "', argument " "2"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunction2DParaCrystal_createHexagonal" "', argument " "2"" of type '" "double""'");
   } 
   arg2 = static_cast< double >(val2);
   ecode3 = SWIG_AsVal_double(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_InterferenceFunctionFinite2DLattice" "', argument " "3"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "InterferenceFunction2DParaCrystal_createHexagonal" "', argument " "3"" of type '" "double""'");
   } 
   arg3 = static_cast< double >(val3);
-  ecode4 = SWIG_AsVal_double(obj3, &val4);
-  if (!SWIG_IsOK(ecode4)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "new_InterferenceFunctionFinite2DLattice" "', argument " "4"" of type '" "double""'");
+  result = (InterferenceFunction2DParaCrystal *)InterferenceFunction2DParaCrystal::createHexagonal(arg1,arg2,arg3);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_createHexagonal__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  double arg1 ;
+  double arg2 ;
+  double val1 ;
+  int ecode1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  InterferenceFunction2DParaCrystal *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunction2DParaCrystal_createHexagonal",&obj0,&obj1)) SWIG_fail;
+  ecode1 = SWIG_AsVal_double(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "InterferenceFunction2DParaCrystal_createHexagonal" "', argument " "1"" of type '" "double""'");
   } 
-  arg4 = static_cast< double >(val4);
-  ecode5 = SWIG_AsVal_unsigned_SS_int(obj4, &val5);
-  if (!SWIG_IsOK(ecode5)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "new_InterferenceFunctionFinite2DLattice" "', argument " "5"" of type '" "unsigned int""'");
+  arg1 = static_cast< double >(val1);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunction2DParaCrystal_createHexagonal" "', argument " "2"" of type '" "double""'");
   } 
-  arg5 = static_cast< unsigned int >(val5);
-  ecode6 = SWIG_AsVal_unsigned_SS_int(obj5, &val6);
-  if (!SWIG_IsOK(ecode6)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "new_InterferenceFunctionFinite2DLattice" "', argument " "6"" of type '" "unsigned int""'");
+  arg2 = static_cast< double >(val2);
+  result = (InterferenceFunction2DParaCrystal *)InterferenceFunction2DParaCrystal::createHexagonal(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_createHexagonal__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  double arg1 ;
+  double val1 ;
+  int ecode1 = 0 ;
+  PyObject * obj0 = 0 ;
+  InterferenceFunction2DParaCrystal *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction2DParaCrystal_createHexagonal",&obj0)) SWIG_fail;
+  ecode1 = SWIG_AsVal_double(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "InterferenceFunction2DParaCrystal_createHexagonal" "', argument " "1"" of type '" "double""'");
   } 
-  arg6 = static_cast< unsigned int >(val6);
-  result = (InterferenceFunctionFinite2DLattice *)new InterferenceFunctionFinite2DLattice(arg1,arg2,arg3,arg4,arg5,arg6);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunctionFinite2DLattice, SWIG_POINTER_NEW |  0 );
+  arg1 = static_cast< double >(val1);
+  result = (InterferenceFunction2DParaCrystal *)InterferenceFunction2DParaCrystal::createHexagonal(arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_new_InterferenceFunctionFinite2DLattice(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_createHexagonal(PyObject *self, PyObject *args) {
   Py_ssize_t argc;
-  PyObject *argv[7] = {
+  PyObject *argv[5] = {
     0
   };
   Py_ssize_t ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
   argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 6) && (ii < argc); ii++) {
+  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
+  if (argc == 1) {
+    int _v;
+    {
+      int res = SWIG_AsVal_double(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      return _wrap_InterferenceFunction2DParaCrystal_createHexagonal__SWIG_3(self, args);
+    }
+  }
+  if (argc == 2) {
+    int _v;
+    {
+      int res = SWIG_AsVal_double(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      {
+        int res = SWIG_AsVal_double(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        return _wrap_InterferenceFunction2DParaCrystal_createHexagonal__SWIG_2(self, args);
+      }
+    }
+  }
   if (argc == 3) {
     int _v;
-    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_Lattice2D, 0);
-    _v = SWIG_CheckState(res);
+    {
+      int res = SWIG_AsVal_double(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
     if (_v) {
       {
-        int res = SWIG_AsVal_unsigned_SS_int(argv[1], NULL);
+        int res = SWIG_AsVal_double(argv[1], NULL);
         _v = SWIG_CheckState(res);
       }
       if (_v) {
         {
-          int res = SWIG_AsVal_unsigned_SS_int(argv[2], NULL);
+          int res = SWIG_AsVal_double(argv[2], NULL);
           _v = SWIG_CheckState(res);
         }
         if (_v) {
-          return _wrap_new_InterferenceFunctionFinite2DLattice__SWIG_0(self, args);
+          return _wrap_InterferenceFunction2DParaCrystal_createHexagonal__SWIG_1(self, args);
         }
       }
     }
   }
-  if (argc == 6) {
+  if (argc == 4) {
     int _v;
     {
       int res = SWIG_AsVal_double(argv[0], NULL);
@@ -100031,19 +93156,7 @@ SWIGINTERN PyObject *_wrap_new_InterferenceFunctionFinite2DLattice(PyObject *sel
             _v = SWIG_CheckState(res);
           }
           if (_v) {
-            {
-              int res = SWIG_AsVal_unsigned_SS_int(argv[4], NULL);
-              _v = SWIG_CheckState(res);
-            }
-            if (_v) {
-              {
-                int res = SWIG_AsVal_unsigned_SS_int(argv[5], NULL);
-                _v = SWIG_CheckState(res);
-              }
-              if (_v) {
-                return _wrap_new_InterferenceFunctionFinite2DLattice__SWIG_1(self, args);
-              }
-            }
+            return _wrap_InterferenceFunction2DParaCrystal_createHexagonal__SWIG_0(self, args);
           }
         }
       }
@@ -100051,28 +93164,48 @@ SWIGINTERN PyObject *_wrap_new_InterferenceFunctionFinite2DLattice(PyObject *sel
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_InterferenceFunctionFinite2DLattice'.\n"
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'InterferenceFunction2DParaCrystal_createHexagonal'.\n"
     "  Possible C/C++ prototypes are:\n"
-    "    InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice(Lattice2D const &,unsigned int,unsigned int)\n"
-    "    InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice(double,double,double,double,unsigned int,unsigned int)\n");
+    "    InterferenceFunction2DParaCrystal::createHexagonal(double,double,double,double)\n"
+    "    InterferenceFunction2DParaCrystal::createHexagonal(double,double,double)\n"
+    "    InterferenceFunction2DParaCrystal::createHexagonal(double,double)\n"
+    "    InterferenceFunction2DParaCrystal::createHexagonal(double)\n");
   return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_delete_InterferenceFunctionFinite2DLattice(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_setDomainSizes(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunctionFinite2DLattice *arg1 = (InterferenceFunctionFinite2DLattice *) 0 ;
+  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
+  double arg2 ;
+  double arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  double val3 ;
+  int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_InterferenceFunctionFinite2DLattice",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite2DLattice, SWIG_POINTER_DISOWN |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:InterferenceFunction2DParaCrystal_setDomainSizes",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_InterferenceFunctionFinite2DLattice" "', argument " "1"" of type '" "InterferenceFunctionFinite2DLattice *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_setDomainSizes" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal *""'"); 
   }
-  arg1 = reinterpret_cast< InterferenceFunctionFinite2DLattice * >(argp1);
-  delete arg1;
+  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunction2DParaCrystal_setDomainSizes" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  ecode3 = SWIG_AsVal_double(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "InterferenceFunction2DParaCrystal_setDomainSizes" "', argument " "3"" of type '" "double""'");
+  } 
+  arg3 = static_cast< double >(val3);
+  (arg1)->setDomainSizes(arg2,arg3);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -100080,51 +93213,44 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  InterferenceFunctionFinite2DLattice *arg1 = (InterferenceFunctionFinite2DLattice *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  InterferenceFunctionFinite2DLattice *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionFinite2DLattice_clone",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite2DLattice, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite2DLattice_clone" "', argument " "1"" of type '" "InterferenceFunctionFinite2DLattice const *""'"); 
-  }
-  arg1 = reinterpret_cast< InterferenceFunctionFinite2DLattice * >(argp1);
-  result = (InterferenceFunctionFinite2DLattice *)((InterferenceFunctionFinite2DLattice const *)arg1)->clone();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunctionFinite2DLattice, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_accept(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_setProbabilityDistributions(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunctionFinite2DLattice *arg1 = (InterferenceFunctionFinite2DLattice *) 0 ;
-  INodeVisitor *arg2 = (INodeVisitor *) 0 ;
+  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
+  IFTDistribution2D *arg2 = 0 ;
+  IFTDistribution2D *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
   int res2 = 0 ;
+  void *argp3 = 0 ;
+  int res3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunctionFinite2DLattice_accept",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite2DLattice, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:InterferenceFunction2DParaCrystal_setProbabilityDistributions",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite2DLattice_accept" "', argument " "1"" of type '" "InterferenceFunctionFinite2DLattice const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_setProbabilityDistributions" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal *""'"); 
   }
-  arg1 = reinterpret_cast< InterferenceFunctionFinite2DLattice * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_INodeVisitor, 0 |  0 );
+  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_IFTDistribution2D,  0  | 0);
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "InterferenceFunctionFinite2DLattice_accept" "', argument " "2"" of type '" "INodeVisitor *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "InterferenceFunction2DParaCrystal_setProbabilityDistributions" "', argument " "2"" of type '" "IFTDistribution2D const &""'"); 
   }
-  arg2 = reinterpret_cast< INodeVisitor * >(argp2);
-  ((InterferenceFunctionFinite2DLattice const *)arg1)->accept(arg2);
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "InterferenceFunction2DParaCrystal_setProbabilityDistributions" "', argument " "2"" of type '" "IFTDistribution2D const &""'"); 
+  }
+  arg2 = reinterpret_cast< IFTDistribution2D * >(argp2);
+  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_IFTDistribution2D,  0  | 0);
+  if (!SWIG_IsOK(res3)) {
+    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "InterferenceFunction2DParaCrystal_setProbabilityDistributions" "', argument " "3"" of type '" "IFTDistribution2D const &""'"); 
+  }
+  if (!argp3) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "InterferenceFunction2DParaCrystal_setProbabilityDistributions" "', argument " "3"" of type '" "IFTDistribution2D const &""'"); 
+  }
+  arg3 = reinterpret_cast< IFTDistribution2D * >(argp3);
+  (arg1)->setProbabilityDistributions((IFTDistribution2D const &)*arg2,(IFTDistribution2D const &)*arg3);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -100132,107 +93258,39 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_createSquare(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  double arg1 ;
-  double arg2 ;
-  unsigned int arg3 ;
-  unsigned int arg4 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  unsigned int val3 ;
-  int ecode3 = 0 ;
-  unsigned int val4 ;
-  int ecode4 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  PyObject * obj3 = 0 ;
-  InterferenceFunctionFinite2DLattice *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOOO:InterferenceFunctionFinite2DLattice_createSquare",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(obj0, &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "InterferenceFunctionFinite2DLattice_createSquare" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunctionFinite2DLattice_createSquare" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_unsigned_SS_int(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "InterferenceFunctionFinite2DLattice_createSquare" "', argument " "3"" of type '" "unsigned int""'");
-  } 
-  arg3 = static_cast< unsigned int >(val3);
-  ecode4 = SWIG_AsVal_unsigned_SS_int(obj3, &val4);
-  if (!SWIG_IsOK(ecode4)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "InterferenceFunctionFinite2DLattice_createSquare" "', argument " "4"" of type '" "unsigned int""'");
-  } 
-  arg4 = static_cast< unsigned int >(val4);
-  result = (InterferenceFunctionFinite2DLattice *)InterferenceFunctionFinite2DLattice::createSquare(arg1,arg2,arg3,arg4);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunctionFinite2DLattice, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_createHexagonal(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_setDampingLength(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  double arg1 ;
+  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
   double arg2 ;
-  unsigned int arg3 ;
-  unsigned int arg4 ;
-  double val1 ;
-  int ecode1 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
   double val2 ;
   int ecode2 = 0 ;
-  unsigned int val3 ;
-  int ecode3 = 0 ;
-  unsigned int val4 ;
-  int ecode4 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  PyObject * obj3 = 0 ;
-  InterferenceFunctionFinite2DLattice *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOOO:InterferenceFunctionFinite2DLattice_createHexagonal",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(obj0, &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "InterferenceFunctionFinite2DLattice_createHexagonal" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
+  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunction2DParaCrystal_setDampingLength",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_setDampingLength" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
   ecode2 = SWIG_AsVal_double(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunctionFinite2DLattice_createHexagonal" "', argument " "2"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunction2DParaCrystal_setDampingLength" "', argument " "2"" of type '" "double""'");
   } 
   arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_unsigned_SS_int(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "InterferenceFunctionFinite2DLattice_createHexagonal" "', argument " "3"" of type '" "unsigned int""'");
-  } 
-  arg3 = static_cast< unsigned int >(val3);
-  ecode4 = SWIG_AsVal_unsigned_SS_int(obj3, &val4);
-  if (!SWIG_IsOK(ecode4)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "InterferenceFunctionFinite2DLattice_createHexagonal" "', argument " "4"" of type '" "unsigned int""'");
-  } 
-  arg4 = static_cast< unsigned int >(val4);
-  result = (InterferenceFunctionFinite2DLattice *)InterferenceFunctionFinite2DLattice::createHexagonal(arg1,arg2,arg3,arg4);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunctionFinite2DLattice, SWIG_POINTER_OWN |  0 );
+  (arg1)->setDampingLength(arg2);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_evaluate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_evaluate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunctionFinite2DLattice *arg1 = (InterferenceFunctionFinite2DLattice *) 0 ;
+  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
   kvector_t arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
@@ -100242,26 +93300,26 @@ SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_evaluate(PyObject
   PyObject * obj1 = 0 ;
   double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunctionFinite2DLattice_evaluate",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite2DLattice, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunction2DParaCrystal_evaluate",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite2DLattice_evaluate" "', argument " "1"" of type '" "InterferenceFunctionFinite2DLattice const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_evaluate" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal const *""'"); 
   }
-  arg1 = reinterpret_cast< InterferenceFunctionFinite2DLattice * >(argp1);
+  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
   {
     res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_BasicVector3DT_double_t,  0  | 0);
     if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "InterferenceFunctionFinite2DLattice_evaluate" "', argument " "2"" of type '" "kvector_t const""'"); 
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "InterferenceFunction2DParaCrystal_evaluate" "', argument " "2"" of type '" "kvector_t const""'"); 
     }  
     if (!argp2) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "InterferenceFunctionFinite2DLattice_evaluate" "', argument " "2"" of type '" "kvector_t const""'");
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "InterferenceFunction2DParaCrystal_evaluate" "', argument " "2"" of type '" "kvector_t const""'");
     } else {
       kvector_t * temp = reinterpret_cast< kvector_t * >(argp2);
       arg2 = *temp;
       if (SWIG_IsNewObj(res2)) delete temp;
     }
   }
-  result = (double)((InterferenceFunctionFinite2DLattice const *)arg1)->evaluate(arg2);
+  result = (double)((InterferenceFunction2DParaCrystal const *)arg1)->evaluate(arg2);
   resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
@@ -100269,95 +93327,95 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_domainSize1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_domainSizes(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunctionFinite2DLattice *arg1 = (InterferenceFunctionFinite2DLattice *) 0 ;
+  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  unsigned int result;
+  std::vector< double,std::allocator< double > > result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionFinite2DLattice_domainSize1",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite2DLattice, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction2DParaCrystal_domainSizes",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite2DLattice_domainSize1" "', argument " "1"" of type '" "InterferenceFunctionFinite2DLattice const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_domainSizes" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal const *""'"); 
   }
-  arg1 = reinterpret_cast< InterferenceFunctionFinite2DLattice * >(argp1);
-  result = (unsigned int)((InterferenceFunctionFinite2DLattice const *)arg1)->domainSize1();
-  resultobj = SWIG_From_unsigned_SS_int(static_cast< unsigned int >(result));
+  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
+  result = ((InterferenceFunction2DParaCrystal const *)arg1)->domainSizes();
+  resultobj = swig::from(static_cast< std::vector< double,std::allocator< double > > >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_domainSize2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_setIntegrationOverXi(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunctionFinite2DLattice *arg1 = (InterferenceFunctionFinite2DLattice *) 0 ;
+  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
+  bool arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  bool val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  unsigned int result;
+  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionFinite2DLattice_domainSize2",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite2DLattice, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunction2DParaCrystal_setIntegrationOverXi",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite2DLattice_domainSize2" "', argument " "1"" of type '" "InterferenceFunctionFinite2DLattice const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_setIntegrationOverXi" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal *""'"); 
   }
-  arg1 = reinterpret_cast< InterferenceFunctionFinite2DLattice * >(argp1);
-  result = (unsigned int)((InterferenceFunctionFinite2DLattice const *)arg1)->domainSize2();
-  resultobj = SWIG_From_unsigned_SS_int(static_cast< unsigned int >(result));
+  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
+  ecode2 = SWIG_AsVal_bool(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunction2DParaCrystal_setIntegrationOverXi" "', argument " "2"" of type '" "bool""'");
+  } 
+  arg2 = static_cast< bool >(val2);
+  (arg1)->setIntegrationOverXi(arg2);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_setPositionVariance(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_integrationOverXi(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunctionFinite2DLattice *arg1 = (InterferenceFunctionFinite2DLattice *) 0 ;
-  double arg2 ;
+  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunctionFinite2DLattice_setPositionVariance",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite2DLattice, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction2DParaCrystal_integrationOverXi",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite2DLattice_setPositionVariance" "', argument " "1"" of type '" "InterferenceFunctionFinite2DLattice *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_integrationOverXi" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal const *""'"); 
   }
-  arg1 = reinterpret_cast< InterferenceFunctionFinite2DLattice * >(argp1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunctionFinite2DLattice_setPositionVariance" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  (arg1)->setPositionVariance(arg2);
-  resultobj = SWIG_Py_Void();
+  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
+  result = (bool)((InterferenceFunction2DParaCrystal const *)arg1)->integrationOverXi();
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_positionVariance(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_dampingLength(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunctionFinite2DLattice *arg1 = (InterferenceFunctionFinite2DLattice *) 0 ;
+  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
   double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionFinite2DLattice_positionVariance",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite2DLattice, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction2DParaCrystal_dampingLength",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite2DLattice_positionVariance" "', argument " "1"" of type '" "InterferenceFunctionFinite2DLattice const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_dampingLength" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal const *""'"); 
   }
-  arg1 = reinterpret_cast< InterferenceFunctionFinite2DLattice * >(argp1);
-  result = (double)((InterferenceFunctionFinite2DLattice const *)arg1)->positionVariance();
+  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
+  result = (double)((InterferenceFunction2DParaCrystal const *)arg1)->dampingLength();
   resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
@@ -100365,128 +93423,120 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_setIntegrationOverXi(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_lattice(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunctionFinite2DLattice *arg1 = (InterferenceFunctionFinite2DLattice *) 0 ;
-  bool arg2 ;
+  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  bool val2 ;
-  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  Lattice2D *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunctionFinite2DLattice_setIntegrationOverXi",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite2DLattice, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction2DParaCrystal_lattice",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite2DLattice_setIntegrationOverXi" "', argument " "1"" of type '" "InterferenceFunctionFinite2DLattice *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_lattice" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal const *""'"); 
   }
-  arg1 = reinterpret_cast< InterferenceFunctionFinite2DLattice * >(argp1);
-  ecode2 = SWIG_AsVal_bool(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunctionFinite2DLattice_setIntegrationOverXi" "', argument " "2"" of type '" "bool""'");
-  } 
-  arg2 = static_cast< bool >(val2);
-  (arg1)->setIntegrationOverXi(arg2);
-  resultobj = SWIG_Py_Void();
+  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
+  result = (Lattice2D *) &((InterferenceFunction2DParaCrystal const *)arg1)->lattice();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Lattice2D, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_integrationOverXi(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_getParticleDensity(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunctionFinite2DLattice *arg1 = (InterferenceFunctionFinite2DLattice *) 0 ;
+  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  bool result;
+  double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionFinite2DLattice_integrationOverXi",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite2DLattice, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction2DParaCrystal_getParticleDensity",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite2DLattice_integrationOverXi" "', argument " "1"" of type '" "InterferenceFunctionFinite2DLattice const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_getParticleDensity" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal const *""'"); 
   }
-  arg1 = reinterpret_cast< InterferenceFunctionFinite2DLattice * >(argp1);
-  result = (bool)((InterferenceFunctionFinite2DLattice const *)arg1)->integrationOverXi();
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
+  result = (double)((InterferenceFunction2DParaCrystal const *)arg1)->getParticleDensity();
+  resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_lattice(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_getChildren(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunctionFinite2DLattice *arg1 = (InterferenceFunctionFinite2DLattice *) 0 ;
+  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  Lattice2D *result = 0 ;
+  std::vector< INode const *,std::allocator< INode const * > > result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionFinite2DLattice_lattice",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite2DLattice, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction2DParaCrystal_getChildren",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite2DLattice_lattice" "', argument " "1"" of type '" "InterferenceFunctionFinite2DLattice const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_getChildren" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal const *""'"); 
   }
-  arg1 = reinterpret_cast< InterferenceFunctionFinite2DLattice * >(argp1);
-  result = (Lattice2D *) &((InterferenceFunctionFinite2DLattice const *)arg1)->lattice();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Lattice2D, 0 |  0 );
+  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
+  result = ((InterferenceFunction2DParaCrystal const *)arg1)->getChildren();
+  resultobj = swig::from(static_cast< std::vector< INode const*,std::allocator< INode const * > > >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_getParticleDensity(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_pdf1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunctionFinite2DLattice *arg1 = (InterferenceFunctionFinite2DLattice *) 0 ;
+  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  double result;
+  IFTDistribution2D *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionFinite2DLattice_getParticleDensity",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite2DLattice, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction2DParaCrystal_pdf1",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite2DLattice_getParticleDensity" "', argument " "1"" of type '" "InterferenceFunctionFinite2DLattice const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_pdf1" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal const *""'"); 
   }
-  arg1 = reinterpret_cast< InterferenceFunctionFinite2DLattice * >(argp1);
-  result = (double)((InterferenceFunctionFinite2DLattice const *)arg1)->getParticleDensity();
-  resultobj = SWIG_From_double(static_cast< double >(result));
+  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
+  result = (IFTDistribution2D *)((InterferenceFunction2DParaCrystal const *)arg1)->pdf1();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IFTDistribution2D, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_getChildren(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_pdf2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunctionFinite2DLattice *arg1 = (InterferenceFunctionFinite2DLattice *) 0 ;
+  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  std::vector< INode const *,std::allocator< INode const * > > result;
+  IFTDistribution2D *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionFinite2DLattice_getChildren",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite2DLattice, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction2DParaCrystal_pdf2",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite2DLattice_getChildren" "', argument " "1"" of type '" "InterferenceFunctionFinite2DLattice const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_pdf2" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal const *""'"); 
   }
-  arg1 = reinterpret_cast< InterferenceFunctionFinite2DLattice * >(argp1);
-  result = ((InterferenceFunctionFinite2DLattice const *)arg1)->getChildren();
-  resultobj = swig::from(static_cast< std::vector< INode const*,std::allocator< INode const * > > >(result));
+  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
+  result = (IFTDistribution2D *)((InterferenceFunction2DParaCrystal const *)arg1)->pdf2();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IFTDistribution2D, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *InterferenceFunctionFinite2DLattice_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *InterferenceFunction2DParaCrystal_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
   if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_InterferenceFunctionFinite2DLattice, SWIG_NewClientData(obj));
+  SWIG_TypeNewClientData(SWIGTYPE_p_InterferenceFunction2DParaCrystal, SWIG_NewClientData(obj));
   return SWIG_Py_Void();
 }
 
@@ -101153,104 +94203,140 @@ SWIGINTERN PyObject *InterferenceFunction2DSuperLattice_swigregister(PyObject *S
   return SWIG_Py_Void();
 }
 
-SWIGINTERN PyObject *_wrap_new_InterferenceFunction2DParaCrystal__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_InterferenceFunction3DLattice(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  Lattice2D *arg1 = 0 ;
-  double arg2 ;
-  double arg3 ;
-  double arg4 ;
+  Lattice *arg1 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
-  double val4 ;
-  int ecode4 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  PyObject * obj3 = 0 ;
-  InterferenceFunction2DParaCrystal *result = 0 ;
+  InterferenceFunction3DLattice *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOOO:new_InterferenceFunction2DParaCrystal",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_Lattice2D,  0  | 0);
+  if (!PyArg_ParseTuple(args,(char *)"O:new_InterferenceFunction3DLattice",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_Lattice,  0  | 0);
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "1"" of type '" "Lattice2D const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_InterferenceFunction3DLattice" "', argument " "1"" of type '" "Lattice const &""'"); 
   }
   if (!argp1) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "1"" of type '" "Lattice2D const &""'"); 
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_InterferenceFunction3DLattice" "', argument " "1"" of type '" "Lattice const &""'"); 
   }
-  arg1 = reinterpret_cast< Lattice2D * >(argp1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  ecode4 = SWIG_AsVal_double(obj3, &val4);
-  if (!SWIG_IsOK(ecode4)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "4"" of type '" "double""'");
-  } 
-  arg4 = static_cast< double >(val4);
-  result = (InterferenceFunction2DParaCrystal *)new InterferenceFunction2DParaCrystal((Lattice2D const &)*arg1,arg2,arg3,arg4);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, SWIG_POINTER_NEW |  0 );
+  arg1 = reinterpret_cast< Lattice * >(argp1);
+  result = (InterferenceFunction3DLattice *)new InterferenceFunction3DLattice((Lattice const &)*arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction3DLattice, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_new_InterferenceFunction2DParaCrystal__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_delete_InterferenceFunction3DLattice(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  Lattice2D *arg1 = 0 ;
-  double arg2 ;
-  double arg3 ;
+  InterferenceFunction3DLattice *arg1 = (InterferenceFunction3DLattice *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:delete_InterferenceFunction3DLattice",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction3DLattice, SWIG_POINTER_DISOWN |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_InterferenceFunction3DLattice" "', argument " "1"" of type '" "InterferenceFunction3DLattice *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunction3DLattice * >(argp1);
+  delete arg1;
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_InterferenceFunction3DLattice_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  InterferenceFunction3DLattice *arg1 = (InterferenceFunction3DLattice *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
+  PyObject * obj0 = 0 ;
+  InterferenceFunction3DLattice *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction3DLattice_clone",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction3DLattice, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction3DLattice_clone" "', argument " "1"" of type '" "InterferenceFunction3DLattice const *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunction3DLattice * >(argp1);
+  result = (InterferenceFunction3DLattice *)((InterferenceFunction3DLattice const *)arg1)->clone();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction3DLattice, 0 |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_InterferenceFunction3DLattice_accept(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  InterferenceFunction3DLattice *arg1 = (InterferenceFunction3DLattice *) 0 ;
+  INodeVisitor *arg2 = (INodeVisitor *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  InterferenceFunction2DParaCrystal *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:new_InterferenceFunction2DParaCrystal",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_Lattice2D,  0  | 0);
+  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunction3DLattice_accept",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction3DLattice, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "1"" of type '" "Lattice2D const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction3DLattice_accept" "', argument " "1"" of type '" "InterferenceFunction3DLattice const *""'"); 
   }
-  if (!argp1) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "1"" of type '" "Lattice2D const &""'"); 
+  arg1 = reinterpret_cast< InterferenceFunction3DLattice * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_INodeVisitor, 0 |  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "InterferenceFunction3DLattice_accept" "', argument " "2"" of type '" "INodeVisitor *""'"); 
   }
-  arg1 = reinterpret_cast< Lattice2D * >(argp1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  result = (InterferenceFunction2DParaCrystal *)new InterferenceFunction2DParaCrystal((Lattice2D const &)*arg1,arg2,arg3);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, SWIG_POINTER_NEW |  0 );
+  arg2 = reinterpret_cast< INodeVisitor * >(argp2);
+  ((InterferenceFunction3DLattice const *)arg1)->accept(arg2);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_new_InterferenceFunction2DParaCrystal__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunction3DLattice_setPeakShape(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  Lattice2D *arg1 = 0 ;
+  InterferenceFunction3DLattice *arg1 = (InterferenceFunction3DLattice *) 0 ;
+  IPeakShape *arg2 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunction3DLattice_setPeakShape",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction3DLattice, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction3DLattice_setPeakShape" "', argument " "1"" of type '" "InterferenceFunction3DLattice *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunction3DLattice * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_IPeakShape,  0  | 0);
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "InterferenceFunction3DLattice_setPeakShape" "', argument " "2"" of type '" "IPeakShape const &""'"); 
+  }
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "InterferenceFunction3DLattice_setPeakShape" "', argument " "2"" of type '" "IPeakShape const &""'"); 
+  }
+  arg2 = reinterpret_cast< IPeakShape * >(argp2);
+  (arg1)->setPeakShape((IPeakShape const &)*arg2);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_InterferenceFunction3DLattice_setDebyeWallerFactor(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  InterferenceFunction3DLattice *arg1 = (InterferenceFunction3DLattice *) 0 ;
   double arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
@@ -101258,119 +94344,210 @@ SWIGINTERN PyObject *_wrap_new_InterferenceFunction2DParaCrystal__SWIG_2(PyObjec
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  InterferenceFunction2DParaCrystal *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:new_InterferenceFunction2DParaCrystal",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_Lattice2D,  0  | 0);
+  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunction3DLattice_setDebyeWallerFactor",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction3DLattice, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "1"" of type '" "Lattice2D const &""'"); 
-  }
-  if (!argp1) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "1"" of type '" "Lattice2D const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction3DLattice_setDebyeWallerFactor" "', argument " "1"" of type '" "InterferenceFunction3DLattice *""'"); 
   }
-  arg1 = reinterpret_cast< Lattice2D * >(argp1);
+  arg1 = reinterpret_cast< InterferenceFunction3DLattice * >(argp1);
   ecode2 = SWIG_AsVal_double(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "2"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunction3DLattice_setDebyeWallerFactor" "', argument " "2"" of type '" "double""'");
   } 
   arg2 = static_cast< double >(val2);
-  result = (InterferenceFunction2DParaCrystal *)new InterferenceFunction2DParaCrystal((Lattice2D const &)*arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, SWIG_POINTER_NEW |  0 );
+  (arg1)->setDebyeWallerFactor(arg2);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_new_InterferenceFunction2DParaCrystal__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunction3DLattice_evaluate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  Lattice2D *arg1 = 0 ;
+  InterferenceFunction3DLattice *arg1 = (InterferenceFunction3DLattice *) 0 ;
+  kvector_t arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  void *argp2 ;
+  int res2 = 0 ;
   PyObject * obj0 = 0 ;
-  InterferenceFunction2DParaCrystal *result = 0 ;
+  PyObject * obj1 = 0 ;
+  double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:new_InterferenceFunction2DParaCrystal",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_Lattice2D,  0  | 0);
+  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunction3DLattice_evaluate",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction3DLattice, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "1"" of type '" "Lattice2D const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction3DLattice_evaluate" "', argument " "1"" of type '" "InterferenceFunction3DLattice const *""'"); 
   }
-  if (!argp1) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "1"" of type '" "Lattice2D const &""'"); 
+  arg1 = reinterpret_cast< InterferenceFunction3DLattice * >(argp1);
+  {
+    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_BasicVector3DT_double_t,  0  | 0);
+    if (!SWIG_IsOK(res2)) {
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "InterferenceFunction3DLattice_evaluate" "', argument " "2"" of type '" "kvector_t const""'"); 
+    }  
+    if (!argp2) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "InterferenceFunction3DLattice_evaluate" "', argument " "2"" of type '" "kvector_t const""'");
+    } else {
+      kvector_t * temp = reinterpret_cast< kvector_t * >(argp2);
+      arg2 = *temp;
+      if (SWIG_IsNewObj(res2)) delete temp;
+    }
   }
-  arg1 = reinterpret_cast< Lattice2D * >(argp1);
-  result = (InterferenceFunction2DParaCrystal *)new InterferenceFunction2DParaCrystal((Lattice2D const &)*arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, SWIG_POINTER_NEW |  0 );
+  result = (double)((InterferenceFunction3DLattice const *)arg1)->evaluate(arg2);
+  resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_new_InterferenceFunction2DParaCrystal__SWIG_4(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunction3DLattice_lattice(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  double arg1 ;
-  double arg2 ;
-  double arg3 ;
-  double arg4 ;
-  double arg5 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  double val2 ;
+  InterferenceFunction3DLattice *arg1 = (InterferenceFunction3DLattice *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  Lattice *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction3DLattice_lattice",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction3DLattice, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction3DLattice_lattice" "', argument " "1"" of type '" "InterferenceFunction3DLattice const *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunction3DLattice * >(argp1);
+  result = (Lattice *) &((InterferenceFunction3DLattice const *)arg1)->lattice();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Lattice, 0 |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_InterferenceFunction3DLattice_supportsMultilayer(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  InterferenceFunction3DLattice *arg1 = (InterferenceFunction3DLattice *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  bool result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction3DLattice_supportsMultilayer",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction3DLattice, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction3DLattice_supportsMultilayer" "', argument " "1"" of type '" "InterferenceFunction3DLattice const *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunction3DLattice * >(argp1);
+  result = (bool)((InterferenceFunction3DLattice const *)arg1)->supportsMultilayer();
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_InterferenceFunction3DLattice_getChildren(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  InterferenceFunction3DLattice *arg1 = (InterferenceFunction3DLattice *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::vector< INode const *,std::allocator< INode const * > > result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction3DLattice_getChildren",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction3DLattice, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction3DLattice_getChildren" "', argument " "1"" of type '" "InterferenceFunction3DLattice const *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunction3DLattice * >(argp1);
+  result = ((InterferenceFunction3DLattice const *)arg1)->getChildren();
+  resultobj = swig::from(static_cast< std::vector< INode const*,std::allocator< INode const * > > >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_InterferenceFunction3DLattice_onChange(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  InterferenceFunction3DLattice *arg1 = (InterferenceFunction3DLattice *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction3DLattice_onChange",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction3DLattice, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction3DLattice_onChange" "', argument " "1"" of type '" "InterferenceFunction3DLattice *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunction3DLattice * >(argp1);
+  (arg1)->onChange();
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *InterferenceFunction3DLattice_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *obj;
+  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_InterferenceFunction3DLattice, SWIG_NewClientData(obj));
+  return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *_wrap_new_InterferenceFunctionFinite2DLattice__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Lattice2D *arg1 = 0 ;
+  unsigned int arg2 ;
+  unsigned int arg3 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  unsigned int val2 ;
   int ecode2 = 0 ;
-  double val3 ;
+  unsigned int val3 ;
   int ecode3 = 0 ;
-  double val4 ;
-  int ecode4 = 0 ;
-  double val5 ;
-  int ecode5 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
-  PyObject * obj3 = 0 ;
-  PyObject * obj4 = 0 ;
-  InterferenceFunction2DParaCrystal *result = 0 ;
+  InterferenceFunctionFinite2DLattice *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOOOO:new_InterferenceFunction2DParaCrystal",&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(obj0, &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!PyArg_ParseTuple(args,(char *)"OOO:new_InterferenceFunctionFinite2DLattice",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_Lattice2D,  0  | 0);
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_InterferenceFunctionFinite2DLattice" "', argument " "1"" of type '" "Lattice2D const &""'"); 
+  }
+  if (!argp1) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_InterferenceFunctionFinite2DLattice" "', argument " "1"" of type '" "Lattice2D const &""'"); 
+  }
+  arg1 = reinterpret_cast< Lattice2D * >(argp1);
+  ecode2 = SWIG_AsVal_unsigned_SS_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "2"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_InterferenceFunctionFinite2DLattice" "', argument " "2"" of type '" "unsigned int""'");
   } 
-  arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
+  arg2 = static_cast< unsigned int >(val2);
+  ecode3 = SWIG_AsVal_unsigned_SS_int(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  ecode4 = SWIG_AsVal_double(obj3, &val4);
-  if (!SWIG_IsOK(ecode4)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "4"" of type '" "double""'");
-  } 
-  arg4 = static_cast< double >(val4);
-  ecode5 = SWIG_AsVal_double(obj4, &val5);
-  if (!SWIG_IsOK(ecode5)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "5"" of type '" "double""'");
-  } 
-  arg5 = static_cast< double >(val5);
-  result = (InterferenceFunction2DParaCrystal *)new InterferenceFunction2DParaCrystal(arg1,arg2,arg3,arg4,arg5);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, SWIG_POINTER_NEW |  0 );
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_InterferenceFunctionFinite2DLattice" "', argument " "3"" of type '" "unsigned int""'");
+  } 
+  arg3 = static_cast< unsigned int >(val3);
+  result = (InterferenceFunctionFinite2DLattice *)new InterferenceFunctionFinite2DLattice((Lattice2D const &)*arg1,arg2,arg3);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunctionFinite2DLattice, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_new_InterferenceFunction2DParaCrystal__SWIG_5(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_InterferenceFunctionFinite2DLattice__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   double arg1 ;
   double arg2 ;
   double arg3 ;
   double arg4 ;
+  unsigned int arg5 ;
+  unsigned int arg6 ;
   double val1 ;
   int ecode1 = 0 ;
   double val2 ;
@@ -101379,212 +94556,90 @@ SWIGINTERN PyObject *_wrap_new_InterferenceFunction2DParaCrystal__SWIG_5(PyObjec
   int ecode3 = 0 ;
   double val4 ;
   int ecode4 = 0 ;
+  unsigned int val5 ;
+  int ecode5 = 0 ;
+  unsigned int val6 ;
+  int ecode6 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
   PyObject * obj3 = 0 ;
-  InterferenceFunction2DParaCrystal *result = 0 ;
+  PyObject * obj4 = 0 ;
+  PyObject * obj5 = 0 ;
+  InterferenceFunctionFinite2DLattice *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOOO:new_InterferenceFunction2DParaCrystal",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+  if (!PyArg_ParseTuple(args,(char *)"OOOOOO:new_InterferenceFunctionFinite2DLattice",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5)) SWIG_fail;
   ecode1 = SWIG_AsVal_double(obj0, &val1);
   if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "1"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_InterferenceFunctionFinite2DLattice" "', argument " "1"" of type '" "double""'");
   } 
   arg1 = static_cast< double >(val1);
   ecode2 = SWIG_AsVal_double(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "2"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_InterferenceFunctionFinite2DLattice" "', argument " "2"" of type '" "double""'");
   } 
   arg2 = static_cast< double >(val2);
   ecode3 = SWIG_AsVal_double(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "3"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_InterferenceFunctionFinite2DLattice" "', argument " "3"" of type '" "double""'");
   } 
   arg3 = static_cast< double >(val3);
   ecode4 = SWIG_AsVal_double(obj3, &val4);
   if (!SWIG_IsOK(ecode4)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "4"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "new_InterferenceFunctionFinite2DLattice" "', argument " "4"" of type '" "double""'");
   } 
   arg4 = static_cast< double >(val4);
-  result = (InterferenceFunction2DParaCrystal *)new InterferenceFunction2DParaCrystal(arg1,arg2,arg3,arg4);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_InterferenceFunction2DParaCrystal__SWIG_6(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  double arg1 ;
-  double arg2 ;
-  double arg3 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  InterferenceFunction2DParaCrystal *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOO:new_InterferenceFunction2DParaCrystal",&obj0,&obj1,&obj2)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(obj0, &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "2"" of type '" "double""'");
+  ecode5 = SWIG_AsVal_unsigned_SS_int(obj4, &val5);
+  if (!SWIG_IsOK(ecode5)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "new_InterferenceFunctionFinite2DLattice" "', argument " "5"" of type '" "unsigned int""'");
   } 
-  arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_InterferenceFunction2DParaCrystal" "', argument " "3"" of type '" "double""'");
+  arg5 = static_cast< unsigned int >(val5);
+  ecode6 = SWIG_AsVal_unsigned_SS_int(obj5, &val6);
+  if (!SWIG_IsOK(ecode6)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "new_InterferenceFunctionFinite2DLattice" "', argument " "6"" of type '" "unsigned int""'");
   } 
-  arg3 = static_cast< double >(val3);
-  result = (InterferenceFunction2DParaCrystal *)new InterferenceFunction2DParaCrystal(arg1,arg2,arg3);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, SWIG_POINTER_NEW |  0 );
+  arg6 = static_cast< unsigned int >(val6);
+  result = (InterferenceFunctionFinite2DLattice *)new InterferenceFunctionFinite2DLattice(arg1,arg2,arg3,arg4,arg5,arg6);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunctionFinite2DLattice, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_new_InterferenceFunction2DParaCrystal(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_InterferenceFunctionFinite2DLattice(PyObject *self, PyObject *args) {
   Py_ssize_t argc;
-  PyObject *argv[6] = {
+  PyObject *argv[7] = {
     0
   };
   Py_ssize_t ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
   argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 5) && (ii < argc); ii++) {
+  for (ii = 0; (ii < 6) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  if (argc == 1) {
-    int _v;
-    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_Lattice2D, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_new_InterferenceFunction2DParaCrystal__SWIG_3(self, args);
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_Lattice2D, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_double(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_new_InterferenceFunction2DParaCrystal__SWIG_2(self, args);
-      }
-    }
-  }
-  if (argc == 3) {
-    int _v;
-    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_Lattice2D, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_double(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        {
-          int res = SWIG_AsVal_double(argv[2], NULL);
-          _v = SWIG_CheckState(res);
-        }
-        if (_v) {
-          return _wrap_new_InterferenceFunction2DParaCrystal__SWIG_1(self, args);
-        }
-      }
-    }
-  }
   if (argc == 3) {
-    int _v;
-    {
-      int res = SWIG_AsVal_double(argv[0], NULL);
-      _v = SWIG_CheckState(res);
-    }
-    if (_v) {
-      {
-        int res = SWIG_AsVal_double(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        {
-          int res = SWIG_AsVal_double(argv[2], NULL);
-          _v = SWIG_CheckState(res);
-        }
-        if (_v) {
-          return _wrap_new_InterferenceFunction2DParaCrystal__SWIG_6(self, args);
-        }
-      }
-    }
-  }
-  if (argc == 4) {
     int _v;
     int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_Lattice2D, 0);
     _v = SWIG_CheckState(res);
     if (_v) {
       {
-        int res = SWIG_AsVal_double(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        {
-          int res = SWIG_AsVal_double(argv[2], NULL);
-          _v = SWIG_CheckState(res);
-        }
-        if (_v) {
-          {
-            int res = SWIG_AsVal_double(argv[3], NULL);
-            _v = SWIG_CheckState(res);
-          }
-          if (_v) {
-            return _wrap_new_InterferenceFunction2DParaCrystal__SWIG_0(self, args);
-          }
-        }
-      }
-    }
-  }
-  if (argc == 4) {
-    int _v;
-    {
-      int res = SWIG_AsVal_double(argv[0], NULL);
-      _v = SWIG_CheckState(res);
-    }
-    if (_v) {
-      {
-        int res = SWIG_AsVal_double(argv[1], NULL);
+        int res = SWIG_AsVal_unsigned_SS_int(argv[1], NULL);
         _v = SWIG_CheckState(res);
       }
       if (_v) {
         {
-          int res = SWIG_AsVal_double(argv[2], NULL);
+          int res = SWIG_AsVal_unsigned_SS_int(argv[2], NULL);
           _v = SWIG_CheckState(res);
         }
         if (_v) {
-          {
-            int res = SWIG_AsVal_double(argv[3], NULL);
-            _v = SWIG_CheckState(res);
-          }
-          if (_v) {
-            return _wrap_new_InterferenceFunction2DParaCrystal__SWIG_5(self, args);
-          }
+          return _wrap_new_InterferenceFunctionFinite2DLattice__SWIG_0(self, args);
         }
       }
     }
   }
-  if (argc == 5) {
+  if (argc == 6) {
     int _v;
     {
       int res = SWIG_AsVal_double(argv[0], NULL);
@@ -101607,11 +94662,17 @@ SWIGINTERN PyObject *_wrap_new_InterferenceFunction2DParaCrystal(PyObject *self,
           }
           if (_v) {
             {
-              int res = SWIG_AsVal_double(argv[4], NULL);
+              int res = SWIG_AsVal_unsigned_SS_int(argv[4], NULL);
               _v = SWIG_CheckState(res);
             }
             if (_v) {
-              return _wrap_new_InterferenceFunction2DParaCrystal__SWIG_4(self, args);
+              {
+                int res = SWIG_AsVal_unsigned_SS_int(argv[5], NULL);
+                _v = SWIG_CheckState(res);
+              }
+              if (_v) {
+                return _wrap_new_InterferenceFunctionFinite2DLattice__SWIG_1(self, args);
+              }
             }
           }
         }
@@ -101620,32 +94681,27 @@ SWIGINTERN PyObject *_wrap_new_InterferenceFunction2DParaCrystal(PyObject *self,
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_InterferenceFunction2DParaCrystal'.\n"
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_InterferenceFunctionFinite2DLattice'.\n"
     "  Possible C/C++ prototypes are:\n"
-    "    InterferenceFunction2DParaCrystal::InterferenceFunction2DParaCrystal(Lattice2D const &,double,double,double)\n"
-    "    InterferenceFunction2DParaCrystal::InterferenceFunction2DParaCrystal(Lattice2D const &,double,double)\n"
-    "    InterferenceFunction2DParaCrystal::InterferenceFunction2DParaCrystal(Lattice2D const &,double)\n"
-    "    InterferenceFunction2DParaCrystal::InterferenceFunction2DParaCrystal(Lattice2D const &)\n"
-    "    InterferenceFunction2DParaCrystal::InterferenceFunction2DParaCrystal(double,double,double,double,double)\n"
-    "    InterferenceFunction2DParaCrystal::InterferenceFunction2DParaCrystal(double,double,double,double)\n"
-    "    InterferenceFunction2DParaCrystal::InterferenceFunction2DParaCrystal(double,double,double)\n");
+    "    InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice(Lattice2D const &,unsigned int,unsigned int)\n"
+    "    InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice(double,double,double,double,unsigned int,unsigned int)\n");
   return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_delete_InterferenceFunction2DParaCrystal(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_delete_InterferenceFunctionFinite2DLattice(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
+  InterferenceFunctionFinite2DLattice *arg1 = (InterferenceFunctionFinite2DLattice *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_InterferenceFunction2DParaCrystal",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, SWIG_POINTER_DISOWN |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:delete_InterferenceFunctionFinite2DLattice",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite2DLattice, SWIG_POINTER_DISOWN |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_InterferenceFunction2DParaCrystal" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_InterferenceFunctionFinite2DLattice" "', argument " "1"" of type '" "InterferenceFunctionFinite2DLattice *""'"); 
   }
-  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
+  arg1 = reinterpret_cast< InterferenceFunctionFinite2DLattice * >(argp1);
   delete arg1;
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -101654,31 +94710,31 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
+  InterferenceFunctionFinite2DLattice *arg1 = (InterferenceFunctionFinite2DLattice *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  InterferenceFunction2DParaCrystal *result = 0 ;
+  InterferenceFunctionFinite2DLattice *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction2DParaCrystal_clone",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionFinite2DLattice_clone",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite2DLattice, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_clone" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite2DLattice_clone" "', argument " "1"" of type '" "InterferenceFunctionFinite2DLattice const *""'"); 
   }
-  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
-  result = (InterferenceFunction2DParaCrystal *)((InterferenceFunction2DParaCrystal const *)arg1)->clone();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
+  arg1 = reinterpret_cast< InterferenceFunctionFinite2DLattice * >(argp1);
+  result = (InterferenceFunctionFinite2DLattice *)((InterferenceFunctionFinite2DLattice const *)arg1)->clone();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunctionFinite2DLattice, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_accept(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_accept(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
+  InterferenceFunctionFinite2DLattice *arg1 = (InterferenceFunctionFinite2DLattice *) 0 ;
   INodeVisitor *arg2 = (INodeVisitor *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
@@ -101687,18 +94743,18 @@ SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_accept(PyObject *SW
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunction2DParaCrystal_accept",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunctionFinite2DLattice_accept",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite2DLattice, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_accept" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite2DLattice_accept" "', argument " "1"" of type '" "InterferenceFunctionFinite2DLattice const *""'"); 
   }
-  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
+  arg1 = reinterpret_cast< InterferenceFunctionFinite2DLattice * >(argp1);
   res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_INodeVisitor, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "InterferenceFunction2DParaCrystal_accept" "', argument " "2"" of type '" "INodeVisitor *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "InterferenceFunctionFinite2DLattice_accept" "', argument " "2"" of type '" "INodeVisitor *""'"); 
   }
   arg2 = reinterpret_cast< INodeVisitor * >(argp2);
-  ((InterferenceFunction2DParaCrystal const *)arg1)->accept(arg2);
+  ((InterferenceFunctionFinite2DLattice const *)arg1)->accept(arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -101706,688 +94762,482 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_createSquare__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_createSquare(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   double arg1 ;
   double arg2 ;
-  double arg3 ;
-  double arg4 ;
+  unsigned int arg3 ;
+  unsigned int arg4 ;
   double val1 ;
   int ecode1 = 0 ;
   double val2 ;
   int ecode2 = 0 ;
-  double val3 ;
+  unsigned int val3 ;
   int ecode3 = 0 ;
-  double val4 ;
+  unsigned int val4 ;
   int ecode4 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
   PyObject * obj3 = 0 ;
-  InterferenceFunction2DParaCrystal *result = 0 ;
+  InterferenceFunctionFinite2DLattice *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOOO:InterferenceFunction2DParaCrystal_createSquare",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+  if (!PyArg_ParseTuple(args,(char *)"OOOO:InterferenceFunctionFinite2DLattice_createSquare",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
   ecode1 = SWIG_AsVal_double(obj0, &val1);
   if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "InterferenceFunction2DParaCrystal_createSquare" "', argument " "1"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "InterferenceFunctionFinite2DLattice_createSquare" "', argument " "1"" of type '" "double""'");
   } 
   arg1 = static_cast< double >(val1);
   ecode2 = SWIG_AsVal_double(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunction2DParaCrystal_createSquare" "', argument " "2"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunctionFinite2DLattice_createSquare" "', argument " "2"" of type '" "double""'");
   } 
   arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
+  ecode3 = SWIG_AsVal_unsigned_SS_int(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "InterferenceFunction2DParaCrystal_createSquare" "', argument " "3"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "InterferenceFunctionFinite2DLattice_createSquare" "', argument " "3"" of type '" "unsigned int""'");
   } 
-  arg3 = static_cast< double >(val3);
-  ecode4 = SWIG_AsVal_double(obj3, &val4);
+  arg3 = static_cast< unsigned int >(val3);
+  ecode4 = SWIG_AsVal_unsigned_SS_int(obj3, &val4);
   if (!SWIG_IsOK(ecode4)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "InterferenceFunction2DParaCrystal_createSquare" "', argument " "4"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "InterferenceFunctionFinite2DLattice_createSquare" "', argument " "4"" of type '" "unsigned int""'");
   } 
-  arg4 = static_cast< double >(val4);
-  result = (InterferenceFunction2DParaCrystal *)InterferenceFunction2DParaCrystal::createSquare(arg1,arg2,arg3,arg4);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, SWIG_POINTER_OWN |  0 );
+  arg4 = static_cast< unsigned int >(val4);
+  result = (InterferenceFunctionFinite2DLattice *)InterferenceFunctionFinite2DLattice::createSquare(arg1,arg2,arg3,arg4);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunctionFinite2DLattice, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_createSquare__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_createHexagonal(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   double arg1 ;
   double arg2 ;
-  double arg3 ;
+  unsigned int arg3 ;
+  unsigned int arg4 ;
   double val1 ;
   int ecode1 = 0 ;
   double val2 ;
   int ecode2 = 0 ;
-  double val3 ;
+  unsigned int val3 ;
   int ecode3 = 0 ;
+  unsigned int val4 ;
+  int ecode4 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
-  InterferenceFunction2DParaCrystal *result = 0 ;
+  PyObject * obj3 = 0 ;
+  InterferenceFunctionFinite2DLattice *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:InterferenceFunction2DParaCrystal_createSquare",&obj0,&obj1,&obj2)) SWIG_fail;
+  if (!PyArg_ParseTuple(args,(char *)"OOOO:InterferenceFunctionFinite2DLattice_createHexagonal",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
   ecode1 = SWIG_AsVal_double(obj0, &val1);
   if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "InterferenceFunction2DParaCrystal_createSquare" "', argument " "1"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "InterferenceFunctionFinite2DLattice_createHexagonal" "', argument " "1"" of type '" "double""'");
   } 
   arg1 = static_cast< double >(val1);
   ecode2 = SWIG_AsVal_double(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunction2DParaCrystal_createSquare" "', argument " "2"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunctionFinite2DLattice_createHexagonal" "', argument " "2"" of type '" "double""'");
   } 
   arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
+  ecode3 = SWIG_AsVal_unsigned_SS_int(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "InterferenceFunction2DParaCrystal_createSquare" "', argument " "3"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "InterferenceFunctionFinite2DLattice_createHexagonal" "', argument " "3"" of type '" "unsigned int""'");
   } 
-  arg3 = static_cast< double >(val3);
-  result = (InterferenceFunction2DParaCrystal *)InterferenceFunction2DParaCrystal::createSquare(arg1,arg2,arg3);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
+  arg3 = static_cast< unsigned int >(val3);
+  ecode4 = SWIG_AsVal_unsigned_SS_int(obj3, &val4);
+  if (!SWIG_IsOK(ecode4)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "InterferenceFunctionFinite2DLattice_createHexagonal" "', argument " "4"" of type '" "unsigned int""'");
+  } 
+  arg4 = static_cast< unsigned int >(val4);
+  result = (InterferenceFunctionFinite2DLattice *)InterferenceFunctionFinite2DLattice::createHexagonal(arg1,arg2,arg3,arg4);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunctionFinite2DLattice, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_createSquare__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_evaluate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  double arg1 ;
-  double arg2 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
+  InterferenceFunctionFinite2DLattice *arg1 = (InterferenceFunctionFinite2DLattice *) 0 ;
+  kvector_t arg2 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 ;
+  int res2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  InterferenceFunction2DParaCrystal *result = 0 ;
+  double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunction2DParaCrystal_createSquare",&obj0,&obj1)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(obj0, &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "InterferenceFunction2DParaCrystal_createSquare" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunction2DParaCrystal_createSquare" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  result = (InterferenceFunction2DParaCrystal *)InterferenceFunction2DParaCrystal::createSquare(arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunctionFinite2DLattice_evaluate",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite2DLattice, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite2DLattice_evaluate" "', argument " "1"" of type '" "InterferenceFunctionFinite2DLattice const *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunctionFinite2DLattice * >(argp1);
+  {
+    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_BasicVector3DT_double_t,  0  | 0);
+    if (!SWIG_IsOK(res2)) {
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "InterferenceFunctionFinite2DLattice_evaluate" "', argument " "2"" of type '" "kvector_t const""'"); 
+    }  
+    if (!argp2) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "InterferenceFunctionFinite2DLattice_evaluate" "', argument " "2"" of type '" "kvector_t const""'");
+    } else {
+      kvector_t * temp = reinterpret_cast< kvector_t * >(argp2);
+      arg2 = *temp;
+      if (SWIG_IsNewObj(res2)) delete temp;
+    }
+  }
+  result = (double)((InterferenceFunctionFinite2DLattice const *)arg1)->evaluate(arg2);
+  resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_createSquare__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_numberUnitCells1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  double arg1 ;
-  double val1 ;
-  int ecode1 = 0 ;
+  InterferenceFunctionFinite2DLattice *arg1 = (InterferenceFunctionFinite2DLattice *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  InterferenceFunction2DParaCrystal *result = 0 ;
+  unsigned int result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction2DParaCrystal_createSquare",&obj0)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(obj0, &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "InterferenceFunction2DParaCrystal_createSquare" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  result = (InterferenceFunction2DParaCrystal *)InterferenceFunction2DParaCrystal::createSquare(arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionFinite2DLattice_numberUnitCells1",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite2DLattice, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite2DLattice_numberUnitCells1" "', argument " "1"" of type '" "InterferenceFunctionFinite2DLattice const *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunctionFinite2DLattice * >(argp1);
+  result = (unsigned int)((InterferenceFunctionFinite2DLattice const *)arg1)->numberUnitCells1();
+  resultobj = SWIG_From_unsigned_SS_int(static_cast< unsigned int >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_createSquare(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[5] = {
-    0
-  };
-  Py_ssize_t ii;
+SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_numberUnitCells2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  InterferenceFunctionFinite2DLattice *arg1 = (InterferenceFunctionFinite2DLattice *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  unsigned int result;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    {
-      int res = SWIG_AsVal_double(argv[0], NULL);
-      _v = SWIG_CheckState(res);
-    }
-    if (_v) {
-      return _wrap_InterferenceFunction2DParaCrystal_createSquare__SWIG_3(self, args);
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    {
-      int res = SWIG_AsVal_double(argv[0], NULL);
-      _v = SWIG_CheckState(res);
-    }
-    if (_v) {
-      {
-        int res = SWIG_AsVal_double(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_InterferenceFunction2DParaCrystal_createSquare__SWIG_2(self, args);
-      }
-    }
-  }
-  if (argc == 3) {
-    int _v;
-    {
-      int res = SWIG_AsVal_double(argv[0], NULL);
-      _v = SWIG_CheckState(res);
-    }
-    if (_v) {
-      {
-        int res = SWIG_AsVal_double(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        {
-          int res = SWIG_AsVal_double(argv[2], NULL);
-          _v = SWIG_CheckState(res);
-        }
-        if (_v) {
-          return _wrap_InterferenceFunction2DParaCrystal_createSquare__SWIG_1(self, args);
-        }
-      }
-    }
-  }
-  if (argc == 4) {
-    int _v;
-    {
-      int res = SWIG_AsVal_double(argv[0], NULL);
-      _v = SWIG_CheckState(res);
-    }
-    if (_v) {
-      {
-        int res = SWIG_AsVal_double(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        {
-          int res = SWIG_AsVal_double(argv[2], NULL);
-          _v = SWIG_CheckState(res);
-        }
-        if (_v) {
-          {
-            int res = SWIG_AsVal_double(argv[3], NULL);
-            _v = SWIG_CheckState(res);
-          }
-          if (_v) {
-            return _wrap_InterferenceFunction2DParaCrystal_createSquare__SWIG_0(self, args);
-          }
-        }
-      }
-    }
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionFinite2DLattice_numberUnitCells2",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite2DLattice, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite2DLattice_numberUnitCells2" "', argument " "1"" of type '" "InterferenceFunctionFinite2DLattice const *""'"); 
   }
-  
+  arg1 = reinterpret_cast< InterferenceFunctionFinite2DLattice * >(argp1);
+  result = (unsigned int)((InterferenceFunctionFinite2DLattice const *)arg1)->numberUnitCells2();
+  resultobj = SWIG_From_unsigned_SS_int(static_cast< unsigned int >(result));
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'InterferenceFunction2DParaCrystal_createSquare'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    InterferenceFunction2DParaCrystal::createSquare(double,double,double,double)\n"
-    "    InterferenceFunction2DParaCrystal::createSquare(double,double,double)\n"
-    "    InterferenceFunction2DParaCrystal::createSquare(double,double)\n"
-    "    InterferenceFunction2DParaCrystal::createSquare(double)\n");
-  return 0;
+  return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_createHexagonal__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_setPositionVariance(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  double arg1 ;
+  InterferenceFunctionFinite2DLattice *arg1 = (InterferenceFunctionFinite2DLattice *) 0 ;
   double arg2 ;
-  double arg3 ;
-  double arg4 ;
-  double val1 ;
-  int ecode1 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
   double val2 ;
   int ecode2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
-  double val4 ;
-  int ecode4 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  PyObject * obj3 = 0 ;
-  InterferenceFunction2DParaCrystal *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOOO:InterferenceFunction2DParaCrystal_createHexagonal",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(obj0, &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "InterferenceFunction2DParaCrystal_createHexagonal" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
+  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunctionFinite2DLattice_setPositionVariance",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite2DLattice, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite2DLattice_setPositionVariance" "', argument " "1"" of type '" "InterferenceFunctionFinite2DLattice *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunctionFinite2DLattice * >(argp1);
   ecode2 = SWIG_AsVal_double(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunction2DParaCrystal_createHexagonal" "', argument " "2"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunctionFinite2DLattice_setPositionVariance" "', argument " "2"" of type '" "double""'");
   } 
   arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "InterferenceFunction2DParaCrystal_createHexagonal" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  ecode4 = SWIG_AsVal_double(obj3, &val4);
-  if (!SWIG_IsOK(ecode4)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "InterferenceFunction2DParaCrystal_createHexagonal" "', argument " "4"" of type '" "double""'");
-  } 
-  arg4 = static_cast< double >(val4);
-  result = (InterferenceFunction2DParaCrystal *)InterferenceFunction2DParaCrystal::createHexagonal(arg1,arg2,arg3,arg4);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, SWIG_POINTER_OWN |  0 );
+  (arg1)->setPositionVariance(arg2);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_createHexagonal__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_positionVariance(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  double arg1 ;
-  double arg2 ;
-  double arg3 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
+  InterferenceFunctionFinite2DLattice *arg1 = (InterferenceFunctionFinite2DLattice *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  InterferenceFunction2DParaCrystal *result = 0 ;
+  double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:InterferenceFunction2DParaCrystal_createHexagonal",&obj0,&obj1,&obj2)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(obj0, &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "InterferenceFunction2DParaCrystal_createHexagonal" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunction2DParaCrystal_createHexagonal" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "InterferenceFunction2DParaCrystal_createHexagonal" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  result = (InterferenceFunction2DParaCrystal *)InterferenceFunction2DParaCrystal::createHexagonal(arg1,arg2,arg3);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionFinite2DLattice_positionVariance",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite2DLattice, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite2DLattice_positionVariance" "', argument " "1"" of type '" "InterferenceFunctionFinite2DLattice const *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunctionFinite2DLattice * >(argp1);
+  result = (double)((InterferenceFunctionFinite2DLattice const *)arg1)->positionVariance();
+  resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_createHexagonal__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_setIntegrationOverXi(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  double arg1 ;
-  double arg2 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  double val2 ;
+  InterferenceFunctionFinite2DLattice *arg1 = (InterferenceFunctionFinite2DLattice *) 0 ;
+  bool arg2 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  bool val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  InterferenceFunction2DParaCrystal *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunction2DParaCrystal_createHexagonal",&obj0,&obj1)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(obj0, &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "InterferenceFunction2DParaCrystal_createHexagonal" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunctionFinite2DLattice_setIntegrationOverXi",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite2DLattice, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite2DLattice_setIntegrationOverXi" "', argument " "1"" of type '" "InterferenceFunctionFinite2DLattice *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunctionFinite2DLattice * >(argp1);
+  ecode2 = SWIG_AsVal_bool(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunction2DParaCrystal_createHexagonal" "', argument " "2"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunctionFinite2DLattice_setIntegrationOverXi" "', argument " "2"" of type '" "bool""'");
   } 
-  arg2 = static_cast< double >(val2);
-  result = (InterferenceFunction2DParaCrystal *)InterferenceFunction2DParaCrystal::createHexagonal(arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
+  arg2 = static_cast< bool >(val2);
+  (arg1)->setIntegrationOverXi(arg2);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_createHexagonal__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_integrationOverXi(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  double arg1 ;
-  double val1 ;
-  int ecode1 = 0 ;
+  InterferenceFunctionFinite2DLattice *arg1 = (InterferenceFunctionFinite2DLattice *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  InterferenceFunction2DParaCrystal *result = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction2DParaCrystal_createHexagonal",&obj0)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(obj0, &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "InterferenceFunction2DParaCrystal_createHexagonal" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  result = (InterferenceFunction2DParaCrystal *)InterferenceFunction2DParaCrystal::createHexagonal(arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionFinite2DLattice_integrationOverXi",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite2DLattice, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite2DLattice_integrationOverXi" "', argument " "1"" of type '" "InterferenceFunctionFinite2DLattice const *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunctionFinite2DLattice * >(argp1);
+  result = (bool)((InterferenceFunctionFinite2DLattice const *)arg1)->integrationOverXi();
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_createHexagonal(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[5] = {
-    0
-  };
-  Py_ssize_t ii;
+SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_lattice(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  InterferenceFunctionFinite2DLattice *arg1 = (InterferenceFunctionFinite2DLattice *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  Lattice2D *result = 0 ;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = args ? PyObject_Length(args) : 0;
-  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    {
-      int res = SWIG_AsVal_double(argv[0], NULL);
-      _v = SWIG_CheckState(res);
-    }
-    if (_v) {
-      return _wrap_InterferenceFunction2DParaCrystal_createHexagonal__SWIG_3(self, args);
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    {
-      int res = SWIG_AsVal_double(argv[0], NULL);
-      _v = SWIG_CheckState(res);
-    }
-    if (_v) {
-      {
-        int res = SWIG_AsVal_double(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_InterferenceFunction2DParaCrystal_createHexagonal__SWIG_2(self, args);
-      }
-    }
-  }
-  if (argc == 3) {
-    int _v;
-    {
-      int res = SWIG_AsVal_double(argv[0], NULL);
-      _v = SWIG_CheckState(res);
-    }
-    if (_v) {
-      {
-        int res = SWIG_AsVal_double(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        {
-          int res = SWIG_AsVal_double(argv[2], NULL);
-          _v = SWIG_CheckState(res);
-        }
-        if (_v) {
-          return _wrap_InterferenceFunction2DParaCrystal_createHexagonal__SWIG_1(self, args);
-        }
-      }
-    }
-  }
-  if (argc == 4) {
-    int _v;
-    {
-      int res = SWIG_AsVal_double(argv[0], NULL);
-      _v = SWIG_CheckState(res);
-    }
-    if (_v) {
-      {
-        int res = SWIG_AsVal_double(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        {
-          int res = SWIG_AsVal_double(argv[2], NULL);
-          _v = SWIG_CheckState(res);
-        }
-        if (_v) {
-          {
-            int res = SWIG_AsVal_double(argv[3], NULL);
-            _v = SWIG_CheckState(res);
-          }
-          if (_v) {
-            return _wrap_InterferenceFunction2DParaCrystal_createHexagonal__SWIG_0(self, args);
-          }
-        }
-      }
-    }
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionFinite2DLattice_lattice",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite2DLattice, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite2DLattice_lattice" "', argument " "1"" of type '" "InterferenceFunctionFinite2DLattice const *""'"); 
   }
-  
+  arg1 = reinterpret_cast< InterferenceFunctionFinite2DLattice * >(argp1);
+  result = (Lattice2D *) &((InterferenceFunctionFinite2DLattice const *)arg1)->lattice();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Lattice2D, 0 |  0 );
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'InterferenceFunction2DParaCrystal_createHexagonal'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    InterferenceFunction2DParaCrystal::createHexagonal(double,double,double,double)\n"
-    "    InterferenceFunction2DParaCrystal::createHexagonal(double,double,double)\n"
-    "    InterferenceFunction2DParaCrystal::createHexagonal(double,double)\n"
-    "    InterferenceFunction2DParaCrystal::createHexagonal(double)\n");
-  return 0;
+  return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_setDomainSizes(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_getParticleDensity(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
-  double arg2 ;
-  double arg3 ;
+  InterferenceFunctionFinite2DLattice *arg1 = (InterferenceFunctionFinite2DLattice *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
+  double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:InterferenceFunction2DParaCrystal_setDomainSizes",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionFinite2DLattice_getParticleDensity",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite2DLattice, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_setDomainSizes" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite2DLattice_getParticleDensity" "', argument " "1"" of type '" "InterferenceFunctionFinite2DLattice const *""'"); 
   }
-  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunction2DParaCrystal_setDomainSizes" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "InterferenceFunction2DParaCrystal_setDomainSizes" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  (arg1)->setDomainSizes(arg2,arg3);
-  resultobj = SWIG_Py_Void();
+  arg1 = reinterpret_cast< InterferenceFunctionFinite2DLattice * >(argp1);
+  result = (double)((InterferenceFunctionFinite2DLattice const *)arg1)->getParticleDensity();
+  resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_setProbabilityDistributions(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite2DLattice_getChildren(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
-  IFTDistribution2D *arg2 = 0 ;
-  IFTDistribution2D *arg3 = 0 ;
+  InterferenceFunctionFinite2DLattice *arg1 = (InterferenceFunctionFinite2DLattice *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  void *argp3 = 0 ;
-  int res3 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
+  std::vector< INode const *,std::allocator< INode const * > > result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:InterferenceFunction2DParaCrystal_setProbabilityDistributions",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionFinite2DLattice_getChildren",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite2DLattice, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_setProbabilityDistributions" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal *""'"); 
-  }
-  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_IFTDistribution2D,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "InterferenceFunction2DParaCrystal_setProbabilityDistributions" "', argument " "2"" of type '" "IFTDistribution2D const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "InterferenceFunction2DParaCrystal_setProbabilityDistributions" "', argument " "2"" of type '" "IFTDistribution2D const &""'"); 
-  }
-  arg2 = reinterpret_cast< IFTDistribution2D * >(argp2);
-  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_IFTDistribution2D,  0  | 0);
-  if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "InterferenceFunction2DParaCrystal_setProbabilityDistributions" "', argument " "3"" of type '" "IFTDistribution2D const &""'"); 
-  }
-  if (!argp3) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "InterferenceFunction2DParaCrystal_setProbabilityDistributions" "', argument " "3"" of type '" "IFTDistribution2D const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite2DLattice_getChildren" "', argument " "1"" of type '" "InterferenceFunctionFinite2DLattice const *""'"); 
   }
-  arg3 = reinterpret_cast< IFTDistribution2D * >(argp3);
-  (arg1)->setProbabilityDistributions((IFTDistribution2D const &)*arg2,(IFTDistribution2D const &)*arg3);
-  resultobj = SWIG_Py_Void();
+  arg1 = reinterpret_cast< InterferenceFunctionFinite2DLattice * >(argp1);
+  result = ((InterferenceFunctionFinite2DLattice const *)arg1)->getChildren();
+  resultobj = swig::from(static_cast< std::vector< INode const*,std::allocator< INode const * > > >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_setDampingLength(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *InterferenceFunctionFinite2DLattice_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *obj;
+  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_InterferenceFunctionFinite2DLattice, SWIG_NewClientData(obj));
+  return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *_wrap_new_InterferenceFunctionFinite3DLattice(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
-  double arg2 ;
+  Lattice *arg1 = 0 ;
+  unsigned int arg2 ;
+  unsigned int arg3 ;
+  unsigned int arg4 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  double val2 ;
+  unsigned int val2 ;
   int ecode2 = 0 ;
+  unsigned int val3 ;
+  int ecode3 = 0 ;
+  unsigned int val4 ;
+  int ecode4 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
+  InterferenceFunctionFinite3DLattice *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunction2DParaCrystal_setDampingLength",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOOO:new_InterferenceFunctionFinite3DLattice",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_Lattice,  0  | 0);
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_setDampingLength" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_InterferenceFunctionFinite3DLattice" "', argument " "1"" of type '" "Lattice const &""'"); 
   }
-  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!argp1) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_InterferenceFunctionFinite3DLattice" "', argument " "1"" of type '" "Lattice const &""'"); 
+  }
+  arg1 = reinterpret_cast< Lattice * >(argp1);
+  ecode2 = SWIG_AsVal_unsigned_SS_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunction2DParaCrystal_setDampingLength" "', argument " "2"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_InterferenceFunctionFinite3DLattice" "', argument " "2"" of type '" "unsigned int""'");
   } 
-  arg2 = static_cast< double >(val2);
-  (arg1)->setDampingLength(arg2);
-  resultobj = SWIG_Py_Void();
+  arg2 = static_cast< unsigned int >(val2);
+  ecode3 = SWIG_AsVal_unsigned_SS_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_InterferenceFunctionFinite3DLattice" "', argument " "3"" of type '" "unsigned int""'");
+  } 
+  arg3 = static_cast< unsigned int >(val3);
+  ecode4 = SWIG_AsVal_unsigned_SS_int(obj3, &val4);
+  if (!SWIG_IsOK(ecode4)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "new_InterferenceFunctionFinite3DLattice" "', argument " "4"" of type '" "unsigned int""'");
+  } 
+  arg4 = static_cast< unsigned int >(val4);
+  result = (InterferenceFunctionFinite3DLattice *)new InterferenceFunctionFinite3DLattice((Lattice const &)*arg1,arg2,arg3,arg4);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunctionFinite3DLattice, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_evaluate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_delete_InterferenceFunctionFinite3DLattice(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
-  kvector_t arg2 ;
+  InterferenceFunctionFinite3DLattice *arg1 = (InterferenceFunctionFinite3DLattice *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  void *argp2 ;
-  int res2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunction2DParaCrystal_evaluate",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:delete_InterferenceFunctionFinite3DLattice",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite3DLattice, SWIG_POINTER_DISOWN |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_evaluate" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal const *""'"); 
-  }
-  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
-  {
-    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_BasicVector3DT_double_t,  0  | 0);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "InterferenceFunction2DParaCrystal_evaluate" "', argument " "2"" of type '" "kvector_t const""'"); 
-    }  
-    if (!argp2) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "InterferenceFunction2DParaCrystal_evaluate" "', argument " "2"" of type '" "kvector_t const""'");
-    } else {
-      kvector_t * temp = reinterpret_cast< kvector_t * >(argp2);
-      arg2 = *temp;
-      if (SWIG_IsNewObj(res2)) delete temp;
-    }
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_InterferenceFunctionFinite3DLattice" "', argument " "1"" of type '" "InterferenceFunctionFinite3DLattice *""'"); 
   }
-  result = (double)((InterferenceFunction2DParaCrystal const *)arg1)->evaluate(arg2);
-  resultobj = SWIG_From_double(static_cast< double >(result));
+  arg1 = reinterpret_cast< InterferenceFunctionFinite3DLattice * >(argp1);
+  delete arg1;
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_domainSizes(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite3DLattice_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
+  InterferenceFunctionFinite3DLattice *arg1 = (InterferenceFunctionFinite3DLattice *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  std::vector< double,std::allocator< double > > result;
+  InterferenceFunctionFinite3DLattice *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction2DParaCrystal_domainSizes",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionFinite3DLattice_clone",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite3DLattice, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_domainSizes" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite3DLattice_clone" "', argument " "1"" of type '" "InterferenceFunctionFinite3DLattice const *""'"); 
   }
-  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
-  result = ((InterferenceFunction2DParaCrystal const *)arg1)->domainSizes();
-  resultobj = swig::from(static_cast< std::vector< double,std::allocator< double > > >(result));
+  arg1 = reinterpret_cast< InterferenceFunctionFinite3DLattice * >(argp1);
+  result = (InterferenceFunctionFinite3DLattice *)((InterferenceFunctionFinite3DLattice const *)arg1)->clone();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunctionFinite3DLattice, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_setIntegrationOverXi(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite3DLattice_accept(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
-  bool arg2 ;
+  InterferenceFunctionFinite3DLattice *arg1 = (InterferenceFunctionFinite3DLattice *) 0 ;
+  INodeVisitor *arg2 = (INodeVisitor *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  bool val2 ;
-  int ecode2 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunction2DParaCrystal_setIntegrationOverXi",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunctionFinite3DLattice_accept",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite3DLattice, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_setIntegrationOverXi" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite3DLattice_accept" "', argument " "1"" of type '" "InterferenceFunctionFinite3DLattice const *""'"); 
   }
-  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
-  ecode2 = SWIG_AsVal_bool(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunction2DParaCrystal_setIntegrationOverXi" "', argument " "2"" of type '" "bool""'");
-  } 
-  arg2 = static_cast< bool >(val2);
-  (arg1)->setIntegrationOverXi(arg2);
+  arg1 = reinterpret_cast< InterferenceFunctionFinite3DLattice * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_INodeVisitor, 0 |  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "InterferenceFunctionFinite3DLattice_accept" "', argument " "2"" of type '" "INodeVisitor *""'"); 
+  }
+  arg2 = reinterpret_cast< INodeVisitor * >(argp2);
+  ((InterferenceFunctionFinite3DLattice const *)arg1)->accept(arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -102395,109 +95245,148 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_integrationOverXi(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite3DLattice_evaluate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
+  InterferenceFunctionFinite3DLattice *arg1 = (InterferenceFunctionFinite3DLattice *) 0 ;
+  kvector_t arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  void *argp2 ;
+  int res2 = 0 ;
   PyObject * obj0 = 0 ;
-  bool result;
+  PyObject * obj1 = 0 ;
+  double result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction2DParaCrystal_integrationOverXi",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunctionFinite3DLattice_evaluate",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite3DLattice, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_integrationOverXi" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite3DLattice_evaluate" "', argument " "1"" of type '" "InterferenceFunctionFinite3DLattice const *""'"); 
   }
-  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
-  result = (bool)((InterferenceFunction2DParaCrystal const *)arg1)->integrationOverXi();
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  arg1 = reinterpret_cast< InterferenceFunctionFinite3DLattice * >(argp1);
+  {
+    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_BasicVector3DT_double_t,  0  | 0);
+    if (!SWIG_IsOK(res2)) {
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "InterferenceFunctionFinite3DLattice_evaluate" "', argument " "2"" of type '" "kvector_t const""'"); 
+    }  
+    if (!argp2) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "InterferenceFunctionFinite3DLattice_evaluate" "', argument " "2"" of type '" "kvector_t const""'");
+    } else {
+      kvector_t * temp = reinterpret_cast< kvector_t * >(argp2);
+      arg2 = *temp;
+      if (SWIG_IsNewObj(res2)) delete temp;
+    }
+  }
+  result = (double)((InterferenceFunctionFinite3DLattice const *)arg1)->evaluate(arg2);
+  resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_dampingLength(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite3DLattice_numberUnitCells1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
+  InterferenceFunctionFinite3DLattice *arg1 = (InterferenceFunctionFinite3DLattice *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  double result;
+  unsigned int result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction2DParaCrystal_dampingLength",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionFinite3DLattice_numberUnitCells1",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite3DLattice, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_dampingLength" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite3DLattice_numberUnitCells1" "', argument " "1"" of type '" "InterferenceFunctionFinite3DLattice const *""'"); 
   }
-  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
-  result = (double)((InterferenceFunction2DParaCrystal const *)arg1)->dampingLength();
-  resultobj = SWIG_From_double(static_cast< double >(result));
+  arg1 = reinterpret_cast< InterferenceFunctionFinite3DLattice * >(argp1);
+  result = (unsigned int)((InterferenceFunctionFinite3DLattice const *)arg1)->numberUnitCells1();
+  resultobj = SWIG_From_unsigned_SS_int(static_cast< unsigned int >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_lattice(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite3DLattice_numberUnitCells2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
+  InterferenceFunctionFinite3DLattice *arg1 = (InterferenceFunctionFinite3DLattice *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  Lattice2D *result = 0 ;
+  unsigned int result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction2DParaCrystal_lattice",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionFinite3DLattice_numberUnitCells2",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite3DLattice, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_lattice" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite3DLattice_numberUnitCells2" "', argument " "1"" of type '" "InterferenceFunctionFinite3DLattice const *""'"); 
   }
-  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
-  result = (Lattice2D *) &((InterferenceFunction2DParaCrystal const *)arg1)->lattice();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Lattice2D, 0 |  0 );
+  arg1 = reinterpret_cast< InterferenceFunctionFinite3DLattice * >(argp1);
+  result = (unsigned int)((InterferenceFunctionFinite3DLattice const *)arg1)->numberUnitCells2();
+  resultobj = SWIG_From_unsigned_SS_int(static_cast< unsigned int >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_getParticleDensity(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite3DLattice_numberUnitCells3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
+  InterferenceFunctionFinite3DLattice *arg1 = (InterferenceFunctionFinite3DLattice *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  double result;
+  unsigned int result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction2DParaCrystal_getParticleDensity",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionFinite3DLattice_numberUnitCells3",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite3DLattice, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_getParticleDensity" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite3DLattice_numberUnitCells3" "', argument " "1"" of type '" "InterferenceFunctionFinite3DLattice const *""'"); 
   }
-  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
-  result = (double)((InterferenceFunction2DParaCrystal const *)arg1)->getParticleDensity();
-  resultobj = SWIG_From_double(static_cast< double >(result));
+  arg1 = reinterpret_cast< InterferenceFunctionFinite3DLattice * >(argp1);
+  result = (unsigned int)((InterferenceFunctionFinite3DLattice const *)arg1)->numberUnitCells3();
+  resultobj = SWIG_From_unsigned_SS_int(static_cast< unsigned int >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_InterferenceFunction2DParaCrystal_getChildren(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite3DLattice_lattice(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  InterferenceFunction2DParaCrystal *arg1 = (InterferenceFunction2DParaCrystal *) 0 ;
+  InterferenceFunctionFinite3DLattice *arg1 = (InterferenceFunctionFinite3DLattice *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  Lattice *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionFinite3DLattice_lattice",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite3DLattice, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite3DLattice_lattice" "', argument " "1"" of type '" "InterferenceFunctionFinite3DLattice const *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunctionFinite3DLattice * >(argp1);
+  result = (Lattice *) &((InterferenceFunctionFinite3DLattice const *)arg1)->lattice();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Lattice, 0 |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_InterferenceFunctionFinite3DLattice_getChildren(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  InterferenceFunctionFinite3DLattice *arg1 = (InterferenceFunctionFinite3DLattice *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
   std::vector< INode const *,std::allocator< INode const * > > result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunction2DParaCrystal_getChildren",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunction2DParaCrystal, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionFinite3DLattice_getChildren",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionFinite3DLattice, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunction2DParaCrystal_getChildren" "', argument " "1"" of type '" "InterferenceFunction2DParaCrystal const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionFinite3DLattice_getChildren" "', argument " "1"" of type '" "InterferenceFunctionFinite3DLattice const *""'"); 
   }
-  arg1 = reinterpret_cast< InterferenceFunction2DParaCrystal * >(argp1);
-  result = ((InterferenceFunction2DParaCrystal const *)arg1)->getChildren();
+  arg1 = reinterpret_cast< InterferenceFunctionFinite3DLattice * >(argp1);
+  result = ((InterferenceFunctionFinite3DLattice const *)arg1)->getChildren();
   resultobj = swig::from(static_cast< std::vector< INode const*,std::allocator< INode const * > > >(result));
   return resultobj;
 fail:
@@ -102505,10 +95394,10 @@ fail:
 }
 
 
-SWIGINTERN PyObject *InterferenceFunction2DParaCrystal_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *InterferenceFunctionFinite3DLattice_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
   if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_InterferenceFunction2DParaCrystal, SWIG_NewClientData(obj));
+  SWIG_TypeNewClientData(SWIGTYPE_p_InterferenceFunctionFinite3DLattice, SWIG_NewClientData(obj));
   return SWIG_Py_Void();
 }
 
@@ -102644,6 +95533,482 @@ SWIGINTERN PyObject *InterferenceFunctionNone_swigregister(PyObject *SWIGUNUSEDP
   return SWIG_Py_Void();
 }
 
+SWIGINTERN PyObject *_wrap_new_InterferenceFunctionRadialParaCrystal__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  double arg1 ;
+  double arg2 ;
+  double val1 ;
+  int ecode1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  InterferenceFunctionRadialParaCrystal *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OO:new_InterferenceFunctionRadialParaCrystal",&obj0,&obj1)) SWIG_fail;
+  ecode1 = SWIG_AsVal_double(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_InterferenceFunctionRadialParaCrystal" "', argument " "1"" of type '" "double""'");
+  } 
+  arg1 = static_cast< double >(val1);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_InterferenceFunctionRadialParaCrystal" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  result = (InterferenceFunctionRadialParaCrystal *)new InterferenceFunctionRadialParaCrystal(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_new_InterferenceFunctionRadialParaCrystal__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  double arg1 ;
+  double val1 ;
+  int ecode1 = 0 ;
+  PyObject * obj0 = 0 ;
+  InterferenceFunctionRadialParaCrystal *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:new_InterferenceFunctionRadialParaCrystal",&obj0)) SWIG_fail;
+  ecode1 = SWIG_AsVal_double(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_InterferenceFunctionRadialParaCrystal" "', argument " "1"" of type '" "double""'");
+  } 
+  arg1 = static_cast< double >(val1);
+  result = (InterferenceFunctionRadialParaCrystal *)new InterferenceFunctionRadialParaCrystal(arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_new_InterferenceFunctionRadialParaCrystal(PyObject *self, PyObject *args) {
+  Py_ssize_t argc;
+  PyObject *argv[3] = {
+    0
+  };
+  Py_ssize_t ii;
+  
+  if (!PyTuple_Check(args)) SWIG_fail;
+  argc = args ? PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
+    argv[ii] = PyTuple_GET_ITEM(args,ii);
+  }
+  if (argc == 1) {
+    int _v;
+    {
+      int res = SWIG_AsVal_double(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      return _wrap_new_InterferenceFunctionRadialParaCrystal__SWIG_1(self, args);
+    }
+  }
+  if (argc == 2) {
+    int _v;
+    {
+      int res = SWIG_AsVal_double(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      {
+        int res = SWIG_AsVal_double(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        return _wrap_new_InterferenceFunctionRadialParaCrystal__SWIG_0(self, args);
+      }
+    }
+  }
+  
+fail:
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_InterferenceFunctionRadialParaCrystal'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    InterferenceFunctionRadialParaCrystal::InterferenceFunctionRadialParaCrystal(double,double)\n"
+    "    InterferenceFunctionRadialParaCrystal::InterferenceFunctionRadialParaCrystal(double)\n");
+  return 0;
+}
+
+
+SWIGINTERN PyObject *_wrap_InterferenceFunctionRadialParaCrystal_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  InterferenceFunctionRadialParaCrystal *arg1 = (InterferenceFunctionRadialParaCrystal *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  InterferenceFunctionRadialParaCrystal *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionRadialParaCrystal_clone",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionRadialParaCrystal_clone" "', argument " "1"" of type '" "InterferenceFunctionRadialParaCrystal const *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp1);
+  result = (InterferenceFunctionRadialParaCrystal *)((InterferenceFunctionRadialParaCrystal const *)arg1)->clone();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_InterferenceFunctionRadialParaCrystal_accept(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  InterferenceFunctionRadialParaCrystal *arg1 = (InterferenceFunctionRadialParaCrystal *) 0 ;
+  INodeVisitor *arg2 = (INodeVisitor *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunctionRadialParaCrystal_accept",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionRadialParaCrystal_accept" "', argument " "1"" of type '" "InterferenceFunctionRadialParaCrystal const *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_INodeVisitor, 0 |  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "InterferenceFunctionRadialParaCrystal_accept" "', argument " "2"" of type '" "INodeVisitor *""'"); 
+  }
+  arg2 = reinterpret_cast< INodeVisitor * >(argp2);
+  ((InterferenceFunctionRadialParaCrystal const *)arg1)->accept(arg2);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_InterferenceFunctionRadialParaCrystal_setKappa(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  InterferenceFunctionRadialParaCrystal *arg1 = (InterferenceFunctionRadialParaCrystal *) 0 ;
+  double arg2 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunctionRadialParaCrystal_setKappa",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionRadialParaCrystal_setKappa" "', argument " "1"" of type '" "InterferenceFunctionRadialParaCrystal *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp1);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunctionRadialParaCrystal_setKappa" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  (arg1)->setKappa(arg2);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_InterferenceFunctionRadialParaCrystal_kappa(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  InterferenceFunctionRadialParaCrystal *arg1 = (InterferenceFunctionRadialParaCrystal *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  double result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionRadialParaCrystal_kappa",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionRadialParaCrystal_kappa" "', argument " "1"" of type '" "InterferenceFunctionRadialParaCrystal const *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp1);
+  result = (double)((InterferenceFunctionRadialParaCrystal const *)arg1)->kappa();
+  resultobj = SWIG_From_double(static_cast< double >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_InterferenceFunctionRadialParaCrystal_setDomainSize(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  InterferenceFunctionRadialParaCrystal *arg1 = (InterferenceFunctionRadialParaCrystal *) 0 ;
+  double arg2 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunctionRadialParaCrystal_setDomainSize",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionRadialParaCrystal_setDomainSize" "', argument " "1"" of type '" "InterferenceFunctionRadialParaCrystal *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp1);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunctionRadialParaCrystal_setDomainSize" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  (arg1)->setDomainSize(arg2);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_InterferenceFunctionRadialParaCrystal_domainSize(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  InterferenceFunctionRadialParaCrystal *arg1 = (InterferenceFunctionRadialParaCrystal *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  double result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionRadialParaCrystal_domainSize",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionRadialParaCrystal_domainSize" "', argument " "1"" of type '" "InterferenceFunctionRadialParaCrystal const *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp1);
+  result = (double)((InterferenceFunctionRadialParaCrystal const *)arg1)->domainSize();
+  resultobj = SWIG_From_double(static_cast< double >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_InterferenceFunctionRadialParaCrystal_evaluate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  InterferenceFunctionRadialParaCrystal *arg1 = (InterferenceFunctionRadialParaCrystal *) 0 ;
+  kvector_t arg2 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 ;
+  int res2 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  double result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunctionRadialParaCrystal_evaluate",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionRadialParaCrystal_evaluate" "', argument " "1"" of type '" "InterferenceFunctionRadialParaCrystal const *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp1);
+  {
+    res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_BasicVector3DT_double_t,  0  | 0);
+    if (!SWIG_IsOK(res2)) {
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "InterferenceFunctionRadialParaCrystal_evaluate" "', argument " "2"" of type '" "kvector_t const""'"); 
+    }  
+    if (!argp2) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "InterferenceFunctionRadialParaCrystal_evaluate" "', argument " "2"" of type '" "kvector_t const""'");
+    } else {
+      kvector_t * temp = reinterpret_cast< kvector_t * >(argp2);
+      arg2 = *temp;
+      if (SWIG_IsNewObj(res2)) delete temp;
+    }
+  }
+  result = (double)((InterferenceFunctionRadialParaCrystal const *)arg1)->evaluate(arg2);
+  resultobj = SWIG_From_double(static_cast< double >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_InterferenceFunctionRadialParaCrystal_FTPDF(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  InterferenceFunctionRadialParaCrystal *arg1 = (InterferenceFunctionRadialParaCrystal *) 0 ;
+  double arg2 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  complex_t result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunctionRadialParaCrystal_FTPDF",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionRadialParaCrystal_FTPDF" "', argument " "1"" of type '" "InterferenceFunctionRadialParaCrystal const *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp1);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "InterferenceFunctionRadialParaCrystal_FTPDF" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  result = ((InterferenceFunctionRadialParaCrystal const *)arg1)->FTPDF(arg2);
+  resultobj = SWIG_From_std_complex_Sl_double_Sg_(static_cast< std::complex<double> >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_InterferenceFunctionRadialParaCrystal_setProbabilityDistribution(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  InterferenceFunctionRadialParaCrystal *arg1 = (InterferenceFunctionRadialParaCrystal *) 0 ;
+  IFTDistribution1D *arg2 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OO:InterferenceFunctionRadialParaCrystal_setProbabilityDistribution",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionRadialParaCrystal_setProbabilityDistribution" "', argument " "1"" of type '" "InterferenceFunctionRadialParaCrystal *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_IFTDistribution1D,  0  | 0);
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "InterferenceFunctionRadialParaCrystal_setProbabilityDistribution" "', argument " "2"" of type '" "IFTDistribution1D const &""'"); 
+  }
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "InterferenceFunctionRadialParaCrystal_setProbabilityDistribution" "', argument " "2"" of type '" "IFTDistribution1D const &""'"); 
+  }
+  arg2 = reinterpret_cast< IFTDistribution1D * >(argp2);
+  (arg1)->setProbabilityDistribution((IFTDistribution1D const &)*arg2);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_InterferenceFunctionRadialParaCrystal_peakDistance(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  InterferenceFunctionRadialParaCrystal *arg1 = (InterferenceFunctionRadialParaCrystal *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  double result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionRadialParaCrystal_peakDistance",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionRadialParaCrystal_peakDistance" "', argument " "1"" of type '" "InterferenceFunctionRadialParaCrystal const *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp1);
+  result = (double)((InterferenceFunctionRadialParaCrystal const *)arg1)->peakDistance();
+  resultobj = SWIG_From_double(static_cast< double >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_InterferenceFunctionRadialParaCrystal_dampingLength(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  InterferenceFunctionRadialParaCrystal *arg1 = (InterferenceFunctionRadialParaCrystal *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  double result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionRadialParaCrystal_dampingLength",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionRadialParaCrystal_dampingLength" "', argument " "1"" of type '" "InterferenceFunctionRadialParaCrystal const *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp1);
+  result = (double)((InterferenceFunctionRadialParaCrystal const *)arg1)->dampingLength();
+  resultobj = SWIG_From_double(static_cast< double >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_InterferenceFunctionRadialParaCrystal_getChildren(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  InterferenceFunctionRadialParaCrystal *arg1 = (InterferenceFunctionRadialParaCrystal *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::vector< INode const *,std::allocator< INode const * > > result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionRadialParaCrystal_getChildren",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionRadialParaCrystal_getChildren" "', argument " "1"" of type '" "InterferenceFunctionRadialParaCrystal const *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp1);
+  result = ((InterferenceFunctionRadialParaCrystal const *)arg1)->getChildren();
+  resultobj = swig::from(static_cast< std::vector< INode const*,std::allocator< INode const * > > >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_InterferenceFunctionRadialParaCrystal_randomSample(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  InterferenceFunctionRadialParaCrystal *arg1 = (InterferenceFunctionRadialParaCrystal *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  double result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:InterferenceFunctionRadialParaCrystal_randomSample",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceFunctionRadialParaCrystal_randomSample" "', argument " "1"" of type '" "InterferenceFunctionRadialParaCrystal const *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp1);
+  result = (double)((InterferenceFunctionRadialParaCrystal const *)arg1)->randomSample();
+  resultobj = SWIG_From_double(static_cast< double >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_delete_InterferenceFunctionRadialParaCrystal(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  InterferenceFunctionRadialParaCrystal *arg1 = (InterferenceFunctionRadialParaCrystal *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:delete_InterferenceFunctionRadialParaCrystal",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, SWIG_POINTER_DISOWN |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_InterferenceFunctionRadialParaCrystal" "', argument " "1"" of type '" "InterferenceFunctionRadialParaCrystal *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceFunctionRadialParaCrystal * >(argp1);
+  delete arg1;
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *InterferenceFunctionRadialParaCrystal_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *obj;
+  if (!PyArg_ParseTuple(args,(char *)"O:swigregister", &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_InterferenceFunctionRadialParaCrystal, SWIG_NewClientData(obj));
+  return SWIG_Py_Void();
+}
+
 SWIGINTERN PyObject *_wrap_delete_IPixel(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   IPixel *arg1 = (IPixel *) 0 ;
@@ -103740,14 +97105,14 @@ SWIGINTERN PyObject *ILatticeOrientation_swigregister(PyObject *SWIGUNUSEDPARM(s
 
 SWIGINTERN PyObject *_wrap_new_MillerIndex(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  int arg1 ;
-  int arg2 ;
-  int arg3 ;
-  int val1 ;
+  double arg1 ;
+  double arg2 ;
+  double arg3 ;
+  double val1 ;
   int ecode1 = 0 ;
-  int val2 ;
+  double val2 ;
   int ecode2 = 0 ;
-  int val3 ;
+  double val3 ;
   int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
@@ -103755,21 +97120,21 @@ SWIGINTERN PyObject *_wrap_new_MillerIndex(PyObject *SWIGUNUSEDPARM(self), PyObj
   MillerIndex *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OOO:new_MillerIndex",&obj0,&obj1,&obj2)) SWIG_fail;
-  ecode1 = SWIG_AsVal_int(obj0, &val1);
+  ecode1 = SWIG_AsVal_double(obj0, &val1);
   if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_MillerIndex" "', argument " "1"" of type '" "int""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_MillerIndex" "', argument " "1"" of type '" "double""'");
   } 
-  arg1 = static_cast< int >(val1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  arg1 = static_cast< double >(val1);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_MillerIndex" "', argument " "2"" of type '" "int""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_MillerIndex" "', argument " "2"" of type '" "double""'");
   } 
-  arg2 = static_cast< int >(val2);
-  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  arg2 = static_cast< double >(val2);
+  ecode3 = SWIG_AsVal_double(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_MillerIndex" "', argument " "3"" of type '" "int""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_MillerIndex" "', argument " "3"" of type '" "double""'");
   } 
-  arg3 = static_cast< int >(val3);
+  arg3 = static_cast< double >(val3);
   result = (MillerIndex *)new MillerIndex(arg1,arg2,arg3);
   resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_MillerIndex, SWIG_POINTER_NEW |  0 );
   return resultobj;
@@ -103781,10 +97146,10 @@ fail:
 SWIGINTERN PyObject *_wrap_MillerIndex_h_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   MillerIndex *arg1 = (MillerIndex *) 0 ;
-  int arg2 ;
+  double arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int val2 ;
+  double val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
@@ -103795,11 +97160,11 @@ SWIGINTERN PyObject *_wrap_MillerIndex_h_set(PyObject *SWIGUNUSEDPARM(self), PyO
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MillerIndex_h_set" "', argument " "1"" of type '" "MillerIndex *""'"); 
   }
   arg1 = reinterpret_cast< MillerIndex * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "MillerIndex_h_set" "', argument " "2"" of type '" "int""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "MillerIndex_h_set" "', argument " "2"" of type '" "double""'");
   } 
-  arg2 = static_cast< int >(val2);
+  arg2 = static_cast< double >(val2);
   if (arg1) (arg1)->h = arg2;
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -103814,7 +97179,7 @@ SWIGINTERN PyObject *_wrap_MillerIndex_h_get(PyObject *SWIGUNUSEDPARM(self), PyO
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  int result;
+  double result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:MillerIndex_h_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_MillerIndex, 0 |  0 );
@@ -103822,8 +97187,8 @@ SWIGINTERN PyObject *_wrap_MillerIndex_h_get(PyObject *SWIGUNUSEDPARM(self), PyO
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MillerIndex_h_get" "', argument " "1"" of type '" "MillerIndex *""'"); 
   }
   arg1 = reinterpret_cast< MillerIndex * >(argp1);
-  result = (int) ((arg1)->h);
-  resultobj = SWIG_From_int(static_cast< int >(result));
+  result = (double) ((arg1)->h);
+  resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
   return NULL;
@@ -103833,10 +97198,10 @@ fail:
 SWIGINTERN PyObject *_wrap_MillerIndex_k_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   MillerIndex *arg1 = (MillerIndex *) 0 ;
-  int arg2 ;
+  double arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int val2 ;
+  double val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
@@ -103847,11 +97212,11 @@ SWIGINTERN PyObject *_wrap_MillerIndex_k_set(PyObject *SWIGUNUSEDPARM(self), PyO
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MillerIndex_k_set" "', argument " "1"" of type '" "MillerIndex *""'"); 
   }
   arg1 = reinterpret_cast< MillerIndex * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "MillerIndex_k_set" "', argument " "2"" of type '" "int""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "MillerIndex_k_set" "', argument " "2"" of type '" "double""'");
   } 
-  arg2 = static_cast< int >(val2);
+  arg2 = static_cast< double >(val2);
   if (arg1) (arg1)->k = arg2;
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -103866,7 +97231,7 @@ SWIGINTERN PyObject *_wrap_MillerIndex_k_get(PyObject *SWIGUNUSEDPARM(self), PyO
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  int result;
+  double result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:MillerIndex_k_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_MillerIndex, 0 |  0 );
@@ -103874,8 +97239,8 @@ SWIGINTERN PyObject *_wrap_MillerIndex_k_get(PyObject *SWIGUNUSEDPARM(self), PyO
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MillerIndex_k_get" "', argument " "1"" of type '" "MillerIndex *""'"); 
   }
   arg1 = reinterpret_cast< MillerIndex * >(argp1);
-  result = (int) ((arg1)->k);
-  resultobj = SWIG_From_int(static_cast< int >(result));
+  result = (double) ((arg1)->k);
+  resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
   return NULL;
@@ -103885,10 +97250,10 @@ fail:
 SWIGINTERN PyObject *_wrap_MillerIndex_l_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   MillerIndex *arg1 = (MillerIndex *) 0 ;
-  int arg2 ;
+  double arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int val2 ;
+  double val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
@@ -103899,11 +97264,11 @@ SWIGINTERN PyObject *_wrap_MillerIndex_l_set(PyObject *SWIGUNUSEDPARM(self), PyO
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MillerIndex_l_set" "', argument " "1"" of type '" "MillerIndex *""'"); 
   }
   arg1 = reinterpret_cast< MillerIndex * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "MillerIndex_l_set" "', argument " "2"" of type '" "int""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "MillerIndex_l_set" "', argument " "2"" of type '" "double""'");
   } 
-  arg2 = static_cast< int >(val2);
+  arg2 = static_cast< double >(val2);
   if (arg1) (arg1)->l = arg2;
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -103918,7 +97283,7 @@ SWIGINTERN PyObject *_wrap_MillerIndex_l_get(PyObject *SWIGUNUSEDPARM(self), PyO
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
-  int result;
+  double result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:MillerIndex_l_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_MillerIndex, 0 |  0 );
@@ -103926,8 +97291,8 @@ SWIGINTERN PyObject *_wrap_MillerIndex_l_get(PyObject *SWIGUNUSEDPARM(self), PyO
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "MillerIndex_l_get" "', argument " "1"" of type '" "MillerIndex *""'"); 
   }
   arg1 = reinterpret_cast< MillerIndex * >(argp1);
-  result = (int) ((arg1)->l);
-  resultobj = SWIG_From_int(static_cast< int >(result));
+  result = (double) ((arg1)->l);
+  resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
   return NULL;
@@ -104531,16 +97896,16 @@ fail:
 SWIGINTERN PyObject *_wrap_Lattice_getMillerDirection(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Lattice *arg1 = (Lattice *) 0 ;
-  int arg2 ;
-  int arg3 ;
-  int arg4 ;
+  double arg2 ;
+  double arg3 ;
+  double arg4 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int val2 ;
+  double val2 ;
   int ecode2 = 0 ;
-  int val3 ;
+  double val3 ;
   int ecode3 = 0 ;
-  int val4 ;
+  double val4 ;
   int ecode4 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
@@ -104554,21 +97919,21 @@ SWIGINTERN PyObject *_wrap_Lattice_getMillerDirection(PyObject *SWIGUNUSEDPARM(s
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Lattice_getMillerDirection" "', argument " "1"" of type '" "Lattice const *""'"); 
   }
   arg1 = reinterpret_cast< Lattice * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Lattice_getMillerDirection" "', argument " "2"" of type '" "int""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Lattice_getMillerDirection" "', argument " "2"" of type '" "double""'");
   } 
-  arg2 = static_cast< int >(val2);
-  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  arg2 = static_cast< double >(val2);
+  ecode3 = SWIG_AsVal_double(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Lattice_getMillerDirection" "', argument " "3"" of type '" "int""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Lattice_getMillerDirection" "', argument " "3"" of type '" "double""'");
   } 
-  arg3 = static_cast< int >(val3);
-  ecode4 = SWIG_AsVal_int(obj3, &val4);
+  arg3 = static_cast< double >(val3);
+  ecode4 = SWIG_AsVal_double(obj3, &val4);
   if (!SWIG_IsOK(ecode4)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "Lattice_getMillerDirection" "', argument " "4"" of type '" "int""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "Lattice_getMillerDirection" "', argument " "4"" of type '" "double""'");
   } 
-  arg4 = static_cast< int >(val4);
+  arg4 = static_cast< double >(val4);
   result = ((Lattice const *)arg1)->getMillerDirection(arg2,arg3,arg4);
   resultobj = SWIG_NewPointerObj((new kvector_t(static_cast< const kvector_t& >(result))), SWIGTYPE_p_BasicVector3DT_double_t, SWIG_POINTER_OWN |  0 );
   return resultobj;
@@ -126563,42 +119928,26 @@ static PyMethodDef SwigMethods[] = {
 		"clone method \n"
 		"\n"
 		""},
-	 { (char *)"IChiSquaredModule_getSquaredFunction", _wrap_IChiSquaredModule_getSquaredFunction, METH_VARARGS, (char *)"\n"
-		"IChiSquaredModule_getSquaredFunction(IChiSquaredModule self) -> ISquaredFunction\n"
+	 { (char *)"IChiSquaredModule_varianceFunction", _wrap_IChiSquaredModule_varianceFunction, METH_VARARGS, (char *)"\n"
+		"IChiSquaredModule_varianceFunction(IChiSquaredModule self) -> IVarianceFunction\n"
 		"\n"
-		"const ISquaredFunction* IChiSquaredModule::getSquaredFunction() const\n"
+		"const IVarianceFunction * IChiSquaredModule::varianceFunction() const\n"
 		"\n"
 		"Returns squared function. \n"
 		"\n"
 		""},
-	 { (char *)"IChiSquaredModule_setChiSquaredFunction", _wrap_IChiSquaredModule_setChiSquaredFunction, METH_VARARGS, (char *)"\n"
-		"setChiSquaredFunction(ISquaredFunction squared_function)\n"
-		"IChiSquaredModule_setChiSquaredFunction(IChiSquaredModule self, ISquaredFunction squared_function)\n"
-		"\n"
-		"void IChiSquaredModule::setChiSquaredFunction(const ISquaredFunction &squared_function)\n"
-		"\n"
-		""},
-	 { (char *)"IChiSquaredModule_getIntensityNormalizer", _wrap_IChiSquaredModule_getIntensityNormalizer, METH_VARARGS, (char *)"\n"
-		"getIntensityNormalizer() -> IIntensityNormalizer\n"
-		"IChiSquaredModule_getIntensityNormalizer(IChiSquaredModule self) -> IIntensityNormalizer\n"
-		"\n"
-		"virtual IIntensityNormalizer* IChiSquaredModule::getIntensityNormalizer()\n"
-		"\n"
-		"Returns data normalizer, non-const version needed to set internals. \n"
-		"\n"
-		""},
-	 { (char *)"IChiSquaredModule_setIntensityNormalizer", _wrap_IChiSquaredModule_setIntensityNormalizer, METH_VARARGS, (char *)"\n"
-		"IChiSquaredModule_setIntensityNormalizer(IChiSquaredModule self, IIntensityNormalizer data_normalizer)\n"
+	 { (char *)"IChiSquaredModule_setVarianceFunction", _wrap_IChiSquaredModule_setVarianceFunction, METH_VARARGS, (char *)"\n"
+		"IChiSquaredModule_setVarianceFunction(IChiSquaredModule self, IVarianceFunction variance_function)\n"
 		"\n"
-		"void IChiSquaredModule::setIntensityNormalizer(const IIntensityNormalizer &data_normalizer)\n"
+		"void IChiSquaredModule::setVarianceFunction(const IVarianceFunction &variance_function)\n"
 		"\n"
-		"Sets data normalizer. \n"
+		"Sets squared function. \n"
 		"\n"
 		""},
 	 { (char *)"IChiSquaredModule_getIntensityFunction", _wrap_IChiSquaredModule_getIntensityFunction, METH_VARARGS, (char *)"\n"
 		"IChiSquaredModule_getIntensityFunction(IChiSquaredModule self) -> IIntensityFunction\n"
 		"\n"
-		"virtual const IIntensityFunction* IChiSquaredModule::getIntensityFunction() const\n"
+		"const IIntensityFunction * IChiSquaredModule::getIntensityFunction() const\n"
 		"\n"
 		"Returns data rescaler. \n"
 		"\n"
@@ -126611,12 +119960,6 @@ static PyMethodDef SwigMethods[] = {
 		"Sets data rescaler. \n"
 		"\n"
 		""},
-	 { (char *)"IChiSquaredModule_processFitElements", _wrap_IChiSquaredModule_processFitElements, METH_VARARGS, (char *)"\n"
-		"IChiSquaredModule_processFitElements(IChiSquaredModule self, std::vector< FitElement,std::allocator< FitElement > >::iterator arg3, std::vector< FitElement,std::allocator< FitElement > >::iterator arg4)\n"
-		"\n"
-		"virtual void IChiSquaredModule::processFitElements(std::vector< FitElement >::iterator, std::vector< FitElement >::iterator)\n"
-		"\n"
-		""},
 	 { (char *)"IChiSquaredModule_residual", _wrap_IChiSquaredModule_residual, METH_VARARGS, (char *)"\n"
 		"IChiSquaredModule_residual(IChiSquaredModule self, double a, double b, double weight) -> double\n"
 		"\n"
@@ -126662,7 +120005,7 @@ static PyMethodDef SwigMethods[] = {
 		"\n"
 		""},
 	 { (char *)"new_IObservable", _wrap_new_IObservable, METH_VARARGS, (char *)"\n"
-		"new_IObservable(PyObject * arg2) -> IObservable\n"
+		"new_IObservable() -> IObservable\n"
 		"\n"
 		"\n"
 		"\n"
@@ -126671,82 +120014,11 @@ static PyMethodDef SwigMethods[] = {
 		"C++ includes: IObserver.h\n"
 		"\n"
 		""},
-	 { (char *)"disown_IObservable", _wrap_disown_IObservable, METH_VARARGS, NULL},
 	 { (char *)"IObservable_swigregister", IObservable_swigregister, METH_VARARGS, NULL},
-	 { (char *)"new_IFitObserver", _wrap_new_IFitObserver, METH_VARARGS, (char *)"\n"
-		"new_IFitObserver(PyObject * arg2, int update_every_nth) -> IFitObserver\n"
-		"\n"
-		"IFitObserver::IFitObserver(int update_every_nth)\n"
-		"\n"
-		""},
-	 { (char *)"IFitObserver_notify", _wrap_IFitObserver_notify, METH_VARARGS, (char *)"\n"
-		"IFitObserver_notify(IFitObserver self, IObservable subject)\n"
-		"\n"
-		"void IFitObserver::notify(IObservable *subject)\n"
-		"\n"
-		"The method used by Ovservable when he wants to be observed by this. \n"
-		"\n"
-		""},
-	 { (char *)"IFitObserver_update", _wrap_IFitObserver_update, METH_VARARGS, (char *)"\n"
-		"IFitObserver_update(IFitObserver self, FitSuite fit_suite)\n"
-		"\n"
-		"void IFitObserver::update(FitSuite *fit_suite)\n"
-		"\n"
-		"Here Onserver will do actuall job when he thinks that it is a right moment. \n"
-		"\n"
-		""},
-	 { (char *)"delete_IFitObserver", _wrap_delete_IFitObserver, METH_VARARGS, (char *)"delete_IFitObserver(IFitObserver self)"},
-	 { (char *)"disown_IFitObserver", _wrap_disown_IFitObserver, METH_VARARGS, NULL},
-	 { (char *)"IFitObserver_swigregister", IFitObserver_swigregister, METH_VARARGS, NULL},
-	 { (char *)"delete_IFitStrategy", _wrap_delete_IFitStrategy, METH_VARARGS, (char *)"\n"
-		"delete_IFitStrategy(IFitStrategy self)\n"
-		"\n"
-		"virtual IFitStrategy::~IFitStrategy()\n"
-		"\n"
-		""},
-	 { (char *)"IFitStrategy_clone", _wrap_IFitStrategy_clone, METH_VARARGS, (char *)"\n"
-		"IFitStrategy_clone(IFitStrategy self) -> IFitStrategy\n"
-		"\n"
-		"virtual IFitStrategy* IFitStrategy::clone() const =0\n"
-		"\n"
-		""},
-	 { (char *)"IFitStrategy_init", _wrap_IFitStrategy_init, METH_VARARGS, (char *)"\n"
-		"IFitStrategy_init(IFitStrategy self, FitSuiteImpl * fit_suite)\n"
-		"\n"
-		"void IFitStrategy::init(FitSuiteImpl *fit_suite)\n"
-		"\n"
-		""},
-	 { (char *)"IFitStrategy_execute", _wrap_IFitStrategy_execute, METH_VARARGS, (char *)"\n"
-		"IFitStrategy_execute(IFitStrategy self)\n"
-		"\n"
-		"virtual void IFitStrategy::execute()=0\n"
-		"\n"
-		""},
-	 { (char *)"IFitStrategy_swigregister", IFitStrategy_swigregister, METH_VARARGS, NULL},
-	 { (char *)"new_FitStrategyDefault", _wrap_new_FitStrategyDefault, METH_VARARGS, (char *)"\n"
-		"new_FitStrategyDefault() -> FitStrategyDefault\n"
-		"\n"
-		"FitStrategyDefault::FitStrategyDefault()\n"
-		"\n"
-		""},
-	 { (char *)"FitStrategyDefault_clone", _wrap_FitStrategyDefault_clone, METH_VARARGS, (char *)"\n"
-		"FitStrategyDefault_clone(FitStrategyDefault self) -> FitStrategyDefault\n"
-		"\n"
-		"FitStrategyDefault * FitStrategyDefault::clone() const\n"
-		"\n"
-		""},
-	 { (char *)"FitStrategyDefault_execute", _wrap_FitStrategyDefault_execute, METH_VARARGS, (char *)"\n"
-		"FitStrategyDefault_execute(FitStrategyDefault self)\n"
-		"\n"
-		"void FitStrategyDefault::execute()\n"
-		"\n"
-		""},
-	 { (char *)"delete_FitStrategyDefault", _wrap_delete_FitStrategyDefault, METH_VARARGS, (char *)"delete_FitStrategyDefault(FitStrategyDefault self)"},
-	 { (char *)"FitStrategyDefault_swigregister", FitStrategyDefault_swigregister, METH_VARARGS, NULL},
 	 { (char *)"delete_IIntensityFunction", _wrap_delete_IIntensityFunction, METH_VARARGS, (char *)"\n"
 		"delete_IIntensityFunction(IIntensityFunction self)\n"
 		"\n"
-		"virtual IIntensityFunction::~IIntensityFunction()\n"
+		"IIntensityFunction::~IIntensityFunction()\n"
 		"\n"
 		""},
 	 { (char *)"IIntensityFunction_clone", _wrap_IIntensityFunction_clone, METH_VARARGS, (char *)"\n"
@@ -126762,16 +120034,10 @@ static PyMethodDef SwigMethods[] = {
 		"\n"
 		""},
 	 { (char *)"IIntensityFunction_swigregister", IIntensityFunction_swigregister, METH_VARARGS, NULL},
-	 { (char *)"delete_IntensityFunctionLog", _wrap_delete_IntensityFunctionLog, METH_VARARGS, (char *)"\n"
-		"delete_IntensityFunctionLog(IntensityFunctionLog self)\n"
-		"\n"
-		"virtual IntensityFunctionLog::~IntensityFunctionLog()\n"
-		"\n"
-		""},
 	 { (char *)"IntensityFunctionLog_clone", _wrap_IntensityFunctionLog_clone, METH_VARARGS, (char *)"\n"
 		"IntensityFunctionLog_clone(IntensityFunctionLog self) -> IntensityFunctionLog\n"
 		"\n"
-		"virtual IntensityFunctionLog* IntensityFunctionLog::clone() const\n"
+		"IntensityFunctionLog * IntensityFunctionLog::clone() const\n"
 		"\n"
 		""},
 	 { (char *)"IntensityFunctionLog_evaluate", _wrap_IntensityFunctionLog_evaluate, METH_VARARGS, (char *)"\n"
@@ -126790,17 +120056,12 @@ static PyMethodDef SwigMethods[] = {
 		"C++ includes: IIntensityFunction.h\n"
 		"\n"
 		""},
+	 { (char *)"delete_IntensityFunctionLog", _wrap_delete_IntensityFunctionLog, METH_VARARGS, (char *)"delete_IntensityFunctionLog(IntensityFunctionLog self)"},
 	 { (char *)"IntensityFunctionLog_swigregister", IntensityFunctionLog_swigregister, METH_VARARGS, NULL},
-	 { (char *)"delete_IntensityFunctionSqrt", _wrap_delete_IntensityFunctionSqrt, METH_VARARGS, (char *)"\n"
-		"delete_IntensityFunctionSqrt(IntensityFunctionSqrt self)\n"
-		"\n"
-		"virtual IntensityFunctionSqrt::~IntensityFunctionSqrt()\n"
-		"\n"
-		""},
 	 { (char *)"IntensityFunctionSqrt_clone", _wrap_IntensityFunctionSqrt_clone, METH_VARARGS, (char *)"\n"
 		"IntensityFunctionSqrt_clone(IntensityFunctionSqrt self) -> IntensityFunctionSqrt\n"
 		"\n"
-		"virtual IntensityFunctionSqrt* IntensityFunctionSqrt::clone() const\n"
+		"IntensityFunctionSqrt * IntensityFunctionSqrt::clone() const\n"
 		"\n"
 		""},
 	 { (char *)"IntensityFunctionSqrt_evaluate", _wrap_IntensityFunctionSqrt_evaluate, METH_VARARGS, (char *)"\n"
@@ -126819,6 +120080,7 @@ static PyMethodDef SwigMethods[] = {
 		"C++ includes: IIntensityFunction.h\n"
 		"\n"
 		""},
+	 { (char *)"delete_IntensityFunctionSqrt", _wrap_delete_IntensityFunctionSqrt, METH_VARARGS, (char *)"delete_IntensityFunctionSqrt(IntensityFunctionSqrt self)"},
 	 { (char *)"IntensityFunctionSqrt_swigregister", IntensityFunctionSqrt_swigregister, METH_VARARGS, NULL},
 	 { (char *)"delete_IIntensityNormalizer", _wrap_delete_IIntensityNormalizer, METH_VARARGS, (char *)"\n"
 		"delete_IIntensityNormalizer(IIntensityNormalizer self)\n"
@@ -126933,164 +120195,70 @@ static PyMethodDef SwigMethods[] = {
 		"\n"
 		""},
 	 { (char *)"IntensityScaleAndShiftNormalizer_swigregister", IntensityScaleAndShiftNormalizer_swigregister, METH_VARARGS, NULL},
-	 { (char *)"delete_ISquaredFunction", _wrap_delete_ISquaredFunction, METH_VARARGS, (char *)"\n"
-		"delete_ISquaredFunction(ISquaredFunction self)\n"
+	 { (char *)"delete_IVarianceFunction", _wrap_delete_IVarianceFunction, METH_VARARGS, (char *)"\n"
+		"delete_IVarianceFunction(IVarianceFunction self)\n"
 		"\n"
-		"virtual ISquaredFunction::~ISquaredFunction()\n"
+		"IVarianceFunction::~IVarianceFunction()\n"
 		"\n"
 		""},
-	 { (char *)"ISquaredFunction_clone", _wrap_ISquaredFunction_clone, METH_VARARGS, (char *)"\n"
-		"ISquaredFunction_clone(ISquaredFunction self) -> ISquaredFunction\n"
+	 { (char *)"IVarianceFunction_clone", _wrap_IVarianceFunction_clone, METH_VARARGS, (char *)"\n"
+		"IVarianceFunction_clone(IVarianceFunction self) -> IVarianceFunction\n"
 		"\n"
-		"virtual ISquaredFunction* ISquaredFunction::clone() const =0\n"
+		"virtual IVarianceFunction* IVarianceFunction::clone() const =0\n"
 		"\n"
 		""},
-	 { (char *)"ISquaredFunction_calculateSquaredDifference", _wrap_ISquaredFunction_calculateSquaredDifference, METH_VARARGS, (char *)"\n"
-		"ISquaredFunction_calculateSquaredDifference(ISquaredFunction self, double real_value, double simulated_value) -> double\n"
+	 { (char *)"IVarianceFunction_variance", _wrap_IVarianceFunction_variance, METH_VARARGS, (char *)"\n"
+		"IVarianceFunction_variance(IVarianceFunction self, double real_value, double simulated_value) -> double\n"
 		"\n"
-		"virtual double ISquaredFunction::calculateSquaredDifference(double real_value, double simulated_value) const =0\n"
+		"virtual double IVarianceFunction::variance(double real_value, double simulated_value) const =0\n"
 		"\n"
 		""},
-	 { (char *)"ISquaredFunction_calculateSquaredError", _wrap_ISquaredFunction_calculateSquaredError, METH_VARARGS, (char *)"\n"
-		"calculateSquaredError(double real_value, double simulated_value=0.0) -> double\n"
-		"ISquaredFunction_calculateSquaredError(ISquaredFunction self, double real_value) -> double\n"
+	 { (char *)"IVarianceFunction_swigregister", IVarianceFunction_swigregister, METH_VARARGS, NULL},
+	 { (char *)"VarianceConstantFunction_clone", _wrap_VarianceConstantFunction_clone, METH_VARARGS, (char *)"\n"
+		"VarianceConstantFunction_clone(VarianceConstantFunction self) -> VarianceConstantFunction\n"
 		"\n"
-		"virtual double ISquaredFunction::calculateSquaredError(double real_value, double simulated_value=0.0) const =0\n"
+		"VarianceConstantFunction * VarianceConstantFunction::clone() const override\n"
 		"\n"
 		""},
-	 { (char *)"ISquaredFunction_swigregister", ISquaredFunction_swigregister, METH_VARARGS, NULL},
-	 { (char *)"new_SquaredFunctionDefault", _wrap_new_SquaredFunctionDefault, METH_VARARGS, (char *)"\n"
-		"new_SquaredFunctionDefault() -> SquaredFunctionDefault\n"
+	 { (char *)"VarianceConstantFunction_variance", _wrap_VarianceConstantFunction_variance, METH_VARARGS, (char *)"\n"
+		"VarianceConstantFunction_variance(VarianceConstantFunction self, double arg3, double arg4) -> double\n"
 		"\n"
-		"SquaredFunctionDefault::SquaredFunctionDefault()\n"
+		"double VarianceConstantFunction::variance(double, double) const override\n"
 		"\n"
 		""},
-	 { (char *)"delete_SquaredFunctionDefault", _wrap_delete_SquaredFunctionDefault, METH_VARARGS, (char *)"\n"
-		"delete_SquaredFunctionDefault(SquaredFunctionDefault self)\n"
+	 { (char *)"new_VarianceConstantFunction", _wrap_new_VarianceConstantFunction, METH_VARARGS, (char *)"\n"
+		"new_VarianceConstantFunction() -> VarianceConstantFunction\n"
 		"\n"
-		"SquaredFunctionDefault::~SquaredFunctionDefault()\n"
-		"\n"
-		""},
-	 { (char *)"SquaredFunctionDefault_clone", _wrap_SquaredFunctionDefault_clone, METH_VARARGS, (char *)"\n"
-		"SquaredFunctionDefault_clone(SquaredFunctionDefault self) -> SquaredFunctionDefault\n"
-		"\n"
-		"SquaredFunctionDefault * SquaredFunctionDefault::clone() const override\n"
-		"\n"
-		""},
-	 { (char *)"SquaredFunctionDefault_calculateSquaredDifference", _wrap_SquaredFunctionDefault_calculateSquaredDifference, METH_VARARGS, (char *)"\n"
-		"SquaredFunctionDefault_calculateSquaredDifference(SquaredFunctionDefault self, double real_value, double simulated_value) -> double\n"
 		"\n"
-		"double SquaredFunctionDefault::calculateSquaredDifference(double real_value, double simulated_value) const override\n"
 		"\n"
-		""},
-	 { (char *)"SquaredFunctionDefault_calculateSquaredError", _wrap_SquaredFunctionDefault_calculateSquaredError, METH_VARARGS, (char *)"\n"
-		"calculateSquaredError(double real_value, double simulated_value=0) -> double\n"
-		"SquaredFunctionDefault_calculateSquaredError(SquaredFunctionDefault self, double real_value) -> double\n"
-		"\n"
-		"double SquaredFunctionDefault::calculateSquaredError(double real_value, double simulated_value=0) const override\n"
-		"\n"
-		""},
-	 { (char *)"SquaredFunctionDefault_swigregister", SquaredFunctionDefault_swigregister, METH_VARARGS, NULL},
-	 { (char *)"delete_SquaredFunctionSimError", _wrap_delete_SquaredFunctionSimError, METH_VARARGS, (char *)"\n"
-		"delete_SquaredFunctionSimError(SquaredFunctionSimError self)\n"
-		"\n"
-		"SquaredFunctionSimError::~SquaredFunctionSimError()\n"
-		"\n"
-		""},
-	 { (char *)"SquaredFunctionSimError_clone", _wrap_SquaredFunctionSimError_clone, METH_VARARGS, (char *)"\n"
-		"SquaredFunctionSimError_clone(SquaredFunctionSimError self) -> SquaredFunctionSimError\n"
-		"\n"
-		"SquaredFunctionSimError * SquaredFunctionSimError::clone() const override\n"
-		"\n"
-		""},
-	 { (char *)"SquaredFunctionSimError_calculateSquaredDifference", _wrap_SquaredFunctionSimError_calculateSquaredDifference, METH_VARARGS, (char *)"\n"
-		"SquaredFunctionSimError_calculateSquaredDifference(SquaredFunctionSimError self, double real_value, double simulated_value) -> double\n"
-		"\n"
-		"double SquaredFunctionSimError::calculateSquaredDifference(double real_value, double simulated_value) const override\n"
-		"\n"
-		""},
-	 { (char *)"SquaredFunctionSimError_calculateSquaredError", _wrap_SquaredFunctionSimError_calculateSquaredError, METH_VARARGS, (char *)"\n"
-		"SquaredFunctionSimError_calculateSquaredError(SquaredFunctionSimError self, double real_value, double simulated_value) -> double\n"
-		"\n"
-		"double SquaredFunctionSimError::calculateSquaredError(double real_value, double simulated_value) const override\n"
-		"\n"
-		""},
-	 { (char *)"SquaredFunctionSimError_swigregister", SquaredFunctionSimError_swigregister, METH_VARARGS, NULL},
-	 { (char *)"delete_SquaredFunctionMeanSquaredError", _wrap_delete_SquaredFunctionMeanSquaredError, METH_VARARGS, (char *)"\n"
-		"delete_SquaredFunctionMeanSquaredError(SquaredFunctionMeanSquaredError self)\n"
-		"\n"
-		"SquaredFunctionMeanSquaredError::~SquaredFunctionMeanSquaredError()\n"
-		"\n"
-		""},
-	 { (char *)"SquaredFunctionMeanSquaredError_clone", _wrap_SquaredFunctionMeanSquaredError_clone, METH_VARARGS, (char *)"\n"
-		"SquaredFunctionMeanSquaredError_clone(SquaredFunctionMeanSquaredError self) -> SquaredFunctionMeanSquaredError\n"
-		"\n"
-		"SquaredFunctionMeanSquaredError * SquaredFunctionMeanSquaredError::clone() const override\n"
-		"\n"
-		""},
-	 { (char *)"SquaredFunctionMeanSquaredError_calculateSquaredDifference", _wrap_SquaredFunctionMeanSquaredError_calculateSquaredDifference, METH_VARARGS, (char *)"\n"
-		"SquaredFunctionMeanSquaredError_calculateSquaredDifference(SquaredFunctionMeanSquaredError self, double real_value, double simulated_value) -> double\n"
-		"\n"
-		"double SquaredFunctionMeanSquaredError::calculateSquaredDifference(double real_value, double simulated_value) const override\n"
-		"\n"
-		""},
-	 { (char *)"SquaredFunctionMeanSquaredError_calculateSquaredError", _wrap_SquaredFunctionMeanSquaredError_calculateSquaredError, METH_VARARGS, (char *)"\n"
-		"SquaredFunctionMeanSquaredError_calculateSquaredError(SquaredFunctionMeanSquaredError self, double real_value, double simulated_value) -> double\n"
-		"\n"
-		"double SquaredFunctionMeanSquaredError::calculateSquaredError(double real_value, double simulated_value) const override\n"
-		"\n"
-		""},
-	 { (char *)"SquaredFunctionMeanSquaredError_swigregister", SquaredFunctionMeanSquaredError_swigregister, METH_VARARGS, NULL},
-	 { (char *)"delete_SquaredFunctionSystematicError", _wrap_delete_SquaredFunctionSystematicError, METH_VARARGS, (char *)"\n"
-		"delete_SquaredFunctionSystematicError(SquaredFunctionSystematicError self)\n"
-		"\n"
-		"SquaredFunctionSystematicError::~SquaredFunctionSystematicError()\n"
-		"\n"
-		""},
-	 { (char *)"SquaredFunctionSystematicError_clone", _wrap_SquaredFunctionSystematicError_clone, METH_VARARGS, (char *)"\n"
-		"SquaredFunctionSystematicError_clone(SquaredFunctionSystematicError self) -> SquaredFunctionSystematicError\n"
-		"\n"
-		"SquaredFunctionSystematicError * SquaredFunctionSystematicError::clone() const override\n"
-		"\n"
-		""},
-	 { (char *)"SquaredFunctionSystematicError_calculateSquaredDifference", _wrap_SquaredFunctionSystematicError_calculateSquaredDifference, METH_VARARGS, (char *)"\n"
-		"SquaredFunctionSystematicError_calculateSquaredDifference(SquaredFunctionSystematicError self, double real_value, double simulated_value) -> double\n"
-		"\n"
-		"double SquaredFunctionSystematicError::calculateSquaredDifference(double real_value, double simulated_value) const override\n"
-		"\n"
-		""},
-	 { (char *)"SquaredFunctionSystematicError_calculateSquaredError", _wrap_SquaredFunctionSystematicError_calculateSquaredError, METH_VARARGS, (char *)"\n"
-		"SquaredFunctionSystematicError_calculateSquaredError(SquaredFunctionSystematicError self, double real_value, double simulated_value) -> double\n"
-		"\n"
-		"double SquaredFunctionSystematicError::calculateSquaredError(double real_value, double simulated_value) const override\n"
-		"\n"
-		""},
-	 { (char *)"SquaredFunctionSystematicError_swigregister", SquaredFunctionSystematicError_swigregister, METH_VARARGS, NULL},
-	 { (char *)"delete_SquaredFunctionGaussianError", _wrap_delete_SquaredFunctionGaussianError, METH_VARARGS, (char *)"\n"
-		"delete_SquaredFunctionGaussianError(SquaredFunctionGaussianError self)\n"
+		"Returns 1.0 as variance value\n"
 		"\n"
-		"SquaredFunctionGaussianError::~SquaredFunctionGaussianError()\n"
+		"C++ includes: VarianceFunctions.h\n"
 		"\n"
 		""},
-	 { (char *)"SquaredFunctionGaussianError_clone", _wrap_SquaredFunctionGaussianError_clone, METH_VARARGS, (char *)"\n"
-		"SquaredFunctionGaussianError_clone(SquaredFunctionGaussianError self) -> SquaredFunctionGaussianError\n"
+	 { (char *)"delete_VarianceConstantFunction", _wrap_delete_VarianceConstantFunction, METH_VARARGS, (char *)"delete_VarianceConstantFunction(VarianceConstantFunction self)"},
+	 { (char *)"VarianceConstantFunction_swigregister", VarianceConstantFunction_swigregister, METH_VARARGS, NULL},
+	 { (char *)"new_VarianceSimFunction", _wrap_new_VarianceSimFunction, METH_VARARGS, (char *)"\n"
+		"VarianceSimFunction(double epsilon=1.0)\n"
+		"new_VarianceSimFunction() -> VarianceSimFunction\n"
 		"\n"
-		"SquaredFunctionGaussianError * SquaredFunctionGaussianError::clone() const override\n"
+		"VarianceSimFunction::VarianceSimFunction(double epsilon=1.0)\n"
 		"\n"
 		""},
-	 { (char *)"SquaredFunctionGaussianError_calculateSquaredDifference", _wrap_SquaredFunctionGaussianError_calculateSquaredDifference, METH_VARARGS, (char *)"\n"
-		"SquaredFunctionGaussianError_calculateSquaredDifference(SquaredFunctionGaussianError self, double real_value, double simulated_value) -> double\n"
+	 { (char *)"VarianceSimFunction_clone", _wrap_VarianceSimFunction_clone, METH_VARARGS, (char *)"\n"
+		"VarianceSimFunction_clone(VarianceSimFunction self) -> VarianceSimFunction\n"
 		"\n"
-		"double SquaredFunctionGaussianError::calculateSquaredDifference(double real_value, double simulated_value) const override\n"
+		"VarianceSimFunction * VarianceSimFunction::clone() const override\n"
 		"\n"
 		""},
-	 { (char *)"SquaredFunctionGaussianError_calculateSquaredError", _wrap_SquaredFunctionGaussianError_calculateSquaredError, METH_VARARGS, (char *)"\n"
-		"SquaredFunctionGaussianError_calculateSquaredError(SquaredFunctionGaussianError self, double real_value, double simulated_value) -> double\n"
+	 { (char *)"VarianceSimFunction_variance", _wrap_VarianceSimFunction_variance, METH_VARARGS, (char *)"\n"
+		"VarianceSimFunction_variance(VarianceSimFunction self, double exp, double sim) -> double\n"
 		"\n"
-		"double SquaredFunctionGaussianError::calculateSquaredError(double real_value, double simulated_value) const override\n"
+		"double VarianceSimFunction::variance(double exp, double sim) const override\n"
 		"\n"
 		""},
-	 { (char *)"SquaredFunctionGaussianError_swigregister", SquaredFunctionGaussianError_swigregister, METH_VARARGS, NULL},
+	 { (char *)"delete_VarianceSimFunction", _wrap_delete_VarianceSimFunction, METH_VARARGS, (char *)"delete_VarianceSimFunction(VarianceSimFunction self)"},
+	 { (char *)"VarianceSimFunction_swigregister", VarianceSimFunction_swigregister, METH_VARARGS, NULL},
 	 { (char *)"new_ChiSquaredModule", _wrap_new_ChiSquaredModule, METH_VARARGS, (char *)"\n"
 		"ChiSquaredModule()\n"
 		"new_ChiSquaredModule(ChiSquaredModule other) -> ChiSquaredModule\n"
@@ -127112,12 +120280,6 @@ static PyMethodDef SwigMethods[] = {
 		"clone method \n"
 		"\n"
 		""},
-	 { (char *)"ChiSquaredModule_processFitElements", _wrap_ChiSquaredModule_processFitElements, METH_VARARGS, (char *)"\n"
-		"ChiSquaredModule_processFitElements(ChiSquaredModule self, std::vector< FitElement,std::allocator< FitElement > >::iterator first, std::vector< FitElement,std::allocator< FitElement > >::iterator last)\n"
-		"\n"
-		"void ChiSquaredModule::processFitElements(std::vector< FitElement >::iterator first, std::vector< FitElement >::iterator last)\n"
-		"\n"
-		""},
 	 { (char *)"ChiSquaredModule_residual", _wrap_ChiSquaredModule_residual, METH_VARARGS, (char *)"\n"
 		"ChiSquaredModule_residual(ChiSquaredModule self, double a, double b, double weight) -> double\n"
 		"\n"
@@ -127125,125 +120287,6 @@ static PyMethodDef SwigMethods[] = {
 		"\n"
 		""},
 	 { (char *)"ChiSquaredModule_swigregister", ChiSquaredModule_swigregister, METH_VARARGS, NULL},
-	 { (char *)"new_FitObject", _wrap_new_FitObject, METH_VARARGS, (char *)"\n"
-		"FitObject(Simulation simulation, IntensityData data, double weight=1)\n"
-		"FitObject(Simulation simulation, IntensityData data)\n"
-		"FitObject(Simulation simulation, vdouble2d_t data, double weight=1)\n"
-		"new_FitObject(Simulation simulation, vdouble2d_t data) -> FitObject\n"
-		"\n"
-		"FitObject::FitObject(const Simulation &simulation, const std::vector< std::vector< double >> &data, double weight=1)\n"
-		"\n"
-		"Constructs simulation/data pair for later fit.\n"
-		"\n"
-		"Parameters:\n"
-		"-----------\n"
-		"\n"
-		"simulation: \n"
-		"simulation to run\n"
-		"\n"
-		"data: \n"
-		"experimental data\n"
-		"\n"
-		"weight: \n"
-		"weight of dataset in chi2 calculations \n"
-		"\n"
-		""},
-	 { (char *)"delete_FitObject", _wrap_delete_FitObject, METH_VARARGS, (char *)"\n"
-		"delete_FitObject(FitObject self)\n"
-		"\n"
-		"FitObject::~FitObject()\n"
-		"\n"
-		""},
-	 { (char *)"FitObject_accept", _wrap_FitObject_accept, METH_VARARGS, (char *)"\n"
-		"FitObject_accept(FitObject self, INodeVisitor visitor)\n"
-		"\n"
-		"void FitObject::accept(INodeVisitor *visitor) const final\n"
-		"\n"
-		"Calls the  INodeVisitor's visit method. \n"
-		"\n"
-		""},
-	 { (char *)"FitObject_weight", _wrap_FitObject_weight, METH_VARARGS, (char *)"\n"
-		"FitObject_weight(FitObject self) -> double\n"
-		"\n"
-		"double FitObject::weight() const\n"
-		"\n"
-		"Returns weight of data set in chi2 calculations. \n"
-		"\n"
-		""},
-	 { (char *)"FitObject_numberOfFitElements", _wrap_FitObject_numberOfFitElements, METH_VARARGS, (char *)"\n"
-		"FitObject_numberOfFitElements(FitObject self) -> size_t\n"
-		"\n"
-		"size_t FitObject::numberOfFitElements() const\n"
-		"\n"
-		"Returns the size of the data. It is equal to the number of non-masked detector channels which will participate in chi2 calculations. \n"
-		"\n"
-		""},
-	 { (char *)"FitObject_prepareFitElements", _wrap_FitObject_prepareFitElements, METH_VARARGS, (char *)"\n"
-		"prepareFitElements(std::vector< FitElement,std::allocator< FitElement > > & fit_elements, double weight, IIntensityNormalizer arg4=None)\n"
-		"FitObject_prepareFitElements(FitObject self, std::vector< FitElement,std::allocator< FitElement > > & fit_elements, double weight)\n"
-		"\n"
-		"void FitObject::prepareFitElements(std::vector< FitElement > &fit_elements, double weight, IIntensityNormalizer *=0)\n"
-		"\n"
-		"Runs simulation and put results (the real and simulated intensities) into external vector. Masked channels will be excluded from the vector. \n"
-		"\n"
-		""},
-	 { (char *)"FitObject_getChildren", _wrap_FitObject_getChildren, METH_VARARGS, (char *)"\n"
-		"FitObject_getChildren(FitObject self) -> swig_dummy_type_const_inode_vector\n"
-		"\n"
-		"std::vector< const INode * > FitObject::getChildren() const\n"
-		"\n"
-		"Returns a vector of children (const). \n"
-		"\n"
-		""},
-	 { (char *)"FitObject_simulationResult", _wrap_FitObject_simulationResult, METH_VARARGS, (char *)"\n"
-		"FitObject_simulationResult(FitObject self) -> SimulationResult\n"
-		"\n"
-		"SimulationResult FitObject::simulationResult() const\n"
-		"\n"
-		"Returns simulation result. \n"
-		"\n"
-		""},
-	 { (char *)"FitObject_experimentalData", _wrap_FitObject_experimentalData, METH_VARARGS, (char *)"\n"
-		"FitObject_experimentalData(FitObject self) -> SimulationResult\n"
-		"\n"
-		"SimulationResult FitObject::experimentalData() const\n"
-		"\n"
-		"Returns experimental data. \n"
-		"\n"
-		""},
-	 { (char *)"FitObject_relativeDifference", _wrap_FitObject_relativeDifference, METH_VARARGS, (char *)"\n"
-		"FitObject_relativeDifference(FitObject self) -> SimulationResult\n"
-		"\n"
-		"SimulationResult FitObject::relativeDifference() const\n"
-		"\n"
-		"Returns relative difference between simulation and experimental data. \n"
-		"\n"
-		""},
-	 { (char *)"FitObject_runSimulation", _wrap_FitObject_runSimulation, METH_VARARGS, (char *)"\n"
-		"FitObject_runSimulation(FitObject self)\n"
-		"\n"
-		"void FitObject::runSimulation()\n"
-		"\n"
-		"Runs internal simulation object. \n"
-		"\n"
-		""},
-	 { (char *)"FitObject_experimental_array", _wrap_FitObject_experimental_array, METH_VARARGS, (char *)"\n"
-		"FitObject_experimental_array(FitObject self) -> vdouble1d_t\n"
-		"\n"
-		"std::vector< double > FitObject::experimental_array() const\n"
-		"\n"
-		"Returns one dimensional array representing experimental data. Masked areas and the area outside of region of interest are not included. \n"
-		"\n"
-		""},
-	 { (char *)"FitObject_simulation_array", _wrap_FitObject_simulation_array, METH_VARARGS, (char *)"\n"
-		"FitObject_simulation_array(FitObject self) -> vdouble1d_t\n"
-		"\n"
-		"std::vector< double > FitObject::simulation_array() const\n"
-		"\n"
-		"Returns one dimensional array representing simulated intensities data. Masked areas and the area outside of region of interest are not included. \n"
-		"\n"
-		""},
-	 { (char *)"FitObject_swigregister", FitObject_swigregister, METH_VARARGS, NULL},
 	 { (char *)"new_FitOptions", _wrap_new_FitOptions, METH_VARARGS, (char *)"new_FitOptions() -> FitOptions"},
 	 { (char *)"FitOptions_derivEpsilon", _wrap_FitOptions_derivEpsilon, METH_VARARGS, (char *)"FitOptions_derivEpsilon(FitOptions self) -> double"},
 	 { (char *)"FitOptions_setDerivEpsilon", _wrap_FitOptions_setDerivEpsilon, METH_VARARGS, (char *)"FitOptions_setDerivEpsilon(FitOptions self, double deriv_epsilon)"},
@@ -127251,841 +120294,6 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"FitOptions_setStepFactor", _wrap_FitOptions_setStepFactor, METH_VARARGS, (char *)"FitOptions_setStepFactor(FitOptions self, double step_factor)"},
 	 { (char *)"delete_FitOptions", _wrap_delete_FitOptions, METH_VARARGS, (char *)"delete_FitOptions(FitOptions self)"},
 	 { (char *)"FitOptions_swigregister", FitOptions_swigregister, METH_VARARGS, NULL},
-	 { (char *)"new_IFitParameter", _wrap_new_IFitParameter, METH_VARARGS, (char *)"\n"
-		"IFitParameter()\n"
-		"IFitParameter(std::string const & name, double value, AttLimits limits, double step=0.0)\n"
-		"IFitParameter(std::string const & name, double value, AttLimits limits)\n"
-		"new_IFitParameter(std::string const & name, double value) -> IFitParameter\n"
-		"\n"
-		"IFitParameter::IFitParameter(const std::string &name, double value, const AttLimits &limits=AttLimits::limitless(), double step=0.0)\n"
-		"\n"
-		""},
-	 { (char *)"delete_IFitParameter", _wrap_delete_IFitParameter, METH_VARARGS, (char *)"\n"
-		"delete_IFitParameter(IFitParameter self)\n"
-		"\n"
-		"virtual IFitParameter::~IFitParameter()\n"
-		"\n"
-		""},
-	 { (char *)"IFitParameter_clone", _wrap_IFitParameter_clone, METH_VARARGS, (char *)"\n"
-		"IFitParameter_clone(IFitParameter self) -> IFitParameter\n"
-		"\n"
-		"IFitParameter * IFitParameter::clone() const\n"
-		"\n"
-		""},
-	 { (char *)"IFitParameter_name", _wrap_IFitParameter_name, METH_VARARGS, (char *)"\n"
-		"IFitParameter_name(IFitParameter self) -> std::string\n"
-		"\n"
-		"std::string IFitParameter::name() const\n"
-		"\n"
-		""},
-	 { (char *)"IFitParameter_setName", _wrap_IFitParameter_setName, METH_VARARGS, (char *)"\n"
-		"IFitParameter_setName(IFitParameter self, std::string const & name) -> IFitParameter\n"
-		"\n"
-		"IFitParameter & IFitParameter::setName(const std::string &name)\n"
-		"\n"
-		""},
-	 { (char *)"IFitParameter_startValue", _wrap_IFitParameter_startValue, METH_VARARGS, (char *)"\n"
-		"IFitParameter_startValue(IFitParameter self) -> double\n"
-		"\n"
-		"double IFitParameter::startValue() const\n"
-		"\n"
-		""},
-	 { (char *)"IFitParameter_setStartValue", _wrap_IFitParameter_setStartValue, METH_VARARGS, (char *)"\n"
-		"IFitParameter_setStartValue(IFitParameter self, double value)\n"
-		"\n"
-		"void IFitParameter::setStartValue(double value)\n"
-		"\n"
-		""},
-	 { (char *)"IFitParameter_value", _wrap_IFitParameter_value, METH_VARARGS, (char *)"\n"
-		"IFitParameter_value(IFitParameter self) -> double\n"
-		"\n"
-		"double IFitParameter::value() const\n"
-		"\n"
-		""},
-	 { (char *)"IFitParameter_setValue", _wrap_IFitParameter_setValue, METH_VARARGS, (char *)"\n"
-		"IFitParameter_setValue(IFitParameter self, double value)\n"
-		"\n"
-		"void IFitParameter::setValue(double value)\n"
-		"\n"
-		""},
-	 { (char *)"IFitParameter_addPattern", _wrap_IFitParameter_addPattern, METH_VARARGS, (char *)"\n"
-		"IFitParameter_addPattern(IFitParameter self, std::string const & pattern) -> IFitParameter\n"
-		"\n"
-		"IFitParameter & IFitParameter::addPattern(const std::string &pattern)\n"
-		"\n"
-		""},
-	 { (char *)"IFitParameter_step", _wrap_IFitParameter_step, METH_VARARGS, (char *)"\n"
-		"IFitParameter_step(IFitParameter self) -> double\n"
-		"\n"
-		"double IFitParameter::step() const\n"
-		"\n"
-		""},
-	 { (char *)"IFitParameter_setStep", _wrap_IFitParameter_setStep, METH_VARARGS, (char *)"\n"
-		"IFitParameter_setStep(IFitParameter self, double value) -> IFitParameter\n"
-		"\n"
-		"IFitParameter & IFitParameter::setStep(double value)\n"
-		"\n"
-		""},
-	 { (char *)"IFitParameter_error", _wrap_IFitParameter_error, METH_VARARGS, (char *)"\n"
-		"IFitParameter_error(IFitParameter self) -> double\n"
-		"\n"
-		"double IFitParameter::error() const\n"
-		"\n"
-		""},
-	 { (char *)"IFitParameter_setError", _wrap_IFitParameter_setError, METH_VARARGS, (char *)"\n"
-		"IFitParameter_setError(IFitParameter self, double value)\n"
-		"\n"
-		"void IFitParameter::setError(double value)\n"
-		"\n"
-		""},
-	 { (char *)"IFitParameter_limits", _wrap_IFitParameter_limits, METH_VARARGS, (char *)"\n"
-		"limits() -> AttLimits\n"
-		"IFitParameter_limits(IFitParameter self) -> AttLimits\n"
-		"\n"
-		"AttLimits & IFitParameter::limits()\n"
-		"\n"
-		""},
-	 { (char *)"IFitParameter_setLimits", _wrap_IFitParameter_setLimits, METH_VARARGS, (char *)"\n"
-		"IFitParameter_setLimits(IFitParameter self, AttLimits limits) -> IFitParameter\n"
-		"\n"
-		"IFitParameter & IFitParameter::setLimits(const AttLimits &limits)\n"
-		"\n"
-		""},
-	 { (char *)"IFitParameter_setLowerLimited", _wrap_IFitParameter_setLowerLimited, METH_VARARGS, (char *)"\n"
-		"IFitParameter_setLowerLimited(IFitParameter self, double bound_value) -> IFitParameter\n"
-		"\n"
-		"IFitParameter & IFitParameter::setLowerLimited(double bound_value)\n"
-		"\n"
-		""},
-	 { (char *)"IFitParameter_setPositive", _wrap_IFitParameter_setPositive, METH_VARARGS, (char *)"\n"
-		"IFitParameter_setPositive(IFitParameter self) -> IFitParameter\n"
-		"\n"
-		"IFitParameter & IFitParameter::setPositive()\n"
-		"\n"
-		""},
-	 { (char *)"IFitParameter_setNonnegative", _wrap_IFitParameter_setNonnegative, METH_VARARGS, (char *)"\n"
-		"IFitParameter_setNonnegative(IFitParameter self) -> IFitParameter\n"
-		"\n"
-		"IFitParameter & IFitParameter::setNonnegative()\n"
-		"\n"
-		""},
-	 { (char *)"IFitParameter_setUpperLimited", _wrap_IFitParameter_setUpperLimited, METH_VARARGS, (char *)"\n"
-		"IFitParameter_setUpperLimited(IFitParameter self, double bound_value) -> IFitParameter\n"
-		"\n"
-		"IFitParameter & IFitParameter::setUpperLimited(double bound_value)\n"
-		"\n"
-		""},
-	 { (char *)"IFitParameter_setLimited", _wrap_IFitParameter_setLimited, METH_VARARGS, (char *)"\n"
-		"IFitParameter_setLimited(IFitParameter self, double left_bound_value, double right_bound_value) -> IFitParameter\n"
-		"\n"
-		"IFitParameter & IFitParameter::setLimited(double left_bound_value, double right_bound_value)\n"
-		"\n"
-		""},
-	 { (char *)"IFitParameter_setFixed", _wrap_IFitParameter_setFixed, METH_VARARGS, (char *)"\n"
-		"IFitParameter_setFixed(IFitParameter self) -> IFitParameter\n"
-		"\n"
-		"IFitParameter & IFitParameter::setFixed()\n"
-		"\n"
-		""},
-	 { (char *)"IFitParameter_toString", _wrap_IFitParameter_toString, METH_VARARGS, (char *)"\n"
-		"IFitParameter_toString(IFitParameter self) -> std::string\n"
-		"\n"
-		"std::string IFitParameter::toString() const\n"
-		"\n"
-		""},
-	 { (char *)"IFitParameter_swigregister", IFitParameter_swigregister, METH_VARARGS, NULL},
-	 { (char *)"new_FitParameterSet", _wrap_new_FitParameterSet, METH_VARARGS, (char *)"\n"
-		"new_FitParameterSet() -> FitParameterSet\n"
-		"\n"
-		"FitParameterSet::FitParameterSet()\n"
-		"\n"
-		""},
-	 { (char *)"delete_FitParameterSet", _wrap_delete_FitParameterSet, METH_VARARGS, (char *)"\n"
-		"delete_FitParameterSet(FitParameterSet self)\n"
-		"\n"
-		"FitParameterSet::~FitParameterSet()\n"
-		"\n"
-		""},
-	 { (char *)"FitParameterSet_clear", _wrap_FitParameterSet_clear, METH_VARARGS, (char *)"\n"
-		"FitParameterSet_clear(FitParameterSet self)\n"
-		"\n"
-		"void FitParameterSet::clear()\n"
-		"\n"
-		"Clears all defined parameters. \n"
-		"\n"
-		""},
-	 { (char *)"FitParameterSet_size", _wrap_FitParameterSet_size, METH_VARARGS, (char *)"\n"
-		"FitParameterSet_size(FitParameterSet self) -> size_t\n"
-		"\n"
-		"size_t FitParameterSet::size() const\n"
-		"\n"
-		"Returns number of parameters. \n"
-		"\n"
-		""},
-	 { (char *)"FitParameterSet_begin", _wrap_FitParameterSet_begin, METH_VARARGS, (char *)"\n"
-		"begin() -> FitParameterSet::iterator\n"
-		"FitParameterSet_begin(FitParameterSet self) -> FitParameterSet::const_iterator\n"
-		"\n"
-		"FitParameterSet::const_iterator FitParameterSet::begin() const\n"
-		"\n"
-		""},
-	 { (char *)"FitParameterSet_end", _wrap_FitParameterSet_end, METH_VARARGS, (char *)"\n"
-		"end() -> FitParameterSet::iterator\n"
-		"FitParameterSet_end(FitParameterSet self) -> FitParameterSet::const_iterator\n"
-		"\n"
-		"FitParameterSet::const_iterator FitParameterSet::end() const\n"
-		"\n"
-		""},
-	 { (char *)"FitParameterSet_addFitParameter", _wrap_FitParameterSet_addFitParameter, METH_VARARGS, (char *)"\n"
-		"FitParameterSet_addFitParameter(FitParameterSet self, IFitParameter par)\n"
-		"\n"
-		"void FitParameterSet::addFitParameter(IFitParameter *par)\n"
-		"\n"
-		"Adds fit parameter. \n"
-		"\n"
-		""},
-	 { (char *)"FitParameterSet_fitParameter", _wrap_FitParameterSet_fitParameter, METH_VARARGS, (char *)"\n"
-		"fitParameter(std::string const & name) -> IFitParameter\n"
-		"FitParameterSet_fitParameter(FitParameterSet self, std::string const & name) -> IFitParameter\n"
-		"\n"
-		"IFitParameter * FitParameterSet::fitParameter(const std::string &name)\n"
-		"\n"
-		""},
-	 { (char *)"FitParameterSet_values", _wrap_FitParameterSet_values, METH_VARARGS, (char *)"\n"
-		"FitParameterSet_values(FitParameterSet self) -> vdouble1d_t\n"
-		"\n"
-		"std::vector< double > FitParameterSet::values() const\n"
-		"\n"
-		"Returns values of all defined parameters. \n"
-		"\n"
-		""},
-	 { (char *)"FitParameterSet_setValues", _wrap_FitParameterSet_setValues, METH_VARARGS, (char *)"\n"
-		"FitParameterSet_setValues(FitParameterSet self, vdouble1d_t pars_values)\n"
-		"\n"
-		"void FitParameterSet::setValues(const std::vector< double > &pars_values)\n"
-		"\n"
-		"Sets values for all defined parameters. \n"
-		"\n"
-		""},
-	 { (char *)"FitParameterSet_valuesDifferFrom", _wrap_FitParameterSet_valuesDifferFrom, METH_VARARGS, (char *)"\n"
-		"valuesDifferFrom(vdouble1d_t par_values, double tolerance=2.0) -> bool\n"
-		"FitParameterSet_valuesDifferFrom(FitParameterSet self, vdouble1d_t par_values) -> bool\n"
-		"\n"
-		"bool FitParameterSet::valuesDifferFrom(const std::vector< double > &par_values, double tolerance=2.0) const\n"
-		"\n"
-		"Returns true if parameters already have the given values. \n"
-		"\n"
-		""},
-	 { (char *)"FitParameterSet_errors", _wrap_FitParameterSet_errors, METH_VARARGS, (char *)"\n"
-		"FitParameterSet_errors(FitParameterSet self) -> vdouble1d_t\n"
-		"\n"
-		"std::vector< double > FitParameterSet::errors() const\n"
-		"\n"
-		"Returns errors of all defined parameters. \n"
-		"\n"
-		""},
-	 { (char *)"FitParameterSet_setErrors", _wrap_FitParameterSet_setErrors, METH_VARARGS, (char *)"\n"
-		"FitParameterSet_setErrors(FitParameterSet self, vdouble1d_t pars_errors)\n"
-		"\n"
-		"void FitParameterSet::setErrors(const std::vector< double > &pars_errors)\n"
-		"\n"
-		"Sets errors to all parameters. \n"
-		"\n"
-		""},
-	 { (char *)"FitParameterSet_freeFitParameterCount", _wrap_FitParameterSet_freeFitParameterCount, METH_VARARGS, (char *)"\n"
-		"FitParameterSet_freeFitParameterCount(FitParameterSet self) -> size_t\n"
-		"\n"
-		"size_t FitParameterSet::freeFitParameterCount() const\n"
-		"\n"
-		"Returns number of free parameters. \n"
-		"\n"
-		""},
-	 { (char *)"FitParameterSet_fixAll", _wrap_FitParameterSet_fixAll, METH_VARARGS, (char *)"\n"
-		"FitParameterSet_fixAll(FitParameterSet self)\n"
-		"\n"
-		"void FitParameterSet::fixAll()\n"
-		"\n"
-		"Fix all parameters. \n"
-		"\n"
-		""},
-	 { (char *)"FitParameterSet_releaseAll", _wrap_FitParameterSet_releaseAll, METH_VARARGS, (char *)"\n"
-		"FitParameterSet_releaseAll(FitParameterSet self)\n"
-		"\n"
-		"void FitParameterSet::releaseAll()\n"
-		"\n"
-		"Release all parameters. \n"
-		"\n"
-		""},
-	 { (char *)"FitParameterSet_setFixed", _wrap_FitParameterSet_setFixed, METH_VARARGS, (char *)"\n"
-		"FitParameterSet_setFixed(FitParameterSet self, vector_string_t pars, bool is_fixed)\n"
-		"\n"
-		"void FitParameterSet::setFixed(const std::vector< std::string > &pars, bool is_fixed)\n"
-		"\n"
-		"Set fixed flag for parameters from the list. \n"
-		"\n"
-		""},
-	 { (char *)"FitParameterSet_correlationMatrix", _wrap_FitParameterSet_correlationMatrix, METH_VARARGS, (char *)"\n"
-		"FitParameterSet_correlationMatrix(FitParameterSet self) -> vdouble2d_t\n"
-		"\n"
-		"corr_matrix_t FitParameterSet::correlationMatrix() const\n"
-		"\n"
-		""},
-	 { (char *)"FitParameterSet_setCorrelationMatrix", _wrap_FitParameterSet_setCorrelationMatrix, METH_VARARGS, (char *)"\n"
-		"FitParameterSet_setCorrelationMatrix(FitParameterSet self, vdouble2d_t matrix)\n"
-		"\n"
-		"void FitParameterSet::setCorrelationMatrix(const corr_matrix_t &matrix)\n"
-		"\n"
-		"Sets resulting correlation matrix. \n"
-		"\n"
-		""},
-	 { (char *)"FitParameterSet_fitParametersNewKernel", _wrap_FitParameterSet_fitParametersNewKernel, METH_VARARGS, (char *)"\n"
-		"FitParameterSet_fitParametersNewKernel(FitParameterSet self) -> Parameters\n"
-		"\n"
-		"Fit::Parameters FitParameterSet::fitParametersNewKernel() const\n"
-		"\n"
-		"Refactoring temp: returns set of new fit parameters. \n"
-		"\n"
-		""},
-	 { (char *)"FitParameterSet___getitem__", _wrap_FitParameterSet___getitem__, METH_VARARGS, (char *)"\n"
-		"__getitem__(std::string name) -> IFitParameter\n"
-		"FitParameterSet___getitem__(FitParameterSet self, size_t index) -> IFitParameter\n"
-		""},
-	 { (char *)"FitParameterSet_swigregister", FitParameterSet_swigregister, METH_VARARGS, NULL},
-	 { (char *)"new_FitParameter", _wrap_new_FitParameter, METH_VARARGS, (char *)"\n"
-		"FitParameter()\n"
-		"FitParameter(std::string const & pattern, double value, AttLimits lim, double step=0.0)\n"
-		"FitParameter(std::string const & pattern, double value, AttLimits lim)\n"
-		"FitParameter(std::string const & pattern, double value)\n"
-		"FitParameter(double value, AttLimits lim, double step=0.0)\n"
-		"FitParameter(double value, AttLimits lim)\n"
-		"new_FitParameter(double value) -> FitParameter\n"
-		"\n"
-		"FitParameter::FitParameter(double value, const AttLimits &lim=AttLimits::limitless(), double step=0.0)\n"
-		"\n"
-		""},
-	 { (char *)"delete_FitParameter", _wrap_delete_FitParameter, METH_VARARGS, (char *)"\n"
-		"delete_FitParameter(FitParameter self)\n"
-		"\n"
-		"FitParameter::~FitParameter() final\n"
-		"\n"
-		""},
-	 { (char *)"FitParameter_clone", _wrap_FitParameter_clone, METH_VARARGS, (char *)"\n"
-		"FitParameter_clone(FitParameter self) -> FitParameter\n"
-		"\n"
-		"FitParameter * FitParameter::clone() const\n"
-		"\n"
-		""},
-	 { (char *)"FitParameter_setValue", _wrap_FitParameter_setValue, METH_VARARGS, (char *)"\n"
-		"FitParameter_setValue(FitParameter self, double value)\n"
-		"\n"
-		"void FitParameter::setValue(double value) final\n"
-		"\n"
-		"Sets given value for all bound parameters. \n"
-		"\n"
-		""},
-	 { (char *)"FitParameter_addPattern", _wrap_FitParameter_addPattern, METH_VARARGS, (char *)"\n"
-		"FitParameter_addPattern(FitParameter self, std::string const & pattern) -> FitParameter\n"
-		"\n"
-		"FitParameter & FitParameter::addPattern(const std::string &pattern)\n"
-		"\n"
-		"Adds pattern to the list for later usage in parameter pool matching. \n"
-		"\n"
-		""},
-	 { (char *)"FitParameter_addParameter", _wrap_FitParameter_addParameter, METH_VARARGS, (char *)"\n"
-		"FitParameter_addParameter(FitParameter self, RealParameter par)\n"
-		"\n"
-		"void FitParameter::addParameter(const RealParameter &par)\n"
-		"\n"
-		"Adds real parameter to the collection. \n"
-		"\n"
-		""},
-	 { (char *)"FitParameter_addMatchedParameters", _wrap_FitParameter_addMatchedParameters, METH_VARARGS, (char *)"\n"
-		"FitParameter_addMatchedParameters(FitParameter self, ParameterPool pool)\n"
-		"\n"
-		"void FitParameter::addMatchedParameters(const ParameterPool &pool)\n"
-		"\n"
-		"Adds parameters from pool which match given wildcard. \n"
-		"\n"
-		""},
-	 { (char *)"FitParameter_patterns", _wrap_FitParameter_patterns, METH_VARARGS, (char *)"\n"
-		"FitParameter_patterns(FitParameter self) -> vector_string_t\n"
-		"\n"
-		"std::vector< std::string > FitParameter::patterns() const\n"
-		"\n"
-		""},
-	 { (char *)"FitParameter_matchedParameterNames", _wrap_FitParameter_matchedParameterNames, METH_VARARGS, (char *)"\n"
-		"FitParameter_matchedParameterNames(FitParameter self) -> vector_string_t\n"
-		"\n"
-		"std::vector< std::string > FitParameter::matchedParameterNames() const\n"
-		"\n"
-		"Returns vector of strings with names of all matched parameters. \n"
-		"\n"
-		""},
-	 { (char *)"FitParameter_patternIntersection", _wrap_FitParameter_patternIntersection, METH_VARARGS, (char *)"\n"
-		"FitParameter_patternIntersection(FitParameter self, FitParameter other) -> vector_string_t\n"
-		"\n"
-		"std::vector< std::string > FitParameter::patternIntersection(const FitParameter &other) const\n"
-		"\n"
-		"Returns vector containing patterns existing in both FitParametersLinked. \n"
-		"\n"
-		""},
-	 { (char *)"FitParameter_isConflicting", _wrap_FitParameter_isConflicting, METH_VARARGS, (char *)"\n"
-		"FitParameter_isConflicting(FitParameter self, FitParameter other) -> bool\n"
-		"\n"
-		"bool FitParameter::isConflicting(const FitParameter &other) const\n"
-		"\n"
-		"Returns true if two FitParameterLinked are intended to steer same  RealParameter. \n"
-		"\n"
-		""},
-	 { (char *)"FitParameter_swigregister", FitParameter_swigregister, METH_VARARGS, NULL},
-	 { (char *)"new_FitSuite", _wrap_new_FitSuite, METH_VARARGS, (char *)"\n"
-		"new_FitSuite() -> FitSuite\n"
-		"\n"
-		"FitSuite::FitSuite(const FitSuite &)=delete\n"
-		"\n"
-		""},
-	 { (char *)"delete_FitSuite", _wrap_delete_FitSuite, METH_VARARGS, (char *)"\n"
-		"delete_FitSuite(FitSuite self)\n"
-		"\n"
-		"FitSuite::~FitSuite()\n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_addSimulationAndRealData", _wrap_FitSuite_addSimulationAndRealData, METH_VARARGS, (char *)"\n"
-		"addSimulationAndRealData(Simulation simulation, IntensityData real_data, double weight=1)\n"
-		"addSimulationAndRealData(Simulation simulation, IntensityData real_data)\n"
-		"addSimulationAndRealData(Simulation simulation, IHistogram real_data, double weight=1)\n"
-		"addSimulationAndRealData(Simulation simulation, IHistogram real_data)\n"
-		"addSimulationAndRealData(Simulation simulation, vdouble2d_t real_data, double weight=1)\n"
-		"addSimulationAndRealData(Simulation simulation, vdouble2d_t real_data)\n"
-		"addSimulationAndRealData(Simulation simulation, vdouble1d_t real_data, double weight=1)\n"
-		"FitSuite_addSimulationAndRealData(FitSuite self, Simulation simulation, vdouble1d_t real_data)\n"
-		"\n"
-		"void FitSuite::addSimulationAndRealData(const Simulation &simulation, const std::vector< double > &real_data, double weight=1)\n"
-		"\n"
-		"Assigns pair of (simulation, real_data) for fitting. A version for the  real_data represented as a one-dimensional numpy array.  Simulation output must agree in dimensions with  real_data. \n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_addFitParameter", _wrap_FitSuite_addFitParameter, METH_VARARGS, (char *)"\n"
-		"addFitParameter(std::string const & pattern, double value, AttLimits limits, double step=0.0) -> FitParameter\n"
-		"addFitParameter(std::string const & pattern, double value, AttLimits limits) -> FitParameter\n"
-		"addFitParameter(std::string const & pattern, double value) -> FitParameter\n"
-		"FitSuite_addFitParameter(FitSuite self, FitParameter fitPar) -> FitParameter\n"
-		"\n"
-		"FitParameter * FitSuite::addFitParameter(const FitParameter &fitPar)\n"
-		"\n"
-		"Adds fit parameter\n"
-		"\n"
-		"Parameters:\n"
-		"-----------\n"
-		"\n"
-		"fitPar: \n"
-		"Fully constructed fit parameter. \n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_setChiSquaredModule", _wrap_FitSuite_setChiSquaredModule, METH_VARARGS, (char *)"\n"
-		"FitSuite_setChiSquaredModule(FitSuite self, IChiSquaredModule chi2_module)\n"
-		"\n"
-		"void FitSuite::setChiSquaredModule(const IChiSquaredModule &chi2_module)\n"
-		"\n"
-		"Replaces default  ChiSquaredModule with new one. \n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_addFitStrategy", _wrap_FitSuite_addFitStrategy, METH_VARARGS, (char *)"\n"
-		"FitSuite_addFitStrategy(FitSuite self, IFitStrategy strategy)\n"
-		"\n"
-		"void FitSuite::addFitStrategy(const IFitStrategy &strategy)\n"
-		"\n"
-		"Adds fit strategy. \n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_setMinimizer", _wrap_FitSuite_setMinimizer, METH_VARARGS, (char *)"\n"
-		"setMinimizer(std::string const & minimizer_name, std::string const & algorithm_name, std::string const & minimizer_options)\n"
-		"setMinimizer(std::string const & minimizer_name, std::string const & algorithm_name)\n"
-		"setMinimizer(std::string const & minimizer_name)\n"
-		"FitSuite_setMinimizer(FitSuite self, IMinimizer * minimizer)\n"
-		"\n"
-		"void FitSuite::setMinimizer(IMinimizer *minimizer)\n"
-		"\n"
-		"Sets minimizer. \n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_minimizerName", _wrap_FitSuite_minimizerName, METH_VARARGS, (char *)"\n"
-		"FitSuite_minimizerName(FitSuite self) -> std::string\n"
-		"\n"
-		"std::string FitSuite::minimizerName() const\n"
-		"\n"
-		"Returns minimizer. \n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_initPrint", _wrap_FitSuite_initPrint, METH_VARARGS, (char *)"\n"
-		"FitSuite_initPrint(FitSuite self, int print_every_nth)\n"
-		"\n"
-		"void FitSuite::initPrint(int print_every_nth)\n"
-		"\n"
-		"Initializes printing to standard output during the fitting. Prints also the summary when completed.\n"
-		"\n"
-		"Parameters:\n"
-		"-----------\n"
-		"\n"
-		"print_every_nth: \n"
-		"Print every n'th iteration \n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_runFit", _wrap_FitSuite_runFit, METH_VARARGS, (char *)"\n"
-		"FitSuite_runFit(FitSuite self)\n"
-		"\n"
-		"void FitSuite::runFit()\n"
-		"\n"
-		"main method to run the fitting \n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_numberOfFitObjects", _wrap_FitSuite_numberOfFitObjects, METH_VARARGS, (char *)"\n"
-		"FitSuite_numberOfFitObjects(FitSuite self) -> size_t\n"
-		"\n"
-		"size_t FitSuite::numberOfFitObjects() const\n"
-		"\n"
-		"Returns number of fit objects, where fit object stands for (real, simulated) pair. \n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_fitObjects", _wrap_FitSuite_fitObjects, METH_VARARGS, (char *)"\n"
-		"FitSuite_fitObjects(FitSuite self) -> FitSuiteObjects\n"
-		"\n"
-		"FitSuiteObjects * FitSuite::fitObjects()\n"
-		"\n"
-		"returns  FitObject (pair of simulation/real data) \n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_fitParameters", _wrap_FitSuite_fitParameters, METH_VARARGS, (char *)"\n"
-		"FitSuite_fitParameters(FitSuite self) -> FitParameterSet\n"
-		"\n"
-		"FitParameterSet * FitSuite::fitParameters()\n"
-		"\n"
-		"Returns reference to fit parameters. \n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_fitStrategies", _wrap_FitSuite_fitStrategies, METH_VARARGS, (char *)"\n"
-		"FitSuite_fitStrategies(FitSuite self) -> FitSuiteStrategies *\n"
-		"\n"
-		"FitSuiteStrategies * FitSuite::fitStrategies()\n"
-		"\n"
-		"Returns reference to fit parameters. \n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_isFirstIteration", _wrap_FitSuite_isFirstIteration, METH_VARARGS, (char *)"\n"
-		"FitSuite_isFirstIteration(FitSuite self) -> bool\n"
-		"\n"
-		"bool FitSuite::isFirstIteration() const\n"
-		"\n"
-		"temporary method to check if it is first iteration \n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_isLastIteration", _wrap_FitSuite_isLastIteration, METH_VARARGS, (char *)"\n"
-		"FitSuite_isLastIteration(FitSuite self) -> bool\n"
-		"\n"
-		"bool FitSuite::isLastIteration() const\n"
-		"\n"
-		"if the last iteration is done (used by observers to print summary) \n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_numberOfIterations", _wrap_FitSuite_numberOfIterations, METH_VARARGS, (char *)"\n"
-		"FitSuite_numberOfIterations(FitSuite self) -> size_t\n"
-		"\n"
-		"size_t FitSuite::numberOfIterations() const\n"
-		"\n"
-		"Returns current number of minimization function calls. \n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_currentStrategyIndex", _wrap_FitSuite_currentStrategyIndex, METH_VARARGS, (char *)"\n"
-		"FitSuite_currentStrategyIndex(FitSuite self) -> size_t\n"
-		"\n"
-		"size_t FitSuite::currentStrategyIndex() const\n"
-		"\n"
-		"Returns the number of current strategy. \n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_printResults", _wrap_FitSuite_printResults, METH_VARARGS, (char *)"\n"
-		"FitSuite_printResults(FitSuite self)\n"
-		"\n"
-		"void FitSuite::printResults() const\n"
-		"\n"
-		"Prints results of the minimization to the standard output. \n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_reportResults", _wrap_FitSuite_reportResults, METH_VARARGS, (char *)"\n"
-		"FitSuite_reportResults(FitSuite self) -> std::string\n"
-		"\n"
-		"std::string FitSuite::reportResults() const\n"
-		"\n"
-		"Reports results of minimization in the form of multi-line string. \n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_getChi2", _wrap_FitSuite_getChi2, METH_VARARGS, (char *)"\n"
-		"FitSuite_getChi2(FitSuite self) -> double\n"
-		"\n"
-		"double FitSuite::getChi2() const\n"
-		"\n"
-		"Returns minimum chi squared value found. \n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_interruptFitting", _wrap_FitSuite_interruptFitting, METH_VARARGS, (char *)"\n"
-		"FitSuite_interruptFitting(FitSuite self)\n"
-		"\n"
-		"void FitSuite::interruptFitting()\n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_resetInterrupt", _wrap_FitSuite_resetInterrupt, METH_VARARGS, (char *)"\n"
-		"FitSuite_resetInterrupt(FitSuite self)\n"
-		"\n"
-		"void FitSuite::resetInterrupt()\n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_isInterrupted", _wrap_FitSuite_isInterrupted, METH_VARARGS, (char *)"\n"
-		"FitSuite_isInterrupted(FitSuite self) -> bool\n"
-		"\n"
-		"bool FitSuite::isInterrupted()\n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_parametersToString", _wrap_FitSuite_parametersToString, METH_VARARGS, (char *)"\n"
-		"FitSuite_parametersToString(FitSuite self) -> std::string\n"
-		"\n"
-		"std::string FitSuite::parametersToString() const\n"
-		"\n"
-		"Returns multiline string representing possible fit parameters. \n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_treeToString", _wrap_FitSuite_treeToString, METH_VARARGS, (char *)"\n"
-		"FitSuite_treeToString(FitSuite self) -> std::string\n"
-		"\n"
-		"std::string FitSuite::treeToString() const\n"
-		"\n"
-		"Returns multiline string representing tree structure of fit components. \n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_setupToString", _wrap_FitSuite_setupToString, METH_VARARGS, (char *)"\n"
-		"FitSuite_setupToString(FitSuite self) -> std::string\n"
-		"\n"
-		"std::string FitSuite::setupToString()\n"
-		"\n"
-		"Returns multiline string representing fit setup. \n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_simulationResult", _wrap_FitSuite_simulationResult, METH_VARARGS, (char *)"\n"
-		"simulationResult(size_t i_item=0) -> SimulationResult\n"
-		"FitSuite_simulationResult(FitSuite self) -> SimulationResult\n"
-		"\n"
-		"SimulationResult FitSuite::simulationResult(size_t i_item=0) const\n"
-		"\n"
-		"Returns simulation result.\n"
-		"\n"
-		"Parameters:\n"
-		"-----------\n"
-		"\n"
-		"i_item: \n"
-		"the index of fit pair \n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_experimentalData", _wrap_FitSuite_experimentalData, METH_VARARGS, (char *)"\n"
-		"experimentalData(size_t i_item=0) -> SimulationResult\n"
-		"FitSuite_experimentalData(FitSuite self) -> SimulationResult\n"
-		"\n"
-		"SimulationResult FitSuite::experimentalData(size_t i_item=0) const\n"
-		"\n"
-		"Returns experimental data.\n"
-		"\n"
-		"Parameters:\n"
-		"-----------\n"
-		"\n"
-		"i_item: \n"
-		"the index of fit pair \n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_relativeDifference", _wrap_FitSuite_relativeDifference, METH_VARARGS, (char *)"\n"
-		"relativeDifference(size_t i_item=0) -> SimulationResult\n"
-		"FitSuite_relativeDifference(FitSuite self) -> SimulationResult\n"
-		"\n"
-		"SimulationResult FitSuite::relativeDifference(size_t i_item=0) const\n"
-		"\n"
-		"Returns relative difference between simulation and experimental data.\n"
-		"\n"
-		"Parameters:\n"
-		"-----------\n"
-		"\n"
-		"i_item: \n"
-		"the index of fit pair \n"
-		"\n"
-		""},
-	 { (char *)"FitSuite_swigregister", FitSuite_swigregister, METH_VARARGS, NULL},
-	 { (char *)"new_FitSuiteObjects", _wrap_new_FitSuiteObjects, METH_VARARGS, (char *)"\n"
-		"new_FitSuiteObjects() -> FitSuiteObjects\n"
-		"\n"
-		"FitSuiteObjects::FitSuiteObjects()\n"
-		"\n"
-		""},
-	 { (char *)"delete_FitSuiteObjects", _wrap_delete_FitSuiteObjects, METH_VARARGS, (char *)"\n"
-		"delete_FitSuiteObjects(FitSuiteObjects self)\n"
-		"\n"
-		"FitSuiteObjects::~FitSuiteObjects()\n"
-		"\n"
-		""},
-	 { (char *)"FitSuiteObjects_accept", _wrap_FitSuiteObjects_accept, METH_VARARGS, (char *)"\n"
-		"FitSuiteObjects_accept(FitSuiteObjects self, INodeVisitor visitor)\n"
-		"\n"
-		"void FitSuiteObjects::accept(INodeVisitor *visitor) const final\n"
-		"\n"
-		"Calls the  INodeVisitor's visit method. \n"
-		"\n"
-		""},
-	 { (char *)"FitSuiteObjects_add", _wrap_FitSuiteObjects_add, METH_VARARGS, (char *)"\n"
-		"add(Simulation simulation, IntensityData real_data, double weight=1.0) -> FitObject\n"
-		"FitSuiteObjects_add(FitSuiteObjects self, Simulation simulation, IntensityData real_data) -> FitObject\n"
-		"\n"
-		"FitObject * FitSuiteObjects::add(const Simulation &simulation, const OutputData< double > &real_data, double weight=1.0)\n"
-		"\n"
-		"Adds to kit pair of (simulation, real data) for consecutive simulation. \n"
-		"\n"
-		""},
-	 { (char *)"FitSuiteObjects_getSizeOfDataSet", _wrap_FitSuiteObjects_getSizeOfDataSet, METH_VARARGS, (char *)"\n"
-		"FitSuiteObjects_getSizeOfDataSet(FitSuiteObjects self) -> size_t\n"
-		"\n"
-		"size_t FitSuiteObjects::getSizeOfDataSet() const\n"
-		"\n"
-		"Returns total number of data points (number of all non-masked channels in all fit objects)\n"
-		"\n"
-		"Returns total number of data points. \n"
-		"\n"
-		""},
-	 { (char *)"FitSuiteObjects_setChiSquaredModule", _wrap_FitSuiteObjects_setChiSquaredModule, METH_VARARGS, (char *)"\n"
-		"FitSuiteObjects_setChiSquaredModule(FitSuiteObjects self, IChiSquaredModule chi2_module)\n"
-		"\n"
-		"void FitSuiteObjects::setChiSquaredModule(const IChiSquaredModule &chi2_module)\n"
-		"\n"
-		"Replaces default  ChiSquaredModule with new one. \n"
-		"\n"
-		""},
-	 { (char *)"FitSuiteObjects_simulationResult", _wrap_FitSuiteObjects_simulationResult, METH_VARARGS, (char *)"\n"
-		"simulationResult(size_t i_item=0) -> SimulationResult\n"
-		"FitSuiteObjects_simulationResult(FitSuiteObjects self) -> SimulationResult\n"
-		"\n"
-		"SimulationResult FitSuiteObjects::simulationResult(size_t i_item=0) const\n"
-		"\n"
-		"Returns simulation result.\n"
-		"\n"
-		"Parameters:\n"
-		"-----------\n"
-		"\n"
-		"i_item: \n"
-		"the index of fit pair \n"
-		"\n"
-		""},
-	 { (char *)"FitSuiteObjects_experimentalData", _wrap_FitSuiteObjects_experimentalData, METH_VARARGS, (char *)"\n"
-		"experimentalData(size_t i_item=0) -> SimulationResult\n"
-		"FitSuiteObjects_experimentalData(FitSuiteObjects self) -> SimulationResult\n"
-		"\n"
-		"SimulationResult FitSuiteObjects::experimentalData(size_t i_item=0) const\n"
-		"\n"
-		"Returns experimental data.\n"
-		"\n"
-		"Parameters:\n"
-		"-----------\n"
-		"\n"
-		"i_item: \n"
-		"the index of fit pair \n"
-		"\n"
-		""},
-	 { (char *)"FitSuiteObjects_relativeDifference", _wrap_FitSuiteObjects_relativeDifference, METH_VARARGS, (char *)"\n"
-		"relativeDifference(size_t i_item=0) -> SimulationResult\n"
-		"FitSuiteObjects_relativeDifference(FitSuiteObjects self) -> SimulationResult\n"
-		"\n"
-		"SimulationResult FitSuiteObjects::relativeDifference(size_t i_item=0) const\n"
-		"\n"
-		"Returns relative difference between simulation and experimental data.\n"
-		"\n"
-		"Parameters:\n"
-		"-----------\n"
-		"\n"
-		"i_item: \n"
-		"the index of fit pair \n"
-		"\n"
-		""},
-	 { (char *)"FitSuiteObjects_runSimulations", _wrap_FitSuiteObjects_runSimulations, METH_VARARGS, (char *)"\n"
-		"FitSuiteObjects_runSimulations(FitSuiteObjects self)\n"
-		"\n"
-		"void FitSuiteObjects::runSimulations()\n"
-		"\n"
-		"run all simulation defined in fit pairs\n"
-		"\n"
-		"loop through all defined simulations and run them \n"
-		"\n"
-		""},
-	 { (char *)"FitSuiteObjects_getChiSquaredValue", _wrap_FitSuiteObjects_getChiSquaredValue, METH_VARARGS, (char *)"\n"
-		"FitSuiteObjects_getChiSquaredValue(FitSuiteObjects self) -> double\n"
-		"\n"
-		"double FitSuiteObjects::getChiSquaredValue() const\n"
-		"\n"
-		"Returns chi2 calculated over whole dataset. \n"
-		"\n"
-		""},
-	 { (char *)"FitSuiteObjects_getResidualValue", _wrap_FitSuiteObjects_getResidualValue, METH_VARARGS, (char *)"\n"
-		"FitSuiteObjects_getResidualValue(FitSuiteObjects self, size_t global_index) -> double\n"
-		"\n"
-		"double FitSuiteObjects::getResidualValue(size_t global_index)\n"
-		"\n"
-		"Returns residuals for single data element\n"
-		"\n"
-		"Parameters:\n"
-		"-----------\n"
-		"\n"
-		"global_index: \n"
-		"index across all element in  FitElement vector \n"
-		"\n"
-		""},
-	 { (char *)"FitSuiteObjects_residuals", _wrap_FitSuiteObjects_residuals, METH_VARARGS, (char *)"\n"
-		"FitSuiteObjects_residuals(FitSuiteObjects self) -> vdouble1d_t\n"
-		"\n"
-		"std::vector< double > FitSuiteObjects::residuals() const\n"
-		"\n"
-		""},
-	 { (char *)"FitSuiteObjects_setNfreeParameters", _wrap_FitSuiteObjects_setNfreeParameters, METH_VARARGS, (char *)"\n"
-		"FitSuiteObjects_setNfreeParameters(FitSuiteObjects self, int nfree_parameters)\n"
-		"\n"
-		"void FitSuiteObjects::setNfreeParameters(int nfree_parameters)\n"
-		"\n"
-		""},
-	 { (char *)"FitSuiteObjects_clear", _wrap_FitSuiteObjects_clear, METH_VARARGS, (char *)"\n"
-		"FitSuiteObjects_clear(FitSuiteObjects self)\n"
-		"\n"
-		"void FitSuiteObjects::clear()\n"
-		"\n"
-		"clear all data \n"
-		"\n"
-		""},
-	 { (char *)"FitSuiteObjects_size", _wrap_FitSuiteObjects_size, METH_VARARGS, (char *)"\n"
-		"FitSuiteObjects_size(FitSuiteObjects self) -> size_t\n"
-		"\n"
-		"size_t FitSuiteObjects::size() const\n"
-		"\n"
-		""},
-	 { (char *)"FitSuiteObjects_begin", _wrap_FitSuiteObjects_begin, METH_VARARGS, (char *)"\n"
-		"FitSuiteObjects_begin(FitSuiteObjects self) -> FitSuiteObjects::iterator\n"
-		"\n"
-		"iterator FitSuiteObjects::begin()\n"
-		"\n"
-		""},
-	 { (char *)"FitSuiteObjects_end", _wrap_FitSuiteObjects_end, METH_VARARGS, (char *)"\n"
-		"FitSuiteObjects_end(FitSuiteObjects self) -> FitSuiteObjects::iterator\n"
-		"\n"
-		"iterator FitSuiteObjects::end()\n"
-		"\n"
-		""},
-	 { (char *)"FitSuiteObjects_getChildren", _wrap_FitSuiteObjects_getChildren, METH_VARARGS, (char *)"\n"
-		"FitSuiteObjects_getChildren(FitSuiteObjects self) -> swig_dummy_type_const_inode_vector\n"
-		"\n"
-		"std::vector< const INode * > FitSuiteObjects::getChildren() const\n"
-		"\n"
-		"Returns a vector of children (const). \n"
-		"\n"
-		""},
-	 { (char *)"FitSuiteObjects_swigregister", FitSuiteObjects_swigregister, METH_VARARGS, NULL},
 	 { (char *)"new_PyBuilderCallback", _wrap_new_PyBuilderCallback, METH_VARARGS, (char *)"\n"
 		"new_PyBuilderCallback(PyObject * arg2) -> PyBuilderCallback\n"
 		"\n"
@@ -128127,7 +120335,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"disown_PyObserverCallback", _wrap_disown_PyObserverCallback, METH_VARARGS, NULL},
 	 { (char *)"PyObserverCallback_swigregister", PyObserverCallback_swigregister, METH_VARARGS, NULL},
 	 { (char *)"new_FitObjective", _wrap_new_FitObjective, METH_VARARGS, (char *)"\n"
-		"new_FitObjective() -> FitObjective\n"
+		"new_FitObjective(PyObject * arg2) -> FitObjective\n"
 		"\n"
 		"FitObjective::FitObjective()\n"
 		"\n"
@@ -128181,6 +120389,14 @@ static PyMethodDef SwigMethods[] = {
 		"Returns one dimensional array representing simulated intensities data. Masked areas and the area outside of region of interest are not included. Data from different datasets merged together. \n"
 		"\n"
 		""},
+	 { (char *)"FitObjective_weights_array", _wrap_FitObjective_weights_array, METH_VARARGS, (char *)"\n"
+		"FitObjective_weights_array(FitObjective self) -> vdouble1d_t\n"
+		"\n"
+		"std::vector< double > FitObjective::weights_array() const\n"
+		"\n"
+		"Returns one dimensional array representing weights of bin intensity for residuals. \n"
+		"\n"
+		""},
 	 { (char *)"FitObjective_simulationResult", _wrap_FitObjective_simulationResult, METH_VARARGS, (char *)"\n"
 		"simulationResult(size_t i_item=0) -> SimulationResult\n"
 		"FitObjective_simulationResult(FitObjective self) -> SimulationResult\n"
@@ -128226,6 +120442,21 @@ static PyMethodDef SwigMethods[] = {
 		"the index of fit pair \n"
 		"\n"
 		""},
+	 { (char *)"FitObjective_absoluteDifference", _wrap_FitObjective_absoluteDifference, METH_VARARGS, (char *)"\n"
+		"absoluteDifference(size_t i_item=0) -> SimulationResult\n"
+		"FitObjective_absoluteDifference(FitObjective self) -> SimulationResult\n"
+		"\n"
+		"SimulationResult FitObjective::absoluteDifference(size_t i_item=0) const\n"
+		"\n"
+		"Returns absolute value of difference between simulation and experimental data.\n"
+		"\n"
+		"Parameters:\n"
+		"-----------\n"
+		"\n"
+		"i_item: \n"
+		"the index of fit pair \n"
+		"\n"
+		""},
 	 { (char *)"FitObjective_initPrint", _wrap_FitObjective_initPrint, METH_VARARGS, (char *)"\n"
 		"FitObjective_initPrint(FitObjective self, int every_nth)\n"
 		"\n"
@@ -128245,14 +120476,6 @@ static PyMethodDef SwigMethods[] = {
 		"\n"
 		"void FitObjective::initPlot(int every_nth, PyObserverCallback &callback)\n"
 		"\n"
-		"Initializes plotting during the fitting using Python callable.\n"
-		"\n"
-		"Parameters:\n"
-		"-----------\n"
-		"\n"
-		"every_nth: \n"
-		"Called on every n'th iteration. \n"
-		"\n"
 		""},
 	 { (char *)"FitObjective_isCompleted", _wrap_FitObjective_isCompleted, METH_VARARGS, (char *)"\n"
 		"FitObjective_isCompleted(FitObjective self) -> bool\n"
@@ -128286,6 +120509,37 @@ static PyMethodDef SwigMethods[] = {
 		"unsigned FitObjective::fitObjectCount() const\n"
 		"\n"
 		""},
+	 { (char *)"FitObjective_interruptFitting", _wrap_FitObjective_interruptFitting, METH_VARARGS, (char *)"\n"
+		"FitObjective_interruptFitting(FitObjective self)\n"
+		"\n"
+		"void FitObjective::interruptFitting()\n"
+		"\n"
+		""},
+	 { (char *)"FitObjective_isInterrupted", _wrap_FitObjective_isInterrupted, METH_VARARGS, (char *)"\n"
+		"FitObjective_isInterrupted(FitObjective self) -> bool\n"
+		"\n"
+		"bool FitObjective::isInterrupted() const\n"
+		"\n"
+		""},
+	 { (char *)"FitObjective_isFirstIteration", _wrap_FitObjective_isFirstIteration, METH_VARARGS, (char *)"\n"
+		"FitObjective_isFirstIteration(FitObjective self) -> bool\n"
+		"\n"
+		"bool FitObjective::isFirstIteration() const\n"
+		"\n"
+		""},
+	 { (char *)"FitObjective_run_simulations", _wrap_FitObjective_run_simulations, METH_VARARGS, (char *)"\n"
+		"FitObjective_run_simulations(FitObjective self, Parameters params)\n"
+		"\n"
+		"void FitObjective::run_simulations(const Fit::Parameters &params)\n"
+		"\n"
+		""},
+	 { (char *)"FitObjective_setChiSquaredModule", _wrap_FitObjective_setChiSquaredModule, METH_VARARGS, (char *)"\n"
+		"FitObjective_setChiSquaredModule(FitObjective self, IChiSquaredModule module)\n"
+		"\n"
+		"void FitObjective::setChiSquaredModule(const IChiSquaredModule &module)\n"
+		"\n"
+		""},
+	 { (char *)"disown_FitObjective", _wrap_disown_FitObjective, METH_VARARGS, NULL},
 	 { (char *)"FitObjective_swigregister", FitObjective_swigregister, METH_VARARGS, NULL},
 	 { (char *)"StandardNormal", _wrap_StandardNormal, METH_VARARGS, (char *)"\n"
 		"StandardNormal(double x) -> double\n"
@@ -128339,9 +120593,11 @@ static PyMethodDef SwigMethods[] = {
 		"\n"
 		""},
 	 { (char *)"Laue", _wrap_Laue, METH_VARARGS, (char *)"\n"
-		"Laue(complex_t const z, size_t N) -> complex_t\n"
+		"Laue(double const x, size_t N) -> double\n"
 		"\n"
-		"complex_t MathFunctions::Laue(const complex_t z, size_t N)\n"
+		"double MathFunctions::Laue(const double x, size_t N)\n"
+		"\n"
+		"Real Laue function:  $Laue(x,N)\\\\equiv\\\\sin(Nx)/sin(x)$. \n"
 		"\n"
 		""},
 	 { (char *)"erf", _wrap_erf, METH_VARARGS, (char *)"\n"
@@ -128420,37 +120676,6 @@ static PyMethodDef SwigMethods[] = {
 		"double MathFunctions::GeneratePoissonRandom(double average)\n"
 		"\n"
 		""},
-	 { (char *)"new_AdjustMinimizerStrategy", _wrap_new_AdjustMinimizerStrategy, METH_VARARGS, (char *)"\n"
-		"AdjustMinimizerStrategy()\n"
-		"AdjustMinimizerStrategy(std::string const & minimizerName, std::string const & algorithmName, std::string const & optionString)\n"
-		"AdjustMinimizerStrategy(std::string const & minimizerName, std::string const & algorithmName)\n"
-		"new_AdjustMinimizerStrategy(std::string const & minimizerName) -> AdjustMinimizerStrategy\n"
-		"\n"
-		"AdjustMinimizerStrategy::AdjustMinimizerStrategy(const std::string &minimizerName, const std::string &algorithmName=\"\", const std::string &optionString=\"\")\n"
-		"\n"
-		""},
-	 { (char *)"AdjustMinimizerStrategy_clone", _wrap_AdjustMinimizerStrategy_clone, METH_VARARGS, (char *)"\n"
-		"AdjustMinimizerStrategy_clone(AdjustMinimizerStrategy self) -> AdjustMinimizerStrategy\n"
-		"\n"
-		"AdjustMinimizerStrategy * AdjustMinimizerStrategy::clone() const\n"
-		"\n"
-		""},
-	 { (char *)"AdjustMinimizerStrategy_setMinimizer", _wrap_AdjustMinimizerStrategy_setMinimizer, METH_VARARGS, (char *)"\n"
-		"setMinimizer(std::string const & minimizerName, std::string const & algorithmName, std::string const & optionString)\n"
-		"setMinimizer(std::string const & minimizerName, std::string const & algorithmName)\n"
-		"AdjustMinimizerStrategy_setMinimizer(AdjustMinimizerStrategy self, std::string const & minimizerName)\n"
-		"\n"
-		"void AdjustMinimizerStrategy::setMinimizer(const std::string &minimizerName, const std::string &algorithmName=\"\", const std::string &optionString=\"\")\n"
-		"\n"
-		""},
-	 { (char *)"AdjustMinimizerStrategy_execute", _wrap_AdjustMinimizerStrategy_execute, METH_VARARGS, (char *)"\n"
-		"AdjustMinimizerStrategy_execute(AdjustMinimizerStrategy self)\n"
-		"\n"
-		"void AdjustMinimizerStrategy::execute()\n"
-		"\n"
-		""},
-	 { (char *)"delete_AdjustMinimizerStrategy", _wrap_delete_AdjustMinimizerStrategy, METH_VARARGS, (char *)"delete_AdjustMinimizerStrategy(AdjustMinimizerStrategy self)"},
-	 { (char *)"AdjustMinimizerStrategy_swigregister", AdjustMinimizerStrategy_swigregister, METH_VARARGS, NULL},
 	 { (char *)"new_IMultiLayerBuilder", _wrap_new_IMultiLayerBuilder, METH_VARARGS, (char *)"\n"
 		"new_IMultiLayerBuilder(PyObject * arg2) -> IMultiLayerBuilder\n"
 		"\n"
@@ -128547,8 +120772,6 @@ static PyMethodDef SwigMethods[] = {
 		"visit(DistributionLogNormal arg2)\n"
 		"visit(DistributionLorentz arg2)\n"
 		"visit(DistributionTrapezoid arg2)\n"
-		"visit(FitObject arg2)\n"
-		"visit(FitSuiteObjects arg2)\n"
 		"visit(FootprintFactorGaussian arg2)\n"
 		"visit(FootprintFactorSquare arg2)\n"
 		"visit(FormFactorAnisoPyramid arg2)\n"
@@ -128572,6 +120795,7 @@ static PyMethodDef SwigMethods[] = {
 		"visit(FormFactorGauss arg2)\n"
 		"visit(FormFactorHemiEllipsoid arg2)\n"
 		"visit(FormFactorIcosahedron arg2)\n"
+		"visit(FormFactorLongBox arg2)\n"
 		"visit(FormFactorLongBoxGauss arg2)\n"
 		"visit(FormFactorLongBoxLorentz arg2)\n"
 		"visit(FormFactorLorentz arg2)\n"
@@ -128622,12 +120846,13 @@ static PyMethodDef SwigMethods[] = {
 		"visit(IntensityScaleAndShiftNormalizer arg2)\n"
 		"visit(InterferenceFunction1DLattice arg2)\n"
 		"visit(InterferenceFunction2DLattice arg2)\n"
-		"visit(InterferenceFunction3DLattice arg2)\n"
+		"visit(InterferenceFunction2DParaCrystal arg2)\n"
 		"visit(InterferenceFunction2DSuperLattice arg2)\n"
+		"visit(InterferenceFunction3DLattice arg2)\n"
 		"visit(InterferenceFunctionFinite2DLattice arg2)\n"
-		"visit(InterferenceFunction2DParaCrystal arg2)\n"
-		"visit(InterferenceFunctionNone arg2)\n"
+		"visit(InterferenceFunctionFinite3DLattice arg2)\n"
 		"visit(InterferenceFunctionRadialParaCrystal arg2)\n"
+		"visit(InterferenceFunctionNone arg2)\n"
 		"visit(IParticle arg2)\n"
 		"visit(IPeakShape arg2)\n"
 		"visit(IRotation arg2)\n"
@@ -130727,10 +122952,7 @@ static PyMethodDef SwigMethods[] = {
 		"-----------\n"
 		"\n"
 		"V: \n"
-		"oriented vertex list\n"
-		"\n"
-		"_sym_S2: \n"
-		"true if face has a perpedicular two-fold symmetry axis \n"
+		"oriented vertex list \n"
 		"\n"
 		""},
 	 { (char *)"PolyhedralFace_area", _wrap_PolyhedralFace_area, METH_VARARGS, (char *)"\n"
@@ -131904,6 +124126,78 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { (char *)"delete_FormFactorIcosahedron", _wrap_delete_FormFactorIcosahedron, METH_VARARGS, (char *)"delete_FormFactorIcosahedron(FormFactorIcosahedron self)"},
 	 { (char *)"FormFactorIcosahedron_swigregister", FormFactorIcosahedron_swigregister, METH_VARARGS, NULL},
+	 { (char *)"new_FormFactorLongBox", _wrap_new_FormFactorLongBox, METH_VARARGS, (char *)"\n"
+		"new_FormFactorLongBox(double length, double width, double height) -> FormFactorLongBox\n"
+		"\n"
+		"FormFactorLongBox::FormFactorLongBox(double length, double width, double height)\n"
+		"\n"
+		"Box constructor.\n"
+		"\n"
+		"Parameters:\n"
+		"-----------\n"
+		"\n"
+		"length: \n"
+		"of  Box's base\n"
+		"\n"
+		"width: \n"
+		"of  Box's base\n"
+		"\n"
+		"height: \n"
+		"of  Box\n"
+		"\n"
+		""},
+	 { (char *)"FormFactorLongBox_clone", _wrap_FormFactorLongBox_clone, METH_VARARGS, (char *)"\n"
+		"FormFactorLongBox_clone(FormFactorLongBox self) -> FormFactorLongBox\n"
+		"\n"
+		"FormFactorLongBox* FormFactorLongBox::clone() const override final\n"
+		"\n"
+		"Returns a clone of this  ISample object. \n"
+		"\n"
+		""},
+	 { (char *)"FormFactorLongBox_accept", _wrap_FormFactorLongBox_accept, METH_VARARGS, (char *)"\n"
+		"FormFactorLongBox_accept(FormFactorLongBox self, INodeVisitor visitor)\n"
+		"\n"
+		"void FormFactorLongBox::accept(INodeVisitor *visitor) const override final\n"
+		"\n"
+		"Calls the  INodeVisitor's visit method. \n"
+		"\n"
+		""},
+	 { (char *)"FormFactorLongBox_getLength", _wrap_FormFactorLongBox_getLength, METH_VARARGS, (char *)"\n"
+		"FormFactorLongBox_getLength(FormFactorLongBox self) -> double\n"
+		"\n"
+		"double FormFactorLongBox::getLength() const\n"
+		"\n"
+		""},
+	 { (char *)"FormFactorLongBox_getHeight", _wrap_FormFactorLongBox_getHeight, METH_VARARGS, (char *)"\n"
+		"FormFactorLongBox_getHeight(FormFactorLongBox self) -> double\n"
+		"\n"
+		"double FormFactorLongBox::getHeight() const\n"
+		"\n"
+		""},
+	 { (char *)"FormFactorLongBox_getWidth", _wrap_FormFactorLongBox_getWidth, METH_VARARGS, (char *)"\n"
+		"FormFactorLongBox_getWidth(FormFactorLongBox self) -> double\n"
+		"\n"
+		"double FormFactorLongBox::getWidth() const\n"
+		"\n"
+		""},
+	 { (char *)"FormFactorLongBox_radialExtension", _wrap_FormFactorLongBox_radialExtension, METH_VARARGS, (char *)"\n"
+		"FormFactorLongBox_radialExtension(FormFactorLongBox self) -> double\n"
+		"\n"
+		"double FormFactorLongBox::radialExtension() const override final\n"
+		"\n"
+		"Returns the (approximate in some cases) radial size of the particle of this form factor's shape. This is used for SSCA calculations \n"
+		"\n"
+		""},
+	 { (char *)"FormFactorLongBox_evaluate_for_q", _wrap_FormFactorLongBox_evaluate_for_q, METH_VARARGS, (char *)"\n"
+		"FormFactorLongBox_evaluate_for_q(FormFactorLongBox self, cvector_t q) -> complex_t\n"
+		"\n"
+		"complex_t FormFactorLongBox::evaluate_for_q(cvector_t q) const override final\n"
+		"\n"
+		"Returns scattering amplitude for complex scattering wavevector q=k_i-k_f. This method is public only for convenience of plotting form factors in Python. \n"
+		"\n"
+		""},
+	 { (char *)"delete_FormFactorLongBox", _wrap_delete_FormFactorLongBox, METH_VARARGS, (char *)"delete_FormFactorLongBox(FormFactorLongBox self)"},
+	 { (char *)"FormFactorLongBox_swigregister", FormFactorLongBox_swigregister, METH_VARARGS, NULL},
 	 { (char *)"new_FormFactorLongBoxGauss", _wrap_new_FormFactorLongBoxGauss, METH_VARARGS, (char *)"\n"
 		"new_FormFactorLongBoxGauss(double length, double width, double height) -> FormFactorLongBoxGauss\n"
 		"\n"
@@ -135150,67 +127444,186 @@ static PyMethodDef SwigMethods[] = {
 		"\n"
 		""},
 	 { (char *)"IPeakShape_evaluate", _wrap_IPeakShape_evaluate, METH_VARARGS, (char *)"\n"
-		"IPeakShape_evaluate(IPeakShape self, kvector_t q) -> double\n"
+		"IPeakShape_evaluate(IPeakShape self, kvector_t q, kvector_t q_lattice_point) -> double\n"
 		"\n"
-		"virtual double IPeakShape::evaluate(const kvector_t q) const =0\n"
+		"virtual double IPeakShape::evaluate(const kvector_t q, const kvector_t q_lattice_point) const =0\n"
 		"\n"
-		"Evaluates the peak shape at displacement q from the center at 0. \n"
+		"Evaluates the peak shape at q from a reciprocal lattice point at q_lattice_point. \n"
 		"\n"
 		""},
-	 { (char *)"IPeakShape_thickness_z", _wrap_IPeakShape_thickness_z, METH_VARARGS, (char *)"\n"
-		"IPeakShape_thickness_z(IPeakShape self) -> double\n"
+	 { (char *)"IPeakShape_angularDisorder", _wrap_IPeakShape_angularDisorder, METH_VARARGS, (char *)"\n"
+		"IPeakShape_angularDisorder(IPeakShape self) -> bool\n"
 		"\n"
-		"virtual double IPeakShape::thickness_z() const =0\n"
+		"virtual bool IPeakShape::angularDisorder() const\n"
 		"\n"
-		"Returns the thickness in the z-direction. \n"
+		"Indicates if the peak shape encodes angular disorder, in which case all peaks in a spherical shell are needed \n"
 		"\n"
 		""},
 	 { (char *)"IPeakShape_swigregister", IPeakShape_swigregister, METH_VARARGS, NULL},
-	 { (char *)"new_GaussPeakShape", _wrap_new_GaussPeakShape, METH_VARARGS, (char *)"\n"
-		"new_GaussPeakShape(double domainsize) -> GaussPeakShape\n"
+	 { (char *)"new_IsotropicGaussPeakShape", _wrap_new_IsotropicGaussPeakShape, METH_VARARGS, (char *)"\n"
+		"new_IsotropicGaussPeakShape(double max_intensity, double domainsize) -> IsotropicGaussPeakShape\n"
+		"\n"
+		"IsotropicGaussPeakShape::IsotropicGaussPeakShape(double max_intensity, double domainsize)\n"
+		"\n"
+		""},
+	 { (char *)"delete_IsotropicGaussPeakShape", _wrap_delete_IsotropicGaussPeakShape, METH_VARARGS, (char *)"\n"
+		"delete_IsotropicGaussPeakShape(IsotropicGaussPeakShape self)\n"
+		"\n"
+		"IsotropicGaussPeakShape::~IsotropicGaussPeakShape() override\n"
+		"\n"
+		""},
+	 { (char *)"IsotropicGaussPeakShape_clone", _wrap_IsotropicGaussPeakShape_clone, METH_VARARGS, (char *)"\n"
+		"IsotropicGaussPeakShape_clone(IsotropicGaussPeakShape self) -> IsotropicGaussPeakShape\n"
+		"\n"
+		"IsotropicGaussPeakShape * IsotropicGaussPeakShape::clone() const override\n"
+		"\n"
+		"Returns a clone of this  ISample object. \n"
+		"\n"
+		""},
+	 { (char *)"IsotropicGaussPeakShape_accept", _wrap_IsotropicGaussPeakShape_accept, METH_VARARGS, (char *)"\n"
+		"IsotropicGaussPeakShape_accept(IsotropicGaussPeakShape self, INodeVisitor visitor)\n"
+		"\n"
+		"void IsotropicGaussPeakShape::accept(INodeVisitor *visitor) const override\n"
+		"\n"
+		"Calls the  INodeVisitor's visit method. \n"
+		"\n"
+		""},
+	 { (char *)"IsotropicGaussPeakShape_evaluate", _wrap_IsotropicGaussPeakShape_evaluate, METH_VARARGS, (char *)"\n"
+		"IsotropicGaussPeakShape_evaluate(IsotropicGaussPeakShape self, kvector_t q, kvector_t q_lattice_point) -> double\n"
+		"\n"
+		"double IsotropicGaussPeakShape::evaluate(const kvector_t q, const kvector_t q_lattice_point) const override\n"
+		"\n"
+		"Evaluates the peak shape at q from a reciprocal lattice point at q_lattice_point. \n"
+		"\n"
+		""},
+	 { (char *)"IsotropicGaussPeakShape_swigregister", IsotropicGaussPeakShape_swigregister, METH_VARARGS, NULL},
+	 { (char *)"new_IsotropicLorentzPeakShape", _wrap_new_IsotropicLorentzPeakShape, METH_VARARGS, (char *)"\n"
+		"new_IsotropicLorentzPeakShape(double max_intensity, double domainsize) -> IsotropicLorentzPeakShape\n"
+		"\n"
+		"IsotropicLorentzPeakShape::IsotropicLorentzPeakShape(double max_intensity, double domainsize)\n"
+		"\n"
+		""},
+	 { (char *)"delete_IsotropicLorentzPeakShape", _wrap_delete_IsotropicLorentzPeakShape, METH_VARARGS, (char *)"\n"
+		"delete_IsotropicLorentzPeakShape(IsotropicLorentzPeakShape self)\n"
+		"\n"
+		"IsotropicLorentzPeakShape::~IsotropicLorentzPeakShape() override\n"
+		"\n"
+		""},
+	 { (char *)"IsotropicLorentzPeakShape_clone", _wrap_IsotropicLorentzPeakShape_clone, METH_VARARGS, (char *)"\n"
+		"IsotropicLorentzPeakShape_clone(IsotropicLorentzPeakShape self) -> IsotropicLorentzPeakShape\n"
+		"\n"
+		"IsotropicLorentzPeakShape * IsotropicLorentzPeakShape::clone() const override\n"
+		"\n"
+		"Returns a clone of this  ISample object. \n"
+		"\n"
+		""},
+	 { (char *)"IsotropicLorentzPeakShape_accept", _wrap_IsotropicLorentzPeakShape_accept, METH_VARARGS, (char *)"\n"
+		"IsotropicLorentzPeakShape_accept(IsotropicLorentzPeakShape self, INodeVisitor visitor)\n"
+		"\n"
+		"void IsotropicLorentzPeakShape::accept(INodeVisitor *visitor) const override\n"
+		"\n"
+		"Calls the  INodeVisitor's visit method. \n"
+		"\n"
+		""},
+	 { (char *)"IsotropicLorentzPeakShape_evaluate", _wrap_IsotropicLorentzPeakShape_evaluate, METH_VARARGS, (char *)"\n"
+		"IsotropicLorentzPeakShape_evaluate(IsotropicLorentzPeakShape self, kvector_t q, kvector_t q_lattice_point) -> double\n"
+		"\n"
+		"double IsotropicLorentzPeakShape::evaluate(const kvector_t q, const kvector_t q_lattice_point) const override\n"
+		"\n"
+		"Evaluates the peak shape at q from a reciprocal lattice point at q_lattice_point. \n"
+		"\n"
+		""},
+	 { (char *)"IsotropicLorentzPeakShape_swigregister", IsotropicLorentzPeakShape_swigregister, METH_VARARGS, NULL},
+	 { (char *)"new_GaussFisherPeakShape", _wrap_new_GaussFisherPeakShape, METH_VARARGS, (char *)"\n"
+		"new_GaussFisherPeakShape(double max_intensity, double radial_size, double kappa) -> GaussFisherPeakShape\n"
+		"\n"
+		"GaussFisherPeakShape::GaussFisherPeakShape(double max_intensity, double radial_size, double kappa)\n"
+		"\n"
+		""},
+	 { (char *)"delete_GaussFisherPeakShape", _wrap_delete_GaussFisherPeakShape, METH_VARARGS, (char *)"\n"
+		"delete_GaussFisherPeakShape(GaussFisherPeakShape self)\n"
+		"\n"
+		"GaussFisherPeakShape::~GaussFisherPeakShape() override\n"
+		"\n"
+		""},
+	 { (char *)"GaussFisherPeakShape_clone", _wrap_GaussFisherPeakShape_clone, METH_VARARGS, (char *)"\n"
+		"GaussFisherPeakShape_clone(GaussFisherPeakShape self) -> GaussFisherPeakShape\n"
+		"\n"
+		"GaussFisherPeakShape * GaussFisherPeakShape::clone() const override\n"
+		"\n"
+		"Returns a clone of this  ISample object. \n"
+		"\n"
+		""},
+	 { (char *)"GaussFisherPeakShape_accept", _wrap_GaussFisherPeakShape_accept, METH_VARARGS, (char *)"\n"
+		"GaussFisherPeakShape_accept(GaussFisherPeakShape self, INodeVisitor visitor)\n"
+		"\n"
+		"void GaussFisherPeakShape::accept(INodeVisitor *visitor) const override\n"
+		"\n"
+		"Calls the  INodeVisitor's visit method. \n"
+		"\n"
+		""},
+	 { (char *)"GaussFisherPeakShape_evaluate", _wrap_GaussFisherPeakShape_evaluate, METH_VARARGS, (char *)"\n"
+		"GaussFisherPeakShape_evaluate(GaussFisherPeakShape self, kvector_t q, kvector_t q_lattice_point) -> double\n"
+		"\n"
+		"double GaussFisherPeakShape::evaluate(const kvector_t q, const kvector_t q_lattice_point) const override\n"
+		"\n"
+		"Evaluates the peak shape at q from a reciprocal lattice point at q_lattice_point. \n"
+		"\n"
+		""},
+	 { (char *)"GaussFisherPeakShape_angularDisorder", _wrap_GaussFisherPeakShape_angularDisorder, METH_VARARGS, (char *)"\n"
+		"GaussFisherPeakShape_angularDisorder(GaussFisherPeakShape self) -> bool\n"
+		"\n"
+		"bool GaussFisherPeakShape::angularDisorder() const override\n"
+		"\n"
+		"Indicates if the peak shape encodes angular disorder, in which case all peaks in a spherical shell are needed \n"
+		"\n"
+		""},
+	 { (char *)"GaussFisherPeakShape_swigregister", GaussFisherPeakShape_swigregister, METH_VARARGS, NULL},
+	 { (char *)"new_LorentzFisherPeakShape", _wrap_new_LorentzFisherPeakShape, METH_VARARGS, (char *)"\n"
+		"new_LorentzFisherPeakShape(double max_intensity, double radial_size, double kappa) -> LorentzFisherPeakShape\n"
 		"\n"
-		"GaussPeakShape::GaussPeakShape(double domainsize)\n"
+		"LorentzFisherPeakShape::LorentzFisherPeakShape(double max_intensity, double radial_size, double kappa)\n"
 		"\n"
 		""},
-	 { (char *)"delete_GaussPeakShape", _wrap_delete_GaussPeakShape, METH_VARARGS, (char *)"\n"
-		"delete_GaussPeakShape(GaussPeakShape self)\n"
+	 { (char *)"delete_LorentzFisherPeakShape", _wrap_delete_LorentzFisherPeakShape, METH_VARARGS, (char *)"\n"
+		"delete_LorentzFisherPeakShape(LorentzFisherPeakShape self)\n"
 		"\n"
-		"GaussPeakShape::~GaussPeakShape() override\n"
+		"LorentzFisherPeakShape::~LorentzFisherPeakShape() override\n"
 		"\n"
 		""},
-	 { (char *)"GaussPeakShape_clone", _wrap_GaussPeakShape_clone, METH_VARARGS, (char *)"\n"
-		"GaussPeakShape_clone(GaussPeakShape self) -> GaussPeakShape\n"
+	 { (char *)"LorentzFisherPeakShape_clone", _wrap_LorentzFisherPeakShape_clone, METH_VARARGS, (char *)"\n"
+		"LorentzFisherPeakShape_clone(LorentzFisherPeakShape self) -> LorentzFisherPeakShape\n"
 		"\n"
-		"GaussPeakShape * GaussPeakShape::clone() const override\n"
+		"LorentzFisherPeakShape * LorentzFisherPeakShape::clone() const override\n"
 		"\n"
 		"Returns a clone of this  ISample object. \n"
 		"\n"
 		""},
-	 { (char *)"GaussPeakShape_accept", _wrap_GaussPeakShape_accept, METH_VARARGS, (char *)"\n"
-		"GaussPeakShape_accept(GaussPeakShape self, INodeVisitor visitor)\n"
+	 { (char *)"LorentzFisherPeakShape_accept", _wrap_LorentzFisherPeakShape_accept, METH_VARARGS, (char *)"\n"
+		"LorentzFisherPeakShape_accept(LorentzFisherPeakShape self, INodeVisitor visitor)\n"
 		"\n"
-		"void GaussPeakShape::accept(INodeVisitor *visitor) const override\n"
+		"void LorentzFisherPeakShape::accept(INodeVisitor *visitor) const override\n"
 		"\n"
 		"Calls the  INodeVisitor's visit method. \n"
 		"\n"
 		""},
-	 { (char *)"GaussPeakShape_evaluate", _wrap_GaussPeakShape_evaluate, METH_VARARGS, (char *)"\n"
-		"GaussPeakShape_evaluate(GaussPeakShape self, kvector_t q) -> double\n"
+	 { (char *)"LorentzFisherPeakShape_evaluate", _wrap_LorentzFisherPeakShape_evaluate, METH_VARARGS, (char *)"\n"
+		"LorentzFisherPeakShape_evaluate(LorentzFisherPeakShape self, kvector_t q, kvector_t q_lattice_point) -> double\n"
 		"\n"
-		"double GaussPeakShape::evaluate(const kvector_t q) const override\n"
+		"double LorentzFisherPeakShape::evaluate(const kvector_t q, const kvector_t q_lattice_point) const override\n"
 		"\n"
-		"Evaluates the peak shape at displacement q from the center at 0. \n"
+		"Evaluates the peak shape at q from a reciprocal lattice point at q_lattice_point. \n"
 		"\n"
 		""},
-	 { (char *)"GaussPeakShape_thickness_z", _wrap_GaussPeakShape_thickness_z, METH_VARARGS, (char *)"\n"
-		"GaussPeakShape_thickness_z(GaussPeakShape self) -> double\n"
+	 { (char *)"LorentzFisherPeakShape_angularDisorder", _wrap_LorentzFisherPeakShape_angularDisorder, METH_VARARGS, (char *)"\n"
+		"LorentzFisherPeakShape_angularDisorder(LorentzFisherPeakShape self) -> bool\n"
 		"\n"
-		"double GaussPeakShape::thickness_z() const override\n"
+		"bool LorentzFisherPeakShape::angularDisorder() const override\n"
 		"\n"
-		"Returns the thickness in the z-direction. \n"
+		"Indicates if the peak shape encodes angular disorder, in which case all peaks in a spherical shell are needed \n"
 		"\n"
 		""},
-	 { (char *)"GaussPeakShape_swigregister", GaussPeakShape_swigregister, METH_VARARGS, NULL},
+	 { (char *)"LorentzFisherPeakShape_swigregister", LorentzFisherPeakShape_swigregister, METH_VARARGS, NULL},
 	 { (char *)"delete_IResolutionFunction2D", _wrap_delete_IResolutionFunction2D, METH_VARARGS, (char *)"\n"
 		"delete_IResolutionFunction2D(IResolutionFunction2D self)\n"
 		"\n"
@@ -135850,7 +128263,9 @@ static PyMethodDef SwigMethods[] = {
 		"\n"
 		"\n"
 		"\n"
-		"Provides users with possibility to read and write IntensityData from/to files in different format. Type of the file will be deduced from file name. *.txt - ASCII file with 2D array [nrow][ncol], layout as in numpy. *.int -  BornAgain internal ASCII format. *.tif - 32-bits tiff file. If file name ends woth \"*.gz\" or \"*.bz2\" the file will be zipped on the fly using appropriate algorithm. Usage:\n"
+		"Provides users with possibility to read and write IntensityData from/to files in different format. Type of the file will be deduced from file name. *.txt - ASCII file with 2D array [nrow][ncol], layout as in numpy. *.int -  BornAgain internal ASCII format. *.tif - 32-bits tiff file. If file name ends woth \"*.gz\" or \"*.bz2\" the file will be zipped on the fly using appropriate algorithm.\n"
+		"\n"
+		"Usage:\n"
 		"\n"
 		"C++ includes: IntensityDataIOFactory.h\n"
 		"\n"
@@ -135933,130 +128348,6 @@ static PyMethodDef SwigMethods[] = {
 		"\n"
 		""},
 	 { (char *)"InterferenceFunction1DLattice_swigregister", InterferenceFunction1DLattice_swigregister, METH_VARARGS, NULL},
-	 { (char *)"new_InterferenceFunctionRadialParaCrystal", _wrap_new_InterferenceFunctionRadialParaCrystal, METH_VARARGS, (char *)"\n"
-		"InterferenceFunctionRadialParaCrystal(double peak_distance, double damping_length=0.0)\n"
-		"new_InterferenceFunctionRadialParaCrystal(double peak_distance) -> InterferenceFunctionRadialParaCrystal\n"
-		"\n"
-		"InterferenceFunctionRadialParaCrystal::InterferenceFunctionRadialParaCrystal(double peak_distance, double damping_length=0.0)\n"
-		"\n"
-		"Constructor of interference function of radial paracrystal.\n"
-		"\n"
-		"Parameters:\n"
-		"-----------\n"
-		"\n"
-		"peak_distance: \n"
-		"average distance to the next neighbor in nanometers\n"
-		"\n"
-		"damping_length: \n"
-		"the damping (coherence) length of the paracrystal in nanometers \n"
-		"\n"
-		""},
-	 { (char *)"InterferenceFunctionRadialParaCrystal_clone", _wrap_InterferenceFunctionRadialParaCrystal_clone, METH_VARARGS, (char *)"\n"
-		"InterferenceFunctionRadialParaCrystal_clone(InterferenceFunctionRadialParaCrystal self) -> InterferenceFunctionRadialParaCrystal\n"
-		"\n"
-		"InterferenceFunctionRadialParaCrystal * InterferenceFunctionRadialParaCrystal::clone() const final\n"
-		"\n"
-		"Returns a clone of this  ISample object. \n"
-		"\n"
-		""},
-	 { (char *)"InterferenceFunctionRadialParaCrystal_accept", _wrap_InterferenceFunctionRadialParaCrystal_accept, METH_VARARGS, (char *)"\n"
-		"InterferenceFunctionRadialParaCrystal_accept(InterferenceFunctionRadialParaCrystal self, INodeVisitor visitor)\n"
-		"\n"
-		"void InterferenceFunctionRadialParaCrystal::accept(INodeVisitor *visitor) const final\n"
-		"\n"
-		"Calls the  INodeVisitor's visit method. \n"
-		"\n"
-		""},
-	 { (char *)"InterferenceFunctionRadialParaCrystal_setKappa", _wrap_InterferenceFunctionRadialParaCrystal_setKappa, METH_VARARGS, (char *)"\n"
-		"InterferenceFunctionRadialParaCrystal_setKappa(InterferenceFunctionRadialParaCrystal self, double kappa)\n"
-		"\n"
-		"void InterferenceFunctionRadialParaCrystal::setKappa(double kappa)\n"
-		"\n"
-		"Sets size spacing coupling parameter of the Size Spacing Correlation Approximation.\n"
-		"\n"
-		"Parameters:\n"
-		"-----------\n"
-		"\n"
-		"size: \n"
-		"spacing coupling parameter \n"
-		"\n"
-		""},
-	 { (char *)"InterferenceFunctionRadialParaCrystal_kappa", _wrap_InterferenceFunctionRadialParaCrystal_kappa, METH_VARARGS, (char *)"\n"
-		"InterferenceFunctionRadialParaCrystal_kappa(InterferenceFunctionRadialParaCrystal self) -> double\n"
-		"\n"
-		"double InterferenceFunctionRadialParaCrystal::kappa() const\n"
-		"\n"
-		""},
-	 { (char *)"InterferenceFunctionRadialParaCrystal_setDomainSize", _wrap_InterferenceFunctionRadialParaCrystal_setDomainSize, METH_VARARGS, (char *)"\n"
-		"InterferenceFunctionRadialParaCrystal_setDomainSize(InterferenceFunctionRadialParaCrystal self, double size)\n"
-		"\n"
-		"void InterferenceFunctionRadialParaCrystal::setDomainSize(double size)\n"
-		"\n"
-		"Sets domain size (finite size corrections).\n"
-		"\n"
-		"Parameters:\n"
-		"-----------\n"
-		"\n"
-		"size: \n"
-		"size of coherence domain along the lattice main axis in nanometers \n"
-		"\n"
-		""},
-	 { (char *)"InterferenceFunctionRadialParaCrystal_domainSize", _wrap_InterferenceFunctionRadialParaCrystal_domainSize, METH_VARARGS, (char *)"\n"
-		"InterferenceFunctionRadialParaCrystal_domainSize(InterferenceFunctionRadialParaCrystal self) -> double\n"
-		"\n"
-		"double InterferenceFunctionRadialParaCrystal::domainSize() const\n"
-		"\n"
-		""},
-	 { (char *)"InterferenceFunctionRadialParaCrystal_evaluate", _wrap_InterferenceFunctionRadialParaCrystal_evaluate, METH_VARARGS, (char *)"\n"
-		"InterferenceFunctionRadialParaCrystal_evaluate(InterferenceFunctionRadialParaCrystal self, kvector_t q) -> double\n"
-		"\n"
-		"double InterferenceFunctionRadialParaCrystal::evaluate(const kvector_t q) const final\n"
-		"\n"
-		"Evaluates the interference function for a given wavevector transfer (only the real x and y components are relevant) \n"
-		"\n"
-		""},
-	 { (char *)"InterferenceFunctionRadialParaCrystal_FTPDF", _wrap_InterferenceFunctionRadialParaCrystal_FTPDF, METH_VARARGS, (char *)"\n"
-		"InterferenceFunctionRadialParaCrystal_FTPDF(InterferenceFunctionRadialParaCrystal self, double qpar) -> complex_t\n"
-		"\n"
-		"complex_t InterferenceFunctionRadialParaCrystal::FTPDF(double qpar) const\n"
-		"\n"
-		""},
-	 { (char *)"InterferenceFunctionRadialParaCrystal_setProbabilityDistribution", _wrap_InterferenceFunctionRadialParaCrystal_setProbabilityDistribution, METH_VARARGS, (char *)"\n"
-		"InterferenceFunctionRadialParaCrystal_setProbabilityDistribution(InterferenceFunctionRadialParaCrystal self, IFTDistribution1D pdf)\n"
-		"\n"
-		"void InterferenceFunctionRadialParaCrystal::setProbabilityDistribution(const IFTDistribution1D &pdf)\n"
-		"\n"
-		"Sets one-dimensional probability distribution.\n"
-		"\n"
-		"Parameters:\n"
-		"-----------\n"
-		"\n"
-		"pdf: \n"
-		"probability distribution (Fourier transform of probability density) \n"
-		"\n"
-		""},
-	 { (char *)"InterferenceFunctionRadialParaCrystal_peakDistance", _wrap_InterferenceFunctionRadialParaCrystal_peakDistance, METH_VARARGS, (char *)"\n"
-		"InterferenceFunctionRadialParaCrystal_peakDistance(InterferenceFunctionRadialParaCrystal self) -> double\n"
-		"\n"
-		"double InterferenceFunctionRadialParaCrystal::peakDistance() const\n"
-		"\n"
-		""},
-	 { (char *)"InterferenceFunctionRadialParaCrystal_dampingLength", _wrap_InterferenceFunctionRadialParaCrystal_dampingLength, METH_VARARGS, (char *)"\n"
-		"InterferenceFunctionRadialParaCrystal_dampingLength(InterferenceFunctionRadialParaCrystal self) -> double\n"
-		"\n"
-		"double InterferenceFunctionRadialParaCrystal::dampingLength() const\n"
-		"\n"
-		""},
-	 { (char *)"InterferenceFunctionRadialParaCrystal_getChildren", _wrap_InterferenceFunctionRadialParaCrystal_getChildren, METH_VARARGS, (char *)"\n"
-		"InterferenceFunctionRadialParaCrystal_getChildren(InterferenceFunctionRadialParaCrystal self) -> swig_dummy_type_const_inode_vector\n"
-		"\n"
-		"std::vector< const INode * > InterferenceFunctionRadialParaCrystal::getChildren() const override\n"
-		"\n"
-		"Returns a vector of children (const). \n"
-		"\n"
-		""},
-	 { (char *)"delete_InterferenceFunctionRadialParaCrystal", _wrap_delete_InterferenceFunctionRadialParaCrystal, METH_VARARGS, (char *)"delete_InterferenceFunctionRadialParaCrystal(InterferenceFunctionRadialParaCrystal self)"},
-	 { (char *)"InterferenceFunctionRadialParaCrystal_swigregister", InterferenceFunctionRadialParaCrystal_swigregister, METH_VARARGS, NULL},
 	 { (char *)"new_InterferenceFunction2DLattice", _wrap_new_InterferenceFunction2DLattice, METH_VARARGS, (char *)"\n"
 		"InterferenceFunction2DLattice(Lattice2D lattice)\n"
 		"InterferenceFunction2DLattice(double length_1, double length_2, double alpha, double xi=0.0)\n"
@@ -136177,208 +128468,195 @@ static PyMethodDef SwigMethods[] = {
 		"\n"
 		""},
 	 { (char *)"InterferenceFunction2DLattice_swigregister", InterferenceFunction2DLattice_swigregister, METH_VARARGS, NULL},
-	 { (char *)"new_InterferenceFunction3DLattice", _wrap_new_InterferenceFunction3DLattice, METH_VARARGS, (char *)"\n"
-		"new_InterferenceFunction3DLattice(Lattice lattice) -> InterferenceFunction3DLattice\n"
-		"\n"
-		"InterferenceFunction3DLattice::InterferenceFunction3DLattice(const Lattice &lattice)\n"
+	 { (char *)"new_InterferenceFunction2DParaCrystal", _wrap_new_InterferenceFunction2DParaCrystal, METH_VARARGS, (char *)"\n"
+		"InterferenceFunction2DParaCrystal(Lattice2D lattice, double damping_length=0.0, double domain_size_1=0.0, double domain_size_2=0.0)\n"
+		"InterferenceFunction2DParaCrystal(Lattice2D lattice, double damping_length=0.0, double domain_size_1=0.0)\n"
+		"InterferenceFunction2DParaCrystal(Lattice2D lattice, double damping_length=0.0)\n"
+		"InterferenceFunction2DParaCrystal(Lattice2D lattice)\n"
+		"InterferenceFunction2DParaCrystal(double length_1, double length_2, double alpha, double xi=0.0, double damping_length=0.0)\n"
+		"InterferenceFunction2DParaCrystal(double length_1, double length_2, double alpha, double xi=0.0)\n"
+		"new_InterferenceFunction2DParaCrystal(double length_1, double length_2, double alpha) -> InterferenceFunction2DParaCrystal\n"
 		"\n"
-		""},
-	 { (char *)"delete_InterferenceFunction3DLattice", _wrap_delete_InterferenceFunction3DLattice, METH_VARARGS, (char *)"\n"
-		"delete_InterferenceFunction3DLattice(InterferenceFunction3DLattice self)\n"
+		"InterferenceFunction2DParaCrystal::InterferenceFunction2DParaCrystal(double length_1, double length_2, double alpha, double xi=0.0, double damping_length=0.0)\n"
 		"\n"
-		"InterferenceFunction3DLattice::~InterferenceFunction3DLattice() final\n"
+		"Constructor of interference function of two-dimensional paracrystal.\n"
 		"\n"
-		""},
-	 { (char *)"InterferenceFunction3DLattice_clone", _wrap_InterferenceFunction3DLattice_clone, METH_VARARGS, (char *)"\n"
-		"InterferenceFunction3DLattice_clone(InterferenceFunction3DLattice self) -> InterferenceFunction3DLattice\n"
+		"Parameters:\n"
+		"-----------\n"
 		"\n"
-		"InterferenceFunction3DLattice * InterferenceFunction3DLattice::clone() const final\n"
+		"length_1: \n"
+		"length of first lattice vector in nanometers\n"
 		"\n"
-		"Returns a clone of this  ISample object. \n"
+		"length_2: \n"
+		"length of second lattice vector in nanometers\n"
 		"\n"
-		""},
-	 { (char *)"InterferenceFunction3DLattice_accept", _wrap_InterferenceFunction3DLattice_accept, METH_VARARGS, (char *)"\n"
-		"InterferenceFunction3DLattice_accept(InterferenceFunction3DLattice self, INodeVisitor visitor)\n"
+		"alpha: \n"
+		"angle between lattice vectors in radians\n"
 		"\n"
-		"void InterferenceFunction3DLattice::accept(INodeVisitor *visitor) const final\n"
+		"xi: \n"
+		"rotation of lattice with respect to x-axis (beam direction) in radians\n"
 		"\n"
-		"Calls the  INodeVisitor's visit method. \n"
+		"damping_length: \n"
+		"the damping (coherence) length of the paracrystal in nanometers \n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunction3DLattice_setPeakShape", _wrap_InterferenceFunction3DLattice_setPeakShape, METH_VARARGS, (char *)"\n"
-		"InterferenceFunction3DLattice_setPeakShape(InterferenceFunction3DLattice self, IPeakShape peak_shape)\n"
+	 { (char *)"delete_InterferenceFunction2DParaCrystal", _wrap_delete_InterferenceFunction2DParaCrystal, METH_VARARGS, (char *)"\n"
+		"delete_InterferenceFunction2DParaCrystal(InterferenceFunction2DParaCrystal self)\n"
 		"\n"
-		"void InterferenceFunction3DLattice::setPeakShape(const IPeakShape &peak_shape)\n"
+		"InterferenceFunction2DParaCrystal::~InterferenceFunction2DParaCrystal() final\n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunction3DLattice_setDebyeWallerFactor", _wrap_InterferenceFunction3DLattice_setDebyeWallerFactor, METH_VARARGS, (char *)"\n"
-		"InterferenceFunction3DLattice_setDebyeWallerFactor(InterferenceFunction3DLattice self, double dw_length)\n"
+	 { (char *)"InterferenceFunction2DParaCrystal_clone", _wrap_InterferenceFunction2DParaCrystal_clone, METH_VARARGS, (char *)"\n"
+		"InterferenceFunction2DParaCrystal_clone(InterferenceFunction2DParaCrystal self) -> InterferenceFunction2DParaCrystal\n"
 		"\n"
-		"void InterferenceFunction3DLattice::setDebyeWallerFactor(double dw_length)\n"
+		"InterferenceFunction2DParaCrystal * InterferenceFunction2DParaCrystal::clone() const final\n"
+		"\n"
+		"Returns a clone of this  ISample object. \n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunction3DLattice_evaluate", _wrap_InterferenceFunction3DLattice_evaluate, METH_VARARGS, (char *)"\n"
-		"InterferenceFunction3DLattice_evaluate(InterferenceFunction3DLattice self, kvector_t q) -> double\n"
+	 { (char *)"InterferenceFunction2DParaCrystal_accept", _wrap_InterferenceFunction2DParaCrystal_accept, METH_VARARGS, (char *)"\n"
+		"InterferenceFunction2DParaCrystal_accept(InterferenceFunction2DParaCrystal self, INodeVisitor visitor)\n"
 		"\n"
-		"double InterferenceFunction3DLattice::evaluate(const kvector_t q) const final\n"
+		"void InterferenceFunction2DParaCrystal::accept(INodeVisitor *visitor) const final\n"
 		"\n"
-		"Evaluates the interference function for a given wavevector transfer (only the real x and y components are relevant) \n"
+		"Calls the  INodeVisitor's visit method. \n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunction3DLattice_lattice", _wrap_InterferenceFunction3DLattice_lattice, METH_VARARGS, (char *)"\n"
-		"InterferenceFunction3DLattice_lattice(InterferenceFunction3DLattice self) -> Lattice\n"
-		"\n"
-		"const Lattice & InterferenceFunction3DLattice::lattice() const\n"
-		"\n"
+	 { (char *)"InterferenceFunction2DParaCrystal_createSquare", _wrap_InterferenceFunction2DParaCrystal_createSquare, METH_VARARGS, (char *)"\n"
+		"createSquare(double lattice_length, double damping_length=0.0, double domain_size_1=0.0, double domain_size_2=0.0) -> InterferenceFunction2DParaCrystal\n"
+		"createSquare(double lattice_length, double damping_length=0.0, double domain_size_1=0.0) -> InterferenceFunction2DParaCrystal\n"
+		"createSquare(double lattice_length, double damping_length=0.0) -> InterferenceFunction2DParaCrystal\n"
+		"InterferenceFunction2DParaCrystal_createSquare(double lattice_length) -> InterferenceFunction2DParaCrystal\n"
+		""},
+	 { (char *)"InterferenceFunction2DParaCrystal_createHexagonal", _wrap_InterferenceFunction2DParaCrystal_createHexagonal, METH_VARARGS, (char *)"\n"
+		"createHexagonal(double lattice_length, double damping_length=0.0, double domain_size_1=0.0, double domain_size_2=0.0) -> InterferenceFunction2DParaCrystal\n"
+		"createHexagonal(double lattice_length, double damping_length=0.0, double domain_size_1=0.0) -> InterferenceFunction2DParaCrystal\n"
+		"createHexagonal(double lattice_length, double damping_length=0.0) -> InterferenceFunction2DParaCrystal\n"
+		"InterferenceFunction2DParaCrystal_createHexagonal(double lattice_length) -> InterferenceFunction2DParaCrystal\n"
 		""},
-	 { (char *)"InterferenceFunction3DLattice_getParticleDensity", _wrap_InterferenceFunction3DLattice_getParticleDensity, METH_VARARGS, (char *)"\n"
-		"InterferenceFunction3DLattice_getParticleDensity(InterferenceFunction3DLattice self) -> double\n"
+	 { (char *)"InterferenceFunction2DParaCrystal_setDomainSizes", _wrap_InterferenceFunction2DParaCrystal_setDomainSizes, METH_VARARGS, (char *)"\n"
+		"InterferenceFunction2DParaCrystal_setDomainSizes(InterferenceFunction2DParaCrystal self, double size_1, double size_2)\n"
 		"\n"
-		"double InterferenceFunction3DLattice::getParticleDensity() const final\n"
+		"void InterferenceFunction2DParaCrystal::setDomainSizes(double size_1, double size_2)\n"
 		"\n"
-		"If defined by this interference function's parameters, returns the particle density (per area). Otherwise, returns zero or a user-defined value \n"
+		"Sets the sizes of coherence domains.\n"
 		"\n"
-		""},
-	 { (char *)"InterferenceFunction3DLattice_supportsMultilayer", _wrap_InterferenceFunction3DLattice_supportsMultilayer, METH_VARARGS, (char *)"\n"
-		"InterferenceFunction3DLattice_supportsMultilayer(InterferenceFunction3DLattice self) -> bool\n"
+		"Parameters:\n"
+		"-----------\n"
 		"\n"
-		"bool InterferenceFunction3DLattice::supportsMultilayer() const override\n"
+		"size_1: \n"
+		"coherence domain size along the first basis vector in nanometers\n"
 		"\n"
-		"Indicates if this interference function can be used with a multilayer (DWBA mode) \n"
+		"size_2: \n"
+		"coherence domain size along the second basis vector in nanometers \n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunction3DLattice_getChildren", _wrap_InterferenceFunction3DLattice_getChildren, METH_VARARGS, (char *)"\n"
-		"InterferenceFunction3DLattice_getChildren(InterferenceFunction3DLattice self) -> swig_dummy_type_const_inode_vector\n"
+	 { (char *)"InterferenceFunction2DParaCrystal_setProbabilityDistributions", _wrap_InterferenceFunction2DParaCrystal_setProbabilityDistributions, METH_VARARGS, (char *)"\n"
+		"InterferenceFunction2DParaCrystal_setProbabilityDistributions(InterferenceFunction2DParaCrystal self, IFTDistribution2D pdf_1, IFTDistribution2D pdf_2)\n"
 		"\n"
-		"std::vector< const INode * > InterferenceFunction3DLattice::getChildren() const override\n"
+		"void InterferenceFunction2DParaCrystal::setProbabilityDistributions(const IFTDistribution2D &pdf_1, const IFTDistribution2D &pdf_2)\n"
 		"\n"
-		"Returns a vector of children (const). \n"
+		"Sets the probability distributions (Fourier transformed) for the two lattice directions.\n"
 		"\n"
-		""},
-	 { (char *)"InterferenceFunction3DLattice_onChange", _wrap_InterferenceFunction3DLattice_onChange, METH_VARARGS, (char *)"\n"
-		"InterferenceFunction3DLattice_onChange(InterferenceFunction3DLattice self)\n"
+		"Parameters:\n"
+		"-----------\n"
 		"\n"
-		"void InterferenceFunction3DLattice::onChange() override final\n"
+		"pdf_1: \n"
+		"probability distribution in first lattice direction\n"
 		"\n"
-		"Action to be taken in inherited class when a parameter has changed. \n"
+		"pdf_2: \n"
+		"probability distribution in second lattice direction \n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunction3DLattice_swigregister", InterferenceFunction3DLattice_swigregister, METH_VARARGS, NULL},
-	 { (char *)"new_InterferenceFunctionFinite2DLattice", _wrap_new_InterferenceFunctionFinite2DLattice, METH_VARARGS, (char *)"\n"
-		"InterferenceFunctionFinite2DLattice(Lattice2D lattice, unsigned int size_1, unsigned int size_2)\n"
-		"new_InterferenceFunctionFinite2DLattice(double length_1, double length_2, double alpha, double xi, unsigned int size_1, unsigned int size_2) -> InterferenceFunctionFinite2DLattice\n"
+	 { (char *)"InterferenceFunction2DParaCrystal_setDampingLength", _wrap_InterferenceFunction2DParaCrystal_setDampingLength, METH_VARARGS, (char *)"\n"
+		"InterferenceFunction2DParaCrystal_setDampingLength(InterferenceFunction2DParaCrystal self, double damping_length)\n"
 		"\n"
-		"InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice(double length_1, double length_2, double alpha, double xi, unsigned size_1, unsigned size_2)\n"
+		"void InterferenceFunction2DParaCrystal::setDampingLength(double damping_length)\n"
 		"\n"
-		"Constructor of two-dimensional interference function.\n"
+		"Sets the damping length.\n"
 		"\n"
 		"Parameters:\n"
 		"-----------\n"
 		"\n"
-		"length_1: \n"
-		"length of first lattice vector in nanometers\n"
-		"\n"
-		"length_2: \n"
-		"length of second lattice vector in nanometers\n"
-		"\n"
-		"alpha: \n"
-		"angle between lattice vectors in radians\n"
-		"\n"
-		"xi: \n"
-		"rotation of lattice with respect to x-axis (beam direction) in radians \n"
-		"\n"
-		""},
-	 { (char *)"delete_InterferenceFunctionFinite2DLattice", _wrap_delete_InterferenceFunctionFinite2DLattice, METH_VARARGS, (char *)"\n"
-		"delete_InterferenceFunctionFinite2DLattice(InterferenceFunctionFinite2DLattice self)\n"
-		"\n"
-		"InterferenceFunctionFinite2DLattice::~InterferenceFunctionFinite2DLattice() final\n"
+		"damping_length: \n"
+		"the damping (coherence) length of the paracrystal in nanometers \n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunctionFinite2DLattice_clone", _wrap_InterferenceFunctionFinite2DLattice_clone, METH_VARARGS, (char *)"\n"
-		"InterferenceFunctionFinite2DLattice_clone(InterferenceFunctionFinite2DLattice self) -> InterferenceFunctionFinite2DLattice\n"
+	 { (char *)"InterferenceFunction2DParaCrystal_evaluate", _wrap_InterferenceFunction2DParaCrystal_evaluate, METH_VARARGS, (char *)"\n"
+		"InterferenceFunction2DParaCrystal_evaluate(InterferenceFunction2DParaCrystal self, kvector_t q) -> double\n"
 		"\n"
-		"InterferenceFunctionFinite2DLattice * InterferenceFunctionFinite2DLattice::clone() const final\n"
+		"double InterferenceFunction2DParaCrystal::evaluate(const kvector_t q) const final\n"
 		"\n"
-		"Returns a clone of this  ISample object. \n"
+		"Evaluates the interference function for a given wavevector transfer (only the real x and y components are relevant) \n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunctionFinite2DLattice_accept", _wrap_InterferenceFunctionFinite2DLattice_accept, METH_VARARGS, (char *)"\n"
-		"InterferenceFunctionFinite2DLattice_accept(InterferenceFunctionFinite2DLattice self, INodeVisitor visitor)\n"
-		"\n"
-		"void InterferenceFunctionFinite2DLattice::accept(INodeVisitor *visitor) const final\n"
+	 { (char *)"InterferenceFunction2DParaCrystal_domainSizes", _wrap_InterferenceFunction2DParaCrystal_domainSizes, METH_VARARGS, (char *)"\n"
+		"InterferenceFunction2DParaCrystal_domainSizes(InterferenceFunction2DParaCrystal self) -> vdouble1d_t\n"
 		"\n"
-		"Calls the  INodeVisitor's visit method. \n"
+		"std::vector< double > InterferenceFunction2DParaCrystal::domainSizes() const\n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunctionFinite2DLattice_createSquare", _wrap_InterferenceFunctionFinite2DLattice_createSquare, METH_VARARGS, (char *)"InterferenceFunctionFinite2DLattice_createSquare(double lattice_length, double xi, unsigned int size_1, unsigned int size_2) -> InterferenceFunctionFinite2DLattice"},
-	 { (char *)"InterferenceFunctionFinite2DLattice_createHexagonal", _wrap_InterferenceFunctionFinite2DLattice_createHexagonal, METH_VARARGS, (char *)"InterferenceFunctionFinite2DLattice_createHexagonal(double lattice_length, double xi, unsigned int size_1, unsigned int size_2) -> InterferenceFunctionFinite2DLattice"},
-	 { (char *)"InterferenceFunctionFinite2DLattice_evaluate", _wrap_InterferenceFunctionFinite2DLattice_evaluate, METH_VARARGS, (char *)"\n"
-		"InterferenceFunctionFinite2DLattice_evaluate(InterferenceFunctionFinite2DLattice self, kvector_t q) -> double\n"
+	 { (char *)"InterferenceFunction2DParaCrystal_setIntegrationOverXi", _wrap_InterferenceFunction2DParaCrystal_setIntegrationOverXi, METH_VARARGS, (char *)"\n"
+		"InterferenceFunction2DParaCrystal_setIntegrationOverXi(InterferenceFunction2DParaCrystal self, bool integrate_xi)\n"
 		"\n"
-		"double InterferenceFunctionFinite2DLattice::evaluate(const kvector_t q) const final\n"
+		"void InterferenceFunction2DParaCrystal::setIntegrationOverXi(bool integrate_xi)\n"
 		"\n"
-		"Evaluates the interference function for a given wavevector transfer (only the real x and y components are relevant) \n"
+		"Enables/disables averaging over the lattice rotation angle.\n"
 		"\n"
-		""},
-	 { (char *)"InterferenceFunctionFinite2DLattice_domainSize1", _wrap_InterferenceFunctionFinite2DLattice_domainSize1, METH_VARARGS, (char *)"\n"
-		"InterferenceFunctionFinite2DLattice_domainSize1(InterferenceFunctionFinite2DLattice self) -> unsigned int\n"
+		"Parameters:\n"
+		"-----------\n"
 		"\n"
-		"unsigned InterferenceFunctionFinite2DLattice::domainSize1() const\n"
+		"integrate_xi: \n"
+		"integration flag \n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunctionFinite2DLattice_domainSize2", _wrap_InterferenceFunctionFinite2DLattice_domainSize2, METH_VARARGS, (char *)"\n"
-		"InterferenceFunctionFinite2DLattice_domainSize2(InterferenceFunctionFinite2DLattice self) -> unsigned int\n"
+	 { (char *)"InterferenceFunction2DParaCrystal_integrationOverXi", _wrap_InterferenceFunction2DParaCrystal_integrationOverXi, METH_VARARGS, (char *)"\n"
+		"InterferenceFunction2DParaCrystal_integrationOverXi(InterferenceFunction2DParaCrystal self) -> bool\n"
 		"\n"
-		"unsigned InterferenceFunctionFinite2DLattice::domainSize2() const\n"
+		"bool InterferenceFunction2DParaCrystal::integrationOverXi() const\n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunctionFinite2DLattice_setPositionVariance", _wrap_InterferenceFunctionFinite2DLattice_setPositionVariance, METH_VARARGS, (char *)"\n"
-		"InterferenceFunctionFinite2DLattice_setPositionVariance(InterferenceFunctionFinite2DLattice self, double sigma2)\n"
+	 { (char *)"InterferenceFunction2DParaCrystal_dampingLength", _wrap_InterferenceFunction2DParaCrystal_dampingLength, METH_VARARGS, (char *)"\n"
+		"InterferenceFunction2DParaCrystal_dampingLength(InterferenceFunction2DParaCrystal self) -> double\n"
 		"\n"
-		"void InterferenceFunctionFinite2DLattice::setPositionVariance(double sigma2)\n"
+		"double InterferenceFunction2DParaCrystal::dampingLength() const\n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunctionFinite2DLattice_positionVariance", _wrap_InterferenceFunctionFinite2DLattice_positionVariance, METH_VARARGS, (char *)"\n"
-		"InterferenceFunctionFinite2DLattice_positionVariance(InterferenceFunctionFinite2DLattice self) -> double\n"
+	 { (char *)"InterferenceFunction2DParaCrystal_lattice", _wrap_InterferenceFunction2DParaCrystal_lattice, METH_VARARGS, (char *)"\n"
+		"InterferenceFunction2DParaCrystal_lattice(InterferenceFunction2DParaCrystal self) -> Lattice2D\n"
 		"\n"
-		"double InterferenceFunctionFinite2DLattice::positionVariance() const\n"
+		"const Lattice2D & InterferenceFunction2DParaCrystal::lattice() const\n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunctionFinite2DLattice_setIntegrationOverXi", _wrap_InterferenceFunctionFinite2DLattice_setIntegrationOverXi, METH_VARARGS, (char *)"\n"
-		"InterferenceFunctionFinite2DLattice_setIntegrationOverXi(InterferenceFunctionFinite2DLattice self, bool integrate_xi)\n"
-		"\n"
-		"void InterferenceFunctionFinite2DLattice::setIntegrationOverXi(bool integrate_xi)\n"
+	 { (char *)"InterferenceFunction2DParaCrystal_getParticleDensity", _wrap_InterferenceFunction2DParaCrystal_getParticleDensity, METH_VARARGS, (char *)"\n"
+		"InterferenceFunction2DParaCrystal_getParticleDensity(InterferenceFunction2DParaCrystal self) -> double\n"
 		"\n"
-		""},
-	 { (char *)"InterferenceFunctionFinite2DLattice_integrationOverXi", _wrap_InterferenceFunctionFinite2DLattice_integrationOverXi, METH_VARARGS, (char *)"\n"
-		"InterferenceFunctionFinite2DLattice_integrationOverXi(InterferenceFunctionFinite2DLattice self) -> bool\n"
+		"double InterferenceFunction2DParaCrystal::getParticleDensity() const final\n"
 		"\n"
-		"bool InterferenceFunctionFinite2DLattice::integrationOverXi() const\n"
+		"If defined by this interference function's parameters, returns the particle density (per area). Otherwise, returns zero or a user-defined value \n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunctionFinite2DLattice_lattice", _wrap_InterferenceFunctionFinite2DLattice_lattice, METH_VARARGS, (char *)"\n"
-		"InterferenceFunctionFinite2DLattice_lattice(InterferenceFunctionFinite2DLattice self) -> Lattice2D\n"
+	 { (char *)"InterferenceFunction2DParaCrystal_getChildren", _wrap_InterferenceFunction2DParaCrystal_getChildren, METH_VARARGS, (char *)"\n"
+		"InterferenceFunction2DParaCrystal_getChildren(InterferenceFunction2DParaCrystal self) -> swig_dummy_type_const_inode_vector\n"
 		"\n"
-		"const Lattice2D & InterferenceFunctionFinite2DLattice::lattice() const\n"
+		"std::vector< const INode * > InterferenceFunction2DParaCrystal::getChildren() const\n"
 		"\n"
-		""},
-	 { (char *)"InterferenceFunctionFinite2DLattice_getParticleDensity", _wrap_InterferenceFunctionFinite2DLattice_getParticleDensity, METH_VARARGS, (char *)"\n"
-		"InterferenceFunctionFinite2DLattice_getParticleDensity(InterferenceFunctionFinite2DLattice self) -> double\n"
+		"Returns a vector of children (const). \n"
 		"\n"
-		"double InterferenceFunctionFinite2DLattice::getParticleDensity() const final\n"
+		""},
+	 { (char *)"InterferenceFunction2DParaCrystal_pdf1", _wrap_InterferenceFunction2DParaCrystal_pdf1, METH_VARARGS, (char *)"\n"
+		"InterferenceFunction2DParaCrystal_pdf1(InterferenceFunction2DParaCrystal self) -> IFTDistribution2D\n"
 		"\n"
-		"Returns the particle density associated with this 2d lattice. \n"
+		"const IFTDistribution2D* InterferenceFunction2DParaCrystal::pdf1() const\n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunctionFinite2DLattice_getChildren", _wrap_InterferenceFunctionFinite2DLattice_getChildren, METH_VARARGS, (char *)"\n"
-		"InterferenceFunctionFinite2DLattice_getChildren(InterferenceFunctionFinite2DLattice self) -> swig_dummy_type_const_inode_vector\n"
+	 { (char *)"InterferenceFunction2DParaCrystal_pdf2", _wrap_InterferenceFunction2DParaCrystal_pdf2, METH_VARARGS, (char *)"\n"
+		"InterferenceFunction2DParaCrystal_pdf2(InterferenceFunction2DParaCrystal self) -> IFTDistribution2D\n"
 		"\n"
-		"std::vector< const INode * > InterferenceFunctionFinite2DLattice::getChildren() const override\n"
-		"\n"
-		"Returns a vector of children (const). \n"
+		"const IFTDistribution2D* InterferenceFunction2DParaCrystal::pdf2() const\n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunctionFinite2DLattice_swigregister", InterferenceFunctionFinite2DLattice_swigregister, METH_VARARGS, NULL},
+	 { (char *)"InterferenceFunction2DParaCrystal_swigregister", InterferenceFunction2DParaCrystal_swigregister, METH_VARARGS, NULL},
 	 { (char *)"new_InterferenceFunction2DSuperLattice", _wrap_new_InterferenceFunction2DSuperLattice, METH_VARARGS, (char *)"\n"
 		"InterferenceFunction2DSuperLattice(Lattice2D lattice, unsigned int size_1, unsigned int size_2)\n"
 		"new_InterferenceFunction2DSuperLattice(double length_1, double length_2, double alpha, double xi, unsigned int size_1, unsigned int size_2) -> InterferenceFunction2DSuperLattice\n"
@@ -136498,18 +128776,92 @@ static PyMethodDef SwigMethods[] = {
 		"\n"
 		""},
 	 { (char *)"InterferenceFunction2DSuperLattice_swigregister", InterferenceFunction2DSuperLattice_swigregister, METH_VARARGS, NULL},
-	 { (char *)"new_InterferenceFunction2DParaCrystal", _wrap_new_InterferenceFunction2DParaCrystal, METH_VARARGS, (char *)"\n"
-		"InterferenceFunction2DParaCrystal(Lattice2D lattice, double damping_length=0.0, double domain_size_1=0.0, double domain_size_2=0.0)\n"
-		"InterferenceFunction2DParaCrystal(Lattice2D lattice, double damping_length=0.0, double domain_size_1=0.0)\n"
-		"InterferenceFunction2DParaCrystal(Lattice2D lattice, double damping_length=0.0)\n"
-		"InterferenceFunction2DParaCrystal(Lattice2D lattice)\n"
-		"InterferenceFunction2DParaCrystal(double length_1, double length_2, double alpha, double xi=0.0, double damping_length=0.0)\n"
-		"InterferenceFunction2DParaCrystal(double length_1, double length_2, double alpha, double xi=0.0)\n"
-		"new_InterferenceFunction2DParaCrystal(double length_1, double length_2, double alpha) -> InterferenceFunction2DParaCrystal\n"
+	 { (char *)"new_InterferenceFunction3DLattice", _wrap_new_InterferenceFunction3DLattice, METH_VARARGS, (char *)"\n"
+		"new_InterferenceFunction3DLattice(Lattice lattice) -> InterferenceFunction3DLattice\n"
 		"\n"
-		"InterferenceFunction2DParaCrystal::InterferenceFunction2DParaCrystal(double length_1, double length_2, double alpha, double xi=0.0, double damping_length=0.0)\n"
+		"InterferenceFunction3DLattice::InterferenceFunction3DLattice(const Lattice &lattice)\n"
 		"\n"
-		"Constructor of interference function of two-dimensional paracrystal.\n"
+		""},
+	 { (char *)"delete_InterferenceFunction3DLattice", _wrap_delete_InterferenceFunction3DLattice, METH_VARARGS, (char *)"\n"
+		"delete_InterferenceFunction3DLattice(InterferenceFunction3DLattice self)\n"
+		"\n"
+		"InterferenceFunction3DLattice::~InterferenceFunction3DLattice() final\n"
+		"\n"
+		""},
+	 { (char *)"InterferenceFunction3DLattice_clone", _wrap_InterferenceFunction3DLattice_clone, METH_VARARGS, (char *)"\n"
+		"InterferenceFunction3DLattice_clone(InterferenceFunction3DLattice self) -> InterferenceFunction3DLattice\n"
+		"\n"
+		"InterferenceFunction3DLattice * InterferenceFunction3DLattice::clone() const final\n"
+		"\n"
+		"Returns a clone of this  ISample object. \n"
+		"\n"
+		""},
+	 { (char *)"InterferenceFunction3DLattice_accept", _wrap_InterferenceFunction3DLattice_accept, METH_VARARGS, (char *)"\n"
+		"InterferenceFunction3DLattice_accept(InterferenceFunction3DLattice self, INodeVisitor visitor)\n"
+		"\n"
+		"void InterferenceFunction3DLattice::accept(INodeVisitor *visitor) const final\n"
+		"\n"
+		"Calls the  INodeVisitor's visit method. \n"
+		"\n"
+		""},
+	 { (char *)"InterferenceFunction3DLattice_setPeakShape", _wrap_InterferenceFunction3DLattice_setPeakShape, METH_VARARGS, (char *)"\n"
+		"InterferenceFunction3DLattice_setPeakShape(InterferenceFunction3DLattice self, IPeakShape peak_shape)\n"
+		"\n"
+		"void InterferenceFunction3DLattice::setPeakShape(const IPeakShape &peak_shape)\n"
+		"\n"
+		""},
+	 { (char *)"InterferenceFunction3DLattice_setDebyeWallerFactor", _wrap_InterferenceFunction3DLattice_setDebyeWallerFactor, METH_VARARGS, (char *)"\n"
+		"InterferenceFunction3DLattice_setDebyeWallerFactor(InterferenceFunction3DLattice self, double dw_length)\n"
+		"\n"
+		"void InterferenceFunction3DLattice::setDebyeWallerFactor(double dw_length)\n"
+		"\n"
+		""},
+	 { (char *)"InterferenceFunction3DLattice_evaluate", _wrap_InterferenceFunction3DLattice_evaluate, METH_VARARGS, (char *)"\n"
+		"InterferenceFunction3DLattice_evaluate(InterferenceFunction3DLattice self, kvector_t q) -> double\n"
+		"\n"
+		"double InterferenceFunction3DLattice::evaluate(const kvector_t q) const final\n"
+		"\n"
+		"Evaluates the interference function for a given wavevector transfer (only the real x and y components are relevant) \n"
+		"\n"
+		""},
+	 { (char *)"InterferenceFunction3DLattice_lattice", _wrap_InterferenceFunction3DLattice_lattice, METH_VARARGS, (char *)"\n"
+		"InterferenceFunction3DLattice_lattice(InterferenceFunction3DLattice self) -> Lattice\n"
+		"\n"
+		"const Lattice & InterferenceFunction3DLattice::lattice() const\n"
+		"\n"
+		""},
+	 { (char *)"InterferenceFunction3DLattice_supportsMultilayer", _wrap_InterferenceFunction3DLattice_supportsMultilayer, METH_VARARGS, (char *)"\n"
+		"InterferenceFunction3DLattice_supportsMultilayer(InterferenceFunction3DLattice self) -> bool\n"
+		"\n"
+		"bool InterferenceFunction3DLattice::supportsMultilayer() const override\n"
+		"\n"
+		"Indicates if this interference function can be used with a multilayer (DWBA mode) \n"
+		"\n"
+		""},
+	 { (char *)"InterferenceFunction3DLattice_getChildren", _wrap_InterferenceFunction3DLattice_getChildren, METH_VARARGS, (char *)"\n"
+		"InterferenceFunction3DLattice_getChildren(InterferenceFunction3DLattice self) -> swig_dummy_type_const_inode_vector\n"
+		"\n"
+		"std::vector< const INode * > InterferenceFunction3DLattice::getChildren() const override\n"
+		"\n"
+		"Returns a vector of children (const). \n"
+		"\n"
+		""},
+	 { (char *)"InterferenceFunction3DLattice_onChange", _wrap_InterferenceFunction3DLattice_onChange, METH_VARARGS, (char *)"\n"
+		"InterferenceFunction3DLattice_onChange(InterferenceFunction3DLattice self)\n"
+		"\n"
+		"void InterferenceFunction3DLattice::onChange() override final\n"
+		"\n"
+		"Action to be taken in inherited class when a parameter has changed. \n"
+		"\n"
+		""},
+	 { (char *)"InterferenceFunction3DLattice_swigregister", InterferenceFunction3DLattice_swigregister, METH_VARARGS, NULL},
+	 { (char *)"new_InterferenceFunctionFinite2DLattice", _wrap_new_InterferenceFunctionFinite2DLattice, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionFinite2DLattice(Lattice2D lattice, unsigned int N_1, unsigned int N_2)\n"
+		"new_InterferenceFunctionFinite2DLattice(double length_1, double length_2, double alpha, double xi, unsigned int N_1, unsigned int N_2) -> InterferenceFunctionFinite2DLattice\n"
+		"\n"
+		"InterferenceFunctionFinite2DLattice::InterferenceFunctionFinite2DLattice(double length_1, double length_2, double alpha, double xi, unsigned N_1, unsigned N_2)\n"
+		"\n"
+		"Constructor of two-dimensional finite lattice interference function.\n"
 		"\n"
 		"Parameters:\n"
 		"-----------\n"
@@ -136526,155 +128878,187 @@ static PyMethodDef SwigMethods[] = {
 		"xi: \n"
 		"rotation of lattice with respect to x-axis (beam direction) in radians\n"
 		"\n"
-		"damping_length: \n"
-		"the damping (coherence) length of the paracrystal in nanometers \n"
+		"N_1: \n"
+		"number of lattice cells in the first lattice direction\n"
+		"\n"
+		"N_2: \n"
+		"number of lattice cells in the second lattice direction \n"
 		"\n"
 		""},
-	 { (char *)"delete_InterferenceFunction2DParaCrystal", _wrap_delete_InterferenceFunction2DParaCrystal, METH_VARARGS, (char *)"\n"
-		"delete_InterferenceFunction2DParaCrystal(InterferenceFunction2DParaCrystal self)\n"
+	 { (char *)"delete_InterferenceFunctionFinite2DLattice", _wrap_delete_InterferenceFunctionFinite2DLattice, METH_VARARGS, (char *)"\n"
+		"delete_InterferenceFunctionFinite2DLattice(InterferenceFunctionFinite2DLattice self)\n"
 		"\n"
-		"InterferenceFunction2DParaCrystal::~InterferenceFunction2DParaCrystal() final\n"
+		"InterferenceFunctionFinite2DLattice::~InterferenceFunctionFinite2DLattice() final\n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunction2DParaCrystal_clone", _wrap_InterferenceFunction2DParaCrystal_clone, METH_VARARGS, (char *)"\n"
-		"InterferenceFunction2DParaCrystal_clone(InterferenceFunction2DParaCrystal self) -> InterferenceFunction2DParaCrystal\n"
+	 { (char *)"InterferenceFunctionFinite2DLattice_clone", _wrap_InterferenceFunctionFinite2DLattice_clone, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionFinite2DLattice_clone(InterferenceFunctionFinite2DLattice self) -> InterferenceFunctionFinite2DLattice\n"
 		"\n"
-		"InterferenceFunction2DParaCrystal * InterferenceFunction2DParaCrystal::clone() const final\n"
+		"InterferenceFunctionFinite2DLattice * InterferenceFunctionFinite2DLattice::clone() const final\n"
 		"\n"
 		"Returns a clone of this  ISample object. \n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunction2DParaCrystal_accept", _wrap_InterferenceFunction2DParaCrystal_accept, METH_VARARGS, (char *)"\n"
-		"InterferenceFunction2DParaCrystal_accept(InterferenceFunction2DParaCrystal self, INodeVisitor visitor)\n"
+	 { (char *)"InterferenceFunctionFinite2DLattice_accept", _wrap_InterferenceFunctionFinite2DLattice_accept, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionFinite2DLattice_accept(InterferenceFunctionFinite2DLattice self, INodeVisitor visitor)\n"
 		"\n"
-		"void InterferenceFunction2DParaCrystal::accept(INodeVisitor *visitor) const final\n"
+		"void InterferenceFunctionFinite2DLattice::accept(INodeVisitor *visitor) const final\n"
 		"\n"
 		"Calls the  INodeVisitor's visit method. \n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunction2DParaCrystal_createSquare", _wrap_InterferenceFunction2DParaCrystal_createSquare, METH_VARARGS, (char *)"\n"
-		"createSquare(double lattice_length, double damping_length=0.0, double domain_size_1=0.0, double domain_size_2=0.0) -> InterferenceFunction2DParaCrystal\n"
-		"createSquare(double lattice_length, double damping_length=0.0, double domain_size_1=0.0) -> InterferenceFunction2DParaCrystal\n"
-		"createSquare(double lattice_length, double damping_length=0.0) -> InterferenceFunction2DParaCrystal\n"
-		"InterferenceFunction2DParaCrystal_createSquare(double lattice_length) -> InterferenceFunction2DParaCrystal\n"
+	 { (char *)"InterferenceFunctionFinite2DLattice_createSquare", _wrap_InterferenceFunctionFinite2DLattice_createSquare, METH_VARARGS, (char *)"InterferenceFunctionFinite2DLattice_createSquare(double lattice_length, double xi, unsigned int N_1, unsigned int N_2) -> InterferenceFunctionFinite2DLattice"},
+	 { (char *)"InterferenceFunctionFinite2DLattice_createHexagonal", _wrap_InterferenceFunctionFinite2DLattice_createHexagonal, METH_VARARGS, (char *)"InterferenceFunctionFinite2DLattice_createHexagonal(double lattice_length, double xi, unsigned int N_1, unsigned int N_2) -> InterferenceFunctionFinite2DLattice"},
+	 { (char *)"InterferenceFunctionFinite2DLattice_evaluate", _wrap_InterferenceFunctionFinite2DLattice_evaluate, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionFinite2DLattice_evaluate(InterferenceFunctionFinite2DLattice self, kvector_t q) -> double\n"
+		"\n"
+		"double InterferenceFunctionFinite2DLattice::evaluate(const kvector_t q) const final\n"
+		"\n"
+		"Evaluates the interference function for a given wavevector transfer (only the real x and y components are relevant) \n"
+		"\n"
 		""},
-	 { (char *)"InterferenceFunction2DParaCrystal_createHexagonal", _wrap_InterferenceFunction2DParaCrystal_createHexagonal, METH_VARARGS, (char *)"\n"
-		"createHexagonal(double lattice_length, double damping_length=0.0, double domain_size_1=0.0, double domain_size_2=0.0) -> InterferenceFunction2DParaCrystal\n"
-		"createHexagonal(double lattice_length, double damping_length=0.0, double domain_size_1=0.0) -> InterferenceFunction2DParaCrystal\n"
-		"createHexagonal(double lattice_length, double damping_length=0.0) -> InterferenceFunction2DParaCrystal\n"
-		"InterferenceFunction2DParaCrystal_createHexagonal(double lattice_length) -> InterferenceFunction2DParaCrystal\n"
+	 { (char *)"InterferenceFunctionFinite2DLattice_numberUnitCells1", _wrap_InterferenceFunctionFinite2DLattice_numberUnitCells1, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionFinite2DLattice_numberUnitCells1(InterferenceFunctionFinite2DLattice self) -> unsigned int\n"
+		"\n"
+		"unsigned InterferenceFunctionFinite2DLattice::numberUnitCells1() const\n"
+		"\n"
 		""},
-	 { (char *)"InterferenceFunction2DParaCrystal_setDomainSizes", _wrap_InterferenceFunction2DParaCrystal_setDomainSizes, METH_VARARGS, (char *)"\n"
-		"InterferenceFunction2DParaCrystal_setDomainSizes(InterferenceFunction2DParaCrystal self, double size_1, double size_2)\n"
+	 { (char *)"InterferenceFunctionFinite2DLattice_numberUnitCells2", _wrap_InterferenceFunctionFinite2DLattice_numberUnitCells2, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionFinite2DLattice_numberUnitCells2(InterferenceFunctionFinite2DLattice self) -> unsigned int\n"
 		"\n"
-		"void InterferenceFunction2DParaCrystal::setDomainSizes(double size_1, double size_2)\n"
+		"unsigned InterferenceFunctionFinite2DLattice::numberUnitCells2() const\n"
 		"\n"
-		"Sets the sizes of coherence domains.\n"
+		""},
+	 { (char *)"InterferenceFunctionFinite2DLattice_setPositionVariance", _wrap_InterferenceFunctionFinite2DLattice_setPositionVariance, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionFinite2DLattice_setPositionVariance(InterferenceFunctionFinite2DLattice self, double sigma2)\n"
 		"\n"
-		"Parameters:\n"
-		"-----------\n"
+		"void InterferenceFunctionFinite2DLattice::setPositionVariance(double sigma2)\n"
 		"\n"
-		"size_1: \n"
-		"coherence domain size along the first basis vector in nanometers\n"
+		""},
+	 { (char *)"InterferenceFunctionFinite2DLattice_positionVariance", _wrap_InterferenceFunctionFinite2DLattice_positionVariance, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionFinite2DLattice_positionVariance(InterferenceFunctionFinite2DLattice self) -> double\n"
 		"\n"
-		"size_2: \n"
-		"coherence domain size along the second basis vector in nanometers \n"
+		"double InterferenceFunctionFinite2DLattice::positionVariance() const\n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunction2DParaCrystal_setProbabilityDistributions", _wrap_InterferenceFunction2DParaCrystal_setProbabilityDistributions, METH_VARARGS, (char *)"\n"
-		"InterferenceFunction2DParaCrystal_setProbabilityDistributions(InterferenceFunction2DParaCrystal self, IFTDistribution2D pdf_1, IFTDistribution2D pdf_2)\n"
+	 { (char *)"InterferenceFunctionFinite2DLattice_setIntegrationOverXi", _wrap_InterferenceFunctionFinite2DLattice_setIntegrationOverXi, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionFinite2DLattice_setIntegrationOverXi(InterferenceFunctionFinite2DLattice self, bool integrate_xi)\n"
 		"\n"
-		"void InterferenceFunction2DParaCrystal::setProbabilityDistributions(const IFTDistribution2D &pdf_1, const IFTDistribution2D &pdf_2)\n"
+		"void InterferenceFunctionFinite2DLattice::setIntegrationOverXi(bool integrate_xi)\n"
 		"\n"
-		"Sets the probability distributions (Fourier transformed) for the two lattice directions.\n"
+		""},
+	 { (char *)"InterferenceFunctionFinite2DLattice_integrationOverXi", _wrap_InterferenceFunctionFinite2DLattice_integrationOverXi, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionFinite2DLattice_integrationOverXi(InterferenceFunctionFinite2DLattice self) -> bool\n"
 		"\n"
-		"Parameters:\n"
-		"-----------\n"
+		"bool InterferenceFunctionFinite2DLattice::integrationOverXi() const\n"
 		"\n"
-		"pdf_1: \n"
-		"probability distribution in first lattice direction\n"
+		""},
+	 { (char *)"InterferenceFunctionFinite2DLattice_lattice", _wrap_InterferenceFunctionFinite2DLattice_lattice, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionFinite2DLattice_lattice(InterferenceFunctionFinite2DLattice self) -> Lattice2D\n"
 		"\n"
-		"pdf_2: \n"
-		"probability distribution in second lattice direction \n"
+		"const Lattice2D & InterferenceFunctionFinite2DLattice::lattice() const\n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunction2DParaCrystal_setDampingLength", _wrap_InterferenceFunction2DParaCrystal_setDampingLength, METH_VARARGS, (char *)"\n"
-		"InterferenceFunction2DParaCrystal_setDampingLength(InterferenceFunction2DParaCrystal self, double damping_length)\n"
+	 { (char *)"InterferenceFunctionFinite2DLattice_getParticleDensity", _wrap_InterferenceFunctionFinite2DLattice_getParticleDensity, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionFinite2DLattice_getParticleDensity(InterferenceFunctionFinite2DLattice self) -> double\n"
 		"\n"
-		"void InterferenceFunction2DParaCrystal::setDampingLength(double damping_length)\n"
+		"double InterferenceFunctionFinite2DLattice::getParticleDensity() const final\n"
 		"\n"
-		"Sets the damping length.\n"
+		"Returns the particle density associated with this 2d lattice. \n"
 		"\n"
-		"Parameters:\n"
-		"-----------\n"
+		""},
+	 { (char *)"InterferenceFunctionFinite2DLattice_getChildren", _wrap_InterferenceFunctionFinite2DLattice_getChildren, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionFinite2DLattice_getChildren(InterferenceFunctionFinite2DLattice self) -> swig_dummy_type_const_inode_vector\n"
 		"\n"
-		"damping_length: \n"
-		"the damping (coherence) length of the paracrystal in nanometers \n"
+		"std::vector< const INode * > InterferenceFunctionFinite2DLattice::getChildren() const override\n"
+		"\n"
+		"Returns a vector of children (const). \n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunction2DParaCrystal_evaluate", _wrap_InterferenceFunction2DParaCrystal_evaluate, METH_VARARGS, (char *)"\n"
-		"InterferenceFunction2DParaCrystal_evaluate(InterferenceFunction2DParaCrystal self, kvector_t q) -> double\n"
+	 { (char *)"InterferenceFunctionFinite2DLattice_swigregister", InterferenceFunctionFinite2DLattice_swigregister, METH_VARARGS, NULL},
+	 { (char *)"new_InterferenceFunctionFinite3DLattice", _wrap_new_InterferenceFunctionFinite3DLattice, METH_VARARGS, (char *)"\n"
+		"new_InterferenceFunctionFinite3DLattice(Lattice lattice, unsigned int N_1, unsigned int N_2, unsigned int N_3) -> InterferenceFunctionFinite3DLattice\n"
 		"\n"
-		"double InterferenceFunction2DParaCrystal::evaluate(const kvector_t q) const final\n"
+		"InterferenceFunctionFinite3DLattice::InterferenceFunctionFinite3DLattice(const Lattice &lattice, unsigned N_1, unsigned N_2, unsigned N_3)\n"
 		"\n"
-		"Evaluates the interference function for a given wavevector transfer (only the real x and y components are relevant) \n"
+		"Constructor of three-dimensional finite lattice interference function.\n"
+		"\n"
+		"Parameters:\n"
+		"-----------\n"
+		"\n"
+		"lattice: \n"
+		"object specifying a 2d lattice structure\n"
+		"\n"
+		"N_1: \n"
+		"number of lattice cells in the first lattice direction\n"
+		"\n"
+		"N_2: \n"
+		"number of lattice cells in the second lattice direction \n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunction2DParaCrystal_domainSizes", _wrap_InterferenceFunction2DParaCrystal_domainSizes, METH_VARARGS, (char *)"\n"
-		"InterferenceFunction2DParaCrystal_domainSizes(InterferenceFunction2DParaCrystal self) -> vdouble1d_t\n"
+	 { (char *)"delete_InterferenceFunctionFinite3DLattice", _wrap_delete_InterferenceFunctionFinite3DLattice, METH_VARARGS, (char *)"\n"
+		"delete_InterferenceFunctionFinite3DLattice(InterferenceFunctionFinite3DLattice self)\n"
 		"\n"
-		"std::vector< double > InterferenceFunction2DParaCrystal::domainSizes() const\n"
+		"InterferenceFunctionFinite3DLattice::~InterferenceFunctionFinite3DLattice() final\n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunction2DParaCrystal_setIntegrationOverXi", _wrap_InterferenceFunction2DParaCrystal_setIntegrationOverXi, METH_VARARGS, (char *)"\n"
-		"InterferenceFunction2DParaCrystal_setIntegrationOverXi(InterferenceFunction2DParaCrystal self, bool integrate_xi)\n"
+	 { (char *)"InterferenceFunctionFinite3DLattice_clone", _wrap_InterferenceFunctionFinite3DLattice_clone, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionFinite3DLattice_clone(InterferenceFunctionFinite3DLattice self) -> InterferenceFunctionFinite3DLattice\n"
 		"\n"
-		"void InterferenceFunction2DParaCrystal::setIntegrationOverXi(bool integrate_xi)\n"
+		"InterferenceFunctionFinite3DLattice * InterferenceFunctionFinite3DLattice::clone() const final\n"
 		"\n"
-		"Enables/disables averaging over the lattice rotation angle.\n"
+		"Returns a clone of this  ISample object. \n"
 		"\n"
-		"Parameters:\n"
-		"-----------\n"
+		""},
+	 { (char *)"InterferenceFunctionFinite3DLattice_accept", _wrap_InterferenceFunctionFinite3DLattice_accept, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionFinite3DLattice_accept(InterferenceFunctionFinite3DLattice self, INodeVisitor visitor)\n"
 		"\n"
-		"integrate_xi: \n"
-		"integration flag \n"
+		"void InterferenceFunctionFinite3DLattice::accept(INodeVisitor *visitor) const final\n"
+		"\n"
+		"Calls the  INodeVisitor's visit method. \n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunction2DParaCrystal_integrationOverXi", _wrap_InterferenceFunction2DParaCrystal_integrationOverXi, METH_VARARGS, (char *)"\n"
-		"InterferenceFunction2DParaCrystal_integrationOverXi(InterferenceFunction2DParaCrystal self) -> bool\n"
+	 { (char *)"InterferenceFunctionFinite3DLattice_evaluate", _wrap_InterferenceFunctionFinite3DLattice_evaluate, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionFinite3DLattice_evaluate(InterferenceFunctionFinite3DLattice self, kvector_t q) -> double\n"
 		"\n"
-		"bool InterferenceFunction2DParaCrystal::integrationOverXi() const\n"
+		"double InterferenceFunctionFinite3DLattice::evaluate(const kvector_t q) const final\n"
+		"\n"
+		"Evaluates the interference function for a given wavevector transfer (only the real x and y components are relevant) \n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunction2DParaCrystal_dampingLength", _wrap_InterferenceFunction2DParaCrystal_dampingLength, METH_VARARGS, (char *)"\n"
-		"InterferenceFunction2DParaCrystal_dampingLength(InterferenceFunction2DParaCrystal self) -> double\n"
+	 { (char *)"InterferenceFunctionFinite3DLattice_numberUnitCells1", _wrap_InterferenceFunctionFinite3DLattice_numberUnitCells1, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionFinite3DLattice_numberUnitCells1(InterferenceFunctionFinite3DLattice self) -> unsigned int\n"
 		"\n"
-		"double InterferenceFunction2DParaCrystal::dampingLength() const\n"
+		"unsigned InterferenceFunctionFinite3DLattice::numberUnitCells1() const\n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunction2DParaCrystal_lattice", _wrap_InterferenceFunction2DParaCrystal_lattice, METH_VARARGS, (char *)"\n"
-		"InterferenceFunction2DParaCrystal_lattice(InterferenceFunction2DParaCrystal self) -> Lattice2D\n"
+	 { (char *)"InterferenceFunctionFinite3DLattice_numberUnitCells2", _wrap_InterferenceFunctionFinite3DLattice_numberUnitCells2, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionFinite3DLattice_numberUnitCells2(InterferenceFunctionFinite3DLattice self) -> unsigned int\n"
 		"\n"
-		"const Lattice2D & InterferenceFunction2DParaCrystal::lattice() const\n"
+		"unsigned InterferenceFunctionFinite3DLattice::numberUnitCells2() const\n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunction2DParaCrystal_getParticleDensity", _wrap_InterferenceFunction2DParaCrystal_getParticleDensity, METH_VARARGS, (char *)"\n"
-		"InterferenceFunction2DParaCrystal_getParticleDensity(InterferenceFunction2DParaCrystal self) -> double\n"
+	 { (char *)"InterferenceFunctionFinite3DLattice_numberUnitCells3", _wrap_InterferenceFunctionFinite3DLattice_numberUnitCells3, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionFinite3DLattice_numberUnitCells3(InterferenceFunctionFinite3DLattice self) -> unsigned int\n"
 		"\n"
-		"double InterferenceFunction2DParaCrystal::getParticleDensity() const final\n"
+		"unsigned InterferenceFunctionFinite3DLattice::numberUnitCells3() const\n"
 		"\n"
-		"If defined by this interference function's parameters, returns the particle density (per area). Otherwise, returns zero or a user-defined value \n"
+		""},
+	 { (char *)"InterferenceFunctionFinite3DLattice_lattice", _wrap_InterferenceFunctionFinite3DLattice_lattice, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionFinite3DLattice_lattice(InterferenceFunctionFinite3DLattice self) -> Lattice\n"
+		"\n"
+		"const Lattice & InterferenceFunctionFinite3DLattice::lattice() const\n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunction2DParaCrystal_getChildren", _wrap_InterferenceFunction2DParaCrystal_getChildren, METH_VARARGS, (char *)"\n"
-		"InterferenceFunction2DParaCrystal_getChildren(InterferenceFunction2DParaCrystal self) -> swig_dummy_type_const_inode_vector\n"
+	 { (char *)"InterferenceFunctionFinite3DLattice_getChildren", _wrap_InterferenceFunctionFinite3DLattice_getChildren, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionFinite3DLattice_getChildren(InterferenceFunctionFinite3DLattice self) -> swig_dummy_type_const_inode_vector\n"
 		"\n"
-		"std::vector< const INode * > InterferenceFunction2DParaCrystal::getChildren() const\n"
+		"std::vector< const INode * > InterferenceFunctionFinite3DLattice::getChildren() const override\n"
 		"\n"
 		"Returns a vector of children (const). \n"
 		"\n"
 		""},
-	 { (char *)"InterferenceFunction2DParaCrystal_swigregister", InterferenceFunction2DParaCrystal_swigregister, METH_VARARGS, NULL},
+	 { (char *)"InterferenceFunctionFinite3DLattice_swigregister", InterferenceFunctionFinite3DLattice_swigregister, METH_VARARGS, NULL},
 	 { (char *)"new_InterferenceFunctionNone", _wrap_new_InterferenceFunctionNone, METH_VARARGS, (char *)"\n"
 		"new_InterferenceFunctionNone() -> InterferenceFunctionNone\n"
 		"\n"
@@ -136707,6 +129091,136 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { (char *)"delete_InterferenceFunctionNone", _wrap_delete_InterferenceFunctionNone, METH_VARARGS, (char *)"delete_InterferenceFunctionNone(InterferenceFunctionNone self)"},
 	 { (char *)"InterferenceFunctionNone_swigregister", InterferenceFunctionNone_swigregister, METH_VARARGS, NULL},
+	 { (char *)"new_InterferenceFunctionRadialParaCrystal", _wrap_new_InterferenceFunctionRadialParaCrystal, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionRadialParaCrystal(double peak_distance, double damping_length=0.0)\n"
+		"new_InterferenceFunctionRadialParaCrystal(double peak_distance) -> InterferenceFunctionRadialParaCrystal\n"
+		"\n"
+		"InterferenceFunctionRadialParaCrystal::InterferenceFunctionRadialParaCrystal(double peak_distance, double damping_length=0.0)\n"
+		"\n"
+		"Constructor of interference function of radial paracrystal.\n"
+		"\n"
+		"Parameters:\n"
+		"-----------\n"
+		"\n"
+		"peak_distance: \n"
+		"average distance to the next neighbor in nanometers\n"
+		"\n"
+		"damping_length: \n"
+		"the damping (coherence) length of the paracrystal in nanometers \n"
+		"\n"
+		""},
+	 { (char *)"InterferenceFunctionRadialParaCrystal_clone", _wrap_InterferenceFunctionRadialParaCrystal_clone, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionRadialParaCrystal_clone(InterferenceFunctionRadialParaCrystal self) -> InterferenceFunctionRadialParaCrystal\n"
+		"\n"
+		"InterferenceFunctionRadialParaCrystal * InterferenceFunctionRadialParaCrystal::clone() const final\n"
+		"\n"
+		"Returns a clone of this  ISample object. \n"
+		"\n"
+		""},
+	 { (char *)"InterferenceFunctionRadialParaCrystal_accept", _wrap_InterferenceFunctionRadialParaCrystal_accept, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionRadialParaCrystal_accept(InterferenceFunctionRadialParaCrystal self, INodeVisitor visitor)\n"
+		"\n"
+		"void InterferenceFunctionRadialParaCrystal::accept(INodeVisitor *visitor) const final\n"
+		"\n"
+		"Calls the  INodeVisitor's visit method. \n"
+		"\n"
+		""},
+	 { (char *)"InterferenceFunctionRadialParaCrystal_setKappa", _wrap_InterferenceFunctionRadialParaCrystal_setKappa, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionRadialParaCrystal_setKappa(InterferenceFunctionRadialParaCrystal self, double kappa)\n"
+		"\n"
+		"void InterferenceFunctionRadialParaCrystal::setKappa(double kappa)\n"
+		"\n"
+		"Sets size spacing coupling parameter of the Size Spacing Correlation Approximation.\n"
+		"\n"
+		"Parameters:\n"
+		"-----------\n"
+		"\n"
+		"size: \n"
+		"spacing coupling parameter \n"
+		"\n"
+		""},
+	 { (char *)"InterferenceFunctionRadialParaCrystal_kappa", _wrap_InterferenceFunctionRadialParaCrystal_kappa, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionRadialParaCrystal_kappa(InterferenceFunctionRadialParaCrystal self) -> double\n"
+		"\n"
+		"double InterferenceFunctionRadialParaCrystal::kappa() const\n"
+		"\n"
+		""},
+	 { (char *)"InterferenceFunctionRadialParaCrystal_setDomainSize", _wrap_InterferenceFunctionRadialParaCrystal_setDomainSize, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionRadialParaCrystal_setDomainSize(InterferenceFunctionRadialParaCrystal self, double size)\n"
+		"\n"
+		"void InterferenceFunctionRadialParaCrystal::setDomainSize(double size)\n"
+		"\n"
+		"Sets domain size (finite size corrections).\n"
+		"\n"
+		"Parameters:\n"
+		"-----------\n"
+		"\n"
+		"size: \n"
+		"size of coherence domain along the lattice main axis in nanometers \n"
+		"\n"
+		""},
+	 { (char *)"InterferenceFunctionRadialParaCrystal_domainSize", _wrap_InterferenceFunctionRadialParaCrystal_domainSize, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionRadialParaCrystal_domainSize(InterferenceFunctionRadialParaCrystal self) -> double\n"
+		"\n"
+		"double InterferenceFunctionRadialParaCrystal::domainSize() const\n"
+		"\n"
+		""},
+	 { (char *)"InterferenceFunctionRadialParaCrystal_evaluate", _wrap_InterferenceFunctionRadialParaCrystal_evaluate, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionRadialParaCrystal_evaluate(InterferenceFunctionRadialParaCrystal self, kvector_t q) -> double\n"
+		"\n"
+		"double InterferenceFunctionRadialParaCrystal::evaluate(const kvector_t q) const final\n"
+		"\n"
+		"Evaluates the interference function for a given wavevector transfer (only the real x and y components are relevant) \n"
+		"\n"
+		""},
+	 { (char *)"InterferenceFunctionRadialParaCrystal_FTPDF", _wrap_InterferenceFunctionRadialParaCrystal_FTPDF, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionRadialParaCrystal_FTPDF(InterferenceFunctionRadialParaCrystal self, double qpar) -> complex_t\n"
+		"\n"
+		"complex_t InterferenceFunctionRadialParaCrystal::FTPDF(double qpar) const\n"
+		"\n"
+		""},
+	 { (char *)"InterferenceFunctionRadialParaCrystal_setProbabilityDistribution", _wrap_InterferenceFunctionRadialParaCrystal_setProbabilityDistribution, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionRadialParaCrystal_setProbabilityDistribution(InterferenceFunctionRadialParaCrystal self, IFTDistribution1D pdf)\n"
+		"\n"
+		"void InterferenceFunctionRadialParaCrystal::setProbabilityDistribution(const IFTDistribution1D &pdf)\n"
+		"\n"
+		"Sets one-dimensional probability distribution.\n"
+		"\n"
+		"Parameters:\n"
+		"-----------\n"
+		"\n"
+		"pdf: \n"
+		"probability distribution (Fourier transform of probability density) \n"
+		"\n"
+		""},
+	 { (char *)"InterferenceFunctionRadialParaCrystal_peakDistance", _wrap_InterferenceFunctionRadialParaCrystal_peakDistance, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionRadialParaCrystal_peakDistance(InterferenceFunctionRadialParaCrystal self) -> double\n"
+		"\n"
+		"double InterferenceFunctionRadialParaCrystal::peakDistance() const\n"
+		"\n"
+		""},
+	 { (char *)"InterferenceFunctionRadialParaCrystal_dampingLength", _wrap_InterferenceFunctionRadialParaCrystal_dampingLength, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionRadialParaCrystal_dampingLength(InterferenceFunctionRadialParaCrystal self) -> double\n"
+		"\n"
+		"double InterferenceFunctionRadialParaCrystal::dampingLength() const\n"
+		"\n"
+		""},
+	 { (char *)"InterferenceFunctionRadialParaCrystal_getChildren", _wrap_InterferenceFunctionRadialParaCrystal_getChildren, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionRadialParaCrystal_getChildren(InterferenceFunctionRadialParaCrystal self) -> swig_dummy_type_const_inode_vector\n"
+		"\n"
+		"std::vector< const INode * > InterferenceFunctionRadialParaCrystal::getChildren() const override\n"
+		"\n"
+		"Returns a vector of children (const). \n"
+		"\n"
+		""},
+	 { (char *)"InterferenceFunctionRadialParaCrystal_randomSample", _wrap_InterferenceFunctionRadialParaCrystal_randomSample, METH_VARARGS, (char *)"\n"
+		"InterferenceFunctionRadialParaCrystal_randomSample(InterferenceFunctionRadialParaCrystal self) -> double\n"
+		"\n"
+		"double InterferenceFunctionRadialParaCrystal::randomSample() const\n"
+		"\n"
+		""},
+	 { (char *)"delete_InterferenceFunctionRadialParaCrystal", _wrap_delete_InterferenceFunctionRadialParaCrystal, METH_VARARGS, (char *)"delete_InterferenceFunctionRadialParaCrystal(InterferenceFunctionRadialParaCrystal self)"},
+	 { (char *)"InterferenceFunctionRadialParaCrystal_swigregister", InterferenceFunctionRadialParaCrystal_swigregister, METH_VARARGS, NULL},
 	 { (char *)"delete_IPixel", _wrap_delete_IPixel, METH_VARARGS, (char *)"\n"
 		"delete_IPixel(IPixel self)\n"
 		"\n"
@@ -136874,17 +129388,17 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { (char *)"ILatticeOrientation_swigregister", ILatticeOrientation_swigregister, METH_VARARGS, NULL},
 	 { (char *)"new_MillerIndex", _wrap_new_MillerIndex, METH_VARARGS, (char *)"\n"
-		"new_MillerIndex(int h_, int k_, int l_) -> MillerIndex\n"
+		"new_MillerIndex(double h_, double k_, double l_) -> MillerIndex\n"
 		"\n"
-		"MillerIndex::MillerIndex(int h_, int k_, int l_)\n"
+		"MillerIndex::MillerIndex(double h_, double k_, double l_)\n"
 		"\n"
 		""},
-	 { (char *)"MillerIndex_h_set", _wrap_MillerIndex_h_set, METH_VARARGS, (char *)"MillerIndex_h_set(MillerIndex self, int h)"},
-	 { (char *)"MillerIndex_h_get", _wrap_MillerIndex_h_get, METH_VARARGS, (char *)"MillerIndex_h_get(MillerIndex self) -> int"},
-	 { (char *)"MillerIndex_k_set", _wrap_MillerIndex_k_set, METH_VARARGS, (char *)"MillerIndex_k_set(MillerIndex self, int k)"},
-	 { (char *)"MillerIndex_k_get", _wrap_MillerIndex_k_get, METH_VARARGS, (char *)"MillerIndex_k_get(MillerIndex self) -> int"},
-	 { (char *)"MillerIndex_l_set", _wrap_MillerIndex_l_set, METH_VARARGS, (char *)"MillerIndex_l_set(MillerIndex self, int l)"},
-	 { (char *)"MillerIndex_l_get", _wrap_MillerIndex_l_get, METH_VARARGS, (char *)"MillerIndex_l_get(MillerIndex self) -> int"},
+	 { (char *)"MillerIndex_h_set", _wrap_MillerIndex_h_set, METH_VARARGS, (char *)"MillerIndex_h_set(MillerIndex self, double h)"},
+	 { (char *)"MillerIndex_h_get", _wrap_MillerIndex_h_get, METH_VARARGS, (char *)"MillerIndex_h_get(MillerIndex self) -> double"},
+	 { (char *)"MillerIndex_k_set", _wrap_MillerIndex_k_set, METH_VARARGS, (char *)"MillerIndex_k_set(MillerIndex self, double k)"},
+	 { (char *)"MillerIndex_k_get", _wrap_MillerIndex_k_get, METH_VARARGS, (char *)"MillerIndex_k_get(MillerIndex self) -> double"},
+	 { (char *)"MillerIndex_l_set", _wrap_MillerIndex_l_set, METH_VARARGS, (char *)"MillerIndex_l_set(MillerIndex self, double l)"},
+	 { (char *)"MillerIndex_l_get", _wrap_MillerIndex_l_get, METH_VARARGS, (char *)"MillerIndex_l_get(MillerIndex self) -> double"},
 	 { (char *)"delete_MillerIndex", _wrap_delete_MillerIndex, METH_VARARGS, (char *)"delete_MillerIndex(MillerIndex self)"},
 	 { (char *)"MillerIndex_swigregister", MillerIndex_swigregister, METH_VARARGS, NULL},
 	 { (char *)"new_MillerIndexOrientation", _wrap_new_MillerIndexOrientation, METH_VARARGS, (char *)"\n"
@@ -136989,9 +129503,9 @@ static PyMethodDef SwigMethods[] = {
 		"\n"
 		""},
 	 { (char *)"Lattice_getMillerDirection", _wrap_Lattice_getMillerDirection, METH_VARARGS, (char *)"\n"
-		"Lattice_getMillerDirection(Lattice self, int h, int k, int l) -> kvector_t\n"
+		"Lattice_getMillerDirection(Lattice self, double h, double k, double l) -> kvector_t\n"
 		"\n"
-		"kvector_t Lattice::getMillerDirection(int h, int k, int l) const\n"
+		"kvector_t Lattice::getMillerDirection(double h, double k, double l) const\n"
 		"\n"
 		"Returns normalized direction corresponding to the given Miller indices. \n"
 		"\n"
@@ -138601,7 +131115,7 @@ static PyMethodDef SwigMethods[] = {
 		"\n"
 		"Adds parameter to the pool, and returns reference to the input pointer.\n"
 		"\n"
-		"Returning the input pointer allows us to concatenate function calls like pool->addParameter( new  RealParameter(...) ).setLimits(-1,+1).setFixed().setUnit(\"nm\") \n"
+		"Returning the input pointer allows us to concatenate function calls like pool->addParameter( new RealParameter(...) ).setLimits(-1,+1).setFixed().setUnit(\"nm\") \n"
 		"\n"
 		""},
 	 { (char *)"ParameterPool_parameter", _wrap_ParameterPool_parameter, METH_VARARGS, (char *)"\n"
@@ -140062,9 +132576,6 @@ static void *_p_HorizontalLineTo_p_IShape2D(void *x, int *SWIGUNUSEDPARM(newmemo
 static void *_p_RectangleTo_p_IShape2D(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IShape2D *)  ((Rectangle *) x));
 }
-static void *_p_FitParameterTo_p_IFitParameter(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IFitParameter *)  ((FitParameter *) x));
-}
 static void *_p_Simulation2DTo_p_Simulation(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((Simulation *)  ((Simulation2D *) x));
 }
@@ -140128,6 +132639,9 @@ static void *_p_FormFactorPolygonalSurfaceTo_p_IFormFactorBorn(void *x, int *SWI
 static void *_p_FormFactorRipple2To_p_IFormFactorBorn(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IFormFactorBorn *)  ((FormFactorRipple2 *) x));
 }
+static void *_p_FormFactorLongBoxTo_p_IFormFactorBorn(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IFormFactorBorn *)  ((FormFactorLongBox *) x));
+}
 static void *_p_FormFactorFullSphereTo_p_IFormFactorBorn(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IFormFactorBorn *)  ((FormFactorFullSphere *) x));
 }
@@ -140191,9 +132705,6 @@ static void *_p_FormFactorLongRipple1LorentzTo_p_IFormFactorBorn(void *x, int *S
 static void *_p_FormFactorLongBoxLorentzTo_p_IFormFactorBorn(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IFormFactorBorn *)  ((FormFactorLongBoxLorentz *) x));
 }
-static void *_p_FormFactorSphereUniformRadiusTo_p_IFormFactorBorn(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IFormFactorBorn *)  ((FormFactorSphereUniformRadius *) x));
-}
 static void *_p_FormFactorPyramidTo_p_IFormFactorBorn(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IFormFactorBorn *) (FormFactorPolyhedron *) ((FormFactorPyramid *) x));
 }
@@ -140203,6 +132714,9 @@ static void *_p_FormFactorAnisoPyramidTo_p_IFormFactorBorn(void *x, int *SWIGUNU
 static void *_p_FormFactorPrism3To_p_IFormFactorBorn(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IFormFactorBorn *) (FormFactorPolygonalPrism *) ((FormFactorPrism3 *) x));
 }
+static void *_p_FormFactorSphereUniformRadiusTo_p_IFormFactorBorn(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IFormFactorBorn *)  ((FormFactorSphereUniformRadius *) x));
+}
 static void *_p_FormFactorLongRipple2GaussTo_p_IFormFactorBorn(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IFormFactorBorn *)  ((FormFactorLongRipple2Gauss *) x));
 }
@@ -140236,9 +132750,6 @@ static void *_p_ParticleLayoutTo_p_ILayout(void *x, int *SWIGUNUSEDPARM(newmemor
 static void *_p_FormFactorDecoratorDebyeWallerTo_p_IFormFactorDecorator(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IFormFactorDecorator *)  ((FormFactorDecoratorDebyeWaller *) x));
 }
-static void *_p_IFitObserverTo_p_IObserver(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IObserver *)  ((IFitObserver *) x));
-}
 static void *_p_RotationYTo_p_IRotation(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IRotation *)  ((RotationY *) x));
 }
@@ -140257,19 +132768,9 @@ static void *_p_RotationXTo_p_IRotation(void *x, int *SWIGUNUSEDPARM(newmemory))
 static void *_p_MillerIndexOrientationTo_p_ILatticeOrientation(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ILatticeOrientation *)  ((MillerIndexOrientation *) x));
 }
-static void *_p_AdjustMinimizerStrategyTo_p_IFitStrategy(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IFitStrategy *)  ((AdjustMinimizerStrategy *) x));
-}
-static void *_p_FitStrategyDefaultTo_p_IFitStrategy(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IFitStrategy *)  ((FitStrategyDefault *) x));
-}
 static void *_p_SimpleSelectionRuleTo_p_ISelectionRule(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ISelectionRule *)  ((SimpleSelectionRule *) x));
 }
-static void *_p_std__shared_ptrT_IFitObserver_tTo_p_std__shared_ptrT_IObserver_t(void *x, int *newmemory) {
-    *newmemory = SWIG_CAST_NEW_MEMORY;
-    return (void *) new std::shared_ptr< IObserver >(*(std::shared_ptr< IFitObserver > *)x);
-}
 static void *_p_RectangularPixelTo_p_IPixel(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IPixel *)  ((RectangularPixel *) x));
 }
@@ -140285,9 +132786,6 @@ static void *_p_Histogram2DTo_p_IHistogram(void *x, int *SWIGUNUSEDPARM(newmemor
 static void *_p_Histogram1DTo_p_IHistogram(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IHistogram *)  ((Histogram1D *) x));
 }
-static void *_p_FitSuiteTo_p_IObservable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IObservable *)  ((FitSuite *) x));
-}
 static void *_p_FormFactorBoxTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ICloneable *) (ISample *)(IFormFactor *)(IFormFactorBorn *) ((FormFactorBox *) x));
 }
@@ -140372,8 +132870,17 @@ static void *_p_RectangularDetectorTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(
 static void *_p_IPeakShapeTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ICloneable *) (ISample *) ((IPeakShape *) x));
 }
-static void *_p_GaussPeakShapeTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ICloneable *) (ISample *)(IPeakShape *) ((GaussPeakShape *) x));
+static void *_p_IsotropicGaussPeakShapeTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *) (ISample *)(IPeakShape *) ((IsotropicGaussPeakShape *) x));
+}
+static void *_p_IsotropicLorentzPeakShapeTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *) (ISample *)(IPeakShape *) ((IsotropicLorentzPeakShape *) x));
+}
+static void *_p_GaussFisherPeakShapeTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *) (ISample *)(IPeakShape *) ((GaussFisherPeakShape *) x));
+}
+static void *_p_LorentzFisherPeakShapeTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *) (ISample *)(IPeakShape *) ((LorentzFisherPeakShape *) x));
 }
 static void *_p_FormFactorPrism3To_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ICloneable *) (ISample *)(IFormFactor *)(IFormFactorBorn *)(FormFactorPolygonalPrism *) ((FormFactorPrism3 *) x));
@@ -140591,6 +133098,9 @@ static void *_p_FTDistribution1DCosineTo_p_ICloneable(void *x, int *SWIGUNUSEDPA
 static void *_p_FTDistribution1DGateTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ICloneable *) (IFTDistribution1D *) ((FTDistribution1DGate *) x));
 }
+static void *_p_FormFactorLongBoxTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *) (ISample *)(IFormFactor *)(IFormFactorBorn *) ((FormFactorLongBox *) x));
+}
 static void *_p_FTDistribution2DVoigtTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ICloneable *) (IFTDistribution2D *) ((FTDistribution2DVoigt *) x));
 }
@@ -140645,12 +133155,12 @@ static void *_p_FormFactorCrystalTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(ne
 static void *_p_CrystalTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ICloneable *) (ISample *)(IClusteredParticles *) ((Crystal *) x));
 }
-static void *_p_InterferenceFunctionRadialParaCrystalTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ICloneable *) (ISample *)(IInterferenceFunction *) ((InterferenceFunctionRadialParaCrystal *) x));
-}
 static void *_p_InterferenceFunction2DParaCrystalTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ICloneable *) (ISample *)(IInterferenceFunction *) ((InterferenceFunction2DParaCrystal *) x));
 }
+static void *_p_InterferenceFunctionRadialParaCrystalTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *) (ISample *)(IInterferenceFunction *) ((InterferenceFunctionRadialParaCrystal *) x));
+}
 static void *_p_MesoCrystalTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ICloneable *) (ISample *)(IAbstractParticle *)(IParticle *) ((MesoCrystal *) x));
 }
@@ -140690,14 +133200,17 @@ static void *_p_InterferenceFunction1DLatticeTo_p_ICloneable(void *x, int *SWIGU
 static void *_p_InterferenceFunction2DLatticeTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ICloneable *) (ISample *)(IInterferenceFunction *) ((InterferenceFunction2DLattice *) x));
 }
+static void *_p_InterferenceFunction2DSuperLatticeTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *) (ISample *)(IInterferenceFunction *) ((InterferenceFunction2DSuperLattice *) x));
+}
 static void *_p_InterferenceFunction3DLatticeTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ICloneable *) (ISample *)(IInterferenceFunction *) ((InterferenceFunction3DLattice *) x));
 }
 static void *_p_InterferenceFunctionFinite2DLatticeTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ICloneable *) (ISample *)(IInterferenceFunction *) ((InterferenceFunctionFinite2DLattice *) x));
 }
-static void *_p_InterferenceFunction2DSuperLatticeTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ICloneable *) (ISample *)(IInterferenceFunction *) ((InterferenceFunction2DSuperLattice *) x));
+static void *_p_InterferenceFunctionFinite3DLatticeTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *) (ISample *)(IInterferenceFunction *) ((InterferenceFunctionFinite3DLattice *) x));
 }
 static void *_p_BasicLatticeTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ICloneable *) (Lattice2D *) ((BasicLattice *) x));
@@ -140747,12 +133260,12 @@ static void *_p_ParticleDistributionTo_p_INamed(void *x, int *SWIGUNUSEDPARM(new
 static void *_p_IParameterT_double_tTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *)  ((IParameter< double > *) x));
 }
-static void *_p_FTDistribution1DGaussTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INamed *) (IParameterized *)(INode *)(IFTDistribution1D *) ((FTDistribution1DGauss *) x));
-}
 static void *_p_FTDecayFunction1DGaussTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(IFTDecayFunction1D *) ((FTDecayFunction1DGauss *) x));
 }
+static void *_p_FTDistribution1DGaussTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INamed *) (IParameterized *)(INode *)(IFTDistribution1D *) ((FTDistribution1DGauss *) x));
+}
 static void *_p_IDetector2DTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(IDetector *) ((IDetector2D *) x));
 }
@@ -140804,8 +133317,17 @@ static void *_p_RectangularDetectorTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newm
 static void *_p_IPeakShapeTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(ISample *) ((IPeakShape *) x));
 }
-static void *_p_GaussPeakShapeTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IPeakShape *) ((GaussPeakShape *) x));
+static void *_p_IsotropicGaussPeakShapeTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IPeakShape *) ((IsotropicGaussPeakShape *) x));
+}
+static void *_p_IsotropicLorentzPeakShapeTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IPeakShape *) ((IsotropicLorentzPeakShape *) x));
+}
+static void *_p_GaussFisherPeakShapeTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IPeakShape *) ((GaussFisherPeakShape *) x));
+}
+static void *_p_LorentzFisherPeakShapeTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IPeakShape *) ((LorentzFisherPeakShape *) x));
 }
 static void *_p_FormFactorPrism3To_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IFormFactor *)(IFormFactorBorn *)(FormFactorPolygonalPrism *) ((FormFactorPrism3 *) x));
@@ -140876,9 +133398,6 @@ static void *_p_FormFactorLongBoxGaussTo_p_INamed(void *x, int *SWIGUNUSEDPARM(n
 static void *_p_FormFactorPolygonalPrismTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IFormFactor *)(IFormFactorBorn *) ((FormFactorPolygonalPrism *) x));
 }
-static void *_p_FitSuiteObjectsTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INamed *) (IParameterized *)(INode *) ((FitSuiteObjects *) x));
-}
 static void *_p_FTDistribution2DGateTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(IFTDistribution2D *) ((FTDistribution2DGate *) x));
 }
@@ -140924,9 +133443,6 @@ static void *_p_FormFactorTruncatedCubeTo_p_INamed(void *x, int *SWIGUNUSEDPARM(
 static void *_p_RotationYTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IRotation *) ((RotationY *) x));
 }
-static void *_p_FitStrategyDefaultTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INamed *) (IFitStrategy *) ((FitStrategyDefault *) x));
-}
 static void *_p_RotationZTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IRotation *) ((RotationZ *) x));
 }
@@ -141029,15 +133545,18 @@ static void *_p_ParticleCompositionTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newm
 static void *_p_FormFactorSphereUniformRadiusTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IFormFactor *)(IFormFactorBorn *) ((FormFactorSphereUniformRadius *) x));
 }
-static void *_p_FTDistribution1DCosineTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INamed *) (IParameterized *)(INode *)(IFTDistribution1D *) ((FTDistribution1DCosine *) x));
-}
 static void *_p_DistributionCosineTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(IDistribution1D *) ((DistributionCosine *) x));
 }
+static void *_p_FTDistribution1DCosineTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INamed *) (IParameterized *)(INode *)(IFTDistribution1D *) ((FTDistribution1DCosine *) x));
+}
 static void *_p_FTDistribution1DGateTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(IFTDistribution1D *) ((FTDistribution1DGate *) x));
 }
+static void *_p_FormFactorLongBoxTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IFormFactor *)(IFormFactorBorn *) ((FormFactorLongBox *) x));
+}
 static void *_p_FTDistribution2DVoigtTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(IFTDistribution2D *) ((FTDistribution2DVoigt *) x));
 }
@@ -141047,36 +133566,27 @@ static void *_p_FTDecayFunction2DVoigtTo_p_INamed(void *x, int *SWIGUNUSEDPARM(n
 static void *_p_FTDistribution2DCauchyTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(IFTDistribution2D *) ((FTDistribution2DCauchy *) x));
 }
-static void *_p_FTDistribution1DCauchyTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INamed *) (IParameterized *)(INode *)(IFTDistribution1D *) ((FTDistribution1DCauchy *) x));
-}
 static void *_p_FTDecayFunction1DCauchyTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(IFTDecayFunction1D *) ((FTDecayFunction1DCauchy *) x));
 }
 static void *_p_FTDecayFunction2DCauchyTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(IFTDecayFunction2D *) ((FTDecayFunction2DCauchy *) x));
 }
+static void *_p_FTDistribution1DCauchyTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INamed *) (IParameterized *)(INode *)(IFTDistribution1D *) ((FTDistribution1DCauchy *) x));
+}
 static void *_p_IInterferenceFunctionTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(ISample *) ((IInterferenceFunction *) x));
 }
 static void *_p_FootprintFactorSquareTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(IFootprintFactor *) ((FootprintFactorSquare *) x));
 }
-static void *_p_FitObjectTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INamed *) (IParameterized *)(INode *) ((FitObject *) x));
-}
 static void *_p_FormFactorCone6To_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IFormFactor *)(IFormFactorBorn *)(FormFactorPolyhedron *) ((FormFactorCone6 *) x));
 }
 static void *_p_FormFactorLongRipple1GaussTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IFormFactor *)(IFormFactorBorn *) ((FormFactorLongRipple1Gauss *) x));
 }
-static void *_p_AdjustMinimizerStrategyTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INamed *) (IFitStrategy *) ((AdjustMinimizerStrategy *) x));
-}
-static void *_p_IFitStrategyTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INamed *)  ((IFitStrategy *) x));
-}
 static void *_p_IFormFactorDecoratorTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IFormFactor *) ((IFormFactorDecorator *) x));
 }
@@ -141098,12 +133608,12 @@ static void *_p_FormFactorCrystalTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmem
 static void *_p_CrystalTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IClusteredParticles *) ((Crystal *) x));
 }
-static void *_p_InterferenceFunctionRadialParaCrystalTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IInterferenceFunction *) ((InterferenceFunctionRadialParaCrystal *) x));
-}
 static void *_p_InterferenceFunction2DParaCrystalTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IInterferenceFunction *) ((InterferenceFunction2DParaCrystal *) x));
 }
+static void *_p_InterferenceFunctionRadialParaCrystalTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IInterferenceFunction *) ((InterferenceFunctionRadialParaCrystal *) x));
+}
 static void *_p_MesoCrystalTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IAbstractParticle *)(IParticle *) ((MesoCrystal *) x));
 }
@@ -141125,6 +133635,12 @@ static void *_p_FormFactorWeightedTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newme
 static void *_p_RealParameterTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameter< double > *) ((RealParameter *) x));
 }
+static void *_p_FormFactorLorentzTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IFormFactor *)(IFormFactorBorn *) ((FormFactorLorentz *) x));
+}
+static void *_p_FormFactorLongRipple2LorentzTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IFormFactor *)(IFormFactorBorn *) ((FormFactorLongRipple2Lorentz *) x));
+}
 static void *_p_FormFactorLongRipple1LorentzTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IFormFactor *)(IFormFactorBorn *) ((FormFactorLongRipple1Lorentz *) x));
 }
@@ -141134,26 +133650,23 @@ static void *_p_FormFactorLongBoxLorentzTo_p_INamed(void *x, int *SWIGUNUSEDPARM
 static void *_p_DistributionLorentzTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(IDistribution1D *) ((DistributionLorentz *) x));
 }
-static void *_p_FormFactorLongRipple2LorentzTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IFormFactor *)(IFormFactorBorn *) ((FormFactorLongRipple2Lorentz *) x));
-}
-static void *_p_FormFactorLorentzTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IFormFactor *)(IFormFactorBorn *) ((FormFactorLorentz *) x));
-}
 static void *_p_InterferenceFunction1DLatticeTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IInterferenceFunction *) ((InterferenceFunction1DLattice *) x));
 }
 static void *_p_InterferenceFunction2DLatticeTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IInterferenceFunction *) ((InterferenceFunction2DLattice *) x));
 }
+static void *_p_InterferenceFunction2DSuperLatticeTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IInterferenceFunction *) ((InterferenceFunction2DSuperLattice *) x));
+}
 static void *_p_InterferenceFunction3DLatticeTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IInterferenceFunction *) ((InterferenceFunction3DLattice *) x));
 }
 static void *_p_InterferenceFunctionFinite2DLatticeTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IInterferenceFunction *) ((InterferenceFunctionFinite2DLattice *) x));
 }
-static void *_p_InterferenceFunction2DSuperLatticeTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IInterferenceFunction *) ((InterferenceFunction2DSuperLattice *) x));
+static void *_p_InterferenceFunctionFinite3DLatticeTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IInterferenceFunction *) ((InterferenceFunctionFinite3DLattice *) x));
 }
 static void *_p_LatticeTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *) ((Lattice *) x));
@@ -141167,12 +133680,12 @@ static void *_p_SquareLatticeTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)
 static void *_p_HexagonalLatticeTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(Lattice2D *) ((HexagonalLattice *) x));
 }
-static void *_p_FTDistribution1DTriangleTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INamed *) (IParameterized *)(INode *)(IFTDistribution1D *) ((FTDistribution1DTriangle *) x));
-}
 static void *_p_FTDecayFunction1DTriangleTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(IFTDecayFunction1D *) ((FTDecayFunction1DTriangle *) x));
 }
+static void *_p_FTDistribution1DTriangleTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INamed *) (IParameterized *)(INode *)(IFTDistribution1D *) ((FTDistribution1DTriangle *) x));
+}
 static void *_p_RotationEulerTo_p_INamed(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INamed *) (IParameterized *)(INode *)(ISample *)(IRotation *) ((RotationEuler *) x));
 }
@@ -141182,38 +133695,32 @@ static void *_p_InterferenceFunction1DLatticeTo_p_IInterferenceFunction(void *x,
 static void *_p_InterferenceFunction2DLatticeTo_p_IInterferenceFunction(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IInterferenceFunction *)  ((InterferenceFunction2DLattice *) x));
 }
+static void *_p_InterferenceFunction2DSuperLatticeTo_p_IInterferenceFunction(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IInterferenceFunction *)  ((InterferenceFunction2DSuperLattice *) x));
+}
 static void *_p_InterferenceFunction3DLatticeTo_p_IInterferenceFunction(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IInterferenceFunction *)  ((InterferenceFunction3DLattice *) x));
 }
 static void *_p_InterferenceFunctionFinite2DLatticeTo_p_IInterferenceFunction(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IInterferenceFunction *)  ((InterferenceFunctionFinite2DLattice *) x));
 }
-static void *_p_InterferenceFunction2DSuperLatticeTo_p_IInterferenceFunction(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IInterferenceFunction *)  ((InterferenceFunction2DSuperLattice *) x));
+static void *_p_InterferenceFunctionFinite3DLatticeTo_p_IInterferenceFunction(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IInterferenceFunction *)  ((InterferenceFunctionFinite3DLattice *) x));
 }
 static void *_p_InterferenceFunctionNoneTo_p_IInterferenceFunction(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IInterferenceFunction *)  ((InterferenceFunctionNone *) x));
 }
-static void *_p_InterferenceFunctionRadialParaCrystalTo_p_IInterferenceFunction(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IInterferenceFunction *)  ((InterferenceFunctionRadialParaCrystal *) x));
-}
 static void *_p_InterferenceFunction2DParaCrystalTo_p_IInterferenceFunction(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IInterferenceFunction *)  ((InterferenceFunction2DParaCrystal *) x));
 }
-static void *_p_SquaredFunctionGaussianErrorTo_p_ISquaredFunction(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ISquaredFunction *)  ((SquaredFunctionGaussianError *) x));
-}
-static void *_p_SquaredFunctionMeanSquaredErrorTo_p_ISquaredFunction(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ISquaredFunction *)  ((SquaredFunctionMeanSquaredError *) x));
-}
-static void *_p_SquaredFunctionDefaultTo_p_ISquaredFunction(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ISquaredFunction *)  ((SquaredFunctionDefault *) x));
+static void *_p_InterferenceFunctionRadialParaCrystalTo_p_IInterferenceFunction(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IInterferenceFunction *)  ((InterferenceFunctionRadialParaCrystal *) x));
 }
-static void *_p_SquaredFunctionSimErrorTo_p_ISquaredFunction(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ISquaredFunction *)  ((SquaredFunctionSimError *) x));
+static void *_p_VarianceConstantFunctionTo_p_IVarianceFunction(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IVarianceFunction *)  ((VarianceConstantFunction *) x));
 }
-static void *_p_SquaredFunctionSystematicErrorTo_p_ISquaredFunction(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ISquaredFunction *)  ((SquaredFunctionSystematicError *) x));
+static void *_p_VarianceSimFunctionTo_p_IVarianceFunction(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IVarianceFunction *)  ((VarianceSimFunction *) x));
 }
 static void *_p_IntensityFunctionSqrtTo_p_IIntensityFunction(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IIntensityFunction *)  ((IntensityFunctionSqrt *) x));
@@ -141305,8 +133812,17 @@ static void *_p_RectangularDetectorTo_p_IParameterized(void *x, int *SWIGUNUSEDP
 static void *_p_IPeakShapeTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IParameterized *) (INode *)(ISample *) ((IPeakShape *) x));
 }
-static void *_p_GaussPeakShapeTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IParameterized *) (INode *)(ISample *)(IPeakShape *) ((GaussPeakShape *) x));
+static void *_p_IsotropicGaussPeakShapeTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IParameterized *) (INode *)(ISample *)(IPeakShape *) ((IsotropicGaussPeakShape *) x));
+}
+static void *_p_IsotropicLorentzPeakShapeTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IParameterized *) (INode *)(ISample *)(IPeakShape *) ((IsotropicLorentzPeakShape *) x));
+}
+static void *_p_GaussFisherPeakShapeTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IParameterized *) (INode *)(ISample *)(IPeakShape *) ((GaussFisherPeakShape *) x));
+}
+static void *_p_LorentzFisherPeakShapeTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IParameterized *) (INode *)(ISample *)(IPeakShape *) ((LorentzFisherPeakShape *) x));
 }
 static void *_p_FormFactorPrism3To_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IParameterized *) (INode *)(ISample *)(IFormFactor *)(IFormFactorBorn *)(FormFactorPolygonalPrism *) ((FormFactorPrism3 *) x));
@@ -141377,9 +133893,6 @@ static void *_p_FormFactorLongBoxGaussTo_p_IParameterized(void *x, int *SWIGUNUS
 static void *_p_FormFactorPolygonalPrismTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IParameterized *) (INode *)(ISample *)(IFormFactor *)(IFormFactorBorn *) ((FormFactorPolygonalPrism *) x));
 }
-static void *_p_FitSuiteObjectsTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IParameterized *) (INode *) ((FitSuiteObjects *) x));
-}
 static void *_p_FTDistribution2DGateTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IParameterized *) (INode *)(IFTDistribution2D *) ((FTDistribution2DGate *) x));
 }
@@ -141524,15 +134037,15 @@ static void *_p_FTDistribution1DCosineTo_p_IParameterized(void *x, int *SWIGUNUS
 static void *_p_FTDistribution1DGateTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IParameterized *) (INode *)(IFTDistribution1D *) ((FTDistribution1DGate *) x));
 }
+static void *_p_FormFactorLongBoxTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IParameterized *) (INode *)(ISample *)(IFormFactor *)(IFormFactorBorn *) ((FormFactorLongBox *) x));
+}
 static void *_p_FTDistribution2DVoigtTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IParameterized *) (INode *)(IFTDistribution2D *) ((FTDistribution2DVoigt *) x));
 }
 static void *_p_FTDecayFunction2DVoigtTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IParameterized *) (INode *)(IFTDecayFunction2D *) ((FTDecayFunction2DVoigt *) x));
 }
-static void *_p_FTDistribution2DCauchyTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IParameterized *) (INode *)(IFTDistribution2D *) ((FTDistribution2DCauchy *) x));
-}
 static void *_p_FTDecayFunction1DCauchyTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IParameterized *) (INode *)(IFTDecayFunction1D *) ((FTDecayFunction1DCauchy *) x));
 }
@@ -141542,15 +134055,15 @@ static void *_p_FTDecayFunction2DCauchyTo_p_IParameterized(void *x, int *SWIGUNU
 static void *_p_FTDistribution1DCauchyTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IParameterized *) (INode *)(IFTDistribution1D *) ((FTDistribution1DCauchy *) x));
 }
+static void *_p_FTDistribution2DCauchyTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IParameterized *) (INode *)(IFTDistribution2D *) ((FTDistribution2DCauchy *) x));
+}
 static void *_p_IInterferenceFunctionTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IParameterized *) (INode *)(ISample *) ((IInterferenceFunction *) x));
 }
 static void *_p_FootprintFactorSquareTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IParameterized *) (INode *)(IFootprintFactor *) ((FootprintFactorSquare *) x));
 }
-static void *_p_FitObjectTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IParameterized *) (INode *) ((FitObject *) x));
-}
 static void *_p_FormFactorCone6To_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IParameterized *) (INode *)(ISample *)(IFormFactor *)(IFormFactorBorn *)(FormFactorPolyhedron *) ((FormFactorCone6 *) x));
 }
@@ -141575,21 +134088,21 @@ static void *_p_FormFactorCrystalTo_p_IParameterized(void *x, int *SWIGUNUSEDPAR
 static void *_p_CrystalTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IParameterized *) (INode *)(ISample *)(IClusteredParticles *) ((Crystal *) x));
 }
-static void *_p_InterferenceFunctionRadialParaCrystalTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IParameterized *) (INode *)(ISample *)(IInterferenceFunction *) ((InterferenceFunctionRadialParaCrystal *) x));
-}
 static void *_p_InterferenceFunction2DParaCrystalTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IParameterized *) (INode *)(ISample *)(IInterferenceFunction *) ((InterferenceFunction2DParaCrystal *) x));
 }
+static void *_p_InterferenceFunctionRadialParaCrystalTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IParameterized *) (INode *)(ISample *)(IInterferenceFunction *) ((InterferenceFunctionRadialParaCrystal *) x));
+}
 static void *_p_MesoCrystalTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IParameterized *) (INode *)(ISample *)(IAbstractParticle *)(IParticle *) ((MesoCrystal *) x));
 }
-static void *_p_IFTDistribution2DTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IParameterized *) (INode *) ((IFTDistribution2D *) x));
-}
 static void *_p_IFTDecayFunction2DTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IParameterized *) (INode *) ((IFTDecayFunction2D *) x));
 }
+static void *_p_IFTDistribution2DTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IParameterized *) (INode *) ((IFTDistribution2D *) x));
+}
 static void *_p_Simulation2DTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IParameterized *) (INode *)(Simulation *) ((Simulation2D *) x));
 }
@@ -141620,14 +134133,17 @@ static void *_p_InterferenceFunction1DLatticeTo_p_IParameterized(void *x, int *S
 static void *_p_InterferenceFunction2DLatticeTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IParameterized *) (INode *)(ISample *)(IInterferenceFunction *) ((InterferenceFunction2DLattice *) x));
 }
+static void *_p_InterferenceFunction2DSuperLatticeTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IParameterized *) (INode *)(ISample *)(IInterferenceFunction *) ((InterferenceFunction2DSuperLattice *) x));
+}
 static void *_p_InterferenceFunction3DLatticeTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IParameterized *) (INode *)(ISample *)(IInterferenceFunction *) ((InterferenceFunction3DLattice *) x));
 }
 static void *_p_InterferenceFunctionFinite2DLatticeTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IParameterized *) (INode *)(ISample *)(IInterferenceFunction *) ((InterferenceFunctionFinite2DLattice *) x));
 }
-static void *_p_InterferenceFunction2DSuperLatticeTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IParameterized *) (INode *)(ISample *)(IInterferenceFunction *) ((InterferenceFunction2DSuperLattice *) x));
+static void *_p_InterferenceFunctionFinite3DLatticeTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IParameterized *) (INode *)(ISample *)(IInterferenceFunction *) ((InterferenceFunctionFinite3DLattice *) x));
 }
 static void *_p_LatticeTo_p_IParameterized(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IParameterized *) (INode *) ((Lattice *) x));
@@ -141680,18 +134196,21 @@ static void *_p_FormFactorLongBoxGaussTo_p_IFormFactor(void *x, int *SWIGUNUSEDP
 static void *_p_FormFactorOrnsteinZernikeTo_p_IFormFactor(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IFormFactor *) (IFormFactorBorn *) ((FormFactorOrnsteinZernike *) x));
 }
-static void *_p_FormFactorRipple1To_p_IFormFactor(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IFormFactor *) (IFormFactorBorn *) ((FormFactorRipple1 *) x));
-}
 static void *_p_FormFactorPolygonalSurfaceTo_p_IFormFactor(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IFormFactor *) (IFormFactorBorn *) ((FormFactorPolygonalSurface *) x));
 }
 static void *_p_FormFactorCrystalTo_p_IFormFactor(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IFormFactor *)  ((FormFactorCrystal *) x));
 }
+static void *_p_FormFactorRipple1To_p_IFormFactor(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IFormFactor *) (IFormFactorBorn *) ((FormFactorRipple1 *) x));
+}
 static void *_p_FormFactorRipple2To_p_IFormFactor(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IFormFactor *) (IFormFactorBorn *) ((FormFactorRipple2 *) x));
 }
+static void *_p_FormFactorLongBoxTo_p_IFormFactor(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IFormFactor *) (IFormFactorBorn *) ((FormFactorLongBox *) x));
+}
 static void *_p_FormFactorFullSphereTo_p_IFormFactor(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IFormFactor *) (IFormFactorBorn *) ((FormFactorFullSphere *) x));
 }
@@ -141815,8 +134334,17 @@ static void *_p_FormFactorHemiEllipsoidTo_p_ISample(void *x, int *SWIGUNUSEDPARM
 static void *_p_ParticleLayoutTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ISample *) (ILayout *) ((ParticleLayout *) x));
 }
-static void *_p_GaussPeakShapeTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ISample *) (IPeakShape *) ((GaussPeakShape *) x));
+static void *_p_LorentzFisherPeakShapeTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ISample *) (IPeakShape *) ((LorentzFisherPeakShape *) x));
+}
+static void *_p_GaussFisherPeakShapeTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ISample *) (IPeakShape *) ((GaussFisherPeakShape *) x));
+}
+static void *_p_IsotropicLorentzPeakShapeTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ISample *) (IPeakShape *) ((IsotropicLorentzPeakShape *) x));
+}
+static void *_p_IsotropicGaussPeakShapeTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ISample *) (IPeakShape *) ((IsotropicGaussPeakShape *) x));
 }
 static void *_p_IPeakShapeTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ISample *)  ((IPeakShape *) x));
@@ -141902,15 +134430,15 @@ static void *_p_IFormFactorBornTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemo
 static void *_p_IClusteredParticlesTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ISample *)  ((IClusteredParticles *) x));
 }
-static void *_p_ParticleTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ISample *) (IAbstractParticle *)(IParticle *) ((Particle *) x));
-}
 static void *_p_IParticleTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ISample *) (IAbstractParticle *) ((IParticle *) x));
 }
 static void *_p_IAbstractParticleTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ISample *)  ((IAbstractParticle *) x));
 }
+static void *_p_ParticleTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ISample *) (IAbstractParticle *)(IParticle *) ((Particle *) x));
+}
 static void *_p_FormFactorConeTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ISample *) (IFormFactor *)(IFormFactorBorn *) ((FormFactorCone *) x));
 }
@@ -141944,6 +134472,9 @@ static void *_p_ParticleCompositionTo_p_ISample(void *x, int *SWIGUNUSEDPARM(new
 static void *_p_FormFactorSphereUniformRadiusTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ISample *) (IFormFactor *)(IFormFactorBorn *) ((FormFactorSphereUniformRadius *) x));
 }
+static void *_p_FormFactorLongBoxTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ISample *) (IFormFactor *)(IFormFactorBorn *) ((FormFactorLongBox *) x));
+}
 static void *_p_IInterferenceFunctionTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ISample *)  ((IInterferenceFunction *) x));
 }
@@ -141968,12 +134499,12 @@ static void *_p_LayerRoughnessTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemor
 static void *_p_MesoCrystalTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ISample *) (IAbstractParticle *)(IParticle *) ((MesoCrystal *) x));
 }
-static void *_p_InterferenceFunction2DParaCrystalTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ISample *) (IInterferenceFunction *) ((InterferenceFunction2DParaCrystal *) x));
-}
 static void *_p_InterferenceFunctionRadialParaCrystalTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ISample *) (IInterferenceFunction *) ((InterferenceFunctionRadialParaCrystal *) x));
 }
+static void *_p_InterferenceFunction2DParaCrystalTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ISample *) (IInterferenceFunction *) ((InterferenceFunction2DParaCrystal *) x));
+}
 static void *_p_FormFactorCrystalTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ISample *) (IFormFactor *) ((FormFactorCrystal *) x));
 }
@@ -141995,8 +134526,8 @@ static void *_p_FormFactorLongRipple2LorentzTo_p_ISample(void *x, int *SWIGUNUSE
 static void *_p_FormFactorLorentzTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ISample *) (IFormFactor *)(IFormFactorBorn *) ((FormFactorLorentz *) x));
 }
-static void *_p_InterferenceFunction2DSuperLatticeTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ISample *) (IInterferenceFunction *) ((InterferenceFunction2DSuperLattice *) x));
+static void *_p_InterferenceFunctionFinite3DLatticeTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ISample *) (IInterferenceFunction *) ((InterferenceFunctionFinite3DLattice *) x));
 }
 static void *_p_InterferenceFunctionFinite2DLatticeTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ISample *) (IInterferenceFunction *) ((InterferenceFunctionFinite2DLattice *) x));
@@ -142004,6 +134535,9 @@ static void *_p_InterferenceFunctionFinite2DLatticeTo_p_ISample(void *x, int *SW
 static void *_p_InterferenceFunction3DLatticeTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ISample *) (IInterferenceFunction *) ((InterferenceFunction3DLattice *) x));
 }
+static void *_p_InterferenceFunction2DSuperLatticeTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ISample *) (IInterferenceFunction *) ((InterferenceFunction2DSuperLattice *) x));
+}
 static void *_p_InterferenceFunction2DLatticeTo_p_ISample(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ISample *) (IInterferenceFunction *) ((InterferenceFunction2DLattice *) x));
 }
@@ -142082,8 +134616,17 @@ static void *_p_RectangularDetectorTo_p_INode(void *x, int *SWIGUNUSEDPARM(newme
 static void *_p_IPeakShapeTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INode *) (ISample *) ((IPeakShape *) x));
 }
-static void *_p_GaussPeakShapeTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INode *) (ISample *)(IPeakShape *) ((GaussPeakShape *) x));
+static void *_p_IsotropicGaussPeakShapeTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INode *) (ISample *)(IPeakShape *) ((IsotropicGaussPeakShape *) x));
+}
+static void *_p_IsotropicLorentzPeakShapeTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INode *) (ISample *)(IPeakShape *) ((IsotropicLorentzPeakShape *) x));
+}
+static void *_p_GaussFisherPeakShapeTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INode *) (ISample *)(IPeakShape *) ((GaussFisherPeakShape *) x));
+}
+static void *_p_LorentzFisherPeakShapeTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INode *) (ISample *)(IPeakShape *) ((LorentzFisherPeakShape *) x));
 }
 static void *_p_FormFactorPrism3To_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INode *) (ISample *)(IFormFactor *)(IFormFactorBorn *)(FormFactorPolygonalPrism *) ((FormFactorPrism3 *) x));
@@ -142154,9 +134697,6 @@ static void *_p_FormFactorLongBoxGaussTo_p_INode(void *x, int *SWIGUNUSEDPARM(ne
 static void *_p_FormFactorPolygonalPrismTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INode *) (ISample *)(IFormFactor *)(IFormFactorBorn *) ((FormFactorPolygonalPrism *) x));
 }
-static void *_p_FitSuiteObjectsTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INode *)  ((FitSuiteObjects *) x));
-}
 static void *_p_FTDistribution2DGateTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INode *) (IFTDistribution2D *) ((FTDistribution2DGate *) x));
 }
@@ -142187,12 +134727,12 @@ static void *_p_FormFactorTruncatedSpheroidTo_p_INode(void *x, int *SWIGUNUSEDPA
 static void *_p_RotationXTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INode *) (ISample *)(IRotation *) ((RotationX *) x));
 }
-static void *_p_FTDistribution2DGaussTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INode *) (IFTDistribution2D *) ((FTDistribution2DGauss *) x));
-}
 static void *_p_FTDecayFunction2DGaussTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INode *) (IFTDecayFunction2D *) ((FTDecayFunction2DGauss *) x));
 }
+static void *_p_FTDistribution2DGaussTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INode *) (IFTDistribution2D *) ((FTDistribution2DGauss *) x));
+}
 static void *_p_FormFactorTruncatedCubeTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INode *) (ISample *)(IFormFactor *)(IFormFactorBorn *)(FormFactorPolyhedron *) ((FormFactorTruncatedCube *) x));
 }
@@ -142298,6 +134838,9 @@ static void *_p_FTDistribution1DCosineTo_p_INode(void *x, int *SWIGUNUSEDPARM(ne
 static void *_p_FTDistribution1DGateTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INode *) (IFTDistribution1D *) ((FTDistribution1DGate *) x));
 }
+static void *_p_FormFactorLongBoxTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INode *) (ISample *)(IFormFactor *)(IFormFactorBorn *) ((FormFactorLongBox *) x));
+}
 static void *_p_FTDistribution2DVoigtTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INode *) (IFTDistribution2D *) ((FTDistribution2DVoigt *) x));
 }
@@ -142322,9 +134865,6 @@ static void *_p_IInterferenceFunctionTo_p_INode(void *x, int *SWIGUNUSEDPARM(new
 static void *_p_FootprintFactorSquareTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INode *) (IFootprintFactor *) ((FootprintFactorSquare *) x));
 }
-static void *_p_FitObjectTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INode *)  ((FitObject *) x));
-}
 static void *_p_FormFactorCone6To_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INode *) (ISample *)(IFormFactor *)(IFormFactorBorn *)(FormFactorPolyhedron *) ((FormFactorCone6 *) x));
 }
@@ -142349,12 +134889,12 @@ static void *_p_FormFactorCrystalTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemo
 static void *_p_CrystalTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INode *) (ISample *)(IClusteredParticles *) ((Crystal *) x));
 }
-static void *_p_InterferenceFunctionRadialParaCrystalTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INode *) (ISample *)(IInterferenceFunction *) ((InterferenceFunctionRadialParaCrystal *) x));
-}
 static void *_p_InterferenceFunction2DParaCrystalTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INode *) (ISample *)(IInterferenceFunction *) ((InterferenceFunction2DParaCrystal *) x));
 }
+static void *_p_InterferenceFunctionRadialParaCrystalTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INode *) (ISample *)(IInterferenceFunction *) ((InterferenceFunctionRadialParaCrystal *) x));
+}
 static void *_p_MesoCrystalTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INode *) (ISample *)(IAbstractParticle *)(IParticle *) ((MesoCrystal *) x));
 }
@@ -142394,14 +134934,17 @@ static void *_p_InterferenceFunction1DLatticeTo_p_INode(void *x, int *SWIGUNUSED
 static void *_p_InterferenceFunction2DLatticeTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INode *) (ISample *)(IInterferenceFunction *) ((InterferenceFunction2DLattice *) x));
 }
+static void *_p_InterferenceFunction2DSuperLatticeTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INode *) (ISample *)(IInterferenceFunction *) ((InterferenceFunction2DSuperLattice *) x));
+}
 static void *_p_InterferenceFunction3DLatticeTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INode *) (ISample *)(IInterferenceFunction *) ((InterferenceFunction3DLattice *) x));
 }
 static void *_p_InterferenceFunctionFinite2DLatticeTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INode *) (ISample *)(IInterferenceFunction *) ((InterferenceFunctionFinite2DLattice *) x));
 }
-static void *_p_InterferenceFunction2DSuperLatticeTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INode *) (ISample *)(IInterferenceFunction *) ((InterferenceFunction2DSuperLattice *) x));
+static void *_p_InterferenceFunctionFinite3DLatticeTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INode *) (ISample *)(IInterferenceFunction *) ((InterferenceFunctionFinite3DLattice *) x));
 }
 static void *_p_LatticeTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INode *)  ((Lattice *) x));
@@ -142457,8 +135000,17 @@ static void *_p_ParticleCoreShellTo_p_IAbstractParticle(void *x, int *SWIGUNUSED
 static void *_p_RealParameterTo_p_IParameterT_double_t(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IParameter< double > *)  ((RealParameter *) x));
 }
-static void *_p_GaussPeakShapeTo_p_IPeakShape(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IPeakShape *)  ((GaussPeakShape *) x));
+static void *_p_IsotropicGaussPeakShapeTo_p_IPeakShape(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IPeakShape *)  ((IsotropicGaussPeakShape *) x));
+}
+static void *_p_IsotropicLorentzPeakShapeTo_p_IPeakShape(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IPeakShape *)  ((IsotropicLorentzPeakShape *) x));
+}
+static void *_p_GaussFisherPeakShapeTo_p_IPeakShape(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IPeakShape *)  ((GaussFisherPeakShape *) x));
+}
+static void *_p_LorentzFisherPeakShapeTo_p_IPeakShape(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IPeakShape *)  ((LorentzFisherPeakShape *) x));
 }
 static void *_p_ConstantBackgroundTo_p_IBackground(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IBackground *)  ((ConstantBackground *) x));
@@ -142583,8 +135135,6 @@ static void *_p_GISASSimulationTo_p_Simulation2D(void *x, int *SWIGUNUSEDPARM(ne
 static void *_p_OffSpecSimulationTo_p_Simulation2D(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((Simulation2D *)  ((OffSpecSimulation *) x));
 }
-static swig_type_info _swigt__p_AdjustMinimizerStrategy = {"_p_AdjustMinimizerStrategy", "AdjustMinimizerStrategy *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_AttLimits = {"_p_AttLimits", "AttLimits *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Attributes = {"_p_Attributes", "Attributes *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_AxesUnitsWrap = {"_p_AxesUnitsWrap", "AxesUnitsWrap *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_AxesUnitsWrap__AxesUnits = {"_p_AxesUnitsWrap__AxesUnits", "enum AxesUnitsWrap::AxesUnits *|AxesUnits *", 0, 0, (void*)0, 0};
@@ -142635,17 +135185,8 @@ static swig_type_info _swigt__p_FTDistribution2DCone = {"_p_FTDistribution2DCone
 static swig_type_info _swigt__p_FTDistribution2DGate = {"_p_FTDistribution2DGate", "FTDistribution2DGate *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_FTDistribution2DGauss = {"_p_FTDistribution2DGauss", "FTDistribution2DGauss *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_FTDistribution2DVoigt = {"_p_FTDistribution2DVoigt", "FTDistribution2DVoigt *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_FitObject = {"_p_FitObject", "FitObject *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_FitObjective = {"_p_FitObjective", "FitObjective *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_FitObjects_t = {"_p_FitObjects_t", "FitObjects_t *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_FitOptions = {"_p_FitOptions", "FitOptions *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_FitParameter = {"_p_FitParameter", "FitParameter *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_FitParameterSet = {"_p_FitParameterSet", "FitParameterSet *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_FitStrategyDefault = {"_p_FitStrategyDefault", "FitStrategyDefault *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_FitSuite = {"_p_FitSuite", "FitSuite *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_FitSuiteImpl = {"_p_FitSuiteImpl", "FitSuiteImpl *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_FitSuiteObjects = {"_p_FitSuiteObjects", "FitSuiteObjects *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_FitSuiteStrategies = {"_p_FitSuiteStrategies", "FitSuiteStrategies *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Fit__MinimizerResult = {"_p_Fit__MinimizerResult", "Fit::MinimizerResult *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Fit__Parameters = {"_p_Fit__Parameters", "Fit::Parameters *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_FixedBinAxis = {"_p_FixedBinAxis", "FixedBinAxis *", 0, 0, (void*)0, 0};
@@ -142674,6 +135215,7 @@ static swig_type_info _swigt__p_FormFactorFullSpheroid = {"_p_FormFactorFullSphe
 static swig_type_info _swigt__p_FormFactorGauss = {"_p_FormFactorGauss", "FormFactorGauss *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_FormFactorHemiEllipsoid = {"_p_FormFactorHemiEllipsoid", "FormFactorHemiEllipsoid *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_FormFactorIcosahedron = {"_p_FormFactorIcosahedron", "FormFactorIcosahedron *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_FormFactorLongBox = {"_p_FormFactorLongBox", "FormFactorLongBox *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_FormFactorLongBoxGauss = {"_p_FormFactorLongBoxGauss", "FormFactorLongBoxGauss *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_FormFactorLongBoxLorentz = {"_p_FormFactorLongBoxLorentz", "FormFactorLongBoxLorentz *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_FormFactorLongRipple1Gauss = {"_p_FormFactorLongRipple1Gauss", "FormFactorLongRipple1Gauss *", 0, 0, (void*)0, 0};
@@ -142699,7 +135241,7 @@ static swig_type_info _swigt__p_FormFactorTruncatedSphere = {"_p_FormFactorTrunc
 static swig_type_info _swigt__p_FormFactorTruncatedSpheroid = {"_p_FormFactorTruncatedSpheroid", "FormFactorTruncatedSpheroid *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_FormFactorWeighted = {"_p_FormFactorWeighted", "FormFactorWeighted *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_GISASSimulation = {"_p_GISASSimulation", "GISASSimulation *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_GaussPeakShape = {"_p_GaussPeakShape", "GaussPeakShape *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_GaussFisherPeakShape = {"_p_GaussFisherPeakShape", "GaussFisherPeakShape *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_HexagonalLattice = {"_p_HexagonalLattice", "HexagonalLattice *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Histogram1D = {"_p_Histogram1D", "Histogram1D *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Histogram2D = {"_p_Histogram2D", "Histogram2D *", 0, 0, (void*)0, 0};
@@ -142720,9 +135262,6 @@ static swig_type_info _swigt__p_IFTDistribution1D = {"_p_IFTDistribution1D", "IF
 static swig_type_info _swigt__p_IFTDistribution2D = {"_p_IFTDistribution2D", "IFTDistribution2D *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_IFactoryT_std__string_IMultiLayerBuilder_t = {"_p_IFactoryT_std__string_IMultiLayerBuilder_t", "IFactory< std::string,IMultiLayerBuilder > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_IFactoryT_std__string_Simulation_t = {"_p_IFactoryT_std__string_Simulation_t", "IFactory< std::string,Simulation > *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_IFitObserver = {"_p_IFitObserver", "IFitObserver *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_IFitParameter = {"_p_IFitParameter", "IFitParameter *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_IFitStrategy = {"_p_IFitStrategy", "IFitStrategy *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_IFootprintFactor = {"_p_IFootprintFactor", "IFootprintFactor *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_IFormFactor = {"_p_IFormFactor", "std::vector< IFormFactor * >::value_type|IFormFactor *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_IFormFactorBorn = {"_p_IFormFactorBorn", "IFormFactorBorn *", 0, 0, (void*)0, 0};
@@ -142733,7 +135272,6 @@ static swig_type_info _swigt__p_IIntensityNormalizer = {"_p_IIntensityNormalizer
 static swig_type_info _swigt__p_IInterferenceFunction = {"_p_IInterferenceFunction", "IInterferenceFunction *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_ILatticeOrientation = {"_p_ILatticeOrientation", "ILatticeOrientation *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_ILayout = {"_p_ILayout", "ILayout *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_IMinimizer = {"_p_IMinimizer", "IMinimizer *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_IMultiLayerBuilder = {"_p_IMultiLayerBuilder", "IMultiLayerBuilder *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_INamed = {"_p_INamed", "INamed *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_INode = {"_p_INode", "INode *|std::vector< INode * >::value_type|std::vector< INode const * >::value_type", 0, 0, (void*)0, 0};
@@ -142750,8 +135288,8 @@ static swig_type_info _swigt__p_IRotation = {"_p_IRotation", "IRotation *", 0, 0
 static swig_type_info _swigt__p_ISample = {"_p_ISample", "ISample *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_ISelectionRule = {"_p_ISelectionRule", "ISelectionRule *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_IShape2D = {"_p_IShape2D", "IShape2D *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_ISquaredFunction = {"_p_ISquaredFunction", "ISquaredFunction *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_IUnitConverter = {"_p_IUnitConverter", "IUnitConverter *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_IVarianceFunction = {"_p_IVarianceFunction", "IVarianceFunction *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_IdentityRotation = {"_p_IdentityRotation", "IdentityRotation *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Instrument = {"_p_Instrument", "Instrument *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_IntensityDataIOFactory = {"_p_IntensityDataIOFactory", "IntensityDataIOFactory *", 0, 0, (void*)0, 0};
@@ -142765,9 +135303,12 @@ static swig_type_info _swigt__p_InterferenceFunction2DParaCrystal = {"_p_Interfe
 static swig_type_info _swigt__p_InterferenceFunction2DSuperLattice = {"_p_InterferenceFunction2DSuperLattice", "InterferenceFunction2DSuperLattice *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_InterferenceFunction3DLattice = {"_p_InterferenceFunction3DLattice", "InterferenceFunction3DLattice *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_InterferenceFunctionFinite2DLattice = {"_p_InterferenceFunctionFinite2DLattice", "InterferenceFunctionFinite2DLattice *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_InterferenceFunctionFinite3DLattice = {"_p_InterferenceFunctionFinite3DLattice", "InterferenceFunctionFinite3DLattice *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_InterferenceFunctionNone = {"_p_InterferenceFunctionNone", "InterferenceFunctionNone *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_InterferenceFunctionRadialParaCrystal = {"_p_InterferenceFunctionRadialParaCrystal", "InterferenceFunctionRadialParaCrystal *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_IsGISAXSDetector = {"_p_IsGISAXSDetector", "IsGISAXSDetector *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_IsotropicGaussPeakShape = {"_p_IsotropicGaussPeakShape", "IsotropicGaussPeakShape *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_IsotropicLorentzPeakShape = {"_p_IsotropicLorentzPeakShape", "IsotropicLorentzPeakShape *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_IterationInfo = {"_p_IterationInfo", "IterationInfo *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Lattice = {"_p_Lattice", "Lattice *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Lattice1DParameters = {"_p_Lattice1DParameters", "Lattice1DParameters *", 0, 0, (void*)0, 0};
@@ -142777,6 +135318,7 @@ static swig_type_info _swigt__p_Layer = {"_p_Layer", "Layer *", 0, 0, (void*)0,
 static swig_type_info _swigt__p_LayerInterface = {"_p_LayerInterface", "LayerInterface *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_LayerRoughness = {"_p_LayerRoughness", "LayerRoughness *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Line = {"_p_Line", "Line *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_LorentzFisherPeakShape = {"_p_LorentzFisherPeakShape", "LorentzFisherPeakShape *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Material = {"_p_Material", "Material *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_MesoCrystal = {"_p_MesoCrystal", "MesoCrystal *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_MillerIndex = {"_p_MillerIndex", "MillerIndex *", 0, 0, (void*)0, 0};
@@ -142818,7 +135360,6 @@ static swig_type_info _swigt__p_RotationEuler = {"_p_RotationEuler", "RotationEu
 static swig_type_info _swigt__p_RotationX = {"_p_RotationX", "RotationX *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_RotationY = {"_p_RotationY", "RotationY *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_RotationZ = {"_p_RotationZ", "RotationZ *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_SafePointerVectorT_FitObject_t__iterator = {"_p_SafePointerVectorT_FitObject_t__iterator", "SafePointerVector< FitObject >::iterator *|FitSuiteObjects::iterator *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_SafePointerVectorT_IParticle_t = {"_p_SafePointerVectorT_IParticle_t", "SafePointerVector< IParticle > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_SafePointerVectorT_Layer_t = {"_p_SafePointerVectorT_Layer_t", "SafePointerVector< Layer > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_SampleBuilderFactory = {"_p_SampleBuilderFactory", "SampleBuilderFactory *", 0, 0, (void*)0, 0};
@@ -142835,14 +135376,11 @@ static swig_type_info _swigt__p_SpecularSimulation = {"_p_SpecularSimulation", "
 static swig_type_info _swigt__p_SphericalDetector = {"_p_SphericalDetector", "SphericalDetector *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_SphericalPixel = {"_p_SphericalPixel", "SphericalPixel *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_SquareLattice = {"_p_SquareLattice", "SquareLattice *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_SquaredFunctionDefault = {"_p_SquaredFunctionDefault", "SquaredFunctionDefault *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_SquaredFunctionGaussianError = {"_p_SquaredFunctionGaussianError", "SquaredFunctionGaussianError *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_SquaredFunctionMeanSquaredError = {"_p_SquaredFunctionMeanSquaredError", "SquaredFunctionMeanSquaredError *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_SquaredFunctionSimError = {"_p_SquaredFunctionSimError", "SquaredFunctionSimError *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_SquaredFunctionSystematicError = {"_p_SquaredFunctionSystematicError", "SquaredFunctionSystematicError *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_ThreadInfo = {"_p_ThreadInfo", "ThreadInfo *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Transform3D = {"_p_Transform3D", "Transform3D *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_VariableBinAxis = {"_p_VariableBinAxis", "VariableBinAxis *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_VarianceConstantFunction = {"_p_VarianceConstantFunction", "VarianceConstantFunction *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_VarianceSimFunction = {"_p_VarianceSimFunction", "VarianceSimFunction *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_VerticalLine = {"_p_VerticalLine", "VerticalLine *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_WavevectorInfo = {"_p_WavevectorInfo", "WavevectorInfo *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_ZLimits = {"_p_ZLimits", "ZLimits *", 0, 0, (void*)0, 0};
@@ -142851,7 +135389,6 @@ static swig_type_info _swigt__p_bool = {"_p_bool", "bool *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_const_iterator = {"_p_const_iterator", "const_iterator *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_const_reference = {"_p_const_reference", "const_reference *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_container_t = {"_p_container_t", "container_t *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_corr_matrix_t = {"_p_corr_matrix_t", "corr_matrix_t *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_difference_type = {"_p_difference_type", "difference_type *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_double = {"_p_double", "double *", 0, 0, (void*)0, 0};
@@ -142892,18 +135429,13 @@ static swig_type_info _swigt__p_std__lessT_std__string_t = {"_p_std__lessT_std__
 static swig_type_info _swigt__p_std__mapT_std__string_double_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_double_t_t_t = {"_p_std__mapT_std__string_double_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_double_t_t_t", "std::map< std::string,double,std::less< std::string >,std::allocator< std::pair< std::string const,double > > > *|std::map< std::string,double > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__mapT_std__string_std__string_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_std__string_t_t_t__const_iterator = {"_p_std__mapT_std__string_std__string_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_std__string_t_t_t__const_iterator", "std::map< std::string,std::string,std::less< std::string >,std::allocator< std::pair< std::string const,std::string > > >::const_iterator *|IFactory< std::string,Simulation >::const_iterator *|IFactory< std::string,IMultiLayerBuilder >::const_iterator *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__pairT_double_double_t = {"_p_std__pairT_double_double_t", "std::pair< double,double > *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__shared_ptrT_IFitObserver_t = {"_p_std__shared_ptrT_IFitObserver_t", "std::shared_ptr< IFitObserver > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__shared_ptrT_IMultiLayerBuilder_t = {"_p_std__shared_ptrT_IMultiLayerBuilder_t", "std::shared_ptr< IMultiLayerBuilder > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__shared_ptrT_IObserver_t = {"_p_std__shared_ptrT_IObserver_t", "std::shared_ptr< IObserver > *|IObservable::observer_t *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__vectorT_AxesUnitsWrap__AxesUnits_std__allocatorT_AxesUnitsWrap__AxesUnits_t_t = {"_p_std__vectorT_AxesUnitsWrap__AxesUnits_std__allocatorT_AxesUnitsWrap__AxesUnits_t_t", "std::vector< enum AxesUnitsWrap::AxesUnits,std::allocator< enum AxesUnitsWrap::AxesUnits > > *|std::vector< AxesUnits,std::allocator< AxesUnits > > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__vectorT_AxisInfo_std__allocatorT_AxisInfo_t_t = {"_p_std__vectorT_AxisInfo_std__allocatorT_AxisInfo_t_t", "std::vector< AxisInfo,std::allocator< AxisInfo > > *|std::vector< AxisInfo > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__vectorT_BasicVector3DT_double_t_std__allocatorT_BasicVector3DT_double_t_t_t = {"_p_std__vectorT_BasicVector3DT_double_t_std__allocatorT_BasicVector3DT_double_t_t_t", "std::vector< BasicVector3D< double > > *|std::vector< BasicVector3D< double >,std::allocator< BasicVector3D< double > > > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__vectorT_BasicVector3DT_std__complexT_double_t_t_std__allocatorT_BasicVector3DT_std__complexT_double_t_t_t_t = {"_p_std__vectorT_BasicVector3DT_std__complexT_double_t_t_std__allocatorT_BasicVector3DT_std__complexT_double_t_t_t_t", "std::vector< BasicVector3D< std::complex< double > > > *|std::vector< BasicVector3D< std::complex< double > >,std::allocator< BasicVector3D< std::complex< double > > > > *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__vectorT_FitElement_std__allocatorT_FitElement_t_t = {"_p_std__vectorT_FitElement_std__allocatorT_FitElement_t_t", "std::vector< FitElement,std::allocator< FitElement > > *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__vectorT_FitElement_std__allocatorT_FitElement_t_t__iterator = {"_p_std__vectorT_FitElement_std__allocatorT_FitElement_t_t__iterator", "std::vector< FitElement,std::allocator< FitElement > >::iterator *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__vectorT_HomogeneousRegion_std__allocatorT_HomogeneousRegion_t_t = {"_p_std__vectorT_HomogeneousRegion_std__allocatorT_HomogeneousRegion_t_t", "std::vector< HomogeneousRegion,std::allocator< HomogeneousRegion > > *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__vectorT_IFitParameter_p_std__allocatorT_IFitParameter_p_t_t__const_iterator = {"_p_std__vectorT_IFitParameter_p_std__allocatorT_IFitParameter_p_t_t__const_iterator", "FitParameterSet::const_iterator *|std::vector< IFitParameter *,std::allocator< IFitParameter * > >::const_iterator *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__vectorT_IFitParameter_p_std__allocatorT_IFitParameter_p_t_t__iterator = {"_p_std__vectorT_IFitParameter_p_std__allocatorT_IFitParameter_p_t_t__iterator", "FitParameterSet::iterator *|std::vector< IFitParameter *,std::allocator< IFitParameter * > >::iterator *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__vectorT_IFormFactor_p_std__allocatorT_IFormFactor_p_t_t = {"_p_std__vectorT_IFormFactor_p_std__allocatorT_IFormFactor_p_t_t", "std::vector< IFormFactor *,std::allocator< IFormFactor * > > *|std::vector< IFormFactor * > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__vectorT_ILayout_const_p_std__allocatorT_ILayout_const_p_t_t = {"_p_std__vectorT_ILayout_const_p_std__allocatorT_ILayout_const_p_t_t", "std::vector< ILayout const *,std::allocator< ILayout const * > > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__vectorT_INode_const_p_std__allocatorT_INode_const_p_t_t = {"_p_std__vectorT_INode_const_p_std__allocatorT_INode_const_p_t_t", "std::vector< INode const *,std::allocator< INode const * > > *|std::vector< INode const * > *", 0, 0, (void*)0, 0};
@@ -142930,8 +135462,6 @@ static swig_type_info _swigt__p_unsigned_short = {"_p_unsigned_short", "unsigned
 static swig_type_info _swigt__p_value_type = {"_p_value_type", "value_type *", 0, 0, (void*)0, 0};
 
 static swig_type_info *swig_type_initial[] = {
-  &_swigt__p_AdjustMinimizerStrategy,
-  &_swigt__p_AttLimits,
   &_swigt__p_Attributes,
   &_swigt__p_AxesUnitsWrap,
   &_swigt__p_AxesUnitsWrap__AxesUnits,
@@ -142982,17 +135512,8 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_FTDistribution2DGate,
   &_swigt__p_FTDistribution2DGauss,
   &_swigt__p_FTDistribution2DVoigt,
-  &_swigt__p_FitObject,
   &_swigt__p_FitObjective,
-  &_swigt__p_FitObjects_t,
   &_swigt__p_FitOptions,
-  &_swigt__p_FitParameter,
-  &_swigt__p_FitParameterSet,
-  &_swigt__p_FitStrategyDefault,
-  &_swigt__p_FitSuite,
-  &_swigt__p_FitSuiteImpl,
-  &_swigt__p_FitSuiteObjects,
-  &_swigt__p_FitSuiteStrategies,
   &_swigt__p_Fit__MinimizerResult,
   &_swigt__p_Fit__Parameters,
   &_swigt__p_FixedBinAxis,
@@ -143021,6 +135542,7 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_FormFactorGauss,
   &_swigt__p_FormFactorHemiEllipsoid,
   &_swigt__p_FormFactorIcosahedron,
+  &_swigt__p_FormFactorLongBox,
   &_swigt__p_FormFactorLongBoxGauss,
   &_swigt__p_FormFactorLongBoxLorentz,
   &_swigt__p_FormFactorLongRipple1Gauss,
@@ -143046,7 +135568,7 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_FormFactorTruncatedSpheroid,
   &_swigt__p_FormFactorWeighted,
   &_swigt__p_GISASSimulation,
-  &_swigt__p_GaussPeakShape,
+  &_swigt__p_GaussFisherPeakShape,
   &_swigt__p_HexagonalLattice,
   &_swigt__p_Histogram1D,
   &_swigt__p_Histogram2D,
@@ -143067,9 +135589,6 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_IFTDistribution2D,
   &_swigt__p_IFactoryT_std__string_IMultiLayerBuilder_t,
   &_swigt__p_IFactoryT_std__string_Simulation_t,
-  &_swigt__p_IFitObserver,
-  &_swigt__p_IFitParameter,
-  &_swigt__p_IFitStrategy,
   &_swigt__p_IFootprintFactor,
   &_swigt__p_IFormFactor,
   &_swigt__p_IFormFactorBorn,
@@ -143080,7 +135599,6 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_IInterferenceFunction,
   &_swigt__p_ILatticeOrientation,
   &_swigt__p_ILayout,
-  &_swigt__p_IMinimizer,
   &_swigt__p_IMultiLayerBuilder,
   &_swigt__p_INamed,
   &_swigt__p_INode,
@@ -143097,8 +135615,8 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_ISample,
   &_swigt__p_ISelectionRule,
   &_swigt__p_IShape2D,
-  &_swigt__p_ISquaredFunction,
   &_swigt__p_IUnitConverter,
+  &_swigt__p_IVarianceFunction,
   &_swigt__p_IdentityRotation,
   &_swigt__p_Instrument,
   &_swigt__p_IntensityDataIOFactory,
@@ -143112,9 +135630,12 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_InterferenceFunction2DSuperLattice,
   &_swigt__p_InterferenceFunction3DLattice,
   &_swigt__p_InterferenceFunctionFinite2DLattice,
+  &_swigt__p_InterferenceFunctionFinite3DLattice,
   &_swigt__p_InterferenceFunctionNone,
   &_swigt__p_InterferenceFunctionRadialParaCrystal,
   &_swigt__p_IsGISAXSDetector,
+  &_swigt__p_IsotropicGaussPeakShape,
+  &_swigt__p_IsotropicLorentzPeakShape,
   &_swigt__p_IterationInfo,
   &_swigt__p_Lattice,
   &_swigt__p_Lattice1DParameters,
@@ -143124,6 +135645,7 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_LayerInterface,
   &_swigt__p_LayerRoughness,
   &_swigt__p_Line,
+  &_swigt__p_LorentzFisherPeakShape,
   &_swigt__p_Material,
   &_swigt__p_MesoCrystal,
   &_swigt__p_MillerIndex,
@@ -143165,7 +135687,6 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_RotationX,
   &_swigt__p_RotationY,
   &_swigt__p_RotationZ,
-  &_swigt__p_SafePointerVectorT_FitObject_t__iterator,
   &_swigt__p_SafePointerVectorT_IParticle_t,
   &_swigt__p_SafePointerVectorT_Layer_t,
   &_swigt__p_SampleBuilderFactory,
@@ -143182,14 +135703,11 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_SphericalDetector,
   &_swigt__p_SphericalPixel,
   &_swigt__p_SquareLattice,
-  &_swigt__p_SquaredFunctionDefault,
-  &_swigt__p_SquaredFunctionGaussianError,
-  &_swigt__p_SquaredFunctionMeanSquaredError,
-  &_swigt__p_SquaredFunctionSimError,
-  &_swigt__p_SquaredFunctionSystematicError,
   &_swigt__p_ThreadInfo,
   &_swigt__p_Transform3D,
   &_swigt__p_VariableBinAxis,
+  &_swigt__p_VarianceConstantFunction,
+  &_swigt__p_VarianceSimFunction,
   &_swigt__p_VerticalLine,
   &_swigt__p_WavevectorInfo,
   &_swigt__p_ZLimits,
@@ -143198,7 +135716,6 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_char,
   &_swigt__p_const_iterator,
   &_swigt__p_const_reference,
-  &_swigt__p_container_t,
   &_swigt__p_corr_matrix_t,
   &_swigt__p_difference_type,
   &_swigt__p_double,
@@ -143239,18 +135756,13 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_std__mapT_std__string_double_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_double_t_t_t,
   &_swigt__p_std__mapT_std__string_std__string_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_std__string_t_t_t__const_iterator,
   &_swigt__p_std__pairT_double_double_t,
-  &_swigt__p_std__shared_ptrT_IFitObserver_t,
   &_swigt__p_std__shared_ptrT_IMultiLayerBuilder_t,
   &_swigt__p_std__shared_ptrT_IObserver_t,
   &_swigt__p_std__vectorT_AxesUnitsWrap__AxesUnits_std__allocatorT_AxesUnitsWrap__AxesUnits_t_t,
   &_swigt__p_std__vectorT_AxisInfo_std__allocatorT_AxisInfo_t_t,
   &_swigt__p_std__vectorT_BasicVector3DT_double_t_std__allocatorT_BasicVector3DT_double_t_t_t,
   &_swigt__p_std__vectorT_BasicVector3DT_std__complexT_double_t_t_std__allocatorT_BasicVector3DT_std__complexT_double_t_t_t_t,
-  &_swigt__p_std__vectorT_FitElement_std__allocatorT_FitElement_t_t,
-  &_swigt__p_std__vectorT_FitElement_std__allocatorT_FitElement_t_t__iterator,
   &_swigt__p_std__vectorT_HomogeneousRegion_std__allocatorT_HomogeneousRegion_t_t,
-  &_swigt__p_std__vectorT_IFitParameter_p_std__allocatorT_IFitParameter_p_t_t__const_iterator,
-  &_swigt__p_std__vectorT_IFitParameter_p_std__allocatorT_IFitParameter_p_t_t__iterator,
   &_swigt__p_std__vectorT_IFormFactor_p_std__allocatorT_IFormFactor_p_t_t,
   &_swigt__p_std__vectorT_ILayout_const_p_std__allocatorT_ILayout_const_p_t_t,
   &_swigt__p_std__vectorT_INode_const_p_std__allocatorT_INode_const_p_t_t,
@@ -143277,8 +135789,6 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_value_type,
 };
 
-static swig_cast_info _swigc__p_AdjustMinimizerStrategy[] = {  {&_swigt__p_AdjustMinimizerStrategy, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_AttLimits[] = {  {&_swigt__p_AttLimits, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_Attributes[] = {  {&_swigt__p_Attributes, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_AxesUnitsWrap[] = {  {&_swigt__p_AxesUnitsWrap, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_AxesUnitsWrap__AxesUnits[] = {  {&_swigt__p_AxesUnitsWrap__AxesUnits, 0, 0, 0},{0, 0, 0, 0}};
@@ -143329,17 +135839,8 @@ static swig_cast_info _swigc__p_FTDistribution2DCone[] = {  {&_swigt__p_FTDistri
 static swig_cast_info _swigc__p_FTDistribution2DGate[] = {  {&_swigt__p_FTDistribution2DGate, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_FTDistribution2DGauss[] = {  {&_swigt__p_FTDistribution2DGauss, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_FTDistribution2DVoigt[] = {  {&_swigt__p_FTDistribution2DVoigt, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_FitObject[] = {  {&_swigt__p_FitObject, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_FitObjective[] = {  {&_swigt__p_FitObjective, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_FitObjects_t[] = {  {&_swigt__p_FitObjects_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_FitOptions[] = {  {&_swigt__p_FitOptions, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_FitParameter[] = {  {&_swigt__p_FitParameter, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_FitParameterSet[] = {  {&_swigt__p_FitParameterSet, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_FitStrategyDefault[] = {  {&_swigt__p_FitStrategyDefault, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_FitSuite[] = {  {&_swigt__p_FitSuite, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_FitSuiteImpl[] = {  {&_swigt__p_FitSuiteImpl, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_FitSuiteObjects[] = {  {&_swigt__p_FitSuiteObjects, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_FitSuiteStrategies[] = {  {&_swigt__p_FitSuiteStrategies, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_Fit__MinimizerResult[] = {  {&_swigt__p_Fit__MinimizerResult, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_Fit__Parameters[] = {  {&_swigt__p_Fit__Parameters, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_FixedBinAxis[] = {  {&_swigt__p_FixedBinAxis, 0, 0, 0},{0, 0, 0, 0}};
@@ -143368,6 +135869,7 @@ static swig_cast_info _swigc__p_FormFactorFullSpheroid[] = {  {&_swigt__p_FormFa
 static swig_cast_info _swigc__p_FormFactorGauss[] = {  {&_swigt__p_FormFactorGauss, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_FormFactorHemiEllipsoid[] = {  {&_swigt__p_FormFactorHemiEllipsoid, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_FormFactorIcosahedron[] = {  {&_swigt__p_FormFactorIcosahedron, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_FormFactorLongBox[] = {  {&_swigt__p_FormFactorLongBox, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_FormFactorLongBoxGauss[] = {  {&_swigt__p_FormFactorLongBoxGauss, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_FormFactorLongBoxLorentz[] = {  {&_swigt__p_FormFactorLongBoxLorentz, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_FormFactorLongRipple1Gauss[] = {  {&_swigt__p_FormFactorLongRipple1Gauss, 0, 0, 0},{0, 0, 0, 0}};
@@ -143393,7 +135895,7 @@ static swig_cast_info _swigc__p_FormFactorTruncatedSphere[] = {  {&_swigt__p_For
 static swig_cast_info _swigc__p_FormFactorTruncatedSpheroid[] = {  {&_swigt__p_FormFactorTruncatedSpheroid, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_FormFactorWeighted[] = {  {&_swigt__p_FormFactorWeighted, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_GISASSimulation[] = {  {&_swigt__p_GISASSimulation, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_GaussPeakShape[] = {  {&_swigt__p_GaussPeakShape, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_GaussFisherPeakShape[] = {  {&_swigt__p_GaussFisherPeakShape, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_HexagonalLattice[] = {  {&_swigt__p_HexagonalLattice, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_Histogram1D[] = {  {&_swigt__p_Histogram1D, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_Histogram2D[] = {  {&_swigt__p_Histogram2D, 0, 0, 0},{0, 0, 0, 0}};
@@ -143402,7 +135904,7 @@ static swig_cast_info _swigc__p_IAbstractParticle[] = {  {&_swigt__p_ParticleCom
 static swig_cast_info _swigc__p_IAxis[] = {  {&_swigt__p_IAxis, 0, 0, 0},  {&_swigt__p_VariableBinAxis, _p_VariableBinAxisTo_p_IAxis, 0, 0},  {&_swigt__p_ConstKBinAxis, _p_ConstKBinAxisTo_p_IAxis, 0, 0},  {&_swigt__p_CustomBinAxis, _p_CustomBinAxisTo_p_IAxis, 0, 0},  {&_swigt__p_FixedBinAxis, _p_FixedBinAxisTo_p_IAxis, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IBackground[] = {  {&_swigt__p_IBackground, 0, 0, 0},  {&_swigt__p_ConstantBackground, _p_ConstantBackgroundTo_p_IBackground, 0, 0},  {&_swigt__p_PoissonNoiseBackground, _p_PoissonNoiseBackgroundTo_p_IBackground, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IChiSquaredModule[] = {  {&_swigt__p_IChiSquaredModule, 0, 0, 0},  {&_swigt__p_ChiSquaredModule, _p_ChiSquaredModuleTo_p_IChiSquaredModule, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_ICloneable[] = {  {&_swigt__p_FormFactorBox, _p_FormFactorBoxTo_p_ICloneable, 0, 0},  {&_swigt__p_IBackground, _p_IBackgroundTo_p_ICloneable, 0, 0},  {&_swigt__p_ConstantBackground, _p_ConstantBackgroundTo_p_ICloneable, 0, 0},  {&_swigt__p_PoissonNoiseBackground, _p_PoissonNoiseBackgroundTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorSphereGaussianRadius, _p_FormFactorSphereGaussianRadiusTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorSphereLogNormalRadius, _p_FormFactorSphereLogNormalRadiusTo_p_ICloneable, 0, 0},  {&_swigt__p_MultiLayer, _p_MultiLayerTo_p_ICloneable, 0, 0},  {&_swigt__p_ParticleDistribution, _p_ParticleDistributionTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDecayFunction1DGauss, _p_FTDecayFunction1DGaussTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDistribution1DGauss, _p_FTDistribution1DGaussTo_p_ICloneable, 0, 0},  {&_swigt__p_InterferenceFunctionNone, _p_InterferenceFunctionNoneTo_p_ICloneable, 0, 0},  {&_swigt__p_Polygon, _p_PolygonTo_p_ICloneable, 0, 0},  {&_swigt__p_IDetector2D, _p_IDetector2DTo_p_ICloneable, 0, 0},  {&_swigt__p_Ellipse, _p_EllipseTo_p_ICloneable, 0, 0},  {&_swigt__p_ILayout, _p_ILayoutTo_p_ICloneable, 0, 0},  {&_swigt__p_ParticleLayout, _p_ParticleLayoutTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorHemiEllipsoid, _p_FormFactorHemiEllipsoidTo_p_ICloneable, 0, 0},  {&_swigt__p_IntensityScaleAndShiftNormalizer, _p_IntensityScaleAndShiftNormalizerTo_p_ICloneable, 0, 0},  {&_swigt__p_IntensityNormalizer, _p_IntensityNormalizerTo_p_ICloneable, 0, 0},  {&_swigt__p_IIntensityNormalizer, _p_IIntensityNormalizerTo_p_ICloneable, 0, 0},  {&_swigt__p_ChiSquaredModule, _p_ChiSquaredModuleTo_p_ICloneable, 0, 0},  {&_swigt__p_IChiSquaredModule, _p_IChiSquaredModuleTo_p_ICloneable, 0, 0},  {&_swigt__p_HorizontalLine, _p_HorizontalLineTo_p_ICloneable, 0, 0},  {&_swigt__p_SphericalDetector, _p_SphericalDetectorTo_p_ICloneable, 0, 0},  {&_swigt__p_IsGISAXSDetector, _p_IsGISAXSDetectorTo_p_ICloneable, 0, 0},  {&_swigt__p_RectangularDetector, _p_RectangularDetectorTo_p_ICloneable, 0, 0},  {&_swigt__p_IDetector, _p_IDetectorTo_p_ICloneable, 0, 0},  {&_swigt__p_IPeakShape, _p_IPeakShapeTo_p_ICloneable, 0, 0},  {&_swigt__p_GaussPeakShape, _p_GaussPeakShapeTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorPrism3, _p_FormFactorPrism3To_p_ICloneable, 0, 0},  {&_swigt__p_DistributionTrapezoid, _p_DistributionTrapezoidTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorIcosahedron, _p_FormFactorIcosahedronTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorDodecahedron, _p_FormFactorDodecahedronTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorCuboctahedron, _p_FormFactorCuboctahedronTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorTetrahedron, _p_FormFactorTetrahedronTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorPolyhedron, _p_FormFactorPolyhedronTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorDebyeBueche, _p_FormFactorDebyeBuecheTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorPrism6, _p_FormFactorPrism6To_p_ICloneable, 0, 0},  {&_swigt__p_Simulation, _p_SimulationTo_p_ICloneable, 0, 0},  {&_swigt__p_GISASSimulation, _p_GISASSimulationTo_p_ICloneable, 0, 0},  {&_swigt__p_OffSpecSimulation, _p_OffSpecSimulationTo_p_ICloneable, 0, 0},  {&_swigt__p_DepthProbeSimulation, _p_DepthProbeSimulationTo_p_ICloneable, 0, 0},  {&_swigt__p_SpecularSimulation, _p_SpecularSimulationTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDistribution2DCone, _p_FTDistribution2DConeTo_p_ICloneable, 0, 0},  {&_swigt__p_ParticleCoreShell, _p_ParticleCoreShellTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorFullSphere, _p_FormFactorFullSphereTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorTruncatedSphere, _p_FormFactorTruncatedSphereTo_p_ICloneable, 0, 0},  {&_swigt__p_IFormFactor, _p_IFormFactorTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorPolygonalSurface, _p_FormFactorPolygonalSurfaceTo_p_ICloneable, 0, 0},  {&_swigt__p_ISample, _p_ISampleTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorLongBoxGauss, _p_FormFactorLongBoxGaussTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorPolygonalPrism, _p_FormFactorPolygonalPrismTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDistribution2DGate, _p_FTDistribution2DGateTo_p_ICloneable, 0, 0},  {&_swigt__p_DistributionLogNormal, _p_DistributionLogNormalTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDistribution1DVoigt, _p_FTDistribution1DVoigtTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDecayFunction1DVoigt, _p_FTDecayFunction1DVoigtTo_p_ICloneable, 0, 0},  {&_swigt__p_IdentityRotation, _p_IdentityRotationTo_p_ICloneable, 0, 0},  {&_swigt__p_IRotation, _p_IRotationTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorTruncatedSpheroid, _p_FormFactorTruncatedSpheroidTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorFullSpheroid, _p_FormFactorFullSpheroidTo_p_ICloneable, 0, 0},  {&_swigt__p_RotationX, _p_RotationXTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorTruncatedCube, _p_FormFactorTruncatedCubeTo_p_ICloneable, 0, 0},  {&_swigt__p_RotationY, _p_RotationYTo_p_ICloneable, 0, 0},  {&_swigt__p_IShape2D, _p_IShape2DTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDecayFunction2DGauss, _p_FTDecayFunction2DGaussTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDistribution2DGauss, _p_FTDistribution2DGaussTo_p_ICloneable, 0, 0},  {&_swigt__p_RotationZ, _p_RotationZTo_p_ICloneable, 0, 0},  {&_swigt__p_Rectangle, _p_RectangleTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorLongRipple2Gauss, _p_FormFactorLongRipple2GaussTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorGauss, _p_FormFactorGaussTo_p_ICloneable, 0, 0},  {&_swigt__p_VerticalLine, _p_VerticalLineTo_p_ICloneable, 0, 0},  {&_swigt__p_IFormFactorBorn, _p_IFormFactorBornTo_p_ICloneable, 0, 0},  {&_swigt__p_IDetectorResolution, _p_IDetectorResolutionTo_p_ICloneable, 0, 0},  {&_swigt__p_IClusteredParticles, _p_IClusteredParticlesTo_p_ICloneable, 0, 0},  {&_swigt__p_IAbstractParticle, _p_IAbstractParticleTo_p_ICloneable, 0, 0},  {&_swigt__p_IParticle, _p_IParticleTo_p_ICloneable, 0, 0},  {&_swigt__p_Particle, _p_ParticleTo_p_ICloneable, 0, 0},  {&_swigt__p_Lattice2D, _p_Lattice2DTo_p_ICloneable, 0, 0},  {&_swigt__p_DistributionGate, _p_DistributionGateTo_p_ICloneable, 0, 0},  {&_swigt__p_IDistribution1D, _p_IDistribution1DTo_p_ICloneable, 0, 0},  {&_swigt__p_IFTDecayFunction1D, _p_IFTDecayFunction1DTo_p_ICloneable, 0, 0},  {&_swigt__p_IFTDistribution1D, _p_IFTDistribution1DTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorCone, _p_FormFactorConeTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorRipple1, _p_FormFactorRipple1To_p_ICloneable, 0, 0},  {&_swigt__p_Layer, _p_LayerTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorPyramid, _p_FormFactorPyramidTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorAnisoPyramid, _p_FormFactorAnisoPyramidTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorDecoratorDebyeWaller, _p_FormFactorDecoratorDebyeWallerTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorRipple2, _p_FormFactorRipple2To_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorEllipsoidalCylinder, _p_FormFactorEllipsoidalCylinderTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorCylinder, _p_FormFactorCylinderTo_p_ICloneable, 0, 0},  {&_swigt__p_DistributionGaussian, _p_DistributionGaussianTo_p_ICloneable, 0, 0},  {&_swigt__p_FootprintFactorGaussian, _p_FootprintFactorGaussianTo_p_ICloneable, 0, 0},  {&_swigt__p_ResolutionFunction2DGaussian, _p_ResolutionFunction2DGaussianTo_p_ICloneable, 0, 0},  {&_swigt__p_IFootprintFactor, _p_IFootprintFactorTo_p_ICloneable, 0, 0},  {&_swigt__p_ParticleComposition, _p_ParticleCompositionTo_p_ICloneable, 0, 0},  {&_swigt__p_Line, _p_LineTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorSphereUniformRadius, _p_FormFactorSphereUniformRadiusTo_p_ICloneable, 0, 0},  {&_swigt__p_DistributionCosine, _p_DistributionCosineTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDistribution1DCosine, _p_FTDistribution1DCosineTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDistribution1DGate, _p_FTDistribution1DGateTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDistribution2DVoigt, _p_FTDistribution2DVoigtTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDecayFunction2DVoigt, _p_FTDecayFunction2DVoigtTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDecayFunction1DCauchy, _p_FTDecayFunction1DCauchyTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDistribution1DCauchy, _p_FTDistribution1DCauchyTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDistribution2DCauchy, _p_FTDistribution2DCauchyTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDecayFunction2DCauchy, _p_FTDecayFunction2DCauchyTo_p_ICloneable, 0, 0},  {&_swigt__p_IInterferenceFunction, _p_IInterferenceFunctionTo_p_ICloneable, 0, 0},  {&_swigt__p_FootprintFactorSquare, _p_FootprintFactorSquareTo_p_ICloneable, 0, 0},  {&_swigt__p_ParameterPool, _p_ParameterPoolTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorCone6, _p_FormFactorCone6To_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorLongRipple1Gauss, _p_FormFactorLongRipple1GaussTo_p_ICloneable, 0, 0},  {&_swigt__p_IUnitConverter, _p_IUnitConverterTo_p_ICloneable, 0, 0},  {&_swigt__p_IFormFactorDecorator, _p_IFormFactorDecoratorTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorOrnsteinZernike, _p_FormFactorOrnsteinZernikeTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorDot, _p_FormFactorDotTo_p_ICloneable, 0, 0},  {&_swigt__p_LayerRoughness, _p_LayerRoughnessTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorCrystal, _p_FormFactorCrystalTo_p_ICloneable, 0, 0},  {&_swigt__p_Crystal, _p_CrystalTo_p_ICloneable, 0, 0},  {&_swigt__p_MesoCrystal, _p_MesoCrystalTo_p_ICloneable, 0, 0},  {&_swigt__p_InterferenceFunctionRadialParaCrystal, _p_InterferenceFunctionRadialParaCrystalTo_p_ICloneable, 0, 0},  {&_swigt__p_InterferenceFunction2DParaCrystal, _p_InterferenceFunction2DParaCrystalTo_p_ICloneable, 0, 0},  {&_swigt__p_Simulation2D, _p_Simulation2DTo_p_ICloneable, 0, 0},  {&_swigt__p_IFTDecayFunction2D, _p_IFTDecayFunction2DTo_p_ICloneable, 0, 0},  {&_swigt__p_IFTDistribution2D, _p_IFTDistribution2DTo_p_ICloneable, 0, 0},  {&_swigt__p_IResolutionFunction2D, _p_IResolutionFunction2DTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorWeighted, _p_FormFactorWeightedTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorLongRipple2Lorentz, _p_FormFactorLongRipple2LorentzTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorLongRipple1Lorentz, _p_FormFactorLongRipple1LorentzTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorLongBoxLorentz, _p_FormFactorLongBoxLorentzTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorLorentz, _p_FormFactorLorentzTo_p_ICloneable, 0, 0},  {&_swigt__p_InterferenceFunction1DLattice, _p_InterferenceFunction1DLatticeTo_p_ICloneable, 0, 0},  {&_swigt__p_InterferenceFunction2DLattice, _p_InterferenceFunction2DLatticeTo_p_ICloneable, 0, 0},  {&_swigt__p_InterferenceFunction3DLattice, _p_InterferenceFunction3DLatticeTo_p_ICloneable, 0, 0},  {&_swigt__p_InterferenceFunctionFinite2DLattice, _p_InterferenceFunctionFinite2DLatticeTo_p_ICloneable, 0, 0},  {&_swigt__p_InterferenceFunction2DSuperLattice, _p_InterferenceFunction2DSuperLatticeTo_p_ICloneable, 0, 0},  {&_swigt__p_BasicLattice, _p_BasicLatticeTo_p_ICloneable, 0, 0},  {&_swigt__p_SquareLattice, _p_SquareLatticeTo_p_ICloneable, 0, 0},  {&_swigt__p_HexagonalLattice, _p_HexagonalLatticeTo_p_ICloneable, 0, 0},  {&_swigt__p_DistributionLorentz, _p_DistributionLorentzTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDecayFunction1DTriangle, _p_FTDecayFunction1DTriangleTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDistribution1DTriangle, _p_FTDistribution1DTriangleTo_p_ICloneable, 0, 0},  {&_swigt__p_ICloneable, 0, 0, 0},  {&_swigt__p_RotationEuler, _p_RotationEulerTo_p_ICloneable, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_ICloneable[] = {  {&_swigt__p_FormFactorBox, _p_FormFactorBoxTo_p_ICloneable, 0, 0},  {&_swigt__p_IBackground, _p_IBackgroundTo_p_ICloneable, 0, 0},  {&_swigt__p_ConstantBackground, _p_ConstantBackgroundTo_p_ICloneable, 0, 0},  {&_swigt__p_PoissonNoiseBackground, _p_PoissonNoiseBackgroundTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorSphereGaussianRadius, _p_FormFactorSphereGaussianRadiusTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorSphereLogNormalRadius, _p_FormFactorSphereLogNormalRadiusTo_p_ICloneable, 0, 0},  {&_swigt__p_MultiLayer, _p_MultiLayerTo_p_ICloneable, 0, 0},  {&_swigt__p_ParticleDistribution, _p_ParticleDistributionTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDecayFunction1DGauss, _p_FTDecayFunction1DGaussTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDistribution1DGauss, _p_FTDistribution1DGaussTo_p_ICloneable, 0, 0},  {&_swigt__p_InterferenceFunctionNone, _p_InterferenceFunctionNoneTo_p_ICloneable, 0, 0},  {&_swigt__p_Polygon, _p_PolygonTo_p_ICloneable, 0, 0},  {&_swigt__p_IDetector2D, _p_IDetector2DTo_p_ICloneable, 0, 0},  {&_swigt__p_Ellipse, _p_EllipseTo_p_ICloneable, 0, 0},  {&_swigt__p_ILayout, _p_ILayoutTo_p_ICloneable, 0, 0},  {&_swigt__p_ParticleLayout, _p_ParticleLayoutTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorHemiEllipsoid, _p_FormFactorHemiEllipsoidTo_p_ICloneable, 0, 0},  {&_swigt__p_IntensityScaleAndShiftNormalizer, _p_IntensityScaleAndShiftNormalizerTo_p_ICloneable, 0, 0},  {&_swigt__p_IntensityNormalizer, _p_IntensityNormalizerTo_p_ICloneable, 0, 0},  {&_swigt__p_IIntensityNormalizer, _p_IIntensityNormalizerTo_p_ICloneable, 0, 0},  {&_swigt__p_ChiSquaredModule, _p_ChiSquaredModuleTo_p_ICloneable, 0, 0},  {&_swigt__p_IChiSquaredModule, _p_IChiSquaredModuleTo_p_ICloneable, 0, 0},  {&_swigt__p_HorizontalLine, _p_HorizontalLineTo_p_ICloneable, 0, 0},  {&_swigt__p_SphericalDetector, _p_SphericalDetectorTo_p_ICloneable, 0, 0},  {&_swigt__p_IsGISAXSDetector, _p_IsGISAXSDetectorTo_p_ICloneable, 0, 0},  {&_swigt__p_RectangularDetector, _p_RectangularDetectorTo_p_ICloneable, 0, 0},  {&_swigt__p_IDetector, _p_IDetectorTo_p_ICloneable, 0, 0},  {&_swigt__p_IPeakShape, _p_IPeakShapeTo_p_ICloneable, 0, 0},  {&_swigt__p_IsotropicGaussPeakShape, _p_IsotropicGaussPeakShapeTo_p_ICloneable, 0, 0},  {&_swigt__p_IsotropicLorentzPeakShape, _p_IsotropicLorentzPeakShapeTo_p_ICloneable, 0, 0},  {&_swigt__p_GaussFisherPeakShape, _p_GaussFisherPeakShapeTo_p_ICloneable, 0, 0},  {&_swigt__p_LorentzFisherPeakShape, _p_LorentzFisherPeakShapeTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorPrism3, _p_FormFactorPrism3To_p_ICloneable, 0, 0},  {&_swigt__p_DistributionTrapezoid, _p_DistributionTrapezoidTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorIcosahedron, _p_FormFactorIcosahedronTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorDodecahedron, _p_FormFactorDodecahedronTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorCuboctahedron, _p_FormFactorCuboctahedronTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorPolyhedron, _p_FormFactorPolyhedronTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorTetrahedron, _p_FormFactorTetrahedronTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorDebyeBueche, _p_FormFactorDebyeBuecheTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorPrism6, _p_FormFactorPrism6To_p_ICloneable, 0, 0},  {&_swigt__p_Simulation, _p_SimulationTo_p_ICloneable, 0, 0},  {&_swigt__p_GISASSimulation, _p_GISASSimulationTo_p_ICloneable, 0, 0},  {&_swigt__p_OffSpecSimulation, _p_OffSpecSimulationTo_p_ICloneable, 0, 0},  {&_swigt__p_DepthProbeSimulation, _p_DepthProbeSimulationTo_p_ICloneable, 0, 0},  {&_swigt__p_SpecularSimulation, _p_SpecularSimulationTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDistribution2DCone, _p_FTDistribution2DConeTo_p_ICloneable, 0, 0},  {&_swigt__p_ParticleCoreShell, _p_ParticleCoreShellTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorFullSphere, _p_FormFactorFullSphereTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorTruncatedSphere, _p_FormFactorTruncatedSphereTo_p_ICloneable, 0, 0},  {&_swigt__p_IFormFactor, _p_IFormFactorTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorPolygonalSurface, _p_FormFactorPolygonalSurfaceTo_p_ICloneable, 0, 0},  {&_swigt__p_ISample, _p_ISampleTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorLongBoxGauss, _p_FormFactorLongBoxGaussTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorPolygonalPrism, _p_FormFactorPolygonalPrismTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDistribution2DGate, _p_FTDistribution2DGateTo_p_ICloneable, 0, 0},  {&_swigt__p_DistributionLogNormal, _p_DistributionLogNormalTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDistribution1DVoigt, _p_FTDistribution1DVoigtTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDecayFunction1DVoigt, _p_FTDecayFunction1DVoigtTo_p_ICloneable, 0, 0},  {&_swigt__p_IdentityRotation, _p_IdentityRotationTo_p_ICloneable, 0, 0},  {&_swigt__p_IRotation, _p_IRotationTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorTruncatedSpheroid, _p_FormFactorTruncatedSpheroidTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorFullSpheroid, _p_FormFactorFullSpheroidTo_p_ICloneable, 0, 0},  {&_swigt__p_RotationX, _p_RotationXTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorTruncatedCube, _p_FormFactorTruncatedCubeTo_p_ICloneable, 0, 0},  {&_swigt__p_RotationY, _p_RotationYTo_p_ICloneable, 0, 0},  {&_swigt__p_IShape2D, _p_IShape2DTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDecayFunction2DGauss, _p_FTDecayFunction2DGaussTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDistribution2DGauss, _p_FTDistribution2DGaussTo_p_ICloneable, 0, 0},  {&_swigt__p_RotationZ, _p_RotationZTo_p_ICloneable, 0, 0},  {&_swigt__p_Rectangle, _p_RectangleTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorLongRipple2Gauss, _p_FormFactorLongRipple2GaussTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorGauss, _p_FormFactorGaussTo_p_ICloneable, 0, 0},  {&_swigt__p_VerticalLine, _p_VerticalLineTo_p_ICloneable, 0, 0},  {&_swigt__p_IFormFactorBorn, _p_IFormFactorBornTo_p_ICloneable, 0, 0},  {&_swigt__p_IDetectorResolution, _p_IDetectorResolutionTo_p_ICloneable, 0, 0},  {&_swigt__p_IClusteredParticles, _p_IClusteredParticlesTo_p_ICloneable, 0, 0},  {&_swigt__p_Particle, _p_ParticleTo_p_ICloneable, 0, 0},  {&_swigt__p_IAbstractParticle, _p_IAbstractParticleTo_p_ICloneable, 0, 0},  {&_swigt__p_IParticle, _p_IParticleTo_p_ICloneable, 0, 0},  {&_swigt__p_Lattice2D, _p_Lattice2DTo_p_ICloneable, 0, 0},  {&_swigt__p_DistributionGate, _p_DistributionGateTo_p_ICloneable, 0, 0},  {&_swigt__p_IDistribution1D, _p_IDistribution1DTo_p_ICloneable, 0, 0},  {&_swigt__p_IFTDecayFunction1D, _p_IFTDecayFunction1DTo_p_ICloneable, 0, 0},  {&_swigt__p_IFTDistribution1D, _p_IFTDistribution1DTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorCone, _p_FormFactorConeTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorRipple1, _p_FormFactorRipple1To_p_ICloneable, 0, 0},  {&_swigt__p_Layer, _p_LayerTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorPyramid, _p_FormFactorPyramidTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorAnisoPyramid, _p_FormFactorAnisoPyramidTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorDecoratorDebyeWaller, _p_FormFactorDecoratorDebyeWallerTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorRipple2, _p_FormFactorRipple2To_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorEllipsoidalCylinder, _p_FormFactorEllipsoidalCylinderTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorCylinder, _p_FormFactorCylinderTo_p_ICloneable, 0, 0},  {&_swigt__p_DistributionGaussian, _p_DistributionGaussianTo_p_ICloneable, 0, 0},  {&_swigt__p_FootprintFactorGaussian, _p_FootprintFactorGaussianTo_p_ICloneable, 0, 0},  {&_swigt__p_ResolutionFunction2DGaussian, _p_ResolutionFunction2DGaussianTo_p_ICloneable, 0, 0},  {&_swigt__p_IFootprintFactor, _p_IFootprintFactorTo_p_ICloneable, 0, 0},  {&_swigt__p_ParticleComposition, _p_ParticleCompositionTo_p_ICloneable, 0, 0},  {&_swigt__p_Line, _p_LineTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorSphereUniformRadius, _p_FormFactorSphereUniformRadiusTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorLongBox, _p_FormFactorLongBoxTo_p_ICloneable, 0, 0},  {&_swigt__p_DistributionCosine, _p_DistributionCosineTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDistribution1DCosine, _p_FTDistribution1DCosineTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDistribution1DGate, _p_FTDistribution1DGateTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDistribution2DVoigt, _p_FTDistribution2DVoigtTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDecayFunction2DVoigt, _p_FTDecayFunction2DVoigtTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDecayFunction1DCauchy, _p_FTDecayFunction1DCauchyTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDistribution1DCauchy, _p_FTDistribution1DCauchyTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDistribution2DCauchy, _p_FTDistribution2DCauchyTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDecayFunction2DCauchy, _p_FTDecayFunction2DCauchyTo_p_ICloneable, 0, 0},  {&_swigt__p_IInterferenceFunction, _p_IInterferenceFunctionTo_p_ICloneable, 0, 0},  {&_swigt__p_FootprintFactorSquare, _p_FootprintFactorSquareTo_p_ICloneable, 0, 0},  {&_swigt__p_ParameterPool, _p_ParameterPoolTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorCone6, _p_FormFactorCone6To_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorLongRipple1Gauss, _p_FormFactorLongRipple1GaussTo_p_ICloneable, 0, 0},  {&_swigt__p_IUnitConverter, _p_IUnitConverterTo_p_ICloneable, 0, 0},  {&_swigt__p_IFormFactorDecorator, _p_IFormFactorDecoratorTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorOrnsteinZernike, _p_FormFactorOrnsteinZernikeTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorDot, _p_FormFactorDotTo_p_ICloneable, 0, 0},  {&_swigt__p_LayerRoughness, _p_LayerRoughnessTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorCrystal, _p_FormFactorCrystalTo_p_ICloneable, 0, 0},  {&_swigt__p_Crystal, _p_CrystalTo_p_ICloneable, 0, 0},  {&_swigt__p_MesoCrystal, _p_MesoCrystalTo_p_ICloneable, 0, 0},  {&_swigt__p_InterferenceFunction2DParaCrystal, _p_InterferenceFunction2DParaCrystalTo_p_ICloneable, 0, 0},  {&_swigt__p_InterferenceFunctionRadialParaCrystal, _p_InterferenceFunctionRadialParaCrystalTo_p_ICloneable, 0, 0},  {&_swigt__p_Simulation2D, _p_Simulation2DTo_p_ICloneable, 0, 0},  {&_swigt__p_IFTDecayFunction2D, _p_IFTDecayFunction2DTo_p_ICloneable, 0, 0},  {&_swigt__p_IFTDistribution2D, _p_IFTDistribution2DTo_p_ICloneable, 0, 0},  {&_swigt__p_IResolutionFunction2D, _p_IResolutionFunction2DTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorWeighted, _p_FormFactorWeightedTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorLongBoxLorentz, _p_FormFactorLongBoxLorentzTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorLongRipple1Lorentz, _p_FormFactorLongRipple1LorentzTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorLongRipple2Lorentz, _p_FormFactorLongRipple2LorentzTo_p_ICloneable, 0, 0},  {&_swigt__p_FormFactorLorentz, _p_FormFactorLorentzTo_p_ICloneable, 0, 0},  {&_swigt__p_InterferenceFunction1DLattice, _p_InterferenceFunction1DLatticeTo_p_ICloneable, 0, 0},  {&_swigt__p_InterferenceFunction2DLattice, _p_InterferenceFunction2DLatticeTo_p_ICloneable, 0, 0},  {&_swigt__p_InterferenceFunction2DSuperLattice, _p_InterferenceFunction2DSuperLatticeTo_p_ICloneable, 0, 0},  {&_swigt__p_InterferenceFunction3DLattice, _p_InterferenceFunction3DLatticeTo_p_ICloneable, 0, 0},  {&_swigt__p_InterferenceFunctionFinite2DLattice, _p_InterferenceFunctionFinite2DLatticeTo_p_ICloneable, 0, 0},  {&_swigt__p_InterferenceFunctionFinite3DLattice, _p_InterferenceFunctionFinite3DLatticeTo_p_ICloneable, 0, 0},  {&_swigt__p_BasicLattice, _p_BasicLatticeTo_p_ICloneable, 0, 0},  {&_swigt__p_SquareLattice, _p_SquareLatticeTo_p_ICloneable, 0, 0},  {&_swigt__p_HexagonalLattice, _p_HexagonalLatticeTo_p_ICloneable, 0, 0},  {&_swigt__p_DistributionLorentz, _p_DistributionLorentzTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDecayFunction1DTriangle, _p_FTDecayFunction1DTriangleTo_p_ICloneable, 0, 0},  {&_swigt__p_FTDistribution1DTriangle, _p_FTDistribution1DTriangleTo_p_ICloneable, 0, 0},  {&_swigt__p_ICloneable, 0, 0, 0},  {&_swigt__p_RotationEuler, _p_RotationEulerTo_p_ICloneable, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IClusteredParticles[] = {  {&_swigt__p_IClusteredParticles, 0, 0, 0},  {&_swigt__p_Crystal, _p_CrystalTo_p_IClusteredParticles, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IDetector[] = {  {&_swigt__p_IDetector, 0, 0, 0},  {&_swigt__p_SphericalDetector, _p_SphericalDetectorTo_p_IDetector, 0, 0},  {&_swigt__p_IsGISAXSDetector, _p_IsGISAXSDetectorTo_p_IDetector, 0, 0},  {&_swigt__p_RectangularDetector, _p_RectangularDetectorTo_p_IDetector, 0, 0},  {&_swigt__p_IDetector2D, _p_IDetector2DTo_p_IDetector, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IDetector2D[] = {  {&_swigt__p_SphericalDetector, _p_SphericalDetectorTo_p_IDetector2D, 0, 0},  {&_swigt__p_IsGISAXSDetector, _p_IsGISAXSDetectorTo_p_IDetector2D, 0, 0},  {&_swigt__p_RectangularDetector, _p_RectangularDetectorTo_p_IDetector2D, 0, 0},  {&_swigt__p_IDetector2D, 0, 0, 0},{0, 0, 0, 0}};
@@ -143414,38 +135916,34 @@ static swig_cast_info _swigc__p_IFTDistribution1D[] = {  {&_swigt__p_FTDistribut
 static swig_cast_info _swigc__p_IFTDistribution2D[] = {  {&_swigt__p_FTDistribution2DCauchy, _p_FTDistribution2DCauchyTo_p_IFTDistribution2D, 0, 0},  {&_swigt__p_FTDistribution2DGauss, _p_FTDistribution2DGaussTo_p_IFTDistribution2D, 0, 0},  {&_swigt__p_IFTDistribution2D, 0, 0, 0},  {&_swigt__p_FTDistribution2DVoigt, _p_FTDistribution2DVoigtTo_p_IFTDistribution2D, 0, 0},  {&_swigt__p_FTDistribution2DGate, _p_FTDistribution2DGateTo_p_IFTDistribution2D, 0, 0},  {&_swigt__p_FTDistribution2DCone, _p_FTDistribution2DConeTo_p_IFTDistribution2D, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IFactoryT_std__string_IMultiLayerBuilder_t[] = {  {&_swigt__p_IFactoryT_std__string_IMultiLayerBuilder_t, 0, 0, 0},  {&_swigt__p_SampleBuilderFactory, _p_SampleBuilderFactoryTo_p_IFactoryT_std__string_IMultiLayerBuilder_t, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IFactoryT_std__string_Simulation_t[] = {  {&_swigt__p_SimulationFactory, _p_SimulationFactoryTo_p_IFactoryT_std__string_Simulation_t, 0, 0},  {&_swigt__p_IFactoryT_std__string_Simulation_t, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_IFitObserver[] = {  {&_swigt__p_IFitObserver, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_IFitParameter[] = {  {&_swigt__p_IFitParameter, 0, 0, 0},  {&_swigt__p_FitParameter, _p_FitParameterTo_p_IFitParameter, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_IFitStrategy[] = {  {&_swigt__p_IFitStrategy, 0, 0, 0},  {&_swigt__p_AdjustMinimizerStrategy, _p_AdjustMinimizerStrategyTo_p_IFitStrategy, 0, 0},  {&_swigt__p_FitStrategyDefault, _p_FitStrategyDefaultTo_p_IFitStrategy, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IFootprintFactor[] = {  {&_swigt__p_FootprintFactorSquare, _p_FootprintFactorSquareTo_p_IFootprintFactor, 0, 0},  {&_swigt__p_IFootprintFactor, 0, 0, 0},  {&_swigt__p_FootprintFactorGaussian, _p_FootprintFactorGaussianTo_p_IFootprintFactor, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_IFormFactor[] = {  {&_swigt__p_FormFactorPrism6, _p_FormFactorPrism6To_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorHemiEllipsoid, _p_FormFactorHemiEllipsoidTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorPolygonalPrism, _p_FormFactorPolygonalPrismTo_p_IFormFactor, 0, 0},  {&_swigt__p_IFormFactor, 0, 0, 0},  {&_swigt__p_FormFactorFullSpheroid, _p_FormFactorFullSpheroidTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorTruncatedSpheroid, _p_FormFactorTruncatedSpheroidTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorDebyeBueche, _p_FormFactorDebyeBuecheTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorLongBoxGauss, _p_FormFactorLongBoxGaussTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorOrnsteinZernike, _p_FormFactorOrnsteinZernikeTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorRipple1, _p_FormFactorRipple1To_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorPolygonalSurface, _p_FormFactorPolygonalSurfaceTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorCrystal, _p_FormFactorCrystalTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorRipple2, _p_FormFactorRipple2To_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorTruncatedCube, _p_FormFactorTruncatedCubeTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorFullSphere, _p_FormFactorFullSphereTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorTruncatedSphere, _p_FormFactorTruncatedSphereTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorLongRipple1Gauss, _p_FormFactorLongRipple1GaussTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorEllipsoidalCylinder, _p_FormFactorEllipsoidalCylinderTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorCylinder, _p_FormFactorCylinderTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorBox, _p_FormFactorBoxTo_p_IFormFactor, 0, 0},  {&_swigt__p_IFormFactorDecorator, _p_IFormFactorDecoratorTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorIcosahedron, _p_FormFactorIcosahedronTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorDodecahedron, _p_FormFactorDodecahedronTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorPolyhedron, _p_FormFactorPolyhedronTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorCuboctahedron, _p_FormFactorCuboctahedronTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorTetrahedron, _p_FormFactorTetrahedronTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorCone, _p_FormFactorConeTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorCone6, _p_FormFactorCone6To_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorSphereGaussianRadius, _p_FormFactorSphereGaussianRadiusTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorSphereLogNormalRadius, _p_FormFactorSphereLogNormalRadiusTo_p_IFormFactor, 0, 0},  {&_swigt__p_IFormFactorBorn, _p_IFormFactorBornTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorDot, _p_FormFactorDotTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorDecoratorDebyeWaller, _p_FormFactorDecoratorDebyeWallerTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorLongBoxLorentz, _p_FormFactorLongBoxLorentzTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorLongRipple1Lorentz, _p_FormFactorLongRipple1LorentzTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorLongRipple2Lorentz, _p_FormFactorLongRipple2LorentzTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorLorentz, _p_FormFactorLorentzTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorWeighted, _p_FormFactorWeightedTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorPyramid, _p_FormFactorPyramidTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorAnisoPyramid, _p_FormFactorAnisoPyramidTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorPrism3, _p_FormFactorPrism3To_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorSphereUniformRadius, _p_FormFactorSphereUniformRadiusTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorLongRipple2Gauss, _p_FormFactorLongRipple2GaussTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorGauss, _p_FormFactorGaussTo_p_IFormFactor, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_IFormFactorBorn[] = {  {&_swigt__p_FormFactorPrism6, _p_FormFactorPrism6To_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorHemiEllipsoid, _p_FormFactorHemiEllipsoidTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorPolygonalPrism, _p_FormFactorPolygonalPrismTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorFullSpheroid, _p_FormFactorFullSpheroidTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorTruncatedSpheroid, _p_FormFactorTruncatedSpheroidTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorDebyeBueche, _p_FormFactorDebyeBuecheTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorLongBoxGauss, _p_FormFactorLongBoxGaussTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorOrnsteinZernike, _p_FormFactorOrnsteinZernikeTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorRipple1, _p_FormFactorRipple1To_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorPolygonalSurface, _p_FormFactorPolygonalSurfaceTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorRipple2, _p_FormFactorRipple2To_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorTruncatedCube, _p_FormFactorTruncatedCubeTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorFullSphere, _p_FormFactorFullSphereTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorTruncatedSphere, _p_FormFactorTruncatedSphereTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorLongRipple1Gauss, _p_FormFactorLongRipple1GaussTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorCylinder, _p_FormFactorCylinderTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorEllipsoidalCylinder, _p_FormFactorEllipsoidalCylinderTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorBox, _p_FormFactorBoxTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorIcosahedron, _p_FormFactorIcosahedronTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorPolyhedron, _p_FormFactorPolyhedronTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorCuboctahedron, _p_FormFactorCuboctahedronTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorDodecahedron, _p_FormFactorDodecahedronTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorTetrahedron, _p_FormFactorTetrahedronTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorCone, _p_FormFactorConeTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorCone6, _p_FormFactorCone6To_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorSphereLogNormalRadius, _p_FormFactorSphereLogNormalRadiusTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorSphereGaussianRadius, _p_FormFactorSphereGaussianRadiusTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_IFormFactorBorn, 0, 0, 0},  {&_swigt__p_FormFactorDot, _p_FormFactorDotTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorLongRipple1Lorentz, _p_FormFactorLongRipple1LorentzTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorLongBoxLorentz, _p_FormFactorLongBoxLorentzTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorLongRipple2Lorentz, _p_FormFactorLongRipple2LorentzTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorLorentz, _p_FormFactorLorentzTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorPyramid, _p_FormFactorPyramidTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorAnisoPyramid, _p_FormFactorAnisoPyramidTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorPrism3, _p_FormFactorPrism3To_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorSphereUniformRadius, _p_FormFactorSphereUniformRadiusTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorLongRipple2Gauss, _p_FormFactorLongRipple2GaussTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorGauss, _p_FormFactorGaussTo_p_IFormFactorBorn, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_IFormFactor[] = {  {&_swigt__p_FormFactorPrism6, _p_FormFactorPrism6To_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorHemiEllipsoid, _p_FormFactorHemiEllipsoidTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorPolygonalPrism, _p_FormFactorPolygonalPrismTo_p_IFormFactor, 0, 0},  {&_swigt__p_IFormFactor, 0, 0, 0},  {&_swigt__p_FormFactorFullSpheroid, _p_FormFactorFullSpheroidTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorTruncatedSpheroid, _p_FormFactorTruncatedSpheroidTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorDebyeBueche, _p_FormFactorDebyeBuecheTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorLongBoxGauss, _p_FormFactorLongBoxGaussTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorOrnsteinZernike, _p_FormFactorOrnsteinZernikeTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorRipple1, _p_FormFactorRipple1To_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorPolygonalSurface, _p_FormFactorPolygonalSurfaceTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorCrystal, _p_FormFactorCrystalTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorRipple2, _p_FormFactorRipple2To_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorTruncatedCube, _p_FormFactorTruncatedCubeTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorLongBox, _p_FormFactorLongBoxTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorFullSphere, _p_FormFactorFullSphereTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorTruncatedSphere, _p_FormFactorTruncatedSphereTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorLongRipple1Gauss, _p_FormFactorLongRipple1GaussTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorEllipsoidalCylinder, _p_FormFactorEllipsoidalCylinderTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorCylinder, _p_FormFactorCylinderTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorBox, _p_FormFactorBoxTo_p_IFormFactor, 0, 0},  {&_swigt__p_IFormFactorDecorator, _p_IFormFactorDecoratorTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorIcosahedron, _p_FormFactorIcosahedronTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorDodecahedron, _p_FormFactorDodecahedronTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorPolyhedron, _p_FormFactorPolyhedronTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorCuboctahedron, _p_FormFactorCuboctahedronTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorTetrahedron, _p_FormFactorTetrahedronTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorCone, _p_FormFactorConeTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorCone6, _p_FormFactorCone6To_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorSphereLogNormalRadius, _p_FormFactorSphereLogNormalRadiusTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorSphereGaussianRadius, _p_FormFactorSphereGaussianRadiusTo_p_IFormFactor, 0, 0},  {&_swigt__p_IFormFactorBorn, _p_IFormFactorBornTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorDot, _p_FormFactorDotTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorDecoratorDebyeWaller, _p_FormFactorDecoratorDebyeWallerTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorLongBoxLorentz, _p_FormFactorLongBoxLorentzTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorLongRipple1Lorentz, _p_FormFactorLongRipple1LorentzTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorLongRipple2Lorentz, _p_FormFactorLongRipple2LorentzTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorLorentz, _p_FormFactorLorentzTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorWeighted, _p_FormFactorWeightedTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorPyramid, _p_FormFactorPyramidTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorAnisoPyramid, _p_FormFactorAnisoPyramidTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorPrism3, _p_FormFactorPrism3To_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorSphereUniformRadius, _p_FormFactorSphereUniformRadiusTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorLongRipple2Gauss, _p_FormFactorLongRipple2GaussTo_p_IFormFactor, 0, 0},  {&_swigt__p_FormFactorGauss, _p_FormFactorGaussTo_p_IFormFactor, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_IFormFactorBorn[] = {  {&_swigt__p_FormFactorPrism6, _p_FormFactorPrism6To_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorHemiEllipsoid, _p_FormFactorHemiEllipsoidTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorPolygonalPrism, _p_FormFactorPolygonalPrismTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorFullSpheroid, _p_FormFactorFullSpheroidTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorTruncatedSpheroid, _p_FormFactorTruncatedSpheroidTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorDebyeBueche, _p_FormFactorDebyeBuecheTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorLongBoxGauss, _p_FormFactorLongBoxGaussTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorOrnsteinZernike, _p_FormFactorOrnsteinZernikeTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorRipple1, _p_FormFactorRipple1To_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorPolygonalSurface, _p_FormFactorPolygonalSurfaceTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorRipple2, _p_FormFactorRipple2To_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorTruncatedCube, _p_FormFactorTruncatedCubeTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorLongBox, _p_FormFactorLongBoxTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorFullSphere, _p_FormFactorFullSphereTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorTruncatedSphere, _p_FormFactorTruncatedSphereTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorLongRipple1Gauss, _p_FormFactorLongRipple1GaussTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorCylinder, _p_FormFactorCylinderTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorEllipsoidalCylinder, _p_FormFactorEllipsoidalCylinderTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorBox, _p_FormFactorBoxTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorIcosahedron, _p_FormFactorIcosahedronTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorPolyhedron, _p_FormFactorPolyhedronTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorCuboctahedron, _p_FormFactorCuboctahedronTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorDodecahedron, _p_FormFactorDodecahedronTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorTetrahedron, _p_FormFactorTetrahedronTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorCone, _p_FormFactorConeTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorCone6, _p_FormFactorCone6To_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorSphereLogNormalRadius, _p_FormFactorSphereLogNormalRadiusTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorSphereGaussianRadius, _p_FormFactorSphereGaussianRadiusTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_IFormFactorBorn, 0, 0, 0},  {&_swigt__p_FormFactorDot, _p_FormFactorDotTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorLongBoxLorentz, _p_FormFactorLongBoxLorentzTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorLongRipple1Lorentz, _p_FormFactorLongRipple1LorentzTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorLongRipple2Lorentz, _p_FormFactorLongRipple2LorentzTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorLorentz, _p_FormFactorLorentzTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorPyramid, _p_FormFactorPyramidTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorAnisoPyramid, _p_FormFactorAnisoPyramidTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorPrism3, _p_FormFactorPrism3To_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorSphereUniformRadius, _p_FormFactorSphereUniformRadiusTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorLongRipple2Gauss, _p_FormFactorLongRipple2GaussTo_p_IFormFactorBorn, 0, 0},  {&_swigt__p_FormFactorGauss, _p_FormFactorGaussTo_p_IFormFactorBorn, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IFormFactorDecorator[] = {  {&_swigt__p_IFormFactorDecorator, 0, 0, 0},  {&_swigt__p_FormFactorDecoratorDebyeWaller, _p_FormFactorDecoratorDebyeWallerTo_p_IFormFactorDecorator, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IHistogram[] = {  {&_swigt__p_IHistogram, 0, 0, 0},  {&_swigt__p_Histogram2D, _p_Histogram2DTo_p_IHistogram, 0, 0},  {&_swigt__p_Histogram1D, _p_Histogram1DTo_p_IHistogram, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IIntensityFunction[] = {  {&_swigt__p_IntensityFunctionSqrt, _p_IntensityFunctionSqrtTo_p_IIntensityFunction, 0, 0},  {&_swigt__p_IIntensityFunction, 0, 0, 0},  {&_swigt__p_IntensityFunctionLog, _p_IntensityFunctionLogTo_p_IIntensityFunction, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IIntensityNormalizer[] = {  {&_swigt__p_IIntensityNormalizer, 0, 0, 0},  {&_swigt__p_IntensityNormalizer, _p_IntensityNormalizerTo_p_IIntensityNormalizer, 0, 0},  {&_swigt__p_IntensityScaleAndShiftNormalizer, _p_IntensityScaleAndShiftNormalizerTo_p_IIntensityNormalizer, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_IInterferenceFunction[] = {  {&_swigt__p_IInterferenceFunction, 0, 0, 0},  {&_swigt__p_InterferenceFunction1DLattice, _p_InterferenceFunction1DLatticeTo_p_IInterferenceFunction, 0, 0},  {&_swigt__p_InterferenceFunction2DLattice, _p_InterferenceFunction2DLatticeTo_p_IInterferenceFunction, 0, 0},  {&_swigt__p_InterferenceFunction3DLattice, _p_InterferenceFunction3DLatticeTo_p_IInterferenceFunction, 0, 0},  {&_swigt__p_InterferenceFunctionFinite2DLattice, _p_InterferenceFunctionFinite2DLatticeTo_p_IInterferenceFunction, 0, 0},  {&_swigt__p_InterferenceFunction2DSuperLattice, _p_InterferenceFunction2DSuperLatticeTo_p_IInterferenceFunction, 0, 0},  {&_swigt__p_InterferenceFunctionNone, _p_InterferenceFunctionNoneTo_p_IInterferenceFunction, 0, 0},  {&_swigt__p_InterferenceFunctionRadialParaCrystal, _p_InterferenceFunctionRadialParaCrystalTo_p_IInterferenceFunction, 0, 0},  {&_swigt__p_InterferenceFunction2DParaCrystal, _p_InterferenceFunction2DParaCrystalTo_p_IInterferenceFunction, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_IInterferenceFunction[] = {  {&_swigt__p_IInterferenceFunction, 0, 0, 0},  {&_swigt__p_InterferenceFunction1DLattice, _p_InterferenceFunction1DLatticeTo_p_IInterferenceFunction, 0, 0},  {&_swigt__p_InterferenceFunction2DLattice, _p_InterferenceFunction2DLatticeTo_p_IInterferenceFunction, 0, 0},  {&_swigt__p_InterferenceFunction2DSuperLattice, _p_InterferenceFunction2DSuperLatticeTo_p_IInterferenceFunction, 0, 0},  {&_swigt__p_InterferenceFunction3DLattice, _p_InterferenceFunction3DLatticeTo_p_IInterferenceFunction, 0, 0},  {&_swigt__p_InterferenceFunctionFinite2DLattice, _p_InterferenceFunctionFinite2DLatticeTo_p_IInterferenceFunction, 0, 0},  {&_swigt__p_InterferenceFunctionFinite3DLattice, _p_InterferenceFunctionFinite3DLatticeTo_p_IInterferenceFunction, 0, 0},  {&_swigt__p_InterferenceFunctionNone, _p_InterferenceFunctionNoneTo_p_IInterferenceFunction, 0, 0},  {&_swigt__p_InterferenceFunction2DParaCrystal, _p_InterferenceFunction2DParaCrystalTo_p_IInterferenceFunction, 0, 0},  {&_swigt__p_InterferenceFunctionRadialParaCrystal, _p_InterferenceFunctionRadialParaCrystalTo_p_IInterferenceFunction, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_ILatticeOrientation[] = {  {&_swigt__p_ILatticeOrientation, 0, 0, 0},  {&_swigt__p_MillerIndexOrientation, _p_MillerIndexOrientationTo_p_ILatticeOrientation, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_ILayout[] = {  {&_swigt__p_ILayout, 0, 0, 0},  {&_swigt__p_ParticleLayout, _p_ParticleLayoutTo_p_ILayout, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_IMinimizer[] = {  {&_swigt__p_IMinimizer, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IMultiLayerBuilder[] = {  {&_swigt__p_IMultiLayerBuilder, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_INamed[] = {  {&_swigt__p_FormFactorBox, _p_FormFactorBoxTo_p_INamed, 0, 0},  {&_swigt__p_IBackground, _p_IBackgroundTo_p_INamed, 0, 0},  {&_swigt__p_ConstantBackground, _p_ConstantBackgroundTo_p_INamed, 0, 0},  {&_swigt__p_PoissonNoiseBackground, _p_PoissonNoiseBackgroundTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorSphereGaussianRadius, _p_FormFactorSphereGaussianRadiusTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorSphereLogNormalRadius, _p_FormFactorSphereLogNormalRadiusTo_p_INamed, 0, 0},  {&_swigt__p_MultiLayer, _p_MultiLayerTo_p_INamed, 0, 0},  {&_swigt__p_ParameterDistribution, _p_ParameterDistributionTo_p_INamed, 0, 0},  {&_swigt__p_ParticleDistribution, _p_ParticleDistributionTo_p_INamed, 0, 0},  {&_swigt__p_FTDistribution1DGauss, _p_FTDistribution1DGaussTo_p_INamed, 0, 0},  {&_swigt__p_FTDecayFunction1DGauss, _p_FTDecayFunction1DGaussTo_p_INamed, 0, 0},  {&_swigt__p_InterferenceFunctionNone, _p_InterferenceFunctionNoneTo_p_INamed, 0, 0},  {&_swigt__p_Polygon, _p_PolygonTo_p_INamed, 0, 0},  {&_swigt__p_IDetector2D, _p_IDetector2DTo_p_INamed, 0, 0},  {&_swigt__p_Ellipse, _p_EllipseTo_p_INamed, 0, 0},  {&_swigt__p_ILayout, _p_ILayoutTo_p_INamed, 0, 0},  {&_swigt__p_ParticleLayout, _p_ParticleLayoutTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorHemiEllipsoid, _p_FormFactorHemiEllipsoidTo_p_INamed, 0, 0},  {&_swigt__p_IntensityScaleAndShiftNormalizer, _p_IntensityScaleAndShiftNormalizerTo_p_INamed, 0, 0},  {&_swigt__p_IntensityNormalizer, _p_IntensityNormalizerTo_p_INamed, 0, 0},  {&_swigt__p_IIntensityNormalizer, _p_IIntensityNormalizerTo_p_INamed, 0, 0},  {&_swigt__p_HorizontalLine, _p_HorizontalLineTo_p_INamed, 0, 0},  {&_swigt__p_SphericalDetector, _p_SphericalDetectorTo_p_INamed, 0, 0},  {&_swigt__p_IsGISAXSDetector, _p_IsGISAXSDetectorTo_p_INamed, 0, 0},  {&_swigt__p_RectangularDetector, _p_RectangularDetectorTo_p_INamed, 0, 0},  {&_swigt__p_IDetector, _p_IDetectorTo_p_INamed, 0, 0},  {&_swigt__p_INode, _p_INodeTo_p_INamed, 0, 0},  {&_swigt__p_IPeakShape, _p_IPeakShapeTo_p_INamed, 0, 0},  {&_swigt__p_GaussPeakShape, _p_GaussPeakShapeTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorPrism3, _p_FormFactorPrism3To_p_INamed, 0, 0},  {&_swigt__p_DistributionTrapezoid, _p_DistributionTrapezoidTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorTetrahedron, _p_FormFactorTetrahedronTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorPolyhedron, _p_FormFactorPolyhedronTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorCuboctahedron, _p_FormFactorCuboctahedronTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorIcosahedron, _p_FormFactorIcosahedronTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorDodecahedron, _p_FormFactorDodecahedronTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorDebyeBueche, _p_FormFactorDebyeBuecheTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorPrism6, _p_FormFactorPrism6To_p_INamed, 0, 0},  {&_swigt__p_Simulation, _p_SimulationTo_p_INamed, 0, 0},  {&_swigt__p_GISASSimulation, _p_GISASSimulationTo_p_INamed, 0, 0},  {&_swigt__p_OffSpecSimulation, _p_OffSpecSimulationTo_p_INamed, 0, 0},  {&_swigt__p_DepthProbeSimulation, _p_DepthProbeSimulationTo_p_INamed, 0, 0},  {&_swigt__p_SpecularSimulation, _p_SpecularSimulationTo_p_INamed, 0, 0},  {&_swigt__p_FTDistribution2DCone, _p_FTDistribution2DConeTo_p_INamed, 0, 0},  {&_swigt__p_ParticleCoreShell, _p_ParticleCoreShellTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorFullSphere, _p_FormFactorFullSphereTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorTruncatedSphere, _p_FormFactorTruncatedSphereTo_p_INamed, 0, 0},  {&_swigt__p_IFormFactor, _p_IFormFactorTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorPolygonalSurface, _p_FormFactorPolygonalSurfaceTo_p_INamed, 0, 0},  {&_swigt__p_ISample, _p_ISampleTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorLongBoxGauss, _p_FormFactorLongBoxGaussTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorPolygonalPrism, _p_FormFactorPolygonalPrismTo_p_INamed, 0, 0},  {&_swigt__p_FitSuiteObjects, _p_FitSuiteObjectsTo_p_INamed, 0, 0},  {&_swigt__p_FTDistribution2DGate, _p_FTDistribution2DGateTo_p_INamed, 0, 0},  {&_swigt__p_DistributionLogNormal, _p_DistributionLogNormalTo_p_INamed, 0, 0},  {&_swigt__p_Instrument, _p_InstrumentTo_p_INamed, 0, 0},  {&_swigt__p_FTDistribution1DVoigt, _p_FTDistribution1DVoigtTo_p_INamed, 0, 0},  {&_swigt__p_FTDecayFunction1DVoigt, _p_FTDecayFunction1DVoigtTo_p_INamed, 0, 0},  {&_swigt__p_IdentityRotation, _p_IdentityRotationTo_p_INamed, 0, 0},  {&_swigt__p_IRotation, _p_IRotationTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorTruncatedSpheroid, _p_FormFactorTruncatedSpheroidTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorFullSpheroid, _p_FormFactorFullSpheroidTo_p_INamed, 0, 0},  {&_swigt__p_RotationX, _p_RotationXTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorTruncatedCube, _p_FormFactorTruncatedCubeTo_p_INamed, 0, 0},  {&_swigt__p_RotationY, _p_RotationYTo_p_INamed, 0, 0},  {&_swigt__p_FTDecayFunction2DGauss, _p_FTDecayFunction2DGaussTo_p_INamed, 0, 0},  {&_swigt__p_FTDistribution2DGauss, _p_FTDistribution2DGaussTo_p_INamed, 0, 0},  {&_swigt__p_IShape2D, _p_IShape2DTo_p_INamed, 0, 0},  {&_swigt__p_RotationZ, _p_RotationZTo_p_INamed, 0, 0},  {&_swigt__p_Rectangle, _p_RectangleTo_p_INamed, 0, 0},  {&_swigt__p_FitStrategyDefault, _p_FitStrategyDefaultTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorLongRipple2Gauss, _p_FormFactorLongRipple2GaussTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorGauss, _p_FormFactorGaussTo_p_INamed, 0, 0},  {&_swigt__p_VerticalLine, _p_VerticalLineTo_p_INamed, 0, 0},  {&_swigt__p_IFormFactorBorn, _p_IFormFactorBornTo_p_INamed, 0, 0},  {&_swigt__p_IDetectorResolution, _p_IDetectorResolutionTo_p_INamed, 0, 0},  {&_swigt__p_IClusteredParticles, _p_IClusteredParticlesTo_p_INamed, 0, 0},  {&_swigt__p_IMultiLayerBuilder, _p_IMultiLayerBuilderTo_p_INamed, 0, 0},  {&_swigt__p_IAbstractParticle, _p_IAbstractParticleTo_p_INamed, 0, 0},  {&_swigt__p_IParticle, _p_IParticleTo_p_INamed, 0, 0},  {&_swigt__p_Particle, _p_ParticleTo_p_INamed, 0, 0},  {&_swigt__p_Lattice2D, _p_Lattice2DTo_p_INamed, 0, 0},  {&_swigt__p_INamed, 0, 0, 0},  {&_swigt__p_DistributionGate, _p_DistributionGateTo_p_INamed, 0, 0},  {&_swigt__p_IDistribution1D, _p_IDistribution1DTo_p_INamed, 0, 0},  {&_swigt__p_IFTDecayFunction1D, _p_IFTDecayFunction1DTo_p_INamed, 0, 0},  {&_swigt__p_IFTDistribution1D, _p_IFTDistribution1DTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorCone, _p_FormFactorConeTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorRipple1, _p_FormFactorRipple1To_p_INamed, 0, 0},  {&_swigt__p_Layer, _p_LayerTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorPyramid, _p_FormFactorPyramidTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorAnisoPyramid, _p_FormFactorAnisoPyramidTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorDecoratorDebyeWaller, _p_FormFactorDecoratorDebyeWallerTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorRipple2, _p_FormFactorRipple2To_p_INamed, 0, 0},  {&_swigt__p_FormFactorEllipsoidalCylinder, _p_FormFactorEllipsoidalCylinderTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorCylinder, _p_FormFactorCylinderTo_p_INamed, 0, 0},  {&_swigt__p_IParameterT_double_t, _p_IParameterT_double_tTo_p_INamed, 0, 0},  {&_swigt__p_DistributionGaussian, _p_DistributionGaussianTo_p_INamed, 0, 0},  {&_swigt__p_FootprintFactorGaussian, _p_FootprintFactorGaussianTo_p_INamed, 0, 0},  {&_swigt__p_ResolutionFunction2DGaussian, _p_ResolutionFunction2DGaussianTo_p_INamed, 0, 0},  {&_swigt__p_IFootprintFactor, _p_IFootprintFactorTo_p_INamed, 0, 0},  {&_swigt__p_ParticleComposition, _p_ParticleCompositionTo_p_INamed, 0, 0},  {&_swigt__p_Line, _p_LineTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorSphereUniformRadius, _p_FormFactorSphereUniformRadiusTo_p_INamed, 0, 0},  {&_swigt__p_DistributionCosine, _p_DistributionCosineTo_p_INamed, 0, 0},  {&_swigt__p_FTDistribution1DCosine, _p_FTDistribution1DCosineTo_p_INamed, 0, 0},  {&_swigt__p_FTDistribution1DGate, _p_FTDistribution1DGateTo_p_INamed, 0, 0},  {&_swigt__p_FTDistribution2DVoigt, _p_FTDistribution2DVoigtTo_p_INamed, 0, 0},  {&_swigt__p_FTDecayFunction2DVoigt, _p_FTDecayFunction2DVoigtTo_p_INamed, 0, 0},  {&_swigt__p_FTDecayFunction1DCauchy, _p_FTDecayFunction1DCauchyTo_p_INamed, 0, 0},  {&_swigt__p_FTDistribution1DCauchy, _p_FTDistribution1DCauchyTo_p_INamed, 0, 0},  {&_swigt__p_FTDecayFunction2DCauchy, _p_FTDecayFunction2DCauchyTo_p_INamed, 0, 0},  {&_swigt__p_FTDistribution2DCauchy, _p_FTDistribution2DCauchyTo_p_INamed, 0, 0},  {&_swigt__p_IInterferenceFunction, _p_IInterferenceFunctionTo_p_INamed, 0, 0},  {&_swigt__p_FootprintFactorSquare, _p_FootprintFactorSquareTo_p_INamed, 0, 0},  {&_swigt__p_FitObject, _p_FitObjectTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorCone6, _p_FormFactorCone6To_p_INamed, 0, 0},  {&_swigt__p_FormFactorLongRipple1Gauss, _p_FormFactorLongRipple1GaussTo_p_INamed, 0, 0},  {&_swigt__p_Beam, _p_BeamTo_p_INamed, 0, 0},  {&_swigt__p_AdjustMinimizerStrategy, _p_AdjustMinimizerStrategyTo_p_INamed, 0, 0},  {&_swigt__p_IFitStrategy, _p_IFitStrategyTo_p_INamed, 0, 0},  {&_swigt__p_IFormFactorDecorator, _p_IFormFactorDecoratorTo_p_INamed, 0, 0},  {&_swigt__p_IParameterized, _p_IParameterizedTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorOrnsteinZernike, _p_FormFactorOrnsteinZernikeTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorDot, _p_FormFactorDotTo_p_INamed, 0, 0},  {&_swigt__p_LayerRoughness, _p_LayerRoughnessTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorCrystal, _p_FormFactorCrystalTo_p_INamed, 0, 0},  {&_swigt__p_Crystal, _p_CrystalTo_p_INamed, 0, 0},  {&_swigt__p_MesoCrystal, _p_MesoCrystalTo_p_INamed, 0, 0},  {&_swigt__p_InterferenceFunctionRadialParaCrystal, _p_InterferenceFunctionRadialParaCrystalTo_p_INamed, 0, 0},  {&_swigt__p_InterferenceFunction2DParaCrystal, _p_InterferenceFunction2DParaCrystalTo_p_INamed, 0, 0},  {&_swigt__p_Simulation2D, _p_Simulation2DTo_p_INamed, 0, 0},  {&_swigt__p_IFTDecayFunction2D, _p_IFTDecayFunction2DTo_p_INamed, 0, 0},  {&_swigt__p_IFTDistribution2D, _p_IFTDistribution2DTo_p_INamed, 0, 0},  {&_swigt__p_IResolutionFunction2D, _p_IResolutionFunction2DTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorWeighted, _p_FormFactorWeightedTo_p_INamed, 0, 0},  {&_swigt__p_RealParameter, _p_RealParameterTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorLongRipple2Lorentz, _p_FormFactorLongRipple2LorentzTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorLongRipple1Lorentz, _p_FormFactorLongRipple1LorentzTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorLongBoxLorentz, _p_FormFactorLongBoxLorentzTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorLorentz, _p_FormFactorLorentzTo_p_INamed, 0, 0},  {&_swigt__p_InterferenceFunction1DLattice, _p_InterferenceFunction1DLatticeTo_p_INamed, 0, 0},  {&_swigt__p_InterferenceFunction2DLattice, _p_InterferenceFunction2DLatticeTo_p_INamed, 0, 0},  {&_swigt__p_InterferenceFunction3DLattice, _p_InterferenceFunction3DLatticeTo_p_INamed, 0, 0},  {&_swigt__p_InterferenceFunctionFinite2DLattice, _p_InterferenceFunctionFinite2DLatticeTo_p_INamed, 0, 0},  {&_swigt__p_InterferenceFunction2DSuperLattice, _p_InterferenceFunction2DSuperLatticeTo_p_INamed, 0, 0},  {&_swigt__p_BasicLattice, _p_BasicLatticeTo_p_INamed, 0, 0},  {&_swigt__p_SquareLattice, _p_SquareLatticeTo_p_INamed, 0, 0},  {&_swigt__p_HexagonalLattice, _p_HexagonalLatticeTo_p_INamed, 0, 0},  {&_swigt__p_DistributionLorentz, _p_DistributionLorentzTo_p_INamed, 0, 0},  {&_swigt__p_Lattice, _p_LatticeTo_p_INamed, 0, 0},  {&_swigt__p_FTDecayFunction1DTriangle, _p_FTDecayFunction1DTriangleTo_p_INamed, 0, 0},  {&_swigt__p_FTDistribution1DTriangle, _p_FTDistribution1DTriangleTo_p_INamed, 0, 0},  {&_swigt__p_RotationEuler, _p_RotationEulerTo_p_INamed, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_INode[] = {  {&_swigt__p_FormFactorBox, _p_FormFactorBoxTo_p_INode, 0, 0},  {&_swigt__p_IBackground, _p_IBackgroundTo_p_INode, 0, 0},  {&_swigt__p_ConstantBackground, _p_ConstantBackgroundTo_p_INode, 0, 0},  {&_swigt__p_PoissonNoiseBackground, _p_PoissonNoiseBackgroundTo_p_INode, 0, 0},  {&_swigt__p_FormFactorSphereGaussianRadius, _p_FormFactorSphereGaussianRadiusTo_p_INode, 0, 0},  {&_swigt__p_FormFactorSphereLogNormalRadius, _p_FormFactorSphereLogNormalRadiusTo_p_INode, 0, 0},  {&_swigt__p_MultiLayer, _p_MultiLayerTo_p_INode, 0, 0},  {&_swigt__p_ParticleDistribution, _p_ParticleDistributionTo_p_INode, 0, 0},  {&_swigt__p_FTDecayFunction1DGauss, _p_FTDecayFunction1DGaussTo_p_INode, 0, 0},  {&_swigt__p_FTDistribution1DGauss, _p_FTDistribution1DGaussTo_p_INode, 0, 0},  {&_swigt__p_InterferenceFunctionNone, _p_InterferenceFunctionNoneTo_p_INode, 0, 0},  {&_swigt__p_IDetector2D, _p_IDetector2DTo_p_INode, 0, 0},  {&_swigt__p_ILayout, _p_ILayoutTo_p_INode, 0, 0},  {&_swigt__p_ParticleLayout, _p_ParticleLayoutTo_p_INode, 0, 0},  {&_swigt__p_FormFactorHemiEllipsoid, _p_FormFactorHemiEllipsoidTo_p_INode, 0, 0},  {&_swigt__p_IntensityScaleAndShiftNormalizer, _p_IntensityScaleAndShiftNormalizerTo_p_INode, 0, 0},  {&_swigt__p_IntensityNormalizer, _p_IntensityNormalizerTo_p_INode, 0, 0},  {&_swigt__p_IIntensityNormalizer, _p_IIntensityNormalizerTo_p_INode, 0, 0},  {&_swigt__p_SphericalDetector, _p_SphericalDetectorTo_p_INode, 0, 0},  {&_swigt__p_IsGISAXSDetector, _p_IsGISAXSDetectorTo_p_INode, 0, 0},  {&_swigt__p_RectangularDetector, _p_RectangularDetectorTo_p_INode, 0, 0},  {&_swigt__p_IDetector, _p_IDetectorTo_p_INode, 0, 0},  {&_swigt__p_INode, 0, 0, 0},  {&_swigt__p_IPeakShape, _p_IPeakShapeTo_p_INode, 0, 0},  {&_swigt__p_GaussPeakShape, _p_GaussPeakShapeTo_p_INode, 0, 0},  {&_swigt__p_FormFactorPrism3, _p_FormFactorPrism3To_p_INode, 0, 0},  {&_swigt__p_DistributionTrapezoid, _p_DistributionTrapezoidTo_p_INode, 0, 0},  {&_swigt__p_FormFactorIcosahedron, _p_FormFactorIcosahedronTo_p_INode, 0, 0},  {&_swigt__p_FormFactorDodecahedron, _p_FormFactorDodecahedronTo_p_INode, 0, 0},  {&_swigt__p_FormFactorCuboctahedron, _p_FormFactorCuboctahedronTo_p_INode, 0, 0},  {&_swigt__p_FormFactorPolyhedron, _p_FormFactorPolyhedronTo_p_INode, 0, 0},  {&_swigt__p_FormFactorTetrahedron, _p_FormFactorTetrahedronTo_p_INode, 0, 0},  {&_swigt__p_FormFactorDebyeBueche, _p_FormFactorDebyeBuecheTo_p_INode, 0, 0},  {&_swigt__p_FormFactorPrism6, _p_FormFactorPrism6To_p_INode, 0, 0},  {&_swigt__p_Simulation, _p_SimulationTo_p_INode, 0, 0},  {&_swigt__p_GISASSimulation, _p_GISASSimulationTo_p_INode, 0, 0},  {&_swigt__p_OffSpecSimulation, _p_OffSpecSimulationTo_p_INode, 0, 0},  {&_swigt__p_DepthProbeSimulation, _p_DepthProbeSimulationTo_p_INode, 0, 0},  {&_swigt__p_SpecularSimulation, _p_SpecularSimulationTo_p_INode, 0, 0},  {&_swigt__p_FTDistribution2DCone, _p_FTDistribution2DConeTo_p_INode, 0, 0},  {&_swigt__p_ParticleCoreShell, _p_ParticleCoreShellTo_p_INode, 0, 0},  {&_swigt__p_FormFactorFullSphere, _p_FormFactorFullSphereTo_p_INode, 0, 0},  {&_swigt__p_FormFactorTruncatedSphere, _p_FormFactorTruncatedSphereTo_p_INode, 0, 0},  {&_swigt__p_IFormFactor, _p_IFormFactorTo_p_INode, 0, 0},  {&_swigt__p_FormFactorPolygonalSurface, _p_FormFactorPolygonalSurfaceTo_p_INode, 0, 0},  {&_swigt__p_ISample, _p_ISampleTo_p_INode, 0, 0},  {&_swigt__p_FormFactorLongBoxGauss, _p_FormFactorLongBoxGaussTo_p_INode, 0, 0},  {&_swigt__p_FormFactorPolygonalPrism, _p_FormFactorPolygonalPrismTo_p_INode, 0, 0},  {&_swigt__p_FitSuiteObjects, _p_FitSuiteObjectsTo_p_INode, 0, 0},  {&_swigt__p_FTDistribution2DGate, _p_FTDistribution2DGateTo_p_INode, 0, 0},  {&_swigt__p_DistributionLogNormal, _p_DistributionLogNormalTo_p_INode, 0, 0},  {&_swigt__p_Instrument, _p_InstrumentTo_p_INode, 0, 0},  {&_swigt__p_FTDistribution1DVoigt, _p_FTDistribution1DVoigtTo_p_INode, 0, 0},  {&_swigt__p_FTDecayFunction1DVoigt, _p_FTDecayFunction1DVoigtTo_p_INode, 0, 0},  {&_swigt__p_IdentityRotation, _p_IdentityRotationTo_p_INode, 0, 0},  {&_swigt__p_IRotation, _p_IRotationTo_p_INode, 0, 0},  {&_swigt__p_FormFactorTruncatedSpheroid, _p_FormFactorTruncatedSpheroidTo_p_INode, 0, 0},  {&_swigt__p_FormFactorFullSpheroid, _p_FormFactorFullSpheroidTo_p_INode, 0, 0},  {&_swigt__p_RotationX, _p_RotationXTo_p_INode, 0, 0},  {&_swigt__p_FormFactorTruncatedCube, _p_FormFactorTruncatedCubeTo_p_INode, 0, 0},  {&_swigt__p_RotationY, _p_RotationYTo_p_INode, 0, 0},  {&_swigt__p_FTDecayFunction2DGauss, _p_FTDecayFunction2DGaussTo_p_INode, 0, 0},  {&_swigt__p_FTDistribution2DGauss, _p_FTDistribution2DGaussTo_p_INode, 0, 0},  {&_swigt__p_RotationZ, _p_RotationZTo_p_INode, 0, 0},  {&_swigt__p_FormFactorGauss, _p_FormFactorGaussTo_p_INode, 0, 0},  {&_swigt__p_FormFactorLongRipple2Gauss, _p_FormFactorLongRipple2GaussTo_p_INode, 0, 0},  {&_swigt__p_IFormFactorBorn, _p_IFormFactorBornTo_p_INode, 0, 0},  {&_swigt__p_IDetectorResolution, _p_IDetectorResolutionTo_p_INode, 0, 0},  {&_swigt__p_IClusteredParticles, _p_IClusteredParticlesTo_p_INode, 0, 0},  {&_swigt__p_IAbstractParticle, _p_IAbstractParticleTo_p_INode, 0, 0},  {&_swigt__p_IParticle, _p_IParticleTo_p_INode, 0, 0},  {&_swigt__p_Particle, _p_ParticleTo_p_INode, 0, 0},  {&_swigt__p_Lattice2D, _p_Lattice2DTo_p_INode, 0, 0},  {&_swigt__p_DistributionGate, _p_DistributionGateTo_p_INode, 0, 0},  {&_swigt__p_IDistribution1D, _p_IDistribution1DTo_p_INode, 0, 0},  {&_swigt__p_IFTDecayFunction1D, _p_IFTDecayFunction1DTo_p_INode, 0, 0},  {&_swigt__p_IFTDistribution1D, _p_IFTDistribution1DTo_p_INode, 0, 0},  {&_swigt__p_FormFactorCone, _p_FormFactorConeTo_p_INode, 0, 0},  {&_swigt__p_FormFactorRipple1, _p_FormFactorRipple1To_p_INode, 0, 0},  {&_swigt__p_Layer, _p_LayerTo_p_INode, 0, 0},  {&_swigt__p_FormFactorPyramid, _p_FormFactorPyramidTo_p_INode, 0, 0},  {&_swigt__p_FormFactorAnisoPyramid, _p_FormFactorAnisoPyramidTo_p_INode, 0, 0},  {&_swigt__p_FormFactorDecoratorDebyeWaller, _p_FormFactorDecoratorDebyeWallerTo_p_INode, 0, 0},  {&_swigt__p_FormFactorRipple2, _p_FormFactorRipple2To_p_INode, 0, 0},  {&_swigt__p_FormFactorEllipsoidalCylinder, _p_FormFactorEllipsoidalCylinderTo_p_INode, 0, 0},  {&_swigt__p_FormFactorCylinder, _p_FormFactorCylinderTo_p_INode, 0, 0},  {&_swigt__p_DistributionGaussian, _p_DistributionGaussianTo_p_INode, 0, 0},  {&_swigt__p_FootprintFactorGaussian, _p_FootprintFactorGaussianTo_p_INode, 0, 0},  {&_swigt__p_ResolutionFunction2DGaussian, _p_ResolutionFunction2DGaussianTo_p_INode, 0, 0},  {&_swigt__p_IFootprintFactor, _p_IFootprintFactorTo_p_INode, 0, 0},  {&_swigt__p_ParticleComposition, _p_ParticleCompositionTo_p_INode, 0, 0},  {&_swigt__p_FormFactorSphereUniformRadius, _p_FormFactorSphereUniformRadiusTo_p_INode, 0, 0},  {&_swigt__p_DistributionCosine, _p_DistributionCosineTo_p_INode, 0, 0},  {&_swigt__p_FTDistribution1DCosine, _p_FTDistribution1DCosineTo_p_INode, 0, 0},  {&_swigt__p_FTDistribution1DGate, _p_FTDistribution1DGateTo_p_INode, 0, 0},  {&_swigt__p_FTDistribution2DVoigt, _p_FTDistribution2DVoigtTo_p_INode, 0, 0},  {&_swigt__p_FTDecayFunction2DVoigt, _p_FTDecayFunction2DVoigtTo_p_INode, 0, 0},  {&_swigt__p_FTDecayFunction1DCauchy, _p_FTDecayFunction1DCauchyTo_p_INode, 0, 0},  {&_swigt__p_FTDistribution1DCauchy, _p_FTDistribution1DCauchyTo_p_INode, 0, 0},  {&_swigt__p_FTDecayFunction2DCauchy, _p_FTDecayFunction2DCauchyTo_p_INode, 0, 0},  {&_swigt__p_FTDistribution2DCauchy, _p_FTDistribution2DCauchyTo_p_INode, 0, 0},  {&_swigt__p_IInterferenceFunction, _p_IInterferenceFunctionTo_p_INode, 0, 0},  {&_swigt__p_FootprintFactorSquare, _p_FootprintFactorSquareTo_p_INode, 0, 0},  {&_swigt__p_FitObject, _p_FitObjectTo_p_INode, 0, 0},  {&_swigt__p_FormFactorCone6, _p_FormFactorCone6To_p_INode, 0, 0},  {&_swigt__p_FormFactorLongRipple1Gauss, _p_FormFactorLongRipple1GaussTo_p_INode, 0, 0},  {&_swigt__p_Beam, _p_BeamTo_p_INode, 0, 0},  {&_swigt__p_IFormFactorDecorator, _p_IFormFactorDecoratorTo_p_INode, 0, 0},  {&_swigt__p_FormFactorOrnsteinZernike, _p_FormFactorOrnsteinZernikeTo_p_INode, 0, 0},  {&_swigt__p_FormFactorDot, _p_FormFactorDotTo_p_INode, 0, 0},  {&_swigt__p_LayerRoughness, _p_LayerRoughnessTo_p_INode, 0, 0},  {&_swigt__p_FormFactorCrystal, _p_FormFactorCrystalTo_p_INode, 0, 0},  {&_swigt__p_Crystal, _p_CrystalTo_p_INode, 0, 0},  {&_swigt__p_MesoCrystal, _p_MesoCrystalTo_p_INode, 0, 0},  {&_swigt__p_InterferenceFunctionRadialParaCrystal, _p_InterferenceFunctionRadialParaCrystalTo_p_INode, 0, 0},  {&_swigt__p_InterferenceFunction2DParaCrystal, _p_InterferenceFunction2DParaCrystalTo_p_INode, 0, 0},  {&_swigt__p_Simulation2D, _p_Simulation2DTo_p_INode, 0, 0},  {&_swigt__p_IFTDecayFunction2D, _p_IFTDecayFunction2DTo_p_INode, 0, 0},  {&_swigt__p_IFTDistribution2D, _p_IFTDistribution2DTo_p_INode, 0, 0},  {&_swigt__p_IResolutionFunction2D, _p_IResolutionFunction2DTo_p_INode, 0, 0},  {&_swigt__p_FormFactorWeighted, _p_FormFactorWeightedTo_p_INode, 0, 0},  {&_swigt__p_FormFactorLorentz, _p_FormFactorLorentzTo_p_INode, 0, 0},  {&_swigt__p_FormFactorLongRipple2Lorentz, _p_FormFactorLongRipple2LorentzTo_p_INode, 0, 0},  {&_swigt__p_FormFactorLongRipple1Lorentz, _p_FormFactorLongRipple1LorentzTo_p_INode, 0, 0},  {&_swigt__p_FormFactorLongBoxLorentz, _p_FormFactorLongBoxLorentzTo_p_INode, 0, 0},  {&_swigt__p_InterferenceFunction1DLattice, _p_InterferenceFunction1DLatticeTo_p_INode, 0, 0},  {&_swigt__p_InterferenceFunction2DLattice, _p_InterferenceFunction2DLatticeTo_p_INode, 0, 0},  {&_swigt__p_InterferenceFunction3DLattice, _p_InterferenceFunction3DLatticeTo_p_INode, 0, 0},  {&_swigt__p_InterferenceFunctionFinite2DLattice, _p_InterferenceFunctionFinite2DLatticeTo_p_INode, 0, 0},  {&_swigt__p_InterferenceFunction2DSuperLattice, _p_InterferenceFunction2DSuperLatticeTo_p_INode, 0, 0},  {&_swigt__p_BasicLattice, _p_BasicLatticeTo_p_INode, 0, 0},  {&_swigt__p_SquareLattice, _p_SquareLatticeTo_p_INode, 0, 0},  {&_swigt__p_HexagonalLattice, _p_HexagonalLatticeTo_p_INode, 0, 0},  {&_swigt__p_DistributionLorentz, _p_DistributionLorentzTo_p_INode, 0, 0},  {&_swigt__p_Lattice, _p_LatticeTo_p_INode, 0, 0},  {&_swigt__p_FTDecayFunction1DTriangle, _p_FTDecayFunction1DTriangleTo_p_INode, 0, 0},  {&_swigt__p_FTDistribution1DTriangle, _p_FTDistribution1DTriangleTo_p_INode, 0, 0},  {&_swigt__p_RotationEuler, _p_RotationEulerTo_p_INode, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_INamed[] = {  {&_swigt__p_FormFactorBox, _p_FormFactorBoxTo_p_INamed, 0, 0},  {&_swigt__p_IBackground, _p_IBackgroundTo_p_INamed, 0, 0},  {&_swigt__p_ConstantBackground, _p_ConstantBackgroundTo_p_INamed, 0, 0},  {&_swigt__p_PoissonNoiseBackground, _p_PoissonNoiseBackgroundTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorSphereGaussianRadius, _p_FormFactorSphereGaussianRadiusTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorSphereLogNormalRadius, _p_FormFactorSphereLogNormalRadiusTo_p_INamed, 0, 0},  {&_swigt__p_MultiLayer, _p_MultiLayerTo_p_INamed, 0, 0},  {&_swigt__p_ParameterDistribution, _p_ParameterDistributionTo_p_INamed, 0, 0},  {&_swigt__p_ParticleDistribution, _p_ParticleDistributionTo_p_INamed, 0, 0},  {&_swigt__p_FTDecayFunction1DGauss, _p_FTDecayFunction1DGaussTo_p_INamed, 0, 0},  {&_swigt__p_FTDistribution1DGauss, _p_FTDistribution1DGaussTo_p_INamed, 0, 0},  {&_swigt__p_InterferenceFunctionNone, _p_InterferenceFunctionNoneTo_p_INamed, 0, 0},  {&_swigt__p_Polygon, _p_PolygonTo_p_INamed, 0, 0},  {&_swigt__p_IDetector2D, _p_IDetector2DTo_p_INamed, 0, 0},  {&_swigt__p_Ellipse, _p_EllipseTo_p_INamed, 0, 0},  {&_swigt__p_ILayout, _p_ILayoutTo_p_INamed, 0, 0},  {&_swigt__p_ParticleLayout, _p_ParticleLayoutTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorHemiEllipsoid, _p_FormFactorHemiEllipsoidTo_p_INamed, 0, 0},  {&_swigt__p_IntensityScaleAndShiftNormalizer, _p_IntensityScaleAndShiftNormalizerTo_p_INamed, 0, 0},  {&_swigt__p_IntensityNormalizer, _p_IntensityNormalizerTo_p_INamed, 0, 0},  {&_swigt__p_IIntensityNormalizer, _p_IIntensityNormalizerTo_p_INamed, 0, 0},  {&_swigt__p_HorizontalLine, _p_HorizontalLineTo_p_INamed, 0, 0},  {&_swigt__p_SphericalDetector, _p_SphericalDetectorTo_p_INamed, 0, 0},  {&_swigt__p_IsGISAXSDetector, _p_IsGISAXSDetectorTo_p_INamed, 0, 0},  {&_swigt__p_RectangularDetector, _p_RectangularDetectorTo_p_INamed, 0, 0},  {&_swigt__p_IDetector, _p_IDetectorTo_p_INamed, 0, 0},  {&_swigt__p_INode, _p_INodeTo_p_INamed, 0, 0},  {&_swigt__p_IPeakShape, _p_IPeakShapeTo_p_INamed, 0, 0},  {&_swigt__p_IsotropicGaussPeakShape, _p_IsotropicGaussPeakShapeTo_p_INamed, 0, 0},  {&_swigt__p_IsotropicLorentzPeakShape, _p_IsotropicLorentzPeakShapeTo_p_INamed, 0, 0},  {&_swigt__p_GaussFisherPeakShape, _p_GaussFisherPeakShapeTo_p_INamed, 0, 0},  {&_swigt__p_LorentzFisherPeakShape, _p_LorentzFisherPeakShapeTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorPrism3, _p_FormFactorPrism3To_p_INamed, 0, 0},  {&_swigt__p_DistributionTrapezoid, _p_DistributionTrapezoidTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorPolyhedron, _p_FormFactorPolyhedronTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorCuboctahedron, _p_FormFactorCuboctahedronTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorDodecahedron, _p_FormFactorDodecahedronTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorIcosahedron, _p_FormFactorIcosahedronTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorTetrahedron, _p_FormFactorTetrahedronTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorDebyeBueche, _p_FormFactorDebyeBuecheTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorPrism6, _p_FormFactorPrism6To_p_INamed, 0, 0},  {&_swigt__p_Simulation, _p_SimulationTo_p_INamed, 0, 0},  {&_swigt__p_GISASSimulation, _p_GISASSimulationTo_p_INamed, 0, 0},  {&_swigt__p_OffSpecSimulation, _p_OffSpecSimulationTo_p_INamed, 0, 0},  {&_swigt__p_DepthProbeSimulation, _p_DepthProbeSimulationTo_p_INamed, 0, 0},  {&_swigt__p_SpecularSimulation, _p_SpecularSimulationTo_p_INamed, 0, 0},  {&_swigt__p_FTDistribution2DCone, _p_FTDistribution2DConeTo_p_INamed, 0, 0},  {&_swigt__p_ParticleCoreShell, _p_ParticleCoreShellTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorFullSphere, _p_FormFactorFullSphereTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorTruncatedSphere, _p_FormFactorTruncatedSphereTo_p_INamed, 0, 0},  {&_swigt__p_IFormFactor, _p_IFormFactorTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorPolygonalSurface, _p_FormFactorPolygonalSurfaceTo_p_INamed, 0, 0},  {&_swigt__p_ISample, _p_ISampleTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorLongBoxGauss, _p_FormFactorLongBoxGaussTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorPolygonalPrism, _p_FormFactorPolygonalPrismTo_p_INamed, 0, 0},  {&_swigt__p_FTDistribution2DGate, _p_FTDistribution2DGateTo_p_INamed, 0, 0},  {&_swigt__p_DistributionLogNormal, _p_DistributionLogNormalTo_p_INamed, 0, 0},  {&_swigt__p_Instrument, _p_InstrumentTo_p_INamed, 0, 0},  {&_swigt__p_FTDistribution1DVoigt, _p_FTDistribution1DVoigtTo_p_INamed, 0, 0},  {&_swigt__p_FTDecayFunction1DVoigt, _p_FTDecayFunction1DVoigtTo_p_INamed, 0, 0},  {&_swigt__p_IdentityRotation, _p_IdentityRotationTo_p_INamed, 0, 0},  {&_swigt__p_IRotation, _p_IRotationTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorTruncatedSpheroid, _p_FormFactorTruncatedSpheroidTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorFullSpheroid, _p_FormFactorFullSpheroidTo_p_INamed, 0, 0},  {&_swigt__p_RotationX, _p_RotationXTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorTruncatedCube, _p_FormFactorTruncatedCubeTo_p_INamed, 0, 0},  {&_swigt__p_RotationY, _p_RotationYTo_p_INamed, 0, 0},  {&_swigt__p_FTDistribution2DGauss, _p_FTDistribution2DGaussTo_p_INamed, 0, 0},  {&_swigt__p_FTDecayFunction2DGauss, _p_FTDecayFunction2DGaussTo_p_INamed, 0, 0},  {&_swigt__p_IShape2D, _p_IShape2DTo_p_INamed, 0, 0},  {&_swigt__p_RotationZ, _p_RotationZTo_p_INamed, 0, 0},  {&_swigt__p_Rectangle, _p_RectangleTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorLongRipple2Gauss, _p_FormFactorLongRipple2GaussTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorGauss, _p_FormFactorGaussTo_p_INamed, 0, 0},  {&_swigt__p_VerticalLine, _p_VerticalLineTo_p_INamed, 0, 0},  {&_swigt__p_IFormFactorBorn, _p_IFormFactorBornTo_p_INamed, 0, 0},  {&_swigt__p_IDetectorResolution, _p_IDetectorResolutionTo_p_INamed, 0, 0},  {&_swigt__p_IClusteredParticles, _p_IClusteredParticlesTo_p_INamed, 0, 0},  {&_swigt__p_IMultiLayerBuilder, _p_IMultiLayerBuilderTo_p_INamed, 0, 0},  {&_swigt__p_Particle, _p_ParticleTo_p_INamed, 0, 0},  {&_swigt__p_IAbstractParticle, _p_IAbstractParticleTo_p_INamed, 0, 0},  {&_swigt__p_IParticle, _p_IParticleTo_p_INamed, 0, 0},  {&_swigt__p_Lattice2D, _p_Lattice2DTo_p_INamed, 0, 0},  {&_swigt__p_INamed, 0, 0, 0},  {&_swigt__p_DistributionGate, _p_DistributionGateTo_p_INamed, 0, 0},  {&_swigt__p_IDistribution1D, _p_IDistribution1DTo_p_INamed, 0, 0},  {&_swigt__p_IFTDecayFunction1D, _p_IFTDecayFunction1DTo_p_INamed, 0, 0},  {&_swigt__p_IFTDistribution1D, _p_IFTDistribution1DTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorCone, _p_FormFactorConeTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorRipple1, _p_FormFactorRipple1To_p_INamed, 0, 0},  {&_swigt__p_Layer, _p_LayerTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorPyramid, _p_FormFactorPyramidTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorAnisoPyramid, _p_FormFactorAnisoPyramidTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorDecoratorDebyeWaller, _p_FormFactorDecoratorDebyeWallerTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorRipple2, _p_FormFactorRipple2To_p_INamed, 0, 0},  {&_swigt__p_FormFactorEllipsoidalCylinder, _p_FormFactorEllipsoidalCylinderTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorCylinder, _p_FormFactorCylinderTo_p_INamed, 0, 0},  {&_swigt__p_IParameterT_double_t, _p_IParameterT_double_tTo_p_INamed, 0, 0},  {&_swigt__p_DistributionGaussian, _p_DistributionGaussianTo_p_INamed, 0, 0},  {&_swigt__p_FootprintFactorGaussian, _p_FootprintFactorGaussianTo_p_INamed, 0, 0},  {&_swigt__p_ResolutionFunction2DGaussian, _p_ResolutionFunction2DGaussianTo_p_INamed, 0, 0},  {&_swigt__p_IFootprintFactor, _p_IFootprintFactorTo_p_INamed, 0, 0},  {&_swigt__p_ParticleComposition, _p_ParticleCompositionTo_p_INamed, 0, 0},  {&_swigt__p_Line, _p_LineTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorSphereUniformRadius, _p_FormFactorSphereUniformRadiusTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorLongBox, _p_FormFactorLongBoxTo_p_INamed, 0, 0},  {&_swigt__p_DistributionCosine, _p_DistributionCosineTo_p_INamed, 0, 0},  {&_swigt__p_FTDistribution1DCosine, _p_FTDistribution1DCosineTo_p_INamed, 0, 0},  {&_swigt__p_FTDistribution1DGate, _p_FTDistribution1DGateTo_p_INamed, 0, 0},  {&_swigt__p_FTDistribution2DVoigt, _p_FTDistribution2DVoigtTo_p_INamed, 0, 0},  {&_swigt__p_FTDecayFunction2DVoigt, _p_FTDecayFunction2DVoigtTo_p_INamed, 0, 0},  {&_swigt__p_FTDecayFunction1DCauchy, _p_FTDecayFunction1DCauchyTo_p_INamed, 0, 0},  {&_swigt__p_FTDistribution1DCauchy, _p_FTDistribution1DCauchyTo_p_INamed, 0, 0},  {&_swigt__p_FTDecayFunction2DCauchy, _p_FTDecayFunction2DCauchyTo_p_INamed, 0, 0},  {&_swigt__p_FTDistribution2DCauchy, _p_FTDistribution2DCauchyTo_p_INamed, 0, 0},  {&_swigt__p_IInterferenceFunction, _p_IInterferenceFunctionTo_p_INamed, 0, 0},  {&_swigt__p_FootprintFactorSquare, _p_FootprintFactorSquareTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorCone6, _p_FormFactorCone6To_p_INamed, 0, 0},  {&_swigt__p_FormFactorLongRipple1Gauss, _p_FormFactorLongRipple1GaussTo_p_INamed, 0, 0},  {&_swigt__p_Beam, _p_BeamTo_p_INamed, 0, 0},  {&_swigt__p_IFormFactorDecorator, _p_IFormFactorDecoratorTo_p_INamed, 0, 0},  {&_swigt__p_IParameterized, _p_IParameterizedTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorOrnsteinZernike, _p_FormFactorOrnsteinZernikeTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorDot, _p_FormFactorDotTo_p_INamed, 0, 0},  {&_swigt__p_LayerRoughness, _p_LayerRoughnessTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorCrystal, _p_FormFactorCrystalTo_p_INamed, 0, 0},  {&_swigt__p_Crystal, _p_CrystalTo_p_INamed, 0, 0},  {&_swigt__p_MesoCrystal, _p_MesoCrystalTo_p_INamed, 0, 0},  {&_swigt__p_InterferenceFunction2DParaCrystal, _p_InterferenceFunction2DParaCrystalTo_p_INamed, 0, 0},  {&_swigt__p_InterferenceFunctionRadialParaCrystal, _p_InterferenceFunctionRadialParaCrystalTo_p_INamed, 0, 0},  {&_swigt__p_Simulation2D, _p_Simulation2DTo_p_INamed, 0, 0},  {&_swigt__p_IFTDecayFunction2D, _p_IFTDecayFunction2DTo_p_INamed, 0, 0},  {&_swigt__p_IFTDistribution2D, _p_IFTDistribution2DTo_p_INamed, 0, 0},  {&_swigt__p_IResolutionFunction2D, _p_IResolutionFunction2DTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorWeighted, _p_FormFactorWeightedTo_p_INamed, 0, 0},  {&_swigt__p_RealParameter, _p_RealParameterTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorLongBoxLorentz, _p_FormFactorLongBoxLorentzTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorLongRipple1Lorentz, _p_FormFactorLongRipple1LorentzTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorLongRipple2Lorentz, _p_FormFactorLongRipple2LorentzTo_p_INamed, 0, 0},  {&_swigt__p_FormFactorLorentz, _p_FormFactorLorentzTo_p_INamed, 0, 0},  {&_swigt__p_InterferenceFunction1DLattice, _p_InterferenceFunction1DLatticeTo_p_INamed, 0, 0},  {&_swigt__p_InterferenceFunction2DLattice, _p_InterferenceFunction2DLatticeTo_p_INamed, 0, 0},  {&_swigt__p_InterferenceFunction2DSuperLattice, _p_InterferenceFunction2DSuperLatticeTo_p_INamed, 0, 0},  {&_swigt__p_InterferenceFunction3DLattice, _p_InterferenceFunction3DLatticeTo_p_INamed, 0, 0},  {&_swigt__p_InterferenceFunctionFinite2DLattice, _p_InterferenceFunctionFinite2DLatticeTo_p_INamed, 0, 0},  {&_swigt__p_InterferenceFunctionFinite3DLattice, _p_InterferenceFunctionFinite3DLatticeTo_p_INamed, 0, 0},  {&_swigt__p_BasicLattice, _p_BasicLatticeTo_p_INamed, 0, 0},  {&_swigt__p_SquareLattice, _p_SquareLatticeTo_p_INamed, 0, 0},  {&_swigt__p_HexagonalLattice, _p_HexagonalLatticeTo_p_INamed, 0, 0},  {&_swigt__p_DistributionLorentz, _p_DistributionLorentzTo_p_INamed, 0, 0},  {&_swigt__p_Lattice, _p_LatticeTo_p_INamed, 0, 0},  {&_swigt__p_FTDecayFunction1DTriangle, _p_FTDecayFunction1DTriangleTo_p_INamed, 0, 0},  {&_swigt__p_FTDistribution1DTriangle, _p_FTDistribution1DTriangleTo_p_INamed, 0, 0},  {&_swigt__p_RotationEuler, _p_RotationEulerTo_p_INamed, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_INode[] = {  {&_swigt__p_FormFactorBox, _p_FormFactorBoxTo_p_INode, 0, 0},  {&_swigt__p_IBackground, _p_IBackgroundTo_p_INode, 0, 0},  {&_swigt__p_ConstantBackground, _p_ConstantBackgroundTo_p_INode, 0, 0},  {&_swigt__p_PoissonNoiseBackground, _p_PoissonNoiseBackgroundTo_p_INode, 0, 0},  {&_swigt__p_FormFactorSphereGaussianRadius, _p_FormFactorSphereGaussianRadiusTo_p_INode, 0, 0},  {&_swigt__p_FormFactorSphereLogNormalRadius, _p_FormFactorSphereLogNormalRadiusTo_p_INode, 0, 0},  {&_swigt__p_MultiLayer, _p_MultiLayerTo_p_INode, 0, 0},  {&_swigt__p_ParticleDistribution, _p_ParticleDistributionTo_p_INode, 0, 0},  {&_swigt__p_FTDecayFunction1DGauss, _p_FTDecayFunction1DGaussTo_p_INode, 0, 0},  {&_swigt__p_FTDistribution1DGauss, _p_FTDistribution1DGaussTo_p_INode, 0, 0},  {&_swigt__p_InterferenceFunctionNone, _p_InterferenceFunctionNoneTo_p_INode, 0, 0},  {&_swigt__p_IDetector2D, _p_IDetector2DTo_p_INode, 0, 0},  {&_swigt__p_ILayout, _p_ILayoutTo_p_INode, 0, 0},  {&_swigt__p_ParticleLayout, _p_ParticleLayoutTo_p_INode, 0, 0},  {&_swigt__p_FormFactorHemiEllipsoid, _p_FormFactorHemiEllipsoidTo_p_INode, 0, 0},  {&_swigt__p_IntensityScaleAndShiftNormalizer, _p_IntensityScaleAndShiftNormalizerTo_p_INode, 0, 0},  {&_swigt__p_IntensityNormalizer, _p_IntensityNormalizerTo_p_INode, 0, 0},  {&_swigt__p_IIntensityNormalizer, _p_IIntensityNormalizerTo_p_INode, 0, 0},  {&_swigt__p_SphericalDetector, _p_SphericalDetectorTo_p_INode, 0, 0},  {&_swigt__p_IsGISAXSDetector, _p_IsGISAXSDetectorTo_p_INode, 0, 0},  {&_swigt__p_RectangularDetector, _p_RectangularDetectorTo_p_INode, 0, 0},  {&_swigt__p_IDetector, _p_IDetectorTo_p_INode, 0, 0},  {&_swigt__p_INode, 0, 0, 0},  {&_swigt__p_IPeakShape, _p_IPeakShapeTo_p_INode, 0, 0},  {&_swigt__p_IsotropicGaussPeakShape, _p_IsotropicGaussPeakShapeTo_p_INode, 0, 0},  {&_swigt__p_IsotropicLorentzPeakShape, _p_IsotropicLorentzPeakShapeTo_p_INode, 0, 0},  {&_swigt__p_GaussFisherPeakShape, _p_GaussFisherPeakShapeTo_p_INode, 0, 0},  {&_swigt__p_LorentzFisherPeakShape, _p_LorentzFisherPeakShapeTo_p_INode, 0, 0},  {&_swigt__p_FormFactorPrism3, _p_FormFactorPrism3To_p_INode, 0, 0},  {&_swigt__p_DistributionTrapezoid, _p_DistributionTrapezoidTo_p_INode, 0, 0},  {&_swigt__p_FormFactorPolyhedron, _p_FormFactorPolyhedronTo_p_INode, 0, 0},  {&_swigt__p_FormFactorTetrahedron, _p_FormFactorTetrahedronTo_p_INode, 0, 0},  {&_swigt__p_FormFactorIcosahedron, _p_FormFactorIcosahedronTo_p_INode, 0, 0},  {&_swigt__p_FormFactorDodecahedron, _p_FormFactorDodecahedronTo_p_INode, 0, 0},  {&_swigt__p_FormFactorCuboctahedron, _p_FormFactorCuboctahedronTo_p_INode, 0, 0},  {&_swigt__p_FormFactorDebyeBueche, _p_FormFactorDebyeBuecheTo_p_INode, 0, 0},  {&_swigt__p_FormFactorPrism6, _p_FormFactorPrism6To_p_INode, 0, 0},  {&_swigt__p_Simulation, _p_SimulationTo_p_INode, 0, 0},  {&_swigt__p_GISASSimulation, _p_GISASSimulationTo_p_INode, 0, 0},  {&_swigt__p_OffSpecSimulation, _p_OffSpecSimulationTo_p_INode, 0, 0},  {&_swigt__p_DepthProbeSimulation, _p_DepthProbeSimulationTo_p_INode, 0, 0},  {&_swigt__p_SpecularSimulation, _p_SpecularSimulationTo_p_INode, 0, 0},  {&_swigt__p_FTDistribution2DCone, _p_FTDistribution2DConeTo_p_INode, 0, 0},  {&_swigt__p_ParticleCoreShell, _p_ParticleCoreShellTo_p_INode, 0, 0},  {&_swigt__p_FormFactorFullSphere, _p_FormFactorFullSphereTo_p_INode, 0, 0},  {&_swigt__p_FormFactorTruncatedSphere, _p_FormFactorTruncatedSphereTo_p_INode, 0, 0},  {&_swigt__p_IFormFactor, _p_IFormFactorTo_p_INode, 0, 0},  {&_swigt__p_FormFactorPolygonalSurface, _p_FormFactorPolygonalSurfaceTo_p_INode, 0, 0},  {&_swigt__p_ISample, _p_ISampleTo_p_INode, 0, 0},  {&_swigt__p_FormFactorLongBoxGauss, _p_FormFactorLongBoxGaussTo_p_INode, 0, 0},  {&_swigt__p_FormFactorPolygonalPrism, _p_FormFactorPolygonalPrismTo_p_INode, 0, 0},  {&_swigt__p_FTDistribution2DGate, _p_FTDistribution2DGateTo_p_INode, 0, 0},  {&_swigt__p_DistributionLogNormal, _p_DistributionLogNormalTo_p_INode, 0, 0},  {&_swigt__p_Instrument, _p_InstrumentTo_p_INode, 0, 0},  {&_swigt__p_FTDistribution1DVoigt, _p_FTDistribution1DVoigtTo_p_INode, 0, 0},  {&_swigt__p_FTDecayFunction1DVoigt, _p_FTDecayFunction1DVoigtTo_p_INode, 0, 0},  {&_swigt__p_IdentityRotation, _p_IdentityRotationTo_p_INode, 0, 0},  {&_swigt__p_IRotation, _p_IRotationTo_p_INode, 0, 0},  {&_swigt__p_FormFactorTruncatedSpheroid, _p_FormFactorTruncatedSpheroidTo_p_INode, 0, 0},  {&_swigt__p_FormFactorFullSpheroid, _p_FormFactorFullSpheroidTo_p_INode, 0, 0},  {&_swigt__p_RotationX, _p_RotationXTo_p_INode, 0, 0},  {&_swigt__p_FormFactorTruncatedCube, _p_FormFactorTruncatedCubeTo_p_INode, 0, 0},  {&_swigt__p_RotationY, _p_RotationYTo_p_INode, 0, 0},  {&_swigt__p_FTDistribution2DGauss, _p_FTDistribution2DGaussTo_p_INode, 0, 0},  {&_swigt__p_FTDecayFunction2DGauss, _p_FTDecayFunction2DGaussTo_p_INode, 0, 0},  {&_swigt__p_RotationZ, _p_RotationZTo_p_INode, 0, 0},  {&_swigt__p_FormFactorLongRipple2Gauss, _p_FormFactorLongRipple2GaussTo_p_INode, 0, 0},  {&_swigt__p_FormFactorGauss, _p_FormFactorGaussTo_p_INode, 0, 0},  {&_swigt__p_IFormFactorBorn, _p_IFormFactorBornTo_p_INode, 0, 0},  {&_swigt__p_IDetectorResolution, _p_IDetectorResolutionTo_p_INode, 0, 0},  {&_swigt__p_IClusteredParticles, _p_IClusteredParticlesTo_p_INode, 0, 0},  {&_swigt__p_Particle, _p_ParticleTo_p_INode, 0, 0},  {&_swigt__p_IAbstractParticle, _p_IAbstractParticleTo_p_INode, 0, 0},  {&_swigt__p_IParticle, _p_IParticleTo_p_INode, 0, 0},  {&_swigt__p_Lattice2D, _p_Lattice2DTo_p_INode, 0, 0},  {&_swigt__p_DistributionGate, _p_DistributionGateTo_p_INode, 0, 0},  {&_swigt__p_IDistribution1D, _p_IDistribution1DTo_p_INode, 0, 0},  {&_swigt__p_IFTDecayFunction1D, _p_IFTDecayFunction1DTo_p_INode, 0, 0},  {&_swigt__p_IFTDistribution1D, _p_IFTDistribution1DTo_p_INode, 0, 0},  {&_swigt__p_FormFactorCone, _p_FormFactorConeTo_p_INode, 0, 0},  {&_swigt__p_FormFactorRipple1, _p_FormFactorRipple1To_p_INode, 0, 0},  {&_swigt__p_Layer, _p_LayerTo_p_INode, 0, 0},  {&_swigt__p_FormFactorPyramid, _p_FormFactorPyramidTo_p_INode, 0, 0},  {&_swigt__p_FormFactorAnisoPyramid, _p_FormFactorAnisoPyramidTo_p_INode, 0, 0},  {&_swigt__p_FormFactorDecoratorDebyeWaller, _p_FormFactorDecoratorDebyeWallerTo_p_INode, 0, 0},  {&_swigt__p_FormFactorRipple2, _p_FormFactorRipple2To_p_INode, 0, 0},  {&_swigt__p_FormFactorEllipsoidalCylinder, _p_FormFactorEllipsoidalCylinderTo_p_INode, 0, 0},  {&_swigt__p_FormFactorCylinder, _p_FormFactorCylinderTo_p_INode, 0, 0},  {&_swigt__p_DistributionGaussian, _p_DistributionGaussianTo_p_INode, 0, 0},  {&_swigt__p_FootprintFactorGaussian, _p_FootprintFactorGaussianTo_p_INode, 0, 0},  {&_swigt__p_ResolutionFunction2DGaussian, _p_ResolutionFunction2DGaussianTo_p_INode, 0, 0},  {&_swigt__p_IFootprintFactor, _p_IFootprintFactorTo_p_INode, 0, 0},  {&_swigt__p_ParticleComposition, _p_ParticleCompositionTo_p_INode, 0, 0},  {&_swigt__p_FormFactorSphereUniformRadius, _p_FormFactorSphereUniformRadiusTo_p_INode, 0, 0},  {&_swigt__p_FormFactorLongBox, _p_FormFactorLongBoxTo_p_INode, 0, 0},  {&_swigt__p_DistributionCosine, _p_DistributionCosineTo_p_INode, 0, 0},  {&_swigt__p_FTDistribution1DCosine, _p_FTDistribution1DCosineTo_p_INode, 0, 0},  {&_swigt__p_FTDistribution1DGate, _p_FTDistribution1DGateTo_p_INode, 0, 0},  {&_swigt__p_FTDistribution2DVoigt, _p_FTDistribution2DVoigtTo_p_INode, 0, 0},  {&_swigt__p_FTDecayFunction2DVoigt, _p_FTDecayFunction2DVoigtTo_p_INode, 0, 0},  {&_swigt__p_FTDecayFunction1DCauchy, _p_FTDecayFunction1DCauchyTo_p_INode, 0, 0},  {&_swigt__p_FTDistribution1DCauchy, _p_FTDistribution1DCauchyTo_p_INode, 0, 0},  {&_swigt__p_FTDecayFunction2DCauchy, _p_FTDecayFunction2DCauchyTo_p_INode, 0, 0},  {&_swigt__p_FTDistribution2DCauchy, _p_FTDistribution2DCauchyTo_p_INode, 0, 0},  {&_swigt__p_IInterferenceFunction, _p_IInterferenceFunctionTo_p_INode, 0, 0},  {&_swigt__p_FootprintFactorSquare, _p_FootprintFactorSquareTo_p_INode, 0, 0},  {&_swigt__p_FormFactorCone6, _p_FormFactorCone6To_p_INode, 0, 0},  {&_swigt__p_FormFactorLongRipple1Gauss, _p_FormFactorLongRipple1GaussTo_p_INode, 0, 0},  {&_swigt__p_Beam, _p_BeamTo_p_INode, 0, 0},  {&_swigt__p_IFormFactorDecorator, _p_IFormFactorDecoratorTo_p_INode, 0, 0},  {&_swigt__p_FormFactorOrnsteinZernike, _p_FormFactorOrnsteinZernikeTo_p_INode, 0, 0},  {&_swigt__p_FormFactorDot, _p_FormFactorDotTo_p_INode, 0, 0},  {&_swigt__p_LayerRoughness, _p_LayerRoughnessTo_p_INode, 0, 0},  {&_swigt__p_FormFactorCrystal, _p_FormFactorCrystalTo_p_INode, 0, 0},  {&_swigt__p_Crystal, _p_CrystalTo_p_INode, 0, 0},  {&_swigt__p_MesoCrystal, _p_MesoCrystalTo_p_INode, 0, 0},  {&_swigt__p_InterferenceFunction2DParaCrystal, _p_InterferenceFunction2DParaCrystalTo_p_INode, 0, 0},  {&_swigt__p_InterferenceFunctionRadialParaCrystal, _p_InterferenceFunctionRadialParaCrystalTo_p_INode, 0, 0},  {&_swigt__p_Simulation2D, _p_Simulation2DTo_p_INode, 0, 0},  {&_swigt__p_IFTDecayFunction2D, _p_IFTDecayFunction2DTo_p_INode, 0, 0},  {&_swigt__p_IFTDistribution2D, _p_IFTDistribution2DTo_p_INode, 0, 0},  {&_swigt__p_IResolutionFunction2D, _p_IResolutionFunction2DTo_p_INode, 0, 0},  {&_swigt__p_FormFactorWeighted, _p_FormFactorWeightedTo_p_INode, 0, 0},  {&_swigt__p_FormFactorLorentz, _p_FormFactorLorentzTo_p_INode, 0, 0},  {&_swigt__p_FormFactorLongRipple2Lorentz, _p_FormFactorLongRipple2LorentzTo_p_INode, 0, 0},  {&_swigt__p_FormFactorLongRipple1Lorentz, _p_FormFactorLongRipple1LorentzTo_p_INode, 0, 0},  {&_swigt__p_FormFactorLongBoxLorentz, _p_FormFactorLongBoxLorentzTo_p_INode, 0, 0},  {&_swigt__p_InterferenceFunction1DLattice, _p_InterferenceFunction1DLatticeTo_p_INode, 0, 0},  {&_swigt__p_InterferenceFunction2DLattice, _p_InterferenceFunction2DLatticeTo_p_INode, 0, 0},  {&_swigt__p_InterferenceFunction2DSuperLattice, _p_InterferenceFunction2DSuperLatticeTo_p_INode, 0, 0},  {&_swigt__p_InterferenceFunction3DLattice, _p_InterferenceFunction3DLatticeTo_p_INode, 0, 0},  {&_swigt__p_InterferenceFunctionFinite2DLattice, _p_InterferenceFunctionFinite2DLatticeTo_p_INode, 0, 0},  {&_swigt__p_InterferenceFunctionFinite3DLattice, _p_InterferenceFunctionFinite3DLatticeTo_p_INode, 0, 0},  {&_swigt__p_BasicLattice, _p_BasicLatticeTo_p_INode, 0, 0},  {&_swigt__p_SquareLattice, _p_SquareLatticeTo_p_INode, 0, 0},  {&_swigt__p_HexagonalLattice, _p_HexagonalLatticeTo_p_INode, 0, 0},  {&_swigt__p_DistributionLorentz, _p_DistributionLorentzTo_p_INode, 0, 0},  {&_swigt__p_Lattice, _p_LatticeTo_p_INode, 0, 0},  {&_swigt__p_FTDecayFunction1DTriangle, _p_FTDecayFunction1DTriangleTo_p_INode, 0, 0},  {&_swigt__p_FTDistribution1DTriangle, _p_FTDistribution1DTriangleTo_p_INode, 0, 0},  {&_swigt__p_RotationEuler, _p_RotationEulerTo_p_INode, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_INodeVisitor[] = {  {&_swigt__p_INodeVisitor, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_IObservable[] = {  {&_swigt__p_IObservable, 0, 0, 0},  {&_swigt__p_FitSuite, _p_FitSuiteTo_p_IObservable, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_IObserver[] = {  {&_swigt__p_IObserver, 0, 0, 0},  {&_swigt__p_IFitObserver, _p_IFitObserverTo_p_IObserver, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_IObservable[] = {  {&_swigt__p_IObservable, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_IObserver[] = {  {&_swigt__p_IObserver, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IParameterT_double_t[] = {  {&_swigt__p_IParameterT_double_t, 0, 0, 0},  {&_swigt__p_RealParameter, _p_RealParameterTo_p_IParameterT_double_t, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_IParameterized[] = {  {&_swigt__p_FormFactorBox, _p_FormFactorBoxTo_p_IParameterized, 0, 0},  {&_swigt__p_IBackground, _p_IBackgroundTo_p_IParameterized, 0, 0},  {&_swigt__p_ConstantBackground, _p_ConstantBackgroundTo_p_IParameterized, 0, 0},  {&_swigt__p_PoissonNoiseBackground, _p_PoissonNoiseBackgroundTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorSphereGaussianRadius, _p_FormFactorSphereGaussianRadiusTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorSphereLogNormalRadius, _p_FormFactorSphereLogNormalRadiusTo_p_IParameterized, 0, 0},  {&_swigt__p_MultiLayer, _p_MultiLayerTo_p_IParameterized, 0, 0},  {&_swigt__p_ParameterDistribution, _p_ParameterDistributionTo_p_IParameterized, 0, 0},  {&_swigt__p_ParticleDistribution, _p_ParticleDistributionTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDecayFunction1DGauss, _p_FTDecayFunction1DGaussTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDistribution1DGauss, _p_FTDistribution1DGaussTo_p_IParameterized, 0, 0},  {&_swigt__p_InterferenceFunctionNone, _p_InterferenceFunctionNoneTo_p_IParameterized, 0, 0},  {&_swigt__p_IDetector2D, _p_IDetector2DTo_p_IParameterized, 0, 0},  {&_swigt__p_ILayout, _p_ILayoutTo_p_IParameterized, 0, 0},  {&_swigt__p_ParticleLayout, _p_ParticleLayoutTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorHemiEllipsoid, _p_FormFactorHemiEllipsoidTo_p_IParameterized, 0, 0},  {&_swigt__p_IntensityScaleAndShiftNormalizer, _p_IntensityScaleAndShiftNormalizerTo_p_IParameterized, 0, 0},  {&_swigt__p_IntensityNormalizer, _p_IntensityNormalizerTo_p_IParameterized, 0, 0},  {&_swigt__p_IIntensityNormalizer, _p_IIntensityNormalizerTo_p_IParameterized, 0, 0},  {&_swigt__p_SphericalDetector, _p_SphericalDetectorTo_p_IParameterized, 0, 0},  {&_swigt__p_IsGISAXSDetector, _p_IsGISAXSDetectorTo_p_IParameterized, 0, 0},  {&_swigt__p_RectangularDetector, _p_RectangularDetectorTo_p_IParameterized, 0, 0},  {&_swigt__p_IDetector, _p_IDetectorTo_p_IParameterized, 0, 0},  {&_swigt__p_INode, _p_INodeTo_p_IParameterized, 0, 0},  {&_swigt__p_IPeakShape, _p_IPeakShapeTo_p_IParameterized, 0, 0},  {&_swigt__p_GaussPeakShape, _p_GaussPeakShapeTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorPrism3, _p_FormFactorPrism3To_p_IParameterized, 0, 0},  {&_swigt__p_DistributionTrapezoid, _p_DistributionTrapezoidTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorIcosahedron, _p_FormFactorIcosahedronTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorDodecahedron, _p_FormFactorDodecahedronTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorCuboctahedron, _p_FormFactorCuboctahedronTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorPolyhedron, _p_FormFactorPolyhedronTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorTetrahedron, _p_FormFactorTetrahedronTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorDebyeBueche, _p_FormFactorDebyeBuecheTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorPrism6, _p_FormFactorPrism6To_p_IParameterized, 0, 0},  {&_swigt__p_Simulation, _p_SimulationTo_p_IParameterized, 0, 0},  {&_swigt__p_GISASSimulation, _p_GISASSimulationTo_p_IParameterized, 0, 0},  {&_swigt__p_OffSpecSimulation, _p_OffSpecSimulationTo_p_IParameterized, 0, 0},  {&_swigt__p_DepthProbeSimulation, _p_DepthProbeSimulationTo_p_IParameterized, 0, 0},  {&_swigt__p_SpecularSimulation, _p_SpecularSimulationTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDistribution2DCone, _p_FTDistribution2DConeTo_p_IParameterized, 0, 0},  {&_swigt__p_ParticleCoreShell, _p_ParticleCoreShellTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorFullSphere, _p_FormFactorFullSphereTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorTruncatedSphere, _p_FormFactorTruncatedSphereTo_p_IParameterized, 0, 0},  {&_swigt__p_IFormFactor, _p_IFormFactorTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorPolygonalSurface, _p_FormFactorPolygonalSurfaceTo_p_IParameterized, 0, 0},  {&_swigt__p_ISample, _p_ISampleTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorLongBoxGauss, _p_FormFactorLongBoxGaussTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorPolygonalPrism, _p_FormFactorPolygonalPrismTo_p_IParameterized, 0, 0},  {&_swigt__p_FitSuiteObjects, _p_FitSuiteObjectsTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDistribution2DGate, _p_FTDistribution2DGateTo_p_IParameterized, 0, 0},  {&_swigt__p_DistributionLogNormal, _p_DistributionLogNormalTo_p_IParameterized, 0, 0},  {&_swigt__p_Instrument, _p_InstrumentTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDistribution1DVoigt, _p_FTDistribution1DVoigtTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDecayFunction1DVoigt, _p_FTDecayFunction1DVoigtTo_p_IParameterized, 0, 0},  {&_swigt__p_IdentityRotation, _p_IdentityRotationTo_p_IParameterized, 0, 0},  {&_swigt__p_IRotation, _p_IRotationTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorTruncatedSpheroid, _p_FormFactorTruncatedSpheroidTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorFullSpheroid, _p_FormFactorFullSpheroidTo_p_IParameterized, 0, 0},  {&_swigt__p_RotationX, _p_RotationXTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorTruncatedCube, _p_FormFactorTruncatedCubeTo_p_IParameterized, 0, 0},  {&_swigt__p_RotationY, _p_RotationYTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDecayFunction2DGauss, _p_FTDecayFunction2DGaussTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDistribution2DGauss, _p_FTDistribution2DGaussTo_p_IParameterized, 0, 0},  {&_swigt__p_RotationZ, _p_RotationZTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorLongRipple2Gauss, _p_FormFactorLongRipple2GaussTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorGauss, _p_FormFactorGaussTo_p_IParameterized, 0, 0},  {&_swigt__p_IFormFactorBorn, _p_IFormFactorBornTo_p_IParameterized, 0, 0},  {&_swigt__p_IDetectorResolution, _p_IDetectorResolutionTo_p_IParameterized, 0, 0},  {&_swigt__p_IClusteredParticles, _p_IClusteredParticlesTo_p_IParameterized, 0, 0},  {&_swigt__p_IMultiLayerBuilder, _p_IMultiLayerBuilderTo_p_IParameterized, 0, 0},  {&_swigt__p_IAbstractParticle, _p_IAbstractParticleTo_p_IParameterized, 0, 0},  {&_swigt__p_IParticle, _p_IParticleTo_p_IParameterized, 0, 0},  {&_swigt__p_Particle, _p_ParticleTo_p_IParameterized, 0, 0},  {&_swigt__p_Lattice2D, _p_Lattice2DTo_p_IParameterized, 0, 0},  {&_swigt__p_DistributionGate, _p_DistributionGateTo_p_IParameterized, 0, 0},  {&_swigt__p_IDistribution1D, _p_IDistribution1DTo_p_IParameterized, 0, 0},  {&_swigt__p_IFTDecayFunction1D, _p_IFTDecayFunction1DTo_p_IParameterized, 0, 0},  {&_swigt__p_IFTDistribution1D, _p_IFTDistribution1DTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorCone, _p_FormFactorConeTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorRipple1, _p_FormFactorRipple1To_p_IParameterized, 0, 0},  {&_swigt__p_Layer, _p_LayerTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorPyramid, _p_FormFactorPyramidTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorAnisoPyramid, _p_FormFactorAnisoPyramidTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorDecoratorDebyeWaller, _p_FormFactorDecoratorDebyeWallerTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorRipple2, _p_FormFactorRipple2To_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorEllipsoidalCylinder, _p_FormFactorEllipsoidalCylinderTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorCylinder, _p_FormFactorCylinderTo_p_IParameterized, 0, 0},  {&_swigt__p_DistributionGaussian, _p_DistributionGaussianTo_p_IParameterized, 0, 0},  {&_swigt__p_FootprintFactorGaussian, _p_FootprintFactorGaussianTo_p_IParameterized, 0, 0},  {&_swigt__p_ResolutionFunction2DGaussian, _p_ResolutionFunction2DGaussianTo_p_IParameterized, 0, 0},  {&_swigt__p_IFootprintFactor, _p_IFootprintFactorTo_p_IParameterized, 0, 0},  {&_swigt__p_ParticleComposition, _p_ParticleCompositionTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorSphereUniformRadius, _p_FormFactorSphereUniformRadiusTo_p_IParameterized, 0, 0},  {&_swigt__p_DistributionCosine, _p_DistributionCosineTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDistribution1DCosine, _p_FTDistribution1DCosineTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDistribution1DGate, _p_FTDistribution1DGateTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDistribution2DVoigt, _p_FTDistribution2DVoigtTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDecayFunction2DVoigt, _p_FTDecayFunction2DVoigtTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDecayFunction1DCauchy, _p_FTDecayFunction1DCauchyTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDistribution1DCauchy, _p_FTDistribution1DCauchyTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDecayFunction2DCauchy, _p_FTDecayFunction2DCauchyTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDistribution2DCauchy, _p_FTDistribution2DCauchyTo_p_IParameterized, 0, 0},  {&_swigt__p_IInterferenceFunction, _p_IInterferenceFunctionTo_p_IParameterized, 0, 0},  {&_swigt__p_FootprintFactorSquare, _p_FootprintFactorSquareTo_p_IParameterized, 0, 0},  {&_swigt__p_FitObject, _p_FitObjectTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorCone6, _p_FormFactorCone6To_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorLongRipple1Gauss, _p_FormFactorLongRipple1GaussTo_p_IParameterized, 0, 0},  {&_swigt__p_Beam, _p_BeamTo_p_IParameterized, 0, 0},  {&_swigt__p_IFormFactorDecorator, _p_IFormFactorDecoratorTo_p_IParameterized, 0, 0},  {&_swigt__p_IParameterized, 0, 0, 0},  {&_swigt__p_FormFactorOrnsteinZernike, _p_FormFactorOrnsteinZernikeTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorDot, _p_FormFactorDotTo_p_IParameterized, 0, 0},  {&_swigt__p_LayerRoughness, _p_LayerRoughnessTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorCrystal, _p_FormFactorCrystalTo_p_IParameterized, 0, 0},  {&_swigt__p_Crystal, _p_CrystalTo_p_IParameterized, 0, 0},  {&_swigt__p_MesoCrystal, _p_MesoCrystalTo_p_IParameterized, 0, 0},  {&_swigt__p_InterferenceFunctionRadialParaCrystal, _p_InterferenceFunctionRadialParaCrystalTo_p_IParameterized, 0, 0},  {&_swigt__p_InterferenceFunction2DParaCrystal, _p_InterferenceFunction2DParaCrystalTo_p_IParameterized, 0, 0},  {&_swigt__p_Simulation2D, _p_Simulation2DTo_p_IParameterized, 0, 0},  {&_swigt__p_IFTDecayFunction2D, _p_IFTDecayFunction2DTo_p_IParameterized, 0, 0},  {&_swigt__p_IFTDistribution2D, _p_IFTDistribution2DTo_p_IParameterized, 0, 0},  {&_swigt__p_IResolutionFunction2D, _p_IResolutionFunction2DTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorWeighted, _p_FormFactorWeightedTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorLorentz, _p_FormFactorLorentzTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorLongRipple2Lorentz, _p_FormFactorLongRipple2LorentzTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorLongRipple1Lorentz, _p_FormFactorLongRipple1LorentzTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorLongBoxLorentz, _p_FormFactorLongBoxLorentzTo_p_IParameterized, 0, 0},  {&_swigt__p_InterferenceFunction1DLattice, _p_InterferenceFunction1DLatticeTo_p_IParameterized, 0, 0},  {&_swigt__p_InterferenceFunction2DLattice, _p_InterferenceFunction2DLatticeTo_p_IParameterized, 0, 0},  {&_swigt__p_InterferenceFunction3DLattice, _p_InterferenceFunction3DLatticeTo_p_IParameterized, 0, 0},  {&_swigt__p_InterferenceFunctionFinite2DLattice, _p_InterferenceFunctionFinite2DLatticeTo_p_IParameterized, 0, 0},  {&_swigt__p_InterferenceFunction2DSuperLattice, _p_InterferenceFunction2DSuperLatticeTo_p_IParameterized, 0, 0},  {&_swigt__p_BasicLattice, _p_BasicLatticeTo_p_IParameterized, 0, 0},  {&_swigt__p_SquareLattice, _p_SquareLatticeTo_p_IParameterized, 0, 0},  {&_swigt__p_HexagonalLattice, _p_HexagonalLatticeTo_p_IParameterized, 0, 0},  {&_swigt__p_DistributionLorentz, _p_DistributionLorentzTo_p_IParameterized, 0, 0},  {&_swigt__p_Lattice, _p_LatticeTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDecayFunction1DTriangle, _p_FTDecayFunction1DTriangleTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDistribution1DTriangle, _p_FTDistribution1DTriangleTo_p_IParameterized, 0, 0},  {&_swigt__p_RotationEuler, _p_RotationEulerTo_p_IParameterized, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_IParameterized[] = {  {&_swigt__p_FormFactorBox, _p_FormFactorBoxTo_p_IParameterized, 0, 0},  {&_swigt__p_IBackground, _p_IBackgroundTo_p_IParameterized, 0, 0},  {&_swigt__p_ConstantBackground, _p_ConstantBackgroundTo_p_IParameterized, 0, 0},  {&_swigt__p_PoissonNoiseBackground, _p_PoissonNoiseBackgroundTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorSphereGaussianRadius, _p_FormFactorSphereGaussianRadiusTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorSphereLogNormalRadius, _p_FormFactorSphereLogNormalRadiusTo_p_IParameterized, 0, 0},  {&_swigt__p_MultiLayer, _p_MultiLayerTo_p_IParameterized, 0, 0},  {&_swigt__p_ParameterDistribution, _p_ParameterDistributionTo_p_IParameterized, 0, 0},  {&_swigt__p_ParticleDistribution, _p_ParticleDistributionTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDecayFunction1DGauss, _p_FTDecayFunction1DGaussTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDistribution1DGauss, _p_FTDistribution1DGaussTo_p_IParameterized, 0, 0},  {&_swigt__p_InterferenceFunctionNone, _p_InterferenceFunctionNoneTo_p_IParameterized, 0, 0},  {&_swigt__p_IDetector2D, _p_IDetector2DTo_p_IParameterized, 0, 0},  {&_swigt__p_ILayout, _p_ILayoutTo_p_IParameterized, 0, 0},  {&_swigt__p_ParticleLayout, _p_ParticleLayoutTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorHemiEllipsoid, _p_FormFactorHemiEllipsoidTo_p_IParameterized, 0, 0},  {&_swigt__p_IntensityScaleAndShiftNormalizer, _p_IntensityScaleAndShiftNormalizerTo_p_IParameterized, 0, 0},  {&_swigt__p_IntensityNormalizer, _p_IntensityNormalizerTo_p_IParameterized, 0, 0},  {&_swigt__p_IIntensityNormalizer, _p_IIntensityNormalizerTo_p_IParameterized, 0, 0},  {&_swigt__p_SphericalDetector, _p_SphericalDetectorTo_p_IParameterized, 0, 0},  {&_swigt__p_IsGISAXSDetector, _p_IsGISAXSDetectorTo_p_IParameterized, 0, 0},  {&_swigt__p_RectangularDetector, _p_RectangularDetectorTo_p_IParameterized, 0, 0},  {&_swigt__p_IDetector, _p_IDetectorTo_p_IParameterized, 0, 0},  {&_swigt__p_INode, _p_INodeTo_p_IParameterized, 0, 0},  {&_swigt__p_IPeakShape, _p_IPeakShapeTo_p_IParameterized, 0, 0},  {&_swigt__p_IsotropicGaussPeakShape, _p_IsotropicGaussPeakShapeTo_p_IParameterized, 0, 0},  {&_swigt__p_IsotropicLorentzPeakShape, _p_IsotropicLorentzPeakShapeTo_p_IParameterized, 0, 0},  {&_swigt__p_GaussFisherPeakShape, _p_GaussFisherPeakShapeTo_p_IParameterized, 0, 0},  {&_swigt__p_LorentzFisherPeakShape, _p_LorentzFisherPeakShapeTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorPrism3, _p_FormFactorPrism3To_p_IParameterized, 0, 0},  {&_swigt__p_DistributionTrapezoid, _p_DistributionTrapezoidTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorPolyhedron, _p_FormFactorPolyhedronTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorCuboctahedron, _p_FormFactorCuboctahedronTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorDodecahedron, _p_FormFactorDodecahedronTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorTetrahedron, _p_FormFactorTetrahedronTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorIcosahedron, _p_FormFactorIcosahedronTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorDebyeBueche, _p_FormFactorDebyeBuecheTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorPrism6, _p_FormFactorPrism6To_p_IParameterized, 0, 0},  {&_swigt__p_Simulation, _p_SimulationTo_p_IParameterized, 0, 0},  {&_swigt__p_GISASSimulation, _p_GISASSimulationTo_p_IParameterized, 0, 0},  {&_swigt__p_OffSpecSimulation, _p_OffSpecSimulationTo_p_IParameterized, 0, 0},  {&_swigt__p_DepthProbeSimulation, _p_DepthProbeSimulationTo_p_IParameterized, 0, 0},  {&_swigt__p_SpecularSimulation, _p_SpecularSimulationTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDistribution2DCone, _p_FTDistribution2DConeTo_p_IParameterized, 0, 0},  {&_swigt__p_ParticleCoreShell, _p_ParticleCoreShellTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorFullSphere, _p_FormFactorFullSphereTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorTruncatedSphere, _p_FormFactorTruncatedSphereTo_p_IParameterized, 0, 0},  {&_swigt__p_IFormFactor, _p_IFormFactorTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorPolygonalSurface, _p_FormFactorPolygonalSurfaceTo_p_IParameterized, 0, 0},  {&_swigt__p_ISample, _p_ISampleTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorLongBoxGauss, _p_FormFactorLongBoxGaussTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorPolygonalPrism, _p_FormFactorPolygonalPrismTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDistribution2DGate, _p_FTDistribution2DGateTo_p_IParameterized, 0, 0},  {&_swigt__p_DistributionLogNormal, _p_DistributionLogNormalTo_p_IParameterized, 0, 0},  {&_swigt__p_Instrument, _p_InstrumentTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDistribution1DVoigt, _p_FTDistribution1DVoigtTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDecayFunction1DVoigt, _p_FTDecayFunction1DVoigtTo_p_IParameterized, 0, 0},  {&_swigt__p_IdentityRotation, _p_IdentityRotationTo_p_IParameterized, 0, 0},  {&_swigt__p_IRotation, _p_IRotationTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorTruncatedSpheroid, _p_FormFactorTruncatedSpheroidTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorFullSpheroid, _p_FormFactorFullSpheroidTo_p_IParameterized, 0, 0},  {&_swigt__p_RotationX, _p_RotationXTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorTruncatedCube, _p_FormFactorTruncatedCubeTo_p_IParameterized, 0, 0},  {&_swigt__p_RotationY, _p_RotationYTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDistribution2DGauss, _p_FTDistribution2DGaussTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDecayFunction2DGauss, _p_FTDecayFunction2DGaussTo_p_IParameterized, 0, 0},  {&_swigt__p_RotationZ, _p_RotationZTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorLongRipple2Gauss, _p_FormFactorLongRipple2GaussTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorGauss, _p_FormFactorGaussTo_p_IParameterized, 0, 0},  {&_swigt__p_IFormFactorBorn, _p_IFormFactorBornTo_p_IParameterized, 0, 0},  {&_swigt__p_IDetectorResolution, _p_IDetectorResolutionTo_p_IParameterized, 0, 0},  {&_swigt__p_IClusteredParticles, _p_IClusteredParticlesTo_p_IParameterized, 0, 0},  {&_swigt__p_IMultiLayerBuilder, _p_IMultiLayerBuilderTo_p_IParameterized, 0, 0},  {&_swigt__p_Particle, _p_ParticleTo_p_IParameterized, 0, 0},  {&_swigt__p_IAbstractParticle, _p_IAbstractParticleTo_p_IParameterized, 0, 0},  {&_swigt__p_IParticle, _p_IParticleTo_p_IParameterized, 0, 0},  {&_swigt__p_Lattice2D, _p_Lattice2DTo_p_IParameterized, 0, 0},  {&_swigt__p_DistributionGate, _p_DistributionGateTo_p_IParameterized, 0, 0},  {&_swigt__p_IDistribution1D, _p_IDistribution1DTo_p_IParameterized, 0, 0},  {&_swigt__p_IFTDecayFunction1D, _p_IFTDecayFunction1DTo_p_IParameterized, 0, 0},  {&_swigt__p_IFTDistribution1D, _p_IFTDistribution1DTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorCone, _p_FormFactorConeTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorRipple1, _p_FormFactorRipple1To_p_IParameterized, 0, 0},  {&_swigt__p_Layer, _p_LayerTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorPyramid, _p_FormFactorPyramidTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorAnisoPyramid, _p_FormFactorAnisoPyramidTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorDecoratorDebyeWaller, _p_FormFactorDecoratorDebyeWallerTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorRipple2, _p_FormFactorRipple2To_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorEllipsoidalCylinder, _p_FormFactorEllipsoidalCylinderTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorCylinder, _p_FormFactorCylinderTo_p_IParameterized, 0, 0},  {&_swigt__p_DistributionGaussian, _p_DistributionGaussianTo_p_IParameterized, 0, 0},  {&_swigt__p_FootprintFactorGaussian, _p_FootprintFactorGaussianTo_p_IParameterized, 0, 0},  {&_swigt__p_ResolutionFunction2DGaussian, _p_ResolutionFunction2DGaussianTo_p_IParameterized, 0, 0},  {&_swigt__p_IFootprintFactor, _p_IFootprintFactorTo_p_IParameterized, 0, 0},  {&_swigt__p_ParticleComposition, _p_ParticleCompositionTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorSphereUniformRadius, _p_FormFactorSphereUniformRadiusTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorLongBox, _p_FormFactorLongBoxTo_p_IParameterized, 0, 0},  {&_swigt__p_DistributionCosine, _p_DistributionCosineTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDistribution1DCosine, _p_FTDistribution1DCosineTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDistribution1DGate, _p_FTDistribution1DGateTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDistribution2DVoigt, _p_FTDistribution2DVoigtTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDecayFunction2DVoigt, _p_FTDecayFunction2DVoigtTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDecayFunction1DCauchy, _p_FTDecayFunction1DCauchyTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDistribution1DCauchy, _p_FTDistribution1DCauchyTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDecayFunction2DCauchy, _p_FTDecayFunction2DCauchyTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDistribution2DCauchy, _p_FTDistribution2DCauchyTo_p_IParameterized, 0, 0},  {&_swigt__p_IInterferenceFunction, _p_IInterferenceFunctionTo_p_IParameterized, 0, 0},  {&_swigt__p_FootprintFactorSquare, _p_FootprintFactorSquareTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorCone6, _p_FormFactorCone6To_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorLongRipple1Gauss, _p_FormFactorLongRipple1GaussTo_p_IParameterized, 0, 0},  {&_swigt__p_Beam, _p_BeamTo_p_IParameterized, 0, 0},  {&_swigt__p_IFormFactorDecorator, _p_IFormFactorDecoratorTo_p_IParameterized, 0, 0},  {&_swigt__p_IParameterized, 0, 0, 0},  {&_swigt__p_FormFactorOrnsteinZernike, _p_FormFactorOrnsteinZernikeTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorDot, _p_FormFactorDotTo_p_IParameterized, 0, 0},  {&_swigt__p_LayerRoughness, _p_LayerRoughnessTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorCrystal, _p_FormFactorCrystalTo_p_IParameterized, 0, 0},  {&_swigt__p_Crystal, _p_CrystalTo_p_IParameterized, 0, 0},  {&_swigt__p_MesoCrystal, _p_MesoCrystalTo_p_IParameterized, 0, 0},  {&_swigt__p_InterferenceFunction2DParaCrystal, _p_InterferenceFunction2DParaCrystalTo_p_IParameterized, 0, 0},  {&_swigt__p_InterferenceFunctionRadialParaCrystal, _p_InterferenceFunctionRadialParaCrystalTo_p_IParameterized, 0, 0},  {&_swigt__p_Simulation2D, _p_Simulation2DTo_p_IParameterized, 0, 0},  {&_swigt__p_IFTDecayFunction2D, _p_IFTDecayFunction2DTo_p_IParameterized, 0, 0},  {&_swigt__p_IFTDistribution2D, _p_IFTDistribution2DTo_p_IParameterized, 0, 0},  {&_swigt__p_IResolutionFunction2D, _p_IResolutionFunction2DTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorWeighted, _p_FormFactorWeightedTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorLongRipple1Lorentz, _p_FormFactorLongRipple1LorentzTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorLongBoxLorentz, _p_FormFactorLongBoxLorentzTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorLongRipple2Lorentz, _p_FormFactorLongRipple2LorentzTo_p_IParameterized, 0, 0},  {&_swigt__p_FormFactorLorentz, _p_FormFactorLorentzTo_p_IParameterized, 0, 0},  {&_swigt__p_InterferenceFunction1DLattice, _p_InterferenceFunction1DLatticeTo_p_IParameterized, 0, 0},  {&_swigt__p_InterferenceFunction2DLattice, _p_InterferenceFunction2DLatticeTo_p_IParameterized, 0, 0},  {&_swigt__p_InterferenceFunction2DSuperLattice, _p_InterferenceFunction2DSuperLatticeTo_p_IParameterized, 0, 0},  {&_swigt__p_InterferenceFunction3DLattice, _p_InterferenceFunction3DLatticeTo_p_IParameterized, 0, 0},  {&_swigt__p_InterferenceFunctionFinite2DLattice, _p_InterferenceFunctionFinite2DLatticeTo_p_IParameterized, 0, 0},  {&_swigt__p_InterferenceFunctionFinite3DLattice, _p_InterferenceFunctionFinite3DLatticeTo_p_IParameterized, 0, 0},  {&_swigt__p_BasicLattice, _p_BasicLatticeTo_p_IParameterized, 0, 0},  {&_swigt__p_SquareLattice, _p_SquareLatticeTo_p_IParameterized, 0, 0},  {&_swigt__p_HexagonalLattice, _p_HexagonalLatticeTo_p_IParameterized, 0, 0},  {&_swigt__p_DistributionLorentz, _p_DistributionLorentzTo_p_IParameterized, 0, 0},  {&_swigt__p_Lattice, _p_LatticeTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDecayFunction1DTriangle, _p_FTDecayFunction1DTriangleTo_p_IParameterized, 0, 0},  {&_swigt__p_FTDistribution1DTriangle, _p_FTDistribution1DTriangleTo_p_IParameterized, 0, 0},  {&_swigt__p_RotationEuler, _p_RotationEulerTo_p_IParameterized, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IParticle[] = {  {&_swigt__p_ParticleComposition, _p_ParticleCompositionTo_p_IParticle, 0, 0},  {&_swigt__p_MesoCrystal, _p_MesoCrystalTo_p_IParticle, 0, 0},  {&_swigt__p_IParticle, 0, 0, 0},  {&_swigt__p_Particle, _p_ParticleTo_p_IParticle, 0, 0},  {&_swigt__p_ParticleCoreShell, _p_ParticleCoreShellTo_p_IParticle, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_IPeakShape[] = {  {&_swigt__p_IPeakShape, 0, 0, 0},  {&_swigt__p_GaussPeakShape, _p_GaussPeakShapeTo_p_IPeakShape, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_IPeakShape[] = {  {&_swigt__p_IPeakShape, 0, 0, 0},  {&_swigt__p_IsotropicGaussPeakShape, _p_IsotropicGaussPeakShapeTo_p_IPeakShape, 0, 0},  {&_swigt__p_IsotropicLorentzPeakShape, _p_IsotropicLorentzPeakShapeTo_p_IPeakShape, 0, 0},  {&_swigt__p_GaussFisherPeakShape, _p_GaussFisherPeakShapeTo_p_IPeakShape, 0, 0},  {&_swigt__p_LorentzFisherPeakShape, _p_LorentzFisherPeakShapeTo_p_IPeakShape, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IPixel[] = {  {&_swigt__p_RectangularPixel, _p_RectangularPixelTo_p_IPixel, 0, 0},  {&_swigt__p_SphericalPixel, _p_SphericalPixelTo_p_IPixel, 0, 0},  {&_swigt__p_IPixel, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IResolutionFunction2D[] = {  {&_swigt__p_IResolutionFunction2D, 0, 0, 0},  {&_swigt__p_ResolutionFunction2DGaussian, _p_ResolutionFunction2DGaussianTo_p_IResolutionFunction2D, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IRotation[] = {  {&_swigt__p_RotationY, _p_RotationYTo_p_IRotation, 0, 0},  {&_swigt__p_RotationEuler, _p_RotationEulerTo_p_IRotation, 0, 0},  {&_swigt__p_RotationZ, _p_RotationZTo_p_IRotation, 0, 0},  {&_swigt__p_IRotation, 0, 0, 0},  {&_swigt__p_IdentityRotation, _p_IdentityRotationTo_p_IRotation, 0, 0},  {&_swigt__p_RotationX, _p_RotationXTo_p_IRotation, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_ISample[] = {  {&_swigt__p_FormFactorBox, _p_FormFactorBoxTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorSphereLogNormalRadius, _p_FormFactorSphereLogNormalRadiusTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorSphereGaussianRadius, _p_FormFactorSphereGaussianRadiusTo_p_ISample, 0, 0},  {&_swigt__p_MultiLayer, _p_MultiLayerTo_p_ISample, 0, 0},  {&_swigt__p_ParticleDistribution, _p_ParticleDistributionTo_p_ISample, 0, 0},  {&_swigt__p_InterferenceFunctionNone, _p_InterferenceFunctionNoneTo_p_ISample, 0, 0},  {&_swigt__p_ILayout, _p_ILayoutTo_p_ISample, 0, 0},  {&_swigt__p_ParticleLayout, _p_ParticleLayoutTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorHemiEllipsoid, _p_FormFactorHemiEllipsoidTo_p_ISample, 0, 0},  {&_swigt__p_GaussPeakShape, _p_GaussPeakShapeTo_p_ISample, 0, 0},  {&_swigt__p_IPeakShape, _p_IPeakShapeTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorPrism3, _p_FormFactorPrism3To_p_ISample, 0, 0},  {&_swigt__p_FormFactorTetrahedron, _p_FormFactorTetrahedronTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorCuboctahedron, _p_FormFactorCuboctahedronTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorPolyhedron, _p_FormFactorPolyhedronTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorDodecahedron, _p_FormFactorDodecahedronTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorIcosahedron, _p_FormFactorIcosahedronTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorDebyeBueche, _p_FormFactorDebyeBuecheTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorPrism6, _p_FormFactorPrism6To_p_ISample, 0, 0},  {&_swigt__p_ParticleCoreShell, _p_ParticleCoreShellTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorTruncatedSphere, _p_FormFactorTruncatedSphereTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorFullSphere, _p_FormFactorFullSphereTo_p_ISample, 0, 0},  {&_swigt__p_IFormFactor, _p_IFormFactorTo_p_ISample, 0, 0},  {&_swigt__p_ISample, 0, 0, 0},  {&_swigt__p_FormFactorPolygonalSurface, _p_FormFactorPolygonalSurfaceTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorLongBoxGauss, _p_FormFactorLongBoxGaussTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorPolygonalPrism, _p_FormFactorPolygonalPrismTo_p_ISample, 0, 0},  {&_swigt__p_IRotation, _p_IRotationTo_p_ISample, 0, 0},  {&_swigt__p_IdentityRotation, _p_IdentityRotationTo_p_ISample, 0, 0},  {&_swigt__p_RotationX, _p_RotationXTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorFullSpheroid, _p_FormFactorFullSpheroidTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorTruncatedSpheroid, _p_FormFactorTruncatedSpheroidTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorTruncatedCube, _p_FormFactorTruncatedCubeTo_p_ISample, 0, 0},  {&_swigt__p_RotationY, _p_RotationYTo_p_ISample, 0, 0},  {&_swigt__p_RotationZ, _p_RotationZTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorGauss, _p_FormFactorGaussTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorLongRipple2Gauss, _p_FormFactorLongRipple2GaussTo_p_ISample, 0, 0},  {&_swigt__p_IFormFactorBorn, _p_IFormFactorBornTo_p_ISample, 0, 0},  {&_swigt__p_IClusteredParticles, _p_IClusteredParticlesTo_p_ISample, 0, 0},  {&_swigt__p_Particle, _p_ParticleTo_p_ISample, 0, 0},  {&_swigt__p_IParticle, _p_IParticleTo_p_ISample, 0, 0},  {&_swigt__p_IAbstractParticle, _p_IAbstractParticleTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorCone, _p_FormFactorConeTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorRipple1, _p_FormFactorRipple1To_p_ISample, 0, 0},  {&_swigt__p_Layer, _p_LayerTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorAnisoPyramid, _p_FormFactorAnisoPyramidTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorPyramid, _p_FormFactorPyramidTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorDecoratorDebyeWaller, _p_FormFactorDecoratorDebyeWallerTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorRipple2, _p_FormFactorRipple2To_p_ISample, 0, 0},  {&_swigt__p_FormFactorEllipsoidalCylinder, _p_FormFactorEllipsoidalCylinderTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorCylinder, _p_FormFactorCylinderTo_p_ISample, 0, 0},  {&_swigt__p_ParticleComposition, _p_ParticleCompositionTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorSphereUniformRadius, _p_FormFactorSphereUniformRadiusTo_p_ISample, 0, 0},  {&_swigt__p_IInterferenceFunction, _p_IInterferenceFunctionTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorCone6, _p_FormFactorCone6To_p_ISample, 0, 0},  {&_swigt__p_FormFactorLongRipple1Gauss, _p_FormFactorLongRipple1GaussTo_p_ISample, 0, 0},  {&_swigt__p_IFormFactorDecorator, _p_IFormFactorDecoratorTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorOrnsteinZernike, _p_FormFactorOrnsteinZernikeTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorDot, _p_FormFactorDotTo_p_ISample, 0, 0},  {&_swigt__p_LayerRoughness, _p_LayerRoughnessTo_p_ISample, 0, 0},  {&_swigt__p_InterferenceFunctionRadialParaCrystal, _p_InterferenceFunctionRadialParaCrystalTo_p_ISample, 0, 0},  {&_swigt__p_MesoCrystal, _p_MesoCrystalTo_p_ISample, 0, 0},  {&_swigt__p_Crystal, _p_CrystalTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorCrystal, _p_FormFactorCrystalTo_p_ISample, 0, 0},  {&_swigt__p_InterferenceFunction2DParaCrystal, _p_InterferenceFunction2DParaCrystalTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorWeighted, _p_FormFactorWeightedTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorLorentz, _p_FormFactorLorentzTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorLongRipple2Lorentz, _p_FormFactorLongRipple2LorentzTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorLongRipple1Lorentz, _p_FormFactorLongRipple1LorentzTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorLongBoxLorentz, _p_FormFactorLongBoxLorentzTo_p_ISample, 0, 0},  {&_swigt__p_InterferenceFunction2DSuperLattice, _p_InterferenceFunction2DSuperLatticeTo_p_ISample, 0, 0},  {&_swigt__p_InterferenceFunctionFinite2DLattice, _p_InterferenceFunctionFinite2DLatticeTo_p_ISample, 0, 0},  {&_swigt__p_InterferenceFunction3DLattice, _p_InterferenceFunction3DLatticeTo_p_ISample, 0, 0},  {&_swigt__p_InterferenceFunction2DLattice, _p_InterferenceFunction2DLatticeTo_p_ISample, 0, 0},  {&_swigt__p_InterferenceFunction1DLattice, _p_InterferenceFunction1DLatticeTo_p_ISample, 0, 0},  {&_swigt__p_RotationEuler, _p_RotationEulerTo_p_ISample, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_ISample[] = {  {&_swigt__p_FormFactorBox, _p_FormFactorBoxTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorSphereLogNormalRadius, _p_FormFactorSphereLogNormalRadiusTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorSphereGaussianRadius, _p_FormFactorSphereGaussianRadiusTo_p_ISample, 0, 0},  {&_swigt__p_MultiLayer, _p_MultiLayerTo_p_ISample, 0, 0},  {&_swigt__p_ParticleDistribution, _p_ParticleDistributionTo_p_ISample, 0, 0},  {&_swigt__p_InterferenceFunctionNone, _p_InterferenceFunctionNoneTo_p_ISample, 0, 0},  {&_swigt__p_ILayout, _p_ILayoutTo_p_ISample, 0, 0},  {&_swigt__p_ParticleLayout, _p_ParticleLayoutTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorHemiEllipsoid, _p_FormFactorHemiEllipsoidTo_p_ISample, 0, 0},  {&_swigt__p_LorentzFisherPeakShape, _p_LorentzFisherPeakShapeTo_p_ISample, 0, 0},  {&_swigt__p_GaussFisherPeakShape, _p_GaussFisherPeakShapeTo_p_ISample, 0, 0},  {&_swigt__p_IsotropicLorentzPeakShape, _p_IsotropicLorentzPeakShapeTo_p_ISample, 0, 0},  {&_swigt__p_IsotropicGaussPeakShape, _p_IsotropicGaussPeakShapeTo_p_ISample, 0, 0},  {&_swigt__p_IPeakShape, _p_IPeakShapeTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorPrism3, _p_FormFactorPrism3To_p_ISample, 0, 0},  {&_swigt__p_FormFactorTetrahedron, _p_FormFactorTetrahedronTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorCuboctahedron, _p_FormFactorCuboctahedronTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorPolyhedron, _p_FormFactorPolyhedronTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorDodecahedron, _p_FormFactorDodecahedronTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorIcosahedron, _p_FormFactorIcosahedronTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorDebyeBueche, _p_FormFactorDebyeBuecheTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorPrism6, _p_FormFactorPrism6To_p_ISample, 0, 0},  {&_swigt__p_ParticleCoreShell, _p_ParticleCoreShellTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorTruncatedSphere, _p_FormFactorTruncatedSphereTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorFullSphere, _p_FormFactorFullSphereTo_p_ISample, 0, 0},  {&_swigt__p_IFormFactor, _p_IFormFactorTo_p_ISample, 0, 0},  {&_swigt__p_ISample, 0, 0, 0},  {&_swigt__p_FormFactorPolygonalSurface, _p_FormFactorPolygonalSurfaceTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorLongBoxGauss, _p_FormFactorLongBoxGaussTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorPolygonalPrism, _p_FormFactorPolygonalPrismTo_p_ISample, 0, 0},  {&_swigt__p_IRotation, _p_IRotationTo_p_ISample, 0, 0},  {&_swigt__p_IdentityRotation, _p_IdentityRotationTo_p_ISample, 0, 0},  {&_swigt__p_RotationX, _p_RotationXTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorFullSpheroid, _p_FormFactorFullSpheroidTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorTruncatedSpheroid, _p_FormFactorTruncatedSpheroidTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorTruncatedCube, _p_FormFactorTruncatedCubeTo_p_ISample, 0, 0},  {&_swigt__p_RotationY, _p_RotationYTo_p_ISample, 0, 0},  {&_swigt__p_RotationZ, _p_RotationZTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorGauss, _p_FormFactorGaussTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorLongRipple2Gauss, _p_FormFactorLongRipple2GaussTo_p_ISample, 0, 0},  {&_swigt__p_IFormFactorBorn, _p_IFormFactorBornTo_p_ISample, 0, 0},  {&_swigt__p_IClusteredParticles, _p_IClusteredParticlesTo_p_ISample, 0, 0},  {&_swigt__p_IParticle, _p_IParticleTo_p_ISample, 0, 0},  {&_swigt__p_IAbstractParticle, _p_IAbstractParticleTo_p_ISample, 0, 0},  {&_swigt__p_Particle, _p_ParticleTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorCone, _p_FormFactorConeTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorRipple1, _p_FormFactorRipple1To_p_ISample, 0, 0},  {&_swigt__p_Layer, _p_LayerTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorAnisoPyramid, _p_FormFactorAnisoPyramidTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorPyramid, _p_FormFactorPyramidTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorDecoratorDebyeWaller, _p_FormFactorDecoratorDebyeWallerTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorRipple2, _p_FormFactorRipple2To_p_ISample, 0, 0},  {&_swigt__p_FormFactorEllipsoidalCylinder, _p_FormFactorEllipsoidalCylinderTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorCylinder, _p_FormFactorCylinderTo_p_ISample, 0, 0},  {&_swigt__p_ParticleComposition, _p_ParticleCompositionTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorSphereUniformRadius, _p_FormFactorSphereUniformRadiusTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorLongBox, _p_FormFactorLongBoxTo_p_ISample, 0, 0},  {&_swigt__p_IInterferenceFunction, _p_IInterferenceFunctionTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorCone6, _p_FormFactorCone6To_p_ISample, 0, 0},  {&_swigt__p_FormFactorLongRipple1Gauss, _p_FormFactorLongRipple1GaussTo_p_ISample, 0, 0},  {&_swigt__p_IFormFactorDecorator, _p_IFormFactorDecoratorTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorOrnsteinZernike, _p_FormFactorOrnsteinZernikeTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorDot, _p_FormFactorDotTo_p_ISample, 0, 0},  {&_swigt__p_LayerRoughness, _p_LayerRoughnessTo_p_ISample, 0, 0},  {&_swigt__p_MesoCrystal, _p_MesoCrystalTo_p_ISample, 0, 0},  {&_swigt__p_Crystal, _p_CrystalTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorCrystal, _p_FormFactorCrystalTo_p_ISample, 0, 0},  {&_swigt__p_InterferenceFunction2DParaCrystal, _p_InterferenceFunction2DParaCrystalTo_p_ISample, 0, 0},  {&_swigt__p_InterferenceFunctionRadialParaCrystal, _p_InterferenceFunctionRadialParaCrystalTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorWeighted, _p_FormFactorWeightedTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorLorentz, _p_FormFactorLorentzTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorLongRipple2Lorentz, _p_FormFactorLongRipple2LorentzTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorLongRipple1Lorentz, _p_FormFactorLongRipple1LorentzTo_p_ISample, 0, 0},  {&_swigt__p_FormFactorLongBoxLorentz, _p_FormFactorLongBoxLorentzTo_p_ISample, 0, 0},  {&_swigt__p_InterferenceFunction2DLattice, _p_InterferenceFunction2DLatticeTo_p_ISample, 0, 0},  {&_swigt__p_InterferenceFunction1DLattice, _p_InterferenceFunction1DLatticeTo_p_ISample, 0, 0},  {&_swigt__p_InterferenceFunction2DSuperLattice, _p_InterferenceFunction2DSuperLatticeTo_p_ISample, 0, 0},  {&_swigt__p_InterferenceFunction3DLattice, _p_InterferenceFunction3DLatticeTo_p_ISample, 0, 0},  {&_swigt__p_InterferenceFunctionFinite2DLattice, _p_InterferenceFunctionFinite2DLatticeTo_p_ISample, 0, 0},  {&_swigt__p_InterferenceFunctionFinite3DLattice, _p_InterferenceFunctionFinite3DLatticeTo_p_ISample, 0, 0},  {&_swigt__p_RotationEuler, _p_RotationEulerTo_p_ISample, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_ISelectionRule[] = {  {&_swigt__p_ISelectionRule, 0, 0, 0},  {&_swigt__p_SimpleSelectionRule, _p_SimpleSelectionRuleTo_p_ISelectionRule, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IShape2D[] = {  {&_swigt__p_Polygon, _p_PolygonTo_p_IShape2D, 0, 0},  {&_swigt__p_Line, _p_LineTo_p_IShape2D, 0, 0},  {&_swigt__p_VerticalLine, _p_VerticalLineTo_p_IShape2D, 0, 0},  {&_swigt__p_Ellipse, _p_EllipseTo_p_IShape2D, 0, 0},  {&_swigt__p_HorizontalLine, _p_HorizontalLineTo_p_IShape2D, 0, 0},  {&_swigt__p_Rectangle, _p_RectangleTo_p_IShape2D, 0, 0},  {&_swigt__p_IShape2D, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_ISquaredFunction[] = {  {&_swigt__p_SquaredFunctionGaussianError, _p_SquaredFunctionGaussianErrorTo_p_ISquaredFunction, 0, 0},  {&_swigt__p_SquaredFunctionMeanSquaredError, _p_SquaredFunctionMeanSquaredErrorTo_p_ISquaredFunction, 0, 0},  {&_swigt__p_ISquaredFunction, 0, 0, 0},  {&_swigt__p_SquaredFunctionDefault, _p_SquaredFunctionDefaultTo_p_ISquaredFunction, 0, 0},  {&_swigt__p_SquaredFunctionSimError, _p_SquaredFunctionSimErrorTo_p_ISquaredFunction, 0, 0},  {&_swigt__p_SquaredFunctionSystematicError, _p_SquaredFunctionSystematicErrorTo_p_ISquaredFunction, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IUnitConverter[] = {  {&_swigt__p_IUnitConverter, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_IVarianceFunction[] = {  {&_swigt__p_IVarianceFunction, 0, 0, 0},  {&_swigt__p_VarianceConstantFunction, _p_VarianceConstantFunctionTo_p_IVarianceFunction, 0, 0},  {&_swigt__p_VarianceSimFunction, _p_VarianceSimFunctionTo_p_IVarianceFunction, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IdentityRotation[] = {  {&_swigt__p_IdentityRotation, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_Instrument[] = {  {&_swigt__p_Instrument, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IntensityDataIOFactory[] = {  {&_swigt__p_IntensityDataIOFactory, 0, 0, 0},{0, 0, 0, 0}};
@@ -143459,9 +135957,12 @@ static swig_cast_info _swigc__p_InterferenceFunction2DParaCrystal[] = {  {&_swig
 static swig_cast_info _swigc__p_InterferenceFunction2DSuperLattice[] = {  {&_swigt__p_InterferenceFunction2DSuperLattice, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_InterferenceFunction3DLattice[] = {  {&_swigt__p_InterferenceFunction3DLattice, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_InterferenceFunctionFinite2DLattice[] = {  {&_swigt__p_InterferenceFunctionFinite2DLattice, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_InterferenceFunctionFinite3DLattice[] = {  {&_swigt__p_InterferenceFunctionFinite3DLattice, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_InterferenceFunctionNone[] = {  {&_swigt__p_InterferenceFunctionNone, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_InterferenceFunctionRadialParaCrystal[] = {  {&_swigt__p_InterferenceFunctionRadialParaCrystal, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IsGISAXSDetector[] = {  {&_swigt__p_IsGISAXSDetector, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_IsotropicGaussPeakShape[] = {  {&_swigt__p_IsotropicGaussPeakShape, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_IsotropicLorentzPeakShape[] = {  {&_swigt__p_IsotropicLorentzPeakShape, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IterationInfo[] = {  {&_swigt__p_IterationInfo, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_Lattice[] = {  {&_swigt__p_Lattice, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_Lattice1DParameters[] = {  {&_swigt__p_Lattice1DParameters, 0, 0, 0},{0, 0, 0, 0}};
@@ -143471,6 +135972,7 @@ static swig_cast_info _swigc__p_Layer[] = {  {&_swigt__p_Layer, 0, 0, 0},{0, 0,
 static swig_cast_info _swigc__p_LayerInterface[] = {  {&_swigt__p_LayerInterface, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_LayerRoughness[] = {  {&_swigt__p_LayerRoughness, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_Line[] = {  {&_swigt__p_Line, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_LorentzFisherPeakShape[] = {  {&_swigt__p_LorentzFisherPeakShape, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_Material[] = {  {&_swigt__p_Material, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_MesoCrystal[] = {  {&_swigt__p_MesoCrystal, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_MillerIndex[] = {  {&_swigt__p_MillerIndex, 0, 0, 0},{0, 0, 0, 0}};
@@ -143512,7 +136014,6 @@ static swig_cast_info _swigc__p_RotationEuler[] = {  {&_swigt__p_RotationEuler,
 static swig_cast_info _swigc__p_RotationX[] = {  {&_swigt__p_RotationX, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_RotationY[] = {  {&_swigt__p_RotationY, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_RotationZ[] = {  {&_swigt__p_RotationZ, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_SafePointerVectorT_FitObject_t__iterator[] = {  {&_swigt__p_SafePointerVectorT_FitObject_t__iterator, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_SafePointerVectorT_IParticle_t[] = {  {&_swigt__p_SafePointerVectorT_IParticle_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_SafePointerVectorT_Layer_t[] = {  {&_swigt__p_SafePointerVectorT_Layer_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_SampleBuilderFactory[] = {  {&_swigt__p_SampleBuilderFactory, 0, 0, 0},{0, 0, 0, 0}};
@@ -143529,14 +136030,11 @@ static swig_cast_info _swigc__p_SpecularSimulation[] = {  {&_swigt__p_SpecularSi
 static swig_cast_info _swigc__p_SphericalDetector[] = {  {&_swigt__p_SphericalDetector, 0, 0, 0},  {&_swigt__p_IsGISAXSDetector, _p_IsGISAXSDetectorTo_p_SphericalDetector, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_SphericalPixel[] = {  {&_swigt__p_SphericalPixel, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_SquareLattice[] = {  {&_swigt__p_SquareLattice, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_SquaredFunctionDefault[] = {  {&_swigt__p_SquaredFunctionDefault, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_SquaredFunctionGaussianError[] = {  {&_swigt__p_SquaredFunctionGaussianError, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_SquaredFunctionMeanSquaredError[] = {  {&_swigt__p_SquaredFunctionMeanSquaredError, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_SquaredFunctionSimError[] = {  {&_swigt__p_SquaredFunctionSimError, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_SquaredFunctionSystematicError[] = {  {&_swigt__p_SquaredFunctionSystematicError, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_ThreadInfo[] = {  {&_swigt__p_ThreadInfo, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_Transform3D[] = {  {&_swigt__p_Transform3D, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_VariableBinAxis[] = {  {&_swigt__p_VariableBinAxis, 0, 0, 0},  {&_swigt__p_ConstKBinAxis, _p_ConstKBinAxisTo_p_VariableBinAxis, 0, 0},  {&_swigt__p_CustomBinAxis, _p_CustomBinAxisTo_p_VariableBinAxis, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_VarianceConstantFunction[] = {  {&_swigt__p_VarianceConstantFunction, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_VarianceSimFunction[] = {  {&_swigt__p_VarianceSimFunction, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_VerticalLine[] = {  {&_swigt__p_VerticalLine, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_WavevectorInfo[] = {  {&_swigt__p_WavevectorInfo, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_ZLimits[] = {  {&_swigt__p_ZLimits, 0, 0, 0},{0, 0, 0, 0}};
@@ -143545,7 +136043,6 @@ static swig_cast_info _swigc__p_bool[] = {  {&_swigt__p_bool, 0, 0, 0},{0, 0, 0,
 static swig_cast_info _swigc__p_char[] = {  {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_const_iterator[] = {  {&_swigt__p_const_iterator, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_const_reference[] = {  {&_swigt__p_const_reference, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_container_t[] = {  {&_swigt__p_container_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_corr_matrix_t[] = {  {&_swigt__p_corr_matrix_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_difference_type[] = {  {&_swigt__p_difference_type, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_double[] = {  {&_swigt__p_double, 0, 0, 0},{0, 0, 0, 0}};
@@ -143586,18 +136083,13 @@ static swig_cast_info _swigc__p_std__lessT_std__string_t[] = {  {&_swigt__p_std_
 static swig_cast_info _swigc__p_std__mapT_std__string_double_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_double_t_t_t[] = {  {&_swigt__p_std__mapT_std__string_double_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_double_t_t_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__mapT_std__string_std__string_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_std__string_t_t_t__const_iterator[] = {  {&_swigt__p_std__mapT_std__string_std__string_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_std__string_t_t_t__const_iterator, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__pairT_double_double_t[] = {  {&_swigt__p_std__pairT_double_double_t, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__shared_ptrT_IFitObserver_t[] = {  {&_swigt__p_std__shared_ptrT_IFitObserver_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__shared_ptrT_IMultiLayerBuilder_t[] = {  {&_swigt__p_std__shared_ptrT_IMultiLayerBuilder_t, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__shared_ptrT_IObserver_t[] = {  {&_swigt__p_std__shared_ptrT_IObserver_t, 0, 0, 0},  {&_swigt__p_std__shared_ptrT_IFitObserver_t, _p_std__shared_ptrT_IFitObserver_tTo_p_std__shared_ptrT_IObserver_t, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__shared_ptrT_IObserver_t[] = {  {&_swigt__p_std__shared_ptrT_IObserver_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__vectorT_AxesUnitsWrap__AxesUnits_std__allocatorT_AxesUnitsWrap__AxesUnits_t_t[] = {  {&_swigt__p_std__vectorT_AxesUnitsWrap__AxesUnits_std__allocatorT_AxesUnitsWrap__AxesUnits_t_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__vectorT_AxisInfo_std__allocatorT_AxisInfo_t_t[] = {  {&_swigt__p_std__vectorT_AxisInfo_std__allocatorT_AxisInfo_t_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__vectorT_BasicVector3DT_double_t_std__allocatorT_BasicVector3DT_double_t_t_t[] = {  {&_swigt__p_std__vectorT_BasicVector3DT_double_t_std__allocatorT_BasicVector3DT_double_t_t_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__vectorT_BasicVector3DT_std__complexT_double_t_t_std__allocatorT_BasicVector3DT_std__complexT_double_t_t_t_t[] = {  {&_swigt__p_std__vectorT_BasicVector3DT_std__complexT_double_t_t_std__allocatorT_BasicVector3DT_std__complexT_double_t_t_t_t, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__vectorT_FitElement_std__allocatorT_FitElement_t_t[] = {  {&_swigt__p_std__vectorT_FitElement_std__allocatorT_FitElement_t_t, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__vectorT_FitElement_std__allocatorT_FitElement_t_t__iterator[] = {  {&_swigt__p_std__vectorT_FitElement_std__allocatorT_FitElement_t_t__iterator, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__vectorT_HomogeneousRegion_std__allocatorT_HomogeneousRegion_t_t[] = {  {&_swigt__p_std__vectorT_HomogeneousRegion_std__allocatorT_HomogeneousRegion_t_t, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__vectorT_IFitParameter_p_std__allocatorT_IFitParameter_p_t_t__const_iterator[] = {  {&_swigt__p_std__vectorT_IFitParameter_p_std__allocatorT_IFitParameter_p_t_t__const_iterator, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__vectorT_IFitParameter_p_std__allocatorT_IFitParameter_p_t_t__iterator[] = {  {&_swigt__p_std__vectorT_IFitParameter_p_std__allocatorT_IFitParameter_p_t_t__iterator, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__vectorT_IFormFactor_p_std__allocatorT_IFormFactor_p_t_t[] = {  {&_swigt__p_std__vectorT_IFormFactor_p_std__allocatorT_IFormFactor_p_t_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__vectorT_ILayout_const_p_std__allocatorT_ILayout_const_p_t_t[] = {  {&_swigt__p_std__vectorT_ILayout_const_p_std__allocatorT_ILayout_const_p_t_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__vectorT_INode_const_p_std__allocatorT_INode_const_p_t_t[] = {  {&_swigt__p_std__vectorT_INode_const_p_std__allocatorT_INode_const_p_t_t, 0, 0, 0},{0, 0, 0, 0}};
@@ -143624,8 +136116,6 @@ static swig_cast_info _swigc__p_unsigned_short[] = {  {&_swigt__p_unsigned_short
 static swig_cast_info _swigc__p_value_type[] = {  {&_swigt__p_value_type, 0, 0, 0},{0, 0, 0, 0}};
 
 static swig_cast_info *swig_cast_initial[] = {
-  _swigc__p_AdjustMinimizerStrategy,
-  _swigc__p_AttLimits,
   _swigc__p_Attributes,
   _swigc__p_AxesUnitsWrap,
   _swigc__p_AxesUnitsWrap__AxesUnits,
@@ -143676,17 +136166,8 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_FTDistribution2DGate,
   _swigc__p_FTDistribution2DGauss,
   _swigc__p_FTDistribution2DVoigt,
-  _swigc__p_FitObject,
   _swigc__p_FitObjective,
-  _swigc__p_FitObjects_t,
   _swigc__p_FitOptions,
-  _swigc__p_FitParameter,
-  _swigc__p_FitParameterSet,
-  _swigc__p_FitStrategyDefault,
-  _swigc__p_FitSuite,
-  _swigc__p_FitSuiteImpl,
-  _swigc__p_FitSuiteObjects,
-  _swigc__p_FitSuiteStrategies,
   _swigc__p_Fit__MinimizerResult,
   _swigc__p_Fit__Parameters,
   _swigc__p_FixedBinAxis,
@@ -143715,6 +136196,7 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_FormFactorGauss,
   _swigc__p_FormFactorHemiEllipsoid,
   _swigc__p_FormFactorIcosahedron,
+  _swigc__p_FormFactorLongBox,
   _swigc__p_FormFactorLongBoxGauss,
   _swigc__p_FormFactorLongBoxLorentz,
   _swigc__p_FormFactorLongRipple1Gauss,
@@ -143740,7 +136222,7 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_FormFactorTruncatedSpheroid,
   _swigc__p_FormFactorWeighted,
   _swigc__p_GISASSimulation,
-  _swigc__p_GaussPeakShape,
+  _swigc__p_GaussFisherPeakShape,
   _swigc__p_HexagonalLattice,
   _swigc__p_Histogram1D,
   _swigc__p_Histogram2D,
@@ -143761,9 +136243,6 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_IFTDistribution2D,
   _swigc__p_IFactoryT_std__string_IMultiLayerBuilder_t,
   _swigc__p_IFactoryT_std__string_Simulation_t,
-  _swigc__p_IFitObserver,
-  _swigc__p_IFitParameter,
-  _swigc__p_IFitStrategy,
   _swigc__p_IFootprintFactor,
   _swigc__p_IFormFactor,
   _swigc__p_IFormFactorBorn,
@@ -143774,7 +136253,6 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_IInterferenceFunction,
   _swigc__p_ILatticeOrientation,
   _swigc__p_ILayout,
-  _swigc__p_IMinimizer,
   _swigc__p_IMultiLayerBuilder,
   _swigc__p_INamed,
   _swigc__p_INode,
@@ -143791,8 +136269,8 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_ISample,
   _swigc__p_ISelectionRule,
   _swigc__p_IShape2D,
-  _swigc__p_ISquaredFunction,
   _swigc__p_IUnitConverter,
+  _swigc__p_IVarianceFunction,
   _swigc__p_IdentityRotation,
   _swigc__p_Instrument,
   _swigc__p_IntensityDataIOFactory,
@@ -143806,9 +136284,12 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_InterferenceFunction2DSuperLattice,
   _swigc__p_InterferenceFunction3DLattice,
   _swigc__p_InterferenceFunctionFinite2DLattice,
+  _swigc__p_InterferenceFunctionFinite3DLattice,
   _swigc__p_InterferenceFunctionNone,
   _swigc__p_InterferenceFunctionRadialParaCrystal,
   _swigc__p_IsGISAXSDetector,
+  _swigc__p_IsotropicGaussPeakShape,
+  _swigc__p_IsotropicLorentzPeakShape,
   _swigc__p_IterationInfo,
   _swigc__p_Lattice,
   _swigc__p_Lattice1DParameters,
@@ -143818,6 +136299,7 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_LayerInterface,
   _swigc__p_LayerRoughness,
   _swigc__p_Line,
+  _swigc__p_LorentzFisherPeakShape,
   _swigc__p_Material,
   _swigc__p_MesoCrystal,
   _swigc__p_MillerIndex,
@@ -143859,7 +136341,6 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_RotationX,
   _swigc__p_RotationY,
   _swigc__p_RotationZ,
-  _swigc__p_SafePointerVectorT_FitObject_t__iterator,
   _swigc__p_SafePointerVectorT_IParticle_t,
   _swigc__p_SafePointerVectorT_Layer_t,
   _swigc__p_SampleBuilderFactory,
@@ -143876,14 +136357,11 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_SphericalDetector,
   _swigc__p_SphericalPixel,
   _swigc__p_SquareLattice,
-  _swigc__p_SquaredFunctionDefault,
-  _swigc__p_SquaredFunctionGaussianError,
-  _swigc__p_SquaredFunctionMeanSquaredError,
-  _swigc__p_SquaredFunctionSimError,
-  _swigc__p_SquaredFunctionSystematicError,
   _swigc__p_ThreadInfo,
   _swigc__p_Transform3D,
   _swigc__p_VariableBinAxis,
+  _swigc__p_VarianceConstantFunction,
+  _swigc__p_VarianceSimFunction,
   _swigc__p_VerticalLine,
   _swigc__p_WavevectorInfo,
   _swigc__p_ZLimits,
@@ -143892,7 +136370,6 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_char,
   _swigc__p_const_iterator,
   _swigc__p_const_reference,
-  _swigc__p_container_t,
   _swigc__p_corr_matrix_t,
   _swigc__p_difference_type,
   _swigc__p_double,
@@ -143933,18 +136410,13 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_std__mapT_std__string_double_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_double_t_t_t,
   _swigc__p_std__mapT_std__string_std__string_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_std__string_t_t_t__const_iterator,
   _swigc__p_std__pairT_double_double_t,
-  _swigc__p_std__shared_ptrT_IFitObserver_t,
   _swigc__p_std__shared_ptrT_IMultiLayerBuilder_t,
   _swigc__p_std__shared_ptrT_IObserver_t,
   _swigc__p_std__vectorT_AxesUnitsWrap__AxesUnits_std__allocatorT_AxesUnitsWrap__AxesUnits_t_t,
   _swigc__p_std__vectorT_AxisInfo_std__allocatorT_AxisInfo_t_t,
   _swigc__p_std__vectorT_BasicVector3DT_double_t_std__allocatorT_BasicVector3DT_double_t_t_t,
   _swigc__p_std__vectorT_BasicVector3DT_std__complexT_double_t_t_std__allocatorT_BasicVector3DT_std__complexT_double_t_t_t_t,
-  _swigc__p_std__vectorT_FitElement_std__allocatorT_FitElement_t_t,
-  _swigc__p_std__vectorT_FitElement_std__allocatorT_FitElement_t_t__iterator,
   _swigc__p_std__vectorT_HomogeneousRegion_std__allocatorT_HomogeneousRegion_t_t,
-  _swigc__p_std__vectorT_IFitParameter_p_std__allocatorT_IFitParameter_p_t_t__const_iterator,
-  _swigc__p_std__vectorT_IFitParameter_p_std__allocatorT_IFitParameter_p_t_t__iterator,
   _swigc__p_std__vectorT_IFormFactor_p_std__allocatorT_IFormFactor_p_t_t,
   _swigc__p_std__vectorT_ILayout_const_p_std__allocatorT_ILayout_const_p_t_t,
   _swigc__p_std__vectorT_INode_const_p_std__allocatorT_INode_const_p_t_t,
diff --git a/auto/Wrap/libBornAgainCore_wrap.h b/auto/Wrap/libBornAgainCore_wrap.h
index b2158e20fcc3c4f35641ed9bad94d7be21a1ca76..c77216f09cf080bc2c036d314963d25d08db69bf 100644
--- a/auto/Wrap/libBornAgainCore_wrap.h
+++ b/auto/Wrap/libBornAgainCore_wrap.h
@@ -177,56 +177,12 @@ private:
 };
 
 
-class SwigDirector_IObservable : public IObservable, public Swig::Director {
-
-public:
-    SwigDirector_IObservable(PyObject *self);
-    virtual ~SwigDirector_IObservable();
-    virtual void attachObserver(IObservable::observer_t obj);
-    virtual void notifyObservers();
-
-/* Internal director utilities */
-public:
-    bool swig_get_inner(const char *swig_protected_method_name) const {
-      std::map<std::string, bool>::const_iterator iv = swig_inner.find(swig_protected_method_name);
-      return (iv != swig_inner.end() ? iv->second : false);
-    }
-    void swig_set_inner(const char *swig_protected_method_name, bool swig_val) const {
-      swig_inner[swig_protected_method_name] = swig_val;
-    }
-private:
-    mutable std::map<std::string, bool> swig_inner;
-
-#if defined(SWIG_PYTHON_DIRECTOR_VTABLE)
-/* VTable implementation */
-    PyObject *swig_get_method(size_t method_index, const char *method_name) const {
-      PyObject *method = vtable[method_index];
-      if (!method) {
-        swig::SwigVar_PyObject name = SWIG_Python_str_FromChar(method_name);
-        method = PyObject_GetAttr(swig_get_self(), name);
-        if (!method) {
-          std::string msg = "Method in class IObservable doesn't exist, undefined ";
-          msg += method_name;
-          Swig::DirectorMethodException::raise(msg.c_str());
-        }
-        vtable[method_index] = method;
-      }
-      return method;
-    }
-private:
-    mutable swig::SwigVar_PyObject vtable[2];
-#endif
-
-};
-
-
-class SwigDirector_IFitObserver : public IFitObserver, public Swig::Director {
+class SwigDirector_PyBuilderCallback : public PyBuilderCallback, public Swig::Director {
 
 public:
-    SwigDirector_IFitObserver(PyObject *self, int update_every_nth);
-    virtual ~SwigDirector_IFitObserver();
-    virtual void notify(IObservable *subject);
-    virtual void update(FitSuite *fit_suite);
+    SwigDirector_PyBuilderCallback(PyObject *self);
+    virtual ~SwigDirector_PyBuilderCallback();
+    virtual Simulation *build_simulation(Fit::Parameters arg0);
 
 /* Internal director utilities */
 public:
@@ -248,7 +204,7 @@ private:
         swig::SwigVar_PyObject name = SWIG_Python_str_FromChar(method_name);
         method = PyObject_GetAttr(swig_get_self(), name);
         if (!method) {
-          std::string msg = "Method in class IFitObserver doesn't exist, undefined ";
+          std::string msg = "Method in class PyBuilderCallback doesn't exist, undefined ";
           msg += method_name;
           Swig::DirectorMethodException::raise(msg.c_str());
         }
@@ -257,18 +213,18 @@ private:
       return method;
     }
 private:
-    mutable swig::SwigVar_PyObject vtable[2];
+    mutable swig::SwigVar_PyObject vtable[1];
 #endif
 
 };
 
 
-class SwigDirector_PyBuilderCallback : public PyBuilderCallback, public Swig::Director {
+class SwigDirector_PyObserverCallback : public PyObserverCallback, public Swig::Director {
 
 public:
-    SwigDirector_PyBuilderCallback(PyObject *self);
-    virtual ~SwigDirector_PyBuilderCallback();
-    virtual Simulation *build_simulation(Fit::Parameters arg0);
+    SwigDirector_PyObserverCallback(PyObject *self);
+    virtual ~SwigDirector_PyObserverCallback();
+    virtual void update(FitObjective const &arg0);
 
 /* Internal director utilities */
 public:
@@ -290,7 +246,7 @@ private:
         swig::SwigVar_PyObject name = SWIG_Python_str_FromChar(method_name);
         method = PyObject_GetAttr(swig_get_self(), name);
         if (!method) {
-          std::string msg = "Method in class PyBuilderCallback doesn't exist, undefined ";
+          std::string msg = "Method in class PyObserverCallback doesn't exist, undefined ";
           msg += method_name;
           Swig::DirectorMethodException::raise(msg.c_str());
         }
@@ -305,12 +261,13 @@ private:
 };
 
 
-class SwigDirector_PyObserverCallback : public PyObserverCallback, public Swig::Director {
+class SwigDirector_FitObjective : public FitObjective, public Swig::Director {
 
 public:
-    SwigDirector_PyObserverCallback(PyObject *self);
-    virtual ~SwigDirector_PyObserverCallback();
-    virtual void update(FitObjective const &arg0);
+    SwigDirector_FitObjective(PyObject *self);
+    virtual ~SwigDirector_FitObjective();
+    virtual double evaluate(Fit::Parameters const &params);
+    virtual std::vector< double,std::allocator< double > > evaluate_residuals(Fit::Parameters const &params);
 
 /* Internal director utilities */
 public:
@@ -332,7 +289,7 @@ private:
         swig::SwigVar_PyObject name = SWIG_Python_str_FromChar(method_name);
         method = PyObject_GetAttr(swig_get_self(), name);
         if (!method) {
-          std::string msg = "Method in class PyObserverCallback doesn't exist, undefined ";
+          std::string msg = "Method in class FitObjective doesn't exist, undefined ";
           msg += method_name;
           Swig::DirectorMethodException::raise(msg.c_str());
         }
@@ -341,7 +298,7 @@ private:
       return method;
     }
 private:
-    mutable swig::SwigVar_PyObject vtable[1];
+    mutable swig::SwigVar_PyObject vtable[2];
 #endif
 
 };
diff --git a/auto/Wrap/libBornAgainFit_wrap.cpp b/auto/Wrap/libBornAgainFit_wrap.cpp
index d118c8b718a875dceaf3051930ba0b9e5dd66583..7f1f26a9fd9f74f6da8f911a0ce3a59f296b568c 100644
--- a/auto/Wrap/libBornAgainFit_wrap.cpp
+++ b/auto/Wrap/libBornAgainFit_wrap.cpp
@@ -3484,25 +3484,23 @@ namespace Swig {
 #define SWIGTYPE_p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t swig_types[30]
 #define SWIGTYPE_p_std__allocatorT_unsigned_long_t swig_types[31]
 #define SWIGTYPE_p_std__invalid_argument swig_types[32]
-#define SWIGTYPE_p_std__shared_ptrT_IFitObserver_t swig_types[33]
-#define SWIGTYPE_p_std__shared_ptrT_IMultiLayerBuilder_t swig_types[34]
-#define SWIGTYPE_p_std__shared_ptrT_IObserver_t swig_types[35]
-#define SWIGTYPE_p_std__vectorT_Fit__Parameter_std__allocatorT_Fit__Parameter_t_t__const_iterator swig_types[36]
-#define SWIGTYPE_p_std__vectorT_Fit__Parameter_std__allocatorT_Fit__Parameter_t_t__iterator swig_types[37]
-#define SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t swig_types[38]
-#define SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t swig_types[39]
-#define SWIGTYPE_p_std__vectorT_std__complexT_double_t_std__allocatorT_std__complexT_double_t_t_t swig_types[40]
-#define SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t swig_types[41]
-#define SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t swig_types[42]
-#define SWIGTYPE_p_std__vectorT_unsigned_long_std__allocatorT_unsigned_long_t_t swig_types[43]
-#define SWIGTYPE_p_swig__SwigPyIterator swig_types[44]
-#define SWIGTYPE_p_unsigned_char swig_types[45]
-#define SWIGTYPE_p_unsigned_int swig_types[46]
-#define SWIGTYPE_p_unsigned_long_long swig_types[47]
-#define SWIGTYPE_p_unsigned_short swig_types[48]
-#define SWIGTYPE_p_value_type swig_types[49]
-static swig_type_info *swig_types[51];
-static swig_module_info swig_module = {swig_types, 50, 0, 0, 0, 0};
+#define SWIGTYPE_p_std__shared_ptrT_IMultiLayerBuilder_t swig_types[33]
+#define SWIGTYPE_p_std__vectorT_Fit__Parameter_std__allocatorT_Fit__Parameter_t_t__const_iterator swig_types[34]
+#define SWIGTYPE_p_std__vectorT_Fit__Parameter_std__allocatorT_Fit__Parameter_t_t__iterator swig_types[35]
+#define SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t swig_types[36]
+#define SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t swig_types[37]
+#define SWIGTYPE_p_std__vectorT_std__complexT_double_t_std__allocatorT_std__complexT_double_t_t_t swig_types[38]
+#define SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t swig_types[39]
+#define SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t swig_types[40]
+#define SWIGTYPE_p_std__vectorT_unsigned_long_std__allocatorT_unsigned_long_t_t swig_types[41]
+#define SWIGTYPE_p_swig__SwigPyIterator swig_types[42]
+#define SWIGTYPE_p_unsigned_char swig_types[43]
+#define SWIGTYPE_p_unsigned_int swig_types[44]
+#define SWIGTYPE_p_unsigned_long_long swig_types[45]
+#define SWIGTYPE_p_unsigned_short swig_types[46]
+#define SWIGTYPE_p_value_type swig_types[47]
+static swig_type_info *swig_types[49];
+static swig_module_info swig_module = {swig_types, 48, 0, 0, 0, 0};
 #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
 #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
 
@@ -23764,9 +23762,7 @@ static swig_type_info _swigt__p_std__allocatorT_std__string_t = {"_p_std__alloca
 static swig_type_info _swigt__p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t = {"_p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t", "std::vector< std::vector< double > >::allocator_type *|std::allocator< std::vector< double,std::allocator< double > > > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__allocatorT_unsigned_long_t = {"_p_std__allocatorT_unsigned_long_t", "std::vector< unsigned long >::allocator_type *|std::allocator< unsigned long > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__invalid_argument = {"_p_std__invalid_argument", "std::invalid_argument *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__shared_ptrT_IFitObserver_t = {"_p_std__shared_ptrT_IFitObserver_t", "std::shared_ptr< IFitObserver > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__shared_ptrT_IMultiLayerBuilder_t = {"_p_std__shared_ptrT_IMultiLayerBuilder_t", "std::shared_ptr< IMultiLayerBuilder > *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__shared_ptrT_IObserver_t = {"_p_std__shared_ptrT_IObserver_t", "std::shared_ptr< IObserver > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__vectorT_Fit__Parameter_std__allocatorT_Fit__Parameter_t_t__const_iterator = {"_p_std__vectorT_Fit__Parameter_std__allocatorT_Fit__Parameter_t_t__const_iterator", "std::vector< Fit::Parameter,std::allocator< Fit::Parameter > >::const_iterator *|Fit::Parameters::const_iterator *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__vectorT_Fit__Parameter_std__allocatorT_Fit__Parameter_t_t__iterator = {"_p_std__vectorT_Fit__Parameter_std__allocatorT_Fit__Parameter_t_t__iterator", "std::vector< Fit::Parameter,std::allocator< Fit::Parameter > >::iterator *|Fit::Parameters::iterator *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__vectorT_double_std__allocatorT_double_t_t = {"_p_std__vectorT_double_std__allocatorT_double_t_t", "std::vector< double,std::allocator< double > > *|std::vector< double > *", 0, 0, (void*)0, 0};
@@ -23816,9 +23812,7 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t,
   &_swigt__p_std__allocatorT_unsigned_long_t,
   &_swigt__p_std__invalid_argument,
-  &_swigt__p_std__shared_ptrT_IFitObserver_t,
   &_swigt__p_std__shared_ptrT_IMultiLayerBuilder_t,
-  &_swigt__p_std__shared_ptrT_IObserver_t,
   &_swigt__p_std__vectorT_Fit__Parameter_std__allocatorT_Fit__Parameter_t_t__const_iterator,
   &_swigt__p_std__vectorT_Fit__Parameter_std__allocatorT_Fit__Parameter_t_t__iterator,
   &_swigt__p_std__vectorT_double_std__allocatorT_double_t_t,
@@ -23868,9 +23862,7 @@ static swig_cast_info _swigc__p_std__allocatorT_std__string_t[] = {  {&_swigt__p
 static swig_cast_info _swigc__p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t[] = {  {&_swigt__p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__allocatorT_unsigned_long_t[] = {  {&_swigt__p_std__allocatorT_unsigned_long_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__invalid_argument[] = {  {&_swigt__p_std__invalid_argument, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__shared_ptrT_IFitObserver_t[] = {  {&_swigt__p_std__shared_ptrT_IFitObserver_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__shared_ptrT_IMultiLayerBuilder_t[] = {  {&_swigt__p_std__shared_ptrT_IMultiLayerBuilder_t, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__shared_ptrT_IObserver_t[] = {  {&_swigt__p_std__shared_ptrT_IObserver_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__vectorT_Fit__Parameter_std__allocatorT_Fit__Parameter_t_t__const_iterator[] = {  {&_swigt__p_std__vectorT_Fit__Parameter_std__allocatorT_Fit__Parameter_t_t__const_iterator, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__vectorT_Fit__Parameter_std__allocatorT_Fit__Parameter_t_t__iterator[] = {  {&_swigt__p_std__vectorT_Fit__Parameter_std__allocatorT_Fit__Parameter_t_t__iterator, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__vectorT_double_std__allocatorT_double_t_t[] = {  {&_swigt__p_std__vectorT_double_std__allocatorT_double_t_t, 0, 0, 0},{0, 0, 0, 0}};
@@ -23920,9 +23912,7 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t,
   _swigc__p_std__allocatorT_unsigned_long_t,
   _swigc__p_std__invalid_argument,
-  _swigc__p_std__shared_ptrT_IFitObserver_t,
   _swigc__p_std__shared_ptrT_IMultiLayerBuilder_t,
-  _swigc__p_std__shared_ptrT_IObserver_t,
   _swigc__p_std__vectorT_Fit__Parameter_std__allocatorT_Fit__Parameter_t_t__const_iterator,
   _swigc__p_std__vectorT_Fit__Parameter_std__allocatorT_Fit__Parameter_t_t__iterator,
   _swigc__p_std__vectorT_double_std__allocatorT_double_t_t,
diff --git a/cmake/bornagain/modules/BornAgainCPack.cmake b/cmake/bornagain/modules/BornAgainCPack.cmake
index cea5857dc682c24961102f18e94434640db95465..0977d0f07919124fdf4b8ac7616c6932a63786df 100644
--- a/cmake/bornagain/modules/BornAgainCPack.cmake
+++ b/cmake/bornagain/modules/BornAgainCPack.cmake
@@ -6,7 +6,7 @@ set(BORNAGAIN_VERSION "${BornAgain_VERSION_MAJOR}.${BornAgain_VERSION_MINOR}.${B
 
 set(CPACK_PACKAGE_NAME "BornAgain")
 set(CPACK_PACKAGE_DESCRIPTION "BornAgain: simulate and fit scattering at grazing incidence.")
-set(CPACK_PACKAGE_VENDOR "Forschungszentrum Juelich GmbH. Scientific Computing Group at MLZ Garching.")
+set(CPACK_PACKAGE_VENDOR "Forschungszentrum Juelich GmbH")
 set(CPACK_PACKAGE_VERSION ${BORNAGAIN_VERSION})
 set(CPACK_PACKAGE_VERSION_MAJOR ${BornAgain_VERSION_MAJOR})
 set(CPACK_PACKAGE_VERSION_MINOR ${BornAgain_VERSION_MINOR})
@@ -42,6 +42,9 @@ endif()
 set(CPACK_SOURCE_GENERATOR "TGZ")
 set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
 
+message(STATUS "Installer name: ${CPACK_PACKAGE_FILE_NAME}")
+message(STATUS "Source package name: ${CPACK_SOURCE_PACKAGE_FILE_NAME}")
+
 # Specify which files not to include into the source package generated by make package_source
 set(CPACK_SOURCE_IGNORE_FILES
     ${CPACK_SOURCE_IGNORE_FILES} # first take the default parameters
@@ -80,4 +83,3 @@ set(CPACK_SOURCE_IGNORE_FILES
 include(CPack)
 
 set(CPACK_COMPONENTS_ALL Libraries Headers Examples)
-
diff --git a/cmake/bornagain/modules/BornAgainPolicy.cmake b/cmake/bornagain/modules/BornAgainPolicy.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..15eb6dcece9911a39dfa08012df96d5b4eb60e55
--- /dev/null
+++ b/cmake/bornagain/modules/BornAgainPolicy.cmake
@@ -0,0 +1,25 @@
+if(APPLE)
+if(POLICY CMP0025)
+    cmake_policy(SET CMP0025 NEW)
+endif()
+endif()
+
+if(POLICY CMP0020)
+    cmake_policy(SET CMP0020 NEW)
+endif()
+
+if(POLICY CMP0028)
+    cmake_policy(SET CMP0028 NEW)
+endif()
+
+if(POLICY CMP0042)
+    cmake_policy(SET CMP0042 NEW)
+endif()
+
+if(POLICY CMP0043)
+    cmake_policy(SET CMP0043 NEW)
+endif()
+
+if(POLICY CMP0071)
+  cmake_policy(SET CMP0071 NEW)
+endif()
diff --git a/cmake/bornagain/modules/CPackApple.cmake b/cmake/bornagain/modules/CPackApple.cmake
index c523c827fa70fee378268cd956a61c9f1c363629..f19dac116ac6c05345f2c78c9385a4cc843db8bc 100644
--- a/cmake/bornagain/modules/CPackApple.cmake
+++ b/cmake/bornagain/modules/CPackApple.cmake
@@ -1,13 +1,9 @@
 # BornAgain Mac packaging 
 
-if(BORNAGAIN_USE_PYTHON3)
-  set(MAC_PYTHON_VERSION "python3")
-else()
-  set(MAC_PYTHON_VERSION "python2")
-endif()
+set(SELECTED_PYTHON_VERSION "python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}")
 
 set(CPACK_PACKAGE_FILE_NAME
-    "${CMAKE_PROJECT_NAME}-${BORNAGAIN_VERSION}-${MAC_PYTHON_VERSION}-${BORNAGAIN_ARCHITECTURE}-10.10+")
+    "${CMAKE_PROJECT_NAME}-${BORNAGAIN_VERSION}-${SELECTED_PYTHON_VERSION}-${BORNAGAIN_ARCHITECTURE}-10.10+")
 
 set(CPACK_BINARY_DRAGNDROP ON)
 set(CPACK_GENERATOR "DragNDrop")
diff --git a/cmake/bornagain/modules/CPackWindows.cmake b/cmake/bornagain/modules/CPackWindows.cmake
index fc4436e3095789e4bccb91f78b6f5ccd79c0d09c..91705c836ab992d6b7a4fb51e486edb8e2187842 100644
--- a/cmake/bornagain/modules/CPackWindows.cmake
+++ b/cmake/bornagain/modules/CPackWindows.cmake
@@ -1,13 +1,9 @@
 # BornAgain Windows packaging
 
-if(BORNAGAIN_USE_PYTHON3)
-  set(WIN_PYTHON_VERSION "python3")
-else()
-  set(WIN_PYTHON_VERSION "python2")
-endif()
+set(SELECTED_PYTHON_VERSION "python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}")
 
 set(CPACK_PACKAGE_FILE_NAME
-    "${CMAKE_PROJECT_NAME}-${BORNAGAIN_VERSION}-${WIN_PYTHON_VERSION}-${BORNAGAIN_ARCHITECTURE}")
+    "${CMAKE_PROJECT_NAME}-${BORNAGAIN_VERSION}-${SELECTED_PYTHON_VERSION}-${BORNAGAIN_ARCHITECTURE}")
 
 set(CPACK_GENERATOR "NSIS")
 
diff --git a/cmake/bornagain/modules/SearchInstalledSoftware.cmake b/cmake/bornagain/modules/SearchInstalledSoftware.cmake
index 002df74014a2d55419ea6f74f4fa03f04a8d085e..76beb903a48fe635fe7a0449324a9f271747d1c6 100644
--- a/cmake/bornagain/modules/SearchInstalledSoftware.cmake
+++ b/cmake/bornagain/modules/SearchInstalledSoftware.cmake
@@ -47,11 +47,14 @@ if (BORNAGAIN_GENERATE_BINDINGS AND BORNAGAIN_GENERATE_PYTHON_DOCS)
     find_package(Doxygen REQUIRED)
 endif()
 
-if (BORNAGAIN_USE_PYTHON3)
-    set(Python_ADDITIONAL_VERSIONS 3.6 3.5 3.4 3.3)
-else()
-    set(Python_ADDITIONAL_VERSIONS 2.7)
+if (NOT DEFINED Python_ADDITIONAL_VERSIONS)
+    if (BORNAGAIN_USE_PYTHON3)
+        set(Python_ADDITIONAL_VERSIONS 3.7 3.6 3.5 3.4 3.3)
+    else()
+        set(Python_ADDITIONAL_VERSIONS 2.7)
+    endif()
 endif()
+message(STATUS "Requested Python versions ${Python_ADDITIONAL_VERSIONS}")
 
 if(BORNAGAIN_PYTHON OR BORNAGAIN_GUI)
     find_package(PythonInterp REQUIRED)
diff --git a/cmake/generic/modules/AddGTest.cmake b/cmake/generic/modules/AddGTest.cmake
deleted file mode 100644
index d1d1289b21b7578d23c11d235af5fd30b8c7328b..0000000000000000000000000000000000000000
--- a/cmake/generic/modules/AddGTest.cmake
+++ /dev/null
@@ -1,42 +0,0 @@
-#################################################################################
-#
-#  BornAgain: simulate and fit scattering at grazing incidence
-#
-#  @file      cmake/bornagain/modules/AddGTest.cmake
-#  @brief     Implements macro ADD_GTEST(..)
-#
-#  @homepage  http://www.bornagainproject.org
-#  @license   GNU General Public License v3 or higher (see COPYING)
-#  @copyright Forschungszentrum Jülich GmbH 2016
-#  @authors   Scientific Computing Group at MLZ Garching
-#  @authors   J. Fisher, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke
-#
-##################################################################################
-
-#  @brief Build test target from ${subdir}/main.cpp.
-
-#  stage=0: test run at compile time
-#  stage=1: test run upon "ctest"="make check"
-#  stage=2: test run upon "ctest"="make fullcheck"
-
-MACRO(ADD_GTEST project subdir libs stage)
-    set(TEST_NAME ${project}${subdir})
-    set(EXE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TEST_NAME})
-    file(GLOB include_files ${subdir}/*.h)
-    add_executable(${TEST_NAME} ${subdir}/../../utilities/main_testlist.cpp ${include_files})
-    target_include_directories(${TEST_NAME} PUBLIC ${subdir})
-    target_link_libraries(${TEST_NAME} gtest ${libs})
-    if    (${stage} EQUAL 0)
-        # Execute test just after compilation
-        add_custom_target(${TEST_NAME}_run ALL DEPENDS ${TEST_NAME} COMMAND ${EXE})
-    elseif(${stage} EQUAL 1)
-        # Put test under control of CTest
-        add_test(${TEST_NAME} ${EXE})
-    elseif(${stage} EQUAL 2)
-        # Put test under control of CTest in "fullcheck" section
-        add_test(${TEST_NAME} ${EXE})
-        set_tests_properties(${TEST_NAME} PROPERTIES LABELS "Fullcheck")
-    else()
-        message(FATAL_ERROR "invalid parameter stage=${stage} in ADD_GTEST")
-    endif()
-ENDMACRO()
diff --git a/cmake/generic/modules/PreventInSourceBuilds.cmake b/cmake/generic/modules/PreventInSourceBuilds.cmake
index 48ff010bf57549a147f4f51c2142d20d87f6878a..ca2ee52036b47a8160c6b3b85ac4aa689673263e 100644
--- a/cmake/generic/modules/PreventInSourceBuilds.cmake
+++ b/cmake/generic/modules/PreventInSourceBuilds.cmake
@@ -6,7 +6,7 @@ function(prevent_in_source_builds)
   get_filename_component(bindir "${CMAKE_BINARY_DIR}" REALPATH)
 
   # disallow in-source builds
-  if("${srcdir}" STREQUAL "${bindir}")
+  if(srcdir STREQUAL bindir)
     message(FATAL_ERROR "\
 
 CMake must not to be run in the source directory. \
diff --git a/cmake/generic/modules/ThirdPartyLibUtilities.cmake b/cmake/generic/modules/ThirdPartyLibUtilities.cmake
deleted file mode 100644
index fc09da958946fe5864ac2bbbc153a60112b6c277..0000000000000000000000000000000000000000
--- a/cmake/generic/modules/ThirdPartyLibUtilities.cmake
+++ /dev/null
@@ -1,14 +0,0 @@
-# Utilities for treating certain third-party libraries/headers
-# as system ones.
-# include_as_system_directory mutes all warnings from particular
-# directory which arise during compilation
-
-function(include_as_system_directory DIR)
-    if(NOT DIR)
-        message(FATAL_ERROR
-                "include_as_system_directory:
-                directory is undefined"
-               )
-    endif(NOT DIR)
-    include_directories(SYSTEM "${DIR}")
-endfunction(include_as_system_directory)
diff --git a/dev-tools/code-tools/update-gtestlist.py b/dev-tools/code-tools/update-gtestlist.py
deleted file mode 100755
index 68e0e10b19e40ef4db5a25dd799f898835f303e4..0000000000000000000000000000000000000000
--- a/dev-tools/code-tools/update-gtestlist.py
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/env python3
-
-"""
-Renews file testlist.h in given unit test subdirectory.
-This file just includes all other files from that directory.
-"""
-
-import fnmatch, glob, os, re, sys
-
-def find(pattern, path):
-    result = []
-    for root, dirs, files in os.walk(path):
-        for name in files:
-            if fnmatch.fnmatch(name, pattern):
-                result.append( name )
-    return result
-
-if( len(sys.argv)<=1 ):
-    print( "Usage: %s <directories>" % sys.argv[0] )
-    sys.exit(0)
-
-filelist = []
-for dir in sys.argv[1:]:
-    filelist = find( '*.h', dir )
-    fd = open( dir+"/testlist.h", "w" )
-    fd.write( "// To renew this file, run %s <directory>\n\n" % sys.argv[0] )
-    for fname in filelist:
-        if fname=="testlist.h":
-            continue
-        fd.write( '#include "%s"\n' % fname )
-    fd.close()
diff --git a/dev-tools/deploy/yosemite-dev/build_bornagain.sh b/dev-tools/deploy/yosemite-dev/build_bornagain.sh
index 4bea7aa0105c91c1a34bd12b07f537917bbf881c..a9f1fc43700c528837c1c80bb9562946533d7eba 100644
--- a/dev-tools/deploy/yosemite-dev/build_bornagain.sh
+++ b/dev-tools/deploy/yosemite-dev/build_bornagain.sh
@@ -1,42 +1,43 @@
 #!/usr/bin/env bash
 
-
-#export QTDIR=/usr/local/opt/qt5
 export QTDIR=/Users/vagrant/Qt/5.10.1/clang_64
-export PATH=/usr/local/bin:$QTDIR/bin/:$PATH
+export PATH=/Users/vagrant/.pyenv:/usr/local/bin:$QTDIR/bin/:$PATH
 export WORKDIR=/Users/vagrant/build
 rm -r -f $WORKDIR; mkdir -p $WORKDIR; cd $WORKDIR;
 
-#git clone --recurse-submodules -b develop https://github.com/scgmlz/BornAgain.git
-git clone --recurse-submodules -b MacBuild https://github.com/gpospelov/BornAgain.git
-
-# --------------------------------------------------------------------
-echo 'Building on Python2'
-# --------------------------------------------------------------------
-
-mkdir BornAgain-build-python2
-cd BornAgain-build-python2
-#export ANACONDA=/Users/vagrant/anaconda2
-#cmake -DCMAKE_C_COMPILER=/usr/local/opt/llvm/bin/clang -DCMAKE_CXX_COMPILER=/usr/local/opt/llvm/bin/clang++  -DPYTHON_LIBRARY=$ANACONDA/lib/libpython2.7.dylib -DPYTHON_EXECUTABLE=$ANACONDA/bin/python2.7 -DBORNAGAIN_APPLE_BUNDLE=ON -DCMAKE_PREFIX_PATH=/usr/local ../BornAgain
-cmake -DCMAKE_C_COMPILER=/usr/local/opt/llvm/bin/clang -DCMAKE_CXX_COMPILER=/usr/local/opt/llvm/bin/clang++ -DBORNAGAIN_USE_PYTHON3=OFF -DBORNAGAIN_APPLE_BUNDLE=ON -DCMAKE_PREFIX_PATH=/usr/local ../BornAgain
-make -j4
-cpack -V
-
-echo 'Copying dmg installer back to build server'
-echo 'scp /Users/vagrant/build/BornAgain-build-python2/*.dmg scg@scgmini:./deployment/results/.'
-scp /Users/vagrant/build/BornAgain-build-python2/*.dmg scg@scgmini:./deployment/results/.
-
-# --------------------------------------------------------------------
-echo 'Building on Python3'
-# --------------------------------------------------------------------
-cd $WORKDIR
-
-mkdir BornAgain-build-python3
-cd BornAgain-build-python3
-cmake -DCMAKE_C_COMPILER=/usr/local/opt/llvm/bin/clang -DCMAKE_CXX_COMPILER=/usr/local/opt/llvm/bin/clang++ -DBORNAGAIN_USE_PYTHON3=ON -DBORNAGAIN_APPLE_BUNDLE=ON -DCMAKE_PREFIX_PATH=/usr/local ../BornAgain
-make -j4
-cpack -V
-
-echo 'Copying dmg installer back to build server'
-echo 'scp /Users/vagrant/build/BornAgain-build-python3/*.dmg scg@scgmini:./deployment/results/.'
-scp /Users/vagrant/build/BornAgain-build-python3/*.dmg scg@scgmini:./deployment/results/.
+git clone --recurse-submodules -b release-1.14.0 https://github.com/develop/BornAgain.git
+
+
+pyversions[1]=2.7.15
+pyversions[2]=3.6.7
+pyversions[3]=3.7.1
+
+pyadd[1]=2.7
+pyadd[2]=3.6
+pyadd[3]=3.7
+
+for i in {1..3}
+do
+    cd $WORKDIR;
+    export PYVER=${pyversions[$i]}
+    export PYSHORT=${pyadd[$i]}
+    echo "Building on" $PYVER $PYADD
+    export BUILDDIR=build-$PYVER
+    mkdir $BUILDDIR
+    cd $BUILDDIR
+    echo "PWD" $PWD "PYVER" $PYVER "PYSHORT" $PYSHORT
+    eval "$(pyenv init -)"
+    pyenv local $PYVER
+
+    export PYEXE=/Users/vagrant/.pyenv/versions/${PYVER}/bin/python
+    export PYLIB=/Users/vagrant/.pyenv/versions/${PYVER}/lib/libpython${PYSHORT}m.dylib
+    echo "PYEXE" $PYEXE
+    echo "PYLIB" $PYLIB
+
+    cmake -DCMAKE_C_COMPILER=/usr/local/opt/llvm/bin/clang -DCMAKE_CXX_COMPILER=/usr/local/opt/llvm/bin/clang++ -DPython_ADDITIONAL_VERSIONS=$PYSHORT -DBORNAGAIN_APPLE_BUNDLE=ON  -DPYTHON_LIBRARY=$PYLIB -DPYTHON_EXECUTABLE=$PYEXE -DCMAKE_PREFIX_PATH=/usr/local ../BornAgain
+    make -j4
+    cpack -V
+    echo 'Copying dmg installer back to build server'
+    echo 'scp /Users/vagrant/build/BornAgain-build-python2/*.dmg scg@scgmini:./deployment/results/.'
+    scp /Users/vagrant/build/$BUILDDIR/*.dmg scg@scgmini:./deployment/results/.
+done