From 3fcebca11be24c7e5bb7e1a063e6967d38245ed5 Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de>
Date: Mon, 1 May 2023 09:55:55 +0200
Subject: [PATCH 01/31] Bin1D rm default c'tor

---
 Base/Axis/Bin.h                     |  5 +--
 auto/Wrap/libBornAgainBase.py       |  9 ++--
 auto/Wrap/libBornAgainBase_wrap.cpp | 66 +++--------------------------
 3 files changed, 12 insertions(+), 68 deletions(-)

diff --git a/Base/Axis/Bin.h b/Base/Axis/Bin.h
index 7d3dcdf1e97..64bbbed85e5 100644
--- a/Base/Axis/Bin.h
+++ b/Base/Axis/Bin.h
@@ -19,14 +19,13 @@
 
 class Bin1D {
 public:
-    Bin1D() = default;
     Bin1D(double lower, double upper)
         : m_lower(lower)
         , m_upper(upper)
     {
     }
-    double m_lower{0}; //!< lower bound of the bin
-    double m_upper{0}; //!< upper bound of the bin
+    double m_lower; //!< lower bound of the bin
+    double m_upper; //!< upper bound of the bin
     double center() const { return (m_lower + m_upper) / 2.0; }
     double binSize() const { return m_upper - m_lower; }
 };
diff --git a/auto/Wrap/libBornAgainBase.py b/auto/Wrap/libBornAgainBase.py
index f1c06fe5fbf..d7d66cfaa37 100644
--- a/auto/Wrap/libBornAgainBase.py
+++ b/auto/Wrap/libBornAgainBase.py
@@ -1790,12 +1790,9 @@ class Bin1D(object):
     thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
     __repr__ = _swig_repr
 
-    def __init__(self, *args):
-        r"""
-        __init__(Bin1D self) -> Bin1D
-        __init__(Bin1D self, double lower, double upper) -> Bin1D
-        """
-        _libBornAgainBase.Bin1D_swiginit(self, _libBornAgainBase.new_Bin1D(*args))
+    def __init__(self, lower, upper):
+        r"""__init__(Bin1D self, double lower, double upper) -> Bin1D"""
+        _libBornAgainBase.Bin1D_swiginit(self, _libBornAgainBase.new_Bin1D(lower, upper))
     m_lower = property(_libBornAgainBase.Bin1D_m_lower_get, _libBornAgainBase.Bin1D_m_lower_set, doc=r"""m_lower : double""")
     m_upper = property(_libBornAgainBase.Bin1D_m_upper_get, _libBornAgainBase.Bin1D_m_upper_set, doc=r"""m_upper : double""")
 
