diff --git a/Base/Axis/PointwiseAxis.h b/Base/Axis/PointwiseAxis.h
index 11c93bdc05377eff6d3fc70e7288f0ff741d1fc3..82499fcde21ebbecd80dc9daadd6dc32ce1dc95e 100644
--- a/Base/Axis/PointwiseAxis.h
+++ b/Base/Axis/PointwiseAxis.h
@@ -12,6 +12,10 @@
 //
 //  ************************************************************************************************
 
+#ifdef SWIG
+#error no need to expose this header to Swig
+#endif
+
 #ifndef BORNAGAIN_BASE_AXIS_POINTWISEAXIS_H
 #define BORNAGAIN_BASE_AXIS_POINTWISEAXIS_H
 
diff --git a/Base/Const/PhysicalConstants.h b/Base/Const/PhysicalConstants.h
index 57ffbf941a84420472b682422040a849deee5616..d76ddd9afa14bff4c709a72e345e35efd90f21df 100644
--- a/Base/Const/PhysicalConstants.h
+++ b/Base/Const/PhysicalConstants.h
@@ -12,6 +12,10 @@
 //
 //  ************************************************************************************************
 
+#ifdef SWIG
+#error no need to expose this header to Swig
+#endif
+
 #ifndef BORNAGAIN_BASE_CONST_PHYSICALCONSTANTS_H
 #define BORNAGAIN_BASE_CONST_PHYSICALCONSTANTS_H
 
diff --git a/Base/Math/Bessel.h b/Base/Math/Bessel.h
index 12382765e8b1126fea0a4f899137d8d748e16f4e..cdc9c69350942e10ca39338706ca00adf7957c8e 100644
--- a/Base/Math/Bessel.h
+++ b/Base/Math/Bessel.h
@@ -12,6 +12,10 @@
 //
 //  ************************************************************************************************
 
+#ifdef SWIG
+#error no need to expose this header to Swig
+#endif
+
 #ifndef BORNAGAIN_BASE_MATH_BESSEL_H
 #define BORNAGAIN_BASE_MATH_BESSEL_H
 
diff --git a/Base/Math/Constants.h b/Base/Math/Constants.h
index 1bef78cfbed3ea559f41786130c45582171b4de0..a0ea072179330815627b6d786d0bf8654cd8a085 100644
--- a/Base/Math/Constants.h
+++ b/Base/Math/Constants.h
@@ -12,6 +12,10 @@
 //
 //  ************************************************************************************************
 
+#ifdef SWIG
+#error no need to expose this header to Swig
+#endif
+
 #ifndef BORNAGAIN_BASE_MATH_CONSTANTS_H
 #define BORNAGAIN_BASE_MATH_CONSTANTS_H
 
diff --git a/Base/Math/Functions.h b/Base/Math/Functions.h
index 7fe8560926673b03a9988e585cde02500323eb5c..4455282d90c3309291586b00f931dc0f2838e247 100644
--- a/Base/Math/Functions.h
+++ b/Base/Math/Functions.h
@@ -12,6 +12,10 @@
 //
 //  ************************************************************************************************
 
+#ifdef SWIG
+#error no need to expose this header to Swig
+#endif
+
 #ifndef BORNAGAIN_BASE_MATH_FUNCTIONS_H
 #define BORNAGAIN_BASE_MATH_FUNCTIONS_H
 
diff --git a/Base/Math/IntegratorGK.h b/Base/Math/IntegratorGK.h
index d89b44c4b02980f5f588811aa7930fca6b016d08..b498482148577ab9e53ae14dbec43af81300c38f 100644
--- a/Base/Math/IntegratorGK.h
+++ b/Base/Math/IntegratorGK.h
@@ -12,6 +12,10 @@
 //
 //  ************************************************************************************************
 
+#ifdef SWIG
+#error no need to expose this header to Swig
+#endif
+
 #ifndef BORNAGAIN_BASE_MATH_INTEGRATORGK_H
 #define BORNAGAIN_BASE_MATH_INTEGRATORGK_H
 
diff --git a/Base/Math/IntegratorMCMiser.h b/Base/Math/IntegratorMCMiser.h
index a5f78213c718a348da4f08c3ceb4658eba3d2641..6ebd742efe8ff86ec0be1836029ca7334bf2000c 100644
--- a/Base/Math/IntegratorMCMiser.h
+++ b/Base/Math/IntegratorMCMiser.h
@@ -12,6 +12,10 @@
 //
 //  ************************************************************************************************
 
+#ifdef SWIG
+#error no need to expose this header to Swig
+#endif
+
 #ifndef BORNAGAIN_BASE_MATH_INTEGRATORMCMISER_H
 #define BORNAGAIN_BASE_MATH_INTEGRATORMCMISER_H
 
diff --git a/Base/Math/Numeric.h b/Base/Math/Numeric.h
index dbaec088c6eb1213416b545ef486cb8b31d7f5cf..252fa097229c3690e926216c6f751375aeba4a62 100644
--- a/Base/Math/Numeric.h
+++ b/Base/Math/Numeric.h
@@ -12,6 +12,10 @@
 //
 //  ************************************************************************************************
 
+#ifdef SWIG
+#error no need to expose this header to Swig
+#endif
+
 #ifndef BORNAGAIN_BASE_MATH_NUMERIC_H
 #define BORNAGAIN_BASE_MATH_NUMERIC_H
 
diff --git a/Base/Math/Precomputed.h b/Base/Math/Precomputed.h
index 2cafed73754b4166b5119d2122dc481d81005953..8270134a5ec1502fd0f09f64f8e213911f58ed9f 100644
--- a/Base/Math/Precomputed.h
+++ b/Base/Math/Precomputed.h
@@ -12,6 +12,10 @@
 //
 //  ************************************************************************************************
 
+#ifdef SWIG
+#error no need to expose this header to Swig
+#endif
+
 #ifndef BORNAGAIN_BASE_MATH_PRECOMPUTED_H
 #define BORNAGAIN_BASE_MATH_PRECOMPUTED_H
 
diff --git a/Base/Pixel/PolarizationHandler.h b/Base/Pixel/PolarizationHandler.h
index 2c0df2cd0ba75c08b47e1c372bd454d46552387a..9f4ce9240d33e23b725ee5bac7a638c0949dc03d 100644
--- a/Base/Pixel/PolarizationHandler.h
+++ b/Base/Pixel/PolarizationHandler.h
@@ -12,6 +12,10 @@
 //
 //  ************************************************************************************************
 
+#ifdef SWIG
+#error no need to expose this header to Swig
+#endif
+
 #ifndef BORNAGAIN_BASE_PIXEL_POLARIZATIONHANDLER_H
 #define BORNAGAIN_BASE_PIXEL_POLARIZATIONHANDLER_H
 
diff --git a/Base/Pixel/SimulationElement.h b/Base/Pixel/SimulationElement.h
index ca16173a6ffab41f3f1907ff6b532bfdf5ca799d..102b7553a51e3fb212fa3faa72a57b002e1f2af8 100644
--- a/Base/Pixel/SimulationElement.h
+++ b/Base/Pixel/SimulationElement.h
@@ -12,6 +12,10 @@
 //
 //  ************************************************************************************************
 
+#ifdef SWIG
+#error no need to expose this header to Swig
+#endif
+
 #ifndef BORNAGAIN_BASE_PIXEL_SIMULATIONELEMENT_H
 #define BORNAGAIN_BASE_PIXEL_SIMULATIONELEMENT_H
 
diff --git a/Base/Progress/DelayedProgressCounter.h b/Base/Progress/DelayedProgressCounter.h
index c3aaa0cf1c41eb3a2cd7f34f1176bd2e156d2abc..9667d009de71e2fc63b598183d16ce3ed4a06dcb 100644
--- a/Base/Progress/DelayedProgressCounter.h
+++ b/Base/Progress/DelayedProgressCounter.h
@@ -12,6 +12,10 @@
 //
 //  ************************************************************************************************
 
+#ifdef SWIG
+#error no need to expose this header to Swig
+#endif
+
 #ifndef BORNAGAIN_BASE_PROGRESS_DELAYEDPROGRESSCOUNTER_H
 #define BORNAGAIN_BASE_PROGRESS_DELAYEDPROGRESSCOUNTER_H
 
diff --git a/Base/Progress/ProgressHandler.h b/Base/Progress/ProgressHandler.h
index b44edef0e70f37ac18f7814e3866e29964a9e268..02b2ba6a4d8bd3899b2cfefebab03a6e4b074a03 100644
--- a/Base/Progress/ProgressHandler.h
+++ b/Base/Progress/ProgressHandler.h
@@ -12,6 +12,10 @@
 //
 //  ************************************************************************************************
 
+#ifdef SWIG
+#error no need to expose this header to Swig
+#endif
+
 #ifndef BORNAGAIN_BASE_PROGRESS_PROGRESSHANDLER_H
 #define BORNAGAIN_BASE_PROGRESS_PROGRESSHANDLER_H
 
diff --git a/Base/Py/PyEmbeddedUtils.h b/Base/Py/PyEmbeddedUtils.h
index 2a73c311a80f6695c2539123822e4711d3c492d8..c24cbb109c189e354ccdb36ea37b6824d8da1ada 100644
--- a/Base/Py/PyEmbeddedUtils.h
+++ b/Base/Py/PyEmbeddedUtils.h
@@ -12,6 +12,10 @@
 //
 //  ************************************************************************************************
 
+#ifdef SWIG
+#error no need to expose this header to Swig
+#endif
+
 #ifndef BORNAGAIN_BASE_PY_PYEMBEDDEDUTILS_H
 #define BORNAGAIN_BASE_PY_PYEMBEDDEDUTILS_H
 
diff --git a/Base/Py/PyObject.h b/Base/Py/PyObject.h
index 67945360787b0148f4bd776511a1326f6de910de..c22c63aa9c24429c8b86a233db03849f7a86db56 100644
--- a/Base/Py/PyObject.h
+++ b/Base/Py/PyObject.h
@@ -12,6 +12,10 @@
 //
 //  ************************************************************************************************
 
+#ifdef SWIG
+#error no need to expose this header to Swig
+#endif
+
 #ifndef BORNAGAIN_BASE_PY_PYOBJECT_H
 #define BORNAGAIN_BASE_PY_PYOBJECT_H
 
diff --git a/Base/Py/PythonCore.h b/Base/Py/PythonCore.h
index 62f2f4d87fbaad9b849a9175a543e52f92ad2c83..380e25400ca5dc78583b0f2f28e35f2b259c73cb 100644
--- a/Base/Py/PythonCore.h
+++ b/Base/Py/PythonCore.h
@@ -12,6 +12,10 @@
 //
 //  ************************************************************************************************
 
+#ifdef SWIG
+#error no need to expose this header to Swig
+#endif
+
 #ifndef BORNAGAIN_BASE_PY_PYTHONCORE_H
 #define BORNAGAIN_BASE_PY_PYTHONCORE_H
 
diff --git a/Base/Types/CloneableVector.h b/Base/Types/CloneableVector.h
index 3ebf585d1a77035259865fdc5b0aa2893c697014..5ed210b48d826f69382a9d55bbc3c9f1e928981d 100644
--- a/Base/Types/CloneableVector.h
+++ b/Base/Types/CloneableVector.h
@@ -12,6 +12,10 @@
 //
 //  ************************************************************************************************
 
+#ifdef SWIG
+#error no need to expose this header to Swig
+#endif
+
 #ifndef BORNAGAIN_BASE_TYPES_CLONEABLEVECTOR_H
 #define BORNAGAIN_BASE_TYPES_CLONEABLEVECTOR_H
 
diff --git a/Base/Types/SafePointerVector.h b/Base/Types/SafePointerVector.h
index 634ba9c1dfb6f95a1180549b88b89b3f976ce0a0..257ccc8987e0143bfa56356e718533865f95156b 100644
--- a/Base/Types/SafePointerVector.h
+++ b/Base/Types/SafePointerVector.h
@@ -12,6 +12,10 @@
 //
 //  ************************************************************************************************
 
+#ifdef SWIG
+#error no need to expose this header to Swig
+#endif
+
 #ifndef BORNAGAIN_BASE_TYPES_SAFEPOINTERVECTOR_H
 #define BORNAGAIN_BASE_TYPES_SAFEPOINTERVECTOR_H
 
diff --git a/Base/Utils/Algorithms.h b/Base/Utils/Algorithms.h
index 2e14d76e2c1b4b16f326d921717b4e1ae5777571..f5e6a6d181826d78732a6fcaa7f7d67e1f77cfac 100644
--- a/Base/Utils/Algorithms.h
+++ b/Base/Utils/Algorithms.h
@@ -12,6 +12,10 @@
 //
 //  ************************************************************************************************
 
+#ifdef SWIG
+#error no need to expose this header to Swig
+#endif
+
 #ifndef BORNAGAIN_BASE_UTILS_ALGORITHMS_H
 #define BORNAGAIN_BASE_UTILS_ALGORITHMS_H
 
diff --git a/Base/Utils/Assert.h b/Base/Utils/Assert.h
index d074536f21b481f3d0b589ff40ec4bb4ca90f03b..a4f3bcd3e691c644ffe74d2dfe95124b4eafd217 100644
--- a/Base/Utils/Assert.h
+++ b/Base/Utils/Assert.h
@@ -12,6 +12,10 @@
 //
 //  ************************************************************************************************
 
+#ifdef SWIG
+#error no need to expose this header to Swig
+#endif
+
 #ifndef BORNAGAIN_BASE_UTILS_ASSERT_H
 #define BORNAGAIN_BASE_UTILS_ASSERT_H
 
diff --git a/Base/Utils/FileSystemUtils.h b/Base/Utils/FileSystemUtils.h
index c3ca55c2254fd4adc45a15c8906373cfe4fb0ebf..86dc937ae8a76f5b2b145f97eb39788aeb8fb14f 100644
--- a/Base/Utils/FileSystemUtils.h
+++ b/Base/Utils/FileSystemUtils.h
@@ -12,6 +12,10 @@
 //
 //  ************************************************************************************************
 
+#ifdef SWIG
+#error no need to expose this header to Swig
+#endif
+
 #ifndef BORNAGAIN_BASE_UTILS_FILESYSTEMUTILS_H
 #define BORNAGAIN_BASE_UTILS_FILESYSTEMUTILS_H
 
diff --git a/Base/Utils/IFactory.h b/Base/Utils/IFactory.h
index c33f0572fb38c8bc249f4826a0462f8dfef862b0..9e2c142ace042df904959deea2e5546b6ee971f1 100644
--- a/Base/Utils/IFactory.h
+++ b/Base/Utils/IFactory.h
@@ -12,6 +12,10 @@
 //
 //  ************************************************************************************************
 
+#ifdef SWIG
+#error no need to expose this header to Swig
+#endif
+
 #ifndef BORNAGAIN_BASE_UTILS_IFACTORY_H
 #define BORNAGAIN_BASE_UTILS_IFACTORY_H
 
diff --git a/Base/Utils/StringUtils.h b/Base/Utils/StringUtils.h
index e4b458915f50cf889135594de25782666b3f3e07..73c26cd0bbf5a96c10b34392c9f71c981b0640a0 100644
--- a/Base/Utils/StringUtils.h
+++ b/Base/Utils/StringUtils.h
@@ -12,6 +12,10 @@
 //
 //  ************************************************************************************************
 
+#ifdef SWIG
+#error no need to expose this header to Swig
+#endif
+
 #ifndef BORNAGAIN_BASE_UTILS_STRINGUTILS_H
 #define BORNAGAIN_BASE_UTILS_STRINGUTILS_H
 
diff --git a/Base/Utils/SysUtils.h b/Base/Utils/SysUtils.h
index ea00e83d117befb4f664d843279df64a0d074b3e..536ff1333ddd40bd07c7f1e9742e992d682f07c8 100644
--- a/Base/Utils/SysUtils.h
+++ b/Base/Utils/SysUtils.h
@@ -12,6 +12,10 @@
 //
 //  ************************************************************************************************
 
+#ifdef SWIG
+#error no need to expose this header to Swig
+#endif
+
 #ifndef BORNAGAIN_BASE_UTILS_SYSUTILS_H
 #define BORNAGAIN_BASE_UTILS_SYSUTILS_H
 
diff --git a/Base/Vector/BasicVector3D.h b/Base/Vector/BasicVector3D.h
index 8c32bfde7f187e491772b63123f19860eadac6e7..eac697c326adb3aa85db79150a609095c080003e 100644
--- a/Base/Vector/BasicVector3D.h
+++ b/Base/Vector/BasicVector3D.h
@@ -33,14 +33,14 @@ public:
     // Constructors and other set functions
     // -------------------------------------------------------------------------
 
-    //! Default constructor.
+    //! Constructs the null vector.
     BasicVector3D() {
         v_[0] = 0.0;
         v_[1] = 0.0;
         v_[2] = 0.0;
     }
 
