diff --git a/Base/Axis/IAxis.cpp b/Base/Axis/IAxis.cpp
index 051c9ba8a9b9cc29ff4f1554e8c02e314ffb372e..4dfdc78fd500cbd60244bb9794d85bba4254a1b7 100644
--- a/Base/Axis/IAxis.cpp
+++ b/Base/Axis/IAxis.cpp
@@ -39,5 +39,5 @@ double IAxis::span() const {
 }
 
 double IAxis::center() const {
-    return (upperBound() + lowerBound())/2;
+    return (upperBound() + lowerBound()) / 2;
 }
diff --git a/Base/Axis/IAxis.h b/Base/Axis/IAxis.h
index f4ba5bf2186e587853d7130b6ff48dac95409ff3..dc2ea39316e6626d62e3df51e971499c550af785 100644
--- a/Base/Axis/IAxis.h
+++ b/Base/Axis/IAxis.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_AXIS_IAXIS_H
 #define BORNAGAIN_BASE_AXIS_IAXIS_H
 
@@ -100,3 +101,4 @@ inline bool HaveSameNameAndShape(const IAxis& left, const IAxis& right) {
 }
 
 #endif // BORNAGAIN_BASE_AXIS_IAXIS_H
+#endif // USER_API
diff --git a/Base/Axis/PointwiseAxis.h b/Base/Axis/PointwiseAxis.h
index 82499fcde21ebbecd80dc9daadd6dc32ce1dc95e..82de012a21d3f38b1e4d2d0eb29c6d673d2fdeca 100644
--- a/Base/Axis/PointwiseAxis.h
+++ b/Base/Axis/PointwiseAxis.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_AXIS_POINTWISEAXIS_H
 #define BORNAGAIN_BASE_AXIS_POINTWISEAXIS_H
 
@@ -89,3 +90,4 @@ private:
 };
 
 #endif // BORNAGAIN_BASE_AXIS_POINTWISEAXIS_H
+#endif // USER_API
diff --git a/Base/Const/PhysicalConstants.h b/Base/Const/PhysicalConstants.h
index d76ddd9afa14bff4c709a72e345e35efd90f21df..5ff809e4877ef0815bd13f882fbf6810ebb7b66a 100644
--- a/Base/Const/PhysicalConstants.h
+++ b/Base/Const/PhysicalConstants.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_CONST_PHYSICALCONSTANTS_H
 #define BORNAGAIN_BASE_CONST_PHYSICALCONSTANTS_H
 
@@ -35,3 +36,4 @@ constexpr double g_factor_n = -3.82608545; //!< neutron g-factor
 } // namespace PhysConsts
 
 #endif // BORNAGAIN_BASE_CONST_PHYSICALCONSTANTS_H
+#endif // USER_API
diff --git a/Base/Const/Units.h b/Base/Const/Units.h
index b8ce27bb73ea5950d1502f5e409e5bb90d9c75bc..5832545c91903fe344209e97e5c32d574c18271a 100644
--- a/Base/Const/Units.h
+++ b/Base/Const/Units.h
@@ -16,45 +16,49 @@
 #define BORNAGAIN_BASE_CONST_UNITS_H
 
 //! Constants and functions for physical unit conversions.
+//!
+//! In user code, quantities that have a physical dimension should always
+//! be given in the form _value * unit_, e.g. 0.529 * angstrom for a length,
+//! or 45 * deg for an angle.
+//!
+//! Internally, BornAgain has length, angle, magnetic field units of nanometer,
+//! radians, Tesla. Therefore, in principle, the multipliers nm, rad, tesla could
+//! be ommited from code. However, to make code more readable, and to prevent
+//! misunderstandings, we recommend that physical dimension be always made clear
+//! by multiplying values with an appropriate constant, even if this expands to 1.
 
 namespace Units {
 
 // Length
-static constexpr double nanometer = 1.;
+static constexpr double nanometer = 1.; //!< Internal unit for lengths
 static constexpr double angstrom = 1.e-1 * nanometer;
 static constexpr double micrometer = 1.e+3 * nanometer;
 static constexpr double millimeter = 1.e+6 * nanometer;
-static constexpr double meter = 1.e+9 * nanometer;
 
 // Symbols for length
 static constexpr double nm = nanometer;
 
 // Area (cross-section)
 static constexpr double nm2 = nanometer * nanometer;
-static constexpr double barn = nanometer * nanometer * 1e-10;
 
 // Angle
-static constexpr double radian = 1.;
-static constexpr double milliradian = 1.e-3 * radian;
-static constexpr double degree = (3.1415926535897932 / 180.0) * radian;
-static constexpr double steradian = 1.;
+static constexpr double rad = 1.; //!< Radian, internal unit for angles
+static constexpr double deg = (3.1415926535897932 / 180.0) * rad;
+
+// Magnetic field
+static constexpr double tesla = 1.; //!< Internal unit for magnetic fields
+static constexpr double gauss = 1e-4;
 
+// Converters
+
+#ifndef SWIG
 inline double rad2deg(double angle) {
-    return angle / degree;
+    return angle / deg;
 }
 inline double deg2rad(double angle) {
-    return angle * degree;
+    return angle * deg;
 }
-
-// Symbols for (solid) angle
-static constexpr double rad = radian;
-static constexpr double mrad = milliradian;
-static constexpr double sr = steradian;
-static constexpr double deg = degree;
-
-// Magnetic field
-static constexpr double tesla = 1.;
-static constexpr double gauss = 1e-4;
+#endif // USER_API
 
 } // namespace Units
 
diff --git a/Base/Math/Bessel.h b/Base/Math/Bessel.h
index cdc9c69350942e10ca39338706ca00adf7957c8e..c9e8ee853db374c1183b5dc81e614230c3000e46 100644
--- a/Base/Math/Bessel.h
+++ b/Base/Math/Bessel.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_MATH_BESSEL_H
 #define BORNAGAIN_BASE_MATH_BESSEL_H
 
@@ -52,3 +53,4 @@ complex_t J1c(const complex_t z);
 } // namespace Math
 
 #endif // BORNAGAIN_BASE_MATH_BESSEL_H
+#endif // USER_API
diff --git a/Base/Math/Constants.h b/Base/Math/Constants.h
index a0ea072179330815627b6d786d0bf8654cd8a085..1e6d891c2c726a4c7c4cf69b350398c47a1f7327 100644
--- a/Base/Math/Constants.h
+++ b/Base/Math/Constants.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_MATH_CONSTANTS_H
 #define BORNAGAIN_BASE_MATH_CONSTANTS_H
 
@@ -53,3 +54,4 @@
 #define M_TWOPI 6.28318530717958647693
 
 #endif // BORNAGAIN_BASE_MATH_CONSTANTS_H
+#endif // USER_API
diff --git a/Device/Instrument/FourierTransform.cpp b/Base/Math/FourierTransform.cpp
similarity index 98%
rename from Device/Instrument/FourierTransform.cpp
rename to Base/Math/FourierTransform.cpp
index 3805beacb569048189266f4a8a2d61377bf362e9..da2ee1ec5b7d06cb5cc592953dd49f6cb27a02fd 100644
--- a/Device/Instrument/FourierTransform.cpp
+++ b/Base/Math/FourierTransform.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Device/Instrument/FourierTransform.cpp
+//! @file      Base/Math/FourierTransform.cpp
 //! @brief     Implements class FourierTransform.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -13,7 +13,7 @@
 //
 //  ************************************************************************************************
 
-#include "Device/Instrument/FourierTransform.h"
+#include "Base/Math/FourierTransform.h"
 #include <algorithm>
 #include <cmath>
 #include <iostream>
diff --git a/Device/Instrument/FourierTransform.h b/Base/Math/FourierTransform.h
similarity index 92%
rename from Device/Instrument/FourierTransform.h
rename to Base/Math/FourierTransform.h
index 07e08ee8d252f66cab00207208e99acda1c1c590..cd0208418ea6915b8bdde4c19f43eb582ab1c2cb 100644
--- a/Device/Instrument/FourierTransform.h
+++ b/Base/Math/FourierTransform.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Device/Instrument/FourierTransform.h
+//! @file      Base/Math/FourierTransform.h
 //! @brief     Defines class Math::FourierTransform.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -17,8 +17,9 @@
 #error no need to expose this header to Swig
 #endif
 
-#ifndef BORNAGAIN_DEVICE_INSTRUMENT_FOURIERTRANSFORM_H
-#define BORNAGAIN_DEVICE_INSTRUMENT_FOURIERTRANSFORM_H
+#ifndef USER_API
+#ifndef BORNAGAIN_BASE_MATH_FOURIERTRANSFORM_H
+#define BORNAGAIN_BASE_MATH_FOURIERTRANSFORM_H
 
 #include <fftw3.h>
 #include <vector>
@@ -93,4 +94,5 @@ private:
     Workspace ws;
 };
 
-#endif // BORNAGAIN_DEVICE_INSTRUMENT_FOURIERTRANSFORM_H
+#endif // BORNAGAIN_BASE_MATH_FOURIERTRANSFORM_H
+#endif // USER_API
diff --git a/Base/Math/Functions.h b/Base/Math/Functions.h
index 4455282d90c3309291586b00f931dc0f2838e247..9ec04441a8ab3b4b0b78023c3b9f6f6799237e9e 100644
--- a/Base/Math/Functions.h
+++ b/Base/Math/Functions.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_MATH_FUNCTIONS_H
 #define BORNAGAIN_BASE_MATH_FUNCTIONS_H
 
@@ -64,3 +65,4 @@ double GeneratePoissonRandom(double average);
 } // Namespace Math
 
 #endif // BORNAGAIN_BASE_MATH_FUNCTIONS_H
+#endif // USER_API
diff --git a/Base/Math/IntegratorGK.h b/Base/Math/IntegratorGK.h
index b498482148577ab9e53ae14dbec43af81300c38f..c1e9d2253b95d1f0ccf19d8f5a320199beb94566 100644
--- a/Base/Math/IntegratorGK.h
+++ b/Base/Math/IntegratorGK.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_MATH_INTEGRATORGK_H
 #define BORNAGAIN_BASE_MATH_INTEGRATORGK_H
 
@@ -49,3 +50,4 @@ private:
 };
 
 #endif // BORNAGAIN_BASE_MATH_INTEGRATORGK_H
+#endif // USER_API
diff --git a/Base/Math/IntegratorMCMiser.h b/Base/Math/IntegratorMCMiser.h
index 6ebd742efe8ff86ec0be1836029ca7334bf2000c..c28bbaf956e948853885f468a715b9164a7dc598 100644
--- a/Base/Math/IntegratorMCMiser.h
+++ b/Base/Math/IntegratorMCMiser.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_MATH_INTEGRATORMCMISER_H
 #define BORNAGAIN_BASE_MATH_INTEGRATORMCMISER_H
 
@@ -119,3 +120,4 @@ double IntegratorMCMiser<T>::integrate(double* min_array, double* max_array, voi
 }
 
 #endif // BORNAGAIN_BASE_MATH_INTEGRATORMCMISER_H
+#endif // USER_API
diff --git a/Base/Math/Numeric.h b/Base/Math/Numeric.h
index 252fa097229c3690e926216c6f751375aeba4a62..022736d6099a3a0edbaa28814ec3c8655e2c68b1 100644
--- a/Base/Math/Numeric.h
+++ b/Base/Math/Numeric.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_MATH_NUMERIC_H
 #define BORNAGAIN_BASE_MATH_NUMERIC_H
 
@@ -34,3 +35,4 @@ double GetLogDifference(double a, double b);
 } // namespace Numeric
 
 #endif // BORNAGAIN_BASE_MATH_NUMERIC_H
+#endif // USER_API
diff --git a/Base/Math/Precomputed.h b/Base/Math/Precomputed.h
index 8270134a5ec1502fd0f09f64f8e213911f58ed9f..7207ce7d4140fb739552b9a8e0ae8209f66650e7 100644
--- a/Base/Math/Precomputed.h
+++ b/Base/Math/Precomputed.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_MATH_PRECOMPUTED_H
 #define BORNAGAIN_BASE_MATH_PRECOMPUTED_H
 
@@ -48,3 +49,4 @@ constexpr std::array<double, N> generateReciprocalFactorialArray() {
 } // namespace Math
 
 #endif // BORNAGAIN_BASE_MATH_PRECOMPUTED_H
+#endif // USER_API
diff --git a/Base/Pixel/IPixel.h b/Base/Pixel/IPixel.h
index b5bcb66b90affddc363cea42d3c765959d6cb851..53b1c8c7678a94a25d5df390eec7223fc15f940f 100644
--- a/Base/Pixel/IPixel.h
+++ b/Base/Pixel/IPixel.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_PIXEL_IPIXEL_H
 #define BORNAGAIN_BASE_PIXEL_IPIXEL_H
 
@@ -33,3 +34,4 @@ public:
 };
 
 #endif // BORNAGAIN_BASE_PIXEL_IPIXEL_H
+#endif // USER_API
diff --git a/Base/Pixel/PolarizationHandler.h b/Base/Pixel/PolarizationHandler.h
index 9f4ce9240d33e23b725ee5bac7a638c0949dc03d..de31a5e5640efa408a6c3461efba8eaa753459df 100644
--- a/Base/Pixel/PolarizationHandler.h
+++ b/Base/Pixel/PolarizationHandler.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_PIXEL_POLARIZATIONHANDLER_H
 #define BORNAGAIN_BASE_PIXEL_POLARIZATIONHANDLER_H
 
@@ -49,3 +50,4 @@ private:
 };
 
 #endif // BORNAGAIN_BASE_PIXEL_POLARIZATIONHANDLER_H
+#endif // USER_API
diff --git a/Base/Pixel/SimulationElement.h b/Base/Pixel/SimulationElement.h
index 7b52531e32ebd837514343cf357232f18b2e3f1d..de13b05992e7ee2b733790cd90206d6b930f5fee 100644
--- a/Base/Pixel/SimulationElement.h
+++ b/Base/Pixel/SimulationElement.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_PIXEL_SIMULATIONELEMENT_H
 #define BORNAGAIN_BASE_PIXEL_SIMULATIONELEMENT_H
 
@@ -84,3 +85,4 @@ private:
 };
 
 #endif // BORNAGAIN_BASE_PIXEL_SIMULATIONELEMENT_H
+#endif // USER_API
diff --git a/Base/Progress/DelayedProgressCounter.h b/Base/Progress/DelayedProgressCounter.h
index 9667d009de71e2fc63b598183d16ce3ed4a06dcb..e7b661a2a70341836c8d6a397b0f9b4dbfe46d62 100644
--- a/Base/Progress/DelayedProgressCounter.h
+++ b/Base/Progress/DelayedProgressCounter.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_PROGRESS_DELAYEDPROGRESSCOUNTER_H
 #define BORNAGAIN_BASE_PROGRESS_DELAYEDPROGRESSCOUNTER_H
 
@@ -40,3 +41,4 @@ private:
 };
 
 #endif // BORNAGAIN_BASE_PROGRESS_DELAYEDPROGRESSCOUNTER_H
+#endif // USER_API
diff --git a/Base/Progress/ProgressHandler.h b/Base/Progress/ProgressHandler.h
index 02b2ba6a4d8bd3899b2cfefebab03a6e4b074a03..53e0cfbabe757f286f93e12bf50fff7e91af577d 100644
--- a/Base/Progress/ProgressHandler.h
+++ b/Base/Progress/ProgressHandler.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_PROGRESS_PROGRESSHANDLER_H
 #define BORNAGAIN_BASE_PROGRESS_PROGRESSHANDLER_H
 
@@ -62,3 +63,4 @@ private:
 };
 
 #endif // BORNAGAIN_BASE_PROGRESS_PROGRESSHANDLER_H
+#endif // USER_API
diff --git a/Base/Py/PythonCore.h b/Base/Py/PyCore.h
similarity index 87%
rename from Base/Py/PythonCore.h
rename to Base/Py/PyCore.h
index 380e25400ca5dc78583b0f2f28e35f2b259c73cb..bb73bb34d56fb8a7503188f203f2878ecccd6b04 100644
--- a/Base/Py/PythonCore.h
+++ b/Base/Py/PyCore.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Base/Py/PythonCore.h
+//! @file      Base/Py/PyCore.h
 //! @brief     Includes python header and takes care of warnings.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -16,8 +16,9 @@
 #error no need to expose this header to Swig
 #endif
 
-#ifndef BORNAGAIN_BASE_PY_PYTHONCORE_H
-#define BORNAGAIN_BASE_PY_PYTHONCORE_H
+#ifndef USER_API
+#ifndef BORNAGAIN_BASE_PY_PYCORE_H
+#define BORNAGAIN_BASE_PY_PYCORE_H
 
 #ifdef BORNAGAIN_PYTHON
 
@@ -45,4 +46,5 @@
 
 #endif // BORNAGAIN_PYTHON
 
-#endif // BORNAGAIN_BASE_PY_PYTHONCORE_H
+#endif // BORNAGAIN_BASE_PY_PYCORE_H
+#endif // USER_API
diff --git a/Base/Py/PyObject.h b/Base/Py/PyObject.h
index c22c63aa9c24429c8b86a233db03849f7a86db56..0d78a56d4e08dddef54e9f963de3839953c98676 100644
--- a/Base/Py/PyObject.h
+++ b/Base/Py/PyObject.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_PY_PYOBJECT_H
 #define BORNAGAIN_BASE_PY_PYOBJECT_H
 
@@ -27,3 +28,4 @@ typedef _object PyObject;
 #endif
 
 #endif // BORNAGAIN_BASE_PY_PYOBJECT_H
+#endif // USER_API
diff --git a/Base/Py/PyEmbeddedUtils.cpp b/Base/Py/PyUtils.cpp
similarity index 69%
rename from Base/Py/PyEmbeddedUtils.cpp
rename to Base/Py/PyUtils.cpp
index e2eb8622c478812e542a83da9971edc82b1796bd..964b1fc64a31e0fcdbcdb563baf1fa2788994529 100644
--- a/Base/Py/PyEmbeddedUtils.cpp
+++ b/Base/Py/PyUtils.cpp
@@ -2,8 +2,8 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Base/Py/PyEmbeddedUtils.cpp
-//! @brief     IOmplements various functions from PyEmbeddedUtils namespace
+//! @file      Base/Py/PyUtils.cpp
+//! @brief     IOmplements various functions from PyUtils namespace
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -14,27 +14,22 @@
 
 #ifdef BORNAGAIN_PYTHON
 
-#include "Base/Py/PyEmbeddedUtils.h"
-#include "Base/Py/PythonCore.h"
+#include "Base/Py/PyUtils.h"
+#include "Base/Py/PyCore.h"
 #include "Base/Utils/SysUtils.h"
 #include <iostream>
 #include <sstream>
 #include <stdexcept>
 
-std::string PyEmbeddedUtils::toString(PyObject* obj) {
+std::string PyUtils::toString(PyObject* obj) {
     std::string result;
-#if PY_MAJOR_VERSION >= 3
     PyObject* pyStr = PyUnicode_AsEncodedString(obj, "utf-8", "Error ~");
     result = std::string(PyBytes_AsString(pyStr));
     Py_DecRef(pyStr);
-#else
-    result = std::string(PyString_AsString(obj));
-#endif
-
     return result;
 }
 
-std::vector<std::string> PyEmbeddedUtils::toVectorString(PyObject* obj) {
+std::vector<std::string> PyUtils::toVectorString(PyObject* obj) {
     std::vector<std::string> result;
 
     if (PyTuple_Check(obj)) {
@@ -49,31 +44,27 @@ std::vector<std::string> PyEmbeddedUtils::toVectorString(PyObject* obj) {
             result.push_back(toString(value));
         }
 
-    } else {
-        throw std::runtime_error("PyEmbeddedUtils::toVectorString() -> Error. Unexpected object.");
-    }
+    } else
+        throw std::runtime_error("PyUtils::toVectorString() -> Error. Unexpected object.");
 
     return result;
 }
 
-std::string PyEmbeddedUtils::toString(char* c) {
+std::string PyUtils::toString(char* c) {
     if (c)
         return c;
     else
         return "";
 }
 
-std::string PyEmbeddedUtils::toString(wchar_t* c) {
-    if (c) {
-        std::wstring wstr(c);
-        std::string result(wstr.begin(), wstr.end());
-        return result;
-    } else {
+std::string PyUtils::toString(wchar_t* c) {
+    if (!c)
         return "";
-    }
+    std::wstring wstr(c);
+    return std::string(wstr.begin(), wstr.end());
 }
 
-void PyEmbeddedUtils::import_bornagain(const std::string& path) {
+void PyUtils::import_bornagain(const std::string& path) {
     if (!Py_IsInitialized()) {
         Py_InitializeEx(0);
 
@@ -101,7 +92,7 @@ void PyEmbeddedUtils::import_bornagain(const std::string& path) {
     }
 }
 
-std::string PyEmbeddedUtils::pythonRuntimeInfo() {
+std::string PyUtils::pythonRuntimeInfo() {
     Py_InitializeEx(0);
 
     std::stringstream result;
@@ -113,15 +104,14 @@ std::string PyEmbeddedUtils::pythonRuntimeInfo() {
     result << "PYTHONHOME: " << SysUtils::getenv("PYTHONHOME") << "\n";
 
     // Embedded Python details
-    result << "Py_GetProgramName(): " << PyEmbeddedUtils::toString(Py_GetProgramName()) << "\n";
-    result << "Py_GetProgramFullPath(): " << PyEmbeddedUtils::toString(Py_GetProgramFullPath())
-           << "\n";
-    result << "Py_GetPath(): " << PyEmbeddedUtils::toString(Py_GetPath()) << "\n";
-    result << "Py_GetPythonHome(): " << PyEmbeddedUtils::toString(Py_GetPythonHome()) << "\n";
+    result << "Py_GetProgramName(): " << PyUtils::toString(Py_GetProgramName()) << "\n";
+    result << "Py_GetProgramFullPath(): " << PyUtils::toString(Py_GetProgramFullPath()) << "\n";
+    result << "Py_GetPath(): " << PyUtils::toString(Py_GetPath()) << "\n";
+    result << "Py_GetPythonHome(): " << PyUtils::toString(Py_GetPythonHome()) << "\n";
 
     // Runtime Python's sys.path
     PyObject* sysPath = PySys_GetObject((char*)"path");
-    auto content = PyEmbeddedUtils::toVectorString(sysPath);
+    auto content = PyUtils::toVectorString(sysPath);
     result << "sys.path: ";
     for (auto s : content)
         result << s << ",";
@@ -133,7 +123,7 @@ std::string PyEmbeddedUtils::pythonRuntimeInfo() {
 // Attempt to retrieve Python stack trace
 // https://stackoverflow.com/questions/1796510/accessing-a-python-traceback-from-the-c-api
 
-std::string PyEmbeddedUtils::pythonStackTrace() {
+std::string PyUtils::pythonStackTrace() {
     std::stringstream result;
 
     if (PyErr_Occurred()) {
@@ -172,4 +162,25 @@ std::string PyEmbeddedUtils::pythonStackTrace() {
     return result.str();
 }
 
+PyObject* PyUtils::createNumpyArray(const std::vector<double>& data) {
+    const size_t ndim(1);
+    npy_int ndim_numpy = ndim;
+    npy_intp* ndimsizes_numpy = new npy_intp[ndim];
+    ndimsizes_numpy[0] = data.size();
+
+    // creating standalone numpy array
+    PyObject* pyarray = PyArray_SimpleNew(ndim_numpy, ndimsizes_numpy, NPY_DOUBLE);
+    delete[] ndimsizes_numpy;
+    if (pyarray == nullptr)
+        throw std::runtime_error("ExportOutputData() -> Panic in PyArray_SimpleNew");
+
+    // getting pointer to data buffer of numpy array
+    double* array_buffer = (double*)PyArray_DATA((PyArrayObject*)pyarray);
+
+    for (size_t index = 0; index < data.size(); ++index)
+        *array_buffer++ = data[index];
+
+    return pyarray;
+}
+
 #endif // BORNAGAIN_PYTHON
diff --git a/Base/Py/PyEmbeddedUtils.h b/Base/Py/PyUtils.h
similarity index 88%
rename from Base/Py/PyEmbeddedUtils.h
rename to Base/Py/PyUtils.h
index c24cbb109c189e354ccdb36ea37b6824d8da1ada..6096734589f5b4d2f783e3f06ff08bf356e6a9e9 100644
--- a/Base/Py/PyEmbeddedUtils.h
+++ b/Base/Py/PyUtils.h
@@ -2,8 +2,8 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Base/Py/PyEmbeddedUtils.h
-//! @brief     Defines PyEmbeddedUtils namespace
+//! @file      Base/Py/PyUtils.h
+//! @brief     Defines PyUtils namespace
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_PY_PYEMBEDDEDUTILS_H
 #define BORNAGAIN_BASE_PY_PYEMBEDDEDUTILS_H
 
@@ -28,7 +29,7 @@
 
 class MultiLayer;
 
-namespace PyEmbeddedUtils {
+namespace PyUtils {
 
 //! Converts PyObject into string, if possible, or throws exception.
 std::string toString(PyObject* obj);
@@ -48,8 +49,12 @@ std::string pythonRuntimeInfo();
 
 //! Returns string representing python stack trace.
 std::string pythonStackTrace();
-} // namespace PyEmbeddedUtils
+
+PyObject* createNumpyArray(const std::vector<double>& data);
+
+} // namespace PyUtils
 
 #endif // BORNAGAIN_PYTHON
 
 #endif // BORNAGAIN_BASE_PY_PYEMBEDDEDUTILS_H
+#endif // USER_API
diff --git a/Base/Types/CloneableVector.h b/Base/Types/CloneableVector.h
index 5ed210b48d826f69382a9d55bbc3c9f1e928981d..cf207935bf285b6512a902c5eac97a25d938c221 100644
--- a/Base/Types/CloneableVector.h
+++ b/Base/Types/CloneableVector.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_TYPES_CLONEABLEVECTOR_H
 #define BORNAGAIN_BASE_TYPES_CLONEABLEVECTOR_H
 
@@ -46,3 +47,4 @@ public:
 };
 
 #endif // BORNAGAIN_BASE_TYPES_CLONEABLEVECTOR_H
+#endif // USER_API
diff --git a/Base/Types/ICloneable.h b/Base/Types/ICloneable.h
index 825a117feb02e30331d98d71412c515fa57087a1..e11a528ca1325a69ef36ae651d5818c8881ed284 100644
--- a/Base/Types/ICloneable.h
+++ b/Base/Types/ICloneable.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_TYPES_ICLONEABLE_H
 #define BORNAGAIN_BASE_TYPES_ICLONEABLE_H
 
@@ -34,3 +35,4 @@ public:
 };
 
 #endif // BORNAGAIN_BASE_TYPES_ICLONEABLE_H
+#endif // USER_API
diff --git a/Base/Types/SafePointerVector.h b/Base/Types/SafePointerVector.h
index 257ccc8987e0143bfa56356e718533865f95156b..2306a3cad1fd51dec6541c2eca9ed12544a489d5 100644
--- a/Base/Types/SafePointerVector.h
+++ b/Base/Types/SafePointerVector.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_TYPES_SAFEPOINTERVECTOR_H
 #define BORNAGAIN_BASE_TYPES_SAFEPOINTERVECTOR_H
 
@@ -90,3 +91,4 @@ template <class T> void SafePointerVector<T>::clear() {
 }
 
 #endif // BORNAGAIN_BASE_TYPES_SAFEPOINTERVECTOR_H
+#endif // USER_API
diff --git a/Base/Utils/Algorithms.h b/Base/Utils/Algorithms.h
index f5e6a6d181826d78732a6fcaa7f7d67e1f77cfac..014b21dce309366bbf145b1bc816817fb2bfbcc5 100644
--- a/Base/Utils/Algorithms.h
+++ b/Base/Utils/Algorithms.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_UTILS_ALGORITHMS_H
 #define BORNAGAIN_BASE_UTILS_ALGORITHMS_H
 
@@ -79,3 +80,4 @@ template <class T> std::vector<T> algo::concat(const std::vector<T>& v1, const s
 }
 
 #endif // BORNAGAIN_BASE_UTILS_ALGORITHMS_H
+#endif // USER_API
diff --git a/Base/Utils/Assert.h b/Base/Utils/Assert.h
index a4f3bcd3e691c644ffe74d2dfe95124b4eafd217..bc8ab08ef958befc167c12f5ea6ba18731df6d64 100644
--- a/Base/Utils/Assert.h
+++ b/Base/Utils/Assert.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_UTILS_ASSERT_H
 #define BORNAGAIN_BASE_UTILS_ASSERT_H
 
@@ -35,3 +36,4 @@
     }
 
 #endif // BORNAGAIN_BASE_UTILS_ASSERT_H
+#endif // USER_API
diff --git a/Base/Utils/FileSystemUtils.h b/Base/Utils/FileSystemUtils.h
index 86dc937ae8a76f5b2b145f97eb39788aeb8fb14f..1d3f0f2f72b0d0cc709fdc3503be686ed2592987 100644
--- a/Base/Utils/FileSystemUtils.h
+++ b/Base/Utils/FileSystemUtils.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_UTILS_FILESYSTEMUTILS_H
 #define BORNAGAIN_BASE_UTILS_FILESYSTEMUTILS_H
 
@@ -69,3 +70,4 @@ bool IsFileExists(const std::string& path);
 } // namespace FileSystemUtils
 
 #endif // BORNAGAIN_BASE_UTILS_FILESYSTEMUTILS_H
+#endif // USER_API
diff --git a/Base/Utils/IFactory.h b/Base/Utils/IFactory.h
index c33f0572fb38c8bc249f4826a0462f8dfef862b0..d10c93076ca2243e95b6a051f5f0b6de228a63e4 100644
--- a/Base/Utils/IFactory.h
+++ b/Base/Utils/IFactory.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Fit/TestEngine/IFactory.h
+//! @file      Base/Utils/IFactory.h
 //! @brief     Defines interface class IFactory.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_UTILS_IFACTORY_H
 #define BORNAGAIN_BASE_UTILS_IFACTORY_H
 
@@ -74,3 +75,4 @@ template <class T> T* create_new() {
 }
 
 #endif // BORNAGAIN_BASE_UTILS_IFACTORY_H
+#endif // USER_API
diff --git a/Base/Utils/StringUtils.cpp b/Base/Utils/StringUtils.cpp
index a583674eb03565d3f9af242a391e5c851452b68a..e8bcc739142ba5d5efa688772e8b50d8d5f1d64e 100644
--- a/Base/Utils/StringUtils.cpp
+++ b/Base/Utils/StringUtils.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Fit/Tools/StringUtils.cpp
+//! @file      Base/Utils/StringUtils.cpp
 //! @brief     Implements a few helper functions
 //!
 //! @homepage  http://www.bornagainproject.org
diff --git a/Base/Utils/StringUtils.h b/Base/Utils/StringUtils.h
index 73c26cd0bbf5a96c10b34392c9f71c981b0640a0..a6775b376605562fd4e566c0e42b8f3e39953203 100644
--- a/Base/Utils/StringUtils.h
+++ b/Base/Utils/StringUtils.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Fit/Tools/StringUtils.h
+//! @file      Base/Utils/StringUtils.h
 //! @brief     Defines a few helper functions
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_UTILS_STRINGUTILS_H
 #define BORNAGAIN_BASE_UTILS_STRINGUTILS_H
 
@@ -64,3 +65,4 @@ template <typename T> std::string StringUtils::scientific(const T value, int n)
 }
 
 #endif // BORNAGAIN_BASE_UTILS_STRINGUTILS_H
+#endif // USER_API
diff --git a/Base/Utils/SysUtils.h b/Base/Utils/SysUtils.h
index 536ff1333ddd40bd07c7f1e9742e992d682f07c8..23449da5ffa18ac8756bb544e53e1bdf5096370b 100644
--- a/Base/Utils/SysUtils.h
+++ b/Base/Utils/SysUtils.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_UTILS_SYSUTILS_H
 #define BORNAGAIN_BASE_UTILS_SYSUTILS_H
 
@@ -39,3 +40,4 @@ bool isWindowsHost();
 } // namespace SysUtils
 
 #endif // BORNAGAIN_BASE_UTILS_SYSUTILS_H
+#endif // USER_API
diff --git a/Base/Vector/BasicVector3D.h b/Base/Vector/BasicVector3D.h
index 6893c3f053ed4c4953551de2aec33f05ba180ec2..94fabbd7bfe7220a55215d3cecb7474160bb0247 100644
--- a/Base/Vector/BasicVector3D.h
+++ b/Base/Vector/BasicVector3D.h
@@ -9,17 +9,17 @@
 //! @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)
+//!
+//! Forked from CLHEP/Geometry by E. Chernyaev <Evgueni.Tcherniaev@cern.ch>,
+//! then reworked beyond recognition. Removed split of point and vector semantics.
+//! Transforms are relegated to a separate class Transform3D.
 //
 //  ************************************************************************************************
 
 #ifndef BORNAGAIN_BASE_VECTOR_BASICVECTOR3D_H
 #define BORNAGAIN_BASE_VECTOR_BASICVECTOR3D_H
 
-//! Forked from CLHEP/Geometry by E. Chernyaev <Evgueni.Tcherniaev@cern.ch>,
-//! then reworked beyond recognition. Removed split of point and vector semantics.
-//! Transforms are relegated to a separate class Transform3D.
-
-#include <complex>
+#include "Base/Types/Complex.h"
 
 //! Three-dimensional vector template, for use with integer, double, or complex components.
 //! @ingroup tools_internal
@@ -99,7 +99,7 @@ public:
         v_[2] *= a;
         return *this;
     }
-#endif // SWIG
+#endif // USER_API
 
     //! Divides this by a scalar, and returns result.
 #ifndef SWIG
@@ -109,7 +109,7 @@ public:
         v_[2] /= a;
         return *this;
     }
-#endif // SWIG
+#endif // USER_API
 
     // -------------------------------------------------------------------------
     // Functions of this (with no further argument)
@@ -146,7 +146,7 @@ public:
     BasicVector3D<T> unit() const;
 
     //! Returns this, trivially converted to complex type.
-    BasicVector3D<std::complex<double>> complex() const;
+    BasicVector3D<complex_t> complex() const;
 
     //! Returns real parts.
     BasicVector3D<double> real() const;
@@ -158,12 +158,12 @@ public:
     //! Returns dot product of vectors (antilinear in the first [=self] argument).
 #ifndef SWIG
     template <class U> auto dot(const BasicVector3D<U>& v) const;
-#endif // SWIG
+#endif // USER_API
 
     //! Returns cross product of vectors (linear in both arguments).
 #ifndef SWIG
     template <class U> auto cross(const BasicVector3D<U>& v) const;
-#endif // SWIG
+#endif // USER_API
 
     //! Returns angle with respect to another vector.
     double angle(const BasicVector3D<T>& v) const;
@@ -239,7 +239,7 @@ inline BasicVector3D<T> operator-(const BasicVector3D<T>& a, const BasicVector3D
 template <class T, class U> inline auto operator*(const BasicVector3D<T>& v, const U a) {
     return BasicVector3D<decltype(v.x() * a)>(v.x() * a, v.y() * a, v.z() * a);
 }
-#endif // SWIG
+#endif // USER_API
 
 //! Multiplication scalar by vector.
 //! @relates BasicVector3D
@@ -247,7 +247,7 @@ template <class T, class U> inline auto operator*(const BasicVector3D<T>& v, con
 template <class T, class U> inline auto operator*(const U a, const BasicVector3D<T>& v) {
     return BasicVector3D<decltype(a * v.x())>(a * v.x(), a * v.y(), a * v.z());
 }
-#endif // SWIG
+#endif // USER_API
 
 // vector*vector not supported
 //    (We do not provide the operator form a*b of the dot product:
@@ -284,7 +284,7 @@ inline auto BasicVector3D<T>::dot(const BasicVector3D<U>& v) const {
     BasicVector3D<T> left_star = this->conj();
     return left_star.x() * v.x() + left_star.y() * v.y() + left_star.z() * v.z();
 }
-#endif // SWIG
+#endif // USER_API
 
 //! Returns cross product of (complex) vectors.
 #ifndef SWIG
@@ -294,11 +294,11 @@ inline auto BasicVector3D<T>::cross(const BasicVector3D<U>& v) const {
     return BasicVector3D<decltype(this->x() * v.x())>(
         y() * v.z() - v.y() * z(), z() * v.x() - v.z() * x(), x() * v.y() - v.x() * y());
 }
-#endif // SWIG
+#endif // USER_API
 
 template <> BasicVector3D<double> BasicVector3D<double>::conj() const;
 
-template <> BasicVector3D<std::complex<double>> BasicVector3D<std::complex<double>>::conj() const;
+template <> BasicVector3D<complex_t> BasicVector3D<complex_t>::conj() const;
 
 template <> double BasicVector3D<double>::phi() const;
 
@@ -308,15 +308,15 @@ template <> double BasicVector3D<double>::cosTheta() const;
 
 template <> double BasicVector3D<double>::sin2Theta() const;
 
-template <> BasicVector3D<std::complex<double>> BasicVector3D<double>::complex() const;
+template <> BasicVector3D<complex_t> BasicVector3D<double>::complex() const;
 
 template <> BasicVector3D<double> BasicVector3D<double>::real() const;
 
-template <> BasicVector3D<double> BasicVector3D<std::complex<double>>::real() const;
+template <> BasicVector3D<double> BasicVector3D<complex_t>::real() const;
 
 template <> BasicVector3D<double> BasicVector3D<double>::unit() const;
 
-template <> BasicVector3D<std::complex<double>> BasicVector3D<std::complex<double>>::unit() const;
+template <> BasicVector3D<complex_t> BasicVector3D<complex_t>::unit() const;
 
 template <> double BasicVector3D<double>::angle(const BasicVector3D<double>& v) const;
 
diff --git a/Base/Vector/Direction.h b/Base/Vector/Direction.h
index 5aa0b4e6aa1bcf74e57015fe0634bf1f1a02db62..47b704539b1d1141b7ea2e93b3149f9573741272 100644
--- a/Base/Vector/Direction.h
+++ b/Base/Vector/Direction.h
@@ -19,6 +19,8 @@
 
 kvector_t vecOfLambdaAlphaPhi(double _lambda, double _alpha, double _phi);
 
+//! A direction in three-dimensional space.
+
 class Direction {
 public:
     Direction(double alpha, double phi) : m_alpha(alpha), m_phi(phi) {}
diff --git a/Base/Vector/EigenCore.h b/Base/Vector/EigenCore.h
index 12c07911a573254cf3b012cae3b94fd5246bb9a8..68ca88e4efb3363770d696d414a4b8f966527240 100644
--- a/Base/Vector/EigenCore.h
+++ b/Base/Vector/EigenCore.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_VECTOR_EIGENCORE_H
 #define BORNAGAIN_BASE_VECTOR_EIGENCORE_H
 
@@ -34,3 +35,4 @@
 #endif
 
 #endif // BORNAGAIN_BASE_VECTOR_EIGENCORE_H
+#endif // USER_API
diff --git a/Base/Vector/Transform3D.h b/Base/Vector/Transform3D.h
index 5e4cdac7ecd94bcc12066811c3edd62305065095..66ee79934603b48b5027c7dfecb3fba0a5ec3e66 100644
--- a/Base/Vector/Transform3D.h
+++ b/Base/Vector/Transform3D.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_BASE_VECTOR_TRANSFORM3D_H
 #define BORNAGAIN_BASE_VECTOR_TRANSFORM3D_H
 
@@ -113,3 +114,4 @@ private:
 };
 
 #endif // BORNAGAIN_BASE_VECTOR_TRANSFORM3D_H
+#endif // USER_API
diff --git a/Base/Vector/Vectors3D.h b/Base/Vector/Vectors3D.h
index f599ef439a3998892f25f449ad1a895cc9e86b11..692fb0475a6df2154b57f6e18216371e0ae554f3 100644
--- a/Base/Vector/Vectors3D.h
+++ b/Base/Vector/Vectors3D.h
@@ -19,6 +19,6 @@
 
 using ivector_t = BasicVector3D<int>;
 using kvector_t = BasicVector3D<double>;
-using cvector_t = BasicVector3D<std::complex<double>>;
+using cvector_t = BasicVector3D<complex_t>;
 
 #endif // BORNAGAIN_BASE_VECTOR_VECTORS3D_H
diff --git a/CHANGELOG b/CHANGELOG
index fa35811f78963848abfb40e1e60d0c43a1160502..049d162bd1ab3ca3b77c77121752cc62199dd57e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -4,14 +4,16 @@ BornAgain-1.18.99, ongoing development
     * Removed "get" from several accessor functions
     * Class Instrument removed  from Python API (instead use simulation.beam() etc)
     * Lattice has been renamed to Lattice3D, for clearer disambuation from Lattice2D
+    * "OffSpecular" instead of "OffSpec"
     * Removed some interference functions constructors
     * Remove old R&T computations from API (now in Code/Legacy and Tests)
     * Python plot API entirely keyword based
   > Fixes of unreported bugs:
     * Several GUI bugs that caused crashes
     * For alpha_i=0, set scattered intensity to 0
-  > Examples:
-    * Uniform API usage in line with exported Python code
+  > Documentation:
+    * Unified API usage in many examples, using BornAgain's Python exporter
+    * Removed many entries from Doxygen user API
   > Internal refactoring:
     * Moved code to break directory include cycles
     * Renamed a few classes (ISimulation)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cceaf3cc385497a0ce53b79aba5cac6b2b29e745..7903e34465e01ae0f9d21cd9b2479bf0d436f7bc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -72,9 +72,10 @@ endif()
 ## Various CMake settings (include order is of critical importance)
 
 # function definitions
-include(commons/GetFilenameComponent) # overwrite CMake command
-include(BornAgain/MakeLib)
-include(BornAgain/SwigLib)
+include(commons/GetFilenameComponent) # fct get_filename_component (overwrites CMake's built-in)
+include(BornAgain/PythonDocs) # fct GeneratePythonDocs
+include(BornAgain/SwigLib) # fct SwigLib
+include(BornAgain/MakeLib) # fct MakeLib
 
 # main settings
 
@@ -104,7 +105,6 @@ include(BornAgain/Config)
 if(BORNAGAIN_PYTHON)
     include(BornAgain/PythonAPI)
 endif()
-include(BornAgain/PythonDocs)
 
 # debug optimization
 if(BORNAGAIN_DEBUG_OPTIMIZATION)
diff --git a/Core/Computation/ComputationStatus.h b/Core/Computation/ComputationStatus.h
index b8722c5ec697d1ec0547f00787be6089ba3a8cd6..dc772ae0a780d9a7d7da395b9a8130f5a3590516 100644
--- a/Core/Computation/ComputationStatus.h
+++ b/Core/Computation/ComputationStatus.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_COMPUTATION_COMPUTATIONSTATUS_H
 #define BORNAGAIN_CORE_COMPUTATION_COMPUTATIONSTATUS_H
 
@@ -46,3 +47,4 @@ private:
 };
 
 #endif // BORNAGAIN_CORE_COMPUTATION_COMPUTATIONSTATUS_H
+#endif // USER_API
diff --git a/Core/Computation/DWBAComputation.h b/Core/Computation/DWBAComputation.h
index d4219a5b5f1aacf4a862688c24ef02100d69d44d..f6d10cea7212c0cfeeab57e414328db67c2bdecc 100644
--- a/Core/Computation/DWBAComputation.h
+++ b/Core/Computation/DWBAComputation.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_COMPUTATION_DWBACOMPUTATION_H
 #define BORNAGAIN_CORE_COMPUTATION_DWBACOMPUTATION_H
 
@@ -48,3 +49,4 @@ private:
 };
 
 #endif // BORNAGAIN_CORE_COMPUTATION_DWBACOMPUTATION_H
+#endif // USER_API
diff --git a/Core/Computation/DWBASingleComputation.h b/Core/Computation/DWBASingleComputation.h
index 9afed99c0b0c8f7c2480142357fae91aa4a2f7d0..c686c2263c84bd5842206aae47bb019087b63029 100644
--- a/Core/Computation/DWBASingleComputation.h
+++ b/Core/Computation/DWBASingleComputation.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_COMPUTATION_DWBASINGLECOMPUTATION_H
 #define BORNAGAIN_CORE_COMPUTATION_DWBASINGLECOMPUTATION_H
 
@@ -59,3 +60,4 @@ private:
 };
 
 #endif // BORNAGAIN_CORE_COMPUTATION_DWBASINGLECOMPUTATION_H
+#endif // USER_API
diff --git a/Core/Computation/DepthProbeComputation.h b/Core/Computation/DepthProbeComputation.h
index f1b7a0d9bd6956c167107435faf7a0685cdfca74..f1f9c96326d0ebeee820c41204b93b44f18bb040 100644
--- a/Core/Computation/DepthProbeComputation.h
+++ b/Core/Computation/DepthProbeComputation.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_COMPUTATION_DEPTHPROBECOMPUTATION_H
 #define BORNAGAIN_CORE_COMPUTATION_DEPTHPROBECOMPUTATION_H
 
@@ -47,3 +48,4 @@ private:
 };
 
 #endif // BORNAGAIN_CORE_COMPUTATION_DEPTHPROBECOMPUTATION_H
+#endif // USER_API
diff --git a/Core/Computation/GISASSpecularComputation.h b/Core/Computation/GISASSpecularComputation.h
index 6ad78fcc13af44a9dc2a5f35d0623c330d01d441..0302aa78bd788db1342db1d08b63191037b30ea1 100644
--- a/Core/Computation/GISASSpecularComputation.h
+++ b/Core/Computation/GISASSpecularComputation.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_COMPUTATION_GISASSPECULARCOMPUTATION_H
 #define BORNAGAIN_CORE_COMPUTATION_GISASSPECULARCOMPUTATION_H
 
@@ -36,3 +37,4 @@ private:
 };
 
 #endif // BORNAGAIN_CORE_COMPUTATION_GISASSPECULARCOMPUTATION_H
+#endif // USER_API
diff --git a/Core/Computation/IBackground.h b/Core/Computation/IBackground.h
index 1a932bfd16dea9da6a328602e458399dfda8ba49..73e2f88ea6fa8731cbc3da26be9f719ac9de04e0 100644
--- a/Core/Computation/IBackground.h
+++ b/Core/Computation/IBackground.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_COMPUTATION_IBACKGROUND_H
 #define BORNAGAIN_CORE_COMPUTATION_IBACKGROUND_H
 
@@ -32,3 +33,4 @@ public:
 };
 
 #endif // BORNAGAIN_CORE_COMPUTATION_IBACKGROUND_H
+#endif // USER_API
diff --git a/Core/Computation/IComputation.h b/Core/Computation/IComputation.h
index 64e500e348359a9b45721a30f7d638dd013834e3..6b7e9e83246f662ea08d2c0982b654f9bc1fa188 100644
--- a/Core/Computation/IComputation.h
+++ b/Core/Computation/IComputation.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_COMPUTATION_ICOMPUTATION_H
 #define BORNAGAIN_CORE_COMPUTATION_ICOMPUTATION_H
 
@@ -57,3 +58,4 @@ private:
 };
 
 #endif // BORNAGAIN_CORE_COMPUTATION_ICOMPUTATION_H
+#endif // USER_API
diff --git a/Core/Computation/ParticleLayoutComputation.h b/Core/Computation/ParticleLayoutComputation.h
index ece5291210950a55e3f567b99d8320c3cfe52aa2..ce37377cb62ec84162c48a2411229bb664b4794d 100644
--- a/Core/Computation/ParticleLayoutComputation.h
+++ b/Core/Computation/ParticleLayoutComputation.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_COMPUTATION_PARTICLELAYOUTCOMPUTATION_H
 #define BORNAGAIN_CORE_COMPUTATION_PARTICLELAYOUTCOMPUTATION_H
 
@@ -51,3 +52,4 @@ private:
 };
 
 #endif // BORNAGAIN_CORE_COMPUTATION_PARTICLELAYOUTCOMPUTATION_H
+#endif // USER_API
diff --git a/Core/Computation/RoughMultiLayerComputation.h b/Core/Computation/RoughMultiLayerComputation.h
index 0cf04d5d59896f1aa7529397814374e0c83026b0..453694b283a4eab76f79885656d6361c9bcc485e 100644
--- a/Core/Computation/RoughMultiLayerComputation.h
+++ b/Core/Computation/RoughMultiLayerComputation.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_COMPUTATION_ROUGHMULTILAYERCOMPUTATION_H
 #define BORNAGAIN_CORE_COMPUTATION_ROUGHMULTILAYERCOMPUTATION_H
 
@@ -41,3 +42,4 @@ private:
 };
 
 #endif // BORNAGAIN_CORE_COMPUTATION_ROUGHMULTILAYERCOMPUTATION_H
+#endif // USER_API
diff --git a/Core/Computation/SpecularComputation.h b/Core/Computation/SpecularComputation.h
index b28e414ed935e9fd0de8a9f1ee42449d9dbdfcf9..298914c8ecc4bbf07f7340983c900513c2fbbee6 100644
--- a/Core/Computation/SpecularComputation.h
+++ b/Core/Computation/SpecularComputation.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_COMPUTATION_SPECULARCOMPUTATION_H
 #define BORNAGAIN_CORE_COMPUTATION_SPECULARCOMPUTATION_H
 
@@ -49,3 +50,4 @@ private:
 };
 
 #endif // BORNAGAIN_CORE_COMPUTATION_SPECULARCOMPUTATION_H
+#endif // USER_API
diff --git a/Core/Element/DepthProbeElement.h b/Core/Element/DepthProbeElement.h
index 04b23e9ad588973ca214c8188305df47f886d5dd..73c0d1c4cd51a5f0924dd7ce3149c2fb9ccc3976 100644
--- a/Core/Element/DepthProbeElement.h
+++ b/Core/Element/DepthProbeElement.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_ELEMENT_DEPTHPROBEELEMENT_H
 #define BORNAGAIN_CORE_ELEMENT_DEPTHPROBEELEMENT_H
 
@@ -67,3 +68,4 @@ private:
 };
 
 #endif // BORNAGAIN_CORE_ELEMENT_DEPTHPROBEELEMENT_H
+#endif // USER_API
diff --git a/Core/Element/SpecularSimulationElement.h b/Core/Element/SpecularSimulationElement.h
index f2172237d011f600035b6d349b397368d6ddb661..07877f48efb721c20d0c8ce1e5cad2b2f1134f33 100644
--- a/Core/Element/SpecularSimulationElement.h
+++ b/Core/Element/SpecularSimulationElement.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_ELEMENT_SPECULARSIMULATIONELEMENT_H
 #define BORNAGAIN_CORE_ELEMENT_SPECULARSIMULATIONELEMENT_H
 
@@ -64,3 +65,4 @@ private:
 };
 
 #endif // BORNAGAIN_CORE_ELEMENT_SPECULARSIMULATIONELEMENT_H
+#endif // USER_API
diff --git a/Core/Export/ComponentKeyHandler.h b/Core/Export/ComponentKeyHandler.h
index d13f5b186a12040e642cd9a0798a4bef94101485..e4d39ae0b05913fa18ab56f5d241f5e95bc764e3 100644
--- a/Core/Export/ComponentKeyHandler.h
+++ b/Core/Export/ComponentKeyHandler.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_EXPORT_COMPONENTKEYHANDLER_H
 #define BORNAGAIN_CORE_EXPORT_COMPONENTKEYHANDLER_H
 
@@ -49,3 +50,4 @@ template <class T> std::vector<const T*> ComponentKeyHandler::objectsOfType() co
 }
 
 #endif // BORNAGAIN_CORE_EXPORT_COMPONENTKEYHANDLER_H
+#endif // USER_API
diff --git a/Core/Export/MaterialKeyHandler.h b/Core/Export/MaterialKeyHandler.h
index c0356ca249175044f53c7659a3845b9849b55389..7ca324a2f53c7f1a3397c18ca063200c9c083b00 100644
--- a/Core/Export/MaterialKeyHandler.h
+++ b/Core/Export/MaterialKeyHandler.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_EXPORT_MATERIALKEYHANDLER_H
 #define BORNAGAIN_CORE_EXPORT_MATERIALKEYHANDLER_H
 
@@ -41,3 +42,4 @@ private:
 };
 
 #endif // BORNAGAIN_CORE_EXPORT_MATERIALKEYHANDLER_H
+#endif // USER_API
diff --git a/Core/Export/NodeProgeny.h b/Core/Export/NodeProgeny.h
index 74ea17191494aee96060e7a8e9200014bdd040ac..e6ea027979ccc7353e0f022032160fc0fab85507 100644
--- a/Core/Export/NodeProgeny.h
+++ b/Core/Export/NodeProgeny.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_EXPORT_NODEPROGENY_H
 #define BORNAGAIN_CORE_EXPORT_NODEPROGENY_H
 
@@ -53,3 +54,4 @@ template <typename T> std::vector<const T*> AllDescendantsOfType(const INode& no
 } // namespace node_progeny
 
 #endif // BORNAGAIN_CORE_EXPORT_NODEPROGENY_H
+#endif // USER_API
diff --git a/Core/Export/PyFmt.cpp b/Core/Export/PyFmt.cpp
index fb24b391dbb2acdf4233e59bcf5b9582bf8f3e27..c19b4e5f7b73acbfe9058b5ced20d978950173f8 100644
--- a/Core/Export/PyFmt.cpp
+++ b/Core/Export/PyFmt.cpp
@@ -22,8 +22,8 @@ namespace pyfmt {
 
 std::string scriptPreamble() {
     return "import numpy, sys\n"
-        "import bornagain as ba\n"
-        "from bornagain import angstrom, deg, micrometer, nm, nm2, kvector_t\n\n\n";
+           "import bornagain as ba\n"
+           "from bornagain import angstrom, deg, micrometer, nm, nm2, kvector_t\n\n\n";
 }
 
 std::string printBool(double value) {
diff --git a/Core/Export/PyFmt.h b/Core/Export/PyFmt.h
index bc199db5f8af7f501aadf60335af9454e152ddc9..5bcd068d5a1293c7ac55a761cf2b964bd572724a 100644
--- a/Core/Export/PyFmt.h
+++ b/Core/Export/PyFmt.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_EXPORT_PYFMT_H
 #define BORNAGAIN_CORE_EXPORT_PYFMT_H
 
@@ -51,3 +52,4 @@ std::string indent(size_t width = 4u);
 } // namespace pyfmt
 
 #endif // BORNAGAIN_CORE_EXPORT_PYFMT_H
+#endif // USER_API
diff --git a/Core/Export/PyFmt2.h b/Core/Export/PyFmt2.h
index 9770bef40afafcb41d08bb62d2fd7f3657aab39e..e91045b89235b71f5838bff2a0b37e00072d2f22 100644
--- a/Core/Export/PyFmt2.h
+++ b/Core/Export/PyFmt2.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_EXPORT_PYFMT2_H
 #define BORNAGAIN_CORE_EXPORT_PYFMT2_H
 
@@ -53,3 +54,4 @@ std::string printRangedDistribution(const IRangedDistribution& distr);
 } // namespace pyfmt2
 
 #endif // BORNAGAIN_CORE_EXPORT_PYFMT2_H
+#endif // USER_API
diff --git a/Core/Export/PyFmtLimits.h b/Core/Export/PyFmtLimits.h
index 9bb5dfd9d0f7cbe8166508e9fbda0d85ca06bce8..2684435c88e016d7774c3a7cb35ab5a9867a7059 100644
--- a/Core/Export/PyFmtLimits.h
+++ b/Core/Export/PyFmtLimits.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_EXPORT_PYFMTLIMITS_H
 #define BORNAGAIN_CORE_EXPORT_PYFMTLIMITS_H
 
@@ -31,3 +32,4 @@ std::string printRealLimitsArg(const RealLimits& limits, const std::string& unit
 } // namespace pyfmt
 
 #endif // BORNAGAIN_CORE_EXPORT_PYFMTLIMITS_H
+#endif // USER_API
diff --git a/Core/Export/SampleToPython.h b/Core/Export/SampleToPython.h
index 18074fdb2185a50d0a2da436c2f8bfff6ef17a53..b195d0bb025277514d83ac649081e416e91c69c3 100644
--- a/Core/Export/SampleToPython.h
+++ b/Core/Export/SampleToPython.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_EXPORT_SAMPLETOPYTHON_H
 #define BORNAGAIN_CORE_EXPORT_SAMPLETOPYTHON_H
 
@@ -61,3 +62,4 @@ private:
 };
 
 #endif // BORNAGAIN_CORE_EXPORT_SAMPLETOPYTHON_H
+#endif // USER_API
diff --git a/Core/Export/SimulationToPython.cpp b/Core/Export/SimulationToPython.cpp
index 178fb875ed9c8484d86b323e1af3a6f513f06c94..710d3a25ad4fd3def2ef09beb08d28b4a652e9c4 100644
--- a/Core/Export/SimulationToPython.cpp
+++ b/Core/Export/SimulationToPython.cpp
@@ -24,7 +24,7 @@
 #include "Core/Scan/AngularSpecScan.h"
 #include "Core/Scan/QSpecScan.h"
 #include "Core/Simulation/GISASSimulation.h"
-#include "Core/Simulation/OffSpecSimulation.h"
+#include "Core/Simulation/OffSpecularSimulation.h"
 #include "Core/Simulation/SpecularSimulation.h"
 #include "Device/Beam/FootprintGauss.h"
 #include "Device/Beam/FootprintSquare.h"
@@ -128,7 +128,7 @@ std::string defineDetector(const ISimulation* simulation) {
     result << std::setprecision(12);
 
     if (const auto* const det = dynamic_cast<const SphericalDetector*>(detector)) {
-        ASSERT(det->dimension()==2);
+        ASSERT(det->dimension() == 2);
         if (DetectorUtils::isQuadratic(*det)) {
             result << indent() << "nbin = " << det->axis(0).size() << "\n";
             result << indent() << "detector = ba.SphericalDetector(nbin, "
@@ -141,8 +141,7 @@ std::string defineDetector(const ISimulation* simulation) {
             result << indent() << "detector = ba.SphericalDetector(nx, "
                    << pyfmt::printDegrees(det->axis(0).lowerBound()) << ", "
                    << pyfmt::printDegrees(det->axis(0).upperBound()) << ", "
-                   << "ny , "
-                   << pyfmt::printDegrees(det->axis(1).lowerBound()) << ", "
+                   << "ny , " << pyfmt::printDegrees(det->axis(1).lowerBound()) << ", "
                    << pyfmt::printDegrees(det->axis(1).upperBound());
         }
         result << ")\n";
@@ -258,7 +257,7 @@ std::string defineBeamIntensity(const Beam& beam) {
     std::ostringstream result;
     double beam_intensity = beam.intensity();
     if (beam_intensity > 0.0)
-        result << indent() << "simulation.setBeamIntensity("
+        result << indent() << "simulation.beam().setIntensity("
                << pyfmt::printScientificDouble(beam_intensity) << ")\n";
     return result.str();
 }
@@ -277,7 +276,7 @@ std::string defineGISASBeam(const GISASSimulation& simulation) {
     return result.str();
 }
 
-std::string defineOffSpecBeam(const OffSpecSimulation& simulation) {
+std::string defineOffSpecularBeam(const OffSpecularSimulation& simulation) {
     std::ostringstream result;
     const Beam& beam = simulation.instrument().beam();
 
@@ -398,13 +397,13 @@ std::string defineGISASSimulation(const GISASSimulation* simulation) {
     return result.str();
 }
 
-std::string defineOffSpecSimulation(const OffSpecSimulation* simulation) {
+std::string defineOffSpecularSimulation(const OffSpecularSimulation* simulation) {
     std::ostringstream result;
-    result << indent() << "simulation = ba.OffSpecSimulation()\n";
+    result << indent() << "simulation = ba.OffSpecularSimulation()\n";
     result << defineDetector(simulation);
     result << defineDetectorResolutionFunction(simulation);
     result << defineDetectorPolarizationAnalysis(simulation);
-    result << defineOffSpecBeam(*simulation);
+    result << defineOffSpecularBeam(*simulation);
     result << defineParameterDistributions(simulation);
     result << defineMasks(simulation);
     result << defineSimulationOptions(simulation);
@@ -430,8 +429,8 @@ std::string defineSimulate(const ISimulation* simulation) {
     result << "def get_simulation():\n";
     if (auto gisas = dynamic_cast<const GISASSimulation*>(simulation))
         result << defineGISASSimulation(gisas);
-    else if (auto offspec = dynamic_cast<const OffSpecSimulation*>(simulation))
-        result << defineOffSpecSimulation(offspec);
+    else if (auto offspec = dynamic_cast<const OffSpecularSimulation*>(simulation))
+        result << defineOffSpecularSimulation(offspec);
     else if (auto spec = dynamic_cast<const SpecularSimulation*>(simulation))
         result << defineSpecularSimulation(spec);
     else
diff --git a/Core/Export/SimulationToPython.h b/Core/Export/SimulationToPython.h
index 655f4c3cee7301bb115669e496b55fabf27f30f5..2110dc202a28451b1ba4fd8da4178f872213bb29 100644
--- a/Core/Export/SimulationToPython.h
+++ b/Core/Export/SimulationToPython.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_EXPORT_SIMULATIONTOPYTHON_H
 #define BORNAGAIN_CORE_EXPORT_SIMULATIONTOPYTHON_H
 
@@ -32,3 +33,4 @@ public:
 };
 
 #endif // BORNAGAIN_CORE_EXPORT_SIMULATIONTOPYTHON_H
+#endif // USER_API
diff --git a/Core/Fitting/FitObjective.cpp b/Core/Fitting/FitObjective.cpp
index bbfe22194049751bd6793e6d3c5e08717955316a..f1e71a0075ec836460cd624165259621e59011e2 100644
--- a/Core/Fitting/FitObjective.cpp
+++ b/Core/Fitting/FitObjective.cpp
@@ -18,7 +18,7 @@
 #include "Core/Fitting/ObjectiveMetricUtils.h"
 #include "Core/Fitting/PyFittingCallbacks.h"
 #include "Core/Simulation/ISimulation.h"
-#include "Device/Instrument/ChiSquaredModule.h"
+#include "Core/Residual/ChiSquaredModule.h"
 #include <stdexcept>
 
 class IMetricWrapper {
diff --git a/Core/Fitting/FitObjective.h b/Core/Fitting/FitObjective.h
index e3d1570096a439ab4689fb877b9f683b8649d49d..dd66a0d61e912b29fda3bdc49181370f102fe14a 100644
--- a/Core/Fitting/FitObjective.h
+++ b/Core/Fitting/FitObjective.h
@@ -17,7 +17,7 @@
 
 #include "Core/Fitting/IterationInfo.h"
 #include "Core/Fitting/SimDataPair.h"
-#include "Device/Intensity/ArrayUtils.h"
+#include "Device/Data/ArrayUtils.h"
 #include "Fit/Minimizer/MinimizerResult.h"
 
 class FitStatus;
@@ -126,7 +126,7 @@ public:
     bool isFirstIteration() const;
 
     void setObjectiveMetric(std::unique_ptr<ObjectiveMetric> metric);
-#endif // SWIG
+#endif // USER_API
 
 private:
     typedef std::vector<double> (SimDataPair::*DataPairAccessor)() const;
diff --git a/Core/Fitting/FitObserver.h b/Core/Fitting/FitObserver.h
index 8a913270791d58f8e8fcf091a71e83d019bc55f1..cf0b74f8058382c5fe286dff41d8027a90ce0e6b 100644
--- a/Core/Fitting/FitObserver.h
+++ b/Core/Fitting/FitObserver.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_FITTING_FITOBSERVER_H
 #define BORNAGAIN_CORE_FITTING_FITOBSERVER_H
 
@@ -86,3 +87,4 @@ template <class T> bool FitObserver<T>::need_notify(int every_nth) {
 }
 
 #endif // BORNAGAIN_CORE_FITTING_FITOBSERVER_H
+#endif // USER_API
diff --git a/Core/Fitting/FitPrintService.h b/Core/Fitting/FitPrintService.h
index f4a55916b99caaef0d690a6f81ddbd2e33b75352..cd0125ee62593b9e385865d9d5fbbd2bb18f29c1 100644
--- a/Core/Fitting/FitPrintService.h
+++ b/Core/Fitting/FitPrintService.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_FITTING_FITPRINTSERVICE_H
 #define BORNAGAIN_CORE_FITTING_FITPRINTSERVICE_H
 
@@ -43,3 +44,4 @@ private:
 };
 
 #endif // BORNAGAIN_CORE_FITTING_FITPRINTSERVICE_H
+#endif // USER_API
diff --git a/Core/Fitting/FitStatus.h b/Core/Fitting/FitStatus.h
index ce5cbe66705e1fa57865cadc7a5a078ceb0240a3..d53db89e0967510ca3a170deeed1119d21077661 100644
--- a/Core/Fitting/FitStatus.h
+++ b/Core/Fitting/FitStatus.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_FITTING_FITSTATUS_H
 #define BORNAGAIN_CORE_FITTING_FITSTATUS_H
 
@@ -67,3 +68,4 @@ private:
 };
 
 #endif // BORNAGAIN_CORE_FITTING_FITSTATUS_H
+#endif // USER_API
diff --git a/Core/Fitting/FitTypes.h b/Core/Fitting/FitTypes.h
index 4b2baa06ca7a284188e6e31237a8340eb6041b15..17351e31750aeb6e94e9f2aeede082e446c43aae 100644
--- a/Core/Fitting/FitTypes.h
+++ b/Core/Fitting/FitTypes.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_FITTING_FITTYPES_H
 #define BORNAGAIN_CORE_FITTING_FITTYPES_H
 
@@ -34,3 +35,4 @@ using simulation_builder_t =
 using fit_observer_t = std::function<void(const FitObjective&)>;
 
 #endif // BORNAGAIN_CORE_FITTING_FITTYPES_H
+#endif // USER_API
diff --git a/Core/Fitting/IObserver.cpp b/Core/Fitting/IObserver.cpp
deleted file mode 100644
index 3758b81cf5db58fa50f1575cbc089348024bc7fa..0000000000000000000000000000000000000000
--- a/Core/Fitting/IObserver.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-//  ************************************************************************************************
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Fitting/IObserver.cpp
-//! @brief     Implements interface IObserver, mostly by including IObserver.h.
-//!
-//! @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 "Core/Fitting/IObserver.h"
-
-void IObservable::attachObserver(observer_t obj) {
-    m_observers.push_back(obj);
-}
-
-void IObservable::notifyObservers() {
-    for (auto it : m_observers)
-        it->notify(this);
-}
-
-IObserver::~IObserver() = default;
-
-IObservable::~IObservable() = default;
diff --git a/Core/Fitting/IObserver.h b/Core/Fitting/IObserver.h
deleted file mode 100644
index caecd709cb88ddb9c2bd6400dfb81815ccd41e24..0000000000000000000000000000000000000000
--- a/Core/Fitting/IObserver.h
+++ /dev/null
@@ -1,54 +0,0 @@
-//  ************************************************************************************************
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Core/Fitting/IObserver.h
-//! @brief     Defines classes IObserver and IObservable (Observer pattern).
-//!
-//! @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 BORNAGAIN_CORE_FITTING_IOBSERVER_H
-#define BORNAGAIN_CORE_FITTING_IOBSERVER_H
-
-#include <list>
-#include <memory>
-
-class IObservable;
-
-//! Observer interface from %Observer pattern.
-//! @ingroup tools_internal
-
-class IObserver {
-public:
-    virtual ~IObserver();
-
-    //! method which is used by observable subject to notify change in status
-    virtual void notify(IObservable* subject) = 0;
-};
-
-//! Observable interface from %Observer pattern
-//! @ingroup tools_internal
-
-class IObservable {
-public:
-    //! Shared pointer is used when passing these objects from Python to C++
-    typedef std::shared_ptr<IObserver> observer_t;
-
-    virtual ~IObservable();
-
-    //! attach observer to the list of observers
-    virtual void attachObserver(observer_t obj);
-
-    //! notify observers about change in status
-    virtual void notifyObservers();
-
-private:
-    std::list<observer_t> m_observers;
-};
-
-#endif // BORNAGAIN_CORE_FITTING_IOBSERVER_H
diff --git a/Core/Fitting/ObjectiveMetric.h b/Core/Fitting/ObjectiveMetric.h
index f514d1ddd01ad87deb2e2dd1b910d590a8cc5598..f00a56478ac0880c6e13d2f3fb50a5afc57a8624 100644
--- a/Core/Fitting/ObjectiveMetric.h
+++ b/Core/Fitting/ObjectiveMetric.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_FITTING_OBJECTIVEMETRIC_H
 #define BORNAGAIN_CORE_FITTING_OBJECTIVEMETRIC_H
 
@@ -198,3 +199,4 @@ public:
 };
 
 #endif // BORNAGAIN_CORE_FITTING_OBJECTIVEMETRIC_H
+#endif // USER_API
diff --git a/Core/Fitting/ObjectiveMetricUtils.h b/Core/Fitting/ObjectiveMetricUtils.h
index 25d73db4144882d77bf6b77fdb020f27414e51b2..f6f50a127ea368775fea2314797e9d69d523c063 100644
--- a/Core/Fitting/ObjectiveMetricUtils.h
+++ b/Core/Fitting/ObjectiveMetricUtils.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_FITTING_OBJECTIVEMETRICUTILS_H
 #define BORNAGAIN_CORE_FITTING_OBJECTIVEMETRICUTILS_H
 
@@ -59,3 +60,4 @@ std::string defaultMetricName();
 } // namespace ObjectiveMetricUtils
 
 #endif // BORNAGAIN_CORE_FITTING_OBJECTIVEMETRICUTILS_H
+#endif // USER_API
diff --git a/Core/Fitting/SimDataPair.cpp b/Core/Fitting/SimDataPair.cpp
index 96340ff15711e04bcae87c552b8aeb1d5664140d..27e5f2898d52cb7e02e6685a9104a5aafb80e453 100644
--- a/Core/Fitting/SimDataPair.cpp
+++ b/Core/Fitting/SimDataPair.cpp
@@ -16,7 +16,7 @@
 #include "Base/Math/Numeric.h"
 #include "Core/Simulation/ISimulation.h"
 #include "Core/Simulation/UnitConverterUtils.h"
-#include "Device/Instrument/IntensityDataFunctions.h"
+#include "Device/Data/DataUtils.h"
 
 namespace {
 [[noreturn]] void throwInitializationException(std::string method) {
diff --git a/Core/Fitting/SimDataPair.h b/Core/Fitting/SimDataPair.h
index 3da9ac94e500a2becb21f56f39b1197a230f8806..1eebd6f632c0c720dc24dc706f24968463870489 100644
--- a/Core/Fitting/SimDataPair.h
+++ b/Core/Fitting/SimDataPair.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_FITTING_SIMDATAPAIR_H
 #define BORNAGAIN_CORE_FITTING_SIMDATAPAIR_H
 
@@ -109,3 +110,4 @@ private:
 };
 
 #endif // BORNAGAIN_CORE_FITTING_SIMDATAPAIR_H
+#endif // USER_API
diff --git a/Device/Instrument/ChiSquaredModule.cpp b/Core/Residual/ChiSquaredModule.cpp
similarity index 85%
rename from Device/Instrument/ChiSquaredModule.cpp
rename to Core/Residual/ChiSquaredModule.cpp
index 20054b719adb85f194754f7f0aa5b13020d94f42..8eb31544b17147da10993df6846dd92d9bfd4589 100644
--- a/Device/Instrument/ChiSquaredModule.cpp
+++ b/Core/Residual/ChiSquaredModule.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Device/Instrument/ChiSquaredModule.cpp
+//! @file      Core/Residual/ChiSquaredModule.cpp
 //! @brief     Implements class ChiSquaredModule.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,10 +12,10 @@
 //
 //  ************************************************************************************************
 
-#include "Device/Instrument/ChiSquaredModule.h"
+#include "Core/Residual/ChiSquaredModule.h"
 #include "Base/Utils/Assert.h"
-#include "Device/Instrument/VarianceFunctions.h"
-#include "Device/Intensity/IIntensityFunction.h"
+#include "Core/Residual/VarianceFunctions.h"
+#include "Core/Residual/IIntensityFunction.h"
 #include <cmath>
 #include <limits>
 
diff --git a/Device/Instrument/ChiSquaredModule.h b/Core/Residual/ChiSquaredModule.h
similarity index 92%
rename from Device/Instrument/ChiSquaredModule.h
rename to Core/Residual/ChiSquaredModule.h
index 9f38ccee04f8427af61e4ba45e177d6bb678bcd5..f9d200997f079df965764a0683195945f6df17e0 100644
--- a/Device/Instrument/ChiSquaredModule.h
+++ b/Core/Residual/ChiSquaredModule.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Device/Instrument/ChiSquaredModule.h
+//! @file      Core/Residual/ChiSquaredModule.h
 //! @brief     Defines class ChiSquaredModule.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -15,7 +15,7 @@
 #ifndef BORNAGAIN_DEVICE_INSTRUMENT_CHISQUAREDMODULE_H
 #define BORNAGAIN_DEVICE_INSTRUMENT_CHISQUAREDMODULE_H
 
-#include "Device/Instrument/IChiSquaredModule.h"
+#include "Core/Residual/IChiSquaredModule.h"
 
 //! Calculation of chi2 between two data sets.
 //! @ingroup fitting
diff --git a/Device/Instrument/IChiSquaredModule.cpp b/Core/Residual/IChiSquaredModule.cpp
similarity index 88%
rename from Device/Instrument/IChiSquaredModule.cpp
rename to Core/Residual/IChiSquaredModule.cpp
index 68ba170cecf257af8247031b5b8f57bf594117bc..0351bd6faa524a6a548cb90bb59b63a1d76ae315 100644
--- a/Device/Instrument/IChiSquaredModule.cpp
+++ b/Core/Residual/IChiSquaredModule.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Device/Instrument/IChiSquaredModule.cpp
+//! @file      Core/Residual/IChiSquaredModule.cpp
 //! @brief     Implements interface IChiSquaredModule.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,9 +12,9 @@
 //
 //  ************************************************************************************************
 
-#include "Device/Instrument/IChiSquaredModule.h"
-#include "Device/Instrument/VarianceFunctions.h"
-#include "Device/Intensity/IIntensityFunction.h"
+#include "Core/Residual/IChiSquaredModule.h"
+#include "Core/Residual/VarianceFunctions.h"
+#include "Core/Residual/IIntensityFunction.h"
 
 IChiSquaredModule::IChiSquaredModule() : m_variance_function(new VarianceSimFunction) {}
 
diff --git a/Device/Instrument/IChiSquaredModule.h b/Core/Residual/IChiSquaredModule.h
similarity index 95%
rename from Device/Instrument/IChiSquaredModule.h
rename to Core/Residual/IChiSquaredModule.h
index 3e66f788e0da0abbb2fdfd295fb5ff993ae23bf0..7beda9b879e4c05250320458813b8ad4a3ca48e3 100644
--- a/Device/Instrument/IChiSquaredModule.h
+++ b/Core/Residual/IChiSquaredModule.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Device/Instrument/IChiSquaredModule.h
+//! @file      Core/Residual/IChiSquaredModule.h
 //! @brief     Defines interface IChiSquaredModule.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_INSTRUMENT_ICHISQUAREDMODULE_H
 #define BORNAGAIN_DEVICE_INSTRUMENT_ICHISQUAREDMODULE_H
 
@@ -54,3 +55,4 @@ protected:
 };
 
 #endif // BORNAGAIN_DEVICE_INSTRUMENT_ICHISQUAREDMODULE_H
+#endif // USER_API
diff --git a/Device/Intensity/IIntensityFunction.cpp b/Core/Residual/IIntensityFunction.cpp
similarity index 91%
rename from Device/Intensity/IIntensityFunction.cpp
rename to Core/Residual/IIntensityFunction.cpp
index f55aeda750f3b87fd6b4111ead353d7a0ce6f733..d06c0ffe8ecd320d6a917639f4b7ef815ece9539 100644
--- a/Device/Intensity/IIntensityFunction.cpp
+++ b/Core/Residual/IIntensityFunction.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Device/Intensity/IIntensityFunction.cpp
+//! @file      Core/Residual/IIntensityFunction.cpp
 //! @brief     Implements the classes IntensityFunctionLog, IntensityFunctionSqrt
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,7 +12,7 @@
 //
 //  ************************************************************************************************
 
-#include "Device/Intensity/IIntensityFunction.h"
+#include "Core/Residual/IIntensityFunction.h"
 #include <cmath>
 #include <limits>
 
diff --git a/Device/Intensity/IIntensityFunction.h b/Core/Residual/IIntensityFunction.h
similarity index 95%
rename from Device/Intensity/IIntensityFunction.h
rename to Core/Residual/IIntensityFunction.h
index fb3efe7d517c3978c84766d71a586e6b87606600..4fbe8077738249d2f38527821b58c6877007bd0a 100644
--- a/Device/Intensity/IIntensityFunction.h
+++ b/Core/Residual/IIntensityFunction.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Device/Intensity/IIntensityFunction.h
+//! @file      Core/Residual/IIntensityFunction.h
 //! @brief     Defines and implements the interface class IIntensityFunction
 //!            and its child classes IntensityFunctionLog, IntensityFunctionSqrt
 //!
@@ -13,6 +13,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_INTENSITY_IINTENSITYFUNCTION_H
 #define BORNAGAIN_DEVICE_INTENSITY_IINTENSITYFUNCTION_H
 
@@ -45,3 +46,4 @@ public:
 };
 
 #endif // BORNAGAIN_DEVICE_INTENSITY_IINTENSITYFUNCTION_H
+#endif // USER_API
diff --git a/Device/Instrument/VarianceFunctions.cpp b/Core/Residual/VarianceFunctions.cpp
similarity index 93%
rename from Device/Instrument/VarianceFunctions.cpp
rename to Core/Residual/VarianceFunctions.cpp
index ce2901780280308f16cf12d814bbfa68064d72b2..af51a0493924f66470aaae53fc6aa3d19737b5e7 100644
--- a/Device/Instrument/VarianceFunctions.cpp
+++ b/Core/Residual/VarianceFunctions.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Device/Instrument/VarianceFunctions.cpp
+//! @file      Core/Residual/VarianceFunctions.cpp
 //! @brief     Implements IVarianceFunction classes
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,7 +12,7 @@
 //
 //  ************************************************************************************************
 
-#include "Device/Instrument/VarianceFunctions.h"
+#include "Core/Residual/VarianceFunctions.h"
 #include <algorithm>
 
 //  ************************************************************************************************
diff --git a/Device/Instrument/VarianceFunctions.h b/Core/Residual/VarianceFunctions.h
similarity index 97%
rename from Device/Instrument/VarianceFunctions.h
rename to Core/Residual/VarianceFunctions.h
index fb27ea2bdb8331965eec8454f53c046687b356ac..833f5f72f3bdc419a8fe757b02b4f2653308af85 100644
--- a/Device/Instrument/VarianceFunctions.h
+++ b/Core/Residual/VarianceFunctions.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Device/Instrument/VarianceFunctions.h
+//! @file      Core/Residual/VarianceFunctions.h
 //! @brief     Defines IVarianceFunction classes
 //!
 //! @homepage  http://www.bornagainproject.org
diff --git a/Core/Scan/AngularSpecScan.h b/Core/Scan/AngularSpecScan.h
index d8c7d24690257b02b95bc108c5ad3cd7cfe332db..a073a15ad27124adb31c56fe7716d81776546d50 100644
--- a/Core/Scan/AngularSpecScan.h
+++ b/Core/Scan/AngularSpecScan.h
@@ -64,7 +64,7 @@ public:
     // TODO: remove these getters after transition to the new resolution machinery is finished
     const ScanResolution* wavelengthResolution() const { return m_wl_resolution.get(); }
     const ScanResolution* angleResolution() const { return m_inc_resolution.get(); }
-#endif // SWIG
+#endif // USER_API
 
     //! Sets footprint correction factor
     void setFootprintFactor(const IFootprintFactor* f_factor);
diff --git a/Core/Scan/ISpecularScan.h b/Core/Scan/ISpecularScan.h
index 30ceb9e0b6e21574ce634b2933830c7717d7a33e..24e01d65517a3ddccf207be95ee4dc6ee2f37468 100644
--- a/Core/Scan/ISpecularScan.h
+++ b/Core/Scan/ISpecularScan.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_SCAN_ISPECULARSCAN_H
 #define BORNAGAIN_CORE_SCAN_ISPECULARSCAN_H
 
@@ -54,7 +55,8 @@ public:
     virtual std::vector<double>
     createIntensities(const std::vector<SpecularSimulationElement>& sim_elements) const = 0;
 
-#endif // SWIG
+#endif // USER_API
 };
 
 #endif // BORNAGAIN_CORE_SCAN_ISPECULARSCAN_H
+#endif // USER_API
diff --git a/Core/Scan/QSpecScan.h b/Core/Scan/QSpecScan.h
index 0f6289e17232516707c9ccc268eeac66aa05ed7e..89bf72cfe5d5e744577b0df861cecf54758446c7 100644
--- a/Core/Scan/QSpecScan.h
+++ b/Core/Scan/QSpecScan.h
@@ -63,7 +63,7 @@ public:
     std::vector<double>
     createIntensities(const std::vector<SpecularSimulationElement>& sim_elements) const override;
 
-#endif // SWIG
+#endif // USER_API
 
     //! Sets q resolution values via ScanResolution object.
     void setQResolution(const ScanResolution& resolution);
diff --git a/Core/Scan/UnitConverter1D.h b/Core/Scan/UnitConverter1D.h
index deac928ceb6b43c990e817c9ff146b12322683fb..88b373e07f0ff07e12c0a80c72dceb1d16935b79 100644
--- a/Core/Scan/UnitConverter1D.h
+++ b/Core/Scan/UnitConverter1D.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_SCAN_UNITCONVERTER1D_H
 #define BORNAGAIN_CORE_SCAN_UNITCONVERTER1D_H
 
@@ -131,3 +132,4 @@ protected:
     std::unique_ptr<IAxis> m_axis; //!< qz values (in inv. nm).
 };
 #endif // BORNAGAIN_CORE_SCAN_UNITCONVERTER1D_H
+#endif // USER_API
diff --git a/Core/Simulation/ISimulation.cpp b/Core/Simulation/ISimulation.cpp
index 402d1fc08121dbaa13a6435c794caa4008b91bc8..4baa823d776e642fec12b169b72db38dae7700b7 100644
--- a/Core/Simulation/ISimulation.cpp
+++ b/Core/Simulation/ISimulation.cpp
@@ -162,15 +162,6 @@ void ISimulation::setAnalyzerProperties(const kvector_t direction, double effici
     detector().setAnalyzerProperties(direction, efficiency, total_transmission);
 }
 
-void ISimulation::setBeamIntensity(double intensity) {
-    beam().setIntensity(intensity);
-}
-
-//! Sets the beam polarization according to the given Bloch vector
-void ISimulation::setBeamPolarization(const kvector_t bloch_vector) {
-    beam().setPolarization(bloch_vector);
-}
-
 void ISimulation::prepareSimulation() {
     m_sample_provider.updateSample();
     if (!MultiLayerUtils::ContainsCompatibleMaterials(*m_sample_provider.sample()))
diff --git a/Core/Simulation/ISimulation.h b/Core/Simulation/ISimulation.h
index f14278900e4d1231f1e14027135091b65aa56704..89d9ea501524ff60eb8f0a5c62f05238cf5d35da 100644
--- a/Core/Simulation/ISimulation.h
+++ b/Core/Simulation/ISimulation.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_SIMULATION_ISIMULATION_H
 #define BORNAGAIN_CORE_SIMULATION_ISIMULATION_H
 
@@ -61,10 +62,6 @@ public:
     IDetector& detector() { return m_instrument.detector(); }
     const IDetector& detector() const { return m_instrument.detector(); }
 
-    void setBeamIntensity(double intensity);
-
-    void setBeamPolarization(const kvector_t bloch_vector);
-
     void setDetectorResolutionFunction(const IResolutionFunction2D& resolution_function);
 
     void setAnalyzerProperties(const kvector_t direction, double efficiency,
@@ -162,3 +159,4 @@ private:
 };
 
 #endif // BORNAGAIN_CORE_SIMULATION_ISIMULATION_H
+#endif // USER_API
diff --git a/Core/Simulation/ISimulation2D.h b/Core/Simulation/ISimulation2D.h
index e97dfa2369d66ebba3e7ad427020e7d36b3e58e6..2c04c936e76729422719c040de25bf0a58a902c0 100644
--- a/Core/Simulation/ISimulation2D.h
+++ b/Core/Simulation/ISimulation2D.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_SIMULATION_ISIMULATION2D_H
 #define BORNAGAIN_CORE_SIMULATION_ISIMULATION2D_H
 
@@ -98,3 +99,4 @@ private:
 };
 
 #endif // BORNAGAIN_CORE_SIMULATION_ISIMULATION2D_H
+#endif // USER_API
diff --git a/Core/Simulation/MPISimulation.h b/Core/Simulation/MPISimulation.h
index 67e644e47e92a5ac639b9f998e9cdd945d4bf828..e52901456f228f235770973f9e11390c282cd81c 100644
--- a/Core/Simulation/MPISimulation.h
+++ b/Core/Simulation/MPISimulation.h
@@ -17,6 +17,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_SIMULATION_MPISIMULATION_H
 #define BORNAGAIN_CORE_SIMULATION_MPISIMULATION_H
 
@@ -28,3 +29,4 @@ public:
 };
 
 #endif // BORNAGAIN_CORE_SIMULATION_MPISIMULATION_H
+#endif // USER_API
diff --git a/Core/Simulation/OffSpecSimulation.cpp b/Core/Simulation/OffSpecularSimulation.cpp
similarity index 70%
rename from Core/Simulation/OffSpecSimulation.cpp
rename to Core/Simulation/OffSpecularSimulation.cpp
index 176b059ba0e8c78b43fd8a5f2a5df06c0af9d060..58e32d43b8dbb1b7085a62087548e5ec0d811f4b 100644
--- a/Core/Simulation/OffSpecSimulation.cpp
+++ b/Core/Simulation/OffSpecularSimulation.cpp
@@ -2,8 +2,8 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Core/Simulation/OffSpecSimulation.cpp
-//! @brief     Implements class OffSpecSimulation.
+//! @file      Core/Simulation/OffSpecularSimulation.cpp
+//! @brief     Implements class OffSpecularSimulation.
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -12,7 +12,7 @@
 //
 //  ************************************************************************************************
 
-#include "Core/Simulation/OffSpecSimulation.h"
+#include "Core/Simulation/OffSpecularSimulation.h"
 #include "Core/Computation/DWBAComputation.h"
 #include "Device/Detector/SimpleUnitConverters.h"
 #include "Device/Histo/Histogram2D.h"
@@ -22,67 +22,68 @@
 #include "Sample/Multilayer/MultiLayer.h"
 #include "Sample/SampleBuilderEngine/ISampleBuilder.h"
 
-OffSpecSimulation::OffSpecSimulation(const Beam& beam, const MultiLayer& sample,
-                                     const IDetector& detector)
+OffSpecularSimulation::OffSpecularSimulation(const Beam& beam, const MultiLayer& sample,
+                                             const IDetector& detector)
     : ISimulation2D(beam, sample, detector) {}
 
-OffSpecSimulation::OffSpecSimulation() {
+OffSpecularSimulation::OffSpecularSimulation() {
     initialize();
 }
 
-void OffSpecSimulation::prepareSimulation() {
+void OffSpecularSimulation::prepareSimulation() {
     checkInitialization();
     ISimulation2D::prepareSimulation();
 }
 
-size_t OffSpecSimulation::numberOfSimulationElements() const {
+size_t OffSpecularSimulation::numberOfSimulationElements() const {
     checkInitialization();
     return ISimulation2D::numberOfSimulationElements() * m_alpha_i_axis->size();
 }
 
-SimulationResult OffSpecSimulation::result() const {
+SimulationResult OffSpecularSimulation::result() const {
     auto data = std::unique_ptr<OutputData<double>>(m_intensity_map.clone());
     OffSpecularConverter converter(instrument().detector2D(), instrument().beam(), *m_alpha_i_axis);
     return SimulationResult(*data, converter);
 }
 
-void OffSpecSimulation::setBeamParameters(double wavelength, const IAxis& alpha_axis,
-                                          double phi_i) {
+void OffSpecularSimulation::setBeamParameters(double wavelength, const IAxis& alpha_axis,
+                                              double phi_i) {
     m_alpha_i_axis.reset(alpha_axis.clone());
     if (alpha_axis.size() < 1)
-        throw std::runtime_error("OffSpecSimulation::prepareSimulation() "
+        throw std::runtime_error("OffSpecularSimulation::prepareSimulation() "
                                  "-> Error. Incoming alpha range size < 1.");
     const double alpha_zero = alpha_axis.lowerBound();
     instrument().setBeamParameters(wavelength, alpha_zero, phi_i);
     updateIntensityMap();
 }
 
-const IAxis* OffSpecSimulation::beamAxis() const {
+const IAxis* OffSpecularSimulation::beamAxis() const {
     return m_alpha_i_axis.get();
 }
 
-std::unique_ptr<IUnitConverter> OffSpecSimulation::createUnitConverter() const {
+std::unique_ptr<IUnitConverter> OffSpecularSimulation::createUnitConverter() const {
     const IAxis* axis = beamAxis();
     if (!axis)
-        throw std::runtime_error("Error in OffSpecSimulation::createUnitConverter:"
+        throw std::runtime_error("Error in OffSpecularSimulation::createUnitConverter:"
                                  " missing inclination angle axis");
     return std::make_unique<OffSpecularConverter>(instrument().detector2D(), instrument().beam(),
                                                   *axis);
 }
 
-size_t OffSpecSimulation::intensityMapSize() const {
+size_t OffSpecularSimulation::intensityMapSize() const {
     checkInitialization();
     return m_alpha_i_axis->size() * detector().axis(1).size();
 }
 
-OffSpecSimulation::OffSpecSimulation(const OffSpecSimulation& other) : ISimulation2D(other) {
+OffSpecularSimulation::OffSpecularSimulation(const OffSpecularSimulation& other)
+    : ISimulation2D(other) {
     if (other.m_alpha_i_axis)
         m_alpha_i_axis.reset(other.m_alpha_i_axis->clone());
     m_intensity_map.copyFrom(other.m_intensity_map);
     initialize();
 }
 
-void OffSpecSimulation::initSimulationElementVector() {
+void OffSpecularSimulation::initSimulationElementVector() {
     m_sim_elements.clear();
     Beam beam = instrument().beam();
     for (size_t i = 0; i < m_alpha_i_axis->size(); ++i) {
@@ -95,7 +96,7 @@ void OffSpecSimulation::initSimulationElementVector() {
         m_cache.resize(m_sim_elements.size(), 0.0);
 }
 
-void OffSpecSimulation::validateParametrization(const ParameterDistribution& par_distr) const {
+void OffSpecularSimulation::validateParametrization(const ParameterDistribution& par_distr) const {
     const bool zero_mean = par_distr.getDistribution()->getMean() == 0.0;
     if (zero_mean)
         return;
@@ -105,23 +106,23 @@ void OffSpecSimulation::validateParametrization(const ParameterDistribution& par
         parameter_pool->getMatchedParameters(par_distr.getMainParameterName());
     for (const auto par : names)
         if (par->getName().find("InclinationAngle") != std::string::npos && !zero_mean)
-            throw std::runtime_error("Error in OffSpecSimulation: parameter distribution of "
+            throw std::runtime_error("Error in OffSpecularSimulation: parameter distribution of "
                                      "beam inclination angle should have zero mean.");
 }
 
-void OffSpecSimulation::transferResultsToIntensityMap() {
+void OffSpecularSimulation::transferResultsToIntensityMap() {
     checkInitialization();
     const IAxis& phi_axis = detector().axis(0);
     size_t phi_f_size = phi_axis.size();
     if (phi_f_size * m_intensity_map.getAllocatedSize() != m_sim_elements.size())
         throw std::runtime_error(
-            "OffSpecSimulation::transferResultsToIntensityMap: "
+            "OffSpecularSimulation::transferResultsToIntensityMap: "
             "intensity map size does not conform to number of calculated intensities");
     for (size_t i = 0; i < m_alpha_i_axis->size(); ++i)
         transferDetectorImage(i);
 }
 
-void OffSpecSimulation::updateIntensityMap() {
+void OffSpecularSimulation::updateIntensityMap() {
     m_intensity_map.clear();
     if (m_alpha_i_axis)
         m_intensity_map.addAxis(*m_alpha_i_axis);
@@ -131,7 +132,7 @@ void OffSpecSimulation::updateIntensityMap() {
     m_intensity_map.setAllTo(0.);
 }
 
-void OffSpecSimulation::transferDetectorImage(size_t index) {
+void OffSpecularSimulation::transferDetectorImage(size_t index) {
     OutputData<double> detector_image;
     size_t detector_dimension = detector().dimension();
     for (size_t dim = 0; dim < detector_dimension; ++dim)
@@ -145,15 +146,15 @@ void OffSpecSimulation::transferDetectorImage(size_t index) {
         m_intensity_map[index * y_axis_size + i % y_axis_size] += detector_image[i];
 }
 
-void OffSpecSimulation::checkInitialization() const {
+void OffSpecularSimulation::checkInitialization() const {
     if (!m_alpha_i_axis || m_alpha_i_axis->size() < 1)
-        throw std::runtime_error("OffSpecSimulation::checkInitialization() "
+        throw std::runtime_error("OffSpecularSimulation::checkInitialization() "
                                  "Incoming alpha range not configured.");
     if (detector().dimension() != 2)
         throw std::runtime_error(
-            "OffSpecSimulation::checkInitialization: detector is not two-dimensional");
+            "OffSpecularSimulation::checkInitialization: detector is not two-dimensional");
 }
 
-void OffSpecSimulation::initialize() {
-    setName("OffSpecSimulation");
+void OffSpecularSimulation::initialize() {
+    setName("OffSpecularSimulation");
 }
diff --git a/Core/Simulation/OffSpecSimulation.h b/Core/Simulation/OffSpecularSimulation.h
similarity index 79%
rename from Core/Simulation/OffSpecSimulation.h
rename to Core/Simulation/OffSpecularSimulation.h
index 25e72c996dc2eafd5b07c46e1fe355ec0714243f..3dcb4526a0df7983e58ca0e7f16e7ed7c0f19253 100644
--- a/Core/Simulation/OffSpecSimulation.h
+++ b/Core/Simulation/OffSpecularSimulation.h
@@ -2,8 +2,8 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Core/Simulation/OffSpecSimulation.h
-//! @brief     Defines class OffSpecSimulation.
+//! @file      Core/Simulation/OffSpecularSimulation.h
+//! @brief     Defines class OffSpecularSimulation.
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -12,8 +12,8 @@
 //
 //  ************************************************************************************************
 
-#ifndef BORNAGAIN_CORE_SIMULATION_OFFSPECSIMULATION_H
-#define BORNAGAIN_CORE_SIMULATION_OFFSPECSIMULATION_H
+#ifndef BORNAGAIN_CORE_SIMULATION_OFFSPECULARSIMULATION_H
+#define BORNAGAIN_CORE_SIMULATION_OFFSPECULARSIMULATION_H
 
 #include "Base/Pixel/SimulationElement.h"
 #include "Core/Simulation/ISimulation2D.h"
@@ -23,13 +23,13 @@ class Histogram2D;
 //! Main class to run an off-specular simulation.
 //! @ingroup simulation
 
-class OffSpecSimulation : public ISimulation2D {
+class OffSpecularSimulation : public ISimulation2D {
 public:
-    OffSpecSimulation(const Beam& beam, const MultiLayer& sample, const IDetector& detector);
-    OffSpecSimulation();
-    ~OffSpecSimulation() override {}
+    OffSpecularSimulation(const Beam& beam, const MultiLayer& sample, const IDetector& detector);
+    OffSpecularSimulation();
+    ~OffSpecularSimulation() override {}
 
-    OffSpecSimulation* clone() const override { return new OffSpecSimulation(*this); }
+    OffSpecularSimulation* clone() const override { return new OffSpecularSimulation(*this); }
 
     void accept(INodeVisitor* visitor) const override { visitor->visit(this); }
 
@@ -54,7 +54,7 @@ public:
     size_t intensityMapSize() const override;
 
 private:
-    OffSpecSimulation(const OffSpecSimulation& other);
+    OffSpecularSimulation(const OffSpecularSimulation& other);
 
     //! Initializes the vector of ISimulation elements
     void initSimulationElementVector() override;
@@ -85,4 +85,4 @@ private:
     OutputData<double> m_intensity_map;
 };
 
-#endif // BORNAGAIN_CORE_SIMULATION_OFFSPECSIMULATION_H
+#endif // BORNAGAIN_CORE_SIMULATION_OFFSPECULARSIMULATION_H
diff --git a/Core/Simulation/SimulationFactory.cpp b/Core/Simulation/SimulationFactory.cpp
index f85e1d56f357b824b075cd0e5c41226ca506096d..d744bbe7c9f0ba9b9adc9d96988032d3b316006a 100644
--- a/Core/Simulation/SimulationFactory.cpp
+++ b/Core/Simulation/SimulationFactory.cpp
@@ -14,7 +14,7 @@
 
 #include "Core/Simulation/SimulationFactory.h"
 #include "Core/Simulation/DepthProbeSimulation.h"
-#include "Core/Simulation/OffSpecSimulation.h"
+#include "Core/Simulation/OffSpecularSimulation.h"
 #include "Core/Simulation/SpecularSimulation.h"
 #include "Core/Simulation/StandardSimulations.h"
 #include "Param/Base/RealParameter.h"
@@ -100,7 +100,7 @@ SimulationFactory::SimulationFactory() {
 
     registerItem("TOFRWithPointwiseResolution", StandardSimulations::TOFRWithPointwiseResolution);
 
-    registerItem("OffSpecMini", StandardSimulations::MiniOffSpec);
+    registerItem("OffSpecularMini", StandardSimulations::MiniOffSpecular);
 
     // polarized specular
 
diff --git a/Core/Simulation/SimulationFactory.h b/Core/Simulation/SimulationFactory.h
index 9c31fb459f2f1a020a35da04d87e709b422029a5..8b566ee7937608c035ff59d412d0814e45e986ba 100644
--- a/Core/Simulation/SimulationFactory.h
+++ b/Core/Simulation/SimulationFactory.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_SIMULATION_SIMULATIONFACTORY_H
 #define BORNAGAIN_CORE_SIMULATION_SIMULATIONFACTORY_H
 
@@ -33,3 +34,4 @@ public:
 };
 
 #endif // BORNAGAIN_CORE_SIMULATION_SIMULATIONFACTORY_H
+#endif // USER_API
diff --git a/Core/Simulation/SpecularSimulation.cpp b/Core/Simulation/SpecularSimulation.cpp
index 02af3b78ceb9a2bed4001628a0db6494226fd939..aaedd6f7dc4be85577122e8b8bdbf4a80d68dcac 100644
--- a/Core/Simulation/SpecularSimulation.cpp
+++ b/Core/Simulation/SpecularSimulation.cpp
@@ -3,7 +3,7 @@
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
 //! @file      Core/Simulation/SpecularSimulation.cpp
-//! @brief     Implements class OffSpecSimulation.
+//! @brief     Implements class OffSpecularSimulation.
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
diff --git a/Core/Simulation/SpecularSimulation.h b/Core/Simulation/SpecularSimulation.h
index 9581348329bf0966b8cc57e7445b62972439f83e..3d29924121c42abe2948ee6a1b2e7893541dcb4b 100644
--- a/Core/Simulation/SpecularSimulation.h
+++ b/Core/Simulation/SpecularSimulation.h
@@ -61,7 +61,7 @@ public:
 #ifndef SWIG
     //! Returns internal data handler
     const ISpecularScan* dataHandler() const { return m_scan.get(); }
-#endif // SWIG
+#endif // USER_API
 
 private:
     SpecularSimulation(const SpecularSimulation& other); // used by clone()
diff --git a/Core/Simulation/StandardSimulations.cpp b/Core/Simulation/StandardSimulations.cpp
index 649dc1301bc3b01f47d77d7dd06cc1dc031dc1ce..2c564d519817fa3ff7196c3f5e54ca78498e9b0c 100644
--- a/Core/Simulation/StandardSimulations.cpp
+++ b/Core/Simulation/StandardSimulations.cpp
@@ -19,7 +19,7 @@
 #include "Core/Scan/QSpecScan.h"
 #include "Core/Simulation/DepthProbeSimulation.h"
 #include "Core/Simulation/GISASSimulation.h"
-#include "Core/Simulation/OffSpecSimulation.h"
+#include "Core/Simulation/OffSpecularSimulation.h"
 #include "Core/Simulation/SpecularSimulation.h"
 #include "Device/Beam/FootprintGauss.h"
 #include "Device/Beam/FootprintSquare.h"
@@ -58,7 +58,7 @@ GISASSimulation* StandardSimulations::BasicGISAS() {
 GISASSimulation* StandardSimulations::BasicGISAS00() {
     GISASSimulation* result = BasicGISAS();
     kvector_t zplus(0.0, 0.0, 1.0);
-    result->setBeamPolarization(zplus);
+    result->beam().setPolarization(zplus);
     result->setAnalyzerProperties(zplus, 1.0, 0.5);
     return result;
 }
@@ -68,7 +68,7 @@ GISASSimulation* StandardSimulations::BasicGISAS00() {
 GISASSimulation* StandardSimulations::BasicPolarizedGISAS() {
     GISASSimulation* result = BasicGISAS();
     kvector_t zplus(0.0, 0.0, 1.0);
-    result->setBeamPolarization(zplus);
+    result->beam().setPolarization(zplus);
     result->setAnalyzerProperties(zplus, -1.0, 0.5);
     return result;
 }
@@ -122,7 +122,7 @@ GISASSimulation* StandardSimulations::GISASWithMasks() {
     result->setDetectorParameters(50, -1.0 * Units::deg, 1.0 * Units::deg, 50, 0.0 * Units::deg,
                                   2.0 * Units::deg);
     result->setBeamParameters(1.0 * Units::angstrom, 0.2 * Units::deg, 0.0 * Units::deg);
-    result->setBeamIntensity(1e+7);
+    result->beam().setIntensity(1e+7);
 
     result->maskAll();
     // pacman
@@ -163,7 +163,7 @@ GISASSimulation* StandardSimulations::MiniGISASPolarizationPP() {
     kvector_t analyzer_dir(0.0, 0.0, 1.0);
     kvector_t beampol(0.0, 0.0, 1.0);
 
-    result->setBeamPolarization(beampol);
+    result->beam().setPolarization(beampol);
     result->setAnalyzerProperties(analyzer_dir, 1.0, 0.5);
     return result;
 }
@@ -174,7 +174,7 @@ GISASSimulation* StandardSimulations::MiniGISASPolarizationPM() {
     kvector_t analyzer_dir(0.0, 0.0, -1.0);
     kvector_t beampol(0.0, 0.0, 1.0);
 
-    result->setBeamPolarization(beampol);
+    result->beam().setPolarization(beampol);
     result->setAnalyzerProperties(analyzer_dir, 1.0, 0.5);
     return result;
 }
@@ -185,7 +185,7 @@ GISASSimulation* StandardSimulations::MiniGISASPolarizationMP() {
     kvector_t analyzer_dir(0.0, 0.0, 1.0);
     kvector_t beampol(0.0, 0.0, -1.0);
 
-    result->setBeamPolarization(beampol);
+    result->beam().setPolarization(beampol);
     result->setAnalyzerProperties(analyzer_dir, 1.0, 0.5);
     return result;
 }
@@ -196,7 +196,7 @@ GISASSimulation* StandardSimulations::MiniGISASPolarizationMM() {
     kvector_t analyzer_dir(0.0, 0.0, -1.0);
     kvector_t beampol(0.0, 0.0, -1.0);
 
-    result->setBeamPolarization(beampol);
+    result->beam().setPolarization(beampol);
     result->setAnalyzerProperties(analyzer_dir, 1.0, 0.5);
     return result;
 }
@@ -227,7 +227,7 @@ GISASSimulation* StandardSimulations::MaxiGISAS() {
 GISASSimulation* StandardSimulations::MaxiGISAS00() {
     GISASSimulation* result = MaxiGISAS();
     kvector_t zplus(0.0, 0.0, 1.0);
-    result->setBeamPolarization(zplus);
+    result->beam().setPolarization(zplus);
     result->setAnalyzerProperties(zplus, 1.0, 0.5);
     return result;
 }
@@ -370,7 +370,7 @@ GISASSimulation* StandardSimulations::ExtraLongWavelengthGISAS() {
                                       2.0 * Units::deg);
 
     simulation->setBeamParameters(13.52 * Units::nm, 0.2 * Units::deg, 0.0 * Units::deg);
-    simulation->setBeamIntensity(1.0e+08);
+    simulation->beam().setIntensity(1.0e+08);
     simulation->getOptions().setIncludeSpecular(true);
     return simulation;
 }
@@ -495,65 +495,65 @@ SpecularSimulation* StandardSimulations::TOFRWithPointwiseResolution() {
 // ------------ polarized specular ----------------
 SpecularSimulation* StandardSimulations::BasicSpecularPP() {
     auto* simulation = BasicSpecular();
-    simulation->setBeamPolarization({0.0, 1.0, 0.0});
+    simulation->beam().setPolarization({0.0, 1.0, 0.0});
     simulation->setAnalyzerProperties({0.0, 1.0, 0.0}, 1.0, 0.5);
     return simulation;
 }
 
 SpecularSimulation* StandardSimulations::BasicSpecularPM() {
     auto* simulation = BasicSpecular();
-    simulation->setBeamPolarization({0.0, 1.0, 0.0});
+    simulation->beam().setPolarization({0.0, 1.0, 0.0});
     simulation->setAnalyzerProperties({0.0, -1.0, 0.0}, 1.0, 0.5);
     return simulation;
 }
 
 SpecularSimulation* StandardSimulations::BasicSpecularMP() {
     auto* simulation = BasicSpecular();
-    simulation->setBeamPolarization({0.0, -1.0, 0.0});
+    simulation->beam().setPolarization({0.0, -1.0, 0.0});
     simulation->setAnalyzerProperties({0.0, 1.0, 0.0}, 1.0, 0.5);
     return simulation;
 }
 
 SpecularSimulation* StandardSimulations::BasicSpecularMM() {
     auto* simulation = BasicSpecular();
-    simulation->setBeamPolarization({0.0, -1.0, 0.0});
+    simulation->beam().setPolarization({0.0, -1.0, 0.0});
     simulation->setAnalyzerProperties({0.0, -1.0, 0.0}, 1.0, 0.5);
     return simulation;
 }
 
 SpecularSimulation* StandardSimulations::BasicSpecularQPP() {
     auto* simulation = BasicSpecularQ();
-    simulation->setBeamPolarization({0.0, 1.0, 0.0});
+    simulation->beam().setPolarization({0.0, 1.0, 0.0});
     simulation->setAnalyzerProperties({0.0, 1.0, 0.0}, 1.0, 0.5);
     return simulation;
 }
 
 SpecularSimulation* StandardSimulations::BasicSpecularQMM() {
     auto* simulation = BasicSpecularQ();
-    simulation->setBeamPolarization({0.0, -1.0, 0.0});
+    simulation->beam().setPolarization({0.0, -1.0, 0.0});
     simulation->setAnalyzerProperties({0.0, -1.0, 0.0}, 1.0, 0.5);
     return simulation;
 }
 
 SpecularSimulation* StandardSimulations::BasicSpecularQPM() {
     auto* simulation = BasicSpecularQ();
-    simulation->setBeamPolarization({0.0, 1.0, 0.0});
+    simulation->beam().setPolarization({0.0, 1.0, 0.0});
     simulation->setAnalyzerProperties({0.0, -1.0, 0.0}, 1.0, 0.5);
     return simulation;
 }
 
 SpecularSimulation* StandardSimulations::BasicSpecularQMP() {
     auto* simulation = BasicSpecularQ();
-    simulation->setBeamPolarization({0.0, -1.0, 0.0});
+    simulation->beam().setPolarization({0.0, -1.0, 0.0});
     simulation->setAnalyzerProperties({0.0, 1.0, 0.0}, 1.0, 0.5);
     return simulation;
 }
 
 // ----------------------- off-spec simulations ------------------
 
-// OffSpec simulation used in ResonatorOffSpecSetup.py
-OffSpecSimulation* StandardSimulations::MiniOffSpec() {
-    auto* result = new OffSpecSimulation;
+// OffSpecular simulation used in ResonatorOffSpecularSetup.py
+OffSpecularSimulation* StandardSimulations::MiniOffSpecular() {
+    auto* result = new OffSpecularSimulation;
 
     const int n_alpha(19);
     const double alpha_min(0.0 * Units::deg);
@@ -571,7 +571,7 @@ OffSpecSimulation* StandardSimulations::MiniOffSpec() {
     FixedBinAxis alpha_i_axis("alpha_i", n_scan_points, alpha_i_min, alpha_i_max);
     result->setBeamParameters(5.0 * Units::angstrom, alpha_i_axis, 0.0);
 
-    result->setBeamIntensity(1e9);
+    result->beam().setIntensity(1e9);
     result->getOptions().setIncludeSpecular(true);
 
     return result;
@@ -601,6 +601,6 @@ GISASSimulation* StandardSimulations::MiniGISASFit() {
     result->setDetectorParameters(25, -2.0 * Units::deg, 2.0 * Units::deg, 25, 0.0 * Units::deg,
                                   2.0 * Units::deg);
     result->setBeamParameters(1.0 * Units::angstrom, 0.2 * Units::deg, 0.0 * Units::deg);
-    result->setBeamIntensity(1e6);
+    result->beam().setIntensity(1e6);
     return result;
 }
diff --git a/Core/Simulation/StandardSimulations.h b/Core/Simulation/StandardSimulations.h
index 630c81778ff62862ab3673332f39421fead0c30a..03d7720bed635e4a317a746430b45ab3d3e73817 100644
--- a/Core/Simulation/StandardSimulations.h
+++ b/Core/Simulation/StandardSimulations.h
@@ -16,13 +16,14 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_SIMULATION_STANDARDSIMULATIONS_H
 #define BORNAGAIN_CORE_SIMULATION_STANDARDSIMULATIONS_H
 
 class DepthProbeSimulation;
 class GISASSimulation;
 class SpecularSimulation;
-class OffSpecSimulation;
+class OffSpecularSimulation;
 
 //! Standard pre-defined simulations.
 
@@ -79,8 +80,8 @@ SpecularSimulation* BasicSpecularQMM();
 SpecularSimulation* BasicSpecularQPM();
 SpecularSimulation* BasicSpecularQMP();
 
-// OffSpec simulations
-OffSpecSimulation* MiniOffSpec();
+// OffSpecular simulations
+OffSpecularSimulation* MiniOffSpecular();
 
 // Depth probe simulations
 DepthProbeSimulation* BasicDepthProbe();
@@ -88,3 +89,4 @@ DepthProbeSimulation* BasicDepthProbe();
 } // namespace StandardSimulations
 
 #endif // BORNAGAIN_CORE_SIMULATION_STANDARDSIMULATIONS_H
+#endif // USER_API
diff --git a/Core/Simulation/UnitConverterUtils.cpp b/Core/Simulation/UnitConverterUtils.cpp
index 21439b45ea1844d72679ac38832cafd11be8e7a9..b6fb8e9438ca3e7fa5b226e462c45c5fb3fde03c 100644
--- a/Core/Simulation/UnitConverterUtils.cpp
+++ b/Core/Simulation/UnitConverterUtils.cpp
@@ -16,7 +16,7 @@
 #include "Core/Scan/UnitConverter1D.h"
 #include "Core/Simulation/DepthProbeSimulation.h"
 #include "Core/Simulation/GISASSimulation.h"
-#include "Core/Simulation/OffSpecSimulation.h"
+#include "Core/Simulation/OffSpecularSimulation.h"
 #include "Core/Simulation/SpecularSimulation.h"
 #include "Device/Detector/RectangularDetector.h"
 #include "Device/Detector/SimpleUnitConverters.h"
@@ -53,7 +53,7 @@ std::unique_ptr<IUnitConverter> UnitConverterUtils::createConverter(const ISimul
     } else if (auto probe = dynamic_cast<const DepthProbeSimulation*>(&simulation)) {
         return probe->createUnitConverter();
 
-    } else if (auto off_spec = dynamic_cast<const OffSpecSimulation*>(&simulation)) {
+    } else if (auto off_spec = dynamic_cast<const OffSpecularSimulation*>(&simulation)) {
         return off_spec->createUnitConverter();
 
     } else {
diff --git a/Core/Simulation/UnitConverterUtils.h b/Core/Simulation/UnitConverterUtils.h
index bf57ad4ee8dc8b14f33981dc1b2c392f5ba13c73..9c5666e3a5bba9f625749f220cd013ef0ca30073 100644
--- a/Core/Simulation/UnitConverterUtils.h
+++ b/Core/Simulation/UnitConverterUtils.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_SIMULATION_UNITCONVERTERUTILS_H
 #define BORNAGAIN_CORE_SIMULATION_UNITCONVERTERUTILS_H
 
@@ -41,3 +42,4 @@ std::unique_ptr<IUnitConverter> createConverter(const ISimulation& simulation);
 } // namespace UnitConverterUtils
 
 #endif // BORNAGAIN_CORE_SIMULATION_UNITCONVERTERUTILS_H
+#endif // USER_API
diff --git a/Core/Term/DepthProbeComputationTerm.h b/Core/Term/DepthProbeComputationTerm.h
index ff548e1cc721993b51cb5315d5383876dd2cdf1c..caaefd9a516f2ffbe917d195f351139e2984968e 100644
--- a/Core/Term/DepthProbeComputationTerm.h
+++ b/Core/Term/DepthProbeComputationTerm.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_TERM_DEPTHPROBECOMPUTATIONTERM_H
 #define BORNAGAIN_CORE_TERM_DEPTHPROBECOMPUTATIONTERM_H
 
@@ -41,3 +42,4 @@ private:
 };
 
 #endif // BORNAGAIN_CORE_TERM_DEPTHPROBECOMPUTATIONTERM_H
+#endif // USER_API
diff --git a/Core/Term/SpecularComputationTerm.h b/Core/Term/SpecularComputationTerm.h
index 092be278b91263c4b7f56d778b49dab8900ebf6a..85faa86356948a1ce457a1437e2d9c0156c103c3 100644
--- a/Core/Term/SpecularComputationTerm.h
+++ b/Core/Term/SpecularComputationTerm.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_TERM_SPECULARCOMPUTATIONTERM_H
 #define BORNAGAIN_CORE_TERM_SPECULARCOMPUTATIONTERM_H
 
@@ -85,3 +86,4 @@ private:
 };
 
 #endif // BORNAGAIN_CORE_TERM_SPECULARCOMPUTATIONTERM_H
+#endif // USER_API
diff --git a/Device/Beam/Beam.h b/Device/Beam/Beam.h
index c07bdb1a75985c9bf16496511f08c655d40a0718..2911d5d9ca887e2ea6c1db57935682925a70c336 100644
--- a/Device/Beam/Beam.h
+++ b/Device/Beam/Beam.h
@@ -21,7 +21,7 @@
 
 class IFootprintFactor;
 
-//! Beam defined by wavelength, direction and intensity.
+//! An incident neutron or x-ray beam.
 //! @ingroup beam
 
 class Beam : public INode {
diff --git a/Device/Beam/FootprintGauss.h b/Device/Beam/FootprintGauss.h
index 1a945c109f447556c680b1dc1c3159d5534e56eb..cb557cb2d0c928a0ae3437c377e7ac2a6c8b0afd 100644
--- a/Device/Beam/FootprintGauss.h
+++ b/Device/Beam/FootprintGauss.h
@@ -17,9 +17,9 @@
 
 #include "Device/Beam/IFootprintFactor.h"
 
-//! Calculates footprint coefficient for a gaussian beam
-//! Beam width is interpreted as the full width on the level
-//! of \f[ \exp{-1/2} \f] from the peak intensity.
+//! Gaussian beam footprint.
+//!
+//! Beam width is the full width at half maximum.
 //! @ingroup beam
 
 class FootprintGauss : public IFootprintFactor {
diff --git a/Device/Beam/FootprintSquare.h b/Device/Beam/FootprintSquare.h
index 84922298f776a40f0e0cf2007b6599c256a126ae..d466decfd5e335e1f032f89d5cbbc16984796fa8 100644
--- a/Device/Beam/FootprintSquare.h
+++ b/Device/Beam/FootprintSquare.h
@@ -17,7 +17,7 @@
 
 #include "Device/Beam/IFootprintFactor.h"
 
-//! Calculates footprint coefficient for a square beam
+//! Rectangular beam footprint.
 //! @ingroup beam
 
 class FootprintSquare : public IFootprintFactor {
diff --git a/Device/Beam/IFootprintFactor.h b/Device/Beam/IFootprintFactor.h
index 6196537593f678c2bf5710cf3b1589cddc679453..8e7741039ae5619e3a702a233deab68059935cf2 100644
--- a/Device/Beam/IFootprintFactor.h
+++ b/Device/Beam/IFootprintFactor.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_BEAM_IFOOTPRINTFACTOR_H
 #define BORNAGAIN_DEVICE_BEAM_IFOOTPRINTFACTOR_H
 
@@ -48,3 +49,4 @@ private:
 };
 
 #endif // BORNAGAIN_DEVICE_BEAM_IFOOTPRINTFACTOR_H
+#endif // USER_API
diff --git a/Device/Intensity/ArrayUtils.h b/Device/Data/ArrayUtils.h
similarity index 94%
rename from Device/Intensity/ArrayUtils.h
rename to Device/Data/ArrayUtils.h
index 105daba33698de04f8cf001ad82f72101016a835..f433665cae9a06153ce850940822a9b452ec2b03 100644
--- a/Device/Intensity/ArrayUtils.h
+++ b/Device/Data/ArrayUtils.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Device/Intensity/ArrayUtils.h
+//! @file      Device/Data/ArrayUtils.h
 //! @brief     Defines various functions to interact from numpy on Python side
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_INTENSITY_ARRAYUTILS_H
 #define BORNAGAIN_DEVICE_INTENSITY_ARRAYUTILS_H
 
@@ -24,9 +25,10 @@
 #include <stdexcept>
 #include <vector>
 
-//! Array and Numpy utility functions getShape, createNumpyArray.
+//! Array utility functions getShape
 
 namespace ArrayUtils {
+
 //! Returns shape nrows, ncols of 2D array.
 template <class T> std::pair<size_t, size_t> getShape(const T& data);
 
@@ -69,10 +71,6 @@ template <class T> CreateDataImpl::ReturnType<T> createData(const T& vec) {
     return CreateDataImpl::createDataImpl(vec);
 }
 
-#ifdef BORNAGAIN_PYTHON
-PyObject* createNumpyArray(const std::vector<double>& data);
-#endif // BORNAGAIN_PYTHON
-
 //! Creates 1D vector from OutputData.
 template <class T> decltype(auto) createVector1D(const T& data);
 
@@ -81,6 +79,11 @@ template <class T> decltype(auto) createVector2D(const T& data);
 
 } // namespace ArrayUtils
 
+
+//  ************************************************************************************************
+//  implementation
+//  ************************************************************************************************
+
 template <class T>
 std::unique_ptr<OutputData<T>>
 ArrayUtils::CreateDataImpl::createDataImpl(const std::vector<T>& vec) {
@@ -160,3 +163,4 @@ template <class T> decltype(auto) ArrayUtils::createVector2D(const T& data) {
 }
 
 #endif // BORNAGAIN_DEVICE_INTENSITY_ARRAYUTILS_H
+#endif // USER_API
diff --git a/Device/Data/CumulativeValue.h b/Device/Data/CumulativeValue.h
index c669e56267ed1b43f01cc7bc250af535d3fd17cd..e5ae038a171ad694af7adde6b4dd6d07fd46d6cf 100644
--- a/Device/Data/CumulativeValue.h
+++ b/Device/Data/CumulativeValue.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_DATA_CUMULATIVEVALUE_H
 #define BORNAGAIN_DEVICE_DATA_CUMULATIVEVALUE_H
 
@@ -47,3 +48,4 @@ bool operator<(const CumulativeValue& lhs, const CumulativeValue& rhs);
 bool operator>(const CumulativeValue& lhs, const CumulativeValue& rhs);
 
 #endif // BORNAGAIN_DEVICE_DATA_CUMULATIVEVALUE_H
+#endif // USER_API
diff --git a/Device/Instrument/IntensityDataFunctions.cpp b/Device/Data/DataUtils.cpp
similarity index 63%
rename from Device/Instrument/IntensityDataFunctions.cpp
rename to Device/Data/DataUtils.cpp
index bded700dbeac7d1ee7b3d0654d212f0c1579c926..57947965f602c8794ad05611b4062f861fed8349 100644
--- a/Device/Instrument/IntensityDataFunctions.cpp
+++ b/Device/Data/DataUtils.cpp
@@ -2,8 +2,8 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Device/Instrument/IntensityDataFunctions.cpp
-//! @brief     Implement class IntensityDataFunctions.
+//! @file      Device/Data/DataUtils.cpp
+//! @brief     Implements namespace DataUtils.
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -12,60 +12,43 @@
 //
 //  ************************************************************************************************
 
-#include "Device/Instrument/IntensityDataFunctions.h"
+#include "Device/Data/DataUtils.h"
+#include "Device/Data/ArrayUtils.h"
+#include "Base/Math/FourierTransform.h"
 #include "Base/Math/Numeric.h"
-#include "Device/Histo/IHistogram.h"
-#include "Device/Histo/SimulationResult.h"
-#include "Device/Instrument/FourierTransform.h"
-#include "Device/Instrument/Instrument.h"
-#include "Device/Intensity/ArrayUtils.h"
-#include "Device/Resolution/ConvolutionDetectorResolution.h"
-#include <cmath>
 #include <iostream>
 
-//! Returns sum of relative differences between each pair of elements:
-//! (a, b) -> 2*abs(a - b)/(|a| + |b|)      ( and zero if  a=b=0 within epsilon )
-double IntensityDataFunctions::RelativeDifference(const SimulationResult& dat,
-                                                  const SimulationResult& ref) {
-    if (dat.size() != ref.size())
-        throw std::runtime_error("Error in IntensityDataFunctions::RelativeDifference: "
-                                 "different number of elements");
-    if (dat.empty())
-        return 0.0;
-    double sum_of_diff = 0.0;
-    for (size_t i = 0; i < dat.size(); ++i) {
-        sum_of_diff += Numeric::GetRelativeDifference(dat[i], ref[i]);
-    }
-    return sum_of_diff / dat.size();
+namespace {
+
+std::vector<std::vector<double>> FT2DArray(const std::vector<std::vector<double>>& signal) {
+    FourierTransform ft;
+    std::vector<std::vector<double>> ret;
+    ft.fft(signal, ret);
+    ft.fftshift(ret); // low frequency to center of array
+    return ret;
 }
 
+} // namespace
+
 //! Returns relative difference between two data sets sum(dat[i] - ref[i])/ref[i]).
-double IntensityDataFunctions::getRelativeDifference(const OutputData<double>& dat,
-                                                     const OutputData<double>& ref) {
+double DataUtils::relativeDataDifference(const OutputData<double>& dat,
+                                         const OutputData<double>& ref) {
     if (!dat.hasSameDimensions(ref))
-        throw std::runtime_error("IntensityDataFunctions::getRelativeDifference() -> "
-                                 "Error. Different dimensions of data and reference.");
+        throw std::runtime_error("OutputData dimension differs from reference");
 
     double diff = 0.0;
     for (size_t i = 0; i < dat.getAllocatedSize(); ++i)
         diff += Numeric::GetRelativeDifference(dat[i], ref[i]);
     diff /= dat.getAllocatedSize();
-
     if (std::isnan(diff))
         throw std::runtime_error("diff=NaN!");
     return diff;
 }
 
-double IntensityDataFunctions::getRelativeDifference(const IHistogram& dat, const IHistogram& ref) {
-    return getRelativeDifference(*std::unique_ptr<OutputData<double>>(dat.getData().meanValues()),
-                                 *std::unique_ptr<OutputData<double>>(ref.getData().meanValues()));
-}
-
 //! Returns true is relative difference is below threshold; prints informative output
-bool IntensityDataFunctions::checkRelativeDifference(const OutputData<double>& dat,
-                                                     const OutputData<double>& ref,
-                                                     const double threshold) {
-    const double diff = getRelativeDifference(dat, ref);
+bool DataUtils::checkRelativeDifference(const OutputData<double>& dat,
+                                        const OutputData<double>& ref, const double threshold) {
+    const double diff = relativeDataDifference(dat, ref);
     if (diff > threshold) {
         std::cerr << "FAILED: relative deviation of dat from ref is " << diff
                   << ", above given threshold " << threshold << "\n";
@@ -80,10 +63,10 @@ bool IntensityDataFunctions::checkRelativeDifference(const OutputData<double>& d
 }
 
 std::unique_ptr<OutputData<double>>
-IntensityDataFunctions::createRelativeDifferenceData(const OutputData<double>& data,
-                                                     const OutputData<double>& reference) {
+DataUtils::createRelativeDifferenceData(const OutputData<double>& data,
+                                        const OutputData<double>& reference) {
     if (!data.hasSameDimensions(reference))
-        throw std::runtime_error("IntensityDataFunctions::createRelativeDifferenceData() -> "
+        throw std::runtime_error("DataUtils::createRelativeDifferenceData() -> "
                                  "Error. Different dimensions of data and reference.");
     std::unique_ptr<OutputData<double>> result(reference.clone());
     for (size_t i = 0; i < result->getAllocatedSize(); ++i)
@@ -92,9 +75,9 @@ IntensityDataFunctions::createRelativeDifferenceData(const OutputData<double>& d
 }
 
 std::unique_ptr<OutputData<double>>
-IntensityDataFunctions::createRearrangedDataSet(const OutputData<double>& data, int n) {
+DataUtils::createRearrangedDataSet(const OutputData<double>& data, int n) {
     if (data.rank() != 2)
-        throw std::runtime_error("IntensityDataFunctions::rotateDataByN90Deg()"
+        throw std::runtime_error("DataUtils::rotateDataByN90Deg()"
                                  " -> Error! Works only on two-dimensional data");
     n = (4 + n % 4) % 4;
     if (n == 0)
@@ -137,10 +120,10 @@ IntensityDataFunctions::createRearrangedDataSet(const OutputData<double>& data,
 }
 
 std::unique_ptr<OutputData<double>>
-IntensityDataFunctions::createClippedDataSet(const OutputData<double>& origin, double x1, double y1,
-                                             double x2, double y2) {
+DataUtils::createClippedDataSet(const OutputData<double>& origin, double x1, double y1, double x2,
+                                double y2) {
     if (origin.rank() != 2)
-        throw std::runtime_error("IntensityDataFunctions::createClippedData()"
+        throw std::runtime_error("DataUtils::createClippedData()"
                                  " -> Error! Works only on two-dimensional data");
 
     std::unique_ptr<OutputData<double>> result(new OutputData<double>);
@@ -177,14 +160,14 @@ IntensityDataFunctions::createClippedDataSet(const OutputData<double>& origin, d
 // (center of non-existing bin #-1).
 // Used for Mask conversion.
 
-double IntensityDataFunctions::coordinateToBinf(double coordinate, const IAxis& axis) {
+double DataUtils::coordinateToBinf(double coordinate, const IAxis& axis) {
     size_t index = axis.findClosestIndex(coordinate);
     Bin1D bin = axis.bin(index);
     double f = (coordinate - bin.m_lower) / bin.binSize();
     return static_cast<double>(index) + f;
 }
 
-double IntensityDataFunctions::coordinateFromBinf(double value, const IAxis& axis) {
+double DataUtils::coordinateFromBinf(double value, const IAxis& axis) {
     int index = static_cast<int>(value);
 
     double result(0);
@@ -202,22 +185,20 @@ double IntensityDataFunctions::coordinateFromBinf(double value, const IAxis& axi
     return result;
 }
 
-void IntensityDataFunctions::coordinateToBinf(double& x, double& y,
-                                              const OutputData<double>& data) {
+void DataUtils::coordinateToBinf(double& x, double& y, const OutputData<double>& data) {
     x = coordinateToBinf(x, data.axis(0));
     y = coordinateToBinf(y, data.axis(1));
 }
 
-void IntensityDataFunctions::coordinateFromBinf(double& x, double& y,
-                                                const OutputData<double>& data) {
+void DataUtils::coordinateFromBinf(double& x, double& y, const OutputData<double>& data) {
     x = coordinateFromBinf(x, data.axis(0));
     y = coordinateFromBinf(y, data.axis(1));
 }
 
 std::vector<std::vector<double>>
-IntensityDataFunctions::create2DArrayfromOutputData(const OutputData<double>& data) {
+DataUtils::create2DArrayfromOutputData(const OutputData<double>& data) {
     if (data.rank() != 2)
-        throw std::runtime_error("IntensityDataFunctions::create2DArrayfromOutputData() -> "
+        throw std::runtime_error("DataUtils::create2DArrayfromOutputData() -> "
                                  "Error! Works only on two-dimensional data");
 
     std::vector<std::vector<double>> array_2d;
@@ -239,19 +220,8 @@ IntensityDataFunctions::create2DArrayfromOutputData(const OutputData<double>& da
     return array_2d;
 }
 
-std::vector<std::vector<double>>
-IntensityDataFunctions::FT2DArray(const std::vector<std::vector<double>>& signal) {
-    FourierTransform ft;
-    std::vector<std::vector<double>> fft_array;
-    ft.fft(signal, fft_array);
-    // shifting low frequency to center of array
-    ft.fftshift(fft_array);
-
-    return fft_array;
-}
-
-std::unique_ptr<OutputData<double>> IntensityDataFunctions::createOutputDatafrom2DArray(
-    const std::vector<std::vector<double>>& array_2d) {
+std::unique_ptr<OutputData<double>>
+DataUtils::createOutputDatafrom2DArray(const std::vector<std::vector<double>>& array_2d) {
     std::unique_ptr<OutputData<double>> result(new OutputData<double>);
     size_t nrows = array_2d.size();
     size_t ncols = array_2d[0].size();
@@ -271,9 +241,17 @@ std::unique_ptr<OutputData<double>> IntensityDataFunctions::createOutputDatafrom
     return result;
 }
 
-std::unique_ptr<OutputData<double>>
-IntensityDataFunctions::createFFT(const OutputData<double>& data) {
-    auto array_2d = IntensityDataFunctions::create2DArrayfromOutputData(data);
-    auto fft_array_2d = IntensityDataFunctions::FT2DArray(array_2d);
-    return IntensityDataFunctions::createOutputDatafrom2DArray(fft_array_2d);
+std::unique_ptr<OutputData<double>> DataUtils::createFFT(const OutputData<double>& data) {
+    auto array_2d = DataUtils::create2DArrayfromOutputData(data);
+    auto fft_array_2d = FT2DArray(array_2d);
+    return DataUtils::createOutputDatafrom2DArray(fft_array_2d);
+}
+
+OutputData<double>* DataUtils::importArrayToOutputData(const std::vector<double>& vec) {
+    return ArrayUtils::createData(vec).release();
+}
+
+OutputData<double>*
+DataUtils::importArrayToOutputData(const std::vector<std::vector<double>>& vec) {
+    return ArrayUtils::createData(vec).release();
 }
diff --git a/Device/Instrument/IntensityDataFunctions.h b/Device/Data/DataUtils.h
similarity index 71%
rename from Device/Instrument/IntensityDataFunctions.h
rename to Device/Data/DataUtils.h
index f81986a4ff04f27d1c952b354645cec64a7cc953..b519141ff3c9620338d3daa32a1315b36f458e45 100644
--- a/Device/Instrument/IntensityDataFunctions.h
+++ b/Device/Data/DataUtils.h
@@ -2,8 +2,8 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Device/Instrument/IntensityDataFunctions.h
-//! @brief     Defines class IntensityDataFunctions.
+//! @file      Device/Data/DataUtils.h
+//! @brief     Defines namespace DataUtils.
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -12,33 +12,21 @@
 //
 //  ************************************************************************************************
 
-#ifndef BORNAGAIN_DEVICE_INSTRUMENT_INTENSITYDATAFUNCTIONS_H
-#define BORNAGAIN_DEVICE_INSTRUMENT_INTENSITYDATAFUNCTIONS_H
+#ifndef BORNAGAIN_DEVICE_DATA_DATAUTILS_H
+#define BORNAGAIN_DEVICE_DATA_DATAUTILS_H
 
 #include "Device/Data/OutputData.h"
 #include <memory>
 
-class IHistogram;
-class SimulationResult;
-class ISimulation;
-
-//! Functions to work with intensity data.
-//! @ingroup tools
-
-namespace IntensityDataFunctions {
-//! Returns sum of relative differences between each pair of elements:
-//! (a, b) -> 2*abs(a - b)/(a + b)      ( and zero if  a-b=0 )
-double RelativeDifference(const SimulationResult& dat, const SimulationResult& ref);
+namespace DataUtils {
 
 //! Returns relative difference between two data sets sum(dat[i] - ref[i])/ref[i]).
-double getRelativeDifference(const OutputData<double>& dat, const OutputData<double>& ref);
+double relativeDataDifference(const OutputData<double>& dat, const OutputData<double>& ref);
 
 //! Returns true is relative difference is below threshold; prints informative output
 bool checkRelativeDifference(const OutputData<double>& dat, const OutputData<double>& ref,
                              const double threshold);
 
-double getRelativeDifference(const IHistogram& dat, const IHistogram& ref);
-
 //! Transforms coordinate on axis into the bin-fraction-coordinate.
 double coordinateToBinf(double coordinate, const IAxis& axis);
 
@@ -54,8 +42,10 @@ void coordinateFromBinf(double& x, double& y, const OutputData<double>& data);
 //! Creates a vector of vectors of double (2D Array) from OutputData.
 std::vector<std::vector<double>> create2DArrayfromOutputData(const OutputData<double>& data);
 
-//! Creates a Fourier Transform of a 2D Array (vector of vectors).
-std::vector<std::vector<double>> FT2DArray(const std::vector<std::vector<double>>& signal);
+//! Reads 1D array of doubles to Python, for use in persistence test
+OutputData<double>* importArrayToOutputData(const std::vector<double>& vec);
+//! Reads 2D array of doubles to Python, for use in persistence test
+OutputData<double>* importArrayToOutputData(const std::vector<std::vector<double>>& vec);
 
 #ifndef SWIG
 
@@ -79,8 +69,8 @@ createOutputDatafrom2DArray(const std::vector<std::vector<double>>& array_2d);
 //! Creates Fourier Transform (OutputData format) of intensity map (OutputData format).
 std::unique_ptr<OutputData<double>> createFFT(const OutputData<double>& data);
 
-#endif // SWIG
+#endif // USER_API
 
-}; // namespace IntensityDataFunctions
+} // namespace DataUtils
 
-#endif // BORNAGAIN_DEVICE_INSTRUMENT_INTENSITYDATAFUNCTIONS_H
+#endif // BORNAGAIN_DEVICE_DATA_DATAUTILS_H
diff --git a/Device/Data/LLData.h b/Device/Data/LLData.h
index a3b84ea5f14b18e0f42e093d5e5e3c007db1c171..72f54a1ec6bd379856205c88a1a70fed67279c3b 100644
--- a/Device/Data/LLData.h
+++ b/Device/Data/LLData.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_DATA_LLDATA_H
 #define BORNAGAIN_DEVICE_DATA_LLDATA_H
 
@@ -285,3 +286,4 @@ template <class T> bool HaveSameDimensions(const LLData<T>& left, const LLData<T
 }
 
 #endif // BORNAGAIN_DEVICE_DATA_LLDATA_H
+#endif // USER_API
diff --git a/Device/Data/OutputData.cpp b/Device/Data/OutputData.cpp
index 9043406c1d214af77073189eb7495ba36e4e8cc5..c7b2e023a5cd228a07f038b275e500686c07fd9c 100644
--- a/Device/Data/OutputData.cpp
+++ b/Device/Data/OutputData.cpp
@@ -17,7 +17,7 @@
 
 #ifdef BORNAGAIN_PYTHON
 
-#include "Base/Py/PythonCore.h"
+#include "Base/Py/PyCore.h"
 
 template <> PyObject* OutputData<double>::getArray() const {
     std::vector<size_t> dimensions;
diff --git a/Device/Data/OutputData.h b/Device/Data/OutputData.h
index 5aaba72399e973d9a6a9a68f37aa7a812511fa84..ab60d1e28427c6ccae92e539f2a03e8d95c3c55f 100644
--- a/Device/Data/OutputData.h
+++ b/Device/Data/OutputData.h
@@ -3,7 +3,7 @@
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
 //! @file      Device/Data/OutputData.h
-//! @brief     Defines and implements template class OutputData.
+//! @brief     Defines and implements templated class OutputData.
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -26,7 +26,7 @@
 
 using std::size_t;
 
-//! Template class to store data of any type in multi-dimensional space.
+//! Templated class to store data of type double or CumulativeValue in multi-dimensional space.
 //! @ingroup tools
 
 template <class T> class OutputData {
@@ -49,9 +49,6 @@ public:
     //! returns axis with given serial number
     const IAxis& axis(size_t serial_number) const;
 
-    //! returns axis with given name
-    const IAxis& axis(const std::string& axis_name) const;
-
     // retrieve basic info
 
     //! Returns number of dimensions.
@@ -303,10 +300,6 @@ template <class T> const IAxis& OutputData<T>::axis(size_t serial_number) const
     return *m_value_axes[serial_number];
 }
 
-template <class T> const IAxis& OutputData<T>::axis(const std::string& axis_name) const {
-    return axis(getAxisIndex(axis_name));
-}
-
 template <class T> inline std::vector<size_t> OutputData<T>::getAllSizes() const {
     ASSERT(m_ll_data);
     std::vector<size_t> result;
diff --git a/Device/Data/OutputDataIterator.h b/Device/Data/OutputDataIterator.h
index c65ccc362495e874833dde46460439d7d0a7a94b..f1c32bad2a206c66c82e0bdbd7f54b02567d9d9d 100644
--- a/Device/Data/OutputDataIterator.h
+++ b/Device/Data/OutputDataIterator.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_DATA_OUTPUTDATAITERATOR_H
 #define BORNAGAIN_DEVICE_DATA_OUTPUTDATAITERATOR_H
 
@@ -199,3 +200,4 @@ bool operator!=(const OutputDataIterator<TValue1, TContainer1>& left,
 }
 
 #endif // BORNAGAIN_DEVICE_DATA_OUTPUTDATAITERATOR_H
+#endif // USER_API
diff --git a/Device/Detector/DetectionProperties.h b/Device/Detector/DetectionProperties.h
index eedd05c70560088d00dea29371b23e0c22e72145..e5806f73ebd46d9c6eae1af94787483c982f8975 100644
--- a/Device/Detector/DetectionProperties.h
+++ b/Device/Detector/DetectionProperties.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_DETECTOR_DETECTIONPROPERTIES_H
 #define BORNAGAIN_DEVICE_DETECTOR_DETECTIONPROPERTIES_H
 
@@ -58,3 +59,4 @@ private:
 };
 
 #endif // BORNAGAIN_DEVICE_DETECTOR_DETECTIONPROPERTIES_H
+#endif // USER_API
diff --git a/Device/Detector/DetectorContext.h b/Device/Detector/DetectorContext.h
index deecf6d296452e59f09777df7d273d181c33c61c..39ac3c2d3e34cd52c88ffc3d9d2faae7ec46664b 100644
--- a/Device/Detector/DetectorContext.h
+++ b/Device/Detector/DetectorContext.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_DETECTOR_DETECTORCONTEXT_H
 #define BORNAGAIN_DEVICE_DETECTOR_DETECTORCONTEXT_H
 
@@ -51,3 +52,4 @@ private:
 };
 
 #endif // BORNAGAIN_DEVICE_DETECTOR_DETECTORCONTEXT_H
+#endif // USER_API
diff --git a/Device/Detector/DetectorUtils.cpp b/Device/Detector/DetectorUtils.cpp
index fdf1a5af6fbc0bc76ecef5ff515490e42dbc8797..983e45d280f6006392b489776b39df004b1f3da4 100644
--- a/Device/Detector/DetectorUtils.cpp
+++ b/Device/Detector/DetectorUtils.cpp
@@ -16,11 +16,11 @@
 #include "Device/Detector/IDetector2D.h"
 
 bool DetectorUtils::isQuadratic(const IDetector2D& det) {
-    ASSERT(det.dimension()==2);
-    if (det.axis(0).size()!=det.axis(1).size())
+    ASSERT(det.dimension() == 2);
+    if (det.axis(0).size() != det.axis(1).size())
         return false;
-    if (std::abs(det.axis(0).span() - det.axis(1).span()) >
-        1e-12*(det.axis(0).span() + det.axis(1).span()))
+    if (std::abs(det.axis(0).span() - det.axis(1).span())
+        > 1e-12 * (det.axis(0).span() + det.axis(1).span()))
         return false;
     return true;
 }
diff --git a/Device/Detector/IDetector.h b/Device/Detector/IDetector.h
index 995c6c22b70a383dc2a9c735e9405fc86a86de0c..40594deb0ca4a651f17d0332a9bddc1dd3cf735f 100644
--- a/Device/Detector/IDetector.h
+++ b/Device/Detector/IDetector.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_DETECTOR_IDETECTOR_H
 #define BORNAGAIN_DEVICE_DETECTOR_IDETECTOR_H
 
@@ -76,7 +77,7 @@ public:
 #ifndef SWIG
     //! Returns empty detector map in given axes units.
     std::unique_ptr<OutputData<double>> createDetectorMap() const;
-#endif // SWIG
+#endif // USER_API
     //! Returns detection properties
     const DetectionProperties& detectionProperties() const { return m_detection_properties; }
 
@@ -116,3 +117,4 @@ private:
 };
 
 #endif // BORNAGAIN_DEVICE_DETECTOR_IDETECTOR_H
+#endif // USER_API
diff --git a/Device/Detector/IDetector2D.h b/Device/Detector/IDetector2D.h
index b6863a731de988b359a02191972560cbfdf14ea2..1f3e769ab38de972efb94d409d5f7126d354979b 100644
--- a/Device/Detector/IDetector2D.h
+++ b/Device/Detector/IDetector2D.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_DETECTOR_IDETECTOR2D_H
 #define BORNAGAIN_DEVICE_DETECTOR_IDETECTOR2D_H
 
@@ -87,3 +88,4 @@ private:
 };
 
 #endif // BORNAGAIN_DEVICE_DETECTOR_IDETECTOR2D_H
+#endif // USER_API
diff --git a/Device/Detector/RectangularPixel.h b/Device/Detector/RectangularPixel.h
index a61a082cdea65ba811bf487a60d6833541cb0162..0c83ee83a81d1f7e570b4a6da5077cecf966dd64 100644
--- a/Device/Detector/RectangularPixel.h
+++ b/Device/Detector/RectangularPixel.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_DETECTOR_RECTANGULARPIXEL_H
 #define BORNAGAIN_DEVICE_DETECTOR_RECTANGULARPIXEL_H
 
@@ -46,3 +47,4 @@ private:
 };
 
 #endif // BORNAGAIN_DEVICE_DETECTOR_RECTANGULARPIXEL_H
+#endif // USER_API
diff --git a/Device/Detector/RegionOfInterest.h b/Device/Detector/RegionOfInterest.h
index 3466366fbf044d64d8126322f1c8a4f21e093109..d56430a026e3914d2f0645ed6a27b9b7a6b01d73 100644
--- a/Device/Detector/RegionOfInterest.h
+++ b/Device/Detector/RegionOfInterest.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_DETECTOR_REGIONOFINTEREST_H
 #define BORNAGAIN_DEVICE_DETECTOR_REGIONOFINTEREST_H
 
@@ -89,3 +90,4 @@ inline size_t RegionOfInterest::ycoord(size_t index, const std::vector<size_t>&
 }
 
 #endif // BORNAGAIN_DEVICE_DETECTOR_REGIONOFINTEREST_H
+#endif // USER_API
diff --git a/Device/Detector/SimpleUnitConverters.cpp b/Device/Detector/SimpleUnitConverters.cpp
index 17bfce06064e588b57d8b890e8aac977b82c1894..ec0d4ba82ae1dda88ad0ef9f21ef017239c47716 100644
--- a/Device/Detector/SimpleUnitConverters.cpp
+++ b/Device/Detector/SimpleUnitConverters.cpp
@@ -325,8 +325,8 @@ double OffSpecularConverter::calculateValue(size_t, Axes::Units units_type, doub
 
 std::vector<std::map<Axes::Units, std::string>> OffSpecularConverter::createNameMaps() const {
     std::vector<std::map<Axes::Units, std::string>> result;
-    result.push_back(AxisNames::InitOffSpecAxis0());
-    result.push_back(AxisNames::InitOffSpecAxis1());
+    result.push_back(AxisNames::InitOffSpecularAxis0());
+    result.push_back(AxisNames::InitOffSpecularAxis1());
     return result;
 }
 
diff --git a/Device/Detector/SimpleUnitConverters.h b/Device/Detector/SimpleUnitConverters.h
index 2b100f2f7756bb36641944aa1bc1b393abf58b95..08d3f1993aa0281ce681c8043adcaa478f75a630 100644
--- a/Device/Detector/SimpleUnitConverters.h
+++ b/Device/Detector/SimpleUnitConverters.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_DETECTOR_SIMPLEUNITCONVERTERS_H
 #define BORNAGAIN_DEVICE_DETECTOR_SIMPLEUNITCONVERTERS_H
 
@@ -165,3 +166,4 @@ private:
 };
 
 #endif // BORNAGAIN_DEVICE_DETECTOR_SIMPLEUNITCONVERTERS_H
+#endif // USER_API
diff --git a/Device/Detector/SimulationArea.h b/Device/Detector/SimulationArea.h
index 10ea8c4bed5c6520dc2d7ae28a6a84c726ebc0f4..cb06a117efb2198f8a56a411e9ec4fd5a3014c50 100644
--- a/Device/Detector/SimulationArea.h
+++ b/Device/Detector/SimulationArea.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_DETECTOR_SIMULATIONAREA_H
 #define BORNAGAIN_DEVICE_DETECTOR_SIMULATIONAREA_H
 
@@ -68,3 +69,4 @@ public:
 };
 
 #endif // BORNAGAIN_DEVICE_DETECTOR_SIMULATIONAREA_H
+#endif // USER_API
diff --git a/Device/Detector/SimulationAreaIterator.h b/Device/Detector/SimulationAreaIterator.h
index 8593ea79c7a7556a8c7579c7a4baa15a8ef561c6..95d951b5855df9f0c34ba2439eb691b61c20daa0 100644
--- a/Device/Detector/SimulationAreaIterator.h
+++ b/Device/Detector/SimulationAreaIterator.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_DETECTOR_SIMULATIONAREAITERATOR_H
 #define BORNAGAIN_DEVICE_DETECTOR_SIMULATIONAREAITERATOR_H
 
@@ -59,3 +60,4 @@ inline bool SimulationAreaIterator::operator!=(const SimulationAreaIterator& rig
 }
 
 #endif // BORNAGAIN_DEVICE_DETECTOR_SIMULATIONAREAITERATOR_H
+#endif // USER_API
diff --git a/Device/Detector/SpecularDetector1D.h b/Device/Detector/SpecularDetector1D.h
index 38b3e7494ad33ea51717afbfba01962ec4c4c4a0..fc330ceaaa158dc8efa00a4b2322f5a7aaaddef2 100644
--- a/Device/Detector/SpecularDetector1D.h
+++ b/Device/Detector/SpecularDetector1D.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_DETECTOR_SPECULARDETECTOR1D_H
 #define BORNAGAIN_DEVICE_DETECTOR_SPECULARDETECTOR1D_H
 
@@ -56,3 +57,4 @@ protected:
 };
 
 #endif // BORNAGAIN_DEVICE_DETECTOR_SPECULARDETECTOR1D_H
+#endif // USER_API
diff --git a/Device/Detector/SphericalDetector.cpp b/Device/Detector/SphericalDetector.cpp
index 24ddc90549ed201f5c422239cd92392523e5d913..761aff47d1aa46fed0bb7581271f613127cf49b0 100644
--- a/Device/Detector/SphericalDetector.cpp
+++ b/Device/Detector/SphericalDetector.cpp
@@ -31,8 +31,8 @@ SphericalDetector::SphericalDetector(size_t n_phi, double phi_min, double phi_ma
 }
 
 SphericalDetector::SphericalDetector(size_t n_bin, double width, double phi, double alpha)
-    : SphericalDetector(n_bin, phi-width/2, phi+width/2, n_bin, alpha-width/2, alpha+width/2) {
-}
+    : SphericalDetector(n_bin, phi - width / 2, phi + width / 2, n_bin, alpha - width / 2,
+                        alpha + width / 2) {}
 
 SphericalDetector::SphericalDetector(const SphericalDetector& other) : IDetector2D(other) {
     setName("SphericalDetector");
diff --git a/Device/Detector/SphericalPixel.h b/Device/Detector/SphericalPixel.h
index 2577b4c2685554c2555641160451c3af4f2590a8..2c7ccc7a64bdbfd736003b579fed0872c6ec4052 100644
--- a/Device/Detector/SphericalPixel.h
+++ b/Device/Detector/SphericalPixel.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_DETECTOR_SPHERICALPIXEL_H
 #define BORNAGAIN_DEVICE_DETECTOR_SPHERICALPIXEL_H
 
@@ -44,3 +45,4 @@ private:
 };
 
 #endif // BORNAGAIN_DEVICE_DETECTOR_SPHERICALPIXEL_H
+#endif // USER_API
diff --git a/Device/Instrument/SpectrumUtils.cpp b/Device/Histo/HistoUtils.cpp
similarity index 51%
rename from Device/Instrument/SpectrumUtils.cpp
rename to Device/Histo/HistoUtils.cpp
index 87b192fcd57a42aaff940643bca702089864a803..e2ed7f7e71d8d4dde7d0454aa1b79a17db8c4cbe 100644
--- a/Device/Instrument/SpectrumUtils.cpp
+++ b/Device/Histo/HistoUtils.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Device/Instrument/SpectrumUtils.cpp
+//! @file      Device/Histo/HistoUtils.cpp
 //! @brief     PyObvject forward declaration.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,14 +12,17 @@
 //
 //  ************************************************************************************************
 
-#include "Device/Instrument/SpectrumUtils.h"
+#include "Device/Histo/HistoUtils.h"
+#include "Base/Math/Numeric.h"
+#include "Device/Data/DataUtils.h"
+#include "Device/Histo/Histogram2D.h"
+#include "Device/Histo/SimulationResult.h"
 #include <cmath>
-#include <tspectrum.h>
+#include <tspectrum.h> // third-party code, extracted from CERN ROOT (class TSpectrum2)
 
-std::vector<std::pair<double, double>> SpectrumUtils::FindPeaks(const Histogram2D& hist,
-                                                                double sigma,
-                                                                const std::string& option,
-                                                                double threshold) {
+std::vector<std::pair<double, double>> HistoUtils::FindPeaks(const Histogram2D& hist, double sigma,
+                                                             const std::string& option,
+                                                             double threshold) {
     std::unique_ptr<OutputData<double>> data(hist.createOutputData());
     std::vector<std::vector<double>> arr = ArrayUtils::createVector2D(*data);
     tspectrum::Spectrum2D spec;
@@ -48,3 +51,23 @@ std::vector<std::pair<double, double>> SpectrumUtils::FindPeaks(const Histogram2
     }
     return result;
 }
+
+//! Returns sum of relative differences between each pair of elements:
+//! (a, b) -> 2*abs(a - b)/(|a| + |b|)      ( and zero if  a=b=0 within epsilon )
+double HistoUtils::RelativeDifference(const SimulationResult& dat, const SimulationResult& ref) {
+    if (dat.size() != ref.size())
+        throw std::runtime_error("Error in HistoUtils::RelativeDifference: "
+                                 "different number of elements");
+    if (dat.empty())
+        return 0.0;
+    double sum_of_diff = 0.0;
+    for (size_t i = 0; i < dat.size(); ++i)
+        sum_of_diff += Numeric::GetRelativeDifference(dat[i], ref[i]);
+    return sum_of_diff / dat.size();
+}
+
+double HistoUtils::getRelativeDifference(const IHistogram& dat, const IHistogram& ref) {
+    return DataUtils::relativeDataDifference(
+        *std::unique_ptr<OutputData<double>>(dat.getData().meanValues()),
+        *std::unique_ptr<OutputData<double>>(ref.getData().meanValues()));
+}
diff --git a/Device/Instrument/SpectrumUtils.h b/Device/Histo/HistoUtils.h
similarity index 53%
rename from Device/Instrument/SpectrumUtils.h
rename to Device/Histo/HistoUtils.h
index a8c897386d0cbe222f64b863edbddd3c1de9c393..ae112ee3a33cd21fddab465610d6cb21bb17e835 100644
--- a/Device/Instrument/SpectrumUtils.h
+++ b/Device/Histo/HistoUtils.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Device/Instrument/SpectrumUtils.h
+//! @file      Device/Histo/HistoUtils.h
 //! @brief     PyObvject forward declaration.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,22 +12,33 @@
 //
 //  ************************************************************************************************
 
-#ifndef BORNAGAIN_DEVICE_INSTRUMENT_SPECTRUMUTILS_H
-#define BORNAGAIN_DEVICE_INSTRUMENT_SPECTRUMUTILS_H
+#ifndef BORNAGAIN_DEVICE_HISTO_HISTOUTILS_H
+#define BORNAGAIN_DEVICE_HISTO_HISTOUTILS_H
 
-#include "Device/Histo/Histogram2D.h"
+#include "Device/Data/OutputData.h"
 #include <string>
 #include <vector>
 
 class Histogram2D;
+class IHistogram;
+class SimulationResult;
 
-//! Collection of utils for 1D and 2D spectrum processing (background, peaks, ets).
+//! Collection of utils for 1D and 2D image processing (background, peaks, ets).
 
-namespace SpectrumUtils {
+namespace HistoUtils {
+
+//! Returns vector of peak center coordinates, for peaks in given histogram.
 
 std::vector<std::pair<double, double>> FindPeaks(const Histogram2D& hist, double sigma = 2,
                                                  const std::string& option = {},
                                                  double threshold = 0.05);
-}
 
-#endif // BORNAGAIN_DEVICE_INSTRUMENT_SPECTRUMUTILS_H
+//! Returns sum of relative differences between each pair of elements:
+//! (a, b) -> 2*abs(a - b)/(a + b)      ( and zero if  a-b=0 )
+double RelativeDifference(const SimulationResult& dat, const SimulationResult& ref);
+
+double getRelativeDifference(const IHistogram& dat, const IHistogram& ref);
+
+} // namespace HistoUtils
+
+#endif // BORNAGAIN_DEVICE_HISTO_HISTOUTILS_H
diff --git a/Device/Histo/Histogram1D.cpp b/Device/Histo/Histogram1D.cpp
index 38f4612a08d56bf0d3f904f748c46c755fe632fb..d137b7451decf981c10c28b30beca5458b2b3fde 100644
--- a/Device/Histo/Histogram1D.cpp
+++ b/Device/Histo/Histogram1D.cpp
@@ -14,7 +14,7 @@
 
 #include "Device/Histo/Histogram1D.h"
 #include "Base/Axis/VariableBinAxis.h"
-#include "Device/Intensity/ArrayUtils.h"
+#include "Base/Py/PyUtils.h"
 #include <memory>
 
 Histogram1D::Histogram1D(int nbinsx, double xlow, double xup) {
@@ -59,15 +59,15 @@ std::vector<double> Histogram1D::binErrors() const {
 #ifdef BORNAGAIN_PYTHON
 
 PyObject* Histogram1D::binCentersNumpy() const {
-    return ArrayUtils::createNumpyArray(binCenters());
+    return PyUtils::createNumpyArray(binCenters());
 }
 
 PyObject* Histogram1D::binValuesNumpy() const {
-    return ArrayUtils::createNumpyArray(binValues());
+    return PyUtils::createNumpyArray(binValues());
 }
 
 PyObject* Histogram1D::binErrorsNumpy() const {
-    return ArrayUtils::createNumpyArray(binErrors());
+    return PyUtils::createNumpyArray(binErrors());
 }
 
 #endif // BORNAGAIN_PYTHON
diff --git a/Device/Histo/Histogram2D.h b/Device/Histo/Histogram2D.h
index 7507cc960e049723753ecd9a58a915748486910e..c26532ea12eaf91b466f03ba840bec02c0dc675b 100644
--- a/Device/Histo/Histogram2D.h
+++ b/Device/Histo/Histogram2D.h
@@ -16,7 +16,7 @@
 #define BORNAGAIN_DEVICE_HISTO_HISTOGRAM2D_H
 
 #include "Device/Histo/IHistogram.h"
-#include "Device/Intensity/ArrayUtils.h"
+#include "Device/Data/ArrayUtils.h"
 
 //! Two dimensional histogram.
 //! @ingroup tools
diff --git a/Device/Histo/IHistogram.h b/Device/Histo/IHistogram.h
index 373039e8b6d3c976ee0e70e8a21cdf36da0522ae..d941c42183e7d1eee7487abcfd74d66a869a87f5 100644
--- a/Device/Histo/IHistogram.h
+++ b/Device/Histo/IHistogram.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_HISTO_IHISTOGRAM_H
 #define BORNAGAIN_DEVICE_HISTO_IHISTOGRAM_H
 
@@ -193,3 +194,4 @@ protected:
 };
 
 #endif // BORNAGAIN_DEVICE_HISTO_IHISTOGRAM_H
+#endif // USER_API
diff --git a/Device/InputOutput/DataFormatUtils.h b/Device/InputOutput/DataFormatUtils.h
index 90fe0778af5c405a601a6b71b3c00a09914f2e32..b95a4eb3dea80e3a3921320341f850342015bc25 100644
--- a/Device/InputOutput/DataFormatUtils.h
+++ b/Device/InputOutput/DataFormatUtils.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_INPUTOUTPUT_DATAFORMATUTILS_H
 #define BORNAGAIN_DEVICE_INPUTOUTPUT_DATAFORMATUTILS_H
 
@@ -57,3 +58,4 @@ void readLineOfDoubles(std::vector<double>& buffer, std::istringstream& iss);
 } // namespace DataFormatUtils
 
 #endif // BORNAGAIN_DEVICE_INPUTOUTPUT_DATAFORMATUTILS_H
+#endif // USER_API
diff --git a/Device/InputOutput/OutputDataReadReflectometry.cpp b/Device/InputOutput/OutputDataReadReflectometry.cpp
index c42d687f874a635d256a95f7ec5d8555b1c6ec8a..eaf9f672ed4a272b7d2eb00e1f15e91de2437713 100644
--- a/Device/InputOutput/OutputDataReadReflectometry.cpp
+++ b/Device/InputOutput/OutputDataReadReflectometry.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Device/InputOutput/OutputDataReadWriteReflectometry.cpp
+//! @file      Device/InputOutput/OutputDataReadReflectometry.cpp
 //! @brief     Implements class OutputDataReadWriteReflectometry.
 //!
 //! @homepage  http://www.bornagainproject.org
diff --git a/Device/InputOutput/OutputDataReadReflectometry.h b/Device/InputOutput/OutputDataReadReflectometry.h
index 4a536ce063dcf4e2619585b7e1b7fd875efb04de..8c04603ed1793d3087cfc54cdb2dd5301287f150 100644
--- a/Device/InputOutput/OutputDataReadReflectometry.h
+++ b/Device/InputOutput/OutputDataReadReflectometry.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_INPUTOUTPUT_OUTPUTDATAREADREFLECTOMETRY_H
 #define BORNAGAIN_DEVICE_INPUTOUTPUT_OUTPUTDATAREADREFLECTOMETRY_H
 
@@ -32,3 +33,4 @@ public:
 };
 
 #endif // BORNAGAIN_DEVICE_INPUTOUTPUT_OUTPUTDATAREADREFLECTOMETRY_H
+#endif // USER_API
diff --git a/Device/InputOutput/OutputDataReadWriteINT.cpp b/Device/InputOutput/OutputDataReadWriteINT.cpp
index 1879cd56c20432fc674ccf6b27d0d90b36be5c3d..fbc3d10d599c56f62ec4ef3853c8c53fff4f9e6d 100644
--- a/Device/InputOutput/OutputDataReadWriteINT.cpp
+++ b/Device/InputOutput/OutputDataReadWriteINT.cpp
@@ -15,7 +15,7 @@
 #include "Device/InputOutput/OutputDataReadWriteINT.h"
 #include "Base/Utils/StringUtils.h"
 #include "Device/InputOutput/DataFormatUtils.h"
-#include "Device/Intensity/ArrayUtils.h"
+#include "Device/Data/ArrayUtils.h"
 
 OutputData<double>* OutputDataReadWriteINT::readOutputData(std::istream& input_stream) {
     OutputData<double>* result = new OutputData<double>;
diff --git a/Device/InputOutput/OutputDataReadWriteINT.h b/Device/InputOutput/OutputDataReadWriteINT.h
index 7e354328da62aa0c6c8190eee20e543d809ffece..a4003b4367a27a338f9dd5f6984aac8221b64a08 100644
--- a/Device/InputOutput/OutputDataReadWriteINT.h
+++ b/Device/InputOutput/OutputDataReadWriteINT.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_INPUTOUTPUT_OUTPUTDATAREADWRITEINT_H
 #define BORNAGAIN_DEVICE_INPUTOUTPUT_OUTPUTDATAREADWRITEINT_H
 
@@ -38,3 +39,4 @@ private:
 };
 
 #endif // BORNAGAIN_DEVICE_INPUTOUTPUT_OUTPUTDATAREADWRITEINT_H
+#endif // USER_API
diff --git a/Device/InputOutput/OutputDataReadWriteNumpyTXT.cpp b/Device/InputOutput/OutputDataReadWriteNumpyTXT.cpp
index 0e500d9d3562f13fc9803b5ec08105c3f6d4b45e..717da3a86be652971999a1ef60876d679d48af18 100644
--- a/Device/InputOutput/OutputDataReadWriteNumpyTXT.cpp
+++ b/Device/InputOutput/OutputDataReadWriteNumpyTXT.cpp
@@ -15,7 +15,7 @@
 #include "Device/InputOutput/OutputDataReadWriteNumpyTXT.h"
 #include "Base/Utils/StringUtils.h"
 #include "Device/InputOutput/DataFormatUtils.h"
-#include "Device/Intensity/ArrayUtils.h"
+#include "Device/Data/ArrayUtils.h"
 #include <string>
 #include <vector>
 
diff --git a/Device/InputOutput/OutputDataReadWriteNumpyTXT.h b/Device/InputOutput/OutputDataReadWriteNumpyTXT.h
index f8199964809d88615756b88d2bff22fb14c0b847..ffb45d82ab08d24770cd6bbda23a81e6a1c93543 100644
--- a/Device/InputOutput/OutputDataReadWriteNumpyTXT.h
+++ b/Device/InputOutput/OutputDataReadWriteNumpyTXT.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_INPUTOUTPUT_OUTPUTDATAREADWRITENUMPYTXT_H
 #define BORNAGAIN_DEVICE_INPUTOUTPUT_OUTPUTDATAREADWRITENUMPYTXT_H
 
@@ -39,3 +40,4 @@ private:
 };
 
 #endif // BORNAGAIN_DEVICE_INPUTOUTPUT_OUTPUTDATAREADWRITENUMPYTXT_H
+#endif // USER_API
diff --git a/Device/InputOutput/OutputDataReadWriteTiff.h b/Device/InputOutput/OutputDataReadWriteTiff.h
index 286caa5b138aae0eac593d31feda43d0d1197d4d..b126f79b1b7a2583c483903f8c14ae8a5b1bed19 100644
--- a/Device/InputOutput/OutputDataReadWriteTiff.h
+++ b/Device/InputOutput/OutputDataReadWriteTiff.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_INPUTOUTPUT_OUTPUTDATAREADWRITETIFF_H
 #define BORNAGAIN_DEVICE_INPUTOUTPUT_OUTPUTDATAREADWRITETIFF_H
 
@@ -54,3 +55,4 @@ private:
 #endif // BORNAGAIN_TIFF_SUPPORT
 
 #endif // BORNAGAIN_DEVICE_INPUTOUTPUT_OUTPUTDATAREADWRITETIFF_H
+#endif // USER_API
diff --git a/Device/InputOutput/boost_streams.h b/Device/InputOutput/boost_streams.h
index aeda4f3cb92eefad9c31d308f37fec4e9441b1ef..db405d75d07e5d653385e4c574c6b98debb440e6 100644
--- a/Device/InputOutput/boost_streams.h
+++ b/Device/InputOutput/boost_streams.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_INPUTOUTPUT_BOOST_STREAMS_H
 #define BORNAGAIN_DEVICE_INPUTOUTPUT_BOOST_STREAMS_H
 
@@ -32,3 +33,4 @@
 #endif
 
 #endif // BORNAGAIN_DEVICE_INPUTOUTPUT_BOOST_STREAMS_H
+#endif // USER_API
diff --git a/Device/Instrument/Instrument.cpp b/Device/Instrument/Instrument.cpp
index dec056caedc9c75c0912a0d12bec6be76158725d..4ac393487904e6ac2f6f89821ba5c2e131c9f63e 100644
--- a/Device/Instrument/Instrument.cpp
+++ b/Device/Instrument/Instrument.cpp
@@ -80,14 +80,6 @@ void Instrument::setBeam(const Beam& beam) {
         initDetector();
 }
 
-void Instrument::setBeamIntensity(double intensity) {
-    m_beam.setIntensity(intensity);
-}
-
-void Instrument::setBeamPolarization(const kvector_t bloch_vector) {
-    m_beam.setPolarization(bloch_vector);
-}
-
 const IDetector* Instrument::getDetector() const {
     ASSERT(m_detector);
     return m_detector.get();
diff --git a/Device/Instrument/Instrument.h b/Device/Instrument/Instrument.h
index 76639628b5cb4e8f32438fc7665cc9b0da935fcb..7db47e2f5717b13b2ddb1c4e7611be20d0689eeb 100644
--- a/Device/Instrument/Instrument.h
+++ b/Device/Instrument/Instrument.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_INSTRUMENT_INSTRUMENT_H
 #define BORNAGAIN_DEVICE_INSTRUMENT_INSTRUMENT_H
 
@@ -46,11 +47,6 @@ public:
     //! Sets the beam wavelength and incoming angles
     void setBeamParameters(double wavelength, double alpha_i, double phi_i);
 
-    void setBeamIntensity(double intensity);
-
-    //! Sets the beam's polarization according to the given Bloch vector
-    void setBeamPolarization(const kvector_t bloch_vector);
-
     const IDetector* getDetector() const;
     IDetector& detector();
     const IDetector& detector() const;
@@ -72,3 +68,4 @@ protected:
 };
 
 #endif // BORNAGAIN_DEVICE_INSTRUMENT_INSTRUMENT_H
+#endif // USER_API
diff --git a/Device/Instrument/PyArrayImportUtils.cpp b/Device/Instrument/PyArrayImportUtils.cpp
deleted file mode 100644
index 7e229a1be38068c5f01f61ef7d18ba12775d73c0..0000000000000000000000000000000000000000
--- a/Device/Instrument/PyArrayImportUtils.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-//  ************************************************************************************************
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Device/Instrument/PyArrayImportUtils.cpp
-//! @brief     Implements functions in namespace PyArrayImport
-//!
-//! @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 "Device/Instrument/PyArrayImportUtils.h"
-#include "Device/Intensity/ArrayUtils.h"
-
-OutputData<double>* PyArrayImport::importArrayToOutputData(const std::vector<double>& vec) {
-    return ArrayUtils::createData(vec).release();
-}
-
-OutputData<double>*
-PyArrayImport::importArrayToOutputData(const std::vector<std::vector<double>>& vec) {
-    return ArrayUtils::createData(vec).release();
-}
diff --git a/Device/Instrument/PyArrayImportUtils.h b/Device/Instrument/PyArrayImportUtils.h
deleted file mode 100644
index 0f6d1229a8d0c17a601ab79c5c9e7983b17707be..0000000000000000000000000000000000000000
--- a/Device/Instrument/PyArrayImportUtils.h
+++ /dev/null
@@ -1,34 +0,0 @@
-//  ************************************************************************************************
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Device/Instrument/PyArrayImportUtils.h
-//! @brief     Declares functions in namespace PyArrayImport.
-//!
-//! @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 BORNAGAIN_DEVICE_INSTRUMENT_PYARRAYIMPORTUTILS_H
-#define BORNAGAIN_DEVICE_INSTRUMENT_PYARRAYIMPORTUTILS_H
-
-#include <vector>
-
-template <class T> class OutputData;
-
-//! Functions for numpy array import to OutputData.
-//! Required solely as a shortcut to produce OutputData from numpy arrays of doubles.
-
-namespace PyArrayImport {
-
-//! for importing 1D array of doubles from python into OutputData
-OutputData<double>* importArrayToOutputData(const std::vector<double>& vec);
-//! for importing 2D array of doubles from python into OutputData
-OutputData<double>* importArrayToOutputData(const std::vector<std::vector<double>>& vec);
-
-} // namespace PyArrayImport
-
-#endif // BORNAGAIN_DEVICE_INSTRUMENT_PYARRAYIMPORTUTILS_H
diff --git a/Device/Intensity/ArrayUtils.cpp b/Device/Intensity/ArrayUtils.cpp
deleted file mode 100644
index d3b70da3d40167b40b84ee05cfeeeaf645377271..0000000000000000000000000000000000000000
--- a/Device/Intensity/ArrayUtils.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-//  ************************************************************************************************
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Device/Intensity/ArrayUtils.cpp
-//! @brief     Implements various functions to interact from numpy on Python side
-//!
-//! @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)
-//
-//  ************************************************************************************************
-
-#ifdef BORNAGAIN_PYTHON
-
-#include "Device/Intensity/ArrayUtils.h"
-#include "Base/Py/PythonCore.h"
-
-PyObject* ArrayUtils::createNumpyArray(const std::vector<double>& data) {
-    const size_t ndim(1);
-    npy_int ndim_numpy = ndim;
-    npy_intp* ndimsizes_numpy = new npy_intp[ndim];
-    ndimsizes_numpy[0] = data.size();
-
-    // creating standalone numpy array
-    PyObject* pyarray = PyArray_SimpleNew(ndim_numpy, ndimsizes_numpy, NPY_DOUBLE);
-    delete[] ndimsizes_numpy;
-    if (pyarray == nullptr)
-        throw std::runtime_error("ExportOutputData() -> Panic in PyArray_SimpleNew");
-
-    // getting pointer to data buffer of numpy array
-    double* array_buffer = (double*)PyArray_DATA((PyArrayObject*)pyarray);
-
-    for (size_t index = 0; index < data.size(); ++index)
-        *array_buffer++ = data[index];
-
-    return pyarray;
-}
-
-#endif // BORNAGAIN_PYTHON
diff --git a/Device/Mask/Ellipse.h b/Device/Mask/Ellipse.h
index 9ad77609f644d80e5910ac9d763d020ff589244d..d820582c3a20f2144e2875649a4ac144ad15639d 100644
--- a/Device/Mask/Ellipse.h
+++ b/Device/Mask/Ellipse.h
@@ -17,7 +17,7 @@
 
 #include "Device/Mask/IShape2D.h"
 
-//! Ellipse shape.
+//! An ellipse, for use in detector masks.
 //! @ingroup tools
 
 class Ellipse : public IShape2D {
diff --git a/Device/Mask/IShape2D.h b/Device/Mask/IShape2D.h
index 282648bf736f08c9c29036f9ebf62a0da87e818f..319064c1429b7e41822341c836dcf1a97619fb3c 100644
--- a/Device/Mask/IShape2D.h
+++ b/Device/Mask/IShape2D.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_MASK_ISHAPE2D_H
 #define BORNAGAIN_DEVICE_MASK_ISHAPE2D_H
 
@@ -48,3 +49,4 @@ private:
 };
 
 #endif // BORNAGAIN_DEVICE_MASK_ISHAPE2D_H
+#endif // USER_API
diff --git a/Device/Mask/InfinitePlane.h b/Device/Mask/InfinitePlane.h
index 83df83711fb406737dd7b0556bf561acb73f253b..470c2005b6199295293a7bb7b018be1d76c089bd 100644
--- a/Device/Mask/InfinitePlane.h
+++ b/Device/Mask/InfinitePlane.h
@@ -16,12 +16,13 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_MASK_INFINITEPLANE_H
 #define BORNAGAIN_DEVICE_MASK_INFINITEPLANE_H
 
 #include "Device/Mask/IShape2D.h"
 
-//! The infinite plane is used for masking everything once and forever.
+//! The infinite plane is used for masking the entire detector.
 //! @ingroup tools
 
 class InfinitePlane : public IShape2D {
@@ -34,3 +35,4 @@ public:
 };
 
 #endif // BORNAGAIN_DEVICE_MASK_INFINITEPLANE_H
+#endif // USER_API
diff --git a/Device/Mask/Line.h b/Device/Mask/Line.h
index 4e65a401c026976d9b0552c9adc96cd0d4017317..d2dd1cd3bdb3ff6cf9094710fd8e780c9b9bf996 100644
--- a/Device/Mask/Line.h
+++ b/Device/Mask/Line.h
@@ -17,7 +17,7 @@
 
 #include "Device/Mask/IShape2D.h"
 
-//! A line segment.
+//! A line segment, for use in detector masks.
 //! @ingroup mask
 
 class Line : public IShape2D {
diff --git a/Device/Mask/Polygon.h b/Device/Mask/Polygon.h
index ac6fff04d438092769858f43535ec2ee9eee5f0b..cc22fc92f09c3e5ff0d0d076150835747272bc9c 100644
--- a/Device/Mask/Polygon.h
+++ b/Device/Mask/Polygon.h
@@ -20,7 +20,7 @@
 
 class PolygonPrivate;
 
-//! A polygon in 2D space.
+//! A polygon, for use in detector masks.
 //! @ingroup mask
 
 //! Polygon defined by two arrays with x and y coordinates of points.
diff --git a/Device/Mask/Rectangle.h b/Device/Mask/Rectangle.h
index db7d344e698b976f8fdbbece4c3e79ad68063a4c..29a9aa33cf814bb8f8da8dff10964247aa8d3d9b 100644
--- a/Device/Mask/Rectangle.h
+++ b/Device/Mask/Rectangle.h
@@ -17,7 +17,9 @@
 
 #include "Device/Mask/IShape2D.h"
 
-//! The rectangle shape having its axis aligned to the (non-rotated) coordinate system.
+//! A rectangle, for use in detector masks.
+//!
+//! Edges are along the coordinate axes.
 //! @ingroup mask
 
 class Rectangle : public IShape2D {
diff --git a/Device/Resolution/ConvolutionDetectorResolution.h b/Device/Resolution/ConvolutionDetectorResolution.h
index 88d757ea1d2e76f8bd7eb8f4d84932bc99a688da..a24d2c8dcfd0f06bb830e99ae162b23124bdeecd 100644
--- a/Device/Resolution/ConvolutionDetectorResolution.h
+++ b/Device/Resolution/ConvolutionDetectorResolution.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_RESOLUTION_CONVOLUTIONDETECTORRESOLUTION_H
 #define BORNAGAIN_DEVICE_RESOLUTION_CONVOLUTIONDETECTORRESOLUTION_H
 
@@ -70,3 +71,4 @@ inline const IResolutionFunction2D* ConvolutionDetectorResolution::getResolution
 }
 
 #endif // BORNAGAIN_DEVICE_RESOLUTION_CONVOLUTIONDETECTORRESOLUTION_H
+#endif // USER_API
diff --git a/Device/Resolution/Convolve.h b/Device/Resolution/Convolve.h
index d83dd05e4c5bb32f08201ebdf09420400f78fa33..0b70b4265b1527e683ea928e4836f7f3b67243a0 100644
--- a/Device/Resolution/Convolve.h
+++ b/Device/Resolution/Convolve.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_RESOLUTION_CONVOLVE_H
 #define BORNAGAIN_DEVICE_RESOLUTION_CONVOLVE_H
 
@@ -122,3 +123,4 @@ private:
 };
 
 #endif // BORNAGAIN_DEVICE_RESOLUTION_CONVOLVE_H
+#endif // USER_API
diff --git a/Device/Resolution/IDetectorResolution.h b/Device/Resolution/IDetectorResolution.h
index 2159167891a1e8300dee089f6625e753834adc81..8552b761b0d66dc99bf4131816f2ba0402c023cf 100644
--- a/Device/Resolution/IDetectorResolution.h
+++ b/Device/Resolution/IDetectorResolution.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_RESOLUTION_IDETECTORRESOLUTION_H
 #define BORNAGAIN_DEVICE_RESOLUTION_IDETECTORRESOLUTION_H
 
@@ -35,3 +36,4 @@ public:
 };
 
 #endif // BORNAGAIN_DEVICE_RESOLUTION_IDETECTORRESOLUTION_H
+#endif // USER_API
diff --git a/Device/Resolution/IResolutionFunction2D.h b/Device/Resolution/IResolutionFunction2D.h
index 32f2b4d0ef3b3681a4a96ece5988aba567deff89..e61f1f05d56121418c9879a4e014f7dbb54a9e65 100644
--- a/Device/Resolution/IResolutionFunction2D.h
+++ b/Device/Resolution/IResolutionFunction2D.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_RESOLUTION_IRESOLUTIONFUNCTION2D_H
 #define BORNAGAIN_DEVICE_RESOLUTION_IRESOLUTIONFUNCTION2D_H
 
@@ -33,3 +34,4 @@ public:
 };
 
 #endif // BORNAGAIN_DEVICE_RESOLUTION_IRESOLUTIONFUNCTION2D_H
+#endif // USER_API
diff --git a/Device/Resolution/ScanResolution.h b/Device/Resolution/ScanResolution.h
index f4298c8e4b921202dce80b0b71e95ed8afcc0352..a1aaddced35233fa52fde0a8a27cd51ab18ce4a9 100644
--- a/Device/Resolution/ScanResolution.h
+++ b/Device/Resolution/ScanResolution.h
@@ -53,7 +53,7 @@ public:
     virtual std::string name() const = 0;
     virtual double delta() const = 0;
 
-#endif // SWIG
+#endif // USER_API
 protected:
     ScanResolution();
     ScanResolution(const IRangedDistribution& distr);
diff --git a/Device/Unit/AxisNames.cpp b/Device/Unit/AxisNames.cpp
index e2ff4f806619f5baf402941280f202dc2cbf4986..34e8278e9ba59913b79747abeeb690f48805685b 100644
--- a/Device/Unit/AxisNames.cpp
+++ b/Device/Unit/AxisNames.cpp
@@ -58,14 +58,14 @@ std::map<Axes::Units, std::string> InitRectangularAxis1() {
 }
 // For off-specular simulations (both spherical and rectangular detectors)
 // Currently 'mm' is not supported for the y-axis
-std::map<Axes::Units, std::string> InitOffSpecAxis0() {
+std::map<Axes::Units, std::string> InitOffSpecularAxis0() {
     std::map<Axes::Units, std::string> result;
     result[Axes::Units::NBINS] = "X [nbins]";
     result[Axes::Units::RADIANS] = "alpha_i [rad]";
     result[Axes::Units::DEGREES] = "alpha_i [deg]";
     return result;
 }
-std::map<Axes::Units, std::string> InitOffSpecAxis1() {
+std::map<Axes::Units, std::string> InitOffSpecularAxis1() {
     std::map<Axes::Units, std::string> result;
     result[Axes::Units::NBINS] = "Y [nbins]";
     result[Axes::Units::RADIANS] = "alpha_f [rad]";
diff --git a/Device/Unit/AxisNames.h b/Device/Unit/AxisNames.h
index 62c47573a9f222787b2f771a7cecd35310f1f8d7..120f5a2122ddff39141e877711d567a0422cc781 100644
--- a/Device/Unit/AxisNames.h
+++ b/Device/Unit/AxisNames.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_DEVICE_UNIT_AXISNAMES_H
 #define BORNAGAIN_DEVICE_UNIT_AXISNAMES_H
 
@@ -31,11 +32,12 @@ std::map<Axes::Units, std::string> InitSphericalAxis0();
 std::map<Axes::Units, std::string> InitSphericalAxis1();
 std::map<Axes::Units, std::string> InitRectangularAxis0();
 std::map<Axes::Units, std::string> InitRectangularAxis1();
-std::map<Axes::Units, std::string> InitOffSpecAxis0();
-std::map<Axes::Units, std::string> InitOffSpecAxis1();
+std::map<Axes::Units, std::string> InitOffSpecularAxis0();
+std::map<Axes::Units, std::string> InitOffSpecularAxis1();
 std::map<Axes::Units, std::string> InitSpecAxis();
 std::map<Axes::Units, std::string> InitSpecAxisQ();
 std::map<Axes::Units, std::string> InitSampleDepthAxis();
 } // namespace AxisNames
 
 #endif // BORNAGAIN_DEVICE_UNIT_AXISNAMES_H
+#endif // USER_API
diff --git a/Device/Unit/IUnitConverter.h b/Device/Unit/IUnitConverter.h
index c95d4c9891348e2b207977a414c9fc5950d94bdc..00463e648431c5affbe0721a23e2c541298801d7 100644
--- a/Device/Unit/IUnitConverter.h
+++ b/Device/Unit/IUnitConverter.h
@@ -65,13 +65,13 @@ public:
     //! Creates OutputData array in converter units.
     virtual std::unique_ptr<OutputData<double>> createConvertedData(const OutputData<double>& data,
                                                                     Axes::Units units) const;
-#endif // SWIG
+#endif // USER_API
 
 protected:
     void checkIndex(size_t i_axis) const;
 #ifndef SWIG
     [[noreturn]] void throwUnitsError(std::string method, std::vector<Axes::Units> available) const;
-#endif // SWIG
+#endif // USER_API
 
 private:
     virtual std::vector<std::map<Axes::Units, std::string>> createNameMaps() const = 0;
diff --git a/Doc/Doxygen/CMakeLists.txt b/Doc/Doxygen/CMakeLists.txt
index ddc6f220e43f499da2c97d440bf06483d0972768..01f7cd6cf3d048e19c902be7c1cdc9fd60f38945 100644
--- a/Doc/Doxygen/CMakeLists.txt
+++ b/Doc/Doxygen/CMakeLists.txt
@@ -4,7 +4,7 @@ file(MAKE_DIRECTORY ${AUTO_DOX_DIR})
 file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/html)
 add_custom_target(doxy) # this target builds _all_ documentation flavors
 foreach(flavor user long)
-    configure_file(Doxyfile.${flavor}.in
+    configure_file(${flavor}/Doxyfile.in
         ${AUTO_DOX_DIR}/Doxyfile.${flavor} @ONLY)
     add_custom_target(doxy${flavor}
         COMMAND doxygen ${AUTO_DOX_DIR}/Doxyfile.${flavor} )
diff --git a/Doc/Doxygen/README.md b/Doc/Doxygen/README.md
index 33122b51814f5556a545e5eb2b8f528770c397f8..eb04b640117411534dd7508253f4d816282a9232 100644
--- a/Doc/Doxygen/README.md
+++ b/Doc/Doxygen/README.md
@@ -2,7 +2,6 @@ We support different flavors of Doxygen documentation:
 
 - "user", the BornAgain user API
 - "long", full C++ source documentation for developers
-- "dirgraphs", for analysing include dependences
 
 To build the documentation,
 ```
@@ -10,12 +9,13 @@ cd build
 # configure:
 cmake -DBORNAGAIN_CONFIGURE_DOXY=ON ..
 # make:
-make doxyuser # other make targets are 'doxylong' etc,
-              # or 'doxy' to build all available flavors
+make doxyuser
+make doxylong
+make doxy     # to build both flavors
 ```
 
 The configure step writes Doxyfiles to the directory
 `<build>/doxygen`. Do not edit these files.
 
 The make step writes the documentation to directories
-`<build>/html/user` etc.
+`<build>/html/user`, `<build>/html/long`.
diff --git a/Doc/Doxygen/defgroups.dox b/Doc/Doxygen/common/defgroups.dox
similarity index 100%
rename from Doc/Doxygen/defgroups.dox
rename to Doc/Doxygen/common/defgroups.dox
diff --git a/Doc/Doxygen/Doxyfile.long.in b/Doc/Doxygen/long/Doxyfile.in
similarity index 99%
rename from Doc/Doxygen/Doxyfile.long.in
rename to Doc/Doxygen/long/Doxyfile.in
index 1ea3268dd066e68234edf430fd585acea5667381..d76c1cbdb9f3222875ce6df064effaaa66532b29 100644
--- a/Doc/Doxygen/Doxyfile.long.in
+++ b/Doc/Doxygen/long/Doxyfile.in
@@ -106,7 +106,7 @@ OUTPUT_TEXT_DIRECTION  = None
 # documentation (similar to Javadoc). Set to NO to disable this.
 # The default value is: YES.
 
-BRIEF_MEMBER_DESC      = NO
+BRIEF_MEMBER_DESC      = YES
 
 # If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
 # description of a member or function before the detailed description
@@ -835,7 +835,8 @@ WARN_LOGFILE           =
 # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
 # Note: If this tag is empty the current directory is searched.
 
-INPUT                  = @CMAKE_SOURCE_DIR@/Doc/Doxygen \
+INPUT                  = @CMAKE_SOURCE_DIR@/Doc/Doxygen/long \
+                         @CMAKE_SOURCE_DIR@/Doc/Doxygen/common \
                          @CMAKE_SOURCE_DIR@/Base \
                          @CMAKE_SOURCE_DIR@/Fit \
                          @CMAKE_SOURCE_DIR@/Param \
@@ -870,7 +871,8 @@ INPUT_ENCODING         = UTF-8
 
 FILE_PATTERNS          = *.cpp \
                          *.h \
-                         *.dox
+                         *.dox \
+                         *.md
 
 # The RECURSIVE tag can be used to specify whether or not subdirectories should
 # be searched for input files as well.
@@ -901,7 +903,7 @@ EXCLUDE_SYMLINKS       = NO
 # Note that the wildcards are matched against the file with absolute path, so to
 # exclude all test directories for example use the pattern */test/*
 
-EXCLUDE_PATTERNS       = */PythonAPI/*
+EXCLUDE_PATTERNS       = */3rdParty/* */Test/*
 
 # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
 # (namespaces, classes, functions, etc.) that should be excluded from the
diff --git a/Doc/Doxygen/long/mainpage.md b/Doc/Doxygen/long/mainpage.md
new file mode 100644
index 0000000000000000000000000000000000000000..60c0f397075f0558028f793cd8e4bc72333c70b2
--- /dev/null
+++ b/Doc/Doxygen/long/mainpage.md
@@ -0,0 +1,27 @@
+## BornAgain developer reference {#mainpage}
+
+C++ developer reference of <a href="http://www.bornagainproject.org">BornAgain Project</a>,
+ an open-source software to simulate and fit
+ neutron and x-ray reflectometry and grazing-incidence small-angle scattering.
+
+### See also
+
+* <https://bornagainproject.org>, project homepage;
+* <https://github.com/scgmlz/BornAgain>, source repository;
+
+### License
+
+[GNU General Public License v3 or higher](https://github.com/scgmlz/BornAgain/blob/master/COPYING)
+
+Copyright Forschungszentrum Jülich GmbH 2015-
+
+
+### Authors
+
+Scientific Computing Group at MLZ Garching.
+
+See file [AUTHORS](https://github.com/scgmlz/BornAgain/blob/master/AUTHORS).
+
+### Citation
+
+See file [CITATION](https://github.com/scgmlz/BornAgain/blob/master/CITATION).
diff --git a/Doc/Doxygen/mainpage.dox b/Doc/Doxygen/mainpage.dox
deleted file mode 100644
index 238aa7a5033c1de75d797fce03fa625d08db8446..0000000000000000000000000000000000000000
--- a/Doc/Doxygen/mainpage.dox
+++ /dev/null
@@ -1,38 +0,0 @@
-/*!
-\mainpage
-
-C++ API Reference of <a href="http://www.bornagainproject.org">BornAgain Project</a>,
- an open-source software to simulate and fit
- neutron and x-ray reflectometry and grazing-incidence small-angle scattering.
-
-<ul>
-<li> Section <a href="userapi.html">User API</a>
-  contains list of main classes to run the simulation.
-<li> Section <a href="annotated.html">Full C++ API</a>
-  contains a full list of classes belonging to the %BornAgain framework.
-<li> Section <a href="namespace.html">Namespace List</a>
-  contains a full list of namespaces belonging to the %BornAgain framework.
-<li> Section <a href="files.html">File List</a>
-  lets you browse the C++ source code.
-
-</ul>
-
-
-<b> License: </b>
-<br>
-<a href="https://github.com/scgmlz/BornAgain/blob/master/COPYING"
-  >GNU General Public License v3 or higher</a>
-<br>
-Copyright Forschungszentrum Jülich GmbH 2015-
-
-
-<b> Authors:  </b>
-<br>
-Scientific Computing Group at MLZ Garching.
-<br>
-See file <a href="https://github.com/scgmlz/BornAgain/blob/master/AUTHORS">AUTHORS</a>
-
-<b> Citation:  </b>
-See file <a href="https://github.com/scgmlz/BornAgain/blob/master/CITATION">CITATION</a>
-
-*/
diff --git a/Doc/Doxygen/Doxyfile.user.in b/Doc/Doxygen/user/Doxyfile.in
similarity index 99%
rename from Doc/Doxygen/Doxyfile.user.in
rename to Doc/Doxygen/user/Doxyfile.in
index 457a9b872c264a8b4ff437f8c17c075c937f7523..e54f2ed1f9c151d59372222ad0bdb94eee497647 100644
--- a/Doc/Doxygen/Doxyfile.user.in
+++ b/Doc/Doxygen/user/Doxyfile.in
@@ -141,7 +141,7 @@ ALWAYS_DETAILED_SEC    = NO
 # operators of the base classes will not be shown.
 # The default value is: NO.
 
-INLINE_INHERITED_MEMB  = NO
+INLINE_INHERITED_MEMB  = YES
 
 # If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
 # before files name in the file list and in the header files. If set to NO the
@@ -497,7 +497,7 @@ EXTRACT_PACKAGE        = NO
 # included in the documentation.
 # The default value is: NO.
 
-EXTRACT_STATIC         = NO
+EXTRACT_STATIC         = YES
 
 # If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
 # locally in source files will be included in the documentation. If set to NO,
@@ -505,7 +505,7 @@ EXTRACT_STATIC         = NO
 # for Java sources.
 # The default value is: YES.
 
-EXTRACT_LOCAL_CLASSES  = YES
+EXTRACT_LOCAL_CLASSES  = NO
 
 # This flag is only useful for Objective-C code. If set to YES, local methods,
 # which are defined in the implementation section but not in the interface are
@@ -607,14 +607,14 @@ FORCE_LOCAL_INCLUDES   = YES
 # documentation for inline members.
 # The default value is: YES.
 
-INLINE_INFO            = YES
+INLINE_INFO            = NO
 
 # If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
 # (detailed) documentation of file and class members alphabetically by member
 # name. If set to NO, the members will appear in declaration order.
 # The default value is: YES.
 
-SORT_MEMBER_DOCS       = NO
+SORT_MEMBER_DOCS       = YES
 
 # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
 # descriptions of file, namespace and class members alphabetically by member
@@ -622,7 +622,7 @@ SORT_MEMBER_DOCS       = NO
 # this will also influence the order of the classes in the class list.
 # The default value is: NO.
 
-SORT_BRIEF_DOCS        = NO
+SORT_BRIEF_DOCS        = YES
 
 # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
 # (brief and detailed) documentation of class members so that constructors and
@@ -634,14 +634,14 @@ SORT_BRIEF_DOCS        = NO
 # detailed member documentation.
 # The default value is: NO.
 
-SORT_MEMBERS_CTORS_1ST = NO
+SORT_MEMBERS_CTORS_1ST = YES
 
 # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
 # of group names into alphabetical order. If set to NO the group names will
 # appear in their defined order.
 # The default value is: NO.
 
-SORT_GROUP_NAMES       = NO
+SORT_GROUP_NAMES       = YES
 
 # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
 # fully-qualified names, including namespaces. If set to NO, the class list will
@@ -667,19 +667,19 @@ STRICT_PROTO_MATCHING  = NO
 # list. This list is created by putting \todo commands in the documentation.
 # The default value is: YES.
 
-GENERATE_TODOLIST      = YES
+GENERATE_TODOLIST      = NO
 
 # The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
 # list. This list is created by putting \test commands in the documentation.
 # The default value is: YES.
 
-GENERATE_TESTLIST      = YES
+GENERATE_TESTLIST      = NO
 
 # The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
 # list. This list is created by putting \bug commands in the documentation.
 # The default value is: YES.
 
-GENERATE_BUGLIST       = YES
+GENERATE_BUGLIST       = NO
 
 # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
 # the deprecated list. This list is created by putting \deprecated commands in
@@ -835,7 +835,8 @@ WARN_LOGFILE           =
 # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
 # Note: If this tag is empty the current directory is searched.
 
-INPUT                  = @CMAKE_SOURCE_DIR@/Doc/Doxygen \
+INPUT                  = @CMAKE_SOURCE_DIR@/Doc/Doxygen/user \
+                         @CMAKE_SOURCE_DIR@/Doc/Doxygen/common \
                          @CMAKE_SOURCE_DIR@/Base \
                          @CMAKE_SOURCE_DIR@/Fit \
                          @CMAKE_SOURCE_DIR@/Param \
@@ -870,7 +871,8 @@ INPUT_ENCODING         = UTF-8
 
 FILE_PATTERNS          = *.cpp \
                          *.h \
-                         *.dox
+                         *.dox \
+                         *.md
 
 # The RECURSIVE tag can be used to specify whether or not subdirectories should
 # be searched for input files as well.
@@ -901,7 +903,7 @@ EXCLUDE_SYMLINKS       = NO
 # Note that the wildcards are matched against the file with absolute path, so to
 # exclude all test directories for example use the pattern */test/*
 
-EXCLUDE_PATTERNS       = */PythonAPI/*
+EXCLUDE_PATTERNS       = */3rdParty/* */Test/*
 
 # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
 # (namespaces, classes, functions, etc.) that should be excluded from the
@@ -1007,7 +1009,7 @@ USE_MDFILE_AS_MAINPAGE =
 # also VERBATIM_HEADERS is set to NO.
 # The default value is: NO.
 
-SOURCE_BROWSER         = YES
+SOURCE_BROWSER         = NO
 
 # Setting the INLINE_SOURCES tag to YES will include the body of functions,
 # classes and enums directly into the documentation.
@@ -1123,7 +1125,7 @@ CLANG_DATABASE_PATH    =
 # classes, structs, unions or interfaces.
 # The default value is: YES.
 
-ALPHABETICAL_INDEX     = YES
+ALPHABETICAL_INDEX     = NO
 
 # The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
 # which the alphabetical index list will be split.
@@ -2183,7 +2185,9 @@ INCLUDE_FILE_PATTERNS  =
 # recursively expanded use the := operator instead of the = operator.
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
-PREDEFINED             = BORNAGAIN_PYTHON
+PREDEFINED             = BORNAGAIN_PYTHON \
+                         SWIG \
+                         USER_API
 
 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
 # tag can be used to specify a list of macro names that should be expanded. The
@@ -2419,7 +2423,7 @@ CALLER_GRAPH           = NO
 # The default value is: YES.
 # This tag requires that the tag HAVE_DOT is set to YES.
 
-GRAPHICAL_HIERARCHY    = YES
+GRAPHICAL_HIERARCHY    = NO
 
 # If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
 # dependencies a directory has on other directories in a graphical way. The
diff --git a/Doc/Doxygen/userapi.dox b/Doc/Doxygen/user/mainpage.md
similarity index 73%
rename from Doc/Doxygen/userapi.dox
rename to Doc/Doxygen/user/mainpage.md
index 792593fd4ab0b25cd6a200b59159b295786ad4ac..6e210cda4cf3a79c9fedf6a52c646b91c1e19d6e 100644
--- a/Doc/Doxygen/userapi.dox
+++ b/Doc/Doxygen/user/mainpage.md
@@ -1,5 +1,11 @@
-/*!
-\page userapi User API
+## BornAgain Python user reference {#mainpage}
+
+Python user reference of <a href="http://www.bornagainproject.org">BornAgain Project</a>,
+ an open-source software to simulate and fit
+ neutron and x-ray reflectometry and grazing-incidence small-angle scattering.
+
+
+<div>
 
 Here is a list of classes grouped in several categories to create the sample, describe scattering geometry, run the simulation and perform fitting.
 
@@ -50,8 +56,29 @@ Here is a list of additional classes from internal API.
 <li> \ref formfactors_internal "Form factors internals" <br>
 <li> \ref distribution_internal "Distribution function internals"
 <li> \ref tools_internal "Tools internals" <br>
-<li> \ref input_output_internal "Input/output internals" <br>
 <li> \ref fitting_internal "Fitting internals" <br>
 </ul>
 
-*/
+</div>
+
+### See also
+
+* <https://bornagainproject.org>, project homepage;
+* <https://github.com/scgmlz/BornAgain>, source repository;
+
+### License
+
+[GNU General Public License v3 or higher](https://github.com/scgmlz/BornAgain/blob/master/COPYING)
+
+Copyright Forschungszentrum Jülich GmbH 2015-
+
+
+### Authors
+
+Scientific Computing Group at MLZ Garching.
+
+See file [AUTHORS](https://github.com/scgmlz/BornAgain/blob/master/AUTHORS).
+
+### Citation
+
+See file [CITATION](https://github.com/scgmlz/BornAgain/blob/master/CITATION).
diff --git a/Doc/FFCatalog/fig/ff2/bornplot.py b/Doc/FFCatalog/fig/ff2/bornplot.py
index a834a978c71c011f17798058a6e66f4e1c48fc44..7e8ecc7b9d71f9fe603d4f66d43a3c4e69be04ac 100644
--- a/Doc/FFCatalog/fig/ff2/bornplot.py
+++ b/Doc/FFCatalog/fig/ff2/bornplot.py
@@ -10,7 +10,7 @@ rc('text', usetex=True)
 rc('image', cmap='inferno')
 
 import bornagain as ba
-from bornagain import nm, deg, angstrom, deg2rad
+from bornagain import deg, angstrom
 
 
 class BinRange:
diff --git a/Examples/Python/fit55_SpecularIntro/PolarizedSpinAsymmetryFit.py b/Examples/Python/fit55_SpecularIntro/PolarizedSpinAsymmetryFit.py
index 4b89d453bb1122cf8f5bec6cc9d7d21f0b596751..970338e1de1c273111fb3925eb0aa6cf635ab805 100644
--- a/Examples/Python/fit55_SpecularIntro/PolarizedSpinAsymmetryFit.py
+++ b/Examples/Python/fit55_SpecularIntro/PolarizedSpinAsymmetryFit.py
@@ -91,7 +91,7 @@ def get_simulation(q_axis, parameters, polarization, analyzer):
     distr = ba.RangedDistributionGaussian(n_samples, n_sig)
     scan.setAbsoluteQResolution(distr, parameters["q_res"])
 
-    simulation.setBeamPolarization(polarization)
+    simulation.beam().setPolarization(polarization)
     simulation.setAnalyzerProperties(analyzer, 1.0, 0.5)
 
     simulation.setScan(scan)
diff --git a/Examples/Python/sim03_Structures/ApproximationDA.py b/Examples/Python/scatter2d/ApproximationDA.py
similarity index 100%
rename from Examples/Python/sim03_Structures/ApproximationDA.py
rename to Examples/Python/scatter2d/ApproximationDA.py
diff --git a/Examples/Python/sim03_Structures/ApproximationLMA.py b/Examples/Python/scatter2d/ApproximationLMA.py
similarity index 100%
rename from Examples/Python/sim03_Structures/ApproximationLMA.py
rename to Examples/Python/scatter2d/ApproximationLMA.py
diff --git a/Examples/Python/sim03_Structures/ApproximationSSCA.py b/Examples/Python/scatter2d/ApproximationSSCA.py
similarity index 100%
rename from Examples/Python/sim03_Structures/ApproximationSSCA.py
rename to Examples/Python/scatter2d/ApproximationSSCA.py
diff --git a/Examples/Python/sim11_Device/BeamDivergence.py b/Examples/Python/scatter2d/BeamDivergence.py
similarity index 100%
rename from Examples/Python/sim11_Device/BeamDivergence.py
rename to Examples/Python/scatter2d/BeamDivergence.py
diff --git a/Examples/Python/sim02_Complexes/BiMaterialCylinders.py b/Examples/Python/scatter2d/BiMaterialCylinders.py
similarity index 100%
rename from Examples/Python/sim02_Complexes/BiMaterialCylinders.py
rename to Examples/Python/scatter2d/BiMaterialCylinders.py
diff --git a/Examples/Python/sim22_OffSpecular/BoxesWithSpecularPeak.py b/Examples/Python/scatter2d/BoxesWithSpecularPeak.py
similarity index 100%
rename from Examples/Python/sim22_OffSpecular/BoxesWithSpecularPeak.py
rename to Examples/Python/scatter2d/BoxesWithSpecularPeak.py
diff --git a/Examples/Python/sim04_Multilayers/BuriedParticles.py b/Examples/Python/scatter2d/BuriedParticles.py
similarity index 100%
rename from Examples/Python/sim04_Multilayers/BuriedParticles.py
rename to Examples/Python/scatter2d/BuriedParticles.py
diff --git a/Examples/Python/sim11_Device/ConstantBackground.py b/Examples/Python/scatter2d/ConstantBackground.py
similarity index 100%
rename from Examples/Python/sim11_Device/ConstantBackground.py
rename to Examples/Python/scatter2d/ConstantBackground.py
diff --git a/Examples/Python/sim02_Complexes/CoreShellNanoparticles.py b/Examples/Python/scatter2d/CoreShellNanoparticles.py
similarity index 100%
rename from Examples/Python/sim02_Complexes/CoreShellNanoparticles.py
rename to Examples/Python/scatter2d/CoreShellNanoparticles.py
diff --git a/Examples/Python/sim04_Multilayers/CorrelatedRoughness.py b/Examples/Python/scatter2d/CorrelatedRoughness.py
similarity index 97%
rename from Examples/Python/sim04_Multilayers/CorrelatedRoughness.py
rename to Examples/Python/scatter2d/CorrelatedRoughness.py
index f968871ae5b3ff1fc5792df6b6679ec0641bc6ad..e2731cccefc3fe895ec8c7231ca6f623be5d1148 100644
--- a/Examples/Python/sim04_Multilayers/CorrelatedRoughness.py
+++ b/Examples/Python/scatter2d/CorrelatedRoughness.py
@@ -40,8 +40,6 @@ def get_sample():
     my_sample.addLayerWithTopRoughness(l_substrate, roughness)
     my_sample.setCrossCorrLength(10*nm)
 
-    print(my_sample.treeToString())
-
     return my_sample
 
 
diff --git a/Examples/Python/sim03_Structures/CosineRipplesAtRectLattice.py b/Examples/Python/scatter2d/CosineRipplesAtRectLattice.py
similarity index 100%
rename from Examples/Python/sim03_Structures/CosineRipplesAtRectLattice.py
rename to Examples/Python/scatter2d/CosineRipplesAtRectLattice.py
diff --git a/Examples/Python/sim01_Particles/CylindersAndPrisms.py b/Examples/Python/scatter2d/CylindersAndPrisms.py
similarity index 100%
rename from Examples/Python/sim01_Particles/CylindersAndPrisms.py
rename to Examples/Python/scatter2d/CylindersAndPrisms.py
diff --git a/Examples/Python/sim04_Multilayers/CylindersInAverageLayer.py b/Examples/Python/scatter2d/CylindersInAverageLayer.py
similarity index 100%
rename from Examples/Python/sim04_Multilayers/CylindersInAverageLayer.py
rename to Examples/Python/scatter2d/CylindersInAverageLayer.py
diff --git a/Examples/Python/sim01_Particles/CylindersInBA.py b/Examples/Python/scatter2d/CylindersInBA.py
similarity index 100%
rename from Examples/Python/sim01_Particles/CylindersInBA.py
rename to Examples/Python/scatter2d/CylindersInBA.py
diff --git a/Examples/Python/sim01_Particles/CylindersInDWBA.py b/Examples/Python/scatter2d/CylindersInDWBA.py
similarity index 100%
rename from Examples/Python/sim01_Particles/CylindersInDWBA.py
rename to Examples/Python/scatter2d/CylindersInDWBA.py
diff --git a/Examples/Python/sim01_Particles/CylindersWithSizeDistribution.py b/Examples/Python/scatter2d/CylindersWithSizeDistribution.py
similarity index 100%
rename from Examples/Python/sim01_Particles/CylindersWithSizeDistribution.py
rename to Examples/Python/scatter2d/CylindersWithSizeDistribution.py
diff --git a/Examples/Python/sim11_Device/DetectorResolutionFunction.py b/Examples/Python/scatter2d/DetectorResolutionFunction.py
similarity index 100%
rename from Examples/Python/sim11_Device/DetectorResolutionFunction.py
rename to Examples/Python/scatter2d/DetectorResolutionFunction.py
diff --git a/Examples/Python/sim04_Multilayers/HalfSpheresInAverageTopLayer.py b/Examples/Python/scatter2d/HalfSpheresInAverageTopLayer.py
similarity index 100%
rename from Examples/Python/sim04_Multilayers/HalfSpheresInAverageTopLayer.py
rename to Examples/Python/scatter2d/HalfSpheresInAverageTopLayer.py
diff --git a/Examples/Python/sim02_Complexes/HexagonalLatticesWithBasis.py b/Examples/Python/scatter2d/HexagonalLatticesWithBasis.py
similarity index 100%
rename from Examples/Python/sim02_Complexes/HexagonalLatticesWithBasis.py
rename to Examples/Python/scatter2d/HexagonalLatticesWithBasis.py
diff --git a/Examples/Python/sim03_Structures/Interference1DRadialParaCrystal.py b/Examples/Python/scatter2d/Interference1DRadialParaCrystal.py
similarity index 100%
rename from Examples/Python/sim03_Structures/Interference1DRadialParaCrystal.py
rename to Examples/Python/scatter2d/Interference1DRadialParaCrystal.py
diff --git a/Examples/Python/sim03_Structures/Interference2DCenteredSquareLattice.py b/Examples/Python/scatter2d/Interference2DCenteredSquareLattice.py
similarity index 100%
rename from Examples/Python/sim03_Structures/Interference2DCenteredSquareLattice.py
rename to Examples/Python/scatter2d/Interference2DCenteredSquareLattice.py
diff --git a/Examples/Python/sim03_Structures/Interference2DLatticeSumOfRotated.py b/Examples/Python/scatter2d/Interference2DLatticeSumOfRotated.py
similarity index 100%
rename from Examples/Python/sim03_Structures/Interference2DLatticeSumOfRotated.py
rename to Examples/Python/scatter2d/Interference2DLatticeSumOfRotated.py
diff --git a/Examples/Python/sim03_Structures/Interference2DParaCrystal.py b/Examples/Python/scatter2d/Interference2DParaCrystal.py
similarity index 100%
rename from Examples/Python/sim03_Structures/Interference2DParaCrystal.py
rename to Examples/Python/scatter2d/Interference2DParaCrystal.py
diff --git a/Examples/Python/sim03_Structures/Interference2DRotatedSquareLattice.py b/Examples/Python/scatter2d/Interference2DRotatedSquareLattice.py
similarity index 100%
rename from Examples/Python/sim03_Structures/Interference2DRotatedSquareLattice.py
rename to Examples/Python/scatter2d/Interference2DRotatedSquareLattice.py
diff --git a/Examples/Python/sim03_Structures/Interference2DSquareFiniteLattice.py b/Examples/Python/scatter2d/Interference2DSquareFiniteLattice.py
similarity index 100%
rename from Examples/Python/sim03_Structures/Interference2DSquareFiniteLattice.py
rename to Examples/Python/scatter2d/Interference2DSquareFiniteLattice.py
diff --git a/Examples/Python/sim03_Structures/Interference2DSquareLattice.py b/Examples/Python/scatter2d/Interference2DSquareLattice.py
similarity index 100%
rename from Examples/Python/sim03_Structures/Interference2DSquareLattice.py
rename to Examples/Python/scatter2d/Interference2DSquareLattice.py
diff --git a/Examples/Python/sim05_Magnetism/MagneticSpheres.py b/Examples/Python/scatter2d/MagneticSpheres.py
similarity index 100%
rename from Examples/Python/sim05_Magnetism/MagneticSpheres.py
rename to Examples/Python/scatter2d/MagneticSpheres.py
diff --git a/Examples/Python/sim02_Complexes/MesoCrystal.py b/Examples/Python/scatter2d/MesoCrystal.py
similarity index 100%
rename from Examples/Python/sim02_Complexes/MesoCrystal.py
rename to Examples/Python/scatter2d/MesoCrystal.py
diff --git a/Examples/Python/sim02_Complexes/ParticlesCrossingInterface.py b/Examples/Python/scatter2d/ParticlesCrossingInterface.py
similarity index 100%
rename from Examples/Python/sim02_Complexes/ParticlesCrossingInterface.py
rename to Examples/Python/scatter2d/ParticlesCrossingInterface.py
diff --git a/Examples/Python/sim03_Structures/RectangularGrating.py b/Examples/Python/scatter2d/RectangularGrating.py
similarity index 100%
rename from Examples/Python/sim03_Structures/RectangularGrating.py
rename to Examples/Python/scatter2d/RectangularGrating.py
diff --git a/Examples/Python/sim01_Particles/RotatedPyramids.py b/Examples/Python/scatter2d/RotatedPyramids.py
similarity index 100%
rename from Examples/Python/sim01_Particles/RotatedPyramids.py
rename to Examples/Python/scatter2d/RotatedPyramids.py
diff --git a/Examples/Python/sim03_Structures/SpheresAtHexLattice.py b/Examples/Python/scatter2d/SpheresAtHexLattice.py
similarity index 100%
rename from Examples/Python/sim03_Structures/SpheresAtHexLattice.py
rename to Examples/Python/scatter2d/SpheresAtHexLattice.py
diff --git a/Examples/Python/sim03_Structures/TriangularRipple.py b/Examples/Python/scatter2d/TriangularRipple.py
similarity index 100%
rename from Examples/Python/sim03_Structures/TriangularRipple.py
rename to Examples/Python/scatter2d/TriangularRipple.py
diff --git a/Examples/Python/sim01_Particles/TwoTypesOfCylindersWithSizeDistribution.py b/Examples/Python/scatter2d/TwoTypesOfCylindersWithSizeDistribution.py
similarity index 100%
rename from Examples/Python/sim01_Particles/TwoTypesOfCylindersWithSizeDistribution.py
rename to Examples/Python/scatter2d/TwoTypesOfCylindersWithSizeDistribution.py
diff --git a/Examples/Python/sim21_Reflectometry/BasicSpecularSimulation.py b/Examples/Python/specular/BasicSpecularSimulation.py
similarity index 100%
rename from Examples/Python/sim21_Reflectometry/BasicSpecularSimulation.py
rename to Examples/Python/specular/BasicSpecularSimulation.py
diff --git a/Examples/Python/sim21_Reflectometry/BeamAngularDivergence.py b/Examples/Python/specular/BeamAngularDivergence.py
similarity index 100%
rename from Examples/Python/sim21_Reflectometry/BeamAngularDivergence.py
rename to Examples/Python/specular/BeamAngularDivergence.py
diff --git a/Examples/Python/sim21_Reflectometry/BeamFullDivergence.py b/Examples/Python/specular/BeamFullDivergence.py
similarity index 100%
rename from Examples/Python/sim21_Reflectometry/BeamFullDivergence.py
rename to Examples/Python/specular/BeamFullDivergence.py
diff --git a/Examples/Python/sim21_Reflectometry/TOFRWithResolution.py b/Examples/Python/specular/TOFRWithResolution.py
similarity index 100%
rename from Examples/Python/sim21_Reflectometry/TOFRWithResolution.py
rename to Examples/Python/specular/TOFRWithResolution.py
diff --git a/Examples/Python/sim21_Reflectometry/TimeOfFlightReflectometry.py b/Examples/Python/specular/TimeOfFlightReflectometry.py
similarity index 100%
rename from Examples/Python/sim21_Reflectometry/TimeOfFlightReflectometry.py
rename to Examples/Python/specular/TimeOfFlightReflectometry.py
diff --git a/Examples/Python/sim21_Reflectometry/genx_angular_divergence.dat.gz b/Examples/Python/specular/genx_angular_divergence.dat.gz
similarity index 100%
rename from Examples/Python/sim21_Reflectometry/genx_angular_divergence.dat.gz
rename to Examples/Python/specular/genx_angular_divergence.dat.gz
diff --git a/Examples/Python/sim31_Parameterization/AccessingSimulationResults.py b/Examples/Python/varia/AccessingSimulationResults.py
similarity index 100%
rename from Examples/Python/sim31_Parameterization/AccessingSimulationResults.py
rename to Examples/Python/varia/AccessingSimulationResults.py
diff --git a/Examples/Python/sim01_Particles/AllFormFactorsAvailable.py b/Examples/Python/varia/AllFormFactorsAvailable.py
similarity index 100%
rename from Examples/Python/sim01_Particles/AllFormFactorsAvailable.py
rename to Examples/Python/varia/AllFormFactorsAvailable.py
diff --git a/Examples/Python/sim11_Device/AxesInDifferentUnits.py b/Examples/Python/varia/AxesInDifferentUnits.py
similarity index 100%
rename from Examples/Python/sim11_Device/AxesInDifferentUnits.py
rename to Examples/Python/varia/AxesInDifferentUnits.py
diff --git a/Examples/Python/sim21_Reflectometry/BasicPolarizedReflectometry.py b/Examples/Python/varia/BasicPolarizedReflectometry.py
similarity index 97%
rename from Examples/Python/sim21_Reflectometry/BasicPolarizedReflectometry.py
rename to Examples/Python/varia/BasicPolarizedReflectometry.py
index a61b8f9da614369882137b1e201b4eba94cbb7da..876ffbc11af1a46f5c2ff85aed3b2f6f556d65ed 100644
--- a/Examples/Python/sim21_Reflectometry/BasicPolarizedReflectometry.py
+++ b/Examples/Python/varia/BasicPolarizedReflectometry.py
@@ -53,7 +53,7 @@ def run_simulation(polarization=ba.kvector_t(0, 1, 0),
     simulation = get_simulation()
 
     # adding polarization and analyzer operator
-    simulation.setBeamPolarization(polarization)
+    simulation.beam().setPolarization(polarization)
     simulation.setAnalyzerProperties(analyzer, 1.0, 0.5)
 
     simulation.setSample(sample)
diff --git a/Examples/Python/sim02_Complexes/CustomFormFactor.py b/Examples/Python/varia/CustomFormFactor.py
similarity index 100%
rename from Examples/Python/sim02_Complexes/CustomFormFactor.py
rename to Examples/Python/varia/CustomFormFactor.py
diff --git a/Examples/Python/special40_DepthProbe/DepthProbe.py b/Examples/Python/varia/DepthProbe.py
similarity index 100%
rename from Examples/Python/special40_DepthProbe/DepthProbe.py
rename to Examples/Python/varia/DepthProbe.py
diff --git a/Examples/Python/sim03_Structures/FindPeaks.py b/Examples/Python/varia/FindPeaks.py
similarity index 100%
rename from Examples/Python/sim03_Structures/FindPeaks.py
rename to Examples/Python/varia/FindPeaks.py
diff --git a/Examples/Python/sim21_Reflectometry/FootprintCorrection.py b/Examples/Python/varia/FootprintCorrection.py
similarity index 100%
rename from Examples/Python/sim21_Reflectometry/FootprintCorrection.py
rename to Examples/Python/varia/FootprintCorrection.py
diff --git a/Examples/Python/sim04_Multilayers/GratingMC.py b/Examples/Python/varia/GratingMC.py
similarity index 100%
rename from Examples/Python/sim04_Multilayers/GratingMC.py
rename to Examples/Python/varia/GratingMC.py
diff --git a/Examples/Python/sim03_Structures/Interference1DLattice.py b/Examples/Python/varia/Interference1DLattice.py
similarity index 100%
rename from Examples/Python/sim03_Structures/Interference1DLattice.py
rename to Examples/Python/varia/Interference1DLattice.py
diff --git a/Examples/Python/sim02_Complexes/LargeParticlesFormFactor.py b/Examples/Python/varia/LargeParticlesFormFactor.py
similarity index 100%
rename from Examples/Python/sim02_Complexes/LargeParticlesFormFactor.py
rename to Examples/Python/varia/LargeParticlesFormFactor.py
diff --git a/Examples/Python/sim21_Reflectometry/MaterialProfile.py b/Examples/Python/varia/MaterialProfile.py
similarity index 100%
rename from Examples/Python/sim21_Reflectometry/MaterialProfile.py
rename to Examples/Python/varia/MaterialProfile.py
diff --git a/Examples/Python/sim21_Reflectometry/MaterialProfileWithParticles.py b/Examples/Python/varia/MaterialProfileWithParticles.py
similarity index 100%
rename from Examples/Python/sim21_Reflectometry/MaterialProfileWithParticles.py
rename to Examples/Python/varia/MaterialProfileWithParticles.py
diff --git a/Examples/Python/sim11_Device/OffSpecularSimulation.py b/Examples/Python/varia/OffSpecularSimulation.py
similarity index 98%
rename from Examples/Python/sim11_Device/OffSpecularSimulation.py
rename to Examples/Python/varia/OffSpecularSimulation.py
index 7784246f726613695eafa3ba83749b7853c4cff9..495eb8923d019df0cca88c5e6b431e89b27418b0 100644
--- a/Examples/Python/sim11_Device/OffSpecularSimulation.py
+++ b/Examples/Python/varia/OffSpecularSimulation.py
@@ -57,7 +57,7 @@ def get_simulation():
     """
     Returns an off-specular simulation with beam and detector defined.
     """
-    simulation = ba.OffSpecSimulation()
+    simulation = ba.OffSpecularSimulation()
     simulation.setDetectorParameters(20, phi_f_min*deg, phi_f_max*deg, 200,
                                      alpha_f_min*deg, alpha_f_max*deg)
     # define the beam with alpha_i varied between alpha_i_min and alpha_i_max
diff --git a/Examples/Python/sim21_Reflectometry/PolarizedNoAnalyzer.py b/Examples/Python/varia/PolarizedNoAnalyzer.py
similarity index 98%
rename from Examples/Python/sim21_Reflectometry/PolarizedNoAnalyzer.py
rename to Examples/Python/varia/PolarizedNoAnalyzer.py
index 3be7294ae9257c39797f09005a7d29121cd65613..2235504c4acb7e00659ef0cc0b8f0518b3ee5e91 100644
--- a/Examples/Python/sim21_Reflectometry/PolarizedNoAnalyzer.py
+++ b/Examples/Python/varia/PolarizedNoAnalyzer.py
@@ -52,7 +52,7 @@ def run_simulation(polarization=ba.kvector_t(0.0, 1.0, 0.0), analyzer=None):
     simulation = get_simulation()
 
     # adding polarization and analyzer operator
-    simulation.setBeamPolarization(polarization)
+    simulation.beam().setPolarization(polarization)
     if analyzer:
         simulation.setAnalyzerProperties(analyzer, 1.0, 0.5)
 
diff --git a/Examples/Python/sim21_Reflectometry/PolarizedNonperfectAnalyzerPolarizer.py b/Examples/Python/varia/PolarizedNonperfectAnalyzerPolarizer.py
similarity index 98%
rename from Examples/Python/sim21_Reflectometry/PolarizedNonperfectAnalyzerPolarizer.py
rename to Examples/Python/varia/PolarizedNonperfectAnalyzerPolarizer.py
index 449294f4e1668ecc04836a64b337520e1e3cf718..9d1f7089067fcd9e6155e181652bd2d8ca85748a 100644
--- a/Examples/Python/sim21_Reflectometry/PolarizedNonperfectAnalyzerPolarizer.py
+++ b/Examples/Python/varia/PolarizedNonperfectAnalyzerPolarizer.py
@@ -81,7 +81,7 @@ def run_simulation(*,
 
     simulation = get_simulation()
 
-    simulation.setBeamPolarization(polarization*polarizer_efficiency)
+    simulation.beam().setPolarization(polarization*polarizer_efficiency)
     simulation.setAnalyzerProperties(analyzer, analyzer_efficiency, 0.5)
 
     simulation.setBackground(ba.ConstantBackground(1e-7))
diff --git a/Examples/Python/sim23_SAS/PolarizedSANS.py b/Examples/Python/varia/PolarizedSANS.py
similarity index 98%
rename from Examples/Python/sim23_SAS/PolarizedSANS.py
rename to Examples/Python/varia/PolarizedSANS.py
index 5c7f8a6f7c6cbac99e4ea1cb9928f0318e4d3782..72544844103c7bc3f7b681df218fa6df4e9bc0a5 100644
--- a/Examples/Python/sim23_SAS/PolarizedSANS.py
+++ b/Examples/Python/varia/PolarizedSANS.py
@@ -68,7 +68,7 @@ def get_simulation():
     # Defining beam polarization and polarization analysis for spin-flip channel
     analyzer_dir = kvector_t(0.0, 0.0, -1.0)
     beampol = kvector_t(0.0, 0.0, 1.0)
-    simulation.setBeamPolarization(beampol)
+    simulation.beam().setPolarization(beampol)
     simulation.setAnalyzerProperties(analyzer_dir, 1.0, 0.5)
 
     return simulation
diff --git a/Examples/Python/sim21_Reflectometry/PolarizedSpinAsymmetry.py b/Examples/Python/varia/PolarizedSpinAsymmetry.py
similarity index 99%
rename from Examples/Python/sim21_Reflectometry/PolarizedSpinAsymmetry.py
rename to Examples/Python/varia/PolarizedSpinAsymmetry.py
index 68d9a849b06db28ed3ffaf0f927c8533f80d4cae..069a4e34a79afcc62704cbc08676eff2b3e9d36d 100644
--- a/Examples/Python/sim21_Reflectometry/PolarizedSpinAsymmetry.py
+++ b/Examples/Python/varia/PolarizedSpinAsymmetry.py
@@ -91,7 +91,7 @@ def get_simulation(q_axis, parameters, polarization, analyzer):
     distr = ba.RangedDistributionGaussian(n_samples, n_sig)
     scan.setAbsoluteQResolution(distr, parameters["q_res"])
 
-    simulation.setBeamPolarization(polarization)
+    simulation.beam().setPolarization(polarization)
     simulation.setAnalyzerProperties(analyzer, 1.0, 0.5)
 
     simulation.setScan(scan)
diff --git a/Examples/Python/sim21_Reflectometry/PolarizedSpinFlip.py b/Examples/Python/varia/PolarizedSpinFlip.py
similarity index 97%
rename from Examples/Python/sim21_Reflectometry/PolarizedSpinFlip.py
rename to Examples/Python/varia/PolarizedSpinFlip.py
index 901087ebb03e3a7cdba54d300c2bdb7811e9a2e2..293c35a741cc6c0ed63556d52ac233600102bf9f 100644
--- a/Examples/Python/sim21_Reflectometry/PolarizedSpinFlip.py
+++ b/Examples/Python/varia/PolarizedSpinFlip.py
@@ -54,7 +54,7 @@ def run_simulation(polarization=ba.kvector_t(0, 1, 0),
     simulation = get_simulation()
 
     # adding polarization and analyzer operator
-    simulation.setBeamPolarization(polarization)
+    simulation.beam().setPolarization(polarization)
     simulation.setAnalyzerProperties(analyzer, 1.0, 0.5)
 
     simulation.setSample(sample)
diff --git a/Examples/Python/sim11_Device/RectangularDetector.py b/Examples/Python/varia/RectangularDetector.py
similarity index 100%
rename from Examples/Python/sim11_Device/RectangularDetector.py
rename to Examples/Python/varia/RectangularDetector.py
diff --git a/Examples/Python/sim11_Device/ResonatorOffSpecSetup.py b/Examples/Python/varia/ResonatorOffSpecSetup.py
similarity index 98%
rename from Examples/Python/sim11_Device/ResonatorOffSpecSetup.py
rename to Examples/Python/varia/ResonatorOffSpecSetup.py
index 2ea4b1cc604c01e3fe6bcc1b629c631aee5aba74..2d3a022203632101d248811b651abfed644dec2a 100644
--- a/Examples/Python/sim11_Device/ResonatorOffSpecSetup.py
+++ b/Examples/Python/varia/ResonatorOffSpecSetup.py
@@ -56,7 +56,7 @@ def get_offspec_simulation():
     """
 
     # create OffSpecular simulation
-    simulation = ba.OffSpecSimulation()
+    simulation = ba.OffSpecularSimulation()
     if not "__no_terminal__" in globals():
         simulation.setTerminalProgressMonitor()
 
diff --git a/Examples/Python/sim21_Reflectometry/RoughnessModel.py b/Examples/Python/varia/RoughnessModel.py
similarity index 100%
rename from Examples/Python/sim21_Reflectometry/RoughnessModel.py
rename to Examples/Python/varia/RoughnessModel.py
diff --git a/Examples/Python/sim31_Parameterization/SimulationParameters.py b/Examples/Python/varia/SimulationParameters.py
similarity index 100%
rename from Examples/Python/sim31_Parameterization/SimulationParameters.py
rename to Examples/Python/varia/SimulationParameters.py
diff --git a/Examples/Python/sim21_Reflectometry/SpecularSimulationWithRoughness.py b/Examples/Python/varia/SpecularSimulationWithRoughness.py
similarity index 100%
rename from Examples/Python/sim21_Reflectometry/SpecularSimulationWithRoughness.py
rename to Examples/Python/varia/SpecularSimulationWithRoughness.py
diff --git a/Fit/Adapter/GSLLevenbergMarquardtMinimizer.h b/Fit/Adapter/GSLLevenbergMarquardtMinimizer.h
index 7fa2133283f0ed7d2d5c96ec7bc1505326a155ce..05d891daa96851ee7cbd905ecb2c5cf99ebf5f51 100644
--- a/Fit/Adapter/GSLLevenbergMarquardtMinimizer.h
+++ b/Fit/Adapter/GSLLevenbergMarquardtMinimizer.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_FIT_ADAPTER_GSLLEVENBERGMARQUARDTMINIMIZER_H
 #define BORNAGAIN_FIT_ADAPTER_GSLLEVENBERGMARQUARDTMINIMIZER_H
 
@@ -64,3 +65,4 @@ private:
 };
 
 #endif // BORNAGAIN_FIT_ADAPTER_GSLLEVENBERGMARQUARDTMINIMIZER_H
+#endif // USER_API
diff --git a/Fit/Adapter/GSLMultiMinimizer.h b/Fit/Adapter/GSLMultiMinimizer.h
index 9ccf52a9489b4fe3e9e4b2bfd0330077cf8d4be8..0e1703908adcf293c32920585891cbe989d78871 100644
--- a/Fit/Adapter/GSLMultiMinimizer.h
+++ b/Fit/Adapter/GSLMultiMinimizer.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_FIT_ADAPTER_GSLMULTIMINIMIZER_H
 #define BORNAGAIN_FIT_ADAPTER_GSLMULTIMINIMIZER_H
 
@@ -54,3 +55,4 @@ private:
 };
 
 #endif // BORNAGAIN_FIT_ADAPTER_GSLMULTIMINIMIZER_H
+#endif // USER_API
diff --git a/Fit/Adapter/GeneticMinimizer.h b/Fit/Adapter/GeneticMinimizer.h
index c3a2f548e67508f1a537e974e9b89a0eb3d1982a..26194b4ec935ab7492fa631eff83c1529e0a29c7 100644
--- a/Fit/Adapter/GeneticMinimizer.h
+++ b/Fit/Adapter/GeneticMinimizer.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_FIT_ADAPTER_GENETICMINIMIZER_H
 #define BORNAGAIN_FIT_ADAPTER_GENETICMINIMIZER_H
 
@@ -71,3 +72,4 @@ private:
 };
 
 #endif // BORNAGAIN_FIT_ADAPTER_GENETICMINIMIZER_H
+#endif // USER_API
diff --git a/Fit/Adapter/IFunctionAdapter.h b/Fit/Adapter/IFunctionAdapter.h
index 2cc5ea801f27e0fd2ed86fe8c667f82d34d268a9..7d7cd3b8af59ae3af3aebc321fa8989c9c1276ba 100644
--- a/Fit/Adapter/IFunctionAdapter.h
+++ b/Fit/Adapter/IFunctionAdapter.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_FIT_ADAPTER_IFUNCTIONADAPTER_H
 #define BORNAGAIN_FIT_ADAPTER_IFUNCTIONADAPTER_H
 
@@ -40,3 +41,4 @@ protected:
 } // namespace mumufit
 
 #endif // BORNAGAIN_FIT_ADAPTER_IFUNCTIONADAPTER_H
+#endif // USER_API
diff --git a/Fit/Adapter/MinimizerAdapter.h b/Fit/Adapter/MinimizerAdapter.h
index 4127c5935b5ef30bcac97091bc525158a805c136..a778917be1d46b8562ad86a89c6f2e93db96d877 100644
--- a/Fit/Adapter/MinimizerAdapter.h
+++ b/Fit/Adapter/MinimizerAdapter.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_FIT_ADAPTER_MINIMIZERADAPTER_H
 #define BORNAGAIN_FIT_ADAPTER_MINIMIZERADAPTER_H
 
@@ -121,3 +122,4 @@ template <class T> T MinimizerAdapter::optionValue(const std::string& optionName
 }
 
 #endif // BORNAGAIN_FIT_ADAPTER_MINIMIZERADAPTER_H
+#endif // USER_API
diff --git a/Fit/Adapter/Minuit2Minimizer.h b/Fit/Adapter/Minuit2Minimizer.h
index 0784dfd33505a0b239c29abd151ad07ac674cae0..faa26e75207dd1a1458d34fbdc7be3aebe0c5c07 100644
--- a/Fit/Adapter/Minuit2Minimizer.h
+++ b/Fit/Adapter/Minuit2Minimizer.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_FIT_ADAPTER_MINUIT2MINIMIZER_H
 #define BORNAGAIN_FIT_ADAPTER_MINUIT2MINIMIZER_H
 
@@ -84,3 +85,4 @@ private:
 };
 
 #endif // BORNAGAIN_FIT_ADAPTER_MINUIT2MINIMIZER_H
+#endif // USER_API
diff --git a/Fit/Adapter/ObjectiveFunctionAdapter.h b/Fit/Adapter/ObjectiveFunctionAdapter.h
index f0513d65e08911ae27d9d5e654e774e462964477..ef1df8d348b2021f10cce3c7eddddf51e44aa1e4 100644
--- a/Fit/Adapter/ObjectiveFunctionAdapter.h
+++ b/Fit/Adapter/ObjectiveFunctionAdapter.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_FIT_ADAPTER_OBJECTIVEFUNCTIONADAPTER_H
 #define BORNAGAIN_FIT_ADAPTER_OBJECTIVEFUNCTIONADAPTER_H
 
@@ -53,3 +54,4 @@ private:
 } // namespace mumufit
 
 #endif // BORNAGAIN_FIT_ADAPTER_OBJECTIVEFUNCTIONADAPTER_H
+#endif // USER_API
diff --git a/Fit/Adapter/Report.h b/Fit/Adapter/Report.h
index e00130bf7f8a6d2e319567d8d8901f82537ddaa9..2097fc56cc6542657d0f72d7fc2ba4a691caeb12 100644
--- a/Fit/Adapter/Report.h
+++ b/Fit/Adapter/Report.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_FIT_ADAPTER_REPORT_H
 #define BORNAGAIN_FIT_ADAPTER_REPORT_H
 
@@ -33,3 +34,4 @@ std::string reportToString(const MinimizerAdapter& minimizer);
 }; // namespace mumufit::internal
 
 #endif // BORNAGAIN_FIT_ADAPTER_REPORT_H
+#endif // USER_API
diff --git a/Fit/Adapter/ResidualFunctionAdapter.h b/Fit/Adapter/ResidualFunctionAdapter.h
index 6372d89bcf1510c1a8914d27d6383a571b3cd933..b2735f57ee8a47e5b064087963b8ddfbba59bb3a 100644
--- a/Fit/Adapter/ResidualFunctionAdapter.h
+++ b/Fit/Adapter/ResidualFunctionAdapter.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_FIT_ADAPTER_RESIDUALFUNCTIONADAPTER_H
 #define BORNAGAIN_FIT_ADAPTER_RESIDUALFUNCTIONADAPTER_H
 
@@ -61,3 +62,4 @@ private:
 } //  namespace mumufit
 
 #endif // BORNAGAIN_FIT_ADAPTER_RESIDUALFUNCTIONADAPTER_H
+#endif // USER_API
diff --git a/Fit/Adapter/RootResidualFunction.h b/Fit/Adapter/RootResidualFunction.h
index bdd9b646bb4a3d54d7b7dfc832ad7b4e8756c714..828becee6a13c345a726ac86a7ab32a169899e97 100644
--- a/Fit/Adapter/RootResidualFunction.h
+++ b/Fit/Adapter/RootResidualFunction.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_FIT_ADAPTER_ROOTRESIDUALFUNCTION_H
 #define BORNAGAIN_FIT_ADAPTER_ROOTRESIDUALFUNCTION_H
 
@@ -60,3 +61,4 @@ private:
 };
 
 #endif // BORNAGAIN_FIT_ADAPTER_ROOTRESIDUALFUNCTION_H
+#endif // USER_API
diff --git a/Fit/Adapter/RootScalarFunction.h b/Fit/Adapter/RootScalarFunction.h
index df593e1739529cc23aaeb80a1c903047c2a41761..b2dce86cc960f638ddb413a2749a2702f6702922 100644
--- a/Fit/Adapter/RootScalarFunction.h
+++ b/Fit/Adapter/RootScalarFunction.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_FIT_ADAPTER_ROOTSCALARFUNCTION_H
 #define BORNAGAIN_FIT_ADAPTER_ROOTSCALARFUNCTION_H
 
@@ -39,3 +40,4 @@ public:
 };
 
 #endif // BORNAGAIN_FIT_ADAPTER_ROOTSCALARFUNCTION_H
+#endif // USER_API
diff --git a/Fit/Adapter/ScalarFunctionAdapter.h b/Fit/Adapter/ScalarFunctionAdapter.h
index 18f0d55523eadac1eddcb3282409f2f9f41bd929..7b08704545beab25daf0a4656f49da78b2d5c5cb 100644
--- a/Fit/Adapter/ScalarFunctionAdapter.h
+++ b/Fit/Adapter/ScalarFunctionAdapter.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_FIT_ADAPTER_SCALARFUNCTIONADAPTER_H
 #define BORNAGAIN_FIT_ADAPTER_SCALARFUNCTIONADAPTER_H
 
@@ -51,3 +52,4 @@ private:
 } //  namespace mumufit
 
 #endif // BORNAGAIN_FIT_ADAPTER_SCALARFUNCTIONADAPTER_H
+#endif // USER_API
diff --git a/Fit/Adapter/SimAnMinimizer.h b/Fit/Adapter/SimAnMinimizer.h
index 8e88432c366c457653649326bfe27b7908bd14e9..2fdd0c2b40f715bd25650a2f2d8136fe406d756d 100644
--- a/Fit/Adapter/SimAnMinimizer.h
+++ b/Fit/Adapter/SimAnMinimizer.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_FIT_ADAPTER_SIMANMINIMIZER_H
 #define BORNAGAIN_FIT_ADAPTER_SIMANMINIMIZER_H
 
@@ -77,3 +78,4 @@ private:
 };
 
 #endif // BORNAGAIN_FIT_ADAPTER_SIMANMINIMIZER_H
+#endif // USER_API
diff --git a/Fit/Kernel/Kernel.h b/Fit/Kernel/Kernel.h
index 2a6cee927a80273432d2671d313e6fe27c2ac28a..808759b5feab9ce07047936814c1fc0f187b06de 100644
--- a/Fit/Kernel/Kernel.h
+++ b/Fit/Kernel/Kernel.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_FIT_KERNEL_KERNEL_H
 #define BORNAGAIN_FIT_KERNEL_KERNEL_H
 
@@ -57,3 +58,4 @@ private:
 } // namespace mumufit
 
 #endif // BORNAGAIN_FIT_KERNEL_KERNEL_H
+#endif // USER_API
diff --git a/Fit/Minimizer/IMinimizer.h b/Fit/Minimizer/IMinimizer.h
index a155e9f93a00e38a7229bbec61f770f72f3c3ea6..8c6e7f7bbc8ca5e0051ca2bdd5f26c85e6be9968 100644
--- a/Fit/Minimizer/IMinimizer.h
+++ b/Fit/Minimizer/IMinimizer.h
@@ -56,7 +56,7 @@ public:
 #ifndef SWIG
     //! Returns true if minimizer computations are residual-based, false otherwise
     virtual bool requiresResiduals() { return false; }
-#endif // SWIG
+#endif // USER_API
 };
 
 #endif // BORNAGAIN_FIT_MINIMIZER_IMINIMIZER_H
diff --git a/Fit/Minimizer/MinimizerInfo.h b/Fit/Minimizer/MinimizerInfo.h
index d86ef8d2be291180b6e286843c3df5788355812b..6cd5072aee8eec71afed736aec30f0e9d8bc16a2 100644
--- a/Fit/Minimizer/MinimizerInfo.h
+++ b/Fit/Minimizer/MinimizerInfo.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_FIT_MINIMIZER_MINIMIZERINFO_H
 #define BORNAGAIN_FIT_MINIMIZER_MINIMIZERINFO_H
 
@@ -77,3 +78,4 @@ private:
 };
 
 #endif // BORNAGAIN_FIT_MINIMIZER_MINIMIZERINFO_H
+#endif // USER_API
diff --git a/Fit/Minimizer/MinimizerOptions.h b/Fit/Minimizer/MinimizerOptions.h
index f0b6110f484c6850e16ded6a87dff3982cc8e690..d8dc88fcd4db6895188e81eb7e11f7369aa0fc6b 100644
--- a/Fit/Minimizer/MinimizerOptions.h
+++ b/Fit/Minimizer/MinimizerOptions.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_FIT_MINIMIZER_MINIMIZEROPTIONS_H
 #define BORNAGAIN_FIT_MINIMIZER_MINIMIZEROPTIONS_H
 
@@ -37,3 +38,4 @@ private:
 };
 
 #endif // BORNAGAIN_FIT_MINIMIZER_MINIMIZEROPTIONS_H
+#endif // USER_API
diff --git a/Fit/Minimizer/TestMinimizer.h b/Fit/Minimizer/TestMinimizer.h
index b0708efa6ad08444b87dc0f8b9a0e3c637736747..3bb59d547c85cf1d3d25ced73c7b54570a30c7b3 100644
--- a/Fit/Minimizer/TestMinimizer.h
+++ b/Fit/Minimizer/TestMinimizer.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_FIT_MINIMIZER_TESTMINIMIZER_H
 #define BORNAGAIN_FIT_MINIMIZER_TESTMINIMIZER_H
 
@@ -40,3 +41,4 @@ private:
 };
 
 #endif // BORNAGAIN_FIT_MINIMIZER_TESTMINIMIZER_H
+#endif // USER_API
diff --git a/Fit/Minimizer/Types.h b/Fit/Minimizer/Types.h
index 976532d54df71abacd9d4e54aacf2099ff705605..ea32497d1e9dad5e0e14b1e91a8d1892f044a48e 100644
--- a/Fit/Minimizer/Types.h
+++ b/Fit/Minimizer/Types.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_FIT_MINIMIZER_TYPES_H
 #define BORNAGAIN_FIT_MINIMIZER_TYPES_H
 
@@ -39,3 +40,4 @@ using fcn_scalar_t = std::function<double(const mumufit::Parameters&)>;
 using fcn_residual_t = std::function<std::vector<double>(const mumufit::Parameters&)>;
 
 #endif // BORNAGAIN_FIT_MINIMIZER_TYPES_H
+#endif // USER_API
diff --git a/Fit/Param/Attributes.h b/Fit/Param/Attributes.h
index 580815178b6b3965573a096b69bd055d091b8a19..0d26d12fe3e48f973f08a58d51c2bc39b2e24639 100644
--- a/Fit/Param/Attributes.h
+++ b/Fit/Param/Attributes.h
@@ -12,14 +12,15 @@
 //
 //  ************************************************************************************************
 
-// Not exposed to Swig, but #include'd
+// Swig: not %include'd, but #include'd
 
+#ifndef USER_API
 #ifndef BORNAGAIN_FIT_PARAM_ATTRIBUTES_H
 #define BORNAGAIN_FIT_PARAM_ATTRIBUTES_H
 
 #include <ostream>
 
-//! Attributes for a fit parameter. Currently, the only attribute is fixed/free.
+//! %Attributes for a fit parameter. Currently, the only attribute is fixed/free.
 //! @ingroup fitting
 
 class Attributes {
@@ -58,3 +59,4 @@ inline void Attributes::print(std::ostream& ostr) const {
 }
 
 #endif // BORNAGAIN_FIT_PARAM_ATTRIBUTES_H
+#endif // USER_API
diff --git a/Fit/Param/ParameterPlan.h b/Fit/Param/ParameterPlan.h
index 3e34cb54a5bd646c049e8aef654739353d025950..d472f5dfbea4baf28fbdd75d8b27ded8f2b89907 100644
--- a/Fit/Param/ParameterPlan.h
+++ b/Fit/Param/ParameterPlan.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_FIT_PARAM_PARAMETERPLAN_H
 #define BORNAGAIN_FIT_PARAM_PARAMETERPLAN_H
 
@@ -42,3 +43,4 @@ private:
 };
 
 #endif // BORNAGAIN_FIT_PARAM_PARAMETERPLAN_H
+#endif // USER_API
diff --git a/Fit/TestEngine/IFactory.h b/Fit/TestEngine/IFactory.h
index 673a4a0d7fde197fe403efd8bbed250c9a98ff94..834d908ffb3853e5ea88b4d193ffa2d744ae4abc 100644
--- a/Fit/TestEngine/IFactory.h
+++ b/Fit/TestEngine/IFactory.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_FIT_TESTENGINE_IFACTORY_H
 #define BORNAGAIN_FIT_TESTENGINE_IFACTORY_H
 
@@ -82,3 +83,4 @@ template <class T> T* create_new() {
 } // namespace mumufit::test
 
 #endif // BORNAGAIN_FIT_TESTENGINE_IFACTORY_H
+#endif // USER_API
diff --git a/Fit/TestEngine/MinimizerTestPlan.h b/Fit/TestEngine/MinimizerTestPlan.h
index 972ccb567aea35a2bc4cb6f6ba6e07213e25bbb4..bb4e937420ea7215f49dd76a723d18b5291f457d 100644
--- a/Fit/TestEngine/MinimizerTestPlan.h
+++ b/Fit/TestEngine/MinimizerTestPlan.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_FIT_TESTENGINE_MINIMIZERTESTPLAN_H
 #define BORNAGAIN_FIT_TESTENGINE_MINIMIZERTESTPLAN_H
 
@@ -55,3 +56,4 @@ protected:
 };
 
 #endif // BORNAGAIN_FIT_TESTENGINE_MINIMIZERTESTPLAN_H
+#endif // USER_API
diff --git a/Fit/Tools/MinimizerUtils.h b/Fit/Tools/MinimizerUtils.h
index 703b5474cda70a75623c558cd62383753af4cce7..77e3fbce263d0e6c3f600dc5470991db7f38fabf 100644
--- a/Fit/Tools/MinimizerUtils.h
+++ b/Fit/Tools/MinimizerUtils.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_FIT_TOOLS_MINIMIZERUTILS_H
 #define BORNAGAIN_FIT_TOOLS_MINIMIZERUTILS_H
 
@@ -40,3 +41,4 @@ std::string sectionString(const std::string& sectionName = "", size_t report_wid
 } // namespace mumufit::utils
 
 #endif // BORNAGAIN_FIT_TOOLS_MINIMIZERUTILS_H
+#endif // USER_API
diff --git a/Fit/Tools/MultiOption.h b/Fit/Tools/MultiOption.h
index b15dc55a1206f3debfca0e18addd136d7012ec10..67d34d9db3c82ab74a9d3ba0a38218d6bfd17653 100644
--- a/Fit/Tools/MultiOption.h
+++ b/Fit/Tools/MultiOption.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_FIT_TOOLS_MULTIOPTION_H
 #define BORNAGAIN_FIT_TOOLS_MULTIOPTION_H
 
@@ -75,3 +76,4 @@ template <typename T> T MultiOption::getDefault() const {
 }
 
 #endif // BORNAGAIN_FIT_TOOLS_MULTIOPTION_H
+#endif // USER_API
diff --git a/Fit/Tools/OptionContainer.h b/Fit/Tools/OptionContainer.h
index f279bc0a1bb3ea8b531da87979be585b7720350a..106e6655fc486e378a92ec23e0bb04593fd22402 100644
--- a/Fit/Tools/OptionContainer.h
+++ b/Fit/Tools/OptionContainer.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_FIT_TOOLS_OPTIONCONTAINER_H
 #define BORNAGAIN_FIT_TOOLS_OPTIONCONTAINER_H
 
@@ -91,3 +92,4 @@ template <class T> void OptionContainer::setOptionValue(const std::string& optio
 }
 
 #endif // BORNAGAIN_FIT_TOOLS_OPTIONCONTAINER_H
+#endif // USER_API
diff --git a/Fit/Tools/StringUtils.h b/Fit/Tools/StringUtils.h
index 18212851c31479f89e2f4162cde067c3db221903..20ed0514e082f9de2b7b424af0070980fd8c6ce8 100644
--- a/Fit/Tools/StringUtils.h
+++ b/Fit/Tools/StringUtils.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_FIT_TOOLS_STRINGUTILS_H
 #define BORNAGAIN_FIT_TOOLS_STRINGUTILS_H
 
@@ -46,3 +47,4 @@ template <typename T> std::string scientific(const T value, int n) {
 } // namespace mumufit::stringUtils
 
 #endif // BORNAGAIN_FIT_TOOLS_STRINGUTILS_H
+#endif // USER_API
diff --git a/Fit/Tools/WallclockTimer.h b/Fit/Tools/WallclockTimer.h
index d8625e4bad2000b0348bb55b2e93076ca5822608..82327c5d43f0917d0b3d3396829a51bd9403cd04 100644
--- a/Fit/Tools/WallclockTimer.h
+++ b/Fit/Tools/WallclockTimer.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_FIT_TOOLS_WALLCLOCKTIMER_H
 #define BORNAGAIN_FIT_TOOLS_WALLCLOCKTIMER_H
 
@@ -41,3 +42,4 @@ private:
 };
 
 #endif // BORNAGAIN_FIT_TOOLS_WALLCLOCKTIMER_H
+#endif // USER_API
diff --git a/GUI/coregui/Models/ApplicationModels.cpp b/GUI/coregui/Models/ApplicationModels.cpp
index bdeb6cef3e39b5164ca2ad226b8691cf13683192..d73fc6ccf43277210d5f2e26d798198a36b4e549 100644
--- a/GUI/coregui/Models/ApplicationModels.cpp
+++ b/GUI/coregui/Models/ApplicationModels.cpp
@@ -13,7 +13,7 @@
 //  ************************************************************************************************
 
 #include "GUI/coregui/Models/ApplicationModels.h"
-#include "Core/Simulation/OffSpecSimulation.h"
+#include "Core/Simulation/OffSpecularSimulation.h"
 #include "Core/Simulation/StandardSimulations.h"
 #include "Device/Histo/IntensityDataIOFactory.h"
 #include "GUI/coregui/Models/DocumentModel.h"
@@ -154,7 +154,7 @@ void ApplicationModels::createTestSample() {
     GUIObjectBuilder::populateSampleModel(m_sampleModel, m_materialModel, *P_sample);
 
     // to populate InstrumentView with predefined instrument
-    const std::unique_ptr<OffSpecSimulation> simulation(StandardSimulations::MiniOffSpec());
+    const std::unique_ptr<OffSpecularSimulation> simulation(StandardSimulations::MiniOffSpecular());
     GUIObjectBuilder::populateInstrumentModel(m_instrumentModel, *simulation);
 }
 
diff --git a/GUI/coregui/Models/DomainObjectBuilder.cpp b/GUI/coregui/Models/DomainObjectBuilder.cpp
index 36f137bcfc104d49872ca06c03741dd80d7fa638..b1c7025f0525aa92571b33932d88346d1ef631e6 100644
--- a/GUI/coregui/Models/DomainObjectBuilder.cpp
+++ b/GUI/coregui/Models/DomainObjectBuilder.cpp
@@ -139,9 +139,9 @@ DomainObjectBuilder::createUnitConverter(const InstrumentItem* instrumentItem) {
     if (instrumentItem->modelType() == "GISASInstrument")
         return UnitConverterUtils::createConverterForGISAS(*instrument);
 
-    if (instrumentItem->modelType() == "OffSpecInstrument") {
+    if (instrumentItem->modelType() == "OffSpecularInstrument") {
         auto axis_item = dynamic_cast<BasicAxisItem*>(
-            instrumentItem->getItem(OffSpecInstrumentItem::P_ALPHA_AXIS));
+            instrumentItem->getItem(OffSpecularInstrumentItem::P_ALPHA_AXIS));
         const auto detector2d = dynamic_cast<const IDetector2D*>(instrument->getDetector());
         return std::make_unique<OffSpecularConverter>(*detector2d, instrument->beam(),
                                                       *axis_item->createAxis(Units::deg));
diff --git a/GUI/coregui/Models/DomainSimulationBuilder.cpp b/GUI/coregui/Models/DomainSimulationBuilder.cpp
index b544247e94ba4e0ff503150b63ecb4ab01625c64..4cd6c41a12dd8d0b8c412de6459cf6242aa7428c 100644
--- a/GUI/coregui/Models/DomainSimulationBuilder.cpp
+++ b/GUI/coregui/Models/DomainSimulationBuilder.cpp
@@ -18,7 +18,7 @@
 #include "Core/Scan/AngularSpecScan.h"
 #include "Core/Simulation/DepthProbeSimulation.h"
 #include "Core/Simulation/GISASSimulation.h"
-#include "Core/Simulation/OffSpecSimulation.h"
+#include "Core/Simulation/OffSpecularSimulation.h"
 #include "Core/Simulation/SpecularSimulation.h"
 #include "Device/Beam/IFootprintFactor.h"
 #include "GUI/coregui/Models/AxesItems.h"
@@ -40,10 +40,10 @@ std::unique_ptr<GISASSimulation> createGISASSimulation(std::unique_ptr<MultiLaye
                                                        const GISASInstrumentItem* gisasInstrument,
                                                        const SimulationOptionsItem* optionsItem);
 
-std::unique_ptr<OffSpecSimulation>
-createOffSpecSimulation(std::unique_ptr<MultiLayer> P_multilayer,
-                        const OffSpecInstrumentItem* offspecInstrument,
-                        const SimulationOptionsItem* optionsItem);
+std::unique_ptr<OffSpecularSimulation>
+createOffSpecularSimulation(std::unique_ptr<MultiLayer> P_multilayer,
+                            const OffSpecularInstrumentItem* offspecInstrument,
+                            const SimulationOptionsItem* optionsItem);
 
 std::unique_ptr<SpecularSimulation>
 createSpecularSimulation(std::unique_ptr<MultiLayer> P_multilayer,
@@ -71,8 +71,9 @@ DomainSimulationBuilder::createSimulation(const MultiLayerItem* sampleItem,
 
     if (auto gisasInstrument = dynamic_cast<const GISASInstrumentItem*>(instrumentItem))
         return createGISASSimulation(std::move(P_multilayer), gisasInstrument, optionsItem);
-    else if (auto offspecInstrument = dynamic_cast<const OffSpecInstrumentItem*>(instrumentItem))
-        return createOffSpecSimulation(std::move(P_multilayer), offspecInstrument, optionsItem);
+    else if (auto offspecInstrument =
+                 dynamic_cast<const OffSpecularInstrumentItem*>(instrumentItem))
+        return createOffSpecularSimulation(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))
@@ -107,18 +108,18 @@ std::unique_ptr<GISASSimulation> createGISASSimulation(std::unique_ptr<MultiLaye
     return ret;
 }
 
-std::unique_ptr<OffSpecSimulation>
-createOffSpecSimulation(std::unique_ptr<MultiLayer> P_multilayer,
-                        const OffSpecInstrumentItem* instrument,
-                        const SimulationOptionsItem* optionsItem) {
-    std::unique_ptr<OffSpecSimulation> ret(new OffSpecSimulation);
+std::unique_ptr<OffSpecularSimulation>
+createOffSpecularSimulation(std::unique_ptr<MultiLayer> P_multilayer,
+                            const OffSpecularInstrumentItem* instrument,
+                            const SimulationOptionsItem* optionsItem) {
+    std::unique_ptr<OffSpecularSimulation> ret(new OffSpecularSimulation);
     auto P_instrument = DomainObjectBuilder::buildInstrument(*instrument);
     ret->setSample(*P_multilayer);
     ret->setInstrument(*P_instrument);
 
     auto beamItem = instrument->beamItem();
     auto axisItem =
-        dynamic_cast<BasicAxisItem*>(instrument->getItem(OffSpecInstrumentItem::P_ALPHA_AXIS));
+        dynamic_cast<BasicAxisItem*>(instrument->getItem(OffSpecularInstrumentItem::P_ALPHA_AXIS));
     ret->setBeamParameters(beamItem->wavelength(), *axisItem->createAxis(Units::deg),
                            beamItem->getAzimuthalAngle());
 
@@ -151,7 +152,7 @@ createSpecularSimulation(std::unique_ptr<MultiLayer> P_multilayer,
 
     TransformToDomain::addBeamDivergencesToScan(*beam_item, scan);
 
-    ret->setBeamIntensity(beam_item->intensity());
+    ret->beam().setIntensity(beam_item->intensity());
     ret->setScan(scan);
 
     // ISimulation options
diff --git a/GUI/coregui/Models/GUIObjectBuilder.cpp b/GUI/coregui/Models/GUIObjectBuilder.cpp
index 0a3f6efa458ea3b7d183da8674e5353e7d520f5b..3cc8ee09b416628643145caa7a43fa887692245b 100644
--- a/GUI/coregui/Models/GUIObjectBuilder.cpp
+++ b/GUI/coregui/Models/GUIObjectBuilder.cpp
@@ -15,7 +15,7 @@
 #include "GUI/coregui/Models/GUIObjectBuilder.h"
 #include "Base/Const/Units.h"
 #include "Core/Simulation/GISASSimulation.h"
-#include "Core/Simulation/OffSpecSimulation.h"
+#include "Core/Simulation/OffSpecularSimulation.h"
 #include "Core/Simulation/SpecularSimulation.h"
 #include "GUI/coregui/Models/DocumentModel.h"
 #include "GUI/coregui/Models/GUIDomainSampleVisitor.h"
@@ -32,9 +32,9 @@ GISASInstrumentItem* createGISASInstrumentItem(InstrumentModel* model,
                                                const GISASSimulation& simulation,
                                                const QString& name);
 
-OffSpecInstrumentItem* createOffSpecInstrumentItem(InstrumentModel* model,
-                                                   const OffSpecSimulation& simulation,
-                                                   const QString& name);
+OffSpecularInstrumentItem* createOffSpecularInstrumentItem(InstrumentModel* model,
+                                                           const OffSpecularSimulation& simulation,
+                                                           const QString& name);
 
 SpecularInstrumentItem* createSpecularInstrumentItem(InstrumentModel* model,
                                                      const SpecularSimulation& simulation,
@@ -69,8 +69,8 @@ SessionItem* GUIObjectBuilder::populateInstrumentModel(InstrumentModel* p_instru
 
     if (auto gisasSimulation = dynamic_cast<const GISASSimulation*>(&simulation)) {
         return createGISASInstrumentItem(p_instrument_model, *gisasSimulation, name);
-    } else if (auto offSpecSimulation = dynamic_cast<const OffSpecSimulation*>(&simulation)) {
-        return createOffSpecInstrumentItem(p_instrument_model, *offSpecSimulation, name);
+    } else if (auto offSpecSimulation = dynamic_cast<const OffSpecularSimulation*>(&simulation)) {
+        return createOffSpecularInstrumentItem(p_instrument_model, *offSpecSimulation, name);
     } else if (auto spec_simulation = dynamic_cast<const SpecularSimulation*>(&simulation)) {
         return createSpecularInstrumentItem(p_instrument_model, *spec_simulation, name);
     }
@@ -112,17 +112,18 @@ GISASInstrumentItem* createGISASInstrumentItem(InstrumentModel* model,
     return result;
 }
 
-OffSpecInstrumentItem* createOffSpecInstrumentItem(InstrumentModel* model,
-                                                   const OffSpecSimulation& simulation,
-                                                   const QString& name) {
-    auto result = dynamic_cast<OffSpecInstrumentItem*>(model->insertNewItem("OffSpecInstrument"));
+OffSpecularInstrumentItem* createOffSpecularInstrumentItem(InstrumentModel* model,
+                                                           const OffSpecularSimulation& simulation,
+                                                           const QString& name) {
+    auto result =
+        dynamic_cast<OffSpecularInstrumentItem*>(model->insertNewItem("OffSpecularInstrument"));
 
     result->setItemName(name);
-    TransformFromDomain::setOffSpecBeamItem(result->beamItem(), simulation);
+    TransformFromDomain::setOffSpecularBeamItem(result->beamItem(), simulation);
     TransformFromDomain::setDetector(result, simulation);
     TransformFromDomain::setBackground(result, simulation);
 
-    auto axisItem = result->getItem(OffSpecInstrumentItem::P_ALPHA_AXIS);
+    auto axisItem = result->getItem(OffSpecularInstrumentItem::P_ALPHA_AXIS);
     TransformFromDomain::setAxisItem(axisItem, *simulation.beamAxis(), 1. / Units::deg);
 
     return result;
diff --git a/GUI/coregui/Models/InstrumentItems.cpp b/GUI/coregui/Models/InstrumentItems.cpp
index d4c2843a51a91319b7dde1570d27236c5f46b013..defb6a826851925ab75287a2e63d597b8d8e5775 100644
--- a/GUI/coregui/Models/InstrumentItems.cpp
+++ b/GUI/coregui/Models/InstrumentItems.cpp
@@ -30,7 +30,8 @@
 
 namespace {
 const QString background_group_label = "Type";
-const QStringList instrument_names{"GISASInstrument", "OffSpecInstrument", "SpecularInstrument"};
+const QStringList instrument_names{"GISASInstrument", "OffSpecularInstrument",
+                                   "SpecularInstrument"};
 void addAxisGroupProperty(SessionItem* parent, const QString& tag);
 } // namespace
 
@@ -219,9 +220,9 @@ void GISASInstrumentItem::updateToRealData(const RealDataItem* item) {
     detectorItem()->setYSize(data_shape[1]);
 }
 
-const QString OffSpecInstrumentItem::P_ALPHA_AXIS = "Alpha axis";
+const QString OffSpecularInstrumentItem::P_ALPHA_AXIS = "Alpha axis";
 
-OffSpecInstrumentItem::OffSpecInstrumentItem() : Instrument2DItem("OffSpecInstrument") {
+OffSpecularInstrumentItem::OffSpecularInstrumentItem() : Instrument2DItem("OffSpecularInstrument") {
     addAxisGroupProperty(this, P_ALPHA_AXIS);
     auto inclination_item = getItem(P_ALPHA_AXIS)->getItem(BasicAxisItem::P_MIN_DEG);
     auto beam_item = beamItem();
@@ -232,21 +233,21 @@ OffSpecInstrumentItem::OffSpecInstrumentItem() : Instrument2DItem("OffSpecInstru
     });
 }
 
-std::vector<int> OffSpecInstrumentItem::shape() const {
+std::vector<int> OffSpecularInstrumentItem::shape() const {
     const int x_size = getItem(P_ALPHA_AXIS)->getItemValue(BasicAxisItem::P_NBINS).toInt();
     auto detector_item = detectorItem();
     return {x_size, detector_item->ySize()};
 }
 
-void OffSpecInstrumentItem::updateToRealData(const RealDataItem* item) {
+void OffSpecularInstrumentItem::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::updateToRealData: The type of "
+        throw GUIHelpers::Error("Error in OffSpecularInstrumentItem::updateToRealData: The type of "
                                 "instrument is incompatible with passed data shape.");
-    getItem(OffSpecInstrumentItem::P_ALPHA_AXIS)
+    getItem(OffSpecularInstrumentItem::P_ALPHA_AXIS)
         ->setItemValue(BasicAxisItem::P_NBINS, data_shape[0]);
     detectorItem()->setYSize(data_shape[1]);
 }
diff --git a/GUI/coregui/Models/InstrumentItems.h b/GUI/coregui/Models/InstrumentItems.h
index 2356174e73f0e037fa445c534d89d4e9035c22da..92f369b213918ff0e68a4915021d44f36d0ebcbc 100644
--- a/GUI/coregui/Models/InstrumentItems.h
+++ b/GUI/coregui/Models/InstrumentItems.h
@@ -94,11 +94,11 @@ public:
     void updateToRealData(const RealDataItem* item) override;
 };
 
-class BA_CORE_API_ OffSpecInstrumentItem : public Instrument2DItem {
+class BA_CORE_API_ OffSpecularInstrumentItem : public Instrument2DItem {
 public:
     static const QString P_ALPHA_AXIS;
 
-    OffSpecInstrumentItem();
+    OffSpecularInstrumentItem();
     std::vector<int> shape() const override;
     void updateToRealData(const RealDataItem* item) override;
 };
diff --git a/GUI/coregui/Models/ItemCatalog.cpp b/GUI/coregui/Models/ItemCatalog.cpp
index 603146535ef3d0e7d99235ea83bba3033353985c..f57306e34d6a2acfa676e78faaff4403ba229eae 100644
--- a/GUI/coregui/Models/ItemCatalog.cpp
+++ b/GUI/coregui/Models/ItemCatalog.cpp
@@ -79,7 +79,7 @@ ItemCatalog::ItemCatalog() {
     add("InterferenceHardDisk", create_new<InterferenceFunctionHardDiskItem>);
     add("InterferenceRadialParaCrystal", create_new<InterferenceFunctionRadialParaCrystalItem>);
     add("GISASInstrument", create_new<GISASInstrumentItem>);
-    add("OffSpecInstrument", create_new<OffSpecInstrumentItem>);
+    add("OffSpecularInstrument", create_new<OffSpecularInstrumentItem>);
     add("SpecularInstrument", create_new<SpecularInstrumentItem>);
     add("GISASBeam", create_new<GISASBeamItem>);
     add("SpecularBeam", create_new<SpecularBeamItem>);
diff --git a/GUI/coregui/Models/JobItem.cpp b/GUI/coregui/Models/JobItem.cpp
index bc75abbc8b1bd8b89c685a630cdf8923c775a53d..78188a3362248e59f2629acc5e0fa0140d5896ae 100644
--- a/GUI/coregui/Models/JobItem.cpp
+++ b/GUI/coregui/Models/JobItem.cpp
@@ -73,7 +73,7 @@ JobItem::JobItem() : SessionItem("JobItem") {
     registerTag(T_MATERIAL_CONTAINER, 1, 1, QStringList{"MaterialContainer"});
     registerTag(T_INSTRUMENT, 1, 1,
                 QStringList() << "GISASInstrument"
-                              << "OffSpecInstrument"
+                              << "OffSpecularInstrument"
                               << "SpecularInstrument"
                               << "DepthProbeInstrument");
     registerTag(T_OUTPUT, 1, 1,
diff --git a/GUI/coregui/Models/JobModelFunctions.cpp b/GUI/coregui/Models/JobModelFunctions.cpp
index 079b42f5edaf6815b55757da42009c91d0ad6384..630940be8b8304fc6bb01fb1f3905169f7e38f7f 100644
--- a/GUI/coregui/Models/JobModelFunctions.cpp
+++ b/GUI/coregui/Models/JobModelFunctions.cpp
@@ -142,7 +142,7 @@ void JobModelFunctions::setupJobItemOutput(JobItem* jobItem) {
     if (instrumentType == "SpecularInstrument") {
         model->insertNewItem("SpecularData", model->indexOfItem(jobItem), -1, JobItem::T_OUTPUT);
 
-    } else if (instrumentType == "GISASInstrument" || instrumentType == "OffSpecInstrument"
+    } else if (instrumentType == "GISASInstrument" || instrumentType == "OffSpecularInstrument"
                || instrumentType == "DepthProbeInstrument") {
         model->insertNewItem("IntensityData", model->indexOfItem(jobItem), -1, JobItem::T_OUTPUT);
 
diff --git a/GUI/coregui/Models/RealDataItem.cpp b/GUI/coregui/Models/RealDataItem.cpp
index 71f3d6f0b0622f0ccacd4068afe618e646176484..65041518756918af10311a0db057643039597c63 100644
--- a/GUI/coregui/Models/RealDataItem.cpp
+++ b/GUI/coregui/Models/RealDataItem.cpp
@@ -97,8 +97,9 @@ void RealDataItem::setOutputData(OutputData<double>* data) {
     ASSERT(data && "Assertion failed in RealDataItem::setOutputData: passed data is nullptr");
     ASSERT(data->rank() < 3 && data->rank() > 0);
 
-    const QString& target_model_type =
-        data->rank() == 2 ? "IntensityData" : data->rank() == 1 ? "SpecularData" : "";
+    const QString& target_model_type = data->rank() == 2   ? "IntensityData"
+                                       : data->rank() == 1 ? "SpecularData"
+                                                           : "";
     auto data_item = getItem(T_INTENSITY_DATA);
     if (data_item && data_item->modelType() != target_model_type)
         throw GUIHelpers::Error("Error in RealDataItem::setOutputData: trying to set data "
diff --git a/GUI/coregui/Models/SessionDecorationModel.cpp b/GUI/coregui/Models/SessionDecorationModel.cpp
index 4efd79e2a1c9f66bf9ccbf0a99ee45f2f4bf1f71..18be6250a85629486242d97a3eefb27172d5399e 100644
--- a/GUI/coregui/Models/SessionDecorationModel.cpp
+++ b/GUI/coregui/Models/SessionDecorationModel.cpp
@@ -62,7 +62,7 @@ QVariant itemIcon(const SessionItem* item) {
     if (modelType == "GISASInstrument") {
         return QVariant(icons.gisasIcon);
 
-    } else if (modelType == "OffSpecInstrument") {
+    } else if (modelType == "OffSpecularInstrument") {
         return QVariant(icons.offspecIcon);
 
     } else if (modelType == "SpecularInstrument") {
diff --git a/GUI/coregui/Models/TransformFromDomain.cpp b/GUI/coregui/Models/TransformFromDomain.cpp
index c0d4d35552fc31a7ed79594dc335f8f4aa47a6a0..e74ed7f5ff79d3d17186178363be0e0a7a3e8c67 100644
--- a/GUI/coregui/Models/TransformFromDomain.cpp
+++ b/GUI/coregui/Models/TransformFromDomain.cpp
@@ -19,7 +19,7 @@
 #include "Core/Export/NodeProgeny.h"
 #include "Core/Scan/AngularSpecScan.h"
 #include "Core/Simulation/GISASSimulation.h"
-#include "Core/Simulation/OffSpecSimulation.h"
+#include "Core/Simulation/OffSpecularSimulation.h"
 #include "Core/Simulation/SpecularSimulation.h"
 #include "Device/Beam/FootprintGauss.h"
 #include "Device/Beam/FootprintSquare.h"
@@ -251,8 +251,8 @@ void TransformFromDomain::setGISASBeamItem(BeamItem* beam_item, const GISASSimul
     SetVectorItem(*beam_item, BeamItem::P_POLARIZATION, beam.getBlochVector());
 }
 
-void TransformFromDomain::setOffSpecBeamItem(BeamItem* beam_item,
-                                             const OffSpecSimulation& simulation) {
+void TransformFromDomain::setOffSpecularBeamItem(BeamItem* beam_item,
+                                                 const OffSpecularSimulation& simulation) {
     Beam beam = simulation.instrument().beam();
 
     beam_item->setIntensity(beam.intensity());
diff --git a/GUI/coregui/Models/TransformFromDomain.h b/GUI/coregui/Models/TransformFromDomain.h
index f7013f297fd0d7fd512d3b9f0aed5b6d9c8a05af..71e01aeb1b7bf547b4b064f5602d20f84679a02d 100644
--- a/GUI/coregui/Models/TransformFromDomain.h
+++ b/GUI/coregui/Models/TransformFromDomain.h
@@ -47,7 +47,7 @@ class GISASInstrumentItem;
 class Instrument2DItem;
 class InstrumentItem;
 class ISimulation2D;
-class OffSpecSimulation;
+class OffSpecularSimulation;
 class IAxis;
 
 namespace TransformFromDomain {
@@ -74,7 +74,7 @@ bool isValidRoughness(const LayerRoughness* roughness);
 
 void setGISASBeamItem(BeamItem* beam_item, const GISASSimulation& simulation);
 
-void setOffSpecBeamItem(BeamItem* beam_item, const OffSpecSimulation& simulation);
+void setOffSpecularBeamItem(BeamItem* beam_item, const OffSpecularSimulation& simulation);
 
 void setSpecularBeamItem(SpecularBeamItem* beam_item, const SpecularSimulation& simulation);
 
diff --git a/GUI/coregui/Views/FitWidgets/FitComparisonController.cpp b/GUI/coregui/Views/FitWidgets/FitComparisonController.cpp
index e97d4ad21f7aa9b1c11dc16310996a79fd3d89f2..41fdc1e30945c23bdce446b3a0b48f1f65eb180c 100644
--- a/GUI/coregui/Views/FitWidgets/FitComparisonController.cpp
+++ b/GUI/coregui/Views/FitWidgets/FitComparisonController.cpp
@@ -13,7 +13,7 @@
 //  ************************************************************************************************
 
 #include "GUI/coregui/Views/FitWidgets/FitComparisonController.h"
-#include "Device/Instrument/IntensityDataFunctions.h"
+#include "Device/Data/DataUtils.h"
 #include "GUI/coregui/Models/AxesItems.h"
 #include "GUI/coregui/Models/IntensityDataItem.h"
 #include "GUI/coregui/Models/JobItem.h"
@@ -143,8 +143,8 @@ void DiffItemController::updateDiffData() {
     if (!sim_data->getOutputData()) // job failed
         return;
 
-    m_diff_item->setOutputData(IntensityDataFunctions::createRelativeDifferenceData(
-                                   *sim_data->getOutputData(), *real_data->getOutputData())
+    m_diff_item->setOutputData(DataUtils::createRelativeDifferenceData(*sim_data->getOutputData(),
+                                                                       *real_data->getOutputData())
                                    .release());
 }
 
diff --git a/GUI/coregui/Views/FitWidgets/FitComparisonViewController.cpp b/GUI/coregui/Views/FitWidgets/FitComparisonViewController.cpp
index 8fe189cc4475918ac9fc02ff1a2d607c993894b7..67538c1adf6cefb26038bf8c85f5911baf99bfc0 100644
--- a/GUI/coregui/Views/FitWidgets/FitComparisonViewController.cpp
+++ b/GUI/coregui/Views/FitWidgets/FitComparisonViewController.cpp
@@ -13,7 +13,7 @@
 //  ************************************************************************************************
 
 #include "GUI/coregui/Views/FitWidgets/FitComparisonViewController.h"
-#include "Device/Instrument/IntensityDataFunctions.h"
+#include "Device/Data/DataUtils.h"
 #include "GUI/coregui/Models/AxesItems.h"
 #include "GUI/coregui/Models/Data1DViewItem.h"
 #include "GUI/coregui/Models/DataItem.h"
@@ -132,8 +132,8 @@ void DiffItemController::updateDiffData() {
     if (!sim_data->getOutputData()) // job failed
         return;
 
-    m_diff_item->setOutputData(IntensityDataFunctions::createRelativeDifferenceData(
-                                   *sim_data->getOutputData(), *real_data->getOutputData())
+    m_diff_item->setOutputData(DataUtils::createRelativeDifferenceData(*sim_data->getOutputData(),
+                                                                       *real_data->getOutputData())
                                    .release());
 }
 
diff --git a/GUI/coregui/Views/ImportDataWidgets/RealDataSelectorActions.cpp b/GUI/coregui/Views/ImportDataWidgets/RealDataSelectorActions.cpp
index 1c5d5b0904206a5ea6b0264a55aa21a7814b91fa..53d88a4d835f9f6cebaff9d2c36cda0a57a50e2c 100644
--- a/GUI/coregui/Views/ImportDataWidgets/RealDataSelectorActions.cpp
+++ b/GUI/coregui/Views/ImportDataWidgets/RealDataSelectorActions.cpp
@@ -13,7 +13,7 @@
 //  ************************************************************************************************
 
 #include "GUI/coregui/Views/ImportDataWidgets/RealDataSelectorActions.h"
-#include "Device/Instrument/IntensityDataFunctions.h"
+#include "Device/Data/DataUtils.h"
 #include "GUI/coregui/Models/IntensityDataItem.h"
 #include "GUI/coregui/Models/MaskItems.h"
 #include "GUI/coregui/Models/ProjectionItems.h"
@@ -202,8 +202,7 @@ void RealDataSelectorActions::onRotateDataRequest() {
 
     QApplication::setOverrideCursor(Qt::WaitCursor);
     const auto input = intensityItem->getOutputData();
-    intensityItem->setOutputData(
-        IntensityDataFunctions::createRearrangedDataSet(*input, 1).release());
+    intensityItem->setOutputData(DataUtils::createRearrangedDataSet(*input, 1).release());
     intensityItem->setAxesRangeToData();
 
     m_selectionModel->select(currentIndex, QItemSelectionModel::Select);
diff --git a/GUI/coregui/Views/InstrumentWidgets/InstrumentPresenter.cpp b/GUI/coregui/Views/InstrumentWidgets/InstrumentPresenter.cpp
index 1bc37d8cd46e03829924eca8ea9750c0ee2cc7df..4615b4bd1ada39c195c489f0319ffdb549fb995a 100644
--- a/GUI/coregui/Views/InstrumentWidgets/InstrumentPresenter.cpp
+++ b/GUI/coregui/Views/InstrumentWidgets/InstrumentPresenter.cpp
@@ -16,20 +16,20 @@
 #include "GUI/coregui/Models/SessionItem.h"
 #include "GUI/coregui/Views/InstrumentWidgets/DepthProbeInstrumentEditor.h"
 #include "GUI/coregui/Views/InstrumentWidgets/GISASInstrumentEditor.h"
-#include "GUI/coregui/Views/InstrumentWidgets/OffSpecInstrumentEditor.h"
+#include "GUI/coregui/Views/InstrumentWidgets/OffSpecularInstrumentEditor.h"
 #include "GUI/coregui/Views/InstrumentWidgets/SpecularInstrumentEditor.h"
 #include "GUI/coregui/utils/GUIHelpers.h"
 
 namespace {
 const QString GISASPresentation = "GISAS";
-const QString OffSpecPresentation = "OffSpec";
+const QString OffSpecularPresentation = "OffSpecular";
 const QString SpecularPresentation = "Specular";
 const QString DepthProbePresentation = "DepthProbe";
 } // namespace
 
 InstrumentPresenter::InstrumentPresenter(QWidget* parent) : ItemComboWidget(parent) {
     registerWidget(GISASPresentation, create_new<GISASInstrumentEditor>);
-    registerWidget(OffSpecPresentation, create_new<OffSpecInstrumentEditor>);
+    registerWidget(OffSpecularPresentation, create_new<OffSpecularInstrumentEditor>);
     registerWidget(SpecularPresentation, create_new<SpecularInstrumentEditor>);
     registerWidget(DepthProbePresentation, create_new<DepthProbeInstrumentEditor>);
     setToolBarVisible(false);
@@ -41,8 +41,8 @@ QString InstrumentPresenter::itemPresentation() const {
 
     if (currentItem()->modelType() == "GISASInstrument")
         return GISASPresentation;
-    else if (currentItem()->modelType() == "OffSpecInstrument")
-        return OffSpecPresentation;
+    else if (currentItem()->modelType() == "OffSpecularInstrument")
+        return OffSpecularPresentation;
     else if (currentItem()->modelType() == "SpecularInstrument")
         return SpecularPresentation;
     else if (currentItem()->modelType() == "DepthProbeInstrument")
@@ -55,6 +55,6 @@ QString InstrumentPresenter::itemPresentation() const {
 
 QStringList InstrumentPresenter::activePresentationList(SessionItem* item) {
     Q_UNUSED(item);
-    return QStringList() << GISASPresentation << OffSpecPresentation << SpecularPresentation
+    return QStringList() << GISASPresentation << OffSpecularPresentation << SpecularPresentation
                          << DepthProbePresentation;
 }
diff --git a/GUI/coregui/Views/InstrumentWidgets/InstrumentPresenter.h b/GUI/coregui/Views/InstrumentWidgets/InstrumentPresenter.h
index 885e5bbfe87fc1ea00545b6d21b6c73b779dac60..5c42ebc39b36cdf0beb2219b7d52ac7240805f72 100644
--- a/GUI/coregui/Views/InstrumentWidgets/InstrumentPresenter.h
+++ b/GUI/coregui/Views/InstrumentWidgets/InstrumentPresenter.h
@@ -18,7 +18,7 @@
 #include "GUI/coregui/Views/CommonWidgets/ItemComboWidget.h"
 
 //! Contains stack of instrument editors and the logic to show proper editor for certain type
-//! of instrument (GISAS, OffSpec and Specular). Main component of InstrumentEditorWidget.
+//! of instrument (GISAS, OffSpecular and Specular). Main component of InstrumentEditorWidget.
 
 class InstrumentPresenter : public ItemComboWidget {
     Q_OBJECT
diff --git a/GUI/coregui/Views/InstrumentWidgets/InstrumentViewActions.cpp b/GUI/coregui/Views/InstrumentWidgets/InstrumentViewActions.cpp
index 9a64d8040ec0bb6c0dba4311b11db3a696955052..613b203689946f599a9db4c714a189e5c15560e1 100644
--- a/GUI/coregui/Views/InstrumentWidgets/InstrumentViewActions.cpp
+++ b/GUI/coregui/Views/InstrumentWidgets/InstrumentViewActions.cpp
@@ -75,9 +75,9 @@ void InstrumentViewActions::onAddInstrument() {
     if (instrumentType == "GISASInstrument") {
         auto instrument = m_model->insertNewItem(instrumentType);
         instrument->setItemName(suggestInstrumentName("GISAS"));
-    } else if (instrumentType == "OffSpecInstrument") {
+    } else if (instrumentType == "OffSpecularInstrument") {
         auto instrument = m_model->insertNewItem(instrumentType);
-        instrument->setItemName(suggestInstrumentName("OffSpec"));
+        instrument->setItemName(suggestInstrumentName("OffSpecular"));
     } else if (instrumentType == "SpecularInstrument") {
         auto instrument = m_model->insertNewItem(instrumentType);
         instrument->setItemName(suggestInstrumentName("Specular"));
@@ -211,9 +211,9 @@ void InstrumentViewActions::initAddInstrumentMenu() {
     connect(action, &QAction::triggered, this, &InstrumentViewActions::onAddInstrument);
     m_addInstrumentMenu->setDefaultAction(action);
 
-    action = m_addInstrumentMenu->addAction("OffSpec");
-    action->setData(QVariant::fromValue(QString{"OffSpecInstrument"}));
-    action->setToolTip("Add OffSpec instrument with default settings");
+    action = m_addInstrumentMenu->addAction("OffSpecular");
+    action->setData(QVariant::fromValue(QString{"OffSpecularInstrument"}));
+    action->setToolTip("Add OffSpecular instrument with default settings");
     connect(action, &QAction::triggered, this, &InstrumentViewActions::onAddInstrument);
 
     action = m_addInstrumentMenu->addAction("Specular");
diff --git a/GUI/coregui/Views/InstrumentWidgets/OffSpecBeamEditor.cpp b/GUI/coregui/Views/InstrumentWidgets/OffSpecularBeamEditor.cpp
similarity index 77%
rename from GUI/coregui/Views/InstrumentWidgets/OffSpecBeamEditor.cpp
rename to GUI/coregui/Views/InstrumentWidgets/OffSpecularBeamEditor.cpp
index 3b310285a52c89186abf805b9aaac40883c9077d..942d0429ca64a818135a0199fbfe64279b5acb4e 100644
--- a/GUI/coregui/Views/InstrumentWidgets/OffSpecBeamEditor.cpp
+++ b/GUI/coregui/Views/InstrumentWidgets/OffSpecularBeamEditor.cpp
@@ -2,8 +2,8 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      GUI/coregui/Views/InstrumentWidgets/OffSpecBeamEditor.cpp
-//! @brief     Implements class OffSpecBeamEditor
+//! @file      GUI/coregui/Views/InstrumentWidgets/OffSpecularBeamEditor.cpp
+//! @brief     Implements class OffSpecularBeamEditor
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -12,7 +12,7 @@
 //
 //  ************************************************************************************************
 
-#include "GUI/coregui/Views/InstrumentWidgets/OffSpecBeamEditor.h"
+#include "GUI/coregui/Views/InstrumentWidgets/OffSpecularBeamEditor.h"
 #include "GUI/coregui/Models/BeamDistributionItem.h"
 #include "GUI/coregui/Models/InstrumentItems.h"
 #include "GUI/coregui/Views/CommonWidgets/ColumnResizer.h"
@@ -28,7 +28,7 @@ const QString azimuthal_title("Azimuthal angle [deg]");
 const QString polarization_title("Polarization (Bloch vector)");
 } // namespace
 
-OffSpecBeamEditor::OffSpecBeamEditor(ColumnResizer* columnResizer, QWidget* parent)
+OffSpecularBeamEditor::OffSpecularBeamEditor(ColumnResizer* columnResizer, QWidget* parent)
     : SessionItemWidget(parent)
     , m_columnResizer(columnResizer)
     , m_intensityEditor(new ComponentEditor(ComponentEditor::PlainWidget))
@@ -47,48 +47,48 @@ OffSpecBeamEditor::OffSpecBeamEditor(ColumnResizer* columnResizer, QWidget* pare
     setLayout(mainLayout);
 
     connect(m_wavelengthEditor, &ComponentEditor::dialogRequest, this,
-            &OffSpecBeamEditor::onDialogRequest);
+            &OffSpecularBeamEditor::onDialogRequest);
     connect(m_inclinationEditor, &ComponentEditor::dialogRequest, this,
-            &OffSpecBeamEditor::onDialogRequest);
+            &OffSpecularBeamEditor::onDialogRequest);
     connect(m_azimuthalEditor, &ComponentEditor::dialogRequest, this,
-            &OffSpecBeamEditor::onDialogRequest);
+            &OffSpecularBeamEditor::onDialogRequest);
 
     m_columnResizer->addWidgetsFromGridLayout(m_gridLayout, 0);
     m_columnResizer->addWidgetsFromGridLayout(m_gridLayout, 1);
     m_columnResizer->addWidgetsFromGridLayout(m_gridLayout, 2);
 }
 
-void OffSpecBeamEditor::subscribeToItem() {
+void OffSpecularBeamEditor::subscribeToItem() {
     m_intensityEditor->setItem(beamItem()->getItem(BeamItem::P_INTENSITY));
 
     auto wavelengthItem = beamItem()->getItem(BeamItem::P_WAVELENGTH);
     m_wavelengthEditor->setItem(wavelengthItem->getItem(BeamDistributionItem::P_DISTRIBUTION));
 
-    auto inclinationItem = instrumentItem()->getItem(OffSpecInstrumentItem::P_ALPHA_AXIS);
+    auto inclinationItem = instrumentItem()->getItem(OffSpecularInstrumentItem::P_ALPHA_AXIS);
     m_inclinationEditor->setItem(inclinationItem);
 
     auto azimuthalItem = beamItem()->getItem(BeamItem::P_AZIMUTHAL_ANGLE);
     m_azimuthalEditor->setItem(azimuthalItem->getItem(BeamDistributionItem::P_DISTRIBUTION));
 }
 
-void OffSpecBeamEditor::unsubscribeFromItem() {
+void OffSpecularBeamEditor::unsubscribeFromItem() {
     m_intensityEditor->clearEditor();
     m_wavelengthEditor->clearEditor();
     m_inclinationEditor->clearEditor();
     m_azimuthalEditor->clearEditor();
 }
 
-OffSpecInstrumentItem* OffSpecBeamEditor::instrumentItem() {
-    auto result = dynamic_cast<OffSpecInstrumentItem*>(currentItem());
+OffSpecularInstrumentItem* OffSpecularBeamEditor::instrumentItem() {
+    auto result = dynamic_cast<OffSpecularInstrumentItem*>(currentItem());
     ASSERT(result);
     return result;
 }
 
-BeamItem* OffSpecBeamEditor::beamItem() {
+BeamItem* OffSpecularBeamEditor::beamItem() {
     return instrumentItem()->beamItem();
 }
 
-void OffSpecBeamEditor::onDialogRequest(SessionItem* item, const QString& name) {
+void OffSpecularBeamEditor::onDialogRequest(SessionItem* item, const QString& name) {
     if (!item)
         return;
 
diff --git a/GUI/coregui/Views/InstrumentWidgets/OffSpecBeamEditor.h b/GUI/coregui/Views/InstrumentWidgets/OffSpecularBeamEditor.h
similarity index 65%
rename from GUI/coregui/Views/InstrumentWidgets/OffSpecBeamEditor.h
rename to GUI/coregui/Views/InstrumentWidgets/OffSpecularBeamEditor.h
index 87d9c50a6bcc711f0e6c3a7adb81687e78cfe276..ee241397ef733d46a3eb2b44530cbf149afa3b7e 100644
--- a/GUI/coregui/Views/InstrumentWidgets/OffSpecBeamEditor.h
+++ b/GUI/coregui/Views/InstrumentWidgets/OffSpecularBeamEditor.h
@@ -2,8 +2,8 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      GUI/coregui/Views/InstrumentWidgets/OffSpecBeamEditor.h
-//! @brief     Defines class OffSpecBeamEditor
+//! @file      GUI/coregui/Views/InstrumentWidgets/OffSpecularBeamEditor.h
+//! @brief     Defines class OffSpecularBeamEditor
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -12,31 +12,31 @@
 //
 //  ************************************************************************************************
 
-#ifndef BORNAGAIN_GUI_COREGUI_VIEWS_INSTRUMENTWIDGETS_OFFSPECBEAMEDITOR_H
-#define BORNAGAIN_GUI_COREGUI_VIEWS_INSTRUMENTWIDGETS_OFFSPECBEAMEDITOR_H
+#ifndef BORNAGAIN_GUI_COREGUI_VIEWS_INSTRUMENTWIDGETS_OFFSPECULARBEAMEDITOR_H
+#define BORNAGAIN_GUI_COREGUI_VIEWS_INSTRUMENTWIDGETS_OFFSPECULARBEAMEDITOR_H
 
 #include "GUI/coregui/Views/CommonWidgets/SessionItemWidget.h"
 
 class ComponentEditor;
 class QGridLayout;
-class OffSpecInstrumentItem;
+class OffSpecularInstrumentItem;
 class BeamItem;
 class ColumnResizer;
 
 //! GISAS beam editor. Operates on GISASInstrumentItem.
 
-class OffSpecBeamEditor : public SessionItemWidget {
+class OffSpecularBeamEditor : public SessionItemWidget {
     Q_OBJECT
 
 public:
-    explicit OffSpecBeamEditor(ColumnResizer* columnResizer, QWidget* parent = nullptr);
+    explicit OffSpecularBeamEditor(ColumnResizer* columnResizer, QWidget* parent = nullptr);
 
 protected:
     void subscribeToItem();
     void unsubscribeFromItem();
 
 private:
-    OffSpecInstrumentItem* instrumentItem();
+    OffSpecularInstrumentItem* instrumentItem();
     BeamItem* beamItem();
     void onDialogRequest(SessionItem* item, const QString& name);
 
@@ -48,4 +48,4 @@ private:
     QGridLayout* m_gridLayout;
 };
 
-#endif // BORNAGAIN_GUI_COREGUI_VIEWS_INSTRUMENTWIDGETS_OFFSPECBEAMEDITOR_H
+#endif // BORNAGAIN_GUI_COREGUI_VIEWS_INSTRUMENTWIDGETS_OFFSPECULARBEAMEDITOR_H
diff --git a/GUI/coregui/Views/InstrumentWidgets/OffSpecInstrumentEditor.cpp b/GUI/coregui/Views/InstrumentWidgets/OffSpecularInstrumentEditor.cpp
similarity index 74%
rename from GUI/coregui/Views/InstrumentWidgets/OffSpecInstrumentEditor.cpp
rename to GUI/coregui/Views/InstrumentWidgets/OffSpecularInstrumentEditor.cpp
index 5a83492af0c10b0848d78fadcaf9669440a8c4ca..0f11d05d0f7436796b482714f1f96b90af18f097 100644
--- a/GUI/coregui/Views/InstrumentWidgets/OffSpecInstrumentEditor.cpp
+++ b/GUI/coregui/Views/InstrumentWidgets/OffSpecularInstrumentEditor.cpp
@@ -2,8 +2,8 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      GUI/coregui/Views/InstrumentWidgets/OffSpecInstrumentEditor.cpp
-//! @brief     Implements class OffSpecInstrumentEditor
+//! @file      GUI/coregui/Views/InstrumentWidgets/OffSpecularInstrumentEditor.cpp
+//! @brief     Implements class OffSpecularInstrumentEditor
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -12,20 +12,20 @@
 //
 //  ************************************************************************************************
 
-#include "GUI/coregui/Views/InstrumentWidgets/OffSpecInstrumentEditor.h"
+#include "GUI/coregui/Views/InstrumentWidgets/OffSpecularInstrumentEditor.h"
 #include "GUI/coregui/Models/InstrumentItems.h"
 #include "GUI/coregui/Views/CommonWidgets/ColumnResizer.h"
 #include "GUI/coregui/Views/InstrumentWidgets/EnvironmentEditor.h"
 #include "GUI/coregui/Views/InstrumentWidgets/GISASDetectorEditor.h"
-#include "GUI/coregui/Views/InstrumentWidgets/OffSpecBeamEditor.h"
+#include "GUI/coregui/Views/InstrumentWidgets/OffSpecularBeamEditor.h"
 #include "GUI/coregui/Views/InstrumentWidgets/PolarizationAnalysisEditor.h"
 #include "GUI/coregui/utils/StyleUtils.h"
 #include <QVBoxLayout>
 
-OffSpecInstrumentEditor::OffSpecInstrumentEditor(QWidget* parent)
+OffSpecularInstrumentEditor::OffSpecularInstrumentEditor(QWidget* parent)
     : SessionItemWidget(parent)
     , m_columnResizer(new ColumnResizer(this))
-    , m_beamEditor(new OffSpecBeamEditor(m_columnResizer))
+    , m_beamEditor(new OffSpecularBeamEditor(m_columnResizer))
     , m_detectorEditor(new GISASDetectorEditor)
     // temporary switched off to avoid memory leakage
     //, m_environmentEditor(new EnvironmentEditor(m_columnResizer))
@@ -41,15 +41,15 @@ OffSpecInstrumentEditor::OffSpecInstrumentEditor(QWidget* parent)
     setLayout(mainLayout);
 }
 
-void OffSpecInstrumentEditor::subscribeToItem() {
+void OffSpecularInstrumentEditor::subscribeToItem() {
     m_beamEditor->setItem(instrumentItem());
     m_detectorEditor->setItem(instrumentItem());
     //    m_environmentEditor->setItem(instrumentItem());
     //    m_polarizationAnalysisEditor->setItem(instrumentItem());
 }
 
-OffSpecInstrumentItem* OffSpecInstrumentEditor::instrumentItem() {
-    auto result = dynamic_cast<OffSpecInstrumentItem*>(currentItem());
+OffSpecularInstrumentItem* OffSpecularInstrumentEditor::instrumentItem() {
+    auto result = dynamic_cast<OffSpecularInstrumentItem*>(currentItem());
     ASSERT(result);
     return result;
 }
diff --git a/GUI/coregui/Views/InstrumentWidgets/OffSpecInstrumentEditor.h b/GUI/coregui/Views/InstrumentWidgets/OffSpecularInstrumentEditor.h
similarity index 58%
rename from GUI/coregui/Views/InstrumentWidgets/OffSpecInstrumentEditor.h
rename to GUI/coregui/Views/InstrumentWidgets/OffSpecularInstrumentEditor.h
index 18ccc5fd818a41c196423687aa8f923a30875b04..8ddaf9de2776f9f7e1003e4513764577d6acc885 100644
--- a/GUI/coregui/Views/InstrumentWidgets/OffSpecInstrumentEditor.h
+++ b/GUI/coregui/Views/InstrumentWidgets/OffSpecularInstrumentEditor.h
@@ -2,8 +2,8 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      GUI/coregui/Views/InstrumentWidgets/OffSpecInstrumentEditor.h
-//! @brief     Defines class OffSpecInstrumentEditor
+//! @file      GUI/coregui/Views/InstrumentWidgets/OffSpecularInstrumentEditor.h
+//! @brief     Defines class OffSpecularInstrumentEditor
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -12,34 +12,34 @@
 //
 //  ************************************************************************************************
 
-#ifndef BORNAGAIN_GUI_COREGUI_VIEWS_INSTRUMENTWIDGETS_OFFSPECINSTRUMENTEDITOR_H
-#define BORNAGAIN_GUI_COREGUI_VIEWS_INSTRUMENTWIDGETS_OFFSPECINSTRUMENTEDITOR_H
+#ifndef BORNAGAIN_GUI_COREGUI_VIEWS_INSTRUMENTWIDGETS_OFFSPECULARINSTRUMENTEDITOR_H
+#define BORNAGAIN_GUI_COREGUI_VIEWS_INSTRUMENTWIDGETS_OFFSPECULARINSTRUMENTEDITOR_H
 
 #include "GUI/coregui/Views/CommonWidgets/SessionItemWidget.h"
 
-class OffSpecInstrumentItem;
-class OffSpecBeamEditor;
+class OffSpecularInstrumentItem;
+class OffSpecularBeamEditor;
 class GISASDetectorEditor;
 class EnvironmentEditor;
 class PolarizationAnalysisEditor;
 class ColumnResizer;
 
-class OffSpecInstrumentEditor : public SessionItemWidget {
+class OffSpecularInstrumentEditor : public SessionItemWidget {
     Q_OBJECT
 
 public:
-    OffSpecInstrumentEditor(QWidget* parent = nullptr);
+    OffSpecularInstrumentEditor(QWidget* parent = nullptr);
 
 protected:
     void subscribeToItem();
 
 private:
-    OffSpecInstrumentItem* instrumentItem();
+    OffSpecularInstrumentItem* instrumentItem();
     ColumnResizer* m_columnResizer;
-    OffSpecBeamEditor* m_beamEditor;
+    OffSpecularBeamEditor* m_beamEditor;
     GISASDetectorEditor* m_detectorEditor;
     EnvironmentEditor* m_environmentEditor;
     PolarizationAnalysisEditor* m_polarizationAnalysisEditor;
 };
 
-#endif // BORNAGAIN_GUI_COREGUI_VIEWS_INSTRUMENTWIDGETS_OFFSPECINSTRUMENTEDITOR_H
+#endif // BORNAGAIN_GUI_COREGUI_VIEWS_INSTRUMENTWIDGETS_OFFSPECULARINSTRUMENTEDITOR_H
diff --git a/GUI/coregui/Views/IntensityDataWidgets/IntensityDataFFTPresenter.cpp b/GUI/coregui/Views/IntensityDataWidgets/IntensityDataFFTPresenter.cpp
index cbe73be754afdfb8d379e45b7f155ff6705cae84..7162a95a529f1edc1757b5562b4e1897fe09446c 100644
--- a/GUI/coregui/Views/IntensityDataWidgets/IntensityDataFFTPresenter.cpp
+++ b/GUI/coregui/Views/IntensityDataWidgets/IntensityDataFFTPresenter.cpp
@@ -13,7 +13,7 @@
 //  ************************************************************************************************
 
 #include "GUI/coregui/Views/IntensityDataWidgets/IntensityDataFFTPresenter.h"
-#include "Device/Instrument/IntensityDataFunctions.h"
+#include "Device/Data/DataUtils.h"
 #include "GUI/coregui/Models/IntensityDataItem.h"
 #include "GUI/coregui/Models/SessionModel.h"
 #include "GUI/coregui/utils/GUIHelpers.h"
@@ -46,8 +46,7 @@ IntensityDataItem* IntensityDataFFTPresenter::fftItem(IntensityDataItem* origIte
 
     QApplication::setOverrideCursor(Qt::WaitCursor);
 
-    m_fftItem->setOutputData(
-        IntensityDataFunctions::createFFT(*origItem->getOutputData()).release());
+    m_fftItem->setOutputData(DataUtils::createFFT(*origItem->getOutputData()).release());
 
     QApplication::restoreOverrideCursor();
 
diff --git a/GUI/coregui/Views/JobWidgets/JobResultsPresenter.cpp b/GUI/coregui/Views/JobWidgets/JobResultsPresenter.cpp
index 27e3a44b53c24e2217b8f6fd0f71f39994f3d84d..eef69b73a085066fd36fb0973b48d14d9d0f9ec5 100644
--- a/GUI/coregui/Views/JobWidgets/JobResultsPresenter.cpp
+++ b/GUI/coregui/Views/JobWidgets/JobResultsPresenter.cpp
@@ -28,13 +28,13 @@ const bool use_job_last_presentation = true;
 const std::map<QString, QString> instrument_to_default_presentaion{
     {"SpecularInstrument", "Reflectometry"},
     {"GISASInstrument", "Color Map"},
-    {"OffSpecInstrument", "Color Map"},
+    {"OffSpecularInstrument", "Color Map"},
     {"DepthProbeInstrument", "Color Map"}};
 
 const std::map<QString, QString> instrument_to_fit_presentaion{
     {"SpecularInstrument", "Fit 1D Data"},
     {"GISASInstrument", "Fit 2D Data"},
-    {"OffSpecInstrument", "Fit 2D Data"}};
+    {"OffSpecularInstrument", "Fit 2D Data"}};
 
 const std::map<JobViewFlags::EActivities, std::map<QString, QString>> activity_to_presentation{
     {JobViewFlags::FITTING_ACTIVITY, instrument_to_fit_presentaion},
@@ -44,7 +44,7 @@ const std::map<JobViewFlags::EActivities, std::map<QString, QString>> activity_t
 const std::map<QString, QStringList> default_active_presentation_list{
     {"SpecularInstrument", {"Reflectometry"}},
     {{"GISASInstrument"}, {"Color Map", "Projections"}},
-    {{"OffSpecInstrument"}, {"Color Map", "Projections"}},
+    {{"OffSpecularInstrument"}, {"Color Map", "Projections"}},
     {{"DepthProbeInstrument"}, {"Color Map", "Projections"}}};
 
 template <class QStringObj>
diff --git a/GUI/coregui/Views/MaskWidgets/MaskUnitsConverter.cpp b/GUI/coregui/Views/MaskWidgets/MaskUnitsConverter.cpp
index d485b0f3a292987cb9462ff6532d02ce26a57363..cea32f8295b059752ff4513f8a2550ed4cb7d79e 100644
--- a/GUI/coregui/Views/MaskWidgets/MaskUnitsConverter.cpp
+++ b/GUI/coregui/Views/MaskWidgets/MaskUnitsConverter.cpp
@@ -13,7 +13,7 @@
 //  ************************************************************************************************
 
 #include "GUI/coregui/Views/MaskWidgets/MaskUnitsConverter.h"
-#include "Device/Instrument/IntensityDataFunctions.h"
+#include "Device/Data/DataUtils.h"
 #include "GUI/coregui/Models/IntensityDataItem.h"
 #include "GUI/coregui/Models/MaskItems.h"
 #include "GUI/coregui/Models/ProjectionItems.h"
@@ -76,11 +76,11 @@ void MaskUnitsConverter::convertMask(SessionItem* maskItem) {
         double y2 = yc + yR;
 
         if (m_direction == TO_NBINS) {
-            IntensityDataFunctions::coordinateToBinf(xc, yc, *m_data);
-            IntensityDataFunctions::coordinateToBinf(x2, y2, *m_data);
+            DataUtils::coordinateToBinf(xc, yc, *m_data);
+            DataUtils::coordinateToBinf(x2, y2, *m_data);
         } else {
-            IntensityDataFunctions::coordinateFromBinf(xc, yc, *m_data);
-            IntensityDataFunctions::coordinateFromBinf(x2, y2, *m_data);
+            DataUtils::coordinateFromBinf(xc, yc, *m_data);
+            DataUtils::coordinateFromBinf(x2, y2, *m_data);
         }
         maskItem->setItemValue(EllipseItem::P_XCENTER, xc);
         maskItem->setItemValue(EllipseItem::P_YCENTER, yc);
@@ -111,9 +111,9 @@ double MaskUnitsConverter::convert(double value, int axis_index) {
     ASSERT(axis_index == 0 || axis_index == 1);
 
     if (m_direction == TO_NBINS) {
-        return IntensityDataFunctions::coordinateToBinf(value, m_data->axis(axis_index));
+        return DataUtils::coordinateToBinf(value, m_data->axis(axis_index));
     } else if (m_direction == FROM_NBINS) {
-        return IntensityDataFunctions::coordinateFromBinf(value, m_data->axis(axis_index));
+        return DataUtils::coordinateFromBinf(value, m_data->axis(axis_index));
     }
     throw GUIHelpers::Error("MaskUnitsConverter::convertX() -> Error. Unknown conversion");
 }
diff --git a/GUI/coregui/Views/PropertyEditor/PropertyEditorFactory.cpp b/GUI/coregui/Views/PropertyEditor/PropertyEditorFactory.cpp
index 68532ef8b35ea19d41cc9b0a3a9a32c39f9bc1c0..d32ee45e46cc6dda1a665d2c4e0ee0c972df7a94 100644
--- a/GUI/coregui/Views/PropertyEditor/PropertyEditorFactory.cpp
+++ b/GUI/coregui/Views/PropertyEditor/PropertyEditorFactory.cpp
@@ -82,9 +82,9 @@ QString PropertyEditorFactory::toString(const QModelIndex& index) {
         auto item = static_cast<SessionItem*>(index.internalPointer());
         return item->editorType() == "ScientificDouble"
                    ? QString::number(item->value().toDouble(), 'g')
-                   : item->editorType() == "ScientificSpinBox"
-                         ? ScientificSpinBox::toString(item->value().toDouble(), item->decimals())
-                         : QString::number(item->value().toDouble(), 'f', item->decimals());
+               : item->editorType() == "ScientificSpinBox"
+                   ? ScientificSpinBox::toString(item->value().toDouble(), item->decimals())
+                   : QString::number(item->value().toDouble(), 'f', item->decimals());
     }
 
     return "";
diff --git a/Param/Base/IComponent.h b/Param/Base/IComponent.h
index 6a7ad257346d659bd942c8143ad44dabcf6a2e50..4ab5e70c653845abce08940f58a548863b1cd42c 100644
--- a/Param/Base/IComponent.h
+++ b/Param/Base/IComponent.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_PARAM_BASE_ICOMPONENT_H
 #define BORNAGAIN_PARAM_BASE_ICOMPONENT_H
 
@@ -23,3 +24,4 @@ public:
 };
 
 #endif // BORNAGAIN_PARAM_BASE_ICOMPONENT_H
+#endif // USER_API
diff --git a/Param/Base/IParameter.h b/Param/Base/IParameter.h
index 59b09db18cab03f2aee808b9a3ceaf55315a5202..289ef88824a9365a870dd7c060bba6db065ec0d5 100644
--- a/Param/Base/IParameter.h
+++ b/Param/Base/IParameter.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_PARAM_BASE_IPARAMETER_H
 #define BORNAGAIN_PARAM_BASE_IPARAMETER_H
 
@@ -71,3 +72,4 @@ template <class T> bool IParameter<T>::hasSameData(const IParameter<T>& other) {
 }
 
 #endif // BORNAGAIN_PARAM_BASE_IPARAMETER_H
+#endif // USER_API
diff --git a/Param/Base/IParametricComponent.h b/Param/Base/IParametricComponent.h
index 6e8be06d038e005af022085f22bbb87cd0ad35e6..3b551706e1f065f16caae39ea98337538ea02b90 100644
--- a/Param/Base/IParametricComponent.h
+++ b/Param/Base/IParametricComponent.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_PARAM_BASE_IPARAMETRICCOMPONENT_H
 #define BORNAGAIN_PARAM_BASE_IPARAMETRICCOMPONENT_H
 
@@ -74,3 +75,4 @@ private:
 };
 
 #endif // BORNAGAIN_PARAM_BASE_IPARAMETRICCOMPONENT_H
+#endif // USER_API
diff --git a/Param/Base/Unit.h b/Param/Base/Unit.h
index 26d46c39c2e7ea96c8e48cd5a36c8a6ff51feda4..84755a1f39901a379eb48c365d681813c1a87246 100644
--- a/Param/Base/Unit.h
+++ b/Param/Base/Unit.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_PARAM_BASE_UNIT_H
 #define BORNAGAIN_PARAM_BASE_UNIT_H
 
@@ -34,3 +35,4 @@ private:
 };
 
 #endif // BORNAGAIN_PARAM_BASE_UNIT_H
+#endif // USER_API
diff --git a/Param/Distrib/DistributionHandler.h b/Param/Distrib/DistributionHandler.h
index 064d990abd62f78c5768e86bcd6abf40642805d7..ed4b9c1740a1379b0bb8bab6d3bb7bf5f98d8b41 100644
--- a/Param/Distrib/DistributionHandler.h
+++ b/Param/Distrib/DistributionHandler.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_PARAM_DISTRIB_DISTRIBUTIONHANDLER_H
 #define BORNAGAIN_PARAM_DISTRIB_DISTRIBUTIONHANDLER_H
 
@@ -61,3 +62,4 @@ private:
 };
 
 #endif // BORNAGAIN_PARAM_DISTRIB_DISTRIBUTIONHANDLER_H
+#endif // USER_API
diff --git a/Param/Node/INode.h b/Param/Node/INode.h
index 9d99e9c0fa0ac74ba4dcbb34cf11c4553b7e5c9e..b8113b2129bf891d3bf74dbe0782129944ff8c36 100644
--- a/Param/Node/INode.h
+++ b/Param/Node/INode.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_PARAM_NODE_INODE_H
 #define BORNAGAIN_PARAM_NODE_INODE_H
 
@@ -62,7 +63,7 @@ public:
 
     //! Returns a vector of children
     virtual std::vector<const INode*> getChildren() const;
-    //! Returns a vector of all descendents
+    //! Returns a vector of all descendants
     std::vector<const INode*> progeny() const;
 
     virtual void setParent(const INode* newParent);
@@ -128,3 +129,4 @@ inline std::vector<const INode*>& operator<<(std::vector<const INode*>&& v_node,
 }
 
 #endif // BORNAGAIN_PARAM_NODE_INODE_H
+#endif // USER_API
diff --git a/Param/Node/INodeVisitor.h b/Param/Node/INodeVisitor.h
index 2acf99b0819f038920b4944c476ca08eb0d8d68d..310cbaafcd8a1a62ea95fe210fb0153bb5db3d9c 100644
--- a/Param/Node/INodeVisitor.h
+++ b/Param/Node/INodeVisitor.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_PARAM_NODE_INODEVISITOR_H
 #define BORNAGAIN_PARAM_NODE_INODEVISITOR_H
 
@@ -120,7 +121,7 @@ class LayerInterface;
 class LayerRoughness;
 class MesoCrystal;
 class MultiLayer;
-class OffSpecSimulation;
+class OffSpecularSimulation;
 class Particle;
 class ParticleComposition;
 class ParticleCoreShell;
@@ -252,7 +253,7 @@ public:
     virtual void visit(const LayerRoughness*) {}
     virtual void visit(const MesoCrystal*) {}
     virtual void visit(const MultiLayer*) {}
-    virtual void visit(const OffSpecSimulation*) {}
+    virtual void visit(const OffSpecularSimulation*) {}
     virtual void visit(const Particle*) {}
     virtual void visit(const ParticleComposition*) {}
     virtual void visit(const ParticleCoreShell*) {}
@@ -280,3 +281,4 @@ private:
 };
 
 #endif // BORNAGAIN_PARAM_NODE_INODEVISITOR_H
+#endif // USER_API
diff --git a/Param/Node/NodeUtils.h b/Param/Node/NodeUtils.h
index 578d8222f68b78ec88b32d234c6b6784229cba1d..2f7cbeb65846ace1664943e2801112ff548783cd 100644
--- a/Param/Node/NodeUtils.h
+++ b/Param/Node/NodeUtils.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_PARAM_NODE_NODEUTILS_H
 #define BORNAGAIN_PARAM_NODE_NODEUTILS_H
 
@@ -26,7 +27,7 @@ class INode;
 
 namespace NodeUtils {
 
-//! Returns a vector of triples (descendent, depth, parent)
+//! Returns a vector of triples (descendant, depth, parent)
 std::vector<std::tuple<const INode*, int, const INode*>> progenyPlus(const INode* node,
                                                                      int level = 0);
 
@@ -39,3 +40,4 @@ std::string nodePath(const INode* node, const INode* root = nullptr);
 } // namespace NodeUtils
 
 #endif // BORNAGAIN_PARAM_NODE_NODEUTILS_H
+#endif // USER_API
diff --git a/Param/Varia/ParameterPattern.h b/Param/Varia/ParameterPattern.h
index 6bc7a0f4604adc8b03fdf9480945a8890009d558..801834ea1569791fbc5351f46d4762bafbf0dfa6 100644
--- a/Param/Varia/ParameterPattern.h
+++ b/Param/Varia/ParameterPattern.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_PARAM_VARIA_PARAMETERPATTERN_H
 #define BORNAGAIN_PARAM_VARIA_PARAMETERPATTERN_H
 
@@ -39,3 +40,4 @@ private:
 };
 
 #endif // BORNAGAIN_PARAM_VARIA_PARAMETERPATTERN_H
+#endif // USER_API
diff --git a/Param/Varia/ParameterUtils.h b/Param/Varia/ParameterUtils.h
index 994c483379c8916f492cddcb50896eb8884e6911..7fcb601f1209f5ec3883ff26055a9fcf8e8c4f66 100644
--- a/Param/Varia/ParameterUtils.h
+++ b/Param/Varia/ParameterUtils.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_PARAM_VARIA_PARAMETERUTILS_H
 #define BORNAGAIN_PARAM_VARIA_PARAMETERUTILS_H
 
@@ -34,3 +35,4 @@ std::string poolParameterUnits(const IParametricComponent& node, const std::stri
 } // namespace ParameterUtils
 
 #endif // BORNAGAIN_PARAM_VARIA_PARAMETERUTILS_H
+#endif // USER_API
diff --git a/Sample/Aggregate/IInterferenceFunction.h b/Sample/Aggregate/IInterferenceFunction.h
index 5571ed969a49737706d4231524ca8fe82df26b09..4ac2a77190f7790b615ca408b9357da061bd2da4 100644
--- a/Sample/Aggregate/IInterferenceFunction.h
+++ b/Sample/Aggregate/IInterferenceFunction.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_AGGREGATE_IINTERFERENCEFUNCTION_H
 #define BORNAGAIN_SAMPLE_AGGREGATE_IINTERFERENCEFUNCTION_H
 
@@ -58,3 +59,4 @@ protected:
 };
 
 #endif // BORNAGAIN_SAMPLE_AGGREGATE_IINTERFERENCEFUNCTION_H
+#endif // USER_API
diff --git a/Sample/Aggregate/InterferenceFunctions.h b/Sample/Aggregate/InterferenceFunctions.h
index afcf7003ccafaac822ff0612bc076d26944dcfc6..db1154e5656add363231bcde1f38ae08c88ff800 100644
--- a/Sample/Aggregate/InterferenceFunctions.h
+++ b/Sample/Aggregate/InterferenceFunctions.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_AGGREGATE_INTERFERENCEFUNCTIONS_H
 #define BORNAGAIN_SAMPLE_AGGREGATE_INTERFERENCEFUNCTIONS_H
 
@@ -32,3 +33,4 @@
 #include "Sample/Aggregate/InterferenceFunctionTwin.h"
 
 #endif // BORNAGAIN_SAMPLE_AGGREGATE_INTERFERENCEFUNCTIONS_H
+#endif // USER_API
diff --git a/Sample/Correlations/IDistribution1DSampler.h b/Sample/Correlations/IDistribution1DSampler.h
index a1399a61a2e9898d3c99f06f8646b6fa6adea235..13a159e2b07b2e681182c026b1c11e63a3fd2594 100644
--- a/Sample/Correlations/IDistribution1DSampler.h
+++ b/Sample/Correlations/IDistribution1DSampler.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_CORRELATIONS_IDISTRIBUTION1DSAMPLER_H
 #define BORNAGAIN_SAMPLE_CORRELATIONS_IDISTRIBUTION1DSAMPLER_H
 
@@ -73,3 +74,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_CORRELATIONS_IDISTRIBUTION1DSAMPLER_H
+#endif // USER_API
diff --git a/Sample/Correlations/IDistribution2DSampler.h b/Sample/Correlations/IDistribution2DSampler.h
index fda6cb305082ca28c9c2f09067475feaebe722a1..b164b83a863021eaeab5841faca848f5208c407c 100644
--- a/Sample/Correlations/IDistribution2DSampler.h
+++ b/Sample/Correlations/IDistribution2DSampler.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_CORRELATIONS_IDISTRIBUTION2DSAMPLER_H
 #define BORNAGAIN_SAMPLE_CORRELATIONS_IDISTRIBUTION2DSAMPLER_H
 
@@ -70,3 +71,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_CORRELATIONS_IDISTRIBUTION2DSAMPLER_H
+#endif // USER_API
diff --git a/Sample/Correlations/IPeakShape.h b/Sample/Correlations/IPeakShape.h
index c7883472151b42637408ce8978464431a8673be7..e835d301efe0b00011e64d0928a472f3ffb37dd3 100644
--- a/Sample/Correlations/IPeakShape.h
+++ b/Sample/Correlations/IPeakShape.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_CORRELATIONS_IPEAKSHAPE_H
 #define BORNAGAIN_SAMPLE_CORRELATIONS_IPEAKSHAPE_H
 
@@ -187,3 +188,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_CORRELATIONS_IPEAKSHAPE_H
+#endif // USER_API
diff --git a/Sample/FFCompute/ComputeBA.h b/Sample/FFCompute/ComputeBA.h
index a246855534bcc92ac7b5f4a94ee9bf4d7a263cf0..cb4990d5c2531cce760144226bd41bccad29b642 100644
--- a/Sample/FFCompute/ComputeBA.h
+++ b/Sample/FFCompute/ComputeBA.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_FFCOMPUTE_COMPUTEBA_H
 #define BORNAGAIN_SAMPLE_FFCOMPUTE_COMPUTEBA_H
 
@@ -38,3 +39,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_FFCOMPUTE_COMPUTEBA_H
+#endif // USER_API
diff --git a/Sample/FFCompute/ComputeBAPol.h b/Sample/FFCompute/ComputeBAPol.h
index a52901f5fdbc88a65bd3fe0370029de3b6eca661..5959afe03b2c5927ce22cc4f2ea92383baac4f9a 100644
--- a/Sample/FFCompute/ComputeBAPol.h
+++ b/Sample/FFCompute/ComputeBAPol.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_FFCOMPUTE_COMPUTEBAPOL_H
 #define BORNAGAIN_SAMPLE_FFCOMPUTE_COMPUTEBAPOL_H
 
@@ -42,3 +43,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_FFCOMPUTE_COMPUTEBAPOL_H
+#endif // USER_API
diff --git a/Sample/FFCompute/ComputeDWBA.h b/Sample/FFCompute/ComputeDWBA.h
index 0ddd0acb335b4ec9cba8a2b0e5b7431dd50c32b0..9e3eb5b5a1477973593d8d604581f2d7fdb5d6b2 100644
--- a/Sample/FFCompute/ComputeDWBA.h
+++ b/Sample/FFCompute/ComputeDWBA.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_FFCOMPUTE_COMPUTEDWBA_H
 #define BORNAGAIN_SAMPLE_FFCOMPUTE_COMPUTEDWBA_H
 
@@ -49,3 +50,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_FFCOMPUTE_COMPUTEDWBA_H
+#endif // USER_API
diff --git a/Sample/FFCompute/ComputeDWBAPol.cpp b/Sample/FFCompute/ComputeDWBAPol.cpp
index befc74c84a8f241da5e2b5b29dff37f8e4a0f346..58aa9707556591376618f005929991ef2e43896a 100644
--- a/Sample/FFCompute/ComputeDWBAPol.cpp
+++ b/Sample/FFCompute/ComputeDWBAPol.cpp
@@ -18,8 +18,8 @@
 #include "Sample/Scattering/IFormFactor.h"
 
 namespace {
-std::complex<double> VecMatVecProduct(const Eigen::Vector2cd& vec1, const Eigen::Matrix2cd& ff,
-                                      const Eigen::Vector2cd& vec2) {
+complex_t VecMatVecProduct(const Eigen::Vector2cd& vec1, const Eigen::Matrix2cd& ff,
+                           const Eigen::Vector2cd& vec2) {
     return vec1.transpose() * ff * vec2;
 }
 } // namespace
diff --git a/Sample/FFCompute/ComputeDWBAPol.h b/Sample/FFCompute/ComputeDWBAPol.h
index 4b8fb81427dd4042085a4d21813b80803410efe8..30587534a1aa030356a7be64115df47aba11a0fb 100644
--- a/Sample/FFCompute/ComputeDWBAPol.h
+++ b/Sample/FFCompute/ComputeDWBAPol.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_FFCOMPUTE_COMPUTEDWBAPOL_H
 #define BORNAGAIN_SAMPLE_FFCOMPUTE_COMPUTEDWBAPOL_H
 
@@ -52,3 +53,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_FFCOMPUTE_COMPUTEDWBAPOL_H
+#endif // USER_API
diff --git a/Sample/FFCompute/IComputeFF.h b/Sample/FFCompute/IComputeFF.h
index d567ef99584fe1480e847886d56db383543c158f..bbd9d4761ccd26214fd63c182782b6bd8e6f27c0 100644
--- a/Sample/FFCompute/IComputeFF.h
+++ b/Sample/FFCompute/IComputeFF.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_FFCOMPUTE_ICOMPUTEFF_H
 #define BORNAGAIN_SAMPLE_FFCOMPUTE_ICOMPUTEFF_H
 
@@ -64,3 +65,4 @@ protected:
 };
 
 #endif // BORNAGAIN_SAMPLE_FFCOMPUTE_ICOMPUTEFF_H
+#endif // USER_API
diff --git a/Sample/Fresnel/FormFactorCoherentPart.h b/Sample/Fresnel/FormFactorCoherentPart.h
index 717b76902d694193a6180aaf85352e7fcd83bf3d..64fd53b00b03d42ae85f95a326dcacb1399da3e9 100644
--- a/Sample/Fresnel/FormFactorCoherentPart.h
+++ b/Sample/Fresnel/FormFactorCoherentPart.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_FRESNEL_FORMFACTORCOHERENTPART_H
 #define BORNAGAIN_SAMPLE_FRESNEL_FORMFACTORCOHERENTPART_H
 
@@ -54,3 +55,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_FRESNEL_FORMFACTORCOHERENTPART_H
+#endif // USER_API
diff --git a/Sample/Fresnel/FormFactorCoherentSum.h b/Sample/Fresnel/FormFactorCoherentSum.h
index 3edc468827f1c683709bbbe215e97c33c72583b4..a03847610728e0e7086c16a3aaaf535be560a250 100644
--- a/Sample/Fresnel/FormFactorCoherentSum.h
+++ b/Sample/Fresnel/FormFactorCoherentSum.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_FRESNEL_FORMFACTORCOHERENTSUM_H
 #define BORNAGAIN_SAMPLE_FRESNEL_FORMFACTORCOHERENTSUM_H
 
@@ -50,3 +51,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_FRESNEL_FORMFACTORCOHERENTSUM_H
+#endif // USER_API
diff --git a/Sample/Fresnel/IFresnelMap.h b/Sample/Fresnel/IFresnelMap.h
index ab37382a759196d8f0fbe909953e641720f1816f..f14ccd6bd7e08f781e4bc7db73e44e38f734546a 100644
--- a/Sample/Fresnel/IFresnelMap.h
+++ b/Sample/Fresnel/IFresnelMap.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_FRESNEL_IFRESNELMAP_H
 #define BORNAGAIN_SAMPLE_FRESNEL_IFRESNELMAP_H
 
@@ -63,3 +64,4 @@ protected:
 };
 
 #endif // BORNAGAIN_SAMPLE_FRESNEL_IFRESNELMAP_H
+#endif // USER_API
diff --git a/Sample/Fresnel/MatrixFresnelMap.h b/Sample/Fresnel/MatrixFresnelMap.h
index dadeaaa563c6ac2bbf58d44d293d7f19aed810ef..0e4c8310b8cc50de5156e9dc9885cfadd2c89a4c 100644
--- a/Sample/Fresnel/MatrixFresnelMap.h
+++ b/Sample/Fresnel/MatrixFresnelMap.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_FRESNEL_MATRIXFRESNELMAP_H
 #define BORNAGAIN_SAMPLE_FRESNEL_MATRIXFRESNELMAP_H
 
@@ -71,3 +72,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_FRESNEL_MATRIXFRESNELMAP_H
+#endif // USER_API
diff --git a/Sample/Fresnel/ScalarFresnelMap.cpp b/Sample/Fresnel/ScalarFresnelMap.cpp
index 409ecbcf9409be9038efb04b1bd158e89e37c590..ea36b4137884c86e4d7f1bb1590f9047a29d9a45 100644
--- a/Sample/Fresnel/ScalarFresnelMap.cpp
+++ b/Sample/Fresnel/ScalarFresnelMap.cpp
@@ -22,8 +22,8 @@ ScalarFresnelMap::ScalarFresnelMap(std::unique_ptr<ISpecularStrategy> strategy)
 ScalarFresnelMap::~ScalarFresnelMap() = default;
 
 //! Returns hash value of a pair of doubles, computed by exclusive-or of the component hash values.
-size_t ScalarFresnelMap::Hash2Doubles::operator()(const std::pair<double, double>& doubles) const
-    noexcept {
+size_t ScalarFresnelMap::Hash2Doubles::operator()(
+    const std::pair<double, double>& doubles) const noexcept {
     return std::hash<double>{}(doubles.first) ^ std::hash<double>{}(doubles.second);
 }
 
diff --git a/Sample/Fresnel/ScalarFresnelMap.h b/Sample/Fresnel/ScalarFresnelMap.h
index 7a02e8a26339f80dc1850c40d81e2b8106a7dd4d..29a00b5161cc00f3caf52227660dc486de5635ef 100644
--- a/Sample/Fresnel/ScalarFresnelMap.h
+++ b/Sample/Fresnel/ScalarFresnelMap.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_FRESNEL_SCALARFRESNELMAP_H
 #define BORNAGAIN_SAMPLE_FRESNEL_SCALARFRESNELMAP_H
 
@@ -59,3 +60,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_FRESNEL_SCALARFRESNELMAP_H
+#endif // USER_API
diff --git a/Sample/HardParticle/FormFactorBar.h b/Sample/HardParticle/FormFactorBar.h
index c4c0be554527a98a563461f1b3b97df3e480bf44..ebaaf11be6eea7f2ef85e3cdcab5510ed42c2548 100644
--- a/Sample/HardParticle/FormFactorBar.h
+++ b/Sample/HardParticle/FormFactorBar.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_HARDPARTICLE_FORMFACTORBAR_H
 #define BORNAGAIN_SAMPLE_HARDPARTICLE_FORMFACTORBAR_H
 
@@ -48,3 +49,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_HARDPARTICLE_FORMFACTORBAR_H
+#endif // USER_API
diff --git a/Sample/HardParticle/HardParticles.h b/Sample/HardParticle/HardParticles.h
index 296fd4d3ecf26bfb8f5f159dff42f87776172a9d..c2844eacc17ca3fc503529063f4be0661e4559ff 100644
--- a/Sample/HardParticle/HardParticles.h
+++ b/Sample/HardParticle/HardParticles.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_HARDPARTICLE_HARDPARTICLES_H
 #define BORNAGAIN_SAMPLE_HARDPARTICLE_HARDPARTICLES_H
 
@@ -47,3 +48,4 @@
 #include "Sample/HardParticle/FormFactorTruncatedSpheroid.h"
 
 #endif // BORNAGAIN_SAMPLE_HARDPARTICLE_HARDPARTICLES_H
+#endif // USER_API
diff --git a/Sample/HardParticle/IFormFactorPolyhedron.h b/Sample/HardParticle/IFormFactorPolyhedron.h
index 9ac8dc0c94cf6daec31a486a232d104682c67a40..cee435daf89cd538384095f88b2c40be8c1f8050 100644
--- a/Sample/HardParticle/IFormFactorPolyhedron.h
+++ b/Sample/HardParticle/IFormFactorPolyhedron.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_HARDPARTICLE_IFORMFACTORPOLYHEDRON_H
 #define BORNAGAIN_SAMPLE_HARDPARTICLE_IFORMFACTORPOLYHEDRON_H
 
@@ -52,3 +53,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_HARDPARTICLE_IFORMFACTORPOLYHEDRON_H
+#endif // USER_API
diff --git a/Sample/HardParticle/IFormFactorPrism.h b/Sample/HardParticle/IFormFactorPrism.h
index 701fb7d0f234551bf7ef306955e2b8871a07a619..715ea431f971c950050f783f32bdaf70929439be 100644
--- a/Sample/HardParticle/IFormFactorPrism.h
+++ b/Sample/HardParticle/IFormFactorPrism.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_HARDPARTICLE_IFORMFACTORPRISM_H
 #define BORNAGAIN_SAMPLE_HARDPARTICLE_IFORMFACTORPRISM_H
 
@@ -44,3 +45,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_HARDPARTICLE_IFORMFACTORPRISM_H
+#endif // USER_API
diff --git a/Sample/HardParticle/IProfileRipple.h b/Sample/HardParticle/IProfileRipple.h
index 26f6e09c59f84e7ffb478f82fb180589ce85da68..d69d71d217eb3243f7f488b274787474522e5d87 100644
--- a/Sample/HardParticle/IProfileRipple.h
+++ b/Sample/HardParticle/IProfileRipple.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_HARDPARTICLE_IPROFILERIPPLE_H
 #define BORNAGAIN_SAMPLE_HARDPARTICLE_IPROFILERIPPLE_H
 
@@ -80,3 +81,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_HARDPARTICLE_IPROFILERIPPLE_H
+#endif // USER_API
diff --git a/Sample/HardParticle/PolyhedralComponents.h b/Sample/HardParticle/PolyhedralComponents.h
index 34b88c71bf2fe8910bcce9cd6f48a09cd5de6c15..d7ac4772b92caa1a472dd310c8cdb2898de2b8c5 100644
--- a/Sample/HardParticle/PolyhedralComponents.h
+++ b/Sample/HardParticle/PolyhedralComponents.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_HARDPARTICLE_POLYHEDRALCOMPONENTS_H
 #define BORNAGAIN_SAMPLE_HARDPARTICLE_POLYHEDRALCOMPONENTS_H
 
@@ -83,3 +84,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_HARDPARTICLE_POLYHEDRALCOMPONENTS_H
+#endif // USER_API
diff --git a/Sample/HardParticle/PolyhedralTopology.h b/Sample/HardParticle/PolyhedralTopology.h
index 020efad91e8bbfead648cb46e73add449d53727e..29e79f206176ea2e1268526d7d9fc36e3b1ddf62 100644
--- a/Sample/HardParticle/PolyhedralTopology.h
+++ b/Sample/HardParticle/PolyhedralTopology.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_HARDPARTICLE_POLYHEDRALTOPOLOGY_H
 #define BORNAGAIN_SAMPLE_HARDPARTICLE_POLYHEDRALTOPOLOGY_H
 
@@ -36,3 +37,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_HARDPARTICLE_POLYHEDRALTOPOLOGY_H
+#endif // USER_API
diff --git a/Sample/HardParticle/Polyhedron.h b/Sample/HardParticle/Polyhedron.h
index 443aadaaa2622b605962e7e47cda545fda5943bb..18d02a0a1b1e5937faa471ebe19f4089675f32ae 100644
--- a/Sample/HardParticle/Polyhedron.h
+++ b/Sample/HardParticle/Polyhedron.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_HARDPARTICLE_POLYHEDRON_H
 #define BORNAGAIN_SAMPLE_HARDPARTICLE_POLYHEDRON_H
 
@@ -50,3 +51,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_HARDPARTICLE_POLYHEDRON_H
+#endif // USER_API
diff --git a/Sample/HardParticle/Prism.h b/Sample/HardParticle/Prism.h
index b2649933e8a6411e0225a1023820a1fa40f8cac1..8e1b3b6c7d043c4250ec83244c800f4af11a020b 100644
--- a/Sample/HardParticle/Prism.h
+++ b/Sample/HardParticle/Prism.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_HARDPARTICLE_PRISM_H
 #define BORNAGAIN_SAMPLE_HARDPARTICLE_PRISM_H
 
@@ -39,3 +40,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_HARDPARTICLE_PRISM_H
+#endif // USER_API
diff --git a/Sample/HardParticle/Ripples.h b/Sample/HardParticle/Ripples.h
index e5e03553dc970b09c32a2cc2f7fe72e84682e99b..18b2f573ff7dce6d62d25b3fa99dec56a07cf367 100644
--- a/Sample/HardParticle/Ripples.h
+++ b/Sample/HardParticle/Ripples.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_HARDPARTICLE_RIPPLES_H
 #define BORNAGAIN_SAMPLE_HARDPARTICLE_RIPPLES_H
 
@@ -36,3 +37,4 @@ complex_t profile_yz_triangular(complex_t qy, complex_t qz, double width, double
 } // namespace ripples
 
 #endif // BORNAGAIN_SAMPLE_HARDPARTICLE_RIPPLES_H
+#endif // USER_API
diff --git a/Sample/Interference/DecouplingApproximationStrategy.h b/Sample/Interference/DecouplingApproximationStrategy.h
index 8a33b35dbb224fba129e66abd2a0143ccf628c22..708e011900c77966c1754a3a1b9d73e4a6283655 100644
--- a/Sample/Interference/DecouplingApproximationStrategy.h
+++ b/Sample/Interference/DecouplingApproximationStrategy.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_INTERFERENCE_DECOUPLINGAPPROXIMATIONSTRATEGY_H
 #define BORNAGAIN_SAMPLE_INTERFERENCE_DECOUPLINGAPPROXIMATIONSTRATEGY_H
 
@@ -41,3 +42,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_INTERFERENCE_DECOUPLINGAPPROXIMATIONSTRATEGY_H
+#endif // USER_API
diff --git a/Sample/Interference/FormFactorPrecompute.h b/Sample/Interference/FormFactorPrecompute.h
index f5cecc8e33e4082b89676fa2daf3547f7fc4d4d7..eba208bd6706b33cdcafe7304e277af303b8d052 100644
--- a/Sample/Interference/FormFactorPrecompute.h
+++ b/Sample/Interference/FormFactorPrecompute.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_INTERFERENCE_FORMFACTORPRECOMPUTE_H
 #define BORNAGAIN_SAMPLE_INTERFERENCE_FORMFACTORPRECOMPUTE_H
 
@@ -37,3 +38,4 @@ matrixFFVector_t polarized(const SimulationElement& sim_element,
 } // namespace FormFactorPrecompute
 
 #endif // BORNAGAIN_SAMPLE_INTERFERENCE_FORMFACTORPRECOMPUTE_H
+#endif // USER_API
diff --git a/Sample/Interference/IInterferenceFunctionStrategy.h b/Sample/Interference/IInterferenceFunctionStrategy.h
index de52ab267513f4635bd2077d10114dfbc609a8ea..c911697a40e8279810653caf88e464a3b70ee40d 100644
--- a/Sample/Interference/IInterferenceFunctionStrategy.h
+++ b/Sample/Interference/IInterferenceFunctionStrategy.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_INTERFERENCE_IINTERFERENCEFUNCTIONSTRATEGY_H
 #define BORNAGAIN_SAMPLE_INTERFERENCE_IINTERFERENCEFUNCTIONSTRATEGY_H
 
@@ -72,3 +73,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_INTERFERENCE_IINTERFERENCEFUNCTIONSTRATEGY_H
+#endif // USER_API
diff --git a/Sample/Interference/SSCApproximationStrategy.h b/Sample/Interference/SSCApproximationStrategy.h
index b3712a4a6f57d0cdc25e64c7f4a9dcf37f2eab0c..71c7d1f2f705bd9bdb07254dcd6b057dff1c1969 100644
--- a/Sample/Interference/SSCApproximationStrategy.h
+++ b/Sample/Interference/SSCApproximationStrategy.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_INTERFERENCE_SSCAPPROXIMATIONSTRATEGY_H
 #define BORNAGAIN_SAMPLE_INTERFERENCE_SSCAPPROXIMATIONSTRATEGY_H
 
@@ -52,3 +53,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_INTERFERENCE_SSCAPPROXIMATIONSTRATEGY_H
+#endif // USER_API
diff --git a/Sample/Lattice/ISelectionRule.h b/Sample/Lattice/ISelectionRule.h
index b4bcbf708c2e5cf1e4a8f4ec395f5122c604e583..d716fcbdba014433a35401af11af2f12e5dc782e 100644
--- a/Sample/Lattice/ISelectionRule.h
+++ b/Sample/Lattice/ISelectionRule.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_LATTICE_ISELECTIONRULE_H
 #define BORNAGAIN_SAMPLE_LATTICE_ISELECTIONRULE_H
 
@@ -58,3 +59,4 @@ inline bool SimpleSelectionRule::coordinateSelected(const ivector_t& coordinate)
 }
 
 #endif // BORNAGAIN_SAMPLE_LATTICE_ISELECTIONRULE_H
+#endif // USER_API
diff --git a/Sample/Lattice/Lattice2D.h b/Sample/Lattice/Lattice2D.h
index 77a3685ecc98ba283ced69cb6882ab4b12d6feb3..6be45527ec4b292d099a25a137234066ee87aa25 100644
--- a/Sample/Lattice/Lattice2D.h
+++ b/Sample/Lattice/Lattice2D.h
@@ -18,6 +18,8 @@
 #include "Base/Types/ICloneable.h"
 #include "Param/Node/INode.h"
 
+//! A two-dimensional Bravais lattice.
+
 class Lattice2D : public ICloneable, public INode {
 public:
     Lattice2D(const NodeMeta& meta, const std::vector<double>& PValues);
@@ -46,6 +48,8 @@ protected:
     double m_xi;
 };
 
+//! A two-dimensional Bravais lattice with no special symmetry.
+
 class BasicLattice2D : public Lattice2D {
 public:
     BasicLattice2D(double length1, double length2, double angle, double xi);
@@ -64,6 +68,8 @@ private:
     double m_angle;
 };
 
+//! A two-dimensional Bravais lattice with square unit cell.
+
 class SquareLattice2D : public Lattice2D {
 public:
     SquareLattice2D(double length, double xi = 0.0);
@@ -81,6 +87,8 @@ private:
     double m_length;
 };
 
+//! A two-dimensional Bravais lattice with hexagonal symmetry.
+
 class HexagonalLattice2D : public Lattice2D {
 public:
     HexagonalLattice2D(double length, double xi);
diff --git a/Core/Legacy/MatrixRTCoefficients_v1.cpp b/Sample/LegacyRT/MatrixRTCoefficients_v1.cpp
similarity index 98%
rename from Core/Legacy/MatrixRTCoefficients_v1.cpp
rename to Sample/LegacyRT/MatrixRTCoefficients_v1.cpp
index 7f297e3ab5a23907a8d6b1f38748d87b9681448b..7f6dd9b646ce0e856b43d2b3293ec85818d877c2 100644
--- a/Core/Legacy/MatrixRTCoefficients_v1.cpp
+++ b/Sample/LegacyRT/MatrixRTCoefficients_v1.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Sample/RT/MatrixRTCoefficients_v1.cpp
+//! @file      Sample/LegacyRT/MatrixRTCoefficients_v1.cpp
 //! @brief     Implements class MatrixRTCoefficients_v1.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,7 +12,7 @@
 //
 //  ************************************************************************************************
 
-#include "Core/Legacy/MatrixRTCoefficients_v1.h"
+#include "Sample/LegacyRT/MatrixRTCoefficients_v1.h"
 
 MatrixRTCoefficients_v1* MatrixRTCoefficients_v1::clone() const {
     return new MatrixRTCoefficients_v1(*this);
diff --git a/Core/Legacy/MatrixRTCoefficients_v1.h b/Sample/LegacyRT/MatrixRTCoefficients_v1.h
similarity index 97%
rename from Core/Legacy/MatrixRTCoefficients_v1.h
rename to Sample/LegacyRT/MatrixRTCoefficients_v1.h
index 761c79e7da5e5fef98c4b7f7a990ea64b8e90437..3dbebc453fb43e6e13f8c7d174f90770c3c27256 100644
--- a/Core/Legacy/MatrixRTCoefficients_v1.h
+++ b/Sample/LegacyRT/MatrixRTCoefficients_v1.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Sample/RT/MatrixRTCoefficients_v1.h
+//! @file      Sample/LegacyRT/MatrixRTCoefficients_v1.h
 //! @brief    Defines class MatrixRTCoefficients_v1.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_LEGACY_MATRIXRTCOEFFICIENTS_V1_H
 #define BORNAGAIN_CORE_LEGACY_MATRIXRTCOEFFICIENTS_V1_H
 
@@ -71,3 +72,4 @@ public:
 };
 
 #endif // BORNAGAIN_CORE_LEGACY_MATRIXRTCOEFFICIENTS_V1_H
+#endif // USER_API
diff --git a/Core/Legacy/MatrixRTCoefficients_v2.cpp b/Sample/LegacyRT/MatrixRTCoefficients_v2.cpp
similarity index 96%
rename from Core/Legacy/MatrixRTCoefficients_v2.cpp
rename to Sample/LegacyRT/MatrixRTCoefficients_v2.cpp
index 24f23b5b5a74384c7885b86197784022a164dd5d..1df1c15a887341388a8541e6117cbef777c3892b 100644
--- a/Core/Legacy/MatrixRTCoefficients_v2.cpp
+++ b/Sample/LegacyRT/MatrixRTCoefficients_v2.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file     Sample/RT/MatrixRTCoefficients_v2.cpp
+//! @file     Sample/LegacyRT/MatrixRTCoefficients_v2.cpp
 //! @brief    Implements class MatrixRTCoefficients_v2.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -12,7 +12,7 @@
 //
 //  ************************************************************************************************
 
-#include "Core/Legacy/MatrixRTCoefficients_v2.h"
+#include "Sample/LegacyRT/MatrixRTCoefficients_v2.h"
 
 namespace {
 Eigen::Vector2cd waveVector(const Eigen::Matrix4cd& frob_matrix,
diff --git a/Core/Legacy/MatrixRTCoefficients_v2.h b/Sample/LegacyRT/MatrixRTCoefficients_v2.h
similarity index 97%
rename from Core/Legacy/MatrixRTCoefficients_v2.h
rename to Sample/LegacyRT/MatrixRTCoefficients_v2.h
index 5d12d998bf6c215bc60324c81faac20dfac87515..dfa995e8b277bb16eca3fd828b96555f4c9179e9 100644
--- a/Core/Legacy/MatrixRTCoefficients_v2.h
+++ b/Sample/LegacyRT/MatrixRTCoefficients_v2.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file     Sample/RT/MatrixRTCoefficients_v2.h
+//! @file     Sample/LegacyRT/MatrixRTCoefficients_v2.h
 //! @brief    Defines class MatrixRTCoefficients_v2.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_LEGACY_MATRIXRTCOEFFICIENTS_V2_H
 #define BORNAGAIN_CORE_LEGACY_MATRIXRTCOEFFICIENTS_V2_H
 
@@ -72,3 +73,4 @@ private:
 };
 
 #endif // BORNAGAIN_CORE_LEGACY_MATRIXRTCOEFFICIENTS_V2_H
+#endif // USER_API
diff --git a/Core/Legacy/SpecularMagneticStrategy_v1.cpp b/Sample/LegacyRT/SpecularMagneticStrategy_v1.cpp
similarity index 99%
rename from Core/Legacy/SpecularMagneticStrategy_v1.cpp
rename to Sample/LegacyRT/SpecularMagneticStrategy_v1.cpp
index 0171d494e2be2c5d7b975a08aaf21f2e530155ac..632d3b21fa38c88f26ef635a44c35d65aff433b1 100644
--- a/Core/Legacy/SpecularMagneticStrategy_v1.cpp
+++ b/Sample/LegacyRT/SpecularMagneticStrategy_v1.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Sample/Specular/SpecularMagneticStrategy_v1.cpp
+//! @file      Sample/LegacyRT/SpecularMagneticStrategy_v1.cpp
 //! @brief     Implements class SpecularMagneticStrategy_v1.
 //!
 //! @homepage  http://www.bornagainproject.org
diff --git a/Core/Legacy/SpecularMagneticStrategy_v1.h b/Sample/LegacyRT/SpecularMagneticStrategy_v1.h
similarity index 95%
rename from Core/Legacy/SpecularMagneticStrategy_v1.h
rename to Sample/LegacyRT/SpecularMagneticStrategy_v1.h
index eab0fb2b920f4851a1724d5ad98c7ea0dcb3228f..d2f432fedc87f7f97b76a5411e3a2cfa75676655 100644
--- a/Core/Legacy/SpecularMagneticStrategy_v1.h
+++ b/Sample/LegacyRT/SpecularMagneticStrategy_v1.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Sample/Specular/SpecularMagneticStrategy_v1.h
+//! @file      Sample/LegacyRT/SpecularMagneticStrategy_v1.h
 //! @brief     Defines class SpecularMagneticStrategy_v1.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_LEGACY_SPECULARMAGNETICSTRATEGY_V1_H
 #define BORNAGAIN_CORE_LEGACY_SPECULARMAGNETICSTRATEGY_V1_H
 
@@ -48,3 +49,4 @@ public:
 }; // class SpecularMagneticStrategy_v1
 
 #endif // BORNAGAIN_CORE_LEGACY_SPECULARMAGNETICSTRATEGY_V1_H
+#endif // USER_API
diff --git a/Core/Legacy/SpecularMagneticStrategy_v2.cpp b/Sample/LegacyRT/SpecularMagneticStrategy_v2.cpp
similarity index 99%
rename from Core/Legacy/SpecularMagneticStrategy_v2.cpp
rename to Sample/LegacyRT/SpecularMagneticStrategy_v2.cpp
index 4fc9b2485fd7d82dac89439544b9416fb6042f75..acca4f6227082e110a8c82db94aabc2e3ad9bb5f 100644
--- a/Core/Legacy/SpecularMagneticStrategy_v2.cpp
+++ b/Sample/LegacyRT/SpecularMagneticStrategy_v2.cpp
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Sample/Specular/SpecularMagneticStrategy_v2.cpp
+//! @file      Sample/LegacyRT/SpecularMagneticStrategy_v2.cpp
 //! @brief     Implements class SpecularMagneticStrategy_v2.
 //!
 //! @homepage  http://www.bornagainproject.org
diff --git a/Core/Legacy/SpecularMagneticStrategy_v2.h b/Sample/LegacyRT/SpecularMagneticStrategy_v2.h
similarity index 97%
rename from Core/Legacy/SpecularMagneticStrategy_v2.h
rename to Sample/LegacyRT/SpecularMagneticStrategy_v2.h
index 003e60cac849eecd4f04f72995962443b7136822..e0e35d390031d1b754d8974c17010cdd34f0f7b0 100644
--- a/Core/Legacy/SpecularMagneticStrategy_v2.h
+++ b/Sample/LegacyRT/SpecularMagneticStrategy_v2.h
@@ -2,7 +2,7 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Sample/Specular/SpecularMagneticStrategy_v2.h
+//! @file      Sample/LegacyRT/SpecularMagneticStrategy_v2.h
 //! @brief     Defines class SpecularMagneticStrategy_v2.
 //!
 //! @homepage  http://www.bornagainproject.org
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_CORE_LEGACY_SPECULARMAGNETICSTRATEGY_V2_H
 #define BORNAGAIN_CORE_LEGACY_SPECULARMAGNETICSTRATEGY_V2_H
 
@@ -78,3 +79,4 @@ private:
 };
 
 #endif // BORNAGAIN_CORE_LEGACY_SPECULARMAGNETICSTRATEGY_V2_H
+#endif // USER_API
diff --git a/Sample/LibFF/SomeFormFactors.h b/Sample/LibFF/SomeFormFactors.h
index d879af7f89a3f9fb430d94259fb0c666e05dcb25..80883678150f82bca459d637b7e080ec1f05d0db 100644
--- a/Sample/LibFF/SomeFormFactors.h
+++ b/Sample/LibFF/SomeFormFactors.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_LIBFF_SOMEFORMFACTORS_H
 #define BORNAGAIN_SAMPLE_LIBFF_SOMEFORMFACTORS_H
 
@@ -31,3 +32,4 @@ complex_t ffSphere(cvector_t q, double R);
 } // namespace someff
 
 #endif // BORNAGAIN_SAMPLE_LIBFF_SOMEFORMFACTORS_H
+#endif // USER_API
diff --git a/Sample/Material/BaseMaterialImpl.h b/Sample/Material/BaseMaterialImpl.h
index b484af4e33366c110c47a449b51db528266c18bf..d3f17df05d27acff1311ecc38325e433628391f1 100644
--- a/Sample/Material/BaseMaterialImpl.h
+++ b/Sample/Material/BaseMaterialImpl.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_MATERIAL_BASEMATERIALIMPL_H
 #define BORNAGAIN_SAMPLE_MATERIAL_BASEMATERIALIMPL_H
 
@@ -85,3 +86,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_MATERIAL_BASEMATERIALIMPL_H
+#endif // USER_API
diff --git a/Sample/Material/MagneticMaterialImpl.h b/Sample/Material/MagneticMaterialImpl.h
index a5a30613cedfc073c828c56b9ff69a4735e0a2ef..fceda02bb5286843d0d5700ed77512c20a44c111 100644
--- a/Sample/Material/MagneticMaterialImpl.h
+++ b/Sample/Material/MagneticMaterialImpl.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_MATERIAL_MAGNETICMATERIALIMPL_H
 #define BORNAGAIN_SAMPLE_MATERIAL_MAGNETICMATERIALIMPL_H
 
@@ -63,3 +64,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_MATERIAL_MAGNETICMATERIALIMPL_H
+#endif // USER_API
diff --git a/Sample/Material/Material.h b/Sample/Material/Material.h
index 8ceb5ce52515f064cf6fc2d3fa1aef57c861d5a1..02a2192d72ee2f64140a5f829b4a7385e7ee76cb 100644
--- a/Sample/Material/Material.h
+++ b/Sample/Material/Material.h
@@ -31,17 +31,17 @@ public:
 #ifndef SWIG
     //! Creates material with particular material implementation
     Material(std::unique_ptr<BaseMaterialImpl> material_impl);
-#endif // SWIG
+#endif // USER_API
 
     Material(const Material& material);
 #ifndef SWIG
     Material(Material&& material) = default;
-#endif // SWIG
+#endif // USER_API
 
     Material& operator=(const Material& other);
 #ifndef SWIG
     Material& operator=(Material&& other) = default;
-#endif // SWIG
+#endif // USER_API
 
     //! Constructs a material with inverted magnetization
     Material inverted() const;
@@ -64,7 +64,7 @@ public:
 #ifndef SWIG
     //! Returns the type of underlying material implementation
     MATERIAL_TYPES typeID() const;
-#endif // SWIG
+#endif // USER_API
 
     //! Get the magnetization (in A/m)
     kvector_t magnetization() const;
diff --git a/Sample/Material/MaterialBySLDImpl.h b/Sample/Material/MaterialBySLDImpl.h
index 95863ced0711d9d4942a20f70d6a0b1fe4788688..0d9b578b235d39dde3f750a641384740bc4263ff 100644
--- a/Sample/Material/MaterialBySLDImpl.h
+++ b/Sample/Material/MaterialBySLDImpl.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_MATERIAL_MATERIALBYSLDIMPL_H
 #define BORNAGAIN_SAMPLE_MATERIAL_MATERIALBYSLDIMPL_H
 
@@ -67,3 +68,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_MATERIAL_MATERIALBYSLDIMPL_H
+#endif // USER_API
diff --git a/Sample/Material/MaterialUtils.h b/Sample/Material/MaterialUtils.h
index d8acb02edfb976bce328e8b05fd6e5b10cf2b1ac..7c44d51e818f9e4fae6081193386f348bd69a727 100644
--- a/Sample/Material/MaterialUtils.h
+++ b/Sample/Material/MaterialUtils.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_MATERIAL_MATERIALUTILS_H
 #define BORNAGAIN_SAMPLE_MATERIAL_MATERIALUTILS_H
 
@@ -52,3 +53,4 @@ MATERIAL_TYPES checkMaterialTypes(const std::vector<const Material*>& materials)
 } // namespace MaterialUtils
 
 #endif // BORNAGAIN_SAMPLE_MATERIAL_MATERIALUTILS_H
+#endif // USER_API
diff --git a/Sample/Material/RefractiveMaterialImpl.h b/Sample/Material/RefractiveMaterialImpl.h
index 35912e0ff6dcc0ef4080a9f8b78effb0245a7bdb..950ea43e347ebb9b78af64154df15b008f4a915c 100644
--- a/Sample/Material/RefractiveMaterialImpl.h
+++ b/Sample/Material/RefractiveMaterialImpl.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_MATERIAL_REFRACTIVEMATERIALIMPL_H
 #define BORNAGAIN_SAMPLE_MATERIAL_REFRACTIVEMATERIALIMPL_H
 
@@ -70,3 +71,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_MATERIAL_REFRACTIVEMATERIALIMPL_H
+#endif // USER_API
diff --git a/Sample/Multilayer/Layer.h b/Sample/Multilayer/Layer.h
index 89a20a96a04f48a606999c7e3b48f5365ac2ad2d..1a53cabdff8685dd745a5a186dcbd30d5e57060c 100644
--- a/Sample/Multilayer/Layer.h
+++ b/Sample/Multilayer/Layer.h
@@ -21,7 +21,7 @@
 
 class ParticleLayout;
 
-//! A layer, with thickness (in nanometer) and material.
+//! A layer in a MultiLayer sample.
 //! @ingroup samples
 
 class Layer : public ISampleNode {
diff --git a/Sample/Multilayer/MultiLayerUtils.h b/Sample/Multilayer/MultiLayerUtils.h
index a637ae33d4563db3a66138c52d305c423e3cc338..40c9cd6d53310523c9c60c482cbe00012332a00f 100644
--- a/Sample/Multilayer/MultiLayerUtils.h
+++ b/Sample/Multilayer/MultiLayerUtils.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_MULTILAYER_MULTILAYERUTILS_H
 #define BORNAGAIN_SAMPLE_MULTILAYER_MULTILAYERUTILS_H
 
@@ -42,3 +43,4 @@ bool hasRoughness(const MultiLayer& sample);
 } // namespace MultiLayerUtils
 
 #endif // BORNAGAIN_SAMPLE_MULTILAYER_MULTILAYERUTILS_H
+#endif // USER_API
diff --git a/Sample/Multilayer/PyImport.cpp b/Sample/Multilayer/PyImport.cpp
index 07985e8d97815bb5e10925c6d8e3ca40b432de6e..1f2c711ec105be19b44a0a3010c99e576cb8bc99 100644
--- a/Sample/Multilayer/PyImport.cpp
+++ b/Sample/Multilayer/PyImport.cpp
@@ -15,8 +15,8 @@
 #ifdef BORNAGAIN_PYTHON
 
 #include "Sample/Multilayer/PyImport.h"
-#include "Base/Py/PyEmbeddedUtils.h"
-#include "Base/Py/PythonCore.h"
+#include "Base/Py/PyCore.h"
+#include "Base/Py/PyUtils.h"
 #include "Sample/Multilayer/MultiLayer.h"
 
 namespace {
@@ -24,7 +24,7 @@ namespace {
 std::string error_description(const std::string& title) {
     std::stringstream buf;
     buf << title << "\n";
-    buf << PyEmbeddedUtils::pythonStackTrace() << "\n";
+    buf << PyUtils::pythonStackTrace() << "\n";
     return buf.str();
 }
 
@@ -33,7 +33,7 @@ std::string error_description(const std::string& title) {
 std::unique_ptr<MultiLayer> PyImport::createFromPython(const std::string& script,
                                                        const std::string& functionName,
                                                        const std::string& path) {
-    PyEmbeddedUtils::import_bornagain(path);
+    PyUtils::import_bornagain(path);
 
     PyObject* pCompiledFn = Py_CompileString(script.c_str(), "", Py_file_input);
     if (!pCompiledFn)
@@ -83,7 +83,7 @@ std::unique_ptr<MultiLayer> PyImport::createFromPython(const std::string& script
 
 std::vector<std::string> PyImport::listOfFunctions(const std::string& script,
                                                    const std::string& path) {
-    PyEmbeddedUtils::import_bornagain(path);
+    PyUtils::import_bornagain(path);
 
     PyObject* pCompiledFn = Py_CompileString(script.c_str(), "", Py_file_input);
     if (!pCompiledFn)
@@ -105,7 +105,7 @@ std::vector<std::string> PyImport::listOfFunctions(const std::string& script,
     Py_ssize_t pos = 0;
     while (PyDict_Next(dict, &pos, &key, &value)) {
         if (PyCallable_Check(value)) {
-            std::string func_name = PyEmbeddedUtils::toString(key);
+            std::string func_name = PyUtils::toString(key);
             if (func_name.find("__") == std::string::npos)
                 result.push_back(func_name);
         }
diff --git a/Sample/Multilayer/PyImport.h b/Sample/Multilayer/PyImport.h
index 44d7040a75652077f6815ac58715f00365726cf7..6cca33d04bbf58e08a69330b93f5e1d90326d485 100644
--- a/Sample/Multilayer/PyImport.h
+++ b/Sample/Multilayer/PyImport.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_MULTILAYER_PYIMPORT_H
 #define BORNAGAIN_SAMPLE_MULTILAYER_PYIMPORT_H
 
@@ -49,3 +50,4 @@ std::vector<std::string> listOfFunctions(const std::string& script, const std::s
 #endif // BORNAGAIN_PYTHON
 
 #endif // BORNAGAIN_SAMPLE_MULTILAYER_PYIMPORT_H
+#endif // USER_API
diff --git a/Sample/Particle/FormFactorCoreShell.h b/Sample/Particle/FormFactorCoreShell.h
index 0b6fdce882f2294b8e49f9ff5beacb7bdaad2bf5..1eea2a8e0c67d0eea7bf873ed44531670ff8ac29 100644
--- a/Sample/Particle/FormFactorCoreShell.h
+++ b/Sample/Particle/FormFactorCoreShell.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_PARTICLE_FORMFACTORCORESHELL_H
 #define BORNAGAIN_SAMPLE_PARTICLE_FORMFACTORCORESHELL_H
 
@@ -59,3 +60,4 @@ protected:
 };
 
 #endif // BORNAGAIN_SAMPLE_PARTICLE_FORMFACTORCORESHELL_H
+#endif // USER_API
diff --git a/Sample/Particle/HomogeneousRegion.h b/Sample/Particle/HomogeneousRegion.h
index 0519b6c40aed59c54beedca9f4ec62396e9d256a..1fec82b22fdb4f81986a0d0646235317f81e9f34 100644
--- a/Sample/Particle/HomogeneousRegion.h
+++ b/Sample/Particle/HomogeneousRegion.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_PARTICLE_HOMOGENEOUSREGION_H
 #define BORNAGAIN_SAMPLE_PARTICLE_HOMOGENEOUSREGION_H
 
@@ -42,6 +43,7 @@ struct HomogeneousRegion {
 Material createAveragedMaterial(const Material& layer_mat,
                                 const std::vector<HomogeneousRegion>& regions);
 
-#endif // SWIG
+#endif // USER_API
 
 #endif // BORNAGAIN_SAMPLE_PARTICLE_HOMOGENEOUSREGION_H
+#endif // USER_API
diff --git a/Sample/Particle/IAbstractParticle.h b/Sample/Particle/IAbstractParticle.h
index 15bfeb2b36d320e26f685f664de74d5636077ad4..3b6c21690ef0582d6b13023a49927876502dd4ed 100644
--- a/Sample/Particle/IAbstractParticle.h
+++ b/Sample/Particle/IAbstractParticle.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_PARTICLE_IABSTRACTPARTICLE_H
 #define BORNAGAIN_SAMPLE_PARTICLE_IABSTRACTPARTICLE_H
 
@@ -53,3 +54,4 @@ protected:
 };
 
 #endif // BORNAGAIN_SAMPLE_PARTICLE_IABSTRACTPARTICLE_H
+#endif // USER_API
diff --git a/Sample/Particle/IParticle.h b/Sample/Particle/IParticle.h
index 1629dea65f5ab7711c7b2887776c027eb04c1de6..a50727ce437e6ccaa385aac7c9b6a68823970979 100644
--- a/Sample/Particle/IParticle.h
+++ b/Sample/Particle/IParticle.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_PARTICLE_IPARTICLE_H
 #define BORNAGAIN_SAMPLE_PARTICLE_IPARTICLE_H
 
@@ -95,3 +96,4 @@ protected:
 };
 
 #endif // BORNAGAIN_SAMPLE_PARTICLE_IPARTICLE_H
+#endif // USER_API
diff --git a/Sample/Particle/SlicedParticle.h b/Sample/Particle/SlicedParticle.h
index 3eba07be1fba65bac197c367087e6f1c28f10a2e..cc837b0e31cca30e81cf6ff671bf8d2bb950ff27 100644
--- a/Sample/Particle/SlicedParticle.h
+++ b/Sample/Particle/SlicedParticle.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_PARTICLE_SLICEDPARTICLE_H
 #define BORNAGAIN_SAMPLE_PARTICLE_SLICEDPARTICLE_H
 
@@ -35,3 +36,4 @@ struct SlicedParticle {
 };
 
 #endif // BORNAGAIN_SAMPLE_PARTICLE_SLICEDPARTICLE_H
+#endif // USER_API
diff --git a/Sample/Particle/TRange.h b/Sample/Particle/TRange.h
index 613c23f6dc2c8605446a129bd628dcfe499d60ad..8f51fd7f5caa1013c5fed0c9776f07c745ebc3f8 100644
--- a/Sample/Particle/TRange.h
+++ b/Sample/Particle/TRange.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_PARTICLE_TRANGE_H
 #define BORNAGAIN_SAMPLE_PARTICLE_TRANGE_H
 
@@ -53,3 +54,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_PARTICLE_TRANGE_H
+#endif // USER_API
diff --git a/Sample/Processed/MultiLayerFuncs.h b/Sample/Processed/MultiLayerFuncs.h
index 8aadfc55fd78ce7444353a5c31f57768ae8e96c1..002158acddf89d8c14bc3c79a868411a0bc8c3fd 100644
--- a/Sample/Processed/MultiLayerFuncs.h
+++ b/Sample/Processed/MultiLayerFuncs.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_PROCESSED_MULTILAYERFUNCS_H
 #define BORNAGAIN_SAMPLE_PROCESSED_MULTILAYERFUNCS_H
 
@@ -38,3 +39,4 @@ std::pair<double, double> defaultMaterialProfileLimits(const MultiLayer& multila
 } // namespace swigAPI
 
 #endif // BORNAGAIN_SAMPLE_PROCESSED_MULTILAYERFUNCS_H
+#endif // USER_API
diff --git a/Sample/Processed/ProcessedLayout.h b/Sample/Processed/ProcessedLayout.h
index 38f6a0cfc4d367515ba7ead153c3e606af809ede..2a6a8580dc02f7fd4991a841e6ea37737adcfa53 100644
--- a/Sample/Processed/ProcessedLayout.h
+++ b/Sample/Processed/ProcessedLayout.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_PROCESSED_PROCESSEDLAYOUT_H
 #define BORNAGAIN_SAMPLE_PROCESSED_PROCESSEDLAYOUT_H
 
@@ -67,3 +68,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_PROCESSED_PROCESSEDLAYOUT_H
+#endif // USER_API
diff --git a/Sample/Processed/ProcessedSample.h b/Sample/Processed/ProcessedSample.h
index 150dac0385740bb44541ec9f106c4061f6c82852..336037d452f82d3bc16be45580f390942603e3f2 100644
--- a/Sample/Processed/ProcessedSample.h
+++ b/Sample/Processed/ProcessedSample.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_PROCESSED_PROCESSEDSAMPLE_H
 #define BORNAGAIN_SAMPLE_PROCESSED_PROCESSEDSAMPLE_H
 
@@ -82,3 +83,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_PROCESSED_PROCESSEDSAMPLE_H
+#endif // USER_API
diff --git a/Sample/Processed/ProfileHelper.h b/Sample/Processed/ProfileHelper.h
index bbeeea8d453cabf43931ca53f6dfad7cf2ec843f..bc0329396192271014f24423d8491ec59379484c 100644
--- a/Sample/Processed/ProfileHelper.h
+++ b/Sample/Processed/ProfileHelper.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_PROCESSED_PROFILEHELPER_H
 #define BORNAGAIN_SAMPLE_PROCESSED_PROFILEHELPER_H
 
@@ -47,3 +48,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_PROCESSED_PROFILEHELPER_H
+#endif // USER_API
diff --git a/Sample/RT/ILayerRTCoefficients.h b/Sample/RT/ILayerRTCoefficients.h
index 647902aa57954cbfa90ab3de1d6984ecb66e3128..4bdea5e8de96a1ea3a3bc126644ae4688e6d36c5 100644
--- a/Sample/RT/ILayerRTCoefficients.h
+++ b/Sample/RT/ILayerRTCoefficients.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_RT_ILAYERRTCOEFFICIENTS_H
 #define BORNAGAIN_SAMPLE_RT_ILAYERRTCOEFFICIENTS_H
 
@@ -66,3 +67,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_RT_ILAYERRTCOEFFICIENTS_H
+#endif // USER_API
diff --git a/Sample/RT/MatrixRTCoefficients.h b/Sample/RT/MatrixRTCoefficients.h
index b10fa8a895bab9abe8b70db5b7f254d22a60cc0f..e16063a0b633690f7d7319e6a7753e8ca2023569 100644
--- a/Sample/RT/MatrixRTCoefficients.h
+++ b/Sample/RT/MatrixRTCoefficients.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_RT_MATRIXRTCOEFFICIENTS_H
 #define BORNAGAIN_SAMPLE_RT_MATRIXRTCOEFFICIENTS_H
 
@@ -79,3 +80,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_RT_MATRIXRTCOEFFICIENTS_H
+#endif // USER_API
diff --git a/Sample/RT/ScalarRTCoefficients.h b/Sample/RT/ScalarRTCoefficients.h
index f9eb38944357dc6b133004eb12fee1b2930d2c37..e21adc356d857363124ccbd7f844c5c1f8cea072 100644
--- a/Sample/RT/ScalarRTCoefficients.h
+++ b/Sample/RT/ScalarRTCoefficients.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_RT_SCALARRTCOEFFICIENTS_H
 #define BORNAGAIN_SAMPLE_RT_SCALARRTCOEFFICIENTS_H
 
@@ -132,3 +133,4 @@ inline complex_t ScalarRTCoefficients::getScalarT() const {
 }
 
 #endif // BORNAGAIN_SAMPLE_RT_SCALARRTCOEFFICIENTS_H
+#endif // USER_API
diff --git a/Sample/SampleBuilderEngine/FixedBuilder.h b/Sample/SampleBuilderEngine/FixedBuilder.h
index b0b15b24d9136f2d2e33610599fe61ed9180715a..98ecdcec0b4c3325c5bd055b5e96267e52d40ccd 100644
--- a/Sample/SampleBuilderEngine/FixedBuilder.h
+++ b/Sample/SampleBuilderEngine/FixedBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SAMPLEBUILDERENGINE_FIXEDBUILDER_H
 #define BORNAGAIN_SAMPLE_SAMPLEBUILDERENGINE_FIXEDBUILDER_H
 
@@ -37,3 +38,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_SAMPLEBUILDERENGINE_FIXEDBUILDER_H
+#endif // USER_API
diff --git a/Sample/SampleBuilderEngine/IRegistry.h b/Sample/SampleBuilderEngine/IRegistry.h
index 1ebae261c838ff9f1785a8642e560833b0bb3273..6af06f60a7beacacfb7f287240e6fc38a6f8b4f2 100644
--- a/Sample/SampleBuilderEngine/IRegistry.h
+++ b/Sample/SampleBuilderEngine/IRegistry.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SAMPLEBUILDERENGINE_IREGISTRY_H
 #define BORNAGAIN_SAMPLE_SAMPLEBUILDERENGINE_IREGISTRY_H
 
@@ -59,3 +60,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_SAMPLEBUILDERENGINE_IREGISTRY_H
+#endif // USER_API
diff --git a/Sample/SampleBuilderEngine/ISampleBuilder.h b/Sample/SampleBuilderEngine/ISampleBuilder.h
index 5ec57d8535783c32b6fdf84b449de78f262efccf..06383918222c49fbf4ec6e83ec32ac4dbde227a1 100644
--- a/Sample/SampleBuilderEngine/ISampleBuilder.h
+++ b/Sample/SampleBuilderEngine/ISampleBuilder.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SAMPLEBUILDERENGINE_ISAMPLEBUILDER_H
 #define BORNAGAIN_SAMPLE_SAMPLEBUILDERENGINE_ISAMPLEBUILDER_H
 
@@ -34,3 +35,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_SAMPLEBUILDERENGINE_ISAMPLEBUILDER_H
+#endif // USER_API
diff --git a/Sample/SampleBuilderEngine/SampleBuilderNode.h b/Sample/SampleBuilderEngine/SampleBuilderNode.h
index 0fb43532aa4eb539f20a73bff80fbec287009533..19f3efb35bd098aeff317bfb7e656fd0d751a262 100644
--- a/Sample/SampleBuilderEngine/SampleBuilderNode.h
+++ b/Sample/SampleBuilderEngine/SampleBuilderNode.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SAMPLEBUILDERENGINE_SAMPLEBUILDERNODE_H
 #define BORNAGAIN_SAMPLE_SAMPLEBUILDERENGINE_SAMPLEBUILDERNODE_H
 
@@ -53,3 +54,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_SAMPLEBUILDERENGINE_SAMPLEBUILDERNODE_H
+#endif // USER_API
diff --git a/Sample/SampleBuilderEngine/SampleComponents.h b/Sample/SampleBuilderEngine/SampleComponents.h
index 17f107bac148516ab242d7b486d1d57084a52a24..e1fa4f3c838dc8f5135066259d3c4649de93a1ee 100644
--- a/Sample/SampleBuilderEngine/SampleComponents.h
+++ b/Sample/SampleBuilderEngine/SampleComponents.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SAMPLEBUILDERENGINE_SAMPLECOMPONENTS_H
 #define BORNAGAIN_SAMPLE_SAMPLEBUILDERENGINE_SAMPLECOMPONENTS_H
 
@@ -39,3 +40,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_SAMPLEBUILDERENGINE_SAMPLECOMPONENTS_H
+#endif // USER_API
diff --git a/Sample/SampleBuilderEngine/SampleProvider.h b/Sample/SampleBuilderEngine/SampleProvider.h
index 8c0b67e904495842644f61237126523bca9eb497..6b66a4e033c4573e5f7ce80f39767f525065652b 100644
--- a/Sample/SampleBuilderEngine/SampleProvider.h
+++ b/Sample/SampleBuilderEngine/SampleProvider.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SAMPLEBUILDERENGINE_SAMPLEPROVIDER_H
 #define BORNAGAIN_SAMPLE_SAMPLEBUILDERENGINE_SAMPLEPROVIDER_H
 
@@ -55,3 +56,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_SAMPLEBUILDERENGINE_SAMPLEPROVIDER_H
+#endif // USER_API
diff --git a/Sample/Scattering/FormFactorDecoratorMaterial.h b/Sample/Scattering/FormFactorDecoratorMaterial.h
index a23a988d11d8381734282a1fe3fcc7f665efa0aa..81648cd6006785f406902163d67ef8732f934b40 100644
--- a/Sample/Scattering/FormFactorDecoratorMaterial.h
+++ b/Sample/Scattering/FormFactorDecoratorMaterial.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SCATTERING_FORMFACTORDECORATORMATERIAL_H
 #define BORNAGAIN_SAMPLE_SCATTERING_FORMFACTORDECORATORMATERIAL_H
 
@@ -57,3 +58,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_SCATTERING_FORMFACTORDECORATORMATERIAL_H
+#endif // USER_API
diff --git a/Sample/Scattering/FormFactorDecoratorPositionFactor.h b/Sample/Scattering/FormFactorDecoratorPositionFactor.h
index abe3c90e51fc195a714b8eda93c575e4bb5a55f4..a550afec31844feb4213b242dd7fe0f66414b927 100644
--- a/Sample/Scattering/FormFactorDecoratorPositionFactor.h
+++ b/Sample/Scattering/FormFactorDecoratorPositionFactor.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SCATTERING_FORMFACTORDECORATORPOSITIONFACTOR_H
 #define BORNAGAIN_SAMPLE_SCATTERING_FORMFACTORDECORATORPOSITIONFACTOR_H
 
@@ -50,3 +51,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_SCATTERING_FORMFACTORDECORATORPOSITIONFACTOR_H
+#endif // USER_API
diff --git a/Sample/Scattering/FormFactorDecoratorRotation.h b/Sample/Scattering/FormFactorDecoratorRotation.h
index 80fea1616bb0579a3c36965b12a7034889e9815c..102ec63a95c4c3d2302a5df3debb6e4fd358ebc1 100644
--- a/Sample/Scattering/FormFactorDecoratorRotation.h
+++ b/Sample/Scattering/FormFactorDecoratorRotation.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SCATTERING_FORMFACTORDECORATORROTATION_H
 #define BORNAGAIN_SAMPLE_SCATTERING_FORMFACTORDECORATORROTATION_H
 
@@ -52,3 +53,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_SCATTERING_FORMFACTORDECORATORROTATION_H
+#endif // USER_API
diff --git a/Sample/Scattering/IBornFF.h b/Sample/Scattering/IBornFF.h
index 3860b1e031eb85079a48113a5ca6fd57d086441b..78f1ff42cb32b0c3266a41743f4698ee87e51779 100644
--- a/Sample/Scattering/IBornFF.h
+++ b/Sample/Scattering/IBornFF.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SCATTERING_IBORNFF_H
 #define BORNAGAIN_SAMPLE_SCATTERING_IBORNFF_H
 
@@ -87,3 +88,4 @@ protected:
 };
 
 #endif // BORNAGAIN_SAMPLE_SCATTERING_IBORNFF_H
+#endif // USER_API
diff --git a/Sample/Scattering/IFormFactor.h b/Sample/Scattering/IFormFactor.h
index df4c67ecaaa7ba61d0744f44f57c51e0bf2c8841..bff0f273333afec1b535b47af5c88be46bc8fa00 100644
--- a/Sample/Scattering/IFormFactor.h
+++ b/Sample/Scattering/IFormFactor.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SCATTERING_IFORMFACTOR_H
 #define BORNAGAIN_SAMPLE_SCATTERING_IFORMFACTOR_H
 
@@ -88,3 +89,4 @@ protected:
 };
 
 #endif // BORNAGAIN_SAMPLE_SCATTERING_IFORMFACTOR_H
+#endif // USER_API
diff --git a/Sample/Scattering/IFormFactorDecorator.h b/Sample/Scattering/IFormFactorDecorator.h
index 908f0cb1d37729ec4cc0156928565958fd6141f0..e5d8ad306432a9363f6a86f3b5d7215caec32047 100644
--- a/Sample/Scattering/IFormFactorDecorator.h
+++ b/Sample/Scattering/IFormFactorDecorator.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SCATTERING_IFORMFACTORDECORATOR_H
 #define BORNAGAIN_SAMPLE_SCATTERING_IFORMFACTORDECORATOR_H
 
@@ -50,3 +51,4 @@ protected:
 };
 
 #endif // BORNAGAIN_SAMPLE_SCATTERING_IFORMFACTORDECORATOR_H
+#endif // USER_API
diff --git a/Sample/Scattering/ISampleNode.h b/Sample/Scattering/ISampleNode.h
index 831a2cd2fce5f40f721832efd306d4cc082f2235..e52c1cad136f4156133b7aa58d2faf0bdc70b51e 100644
--- a/Sample/Scattering/ISampleNode.h
+++ b/Sample/Scattering/ISampleNode.h
@@ -12,6 +12,7 @@
 //
 //  ************************************************************************************************
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SCATTERING_ISAMPLENODE_H
 #define BORNAGAIN_SAMPLE_SCATTERING_ISAMPLENODE_H
 
@@ -43,3 +44,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_SCATTERING_ISAMPLENODE_H
+#endif // USER_API
diff --git a/Sample/Scattering/LayerFillLimits.h b/Sample/Scattering/LayerFillLimits.h
index 39c7252dfaaabb10c3a681b9cb725a7857847080..308c74d60e64d21b7f1fb5011afd92b062bc4025 100644
--- a/Sample/Scattering/LayerFillLimits.h
+++ b/Sample/Scattering/LayerFillLimits.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SCATTERING_LAYERFILLLIMITS_H
 #define BORNAGAIN_SAMPLE_SCATTERING_LAYERFILLLIMITS_H
 
@@ -50,3 +51,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_SCATTERING_LAYERFILLLIMITS_H
+#endif // USER_API
diff --git a/Sample/Scattering/ZLimits.h b/Sample/Scattering/ZLimits.h
index 46f81f2f422e14d49efa65d6c9f12e65cef784e8..a77cb854de3efc121c676695529267506f9a2668 100644
--- a/Sample/Scattering/ZLimits.h
+++ b/Sample/Scattering/ZLimits.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SCATTERING_ZLIMITS_H
 #define BORNAGAIN_SAMPLE_SCATTERING_ZLIMITS_H
 
@@ -71,3 +72,4 @@ bool operator!=(const ZLimits& left, const ZLimits& right);
 std::ostream& operator<<(std::ostream& ostr, const ZLimits& limits);
 
 #endif // BORNAGAIN_SAMPLE_SCATTERING_ZLIMITS_H
+#endif // USER_API
diff --git a/Sample/Shapes/Box.h b/Sample/Shapes/Box.h
index e166bf89e9a6339377bbc80939366959121dea00..9fcdc287505bb6e5b8153632f29cb6bbbf698bed 100644
--- a/Sample/Shapes/Box.h
+++ b/Sample/Shapes/Box.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SHAPES_BOX_H
 #define BORNAGAIN_SAMPLE_SHAPES_BOX_H
 
@@ -28,3 +29,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_SHAPES_BOX_H
+#endif // USER_API
diff --git a/Sample/Shapes/DoubleEllipse.h b/Sample/Shapes/DoubleEllipse.h
index c616b6cfb97e67cdb0621c1eafe3ada23c469d3f..874d28be4ca197f0db896377d4e03833bc5ad2cf 100644
--- a/Sample/Shapes/DoubleEllipse.h
+++ b/Sample/Shapes/DoubleEllipse.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SHAPES_DOUBLEELLIPSE_H
 #define BORNAGAIN_SAMPLE_SHAPES_DOUBLEELLIPSE_H
 
@@ -28,3 +29,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_SHAPES_DOUBLEELLIPSE_H
+#endif // USER_API
diff --git a/Sample/Shapes/IShape.h b/Sample/Shapes/IShape.h
index 96d4c30b6ff8080b389323610ebfec5880eebaa2..75b747750b27f6e718c2c96afcf34fa5441e27f7 100644
--- a/Sample/Shapes/IShape.h
+++ b/Sample/Shapes/IShape.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SHAPES_ISHAPE_H
 #define BORNAGAIN_SAMPLE_SHAPES_ISHAPE_H
 
@@ -52,3 +53,4 @@ std::vector<kvector_t> RectangleVertices(double length, double width, double z);
 std::vector<kvector_t> EllipseVertices(double r_x, double r_y, double z);
 
 #endif // BORNAGAIN_SAMPLE_SHAPES_ISHAPE_H
+#endif // USER_API
diff --git a/Sample/Shapes/RippleCosine.h b/Sample/Shapes/RippleCosine.h
index cef9cdd584d9204da56f597e77f093ed9ed763b7..ce9356d44c9cdaef81dd06e620edf77243371564 100644
--- a/Sample/Shapes/RippleCosine.h
+++ b/Sample/Shapes/RippleCosine.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SHAPES_RIPPLECOSINE_H
 #define BORNAGAIN_SAMPLE_SHAPES_RIPPLECOSINE_H
 
@@ -28,3 +29,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_SHAPES_RIPPLECOSINE_H
+#endif // USER_API
diff --git a/Sample/Shapes/RippleSawtooth.h b/Sample/Shapes/RippleSawtooth.h
index 6e1c971c45d203d74f3a2d0f5637a04a8927f5ab..b9592b116bf27c958997362d5d97ff7bbe43d07a 100644
--- a/Sample/Shapes/RippleSawtooth.h
+++ b/Sample/Shapes/RippleSawtooth.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SHAPES_RIPPLESAWTOOTH_H
 #define BORNAGAIN_SAMPLE_SHAPES_RIPPLESAWTOOTH_H
 
@@ -28,3 +29,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_SHAPES_RIPPLESAWTOOTH_H
+#endif // USER_API
diff --git a/Sample/Shapes/TruncatedEllipsoid.h b/Sample/Shapes/TruncatedEllipsoid.h
index ff139024741cf71c5521217bf37754d93bb7c9d9..d90f9589183969427b334b1aba859079a784a466 100644
--- a/Sample/Shapes/TruncatedEllipsoid.h
+++ b/Sample/Shapes/TruncatedEllipsoid.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SHAPES_TRUNCATEDELLIPSOID_H
 #define BORNAGAIN_SAMPLE_SHAPES_TRUNCATEDELLIPSOID_H
 
@@ -28,3 +29,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_SHAPES_TRUNCATEDELLIPSOID_H
+#endif // USER_API
diff --git a/Sample/Slice/KzComputation.h b/Sample/Slice/KzComputation.h
index b64b97bad052ec9dd12741704240ef0cbbb521c8..491213450dd9db6bd56321f40511d38f9f2cbf83 100644
--- a/Sample/Slice/KzComputation.h
+++ b/Sample/Slice/KzComputation.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SLICE_KZCOMPUTATION_H
 #define BORNAGAIN_SAMPLE_SLICE_KZCOMPUTATION_H
 
@@ -52,3 +53,4 @@ std::vector<complex_t> computeKzFromRefIndices(const std::vector<Slice>& slices,
 } // namespace KzComputation
 
 #endif // BORNAGAIN_SAMPLE_SLICE_KZCOMPUTATION_H
+#endif // USER_API
diff --git a/Sample/Slice/LayerInterface.h b/Sample/Slice/LayerInterface.h
index 3528b31fcc056d4ffa51fa4a28de558bdfd58226..f0c5cd824b122ca243ed59e2ef9b4c923350b2f7 100644
--- a/Sample/Slice/LayerInterface.h
+++ b/Sample/Slice/LayerInterface.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SLICE_LAYERINTERFACE_H
 #define BORNAGAIN_SAMPLE_SLICE_LAYERINTERFACE_H
 
@@ -76,3 +77,4 @@ inline const Layer* LayerInterface::bottomLayer() const {
 }
 
 #endif // BORNAGAIN_SAMPLE_SLICE_LAYERINTERFACE_H
+#endif // USER_API
diff --git a/Sample/Slice/Slice.h b/Sample/Slice/Slice.h
index 9c83e230326f18082a2d80a07ac41ae43496ce41..e35e43b3e78d472304631a01b9afde676f5c096c 100644
--- a/Sample/Slice/Slice.h
+++ b/Sample/Slice/Slice.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SLICE_SLICE_H
 #define BORNAGAIN_SAMPLE_SLICE_SLICE_H
 
@@ -68,3 +69,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_SLICE_SLICE_H
+#endif // USER_API
diff --git a/Sample/Slice/SlicedFormFactorList.h b/Sample/Slice/SlicedFormFactorList.h
index 6780b0221a5601e676cfc2a77be32b035e571b13..ff6ea915afd4589eab243ed5a9d24e2a3ae92c27 100644
--- a/Sample/Slice/SlicedFormFactorList.h
+++ b/Sample/Slice/SlicedFormFactorList.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SLICE_SLICEDFORMFACTORLIST_H
 #define BORNAGAIN_SAMPLE_SLICE_SLICEDFORMFACTORLIST_H
 
@@ -56,3 +57,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_SLICE_SLICEDFORMFACTORLIST_H
+#endif // USER_API
diff --git a/Sample/SoftParticle/SoftParticles.h b/Sample/SoftParticle/SoftParticles.h
index 9e73cbdbb6234b6a5eec532ec21bea73389564e1..2f4ba048cae73333c21ba300c81582de3649cef9 100644
--- a/Sample/SoftParticle/SoftParticles.h
+++ b/Sample/SoftParticle/SoftParticles.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SOFTPARTICLE_SOFTPARTICLES_H
 #define BORNAGAIN_SAMPLE_SOFTPARTICLE_SOFTPARTICLES_H
 
@@ -24,3 +25,4 @@
 #include "Sample/SoftParticle/FormFactorSphereLogNormalRadius.h"
 
 #endif // BORNAGAIN_SAMPLE_SOFTPARTICLE_SOFTPARTICLES_H
+#endif // USER_API
diff --git a/Sample/Specular/ISpecularStrategy.h b/Sample/Specular/ISpecularStrategy.h
index 3fe2700168cce7e453477dbf380a74f5ca9efd9e..a4958fe6faf699ec85cf9c4ab17d1d3441e6a76a 100644
--- a/Sample/Specular/ISpecularStrategy.h
+++ b/Sample/Specular/ISpecularStrategy.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SPECULAR_ISPECULARSTRATEGY_H
 #define BORNAGAIN_SAMPLE_SPECULAR_ISPECULARSTRATEGY_H
 
@@ -49,3 +50,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_SPECULAR_ISPECULARSTRATEGY_H
+#endif // USER_API
diff --git a/Sample/Specular/SpecularMagneticNCStrategy.h b/Sample/Specular/SpecularMagneticNCStrategy.h
index da43b6575a130ba8c9bdbf6d40f0ee66ea058d6a..6ad085e86c6c8376868a0eca31b2e42f961b8405 100644
--- a/Sample/Specular/SpecularMagneticNCStrategy.h
+++ b/Sample/Specular/SpecularMagneticNCStrategy.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SPECULAR_SPECULARMAGNETICNCSTRATEGY_H
 #define BORNAGAIN_SAMPLE_SPECULAR_SPECULARMAGNETICNCSTRATEGY_H
 
@@ -43,3 +44,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_SPECULAR_SPECULARMAGNETICNCSTRATEGY_H
+#endif // USER_API
diff --git a/Sample/Specular/SpecularMagneticStrategy.h b/Sample/Specular/SpecularMagneticStrategy.h
index f936cc94d8b124eb7a430ecdd0f27d1ac1d76892..e948dc435c537ef81280533111d72687e47569f4 100644
--- a/Sample/Specular/SpecularMagneticStrategy.h
+++ b/Sample/Specular/SpecularMagneticStrategy.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SPECULAR_SPECULARMAGNETICSTRATEGY_H
 #define BORNAGAIN_SAMPLE_SPECULAR_SPECULARMAGNETICSTRATEGY_H
 
@@ -64,3 +65,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_SPECULAR_SPECULARMAGNETICSTRATEGY_H
+#endif // USER_API
diff --git a/Sample/Specular/SpecularMagneticTanhStrategy.h b/Sample/Specular/SpecularMagneticTanhStrategy.h
index 52322a81a7529ad9aa333ede9f79dade3e987cc2..01a0632a9bfa0015799f65d4ba72cc51de632c5d 100644
--- a/Sample/Specular/SpecularMagneticTanhStrategy.h
+++ b/Sample/Specular/SpecularMagneticTanhStrategy.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SPECULAR_SPECULARMAGNETICTANHSTRATEGY_H
 #define BORNAGAIN_SAMPLE_SPECULAR_SPECULARMAGNETICTANHSTRATEGY_H
 
@@ -40,3 +41,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_SPECULAR_SPECULARMAGNETICTANHSTRATEGY_H
+#endif // USER_API
diff --git a/Sample/Specular/SpecularScalarNCStrategy.h b/Sample/Specular/SpecularScalarNCStrategy.h
index f492ae35d2af3f410f555295e9aa0d07b2f666d5..d6b566d5c0799105bb7b627f08b2e0a32a51d9bf 100644
--- a/Sample/Specular/SpecularScalarNCStrategy.h
+++ b/Sample/Specular/SpecularScalarNCStrategy.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SPECULAR_SPECULARSCALARNCSTRATEGY_H
 #define BORNAGAIN_SAMPLE_SPECULAR_SPECULARSCALARNCSTRATEGY_H
 
@@ -42,3 +43,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_SPECULAR_SPECULARSCALARNCSTRATEGY_H
+#endif // USER_API
diff --git a/Sample/Specular/SpecularScalarStrategy.h b/Sample/Specular/SpecularScalarStrategy.h
index 6ba7a7ddd4bdbbe4ea8ff2da81055f346d17eb22..599b609138a18b8ff617dc250c494c69f0a6cdb8 100644
--- a/Sample/Specular/SpecularScalarStrategy.h
+++ b/Sample/Specular/SpecularScalarStrategy.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SPECULAR_SPECULARSCALARSTRATEGY_H
 #define BORNAGAIN_SAMPLE_SPECULAR_SPECULARSCALARSTRATEGY_H
 
@@ -65,3 +66,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_SPECULAR_SPECULARSCALARSTRATEGY_H
+#endif // USER_API
diff --git a/Sample/Specular/SpecularScalarTanhStrategy.h b/Sample/Specular/SpecularScalarTanhStrategy.h
index bf8f908f141cb53cb98bb250773d7b86fff0913b..19de5f143afe5e7cec34c9b62f972669a1080549 100644
--- a/Sample/Specular/SpecularScalarTanhStrategy.h
+++ b/Sample/Specular/SpecularScalarTanhStrategy.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SPECULAR_SPECULARSCALARTANHSTRATEGY_H
 #define BORNAGAIN_SAMPLE_SPECULAR_SPECULARSCALARTANHSTRATEGY_H
 
@@ -38,3 +39,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_SPECULAR_SPECULARSCALARTANHSTRATEGY_H
+#endif // USER_API
diff --git a/Sample/Specular/SpecularStrategyBuilder.h b/Sample/Specular/SpecularStrategyBuilder.h
index ee0c01cc950963591a2a2fca573c59b773b90a34..a13336e14b9584d1583e6c6e496be86c68b5f347 100644
--- a/Sample/Specular/SpecularStrategyBuilder.h
+++ b/Sample/Specular/SpecularStrategyBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_SPECULAR_SPECULARSTRATEGYBUILDER_H
 #define BORNAGAIN_SAMPLE_SPECULAR_SPECULARSTRATEGYBUILDER_H
 
@@ -29,3 +30,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_SPECULAR_SPECULARSTRATEGYBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/BoxCompositionBuilder.h b/Sample/StandardSamples/BoxCompositionBuilder.h
index 12603fb3b61811dc6b40d69e7a81fcffbddf5db9..65204fb1ecad0cfea23905545b25b11628693b3b 100644
--- a/Sample/StandardSamples/BoxCompositionBuilder.h
+++ b/Sample/StandardSamples/BoxCompositionBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_BOXCOMPOSITIONBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_BOXCOMPOSITIONBUILDER_H
 
@@ -62,3 +63,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_BOXCOMPOSITIONBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/BoxesSquareLatticeBuilder.h b/Sample/StandardSamples/BoxesSquareLatticeBuilder.h
index 9af2f5c4dff194e54b8e03c09852488bd7ab21bc..4a52ab83531505b85f1bc24e14f1c98a2bf562aa 100644
--- a/Sample/StandardSamples/BoxesSquareLatticeBuilder.h
+++ b/Sample/StandardSamples/BoxesSquareLatticeBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_BOXESSQUARELATTICEBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_BOXESSQUARELATTICEBUILDER_H
 
@@ -30,3 +31,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_BOXESSQUARELATTICEBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/CoreShellParticleBuilder.h b/Sample/StandardSamples/CoreShellParticleBuilder.h
index 3dde8bda2585721f20975fc5c059d706a93541be..c706aa0e3da6b6741b62a52074e939103363dfba 100644
--- a/Sample/StandardSamples/CoreShellParticleBuilder.h
+++ b/Sample/StandardSamples/CoreShellParticleBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_CORESHELLPARTICLEBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_CORESHELLPARTICLEBUILDER_H
 
@@ -38,3 +39,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_CORESHELLPARTICLEBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/CustomMorphologyBuilder.h b/Sample/StandardSamples/CustomMorphologyBuilder.h
index a6e5767ad69df914814a49fba9ccd99c1dbf6cfc..f1b997e29a8067033eac776bbdb6caef5661be88 100644
--- a/Sample/StandardSamples/CustomMorphologyBuilder.h
+++ b/Sample/StandardSamples/CustomMorphologyBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_CUSTOMMORPHOLOGYBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_CUSTOMMORPHOLOGYBUILDER_H
 
@@ -30,3 +31,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_CUSTOMMORPHOLOGYBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/CylindersAndPrismsBuilder.h b/Sample/StandardSamples/CylindersAndPrismsBuilder.h
index 5d18aa8384ce07ba7ebdd789898ea65d855bf6fa..282195abf110123f701637e57e8c427677d7c113 100644
--- a/Sample/StandardSamples/CylindersAndPrismsBuilder.h
+++ b/Sample/StandardSamples/CylindersAndPrismsBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_CYLINDERSANDPRISMSBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_CYLINDERSANDPRISMSBUILDER_H
 
@@ -30,3 +31,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_CYLINDERSANDPRISMSBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/CylindersBuilder.h b/Sample/StandardSamples/CylindersBuilder.h
index cad88c2fea9919e9412ad0f4a2c5f8e2c7c2980d..cfa02327f09a42bd53645ee12ee4f46c5cfe72b1 100644
--- a/Sample/StandardSamples/CylindersBuilder.h
+++ b/Sample/StandardSamples/CylindersBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_CYLINDERSBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_CYLINDERSBUILDER_H
 
@@ -74,3 +75,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_CYLINDERSBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/FeNiBilayerBuilder.h b/Sample/StandardSamples/FeNiBilayerBuilder.h
index 0feb343dbd6906af7a4803795e4b1299b31cccb1..90f9f9c505d20dea671c6eb7b00f48668f703a63 100644
--- a/Sample/StandardSamples/FeNiBilayerBuilder.h
+++ b/Sample/StandardSamples/FeNiBilayerBuilder.h
@@ -17,6 +17,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_FENIBILAYERBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_FENIBILAYERBUILDER_H
 
@@ -53,3 +54,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_FENIBILAYERBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/HomogeneousMultilayerBuilder.h b/Sample/StandardSamples/HomogeneousMultilayerBuilder.h
index 3cd30a87737661581c98622116beeb3ebe54127e..466504bde80e7645e9fc12df93a82d6999ca7997 100644
--- a/Sample/StandardSamples/HomogeneousMultilayerBuilder.h
+++ b/Sample/StandardSamples/HomogeneousMultilayerBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_HOMOGENEOUSMULTILAYERBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_HOMOGENEOUSMULTILAYERBUILDER_H
 
@@ -32,3 +33,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_HOMOGENEOUSMULTILAYERBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/LatticeBuilder.h b/Sample/StandardSamples/LatticeBuilder.h
index 997e74fc250585fa8e0b20a8cfc67a2ae95ae2ad..9ffa62c6c0fcdc8ad60fdf7d779ad8852bbde4f7 100644
--- a/Sample/StandardSamples/LatticeBuilder.h
+++ b/Sample/StandardSamples/LatticeBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_LATTICEBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_LATTICEBUILDER_H
 
@@ -30,3 +31,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_LATTICEBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/LayersWithAbsorptionBuilder.h b/Sample/StandardSamples/LayersWithAbsorptionBuilder.h
index 22688c186bd8222c9b7b79a4b6413ecc77e5b313..ded0762d5a53764a58ce4d625ad9dcea3e5d0fe2 100644
--- a/Sample/StandardSamples/LayersWithAbsorptionBuilder.h
+++ b/Sample/StandardSamples/LayersWithAbsorptionBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_LAYERSWITHABSORPTIONBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_LAYERSWITHABSORPTIONBUILDER_H
 
@@ -45,3 +46,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_LAYERSWITHABSORPTIONBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/LayersWithAbsorptionBySLDBuilder.h b/Sample/StandardSamples/LayersWithAbsorptionBySLDBuilder.h
index ae805e2b63bad22c37290976d2e0415cafdb8bf7..74348bba2e86f471d2e5e591d76b157b28d7c82c 100644
--- a/Sample/StandardSamples/LayersWithAbsorptionBySLDBuilder.h
+++ b/Sample/StandardSamples/LayersWithAbsorptionBySLDBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_LAYERSWITHABSORPTIONBYSLDBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_LAYERSWITHABSORPTIONBYSLDBUILDER_H
 
@@ -32,3 +33,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_LAYERSWITHABSORPTIONBYSLDBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/MagneticLayersBuilder.h b/Sample/StandardSamples/MagneticLayersBuilder.h
index 7b43960a7da610e91c049791ac70c8bf4e96a810..befd86602ed7d121268daaa59d2139a561a2f6e0 100644
--- a/Sample/StandardSamples/MagneticLayersBuilder.h
+++ b/Sample/StandardSamples/MagneticLayersBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_MAGNETICLAYERSBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_MAGNETICLAYERSBUILDER_H
 
@@ -66,3 +67,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_MAGNETICLAYERSBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/MagneticParticlesBuilder.h b/Sample/StandardSamples/MagneticParticlesBuilder.h
index 3c258b94cc9685493f8bbb0059959a5ed6adc468..b758b0a5902b224eb9ad750d6deb8ce438a39a5c 100644
--- a/Sample/StandardSamples/MagneticParticlesBuilder.h
+++ b/Sample/StandardSamples/MagneticParticlesBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_MAGNETICPARTICLESBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_MAGNETICPARTICLESBUILDER_H
 
@@ -46,3 +47,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_MAGNETICPARTICLESBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/MesoCrystalBuilder.h b/Sample/StandardSamples/MesoCrystalBuilder.h
index 77f27453af7c6dd78d1a3b9fffcbe705726da531..d9afaf8897eb86109b23d6e71c8e76efb9ea7484 100644
--- a/Sample/StandardSamples/MesoCrystalBuilder.h
+++ b/Sample/StandardSamples/MesoCrystalBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_MESOCRYSTALBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_MESOCRYSTALBUILDER_H
 
@@ -30,3 +31,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_MESOCRYSTALBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/MultiLayerWithNCRoughnessBuilder.h b/Sample/StandardSamples/MultiLayerWithNCRoughnessBuilder.h
index ad0aa325d57ef61ec1bfdd21e5af8495c4de5000..eff31cf24a204d57b7c50a8efe160bc069dd1300 100644
--- a/Sample/StandardSamples/MultiLayerWithNCRoughnessBuilder.h
+++ b/Sample/StandardSamples/MultiLayerWithNCRoughnessBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_MULTILAYERWITHNCROUGHNESSBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_MULTILAYERWITHNCROUGHNESSBUILDER_H
 
@@ -30,3 +31,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_MULTILAYERWITHNCROUGHNESSBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/MultiLayerWithRoughnessBuilder.h b/Sample/StandardSamples/MultiLayerWithRoughnessBuilder.h
index f87040eb72c4b4fa219364a5728569c0f7b515ec..80d6c514fa8c9b972e4ab1598e89bd4b294ecd64 100644
--- a/Sample/StandardSamples/MultiLayerWithRoughnessBuilder.h
+++ b/Sample/StandardSamples/MultiLayerWithRoughnessBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_MULTILAYERWITHROUGHNESSBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_MULTILAYERWITHROUGHNESSBUILDER_H
 
@@ -30,3 +31,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_MULTILAYERWITHROUGHNESSBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/MultipleLayoutBuilder.h b/Sample/StandardSamples/MultipleLayoutBuilder.h
index 05ee9b0e8cadaaa6819c29d4e24a2861a147cade..452f3f813959f3db34b337a9157dafc81d9a43dc 100644
--- a/Sample/StandardSamples/MultipleLayoutBuilder.h
+++ b/Sample/StandardSamples/MultipleLayoutBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_MULTIPLELAYOUTBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_MULTIPLELAYOUTBUILDER_H
 
@@ -31,3 +32,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_MULTIPLELAYOUTBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/ParaCrystalBuilder.h b/Sample/StandardSamples/ParaCrystalBuilder.h
index 51fc6573e9f604077319dabd44e2c7e05fa90464..94a019e472012f7d6ac28e1f048c2ee0f7393b85 100644
--- a/Sample/StandardSamples/ParaCrystalBuilder.h
+++ b/Sample/StandardSamples/ParaCrystalBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_PARACRYSTALBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_PARACRYSTALBUILDER_H
 
@@ -67,3 +68,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_PARACRYSTALBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/ParticleCompositionBuilder.h b/Sample/StandardSamples/ParticleCompositionBuilder.h
index 22ca2a9395322b0e12ba2873ef661fca45c72bbe..0f7eb497737bf0ad08dc2c4989fe3bea08678649 100644
--- a/Sample/StandardSamples/ParticleCompositionBuilder.h
+++ b/Sample/StandardSamples/ParticleCompositionBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_PARTICLECOMPOSITIONBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_PARTICLECOMPOSITIONBUILDER_H
 
@@ -30,3 +31,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_PARTICLECOMPOSITIONBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/ParticleDistributionsBuilder.h b/Sample/StandardSamples/ParticleDistributionsBuilder.h
index f0c643f643cffe83c3071905103215ac5ad053a0..d3335a80fc06959d94dd7dae718fb6a4be9596cf 100644
--- a/Sample/StandardSamples/ParticleDistributionsBuilder.h
+++ b/Sample/StandardSamples/ParticleDistributionsBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_PARTICLEDISTRIBUTIONSBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_PARTICLEDISTRIBUTIONSBUILDER_H
 
@@ -89,3 +90,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_PARTICLEDISTRIBUTIONSBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/ParticleInVacuumBuilder.h b/Sample/StandardSamples/ParticleInVacuumBuilder.h
index 200c6a5f156518bcd929f3fd743d9070bb0684fd..11b1e8a91a67f309e9258670f4d724475eb703b9 100644
--- a/Sample/StandardSamples/ParticleInVacuumBuilder.h
+++ b/Sample/StandardSamples/ParticleInVacuumBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_PARTICLEINVACUUMBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_PARTICLEINVACUUMBUILDER_H
 
@@ -42,3 +43,4 @@ protected:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_PARTICLEINVACUUMBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/PercusYevickBuilder.h b/Sample/StandardSamples/PercusYevickBuilder.h
index 06cc34d1198c1401ae2b2a4c5d6e281c2c5df9d6..3a2ede1f6fc3571f0df551e199658c2823743ae9 100644
--- a/Sample/StandardSamples/PercusYevickBuilder.h
+++ b/Sample/StandardSamples/PercusYevickBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_PERCUSYEVICKBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_PERCUSYEVICKBUILDER_H
 
@@ -30,3 +31,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_PERCUSYEVICKBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/PlainMultiLayerBySLDBuilder.h b/Sample/StandardSamples/PlainMultiLayerBySLDBuilder.h
index 5faf02f2e03883249f2e38f55be05e9e905e50e5..2fa5955e5d7e96e70873838768ae53e3ed2de6dd 100644
--- a/Sample/StandardSamples/PlainMultiLayerBySLDBuilder.h
+++ b/Sample/StandardSamples/PlainMultiLayerBySLDBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_PLAINMULTILAYERBYSLDBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_PLAINMULTILAYERBYSLDBUILDER_H
 
@@ -44,3 +45,4 @@ protected:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_PLAINMULTILAYERBYSLDBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/ReferenceMaterials.h b/Sample/StandardSamples/ReferenceMaterials.h
index bd57e6dd130f24f6c8258efec32ae606ee2a2f20..1b4fb4b9e9eebd12c0ab6458dc8bc9e9f1d5d1b2 100644
--- a/Sample/StandardSamples/ReferenceMaterials.h
+++ b/Sample/StandardSamples/ReferenceMaterials.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_REFERENCEMATERIALS_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_REFERENCEMATERIALS_H
 
@@ -38,3 +39,4 @@ static const Material Substrate2 = HomogeneousMaterial("Substrate2", 3.212e-6, 3
 } // namespace refMat
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_REFERENCEMATERIALS_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/ResonatorBuilder.h b/Sample/StandardSamples/ResonatorBuilder.h
index 31271cd3da817722b4bf68887fdcf1766dd57efc..3e456a64259f9da65afad99cb18eb407c641d748 100644
--- a/Sample/StandardSamples/ResonatorBuilder.h
+++ b/Sample/StandardSamples/ResonatorBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_RESONATORBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_RESONATORBUILDER_H
 
@@ -34,3 +35,4 @@ private:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_RESONATORBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/RipplesBuilder.h b/Sample/StandardSamples/RipplesBuilder.h
index 47f611b315e543447ef9f5024d7ab7bf9a54680a..5367d0e2ecbeee6d0f752facb2606dfe1a1eee99 100644
--- a/Sample/StandardSamples/RipplesBuilder.h
+++ b/Sample/StandardSamples/RipplesBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_RIPPLESBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_RIPPLESBUILDER_H
 
@@ -47,3 +48,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_RIPPLESBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/RotatedPyramidsBuilder.h b/Sample/StandardSamples/RotatedPyramidsBuilder.h
index 7bf8d02379f41768a1f64247d36bdf1542caaf17..cfba796dd6acd8d4c7ecba272b672883620174c9 100644
--- a/Sample/StandardSamples/RotatedPyramidsBuilder.h
+++ b/Sample/StandardSamples/RotatedPyramidsBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_ROTATEDPYRAMIDSBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_ROTATEDPYRAMIDSBUILDER_H
 
@@ -30,3 +31,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_ROTATEDPYRAMIDSBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/SizeDistributionModelsBuilder.h b/Sample/StandardSamples/SizeDistributionModelsBuilder.h
index 757fc77bf3f9741d12e37bad18164dfc42d49b49..7e01c21c55181a610d6d0574f58b686b5b3804e4 100644
--- a/Sample/StandardSamples/SizeDistributionModelsBuilder.h
+++ b/Sample/StandardSamples/SizeDistributionModelsBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_SIZEDISTRIBUTIONMODELSBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_SIZEDISTRIBUTIONMODELSBUILDER_H
 
@@ -57,3 +58,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_SIZEDISTRIBUTIONMODELSBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/SlicedCompositionBuilder.h b/Sample/StandardSamples/SlicedCompositionBuilder.h
index 8770fe902381e469ba378dc13e54b1c6f36ca868..368e4e113fde959fd56562067ea2b40040a77acd 100644
--- a/Sample/StandardSamples/SlicedCompositionBuilder.h
+++ b/Sample/StandardSamples/SlicedCompositionBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_SLICEDCOMPOSITIONBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_SLICEDCOMPOSITIONBUILDER_H
 
@@ -30,3 +31,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_SLICEDCOMPOSITIONBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/SlicedCylindersBuilder.h b/Sample/StandardSamples/SlicedCylindersBuilder.h
index 848d8836338b1bb33c60460b19f94fa7339dfed7..729b2a3de72b493369adb997f9aadca52be2ca8d 100644
--- a/Sample/StandardSamples/SlicedCylindersBuilder.h
+++ b/Sample/StandardSamples/SlicedCylindersBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_SLICEDCYLINDERSBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_SLICEDCYLINDERSBUILDER_H
 
@@ -49,3 +50,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_SLICEDCYLINDERSBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/ThickAbsorptiveSampleBuilder.h b/Sample/StandardSamples/ThickAbsorptiveSampleBuilder.h
index f2daabaec738b81a524ede75a1379db045cd35c2..0ba7bfae303eab223879649cd176a260a94ff39a 100644
--- a/Sample/StandardSamples/ThickAbsorptiveSampleBuilder.h
+++ b/Sample/StandardSamples/ThickAbsorptiveSampleBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_THICKABSORPTIVESAMPLEBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_THICKABSORPTIVESAMPLEBUILDER_H
 
@@ -27,3 +28,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_THICKABSORPTIVESAMPLEBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/TransformationsBuilder.h b/Sample/StandardSamples/TransformationsBuilder.h
index 3b722d179e4b131d45f42b694961a5dd56aeb0e6..dbae7ffd97e904118d93f4e0948cc08d9bbb4348 100644
--- a/Sample/StandardSamples/TransformationsBuilder.h
+++ b/Sample/StandardSamples/TransformationsBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_TRANSFORMATIONSBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_TRANSFORMATIONSBUILDER_H
 
@@ -30,3 +31,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_TRANSFORMATIONSBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/TwoDimLatticeBuilder.h b/Sample/StandardSamples/TwoDimLatticeBuilder.h
index 7c144696f0efd93df13d7135cb245af5dd0b057d..edc22ba3955b1bf8e245ebb68cb1f8ea5388dcae 100644
--- a/Sample/StandardSamples/TwoDimLatticeBuilder.h
+++ b/Sample/StandardSamples/TwoDimLatticeBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_TWODIMLATTICEBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_TWODIMLATTICEBUILDER_H
 
@@ -72,3 +73,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_TWODIMLATTICEBUILDER_H
+#endif // USER_API
diff --git a/Sample/StandardSamples/TwoLayerRoughnessBuilder.h b/Sample/StandardSamples/TwoLayerRoughnessBuilder.h
index bebd5f18589a7000a492e7d3112a824b5de1259c..7056e43f7b061f2ffc195b8af1c8d65688f92580 100644
--- a/Sample/StandardSamples/TwoLayerRoughnessBuilder.h
+++ b/Sample/StandardSamples/TwoLayerRoughnessBuilder.h
@@ -16,6 +16,7 @@
 #error no need to expose this header to Swig
 #endif
 
+#ifndef USER_API
 #ifndef BORNAGAIN_SAMPLE_STANDARDSAMPLES_TWOLAYERROUGHNESSBUILDER_H
 #define BORNAGAIN_SAMPLE_STANDARDSAMPLES_TWOLAYERROUGHNESSBUILDER_H
 
@@ -30,3 +31,4 @@ public:
 };
 
 #endif // BORNAGAIN_SAMPLE_STANDARDSAMPLES_TWOLAYERROUGHNESSBUILDER_H
+#endif // USER_API
diff --git a/Tests/Functional/Core/Consistence/CompareTwoReferences.cpp b/Tests/Functional/Core/Consistence/CompareTwoReferences.cpp
index 3cc2a1902d4edf9cc1056f3ee250b033aaa3241a..def7e10296a285cff08a96a3553f5908c8465ace 100644
--- a/Tests/Functional/Core/Consistence/CompareTwoReferences.cpp
+++ b/Tests/Functional/Core/Consistence/CompareTwoReferences.cpp
@@ -14,8 +14,8 @@
 
 #include "BATesting.h"
 #include "Base/Utils/FileSystemUtils.h"
+#include "Device/Data/DataUtils.h"
 #include "Device/Histo/IntensityDataIOFactory.h"
-#include "Device/Instrument/IntensityDataFunctions.h"
 #include <iostream>
 
 namespace {
@@ -42,5 +42,5 @@ int compareTwoReferences(const std::string& name0, const std::string& name1, con
     std::unique_ptr<OutputData<double>> data0 = load(name0);
     std::unique_ptr<OutputData<double>> data1 = load(name1);
 
-    return IntensityDataFunctions::checkRelativeDifference(*data0, *data1, limit);
+    return DataUtils::checkRelativeDifference(*data0, *data1, limit);
 }
diff --git a/Tests/Functional/Core/CoreSpecial/BatchSimulation.cpp b/Tests/Functional/Core/CoreSpecial/BatchSimulation.cpp
index 819dbc8a67851971b83761c0765abe70d47cfec4..46940579d4d0286baf5788af6cab1c4603fde30d 100644
--- a/Tests/Functional/Core/CoreSpecial/BatchSimulation.cpp
+++ b/Tests/Functional/Core/CoreSpecial/BatchSimulation.cpp
@@ -12,7 +12,7 @@
 //  ************************************************************************************************
 
 #include "Core/Simulation/SimulationFactory.h"
-#include "Device/Instrument/IntensityDataFunctions.h"
+#include "Device/Data/DataUtils.h"
 #include "Sample/StandardSamples/SampleBuilderFactory.h"
 #include "Tests/GTestWrapper/google_test.h"
 #include <iostream>
@@ -49,7 +49,7 @@ TEST_F(BatchSimulation, BatchSimulation) {
         *result += *batchResult;
     }
 
-    double diff = IntensityDataFunctions::getRelativeDifference(*result, *reference);
+    double diff = DataUtils::relativeDataDifference(*result, *reference);
 
     EXPECT_LE(diff, threshold);
 }
diff --git a/Tests/Functional/Core/CoreSpecial/CoreIOPathTest.cpp b/Tests/Functional/Core/CoreSpecial/CoreIOPathTest.cpp
index 3e85ae88c81a24099991bc2794cd8dfb990a2f37..580f3f30a3e75b8bba8e5bec139ea6905f18fd8d 100644
--- a/Tests/Functional/Core/CoreSpecial/CoreIOPathTest.cpp
+++ b/Tests/Functional/Core/CoreSpecial/CoreIOPathTest.cpp
@@ -14,8 +14,8 @@
 
 #include "BATesting.h"
 #include "Base/Utils/FileSystemUtils.h"
+#include "Device/Data/DataUtils.h"
 #include "Device/Histo/IntensityDataIOFactory.h"
-#include "Device/Instrument/IntensityDataFunctions.h"
 #include "Tests/GTestWrapper/google_test.h"
 #include <filesystem>
 #include <iostream>
@@ -33,7 +33,7 @@ std::unique_ptr<OutputData<double>> createTestData() {
 bool test_io(const OutputData<double>* data, const std::string& file_name) {
     IntensityDataIOFactory::writeOutputData(*data, file_name);
     std::unique_ptr<OutputData<double>> loaded(IntensityDataIOFactory::readOutputData(file_name));
-    return IntensityDataFunctions::getRelativeDifference(*data, *loaded) <= 1e-06;
+    return DataUtils::relativeDataDifference(*data, *loaded) <= 1e-06;
 }
 
 } // namespace
diff --git a/Tests/Functional/Core/CoreSpecial/FourierTransformationTest.cpp b/Tests/Functional/Core/CoreSpecial/FourierTransformationTest.cpp
index 151ed0a460294523e486205c4d33861aba56898e..33a1175367cd80d97b9e36d3fc26cc3335adac7d 100644
--- a/Tests/Functional/Core/CoreSpecial/FourierTransformationTest.cpp
+++ b/Tests/Functional/Core/CoreSpecial/FourierTransformationTest.cpp
@@ -14,8 +14,8 @@
 
 #include "BATesting.h"
 #include "Base/Utils/FileSystemUtils.h"
+#include "Device/Data/DataUtils.h"
 #include "Device/Histo/IntensityDataIOFactory.h"
-#include "Device/Instrument/IntensityDataFunctions.h"
 #include "Tests/GTestWrapper/google_test.h"
 #include <iostream>
 #include <memory>
@@ -49,7 +49,7 @@ bool test_fft(const std::string& input_image_name, const std::string& reference_
     }
 
     std::cout << "transforming" << std::endl;
-    std::unique_ptr<OutputData<double>> fft = IntensityDataFunctions::createFFT(*input_image);
+    std::unique_ptr<OutputData<double>> fft = DataUtils::createFFT(*input_image);
 
     std::cout << "loading reference" << std::endl;
     std::unique_ptr<OutputData<double>> reference_fft;
@@ -62,7 +62,7 @@ bool test_fft(const std::string& input_image_name, const std::string& reference_
     std::cout << "comparing" << std::endl;
     bool success(false);
     if (reference_fft)
-        success = IntensityDataFunctions::getRelativeDifference(*fft, *reference_fft) <= threshold;
+        success = DataUtils::relativeDataDifference(*fft, *reference_fft) <= threshold;
 
     if (!success) {
         FileSystemUtils::createDirectory(BATesting::TestOutDir_Core());
diff --git a/Tests/Functional/Core/Fitting/FitTests.cpp b/Tests/Functional/Core/Fitting/FitTests.cpp
index 0cdc5c2bb8ca914081224ae5a59f34b653beea13..0285653423a65eeaaf50871ba7046083971e1772 100644
--- a/Tests/Functional/Core/Fitting/FitTests.cpp
+++ b/Tests/Functional/Core/Fitting/FitTests.cpp
@@ -85,6 +85,6 @@ TEST_F(Fitting, MultipleSpecFittingTest) {
     EXPECT_TRUE(run("Minuit2", "Migrad", "MultipleSpecPlan"));
 }
 
-TEST_F(Fitting, OffSpecFitTest) {
-    EXPECT_TRUE(run("Minuit2", "Migrad", "OffSpecPlan"));
+TEST_F(Fitting, OffSpecularFitTest) {
+    EXPECT_TRUE(run("Minuit2", "Migrad", "OffSpecularPlan"));
 }
diff --git a/Tests/Functional/Core/Fitting/PlanCases.cpp b/Tests/Functional/Core/Fitting/PlanCases.cpp
index 63b60720d28ec448ab213b9d2ab5f657ded3ccd0..211627665c9735285a4d69931b257b595cef17c6 100644
--- a/Tests/Functional/Core/Fitting/PlanCases.cpp
+++ b/Tests/Functional/Core/Fitting/PlanCases.cpp
@@ -127,9 +127,9 @@ std::unique_ptr<FitObjective> MultipleSpecPlan::createFitObjective() const {
 
 // ----------------------------------------------------------------------------
 
-OffSpecPlan::OffSpecPlan() : Plan("OffSpecPlan") {
+OffSpecularPlan::OffSpecularPlan() : Plan("OffSpecularPlan") {
     setBuilderName("ResonatorBuilder");
-    setSimulationName("OffSpecMini");
+    setSimulationName("OffSpecularMini");
     addParameter(
         Parameter("ti_thickness", 12.0 * nm, AttLimits::limited(11.5 * nm, 14.0 * nm), 0.1 * nm),
         13.0 * nm);
diff --git a/Tests/Functional/Core/Fitting/PlanCases.h b/Tests/Functional/Core/Fitting/PlanCases.h
index f1ea57480eb69ed519ed11a7f635311c2c660e05..f35ae32678550cc74c77fefeab4c76d125f0b0b3 100644
--- a/Tests/Functional/Core/Fitting/PlanCases.h
+++ b/Tests/Functional/Core/Fitting/PlanCases.h
@@ -79,10 +79,10 @@ protected:
 
 //! Fit for off-specular experiment
 
-class OffSpecPlan : public Plan {
+class OffSpecularPlan : public Plan {
 public:
-    OffSpecPlan();
-    ~OffSpecPlan() override = default;
+    OffSpecularPlan();
+    ~OffSpecularPlan() override = default;
 };
 
 #endif // BORNAGAIN_TESTS_FUNCTIONAL_CORE_FITTING_PLANCASES_H
diff --git a/Tests/Functional/Core/Fitting/PlanFactory.cpp b/Tests/Functional/Core/Fitting/PlanFactory.cpp
index 3a72fea24f1188b00f4bd679abe454afb6d1fcca..6bc03c0bb5af3a497da0d804b689a8f9d7ccc52b 100644
--- a/Tests/Functional/Core/Fitting/PlanFactory.cpp
+++ b/Tests/Functional/Core/Fitting/PlanFactory.cpp
@@ -25,5 +25,5 @@ PlanFactory::PlanFactory() {
     registerItem("SpecularPlan", create_new<SpecularPlan>);
     registerItem("SpecularPlanQ", create_new<SpecularPlanQ>);
     registerItem("MultipleSpecPlan", create_new<MultipleSpecPlan>);
-    registerItem("OffSpecPlan", create_new<OffSpecPlan>);
+    registerItem("OffSpecularPlan", create_new<OffSpecularPlan>);
 }
diff --git a/Tests/Functional/Core/MPI/mpitest.cpp b/Tests/Functional/Core/MPI/mpitest.cpp
index 25f8c66d62f6c216b7bb8feab80c3259d7fe7f3f..83c871f4028230551723865efffce6e5a524ee87 100644
--- a/Tests/Functional/Core/MPI/mpitest.cpp
+++ b/Tests/Functional/Core/MPI/mpitest.cpp
@@ -1,8 +1,8 @@
 #include <mpi.h>
 
 #include "Core/Simulation/SimulationFactory.h"
+#include "Device/Data/DataUtils.h"
 #include "Device/Histo/IntensityDataIOFactory.h"
-#include "Device/Instrument/IntensityDataFunctions.h"
 #include "Sample/Multilayer/MultiLayer.h"
 #include "Sample/StandardSamples/SampleBuilderFactory.h"
 
@@ -41,7 +41,7 @@ int main(int argc, char** argv) {
         p_simulation->runSimulation();
         auto reference = p_simulation->result();
 
-        double diff = IntensityDataFunctions::RelativeDifference(result, reference);
+        double diff = DataUtils::RelativeDifference(result, reference);
         std::cout << "Difference: " << diff << std::endl;
     }
     MPI_Finalize();
diff --git a/Tests/Functional/Core/Std/Check.cpp b/Tests/Functional/Core/Std/Check.cpp
index 5071c320efdca4968eaec8e6beb4d9e8e2d816f2..d66137a610fbc0fcd90297aac0c2713457a86c6c 100644
--- a/Tests/Functional/Core/Std/Check.cpp
+++ b/Tests/Functional/Core/Std/Check.cpp
@@ -16,8 +16,8 @@
 #include "BATesting.h"
 #include "Base/Utils/FileSystemUtils.h"
 #include "Core/Simulation/SimulationFactory.h"
+#include "Device/Data/DataUtils.h"
 #include "Device/Histo/IntensityDataIOFactory.h"
-#include "Device/Instrument/IntensityDataFunctions.h"
 #include "Sample/Multilayer/MultiLayer.h"
 #include "Sample/StandardSamples/SampleBuilderFactory.h"
 #include <iostream>
@@ -46,7 +46,7 @@ bool checkSimulation(const std::string& name, const ISimulation& direct_simulati
     // Compare with reference if available.
     if (reference) {
         std::cout << "- check diff" << std::endl;
-        if (IntensityDataFunctions::checkRelativeDifference(*reference, *result_data, limit)) {
+        if (DataUtils::checkRelativeDifference(*reference, *result_data, limit)) {
             std::cout << "- success" << std::endl;
             return true; // regular exit
         }
diff --git a/Tests/Functional/GUI/Std/Check.cpp b/Tests/Functional/GUI/Std/Check.cpp
index 8d229f705b3db8787e337d229fdcdc9a5c85bd4e..d9def3115f7a107ef83b3f839c392fdadcfbd08f 100644
--- a/Tests/Functional/GUI/Std/Check.cpp
+++ b/Tests/Functional/GUI/Std/Check.cpp
@@ -13,7 +13,7 @@
 //  ************************************************************************************************
 
 #include "Core/Simulation/ISimulation.h"
-#include "Device/Instrument/IntensityDataFunctions.h"
+#include "Device/Data/DataUtils.h"
 #include "GUI/coregui/Models/DocumentModel.h"
 #include "GUI/coregui/Models/DomainSimulationBuilder.h"
 #include "GUI/coregui/Models/GUIObjectBuilder.h"
@@ -55,5 +55,5 @@ bool checkSimulation(const std::string& name, const ISimulation& direct_simulati
 
     const std::unique_ptr<OutputData<double>> ref_data = direct_simulation.result().data();
 
-    return IntensityDataFunctions::checkRelativeDifference(*domain_data, *ref_data, limit);
+    return DataUtils::checkRelativeDifference(*domain_data, *ref_data, limit);
 }
diff --git a/Tests/Functional/GUI/Translate/GUITranslationTest.cpp b/Tests/Functional/GUI/Translate/GUITranslationTest.cpp
index 62d036edf8b233a1b60afda5663cffba859ed4ff..f6932385e74d20af235513220e788c71e13ad45d 100644
--- a/Tests/Functional/GUI/Translate/GUITranslationTest.cpp
+++ b/Tests/Functional/GUI/Translate/GUITranslationTest.cpp
@@ -51,7 +51,7 @@ const QVector<QPair<QStringList, QStringList>> black_list{
      {""},
      {"Sigma factor", "MaterialRefractiveData", "MaterialSLDData", MaterialItem::P_MAGNETIZATION}},
     {// Instrument scope
-     {"GISASInstrument", "OffSpecInstrument", "SpecularInstrument"},
+     {"GISASInstrument", "OffSpecularInstrument", "SpecularInstrument"},
      {// Distribution types
       "DistributionGate", "DistributionLorentz", "DistributionGaussian", "DistributionLogNormal",
       "DistributionCosine", "DistributionTrapezoid",
@@ -59,7 +59,7 @@ const QVector<QPair<QStringList, QStringList>> black_list{
       // Detector axes
       SphericalDetectorItem::P_PHI_AXIS, SphericalDetectorItem::P_ALPHA_AXIS,
       RectangularDetectorItem::P_X_AXIS, RectangularDetectorItem::P_Y_AXIS,
-      OffSpecInstrumentItem::P_ALPHA_AXIS,
+      OffSpecularInstrumentItem::P_ALPHA_AXIS,
 
       // Rectangular detector positioning
       RectangularDetectorItem::P_ALIGNMENT, RectangularDetectorItem::P_NORMAL,
diff --git a/Tests/Functional/Python/PyCore/intensitydata_io.py b/Tests/Functional/Python/PyCore/intensitydata_io.py
index d11811068d2c1daa1e9d61dcc9abfda6fb6dba38..476285466cdae0c82773c72972283e1a7ba3ee22 100644
--- a/Tests/Functional/Python/PyCore/intensitydata_io.py
+++ b/Tests/Functional/Python/PyCore/intensitydata_io.py
@@ -2,7 +2,7 @@
 
 import math, numpy, os, sys, time, unittest
 import bornagain as ba
-from bornagain import deg, deg2rad, rad2deg
+from bornagain import deg
 
 
 def fill_data(data):
@@ -35,11 +35,11 @@ def get_boundaries_flat_in_sin(nbins, start, end):
     Returns flat_in_sin binning of angle axis
     """
     result = []
-    start_sin = math.sin(deg2rad(start))
-    end_sin = math.sin(deg2rad(end))
+    start_sin = math.sin(start)
+    end_sin = math.sin(end)
     step = (end_sin - start_sin)/nbins
     for i in range(0, nbins + 1):
-        result.append(rad2deg(math.asin(start_sin + step*i)))
+        result.append(math.degrees(math.asin(start_sin + step*i)))
     return result
 
 
@@ -78,7 +78,7 @@ class OutputDataIOTest(unittest.TestCase):
         data = ba.IntensityData()
         data.addAxis(
             ba.VariableBinAxis("axis0", 10,
-                               get_boundaries_flat_in_sin(10, -5.0, 5.0)))
+                               get_boundaries_flat_in_sin(10, -5*deg, 5*deg)))
         fill_data(data)
         ba.IntensityDataIOFactory.writeOutputData(data, "tmp.int")
         newdata = ba.IntensityDataIOFactory.readOutputData("tmp.int")
@@ -88,10 +88,10 @@ class OutputDataIOTest(unittest.TestCase):
         data = ba.IntensityData()
         data.addAxis(
             ba.VariableBinAxis("axis0", 10,
-                               get_boundaries_flat_in_sin(10, -5.0, 5.0)))
+                               get_boundaries_flat_in_sin(10, -5*deg, 5*deg)))
         data.addAxis(
             ba.VariableBinAxis("axis1", 3,
-                               get_boundaries_flat_in_sin(3, 0.0, 2.0)))
+                               get_boundaries_flat_in_sin(3, 0*deg, 2*deg)))
         fill_data(data)
         ba.IntensityDataIOFactory.writeOutputData(data, "tmp.int")
         newdata = ba.IntensityDataIOFactory.readOutputData("tmp.int")
@@ -102,7 +102,7 @@ class OutputDataIOTest(unittest.TestCase):
         data.addAxis(ba.FixedBinAxis("axis0", 10, -5.0, 5.0))
         data.addAxis(
             ba.VariableBinAxis("axis1", 3,
-                               get_boundaries_flat_in_sin(3, 0.0, 2.0)))
+                               get_boundaries_flat_in_sin(3, 0*deg, 2*deg)))
         fill_data(data)
         ba.IntensityDataIOFactory.writeOutputData(data, "tmp.int")
         newdata = ba.IntensityDataIOFactory.readOutputData("tmp.int")
diff --git a/Tests/Functional/Python/PyCore/polmagcylinders2.py b/Tests/Functional/Python/PyCore/polmagcylinders2.py
index 3e969efa3c3bc0a638e0e72de106e7bd0b09d806..783a446486eddbacd76495553eb887d30eadd645 100644
--- a/Tests/Functional/Python/PyCore/polmagcylinders2.py
+++ b/Tests/Functional/Python/PyCore/polmagcylinders2.py
@@ -45,7 +45,7 @@ def getSimulationIntensity(rho_beam, efficiency):
     zplus = kvector_t(0.0, 0.0, 1.0)
     simulation.setAnalyzerProperties(zplus, efficiency, 0.5)
     simulation.setBeamParameters(1.0*angstrom, 0.2*deg, 0.0*deg)
-    simulation.setBeamPolarization(rho_beam)
+    simulation.beam().setPolarization(rho_beam)
     simulation.setSample(multi_layer)
     simulation.beam().setIntensity(1e9)
     simulation.runSimulation()
diff --git a/Tests/Functional/Python/PyEmbedded/Tests.cpp b/Tests/Functional/Python/PyEmbedded/Tests.cpp
index 65d661015b74a971ed36e8c084ff6aeba26e7235..3347bea4e7741cde4c558e73aeb5100033f2adb3 100644
--- a/Tests/Functional/Python/PyEmbedded/Tests.cpp
+++ b/Tests/Functional/Python/PyEmbedded/Tests.cpp
@@ -13,8 +13,8 @@
 
 #include "BABuild.h"
 #include "BAVersion.h"
-#include "Base/Py/PyEmbeddedUtils.h"
-#include "Base/Py/PythonCore.h"
+#include "Base/Py/PyCore.h"
+#include "Base/Py/PyUtils.h"
 #include "Base/Utils/SysUtils.h"
 #include "Core/Export/ExportToPython.h"
 #include "Core/Export/PyFmt.h"
@@ -44,7 +44,7 @@ TEST_F(PyEmbedded, SysPath) {
     std::cout << "buildLibDir(): " << BABuild::buildLibDir() << std::endl;
 
     // Runtime info
-    auto content = PyEmbeddedUtils::pythonRuntimeInfo();
+    auto content = PyUtils::pythonRuntimeInfo();
 
     EXPECT_TRUE(!content.empty());
 }
@@ -63,7 +63,7 @@ TEST_F(PyEmbedded, ImportNumpy) {
     if (!pvar)
         throw std::runtime_error("Can't get a variable");
 
-    auto version_string = PyEmbeddedUtils::toString(pvar);
+    auto version_string = PyUtils::toString(pvar);
     Py_DecRef(pvar);
     std::cout << "numpy_version_string=" << version_string << std::endl;
 
@@ -102,7 +102,7 @@ TEST_F(PyEmbedded, FunctionCall) {
     if (!result)
         throw std::runtime_error("Error while calling function");
 
-    auto str = PyEmbeddedUtils::toString(result);
+    auto str = PyUtils::toString(result);
     Py_DecRef(result);
 
     Py_Finalize();
@@ -242,7 +242,7 @@ TEST_F(PyEmbedded, CompiledFunction) {
 
     // convert the result to a string
     PyObject* pResultRepr = PyObject_Repr(pResult);
-    std::string result = PyEmbeddedUtils::toString(pResultRepr);
+    std::string result = PyUtils::toString(pResultRepr);
     Py_DecRef(pResultRepr);
 
     Py_Finalize();
diff --git a/Tests/Functional/Python/PyExamples/CMakeLists.txt b/Tests/Functional/Python/PyExamples/CMakeLists.txt
index 4b3c7629b4306187be94bbc3534dfdd47f5ed557..2889530f3542fcdbea625d0aa6c9d7417ac8575f 100644
--- a/Tests/Functional/Python/PyExamples/CMakeLists.txt
+++ b/Tests/Functional/Python/PyExamples/CMakeLists.txt
@@ -8,16 +8,16 @@
 set(output_dir ${TEST_OUTPUT_DIR_PY_EXAMPLES})
 file(MAKE_DIRECTORY ${output_dir})
 
-file(GLOB sim_examples ${PY_EXAMPLES_DIR}/sim*/*.py)
+file(GLOB examples
+    ${PY_EXAMPLES_DIR}/scatter2d/*.py
+    ${PY_EXAMPLES_DIR}/specular/*.py
+    ${PY_EXAMPLES_DIR}/varia/*.py
+    ${PY_EXAMPLES_DIR}/fit55_Specular/FitSpecularBasics.py)
 if (WIN32)
     # Convergence problem in Gauss-Kronrod integration
-    list(REMOVE_ITEM sim_examples ${PY_EXAMPLES_DIR}/sim03_Structures/Interference2DParaCrystal.py)
+    list(REMOVE_ITEM examples ${PY_EXAMPLES_DIR}/scatter2d/Interference2DParaCrystal.py)
 endif()
 
-
-file(GLOB fit_examples ${PY_EXAMPLES_DIR}/fit55_Specular/FitSpecularBasics.py)
-set(examples ${sim_examples} ${fit_examples})
-
 set(test_script ${TOOL_DIR}/code-tools/batch-plot.py)
 
 foreach(example_path ${examples})
diff --git a/Tests/Functional/Python/PyPersistence/CMakeLists.txt b/Tests/Functional/Python/PyPersistence/CMakeLists.txt
index 00a6defb321078447d52915d3704023abf0c6e5e..f140549343915daaf070cc76b81b038716b1468b 100644
--- a/Tests/Functional/Python/PyPersistence/CMakeLists.txt
+++ b/Tests/Functional/Python/PyPersistence/CMakeLists.txt
@@ -22,50 +22,44 @@ function(test_example example tolerance)
     add_test(${test_name} ${Python3_EXECUTABLE} -B ${example_mod})
 endfunction()
 
-test_example(sim01_Particles/CylindersAndPrisms 2e-10)
-test_example(sim01_Particles/CylindersInBA 2e-10)
-test_example(sim01_Particles/CylindersInDWBA 2e-10)
-test_example(sim01_Particles/CylindersWithSizeDistribution 2e-10)
-test_example(sim01_Particles/RotatedPyramids 2e-10)
-test_example(sim01_Particles/TwoTypesOfCylindersWithSizeDistribution 2e-10)
+test_example(scatter2d/ApproximationDA 2e-10)
+test_example(scatter2d/ApproximationLMA 2e-10)
+test_example(scatter2d/ApproximationSSCA 2e-10)
+test_example(scatter2d/BeamDivergence 2e-10)
+test_example(scatter2d/BuriedParticles 2e-10)
+test_example(scatter2d/ConstantBackground 2e-10)
+test_example(scatter2d/CoreShellNanoparticles 2e-10)
+test_example(scatter2d/CorrelatedRoughness 2e-10)
+test_example(scatter2d/CosineRipplesAtRectLattice 2e-10)
+test_example(scatter2d/CylindersAndPrisms 2e-10)
+test_example(scatter2d/CylindersInAverageLayer 2e-10)
+test_example(scatter2d/CylindersInBA 2e-10)
+test_example(scatter2d/CylindersInDWBA 2e-10)
+test_example(scatter2d/CylindersWithSizeDistribution 2e-10)
+test_example(scatter2d/DetectorResolutionFunction 2e-10)
+test_example(scatter2d/HalfSpheresInAverageTopLayer 2e-10)
+test_example(scatter2d/HexagonalLatticesWithBasis 2e-10)
+test_example(scatter2d/Interference1DRadialParaCrystal 2e-10)
+test_example(scatter2d/Interference2DCenteredSquareLattice 2e-10)
+test_example(scatter2d/Interference2DLatticeSumOfRotated 2e-10)
+test_example(scatter2d/Interference2DParaCrystal 2e-10)
+test_example(scatter2d/Interference2DRotatedSquareLattice 2e-10)
+test_example(scatter2d/Interference2DSquareLattice 2e-10)
+test_example(scatter2d/MagneticSpheres 2e-10)
+test_example(scatter2d/RectangularGrating 0.5)
+test_example(scatter2d/RotatedPyramids 2e-10)
+test_example(scatter2d/SpheresAtHexLattice 2e-10)
+test_example(scatter2d/TriangularRipple 2e-10)
+test_example(scatter2d/TwoTypesOfCylindersWithSizeDistribution 2e-10)
 
-test_example(sim02_Complexes/CoreShellNanoparticles 2e-10)
-test_example(sim02_Complexes/CustomFormFactor 2e-10)
-test_example(sim02_Complexes/HexagonalLatticesWithBasis 2e-10)
+test_example(specular/BasicSpecularSimulation 2e-10)
+test_example(specular/BeamAngularDivergence 2e-10)
+test_example(specular/BeamFullDivergence 2e-10)
+test_example(specular/TOFRWithResolution 2e-10)
+test_example(specular/TimeOfFlightReflectometry 2e-10)
 
-test_example(sim03_Structures/ApproximationDA 2e-10)
-test_example(sim03_Structures/ApproximationLMA 2e-10)
-test_example(sim03_Structures/ApproximationSSCA 2e-10)
-test_example(sim03_Structures/CosineRipplesAtRectLattice 2e-10)
-test_example(sim03_Structures/Interference1DLattice 1.5)
-test_example(sim03_Structures/Interference1DRadialParaCrystal 2e-10)
-test_example(sim03_Structures/Interference2DCenteredSquareLattice 2e-10)
-test_example(sim03_Structures/Interference2DParaCrystal 2e-10)
-test_example(sim03_Structures/Interference2DRotatedSquareLattice 2e-10)
-test_example(sim03_Structures/Interference2DSquareLattice 2e-10)
-test_example(sim03_Structures/Interference2DLatticeSumOfRotated 2e-10)
-test_example(sim03_Structures/RectangularGrating 0.5)
-test_example(sim03_Structures/SpheresAtHexLattice 2e-10)
-test_example(sim03_Structures/TriangularRipple 2e-10)
-
-test_example(sim04_Multilayers/BuriedParticles 2e-10)
-test_example(sim04_Multilayers/CorrelatedRoughness 2e-10)
-test_example(sim04_Multilayers/CylindersInAverageLayer 2e-10)
-test_example(sim04_Multilayers/HalfSpheresInAverageTopLayer 2e-10)
-
-test_example(sim05_Magnetism/MagneticSpheres 2e-10)
-
-test_example(sim11_Device/BeamDivergence 2e-10)
-test_example(sim11_Device/DetectorResolutionFunction 2e-10)
-test_example(sim11_Device/OffSpecularSimulation 2e-10)
-test_example(sim11_Device/ConstantBackground 2e-10)
-
-test_example(sim21_Reflectometry/BasicSpecularSimulation 2e-10)
-test_example(sim21_Reflectometry/BeamAngularDivergence 2e-10)
-test_example(sim21_Reflectometry/BeamFullDivergence 2e-10)
-test_example(sim21_Reflectometry/TimeOfFlightReflectometry 2e-10)
-test_example(sim21_Reflectometry/TOFRWithResolution 2e-10)
-
-test_example(special40_DepthProbe/DepthProbe 2e-10)
-
-test_example(sim31_Parameterization/SimulationParameters 2e-10)
+test_example(varia/CustomFormFactor 2e-10)
+test_example(varia/DepthProbe 2e-10)
+test_example(varia/Interference1DLattice 1.5)
+test_example(varia/OffSpecularSimulation 2e-10)
+test_example(varia/SimulationParameters 2e-10)
diff --git a/Tests/Functional/Python/PyPersistence/PyPersistence.py.in b/Tests/Functional/Python/PyPersistence/PyPersistence.py.in
index 51a877e200299274c4656a5650f3d97824d0c592..6db266e67f9749aeed98042db4acae25d6efac66 100644
--- a/Tests/Functional/Python/PyPersistence/PyPersistence.py.in
+++ b/Tests/Functional/Python/PyPersistence/PyPersistence.py.in
@@ -78,7 +78,7 @@ def get_minified_simulation():
     """
     Returns a simulation constructed from example simulation with smaller detector.
     """
-    if "sim21_Reflectometry" in EXAMPLE_DIR:
+    if "specular" in EXAMPLE_DIR:
         return get_simulation_SpecularSimulation()
 
     elif EXAMPLE_NAME == "RectangularGrating":
@@ -149,7 +149,7 @@ def check_result(result, example_name):
     print("Loading reference file '{}'".format(reffile))
     reference = ba.IntensityDataIOFactory.readOutputData(reffile)
 
-    diff = ba.getRelativeDifference(ba.importArrayToOutputData(result.array()), reference)
+    diff = ba.relativeDataDifference(ba.importArrayToOutputData(result.array()), reference)
 
     if diff > TOLERANCE:
         print("Failure - Difference {0} is above tolerance level {1}".format(diff, TOLERANCE))
diff --git a/Tests/Functional/Python/Std/Check.cpp b/Tests/Functional/Python/Std/Check.cpp
index 594dddc2d78396ecdd06401afcca9131a08c5a10..033d7ade325045096080fa5a23b6df100c96a8f3 100644
--- a/Tests/Functional/Python/Std/Check.cpp
+++ b/Tests/Functional/Python/Std/Check.cpp
@@ -17,8 +17,8 @@
 #include "Base/Utils/FileSystemUtils.h"
 #include "Core/Export/ExportToPython.h"
 #include "Core/Simulation/ISimulation.h"
+#include "Device/Data/DataUtils.h"
 #include "Device/Histo/IntensityDataIOFactory.h"
-#include "Device/Instrument/IntensityDataFunctions.h"
 #include <fstream>
 #include <iostream>
 
@@ -71,5 +71,5 @@ bool checkSimulation(const std::string& name, const ISimulation& direct_simulati
 
     const std::unique_ptr<OutputData<double>> ref_data = direct_simulation.result().data();
 
-    return IntensityDataFunctions::checkRelativeDifference(*domain_data, *ref_data, limit);
+    return DataUtils::checkRelativeDifference(*domain_data, *ref_data, limit);
 }
diff --git a/Tests/Functional/Std/StandardTests.h b/Tests/Functional/Std/StandardTests.h
index 521d9b1c90eca3d2c5a2deb5d6a7406e1eea1f51..401991a016c36eeb39bb9d1093ae5e4056b3b67c 100644
--- a/Tests/Functional/Std/StandardTests.h
+++ b/Tests/Functional/Std/StandardTests.h
@@ -367,7 +367,7 @@ TEST_F(Std, RelativeResolutionTOF) {
 #ifndef PYTHON_STD_TEST
 
 TEST_F(Std, OffSpecularResonator) {
-    EXPECT_TRUE(run("OffSpecularResonator", "OffSpecMini", "ResonatorBuilder", 1e-10));
+    EXPECT_TRUE(run("OffSpecularResonator", "OffSpecularMini", "ResonatorBuilder", 1e-10));
 }
 
 TEST_F(Std, FormFactorsWithAbsorption) {
diff --git a/Tests/Performance/Core/Mesocrystal.cpp b/Tests/Performance/Core/Mesocrystal.cpp
index fa0e9ffa2934ab8167a0543d5b8ed8575d383f3a..602e9ed5b83d38f6c361731fa1330629b1555236 100644
--- a/Tests/Performance/Core/Mesocrystal.cpp
+++ b/Tests/Performance/Core/Mesocrystal.cpp
@@ -195,7 +195,7 @@ int main() {
     simulation.setDetector(*detector);
 
     simulation.setBeamParameters(1.77 * Units::angstrom, 0.4 * Units::deg, 0.0);
-    simulation.setBeamIntensity(6.1e+12);
+    simulation.beam().setIntensity(6.1e+12);
 
     std::shared_ptr<ISampleBuilder> builder(new MesoCrystalPerformanceBuilder);
     simulation.setSampleBuilder(builder);
diff --git a/Tests/Performance/GUI/CsvImportAssistantPerformanceTest.cpp b/Tests/Performance/GUI/CsvImportAssistantPerformanceTest.cpp
index ecd1df62ccdbe9b484fc813e8a6eb96dd7dacd63..5013199da8d4bec966a0fecf1b6e8438e20a4cba 100644
--- a/Tests/Performance/GUI/CsvImportAssistantPerformanceTest.cpp
+++ b/Tests/Performance/GUI/CsvImportAssistantPerformanceTest.cpp
@@ -14,7 +14,7 @@
 
 #include "Tests/Performance/GUI/CsvImportAssistantPerformanceTest.h"
 #include "Device/Histo/IntensityDataIOFactory.h"
-#include "Device/Intensity/ArrayUtils.h"
+#include "Device/Data/ArrayUtils.h"
 #include "GUI/coregui/Views/ImportDataWidgets/CsvImportAssistant/CsvImportAssistant.h"
 #include <ctime>
 #include <iostream>
diff --git a/Tests/UnitTests/Core/DataStructure/ArrayUtilsTest.cpp b/Tests/UnitTests/Core/DataStructure/ArrayUtilsTest.cpp
index 96bbb82d1f498c3a8b2664fab498ee224fb464a7..692238912cd616a2fb30d097c929d9b38ea06be0 100644
--- a/Tests/UnitTests/Core/DataStructure/ArrayUtilsTest.cpp
+++ b/Tests/UnitTests/Core/DataStructure/ArrayUtilsTest.cpp
@@ -1,4 +1,4 @@
-#include "Device/Intensity/ArrayUtils.h"
+#include "Device/Data/ArrayUtils.h"
 #include "Tests/GTestWrapper/google_test.h"
 #include <vector>
 
diff --git a/Tests/UnitTests/Core/DataStructure/IntensityDataFunctionsTest.cpp b/Tests/UnitTests/Core/DataStructure/IntensityDataFunctionsTest.cpp
index 7cb8cac72205f4cc2b458b585505205f48b7f4f7..9be737458d921460199b5b7b26f1e1deca5e39d1 100644
--- a/Tests/UnitTests/Core/DataStructure/IntensityDataFunctionsTest.cpp
+++ b/Tests/UnitTests/Core/DataStructure/IntensityDataFunctionsTest.cpp
@@ -1,10 +1,10 @@
-#include "Device/Instrument/IntensityDataFunctions.h"
 #include "Base/Axis/VariableBinAxis.h"
+#include "Device/Data/DataUtils.h"
 #include "Tests/GTestWrapper/google_test.h"
 
-class IntensityDataFunctionsTest : public ::testing::Test {};
+class DataUtilsTest : public ::testing::Test {};
 
-TEST_F(IntensityDataFunctionsTest, ClipDataSetFixed) {
+TEST_F(DataUtilsTest, ClipDataSetFixed) {
     OutputData<double> data;
     FixedBinAxis axis0("axis0", 10, -5.0, 5.0);
     data.addAxis(axis0);
@@ -14,7 +14,7 @@ TEST_F(IntensityDataFunctionsTest, ClipDataSetFixed) {
     for (size_t i = 0; i < data.getAllocatedSize(); ++i)
         data[i] = static_cast<double>(i);
 
-    auto clip = IntensityDataFunctions::createClippedDataSet(data, -5.0, 0.0, -1.5, 1.5);
+    auto clip = DataUtils::createClippedDataSet(data, -5.0, 0.0, -1.5, 1.5);
     std::vector<double> vref = {0.0, 1.0, 3.0, 4.0, 6.0, 7.0, 9.0, 10.0};
     EXPECT_EQ(clip->getAllocatedSize(), size_t(8));
     size_t index(0);
@@ -22,7 +22,7 @@ TEST_F(IntensityDataFunctionsTest, ClipDataSetFixed) {
         EXPECT_EQ(vref[index++], (*clip)[i]);
 }
 
-TEST_F(IntensityDataFunctionsTest, ClipDataSetVariable) {
+TEST_F(DataUtilsTest, ClipDataSetVariable) {
     static const double arr[] = {-1.0, -0.5, 0.5, 1.0, 2.0};
     std::vector<double> values(arr, arr + sizeof(arr) / sizeof(arr[0]));
 
@@ -35,7 +35,7 @@ TEST_F(IntensityDataFunctionsTest, ClipDataSetVariable) {
     for (size_t i = 0; i < data.getAllocatedSize(); ++i)
         data[i] = static_cast<double>(i);
 
-    auto clip = IntensityDataFunctions::createClippedDataSet(data, -0.5, 0.5, 0.99, 2.0);
+    auto clip = DataUtils::createClippedDataSet(data, -0.5, 0.5, 0.99, 2.0);
     std::vector<double> vref = {6.0, 7.0, 10.0, 11.0};
     EXPECT_EQ(clip->getAllocatedSize(), size_t(4));
     size_t index(0);
@@ -43,14 +43,14 @@ TEST_F(IntensityDataFunctionsTest, ClipDataSetVariable) {
         EXPECT_EQ(vref[index++], (*clip)[i]);
 }
 
-TEST_F(IntensityDataFunctionsTest, createRearrangedDataSet) {
+TEST_F(DataUtilsTest, createRearrangedDataSet) {
     OutputData<double> input_data;
     input_data.addAxis("axis0", 2, 1.0, 2.0);
     input_data.addAxis("axis1", 3, 3.0, 4.0);
     input_data.setRawDataVector(std::vector<double>{1.0, 2.0, 3.0, 4.0, 5.0, 6.0});
 
     std::unique_ptr<OutputData<double>> output_data =
-        IntensityDataFunctions::createRearrangedDataSet(input_data, 5);
+        DataUtils::createRearrangedDataSet(input_data, 5);
 
     EXPECT_EQ(3.0, output_data->axis(0).binBoundaries().front());
     EXPECT_EQ(4.0, output_data->axis(0).binBoundaries().back());
@@ -66,7 +66,7 @@ TEST_F(IntensityDataFunctionsTest, createRearrangedDataSet) {
     EXPECT_EQ(input_data[0], (*output_data)[4]);
     EXPECT_EQ(input_data[3], (*output_data)[5]);
 
-    output_data = IntensityDataFunctions::createRearrangedDataSet(input_data, -6);
+    output_data = DataUtils::createRearrangedDataSet(input_data, -6);
 
     EXPECT_EQ(1.0, output_data->axis(0).binBoundaries().front());
     EXPECT_EQ(2.0, output_data->axis(0).binBoundaries().back());
@@ -82,7 +82,7 @@ TEST_F(IntensityDataFunctionsTest, createRearrangedDataSet) {
     EXPECT_EQ(input_data[1], (*output_data)[4]);
     EXPECT_EQ(input_data[0], (*output_data)[5]);
 
-    output_data = IntensityDataFunctions::createRearrangedDataSet(input_data, 3);
+    output_data = DataUtils::createRearrangedDataSet(input_data, 3);
 
     EXPECT_EQ(3.0, output_data->axis(0).binBoundaries().front());
     EXPECT_EQ(4.0, output_data->axis(0).binBoundaries().back());
@@ -99,28 +99,28 @@ TEST_F(IntensityDataFunctionsTest, createRearrangedDataSet) {
     EXPECT_EQ(input_data[2], (*output_data)[5]);
 }
 
-TEST_F(IntensityDataFunctionsTest, coordinateToFromBinf) {
+TEST_F(DataUtilsTest, coordinateToFromBinf) {
     FixedBinAxis axis("axis", 8, -5.0, 3.0);
-    EXPECT_EQ(0.5, IntensityDataFunctions::coordinateToBinf(-4.5, axis));
-    EXPECT_EQ(-4.5, IntensityDataFunctions::coordinateFromBinf(0.5, axis));
+    EXPECT_EQ(0.5, DataUtils::coordinateToBinf(-4.5, axis));
+    EXPECT_EQ(-4.5, DataUtils::coordinateFromBinf(0.5, axis));
 
-    EXPECT_EQ(1.0, IntensityDataFunctions::coordinateToBinf(-4.0, axis));
-    EXPECT_EQ(-4.0, IntensityDataFunctions::coordinateFromBinf(1.0, axis));
+    EXPECT_EQ(1.0, DataUtils::coordinateToBinf(-4.0, axis));
+    EXPECT_EQ(-4.0, DataUtils::coordinateFromBinf(1.0, axis));
 
-    EXPECT_EQ(-0.5, IntensityDataFunctions::coordinateToBinf(-5.5, axis));
-    EXPECT_EQ(-5.5, IntensityDataFunctions::coordinateFromBinf(-0.5, axis));
+    EXPECT_EQ(-0.5, DataUtils::coordinateToBinf(-5.5, axis));
+    EXPECT_EQ(-5.5, DataUtils::coordinateFromBinf(-0.5, axis));
 
-    EXPECT_EQ(8.0, IntensityDataFunctions::coordinateToBinf(3.0, axis));
-    EXPECT_EQ(3.0, IntensityDataFunctions::coordinateFromBinf(8.0, axis));
+    EXPECT_EQ(8.0, DataUtils::coordinateToBinf(3.0, axis));
+    EXPECT_EQ(3.0, DataUtils::coordinateFromBinf(8.0, axis));
 
-    EXPECT_EQ(8.5, IntensityDataFunctions::coordinateToBinf(3.5, axis));
-    EXPECT_EQ(3.5, IntensityDataFunctions::coordinateFromBinf(8.5, axis));
+    EXPECT_EQ(8.5, DataUtils::coordinateToBinf(3.5, axis));
+    EXPECT_EQ(3.5, DataUtils::coordinateFromBinf(8.5, axis));
 }
 
 //! Transformation of coordinates from one OutputData to another using conversion from axes
 //! coordinates to bin-fraction-coordinates and then to another axes coordinates.
 
-TEST_F(IntensityDataFunctionsTest, outputDataCoordinatesToFromBinf) {
+TEST_F(DataUtilsTest, outputDataCoordinatesToFromBinf) {
     OutputData<double> data1;
     data1.addAxis("axis0", 8, -5.0, 3.0);
     data1.addAxis("axis1", 3, 2.0, 5.0);
@@ -130,20 +130,20 @@ TEST_F(IntensityDataFunctionsTest, outputDataCoordinatesToFromBinf) {
     data2.addAxis("axis1", 3, -10.0, 20.0);
 
     double x(-4.5), y(2.5);
-    IntensityDataFunctions::coordinateToBinf(x, y, data1);
-    IntensityDataFunctions::coordinateFromBinf(x, y, data2);
+    DataUtils::coordinateToBinf(x, y, data1);
+    DataUtils::coordinateFromBinf(x, y, data2);
     EXPECT_DOUBLE_EQ(x, -5.0);
     EXPECT_DOUBLE_EQ(y, -5.0);
 
     x = 3.1;
     y = 5.1;
-    IntensityDataFunctions::coordinateToBinf(x, y, data1);
-    IntensityDataFunctions::coordinateFromBinf(x, y, data2);
+    DataUtils::coordinateToBinf(x, y, data1);
+    DataUtils::coordinateFromBinf(x, y, data2);
     EXPECT_DOUBLE_EQ(x, 71.0);
     EXPECT_DOUBLE_EQ(y, 21.0);
 }
 
-TEST_F(IntensityDataFunctionsTest, create2DArrayfromOutputDataTest) {
+TEST_F(DataUtilsTest, create2DArrayfromOutputDataTest) {
     OutputData<double> out_data;
     out_data.addAxis("axis0", 2, 1.0, 2.0);
     out_data.addAxis("axis1", 3, 3.0, 4.0);
@@ -165,17 +165,17 @@ TEST_F(IntensityDataFunctionsTest, create2DArrayfromOutputDataTest) {
     auto arr_out = out_data.getRawDataVector();
     EXPECT_EQ(arr_in, arr_out);
 
-    auto array_2d = IntensityDataFunctions::create2DArrayfromOutputData(out_data);
+    auto array_2d = DataUtils::create2DArrayfromOutputData(out_data);
 
     std::vector<std::vector<double>> array_expected_2d{{arr_in[0], arr_in[1], arr_in[2]},
                                                        {arr_in[3], arr_in[4], arr_in[5]}};
     EXPECT_EQ(array_expected_2d, array_2d);
 }
 
-TEST_F(IntensityDataFunctionsTest, createOutputDatafrom2DArrayTest) {
+TEST_F(DataUtilsTest, createOutputDatafrom2DArrayTest) {
     std::vector<double> arr_in{1, 2, 3, 4, 5, 6};
     std::vector<std::vector<double>> array_2d{{arr_in[0], arr_in[1], arr_in[2]},
                                               {arr_in[3], arr_in[4], arr_in[5]}};
-    auto data = IntensityDataFunctions::createOutputDatafrom2DArray(array_2d);
+    auto data = DataUtils::createOutputDatafrom2DArray(array_2d);
     EXPECT_EQ(arr_in, data->getRawDataVector());
 }
diff --git a/Tests/UnitTests/Core/DataStructure/OutputDataTest.cpp b/Tests/UnitTests/Core/DataStructure/OutputDataTest.cpp
index de02169456d168dc9d37ddfcd79da6fe509a1bcc..89846da474bef9e162f64bb376b36aa3bdd1aeb2 100644
--- a/Tests/UnitTests/Core/DataStructure/OutputDataTest.cpp
+++ b/Tests/UnitTests/Core/DataStructure/OutputDataTest.cpp
@@ -1,5 +1,5 @@
 #include "Base/Axis/VariableBinAxis.h"
-#include "Device/Instrument/IntensityDataFunctions.h"
+#include "Device/Data/DataUtils.h"
 #include "Tests/GTestWrapper/google_test.h"
 #include <algorithm>
 
diff --git a/Tests/UnitTests/Core/Fresnel/DepthProbeSimulationTest.cpp b/Tests/UnitTests/Core/Fresnel/DepthProbeSimulationTest.cpp
index d647752596219e792f2cd20e55bebb67f0b5f9d5..a7b7a66eb87eb1c01ebd7349c9ef3f43b7dc03ec 100644
--- a/Tests/UnitTests/Core/Fresnel/DepthProbeSimulationTest.cpp
+++ b/Tests/UnitTests/Core/Fresnel/DepthProbeSimulationTest.cpp
@@ -104,7 +104,7 @@ TEST_F(DepthProbeSimulationTest, SetBeamParameters) {
 
     checkBeamState(sim);
 
-    sim.setBeamIntensity(2.0);
+    sim.beam().setIntensity(2.0);
     EXPECT_EQ(2.0, beam.intensity());
 
     EXPECT_THROW(sim.setBeamParameters(1.0, 10, -2.0, 3.0), std::runtime_error);
diff --git a/Tests/UnitTests/Core/Fresnel/SpecularMagneticTest.cpp b/Tests/UnitTests/Core/Fresnel/SpecularMagneticTest.cpp
index b03cccda414e131bf43c81e5d58a15cbb5184c49..2cdb7ef69a2991afd866ef88fc10be30b37fa9b5 100644
--- a/Tests/UnitTests/Core/Fresnel/SpecularMagneticTest.cpp
+++ b/Tests/UnitTests/Core/Fresnel/SpecularMagneticTest.cpp
@@ -1,6 +1,6 @@
 #include "Base/Const/Units.h"
 #include "Base/Vector/Direction.h"
-#include "Core/Legacy/SpecularMagneticStrategy_v2.h"
+#include "Sample/LegacyRT/SpecularMagneticStrategy_v2.h"
 #include "Sample/Material/MaterialFactoryFuncs.h"
 #include "Sample/Multilayer/Layer.h"
 #include "Sample/Multilayer/MultiLayer.h"
diff --git a/Tests/UnitTests/Core/Fresnel/SpecularSimulationTest.cpp b/Tests/UnitTests/Core/Fresnel/SpecularSimulationTest.cpp
index 0956f0c5146b8c0c701448eb07fb5365bf51798d..2e2f6edd10d9ec639840af31fefc0925f711a7ff 100644
--- a/Tests/UnitTests/Core/Fresnel/SpecularSimulationTest.cpp
+++ b/Tests/UnitTests/Core/Fresnel/SpecularSimulationTest.cpp
@@ -91,7 +91,7 @@ TEST_F(SpecularSimulationTest, SetAngularScan) {
 
     checkBeamState(sim);
 
-    sim.setBeamIntensity(2.0);
+    sim.beam().setIntensity(2.0);
     EXPECT_EQ(2.0, beam.intensity());
 
     AngularSpecScan scan2(1.0, 10, 1.0 * Units::deg, 10.0 * Units::deg);
@@ -139,7 +139,7 @@ TEST_F(SpecularSimulationTest, SetQScan) {
 
     checkBeamState(sim);
 
-    sim.setBeamIntensity(2.0);
+    sim.beam().setIntensity(2.0);
     EXPECT_EQ(2.0, beam.intensity());
 
     QSpecScan scan2(10, 1.0, 10.0);
diff --git a/Tests/UnitTests/Core/Legacy/MatrixRTCoefficients_v1Test.cpp b/Tests/UnitTests/Core/Legacy/MatrixRTCoefficients_v1Test.cpp
index 1b8d11b56eb535adb469acfc3dffb5258da8023d..4934eea3cec26bd40e0e15a6e6073fcd4af0d749 100644
--- a/Tests/UnitTests/Core/Legacy/MatrixRTCoefficients_v1Test.cpp
+++ b/Tests/UnitTests/Core/Legacy/MatrixRTCoefficients_v1Test.cpp
@@ -1,4 +1,4 @@
-#include "Core/Legacy/MatrixRTCoefficients_v1.h"
+#include "Sample/LegacyRT/MatrixRTCoefficients_v1.h"
 #include "Tests/GTestWrapper/google_test.h"
 
 class MatrixRTCoefficients_v1Test : public ::testing::Test {
diff --git a/Tests/UnitTests/Core/Legacy/MatrixRTCoefficients_v2Test.cpp b/Tests/UnitTests/Core/Legacy/MatrixRTCoefficients_v2Test.cpp
index 6934736917de848b4e8d7f8eb33e05671035a704..86b72c342a6c4c9338790165986258638852237e 100644
--- a/Tests/UnitTests/Core/Legacy/MatrixRTCoefficients_v2Test.cpp
+++ b/Tests/UnitTests/Core/Legacy/MatrixRTCoefficients_v2Test.cpp
@@ -1,4 +1,4 @@
-#include "Core/Legacy/MatrixRTCoefficients_v2.h"
+#include "Sample/LegacyRT/MatrixRTCoefficients_v2.h"
 #include "Tests/GTestWrapper/google_test.h"
 
 class MatrixRTCoefficients_v2Test : public ::testing::Test {
diff --git a/Tests/UnitTests/Core/Legacy/SpecularMagneticConsistencyTest.cpp b/Tests/UnitTests/Core/Legacy/SpecularMagneticConsistencyTest.cpp
index f51ad50cffcbc7922bf6b53303807d671271366d..4326f2f9ba6f41eedfee132391a8f697facef988 100644
--- a/Tests/UnitTests/Core/Legacy/SpecularMagneticConsistencyTest.cpp
+++ b/Tests/UnitTests/Core/Legacy/SpecularMagneticConsistencyTest.cpp
@@ -1,5 +1,5 @@
 #include "Base/Const/Units.h"
-#include "Core/Legacy/SpecularMagneticStrategy_v2.h"
+#include "Sample/LegacyRT/SpecularMagneticStrategy_v2.h"
 #include "Sample/Material/MaterialFactoryFuncs.h"
 #include "Sample/Multilayer/Layer.h"
 #include "Sample/Multilayer/MultiLayer.h"
diff --git a/Tests/UnitTests/Core/Legacy/SpecularMagnetic_v1Test.cpp b/Tests/UnitTests/Core/Legacy/SpecularMagnetic_v1Test.cpp
index ae4c28ae6b195ea8010fd3d3e2da70cf8ba7b71e..df69fd64bba91e7fbeb3ae5ddfc783ff6844b7a6 100644
--- a/Tests/UnitTests/Core/Legacy/SpecularMagnetic_v1Test.cpp
+++ b/Tests/UnitTests/Core/Legacy/SpecularMagnetic_v1Test.cpp
@@ -1,6 +1,6 @@
 #include "Base/Const/Units.h"
 #include "Base/Vector/Direction.h"
-#include "Core/Legacy/SpecularMagneticStrategy_v1.h"
+#include "Sample/LegacyRT/SpecularMagneticStrategy_v1.h"
 #include "Sample/Material/MaterialFactoryFuncs.h"
 #include "Sample/Multilayer/Layer.h"
 #include "Sample/Multilayer/MultiLayer.h"
diff --git a/Tests/UnitTests/Core/Other/ChiSquaredModuleTest.cpp b/Tests/UnitTests/Core/Other/ChiSquaredModuleTest.cpp
index 68b9b93b4af76eeef5c3d023cc909f515c77cfa7..26d540d7b7f1c39c1c37f04da6f9f76952ce8644 100644
--- a/Tests/UnitTests/Core/Other/ChiSquaredModuleTest.cpp
+++ b/Tests/UnitTests/Core/Other/ChiSquaredModuleTest.cpp
@@ -1,6 +1,6 @@
-#include "Device/Instrument/ChiSquaredModule.h"
+#include "Core/Residual/ChiSquaredModule.h"
 #include "Device/Data/OutputData.h"
-#include "Device/Instrument/VarianceFunctions.h"
+#include "Core/Residual/VarianceFunctions.h"
 #include "Tests/GTestWrapper/google_test.h"
 
 // TODO revise test
diff --git a/Tests/UnitTests/Core/Other/FourierTransformTest.cpp b/Tests/UnitTests/Core/Other/FourierTransformTest.cpp
index 9e8c1574e20315cb98bea9aeb8633cede9734812..47207e949d15dab2d2554619048fe13e7ececa46 100644
--- a/Tests/UnitTests/Core/Other/FourierTransformTest.cpp
+++ b/Tests/UnitTests/Core/Other/FourierTransformTest.cpp
@@ -1,4 +1,4 @@
-#include "Device/Instrument/FourierTransform.h"
+#include "Base/Math/FourierTransform.h"
 #include "Base/Math/Constants.h"
 #include "Device/Data/OutputData.h"
 #include "Tests/GTestWrapper/google_test.h"
diff --git a/Tests/UnitTests/Core/Other/SpectrumTest.cpp b/Tests/UnitTests/Core/Other/SpectrumTest.cpp
index 61a29e150f42c0d02a775c4545a34ac0a093c25c..bdb3e3c8bd322c97f9bffbcf28c704284b22dd60 100644
--- a/Tests/UnitTests/Core/Other/SpectrumTest.cpp
+++ b/Tests/UnitTests/Core/Other/SpectrumTest.cpp
@@ -1,4 +1,5 @@
-#include "Device/Instrument/SpectrumUtils.h"
+#include "Device/Histo/HistoUtils.h"
+#include "Device/Histo/Histogram2D.h"
 #include "Tests/GTestWrapper/google_test.h"
 #include <iostream>
 #include <tspectrum.h>
@@ -33,7 +34,7 @@ TEST_F(SpectrumTest, histogramPeaks) {
 
     EXPECT_EQ(hist.binContent(4, 2), 10.0);
 
-    auto peaks = SpectrumUtils::FindPeaks(hist, 3, "nomarkov", 0.1);
+    auto peaks = HistoUtils::FindPeaks(hist, 3, "nomarkov", 0.1);
     EXPECT_NEAR(peaks[0].first, 55.0, 0.01);  // center of histogram x-axis bin with index=4
     EXPECT_NEAR(peaks[0].second, 25.0, 0.01); // center of histogram y-axis bin with index=2
 }
diff --git a/Tests/UnitTests/GUI/TestCsvImportAssistant.cpp b/Tests/UnitTests/GUI/TestCsvImportAssistant.cpp
index f87b66231e8e671dd899a26e936a028a922a628e..e26d642f7b6d52ab1f2cd465f449ebc4102f105c 100644
--- a/Tests/UnitTests/GUI/TestCsvImportAssistant.cpp
+++ b/Tests/UnitTests/GUI/TestCsvImportAssistant.cpp
@@ -1,5 +1,5 @@
 #include "Device/Histo/IntensityDataIOFactory.h"
-#include "Device/Intensity/ArrayUtils.h"
+#include "Device/Data/ArrayUtils.h"
 #include "Device/Unit/AxisNames.h"
 #include "GUI/coregui/Models/JobItemUtils.h"
 #include "GUI/coregui/Models/SpecularDataItem.h"
diff --git a/Tests/UnitTests/GUI/Utils.cpp b/Tests/UnitTests/GUI/Utils.cpp
index 41be0b6b03f711c7273d605537154837b90e61a0..9b53cef3ec4573c6ad980f3df448b7201b8d714b 100644
--- a/Tests/UnitTests/GUI/Utils.cpp
+++ b/Tests/UnitTests/GUI/Utils.cpp
@@ -14,8 +14,8 @@
 //  ************************************************************************************************
 
 #include "Tests/UnitTests/GUI/Utils.h"
+#include "Device/Data/DataUtils.h"
 #include "Device/Histo/IntensityDataIOFactory.h"
-#include "Device/Instrument/IntensityDataFunctions.h"
 #include "GUI/coregui/Models/RealDataItem.h"
 #include "GUI/coregui/Models/SessionModel.h"
 #include "GUI/coregui/mainwindow/ProjectUtils.h"
@@ -54,7 +54,7 @@ RealDataItem* GuiUnittestUtils::createRealData(const QString& name, SessionModel
 }
 
 bool GuiUnittestUtils::isTheSame(const OutputData<double>& data1, const OutputData<double>& data2) {
-    double diff = IntensityDataFunctions::getRelativeDifference(data1, data2);
+    double diff = DataUtils::relativeDataDifference(data1, data2);
     return diff < 1e-10;
 }
 
diff --git a/Wrap/Python/plot_utils.py b/Wrap/Python/plot_utils.py
index 6b569d757f72ee5de8ad7934d57b9876cfc1a151..d451cd7ddddf09255a4098dc17ead7c974d1b0aa 100644
--- a/Wrap/Python/plot_utils.py
+++ b/Wrap/Python/plot_utils.py
@@ -145,7 +145,7 @@ def plot_histogram(hist, **kwargs):
 def plot_colormap(result, **kwargs):
     """
     Plots intensity data as color map
-    :param result: SimulationResult from GISAS/OffSpecSimulation
+    :param result: SimulationResult from GISAS/OffSpecularSimulation
     :param zmin: Min value on amplitude's color bar
     :param zmax: Max value on amplitude's color bar
     """
@@ -198,7 +198,7 @@ def plot_specular_simulation_result(result, **kwargs):
 def plot_simulation_result(result, **kwargs):
     """
     Draws simulation result and (optionally) shows the plot.
-    :param result_: SimulationResult object obtained from GISAS/OffSpec/SpecularSimulation
+    :param result_: SimulationResult object obtained from GISAS/OffSpecular/SpecularSimulation
     :param intensity_min: Min value on amplitude's axis or color bar
     :param intensity_max: Max value on amplitude's axis or color bar
     :param units: units for plot axes
diff --git a/Wrap/Swig/DoxyfileSwig.in b/Wrap/Swig/DoxyfileSwig.in
index 82a483d43e88713cd556603541c5c5908cc3d598..16ea2c8bea06ea79e9790c0d14ab4b5a704457e6 100644
--- a/Wrap/Swig/DoxyfileSwig.in
+++ b/Wrap/Swig/DoxyfileSwig.in
@@ -880,7 +880,7 @@ RECURSIVE              = YES
 # Note that relative paths are relative to the directory from which doxygen is
 # run.
 
-EXCLUDE                =
+EXCLUDE                = 3rdParty
 
 # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
 # directories that are symbolic links (a Unix file system feature) are excluded
@@ -896,7 +896,7 @@ EXCLUDE_SYMLINKS       = NO
 # Note that the wildcards are matched against the file with absolute path, so to
 # exclude all test directories for example use the pattern */test/*
 
-EXCLUDE_PATTERNS       = */PythonAPI/*
+EXCLUDE_PATTERNS       =
 
 # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
 # (namespaces, classes, functions, etc.) that should be excluded from the
diff --git a/Wrap/Swig/libBornAgainBase.i b/Wrap/Swig/libBornAgainBase.i
index 2497f9d26aa94c173e774a4ef48f4f7b7315e677..4d280f2088a96d071e9b0304d4c6331dbad56ac5 100644
--- a/Wrap/Swig/libBornAgainBase.i
+++ b/Wrap/Swig/libBornAgainBase.i
@@ -25,10 +25,10 @@
 #include "Base/Types/Complex.h"
 #include "Base/Types/ICloneable.h"
 
-#include "Base/Utils/ThreadInfo.h"
-
 #include "Base/Const/Units.h"
 
+#include "Base/Utils/ThreadInfo.h"
+
 #include "Base/Vector/BasicVector3D.h"
 #include "Base/Vector/Vectors3D.h"
 #include "Base/Vector/Direction.h"
diff --git a/Wrap/Swig/libBornAgainCore.i b/Wrap/Swig/libBornAgainCore.i
index 69114fd852ee5a329f8089a88f44df97c4548639..2953ae10d67ea4af0e1e70075cbc4e0723a4f0e8 100644
--- a/Wrap/Swig/libBornAgainCore.i
+++ b/Wrap/Swig/libBornAgainCore.i
@@ -63,16 +63,20 @@
 #include "Core/Computation/PoissonNoiseBackground.h"
 #include "Core/Export/ExportToPython.h"
 #include "Core/Fitting/FitObjective.h"
-#include "Core/Fitting/IObserver.h"
 #include "Core/Fitting/IterationInfo.h"
 #include "Core/Fitting/PyFittingCallbacks.h"
+#include "Core/Residual/ChiSquaredModule.h"
+#include "Core/Residual/IChiSquaredModule.h"
+#include "Core/Residual/IIntensityFunction.h"
+#include "Core/Residual/IIntensityFunction.h"
+#include "Core/Residual/VarianceFunctions.h"
 #include "Core/Scan/AngularSpecScan.h"
 #include "Core/Scan/QSpecScan.h"
 #include "Core/Simulation/DepthProbeSimulation.h"
 #include "Core/Simulation/GISASSimulation.h"
 #include "Core/Simulation/ISimulation.h"
 #include "Core/Simulation/ISimulation2D.h"
-#include "Core/Simulation/OffSpecSimulation.h"
+#include "Core/Simulation/OffSpecularSimulation.h"
 #include "Core/Simulation/SimulationFactory.h"
 #include "Core/Simulation/SpecularSimulation.h"
 %}
@@ -99,7 +103,6 @@
 
 %include "BAVersion.h"
 
-%include "Core/Fitting/IObserver.h"
 %include "Core/Fitting/IterationInfo.h"
 %include "Core/Fitting/PyFittingCallbacks.h"
 
@@ -112,7 +115,7 @@
 %include "Core/Simulation/GISASSimulation.h"
 %include "Core/Simulation/DepthProbeSimulation.h"
 %include "Core/Simulation/SpecularSimulation.h"
-%include "Core/Simulation/OffSpecSimulation.h"
+%include "Core/Simulation/OffSpecularSimulation.h"
 
 %include "Core/Computation/IBackground.h"
 %include "Core/Computation/ConstantBackground.h"
@@ -120,6 +123,11 @@
 
 %include "Core/Export/ExportToPython.h"
 
+%include "Core/Residual/IIntensityFunction.h"
+%include "Core/Residual/IChiSquaredModule.h"
+%include "Core/Residual/ChiSquaredModule.h"
+%include "Core/Residual/VarianceFunctions.h"
+
 %extend BasicVector3D<double> {
     BasicVector3D<double> __add__(const BasicVector3D<double>& rhs) const {
         return *($self) + rhs; }
diff --git a/Wrap/Swig/libBornAgainDevice.i b/Wrap/Swig/libBornAgainDevice.i
index e795c309a36a34ff144437e76514bb21c3dcdfbb..79decbdfe6def3c9774e0d42dbe4f964d9e7d508 100644
--- a/Wrap/Swig/libBornAgainDevice.i
+++ b/Wrap/Swig/libBornAgainDevice.i
@@ -38,25 +38,19 @@
 #include "Device/Beam/Beam.h"
 #include "Device/Beam/FootprintGauss.h"
 #include "Device/Beam/FootprintSquare.h"
+#include "Device/Data/DataUtils.h"
 #include "Device/Data/OutputData.h"
 #include "Device/Detector/DetectorMask.h"
 #include "Device/Detector/IDetector2D.h"
 #include "Device/Detector/IsGISAXSDetector.h"
 #include "Device/Detector/RectangularDetector.h"
 #include "Device/Detector/SphericalDetector.h"
+#include "Device/Histo/HistoUtils.h"
 #include "Device/Histo/Histogram1D.h"
 #include "Device/Histo/Histogram2D.h"
 #include "Device/Histo/IHistogram.h"
 #include "Device/Histo/IntensityDataIOFactory.h"
 #include "Device/Histo/SimulationResult.h"
-#include "Device/Instrument/ChiSquaredModule.h"
-#include "Device/Instrument/IChiSquaredModule.h"
-#include "Device/Instrument/IntensityDataFunctions.h"
-#include "Device/Instrument/PyArrayImportUtils.h"
-#include "Device/Instrument/SpectrumUtils.h"
-#include "Device/Instrument/VarianceFunctions.h"
-#include "Device/Intensity/IIntensityFunction.h"
-#include "Device/Intensity/IIntensityFunction.h"
 #include "Device/Mask/Ellipse.h"
 #include "Device/Mask/IShape2D.h"
 #include "Device/Mask/Line.h"
@@ -88,18 +82,18 @@
 
 %newobject DetectorMask::createHistogram() const;
 
-%newobject PyArrayImport::importArrayToOutputData;
+%newobject DataUtils::importArrayToOutputData;
 %newobject IHistogram::createFrom(const std::string& filename);
 %newobject IHistogram::createFrom(const std::vector<std::vector<double>>& data);
 
 %include "Device/Data/OutputData.h"
 %template(IntensityData) OutputData<double>;
+%include "Device/Data/DataUtils.h"
 
 %include "Device/Beam/Beam.h"
 %include "Device/Beam/IFootprintFactor.h"
 %include "Device/Beam/FootprintGauss.h"
 %include "Device/Beam/FootprintSquare.h"
-%include "Device/Intensity/IIntensityFunction.h"
 %include "Device/Mask/IShape2D.h"
 %include "Device/Mask/Ellipse.h"
 %include "Device/Mask/Line.h"
@@ -110,13 +104,6 @@
 %include "Device/Resolution/ResolutionFunction2DGaussian.h"
 %include "Device/Resolution/ScanResolution.h"
 
-%include "Device/Instrument/IChiSquaredModule.h"
-%include "Device/Instrument/ChiSquaredModule.h"
-%include "Device/Instrument/IntensityDataFunctions.h"
-%include "Device/Instrument/PyArrayImportUtils.h"
-%include "Device/Instrument/SpectrumUtils.h"
-%include "Device/Instrument/VarianceFunctions.h"
-
 %include "Device/Unit/IUnitConverter.h"
 
 %include "Device/Detector/DetectorMask.h"
@@ -126,6 +113,7 @@
 %include "Device/Detector/SphericalDetector.h"
 %include "Device/Detector/IsGISAXSDetector.h"
 
+%include "Device/Histo/HistoUtils.h"
 %include "Device/Histo/IHistogram.h"
 %include "Device/Histo/Histogram1D.h"
 %include "Device/Histo/Histogram2D.h"
diff --git a/auto/Wrap/doxygenBase.i b/auto/Wrap/doxygenBase.i
index b9bb4d6f0f66217816bb62387d10017d5bda3046..95db86ee529200b4eab1e1c1cb7f5372fcbfd37b 100644
--- a/auto/Wrap/doxygenBase.i
+++ b/auto/Wrap/doxygenBase.i
@@ -4,7 +4,7 @@
 // File: classBasicVector3D.xml
 %feature("docstring") BasicVector3D "
 
-Forked from CLHEP/Geometry by E. Chernyaev Evgueni.Tcherniaev@cern.ch, then reworked beyond recognition. Removed split of point and vector semantics. Transforms are relegated to a separate class  Transform3D. Three-dimensional vector template, for use with integer, double, or complex components.
+Three-dimensional vector template, for use with integer, double, or complex components.
 
 C++ includes: BasicVector3D.h
 ";
@@ -99,7 +99,7 @@ Returns squared sine of polar angle.
 Returns unit vector in direction of this. Throws for null vector. 
 ";
 
-%feature("docstring")  BasicVector3D::complex "BasicVector3D<std::complex<double> > BasicVector3D< T >::complex() const
+%feature("docstring")  BasicVector3D::complex "BasicVector3D<complex_t> BasicVector3D< T >::complex() const
 
 Returns this, trivially converted to complex type. 
 ";
@@ -153,15 +153,6 @@ Returns result of rotation around z-axis.
 Returns result of rotation around the axis specified by another vector. 
 ";
 
-%feature("docstring")  BasicVector3D::conj "BasicVector3D< complex_t > BasicVector3D< complex_t >::conj() const
-";
-
-%feature("docstring")  BasicVector3D::real "BasicVector3D< double > BasicVector3D< complex_t >::real() const
-";
-
-%feature("docstring")  BasicVector3D::unit "BasicVector3D< complex_t > BasicVector3D< complex_t >::unit() const
-";
-
 
 // File: structBin1D.xml
 %feature("docstring") Bin1D "";
@@ -390,7 +381,12 @@ Increments inner counter; at regular intervals updates progress handler.
 
 
 // File: classDirection.xml
-%feature("docstring") Direction "";
+%feature("docstring") Direction "
+
+A direction in three-dimensional space.
+
+C++ includes: Direction.h
+";
 
 %feature("docstring")  Direction::Direction "Direction::Direction(double alpha, double phi)
 ";
@@ -492,6 +488,47 @@ Creates a new clipped axis.
 ";
 
 
+// File: classFourierTransform.xml
+%feature("docstring") FourierTransform "
+
+Fourier transform of vectors (in 1D or 2D) using Fast Fourier Transform (fftw package).
+
+Usage: std::vector<double> signal, result;  FourierTransform ft; ft.fft(signal, result)
+
+Given code rely on code from Jeremy Fix page, http://jeremy.fix.free.fr/spip.php?article15, see also \"Efficient convolution using the Fast Fourier Transform, Application in C++\" by Jeremy Fix, May 30, 2011
+
+C++ includes: FourierTransform.h
+";
+
+%feature("docstring")  FourierTransform::FourierTransform "FourierTransform::FourierTransform()
+";
+
+%feature("docstring")  FourierTransform::fft "void FourierTransform::fft(const double1d_t &source, double1d_t &result)
+
+FT in 1D. 
+";
+
+%feature("docstring")  FourierTransform::fftshift "void FourierTransform::fftshift(double1d_t &result)
+
+Shift low frequency to the center of 1D FT array. 
+";
+
+%feature("docstring")  FourierTransform::fft "void FourierTransform::fft(const double2d_t &source, double2d_t &result)
+
+FT in 2D. 
+";
+
+%feature("docstring")  FourierTransform::fftshift "void FourierTransform::fftshift(double2d_t &result)
+
+Shift low frequency to the center of 2D FT array. 
+";
+
+%feature("docstring")  FourierTransform::init "void FourierTransform::init(int h_src, int w_src)
+
+prepare arrays for 2D Fourier Transformation (FT) of the given vector 
+";
+
+
 // File: classIAxis.xml
 %feature("docstring") IAxis "
 
@@ -1166,6 +1203,9 @@ Creates a new clipped axis.
 ";
 
 
+// File: classFourierTransform_1_1Workspace.xml
+
+
 // File: namespace_0d16.xml
 
 
@@ -1364,40 +1404,43 @@ Returns the difference of the logarithm; input values are truncated at the minim
 // File: namespacePhysConsts.xml
 
 
-// File: namespacePyEmbeddedUtils.xml
-%feature("docstring")  PyEmbeddedUtils::toString "std::string PyEmbeddedUtils::toString(PyObject *obj)
+// File: namespacePyUtils.xml
+%feature("docstring")  PyUtils::toString "std::string PyUtils::toString(PyObject *obj)
 
 Converts PyObject into string, if possible, or throws exception. 
 ";
 
-%feature("docstring")  PyEmbeddedUtils::toVectorString "std::vector< std::string > PyEmbeddedUtils::toVectorString(PyObject *obj)
+%feature("docstring")  PyUtils::toVectorString "std::vector< std::string > PyUtils::toVectorString(PyObject *obj)
 
 Converts PyObject into vector of strings, if possible, or throws exception. 
 ";
 
-%feature("docstring")  PyEmbeddedUtils::toString "std::string PyEmbeddedUtils::toString(char *c)
+%feature("docstring")  PyUtils::toString "std::string PyUtils::toString(char *c)
 
 Converts char to string. In the case of nullptr will return an empty string. 
 ";
 
-%feature("docstring")  PyEmbeddedUtils::toString "std::string PyEmbeddedUtils::toString(wchar_t *c)
+%feature("docstring")  PyUtils::toString "std::string PyUtils::toString(wchar_t *c)
 ";
 
-%feature("docstring")  PyEmbeddedUtils::import_bornagain "void PyEmbeddedUtils::import_bornagain(const std::string &path=\"\")
+%feature("docstring")  PyUtils::import_bornagain "void PyUtils::import_bornagain(const std::string &path=\"\")
 
 Imports BornAgain from given location. If path is empty, tries to rely on PYTHONPATH. 
 ";
 
-%feature("docstring")  PyEmbeddedUtils::pythonRuntimeInfo "std::string PyEmbeddedUtils::pythonRuntimeInfo()
+%feature("docstring")  PyUtils::pythonRuntimeInfo "std::string PyUtils::pythonRuntimeInfo()
 
 Returns multi-line string representing PATH, PYTHONPATH, sys.path and other info. 
 ";
 
-%feature("docstring")  PyEmbeddedUtils::pythonStackTrace "std::string PyEmbeddedUtils::pythonStackTrace()
+%feature("docstring")  PyUtils::pythonStackTrace "std::string PyUtils::pythonStackTrace()
 
 Returns string representing python stack trace. 
 ";
 
+%feature("docstring")  PyUtils::createNumpyArray "PyObject * PyUtils::createNumpyArray(const std::vector< double > &data)
+";
+
 
 // File: namespaceStringUtils.xml
 %feature("docstring")  StringUtils::matchesPattern "bool StringUtils::matchesPattern(const std::string &text, const std::string &wildcardPattern)
@@ -1547,6 +1590,12 @@ global helper function for comparison of axes
 // File: Constants_8h.xml
 
 
+// File: FourierTransform_8cpp.xml
+
+
+// File: FourierTransform_8h.xml
+
+
 // File: Functions_8cpp.xml
 
 
@@ -1602,16 +1651,16 @@ Template function to create an integrator object
 // File: ProgressHandler_8h.xml
 
 
-// File: PyEmbeddedUtils_8cpp.xml
+// File: PyCore_8h.xml
 
 
-// File: PyEmbeddedUtils_8h.xml
+// File: PyObject_8h.xml
 
 
-// File: PyObject_8h.xml
+// File: PyUtils_8cpp.xml
 
 
-// File: PythonCore_8h.xml
+// File: PyUtils_8h.xml
 
 
 // File: CloneableVector_8h.xml
diff --git a/auto/Wrap/doxygenCore.i b/auto/Wrap/doxygenCore.i
index d0749185511c3e8b5f18dd03f6f77d8cd4255913..e3146e9007ac9bc782a3ce5a28992d4fd24d770e 100644
--- a/auto/Wrap/doxygenCore.i
+++ b/auto/Wrap/doxygenCore.i
@@ -178,6 +178,32 @@ Metric wrapper for back-compaptibility with old scripts.
 ";
 
 
+// File: classChiSquaredModule.xml
+%feature("docstring") ChiSquaredModule "
+
+Calculation of chi2 between two data sets.
+
+C++ includes: ChiSquaredModule.h
+";
+
+%feature("docstring")  ChiSquaredModule::ChiSquaredModule "ChiSquaredModule::ChiSquaredModule()
+";
+
+%feature("docstring")  ChiSquaredModule::ChiSquaredModule "ChiSquaredModule::ChiSquaredModule(const ChiSquaredModule &other)
+";
+
+%feature("docstring")  ChiSquaredModule::~ChiSquaredModule "virtual ChiSquaredModule::~ChiSquaredModule()
+";
+
+%feature("docstring")  ChiSquaredModule::clone "virtual ChiSquaredModule* ChiSquaredModule::clone() const
+
+clone method 
+";
+
+%feature("docstring")  ChiSquaredModule::residual "double ChiSquaredModule::residual(double a, double b, double weight)
+";
+
+
 // File: classComponentKeyHandler.xml
 %feature("docstring") ComponentKeyHandler "
 
@@ -814,6 +840,49 @@ C++ includes: IBackground.h
 ";
 
 
+// File: classIChiSquaredModule.xml
+%feature("docstring") IChiSquaredModule "
+
+Interface residual calculations.
+
+C++ includes: IChiSquaredModule.h
+";
+
+%feature("docstring")  IChiSquaredModule::IChiSquaredModule "IChiSquaredModule::IChiSquaredModule()
+";
+
+%feature("docstring")  IChiSquaredModule::~IChiSquaredModule "IChiSquaredModule::~IChiSquaredModule()
+";
+
+%feature("docstring")  IChiSquaredModule::clone "virtual IChiSquaredModule* IChiSquaredModule::clone() const =0
+
+clone method 
+";
+
+%feature("docstring")  IChiSquaredModule::varianceFunction "const IVarianceFunction * IChiSquaredModule::varianceFunction() const
+
+Returns squared function. 
+";
+
+%feature("docstring")  IChiSquaredModule::setVarianceFunction "void IChiSquaredModule::setVarianceFunction(const IVarianceFunction &variance_function)
+
+Sets squared function. 
+";
+
+%feature("docstring")  IChiSquaredModule::getIntensityFunction "const IIntensityFunction * IChiSquaredModule::getIntensityFunction() const
+
+Returns data rescaler. 
+";
+
+%feature("docstring")  IChiSquaredModule::setIntensityFunction "void IChiSquaredModule::setIntensityFunction(const IIntensityFunction &intensity_function)
+
+Sets data rescaler. 
+";
+
+%feature("docstring")  IChiSquaredModule::residual "virtual double IChiSquaredModule::residual(double a, double b, double weight)=0
+";
+
+
 // File: classIComputation.xml
 %feature("docstring") IComputation "
 
@@ -840,59 +909,68 @@ C++ includes: IComputation.h
 ";
 
 
-// File: classIMetricWrapper.xml
-%feature("docstring") IMetricWrapper "";
+// File: classIIntensityFunction.xml
+%feature("docstring") IIntensityFunction "
 
-%feature("docstring")  IMetricWrapper::~IMetricWrapper "IMetricWrapper::~IMetricWrapper()
+Interface for applying arbitrary function to the measured intensity.
+
+C++ includes: IIntensityFunction.h
 ";
 
-%feature("docstring")  IMetricWrapper::compute "virtual double IMetricWrapper::compute(const std::vector< SimDataPair > &fit_objects, size_t n_pars) const =0
+%feature("docstring")  IIntensityFunction::~IIntensityFunction "IIntensityFunction::~IIntensityFunction()
 ";
 
+%feature("docstring")  IIntensityFunction::clone "virtual IIntensityFunction* IIntensityFunction::clone() const =0
+";
+
+%feature("docstring")  IIntensityFunction::evaluate "virtual double IIntensityFunction::evaluate(double value) const =0
+";
 
-// File: classIObservable.xml
-%feature("docstring") IObservable "
 
-Observable interface from Observer pattern
+// File: classIMetricWrapper.xml
+%feature("docstring") IMetricWrapper "";
 
-C++ includes: IObserver.h
+%feature("docstring")  IMetricWrapper::~IMetricWrapper "IMetricWrapper::~IMetricWrapper()
 ";
 
-%feature("docstring")  IObservable::~IObservable "IObservable::~IObservable()
+%feature("docstring")  IMetricWrapper::compute "virtual double IMetricWrapper::compute(const std::vector< SimDataPair > &fit_objects, size_t n_pars) const =0
 ";
 
-%feature("docstring")  IObservable::attachObserver "void IObservable::attachObserver(observer_t obj)
 
-attach observer to the list of observers 
+// File: classIntensityFunctionLog.xml
+%feature("docstring") IntensityFunctionLog "
+
+Algorithm for applying log function to the measured intensity.
+
+C++ includes: IIntensityFunction.h
 ";
 
-%feature("docstring")  IObservable::notifyObservers "void IObservable::notifyObservers()
+%feature("docstring")  IntensityFunctionLog::clone "IntensityFunctionLog * IntensityFunctionLog::clone() const
+";
 
-notify observers about change in status 
+%feature("docstring")  IntensityFunctionLog::evaluate "double IntensityFunctionLog::evaluate(double value) const
 ";
 
 
-// File: classIObserver.xml
-%feature("docstring") IObserver "
+// File: classIntensityFunctionSqrt.xml
+%feature("docstring") IntensityFunctionSqrt "
 
-Observer interface from Observer pattern.
+Algorithm for applying sqrt function to the measured intensity.
 
-C++ includes: IObserver.h
+C++ includes: IIntensityFunction.h
 ";
 
-%feature("docstring")  IObserver::~IObserver "IObserver::~IObserver()
+%feature("docstring")  IntensityFunctionSqrt::clone "IntensityFunctionSqrt * IntensityFunctionSqrt::clone() const
 ";
 
-%feature("docstring")  IObserver::notify "virtual void IObserver::notify(IObservable *subject)=0
-
-method which is used by observable subject to notify change in status 
+%feature("docstring")  IntensityFunctionSqrt::evaluate "double IntensityFunctionSqrt::evaluate(double value) const
 ";
 
 
 // File: classISimulation.xml
 %feature("docstring") ISimulation "
 
-Abstract base class of OffSpecularSimulation,  GISASSimulation and  SpecularSimulation. Holds the common infrastructure to run a simulation: multithreading, batch processing, weighting over parameter distributions, ...
+Abstract base class of  OffSpecularSimulation,  GISASSimulation and  SpecularSimulation. Holds the common infrastructure to run a simulation: multithreading, batch processing, weighting over parameter distributions, ...
 
 C++ includes: ISimulation.h
 ";
@@ -947,14 +1025,6 @@ Run a simulation in a MPI environment.
 %feature("docstring")  ISimulation::detector "const IDetector& ISimulation::detector() const
 ";
 
-%feature("docstring")  ISimulation::setBeamIntensity "void ISimulation::setBeamIntensity(double intensity)
-";
-
-%feature("docstring")  ISimulation::setBeamPolarization "void ISimulation::setBeamPolarization(const kvector_t bloch_vector)
-
-Sets the beam polarization according to the given Bloch vector. 
-";
-
 %feature("docstring")  ISimulation::setDetectorResolutionFunction "void ISimulation::setDetectorResolutionFunction(const IResolutionFunction2D &resolution_function)
 ";
 
@@ -1028,7 +1098,7 @@ Convert user data to SimulationResult object for later drawing in various axes u
 // File: classISimulation2D.xml
 %feature("docstring") ISimulation2D "
 
-Abstract base class of OffSpecularSimulation and  GISASSimulation. Holds the common implementations for simulations with a 2D detector
+Abstract base class of  OffSpecularSimulation and  GISASSimulation. Holds the common implementations for simulations with a 2D detector
 
 C++ includes: ISimulation2D.h
 ";
@@ -1179,6 +1249,30 @@ Returns map of fit parameter names and its current values.
 ";
 
 
+// File: classIVarianceFunction.xml
+%feature("docstring") IVarianceFunction "
+
+Variance function interface.
+
+C++ includes: VarianceFunctions.h
+";
+
+%feature("docstring")  IVarianceFunction::IVarianceFunction "IVarianceFunction::IVarianceFunction()=default
+";
+
+%feature("docstring")  IVarianceFunction::~IVarianceFunction "virtual IVarianceFunction::~IVarianceFunction()=default
+";
+
+%feature("docstring")  IVarianceFunction::IVarianceFunction "IVarianceFunction::IVarianceFunction(const IVarianceFunction &)=delete
+";
+
+%feature("docstring")  IVarianceFunction::clone "virtual IVarianceFunction* IVarianceFunction::clone() const =0
+";
+
+%feature("docstring")  IVarianceFunction::variance "virtual double IVarianceFunction::variance(double real_value, double simulated_value) const =0
+";
+
+
 // File: classLogMetric.xml
 %feature("docstring") LogMetric "
 
@@ -1249,119 +1343,6 @@ C++ includes: MaterialKeyHandler.h
 ";
 
 
-// File: classMatrixRTCoefficients__v1.xml
-%feature("docstring") MatrixRTCoefficients_v1 "
-
-Specular reflection and transmission coefficients in a layer in case of 2x2 matrix interactions between the layers and the scattered particle.
-
-C++ includes: MatrixRTCoefficients_v1.h
-";
-
-%feature("docstring")  MatrixRTCoefficients_v1::MatrixRTCoefficients_v1 "MatrixRTCoefficients_v1::MatrixRTCoefficients_v1()
-";
-
-%feature("docstring")  MatrixRTCoefficients_v1::~MatrixRTCoefficients_v1 "virtual MatrixRTCoefficients_v1::~MatrixRTCoefficients_v1()
-";
-
-%feature("docstring")  MatrixRTCoefficients_v1::clone "MatrixRTCoefficients_v1 * MatrixRTCoefficients_v1::clone() const
-";
-
-%feature("docstring")  MatrixRTCoefficients_v1::T1plus "Eigen::Vector2cd MatrixRTCoefficients_v1::T1plus() const
-
-The following functions return the transmitted and reflected amplitudes for different incoming beam polarizations and eigenmodes 
-";
-
-%feature("docstring")  MatrixRTCoefficients_v1::R1plus "Eigen::Vector2cd MatrixRTCoefficients_v1::R1plus() const
-";
-
-%feature("docstring")  MatrixRTCoefficients_v1::T2plus "Eigen::Vector2cd MatrixRTCoefficients_v1::T2plus() const
-";
-
-%feature("docstring")  MatrixRTCoefficients_v1::R2plus "Eigen::Vector2cd MatrixRTCoefficients_v1::R2plus() const
-";
-
-%feature("docstring")  MatrixRTCoefficients_v1::T1min "Eigen::Vector2cd MatrixRTCoefficients_v1::T1min() const
-";
-
-%feature("docstring")  MatrixRTCoefficients_v1::R1min "Eigen::Vector2cd MatrixRTCoefficients_v1::R1min() const
-";
-
-%feature("docstring")  MatrixRTCoefficients_v1::T2min "Eigen::Vector2cd MatrixRTCoefficients_v1::T2min() const
-";
-
-%feature("docstring")  MatrixRTCoefficients_v1::R2min "Eigen::Vector2cd MatrixRTCoefficients_v1::R2min() const
-";
-
-%feature("docstring")  MatrixRTCoefficients_v1::getKz "virtual Eigen::Vector2cd MatrixRTCoefficients_v1::getKz() const
-
-Returns z-part of the two wavevector eigenmodes. 
-";
-
-%feature("docstring")  MatrixRTCoefficients_v1::calculateTRMatrices "void MatrixRTCoefficients_v1::calculateTRMatrices()
-";
-
-%feature("docstring")  MatrixRTCoefficients_v1::calculateTRWithoutMagnetization "void MatrixRTCoefficients_v1::calculateTRWithoutMagnetization()
-";
-
-%feature("docstring")  MatrixRTCoefficients_v1::initializeBottomLayerPhiPsi "void MatrixRTCoefficients_v1::initializeBottomLayerPhiPsi()
-";
-
-
-// File: classMatrixRTCoefficients__v2.xml
-%feature("docstring") MatrixRTCoefficients_v2 "
-
-Specular reflection and transmission coefficients in a layer in case of magnetic interactions between the scattered particle and the layer.
-
-C++ includes: MatrixRTCoefficients_v2.h
-";
-
-%feature("docstring")  MatrixRTCoefficients_v2::MatrixRTCoefficients_v2 "MatrixRTCoefficients_v2::MatrixRTCoefficients_v2(double kz_sign, Eigen::Vector2cd eigenvalues, kvector_t b)
-";
-
-%feature("docstring")  MatrixRTCoefficients_v2::MatrixRTCoefficients_v2 "MatrixRTCoefficients_v2::MatrixRTCoefficients_v2(const MatrixRTCoefficients_v2 &other)
-";
-
-%feature("docstring")  MatrixRTCoefficients_v2::~MatrixRTCoefficients_v2 "MatrixRTCoefficients_v2::~MatrixRTCoefficients_v2() override
-";
-
-%feature("docstring")  MatrixRTCoefficients_v2::clone "MatrixRTCoefficients_v2 * MatrixRTCoefficients_v2::clone() const override
-";
-
-%feature("docstring")  MatrixRTCoefficients_v2::T1plus "Eigen::Vector2cd MatrixRTCoefficients_v2::T1plus() const override
-
-The following functions return the transmitted and reflected amplitudes for different incoming beam polarizations and eigenmodes 
-";
-
-%feature("docstring")  MatrixRTCoefficients_v2::R1plus "Eigen::Vector2cd MatrixRTCoefficients_v2::R1plus() const override
-";
-
-%feature("docstring")  MatrixRTCoefficients_v2::T2plus "Eigen::Vector2cd MatrixRTCoefficients_v2::T2plus() const override
-";
-
-%feature("docstring")  MatrixRTCoefficients_v2::R2plus "Eigen::Vector2cd MatrixRTCoefficients_v2::R2plus() const override
-";
-
-%feature("docstring")  MatrixRTCoefficients_v2::T1min "Eigen::Vector2cd MatrixRTCoefficients_v2::T1min() const override
-";
-
-%feature("docstring")  MatrixRTCoefficients_v2::R1min "Eigen::Vector2cd MatrixRTCoefficients_v2::R1min() const override
-";
-
-%feature("docstring")  MatrixRTCoefficients_v2::T2min "Eigen::Vector2cd MatrixRTCoefficients_v2::T2min() const override
-";
-
-%feature("docstring")  MatrixRTCoefficients_v2::R2min "Eigen::Vector2cd MatrixRTCoefficients_v2::R2min() const override
-";
-
-%feature("docstring")  MatrixRTCoefficients_v2::getKz "Eigen::Vector2cd MatrixRTCoefficients_v2::getKz() const override
-
-Returns z-part of the two wavevector eigenmodes. 
-";
-
-%feature("docstring")  MatrixRTCoefficients_v2::getReflectionMatrix "Eigen::Matrix2cd MatrixRTCoefficients_v2::getReflectionMatrix() const override
-";
-
-
 // File: classMPISimulation.xml
 %feature("docstring") MPISimulation "";
 
@@ -1456,53 +1437,53 @@ Returns a copy of the normalization function used.
 // File: classFitObserver_1_1ObserverData.xml
 
 
-// File: classOffSpecSimulation.xml
-%feature("docstring") OffSpecSimulation "
+// File: classOffSpecularSimulation.xml
+%feature("docstring") OffSpecularSimulation "
 
 Main class to run an off-specular simulation.
 
-C++ includes: OffSpecSimulation.h
+C++ includes: OffSpecularSimulation.h
 ";
 
-%feature("docstring")  OffSpecSimulation::OffSpecSimulation "OffSpecSimulation::OffSpecSimulation(const Beam &beam, const MultiLayer &sample, const IDetector &detector)
+%feature("docstring")  OffSpecularSimulation::OffSpecularSimulation "OffSpecularSimulation::OffSpecularSimulation(const Beam &beam, const MultiLayer &sample, const IDetector &detector)
 ";
 
-%feature("docstring")  OffSpecSimulation::OffSpecSimulation "OffSpecSimulation::OffSpecSimulation()
+%feature("docstring")  OffSpecularSimulation::OffSpecularSimulation "OffSpecularSimulation::OffSpecularSimulation()
 ";
 
-%feature("docstring")  OffSpecSimulation::~OffSpecSimulation "OffSpecSimulation::~OffSpecSimulation() override
+%feature("docstring")  OffSpecularSimulation::~OffSpecularSimulation "OffSpecularSimulation::~OffSpecularSimulation() override
 ";
 
-%feature("docstring")  OffSpecSimulation::clone "OffSpecSimulation* OffSpecSimulation::clone() const override
+%feature("docstring")  OffSpecularSimulation::clone "OffSpecularSimulation* OffSpecularSimulation::clone() const override
 ";
 
-%feature("docstring")  OffSpecSimulation::accept "void OffSpecSimulation::accept(INodeVisitor *visitor) const override
+%feature("docstring")  OffSpecularSimulation::accept "void OffSpecularSimulation::accept(INodeVisitor *visitor) const override
 ";
 
-%feature("docstring")  OffSpecSimulation::prepareSimulation "void OffSpecSimulation::prepareSimulation() override
+%feature("docstring")  OffSpecularSimulation::prepareSimulation "void OffSpecularSimulation::prepareSimulation() override
 
 Put into a clean state for running a simulation. 
 ";
 
-%feature("docstring")  OffSpecSimulation::result "SimulationResult OffSpecSimulation::result() const override
+%feature("docstring")  OffSpecularSimulation::result "SimulationResult OffSpecularSimulation::result() const override
 
 Returns the results of the simulation in a format that supports unit conversion and export to numpy arrays 
 ";
 
-%feature("docstring")  OffSpecSimulation::setBeamParameters "void OffSpecSimulation::setBeamParameters(double wavelength, const IAxis &alpha_axis, double phi_i)
+%feature("docstring")  OffSpecularSimulation::setBeamParameters "void OffSpecularSimulation::setBeamParameters(double wavelength, const IAxis &alpha_axis, double phi_i)
 
 Sets beam parameters from here (forwarded to Instrument) 
 ";
 
-%feature("docstring")  OffSpecSimulation::beamAxis "const IAxis * OffSpecSimulation::beamAxis() const
+%feature("docstring")  OffSpecularSimulation::beamAxis "const IAxis * OffSpecularSimulation::beamAxis() const
 
 Returns axis of the beam. 
 ";
 
-%feature("docstring")  OffSpecSimulation::createUnitConverter "std::unique_ptr< IUnitConverter > OffSpecSimulation::createUnitConverter() const
+%feature("docstring")  OffSpecularSimulation::createUnitConverter "std::unique_ptr< IUnitConverter > OffSpecularSimulation::createUnitConverter() const
 ";
 
-%feature("docstring")  OffSpecSimulation::intensityMapSize "size_t OffSpecSimulation::intensityMapSize() const override
+%feature("docstring")  OffSpecularSimulation::intensityMapSize "size_t OffSpecularSimulation::intensityMapSize() const override
 
 Returns the total number of the intensity values in the simulation result. 
 ";
@@ -2027,44 +2008,6 @@ C++ includes: SpecularComputationTerm.h
 ";
 
 
-// File: classSpecularMagneticStrategy__v1.xml
-%feature("docstring") SpecularMagneticStrategy_v1 "
-
-Implements the matrix formalism for the calculation of wave amplitudes of the coherent wave solution in a multilayer with magnetization.
-
-C++ includes: SpecularMagneticStrategy_v1.h
-";
-
-%feature("docstring")  SpecularMagneticStrategy_v1::Execute "ISpecularStrategy::coeffs_t SpecularMagneticStrategy_v1::Execute(const std::vector< Slice > &slices, const kvector_t &k) const
-
-Computes refraction angle reflection/transmission coefficients for given sliced multilayer and wavevector k 
-";
-
-%feature("docstring")  SpecularMagneticStrategy_v1::Execute "ISpecularStrategy::coeffs_t SpecularMagneticStrategy_v1::Execute(const std::vector< Slice > &slices, const std::vector< complex_t > &kz) const
-";
-
-
-// File: classSpecularMagneticStrategy__v2.xml
-%feature("docstring") SpecularMagneticStrategy_v2 "
-
-Implements the magnetic Fresnel computation without roughness
-
-Implements the matrix formalism for the calculation of wave amplitudes of the coherent wave solution in a multilayer with magnetization. For a detailed description see internal document \"Polarized Specular Reflectometry\"
-
-C++ includes: SpecularMagneticStrategy_v2.h
-";
-
-%feature("docstring")  SpecularMagneticStrategy_v2::Execute "ISpecularStrategy::coeffs_t SpecularMagneticStrategy_v2::Execute(const std::vector< Slice > &slices, const kvector_t &k) const
-
-Computes refraction angle reflection/transmission coefficients for given sliced multilayer and wavevector k 
-";
-
-%feature("docstring")  SpecularMagneticStrategy_v2::Execute "ISpecularStrategy::coeffs_t SpecularMagneticStrategy_v2::Execute(const std::vector< Slice > &slices, const std::vector< complex_t > &kz) const
-
-Computes refraction angle reflection/transmission coefficients for given sliced multilayer and a set of kz projections corresponding to each slice 
-";
-
-
 // File: classSpecularMatrixTerm.xml
 %feature("docstring") SpecularMatrixTerm "
 
@@ -2301,7 +2244,37 @@ Returns default units to convert to.
 ";
 
 
-// File: namespace_0d101.xml
+// 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: namespace_0d15.xml
@@ -2319,40 +2292,34 @@ Returns default units to convert to.
 // File: namespace_0d47.xml
 
 
-// File: namespace_0d56.xml
-
-
-// File: namespace_0d58.xml
-
+// File: namespace_0d54.xml
 
-// File: namespace_0d62.xml
 
-
-// File: namespace_0d66.xml
+// File: namespace_0d56.xml
 
 
-// File: namespace_0d68.xml
+// File: namespace_0d60.xml
 
 
 // File: namespace_0d70.xml
 
 
-// File: namespace_0d72.xml
+// File: namespace_0d75.xml
 
 
 // File: namespace_0d77.xml
 
 
-// File: namespace_0d79.xml
+// File: namespace_0d81.xml
 
 
-// File: namespace_0d83.xml
+// File: namespace_0d91.xml
 
 
 // File: namespace_0d93.xml
 
 
-// File: namespace_0d95.xml
+// File: namespace_0d99.xml
 
 
 // File: namespaceExportToPython.xml
@@ -2687,7 +2654,7 @@ GISAS simulation with an extra long wavelength.
 %feature("docstring")  StandardSimulations::BasicSpecularQMP "SpecularSimulation * StandardSimulations::BasicSpecularQMP()
 ";
 
-%feature("docstring")  StandardSimulations::MiniOffSpec "OffSpecSimulation * StandardSimulations::MiniOffSpec()
+%feature("docstring")  StandardSimulations::MiniOffSpecular "OffSpecularSimulation * StandardSimulations::MiniOffSpecular()
 ";
 
 %feature("docstring")  StandardSimulations::BasicDepthProbe "DepthProbeSimulation * StandardSimulations::BasicDepthProbe()
@@ -2865,12 +2832,6 @@ Helper factory function to use in  GISASSimulation. Depending on the type of det
 // File: FitTypes_8h.xml
 
 
-// File: IObserver_8cpp.xml
-
-
-// File: IObserver_8h.xml
-
-
 // File: IterationInfo_8cpp.xml
 
 
@@ -2901,28 +2862,28 @@ Helper factory function to use in  GISASSimulation. Depending on the type of det
 // File: SimDataPair_8h.xml
 
 
-// File: MatrixRTCoefficients__v1_8cpp.xml
+// File: ChiSquaredModule_8cpp.xml
 
 
-// File: MatrixRTCoefficients__v1_8h.xml
+// File: ChiSquaredModule_8h.xml
 
 
-// File: MatrixRTCoefficients__v2_8cpp.xml
+// File: IChiSquaredModule_8cpp.xml
 
 
-// File: MatrixRTCoefficients__v2_8h.xml
+// File: IChiSquaredModule_8h.xml
 
 
-// File: SpecularMagneticStrategy__v1_8cpp.xml
+// File: IIntensityFunction_8cpp.xml
 
 
-// File: SpecularMagneticStrategy__v1_8h.xml
+// File: IIntensityFunction_8h.xml
 
 
-// File: SpecularMagneticStrategy__v2_8cpp.xml
+// File: VarianceFunctions_8cpp.xml
 
 
-// File: SpecularMagneticStrategy__v2_8h.xml
+// File: VarianceFunctions_8h.xml
 
 
 // File: AngularSpecScan_8cpp.xml
@@ -2976,10 +2937,10 @@ Helper factory function to use in  GISASSimulation. Depending on the type of det
 // File: MPISimulation_8h.xml
 
 
-// File: OffSpecSimulation_8cpp.xml
+// File: OffSpecularSimulation_8cpp.xml
 
 
-// File: OffSpecSimulation_8h.xml
+// File: OffSpecularSimulation_8h.xml
 
 
 // File: SimulationFactory_8cpp.xml
@@ -3033,7 +2994,7 @@ Helper factory function to use in  GISASSimulation. Depending on the type of det
 // File: dir_4470199ae7eb44153ffe31d163ed0f28.xml
 
 
-// File: dir_bd39ec89b96ad8d1385770847b662047.xml
+// File: dir_bfeb1e458a74587b0ec5055179ee8176.xml
 
 
 // File: dir_6de83e740cfcd9d0abfe8dffab2832a5.xml
diff --git a/auto/Wrap/doxygenDevice.i b/auto/Wrap/doxygenDevice.i
index c1a20b8f1ca65a87e951a4fdea27fb9a59aaf111..f3966bd3db5ec507b6452b120fa1eff7abcbbe75 100644
--- a/auto/Wrap/doxygenDevice.i
+++ b/auto/Wrap/doxygenDevice.i
@@ -110,32 +110,6 @@ Sets the polarization density matrix according to the given Bloch vector.
 ";
 
 
-// File: classChiSquaredModule.xml
-%feature("docstring") ChiSquaredModule "
-
-Calculation of chi2 between two data sets.
-
-C++ includes: ChiSquaredModule.h
-";
-
-%feature("docstring")  ChiSquaredModule::ChiSquaredModule "ChiSquaredModule::ChiSquaredModule()
-";
-
-%feature("docstring")  ChiSquaredModule::ChiSquaredModule "ChiSquaredModule::ChiSquaredModule(const ChiSquaredModule &other)
-";
-
-%feature("docstring")  ChiSquaredModule::~ChiSquaredModule "virtual ChiSquaredModule::~ChiSquaredModule()
-";
-
-%feature("docstring")  ChiSquaredModule::clone "virtual ChiSquaredModule* ChiSquaredModule::clone() const
-
-clone method 
-";
-
-%feature("docstring")  ChiSquaredModule::residual "double ChiSquaredModule::residual(double a, double b, double weight)
-";
-
-
 // File: classConvolutionDetectorResolution.xml
 %feature("docstring") ConvolutionDetectorResolution "
 
@@ -525,47 +499,6 @@ Calculate footprint correction coefficient from the beam incident angle  alpha.
 ";
 
 
-// File: classFourierTransform.xml
-%feature("docstring") FourierTransform "
-
-Fourier transform of vectors (in 1D or 2D) using Fast Fourier Transform (fftw package).
-
-Usage: std::vector<double> signal, result;  FourierTransform ft; ft.fft(signal, result)
-
-Given code rely on code from Jeremy Fix page, http://jeremy.fix.free.fr/spip.php?article15, see also \"Efficient convolution using the Fast Fourier Transform, Application in C++\" by Jeremy Fix, May 30, 2011
-
-C++ includes: FourierTransform.h
-";
-
-%feature("docstring")  FourierTransform::FourierTransform "FourierTransform::FourierTransform()
-";
-
-%feature("docstring")  FourierTransform::fft "void FourierTransform::fft(const double1d_t &source, double1d_t &result)
-
-FT in 1D. 
-";
-
-%feature("docstring")  FourierTransform::fftshift "void FourierTransform::fftshift(double1d_t &result)
-
-Shift low frequency to the center of 1D FT array. 
-";
-
-%feature("docstring")  FourierTransform::fft "void FourierTransform::fft(const double2d_t &source, double2d_t &result)
-
-FT in 2D. 
-";
-
-%feature("docstring")  FourierTransform::fftshift "void FourierTransform::fftshift(double2d_t &result)
-
-Shift low frequency to the center of 2D FT array. 
-";
-
-%feature("docstring")  FourierTransform::init "void FourierTransform::init(int h_src, int w_src)
-
-prepare arrays for 2D Fourier Transformation (FT) of the given vector 
-";
-
-
 // File: classHistogram1D.xml
 %feature("docstring") Histogram1D "
 
@@ -854,49 +787,6 @@ Returns true if area defined by two bins is inside or on border of polygon (more
 ";
 
 
-// File: classIChiSquaredModule.xml
-%feature("docstring") IChiSquaredModule "
-
-Interface residual calculations.
-
-C++ includes: IChiSquaredModule.h
-";
-
-%feature("docstring")  IChiSquaredModule::IChiSquaredModule "IChiSquaredModule::IChiSquaredModule()
-";
-
-%feature("docstring")  IChiSquaredModule::~IChiSquaredModule "IChiSquaredModule::~IChiSquaredModule()
-";
-
-%feature("docstring")  IChiSquaredModule::clone "virtual IChiSquaredModule* IChiSquaredModule::clone() const =0
-
-clone method 
-";
-
-%feature("docstring")  IChiSquaredModule::varianceFunction "const IVarianceFunction * IChiSquaredModule::varianceFunction() const
-
-Returns squared function. 
-";
-
-%feature("docstring")  IChiSquaredModule::setVarianceFunction "void IChiSquaredModule::setVarianceFunction(const IVarianceFunction &variance_function)
-
-Sets squared function. 
-";
-
-%feature("docstring")  IChiSquaredModule::getIntensityFunction "const IIntensityFunction * IChiSquaredModule::getIntensityFunction() const
-
-Returns data rescaler. 
-";
-
-%feature("docstring")  IChiSquaredModule::setIntensityFunction "void IChiSquaredModule::setIntensityFunction(const IIntensityFunction &intensity_function)
-
-Sets data rescaler. 
-";
-
-%feature("docstring")  IChiSquaredModule::residual "virtual double IChiSquaredModule::residual(double a, double b, double weight)=0
-";
-
-
 // File: classIDetector.xml
 %feature("docstring") IDetector "
 
@@ -1391,24 +1281,6 @@ Loads histogram from file, the shape of array in file should match Following for
 ";
 
 
-// File: classIIntensityFunction.xml
-%feature("docstring") IIntensityFunction "
-
-Interface for applying arbitrary function to the measured intensity.
-
-C++ includes: IIntensityFunction.h
-";
-
-%feature("docstring")  IIntensityFunction::~IIntensityFunction "IIntensityFunction::~IIntensityFunction()
-";
-
-%feature("docstring")  IIntensityFunction::clone "virtual IIntensityFunction* IIntensityFunction::clone() const =0
-";
-
-%feature("docstring")  IIntensityFunction::evaluate "virtual double IIntensityFunction::evaluate(double value) const =0
-";
-
-
 // File: classInfinitePlane.xml
 %feature("docstring") InfinitePlane "
 
@@ -1471,14 +1343,6 @@ C++ includes: Instrument.h
 Sets the beam wavelength and incoming angles. 
 ";
 
-%feature("docstring")  Instrument::setBeamIntensity "void Instrument::setBeamIntensity(double intensity)
-";
-
-%feature("docstring")  Instrument::setBeamPolarization "void Instrument::setBeamPolarization(const kvector_t bloch_vector)
-
-Sets the beam's polarization according to the given Bloch vector. 
-";
-
 %feature("docstring")  Instrument::getDetector "const IDetector * Instrument::getDetector() const
 ";
 
@@ -1519,36 +1383,6 @@ C++ includes: IntensityDataIOFactory.h
 ";
 
 
-// File: classIntensityFunctionLog.xml
-%feature("docstring") IntensityFunctionLog "
-
-Algorithm for applying log function to the measured intensity.
-
-C++ includes: IIntensityFunction.h
-";
-
-%feature("docstring")  IntensityFunctionLog::clone "IntensityFunctionLog * IntensityFunctionLog::clone() const
-";
-
-%feature("docstring")  IntensityFunctionLog::evaluate "double IntensityFunctionLog::evaluate(double value) const
-";
-
-
-// File: classIntensityFunctionSqrt.xml
-%feature("docstring") IntensityFunctionSqrt "
-
-Algorithm for applying sqrt function to the measured intensity.
-
-C++ includes: IIntensityFunction.h
-";
-
-%feature("docstring")  IntensityFunctionSqrt::clone "IntensityFunctionSqrt * IntensityFunctionSqrt::clone() const
-";
-
-%feature("docstring")  IntensityFunctionSqrt::evaluate "double IntensityFunctionSqrt::evaluate(double value) const
-";
-
-
 // File: classIResolutionFunction2D.xml
 %feature("docstring") IResolutionFunction2D "
 
@@ -1669,30 +1503,6 @@ Creates  OutputData array in converter units.
 ";
 
 
-// File: classIVarianceFunction.xml
-%feature("docstring") IVarianceFunction "
-
-Variance function interface.
-
-C++ includes: VarianceFunctions.h
-";
-
-%feature("docstring")  IVarianceFunction::IVarianceFunction "IVarianceFunction::IVarianceFunction()=default
-";
-
-%feature("docstring")  IVarianceFunction::~IVarianceFunction "virtual IVarianceFunction::~IVarianceFunction()=default
-";
-
-%feature("docstring")  IVarianceFunction::IVarianceFunction "IVarianceFunction::IVarianceFunction(const IVarianceFunction &)=delete
-";
-
-%feature("docstring")  IVarianceFunction::clone "virtual IVarianceFunction* IVarianceFunction::clone() const =0
-";
-
-%feature("docstring")  IVarianceFunction::variance "virtual double IVarianceFunction::variance(double real_value, double simulated_value) const =0
-";
-
-
 // File: classLine.xml
 %feature("docstring") Line "
 
@@ -1793,7 +1603,7 @@ C++ includes: SimpleUnitConverters.h
 // File: classOutputData.xml
 %feature("docstring") OutputData "
 
-Template class to store data of any type in multi-dimensional space.
+Templated class to store data of type double or  CumulativeValue in multi-dimensional space.
 
 C++ includes: OutputData.h
 ";
@@ -1830,11 +1640,6 @@ C++ includes: OutputData.h
 returns axis with given serial number 
 ";
 
-%feature("docstring")  OutputData::axis "const IAxis & OutputData< T >::axis(const std::string &axis_name) const
-
-returns axis with given name 
-";
-
 %feature("docstring")  OutputData::rank "size_t OutputData< T >::rank() const
 
 Returns number of dimensions. 
@@ -2950,39 +2755,6 @@ Returns the list of all available units.
 ";
 
 
-// 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 "
 
@@ -3017,22 +2789,22 @@ Returns true if area defined by two bins is inside or on border of polygon (more
 ";
 
 
-// File: classFourierTransform_1_1Workspace.xml
+// File: classConvolve_1_1Workspace.xml
 
 
-// File: classConvolve_1_1Workspace.xml
+// File: namespace_0d11.xml
 
 
-// File: namespace_0d107.xml
+// File: namespace_0d38.xml
 
 
-// File: namespace_0d35.xml
+// File: namespace_0d63.xml
 
 
-// File: namespace_0d58.xml
+// File: namespace_0d69.xml
 
 
-// File: namespace_0d64.xml
+// File: namespace_0d94.xml
 
 
 // File: namespaceArrayUtils.xml
@@ -3046,9 +2818,6 @@ Returns shape nrows, ncols of 2D array.
 Creates  OutputData array from input vector. 
 ";
 
-%feature("docstring")  ArrayUtils::createNumpyArray "PyObject * ArrayUtils::createNumpyArray(const std::vector< double > &data)
-";
-
 %feature("docstring")  ArrayUtils::createVector1D "decltype(auto) ArrayUtils::createVector1D(const T &data)
 
 Creates 1D vector from  OutputData. 
@@ -3073,10 +2842,10 @@ Creates 2D vector from  OutputData.
 %feature("docstring")  AxisNames::InitRectangularAxis1 "std::map< Axes::Units, std::string > AxisNames::InitRectangularAxis1()
 ";
 
-%feature("docstring")  AxisNames::InitOffSpecAxis0 "std::map< Axes::Units, std::string > AxisNames::InitOffSpecAxis0()
+%feature("docstring")  AxisNames::InitOffSpecularAxis0 "std::map< Axes::Units, std::string > AxisNames::InitOffSpecularAxis0()
 ";
 
-%feature("docstring")  AxisNames::InitOffSpecAxis1 "std::map< Axes::Units, std::string > AxisNames::InitOffSpecAxis1()
+%feature("docstring")  AxisNames::InitOffSpecularAxis1 "std::map< Axes::Units, std::string > AxisNames::InitOffSpecularAxis1()
 ";
 
 %feature("docstring")  AxisNames::InitSpecAxis "std::map< Axes::Units, std::string > AxisNames::InitSpecAxis()
@@ -3146,100 +2915,95 @@ Parse double values from string to vector of double.
 ";
 
 
-// File: namespaceDetectorUtils.xml
-%feature("docstring")  DetectorUtils::isQuadratic "bool DetectorUtils::isQuadratic(const IDetector2D &det)
-";
-
-
-// File: namespaceIntensityDataFunctions.xml
-%feature("docstring")  IntensityDataFunctions::RelativeDifference "double IntensityDataFunctions::RelativeDifference(const SimulationResult &dat, const SimulationResult &ref)
-
-Returns sum of relative differences between each pair of elements: (a, b) -> 2*abs(a - b)/(a + b) ( and zero if a-b=0 )
-
-Returns sum of relative differences between each pair of elements: (a, b) -> 2*abs(a - b)/(|a| + |b|) ( and zero if a=b=0 within epsilon ) 
-";
-
-%feature("docstring")  IntensityDataFunctions::getRelativeDifference "double IntensityDataFunctions::getRelativeDifference(const OutputData< double > &dat, const OutputData< double > &ref)
+// File: namespaceDataUtils.xml
+%feature("docstring")  DataUtils::relativeDataDifference "double DataUtils::relativeDataDifference(const OutputData< double > &dat, const OutputData< double > &ref)
 
 Returns relative difference between two data sets sum(dat[i] - ref[i])/ref[i]). 
 ";
 
-%feature("docstring")  IntensityDataFunctions::checkRelativeDifference "bool IntensityDataFunctions::checkRelativeDifference(const OutputData< double > &dat, const OutputData< double > &ref, const double threshold)
+%feature("docstring")  DataUtils::checkRelativeDifference "bool DataUtils::checkRelativeDifference(const OutputData< double > &dat, const OutputData< double > &ref, const double threshold)
 
 Returns true is relative difference is below threshold; prints informative output. 
 ";
 
-%feature("docstring")  IntensityDataFunctions::getRelativeDifference "double IntensityDataFunctions::getRelativeDifference(const IHistogram &dat, const IHistogram &ref)
-";
-
-%feature("docstring")  IntensityDataFunctions::coordinateToBinf "double IntensityDataFunctions::coordinateToBinf(double coordinate, const IAxis &axis)
+%feature("docstring")  DataUtils::coordinateToBinf "double DataUtils::coordinateToBinf(double coordinate, const IAxis &axis)
 
 Transforms coordinate on axis into the bin-fraction-coordinate. 
 ";
 
-%feature("docstring")  IntensityDataFunctions::coordinateFromBinf "double IntensityDataFunctions::coordinateFromBinf(double value, const IAxis &axis)
+%feature("docstring")  DataUtils::coordinateFromBinf "double DataUtils::coordinateFromBinf(double value, const IAxis &axis)
 
 Transforms bin-fraction-coordinate into axis coordinate. 
 ";
 
-%feature("docstring")  IntensityDataFunctions::coordinateToBinf "void IntensityDataFunctions::coordinateToBinf(double &x, double &y, const OutputData< double > &data)
+%feature("docstring")  DataUtils::coordinateToBinf "void DataUtils::coordinateToBinf(double &x, double &y, const OutputData< double > &data)
 
 Transforms x,y coordinate from  OutputData axes coordinates to bin-fraction-coordinates. 
 ";
 
-%feature("docstring")  IntensityDataFunctions::coordinateFromBinf "void IntensityDataFunctions::coordinateFromBinf(double &x, double &y, const OutputData< double > &data)
+%feature("docstring")  DataUtils::coordinateFromBinf "void DataUtils::coordinateFromBinf(double &x, double &y, const OutputData< double > &data)
 
 Transforms x,y coordinate from bin-fraction-coordinates to  OutputData's axes coordinates. 
 ";
 
-%feature("docstring")  IntensityDataFunctions::create2DArrayfromOutputData "std::vector< std::vector< double > > IntensityDataFunctions::create2DArrayfromOutputData(const OutputData< double > &data)
+%feature("docstring")  DataUtils::create2DArrayfromOutputData "std::vector< std::vector< double > > DataUtils::create2DArrayfromOutputData(const OutputData< double > &data)
 
 Creates a vector of vectors of double (2D Array) from  OutputData. 
 ";
 
-%feature("docstring")  IntensityDataFunctions::FT2DArray "std::vector< std::vector< double > > IntensityDataFunctions::FT2DArray(const std::vector< std::vector< double >> &signal)
+%feature("docstring")  DataUtils::importArrayToOutputData "OutputData< double > * DataUtils::importArrayToOutputData(const std::vector< double > &vec)
 
-Creates a Fourier Transform of a 2D Array (vector of vectors). 
+Reads 1D array of doubles to Python, for use in persistence test. 
 ";
 
-%feature("docstring")  IntensityDataFunctions::createRelativeDifferenceData "std::unique_ptr< OutputData< double > > IntensityDataFunctions::createRelativeDifferenceData(const OutputData< double > &data, const OutputData< double > &reference)
+%feature("docstring")  DataUtils::importArrayToOutputData "OutputData< double > * DataUtils::importArrayToOutputData(const std::vector< std::vector< double >> &vec)
+
+Reads 2D array of doubles to Python, for use in persistence test. 
 ";
 
-%feature("docstring")  IntensityDataFunctions::createRearrangedDataSet "std::unique_ptr< OutputData< double > > IntensityDataFunctions::createRearrangedDataSet(const OutputData< double > &data, int n)
+%feature("docstring")  DataUtils::createRelativeDifferenceData "std::unique_ptr< OutputData< double > > DataUtils::createRelativeDifferenceData(const OutputData< double > &data, const OutputData< double > &reference)
+";
+
+%feature("docstring")  DataUtils::createRearrangedDataSet "std::unique_ptr< OutputData< double > > DataUtils::createRearrangedDataSet(const OutputData< double > &data, int n)
 
 Returns new object with input data rotated by n*90 deg counterclockwise (n > 0) or clockwise (n < 0)  Axes are swapped if the data is effectively rotated by 90 or 270 degrees Applicable to 2D arrays only 
 ";
 
-%feature("docstring")  IntensityDataFunctions::createClippedDataSet "std::unique_ptr< OutputData< double > > IntensityDataFunctions::createClippedDataSet(const OutputData< double > &origin, double x1, double y1, double x2, double y2)
+%feature("docstring")  DataUtils::createClippedDataSet "std::unique_ptr< OutputData< double > > DataUtils::createClippedDataSet(const OutputData< double > &origin, double x1, double y1, double x2, double y2)
 
 Returns new IntensityData objects which axes clipped to represent the specified rectangle. 
 ";
 
-%feature("docstring")  IntensityDataFunctions::createOutputDatafrom2DArray "std::unique_ptr< OutputData< double > > IntensityDataFunctions::createOutputDatafrom2DArray(const std::vector< std::vector< double >> &array_2d)
+%feature("docstring")  DataUtils::createOutputDatafrom2DArray "std::unique_ptr< OutputData< double > > DataUtils::createOutputDatafrom2DArray(const std::vector< std::vector< double >> &array_2d)
 
 Creates  OutputData from a 2D Array. 
 ";
 
-%feature("docstring")  IntensityDataFunctions::createFFT "std::unique_ptr< OutputData< double > > IntensityDataFunctions::createFFT(const OutputData< double > &data)
+%feature("docstring")  DataUtils::createFFT "std::unique_ptr< OutputData< double > > DataUtils::createFFT(const OutputData< double > &data)
 
 Creates Fourier Transform ( OutputData format) of intensity map ( OutputData format). 
 ";
 
 
-// File: namespacePyArrayImport.xml
-%feature("docstring")  PyArrayImport::importArrayToOutputData "OutputData< double > * PyArrayImport::importArrayToOutputData(const std::vector< double > &vec)
-
-for importing 1D array of doubles from python into  OutputData
+// File: namespaceDetectorUtils.xml
+%feature("docstring")  DetectorUtils::isQuadratic "bool DetectorUtils::isQuadratic(const IDetector2D &det)
 ";
 
-%feature("docstring")  PyArrayImport::importArrayToOutputData "OutputData< double > * PyArrayImport::importArrayToOutputData(const std::vector< std::vector< double >> &vec)
 
-for importing 2D array of doubles from python into  OutputData
+// File: namespaceHistoUtils.xml
+%feature("docstring")  HistoUtils::FindPeaks "std::vector< std::pair< double, double > > HistoUtils::FindPeaks(const Histogram2D &hist, double sigma=2, const std::string &option={}, double threshold=0.05)
+
+Returns vector of peak center coordinates, for peaks in given histogram. 
 ";
 
+%feature("docstring")  HistoUtils::RelativeDifference "double HistoUtils::RelativeDifference(const SimulationResult &dat, const SimulationResult &ref)
 
-// File: namespaceSpectrumUtils.xml
-%feature("docstring")  SpectrumUtils::FindPeaks "std::vector< std::pair< double, double > > SpectrumUtils::FindPeaks(const Histogram2D &hist, double sigma=2, const std::string &option={}, double threshold=0.05)
+Returns sum of relative differences between each pair of elements: (a, b) -> 2*abs(a - b)/(a + b) ( and zero if a-b=0 )
+
+Returns sum of relative differences between each pair of elements: (a, b) -> 2*abs(a - b)/(|a| + |b|) ( and zero if a=b=0 within epsilon ) 
+";
+
+%feature("docstring")  HistoUtils::getRelativeDifference "double HistoUtils::getRelativeDifference(const IHistogram &dat, const IHistogram &ref)
 ";
 
 
@@ -3267,12 +3031,21 @@ for importing 2D array of doubles from python into  OutputData
 // File: IFootprintFactor_8h.xml
 
 
+// File: ArrayUtils_8h.xml
+
+
 // File: CumulativeValue_8cpp.xml
 
 
 // File: CumulativeValue_8h.xml
 
 
+// File: DataUtils_8cpp.xml
+
+
+// File: DataUtils_8h.xml
+
+
 // File: LLData_8cpp.xml
 
 
@@ -3402,6 +3175,12 @@ make Swappable
 // File: Histogram2D_8h.xml
 
 
+// File: HistoUtils_8cpp.xml
+
+
+// File: HistoUtils_8h.xml
+
+
 // File: IHistogram_8cpp.xml
 
 
@@ -3453,66 +3232,12 @@ make Swappable
 // File: OutputDataReadWriteTiff_8h.xml
 
 
-// File: ChiSquaredModule_8cpp.xml
-
-
-// File: ChiSquaredModule_8h.xml
-
-
-// File: FourierTransform_8cpp.xml
-
-
-// File: FourierTransform_8h.xml
-
-
-// File: IChiSquaredModule_8cpp.xml
-
-
-// File: IChiSquaredModule_8h.xml
-
-
 // File: Instrument_8cpp.xml
 
 
 // File: Instrument_8h.xml
 
 
-// File: IntensityDataFunctions_8cpp.xml
-
-
-// File: IntensityDataFunctions_8h.xml
-
-
-// File: PyArrayImportUtils_8cpp.xml
-
-
-// File: PyArrayImportUtils_8h.xml
-
-
-// File: SpectrumUtils_8cpp.xml
-
-
-// File: SpectrumUtils_8h.xml
-
-
-// File: VarianceFunctions_8cpp.xml
-
-
-// File: VarianceFunctions_8h.xml
-
-
-// File: ArrayUtils_8cpp.xml
-
-
-// File: ArrayUtils_8h.xml
-
-
-// File: IIntensityFunction_8cpp.xml
-
-
-// File: IIntensityFunction_8h.xml
-
-
 // File: Ellipse_8cpp.xml
 
 
@@ -3612,9 +3337,6 @@ make Swappable
 // File: dir_550e786a97bd4c801929243ea9773c04.xml
 
 
-// File: dir_401915efc9e4b0dfad0f4a62e1092d10.xml
-
-
 // File: dir_4866552d576e04b61ad8ade47c8db877.xml
 
 
diff --git a/auto/Wrap/doxygenParam.i b/auto/Wrap/doxygenParam.i
index 5c39d00ae1e728ca78f0fa88fefcbfec7f032970..527a3363a94232170232bdd53b2446960c052681 100644
--- a/auto/Wrap/doxygenParam.i
+++ b/auto/Wrap/doxygenParam.i
@@ -457,7 +457,7 @@ Returns a vector of children.
 
 %feature("docstring")  INode::progeny "std::vector< const INode * > INode::progeny() const
 
-Returns a vector of all descendents. 
+Returns a vector of all descendants. 
 ";
 
 %feature("docstring")  INode::setParent "void INode::setParent(const INode *newParent)
@@ -816,7 +816,7 @@ C++ includes: INodeVisitor.h
 %feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const MultiLayer *)
 ";
 
-%feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const OffSpecSimulation *)
+%feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const OffSpecularSimulation *)
 ";
 
 %feature("docstring")  INodeVisitor::visit "virtual void INodeVisitor::visit(const Particle *)
@@ -1494,7 +1494,7 @@ C++ includes: Unit.h
 // File: namespaceNodeUtils.xml
 %feature("docstring")  NodeUtils::progenyPlus "std::vector< std::tuple< const INode *, int, const INode * > > NodeUtils::progenyPlus(const INode *node, int level=0)
 
-Returns a vector of triples (descendent, depth, parent) 
+Returns a vector of triples (descendant, depth, parent) 
 ";
 
 %feature("docstring")  NodeUtils::nodeToString "std::string NodeUtils::nodeToString(const INode *node)
diff --git a/auto/Wrap/doxygenSample.i b/auto/Wrap/doxygenSample.i
index f113d09dbfbcf1f3d95c3c9548bf7fa225ed5a67..268a397f96a25b042228b05432d81fea26633724 100644
--- a/auto/Wrap/doxygenSample.i
+++ b/auto/Wrap/doxygenSample.i
@@ -140,7 +140,12 @@ C++ includes: ParaCrystalBuilder.h
 
 
 // File: classBasicLattice2D.xml
-%feature("docstring") BasicLattice2D "";
+%feature("docstring") BasicLattice2D "
+
+A two-dimensional Bravais lattice with no special symmetry.
+
+C++ includes: Lattice2D.h
+";
 
 %feature("docstring")  BasicLattice2D::BasicLattice2D "BasicLattice2D::BasicLattice2D(double length1, double length2, double angle, double xi)
 ";
@@ -2855,7 +2860,12 @@ C++ includes: PercusYevickBuilder.h
 
 
 // File: classHexagonalLattice2D.xml
-%feature("docstring") HexagonalLattice2D "";
+%feature("docstring") HexagonalLattice2D "
+
+A two-dimensional Bravais lattice with hexagonal symmetry.
+
+C++ includes: Lattice2D.h
+";
 
 %feature("docstring")  HexagonalLattice2D::HexagonalLattice2D "HexagonalLattice2D::HexagonalLattice2D(double length, double xi)
 ";
@@ -4704,7 +4714,12 @@ C++ includes: LatticeBuilder.h
 
 
 // File: classLattice2D.xml
-%feature("docstring") Lattice2D "";
+%feature("docstring") Lattice2D "
+
+A two-dimensional Bravais lattice.
+
+C++ includes: Lattice2D.h
+";
 
 %feature("docstring")  Lattice2D::Lattice2D "Lattice2D::Lattice2D(const NodeMeta &meta, const std::vector< double > &PValues)
 ";
@@ -4823,7 +4838,7 @@ Sets a selection rule for the reciprocal vectors.
 // File: classLayer.xml
 %feature("docstring") Layer "
 
-A layer, with thickness (in nanometer) and material.
+A layer in a  MultiLayer sample.
 
 C++ includes: Layer.h
 ";
@@ -5470,6 +5485,119 @@ Returns z-part of the two wavevector eigenmodes.
 ";
 
 
+// File: classMatrixRTCoefficients__v1.xml
+%feature("docstring") MatrixRTCoefficients_v1 "
+
+Specular reflection and transmission coefficients in a layer in case of 2x2 matrix interactions between the layers and the scattered particle.
+
+C++ includes: MatrixRTCoefficients_v1.h
+";
+
+%feature("docstring")  MatrixRTCoefficients_v1::MatrixRTCoefficients_v1 "MatrixRTCoefficients_v1::MatrixRTCoefficients_v1()
+";
+
+%feature("docstring")  MatrixRTCoefficients_v1::~MatrixRTCoefficients_v1 "virtual MatrixRTCoefficients_v1::~MatrixRTCoefficients_v1()
+";
+
+%feature("docstring")  MatrixRTCoefficients_v1::clone "MatrixRTCoefficients_v1 * MatrixRTCoefficients_v1::clone() const
+";
+
+%feature("docstring")  MatrixRTCoefficients_v1::T1plus "Eigen::Vector2cd MatrixRTCoefficients_v1::T1plus() const
+
+The following functions return the transmitted and reflected amplitudes for different incoming beam polarizations and eigenmodes 
+";
+
+%feature("docstring")  MatrixRTCoefficients_v1::R1plus "Eigen::Vector2cd MatrixRTCoefficients_v1::R1plus() const
+";
+
+%feature("docstring")  MatrixRTCoefficients_v1::T2plus "Eigen::Vector2cd MatrixRTCoefficients_v1::T2plus() const
+";
+
+%feature("docstring")  MatrixRTCoefficients_v1::R2plus "Eigen::Vector2cd MatrixRTCoefficients_v1::R2plus() const
+";
+
+%feature("docstring")  MatrixRTCoefficients_v1::T1min "Eigen::Vector2cd MatrixRTCoefficients_v1::T1min() const
+";
+
+%feature("docstring")  MatrixRTCoefficients_v1::R1min "Eigen::Vector2cd MatrixRTCoefficients_v1::R1min() const
+";
+
+%feature("docstring")  MatrixRTCoefficients_v1::T2min "Eigen::Vector2cd MatrixRTCoefficients_v1::T2min() const
+";
+
+%feature("docstring")  MatrixRTCoefficients_v1::R2min "Eigen::Vector2cd MatrixRTCoefficients_v1::R2min() const
+";
+
+%feature("docstring")  MatrixRTCoefficients_v1::getKz "virtual Eigen::Vector2cd MatrixRTCoefficients_v1::getKz() const
+
+Returns z-part of the two wavevector eigenmodes. 
+";
+
+%feature("docstring")  MatrixRTCoefficients_v1::calculateTRMatrices "void MatrixRTCoefficients_v1::calculateTRMatrices()
+";
+
+%feature("docstring")  MatrixRTCoefficients_v1::calculateTRWithoutMagnetization "void MatrixRTCoefficients_v1::calculateTRWithoutMagnetization()
+";
+
+%feature("docstring")  MatrixRTCoefficients_v1::initializeBottomLayerPhiPsi "void MatrixRTCoefficients_v1::initializeBottomLayerPhiPsi()
+";
+
+
+// File: classMatrixRTCoefficients__v2.xml
+%feature("docstring") MatrixRTCoefficients_v2 "
+
+Specular reflection and transmission coefficients in a layer in case of magnetic interactions between the scattered particle and the layer.
+
+C++ includes: MatrixRTCoefficients_v2.h
+";
+
+%feature("docstring")  MatrixRTCoefficients_v2::MatrixRTCoefficients_v2 "MatrixRTCoefficients_v2::MatrixRTCoefficients_v2(double kz_sign, Eigen::Vector2cd eigenvalues, kvector_t b)
+";
+
+%feature("docstring")  MatrixRTCoefficients_v2::MatrixRTCoefficients_v2 "MatrixRTCoefficients_v2::MatrixRTCoefficients_v2(const MatrixRTCoefficients_v2 &other)
+";
+
+%feature("docstring")  MatrixRTCoefficients_v2::~MatrixRTCoefficients_v2 "MatrixRTCoefficients_v2::~MatrixRTCoefficients_v2() override
+";
+
+%feature("docstring")  MatrixRTCoefficients_v2::clone "MatrixRTCoefficients_v2 * MatrixRTCoefficients_v2::clone() const override
+";
+
+%feature("docstring")  MatrixRTCoefficients_v2::T1plus "Eigen::Vector2cd MatrixRTCoefficients_v2::T1plus() const override
+
+The following functions return the transmitted and reflected amplitudes for different incoming beam polarizations and eigenmodes 
+";
+
+%feature("docstring")  MatrixRTCoefficients_v2::R1plus "Eigen::Vector2cd MatrixRTCoefficients_v2::R1plus() const override
+";
+
+%feature("docstring")  MatrixRTCoefficients_v2::T2plus "Eigen::Vector2cd MatrixRTCoefficients_v2::T2plus() const override
+";
+
+%feature("docstring")  MatrixRTCoefficients_v2::R2plus "Eigen::Vector2cd MatrixRTCoefficients_v2::R2plus() const override
+";
+
+%feature("docstring")  MatrixRTCoefficients_v2::T1min "Eigen::Vector2cd MatrixRTCoefficients_v2::T1min() const override
+";
+
+%feature("docstring")  MatrixRTCoefficients_v2::R1min "Eigen::Vector2cd MatrixRTCoefficients_v2::R1min() const override
+";
+
+%feature("docstring")  MatrixRTCoefficients_v2::T2min "Eigen::Vector2cd MatrixRTCoefficients_v2::T2min() const override
+";
+
+%feature("docstring")  MatrixRTCoefficients_v2::R2min "Eigen::Vector2cd MatrixRTCoefficients_v2::R2min() const override
+";
+
+%feature("docstring")  MatrixRTCoefficients_v2::getKz "Eigen::Vector2cd MatrixRTCoefficients_v2::getKz() const override
+
+Returns z-part of the two wavevector eigenmodes. 
+";
+
+%feature("docstring")  MatrixRTCoefficients_v2::getReflectionMatrix "Eigen::Matrix2cd MatrixRTCoefficients_v2::getReflectionMatrix() const override
+";
+
+
 // File: classMesoCrystal.xml
 %feature("docstring") MesoCrystal "
 
@@ -7158,6 +7286,44 @@ Computes refraction angle reflection/transmission coefficients for given sliced
 ";
 
 
+// File: classSpecularMagneticStrategy__v1.xml
+%feature("docstring") SpecularMagneticStrategy_v1 "
+
+Implements the matrix formalism for the calculation of wave amplitudes of the coherent wave solution in a multilayer with magnetization.
+
+C++ includes: SpecularMagneticStrategy_v1.h
+";
+
+%feature("docstring")  SpecularMagneticStrategy_v1::Execute "ISpecularStrategy::coeffs_t SpecularMagneticStrategy_v1::Execute(const std::vector< Slice > &slices, const kvector_t &k) const
+
+Computes refraction angle reflection/transmission coefficients for given sliced multilayer and wavevector k 
+";
+
+%feature("docstring")  SpecularMagneticStrategy_v1::Execute "ISpecularStrategy::coeffs_t SpecularMagneticStrategy_v1::Execute(const std::vector< Slice > &slices, const std::vector< complex_t > &kz) const
+";
+
+
+// File: classSpecularMagneticStrategy__v2.xml
+%feature("docstring") SpecularMagneticStrategy_v2 "
+
+Implements the magnetic Fresnel computation without roughness
+
+Implements the matrix formalism for the calculation of wave amplitudes of the coherent wave solution in a multilayer with magnetization. For a detailed description see internal document \"Polarized Specular Reflectometry\"
+
+C++ includes: SpecularMagneticStrategy_v2.h
+";
+
+%feature("docstring")  SpecularMagneticStrategy_v2::Execute "ISpecularStrategy::coeffs_t SpecularMagneticStrategy_v2::Execute(const std::vector< Slice > &slices, const kvector_t &k) const
+
+Computes refraction angle reflection/transmission coefficients for given sliced multilayer and wavevector k 
+";
+
+%feature("docstring")  SpecularMagneticStrategy_v2::Execute "ISpecularStrategy::coeffs_t SpecularMagneticStrategy_v2::Execute(const std::vector< Slice > &slices, const std::vector< complex_t > &kz) const
+
+Computes refraction angle reflection/transmission coefficients for given sliced multilayer and a set of kz projections corresponding to each slice 
+";
+
+
 // File: classSpecularMagneticTanhStrategy.xml
 %feature("docstring") SpecularMagneticTanhStrategy "
 
@@ -7232,7 +7398,12 @@ C++ includes: ParticleDistributionsBuilder.h
 
 
 // File: classSquareLattice2D.xml
-%feature("docstring") SquareLattice2D "";
+%feature("docstring") SquareLattice2D "
+
+A two-dimensional Bravais lattice with square unit cell.
+
+C++ includes: Lattice2D.h
+";
 
 %feature("docstring")  SquareLattice2D::SquareLattice2D "SquareLattice2D::SquareLattice2D(double length, double xi=0.0)
 ";
@@ -7471,10 +7642,13 @@ C++ includes: ZLimits.h
 // File: namespace_0d125.xml
 
 
-// File: namespace_0d149.xml
+// File: namespace_0d148.xml
+
 
+// File: namespace_0d150.xml
 
-// File: namespace_0d153.xml
+
+// File: namespace_0d152.xml
 
 
 // File: namespace_0d157.xml
@@ -7483,82 +7657,88 @@ C++ includes: ZLimits.h
 // File: namespace_0d16.xml
 
 
-// File: namespace_0d169.xml
+// File: namespace_0d161.xml
+
+
+// File: namespace_0d165.xml
+
 
+// File: namespace_0d177.xml
 
-// File: namespace_0d171.xml
 
+// File: namespace_0d179.xml
 
-// File: namespace_0d181.xml
+
+// File: namespace_0d189.xml
 
 
 // File: namespace_0d2.xml
 
 
-// File: namespace_0d201.xml
+// File: namespace_0d209.xml
 
 
-// File: namespace_0d203.xml
+// File: namespace_0d211.xml
 
 
-// File: namespace_0d205.xml
+// File: namespace_0d213.xml
 
 
-// File: namespace_0d208.xml
+// File: namespace_0d216.xml
 
 
-// File: namespace_0d218.xml
+// File: namespace_0d226.xml
 
 
-// File: namespace_0d232.xml
+// File: namespace_0d240.xml
 
 
-// File: namespace_0d237.xml
+// File: namespace_0d245.xml
 
 
 // File: namespace_0d25.xml
 
 
-// File: namespace_0d255.xml
+// File: namespace_0d263.xml
 
 
-// File: namespace_0d263.xml
+// File: namespace_0d271.xml
 
 
-// File: namespace_0d273.xml
+// File: namespace_0d281.xml
 
 
-// File: namespace_0d275.xml
+// File: namespace_0d283.xml
 
 
-// File: namespace_0d277.xml
+// File: namespace_0d285.xml
 
 
-// File: namespace_0d281.xml
+// File: namespace_0d289.xml
 
 
-// File: namespace_0d283.xml
+// File: namespace_0d291.xml
 
 
-// File: namespace_0d287.xml
+// File: namespace_0d295.xml
 
 
-// File: namespace_0d299.xml
+// File: namespace_0d307.xml
 
 
-// File: namespace_0d305.xml
+// File: namespace_0d31.xml
 
 
-// File: namespace_0d309.xml
+// File: namespace_0d313.xml
 
 
-// File: namespace_0d31.xml
+// File: namespace_0d317.xml
 
 
-// File: namespace_0d327.xml
+// File: namespace_0d335.xml
 
 
-// File: namespace_0d346.xml
+// File: namespace_0d354.xml
 
 
 // File: namespace_0d37.xml
@@ -8188,6 +8368,30 @@ Get default z limits for generating a material profile.
 // File: Lattice3D_8h.xml
 
 
+// File: MatrixRTCoefficients__v1_8cpp.xml
+
+
+// File: MatrixRTCoefficients__v1_8h.xml
+
+
+// File: MatrixRTCoefficients__v2_8cpp.xml
+
+
+// File: MatrixRTCoefficients__v2_8h.xml
+
+
+// File: SpecularMagneticStrategy__v1_8cpp.xml
+
+
+// File: SpecularMagneticStrategy__v1_8h.xml
+
+
+// File: SpecularMagneticStrategy__v2_8cpp.xml
+
+
+// File: SpecularMagneticStrategy__v2_8h.xml
+
+
 // File: SomeFormFactors_8cpp.xml
 
 
@@ -8963,6 +9167,9 @@ Generate vertices of centered ellipse with given semi-axes at height z.
 // File: dir_da063889c15f3636a66540651967c41d.xml
 
 
+// File: dir_9a5e0b0e0913dd118bde6961ef93e44c.xml
+
+
 // File: dir_ed097210e0926370940660d36aeab42a.xml
 
 
diff --git a/auto/Wrap/libBornAgainBase.py b/auto/Wrap/libBornAgainBase.py
index 42bc36a22441656ddad66f52c1772fc53170097f..d1bfa23c9cf0e5b9288cdd9946776fad087f5d07 100644
--- a/auto/Wrap/libBornAgainBase.py
+++ b/auto/Wrap/libBornAgainBase.py
@@ -1769,22 +1769,6 @@ class ThreadInfo(object):
 _libBornAgainBase.ThreadInfo_swigregister(ThreadInfo)
 
 
-def rad2deg(angle):
-    r"""
-    rad2deg(double angle) -> double
-    double Units::rad2deg(double angle)
-
-    """
-    return _libBornAgainBase.rad2deg(angle)
-
-def deg2rad(angle):
-    r"""
-    deg2rad(double angle) -> double
-    double Units::deg2rad(double angle)
-
-    """
-    return _libBornAgainBase.deg2rad(angle)
-
 def vecOfLambdaAlphaPhi(_lambda, _alpha, _phi):
     r"""
     vecOfLambdaAlphaPhi(double _lambda, double _alpha, double _phi) -> kvector_t
@@ -1793,7 +1777,14 @@ def vecOfLambdaAlphaPhi(_lambda, _alpha, _phi):
     """
     return _libBornAgainBase.vecOfLambdaAlphaPhi(_lambda, _alpha, _phi)
 class Direction(object):
-    r"""Proxy of C++ Direction class."""
+    r"""
+
+
+    A direction in three-dimensional space.
+
+    C++ includes: Direction.h
+
+    """
 
     thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
     __repr__ = _swig_repr
@@ -1856,17 +1847,9 @@ nanometer = cvar.nanometer
 angstrom = cvar.angstrom
 micrometer = cvar.micrometer
 millimeter = cvar.millimeter
-meter = cvar.meter
 nm = cvar.nm
 nm2 = cvar.nm2
-barn = cvar.barn
-radian = cvar.radian
-milliradian = cvar.milliradian
-degree = cvar.degree
-steradian = cvar.steradian
 rad = cvar.rad
-mrad = cvar.mrad
-sr = cvar.sr
 deg = cvar.deg
 tesla = cvar.tesla
 gauss = cvar.gauss
@@ -2677,7 +2660,7 @@ class kvector_t(object):
     r"""
 
 
-    Forked from CLHEP/Geometry by E. Chernyaev Evgueni.Tcherniaev@cern.ch, then reworked beyond recognition. Removed split of point and vector semantics. Transforms are relegated to a separate class  Transform3D. Three-dimensional vector template, for use with integer, double, or complex components.
+    Three-dimensional vector template, for use with integer, double, or complex components.
 
     C++ includes: BasicVector3D.h
 
@@ -2768,7 +2751,9 @@ class kvector_t(object):
     def conj(self):
         r"""
         conj(kvector_t self) -> kvector_t
-        BasicVector3D< complex_t > BasicVector3D< complex_t >::conj() const
+        BasicVector3D<T> BasicVector3D< T >::conj() const
+
+        Returns complex conjugate vector. 
 
         """
         return _libBornAgainBase.kvector_t_conj(self)
@@ -2856,7 +2841,9 @@ class kvector_t(object):
     def unit(self):
         r"""
         unit(kvector_t self) -> kvector_t
-        BasicVector3D< complex_t > BasicVector3D< complex_t >::unit() const
+        BasicVector3D<T> BasicVector3D< T >::unit() const
+
+        Returns unit vector in direction of this. Throws for null vector. 
 
         """
         return _libBornAgainBase.kvector_t_unit(self)
@@ -2864,7 +2851,7 @@ class kvector_t(object):
     def complex(self):
         r"""
         complex(kvector_t self) -> cvector_t
-        BasicVector3D<std::complex<double> > BasicVector3D< T >::complex() const
+        BasicVector3D<complex_t> BasicVector3D< T >::complex() const
 
         Returns this, trivially converted to complex type. 
 
@@ -2874,7 +2861,9 @@ class kvector_t(object):
     def real(self):
         r"""
         real(kvector_t self) -> kvector_t
-        BasicVector3D< double > BasicVector3D< complex_t >::real() const
+        BasicVector3D<double> BasicVector3D< T >::real() const
+
+        Returns real parts. 
 
         """
         return _libBornAgainBase.kvector_t_real(self)
@@ -3074,7 +3063,7 @@ class cvector_t(object):
     r"""
 
 
-    Forked from CLHEP/Geometry by E. Chernyaev Evgueni.Tcherniaev@cern.ch, then reworked beyond recognition. Removed split of point and vector semantics. Transforms are relegated to a separate class  Transform3D. Three-dimensional vector template, for use with integer, double, or complex components.
+    Three-dimensional vector template, for use with integer, double, or complex components.
 
     C++ includes: BasicVector3D.h
 
@@ -3165,7 +3154,9 @@ class cvector_t(object):
     def conj(self):
         r"""
         conj(cvector_t self) -> cvector_t
-        BasicVector3D< complex_t > BasicVector3D< complex_t >::conj() const
+        BasicVector3D<T> BasicVector3D< T >::conj() const
+
+        Returns complex conjugate vector. 
 
         """
         return _libBornAgainBase.cvector_t_conj(self)
@@ -3213,7 +3204,9 @@ class cvector_t(object):
     def unit(self):
         r"""
         unit(cvector_t self) -> cvector_t
-        BasicVector3D< complex_t > BasicVector3D< complex_t >::unit() const
+        BasicVector3D<T> BasicVector3D< T >::unit() const
+
+        Returns unit vector in direction of this. Throws for null vector. 
 
         """
         return _libBornAgainBase.cvector_t_unit(self)
@@ -3221,7 +3214,9 @@ class cvector_t(object):
     def real(self):
         r"""
         real(cvector_t self) -> kvector_t
-        BasicVector3D< double > BasicVector3D< complex_t >::real() const
+        BasicVector3D<double> BasicVector3D< T >::real() const
+
+        Returns real parts. 
 
         """
         return _libBornAgainBase.cvector_t_real(self)
diff --git a/auto/Wrap/libBornAgainBase_wrap.cpp b/auto/Wrap/libBornAgainBase_wrap.cpp
index c0aa71b944b19ac95bc887ea291f25d177a4c9c5..6b9093a40e0d19dc63a3eb8691987835f6d28517 100644
--- a/auto/Wrap/libBornAgainBase_wrap.cpp
+++ b/auto/Wrap/libBornAgainBase_wrap.cpp
@@ -6654,10 +6654,10 @@ SWIGINTERN void std_vector_Sl_std_pair_Sl_double_Sc_double_Sg__Sg__insert__SWIG_
 #include "Base/Types/Complex.h"
 #include "Base/Types/ICloneable.h"
 
-#include "Base/Utils/ThreadInfo.h"
-
 #include "Base/Const/Units.h"
 
+#include "Base/Utils/ThreadInfo.h"
+
 #include "Base/Vector/BasicVector3D.h"
 #include "Base/Vector/Vectors3D.h"
 #include "Base/Vector/Direction.h"
@@ -24297,20 +24297,6 @@ SWIGINTERN PyObject *Swig_var_millimeter_get(void) {
 }
 
 
-SWIGINTERN int Swig_var_meter_set(PyObject *) {
-  SWIG_Error(SWIG_AttributeError,"Variable meter is read-only.");
-  return 1;
-}
-
-
-SWIGINTERN PyObject *Swig_var_meter_get(void) {
-  PyObject *pyobj = 0;
-  
-  pyobj = SWIG_From_double(static_cast< double >(Units::meter));
-  return pyobj;
-}
-
-
 SWIGINTERN int Swig_var_nm_set(PyObject *) {
   SWIG_Error(SWIG_AttributeError,"Variable nm is read-only.");
   return 1;
@@ -24339,122 +24325,6 @@ SWIGINTERN PyObject *Swig_var_nm2_get(void) {
 }
 
 
-SWIGINTERN int Swig_var_barn_set(PyObject *) {
-  SWIG_Error(SWIG_AttributeError,"Variable barn is read-only.");
-  return 1;
-}
-
-
-SWIGINTERN PyObject *Swig_var_barn_get(void) {
-  PyObject *pyobj = 0;
-  
-  pyobj = SWIG_From_double(static_cast< double >(Units::barn));
-  return pyobj;
-}
-
-
-SWIGINTERN int Swig_var_radian_set(PyObject *) {
-  SWIG_Error(SWIG_AttributeError,"Variable radian is read-only.");
-  return 1;
-}
-
-
-SWIGINTERN PyObject *Swig_var_radian_get(void) {
-  PyObject *pyobj = 0;
-  
-  pyobj = SWIG_From_double(static_cast< double >(Units::radian));
-  return pyobj;
-}
-
-
-SWIGINTERN int Swig_var_milliradian_set(PyObject *) {
-  SWIG_Error(SWIG_AttributeError,"Variable milliradian is read-only.");
-  return 1;
-}
-
-
-SWIGINTERN PyObject *Swig_var_milliradian_get(void) {
-  PyObject *pyobj = 0;
-  
-  pyobj = SWIG_From_double(static_cast< double >(Units::milliradian));
-  return pyobj;
-}
-
-
-SWIGINTERN int Swig_var_degree_set(PyObject *) {
-  SWIG_Error(SWIG_AttributeError,"Variable degree is read-only.");
-  return 1;
-}
-
-
-SWIGINTERN PyObject *Swig_var_degree_get(void) {
-  PyObject *pyobj = 0;
-  
-  pyobj = SWIG_From_double(static_cast< double >(Units::degree));
-  return pyobj;
-}
-
-
-SWIGINTERN int Swig_var_steradian_set(PyObject *) {
-  SWIG_Error(SWIG_AttributeError,"Variable steradian is read-only.");
-  return 1;
-}
-
-
-SWIGINTERN PyObject *Swig_var_steradian_get(void) {
-  PyObject *pyobj = 0;
-  
-  pyobj = SWIG_From_double(static_cast< double >(Units::steradian));
-  return pyobj;
-}
-
-
-SWIGINTERN PyObject *_wrap_rad2deg(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  double arg1 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  PyObject *swig_obj[1] ;
-  double result;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  ecode1 = SWIG_AsVal_double(swig_obj[0], &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "rad2deg" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  result = (double)Units::rad2deg(arg1);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_deg2rad(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  double arg1 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  PyObject *swig_obj[1] ;
-  double result;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  ecode1 = SWIG_AsVal_double(swig_obj[0], &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "deg2rad" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  result = (double)Units::deg2rad(arg1);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN int Swig_var_rad_set(PyObject *) {
   SWIG_Error(SWIG_AttributeError,"Variable rad is read-only.");
   return 1;
@@ -24469,34 +24339,6 @@ SWIGINTERN PyObject *Swig_var_rad_get(void) {
 }
 
 
-SWIGINTERN int Swig_var_mrad_set(PyObject *) {
-  SWIG_Error(SWIG_AttributeError,"Variable mrad is read-only.");
-  return 1;
-}
-
-
-SWIGINTERN PyObject *Swig_var_mrad_get(void) {
-  PyObject *pyobj = 0;
-  
-  pyobj = SWIG_From_double(static_cast< double >(Units::mrad));
-  return pyobj;
-}
-
-
-SWIGINTERN int Swig_var_sr_set(PyObject *) {
-  SWIG_Error(SWIG_AttributeError,"Variable sr is read-only.");
-  return 1;
-}
-
-
-SWIGINTERN PyObject *Swig_var_sr_get(void) {
-  PyObject *pyobj = 0;
-  
-  pyobj = SWIG_From_double(static_cast< double >(Units::sr));
-  return pyobj;
-}
-
-
 SWIGINTERN int Swig_var_deg_set(PyObject *) {
   SWIG_Error(SWIG_AttributeError,"Variable deg is read-only.");
   return 1;
@@ -28178,7 +28020,7 @@ SWIGINTERN PyObject *_wrap_kvector_t_complex(PyObject *SWIGUNUSEDPARM(self), PyO
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject *swig_obj[1] ;
-  BasicVector3D< std::complex< double > > result;
+  BasicVector3D< complex_t > result;
   
   if (!args) SWIG_fail;
   swig_obj[0] = args;
@@ -28188,7 +28030,7 @@ SWIGINTERN PyObject *_wrap_kvector_t_complex(PyObject *SWIGUNUSEDPARM(self), PyO
   }
   arg1 = reinterpret_cast< BasicVector3D< double > * >(argp1);
   result = ((BasicVector3D< double > const *)arg1)->complex();
-  resultobj = SWIG_NewPointerObj((new BasicVector3D< std::complex< double > >(static_cast< const BasicVector3D< std::complex< double > >& >(result))), SWIGTYPE_p_BasicVector3DT_std__complexT_double_t_t, SWIG_POINTER_OWN |  0 );
+  resultobj = SWIG_NewPointerObj((new BasicVector3D< complex_t >(static_cast< const BasicVector3D< complex_t >& >(result))), SWIGTYPE_p_BasicVector3DT_std__complexT_double_t_t, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -33130,16 +32972,6 @@ static PyMethodDef SwigMethods[] = {
 	 { "delete_ThreadInfo", _wrap_delete_ThreadInfo, METH_O, "delete_ThreadInfo(ThreadInfo self)"},
 	 { "ThreadInfo_swigregister", ThreadInfo_swigregister, METH_O, NULL},
 	 { "ThreadInfo_swiginit", ThreadInfo_swiginit, METH_VARARGS, NULL},
-	 { "rad2deg", _wrap_rad2deg, METH_O, "\n"
-		"rad2deg(double angle) -> double\n"
-		"double Units::rad2deg(double angle)\n"
-		"\n"
-		""},
-	 { "deg2rad", _wrap_deg2rad, METH_O, "\n"
-		"deg2rad(double angle) -> double\n"
-		"double Units::deg2rad(double angle)\n"
-		"\n"
-		""},
 	 { "vecOfLambdaAlphaPhi", _wrap_vecOfLambdaAlphaPhi, METH_VARARGS, "\n"
 		"vecOfLambdaAlphaPhi(double _lambda, double _alpha, double _phi) -> kvector_t\n"
 		"kvector_t vecOfLambdaAlphaPhi(double _lambda, double _alpha, double _phi)\n"
@@ -33747,7 +33579,9 @@ static PyMethodDef SwigMethods[] = {
 	 { "kvector_t___isub__", _wrap_kvector_t___isub__, METH_VARARGS, "kvector_t___isub__(kvector_t self, kvector_t v) -> kvector_t"},
 	 { "kvector_t_conj", _wrap_kvector_t_conj, METH_O, "\n"
 		"kvector_t_conj(kvector_t self) -> kvector_t\n"
-		"BasicVector3D< complex_t > BasicVector3D< complex_t >::conj() const\n"
+		"BasicVector3D<T> BasicVector3D< T >::conj() const\n"
+		"\n"
+		"Returns complex conjugate vector. \n"
 		"\n"
 		""},
 	 { "kvector_t_mag2", _wrap_kvector_t_mag2, METH_O, "\n"
@@ -33808,19 +33642,23 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { "kvector_t_unit", _wrap_kvector_t_unit, METH_O, "\n"
 		"kvector_t_unit(kvector_t self) -> kvector_t\n"
-		"BasicVector3D< complex_t > BasicVector3D< complex_t >::unit() const\n"
+		"BasicVector3D<T> BasicVector3D< T >::unit() const\n"
+		"\n"
+		"Returns unit vector in direction of this. Throws for null vector. \n"
 		"\n"
 		""},
 	 { "kvector_t_complex", _wrap_kvector_t_complex, METH_O, "\n"
 		"kvector_t_complex(kvector_t self) -> cvector_t\n"
-		"BasicVector3D<std::complex<double> > BasicVector3D< T >::complex() const\n"
+		"BasicVector3D<complex_t> BasicVector3D< T >::complex() const\n"
 		"\n"
 		"Returns this, trivially converted to complex type. \n"
 		"\n"
 		""},
 	 { "kvector_t_real", _wrap_kvector_t_real, METH_O, "\n"
 		"kvector_t_real(kvector_t self) -> kvector_t\n"
-		"BasicVector3D< double > BasicVector3D< complex_t >::real() const\n"
+		"BasicVector3D<double> BasicVector3D< T >::real() const\n"
+		"\n"
+		"Returns real parts. \n"
 		"\n"
 		""},
 	 { "kvector_t_angle", _wrap_kvector_t_angle, METH_VARARGS, "\n"
@@ -33956,7 +33794,9 @@ static PyMethodDef SwigMethods[] = {
 	 { "cvector_t___isub__", _wrap_cvector_t___isub__, METH_VARARGS, "cvector_t___isub__(cvector_t self, cvector_t v) -> cvector_t"},
 	 { "cvector_t_conj", _wrap_cvector_t_conj, METH_O, "\n"
 		"cvector_t_conj(cvector_t self) -> cvector_t\n"
-		"BasicVector3D< complex_t > BasicVector3D< complex_t >::conj() const\n"
+		"BasicVector3D<T> BasicVector3D< T >::conj() const\n"
+		"\n"
+		"Returns complex conjugate vector. \n"
 		"\n"
 		""},
 	 { "cvector_t_mag2", _wrap_cvector_t_mag2, METH_O, "\n"
@@ -33989,12 +33829,16 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { "cvector_t_unit", _wrap_cvector_t_unit, METH_O, "\n"
 		"cvector_t_unit(cvector_t self) -> cvector_t\n"
-		"BasicVector3D< complex_t > BasicVector3D< complex_t >::unit() const\n"
+		"BasicVector3D<T> BasicVector3D< T >::unit() const\n"
+		"\n"
+		"Returns unit vector in direction of this. Throws for null vector. \n"
 		"\n"
 		""},
 	 { "cvector_t_real", _wrap_cvector_t_real, METH_O, "\n"
 		"cvector_t_real(cvector_t self) -> kvector_t\n"
-		"BasicVector3D< double > BasicVector3D< complex_t >::real() const\n"
+		"BasicVector3D<double> BasicVector3D< T >::real() const\n"
+		"\n"
+		"Returns real parts. \n"
 		"\n"
 		""},
 	 { "cvector_t_project", _wrap_cvector_t_project, METH_VARARGS, "\n"
@@ -34099,7 +33943,7 @@ static void *_p_FixedBinAxisTo_p_IAxis(void *x, int *SWIGUNUSEDPARM(newmemory))
 }
 static swig_type_info _swigt__p_BasicVector3DT_double_t = {"_p_BasicVector3DT_double_t", "std::vector< BasicVector3D< double > >::value_type *|kvector_t *|BasicVector3D< double > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_BasicVector3DT_int_t = {"_p_BasicVector3DT_int_t", "ivector_t *|BasicVector3D< int > *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_BasicVector3DT_std__complexT_double_t_t = {"_p_BasicVector3DT_std__complexT_double_t_t", "BasicVector3D< std::complex< double > > *|std::vector< BasicVector3D< std::complex< double > > >::value_type *|cvector_t *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_BasicVector3DT_std__complexT_double_t_t = {"_p_BasicVector3DT_std__complexT_double_t_t", "BasicVector3D< std::complex< double > > *|std::vector< BasicVector3D< std::complex< double > > >::value_type *|cvector_t *|BasicVector3D< complex_t > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Bin1D = {"_p_Bin1D", "Bin1D *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Bin1DCVector = {"_p_Bin1DCVector", "Bin1DCVector *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Bin1DKVector = {"_p_Bin1DKVector", "Bin1DKVector *", 0, 0, (void*)0, 0};
@@ -35102,17 +34946,9 @@ SWIG_init(void) {
   SWIG_addvarlink(globals, "angstrom", Swig_var_angstrom_get, Swig_var_angstrom_set);
   SWIG_addvarlink(globals, "micrometer", Swig_var_micrometer_get, Swig_var_micrometer_set);
   SWIG_addvarlink(globals, "millimeter", Swig_var_millimeter_get, Swig_var_millimeter_set);
-  SWIG_addvarlink(globals, "meter", Swig_var_meter_get, Swig_var_meter_set);
   SWIG_addvarlink(globals, "nm", Swig_var_nm_get, Swig_var_nm_set);
   SWIG_addvarlink(globals, "nm2", Swig_var_nm2_get, Swig_var_nm2_set);
-  SWIG_addvarlink(globals, "barn", Swig_var_barn_get, Swig_var_barn_set);
-  SWIG_addvarlink(globals, "radian", Swig_var_radian_get, Swig_var_radian_set);
-  SWIG_addvarlink(globals, "milliradian", Swig_var_milliradian_get, Swig_var_milliradian_set);
-  SWIG_addvarlink(globals, "degree", Swig_var_degree_get, Swig_var_degree_set);
-  SWIG_addvarlink(globals, "steradian", Swig_var_steradian_get, Swig_var_steradian_set);
   SWIG_addvarlink(globals, "rad", Swig_var_rad_get, Swig_var_rad_set);
-  SWIG_addvarlink(globals, "mrad", Swig_var_mrad_get, Swig_var_mrad_set);
-  SWIG_addvarlink(globals, "sr", Swig_var_sr_get, Swig_var_sr_set);
   SWIG_addvarlink(globals, "deg", Swig_var_deg_get, Swig_var_deg_set);
   SWIG_addvarlink(globals, "tesla", Swig_var_tesla_get, Swig_var_tesla_set);
   SWIG_addvarlink(globals, "gauss", Swig_var_gauss_get, Swig_var_gauss_set);
diff --git a/auto/Wrap/libBornAgainCore.py b/auto/Wrap/libBornAgainCore.py
index b29772e589413c6221be05902c337aa03a72b949..cacedc4985780e5f146d82797e456e65d412ee2b 100644
--- a/auto/Wrap/libBornAgainCore.py
+++ b/auto/Wrap/libBornAgainCore.py
@@ -2921,7 +2921,7 @@ class FitObjective(object):
 
     def setChiSquaredModule(self, module):
         r"""
-        setChiSquaredModule(FitObjective self, IChiSquaredModule const & module)
+        setChiSquaredModule(FitObjective self, IChiSquaredModule module)
         void FitObjective::setChiSquaredModule(const IChiSquaredModule &module)
 
         """
@@ -3108,89 +3108,6 @@ def GetName():
 def GetVersionNumber():
     r"""GetVersionNumber() -> std::string"""
     return _libBornAgainCore.GetVersionNumber()
-class IObserver(object):
-    r"""
-
-
-    Observer interface from Observer pattern.
-
-    C++ includes: IObserver.h
-
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined - class is abstract")
-    __repr__ = _swig_repr
-    __swig_destroy__ = _libBornAgainCore.delete_IObserver
-
-    def notify(self, subject):
-        r"""
-        notify(IObserver self, IObservable subject)
-        virtual void IObserver::notify(IObservable *subject)=0
-
-        method which is used by observable subject to notify change in status 
-
-        """
-        return _libBornAgainCore.IObserver_notify(self, subject)
-
-# Register IObserver in _libBornAgainCore:
-_libBornAgainCore.IObserver_swigregister(IObserver)
-cvar = _libBornAgainCore.cvar
-major_version_number = cvar.major_version_number
-minor_version_number = cvar.minor_version_number
-patch_version_number = cvar.patch_version_number
-
-class IObservable(object):
-    r"""
-
-
-    Observable interface from Observer pattern
-
-    C++ includes: IObserver.h
-
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-    __swig_destroy__ = _libBornAgainCore.delete_IObservable
-
-    def attachObserver(self, obj):
-        r"""
-        attachObserver(IObservable self, IObservable::observer_t obj)
-        void IObservable::attachObserver(observer_t obj)
-
-        attach observer to the list of observers 
-
-        """
-        return _libBornAgainCore.IObservable_attachObserver(self, obj)
-
-    def notifyObservers(self):
-        r"""
-        notifyObservers(IObservable self)
-        void IObservable::notifyObservers()
-
-        notify observers about change in status 
-
-        """
-        return _libBornAgainCore.IObservable_notifyObservers(self)
-
-    def __init__(self):
-        r"""
-        __init__(IObservable self) -> IObservable
-
-
-        Observable interface from Observer pattern
-
-        C++ includes: IObserver.h
-
-        """
-        _libBornAgainCore.IObservable_swiginit(self, _libBornAgainCore.new_IObservable())
-
-# Register IObservable in _libBornAgainCore:
-_libBornAgainCore.IObservable_swigregister(IObservable)
-
 class IterationInfo(object):
     r"""
 
@@ -3259,6 +3176,10 @@ class IterationInfo(object):
 
 # Register IterationInfo in _libBornAgainCore:
 _libBornAgainCore.IterationInfo_swigregister(IterationInfo)
+cvar = _libBornAgainCore.cvar
+major_version_number = cvar.major_version_number
+minor_version_number = cvar.minor_version_number
+patch_version_number = cvar.patch_version_number
 
 class PyBuilderCallback(object):
     r"""
@@ -3534,7 +3455,7 @@ class ISimulation(libBornAgainBase.ICloneable, libBornAgainParam.INode):
     r"""
 
 
-    Abstract base class of OffSpecularSimulation,  GISASSimulation and  SpecularSimulation. Holds the common infrastructure to run a simulation: multithreading, batch processing, weighting over parameter distributions, ...
+    Abstract base class of  OffSpecularSimulation,  GISASSimulation and  SpecularSimulation. Holds the common infrastructure to run a simulation: multithreading, batch processing, weighting over parameter distributions, ...
 
     C++ includes: ISimulation.h
 
@@ -3622,24 +3543,6 @@ class ISimulation(libBornAgainBase.ICloneable, libBornAgainParam.INode):
         """
         return _libBornAgainCore.ISimulation_detector(self, *args)
 
-    def setBeamIntensity(self, intensity):
-        r"""
-        setBeamIntensity(ISimulation self, double intensity)
-        void ISimulation::setBeamIntensity(double intensity)
-
-        """
-        return _libBornAgainCore.ISimulation_setBeamIntensity(self, intensity)
-
-    def setBeamPolarization(self, bloch_vector):
-        r"""
-        setBeamPolarization(ISimulation self, kvector_t bloch_vector)
-        void ISimulation::setBeamPolarization(const kvector_t bloch_vector)
-
-        Sets the beam polarization according to the given Bloch vector. 
-
-        """
-        return _libBornAgainCore.ISimulation_setBeamPolarization(self, bloch_vector)
-
     def setDetectorResolutionFunction(self, resolution_function):
         r"""
         setDetectorResolutionFunction(ISimulation self, IResolutionFunction2D const & resolution_function)
@@ -3802,7 +3705,7 @@ class ISimulation2D(ISimulation):
     r"""
 
 
-    Abstract base class of OffSpecularSimulation and  GISASSimulation. Holds the common implementations for simulations with a 2D detector
+    Abstract base class of  OffSpecularSimulation and  GISASSimulation. Holds the common implementations for simulations with a 2D detector
 
     C++ includes: ISimulation2D.h
 
@@ -4198,13 +4101,13 @@ class SpecularSimulation(ISimulation):
 # Register SpecularSimulation in _libBornAgainCore:
 _libBornAgainCore.SpecularSimulation_swigregister(SpecularSimulation)
 
-class OffSpecSimulation(ISimulation2D):
+class OffSpecularSimulation(ISimulation2D):
     r"""
 
 
     Main class to run an off-specular simulation.
 
-    C++ includes: OffSpecSimulation.h
+    C++ includes: OffSpecularSimulation.h
 
     """
 
@@ -4213,82 +4116,82 @@ class OffSpecSimulation(ISimulation2D):
 
     def __init__(self, *args):
         r"""
-        __init__(OffSpecSimulation self, Beam const & beam, MultiLayer const & sample, IDetector const & detector) -> OffSpecSimulation
-        __init__(OffSpecSimulation self) -> OffSpecSimulation
-        OffSpecSimulation::OffSpecSimulation()
+        __init__(OffSpecularSimulation self, Beam const & beam, MultiLayer const & sample, IDetector const & detector) -> OffSpecularSimulation
+        __init__(OffSpecularSimulation self) -> OffSpecularSimulation
+        OffSpecularSimulation::OffSpecularSimulation()
 
         """
-        _libBornAgainCore.OffSpecSimulation_swiginit(self, _libBornAgainCore.new_OffSpecSimulation(*args))
-    __swig_destroy__ = _libBornAgainCore.delete_OffSpecSimulation
+        _libBornAgainCore.OffSpecularSimulation_swiginit(self, _libBornAgainCore.new_OffSpecularSimulation(*args))
+    __swig_destroy__ = _libBornAgainCore.delete_OffSpecularSimulation
 
     def clone(self):
         r"""
-        clone(OffSpecSimulation self) -> OffSpecSimulation
-        OffSpecSimulation* OffSpecSimulation::clone() const override
+        clone(OffSpecularSimulation self) -> OffSpecularSimulation
+        OffSpecularSimulation* OffSpecularSimulation::clone() const override
 
         """
-        return _libBornAgainCore.OffSpecSimulation_clone(self)
+        return _libBornAgainCore.OffSpecularSimulation_clone(self)
 
     def accept(self, visitor):
         r"""
-        accept(OffSpecSimulation self, INodeVisitor * visitor)
-        void OffSpecSimulation::accept(INodeVisitor *visitor) const override
+        accept(OffSpecularSimulation self, INodeVisitor * visitor)
+        void OffSpecularSimulation::accept(INodeVisitor *visitor) const override
 
         """
-        return _libBornAgainCore.OffSpecSimulation_accept(self, visitor)
+        return _libBornAgainCore.OffSpecularSimulation_accept(self, visitor)
 
     def prepareSimulation(self):
         r"""
-        prepareSimulation(OffSpecSimulation self)
-        void OffSpecSimulation::prepareSimulation() override
+        prepareSimulation(OffSpecularSimulation self)
+        void OffSpecularSimulation::prepareSimulation() override
 
         Put into a clean state for running a simulation. 
 
         """
-        return _libBornAgainCore.OffSpecSimulation_prepareSimulation(self)
+        return _libBornAgainCore.OffSpecularSimulation_prepareSimulation(self)
 
     def result(self):
         r"""
-        result(OffSpecSimulation self) -> SimulationResult
-        SimulationResult OffSpecSimulation::result() const override
+        result(OffSpecularSimulation self) -> SimulationResult
+        SimulationResult OffSpecularSimulation::result() const override
 
         Returns the results of the simulation in a format that supports unit conversion and export to numpy arrays 
 
         """
-        return _libBornAgainCore.OffSpecSimulation_result(self)
+        return _libBornAgainCore.OffSpecularSimulation_result(self)
 
     def setBeamParameters(self, wavelength, alpha_axis, phi_i):
         r"""
-        setBeamParameters(OffSpecSimulation self, double wavelength, IAxis alpha_axis, double phi_i)
-        void OffSpecSimulation::setBeamParameters(double wavelength, const IAxis &alpha_axis, double phi_i)
+        setBeamParameters(OffSpecularSimulation self, double wavelength, IAxis alpha_axis, double phi_i)
+        void OffSpecularSimulation::setBeamParameters(double wavelength, const IAxis &alpha_axis, double phi_i)
 
         Sets beam parameters from here (forwarded to Instrument) 
 
         """
-        return _libBornAgainCore.OffSpecSimulation_setBeamParameters(self, wavelength, alpha_axis, phi_i)
+        return _libBornAgainCore.OffSpecularSimulation_setBeamParameters(self, wavelength, alpha_axis, phi_i)
 
     def beamAxis(self):
         r"""
-        beamAxis(OffSpecSimulation self) -> IAxis
-        const IAxis * OffSpecSimulation::beamAxis() const
+        beamAxis(OffSpecularSimulation self) -> IAxis
+        const IAxis * OffSpecularSimulation::beamAxis() const
 
         Returns axis of the beam. 
 
         """
-        return _libBornAgainCore.OffSpecSimulation_beamAxis(self)
+        return _libBornAgainCore.OffSpecularSimulation_beamAxis(self)
 
     def intensityMapSize(self):
         r"""
-        intensityMapSize(OffSpecSimulation self) -> size_t
-        size_t OffSpecSimulation::intensityMapSize() const override
+        intensityMapSize(OffSpecularSimulation self) -> size_t
+        size_t OffSpecularSimulation::intensityMapSize() const override
 
         Returns the total number of the intensity values in the simulation result. 
 
         """
-        return _libBornAgainCore.OffSpecSimulation_intensityMapSize(self)
+        return _libBornAgainCore.OffSpecularSimulation_intensityMapSize(self)
 
-# Register OffSpecSimulation in _libBornAgainCore:
-_libBornAgainCore.OffSpecSimulation_swigregister(OffSpecSimulation)
+# Register OffSpecularSimulation in _libBornAgainCore:
+_libBornAgainCore.OffSpecularSimulation_swigregister(OffSpecularSimulation)
 
 class IBackground(libBornAgainBase.ICloneable, libBornAgainParam.INode):
     r"""
@@ -4449,6 +4352,376 @@ def generateSimulationCode(simulation):
 
     """
     return _libBornAgainCore.generateSimulationCode(simulation)
+class IIntensityFunction(object):
+    r"""
+
+
+    Interface for applying arbitrary function to the measured intensity.
+
+    C++ includes: IIntensityFunction.h
+
+    """
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+    __repr__ = _swig_repr
+    __swig_destroy__ = _libBornAgainCore.delete_IIntensityFunction
+
+    def clone(self):
+        r"""
+        clone(IIntensityFunction self) -> IIntensityFunction
+        virtual IIntensityFunction* IIntensityFunction::clone() const =0
+
+        """
+        return _libBornAgainCore.IIntensityFunction_clone(self)
+
+    def evaluate(self, value):
+        r"""
+        evaluate(IIntensityFunction self, double value) -> double
+        virtual double IIntensityFunction::evaluate(double value) const =0
+
+        """
+        return _libBornAgainCore.IIntensityFunction_evaluate(self, value)
+
+# Register IIntensityFunction in _libBornAgainCore:
+_libBornAgainCore.IIntensityFunction_swigregister(IIntensityFunction)
+
+class IntensityFunctionLog(IIntensityFunction):
+    r"""
+
+
+    Algorithm for applying log function to the measured intensity.
+
+    C++ includes: IIntensityFunction.h
+
+    """
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def clone(self):
+        r"""
+        clone(IntensityFunctionLog self) -> IntensityFunctionLog
+        IntensityFunctionLog * IntensityFunctionLog::clone() const
+
+        """
+        return _libBornAgainCore.IntensityFunctionLog_clone(self)
+
+    def evaluate(self, value):
+        r"""
+        evaluate(IntensityFunctionLog self, double value) -> double
+        double IntensityFunctionLog::evaluate(double value) const
+
+        """
+        return _libBornAgainCore.IntensityFunctionLog_evaluate(self, value)
+
+    def __init__(self):
+        r"""
+        __init__(IntensityFunctionLog self) -> IntensityFunctionLog
+
+
+        Algorithm for applying log function to the measured intensity.
+
+        C++ includes: IIntensityFunction.h
+
+        """
+        _libBornAgainCore.IntensityFunctionLog_swiginit(self, _libBornAgainCore.new_IntensityFunctionLog())
+    __swig_destroy__ = _libBornAgainCore.delete_IntensityFunctionLog
+
+# Register IntensityFunctionLog in _libBornAgainCore:
+_libBornAgainCore.IntensityFunctionLog_swigregister(IntensityFunctionLog)
+
+class IntensityFunctionSqrt(IIntensityFunction):
+    r"""
+
+
+    Algorithm for applying sqrt function to the measured intensity.
+
+    C++ includes: IIntensityFunction.h
+
+    """
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def clone(self):
+        r"""
+        clone(IntensityFunctionSqrt self) -> IntensityFunctionSqrt
+        IntensityFunctionSqrt * IntensityFunctionSqrt::clone() const
+
+        """
+        return _libBornAgainCore.IntensityFunctionSqrt_clone(self)
+
+    def evaluate(self, value):
+        r"""
+        evaluate(IntensityFunctionSqrt self, double value) -> double
+        double IntensityFunctionSqrt::evaluate(double value) const
+
+        """
+        return _libBornAgainCore.IntensityFunctionSqrt_evaluate(self, value)
+
+    def __init__(self):
+        r"""
+        __init__(IntensityFunctionSqrt self) -> IntensityFunctionSqrt
+
+
+        Algorithm for applying sqrt function to the measured intensity.
+
+        C++ includes: IIntensityFunction.h
+
+        """
+        _libBornAgainCore.IntensityFunctionSqrt_swiginit(self, _libBornAgainCore.new_IntensityFunctionSqrt())
+    __swig_destroy__ = _libBornAgainCore.delete_IntensityFunctionSqrt
+
+# Register IntensityFunctionSqrt in _libBornAgainCore:
+_libBornAgainCore.IntensityFunctionSqrt_swigregister(IntensityFunctionSqrt)
+
+class IChiSquaredModule(libBornAgainBase.ICloneable):
+    r"""
+
+
+    Interface residual calculations.
+
+    C++ includes: IChiSquaredModule.h
+
+    """
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+    __repr__ = _swig_repr
+    __swig_destroy__ = _libBornAgainCore.delete_IChiSquaredModule
+
+    def clone(self):
+        r"""
+        clone(IChiSquaredModule self) -> IChiSquaredModule
+        virtual IChiSquaredModule* IChiSquaredModule::clone() const =0
+
+        clone method 
+
+        """
+        return _libBornAgainCore.IChiSquaredModule_clone(self)
+
+    def varianceFunction(self):
+        r"""
+        varianceFunction(IChiSquaredModule self) -> IVarianceFunction
+        const IVarianceFunction * IChiSquaredModule::varianceFunction() const
+
+        Returns squared function. 
+
+        """
+        return _libBornAgainCore.IChiSquaredModule_varianceFunction(self)
+
+    def setVarianceFunction(self, variance_function):
+        r"""
+        setVarianceFunction(IChiSquaredModule self, IVarianceFunction variance_function)
+        void IChiSquaredModule::setVarianceFunction(const IVarianceFunction &variance_function)
+
+        Sets squared function. 
+
+        """
+        return _libBornAgainCore.IChiSquaredModule_setVarianceFunction(self, variance_function)
+
+    def getIntensityFunction(self):
+        r"""
+        getIntensityFunction(IChiSquaredModule self) -> IIntensityFunction
+        const IIntensityFunction * IChiSquaredModule::getIntensityFunction() const
+
+        Returns data rescaler. 
+
+        """
+        return _libBornAgainCore.IChiSquaredModule_getIntensityFunction(self)
+
+    def setIntensityFunction(self, intensity_function):
+        r"""
+        setIntensityFunction(IChiSquaredModule self, IIntensityFunction intensity_function)
+        void IChiSquaredModule::setIntensityFunction(const IIntensityFunction &intensity_function)
+
+        Sets data rescaler. 
+
+        """
+        return _libBornAgainCore.IChiSquaredModule_setIntensityFunction(self, intensity_function)
+
+    def residual(self, a, b, weight):
+        r"""
+        residual(IChiSquaredModule self, double a, double b, double weight) -> double
+        virtual double IChiSquaredModule::residual(double a, double b, double weight)=0
+
+        """
+        return _libBornAgainCore.IChiSquaredModule_residual(self, a, b, weight)
+
+# Register IChiSquaredModule in _libBornAgainCore:
+_libBornAgainCore.IChiSquaredModule_swigregister(IChiSquaredModule)
+
+class ChiSquaredModule(IChiSquaredModule):
+    r"""
+
+
+    Calculation of chi2 between two data sets.
+
+    C++ includes: ChiSquaredModule.h
+
+    """
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, *args):
+        r"""
+        __init__(ChiSquaredModule self) -> ChiSquaredModule
+        __init__(ChiSquaredModule self, ChiSquaredModule other) -> ChiSquaredModule
+        ChiSquaredModule::ChiSquaredModule(const ChiSquaredModule &other)
+
+        """
+        _libBornAgainCore.ChiSquaredModule_swiginit(self, _libBornAgainCore.new_ChiSquaredModule(*args))
+    __swig_destroy__ = _libBornAgainCore.delete_ChiSquaredModule
+
+    def clone(self):
+        r"""
+        clone(ChiSquaredModule self) -> ChiSquaredModule
+        virtual ChiSquaredModule* ChiSquaredModule::clone() const
+
+        clone method 
+
+        """
+        return _libBornAgainCore.ChiSquaredModule_clone(self)
+
+    def residual(self, a, b, weight):
+        r"""
+        residual(ChiSquaredModule self, double a, double b, double weight) -> double
+        double ChiSquaredModule::residual(double a, double b, double weight)
+
+        """
+        return _libBornAgainCore.ChiSquaredModule_residual(self, a, b, weight)
+
+# Register ChiSquaredModule in _libBornAgainCore:
+_libBornAgainCore.ChiSquaredModule_swigregister(ChiSquaredModule)
+
+class IVarianceFunction(object):
+    r"""
+
+
+    Variance function interface.
+
+    C++ includes: VarianceFunctions.h
+
+    """
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined - class is abstract")
+    __repr__ = _swig_repr
+    __swig_destroy__ = _libBornAgainCore.delete_IVarianceFunction
+
+    def clone(self):
+        r"""
+        clone(IVarianceFunction self) -> IVarianceFunction
+        virtual IVarianceFunction* IVarianceFunction::clone() const =0
+
+        """
+        return _libBornAgainCore.IVarianceFunction_clone(self)
+
+    def variance(self, real_value, simulated_value):
+        r"""
+        variance(IVarianceFunction self, double real_value, double simulated_value) -> double
+        virtual double IVarianceFunction::variance(double real_value, double simulated_value) const =0
+
+        """
+        return _libBornAgainCore.IVarianceFunction_variance(self, real_value, simulated_value)
+
+# Register IVarianceFunction in _libBornAgainCore:
+_libBornAgainCore.IVarianceFunction_swigregister(IVarianceFunction)
+
+class VarianceConstantFunction(IVarianceFunction):
+    r"""
+
+
+    Returns 1.0 as variance value
+
+    C++ includes: VarianceFunctions.h
+
+    """
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def clone(self):
+        r"""
+        clone(VarianceConstantFunction self) -> VarianceConstantFunction
+        VarianceConstantFunction * VarianceConstantFunction::clone() const override
+
+        """
+        return _libBornAgainCore.VarianceConstantFunction_clone(self)
+
+    def variance(self, arg2, arg3):
+        r"""
+        variance(VarianceConstantFunction self, double arg2, double arg3) -> double
+        double VarianceConstantFunction::variance(double, double) const override
+
+        """
+        return _libBornAgainCore.VarianceConstantFunction_variance(self, arg2, arg3)
+
+    def __init__(self):
+        r"""
+        __init__(VarianceConstantFunction self) -> VarianceConstantFunction
+
+
+        Returns 1.0 as variance value
+
+        C++ includes: VarianceFunctions.h
+
+        """
+        _libBornAgainCore.VarianceConstantFunction_swiginit(self, _libBornAgainCore.new_VarianceConstantFunction())
+    __swig_destroy__ = _libBornAgainCore.delete_VarianceConstantFunction
+
+# Register VarianceConstantFunction in _libBornAgainCore:
+_libBornAgainCore.VarianceConstantFunction_swigregister(VarianceConstantFunction)
+
+class VarianceSimFunction(IVarianceFunction):
+    r"""
+
+
+    Returns max(sim, epsilon)
+
+    C++ includes: VarianceFunctions.h
+
+    """
+
+    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+    __repr__ = _swig_repr
+
+    def __init__(self, epsilon=1.0):
+        r"""
+        __init__(VarianceSimFunction self, double epsilon=1.0) -> VarianceSimFunction
+        VarianceSimFunction::VarianceSimFunction(double epsilon=1.0)
+
+        """
+        _libBornAgainCore.VarianceSimFunction_swiginit(self, _libBornAgainCore.new_VarianceSimFunction(epsilon))
+
+    def clone(self):
+        r"""
+        clone(VarianceSimFunction self) -> VarianceSimFunction
+        VarianceSimFunction * VarianceSimFunction::clone() const override
+
+        """
+        return _libBornAgainCore.VarianceSimFunction_clone(self)
+
+    def variance(self, exp, sim):
+        r"""
+        variance(VarianceSimFunction self, double exp, double sim) -> double
+        double VarianceSimFunction::variance(double exp, double sim) const override
+
+        """
+        return _libBornAgainCore.VarianceSimFunction_variance(self, exp, sim)
+    __swig_destroy__ = _libBornAgainCore.delete_VarianceSimFunction
+
+# Register VarianceSimFunction in _libBornAgainCore:
+_libBornAgainCore.VarianceSimFunction_swigregister(VarianceSimFunction)
+
 
 class SimulationBuilderWrapper(PyBuilderCallback):
     def __init__(self, f):
diff --git a/auto/Wrap/libBornAgainCore_wrap.cpp b/auto/Wrap/libBornAgainCore_wrap.cpp
index 2ac6c2e76d9156c9890c4370a38b047d02a780f9..28c1785d361129af03297554de70f4c1a11d15ca 100644
--- a/auto/Wrap/libBornAgainCore_wrap.cpp
+++ b/auto/Wrap/libBornAgainCore_wrap.cpp
@@ -3103,26 +3103,26 @@ namespace Swig {
 #define SWIGTYPE_p_BasicVector3DT_int_t swig_types[3]
 #define SWIGTYPE_p_BasicVector3DT_std__complexT_double_t_t swig_types[4]
 #define SWIGTYPE_p_Beam swig_types[5]
-#define SWIGTYPE_p_ConstantBackground swig_types[6]
-#define SWIGTYPE_p_DepthProbeSimulation swig_types[7]
-#define SWIGTYPE_p_DistributionHandler swig_types[8]
-#define SWIGTYPE_p_FitObjective swig_types[9]
-#define SWIGTYPE_p_GISASSimulation swig_types[10]
-#define SWIGTYPE_p_IAxis swig_types[11]
-#define SWIGTYPE_p_IBackground swig_types[12]
-#define SWIGTYPE_p_IBornFF swig_types[13]
-#define SWIGTYPE_p_IChiSquaredModule swig_types[14]
-#define SWIGTYPE_p_ICloneable swig_types[15]
-#define SWIGTYPE_p_IComponent swig_types[16]
-#define SWIGTYPE_p_IDetector swig_types[17]
-#define SWIGTYPE_p_IDetector2D swig_types[18]
-#define SWIGTYPE_p_IDistribution1D swig_types[19]
-#define SWIGTYPE_p_IFootprintFactor swig_types[20]
-#define SWIGTYPE_p_IFormFactor swig_types[21]
-#define SWIGTYPE_p_INode swig_types[22]
-#define SWIGTYPE_p_INodeVisitor swig_types[23]
-#define SWIGTYPE_p_IObservable swig_types[24]
-#define SWIGTYPE_p_IObserver swig_types[25]
+#define SWIGTYPE_p_ChiSquaredModule swig_types[6]
+#define SWIGTYPE_p_ConstantBackground swig_types[7]
+#define SWIGTYPE_p_DepthProbeSimulation swig_types[8]
+#define SWIGTYPE_p_DistributionHandler swig_types[9]
+#define SWIGTYPE_p_FitObjective swig_types[10]
+#define SWIGTYPE_p_GISASSimulation swig_types[11]
+#define SWIGTYPE_p_IAxis swig_types[12]
+#define SWIGTYPE_p_IBackground swig_types[13]
+#define SWIGTYPE_p_IBornFF swig_types[14]
+#define SWIGTYPE_p_IChiSquaredModule swig_types[15]
+#define SWIGTYPE_p_ICloneable swig_types[16]
+#define SWIGTYPE_p_IComponent swig_types[17]
+#define SWIGTYPE_p_IDetector swig_types[18]
+#define SWIGTYPE_p_IDetector2D swig_types[19]
+#define SWIGTYPE_p_IDistribution1D swig_types[20]
+#define SWIGTYPE_p_IFootprintFactor swig_types[21]
+#define SWIGTYPE_p_IFormFactor swig_types[22]
+#define SWIGTYPE_p_IIntensityFunction swig_types[23]
+#define SWIGTYPE_p_INode swig_types[24]
+#define SWIGTYPE_p_INodeVisitor swig_types[25]
 #define SWIGTYPE_p_IParametricComponent swig_types[26]
 #define SWIGTYPE_p_IRangedDistribution swig_types[27]
 #define SWIGTYPE_p_IResolutionFunction2D swig_types[28]
@@ -3131,81 +3131,84 @@ namespace Swig {
 #define SWIGTYPE_p_ISimulation swig_types[31]
 #define SWIGTYPE_p_ISimulation2D swig_types[32]
 #define SWIGTYPE_p_ISpecularScan swig_types[33]
-#define SWIGTYPE_p_Instrument swig_types[34]
-#define SWIGTYPE_p_IterationInfo swig_types[35]
-#define SWIGTYPE_p_MultiLayer swig_types[36]
-#define SWIGTYPE_p_OffSpecSimulation swig_types[37]
-#define SWIGTYPE_p_OutputDataT_double_t swig_types[38]
-#define SWIGTYPE_p_ParameterDistribution swig_types[39]
-#define SWIGTYPE_p_ParameterPool swig_types[40]
-#define SWIGTYPE_p_PoissonNoiseBackground swig_types[41]
-#define SWIGTYPE_p_ProgressHandler__Callback_t swig_types[42]
-#define SWIGTYPE_p_PyBuilderCallback swig_types[43]
-#define SWIGTYPE_p_PyObserverCallback swig_types[44]
-#define SWIGTYPE_p_QSpecScan swig_types[45]
-#define SWIGTYPE_p_RealLimits swig_types[46]
-#define SWIGTYPE_p_ScanResolution swig_types[47]
-#define SWIGTYPE_p_SimulationOptions swig_types[48]
-#define SWIGTYPE_p_SimulationResult swig_types[49]
-#define SWIGTYPE_p_SpecularSimulation swig_types[50]
-#define SWIGTYPE_p_allocator_type swig_types[51]
-#define SWIGTYPE_p_char swig_types[52]
-#define SWIGTYPE_p_difference_type swig_types[53]
-#define SWIGTYPE_p_first_type swig_types[54]
-#define SWIGTYPE_p_int swig_types[55]
-#define SWIGTYPE_p_key_type swig_types[56]
-#define SWIGTYPE_p_long_long swig_types[57]
-#define SWIGTYPE_p_mapped_type swig_types[58]
-#define SWIGTYPE_p_mumufit__MinimizerResult swig_types[59]
-#define SWIGTYPE_p_mumufit__Parameters swig_types[60]
-#define SWIGTYPE_p_observer_t swig_types[61]
-#define SWIGTYPE_p_p_PyObject swig_types[62]
-#define SWIGTYPE_p_second_type swig_types[63]
-#define SWIGTYPE_p_short swig_types[64]
-#define SWIGTYPE_p_signed_char swig_types[65]
-#define SWIGTYPE_p_size_type swig_types[66]
-#define SWIGTYPE_p_std__allocatorT_AxisInfo_t swig_types[67]
-#define SWIGTYPE_p_std__allocatorT_BasicVector3DT_double_t_t swig_types[68]
-#define SWIGTYPE_p_std__allocatorT_BasicVector3DT_std__complexT_double_t_t_t swig_types[69]
-#define SWIGTYPE_p_std__allocatorT_INode_const_p_t swig_types[70]
-#define SWIGTYPE_p_std__allocatorT_INode_p_t swig_types[71]
-#define SWIGTYPE_p_std__allocatorT_double_t swig_types[72]
-#define SWIGTYPE_p_std__allocatorT_int_t swig_types[73]
-#define SWIGTYPE_p_std__allocatorT_std__complexT_double_t_t swig_types[74]
-#define SWIGTYPE_p_std__allocatorT_std__pairT_double_double_t_t swig_types[75]
-#define SWIGTYPE_p_std__allocatorT_std__pairT_std__string_const_double_t_t swig_types[76]
-#define SWIGTYPE_p_std__allocatorT_std__string_t swig_types[77]
-#define SWIGTYPE_p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t swig_types[78]
-#define SWIGTYPE_p_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t swig_types[79]
-#define SWIGTYPE_p_std__allocatorT_unsigned_long_t swig_types[80]
-#define SWIGTYPE_p_std__complexT_double_t swig_types[81]
-#define SWIGTYPE_p_std__invalid_argument swig_types[82]
-#define SWIGTYPE_p_std__lessT_std__string_t swig_types[83]
-#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[84]
-#define SWIGTYPE_p_std__pairT_double_double_t swig_types[85]
-#define SWIGTYPE_p_std__shared_ptrT_IObserver_t swig_types[86]
-#define SWIGTYPE_p_std__shared_ptrT_ISampleBuilder_t swig_types[87]
-#define SWIGTYPE_p_std__vectorT_AxisInfo_std__allocatorT_AxisInfo_t_t swig_types[88]
-#define SWIGTYPE_p_std__vectorT_BasicVector3DT_double_t_std__allocatorT_BasicVector3DT_double_t_t_t swig_types[89]
-#define SWIGTYPE_p_std__vectorT_BasicVector3DT_std__complexT_double_t_t_std__allocatorT_BasicVector3DT_std__complexT_double_t_t_t_t swig_types[90]
-#define SWIGTYPE_p_std__vectorT_INode_const_p_std__allocatorT_INode_const_p_t_t swig_types[91]
-#define SWIGTYPE_p_std__vectorT_INode_p_std__allocatorT_INode_p_t_t swig_types[92]
-#define SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t swig_types[93]
-#define SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t swig_types[94]
-#define SWIGTYPE_p_std__vectorT_std__complexT_double_t_std__allocatorT_std__complexT_double_t_t_t swig_types[95]
-#define SWIGTYPE_p_std__vectorT_std__pairT_double_double_t_std__allocatorT_std__pairT_double_double_t_t_t swig_types[96]
-#define SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t swig_types[97]
-#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[98]
-#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[99]
-#define SWIGTYPE_p_std__vectorT_unsigned_long_std__allocatorT_unsigned_long_t_t swig_types[100]
-#define SWIGTYPE_p_swig__SwigPyIterator swig_types[101]
-#define SWIGTYPE_p_unsigned_char swig_types[102]
-#define SWIGTYPE_p_unsigned_int swig_types[103]
-#define SWIGTYPE_p_unsigned_long_long swig_types[104]
-#define SWIGTYPE_p_unsigned_short swig_types[105]
-#define SWIGTYPE_p_value_type swig_types[106]
-static swig_type_info *swig_types[108];
-static swig_module_info swig_module = {swig_types, 107, 0, 0, 0, 0};
+#define SWIGTYPE_p_IVarianceFunction swig_types[34]
+#define SWIGTYPE_p_Instrument swig_types[35]
+#define SWIGTYPE_p_IntensityFunctionLog swig_types[36]
+#define SWIGTYPE_p_IntensityFunctionSqrt swig_types[37]
+#define SWIGTYPE_p_IterationInfo swig_types[38]
+#define SWIGTYPE_p_MultiLayer swig_types[39]
+#define SWIGTYPE_p_OffSpecularSimulation swig_types[40]
+#define SWIGTYPE_p_OutputDataT_double_t swig_types[41]
+#define SWIGTYPE_p_ParameterDistribution swig_types[42]
+#define SWIGTYPE_p_ParameterPool swig_types[43]
+#define SWIGTYPE_p_PoissonNoiseBackground swig_types[44]
+#define SWIGTYPE_p_ProgressHandler__Callback_t swig_types[45]
+#define SWIGTYPE_p_PyBuilderCallback swig_types[46]
+#define SWIGTYPE_p_PyObserverCallback swig_types[47]
+#define SWIGTYPE_p_QSpecScan swig_types[48]
+#define SWIGTYPE_p_RealLimits swig_types[49]
+#define SWIGTYPE_p_ScanResolution swig_types[50]
+#define SWIGTYPE_p_SimulationOptions swig_types[51]
+#define SWIGTYPE_p_SimulationResult swig_types[52]
+#define SWIGTYPE_p_SpecularSimulation swig_types[53]
+#define SWIGTYPE_p_VarianceConstantFunction swig_types[54]
+#define SWIGTYPE_p_VarianceSimFunction swig_types[55]
+#define SWIGTYPE_p_allocator_type swig_types[56]
+#define SWIGTYPE_p_char swig_types[57]
+#define SWIGTYPE_p_difference_type swig_types[58]
+#define SWIGTYPE_p_first_type swig_types[59]
+#define SWIGTYPE_p_int swig_types[60]
+#define SWIGTYPE_p_key_type swig_types[61]
+#define SWIGTYPE_p_long_long swig_types[62]
+#define SWIGTYPE_p_mapped_type swig_types[63]
+#define SWIGTYPE_p_mumufit__MinimizerResult swig_types[64]
+#define SWIGTYPE_p_mumufit__Parameters swig_types[65]
+#define SWIGTYPE_p_p_PyObject swig_types[66]
+#define SWIGTYPE_p_second_type swig_types[67]
+#define SWIGTYPE_p_short swig_types[68]
+#define SWIGTYPE_p_signed_char swig_types[69]
+#define SWIGTYPE_p_size_type swig_types[70]
+#define SWIGTYPE_p_std__allocatorT_AxisInfo_t swig_types[71]
+#define SWIGTYPE_p_std__allocatorT_BasicVector3DT_double_t_t swig_types[72]
+#define SWIGTYPE_p_std__allocatorT_BasicVector3DT_std__complexT_double_t_t_t swig_types[73]
+#define SWIGTYPE_p_std__allocatorT_INode_const_p_t swig_types[74]
+#define SWIGTYPE_p_std__allocatorT_INode_p_t swig_types[75]
+#define SWIGTYPE_p_std__allocatorT_double_t swig_types[76]
+#define SWIGTYPE_p_std__allocatorT_int_t swig_types[77]
+#define SWIGTYPE_p_std__allocatorT_std__complexT_double_t_t swig_types[78]
+#define SWIGTYPE_p_std__allocatorT_std__pairT_double_double_t_t swig_types[79]
+#define SWIGTYPE_p_std__allocatorT_std__pairT_std__string_const_double_t_t swig_types[80]
+#define SWIGTYPE_p_std__allocatorT_std__string_t swig_types[81]
+#define SWIGTYPE_p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t swig_types[82]
+#define SWIGTYPE_p_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t swig_types[83]
+#define SWIGTYPE_p_std__allocatorT_unsigned_long_t swig_types[84]
+#define SWIGTYPE_p_std__complexT_double_t swig_types[85]
+#define SWIGTYPE_p_std__invalid_argument swig_types[86]
+#define SWIGTYPE_p_std__lessT_std__string_t swig_types[87]
+#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[88]
+#define SWIGTYPE_p_std__pairT_double_double_t swig_types[89]
+#define SWIGTYPE_p_std__shared_ptrT_ISampleBuilder_t swig_types[90]
+#define SWIGTYPE_p_std__vectorT_AxisInfo_std__allocatorT_AxisInfo_t_t swig_types[91]
+#define SWIGTYPE_p_std__vectorT_BasicVector3DT_double_t_std__allocatorT_BasicVector3DT_double_t_t_t swig_types[92]
+#define SWIGTYPE_p_std__vectorT_BasicVector3DT_std__complexT_double_t_t_std__allocatorT_BasicVector3DT_std__complexT_double_t_t_t_t swig_types[93]
+#define SWIGTYPE_p_std__vectorT_INode_const_p_std__allocatorT_INode_const_p_t_t swig_types[94]
+#define SWIGTYPE_p_std__vectorT_INode_p_std__allocatorT_INode_p_t_t swig_types[95]
+#define SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t swig_types[96]
+#define SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t swig_types[97]
+#define SWIGTYPE_p_std__vectorT_std__complexT_double_t_std__allocatorT_std__complexT_double_t_t_t swig_types[98]
+#define SWIGTYPE_p_std__vectorT_std__pairT_double_double_t_std__allocatorT_std__pairT_double_double_t_t_t swig_types[99]
+#define SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t swig_types[100]
+#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[101]
+#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[102]
+#define SWIGTYPE_p_std__vectorT_unsigned_long_std__allocatorT_unsigned_long_t_t swig_types[103]
+#define SWIGTYPE_p_swig__SwigPyIterator swig_types[104]
+#define SWIGTYPE_p_unsigned_char swig_types[105]
+#define SWIGTYPE_p_unsigned_int swig_types[106]
+#define SWIGTYPE_p_unsigned_long_long swig_types[107]
+#define SWIGTYPE_p_unsigned_short swig_types[108]
+#define SWIGTYPE_p_value_type swig_types[109]
+static swig_type_info *swig_types[111];
+static swig_module_info swig_module = {swig_types, 110, 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)
 
@@ -6704,16 +6707,20 @@ SWIGINTERN void std_vector_Sl_std_pair_Sl_double_Sc_double_Sg__Sg__insert__SWIG_
 #include "Core/Computation/PoissonNoiseBackground.h"
 #include "Core/Export/ExportToPython.h"
 #include "Core/Fitting/FitObjective.h"
-#include "Core/Fitting/IObserver.h"
 #include "Core/Fitting/IterationInfo.h"
 #include "Core/Fitting/PyFittingCallbacks.h"
+#include "Core/Residual/ChiSquaredModule.h"
+#include "Core/Residual/IChiSquaredModule.h"
+#include "Core/Residual/IIntensityFunction.h"
+#include "Core/Residual/IIntensityFunction.h"
+#include "Core/Residual/VarianceFunctions.h"
 #include "Core/Scan/AngularSpecScan.h"
 #include "Core/Scan/QSpecScan.h"
 #include "Core/Simulation/DepthProbeSimulation.h"
 #include "Core/Simulation/GISASSimulation.h"
 #include "Core/Simulation/ISimulation.h"
 #include "Core/Simulation/ISimulation2D.h"
-#include "Core/Simulation/OffSpecSimulation.h"
+#include "Core/Simulation/OffSpecularSimulation.h"
 #include "Core/Simulation/SimulationFactory.h"
 #include "Core/Simulation/SpecularSimulation.h"
 
@@ -25011,7 +25018,7 @@ SWIGINTERN PyObject *_wrap_kvector_t_complex(PyObject *SWIGUNUSEDPARM(self), PyO
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject *swig_obj[1] ;
-  BasicVector3D< std::complex< double > > result;
+  BasicVector3D< complex_t > result;
   
   if (!args) SWIG_fail;
   swig_obj[0] = args;
@@ -25021,7 +25028,7 @@ SWIGINTERN PyObject *_wrap_kvector_t_complex(PyObject *SWIGUNUSEDPARM(self), PyO
   }
   arg1 = reinterpret_cast< BasicVector3D< double > * >(argp1);
   result = ((BasicVector3D< double > const *)arg1)->complex();
-  resultobj = SWIG_NewPointerObj((new BasicVector3D< std::complex< double > >(static_cast< const BasicVector3D< std::complex< double > >& >(result))), SWIGTYPE_p_BasicVector3DT_std__complexT_double_t_t, SWIG_POINTER_OWN |  0 );
+  resultobj = SWIG_NewPointerObj((new BasicVector3D< complex_t >(static_cast< const BasicVector3D< complex_t >& >(result))), SWIGTYPE_p_BasicVector3DT_std__complexT_double_t_t, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -36843,169 +36850,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_delete_IObserver(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IObserver *arg1 = (IObserver *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &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 *""'"); 
-  }
-  arg1 = reinterpret_cast< IObserver * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IObserver_notify(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IObserver *arg1 = (IObserver *) 0 ;
-  IObservable *arg2 = (IObservable *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject *swig_obj[2] ;
-  
-  if (!SWIG_Python_UnpackTuple(args, "IObserver_notify", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &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(swig_obj[1], &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 *""'"); 
-  }
-  arg2 = reinterpret_cast< IObservable * >(argp2);
-  (arg1)->notify(arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *IObserver_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_IObserver, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *_wrap_delete_IObservable(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IObservable *arg1 = (IObservable *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IObservable, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IObservable" "', argument " "1"" of type '" "IObservable *""'"); 
-  }
-  arg1 = reinterpret_cast< IObservable * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IObservable_attachObserver(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IObservable *arg1 = (IObservable *) 0 ;
-  SwigValueWrapper< std::shared_ptr< IObserver > > arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 ;
-  int res2 = 0 ;
-  PyObject *swig_obj[2] ;
-  
-  if (!SWIG_Python_UnpackTuple(args, "IObservable_attachObserver", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IObservable, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IObservable_attachObserver" "', argument " "1"" of type '" "IObservable *""'"); 
-  }
-  arg1 = reinterpret_cast< IObservable * >(argp1);
-  {
-    res2 = SWIG_ConvertPtr(swig_obj[1], &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) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IObservable_attachObserver" "', argument " "2"" of type '" "IObservable::observer_t""'");
-    } else {
-      IObservable::observer_t * temp = reinterpret_cast< IObservable::observer_t * >(argp2);
-      arg2 = *temp;
-      if (SWIG_IsNewObj(res2)) delete temp;
-    }
-  }
-  (arg1)->attachObserver(arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IObservable_notifyObservers(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IObservable *arg1 = (IObservable *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IObservable, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IObservable_notifyObservers" "', argument " "1"" of type '" "IObservable *""'"); 
-  }
-  arg1 = reinterpret_cast< IObservable * >(argp1);
-  (arg1)->notifyObservers();
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_IObservable(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IObservable *result = 0 ;
-  
-  if (!SWIG_Python_UnpackTuple(args, "new_IObservable", 0, 0, 0)) SWIG_fail;
-  result = (IObservable *)new IObservable();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IObservable, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *IObservable_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_IObservable, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *IObservable_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  return SWIG_Python_InitShadowInstance(args);
-}
-
 SWIGINTERN PyObject *_wrap_new_IterationInfo(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   IterationInfo *result = 0 ;
@@ -39240,72 +39084,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_ISimulation_setBeamIntensity(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  ISimulation *arg1 = (ISimulation *) 0 ;
-  double arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  PyObject *swig_obj[2] ;
-  
-  if (!SWIG_Python_UnpackTuple(args, "ISimulation_setBeamIntensity", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ISimulation, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ISimulation_setBeamIntensity" "', argument " "1"" of type '" "ISimulation *""'"); 
-  }
-  arg1 = reinterpret_cast< ISimulation * >(argp1);
-  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ISimulation_setBeamIntensity" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  (arg1)->setBeamIntensity(arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_ISimulation_setBeamPolarization(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  ISimulation *arg1 = (ISimulation *) 0 ;
-  kvector_t arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 ;
-  int res2 = 0 ;
-  PyObject *swig_obj[2] ;
-  
-  if (!SWIG_Python_UnpackTuple(args, "ISimulation_setBeamPolarization", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ISimulation, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ISimulation_setBeamPolarization" "', argument " "1"" of type '" "ISimulation *""'"); 
-  }
-  arg1 = reinterpret_cast< ISimulation * >(argp1);
-  {
-    res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_BasicVector3DT_double_t,  0  | 0);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ISimulation_setBeamPolarization" "', argument " "2"" of type '" "kvector_t const""'"); 
-    }  
-    if (!argp2) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "ISimulation_setBeamPolarization" "', 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)->setBeamPolarization(arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_ISimulation_setDetectorResolutionFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   ISimulation *arg1 = (ISimulation *) 0 ;
@@ -41605,7 +41383,7 @@ SWIGINTERN PyObject *SpecularSimulation_swiginit(PyObject *SWIGUNUSEDPARM(self),
   return SWIG_Python_InitShadowInstance(args);
 }
 
-SWIGINTERN PyObject *_wrap_new_OffSpecSimulation__SWIG_0(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
+SWIGINTERN PyObject *_wrap_new_OffSpecularSimulation__SWIG_0(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
   PyObject *resultobj = 0;
   Beam *arg1 = 0 ;
   MultiLayer *arg2 = 0 ;
@@ -41616,64 +41394,64 @@ SWIGINTERN PyObject *_wrap_new_OffSpecSimulation__SWIG_0(PyObject *SWIGUNUSEDPAR
   int res2 = 0 ;
   void *argp3 = 0 ;
   int res3 = 0 ;
-  OffSpecSimulation *result = 0 ;
+  OffSpecularSimulation *result = 0 ;
   
   if ((nobjs < 3) || (nobjs > 3)) SWIG_fail;
   res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_Beam,  0  | 0);
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_OffSpecSimulation" "', argument " "1"" of type '" "Beam const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_OffSpecularSimulation" "', argument " "1"" of type '" "Beam const &""'"); 
   }
   if (!argp1) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_OffSpecSimulation" "', argument " "1"" of type '" "Beam const &""'"); 
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_OffSpecularSimulation" "', argument " "1"" of type '" "Beam const &""'"); 
   }
   arg1 = reinterpret_cast< Beam * >(argp1);
   res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_MultiLayer,  0  | 0);
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "new_OffSpecSimulation" "', argument " "2"" of type '" "MultiLayer const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "new_OffSpecularSimulation" "', argument " "2"" of type '" "MultiLayer const &""'"); 
   }
   if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_OffSpecSimulation" "', argument " "2"" of type '" "MultiLayer const &""'"); 
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_OffSpecularSimulation" "', argument " "2"" of type '" "MultiLayer const &""'"); 
   }
   arg2 = reinterpret_cast< MultiLayer * >(argp2);
   res3 = SWIG_ConvertPtr(swig_obj[2], &argp3, SWIGTYPE_p_IDetector,  0  | 0);
   if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "new_OffSpecSimulation" "', argument " "3"" of type '" "IDetector const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "new_OffSpecularSimulation" "', argument " "3"" of type '" "IDetector const &""'"); 
   }
   if (!argp3) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_OffSpecSimulation" "', argument " "3"" of type '" "IDetector const &""'"); 
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_OffSpecularSimulation" "', argument " "3"" of type '" "IDetector const &""'"); 
   }
   arg3 = reinterpret_cast< IDetector * >(argp3);
-  result = (OffSpecSimulation *)new OffSpecSimulation((Beam const &)*arg1,(MultiLayer const &)*arg2,(IDetector const &)*arg3);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_OffSpecSimulation, SWIG_POINTER_NEW |  0 );
+  result = (OffSpecularSimulation *)new OffSpecularSimulation((Beam const &)*arg1,(MultiLayer const &)*arg2,(IDetector const &)*arg3);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_OffSpecularSimulation, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_new_OffSpecSimulation__SWIG_1(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) {
+SWIGINTERN PyObject *_wrap_new_OffSpecularSimulation__SWIG_1(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) {
   PyObject *resultobj = 0;
-  OffSpecSimulation *result = 0 ;
+  OffSpecularSimulation *result = 0 ;
   
   if ((nobjs < 0) || (nobjs > 0)) SWIG_fail;
-  result = (OffSpecSimulation *)new OffSpecSimulation();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_OffSpecSimulation, SWIG_POINTER_NEW |  0 );
+  result = (OffSpecularSimulation *)new OffSpecularSimulation();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_OffSpecularSimulation, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_new_OffSpecSimulation(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_OffSpecularSimulation(PyObject *self, PyObject *args) {
   Py_ssize_t argc;
   PyObject *argv[4] = {
     0
   };
   
-  if (!(argc = SWIG_Python_UnpackTuple(args, "new_OffSpecSimulation", 0, 3, argv))) SWIG_fail;
+  if (!(argc = SWIG_Python_UnpackTuple(args, "new_OffSpecularSimulation", 0, 3, argv))) SWIG_fail;
   --argc;
   if (argc == 0) {
-    return _wrap_new_OffSpecSimulation__SWIG_1(self, argc, argv);
+    return _wrap_new_OffSpecularSimulation__SWIG_1(self, argc, argv);
   }
   if (argc == 3) {
     int _v;
@@ -41686,35 +41464,35 @@ SWIGINTERN PyObject *_wrap_new_OffSpecSimulation(PyObject *self, PyObject *args)
         int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_IDetector, SWIG_POINTER_NO_NULL | 0);
         _v = SWIG_CheckState(res);
         if (_v) {
-          return _wrap_new_OffSpecSimulation__SWIG_0(self, argc, argv);
+          return _wrap_new_OffSpecularSimulation__SWIG_0(self, argc, argv);
         }
       }
     }
   }
   
 fail:
-  SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'new_OffSpecSimulation'.\n"
+  SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'new_OffSpecularSimulation'.\n"
     "  Possible C/C++ prototypes are:\n"
-    "    OffSpecSimulation::OffSpecSimulation(Beam const &,MultiLayer const &,IDetector const &)\n"
-    "    OffSpecSimulation::OffSpecSimulation()\n");
+    "    OffSpecularSimulation::OffSpecularSimulation(Beam const &,MultiLayer const &,IDetector const &)\n"
+    "    OffSpecularSimulation::OffSpecularSimulation()\n");
   return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_delete_OffSpecSimulation(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_delete_OffSpecularSimulation(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  OffSpecSimulation *arg1 = (OffSpecSimulation *) 0 ;
+  OffSpecularSimulation *arg1 = (OffSpecularSimulation *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject *swig_obj[1] ;
   
   if (!args) SWIG_fail;
   swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_OffSpecSimulation, SWIG_POINTER_DISOWN |  0 );
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_OffSpecularSimulation, SWIG_POINTER_DISOWN |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_OffSpecSimulation" "', argument " "1"" of type '" "OffSpecSimulation *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_OffSpecularSimulation" "', argument " "1"" of type '" "OffSpecularSimulation *""'"); 
   }
-  arg1 = reinterpret_cast< OffSpecSimulation * >(argp1);
+  arg1 = reinterpret_cast< OffSpecularSimulation * >(argp1);
   delete arg1;
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -41723,32 +41501,32 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_OffSpecSimulation_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_OffSpecularSimulation_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  OffSpecSimulation *arg1 = (OffSpecSimulation *) 0 ;
+  OffSpecularSimulation *arg1 = (OffSpecularSimulation *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject *swig_obj[1] ;
-  OffSpecSimulation *result = 0 ;
+  OffSpecularSimulation *result = 0 ;
   
   if (!args) SWIG_fail;
   swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_OffSpecSimulation, 0 |  0 );
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_OffSpecularSimulation, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "OffSpecSimulation_clone" "', argument " "1"" of type '" "OffSpecSimulation const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "OffSpecularSimulation_clone" "', argument " "1"" of type '" "OffSpecularSimulation const *""'"); 
   }
-  arg1 = reinterpret_cast< OffSpecSimulation * >(argp1);
-  result = (OffSpecSimulation *)((OffSpecSimulation const *)arg1)->clone();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_OffSpecSimulation, 0 |  0 );
+  arg1 = reinterpret_cast< OffSpecularSimulation * >(argp1);
+  result = (OffSpecularSimulation *)((OffSpecularSimulation const *)arg1)->clone();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_OffSpecularSimulation, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_OffSpecSimulation_accept(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_OffSpecularSimulation_accept(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  OffSpecSimulation *arg1 = (OffSpecSimulation *) 0 ;
+  OffSpecularSimulation *arg1 = (OffSpecularSimulation *) 0 ;
   INodeVisitor *arg2 = (INodeVisitor *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
@@ -41756,18 +41534,18 @@ SWIGINTERN PyObject *_wrap_OffSpecSimulation_accept(PyObject *SWIGUNUSEDPARM(sel
   int res2 = 0 ;
   PyObject *swig_obj[2] ;
   
-  if (!SWIG_Python_UnpackTuple(args, "OffSpecSimulation_accept", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_OffSpecSimulation, 0 |  0 );
+  if (!SWIG_Python_UnpackTuple(args, "OffSpecularSimulation_accept", 2, 2, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_OffSpecularSimulation, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "OffSpecSimulation_accept" "', argument " "1"" of type '" "OffSpecSimulation const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "OffSpecularSimulation_accept" "', argument " "1"" of type '" "OffSpecularSimulation const *""'"); 
   }
-  arg1 = reinterpret_cast< OffSpecSimulation * >(argp1);
+  arg1 = reinterpret_cast< OffSpecularSimulation * >(argp1);
   res2 = SWIG_ConvertPtr(swig_obj[1], &argp2,SWIGTYPE_p_INodeVisitor, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "OffSpecSimulation_accept" "', argument " "2"" of type '" "INodeVisitor *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "OffSpecularSimulation_accept" "', argument " "2"" of type '" "INodeVisitor *""'"); 
   }
   arg2 = reinterpret_cast< INodeVisitor * >(argp2);
-  ((OffSpecSimulation const *)arg1)->accept(arg2);
+  ((OffSpecularSimulation const *)arg1)->accept(arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -41775,20 +41553,20 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_OffSpecSimulation_prepareSimulation(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_OffSpecularSimulation_prepareSimulation(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  OffSpecSimulation *arg1 = (OffSpecSimulation *) 0 ;
+  OffSpecularSimulation *arg1 = (OffSpecularSimulation *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject *swig_obj[1] ;
   
   if (!args) SWIG_fail;
   swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_OffSpecSimulation, 0 |  0 );
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_OffSpecularSimulation, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "OffSpecSimulation_prepareSimulation" "', argument " "1"" of type '" "OffSpecSimulation *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "OffSpecularSimulation_prepareSimulation" "', argument " "1"" of type '" "OffSpecularSimulation *""'"); 
   }
-  arg1 = reinterpret_cast< OffSpecSimulation * >(argp1);
+  arg1 = reinterpret_cast< OffSpecularSimulation * >(argp1);
   (arg1)->prepareSimulation();
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -41797,9 +41575,9 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_OffSpecSimulation_result(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_OffSpecularSimulation_result(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  OffSpecSimulation *arg1 = (OffSpecSimulation *) 0 ;
+  OffSpecularSimulation *arg1 = (OffSpecularSimulation *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject *swig_obj[1] ;
@@ -41807,12 +41585,12 @@ SWIGINTERN PyObject *_wrap_OffSpecSimulation_result(PyObject *SWIGUNUSEDPARM(sel
   
   if (!args) SWIG_fail;
   swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_OffSpecSimulation, 0 |  0 );
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_OffSpecularSimulation, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "OffSpecSimulation_result" "', argument " "1"" of type '" "OffSpecSimulation const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "OffSpecularSimulation_result" "', argument " "1"" of type '" "OffSpecularSimulation const *""'"); 
   }
-  arg1 = reinterpret_cast< OffSpecSimulation * >(argp1);
-  result = ((OffSpecSimulation const *)arg1)->result();
+  arg1 = reinterpret_cast< OffSpecularSimulation * >(argp1);
+  result = ((OffSpecularSimulation const *)arg1)->result();
   resultobj = SWIG_NewPointerObj((new SimulationResult(static_cast< const SimulationResult& >(result))), SWIGTYPE_p_SimulationResult, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
@@ -41820,9 +41598,9 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_OffSpecSimulation_setBeamParameters(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_OffSpecularSimulation_setBeamParameters(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  OffSpecSimulation *arg1 = (OffSpecSimulation *) 0 ;
+  OffSpecularSimulation *arg1 = (OffSpecularSimulation *) 0 ;
   double arg2 ;
   IAxis *arg3 = 0 ;
   double arg4 ;
@@ -41836,28 +41614,28 @@ SWIGINTERN PyObject *_wrap_OffSpecSimulation_setBeamParameters(PyObject *SWIGUNU
   int ecode4 = 0 ;
   PyObject *swig_obj[4] ;
   
-  if (!SWIG_Python_UnpackTuple(args, "OffSpecSimulation_setBeamParameters", 4, 4, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_OffSpecSimulation, 0 |  0 );
+  if (!SWIG_Python_UnpackTuple(args, "OffSpecularSimulation_setBeamParameters", 4, 4, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_OffSpecularSimulation, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "OffSpecSimulation_setBeamParameters" "', argument " "1"" of type '" "OffSpecSimulation *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "OffSpecularSimulation_setBeamParameters" "', argument " "1"" of type '" "OffSpecularSimulation *""'"); 
   }
-  arg1 = reinterpret_cast< OffSpecSimulation * >(argp1);
+  arg1 = reinterpret_cast< OffSpecularSimulation * >(argp1);
   ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "OffSpecSimulation_setBeamParameters" "', argument " "2"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "OffSpecularSimulation_setBeamParameters" "', argument " "2"" of type '" "double""'");
   } 
   arg2 = static_cast< double >(val2);
   res3 = SWIG_ConvertPtr(swig_obj[2], &argp3, SWIGTYPE_p_IAxis,  0  | 0);
   if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "OffSpecSimulation_setBeamParameters" "', argument " "3"" of type '" "IAxis const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "OffSpecularSimulation_setBeamParameters" "', argument " "3"" of type '" "IAxis const &""'"); 
   }
   if (!argp3) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "OffSpecSimulation_setBeamParameters" "', argument " "3"" of type '" "IAxis const &""'"); 
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "OffSpecularSimulation_setBeamParameters" "', argument " "3"" of type '" "IAxis const &""'"); 
   }
   arg3 = reinterpret_cast< IAxis * >(argp3);
   ecode4 = SWIG_AsVal_double(swig_obj[3], &val4);
   if (!SWIG_IsOK(ecode4)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "OffSpecSimulation_setBeamParameters" "', argument " "4"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "OffSpecularSimulation_setBeamParameters" "', argument " "4"" of type '" "double""'");
   } 
   arg4 = static_cast< double >(val4);
   (arg1)->setBeamParameters(arg2,(IAxis const &)*arg3,arg4);
@@ -41868,9 +41646,9 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_OffSpecSimulation_beamAxis(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_OffSpecularSimulation_beamAxis(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  OffSpecSimulation *arg1 = (OffSpecSimulation *) 0 ;
+  OffSpecularSimulation *arg1 = (OffSpecularSimulation *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject *swig_obj[1] ;
@@ -41878,12 +41656,12 @@ SWIGINTERN PyObject *_wrap_OffSpecSimulation_beamAxis(PyObject *SWIGUNUSEDPARM(s
   
   if (!args) SWIG_fail;
   swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_OffSpecSimulation, 0 |  0 );
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_OffSpecularSimulation, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "OffSpecSimulation_beamAxis" "', argument " "1"" of type '" "OffSpecSimulation const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "OffSpecularSimulation_beamAxis" "', argument " "1"" of type '" "OffSpecularSimulation const *""'"); 
   }
-  arg1 = reinterpret_cast< OffSpecSimulation * >(argp1);
-  result = (IAxis *)((OffSpecSimulation const *)arg1)->beamAxis();
+  arg1 = reinterpret_cast< OffSpecularSimulation * >(argp1);
+  result = (IAxis *)((OffSpecularSimulation const *)arg1)->beamAxis();
   resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IAxis, 0 |  0 );
   return resultobj;
 fail:
@@ -41891,9 +41669,9 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_OffSpecSimulation_intensityMapSize(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_OffSpecularSimulation_intensityMapSize(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  OffSpecSimulation *arg1 = (OffSpecSimulation *) 0 ;
+  OffSpecularSimulation *arg1 = (OffSpecularSimulation *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject *swig_obj[1] ;
@@ -41901,12 +41679,12 @@ SWIGINTERN PyObject *_wrap_OffSpecSimulation_intensityMapSize(PyObject *SWIGUNUS
   
   if (!args) SWIG_fail;
   swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_OffSpecSimulation, 0 |  0 );
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_OffSpecularSimulation, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "OffSpecSimulation_intensityMapSize" "', argument " "1"" of type '" "OffSpecSimulation const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "OffSpecularSimulation_intensityMapSize" "', argument " "1"" of type '" "OffSpecularSimulation const *""'"); 
   }
-  arg1 = reinterpret_cast< OffSpecSimulation * >(argp1);
-  result = ((OffSpecSimulation const *)arg1)->intensityMapSize();
+  arg1 = reinterpret_cast< OffSpecularSimulation * >(argp1);
+  result = ((OffSpecularSimulation const *)arg1)->intensityMapSize();
   resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
@@ -41914,14 +41692,14 @@ fail:
 }
 
 
-SWIGINTERN PyObject *OffSpecSimulation_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *OffSpecularSimulation_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
   if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_OffSpecSimulation, SWIG_NewClientData(obj));
+  SWIG_TypeNewClientData(SWIGTYPE_p_OffSpecularSimulation, SWIG_NewClientData(obj));
   return SWIG_Py_Void();
 }
 
-SWIGINTERN PyObject *OffSpecSimulation_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *OffSpecularSimulation_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   return SWIG_Python_InitShadowInstance(args);
 }
 
@@ -42405,6 +42183,1018 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_delete_IIntensityFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IIntensityFunction *arg1 = (IIntensityFunction *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IIntensityFunction, SWIG_POINTER_DISOWN |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IIntensityFunction" "', argument " "1"" of type '" "IIntensityFunction *""'"); 
+  }
+  arg1 = reinterpret_cast< IIntensityFunction * >(argp1);
+  delete arg1;
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_IIntensityFunction_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IIntensityFunction *arg1 = (IIntensityFunction *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  IIntensityFunction *result = 0 ;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IIntensityFunction, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IIntensityFunction_clone" "', argument " "1"" of type '" "IIntensityFunction const *""'"); 
+  }
+  arg1 = reinterpret_cast< IIntensityFunction * >(argp1);
+  result = (IIntensityFunction *)((IIntensityFunction const *)arg1)->clone();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IIntensityFunction, 0 |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_IIntensityFunction_evaluate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IIntensityFunction *arg1 = (IIntensityFunction *) 0 ;
+  double arg2 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  PyObject *swig_obj[2] ;
+  double result;
+  
+  if (!SWIG_Python_UnpackTuple(args, "IIntensityFunction_evaluate", 2, 2, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IIntensityFunction, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IIntensityFunction_evaluate" "', argument " "1"" of type '" "IIntensityFunction const *""'"); 
+  }
+  arg1 = reinterpret_cast< IIntensityFunction * >(argp1);
+  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IIntensityFunction_evaluate" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  result = (double)((IIntensityFunction const *)arg1)->evaluate(arg2);
+  resultobj = SWIG_From_double(static_cast< double >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *IIntensityFunction_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *obj;
+  if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_IIntensityFunction, SWIG_NewClientData(obj));
+  return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *_wrap_IntensityFunctionLog_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IntensityFunctionLog *arg1 = (IntensityFunctionLog *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  IntensityFunctionLog *result = 0 ;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IntensityFunctionLog, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntensityFunctionLog_clone" "', argument " "1"" of type '" "IntensityFunctionLog const *""'"); 
+  }
+  arg1 = reinterpret_cast< IntensityFunctionLog * >(argp1);
+  result = (IntensityFunctionLog *)((IntensityFunctionLog const *)arg1)->clone();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IntensityFunctionLog, 0 |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_IntensityFunctionLog_evaluate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IntensityFunctionLog *arg1 = (IntensityFunctionLog *) 0 ;
+  double arg2 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  PyObject *swig_obj[2] ;
+  double result;
+  
+  if (!SWIG_Python_UnpackTuple(args, "IntensityFunctionLog_evaluate", 2, 2, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IntensityFunctionLog, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntensityFunctionLog_evaluate" "', argument " "1"" of type '" "IntensityFunctionLog const *""'"); 
+  }
+  arg1 = reinterpret_cast< IntensityFunctionLog * >(argp1);
+  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntensityFunctionLog_evaluate" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  result = (double)((IntensityFunctionLog const *)arg1)->evaluate(arg2);
+  resultobj = SWIG_From_double(static_cast< double >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_new_IntensityFunctionLog(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IntensityFunctionLog *result = 0 ;
+  
+  if (!SWIG_Python_UnpackTuple(args, "new_IntensityFunctionLog", 0, 0, 0)) SWIG_fail;
+  result = (IntensityFunctionLog *)new IntensityFunctionLog();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IntensityFunctionLog, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_delete_IntensityFunctionLog(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IntensityFunctionLog *arg1 = (IntensityFunctionLog *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &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 *IntensityFunctionLog_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *obj;
+  if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_IntensityFunctionLog, SWIG_NewClientData(obj));
+  return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *IntensityFunctionLog_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  return SWIG_Python_InitShadowInstance(args);
+}
+
+SWIGINTERN PyObject *_wrap_IntensityFunctionSqrt_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IntensityFunctionSqrt *arg1 = (IntensityFunctionSqrt *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  IntensityFunctionSqrt *result = 0 ;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IntensityFunctionSqrt, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntensityFunctionSqrt_clone" "', argument " "1"" of type '" "IntensityFunctionSqrt const *""'"); 
+  }
+  arg1 = reinterpret_cast< IntensityFunctionSqrt * >(argp1);
+  result = (IntensityFunctionSqrt *)((IntensityFunctionSqrt const *)arg1)->clone();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IntensityFunctionSqrt, 0 |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_IntensityFunctionSqrt_evaluate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IntensityFunctionSqrt *arg1 = (IntensityFunctionSqrt *) 0 ;
+  double arg2 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  PyObject *swig_obj[2] ;
+  double result;
+  
+  if (!SWIG_Python_UnpackTuple(args, "IntensityFunctionSqrt_evaluate", 2, 2, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IntensityFunctionSqrt, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntensityFunctionSqrt_evaluate" "', argument " "1"" of type '" "IntensityFunctionSqrt const *""'"); 
+  }
+  arg1 = reinterpret_cast< IntensityFunctionSqrt * >(argp1);
+  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntensityFunctionSqrt_evaluate" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  result = (double)((IntensityFunctionSqrt const *)arg1)->evaluate(arg2);
+  resultobj = SWIG_From_double(static_cast< double >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_new_IntensityFunctionSqrt(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IntensityFunctionSqrt *result = 0 ;
+  
+  if (!SWIG_Python_UnpackTuple(args, "new_IntensityFunctionSqrt", 0, 0, 0)) SWIG_fail;
+  result = (IntensityFunctionSqrt *)new IntensityFunctionSqrt();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IntensityFunctionSqrt, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_delete_IntensityFunctionSqrt(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IntensityFunctionSqrt *arg1 = (IntensityFunctionSqrt *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &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 (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_IntensityFunctionSqrt, SWIG_NewClientData(obj));
+  return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *IntensityFunctionSqrt_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  return SWIG_Python_InitShadowInstance(args);
+}
+
+SWIGINTERN PyObject *_wrap_delete_IChiSquaredModule(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IChiSquaredModule *arg1 = (IChiSquaredModule *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IChiSquaredModule, SWIG_POINTER_DISOWN |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IChiSquaredModule" "', argument " "1"" of type '" "IChiSquaredModule *""'"); 
+  }
+  arg1 = reinterpret_cast< IChiSquaredModule * >(argp1);
+  delete arg1;
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_IChiSquaredModule_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IChiSquaredModule *arg1 = (IChiSquaredModule *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  IChiSquaredModule *result = 0 ;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IChiSquaredModule, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IChiSquaredModule_clone" "', argument " "1"" of type '" "IChiSquaredModule const *""'"); 
+  }
+  arg1 = reinterpret_cast< IChiSquaredModule * >(argp1);
+  result = (IChiSquaredModule *)((IChiSquaredModule const *)arg1)->clone();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IChiSquaredModule, 0 |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_IChiSquaredModule_varianceFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IChiSquaredModule *arg1 = (IChiSquaredModule *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  IVarianceFunction *result = 0 ;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IChiSquaredModule, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IChiSquaredModule_varianceFunction" "', argument " "1"" of type '" "IChiSquaredModule const *""'"); 
+  }
+  arg1 = reinterpret_cast< IChiSquaredModule * >(argp1);
+  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_setVarianceFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IChiSquaredModule *arg1 = (IChiSquaredModule *) 0 ;
+  IVarianceFunction *arg2 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  PyObject *swig_obj[2] ;
+  
+  if (!SWIG_Python_UnpackTuple(args, "IChiSquaredModule_setVarianceFunction", 2, 2, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IChiSquaredModule, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IChiSquaredModule_setVarianceFunction" "', argument " "1"" of type '" "IChiSquaredModule *""'"); 
+  }
+  arg1 = reinterpret_cast< IChiSquaredModule * >(argp1);
+  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_IVarianceFunction,  0  | 0);
+  if (!SWIG_IsOK(res2)) {
+    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_setVarianceFunction" "', argument " "2"" of type '" "IVarianceFunction const &""'"); 
+  }
+  arg2 = reinterpret_cast< IVarianceFunction * >(argp2);
+  (arg1)->setVarianceFunction((IVarianceFunction const &)*arg2);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_IChiSquaredModule_getIntensityFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IChiSquaredModule *arg1 = (IChiSquaredModule *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  IIntensityFunction *result = 0 ;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IChiSquaredModule, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IChiSquaredModule_getIntensityFunction" "', argument " "1"" of type '" "IChiSquaredModule const *""'"); 
+  }
+  arg1 = reinterpret_cast< IChiSquaredModule * >(argp1);
+  result = (IIntensityFunction *)((IChiSquaredModule const *)arg1)->getIntensityFunction();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IIntensityFunction, 0 |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_IChiSquaredModule_setIntensityFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IChiSquaredModule *arg1 = (IChiSquaredModule *) 0 ;
+  IIntensityFunction *arg2 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  PyObject *swig_obj[2] ;
+  
+  if (!SWIG_Python_UnpackTuple(args, "IChiSquaredModule_setIntensityFunction", 2, 2, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IChiSquaredModule, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IChiSquaredModule_setIntensityFunction" "', argument " "1"" of type '" "IChiSquaredModule *""'"); 
+  }
+  arg1 = reinterpret_cast< IChiSquaredModule * >(argp1);
+  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_IIntensityFunction,  0  | 0);
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IChiSquaredModule_setIntensityFunction" "', argument " "2"" of type '" "IIntensityFunction const &""'"); 
+  }
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IChiSquaredModule_setIntensityFunction" "', argument " "2"" of type '" "IIntensityFunction const &""'"); 
+  }
+  arg2 = reinterpret_cast< IIntensityFunction * >(argp2);
+  (arg1)->setIntensityFunction((IIntensityFunction const &)*arg2);
+  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 ;
+  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 *swig_obj[4] ;
+  double result;
+  
+  if (!SWIG_Python_UnpackTuple(args, "IChiSquaredModule_residual", 4, 4, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IChiSquaredModule, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IChiSquaredModule_residual" "', argument " "1"" of type '" "IChiSquaredModule *""'"); 
+  }
+  arg1 = reinterpret_cast< IChiSquaredModule * >(argp1);
+  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IChiSquaredModule_residual" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  ecode3 = SWIG_AsVal_double(swig_obj[2], &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IChiSquaredModule_residual" "', argument " "3"" of type '" "double""'");
+  } 
+  arg3 = static_cast< double >(val3);
+  ecode4 = SWIG_AsVal_double(swig_obj[3], &val4);
+  if (!SWIG_IsOK(ecode4)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "IChiSquaredModule_residual" "', 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));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *IChiSquaredModule_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *obj;
+  if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_IChiSquaredModule, SWIG_NewClientData(obj));
+  return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *_wrap_new_ChiSquaredModule__SWIG_0(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) {
+  PyObject *resultobj = 0;
+  ChiSquaredModule *result = 0 ;
+  
+  if ((nobjs < 0) || (nobjs > 0)) 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), Py_ssize_t nobjs, PyObject **swig_obj) {
+  PyObject *resultobj = 0;
+  ChiSquaredModule *arg1 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  ChiSquaredModule *result = 0 ;
+  
+  if ((nobjs < 1) || (nobjs > 1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_ChiSquaredModule,  0  | 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 &""'"); 
+  }
+  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_new_ChiSquaredModule(PyObject *self, PyObject *args) {
+  Py_ssize_t argc;
+  PyObject *argv[2] = {
+    0
+  };
+  
+  if (!(argc = SWIG_Python_UnpackTuple(args, "new_ChiSquaredModule", 0, 1, argv))) SWIG_fail;
+  --argc;
+  if (argc == 0) {
+    return _wrap_new_ChiSquaredModule__SWIG_0(self, argc, argv);
+  }
+  if (argc == 1) {
+    int _v;
+    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_ChiSquaredModule, SWIG_POINTER_NO_NULL | 0);
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      return _wrap_new_ChiSquaredModule__SWIG_1(self, argc, argv);
+    }
+  }
+  
+fail:
+  SWIG_Python_RaiseOrModifyTypeError("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;
+}
+
+
+SWIGINTERN PyObject *_wrap_delete_ChiSquaredModule(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  ChiSquaredModule *arg1 = (ChiSquaredModule *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ChiSquaredModule, SWIG_POINTER_DISOWN |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_ChiSquaredModule" "', argument " "1"" of type '" "ChiSquaredModule *""'"); 
+  }
+  arg1 = reinterpret_cast< ChiSquaredModule * >(argp1);
+  delete arg1;
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ChiSquaredModule_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  ChiSquaredModule *arg1 = (ChiSquaredModule *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  ChiSquaredModule *result = 0 ;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &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 *""'"); 
+  }
+  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_ChiSquaredModule_residual(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 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 *swig_obj[4] ;
+  double result;
+  
+  if (!SWIG_Python_UnpackTuple(args, "ChiSquaredModule_residual", 4, 4, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ChiSquaredModule, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ChiSquaredModule_residual" "', argument " "1"" of type '" "ChiSquaredModule *""'"); 
+  }
+  arg1 = reinterpret_cast< ChiSquaredModule * >(argp1);
+  ecode2 = SWIG_AsVal_double(swig_obj[1], &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(swig_obj[2], &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(swig_obj[3], &val4);
+  if (!SWIG_IsOK(ecode4)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "ChiSquaredModule_residual" "', 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));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *ChiSquaredModule_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *obj;
+  if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_ChiSquaredModule, SWIG_NewClientData(obj));
+  return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *ChiSquaredModule_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  return SWIG_Python_InitShadowInstance(args);
+}
+
+SWIGINTERN PyObject *_wrap_delete_IVarianceFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IVarianceFunction *arg1 = (IVarianceFunction *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IVarianceFunction, SWIG_POINTER_DISOWN |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IVarianceFunction" "', argument " "1"" of type '" "IVarianceFunction *""'"); 
+  }
+  arg1 = reinterpret_cast< IVarianceFunction * >(argp1);
+  delete arg1;
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_IVarianceFunction_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IVarianceFunction *arg1 = (IVarianceFunction *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  IVarianceFunction *result = 0 ;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IVarianceFunction, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IVarianceFunction_clone" "', argument " "1"" of type '" "IVarianceFunction const *""'"); 
+  }
+  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_IVarianceFunction_variance(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IVarianceFunction *arg1 = (IVarianceFunction *) 0 ;
+  double arg2 ;
+  double arg3 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  double val3 ;
+  int ecode3 = 0 ;
+  PyObject *swig_obj[3] ;
+  double result;
+  
+  if (!SWIG_Python_UnpackTuple(args, "IVarianceFunction_variance", 3, 3, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IVarianceFunction, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IVarianceFunction_variance" "', argument " "1"" of type '" "IVarianceFunction const *""'"); 
+  }
+  arg1 = reinterpret_cast< IVarianceFunction * >(argp1);
+  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IVarianceFunction_variance" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  ecode3 = SWIG_AsVal_double(swig_obj[2], &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IVarianceFunction_variance" "', argument " "3"" of type '" "double""'");
+  } 
+  arg3 = static_cast< double >(val3);
+  result = (double)((IVarianceFunction const *)arg1)->variance(arg2,arg3);
+  resultobj = SWIG_From_double(static_cast< double >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *IVarianceFunction_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *obj;
+  if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &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 *swig_obj[1] ;
+  VarianceConstantFunction *result = 0 ;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &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;
+  VarianceConstantFunction *arg1 = (VarianceConstantFunction *) 0 ;
+  double arg2 ;
+  double arg3 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  double val3 ;
+  int ecode3 = 0 ;
+  PyObject *swig_obj[3] ;
+  double result;
+  
+  if (!SWIG_Python_UnpackTuple(args, "VarianceConstantFunction_variance", 3, 3, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_VarianceConstantFunction, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarianceConstantFunction_variance" "', argument " "1"" of type '" "VarianceConstantFunction const *""'"); 
+  }
+  arg1 = reinterpret_cast< VarianceConstantFunction * >(argp1);
+  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarianceConstantFunction_variance" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  ecode3 = SWIG_AsVal_double(swig_obj[2], &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VarianceConstantFunction_variance" "', argument " "3"" of type '" "double""'");
+  } 
+  arg3 = static_cast< double >(val3);
+  result = (double)((VarianceConstantFunction const *)arg1)->variance(arg2,arg3);
+  resultobj = SWIG_From_double(static_cast< double >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_new_VarianceConstantFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  VarianceConstantFunction *result = 0 ;
+  
+  if (!SWIG_Python_UnpackTuple(args, "new_VarianceConstantFunction", 0, 0, 0)) 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_delete_VarianceConstantFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  VarianceConstantFunction *arg1 = (VarianceConstantFunction *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &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:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *VarianceConstantFunction_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *obj;
+  if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_VarianceConstantFunction, SWIG_NewClientData(obj));
+  return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *VarianceConstantFunction_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  return SWIG_Python_InitShadowInstance(args);
+}
+
+SWIGINTERN PyObject *_wrap_new_VarianceSimFunction__SWIG_0(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
+  PyObject *resultobj = 0;
+  double arg1 ;
+  double val1 ;
+  int ecode1 = 0 ;
+  VarianceSimFunction *result = 0 ;
+  
+  if ((nobjs < 1) || (nobjs > 1)) SWIG_fail;
+  ecode1 = SWIG_AsVal_double(swig_obj[0], &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_new_VarianceSimFunction__SWIG_1(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) {
+  PyObject *resultobj = 0;
+  VarianceSimFunction *result = 0 ;
+  
+  if ((nobjs < 0) || (nobjs > 0)) 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_new_VarianceSimFunction(PyObject *self, PyObject *args) {
+  Py_ssize_t argc;
+  PyObject *argv[2] = {
+    0
+  };
+  
+  if (!(argc = SWIG_Python_UnpackTuple(args, "new_VarianceSimFunction", 0, 1, argv))) SWIG_fail;
+  --argc;
+  if (argc == 0) {
+    return _wrap_new_VarianceSimFunction__SWIG_1(self, argc, argv);
+  }
+  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, argc, argv);
+    }
+  }
+  
+fail:
+  SWIG_Python_RaiseOrModifyTypeError("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;
+  VarianceSimFunction *arg1 = (VarianceSimFunction *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  VarianceSimFunction *result = 0 ;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_VarianceSimFunction, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarianceSimFunction_clone" "', argument " "1"" of type '" "VarianceSimFunction const *""'"); 
+  }
+  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_VarianceSimFunction_variance(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  VarianceSimFunction *arg1 = (VarianceSimFunction *) 0 ;
+  double arg2 ;
+  double arg3 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  double val3 ;
+  int ecode3 = 0 ;
+  PyObject *swig_obj[3] ;
+  double result;
+  
+  if (!SWIG_Python_UnpackTuple(args, "VarianceSimFunction_variance", 3, 3, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_VarianceSimFunction, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarianceSimFunction_variance" "', argument " "1"" of type '" "VarianceSimFunction const *""'"); 
+  }
+  arg1 = reinterpret_cast< VarianceSimFunction * >(argp1);
+  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarianceSimFunction_variance" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  ecode3 = SWIG_AsVal_double(swig_obj[2], &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VarianceSimFunction_variance" "', argument " "3"" of type '" "double""'");
+  } 
+  arg3 = static_cast< double >(val3);
+  result = (double)((VarianceSimFunction const *)arg1)->variance(arg2,arg3);
+  resultobj = SWIG_From_double(static_cast< double >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_delete_VarianceSimFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  VarianceSimFunction *arg1 = (VarianceSimFunction *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_VarianceSimFunction, SWIG_POINTER_DISOWN |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_VarianceSimFunction" "', argument " "1"" of type '" "VarianceSimFunction *""'"); 
+  }
+  arg1 = reinterpret_cast< VarianceSimFunction * >(argp1);
+  delete arg1;
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *VarianceSimFunction_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *obj;
+  if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_VarianceSimFunction, SWIG_NewClientData(obj));
+  return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *VarianceSimFunction_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  return SWIG_Python_InitShadowInstance(args);
+}
+
 static PyMethodDef SwigMethods[] = {
 	 { "SWIG_PyInstanceMethod_New", SWIG_PyInstanceMethod_New, METH_O, NULL},
 	 { "delete_SwigPyIterator", _wrap_delete_SwigPyIterator, METH_O, "delete_SwigPyIterator(SwigPyIterator self)"},
@@ -43474,7 +44264,7 @@ static PyMethodDef SwigMethods[] = {
 		"\n"
 		""},
 	 { "FitObjective_setChiSquaredModule", _wrap_FitObjective_setChiSquaredModule, METH_VARARGS, "\n"
-		"FitObjective_setChiSquaredModule(FitObjective self, IChiSquaredModule const & module)\n"
+		"FitObjective_setChiSquaredModule(FitObjective self, IChiSquaredModule module)\n"
 		"void FitObjective::setChiSquaredModule(const IChiSquaredModule &module)\n"
 		"\n"
 		""},
@@ -43532,49 +44322,6 @@ static PyMethodDef SwigMethods[] = {
 	 { "GetPatchVersionNumber", _wrap_GetPatchVersionNumber, METH_NOARGS, "GetPatchVersionNumber() -> int"},
 	 { "GetName", _wrap_GetName, METH_NOARGS, "GetName() -> std::string"},
 	 { "GetVersionNumber", _wrap_GetVersionNumber, METH_NOARGS, "GetVersionNumber() -> std::string"},
-	 { "delete_IObserver", _wrap_delete_IObserver, METH_O, "\n"
-		"delete_IObserver(IObserver self)\n"
-		"IObserver::~IObserver()\n"
-		"\n"
-		""},
-	 { "IObserver_notify", _wrap_IObserver_notify, METH_VARARGS, "\n"
-		"IObserver_notify(IObserver self, IObservable subject)\n"
-		"virtual void IObserver::notify(IObservable *subject)=0\n"
-		"\n"
-		"method which is used by observable subject to notify change in status \n"
-		"\n"
-		""},
-	 { "IObserver_swigregister", IObserver_swigregister, METH_O, NULL},
-	 { "delete_IObservable", _wrap_delete_IObservable, METH_O, "\n"
-		"delete_IObservable(IObservable self)\n"
-		"IObservable::~IObservable()\n"
-		"\n"
-		""},
-	 { "IObservable_attachObserver", _wrap_IObservable_attachObserver, METH_VARARGS, "\n"
-		"IObservable_attachObserver(IObservable self, IObservable::observer_t obj)\n"
-		"void IObservable::attachObserver(observer_t obj)\n"
-		"\n"
-		"attach observer to the list of observers \n"
-		"\n"
-		""},
-	 { "IObservable_notifyObservers", _wrap_IObservable_notifyObservers, METH_O, "\n"
-		"IObservable_notifyObservers(IObservable self)\n"
-		"void IObservable::notifyObservers()\n"
-		"\n"
-		"notify observers about change in status \n"
-		"\n"
-		""},
-	 { "new_IObservable", _wrap_new_IObservable, METH_NOARGS, "\n"
-		"new_IObservable() -> IObservable\n"
-		"\n"
-		"\n"
-		"Observable interface from Observer pattern\n"
-		"\n"
-		"C++ includes: IObserver.h\n"
-		"\n"
-		""},
-	 { "IObservable_swigregister", IObservable_swigregister, METH_O, NULL},
-	 { "IObservable_swiginit", IObservable_swiginit, METH_VARARGS, NULL},
 	 { "new_IterationInfo", _wrap_new_IterationInfo, METH_NOARGS, "\n"
 		"new_IterationInfo() -> IterationInfo\n"
 		"IterationInfo::IterationInfo()\n"
@@ -43827,18 +44574,6 @@ static PyMethodDef SwigMethods[] = {
 		"const IDetector& ISimulation::detector() const\n"
 		"\n"
 		""},
-	 { "ISimulation_setBeamIntensity", _wrap_ISimulation_setBeamIntensity, METH_VARARGS, "\n"
-		"ISimulation_setBeamIntensity(ISimulation self, double intensity)\n"
-		"void ISimulation::setBeamIntensity(double intensity)\n"
-		"\n"
-		""},
-	 { "ISimulation_setBeamPolarization", _wrap_ISimulation_setBeamPolarization, METH_VARARGS, "\n"
-		"ISimulation_setBeamPolarization(ISimulation self, kvector_t bloch_vector)\n"
-		"void ISimulation::setBeamPolarization(const kvector_t bloch_vector)\n"
-		"\n"
-		"Sets the beam polarization according to the given Bloch vector. \n"
-		"\n"
-		""},
 	 { "ISimulation_setDetectorResolutionFunction", _wrap_ISimulation_setDetectorResolutionFunction, METH_VARARGS, "\n"
 		"ISimulation_setDetectorResolutionFunction(ISimulation self, IResolutionFunction2D const & resolution_function)\n"
 		"void ISimulation::setDetectorResolutionFunction(const IResolutionFunction2D &resolution_function)\n"
@@ -44201,64 +44936,64 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { "SpecularSimulation_swigregister", SpecularSimulation_swigregister, METH_O, NULL},
 	 { "SpecularSimulation_swiginit", SpecularSimulation_swiginit, METH_VARARGS, NULL},
-	 { "new_OffSpecSimulation", _wrap_new_OffSpecSimulation, METH_VARARGS, "\n"
-		"OffSpecSimulation(Beam const & beam, MultiLayer const & sample, IDetector const & detector)\n"
-		"new_OffSpecSimulation() -> OffSpecSimulation\n"
-		"OffSpecSimulation::OffSpecSimulation()\n"
+	 { "new_OffSpecularSimulation", _wrap_new_OffSpecularSimulation, METH_VARARGS, "\n"
+		"OffSpecularSimulation(Beam const & beam, MultiLayer const & sample, IDetector const & detector)\n"
+		"new_OffSpecularSimulation() -> OffSpecularSimulation\n"
+		"OffSpecularSimulation::OffSpecularSimulation()\n"
 		"\n"
 		""},
-	 { "delete_OffSpecSimulation", _wrap_delete_OffSpecSimulation, METH_O, "\n"
-		"delete_OffSpecSimulation(OffSpecSimulation self)\n"
-		"OffSpecSimulation::~OffSpecSimulation() override\n"
+	 { "delete_OffSpecularSimulation", _wrap_delete_OffSpecularSimulation, METH_O, "\n"
+		"delete_OffSpecularSimulation(OffSpecularSimulation self)\n"
+		"OffSpecularSimulation::~OffSpecularSimulation() override\n"
 		"\n"
 		""},
-	 { "OffSpecSimulation_clone", _wrap_OffSpecSimulation_clone, METH_O, "\n"
-		"OffSpecSimulation_clone(OffSpecSimulation self) -> OffSpecSimulation\n"
-		"OffSpecSimulation* OffSpecSimulation::clone() const override\n"
+	 { "OffSpecularSimulation_clone", _wrap_OffSpecularSimulation_clone, METH_O, "\n"
+		"OffSpecularSimulation_clone(OffSpecularSimulation self) -> OffSpecularSimulation\n"
+		"OffSpecularSimulation* OffSpecularSimulation::clone() const override\n"
 		"\n"
 		""},
-	 { "OffSpecSimulation_accept", _wrap_OffSpecSimulation_accept, METH_VARARGS, "\n"
-		"OffSpecSimulation_accept(OffSpecSimulation self, INodeVisitor * visitor)\n"
-		"void OffSpecSimulation::accept(INodeVisitor *visitor) const override\n"
+	 { "OffSpecularSimulation_accept", _wrap_OffSpecularSimulation_accept, METH_VARARGS, "\n"
+		"OffSpecularSimulation_accept(OffSpecularSimulation self, INodeVisitor * visitor)\n"
+		"void OffSpecularSimulation::accept(INodeVisitor *visitor) const override\n"
 		"\n"
 		""},
-	 { "OffSpecSimulation_prepareSimulation", _wrap_OffSpecSimulation_prepareSimulation, METH_O, "\n"
-		"OffSpecSimulation_prepareSimulation(OffSpecSimulation self)\n"
-		"void OffSpecSimulation::prepareSimulation() override\n"
+	 { "OffSpecularSimulation_prepareSimulation", _wrap_OffSpecularSimulation_prepareSimulation, METH_O, "\n"
+		"OffSpecularSimulation_prepareSimulation(OffSpecularSimulation self)\n"
+		"void OffSpecularSimulation::prepareSimulation() override\n"
 		"\n"
 		"Put into a clean state for running a simulation. \n"
 		"\n"
 		""},
-	 { "OffSpecSimulation_result", _wrap_OffSpecSimulation_result, METH_O, "\n"
-		"OffSpecSimulation_result(OffSpecSimulation self) -> SimulationResult\n"
-		"SimulationResult OffSpecSimulation::result() const override\n"
+	 { "OffSpecularSimulation_result", _wrap_OffSpecularSimulation_result, METH_O, "\n"
+		"OffSpecularSimulation_result(OffSpecularSimulation self) -> SimulationResult\n"
+		"SimulationResult OffSpecularSimulation::result() const override\n"
 		"\n"
 		"Returns the results of the simulation in a format that supports unit conversion and export to numpy arrays \n"
 		"\n"
 		""},
-	 { "OffSpecSimulation_setBeamParameters", _wrap_OffSpecSimulation_setBeamParameters, METH_VARARGS, "\n"
-		"OffSpecSimulation_setBeamParameters(OffSpecSimulation self, double wavelength, IAxis alpha_axis, double phi_i)\n"
-		"void OffSpecSimulation::setBeamParameters(double wavelength, const IAxis &alpha_axis, double phi_i)\n"
+	 { "OffSpecularSimulation_setBeamParameters", _wrap_OffSpecularSimulation_setBeamParameters, METH_VARARGS, "\n"
+		"OffSpecularSimulation_setBeamParameters(OffSpecularSimulation self, double wavelength, IAxis alpha_axis, double phi_i)\n"
+		"void OffSpecularSimulation::setBeamParameters(double wavelength, const IAxis &alpha_axis, double phi_i)\n"
 		"\n"
 		"Sets beam parameters from here (forwarded to Instrument) \n"
 		"\n"
 		""},
-	 { "OffSpecSimulation_beamAxis", _wrap_OffSpecSimulation_beamAxis, METH_O, "\n"
-		"OffSpecSimulation_beamAxis(OffSpecSimulation self) -> IAxis\n"
-		"const IAxis * OffSpecSimulation::beamAxis() const\n"
+	 { "OffSpecularSimulation_beamAxis", _wrap_OffSpecularSimulation_beamAxis, METH_O, "\n"
+		"OffSpecularSimulation_beamAxis(OffSpecularSimulation self) -> IAxis\n"
+		"const IAxis * OffSpecularSimulation::beamAxis() const\n"
 		"\n"
 		"Returns axis of the beam. \n"
 		"\n"
 		""},
-	 { "OffSpecSimulation_intensityMapSize", _wrap_OffSpecSimulation_intensityMapSize, METH_O, "\n"
-		"OffSpecSimulation_intensityMapSize(OffSpecSimulation self) -> size_t\n"
-		"size_t OffSpecSimulation::intensityMapSize() const override\n"
+	 { "OffSpecularSimulation_intensityMapSize", _wrap_OffSpecularSimulation_intensityMapSize, METH_O, "\n"
+		"OffSpecularSimulation_intensityMapSize(OffSpecularSimulation self) -> size_t\n"
+		"size_t OffSpecularSimulation::intensityMapSize() const override\n"
 		"\n"
 		"Returns the total number of the intensity values in the simulation result. \n"
 		"\n"
 		""},
-	 { "OffSpecSimulation_swigregister", OffSpecSimulation_swigregister, METH_O, NULL},
-	 { "OffSpecSimulation_swiginit", OffSpecSimulation_swiginit, METH_VARARGS, NULL},
+	 { "OffSpecularSimulation_swigregister", OffSpecularSimulation_swigregister, METH_O, NULL},
+	 { "OffSpecularSimulation_swiginit", OffSpecularSimulation_swiginit, METH_VARARGS, NULL},
 	 { "delete_IBackground", _wrap_delete_IBackground, METH_O, "\n"
 		"delete_IBackground(IBackground self)\n"
 		"IBackground::~IBackground()\n"
@@ -44337,6 +45072,193 @@ static PyMethodDef SwigMethods[] = {
 		"std::string ExportToPython::generateSimulationCode(const ISimulation &simulation)\n"
 		"\n"
 		""},
+	 { "delete_IIntensityFunction", _wrap_delete_IIntensityFunction, METH_O, "\n"
+		"delete_IIntensityFunction(IIntensityFunction self)\n"
+		"IIntensityFunction::~IIntensityFunction()\n"
+		"\n"
+		""},
+	 { "IIntensityFunction_clone", _wrap_IIntensityFunction_clone, METH_O, "\n"
+		"IIntensityFunction_clone(IIntensityFunction self) -> IIntensityFunction\n"
+		"virtual IIntensityFunction* IIntensityFunction::clone() const =0\n"
+		"\n"
+		""},
+	 { "IIntensityFunction_evaluate", _wrap_IIntensityFunction_evaluate, METH_VARARGS, "\n"
+		"IIntensityFunction_evaluate(IIntensityFunction self, double value) -> double\n"
+		"virtual double IIntensityFunction::evaluate(double value) const =0\n"
+		"\n"
+		""},
+	 { "IIntensityFunction_swigregister", IIntensityFunction_swigregister, METH_O, NULL},
+	 { "IntensityFunctionLog_clone", _wrap_IntensityFunctionLog_clone, METH_O, "\n"
+		"IntensityFunctionLog_clone(IntensityFunctionLog self) -> IntensityFunctionLog\n"
+		"IntensityFunctionLog * IntensityFunctionLog::clone() const\n"
+		"\n"
+		""},
+	 { "IntensityFunctionLog_evaluate", _wrap_IntensityFunctionLog_evaluate, METH_VARARGS, "\n"
+		"IntensityFunctionLog_evaluate(IntensityFunctionLog self, double value) -> double\n"
+		"double IntensityFunctionLog::evaluate(double value) const\n"
+		"\n"
+		""},
+	 { "new_IntensityFunctionLog", _wrap_new_IntensityFunctionLog, METH_NOARGS, "\n"
+		"new_IntensityFunctionLog() -> IntensityFunctionLog\n"
+		"\n"
+		"\n"
+		"Algorithm for applying log function to the measured intensity.\n"
+		"\n"
+		"C++ includes: IIntensityFunction.h\n"
+		"\n"
+		""},
+	 { "delete_IntensityFunctionLog", _wrap_delete_IntensityFunctionLog, METH_O, "delete_IntensityFunctionLog(IntensityFunctionLog self)"},
+	 { "IntensityFunctionLog_swigregister", IntensityFunctionLog_swigregister, METH_O, NULL},
+	 { "IntensityFunctionLog_swiginit", IntensityFunctionLog_swiginit, METH_VARARGS, NULL},
+	 { "IntensityFunctionSqrt_clone", _wrap_IntensityFunctionSqrt_clone, METH_O, "\n"
+		"IntensityFunctionSqrt_clone(IntensityFunctionSqrt self) -> IntensityFunctionSqrt\n"
+		"IntensityFunctionSqrt * IntensityFunctionSqrt::clone() const\n"
+		"\n"
+		""},
+	 { "IntensityFunctionSqrt_evaluate", _wrap_IntensityFunctionSqrt_evaluate, METH_VARARGS, "\n"
+		"IntensityFunctionSqrt_evaluate(IntensityFunctionSqrt self, double value) -> double\n"
+		"double IntensityFunctionSqrt::evaluate(double value) const\n"
+		"\n"
+		""},
+	 { "new_IntensityFunctionSqrt", _wrap_new_IntensityFunctionSqrt, METH_NOARGS, "\n"
+		"new_IntensityFunctionSqrt() -> IntensityFunctionSqrt\n"
+		"\n"
+		"\n"
+		"Algorithm for applying sqrt function to the measured intensity.\n"
+		"\n"
+		"C++ includes: IIntensityFunction.h\n"
+		"\n"
+		""},
+	 { "delete_IntensityFunctionSqrt", _wrap_delete_IntensityFunctionSqrt, METH_O, "delete_IntensityFunctionSqrt(IntensityFunctionSqrt self)"},
+	 { "IntensityFunctionSqrt_swigregister", IntensityFunctionSqrt_swigregister, METH_O, NULL},
+	 { "IntensityFunctionSqrt_swiginit", IntensityFunctionSqrt_swiginit, METH_VARARGS, NULL},
+	 { "delete_IChiSquaredModule", _wrap_delete_IChiSquaredModule, METH_O, "\n"
+		"delete_IChiSquaredModule(IChiSquaredModule self)\n"
+		"IChiSquaredModule::~IChiSquaredModule()\n"
+		"\n"
+		""},
+	 { "IChiSquaredModule_clone", _wrap_IChiSquaredModule_clone, METH_O, "\n"
+		"IChiSquaredModule_clone(IChiSquaredModule self) -> IChiSquaredModule\n"
+		"virtual IChiSquaredModule* IChiSquaredModule::clone() const =0\n"
+		"\n"
+		"clone method \n"
+		"\n"
+		""},
+	 { "IChiSquaredModule_varianceFunction", _wrap_IChiSquaredModule_varianceFunction, METH_O, "\n"
+		"IChiSquaredModule_varianceFunction(IChiSquaredModule self) -> IVarianceFunction\n"
+		"const IVarianceFunction * IChiSquaredModule::varianceFunction() const\n"
+		"\n"
+		"Returns squared function. \n"
+		"\n"
+		""},
+	 { "IChiSquaredModule_setVarianceFunction", _wrap_IChiSquaredModule_setVarianceFunction, METH_VARARGS, "\n"
+		"IChiSquaredModule_setVarianceFunction(IChiSquaredModule self, IVarianceFunction variance_function)\n"
+		"void IChiSquaredModule::setVarianceFunction(const IVarianceFunction &variance_function)\n"
+		"\n"
+		"Sets squared function. \n"
+		"\n"
+		""},
+	 { "IChiSquaredModule_getIntensityFunction", _wrap_IChiSquaredModule_getIntensityFunction, METH_O, "\n"
+		"IChiSquaredModule_getIntensityFunction(IChiSquaredModule self) -> IIntensityFunction\n"
+		"const IIntensityFunction * IChiSquaredModule::getIntensityFunction() const\n"
+		"\n"
+		"Returns data rescaler. \n"
+		"\n"
+		""},
+	 { "IChiSquaredModule_setIntensityFunction", _wrap_IChiSquaredModule_setIntensityFunction, METH_VARARGS, "\n"
+		"IChiSquaredModule_setIntensityFunction(IChiSquaredModule self, IIntensityFunction intensity_function)\n"
+		"void IChiSquaredModule::setIntensityFunction(const IIntensityFunction &intensity_function)\n"
+		"\n"
+		"Sets data rescaler. \n"
+		"\n"
+		""},
+	 { "IChiSquaredModule_residual", _wrap_IChiSquaredModule_residual, METH_VARARGS, "\n"
+		"IChiSquaredModule_residual(IChiSquaredModule self, double a, double b, double weight) -> double\n"
+		"virtual double IChiSquaredModule::residual(double a, double b, double weight)=0\n"
+		"\n"
+		""},
+	 { "IChiSquaredModule_swigregister", IChiSquaredModule_swigregister, METH_O, NULL},
+	 { "new_ChiSquaredModule", _wrap_new_ChiSquaredModule, METH_VARARGS, "\n"
+		"ChiSquaredModule()\n"
+		"new_ChiSquaredModule(ChiSquaredModule other) -> ChiSquaredModule\n"
+		"ChiSquaredModule::ChiSquaredModule(const ChiSquaredModule &other)\n"
+		"\n"
+		""},
+	 { "delete_ChiSquaredModule", _wrap_delete_ChiSquaredModule, METH_O, "\n"
+		"delete_ChiSquaredModule(ChiSquaredModule self)\n"
+		"virtual ChiSquaredModule::~ChiSquaredModule()\n"
+		"\n"
+		""},
+	 { "ChiSquaredModule_clone", _wrap_ChiSquaredModule_clone, METH_O, "\n"
+		"ChiSquaredModule_clone(ChiSquaredModule self) -> ChiSquaredModule\n"
+		"virtual ChiSquaredModule* ChiSquaredModule::clone() const\n"
+		"\n"
+		"clone method \n"
+		"\n"
+		""},
+	 { "ChiSquaredModule_residual", _wrap_ChiSquaredModule_residual, METH_VARARGS, "\n"
+		"ChiSquaredModule_residual(ChiSquaredModule self, double a, double b, double weight) -> double\n"
+		"double ChiSquaredModule::residual(double a, double b, double weight)\n"
+		"\n"
+		""},
+	 { "ChiSquaredModule_swigregister", ChiSquaredModule_swigregister, METH_O, NULL},
+	 { "ChiSquaredModule_swiginit", ChiSquaredModule_swiginit, METH_VARARGS, NULL},
+	 { "delete_IVarianceFunction", _wrap_delete_IVarianceFunction, METH_O, "\n"
+		"delete_IVarianceFunction(IVarianceFunction self)\n"
+		"virtual IVarianceFunction::~IVarianceFunction()=default\n"
+		"\n"
+		""},
+	 { "IVarianceFunction_clone", _wrap_IVarianceFunction_clone, METH_O, "\n"
+		"IVarianceFunction_clone(IVarianceFunction self) -> IVarianceFunction\n"
+		"virtual IVarianceFunction* IVarianceFunction::clone() const =0\n"
+		"\n"
+		""},
+	 { "IVarianceFunction_variance", _wrap_IVarianceFunction_variance, METH_VARARGS, "\n"
+		"IVarianceFunction_variance(IVarianceFunction self, double real_value, double simulated_value) -> double\n"
+		"virtual double IVarianceFunction::variance(double real_value, double simulated_value) const =0\n"
+		"\n"
+		""},
+	 { "IVarianceFunction_swigregister", IVarianceFunction_swigregister, METH_O, NULL},
+	 { "VarianceConstantFunction_clone", _wrap_VarianceConstantFunction_clone, METH_O, "\n"
+		"VarianceConstantFunction_clone(VarianceConstantFunction self) -> VarianceConstantFunction\n"
+		"VarianceConstantFunction * VarianceConstantFunction::clone() const override\n"
+		"\n"
+		""},
+	 { "VarianceConstantFunction_variance", _wrap_VarianceConstantFunction_variance, METH_VARARGS, "\n"
+		"VarianceConstantFunction_variance(VarianceConstantFunction self, double arg2, double arg3) -> double\n"
+		"double VarianceConstantFunction::variance(double, double) const override\n"
+		"\n"
+		""},
+	 { "new_VarianceConstantFunction", _wrap_new_VarianceConstantFunction, METH_NOARGS, "\n"
+		"new_VarianceConstantFunction() -> VarianceConstantFunction\n"
+		"\n"
+		"\n"
+		"Returns 1.0 as variance value\n"
+		"\n"
+		"C++ includes: VarianceFunctions.h\n"
+		"\n"
+		""},
+	 { "delete_VarianceConstantFunction", _wrap_delete_VarianceConstantFunction, METH_O, "delete_VarianceConstantFunction(VarianceConstantFunction self)"},
+	 { "VarianceConstantFunction_swigregister", VarianceConstantFunction_swigregister, METH_O, NULL},
+	 { "VarianceConstantFunction_swiginit", VarianceConstantFunction_swiginit, METH_VARARGS, NULL},
+	 { "new_VarianceSimFunction", _wrap_new_VarianceSimFunction, METH_VARARGS, "\n"
+		"VarianceSimFunction(double epsilon=1.0)\n"
+		"VarianceSimFunction::VarianceSimFunction(double epsilon=1.0)\n"
+		"\n"
+		""},
+	 { "VarianceSimFunction_clone", _wrap_VarianceSimFunction_clone, METH_O, "\n"
+		"VarianceSimFunction_clone(VarianceSimFunction self) -> VarianceSimFunction\n"
+		"VarianceSimFunction * VarianceSimFunction::clone() const override\n"
+		"\n"
+		""},
+	 { "VarianceSimFunction_variance", _wrap_VarianceSimFunction_variance, METH_VARARGS, "\n"
+		"VarianceSimFunction_variance(VarianceSimFunction self, double exp, double sim) -> double\n"
+		"double VarianceSimFunction::variance(double exp, double sim) const override\n"
+		"\n"
+		""},
+	 { "delete_VarianceSimFunction", _wrap_delete_VarianceSimFunction, METH_O, "delete_VarianceSimFunction(VarianceSimFunction self)"},
+	 { "VarianceSimFunction_swigregister", VarianceSimFunction_swigregister, METH_O, NULL},
+	 { "VarianceSimFunction_swiginit", VarianceSimFunction_swiginit, METH_VARARGS, NULL},
 	 { NULL, NULL, 0, NULL }
 };
 
@@ -44353,6 +45275,9 @@ static void *_p_ConstantBackgroundTo_p_IBackground(void *x, int *SWIGUNUSEDPARM(
 static void *_p_PoissonNoiseBackgroundTo_p_IBackground(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IBackground *)  ((PoissonNoiseBackground *) x));
 }
+static void *_p_ChiSquaredModuleTo_p_IChiSquaredModule(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IChiSquaredModule *)  ((ChiSquaredModule *) x));
+}
 static void *_p_ISimulation2DTo_p_ISimulation(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ISimulation *)  ((ISimulation2D *) x));
 }
@@ -44365,8 +45290,8 @@ static void *_p_DepthProbeSimulationTo_p_ISimulation(void *x, int *SWIGUNUSEDPAR
 static void *_p_SpecularSimulationTo_p_ISimulation(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ISimulation *)  ((SpecularSimulation *) x));
 }
-static void *_p_OffSpecSimulationTo_p_ISimulation(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ISimulation *) (ISimulation2D *) ((OffSpecSimulation *) x));
+static void *_p_OffSpecularSimulationTo_p_ISimulation(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ISimulation *) (ISimulation2D *) ((OffSpecularSimulation *) x));
 }
 static void *_p_AngularSpecScanTo_p_ISpecularScan(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ISpecularScan *)  ((AngularSpecScan *) x));
@@ -44377,8 +45302,8 @@ static void *_p_QSpecScanTo_p_ISpecularScan(void *x, int *SWIGUNUSEDPARM(newmemo
 static void *_p_IFormFactorTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IComponent *) (IParametricComponent *)(INode *)(ISampleNode *) ((IFormFactor *) x));
 }
-static void *_p_OffSpecSimulationTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IComponent *) (IParametricComponent *)(INode *)(ISimulation *)(ISimulation2D *) ((OffSpecSimulation *) x));
+static void *_p_OffSpecularSimulationTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IComponent *) (IParametricComponent *)(INode *)(ISimulation *)(ISimulation2D *) ((OffSpecularSimulation *) x));
 }
 static void *_p_SpecularSimulationTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IComponent *) (IParametricComponent *)(INode *)(ISimulation *) ((SpecularSimulation *) x));
@@ -44422,8 +45347,8 @@ static void *_p_ISimulation2DTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmem
 static void *_p_IFormFactorTo_p_IParametricComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IParametricComponent *) (INode *)(ISampleNode *) ((IFormFactor *) x));
 }
-static void *_p_OffSpecSimulationTo_p_IParametricComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IParametricComponent *) (INode *)(ISimulation *)(ISimulation2D *) ((OffSpecSimulation *) x));
+static void *_p_OffSpecularSimulationTo_p_IParametricComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IParametricComponent *) (INode *)(ISimulation *)(ISimulation2D *) ((OffSpecularSimulation *) x));
 }
 static void *_p_SpecularSimulationTo_p_IParametricComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IParametricComponent *) (INode *)(ISimulation *) ((SpecularSimulation *) x));
@@ -44461,6 +45386,18 @@ static void *_p_ParameterDistributionTo_p_IParametricComponent(void *x, int *SWI
 static void *_p_ISimulation2DTo_p_IParametricComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IParametricComponent *) (INode *)(ISimulation *) ((ISimulation2D *) x));
 }
+static void *_p_VarianceConstantFunctionTo_p_IVarianceFunction(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IVarianceFunction *)  ((VarianceConstantFunction *) 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));
+}
+static void *_p_IntensityFunctionLogTo_p_IIntensityFunction(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IIntensityFunction *)  ((IntensityFunctionLog *) x));
+}
 static void *_p_IFormFactorTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INode *) (ISampleNode *) ((IFormFactor *) x));
 }
@@ -44479,8 +45416,8 @@ static void *_p_DepthProbeSimulationTo_p_INode(void *x, int *SWIGUNUSEDPARM(newm
 static void *_p_SpecularSimulationTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INode *) (ISimulation *) ((SpecularSimulation *) x));
 }
-static void *_p_OffSpecSimulationTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INode *) (ISimulation *)(ISimulation2D *) ((OffSpecSimulation *) x));
+static void *_p_OffSpecularSimulationTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INode *) (ISimulation *)(ISimulation2D *) ((OffSpecularSimulation *) x));
 }
 static void *_p_IBackgroundTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((INode *)  ((IBackground *) x));
@@ -44500,14 +45437,14 @@ static void *_p_IBornFFTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
 static void *_p_GISASSimulationTo_p_ISimulation2D(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ISimulation2D *)  ((GISASSimulation *) x));
 }
-static void *_p_OffSpecSimulationTo_p_ISimulation2D(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ISimulation2D *)  ((OffSpecSimulation *) x));
+static void *_p_OffSpecularSimulationTo_p_ISimulation2D(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ISimulation2D *)  ((OffSpecularSimulation *) x));
 }
 static void *_p_IFormFactorTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ICloneable *) (ISampleNode *) ((IFormFactor *) x));
 }
-static void *_p_OffSpecSimulationTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ICloneable *) (ISimulation *)(ISimulation2D *) ((OffSpecSimulation *) x));
+static void *_p_OffSpecularSimulationTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *) (ISimulation *)(ISimulation2D *) ((OffSpecularSimulation *) x));
 }
 static void *_p_SpecularSimulationTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ICloneable *) (ISimulation *) ((SpecularSimulation *) x));
@@ -44539,6 +45476,12 @@ static void *_p_ISpecularScanTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmem
 static void *_p_IBornFFTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ICloneable *) (ISampleNode *)(IFormFactor *) ((IBornFF *) x));
 }
+static void *_p_IChiSquaredModuleTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *)  ((IChiSquaredModule *) x));
+}
+static void *_p_ChiSquaredModuleTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *) (IChiSquaredModule *) ((ChiSquaredModule *) x));
+}
 static void *_p_ISampleNodeTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ICloneable *)  ((ISampleNode *) x));
 }
@@ -44555,8 +45498,9 @@ static swig_type_info _swigt__p_AngularSpecScan = {"_p_AngularSpecScan", "Angula
 static swig_type_info _swigt__p_AxisInfo = {"_p_AxisInfo", "std::vector< AxisInfo >::value_type *|AxisInfo *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_BasicVector3DT_double_t = {"_p_BasicVector3DT_double_t", "std::vector< BasicVector3D< double > >::value_type *|kvector_t *|BasicVector3D< double > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_BasicVector3DT_int_t = {"_p_BasicVector3DT_int_t", "ivector_t *|BasicVector3D< int > *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_BasicVector3DT_std__complexT_double_t_t = {"_p_BasicVector3DT_std__complexT_double_t_t", "BasicVector3D< std::complex< double > > *|std::vector< BasicVector3D< std::complex< double > > >::value_type *|cvector_t *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_BasicVector3DT_std__complexT_double_t_t = {"_p_BasicVector3DT_std__complexT_double_t_t", "BasicVector3D< std::complex< double > > *|std::vector< BasicVector3D< std::complex< double > > >::value_type *|cvector_t *|BasicVector3D< complex_t > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Beam = {"_p_Beam", "Beam *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_ChiSquaredModule = {"_p_ChiSquaredModule", "ChiSquaredModule *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_ConstantBackground = {"_p_ConstantBackground", "ConstantBackground *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_DepthProbeSimulation = {"_p_DepthProbeSimulation", "DepthProbeSimulation *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_DistributionHandler = {"_p_DistributionHandler", "DistributionHandler *", 0, 0, (void*)0, 0};
@@ -44575,10 +45519,9 @@ static swig_type_info _swigt__p_IDetector = {"_p_IDetector", "IDetector *", 0, 0
 static swig_type_info _swigt__p_IDetector2D = {"_p_IDetector2D", "IDetector2D *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_IDistribution1D = {"_p_IDistribution1D", "IDistribution1D *", 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_IIntensityFunction = {"_p_IIntensityFunction", "IIntensityFunction *", 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};
 static swig_type_info _swigt__p_INodeVisitor = {"_p_INodeVisitor", "INodeVisitor *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_IObservable = {"_p_IObservable", "IObservable *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_IObserver = {"_p_IObserver", "IObserver *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_IParametricComponent = {"_p_IParametricComponent", "IParametricComponent *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_IRangedDistribution = {"_p_IRangedDistribution", "IRangedDistribution *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_IResolutionFunction2D = {"_p_IResolutionFunction2D", "IResolutionFunction2D *", 0, 0, (void*)0, 0};
@@ -44586,10 +45529,13 @@ static swig_type_info _swigt__p_IShape2D = {"_p_IShape2D", "IShape2D *", 0, 0, (
 static swig_type_info _swigt__p_ISimulation = {"_p_ISimulation", "ISimulation *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_ISimulation2D = {"_p_ISimulation2D", "ISimulation2D *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_ISpecularScan = {"_p_ISpecularScan", "ISpecularScan *", 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_Instrument = {"_p_Instrument", "Instrument *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_IntensityFunctionLog = {"_p_IntensityFunctionLog", "IntensityFunctionLog *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_IntensityFunctionSqrt = {"_p_IntensityFunctionSqrt", "IntensityFunctionSqrt *", 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_MultiLayer = {"_p_MultiLayer", "MultiLayer *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_OffSpecSimulation = {"_p_OffSpecSimulation", "OffSpecSimulation *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_OffSpecularSimulation = {"_p_OffSpecularSimulation", "OffSpecularSimulation *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_OutputDataT_double_t = {"_p_OutputDataT_double_t", "OutputData< double > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_ParameterDistribution = {"_p_ParameterDistribution", "ParameterDistribution *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_PoissonNoiseBackground = {"_p_PoissonNoiseBackground", "PoissonNoiseBackground *", 0, 0, (void*)0, 0};
@@ -44602,6 +45548,8 @@ static swig_type_info _swigt__p_ScanResolution = {"_p_ScanResolution", "ScanReso
 static swig_type_info _swigt__p_SimulationOptions = {"_p_SimulationOptions", "SimulationOptions *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_SimulationResult = {"_p_SimulationResult", "SimulationResult *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_SpecularSimulation = {"_p_SpecularSimulation", "SpecularSimulation *", 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_allocator_type = {"_p_allocator_type", "allocator_type *", 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_difference_type = {"_p_difference_type", "difference_type *", 0, 0, (void*)0, 0};
@@ -44612,7 +45560,6 @@ static swig_type_info _swigt__p_long_long = {"_p_long_long", "int_least64_t *|in
 static swig_type_info _swigt__p_mapped_type = {"_p_mapped_type", "mapped_type *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_mumufit__MinimizerResult = {"_p_mumufit__MinimizerResult", "mumufit::MinimizerResult *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_mumufit__Parameters = {"_p_mumufit__Parameters", "mumufit::Parameters *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_observer_t = {"_p_observer_t", "observer_t *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_p_PyObject = {"_p_p_PyObject", "PyObject **", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_second_type = {"_p_second_type", "second_type *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_short = {"_p_short", "short *|int_least16_t *|int16_t *", 0, 0, (void*)0, 0};
@@ -44637,7 +45584,6 @@ static swig_type_info _swigt__p_std__invalid_argument = {"_p_std__invalid_argume
 static swig_type_info _swigt__p_std__lessT_std__string_t = {"_p_std__lessT_std__string_t", "std::less< std::string > *", 0, 0, (void*)0, 0};
 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__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_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__shared_ptrT_ISampleBuilder_t = {"_p_std__shared_ptrT_ISampleBuilder_t", "std::shared_ptr< ISampleBuilder > *", 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};
@@ -44666,6 +45612,7 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_BasicVector3DT_int_t,
   &_swigt__p_BasicVector3DT_std__complexT_double_t_t,
   &_swigt__p_Beam,
+  &_swigt__p_ChiSquaredModule,
   &_swigt__p_ConstantBackground,
   &_swigt__p_DepthProbeSimulation,
   &_swigt__p_DistributionHandler,
@@ -44682,10 +45629,9 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_IDistribution1D,
   &_swigt__p_IFootprintFactor,
   &_swigt__p_IFormFactor,
+  &_swigt__p_IIntensityFunction,
   &_swigt__p_INode,
   &_swigt__p_INodeVisitor,
-  &_swigt__p_IObservable,
-  &_swigt__p_IObserver,
   &_swigt__p_IParametricComponent,
   &_swigt__p_IRangedDistribution,
   &_swigt__p_IResolutionFunction2D,
@@ -44694,10 +45640,13 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_ISimulation,
   &_swigt__p_ISimulation2D,
   &_swigt__p_ISpecularScan,
+  &_swigt__p_IVarianceFunction,
   &_swigt__p_Instrument,
+  &_swigt__p_IntensityFunctionLog,
+  &_swigt__p_IntensityFunctionSqrt,
   &_swigt__p_IterationInfo,
   &_swigt__p_MultiLayer,
-  &_swigt__p_OffSpecSimulation,
+  &_swigt__p_OffSpecularSimulation,
   &_swigt__p_OutputDataT_double_t,
   &_swigt__p_ParameterDistribution,
   &_swigt__p_ParameterPool,
@@ -44711,6 +45660,8 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_SimulationOptions,
   &_swigt__p_SimulationResult,
   &_swigt__p_SpecularSimulation,
+  &_swigt__p_VarianceConstantFunction,
+  &_swigt__p_VarianceSimFunction,
   &_swigt__p_allocator_type,
   &_swigt__p_char,
   &_swigt__p_difference_type,
@@ -44721,7 +45672,6 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_mapped_type,
   &_swigt__p_mumufit__MinimizerResult,
   &_swigt__p_mumufit__Parameters,
-  &_swigt__p_observer_t,
   &_swigt__p_p_PyObject,
   &_swigt__p_second_type,
   &_swigt__p_short,
@@ -44746,7 +45696,6 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_std__lessT_std__string_t,
   &_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__pairT_double_double_t,
-  &_swigt__p_std__shared_ptrT_IObserver_t,
   &_swigt__p_std__shared_ptrT_ISampleBuilder_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,
@@ -44775,6 +45724,7 @@ static swig_cast_info _swigc__p_BasicVector3DT_double_t[] = {  {&_swigt__p_Basic
 static swig_cast_info _swigc__p_BasicVector3DT_int_t[] = {  {&_swigt__p_BasicVector3DT_int_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_BasicVector3DT_std__complexT_double_t_t[] = {  {&_swigt__p_BasicVector3DT_std__complexT_double_t_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_Beam[] = {  {&_swigt__p_Beam, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_ChiSquaredModule[] = {  {&_swigt__p_ChiSquaredModule, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_ConstantBackground[] = {  {&_swigt__p_ConstantBackground, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_DepthProbeSimulation[] = {  {&_swigt__p_DepthProbeSimulation, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_DistributionHandler[] = {  {&_swigt__p_DistributionHandler, 0, 0, 0},{0, 0, 0, 0}};
@@ -44782,32 +45732,34 @@ static swig_cast_info _swigc__p_FitObjective[] = {  {&_swigt__p_FitObjective, 0,
 static swig_cast_info _swigc__p_GISASSimulation[] = {  {&_swigt__p_GISASSimulation, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IAxis[] = {  {&_swigt__p_IAxis, 0, 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},{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_IFormFactor[] = {{&_swigt__p_IFormFactor, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_ParameterPool[] = {{&_swigt__p_ParameterPool, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IBornFF[] = {{&_swigt__p_IBornFF, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_ISampleNode[] = {{&_swigt__p_ISampleNode, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_ICloneable[] = {  {&_swigt__p_IFormFactor, _p_IFormFactorTo_p_ICloneable, 0, 0},  {&_swigt__p_SpecularSimulation, _p_SpecularSimulationTo_p_ICloneable, 0, 0},  {&_swigt__p_DepthProbeSimulation, _p_DepthProbeSimulationTo_p_ICloneable, 0, 0},  {&_swigt__p_OffSpecSimulation, _p_OffSpecSimulationTo_p_ICloneable, 0, 0},  {&_swigt__p_GISASSimulation, _p_GISASSimulationTo_p_ICloneable, 0, 0},  {&_swigt__p_ISimulation, _p_ISimulationTo_p_ICloneable, 0, 0},  {&_swigt__p_ICloneable, 0, 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_ParameterPool, _p_ParameterPoolTo_p_ICloneable, 0, 0},  {&_swigt__p_ISpecularScan, _p_ISpecularScanTo_p_ICloneable, 0, 0},  {&_swigt__p_IBornFF, _p_IBornFFTo_p_ICloneable, 0, 0},  {&_swigt__p_AngularSpecScan, _p_AngularSpecScanTo_p_ICloneable, 0, 0},  {&_swigt__p_QSpecScan, _p_QSpecScanTo_p_ICloneable, 0, 0},  {&_swigt__p_ISampleNode, _p_ISampleNodeTo_p_ICloneable, 0, 0},  {&_swigt__p_ISimulation2D, _p_ISimulation2DTo_p_ICloneable, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_IComponent[] = {  {&_swigt__p_IFormFactor, _p_IFormFactorTo_p_IComponent, 0, 0},  {&_swigt__p_SpecularSimulation, _p_SpecularSimulationTo_p_IComponent, 0, 0},  {&_swigt__p_DepthProbeSimulation, _p_DepthProbeSimulationTo_p_IComponent, 0, 0},  {&_swigt__p_OffSpecSimulation, _p_OffSpecSimulationTo_p_IComponent, 0, 0},  {&_swigt__p_GISASSimulation, _p_GISASSimulationTo_p_IComponent, 0, 0},  {&_swigt__p_ISimulation, _p_ISimulationTo_p_IComponent, 0, 0},  {&_swigt__p_IParametricComponent, _p_IParametricComponentTo_p_IComponent, 0, 0},  {&_swigt__p_IComponent, 0, 0, 0},  {&_swigt__p_PoissonNoiseBackground, _p_PoissonNoiseBackgroundTo_p_IComponent, 0, 0},  {&_swigt__p_ConstantBackground, _p_ConstantBackgroundTo_p_IComponent, 0, 0},  {&_swigt__p_IBackground, _p_IBackgroundTo_p_IComponent, 0, 0},  {&_swigt__p_IBornFF, _p_IBornFFTo_p_IComponent, 0, 0},  {&_swigt__p_ISampleNode, _p_ISampleNodeTo_p_IComponent, 0, 0},  {&_swigt__p_ParameterDistribution, _p_ParameterDistributionTo_p_IComponent, 0, 0},  {&_swigt__p_ISimulation2D, _p_ISimulation2DTo_p_IComponent, 0, 0},  {&_swigt__p_INode, _p_INodeTo_p_IComponent, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_ICloneable[] = {  {&_swigt__p_IFormFactor, _p_IFormFactorTo_p_ICloneable, 0, 0},  {&_swigt__p_SpecularSimulation, _p_SpecularSimulationTo_p_ICloneable, 0, 0},  {&_swigt__p_DepthProbeSimulation, _p_DepthProbeSimulationTo_p_ICloneable, 0, 0},  {&_swigt__p_OffSpecularSimulation, _p_OffSpecularSimulationTo_p_ICloneable, 0, 0},  {&_swigt__p_GISASSimulation, _p_GISASSimulationTo_p_ICloneable, 0, 0},  {&_swigt__p_ISimulation, _p_ISimulationTo_p_ICloneable, 0, 0},  {&_swigt__p_ICloneable, 0, 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_ParameterPool, _p_ParameterPoolTo_p_ICloneable, 0, 0},  {&_swigt__p_ISpecularScan, _p_ISpecularScanTo_p_ICloneable, 0, 0},  {&_swigt__p_IBornFF, _p_IBornFFTo_p_ICloneable, 0, 0},  {&_swigt__p_IChiSquaredModule, _p_IChiSquaredModuleTo_p_ICloneable, 0, 0},  {&_swigt__p_ChiSquaredModule, _p_ChiSquaredModuleTo_p_ICloneable, 0, 0},  {&_swigt__p_AngularSpecScan, _p_AngularSpecScanTo_p_ICloneable, 0, 0},  {&_swigt__p_QSpecScan, _p_QSpecScanTo_p_ICloneable, 0, 0},  {&_swigt__p_ISampleNode, _p_ISampleNodeTo_p_ICloneable, 0, 0},  {&_swigt__p_ISimulation2D, _p_ISimulation2DTo_p_ICloneable, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_IComponent[] = {  {&_swigt__p_IFormFactor, _p_IFormFactorTo_p_IComponent, 0, 0},  {&_swigt__p_SpecularSimulation, _p_SpecularSimulationTo_p_IComponent, 0, 0},  {&_swigt__p_DepthProbeSimulation, _p_DepthProbeSimulationTo_p_IComponent, 0, 0},  {&_swigt__p_OffSpecularSimulation, _p_OffSpecularSimulationTo_p_IComponent, 0, 0},  {&_swigt__p_GISASSimulation, _p_GISASSimulationTo_p_IComponent, 0, 0},  {&_swigt__p_ISimulation, _p_ISimulationTo_p_IComponent, 0, 0},  {&_swigt__p_IParametricComponent, _p_IParametricComponentTo_p_IComponent, 0, 0},  {&_swigt__p_IComponent, 0, 0, 0},  {&_swigt__p_PoissonNoiseBackground, _p_PoissonNoiseBackgroundTo_p_IComponent, 0, 0},  {&_swigt__p_ConstantBackground, _p_ConstantBackgroundTo_p_IComponent, 0, 0},  {&_swigt__p_IBackground, _p_IBackgroundTo_p_IComponent, 0, 0},  {&_swigt__p_IBornFF, _p_IBornFFTo_p_IComponent, 0, 0},  {&_swigt__p_ISampleNode, _p_ISampleNodeTo_p_IComponent, 0, 0},  {&_swigt__p_ParameterDistribution, _p_ParameterDistributionTo_p_IComponent, 0, 0},  {&_swigt__p_ISimulation2D, _p_ISimulation2DTo_p_IComponent, 0, 0},  {&_swigt__p_INode, _p_INodeTo_p_IComponent, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IDetector[] = {  {&_swigt__p_IDetector, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IDetector2D[] = {  {&_swigt__p_IDetector2D, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IDistribution1D[] = {  {&_swigt__p_IDistribution1D, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IFootprintFactor[] = {  {&_swigt__p_IFootprintFactor, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_INode[] = {  {&_swigt__p_INode, 0, 0, 0},  {&_swigt__p_IFormFactor, _p_IFormFactorTo_p_INode, 0, 0},  {&_swigt__p_ISimulation2D, _p_ISimulation2DTo_p_INode, 0, 0},  {&_swigt__p_GISASSimulation, _p_GISASSimulationTo_p_INode, 0, 0},  {&_swigt__p_OffSpecSimulation, _p_OffSpecSimulationTo_p_INode, 0, 0},  {&_swigt__p_ISimulation, _p_ISimulationTo_p_INode, 0, 0},  {&_swigt__p_DepthProbeSimulation, _p_DepthProbeSimulationTo_p_INode, 0, 0},  {&_swigt__p_SpecularSimulation, _p_SpecularSimulationTo_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_ISampleNode, _p_ISampleNodeTo_p_INode, 0, 0},  {&_swigt__p_IBornFF, _p_IBornFFTo_p_INode, 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_INode[] = {  {&_swigt__p_INode, 0, 0, 0},  {&_swigt__p_IFormFactor, _p_IFormFactorTo_p_INode, 0, 0},  {&_swigt__p_ISimulation2D, _p_ISimulation2DTo_p_INode, 0, 0},  {&_swigt__p_GISASSimulation, _p_GISASSimulationTo_p_INode, 0, 0},  {&_swigt__p_OffSpecularSimulation, _p_OffSpecularSimulationTo_p_INode, 0, 0},  {&_swigt__p_ISimulation, _p_ISimulationTo_p_INode, 0, 0},  {&_swigt__p_DepthProbeSimulation, _p_DepthProbeSimulationTo_p_INode, 0, 0},  {&_swigt__p_SpecularSimulation, _p_SpecularSimulationTo_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_ISampleNode, _p_ISampleNodeTo_p_INode, 0, 0},  {&_swigt__p_IBornFF, _p_IBornFFTo_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},{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_IParametricComponent[] = {  {&_swigt__p_IFormFactor, _p_IFormFactorTo_p_IParametricComponent, 0, 0},  {&_swigt__p_SpecularSimulation, _p_SpecularSimulationTo_p_IParametricComponent, 0, 0},  {&_swigt__p_DepthProbeSimulation, _p_DepthProbeSimulationTo_p_IParametricComponent, 0, 0},  {&_swigt__p_OffSpecSimulation, _p_OffSpecSimulationTo_p_IParametricComponent, 0, 0},  {&_swigt__p_GISASSimulation, _p_GISASSimulationTo_p_IParametricComponent, 0, 0},  {&_swigt__p_ISimulation, _p_ISimulationTo_p_IParametricComponent, 0, 0},  {&_swigt__p_IParametricComponent, 0, 0, 0},  {&_swigt__p_PoissonNoiseBackground, _p_PoissonNoiseBackgroundTo_p_IParametricComponent, 0, 0},  {&_swigt__p_ConstantBackground, _p_ConstantBackgroundTo_p_IParametricComponent, 0, 0},  {&_swigt__p_IBackground, _p_IBackgroundTo_p_IParametricComponent, 0, 0},  {&_swigt__p_IBornFF, _p_IBornFFTo_p_IParametricComponent, 0, 0},  {&_swigt__p_ISampleNode, _p_ISampleNodeTo_p_IParametricComponent, 0, 0},  {&_swigt__p_ParameterDistribution, _p_ParameterDistributionTo_p_IParametricComponent, 0, 0},  {&_swigt__p_ISimulation2D, _p_ISimulation2DTo_p_IParametricComponent, 0, 0},  {&_swigt__p_INode, _p_INodeTo_p_IParametricComponent, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_IParametricComponent[] = {  {&_swigt__p_IFormFactor, _p_IFormFactorTo_p_IParametricComponent, 0, 0},  {&_swigt__p_SpecularSimulation, _p_SpecularSimulationTo_p_IParametricComponent, 0, 0},  {&_swigt__p_DepthProbeSimulation, _p_DepthProbeSimulationTo_p_IParametricComponent, 0, 0},  {&_swigt__p_OffSpecularSimulation, _p_OffSpecularSimulationTo_p_IParametricComponent, 0, 0},  {&_swigt__p_GISASSimulation, _p_GISASSimulationTo_p_IParametricComponent, 0, 0},  {&_swigt__p_ISimulation, _p_ISimulationTo_p_IParametricComponent, 0, 0},  {&_swigt__p_IParametricComponent, 0, 0, 0},  {&_swigt__p_PoissonNoiseBackground, _p_PoissonNoiseBackgroundTo_p_IParametricComponent, 0, 0},  {&_swigt__p_ConstantBackground, _p_ConstantBackgroundTo_p_IParametricComponent, 0, 0},  {&_swigt__p_IBackground, _p_IBackgroundTo_p_IParametricComponent, 0, 0},  {&_swigt__p_IBornFF, _p_IBornFFTo_p_IParametricComponent, 0, 0},  {&_swigt__p_ISampleNode, _p_ISampleNodeTo_p_IParametricComponent, 0, 0},  {&_swigt__p_ParameterDistribution, _p_ParameterDistributionTo_p_IParametricComponent, 0, 0},  {&_swigt__p_ISimulation2D, _p_ISimulation2DTo_p_IParametricComponent, 0, 0},  {&_swigt__p_INode, _p_INodeTo_p_IParametricComponent, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IRangedDistribution[] = {  {&_swigt__p_IRangedDistribution, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IResolutionFunction2D[] = {  {&_swigt__p_IResolutionFunction2D, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IShape2D[] = {  {&_swigt__p_IShape2D, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_ISimulation[] = {  {&_swigt__p_ISimulation2D, _p_ISimulation2DTo_p_ISimulation, 0, 0},  {&_swigt__p_ISimulation, 0, 0, 0},  {&_swigt__p_GISASSimulation, _p_GISASSimulationTo_p_ISimulation, 0, 0},  {&_swigt__p_OffSpecSimulation, _p_OffSpecSimulationTo_p_ISimulation, 0, 0},  {&_swigt__p_DepthProbeSimulation, _p_DepthProbeSimulationTo_p_ISimulation, 0, 0},  {&_swigt__p_SpecularSimulation, _p_SpecularSimulationTo_p_ISimulation, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_ISimulation2D[] = {  {&_swigt__p_ISimulation2D, 0, 0, 0},  {&_swigt__p_GISASSimulation, _p_GISASSimulationTo_p_ISimulation2D, 0, 0},  {&_swigt__p_OffSpecSimulation, _p_OffSpecSimulationTo_p_ISimulation2D, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_ISimulation[] = {  {&_swigt__p_ISimulation2D, _p_ISimulation2DTo_p_ISimulation, 0, 0},  {&_swigt__p_ISimulation, 0, 0, 0},  {&_swigt__p_GISASSimulation, _p_GISASSimulationTo_p_ISimulation, 0, 0},  {&_swigt__p_OffSpecularSimulation, _p_OffSpecularSimulationTo_p_ISimulation, 0, 0},  {&_swigt__p_DepthProbeSimulation, _p_DepthProbeSimulationTo_p_ISimulation, 0, 0},  {&_swigt__p_SpecularSimulation, _p_SpecularSimulationTo_p_ISimulation, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_ISimulation2D[] = {  {&_swigt__p_ISimulation2D, 0, 0, 0},  {&_swigt__p_GISASSimulation, _p_GISASSimulationTo_p_ISimulation2D, 0, 0},  {&_swigt__p_OffSpecularSimulation, _p_OffSpecularSimulationTo_p_ISimulation2D, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_ISpecularScan[] = {  {&_swigt__p_AngularSpecScan, _p_AngularSpecScanTo_p_ISpecularScan, 0, 0},  {&_swigt__p_QSpecScan, _p_QSpecScanTo_p_ISpecularScan, 0, 0},  {&_swigt__p_ISpecularScan, 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_Instrument[] = {  {&_swigt__p_Instrument, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_IntensityFunctionLog[] = {  {&_swigt__p_IntensityFunctionLog, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_IntensityFunctionSqrt[] = {  {&_swigt__p_IntensityFunctionSqrt, 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_MultiLayer[] = {  {&_swigt__p_MultiLayer, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_OffSpecSimulation[] = {  {&_swigt__p_OffSpecSimulation, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_OffSpecularSimulation[] = {  {&_swigt__p_OffSpecularSimulation, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_OutputDataT_double_t[] = {  {&_swigt__p_OutputDataT_double_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_ParameterDistribution[] = {  {&_swigt__p_ParameterDistribution, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_PoissonNoiseBackground[] = {  {&_swigt__p_PoissonNoiseBackground, 0, 0, 0},{0, 0, 0, 0}};
@@ -44820,6 +45772,8 @@ static swig_cast_info _swigc__p_ScanResolution[] = {  {&_swigt__p_ScanResolution
 static swig_cast_info _swigc__p_SimulationOptions[] = {  {&_swigt__p_SimulationOptions, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_SimulationResult[] = {  {&_swigt__p_SimulationResult, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_SpecularSimulation[] = {  {&_swigt__p_SpecularSimulation, 0, 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_allocator_type[] = {  {&_swigt__p_allocator_type, 0, 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_difference_type[] = {  {&_swigt__p_difference_type, 0, 0, 0},{0, 0, 0, 0}};
@@ -44830,7 +45784,6 @@ static swig_cast_info _swigc__p_long_long[] = {  {&_swigt__p_long_long, 0, 0, 0}
 static swig_cast_info _swigc__p_mapped_type[] = {  {&_swigt__p_mapped_type, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_mumufit__MinimizerResult[] = {  {&_swigt__p_mumufit__MinimizerResult, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_mumufit__Parameters[] = {  {&_swigt__p_mumufit__Parameters, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_observer_t[] = {  {&_swigt__p_observer_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_p_PyObject[] = {  {&_swigt__p_p_PyObject, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_second_type[] = {  {&_swigt__p_second_type, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_short[] = {  {&_swigt__p_short, 0, 0, 0},{0, 0, 0, 0}};
@@ -44855,7 +45808,6 @@ static swig_cast_info _swigc__p_std__invalid_argument[] = {  {&_swigt__p_std__in
 static swig_cast_info _swigc__p_std__lessT_std__string_t[] = {  {&_swigt__p_std__lessT_std__string_t, 0, 0, 0},{0, 0, 0, 0}};
 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__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_IObserver_t[] = {  {&_swigt__p_std__shared_ptrT_IObserver_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__shared_ptrT_ISampleBuilder_t[] = {  {&_swigt__p_std__shared_ptrT_ISampleBuilder_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}};
@@ -44884,6 +45836,7 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_BasicVector3DT_int_t,
   _swigc__p_BasicVector3DT_std__complexT_double_t_t,
   _swigc__p_Beam,
+  _swigc__p_ChiSquaredModule,
   _swigc__p_ConstantBackground,
   _swigc__p_DepthProbeSimulation,
   _swigc__p_DistributionHandler,
@@ -44900,10 +45853,9 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_IDistribution1D,
   _swigc__p_IFootprintFactor,
   _swigc__p_IFormFactor,
+  _swigc__p_IIntensityFunction,
   _swigc__p_INode,
   _swigc__p_INodeVisitor,
-  _swigc__p_IObservable,
-  _swigc__p_IObserver,
   _swigc__p_IParametricComponent,
   _swigc__p_IRangedDistribution,
   _swigc__p_IResolutionFunction2D,
@@ -44912,10 +45864,13 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_ISimulation,
   _swigc__p_ISimulation2D,
   _swigc__p_ISpecularScan,
+  _swigc__p_IVarianceFunction,
   _swigc__p_Instrument,
+  _swigc__p_IntensityFunctionLog,
+  _swigc__p_IntensityFunctionSqrt,
   _swigc__p_IterationInfo,
   _swigc__p_MultiLayer,
-  _swigc__p_OffSpecSimulation,
+  _swigc__p_OffSpecularSimulation,
   _swigc__p_OutputDataT_double_t,
   _swigc__p_ParameterDistribution,
   _swigc__p_ParameterPool,
@@ -44929,6 +45884,8 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_SimulationOptions,
   _swigc__p_SimulationResult,
   _swigc__p_SpecularSimulation,
+  _swigc__p_VarianceConstantFunction,
+  _swigc__p_VarianceSimFunction,
   _swigc__p_allocator_type,
   _swigc__p_char,
   _swigc__p_difference_type,
@@ -44939,7 +45896,6 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_mapped_type,
   _swigc__p_mumufit__MinimizerResult,
   _swigc__p_mumufit__Parameters,
-  _swigc__p_observer_t,
   _swigc__p_p_PyObject,
   _swigc__p_second_type,
   _swigc__p_short,
@@ -44964,7 +45920,6 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_std__lessT_std__string_t,
   _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__pairT_double_double_t,
-  _swigc__p_std__shared_ptrT_IObserver_t,
   _swigc__p_std__shared_ptrT_ISampleBuilder_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,
diff --git a/auto/Wrap/libBornAgainDevice.py b/auto/Wrap/libBornAgainDevice.py
index 15bb81134b2bff3b13dce40d6c6ce168aea6fa74..dfb747dd7c421ee45c037475a73adec5941fd149 100644
--- a/auto/Wrap/libBornAgainDevice.py
+++ b/auto/Wrap/libBornAgainDevice.py
@@ -2217,7 +2217,7 @@ class IntensityData(object):
     r"""
 
 
-    Template class to store data of any type in multi-dimensional space.
+    Templated class to store data of type double or  CumulativeValue in multi-dimensional space.
 
     C++ includes: OutputData.h
 
@@ -2268,16 +2268,15 @@ class IntensityData(object):
         """
         return _libBornAgainDevice.IntensityData_addAxis(self, *args)
 
-    def axis(self, *args):
+    def axis(self, serial_number):
         r"""
         axis(IntensityData self, size_t serial_number) -> IAxis
-        axis(IntensityData self, std::string const & axis_name) -> IAxis
-        const IAxis & OutputData< T >::axis(const std::string &axis_name) const
+        const IAxis & OutputData< T >::axis(size_t serial_number) const
 
-        returns axis with given name 
+        returns axis with given serial number 
 
         """
-        return _libBornAgainDevice.IntensityData_axis(self, *args)
+        return _libBornAgainDevice.IntensityData_axis(self, serial_number)
 
     def rank(self):
         r"""
@@ -2616,6 +2615,69 @@ class IntensityData(object):
 # Register IntensityData in _libBornAgainDevice:
 _libBornAgainDevice.IntensityData_swigregister(IntensityData)
 
+
+def relativeDataDifference(dat, ref):
+    r"""
+    relativeDataDifference(IntensityData dat, IntensityData ref) -> double
+    double DataUtils::relativeDataDifference(const OutputData< double > &dat, const OutputData< double > &ref)
+
+    Returns relative difference between two data sets sum(dat[i] - ref[i])/ref[i]). 
+
+    """
+    return _libBornAgainDevice.relativeDataDifference(dat, ref)
+
+def checkRelativeDifference(dat, ref, threshold):
+    r"""
+    checkRelativeDifference(IntensityData dat, IntensityData ref, double const threshold) -> bool
+    bool DataUtils::checkRelativeDifference(const OutputData< double > &dat, const OutputData< double > &ref, const double threshold)
+
+    Returns true is relative difference is below threshold; prints informative output. 
+
+    """
+    return _libBornAgainDevice.checkRelativeDifference(dat, ref, threshold)
+
+def coordinateToBinf(*args):
+    r"""
+    coordinateToBinf(double coordinate, IAxis axis) -> double
+    coordinateToBinf(double & x, double & y, IntensityData data)
+    void DataUtils::coordinateToBinf(double &x, double &y, const OutputData< double > &data)
+
+    Transforms x,y coordinate from  OutputData axes coordinates to bin-fraction-coordinates. 
+
+    """
+    return _libBornAgainDevice.coordinateToBinf(*args)
+
+def coordinateFromBinf(*args):
+    r"""
+    coordinateFromBinf(double value, IAxis axis) -> double
+    coordinateFromBinf(double & x, double & y, IntensityData data)
+    void DataUtils::coordinateFromBinf(double &x, double &y, const OutputData< double > &data)
+
+    Transforms x,y coordinate from bin-fraction-coordinates to  OutputData's axes coordinates. 
+
+    """
+    return _libBornAgainDevice.coordinateFromBinf(*args)
+
+def create2DArrayfromOutputData(data):
+    r"""
+    create2DArrayfromOutputData(IntensityData data) -> vdouble2d_t
+    std::vector< std::vector< double > > DataUtils::create2DArrayfromOutputData(const OutputData< double > &data)
+
+    Creates a vector of vectors of double (2D Array) from  OutputData. 
+
+    """
+    return _libBornAgainDevice.create2DArrayfromOutputData(data)
+
+def importArrayToOutputData(*args):
+    r"""
+    importArrayToOutputData(vdouble1d_t vec) -> IntensityData
+    importArrayToOutputData(vdouble2d_t vec) -> IntensityData
+    OutputData< double > * DataUtils::importArrayToOutputData(const std::vector< std::vector< double >> &vec)
+
+    Reads 2D array of doubles to Python, for use in persistence test. 
+
+    """
+    return _libBornAgainDevice.importArrayToOutputData(*args)
 class Beam(libBornAgainParam.INode):
     r"""
 
@@ -2967,132 +3029,6 @@ class FootprintSquare(IFootprintFactor):
 # Register FootprintSquare in _libBornAgainDevice:
 _libBornAgainDevice.FootprintSquare_swigregister(FootprintSquare)
 
-class IIntensityFunction(object):
-    r"""
-
-
-    Interface for applying arbitrary function to the measured intensity.
-
-    C++ includes: IIntensityFunction.h
-
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined - class is abstract")
-    __repr__ = _swig_repr
-    __swig_destroy__ = _libBornAgainDevice.delete_IIntensityFunction
-
-    def clone(self):
-        r"""
-        clone(IIntensityFunction self) -> IIntensityFunction
-        virtual IIntensityFunction* IIntensityFunction::clone() const =0
-
-        """
-        return _libBornAgainDevice.IIntensityFunction_clone(self)
-
-    def evaluate(self, value):
-        r"""
-        evaluate(IIntensityFunction self, double value) -> double
-        virtual double IIntensityFunction::evaluate(double value) const =0
-
-        """
-        return _libBornAgainDevice.IIntensityFunction_evaluate(self, value)
-
-# Register IIntensityFunction in _libBornAgainDevice:
-_libBornAgainDevice.IIntensityFunction_swigregister(IIntensityFunction)
-
-class IntensityFunctionLog(IIntensityFunction):
-    r"""
-
-
-    Algorithm for applying log function to the measured intensity.
-
-    C++ includes: IIntensityFunction.h
-
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def clone(self):
-        r"""
-        clone(IntensityFunctionLog self) -> IntensityFunctionLog
-        IntensityFunctionLog * IntensityFunctionLog::clone() const
-
-        """
-        return _libBornAgainDevice.IntensityFunctionLog_clone(self)
-
-    def evaluate(self, value):
-        r"""
-        evaluate(IntensityFunctionLog self, double value) -> double
-        double IntensityFunctionLog::evaluate(double value) const
-
-        """
-        return _libBornAgainDevice.IntensityFunctionLog_evaluate(self, value)
-
-    def __init__(self):
-        r"""
-        __init__(IntensityFunctionLog self) -> IntensityFunctionLog
-
-
-        Algorithm for applying log function to the measured intensity.
-
-        C++ includes: IIntensityFunction.h
-
-        """
-        _libBornAgainDevice.IntensityFunctionLog_swiginit(self, _libBornAgainDevice.new_IntensityFunctionLog())
-    __swig_destroy__ = _libBornAgainDevice.delete_IntensityFunctionLog
-
-# Register IntensityFunctionLog in _libBornAgainDevice:
-_libBornAgainDevice.IntensityFunctionLog_swigregister(IntensityFunctionLog)
-
-class IntensityFunctionSqrt(IIntensityFunction):
-    r"""
-
-
-    Algorithm for applying sqrt function to the measured intensity.
-
-    C++ includes: IIntensityFunction.h
-
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def clone(self):
-        r"""
-        clone(IntensityFunctionSqrt self) -> IntensityFunctionSqrt
-        IntensityFunctionSqrt * IntensityFunctionSqrt::clone() const
-
-        """
-        return _libBornAgainDevice.IntensityFunctionSqrt_clone(self)
-
-    def evaluate(self, value):
-        r"""
-        evaluate(IntensityFunctionSqrt self, double value) -> double
-        double IntensityFunctionSqrt::evaluate(double value) const
-
-        """
-        return _libBornAgainDevice.IntensityFunctionSqrt_evaluate(self, value)
-
-    def __init__(self):
-        r"""
-        __init__(IntensityFunctionSqrt self) -> IntensityFunctionSqrt
-
-
-        Algorithm for applying sqrt function to the measured intensity.
-
-        C++ includes: IIntensityFunction.h
-
-        """
-        _libBornAgainDevice.IntensityFunctionSqrt_swiginit(self, _libBornAgainDevice.new_IntensityFunctionSqrt())
-    __swig_destroy__ = _libBornAgainDevice.delete_IntensityFunctionSqrt
-
-# Register IntensityFunctionSqrt in _libBornAgainDevice:
-_libBornAgainDevice.IntensityFunctionSqrt_swigregister(IntensityFunctionSqrt)
-
 class IShape2D(libBornAgainBase.ICloneable):
     r"""
 
@@ -3744,342 +3680,6 @@ def ScanResolution_scanAbsoluteResolution(*args):
     """
     return _libBornAgainDevice.ScanResolution_scanAbsoluteResolution(*args)
 
-class IChiSquaredModule(libBornAgainBase.ICloneable):
-    r"""
-
-
-    Interface residual calculations.
-
-    C++ includes: IChiSquaredModule.h
-
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined - class is abstract")
-    __repr__ = _swig_repr
-    __swig_destroy__ = _libBornAgainDevice.delete_IChiSquaredModule
-
-    def clone(self):
-        r"""
-        clone(IChiSquaredModule self) -> IChiSquaredModule
-        virtual IChiSquaredModule* IChiSquaredModule::clone() const =0
-
-        clone method 
-
-        """
-        return _libBornAgainDevice.IChiSquaredModule_clone(self)
-
-    def varianceFunction(self):
-        r"""
-        varianceFunction(IChiSquaredModule self) -> IVarianceFunction
-        const IVarianceFunction * IChiSquaredModule::varianceFunction() const
-
-        Returns squared function. 
-
-        """
-        return _libBornAgainDevice.IChiSquaredModule_varianceFunction(self)
-
-    def setVarianceFunction(self, variance_function):
-        r"""
-        setVarianceFunction(IChiSquaredModule self, IVarianceFunction variance_function)
-        void IChiSquaredModule::setVarianceFunction(const IVarianceFunction &variance_function)
-
-        Sets squared function. 
-
-        """
-        return _libBornAgainDevice.IChiSquaredModule_setVarianceFunction(self, variance_function)
-
-    def getIntensityFunction(self):
-        r"""
-        getIntensityFunction(IChiSquaredModule self) -> IIntensityFunction
-        const IIntensityFunction * IChiSquaredModule::getIntensityFunction() const
-
-        Returns data rescaler. 
-
-        """
-        return _libBornAgainDevice.IChiSquaredModule_getIntensityFunction(self)
-
-    def setIntensityFunction(self, intensity_function):
-        r"""
-        setIntensityFunction(IChiSquaredModule self, IIntensityFunction intensity_function)
-        void IChiSquaredModule::setIntensityFunction(const IIntensityFunction &intensity_function)
-
-        Sets data rescaler. 
-
-        """
-        return _libBornAgainDevice.IChiSquaredModule_setIntensityFunction(self, intensity_function)
-
-    def residual(self, a, b, weight):
-        r"""
-        residual(IChiSquaredModule self, double a, double b, double weight) -> double
-        virtual double IChiSquaredModule::residual(double a, double b, double weight)=0
-
-        """
-        return _libBornAgainDevice.IChiSquaredModule_residual(self, a, b, weight)
-
-# Register IChiSquaredModule in _libBornAgainDevice:
-_libBornAgainDevice.IChiSquaredModule_swigregister(IChiSquaredModule)
-
-class ChiSquaredModule(IChiSquaredModule):
-    r"""
-
-
-    Calculation of chi2 between two data sets.
-
-    C++ includes: ChiSquaredModule.h
-
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def __init__(self, *args):
-        r"""
-        __init__(ChiSquaredModule self) -> ChiSquaredModule
-        __init__(ChiSquaredModule self, ChiSquaredModule other) -> ChiSquaredModule
-        ChiSquaredModule::ChiSquaredModule(const ChiSquaredModule &other)
-
-        """
-        _libBornAgainDevice.ChiSquaredModule_swiginit(self, _libBornAgainDevice.new_ChiSquaredModule(*args))
-    __swig_destroy__ = _libBornAgainDevice.delete_ChiSquaredModule
-
-    def clone(self):
-        r"""
-        clone(ChiSquaredModule self) -> ChiSquaredModule
-        virtual ChiSquaredModule* ChiSquaredModule::clone() const
-
-        clone method 
-
-        """
-        return _libBornAgainDevice.ChiSquaredModule_clone(self)
-
-    def residual(self, a, b, weight):
-        r"""
-        residual(ChiSquaredModule self, double a, double b, double weight) -> double
-        double ChiSquaredModule::residual(double a, double b, double weight)
-
-        """
-        return _libBornAgainDevice.ChiSquaredModule_residual(self, a, b, weight)
-
-# Register ChiSquaredModule in _libBornAgainDevice:
-_libBornAgainDevice.ChiSquaredModule_swigregister(ChiSquaredModule)
-
-
-def RelativeDifference(dat, ref):
-    r"""
-    RelativeDifference(SimulationResult dat, SimulationResult ref) -> double
-    double IntensityDataFunctions::RelativeDifference(const SimulationResult &dat, const SimulationResult &ref)
-
-    Returns sum of relative differences between each pair of elements: (a, b) -> 2*abs(a - b)/(a + b) ( and zero if a-b=0 )
-
-    Returns sum of relative differences between each pair of elements: (a, b) -> 2*abs(a - b)/(|a| + |b|) ( and zero if a=b=0 within epsilon ) 
-
-    """
-    return _libBornAgainDevice.RelativeDifference(dat, ref)
-
-def checkRelativeDifference(dat, ref, threshold):
-    r"""
-    checkRelativeDifference(IntensityData dat, IntensityData ref, double const threshold) -> bool
-    bool IntensityDataFunctions::checkRelativeDifference(const OutputData< double > &dat, const OutputData< double > &ref, const double threshold)
-
-    Returns true is relative difference is below threshold; prints informative output. 
-
-    """
-    return _libBornAgainDevice.checkRelativeDifference(dat, ref, threshold)
-
-def getRelativeDifference(*args):
-    r"""
-    getRelativeDifference(IntensityData dat, IntensityData ref) -> double
-    getRelativeDifference(IHistogram dat, IHistogram ref) -> double
-    double IntensityDataFunctions::getRelativeDifference(const IHistogram &dat, const IHistogram &ref)
-
-    """
-    return _libBornAgainDevice.getRelativeDifference(*args)
-
-def coordinateToBinf(*args):
-    r"""
-    coordinateToBinf(double coordinate, IAxis axis) -> double
-    coordinateToBinf(double & x, double & y, IntensityData data)
-    void IntensityDataFunctions::coordinateToBinf(double &x, double &y, const OutputData< double > &data)
-
-    Transforms x,y coordinate from  OutputData axes coordinates to bin-fraction-coordinates. 
-
-    """
-    return _libBornAgainDevice.coordinateToBinf(*args)
-
-def coordinateFromBinf(*args):
-    r"""
-    coordinateFromBinf(double value, IAxis axis) -> double
-    coordinateFromBinf(double & x, double & y, IntensityData data)
-    void IntensityDataFunctions::coordinateFromBinf(double &x, double &y, const OutputData< double > &data)
-
-    Transforms x,y coordinate from bin-fraction-coordinates to  OutputData's axes coordinates. 
-
-    """
-    return _libBornAgainDevice.coordinateFromBinf(*args)
-
-def create2DArrayfromOutputData(data):
-    r"""
-    create2DArrayfromOutputData(IntensityData data) -> vdouble2d_t
-    std::vector< std::vector< double > > IntensityDataFunctions::create2DArrayfromOutputData(const OutputData< double > &data)
-
-    Creates a vector of vectors of double (2D Array) from  OutputData. 
-
-    """
-    return _libBornAgainDevice.create2DArrayfromOutputData(data)
-
-def FT2DArray(signal):
-    r"""
-    FT2DArray(vdouble2d_t signal) -> vdouble2d_t
-    std::vector< std::vector< double > > IntensityDataFunctions::FT2DArray(const std::vector< std::vector< double >> &signal)
-
-    Creates a Fourier Transform of a 2D Array (vector of vectors). 
-
-    """
-    return _libBornAgainDevice.FT2DArray(signal)
-
-def importArrayToOutputData(*args):
-    r"""
-    importArrayToOutputData(vdouble1d_t vec) -> IntensityData
-    importArrayToOutputData(vdouble2d_t vec) -> IntensityData
-    OutputData< double > * PyArrayImport::importArrayToOutputData(const std::vector< std::vector< double >> &vec)
-
-    for importing 2D array of doubles from python into  OutputData
-
-    """
-    return _libBornAgainDevice.importArrayToOutputData(*args)
-
-def FindPeaks(*args):
-    r"""
-    FindPeaks(Histogram2D hist, double sigma=2, std::string const & option={}, double threshold=0.05) -> vector_pvacuum_double_t
-    std::vector< std::pair< double, double > > SpectrumUtils::FindPeaks(const Histogram2D &hist, double sigma=2, const std::string &option={}, double threshold=0.05)
-
-    """
-    return _libBornAgainDevice.FindPeaks(*args)
-class IVarianceFunction(object):
-    r"""
-
-
-    Variance function interface.
-
-    C++ includes: VarianceFunctions.h
-
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-
-    def __init__(self, *args, **kwargs):
-        raise AttributeError("No constructor defined - class is abstract")
-    __repr__ = _swig_repr
-    __swig_destroy__ = _libBornAgainDevice.delete_IVarianceFunction
-
-    def clone(self):
-        r"""
-        clone(IVarianceFunction self) -> IVarianceFunction
-        virtual IVarianceFunction* IVarianceFunction::clone() const =0
-
-        """
-        return _libBornAgainDevice.IVarianceFunction_clone(self)
-
-    def variance(self, real_value, simulated_value):
-        r"""
-        variance(IVarianceFunction self, double real_value, double simulated_value) -> double
-        virtual double IVarianceFunction::variance(double real_value, double simulated_value) const =0
-
-        """
-        return _libBornAgainDevice.IVarianceFunction_variance(self, real_value, simulated_value)
-
-# Register IVarianceFunction in _libBornAgainDevice:
-_libBornAgainDevice.IVarianceFunction_swigregister(IVarianceFunction)
-
-class VarianceConstantFunction(IVarianceFunction):
-    r"""
-
-
-    Returns 1.0 as variance value
-
-    C++ includes: VarianceFunctions.h
-
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def clone(self):
-        r"""
-        clone(VarianceConstantFunction self) -> VarianceConstantFunction
-        VarianceConstantFunction * VarianceConstantFunction::clone() const override
-
-        """
-        return _libBornAgainDevice.VarianceConstantFunction_clone(self)
-
-    def variance(self, arg2, arg3):
-        r"""
-        variance(VarianceConstantFunction self, double arg2, double arg3) -> double
-        double VarianceConstantFunction::variance(double, double) const override
-
-        """
-        return _libBornAgainDevice.VarianceConstantFunction_variance(self, arg2, arg3)
-
-    def __init__(self):
-        r"""
-        __init__(VarianceConstantFunction self) -> VarianceConstantFunction
-
-
-        Returns 1.0 as variance value
-
-        C++ includes: VarianceFunctions.h
-
-        """
-        _libBornAgainDevice.VarianceConstantFunction_swiginit(self, _libBornAgainDevice.new_VarianceConstantFunction())
-    __swig_destroy__ = _libBornAgainDevice.delete_VarianceConstantFunction
-
-# Register VarianceConstantFunction in _libBornAgainDevice:
-_libBornAgainDevice.VarianceConstantFunction_swigregister(VarianceConstantFunction)
-
-class VarianceSimFunction(IVarianceFunction):
-    r"""
-
-
-    Returns max(sim, epsilon)
-
-    C++ includes: VarianceFunctions.h
-
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def __init__(self, epsilon=1.0):
-        r"""
-        __init__(VarianceSimFunction self, double epsilon=1.0) -> VarianceSimFunction
-        VarianceSimFunction::VarianceSimFunction(double epsilon=1.0)
-
-        """
-        _libBornAgainDevice.VarianceSimFunction_swiginit(self, _libBornAgainDevice.new_VarianceSimFunction(epsilon))
-
-    def clone(self):
-        r"""
-        clone(VarianceSimFunction self) -> VarianceSimFunction
-        VarianceSimFunction * VarianceSimFunction::clone() const override
-
-        """
-        return _libBornAgainDevice.VarianceSimFunction_clone(self)
-
-    def variance(self, exp, sim):
-        r"""
-        variance(VarianceSimFunction self, double exp, double sim) -> double
-        double VarianceSimFunction::variance(double exp, double sim) const override
-
-        """
-        return _libBornAgainDevice.VarianceSimFunction_variance(self, exp, sim)
-    __swig_destroy__ = _libBornAgainDevice.delete_VarianceSimFunction
-
-# Register VarianceSimFunction in _libBornAgainDevice:
-_libBornAgainDevice.VarianceSimFunction_swigregister(VarianceSimFunction)
-
 class Axes(object):
     r"""
 
@@ -4999,6 +4599,36 @@ class IsGISAXSDetector(SphericalDetector):
 # Register IsGISAXSDetector in _libBornAgainDevice:
 _libBornAgainDevice.IsGISAXSDetector_swigregister(IsGISAXSDetector)
 
+
+def FindPeaks(*args):
+    r"""
+    FindPeaks(Histogram2D hist, double sigma=2, std::string const & option={}, double threshold=0.05) -> vector_pvacuum_double_t
+    std::vector< std::pair< double, double > > HistoUtils::FindPeaks(const Histogram2D &hist, double sigma=2, const std::string &option={}, double threshold=0.05)
+
+    Returns vector of peak center coordinates, for peaks in given histogram. 
+
+    """
+    return _libBornAgainDevice.FindPeaks(*args)
+
+def RelativeDifference(dat, ref):
+    r"""
+    RelativeDifference(SimulationResult dat, SimulationResult ref) -> double
+    double HistoUtils::RelativeDifference(const SimulationResult &dat, const SimulationResult &ref)
+
+    Returns sum of relative differences between each pair of elements: (a, b) -> 2*abs(a - b)/(a + b) ( and zero if a-b=0 )
+
+    Returns sum of relative differences between each pair of elements: (a, b) -> 2*abs(a - b)/(|a| + |b|) ( and zero if a=b=0 within epsilon ) 
+
+    """
+    return _libBornAgainDevice.RelativeDifference(dat, ref)
+
+def getRelativeDifference(dat, ref):
+    r"""
+    getRelativeDifference(IHistogram dat, IHistogram ref) -> double
+    double HistoUtils::getRelativeDifference(const IHistogram &dat, const IHistogram &ref)
+
+    """
+    return _libBornAgainDevice.getRelativeDifference(dat, ref)
 class IHistogram(object):
     r"""
 
diff --git a/auto/Wrap/libBornAgainDevice_wrap.cpp b/auto/Wrap/libBornAgainDevice_wrap.cpp
index bfa18e94307cadf43cddd59109f8a8298dcaa4ac..fd5e221a304e2019281c3ce6e457746aed1d9c41 100644
--- a/auto/Wrap/libBornAgainDevice_wrap.cpp
+++ b/auto/Wrap/libBornAgainDevice_wrap.cpp
@@ -3104,121 +3104,113 @@ namespace Swig {
 #define SWIGTYPE_p_BasicVector3DT_std__complexT_double_t_t swig_types[4]
 #define SWIGTYPE_p_Beam swig_types[5]
 #define SWIGTYPE_p_Bin1D swig_types[6]
-#define SWIGTYPE_p_ChiSquaredModule swig_types[7]
-#define SWIGTYPE_p_DetectionProperties swig_types[8]
-#define SWIGTYPE_p_DetectorMask swig_types[9]
-#define SWIGTYPE_p_Direction swig_types[10]
-#define SWIGTYPE_p_Ellipse swig_types[11]
-#define SWIGTYPE_p_FootprintGauss swig_types[12]
-#define SWIGTYPE_p_FootprintSquare swig_types[13]
-#define SWIGTYPE_p_Histogram1D swig_types[14]
-#define SWIGTYPE_p_Histogram2D swig_types[15]
-#define SWIGTYPE_p_HorizontalLine swig_types[16]
-#define SWIGTYPE_p_IAxis swig_types[17]
-#define SWIGTYPE_p_IChiSquaredModule swig_types[18]
-#define SWIGTYPE_p_ICloneable swig_types[19]
-#define SWIGTYPE_p_IComponent swig_types[20]
-#define SWIGTYPE_p_IDetector swig_types[21]
-#define SWIGTYPE_p_IDetector2D swig_types[22]
-#define SWIGTYPE_p_IDetectorResolution swig_types[23]
-#define SWIGTYPE_p_IFootprintFactor swig_types[24]
-#define SWIGTYPE_p_IHistogram swig_types[25]
-#define SWIGTYPE_p_IIntensityFunction swig_types[26]
-#define SWIGTYPE_p_INode swig_types[27]
-#define SWIGTYPE_p_INodeVisitor swig_types[28]
-#define SWIGTYPE_p_IParametricComponent swig_types[29]
-#define SWIGTYPE_p_IPixel swig_types[30]
-#define SWIGTYPE_p_IRangedDistribution swig_types[31]
-#define SWIGTYPE_p_IResolutionFunction2D swig_types[32]
-#define SWIGTYPE_p_IShape2D swig_types[33]
-#define SWIGTYPE_p_IUnitConverter swig_types[34]
-#define SWIGTYPE_p_IVarianceFunction swig_types[35]
-#define SWIGTYPE_p_IntensityDataIOFactory swig_types[36]
-#define SWIGTYPE_p_IntensityFunctionLog swig_types[37]
-#define SWIGTYPE_p_IntensityFunctionSqrt swig_types[38]
-#define SWIGTYPE_p_IsGISAXSDetector swig_types[39]
-#define SWIGTYPE_p_Line swig_types[40]
-#define SWIGTYPE_p_OutputDataIteratorT_double_OutputDataT_double_t_t swig_types[41]
-#define SWIGTYPE_p_OutputDataIteratorT_double_const_OutputDataT_double_t_const_t swig_types[42]
-#define SWIGTYPE_p_OutputDataT_CumulativeValue_t swig_types[43]
-#define SWIGTYPE_p_OutputDataT_bool_t swig_types[44]
-#define SWIGTYPE_p_OutputDataT_double_t swig_types[45]
-#define SWIGTYPE_p_ParameterDistribution swig_types[46]
-#define SWIGTYPE_p_ParameterPool swig_types[47]
-#define SWIGTYPE_p_Polygon swig_types[48]
-#define SWIGTYPE_p_PolygonPrivate swig_types[49]
-#define SWIGTYPE_p_Rectangle swig_types[50]
-#define SWIGTYPE_p_RectangularDetector swig_types[51]
-#define SWIGTYPE_p_RectangularPixel swig_types[52]
-#define SWIGTYPE_p_RegionOfInterest swig_types[53]
-#define SWIGTYPE_p_ResolutionFunction2DGaussian swig_types[54]
-#define SWIGTYPE_p_ScanResolution swig_types[55]
-#define SWIGTYPE_p_SimulationResult swig_types[56]
-#define SWIGTYPE_p_SphericalDetector swig_types[57]
-#define SWIGTYPE_p_VarianceConstantFunction swig_types[58]
-#define SWIGTYPE_p_VarianceSimFunction swig_types[59]
-#define SWIGTYPE_p_VerticalLine swig_types[60]
-#define SWIGTYPE_p_allocator_type swig_types[61]
-#define SWIGTYPE_p_bool swig_types[62]
-#define SWIGTYPE_p_char swig_types[63]
-#define SWIGTYPE_p_const_iterator swig_types[64]
-#define SWIGTYPE_p_corr_matrix_t swig_types[65]
-#define SWIGTYPE_p_difference_type swig_types[66]
-#define SWIGTYPE_p_double swig_types[67]
-#define SWIGTYPE_p_first_type swig_types[68]
-#define SWIGTYPE_p_int swig_types[69]
-#define SWIGTYPE_p_iterator swig_types[70]
-#define SWIGTYPE_p_key_type swig_types[71]
-#define SWIGTYPE_p_long_long swig_types[72]
-#define SWIGTYPE_p_mapped_type swig_types[73]
-#define SWIGTYPE_p_p_PyObject swig_types[74]
-#define SWIGTYPE_p_parameters_t swig_types[75]
-#define SWIGTYPE_p_second_type swig_types[76]
-#define SWIGTYPE_p_short swig_types[77]
-#define SWIGTYPE_p_signed_char swig_types[78]
-#define SWIGTYPE_p_size_type swig_types[79]
-#define SWIGTYPE_p_std__allocatorT_BasicVector3DT_double_t_t swig_types[80]
-#define SWIGTYPE_p_std__allocatorT_BasicVector3DT_std__complexT_double_t_t_t swig_types[81]
-#define SWIGTYPE_p_std__allocatorT_double_t swig_types[82]
-#define SWIGTYPE_p_std__allocatorT_int_t swig_types[83]
-#define SWIGTYPE_p_std__allocatorT_std__complexT_double_t_t swig_types[84]
-#define SWIGTYPE_p_std__allocatorT_std__pairT_double_double_t_t swig_types[85]
-#define SWIGTYPE_p_std__allocatorT_std__pairT_std__string_const_double_t_t swig_types[86]
-#define SWIGTYPE_p_std__allocatorT_std__string_t swig_types[87]
-#define SWIGTYPE_p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t swig_types[88]
-#define SWIGTYPE_p_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t swig_types[89]
-#define SWIGTYPE_p_std__allocatorT_unsigned_long_t swig_types[90]
-#define SWIGTYPE_p_std__complexT_double_t swig_types[91]
-#define SWIGTYPE_p_std__functionT_void_fSimulationAreaIterator_const_RF_t swig_types[92]
-#define SWIGTYPE_p_std__invalid_argument swig_types[93]
-#define SWIGTYPE_p_std__lessT_std__string_t swig_types[94]
-#define SWIGTYPE_p_std__mapT_Axes__Units_char_const_p_std__lessT_Axes__Units_t_std__allocatorT_std__pairT_Axes__Units_const_char_const_p_t_t_t swig_types[95]
-#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[96]
-#define SWIGTYPE_p_std__pairT_double_double_t swig_types[97]
-#define SWIGTYPE_p_std__vectorT_Axes__Units_std__allocatorT_Axes__Units_t_t swig_types[98]
-#define SWIGTYPE_p_std__vectorT_AxisInfo_std__allocatorT_AxisInfo_t_t swig_types[99]
-#define SWIGTYPE_p_std__vectorT_BasicVector3DT_double_t_std__allocatorT_BasicVector3DT_double_t_t_t swig_types[100]
-#define SWIGTYPE_p_std__vectorT_BasicVector3DT_std__complexT_double_t_t_std__allocatorT_BasicVector3DT_std__complexT_double_t_t_t_t swig_types[101]
-#define SWIGTYPE_p_std__vectorT_INode_const_p_std__allocatorT_INode_const_p_t_t swig_types[102]
-#define SWIGTYPE_p_std__vectorT_SimulationElement_std__allocatorT_SimulationElement_t_t swig_types[103]
-#define SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t swig_types[104]
-#define SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t swig_types[105]
-#define SWIGTYPE_p_std__vectorT_size_t_std__allocatorT_size_t_t_t swig_types[106]
-#define SWIGTYPE_p_std__vectorT_std__complexT_double_t_std__allocatorT_std__complexT_double_t_t_t swig_types[107]
-#define SWIGTYPE_p_std__vectorT_std__pairT_double_double_t_std__allocatorT_std__pairT_double_double_t_t_t swig_types[108]
-#define SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t swig_types[109]
-#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[110]
-#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[111]
-#define SWIGTYPE_p_std__vectorT_unsigned_int_std__allocatorT_unsigned_int_t_t swig_types[112]
-#define SWIGTYPE_p_std__vectorT_unsigned_long_std__allocatorT_unsigned_long_t_t swig_types[113]
-#define SWIGTYPE_p_swig__SwigPyIterator swig_types[114]
-#define SWIGTYPE_p_unsigned_char swig_types[115]
-#define SWIGTYPE_p_unsigned_int swig_types[116]
-#define SWIGTYPE_p_unsigned_long_long swig_types[117]
-#define SWIGTYPE_p_unsigned_short swig_types[118]
-#define SWIGTYPE_p_value_type swig_types[119]
-static swig_type_info *swig_types[121];
-static swig_module_info swig_module = {swig_types, 120, 0, 0, 0, 0};
+#define SWIGTYPE_p_DetectionProperties swig_types[7]
+#define SWIGTYPE_p_DetectorMask swig_types[8]
+#define SWIGTYPE_p_Direction swig_types[9]
+#define SWIGTYPE_p_Ellipse swig_types[10]
+#define SWIGTYPE_p_FootprintGauss swig_types[11]
+#define SWIGTYPE_p_FootprintSquare swig_types[12]
+#define SWIGTYPE_p_Histogram1D swig_types[13]
+#define SWIGTYPE_p_Histogram2D swig_types[14]
+#define SWIGTYPE_p_HorizontalLine swig_types[15]
+#define SWIGTYPE_p_IAxis swig_types[16]
+#define SWIGTYPE_p_ICloneable swig_types[17]
+#define SWIGTYPE_p_IComponent swig_types[18]
+#define SWIGTYPE_p_IDetector swig_types[19]
+#define SWIGTYPE_p_IDetector2D swig_types[20]
+#define SWIGTYPE_p_IDetectorResolution swig_types[21]
+#define SWIGTYPE_p_IFootprintFactor swig_types[22]
+#define SWIGTYPE_p_IHistogram swig_types[23]
+#define SWIGTYPE_p_INode swig_types[24]
+#define SWIGTYPE_p_INodeVisitor swig_types[25]
+#define SWIGTYPE_p_IParametricComponent swig_types[26]
+#define SWIGTYPE_p_IPixel swig_types[27]
+#define SWIGTYPE_p_IRangedDistribution swig_types[28]
+#define SWIGTYPE_p_IResolutionFunction2D swig_types[29]
+#define SWIGTYPE_p_IShape2D swig_types[30]
+#define SWIGTYPE_p_IUnitConverter swig_types[31]
+#define SWIGTYPE_p_IntensityDataIOFactory swig_types[32]
+#define SWIGTYPE_p_IsGISAXSDetector swig_types[33]
+#define SWIGTYPE_p_Line swig_types[34]
+#define SWIGTYPE_p_OutputDataIteratorT_double_OutputDataT_double_t_t swig_types[35]
+#define SWIGTYPE_p_OutputDataIteratorT_double_const_OutputDataT_double_t_const_t swig_types[36]
+#define SWIGTYPE_p_OutputDataT_CumulativeValue_t swig_types[37]
+#define SWIGTYPE_p_OutputDataT_bool_t swig_types[38]
+#define SWIGTYPE_p_OutputDataT_double_t swig_types[39]
+#define SWIGTYPE_p_ParameterDistribution swig_types[40]
+#define SWIGTYPE_p_ParameterPool swig_types[41]
+#define SWIGTYPE_p_Polygon swig_types[42]
+#define SWIGTYPE_p_PolygonPrivate swig_types[43]
+#define SWIGTYPE_p_Rectangle swig_types[44]
+#define SWIGTYPE_p_RectangularDetector swig_types[45]
+#define SWIGTYPE_p_RectangularPixel swig_types[46]
+#define SWIGTYPE_p_RegionOfInterest swig_types[47]
+#define SWIGTYPE_p_ResolutionFunction2DGaussian swig_types[48]
+#define SWIGTYPE_p_ScanResolution swig_types[49]
+#define SWIGTYPE_p_SimulationResult swig_types[50]
+#define SWIGTYPE_p_SphericalDetector swig_types[51]
+#define SWIGTYPE_p_VerticalLine swig_types[52]
+#define SWIGTYPE_p_allocator_type swig_types[53]
+#define SWIGTYPE_p_bool swig_types[54]
+#define SWIGTYPE_p_char swig_types[55]
+#define SWIGTYPE_p_const_iterator swig_types[56]
+#define SWIGTYPE_p_corr_matrix_t swig_types[57]
+#define SWIGTYPE_p_difference_type swig_types[58]
+#define SWIGTYPE_p_double swig_types[59]
+#define SWIGTYPE_p_first_type swig_types[60]
+#define SWIGTYPE_p_int swig_types[61]
+#define SWIGTYPE_p_iterator swig_types[62]
+#define SWIGTYPE_p_key_type swig_types[63]
+#define SWIGTYPE_p_long_long swig_types[64]
+#define SWIGTYPE_p_mapped_type swig_types[65]
+#define SWIGTYPE_p_p_PyObject swig_types[66]
+#define SWIGTYPE_p_parameters_t swig_types[67]
+#define SWIGTYPE_p_second_type swig_types[68]
+#define SWIGTYPE_p_short swig_types[69]
+#define SWIGTYPE_p_signed_char swig_types[70]
+#define SWIGTYPE_p_size_type swig_types[71]
+#define SWIGTYPE_p_std__allocatorT_BasicVector3DT_double_t_t swig_types[72]
+#define SWIGTYPE_p_std__allocatorT_BasicVector3DT_std__complexT_double_t_t_t swig_types[73]
+#define SWIGTYPE_p_std__allocatorT_double_t swig_types[74]
+#define SWIGTYPE_p_std__allocatorT_int_t swig_types[75]
+#define SWIGTYPE_p_std__allocatorT_std__complexT_double_t_t swig_types[76]
+#define SWIGTYPE_p_std__allocatorT_std__pairT_double_double_t_t swig_types[77]
+#define SWIGTYPE_p_std__allocatorT_std__pairT_std__string_const_double_t_t swig_types[78]
+#define SWIGTYPE_p_std__allocatorT_std__string_t swig_types[79]
+#define SWIGTYPE_p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t swig_types[80]
+#define SWIGTYPE_p_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t swig_types[81]
+#define SWIGTYPE_p_std__allocatorT_unsigned_long_t swig_types[82]
+#define SWIGTYPE_p_std__complexT_double_t swig_types[83]
+#define SWIGTYPE_p_std__functionT_void_fSimulationAreaIterator_const_RF_t swig_types[84]
+#define SWIGTYPE_p_std__invalid_argument swig_types[85]
+#define SWIGTYPE_p_std__lessT_std__string_t swig_types[86]
+#define SWIGTYPE_p_std__mapT_Axes__Units_char_const_p_std__lessT_Axes__Units_t_std__allocatorT_std__pairT_Axes__Units_const_char_const_p_t_t_t swig_types[87]
+#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[88]
+#define SWIGTYPE_p_std__pairT_double_double_t swig_types[89]
+#define SWIGTYPE_p_std__vectorT_Axes__Units_std__allocatorT_Axes__Units_t_t swig_types[90]
+#define SWIGTYPE_p_std__vectorT_AxisInfo_std__allocatorT_AxisInfo_t_t swig_types[91]
+#define SWIGTYPE_p_std__vectorT_BasicVector3DT_double_t_std__allocatorT_BasicVector3DT_double_t_t_t swig_types[92]
+#define SWIGTYPE_p_std__vectorT_BasicVector3DT_std__complexT_double_t_t_std__allocatorT_BasicVector3DT_std__complexT_double_t_t_t_t swig_types[93]
+#define SWIGTYPE_p_std__vectorT_INode_const_p_std__allocatorT_INode_const_p_t_t swig_types[94]
+#define SWIGTYPE_p_std__vectorT_SimulationElement_std__allocatorT_SimulationElement_t_t swig_types[95]
+#define SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t swig_types[96]
+#define SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t swig_types[97]
+#define SWIGTYPE_p_std__vectorT_size_t_std__allocatorT_size_t_t_t swig_types[98]
+#define SWIGTYPE_p_std__vectorT_std__complexT_double_t_std__allocatorT_std__complexT_double_t_t_t swig_types[99]
+#define SWIGTYPE_p_std__vectorT_std__pairT_double_double_t_std__allocatorT_std__pairT_double_double_t_t_t swig_types[100]
+#define SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t swig_types[101]
+#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[102]
+#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[103]
+#define SWIGTYPE_p_std__vectorT_unsigned_int_std__allocatorT_unsigned_int_t_t swig_types[104]
+#define SWIGTYPE_p_std__vectorT_unsigned_long_std__allocatorT_unsigned_long_t_t swig_types[105]
+#define SWIGTYPE_p_swig__SwigPyIterator swig_types[106]
+#define SWIGTYPE_p_unsigned_char swig_types[107]
+#define SWIGTYPE_p_unsigned_int swig_types[108]
+#define SWIGTYPE_p_unsigned_long_long swig_types[109]
+#define SWIGTYPE_p_unsigned_short swig_types[110]
+#define SWIGTYPE_p_value_type swig_types[111]
+static swig_type_info *swig_types[113];
+static swig_module_info swig_module = {swig_types, 112, 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)
 
@@ -6715,25 +6707,19 @@ SWIGINTERN void std_vector_Sl_std_pair_Sl_double_Sc_double_Sg__Sg__insert__SWIG_
 #include "Device/Beam/Beam.h"
 #include "Device/Beam/FootprintGauss.h"
 #include "Device/Beam/FootprintSquare.h"
+#include "Device/Data/DataUtils.h"
 #include "Device/Data/OutputData.h"
 #include "Device/Detector/DetectorMask.h"
 #include "Device/Detector/IDetector2D.h"
 #include "Device/Detector/IsGISAXSDetector.h"
 #include "Device/Detector/RectangularDetector.h"
 #include "Device/Detector/SphericalDetector.h"
+#include "Device/Histo/HistoUtils.h"
 #include "Device/Histo/Histogram1D.h"
 #include "Device/Histo/Histogram2D.h"
 #include "Device/Histo/IHistogram.h"
 #include "Device/Histo/IntensityDataIOFactory.h"
 #include "Device/Histo/SimulationResult.h"
-#include "Device/Instrument/ChiSquaredModule.h"
-#include "Device/Instrument/IChiSquaredModule.h"
-#include "Device/Instrument/IntensityDataFunctions.h"
-#include "Device/Instrument/PyArrayImportUtils.h"
-#include "Device/Instrument/SpectrumUtils.h"
-#include "Device/Instrument/VarianceFunctions.h"
-#include "Device/Intensity/IIntensityFunction.h"
-#include "Device/Intensity/IIntensityFunction.h"
 #include "Device/Mask/Ellipse.h"
 #include "Device/Mask/IShape2D.h"
 #include "Device/Mask/Line.h"
@@ -24550,7 +24536,7 @@ SWIGINTERN PyObject *_wrap_kvector_t_complex(PyObject *SWIGUNUSEDPARM(self), PyO
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject *swig_obj[1] ;
-  BasicVector3D< std::complex< double > > result;
+  BasicVector3D< complex_t > result;
   
   if (!args) SWIG_fail;
   swig_obj[0] = args;
@@ -24560,7 +24546,7 @@ SWIGINTERN PyObject *_wrap_kvector_t_complex(PyObject *SWIGUNUSEDPARM(self), PyO
   }
   arg1 = reinterpret_cast< BasicVector3D< double > * >(argp1);
   result = ((BasicVector3D< double > const *)arg1)->complex();
-  resultobj = SWIG_NewPointerObj((new BasicVector3D< std::complex< double > >(static_cast< const BasicVector3D< std::complex< double > >& >(result))), SWIGTYPE_p_BasicVector3DT_std__complexT_double_t_t, SWIG_POINTER_OWN |  0 );
+  resultobj = SWIG_NewPointerObj((new BasicVector3D< complex_t >(static_cast< const BasicVector3D< complex_t >& >(result))), SWIGTYPE_p_BasicVector3DT_std__complexT_double_t_t, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -29146,7 +29132,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_IntensityData_axis__SWIG_0(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
+SWIGINTERN PyObject *_wrap_IntensityData_axis(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   OutputData< double > *arg1 = (OutputData< double > *) 0 ;
   size_t arg2 ;
@@ -29154,9 +29140,10 @@ SWIGINTERN PyObject *_wrap_IntensityData_axis__SWIG_0(PyObject *SWIGUNUSEDPARM(s
   int res1 = 0 ;
   size_t val2 ;
   int ecode2 = 0 ;
+  PyObject *swig_obj[2] ;
   IAxis *result = 0 ;
   
-  if ((nobjs < 2) || (nobjs > 2)) SWIG_fail;
+  if (!SWIG_Python_UnpackTuple(args, "IntensityData_axis", 2, 2, swig_obj)) SWIG_fail;
   res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_OutputDataT_double_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntensityData_axis" "', argument " "1"" of type '" "OutputData< double > const *""'"); 
@@ -29175,88 +29162,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_IntensityData_axis__SWIG_1(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
-  PyObject *resultobj = 0;
-  OutputData< double > *arg1 = (OutputData< double > *) 0 ;
-  std::string *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
-  IAxis *result = 0 ;
-  
-  if ((nobjs < 2) || (nobjs > 2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_OutputDataT_double_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntensityData_axis" "', argument " "1"" of type '" "OutputData< double > const *""'"); 
-  }
-  arg1 = reinterpret_cast< OutputData< double > * >(argp1);
-  {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(swig_obj[1], &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IntensityData_axis" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IntensityData_axis" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    arg2 = ptr;
-  }
-  result = (IAxis *) &((OutputData< double > const *)arg1)->axis((std::string const &)*arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IAxis, 0 |  0 );
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IntensityData_axis(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[3] = {
-    0
-  };
-  
-  if (!(argc = SWIG_Python_UnpackTuple(args, "IntensityData_axis", 0, 2, argv))) SWIG_fail;
-  --argc;
-  if (argc == 2) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_OutputDataT_double_t, 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_size_t(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_IntensityData_axis__SWIG_0(self, argc, argv);
-      }
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_OutputDataT_double_t, 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_IntensityData_axis__SWIG_1(self, argc, argv);
-      }
-    }
-  }
-  
-fail:
-  SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'IntensityData_axis'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    OutputData< double >::axis(size_t) const\n"
-    "    OutputData< double >::axis(std::string const &) const\n");
-  return 0;
-}
-
-
 SWIGINTERN PyObject *_wrap_IntensityData_rank(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   OutputData< double > *arg1 = (OutputData< double > *) 0 ;
@@ -30570,6 +30475,456 @@ SWIGINTERN PyObject *IntensityData_swiginit(PyObject *SWIGUNUSEDPARM(self), PyOb
   return SWIG_Python_InitShadowInstance(args);
 }
 
+SWIGINTERN PyObject *_wrap_relativeDataDifference(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  OutputData< double > *arg1 = 0 ;
+  OutputData< double > *arg2 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  PyObject *swig_obj[2] ;
+  double result;
+  
+  if (!SWIG_Python_UnpackTuple(args, "relativeDataDifference", 2, 2, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_OutputDataT_double_t,  0  | 0);
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "relativeDataDifference" "', argument " "1"" of type '" "OutputData< double > const &""'"); 
+  }
+  if (!argp1) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "relativeDataDifference" "', argument " "1"" of type '" "OutputData< double > const &""'"); 
+  }
+  arg1 = reinterpret_cast< OutputData< double > * >(argp1);
+  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_OutputDataT_double_t,  0  | 0);
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "relativeDataDifference" "', argument " "2"" of type '" "OutputData< double > const &""'"); 
+  }
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "relativeDataDifference" "', argument " "2"" of type '" "OutputData< double > const &""'"); 
+  }
+  arg2 = reinterpret_cast< OutputData< double > * >(argp2);
+  result = (double)DataUtils::relativeDataDifference((OutputData< double > const &)*arg1,(OutputData< double > const &)*arg2);
+  resultobj = SWIG_From_double(static_cast< double >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_checkRelativeDifference(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  OutputData< double > *arg1 = 0 ;
+  OutputData< double > *arg2 = 0 ;
+  double arg3 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  double val3 ;
+  int ecode3 = 0 ;
+  PyObject *swig_obj[3] ;
+  bool result;
+  
+  if (!SWIG_Python_UnpackTuple(args, "checkRelativeDifference", 3, 3, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_OutputDataT_double_t,  0  | 0);
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "checkRelativeDifference" "', argument " "1"" of type '" "OutputData< double > const &""'"); 
+  }
+  if (!argp1) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "checkRelativeDifference" "', argument " "1"" of type '" "OutputData< double > const &""'"); 
+  }
+  arg1 = reinterpret_cast< OutputData< double > * >(argp1);
+  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_OutputDataT_double_t,  0  | 0);
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "checkRelativeDifference" "', argument " "2"" of type '" "OutputData< double > const &""'"); 
+  }
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "checkRelativeDifference" "', argument " "2"" of type '" "OutputData< double > const &""'"); 
+  }
+  arg2 = reinterpret_cast< OutputData< double > * >(argp2);
+  ecode3 = SWIG_AsVal_double(swig_obj[2], &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "checkRelativeDifference" "', argument " "3"" of type '" "double""'");
+  } 
+  arg3 = static_cast< double >(val3);
+  result = (bool)DataUtils::checkRelativeDifference((OutputData< double > const &)*arg1,(OutputData< double > const &)*arg2,arg3);
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_coordinateToBinf__SWIG_0(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
+  PyObject *resultobj = 0;
+  double arg1 ;
+  IAxis *arg2 = 0 ;
+  double val1 ;
+  int ecode1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  double result;
+  
+  if ((nobjs < 2) || (nobjs > 2)) SWIG_fail;
+  ecode1 = SWIG_AsVal_double(swig_obj[0], &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "coordinateToBinf" "', argument " "1"" of type '" "double""'");
+  } 
+  arg1 = static_cast< double >(val1);
+  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_IAxis,  0  | 0);
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "coordinateToBinf" "', argument " "2"" of type '" "IAxis const &""'"); 
+  }
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "coordinateToBinf" "', argument " "2"" of type '" "IAxis const &""'"); 
+  }
+  arg2 = reinterpret_cast< IAxis * >(argp2);
+  result = (double)DataUtils::coordinateToBinf(arg1,(IAxis const &)*arg2);
+  resultobj = SWIG_From_double(static_cast< double >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_coordinateFromBinf__SWIG_0(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
+  PyObject *resultobj = 0;
+  double arg1 ;
+  IAxis *arg2 = 0 ;
+  double val1 ;
+  int ecode1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  double result;
+  
+  if ((nobjs < 2) || (nobjs > 2)) SWIG_fail;
+  ecode1 = SWIG_AsVal_double(swig_obj[0], &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "coordinateFromBinf" "', argument " "1"" of type '" "double""'");
+  } 
+  arg1 = static_cast< double >(val1);
+  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_IAxis,  0  | 0);
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "coordinateFromBinf" "', argument " "2"" of type '" "IAxis const &""'"); 
+  }
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "coordinateFromBinf" "', argument " "2"" of type '" "IAxis const &""'"); 
+  }
+  arg2 = reinterpret_cast< IAxis * >(argp2);
+  result = (double)DataUtils::coordinateFromBinf(arg1,(IAxis const &)*arg2);
+  resultobj = SWIG_From_double(static_cast< double >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_coordinateToBinf__SWIG_1(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
+  PyObject *resultobj = 0;
+  double *arg1 = 0 ;
+  double *arg2 = 0 ;
+  OutputData< double > *arg3 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  void *argp3 = 0 ;
+  int res3 = 0 ;
+  
+  if ((nobjs < 3) || (nobjs > 3)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_double,  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "coordinateToBinf" "', argument " "1"" of type '" "double &""'"); 
+  }
+  if (!argp1) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "coordinateToBinf" "', argument " "1"" of type '" "double &""'"); 
+  }
+  arg1 = reinterpret_cast< double * >(argp1);
+  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_double,  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "coordinateToBinf" "', argument " "2"" of type '" "double &""'"); 
+  }
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "coordinateToBinf" "', argument " "2"" of type '" "double &""'"); 
+  }
+  arg2 = reinterpret_cast< double * >(argp2);
+  res3 = SWIG_ConvertPtr(swig_obj[2], &argp3, SWIGTYPE_p_OutputDataT_double_t,  0  | 0);
+  if (!SWIG_IsOK(res3)) {
+    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "coordinateToBinf" "', argument " "3"" of type '" "OutputData< double > const &""'"); 
+  }
+  if (!argp3) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "coordinateToBinf" "', argument " "3"" of type '" "OutputData< double > const &""'"); 
+  }
+  arg3 = reinterpret_cast< OutputData< double > * >(argp3);
+  DataUtils::coordinateToBinf(*arg1,*arg2,(OutputData< double > const &)*arg3);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_coordinateToBinf(PyObject *self, PyObject *args) {
+  Py_ssize_t argc;
+  PyObject *argv[4] = {
+    0
+  };
+  
+  if (!(argc = SWIG_Python_UnpackTuple(args, "coordinateToBinf", 0, 3, argv))) SWIG_fail;
+  --argc;
+  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_IAxis, SWIG_POINTER_NO_NULL | 0);
+      _v = SWIG_CheckState(res);
+      if (_v) {
+        return _wrap_coordinateToBinf__SWIG_0(self, argc, argv);
+      }
+    }
+  }
+  if (argc == 3) {
+    int _v;
+    void *vptr = 0;
+    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_double, SWIG_POINTER_NO_NULL);
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      void *vptr = 0;
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_double, SWIG_POINTER_NO_NULL);
+      _v = SWIG_CheckState(res);
+      if (_v) {
+        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_OutputDataT_double_t, SWIG_POINTER_NO_NULL | 0);
+        _v = SWIG_CheckState(res);
+        if (_v) {
+          return _wrap_coordinateToBinf__SWIG_1(self, argc, argv);
+        }
+      }
+    }
+  }
+  
+fail:
+  SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'coordinateToBinf'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    DataUtils::coordinateToBinf(double,IAxis const &)\n"
+    "    DataUtils::coordinateToBinf(double &,double &,OutputData< double > const &)\n");
+  return 0;
+}
+
+
+SWIGINTERN PyObject *_wrap_coordinateFromBinf__SWIG_1(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
+  PyObject *resultobj = 0;
+  double *arg1 = 0 ;
+  double *arg2 = 0 ;
+  OutputData< double > *arg3 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  void *argp3 = 0 ;
+  int res3 = 0 ;
+  
+  if ((nobjs < 3) || (nobjs > 3)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_double,  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "coordinateFromBinf" "', argument " "1"" of type '" "double &""'"); 
+  }
+  if (!argp1) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "coordinateFromBinf" "', argument " "1"" of type '" "double &""'"); 
+  }
+  arg1 = reinterpret_cast< double * >(argp1);
+  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_double,  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "coordinateFromBinf" "', argument " "2"" of type '" "double &""'"); 
+  }
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "coordinateFromBinf" "', argument " "2"" of type '" "double &""'"); 
+  }
+  arg2 = reinterpret_cast< double * >(argp2);
+  res3 = SWIG_ConvertPtr(swig_obj[2], &argp3, SWIGTYPE_p_OutputDataT_double_t,  0  | 0);
+  if (!SWIG_IsOK(res3)) {
+    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "coordinateFromBinf" "', argument " "3"" of type '" "OutputData< double > const &""'"); 
+  }
+  if (!argp3) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "coordinateFromBinf" "', argument " "3"" of type '" "OutputData< double > const &""'"); 
+  }
+  arg3 = reinterpret_cast< OutputData< double > * >(argp3);
+  DataUtils::coordinateFromBinf(*arg1,*arg2,(OutputData< double > const &)*arg3);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_coordinateFromBinf(PyObject *self, PyObject *args) {
+  Py_ssize_t argc;
+  PyObject *argv[4] = {
+    0
+  };
+  
+  if (!(argc = SWIG_Python_UnpackTuple(args, "coordinateFromBinf", 0, 3, argv))) SWIG_fail;
+  --argc;
+  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_IAxis, SWIG_POINTER_NO_NULL | 0);
+      _v = SWIG_CheckState(res);
+      if (_v) {
+        return _wrap_coordinateFromBinf__SWIG_0(self, argc, argv);
+      }
+    }
+  }
+  if (argc == 3) {
+    int _v;
+    void *vptr = 0;
+    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_double, SWIG_POINTER_NO_NULL);
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      void *vptr = 0;
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_double, SWIG_POINTER_NO_NULL);
+      _v = SWIG_CheckState(res);
+      if (_v) {
+        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_OutputDataT_double_t, SWIG_POINTER_NO_NULL | 0);
+        _v = SWIG_CheckState(res);
+        if (_v) {
+          return _wrap_coordinateFromBinf__SWIG_1(self, argc, argv);
+        }
+      }
+    }
+  }
+  
+fail:
+  SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'coordinateFromBinf'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    DataUtils::coordinateFromBinf(double,IAxis const &)\n"
+    "    DataUtils::coordinateFromBinf(double &,double &,OutputData< double > const &)\n");
+  return 0;
+}
+
+
+SWIGINTERN PyObject *_wrap_create2DArrayfromOutputData(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  OutputData< double > *arg1 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > result;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_OutputDataT_double_t,  0  | 0);
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "create2DArrayfromOutputData" "', argument " "1"" of type '" "OutputData< double > const &""'"); 
+  }
+  if (!argp1) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "create2DArrayfromOutputData" "', argument " "1"" of type '" "OutputData< double > const &""'"); 
+  }
+  arg1 = reinterpret_cast< OutputData< double > * >(argp1);
+  result = DataUtils::create2DArrayfromOutputData((OutputData< double > const &)*arg1);
+  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_importArrayToOutputData__SWIG_0(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
+  PyObject *resultobj = 0;
+  std::vector< double,std::allocator< double > > *arg1 = 0 ;
+  int res1 = SWIG_OLDOBJ ;
+  OutputData< double > *result = 0 ;
+  
+  if ((nobjs < 1) || (nobjs > 1)) SWIG_fail;
+  {
+    std::vector< double,std::allocator< double > > *ptr = (std::vector< double,std::allocator< double > > *)0;
+    res1 = swig::asptr(swig_obj[0], &ptr);
+    if (!SWIG_IsOK(res1)) {
+      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "importArrayToOutputData" "', argument " "1"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "importArrayToOutputData" "', argument " "1"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
+    }
+    arg1 = ptr;
+  }
+  result = (OutputData< double > *)DataUtils::importArrayToOutputData((std::vector< double,std::allocator< double > > const &)*arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_OutputDataT_double_t, SWIG_POINTER_OWN |  0 );
+  if (SWIG_IsNewObj(res1)) delete arg1;
+  return resultobj;
+fail:
+  if (SWIG_IsNewObj(res1)) delete arg1;
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_importArrayToOutputData__SWIG_1(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
+  PyObject *resultobj = 0;
+  std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *arg1 = 0 ;
+  int res1 = SWIG_OLDOBJ ;
+  OutputData< double > *result = 0 ;
+  
+  if ((nobjs < 1) || (nobjs > 1)) SWIG_fail;
+  {
+    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;
+    res1 = swig::asptr(swig_obj[0], &ptr);
+    if (!SWIG_IsOK(res1)) {
+      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "importArrayToOutputData" "', argument " "1"" 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 '" "importArrayToOutputData" "', argument " "1"" of type '" "std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &""'"); 
+    }
+    arg1 = ptr;
+  }
+  result = (OutputData< double > *)DataUtils::importArrayToOutputData((std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &)*arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_OutputDataT_double_t, SWIG_POINTER_OWN |  0 );
+  if (SWIG_IsNewObj(res1)) delete arg1;
+  return resultobj;
+fail:
+  if (SWIG_IsNewObj(res1)) delete arg1;
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_importArrayToOutputData(PyObject *self, PyObject *args) {
+  Py_ssize_t argc;
+  PyObject *argv[2] = {
+    0
+  };
+  
+  if (!(argc = SWIG_Python_UnpackTuple(args, "importArrayToOutputData", 0, 1, argv))) SWIG_fail;
+  --argc;
+  if (argc == 1) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector< double,std::allocator< double > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      return _wrap_importArrayToOutputData__SWIG_0(self, argc, argv);
+    }
+  }
+  if (argc == 1) {
+    int _v;
+    int res = swig::asptr(argv[0], (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_importArrayToOutputData__SWIG_1(self, argc, argv);
+    }
+  }
+  
+fail:
+  SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'importArrayToOutputData'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    DataUtils::importArrayToOutputData(std::vector< double,std::allocator< double > > const &)\n"
+    "    DataUtils::importArrayToOutputData(std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &)\n");
+  return 0;
+}
+
+
 SWIGINTERN PyObject *_wrap_new_Beam__SWIG_0(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
   PyObject *resultobj = 0;
   double arg1 ;
@@ -31726,286 +32081,6 @@ SWIGINTERN PyObject *FootprintSquare_swiginit(PyObject *SWIGUNUSEDPARM(self), Py
   return SWIG_Python_InitShadowInstance(args);
 }
 
-SWIGINTERN PyObject *_wrap_delete_IIntensityFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IIntensityFunction *arg1 = (IIntensityFunction *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IIntensityFunction, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IIntensityFunction" "', argument " "1"" of type '" "IIntensityFunction *""'"); 
-  }
-  arg1 = reinterpret_cast< IIntensityFunction * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IIntensityFunction_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IIntensityFunction *arg1 = (IIntensityFunction *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  IIntensityFunction *result = 0 ;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IIntensityFunction, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IIntensityFunction_clone" "', argument " "1"" of type '" "IIntensityFunction const *""'"); 
-  }
-  arg1 = reinterpret_cast< IIntensityFunction * >(argp1);
-  result = (IIntensityFunction *)((IIntensityFunction const *)arg1)->clone();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IIntensityFunction, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IIntensityFunction_evaluate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IIntensityFunction *arg1 = (IIntensityFunction *) 0 ;
-  double arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  PyObject *swig_obj[2] ;
-  double result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "IIntensityFunction_evaluate", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IIntensityFunction, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IIntensityFunction_evaluate" "', argument " "1"" of type '" "IIntensityFunction const *""'"); 
-  }
-  arg1 = reinterpret_cast< IIntensityFunction * >(argp1);
-  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IIntensityFunction_evaluate" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  result = (double)((IIntensityFunction const *)arg1)->evaluate(arg2);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *IIntensityFunction_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_IIntensityFunction, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *_wrap_IntensityFunctionLog_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IntensityFunctionLog *arg1 = (IntensityFunctionLog *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  IntensityFunctionLog *result = 0 ;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IntensityFunctionLog, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntensityFunctionLog_clone" "', argument " "1"" of type '" "IntensityFunctionLog const *""'"); 
-  }
-  arg1 = reinterpret_cast< IntensityFunctionLog * >(argp1);
-  result = (IntensityFunctionLog *)((IntensityFunctionLog const *)arg1)->clone();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IntensityFunctionLog, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IntensityFunctionLog_evaluate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IntensityFunctionLog *arg1 = (IntensityFunctionLog *) 0 ;
-  double arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  PyObject *swig_obj[2] ;
-  double result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "IntensityFunctionLog_evaluate", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IntensityFunctionLog, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntensityFunctionLog_evaluate" "', argument " "1"" of type '" "IntensityFunctionLog const *""'"); 
-  }
-  arg1 = reinterpret_cast< IntensityFunctionLog * >(argp1);
-  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntensityFunctionLog_evaluate" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  result = (double)((IntensityFunctionLog const *)arg1)->evaluate(arg2);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_IntensityFunctionLog(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IntensityFunctionLog *result = 0 ;
-  
-  if (!SWIG_Python_UnpackTuple(args, "new_IntensityFunctionLog", 0, 0, 0)) SWIG_fail;
-  result = (IntensityFunctionLog *)new IntensityFunctionLog();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IntensityFunctionLog, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_delete_IntensityFunctionLog(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IntensityFunctionLog *arg1 = (IntensityFunctionLog *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &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 *IntensityFunctionLog_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_IntensityFunctionLog, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *IntensityFunctionLog_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  return SWIG_Python_InitShadowInstance(args);
-}
-
-SWIGINTERN PyObject *_wrap_IntensityFunctionSqrt_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IntensityFunctionSqrt *arg1 = (IntensityFunctionSqrt *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  IntensityFunctionSqrt *result = 0 ;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IntensityFunctionSqrt, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntensityFunctionSqrt_clone" "', argument " "1"" of type '" "IntensityFunctionSqrt const *""'"); 
-  }
-  arg1 = reinterpret_cast< IntensityFunctionSqrt * >(argp1);
-  result = (IntensityFunctionSqrt *)((IntensityFunctionSqrt const *)arg1)->clone();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IntensityFunctionSqrt, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IntensityFunctionSqrt_evaluate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IntensityFunctionSqrt *arg1 = (IntensityFunctionSqrt *) 0 ;
-  double arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  PyObject *swig_obj[2] ;
-  double result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "IntensityFunctionSqrt_evaluate", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IntensityFunctionSqrt, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntensityFunctionSqrt_evaluate" "', argument " "1"" of type '" "IntensityFunctionSqrt const *""'"); 
-  }
-  arg1 = reinterpret_cast< IntensityFunctionSqrt * >(argp1);
-  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntensityFunctionSqrt_evaluate" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  result = (double)((IntensityFunctionSqrt const *)arg1)->evaluate(arg2);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_IntensityFunctionSqrt(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IntensityFunctionSqrt *result = 0 ;
-  
-  if (!SWIG_Python_UnpackTuple(args, "new_IntensityFunctionSqrt", 0, 0, 0)) SWIG_fail;
-  result = (IntensityFunctionSqrt *)new IntensityFunctionSqrt();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IntensityFunctionSqrt, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_delete_IntensityFunctionSqrt(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IntensityFunctionSqrt *arg1 = (IntensityFunctionSqrt *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &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 (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_IntensityFunctionSqrt, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *IntensityFunctionSqrt_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  return SWIG_Python_InitShadowInstance(args);
-}
-
 SWIGINTERN PyObject *_wrap_IShape2D_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   IShape2D *arg1 = (IShape2D *) 0 ;
@@ -34758,1572 +34833,6 @@ SWIGINTERN PyObject *ScanResolution_swigregister(PyObject *SWIGUNUSEDPARM(self),
   return SWIG_Py_Void();
 }
 
-SWIGINTERN PyObject *_wrap_delete_IChiSquaredModule(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IChiSquaredModule *arg1 = (IChiSquaredModule *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IChiSquaredModule, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IChiSquaredModule" "', argument " "1"" of type '" "IChiSquaredModule *""'"); 
-  }
-  arg1 = reinterpret_cast< IChiSquaredModule * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IChiSquaredModule_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IChiSquaredModule *arg1 = (IChiSquaredModule *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  IChiSquaredModule *result = 0 ;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IChiSquaredModule, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IChiSquaredModule_clone" "', argument " "1"" of type '" "IChiSquaredModule const *""'"); 
-  }
-  arg1 = reinterpret_cast< IChiSquaredModule * >(argp1);
-  result = (IChiSquaredModule *)((IChiSquaredModule const *)arg1)->clone();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IChiSquaredModule, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IChiSquaredModule_varianceFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IChiSquaredModule *arg1 = (IChiSquaredModule *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  IVarianceFunction *result = 0 ;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IChiSquaredModule, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IChiSquaredModule_varianceFunction" "', argument " "1"" of type '" "IChiSquaredModule const *""'"); 
-  }
-  arg1 = reinterpret_cast< IChiSquaredModule * >(argp1);
-  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_setVarianceFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IChiSquaredModule *arg1 = (IChiSquaredModule *) 0 ;
-  IVarianceFunction *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject *swig_obj[2] ;
-  
-  if (!SWIG_Python_UnpackTuple(args, "IChiSquaredModule_setVarianceFunction", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IChiSquaredModule, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IChiSquaredModule_setVarianceFunction" "', argument " "1"" of type '" "IChiSquaredModule *""'"); 
-  }
-  arg1 = reinterpret_cast< IChiSquaredModule * >(argp1);
-  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_IVarianceFunction,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    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_setVarianceFunction" "', argument " "2"" of type '" "IVarianceFunction const &""'"); 
-  }
-  arg2 = reinterpret_cast< IVarianceFunction * >(argp2);
-  (arg1)->setVarianceFunction((IVarianceFunction const &)*arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IChiSquaredModule_getIntensityFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IChiSquaredModule *arg1 = (IChiSquaredModule *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  IIntensityFunction *result = 0 ;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IChiSquaredModule, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IChiSquaredModule_getIntensityFunction" "', argument " "1"" of type '" "IChiSquaredModule const *""'"); 
-  }
-  arg1 = reinterpret_cast< IChiSquaredModule * >(argp1);
-  result = (IIntensityFunction *)((IChiSquaredModule const *)arg1)->getIntensityFunction();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IIntensityFunction, 0 |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IChiSquaredModule_setIntensityFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IChiSquaredModule *arg1 = (IChiSquaredModule *) 0 ;
-  IIntensityFunction *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject *swig_obj[2] ;
-  
-  if (!SWIG_Python_UnpackTuple(args, "IChiSquaredModule_setIntensityFunction", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IChiSquaredModule, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IChiSquaredModule_setIntensityFunction" "', argument " "1"" of type '" "IChiSquaredModule *""'"); 
-  }
-  arg1 = reinterpret_cast< IChiSquaredModule * >(argp1);
-  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_IIntensityFunction,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IChiSquaredModule_setIntensityFunction" "', argument " "2"" of type '" "IIntensityFunction const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IChiSquaredModule_setIntensityFunction" "', argument " "2"" of type '" "IIntensityFunction const &""'"); 
-  }
-  arg2 = reinterpret_cast< IIntensityFunction * >(argp2);
-  (arg1)->setIntensityFunction((IIntensityFunction const &)*arg2);
-  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 ;
-  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 *swig_obj[4] ;
-  double result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "IChiSquaredModule_residual", 4, 4, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IChiSquaredModule, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IChiSquaredModule_residual" "', argument " "1"" of type '" "IChiSquaredModule *""'"); 
-  }
-  arg1 = reinterpret_cast< IChiSquaredModule * >(argp1);
-  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IChiSquaredModule_residual" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(swig_obj[2], &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IChiSquaredModule_residual" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  ecode4 = SWIG_AsVal_double(swig_obj[3], &val4);
-  if (!SWIG_IsOK(ecode4)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "IChiSquaredModule_residual" "', 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));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *IChiSquaredModule_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_IChiSquaredModule, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *_wrap_new_ChiSquaredModule__SWIG_0(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) {
-  PyObject *resultobj = 0;
-  ChiSquaredModule *result = 0 ;
-  
-  if ((nobjs < 0) || (nobjs > 0)) 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), Py_ssize_t nobjs, PyObject **swig_obj) {
-  PyObject *resultobj = 0;
-  ChiSquaredModule *arg1 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  ChiSquaredModule *result = 0 ;
-  
-  if ((nobjs < 1) || (nobjs > 1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_ChiSquaredModule,  0  | 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 &""'"); 
-  }
-  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_new_ChiSquaredModule(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[2] = {
-    0
-  };
-  
-  if (!(argc = SWIG_Python_UnpackTuple(args, "new_ChiSquaredModule", 0, 1, argv))) SWIG_fail;
-  --argc;
-  if (argc == 0) {
-    return _wrap_new_ChiSquaredModule__SWIG_0(self, argc, argv);
-  }
-  if (argc == 1) {
-    int _v;
-    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_ChiSquaredModule, SWIG_POINTER_NO_NULL | 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_new_ChiSquaredModule__SWIG_1(self, argc, argv);
-    }
-  }
-  
-fail:
-  SWIG_Python_RaiseOrModifyTypeError("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;
-}
-
-
-SWIGINTERN PyObject *_wrap_delete_ChiSquaredModule(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  ChiSquaredModule *arg1 = (ChiSquaredModule *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ChiSquaredModule, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_ChiSquaredModule" "', argument " "1"" of type '" "ChiSquaredModule *""'"); 
-  }
-  arg1 = reinterpret_cast< ChiSquaredModule * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_ChiSquaredModule_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  ChiSquaredModule *arg1 = (ChiSquaredModule *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  ChiSquaredModule *result = 0 ;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &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 *""'"); 
-  }
-  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_ChiSquaredModule_residual(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 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 *swig_obj[4] ;
-  double result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "ChiSquaredModule_residual", 4, 4, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ChiSquaredModule, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ChiSquaredModule_residual" "', argument " "1"" of type '" "ChiSquaredModule *""'"); 
-  }
-  arg1 = reinterpret_cast< ChiSquaredModule * >(argp1);
-  ecode2 = SWIG_AsVal_double(swig_obj[1], &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(swig_obj[2], &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(swig_obj[3], &val4);
-  if (!SWIG_IsOK(ecode4)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "ChiSquaredModule_residual" "', 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));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *ChiSquaredModule_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_ChiSquaredModule, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *ChiSquaredModule_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  return SWIG_Python_InitShadowInstance(args);
-}
-
-SWIGINTERN PyObject *_wrap_RelativeDifference(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  SimulationResult *arg1 = 0 ;
-  SimulationResult *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject *swig_obj[2] ;
-  double result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "RelativeDifference", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_SimulationResult,  0  | 0);
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "RelativeDifference" "', argument " "1"" of type '" "SimulationResult const &""'"); 
-  }
-  if (!argp1) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "RelativeDifference" "', argument " "1"" of type '" "SimulationResult const &""'"); 
-  }
-  arg1 = reinterpret_cast< SimulationResult * >(argp1);
-  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_SimulationResult,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "RelativeDifference" "', argument " "2"" of type '" "SimulationResult const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "RelativeDifference" "', argument " "2"" of type '" "SimulationResult const &""'"); 
-  }
-  arg2 = reinterpret_cast< SimulationResult * >(argp2);
-  result = (double)IntensityDataFunctions::RelativeDifference((SimulationResult const &)*arg1,(SimulationResult const &)*arg2);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_getRelativeDifference__SWIG_0(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
-  PyObject *resultobj = 0;
-  OutputData< double > *arg1 = 0 ;
-  OutputData< double > *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  double result;
-  
-  if ((nobjs < 2) || (nobjs > 2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_OutputDataT_double_t,  0  | 0);
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "getRelativeDifference" "', argument " "1"" of type '" "OutputData< double > const &""'"); 
-  }
-  if (!argp1) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "getRelativeDifference" "', argument " "1"" of type '" "OutputData< double > const &""'"); 
-  }
-  arg1 = reinterpret_cast< OutputData< double > * >(argp1);
-  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_OutputDataT_double_t,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "getRelativeDifference" "', argument " "2"" of type '" "OutputData< double > const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "getRelativeDifference" "', argument " "2"" of type '" "OutputData< double > const &""'"); 
-  }
-  arg2 = reinterpret_cast< OutputData< double > * >(argp2);
-  result = (double)IntensityDataFunctions::getRelativeDifference((OutputData< double > const &)*arg1,(OutputData< double > const &)*arg2);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_checkRelativeDifference(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  OutputData< double > *arg1 = 0 ;
-  OutputData< double > *arg2 = 0 ;
-  double arg3 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
-  PyObject *swig_obj[3] ;
-  bool result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "checkRelativeDifference", 3, 3, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_OutputDataT_double_t,  0  | 0);
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "checkRelativeDifference" "', argument " "1"" of type '" "OutputData< double > const &""'"); 
-  }
-  if (!argp1) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "checkRelativeDifference" "', argument " "1"" of type '" "OutputData< double > const &""'"); 
-  }
-  arg1 = reinterpret_cast< OutputData< double > * >(argp1);
-  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_OutputDataT_double_t,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "checkRelativeDifference" "', argument " "2"" of type '" "OutputData< double > const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "checkRelativeDifference" "', argument " "2"" of type '" "OutputData< double > const &""'"); 
-  }
-  arg2 = reinterpret_cast< OutputData< double > * >(argp2);
-  ecode3 = SWIG_AsVal_double(swig_obj[2], &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "checkRelativeDifference" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  result = (bool)IntensityDataFunctions::checkRelativeDifference((OutputData< double > const &)*arg1,(OutputData< double > const &)*arg2,arg3);
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_getRelativeDifference__SWIG_1(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
-  PyObject *resultobj = 0;
-  IHistogram *arg1 = 0 ;
-  IHistogram *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  double result;
-  
-  if ((nobjs < 2) || (nobjs > 2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_IHistogram,  0  | 0);
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "getRelativeDifference" "', argument " "1"" of type '" "IHistogram const &""'"); 
-  }
-  if (!argp1) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "getRelativeDifference" "', argument " "1"" of type '" "IHistogram const &""'"); 
-  }
-  arg1 = reinterpret_cast< IHistogram * >(argp1);
-  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_IHistogram,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "getRelativeDifference" "', argument " "2"" of type '" "IHistogram const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "getRelativeDifference" "', argument " "2"" of type '" "IHistogram const &""'"); 
-  }
-  arg2 = reinterpret_cast< IHistogram * >(argp2);
-  result = (double)IntensityDataFunctions::getRelativeDifference((IHistogram const &)*arg1,(IHistogram const &)*arg2);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_getRelativeDifference(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[3] = {
-    0
-  };
-  
-  if (!(argc = SWIG_Python_UnpackTuple(args, "getRelativeDifference", 0, 2, argv))) SWIG_fail;
-  --argc;
-  if (argc == 2) {
-    int _v;
-    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_OutputDataT_double_t, SWIG_POINTER_NO_NULL | 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_OutputDataT_double_t, SWIG_POINTER_NO_NULL | 0);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        return _wrap_getRelativeDifference__SWIG_0(self, argc, argv);
-      }
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_IHistogram, SWIG_POINTER_NO_NULL | 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_IHistogram, SWIG_POINTER_NO_NULL | 0);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        return _wrap_getRelativeDifference__SWIG_1(self, argc, argv);
-      }
-    }
-  }
-  
-fail:
-  SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'getRelativeDifference'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    IntensityDataFunctions::getRelativeDifference(OutputData< double > const &,OutputData< double > const &)\n"
-    "    IntensityDataFunctions::getRelativeDifference(IHistogram const &,IHistogram const &)\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_coordinateToBinf__SWIG_0(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
-  PyObject *resultobj = 0;
-  double arg1 ;
-  IAxis *arg2 = 0 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  double result;
-  
-  if ((nobjs < 2) || (nobjs > 2)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(swig_obj[0], &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "coordinateToBinf" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_IAxis,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "coordinateToBinf" "', argument " "2"" of type '" "IAxis const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "coordinateToBinf" "', argument " "2"" of type '" "IAxis const &""'"); 
-  }
-  arg2 = reinterpret_cast< IAxis * >(argp2);
-  result = (double)IntensityDataFunctions::coordinateToBinf(arg1,(IAxis const &)*arg2);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_coordinateFromBinf__SWIG_0(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
-  PyObject *resultobj = 0;
-  double arg1 ;
-  IAxis *arg2 = 0 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  double result;
-  
-  if ((nobjs < 2) || (nobjs > 2)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(swig_obj[0], &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "coordinateFromBinf" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_IAxis,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "coordinateFromBinf" "', argument " "2"" of type '" "IAxis const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "coordinateFromBinf" "', argument " "2"" of type '" "IAxis const &""'"); 
-  }
-  arg2 = reinterpret_cast< IAxis * >(argp2);
-  result = (double)IntensityDataFunctions::coordinateFromBinf(arg1,(IAxis const &)*arg2);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_coordinateToBinf__SWIG_1(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
-  PyObject *resultobj = 0;
-  double *arg1 = 0 ;
-  double *arg2 = 0 ;
-  OutputData< double > *arg3 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  void *argp3 = 0 ;
-  int res3 = 0 ;
-  
-  if ((nobjs < 3) || (nobjs > 3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_double,  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "coordinateToBinf" "', argument " "1"" of type '" "double &""'"); 
-  }
-  if (!argp1) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "coordinateToBinf" "', argument " "1"" of type '" "double &""'"); 
-  }
-  arg1 = reinterpret_cast< double * >(argp1);
-  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_double,  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "coordinateToBinf" "', argument " "2"" of type '" "double &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "coordinateToBinf" "', argument " "2"" of type '" "double &""'"); 
-  }
-  arg2 = reinterpret_cast< double * >(argp2);
-  res3 = SWIG_ConvertPtr(swig_obj[2], &argp3, SWIGTYPE_p_OutputDataT_double_t,  0  | 0);
-  if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "coordinateToBinf" "', argument " "3"" of type '" "OutputData< double > const &""'"); 
-  }
-  if (!argp3) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "coordinateToBinf" "', argument " "3"" of type '" "OutputData< double > const &""'"); 
-  }
-  arg3 = reinterpret_cast< OutputData< double > * >(argp3);
-  IntensityDataFunctions::coordinateToBinf(*arg1,*arg2,(OutputData< double > const &)*arg3);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_coordinateToBinf(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[4] = {
-    0
-  };
-  
-  if (!(argc = SWIG_Python_UnpackTuple(args, "coordinateToBinf", 0, 3, argv))) SWIG_fail;
-  --argc;
-  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_IAxis, SWIG_POINTER_NO_NULL | 0);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        return _wrap_coordinateToBinf__SWIG_0(self, argc, argv);
-      }
-    }
-  }
-  if (argc == 3) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_double, SWIG_POINTER_NO_NULL);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_double, SWIG_POINTER_NO_NULL);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_OutputDataT_double_t, SWIG_POINTER_NO_NULL | 0);
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          return _wrap_coordinateToBinf__SWIG_1(self, argc, argv);
-        }
-      }
-    }
-  }
-  
-fail:
-  SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'coordinateToBinf'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    IntensityDataFunctions::coordinateToBinf(double,IAxis const &)\n"
-    "    IntensityDataFunctions::coordinateToBinf(double &,double &,OutputData< double > const &)\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_coordinateFromBinf__SWIG_1(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
-  PyObject *resultobj = 0;
-  double *arg1 = 0 ;
-  double *arg2 = 0 ;
-  OutputData< double > *arg3 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  void *argp3 = 0 ;
-  int res3 = 0 ;
-  
-  if ((nobjs < 3) || (nobjs > 3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_double,  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "coordinateFromBinf" "', argument " "1"" of type '" "double &""'"); 
-  }
-  if (!argp1) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "coordinateFromBinf" "', argument " "1"" of type '" "double &""'"); 
-  }
-  arg1 = reinterpret_cast< double * >(argp1);
-  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_double,  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "coordinateFromBinf" "', argument " "2"" of type '" "double &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "coordinateFromBinf" "', argument " "2"" of type '" "double &""'"); 
-  }
-  arg2 = reinterpret_cast< double * >(argp2);
-  res3 = SWIG_ConvertPtr(swig_obj[2], &argp3, SWIGTYPE_p_OutputDataT_double_t,  0  | 0);
-  if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "coordinateFromBinf" "', argument " "3"" of type '" "OutputData< double > const &""'"); 
-  }
-  if (!argp3) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "coordinateFromBinf" "', argument " "3"" of type '" "OutputData< double > const &""'"); 
-  }
-  arg3 = reinterpret_cast< OutputData< double > * >(argp3);
-  IntensityDataFunctions::coordinateFromBinf(*arg1,*arg2,(OutputData< double > const &)*arg3);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_coordinateFromBinf(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[4] = {
-    0
-  };
-  
-  if (!(argc = SWIG_Python_UnpackTuple(args, "coordinateFromBinf", 0, 3, argv))) SWIG_fail;
-  --argc;
-  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_IAxis, SWIG_POINTER_NO_NULL | 0);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        return _wrap_coordinateFromBinf__SWIG_0(self, argc, argv);
-      }
-    }
-  }
-  if (argc == 3) {
-    int _v;
-    void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_double, SWIG_POINTER_NO_NULL);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      void *vptr = 0;
-      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_double, SWIG_POINTER_NO_NULL);
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_OutputDataT_double_t, SWIG_POINTER_NO_NULL | 0);
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          return _wrap_coordinateFromBinf__SWIG_1(self, argc, argv);
-        }
-      }
-    }
-  }
-  
-fail:
-  SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'coordinateFromBinf'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    IntensityDataFunctions::coordinateFromBinf(double,IAxis const &)\n"
-    "    IntensityDataFunctions::coordinateFromBinf(double &,double &,OutputData< double > const &)\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_create2DArrayfromOutputData(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  OutputData< double > *arg1 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > result;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_OutputDataT_double_t,  0  | 0);
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "create2DArrayfromOutputData" "', argument " "1"" of type '" "OutputData< double > const &""'"); 
-  }
-  if (!argp1) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "create2DArrayfromOutputData" "', argument " "1"" of type '" "OutputData< double > const &""'"); 
-  }
-  arg1 = reinterpret_cast< OutputData< double > * >(argp1);
-  result = IntensityDataFunctions::create2DArrayfromOutputData((OutputData< double > const &)*arg1);
-  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_FT2DArray(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *arg1 = 0 ;
-  int res1 = SWIG_OLDOBJ ;
-  PyObject *swig_obj[1] ;
-  std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > result;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  {
-    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;
-    res1 = swig::asptr(swig_obj[0], &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FT2DArray" "', argument " "1"" 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 '" "FT2DArray" "', argument " "1"" of type '" "std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &""'"); 
-    }
-    arg1 = ptr;
-  }
-  result = IntensityDataFunctions::FT2DArray((std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &)*arg1);
-  resultobj = swig::from(static_cast< std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > >(result));
-  if (SWIG_IsNewObj(res1)) delete arg1;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_importArrayToOutputData__SWIG_0(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
-  PyObject *resultobj = 0;
-  std::vector< double,std::allocator< double > > *arg1 = 0 ;
-  int res1 = SWIG_OLDOBJ ;
-  OutputData< double > *result = 0 ;
-  
-  if ((nobjs < 1) || (nobjs > 1)) SWIG_fail;
-  {
-    std::vector< double,std::allocator< double > > *ptr = (std::vector< double,std::allocator< double > > *)0;
-    res1 = swig::asptr(swig_obj[0], &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "importArrayToOutputData" "', argument " "1"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "importArrayToOutputData" "', argument " "1"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
-    }
-    arg1 = ptr;
-  }
-  result = (OutputData< double > *)PyArrayImport::importArrayToOutputData((std::vector< double,std::allocator< double > > const &)*arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_OutputDataT_double_t, SWIG_POINTER_OWN |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_importArrayToOutputData__SWIG_1(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
-  PyObject *resultobj = 0;
-  std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *arg1 = 0 ;
-  int res1 = SWIG_OLDOBJ ;
-  OutputData< double > *result = 0 ;
-  
-  if ((nobjs < 1) || (nobjs > 1)) SWIG_fail;
-  {
-    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;
-    res1 = swig::asptr(swig_obj[0], &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "importArrayToOutputData" "', argument " "1"" 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 '" "importArrayToOutputData" "', argument " "1"" of type '" "std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &""'"); 
-    }
-    arg1 = ptr;
-  }
-  result = (OutputData< double > *)PyArrayImport::importArrayToOutputData((std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &)*arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_OutputDataT_double_t, SWIG_POINTER_OWN |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_importArrayToOutputData(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[2] = {
-    0
-  };
-  
-  if (!(argc = SWIG_Python_UnpackTuple(args, "importArrayToOutputData", 0, 1, argv))) SWIG_fail;
-  --argc;
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector< double,std::allocator< double > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_importArrayToOutputData__SWIG_0(self, argc, argv);
-    }
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (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_importArrayToOutputData__SWIG_1(self, argc, argv);
-    }
-  }
-  
-fail:
-  SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'importArrayToOutputData'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    PyArrayImport::importArrayToOutputData(std::vector< double,std::allocator< double > > const &)\n"
-    "    PyArrayImport::importArrayToOutputData(std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &)\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_FindPeaks__SWIG_0(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
-  PyObject *resultobj = 0;
-  Histogram2D *arg1 = 0 ;
-  double arg2 ;
-  std::string *arg3 = 0 ;
-  double arg4 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  int res3 = SWIG_OLDOBJ ;
-  double val4 ;
-  int ecode4 = 0 ;
-  std::vector< std::pair< double,double >,std::allocator< std::pair< double,double > > > result;
-  
-  if ((nobjs < 4) || (nobjs > 4)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_Histogram2D,  0  | 0);
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FindPeaks" "', argument " "1"" of type '" "Histogram2D const &""'"); 
-  }
-  if (!argp1) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FindPeaks" "', argument " "1"" of type '" "Histogram2D const &""'"); 
-  }
-  arg1 = reinterpret_cast< Histogram2D * >(argp1);
-  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FindPeaks" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  {
-    std::string *ptr = (std::string *)0;
-    res3 = SWIG_AsPtr_std_string(swig_obj[2], &ptr);
-    if (!SWIG_IsOK(res3)) {
-      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "FindPeaks" "', argument " "3"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FindPeaks" "', argument " "3"" of type '" "std::string const &""'"); 
-    }
-    arg3 = ptr;
-  }
-  ecode4 = SWIG_AsVal_double(swig_obj[3], &val4);
-  if (!SWIG_IsOK(ecode4)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "FindPeaks" "', argument " "4"" of type '" "double""'");
-  } 
-  arg4 = static_cast< double >(val4);
-  result = SpectrumUtils::FindPeaks((Histogram2D const &)*arg1,arg2,(std::string const &)*arg3,arg4);
-  resultobj = swig::from(static_cast< std::vector< std::pair< double,double >,std::allocator< std::pair< double,double > > > >(result));
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FindPeaks__SWIG_1(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
-  PyObject *resultobj = 0;
-  Histogram2D *arg1 = 0 ;
-  double arg2 ;
-  std::string *arg3 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  int res3 = SWIG_OLDOBJ ;
-  std::vector< std::pair< double,double >,std::allocator< std::pair< double,double > > > result;
-  
-  if ((nobjs < 3) || (nobjs > 3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_Histogram2D,  0  | 0);
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FindPeaks" "', argument " "1"" of type '" "Histogram2D const &""'"); 
-  }
-  if (!argp1) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FindPeaks" "', argument " "1"" of type '" "Histogram2D const &""'"); 
-  }
-  arg1 = reinterpret_cast< Histogram2D * >(argp1);
-  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FindPeaks" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  {
-    std::string *ptr = (std::string *)0;
-    res3 = SWIG_AsPtr_std_string(swig_obj[2], &ptr);
-    if (!SWIG_IsOK(res3)) {
-      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "FindPeaks" "', argument " "3"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FindPeaks" "', argument " "3"" of type '" "std::string const &""'"); 
-    }
-    arg3 = ptr;
-  }
-  result = SpectrumUtils::FindPeaks((Histogram2D const &)*arg1,arg2,(std::string const &)*arg3);
-  resultobj = swig::from(static_cast< std::vector< std::pair< double,double >,std::allocator< std::pair< double,double > > > >(result));
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FindPeaks__SWIG_2(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
-  PyObject *resultobj = 0;
-  Histogram2D *arg1 = 0 ;
-  double arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  std::vector< std::pair< double,double >,std::allocator< std::pair< double,double > > > result;
-  
-  if ((nobjs < 2) || (nobjs > 2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_Histogram2D,  0  | 0);
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FindPeaks" "', argument " "1"" of type '" "Histogram2D const &""'"); 
-  }
-  if (!argp1) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FindPeaks" "', argument " "1"" of type '" "Histogram2D const &""'"); 
-  }
-  arg1 = reinterpret_cast< Histogram2D * >(argp1);
-  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FindPeaks" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  result = SpectrumUtils::FindPeaks((Histogram2D const &)*arg1,arg2);
-  resultobj = swig::from(static_cast< std::vector< std::pair< double,double >,std::allocator< std::pair< double,double > > > >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FindPeaks__SWIG_3(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
-  PyObject *resultobj = 0;
-  Histogram2D *arg1 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  std::vector< std::pair< double,double >,std::allocator< std::pair< double,double > > > result;
-  
-  if ((nobjs < 1) || (nobjs > 1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_Histogram2D,  0  | 0);
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FindPeaks" "', argument " "1"" of type '" "Histogram2D const &""'"); 
-  }
-  if (!argp1) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FindPeaks" "', argument " "1"" of type '" "Histogram2D const &""'"); 
-  }
-  arg1 = reinterpret_cast< Histogram2D * >(argp1);
-  result = SpectrumUtils::FindPeaks((Histogram2D const &)*arg1);
-  resultobj = swig::from(static_cast< std::vector< std::pair< double,double >,std::allocator< std::pair< double,double > > > >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FindPeaks(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[5] = {
-    0
-  };
-  
-  if (!(argc = SWIG_Python_UnpackTuple(args, "FindPeaks", 0, 4, argv))) SWIG_fail;
-  --argc;
-  if (argc == 1) {
-    int _v;
-    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_Histogram2D, SWIG_POINTER_NO_NULL | 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_FindPeaks__SWIG_3(self, argc, argv);
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_Histogram2D, SWIG_POINTER_NO_NULL | 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_double(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_FindPeaks__SWIG_2(self, argc, argv);
-      }
-    }
-  }
-  if (argc == 3) {
-    int _v;
-    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_Histogram2D, SWIG_POINTER_NO_NULL | 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_double(argv[1], NULL);
-        _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_FindPeaks__SWIG_1(self, argc, argv);
-        }
-      }
-    }
-  }
-  if (argc == 4) {
-    int _v;
-    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_Histogram2D, SWIG_POINTER_NO_NULL | 0);
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_double(argv[1], NULL);
-        _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_AsVal_double(argv[3], NULL);
-            _v = SWIG_CheckState(res);
-          }
-          if (_v) {
-            return _wrap_FindPeaks__SWIG_0(self, argc, argv);
-          }
-        }
-      }
-    }
-  }
-  
-fail:
-  SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'FindPeaks'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    SpectrumUtils::FindPeaks(Histogram2D const &,double,std::string const &,double)\n"
-    "    SpectrumUtils::FindPeaks(Histogram2D const &,double,std::string const &)\n"
-    "    SpectrumUtils::FindPeaks(Histogram2D const &,double)\n"
-    "    SpectrumUtils::FindPeaks(Histogram2D const &)\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_delete_IVarianceFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IVarianceFunction *arg1 = (IVarianceFunction *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IVarianceFunction, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IVarianceFunction" "', argument " "1"" of type '" "IVarianceFunction *""'"); 
-  }
-  arg1 = reinterpret_cast< IVarianceFunction * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IVarianceFunction_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IVarianceFunction *arg1 = (IVarianceFunction *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  IVarianceFunction *result = 0 ;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IVarianceFunction, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IVarianceFunction_clone" "', argument " "1"" of type '" "IVarianceFunction const *""'"); 
-  }
-  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_IVarianceFunction_variance(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IVarianceFunction *arg1 = (IVarianceFunction *) 0 ;
-  double arg2 ;
-  double arg3 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
-  PyObject *swig_obj[3] ;
-  double result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "IVarianceFunction_variance", 3, 3, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IVarianceFunction, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IVarianceFunction_variance" "', argument " "1"" of type '" "IVarianceFunction const *""'"); 
-  }
-  arg1 = reinterpret_cast< IVarianceFunction * >(argp1);
-  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IVarianceFunction_variance" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(swig_obj[2], &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IVarianceFunction_variance" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  result = (double)((IVarianceFunction const *)arg1)->variance(arg2,arg3);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *IVarianceFunction_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &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 *swig_obj[1] ;
-  VarianceConstantFunction *result = 0 ;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &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;
-  VarianceConstantFunction *arg1 = (VarianceConstantFunction *) 0 ;
-  double arg2 ;
-  double arg3 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
-  PyObject *swig_obj[3] ;
-  double result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "VarianceConstantFunction_variance", 3, 3, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_VarianceConstantFunction, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarianceConstantFunction_variance" "', argument " "1"" of type '" "VarianceConstantFunction const *""'"); 
-  }
-  arg1 = reinterpret_cast< VarianceConstantFunction * >(argp1);
-  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarianceConstantFunction_variance" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(swig_obj[2], &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VarianceConstantFunction_variance" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  result = (double)((VarianceConstantFunction const *)arg1)->variance(arg2,arg3);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_VarianceConstantFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  VarianceConstantFunction *result = 0 ;
-  
-  if (!SWIG_Python_UnpackTuple(args, "new_VarianceConstantFunction", 0, 0, 0)) 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_delete_VarianceConstantFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  VarianceConstantFunction *arg1 = (VarianceConstantFunction *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &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:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *VarianceConstantFunction_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_VarianceConstantFunction, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *VarianceConstantFunction_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  return SWIG_Python_InitShadowInstance(args);
-}
-
-SWIGINTERN PyObject *_wrap_new_VarianceSimFunction__SWIG_0(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
-  PyObject *resultobj = 0;
-  double arg1 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  VarianceSimFunction *result = 0 ;
-  
-  if ((nobjs < 1) || (nobjs > 1)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(swig_obj[0], &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_new_VarianceSimFunction__SWIG_1(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) {
-  PyObject *resultobj = 0;
-  VarianceSimFunction *result = 0 ;
-  
-  if ((nobjs < 0) || (nobjs > 0)) 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_new_VarianceSimFunction(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[2] = {
-    0
-  };
-  
-  if (!(argc = SWIG_Python_UnpackTuple(args, "new_VarianceSimFunction", 0, 1, argv))) SWIG_fail;
-  --argc;
-  if (argc == 0) {
-    return _wrap_new_VarianceSimFunction__SWIG_1(self, argc, argv);
-  }
-  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, argc, argv);
-    }
-  }
-  
-fail:
-  SWIG_Python_RaiseOrModifyTypeError("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;
-  VarianceSimFunction *arg1 = (VarianceSimFunction *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  VarianceSimFunction *result = 0 ;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_VarianceSimFunction, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarianceSimFunction_clone" "', argument " "1"" of type '" "VarianceSimFunction const *""'"); 
-  }
-  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_VarianceSimFunction_variance(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  VarianceSimFunction *arg1 = (VarianceSimFunction *) 0 ;
-  double arg2 ;
-  double arg3 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
-  PyObject *swig_obj[3] ;
-  double result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "VarianceSimFunction_variance", 3, 3, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_VarianceSimFunction, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarianceSimFunction_variance" "', argument " "1"" of type '" "VarianceSimFunction const *""'"); 
-  }
-  arg1 = reinterpret_cast< VarianceSimFunction * >(argp1);
-  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarianceSimFunction_variance" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(swig_obj[2], &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VarianceSimFunction_variance" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  result = (double)((VarianceSimFunction const *)arg1)->variance(arg2,arg3);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_delete_VarianceSimFunction(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  VarianceSimFunction *arg1 = (VarianceSimFunction *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_VarianceSimFunction, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_VarianceSimFunction" "', argument " "1"" of type '" "VarianceSimFunction *""'"); 
-  }
-  arg1 = reinterpret_cast< VarianceSimFunction * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *VarianceSimFunction_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_VarianceSimFunction, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *VarianceSimFunction_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  return SWIG_Python_InitShadowInstance(args);
-}
-
 SWIGINTERN PyObject *_wrap_new_Axes(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Axes *result = 0 ;
@@ -40058,6 +38567,320 @@ SWIGINTERN PyObject *IsGISAXSDetector_swiginit(PyObject *SWIGUNUSEDPARM(self), P
   return SWIG_Python_InitShadowInstance(args);
 }
 
+SWIGINTERN PyObject *_wrap_FindPeaks__SWIG_0(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
+  PyObject *resultobj = 0;
+  Histogram2D *arg1 = 0 ;
+  double arg2 ;
+  std::string *arg3 = 0 ;
+  double arg4 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  int res3 = SWIG_OLDOBJ ;
+  double val4 ;
+  int ecode4 = 0 ;
+  std::vector< std::pair< double,double >,std::allocator< std::pair< double,double > > > result;
+  
+  if ((nobjs < 4) || (nobjs > 4)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_Histogram2D,  0  | 0);
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FindPeaks" "', argument " "1"" of type '" "Histogram2D const &""'"); 
+  }
+  if (!argp1) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FindPeaks" "', argument " "1"" of type '" "Histogram2D const &""'"); 
+  }
+  arg1 = reinterpret_cast< Histogram2D * >(argp1);
+  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FindPeaks" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  {
+    std::string *ptr = (std::string *)0;
+    res3 = SWIG_AsPtr_std_string(swig_obj[2], &ptr);
+    if (!SWIG_IsOK(res3)) {
+      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "FindPeaks" "', argument " "3"" of type '" "std::string const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FindPeaks" "', argument " "3"" of type '" "std::string const &""'"); 
+    }
+    arg3 = ptr;
+  }
+  ecode4 = SWIG_AsVal_double(swig_obj[3], &val4);
+  if (!SWIG_IsOK(ecode4)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "FindPeaks" "', argument " "4"" of type '" "double""'");
+  } 
+  arg4 = static_cast< double >(val4);
+  result = HistoUtils::FindPeaks((Histogram2D const &)*arg1,arg2,(std::string const &)*arg3,arg4);
+  resultobj = swig::from(static_cast< std::vector< std::pair< double,double >,std::allocator< std::pair< double,double > > > >(result));
+  if (SWIG_IsNewObj(res3)) delete arg3;
+  return resultobj;
+fail:
+  if (SWIG_IsNewObj(res3)) delete arg3;
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_FindPeaks__SWIG_1(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
+  PyObject *resultobj = 0;
+  Histogram2D *arg1 = 0 ;
+  double arg2 ;
+  std::string *arg3 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  int res3 = SWIG_OLDOBJ ;
+  std::vector< std::pair< double,double >,std::allocator< std::pair< double,double > > > result;
+  
+  if ((nobjs < 3) || (nobjs > 3)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_Histogram2D,  0  | 0);
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FindPeaks" "', argument " "1"" of type '" "Histogram2D const &""'"); 
+  }
+  if (!argp1) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FindPeaks" "', argument " "1"" of type '" "Histogram2D const &""'"); 
+  }
+  arg1 = reinterpret_cast< Histogram2D * >(argp1);
+  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FindPeaks" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  {
+    std::string *ptr = (std::string *)0;
+    res3 = SWIG_AsPtr_std_string(swig_obj[2], &ptr);
+    if (!SWIG_IsOK(res3)) {
+      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "FindPeaks" "', argument " "3"" of type '" "std::string const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FindPeaks" "', argument " "3"" of type '" "std::string const &""'"); 
+    }
+    arg3 = ptr;
+  }
+  result = HistoUtils::FindPeaks((Histogram2D const &)*arg1,arg2,(std::string const &)*arg3);
+  resultobj = swig::from(static_cast< std::vector< std::pair< double,double >,std::allocator< std::pair< double,double > > > >(result));
+  if (SWIG_IsNewObj(res3)) delete arg3;
+  return resultobj;
+fail:
+  if (SWIG_IsNewObj(res3)) delete arg3;
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_FindPeaks__SWIG_2(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
+  PyObject *resultobj = 0;
+  Histogram2D *arg1 = 0 ;
+  double arg2 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  std::vector< std::pair< double,double >,std::allocator< std::pair< double,double > > > result;
+  
+  if ((nobjs < 2) || (nobjs > 2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_Histogram2D,  0  | 0);
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FindPeaks" "', argument " "1"" of type '" "Histogram2D const &""'"); 
+  }
+  if (!argp1) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FindPeaks" "', argument " "1"" of type '" "Histogram2D const &""'"); 
+  }
+  arg1 = reinterpret_cast< Histogram2D * >(argp1);
+  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FindPeaks" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  result = HistoUtils::FindPeaks((Histogram2D const &)*arg1,arg2);
+  resultobj = swig::from(static_cast< std::vector< std::pair< double,double >,std::allocator< std::pair< double,double > > > >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_FindPeaks__SWIG_3(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
+  PyObject *resultobj = 0;
+  Histogram2D *arg1 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  std::vector< std::pair< double,double >,std::allocator< std::pair< double,double > > > result;
+  
+  if ((nobjs < 1) || (nobjs > 1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_Histogram2D,  0  | 0);
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FindPeaks" "', argument " "1"" of type '" "Histogram2D const &""'"); 
+  }
+  if (!argp1) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "FindPeaks" "', argument " "1"" of type '" "Histogram2D const &""'"); 
+  }
+  arg1 = reinterpret_cast< Histogram2D * >(argp1);
+  result = HistoUtils::FindPeaks((Histogram2D const &)*arg1);
+  resultobj = swig::from(static_cast< std::vector< std::pair< double,double >,std::allocator< std::pair< double,double > > > >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_FindPeaks(PyObject *self, PyObject *args) {
+  Py_ssize_t argc;
+  PyObject *argv[5] = {
+    0
+  };
+  
+  if (!(argc = SWIG_Python_UnpackTuple(args, "FindPeaks", 0, 4, argv))) SWIG_fail;
+  --argc;
+  if (argc == 1) {
+    int _v;
+    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_Histogram2D, SWIG_POINTER_NO_NULL | 0);
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      return _wrap_FindPeaks__SWIG_3(self, argc, argv);
+    }
+  }
+  if (argc == 2) {
+    int _v;
+    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_Histogram2D, SWIG_POINTER_NO_NULL | 0);
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        int res = SWIG_AsVal_double(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        return _wrap_FindPeaks__SWIG_2(self, argc, argv);
+      }
+    }
+  }
+  if (argc == 3) {
+    int _v;
+    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_Histogram2D, SWIG_POINTER_NO_NULL | 0);
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        int res = SWIG_AsVal_double(argv[1], NULL);
+        _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_FindPeaks__SWIG_1(self, argc, argv);
+        }
+      }
+    }
+  }
+  if (argc == 4) {
+    int _v;
+    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_Histogram2D, SWIG_POINTER_NO_NULL | 0);
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        int res = SWIG_AsVal_double(argv[1], NULL);
+        _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_AsVal_double(argv[3], NULL);
+            _v = SWIG_CheckState(res);
+          }
+          if (_v) {
+            return _wrap_FindPeaks__SWIG_0(self, argc, argv);
+          }
+        }
+      }
+    }
+  }
+  
+fail:
+  SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'FindPeaks'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    HistoUtils::FindPeaks(Histogram2D const &,double,std::string const &,double)\n"
+    "    HistoUtils::FindPeaks(Histogram2D const &,double,std::string const &)\n"
+    "    HistoUtils::FindPeaks(Histogram2D const &,double)\n"
+    "    HistoUtils::FindPeaks(Histogram2D const &)\n");
+  return 0;
+}
+
+
+SWIGINTERN PyObject *_wrap_RelativeDifference(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  SimulationResult *arg1 = 0 ;
+  SimulationResult *arg2 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  PyObject *swig_obj[2] ;
+  double result;
+  
+  if (!SWIG_Python_UnpackTuple(args, "RelativeDifference", 2, 2, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_SimulationResult,  0  | 0);
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "RelativeDifference" "', argument " "1"" of type '" "SimulationResult const &""'"); 
+  }
+  if (!argp1) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "RelativeDifference" "', argument " "1"" of type '" "SimulationResult const &""'"); 
+  }
+  arg1 = reinterpret_cast< SimulationResult * >(argp1);
+  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_SimulationResult,  0  | 0);
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "RelativeDifference" "', argument " "2"" of type '" "SimulationResult const &""'"); 
+  }
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "RelativeDifference" "', argument " "2"" of type '" "SimulationResult const &""'"); 
+  }
+  arg2 = reinterpret_cast< SimulationResult * >(argp2);
+  result = (double)HistoUtils::RelativeDifference((SimulationResult const &)*arg1,(SimulationResult const &)*arg2);
+  resultobj = SWIG_From_double(static_cast< double >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_getRelativeDifference(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IHistogram *arg1 = 0 ;
+  IHistogram *arg2 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  PyObject *swig_obj[2] ;
+  double result;
+  
+  if (!SWIG_Python_UnpackTuple(args, "getRelativeDifference", 2, 2, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_IHistogram,  0  | 0);
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "getRelativeDifference" "', argument " "1"" of type '" "IHistogram const &""'"); 
+  }
+  if (!argp1) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "getRelativeDifference" "', argument " "1"" of type '" "IHistogram const &""'"); 
+  }
+  arg1 = reinterpret_cast< IHistogram * >(argp1);
+  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_IHistogram,  0  | 0);
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "getRelativeDifference" "', argument " "2"" of type '" "IHistogram const &""'"); 
+  }
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "getRelativeDifference" "', argument " "2"" of type '" "IHistogram const &""'"); 
+  }
+  arg2 = reinterpret_cast< IHistogram * >(argp2);
+  result = (double)HistoUtils::getRelativeDifference((IHistogram const &)*arg1,(IHistogram const &)*arg2);
+  resultobj = SWIG_From_double(static_cast< double >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *_wrap_delete_IHistogram(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   IHistogram *arg1 = (IHistogram *) 0 ;
@@ -45621,10 +44444,9 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { "IntensityData_axis", _wrap_IntensityData_axis, METH_VARARGS, "\n"
 		"IntensityData_axis(IntensityData self, size_t serial_number) -> IAxis\n"
-		"IntensityData_axis(IntensityData self, std::string const & axis_name) -> IAxis\n"
-		"const IAxis & OutputData< T >::axis(const std::string &axis_name) const\n"
+		"const IAxis & OutputData< T >::axis(size_t serial_number) const\n"
 		"\n"
-		"returns axis with given name \n"
+		"returns axis with given serial number \n"
 		"\n"
 		""},
 	 { "IntensityData_rank", _wrap_IntensityData_rank, METH_O, "\n"
@@ -45871,6 +44693,51 @@ static PyMethodDef SwigMethods[] = {
 	 { "IntensityData___setitem__", _wrap_IntensityData___setitem__, METH_VARARGS, "IntensityData___setitem__(IntensityData self, unsigned int i, double value) -> double"},
 	 { "IntensityData_swigregister", IntensityData_swigregister, METH_O, NULL},
 	 { "IntensityData_swiginit", IntensityData_swiginit, METH_VARARGS, NULL},
+	 { "relativeDataDifference", _wrap_relativeDataDifference, METH_VARARGS, "\n"
+		"relativeDataDifference(IntensityData dat, IntensityData ref) -> double\n"
+		"double DataUtils::relativeDataDifference(const OutputData< double > &dat, const OutputData< double > &ref)\n"
+		"\n"
+		"Returns relative difference between two data sets sum(dat[i] - ref[i])/ref[i]). \n"
+		"\n"
+		""},
+	 { "checkRelativeDifference", _wrap_checkRelativeDifference, METH_VARARGS, "\n"
+		"checkRelativeDifference(IntensityData dat, IntensityData ref, double const threshold) -> bool\n"
+		"bool DataUtils::checkRelativeDifference(const OutputData< double > &dat, const OutputData< double > &ref, const double threshold)\n"
+		"\n"
+		"Returns true is relative difference is below threshold; prints informative output. \n"
+		"\n"
+		""},
+	 { "coordinateToBinf", _wrap_coordinateToBinf, METH_VARARGS, "\n"
+		"coordinateToBinf(double coordinate, IAxis axis) -> double\n"
+		"coordinateToBinf(double & x, double & y, IntensityData data)\n"
+		"void DataUtils::coordinateToBinf(double &x, double &y, const OutputData< double > &data)\n"
+		"\n"
+		"Transforms x,y coordinate from  OutputData axes coordinates to bin-fraction-coordinates. \n"
+		"\n"
+		""},
+	 { "coordinateFromBinf", _wrap_coordinateFromBinf, METH_VARARGS, "\n"
+		"coordinateFromBinf(double value, IAxis axis) -> double\n"
+		"coordinateFromBinf(double & x, double & y, IntensityData data)\n"
+		"void DataUtils::coordinateFromBinf(double &x, double &y, const OutputData< double > &data)\n"
+		"\n"
+		"Transforms x,y coordinate from bin-fraction-coordinates to  OutputData's axes coordinates. \n"
+		"\n"
+		""},
+	 { "create2DArrayfromOutputData", _wrap_create2DArrayfromOutputData, METH_O, "\n"
+		"create2DArrayfromOutputData(IntensityData data) -> vdouble2d_t\n"
+		"std::vector< std::vector< double > > DataUtils::create2DArrayfromOutputData(const OutputData< double > &data)\n"
+		"\n"
+		"Creates a vector of vectors of double (2D Array) from  OutputData. \n"
+		"\n"
+		""},
+	 { "importArrayToOutputData", _wrap_importArrayToOutputData, METH_VARARGS, "\n"
+		"importArrayToOutputData(vdouble1d_t vec) -> IntensityData\n"
+		"importArrayToOutputData(vdouble2d_t vec) -> IntensityData\n"
+		"OutputData< double > * DataUtils::importArrayToOutputData(const std::vector< std::vector< double >> &vec)\n"
+		"\n"
+		"Reads 2D array of doubles to Python, for use in persistence test. \n"
+		"\n"
+		""},
 	 { "new_Beam", _wrap_new_Beam, METH_VARARGS, "\n"
 		"Beam(double intensity, double wavelength, Direction const & direction)\n"
 		"new_Beam(Beam other) -> Beam\n"
@@ -46069,66 +44936,6 @@ static PyMethodDef SwigMethods[] = {
 	 { "delete_FootprintSquare", _wrap_delete_FootprintSquare, METH_O, "delete_FootprintSquare(FootprintSquare self)"},
 	 { "FootprintSquare_swigregister", FootprintSquare_swigregister, METH_O, NULL},
 	 { "FootprintSquare_swiginit", FootprintSquare_swiginit, METH_VARARGS, NULL},
-	 { "delete_IIntensityFunction", _wrap_delete_IIntensityFunction, METH_O, "\n"
-		"delete_IIntensityFunction(IIntensityFunction self)\n"
-		"IIntensityFunction::~IIntensityFunction()\n"
-		"\n"
-		""},
-	 { "IIntensityFunction_clone", _wrap_IIntensityFunction_clone, METH_O, "\n"
-		"IIntensityFunction_clone(IIntensityFunction self) -> IIntensityFunction\n"
-		"virtual IIntensityFunction* IIntensityFunction::clone() const =0\n"
-		"\n"
-		""},
-	 { "IIntensityFunction_evaluate", _wrap_IIntensityFunction_evaluate, METH_VARARGS, "\n"
-		"IIntensityFunction_evaluate(IIntensityFunction self, double value) -> double\n"
-		"virtual double IIntensityFunction::evaluate(double value) const =0\n"
-		"\n"
-		""},
-	 { "IIntensityFunction_swigregister", IIntensityFunction_swigregister, METH_O, NULL},
-	 { "IntensityFunctionLog_clone", _wrap_IntensityFunctionLog_clone, METH_O, "\n"
-		"IntensityFunctionLog_clone(IntensityFunctionLog self) -> IntensityFunctionLog\n"
-		"IntensityFunctionLog * IntensityFunctionLog::clone() const\n"
-		"\n"
-		""},
-	 { "IntensityFunctionLog_evaluate", _wrap_IntensityFunctionLog_evaluate, METH_VARARGS, "\n"
-		"IntensityFunctionLog_evaluate(IntensityFunctionLog self, double value) -> double\n"
-		"double IntensityFunctionLog::evaluate(double value) const\n"
-		"\n"
-		""},
-	 { "new_IntensityFunctionLog", _wrap_new_IntensityFunctionLog, METH_NOARGS, "\n"
-		"new_IntensityFunctionLog() -> IntensityFunctionLog\n"
-		"\n"
-		"\n"
-		"Algorithm for applying log function to the measured intensity.\n"
-		"\n"
-		"C++ includes: IIntensityFunction.h\n"
-		"\n"
-		""},
-	 { "delete_IntensityFunctionLog", _wrap_delete_IntensityFunctionLog, METH_O, "delete_IntensityFunctionLog(IntensityFunctionLog self)"},
-	 { "IntensityFunctionLog_swigregister", IntensityFunctionLog_swigregister, METH_O, NULL},
-	 { "IntensityFunctionLog_swiginit", IntensityFunctionLog_swiginit, METH_VARARGS, NULL},
-	 { "IntensityFunctionSqrt_clone", _wrap_IntensityFunctionSqrt_clone, METH_O, "\n"
-		"IntensityFunctionSqrt_clone(IntensityFunctionSqrt self) -> IntensityFunctionSqrt\n"
-		"IntensityFunctionSqrt * IntensityFunctionSqrt::clone() const\n"
-		"\n"
-		""},
-	 { "IntensityFunctionSqrt_evaluate", _wrap_IntensityFunctionSqrt_evaluate, METH_VARARGS, "\n"
-		"IntensityFunctionSqrt_evaluate(IntensityFunctionSqrt self, double value) -> double\n"
-		"double IntensityFunctionSqrt::evaluate(double value) const\n"
-		"\n"
-		""},
-	 { "new_IntensityFunctionSqrt", _wrap_new_IntensityFunctionSqrt, METH_NOARGS, "\n"
-		"new_IntensityFunctionSqrt() -> IntensityFunctionSqrt\n"
-		"\n"
-		"\n"
-		"Algorithm for applying sqrt function to the measured intensity.\n"
-		"\n"
-		"C++ includes: IIntensityFunction.h\n"
-		"\n"
-		""},
-	 { "delete_IntensityFunctionSqrt", _wrap_delete_IntensityFunctionSqrt, METH_O, "delete_IntensityFunctionSqrt(IntensityFunctionSqrt self)"},
-	 { "IntensityFunctionSqrt_swigregister", IntensityFunctionSqrt_swigregister, METH_O, NULL},
-	 { "IntensityFunctionSqrt_swiginit", IntensityFunctionSqrt_swiginit, METH_VARARGS, NULL},
 	 { "IShape2D_clone", _wrap_IShape2D_clone, METH_O, "\n"
 		"IShape2D_clone(IShape2D self) -> IShape2D\n"
 		"virtual IShape2D* IShape2D::clone() const =0\n"
@@ -46472,198 +45279,6 @@ static PyMethodDef SwigMethods[] = {
 		"ScanResolution_scanAbsoluteResolution(IRangedDistribution const & distr, vdouble1d_t stddevs) -> ScanResolution\n"
 		""},
 	 { "ScanResolution_swigregister", ScanResolution_swigregister, METH_O, NULL},
-	 { "delete_IChiSquaredModule", _wrap_delete_IChiSquaredModule, METH_O, "\n"
-		"delete_IChiSquaredModule(IChiSquaredModule self)\n"
-		"IChiSquaredModule::~IChiSquaredModule()\n"
-		"\n"
-		""},
-	 { "IChiSquaredModule_clone", _wrap_IChiSquaredModule_clone, METH_O, "\n"
-		"IChiSquaredModule_clone(IChiSquaredModule self) -> IChiSquaredModule\n"
-		"virtual IChiSquaredModule* IChiSquaredModule::clone() const =0\n"
-		"\n"
-		"clone method \n"
-		"\n"
-		""},
-	 { "IChiSquaredModule_varianceFunction", _wrap_IChiSquaredModule_varianceFunction, METH_O, "\n"
-		"IChiSquaredModule_varianceFunction(IChiSquaredModule self) -> IVarianceFunction\n"
-		"const IVarianceFunction * IChiSquaredModule::varianceFunction() const\n"
-		"\n"
-		"Returns squared function. \n"
-		"\n"
-		""},
-	 { "IChiSquaredModule_setVarianceFunction", _wrap_IChiSquaredModule_setVarianceFunction, METH_VARARGS, "\n"
-		"IChiSquaredModule_setVarianceFunction(IChiSquaredModule self, IVarianceFunction variance_function)\n"
-		"void IChiSquaredModule::setVarianceFunction(const IVarianceFunction &variance_function)\n"
-		"\n"
-		"Sets squared function. \n"
-		"\n"
-		""},
-	 { "IChiSquaredModule_getIntensityFunction", _wrap_IChiSquaredModule_getIntensityFunction, METH_O, "\n"
-		"IChiSquaredModule_getIntensityFunction(IChiSquaredModule self) -> IIntensityFunction\n"
-		"const IIntensityFunction * IChiSquaredModule::getIntensityFunction() const\n"
-		"\n"
-		"Returns data rescaler. \n"
-		"\n"
-		""},
-	 { "IChiSquaredModule_setIntensityFunction", _wrap_IChiSquaredModule_setIntensityFunction, METH_VARARGS, "\n"
-		"IChiSquaredModule_setIntensityFunction(IChiSquaredModule self, IIntensityFunction intensity_function)\n"
-		"void IChiSquaredModule::setIntensityFunction(const IIntensityFunction &intensity_function)\n"
-		"\n"
-		"Sets data rescaler. \n"
-		"\n"
-		""},
-	 { "IChiSquaredModule_residual", _wrap_IChiSquaredModule_residual, METH_VARARGS, "\n"
-		"IChiSquaredModule_residual(IChiSquaredModule self, double a, double b, double weight) -> double\n"
-		"virtual double IChiSquaredModule::residual(double a, double b, double weight)=0\n"
-		"\n"
-		""},
-	 { "IChiSquaredModule_swigregister", IChiSquaredModule_swigregister, METH_O, NULL},
-	 { "new_ChiSquaredModule", _wrap_new_ChiSquaredModule, METH_VARARGS, "\n"
-		"ChiSquaredModule()\n"
-		"new_ChiSquaredModule(ChiSquaredModule other) -> ChiSquaredModule\n"
-		"ChiSquaredModule::ChiSquaredModule(const ChiSquaredModule &other)\n"
-		"\n"
-		""},
-	 { "delete_ChiSquaredModule", _wrap_delete_ChiSquaredModule, METH_O, "\n"
-		"delete_ChiSquaredModule(ChiSquaredModule self)\n"
-		"virtual ChiSquaredModule::~ChiSquaredModule()\n"
-		"\n"
-		""},
-	 { "ChiSquaredModule_clone", _wrap_ChiSquaredModule_clone, METH_O, "\n"
-		"ChiSquaredModule_clone(ChiSquaredModule self) -> ChiSquaredModule\n"
-		"virtual ChiSquaredModule* ChiSquaredModule::clone() const\n"
-		"\n"
-		"clone method \n"
-		"\n"
-		""},
-	 { "ChiSquaredModule_residual", _wrap_ChiSquaredModule_residual, METH_VARARGS, "\n"
-		"ChiSquaredModule_residual(ChiSquaredModule self, double a, double b, double weight) -> double\n"
-		"double ChiSquaredModule::residual(double a, double b, double weight)\n"
-		"\n"
-		""},
-	 { "ChiSquaredModule_swigregister", ChiSquaredModule_swigregister, METH_O, NULL},
-	 { "ChiSquaredModule_swiginit", ChiSquaredModule_swiginit, METH_VARARGS, NULL},
-	 { "RelativeDifference", _wrap_RelativeDifference, METH_VARARGS, "\n"
-		"RelativeDifference(SimulationResult dat, SimulationResult ref) -> double\n"
-		"double IntensityDataFunctions::RelativeDifference(const SimulationResult &dat, const SimulationResult &ref)\n"
-		"\n"
-		"Returns sum of relative differences between each pair of elements: (a, b) -> 2*abs(a - b)/(a + b) ( and zero if a-b=0 )\n"
-		"\n"
-		"Returns sum of relative differences between each pair of elements: (a, b) -> 2*abs(a - b)/(|a| + |b|) ( and zero if a=b=0 within epsilon ) \n"
-		"\n"
-		""},
-	 { "checkRelativeDifference", _wrap_checkRelativeDifference, METH_VARARGS, "\n"
-		"checkRelativeDifference(IntensityData dat, IntensityData ref, double const threshold) -> bool\n"
-		"bool IntensityDataFunctions::checkRelativeDifference(const OutputData< double > &dat, const OutputData< double > &ref, const double threshold)\n"
-		"\n"
-		"Returns true is relative difference is below threshold; prints informative output. \n"
-		"\n"
-		""},
-	 { "getRelativeDifference", _wrap_getRelativeDifference, METH_VARARGS, "\n"
-		"getRelativeDifference(IntensityData dat, IntensityData ref) -> double\n"
-		"getRelativeDifference(IHistogram dat, IHistogram ref) -> double\n"
-		"double IntensityDataFunctions::getRelativeDifference(const IHistogram &dat, const IHistogram &ref)\n"
-		"\n"
-		""},
-	 { "coordinateToBinf", _wrap_coordinateToBinf, METH_VARARGS, "\n"
-		"coordinateToBinf(double coordinate, IAxis axis) -> double\n"
-		"coordinateToBinf(double & x, double & y, IntensityData data)\n"
-		"void IntensityDataFunctions::coordinateToBinf(double &x, double &y, const OutputData< double > &data)\n"
-		"\n"
-		"Transforms x,y coordinate from  OutputData axes coordinates to bin-fraction-coordinates. \n"
-		"\n"
-		""},
-	 { "coordinateFromBinf", _wrap_coordinateFromBinf, METH_VARARGS, "\n"
-		"coordinateFromBinf(double value, IAxis axis) -> double\n"
-		"coordinateFromBinf(double & x, double & y, IntensityData data)\n"
-		"void IntensityDataFunctions::coordinateFromBinf(double &x, double &y, const OutputData< double > &data)\n"
-		"\n"
-		"Transforms x,y coordinate from bin-fraction-coordinates to  OutputData's axes coordinates. \n"
-		"\n"
-		""},
-	 { "create2DArrayfromOutputData", _wrap_create2DArrayfromOutputData, METH_O, "\n"
-		"create2DArrayfromOutputData(IntensityData data) -> vdouble2d_t\n"
-		"std::vector< std::vector< double > > IntensityDataFunctions::create2DArrayfromOutputData(const OutputData< double > &data)\n"
-		"\n"
-		"Creates a vector of vectors of double (2D Array) from  OutputData. \n"
-		"\n"
-		""},
-	 { "FT2DArray", _wrap_FT2DArray, METH_O, "\n"
-		"FT2DArray(vdouble2d_t signal) -> vdouble2d_t\n"
-		"std::vector< std::vector< double > > IntensityDataFunctions::FT2DArray(const std::vector< std::vector< double >> &signal)\n"
-		"\n"
-		"Creates a Fourier Transform of a 2D Array (vector of vectors). \n"
-		"\n"
-		""},
-	 { "importArrayToOutputData", _wrap_importArrayToOutputData, METH_VARARGS, "\n"
-		"importArrayToOutputData(vdouble1d_t vec) -> IntensityData\n"
-		"importArrayToOutputData(vdouble2d_t vec) -> IntensityData\n"
-		"OutputData< double > * PyArrayImport::importArrayToOutputData(const std::vector< std::vector< double >> &vec)\n"
-		"\n"
-		"for importing 2D array of doubles from python into  OutputData\n"
-		"\n"
-		""},
-	 { "FindPeaks", _wrap_FindPeaks, METH_VARARGS, "\n"
-		"FindPeaks(Histogram2D hist, double sigma=2, std::string const & option={}, double threshold=0.05) -> vector_pvacuum_double_t\n"
-		"std::vector< std::pair< double, double > > SpectrumUtils::FindPeaks(const Histogram2D &hist, double sigma=2, const std::string &option={}, double threshold=0.05)\n"
-		"\n"
-		""},
-	 { "delete_IVarianceFunction", _wrap_delete_IVarianceFunction, METH_O, "\n"
-		"delete_IVarianceFunction(IVarianceFunction self)\n"
-		"virtual IVarianceFunction::~IVarianceFunction()=default\n"
-		"\n"
-		""},
-	 { "IVarianceFunction_clone", _wrap_IVarianceFunction_clone, METH_O, "\n"
-		"IVarianceFunction_clone(IVarianceFunction self) -> IVarianceFunction\n"
-		"virtual IVarianceFunction* IVarianceFunction::clone() const =0\n"
-		"\n"
-		""},
-	 { "IVarianceFunction_variance", _wrap_IVarianceFunction_variance, METH_VARARGS, "\n"
-		"IVarianceFunction_variance(IVarianceFunction self, double real_value, double simulated_value) -> double\n"
-		"virtual double IVarianceFunction::variance(double real_value, double simulated_value) const =0\n"
-		"\n"
-		""},
-	 { "IVarianceFunction_swigregister", IVarianceFunction_swigregister, METH_O, NULL},
-	 { "VarianceConstantFunction_clone", _wrap_VarianceConstantFunction_clone, METH_O, "\n"
-		"VarianceConstantFunction_clone(VarianceConstantFunction self) -> VarianceConstantFunction\n"
-		"VarianceConstantFunction * VarianceConstantFunction::clone() const override\n"
-		"\n"
-		""},
-	 { "VarianceConstantFunction_variance", _wrap_VarianceConstantFunction_variance, METH_VARARGS, "\n"
-		"VarianceConstantFunction_variance(VarianceConstantFunction self, double arg2, double arg3) -> double\n"
-		"double VarianceConstantFunction::variance(double, double) const override\n"
-		"\n"
-		""},
-	 { "new_VarianceConstantFunction", _wrap_new_VarianceConstantFunction, METH_NOARGS, "\n"
-		"new_VarianceConstantFunction() -> VarianceConstantFunction\n"
-		"\n"
-		"\n"
-		"Returns 1.0 as variance value\n"
-		"\n"
-		"C++ includes: VarianceFunctions.h\n"
-		"\n"
-		""},
-	 { "delete_VarianceConstantFunction", _wrap_delete_VarianceConstantFunction, METH_O, "delete_VarianceConstantFunction(VarianceConstantFunction self)"},
-	 { "VarianceConstantFunction_swigregister", VarianceConstantFunction_swigregister, METH_O, NULL},
-	 { "VarianceConstantFunction_swiginit", VarianceConstantFunction_swiginit, METH_VARARGS, NULL},
-	 { "new_VarianceSimFunction", _wrap_new_VarianceSimFunction, METH_VARARGS, "\n"
-		"VarianceSimFunction(double epsilon=1.0)\n"
-		"VarianceSimFunction::VarianceSimFunction(double epsilon=1.0)\n"
-		"\n"
-		""},
-	 { "VarianceSimFunction_clone", _wrap_VarianceSimFunction_clone, METH_O, "\n"
-		"VarianceSimFunction_clone(VarianceSimFunction self) -> VarianceSimFunction\n"
-		"VarianceSimFunction * VarianceSimFunction::clone() const override\n"
-		"\n"
-		""},
-	 { "VarianceSimFunction_variance", _wrap_VarianceSimFunction_variance, METH_VARARGS, "\n"
-		"VarianceSimFunction_variance(VarianceSimFunction self, double exp, double sim) -> double\n"
-		"double VarianceSimFunction::variance(double exp, double sim) const override\n"
-		"\n"
-		""},
-	 { "delete_VarianceSimFunction", _wrap_delete_VarianceSimFunction, METH_O, "delete_VarianceSimFunction(VarianceSimFunction self)"},
-	 { "VarianceSimFunction_swigregister", VarianceSimFunction_swigregister, METH_O, NULL},
-	 { "VarianceSimFunction_swiginit", VarianceSimFunction_swiginit, METH_VARARGS, NULL},
 	 { "new_Axes", _wrap_new_Axes, METH_NOARGS, "\n"
 		"new_Axes() -> Axes\n"
 		"\n"
@@ -47205,6 +45820,27 @@ static PyMethodDef SwigMethods[] = {
 	 { "delete_IsGISAXSDetector", _wrap_delete_IsGISAXSDetector, METH_O, "delete_IsGISAXSDetector(IsGISAXSDetector self)"},
 	 { "IsGISAXSDetector_swigregister", IsGISAXSDetector_swigregister, METH_O, NULL},
 	 { "IsGISAXSDetector_swiginit", IsGISAXSDetector_swiginit, METH_VARARGS, NULL},
+	 { "FindPeaks", _wrap_FindPeaks, METH_VARARGS, "\n"
+		"FindPeaks(Histogram2D hist, double sigma=2, std::string const & option={}, double threshold=0.05) -> vector_pvacuum_double_t\n"
+		"std::vector< std::pair< double, double > > HistoUtils::FindPeaks(const Histogram2D &hist, double sigma=2, const std::string &option={}, double threshold=0.05)\n"
+		"\n"
+		"Returns vector of peak center coordinates, for peaks in given histogram. \n"
+		"\n"
+		""},
+	 { "RelativeDifference", _wrap_RelativeDifference, METH_VARARGS, "\n"
+		"RelativeDifference(SimulationResult dat, SimulationResult ref) -> double\n"
+		"double HistoUtils::RelativeDifference(const SimulationResult &dat, const SimulationResult &ref)\n"
+		"\n"
+		"Returns sum of relative differences between each pair of elements: (a, b) -> 2*abs(a - b)/(a + b) ( and zero if a-b=0 )\n"
+		"\n"
+		"Returns sum of relative differences between each pair of elements: (a, b) -> 2*abs(a - b)/(|a| + |b|) ( and zero if a=b=0 within epsilon ) \n"
+		"\n"
+		""},
+	 { "getRelativeDifference", _wrap_getRelativeDifference, METH_VARARGS, "\n"
+		"getRelativeDifference(IHistogram dat, IHistogram ref) -> double\n"
+		"double HistoUtils::getRelativeDifference(const IHistogram &dat, const IHistogram &ref)\n"
+		"\n"
+		""},
 	 { "delete_IHistogram", _wrap_delete_IHistogram, METH_O, "\n"
 		"delete_IHistogram(IHistogram self)\n"
 		"virtual IHistogram::~IHistogram()=default\n"
@@ -47773,131 +46409,14 @@ static PyMethodDef SwigMethods_proxydocs[] = {
 
 /* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */
 
-static void *_p_ChiSquaredModuleTo_p_IChiSquaredModule(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IChiSquaredModule *)  ((ChiSquaredModule *) x));
-}
-static void *_p_Histogram2DTo_p_IHistogram(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IHistogram *)  ((Histogram2D *) x));
-}
-static void *_p_Histogram1DTo_p_IHistogram(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IHistogram *)  ((Histogram1D *) x));
-}
-static void *_p_FootprintGaussTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ICloneable *) (IFootprintFactor *) ((FootprintGauss *) x));
-}
-static void *_p_IDetectorResolutionTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ICloneable *)  ((IDetectorResolution *) x));
-}
-static void *_p_ScanResolutionTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ICloneable *)  ((ScanResolution *) x));
-}
-static void *_p_IDetector2DTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ICloneable *) (IDetector *) ((IDetector2D *) x));
-}
-static void *_p_RectangleTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ICloneable *) (IShape2D *) ((Rectangle *) x));
-}
-static void *_p_ResolutionFunction2DGaussianTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ICloneable *) (IResolutionFunction2D *) ((ResolutionFunction2DGaussian *) x));
-}
-static void *_p_IFootprintFactorTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ICloneable *)  ((IFootprintFactor *) x));
-}
-static void *_p_IShape2DTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ICloneable *)  ((IShape2D *) x));
-}
-static void *_p_ParameterPoolTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ICloneable *)  ((ParameterPool *) x));
-}
-static void *_p_EllipseTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ICloneable *) (IShape2D *) ((Ellipse *) x));
-}
-static void *_p_HorizontalLineTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ICloneable *) (IShape2D *) ((HorizontalLine *) x));
-}
-static void *_p_VerticalLineTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ICloneable *) (IShape2D *) ((VerticalLine *) x));
-}
-static void *_p_IChiSquaredModuleTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ICloneable *)  ((IChiSquaredModule *) x));
-}
-static void *_p_ChiSquaredModuleTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ICloneable *) (IChiSquaredModule *) ((ChiSquaredModule *) x));
-}
-static void *_p_IDetectorTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ICloneable *)  ((IDetector *) x));
-}
-static void *_p_RectangularDetectorTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ICloneable *) (IDetector *)(IDetector2D *) ((RectangularDetector *) x));
-}
-static void *_p_SphericalDetectorTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ICloneable *) (IDetector *)(IDetector2D *) ((SphericalDetector *) x));
-}
-static void *_p_IsGISAXSDetectorTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ICloneable *) (IDetector *)(IDetector2D *)(SphericalDetector *) ((IsGISAXSDetector *) x));
-}
-static void *_p_PolygonTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ICloneable *) (IShape2D *) ((Polygon *) x));
-}
-static void *_p_FootprintSquareTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ICloneable *) (IFootprintFactor *) ((FootprintSquare *) x));
-}
-static void *_p_IUnitConverterTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ICloneable *)  ((IUnitConverter *) x));
-}
-static void *_p_IResolutionFunction2DTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ICloneable *)  ((IResolutionFunction2D *) x));
-}
-static void *_p_LineTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((ICloneable *) (IShape2D *) ((Line *) x));
-}
-static void *_p_FootprintSquareTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INode *) (IFootprintFactor *) ((FootprintSquare *) x));
-}
-static void *_p_IDetectorResolutionTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INode *)  ((IDetectorResolution *) x));
-}
-static void *_p_IFootprintFactorTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INode *)  ((IFootprintFactor *) x));
-}
-static void *_p_BeamTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INode *)  ((Beam *) x));
-}
-static void *_p_IResolutionFunction2DTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INode *)  ((IResolutionFunction2D *) x));
-}
-static void *_p_ResolutionFunction2DGaussianTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INode *) (IResolutionFunction2D *) ((ResolutionFunction2DGaussian *) x));
-}
-static void *_p_IDetectorTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INode *)  ((IDetector *) x));
-}
-static void *_p_RectangularDetectorTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INode *) (IDetector *)(IDetector2D *) ((RectangularDetector *) x));
-}
-static void *_p_SphericalDetectorTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INode *) (IDetector *)(IDetector2D *) ((SphericalDetector *) x));
-}
-static void *_p_IsGISAXSDetectorTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INode *) (IDetector *)(IDetector2D *)(SphericalDetector *) ((IsGISAXSDetector *) x));
-}
-static void *_p_FootprintGaussTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INode *) (IFootprintFactor *) ((FootprintGauss *) x));
-}
-static void *_p_IDetector2DTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((INode *) (IDetector *) ((IDetector2D *) x));
-}
-static void *_p_IntensityFunctionSqrtTo_p_IIntensityFunction(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IIntensityFunction *)  ((IntensityFunctionSqrt *) x));
-}
-static void *_p_IntensityFunctionLogTo_p_IIntensityFunction(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IIntensityFunction *)  ((IntensityFunctionLog *) x));
+static void *_p_RectangularDetectorTo_p_IDetector2D(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IDetector2D *)  ((RectangularDetector *) x));
 }
-static void *_p_VarianceConstantFunctionTo_p_IVarianceFunction(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IVarianceFunction *)  ((VarianceConstantFunction *) x));
+static void *_p_SphericalDetectorTo_p_IDetector2D(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IDetector2D *)  ((SphericalDetector *) x));
 }
-static void *_p_VarianceSimFunctionTo_p_IVarianceFunction(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IVarianceFunction *)  ((VarianceSimFunction *) x));
+static void *_p_IsGISAXSDetectorTo_p_IDetector2D(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IDetector2D *) (SphericalDetector *) ((IsGISAXSDetector *) x));
 }
 static void *_p_IsGISAXSDetectorTo_p_SphericalDetector(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((SphericalDetector *)  ((IsGISAXSDetector *) x));
@@ -47932,6 +46451,51 @@ 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_FootprintGaussTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IComponent *) (IParametricComponent *)(INode *)(IFootprintFactor *) ((FootprintGauss *) x));
+}
+static void *_p_IDetectorResolutionTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IComponent *) (IParametricComponent *)(INode *) ((IDetectorResolution *) x));
+}
+static void *_p_IDetector2DTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IComponent *) (IParametricComponent *)(INode *)(IDetector *) ((IDetector2D *) x));
+}
+static void *_p_IParametricComponentTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IComponent *)  ((IParametricComponent *) x));
+}
+static void *_p_INodeTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IComponent *) (IParametricComponent *) ((INode *) x));
+}
+static void *_p_ResolutionFunction2DGaussianTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IComponent *) (IParametricComponent *)(INode *)(IResolutionFunction2D *) ((ResolutionFunction2DGaussian *) x));
+}
+static void *_p_IFootprintFactorTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IComponent *) (IParametricComponent *)(INode *) ((IFootprintFactor *) x));
+}
+static void *_p_BeamTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IComponent *) (IParametricComponent *)(INode *) ((Beam *) x));
+}
+static void *_p_SphericalDetectorTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IComponent *) (IParametricComponent *)(INode *)(IDetector *)(IDetector2D *) ((SphericalDetector *) x));
+}
+static void *_p_RectangularDetectorTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IComponent *) (IParametricComponent *)(INode *)(IDetector *)(IDetector2D *) ((RectangularDetector *) x));
+}
+static void *_p_IDetectorTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IComponent *) (IParametricComponent *)(INode *) ((IDetector *) x));
+}
+static void *_p_IsGISAXSDetectorTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IComponent *) (IParametricComponent *)(INode *)(IDetector *)(IDetector2D *)(SphericalDetector *) ((IsGISAXSDetector *) x));
+}
+static void *_p_ParameterDistributionTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IComponent *) (IParametricComponent *) ((ParameterDistribution *) x));
+}
+static void *_p_FootprintSquareTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IComponent *) (IParametricComponent *)(INode *)(IFootprintFactor *) ((FootprintSquare *) x));
+}
+static void *_p_IResolutionFunction2DTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IComponent *) (IParametricComponent *)(INode *) ((IResolutionFunction2D *) x));
+}
 static void *_p_FootprintGaussTo_p_IParametricComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IParametricComponent *) (INode *)(IFootprintFactor *) ((FootprintGauss *) x));
 }
@@ -47974,77 +46538,127 @@ static void *_p_FootprintSquareTo_p_IParametricComponent(void *x, int *SWIGUNUSE
 static void *_p_IResolutionFunction2DTo_p_IParametricComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((IParametricComponent *) (INode *) ((IResolutionFunction2D *) x));
 }
-static void *_p_FootprintGaussTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IComponent *) (IParametricComponent *)(INode *)(IFootprintFactor *) ((FootprintGauss *) x));
+static void *_p_FootprintSquareTo_p_IFootprintFactor(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IFootprintFactor *)  ((FootprintSquare *) x));
 }
-static void *_p_IDetectorResolutionTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IComponent *) (IParametricComponent *)(INode *) ((IDetectorResolution *) x));
+static void *_p_FootprintGaussTo_p_IFootprintFactor(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IFootprintFactor *)  ((FootprintGauss *) x));
 }
-static void *_p_IDetector2DTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IComponent *) (IParametricComponent *)(INode *)(IDetector *) ((IDetector2D *) x));
+static void *_p_Histogram2DTo_p_IHistogram(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IHistogram *)  ((Histogram2D *) x));
 }
-static void *_p_IParametricComponentTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IComponent *)  ((IParametricComponent *) x));
+static void *_p_Histogram1DTo_p_IHistogram(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IHistogram *)  ((Histogram1D *) x));
 }
-static void *_p_INodeTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IComponent *) (IParametricComponent *) ((INode *) x));
+static void *_p_FootprintSquareTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INode *) (IFootprintFactor *) ((FootprintSquare *) x));
 }
-static void *_p_ResolutionFunction2DGaussianTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IComponent *) (IParametricComponent *)(INode *)(IResolutionFunction2D *) ((ResolutionFunction2DGaussian *) x));
+static void *_p_IDetectorResolutionTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INode *)  ((IDetectorResolution *) x));
 }
-static void *_p_IFootprintFactorTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IComponent *) (IParametricComponent *)(INode *) ((IFootprintFactor *) x));
+static void *_p_IFootprintFactorTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INode *)  ((IFootprintFactor *) x));
 }
-static void *_p_BeamTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IComponent *) (IParametricComponent *)(INode *) ((Beam *) x));
+static void *_p_BeamTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INode *)  ((Beam *) x));
 }
-static void *_p_SphericalDetectorTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IComponent *) (IParametricComponent *)(INode *)(IDetector *)(IDetector2D *) ((SphericalDetector *) x));
+static void *_p_IResolutionFunction2DTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INode *)  ((IResolutionFunction2D *) x));
 }
-static void *_p_RectangularDetectorTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IComponent *) (IParametricComponent *)(INode *)(IDetector *)(IDetector2D *) ((RectangularDetector *) x));
+static void *_p_ResolutionFunction2DGaussianTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INode *) (IResolutionFunction2D *) ((ResolutionFunction2DGaussian *) x));
 }
-static void *_p_IDetectorTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IComponent *) (IParametricComponent *)(INode *) ((IDetector *) x));
+static void *_p_IDetectorTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INode *)  ((IDetector *) x));
 }
-static void *_p_IsGISAXSDetectorTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IComponent *) (IParametricComponent *)(INode *)(IDetector *)(IDetector2D *)(SphericalDetector *) ((IsGISAXSDetector *) x));
+static void *_p_RectangularDetectorTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INode *) (IDetector *)(IDetector2D *) ((RectangularDetector *) x));
 }
-static void *_p_ParameterDistributionTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IComponent *) (IParametricComponent *) ((ParameterDistribution *) x));
+static void *_p_SphericalDetectorTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INode *) (IDetector *)(IDetector2D *) ((SphericalDetector *) x));
 }
-static void *_p_FootprintSquareTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IComponent *) (IParametricComponent *)(INode *)(IFootprintFactor *) ((FootprintSquare *) x));
+static void *_p_IsGISAXSDetectorTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INode *) (IDetector *)(IDetector2D *)(SphericalDetector *) ((IsGISAXSDetector *) x));
 }
-static void *_p_IResolutionFunction2DTo_p_IComponent(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IComponent *) (IParametricComponent *)(INode *) ((IResolutionFunction2D *) x));
+static void *_p_FootprintGaussTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INode *) (IFootprintFactor *) ((FootprintGauss *) x));
 }
-static void *_p_RectangularDetectorTo_p_IDetector2D(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IDetector2D *)  ((RectangularDetector *) x));
+static void *_p_IDetector2DTo_p_INode(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((INode *) (IDetector *) ((IDetector2D *) x));
 }
-static void *_p_SphericalDetectorTo_p_IDetector2D(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IDetector2D *)  ((SphericalDetector *) x));
+static void *_p_ResolutionFunction2DGaussianTo_p_IResolutionFunction2D(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((IResolutionFunction2D *)  ((ResolutionFunction2DGaussian *) x));
 }
-static void *_p_IsGISAXSDetectorTo_p_IDetector2D(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IDetector2D *) (SphericalDetector *) ((IsGISAXSDetector *) x));
+static void *_p_FootprintGaussTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *) (IFootprintFactor *) ((FootprintGauss *) x));
 }
-static void *_p_FootprintSquareTo_p_IFootprintFactor(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IFootprintFactor *)  ((FootprintSquare *) x));
+static void *_p_IDetectorResolutionTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *)  ((IDetectorResolution *) x));
 }
-static void *_p_FootprintGaussTo_p_IFootprintFactor(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IFootprintFactor *)  ((FootprintGauss *) x));
+static void *_p_ScanResolutionTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *)  ((ScanResolution *) x));
 }
-static void *_p_ResolutionFunction2DGaussianTo_p_IResolutionFunction2D(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IResolutionFunction2D *)  ((ResolutionFunction2DGaussian *) x));
+static void *_p_IDetector2DTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *) (IDetector *) ((IDetector2D *) x));
+}
+static void *_p_RectangleTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *) (IShape2D *) ((Rectangle *) x));
+}
+static void *_p_ResolutionFunction2DGaussianTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *) (IResolutionFunction2D *) ((ResolutionFunction2DGaussian *) x));
+}
+static void *_p_IFootprintFactorTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *)  ((IFootprintFactor *) x));
+}
+static void *_p_IShape2DTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *)  ((IShape2D *) x));
+}
+static void *_p_ParameterPoolTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *)  ((ParameterPool *) x));
+}
+static void *_p_EllipseTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *) (IShape2D *) ((Ellipse *) x));
+}
+static void *_p_HorizontalLineTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *) (IShape2D *) ((HorizontalLine *) x));
+}
+static void *_p_VerticalLineTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *) (IShape2D *) ((VerticalLine *) x));
+}
+static void *_p_IDetectorTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *)  ((IDetector *) x));
+}
+static void *_p_RectangularDetectorTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *) (IDetector *)(IDetector2D *) ((RectangularDetector *) x));
+}
+static void *_p_SphericalDetectorTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *) (IDetector *)(IDetector2D *) ((SphericalDetector *) x));
+}
+static void *_p_IsGISAXSDetectorTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *) (IDetector *)(IDetector2D *)(SphericalDetector *) ((IsGISAXSDetector *) x));
+}
+static void *_p_PolygonTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *) (IShape2D *) ((Polygon *) x));
+}
+static void *_p_FootprintSquareTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *) (IFootprintFactor *) ((FootprintSquare *) x));
+}
+static void *_p_IUnitConverterTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *)  ((IUnitConverter *) x));
+}
+static void *_p_IResolutionFunction2DTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *)  ((IResolutionFunction2D *) x));
+}
+static void *_p_LineTo_p_ICloneable(void *x, int *SWIGUNUSEDPARM(newmemory)) {
+    return (void *)((ICloneable *) (IShape2D *) ((Line *) x));
 }
 static swig_type_info _swigt__p_Axes = {"_p_Axes", "Axes *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_AxisInfo = {"_p_AxisInfo", "AxisInfo *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_BasicVector3DT_double_t = {"_p_BasicVector3DT_double_t", "std::vector< BasicVector3D< double > >::value_type *|kvector_t *|BasicVector3D< double > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_BasicVector3DT_int_t = {"_p_BasicVector3DT_int_t", "ivector_t *|BasicVector3D< int > *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_BasicVector3DT_std__complexT_double_t_t = {"_p_BasicVector3DT_std__complexT_double_t_t", "BasicVector3D< std::complex< double > > *|std::vector< BasicVector3D< std::complex< double > > >::value_type *|cvector_t *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_BasicVector3DT_std__complexT_double_t_t = {"_p_BasicVector3DT_std__complexT_double_t_t", "BasicVector3D< std::complex< double > > *|std::vector< BasicVector3D< std::complex< double > > >::value_type *|cvector_t *|BasicVector3D< complex_t > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Beam = {"_p_Beam", "Beam *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Bin1D = {"_p_Bin1D", "Bin1D *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_ChiSquaredModule = {"_p_ChiSquaredModule", "ChiSquaredModule *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_DetectionProperties = {"_p_DetectionProperties", "DetectionProperties *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_DetectorMask = {"_p_DetectorMask", "DetectorMask *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Direction = {"_p_Direction", "Direction *", 0, 0, (void*)0, 0};
@@ -48055,7 +46669,6 @@ static swig_type_info _swigt__p_Histogram1D = {"_p_Histogram1D", "Histogram1D *"
 static swig_type_info _swigt__p_Histogram2D = {"_p_Histogram2D", "Histogram2D *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_HorizontalLine = {"_p_HorizontalLine", "HorizontalLine *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_IAxis = {"_p_IAxis", "IAxis *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_IChiSquaredModule = {"_p_IChiSquaredModule", "IChiSquaredModule *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_ICloneable = {"_p_ICloneable", "ICloneable *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_ParameterPool = {"_p_ParameterPool", 0, 0, 0, 0, 0};
 static swig_type_info _swigt__p_IComponent = {"_p_IComponent", "IComponent *", 0, 0, (void*)0, 0};
@@ -48065,7 +46678,6 @@ static swig_type_info _swigt__p_IDetector2D = {"_p_IDetector2D", "IDetector2D *"
 static swig_type_info _swigt__p_IDetectorResolution = {"_p_IDetectorResolution", "IDetectorResolution *", 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_IHistogram = {"_p_IHistogram", "IHistogram *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_IIntensityFunction = {"_p_IIntensityFunction", "IIntensityFunction *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_INode = {"_p_INode", "INode *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_INodeVisitor = {"_p_INodeVisitor", "INodeVisitor *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_IParametricComponent = {"_p_IParametricComponent", "IParametricComponent *", 0, 0, (void*)0, 0};
@@ -48074,10 +46686,7 @@ static swig_type_info _swigt__p_IRangedDistribution = {"_p_IRangedDistribution",
 static swig_type_info _swigt__p_IResolutionFunction2D = {"_p_IResolutionFunction2D", "IResolutionFunction2D *", 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_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_IntensityDataIOFactory = {"_p_IntensityDataIOFactory", "IntensityDataIOFactory *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_IntensityFunctionLog = {"_p_IntensityFunctionLog", "IntensityFunctionLog *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_IntensityFunctionSqrt = {"_p_IntensityFunctionSqrt", "IntensityFunctionSqrt *", 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_Line = {"_p_Line", "Line *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_OutputDataIteratorT_double_OutputDataT_double_t_t = {"_p_OutputDataIteratorT_double_OutputDataT_double_t_t", "OutputData< double >::iterator *|OutputDataIterator< double,OutputData< double > > *", 0, 0, (void*)0, 0};
@@ -48095,8 +46704,6 @@ static swig_type_info _swigt__p_ResolutionFunction2DGaussian = {"_p_ResolutionFu
 static swig_type_info _swigt__p_ScanResolution = {"_p_ScanResolution", "ScanResolution *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_SimulationResult = {"_p_SimulationResult", "SimulationResult *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_SphericalDetector = {"_p_SphericalDetector", "SphericalDetector *", 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_allocator_type = {"_p_allocator_type", "allocator_type *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_bool = {"_p_bool", "bool *", 0, 0, (void*)0, 0};
@@ -48166,7 +46773,6 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_BasicVector3DT_std__complexT_double_t_t,
   &_swigt__p_Beam,
   &_swigt__p_Bin1D,
-  &_swigt__p_ChiSquaredModule,
   &_swigt__p_DetectionProperties,
   &_swigt__p_DetectorMask,
   &_swigt__p_Direction,
@@ -48177,7 +46783,6 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_Histogram2D,
   &_swigt__p_HorizontalLine,
   &_swigt__p_IAxis,
-  &_swigt__p_IChiSquaredModule,
   &_swigt__p_ICloneable,
   &_swigt__p_IComponent,
   &_swigt__p_IDetector,
@@ -48185,7 +46790,6 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_IDetectorResolution,
   &_swigt__p_IFootprintFactor,
   &_swigt__p_IHistogram,
-  &_swigt__p_IIntensityFunction,
   &_swigt__p_INode,
   &_swigt__p_INodeVisitor,
   &_swigt__p_IParametricComponent,
@@ -48194,10 +46798,7 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_IResolutionFunction2D,
   &_swigt__p_IShape2D,
   &_swigt__p_IUnitConverter,
-  &_swigt__p_IVarianceFunction,
   &_swigt__p_IntensityDataIOFactory,
-  &_swigt__p_IntensityFunctionLog,
-  &_swigt__p_IntensityFunctionSqrt,
   &_swigt__p_IsGISAXSDetector,
   &_swigt__p_Line,
   &_swigt__p_OutputDataIteratorT_double_OutputDataT_double_t_t,
@@ -48217,8 +46818,6 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_ScanResolution,
   &_swigt__p_SimulationResult,
   &_swigt__p_SphericalDetector,
-  &_swigt__p_VarianceConstantFunction,
-  &_swigt__p_VarianceSimFunction,
   &_swigt__p_VerticalLine,
   &_swigt__p_allocator_type,
   &_swigt__p_bool,
@@ -48288,7 +46887,6 @@ static swig_cast_info _swigc__p_BasicVector3DT_int_t[] = {  {&_swigt__p_BasicVec
 static swig_cast_info _swigc__p_BasicVector3DT_std__complexT_double_t_t[] = {  {&_swigt__p_BasicVector3DT_std__complexT_double_t_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_Beam[] = {  {&_swigt__p_Beam, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_Bin1D[] = {  {&_swigt__p_Bin1D, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_ChiSquaredModule[] = {  {&_swigt__p_ChiSquaredModule, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_DetectionProperties[] = {  {&_swigt__p_DetectionProperties, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_DetectorMask[] = {  {&_swigt__p_DetectorMask, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_Direction[] = {  {&_swigt__p_Direction, 0, 0, 0},{0, 0, 0, 0}};
@@ -48299,9 +46897,8 @@ static swig_cast_info _swigc__p_Histogram1D[] = {  {&_swigt__p_Histogram1D, 0, 0
 static swig_cast_info _swigc__p_Histogram2D[] = {  {&_swigt__p_Histogram2D, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_HorizontalLine[] = {  {&_swigt__p_HorizontalLine, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IAxis[] = {  {&_swigt__p_IAxis, 0, 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_ParameterPool[] = {{&_swigt__p_ParameterPool, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_ICloneable[] = {  {&_swigt__p_FootprintGauss, _p_FootprintGaussTo_p_ICloneable, 0, 0},  {&_swigt__p_IDetectorResolution, _p_IDetectorResolutionTo_p_ICloneable, 0, 0},  {&_swigt__p_ScanResolution, _p_ScanResolutionTo_p_ICloneable, 0, 0},  {&_swigt__p_IDetector2D, _p_IDetector2DTo_p_ICloneable, 0, 0},  {&_swigt__p_Line, _p_LineTo_p_ICloneable, 0, 0},  {&_swigt__p_ICloneable, 0, 0, 0},  {&_swigt__p_Rectangle, _p_RectangleTo_p_ICloneable, 0, 0},  {&_swigt__p_ResolutionFunction2DGaussian, _p_ResolutionFunction2DGaussianTo_p_ICloneable, 0, 0},  {&_swigt__p_IFootprintFactor, _p_IFootprintFactorTo_p_ICloneable, 0, 0},  {&_swigt__p_IShape2D, _p_IShape2DTo_p_ICloneable, 0, 0},  {&_swigt__p_Ellipse, _p_EllipseTo_p_ICloneable, 0, 0},  {&_swigt__p_ParameterPool, _p_ParameterPoolTo_p_ICloneable, 0, 0},  {&_swigt__p_HorizontalLine, _p_HorizontalLineTo_p_ICloneable, 0, 0},  {&_swigt__p_VerticalLine, _p_VerticalLineTo_p_ICloneable, 0, 0},  {&_swigt__p_IChiSquaredModule, _p_IChiSquaredModuleTo_p_ICloneable, 0, 0},  {&_swigt__p_ChiSquaredModule, _p_ChiSquaredModuleTo_p_ICloneable, 0, 0},  {&_swigt__p_IsGISAXSDetector, _p_IsGISAXSDetectorTo_p_ICloneable, 0, 0},  {&_swigt__p_SphericalDetector, _p_SphericalDetectorTo_p_ICloneable, 0, 0},  {&_swigt__p_RectangularDetector, _p_RectangularDetectorTo_p_ICloneable, 0, 0},  {&_swigt__p_IDetector, _p_IDetectorTo_p_ICloneable, 0, 0},  {&_swigt__p_FootprintSquare, _p_FootprintSquareTo_p_ICloneable, 0, 0},  {&_swigt__p_Polygon, _p_PolygonTo_p_ICloneable, 0, 0},  {&_swigt__p_IUnitConverter, _p_IUnitConverterTo_p_ICloneable, 0, 0},  {&_swigt__p_IResolutionFunction2D, _p_IResolutionFunction2DTo_p_ICloneable, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_ICloneable[] = {  {&_swigt__p_FootprintGauss, _p_FootprintGaussTo_p_ICloneable, 0, 0},  {&_swigt__p_IDetectorResolution, _p_IDetectorResolutionTo_p_ICloneable, 0, 0},  {&_swigt__p_ScanResolution, _p_ScanResolutionTo_p_ICloneable, 0, 0},  {&_swigt__p_IDetector2D, _p_IDetector2DTo_p_ICloneable, 0, 0},  {&_swigt__p_Line, _p_LineTo_p_ICloneable, 0, 0},  {&_swigt__p_ICloneable, 0, 0, 0},  {&_swigt__p_Rectangle, _p_RectangleTo_p_ICloneable, 0, 0},  {&_swigt__p_ResolutionFunction2DGaussian, _p_ResolutionFunction2DGaussianTo_p_ICloneable, 0, 0},  {&_swigt__p_IFootprintFactor, _p_IFootprintFactorTo_p_ICloneable, 0, 0},  {&_swigt__p_IShape2D, _p_IShape2DTo_p_ICloneable, 0, 0},  {&_swigt__p_Ellipse, _p_EllipseTo_p_ICloneable, 0, 0},  {&_swigt__p_ParameterPool, _p_ParameterPoolTo_p_ICloneable, 0, 0},  {&_swigt__p_HorizontalLine, _p_HorizontalLineTo_p_ICloneable, 0, 0},  {&_swigt__p_VerticalLine, _p_VerticalLineTo_p_ICloneable, 0, 0},  {&_swigt__p_IsGISAXSDetector, _p_IsGISAXSDetectorTo_p_ICloneable, 0, 0},  {&_swigt__p_SphericalDetector, _p_SphericalDetectorTo_p_ICloneable, 0, 0},  {&_swigt__p_RectangularDetector, _p_RectangularDetectorTo_p_ICloneable, 0, 0},  {&_swigt__p_IDetector, _p_IDetectorTo_p_ICloneable, 0, 0},  {&_swigt__p_FootprintSquare, _p_FootprintSquareTo_p_ICloneable, 0, 0},  {&_swigt__p_Polygon, _p_PolygonTo_p_ICloneable, 0, 0},  {&_swigt__p_IUnitConverter, _p_IUnitConverterTo_p_ICloneable, 0, 0},  {&_swigt__p_IResolutionFunction2D, _p_IResolutionFunction2DTo_p_ICloneable, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_ParameterDistribution[] = {{&_swigt__p_ParameterDistribution, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IComponent[] = {  {&_swigt__p_Beam, _p_BeamTo_p_IComponent, 0, 0},  {&_swigt__p_FootprintGauss, _p_FootprintGaussTo_p_IComponent, 0, 0},  {&_swigt__p_IDetectorResolution, _p_IDetectorResolutionTo_p_IComponent, 0, 0},  {&_swigt__p_IDetector2D, _p_IDetector2DTo_p_IComponent, 0, 0},  {&_swigt__p_IParametricComponent, _p_IParametricComponentTo_p_IComponent, 0, 0},  {&_swigt__p_IComponent, 0, 0, 0},  {&_swigt__p_ResolutionFunction2DGaussian, _p_ResolutionFunction2DGaussianTo_p_IComponent, 0, 0},  {&_swigt__p_IFootprintFactor, _p_IFootprintFactorTo_p_IComponent, 0, 0},  {&_swigt__p_IDetector, _p_IDetectorTo_p_IComponent, 0, 0},  {&_swigt__p_IsGISAXSDetector, _p_IsGISAXSDetectorTo_p_IComponent, 0, 0},  {&_swigt__p_SphericalDetector, _p_SphericalDetectorTo_p_IComponent, 0, 0},  {&_swigt__p_RectangularDetector, _p_RectangularDetectorTo_p_IComponent, 0, 0},  {&_swigt__p_ParameterDistribution, _p_ParameterDistributionTo_p_IComponent, 0, 0},  {&_swigt__p_FootprintSquare, _p_FootprintSquareTo_p_IComponent, 0, 0},  {&_swigt__p_INode, _p_INodeTo_p_IComponent, 0, 0},  {&_swigt__p_IResolutionFunction2D, _p_IResolutionFunction2DTo_p_IComponent, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IDetector[] = {  {&_swigt__p_IDetector, 0, 0, 0},  {&_swigt__p_RectangularDetector, _p_RectangularDetectorTo_p_IDetector, 0, 0},  {&_swigt__p_SphericalDetector, _p_SphericalDetectorTo_p_IDetector, 0, 0},  {&_swigt__p_IsGISAXSDetector, _p_IsGISAXSDetectorTo_p_IDetector, 0, 0},  {&_swigt__p_IDetector2D, _p_IDetector2DTo_p_IDetector, 0, 0},{0, 0, 0, 0}};
@@ -48309,7 +46906,6 @@ static swig_cast_info _swigc__p_IDetector2D[] = {  {&_swigt__p_RectangularDetect
 static swig_cast_info _swigc__p_IDetectorResolution[] = {  {&_swigt__p_IDetectorResolution, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_IFootprintFactor[] = {  {&_swigt__p_FootprintSquare, _p_FootprintSquareTo_p_IFootprintFactor, 0, 0},  {&_swigt__p_IFootprintFactor, 0, 0, 0},  {&_swigt__p_FootprintGauss, _p_FootprintGaussTo_p_IFootprintFactor, 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_INode[] = {  {&_swigt__p_INode, 0, 0, 0},  {&_swigt__p_FootprintSquare, _p_FootprintSquareTo_p_INode, 0, 0},  {&_swigt__p_IDetectorResolution, _p_IDetectorResolutionTo_p_INode, 0, 0},  {&_swigt__p_IFootprintFactor, _p_IFootprintFactorTo_p_INode, 0, 0},  {&_swigt__p_Beam, _p_BeamTo_p_INode, 0, 0},  {&_swigt__p_IResolutionFunction2D, _p_IResolutionFunction2DTo_p_INode, 0, 0},  {&_swigt__p_ResolutionFunction2DGaussian, _p_ResolutionFunction2DGaussianTo_p_INode, 0, 0},  {&_swigt__p_IDetector, _p_IDetectorTo_p_INode, 0, 0},  {&_swigt__p_RectangularDetector, _p_RectangularDetectorTo_p_INode, 0, 0},  {&_swigt__p_SphericalDetector, _p_SphericalDetectorTo_p_INode, 0, 0},  {&_swigt__p_IsGISAXSDetector, _p_IsGISAXSDetectorTo_p_INode, 0, 0},  {&_swigt__p_FootprintGauss, _p_FootprintGaussTo_p_INode, 0, 0},  {&_swigt__p_IDetector2D, _p_IDetector2DTo_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_IParametricComponent[] = {  {&_swigt__p_Beam, _p_BeamTo_p_IParametricComponent, 0, 0},  {&_swigt__p_FootprintGauss, _p_FootprintGaussTo_p_IParametricComponent, 0, 0},  {&_swigt__p_IDetectorResolution, _p_IDetectorResolutionTo_p_IParametricComponent, 0, 0},  {&_swigt__p_IDetector2D, _p_IDetector2DTo_p_IParametricComponent, 0, 0},  {&_swigt__p_IParametricComponent, 0, 0, 0},  {&_swigt__p_ResolutionFunction2DGaussian, _p_ResolutionFunction2DGaussianTo_p_IParametricComponent, 0, 0},  {&_swigt__p_IFootprintFactor, _p_IFootprintFactorTo_p_IParametricComponent, 0, 0},  {&_swigt__p_IDetector, _p_IDetectorTo_p_IParametricComponent, 0, 0},  {&_swigt__p_IsGISAXSDetector, _p_IsGISAXSDetectorTo_p_IParametricComponent, 0, 0},  {&_swigt__p_SphericalDetector, _p_SphericalDetectorTo_p_IParametricComponent, 0, 0},  {&_swigt__p_RectangularDetector, _p_RectangularDetectorTo_p_IParametricComponent, 0, 0},  {&_swigt__p_ParameterDistribution, _p_ParameterDistributionTo_p_IParametricComponent, 0, 0},  {&_swigt__p_FootprintSquare, _p_FootprintSquareTo_p_IParametricComponent, 0, 0},  {&_swigt__p_INode, _p_INodeTo_p_IParametricComponent, 0, 0},  {&_swigt__p_IResolutionFunction2D, _p_IResolutionFunction2DTo_p_IParametricComponent, 0, 0},{0, 0, 0, 0}};
@@ -48318,10 +46914,7 @@ static swig_cast_info _swigc__p_IRangedDistribution[] = {  {&_swigt__p_IRangedDi
 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_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_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_IntensityDataIOFactory[] = {  {&_swigt__p_IntensityDataIOFactory, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_IntensityFunctionLog[] = {  {&_swigt__p_IntensityFunctionLog, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_IntensityFunctionSqrt[] = {  {&_swigt__p_IntensityFunctionSqrt, 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_Line[] = {  {&_swigt__p_Line, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_OutputDataIteratorT_double_OutputDataT_double_t_t[] = {  {&_swigt__p_OutputDataIteratorT_double_OutputDataT_double_t_t, 0, 0, 0},{0, 0, 0, 0}};
@@ -48339,8 +46932,6 @@ static swig_cast_info _swigc__p_ResolutionFunction2DGaussian[] = {  {&_swigt__p_
 static swig_cast_info _swigc__p_ScanResolution[] = {  {&_swigt__p_ScanResolution, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_SimulationResult[] = {  {&_swigt__p_SimulationResult, 0, 0, 0},{0, 0, 0, 0}};
 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_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_allocator_type[] = {  {&_swigt__p_allocator_type, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_bool[] = {  {&_swigt__p_bool, 0, 0, 0},{0, 0, 0, 0}};
@@ -48410,7 +47001,6 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_BasicVector3DT_std__complexT_double_t_t,
   _swigc__p_Beam,
   _swigc__p_Bin1D,
-  _swigc__p_ChiSquaredModule,
   _swigc__p_DetectionProperties,
   _swigc__p_DetectorMask,
   _swigc__p_Direction,
@@ -48421,7 +47011,6 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_Histogram2D,
   _swigc__p_HorizontalLine,
   _swigc__p_IAxis,
-  _swigc__p_IChiSquaredModule,
   _swigc__p_ICloneable,
   _swigc__p_IComponent,
   _swigc__p_IDetector,
@@ -48429,7 +47018,6 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_IDetectorResolution,
   _swigc__p_IFootprintFactor,
   _swigc__p_IHistogram,
-  _swigc__p_IIntensityFunction,
   _swigc__p_INode,
   _swigc__p_INodeVisitor,
   _swigc__p_IParametricComponent,
@@ -48438,10 +47026,7 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_IResolutionFunction2D,
   _swigc__p_IShape2D,
   _swigc__p_IUnitConverter,
-  _swigc__p_IVarianceFunction,
   _swigc__p_IntensityDataIOFactory,
-  _swigc__p_IntensityFunctionLog,
-  _swigc__p_IntensityFunctionSqrt,
   _swigc__p_IsGISAXSDetector,
   _swigc__p_Line,
   _swigc__p_OutputDataIteratorT_double_OutputDataT_double_t_t,
@@ -48461,8 +47046,6 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_ScanResolution,
   _swigc__p_SimulationResult,
   _swigc__p_SphericalDetector,
-  _swigc__p_VarianceConstantFunction,
-  _swigc__p_VarianceSimFunction,
   _swigc__p_VerticalLine,
   _swigc__p_allocator_type,
   _swigc__p_bool,
diff --git a/auto/Wrap/libBornAgainParam.py b/auto/Wrap/libBornAgainParam.py
index ccd5a62b6833e3e358e852330bdd8c104d177508..c71d60fdac9749296a5da6866f771410c9606da8 100644
--- a/auto/Wrap/libBornAgainParam.py
+++ b/auto/Wrap/libBornAgainParam.py
@@ -3257,7 +3257,7 @@ class INode(IParametricComponent):
         progeny(INode self) -> swig_dummy_type_const_inode_vector
         std::vector< const INode * > INode::progeny() const
 
-        Returns a vector of all descendents. 
+        Returns a vector of all descendants. 
 
         """
         return _libBornAgainParam.INode_progeny(self)
@@ -3447,7 +3447,7 @@ class INodeVisitor(object):
         visit(INodeVisitor self, LayerRoughness const * arg2)
         visit(INodeVisitor self, MesoCrystal const * arg2)
         visit(INodeVisitor self, MultiLayer const * arg2)
-        visit(INodeVisitor self, OffSpecSimulation const * arg2)
+        visit(INodeVisitor self, OffSpecularSimulation const * arg2)
         visit(INodeVisitor self, Particle const * arg2)
         visit(INodeVisitor self, ParticleComposition const * arg2)
         visit(INodeVisitor self, ParticleCoreShell const * arg2)
diff --git a/auto/Wrap/libBornAgainParam_wrap.cpp b/auto/Wrap/libBornAgainParam_wrap.cpp
index 52e2a6cca627deb63db10d156a8ffa3774db2037..2a796b58236968c7b86f9192350fd47479105853 100644
--- a/auto/Wrap/libBornAgainParam_wrap.cpp
+++ b/auto/Wrap/libBornAgainParam_wrap.cpp
@@ -3213,7 +3213,7 @@ namespace Swig {
 #define SWIGTYPE_p_MesoCrystal swig_types[113]
 #define SWIGTYPE_p_MultiLayer swig_types[114]
 #define SWIGTYPE_p_NodeMeta swig_types[115]
-#define SWIGTYPE_p_OffSpecSimulation swig_types[116]
+#define SWIGTYPE_p_OffSpecularSimulation swig_types[116]
 #define SWIGTYPE_p_ParaMeta swig_types[117]
 #define SWIGTYPE_p_ParameterDistribution swig_types[118]
 #define SWIGTYPE_p_ParameterPool swig_types[119]
@@ -25163,7 +25163,7 @@ SWIGINTERN PyObject *_wrap_kvector_t_complex(PyObject *SWIGUNUSEDPARM(self), PyO
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject *swig_obj[1] ;
-  BasicVector3D< std::complex< double > > result;
+  BasicVector3D< complex_t > result;
   
   if (!args) SWIG_fail;
   swig_obj[0] = args;
@@ -25173,7 +25173,7 @@ SWIGINTERN PyObject *_wrap_kvector_t_complex(PyObject *SWIGUNUSEDPARM(self), PyO
   }
   arg1 = reinterpret_cast< BasicVector3D< double > * >(argp1);
   result = ((BasicVector3D< double > const *)arg1)->complex();
-  resultobj = SWIG_NewPointerObj((new BasicVector3D< std::complex< double > >(static_cast< const BasicVector3D< std::complex< double > >& >(result))), SWIGTYPE_p_BasicVector3DT_std__complexT_double_t_t, SWIG_POINTER_OWN |  0 );
+  resultobj = SWIG_NewPointerObj((new BasicVector3D< complex_t >(static_cast< const BasicVector3D< complex_t >& >(result))), SWIGTYPE_p_BasicVector3DT_std__complexT_double_t_t, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -39947,7 +39947,7 @@ fail:
 SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_105(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
   PyObject *resultobj = 0;
   INodeVisitor *arg1 = (INodeVisitor *) 0 ;
-  OffSpecSimulation *arg2 = (OffSpecSimulation *) 0 ;
+  OffSpecularSimulation *arg2 = (OffSpecularSimulation *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
@@ -39959,12 +39959,12 @@ SWIGINTERN PyObject *_wrap_INodeVisitor_visit__SWIG_105(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(swig_obj[1], &argp2,SWIGTYPE_p_OffSpecSimulation, 0 |  0 );
+  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2,SWIGTYPE_p_OffSpecularSimulation, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "INodeVisitor_visit" "', argument " "2"" of type '" "OffSpecSimulation const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "INodeVisitor_visit" "', argument " "2"" of type '" "OffSpecularSimulation const *""'"); 
   }
-  arg2 = reinterpret_cast< OffSpecSimulation * >(argp2);
-  (arg1)->visit((OffSpecSimulation const *)arg2);
+  arg2 = reinterpret_cast< OffSpecularSimulation * >(argp2);
+  (arg1)->visit((OffSpecularSimulation const *)arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -41877,7 +41877,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_OffSpecSimulation, 0);
+      int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_OffSpecularSimulation, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_INodeVisitor_visit__SWIG_105(self, argc, argv);
@@ -42203,7 +42203,7 @@ fail:
     "    INodeVisitor::visit(LayerRoughness const *)\n"
     "    INodeVisitor::visit(MesoCrystal const *)\n"
     "    INodeVisitor::visit(MultiLayer const *)\n"
-    "    INodeVisitor::visit(OffSpecSimulation const *)\n"
+    "    INodeVisitor::visit(OffSpecularSimulation const *)\n"
     "    INodeVisitor::visit(Particle const *)\n"
     "    INodeVisitor::visit(ParticleComposition const *)\n"
     "    INodeVisitor::visit(ParticleCoreShell const *)\n"
@@ -51231,7 +51231,7 @@ static PyMethodDef SwigMethods[] = {
 		"INode_progeny(INode self) -> swig_dummy_type_const_inode_vector\n"
 		"std::vector< const INode * > INode::progeny() const\n"
 		"\n"
-		"Returns a vector of all descendents. \n"
+		"Returns a vector of all descendants. \n"
 		"\n"
 		""},
 	 { "INode_setParent", _wrap_INode_setParent, METH_VARARGS, "\n"
@@ -51385,7 +51385,7 @@ static PyMethodDef SwigMethods[] = {
 		"INodeVisitor_visit(INodeVisitor self, LayerRoughness const * arg2)\n"
 		"INodeVisitor_visit(INodeVisitor self, MesoCrystal const * arg2)\n"
 		"INodeVisitor_visit(INodeVisitor self, MultiLayer const * arg2)\n"
-		"INodeVisitor_visit(INodeVisitor self, OffSpecSimulation const * arg2)\n"
+		"INodeVisitor_visit(INodeVisitor self, OffSpecularSimulation const * arg2)\n"
 		"INodeVisitor_visit(INodeVisitor self, Particle const * arg2)\n"
 		"INodeVisitor_visit(INodeVisitor self, ParticleComposition const * arg2)\n"
 		"INodeVisitor_visit(INodeVisitor self, ParticleCoreShell const * arg2)\n"
@@ -52298,7 +52298,7 @@ static swig_type_info _swigt__p_Attributes = {"_p_Attributes", "Attributes *", 0
 static swig_type_info _swigt__p_BasicLattice2D = {"_p_BasicLattice2D", "BasicLattice2D *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_BasicVector3DT_double_t = {"_p_BasicVector3DT_double_t", "std::vector< BasicVector3D< double > >::value_type *|kvector_t *|BasicVector3D< double > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_BasicVector3DT_int_t = {"_p_BasicVector3DT_int_t", "ivector_t *|BasicVector3D< int > *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_BasicVector3DT_std__complexT_double_t_t = {"_p_BasicVector3DT_std__complexT_double_t_t", "BasicVector3D< std::complex< double > > *|std::vector< BasicVector3D< std::complex< double > > >::value_type *|cvector_t *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_BasicVector3DT_std__complexT_double_t_t = {"_p_BasicVector3DT_std__complexT_double_t_t", "BasicVector3D< std::complex< double > > *|std::vector< BasicVector3D< std::complex< double > > >::value_type *|cvector_t *|BasicVector3D< complex_t > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Beam = {"_p_Beam", "Beam *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_ConstantBackground = {"_p_ConstantBackground", "ConstantBackground *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_ConvolutionDetectorResolution = {"_p_ConvolutionDetectorResolution", "ConvolutionDetectorResolution *", 0, 0, (void*)0, 0};
@@ -52410,7 +52410,7 @@ static swig_type_info _swigt__p_LayerRoughness = {"_p_LayerRoughness", "LayerRou
 static swig_type_info _swigt__p_MesoCrystal = {"_p_MesoCrystal", "MesoCrystal *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_MultiLayer = {"_p_MultiLayer", "MultiLayer *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_NodeMeta = {"_p_NodeMeta", "NodeMeta *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_OffSpecSimulation = {"_p_OffSpecSimulation", "OffSpecSimulation *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_OffSpecularSimulation = {"_p_OffSpecularSimulation", "OffSpecularSimulation *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_ParaMeta = {"_p_ParaMeta", "ParaMeta *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_ParameterDistribution = {"_p_ParameterDistribution", "ParameterDistribution *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_ParameterPool = {"_p_ParameterPool", "ParameterPool *", 0, 0, (void*)0, 0};
@@ -52611,7 +52611,7 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_MesoCrystal,
   &_swigt__p_MultiLayer,
   &_swigt__p_NodeMeta,
-  &_swigt__p_OffSpecSimulation,
+  &_swigt__p_OffSpecularSimulation,
   &_swigt__p_ParaMeta,
   &_swigt__p_ParameterDistribution,
   &_swigt__p_ParameterPool,
@@ -52812,7 +52812,7 @@ static swig_cast_info _swigc__p_LayerRoughness[] = {  {&_swigt__p_LayerRoughness
 static swig_cast_info _swigc__p_MesoCrystal[] = {  {&_swigt__p_MesoCrystal, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_MultiLayer[] = {  {&_swigt__p_MultiLayer, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_NodeMeta[] = {  {&_swigt__p_NodeMeta, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_OffSpecSimulation[] = {  {&_swigt__p_OffSpecSimulation, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_OffSpecularSimulation[] = {  {&_swigt__p_OffSpecularSimulation, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_ParaMeta[] = {  {&_swigt__p_ParaMeta, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_ParameterDistribution[] = {  {&_swigt__p_ParameterDistribution, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_ParameterPool[] = {  {&_swigt__p_ParameterPool, 0, 0, 0},{0, 0, 0, 0}};
@@ -53013,7 +53013,7 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_MesoCrystal,
   _swigc__p_MultiLayer,
   _swigc__p_NodeMeta,
-  _swigc__p_OffSpecSimulation,
+  _swigc__p_OffSpecularSimulation,
   _swigc__p_ParaMeta,
   _swigc__p_ParameterDistribution,
   _swigc__p_ParameterPool,
diff --git a/auto/Wrap/libBornAgainSample.py b/auto/Wrap/libBornAgainSample.py
index fdbdd51b1e11202bd84c6e045e438a5eef0b6eb2..07ed91ac638bc004e6c607b482b9d14417a489bf 100644
--- a/auto/Wrap/libBornAgainSample.py
+++ b/auto/Wrap/libBornAgainSample.py
@@ -8258,7 +8258,7 @@ class Layer(ISampleNode):
     r"""
 
 
-    A layer, with thickness (in nanometer) and material.
+    A layer in a  MultiLayer sample.
 
     C++ includes: Layer.h
 
@@ -11370,7 +11370,14 @@ class Lattice3D(libBornAgainParam.INode):
 _libBornAgainSample.Lattice3D_swigregister(Lattice3D)
 
 class Lattice2D(libBornAgainBase.ICloneable, libBornAgainParam.INode):
-    r"""Proxy of C++ Lattice2D class."""
+    r"""
+
+
+    A two-dimensional Bravais lattice.
+
+    C++ includes: Lattice2D.h
+
+    """
 
     thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
 
@@ -11447,7 +11454,14 @@ class Lattice2D(libBornAgainBase.ICloneable, libBornAgainParam.INode):
 _libBornAgainSample.Lattice2D_swigregister(Lattice2D)
 
 class BasicLattice2D(Lattice2D):
-    r"""Proxy of C++ BasicLattice2D class."""
+    r"""
+
+
+    A two-dimensional Bravais lattice with no special symmetry.
+
+    C++ includes: Lattice2D.h
+
+    """
 
     thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
     __repr__ = _swig_repr
@@ -11513,7 +11527,14 @@ class BasicLattice2D(Lattice2D):
 _libBornAgainSample.BasicLattice2D_swigregister(BasicLattice2D)
 
 class SquareLattice2D(Lattice2D):
-    r"""Proxy of C++ SquareLattice2D class."""
+    r"""
+
+
+    A two-dimensional Bravais lattice with square unit cell.
+
+    C++ includes: Lattice2D.h
+
+    """
 
     thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
     __repr__ = _swig_repr
@@ -11579,7 +11600,14 @@ class SquareLattice2D(Lattice2D):
 _libBornAgainSample.SquareLattice2D_swigregister(SquareLattice2D)
 
 class HexagonalLattice2D(Lattice2D):
-    r"""Proxy of C++ HexagonalLattice2D class."""
+    r"""
+
+
+    A two-dimensional Bravais lattice with hexagonal symmetry.
+
+    C++ includes: Lattice2D.h
+
+    """
 
     thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
     __repr__ = _swig_repr
diff --git a/auto/Wrap/libBornAgainSample_wrap.cpp b/auto/Wrap/libBornAgainSample_wrap.cpp
index 53071a0b3fb570f28157af990b8903e60825cd04..2b3a728a2b5ed0018bfe039fe493ce64b690eaaf 100644
--- a/auto/Wrap/libBornAgainSample_wrap.cpp
+++ b/auto/Wrap/libBornAgainSample_wrap.cpp
@@ -26598,7 +26598,7 @@ SWIGINTERN PyObject *_wrap_kvector_t_complex(PyObject *SWIGUNUSEDPARM(self), PyO
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject *swig_obj[1] ;
-  BasicVector3D< std::complex< double > > result;
+  BasicVector3D< complex_t > result;
   
   if (!args) SWIG_fail;
   swig_obj[0] = args;
@@ -26608,7 +26608,7 @@ SWIGINTERN PyObject *_wrap_kvector_t_complex(PyObject *SWIGUNUSEDPARM(self), PyO
   }
   arg1 = reinterpret_cast< BasicVector3D< double > * >(argp1);
   result = ((BasicVector3D< double > const *)arg1)->complex();
-  resultobj = SWIG_NewPointerObj((new BasicVector3D< std::complex< double > >(static_cast< const BasicVector3D< std::complex< double > >& >(result))), SWIGTYPE_p_BasicVector3DT_std__complexT_double_t_t, SWIG_POINTER_OWN |  0 );
+  resultobj = SWIG_NewPointerObj((new BasicVector3D< complex_t >(static_cast< const BasicVector3D< complex_t >& >(result))), SWIGTYPE_p_BasicVector3DT_std__complexT_double_t_t, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -77485,7 +77485,7 @@ static void *_p_FTDistribution2DConeTo_p_IFTDistribution2D(void *x, int *SWIGUNU
 static swig_type_info _swigt__p_BasicLattice2D = {"_p_BasicLattice2D", "BasicLattice2D *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_BasicVector3DT_double_t = {"_p_BasicVector3DT_double_t", "std::vector< BasicVector3D< double > >::value_type *|kvector_t *|BasicVector3D< double > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_BasicVector3DT_int_t = {"_p_BasicVector3DT_int_t", "ivector_t *|BasicVector3D< int > *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_BasicVector3DT_std__complexT_double_t_t = {"_p_BasicVector3DT_std__complexT_double_t_t", "BasicVector3D< std::complex< double > > *|std::vector< BasicVector3D< std::complex< double > > >::value_type *|cvector_t *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_BasicVector3DT_std__complexT_double_t_t = {"_p_BasicVector3DT_std__complexT_double_t_t", "BasicVector3D< std::complex< double > > *|std::vector< BasicVector3D< std::complex< double > > >::value_type *|cvector_t *|BasicVector3D< complex_t > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_CallbackMap_t = {"_p_CallbackMap_t", "CallbackMap_t *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_CreateItemCallback = {"_p_CreateItemCallback", "CreateItemCallback *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Crystal = {"_p_Crystal", "Crystal *", 0, 0, (void*)0, 0};
diff --git a/cmake/BornAgain/MakeLib.cmake b/cmake/BornAgain/MakeLib.cmake
index 684f2421896567e07b49621513b0f833a189788f..3e2d6ea84ae001c04cd531fe5d5e03ea6b34e0fe 100644
--- a/cmake/BornAgain/MakeLib.cmake
+++ b/cmake/BornAgain/MakeLib.cmake
@@ -1,3 +1,5 @@
+# Configure one component library.
+
 function(MakeLib name lib tmpdir)
 
     if(BORNAGAIN_PYTHON)
diff --git a/cmake/BornAgain/PythonDocs.cmake b/cmake/BornAgain/PythonDocs.cmake
index 4d880d703c78a39e5e78bd33b45fd8bf253effc4..38a218ef900ba492e309747a5518735bf604a1a6 100644
--- a/cmake/BornAgain/PythonDocs.cmake
+++ b/cmake/BornAgain/PythonDocs.cmake
@@ -1,4 +1,5 @@
 # Autogenerate a .i file from doxygen comments, provided -DCONFIGURE_PYTHON_DOCS=ON.
+# Called from function SwigLib.
 
 function(GeneratePythonDocs PD_TARGET SWIG_DIR)
     if(CONFIGURE_PYTHON_DOCS)
diff --git a/cmake/BornAgain/SwigLib.cmake b/cmake/BornAgain/SwigLib.cmake
index 8495507f5abb54507c8e5ca21633058447a9ee0e..1513b5e1c459509b14e8aa300148e99e48fc4329 100644
--- a/cmake/BornAgain/SwigLib.cmake
+++ b/cmake/BornAgain/SwigLib.cmake
@@ -1,3 +1,6 @@
+# Configure Python bindings for one component library.
+# Called from function MakeLib.
+
 function(SwigLib name lib TMP_DIR)
 
     if(NOT BORNAGAIN_PYTHON)
@@ -10,8 +13,7 @@ function(SwigLib name lib TMP_DIR)
 
         file(MAKE_DIRECTORY ${TMP_DIR})
 
-        GeneratePythonDocs(${AUTO_DIR}/doxygen${name}.i ${SWIG_DIR})
-
+        # static (manually written) input files
         set(swig_dependencies
             ${SWIG_DIR}/lib${lib}.i
             ${SWIG_DIR}/deprecation.i
@@ -24,6 +26,9 @@ function(SwigLib name lib TMP_DIR)
                 message(FATAL_ERROR "Could NOT find SWIG input ${FNAM}")
             endif()
         endforeach()
+
+        # dynamic (autogenerated) input files
+        GeneratePythonDocs(${AUTO_DIR}/doxygen${name}.i ${SWIG_DIR})
         list(APPEND swig_dependencies ${AUTO_DIR}/doxygen${name}.i)
 
         # Run Swig.
diff --git a/devtools/code-tools/normalize-usercode.py b/devtools/code-tools/normalize-usercode.py
index 10a0435382c65c525acc2026ac6b5b85c71d903d..3ccc50cf499d269f1238164cc92008c0a53947a5 100755
--- a/devtools/code-tools/normalize-usercode.py
+++ b/devtools/code-tools/normalize-usercode.py
@@ -100,6 +100,7 @@ def normalize_file(fname, inplace):
     result = run_simulation\(\)
     ba.plot_simulation_result\(result, cmap='jet', aspect='auto'\)""", ti)
         if not m:
+            print('=> non-standard => SKIPPED')
             return 3
 
         # normalize
@@ -107,8 +108,7 @@ def normalize_file(fname, inplace):
         if verbose:
             print(f'.. obtained normalized text')
         if tf == ti:
-            if verbose:
-                print(f'.. nothing changed')
+            print(f'=> OK (nothing to change)')
             return 0
         with open('out1.py', 'w') as f:
             f.write(tf)