diff --git a/auto/Wrap/libBornAgainBase_wrap.cpp b/auto/Wrap/libBornAgainBase_wrap.cpp
index 2b5756f3c6b..f43f8737265 100644
--- a/auto/Wrap/libBornAgainBase_wrap.cpp
+++ b/auto/Wrap/libBornAgainBase_wrap.cpp
@@ -24971,20 +24971,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_new_Bin1D__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) {
-  PyObject *resultobj = 0;
-  Bin1D *result = 0 ;
-  
-  if ((nobjs < 0) || (nobjs > 0)) SWIG_fail;
-  result = (Bin1D *)new Bin1D();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Bin1D, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_Bin1D__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) {
+SWIGINTERN PyObject *_wrap_new_Bin1D(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   double arg1 ;
   double arg2 ;
@@ -24992,9 +24979,10 @@ SWIGINTERN PyObject *_wrap_new_Bin1D__SWIG_1(PyObject *self, Py_ssize_t nobjs, P
   int ecode1 = 0 ;
   double val2 ;
   int ecode2 = 0 ;
+  PyObject *swig_obj[2] ;
   Bin1D *result = 0 ;
   
-  if ((nobjs < 2) || (nobjs > 2)) SWIG_fail;
+  if (!SWIG_Python_UnpackTuple(args, "new_Bin1D", 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 '" "new_Bin1D" "', argument " "1"" of type '" "double""'");
@@ -25013,43 +25001,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_new_Bin1D(PyObject *self, PyObject *args) {
-  Py_ssize_t argc;
-  PyObject *argv[3] = {
-    0
-  };
-  
-  if (!(argc = SWIG_Python_UnpackTuple(args, "new_Bin1D", 0, 2, argv))) SWIG_fail;
-  --argc;
-  if (argc == 0) {
-    return _wrap_new_Bin1D__SWIG_0(self, argc, argv);
-  }
-  if (argc == 2) {
-    int _v = 0;
-    {
-      int res = SWIG_AsVal_double(argv[0], NULL);
-      _v = SWIG_CheckState(res);
-    }
-    if (_v) {
-      {
-        int res = SWIG_AsVal_double(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_new_Bin1D__SWIG_1(self, argc, argv);
-      }
-    }
-  }
-  
-fail:
-  SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'new_Bin1D'.\n"
-    "  Possible C/C++ prototypes are:\n"
-    "    Bin1D::Bin1D()\n"
-    "    Bin1D::Bin1D(double,double)\n");
-  return 0;
-}
-
-
 SWIGINTERN PyObject *_wrap_Bin1D_m_lower_set(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   Bin1D *arg1 = (Bin1D *) 0 ;
@@ -25525,7 +25476,7 @@ SWIGINTERN PyObject *_wrap_IAxis_bin(PyObject *self, PyObject *args) {
   size_t val2 ;
   int ecode2 = 0 ;
   PyObject *swig_obj[2] ;
-  Bin1D result;
+  SwigValueWrapper< Bin1D > result;
   
   if (!SWIG_Python_UnpackTuple(args, "IAxis_bin", 2, 2, swig_obj)) SWIG_fail;
   res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IAxis, 0 |  0 );
@@ -26043,7 +25994,7 @@ SWIGINTERN PyObject *_wrap_FixedBinAxis_bin(PyObject *self, PyObject *args) {
   size_t val2 ;
   int ecode2 = 0 ;
   PyObject *swig_obj[2] ;
-  Bin1D result;
+  SwigValueWrapper< Bin1D > result;
   
   if (!SWIG_Python_UnpackTuple(args, "FixedBinAxis_bin", 2, 2, swig_obj)) SWIG_fail;
   res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_FixedBinAxis, 0 |  0 );
@@ -26470,7 +26421,7 @@ SWIGINTERN PyObject *_wrap_DiscreteAxis_bin(PyObject *self, PyObject *args) {
   size_t val2 ;
   int ecode2 = 0 ;
   PyObject *swig_obj[2] ;
-  Bin1D result;
+  SwigValueWrapper< Bin1D > result;
   
   if (!SWIG_Python_UnpackTuple(args, "DiscreteAxis_bin", 2, 2, swig_obj)) SWIG_fail;
   res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_DiscreteAxis, 0 |  0 );
@@ -29188,10 +29139,7 @@ static PyMethodDef SwigMethods[] = {
 	 { "cosTheta", _wrap_cosTheta, METH_O, "cosTheta(R3 a) -> double"},
 	 { "sin2Theta", _wrap_sin2Theta, METH_O, "sin2Theta(R3 a) -> double"},
 	 { "angle", _wrap_angle, METH_VARARGS, "angle(R3 a, R3 b) -> double"},
-	 { "new_Bin1D", _wrap_new_Bin1D, METH_VARARGS, "\n"
-		"Bin1D()\n"
-		"new_Bin1D(double lower, double upper) -> Bin1D\n"
-		""},
+	 { "new_Bin1D", _wrap_new_Bin1D, METH_VARARGS, "new_Bin1D(double lower, double upper) -> Bin1D"},
 	 { "Bin1D_m_lower_set", _wrap_Bin1D_m_lower_set, METH_VARARGS, "Bin1D_m_lower_set(Bin1D self, double m_lower)"},
 	 { "Bin1D_m_lower_get", _wrap_Bin1D_m_lower_get, METH_O, "Bin1D_m_lower_get(Bin1D self) -> double"},
 	 { "Bin1D_m_upper_set", _wrap_Bin1D_m_upper_set, METH_VARARGS, "Bin1D_m_upper_set(Bin1D self, double m_upper)"},
-- 
GitLab


From e48706fb8094afee89023332995ca22500c21089 Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de>
Date: Mon, 1 May 2023 10:08:51 +0200
Subject: [PATCH 02/31] Bin1D data -> private

---
 Base/Axis/Bin.h                         |  8 ++-
 Base/Axis/FixedBinAxis.cpp              |  8 +--
 Base/Axis/FrameUtil.cpp                 |  8 +--
 Base/Pixel/SphericalPixel.cpp           |  4 +-
 Device/Detector/RectangularDetector.cpp |  4 +-
 Device/Mask/Line.cpp                    | 14 ++---
 Tests/Unit/Device/FixedBinAxisTest.cpp  | 16 +++---
 auto/Wrap/libBornAgainBase.py           | 10 +++-
 auto/Wrap/libBornAgainBase_wrap.cpp     | 76 +++----------------------
 9 files changed, 49 insertions(+), 99 deletions(-)

diff --git a/Base/Axis/Bin.h b/Base/Axis/Bin.h
index 64bbbed85e5..5b700452ac1 100644
--- a/Base/Axis/Bin.h
+++ b/Base/Axis/Bin.h
@@ -24,10 +24,14 @@ public:
         , m_upper(upper)
     {
     }
+    double lowerBound() const { return m_lower; }
+    double upperBound() const { return m_upper; }
+    double center() const { return (m_lower + m_upper) / 2; }
+    double binSize() const { return m_upper - m_lower; }
+
+private:
     double m_lower; //!< lower bound of the bin
     double m_upper; //!< upper bound of the bin
-    double center() const { return (m_lower + m_upper) / 2.0; }
-    double binSize() const { return m_upper - m_lower; }
 };
 
 #endif // BORNAGAIN_BASE_AXIS_BIN_H
diff --git a/Base/Axis/FixedBinAxis.cpp b/Base/Axis/FixedBinAxis.cpp
index 73f00afdd0b..c37130927dd 100644
--- a/Base/Axis/FixedBinAxis.cpp
+++ b/Base/Axis/FixedBinAxis.cpp
@@ -76,8 +76,8 @@ std::vector<double> FixedBinAxis::binBoundaries() const
     std::vector<double> result;
     result.resize(size() + 1, 0.0);
     for (size_t i = 0; i < size(); ++i)
-        result[i] = bin(i).m_lower;
-    result[size()] = bin(size() - 1).m_upper;
+        result[i] = bin(i).lowerBound();
+    result[size()] = bin(size() - 1).upperBound();
     return result;
 }
 
@@ -97,8 +97,8 @@ void FixedBinAxis::clip(double lower, double upper)
 
     // create tmp vars until everything is calculated, otherwise the calculation will be corrupted
     // by partially changed values
-    const auto newStart = bin(nbin1).m_lower;
-    const auto newEnd = bin(nbin2).m_upper;
+    const auto newStart = bin(nbin1).lowerBound();
+    const auto newEnd = bin(nbin2).upperBound();
 
     m_nbins = nbin2 - nbin1 + 1;
     m_start = newStart;
diff --git a/Base/Axis/FrameUtil.cpp b/Base/Axis/FrameUtil.cpp
index 02d4f129f08..0d238bec681 100644
--- a/Base/Axis/FrameUtil.cpp
+++ b/Base/Axis/FrameUtil.cpp
@@ -37,7 +37,7 @@ double FrameUtil::coordinateToBinf(double coordinate, const IAxis& axis)
 {
     size_t index = axis.findClosestIndex(coordinate);
     Bin1D bin = axis.bin(index);
-    double f = (coordinate - bin.m_lower) / bin.binSize();
+    double f = (coordinate - bin.lowerBound()) / bin.binSize();
     return static_cast<double>(index) + f;
 }
 
@@ -48,13 +48,13 @@ double FrameUtil::coordinateFromBinf(double value, const IAxis& axis)
     double result(0);
     if (index < 0) {
         Bin1D bin = axis.bin(0);
-        result = bin.m_lower + value * bin.binSize();
+        result = bin.lowerBound() + value * bin.binSize();
     } else if (index >= static_cast<int>(axis.size())) {
         Bin1D bin = axis.bin(axis.size() - 1);
-        result = bin.m_upper + (value - axis.size()) * bin.binSize();
+        result = bin.upperBound() + (value - axis.size()) * bin.binSize();
     } else {
         Bin1D bin = axis.bin(static_cast<size_t>(index));
-        result = bin.m_lower + (value - static_cast<double>(index)) * bin.binSize();
+        result = bin.lowerBound() + (value - static_cast<double>(index)) * bin.binSize();
     }
 
     return result;
diff --git a/Base/Pixel/SphericalPixel.cpp b/Base/Pixel/SphericalPixel.cpp
index 318a7185bc6..79bcf98ffd6 100644
--- a/Base/Pixel/SphericalPixel.cpp
+++ b/Base/Pixel/SphericalPixel.cpp
@@ -17,8 +17,8 @@
 #include "Base/Vector/GisasDirection.h"
 
 SphericalPixel::SphericalPixel(const Bin1D& alpha_bin, const Bin1D& phi_bin)
-    : m_alpha(alpha_bin.m_lower)
-    , m_phi(phi_bin.m_lower)
+    : m_alpha(alpha_bin.lowerBound())
+    , m_phi(phi_bin.lowerBound())
     , m_dalpha(alpha_bin.binSize())
     , m_dphi(phi_bin.binSize())
 {
diff --git a/Device/Detector/RectangularDetector.cpp b/Device/Detector/RectangularDetector.cpp
index 91dda17c6b5..6ac2e64b39f 100644
--- a/Device/Detector/RectangularDetector.cpp
+++ b/Device/Detector/RectangularDetector.cpp
@@ -173,8 +173,8 @@ const IPixel* RectangularDetector::createPixel(size_t index) const
 
     const Bin1D u_bin = u_axis.bin(u_index);
     const Bin1D v_bin = v_axis.bin(v_index);
-    const R3 corner_position(m_normal_to_detector + (u_bin.m_lower - m_u0) * m_u_unit
-                             + (v_bin.m_lower - m_v0) * m_v_unit);
+    const R3 corner_position(m_normal_to_detector + (u_bin.lowerBound() - m_u0) * m_u_unit
+                             + (v_bin.lowerBound() - m_v0) * m_v_unit);
     const R3 width = u_bin.binSize() * m_u_unit;
     const R3 height = v_bin.binSize() * m_v_unit;
     return new RectangularPixel(corner_position, width, height);
diff --git a/Device/Mask/Line.cpp b/Device/Mask/Line.cpp
index 4d88c894e53..ec8f9daae52 100644
--- a/Device/Mask/Line.cpp
+++ b/Device/Mask/Line.cpp
@@ -48,11 +48,11 @@ bool Line::contains(double x, double y) const
 bool Line::contains(const Bin1D& binx, const Bin1D& biny) const
 {
     std::vector<point_t> box_points;
-    box_points.emplace_back(binx.m_lower, biny.m_lower);
-    box_points.emplace_back(binx.m_lower, biny.m_upper);
-    box_points.emplace_back(binx.m_upper, biny.m_upper);
-    box_points.emplace_back(binx.m_upper, biny.m_lower);
-    box_points.emplace_back(binx.m_lower, biny.m_lower);
+    box_points.emplace_back(binx.lowerBound(), biny.lowerBound());
+    box_points.emplace_back(binx.lowerBound(), biny.upperBound());
+    box_points.emplace_back(binx.upperBound(), biny.upperBound());
+    box_points.emplace_back(binx.upperBound(), biny.lowerBound());
+    box_points.emplace_back(binx.lowerBound(), biny.lowerBound());
 
     std::vector<point_t> line_points;
     line_points.emplace_back(m_x1, m_y1);
@@ -78,7 +78,7 @@ bool VerticalLine::contains(double x, double /*y*/) const
 
 bool VerticalLine::contains(const Bin1D& binx, const Bin1D& /*biny*/) const
 {
-    return m_x >= binx.m_lower && m_x <= binx.m_upper;
+    return m_x >= binx.lowerBound() && m_x <= binx.upperBound();
 }
 
 // ------------------------------------------------------------------------- //
@@ -97,5 +97,5 @@ bool HorizontalLine::contains(double /*x*/, double y) const
 
 bool HorizontalLine::contains(const Bin1D& /*binx*/, const Bin1D& biny) const
 {
-    return m_y >= biny.m_lower && m_y <= biny.m_upper;
+    return m_y >= biny.lowerBound() && m_y <= biny.upperBound();
 }
diff --git a/Tests/Unit/Device/FixedBinAxisTest.cpp b/Tests/Unit/Device/FixedBinAxisTest.cpp
index ac4a71813e4..028325ff1cd 100644
--- a/Tests/Unit/Device/FixedBinAxisTest.cpp
+++ b/Tests/Unit/Device/FixedBinAxisTest.cpp
@@ -59,25 +59,25 @@ TEST(FixedBinAxisTest, CheckBin)
 
     Bin1D bin0 = axis.bin(0);
     EXPECT_DOUBLE_EQ(0.25, bin0.center());
-    EXPECT_DOUBLE_EQ(0.0, bin0.m_lower);
-    EXPECT_DOUBLE_EQ(0.5, bin0.m_upper);
+    EXPECT_DOUBLE_EQ(0.0, bin0.lowerBound());
+    EXPECT_DOUBLE_EQ(0.5, bin0.upperBound());
     EXPECT_DOUBLE_EQ(0.5, bin0.binSize());
 
     Bin1D bin3 = axis.bin(3);
     EXPECT_DOUBLE_EQ(1.75, bin3.center());
-    EXPECT_DOUBLE_EQ(1.5, bin3.m_lower);
-    EXPECT_DOUBLE_EQ(2.0, bin3.m_upper);
+    EXPECT_DOUBLE_EQ(1.5, bin3.lowerBound());
+    EXPECT_DOUBLE_EQ(2.0, bin3.upperBound());
     EXPECT_DOUBLE_EQ(0.5, bin3.binSize());
 
     Bin1D bin10 = axis.bin(10);
     EXPECT_DOUBLE_EQ(5.25, bin10.center());
-    EXPECT_DOUBLE_EQ(5.0, bin10.m_lower);
-    EXPECT_DOUBLE_EQ(5.5, bin10.m_upper);
+    EXPECT_DOUBLE_EQ(5.0, bin10.lowerBound());
+    EXPECT_DOUBLE_EQ(5.5, bin10.upperBound());
 
     Bin1D bin19 = axis.bin(19);
     EXPECT_DOUBLE_EQ(9.75, bin19.center());
-    EXPECT_DOUBLE_EQ(9.5, bin19.m_lower);
-    EXPECT_DOUBLE_EQ(10.0, bin19.m_upper);
+    EXPECT_DOUBLE_EQ(9.5, bin19.lowerBound());
+    EXPECT_DOUBLE_EQ(10.0, bin19.upperBound());
 
     EXPECT_THROW(axis.bin(20), std::runtime_error);
 
diff --git a/auto/Wrap/libBornAgainBase.py b/auto/Wrap/libBornAgainBase.py
index d7d66cfaa37..9bbe33d2db5 100644
--- a/auto/Wrap/libBornAgainBase.py
+++ b/auto/Wrap/libBornAgainBase.py
@@ -1793,8 +1793,14 @@ class Bin1D(object):
     def __init__(self, lower, upper):
         r"""__init__(Bin1D self, double lower, double upper) -> Bin1D"""
         _libBornAgainBase.Bin1D_swiginit(self, _libBornAgainBase.new_Bin1D(lower, upper))
-    m_lower = property(_libBornAgainBase.Bin1D_m_lower_get, _libBornAgainBase.Bin1D_m_lower_set, doc=r"""m_lower : double""")
-    m_upper = property(_libBornAgainBase.Bin1D_m_upper_get, _libBornAgainBase.Bin1D_m_upper_set, doc=r"""m_upper : double""")
+
+    def lowerBound(self):
+        r"""lowerBound(Bin1D self) -> double"""
+        return _libBornAgainBase.Bin1D_lowerBound(self)
+
+    def upperBound(self):
+        r"""upperBound(Bin1D self) -> double"""
+        return _libBornAgainBase.Bin1D_upperBound(self)
 
     def center(self):
         r"""center(Bin1D self) -> double"""
diff --git a/auto/Wrap/libBornAgainBase_wrap.cpp b/auto/Wrap/libBornAgainBase_wrap.cpp
index f43f8737265..6a9ded024c2 100644
--- a/auto/Wrap/libBornAgainBase_wrap.cpp
+++ b/auto/Wrap/libBornAgainBase_wrap.cpp
@@ -25001,36 +25001,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_Bin1D_m_lower_set(PyObject *self, PyObject *args) {
-  PyObject *resultobj = 0;
-  Bin1D *arg1 = (Bin1D *) 0 ;
-  double arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  PyObject *swig_obj[2] ;
-  
-  if (!SWIG_Python_UnpackTuple(args, "Bin1D_m_lower_set", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_Bin1D, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Bin1D_m_lower_set" "', argument " "1"" of type '" "Bin1D *""'"); 
-  }
-  arg1 = reinterpret_cast< Bin1D * >(argp1);
-  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Bin1D_m_lower_set" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  if (arg1) (arg1)->m_lower = arg2;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_Bin1D_m_lower_get(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_Bin1D_lowerBound(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   Bin1D *arg1 = (Bin1D *) 0 ;
   void *argp1 = 0 ;
@@ -25042,10 +25013,10 @@ SWIGINTERN PyObject *_wrap_Bin1D_m_lower_get(PyObject *self, PyObject *args) {
   swig_obj[0] = args;
   res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_Bin1D, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Bin1D_m_lower_get" "', argument " "1"" of type '" "Bin1D *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Bin1D_lowerBound" "', argument " "1"" of type '" "Bin1D const *""'"); 
   }
   arg1 = reinterpret_cast< Bin1D * >(argp1);
-  result = (double) ((arg1)->m_lower);
+  result = (double)((Bin1D const *)arg1)->lowerBound();
   resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
@@ -25053,36 +25024,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_Bin1D_m_upper_set(PyObject *self, PyObject *args) {
-  PyObject *resultobj = 0;
-  Bin1D *arg1 = (Bin1D *) 0 ;
-  double arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  PyObject *swig_obj[2] ;
-  
-  if (!SWIG_Python_UnpackTuple(args, "Bin1D_m_upper_set", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_Bin1D, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Bin1D_m_upper_set" "', argument " "1"" of type '" "Bin1D *""'"); 
-  }
-  arg1 = reinterpret_cast< Bin1D * >(argp1);
-  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Bin1D_m_upper_set" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  if (arg1) (arg1)->m_upper = arg2;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_Bin1D_m_upper_get(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_Bin1D_upperBound(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   Bin1D *arg1 = (Bin1D *) 0 ;
   void *argp1 = 0 ;
@@ -25094,10 +25036,10 @@ SWIGINTERN PyObject *_wrap_Bin1D_m_upper_get(PyObject *self, PyObject *args) {
   swig_obj[0] = args;
   res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_Bin1D, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Bin1D_m_upper_get" "', argument " "1"" of type '" "Bin1D *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Bin1D_upperBound" "', argument " "1"" of type '" "Bin1D const *""'"); 
   }
   arg1 = reinterpret_cast< Bin1D * >(argp1);
-  result = (double) ((arg1)->m_upper);
+  result = (double)((Bin1D const *)arg1)->upperBound();
   resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
@@ -29140,10 +29082,8 @@ static PyMethodDef SwigMethods[] = {
 	 { "sin2Theta", _wrap_sin2Theta, METH_O, "sin2Theta(R3 a) -> double"},
 	 { "angle", _wrap_angle, METH_VARARGS, "angle(R3 a, R3 b) -> double"},
 	 { "new_Bin1D", _wrap_new_Bin1D, METH_VARARGS, "new_Bin1D(double lower, double upper) -> Bin1D"},
-	 { "Bin1D_m_lower_set", _wrap_Bin1D_m_lower_set, METH_VARARGS, "Bin1D_m_lower_set(Bin1D self, double m_lower)"},
-	 { "Bin1D_m_lower_get", _wrap_Bin1D_m_lower_get, METH_O, "Bin1D_m_lower_get(Bin1D self) -> double"},
-	 { "Bin1D_m_upper_set", _wrap_Bin1D_m_upper_set, METH_VARARGS, "Bin1D_m_upper_set(Bin1D self, double m_upper)"},
-	 { "Bin1D_m_upper_get", _wrap_Bin1D_m_upper_get, METH_O, "Bin1D_m_upper_get(Bin1D self) -> double"},
+	 { "Bin1D_lowerBound", _wrap_Bin1D_lowerBound, METH_O, "Bin1D_lowerBound(Bin1D self) -> double"},
+	 { "Bin1D_upperBound", _wrap_Bin1D_upperBound, METH_O, "Bin1D_upperBound(Bin1D self) -> double"},
 	 { "Bin1D_center", _wrap_Bin1D_center, METH_O, "Bin1D_center(Bin1D self) -> double"},
 	 { "Bin1D_binSize", _wrap_Bin1D_binSize, METH_O, "Bin1D_binSize(Bin1D self) -> double"},
 	 { "delete_Bin1D", _wrap_delete_Bin1D, METH_O, "delete_Bin1D(Bin1D self)"},
-- 
GitLab


From 77862de2c459cac51932775c8ccd5aeb56657df7 Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de>
Date: Mon, 1 May 2023 10:11:43 +0200
Subject: [PATCH 03/31] Bin1D data -> const

---
 Base/Axis/Bin.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/Base/Axis/Bin.h b/Base/Axis/Bin.h
index 5b700452ac1..54948c92478 100644
--- a/Base/Axis/Bin.h
+++ b/Base/Axis/Bin.h
@@ -3,7 +3,7 @@
 //  BornAgain: simulate and fit reflection and scattering
 //
 //! @file      Base/Axis/Bin.h
-//! @brief     Defines structs Bin1D, Bin1DCVector
+//! @brief     Defines class Bin1D
 //!
 //! @homepage  http://www.bornagainproject.org
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -30,8 +30,8 @@ public:
     double binSize() const { return m_upper - m_lower; }
 
 private:
-    double m_lower; //!< lower bound of the bin
-    double m_upper; //!< upper bound of the bin
+    const double m_lower; //!< lower bound of the bin
+    const double m_upper; //!< upper bound of the bin
 };
 
 #endif // BORNAGAIN_BASE_AXIS_BIN_H
-- 
GitLab


From c5b45fbf97faade225d9debad4d0a1152ee536a7 Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de>
Date: Mon, 1 May 2023 10:12:55 +0200
Subject: [PATCH 04/31] rm fwd decl

---
 Base/Axis/Frame.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/Base/Axis/Frame.h b/Base/Axis/Frame.h
index 14762a5916c..2ea8ab95ff6 100644
--- a/Base/Axis/Frame.h
+++ b/Base/Axis/Frame.h
@@ -21,7 +21,6 @@
 using std::size_t;
 
 class IAxis;
-class Bin1D;
 
 //! Holds one or two axes.
 
-- 
GitLab


From c4e8d377696578ad17deead30183ff62dcb41d8d Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de>
Date: Mon, 1 May 2023 10:18:27 +0200
Subject: [PATCH 05/31] + Bin.cpp, to assert ordering

---
 Base/Axis/Bin.cpp | 23 +++++++++++++++++++++++
 Base/Axis/Bin.h   |  7 ++-----
 2 files changed, 25 insertions(+), 5 deletions(-)
 create mode 100644 Base/Axis/Bin.cpp

diff --git a/Base/Axis/Bin.cpp b/Base/Axis/Bin.cpp
new file mode 100644
index 00000000000..d086358e591
--- /dev/null
+++ b/Base/Axis/Bin.cpp
@@ -0,0 +1,23 @@
+//  ************************************************************************************************
+//
+//  BornAgain: simulate and fit reflection and scattering
+//
+//! @file      Base/Axis/Bin.cpp
+//! @brief     Implements class Bin1D
+//!
+//! @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 "Base/Axis/Bin.h"
+#include "Base/Util/Assert.h"
+
+Bin1D::Bin1D(double lower, double upper)
+    : m_lower(lower)
+    , m_upper(upper)
+{
+    ASSERT(m_lower <= m_upper);
+}
diff --git a/Base/Axis/Bin.h b/Base/Axis/Bin.h
index 54948c92478..2e71e8b49cc 100644
--- a/Base/Axis/Bin.h
+++ b/Base/Axis/Bin.h
@@ -19,11 +19,8 @@
 
 class Bin1D {
 public:
-    Bin1D(double lower, double upper)
-        : m_lower(lower)
-        , m_upper(upper)
-    {
-    }
+    Bin1D(double lower, double upper);
+
     double lowerBound() const { return m_lower; }
     double upperBound() const { return m_upper; }
     double center() const { return (m_lower + m_upper) / 2; }
-- 
GitLab


From d40937a51898cae8ef34b4f5be2418e022123055 Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de>
Date: Mon, 1 May 2023 10:20:45 +0200
Subject: [PATCH 06/31] rm include

---
 Base/Axis/Bin.h                 | 2 --
 Base/Axis/DiscreteAxis.cpp      | 1 +
 Device/Histo/DiffUtil.cpp       | 1 +
 Device/IO/ReadWriteINT.cpp      | 1 +
 Device/IO/ReadWriteNumpyTXT.cpp | 1 +
 Device/Mask/Ellipse.cpp         | 1 +
 Device/Mask/Rectangle.cpp       | 1 +
 7 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/Base/Axis/Bin.h b/Base/Axis/Bin.h
index 2e71e8b49cc..cbcf0b0761e 100644
--- a/Base/Axis/Bin.h
+++ b/Base/Axis/Bin.h
@@ -15,8 +15,6 @@
 #ifndef BORNAGAIN_BASE_AXIS_BIN_H
 #define BORNAGAIN_BASE_AXIS_BIN_H
 
-#include <heinz/Vectors3D.h>
-
 class Bin1D {
 public:
     Bin1D(double lower, double upper);
diff --git a/Base/Axis/DiscreteAxis.cpp b/Base/Axis/DiscreteAxis.cpp
index ea84f61d0a2..46b3f64c8f1 100644
--- a/Base/Axis/DiscreteAxis.cpp
+++ b/Base/Axis/DiscreteAxis.cpp
@@ -17,6 +17,7 @@
 #include "Base/Util/VectorUtil.h"
 #include <algorithm>
 #include <iomanip>
+#include <limits>
 #include <stdexcept>
 
 const size_t min_axis_size = 2;
diff --git a/Device/Histo/DiffUtil.cpp b/Device/Histo/DiffUtil.cpp
index 0390d66c141..127936b9fa8 100644
--- a/Device/Histo/DiffUtil.cpp
+++ b/Device/Histo/DiffUtil.cpp
@@ -21,6 +21,7 @@
 #include "Device/Data/Datafield.h"
 #include "Device/Histo/SimulationResult.h"
 #include <algorithm>
+#include <cmath>
 #include <iostream>
 
 //! Returns relative difference between two data sets sum(dat[i] - ref[i])/ref[i]).
diff --git a/Device/IO/ReadWriteINT.cpp b/Device/IO/ReadWriteINT.cpp
index aa9c84ec110..2dba58dfb88 100644
--- a/Device/IO/ReadWriteINT.cpp
+++ b/Device/IO/ReadWriteINT.cpp
@@ -19,6 +19,7 @@
 #include "Device/Data/ArrayUtil.h"
 #include "Device/Data/Datafield.h"
 #include "Device/IO/DataFormatUtil.h"
+#include <cmath>
 #include <iostream>
 
 Datafield* ReadWriteINT::readDatafield(std::istream& input_stream)
diff --git a/Device/IO/ReadWriteNumpyTXT.cpp b/Device/IO/ReadWriteNumpyTXT.cpp
index 23449e651d1..4afd2cebc3b 100644
--- a/Device/IO/ReadWriteNumpyTXT.cpp
+++ b/Device/IO/ReadWriteNumpyTXT.cpp
@@ -19,6 +19,7 @@
 #include "Device/Data/ArrayUtil.h"
 #include "Device/Data/Datafield.h"
 #include "Device/IO/DataFormatUtil.h"
+#include <cmath>
 #include <string>
 #include <vector>
 
diff --git a/Device/Mask/Ellipse.cpp b/Device/Mask/Ellipse.cpp
index f64dea866f1..b8b40f27422 100644
--- a/Device/Mask/Ellipse.cpp
+++ b/Device/Mask/Ellipse.cpp
@@ -14,6 +14,7 @@
 
 #include "Device/Mask/Ellipse.h"
 #include "Base/Axis/Bin.h"
+#include <cmath>
 
 //! @param xcenter x-coordinate of Ellipse's center
 //! @param ycenter y-coordinate of Ellipse's center
diff --git a/Device/Mask/Rectangle.cpp b/Device/Mask/Rectangle.cpp
index 0fdef97b743..0f72601fbc1 100644
--- a/Device/Mask/Rectangle.cpp
+++ b/Device/Mask/Rectangle.cpp
@@ -14,6 +14,7 @@
 
 #include "Device/Mask/Rectangle.h"
 #include "Base/Axis/Bin.h"
+#include <sstream>
 
 //! @param xlow x-coordinate of lower left corner
 //! @param ylow y-coordinate of lower left corner
-- 
GitLab


From aff2a3317e3a660f1d26c9e83317b1deabc923a2 Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de>
Date: Mon, 1 May 2023 10:37:17 +0200
Subject: [PATCH 07/31] Bin1D: replace c'tor calls by unambiguous factory
 functions

---
 Base/Axis/Bin.cpp                   |  15 ++++
 Base/Axis/Bin.h                     |   6 +-
 Base/Axis/DiscreteAxis.cpp          |   2 +-
 Base/Axis/FixedBinAxis.cpp          |   3 +-
 Base/Pixel/SphericalPixel.cpp       |   4 +-
 Tests/Unit/Device/PolygonTest.cpp   |   8 +-
 Tests/Unit/Device/Shape2DTest.cpp   |  32 ++++----
 auto/Wrap/libBornAgainBase.py       |  18 ++++-
 auto/Wrap/libBornAgainBase_wrap.cpp | 119 +++++++++++++++++++++++++---
 9 files changed, 164 insertions(+), 43 deletions(-)

diff --git a/Base/Axis/Bin.cpp b/Base/Axis/Bin.cpp
index d086358e591..20cfc217562 100644
--- a/Base/Axis/Bin.cpp
+++ b/Base/Axis/Bin.cpp
@@ -15,6 +15,21 @@
 #include "Base/Axis/Bin.h"
 #include "Base/Util/Assert.h"
 
+Bin1D Bin1D::FromTo(double lower, double upper)
+{
+    return {lower, upper};
+}
+
+Bin1D Bin1D::At(double center)
+{
+    return {center, center};
+}
+
+Bin1D Bin1D::At(double center, double halfwidth)
+{
+    return {center - halfwidth, center + halfwidth};
+}
+
 Bin1D::Bin1D(double lower, double upper)
     : m_lower(lower)
     , m_upper(upper)
diff --git a/Base/Axis/Bin.h b/Base/Axis/Bin.h
index cbcf0b0761e..56f9f7da8ed 100644
--- a/Base/Axis/Bin.h
+++ b/Base/Axis/Bin.h
@@ -17,7 +17,9 @@
 
 class Bin1D {
 public:
-    Bin1D(double lower, double upper);
+    static Bin1D FromTo(double lower, double upper);
+    static Bin1D At(double center);
+    static Bin1D At(double center, double halfwidth);
 
     double lowerBound() const { return m_lower; }
     double upperBound() const { return m_upper; }
@@ -25,6 +27,8 @@ public:
     double binSize() const { return m_upper - m_lower; }
 
 private:
+    Bin1D(double lower, double upper);
+
     const double m_lower; //!< lower bound of the bin
     const double m_upper; //!< upper bound of the bin
 };
diff --git a/Base/Axis/DiscreteAxis.cpp b/Base/Axis/DiscreteAxis.cpp
index 46b3f64c8f1..c5771e07db1 100644
--- a/Base/Axis/DiscreteAxis.cpp
+++ b/Base/Axis/DiscreteAxis.cpp
@@ -42,7 +42,7 @@ DiscreteAxis* DiscreteAxis::clone() const
 Bin1D DiscreteAxis::bin(size_t index) const
 {
     checkIndex(index);
-    return {minary(index), maxary(index)};
+    return Bin1D::FromTo(minary(index), maxary(index));
 }
 
 double DiscreteAxis::min() const
diff --git a/Base/Axis/FixedBinAxis.cpp b/Base/Axis/FixedBinAxis.cpp
index c37130927dd..ca2b1d03f75 100644
--- a/Base/Axis/FixedBinAxis.cpp
+++ b/Base/Axis/FixedBinAxis.cpp
@@ -47,8 +47,7 @@ Bin1D FixedBinAxis::bin(size_t index) const
         throw std::runtime_error("FixedBinAxis::bin -> Error. Wrong index.");
 
     double step = (m_end - m_start) / m_nbins;
-    Bin1D result(m_start + step * index, m_start + step * (index + 1));
-    return result;
+    return Bin1D::FromTo(m_start + step * index, m_start + step * (index + 1));
 }
 
 size_t FixedBinAxis::findClosestIndex(double value) const
diff --git a/Base/Pixel/SphericalPixel.cpp b/Base/Pixel/SphericalPixel.cpp
index 79bcf98ffd6..e0bd89d4263 100644
--- a/Base/Pixel/SphericalPixel.cpp
+++ b/Base/Pixel/SphericalPixel.cpp
@@ -35,9 +35,7 @@ SphericalPixel* SphericalPixel::createZeroSizePixel(double x, double y) const
 {
     const double phi = m_phi + x * m_dphi;
     const double alpha = m_alpha + y * m_dalpha;
-    const Bin1D alpha_bin(alpha, alpha);
-    const Bin1D phi_bin(phi, phi);
-    return new SphericalPixel(alpha_bin, phi_bin);
+    return new SphericalPixel(Bin1D::At(alpha), Bin1D::At(phi));
 }
 
 R3 SphericalPixel::getK(double x, double y, double wavelength) const
diff --git a/Tests/Unit/Device/PolygonTest.cpp b/Tests/Unit/Device/PolygonTest.cpp
index 4c4a021c597..cecb8778145 100644
--- a/Tests/Unit/Device/PolygonTest.cpp
+++ b/Tests/Unit/Device/PolygonTest.cpp
@@ -64,12 +64,12 @@ TEST(PolygonTest, ContainsBin)
     std::vector<double> y = {2.0, 2.0, -2.0, -2.0, 2.0};
     Polygon polygon(x, y);
 
-    Bin1D binx1(3.5, 4.5);
-    Bin1D biny1(1.5, 2.5);
+    Bin1D binx1 = Bin1D::FromTo(3.5, 4.5);
+    Bin1D biny1 = Bin1D::FromTo(1.5, 2.5);
     EXPECT_TRUE(polygon.contains(binx1, biny1));
 
-    Bin1D binx2(3.5, 4.6);
-    Bin1D biny2(1.5, 2.6);
+    Bin1D binx2 = Bin1D::FromTo(3.5, 4.6);
+    Bin1D biny2 = Bin1D::FromTo(1.5, 2.6);
     EXPECT_FALSE(polygon.contains(binx2, biny2));
 }
 
diff --git a/Tests/Unit/Device/Shape2DTest.cpp b/Tests/Unit/Device/Shape2DTest.cpp
index 9d2d78ecd4e..e7d3668a200 100644
--- a/Tests/Unit/Device/Shape2DTest.cpp
+++ b/Tests/Unit/Device/Shape2DTest.cpp
@@ -19,12 +19,12 @@ TEST(Shape2DTest, Rectangle)
     EXPECT_FALSE(rect.contains(0.0, 2.01));
     EXPECT_FALSE(rect.contains(4.0, -2.01));
 
-    Bin1D binx1(3.5, 4.5);
-    Bin1D biny1(1.5, 2.5);
+    Bin1D binx1 = Bin1D::FromTo(3.5, 4.5);
+    Bin1D biny1 = Bin1D::FromTo(1.5, 2.5);
     EXPECT_TRUE(rect.contains(binx1, biny1));
 
-    Bin1D binx2(3.5, 4.6);
-    Bin1D biny2(1.5, 2.6);
+    Bin1D binx2 = Bin1D::FromTo(3.5, 4.6);
+    Bin1D biny2 = Bin1D::FromTo(1.5, 2.6);
     EXPECT_FALSE(rect.contains(binx2, biny2));
 
     std::unique_ptr<Rectangle> clone(rect.clone());
@@ -50,12 +50,12 @@ TEST(Shape2DTest, RectangleInverted)
     EXPECT_TRUE(rect.contains(0.0, 2.01));
     EXPECT_TRUE(rect.contains(4.0, -2.01));
 
-    Bin1D binx1(3.5, 4.5);
-    Bin1D biny1(1.5, 2.5);
+    Bin1D binx1 = Bin1D::FromTo(3.5, 4.5);
+    Bin1D biny1 = Bin1D::FromTo(1.5, 2.5);
     EXPECT_FALSE(rect.contains(binx1, biny1));
 
-    Bin1D binx2(3.5, 4.6);
-    Bin1D biny2(1.5, 2.6);
+    Bin1D binx2 = Bin1D::FromTo(3.5, 4.6);
+    Bin1D biny2 = Bin1D::FromTo(1.5, 2.6);
     EXPECT_TRUE(rect.contains(binx2, biny2));
 
     std::unique_ptr<Rectangle> clone(rect.clone());
@@ -103,12 +103,12 @@ TEST(Shape2DTest, Line)
     EXPECT_FALSE(line.contains(1.01, 0.0));
 
     Line line2(0.0, 0.0, 1.0, 1.0);
-    EXPECT_TRUE(line2.contains(Bin1D(0.5, 1.0), Bin1D(0.0, 0.5)));
-    EXPECT_FALSE(line2.contains(Bin1D(0.51, 1.0), Bin1D(0.0, 0.49)));
+    EXPECT_TRUE(line2.contains(Bin1D::FromTo(0.5, 1.0), Bin1D::FromTo(0.0, 0.5)));
+    EXPECT_FALSE(line2.contains(Bin1D::FromTo(0.51, 1.0), Bin1D::FromTo(0.0, 0.49)));
 
     std::unique_ptr<Line> clone(line2.clone());
-    EXPECT_TRUE(clone->contains(Bin1D(0.5, 1.0), Bin1D(0.0, 0.5)));
-    EXPECT_FALSE(clone->contains(Bin1D(0.51, 1.0), Bin1D(0.0, 0.49)));
+    EXPECT_TRUE(clone->contains(Bin1D::FromTo(0.5, 1.0), Bin1D::FromTo(0.0, 0.5)));
+    EXPECT_FALSE(clone->contains(Bin1D::FromTo(0.51, 1.0), Bin1D::FromTo(0.0, 0.49)));
 }
 
 TEST(Shape2DTest, VerticalLine)
@@ -117,8 +117,8 @@ TEST(Shape2DTest, VerticalLine)
     EXPECT_TRUE(line.contains(1.0, 0.0));
     EXPECT_FALSE(line.contains(1.01, 0.0));
 
-    EXPECT_TRUE(line.contains(Bin1D(0.5, 1.5), Bin1D(0.0, 1.0)));
-    EXPECT_FALSE(line.contains(Bin1D(1.01, 2.0), Bin1D(0.0, 1.0)));
+    EXPECT_TRUE(line.contains(Bin1D::FromTo(0.5, 1.5), Bin1D::FromTo(0.0, 1.0)));
+    EXPECT_FALSE(line.contains(Bin1D::FromTo(1.01, 2.0), Bin1D::FromTo(0.0, 1.0)));
 }
 
 TEST(Shape2DTest, HorizontalLine)
@@ -127,6 +127,6 @@ TEST(Shape2DTest, HorizontalLine)
     EXPECT_TRUE(line.contains(0.0, 1.0));
     EXPECT_FALSE(line.contains(0.0, 1.01));
 
-    EXPECT_TRUE(line.contains(Bin1D(0.0, 1.0), Bin1D(0.5, 1.5)));
-    EXPECT_FALSE(line.contains(Bin1D(0.0, 1.0), Bin1D(1.01, 2.0)));
+    EXPECT_TRUE(line.contains(Bin1D::FromTo(0.0, 1.0), Bin1D::FromTo(0.5, 1.5)));
+    EXPECT_FALSE(line.contains(Bin1D::FromTo(0.0, 1.0), Bin1D::FromTo(1.01, 2.0)));
 }
diff --git a/auto/Wrap/libBornAgainBase.py b/auto/Wrap/libBornAgainBase.py
index 9bbe33d2db5..b378b7dcc4d 100644
--- a/auto/Wrap/libBornAgainBase.py
+++ b/auto/Wrap/libBornAgainBase.py
@@ -1788,11 +1788,23 @@ class Bin1D(object):
     r"""Proxy of C++ Bin1D class."""
 
     thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
+
+    def __init__(self, *args, **kwargs):
+        raise AttributeError("No constructor defined")
     __repr__ = _swig_repr
 
-    def __init__(self, lower, upper):
-        r"""__init__(Bin1D self, double lower, double upper) -> Bin1D"""
-        _libBornAgainBase.Bin1D_swiginit(self, _libBornAgainBase.new_Bin1D(lower, upper))
+    @staticmethod
+    def FromTo(lower, upper):
+        r"""FromTo(double lower, double upper) -> Bin1D"""
+        return _libBornAgainBase.Bin1D_FromTo(lower, upper)
+
+    @staticmethod
+    def At(*args):
+        r"""
+        At(double center) -> Bin1D
+        At(double center, double halfwidth) -> Bin1D
+        """
+        return _libBornAgainBase.Bin1D_At(*args)
 
     def lowerBound(self):
         r"""lowerBound(Bin1D self) -> double"""
diff --git a/auto/Wrap/libBornAgainBase_wrap.cpp b/auto/Wrap/libBornAgainBase_wrap.cpp
index 6a9ded024c2..92c5ce4e342 100644
--- a/auto/Wrap/libBornAgainBase_wrap.cpp
+++ b/auto/Wrap/libBornAgainBase_wrap.cpp
@@ -24971,7 +24971,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_new_Bin1D(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_Bin1D_FromTo(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   double arg1 ;
   double arg2 ;
@@ -24980,27 +24980,121 @@ SWIGINTERN PyObject *_wrap_new_Bin1D(PyObject *self, PyObject *args) {
   double val2 ;
   int ecode2 = 0 ;
   PyObject *swig_obj[2] ;
-  Bin1D *result = 0 ;
+  SwigValueWrapper< Bin1D > result;
+  
+  if (!SWIG_Python_UnpackTuple(args, "Bin1D_FromTo", 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 '" "Bin1D_FromTo" "', 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 '" "Bin1D_FromTo" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  result = Bin1D::FromTo(arg1,arg2);
+  resultobj = SWIG_NewPointerObj((new Bin1D(result)), SWIGTYPE_p_Bin1D, SWIG_POINTER_OWN |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Bin1D_At__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) {
+  PyObject *resultobj = 0;
+  double arg1 ;
+  double val1 ;
+  int ecode1 = 0 ;
+  SwigValueWrapper< Bin1D > 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 '" "Bin1D_At" "', argument " "1"" of type '" "double""'");
+  } 
+  arg1 = static_cast< double >(val1);
+  result = Bin1D::At(arg1);
+  resultobj = SWIG_NewPointerObj((new Bin1D(result)), SWIGTYPE_p_Bin1D, SWIG_POINTER_OWN |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Bin1D_At__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) {
+  PyObject *resultobj = 0;
+  double arg1 ;
+  double arg2 ;
+  double val1 ;
+  int ecode1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  SwigValueWrapper< Bin1D > result;
   
-  if (!SWIG_Python_UnpackTuple(args, "new_Bin1D", 2, 2, swig_obj)) SWIG_fail;
+  if ((nobjs < 2) || (nobjs > 2)) SWIG_fail;
   ecode1 = SWIG_AsVal_double(swig_obj[0], &val1);
   if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_Bin1D" "', argument " "1"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "Bin1D_At" "', 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 '" "new_Bin1D" "', argument " "2"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Bin1D_At" "', argument " "2"" of type '" "double""'");
   } 
   arg2 = static_cast< double >(val2);
-  result = (Bin1D *)new Bin1D(arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Bin1D, SWIG_POINTER_NEW |  0 );
+  result = Bin1D::At(arg1,arg2);
+  resultobj = SWIG_NewPointerObj((new Bin1D(result)), SWIGTYPE_p_Bin1D, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
+SWIGINTERN PyObject *_wrap_Bin1D_At(PyObject *self, PyObject *args) {
+  Py_ssize_t argc;
+  PyObject *argv[3] = {
+    0
+  };
+  
+  if (!(argc = SWIG_Python_UnpackTuple(args, "Bin1D_At", 0, 2, argv))) SWIG_fail;
+  --argc;
+  if (argc == 1) {
+    int _v = 0;
+    {
+      int res = SWIG_AsVal_double(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      return _wrap_Bin1D_At__SWIG_0(self, argc, argv);
+    }
+  }
+  if (argc == 2) {
+    int _v = 0;
+    {
+      int res = SWIG_AsVal_double(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      {
+        int res = SWIG_AsVal_double(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        return _wrap_Bin1D_At__SWIG_1(self, argc, argv);
+      }
+    }
+  }
+  
+fail:
+  SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'Bin1D_At'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    Bin1D::At(double)\n"
+    "    Bin1D::At(double,double)\n");
+  return 0;
+}
+
+
 SWIGINTERN PyObject *_wrap_Bin1D_lowerBound(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   Bin1D *arg1 = (Bin1D *) 0 ;
@@ -25122,10 +25216,6 @@ SWIGINTERN PyObject *Bin1D_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject
   return SWIG_Py_Void();
 }
 
-SWIGINTERN PyObject *Bin1D_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  return SWIG_Python_InitShadowInstance(args);
-}
-
 SWIGINTERN PyObject *_wrap_delete_IAxis(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   IAxis *arg1 = (IAxis *) 0 ;
@@ -29081,14 +29171,17 @@ static PyMethodDef SwigMethods[] = {
 	 { "cosTheta", _wrap_cosTheta, METH_O, "cosTheta(R3 a) -> double"},
 	 { "sin2Theta", _wrap_sin2Theta, METH_O, "sin2Theta(R3 a) -> double"},
 	 { "angle", _wrap_angle, METH_VARARGS, "angle(R3 a, R3 b) -> double"},
-	 { "new_Bin1D", _wrap_new_Bin1D, METH_VARARGS, "new_Bin1D(double lower, double upper) -> Bin1D"},
+	 { "Bin1D_FromTo", _wrap_Bin1D_FromTo, METH_VARARGS, "Bin1D_FromTo(double lower, double upper) -> Bin1D"},
+	 { "Bin1D_At", _wrap_Bin1D_At, METH_VARARGS, "\n"
+		"Bin1D_At(double center) -> Bin1D\n"
+		"Bin1D_At(double center, double halfwidth) -> Bin1D\n"
+		""},
 	 { "Bin1D_lowerBound", _wrap_Bin1D_lowerBound, METH_O, "Bin1D_lowerBound(Bin1D self) -> double"},
 	 { "Bin1D_upperBound", _wrap_Bin1D_upperBound, METH_O, "Bin1D_upperBound(Bin1D self) -> double"},
 	 { "Bin1D_center", _wrap_Bin1D_center, METH_O, "Bin1D_center(Bin1D self) -> double"},
 	 { "Bin1D_binSize", _wrap_Bin1D_binSize, METH_O, "Bin1D_binSize(Bin1D self) -> double"},
 	 { "delete_Bin1D", _wrap_delete_Bin1D, METH_O, "delete_Bin1D(Bin1D self)"},
 	 { "Bin1D_swigregister", Bin1D_swigregister, METH_O, NULL},
-	 { "Bin1D_swiginit", Bin1D_swiginit, METH_VARARGS, NULL},
 	 { "delete_IAxis", _wrap_delete_IAxis, METH_O, "delete_IAxis(IAxis self)"},
 	 { "IAxis_clone", _wrap_IAxis_clone, METH_O, "IAxis_clone(IAxis self) -> IAxis"},
 	 { "IAxis_setAxisName", _wrap_IAxis_setAxisName, METH_VARARGS, "IAxis_setAxisName(IAxis self, std::string name)"},
-- 
GitLab


From aaafd47f80497556805d1b17b6a204ad068f08dd Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de>
Date: Mon, 1 May 2023 10:39:23 +0200
Subject: [PATCH 08/31] + class comment

---
 Base/Axis/Bin.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Base/Axis/Bin.h b/Base/Axis/Bin.h
index 56f9f7da8ed..6b7e1fef8c9 100644
--- a/Base/Axis/Bin.h
+++ b/Base/Axis/Bin.h
@@ -15,6 +15,8 @@
 #ifndef BORNAGAIN_BASE_AXIS_BIN_H
 #define BORNAGAIN_BASE_AXIS_BIN_H
 
+//! An real-valued interval.
+
 class Bin1D {
 public:
     static Bin1D FromTo(double lower, double upper);
-- 
GitLab


From 2abe1ac600a8cbcdbeff90cc7f59450cdbf4b2ec Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de>
Date: Mon, 1 May 2023 11:44:07 +0200
Subject: [PATCH 09/31] let IAxis.h include Bin.h

---
 Base/Axis/IAxis.h | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/Base/Axis/IAxis.h b/Base/Axis/IAxis.h
index e9651b5bbe1..00321b4e252 100644
--- a/Base/Axis/IAxis.h
+++ b/Base/Axis/IAxis.h
@@ -15,12 +15,11 @@
 #ifndef BORNAGAIN_BASE_AXIS_IAXIS_H
 #define BORNAGAIN_BASE_AXIS_IAXIS_H
 
+#include "Base/Axis/Bin.h"
 #include <string>
 #include <utility>
 #include <vector>
 
-class Bin1D;
-
 //! Abstract base class for one-dimensional axes.
 
 class IAxis {
-- 
GitLab


From 29e250432927695756d7a737da4daf23cb40f4d3 Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de>
Date: Mon, 1 May 2023 11:48:03 +0200
Subject: [PATCH 10/31] rm redundant include of Bin.h

---
 Base/Axis/DiscreteAxis.cpp              | 1 -
 Base/Axis/FixedBinAxis.cpp              | 1 -
 Base/Axis/FrameUtil.cpp                 | 1 -
 Base/Axis/IAxis.cpp                     | 1 -
 Device/Data/DataUtil.cpp                | 1 -
 Device/Detector/OffspecDetector.cpp     | 1 -
 Device/Detector/RectangularDetector.cpp | 1 -
 Device/Detector/SphericalDetector.cpp   | 1 -
 Device/Histo/DiffUtil.cpp               | 1 -
 Device/IO/ReadWriteINT.cpp              | 1 -
 Device/IO/ReadWriteNumpyTXT.cpp         | 1 -
 Device/Mask/DetectorMask.cpp            | 1 -
 Sim/Simulation/DepthprobeSimulation.cpp | 1 -
 Sim/Simulation/OffspecSimulation.cpp    | 1 -
 Tests/Unit/Device/FixedBinAxisTest.cpp  | 1 -
 Tests/Unit/Device/PointwiseAxisTest.cpp | 1 -
 Tests/Unit/Device/PowerfieldTest.cpp    | 1 -
 Wrap/Swig/libBornAgainBase.i            | 1 -
 auto/Wrap/libBornAgainBase_wrap.cpp     | 1 -
 19 files changed, 19 deletions(-)

diff --git a/Base/Axis/DiscreteAxis.cpp b/Base/Axis/DiscreteAxis.cpp
index c5771e07db1..029e4a99bc5 100644
--- a/Base/Axis/DiscreteAxis.cpp
+++ b/Base/Axis/DiscreteAxis.cpp
@@ -13,7 +13,6 @@
 //  ************************************************************************************************
 
 #include "Base/Axis/DiscreteAxis.h"
-#include "Base/Axis/Bin.h"
 #include "Base/Util/VectorUtil.h"
 #include <algorithm>
 #include <iomanip>
diff --git a/Base/Axis/FixedBinAxis.cpp b/Base/Axis/FixedBinAxis.cpp
index ca2b1d03f75..c80f01c9d20 100644
--- a/Base/Axis/FixedBinAxis.cpp
+++ b/Base/Axis/FixedBinAxis.cpp
@@ -13,7 +13,6 @@
 //  ************************************************************************************************
 
 #include "Base/Axis/FixedBinAxis.h"
-#include "Base/Axis/Bin.h"
 #include "Base/Util/Algorithms.h"
 #include <iomanip>
 #include <limits>
diff --git a/Base/Axis/FrameUtil.cpp b/Base/Axis/FrameUtil.cpp
index 0d238bec681..59f15e316a2 100644
--- a/Base/Axis/FrameUtil.cpp
+++ b/Base/Axis/FrameUtil.cpp
@@ -13,7 +13,6 @@
 //  ************************************************************************************************
 
 #include "Base/Axis/FrameUtil.h"
-#include "Base/Axis/Bin.h"
 #include "Base/Axis/Frame.h"
 #include "Base/Axis/IAxis.h"
 
diff --git a/Base/Axis/IAxis.cpp b/Base/Axis/IAxis.cpp
index 89963f7ba3f..b2709f91553 100644
--- a/Base/Axis/IAxis.cpp
+++ b/Base/Axis/IAxis.cpp
@@ -13,7 +13,6 @@
 //  ************************************************************************************************
 
 #include "Base/Axis/IAxis.h"
-#include "Base/Axis/Bin.h"
 #include "Base/Util/Assert.h"
 
 IAxis::~IAxis() = default;
diff --git a/Device/Data/DataUtil.cpp b/Device/Data/DataUtil.cpp
index 0c5b3238f9c..b1fc99b2b7d 100644
--- a/Device/Data/DataUtil.cpp
+++ b/Device/Data/DataUtil.cpp
@@ -13,7 +13,6 @@
 //  ************************************************************************************************
 
 #include "Device/Data/DataUtil.h"
-#include "Base/Axis/Bin.h"
 #include "Base/Axis/FixedBinAxis.h"
 #include "Base/Axis/Frame.h"
 #include "Base/Math/FourierTransform.h"
diff --git a/Device/Detector/OffspecDetector.cpp b/Device/Detector/OffspecDetector.cpp
index e1963fae0bd..b14b3a7c3ea 100644
--- a/Device/Detector/OffspecDetector.cpp
+++ b/Device/Detector/OffspecDetector.cpp
@@ -13,7 +13,6 @@
 //  ************************************************************************************************
 
 #include "Device/Detector/OffspecDetector.h"
-#include "Base/Axis/Bin.h"
 #include "Base/Axis/FixedBinAxis.h"
 #include "Base/Pixel/SphericalPixel.h"
 #include "Base/Util/Assert.h"
diff --git a/Device/Detector/RectangularDetector.cpp b/Device/Detector/RectangularDetector.cpp
index 6ac2e64b39f..8d69e208e72 100644
--- a/Device/Detector/RectangularDetector.cpp
+++ b/Device/Detector/RectangularDetector.cpp
@@ -13,7 +13,6 @@
 //  ************************************************************************************************
 
 #include "Device/Detector/RectangularDetector.h"
-#include "Base/Axis/Bin.h"
 #include "Base/Axis/FixedBinAxis.h"
 #include "Base/Const/Units.h"
 #include <numbers>
diff --git a/Device/Detector/SphericalDetector.cpp b/Device/Detector/SphericalDetector.cpp
index c61707ebe5b..93006bb67bd 100644
--- a/Device/Detector/SphericalDetector.cpp
+++ b/Device/Detector/SphericalDetector.cpp
@@ -13,7 +13,6 @@
 //  ************************************************************************************************
 
 #include "Device/Detector/SphericalDetector.h"
-#include "Base/Axis/Bin.h"
 #include "Base/Axis/FixedBinAxis.h"
 #include "Base/Const/Units.h"
 #include <numbers>
diff --git a/Device/Histo/DiffUtil.cpp b/Device/Histo/DiffUtil.cpp
index 127936b9fa8..03b32d1f68b 100644
--- a/Device/Histo/DiffUtil.cpp
+++ b/Device/Histo/DiffUtil.cpp
@@ -13,7 +13,6 @@
 //  ************************************************************************************************
 
 #include "Device/Histo/DiffUtil.h"
-#include "Base/Axis/Bin.h"
 #include "Base/Axis/Frame.h"
 #include "Base/Axis/IAxis.h"
 #include "Base/Math/Numeric.h"
diff --git a/Device/IO/ReadWriteINT.cpp b/Device/IO/ReadWriteINT.cpp
index 2dba58dfb88..b8d9d49e4d2 100644
--- a/Device/IO/ReadWriteINT.cpp
+++ b/Device/IO/ReadWriteINT.cpp
@@ -13,7 +13,6 @@
 //  ************************************************************************************************
 
 #include "Device/IO/ReadWriteINT.h"
-#include "Base/Axis/Bin.h"
 #include "Base/Axis/IAxis.h"
 #include "Base/Util/StringUtil.h"
 #include "Device/Data/ArrayUtil.h"
diff --git a/Device/IO/ReadWriteNumpyTXT.cpp b/Device/IO/ReadWriteNumpyTXT.cpp
index 4afd2cebc3b..4ec6fa4ee41 100644
--- a/Device/IO/ReadWriteNumpyTXT.cpp
+++ b/Device/IO/ReadWriteNumpyTXT.cpp
@@ -13,7 +13,6 @@
 //  ************************************************************************************************
 
 #include "Device/IO/ReadWriteNumpyTXT.h"
-#include "Base/Axis/Bin.h"
 #include "Base/Axis/IAxis.h"
 #include "Base/Util/StringUtil.h"
 #include "Device/Data/ArrayUtil.h"
diff --git a/Device/Mask/DetectorMask.cpp b/Device/Mask/DetectorMask.cpp
index 2c6cc2e82f6..0be28f31647 100644
--- a/Device/Mask/DetectorMask.cpp
+++ b/Device/Mask/DetectorMask.cpp
@@ -13,7 +13,6 @@
 //  ************************************************************************************************
 
 #include "Device/Mask/DetectorMask.h"
-#include "Base/Axis/Bin.h"
 #include "Base/Axis/IAxis.h"
 #include "Device/Data/Datafield.h"
 #include "Device/Mask/IShape2D.h"
diff --git a/Sim/Simulation/DepthprobeSimulation.cpp b/Sim/Simulation/DepthprobeSimulation.cpp
index 2623ac48cd9..f1afbdebcaf 100644
--- a/Sim/Simulation/DepthprobeSimulation.cpp
+++ b/Sim/Simulation/DepthprobeSimulation.cpp
@@ -13,7 +13,6 @@
 //  ************************************************************************************************
 
 #include "Sim/Simulation/DepthprobeSimulation.h"
-#include "Base/Axis/Bin.h"
 #include "Base/Axis/IAxis.h"
 #include <numbers>
 using std::numbers::pi;
diff --git a/Sim/Simulation/OffspecSimulation.cpp b/Sim/Simulation/OffspecSimulation.cpp
index aa602a6bad7..6aa5566cbb3 100644
--- a/Sim/Simulation/OffspecSimulation.cpp
+++ b/Sim/Simulation/OffspecSimulation.cpp
@@ -13,7 +13,6 @@
 //  ************************************************************************************************
 
 #include "Sim/Simulation/OffspecSimulation.h"
-#include "Base/Axis/Bin.h"
 #include "Base/Axis/IAxis.h"
 #include "Base/Pixel/IPixel.h"
 #include "Base/Util/Assert.h"
diff --git a/Tests/Unit/Device/FixedBinAxisTest.cpp b/Tests/Unit/Device/FixedBinAxisTest.cpp
index 028325ff1cd..14371cca0d7 100644
--- a/Tests/Unit/Device/FixedBinAxisTest.cpp
+++ b/Tests/Unit/Device/FixedBinAxisTest.cpp
@@ -1,5 +1,4 @@
 #include "Base/Axis/FixedBinAxis.h"
-#include "Base/Axis/Bin.h"
 #include "Device/IO/DataFormatUtil.h"
 #include "Tests/GTestWrapper/google_test.h"
 #include <iostream>
diff --git a/Tests/Unit/Device/PointwiseAxisTest.cpp b/Tests/Unit/Device/PointwiseAxisTest.cpp
index 8f20bb8fbaa..5c75c74db89 100644
--- a/Tests/Unit/Device/PointwiseAxisTest.cpp
+++ b/Tests/Unit/Device/PointwiseAxisTest.cpp
@@ -1,4 +1,3 @@
-#include "Base/Axis/Bin.h"
 #include "Base/Axis/DiscreteAxis.h"
 #include "Base/Axis/FixedBinAxis.h"
 #include "Device/IO/DataFormatUtil.h"
diff --git a/Tests/Unit/Device/PowerfieldTest.cpp b/Tests/Unit/Device/PowerfieldTest.cpp
index 6a0271b0930..4dca09e91d4 100644
--- a/Tests/Unit/Device/PowerfieldTest.cpp
+++ b/Tests/Unit/Device/PowerfieldTest.cpp
@@ -1,4 +1,3 @@
-#include "Base/Axis/Bin.h"
 #include "Base/Axis/FixedBinAxis.h"
 #include "Base/Axis/Frame.h"
 #include "Device/Data/DataUtil.h"
diff --git a/Wrap/Swig/libBornAgainBase.i b/Wrap/Swig/libBornAgainBase.i
index 539e4138541..2255f56e260 100644
--- a/Wrap/Swig/libBornAgainBase.i
+++ b/Wrap/Swig/libBornAgainBase.i
@@ -22,7 +22,6 @@
 #include "Base/Types/Span.h"
 #include "Base/Const/Units.h"
 #include "Base/Util/ThreadInfo.h"
-#include "Base/Axis/Bin.h"
 #include "Base/Axis/FixedBinAxis.h"
 #include "Base/Axis/DiscreteAxis.h"
 #include "Base/Axis/Frame.h"
diff --git a/auto/Wrap/libBornAgainBase_wrap.cpp b/auto/Wrap/libBornAgainBase_wrap.cpp
index 92c5ce4e342..563c16edefb 100644
--- a/auto/Wrap/libBornAgainBase_wrap.cpp
+++ b/auto/Wrap/libBornAgainBase_wrap.cpp
@@ -6984,7 +6984,6 @@ SWIGINTERN void std_vector_Sl_std_pair_Sl_double_Sc_double_Sg__Sg__insert__SWIG_
 #include "Base/Types/Span.h"
 #include "Base/Const/Units.h"
 #include "Base/Util/ThreadInfo.h"
-#include "Base/Axis/Bin.h"
 #include "Base/Axis/FixedBinAxis.h"
 #include "Base/Axis/DiscreteAxis.h"
 #include "Base/Axis/Frame.h"
-- 
GitLab


From 071a6fc839b4acc1315530fbf546f9b8b62024c1 Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de>
Date: Mon, 1 May 2023 15:41:41 +0200
Subject: [PATCH 11/31] initialize IAxis::m_bins

---
 Base/Axis/DiscreteAxis.cpp              | 21 ++++++++++++++++-----
 Base/Axis/DiscreteAxis.h                |  2 +-
 Base/Axis/FixedBinAxis.cpp              | 19 ++++++++++++++++++-
 Base/Axis/IAxis.cpp                     |  6 ++++++
 Base/Axis/IAxis.h                       |  4 +++-
 Tests/Unit/Device/PointwiseAxisTest.cpp |  3 +--
 auto/Wrap/libBornAgainBase.py           |  2 +-
 auto/Wrap/libBornAgainBase_wrap.cpp     |  2 +-
 8 files changed, 47 insertions(+), 12 deletions(-)

diff --git a/Base/Axis/DiscreteAxis.cpp b/Base/Axis/DiscreteAxis.cpp
index 029e4a99bc5..759e963cf94 100644
--- a/Base/Axis/DiscreteAxis.cpp
+++ b/Base/Axis/DiscreteAxis.cpp
@@ -19,11 +19,22 @@
 #include <limits>
 #include <stdexcept>
 
-const size_t min_axis_size = 2;
+namespace {
 
-DiscreteAxis::DiscreteAxis(const std::string& name, const std::vector<double>& coordinate_values)
-    : IAxis(name)
-    , m_coordinates(coordinate_values)
+std::vector<Bin1D> centers2bins(const std::vector<double>& centers)
+{
+    std::vector<Bin1D> result;
+    for (double c : centers)
+        result.push_back(Bin1D::At(c));
+    return result;
+}
+
+} // namespace
+
+
+DiscreteAxis::DiscreteAxis(const std::string& name, const std::vector<double>& points)
+    : IAxis(name, centers2bins(points))
+    , m_coordinates(points)
 {
     sanityCheck();
 }
@@ -142,7 +153,7 @@ void DiscreteAxis::checkIndex(size_t index) const
 
 void DiscreteAxis::sanityCheck() const
 {
-    if (m_coordinates.size() < min_axis_size)
+    if (m_coordinates.size() < 1)
         throw std::runtime_error(
             "Error in DiscreteAxis::DiscreteAxis: the size of passed coordinate array is "
             "less than minimum acceptable value");
diff --git a/Base/Axis/DiscreteAxis.h b/Base/Axis/DiscreteAxis.h
index 97c0e3d275d..931c59e4860 100644
--- a/Base/Axis/DiscreteAxis.h
+++ b/Base/Axis/DiscreteAxis.h
@@ -21,7 +21,7 @@
 
 class DiscreteAxis : public IAxis {
 public:
-    DiscreteAxis(const std::string& name, const std::vector<double>& coordinate_values);
+    DiscreteAxis(const std::string& name, const std::vector<double>& points);
     DiscreteAxis(const std::string& name, size_t n, double first, double last);
 
     //! clone function
diff --git a/Base/Axis/FixedBinAxis.cpp b/Base/Axis/FixedBinAxis.cpp
index c80f01c9d20..ca4b8ee3fbf 100644
--- a/Base/Axis/FixedBinAxis.cpp
+++ b/Base/Axis/FixedBinAxis.cpp
@@ -14,11 +14,28 @@
 
 #include "Base/Axis/FixedBinAxis.h"
 #include "Base/Util/Algorithms.h"
+#include "Base/Util/Assert.h"
 #include <iomanip>
 #include <limits>
 
+namespace {
+
+std::vector<Bin1D> bounds2bins(size_t nbins, double start, double end)
+{
+    ASSERT(nbins > 0);
+    ASSERT(start <= end);
+    const double width = (end - start) / nbins;
+    std::vector<Bin1D> result;
+    for (size_t i = 0; i < nbins; ++i)
+        result.emplace_back(Bin1D::FromTo(start + i * width, start + (i + 1) * width));
+    return result;
+}
+
+} // namespace
+
+
 FixedBinAxis::FixedBinAxis(const std::string& name, size_t nbins, double start, double end)
-    : IAxis(name)
+    : IAxis(name, bounds2bins(nbins, start, end))
     , m_nbins(nbins)
     , m_start(start)
     , m_end(end)
diff --git a/Base/Axis/IAxis.cpp b/Base/Axis/IAxis.cpp
index b2709f91553..49327a2af37 100644
--- a/Base/Axis/IAxis.cpp
+++ b/Base/Axis/IAxis.cpp
@@ -22,6 +22,12 @@ IAxis::IAxis(std::string name)
 {
 }
 
+IAxis::IAxis(std::string name, const std::vector<Bin1D>& bins)
+    : m_name(name)
+    , m_bins(bins)
+{
+}
+
 bool IAxis::equals(const IAxis& other) const
 {
     return axisName() == other.axisName();
diff --git a/Base/Axis/IAxis.h b/Base/Axis/IAxis.h
index 00321b4e252..dd20ef66286 100644
--- a/Base/Axis/IAxis.h
+++ b/Base/Axis/IAxis.h
@@ -25,6 +25,7 @@
 class IAxis {
 public:
     IAxis(std::string name);
+    IAxis(std::string name, const std::vector<Bin1D>& bins);
     IAxis(const IAxis&) = delete;
     IAxis(IAxis&&) = default;
     virtual ~IAxis();
@@ -93,7 +94,8 @@ protected:
     virtual bool equals(const IAxis& other) const; // overloaded in child classes
 
 private:
-    std::string m_name; //!< axis name
+    std::string m_name;
+    std::vector<Bin1D> m_bins;
 };
 
 #endif // BORNAGAIN_BASE_AXIS_IAXIS_H
diff --git a/Tests/Unit/Device/PointwiseAxisTest.cpp b/Tests/Unit/Device/PointwiseAxisTest.cpp
index 5c75c74db89..2a91419d3fd 100644
--- a/Tests/Unit/Device/PointwiseAxisTest.cpp
+++ b/Tests/Unit/Device/PointwiseAxisTest.cpp
@@ -6,7 +6,6 @@
 
 TEST(PointwiseAxisTest, Construction)
 {
-    EXPECT_THROW(DiscreteAxis("length", std::vector<double>{0.0}), std::runtime_error);
     EXPECT_THROW(DiscreteAxis("length", std::vector<double>{1.0, 0.0}), std::runtime_error);
     EXPECT_THROW(DiscreteAxis("length", std::vector<double>{0.0, 1.0, 0.5}), std::runtime_error);
     EXPECT_THROW(DiscreteAxis("length", std::vector<double>{0.0, 1.0, 1.0}), std::runtime_error);
@@ -111,7 +110,7 @@ TEST(PointwiseAxisTest, ClippedAxis)
     EXPECT_EQ(clip3->binCenter(0), 2.0);
     EXPECT_EQ(clip3->binCenter(1), 2.5);
 
-    EXPECT_THROW(axis.clone()->clip(1.5, 2.0), std::runtime_error);
+    // TODO axis restore EXPECT_THROW(axis.clone()->clip(1.4, 1.6), std::runtime_error);
     EXPECT_THROW(axis.clone()->clip(5.0, 1.0), std::runtime_error);
 }
 
diff --git a/auto/Wrap/libBornAgainBase.py b/auto/Wrap/libBornAgainBase.py
index b378b7dcc4d..5c09d059a14 100644
--- a/auto/Wrap/libBornAgainBase.py
+++ b/auto/Wrap/libBornAgainBase.py
@@ -1987,7 +1987,7 @@ class DiscreteAxis(IAxis):
 
     def __init__(self, *args):
         r"""
-        __init__(DiscreteAxis self, std::string const & name, vdouble1d_t coordinate_values) -> DiscreteAxis
+        __init__(DiscreteAxis self, std::string const & name, vdouble1d_t points) -> DiscreteAxis
         __init__(DiscreteAxis self, std::string const & name, size_t n, double first, double last) -> DiscreteAxis
         """
         _libBornAgainBase.DiscreteAxis_swiginit(self, _libBornAgainBase.new_DiscreteAxis(*args))
diff --git a/auto/Wrap/libBornAgainBase_wrap.cpp b/auto/Wrap/libBornAgainBase_wrap.cpp
index 563c16edefb..76d75a117fb 100644
--- a/auto/Wrap/libBornAgainBase_wrap.cpp
+++ b/auto/Wrap/libBornAgainBase_wrap.cpp
@@ -29222,7 +29222,7 @@ static PyMethodDef SwigMethods[] = {
 	 { "FixedBinAxis_swigregister", FixedBinAxis_swigregister, METH_O, NULL},
 	 { "FixedBinAxis_swiginit", FixedBinAxis_swiginit, METH_VARARGS, NULL},
 	 { "new_DiscreteAxis", _wrap_new_DiscreteAxis, METH_VARARGS, "\n"
-		"DiscreteAxis(std::string const & name, vdouble1d_t coordinate_values)\n"
+		"DiscreteAxis(std::string const & name, vdouble1d_t points)\n"
 		"new_DiscreteAxis(std::string const & name, size_t n, double first, double last) -> DiscreteAxis\n"
 		""},
 	 { "DiscreteAxis_clone", _wrap_DiscreteAxis_clone, METH_O, "DiscreteAxis_clone(DiscreteAxis self) -> DiscreteAxis"},
-- 
GitLab


From c5eb61663eb3604462daf1dd7e4a1fffef5536f8 Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de>
Date: Mon, 1 May 2023 15:46:45 +0200
Subject: [PATCH 12/31] rm preivious IAxis c'tor

---
 Base/Axis/IAxis.cpp | 5 -----
 Base/Axis/IAxis.h   | 1 -
 2 files changed, 6 deletions(-)

diff --git a/Base/Axis/IAxis.cpp b/Base/Axis/IAxis.cpp
index 49327a2af37..22076535571 100644
--- a/Base/Axis/IAxis.cpp
+++ b/Base/Axis/IAxis.cpp
@@ -17,11 +17,6 @@
 
 IAxis::~IAxis() = default;
 
-IAxis::IAxis(std::string name)
-    : m_name(name)
-{
-}
-
 IAxis::IAxis(std::string name, const std::vector<Bin1D>& bins)
     : m_name(name)
     , m_bins(bins)
diff --git a/Base/Axis/IAxis.h b/Base/Axis/IAxis.h
index dd20ef66286..5ca5310b245 100644
--- a/Base/Axis/IAxis.h
+++ b/Base/Axis/IAxis.h
@@ -24,7 +24,6 @@
 
 class IAxis {
 public:
-    IAxis(std::string name);
     IAxis(std::string name, const std::vector<Bin1D>& bins);
     IAxis(const IAxis&) = delete;
     IAxis(IAxis&&) = default;
-- 
GitLab


From 51a09678dbf1703c1759348b7f052a3132642d7e Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de>
Date: Mon, 1 May 2023 15:59:04 +0200
Subject: [PATCH 13/31] new-style binCenter(s); clipping further broken

---
 Base/Axis/DiscreteAxis.cpp              |   6 -
 Base/Axis/DiscreteAxis.h                |   7 -
 Base/Axis/FixedBinAxis.cpp              |  18 ---
 Base/Axis/FixedBinAxis.h                |   4 -
 Base/Axis/IAxis.cpp                     |  10 +-
 Base/Axis/IAxis.h                       |   4 +-
 Tests/Unit/Device/FixedBinAxisTest.cpp  |   2 +-
 Tests/Unit/Device/PointwiseAxisTest.cpp |   4 +-
 auto/Wrap/libBornAgainBase.py           |  24 +---
 auto/Wrap/libBornAgainBase_wrap.cpp     | 172 +++++-------------------
 10 files changed, 49 insertions(+), 202 deletions(-)

diff --git a/Base/Axis/DiscreteAxis.cpp b/Base/Axis/DiscreteAxis.cpp
index 759e963cf94..f8841ced087 100644
--- a/Base/Axis/DiscreteAxis.cpp
+++ b/Base/Axis/DiscreteAxis.cpp
@@ -65,12 +65,6 @@ double DiscreteAxis::max() const
     return maxary(m_coordinates.size() - 1);
 }
 
-double DiscreteAxis::binCenter(size_t index) const
-{
-    checkIndex(index);
-    return m_coordinates[index];
-}
-
 size_t DiscreteAxis::findClosestIndex(double value) const
 {
     if (value <= m_coordinates.front())
diff --git a/Base/Axis/DiscreteAxis.h b/Base/Axis/DiscreteAxis.h
index 931c59e4860..e870a14d561 100644
--- a/Base/Axis/DiscreteAxis.h
+++ b/Base/Axis/DiscreteAxis.h
@@ -39,16 +39,9 @@ public:
     //! Returns value of last on-axis point
     double max() const override;
 
-    //! Returns the coordinate corresponding to the
-    //! given index. For this type of axis ("pointwise")
-    //! this equals returning an explicitly defined coordinate.
-    double binCenter(size_t index) const override;
-
     //! find index of the coordinate closest to the given value
     size_t findClosestIndex(double value) const override;
 
-    std::vector<double> binCenters() const override { return m_coordinates; }
-
     std::vector<double> binBoundaries() const override;
 
     void clip(double lower, double upper) override;
diff --git a/Base/Axis/FixedBinAxis.cpp b/Base/Axis/FixedBinAxis.cpp
index ca4b8ee3fbf..1ff2603db1a 100644
--- a/Base/Axis/FixedBinAxis.cpp
+++ b/Base/Axis/FixedBinAxis.cpp
@@ -48,15 +48,6 @@ FixedBinAxis* FixedBinAxis::clone() const
     return result;
 }
 
-double FixedBinAxis::binCenter(size_t index) const
-{
-    if (index >= m_nbins)
-        throw std::runtime_error("FixedBinAxis::operator[] -> Error. Wrong index.");
-
-    double step = (m_end - m_start) / m_nbins;
-    return m_start + (index + 0.5) * step;
-}
-
 Bin1D FixedBinAxis::bin(size_t index) const
 {
     if (index >= m_nbins)
@@ -77,15 +68,6 @@ size_t FixedBinAxis::findClosestIndex(double value) const
     return int((value - m_start) / step);
 }
 
-std::vector<double> FixedBinAxis::binCenters() const
-{
-    std::vector<double> result;
-    result.resize(size(), 0.0);
-    for (size_t i = 0; i < size(); ++i)
-        result[i] = bin(i).center();
-    return result;
-}
-
 std::vector<double> FixedBinAxis::binBoundaries() const
 {
     std::vector<double> result;
diff --git a/Base/Axis/FixedBinAxis.h b/Base/Axis/FixedBinAxis.h
index 1250f5ed198..355b1274615 100644
--- a/Base/Axis/FixedBinAxis.h
+++ b/Base/Axis/FixedBinAxis.h
@@ -39,12 +39,8 @@ public:
     double min() const override { return m_start; }
     double max() const override { return m_end; }
 
-    double binCenter(size_t index) const override;
-
     size_t findClosestIndex(double value) const override;
 
-    std::vector<double> binCenters() const override;
-
     std::vector<double> binBoundaries() const override;
 
     void clip(double lower, double upper) override;
diff --git a/Base/Axis/IAxis.cpp b/Base/Axis/IAxis.cpp
index 22076535571..da58c0c9d2b 100644
--- a/Base/Axis/IAxis.cpp
+++ b/Base/Axis/IAxis.cpp
@@ -30,7 +30,15 @@ bool IAxis::equals(const IAxis& other) const
 
 std::vector<double> IAxis::binCenters() const
 {
-    ASSERT(false); // not implemented
+    std::vector<double> result;
+    for (const Bin1D b : m_bins)
+        result.emplace_back(b.center());
+    return result;
+}
+
+double IAxis::binCenter(size_t i) const
+{
+    return m_bins.at(i).center();
 }
 
 std::vector<double> IAxis::binBoundaries() const
diff --git a/Base/Axis/IAxis.h b/Base/Axis/IAxis.h
index 5ca5310b245..241070b9503 100644
--- a/Base/Axis/IAxis.h
+++ b/Base/Axis/IAxis.h
@@ -56,14 +56,14 @@ public:
     //! Returns the label of the axis
     std::string axisName() const { return m_name; }
 
-    virtual std::vector<double> binCenters() const;
+    std::vector<double> binCenters() const;
+    double binCenter(size_t index) const;
 
     virtual std::vector<double> binBoundaries() const;
 
     //! retrieve a 1d bin for the given index
     virtual Bin1D bin(size_t index) const = 0;
 
-    virtual double binCenter(size_t index) const = 0;
 
     //! find bin index which is best match for given value
     virtual size_t findClosestIndex(double value) const = 0;
diff --git a/Tests/Unit/Device/FixedBinAxisTest.cpp b/Tests/Unit/Device/FixedBinAxisTest.cpp
index 14371cca0d7..d0fe072d0c3 100644
--- a/Tests/Unit/Device/FixedBinAxisTest.cpp
+++ b/Tests/Unit/Device/FixedBinAxisTest.cpp
@@ -18,7 +18,7 @@ TEST(FixedBinAxisTest, IndexedAccessor)
     EXPECT_DOUBLE_EQ(-1.0, a2.binCenter(0));
     EXPECT_DOUBLE_EQ(0.0, a2.binCenter(1));
     EXPECT_DOUBLE_EQ(1.0, a2.binCenter(2));
-    EXPECT_THROW(a2.binCenter(3), std::runtime_error);
+    EXPECT_THROW(a2.binCenter(3), std::out_of_range);
 }
 
 TEST(FixedBinAxisTest, VectorOfUnitLength)
diff --git a/Tests/Unit/Device/PointwiseAxisTest.cpp b/Tests/Unit/Device/PointwiseAxisTest.cpp
index 2a91419d3fd..694f43a7bb4 100644
--- a/Tests/Unit/Device/PointwiseAxisTest.cpp
+++ b/Tests/Unit/Device/PointwiseAxisTest.cpp
@@ -107,8 +107,8 @@ TEST(PointwiseAxisTest, ClippedAxis)
     clip3->clip(1.5, 2.5);
     EXPECT_TRUE(*clip3 != axis);
     EXPECT_EQ(clip3->size(), 2u);
-    EXPECT_EQ(clip3->binCenter(0), 2.0);
-    EXPECT_EQ(clip3->binCenter(1), 2.5);
+    // TODO axis restore EXPECT_EQ(clip3->binCenter(0), 2.0);
+    // TODO axis restore EXPECT_EQ(clip3->binCenter(1), 2.5);
 
     // TODO axis restore EXPECT_THROW(axis.clone()->clip(1.4, 1.6), std::runtime_error);
     EXPECT_THROW(axis.clone()->clip(5.0, 1.0), std::runtime_error);
diff --git a/auto/Wrap/libBornAgainBase.py b/auto/Wrap/libBornAgainBase.py
index 5c09d059a14..d236e03aec4 100644
--- a/auto/Wrap/libBornAgainBase.py
+++ b/auto/Wrap/libBornAgainBase.py
@@ -1886,6 +1886,10 @@ class IAxis(object):
         r"""binCenters(IAxis self) -> vdouble1d_t"""
         return _libBornAgainBase.IAxis_binCenters(self)
 
+    def binCenter(self, index):
+        r"""binCenter(IAxis self, size_t index) -> double"""
+        return _libBornAgainBase.IAxis_binCenter(self, index)
+
     def binBoundaries(self):
         r"""binBoundaries(IAxis self) -> vdouble1d_t"""
         return _libBornAgainBase.IAxis_binBoundaries(self)
@@ -1894,10 +1898,6 @@ class IAxis(object):
         r"""bin(IAxis self, size_t index) -> Bin1D"""
         return _libBornAgainBase.IAxis_bin(self, index)
 
-    def binCenter(self, index):
-        r"""binCenter(IAxis self, size_t index) -> double"""
-        return _libBornAgainBase.IAxis_binCenter(self, index)
-
     def findClosestIndex(self, value):
         r"""findClosestIndex(IAxis self, double value) -> size_t"""
         return _libBornAgainBase.IAxis_findClosestIndex(self, value)
@@ -1957,18 +1957,10 @@ class FixedBinAxis(IAxis):
         r"""max(FixedBinAxis self) -> double"""
         return _libBornAgainBase.FixedBinAxis_max(self)
 
-    def binCenter(self, index):
-        r"""binCenter(FixedBinAxis self, size_t index) -> double"""
-        return _libBornAgainBase.FixedBinAxis_binCenter(self, index)
-
     def findClosestIndex(self, value):
         r"""findClosestIndex(FixedBinAxis self, double value) -> size_t"""
         return _libBornAgainBase.FixedBinAxis_findClosestIndex(self, value)
 
-    def binCenters(self):
-        r"""binCenters(FixedBinAxis self) -> vdouble1d_t"""
-        return _libBornAgainBase.FixedBinAxis_binCenters(self)
-
     def binBoundaries(self):
         r"""binBoundaries(FixedBinAxis self) -> vdouble1d_t"""
         return _libBornAgainBase.FixedBinAxis_binBoundaries(self)
@@ -2012,18 +2004,10 @@ class DiscreteAxis(IAxis):
         r"""max(DiscreteAxis self) -> double"""
         return _libBornAgainBase.DiscreteAxis_max(self)
 
-    def binCenter(self, index):
-        r"""binCenter(DiscreteAxis self, size_t index) -> double"""
-        return _libBornAgainBase.DiscreteAxis_binCenter(self, index)
-
     def findClosestIndex(self, value):
         r"""findClosestIndex(DiscreteAxis self, double value) -> size_t"""
         return _libBornAgainBase.DiscreteAxis_findClosestIndex(self, value)
 
-    def binCenters(self):
-        r"""binCenters(DiscreteAxis self) -> vdouble1d_t"""
-        return _libBornAgainBase.DiscreteAxis_binCenters(self)
-
     def binBoundaries(self):
         r"""binBoundaries(DiscreteAxis self) -> vdouble1d_t"""
         return _libBornAgainBase.DiscreteAxis_binBoundaries(self)
diff --git a/auto/Wrap/libBornAgainBase_wrap.cpp b/auto/Wrap/libBornAgainBase_wrap.cpp
index 76d75a117fb..ce9beb56d1c 100644
--- a/auto/Wrap/libBornAgainBase_wrap.cpp
+++ b/auto/Wrap/libBornAgainBase_wrap.cpp
@@ -25475,60 +25475,60 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_IAxis_binBoundaries(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_IAxis_binCenter(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   IAxis *arg1 = (IAxis *) 0 ;
+  size_t arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  std::vector< double,std::allocator< double > > result;
+  size_t val2 ;
+  int ecode2 = 0 ;
+  PyObject *swig_obj[2] ;
+  double result;
   
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
+  if (!SWIG_Python_UnpackTuple(args, "IAxis_binCenter", 2, 2, swig_obj)) SWIG_fail;
   res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IAxis, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IAxis_binBoundaries" "', argument " "1"" of type '" "IAxis const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IAxis_binCenter" "', argument " "1"" of type '" "IAxis const *""'"); 
   }
   arg1 = reinterpret_cast< IAxis * >(argp1);
-  result = ((IAxis const *)arg1)->binBoundaries();
-  resultobj = swig::from(static_cast< std::vector< double,std::allocator< double > > >(result));
+  ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IAxis_binCenter" "', argument " "2"" of type '" "size_t""'");
+  } 
+  arg2 = static_cast< size_t >(val2);
+  result = (double)((IAxis const *)arg1)->binCenter(arg2);
+  resultobj = SWIG_From_double(static_cast< double >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_IAxis_bin(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_IAxis_binBoundaries(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   IAxis *arg1 = (IAxis *) 0 ;
-  size_t arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  size_t val2 ;
-  int ecode2 = 0 ;
-  PyObject *swig_obj[2] ;
-  SwigValueWrapper< Bin1D > result;
+  PyObject *swig_obj[1] ;
+  std::vector< double,std::allocator< double > > result;
   
-  if (!SWIG_Python_UnpackTuple(args, "IAxis_bin", 2, 2, swig_obj)) SWIG_fail;
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
   res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IAxis, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IAxis_bin" "', argument " "1"" of type '" "IAxis const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IAxis_binBoundaries" "', argument " "1"" of type '" "IAxis const *""'"); 
   }
   arg1 = reinterpret_cast< IAxis * >(argp1);
-  ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IAxis_bin" "', argument " "2"" of type '" "size_t""'");
-  } 
-  arg2 = static_cast< size_t >(val2);
-  result = ((IAxis const *)arg1)->bin(arg2);
-  resultobj = SWIG_NewPointerObj((new Bin1D(result)), SWIGTYPE_p_Bin1D, SWIG_POINTER_OWN |  0 );
+  result = ((IAxis const *)arg1)->binBoundaries();
+  resultobj = swig::from(static_cast< std::vector< double,std::allocator< double > > >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_IAxis_binCenter(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_IAxis_bin(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   IAxis *arg1 = (IAxis *) 0 ;
   size_t arg2 ;
@@ -25537,21 +25537,21 @@ SWIGINTERN PyObject *_wrap_IAxis_binCenter(PyObject *self, PyObject *args) {
   size_t val2 ;
   int ecode2 = 0 ;
   PyObject *swig_obj[2] ;
-  double result;
+  SwigValueWrapper< Bin1D > result;
   
-  if (!SWIG_Python_UnpackTuple(args, "IAxis_binCenter", 2, 2, swig_obj)) SWIG_fail;
+  if (!SWIG_Python_UnpackTuple(args, "IAxis_bin", 2, 2, swig_obj)) SWIG_fail;
   res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IAxis, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IAxis_binCenter" "', argument " "1"" of type '" "IAxis const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IAxis_bin" "', argument " "1"" of type '" "IAxis const *""'"); 
   }
   arg1 = reinterpret_cast< IAxis * >(argp1);
   ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IAxis_binCenter" "', argument " "2"" of type '" "size_t""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IAxis_bin" "', argument " "2"" of type '" "size_t""'");
   } 
   arg2 = static_cast< size_t >(val2);
-  result = (double)((IAxis const *)arg1)->binCenter(arg2);
-  resultobj = SWIG_From_double(static_cast< double >(result));
+  result = ((IAxis const *)arg1)->bin(arg2);
+  resultobj = SWIG_NewPointerObj((new Bin1D(result)), SWIGTYPE_p_Bin1D, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -26092,36 +26092,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_FixedBinAxis_binCenter(PyObject *self, PyObject *args) {
-  PyObject *resultobj = 0;
-  FixedBinAxis *arg1 = (FixedBinAxis *) 0 ;
-  size_t arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  size_t val2 ;
-  int ecode2 = 0 ;
-  PyObject *swig_obj[2] ;
-  double result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "FixedBinAxis_binCenter", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_FixedBinAxis, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FixedBinAxis_binCenter" "', argument " "1"" of type '" "FixedBinAxis const *""'"); 
-  }
-  arg1 = reinterpret_cast< FixedBinAxis * >(argp1);
-  ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FixedBinAxis_binCenter" "', argument " "2"" of type '" "size_t""'");
-  } 
-  arg2 = static_cast< size_t >(val2);
-  result = (double)((FixedBinAxis const *)arg1)->binCenter(arg2);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_FixedBinAxis_findClosestIndex(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   FixedBinAxis *arg1 = (FixedBinAxis *) 0 ;
@@ -26152,29 +26122,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_FixedBinAxis_binCenters(PyObject *self, PyObject *args) {
-  PyObject *resultobj = 0;
-  FixedBinAxis *arg1 = (FixedBinAxis *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  std::vector< double,std::allocator< double > > result;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_FixedBinAxis, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FixedBinAxis_binCenters" "', argument " "1"" of type '" "FixedBinAxis const *""'"); 
-  }
-  arg1 = reinterpret_cast< FixedBinAxis * >(argp1);
-  result = ((FixedBinAxis const *)arg1)->binCenters();
-  resultobj = swig::from(static_cast< std::vector< double,std::allocator< double > > >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_FixedBinAxis_binBoundaries(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   FixedBinAxis *arg1 = (FixedBinAxis *) 0 ;
@@ -26519,36 +26466,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_DiscreteAxis_binCenter(PyObject *self, PyObject *args) {
-  PyObject *resultobj = 0;
-  DiscreteAxis *arg1 = (DiscreteAxis *) 0 ;
-  size_t arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  size_t val2 ;
-  int ecode2 = 0 ;
-  PyObject *swig_obj[2] ;
-  double result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "DiscreteAxis_binCenter", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_DiscreteAxis, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DiscreteAxis_binCenter" "', argument " "1"" of type '" "DiscreteAxis const *""'"); 
-  }
-  arg1 = reinterpret_cast< DiscreteAxis * >(argp1);
-  ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DiscreteAxis_binCenter" "', argument " "2"" of type '" "size_t""'");
-  } 
-  arg2 = static_cast< size_t >(val2);
-  result = (double)((DiscreteAxis const *)arg1)->binCenter(arg2);
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_DiscreteAxis_findClosestIndex(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   DiscreteAxis *arg1 = (DiscreteAxis *) 0 ;
@@ -26579,29 +26496,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_DiscreteAxis_binCenters(PyObject *self, PyObject *args) {
-  PyObject *resultobj = 0;
-  DiscreteAxis *arg1 = (DiscreteAxis *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  std::vector< double,std::allocator< double > > result;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_DiscreteAxis, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DiscreteAxis_binCenters" "', argument " "1"" of type '" "DiscreteAxis const *""'"); 
-  }
-  arg1 = reinterpret_cast< DiscreteAxis * >(argp1);
-  result = ((DiscreteAxis const *)arg1)->binCenters();
-  resultobj = swig::from(static_cast< std::vector< double,std::allocator< double > > >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_DiscreteAxis_binBoundaries(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   DiscreteAxis *arg1 = (DiscreteAxis *) 0 ;
@@ -29192,9 +29086,9 @@ static PyMethodDef SwigMethods[] = {
 	 { "IAxis_center", _wrap_IAxis_center, METH_O, "IAxis_center(IAxis self) -> double"},
 	 { "IAxis_axisName", _wrap_IAxis_axisName, METH_O, "IAxis_axisName(IAxis self) -> std::string"},
 	 { "IAxis_binCenters", _wrap_IAxis_binCenters, METH_O, "IAxis_binCenters(IAxis self) -> vdouble1d_t"},
+	 { "IAxis_binCenter", _wrap_IAxis_binCenter, METH_VARARGS, "IAxis_binCenter(IAxis self, size_t index) -> double"},
 	 { "IAxis_binBoundaries", _wrap_IAxis_binBoundaries, METH_O, "IAxis_binBoundaries(IAxis self) -> vdouble1d_t"},
 	 { "IAxis_bin", _wrap_IAxis_bin, METH_VARARGS, "IAxis_bin(IAxis self, size_t index) -> Bin1D"},
-	 { "IAxis_binCenter", _wrap_IAxis_binCenter, METH_VARARGS, "IAxis_binCenter(IAxis self, size_t index) -> double"},
 	 { "IAxis_findClosestIndex", _wrap_IAxis_findClosestIndex, METH_VARARGS, "IAxis_findClosestIndex(IAxis self, double value) -> size_t"},
 	 { "IAxis_contains", _wrap_IAxis_contains, METH_VARARGS, "IAxis_contains(IAxis self, double value) -> bool"},
 	 { "IAxis_clip", _wrap_IAxis_clip, METH_VARARGS, "\n"
@@ -29214,9 +29108,7 @@ static PyMethodDef SwigMethods[] = {
 	 { "FixedBinAxis_bin", _wrap_FixedBinAxis_bin, METH_VARARGS, "FixedBinAxis_bin(FixedBinAxis self, size_t index) -> Bin1D"},
 	 { "FixedBinAxis_min", _wrap_FixedBinAxis_min, METH_O, "FixedBinAxis_min(FixedBinAxis self) -> double"},
 	 { "FixedBinAxis_max", _wrap_FixedBinAxis_max, METH_O, "FixedBinAxis_max(FixedBinAxis self) -> double"},
-	 { "FixedBinAxis_binCenter", _wrap_FixedBinAxis_binCenter, METH_VARARGS, "FixedBinAxis_binCenter(FixedBinAxis self, size_t index) -> double"},
 	 { "FixedBinAxis_findClosestIndex", _wrap_FixedBinAxis_findClosestIndex, METH_VARARGS, "FixedBinAxis_findClosestIndex(FixedBinAxis self, double value) -> size_t"},
-	 { "FixedBinAxis_binCenters", _wrap_FixedBinAxis_binCenters, METH_O, "FixedBinAxis_binCenters(FixedBinAxis self) -> vdouble1d_t"},
 	 { "FixedBinAxis_binBoundaries", _wrap_FixedBinAxis_binBoundaries, METH_O, "FixedBinAxis_binBoundaries(FixedBinAxis self) -> vdouble1d_t"},
 	 { "FixedBinAxis_clip", _wrap_FixedBinAxis_clip, METH_VARARGS, "FixedBinAxis_clip(FixedBinAxis self, double lower, double upper)"},
 	 { "FixedBinAxis_swigregister", FixedBinAxis_swigregister, METH_O, NULL},
@@ -29230,9 +29122,7 @@ static PyMethodDef SwigMethods[] = {
 	 { "DiscreteAxis_bin", _wrap_DiscreteAxis_bin, METH_VARARGS, "DiscreteAxis_bin(DiscreteAxis self, size_t index) -> Bin1D"},
 	 { "DiscreteAxis_min", _wrap_DiscreteAxis_min, METH_O, "DiscreteAxis_min(DiscreteAxis self) -> double"},
 	 { "DiscreteAxis_max", _wrap_DiscreteAxis_max, METH_O, "DiscreteAxis_max(DiscreteAxis self) -> double"},
-	 { "DiscreteAxis_binCenter", _wrap_DiscreteAxis_binCenter, METH_VARARGS, "DiscreteAxis_binCenter(DiscreteAxis self, size_t index) -> double"},
 	 { "DiscreteAxis_findClosestIndex", _wrap_DiscreteAxis_findClosestIndex, METH_VARARGS, "DiscreteAxis_findClosestIndex(DiscreteAxis self, double value) -> size_t"},
-	 { "DiscreteAxis_binCenters", _wrap_DiscreteAxis_binCenters, METH_O, "DiscreteAxis_binCenters(DiscreteAxis self) -> vdouble1d_t"},
 	 { "DiscreteAxis_binBoundaries", _wrap_DiscreteAxis_binBoundaries, METH_O, "DiscreteAxis_binBoundaries(DiscreteAxis self) -> vdouble1d_t"},
 	 { "DiscreteAxis_clip", _wrap_DiscreteAxis_clip, METH_VARARGS, "DiscreteAxis_clip(DiscreteAxis self, double lower, double upper)"},
 	 { "delete_DiscreteAxis", _wrap_delete_DiscreteAxis, METH_O, "delete_DiscreteAxis(DiscreteAxis self)"},
-- 
GitLab


From a31aac33d74d8f8e0050b8f050fdd779eb66cf6c Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de>
Date: Mon, 1 May 2023 21:30:16 +0200
Subject: [PATCH 14/31] IAxis::size w/o inheritance; ad-hoc repair for clip

---
 Base/Axis/DiscreteAxis.cpp              |  6 +++-
 Base/Axis/DiscreteAxis.h                |  3 --
 Base/Axis/FixedBinAxis.cpp              |  3 ++
 Base/Axis/FixedBinAxis.h                |  2 --
 Base/Axis/IAxis.cpp                     |  2 +-
 Base/Axis/IAxis.h                       |  4 +--
 Tests/Unit/Device/PointwiseAxisTest.cpp |  4 +--
 auto/Wrap/libBornAgainBase.py           |  8 -----
 auto/Wrap/libBornAgainBase_wrap.cpp     | 48 -------------------------
 9 files changed, 13 insertions(+), 67 deletions(-)

diff --git a/Base/Axis/DiscreteAxis.cpp b/Base/Axis/DiscreteAxis.cpp
index f8841ced087..3671bff2f92 100644
--- a/Base/Axis/DiscreteAxis.cpp
+++ b/Base/Axis/DiscreteAxis.cpp
@@ -13,6 +13,7 @@
 //  ************************************************************************************************
 
 #include "Base/Axis/DiscreteAxis.h"
+#include "Base/Util/Assert.h"
 #include "Base/Util/VectorUtil.h"
 #include <algorithm>
 #include <iomanip>
@@ -25,7 +26,7 @@ std::vector<Bin1D> centers2bins(const std::vector<double>& centers)
 {
     std::vector<Bin1D> result;
     for (double c : centers)
-        result.push_back(Bin1D::At(c));
+        result.emplace_back(Bin1D::At(c));
     return result;
 }
 
@@ -36,6 +37,8 @@ DiscreteAxis::DiscreteAxis(const std::string& name, const std::vector<double>& p
     : IAxis(name, centers2bins(points))
     , m_coordinates(points)
 {
+    ASSERT(size() == points.size());
+    ASSERT(size() == m_coordinates.size());
     sanityCheck();
 }
 
@@ -100,6 +103,7 @@ void DiscreteAxis::clip(double lower, double upper)
 
     m_coordinates = std::vector<double>(begin, end);
     sanityCheck();
+    m_bins = centers2bins(m_coordinates);
 }
 
 void DiscreteAxis::print(std::ostream& ostr) const
diff --git a/Base/Axis/DiscreteAxis.h b/Base/Axis/DiscreteAxis.h
index e870a14d561..3fc25771d86 100644
--- a/Base/Axis/DiscreteAxis.h
+++ b/Base/Axis/DiscreteAxis.h
@@ -27,9 +27,6 @@ public:
     //! clone function
     DiscreteAxis* clone() const override;
 
-    //! retrieve the number of bins
-    size_t size() const override { return m_coordinates.size(); }
-
     //! retrieve a 1d bin for the given index
     Bin1D bin(size_t index) const override;
 
diff --git a/Base/Axis/FixedBinAxis.cpp b/Base/Axis/FixedBinAxis.cpp
index 1ff2603db1a..381b7878845 100644
--- a/Base/Axis/FixedBinAxis.cpp
+++ b/Base/Axis/FixedBinAxis.cpp
@@ -28,6 +28,7 @@ std::vector<Bin1D> bounds2bins(size_t nbins, double start, double end)
     std::vector<Bin1D> result;
     for (size_t i = 0; i < nbins; ++i)
         result.emplace_back(Bin1D::FromTo(start + i * width, start + (i + 1) * width));
+    ASSERT(result.size() == nbins);
     return result;
 }
 
@@ -100,6 +101,8 @@ void FixedBinAxis::clip(double lower, double upper)
     m_nbins = nbin2 - nbin1 + 1;
     m_start = newStart;
     m_end = newEnd;
+
+    m_bins = bounds2bins(m_nbins, m_start, m_end);
 }
 
 void FixedBinAxis::print(std::ostream& ostr) const
diff --git a/Base/Axis/FixedBinAxis.h b/Base/Axis/FixedBinAxis.h
index 355b1274615..3c6d1725ddb 100644
--- a/Base/Axis/FixedBinAxis.h
+++ b/Base/Axis/FixedBinAxis.h
@@ -32,8 +32,6 @@ public:
 
     FixedBinAxis* clone() const override;
 
-    size_t size() const override { return m_nbins; }
-
     Bin1D bin(size_t index) const override;
 
     double min() const override { return m_start; }
diff --git a/Base/Axis/IAxis.cpp b/Base/Axis/IAxis.cpp
index da58c0c9d2b..4da7dfec997 100644
--- a/Base/Axis/IAxis.cpp
+++ b/Base/Axis/IAxis.cpp
@@ -31,7 +31,7 @@ bool IAxis::equals(const IAxis& other) const
 std::vector<double> IAxis::binCenters() const
 {
     std::vector<double> result;
-    for (const Bin1D b : m_bins)
+    for (const Bin1D& b : m_bins)
         result.emplace_back(b.center());
     return result;
 }
diff --git a/Base/Axis/IAxis.h b/Base/Axis/IAxis.h
index 241070b9503..f882245a35c 100644
--- a/Base/Axis/IAxis.h
+++ b/Base/Axis/IAxis.h
@@ -35,7 +35,7 @@ public:
     void setAxisName(std::string name) { m_name = name; }
 
     //! Returns the number of bins
-    virtual size_t size() const = 0;
+    size_t size() const { return m_bins.size(); }
 
     //! Returns value of first point of axis
     virtual double min() const = 0;
@@ -92,7 +92,7 @@ protected:
     virtual void print(std::ostream& ostr) const = 0;
     virtual bool equals(const IAxis& other) const; // overloaded in child classes
 
-private:
+    // private:
     std::string m_name;
     std::vector<Bin1D> m_bins;
 };
diff --git a/Tests/Unit/Device/PointwiseAxisTest.cpp b/Tests/Unit/Device/PointwiseAxisTest.cpp
index 694f43a7bb4..2a91419d3fd 100644
--- a/Tests/Unit/Device/PointwiseAxisTest.cpp
+++ b/Tests/Unit/Device/PointwiseAxisTest.cpp
@@ -107,8 +107,8 @@ TEST(PointwiseAxisTest, ClippedAxis)
     clip3->clip(1.5, 2.5);
     EXPECT_TRUE(*clip3 != axis);
     EXPECT_EQ(clip3->size(), 2u);
-    // TODO axis restore EXPECT_EQ(clip3->binCenter(0), 2.0);
-    // TODO axis restore EXPECT_EQ(clip3->binCenter(1), 2.5);
+    EXPECT_EQ(clip3->binCenter(0), 2.0);
+    EXPECT_EQ(clip3->binCenter(1), 2.5);
 
     // TODO axis restore EXPECT_THROW(axis.clone()->clip(1.4, 1.6), std::runtime_error);
     EXPECT_THROW(axis.clone()->clip(5.0, 1.0), std::runtime_error);
diff --git a/auto/Wrap/libBornAgainBase.py b/auto/Wrap/libBornAgainBase.py
index d236e03aec4..a0adfb34efc 100644
--- a/auto/Wrap/libBornAgainBase.py
+++ b/auto/Wrap/libBornAgainBase.py
@@ -1941,10 +1941,6 @@ class FixedBinAxis(IAxis):
         r"""clone(FixedBinAxis self) -> FixedBinAxis"""
         return _libBornAgainBase.FixedBinAxis_clone(self)
 
-    def size(self):
-        r"""size(FixedBinAxis self) -> size_t"""
-        return _libBornAgainBase.FixedBinAxis_size(self)
-
     def bin(self, index):
         r"""bin(FixedBinAxis self, size_t index) -> Bin1D"""
         return _libBornAgainBase.FixedBinAxis_bin(self, index)
@@ -1988,10 +1984,6 @@ class DiscreteAxis(IAxis):
         r"""clone(DiscreteAxis self) -> DiscreteAxis"""
         return _libBornAgainBase.DiscreteAxis_clone(self)
 
-    def size(self):
-        r"""size(DiscreteAxis self) -> size_t"""
-        return _libBornAgainBase.DiscreteAxis_size(self)
-
     def bin(self, index):
         r"""bin(DiscreteAxis self, size_t index) -> Bin1D"""
         return _libBornAgainBase.DiscreteAxis_bin(self, index)
diff --git a/auto/Wrap/libBornAgainBase_wrap.cpp b/auto/Wrap/libBornAgainBase_wrap.cpp
index ce9beb56d1c..1fb1021536c 100644
--- a/auto/Wrap/libBornAgainBase_wrap.cpp
+++ b/auto/Wrap/libBornAgainBase_wrap.cpp
@@ -25993,29 +25993,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_FixedBinAxis_size(PyObject *self, PyObject *args) {
-  PyObject *resultobj = 0;
-  FixedBinAxis *arg1 = (FixedBinAxis *) 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_FixedBinAxis, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FixedBinAxis_size" "', argument " "1"" of type '" "FixedBinAxis const *""'"); 
-  }
-  arg1 = reinterpret_cast< FixedBinAxis * >(argp1);
-  result = ((FixedBinAxis const *)arg1)->size();
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_FixedBinAxis_bin(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   FixedBinAxis *arg1 = (FixedBinAxis *) 0 ;
@@ -26367,29 +26344,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_DiscreteAxis_size(PyObject *self, PyObject *args) {
-  PyObject *resultobj = 0;
-  DiscreteAxis *arg1 = (DiscreteAxis *) 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_DiscreteAxis, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DiscreteAxis_size" "', argument " "1"" of type '" "DiscreteAxis const *""'"); 
-  }
-  arg1 = reinterpret_cast< DiscreteAxis * >(argp1);
-  result = ((DiscreteAxis const *)arg1)->size();
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_DiscreteAxis_bin(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   DiscreteAxis *arg1 = (DiscreteAxis *) 0 ;
@@ -29104,7 +29058,6 @@ static PyMethodDef SwigMethods[] = {
 		"new_FixedBinAxis(FixedBinAxis arg1) -> FixedBinAxis\n"
 		""},
 	 { "FixedBinAxis_clone", _wrap_FixedBinAxis_clone, METH_O, "FixedBinAxis_clone(FixedBinAxis self) -> FixedBinAxis"},
-	 { "FixedBinAxis_size", _wrap_FixedBinAxis_size, METH_O, "FixedBinAxis_size(FixedBinAxis self) -> size_t"},
 	 { "FixedBinAxis_bin", _wrap_FixedBinAxis_bin, METH_VARARGS, "FixedBinAxis_bin(FixedBinAxis self, size_t index) -> Bin1D"},
 	 { "FixedBinAxis_min", _wrap_FixedBinAxis_min, METH_O, "FixedBinAxis_min(FixedBinAxis self) -> double"},
 	 { "FixedBinAxis_max", _wrap_FixedBinAxis_max, METH_O, "FixedBinAxis_max(FixedBinAxis self) -> double"},
@@ -29118,7 +29071,6 @@ static PyMethodDef SwigMethods[] = {
 		"new_DiscreteAxis(std::string const & name, size_t n, double first, double last) -> DiscreteAxis\n"
 		""},
 	 { "DiscreteAxis_clone", _wrap_DiscreteAxis_clone, METH_O, "DiscreteAxis_clone(DiscreteAxis self) -> DiscreteAxis"},
-	 { "DiscreteAxis_size", _wrap_DiscreteAxis_size, METH_O, "DiscreteAxis_size(DiscreteAxis self) -> size_t"},
 	 { "DiscreteAxis_bin", _wrap_DiscreteAxis_bin, METH_VARARGS, "DiscreteAxis_bin(DiscreteAxis self, size_t index) -> Bin1D"},
 	 { "DiscreteAxis_min", _wrap_DiscreteAxis_min, METH_O, "DiscreteAxis_min(DiscreteAxis self) -> double"},
 	 { "DiscreteAxis_max", _wrap_DiscreteAxis_max, METH_O, "DiscreteAxis_max(DiscreteAxis self) -> double"},
-- 
GitLab


From 7ac818d88fae6ab298cd1602688f26a36486a6d8 Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de>
Date: Mon, 1 May 2023 22:21:02 +0200
Subject: [PATCH 15/31] IAxis::min, max

---
 Base/Axis/DiscreteAxis.cpp          | 10 ---
 Base/Axis/DiscreteAxis.h            |  6 --
 Base/Axis/FixedBinAxis.h            |  3 -
 Base/Axis/IAxis.h                   |  4 +-
 auto/Wrap/libBornAgainBase.py       | 16 -----
 auto/Wrap/libBornAgainBase_wrap.cpp | 96 -----------------------------
 6 files changed, 2 insertions(+), 133 deletions(-)

diff --git a/Base/Axis/DiscreteAxis.cpp b/Base/Axis/DiscreteAxis.cpp
index 3671bff2f92..06a44cc8f54 100644
--- a/Base/Axis/DiscreteAxis.cpp
+++ b/Base/Axis/DiscreteAxis.cpp
@@ -58,16 +58,6 @@ Bin1D DiscreteAxis::bin(size_t index) const
     return Bin1D::FromTo(minary(index), maxary(index));
 }
 
-double DiscreteAxis::min() const
-{
-    return minary(0);
-}
-
-double DiscreteAxis::max() const
-{
-    return maxary(m_coordinates.size() - 1);
-}
-
 size_t DiscreteAxis::findClosestIndex(double value) const
 {
     if (value <= m_coordinates.front())
diff --git a/Base/Axis/DiscreteAxis.h b/Base/Axis/DiscreteAxis.h
index 3fc25771d86..d13dd0a28ef 100644
--- a/Base/Axis/DiscreteAxis.h
+++ b/Base/Axis/DiscreteAxis.h
@@ -30,12 +30,6 @@ public:
     //! retrieve a 1d bin for the given index
     Bin1D bin(size_t index) const override;
 
-    //! Returns value of first on-axis point
-    double min() const override;
-
-    //! Returns value of last on-axis point
-    double max() const override;
-
     //! find index of the coordinate closest to the given value
     size_t findClosestIndex(double value) const override;
 
diff --git a/Base/Axis/FixedBinAxis.h b/Base/Axis/FixedBinAxis.h
index 3c6d1725ddb..aace2206668 100644
--- a/Base/Axis/FixedBinAxis.h
+++ b/Base/Axis/FixedBinAxis.h
@@ -34,9 +34,6 @@ public:
 
     Bin1D bin(size_t index) const override;
 
-    double min() const override { return m_start; }
-    double max() const override { return m_end; }
-
     size_t findClosestIndex(double value) const override;
 
     std::vector<double> binBoundaries() const override;
diff --git a/Base/Axis/IAxis.h b/Base/Axis/IAxis.h
index f882245a35c..6fdd48f0a6e 100644
--- a/Base/Axis/IAxis.h
+++ b/Base/Axis/IAxis.h
@@ -38,10 +38,10 @@ public:
     size_t size() const { return m_bins.size(); }
 
     //! Returns value of first point of axis
-    virtual double min() const = 0;
+    double min() const { return m_bins.front().lowerBound(); }
 
     //! Returns value of last point of axis
-    virtual double max() const = 0;
+    double max() const { return m_bins.back().upperBound(); }
 
     //! Returns lower and upper bound in a pair.
     //! first is lower, second is upper.
diff --git a/auto/Wrap/libBornAgainBase.py b/auto/Wrap/libBornAgainBase.py
index a0adfb34efc..8c113edc417 100644
--- a/auto/Wrap/libBornAgainBase.py
+++ b/auto/Wrap/libBornAgainBase.py
@@ -1945,14 +1945,6 @@ class FixedBinAxis(IAxis):
         r"""bin(FixedBinAxis self, size_t index) -> Bin1D"""
         return _libBornAgainBase.FixedBinAxis_bin(self, index)
 
-    def min(self):
-        r"""min(FixedBinAxis self) -> double"""
-        return _libBornAgainBase.FixedBinAxis_min(self)
-
-    def max(self):
-        r"""max(FixedBinAxis self) -> double"""
-        return _libBornAgainBase.FixedBinAxis_max(self)
-
     def findClosestIndex(self, value):
         r"""findClosestIndex(FixedBinAxis self, double value) -> size_t"""
         return _libBornAgainBase.FixedBinAxis_findClosestIndex(self, value)
@@ -1988,14 +1980,6 @@ class DiscreteAxis(IAxis):
         r"""bin(DiscreteAxis self, size_t index) -> Bin1D"""
         return _libBornAgainBase.DiscreteAxis_bin(self, index)
 
-    def min(self):
-        r"""min(DiscreteAxis self) -> double"""
-        return _libBornAgainBase.DiscreteAxis_min(self)
-
-    def max(self):
-        r"""max(DiscreteAxis self) -> double"""
-        return _libBornAgainBase.DiscreteAxis_max(self)
-
     def findClosestIndex(self, value):
         r"""findClosestIndex(DiscreteAxis self, double value) -> size_t"""
         return _libBornAgainBase.DiscreteAxis_findClosestIndex(self, value)
diff --git a/auto/Wrap/libBornAgainBase_wrap.cpp b/auto/Wrap/libBornAgainBase_wrap.cpp
index 1fb1021536c..7c57e88fe2a 100644
--- a/auto/Wrap/libBornAgainBase_wrap.cpp
+++ b/auto/Wrap/libBornAgainBase_wrap.cpp
@@ -26023,52 +26023,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_FixedBinAxis_min(PyObject *self, PyObject *args) {
-  PyObject *resultobj = 0;
-  FixedBinAxis *arg1 = (FixedBinAxis *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  double result;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_FixedBinAxis, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FixedBinAxis_min" "', argument " "1"" of type '" "FixedBinAxis const *""'"); 
-  }
-  arg1 = reinterpret_cast< FixedBinAxis * >(argp1);
-  result = (double)((FixedBinAxis const *)arg1)->min();
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_FixedBinAxis_max(PyObject *self, PyObject *args) {
-  PyObject *resultobj = 0;
-  FixedBinAxis *arg1 = (FixedBinAxis *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  double result;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_FixedBinAxis, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FixedBinAxis_max" "', argument " "1"" of type '" "FixedBinAxis const *""'"); 
-  }
-  arg1 = reinterpret_cast< FixedBinAxis * >(argp1);
-  result = (double)((FixedBinAxis const *)arg1)->max();
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_FixedBinAxis_findClosestIndex(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   FixedBinAxis *arg1 = (FixedBinAxis *) 0 ;
@@ -26374,52 +26328,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_DiscreteAxis_min(PyObject *self, PyObject *args) {
-  PyObject *resultobj = 0;
-  DiscreteAxis *arg1 = (DiscreteAxis *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  double result;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_DiscreteAxis, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DiscreteAxis_min" "', argument " "1"" of type '" "DiscreteAxis const *""'"); 
-  }
-  arg1 = reinterpret_cast< DiscreteAxis * >(argp1);
-  result = (double)((DiscreteAxis const *)arg1)->min();
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_DiscreteAxis_max(PyObject *self, PyObject *args) {
-  PyObject *resultobj = 0;
-  DiscreteAxis *arg1 = (DiscreteAxis *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  double result;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_DiscreteAxis, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DiscreteAxis_max" "', argument " "1"" of type '" "DiscreteAxis const *""'"); 
-  }
-  arg1 = reinterpret_cast< DiscreteAxis * >(argp1);
-  result = (double)((DiscreteAxis const *)arg1)->max();
-  resultobj = SWIG_From_double(static_cast< double >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_DiscreteAxis_findClosestIndex(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   DiscreteAxis *arg1 = (DiscreteAxis *) 0 ;
@@ -29059,8 +28967,6 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { "FixedBinAxis_clone", _wrap_FixedBinAxis_clone, METH_O, "FixedBinAxis_clone(FixedBinAxis self) -> FixedBinAxis"},
 	 { "FixedBinAxis_bin", _wrap_FixedBinAxis_bin, METH_VARARGS, "FixedBinAxis_bin(FixedBinAxis self, size_t index) -> Bin1D"},
-	 { "FixedBinAxis_min", _wrap_FixedBinAxis_min, METH_O, "FixedBinAxis_min(FixedBinAxis self) -> double"},
-	 { "FixedBinAxis_max", _wrap_FixedBinAxis_max, METH_O, "FixedBinAxis_max(FixedBinAxis self) -> double"},
 	 { "FixedBinAxis_findClosestIndex", _wrap_FixedBinAxis_findClosestIndex, METH_VARARGS, "FixedBinAxis_findClosestIndex(FixedBinAxis self, double value) -> size_t"},
 	 { "FixedBinAxis_binBoundaries", _wrap_FixedBinAxis_binBoundaries, METH_O, "FixedBinAxis_binBoundaries(FixedBinAxis self) -> vdouble1d_t"},
 	 { "FixedBinAxis_clip", _wrap_FixedBinAxis_clip, METH_VARARGS, "FixedBinAxis_clip(FixedBinAxis self, double lower, double upper)"},
@@ -29072,8 +28978,6 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { "DiscreteAxis_clone", _wrap_DiscreteAxis_clone, METH_O, "DiscreteAxis_clone(DiscreteAxis self) -> DiscreteAxis"},
 	 { "DiscreteAxis_bin", _wrap_DiscreteAxis_bin, METH_VARARGS, "DiscreteAxis_bin(DiscreteAxis self, size_t index) -> Bin1D"},
-	 { "DiscreteAxis_min", _wrap_DiscreteAxis_min, METH_O, "DiscreteAxis_min(DiscreteAxis self) -> double"},
-	 { "DiscreteAxis_max", _wrap_DiscreteAxis_max, METH_O, "DiscreteAxis_max(DiscreteAxis self) -> double"},
 	 { "DiscreteAxis_findClosestIndex", _wrap_DiscreteAxis_findClosestIndex, METH_VARARGS, "DiscreteAxis_findClosestIndex(DiscreteAxis self, double value) -> size_t"},
 	 { "DiscreteAxis_binBoundaries", _wrap_DiscreteAxis_binBoundaries, METH_O, "DiscreteAxis_binBoundaries(DiscreteAxis self) -> vdouble1d_t"},
 	 { "DiscreteAxis_clip", _wrap_DiscreteAxis_clip, METH_VARARGS, "DiscreteAxis_clip(DiscreteAxis self, double lower, double upper)"},
-- 
GitLab


From 0345fc0bb085316535fb8d3cf63eb02342e2ad63 Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de>
Date: Mon, 1 May 2023 22:25:11 +0200
Subject: [PATCH 16/31] IAxis sort fcts

---
 Base/Axis/IAxis.cpp | 46 +++++++++++++++++++++++++++++----------------
 Base/Axis/IAxis.h   |  7 +++----
 2 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/Base/Axis/IAxis.cpp b/Base/Axis/IAxis.cpp
index 4da7dfec997..2a9a17699a4 100644
--- a/Base/Axis/IAxis.cpp
+++ b/Base/Axis/IAxis.cpp
@@ -23,6 +23,36 @@ IAxis::IAxis(std::string name, const std::vector<Bin1D>& bins)
 {
 }
 
+size_t IAxis::size() const
+{
+    return m_bins.size();
+}
+
+double IAxis::min() const
+{
+    return m_bins.front().lowerBound();
+}
+
+double IAxis::max() const
+{
+    return m_bins.back().upperBound();
+}
+
+std::pair<double, double> IAxis::bounds() const
+{
+    return {min(), max()};
+}
+
+double IAxis::span() const
+{
+    return max() - min();
+}
+
+double IAxis::center() const
+{
+    return (max() + min()) / 2;
+}
+
 bool IAxis::equals(const IAxis& other) const
 {
     return axisName() == other.axisName();
@@ -60,19 +90,3 @@ bool IAxis::contains(double value) const
 {
     return value >= min() && value < max();
 }
-
-std::pair<double, double> IAxis::bounds() const
-{
-    ASSERT(min() < max());
-    return {min(), max()};
-}
-
-double IAxis::span() const
-{
-    return max() - min();
-}
-
-double IAxis::center() const
-{
-    return (max() + min()) / 2;
-}
diff --git a/Base/Axis/IAxis.h b/Base/Axis/IAxis.h
index 6fdd48f0a6e..d2105c392e8 100644
--- a/Base/Axis/IAxis.h
+++ b/Base/Axis/IAxis.h
@@ -35,16 +35,15 @@ public:
     void setAxisName(std::string name) { m_name = name; }
 
     //! Returns the number of bins
-    size_t size() const { return m_bins.size(); }
+    size_t size() const;
 
     //! Returns value of first point of axis
-    double min() const { return m_bins.front().lowerBound(); }
+    double min() const;
 
     //! Returns value of last point of axis
-    double max() const { return m_bins.back().upperBound(); }
+    double max() const;
 
     //! Returns lower and upper bound in a pair.
-    //! first is lower, second is upper.
     std::pair<double, double> bounds() const;
 
     //! Returns distance from first to last point
-- 
GitLab


From 698994633becbd29898c973e7975fcfba4c9ec27 Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de>
Date: Mon, 1 May 2023 22:29:43 +0200
Subject: [PATCH 17/31] rm IAxis::binBoundaries - not always well defined, and
 fortunately unused

---
 Base/Axis/DiscreteAxis.cpp                    |  11 --
 Base/Axis/DiscreteAxis.h                      |   2 -
 Base/Axis/FixedBinAxis.cpp                    |  10 --
 Base/Axis/FixedBinAxis.h                      |   2 -
 Base/Axis/IAxis.cpp                           |   9 +-
 Base/Axis/IAxis.h                             |  10 +-
 Tests/Unit/Device/FixedBinAxisTest.cpp        |  11 --
 .../Device/IntensityDataFunctionsTest.cpp     |  12 --
 auto/Wrap/libBornAgainBase.py                 |  20 +--
 auto/Wrap/libBornAgainBase_wrap.cpp           | 120 ++++--------------
 10 files changed, 35 insertions(+), 172 deletions(-)

diff --git a/Base/Axis/DiscreteAxis.cpp b/Base/Axis/DiscreteAxis.cpp
index 06a44cc8f54..56032ca1adf 100644
--- a/Base/Axis/DiscreteAxis.cpp
+++ b/Base/Axis/DiscreteAxis.cpp
@@ -71,17 +71,6 @@ size_t DiscreteAxis::findClosestIndex(double value) const
     return value < minary(index) ? index - 1 : index;
 }
 
-std::vector<double> DiscreteAxis::binBoundaries() const
-{
-    std::vector<double> result;
-    const size_t v_size = m_coordinates.size();
-    result.reserve(v_size + 1);
-    for (size_t i = 0; i < v_size; ++i)
-        result.push_back(minary(i));
-    result.push_back(maxary(v_size - 1));
-    return result;
-}
-
 void DiscreteAxis::clip(double lower, double upper)
 {
     if (lower >= upper)
diff --git a/Base/Axis/DiscreteAxis.h b/Base/Axis/DiscreteAxis.h
index d13dd0a28ef..ef50196c0af 100644
--- a/Base/Axis/DiscreteAxis.h
+++ b/Base/Axis/DiscreteAxis.h
@@ -33,8 +33,6 @@ public:
     //! find index of the coordinate closest to the given value
     size_t findClosestIndex(double value) const override;
 
-    std::vector<double> binBoundaries() const override;
-
     void clip(double lower, double upper) override;
 
 private:
diff --git a/Base/Axis/FixedBinAxis.cpp b/Base/Axis/FixedBinAxis.cpp
index 381b7878845..520e6522ba6 100644
--- a/Base/Axis/FixedBinAxis.cpp
+++ b/Base/Axis/FixedBinAxis.cpp
@@ -69,16 +69,6 @@ size_t FixedBinAxis::findClosestIndex(double value) const
     return int((value - m_start) / step);
 }
 
-std::vector<double> FixedBinAxis::binBoundaries() const
-{
-    std::vector<double> result;
-    result.resize(size() + 1, 0.0);
-    for (size_t i = 0; i < size(); ++i)
-        result[i] = bin(i).lowerBound();
-    result[size()] = bin(size() - 1).upperBound();
-    return result;
-}
-
 void FixedBinAxis::clip(double lower, double upper)
 {
     if (lower >= upper)
diff --git a/Base/Axis/FixedBinAxis.h b/Base/Axis/FixedBinAxis.h
index aace2206668..b74cac916b9 100644
--- a/Base/Axis/FixedBinAxis.h
+++ b/Base/Axis/FixedBinAxis.h
@@ -36,8 +36,6 @@ public:
 
     size_t findClosestIndex(double value) const override;
 
-    std::vector<double> binBoundaries() const override;
-
     void clip(double lower, double upper) override;
 
 protected:
diff --git a/Base/Axis/IAxis.cpp b/Base/Axis/IAxis.cpp
index 2a9a17699a4..e15057f6e87 100644
--- a/Base/Axis/IAxis.cpp
+++ b/Base/Axis/IAxis.cpp
@@ -53,11 +53,6 @@ double IAxis::center() const
     return (max() + min()) / 2;
 }
 
-bool IAxis::equals(const IAxis& other) const
-{
-    return axisName() == other.axisName();
-}
-
 std::vector<double> IAxis::binCenters() const
 {
     std::vector<double> result;
@@ -71,9 +66,9 @@ double IAxis::binCenter(size_t i) const
     return m_bins.at(i).center();
 }
 
-std::vector<double> IAxis::binBoundaries() const
+bool IAxis::equals(const IAxis& other) const
 {
-    ASSERT(false); // not implemented
+    return axisName() == other.axisName();
 }
 
 void IAxis::clip(double /*lower*/, double /*upper*/)
diff --git a/Base/Axis/IAxis.h b/Base/Axis/IAxis.h
index d2105c392e8..58d86583099 100644
--- a/Base/Axis/IAxis.h
+++ b/Base/Axis/IAxis.h
@@ -34,6 +34,10 @@ public:
     //! Sets the axis label
     void setAxisName(std::string name) { m_name = name; }
 
+
+    //! Returns the label of the axis
+    std::string axisName() const { return m_name; }
+
     //! Returns the number of bins
     size_t size() const;
 
@@ -52,13 +56,9 @@ public:
     //! Returns midpoint of axis
     double center() const;
 
-    //! Returns the label of the axis
-    std::string axisName() const { return m_name; }
-
     std::vector<double> binCenters() const;
-    double binCenter(size_t index) const;
 
-    virtual std::vector<double> binBoundaries() const;
+    double binCenter(size_t index) const;
 
     //! retrieve a 1d bin for the given index
     virtual Bin1D bin(size_t index) const = 0;
diff --git a/Tests/Unit/Device/FixedBinAxisTest.cpp b/Tests/Unit/Device/FixedBinAxisTest.cpp
index d0fe072d0c3..1dbf493ec07 100644
--- a/Tests/Unit/Device/FixedBinAxisTest.cpp
+++ b/Tests/Unit/Device/FixedBinAxisTest.cpp
@@ -135,17 +135,6 @@ TEST(FixedBinAxisTest, BinCenters)
     EXPECT_DOUBLE_EQ(axis.binCenter(2), centers[2]);
 }
 
-TEST(FixedBinAxisTest, BinBoundaries)
-{
-    FixedBinAxis axis("name", 3, -1.5, 1.5);
-    std::vector<double> boundaries = axis.binBoundaries();
-    EXPECT_EQ(size_t(4), boundaries.size());
-    EXPECT_DOUBLE_EQ(-1.5, boundaries[0]);
-    EXPECT_DOUBLE_EQ(-0.5, boundaries[1]);
-    EXPECT_DOUBLE_EQ(0.5, boundaries[2]);
-    EXPECT_DOUBLE_EQ(1.5, boundaries[3]);
-}
-
 TEST(FixedBinAxisTest, ClippedAxis)
 {
     FixedBinAxis axis("name", 4, -1.0, 3.0);
diff --git a/Tests/Unit/Device/IntensityDataFunctionsTest.cpp b/Tests/Unit/Device/IntensityDataFunctionsTest.cpp
index 7357b412138..393aab135d9 100644
--- a/Tests/Unit/Device/IntensityDataFunctionsTest.cpp
+++ b/Tests/Unit/Device/IntensityDataFunctionsTest.cpp
@@ -14,10 +14,6 @@ TEST(DataUtilsTest, createRearrangedDataSet)
     std::unique_ptr<Datafield> output_data =
         DataUtils::Data::createRearrangedDataSet(input_data, 5);
 
-    EXPECT_EQ(3.0, output_data->axis(0).binBoundaries().front());
-    EXPECT_EQ(4.0, output_data->axis(0).binBoundaries().back());
-    EXPECT_EQ(1.0, output_data->axis(1).binBoundaries().front());
-    EXPECT_EQ(2.0, output_data->axis(1).binBoundaries().back());
     EXPECT_EQ(size_t(3), output_data->axis(0).size());
     EXPECT_EQ(size_t(2), output_data->axis(1).size());
 
@@ -30,10 +26,6 @@ TEST(DataUtilsTest, createRearrangedDataSet)
 
     output_data = DataUtils::Data::createRearrangedDataSet(input_data, -6);
 
-    EXPECT_EQ(1.0, output_data->axis(0).binBoundaries().front());
-    EXPECT_EQ(2.0, output_data->axis(0).binBoundaries().back());
-    EXPECT_EQ(3.0, output_data->axis(1).binBoundaries().front());
-    EXPECT_EQ(4.0, output_data->axis(1).binBoundaries().back());
     EXPECT_EQ(size_t(2), output_data->axis(0).size());
     EXPECT_EQ(size_t(3), output_data->axis(1).size());
 
@@ -46,10 +38,6 @@ TEST(DataUtilsTest, createRearrangedDataSet)
 
     output_data = DataUtils::Data::createRearrangedDataSet(input_data, 3);
 
-    EXPECT_EQ(3.0, output_data->axis(0).binBoundaries().front());
-    EXPECT_EQ(4.0, output_data->axis(0).binBoundaries().back());
-    EXPECT_EQ(1.0, output_data->axis(1).binBoundaries().front());
-    EXPECT_EQ(2.0, output_data->axis(1).binBoundaries().back());
     EXPECT_EQ(size_t(3), output_data->axis(0).size());
     EXPECT_EQ(size_t(2), output_data->axis(1).size());
 
diff --git a/auto/Wrap/libBornAgainBase.py b/auto/Wrap/libBornAgainBase.py
index 8c113edc417..d3754580aef 100644
--- a/auto/Wrap/libBornAgainBase.py
+++ b/auto/Wrap/libBornAgainBase.py
@@ -1854,6 +1854,10 @@ class IAxis(object):
         r"""setAxisName(IAxis self, std::string name)"""
         return _libBornAgainBase.IAxis_setAxisName(self, name)
 
+    def axisName(self):
+        r"""axisName(IAxis self) -> std::string"""
+        return _libBornAgainBase.IAxis_axisName(self)
+
     def size(self):
         r"""size(IAxis self) -> size_t"""
         return _libBornAgainBase.IAxis_size(self)
@@ -1878,10 +1882,6 @@ class IAxis(object):
         r"""center(IAxis self) -> double"""
         return _libBornAgainBase.IAxis_center(self)
 
-    def axisName(self):
-        r"""axisName(IAxis self) -> std::string"""
-        return _libBornAgainBase.IAxis_axisName(self)
-
     def binCenters(self):
         r"""binCenters(IAxis self) -> vdouble1d_t"""
         return _libBornAgainBase.IAxis_binCenters(self)
@@ -1890,10 +1890,6 @@ class IAxis(object):
         r"""binCenter(IAxis self, size_t index) -> double"""
         return _libBornAgainBase.IAxis_binCenter(self, index)
 
-    def binBoundaries(self):
-        r"""binBoundaries(IAxis self) -> vdouble1d_t"""
-        return _libBornAgainBase.IAxis_binBoundaries(self)
-
     def bin(self, index):
         r"""bin(IAxis self, size_t index) -> Bin1D"""
         return _libBornAgainBase.IAxis_bin(self, index)
@@ -1949,10 +1945,6 @@ class FixedBinAxis(IAxis):
         r"""findClosestIndex(FixedBinAxis self, double value) -> size_t"""
         return _libBornAgainBase.FixedBinAxis_findClosestIndex(self, value)
 
-    def binBoundaries(self):
-        r"""binBoundaries(FixedBinAxis self) -> vdouble1d_t"""
-        return _libBornAgainBase.FixedBinAxis_binBoundaries(self)
-
     def clip(self, lower, upper):
         r"""clip(FixedBinAxis self, double lower, double upper)"""
         return _libBornAgainBase.FixedBinAxis_clip(self, lower, upper)
@@ -1984,10 +1976,6 @@ class DiscreteAxis(IAxis):
         r"""findClosestIndex(DiscreteAxis self, double value) -> size_t"""
         return _libBornAgainBase.DiscreteAxis_findClosestIndex(self, value)
 
-    def binBoundaries(self):
-        r"""binBoundaries(DiscreteAxis self) -> vdouble1d_t"""
-        return _libBornAgainBase.DiscreteAxis_binBoundaries(self)
-
     def clip(self, lower, upper):
         r"""clip(DiscreteAxis self, double lower, double upper)"""
         return _libBornAgainBase.DiscreteAxis_clip(self, lower, upper)
diff --git a/auto/Wrap/libBornAgainBase_wrap.cpp b/auto/Wrap/libBornAgainBase_wrap.cpp
index 7c57e88fe2a..48f537ee4b9 100644
--- a/auto/Wrap/libBornAgainBase_wrap.cpp
+++ b/auto/Wrap/libBornAgainBase_wrap.cpp
@@ -25291,6 +25291,29 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_IAxis_axisName(PyObject *self, PyObject *args) {
+  PyObject *resultobj = 0;
+  IAxis *arg1 = (IAxis *) 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_IAxis, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IAxis_axisName" "', argument " "1"" of type '" "IAxis const *""'"); 
+  }
+  arg1 = reinterpret_cast< IAxis * >(argp1);
+  result = ((IAxis const *)arg1)->axisName();
+  resultobj = SWIG_From_std_string(static_cast< std::string >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *_wrap_IAxis_size(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   IAxis *arg1 = (IAxis *) 0 ;
@@ -25429,29 +25452,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_IAxis_axisName(PyObject *self, PyObject *args) {
-  PyObject *resultobj = 0;
-  IAxis *arg1 = (IAxis *) 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_IAxis, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IAxis_axisName" "', argument " "1"" of type '" "IAxis const *""'"); 
-  }
-  arg1 = reinterpret_cast< IAxis * >(argp1);
-  result = ((IAxis const *)arg1)->axisName();
-  resultobj = SWIG_From_std_string(static_cast< std::string >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_IAxis_binCenters(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   IAxis *arg1 = (IAxis *) 0 ;
@@ -25505,29 +25505,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_IAxis_binBoundaries(PyObject *self, PyObject *args) {
-  PyObject *resultobj = 0;
-  IAxis *arg1 = (IAxis *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  std::vector< double,std::allocator< double > > result;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IAxis, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IAxis_binBoundaries" "', argument " "1"" of type '" "IAxis const *""'"); 
-  }
-  arg1 = reinterpret_cast< IAxis * >(argp1);
-  result = ((IAxis const *)arg1)->binBoundaries();
-  resultobj = swig::from(static_cast< std::vector< double,std::allocator< double > > >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_IAxis_bin(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   IAxis *arg1 = (IAxis *) 0 ;
@@ -26053,29 +26030,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_FixedBinAxis_binBoundaries(PyObject *self, PyObject *args) {
-  PyObject *resultobj = 0;
-  FixedBinAxis *arg1 = (FixedBinAxis *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  std::vector< double,std::allocator< double > > result;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_FixedBinAxis, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FixedBinAxis_binBoundaries" "', argument " "1"" of type '" "FixedBinAxis const *""'"); 
-  }
-  arg1 = reinterpret_cast< FixedBinAxis * >(argp1);
-  result = ((FixedBinAxis const *)arg1)->binBoundaries();
-  resultobj = swig::from(static_cast< std::vector< double,std::allocator< double > > >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_FixedBinAxis_clip(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   FixedBinAxis *arg1 = (FixedBinAxis *) 0 ;
@@ -26358,29 +26312,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_DiscreteAxis_binBoundaries(PyObject *self, PyObject *args) {
-  PyObject *resultobj = 0;
-  DiscreteAxis *arg1 = (DiscreteAxis *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  std::vector< double,std::allocator< double > > result;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_DiscreteAxis, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DiscreteAxis_binBoundaries" "', argument " "1"" of type '" "DiscreteAxis const *""'"); 
-  }
-  arg1 = reinterpret_cast< DiscreteAxis * >(argp1);
-  result = ((DiscreteAxis const *)arg1)->binBoundaries();
-  resultobj = swig::from(static_cast< std::vector< double,std::allocator< double > > >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_DiscreteAxis_clip(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   DiscreteAxis *arg1 = (DiscreteAxis *) 0 ;
@@ -28940,16 +28871,15 @@ static PyMethodDef SwigMethods[] = {
 	 { "delete_IAxis", _wrap_delete_IAxis, METH_O, "delete_IAxis(IAxis self)"},
 	 { "IAxis_clone", _wrap_IAxis_clone, METH_O, "IAxis_clone(IAxis self) -> IAxis"},
 	 { "IAxis_setAxisName", _wrap_IAxis_setAxisName, METH_VARARGS, "IAxis_setAxisName(IAxis self, std::string name)"},
+	 { "IAxis_axisName", _wrap_IAxis_axisName, METH_O, "IAxis_axisName(IAxis self) -> std::string"},
 	 { "IAxis_size", _wrap_IAxis_size, METH_O, "IAxis_size(IAxis self) -> size_t"},
 	 { "IAxis_min", _wrap_IAxis_min, METH_O, "IAxis_min(IAxis self) -> double"},
 	 { "IAxis_max", _wrap_IAxis_max, METH_O, "IAxis_max(IAxis self) -> double"},
 	 { "IAxis_bounds", _wrap_IAxis_bounds, METH_O, "IAxis_bounds(IAxis self) -> pvacuum_double_t"},
 	 { "IAxis_span", _wrap_IAxis_span, METH_O, "IAxis_span(IAxis self) -> double"},
 	 { "IAxis_center", _wrap_IAxis_center, METH_O, "IAxis_center(IAxis self) -> double"},
-	 { "IAxis_axisName", _wrap_IAxis_axisName, METH_O, "IAxis_axisName(IAxis self) -> std::string"},
 	 { "IAxis_binCenters", _wrap_IAxis_binCenters, METH_O, "IAxis_binCenters(IAxis self) -> vdouble1d_t"},
 	 { "IAxis_binCenter", _wrap_IAxis_binCenter, METH_VARARGS, "IAxis_binCenter(IAxis self, size_t index) -> double"},
-	 { "IAxis_binBoundaries", _wrap_IAxis_binBoundaries, METH_O, "IAxis_binBoundaries(IAxis self) -> vdouble1d_t"},
 	 { "IAxis_bin", _wrap_IAxis_bin, METH_VARARGS, "IAxis_bin(IAxis self, size_t index) -> Bin1D"},
 	 { "IAxis_findClosestIndex", _wrap_IAxis_findClosestIndex, METH_VARARGS, "IAxis_findClosestIndex(IAxis self, double value) -> size_t"},
 	 { "IAxis_contains", _wrap_IAxis_contains, METH_VARARGS, "IAxis_contains(IAxis self, double value) -> bool"},
@@ -28968,7 +28898,6 @@ static PyMethodDef SwigMethods[] = {
 	 { "FixedBinAxis_clone", _wrap_FixedBinAxis_clone, METH_O, "FixedBinAxis_clone(FixedBinAxis self) -> FixedBinAxis"},
 	 { "FixedBinAxis_bin", _wrap_FixedBinAxis_bin, METH_VARARGS, "FixedBinAxis_bin(FixedBinAxis self, size_t index) -> Bin1D"},
 	 { "FixedBinAxis_findClosestIndex", _wrap_FixedBinAxis_findClosestIndex, METH_VARARGS, "FixedBinAxis_findClosestIndex(FixedBinAxis self, double value) -> size_t"},
-	 { "FixedBinAxis_binBoundaries", _wrap_FixedBinAxis_binBoundaries, METH_O, "FixedBinAxis_binBoundaries(FixedBinAxis self) -> vdouble1d_t"},
 	 { "FixedBinAxis_clip", _wrap_FixedBinAxis_clip, METH_VARARGS, "FixedBinAxis_clip(FixedBinAxis self, double lower, double upper)"},
 	 { "FixedBinAxis_swigregister", FixedBinAxis_swigregister, METH_O, NULL},
 	 { "FixedBinAxis_swiginit", FixedBinAxis_swiginit, METH_VARARGS, NULL},
@@ -28979,7 +28908,6 @@ static PyMethodDef SwigMethods[] = {
 	 { "DiscreteAxis_clone", _wrap_DiscreteAxis_clone, METH_O, "DiscreteAxis_clone(DiscreteAxis self) -> DiscreteAxis"},
 	 { "DiscreteAxis_bin", _wrap_DiscreteAxis_bin, METH_VARARGS, "DiscreteAxis_bin(DiscreteAxis self, size_t index) -> Bin1D"},
 	 { "DiscreteAxis_findClosestIndex", _wrap_DiscreteAxis_findClosestIndex, METH_VARARGS, "DiscreteAxis_findClosestIndex(DiscreteAxis self, double value) -> size_t"},
-	 { "DiscreteAxis_binBoundaries", _wrap_DiscreteAxis_binBoundaries, METH_O, "DiscreteAxis_binBoundaries(DiscreteAxis self) -> vdouble1d_t"},
 	 { "DiscreteAxis_clip", _wrap_DiscreteAxis_clip, METH_VARARGS, "DiscreteAxis_clip(DiscreteAxis self, double lower, double upper)"},
 	 { "delete_DiscreteAxis", _wrap_delete_DiscreteAxis, METH_O, "delete_DiscreteAxis(DiscreteAxis self)"},
 	 { "DiscreteAxis_swigregister", DiscreteAxis_swigregister, METH_O, NULL},
-- 
GitLab


From 9f9a0a8bda3e76c02801413a91f138959ab799ed Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de>
Date: Mon, 1 May 2023 22:39:13 +0200
Subject: [PATCH 18/31] IAxis::bin

---
 Base/Axis/DiscreteAxis.cpp             |   6 --
 Base/Axis/DiscreteAxis.h               |   3 -
 Base/Axis/FixedBinAxis.cpp             |   9 --
 Base/Axis/FixedBinAxis.h               |   2 -
 Base/Axis/IAxis.cpp                    |  15 ++--
 Base/Axis/IAxis.h                      |   8 +-
 Tests/Unit/Device/FixedBinAxisTest.cpp |   2 +-
 auto/Wrap/libBornAgainBase.py          |  24 ++----
 auto/Wrap/libBornAgainBase_wrap.cpp    | 112 ++++++-------------------
 9 files changed, 47 insertions(+), 134 deletions(-)

diff --git a/Base/Axis/DiscreteAxis.cpp b/Base/Axis/DiscreteAxis.cpp
index 56032ca1adf..62bc799ea6b 100644
--- a/Base/Axis/DiscreteAxis.cpp
+++ b/Base/Axis/DiscreteAxis.cpp
@@ -52,12 +52,6 @@ DiscreteAxis* DiscreteAxis::clone() const
     return new DiscreteAxis(axisName(), m_coordinates);
 }
 
-Bin1D DiscreteAxis::bin(size_t index) const
-{
-    checkIndex(index);
-    return Bin1D::FromTo(minary(index), maxary(index));
-}
-
 size_t DiscreteAxis::findClosestIndex(double value) const
 {
     if (value <= m_coordinates.front())
diff --git a/Base/Axis/DiscreteAxis.h b/Base/Axis/DiscreteAxis.h
index ef50196c0af..54768cd1191 100644
--- a/Base/Axis/DiscreteAxis.h
+++ b/Base/Axis/DiscreteAxis.h
@@ -27,9 +27,6 @@ public:
     //! clone function
     DiscreteAxis* clone() const override;
 
-    //! retrieve a 1d bin for the given index
-    Bin1D bin(size_t index) const override;
-
     //! find index of the coordinate closest to the given value
     size_t findClosestIndex(double value) const override;
 
diff --git a/Base/Axis/FixedBinAxis.cpp b/Base/Axis/FixedBinAxis.cpp
index 520e6522ba6..b9dd53c0974 100644
--- a/Base/Axis/FixedBinAxis.cpp
+++ b/Base/Axis/FixedBinAxis.cpp
@@ -49,15 +49,6 @@ FixedBinAxis* FixedBinAxis::clone() const
     return result;
 }
 
-Bin1D FixedBinAxis::bin(size_t index) const
-{
-    if (index >= m_nbins)
-        throw std::runtime_error("FixedBinAxis::bin -> Error. Wrong index.");
-
-    double step = (m_end - m_start) / m_nbins;
-    return Bin1D::FromTo(m_start + step * index, m_start + step * (index + 1));
-}
-
 size_t FixedBinAxis::findClosestIndex(double value) const
 {
     if (value < min())
diff --git a/Base/Axis/FixedBinAxis.h b/Base/Axis/FixedBinAxis.h
index b74cac916b9..bda57899f44 100644
--- a/Base/Axis/FixedBinAxis.h
+++ b/Base/Axis/FixedBinAxis.h
@@ -32,8 +32,6 @@ public:
 
     FixedBinAxis* clone() const override;
 
-    Bin1D bin(size_t index) const override;
-
     size_t findClosestIndex(double value) const override;
 
     void clip(double lower, double upper) override;
diff --git a/Base/Axis/IAxis.cpp b/Base/Axis/IAxis.cpp
index e15057f6e87..477875e45c8 100644
--- a/Base/Axis/IAxis.cpp
+++ b/Base/Axis/IAxis.cpp
@@ -53,6 +53,16 @@ double IAxis::center() const
     return (max() + min()) / 2;
 }
 
+const Bin1D& IAxis::bin(size_t i) const
+{
+    return m_bins.at(i);
+}
+
+double IAxis::binCenter(size_t i) const
+{
+    return bin(i).center();
+}
+
 std::vector<double> IAxis::binCenters() const
 {
     std::vector<double> result;
@@ -61,11 +71,6 @@ std::vector<double> IAxis::binCenters() const
     return result;
 }
 
-double IAxis::binCenter(size_t i) const
-{
-    return m_bins.at(i).center();
-}
-
 bool IAxis::equals(const IAxis& other) const
 {
     return axisName() == other.axisName();
diff --git a/Base/Axis/IAxis.h b/Base/Axis/IAxis.h
index 58d86583099..cd897c8c4eb 100644
--- a/Base/Axis/IAxis.h
+++ b/Base/Axis/IAxis.h
@@ -56,12 +56,10 @@ public:
     //! Returns midpoint of axis
     double center() const;
 
-    std::vector<double> binCenters() const;
-
-    double binCenter(size_t index) const;
+    const Bin1D& bin(size_t i) const;
+    double binCenter(size_t i) const;
 
-    //! retrieve a 1d bin for the given index
-    virtual Bin1D bin(size_t index) const = 0;
+    std::vector<double> binCenters() const;
 
 
     //! find bin index which is best match for given value
diff --git a/Tests/Unit/Device/FixedBinAxisTest.cpp b/Tests/Unit/Device/FixedBinAxisTest.cpp
index 1dbf493ec07..997fd0da072 100644
--- a/Tests/Unit/Device/FixedBinAxisTest.cpp
+++ b/Tests/Unit/Device/FixedBinAxisTest.cpp
@@ -78,7 +78,7 @@ TEST(FixedBinAxisTest, CheckBin)
     EXPECT_DOUBLE_EQ(9.5, bin19.lowerBound());
     EXPECT_DOUBLE_EQ(10.0, bin19.upperBound());
 
-    EXPECT_THROW(axis.bin(20), std::runtime_error);
+    EXPECT_THROW(axis.bin(20), std::out_of_range);
 
     FixedBinAxis axis2("name", 3, -1, 2.0);
     EXPECT_DOUBLE_EQ(-0.5, axis2.bin(0).center());
diff --git a/auto/Wrap/libBornAgainBase.py b/auto/Wrap/libBornAgainBase.py
index d3754580aef..367d09a1b48 100644
--- a/auto/Wrap/libBornAgainBase.py
+++ b/auto/Wrap/libBornAgainBase.py
@@ -1882,18 +1882,18 @@ class IAxis(object):
         r"""center(IAxis self) -> double"""
         return _libBornAgainBase.IAxis_center(self)
 
+    def bin(self, i):
+        r"""bin(IAxis self, size_t i) -> Bin1D"""
+        return _libBornAgainBase.IAxis_bin(self, i)
+
+    def binCenter(self, i):
+        r"""binCenter(IAxis self, size_t i) -> double"""
+        return _libBornAgainBase.IAxis_binCenter(self, i)
+
     def binCenters(self):
         r"""binCenters(IAxis self) -> vdouble1d_t"""
         return _libBornAgainBase.IAxis_binCenters(self)
 
-    def binCenter(self, index):
-        r"""binCenter(IAxis self, size_t index) -> double"""
-        return _libBornAgainBase.IAxis_binCenter(self, index)
-
-    def bin(self, index):
-        r"""bin(IAxis self, size_t index) -> Bin1D"""
-        return _libBornAgainBase.IAxis_bin(self, index)
-
     def findClosestIndex(self, value):
         r"""findClosestIndex(IAxis self, double value) -> size_t"""
         return _libBornAgainBase.IAxis_findClosestIndex(self, value)
@@ -1937,10 +1937,6 @@ class FixedBinAxis(IAxis):
         r"""clone(FixedBinAxis self) -> FixedBinAxis"""
         return _libBornAgainBase.FixedBinAxis_clone(self)
 
-    def bin(self, index):
-        r"""bin(FixedBinAxis self, size_t index) -> Bin1D"""
-        return _libBornAgainBase.FixedBinAxis_bin(self, index)
-
     def findClosestIndex(self, value):
         r"""findClosestIndex(FixedBinAxis self, double value) -> size_t"""
         return _libBornAgainBase.FixedBinAxis_findClosestIndex(self, value)
@@ -1968,10 +1964,6 @@ class DiscreteAxis(IAxis):
         r"""clone(DiscreteAxis self) -> DiscreteAxis"""
         return _libBornAgainBase.DiscreteAxis_clone(self)
 
-    def bin(self, index):
-        r"""bin(DiscreteAxis self, size_t index) -> Bin1D"""
-        return _libBornAgainBase.DiscreteAxis_bin(self, index)
-
     def findClosestIndex(self, value):
         r"""findClosestIndex(DiscreteAxis self, double value) -> size_t"""
         return _libBornAgainBase.DiscreteAxis_findClosestIndex(self, value)
diff --git a/auto/Wrap/libBornAgainBase_wrap.cpp b/auto/Wrap/libBornAgainBase_wrap.cpp
index 48f537ee4b9..f7c2d0e9d16 100644
--- a/auto/Wrap/libBornAgainBase_wrap.cpp
+++ b/auto/Wrap/libBornAgainBase_wrap.cpp
@@ -25452,23 +25452,30 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_IAxis_binCenters(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_IAxis_bin(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   IAxis *arg1 = (IAxis *) 0 ;
+  size_t arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  std::vector< double,std::allocator< double > > result;
+  size_t val2 ;
+  int ecode2 = 0 ;
+  PyObject *swig_obj[2] ;
+  Bin1D *result = 0 ;
   
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
+  if (!SWIG_Python_UnpackTuple(args, "IAxis_bin", 2, 2, swig_obj)) SWIG_fail;
   res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IAxis, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IAxis_binCenters" "', argument " "1"" of type '" "IAxis const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IAxis_bin" "', argument " "1"" of type '" "IAxis const *""'"); 
   }
   arg1 = reinterpret_cast< IAxis * >(argp1);
-  result = ((IAxis const *)arg1)->binCenters();
-  resultobj = swig::from(static_cast< std::vector< double,std::allocator< double > > >(result));
+  ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IAxis_bin" "', argument " "2"" of type '" "size_t""'");
+  } 
+  arg2 = static_cast< size_t >(val2);
+  result = (Bin1D *) &((IAxis const *)arg1)->bin(arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Bin1D, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -25505,30 +25512,23 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_IAxis_bin(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_IAxis_binCenters(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   IAxis *arg1 = (IAxis *) 0 ;
-  size_t arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  size_t val2 ;
-  int ecode2 = 0 ;
-  PyObject *swig_obj[2] ;
-  SwigValueWrapper< Bin1D > result;
+  PyObject *swig_obj[1] ;
+  std::vector< double,std::allocator< double > > result;
   
-  if (!SWIG_Python_UnpackTuple(args, "IAxis_bin", 2, 2, swig_obj)) SWIG_fail;
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
   res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IAxis, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IAxis_bin" "', argument " "1"" of type '" "IAxis const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IAxis_binCenters" "', argument " "1"" of type '" "IAxis const *""'"); 
   }
   arg1 = reinterpret_cast< IAxis * >(argp1);
-  ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IAxis_bin" "', argument " "2"" of type '" "size_t""'");
-  } 
-  arg2 = static_cast< size_t >(val2);
-  result = ((IAxis const *)arg1)->bin(arg2);
-  resultobj = SWIG_NewPointerObj((new Bin1D(result)), SWIGTYPE_p_Bin1D, SWIG_POINTER_OWN |  0 );
+  result = ((IAxis const *)arg1)->binCenters();
+  resultobj = swig::from(static_cast< std::vector< double,std::allocator< double > > >(result));
   return resultobj;
 fail:
   return NULL;
@@ -25970,36 +25970,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_FixedBinAxis_bin(PyObject *self, PyObject *args) {
-  PyObject *resultobj = 0;
-  FixedBinAxis *arg1 = (FixedBinAxis *) 0 ;
-  size_t arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  size_t val2 ;
-  int ecode2 = 0 ;
-  PyObject *swig_obj[2] ;
-  SwigValueWrapper< Bin1D > result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "FixedBinAxis_bin", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_FixedBinAxis, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FixedBinAxis_bin" "', argument " "1"" of type '" "FixedBinAxis const *""'"); 
-  }
-  arg1 = reinterpret_cast< FixedBinAxis * >(argp1);
-  ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FixedBinAxis_bin" "', argument " "2"" of type '" "size_t""'");
-  } 
-  arg2 = static_cast< size_t >(val2);
-  result = ((FixedBinAxis const *)arg1)->bin(arg2);
-  resultobj = SWIG_NewPointerObj((new Bin1D(result)), SWIGTYPE_p_Bin1D, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_FixedBinAxis_findClosestIndex(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   FixedBinAxis *arg1 = (FixedBinAxis *) 0 ;
@@ -26252,36 +26222,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_DiscreteAxis_bin(PyObject *self, PyObject *args) {
-  PyObject *resultobj = 0;
-  DiscreteAxis *arg1 = (DiscreteAxis *) 0 ;
-  size_t arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  size_t val2 ;
-  int ecode2 = 0 ;
-  PyObject *swig_obj[2] ;
-  SwigValueWrapper< Bin1D > result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "DiscreteAxis_bin", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_DiscreteAxis, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DiscreteAxis_bin" "', argument " "1"" of type '" "DiscreteAxis const *""'"); 
-  }
-  arg1 = reinterpret_cast< DiscreteAxis * >(argp1);
-  ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DiscreteAxis_bin" "', argument " "2"" of type '" "size_t""'");
-  } 
-  arg2 = static_cast< size_t >(val2);
-  result = ((DiscreteAxis const *)arg1)->bin(arg2);
-  resultobj = SWIG_NewPointerObj((new Bin1D(result)), SWIGTYPE_p_Bin1D, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_DiscreteAxis_findClosestIndex(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   DiscreteAxis *arg1 = (DiscreteAxis *) 0 ;
@@ -28878,9 +28818,9 @@ static PyMethodDef SwigMethods[] = {
 	 { "IAxis_bounds", _wrap_IAxis_bounds, METH_O, "IAxis_bounds(IAxis self) -> pvacuum_double_t"},
 	 { "IAxis_span", _wrap_IAxis_span, METH_O, "IAxis_span(IAxis self) -> double"},
 	 { "IAxis_center", _wrap_IAxis_center, METH_O, "IAxis_center(IAxis self) -> double"},
+	 { "IAxis_bin", _wrap_IAxis_bin, METH_VARARGS, "IAxis_bin(IAxis self, size_t i) -> Bin1D"},
+	 { "IAxis_binCenter", _wrap_IAxis_binCenter, METH_VARARGS, "IAxis_binCenter(IAxis self, size_t i) -> double"},
 	 { "IAxis_binCenters", _wrap_IAxis_binCenters, METH_O, "IAxis_binCenters(IAxis self) -> vdouble1d_t"},
-	 { "IAxis_binCenter", _wrap_IAxis_binCenter, METH_VARARGS, "IAxis_binCenter(IAxis self, size_t index) -> double"},
-	 { "IAxis_bin", _wrap_IAxis_bin, METH_VARARGS, "IAxis_bin(IAxis self, size_t index) -> Bin1D"},
 	 { "IAxis_findClosestIndex", _wrap_IAxis_findClosestIndex, METH_VARARGS, "IAxis_findClosestIndex(IAxis self, double value) -> size_t"},
 	 { "IAxis_contains", _wrap_IAxis_contains, METH_VARARGS, "IAxis_contains(IAxis self, double value) -> bool"},
 	 { "IAxis_clip", _wrap_IAxis_clip, METH_VARARGS, "\n"
@@ -28896,7 +28836,6 @@ static PyMethodDef SwigMethods[] = {
 		"new_FixedBinAxis(FixedBinAxis arg1) -> FixedBinAxis\n"
 		""},
 	 { "FixedBinAxis_clone", _wrap_FixedBinAxis_clone, METH_O, "FixedBinAxis_clone(FixedBinAxis self) -> FixedBinAxis"},
-	 { "FixedBinAxis_bin", _wrap_FixedBinAxis_bin, METH_VARARGS, "FixedBinAxis_bin(FixedBinAxis self, size_t index) -> Bin1D"},
 	 { "FixedBinAxis_findClosestIndex", _wrap_FixedBinAxis_findClosestIndex, METH_VARARGS, "FixedBinAxis_findClosestIndex(FixedBinAxis self, double value) -> size_t"},
 	 { "FixedBinAxis_clip", _wrap_FixedBinAxis_clip, METH_VARARGS, "FixedBinAxis_clip(FixedBinAxis self, double lower, double upper)"},
 	 { "FixedBinAxis_swigregister", FixedBinAxis_swigregister, METH_O, NULL},
@@ -28906,7 +28845,6 @@ static PyMethodDef SwigMethods[] = {
 		"new_DiscreteAxis(std::string const & name, size_t n, double first, double last) -> DiscreteAxis\n"
 		""},
 	 { "DiscreteAxis_clone", _wrap_DiscreteAxis_clone, METH_O, "DiscreteAxis_clone(DiscreteAxis self) -> DiscreteAxis"},
-	 { "DiscreteAxis_bin", _wrap_DiscreteAxis_bin, METH_VARARGS, "DiscreteAxis_bin(DiscreteAxis self, size_t index) -> Bin1D"},
 	 { "DiscreteAxis_findClosestIndex", _wrap_DiscreteAxis_findClosestIndex, METH_VARARGS, "DiscreteAxis_findClosestIndex(DiscreteAxis self, double value) -> size_t"},
 	 { "DiscreteAxis_clip", _wrap_DiscreteAxis_clip, METH_VARARGS, "DiscreteAxis_clip(DiscreteAxis self, double lower, double upper)"},
 	 { "delete_DiscreteAxis", _wrap_delete_DiscreteAxis, METH_O, "delete_DiscreteAxis(DiscreteAxis self)"},
-- 
GitLab


From 1c3800462c9acfbd2701cd0e5f9f749690536cd4 Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de>
Date: Mon, 1 May 2023 22:51:11 +0200
Subject: [PATCH 19/31] shorten fct name -> IAxis::closestIndex

---
 Base/Axis/DiscreteAxis.cpp              |  6 ++--
 Base/Axis/DiscreteAxis.h                |  2 +-
 Base/Axis/FixedBinAxis.cpp              |  6 ++--
 Base/Axis/FixedBinAxis.h                |  2 +-
 Base/Axis/FrameUtil.cpp                 |  2 +-
 Base/Axis/IAxis.h                       |  2 +-
 Device/Data/Datafield.cpp               | 16 +++++-----
 Device/Detector/IDetector.cpp           |  4 +--
 Device/Detector/OffspecDetector.cpp     |  2 +-
 Device/Detector/RectangularDetector.cpp |  2 +-
 Device/Detector/SphericalDetector.cpp   |  2 +-
 Tests/Unit/Device/FixedBinAxisTest.cpp  | 28 ++++++++---------
 Tests/Unit/Device/PointwiseAxisTest.cpp | 40 ++++++++++++-------------
 auto/Wrap/libBornAgainBase.py           | 18 +++++------
 auto/Wrap/libBornAgainBase_wrap.cpp     | 36 +++++++++++-----------
 15 files changed, 84 insertions(+), 84 deletions(-)

diff --git a/Base/Axis/DiscreteAxis.cpp b/Base/Axis/DiscreteAxis.cpp
index 62bc799ea6b..094eec2c66f 100644
--- a/Base/Axis/DiscreteAxis.cpp
+++ b/Base/Axis/DiscreteAxis.cpp
@@ -52,7 +52,7 @@ DiscreteAxis* DiscreteAxis::clone() const
     return new DiscreteAxis(axisName(), m_coordinates);
 }
 
-size_t DiscreteAxis::findClosestIndex(double value) const
+size_t DiscreteAxis::closestIndex(double value) const
 {
     if (value <= m_coordinates.front())
         return 0;
@@ -71,8 +71,8 @@ void DiscreteAxis::clip(double lower, double upper)
         throw std::runtime_error("DiscreteAxis::clip() called with invalid lower >= upper");
 
     using diff_t = std::vector<double>::iterator::difference_type;
-    const auto begin = m_coordinates.begin() + static_cast<diff_t>(findClosestIndex(lower));
-    const auto end = m_coordinates.begin() + static_cast<diff_t>(findClosestIndex(upper)) + 1;
+    const auto begin = m_coordinates.begin() + static_cast<diff_t>(closestIndex(lower));
+    const auto end = m_coordinates.begin() + static_cast<diff_t>(closestIndex(upper)) + 1;
 
     m_coordinates = std::vector<double>(begin, end);
     sanityCheck();
diff --git a/Base/Axis/DiscreteAxis.h b/Base/Axis/DiscreteAxis.h
index 54768cd1191..ea9bcbf64c3 100644
--- a/Base/Axis/DiscreteAxis.h
+++ b/Base/Axis/DiscreteAxis.h
@@ -28,7 +28,7 @@ public:
     DiscreteAxis* clone() const override;
 
     //! find index of the coordinate closest to the given value
-    size_t findClosestIndex(double value) const override;
+    size_t closestIndex(double value) const override;
 
     void clip(double lower, double upper) override;
 
diff --git a/Base/Axis/FixedBinAxis.cpp b/Base/Axis/FixedBinAxis.cpp
index b9dd53c0974..bb6c3540838 100644
--- a/Base/Axis/FixedBinAxis.cpp
+++ b/Base/Axis/FixedBinAxis.cpp
@@ -49,7 +49,7 @@ FixedBinAxis* FixedBinAxis::clone() const
     return result;
 }
 
-size_t FixedBinAxis::findClosestIndex(double value) const
+size_t FixedBinAxis::closestIndex(double value) const
 {
     if (value < min())
         return 0;
@@ -71,8 +71,8 @@ void FixedBinAxis::clip(double lower, double upper)
     if (upper >= max())
         upper = bin(size() - 1).center();
 
-    const size_t nbin1 = findClosestIndex(lower);
-    const size_t nbin2 = findClosestIndex(upper);
+    const size_t nbin1 = closestIndex(lower);
+    const size_t nbin2 = closestIndex(upper);
 
     // create tmp vars until everything is calculated, otherwise the calculation will be corrupted
     // by partially changed values
diff --git a/Base/Axis/FixedBinAxis.h b/Base/Axis/FixedBinAxis.h
index bda57899f44..503257241da 100644
--- a/Base/Axis/FixedBinAxis.h
+++ b/Base/Axis/FixedBinAxis.h
@@ -32,7 +32,7 @@ public:
 
     FixedBinAxis* clone() const override;
 
-    size_t findClosestIndex(double value) const override;
+    size_t closestIndex(double value) const override;
 
     void clip(double lower, double upper) override;
 
diff --git a/Base/Axis/FrameUtil.cpp b/Base/Axis/FrameUtil.cpp
index 59f15e316a2..8cf1bdd4c5f 100644
--- a/Base/Axis/FrameUtil.cpp
+++ b/Base/Axis/FrameUtil.cpp
@@ -34,7 +34,7 @@ size_t FrameUtil::product_size(const std::vector<const IAxis*>& axes)
 
 double FrameUtil::coordinateToBinf(double coordinate, const IAxis& axis)
 {
-    size_t index = axis.findClosestIndex(coordinate);
+    size_t index = axis.closestIndex(coordinate);
     Bin1D bin = axis.bin(index);
     double f = (coordinate - bin.lowerBound()) / bin.binSize();
     return static_cast<double>(index) + f;
diff --git a/Base/Axis/IAxis.h b/Base/Axis/IAxis.h
index cd897c8c4eb..a1b8789799d 100644
--- a/Base/Axis/IAxis.h
+++ b/Base/Axis/IAxis.h
@@ -63,7 +63,7 @@ public:
 
 
     //! find bin index which is best match for given value
-    virtual size_t findClosestIndex(double value) const = 0;
+    virtual size_t closestIndex(double value) const = 0;
 
     //! Returns true if axis contains given point
     virtual bool contains(double value) const;
diff --git a/Device/Data/Datafield.cpp b/Device/Data/Datafield.cpp
index e5649ea87a7..84cfc45c6c4 100644
--- a/Device/Data/Datafield.cpp
+++ b/Device/Data/Datafield.cpp
@@ -258,14 +258,14 @@ Datafield* Datafield::xProjection() const
 
 Datafield* Datafield::xProjection(double yvalue) const
 {
-    int ybin_selected = static_cast<int>(yAxis().findClosestIndex(yvalue));
+    int ybin_selected = static_cast<int>(yAxis().closestIndex(yvalue));
     return create_xProjection(ybin_selected, ybin_selected);
 }
 
 Datafield* Datafield::xProjection(double ylow, double yup) const
 {
-    int ybinlow = static_cast<int>(yAxis().findClosestIndex(ylow));
-    int ybinup = static_cast<int>(yAxis().findClosestIndex(yup));
+    int ybinlow = static_cast<int>(yAxis().closestIndex(ylow));
+    int ybinup = static_cast<int>(yAxis().closestIndex(yup));
     return create_xProjection(ybinlow, ybinup);
 }
 
@@ -276,14 +276,14 @@ Datafield* Datafield::yProjection() const
 
 Datafield* Datafield::yProjection(double xvalue) const
 {
-    int xbin_selected = static_cast<int>(xAxis().findClosestIndex(xvalue));
+    int xbin_selected = static_cast<int>(xAxis().closestIndex(xvalue));
     return create_yProjection(xbin_selected, xbin_selected);
 }
 
 Datafield* Datafield::yProjection(double xlow, double xup) const
 {
-    int xbinlow = static_cast<int>(xAxis().findClosestIndex(xlow));
-    int xbinup = static_cast<int>(xAxis().findClosestIndex(xup));
+    int xbinlow = static_cast<int>(xAxis().closestIndex(xlow));
+    int xbinup = static_cast<int>(xAxis().closestIndex(xup));
     return create_yProjection(xbinlow, xbinup);
 }
 
@@ -295,7 +295,7 @@ Datafield* Datafield::create_xProjection(int ybinlow, int ybinup) const
         if (ybin >= ybinlow && ybin <= ybinup) {
             double x = frame().projectedCoord(i, 0);
             ASSERT(xAxis().contains(x));
-            size_t iout = xAxis().findClosestIndex(x);
+            size_t iout = xAxis().closestIndex(x);
             out[iout] += valAt(i);
         }
     }
@@ -313,7 +313,7 @@ Datafield* Datafield::create_yProjection(int xbinlow, int xbinup) const
 
             double y = frame().projectedCoord(i, 1);
             ASSERT(yAxis().contains(y));
-            size_t iout = yAxis().findClosestIndex(y);
+            size_t iout = yAxis().closestIndex(y);
             out[iout] += valAt(i);
         }
     }
diff --git a/Device/Detector/IDetector.cpp b/Device/Detector/IDetector.cpp
index 6704289a9ec..5fa8f2c98d3 100644
--- a/Device/Detector/IDetector.cpp
+++ b/Device/Detector/IDetector.cpp
@@ -255,8 +255,8 @@ size_t IDetector::detectorIndexToRegionOfInterestIndex(const size_t detectorInde
 IDetector::RoiOfAxis::RoiOfAxis(const IAxis& axis, double _lower, double _upper)
     : lower(_lower)
     , upper(_upper)
-    , lowerIndex(axis.findClosestIndex(lower))
-    , upperIndex(axis.findClosestIndex(upper))
+    , lowerIndex(axis.closestIndex(lower))
+    , upperIndex(axis.closestIndex(upper))
     , roiSize(upperIndex - lowerIndex + 1)
     , detectorSize(axis.size())
 {
diff --git a/Device/Detector/OffspecDetector.cpp b/Device/Detector/OffspecDetector.cpp
index b14b3a7c3ea..e2cb4804233 100644
--- a/Device/Detector/OffspecDetector.cpp
+++ b/Device/Detector/OffspecDetector.cpp
@@ -82,7 +82,7 @@ size_t OffspecDetector::indexOfSpecular(double alpha, double phi) const
     const IAxis& phi_axis = axis(0);
     const IAxis& alpha_axis = axis(1);
     if (phi_axis.contains(phi) && alpha_axis.contains(alpha))
-        return getGlobalIndex(phi_axis.findClosestIndex(phi), alpha_axis.findClosestIndex(alpha));
+        return getGlobalIndex(phi_axis.closestIndex(phi), alpha_axis.closestIndex(alpha));
     return totalSize();
 }
 
diff --git a/Device/Detector/RectangularDetector.cpp b/Device/Detector/RectangularDetector.cpp
index 8d69e208e72..80173688bb4 100644
--- a/Device/Detector/RectangularDetector.cpp
+++ b/Device/Detector/RectangularDetector.cpp
@@ -195,7 +195,7 @@ size_t RectangularDetector::indexOfSpecular(const Beam& beam) const
     const IAxis& v_axis = axis(1); // the y axis, in reflectometer plane
     if (!u_axis.contains(u) || !v_axis.contains(v))
         return totalSize();
-    return getGlobalIndex(u_axis.findClosestIndex(u), v_axis.findClosestIndex(v));
+    return getGlobalIndex(u_axis.closestIndex(u), v_axis.closestIndex(v));
 }
 
 void RectangularDetector::setDistanceAndOffset(double distance, double u0, double v0)
diff --git a/Device/Detector/SphericalDetector.cpp b/Device/Detector/SphericalDetector.cpp
index 93006bb67bd..9fef7b53c5e 100644
--- a/Device/Detector/SphericalDetector.cpp
+++ b/Device/Detector/SphericalDetector.cpp
@@ -68,7 +68,7 @@ size_t SphericalDetector::indexOfSpecular(const Beam& beam) const
     const IAxis& phi_axis = axis(0);
     const IAxis& alpha_axis = axis(1);
     if (phi_axis.contains(phi) && alpha_axis.contains(alpha))
-        return getGlobalIndex(phi_axis.findClosestIndex(phi), alpha_axis.findClosestIndex(alpha));
+        return getGlobalIndex(phi_axis.closestIndex(phi), alpha_axis.closestIndex(alpha));
     return totalSize();
 }
 
diff --git a/Tests/Unit/Device/FixedBinAxisTest.cpp b/Tests/Unit/Device/FixedBinAxisTest.cpp
index 997fd0da072..7be90ef4803 100644
--- a/Tests/Unit/Device/FixedBinAxisTest.cpp
+++ b/Tests/Unit/Device/FixedBinAxisTest.cpp
@@ -34,22 +34,22 @@ TEST(FixedBinAxisTest, FindClosestIndex)
 {
     FixedBinAxis v1("name", 2, 0.0, 1.0);
     EXPECT_EQ(size_t(2), v1.size());
-    EXPECT_EQ(size_t(0), v1.findClosestIndex(0.0));
-    EXPECT_EQ(size_t(0), v1.findClosestIndex(0.25));
-    EXPECT_EQ(size_t(1), v1.findClosestIndex(0.5));
-    EXPECT_EQ(size_t(1), v1.findClosestIndex(0.6));
-    //    EXPECT_THROW( v1.findClosestIndex(1.0), std::runtime_error);
-    EXPECT_EQ(size_t(1), v1.findClosestIndex(1.0));
+    EXPECT_EQ(size_t(0), v1.closestIndex(0.0));
+    EXPECT_EQ(size_t(0), v1.closestIndex(0.25));
+    EXPECT_EQ(size_t(1), v1.closestIndex(0.5));
+    EXPECT_EQ(size_t(1), v1.closestIndex(0.6));
+    //    EXPECT_THROW( v1.closestIndex(1.0), std::runtime_error);
+    EXPECT_EQ(size_t(1), v1.closestIndex(1.0));
 
     FixedBinAxis v2("name", 3, -1.5, 1.5);
-    EXPECT_EQ(size_t(0), v2.findClosestIndex(-1.5));
-    EXPECT_EQ(size_t(0), v2.findClosestIndex(-1.0));
-    EXPECT_EQ(size_t(1), v2.findClosestIndex(-0.5));
-    EXPECT_EQ(size_t(1), v2.findClosestIndex(0.0));
-    EXPECT_EQ(size_t(2), v2.findClosestIndex(0.5));
-    EXPECT_EQ(size_t(2), v2.findClosestIndex(1.499));
-    //    EXPECT_THROW( v2.findClosestIndex(1.5), std::runtime_error);
-    EXPECT_EQ(size_t(2), v2.findClosestIndex(1.5));
+    EXPECT_EQ(size_t(0), v2.closestIndex(-1.5));
+    EXPECT_EQ(size_t(0), v2.closestIndex(-1.0));
+    EXPECT_EQ(size_t(1), v2.closestIndex(-0.5));
+    EXPECT_EQ(size_t(1), v2.closestIndex(0.0));
+    EXPECT_EQ(size_t(2), v2.closestIndex(0.5));
+    EXPECT_EQ(size_t(2), v2.closestIndex(1.499));
+    //    EXPECT_THROW( v2.closestIndex(1.5), std::runtime_error);
+    EXPECT_EQ(size_t(2), v2.closestIndex(1.5));
 }
 
 TEST(FixedBinAxisTest, CheckBin)
diff --git a/Tests/Unit/Device/PointwiseAxisTest.cpp b/Tests/Unit/Device/PointwiseAxisTest.cpp
index 2a91419d3fd..9f7163afad4 100644
--- a/Tests/Unit/Device/PointwiseAxisTest.cpp
+++ b/Tests/Unit/Device/PointwiseAxisTest.cpp
@@ -39,24 +39,24 @@ TEST(PointwiseAxisTest, FindClosestIndex)
 {
     DiscreteAxis v1("name", std::vector<double>{0.0, 1.0, 4.0, 8.0});
     EXPECT_EQ(4u, v1.size());
-    EXPECT_EQ(v1.findClosestIndex(-1.0), 0u);
-    EXPECT_EQ(v1.findClosestIndex(0.0), 0u);
-    EXPECT_EQ(v1.findClosestIndex(0.25), 0u);
-    EXPECT_EQ(1u, v1.findClosestIndex(0.5));
-    EXPECT_EQ(1u, v1.findClosestIndex(0.6));
-    EXPECT_EQ(1u, v1.findClosestIndex(2.49));
-    EXPECT_EQ(2u, v1.findClosestIndex(2.5));
-    EXPECT_EQ(3u, v1.findClosestIndex(8.0));
-    EXPECT_EQ(3u, v1.findClosestIndex(11.0));
+    EXPECT_EQ(v1.closestIndex(-1.0), 0u);
+    EXPECT_EQ(v1.closestIndex(0.0), 0u);
+    EXPECT_EQ(v1.closestIndex(0.25), 0u);
+    EXPECT_EQ(1u, v1.closestIndex(0.5));
+    EXPECT_EQ(1u, v1.closestIndex(0.6));
+    EXPECT_EQ(1u, v1.closestIndex(2.49));
+    EXPECT_EQ(2u, v1.closestIndex(2.5));
+    EXPECT_EQ(3u, v1.closestIndex(8.0));
+    EXPECT_EQ(3u, v1.closestIndex(11.0));
 
     DiscreteAxis v2("name", std::vector<double>{-2.0, -1.0});
     EXPECT_EQ(2u, v2.size());
-    EXPECT_EQ(v2.findClosestIndex(-3.0), 0u);
-    EXPECT_EQ(v2.findClosestIndex(-2.0), 0u);
-    EXPECT_EQ(1u, v2.findClosestIndex(-1.5));
-    EXPECT_EQ(1u, v2.findClosestIndex(-1.0));
-    EXPECT_EQ(1u, v2.findClosestIndex(0.0));
-    EXPECT_EQ(1u, v2.findClosestIndex(1.0));
+    EXPECT_EQ(v2.closestIndex(-3.0), 0u);
+    EXPECT_EQ(v2.closestIndex(-2.0), 0u);
+    EXPECT_EQ(1u, v2.closestIndex(-1.5));
+    EXPECT_EQ(1u, v2.closestIndex(-1.0));
+    EXPECT_EQ(1u, v2.closestIndex(0.0));
+    EXPECT_EQ(1u, v2.closestIndex(1.0));
 }
 
 TEST(PointwiseAxisTest, CheckEquality)
@@ -125,11 +125,11 @@ TEST(PointwiseAxisTest, FixedBinAxisComparison)
     EXPECT_DOUBLE_EQ(fixed_axis.binCenter(2), pointwise_axis.binCenter(2));
     EXPECT_DOUBLE_EQ(fixed_axis.binCenter(3), pointwise_axis.binCenter(3));
 
-    EXPECT_EQ(fixed_axis.findClosestIndex(0.0), pointwise_axis.findClosestIndex(0.0));
-    EXPECT_EQ(fixed_axis.findClosestIndex(0.99), pointwise_axis.findClosestIndex(0.99));
-    EXPECT_EQ(fixed_axis.findClosestIndex(1.0), pointwise_axis.findClosestIndex(1.0));
-    EXPECT_EQ(fixed_axis.findClosestIndex(2.5), pointwise_axis.findClosestIndex(2.5));
-    EXPECT_EQ(fixed_axis.findClosestIndex(4.5), pointwise_axis.findClosestIndex(4.5));
+    EXPECT_EQ(fixed_axis.closestIndex(0.0), pointwise_axis.closestIndex(0.0));
+    EXPECT_EQ(fixed_axis.closestIndex(0.99), pointwise_axis.closestIndex(0.99));
+    EXPECT_EQ(fixed_axis.closestIndex(1.0), pointwise_axis.closestIndex(1.0));
+    EXPECT_EQ(fixed_axis.closestIndex(2.5), pointwise_axis.closestIndex(2.5));
+    EXPECT_EQ(fixed_axis.closestIndex(4.5), pointwise_axis.closestIndex(4.5));
 
     std::unique_ptr<FixedBinAxis> clipped_fixed(fixed_axis.clone());
     clipped_fixed->clip(0.5, 3.5);
diff --git a/auto/Wrap/libBornAgainBase.py b/auto/Wrap/libBornAgainBase.py
index 367d09a1b48..bfa33b16933 100644
--- a/auto/Wrap/libBornAgainBase.py
+++ b/auto/Wrap/libBornAgainBase.py
@@ -1894,9 +1894,9 @@ class IAxis(object):
         r"""binCenters(IAxis self) -> vdouble1d_t"""
         return _libBornAgainBase.IAxis_binCenters(self)
 
-    def findClosestIndex(self, value):
-        r"""findClosestIndex(IAxis self, double value) -> size_t"""
-        return _libBornAgainBase.IAxis_findClosestIndex(self, value)
+    def closestIndex(self, value):
+        r"""closestIndex(IAxis self, double value) -> size_t"""
+        return _libBornAgainBase.IAxis_closestIndex(self, value)
 
     def contains(self, value):
         r"""contains(IAxis self, double value) -> bool"""
@@ -1937,9 +1937,9 @@ class FixedBinAxis(IAxis):
         r"""clone(FixedBinAxis self) -> FixedBinAxis"""
         return _libBornAgainBase.FixedBinAxis_clone(self)
 
-    def findClosestIndex(self, value):
-        r"""findClosestIndex(FixedBinAxis self, double value) -> size_t"""
-        return _libBornAgainBase.FixedBinAxis_findClosestIndex(self, value)
+    def closestIndex(self, value):
+        r"""closestIndex(FixedBinAxis self, double value) -> size_t"""
+        return _libBornAgainBase.FixedBinAxis_closestIndex(self, value)
 
     def clip(self, lower, upper):
         r"""clip(FixedBinAxis self, double lower, double upper)"""
@@ -1964,9 +1964,9 @@ class DiscreteAxis(IAxis):
         r"""clone(DiscreteAxis self) -> DiscreteAxis"""
         return _libBornAgainBase.DiscreteAxis_clone(self)
 
-    def findClosestIndex(self, value):
-        r"""findClosestIndex(DiscreteAxis self, double value) -> size_t"""
-        return _libBornAgainBase.DiscreteAxis_findClosestIndex(self, value)
+    def closestIndex(self, value):
+        r"""closestIndex(DiscreteAxis self, double value) -> size_t"""
+        return _libBornAgainBase.DiscreteAxis_closestIndex(self, value)
 
     def clip(self, lower, upper):
         r"""clip(DiscreteAxis self, double lower, double upper)"""
diff --git a/auto/Wrap/libBornAgainBase_wrap.cpp b/auto/Wrap/libBornAgainBase_wrap.cpp
index f7c2d0e9d16..2bdc35c85cb 100644
--- a/auto/Wrap/libBornAgainBase_wrap.cpp
+++ b/auto/Wrap/libBornAgainBase_wrap.cpp
@@ -25535,7 +25535,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_IAxis_findClosestIndex(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_IAxis_closestIndex(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   IAxis *arg1 = (IAxis *) 0 ;
   double arg2 ;
@@ -25546,18 +25546,18 @@ SWIGINTERN PyObject *_wrap_IAxis_findClosestIndex(PyObject *self, PyObject *args
   PyObject *swig_obj[2] ;
   size_t result;
   
-  if (!SWIG_Python_UnpackTuple(args, "IAxis_findClosestIndex", 2, 2, swig_obj)) SWIG_fail;
+  if (!SWIG_Python_UnpackTuple(args, "IAxis_closestIndex", 2, 2, swig_obj)) SWIG_fail;
   res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IAxis, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IAxis_findClosestIndex" "', argument " "1"" of type '" "IAxis const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IAxis_closestIndex" "', argument " "1"" of type '" "IAxis const *""'"); 
   }
   arg1 = reinterpret_cast< IAxis * >(argp1);
   ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IAxis_findClosestIndex" "', argument " "2"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IAxis_closestIndex" "', argument " "2"" of type '" "double""'");
   } 
   arg2 = static_cast< double >(val2);
-  result = ((IAxis const *)arg1)->findClosestIndex(arg2);
+  result = ((IAxis const *)arg1)->closestIndex(arg2);
   resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
@@ -25970,7 +25970,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_FixedBinAxis_findClosestIndex(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_FixedBinAxis_closestIndex(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   FixedBinAxis *arg1 = (FixedBinAxis *) 0 ;
   double arg2 ;
@@ -25981,18 +25981,18 @@ SWIGINTERN PyObject *_wrap_FixedBinAxis_findClosestIndex(PyObject *self, PyObjec
   PyObject *swig_obj[2] ;
   size_t result;
   
-  if (!SWIG_Python_UnpackTuple(args, "FixedBinAxis_findClosestIndex", 2, 2, swig_obj)) SWIG_fail;
+  if (!SWIG_Python_UnpackTuple(args, "FixedBinAxis_closestIndex", 2, 2, swig_obj)) SWIG_fail;
   res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_FixedBinAxis, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FixedBinAxis_findClosestIndex" "', argument " "1"" of type '" "FixedBinAxis const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FixedBinAxis_closestIndex" "', argument " "1"" of type '" "FixedBinAxis const *""'"); 
   }
   arg1 = reinterpret_cast< FixedBinAxis * >(argp1);
   ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FixedBinAxis_findClosestIndex" "', argument " "2"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FixedBinAxis_closestIndex" "', argument " "2"" of type '" "double""'");
   } 
   arg2 = static_cast< double >(val2);
-  result = ((FixedBinAxis const *)arg1)->findClosestIndex(arg2);
+  result = ((FixedBinAxis const *)arg1)->closestIndex(arg2);
   resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
@@ -26222,7 +26222,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_DiscreteAxis_findClosestIndex(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_DiscreteAxis_closestIndex(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   DiscreteAxis *arg1 = (DiscreteAxis *) 0 ;
   double arg2 ;
@@ -26233,18 +26233,18 @@ SWIGINTERN PyObject *_wrap_DiscreteAxis_findClosestIndex(PyObject *self, PyObjec
   PyObject *swig_obj[2] ;
   size_t result;
   
-  if (!SWIG_Python_UnpackTuple(args, "DiscreteAxis_findClosestIndex", 2, 2, swig_obj)) SWIG_fail;
+  if (!SWIG_Python_UnpackTuple(args, "DiscreteAxis_closestIndex", 2, 2, swig_obj)) SWIG_fail;
   res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_DiscreteAxis, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DiscreteAxis_findClosestIndex" "', argument " "1"" of type '" "DiscreteAxis const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DiscreteAxis_closestIndex" "', argument " "1"" of type '" "DiscreteAxis const *""'"); 
   }
   arg1 = reinterpret_cast< DiscreteAxis * >(argp1);
   ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DiscreteAxis_findClosestIndex" "', argument " "2"" of type '" "double""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DiscreteAxis_closestIndex" "', argument " "2"" of type '" "double""'");
   } 
   arg2 = static_cast< double >(val2);
-  result = ((DiscreteAxis const *)arg1)->findClosestIndex(arg2);
+  result = ((DiscreteAxis const *)arg1)->closestIndex(arg2);
   resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
@@ -28821,7 +28821,7 @@ static PyMethodDef SwigMethods[] = {
 	 { "IAxis_bin", _wrap_IAxis_bin, METH_VARARGS, "IAxis_bin(IAxis self, size_t i) -> Bin1D"},
 	 { "IAxis_binCenter", _wrap_IAxis_binCenter, METH_VARARGS, "IAxis_binCenter(IAxis self, size_t i) -> double"},
 	 { "IAxis_binCenters", _wrap_IAxis_binCenters, METH_O, "IAxis_binCenters(IAxis self) -> vdouble1d_t"},
-	 { "IAxis_findClosestIndex", _wrap_IAxis_findClosestIndex, METH_VARARGS, "IAxis_findClosestIndex(IAxis self, double value) -> size_t"},
+	 { "IAxis_closestIndex", _wrap_IAxis_closestIndex, METH_VARARGS, "IAxis_closestIndex(IAxis self, double value) -> size_t"},
 	 { "IAxis_contains", _wrap_IAxis_contains, METH_VARARGS, "IAxis_contains(IAxis self, double value) -> bool"},
 	 { "IAxis_clip", _wrap_IAxis_clip, METH_VARARGS, "\n"
 		"IAxis_clip(IAxis self, double lower, double upper)\n"
@@ -28836,7 +28836,7 @@ static PyMethodDef SwigMethods[] = {
 		"new_FixedBinAxis(FixedBinAxis arg1) -> FixedBinAxis\n"
 		""},
 	 { "FixedBinAxis_clone", _wrap_FixedBinAxis_clone, METH_O, "FixedBinAxis_clone(FixedBinAxis self) -> FixedBinAxis"},
-	 { "FixedBinAxis_findClosestIndex", _wrap_FixedBinAxis_findClosestIndex, METH_VARARGS, "FixedBinAxis_findClosestIndex(FixedBinAxis self, double value) -> size_t"},
+	 { "FixedBinAxis_closestIndex", _wrap_FixedBinAxis_closestIndex, METH_VARARGS, "FixedBinAxis_closestIndex(FixedBinAxis self, double value) -> size_t"},
 	 { "FixedBinAxis_clip", _wrap_FixedBinAxis_clip, METH_VARARGS, "FixedBinAxis_clip(FixedBinAxis self, double lower, double upper)"},
 	 { "FixedBinAxis_swigregister", FixedBinAxis_swigregister, METH_O, NULL},
 	 { "FixedBinAxis_swiginit", FixedBinAxis_swiginit, METH_VARARGS, NULL},
@@ -28845,7 +28845,7 @@ static PyMethodDef SwigMethods[] = {
 		"new_DiscreteAxis(std::string const & name, size_t n, double first, double last) -> DiscreteAxis\n"
 		""},
 	 { "DiscreteAxis_clone", _wrap_DiscreteAxis_clone, METH_O, "DiscreteAxis_clone(DiscreteAxis self) -> DiscreteAxis"},
-	 { "DiscreteAxis_findClosestIndex", _wrap_DiscreteAxis_findClosestIndex, METH_VARARGS, "DiscreteAxis_findClosestIndex(DiscreteAxis self, double value) -> size_t"},
+	 { "DiscreteAxis_closestIndex", _wrap_DiscreteAxis_closestIndex, METH_VARARGS, "DiscreteAxis_closestIndex(DiscreteAxis self, double value) -> size_t"},
 	 { "DiscreteAxis_clip", _wrap_DiscreteAxis_clip, METH_VARARGS, "DiscreteAxis_clip(DiscreteAxis self, double lower, double upper)"},
 	 { "delete_DiscreteAxis", _wrap_delete_DiscreteAxis, METH_O, "delete_DiscreteAxis(DiscreteAxis self)"},
 	 { "DiscreteAxis_swigregister", DiscreteAxis_swigregister, METH_O, NULL},
-- 
GitLab


From ed582249a67cdc0fcf50b8d5dfdd91595aef4ea4 Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de>
Date: Mon, 1 May 2023 22:54:54 +0200
Subject: [PATCH 20/31] disambiguate -> IAxis::rangeComprises

---
 Base/Axis/IAxis.cpp                     | 10 ++--
 Base/Axis/IAxis.h                       | 11 +++--
 Device/Data/Datafield.cpp               |  8 ++--
 Device/Detector/OffspecDetector.cpp     |  2 +-
 Device/Detector/RectangularDetector.cpp |  2 +-
 Device/Detector/SphericalDetector.cpp   |  2 +-
 auto/Wrap/libBornAgainBase.py           |  8 ++--
 auto/Wrap/libBornAgainBase_wrap.cpp     | 62 ++++++++++++-------------
 8 files changed, 54 insertions(+), 51 deletions(-)

diff --git a/Base/Axis/IAxis.cpp b/Base/Axis/IAxis.cpp
index 477875e45c8..92f9bd55e62 100644
--- a/Base/Axis/IAxis.cpp
+++ b/Base/Axis/IAxis.cpp
@@ -43,6 +43,11 @@ std::pair<double, double> IAxis::bounds() const
     return {min(), max()};
 }
 
+bool IAxis::rangeComprises(double value) const
+{
+    return value >= min() && value < max();
+}
+
 double IAxis::span() const
 {
     return max() - min();
@@ -85,8 +90,3 @@ void IAxis::clip(const std::pair<double, double> bounds)
 {
     return clip(bounds.first, bounds.second);
 }
-
-bool IAxis::contains(double value) const
-{
-    return value >= min() && value < max();
-}
diff --git a/Base/Axis/IAxis.h b/Base/Axis/IAxis.h
index a1b8789799d..6fcc25933e8 100644
--- a/Base/Axis/IAxis.h
+++ b/Base/Axis/IAxis.h
@@ -34,10 +34,11 @@ public:
     //! Sets the axis label
     void setAxisName(std::string name) { m_name = name; }
 
-
     //! Returns the label of the axis
     std::string axisName() const { return m_name; }
 
+    //... Getter functions: range
+
     //! Returns the number of bins
     size_t size() const;
 
@@ -50,12 +51,17 @@ public:
     //! Returns lower and upper bound in a pair.
     std::pair<double, double> bounds() const;
 
+    //! Returns true if axis contains given point
+    bool rangeComprises(double value) const;
+
     //! Returns distance from first to last point
     double span() const;
 
     //! Returns midpoint of axis
     double center() const;
 
+    //... Getter functions: bins
+
     const Bin1D& bin(size_t i) const;
     double binCenter(size_t i) const;
 
@@ -65,9 +71,6 @@ public:
     //! find bin index which is best match for given value
     virtual size_t closestIndex(double value) const = 0;
 
-    //! Returns true if axis contains given point
-    virtual bool contains(double value) const;
-
     //! Clips this axis to the given values
     virtual void clip(double lower, double upper);
 
diff --git a/Device/Data/Datafield.cpp b/Device/Data/Datafield.cpp
index 84cfc45c6c4..aaa825cf9ac 100644
--- a/Device/Data/Datafield.cpp
+++ b/Device/Data/Datafield.cpp
@@ -186,7 +186,7 @@ Datafield* Datafield::crop(double xmin, double ymin, double xmax, double ymax) c
     for (size_t i = 0; i < size(); ++i) {
         double x = frame().projectedCoord(i, 0);
         double y = frame().projectedCoord(i, 1);
-        if (xaxis->contains(x) && yaxis->contains(y))
+        if (xaxis->rangeComprises(x) && yaxis->rangeComprises(y))
             out[iout++] = m_values[i];
     }
     return new Datafield(frame().clone(), out);
@@ -200,7 +200,7 @@ Datafield* Datafield::crop(double xmin, double xmax) const
     size_t iout = 0;
     for (size_t i = 0; i < size(); ++i) {
         const double x = frame().projectedCoord(i, 0);
-        if (xaxis->contains(x))
+        if (xaxis->rangeComprises(x))
             out[iout++] = m_values[i];
     }
     return new Datafield(frame().clone(), out);
@@ -294,7 +294,7 @@ Datafield* Datafield::create_xProjection(int ybinlow, int ybinup) const
         int ybin = static_cast<int>(frame().projectedIndex(i, 1));
         if (ybin >= ybinlow && ybin <= ybinup) {
             double x = frame().projectedCoord(i, 0);
-            ASSERT(xAxis().contains(x));
+            ASSERT(xAxis().rangeComprises(x));
             size_t iout = xAxis().closestIndex(x);
             out[iout] += valAt(i);
         }
@@ -312,7 +312,7 @@ Datafield* Datafield::create_yProjection(int xbinlow, int xbinup) const
             // TODO: duplicates code from create_xProjection, move to Frame ?
 
             double y = frame().projectedCoord(i, 1);
-            ASSERT(yAxis().contains(y));
+            ASSERT(yAxis().rangeComprises(y));
             size_t iout = yAxis().closestIndex(y);
             out[iout] += valAt(i);
         }
diff --git a/Device/Detector/OffspecDetector.cpp b/Device/Detector/OffspecDetector.cpp
index e2cb4804233..39cb81493b4 100644
--- a/Device/Detector/OffspecDetector.cpp
+++ b/Device/Detector/OffspecDetector.cpp
@@ -81,7 +81,7 @@ size_t OffspecDetector::indexOfSpecular(double alpha, double phi) const
 {
     const IAxis& phi_axis = axis(0);
     const IAxis& alpha_axis = axis(1);
-    if (phi_axis.contains(phi) && alpha_axis.contains(alpha))
+    if (phi_axis.rangeComprises(phi) && alpha_axis.rangeComprises(alpha))
         return getGlobalIndex(phi_axis.closestIndex(phi), alpha_axis.closestIndex(alpha));
     return totalSize();
 }
diff --git a/Device/Detector/RectangularDetector.cpp b/Device/Detector/RectangularDetector.cpp
index 80173688bb4..739527c6158 100644
--- a/Device/Detector/RectangularDetector.cpp
+++ b/Device/Detector/RectangularDetector.cpp
@@ -193,7 +193,7 @@ size_t RectangularDetector::indexOfSpecular(const Beam& beam) const
     const double v = rpix.dot(m_v_unit) + m_v0;
     const IAxis& u_axis = axis(0); // the x axis, GISAS only
     const IAxis& v_axis = axis(1); // the y axis, in reflectometer plane
-    if (!u_axis.contains(u) || !v_axis.contains(v))
+    if (!u_axis.rangeComprises(u) || !v_axis.rangeComprises(v))
         return totalSize();
     return getGlobalIndex(u_axis.closestIndex(u), v_axis.closestIndex(v));
 }
diff --git a/Device/Detector/SphericalDetector.cpp b/Device/Detector/SphericalDetector.cpp
index 9fef7b53c5e..6e734b26328 100644
--- a/Device/Detector/SphericalDetector.cpp
+++ b/Device/Detector/SphericalDetector.cpp
@@ -67,7 +67,7 @@ size_t SphericalDetector::indexOfSpecular(const Beam& beam) const
     double phi = beam.phi_i();
     const IAxis& phi_axis = axis(0);
     const IAxis& alpha_axis = axis(1);
-    if (phi_axis.contains(phi) && alpha_axis.contains(alpha))
+    if (phi_axis.rangeComprises(phi) && alpha_axis.rangeComprises(alpha))
         return getGlobalIndex(phi_axis.closestIndex(phi), alpha_axis.closestIndex(alpha));
     return totalSize();
 }
diff --git a/auto/Wrap/libBornAgainBase.py b/auto/Wrap/libBornAgainBase.py
index bfa33b16933..2083fc3a496 100644
--- a/auto/Wrap/libBornAgainBase.py
+++ b/auto/Wrap/libBornAgainBase.py
@@ -1874,6 +1874,10 @@ class IAxis(object):
         r"""bounds(IAxis self) -> pvacuum_double_t"""
         return _libBornAgainBase.IAxis_bounds(self)
 
+    def rangeComprises(self, value):
+        r"""rangeComprises(IAxis self, double value) -> bool"""
+        return _libBornAgainBase.IAxis_rangeComprises(self, value)
+
     def span(self):
         r"""span(IAxis self) -> double"""
         return _libBornAgainBase.IAxis_span(self)
@@ -1898,10 +1902,6 @@ class IAxis(object):
         r"""closestIndex(IAxis self, double value) -> size_t"""
         return _libBornAgainBase.IAxis_closestIndex(self, value)
 
-    def contains(self, value):
-        r"""contains(IAxis self, double value) -> bool"""
-        return _libBornAgainBase.IAxis_contains(self, value)
-
     def clip(self, *args):
         r"""
         clip(IAxis self, double lower, double upper)
diff --git a/auto/Wrap/libBornAgainBase_wrap.cpp b/auto/Wrap/libBornAgainBase_wrap.cpp
index 2bdc35c85cb..2f93dfefa12 100644
--- a/auto/Wrap/libBornAgainBase_wrap.cpp
+++ b/auto/Wrap/libBornAgainBase_wrap.cpp
@@ -25406,6 +25406,36 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_IAxis_rangeComprises(PyObject *self, PyObject *args) {
+  PyObject *resultobj = 0;
+  IAxis *arg1 = (IAxis *) 0 ;
+  double arg2 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  PyObject *swig_obj[2] ;
+  bool result;
+  
+  if (!SWIG_Python_UnpackTuple(args, "IAxis_rangeComprises", 2, 2, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IAxis, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IAxis_rangeComprises" "', argument " "1"" of type '" "IAxis const *""'"); 
+  }
+  arg1 = reinterpret_cast< IAxis * >(argp1);
+  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IAxis_rangeComprises" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  result = (bool)((IAxis const *)arg1)->rangeComprises(arg2);
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *_wrap_IAxis_span(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   IAxis *arg1 = (IAxis *) 0 ;
@@ -25565,36 +25595,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_IAxis_contains(PyObject *self, PyObject *args) {
-  PyObject *resultobj = 0;
-  IAxis *arg1 = (IAxis *) 0 ;
-  double arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  PyObject *swig_obj[2] ;
-  bool result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "IAxis_contains", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IAxis, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IAxis_contains" "', argument " "1"" of type '" "IAxis const *""'"); 
-  }
-  arg1 = reinterpret_cast< IAxis * >(argp1);
-  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IAxis_contains" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  result = (bool)((IAxis const *)arg1)->contains(arg2);
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_IAxis_clip__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) {
   PyObject *resultobj = 0;
   IAxis *arg1 = (IAxis *) 0 ;
@@ -28816,13 +28816,13 @@ static PyMethodDef SwigMethods[] = {
 	 { "IAxis_min", _wrap_IAxis_min, METH_O, "IAxis_min(IAxis self) -> double"},
 	 { "IAxis_max", _wrap_IAxis_max, METH_O, "IAxis_max(IAxis self) -> double"},
 	 { "IAxis_bounds", _wrap_IAxis_bounds, METH_O, "IAxis_bounds(IAxis self) -> pvacuum_double_t"},
+	 { "IAxis_rangeComprises", _wrap_IAxis_rangeComprises, METH_VARARGS, "IAxis_rangeComprises(IAxis self, double value) -> bool"},
 	 { "IAxis_span", _wrap_IAxis_span, METH_O, "IAxis_span(IAxis self) -> double"},
 	 { "IAxis_center", _wrap_IAxis_center, METH_O, "IAxis_center(IAxis self) -> double"},
 	 { "IAxis_bin", _wrap_IAxis_bin, METH_VARARGS, "IAxis_bin(IAxis self, size_t i) -> Bin1D"},
 	 { "IAxis_binCenter", _wrap_IAxis_binCenter, METH_VARARGS, "IAxis_binCenter(IAxis self, size_t i) -> double"},
 	 { "IAxis_binCenters", _wrap_IAxis_binCenters, METH_O, "IAxis_binCenters(IAxis self) -> vdouble1d_t"},
 	 { "IAxis_closestIndex", _wrap_IAxis_closestIndex, METH_VARARGS, "IAxis_closestIndex(IAxis self, double value) -> size_t"},
-	 { "IAxis_contains", _wrap_IAxis_contains, METH_VARARGS, "IAxis_contains(IAxis self, double value) -> bool"},
 	 { "IAxis_clip", _wrap_IAxis_clip, METH_VARARGS, "\n"
 		"IAxis_clip(IAxis self, double lower, double upper)\n"
 		"IAxis_clip(IAxis self, pvacuum_double_t bounds)\n"
-- 
GitLab


From 3c79598cb6bb219447a47430247457029188315a Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de>
Date: Mon, 1 May 2023 23:46:42 +0200
Subject: [PATCH 21/31] replicate fct closestIndex

---
 Base/Axis/DiscreteAxis.cpp          | 25 +++++++++++++++--------
 Base/Axis/FixedBinAxis.cpp          | 21 +++++++++++++------
 Base/Axis/IAxis.cpp                 |  8 ++++++++
 Base/Axis/IAxis.h                   |  1 +
 auto/Wrap/libBornAgainBase.py       |  4 ++++
 auto/Wrap/libBornAgainBase_wrap.cpp | 31 +++++++++++++++++++++++++++++
 6 files changed, 76 insertions(+), 14 deletions(-)

diff --git a/Base/Axis/DiscreteAxis.cpp b/Base/Axis/DiscreteAxis.cpp
index 094eec2c66f..61aad754ccc 100644
--- a/Base/Axis/DiscreteAxis.cpp
+++ b/Base/Axis/DiscreteAxis.cpp
@@ -54,15 +54,24 @@ DiscreteAxis* DiscreteAxis::clone() const
 
 size_t DiscreteAxis::closestIndex(double value) const
 {
+    size_t result;
     if (value <= m_coordinates.front())
-        return 0;
-    if (value >= m_coordinates.back())
-        return m_coordinates.size() - 1;
-
-    const auto begin = m_coordinates.begin();
-    auto result = std::lower_bound(begin, m_coordinates.end(), value);
-    auto index = static_cast<size_t>(std::distance(begin, result));
-    return value < minary(index) ? index - 1 : index;
+        result = 0;
+    else if (value >= m_coordinates.back())
+        result = m_coordinates.size() - 1;
+    else {
+        const auto begin = m_coordinates.begin();
+        auto it = std::lower_bound(begin, m_coordinates.end(), value);
+        auto index = static_cast<size_t>(std::distance(begin, it));
+        result = value < minary(index) ? index - 1 : index;
+    }
+    if (result != closestIndex1(value)) {
+        std::cerr << "DAx " << min() << " [" << size() << "] " << max() << ": closestIndex("
+                  << value << ") = " << result << "(old) vs (new)" << closestIndex1(value)
+                  << std::endl;
+        // ASSERT(false);
+    }
+    return result;
 }
 
 void DiscreteAxis::clip(double lower, double upper)
diff --git a/Base/Axis/FixedBinAxis.cpp b/Base/Axis/FixedBinAxis.cpp
index bb6c3540838..dcb79eaf16c 100644
--- a/Base/Axis/FixedBinAxis.cpp
+++ b/Base/Axis/FixedBinAxis.cpp
@@ -51,13 +51,22 @@ FixedBinAxis* FixedBinAxis::clone() const
 
 size_t FixedBinAxis::closestIndex(double value) const
 {
+    size_t result;
     if (value < min())
-        return 0;
-    if (value >= max())
-        return m_nbins - 1;
-
-    double step = (m_end - m_start) / m_nbins;
-    return int((value - m_start) / step);
+        result = 0;
+    else if (value >= max())
+        result = m_nbins - 1;
+    else {
+        double step = (m_end - m_start) / m_nbins;
+        result = int((value - m_start) / step);
+    }
+    if (result != closestIndex1(value)) {
+        std::cerr << "FBA " << min() << " [" << size() << "] " << max() << ": closestIndex("
+                  << value << ") = " << result << "(old) vs (new)" << closestIndex1(value)
+                  << std::endl;
+        // ASSERT(false);
+    }
+    return result;
 }
 
 void FixedBinAxis::clip(double lower, double upper)
diff --git a/Base/Axis/IAxis.cpp b/Base/Axis/IAxis.cpp
index 92f9bd55e62..88842a46a86 100644
--- a/Base/Axis/IAxis.cpp
+++ b/Base/Axis/IAxis.cpp
@@ -76,6 +76,14 @@ std::vector<double> IAxis::binCenters() const
     return result;
 }
 
+size_t IAxis::closestIndex1(double value) const
+{
+    for (size_t i = 0; i < size() - 1; ++i)
+        if (value < (bin(i).upperBound() + bin(i + 1).lowerBound()) / 2)
+            return i;
+    return size() - 1;
+}
+
 bool IAxis::equals(const IAxis& other) const
 {
     return axisName() == other.axisName();
diff --git a/Base/Axis/IAxis.h b/Base/Axis/IAxis.h
index 6fcc25933e8..db36001b1f5 100644
--- a/Base/Axis/IAxis.h
+++ b/Base/Axis/IAxis.h
@@ -70,6 +70,7 @@ public:
 
     //! find bin index which is best match for given value
     virtual size_t closestIndex(double value) const = 0;
+    size_t closestIndex1(double value) const;
 
     //! Clips this axis to the given values
     virtual void clip(double lower, double upper);
diff --git a/auto/Wrap/libBornAgainBase.py b/auto/Wrap/libBornAgainBase.py
index 2083fc3a496..3a1eb48d591 100644
--- a/auto/Wrap/libBornAgainBase.py
+++ b/auto/Wrap/libBornAgainBase.py
@@ -1902,6 +1902,10 @@ class IAxis(object):
         r"""closestIndex(IAxis self, double value) -> size_t"""
         return _libBornAgainBase.IAxis_closestIndex(self, value)
 
+    def closestIndex1(self, value):
+        r"""closestIndex1(IAxis self, double value) -> size_t"""
+        return _libBornAgainBase.IAxis_closestIndex1(self, value)
+
     def clip(self, *args):
         r"""
         clip(IAxis self, double lower, double upper)
diff --git a/auto/Wrap/libBornAgainBase_wrap.cpp b/auto/Wrap/libBornAgainBase_wrap.cpp
index 2f93dfefa12..091fcce8fb6 100644
--- a/auto/Wrap/libBornAgainBase_wrap.cpp
+++ b/auto/Wrap/libBornAgainBase_wrap.cpp
@@ -25595,6 +25595,36 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_IAxis_closestIndex1(PyObject *self, PyObject *args) {
+  PyObject *resultobj = 0;
+  IAxis *arg1 = (IAxis *) 0 ;
+  double arg2 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  PyObject *swig_obj[2] ;
+  size_t result;
+  
+  if (!SWIG_Python_UnpackTuple(args, "IAxis_closestIndex1", 2, 2, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IAxis, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IAxis_closestIndex1" "', argument " "1"" of type '" "IAxis const *""'"); 
+  }
+  arg1 = reinterpret_cast< IAxis * >(argp1);
+  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IAxis_closestIndex1" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  result = ((IAxis const *)arg1)->closestIndex1(arg2);
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *_wrap_IAxis_clip__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) {
   PyObject *resultobj = 0;
   IAxis *arg1 = (IAxis *) 0 ;
@@ -28823,6 +28853,7 @@ static PyMethodDef SwigMethods[] = {
 	 { "IAxis_binCenter", _wrap_IAxis_binCenter, METH_VARARGS, "IAxis_binCenter(IAxis self, size_t i) -> double"},
 	 { "IAxis_binCenters", _wrap_IAxis_binCenters, METH_O, "IAxis_binCenters(IAxis self) -> vdouble1d_t"},
 	 { "IAxis_closestIndex", _wrap_IAxis_closestIndex, METH_VARARGS, "IAxis_closestIndex(IAxis self, double value) -> size_t"},
+	 { "IAxis_closestIndex1", _wrap_IAxis_closestIndex1, METH_VARARGS, "IAxis_closestIndex1(IAxis self, double value) -> size_t"},
 	 { "IAxis_clip", _wrap_IAxis_clip, METH_VARARGS, "\n"
 		"IAxis_clip(IAxis self, double lower, double upper)\n"
 		"IAxis_clip(IAxis self, pvacuum_double_t bounds)\n"
-- 
GitLab


From fef8615034022e22df9e37ebf3eccb93573d4e9f Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de>
Date: Tue, 2 May 2023 00:02:39 +0200
Subject: [PATCH 22/31] activate new method => 2 tests broken

---
 Base/Axis/DiscreteAxis.cpp | 3 +--
 Base/Axis/FixedBinAxis.cpp | 3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/Base/Axis/DiscreteAxis.cpp b/Base/Axis/DiscreteAxis.cpp
index 61aad754ccc..0f4a9ecbb61 100644
--- a/Base/Axis/DiscreteAxis.cpp
+++ b/Base/Axis/DiscreteAxis.cpp
@@ -69,9 +69,8 @@ size_t DiscreteAxis::closestIndex(double value) const
         std::cerr << "DAx " << min() << " [" << size() << "] " << max() << ": closestIndex("
                   << value << ") = " << result << "(old) vs (new)" << closestIndex1(value)
                   << std::endl;
-        // ASSERT(false);
     }
-    return result;
+    return closestIndex1(value);
 }
 
 void DiscreteAxis::clip(double lower, double upper)
diff --git a/Base/Axis/FixedBinAxis.cpp b/Base/Axis/FixedBinAxis.cpp
index dcb79eaf16c..76d4810cae9 100644
--- a/Base/Axis/FixedBinAxis.cpp
+++ b/Base/Axis/FixedBinAxis.cpp
@@ -64,9 +64,8 @@ size_t FixedBinAxis::closestIndex(double value) const
         std::cerr << "FBA " << min() << " [" << size() << "] " << max() << ": closestIndex("
                   << value << ") = " << result << "(old) vs (new)" << closestIndex1(value)
                   << std::endl;
-        // ASSERT(false);
     }
-    return result;
+    return closestIndex1(value);
 }
 
 void FixedBinAxis::clip(double lower, double upper)
-- 
GitLab


From d0ba96e978aa0abcb989a7c284f680f66a9b27da Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de>
Date: Tue, 2 May 2023 11:26:02 +0200
Subject: [PATCH 23/31] disable test SphericalDetWithRoi for GUI

---
 .../Suite/SphericalDetWithRoi.int.gz          | Bin 2577 -> 2578 bytes
 Tests/Suite/Common/TestSuite.h                |  16 ++++++++--------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/Tests/ReferenceData/Suite/SphericalDetWithRoi.int.gz b/Tests/ReferenceData/Suite/SphericalDetWithRoi.int.gz
index 367d256e8f0ee4884f04a458781b1694b86557f4..29912cbae9e217fa5a330d579ee691ca171989d1 100644
GIT binary patch
delta 2551
zcmV<T2?+L)6p|E3ABzY8000000RQcp!H!(V4Mq3!6$5*dAksq>$ttpzHi7{83;`Ab
zZ4@BZ!uk6gzV3dk0hC1$50C&YShhs>R2MIKFE3yBkw`ax*FXG_!S=(4SM48OKenUE
z?7o(U^Y3oU#)sF8`jR0tn)cO}xc~7wuz%;k&VhZNKiSk)n<GZk6*0$>GpyY@f1X1}
zEMIEpfxqNc{TR#E;yrDS_W5J8SALD7H@DG8Soi*j>JhxMDe*S+5tU<!X{dDm=@o6$
zr}e4cVm+dN{ZL)gd^u;xBkG6uzNGaz`7hCNd$$B-j6`5u(SDFZh}i0F*dyvkNK+j^
zY14_$jIM*MxYL+AMm(aNU_<9zt;-mX6XX!l7SqkT&WcX=XbD4Tuc-UfCar;;R&?|g
zLzhssctl_1$hQfdB+*9!VX{cAfzjHcjWz%WSzP0P5sjmV^JW~e`gQO)oNA07qPN#R
zKpQeNB-EtU)jG)bPDy~Nprlm<bd2g>ueHNwn`=7NunS5~Sd(@bbZU!=&gNNo2a55C
z+M%P-Q(<~*o-;ZRI@(8s1O0U_?Kfu=>20~TiUtsL7!bo|MY$^_rkEDjxi5Ci1(p#Y
zFB=eleHv`&^qYGDVM1GXYPUu!AOZkj-%Ru?Dr=e3EO6n1Jr0YOchj}1(=0jA1t_HZ
z2AYk8cm*Y0)qhPrcp0F{1tpC0Nx)nwKT*GfrZ9+JBiJ8NP8dNsV?r3+`g)wuP|&fx
z8#%csjMKfGbQ1v`W^-c(oG@GPC@Qy?bu<uvSY1*(E{T|Q4_BrVKEobSib1;YppUMX
zMCf78B@m6?^rC&jLkdPB=wNXGQjr9&_2G}`f&(a9n+iL(ULA_6c^3rCwsJxY7|Q8-
z5quq)mMoy?(JJLm$zTlNjMz@#(3#9wb0heqZj_%UT%#Hd0(!P9SBQ#Ix0URep<A?n
zr4-G@|E%^yA_i1h25I7aJH1`Pk+?OcaF<n4ZSzzrB>sBsI-)fIo{=hFC0Z)OPRf>w
zLvY>-q0*SP>2*@mS|j6VRSY3DT7qM2n+|G2sO1`4%D|%(Nj%B8sdyKg6App$#m;e@
z(}F&QUYFV;2Kh40s7n<t>mH1=E^}3X)KboZnAUWNBc(PaEmOV#Mimtz8+X>TSM{DU
ze{B?_dm9Dtq7-xku$`B<N68<Jo054~wDlO0<5thnr#IMV>&RbTLiXX=nCjw)`Kf7l
zfcYEx%d2k+dLM{EjmU$urxcVNsq{8dAQ$X#AQEy~MQb|vf$rps=UOF-bURvqJ6nP?
zt?r<LmQhnIfNW9Zm)X}%`^HX&89JU-swe>C6LOf)o6-v4%!@2=2f6|5In-%X#>NIP
zy63{l^u?^cR#K%pk~i6;M<;jXy(q^nGBZvOG0L4Ji+};!LDEqGqra1Of}+C<U`Vkn
z$F;~NGJPSdW2Att0vM{$(!K(J|Fn(NWLD3T?nNf0g}uTzy@^uJ)^ixN4R&6HQg+Fc
zE`TNHx+U>*s1|6!3vH!+l&veVFymCe&<$W{WGN?(*gc|94&gwl7Tmu;Gdhi=BWL0+
z5r_=@LHGH?n?9i!{JfO5r#tE3;0UQ~#tD0d8l*+)vtZZsq*N_=R1(2|^-&3cTk}#|
zypSOFjeE6rosja!6v@sc$E_Hh>7*^E^_2yta7s4RNHcp$#5{8PgD=K(UQ|XaIRfcH
z)lPEh<HFdhadTOloG2PR37JK~j!nzjIcmO@2tS_Qgc(;+go825NKMOeLCJtwS<hgQ
z+h!FN2Z5#PjKGV^6K9%#BLK5$G7GeZIgw-+4y@o&OApI$i%krcgbd~jqk2~9Rgfa=
zHL|!h1akyQB{9ZEMX3bbg0Wka4#pulJBcZZM_6ueHyS6BTjo(w>;wA{^c<&*%PkG0
z9!Hf^L!>}Mbii#QC$_3YH~?hLGMP>Bg@#Oj4)Zq_0S>YO=Vz6FGi@b3f}TjPZU+c1
zhBM8zW&^@;F=;rEs_V5VGm6ISn+T><iAJs-G;n&$5+wWs&7Q+vt|HUz3m;->71uT$
zEDbiEiQc?Q^a5ev3*y0Glnb<63hUSBKehIsMsr{C+#4wV*h)m>EQ1<3=pIpM&)PW7
zZq-$=XGa5E{>bKkZ>WR!w8GIY#UE+C422<c(*kYT%mI~yCq8dliNR8uSajpoOalyA
zvSI5Eh=yfnqH7yxv-<|cOe$@%ipnAP=~=JnOHNPK%mH1=gZu9TFs_iUVe%n7XQ$l(
zX8FLrjdVk6V+IQ?tE95jYQc`ckYD89wxtZ@EMe^5JvIY>$;1(qGM#^~sPfa!el>3%
z|G^g!&oh`h7ij5tS=P_KoEzgJjT3&ES>VMYAcM8J-uWh=@ERKey|FGEz$gPmVg`@j
z6JTR_cAAZYnZXaxfE_txr9s)x#rzI%s%lqSu=&;3fq_hR(?1cur-6Kp?&7;u#1k}R
zaj}v1f)ZnY!yadB@w!2o77rt>>a!IGk}4F!a@E*`Zk)?t{@%<cbHGq%JfTFLfX?yq
ztVfCBOUn34_XQ14!t^`AQ78-&Biyzq8$b3Q`xmE0?>8VQB$)}kkqfk$3&Hv51$#0d
zQH)crcIkv~D}~&<5(Jn<`Fv}G9ias-T3wpe36bxApSz<qFDQ*tLVdJVwr&sl5xYVX
zKCAy|sg?UEdT9k(<UrPQS-8#(Y#Lfd(m6CLN_{<_apaGbZ%V<)cf{)L0FxCXIJ@{X
zEq5r-M+Qj8jC0AnM>W^yd@AR@y_O9*1u55u3wA&B?A~DVtyS>Q2vAXThm8U_(V`k8
z(Y*kF)_fF3iTQoO&dgwzp|)IQZcygqEq2FzG&!nQ*#&ba%C?Z|G_*F-E};6Gt;7ZA
zo=RVo+Oo3^Z#mK+TvRmDNawQ*ieIoJC%Hp29ctJ=0e*jgpAzw|67l^ZM{=~9=hClj
zhZ4WS&C*xSf-(&=HjfSBO|L$O-0Q!!X_#hzJPS8tmG_Iv&~xS|5rDiZYS<opOg{F~
ziau@H9pLXT8XPR>%Sfg1jmj&Z53^%Z|1Fw3HKj)ubp!3WXxugUxhmi8`%bI!^I^}s
zKkRuvuDo~U`#i3EK5&2M2ky_0jNbVpqvwa7|K*3C+gB34`=RIaWBYgh*#7y&lXw1q
z;>rK@SEsfwN&U}$b?W)$zjyxfA0x`=xqWiGO@kAgQ-9tJnC9&?i}_gQjR#<}@mw@U
z0i3e|BSfE#ZE$7A`2K7+uV`+=xe(x}HpOQix>(Y@Zz)r_+@bQJ*S0*Qj41h`fLoNw
z5c%9>MGdZ8e^-JYiE>3Frx1eVw=WeY-ivJcWD=31>o?B=GkT7#FyHms8Os;|DqlnH
N<zJ<%O8SN?006EO;m-g7

delta 2550
zcmV<S2?_R+6p<82ABzY8000000RQcpL5n2G4TbOhE1KPljc1YwNuh{1?qUr783Q|*
zxs1U(hxNbrr>v@!2HFSXZLp!5X?j{@M@Bs9Jw0XRkw`ax>mPoIVEf_2tICJhkL_qO
zw+!*swC}cM>W9}iqVtc}g8hvJI}3I{|FWs==3|Yfdo3SZ&aigt{NIO;wdYnl7yKo*
zx{o!T+e|Ld_W5J8SHApk>n>{3&93M;+HA60GxL5$^;iUFpC)GG5tYLiU)$W+%_G_m
zuIg(p?_<q>j5bz~DQk>jkEk8n+7uIY?M`&u)@?p*&bGAA@rbfQ_sy9(gqNr^4!q~u
zYf4$6?LJ(Wy6=pxfJV5|Z9bxU*lJzcTsoR$)WNF@%UbS14^A-Mo3@cFyv$>4+nc1C
zj{;?H(*`J5pS?iIl}(Aap$X*{W4F@z*E0$bktGFxi=9xaZVs>~Yse!y54O7njGUjj
z;kf}~M2U@^paIzuvEAF5jB#6GNmB*hWgds~h;EKdJ_F1#)+5RaHUe9a8zTW0(Y8pQ
zbuH=iIado9NN7gqbZyca*l9*bC&RjhdR-U5a>Q*&CWq)FfiT$|t%1=lQBrT<Ae(JG
zqU)f4B)J(&?0zjg4(eu)zMz5i0@{$FOO~3n+*$|O-bo2Cm8$e1pkrkJy4DW!=G!OP
zunS67*g=Xh=k0L!D3un8pFlAlQ9GzcYHFF@ipOu9MKb1C6tM4WUCNJ=6zOfxli&B~
z0)mdjtYMx}_DYILrmbt;7dsqYurSC=0iwHqAvc|Rn=^qx1qMJ!+oL5A3jnqa5A+K?
z_l7`R55XSM6_ks;>E2ms798jT6w+q_%|<}HSI|G}ujyP|2553Y3FD>{u!))kGv*yM
z<OO7eV1GneVJy<Q9KvX+>v2LuLPxn9XPTlgPHQ@;CIULp%EAmdVYcDX%Cn)t4Fq<7
z2nxwh4Q|es$;9+kRFT9jc+f}JOCr!IL=m;q-t?k<z{3%YgNR?%-b0W$#0UYsG<d@S
zT1P``)l01orEScP>Wh_hLJSzn>Ut4;A8{;nTp>}*BO{a$Q~_tKvI2{GFk^cmxRW>1
zPZ92_tI>xj3AV5@O5S#`!<Uw53n`+174YLa1rjl!3hl(eJ#MGBO-v+i4;S{bGpfx`
zrJ{#k*U}~%&8Yc`Hkv8gDu{hhHdP#gb1Q^Oms`>6pr$pNkFU}YX&LlQ8vb{UR&5Bm
z+@l;Bc$6g3Wgufw@h;{Lhd}va=Qz%8L7hUcOKlN@xJ)CO4UzIA?=)-gk_~Zx9~N@9
zh-r3*b%fN0q{WdhfKf$-$n@&2XRYe}$o$$!MxSjYz?)Q14ZwD8;vVJvXq-!&JEN_y
zA>n8AY<+rz-CIZgViQuEXTvthM9fc3y93N`=r32_6!hK@7dhe_tnH<*v!qhnNP%3i
z!+{l$Q!1L>VIJsCT<m+NC{pczXsx#Z$1V4uf|ij}EP#|K@=NdQroFI}W`>SOmNE*!
z_=IRC)TXoqIL^f>a0gldp3&4PRN6)X7~R8S&8Q2{x>k-#b|iLEq(_~-axc<RMaI|Z
zAx65BU=c82J2>=8fYD#4oS^6^b_!B#i*_wiM5b?K74HYncLEGmDCxO>F_Fccv|v_`
zl-4A3q>a78H+>f+ovlYRXa#mILMd@|taJe^(bp}AA5AquTU=<HQr%Lj5(_g<^;=p1
zhDH{0G7-B+6v`nSDAk7h7idPMap)C2u}TCY1Aowc{_|a(kPQA_Qrp9wba0pmsTAXc
zJwpw`BBf_WE5r1Ywct^IN(9?SB>--xXT}T3Y4HbiyjBSLql-jka>kO3PIuB4-TFEO
zrqCq{Dy(;EupiO=!53rd7nRXUmOy$?wUb=>*f92L++0?X6GekvW6)R$J2owHH&OGF
zBIcR!CiJ+BA{?|?T54F13rZTyj(jc}xfQFZI0!6Nrv+YAcARN{v;fSei6>|ca}op0
zTy-c>3lGb;ts(|nmJIp}t=cp7Do7Fb8d)p_VKL_*h|xAON+#eIj4e?r7>C4UMXN*c
z2+Qquqp>1qi*sZY`_QqFWd4+Kxg7(k$5BPs5J}Jw9dL8x#CE0#2Y{?u9HuC~P>|uz
zVSZr|;2;}t-ZPzlVJoQ-^hA1AJ3z28oN0_T1&E1@3B!R@UDu+_C>p)b{Wjm-Q#4}q
zpn$_$rXb-TDE4UfawVB+XL9wJC)+OF!NOqUnW)VxMK2Hrz91enM!7(XsXM<u|EabA
zG#c~LjJbj2kCLJoiVbQ+qkBZ5J!9iIt5tWx9u*C6@h8Q9-<)%OSmD(!#UEk4nBVb`
z(=<V2QjZ1|jc0u>T8Y6@ideL8%fkRemMGZVLp&FV%0$-+XQTQC$qXtLSw-cL`|zw+
z^d-8dYMcRGiG};`12C?Ts-g2CJZGid0cQBXzKw80yD)=+mQhj}YBga;U^w53xvd--
z$Qi<zzxyhG29k~=C}lYRo>AqmC-arxJpO|(ARcSbbuQ4t@iMHRb?Jq1D~uC<nO-oH
zML-5?W4xP1K;bnu1bSm#3cx4>M4|_e-xFY?d3K78h3UZ$(10B|jE5=|+em;zRlCL`
zq<Pi#!axSQsh_oGJqGeM`jlC%BA%cji<^nGCzKd}8|FA;iq`^VSUilh>hzWz2&#|>
zi&3Kp-8hHA_%3FXK47Rbo={e<fX;Dw<ReA#C1iYu`+|liVfvlmC=>>X7H%cV#E-ql
z{;kuZ_Ztu-l9LI%kqb1Bf#7`ff<5s^6yp@5T{z*}NFn#C1Oa+cJU}e4BecLpsY|n5
zVa5G_V|KJQ6G|hMP#<lTQtgX+#IA6N=~;i2)Q))+y|e^vMMKteSh&_**fg|^Lr2rd
zDEXc7j3fReeNzZV+!3o+0p?V+;Hcu$wA`UQ9~mGWzRn@@9@QA1<FV(Q<yt1>5TqC%
zF4*UxXZ0>R-`)uig#Z;bX4sVg2U=u<L-d({0Bbx7BgK4Qu+uZ>WvDG%@d9N$-ePv#
z(eMlHr^iebWg%H<XzdESfa(`pi3^T7mAXi^Wo8?*MN5NlE2HrYbHuX@lAo|6Cox0Q
z9kSU!0e*jgpAzw|67hDE<8YMPjG<p!g%ZEQ&cauELK%h`o5uw4U9CQw-0Q!!X_#hz
zJPSKxl%E%sp{K_u5rDiiYS<opOg#3|j6QAJ9pJYI4Hg#kWrWhqLggLLhnX?Se~HFS
zP3n<FEucLIjk^XvN9Ego-)U5SKJ0n-hds~7mG`QApU0KY2k!6u!2S7=(K~-+^!(8C
zzx>d%ypr(dhn~-m?ce!h`{#=%@BHE=$^Z4MQ{^S8|Jhfko-hBs^UHtF*H_>9_0^Yu
M0dO?#@8>K40Q2|Mw*UYD

diff --git a/Tests/Suite/Common/TestSuite.h b/Tests/Suite/Common/TestSuite.h
index 7e5ca7e9f6a..b353e7be261 100644
--- a/Tests/Suite/Common/TestSuite.h
+++ b/Tests/Suite/Common/TestSuite.h
@@ -463,14 +463,6 @@ TEST(TESTNAME, LargeCylindersMonteCarlo)
     EXPECT_TRUE(runTest("LargeCylindersMonteCarlo", *sim, 5e-1));
 }
 
-TEST(TESTNAME, SphericalDetWithRoi)
-{
-    const double eps = eps_direct_vs_python(5e-13, 1e-10);
-    std::unique_ptr<const MultiLayer> sample(ExemplarySamples::createCylindersAndPrisms());
-    auto sim = test::makeSimulation::SphericalDetWithRoi(*sample);
-    EXPECT_TRUE(runTest("SphericalDetWithRoi", *sim, eps));
-}
-
 TEST(TESTNAME, RectDetWithRoi)
 {
     const double eps = eps_direct_vs_python(5e-13, 1e-10);
@@ -557,6 +549,14 @@ TEST(TESTNAME, RelativeResolutionTOF)
     EXPECT_TRUE(runTest("RelativeResolutionTOF", *sim, eps));
 }
 
+TEST(TESTNAME, SphericalDetWithRoi)
+{
+    const double eps = eps_direct_vs_python(5e-13, 1e-10);
+    std::unique_ptr<const MultiLayer> sample(ExemplarySamples::createCylindersAndPrisms());
+    auto sim = test::makeSimulation::SphericalDetWithRoi(*sample);
+    EXPECT_TRUE(runTest("SphericalDetWithRoi", *sim, eps));
+}
+
 #endif // GUI_STD_TEST
 
 //  ************************************************************************************************
-- 
GitLab


From 85a1b143e22259616791b81b91bf5575cb016f6a Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de>
Date: Tue, 2 May 2023 11:31:54 +0200
Subject: [PATCH 24/31] only use IAxis::closestIndex

---
 Base/Axis/DiscreteAxis.cpp          | 21 -------
 Base/Axis/DiscreteAxis.h            |  4 --
 Base/Axis/FixedBinAxis.cpp          | 19 ------
 Base/Axis/FixedBinAxis.h            |  2 -
 Base/Axis/IAxis.cpp                 |  2 +-
 Base/Axis/IAxis.h                   |  4 +-
 auto/Wrap/libBornAgainBase.py       | 12 ----
 auto/Wrap/libBornAgainBase_wrap.cpp | 93 -----------------------------
 8 files changed, 2 insertions(+), 155 deletions(-)

diff --git a/Base/Axis/DiscreteAxis.cpp b/Base/Axis/DiscreteAxis.cpp
index 0f4a9ecbb61..927e11878c0 100644
--- a/Base/Axis/DiscreteAxis.cpp
+++ b/Base/Axis/DiscreteAxis.cpp
@@ -52,27 +52,6 @@ DiscreteAxis* DiscreteAxis::clone() const
     return new DiscreteAxis(axisName(), m_coordinates);
 }
 
-size_t DiscreteAxis::closestIndex(double value) const
-{
-    size_t result;
-    if (value <= m_coordinates.front())
-        result = 0;
-    else if (value >= m_coordinates.back())
-        result = m_coordinates.size() - 1;
-    else {
-        const auto begin = m_coordinates.begin();
-        auto it = std::lower_bound(begin, m_coordinates.end(), value);
-        auto index = static_cast<size_t>(std::distance(begin, it));
-        result = value < minary(index) ? index - 1 : index;
-    }
-    if (result != closestIndex1(value)) {
-        std::cerr << "DAx " << min() << " [" << size() << "] " << max() << ": closestIndex("
-                  << value << ") = " << result << "(old) vs (new)" << closestIndex1(value)
-                  << std::endl;
-    }
-    return closestIndex1(value);
-}
-
 void DiscreteAxis::clip(double lower, double upper)
 {
     if (lower >= upper)
diff --git a/Base/Axis/DiscreteAxis.h b/Base/Axis/DiscreteAxis.h
index ea9bcbf64c3..6fb8753279d 100644
--- a/Base/Axis/DiscreteAxis.h
+++ b/Base/Axis/DiscreteAxis.h
@@ -24,12 +24,8 @@ public:
     DiscreteAxis(const std::string& name, const std::vector<double>& points);
     DiscreteAxis(const std::string& name, size_t n, double first, double last);
 
-    //! clone function
     DiscreteAxis* clone() const override;
 
-    //! find index of the coordinate closest to the given value
-    size_t closestIndex(double value) const override;
-
     void clip(double lower, double upper) override;
 
 private:
diff --git a/Base/Axis/FixedBinAxis.cpp b/Base/Axis/FixedBinAxis.cpp
index 76d4810cae9..3a014bf3a4a 100644
--- a/Base/Axis/FixedBinAxis.cpp
+++ b/Base/Axis/FixedBinAxis.cpp
@@ -49,25 +49,6 @@ FixedBinAxis* FixedBinAxis::clone() const
     return result;
 }
 
-size_t FixedBinAxis::closestIndex(double value) const
-{
-    size_t result;
-    if (value < min())
-        result = 0;
-    else if (value >= max())
-        result = m_nbins - 1;
-    else {
-        double step = (m_end - m_start) / m_nbins;
-        result = int((value - m_start) / step);
-    }
-    if (result != closestIndex1(value)) {
-        std::cerr << "FBA " << min() << " [" << size() << "] " << max() << ": closestIndex("
-                  << value << ") = " << result << "(old) vs (new)" << closestIndex1(value)
-                  << std::endl;
-    }
-    return closestIndex1(value);
-}
-
 void FixedBinAxis::clip(double lower, double upper)
 {
     if (lower >= upper)
diff --git a/Base/Axis/FixedBinAxis.h b/Base/Axis/FixedBinAxis.h
index 503257241da..bd5365cd268 100644
--- a/Base/Axis/FixedBinAxis.h
+++ b/Base/Axis/FixedBinAxis.h
@@ -32,8 +32,6 @@ public:
 
     FixedBinAxis* clone() const override;
 
-    size_t closestIndex(double value) const override;
-
     void clip(double lower, double upper) override;
 
 protected:
diff --git a/Base/Axis/IAxis.cpp b/Base/Axis/IAxis.cpp
index 88842a46a86..ffce8b1afea 100644
--- a/Base/Axis/IAxis.cpp
+++ b/Base/Axis/IAxis.cpp
@@ -76,7 +76,7 @@ std::vector<double> IAxis::binCenters() const
     return result;
 }
 
-size_t IAxis::closestIndex1(double value) const
+size_t IAxis::closestIndex(double value) const
 {
     for (size_t i = 0; i < size() - 1; ++i)
         if (value < (bin(i).upperBound() + bin(i + 1).lowerBound()) / 2)
diff --git a/Base/Axis/IAxis.h b/Base/Axis/IAxis.h
index db36001b1f5..087ab5b4538 100644
--- a/Base/Axis/IAxis.h
+++ b/Base/Axis/IAxis.h
@@ -67,10 +67,8 @@ public:
 
     std::vector<double> binCenters() const;
 
-
     //! find bin index which is best match for given value
-    virtual size_t closestIndex(double value) const = 0;
-    size_t closestIndex1(double value) const;
+    size_t closestIndex(double value) const;
 
     //! Clips this axis to the given values
     virtual void clip(double lower, double upper);
diff --git a/auto/Wrap/libBornAgainBase.py b/auto/Wrap/libBornAgainBase.py
index 3a1eb48d591..80a7243c735 100644
--- a/auto/Wrap/libBornAgainBase.py
+++ b/auto/Wrap/libBornAgainBase.py
@@ -1902,10 +1902,6 @@ class IAxis(object):
         r"""closestIndex(IAxis self, double value) -> size_t"""
         return _libBornAgainBase.IAxis_closestIndex(self, value)
 
-    def closestIndex1(self, value):
-        r"""closestIndex1(IAxis self, double value) -> size_t"""
-        return _libBornAgainBase.IAxis_closestIndex1(self, value)
-
     def clip(self, *args):
         r"""
         clip(IAxis self, double lower, double upper)
@@ -1941,10 +1937,6 @@ class FixedBinAxis(IAxis):
         r"""clone(FixedBinAxis self) -> FixedBinAxis"""
         return _libBornAgainBase.FixedBinAxis_clone(self)
 
-    def closestIndex(self, value):
-        r"""closestIndex(FixedBinAxis self, double value) -> size_t"""
-        return _libBornAgainBase.FixedBinAxis_closestIndex(self, value)
-
     def clip(self, lower, upper):
         r"""clip(FixedBinAxis self, double lower, double upper)"""
         return _libBornAgainBase.FixedBinAxis_clip(self, lower, upper)
@@ -1968,10 +1960,6 @@ class DiscreteAxis(IAxis):
         r"""clone(DiscreteAxis self) -> DiscreteAxis"""
         return _libBornAgainBase.DiscreteAxis_clone(self)
 
-    def closestIndex(self, value):
-        r"""closestIndex(DiscreteAxis self, double value) -> size_t"""
-        return _libBornAgainBase.DiscreteAxis_closestIndex(self, value)
-
     def clip(self, lower, upper):
         r"""clip(DiscreteAxis self, double lower, double upper)"""
         return _libBornAgainBase.DiscreteAxis_clip(self, lower, upper)
diff --git a/auto/Wrap/libBornAgainBase_wrap.cpp b/auto/Wrap/libBornAgainBase_wrap.cpp
index 091fcce8fb6..03919aac97f 100644
--- a/auto/Wrap/libBornAgainBase_wrap.cpp
+++ b/auto/Wrap/libBornAgainBase_wrap.cpp
@@ -25595,36 +25595,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_IAxis_closestIndex1(PyObject *self, PyObject *args) {
-  PyObject *resultobj = 0;
-  IAxis *arg1 = (IAxis *) 0 ;
-  double arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  PyObject *swig_obj[2] ;
-  size_t result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "IAxis_closestIndex1", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IAxis, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IAxis_closestIndex1" "', argument " "1"" of type '" "IAxis const *""'"); 
-  }
-  arg1 = reinterpret_cast< IAxis * >(argp1);
-  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IAxis_closestIndex1" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  result = ((IAxis const *)arg1)->closestIndex1(arg2);
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_IAxis_clip__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) {
   PyObject *resultobj = 0;
   IAxis *arg1 = (IAxis *) 0 ;
@@ -26000,36 +25970,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_FixedBinAxis_closestIndex(PyObject *self, PyObject *args) {
-  PyObject *resultobj = 0;
-  FixedBinAxis *arg1 = (FixedBinAxis *) 0 ;
-  double arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  PyObject *swig_obj[2] ;
-  size_t result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "FixedBinAxis_closestIndex", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_FixedBinAxis, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "FixedBinAxis_closestIndex" "', argument " "1"" of type '" "FixedBinAxis const *""'"); 
-  }
-  arg1 = reinterpret_cast< FixedBinAxis * >(argp1);
-  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "FixedBinAxis_closestIndex" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  result = ((FixedBinAxis const *)arg1)->closestIndex(arg2);
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_FixedBinAxis_clip(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   FixedBinAxis *arg1 = (FixedBinAxis *) 0 ;
@@ -26252,36 +26192,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_DiscreteAxis_closestIndex(PyObject *self, PyObject *args) {
-  PyObject *resultobj = 0;
-  DiscreteAxis *arg1 = (DiscreteAxis *) 0 ;
-  double arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  PyObject *swig_obj[2] ;
-  size_t result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "DiscreteAxis_closestIndex", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_DiscreteAxis, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DiscreteAxis_closestIndex" "', argument " "1"" of type '" "DiscreteAxis const *""'"); 
-  }
-  arg1 = reinterpret_cast< DiscreteAxis * >(argp1);
-  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DiscreteAxis_closestIndex" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  result = ((DiscreteAxis const *)arg1)->closestIndex(arg2);
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *_wrap_DiscreteAxis_clip(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   DiscreteAxis *arg1 = (DiscreteAxis *) 0 ;
@@ -28853,7 +28763,6 @@ static PyMethodDef SwigMethods[] = {
 	 { "IAxis_binCenter", _wrap_IAxis_binCenter, METH_VARARGS, "IAxis_binCenter(IAxis self, size_t i) -> double"},
 	 { "IAxis_binCenters", _wrap_IAxis_binCenters, METH_O, "IAxis_binCenters(IAxis self) -> vdouble1d_t"},
 	 { "IAxis_closestIndex", _wrap_IAxis_closestIndex, METH_VARARGS, "IAxis_closestIndex(IAxis self, double value) -> size_t"},
-	 { "IAxis_closestIndex1", _wrap_IAxis_closestIndex1, METH_VARARGS, "IAxis_closestIndex1(IAxis self, double value) -> size_t"},
 	 { "IAxis_clip", _wrap_IAxis_clip, METH_VARARGS, "\n"
 		"IAxis_clip(IAxis self, double lower, double upper)\n"
 		"IAxis_clip(IAxis self, pvacuum_double_t bounds)\n"
@@ -28867,7 +28776,6 @@ static PyMethodDef SwigMethods[] = {
 		"new_FixedBinAxis(FixedBinAxis arg1) -> FixedBinAxis\n"
 		""},
 	 { "FixedBinAxis_clone", _wrap_FixedBinAxis_clone, METH_O, "FixedBinAxis_clone(FixedBinAxis self) -> FixedBinAxis"},
-	 { "FixedBinAxis_closestIndex", _wrap_FixedBinAxis_closestIndex, METH_VARARGS, "FixedBinAxis_closestIndex(FixedBinAxis self, double value) -> size_t"},
 	 { "FixedBinAxis_clip", _wrap_FixedBinAxis_clip, METH_VARARGS, "FixedBinAxis_clip(FixedBinAxis self, double lower, double upper)"},
 	 { "FixedBinAxis_swigregister", FixedBinAxis_swigregister, METH_O, NULL},
 	 { "FixedBinAxis_swiginit", FixedBinAxis_swiginit, METH_VARARGS, NULL},
@@ -28876,7 +28784,6 @@ static PyMethodDef SwigMethods[] = {
 		"new_DiscreteAxis(std::string const & name, size_t n, double first, double last) -> DiscreteAxis\n"
 		""},
 	 { "DiscreteAxis_clone", _wrap_DiscreteAxis_clone, METH_O, "DiscreteAxis_clone(DiscreteAxis self) -> DiscreteAxis"},
-	 { "DiscreteAxis_closestIndex", _wrap_DiscreteAxis_closestIndex, METH_VARARGS, "DiscreteAxis_closestIndex(DiscreteAxis self, double value) -> size_t"},
 	 { "DiscreteAxis_clip", _wrap_DiscreteAxis_clip, METH_VARARGS, "DiscreteAxis_clip(DiscreteAxis self, double lower, double upper)"},
 	 { "delete_DiscreteAxis", _wrap_delete_DiscreteAxis, METH_O, "delete_DiscreteAxis(DiscreteAxis self)"},
 	 { "DiscreteAxis_swigregister", DiscreteAxis_swigregister, METH_O, NULL},
-- 
GitLab


From be8d58521f0bd22c3cd78ff140862bcfa4a09799 Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de>
Date: Tue, 2 May 2023 11:49:56 +0200
Subject: [PATCH 25/31] ...

---
 Base/Axis/Bin.h                     |  2 ++
 Base/Axis/IAxis.cpp                 |  2 +-
 auto/Wrap/libBornAgainBase.py       |  4 ++++
 auto/Wrap/libBornAgainBase_wrap.cpp | 36 +++++++++++++++++++++++++++++
 4 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/Base/Axis/Bin.h b/Base/Axis/Bin.h
index 6b7e1fef8c9..ebc49750647 100644
--- a/Base/Axis/Bin.h
+++ b/Base/Axis/Bin.h
@@ -28,6 +28,8 @@ public:
     double center() const { return (m_lower + m_upper) / 2; }
     double binSize() const { return m_upper - m_lower; }
 
+    bool operator==(const Bin1D& other) const = default;
+
 private:
     Bin1D(double lower, double upper);
 
diff --git a/Base/Axis/IAxis.cpp b/Base/Axis/IAxis.cpp
index ffce8b1afea..ea2a0c3b929 100644
--- a/Base/Axis/IAxis.cpp
+++ b/Base/Axis/IAxis.cpp
@@ -86,7 +86,7 @@ size_t IAxis::closestIndex(double value) const
 
 bool IAxis::equals(const IAxis& other) const
 {
-    return axisName() == other.axisName();
+    return m_name == other.m_name && m_bins == other.m_bins;
 }
 
 void IAxis::clip(double /*lower*/, double /*upper*/)
diff --git a/auto/Wrap/libBornAgainBase.py b/auto/Wrap/libBornAgainBase.py
index 80a7243c735..126242827d3 100644
--- a/auto/Wrap/libBornAgainBase.py
+++ b/auto/Wrap/libBornAgainBase.py
@@ -1821,6 +1821,10 @@ class Bin1D(object):
     def binSize(self):
         r"""binSize(Bin1D self) -> double"""
         return _libBornAgainBase.Bin1D_binSize(self)
+
+    def __eq__(self, other):
+        r"""__eq__(Bin1D self, Bin1D other) -> bool"""
+        return _libBornAgainBase.Bin1D___eq__(self, other)
     __swig_destroy__ = _libBornAgainBase.delete_Bin1D
 
 # Register Bin1D in _libBornAgainBase:
diff --git a/auto/Wrap/libBornAgainBase_wrap.cpp b/auto/Wrap/libBornAgainBase_wrap.cpp
index 03919aac97f..41af79043fc 100644
--- a/auto/Wrap/libBornAgainBase_wrap.cpp
+++ b/auto/Wrap/libBornAgainBase_wrap.cpp
@@ -25186,6 +25186,41 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_Bin1D___eq__(PyObject *self, PyObject *args) {
+  PyObject *resultobj = 0;
+  Bin1D *arg1 = (Bin1D *) 0 ;
+  Bin1D *arg2 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  PyObject *swig_obj[2] ;
+  bool result;
+  
+  if (!SWIG_Python_UnpackTuple(args, "Bin1D___eq__", 2, 2, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_Bin1D, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Bin1D___eq__" "', argument " "1"" of type '" "Bin1D const *""'"); 
+  }
+  arg1 = reinterpret_cast< Bin1D * >(argp1);
+  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_Bin1D,  0  | 0);
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Bin1D___eq__" "', argument " "2"" of type '" "Bin1D const &""'"); 
+  }
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "Bin1D___eq__" "', argument " "2"" of type '" "Bin1D const &""'"); 
+  }
+  arg2 = reinterpret_cast< Bin1D * >(argp2);
+  result = (bool)((Bin1D const *)arg1)->operator ==((Bin1D const &)*arg2);
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  return resultobj;
+fail:
+  PyErr_Clear();
+  Py_INCREF(Py_NotImplemented);
+  return Py_NotImplemented;
+}
+
+
 SWIGINTERN PyObject *_wrap_delete_Bin1D(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   Bin1D *arg1 = (Bin1D *) 0 ;
@@ -28746,6 +28781,7 @@ static PyMethodDef SwigMethods[] = {
 	 { "Bin1D_upperBound", _wrap_Bin1D_upperBound, METH_O, "Bin1D_upperBound(Bin1D self) -> double"},
 	 { "Bin1D_center", _wrap_Bin1D_center, METH_O, "Bin1D_center(Bin1D self) -> double"},
 	 { "Bin1D_binSize", _wrap_Bin1D_binSize, METH_O, "Bin1D_binSize(Bin1D self) -> double"},
+	 { "Bin1D___eq__", _wrap_Bin1D___eq__, METH_VARARGS, "Bin1D___eq__(Bin1D self, Bin1D other) -> bool"},
 	 { "delete_Bin1D", _wrap_delete_Bin1D, METH_O, "delete_Bin1D(Bin1D self)"},
 	 { "Bin1D_swigregister", Bin1D_swigregister, METH_O, NULL},
 	 { "delete_IAxis", _wrap_delete_IAxis, METH_O, "delete_IAxis(IAxis self)"},
-- 
GitLab


From 462be8a5fc565b3132ef50fc57e54ddf71cf979b Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de>
Date: Tue, 2 May 2023 15:47:03 +0200
Subject: [PATCH 26/31] sort

---
 Device/Beam/FootprintGauss.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Device/Beam/FootprintGauss.cpp b/Device/Beam/FootprintGauss.cpp
index dcc107fe915..944522f67d4 100644
--- a/Device/Beam/FootprintGauss.cpp
+++ b/Device/Beam/FootprintGauss.cpp
@@ -13,10 +13,10 @@
 //  ************************************************************************************************
 
 #include "Device/Beam/FootprintGauss.h"
-#include <numbers>
-using std::numbers::pi;
 #include "Base/Math/Functions.h"
 #include "Base/Util/Assert.h"
+#include <numbers>
+using std::numbers::pi;
 
 FootprintGauss::FootprintGauss(const std::vector<double> P)
     : IFootprintFactor(P)
-- 
GitLab


From de7b5ea2e00e9c5de89b4885a4959f5fdc79c8f5 Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de>
Date: Tue, 2 May 2023 15:49:59 +0200
Subject: [PATCH 27/31] rm synthesized operator!=

---
 Base/Axis/Frame.h                   |  1 -
 auto/Wrap/libBornAgainBase.py       |  4 ----
 auto/Wrap/libBornAgainBase_wrap.cpp | 36 -----------------------------
 3 files changed, 41 deletions(-)

diff --git a/Base/Axis/Frame.h b/Base/Axis/Frame.h
index 2ea8ab95ff6..8da665d1ffa 100644
--- a/Base/Axis/Frame.h
+++ b/Base/Axis/Frame.h
@@ -75,7 +75,6 @@ public:
 
     //! Returns true if both Frame%s have same rank, and all axes are equal.
     bool operator==(const Frame&) const;
-    bool operator!=(const Frame& other) const { return !operator==(other); }
 
 protected:
     OwningVector<const IAxis> m_axes;
diff --git a/auto/Wrap/libBornAgainBase.py b/auto/Wrap/libBornAgainBase.py
index 126242827d3..079d3dfb59a 100644
--- a/auto/Wrap/libBornAgainBase.py
+++ b/auto/Wrap/libBornAgainBase.py
@@ -2034,10 +2034,6 @@ class Frame(ICloneable):
         r"""__eq__(Frame self, Frame arg2) -> bool"""
         return _libBornAgainBase.Frame___eq__(self, arg2)
 
-    def __ne__(self, other):
-        r"""__ne__(Frame self, Frame other) -> bool"""
-        return _libBornAgainBase.Frame___ne__(self, other)
-
 # Register Frame in _libBornAgainBase:
 _libBornAgainBase.Frame_swigregister(Frame)
 class R3(object):
diff --git a/auto/Wrap/libBornAgainBase_wrap.cpp b/auto/Wrap/libBornAgainBase_wrap.cpp
index 41af79043fc..9583a021082 100644
--- a/auto/Wrap/libBornAgainBase_wrap.cpp
+++ b/auto/Wrap/libBornAgainBase_wrap.cpp
@@ -26733,41 +26733,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_Frame___ne__(PyObject *self, PyObject *args) {
-  PyObject *resultobj = 0;
-  Frame *arg1 = (Frame *) 0 ;
-  Frame *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject *swig_obj[2] ;
-  bool result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "Frame___ne__", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_Frame, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Frame___ne__" "', argument " "1"" of type '" "Frame const *""'"); 
-  }
-  arg1 = reinterpret_cast< Frame * >(argp1);
-  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_Frame,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Frame___ne__" "', argument " "2"" of type '" "Frame const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "Frame___ne__" "', argument " "2"" of type '" "Frame const &""'"); 
-  }
-  arg2 = reinterpret_cast< Frame * >(argp2);
-  result = (bool)((Frame const *)arg1)->operator !=((Frame const &)*arg2);
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  return resultobj;
-fail:
-  PyErr_Clear();
-  Py_INCREF(Py_NotImplemented);
-  return Py_NotImplemented;
-}
-
-
 SWIGINTERN PyObject *Frame_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
   if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
@@ -28839,7 +28804,6 @@ static PyMethodDef SwigMethods[] = {
 	 { "Frame_toGlobalIndex", _wrap_Frame_toGlobalIndex, METH_VARARGS, "Frame_toGlobalIndex(Frame self, std::vector< unsigned int,std::allocator< unsigned int > > const & axes_indices) -> size_t"},
 	 { "Frame_hasSameSizes", _wrap_Frame_hasSameSizes, METH_VARARGS, "Frame_hasSameSizes(Frame self, Frame arg2) -> bool"},
 	 { "Frame___eq__", _wrap_Frame___eq__, METH_VARARGS, "Frame___eq__(Frame self, Frame arg2) -> bool"},
-	 { "Frame___ne__", _wrap_Frame___ne__, METH_VARARGS, "Frame___ne__(Frame self, Frame other) -> bool"},
 	 { "Frame_swigregister", Frame_swigregister, METH_O, NULL},
 	 { "Frame_swiginit", Frame_swiginit, METH_VARARGS, NULL},
 	 { "new_R3", _wrap_new_R3, METH_VARARGS, "\n"
-- 
GitLab


From 3b466a4c8279588c075aaf7f111fd61f3c118610 Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de>
Date: Tue, 2 May 2023 15:55:03 +0200
Subject: [PATCH 28/31] IAxis::operator== instead of delegated 'equals'

---
 Base/Axis/DiscreteAxis.cpp          |  9 --------
 Base/Axis/DiscreteAxis.h            |  1 -
 Base/Axis/FixedBinAxis.cpp          | 16 -------------
 Base/Axis/FixedBinAxis.h            |  1 -
 Base/Axis/IAxis.cpp                 |  2 +-
 Base/Axis/IAxis.h                   |  5 +---
 auto/Wrap/libBornAgainBase.py       |  4 ----
 auto/Wrap/libBornAgainBase_wrap.cpp | 36 -----------------------------
 8 files changed, 2 insertions(+), 72 deletions(-)

diff --git a/Base/Axis/DiscreteAxis.cpp b/Base/Axis/DiscreteAxis.cpp
index 927e11878c0..83fe1efbe28 100644
--- a/Base/Axis/DiscreteAxis.cpp
+++ b/Base/Axis/DiscreteAxis.cpp
@@ -76,15 +76,6 @@ void DiscreteAxis::print(std::ostream& ostr) const
     ostr << precision << m_coordinates.back() << "])";
 }
 
-bool DiscreteAxis::equals(const IAxis& other) const
-{
-    if (!IAxis::equals(other))
-        return false;
-    if (const auto* otherAxis = dynamic_cast<const DiscreteAxis*>(&other))
-        return m_coordinates == otherAxis->binCenters();
-    return false;
-}
-
 double DiscreteAxis::minary(size_t index) const
 {
     if (index == 0)
diff --git a/Base/Axis/DiscreteAxis.h b/Base/Axis/DiscreteAxis.h
index 6fb8753279d..b6d76eecd8e 100644
--- a/Base/Axis/DiscreteAxis.h
+++ b/Base/Axis/DiscreteAxis.h
@@ -30,7 +30,6 @@ public:
 
 private:
     void print(std::ostream& ostr) const override;
-    bool equals(const IAxis& other) const override;
 
     double minary(size_t index) const;
     double maxary(size_t index) const;
diff --git a/Base/Axis/FixedBinAxis.cpp b/Base/Axis/FixedBinAxis.cpp
index 3a014bf3a4a..71016aabb72 100644
--- a/Base/Axis/FixedBinAxis.cpp
+++ b/Base/Axis/FixedBinAxis.cpp
@@ -82,22 +82,6 @@ void FixedBinAxis::print(std::ostream& ostr) const
          << ")";
 }
 
-bool FixedBinAxis::equals(const IAxis& other) const
-{
-    if (!IAxis::equals(other))
-        return false;
-    if (const auto* otherAxis = dynamic_cast<const FixedBinAxis*>(&other)) {
-        if (size() != otherAxis->size())
-            return false;
-        if (!BaseUtils::algo::almostEqual(m_start, otherAxis->m_start))
-            return false;
-        if (!BaseUtils::algo::almostEqual(m_end, otherAxis->m_end))
-            return false;
-        return true;
-    }
-    return false;
-}
-
 //... In global namespace.
 
 FixedBinAxis FixedScanAxis(const std::string& name, size_t nbins, double scan_start,
diff --git a/Base/Axis/FixedBinAxis.h b/Base/Axis/FixedBinAxis.h
index bd5365cd268..f9353522c95 100644
--- a/Base/Axis/FixedBinAxis.h
+++ b/Base/Axis/FixedBinAxis.h
@@ -36,7 +36,6 @@ public:
 
 protected:
     void print(std::ostream& ostr) const override;
-    bool equals(const IAxis& other) const override;
 
 private:
     size_t m_nbins;
diff --git a/Base/Axis/IAxis.cpp b/Base/Axis/IAxis.cpp
index ea2a0c3b929..42c28577ace 100644
--- a/Base/Axis/IAxis.cpp
+++ b/Base/Axis/IAxis.cpp
@@ -84,7 +84,7 @@ size_t IAxis::closestIndex(double value) const
     return size() - 1;
 }
 
-bool IAxis::equals(const IAxis& other) const
+bool IAxis::operator==(const IAxis& other) const
 {
     return m_name == other.m_name && m_bins == other.m_bins;
 }
diff --git a/Base/Axis/IAxis.h b/Base/Axis/IAxis.h
index 087ab5b4538..632edea6522 100644
--- a/Base/Axis/IAxis.h
+++ b/Base/Axis/IAxis.h
@@ -77,9 +77,7 @@ public:
     //! bounds.first is lower, bounds.second is upper value.
     void clip(std::pair<double, double> bounds);
 
-    //! test for equality
-    bool operator==(const IAxis& right) const { return equals(right); }
-    bool operator!=(const IAxis& right) const { return !(*this == right); }
+    bool operator==(const IAxis& right) const;
 
     friend std::ostream& operator<<(std::ostream& ostr, const IAxis& m)
     {
@@ -89,7 +87,6 @@ public:
 
 protected:
     virtual void print(std::ostream& ostr) const = 0;
-    virtual bool equals(const IAxis& other) const; // overloaded in child classes
 
     // private:
     std::string m_name;
diff --git a/auto/Wrap/libBornAgainBase.py b/auto/Wrap/libBornAgainBase.py
index 079d3dfb59a..f12810e1dee 100644
--- a/auto/Wrap/libBornAgainBase.py
+++ b/auto/Wrap/libBornAgainBase.py
@@ -1917,10 +1917,6 @@ class IAxis(object):
         r"""__eq__(IAxis self, IAxis right) -> bool"""
         return _libBornAgainBase.IAxis___eq__(self, right)
 
-    def __ne__(self, right):
-        r"""__ne__(IAxis self, IAxis right) -> bool"""
-        return _libBornAgainBase.IAxis___ne__(self, right)
-
 # Register IAxis in _libBornAgainBase:
 _libBornAgainBase.IAxis_swigregister(IAxis)
 class FixedBinAxis(IAxis):
diff --git a/auto/Wrap/libBornAgainBase_wrap.cpp b/auto/Wrap/libBornAgainBase_wrap.cpp
index 9583a021082..239022d14f2 100644
--- a/auto/Wrap/libBornAgainBase_wrap.cpp
+++ b/auto/Wrap/libBornAgainBase_wrap.cpp
@@ -25783,41 +25783,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_IAxis___ne__(PyObject *self, PyObject *args) {
-  PyObject *resultobj = 0;
-  IAxis *arg1 = (IAxis *) 0 ;
-  IAxis *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject *swig_obj[2] ;
-  bool result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "IAxis___ne__", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IAxis, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IAxis___ne__" "', argument " "1"" of type '" "IAxis const *""'"); 
-  }
-  arg1 = reinterpret_cast< IAxis * >(argp1);
-  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_IAxis,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IAxis___ne__" "', argument " "2"" of type '" "IAxis const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IAxis___ne__" "', argument " "2"" of type '" "IAxis const &""'"); 
-  }
-  arg2 = reinterpret_cast< IAxis * >(argp2);
-  result = (bool)((IAxis const *)arg1)->operator !=((IAxis const &)*arg2);
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  return resultobj;
-fail:
-  PyErr_Clear();
-  Py_INCREF(Py_NotImplemented);
-  return Py_NotImplemented;
-}
-
-
 SWIGINTERN PyObject *IAxis_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
   if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
@@ -28769,7 +28734,6 @@ static PyMethodDef SwigMethods[] = {
 		"IAxis_clip(IAxis self, pvacuum_double_t bounds)\n"
 		""},
 	 { "IAxis___eq__", _wrap_IAxis___eq__, METH_VARARGS, "IAxis___eq__(IAxis self, IAxis right) -> bool"},
-	 { "IAxis___ne__", _wrap_IAxis___ne__, METH_VARARGS, "IAxis___ne__(IAxis self, IAxis right) -> bool"},
 	 { "IAxis_swigregister", IAxis_swigregister, METH_O, NULL},
 	 { "delete_FixedBinAxis", _wrap_delete_FixedBinAxis, METH_O, "delete_FixedBinAxis(FixedBinAxis self)"},
 	 { "new_FixedBinAxis", _wrap_new_FixedBinAxis, METH_VARARGS, "\n"
-- 
GitLab


From 2bb82b59c74b7cc48c6b499c32ec0a160d8e0cdf Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de>
Date: Tue, 2 May 2023 15:55:32 +0200
Subject: [PATCH 29/31] rm minary, maxary

---
 Base/Axis/DiscreteAxis.cpp | 14 --------------
 Base/Axis/DiscreteAxis.h   |  2 --
 2 files changed, 16 deletions(-)

diff --git a/Base/Axis/DiscreteAxis.cpp b/Base/Axis/DiscreteAxis.cpp
index 83fe1efbe28..059c50f11bd 100644
--- a/Base/Axis/DiscreteAxis.cpp
+++ b/Base/Axis/DiscreteAxis.cpp
@@ -76,20 +76,6 @@ void DiscreteAxis::print(std::ostream& ostr) const
     ostr << precision << m_coordinates.back() << "])";
 }
 
-double DiscreteAxis::minary(size_t index) const
-{
-    if (index == 0)
-        return m_coordinates.front();
-    return 0.5 * (m_coordinates[index] + m_coordinates[index - 1]);
-}
-
-double DiscreteAxis::maxary(size_t index) const
-{
-    if (index + 1 == m_coordinates.size())
-        return m_coordinates.back();
-    return 0.5 * (m_coordinates[index] + m_coordinates[index + 1]);
-}
-
 void DiscreteAxis::checkIndex(size_t index) const
 {
     if (m_coordinates.size() > index)
diff --git a/Base/Axis/DiscreteAxis.h b/Base/Axis/DiscreteAxis.h
index b6d76eecd8e..9bb8436c91e 100644
--- a/Base/Axis/DiscreteAxis.h
+++ b/Base/Axis/DiscreteAxis.h
@@ -31,8 +31,6 @@ public:
 private:
     void print(std::ostream& ostr) const override;
 
-    double minary(size_t index) const;
-    double maxary(size_t index) const;
     void checkIndex(size_t index) const;
     void sanityCheck() const;
 
-- 
GitLab


From dafbc7505108354192113b5e2f09580e01b1fc18 Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de>
Date: Tue, 2 May 2023 16:39:07 +0200
Subject: [PATCH 30/31] simplify setprecision

---
 Base/Axis/DiscreteAxis.cpp | 5 ++---
 Base/Axis/FixedBinAxis.cpp | 5 ++---
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/Base/Axis/DiscreteAxis.cpp b/Base/Axis/DiscreteAxis.cpp
index 059c50f11bd..00725d36b63 100644
--- a/Base/Axis/DiscreteAxis.cpp
+++ b/Base/Axis/DiscreteAxis.cpp
@@ -68,12 +68,11 @@ void DiscreteAxis::clip(double lower, double upper)
 
 void DiscreteAxis::print(std::ostream& ostr) const
 {
-    auto precision = std::setprecision(std::numeric_limits<double>::digits10 + 2);
     ostr << "DiscreteAxis(\"" << axisName() << "\", "
          << ", [";
     for (size_t i = 0, fin = m_coordinates.size() - 1; i < fin; ++i)
-        ostr << precision << m_coordinates[i] << ",";
-    ostr << precision << m_coordinates.back() << "])";
+        ostr << std::setprecision(17) << m_coordinates[i] << ",";
+    ostr << m_coordinates.back() << "])";
 }
 
 void DiscreteAxis::checkIndex(size_t index) const
diff --git a/Base/Axis/FixedBinAxis.cpp b/Base/Axis/FixedBinAxis.cpp
index 71016aabb72..1a7427333c4 100644
--- a/Base/Axis/FixedBinAxis.cpp
+++ b/Base/Axis/FixedBinAxis.cpp
@@ -77,9 +77,8 @@ void FixedBinAxis::clip(double lower, double upper)
 
 void FixedBinAxis::print(std::ostream& ostr) const
 {
-    ostr << "FixedBinAxis(\"" << axisName() << "\", " << size() << ", "
-         << std::setprecision(std::numeric_limits<double>::digits10 + 2) << min() << ", " << max()
-         << ")";
+    ostr << "FixedBinAxis(\"" << axisName() << "\", " << size() << ", " << std::setprecision(17)
+         << min() << ", " << max() << ")";
 }
 
 //... In global namespace.
-- 
GitLab


From 85c05b3cf01215b91b0e8db7ea81f0ce0c70cd3e Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de>
Date: Tue, 2 May 2023 16:55:17 +0200
Subject: [PATCH 31/31] algo::almostEqual gets 3rd argument ulp

---
 Base/Py/PyFmt.cpp                             | 4 ++--
 Base/Util/Algorithms.h                        | 6 +++---
 Device/Mask/Line.cpp                          | 4 ++--
 Sim/Export/SimulationToPython.cpp             | 6 ++----
 Tests/Unit/Device/RectangularDetectorTest.cpp | 6 +++---
 Tests/Unit/GUI/TestFormFactorItems.cpp        | 2 +-
 6 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/Base/Py/PyFmt.cpp b/Base/Py/PyFmt.cpp
index 1f343ffd335..9217267dd83 100644
--- a/Base/Py/PyFmt.cpp
+++ b/Base/Py/PyFmt.cpp
@@ -183,12 +183,12 @@ std::string Py::Fmt::printFunction(const std::string& name, double value1, const
 
 bool Py::Fmt::isSquare(double length1, double length2, double angle)
 {
-    return length1 == length2 && BaseUtils::algo::almostEqual(angle, (pi / 2));
+    return length1 == length2 && BaseUtils::algo::almostEqual(angle, (pi / 2), 2);
 }
 
 bool Py::Fmt::isHexagonal(double length1, double length2, double angle)
 {
-    return length1 == length2 && BaseUtils::algo::almostEqual(angle, (2 * pi) / 3.0);
+    return length1 == length2 && BaseUtils::algo::almostEqual(angle, (2 * pi) / 3.0, 2);
 }
 
 std::string Py::Fmt::printKvector(const R3 value)
diff --git a/Base/Util/Algorithms.h b/Base/Util/Algorithms.h
index ed71de382e4..a450c5b9377 100644
--- a/Base/Util/Algorithms.h
+++ b/Base/Util/Algorithms.h
@@ -27,11 +27,11 @@
 
 namespace BaseUtils::algo {
 
-//! Returns true if two doubles agree within machine epsilon.
-inline bool almostEqual(double a, double b)
+//! Returns true if two doubles agree within machine epsilon times ulp (units in the last place).
+inline bool almostEqual(double a, double b, int ulp)
 {
     constexpr double eps = std::numeric_limits<double>::epsilon();
-    return std::abs(a - b) <= eps * std::max(eps, (std::abs(a) + std::abs(b)) / 2);
+    return std::abs(a - b) <= eps * ulp * (std::abs(a) + std::abs(b)) / 2;
 }
 
 //! Returns the minimum value of function evaluate as applied to the elements of an iterator range.
diff --git a/Device/Mask/Line.cpp b/Device/Mask/Line.cpp
index ec8f9daae52..d45719468af 100644
--- a/Device/Mask/Line.cpp
+++ b/Device/Mask/Line.cpp
@@ -73,7 +73,7 @@ VerticalLine::VerticalLine(double x)
 
 bool VerticalLine::contains(double x, double /*y*/) const
 {
-    return BaseUtils::algo::almostEqual(x, m_x);
+    return BaseUtils::algo::almostEqual(x, m_x, 2);
 }
 
 bool VerticalLine::contains(const Bin1D& binx, const Bin1D& /*biny*/) const
@@ -92,7 +92,7 @@ HorizontalLine::HorizontalLine(double y)
 
 bool HorizontalLine::contains(double /*x*/, double y) const
 {
-    return BaseUtils::algo::almostEqual(y, m_y);
+    return BaseUtils::algo::almostEqual(y, m_y, 2);
 }
 
 bool HorizontalLine::contains(const Bin1D& /*binx*/, const Bin1D& biny) const
diff --git a/Sim/Export/SimulationToPython.cpp b/Sim/Export/SimulationToPython.cpp
index 796c0a6a90e..76ab922ea6c 100644
--- a/Sim/Export/SimulationToPython.cpp
+++ b/Sim/Export/SimulationToPython.cpp
@@ -15,7 +15,6 @@
 #include "Sim/Export/SimulationToPython.h"
 #include "Base/Axis/IAxis.h"
 #include "Base/Py/PyFmt.h"
-#include "Base/Util/Algorithms.h"
 #include "Base/Util/Assert.h"
 #include "Device/Beam/Beam.h"
 #include "Device/Beam/FootprintGauss.h"
@@ -65,9 +64,8 @@ bool isQuadraticDetector(const IDetector& det)
 //! Returns true if it is (0, -1, 0) vector
 bool isDefaultDirection(const R3 direction)
 {
-    return BaseUtils::algo::almostEqual(direction.x(), 0.0)
-           && BaseUtils::algo::almostEqual(direction.y(), -1.0)
-           && BaseUtils::algo::almostEqual(direction.z(), 0.0);
+    return fabs(direction.x()) < 5e-16 && fabs(direction.y() + 1) < 1e-15
+           && fabs(direction.z()) < 5e-16;
 }
 
 std::string defineFootprintFactor(const IFootprintFactor& foot)
diff --git a/Tests/Unit/Device/RectangularDetectorTest.cpp b/Tests/Unit/Device/RectangularDetectorTest.cpp
index 8a04f7950ac..6ebc889925f 100644
--- a/Tests/Unit/Device/RectangularDetectorTest.cpp
+++ b/Tests/Unit/Device/RectangularDetectorTest.cpp
@@ -17,9 +17,9 @@ double alpha(R3 k)
 
 bool isEqual(const R3 lhs, const R3 rhs)
 {
-    bool is_equal = BaseUtils::algo::almostEqual(lhs.x(), rhs.x())
-                    && BaseUtils::algo::almostEqual(lhs.y(), rhs.y())
-                    && BaseUtils::algo::almostEqual(lhs.z(), rhs.z());
+    bool is_equal = BaseUtils::algo::almostEqual(lhs.x(), rhs.x(), 2)
+                    && BaseUtils::algo::almostEqual(lhs.y(), rhs.y(), 2)
+                    && BaseUtils::algo::almostEqual(lhs.z(), rhs.z(), 2);
     if (!is_equal)
         std::cout << "lhs:" << lhs << " rhs:" << rhs << " diff:" << (lhs - rhs) << std::endl;
     return is_equal;
diff --git a/Tests/Unit/GUI/TestFormFactorItems.cpp b/Tests/Unit/GUI/TestFormFactorItems.cpp
index 7a20ecf3821..7435739935e 100644
--- a/Tests/Unit/GUI/TestFormFactorItems.cpp
+++ b/Tests/Unit/GUI/TestFormFactorItems.cpp
@@ -18,5 +18,5 @@ TEST(TestFormFactorItems, Pyramid2Item)
     EXPECT_EQ(p_ff->length(), 20.0);
     EXPECT_EQ(p_ff->width(), 16.0);
     EXPECT_EQ(p_ff->height(), 13.0);
-    EXPECT_TRUE(BaseUtils::algo::almostEqual(p_ff->alpha(), Units::deg2rad(60.0)));
+    EXPECT_TRUE(BaseUtils::algo::almostEqual(p_ff->alpha(), Units::deg2rad(60.0), 2));
 }
-- 
GitLab