From 0aea7b93ef90d85b349ad32d80f52ddf52b26d52 Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de>
Date: Mon, 5 Sep 2022 13:31:42 +0200
Subject: [PATCH 1/2] MultiLayer: consequential use of validate

---
 Sample/Multilayer/MultiLayer.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/Sample/Multilayer/MultiLayer.cpp b/Sample/Multilayer/MultiLayer.cpp
index 55b839d7200..e9fe1174561 100644
--- a/Sample/Multilayer/MultiLayer.cpp
+++ b/Sample/Multilayer/MultiLayer.cpp
@@ -15,7 +15,6 @@
 #include "Sample/Multilayer/MultiLayer.h"
 #include "Base/Util/Assert.h"
 #include "Base/Util/StringUtils.h"
-#include "Fit/Param/RealLimits.h"
 #include "Sample/Aggregate/ParticleLayout.h"
 #include "Sample/Interface/LayerInterface.h"
 #include "Sample/Interface/LayerRoughness.h"
@@ -27,7 +26,7 @@ MultiLayer::MultiLayer(std::string name)
     : m_crossCorrLength(0)
     , m_sample_name(std::move(name))
 {
-    RealLimits::nonnegative().check("CrossCorrelationLength", m_crossCorrLength);
+    validateOrThrow();
 }
 
 MultiLayer::~MultiLayer() = default;
@@ -158,6 +157,8 @@ std::string MultiLayer::validate() const
             errs.push_back("{ interface " + std::to_string(i) + ": " + err + " }");
     }
 
+    requestGe0(errs, m_crossCorrLength, "CrossCorrelationLength");
+
     if (!errs.empty())
         return "[ " + BaseUtils::String::join(errs, ", ") + " ]";
     return "";
-- 
GitLab


From 6f32d6e6cd6acfb8da0f9cefe1c83d938e882d49 Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de>
Date: Mon, 5 Sep 2022 16:51:40 +0200
Subject: [PATCH 2/2] use validate instead of RealLimits in all of
 Sample/Aggregate

---
 Sample/Aggregate/IInterference.cpp            |   3 -
 Sample/Aggregate/Interference1DLattice.cpp    |  13 +-
 Sample/Aggregate/Interference1DLattice.h      |   2 +
 .../Aggregate/Interference2DParaCrystal.cpp   |  36 +++--
 Sample/Aggregate/Interference2DParaCrystal.h  |   5 +-
 Sample/Aggregate/InterferenceHardDisk.cpp     |  22 ++-
 Sample/Aggregate/InterferenceHardDisk.h       |   2 +
 .../InterferenceRadialParaCrystal.cpp         |  32 ++--
 .../Aggregate/InterferenceRadialParaCrystal.h |   3 +-
 Sample/Aggregate/InterferenceTwin.cpp         |  21 ++-
 Sample/Aggregate/InterferenceTwin.h           |   2 +
 auto/Wrap/doxygenSample.i                     |  15 ++
 auto/Wrap/libBornAgainSample.py               |  40 +++++
 auto/Wrap/libBornAgainSample_wrap.cpp         | 140 ++++++++++++++++++
 14 files changed, 286 insertions(+), 50 deletions(-)

diff --git a/Sample/Aggregate/IInterference.cpp b/Sample/Aggregate/IInterference.cpp
index e04c2dc8971..d910d761bc1 100644
--- a/Sample/Aggregate/IInterference.cpp
+++ b/Sample/Aggregate/IInterference.cpp
@@ -13,20 +13,17 @@
 //  ************************************************************************************************
 
 #include "Sample/Aggregate/IInterference.h"
-#include "Fit/Param/RealLimits.h"
 #include <algorithm>
 #include <stdexcept>
 
 IInterference::IInterference(const std::vector<double>& PValues)
     : INode(PValues)
 {
-    RealLimits::nonnegative().check("PositionVariance", m_position_var);
 }
 
 IInterference::IInterference(double position_var)
     : m_position_var(position_var)
 {
-    RealLimits::nonnegative().check("PositionVariance", m_position_var);
 }
 
 // Default implementation of evaluate assumes no inner structure
diff --git a/Sample/Aggregate/Interference1DLattice.cpp b/Sample/Aggregate/Interference1DLattice.cpp
index 4a9c3edfbe3..4a8a5771661 100644
--- a/Sample/Aggregate/Interference1DLattice.cpp
+++ b/Sample/Aggregate/Interference1DLattice.cpp
@@ -14,7 +14,6 @@
 
 #include "Sample/Aggregate/Interference1DLattice.h"
 #include "Base/Util/Assert.h"
