diff --git a/Core/Beam/Beam.cpp b/Core/Beam/Beam.cpp
index 1aa5d416c3f000dc1e02972adaab0369fb553fd8..1fd821b77177f6ab45271969b8c745a26d386461 100644
--- a/Core/Beam/Beam.cpp
+++ b/Core/Beam/Beam.cpp
@@ -20,6 +20,9 @@
 #include "RealParameter.h"
 #include "MathConstants.h"
 
+// Allow for 90 degrees by adding a relatively small constant to pi/2
+static constexpr double INCLINATION_LIMIT = M_PI_2 + 1e-10;
+
 Beam::Beam()
     : m_wavelength(1.0), m_alpha(0.0), m_phi(0.0)
     , m_intensity(1.0)
@@ -131,7 +134,7 @@ void Beam::init_parameters()
     registerParameter(BornAgain::Wavelength, &m_wavelength).setUnit(BornAgain::UnitsNm)
         .setNonnegative();
     registerParameter(BornAgain::Inclination, &m_alpha).setUnit(BornAgain::UnitsRad)
-        .setLimited(0, M_PI_2);
+        .setLimited(0, INCLINATION_LIMIT);
     registerParameter(BornAgain::Azimuth, &m_phi).setUnit(BornAgain::UnitsRad)
         .setLimited(-M_PI_2, M_PI_2);
     registerVector(BornAgain::BlochVector, &m_bloch_vector, BornAgain::UnitsNone);
diff --git a/Core/Multilayer/DecouplingApproximationStrategy.cpp b/Core/Multilayer/DecouplingApproximationStrategy.cpp
index a5a9b30f27dc00beae0ef8dc7de393a4ffb9e157..e990d865fa2053ef84669f1c611bc2a1296e1e2a 100644
--- a/Core/Multilayer/DecouplingApproximationStrategy.cpp
+++ b/Core/Multilayer/DecouplingApproximationStrategy.cpp
@@ -16,10 +16,14 @@
 #include "Exceptions.h"
 #include "FormFactorCoherentSum.h"
 #include "IInterferenceFunction.h"
+#include "InterferenceFunctionUtils.h"
 #include "MathFunctions.h"
 #include "RealParameter.h"
 #include "SimulationElement.h"
 
+using InterferenceFunctionUtils::PrecomputeScalarFormFactors;
+using InterferenceFunctionUtils::PrecomputePolarizedFormFactors;
+
 DecouplingApproximationStrategy::DecouplingApproximationStrategy(
         SimulationOptions sim_params, bool polarized)
     : IInterferenceFunctionStrategy(sim_params, polarized)