-    //! Constructor from cartesian components.
+    //! Constructs a vector from cartesian components.
     BasicVector3D(const T x1, const T y1, const T z1) {
         v_[0] = x1;
         v_[1] = y1;
diff --git a/Base/Vector/EigenCore.h b/Base/Vector/EigenCore.h
index db700f3b1c2d3f7825f379a5323ff1388acb636b..12c07911a573254cf3b012cae3b94fd5246bb9a8 100644
--- a/Base/Vector/EigenCore.h
+++ b/Base/Vector/EigenCore.h
@@ -12,6 +12,10 @@
 //
 //  ************************************************************************************************
 
+#ifdef SWIG
+#error no need to expose this header to Swig
+#endif
+
 #ifndef BORNAGAIN_BASE_VECTOR_EIGENCORE_H
 #define BORNAGAIN_BASE_VECTOR_EIGENCORE_H
 
diff --git a/Base/Vector/Transform3D.h b/Base/Vector/Transform3D.h
index d10e9a7bb31397296a55684e9835ec3ce984abdc..5e4cdac7ecd94bcc12066811c3edd62305065095 100644
--- a/Base/Vector/Transform3D.h
+++ b/Base/Vector/Transform3D.h
@@ -12,6 +12,10 @@
 //
 //  ************************************************************************************************
 
+#ifdef SWIG
+#error no need to expose this header to Swig
+#endif
+
 #ifndef BORNAGAIN_BASE_VECTOR_TRANSFORM3D_H
 #define BORNAGAIN_BASE_VECTOR_TRANSFORM3D_H
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2d4500d1d0801d3e6d1e0e6e5aa743365f488983..22a5795e833d0c73367045777d56c5b4969292de 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -135,7 +135,8 @@ endif()
 add_subdirectory(ThirdParty/common)
 add_subdirectory(ThirdParty/Core)
 if(BORNAGAIN_GUI)
-    add_subdirectory(ThirdParty/GUI)
+    add_subdirectory(ThirdParty/GUI/qt-manhattan-style)
+    add_subdirectory(ThirdParty/GUI/qcustomplot)
 endif()
 
 # from here on our own code, occasionally scrutinized by clang-tidy
diff --git a/Core/Export/NodeProgenity.h b/Core/Export/NodeProgeny.h
similarity index 83%
rename from Core/Export/NodeProgenity.h
rename to Core/Export/NodeProgeny.h
index a142431027a68c25e5a84421ea47bb9f2fb2b68f..7e44d3191ee066fa5772418b3afed4dcbc8fbc78 100644
--- a/Core/Export/NodeProgenity.h
+++ b/Core/Export/NodeProgeny.h
@@ -2,8 +2,8 @@
 //
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
-//! @file      Core/Export/NodeProgenity.h
-//! @brief     Defines namespace node_progenity.
+//! @file      Core/Export/NodeProgeny.h
+//! @brief     Defines namespace node_progeny.
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -12,12 +12,12 @@
 //
 //  ************************************************************************************************
 
-#ifndef BORNAGAIN_CORE_EXPORT_NODEPROGENITY_H
-#define BORNAGAIN_CORE_EXPORT_NODEPROGENITY_H
+#ifndef BORNAGAIN_CORE_EXPORT_NODEPROGENY_H
+#define BORNAGAIN_CORE_EXPORT_NODEPROGENY_H
 
 #include "Param/Node/INode.h"
 
-namespace node_progenity {
+namespace node_progeny {
 
 template <typename T> std::vector<const T*> ChildNodesOfType(const INode& node) {
     std::vector<const T*> result;
@@ -46,6 +46,6 @@ template <typename T> std::vector<const T*> AllDescendantsOfType(const INode& no
     return result;
 }
 
-} // namespace node_progenity
+} // namespace node_progeny
 
-#endif // BORNAGAIN_CORE_EXPORT_NODEPROGENITY_H
+#endif // BORNAGAIN_CORE_EXPORT_NODEPROGENY_H
diff --git a/Core/Export/SampleToPython.cpp b/Core/Export/SampleToPython.cpp
index 3a3b544cdf005206be7fb396940b6f1431e41e36..0c1b606067527a769968e7b99dc305307d3e1b6e 100644
--- a/Core/Export/SampleToPython.cpp
+++ b/Core/Export/SampleToPython.cpp
@@ -17,13 +17,11 @@
 #include "Base/Vector/Transform3D.h"
 #include "Core/Export/ComponentKeyHandler.h"
 #include "Core/Export/MaterialKeyHandler.h"
-#include "Core/Export/NodeProgenity.h"
+#include "Core/Export/NodeProgeny.h"
 #include "Core/Export/PyFmt.h"
 #include "Core/Export/PyFmt2.h"
 #include "Sample/Aggregate/InterferenceFunctions.h"
 #include "Sample/Aggregate/ParticleLayout.h"
-#include "Sample/Lattice/Lattice2D.h"
-#include "Sample/Lattice/Lattice3D.h"
 #include "Sample/Multilayer/Layer.h"
 #include "Sample/Multilayer/MultiLayer.h"
 #include "Sample/Particle/Crystal.h"
@@ -108,31 +106,31 @@ void SampleToPython::initLabels(const MultiLayer& multilayer) {
         m_materials->insertMaterial(x);
 
     m_objs->insertModel("sample", &multilayer);
-    for (const auto* x : node_progenity::AllDescendantsOfType<Layer>(multilayer))
+    for (const auto* x : node_progeny::AllDescendantsOfType<Layer>(multilayer))
         m_objs->insertModel("layer", x);
-    for (const auto* x : node_progenity::AllDescendantsOfType<LayerRoughness>(multilayer))
+    for (const auto* x : node_progeny::AllDescendantsOfType<LayerRoughness>(multilayer))
         m_objs->insertModel("roughness", x);
-    for (const auto* x : node_progenity::AllDescendantsOfType<ParticleLayout>(multilayer))
+    for (const auto* x : node_progeny::AllDescendantsOfType<ParticleLayout>(multilayer))
         m_objs->insertModel("layout", x);
-    for (const auto* x : node_progenity::AllDescendantsOfType<IFormFactor>(multilayer))
+    for (const auto* x : node_progeny::AllDescendantsOfType<IFormFactor>(multilayer))
         m_objs->insertModel("ff", x);
-    for (const auto* x : node_progenity::AllDescendantsOfType<IInterferenceFunction>(multilayer))
+    for (const auto* x : node_progeny::AllDescendantsOfType<IInterferenceFunction>(multilayer))
         m_objs->insertModel("iff", x);
-    for (const auto* x : node_progenity::AllDescendantsOfType<Particle>(multilayer))
+    for (const auto* x : node_progeny::AllDescendantsOfType<Particle>(multilayer))
         m_objs->insertModel("particle", x);
-    for (const auto* x : node_progenity::AllDescendantsOfType<ParticleComposition>(multilayer))
+    for (const auto* x : node_progeny::AllDescendantsOfType<ParticleComposition>(multilayer))
         m_objs->insertModel("particle", x);
-    for (const auto* x : node_progenity::AllDescendantsOfType<ParticleCoreShell>(multilayer))
+    for (const auto* x : node_progeny::AllDescendantsOfType<ParticleCoreShell>(multilayer))
         m_objs->insertModel("particle", x);
-    for (const auto* x : node_progenity::AllDescendantsOfType<MesoCrystal>(multilayer))
+    for (const auto* x : node_progeny::AllDescendantsOfType<MesoCrystal>(multilayer))
         m_objs->insertModel("particle", x);
-    for (const auto* x : node_progenity::AllDescendantsOfType<ParticleDistribution>(multilayer))
+    for (const auto* x : node_progeny::AllDescendantsOfType<ParticleDistribution>(multilayer))
         m_objs->insertModel("particle_distrib", x);
-    for (const auto* x : node_progenity::AllDescendantsOfType<Lattice2D>(multilayer))
+    for (const auto* x : node_progeny::AllDescendantsOfType<Lattice2D>(multilayer))
         m_objs->insertModel("lattice", x);
-    for (const auto* x : node_progenity::AllDescendantsOfType<Lattice3D>(multilayer))
+    for (const auto* x : node_progeny::AllDescendantsOfType<Lattice3D>(multilayer))
         m_objs->insertModel("lattice", x);
-    for (const auto* x : node_progenity::AllDescendantsOfType<Crystal>(multilayer))
+    for (const auto* x : node_progeny::AllDescendantsOfType<Crystal>(multilayer))
         m_objs->insertModel("crystal", x);
 }
 
@@ -258,7 +256,7 @@ std::string SampleToPython::defineInterferenceFunctions() const {
                    << pyfmt::printNm(iff->getLength()) << ", " << pyfmt::printDegrees(iff->getXi())
                    << ")\n";
 
-            const auto* pdf = node_progenity::OnlyChildOfType<IFTDecayFunction1D>(*iff);
+            const auto* pdf = node_progeny::OnlyChildOfType<IFTDecayFunction1D>(*iff);
 
             if (pdf->decayLength() != 0.0)
                 result << indent() << key << "_pdf  = ba." << pdf->getName() << "("
@@ -279,7 +277,7 @@ std::string SampleToPython::defineInterferenceFunctions() const {
                 result << indent() << key << ".setDomainSize("
                        << pyfmt::printDouble(iff->domainSize()) << ")\n";
 
-            const auto* pdf = node_progenity::OnlyChildOfType<IFTDistribution1D>(*iff);
+            const auto* pdf = node_progeny::OnlyChildOfType<IFTDistribution1D>(*iff);
 
             if (pdf->omega() != 0.0)
                 result << indent() << key << "_pdf  = ba." << pdf->getName() << "("
@@ -287,12 +285,12 @@ std::string SampleToPython::defineInterferenceFunctions() const {
                        << indent() << key << ".setProbabilityDistribution(" << key << "_pdf)\n";
 
         } else if (const auto* iff = dynamic_cast<const InterferenceFunction2DLattice*>(s)) {
-            const auto* lattice = node_progenity::OnlyChildOfType<Lattice2D>(*iff);
+            const auto* lattice = node_progeny::OnlyChildOfType<Lattice2D>(*iff);
 
             result << indent() << key << " = ba.InterferenceFunction2DLattice("
                    << m_objs->obj2key(lattice) << ")\n";
 
-            const auto* pdf = node_progenity::OnlyChildOfType<IFTDecayFunction2D>(*iff);
+            const auto* pdf = node_progeny::OnlyChildOfType<IFTDecayFunction2D>(*iff);
 
             result << indent() << key << "_pdf  = ba." << pdf->getName() << "("
                    << pyfmt2::argumentList(pdf) << ")\n"
@@ -302,7 +300,7 @@ std::string SampleToPython::defineInterferenceFunctions() const {
                 result << indent() << key << ".setIntegrationOverXi(True)\n";
 
         } else if (const auto* iff = dynamic_cast<const InterferenceFunctionFinite2DLattice*>(s)) {
-            const auto* lattice = node_progenity::OnlyChildOfType<Lattice2D>(*iff);
+            const auto* lattice = node_progeny::OnlyChildOfType<Lattice2D>(*iff);
 
             result << indent() << key << " = ba.InterferenceFunctionFinite2DLattice("
                    << m_objs->obj2key(lattice) << ", " << iff->numberUnitCells1() << ", "
@@ -312,7 +310,7 @@ std::string SampleToPython::defineInterferenceFunctions() const {
                 result << indent() << key << ".setIntegrationOverXi(True)\n";
 
         } else if (const auto* iff = dynamic_cast<const InterferenceFunction2DParaCrystal*>(s)) {
-            const auto* lattice = node_progenity::OnlyChildOfType<Lattice2D>(*iff);
+            const auto* lattice = node_progeny::OnlyChildOfType<Lattice2D>(*iff);
             std::vector<double> domainSize = iff->domainSizes();
 
             result << indent() << key << " = ba.InterferenceFunction2DParaCrystal("
@@ -323,7 +321,7 @@ std::string SampleToPython::defineInterferenceFunctions() const {
             if (iff->integrationOverXi() == true)
                 result << indent() << key << ".setIntegrationOverXi(True)\n";
 
-            const auto pdf_vector = node_progenity::ChildNodesOfType<IFTDistribution2D>(*iff);
+            const auto pdf_vector = node_progeny::ChildNodesOfType<IFTDistribution2D>(*iff);
             if (pdf_vector.size() != 2)
                 continue;
             const IFTDistribution2D* pdf = pdf_vector[0];
@@ -367,13 +365,13 @@ std::string SampleToPython::defineParticleLayouts() const {
     for (const auto* s : v) {
         const std::string& key = m_objs->obj2key(s);
         result << indent() << key << " = ba.ParticleLayout()\n";
-        const auto particles = node_progenity::ChildNodesOfType<IAbstractParticle>(*s);
+        const auto particles = node_progeny::ChildNodesOfType<IAbstractParticle>(*s);
         for (const auto* particle : particles) {
             double abundance = particle->abundance();
             result << indent() << key << ".addParticle(" << m_objs->obj2key(particle) << ", "
                    << pyfmt::printDouble(abundance) << ")\n";
         }
-        if (const auto* iff = node_progenity::OnlyChildOfType<IInterferenceFunction>(*s))
+        if (const auto* iff = node_progeny::OnlyChildOfType<IInterferenceFunction>(*s))
             result << indent() << key << ".setInterferenceFunction(" << m_objs->obj2key(iff)
                    << ")\n";
         result << indent() << key << ".setWeight(" << s->weight() << ")\n";
@@ -392,7 +390,7 @@ std::string SampleToPython::defineParticles() const {
     result << "\n" << indent() << "# Define particles\n";
     for (const auto* s : v) {
         const std::string& key = m_objs->obj2key(s);
-        const auto* ff = node_progenity::OnlyChildOfType<IFormFactor>(*s);
+        const auto* ff = node_progeny::OnlyChildOfType<IFormFactor>(*s);
         ASSERT(ff);
         result << indent() << key << " = ba.Particle(" << m_materials->mat2key(s->material())
                << ", " << m_objs->obj2key(ff) << ")\n";
@@ -452,7 +450,7 @@ std::string SampleToPython::defineParticleDistributions() const {
             result << "\n";
         }
 
-        auto particle = node_progenity::OnlyChildOfType<IParticle>(*s);
+        auto particle = node_progeny::OnlyChildOfType<IParticle>(*s);
         if (!particle)
             continue;
         result << indent() << key << " = ba.ParticleDistribution(" << m_objs->obj2key(particle)
@@ -472,7 +470,7 @@ std::string SampleToPython::defineParticleCompositions() const {
     for (const auto* s : v) {
         const std::string& key = m_objs->obj2key(s);
         result << indent() << key << " = ba.ParticleComposition()\n";
-        const auto particle_list = node_progenity::ChildNodesOfType<IParticle>(*s);
+        const auto particle_list = node_progeny::ChildNodesOfType<IParticle>(*s);
         for (const auto* particle : particle_list) {
             result << indent() << key << ".addParticle(" << m_objs->obj2key(particle) << ")\n";
         }
@@ -491,8 +489,8 @@ std::string SampleToPython::defineMesoCrystals() const {
     result << "\n" << indent() << "# Define mesocrystals\n";
     for (const auto* s : v) {
         const std::string& key = m_objs->obj2key(s);
-        auto crystal = node_progenity::OnlyChildOfType<Crystal>(*s);
-        auto outer_shape = node_progenity::OnlyChildOfType<IFormFactor>(*s);
+        auto crystal = node_progeny::OnlyChildOfType<Crystal>(*s);
+        auto outer_shape = node_progeny::OnlyChildOfType<IFormFactor>(*s);
         if (!crystal || !outer_shape)
             continue;
         result << indent() << key << " = ba.MesoCrystal(";
@@ -553,8 +551,8 @@ std::string SampleToPython::defineCrystals() const {
     result << "\n" << indent() << "# Define crystals\n";
     for (const auto* s : v) {
         const std::string& key = m_objs->obj2key(s);
-        const auto* lattice = node_progenity::OnlyChildOfType<Lattice3D>(*s);
-        const auto* basis = node_progenity::OnlyChildOfType<IParticle>(*s);
+        const auto* lattice = node_progeny::OnlyChildOfType<Lattice3D>(*s);
+        const auto* basis = node_progeny::OnlyChildOfType<IParticle>(*s);
         if (!lattice || !basis)
             continue;
         result << indent() << key << " = ba.Crystal(";
diff --git a/Core/Export/SimulationToPython.cpp b/Core/Export/SimulationToPython.cpp
index 22a99920d77bcf51a32a39107268ee51f5c13a94..d8956fc7b5b64e46fee6585314e13274f7b21f9c 100644
--- a/Core/Export/SimulationToPython.cpp
+++ b/Core/Export/SimulationToPython.cpp
@@ -16,7 +16,7 @@
 #include "Base/Utils/Algorithms.h"
 #include "Core/Computation/ConstantBackground.h"
 #include "Core/Computation/PoissonNoiseBackground.h"
-#include "Core/Export/NodeProgenity.h"
+#include "Core/Export/NodeProgeny.h"
 #include "Core/Export/PyFmt.h"
 #include "Core/Export/PyFmt2.h"
 #include "Core/Export/PyFmtLimits.h"
diff --git a/Core/Legacy/SpecularMagneticStrategy_v1.h b/Core/Legacy/SpecularMagneticStrategy_v1.h
index ea99ca97e451e62fae64b4558bc576ea326ddc70..c88b30067e2443bf7b042c3791017e3a5672f0a2 100644
--- a/Core/Legacy/SpecularMagneticStrategy_v1.h
+++ b/Core/Legacy/SpecularMagneticStrategy_v1.h
@@ -30,14 +30,13 @@ class SpecularMagneticStrategy_v1 : public ISpecularStrategy {
 public:
     // TODO remove once external test code is not needed anmyore
     // for the moment i need them!
-    using coefficient_type         = MatrixRTCoefficients_v1;
+    using coefficient_type = MatrixRTCoefficients_v1;
     using coefficient_pointer_type = std::unique_ptr<const coefficient_type>;
-    using coeffs_t                 = std::vector<coefficient_pointer_type>;
+    using coeffs_t = std::vector<coefficient_pointer_type>;
 
     //! Computes refraction angle reflection/transmission coefficients
     //! for given sliced multilayer and wavevector k
-    ISpecularStrategy::coeffs_t Execute(const std::vector<Slice>& slices,
-                                        const kvector_t& k) const;
+    ISpecularStrategy::coeffs_t Execute(const std::vector<Slice>& slices, const kvector_t& k) const;
 
     ISpecularStrategy::coeffs_t Execute(const std::vector<Slice>& slices,
                                         const std::vector<complex_t>& kz) const;
diff --git a/Core/Legacy/SpecularMagneticStrategy_v2.cpp b/Core/Legacy/SpecularMagneticStrategy_v2.cpp
index 58cc59474368d4f9095bd697be1d4b94c2181182..4fc9b2485fd7d82dac89439544b9416fb6042f75 100644
--- a/Core/Legacy/SpecularMagneticStrategy_v2.cpp
+++ b/Core/Legacy/SpecularMagneticStrategy_v2.cpp
@@ -29,13 +29,13 @@ constexpr double magnetic_prefactor = PhysConsts::m_n * PhysConsts::g_factor_n *
 } // namespace
 
 ISpecularStrategy::coeffs_t SpecularMagneticStrategy_v2::Execute(const std::vector<Slice>& slices,
-                                                              const kvector_t& k) const {
+                                                                 const kvector_t& k) const {
     return Execute(slices, KzComputation::computeReducedKz(slices, k));
 }
 
 ISpecularStrategy::coeffs_t
 SpecularMagneticStrategy_v2::Execute(const std::vector<Slice>& slices,
-                                  const std::vector<complex_t>& kz) const {
+                                     const std::vector<complex_t>& kz) const {
     if (slices.size() != kz.size())
         throw std::runtime_error("Number of slices does not match the size of the kz-vector");
 
@@ -48,7 +48,7 @@ SpecularMagneticStrategy_v2::Execute(const std::vector<Slice>& slices,
 
 std::vector<MatrixRTCoefficients_v2>
 SpecularMagneticStrategy_v2::computeTR(const std::vector<Slice>& slices,
-                                    const std::vector<complex_t>& kzs) {
+                                       const std::vector<complex_t>& kzs) {
     if (kzs[0] == 0.)
         throw std::runtime_error("Edge case k_z = 0 not implemented");
 
diff --git a/Core/Legacy/SpecularMagneticStrategy_v2.h b/Core/Legacy/SpecularMagneticStrategy_v2.h
index 1de56608eabc4df319e9f01513d2c2bd5234e287..11453b465f07e70f64ea69e8d41b88b4c1910768 100644
--- a/Core/Legacy/SpecularMagneticStrategy_v2.h
+++ b/Core/Legacy/SpecularMagneticStrategy_v2.h
@@ -33,14 +33,13 @@ class SpecularMagneticStrategy_v2 : public ISpecularStrategy {
 public:
     // TODO remove once external test code is not needed anmyore
     // for the moment i need them!
-    using coefficient_type         = MatrixRTCoefficients_v2;
+    using coefficient_type = MatrixRTCoefficients_v2;
     using coefficient_pointer_type = std::unique_ptr<const coefficient_type>;
-    using coeffs_t                 = std::vector<coefficient_pointer_type>;
+    using coeffs_t = std::vector<coefficient_pointer_type>;
 
     //! Computes refraction angle reflection/transmission coefficients
     //! for given sliced multilayer and wavevector k
-    ISpecularStrategy::coeffs_t Execute(const std::vector<Slice>& slices,
-                                        const kvector_t& k) const;
+    ISpecularStrategy::coeffs_t Execute(const std::vector<Slice>& slices, const kvector_t& k) const;
 
     //! Computes refraction angle reflection/transmission coefficients
     //! for given sliced multilayer and a set of kz projections corresponding to each slice
diff --git a/Core/Simulation/ISimulation.cpp b/Core/Simulation/ISimulation.cpp
index f3b1c5021b850e088591342012334e522a5ff5ca..79098215e08551fb2847d73e2e476006b766e4f8 100644
--- a/Core/Simulation/ISimulation.cpp
+++ b/Core/Simulation/ISimulation.cpp
@@ -252,6 +252,7 @@ void ISimulation::addParameterDistribution(const std::string& param_name,
 }
 
 void ISimulation::addParameterDistribution(const ParameterDistribution& par_distr) {
+    std::cout << "DEBUG ISimulation::addParameterDistribution" << std::endl;
     validateParametrization(par_distr);
     m_distribution_handler.addParameterDistribution(par_distr);
 }
diff --git a/GUI/CMakeLists.txt b/GUI/CMakeLists.txt
index 33fbcf676ff63feba989b7ae2038801b34d216cd..4ee5af350fa996912a9bfef1b763991f35d06e35 100644
--- a/GUI/CMakeLists.txt
+++ b/GUI/CMakeLists.txt
@@ -10,6 +10,7 @@ add_subdirectory(ba3d)
 add_subdirectory(coregui)
 add_subdirectory(main)
 
+# Transmit variables for use in tests
 set(BornAgainGUI_INCLUDE_DIRS ${BornAgainGUI_INCLUDE_DIRS} PARENT_SCOPE)
 set(BornAgainGUI_LIBRARY ${BornAgainGUI_LIBRARY} PARENT_SCOPE)
 
diff --git a/GUI/coregui/CMakeLists.txt b/GUI/coregui/CMakeLists.txt
index db995c508df03da09a6f4b4eb13afdeed4a44b3c..b3b40ef7ea62902315b4bdafd5146c1b54767ae2 100644
--- a/GUI/coregui/CMakeLists.txt
+++ b/GUI/coregui/CMakeLists.txt
@@ -92,10 +92,15 @@ set(${library_name}_LIBRARY ${library_name} PARENT_SCOPE)
 
 
 # --- dependencies ---------
-target_include_directories(${library_name} PUBLIC ${QtAddOn_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR})
-target_include_directories(${library_name} PUBLIC ${include_dirs})
-target_link_libraries(${library_name} ${QtAddOn_LIBRARIES} ${BornAgainCore_LIBRARY} ${ba3d_LIBRARY})
+target_include_directories(${library_name} PUBLIC
+    ${CMAKE_SOURCE_DIR}/ThirdParty/GUI # for qt-manhattan-style
+    ${qcustomplot_INCLUDE_DIRS}
+    ${CMAKE_SOURCE_DIR})
 target_link_libraries(${library_name}
+    ${ManhattanStyle_LIBRARY}
+    ${qcustomplot_LIBRARY}
+    ${BornAgainCore_LIBRARY}
+    ${ba3d_LIBRARY}
     Qt5::Widgets
     Qt5::Core
     Qt5::Gui
diff --git a/GUI/coregui/Models/GUIDomainSampleVisitor.cpp b/GUI/coregui/Models/GUIDomainSampleVisitor.cpp
index 0bf13734e2ba66990124be696c792a0dc99f3e37..2f8c6095b0c9987eadf5ffcd6bf9aa38e3b612f0 100644
--- a/GUI/coregui/Models/GUIDomainSampleVisitor.cpp
+++ b/GUI/coregui/Models/GUIDomainSampleVisitor.cpp
@@ -30,6 +30,7 @@
 #include "GUI/coregui/Models/TransformationItem.h"
 #include "GUI/coregui/Views/MaterialEditor/MaterialItemUtils.h"
 #include "GUI/coregui/utils/GUIHelpers.h"
+#include "Param/Node/NodeUtils.h"
 #include "Sample/Aggregate/ParticleLayout.h"
 #include "Sample/HardParticle/HardParticles.h"
 #include "Sample/Multilayer/Layer.h"
@@ -77,7 +78,10 @@ SessionItem* GUIDomainSampleVisitor::populateSampleModel(SampleModel* sampleMode
     if (m_topSampleName.isEmpty())
         m_topSampleName = sample.getName().c_str();
 
-    VisitNodesPreorder(sample, *this);
+    for (const auto [child, depth, parent]: NodeUtils::progenyPlus(&sample)) {
+        setDepth(depth+1);
+        child->accept(this);
+    }
     SessionItem* result = m_levelToParentItem[1];
 
     result->setItemName(m_topSampleName);
diff --git a/GUI/coregui/Models/SessionXML.cpp b/GUI/coregui/Models/SessionXML.cpp
index 57efcce93e7847195fd7575ff989b961a7869c5f..5076fd3a3de3903261a254d91da7f34ebb16291a 100644
--- a/GUI/coregui/Models/SessionXML.cpp
+++ b/GUI/coregui/Models/SessionXML.cpp
@@ -129,8 +129,8 @@ void SessionXML::readItems(QXmlStreamReader* reader, SessionItem* parent, QStrin
                 auto newItem = createItem(parent, model_type, tag);
                 if (!newItem) {
                     QString message = QString("Error while parsing XML. Can't create item of "
-                                              "modelType '%1' for tag '%2'")
-                                          .arg(model_type, tag);
+                                              "modelType '%1' for tag '%2', parent '%3'")
+                        .arg(model_type, tag, parent->P_NAME);
                     report_error(messageService, parent, message);
                     // risky attempt to recover the rest of the project
                     reader->skipCurrentElement();
diff --git a/GUI/coregui/Models/TransformFromDomain.cpp b/GUI/coregui/Models/TransformFromDomain.cpp
index 9bb9592b16b8e46c8a3ba16cc85733c779366afe..e31fe5ab63e844014f537184f63535b753e9ecaa 100644
--- a/GUI/coregui/Models/TransformFromDomain.cpp
+++ b/GUI/coregui/Models/TransformFromDomain.cpp
@@ -16,7 +16,7 @@
 #include "Base/Const/Units.h"
 #include "Core/Computation/ConstantBackground.h"
 #include "Core/Computation/PoissonNoiseBackground.h"
-#include "Core/Export/NodeProgenity.h"
+#include "Core/Export/NodeProgeny.h"
 #include "Core/Scan/AngularSpecScan.h"
 #include "Core/Simulation/GISASSimulation.h"
 #include "Core/Simulation/OffSpecSimulation.h"
@@ -63,7 +63,7 @@
 #include "Sample/Slice/LayerInterface.h"
 #include "Sample/Slice/LayerRoughness.h"
 
-using namespace node_progenity;
+using namespace node_progeny;
 using SessionItemUtils::SetVectorItem;
 
 namespace {
diff --git a/GUI/coregui/Views/CommonWidgets/DocksController.cpp b/GUI/coregui/Views/CommonWidgets/DocksController.cpp
index 09efa6c58bbf9b355823bcc6ee57fddff6d292ad..d12975362d8c9d31439eb1589a6da34d5b04d479 100644
--- a/GUI/coregui/Views/CommonWidgets/DocksController.cpp
+++ b/GUI/coregui/Views/CommonWidgets/DocksController.cpp
@@ -19,7 +19,7 @@
 #include <QAction>
 #include <QDockWidget>
 #include <QTimer>
-#include <fancymainwindow.h>
+#include <qt-manhattan-style/fancymainwindow.h>
 
 DocksController::DocksController(Manhattan::FancyMainWindow* mainWindow)
     : QObject(mainWindow), m_mainWindow(mainWindow) {
diff --git a/GUI/coregui/Views/ImportDataView.cpp b/GUI/coregui/Views/ImportDataView.cpp
index f1228fe88165e68e156cb8c934d47cf6afa47594..5f23281b33232279f6520395085aa52d49c521f3 100644
--- a/GUI/coregui/Views/ImportDataView.cpp
+++ b/GUI/coregui/Views/ImportDataView.cpp
@@ -19,7 +19,7 @@
 #include "GUI/coregui/mainwindow/mainwindow.h"
 #include "GUI/coregui/mainwindow/mainwindow_constants.h"
 #include <QVBoxLayout>
-#include <minisplitter.h>
+#include <qt-manhattan-style/minisplitter.h>
 
 namespace {
 const bool reuse_widget = true;
diff --git a/GUI/coregui/Views/ImportDataWidgets/RealDataSelectorWidget.cpp b/GUI/coregui/Views/ImportDataWidgets/RealDataSelectorWidget.cpp
index fdeb08bcea135d7ffbbf40c0907e0c112346edc2..af409487b3ceea2414f4aa64b29fea638f219eb0 100644
--- a/GUI/coregui/Views/ImportDataWidgets/RealDataSelectorWidget.cpp
+++ b/GUI/coregui/Views/ImportDataWidgets/RealDataSelectorWidget.cpp
@@ -21,7 +21,7 @@
 #include "GUI/coregui/Views/ImportDataWidgets/RealDataSelectorToolBar.h"
 #include <QItemSelectionModel>
 #include <QVBoxLayout>
-#include <minisplitter.h>
+#include <qt-manhattan-style/minisplitter.h>
 
 RealDataSelectorWidget::RealDataSelectorWidget(QWidget* parent)
     : QWidget(parent)
diff --git a/GUI/coregui/Views/JobView.h b/GUI/coregui/Views/JobView.h
index 8c06842d53eb5ab1cced86a0bb1c7bd47b681a6b..2d3b2a0d8a97ad7b27bdf99d00d415b867252464 100644
--- a/GUI/coregui/Views/JobView.h
+++ b/GUI/coregui/Views/JobView.h
@@ -15,7 +15,7 @@
 #ifndef BORNAGAIN_GUI_COREGUI_VIEWS_JOBVIEW_H
 #define BORNAGAIN_GUI_COREGUI_VIEWS_JOBVIEW_H
 
-#include <fancymainwindow.h>
+#include <qt-manhattan-style/fancymainwindow.h>
 
 class MainWindow;
 class JobViewDocks;
diff --git a/GUI/coregui/Views/JobWidgets/JobListViewDelegate.cpp b/GUI/coregui/Views/JobWidgets/JobListViewDelegate.cpp
index 5f68b46bc27c1b67e4b7adbd579563dd9989ca69..0caf37ee485d64b04a4566d7aa3d1c8f78920c6e 100644
--- a/GUI/coregui/Views/JobWidgets/JobListViewDelegate.cpp
+++ b/GUI/coregui/Views/JobWidgets/JobListViewDelegate.cpp
@@ -22,7 +22,7 @@
 #include <QPainter>
 #include <QStyleOptionProgressBarV2>
 #include <QWidget>
-#include <progressbar.h>
+#include <qt-manhattan-style/progressbar.h>
 
 JobListViewDelegate::JobListViewDelegate(QWidget* parent) : QItemDelegate(parent) {
     m_buttonState = QStyle::State_Enabled;
diff --git a/GUI/coregui/Views/JobWidgets/JobProgressAssistant.cpp b/GUI/coregui/Views/JobWidgets/JobProgressAssistant.cpp
index 092222d15f657110de0a99995690409cd0683d75..618ca29e42183af7bc21fd939871567ed61b7498 100644
--- a/GUI/coregui/Views/JobWidgets/JobProgressAssistant.cpp
+++ b/GUI/coregui/Views/JobWidgets/JobProgressAssistant.cpp
@@ -16,7 +16,7 @@
 #include "GUI/coregui/Models/JobModel.h"
 #include "GUI/coregui/Models/JobQueueData.h"
 #include "GUI/coregui/mainwindow/mainwindow.h"
-#include <progressbar.h>
+#include <qt-manhattan-style/progressbar.h>
 
 JobProgressAssistant::JobProgressAssistant(MainWindow* mainWindow)
     : QObject(mainWindow), m_mainWindow(mainWindow) {
diff --git a/GUI/coregui/Views/JobWidgets/JobSelectorWidget.cpp b/GUI/coregui/Views/JobWidgets/JobSelectorWidget.cpp
index 29c7178b199e3acd53eafaef0f2f59ae1e806e6c..1bfe5a46bacedeff4e631f4b9ce05ff88dc67fc0 100644
--- a/GUI/coregui/Views/JobWidgets/JobSelectorWidget.cpp
+++ b/GUI/coregui/Views/JobWidgets/JobSelectorWidget.cpp
@@ -22,7 +22,7 @@
 #include "GUI/coregui/mainwindow/mainwindow_constants.h"
 #include "GUI/coregui/utils/StyleUtils.h"
 #include <QHBoxLayout>
-#include <minisplitter.h>
+#include <qt-manhattan-style/minisplitter.h>
 
 JobSelectorWidget::JobSelectorWidget(JobModel* jobModel, QWidget* parent)
     : QWidget(parent)
diff --git a/GUI/coregui/Views/JobWidgets/ProjectionsEditor.cpp b/GUI/coregui/Views/JobWidgets/ProjectionsEditor.cpp
index afe18bda5bf57af6e92754ee11f03ca6c8ceabb0..ece2e36a09fd2741b157354eb4d6aeed17ca92ac 100644
--- a/GUI/coregui/Views/JobWidgets/ProjectionsEditor.cpp
+++ b/GUI/coregui/Views/JobWidgets/ProjectionsEditor.cpp
@@ -22,7 +22,7 @@
 #include "GUI/coregui/Views/JobWidgets/ProjectionsWidget.h"
 #include <QItemSelectionModel>
 #include <QSplitter>
-#include <minisplitter.h>
+#include <qt-manhattan-style/minisplitter.h>
 
 ProjectionsEditor::ProjectionsEditor(QWidget* parent)
     : QMainWindow(parent)
diff --git a/GUI/coregui/Views/MaskWidgets/MaskEditor.cpp b/GUI/coregui/Views/MaskWidgets/MaskEditor.cpp
index 8868933b013e99c48fa4d45c0e2d138e70aa2d99..aa1dfc3ce113cef358c1a285a421e91ae574d18c 100644
--- a/GUI/coregui/Views/MaskWidgets/MaskEditor.cpp
+++ b/GUI/coregui/Views/MaskWidgets/MaskEditor.cpp
@@ -21,7 +21,7 @@
 #include "GUI/coregui/Views/MaskWidgets/MaskGraphicsScene.h"
 #include <QBoxLayout>
 #include <QContextMenuEvent>
-#include <minisplitter.h>
+#include <qt-manhattan-style/minisplitter.h>
 
 MaskEditor::MaskEditor(QWidget* parent)
     : QMainWindow(parent)
diff --git a/GUI/coregui/Views/PropertyEditor/TestComponentView.cpp b/GUI/coregui/Views/PropertyEditor/TestComponentView.cpp
index 56e11292b57f7dd5d23f36d069f1b939f301d64f..027824d4e933346827532fcfe21c5acb5958c987 100644
--- a/GUI/coregui/Views/PropertyEditor/TestComponentView.cpp
+++ b/GUI/coregui/Views/PropertyEditor/TestComponentView.cpp
@@ -32,7 +32,7 @@
 #include <QPushButton>
 #include <QTreeView>
 #include <limits>
-#include <minisplitter.h>
+#include <qt-manhattan-style/minisplitter.h>
 
 TestComponentView::TestComponentView(MainWindow* mainWindow)
     : m_mainWindow(mainWindow)
diff --git a/GUI/coregui/Views/SampleDesigner/SampleWidgetBox.cpp b/GUI/coregui/Views/SampleDesigner/SampleWidgetBox.cpp
index cf1b72afe2711753b5da0bc850f5fffb9d20d9aa..4e94e77e56d9fe521cb4167132b446b995955d3d 100644
--- a/GUI/coregui/Views/SampleDesigner/SampleWidgetBox.cpp
+++ b/GUI/coregui/Views/SampleDesigner/SampleWidgetBox.cpp
@@ -15,7 +15,7 @@
 #include "GUI/coregui/Views/SampleDesigner/SampleWidgetBox.h"
 #include "GUI/coregui/Views/widgetbox/widgetbox.h"
 #include <QVBoxLayout>
-#include <styledbar.h>
+#include <qt-manhattan-style/styledbar.h>
 
 #if QT_VERSION < 0x050000
 #define QStringLiteral QString
diff --git a/GUI/coregui/Views/SampleView.h b/GUI/coregui/Views/SampleView.h
index 0c69b7ad239a6625e05e0b1d4b86644bf09e1b9d..d8e19bcd5b0fb74a7235bbbe180f13c2dc0ca0a3 100644
--- a/GUI/coregui/Views/SampleView.h
+++ b/GUI/coregui/Views/SampleView.h
@@ -15,7 +15,7 @@
 #ifndef BORNAGAIN_GUI_COREGUI_VIEWS_SAMPLEVIEW_H
 #define BORNAGAIN_GUI_COREGUI_VIEWS_SAMPLEVIEW_H
 
-#include <fancymainwindow.h>
+#include <qt-manhattan-style/fancymainwindow.h>
 
 class MainWindow;
 class SampleViewDocks;
diff --git a/GUI/coregui/mainwindow/mainwindow.cpp b/GUI/coregui/mainwindow/mainwindow.cpp
index bf6165e56bf264ed1fa897a64a4527778c45b573..24b460fb69af26b0ed8dd033fe6cbbee469498d0 100644
--- a/GUI/coregui/mainwindow/mainwindow.cpp
+++ b/GUI/coregui/mainwindow/mainwindow.cpp
@@ -34,9 +34,9 @@
 #include <QCloseEvent>
 #include <QMessageBox>
 #include <QSettings>
-#include <fancytabwidget.h>
-#include <progressbar.h>
-#include <stylehelper.h>
+#include <qt-manhattan-style/fancytabwidget.h>
+#include <qt-manhattan-style/progressbar.h>
+#include <qt-manhattan-style/stylehelper.h>
 
 MainWindow::MainWindow()
     : Manhattan::FancyMainWindow(nullptr)
diff --git a/GUI/coregui/mainwindow/mainwindow.h b/GUI/coregui/mainwindow/mainwindow.h
index 7d351dbd5b19ac358ab1b985dd656e0d3b748663..fad9c7e04205b2aab90737d4741d3ef279259175 100644
--- a/GUI/coregui/mainwindow/mainwindow.h
+++ b/GUI/coregui/mainwindow/mainwindow.h
@@ -15,7 +15,7 @@
 #ifndef BORNAGAIN_GUI_COREGUI_MAINWINDOW_MAINWINDOW_H
 #define BORNAGAIN_GUI_COREGUI_MAINWINDOW_MAINWINDOW_H
 
-#include <fancymainwindow.h>
+#include <qt-manhattan-style/fancymainwindow.h>
 
 namespace Manhattan {
 class FancyTabWidget;
diff --git a/Param/Distrib/ParameterDistribution.cpp b/Param/Distrib/ParameterDistribution.cpp
index 3cef9d191f8f9014e83e401635b10cf6e82a774f..f6a62e8d9f479f3830f97ef93349068f2578b69e 100644
--- a/Param/Distrib/ParameterDistribution.cpp
+++ b/Param/Distrib/ParameterDistribution.cpp
@@ -45,18 +45,15 @@ ParameterDistribution::ParameterDistribution(const std::string& par_name,
     , m_xmin(xmin)
     , m_xmax(xmax) {
     m_distribution.reset(distribution.clone());
-    if (m_sigma_factor < 0.0) {
+    if (m_sigma_factor < 0.0)
         throw std::runtime_error("ParameterDistribution::ParameterDistribution() -> Error."
                                  "sigma factor cannot be negative");
-    }
-    if (nbr_samples == 0) {
+    if (nbr_samples == 0)
         throw std::runtime_error("ParameterDistribution::ParameterDistribution() -> Error."
                                  "Number of samples can't be zero.");
-    }
-    if (xmin >= xmax) {
+    if (xmin >= xmax)
         throw std::runtime_error("ParameterDistribution::ParameterDistribution() -> Error."
                                  "xmin>=xmax");
-    }
 }
 
 ParameterDistribution::ParameterDistribution(const ParameterDistribution& other)
@@ -101,8 +98,7 @@ size_t ParameterDistribution::getNbrSamples() const {
 std::vector<ParameterSample> ParameterDistribution::generateSamples() const {
     if (m_xmin < m_xmax)
         return m_distribution->equidistantSamplesInRange(m_nbr_samples, m_xmin, m_xmax);
-    else
-        return m_distribution->equidistantSamples(m_nbr_samples, m_sigma_factor, m_limits);
+    return m_distribution->equidistantSamples(m_nbr_samples, m_sigma_factor, m_limits);
 }
 
 const IDistribution1D* ParameterDistribution::getDistribution() const {
diff --git a/Param/Node/INode.cpp b/Param/Node/INode.cpp
index a701361997a450ae144cd37f2cccea0cd0caeac7..a63c0214d8dd32fd854d87f184b2b8581118b7c8 100644
--- a/Param/Node/INode.cpp
+++ b/Param/Node/INode.cpp
@@ -12,11 +12,10 @@
 //
 //  ************************************************************************************************
 
+#include "Param/Node/INode.h"
 #include "Base/Utils/Algorithms.h"
 #include "Param/Base/ParameterPool.h"
 #include "Param/Base/RealParameter.h"
-#include "Param/Node/IterationStrategy.h"
-#include "Param/Node/NodeIterator.h"
 #include "Param/Node/NodeUtils.h"
 #include <algorithm>
 #include <exception>
@@ -49,7 +48,7 @@ INode::INode(const NodeMeta& meta, const std::vector<double>& PValues)
 }
 
 std::string INode::treeToString() const {
-    return NodeUtils::nodeToString(*this);
+    return NodeUtils::nodeToString(this);
 }
 
 void INode::registerChild(INode* node) {
@@ -61,6 +60,16 @@ std::vector<const INode*> INode::getChildren() const {
     return {};
 }
 
+std::vector<const INode*> INode::progeny() const {
+    std::vector<const INode*> result;
+    result.push_back(this);
+    for (const auto* child : getChildren()) {
+        for (const auto* p : child->progeny())
+            result.push_back(p);
+    }
+    return result;
+}
+
 void INode::setParent(const INode* newParent) {
     m_parent = newParent;
 }
@@ -106,13 +115,9 @@ std::string INode::displayName() const {
 ParameterPool* INode::createParameterTree() const {
     std::unique_ptr<ParameterPool> result(new ParameterPool);
 
-    NodeIterator<PreorderStrategy> it(this);
-    it.first();
-    while (!it.isDone()) {
-        const INode* child = it.getCurrent();
-        const std::string path = NodeUtils::nodePath(*child, this->parent()) + "/";
+    for (const INode* child : progeny()) {
+        const std::string path = NodeUtils::nodePath(child, this->parent()) + "/";
         child->parameterPool()->copyToExternalPool(path, result.get());
-        it.next();
     }
 
     return result.release();
diff --git a/Param/Node/INode.h b/Param/Node/INode.h
index e0df6f1d2f3edca9ffd21b9ee12398bbcf19256e..9d99e9c0fa0ac74ba4dcbb34cf11c4553b7e5c9e 100644
--- a/Param/Node/INode.h
+++ b/Param/Node/INode.h
@@ -60,8 +60,10 @@ public:
 
     void registerChild(INode* node);
 
-    //! Returns a vector of children (const).
+    //! Returns a vector of children
     virtual std::vector<const INode*> getChildren() const;
+    //! Returns a vector of all descendents
+    std::vector<const INode*> progeny() const;
 
     virtual void setParent(const INode* newParent);
     const INode* parent() const;
diff --git a/Param/Node/INodeVisitor.cpp b/Param/Node/INodeVisitor.cpp
deleted file mode 100644
index 6e70df009b59d05fb4e1fac38fe723c469efcc23..0000000000000000000000000000000000000000
--- a/Param/Node/INodeVisitor.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-//  ************************************************************************************************
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Param/Node/INodeVisitor.cpp
-//! @brief     Implements interface INodeVisitor.
-//!
-//! @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 "Param/Node/IterationStrategy.h"
-#include "Param/Node/NodeIterator.h"
-
-void VisitNodesPreorder(const INode& node, INodeVisitor& visitor) {
-    NodeIterator<PreorderStrategy> it(&node);
-    it.first();
-    while (!it.isDone()) {
-        visitor.setDepth(it.depth());
-        const INode* child = it.getCurrent();
-        child->accept(&visitor);
-        it.next();
-    }
-}
diff --git a/Param/Node/INodeVisitor.h b/Param/Node/INodeVisitor.h
index 7520a298676527ddce97186b69292c94235277f9..2acf99b0819f038920b4944c476ca08eb0d8d68d 100644
--- a/Param/Node/INodeVisitor.h
+++ b/Param/Node/INodeVisitor.h
@@ -279,6 +279,4 @@ private:
     int m_depth;
 };
 
-void VisitNodesPreorder(const INode& node, INodeVisitor& visitor);
-
 #endif // BORNAGAIN_PARAM_NODE_INODEVISITOR_H
diff --git a/Param/Node/IterationStrategy.cpp b/Param/Node/IterationStrategy.cpp
deleted file mode 100644
index 8d3d34f184536756b4f870b8799fa6b11995ec8d..0000000000000000000000000000000000000000
--- a/Param/Node/IterationStrategy.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-//  ************************************************************************************************
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Param/Node/IterationStrategy.cpp
-//! @brief     Implements class IterationStrategy and children.
-//!
-//! @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 "Param/Node/IterationStrategy.h"
-#include "Base/Utils/Assert.h"
-#include "Param/Node/NodeIterator.h"
-
-PreorderStrategy::PreorderStrategy() = default;
-
-PreorderStrategy* PreorderStrategy::clone() const {
-    return new PreorderStrategy();
-}
-
-IteratorMemento PreorderStrategy::first(const INode* p_root) {
-    IteratorMemento iterator_stack;
-    iterator_stack.push_state(IteratorState(p_root));
-    return iterator_stack;
-}
-
-void PreorderStrategy::next(IteratorMemento& iterator_stack) const {
-    const INode* node = iterator_stack.getCurrent();
-    ASSERT(node);
-    std::vector<const INode*> children = node->getChildren();
-    if (children.size() > 0) {
-        iterator_stack.push_state(IteratorState(children));
-        return;
-    }
-    iterator_stack.next();
-    while (!iterator_stack.empty() && iterator_stack.get_state().isEnd()) {
-        iterator_stack.pop_state();
-        if (!iterator_stack.empty())
-            iterator_stack.next();
-    }
-}
-
-bool PreorderStrategy::isDone(IteratorMemento& iterator_stack) const {
-    return iterator_stack.empty();
-}
diff --git a/Param/Node/IterationStrategy.h b/Param/Node/IterationStrategy.h
deleted file mode 100644
index 74668675b2ddea78f192fd31abce76aa662c42a9..0000000000000000000000000000000000000000
--- a/Param/Node/IterationStrategy.h
+++ /dev/null
@@ -1,46 +0,0 @@
-//  ************************************************************************************************
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Param/Node/IterationStrategy.h
-//! @brief     Defines class IterationStrategy and children.
-//!
-//! @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_PARAM_NODE_ITERATIONSTRATEGY_H
-#define BORNAGAIN_PARAM_NODE_ITERATIONSTRATEGY_H
-
-class INode;
-class IteratorMemento;
-
-//! Abstract base class for tree traversal strategies, for use in INodeVisitor.
-//!
-//! For definition of different strategies see https://en.wikipedia.org/wiki/Tree_traversal.
-
-class IterationStrategy {
-public:
-    virtual IterationStrategy* clone() const = 0;
-
-    virtual IteratorMemento first(const INode* p_root) = 0;
-    virtual void next(IteratorMemento& iterator_stack) const = 0;
-    virtual bool isDone(IteratorMemento& iterator_stack) const = 0;
-};
-
-//! Traverse tree; visit parents before their children.
-class PreorderStrategy : public IterationStrategy {
-public:
-    PreorderStrategy();
-
-    virtual PreorderStrategy* clone() const;
-
-    virtual IteratorMemento first(const INode* p_root);
-    virtual void next(IteratorMemento& iterator_stack) const;
-    virtual bool isDone(IteratorMemento& iterator_stack) const;
-};
-
-#endif // BORNAGAIN_PARAM_NODE_ITERATIONSTRATEGY_H
diff --git a/Param/Node/NodeIterator.cpp b/Param/Node/NodeIterator.cpp
deleted file mode 100644
index 3ec63f0b68fb18340c8fa917ad2a0e9f25fecb14..0000000000000000000000000000000000000000
--- a/Param/Node/NodeIterator.cpp
+++ /dev/null
@@ -1,22 +0,0 @@
-//  ************************************************************************************************
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Param/Node/NodeIterator.cpp
-//! @brief     Implements class IteratorState.
-//!
-//! @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 "Param/Node/NodeIterator.h"
-
-IteratorState::IteratorState(const INode* single_element) : m_position(0) {
-    m_samples.push_back(single_element);
-}
-
-IteratorState::IteratorState(std::vector<const INode*> samples)
-    : m_samples(samples), m_position(0) {}
diff --git a/Param/Node/NodeIterator.h b/Param/Node/NodeIterator.h
deleted file mode 100644
index afe7857bab7a789f298543a6f873eb6be78c8f68..0000000000000000000000000000000000000000
--- a/Param/Node/NodeIterator.h
+++ /dev/null
@@ -1,125 +0,0 @@
-//  ************************************************************************************************
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Param/Node/NodeIterator.h
-//! @brief     Defines classes IteratorState, IteratorMemento and NodeIterator.
-//!
-//! @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_PARAM_NODE_NODEITERATOR_H
-#define BORNAGAIN_PARAM_NODE_NODEITERATOR_H
-
-#include "Param/Node/INode.h"
-#include <ostream>
-#include <stack>
-#include <vector>
-
-//! Holds state of iterator at single level for SampleTreeIterator.
-//! @ingroup samples_internal
-
-class IteratorState {
-public:
-    IteratorState(const INode* single_element);
-    IteratorState(std::vector<const INode*> samples);
-
-    virtual ~IteratorState() {}
-
-    const INode* getCurrent() const { return m_samples[m_position]; }
-    bool isEnd() const { return m_position >= m_samples.size(); }
-    void next() { ++m_position; }
-
-    friend std::ostream& operator<<(std::ostream& output_stream,
-                                    IteratorState const& iterator_state) {
-        return output_stream << "memento state " << iterator_state.m_position << " "
-                             << iterator_state.m_samples.size();
-    }
-
-private:
-    std::vector<const INode*> m_samples;
-    size_t m_position;
-
-    IteratorState();
-};
-
-//! Holds all iterator states encountered for SampleTreeIterator.
-//! @ingroup samples_internal
-
-class IteratorMemento {
-public:
-    IteratorMemento() {}
-    virtual ~IteratorMemento() {}
-
-    void push_state(const IteratorState& state) { m_state_stack.push(state); }
-    void pop_state() { m_state_stack.pop(); }
-    IteratorState& get_state() { return m_state_stack.top(); }
-    bool empty() const { return m_state_stack.empty(); }
-    void reset() {
-        while (!m_state_stack.empty())
-            m_state_stack.pop();
-    }
-    const INode* getCurrent() { return m_state_stack.top().getCurrent(); }
-    void next() { m_state_stack.top().next(); }
-    size_t size() const { return m_state_stack.size(); }
-
-protected:
-    std::stack<IteratorState> m_state_stack;
-};
-
-//! Iterator through INode tree of objects.
-//!
-//! Usage example:
-//!    SampleTreeIterator<Strategy> it(&sample);
-//!    it.first();
-//!    while( !it.is_done() ) {
-//!        INode *p_sample = it.get_current();
-//!        it.next();
-//!     }
-//! @ingroup samples_internal
-
-template <class Strategy> class NodeIterator {
-public:
-    NodeIterator(const INode* root);
-    virtual ~NodeIterator() {}
-
-    void first();
-    void next();
-    const INode* getCurrent();
-    bool isDone() const;
-    int depth() const;
-
-protected:
-    Strategy m_strategy;
-    IteratorMemento m_memento_itor;
-    const INode* m_root;
-};
-
-template <class Strategy>
-inline NodeIterator<Strategy>::NodeIterator(const INode* root) : m_root(root) {}
-
-template <class Strategy> inline void NodeIterator<Strategy>::first() {
-    m_memento_itor = m_strategy.first(m_root);
-}
-
-template <class Strategy> inline void NodeIterator<Strategy>::next() {
-    m_strategy.next(m_memento_itor);
-}
-
-template <class Strategy> inline const INode* NodeIterator<Strategy>::getCurrent() {
-    return m_memento_itor.getCurrent();
-}
-
-template <class Strategy> inline bool NodeIterator<Strategy>::isDone() const {
-    return m_memento_itor.size() == 0;
-}
-
-template <class Strategy> inline int NodeIterator<Strategy>::depth() const {
-    return static_cast<int>(m_memento_itor.size());
-}
-
-#endif // BORNAGAIN_PARAM_NODE_NODEITERATOR_H
diff --git a/Param/Node/NodeUtils.cpp b/Param/Node/NodeUtils.cpp
index a9ec109cc309c2bdce29002f9e48c37d15c81ea8..40e8adc60590e2385670e8512ac2e42c930d9f09 100644
--- a/Param/Node/NodeUtils.cpp
+++ b/Param/Node/NodeUtils.cpp
@@ -13,10 +13,10 @@
 //  ************************************************************************************************
 
 #include "Param/Node/NodeUtils.h"
+#include "Base/Utils/Assert.h"
 #include "Param/Base/ParameterPool.h"
 #include "Param/Base/RealParameter.h"
-#include "Param/Node/IterationStrategy.h"
-#include "Param/Node/NodeIterator.h"
+#include "Param/Node/INode.h"
 #include <algorithm>
 #include <functional>
 #include <iterator>
@@ -59,34 +59,35 @@ std::string nodeString(const INode& node, int depth) {
 }
 } // namespace
 
-std::string NodeUtils::nodeToString(const INode& node) {
-    std::ostringstream result;
-
-    NodeIterator<PreorderStrategy> it(&node);
-    it.first();
-    while (!it.isDone()) {
-        const INode* child = it.getCurrent();
-        result << nodeString(*child, it.depth() - 1);
-        it.next();
+std::vector<std::tuple<const INode*, int, const INode*>> NodeUtils::progenyPlus(const INode* node,
+                                                                                int level) {
+    std::vector<std::tuple<const INode*, int, const INode*>> result;
+    result.push_back({node, level, nullptr});
+    for (const auto* child : node->getChildren()) {
+        for (const auto [subchild, sublevel, subparent] : progenyPlus(child, level + 1))
+            result.push_back({subchild, sublevel, child});
     }
+    return result;
+}
 
+std::string NodeUtils::nodeToString(const INode* node) {
+    std::ostringstream result;
+    for (const auto [child, depth, parent] : progenyPlus(node))
+        result << nodeString(*child, depth);
     return result.str();
 }
 
-std::string NodeUtils::nodePath(const INode& node, const INode* root) {
+std::string NodeUtils::nodePath(const INode* node, const INode* root) {
     std::vector<std::string> pathElements;
-    const INode* current = &node;
+    const INode* current = node;
     while (current && current != root) {
         pathElements.push_back(current->displayName());
         pathElements.push_back("/");
         current = current->parent();
     }
-
-    if (root != nullptr && current != root) {
+    if (root != nullptr && current != root)
         throw std::runtime_error("NodeUtils::nodePath() -> Error. Node doesn't "
                                  "belong to root's branch");
-    }
-
     std::reverse(pathElements.begin(), pathElements.end());
     std::ostringstream result;
     std::copy(pathElements.begin(), pathElements.end(), std::ostream_iterator<std::string>(result));
diff --git a/Param/Node/NodeUtils.h b/Param/Node/NodeUtils.h
index bc691b01bad580c92fe0eae14388f0aac56d7773..578d8222f68b78ec88b32d234c6b6784229cba1d 100644
--- a/Param/Node/NodeUtils.h
+++ b/Param/Node/NodeUtils.h
@@ -12,20 +12,29 @@
 //
 //  ************************************************************************************************
 
+#ifdef SWIG
+#error no need to expose this header to Swig
+#endif
+
 #ifndef BORNAGAIN_PARAM_NODE_NODEUTILS_H
 #define BORNAGAIN_PARAM_NODE_NODEUTILS_H
 
 #include <string>
+#include <vector>
 
 class INode;
 
 namespace NodeUtils {
 
+//! Returns a vector of triples (descendent, depth, parent)
+std::vector<std::tuple<const INode*, int, const INode*>> progenyPlus(const INode* node,
+                                                                     int level = 0);
+
 //! Returns multiline string representing tree structure starting from given node.
-std::string nodeToString(const INode& node);
+std::string nodeToString(const INode* node);
 
 //! Returns path composed of node's displayName, with respect to root node
-std::string nodePath(const INode& node, const INode* root = nullptr);
+std::string nodePath(const INode* node, const INode* root = nullptr);
 
 } // namespace NodeUtils
 
diff --git a/Sample/Aggregate/InterferenceFunction3DLattice.h b/Sample/Aggregate/InterferenceFunction3DLattice.h
index 7765aff1acc2f265c694f1b5e3011570f1f9ee9a..82eef2da512a713016914ad5e35bf14f0f604696 100644
--- a/Sample/Aggregate/InterferenceFunction3DLattice.h
+++ b/Sample/Aggregate/InterferenceFunction3DLattice.h
@@ -46,7 +46,7 @@ private:
     double iff_without_dw(const kvector_t q) const override;
     void initRecRadius();
 
-    Lattice3D m_lattice; // TODO ASAP unique_ptr as in otehr InterferenceFunction%s
+    Lattice3D m_lattice; // TODO unique_ptr as in other InterferenceFunction%s
     std::unique_ptr<IPeakShape> m_peak_shape;
     double m_rec_radius; //!< radius in reciprocal space defining the nearest q vectors to use
 };
diff --git a/Sample/Fresnel/MatrixFresnelMap.cpp b/Sample/Fresnel/MatrixFresnelMap.cpp
index f1ba1dc45033bff2f220a1152466606e35fb6f3d..f930c42ad60cb4429813fb764224e7b4c9efbf44 100644
--- a/Sample/Fresnel/MatrixFresnelMap.cpp
+++ b/Sample/Fresnel/MatrixFresnelMap.cpp
@@ -13,8 +13,8 @@
 //  ************************************************************************************************
 
 #include "Sample/Fresnel/MatrixFresnelMap.h"
-#include "Sample/RT/ILayerRTCoefficients.h"
 #include "Base/Pixel/SimulationElement.h"
+#include "Sample/RT/ILayerRTCoefficients.h"
 #include "Sample/Slice/Slice.h"
 #include <functional>
 
diff --git a/Sample/Processed/ProcessedSample.cpp b/Sample/Processed/ProcessedSample.cpp
index 6752a395fce755c3ccf3b04aa552a02a12936459..7e18d6862367be17d86e785a087d95f1a9408903 100644
--- a/Sample/Processed/ProcessedSample.cpp
+++ b/Sample/Processed/ProcessedSample.cpp
@@ -177,10 +177,9 @@ bool ProcessedSample::containsMagneticMaterial() const {
 }
 
 bool ProcessedSample::hasRoughness() const {
-    for (const auto& slice : m_slices) {
+    for (const auto& slice : m_slices)
         if (slice.topRoughness())
             return true;
-    }
     return false;
 }
 
@@ -287,9 +286,8 @@ void ProcessedSample::addNSlices(size_t n, double thickness, const Material& mat
                                  "bigger than zero.");
     const double slice_thickness = thickness / n;
     addSlice(slice_thickness, material, roughness);
-    for (size_t i = 1; i < n; ++i) {
+    for (size_t i = 1; i < n; ++i)
         addSlice(slice_thickness, material);
-    }
 }
 
 void ProcessedSample::initBFields() {
diff --git a/Sample/RT/MatrixRTCoefficients.cpp b/Sample/RT/MatrixRTCoefficients.cpp
index aeef6194df18ad8d005b7117797d2abc812f112e..aa02cc6d1ff829e1aece28a256f0443c9ce9a864 100644
--- a/Sample/RT/MatrixRTCoefficients.cpp
+++ b/Sample/RT/MatrixRTCoefficients.cpp
@@ -21,7 +21,7 @@ const auto eps = std::numeric_limits<double>::epsilon() * 10.;
 } // namespace
 
 MatrixRTCoefficients::MatrixRTCoefficients(double kz_sign, Eigen::Vector2cd eigenvalues,
-                                                 kvector_t b, double magnetic_SLD)
+                                           kvector_t b, double magnetic_SLD)
     : m_kz_sign(kz_sign)
     , m_lambda(std::move(eigenvalues))
     , m_b(std::move(b))
diff --git a/Sample/RT/MatrixRTCoefficients.h b/Sample/RT/MatrixRTCoefficients.h
index 0f467eda100970224f81c3a690803f87f488ee78..74132d68cfe81e0c38f06225eac5e6bf2ce4a4cf 100644
--- a/Sample/RT/MatrixRTCoefficients.h
+++ b/Sample/RT/MatrixRTCoefficients.h
@@ -30,7 +30,7 @@ public:
     friend class SpecularMagneticTanhStrategy;
 
     MatrixRTCoefficients(double kz_sign, Eigen::Vector2cd eigenvalues, kvector_t b,
-                            double magnetic_SLD);
+                         double magnetic_SLD);
     MatrixRTCoefficients(const MatrixRTCoefficients& other);
     ~MatrixRTCoefficients() override;
 
diff --git a/Sample/Specular/SpecularMagneticNCStrategy.cpp b/Sample/Specular/SpecularMagneticNCStrategy.cpp
index 85746b1327d6c4af8600f0ecabf4d01f06e68cbc..104dc5074d7228d99c95e356e3f0087b4a182c81 100644
--- a/Sample/Specular/SpecularMagneticNCStrategy.cpp
+++ b/Sample/Specular/SpecularMagneticNCStrategy.cpp
@@ -18,10 +18,8 @@ namespace {
 complex_t checkForUnderflow(complex_t val);
 }
 
-std::pair<Eigen::Matrix2cd, Eigen::Matrix2cd>
-SpecularMagneticNCStrategy::computeRoughnessMatrices(const MatrixRTCoefficients& coeff_i,
-                                                        const MatrixRTCoefficients& coeff_i1,
-                                                        double sigma) const {
+std::pair<Eigen::Matrix2cd, Eigen::Matrix2cd> SpecularMagneticNCStrategy::computeRoughnessMatrices(
+    const MatrixRTCoefficients& coeff_i, const MatrixRTCoefficients& coeff_i1, double sigma) const {
     complex_t beta_i = coeff_i.m_lambda(1) - coeff_i.m_lambda(0);
     complex_t beta_i1 = coeff_i1.m_lambda(1) - coeff_i1.m_lambda(0);
 
@@ -66,8 +64,8 @@ SpecularMagneticNCStrategy::computeRoughnessMatrices(const MatrixRTCoefficients&
 
 std::pair<Eigen::Matrix2cd, Eigen::Matrix2cd>
 SpecularMagneticNCStrategy::computeBackwardsSubmatrices(const MatrixRTCoefficients& coeff_i,
-                                                           const MatrixRTCoefficients& coeff_i1,
-                                                           double sigma) const {
+                                                        const MatrixRTCoefficients& coeff_i1,
+                                                        double sigma) const {
     Eigen::Matrix2cd roughness_sum{Eigen::Matrix2cd::Identity()};
     Eigen::Matrix2cd roughness_diff{Eigen::Matrix2cd::Identity()};
     if (sigma != 0.) {
diff --git a/Sample/Specular/SpecularMagneticStrategy.cpp b/Sample/Specular/SpecularMagneticStrategy.cpp
index e940ff0093f780eea1efa006bd760c139848e5ce..0fa0fb2c1ac0bf367da4bbbd15cee1006e71f4d3 100644
--- a/Sample/Specular/SpecularMagneticStrategy.cpp
+++ b/Sample/Specular/SpecularMagneticStrategy.cpp
@@ -32,13 +32,13 @@ const LayerRoughness* GetBottomRoughness(const std::vector<Slice>& slices,
 } // namespace
 
 ISpecularStrategy::coeffs_t SpecularMagneticStrategy::Execute(const std::vector<Slice>& slices,
-                                                                 const kvector_t& k) const {
+                                                              const kvector_t& k) const {
     return Execute(slices, KzComputation::computeReducedKz(slices, k));
 }
 
 ISpecularStrategy::coeffs_t
 SpecularMagneticStrategy::Execute(const std::vector<Slice>& slices,
-                                     const std::vector<complex_t>& kz) const {
+                                  const std::vector<complex_t>& kz) const {
     if (slices.size() != kz.size())
         throw std::runtime_error("Number of slices does not match the size of the kz-vector");
 
@@ -51,7 +51,7 @@ SpecularMagneticStrategy::Execute(const std::vector<Slice>& slices,
 
 std::vector<MatrixRTCoefficients>
 SpecularMagneticStrategy::computeTR(const std::vector<Slice>& slices,
-                                       const std::vector<complex_t>& kzs) const {
+                                    const std::vector<complex_t>& kzs) const {
     const size_t N = slices.size();
 
     if (slices.size() != kzs.size())
@@ -95,7 +95,7 @@ SpecularMagneticStrategy::computeTR(const std::vector<Slice>& slices,
 }
 
 void SpecularMagneticStrategy::calculateUpwards(std::vector<MatrixRTCoefficients>& coeff,
-                                                   const std::vector<Slice>& slices) const {
+                                                const std::vector<Slice>& slices) const {
     const auto N = slices.size();
     std::vector<Eigen::Matrix2cd> SMatrices(N - 1);
     std::vector<complex_t> Normalization(N - 1);
diff --git a/Sample/Specular/SpecularMagneticStrategy.h b/Sample/Specular/SpecularMagneticStrategy.h
index 4906c817a347788beb1d0d649d3f152bf81c8877..f542da0d856487d0d7e93f9282b5d2feb0f87b89 100644
--- a/Sample/Specular/SpecularMagneticStrategy.h
+++ b/Sample/Specular/SpecularMagneticStrategy.h
@@ -34,14 +34,13 @@ class SpecularMagneticStrategy : public ISpecularStrategy {
 public:
     // TODO remove once external test code is not needed anmyore
     // for the moment i need them!
-    using coefficient_type         = MatrixRTCoefficients;
+    using coefficient_type = MatrixRTCoefficients;
     using coefficient_pointer_type = std::unique_ptr<const coefficient_type>;
-    using coeffs_t                 = std::vector<coefficient_pointer_type>;
+    using coeffs_t = std::vector<coefficient_pointer_type>;
 
     //! Computes refraction angle reflection/transmission coefficients
     //! for given sliced multilayer and wavevector k
-    ISpecularStrategy::coeffs_t Execute(const std::vector<Slice>& slices,
-                                        const kvector_t& k) const;
+    ISpecularStrategy::coeffs_t Execute(const std::vector<Slice>& slices, const kvector_t& k) const;
 
     //! Computes refraction angle reflection/transmission coefficients
     //! for given sliced multilayer and a set of kz projections corresponding to each slice
@@ -50,7 +49,7 @@ public:
 
 private:
     std::vector<MatrixRTCoefficients> computeTR(const std::vector<Slice>& slices,
-                                                   const std::vector<complex_t>& kzs) const;
+                                                const std::vector<complex_t>& kzs) const;
 
     virtual std::pair<Eigen::Matrix2cd, Eigen::Matrix2cd>
     computeBackwardsSubmatrices(const MatrixRTCoefficients& coeff_i,
diff --git a/Sample/Specular/SpecularMagneticTanhStrategy.cpp b/Sample/Specular/SpecularMagneticTanhStrategy.cpp
index 6ddc26a6b29f2b01335ad9947af7070f1922a750..fb85bd052468d4b8b8331fe118092faf3c26884b 100644
--- a/Sample/Specular/SpecularMagneticTanhStrategy.cpp
+++ b/Sample/Specular/SpecularMagneticTanhStrategy.cpp
@@ -22,7 +22,7 @@ const double pi2_15 = std::pow(M_PI_2, 1.5);
 
 Eigen::Matrix2cd
 SpecularMagneticTanhStrategy::computeRoughnessMatrix(const MatrixRTCoefficients& coeff,
-                                                        double sigma, bool inverse) const {
+                                                     double sigma, bool inverse) const {
     if (sigma < 10 * std::numeric_limits<double>::epsilon())
         return Eigen::Matrix2cd{Eigen::Matrix2cd::Identity()};
 
@@ -60,9 +60,9 @@ SpecularMagneticTanhStrategy::computeRoughnessMatrix(const MatrixRTCoefficients&
 }
 
 std::pair<Eigen::Matrix2cd, Eigen::Matrix2cd>
-SpecularMagneticTanhStrategy::computeBackwardsSubmatrices(
-    const MatrixRTCoefficients& coeff_i, const MatrixRTCoefficients& coeff_i1,
-    double sigma) const {
+SpecularMagneticTanhStrategy::computeBackwardsSubmatrices(const MatrixRTCoefficients& coeff_i,
+                                                          const MatrixRTCoefficients& coeff_i1,
+                                                          double sigma) const {
     Eigen::Matrix2cd R{Eigen::Matrix2cd::Identity()};
     Eigen::Matrix2cd RInv{Eigen::Matrix2cd::Identity()};
 
diff --git a/Sample/Specular/SpecularScalarStrategy.h b/Sample/Specular/SpecularScalarStrategy.h
index 15d8ae24e7b64f55e31e0fd8fe4f54f987bce2b6..a9889440cf5d20cc4b02ab0c2792fa69f7099116 100644
--- a/Sample/Specular/SpecularScalarStrategy.h
+++ b/Sample/Specular/SpecularScalarStrategy.h
@@ -34,9 +34,9 @@ class SpecularScalarStrategy : public ISpecularStrategy {
 public:
     // TODO remove once external test code is not needed anmyore
     // for the moment i need them!
-    using coefficient_type         = ScalarRTCoefficients;
+    using coefficient_type = ScalarRTCoefficients;
     using coefficient_pointer_type = std::unique_ptr<const coefficient_type>;
-    using coeffs_t                 = std::vector<coefficient_pointer_type>;
+    using coeffs_t = std::vector<coefficient_pointer_type>;
 
     //! Computes refraction angles and transmission/reflection coefficients
     //! for given coherent wave propagation in a multilayer.
diff --git a/Tests/GTestWrapper/google_test.h b/Tests/GTestWrapper/google_test.h
index b48f1d4f6dde7968d008458103086f9ddc07393f..de875d1891cd4f33d0bc3ee7a7803d760183d80d 100644
--- a/Tests/GTestWrapper/google_test.h
+++ b/Tests/GTestWrapper/google_test.h
@@ -38,16 +38,15 @@
     EXPECT_NEAR_COMPLEX(v1(0), v2(0), eps);                                                        \
     EXPECT_NEAR_COMPLEX(v1(1), v2(1), eps);
 
-#define EXPECT_NEAR_MATRIXCOEFF(c1, c2, eps) \
-    EXPECT_NEAR_VECTOR2CD(c1->T1plus(), c2->T1plus(), eps); \
-    EXPECT_NEAR_VECTOR2CD(c1->R1plus(), c2->R1plus(), eps); \
-    EXPECT_NEAR_VECTOR2CD(c1->T2plus(), c2->T2plus(), eps); \
-    EXPECT_NEAR_VECTOR2CD(c1->R2plus(), c2->R2plus(), eps); \
-    EXPECT_NEAR_VECTOR2CD(c1->T1min(), c2->T1min(), eps); \
-    EXPECT_NEAR_VECTOR2CD(c1->R1min(), c2->R1min(), eps); \
-    EXPECT_NEAR_VECTOR2CD(c1->T2min(), c2->T2min(), eps); \
-    EXPECT_NEAR_VECTOR2CD(c1->R2min(), c2->R2min(), eps); \
+#define EXPECT_NEAR_MATRIXCOEFF(c1, c2, eps)                                                       \
+    EXPECT_NEAR_VECTOR2CD(c1->T1plus(), c2->T1plus(), eps);                                        \
+    EXPECT_NEAR_VECTOR2CD(c1->R1plus(), c2->R1plus(), eps);                                        \
+    EXPECT_NEAR_VECTOR2CD(c1->T2plus(), c2->T2plus(), eps);                                        \
+    EXPECT_NEAR_VECTOR2CD(c1->R2plus(), c2->R2plus(), eps);                                        \
+    EXPECT_NEAR_VECTOR2CD(c1->T1min(), c2->T1min(), eps);                                          \
+    EXPECT_NEAR_VECTOR2CD(c1->R1min(), c2->R1min(), eps);                                          \
+    EXPECT_NEAR_VECTOR2CD(c1->T2min(), c2->T2min(), eps);                                          \
+    EXPECT_NEAR_VECTOR2CD(c1->R2min(), c2->R2min(), eps);                                          \
     EXPECT_NEAR_VECTOR2CD(c1->getKz(), c2->getKz(), eps)
 
-
 #endif // BORNAGAIN_TESTS_GTESTWRAPPER_GOOGLE_TEST_H
diff --git a/Tests/UnitTests/Core/Fresnel/SpecularMagneticTest.cpp b/Tests/UnitTests/Core/Fresnel/SpecularMagneticTest.cpp
index 9d57f448becfc1511b5fc9cc14a49a1133a8a1fc..e11310ffa269a450c2ede5d960b3737340240d2a 100644
--- a/Tests/UnitTests/Core/Fresnel/SpecularMagneticTest.cpp
+++ b/Tests/UnitTests/Core/Fresnel/SpecularMagneticTest.cpp
@@ -11,7 +11,6 @@
 #include "Tests/GTestWrapper/google_test.h"
 #include <utility>
 
-
 class SpecularMagneticTest : public ::testing::Test {
 protected:
     auto static constexpr eps = 1.e-10;
@@ -22,7 +21,8 @@ protected:
     template <typename Strategy> void test_degenerate();
     template <typename Strategy>
     void testZeroField(const kvector_t& k, const ProcessedSample& sample);
-    template <typename Strategy> void testcase_zerofield(std::vector<double>&& angles, bool slab=false);
+    template <typename Strategy>
+    void testcase_zerofield(std::vector<double>&& angles, bool slab = false);
 };
 
 template <> void SpecularMagneticTest::test_degenerate<SpecularMagneticTanhStrategy>() {
@@ -97,7 +97,7 @@ std::unique_ptr<ProcessedSample> SpecularMagneticTest::sample_zerofield(bool sla
     Layer substr_layer_scalar(substr_material_scalar);
     multi_layer_scalar.addLayer(vacuum_layer);
 
-    if(slab) {
+    if (slab) {
         Material layer_material = HomogeneousMaterial("Layer", 3e-6, 1e-8);
         Layer layer(layer_material, 10. * Units::nm);
         multi_layer_scalar.addLayer(layer);
@@ -136,7 +136,6 @@ TEST_F(SpecularMagneticTest, zerofield2_v2_positive_k) {
     testcase_zerofield<SpecularMagneticStrategy_v2>({0.1, 2.0, 10.0}, true);
 }
 
-
 TEST_F(SpecularMagneticTest, zerofield_positive_k) {
     testcase_zerofield<SpecularMagneticTanhStrategy>({0.0, 1.e-9, 1.e-5, 0.1, 2.0, 10.0});
 }
@@ -150,5 +149,6 @@ TEST_F(SpecularMagneticTest, zerofield2_positive_k) {
 }
 
 TEST_F(SpecularMagneticTest, zerofield2_negative_k) {
-    testcase_zerofield<SpecularMagneticTanhStrategy>({-0.0, -1.e-9, -1.e-5, -0.1, -2.0, -10.0}, true);
+    testcase_zerofield<SpecularMagneticTanhStrategy>({-0.0, -1.e-9, -1.e-5, -0.1, -2.0, -10.0},
+                                                     true);
 }
diff --git a/Tests/UnitTests/Core/Legacy/SpecularMagneticConsistencyTest.cpp b/Tests/UnitTests/Core/Legacy/SpecularMagneticConsistencyTest.cpp
index 4b974632db4aada7df0498462a9502d991eb19e4..f51ad50cffcbc7922bf6b53303807d671271366d 100644
--- a/Tests/UnitTests/Core/Legacy/SpecularMagneticConsistencyTest.cpp
+++ b/Tests/UnitTests/Core/Legacy/SpecularMagneticConsistencyTest.cpp
@@ -9,8 +9,7 @@
 #include "Sample/Specular/SpecularMagneticTanhStrategy.h"
 #include "Tests/GTestWrapper/google_test.h"
 
-class SpecularMagneticConsistencyTest : public ::testing::Test
-{
+class SpecularMagneticConsistencyTest : public ::testing::Test {
 protected:
     auto static constexpr eps = 1.e-10;
 
@@ -20,8 +19,7 @@ protected:
     void testcase(const std::vector<Slice>& slices, double k);
 };
 
-std::unique_ptr<ProcessedSample> SpecularMagneticConsistencyTest::sample_1()
-{
+std::unique_ptr<ProcessedSample> SpecularMagneticConsistencyTest::sample_1() {
     MultiLayer multi_layer_scalar;
     Material substr_material_scalar = HomogeneousMaterial("Substrate", 7e-6, 2e-8);
     Material layer_material = HomogeneousMaterial("Layer", 3e-6, 1e-8, kvector_t{1.e7, 0, 1.e7});
@@ -41,8 +39,7 @@ std::unique_ptr<ProcessedSample> SpecularMagneticConsistencyTest::sample_1()
 }
 
 template <typename Strategy1, typename Strategy2>
-void SpecularMagneticConsistencyTest::testcase(const std::vector<Slice>& slices, double k)
-{
+void SpecularMagneticConsistencyTest::testcase(const std::vector<Slice>& slices, double k) {
 
     const auto kz = kvector_t{0., 0., k};
     const auto coeffs1 = std::make_unique<Strategy1>()->Execute(
@@ -55,8 +52,7 @@ void SpecularMagneticConsistencyTest::testcase(const std::vector<Slice>& slices,
     }
 }
 
-TEST_F(SpecularMagneticConsistencyTest, NewOld)
-{
+TEST_F(SpecularMagneticConsistencyTest, NewOld) {
     using Strategy1 = SpecularMagneticTanhStrategy;
     using Strategy2 = SpecularMagneticStrategy_v2;
 
diff --git a/Tests/UnitTests/Core/Legacy/SpecularMagnetic_v1Test.cpp b/Tests/UnitTests/Core/Legacy/SpecularMagnetic_v1Test.cpp
index adc1ff579bcb32fb7a5268b9ee918e1e4bba7c3d..9f7c248d7d26fb07a8384b51fed1dfd3047b1ca9 100644
--- a/Tests/UnitTests/Core/Legacy/SpecularMagnetic_v1Test.cpp
+++ b/Tests/UnitTests/Core/Legacy/SpecularMagnetic_v1Test.cpp
@@ -1,10 +1,10 @@
 #include "Base/Const/Units.h"
+#include "Core/Legacy/SpecularMagneticStrategy_v1.h"
 #include "Sample/Material/MaterialFactoryFuncs.h"
 #include "Sample/Multilayer/Layer.h"
 #include "Sample/Multilayer/MultiLayer.h"
 #include "Sample/Processed/ProcessedSample.h"
 #include "Sample/RT/SimulationOptions.h"
-#include "Core/Legacy/SpecularMagneticStrategy_v1.h"
 #include "Sample/Specular/SpecularScalarTanhStrategy.h"
 #include "Tests/GTestWrapper/google_test.h"
 
diff --git a/Tests/UnitTests/Core/Sample/INodeTest.cpp b/Tests/UnitTests/Core/Sample/INodeTest.cpp
index c7982dde963f83095380954781dc4f355f871615..360cc4e93db946ff2c439bf7611af7e2c5d1404f 100644
--- a/Tests/UnitTests/Core/Sample/INodeTest.cpp
+++ b/Tests/UnitTests/Core/Sample/INodeTest.cpp
@@ -99,29 +99,29 @@ TEST_F(INodeTest, displayName) {
 
 TEST_F(INodeTest, nodePath) {
     INodeTest::TestClass root("root");
-    EXPECT_EQ(NodeUtils::nodePath(root), "/root");
+    EXPECT_EQ(NodeUtils::nodePath(&root), "/root");
 
     // adding first child
     INodeTest::TestClass* child0 = new INodeTest::TestClass("child");
     root.appendChild(child0);
-    EXPECT_EQ(NodeUtils::nodePath(*child0), "/root/child");
+    EXPECT_EQ(NodeUtils::nodePath(child0), "/root/child");
 
     // adding second child with the same name
     INodeTest::TestClass* child1 = new INodeTest::TestClass("child");
     root.appendChild(child1);
-    EXPECT_EQ(NodeUtils::nodePath(*child0), "/root/child0");
-    EXPECT_EQ(NodeUtils::nodePath(*child1), "/root/child1");
+    EXPECT_EQ(NodeUtils::nodePath(child0), "/root/child0");
+    EXPECT_EQ(NodeUtils::nodePath(child1), "/root/child1");
 
     // adding grandchild
     INodeTest::TestClass* grandchild = new INodeTest::TestClass("grandchild");
     child0->appendChild(grandchild);
-    EXPECT_EQ(NodeUtils::nodePath(*grandchild), "/root/child0/grandchild");
+    EXPECT_EQ(NodeUtils::nodePath(grandchild), "/root/child0/grandchild");
 
     // Now check path of grandchild wrt it's direct parent
-    EXPECT_EQ(NodeUtils::nodePath(*grandchild, child0), "/grandchild");
+    EXPECT_EQ(NodeUtils::nodePath(grandchild, child0), "/grandchild");
 
     // Check if exception is thrown when grandchild doesn't belong to child's branch
-    EXPECT_THROW(NodeUtils::nodePath(*grandchild, child1), std::runtime_error);
+    EXPECT_THROW(NodeUtils::nodePath(grandchild, child1), std::runtime_error);
 }
 
 //! Checking parameter tree for INode structure.
diff --git a/Tests/UnitTests/Core/Sample/ParticleLayoutTest.cpp b/Tests/UnitTests/Core/Sample/ParticleLayoutTest.cpp
index 0477413334843ac26f2b1d2c72f9b30550ded570..df3cd5e6b358c677e56a6385066e81068616a5ca 100644
--- a/Tests/UnitTests/Core/Sample/ParticleLayoutTest.cpp
+++ b/Tests/UnitTests/Core/Sample/ParticleLayoutTest.cpp
@@ -1,6 +1,6 @@
 #include "Sample/Aggregate/ParticleLayout.h"
 #include "Base/Const/Units.h"
-#include "Core/Export/NodeProgenity.h"
+#include "Core/Export/NodeProgeny.h"
 #include "Sample/Aggregate/InterferenceFunction1DLattice.h"
 #include "Sample/Aggregate/InterferenceFunctionNone.h"
 #include "Sample/Material/MaterialFactoryFuncs.h"
@@ -17,8 +17,8 @@ ParticleLayoutTest::~ParticleLayoutTest() = default;
 
 TEST_F(ParticleLayoutTest, ParticleLayoutInitial) {
     ParticleLayout particleDecoration;
-    auto p_iff = node_progenity::OnlyChildOfType<IInterferenceFunction>(particleDecoration);
-    auto particles = node_progenity::ChildNodesOfType<IAbstractParticle>(particleDecoration);
+    auto p_iff = node_progeny::OnlyChildOfType<IInterferenceFunction>(particleDecoration);
+    auto particles = node_progeny::ChildNodesOfType<IAbstractParticle>(particleDecoration);
     EXPECT_EQ(size_t(0), particles.size());
     EXPECT_EQ(nullptr, p_iff);
 }
@@ -27,8 +27,8 @@ TEST_F(ParticleLayoutTest, ParticleLayoutInitByValue) {
     Particle particle(HomogeneousMaterial());
 
     ParticleLayout particleDecoration(particle, 2.0);
-    auto p_iff = node_progenity::OnlyChildOfType<IInterferenceFunction>(particleDecoration);
-    auto particles = node_progenity::ChildNodesOfType<IAbstractParticle>(particleDecoration);
+    auto p_iff = node_progeny::OnlyChildOfType<IInterferenceFunction>(particleDecoration);
+    auto particles = node_progeny::ChildNodesOfType<IAbstractParticle>(particleDecoration);
     EXPECT_EQ(size_t(1), particles.size());
     EXPECT_EQ(nullptr, p_iff);
 
@@ -52,7 +52,7 @@ TEST_F(ParticleLayoutTest, ParticleLayoutAddParticle) {
     particleDecoration.addParticle(particle2, 2.2);
     particleDecoration.addParticle(particle3, 1.0, kvector_t(0, 0, 0), transform3);
     particleDecoration.addParticle(particle4, 4.2, kvector_t(0, 0, 0), transform4);
-    auto particles = node_progenity::ChildNodesOfType<IAbstractParticle>(particleDecoration);
+    auto particles = node_progeny::ChildNodesOfType<IAbstractParticle>(particleDecoration);
 
     EXPECT_EQ(size_t(4), particles.size());
 
@@ -117,7 +117,7 @@ TEST_F(ParticleLayoutTest, ParticleLayoutClone) {
     particleDecoration.setInterferenceFunction(iff_none);
 
     ParticleLayout* clone = particleDecoration.clone();
-    auto particles = node_progenity::ChildNodesOfType<IAbstractParticle>(*clone);
+    auto particles = node_progeny::ChildNodesOfType<IAbstractParticle>(*clone);
 
     const IAbstractParticle* p_particle1 = particles[0];
     EXPECT_TRUE(nullptr != p_particle1);
@@ -139,7 +139,7 @@ TEST_F(ParticleLayoutTest, ParticleLayoutClone) {
     EXPECT_TRUE(nullptr != p_particle5);
     EXPECT_EQ(0.0, p_particle5->abundance());
 
-    auto p_iff = node_progenity::OnlyChildOfType<IInterferenceFunction>(*clone);
+    auto p_iff = node_progeny::OnlyChildOfType<IInterferenceFunction>(*clone);
 
     EXPECT_TRUE(nullptr != p_iff);
 }
@@ -149,7 +149,7 @@ TEST_F(ParticleLayoutTest, ParticleLayoutInterferenceFunction) {
 
     InterferenceFunctionNone iff_none;
     particleDecoration.setInterferenceFunction(iff_none);
-    auto p_iff = node_progenity::OnlyChildOfType<IInterferenceFunction>(particleDecoration);
+    auto p_iff = node_progeny::OnlyChildOfType<IInterferenceFunction>(particleDecoration);
 
     EXPECT_TRUE(nullptr != p_iff);
 }
diff --git a/ThirdParty/GUI/CMakeLists.txt b/ThirdParty/GUI/CMakeLists.txt
deleted file mode 100644
index c8f8cea6c2d31bb285d9172486c874f54be59203..0000000000000000000000000000000000000000
--- a/ThirdParty/GUI/CMakeLists.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-add_subdirectory(qt-manhattan-style)
-add_subdirectory(qcustomplot)
-
-set(QtAddOn_INCLUDE_DIRS
-    ${ManhattanStyle_INCLUDE_DIRS}
-    ${qcustomplot_INCLUDE_DIRS}
-    PARENT_SCOPE)
-
-set(QtAddOn_LIBRARIES
-    ${ManhattanStyle_LIBRARY}
-    ${qcustomplot_LIBRARY}
-    PARENT_SCOPE)
diff --git a/Wrap/swig/libBornAgainBase.i b/Wrap/swig/libBornAgainBase.i
index 34fa6b3ded7cef8e0bdebde3651d3ade9ba2f1d0..1c11aeddf35235580ead623452e0db46cf1e76b1 100644
--- a/Wrap/swig/libBornAgainBase.i
+++ b/Wrap/swig/libBornAgainBase.i
@@ -24,14 +24,14 @@
 %{
 #include "Base/Types/Complex.h"
 #include "Base/Types/ICloneable.h"
-#include "Base/Const/Units.h"
+
 #include "Base/Utils/ThreadInfo.h"
 
+#include "Base/Const/Units.h"
+
 #include "Base/Vector/BasicVector3D.h"
 #include "Base/Vector/Vectors3D.h"
 
-#include "Base/Math/Functions.h"
-
 #include "Base/Axis/Bin.h"
 #include "Base/Axis/ConstKBinAxis.h"
 #include "Base/Axis/CustomBinAxis.h"
@@ -42,13 +42,13 @@
 
 %}
 
-%include "Base/Types/ICloneable.h"
 %include "Base/Types/Complex.h"
-%include "Base/Const/Units.h"
+%include "Base/Types/ICloneable.h"
 
-%include "Base/Math/Functions.h"
 %include "Base/Utils/ThreadInfo.h"
 
+%include "Base/Const/Units.h"
+
 %include "Base/Vector/BasicVector3D.h"
 %include "Base/Vector/Vectors3D.h"
 
diff --git a/Wrap/swig/libBornAgainCore.i b/Wrap/swig/libBornAgainCore.i
index 8d5eeda300207e2fcad86b1daea08f552e37ae46..e3c40850623c75f4a0758465c2c0df1a6036f1a1 100644
--- a/Wrap/swig/libBornAgainCore.i
+++ b/Wrap/swig/libBornAgainCore.i
@@ -91,9 +91,6 @@
 %template(swig_dummy_type_inode_vector) std::vector<INode*>;
 %template(swig_dummy_type_const_inode_vector) std::vector<const INode*>;
 
-%include "Base/Utils/IFactory.h"
-%template(SimulationFactoryTemp) IFactory<std::string, ISimulation>;
-
 %include "Core/Fitting/FitObjective.h"
 %template(addSimulationAndData) FitObjective::addSimulationAndData<std::vector<double>>;
 %template(addSimulationAndData) FitObjective::addSimulationAndData<std::vector<std::vector<double>>>;
@@ -119,8 +116,6 @@
 %include "Core/Computation/ConstantBackground.h"
 %include "Core/Computation/PoissonNoiseBackground.h"
 
-%include "Core/Simulation/SimulationFactory.h"
-
 %include "Core/Export/ExportToPython.h"
 
 %extend BasicVector3D<double> {
diff --git a/Wrap/swig/libBornAgainParam.i b/Wrap/swig/libBornAgainParam.i
index 2f68a5c23345d588a9be1234ef9721a806f08a39..1119602270ee835400d3a99b4b121da3524804ca 100644
--- a/Wrap/swig/libBornAgainParam.i
+++ b/Wrap/swig/libBornAgainParam.i
@@ -65,7 +65,6 @@
 %include "Param/Base/IParametricComponent.h"
 %feature("director") INode;              // needed by ISampleNode
 %include "Param/Node/INode.h"
-
 %include "Param/Node/INodeVisitor.h"
 
 %include "Param/Distrib/Distributions.h"
diff --git a/auto/Wrap/doxygenBase.i b/auto/Wrap/doxygenBase.i
index dc8dcfbe99895a5c2c5fe610eecb70cc40b41ef6..a5c37c16ea8822ea598fa0bd635f5250338fd16f 100644
--- a/auto/Wrap/doxygenBase.i
+++ b/auto/Wrap/doxygenBase.i
@@ -11,12 +11,12 @@ C++ includes: BasicVector3D.h
 
 %feature("docstring")  BasicVector3D::BasicVector3D "BasicVector3D< T >::BasicVector3D()
 
-Default constructor. 
+Constructs the null vector. 
 ";
 
 %feature("docstring")  BasicVector3D::BasicVector3D "BasicVector3D< T >::BasicVector3D(const T x1, const T y1, const T z1)
 
-Constructor from cartesian components. 
+Constructs a vector from cartesian components. 
 ";
 
 %feature("docstring")  BasicVector3D::x "T BasicVector3D< T >::x() const
@@ -1185,7 +1185,7 @@ Creates directories in current directory for any element of dir_name which doesn
 Returns filenames of files in directory. 
 ";
 
-%feature("docstring")  FileSystemUtils::jointPath "std::string FileSystemUtils::jointPath(const std::string &spath1, const std::string &spath2)
+%feature("docstring")  FileSystemUtils::jointPath "std::string FileSystemUtils::jointPath(const std::string &path1, const std::string &path2)
 
 Returns joint path name. 
 ";
@@ -1197,7 +1197,7 @@ Returns path without directory part (\"Foo/Bar/Doz.int.gz\" -> \"Doz.int.gz\")
 
 %feature("docstring")  FileSystemUtils::stem "std::string FileSystemUtils::stem(const std::string &path)
 
-Returns filename without extension. \"/home/user/filename.int\" -> \"filename\", \"/home/user/filename.int.gz\" -> \"filename.int\" 
+Returns filename without (last) extension. \"/home/user/filename.int\" -> \"filename\", \"/home/user/filename.int.gz\" -> \"filename.int\" 
 ";
 
 %feature("docstring")  FileSystemUtils::stem_ext "std::string FileSystemUtils::stem_ext(const std::string &path)
@@ -1215,7 +1215,7 @@ Returns file names that agree with a regex glob pattern.
 Converts utf8 string represented by std::string to utf16 string represented by std::wstring. 
 ";
 
-%feature("docstring")  FileSystemUtils::IsFileExists "bool FileSystemUtils::IsFileExists(const std::string &str)
+%feature("docstring")  FileSystemUtils::IsFileExists "bool FileSystemUtils::IsFileExists(const std::string &path)
 
 Returns true if file with given name exists on disk. 
 ";
diff --git a/auto/Wrap/doxygenCore.i b/auto/Wrap/doxygenCore.i
index 5e359576a199fb9233b37ca7b05e17dae16ab508..d2a93462617422b0d316d505b8a9b94975b3e651 100644
--- a/auto/Wrap/doxygenCore.i
+++ b/auto/Wrap/doxygenCore.i
@@ -1236,6 +1236,119 @@ 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 "";
 
@@ -1898,6 +2011,44 @@ 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 "
 
@@ -2134,6 +2285,9 @@ Returns default units to convert to.
 ";
 
 
+// File: namespace_0d101.xml
+
+
 // File: namespace_0d15.xml
 
 
@@ -2158,27 +2312,33 @@ Returns default units to convert to.
 // File: namespace_0d62.xml
 
 
-// File: namespace_0d64.xml
+// File: namespace_0d66.xml
+
 
+// File: namespace_0d68.xml
 
-// File: namespace_0d69.xml
 
+// File: namespace_0d70.xml
 
-// File: namespace_0d71.xml
 
+// File: namespace_0d72.xml
 
-// File: namespace_0d75.xml
 
+// File: namespace_0d77.xml
 
-// File: namespace_0d85.xml
 
+// File: namespace_0d79.xml
 
-// File: namespace_0d87.xml
+
+// File: namespace_0d83.xml
 
 
 // File: namespace_0d93.xml
 
 
+// File: namespace_0d95.xml
+
+
 // File: namespaceExportToPython.xml
 %feature("docstring")  ExportToPython::generateSampleCode "std::string ExportToPython::generateSampleCode(const MultiLayer &multilayer)
 ";
@@ -2190,14 +2350,14 @@ Returns default units to convert to.
 // File: namespacemumufit.xml
 
 
-// File: namespacenode__progenity.xml
-%feature("docstring")  node_progenity::ChildNodesOfType "std::vector<const T*> node_progenity::ChildNodesOfType(const INode &node)
+// File: namespacenode__progeny.xml
+%feature("docstring")  node_progeny::ChildNodesOfType "std::vector<const T*> node_progeny::ChildNodesOfType(const INode &node)
 ";
 
-%feature("docstring")  node_progenity::OnlyChildOfType "const T* node_progenity::OnlyChildOfType(const INode &node)
+%feature("docstring")  node_progeny::OnlyChildOfType "const T* node_progeny::OnlyChildOfType(const INode &node)
 ";
 
-%feature("docstring")  node_progenity::AllDescendantsOfType "std::vector<const T*> node_progenity::AllDescendantsOfType(const INode &node)
+%feature("docstring")  node_progeny::AllDescendantsOfType "std::vector<const T*> node_progeny::AllDescendantsOfType(const INode &node)
 ";
 
 
@@ -2632,7 +2792,7 @@ Helper factory function to use in  GISASSimulation. Depending on the type of det
 // File: MaterialKeyHandler_8h.xml
 
 
-// File: NodeProgenity_8h.xml
+// File: NodeProgeny_8h.xml
 
 
 // File: PyFmt_8cpp.xml
@@ -2725,6 +2885,30 @@ Helper factory function to use in  GISASSimulation. Depending on the type of det
 // File: SimDataPair_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: AngularSpecScan_8cpp.xml
 
 
@@ -2833,6 +3017,9 @@ Helper factory function to use in  GISASSimulation. Depending on the type of det
 // File: dir_4470199ae7eb44153ffe31d163ed0f28.xml
 
 
+// File: dir_bd39ec89b96ad8d1385770847b662047.xml
+
+
 // File: dir_6de83e740cfcd9d0abfe8dffab2832a5.xml
 
 
diff --git a/auto/Wrap/doxygenParam.i b/auto/Wrap/doxygenParam.i
index a6f4d22a3e33ffe8c5a42fbbb692cc51b6ff0303..a777a86bf758b52ee04d38f596d874918b8997fa 100644
--- a/auto/Wrap/doxygenParam.i
+++ b/auto/Wrap/doxygenParam.i
@@ -452,7 +452,12 @@ Returns multiline string representing tree structure below the node.
 
 %feature("docstring")  INode::getChildren "std::vector< const INode * > INode::getChildren() const
 
-Returns a vector of children (const). 
+Returns a vector of children. 
+";
+
+%feature("docstring")  INode::progeny "std::vector< const INode * > INode::progeny() const
+
+Returns a vector of all descendents. 
 ";
 
 %feature("docstring")  INode::setParent "void INode::setParent(const INode *newParent)
@@ -1625,19 +1630,24 @@ C++ includes: Unit.h
 // File: namespace_0d15.xml
 
 
-// File: namespace_0d25.xml
+// File: namespace_0d24.xml
 
 
-// File: namespace_0d30.xml
+// File: namespace_0d29.xml
 
 
 // File: namespaceNodeUtils.xml
-%feature("docstring")  NodeUtils::nodeToString "std::string NodeUtils::nodeToString(const INode &node)
+%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) 
+";
+
+%feature("docstring")  NodeUtils::nodeToString "std::string NodeUtils::nodeToString(const INode *node)
 
 Returns multiline string representing tree structure starting from given node. 
 ";
 
-%feature("docstring")  NodeUtils::nodePath "std::string NodeUtils::nodePath(const INode &node, const INode *root=nullptr)
+%feature("docstring")  NodeUtils::nodePath "std::string NodeUtils::nodePath(const INode *node, const INode *root=nullptr)
 
 Returns path composed of node's displayName, with respect to root node. 
 ";
@@ -1716,14 +1726,7 @@ Returns units of main parameter.
 ";
 
 
-// File: INodeVisitor_8cpp.xml
-%feature("docstring")  VisitNodesPreorder "void VisitNodesPreorder(const INode &node, INodeVisitor &visitor)
-";
-
-
 // File: INodeVisitor_8h.xml
-%feature("docstring")  VisitNodesPreorder "void VisitNodesPreorder(const INode &node, INodeVisitor &visitor)
-";
 
 
 // File: IterationStrategy_8cpp.xml
diff --git a/auto/Wrap/doxygenSample.i b/auto/Wrap/doxygenSample.i
index 4f89b82288769b3bfbc2f0c2eaa1e8369574a746..0ad73a54aa74f9d5c7553716658c64c2401b22b5 100644
--- a/auto/Wrap/doxygenSample.i
+++ b/auto/Wrap/doxygenSample.i
@@ -4655,7 +4655,7 @@ Evaluates the peak shape at q from a reciprocal lattice point at q_lattice_point
 
 Interface for the Fresnel computations, both in the scalar and magnetic case
 
-Inherited by  SpecularScalarStrategy,  SpecularMagneticOldStrategy,  SpecularMagneticStrategy,  SpecularMagneticNewStrategy
+Inherited by  SpecularScalarStrategy, SpecularMagneticOldStrategy,  SpecularMagneticStrategy, SpecularMagneticNewStrategy
 
 C++ includes: ISpecularStrategy.h
 ";
@@ -5406,180 +5406,67 @@ Retrieves the amplitude coefficients for a (time-reversed) outgoing wavevector.
 // File: classMatrixRTCoefficients.xml
 %feature("docstring") MatrixRTCoefficients "
 
-Specular reflection and transmission coefficients in a layer in case of 2x2 matrix interactions between the layers and the scattered particle.
-
-C++ includes: MatrixRTCoefficients.h
-";
-
-%feature("docstring")  MatrixRTCoefficients::MatrixRTCoefficients "MatrixRTCoefficients::MatrixRTCoefficients()
-";
-
-%feature("docstring")  MatrixRTCoefficients::~MatrixRTCoefficients "virtual MatrixRTCoefficients::~MatrixRTCoefficients()
-";
-
-%feature("docstring")  MatrixRTCoefficients::clone "MatrixRTCoefficients * MatrixRTCoefficients::clone() const
-";
-
-%feature("docstring")  MatrixRTCoefficients::T1plus "Eigen::Vector2cd MatrixRTCoefficients::T1plus() const
-
-The following functions return the transmitted and reflected amplitudes for different incoming beam polarizations and eigenmodes 
-";
-
-%feature("docstring")  MatrixRTCoefficients::R1plus "Eigen::Vector2cd MatrixRTCoefficients::R1plus() const
-";
-
-%feature("docstring")  MatrixRTCoefficients::T2plus "Eigen::Vector2cd MatrixRTCoefficients::T2plus() const
-";
-
-%feature("docstring")  MatrixRTCoefficients::R2plus "Eigen::Vector2cd MatrixRTCoefficients::R2plus() const
-";
-
-%feature("docstring")  MatrixRTCoefficients::T1min "Eigen::Vector2cd MatrixRTCoefficients::T1min() const
-";
-
-%feature("docstring")  MatrixRTCoefficients::R1min "Eigen::Vector2cd MatrixRTCoefficients::R1min() const
-";
-
-%feature("docstring")  MatrixRTCoefficients::T2min "Eigen::Vector2cd MatrixRTCoefficients::T2min() const
-";
-
-%feature("docstring")  MatrixRTCoefficients::R2min "Eigen::Vector2cd MatrixRTCoefficients::R2min() const
-";
-
-%feature("docstring")  MatrixRTCoefficients::getKz "virtual Eigen::Vector2cd MatrixRTCoefficients::getKz() const
-
-Returns z-part of the two wavevector eigenmodes. 
-";
-
-%feature("docstring")  MatrixRTCoefficients::calculateTRMatrices "void MatrixRTCoefficients::calculateTRMatrices()
-";
-
-%feature("docstring")  MatrixRTCoefficients::calculateTRWithoutMagnetization "void MatrixRTCoefficients::calculateTRWithoutMagnetization()
-";
-
-%feature("docstring")  MatrixRTCoefficients::initializeBottomLayerPhiPsi "void MatrixRTCoefficients::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: classMatrixRTCoefficients__v3.xml
-%feature("docstring") MatrixRTCoefficients_v3 "
-
 Specular reflection and transmission coefficients in a layer in case of magnetic interactions between the scattered particle and the layer.
 
-C++ includes: MatrixRTCoefficients_v3.h
+C++ includes: MatrixRTCoefficients.h
 ";
 
-%feature("docstring")  MatrixRTCoefficients_v3::MatrixRTCoefficients_v3 "MatrixRTCoefficients_v3::MatrixRTCoefficients_v3(double kz_sign, Eigen::Vector2cd eigenvalues, kvector_t b, double magnetic_SLD)
+%feature("docstring")  MatrixRTCoefficients::MatrixRTCoefficients "MatrixRTCoefficients::MatrixRTCoefficients(double kz_sign, Eigen::Vector2cd eigenvalues, kvector_t b, double magnetic_SLD)
 ";
 
-%feature("docstring")  MatrixRTCoefficients_v3::MatrixRTCoefficients_v3 "MatrixRTCoefficients_v3::MatrixRTCoefficients_v3(const MatrixRTCoefficients_v3 &other)
+%feature("docstring")  MatrixRTCoefficients::MatrixRTCoefficients "MatrixRTCoefficients::MatrixRTCoefficients(const MatrixRTCoefficients &other)
 ";
 
-%feature("docstring")  MatrixRTCoefficients_v3::~MatrixRTCoefficients_v3 "MatrixRTCoefficients_v3::~MatrixRTCoefficients_v3() override
+%feature("docstring")  MatrixRTCoefficients::~MatrixRTCoefficients "MatrixRTCoefficients::~MatrixRTCoefficients() override
 ";
 
-%feature("docstring")  MatrixRTCoefficients_v3::clone "MatrixRTCoefficients_v3 * MatrixRTCoefficients_v3::clone() const override
+%feature("docstring")  MatrixRTCoefficients::clone "MatrixRTCoefficients * MatrixRTCoefficients::clone() const override
 ";
 
-%feature("docstring")  MatrixRTCoefficients_v3::T1plus "Eigen::Vector2cd MatrixRTCoefficients_v3::T1plus() const override
+%feature("docstring")  MatrixRTCoefficients::T1plus "Eigen::Vector2cd MatrixRTCoefficients::T1plus() const override
 
 The following functions return the transmitted and reflected amplitudes for different incoming beam polarizations and eigenmodes 
 ";
 
-%feature("docstring")  MatrixRTCoefficients_v3::R1plus "Eigen::Vector2cd MatrixRTCoefficients_v3::R1plus() const override
+%feature("docstring")  MatrixRTCoefficients::R1plus "Eigen::Vector2cd MatrixRTCoefficients::R1plus() const override
 ";
 
-%feature("docstring")  MatrixRTCoefficients_v3::T2plus "Eigen::Vector2cd MatrixRTCoefficients_v3::T2plus() const override
+%feature("docstring")  MatrixRTCoefficients::T2plus "Eigen::Vector2cd MatrixRTCoefficients::T2plus() const override
 ";
 
-%feature("docstring")  MatrixRTCoefficients_v3::R2plus "Eigen::Vector2cd MatrixRTCoefficients_v3::R2plus() const override
+%feature("docstring")  MatrixRTCoefficients::R2plus "Eigen::Vector2cd MatrixRTCoefficients::R2plus() const override
 ";
 
-%feature("docstring")  MatrixRTCoefficients_v3::T1min "Eigen::Vector2cd MatrixRTCoefficients_v3::T1min() const override
+%feature("docstring")  MatrixRTCoefficients::T1min "Eigen::Vector2cd MatrixRTCoefficients::T1min() const override
 ";
 
-%feature("docstring")  MatrixRTCoefficients_v3::R1min "Eigen::Vector2cd MatrixRTCoefficients_v3::R1min() const override
+%feature("docstring")  MatrixRTCoefficients::R1min "Eigen::Vector2cd MatrixRTCoefficients::R1min() const override
 ";
 
-%feature("docstring")  MatrixRTCoefficients_v3::T2min "Eigen::Vector2cd MatrixRTCoefficients_v3::T2min() const override
+%feature("docstring")  MatrixRTCoefficients::T2min "Eigen::Vector2cd MatrixRTCoefficients::T2min() const override
 ";
 
-%feature("docstring")  MatrixRTCoefficients_v3::R2min "Eigen::Vector2cd MatrixRTCoefficients_v3::R2min() const override
+%feature("docstring")  MatrixRTCoefficients::R2min "Eigen::Vector2cd MatrixRTCoefficients::R2min() const override
 ";
 
-%feature("docstring")  MatrixRTCoefficients_v3::getKz "Eigen::Vector2cd MatrixRTCoefficients_v3::getKz() const override
+%feature("docstring")  MatrixRTCoefficients::getKz "Eigen::Vector2cd MatrixRTCoefficients::getKz() const override
 
 Returns z-part of the two wavevector eigenmodes. 
 ";
 
-%feature("docstring")  MatrixRTCoefficients_v3::magneticSLD "double MatrixRTCoefficients_v3::magneticSLD() const
+%feature("docstring")  MatrixRTCoefficients::magneticSLD "double MatrixRTCoefficients::magneticSLD() const
 ";
 
-%feature("docstring")  MatrixRTCoefficients_v3::computeP "Eigen::Matrix2cd MatrixRTCoefficients_v3::computeP() const
+%feature("docstring")  MatrixRTCoefficients::computeP "Eigen::Matrix2cd MatrixRTCoefficients::computeP() const
 ";
 
-%feature("docstring")  MatrixRTCoefficients_v3::computeInverseP "Eigen::Matrix2cd MatrixRTCoefficients_v3::computeInverseP() const
+%feature("docstring")  MatrixRTCoefficients::computeInverseP "Eigen::Matrix2cd MatrixRTCoefficients::computeInverseP() const
 ";
 
-%feature("docstring")  MatrixRTCoefficients_v3::computeDeltaMatrix "Eigen::Matrix2cd MatrixRTCoefficients_v3::computeDeltaMatrix(double thickness)
+%feature("docstring")  MatrixRTCoefficients::computeDeltaMatrix "Eigen::Matrix2cd MatrixRTCoefficients::computeDeltaMatrix(double thickness)
 ";
 
-%feature("docstring")  MatrixRTCoefficients_v3::getReflectionMatrix "Eigen::Matrix2cd MatrixRTCoefficients_v3::getReflectionMatrix() const override
+%feature("docstring")  MatrixRTCoefficients::getReflectionMatrix "Eigen::Matrix2cd MatrixRTCoefficients::getReflectionMatrix() const override
 ";
 
 
@@ -7239,84 +7126,46 @@ C++ includes: IBornFF.h
 ";
 
 
-// File: classSpecularMagneticNewNCStrategy.xml
-%feature("docstring") SpecularMagneticNewNCStrategy "
+// File: classSpecularMagneticNCStrategy.xml
+%feature("docstring") SpecularMagneticNCStrategy "
 
 Implements the magnetic Fresnel computation with Nevot-Croce roughness
 
 Implements the transfer matrix formalism for the calculation of wave amplitudes of the coherent wave solution in a multilayer with magnetization. For a description, see internal document \"Polarized Implementation of the Transfer Matrix Method\"
 
-C++ includes: SpecularMagneticNewNCStrategy.h
+C++ includes: SpecularMagneticNCStrategy.h
 ";
 
 
-// File: classSpecularMagneticNewStrategy.xml
-%feature("docstring") SpecularMagneticNewStrategy "
+// File: classSpecularMagneticStrategy.xml
+%feature("docstring") SpecularMagneticStrategy "
 
 Implements the magnetic Fresnel computation with Nevot-Croce roughness
 
 Implements the transfer matrix formalism for the calculation of wave amplitudes of the coherent wave solution in a multilayer with magnetization. For a description, see internal document \"Polarized Implementation of the Transfer Matrix Method\"
 
-C++ includes: SpecularMagneticNewStrategy.h
+C++ includes: SpecularMagneticStrategy.h
 ";
 
-%feature("docstring")  SpecularMagneticNewStrategy::Execute "ISpecularStrategy::coeffs_t SpecularMagneticNewStrategy::Execute(const std::vector< Slice > &slices, const kvector_t &k) const
+%feature("docstring")  SpecularMagneticStrategy::Execute "ISpecularStrategy::coeffs_t SpecularMagneticStrategy::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")  SpecularMagneticNewStrategy::Execute "ISpecularStrategy::coeffs_t SpecularMagneticNewStrategy::Execute(const std::vector< Slice > &slices, const std::vector< complex_t > &kz) const
+%feature("docstring")  SpecularMagneticStrategy::Execute "ISpecularStrategy::coeffs_t SpecularMagneticStrategy::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: classSpecularMagneticNewTanhStrategy.xml
-%feature("docstring") SpecularMagneticNewTanhStrategy "
+// File: classSpecularMagneticTanhStrategy.xml
+%feature("docstring") SpecularMagneticTanhStrategy "
 
 Implements the magnetic Fresnel computation with the analytical Tanh roughness
 
 Implements the transfer matrix formalism for the calculation of wave amplitudes of the coherent wave solution in a multilayer with magnetization. For a description, see internal document \"Polarized Implementation of the Transfer Matrix Method\"
 
-C++ includes: SpecularMagneticNewTanhStrategy.h
-";
-
-
-// File: classSpecularMagneticOldStrategy.xml
-%feature("docstring") SpecularMagneticOldStrategy "
-
-Implements the matrix formalism for the calculation of wave amplitudes of the coherent wave solution in a multilayer with magnetization.
-
-C++ includes: SpecularMagneticOldStrategy.h
-";
-
-%feature("docstring")  SpecularMagneticOldStrategy::Execute "ISpecularStrategy::coeffs_t SpecularMagneticOldStrategy::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")  SpecularMagneticOldStrategy::Execute "ISpecularStrategy::coeffs_t SpecularMagneticOldStrategy::Execute(const std::vector< Slice > &slices, const std::vector< complex_t > &kz) const
-";
-
-
-// File: classSpecularMagneticStrategy.xml
-%feature("docstring") SpecularMagneticStrategy "
-
-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.h
-";
-
-%feature("docstring")  SpecularMagneticStrategy::Execute "ISpecularStrategy::coeffs_t SpecularMagneticStrategy::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::Execute "ISpecularStrategy::coeffs_t SpecularMagneticStrategy::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 
+C++ includes: SpecularMagneticTanhStrategy.h
 ";
 
 
@@ -7655,34 +7504,34 @@ C++ includes: ZLimits.h
 // File: namespace_0d205.xml
 
 
-// File: namespace_0d210.xml
+// File: namespace_0d208.xml
 
 
-// File: namespace_0d212.xml
+// File: namespace_0d218.xml
 
 
-// File: namespace_0d222.xml
+// File: namespace_0d232.xml
 
 
-// File: namespace_0d236.xml
+// File: namespace_0d237.xml
 
 
-// File: namespace_0d241.xml
+// File: namespace_0d25.xml
 
 
-// File: namespace_0d25.xml
+// File: namespace_0d255.xml
 
 
-// File: namespace_0d259.xml
+// File: namespace_0d263.xml
 
 
-// File: namespace_0d267.xml
+// File: namespace_0d273.xml
 
 
-// File: namespace_0d277.xml
+// File: namespace_0d275.xml
 
 
-// File: namespace_0d279.xml
+// File: namespace_0d277.xml
 
 
 // File: namespace_0d281.xml
@@ -7691,34 +7540,25 @@ C++ includes: ZLimits.h
 // File: namespace_0d283.xml
 
 
-// File: namespace_0d285.xml
-
-
-// File: namespace_0d289.xml
+// File: namespace_0d287.xml
 
 
-// File: namespace_0d291.xml
+// File: namespace_0d299.xml
 
 
-// File: namespace_0d295.xml
+// File: namespace_0d305.xml
 
 
-// File: namespace_0d307.xml
+// File: namespace_0d309.xml
 
 
 // File: namespace_0d31.xml
 
 
-// File: namespace_0d313.xml
-
-
-// File: namespace_0d317.xml
+// File: namespace_0d327.xml
 
 
-// File: namespace_0d335.xml
-
-
-// File: namespace_0d354.xml
+// File: namespace_0d346.xml
 
 
 // File: namespace_0d37.xml
@@ -8616,18 +8456,6 @@ Creates averaged material. Square refractive index of returned material is arith
 // File: MatrixRTCoefficients_8h.xml
 
 
-// File: MatrixRTCoefficients__v2_8cpp.xml
-
-
-// File: MatrixRTCoefficients__v2_8h.xml
-
-
-// File: MatrixRTCoefficients__v3_8cpp.xml
-
-
-// File: MatrixRTCoefficients__v3_8h.xml
-
-
 // File: ScalarRTCoefficients_8h.xml
 
 
@@ -8863,34 +8691,22 @@ Generate vertices of centered ellipse with given semi-axes at height z.
 // File: ISpecularStrategy_8h.xml
 
 
-// File: SpecularMagneticNewNCStrategy_8cpp.xml
-
-
-// File: SpecularMagneticNewNCStrategy_8h.xml
-
+// File: SpecularMagneticNCStrategy_8cpp.xml
 
-// File: SpecularMagneticNewStrategy_8cpp.xml
 
+// File: SpecularMagneticNCStrategy_8h.xml
 
-// File: SpecularMagneticNewStrategy_8h.xml
 
-
-// File: SpecularMagneticNewTanhStrategy_8cpp.xml
-
-
-// File: SpecularMagneticNewTanhStrategy_8h.xml
-
-
-// File: SpecularMagneticOldStrategy_8cpp.xml
+// File: SpecularMagneticStrategy_8cpp.xml
 
 
-// File: SpecularMagneticOldStrategy_8h.xml
+// File: SpecularMagneticStrategy_8h.xml
 
 
-// File: SpecularMagneticStrategy_8cpp.xml
+// File: SpecularMagneticTanhStrategy_8cpp.xml
 
 
-// File: SpecularMagneticStrategy_8h.xml
+// File: SpecularMagneticTanhStrategy_8h.xml
 
 
 // File: SpecularScalarNCStrategy_8cpp.xml
diff --git a/auto/Wrap/libBornAgainBase.py b/auto/Wrap/libBornAgainBase.py
index ff85d13d1ed183838594f9935f5cc63033063658..6f3a7843bc39c314c6d39f5105a05aa2b80b0613 100644
--- a/auto/Wrap/libBornAgainBase.py
+++ b/auto/Wrap/libBornAgainBase.py
@@ -1678,6 +1678,26 @@ class vector_pvacuum_double_t(object):
 # Register vector_pvacuum_double_t in _libBornAgainBase:
 _libBornAgainBase.vector_pvacuum_double_t_swigregister(vector_pvacuum_double_t)
 
+
+def mul_I(z):
+    r"""
+    mul_I(complex_t z) -> complex_t
+    complex_t mul_I(complex_t z)
+
+    Returns product I*z, where I is the imaginary unit. 
+
+    """
+    return _libBornAgainBase.mul_I(z)
+
+def exp_I(z):
+    r"""
+    exp_I(complex_t z) -> complex_t
+    complex_t exp_I(complex_t z)
+
+    Returns exp(I*z), where I is the imaginary unit. 
+
+    """
+    return _libBornAgainBase.exp_I(z)
 class ICloneable(object):
     r"""
 
@@ -1717,82 +1737,9 @@ class ICloneable(object):
 
 # Register ICloneable in _libBornAgainBase:
 _libBornAgainBase.ICloneable_swigregister(ICloneable)
+cvar = _libBornAgainBase.cvar
+I = cvar.I
 
-
-def mul_I(z):
-    r"""
-    mul_I(complex_t z) -> complex_t
-    complex_t mul_I(complex_t z)
-
-    Returns product I*z, where I is the imaginary unit. 
-
-    """
-    return _libBornAgainBase.mul_I(z)
-
-def exp_I(z):
-    r"""
-    exp_I(complex_t z) -> complex_t
-    complex_t exp_I(complex_t z)
-
-    Returns exp(I*z), where I is the imaginary unit. 
-
-    """
-    return _libBornAgainBase.exp_I(z)
-
-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 StandardNormal(x):
-    r"""StandardNormal(double x) -> double"""
-    return _libBornAgainBase.StandardNormal(x)
-
-def Gaussian(x, average, std_dev):
-    r"""Gaussian(double x, double average, double std_dev) -> double"""
-    return _libBornAgainBase.Gaussian(x, average, std_dev)
-
-def IntegratedGaussian(x, average, std_dev):
-    r"""IntegratedGaussian(double x, double average, double std_dev) -> double"""
-    return _libBornAgainBase.IntegratedGaussian(x, average, std_dev)
-
-def cot(x):
-    r"""cot(double x) -> double"""
-    return _libBornAgainBase.cot(x)
-
-def sinc(*args):
-    r"""
-    sinc(double x) -> double
-    sinc(complex_t const z) -> complex_t
-    """
-    return _libBornAgainBase.sinc(*args)
-
-def tanhc(z):
-    r"""tanhc(complex_t const z) -> complex_t"""
-    return _libBornAgainBase.tanhc(z)
-
-def Laue(x, N):
-    r"""Laue(double const x, size_t N) -> double"""
-    return _libBornAgainBase.Laue(x, N)
-
-def erf(arg):
-    r"""erf(double arg) -> double"""
-    return _libBornAgainBase.erf(arg)
-
-def GeneratePoissonRandom(average):
-    r"""GeneratePoissonRandom(double average) -> double"""
-    return _libBornAgainBase.GeneratePoissonRandom(average)
 class ThreadInfo(object):
     r"""
 
@@ -1820,28 +1767,24 @@ class ThreadInfo(object):
 
 # Register ThreadInfo in _libBornAgainBase:
 _libBornAgainBase.ThreadInfo_swigregister(ThreadInfo)
-cvar = _libBornAgainBase.cvar
-I = cvar.I
-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
 
 
+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
@@ -1887,6 +1830,24 @@ class Bin1D(object):
 
 # Register Bin1D in _libBornAgainBase:
 _libBornAgainBase.Bin1D_swigregister(Bin1D)
+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
 
 
 def BinContains(bin, value):
@@ -2662,7 +2623,7 @@ class kvector_t(object):
         __init__(kvector_t self, double const x1, double const y1, double const z1) -> kvector_t
         BasicVector3D< T >::BasicVector3D(const T x1, const T y1, const T z1)
 
-        Constructor from cartesian components. 
+        Constructs a vector from cartesian components. 
 
         """
         _libBornAgainBase.kvector_t_swiginit(self, _libBornAgainBase.new_kvector_t(*args))
@@ -3059,7 +3020,7 @@ class cvector_t(object):
         __init__(cvector_t self, std::complex< double > const x1, std::complex< double > const y1, std::complex< double > const z1) -> cvector_t
         BasicVector3D< T >::BasicVector3D(const T x1, const T y1, const T z1)
 
-        Constructor from cartesian components. 
+        Constructs a vector from cartesian components. 
 
         """
         _libBornAgainBase.cvector_t_swiginit(self, _libBornAgainBase.new_cvector_t(*args))
diff --git a/auto/Wrap/libBornAgainBase_wrap.cpp b/auto/Wrap/libBornAgainBase_wrap.cpp
index dc63e913963c278c755fcf9115e63bc9fd4f2022..bae9e60e08bfa73c4662619e53a64dba3cce68f7 100644
--- a/auto/Wrap/libBornAgainBase_wrap.cpp
+++ b/auto/Wrap/libBornAgainBase_wrap.cpp
@@ -6652,14 +6652,14 @@ 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/Const/Units.h"
+
 #include "Base/Utils/ThreadInfo.h"
 
+#include "Base/Const/Units.h"
+
 #include "Base/Vector/BasicVector3D.h"
 #include "Base/Vector/Vectors3D.h"
 
-#include "Base/Math/Functions.h"
-
 #include "Base/Axis/Bin.h"
 #include "Base/Axis/ConstKBinAxis.h"
 #include "Base/Axis/CustomBinAxis.h"
@@ -23903,6 +23903,66 @@ SWIGINTERN PyObject *vector_pvacuum_double_t_swiginit(PyObject *SWIGUNUSEDPARM(s
   return SWIG_Python_InitShadowInstance(args);
 }
 
+SWIGINTERN int Swig_var_I_set(PyObject *) {
+  SWIG_Error(SWIG_AttributeError,"Variable I is read-only.");
+  return 1;
+}
+
+
+SWIGINTERN PyObject *Swig_var_I_get(void) {
+  PyObject *pyobj = 0;
+  
+  pyobj = SWIG_From_std_complex_Sl_double_Sg_(static_cast< std::complex<double> >(I));
+  return pyobj;
+}
+
+
+SWIGINTERN PyObject *_wrap_mul_I(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  complex_t arg1 ;
+  std::complex< double > val1 ;
+  int ecode1 = 0 ;
+  PyObject *swig_obj[1] ;
+  complex_t result;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  ecode1 = SWIG_AsVal_std_complex_Sl_double_Sg_(swig_obj[0], &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "mul_I" "', argument " "1"" of type '" "complex_t""'");
+  } 
+  arg1 = static_cast< complex_t >(val1);
+  result = mul_I(arg1);
+  resultobj = SWIG_From_std_complex_Sl_double_Sg_(static_cast< std::complex<double> >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_exp_I(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  complex_t arg1 ;
+  std::complex< double > val1 ;
+  int ecode1 = 0 ;
+  PyObject *swig_obj[1] ;
+  complex_t result;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  ecode1 = SWIG_AsVal_std_complex_Sl_double_Sg_(swig_obj[0], &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "exp_I" "', argument " "1"" of type '" "complex_t""'");
+  } 
+  arg1 = static_cast< complex_t >(val1);
+  result = exp_I(arg1);
+  resultobj = SWIG_From_std_complex_Sl_double_Sg_(static_cast< std::complex<double> >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *_wrap_delete_ICloneable(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   ICloneable *arg1 = (ICloneable *) 0 ;
@@ -23977,83 +24037,225 @@ SWIGINTERN PyObject *ICloneable_swigregister(PyObject *SWIGUNUSEDPARM(self), PyO
   return SWIG_Py_Void();
 }
 
-SWIGINTERN int Swig_var_I_set(PyObject *) {
-  SWIG_Error(SWIG_AttributeError,"Variable I is read-only.");
-  return 1;
+SWIGINTERN PyObject *_wrap_new_ThreadInfo(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  ThreadInfo *result = 0 ;
+  
+  if (!SWIG_Python_UnpackTuple(args, "new_ThreadInfo", 0, 0, 0)) SWIG_fail;
+  result = (ThreadInfo *)new ThreadInfo();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ThreadInfo, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
 }
 
 
-SWIGINTERN PyObject *Swig_var_I_get(void) {
-  PyObject *pyobj = 0;
+SWIGINTERN PyObject *_wrap_ThreadInfo_n_threads_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  ThreadInfo *arg1 = (ThreadInfo *) 0 ;
+  unsigned int arg2 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  unsigned int val2 ;
+  int ecode2 = 0 ;
+  PyObject *swig_obj[2] ;
   
-  pyobj = SWIG_From_std_complex_Sl_double_Sg_(static_cast< std::complex<double> >(I));
-  return pyobj;
+  if (!SWIG_Python_UnpackTuple(args, "ThreadInfo_n_threads_set", 2, 2, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ThreadInfo, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ThreadInfo_n_threads_set" "', argument " "1"" of type '" "ThreadInfo *""'"); 
+  }
+  arg1 = reinterpret_cast< ThreadInfo * >(argp1);
+  ecode2 = SWIG_AsVal_unsigned_SS_int(swig_obj[1], &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ThreadInfo_n_threads_set" "', argument " "2"" of type '" "unsigned int""'");
+  } 
+  arg2 = static_cast< unsigned int >(val2);
+  if (arg1) (arg1)->n_threads = arg2;
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_mul_I(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ThreadInfo_n_threads_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  complex_t arg1 ;
-  std::complex< double > val1 ;
-  int ecode1 = 0 ;
+  ThreadInfo *arg1 = (ThreadInfo *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
   PyObject *swig_obj[1] ;
-  complex_t result;
+  unsigned int result;
   
   if (!args) SWIG_fail;
   swig_obj[0] = args;
-  ecode1 = SWIG_AsVal_std_complex_Sl_double_Sg_(swig_obj[0], &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "mul_I" "', argument " "1"" of type '" "complex_t""'");
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ThreadInfo, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ThreadInfo_n_threads_get" "', argument " "1"" of type '" "ThreadInfo *""'"); 
+  }
+  arg1 = reinterpret_cast< ThreadInfo * >(argp1);
+  result = (unsigned int) ((arg1)->n_threads);
+  resultobj = SWIG_From_unsigned_SS_int(static_cast< unsigned int >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ThreadInfo_n_batches_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  ThreadInfo *arg1 = (ThreadInfo *) 0 ;
+  unsigned int arg2 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  unsigned int val2 ;
+  int ecode2 = 0 ;
+  PyObject *swig_obj[2] ;
+  
+  if (!SWIG_Python_UnpackTuple(args, "ThreadInfo_n_batches_set", 2, 2, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ThreadInfo, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ThreadInfo_n_batches_set" "', argument " "1"" of type '" "ThreadInfo *""'"); 
+  }
+  arg1 = reinterpret_cast< ThreadInfo * >(argp1);
+  ecode2 = SWIG_AsVal_unsigned_SS_int(swig_obj[1], &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ThreadInfo_n_batches_set" "', argument " "2"" of type '" "unsigned int""'");
   } 
-  arg1 = static_cast< complex_t >(val1);
-  result = mul_I(arg1);
-  resultobj = SWIG_From_std_complex_Sl_double_Sg_(static_cast< std::complex<double> >(result));
+  arg2 = static_cast< unsigned int >(val2);
+  if (arg1) (arg1)->n_batches = arg2;
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_exp_I(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ThreadInfo_n_batches_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  complex_t arg1 ;
-  std::complex< double > val1 ;
-  int ecode1 = 0 ;
+  ThreadInfo *arg1 = (ThreadInfo *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
   PyObject *swig_obj[1] ;
-  complex_t result;
+  unsigned int result;
   
   if (!args) SWIG_fail;
   swig_obj[0] = args;
-  ecode1 = SWIG_AsVal_std_complex_Sl_double_Sg_(swig_obj[0], &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "exp_I" "', argument " "1"" of type '" "complex_t""'");
-  } 
-  arg1 = static_cast< complex_t >(val1);
-  result = exp_I(arg1);
-  resultobj = SWIG_From_std_complex_Sl_double_Sg_(static_cast< std::complex<double> >(result));
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ThreadInfo, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ThreadInfo_n_batches_get" "', argument " "1"" of type '" "ThreadInfo *""'"); 
+  }
+  arg1 = reinterpret_cast< ThreadInfo * >(argp1);
+  result = (unsigned int) ((arg1)->n_batches);
+  resultobj = SWIG_From_unsigned_SS_int(static_cast< unsigned int >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN int Swig_var_nanometer_set(PyObject *) {
-  SWIG_Error(SWIG_AttributeError,"Variable nanometer is read-only.");
-  return 1;
+SWIGINTERN PyObject *_wrap_ThreadInfo_current_batch_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  ThreadInfo *arg1 = (ThreadInfo *) 0 ;
+  unsigned int arg2 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  unsigned int val2 ;
+  int ecode2 = 0 ;
+  PyObject *swig_obj[2] ;
+  
+  if (!SWIG_Python_UnpackTuple(args, "ThreadInfo_current_batch_set", 2, 2, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ThreadInfo, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ThreadInfo_current_batch_set" "', argument " "1"" of type '" "ThreadInfo *""'"); 
+  }
+  arg1 = reinterpret_cast< ThreadInfo * >(argp1);
+  ecode2 = SWIG_AsVal_unsigned_SS_int(swig_obj[1], &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ThreadInfo_current_batch_set" "', argument " "2"" of type '" "unsigned int""'");
+  } 
+  arg2 = static_cast< unsigned int >(val2);
+  if (arg1) (arg1)->current_batch = arg2;
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
 }
 
 
-SWIGINTERN PyObject *Swig_var_nanometer_get(void) {
-  PyObject *pyobj = 0;
+SWIGINTERN PyObject *_wrap_ThreadInfo_current_batch_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  ThreadInfo *arg1 = (ThreadInfo *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  unsigned int result;
   
-  pyobj = SWIG_From_double(static_cast< double >(Units::nanometer));
-  return pyobj;
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ThreadInfo, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ThreadInfo_current_batch_get" "', argument " "1"" of type '" "ThreadInfo *""'"); 
+  }
+  arg1 = reinterpret_cast< ThreadInfo * >(argp1);
+  result = (unsigned int) ((arg1)->current_batch);
+  resultobj = SWIG_From_unsigned_SS_int(static_cast< unsigned int >(result));
+  return resultobj;
+fail:
+  return NULL;
 }
 
 
-SWIGINTERN int Swig_var_angstrom_set(PyObject *) {
-  SWIG_Error(SWIG_AttributeError,"Variable angstrom is read-only.");
-  return 1;
+SWIGINTERN PyObject *_wrap_delete_ThreadInfo(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  ThreadInfo *arg1 = (ThreadInfo *) 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_ThreadInfo, SWIG_POINTER_DISOWN |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_ThreadInfo" "', argument " "1"" of type '" "ThreadInfo *""'"); 
+  }
+  arg1 = reinterpret_cast< ThreadInfo * >(argp1);
+  delete arg1;
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *ThreadInfo_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *obj;
+  if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_ThreadInfo, SWIG_NewClientData(obj));
+  return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *ThreadInfo_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  return SWIG_Python_InitShadowInstance(args);
+}
+
+SWIGINTERN int Swig_var_nanometer_set(PyObject *) {
+  SWIG_Error(SWIG_AttributeError,"Variable nanometer is read-only.");
+  return 1;
+}
+
+
+SWIGINTERN PyObject *Swig_var_nanometer_get(void) {
+  PyObject *pyobj = 0;
+  
+  pyobj = SWIG_From_double(static_cast< double >(Units::nanometer));
+  return pyobj;
+}
+
+
+SWIGINTERN int Swig_var_angstrom_set(PyObject *) {
+  SWIG_Error(SWIG_AttributeError,"Variable angstrom is read-only.");
+  return 1;
 }
 
 
@@ -24212,632 +24414,129 @@ SWIGINTERN PyObject *_wrap_rad2deg(PyObject *SWIGUNUSEDPARM(self), PyObject *arg
   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;
-}
-
-
-SWIGINTERN PyObject *Swig_var_rad_get(void) {
-  PyObject *pyobj = 0;
-  
-  pyobj = SWIG_From_double(static_cast< double >(Units::rad));
-  return pyobj;
-}
-
-
-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;
-}
-
-
-SWIGINTERN PyObject *Swig_var_deg_get(void) {
-  PyObject *pyobj = 0;
-  
-  pyobj = SWIG_From_double(static_cast< double >(Units::deg));
-  return pyobj;
-}
-
-
-SWIGINTERN int Swig_var_tesla_set(PyObject *) {
-  SWIG_Error(SWIG_AttributeError,"Variable tesla is read-only.");
-  return 1;
-}
-
-
-SWIGINTERN PyObject *Swig_var_tesla_get(void) {
-  PyObject *pyobj = 0;
-  
-  pyobj = SWIG_From_double(static_cast< double >(Units::tesla));
-  return pyobj;
-}
-
-
-SWIGINTERN int Swig_var_gauss_set(PyObject *) {
-  SWIG_Error(SWIG_AttributeError,"Variable gauss is read-only.");
-  return 1;
-}
-
-
-SWIGINTERN PyObject *Swig_var_gauss_get(void) {
-  PyObject *pyobj = 0;
-  
-  pyobj = SWIG_From_double(static_cast< double >(Units::gauss));
-  return pyobj;
-}
-
-
-SWIGINTERN PyObject *_wrap_StandardNormal(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 '" "StandardNormal" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  result = (double)Math::StandardNormal(arg1);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_Gaussian(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  double arg1 ;
-  double arg2 ;
-  double arg3 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
-  PyObject *swig_obj[3] ;
-  double result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "Gaussian", 3, 3, swig_obj)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(swig_obj[0], &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "Gaussian" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Gaussian" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(swig_obj[2], &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Gaussian" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  result = (double)Math::Gaussian(arg1,arg2,arg3);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IntegratedGaussian(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  double arg1 ;
-  double arg2 ;
-  double arg3 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
-  PyObject *swig_obj[3] ;
-  double result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "IntegratedGaussian", 3, 3, swig_obj)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(swig_obj[0], &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "IntegratedGaussian" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntegratedGaussian" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(swig_obj[2], &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntegratedGaussian" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  result = (double)Math::IntegratedGaussian(arg1,arg2,arg3);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_cot(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  double arg1 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  PyObject *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 '" "cot" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  result = (double)Math::cot(arg1);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_sinc__SWIG_0(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
-  PyObject *resultobj = 0;
-  double arg1 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  double result;
-  
-  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 '" "sinc" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  result = (double)Math::sinc(arg1);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_sinc__SWIG_1(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) {
-  PyObject *resultobj = 0;
-  complex_t arg1 ;
-  std::complex< double > val1 ;
-  int ecode1 = 0 ;
-  complex_t result;
-  
-  if ((nobjs < 1) || (nobjs > 1)) SWIG_fail;
-  ecode1 = SWIG_AsVal_std_complex_Sl_double_Sg_(swig_obj[0], &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "sinc" "', argument " "1"" of type '" "complex_t""'");
-  } 
-  arg1 = static_cast< complex_t >(val1);
-  result = Math::sinc(arg1);
-  resultobj = SWIG_From_std_complex_Sl_double_Sg_(static_cast< std::complex<double> >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_sinc(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[2] = {
-    0
-  };
-  
-  if (!(argc = SWIG_Python_UnpackTuple(args, "sinc", 0, 1, argv))) SWIG_fail;
-  --argc;
-  if (argc == 1) {
-    int _v;
-    {
-      int res = SWIG_AsVal_double(argv[0], NULL);
-      _v = SWIG_CheckState(res);
-    }
-    if (_v) {
-      return _wrap_sinc__SWIG_0(self, argc, argv);
-    }
-  }
-  if (argc == 1) {
-    int _v;
-    {
-      int res = SWIG_AsVal_std_complex_Sl_double_Sg_(argv[0], NULL);
-      _v = SWIG_CheckState(res);
-    }
-    if (_v) {
-      return _wrap_sinc__SWIG_1(self, argc, argv);
-    }
-  }
-  
-fail:
-  SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'sinc'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    Math::sinc(double)\n"
-    "    Math::sinc(complex_t const)\n");
-  return 0;
-}
-
-
-SWIGINTERN PyObject *_wrap_tanhc(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  complex_t arg1 ;
-  std::complex< double > val1 ;
-  int ecode1 = 0 ;
-  PyObject *swig_obj[1] ;
-  complex_t result;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  ecode1 = SWIG_AsVal_std_complex_Sl_double_Sg_(swig_obj[0], &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "tanhc" "', argument " "1"" of type '" "complex_t""'");
-  } 
-  arg1 = static_cast< complex_t >(val1);
-  result = Math::tanhc(arg1);
-  resultobj = SWIG_From_std_complex_Sl_double_Sg_(static_cast< std::complex<double> >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_Laue(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  double arg1 ;
-  size_t arg2 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  size_t val2 ;
-  int ecode2 = 0 ;
-  PyObject *swig_obj[2] ;
-  double result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "Laue", 2, 2, swig_obj)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(swig_obj[0], &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "Laue" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Laue" "', argument " "2"" of type '" "size_t""'");
-  } 
-  arg2 = static_cast< size_t >(val2);
-  result = (double)Math::Laue(arg1,arg2);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_erf(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 '" "erf" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  result = (double)Math::erf(arg1);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_GeneratePoissonRandom(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 '" "GeneratePoissonRandom" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  result = (double)Math::GeneratePoissonRandom(arg1);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_ThreadInfo(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  ThreadInfo *result = 0 ;
-  
-  if (!SWIG_Python_UnpackTuple(args, "new_ThreadInfo", 0, 0, 0)) SWIG_fail;
-  result = (ThreadInfo *)new ThreadInfo();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ThreadInfo, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_ThreadInfo_n_threads_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  ThreadInfo *arg1 = (ThreadInfo *) 0 ;
-  unsigned int arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  unsigned int val2 ;
-  int ecode2 = 0 ;
-  PyObject *swig_obj[2] ;
-  
-  if (!SWIG_Python_UnpackTuple(args, "ThreadInfo_n_threads_set", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ThreadInfo, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ThreadInfo_n_threads_set" "', argument " "1"" of type '" "ThreadInfo *""'"); 
-  }
-  arg1 = reinterpret_cast< ThreadInfo * >(argp1);
-  ecode2 = SWIG_AsVal_unsigned_SS_int(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ThreadInfo_n_threads_set" "', argument " "2"" of type '" "unsigned int""'");
+  
+  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""'");
   } 
-  arg2 = static_cast< unsigned int >(val2);
-  if (arg1) (arg1)->n_threads = arg2;
-  resultobj = SWIG_Py_Void();
+  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_ThreadInfo_n_threads_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_deg2rad(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  ThreadInfo *arg1 = (ThreadInfo *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
+  double arg1 ;
+  double val1 ;
+  int ecode1 = 0 ;
   PyObject *swig_obj[1] ;
-  unsigned int result;
+  double result;
   
   if (!args) SWIG_fail;
   swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ThreadInfo, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ThreadInfo_n_threads_get" "', argument " "1"" of type '" "ThreadInfo *""'"); 
-  }
-  arg1 = reinterpret_cast< ThreadInfo * >(argp1);
-  result = (unsigned int) ((arg1)->n_threads);
-  resultobj = SWIG_From_unsigned_SS_int(static_cast< unsigned int >(result));
+  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 PyObject *_wrap_ThreadInfo_n_batches_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  ThreadInfo *arg1 = (ThreadInfo *) 0 ;
-  unsigned int arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  unsigned int val2 ;
-  int ecode2 = 0 ;
-  PyObject *swig_obj[2] ;
+SWIGINTERN int Swig_var_rad_set(PyObject *) {
+  SWIG_Error(SWIG_AttributeError,"Variable rad is read-only.");
+  return 1;
+}
+
+
+SWIGINTERN PyObject *Swig_var_rad_get(void) {
+  PyObject *pyobj = 0;
   
-  if (!SWIG_Python_UnpackTuple(args, "ThreadInfo_n_batches_set", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ThreadInfo, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ThreadInfo_n_batches_set" "', argument " "1"" of type '" "ThreadInfo *""'"); 
-  }
-  arg1 = reinterpret_cast< ThreadInfo * >(argp1);
-  ecode2 = SWIG_AsVal_unsigned_SS_int(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ThreadInfo_n_batches_set" "', argument " "2"" of type '" "unsigned int""'");
-  } 
-  arg2 = static_cast< unsigned int >(val2);
-  if (arg1) (arg1)->n_batches = arg2;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
+  pyobj = SWIG_From_double(static_cast< double >(Units::rad));
+  return pyobj;
 }
 
 
-SWIGINTERN PyObject *_wrap_ThreadInfo_n_batches_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  ThreadInfo *arg1 = (ThreadInfo *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  unsigned int result;
+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;
   
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ThreadInfo, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ThreadInfo_n_batches_get" "', argument " "1"" of type '" "ThreadInfo *""'"); 
-  }
-  arg1 = reinterpret_cast< ThreadInfo * >(argp1);
-  result = (unsigned int) ((arg1)->n_batches);
-  resultobj = SWIG_From_unsigned_SS_int(static_cast< unsigned int >(result));
-  return resultobj;
-fail:
-  return NULL;
+  pyobj = SWIG_From_double(static_cast< double >(Units::mrad));
+  return pyobj;
 }
 
 
-SWIGINTERN PyObject *_wrap_ThreadInfo_current_batch_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  ThreadInfo *arg1 = (ThreadInfo *) 0 ;
-  unsigned int arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  unsigned int val2 ;
-  int ecode2 = 0 ;
-  PyObject *swig_obj[2] ;
+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;
   
-  if (!SWIG_Python_UnpackTuple(args, "ThreadInfo_current_batch_set", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ThreadInfo, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ThreadInfo_current_batch_set" "', argument " "1"" of type '" "ThreadInfo *""'"); 
-  }
-  arg1 = reinterpret_cast< ThreadInfo * >(argp1);
-  ecode2 = SWIG_AsVal_unsigned_SS_int(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ThreadInfo_current_batch_set" "', argument " "2"" of type '" "unsigned int""'");
-  } 
-  arg2 = static_cast< unsigned int >(val2);
-  if (arg1) (arg1)->current_batch = arg2;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
+  pyobj = SWIG_From_double(static_cast< double >(Units::sr));
+  return pyobj;
 }
 
 
-SWIGINTERN PyObject *_wrap_ThreadInfo_current_batch_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  ThreadInfo *arg1 = (ThreadInfo *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  unsigned int result;
+SWIGINTERN int Swig_var_deg_set(PyObject *) {
+  SWIG_Error(SWIG_AttributeError,"Variable deg is read-only.");
+  return 1;
+}
+
+
+SWIGINTERN PyObject *Swig_var_deg_get(void) {
+  PyObject *pyobj = 0;
   
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ThreadInfo, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ThreadInfo_current_batch_get" "', argument " "1"" of type '" "ThreadInfo *""'"); 
-  }
-  arg1 = reinterpret_cast< ThreadInfo * >(argp1);
-  result = (unsigned int) ((arg1)->current_batch);
-  resultobj = SWIG_From_unsigned_SS_int(static_cast< unsigned int >(result));
-  return resultobj;
-fail:
-  return NULL;
+  pyobj = SWIG_From_double(static_cast< double >(Units::deg));
+  return pyobj;
 }
 
 
-SWIGINTERN PyObject *_wrap_delete_ThreadInfo(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  ThreadInfo *arg1 = (ThreadInfo *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
+SWIGINTERN int Swig_var_tesla_set(PyObject *) {
+  SWIG_Error(SWIG_AttributeError,"Variable tesla is read-only.");
+  return 1;
+}
+
+
+SWIGINTERN PyObject *Swig_var_tesla_get(void) {
+  PyObject *pyobj = 0;
   
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ThreadInfo, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_ThreadInfo" "', argument " "1"" of type '" "ThreadInfo *""'"); 
-  }
-  arg1 = reinterpret_cast< ThreadInfo * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
+  pyobj = SWIG_From_double(static_cast< double >(Units::tesla));
+  return pyobj;
 }
 
 
-SWIGINTERN PyObject *ThreadInfo_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_ThreadInfo, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
+SWIGINTERN int Swig_var_gauss_set(PyObject *) {
+  SWIG_Error(SWIG_AttributeError,"Variable gauss is read-only.");
+  return 1;
 }
 
-SWIGINTERN PyObject *ThreadInfo_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  return SWIG_Python_InitShadowInstance(args);
+
+SWIGINTERN PyObject *Swig_var_gauss_get(void) {
+  PyObject *pyobj = 0;
+  
+  pyobj = SWIG_From_double(static_cast< double >(Units::gauss));
+  return pyobj;
 }
 
+
 SWIGINTERN PyObject *_wrap_vecOfLambdaAlphaPhi(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   double arg1 ;
@@ -33121,24 +32820,6 @@ static PyMethodDef SwigMethods[] = {
 	 { "delete_vector_pvacuum_double_t", _wrap_delete_vector_pvacuum_double_t, METH_O, "delete_vector_pvacuum_double_t(vector_pvacuum_double_t self)"},
 	 { "vector_pvacuum_double_t_swigregister", vector_pvacuum_double_t_swigregister, METH_O, NULL},
 	 { "vector_pvacuum_double_t_swiginit", vector_pvacuum_double_t_swiginit, METH_VARARGS, NULL},
-	 { "delete_ICloneable", _wrap_delete_ICloneable, METH_O, "\n"
-		"delete_ICloneable(ICloneable self)\n"
-		"virtual ICloneable::~ICloneable()=default\n"
-		"\n"
-		""},
-	 { "ICloneable_clone", _wrap_ICloneable_clone, METH_O, "\n"
-		"ICloneable_clone(ICloneable self) -> ICloneable\n"
-		"virtual ICloneable* ICloneable::clone() const =0\n"
-		"\n"
-		""},
-	 { "ICloneable_transferToCPP", _wrap_ICloneable_transferToCPP, METH_O, "\n"
-		"ICloneable_transferToCPP(ICloneable self)\n"
-		"virtual void ICloneable::transferToCPP()\n"
-		"\n"
-		"Used for Python overriding of clone (see swig/tweaks.py) \n"
-		"\n"
-		""},
-	 { "ICloneable_swigregister", ICloneable_swigregister, METH_O, NULL},
 	 { "mul_I", _wrap_mul_I, METH_O, "\n"
 		"mul_I(complex_t z) -> complex_t\n"
 		"complex_t mul_I(complex_t z)\n"
@@ -33153,28 +32834,24 @@ static PyMethodDef SwigMethods[] = {
 		"Returns exp(I*z), where I is the imaginary unit. \n"
 		"\n"
 		""},
-	 { "rad2deg", _wrap_rad2deg, METH_O, "\n"
-		"rad2deg(double angle) -> double\n"
-		"double Units::rad2deg(double angle)\n"
+	 { "delete_ICloneable", _wrap_delete_ICloneable, METH_O, "\n"
+		"delete_ICloneable(ICloneable self)\n"
+		"virtual ICloneable::~ICloneable()=default\n"
 		"\n"
 		""},
-	 { "deg2rad", _wrap_deg2rad, METH_O, "\n"
-		"deg2rad(double angle) -> double\n"
-		"double Units::deg2rad(double angle)\n"
+	 { "ICloneable_clone", _wrap_ICloneable_clone, METH_O, "\n"
+		"ICloneable_clone(ICloneable self) -> ICloneable\n"
+		"virtual ICloneable* ICloneable::clone() const =0\n"
 		"\n"
 		""},
-	 { "StandardNormal", _wrap_StandardNormal, METH_O, "StandardNormal(double x) -> double"},
-	 { "Gaussian", _wrap_Gaussian, METH_VARARGS, "Gaussian(double x, double average, double std_dev) -> double"},
-	 { "IntegratedGaussian", _wrap_IntegratedGaussian, METH_VARARGS, "IntegratedGaussian(double x, double average, double std_dev) -> double"},
-	 { "cot", _wrap_cot, METH_O, "cot(double x) -> double"},
-	 { "sinc", _wrap_sinc, METH_VARARGS, "\n"
-		"sinc(double x) -> double\n"
-		"sinc(complex_t const z) -> complex_t\n"
+	 { "ICloneable_transferToCPP", _wrap_ICloneable_transferToCPP, METH_O, "\n"
+		"ICloneable_transferToCPP(ICloneable self)\n"
+		"virtual void ICloneable::transferToCPP()\n"
+		"\n"
+		"Used for Python overriding of clone (see swig/tweaks.py) \n"
+		"\n"
 		""},
-	 { "tanhc", _wrap_tanhc, METH_O, "tanhc(complex_t const z) -> complex_t"},
-	 { "Laue", _wrap_Laue, METH_VARARGS, "Laue(double const x, size_t N) -> double"},
-	 { "erf", _wrap_erf, METH_O, "erf(double arg) -> double"},
-	 { "GeneratePoissonRandom", _wrap_GeneratePoissonRandom, METH_O, "GeneratePoissonRandom(double average) -> double"},
+	 { "ICloneable_swigregister", ICloneable_swigregister, METH_O, NULL},
 	 { "new_ThreadInfo", _wrap_new_ThreadInfo, METH_NOARGS, "\n"
 		"new_ThreadInfo() -> ThreadInfo\n"
 		"ThreadInfo::ThreadInfo()\n"
@@ -33189,6 +32866,16 @@ 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"
 		"BasicVector3D<double> vecOfLambdaAlphaPhi(double _lambda, double _alpha, double _phi)\n"
@@ -33706,7 +33393,7 @@ static PyMethodDef SwigMethods[] = {
 		"new_kvector_t(double const x1, double const y1, double const z1) -> kvector_t\n"
 		"BasicVector3D< T >::BasicVector3D(const T x1, const T y1, const T z1)\n"
 		"\n"
-		"Constructor from cartesian components. \n"
+		"Constructs a vector from cartesian components. \n"
 		"\n"
 		""},
 	 { "kvector_t_x", _wrap_kvector_t_x, METH_O, "\n"
@@ -33915,7 +33602,7 @@ static PyMethodDef SwigMethods[] = {
 		"new_cvector_t(std::complex< double > const x1, std::complex< double > const y1, std::complex< double > const z1) -> cvector_t\n"
 		"BasicVector3D< T >::BasicVector3D(const T x1, const T y1, const T z1)\n"
 		"\n"
-		"Constructor from cartesian components. \n"
+		"Constructs a vector from cartesian components. \n"
 		"\n"
 		""},
 	 { "cvector_t_x", _wrap_cvector_t_x, METH_O, "\n"
diff --git a/auto/Wrap/libBornAgainCore.py b/auto/Wrap/libBornAgainCore.py
index e87d9628e8b73a38c7d6f8ae6975977ff3d00278..b389485397684c3155d6e6c0684ad04a906c1374 100644
--- a/auto/Wrap/libBornAgainCore.py
+++ b/auto/Wrap/libBornAgainCore.py
@@ -2718,36 +2718,6 @@ class swig_dummy_type_const_inode_vector(object):
 # Register swig_dummy_type_const_inode_vector in _libBornAgainCore:
 _libBornAgainCore.swig_dummy_type_const_inode_vector_swigregister(swig_dummy_type_const_inode_vector)
 
-class SimulationFactoryTemp(object):
-    r"""Proxy of C++ IFactory< std::string,ISimulation > class."""
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def createItem(self, item_key):
-        r"""createItem(SimulationFactoryTemp self, std::string const & item_key) -> ISimulation"""
-        return _libBornAgainCore.SimulationFactoryTemp_createItem(self, item_key)
-
-    def registerItem(self, item_key, CreateFn):
-        r"""registerItem(SimulationFactoryTemp self, std::string const & item_key, IFactory< std::string,ISimulation >::CreateItemCallback CreateFn) -> bool"""
-        return _libBornAgainCore.SimulationFactoryTemp_registerItem(self, item_key, CreateFn)
-
-    def contains(self, item_key):
-        r"""contains(SimulationFactoryTemp self, std::string const & item_key) -> bool"""
-        return _libBornAgainCore.SimulationFactoryTemp_contains(self, item_key)
-
-    def size(self):
-        r"""size(SimulationFactoryTemp self) -> size_t"""
-        return _libBornAgainCore.SimulationFactoryTemp_size(self)
-
-    def __init__(self):
-        r"""__init__(SimulationFactoryTemp self) -> SimulationFactoryTemp"""
-        _libBornAgainCore.SimulationFactoryTemp_swiginit(self, _libBornAgainCore.new_SimulationFactoryTemp())
-    __swig_destroy__ = _libBornAgainCore.delete_SimulationFactoryTemp
-
-# Register SimulationFactoryTemp in _libBornAgainCore:
-_libBornAgainCore.SimulationFactoryTemp_swigregister(SimulationFactoryTemp)
-
 class FitObjective(object):
     r"""
 
@@ -4460,31 +4430,6 @@ class PoissonNoiseBackground(IBackground):
 # Register PoissonNoiseBackground in _libBornAgainCore:
 _libBornAgainCore.PoissonNoiseBackground_swigregister(PoissonNoiseBackground)
 
-class SimulationFactory(SimulationFactoryTemp):
-    r"""
-
-
-    Registry to create standard pre-defined simulations. Used in functional tests, performance measurements, etc.
-
-    C++ includes: SimulationFactory.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):
-        r"""
-        __init__(SimulationFactory self) -> SimulationFactory
-        SimulationFactory::SimulationFactory()
-
-        """
-        _libBornAgainCore.SimulationFactory_swiginit(self, _libBornAgainCore.new_SimulationFactory())
-    __swig_destroy__ = _libBornAgainCore.delete_SimulationFactory
-
-# Register SimulationFactory in _libBornAgainCore:
-_libBornAgainCore.SimulationFactory_swigregister(SimulationFactory)
-
 
 def generateSampleCode(multilayer):
     r"""
diff --git a/auto/Wrap/libBornAgainCore_wrap.cpp b/auto/Wrap/libBornAgainCore_wrap.cpp
index 539dcf5f17a4d9a1a5009472037b6c45ecb4fb2c..adb3ba4ba5f40b463269a0ce46f354665eab4e1b 100644
--- a/auto/Wrap/libBornAgainCore_wrap.cpp
+++ b/auto/Wrap/libBornAgainCore_wrap.cpp
@@ -3102,113 +3102,108 @@ namespace Swig {
 #define SWIGTYPE_p_BasicVector3DT_double_t swig_types[2]
 #define SWIGTYPE_p_BasicVector3DT_int_t swig_types[3]
 #define SWIGTYPE_p_BasicVector3DT_std__complexT_double_t_t swig_types[4]
-#define SWIGTYPE_p_CallbackMap_t swig_types[5]
-#define SWIGTYPE_p_ConstantBackground swig_types[6]
-#define SWIGTYPE_p_CreateItemCallback 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_IDetector2D swig_types[18]
-#define SWIGTYPE_p_IDistribution1D swig_types[19]
-#define SWIGTYPE_p_IFactoryT_std__string_ISimulation_t swig_types[20]
-#define SWIGTYPE_p_IFootprintFactor swig_types[21]
-#define SWIGTYPE_p_IFormFactor swig_types[22]
-#define SWIGTYPE_p_INode swig_types[23]
-#define SWIGTYPE_p_INodeVisitor swig_types[24]
-#define SWIGTYPE_p_IObservable swig_types[25]
-#define SWIGTYPE_p_IObserver swig_types[26]
-#define SWIGTYPE_p_IParametricComponent swig_types[27]
-#define SWIGTYPE_p_IRangedDistribution swig_types[28]
-#define SWIGTYPE_p_IResolutionFunction2D swig_types[29]
-#define SWIGTYPE_p_ISampleNode swig_types[30]
-#define SWIGTYPE_p_IShape2D swig_types[31]
-#define SWIGTYPE_p_ISimulation swig_types[32]
-#define SWIGTYPE_p_ISimulation2D swig_types[33]
-#define SWIGTYPE_p_ISpecularScan swig_types[34]
-#define SWIGTYPE_p_Instrument swig_types[35]
-#define SWIGTYPE_p_IterationInfo swig_types[36]
-#define SWIGTYPE_p_MultiLayer swig_types[37]
-#define SWIGTYPE_p_OffSpecSimulation 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_PoissonNoiseBackground swig_types[42]
-#define SWIGTYPE_p_ProgressHandler__Callback_t swig_types[43]
-#define SWIGTYPE_p_PyBuilderCallback swig_types[44]
-#define SWIGTYPE_p_PyObserverCallback swig_types[45]
-#define SWIGTYPE_p_QSpecScan swig_types[46]
-#define SWIGTYPE_p_RealLimits swig_types[47]
-#define SWIGTYPE_p_ScanResolution swig_types[48]
-#define SWIGTYPE_p_SimulationFactory swig_types[49]
-#define SWIGTYPE_p_SimulationOptions swig_types[50]
-#define SWIGTYPE_p_SimulationResult swig_types[51]
-#define SWIGTYPE_p_SpecularSimulation swig_types[52]
-#define SWIGTYPE_p_allocator_type swig_types[53]
-#define SWIGTYPE_p_char swig_types[54]
-#define SWIGTYPE_p_difference_type swig_types[55]
-#define SWIGTYPE_p_first_type swig_types[56]
-#define SWIGTYPE_p_int swig_types[57]
-#define SWIGTYPE_p_key_type swig_types[58]
-#define SWIGTYPE_p_long_long swig_types[59]
-#define SWIGTYPE_p_mapped_type swig_types[60]
-#define SWIGTYPE_p_mumufit__MinimizerResult swig_types[61]
-#define SWIGTYPE_p_mumufit__Parameters swig_types[62]
-#define SWIGTYPE_p_observer_t swig_types[63]
-#define SWIGTYPE_p_p_PyObject swig_types[64]
-#define SWIGTYPE_p_second_type swig_types[65]
-#define SWIGTYPE_p_short swig_types[66]
-#define SWIGTYPE_p_signed_char swig_types[67]
-#define SWIGTYPE_p_size_type swig_types[68]
-#define SWIGTYPE_p_std__allocatorT_AxisInfo_t swig_types[69]
-#define SWIGTYPE_p_std__allocatorT_BasicVector3DT_double_t_t swig_types[70]
-#define SWIGTYPE_p_std__allocatorT_BasicVector3DT_std__complexT_double_t_t_t swig_types[71]
-#define SWIGTYPE_p_std__allocatorT_INode_const_p_t swig_types[72]
-#define SWIGTYPE_p_std__allocatorT_INode_p_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_ISimulation_pfF_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_std__string_double_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_double_t_t_t swig_types[87]
-#define SWIGTYPE_p_std__pairT_double_double_t swig_types[88]
-#define SWIGTYPE_p_std__shared_ptrT_IObserver_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 SWIGTYPE_p_ConstantBackground swig_types[5]
+#define SWIGTYPE_p_DepthProbeSimulation swig_types[6]
+#define SWIGTYPE_p_DistributionHandler swig_types[7]
+#define SWIGTYPE_p_FitObjective swig_types[8]
+#define SWIGTYPE_p_GISASSimulation swig_types[9]
+#define SWIGTYPE_p_IAxis swig_types[10]
+#define SWIGTYPE_p_IBackground swig_types[11]
+#define SWIGTYPE_p_IBornFF swig_types[12]
+#define SWIGTYPE_p_IChiSquaredModule swig_types[13]
+#define SWIGTYPE_p_ICloneable swig_types[14]
+#define SWIGTYPE_p_IComponent swig_types[15]
+#define SWIGTYPE_p_IDetector2D swig_types[16]
+#define SWIGTYPE_p_IDistribution1D swig_types[17]
+#define SWIGTYPE_p_IFootprintFactor swig_types[18]
+#define SWIGTYPE_p_IFormFactor swig_types[19]
+#define SWIGTYPE_p_INode swig_types[20]
+#define SWIGTYPE_p_INodeVisitor swig_types[21]
+#define SWIGTYPE_p_IObservable swig_types[22]
+#define SWIGTYPE_p_IObserver swig_types[23]
+#define SWIGTYPE_p_IParametricComponent swig_types[24]
+#define SWIGTYPE_p_IRangedDistribution swig_types[25]
+#define SWIGTYPE_p_IResolutionFunction2D swig_types[26]
+#define SWIGTYPE_p_ISampleNode swig_types[27]
+#define SWIGTYPE_p_IShape2D swig_types[28]
+#define SWIGTYPE_p_ISimulation swig_types[29]
+#define SWIGTYPE_p_ISimulation2D swig_types[30]
+#define SWIGTYPE_p_ISpecularScan swig_types[31]
+#define SWIGTYPE_p_Instrument swig_types[32]
+#define SWIGTYPE_p_IterationInfo swig_types[33]
+#define SWIGTYPE_p_MultiLayer swig_types[34]
+#define SWIGTYPE_p_OffSpecSimulation swig_types[35]
+#define SWIGTYPE_p_OutputDataT_double_t swig_types[36]
+#define SWIGTYPE_p_ParameterDistribution swig_types[37]
+#define SWIGTYPE_p_ParameterPool swig_types[38]
+#define SWIGTYPE_p_PoissonNoiseBackground swig_types[39]
+#define SWIGTYPE_p_ProgressHandler__Callback_t swig_types[40]
+#define SWIGTYPE_p_PyBuilderCallback swig_types[41]
+#define SWIGTYPE_p_PyObserverCallback swig_types[42]
+#define SWIGTYPE_p_QSpecScan swig_types[43]
+#define SWIGTYPE_p_RealLimits swig_types[44]
+#define SWIGTYPE_p_ScanResolution swig_types[45]
+#define SWIGTYPE_p_SimulationOptions swig_types[46]
+#define SWIGTYPE_p_SimulationResult swig_types[47]
+#define SWIGTYPE_p_SpecularSimulation swig_types[48]
+#define SWIGTYPE_p_allocator_type swig_types[49]
+#define SWIGTYPE_p_char swig_types[50]
+#define SWIGTYPE_p_difference_type swig_types[51]
+#define SWIGTYPE_p_first_type swig_types[52]
+#define SWIGTYPE_p_int swig_types[53]
+#define SWIGTYPE_p_key_type swig_types[54]
+#define SWIGTYPE_p_long_long swig_types[55]
+#define SWIGTYPE_p_mapped_type swig_types[56]
+#define SWIGTYPE_p_mumufit__MinimizerResult swig_types[57]
+#define SWIGTYPE_p_mumufit__Parameters swig_types[58]
+#define SWIGTYPE_p_observer_t swig_types[59]
+#define SWIGTYPE_p_p_PyObject swig_types[60]
+#define SWIGTYPE_p_second_type swig_types[61]
+#define SWIGTYPE_p_short swig_types[62]
+#define SWIGTYPE_p_signed_char swig_types[63]
+#define SWIGTYPE_p_size_type swig_types[64]
+#define SWIGTYPE_p_std__allocatorT_AxisInfo_t swig_types[65]
+#define SWIGTYPE_p_std__allocatorT_BasicVector3DT_double_t_t swig_types[66]
+#define SWIGTYPE_p_std__allocatorT_BasicVector3DT_std__complexT_double_t_t_t swig_types[67]
+#define SWIGTYPE_p_std__allocatorT_INode_const_p_t swig_types[68]
+#define SWIGTYPE_p_std__allocatorT_INode_p_t swig_types[69]
+#define SWIGTYPE_p_std__allocatorT_double_t swig_types[70]
+#define SWIGTYPE_p_std__allocatorT_int_t swig_types[71]
+#define SWIGTYPE_p_std__allocatorT_std__complexT_double_t_t swig_types[72]
+#define SWIGTYPE_p_std__allocatorT_std__pairT_double_double_t_t swig_types[73]
+#define SWIGTYPE_p_std__allocatorT_std__pairT_std__string_const_double_t_t swig_types[74]
+#define SWIGTYPE_p_std__allocatorT_std__string_t swig_types[75]
+#define SWIGTYPE_p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t swig_types[76]
+#define SWIGTYPE_p_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t swig_types[77]
+#define SWIGTYPE_p_std__allocatorT_unsigned_long_t swig_types[78]
+#define SWIGTYPE_p_std__complexT_double_t swig_types[79]
+#define SWIGTYPE_p_std__invalid_argument swig_types[80]
+#define SWIGTYPE_p_std__lessT_std__string_t swig_types[81]
+#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[82]
+#define SWIGTYPE_p_std__pairT_double_double_t swig_types[83]
+#define SWIGTYPE_p_std__shared_ptrT_IObserver_t swig_types[84]
+#define SWIGTYPE_p_std__shared_ptrT_ISampleBuilder_t swig_types[85]
+#define SWIGTYPE_p_std__vectorT_AxisInfo_std__allocatorT_AxisInfo_t_t swig_types[86]
+#define SWIGTYPE_p_std__vectorT_BasicVector3DT_double_t_std__allocatorT_BasicVector3DT_double_t_t_t swig_types[87]
+#define SWIGTYPE_p_std__vectorT_BasicVector3DT_std__complexT_double_t_t_std__allocatorT_BasicVector3DT_std__complexT_double_t_t_t_t swig_types[88]
+#define SWIGTYPE_p_std__vectorT_INode_const_p_std__allocatorT_INode_const_p_t_t swig_types[89]
+#define SWIGTYPE_p_std__vectorT_INode_p_std__allocatorT_INode_p_t_t swig_types[90]
+#define SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t swig_types[91]
+#define SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t swig_types[92]
+#define SWIGTYPE_p_std__vectorT_std__complexT_double_t_std__allocatorT_std__complexT_double_t_t_t swig_types[93]
+#define SWIGTYPE_p_std__vectorT_std__pairT_double_double_t_std__allocatorT_std__pairT_double_double_t_t_t swig_types[94]
+#define SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t swig_types[95]
+#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[96]
+#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[97]
+#define SWIGTYPE_p_std__vectorT_unsigned_long_std__allocatorT_unsigned_long_t_t swig_types[98]
+#define SWIGTYPE_p_swig__SwigPyIterator swig_types[99]
+#define SWIGTYPE_p_unsigned_char swig_types[100]
+#define SWIGTYPE_p_unsigned_int swig_types[101]
+#define SWIGTYPE_p_unsigned_long_long swig_types[102]
+#define SWIGTYPE_p_unsigned_short swig_types[103]
+#define SWIGTYPE_p_value_type swig_types[104]
+static swig_type_info *swig_types[106];
+static swig_module_info swig_module = {swig_types, 105, 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)
 
@@ -34891,202 +34886,6 @@ SWIGINTERN PyObject *swig_dummy_type_const_inode_vector_swiginit(PyObject *SWIGU
   return SWIG_Python_InitShadowInstance(args);
 }
 
-SWIGINTERN PyObject *_wrap_SimulationFactoryTemp_createItem(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IFactory< std::string,ISimulation > *arg1 = (IFactory< std::string,ISimulation > *) 0 ;
-  std::string *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
-  PyObject *swig_obj[2] ;
-  ISimulation *result = 0 ;
-  
-  if (!SWIG_Python_UnpackTuple(args, "SimulationFactoryTemp_createItem", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IFactoryT_std__string_ISimulation_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SimulationFactoryTemp_createItem" "', argument " "1"" of type '" "IFactory< std::string,ISimulation > const *""'"); 
-  }
-  arg1 = reinterpret_cast< IFactory< std::string,ISimulation > * >(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 '" "SimulationFactoryTemp_createItem" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "SimulationFactoryTemp_createItem" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    arg2 = ptr;
-  }
-  result = (ISimulation *)((IFactory< std::string,ISimulation > const *)arg1)->createItem((std::string const &)*arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ISimulation, 0 |  0 );
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_SimulationFactoryTemp_registerItem(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IFactory< std::string,ISimulation > *arg1 = (IFactory< std::string,ISimulation > *) 0 ;
-  std::string *arg2 = 0 ;
-  SwigValueWrapper< std::function< ISimulation *() > > arg3 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
-  void *argp3 ;
-  int res3 = 0 ;
-  PyObject *swig_obj[3] ;
-  bool result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "SimulationFactoryTemp_registerItem", 3, 3, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IFactoryT_std__string_ISimulation_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SimulationFactoryTemp_registerItem" "', argument " "1"" of type '" "IFactory< std::string,ISimulation > *""'"); 
-  }
-  arg1 = reinterpret_cast< IFactory< std::string,ISimulation > * >(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 '" "SimulationFactoryTemp_registerItem" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "SimulationFactoryTemp_registerItem" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    arg2 = ptr;
-  }
-  {
-    res3 = SWIG_ConvertPtr(swig_obj[2], &argp3, SWIGTYPE_p_std__functionT_ISimulation_pfF_t,  0  | 0);
-    if (!SWIG_IsOK(res3)) {
-      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "SimulationFactoryTemp_registerItem" "', argument " "3"" of type '" "IFactory< std::string,ISimulation >::CreateItemCallback""'"); 
-    }  
-    if (!argp3) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "SimulationFactoryTemp_registerItem" "', argument " "3"" of type '" "IFactory< std::string,ISimulation >::CreateItemCallback""'");
-    } else {
-      IFactory< std::string,ISimulation >::CreateItemCallback * temp = reinterpret_cast< IFactory< std::string,ISimulation >::CreateItemCallback * >(argp3);
-      arg3 = *temp;
-      if (SWIG_IsNewObj(res3)) delete temp;
-    }
-  }
-  result = (bool)(arg1)->registerItem((std::string const &)*arg2,arg3);
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_SimulationFactoryTemp_contains(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IFactory< std::string,ISimulation > *arg1 = (IFactory< std::string,ISimulation > *) 0 ;
-  std::string *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
-  PyObject *swig_obj[2] ;
-  bool result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "SimulationFactoryTemp_contains", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IFactoryT_std__string_ISimulation_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SimulationFactoryTemp_contains" "', argument " "1"" of type '" "IFactory< std::string,ISimulation > const *""'"); 
-  }
-  arg1 = reinterpret_cast< IFactory< std::string,ISimulation > * >(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 '" "SimulationFactoryTemp_contains" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "SimulationFactoryTemp_contains" "', argument " "2"" of type '" "std::string const &""'"); 
-    }
-    arg2 = ptr;
-  }
-  result = (bool)((IFactory< std::string,ISimulation > const *)arg1)->contains((std::string const &)*arg2);
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_SimulationFactoryTemp_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IFactory< std::string,ISimulation > *arg1 = (IFactory< std::string,ISimulation > *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  size_t result;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IFactoryT_std__string_ISimulation_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SimulationFactoryTemp_size" "', argument " "1"" of type '" "IFactory< std::string,ISimulation > const *""'"); 
-  }
-  arg1 = reinterpret_cast< IFactory< std::string,ISimulation > * >(argp1);
-  result = ((IFactory< std::string,ISimulation > const *)arg1)->size();
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_SimulationFactoryTemp(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IFactory< std::string,ISimulation > *result = 0 ;
-  
-  if (!SWIG_Python_UnpackTuple(args, "new_SimulationFactoryTemp", 0, 0, 0)) SWIG_fail;
-  result = (IFactory< std::string,ISimulation > *)new IFactory< std::string,ISimulation >();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IFactoryT_std__string_ISimulation_t, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_delete_SimulationFactoryTemp(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IFactory< std::string,ISimulation > *arg1 = (IFactory< std::string,ISimulation > *) 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_IFactoryT_std__string_ISimulation_t, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SimulationFactoryTemp" "', argument " "1"" of type '" "IFactory< std::string,ISimulation > *""'"); 
-  }
-  arg1 = reinterpret_cast< IFactory< std::string,ISimulation > * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *SimulationFactoryTemp_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_IFactoryT_std__string_ISimulation_t, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *SimulationFactoryTemp_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  return SWIG_Python_InitShadowInstance(args);
-}
-
 SWIGINTERN PyObject *_wrap_new_FitObjective(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   PyObject *arg1 = (PyObject *) 0 ;
@@ -42275,52 +42074,6 @@ SWIGINTERN PyObject *PoissonNoiseBackground_swiginit(PyObject *SWIGUNUSEDPARM(se
   return SWIG_Python_InitShadowInstance(args);
 }
 
-SWIGINTERN PyObject *_wrap_new_SimulationFactory(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  SimulationFactory *result = 0 ;
-  
-  if (!SWIG_Python_UnpackTuple(args, "new_SimulationFactory", 0, 0, 0)) SWIG_fail;
-  result = (SimulationFactory *)new SimulationFactory();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_SimulationFactory, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_delete_SimulationFactory(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  SimulationFactory *arg1 = (SimulationFactory *) 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_SimulationFactory, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SimulationFactory" "', argument " "1"" of type '" "SimulationFactory *""'"); 
-  }
-  arg1 = reinterpret_cast< SimulationFactory * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *SimulationFactory_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_SimulationFactory, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *SimulationFactory_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  return SWIG_Python_InitShadowInstance(args);
-}
-
 SWIGINTERN PyObject *_wrap_generateSampleCode(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   MultiLayer *arg1 = 0 ;
@@ -43314,14 +43067,6 @@ static PyMethodDef SwigMethods[] = {
 	 { "delete_swig_dummy_type_const_inode_vector", _wrap_delete_swig_dummy_type_const_inode_vector, METH_O, "delete_swig_dummy_type_const_inode_vector(swig_dummy_type_const_inode_vector self)"},
 	 { "swig_dummy_type_const_inode_vector_swigregister", swig_dummy_type_const_inode_vector_swigregister, METH_O, NULL},
 	 { "swig_dummy_type_const_inode_vector_swiginit", swig_dummy_type_const_inode_vector_swiginit, METH_VARARGS, NULL},
-	 { "SimulationFactoryTemp_createItem", _wrap_SimulationFactoryTemp_createItem, METH_VARARGS, "SimulationFactoryTemp_createItem(SimulationFactoryTemp self, std::string const & item_key) -> ISimulation"},
-	 { "SimulationFactoryTemp_registerItem", _wrap_SimulationFactoryTemp_registerItem, METH_VARARGS, "SimulationFactoryTemp_registerItem(SimulationFactoryTemp self, std::string const & item_key, IFactory< std::string,ISimulation >::CreateItemCallback CreateFn) -> bool"},
-	 { "SimulationFactoryTemp_contains", _wrap_SimulationFactoryTemp_contains, METH_VARARGS, "SimulationFactoryTemp_contains(SimulationFactoryTemp self, std::string const & item_key) -> bool"},
-	 { "SimulationFactoryTemp_size", _wrap_SimulationFactoryTemp_size, METH_O, "SimulationFactoryTemp_size(SimulationFactoryTemp self) -> size_t"},
-	 { "new_SimulationFactoryTemp", _wrap_new_SimulationFactoryTemp, METH_NOARGS, "new_SimulationFactoryTemp() -> SimulationFactoryTemp"},
-	 { "delete_SimulationFactoryTemp", _wrap_delete_SimulationFactoryTemp, METH_O, "delete_SimulationFactoryTemp(SimulationFactoryTemp self)"},
-	 { "SimulationFactoryTemp_swigregister", SimulationFactoryTemp_swigregister, METH_O, NULL},
-	 { "SimulationFactoryTemp_swiginit", SimulationFactoryTemp_swiginit, METH_VARARGS, NULL},
 	 { "new_FitObjective", _wrap_new_FitObjective, METH_O, "\n"
 		"new_FitObjective(PyObject * _self) -> FitObjective\n"
 		"FitObjective::FitObjective()\n"
@@ -44301,14 +44046,6 @@ static PyMethodDef SwigMethods[] = {
 	 { "delete_PoissonNoiseBackground", _wrap_delete_PoissonNoiseBackground, METH_O, "delete_PoissonNoiseBackground(PoissonNoiseBackground self)"},
 	 { "PoissonNoiseBackground_swigregister", PoissonNoiseBackground_swigregister, METH_O, NULL},
 	 { "PoissonNoiseBackground_swiginit", PoissonNoiseBackground_swiginit, METH_VARARGS, NULL},
-	 { "new_SimulationFactory", _wrap_new_SimulationFactory, METH_NOARGS, "\n"
-		"new_SimulationFactory() -> SimulationFactory\n"
-		"SimulationFactory::SimulationFactory()\n"
-		"\n"
-		""},
-	 { "delete_SimulationFactory", _wrap_delete_SimulationFactory, METH_O, "delete_SimulationFactory(SimulationFactory self)"},
-	 { "SimulationFactory_swigregister", SimulationFactory_swigregister, METH_O, NULL},
-	 { "SimulationFactory_swiginit", SimulationFactory_swiginit, METH_VARARGS, NULL},
 	 { "generateSampleCode", _wrap_generateSampleCode, METH_O, "\n"
 		"generateSampleCode(MultiLayer const & multilayer) -> std::string\n"
 		"std::string ExportToPython::generateSampleCode(const MultiLayer &multilayer)\n"
@@ -44335,9 +44072,6 @@ 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_SimulationFactoryTo_p_IFactoryT_std__string_ISimulation_t(void *x, int *SWIGUNUSEDPARM(newmemory)) {
-    return (void *)((IFactory< std::string,ISimulation > *)  ((SimulationFactory *) x));
-}
 static void *_p_ISimulation2DTo_p_ISimulation(void *x, int *SWIGUNUSEDPARM(newmemory)) {
     return (void *)((ISimulation *)  ((ISimulation2D *) x));
 }
@@ -44541,9 +44275,7 @@ static swig_type_info _swigt__p_AxisInfo = {"_p_AxisInfo", "std::vector< AxisInf
 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_CallbackMap_t = {"_p_CallbackMap_t", "CallbackMap_t *", 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_CreateItemCallback = {"_p_CreateItemCallback", "CreateItemCallback *", 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};
 static swig_type_info _swigt__p_FitObjective = {"_p_FitObjective", "FitObjective *", 0, 0, (void*)0, 0};
@@ -44559,7 +44291,6 @@ static swig_type_info _swigt__p_ISampleNode = {"_p_ISampleNode", 0, 0, 0, 0, 0};
 static swig_type_info _swigt__p_IComponent = {"_p_IComponent", "IComponent *", 0, 0, (void*)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_IFactoryT_std__string_ISimulation_t = {"_p_IFactoryT_std__string_ISimulation_t", "IFactory< std::string,ISimulation > *", 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_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};
@@ -44585,7 +44316,6 @@ static swig_type_info _swigt__p_PyObserverCallback = {"_p_PyObserverCallback", "
 static swig_type_info _swigt__p_QSpecScan = {"_p_QSpecScan", "QSpecScan *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_RealLimits = {"_p_RealLimits", "RealLimits *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_ScanResolution = {"_p_ScanResolution", "ScanResolution *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_SimulationFactory = {"_p_SimulationFactory", "SimulationFactory *", 0, 0, (void*)0, 0};
 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};
@@ -44620,7 +44350,6 @@ static swig_type_info _swigt__p_std__allocatorT_std__vectorT_double_std__allocat
 static swig_type_info _swigt__p_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t = {"_p_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t", "std::vector< std::vector< int > >::allocator_type *|std::allocator< std::vector< int,std::allocator< int > > > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__allocatorT_unsigned_long_t = {"_p_std__allocatorT_unsigned_long_t", "std::vector< unsigned long >::allocator_type *|std::allocator< unsigned long > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__complexT_double_t = {"_p_std__complexT_double_t", "complex_t *|std::complex< double > *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__functionT_ISimulation_pfF_t = {"_p_std__functionT_ISimulation_pfF_t", "IFactory< std::string,ISimulation >::CreateItemCallback *|std::function< ISimulation *() > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__invalid_argument = {"_p_std__invalid_argument", "std::invalid_argument *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__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};
@@ -44653,9 +44382,7 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_BasicVector3DT_double_t,
   &_swigt__p_BasicVector3DT_int_t,
   &_swigt__p_BasicVector3DT_std__complexT_double_t_t,
-  &_swigt__p_CallbackMap_t,
   &_swigt__p_ConstantBackground,
-  &_swigt__p_CreateItemCallback,
   &_swigt__p_DepthProbeSimulation,
   &_swigt__p_DistributionHandler,
   &_swigt__p_FitObjective,
@@ -44668,7 +44395,6 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_IComponent,
   &_swigt__p_IDetector2D,
   &_swigt__p_IDistribution1D,
-  &_swigt__p_IFactoryT_std__string_ISimulation_t,
   &_swigt__p_IFootprintFactor,
   &_swigt__p_IFormFactor,
   &_swigt__p_INode,
@@ -44697,7 +44423,6 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_QSpecScan,
   &_swigt__p_RealLimits,
   &_swigt__p_ScanResolution,
-  &_swigt__p_SimulationFactory,
   &_swigt__p_SimulationOptions,
   &_swigt__p_SimulationResult,
   &_swigt__p_SpecularSimulation,
@@ -44732,7 +44457,6 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t,
   &_swigt__p_std__allocatorT_unsigned_long_t,
   &_swigt__p_std__complexT_double_t,
-  &_swigt__p_std__functionT_ISimulation_pfF_t,
   &_swigt__p_std__invalid_argument,
   &_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,
@@ -44765,9 +44489,7 @@ static swig_cast_info _swigc__p_AxisInfo[] = {  {&_swigt__p_AxisInfo, 0, 0, 0},{
 static swig_cast_info _swigc__p_BasicVector3DT_double_t[] = {  {&_swigt__p_BasicVector3DT_double_t, 0, 0, 0},{0, 0, 0, 0}};
 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_CallbackMap_t[] = {  {&_swigt__p_CallbackMap_t, 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_CreateItemCallback[] = {  {&_swigt__p_CreateItemCallback, 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}};
 static swig_cast_info _swigc__p_FitObjective[] = {  {&_swigt__p_FitObjective, 0, 0, 0},{0, 0, 0, 0}};
@@ -44783,7 +44505,6 @@ static swig_cast_info _swigc__p_ICloneable[] = {  {&_swigt__p_IFormFactor, _p_IF
 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_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_IFactoryT_std__string_ISimulation_t[] = {  {&_swigt__p_SimulationFactory, _p_SimulationFactoryTo_p_IFactoryT_std__string_ISimulation_t, 0, 0},  {&_swigt__p_IFactoryT_std__string_ISimulation_t, 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_INodeVisitor[] = {  {&_swigt__p_INodeVisitor, 0, 0, 0},{0, 0, 0, 0}};
@@ -44809,7 +44530,6 @@ static swig_cast_info _swigc__p_PyObserverCallback[] = {  {&_swigt__p_PyObserver
 static swig_cast_info _swigc__p_QSpecScan[] = {  {&_swigt__p_QSpecScan, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_RealLimits[] = {  {&_swigt__p_RealLimits, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_ScanResolution[] = {  {&_swigt__p_ScanResolution, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_SimulationFactory[] = {  {&_swigt__p_SimulationFactory, 0, 0, 0},{0, 0, 0, 0}};
 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}};
@@ -44844,7 +44564,6 @@ static swig_cast_info _swigc__p_std__allocatorT_std__vectorT_double_std__allocat
 static swig_cast_info _swigc__p_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t[] = {  {&_swigt__p_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__allocatorT_unsigned_long_t[] = {  {&_swigt__p_std__allocatorT_unsigned_long_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__complexT_double_t[] = {  {&_swigt__p_std__complexT_double_t, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__functionT_ISimulation_pfF_t[] = {  {&_swigt__p_std__functionT_ISimulation_pfF_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__invalid_argument[] = {  {&_swigt__p_std__invalid_argument, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__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}};
@@ -44877,9 +44596,7 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_BasicVector3DT_double_t,
   _swigc__p_BasicVector3DT_int_t,
   _swigc__p_BasicVector3DT_std__complexT_double_t_t,
-  _swigc__p_CallbackMap_t,
   _swigc__p_ConstantBackground,
-  _swigc__p_CreateItemCallback,
   _swigc__p_DepthProbeSimulation,
   _swigc__p_DistributionHandler,
   _swigc__p_FitObjective,
@@ -44892,7 +44609,6 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_IComponent,
   _swigc__p_IDetector2D,
   _swigc__p_IDistribution1D,
-  _swigc__p_IFactoryT_std__string_ISimulation_t,
   _swigc__p_IFootprintFactor,
   _swigc__p_IFormFactor,
   _swigc__p_INode,
@@ -44921,7 +44637,6 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_QSpecScan,
   _swigc__p_RealLimits,
   _swigc__p_ScanResolution,
-  _swigc__p_SimulationFactory,
   _swigc__p_SimulationOptions,
   _swigc__p_SimulationResult,
   _swigc__p_SpecularSimulation,
@@ -44956,7 +44671,6 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t,
   _swigc__p_std__allocatorT_unsigned_long_t,
   _swigc__p_std__complexT_double_t,
-  _swigc__p_std__functionT_ISimulation_pfF_t,
   _swigc__p_std__invalid_argument,
   _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,
diff --git a/auto/Wrap/libBornAgainParam.py b/auto/Wrap/libBornAgainParam.py
index 1bf00b64cc8e7f21a3e5f2710d78e345afe9683a..ccd5a62b6833e3e358e852330bdd8c104d177508 100644
--- a/auto/Wrap/libBornAgainParam.py
+++ b/auto/Wrap/libBornAgainParam.py
@@ -3247,11 +3247,21 @@ class INode(IParametricComponent):
         getChildren(INode self) -> swig_dummy_type_const_inode_vector
         std::vector< const INode * > INode::getChildren() const
 
-        Returns a vector of children (const). 
+        Returns a vector of children. 
 
         """
         return _libBornAgainParam.INode_getChildren(self)
 
+    def progeny(self):
+        r"""
+        progeny(INode self) -> swig_dummy_type_const_inode_vector
+        std::vector< const INode * > INode::progeny() const
+
+        Returns a vector of all descendents. 
+
+        """
+        return _libBornAgainParam.INode_progeny(self)
+
     def setParent(self, newParent):
         r"""
         setParent(INode self, INode newParent)
@@ -3481,14 +3491,6 @@ class INodeVisitor(object):
 # Register INodeVisitor in _libBornAgainParam:
 _libBornAgainParam.INodeVisitor_swigregister(INodeVisitor)
 
-
-def VisitNodesPreorder(node, visitor):
-    r"""
-    VisitNodesPreorder(INode node, INodeVisitor visitor)
-    void VisitNodesPreorder(const INode &node, INodeVisitor &visitor)
-
-    """
-    return _libBornAgainParam.VisitNodesPreorder(node, visitor)
 class IDistribution1D(libBornAgainBase.ICloneable, INode):
     r"""
 
diff --git a/auto/Wrap/libBornAgainParam_wrap.cpp b/auto/Wrap/libBornAgainParam_wrap.cpp
index ca4017f249469cd092b384df6277ca2f13788167..52e2a6cca627deb63db10d156a8ffa3774db2037 100644
--- a/auto/Wrap/libBornAgainParam_wrap.cpp
+++ b/auto/Wrap/libBornAgainParam_wrap.cpp
@@ -36685,6 +36685,29 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_INode_progeny(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  INode *arg1 = (INode *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  std::vector< INode const *,std::allocator< INode const * > > result;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_INode, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "INode_progeny" "', argument " "1"" of type '" "INode const *""'"); 
+  }
+  arg1 = reinterpret_cast< INode * >(argp1);
+  result = ((INode const *)arg1)->progeny();
+  resultobj = swig::from(static_cast< std::vector< INode const*,std::allocator< INode const * > > >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *_wrap_INode_setParent(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   INode *arg1 = (INode *) 0 ;
@@ -42263,41 +42286,6 @@ SWIGINTERN PyObject *INodeVisitor_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObj
   return SWIG_Python_InitShadowInstance(args);
 }
 
-SWIGINTERN PyObject *_wrap_VisitNodesPreorder(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  INode *arg1 = 0 ;
-  INodeVisitor *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject *swig_obj[2] ;
-  
-  if (!SWIG_Python_UnpackTuple(args, "VisitNodesPreorder", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_INode,  0  | 0);
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VisitNodesPreorder" "', argument " "1"" of type '" "INode const &""'"); 
-  }
-  if (!argp1) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VisitNodesPreorder" "', argument " "1"" of type '" "INode const &""'"); 
-  }
-  arg1 = reinterpret_cast< INode * >(argp1);
-  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_INodeVisitor,  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VisitNodesPreorder" "', argument " "2"" of type '" "INodeVisitor &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VisitNodesPreorder" "', argument " "2"" of type '" "INodeVisitor &""'"); 
-  }
-  arg2 = reinterpret_cast< INodeVisitor * >(argp2);
-  VisitNodesPreorder((INode const &)*arg1,*arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_IDistribution1D_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   IDistribution1D *arg1 = (IDistribution1D *) 0 ;
@@ -51236,7 +51224,14 @@ static PyMethodDef SwigMethods[] = {
 		"INode_getChildren(INode self) -> swig_dummy_type_const_inode_vector\n"
 		"std::vector< const INode * > INode::getChildren() const\n"
 		"\n"
-		"Returns a vector of children (const). \n"
+		"Returns a vector of children. \n"
+		"\n"
+		""},
+	 { "INode_progeny", _wrap_INode_progeny, METH_O, "\n"
+		"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"
 		"\n"
 		""},
 	 { "INode_setParent", _wrap_INode_setParent, METH_VARARGS, "\n"
@@ -51425,11 +51420,6 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { "INodeVisitor_swigregister", INodeVisitor_swigregister, METH_O, NULL},
 	 { "INodeVisitor_swiginit", INodeVisitor_swiginit, METH_VARARGS, NULL},
-	 { "VisitNodesPreorder", _wrap_VisitNodesPreorder, METH_VARARGS, "\n"
-		"VisitNodesPreorder(INode node, INodeVisitor visitor)\n"
-		"void VisitNodesPreorder(const INode &node, INodeVisitor &visitor)\n"
-		"\n"
-		""},
 	 { "IDistribution1D_clone", _wrap_IDistribution1D_clone, METH_O, "\n"
 		"IDistribution1D_clone(IDistribution1D self) -> IDistribution1D\n"
 		"virtual IDistribution1D* IDistribution1D::clone() const =0\n"
diff --git a/cmake/BornAgain/PackDebian.cmake b/cmake/BornAgain/PackDebian.cmake
index 87db9ff4d47ccd0fc0a249d38af7375b9c826495..1d8f3df54823e19a997e7eced730137830d59a48 100644
--- a/cmake/BornAgain/PackDebian.cmake
+++ b/cmake/BornAgain/PackDebian.cmake
@@ -24,10 +24,6 @@ set(CPACK_DEBIAN_PACKAGE_PRIORITY optional)
 set(CPACK_DEBIAN_PACKAGE_SECTION devel)
 set(CPACK_STRIP_FILES TRUE)
 
-#From the BornAgain webpage: set(CPACK_DEBIAN_PACKAGE_DEPENDS "build-essential, git, cmake(>=3.1), libgsl-dev(>=1.15), libboost-all-dev(>=1.48), libfftw3-dev(>=3.3.1), python3, python3-dev, python3-numpy, python3-matplotlib, libtiff5-dev(>=4.0.2), qt5-default(>=5.4), libqt5designercomponents5, qttools5-dev, libqt5svg5-dev")
-
-#Version Specific Dependencies: set(CPACK_DEBIAN_PACKAGE_DEPENDS "libgsl-dev(>=1.15), libboost-program-options${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}, libboost-iostreams${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}, libboost-regex${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}, libfftw3-3(>=3.3.1), python3, python3-numpy, python3-matplotlib, libqt5widgets5(>=5.4), libtiffxx5(>=4.0.2)")
-
 #Version-free dependencies:
 set(CPACK_DEBIAN_PACKAGE_DEPENDS "libgsl-dev(>=1.15), libboost-all-dev, libfftw3-3(>=3.3.1), python3, python3-numpy, python3-matplotlib, libqt5widgets5(>=5.4), libtiffxx5(>=4.0.2)")
 
diff --git a/devtools/architecture/ParameterDistribution.md b/devtools/architecture/ParameterDistribution.md
new file mode 100644
index 0000000000000000000000000000000000000000..dd175699a18cf5d77c23a51d7b362827baa8fd44
--- /dev/null
+++ b/devtools/architecture/ParameterDistribution.md
@@ -0,0 +1,117 @@
+## Parameter distributions
+
+Analysis of BornAgain develop, per 3dec20.
+
+It seems there are two different ways for handling parameter distributions,
+the one specifically for particle distributions, the other one more generic.
+
+### Particle distribution
+
+#### Typical use
+
+Typical use of parameter distributions is described in
+`Examples/Python/sim01_Particles/CylindersWithSizeDistribution.py`:
+```
+def get_sample():
+    # Define materials and form factor ...
+
+    # Define particles
+    particle = ba.Particle(material_Particle, ff)
+
+    # Define particles with parameter following a distribution
+    distr_1 = ba.DistributionGaussian(5.0*nm, 1.0*nm)
+    par_distr_1 = ba.ParameterDistribution(
+        "/Particle/Cylinder/Radius", distr_1, 100, 2.0)
+    particle_distrib = ba.ParticleDistribution(particle, par_distr_1)
+
+    # Define particle layouts
+    layout = ba.ParticleLayout()
+    layout.addParticle(particle_distrib, 1.0)
+
+    # Define layers
+    layer = ba.Layer(material_Vacuum)
+    layer.addLayout(layout)
+
+    # Define sample
+    sample = ba.MultiLayer()
+    sample.addLayer(layer)
+
+    return sample
+
+
+def get_simulation():
+    simulation = ba.GISASSimulation()
+    simulation.setDetectorParameters(200, 0.0*deg, 2.0*deg, 200, 0.0*deg, 2.0*deg)
+    simulation.setBeamParameters(1.0*angstrom, 0.2*deg, 0.0*deg)
+    return simulation
+
+
+def run_simulation():
+    simulation = get_simulation()
+    simulation.setSample(get_sample())
+    simulation.runSimulation()
+    return simulation.result()
+```
+
+#### What goes on behind the scenes?
+
+Class hierarchy:
+```
+IParametricComponent
+- INode
+  - ISampleNode
+    - IAbstractParticle
+      - ParticleDistribution (final)
+      - IParticle
+        - Particle (final)
+        - ParticleCoreShell (final)
+        ... (all final)
+- ISampleBuilder
+- DistributionHandler (final)
+- ParameterDistribution (final)
+```
+
+As we see from the `CylindersWithSizeDistribution` example,
+a `ParticleDistribution` is bound to a `ParticleLayout`.
+The drawing of `IParticle`s from the distribution happens here:
+
+```
+SafePointerVector<IParticle> ParticleLayout::particles() const {
+    SafePointerVector<IParticle> particle_vector;
+    for (const auto* particle : m_particles) {
+        if (const auto* p_part_distr = dynamic_cast<const ParticleDistribution*>(particle)) {
+            SafePointerVector<IParticle> generated_particles = p_part_distr->generateParticles();
+            for (const IParticle* particle : generated_particles)
+                particle_vector.push_back(particle->clone());
+        } else if (const auto* p_iparticle = dynamic_cast<const IParticle*>(particle)) {
+            particle_vector.push_back(p_iparticle->clone());
+        }
+    }
+    return particle_vector;
+}
+```
+
+### Generic distribution handler
+
+This mechanism acts almost on top of the simulation model hierarchy.
+
+`ISimulation` has member `DistributionHandler m_distribution_handler`.
+It is modified through `ISimulation::addParameterDistribution`.
+This function is called explicitly by some standard simulations and Python scripts
+(e.g. `sim03_Structures/Interference2DLatticeSumOfRotated.py`),
+but not in the above simple example.
+
+
+```
+void ISimulation::runSimulation() {
+    ...
+    size_t param_combinations = m_distribution_handler.getTotalNumberOfSamples();
+    std::unique_ptr<ParameterPool> param_pool(createParameterTree());
+    for (size_t index = 0; index < param_combinations; ++index) {
+        double weight = m_distribution_handler.setParameterValues(param_pool.get(), index);
+        runSingleSimulation(batch_start, batch_size, weight);
+    }
+    m_distribution_handler.setParameterToMeans(param_pool.get());
+    ...
+}
+```
diff --git a/devtools/architecture/Scattering.md b/devtools/architecture/Scattering.md
index 93b1972538ccc1f8b48c07fe1dddb5beac5f1305..c352a07d71a7faa46b72f945202e14b0171dbe9e 100644
--- a/devtools/architecture/Scattering.md
+++ b/devtools/architecture/Scattering.md
@@ -1,6 +1,7 @@
 ## How does BornAgain compute scattering?
 
-Code analysis per 18nov, after merge of https://github.com/scgmlz/BornAgain/pull/1105.
+Analysis of BornAgain develop, per 18nov,
+after merge of https://github.com/scgmlz/BornAgain/pull/1105.
 
 ### Simulation computes an incoherent sum