-#include "Fit/Param/RealLimits.h"
 #include "Sample/Correlations/Profiles1D.h"
 #include "Sample/Correlations/Profiles2D.h"
 #include <algorithm>
@@ -37,7 +36,7 @@ Interference1DLattice::Interference1DLattice(double length, double xi)
     , m_xi(xi)
     , m_na{0}
 {
-    RealLimits::nonnegative().check("Length", m_length);
+    validateOrThrow();
 }
 
 Interference1DLattice::~Interference1DLattice() = default;
@@ -93,3 +92,13 @@ double Interference1DLattice::iff_without_dw(const R3 q) const
     }
     return result / a;
 }
+
+std::string Interference1DLattice::validate() const
+{
+    std::vector<std::string> errs;
+    requestGt0(errs, m_length, "latticeConstant");
+    if (!errs.empty())
+        return jointError(errs);
+    m_validated = true;
+    return "";
+}
diff --git a/Sample/Aggregate/Interference1DLattice.h b/Sample/Aggregate/Interference1DLattice.h
index 744f6776a94..a44965f42c8 100644
--- a/Sample/Aggregate/Interference1DLattice.h
+++ b/Sample/Aggregate/Interference1DLattice.h
@@ -38,6 +38,8 @@ public:
 
     std::vector<const INode*> nodeChildren() const override;
 
+    std::string validate() const override;
+
 private:
     double iff_without_dw(R3 q) const override;
 
diff --git a/Sample/Aggregate/Interference2DParaCrystal.cpp b/Sample/Aggregate/Interference2DParaCrystal.cpp
index e5785a2cd29..52257917f62 100644
--- a/Sample/Aggregate/Interference2DParaCrystal.cpp
+++ b/Sample/Aggregate/Interference2DParaCrystal.cpp
@@ -14,7 +14,7 @@
 
 #include "Sample/Aggregate/Interference2DParaCrystal.h"
 #include "Base/Math/IntegratorGK.h"