@@ -33,7 +37,7 @@ double DecouplingApproximationStrategy::scalarCalculation(
 {
     double intensity = 0.0;
     complex_t amplitude = complex_t(0.0, 0.0);
-    auto precomputed_ff = precomputeScalar(sim_element, m_formfactor_wrappers);
+    auto precomputed_ff = PrecomputeScalarFormFactors(sim_element, m_formfactor_wrappers);
     for (size_t i = 0; i < m_formfactor_wrappers.size(); ++i) {
         complex_t ff = precomputed_ff[i];
         if (std::isnan(ff.real()))
@@ -55,7 +59,7 @@ double DecouplingApproximationStrategy::polarizedCalculation(
     Eigen::Matrix2cd mean_intensity = Eigen::Matrix2cd::Zero();
     Eigen::Matrix2cd mean_amplitude = Eigen::Matrix2cd::Zero();
 
-    auto precomputed_ff = precomputePolarized(sim_element, m_formfactor_wrappers);
+    auto precomputed_ff = PrecomputePolarizedFormFactors(sim_element, m_formfactor_wrappers);
     const auto& polarization_handler = sim_element.polarizationHandler();
     for (size_t i = 0; i < m_formfactor_wrappers.size(); ++i) {
         Eigen::Matrix2cd ff = precomputed_ff[i];
diff --git a/Core/Multilayer/DecouplingApproximationStrategy.h b/Core/Multilayer/DecouplingApproximationStrategy.h
index cf749542baa3e56c761453ae2bc2c486cb3486e9..e38be51ab7ab607a649a475a5245f5c3ee1aa165 100644
--- a/Core/Multilayer/DecouplingApproximationStrategy.h
+++ b/Core/Multilayer/DecouplingApproximationStrategy.h
@@ -28,7 +28,7 @@ class DecouplingApproximationStrategy final : public IInterferenceFunctionStrate
 public:
     DecouplingApproximationStrategy(SimulationOptions sim_params, bool polarized);
 
-protected:
+private:
     double scalarCalculation(const SimulationElement& sim_element) const override;
     double polarizedCalculation(const SimulationElement& sim_element) const override;
 };
diff --git a/Core/Multilayer/IInterferenceFunctionStrategy.cpp b/Core/Multilayer/IInterferenceFunctionStrategy.cpp
index d3e69444669109825deebc9cf5fb24fd3b738da3..4df607d648472e085bc8fe3d442cf5184702a8d5 100644
--- a/Core/Multilayer/IInterferenceFunctionStrategy.cpp
+++ b/Core/Multilayer/IInterferenceFunctionStrategy.cpp
@@ -34,10 +34,8 @@ IInterferenceFunctionStrategy::IInterferenceFunctionStrategy(const SimulationOpt
         this, &IInterferenceFunctionStrategy::evaluate_for_fixed_angles, 2) )
 {}
 
-IInterferenceFunctionStrategy::~IInterferenceFunctionStrategy()
-{} // needs class definitions => don't move to .h
+IInterferenceFunctionStrategy::~IInterferenceFunctionStrategy() =default;
 
-//! Initializes the object with form factors and interference functions
 void IInterferenceFunctionStrategy::init(
     const SafePointerVector<FormFactorCoherentSum>& weighted_formfactors,
     const IInterferenceFunction* p_iff)
@@ -61,29 +59,6 @@ double IInterferenceFunctionStrategy::evaluate(const SimulationElement& sim_elem
     return evaluateSinglePoint(sim_element);
 }
 
-std::vector<complex_t> IInterferenceFunctionStrategy::precomputeScalar(
-        const SimulationElement& sim_element,
-        const SafePointerVector<FormFactorCoherentSum>& ff_wrappers)
-{
-    std::vector<complex_t> result;
-    for (auto ffw: ff_wrappers) {
-        result.push_back(ffw->evaluate(sim_element));
-    }
-    return result;
-}
-
-IInterferenceFunctionStrategy::matrixFFVector_t
-IInterferenceFunctionStrategy::precomputePolarized(
-        const SimulationElement& sim_element,
-        const SafePointerVector<FormFactorCoherentSum>& ff_wrappers)
-{
-    matrixFFVector_t result;
-    for (auto ffw: ff_wrappers) {
-        result.push_back(ffw->evaluatePol(sim_element));
-    }
-    return result;
-}
-
 double IInterferenceFunctionStrategy::evaluateSinglePoint(
         const SimulationElement& sim_element) const
 {
@@ -114,3 +89,6 @@ double IInterferenceFunctionStrategy::evaluate_for_fixed_angles(
     SimulationElement sim_element(*pars, par0, par1);
     return pars->getIntegrationFactor(par0, par1) * evaluateSinglePoint(sim_element);
 }
+
+void IInterferenceFunctionStrategy::strategy_specific_post_init()
+{}
diff --git a/Core/Multilayer/IInterferenceFunctionStrategy.h b/Core/Multilayer/IInterferenceFunctionStrategy.h
index 494c5cb6202b4df9076288c4508811b38d90bc97..bd7d03f373b82b330ebad2baa7ea20f407f39090 100644
--- a/Core/Multilayer/IInterferenceFunctionStrategy.h
+++ b/Core/Multilayer/IInterferenceFunctionStrategy.h
@@ -19,7 +19,6 @@
 #include "SafePointerVector.h"
 #include "SimulationOptions.h"
 #include "Vectors3D.h"
-#include <Eigen/StdVector>
 #include <memory>
 #include <vector>
 
@@ -46,12 +45,10 @@ class SimulationElement;
 class BA_CORE_API_ IInterferenceFunctionStrategy
 {
 public:
-    typedef std::vector<Eigen::Matrix2cd, Eigen::aligned_allocator<Eigen::Matrix2cd>>
-        matrixFFVector_t;
-
     IInterferenceFunctionStrategy(const SimulationOptions& sim_params, bool polarized);
     virtual ~IInterferenceFunctionStrategy();
 
+    //! Initializes the object with form factors and an interference function
     void init(const SafePointerVector<FormFactorCoherentSum>& weighted_formfactors,
               const IInterferenceFunction* p_iff);
 
@@ -59,17 +56,6 @@ public:
     double evaluate(const SimulationElement& sim_element) const;
 
 protected:
-    virtual void strategy_specific_post_init() {}
-    static std::vector<complex_t> precomputeScalar(const SimulationElement& sim_element,
-            const SafePointerVector<FormFactorCoherentSum>& ff_wrappers);
-    static matrixFFVector_t precomputePolarized(const SimulationElement& sim_element,
-            const SafePointerVector<FormFactorCoherentSum>& ff_wrappers);
-
-    //! Evaluates the intensity in the scalar case
-    virtual double scalarCalculation(const SimulationElement& sim_element) const =0;
-    //! Evaluates the intensity in the polarized case
-    virtual double polarizedCalculation(const SimulationElement& sim_element) const =0;
-
     SafePointerVector<FormFactorCoherentSum> m_formfactor_wrappers;
     std::unique_ptr<IInterferenceFunction> mP_iff;
     SimulationOptions m_options;
@@ -78,6 +64,12 @@ private:
     double evaluateSinglePoint(const SimulationElement& sim_element) const;
     double MCIntegratedEvaluate(const SimulationElement& sim_element) const;
     double evaluate_for_fixed_angles(double* fractions, size_t dim, void* params) const;
+    virtual void strategy_specific_post_init();
+    //! Evaluates the intensity in the scalar case
+    virtual double scalarCalculation(const SimulationElement& sim_element) const =0;
+    //! Evaluates the intensity in the polarized case
+    virtual double polarizedCalculation(const SimulationElement& sim_element) const =0;
+
     bool m_polarized;
 
 #ifndef SWIG
diff --git a/Core/Multilayer/InterferenceFunctionUtils.cpp b/Core/Multilayer/InterferenceFunctionUtils.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..784a5d7275deefbbbc72e1912053c6543daf3c9b
--- /dev/null
+++ b/Core/Multilayer/InterferenceFunctionUtils.cpp
@@ -0,0 +1,41 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      Core/Multilayer/InterferenceFunctionUtils.h
+//! @brief     Implements helper functions for InterferenceFunctions and Strategies.
+//!
+//! @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 "InterferenceFunctionUtils.h"
+#include "FormFactorCoherentSum.h"
+
+namespace InterferenceFunctionUtils
+{
+std::vector<complex_t> PrecomputeScalarFormFactors(
+        const SimulationElement& sim_element,
+        const SafePointerVector<FormFactorCoherentSum>& ff_wrappers)
+{
+    std::vector<complex_t> result;
+    for (auto ffw: ff_wrappers) {
+        result.push_back(ffw->evaluate(sim_element));
+    }
+    return result;
+}
+
+matrixFFVector_t PrecomputePolarizedFormFactors(
+        const SimulationElement& sim_element,
+        const SafePointerVector<FormFactorCoherentSum>& ff_wrappers)
+{
+    matrixFFVector_t result;
+    for (auto ffw: ff_wrappers) {
+        result.push_back(ffw->evaluatePol(sim_element));
+    }
+    return result;
+}
+}  // namespace InterferenceFunctionUtils
diff --git a/Core/Multilayer/InterferenceFunctionUtils.h b/Core/Multilayer/InterferenceFunctionUtils.h
new file mode 100644
index 0000000000000000000000000000000000000000..54f4d66337f654e1fe95a07fa14fbe42cbcd92d6
--- /dev/null
+++ b/Core/Multilayer/InterferenceFunctionUtils.h
@@ -0,0 +1,40 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file      Core/Multilayer/InterferenceFunctionUtils.h
+//! @brief     Defines helper functions for InterferenceFunctions and Strategies.
+//!
+//! @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 INTERFERENCEFUNCTIONUTILS_H
+#define INTERFERENCEFUNCTIONUTILS_H
+
+#include "Complex.h"
+#include "SafePointerVector.h"
+#include <Eigen/StdVector>
+#include <vector>
+
+class FormFactorCoherentSum;
+class SimulationElement;
+
+namespace InterferenceFunctionUtils
+{
+using matrixFFVector_t = std::vector<Eigen::Matrix2cd, Eigen::aligned_allocator<Eigen::Matrix2cd>>;
+
+std::vector<complex_t> PrecomputeScalarFormFactors(
+        const SimulationElement& sim_element,
+        const SafePointerVector<FormFactorCoherentSum>& ff_wrappers);
+matrixFFVector_t PrecomputePolarizedFormFactors(
+        const SimulationElement& sim_element,
+        const SafePointerVector<FormFactorCoherentSum>& ff_wrappers);
+
+
+}  // namespace InterferenceFunctionUtils
+
+#endif // INTERFERENCEFUNCTIONUTILS_H
diff --git a/Core/Multilayer/SSCAHelper.cpp b/Core/Multilayer/SSCAHelper.cpp
index bcaf5e40b521b616dee9b30c06e2d2dafce916a6..7dd9d8b38403c7f2e992752c2f9308c00abdc9ff 100644
--- a/Core/Multilayer/SSCAHelper.cpp
+++ b/Core/Multilayer/SSCAHelper.cpp
@@ -47,7 +47,7 @@ complex_t SSCAHelper::getCharacteristicDistribution(
 {
     const InterferenceFunctionRadialParaCrystal *p_iff_radial
         = dynamic_cast<const InterferenceFunctionRadialParaCrystal*>(p_iff);
-    if (p_iff_radial == 0)
+    if (!p_iff_radial)
         throw Exceptions::ClassInitializationException("Wrong interference function for SSCA");
     return p_iff_radial->FTPDF(qp);
 }
@@ -74,7 +74,7 @@ complex_t SSCAHelper::getMeanFormfactorNorm(
 
 void SSCAHelper::getMeanFormfactors(
         double qp, Eigen::Matrix2cd& ff_orig, Eigen::Matrix2cd& ff_conj,
-        const IInterferenceFunctionStrategy::matrixFFVector_t& precomputed_ff,
+        const InterferenceFunctionUtils::matrixFFVector_t& precomputed_ff,
         const SafePointerVector<FormFactorCoherentSum>& ff_wrappers) const
 {
     ff_orig=Eigen::Matrix2cd::Zero();
diff --git a/Core/Multilayer/SSCAHelper.h b/Core/Multilayer/SSCAHelper.h
index f187f75a8cfee4175b7192aa9ff542df00d8bdaf..2328193afb6dfd751b8ad731bdc28686d333d0cb 100644
--- a/Core/Multilayer/SSCAHelper.h
+++ b/Core/Multilayer/SSCAHelper.h
@@ -17,6 +17,7 @@
 
 #include "Complex.h"
 #include "IInterferenceFunctionStrategy.h"
+#include "InterferenceFunctionUtils.h"
 #include "SafePointerVector.h"
 #include <Eigen/StdVector>
 
@@ -41,7 +42,7 @@ public:
     complex_t getMeanFormfactorNorm(double qp, const std::vector<complex_t>& precomputed_ff,
             const SafePointerVector<FormFactorCoherentSum>& ff_wrappers) const;
     void getMeanFormfactors(double qp, Eigen::Matrix2cd& ff_orig, Eigen::Matrix2cd& ff_conj,
-                            const IInterferenceFunctionStrategy::matrixFFVector_t& precomputed_ff,
+                            const InterferenceFunctionUtils::matrixFFVector_t& precomputed_ff,
                             const SafePointerVector<FormFactorCoherentSum>& ff_wrappers) const;
 
 private:
diff --git a/Core/Multilayer/SSCApproximationStrategy.cpp b/Core/Multilayer/SSCApproximationStrategy.cpp
index 0c7f468b06221d0df7a51fbc6d0ee4cb02db5ac9..8ad7ae99789e07f00eb44eb5df8f00ccf14c64cc 100644
--- a/Core/Multilayer/SSCApproximationStrategy.cpp
+++ b/Core/Multilayer/SSCApproximationStrategy.cpp
@@ -14,8 +14,11 @@
 
 #include "SSCApproximationStrategy.h"
 #include "FormFactorCoherentSum.h"
+#include "InterferenceFunctionUtils.h"
 #include "SimulationElement.h"
 
+using InterferenceFunctionUtils::PrecomputeScalarFormFactors;
+using InterferenceFunctionUtils::PrecomputePolarizedFormFactors;
 
 SSCApproximationStrategy::SSCApproximationStrategy(SimulationOptions sim_params, double kappa,
                                                      bool polarized)
@@ -35,7 +38,7 @@ double SSCApproximationStrategy::scalarCalculation(const SimulationElement& sim_
 {
     double qp = sim_element.getMeanQ().magxy();
     double diffuse_intensity = 0.0;
-    auto precomputed_ff = precomputeScalar(sim_element, m_formfactor_wrappers);
+    auto precomputed_ff = PrecomputeScalarFormFactors(sim_element, m_formfactor_wrappers);
     for (size_t i = 0; i < m_formfactor_wrappers.size(); ++i) {
         complex_t ff = precomputed_ff[i];
         double fraction = m_formfactor_wrappers[i]->relativeAbundance();
@@ -54,7 +57,7 @@ double SSCApproximationStrategy::polarizedCalculation(const SimulationElement& s
 {
     double qp = sim_element.getMeanQ().magxy();
     Eigen::Matrix2cd diffuse_matrix = Eigen::Matrix2cd::Zero();
-    auto precomputed_ff = precomputePolarized(sim_element, m_formfactor_wrappers);
+    auto precomputed_ff = PrecomputePolarizedFormFactors(sim_element, m_formfactor_wrappers);
     const auto& polarization_handler = sim_element.polarizationHandler();
     for (size_t i = 0; i < m_formfactor_wrappers.size(); ++i) {
         Eigen::Matrix2cd ff = precomputed_ff[i];
diff --git a/Core/Multilayer/SSCApproximationStrategy.h b/Core/Multilayer/SSCApproximationStrategy.h
index 15c8e7ae18ceb59293a822c0b9cdccc3fb8ddfe9..45d265e9e3c1fc4ed4e2b3f4f045933ec4075d20 100644
--- a/Core/Multilayer/SSCApproximationStrategy.h
+++ b/Core/Multilayer/SSCApproximationStrategy.h
@@ -29,12 +29,10 @@ class SSCApproximationStrategy final : public IInterferenceFunctionStrategy
 public:
     SSCApproximationStrategy(SimulationOptions sim_params, double kappa, bool polarized);
 
-protected:
+private:
     void strategy_specific_post_init() override;
     double scalarCalculation(const SimulationElement& sim_element) const override;
     double polarizedCalculation(const SimulationElement& sim_element) const override;
-
-private:
     SSCAHelper m_helper;
 };
 
diff --git a/Core/Parametrization/Units.h b/Core/Parametrization/Units.h
index ea7aa8d634859278c4fef29b331114c5030824e3..9d397aa9b9e06c4f2c57cd6ec5b66e86da072694 100644
--- a/Core/Parametrization/Units.h
+++ b/Core/Parametrization/Units.h
@@ -35,7 +35,7 @@ static const double barn = nanometer * nanometer * 1e-10;
 // Angle
 static const double radian      = 1.;
 static const double milliradian = 1.e-3*radian;
-static const double degree = (3.14159265358979323846264338327950288/180.0)*radian;
+static const double degree = (3.1415926535897932/180.0)*radian;
 static const double steradian = 1.;
 
 inline double rad2deg(double angle) {return angle/degree; }
diff --git a/auto/Wrap/doxygen_core.i b/auto/Wrap/doxygen_core.i
index 257fa3171df01b16209f7769478fb1b67b50479a..ea70ea1f3029212b7ae116539f785d9b20ad25aa 100644
--- a/auto/Wrap/doxygen_core.i
+++ b/auto/Wrap/doxygen_core.i
@@ -642,21 +642,21 @@ C++ includes: BoxCompositionBuilder.h
 ";
 
 
-// File: structIntegratorReal_1_1CallBackHolder.xml
-%feature("docstring") IntegratorReal::CallBackHolder "
+// File: structIntegratorMCMiser_1_1CallBackHolder.xml
+%feature("docstring") IntegratorMCMiser::CallBackHolder "
 
 structure holding the object and possible extra parameters
 
-C++ includes: IntegratorReal.h
+C++ includes: IntegratorMCMiser.h
 ";
 
 
-// File: structIntegratorMCMiser_1_1CallBackHolder.xml
-%feature("docstring") IntegratorMCMiser::CallBackHolder "
+// File: structIntegratorReal_1_1CallBackHolder.xml
+%feature("docstring") IntegratorReal::CallBackHolder "
 
 structure holding the object and possible extra parameters
 
-C++ includes: IntegratorMCMiser.h
+C++ includes: IntegratorReal.h
 ";
 
 
@@ -1196,13 +1196,13 @@ Counter for reporting progress (with delay interval) in a threaded computation.
 C++ includes: DelayedProgressCounter.h
 ";
 
-%feature("docstring")  DelayedProgressCounter::DelayedProgressCounter "DelayedProgressCounter::DelayedProgressCounter(size_t interval)
+%feature("docstring")  DelayedProgressCounter::DelayedProgressCounter "DelayedProgressCounter::DelayedProgressCounter(ProgressHandler *p_progress, size_t interval)
 ";
 
 %feature("docstring")  DelayedProgressCounter::~DelayedProgressCounter "DelayedProgressCounter::~DelayedProgressCounter()
 ";
 
-%feature("docstring")  DelayedProgressCounter::stepProgress "void DelayedProgressCounter::stepProgress(ProgressHandler *progress)
+%feature("docstring")  DelayedProgressCounter::stepProgress "void DelayedProgressCounter::stepProgress()
 
 Increments inner counter; at regular intervals updates progress handler. 
 ";
@@ -1221,7 +1221,7 @@ C++ includes: DepthProbeComputation.h
 %feature("docstring")  DepthProbeComputation::DepthProbeComputation "DepthProbeComputation::DepthProbeComputation(const MultiLayer &multilayer, const SimulationOptions &options, ProgressHandler &progress, DepthProbeElementIter begin_it, DepthProbeElementIter end_it)
 ";
 
-%feature("docstring")  DepthProbeComputation::~DepthProbeComputation "DepthProbeComputation::~DepthProbeComputation()
+%feature("docstring")  DepthProbeComputation::~DepthProbeComputation "DepthProbeComputation::~DepthProbeComputation() override
 ";
 
 
@@ -1231,7 +1231,13 @@ C++ includes: DepthProbeComputation.h
 %feature("docstring")  DepthProbeComputationTerm::DepthProbeComputationTerm "DepthProbeComputationTerm::DepthProbeComputationTerm(const MultiLayer *p_multi_layer, const IFresnelMap *p_fresnel_map)
 ";
 
-%feature("docstring")  DepthProbeComputationTerm::eval "void DepthProbeComputationTerm::eval(ProgressHandler *progress, const DepthProbeElementIter &begin_it, const DepthProbeElementIter &end_it) const 
+%feature("docstring")  DepthProbeComputationTerm::~DepthProbeComputationTerm "DepthProbeComputationTerm::~DepthProbeComputationTerm()
+";
+
+%feature("docstring")  DepthProbeComputationTerm::setProgressHandler "void DepthProbeComputationTerm::setProgressHandler(ProgressHandler *p_progress)
+";
+
+%feature("docstring")  DepthProbeComputationTerm::compute "void DepthProbeComputationTerm::compute(DepthProbeElement &elem) const 
 ";
 
 
@@ -1904,7 +1910,47 @@ C++ includes: DWBAComputation.h
 %feature("docstring")  DWBAComputation::DWBAComputation "DWBAComputation::DWBAComputation(const MultiLayer &multilayer, const SimulationOptions &options, ProgressHandler &progress, std::vector< SimulationElement >::iterator begin_it, std::vector< SimulationElement >::iterator end_it)
 ";
 
-%feature("docstring")  DWBAComputation::~DWBAComputation "DWBAComputation::~DWBAComputation()
+%feature("docstring")  DWBAComputation::~DWBAComputation "DWBAComputation::~DWBAComputation() override
+";
+
+
+// File: classDWBASingleComputation.xml
+%feature("docstring") DWBASingleComputation "
+
+Class that handles all the computations involved in GISAS (particles, roughness,...) for a single detector bin.
+
+Called by DWBASimulation on each detector bin.
+
+C++ includes: DWBASingleComputation.h
+";
+
+%feature("docstring")  DWBASingleComputation::DWBASingleComputation "DWBASingleComputation::DWBASingleComputation()
+";
+
+%feature("docstring")  DWBASingleComputation::~DWBASingleComputation "DWBASingleComputation::~DWBASingleComputation()
+";
+
+%feature("docstring")  DWBASingleComputation::DWBASingleComputation "DWBASingleComputation::DWBASingleComputation(DWBASingleComputation &&other)
+";
+
+%feature("docstring")  DWBASingleComputation::setProgressHandler "void DWBASingleComputation::setProgressHandler(ProgressHandler *p_progress)
+";
+
+%feature("docstring")  DWBASingleComputation::addLayoutComputation "void DWBASingleComputation::addLayoutComputation(ParticleLayoutComputation *p_layout_comp)
+";
+
+%feature("docstring")  DWBASingleComputation::setRoughnessComputation "void DWBASingleComputation::setRoughnessComputation(RoughMultiLayerComputation *p_roughness_comp)
+";
+
+%feature("docstring")  DWBASingleComputation::setSpecularBinComputation "void DWBASingleComputation::setSpecularBinComputation(GISASSpecularComputation *p_spec_comp)
+";
+
+%feature("docstring")  DWBASingleComputation::compute "void DWBASingleComputation::compute(SimulationElement &elem) const 
+";
+
+%feature("docstring")  DWBASingleComputation::regionMap "const std::map< size_t, std::vector< HomogeneousRegion > > & DWBASingleComputation::regionMap() const
+
+Retrieves a map of regions for the calculation of averaged layers. 
 ";
 
 
@@ -5901,20 +5947,18 @@ Sets beam parameters from here (forwarded to  Instrument)
 ";
 
 
-// File: classGISASSpecularComputationTerm.xml
-%feature("docstring") GISASSpecularComputationTerm "
+// File: classGISASSpecularComputation.xml
+%feature("docstring") GISASSpecularComputation "
 
-Computes the specular scattering. Used by  DWBAComputation.
+Computes the specular signal in the bin where q_parallel = 0. Used by  DWBAComputation.
 
-C++ includes: GISASSpecularComputationTerm.h
+C++ includes: GISASSpecularComputation.h
 ";
 
-%feature("docstring")  GISASSpecularComputationTerm::GISASSpecularComputationTerm "GISASSpecularComputationTerm::GISASSpecularComputationTerm(const MultiLayer *p_multi_layer, const IFresnelMap *p_fresnel_map)
+%feature("docstring")  GISASSpecularComputation::GISASSpecularComputation "GISASSpecularComputation::GISASSpecularComputation(const MultiLayer *p_multi_layer, const IFresnelMap *p_fresnel_map)
 ";
 
-%feature("docstring")  GISASSpecularComputationTerm::eval "void GISASSpecularComputationTerm::eval(ProgressHandler *progress, const std::vector< SimulationElement >::iterator &begin_it, const std::vector< SimulationElement >::iterator &end_it) const override
-
-Calculate scattering intensity for each  SimulationElement returns false if nothing needed to be calculated 
+%feature("docstring")  GISASSpecularComputation::compute "void GISASSpecularComputation::compute(SimulationElement &elem) const 
 ";
 
 
@@ -6254,7 +6298,7 @@ C++ includes: HomogeneousMultilayerBuilder.h
 
 Struct that contains information on a single homogeneous region of a particle inside a single layer. This information is needed for calculating the average of a material, used in the Fresnel calculations.
 
-C++ includes: SlicedParticle.h
+C++ includes: HomogeneousRegion.h
 ";
 
 
@@ -6595,31 +6639,6 @@ C++ includes: IComputation.h
 ";
 
 
-// File: classIComputationTerm.xml
-%feature("docstring") IComputationTerm "
-
-Computes an independent term of the scattering intensity. Used by  DWBAComputation, which adds up all contributions from subclasses of  IComputationTerm
-
-C++ includes: IComputationTerm.h
-";
-
-%feature("docstring")  IComputationTerm::IComputationTerm "IComputationTerm::IComputationTerm(const MultiLayer *p_multilayer, const IFresnelMap *p_fresnel_map)
-";
-
-%feature("docstring")  IComputationTerm::~IComputationTerm "IComputationTerm::~IComputationTerm()
-";
-
-%feature("docstring")  IComputationTerm::eval "virtual void IComputationTerm::eval(ProgressHandler *progress, const std::vector< SimulationElement >::iterator &begin_it, const std::vector< SimulationElement >::iterator &end_it) const =0
-
-Calculate scattering intensity for each  SimulationElement returns false if nothing needed to be calculated 
-";
-
-%feature("docstring")  IComputationTerm::mergeRegionMap "void IComputationTerm::mergeRegionMap(std::map< size_t, std::vector< HomogeneousRegion >> &region_map) const
-
-Merges its region map into the given one (notice non-const reference parameter) 
-";
-
-
 // File: classIcosahedron.xml
 %feature("docstring") Icosahedron "";
 
@@ -7860,7 +7879,7 @@ If defined by this interference function's parameters, returns the particle dens
 
 Base class of all interference function strategy classes. Provides an 'evaluate' function that computes the total scattering intensity from a decorated layer, taking into account a specific inter-particle interference function. This function uses the low-level functions scalarCalculation and polarizedCalculation that are to be overriden in the derived classes. Inheritance is used to support different approximation schemes ( DecouplingApproximationStrategy,  SSCApproximationStrategy).
 
-Instantiation of child classes takes place in LayoutStrategyBuilder::createStrategy, which is called from  ParticleLayoutComputation::eval.
+Instantiation of child classes takes place in LayoutStrategyBuilder::createStrategy, which is called from ParticleLayoutComputation::eval.
 
 C++ includes: IInterferenceFunctionStrategy.h
 ";
@@ -7873,7 +7892,7 @@ C++ includes: IInterferenceFunctionStrategy.h
 
 %feature("docstring")  IInterferenceFunctionStrategy::init "void IInterferenceFunctionStrategy::init(const SafePointerVector< FormFactorCoherentSum > &weighted_formfactors, const IInterferenceFunction *p_iff)
 
-Initializes the object with form factors and interference functions. 
+Initializes the object with form factors and an interference function. 
 ";
 
 %feature("docstring")  IInterferenceFunctionStrategy::evaluate "double IInterferenceFunctionStrategy::evaluate(const SimulationElement &sim_element) const
@@ -11131,6 +11150,18 @@ Returns a vector of children (const).
 ";
 
 
+// File: structMultilayerInfo.xml
+%feature("docstring") MultilayerInfo "
+
+Container struct for information regarding a multilayer: Fresnel coefficients and the multilayer itself. Used by the components of  DWBASingleComputation, which adds up the contributions from particles, roughness and specular signal
+
+C++ includes: MultilayerInfo.h
+";
+
+%feature("docstring")  MultilayerInfo::MultilayerInfo "MultilayerInfo::MultilayerInfo(const MultiLayer *p_multilayer, const IFresnelMap *p_fresnel_map)
+";
+
+
 // File: classMultiLayerWithRoughnessBuilder.xml
 %feature("docstring") MultiLayerWithRoughnessBuilder "
 
@@ -12339,9 +12370,15 @@ C++ includes: ParticleLayoutComputation.h
 %feature("docstring")  ParticleLayoutComputation::ParticleLayoutComputation "ParticleLayoutComputation::ParticleLayoutComputation(const MultiLayer *p_multilayer, const IFresnelMap *p_fresnel_map, const ILayout *p_layout, size_t layer_index, const SimulationOptions &options, bool polarized)
 ";
 
-%feature("docstring")  ParticleLayoutComputation::eval "void ParticleLayoutComputation::eval(ProgressHandler *progress, const std::vector< SimulationElement >::iterator &begin_it, const std::vector< SimulationElement >::iterator &end_it) const override
+%feature("docstring")  ParticleLayoutComputation::~ParticleLayoutComputation "ParticleLayoutComputation::~ParticleLayoutComputation()
+";
+
+%feature("docstring")  ParticleLayoutComputation::compute "void ParticleLayoutComputation::compute(SimulationElement &elem) const 
+";
+
+%feature("docstring")  ParticleLayoutComputation::mergeRegionMap "void ParticleLayoutComputation::mergeRegionMap(std::map< size_t, std::vector< HomogeneousRegion >> &region_map) const
 
-Computes scattering intensity for given range of simulation elements. 
+Merges its region map into the given one (notice non-const reference parameter) 
 ";
 
 
@@ -13400,12 +13437,7 @@ C++ includes: RoughMultiLayerComputation.h
 %feature("docstring")  RoughMultiLayerComputation::RoughMultiLayerComputation "RoughMultiLayerComputation::RoughMultiLayerComputation(const MultiLayer *p_multi_layer, const IFresnelMap *p_fresnel_map)
 ";
 
-%feature("docstring")  RoughMultiLayerComputation::~RoughMultiLayerComputation "RoughMultiLayerComputation::~RoughMultiLayerComputation()
-";
-
-%feature("docstring")  RoughMultiLayerComputation::eval "void RoughMultiLayerComputation::eval(ProgressHandler *progress, const std::vector< SimulationElement >::iterator &begin_it, const std::vector< SimulationElement >::iterator &end_it) const override
-
-Calculate scattering intensity for each  SimulationElement returns false if nothing needed to be calculated 
+%feature("docstring")  RoughMultiLayerComputation::compute "void RoughMultiLayerComputation::compute(SimulationElement &elem) const 
 ";
 
 
@@ -14489,7 +14521,7 @@ C++ includes: SpecularComputation.h
 %feature("docstring")  SpecularComputation::SpecularComputation "SpecularComputation::SpecularComputation(const MultiLayer &multilayer, const SimulationOptions &options, ProgressHandler &progress, SpecularElementIter begin_it, SpecularElementIter end_it)
 ";
 
-%feature("docstring")  SpecularComputation::~SpecularComputation "SpecularComputation::~SpecularComputation()
+%feature("docstring")  SpecularComputation::~SpecularComputation "SpecularComputation::~SpecularComputation() override
 ";
 
 
@@ -14501,10 +14533,16 @@ Computes the specular scattering. Used by  SpecularComputation.
 C++ includes: SpecularComputationTerm.h
 ";
 
-%feature("docstring")  SpecularComputationTerm::SpecularComputationTerm "SpecularComputationTerm::SpecularComputationTerm(const MultiLayer *p_multi_layer, const IFresnelMap *p_fresnel_map)
+%feature("docstring")  SpecularComputationTerm::SpecularComputationTerm "SpecularComputationTerm::SpecularComputationTerm(const IFresnelMap *p_fresnel_map)
+";
+
+%feature("docstring")  SpecularComputationTerm::~SpecularComputationTerm "SpecularComputationTerm::~SpecularComputationTerm()
+";
+
+%feature("docstring")  SpecularComputationTerm::setProgressHandler "void SpecularComputationTerm::setProgressHandler(ProgressHandler *p_progress)
 ";
 
-%feature("docstring")  SpecularComputationTerm::eval "void SpecularComputationTerm::eval(ProgressHandler *progress, const SpecularElementIter &begin_it, const SpecularElementIter &end_it) const 
+%feature("docstring")  SpecularComputationTerm::compute "void SpecularComputationTerm::compute(SpecularSimulationElement &elem) const 
 ";
 
 
@@ -14997,7 +15035,7 @@ C++ includes: SSCAHelper.h
 %feature("docstring")  SSCAHelper::getMeanFormfactorNorm "complex_t SSCAHelper::getMeanFormfactorNorm(double qp, const std::vector< complex_t > &precomputed_ff, const SafePointerVector< FormFactorCoherentSum > &ff_wrappers) const 
 ";
 
-%feature("docstring")  SSCAHelper::getMeanFormfactors "void SSCAHelper::getMeanFormfactors(double qp, Eigen::Matrix2cd &ff_orig, Eigen::Matrix2cd &ff_conj, const IInterferenceFunctionStrategy::matrixFFVector_t &precomputed_ff, const SafePointerVector< FormFactorCoherentSum > &ff_wrappers) const 
+%feature("docstring")  SSCAHelper::getMeanFormfactors "void SSCAHelper::getMeanFormfactors(double qp, Eigen::Matrix2cd &ff_orig, Eigen::Matrix2cd &ff_conj, const InterferenceFunctionUtils::matrixFFVector_t &precomputed_ff, const SafePointerVector< FormFactorCoherentSum > &ff_wrappers) const 
 ";
 
 
@@ -15507,10 +15545,10 @@ C++ includes: WavevectorInfo.h
 ";
 
 
-// File: classFourierTransform_1_1Workspace.xml
+// File: classConvolve_1_1Workspace.xml
 
 
-// File: classConvolve_1_1Workspace.xml
+// File: classFourierTransform_1_1Workspace.xml
 
 
 // File: classZLimits.xml
@@ -15540,13 +15578,13 @@ C++ includes: ZLimits.h
 ";
 
 
-// File: namespace_0D103.xml
+// File: namespace_0D106.xml
 
 
-// File: namespace_0D112.xml
+// File: namespace_0D115.xml
 
 
-// File: namespace_0D180.xml
+// File: namespace_0D183.xml
 
 
 // File: namespace_0D20.xml
@@ -15555,82 +15593,85 @@ C++ includes: ZLimits.h
 // File: namespace_0D22.xml
 
 
-// File: namespace_0D221.xml
+// File: namespace_0D224.xml
 
 
 // File: namespace_0D28.xml
 
 
-// File: namespace_0D288.xml
+// File: namespace_0D291.xml
 
 
-// File: namespace_0D292.xml
+// File: namespace_0D295.xml
 
 
-// File: namespace_0D304.xml
+// File: namespace_0D307.xml
 
 
-// File: namespace_0D325.xml
+// File: namespace_0D328.xml
 
 
-// File: namespace_0D329.xml
+// File: namespace_0D332.xml
 
 
-// File: namespace_0D331.xml
+// File: namespace_0D334.xml
 
 
-// File: namespace_0D333.xml
+// File: namespace_0D336.xml
 
 
-// File: namespace_0D341.xml
+// File: namespace_0D344.xml
 
 
-// File: namespace_0D356.xml
+// File: namespace_0D361.xml
 
 
-// File: namespace_0D364.xml
+// File: namespace_0D369.xml
 
 
-// File: namespace_0D370.xml
+// File: namespace_0D375.xml
 
 
-// File: namespace_0D373.xml
+// File: namespace_0D378.xml
 
 
-// File: namespace_0D375.xml
+// File: namespace_0D380.xml
 
 
-// File: namespace_0D396.xml
+// File: namespace_0D401.xml
 
 
-// File: namespace_0D405.xml
+// File: namespace_0D410.xml
 
 
-// File: namespace_0D438.xml
+// File: namespace_0D444.xml
 
 
-// File: namespace_0D445.xml
+// File: namespace_0D451.xml
 
 
-// File: namespace_0D483.xml
+// File: namespace_0D489.xml
 
 
-// File: namespace_0D491.xml
+// File: namespace_0D497.xml
 
 
-// File: namespace_0D493.xml
+// File: namespace_0D499.xml
 
 
-// File: namespace_0D495.xml
+// File: namespace_0D501.xml
 
 
-// File: namespace_0D573.xml
+// File: namespace_0D579.xml
 
 
-// File: namespace_0D595.xml
+// File: namespace_0D601.xml
 
 
-// File: namespace_0D88.xml
+// File: namespace_0D82.xml
+
+
+// File: namespace_0D91.xml
 
 
 // File: namespaceArrayUtils.xml
@@ -15916,6 +15957,20 @@ Validates all fit parameters for conflicts (steering same sample parameters).
 ";
 
 
+// File: namespaceIComputationUtils.xml
+%feature("docstring")  IComputationUtils::CreateFresnelMap "std::unique_ptr< IFresnelMap > IComputationUtils::CreateFresnelMap(const MultiLayer &multilayer, const SimulationOptions &sim_options, bool allow_average_layers)
+";
+
+%feature("docstring")  IComputationUtils::CreateAveragedMultilayer "std::unique_ptr< MultiLayer > IComputationUtils::CreateAveragedMultilayer(const MultiLayer &multilayer, const std::map< size_t, std::vector< HomogeneousRegion >> &region_map)
+";
+
+%feature("docstring")  IComputationUtils::GetRegionMap "std::map< size_t, std::vector< HomogeneousRegion > > IComputationUtils::GetRegionMap(const MultiLayer &multilayer)
+";
+
+%feature("docstring")  IComputationUtils::MergeRegionMap "void IComputationUtils::MergeRegionMap(std::map< size_t, std::vector< HomogeneousRegion >> &dest, const std::map< size_t, std::vector< HomogeneousRegion >> &source)
+";
+
+
 // File: namespaceINodeUtils.xml
 %feature("docstring")  INodeUtils::ChildNodesOfType "std::vector<const T*> INodeUtils::ChildNodesOfType(const INode &node)
 ";
@@ -16016,6 +16071,14 @@ SimulationResult object.
 ";
 
 
+// File: namespaceInterferenceFunctionUtils.xml
+%feature("docstring")  InterferenceFunctionUtils::PrecomputeScalarFormFactors "std::vector< complex_t > InterferenceFunctionUtils::PrecomputeScalarFormFactors(const SimulationElement &sim_element, const SafePointerVector< FormFactorCoherentSum > &ff_wrappers)
+";
+
+%feature("docstring")  InterferenceFunctionUtils::PrecomputePolarizedFormFactors "matrixFFVector_t InterferenceFunctionUtils::PrecomputePolarizedFormFactors(const SimulationElement &sim_element, const SafePointerVector< FormFactorCoherentSum > &ff_wrappers)
+";
+
+
 // File: namespaceMaterialUtils.xml
 %feature("docstring")  MaterialUtils::ScalarReducedPotential "complex_t MaterialUtils::ScalarReducedPotential(complex_t n, kvector_t k, double n_ref)
 
@@ -16789,10 +16852,16 @@ global helper function for comparison of axes
 // File: DWBAComputation_8h.xml
 
 
-// File: GISASSpecularComputationTerm_8cpp.xml
+// File: DWBASingleComputation_8cpp.xml
+
+
+// File: DWBASingleComputation_8h.xml
 
 
-// File: GISASSpecularComputationTerm_8h.xml
+// File: GISASSpecularComputation_8cpp.xml
+
+
+// File: GISASSpecularComputation_8h.xml
 
 
 // File: IBackground_8cpp.xml
@@ -16807,10 +16876,13 @@ global helper function for comparison of axes
 // File: IComputation_8h.xml
 
 
-// File: IComputationTerm_8cpp.xml
+// File: IComputationUtils_8cpp.xml
+
 
+// File: IComputationUtils_8h.xml
 
-// File: IComputationTerm_8h.xml
+
+// File: MultilayerInfo_8h.xml
 
 
 // File: ParticleLayoutComputation_8cpp.xml
@@ -17601,7 +17673,7 @@ magnetization:
 magnetization (in A/m) 
 ";
 
-%feature("docstring")  createAveragedMaterial "Material createAveragedMaterial(const Material &layer_mat, const std::vector< HomogeneousRegion > &regions)
+%feature("docstring")  CreateAveragedMaterial "Material CreateAveragedMaterial(const Material &layer_mat, const std::vector< HomogeneousRegion > &regions)
 
 Creates averaged material. Square refractive index of returned material is arithmetic mean over  regions and  layer_mat. Magnetization (if present) is averaged linearly. 
 ";
@@ -17642,7 +17714,7 @@ magnetization:
 magnetization (in A/m) 
 ";
 
-%feature("docstring")  createAveragedMaterial "BA_CORE_API_ Material createAveragedMaterial(const Material &layer_mat, const std::vector< HomogeneousRegion > &regions)
+%feature("docstring")  CreateAveragedMaterial "BA_CORE_API_ Material CreateAveragedMaterial(const Material &layer_mat, const std::vector< HomogeneousRegion > &regions)
 
 Creates averaged material. Square refractive index of returned material is arithmetic mean over  regions and  layer_mat. Magnetization (if present) is averaged linearly. 
 ";
@@ -17713,6 +17785,12 @@ Creates averaged material. Square refractive index of returned material is arith
 // File: IMultiLayerBuilder_8h.xml
 
 
+// File: InterferenceFunctionUtils_8cpp.xml
+
+
+// File: InterferenceFunctionUtils_8h.xml
+
+
 // File: Layer_8cpp.xml
 
 
@@ -17948,6 +18026,9 @@ Recursive bisection to determine the number of the deepest layer where RT comput
 // File: FormFactorWeighted_8h.xml
 
 
+// File: HomogeneousRegion_8h.xml
+
+
 // File: IAbstractParticle_8cpp.xml