-#include "Fit/Param/RealLimits.h"
+#include "Base/Util/Assert.h"
 #include <limits>
 
 Interference2DParaCrystal::Interference2DParaCrystal(const Lattice2D& lattice,
@@ -23,12 +23,10 @@ Interference2DParaCrystal::Interference2DParaCrystal(const Lattice2D& lattice,
     : IInterference(0)
     , m_integrate_xi(false)
     , m_damping_length(damping_length)
+    , m_domain_sizes({domain_size_1, domain_size_2})
 {
     m_lattice.reset(lattice.clone());
-    setDomainSizes(domain_size_1, domain_size_2);
-    RealLimits::nonnegative().check("DampingLength", m_damping_length);
-    RealLimits::nonnegative().check("DomainSize1", m_domain_sizes[0]);
-    RealLimits::nonnegative().check("DomainSize2", m_domain_sizes[1]);
+    validateOrThrow();
 }
 
 Interference2DParaCrystal::~Interference2DParaCrystal() = default;
@@ -90,8 +88,7 @@ double Interference2DParaCrystal::iff_without_dw(const R3 q) const
 
 void Interference2DParaCrystal::setDomainSizes(double size_1, double size_2)
 {
-    m_domain_sizes[0] = size_1;
-    m_domain_sizes[1] = size_2;
+    m_domain_sizes = {size_1, size_2};
 }
 
 void Interference2DParaCrystal::transformToPrincipalAxes(double qx, double qy, double gamma,
@@ -115,14 +112,9 @@ double Interference2DParaCrystal::interferenceForXi(double xi, double qx, double
 double Interference2DParaCrystal::interference1D(double qx, double qy, double xi,
                                                  size_t index) const
 {
-    if (index > 1)
-        throw std::runtime_error("Interference2DParaCrystal::"
-                                 "interference1D() -> Error! Index of interference function "
-                                 "probability must be < 2");
-    if (!m_pdf1 || !m_pdf2)
-        throw std::runtime_error("Interference2DParaCrystal::"
-                                 "interference1D() -> Error! Probability distributions for "
-                                 "interference function not properly initialized");
+    ASSERT(m_validated);
+    ASSERT(index <= 1);
+    ASSERT(m_pdf1 && m_pdf2);
 
     double length = index ? m_lattice->length2() : m_lattice->length1();
     int n = static_cast<int>(std::abs(m_domain_sizes[index] / length));
@@ -151,6 +143,7 @@ double Interference2DParaCrystal::interference1D(double qx, double qy, double xi
 
 complex_t Interference2DParaCrystal::FTPDF(double qx, double qy, double xi, size_t index) const
 {
+    ASSERT(m_validated);
     double length = (index ? m_lattice->length2() : m_lattice->length1());
 
     const IProfile2D* pdf = (index ? m_pdf2.get() : m_pdf1.get());
@@ -189,3 +182,16 @@ const Lattice2D& Interference2DParaCrystal::lattice() const
                                  "No lattice defined.");
     return *m_lattice;
 }
+
+
+std::string Interference2DParaCrystal::validate() const
+{
+    std::vector<std::string> errs;
+    requestGe0(errs, m_damping_length, "DampingLength");
+    requestGe0(errs, m_domain_sizes[0], "DomainSize1");
+    requestGe0(errs, m_domain_sizes[1], "DomainSize2");
+    if (!errs.empty())
+        return jointError(errs);
+    m_validated = true;
+    return "";
+}
diff --git a/Sample/Aggregate/Interference2DParaCrystal.h b/Sample/Aggregate/Interference2DParaCrystal.h
index 0d783079461..16c424ceded 100644
--- a/Sample/Aggregate/Interference2DParaCrystal.h
+++ b/Sample/Aggregate/Interference2DParaCrystal.h
@@ -19,6 +19,7 @@
 #include "Sample/Correlations/Profiles2D.h"
 #include "Sample/Lattice/Lattice2D.h"
 #include <heinz/Complex.h>
+#include <array>
 #include <memory>
 
 class IProfile2D;
@@ -62,6 +63,8 @@ public:
 
     const IProfile2D* pdf2() const { return m_pdf2.get(); }
 
+    std::string validate() const override;
+
 private:
     double iff_without_dw(R3 q) const override;
 
@@ -75,7 +78,7 @@ private:
     std::unique_ptr<IProfile2D> m_pdf1, m_pdf2;
     std::unique_ptr<Lattice2D> m_lattice; // TODO ASAP name as in other i-fcts
     double m_damping_length;  //!< Damping length for removing delta function singularity at q=0.
-    double m_domain_sizes[2]; //!< Coherence domain sizes
+    std::array<double,2> m_domain_sizes; //!< Coherence domain sizes
 };
 
 #endif // BORNAGAIN_SAMPLE_AGGREGATE_INTERFERENCE2DPARACRYSTAL_H
diff --git a/Sample/Aggregate/InterferenceHardDisk.cpp b/Sample/Aggregate/InterferenceHardDisk.cpp
index 2ca6636cf41..06747b7e38e 100644
--- a/Sample/Aggregate/InterferenceHardDisk.cpp
+++ b/Sample/Aggregate/InterferenceHardDisk.cpp
@@ -15,7 +15,7 @@
 #include "Sample/Aggregate/InterferenceHardDisk.h"
 #include "Base/Math/Bessel.h"
 #include "Base/Math/IntegratorGK.h"
-#include "Fit/Param/RealLimits.h"
+#include "Base/Util/Assert.h"
 #include <cmath>
 
 namespace {
@@ -51,12 +51,7 @@ InterferenceHardDisk::InterferenceHardDisk(double radius, double density, double
     , m_radius(radius)
     , m_density(density)
 {
-    if (m_radius < 0.0 || m_density < 0.0 || packingRatio() > 0.65)
-        throw std::runtime_error("InterferenceHardDisk::validateParameters: "
-                                 "radius and density must be positive and packing ratio between "
-                                 "0 and 0.65");
-    RealLimits::nonnegative().check("Radius", m_radius);
-    RealLimits::nonnegative().check("TotalParticleDensity", m_density);
+    validateOrThrow();
 }
 
 InterferenceHardDisk* InterferenceHardDisk::clone() const
@@ -82,6 +77,7 @@ double InterferenceHardDisk::density() const
 
 double InterferenceHardDisk::iff_without_dw(const R3 q) const
 {
+    ASSERT(m_validated);
     const double qx = q.x();
     const double qy = q.y();
     const double q2r = 2.0 * std::sqrt(qx * qx + qy * qy) * m_radius;
@@ -104,3 +100,15 @@ double InterferenceHardDisk::packingRatio() const
 {
     return M_PI * m_radius * m_radius * m_density;
 }
+
+std::string InterferenceHardDisk::validate() const
+{
+    std::vector<std::string> errs;
+    requestGt0(errs, m_radius, "Radius");
+    requestGe0(errs, m_density, "TotalParticleDensity");
+    requestIn(errs, packingRatio(), "packing_ratio", 0, .65);
+    if (!errs.empty())
+        return jointError(errs);
+    m_validated = true;
+    return "";
+}
diff --git a/Sample/Aggregate/InterferenceHardDisk.h b/Sample/Aggregate/InterferenceHardDisk.h
index b1e6d185655..6a018702bda 100644
--- a/Sample/Aggregate/InterferenceHardDisk.h
+++ b/Sample/Aggregate/InterferenceHardDisk.h
@@ -41,6 +41,8 @@ public:
     double radius() const;
     double density() const;
 
+    std::string validate() const override;
+
 private:
     double iff_without_dw(R3 q) const override;
     double packingRatio() const;
diff --git a/Sample/Aggregate/InterferenceRadialParaCrystal.cpp b/Sample/Aggregate/InterferenceRadialParaCrystal.cpp
index 7775cc35300..632c66f5939 100644
--- a/Sample/Aggregate/InterferenceRadialParaCrystal.cpp
+++ b/Sample/Aggregate/InterferenceRadialParaCrystal.cpp
@@ -13,7 +13,7 @@
 //  ************************************************************************************************
 
 #include "Sample/Aggregate/InterferenceRadialParaCrystal.h"
-#include "Fit/Param/RealLimits.h"
+#include "Base/Util/Assert.h"
 #include <limits>
 
 //! Constructor of interference function of radial paracrystal.
@@ -24,17 +24,10 @@ InterferenceRadialParaCrystal::InterferenceRadialParaCrystal(double peak_distanc
     : IInterference(0)
     , m_peak_distance(peak_distance)
     , m_damping_length(damping_length)
-    , m_use_damping_length(true)
     , m_kappa(0.0)
     , m_domain_size(0.0)
 {
-    if (m_damping_length == 0.0)
-        m_use_damping_length = false;
-
-    RealLimits::nonnegative().check("PeakDistance", m_peak_distance);
-    RealLimits::nonnegative().check("DampingLength", m_damping_length);
-    RealLimits::nonnegative().check("SizeSpaceCoupling", m_kappa);
-    RealLimits::nonnegative().check("DomainSize", m_domain_size);
+    validateOrThrow();
 }
 
 InterferenceRadialParaCrystal* InterferenceRadialParaCrystal::clone() const
@@ -72,7 +65,7 @@ complex_t InterferenceRadialParaCrystal::FTPDF(double qpar) const
     complex_t phase = exp_I(qpar * m_peak_distance);
     double amplitude = m_pdf->standardizedFT(qpar);
     complex_t result = phase * amplitude;
-    if (m_use_damping_length)
+    if (m_damping_length)
         result *= std::exp(-m_peak_distance / m_damping_length);
     return result;
 }
@@ -92,10 +85,8 @@ std::vector<const INode*> InterferenceRadialParaCrystal::nodeChildren() const
 
 double InterferenceRadialParaCrystal::iff_without_dw(const R3 q) const
 {
-    if (!m_pdf)
-        throw std::runtime_error("InterferenceRadialParaCrystal::"
-                                 "evaluate() -> Error! Probability distribution for "
-                                 "interference function not properly initialized");
+    ASSERT(m_validated);
+    ASSERT(m_pdf);
     double result = 0.0;
     double qxr = q.x();
     double qyr = q.y();
@@ -132,3 +123,16 @@ double InterferenceRadialParaCrystal::iff_without_dw(const R3 q) const
     }
     return result;
 }
+
+std::string InterferenceRadialParaCrystal::validate() const
+{
+    std::vector<std::string> errs;
+    requestGe0(errs, m_peak_distance, "PeakDistance");
+    requestGe0(errs, m_damping_length, "DampingLength");
+    requestGe0(errs, m_kappa, "SizeSpaceCoupling");
+    requestGe0(errs, m_domain_size, "DomainSize");
+    if (!errs.empty())
+        return jointError(errs);
+    m_validated = true;
+    return "";
+}
diff --git a/Sample/Aggregate/InterferenceRadialParaCrystal.h b/Sample/Aggregate/InterferenceRadialParaCrystal.h
index 33d929e7e05..0ee8356274d 100644
--- a/Sample/Aggregate/InterferenceRadialParaCrystal.h
+++ b/Sample/Aggregate/InterferenceRadialParaCrystal.h
@@ -51,6 +51,8 @@ public:
 
     double randomSample() const { return m_pdf->createSampler()->randomSample(); }
 
+    std::string validate() const override;
+
 private:
     double iff_without_dw(R3 q) const override;
     void init_parameters();
@@ -59,7 +61,6 @@ private:
     double m_damping_length; //!< damping length of paracrystal
     //! Fourier transformed probability distribution of the nearest particle
     std::unique_ptr<IProfile1D> m_pdf;
-    bool m_use_damping_length;
     double m_kappa;       //!< Size-spacing coupling parameter
     double m_domain_size; //!< Size of coherence domain
 };
diff --git a/Sample/Aggregate/InterferenceTwin.cpp b/Sample/Aggregate/InterferenceTwin.cpp
index e0c112072f2..049ee31a19b 100644
--- a/Sample/Aggregate/InterferenceTwin.cpp
+++ b/Sample/Aggregate/InterferenceTwin.cpp
@@ -13,7 +13,7 @@
 //  ************************************************************************************************
 
 #include "Sample/Aggregate/InterferenceTwin.h"
-#include "Fit/Param/RealLimits.h"
+#include "Base/Util/Assert.h"
 #include <cmath>
 
 InterferenceTwin::InterferenceTwin(const R3& direction, double mean_distance, double std_dev)
@@ -22,12 +22,7 @@ InterferenceTwin::InterferenceTwin(const R3& direction, double mean_distance, do
     , m_distance(mean_distance)
     , m_std_dev(std_dev)
 {
-    if (m_direction.mag2() <= 0.0 || m_distance < 0.0 || m_std_dev < 0.0)
-        throw std::runtime_error(
-            "InterferenceTwin::validateParameters: mean distance, standard deviation and "
-            "length of direction vector should be positive");
-    RealLimits::nonnegative().check("Mean", m_distance);
-    RealLimits::nonnegative().check("StdDev", m_std_dev);
+    validateOrThrow();
 }
 
 InterferenceTwin* InterferenceTwin::clone() const
@@ -54,8 +49,20 @@ double InterferenceTwin::stdDev() const
 
 double InterferenceTwin::iff_without_dw(const R3 q) const
 {
+    ASSERT(m_validated);
     double q_proj = q.dot(m_direction.unit());
     return 1.0
            + std::exp(-q_proj * q_proj * m_std_dev * m_std_dev / 2.0)
                  * std::cos(q_proj * m_distance);
 }
+
+std::string InterferenceTwin::validate() const
+{
+    std::vector<std::string> errs;
+    requestGt0(errs, m_distance, "Mean");
+    requestGt0(errs, m_std_dev, "StdDev");
+    if (!errs.empty())
+        return jointError(errs);
+    m_validated = true;
+    return "";
+}
diff --git a/Sample/Aggregate/InterferenceTwin.h b/Sample/Aggregate/InterferenceTwin.h
index 5990cda38ab..a081df47c81 100644
--- a/Sample/Aggregate/InterferenceTwin.h
+++ b/Sample/Aggregate/InterferenceTwin.h
@@ -37,6 +37,8 @@ public:
     double meanDistance() const;
     double stdDev() const;
 
+    std::string validate() const override;
+
 private:
     double iff_without_dw(R3 q) const override;
 
diff --git a/auto/Wrap/doxygenSample.i b/auto/Wrap/doxygenSample.i
index 221037cb5b8..346dd16543a 100644
--- a/auto/Wrap/doxygenSample.i
+++ b/auto/Wrap/doxygenSample.i
@@ -1364,6 +1364,9 @@ Interference1DLattice::xi";
 %feature("docstring")  Interference1DLattice::nodeChildren "std::vector< const INode * > Interference1DLattice::nodeChildren() const override
 Interference1DLattice::nodeChildren";
 
+%feature("docstring")  Interference1DLattice::validate "std::string Interference1DLattice::validate() const override
+Interference1DLattice::validate";
+
 
 // File: classInterference2DLattice.xml
 %feature("docstring") Interference2DLattice "
@@ -1513,6 +1516,9 @@ Interference2DParaCrystal::pdf1";
 %feature("docstring")  Interference2DParaCrystal::pdf2 "const IProfile2D * Interference2DParaCrystal::pdf2() const
 Interference2DParaCrystal::pdf2";
 
+%feature("docstring")  Interference2DParaCrystal::validate "std::string Interference2DParaCrystal::validate() const override
+Interference2DParaCrystal::validate";
+
 
 // File: classInterference2DSuperLattice.xml
 %feature("docstring") Interference2DSuperLattice "
@@ -1763,6 +1769,9 @@ InterferenceHardDisk::radius";
 %feature("docstring")  InterferenceHardDisk::density "double InterferenceHardDisk::density() const
 InterferenceHardDisk::density";
 
+%feature("docstring")  InterferenceHardDisk::validate "std::string InterferenceHardDisk::validate() const override
+InterferenceHardDisk::validate";
+
 
 // File: classInterferenceNone.xml
 %feature("docstring") InterferenceNone "
@@ -1861,6 +1870,9 @@ InterferenceRadialParaCrystal::nodeChildren";
 %feature("docstring")  InterferenceRadialParaCrystal::randomSample "double InterferenceRadialParaCrystal::randomSample() const
 InterferenceRadialParaCrystal::randomSample";
 
+%feature("docstring")  InterferenceRadialParaCrystal::validate "std::string InterferenceRadialParaCrystal::validate() const override
+InterferenceRadialParaCrystal::validate";
+
 
 // File: classInterferenceTwin.xml
 %feature("docstring") InterferenceTwin "
@@ -1891,6 +1903,9 @@ InterferenceTwin::meanDistance";
 %feature("docstring")  InterferenceTwin::stdDev "double InterferenceTwin::stdDev() const
 InterferenceTwin::stdDev";
 
+%feature("docstring")  InterferenceTwin::validate "std::string InterferenceTwin::validate() const override
+InterferenceTwin::validate";
+
 
 // File: classIParticle.xml
 %feature("docstring") IParticle "
diff --git a/auto/Wrap/libBornAgainSample.py b/auto/Wrap/libBornAgainSample.py
index 620030b1284..a355ff90cd1 100644
--- a/auto/Wrap/libBornAgainSample.py
+++ b/auto/Wrap/libBornAgainSample.py
@@ -5456,6 +5456,14 @@ class Interference1DLattice(IInterference):
         """
         return _libBornAgainSample.Interference1DLattice_nodeChildren(self)
 
+    def validate(self):
+        r"""
+        validate(Interference1DLattice self) -> std::string
+        std::string Interference1DLattice::validate() const override
+        Interference1DLattice::validate
+        """
+        return _libBornAgainSample.Interference1DLattice_validate(self)
+
 # Register Interference1DLattice in _libBornAgainSample:
 _libBornAgainSample.Interference1DLattice_swigregister(Interference1DLattice)
 
@@ -5740,6 +5748,14 @@ class Interference2DParaCrystal(IInterference):
         """
         return _libBornAgainSample.Interference2DParaCrystal_pdf2(self)
 
+    def validate(self):
+        r"""
+        validate(Interference2DParaCrystal self) -> std::string
+        std::string Interference2DParaCrystal::validate() const override
+        Interference2DParaCrystal::validate
+        """
+        return _libBornAgainSample.Interference2DParaCrystal_validate(self)
+
 # Register Interference2DParaCrystal in _libBornAgainSample:
 _libBornAgainSample.Interference2DParaCrystal_swigregister(Interference2DParaCrystal)
 
@@ -6243,6 +6259,14 @@ class InterferenceHardDisk(IInterference):
         """
         return _libBornAgainSample.InterferenceHardDisk_density(self)
 
+    def validate(self):
+        r"""
+        validate(InterferenceHardDisk self) -> std::string
+        std::string InterferenceHardDisk::validate() const override
+        InterferenceHardDisk::validate
+        """
+        return _libBornAgainSample.InterferenceHardDisk_validate(self)
+
 # Register InterferenceHardDisk in _libBornAgainSample:
 _libBornAgainSample.InterferenceHardDisk_swigregister(InterferenceHardDisk)
 
@@ -6440,6 +6464,14 @@ class InterferenceRadialParaCrystal(IInterference):
         InterferenceRadialParaCrystal::randomSample
         """
         return _libBornAgainSample.InterferenceRadialParaCrystal_randomSample(self)
+
+    def validate(self):
+        r"""
+        validate(InterferenceRadialParaCrystal self) -> std::string
+        std::string InterferenceRadialParaCrystal::validate() const override
+        InterferenceRadialParaCrystal::validate
+        """
+        return _libBornAgainSample.InterferenceRadialParaCrystal_validate(self)
     __swig_destroy__ = _libBornAgainSample.delete_InterferenceRadialParaCrystal
 
 # Register InterferenceRadialParaCrystal in _libBornAgainSample:
@@ -6513,6 +6545,14 @@ class InterferenceTwin(IInterference):
         InterferenceTwin::stdDev
         """
         return _libBornAgainSample.InterferenceTwin_stdDev(self)
+
+    def validate(self):
+        r"""
+        validate(InterferenceTwin self) -> std::string
+        std::string InterferenceTwin::validate() const override
+        InterferenceTwin::validate
+        """
+        return _libBornAgainSample.InterferenceTwin_validate(self)
     __swig_destroy__ = _libBornAgainSample.delete_InterferenceTwin
 
 # Register InterferenceTwin in _libBornAgainSample:
diff --git a/auto/Wrap/libBornAgainSample_wrap.cpp b/auto/Wrap/libBornAgainSample_wrap.cpp
index 0c6bd750c29..c5a13ce52bd 100644
--- a/auto/Wrap/libBornAgainSample_wrap.cpp
+++ b/auto/Wrap/libBornAgainSample_wrap.cpp
@@ -42392,6 +42392,29 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_Interference1DLattice_validate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Interference1DLattice *arg1 = (Interference1DLattice *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  std::string result;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_Interference1DLattice, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Interference1DLattice_validate" "', argument " "1"" of type '" "Interference1DLattice const *""'"); 
+  }
+  arg1 = reinterpret_cast< Interference1DLattice * >(argp1);
+  result = ((Interference1DLattice const *)arg1)->validate();
+  resultobj = SWIG_From_std_string(static_cast< std::string >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *Interference1DLattice_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
   if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
@@ -43123,6 +43146,29 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_Interference2DParaCrystal_validate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  Interference2DParaCrystal *arg1 = (Interference2DParaCrystal *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  std::string result;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_Interference2DParaCrystal, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Interference2DParaCrystal_validate" "', argument " "1"" of type '" "Interference2DParaCrystal const *""'"); 
+  }
+  arg1 = reinterpret_cast< Interference2DParaCrystal * >(argp1);
+  result = ((Interference2DParaCrystal const *)arg1)->validate();
+  resultobj = SWIG_From_std_string(static_cast< std::string >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *Interference2DParaCrystal_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
   if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
@@ -44787,6 +44833,29 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_InterferenceHardDisk_validate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  InterferenceHardDisk *arg1 = (InterferenceHardDisk *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  std::string result;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_InterferenceHardDisk, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceHardDisk_validate" "', argument " "1"" of type '" "InterferenceHardDisk const *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceHardDisk * >(argp1);
+  result = ((InterferenceHardDisk const *)arg1)->validate();
+  resultobj = SWIG_From_std_string(static_cast< std::string >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *InterferenceHardDisk_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
   if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
@@ -45247,6 +45316,29 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_InterferenceRadialParaCrystal_validate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  InterferenceRadialParaCrystal *arg1 = (InterferenceRadialParaCrystal *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  std::string result;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_InterferenceRadialParaCrystal, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceRadialParaCrystal_validate" "', argument " "1"" of type '" "InterferenceRadialParaCrystal const *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceRadialParaCrystal * >(argp1);
+  result = ((InterferenceRadialParaCrystal const *)arg1)->validate();
+  resultobj = SWIG_From_std_string(static_cast< std::string >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *_wrap_delete_InterferenceRadialParaCrystal(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   InterferenceRadialParaCrystal *arg1 = (InterferenceRadialParaCrystal *) 0 ;
@@ -45459,6 +45551,29 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_InterferenceTwin_validate(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  InterferenceTwin *arg1 = (InterferenceTwin *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  std::string result;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_InterferenceTwin, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "InterferenceTwin_validate" "', argument " "1"" of type '" "InterferenceTwin const *""'"); 
+  }
+  arg1 = reinterpret_cast< InterferenceTwin * >(argp1);
+  result = ((InterferenceTwin const *)arg1)->validate();
+  resultobj = SWIG_From_std_string(static_cast< std::string >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *_wrap_delete_InterferenceTwin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   InterferenceTwin *arg1 = (InterferenceTwin *) 0 ;
@@ -63557,6 +63672,11 @@ static PyMethodDef SwigMethods[] = {
 		"std::vector< const INode * > Interference1DLattice::nodeChildren() const override\n"
 		"Interference1DLattice::nodeChildren\n"
 		""},
+	 { "Interference1DLattice_validate", _wrap_Interference1DLattice_validate, METH_O, "\n"
+		"Interference1DLattice_validate(Interference1DLattice self) -> std::string\n"
+		"std::string Interference1DLattice::validate() const override\n"
+		"Interference1DLattice::validate\n"
+		""},
 	 { "Interference1DLattice_swigregister", Interference1DLattice_swigregister, METH_O, NULL},
 	 { "Interference1DLattice_swiginit", Interference1DLattice_swiginit, METH_VARARGS, NULL},
 	 { "new_Interference2DLattice", _wrap_new_Interference2DLattice, METH_O, "\n"
@@ -63746,6 +63866,11 @@ static PyMethodDef SwigMethods[] = {
 		"const IProfile2D * Interference2DParaCrystal::pdf2() const\n"
 		"Interference2DParaCrystal::pdf2\n"
 		""},
+	 { "Interference2DParaCrystal_validate", _wrap_Interference2DParaCrystal_validate, METH_O, "\n"
+		"Interference2DParaCrystal_validate(Interference2DParaCrystal self) -> std::string\n"
+		"std::string Interference2DParaCrystal::validate() const override\n"
+		"Interference2DParaCrystal::validate\n"
+		""},
 	 { "Interference2DParaCrystal_swigregister", Interference2DParaCrystal_swigregister, METH_O, NULL},
 	 { "Interference2DParaCrystal_swiginit", Interference2DParaCrystal_swiginit, METH_VARARGS, NULL},
 	 { "new_Interference2DSuperLattice", _wrap_new_Interference2DSuperLattice, METH_VARARGS, "\n"
@@ -64059,6 +64184,11 @@ static PyMethodDef SwigMethods[] = {
 		"double InterferenceHardDisk::density() const\n"
 		"InterferenceHardDisk::density\n"
 		""},
+	 { "InterferenceHardDisk_validate", _wrap_InterferenceHardDisk_validate, METH_O, "\n"
+		"InterferenceHardDisk_validate(InterferenceHardDisk self) -> std::string\n"
+		"std::string InterferenceHardDisk::validate() const override\n"
+		"InterferenceHardDisk::validate\n"
+		""},
 	 { "InterferenceHardDisk_swigregister", InterferenceHardDisk_swigregister, METH_O, NULL},
 	 { "InterferenceHardDisk_swiginit", InterferenceHardDisk_swiginit, METH_VARARGS, NULL},
 	 { "new_InterferenceNone", _wrap_new_InterferenceNone, METH_NOARGS, "\n"
@@ -64178,6 +64308,11 @@ static PyMethodDef SwigMethods[] = {
 		"double InterferenceRadialParaCrystal::randomSample() const\n"
 		"InterferenceRadialParaCrystal::randomSample\n"
 		""},
+	 { "InterferenceRadialParaCrystal_validate", _wrap_InterferenceRadialParaCrystal_validate, METH_O, "\n"
+		"InterferenceRadialParaCrystal_validate(InterferenceRadialParaCrystal self) -> std::string\n"
+		"std::string InterferenceRadialParaCrystal::validate() const override\n"
+		"InterferenceRadialParaCrystal::validate\n"
+		""},
 	 { "delete_InterferenceRadialParaCrystal", _wrap_delete_InterferenceRadialParaCrystal, METH_O, "delete_InterferenceRadialParaCrystal(InterferenceRadialParaCrystal self)"},
 	 { "InterferenceRadialParaCrystal_swigregister", InterferenceRadialParaCrystal_swigregister, METH_O, NULL},
 	 { "InterferenceRadialParaCrystal_swiginit", InterferenceRadialParaCrystal_swiginit, METH_VARARGS, NULL},
@@ -64216,6 +64351,11 @@ static PyMethodDef SwigMethods[] = {
 		"double InterferenceTwin::stdDev() const\n"
 		"InterferenceTwin::stdDev\n"
 		""},
+	 { "InterferenceTwin_validate", _wrap_InterferenceTwin_validate, METH_O, "\n"
+		"InterferenceTwin_validate(InterferenceTwin self) -> std::string\n"
+		"std::string InterferenceTwin::validate() const override\n"
+		"InterferenceTwin::validate\n"
+		""},
 	 { "delete_InterferenceTwin", _wrap_delete_InterferenceTwin, METH_O, "delete_InterferenceTwin(InterferenceTwin self)"},
 	 { "InterferenceTwin_swigregister", InterferenceTwin_swigregister, METH_O, NULL},
 	 { "InterferenceTwin_swiginit", InterferenceTwin_swiginit, METH_VARARGS, NULL},
-- 
GitLab