diff --git a/.clang-tidy b/.clang-tidy
index cca76d22e646f94bc91fa5d71a367baded34e253..7212210e12c822617c358c6b57e55186f4182171 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -3,7 +3,8 @@
 # This is the BornAgain configuration for clang-tidy.
 #
 # To invoke clang-tidy, run
-#   cmake -DBORNAGAIN_TIDY=ON -DBORNAGAIN_PYTHON=OFF -DBORNAGAIN_GUI=OFF ..
+#   setclang
+#   cmake -DBA_TIDY=ON -DBORNAGAIN_PYTHON=OFF -DBA_GUI=OFF ..
 #   make
 #
 # Below, we select all checks ('*'), then deselect quite a number of them.
@@ -24,7 +25,7 @@ Checks: '*,
 -*-trailing-return*,
 -*-uppercase-literal-suffix,
 -*nodiscard,
--abseil-string-find-str-contains,
+-abseil-*,
 -altera-unroll-loops,
 -bugprone-branch-clone,
 -bugprone-easily-swappable-parameters,
@@ -55,6 +56,7 @@ Checks: '*,
 -google-build-using-namespace,
 -google-default-arguments,
 -google-explicit-constructor,
+-google-readability-avoid-underscore-in-googletest-name,
 -google-readability-casting,
 -google-readability-todo,
 -google-runtime-int,
@@ -68,6 +70,7 @@ Checks: '*,
 -llvmlibc-restrict-system-libc-headers,
 -misc-no-recursion,
 -misc-throw-by-value-catch-by-reference,
+-performance-faster-string-find,
 -performance-inefficient-string-concatenation,
 -performance-noexcept-move-constructor,
 -performance-no-automatic-move,
diff --git a/Base/Axis/Coordinate.cpp b/Base/Axis/Coordinate.cpp
index e98cc4e242fd31d41cf2fc62fb772d2fe331001c..809e16af343d9956ce0899514023a6f38d964e3b 100644
--- a/Base/Axis/Coordinate.cpp
+++ b/Base/Axis/Coordinate.cpp
@@ -38,9 +38,9 @@ std::pair<std::string, std::string> parse_label(const std::string& label)
 } // namespace
 
 
-Coordinate::Coordinate(const std::string& name, const std::string& unit)
-    : m_name(name)
-    , m_unit(unit)
+Coordinate::Coordinate(std::string name, std::string unit)
+    : m_name(std::move(name))
+    , m_unit(std::move(unit))
 {
 }
 
diff --git a/Base/Axis/Coordinate.h b/Base/Axis/Coordinate.h
index 71f05679a94f112e7834fd92f6621b183bf015f7..08323db8ed2a7f0284665985913e9f7a171302fc 100644
--- a/Base/Axis/Coordinate.h
+++ b/Base/Axis/Coordinate.h
@@ -22,7 +22,7 @@
 class Coordinate {
 public:
     Coordinate(const std::string& label);
-    Coordinate(const std::string& name, const std::string& unit);
+    Coordinate(std::string name, std::string unit);
 
     bool operator==(const Coordinate& other) const = default;
 
diff --git a/Base/Axis/MakeScale.cpp b/Base/Axis/MakeScale.cpp
index 460fcc6c06d34e65f23b7352e3b88a2b3abb3f49..a65e063ffe2543e9a91ca3d7bfde27402f0dc0af 100644
--- a/Base/Axis/MakeScale.cpp
+++ b/Base/Axis/MakeScale.cpp
@@ -16,37 +16,37 @@
 #include "Base/Axis/Scale.h"
 #include "Base/Util/Assert.h"
 
-Scale GenericScale(const std::string& name, const std::vector<double>& limits)
+Scale GenericScale(std::string name, const std::vector<double>& limits)
 {
     std::vector<Bin1D> vec;
     ASSERT(!(limits.size() & 1)); // must be an even number
     for (size_t i = 0; i < limits.size(); i += 2)
         vec.emplace_back(Bin1D::FromTo(limits[i], limits[i + 1]));
-    return Scale(name, vec);
+    return {name, vec};
 }
 
-Scale* newGenericScale(const std::string& name, const std::vector<double>& limits)
+Scale* newGenericScale(std::string name, const std::vector<double>& limits)
 {
     return new Scale(GenericScale(name, limits));
 }
 
 
-Scale ListScan(const std::string& name, const std::vector<double>& points)
+Scale ListScan(std::string name, const std::vector<double>& points)
 {
     std::vector<Bin1D> vec;
     vec.reserve(points.size());
     for (double p : points)
         vec.emplace_back(Bin1D::At(p));
-    return Scale(name, vec);
+    return {name, vec};
 }
 
-Scale* newListScan(const std::string& name, const std::vector<double>& points)
+Scale* newListScan(std::string name, const std::vector<double>& points)
 {
     return new Scale(ListScan(name, points));
 }
 
 
-Scale EquiDivision(const std::string& name, size_t N, double start, double end)
+Scale EquiDivision(std::string name, size_t N, double start, double end)
 {
     ASSERT(N > 0);
     ASSERT(start <= end);
@@ -57,28 +57,26 @@ Scale EquiDivision(const std::string& name, size_t N, double start, double end)
                                        (N - i - 1) * (start / N) + (i + 1) * (end / N)));
     ASSERT(vec.size() == N);
 
-    return Scale(name, vec);
+    return {name, vec};
 }
 
-Scale* newEquiDivision(const std::string& name, size_t N, double start, double end)
+Scale* newEquiDivision(std::string name, size_t N, double start, double end)
 {
     return new Scale(EquiDivision(name, N, start, end));
 }
 
-std::shared_ptr<Scale> sharedEquiDivision(const std::string& name, size_t N, double start,
-                                          double end)
+std::shared_ptr<Scale> sharedEquiDivision(std::string name, size_t N, double start, double end)
 {
     return std::shared_ptr<Scale>(newEquiDivision(name, N, start, end));
 }
 
-std::unique_ptr<Scale> uniqueEquiDivision(const std::string& name, size_t N, double start,
-                                          double end)
+std::unique_ptr<Scale> uniqueEquiDivision(std::string name, size_t N, double start, double end)
 {
     return std::unique_ptr<Scale>(newEquiDivision(name, N, start, end));
 }
 
 
-Scale EquiScan(const std::string& name, size_t N, double start, double end)
+Scale EquiScan(std::string name, size_t N, double start, double end)
 {
     ASSERT(N);
     std::vector<Bin1D> vec;
@@ -93,20 +91,20 @@ Scale EquiScan(const std::string& name, size_t N, double start, double end)
         ASSERT(vec.size() == N);
     }
 
-    return Scale(name, vec);
+    return {name, vec};
 }
 
-Scale* newEquiScan(const std::string& name, size_t N, double start, double end)
+Scale* newEquiScan(std::string name, size_t N, double start, double end)
 {
     return new Scale(EquiScan(name, N, start, end));
 }
 
-std::shared_ptr<Scale> sharedEquiScan(const std::string& name, size_t N, double start, double end)
+std::shared_ptr<Scale> sharedEquiScan(std::string name, size_t N, double start, double end)
 {
     return std::shared_ptr<Scale>(newEquiDivision(name, N, start, end));
 }
 
-std::unique_ptr<Scale> uniqueEquiScan(const std::string& name, size_t N, double start, double end)
+std::unique_ptr<Scale> uniqueEquiScan(std::string name, size_t N, double start, double end)
 {
     return std::unique_ptr<Scale>(newEquiDivision(name, N, start, end));
 }
diff --git a/Base/Axis/MakeScale.h b/Base/Axis/MakeScale.h
index 830b13aff22d2ce22d2f4bbbe8aa8f3296506422..2f5f72139d860292269fbe5d1a04567f35b24491 100644
--- a/Base/Axis/MakeScale.h
+++ b/Base/Axis/MakeScale.h
@@ -21,32 +21,30 @@
 
 class Scale;
 
-Scale GenericScale(const std::string& name, const std::vector<double>& limits);
+Scale GenericScale(std::string name, const std::vector<double>& limits);
 #ifndef SWIG
-Scale* newGenericScale(const std::string& name, const std::vector<double>& limits);
+Scale* newGenericScale(std::string name, const std::vector<double>& limits);
 #endif // SWIG
 
-Scale ListScan(const std::string& name, const std::vector<double>& points);
+Scale ListScan(std::string name, const std::vector<double>& points);
 #ifndef SWIG
-Scale* newListScan(const std::string& name, const std::vector<double>& points);
+Scale* newListScan(std::string name, const std::vector<double>& points);
 #endif // SWIG
 
 //! Returns axis with fixed bin size.
-Scale EquiDivision(const std::string& name, size_t N, double start, double end);
+Scale EquiDivision(std::string name, size_t N, double start, double end);
 #ifndef SWIG
-Scale* newEquiDivision(const std::string& name, size_t N, double start, double end);
-std::shared_ptr<Scale> sharedEquiDivision(const std::string& name, size_t N, double start,
-                                          double end);
-std::unique_ptr<Scale> uniqueEquiDivision(const std::string& name, size_t N, double start,
-                                          double end);
+Scale* newEquiDivision(std::string name, size_t N, double start, double end);
+std::shared_ptr<Scale> sharedEquiDivision(std::string name, size_t N, double start, double end);
+std::unique_ptr<Scale> uniqueEquiDivision(std::string name, size_t N, double start, double end);
 #endif // SWIG
 
 //! Returns axis with equidistant points (zero bin width).
-Scale EquiScan(const std::string& name, size_t N, double start, double end);
+Scale EquiScan(std::string name, size_t N, double start, double end);
 #ifndef SWIG
-Scale* newEquiScan(const std::string& name, size_t N, double start, double end);
-std::shared_ptr<Scale> sharedEquiScan(const std::string& name, size_t N, double start, double end);
-std::unique_ptr<Scale> uniqueEquiScan(const std::string& name, size_t N, double start, double end);
+Scale* newEquiScan(std::string name, size_t N, double start, double end);
+std::shared_ptr<Scale> sharedEquiScan(std::string name, size_t N, double start, double end);
+std::unique_ptr<Scale> uniqueEquiScan(std::string name, size_t N, double start, double end);
 #endif // SWIG
 
 #endif // BORNAGAIN_BASE_AXIS_MAKESCALE_H
diff --git a/Base/Axis/Scale.cpp b/Base/Axis/Scale.cpp
index fc239405f607c60ed0f4478f31555d332107158e..25575d914c22f34220492ea38fbe6a46af81c491 100644
--- a/Base/Axis/Scale.cpp
+++ b/Base/Axis/Scale.cpp
@@ -19,9 +19,9 @@
 #include <numbers>
 using std::numbers::pi;
 
-Scale::Scale(const Coordinate& coord, const std::vector<Bin1D>& bins)
+Scale::Scale(const Coordinate& coord, std::vector<Bin1D> bins)
     : m_coord(coord)
-    , m_bins(bins)
+    , m_bins(std::move(bins))
 {
     ASSERT(size() > 0);
     for (size_t i = 0; i < size() - 1; ++i) {
@@ -200,7 +200,7 @@ Scale Scale::plottableScale() const
             double bma = b.upperBound() * 180 / pi;
             outvector.emplace_back(Bin1D::FromTo(bmi, bma));
         }
-        return Scale(outname, outvector);
+        return {outname, outvector};
     }
     return *this;
 }
diff --git a/Base/Axis/Scale.h b/Base/Axis/Scale.h
index 296a3dab4ac24addc8d17d13c1d8067f8082e54b..8516866e035c4dbb0e9894556c801ce5838d87eb 100644
--- a/Base/Axis/Scale.h
+++ b/Base/Axis/Scale.h
@@ -25,7 +25,7 @@
 
 class Scale {
 public:
-    Scale(const Coordinate& coord, const std::vector<Bin1D>& bins);
+    Scale(const Coordinate& coord, std::vector<Bin1D> bins);
     Scale* clone() const { return new Scale(*this); }
 
     //! Returns the label of the axis
@@ -71,9 +71,9 @@ public:
     Scale clipped(double lower, double upper) const;
     Scale clipped(std::pair<double, double> bounds) const;
 
-    bool operator==(const Scale& right) const;
+    bool operator==(const Scale& other) const;
 
-    friend std::ostream& operator<<(std::ostream& ostr, const Scale& m);
+    friend std::ostream& operator<<(std::ostream& ostr, const Scale& ax);
 
     std::string unit() const;
 
diff --git a/Base/Math/Numeric.cpp b/Base/Math/Numeric.cpp
index 1cfb2c801bbf9e07969c06778a6b0385b10d3bee..f481b337bbe34ac9fc123e6d043d78b24062ffc2 100644
--- a/Base/Math/Numeric.cpp
+++ b/Base/Math/Numeric.cpp
@@ -18,6 +18,7 @@
 #include <cstdlib>
 #include <limits>
 
+//! For tests only.
 void check_scalar(double a, double b, int ulp)
 {
     if (!Numeric::almostEqual(a, b, ulp))
diff --git a/Base/Util/StringUtil.cpp b/Base/Util/StringUtil.cpp
index 01e741d7c8a43d071d84007e5a34baa42a88e5b3..c140fb7932eb3958a4c1689346a349d87ee51df5 100644
--- a/Base/Util/StringUtil.cpp
+++ b/Base/Util/StringUtil.cpp
@@ -143,7 +143,7 @@ std::vector<int> Base::String::expandNumberList(const std::string& pattern)
     for (const std::string& word : split(trim(pattern), ",")) {
 
         std::vector<std::string> parts = split(trim(word), "-");
-        if (parts.size() < 1)
+        if (parts.empty())
             throw std::runtime_error("invalid number list");
         if (parts.size() > 2)
             throw std::runtime_error("invalid number list");
diff --git a/CMakeLists.txt b/CMakeLists.txt
index aa1d0b54b959047825818e40bae08ecb212f52ae..7a5780d25ae91a1b4a9986ea27bb09fbc4d65999 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -88,6 +88,7 @@ if(BA_GUI AND NOT BORNAGAIN_PYTHON AND NOT BA_TIDY)
         " (except with BA_TIDY)")
 endif()
 
+
 ### Generator type (Release|Debug)
 
 # Show info about generator type; set CMAKE_BUILD_TYPE if not given
diff --git a/Device/Data/DataUtil.cpp b/Device/Data/DataUtil.cpp
index c51da04e041f677c2e1c96034c42c9957d195ae8..342ed40a419af9ada66ab1f5a5a6a8dcb8672772 100644
--- a/Device/Data/DataUtil.cpp
+++ b/Device/Data/DataUtil.cpp
@@ -63,7 +63,7 @@ DataUtil::Data::invertAxis(int axis, const std::vector<std::vector<double>>& ori
 std::vector<std::vector<double>>
 DataUtil::Data::transpose(const std::vector<std::vector<double>>& original)
 {
-    ASSERT(original.size() > 0);
+    ASSERT(!original.empty());
 
     size_t orig_rows = original.size();
     size_t orig_cols = original.front().size();
diff --git a/Device/Data/Datafield.cpp b/Device/Data/Datafield.cpp
index 240d66f7e891827a0199ba002fd19f49e1d22bb2..965b5a644848367386753d379535aaa6613ab89d 100644
--- a/Device/Data/Datafield.cpp
+++ b/Device/Data/Datafield.cpp
@@ -18,9 +18,9 @@
 #include "Base/Util/Assert.h"
 #include <algorithm>
 
-Datafield::Datafield(const std::string& title, const Frame* frame,
-                     const std::vector<double>& values, const std::vector<double>& errSigmas)
-    : m_title(title)
+Datafield::Datafield(std::string title, const Frame* frame, const std::vector<double>& values,
+                     const std::vector<double>& errSigmas)
+    : m_title(std::move(title))
     , m_frame(frame)
     , m_values(values.empty() ? std::vector<double>(frame->size(), 0.) : values)
     , m_errSigmas(errSigmas)
@@ -42,7 +42,7 @@ Datafield::Datafield(std::vector<const Scale*>&& axes, const std::vector<double>
 {
 }
 
-Datafield::Datafield(Datafield&&) = default;
+Datafield::Datafield(Datafield&&) noexcept = default;
 
 Datafield::Datafield(const Datafield& other)
     : Datafield(other.title(), other.m_frame ? other.m_frame->clone() : nullptr, other.m_values,
diff --git a/Device/Data/Datafield.h b/Device/Data/Datafield.h
index 02230408e26a8d014312a867ae04555d24ca60b1..6ed1721dc61c3487483fd0382b9992e57ec9a4ba 100644
--- a/Device/Data/Datafield.h
+++ b/Device/Data/Datafield.h
@@ -30,7 +30,7 @@ class Frame;
 
 class Datafield {
 public:
-    Datafield(const std::string& title, const Frame* frame, const std::vector<double>& values = {},
+    Datafield(std::string title, const Frame* frame, const std::vector<double>& values = {},
               const std::vector<double>& errSigmas = {});
 
     //! Constructor that takes ownership of supplied frame and initializes values and errorbars
@@ -42,7 +42,7 @@ public:
               const std::vector<double>& errSigmas = {});
 
     Datafield(const Datafield&);
-    Datafield(Datafield&&);
+    Datafield(Datafield&&) noexcept;
     virtual ~Datafield();
 
     Datafield& operator=(Datafield&& other) noexcept;
diff --git a/Device/Detector/FlatDetector.cpp b/Device/Detector/FlatDetector.cpp
index 793d3d6a7eb53a3e8b43b2a644512679f0b1ec08..dcc3ac616a2c4b2f52b4b7a2ae0490dd5ae30076 100644
--- a/Device/Detector/FlatDetector.cpp
+++ b/Device/Detector/FlatDetector.cpp
@@ -217,5 +217,5 @@ void FlatDetector::initUandV()
 
 Frame FlatDetector::scatteringCoords() const
 {
-    return Frame(axesClippedToRegionOfInterest());
+    return {axesClippedToRegionOfInterest()};
 }
diff --git a/Device/Detector/SphericalDetector.cpp b/Device/Detector/SphericalDetector.cpp
index 079a6be7a4cd1b77f739b74cd311ebcbf426b40c..519200c66311960209d0bd3db860ed2d1927cb04 100644
--- a/Device/Detector/SphericalDetector.cpp
+++ b/Device/Detector/SphericalDetector.cpp
@@ -21,9 +21,6 @@
 #include "Base/Util/Assert.h"
 #include "Device/Beam/Beam.h"
 #include "Device/Resolution/IDetectorResolution.h"
-#include <numbers>
-
-using std::numbers::pi;
 
 SphericalDetector::SphericalDetector(const Frame& frame)
     : IDetector(frame)
diff --git a/Device/IO/DiffUtil.cpp b/Device/IO/DiffUtil.cpp
index faa7a2acde33c6ed7d201ce3df43a141c9a383c0..c93f8e5f948d290ea35bf844b9af801ade5691cf 100644
--- a/Device/IO/DiffUtil.cpp
+++ b/Device/IO/DiffUtil.cpp
@@ -40,7 +40,7 @@ Datafield DiffUtil::relativeDifferenceField(const Datafield& dat, const Datafiel
     std::vector<double> out(dat.size());
     for (size_t i = 0; i < dat.size(); ++i)
         out[i] = Numeric::relativeDifference(dat[i], ref[i]);
-    return Datafield(dat.frame().clone(), out);
+    return {dat.frame().clone(), out};
 }
 
 //! Returns sum of relative differences between each pair of elements:
diff --git a/Device/IO/ParseUtil.cpp b/Device/IO/ParseUtil.cpp
index 1ef188b48ebb2fcc8cdc700020c144f3d3109f36..5dbf01ad4adc6d7df6dbf43c3d74973273fea401 100644
--- a/Device/IO/ParseUtil.cpp
+++ b/Device/IO/ParseUtil.cpp
@@ -52,7 +52,7 @@ std::vector<double> parse_x_list(std::string text, const std::string& type)
             throw std::runtime_error("Reading " + type + ": cannot read entry '" + e + "'");
         result.push_back(x);
     }
-    if (!result.size())
+    if (result.empty())
         throw std::runtime_error("Reading " + type + ": found empty list");
     return result;
 }
@@ -79,15 +79,14 @@ Scale* Util::Parse::parseScale(std::istream& input_stream)
               && Base::String::to_double(arr[2], &xma)))
             throw std::runtime_error("Reading EquiDivision: cannot read parameters");
         return newEquiDivision(name, nbins, xmi, xma);
-
-    } else if (type == "ListScan" || type == "DiscreteAxis" /* for compatibility with pre-21 */) {
+    }
+    if (type == "ListScan" || type == "DiscreteAxis" /* for compatibility with pre-21 */)
         return newListScan(name, parse_x_list(body, type));
 
-    } else if (type == "GenericScale" || type == "Scale" /* for compatibility with pre-21 */) {
+    if (type == "GenericScale" || type == "Scale" /* for compatibility with pre-21 */)
         return newGenericScale(name, parse_x_list(body, type));
 
-    } else
-        throw std::runtime_error("Unknown axis type '" + type + "'");
+    throw std::runtime_error("Unknown axis type '" + type + "'");
 }
 
 //! Fills output data raw buffer from input stream
diff --git a/Device/IO/ReadReflectometry.cpp b/Device/IO/ReadReflectometry.cpp
index 2ccb4c4a8a45d8cefdc52f2ea9857e4814a2424c..bec650f48900bca8d0f61ff5401ea9401ac4a3e3 100644
--- a/Device/IO/ReadReflectometry.cpp
+++ b/Device/IO/ReadReflectometry.cpp
@@ -85,7 +85,7 @@ Datafield* Util::RW::readMotofit(std::istream& s)
         throw std::runtime_error("Missing header line 'Number of data points'");
 
     // Blank line
-    if (!ok || trim(line) != "")
+    if (!ok || !trim(line).empty())
         throw std::runtime_error("Missing blank line after header");
 
     // Tab header line
diff --git a/Device/Resolution/ConvolutionDetectorResolution.cpp b/Device/Resolution/ConvolutionDetectorResolution.cpp
index 261dfdae7017619dbef053dd2481f67c6ca998be..bfea137c8552b2bd22d6c2c25c6e33ef6c068ace 100644
--- a/Device/Resolution/ConvolutionDetectorResolution.cpp
+++ b/Device/Resolution/ConvolutionDetectorResolution.cpp
@@ -37,9 +37,9 @@ ConvolutionDetectorResolution::~ConvolutionDetectorResolution() = default;
 
 ConvolutionDetectorResolution::ConvolutionDetectorResolution(
     const ConvolutionDetectorResolution& other)
+    : m_rank(other.m_rank)
+    , m_res_function_1d(other.m_res_function_1d)
 {
-    m_rank = other.m_rank;
-    m_res_function_1d = other.m_res_function_1d;
     if (other.m_res_function_2d)
         setResolutionFunction(*other.m_res_function_2d);
 }
diff --git a/Param/Distrib/Distributions.cpp b/Param/Distrib/Distributions.cpp
index 984e500577d2dfc318c5bdf14bb19008dc0286c1..016a235d97c03e7c345d74ed54c510babc3a8a96 100644
--- a/Param/Distrib/Distributions.cpp
+++ b/Param/Distrib/Distributions.cpp
@@ -478,11 +478,11 @@ std::string DistributionTrapezoid::validate() const
 {
     std::vector<std::string> errs;
     if (m_left < 0.0)
-        errs.push_back("parameters violate condition leftWidth < 0");
+        errs.emplace_back("parameters violate condition leftWidth < 0");
     if (m_middle < 0.0)
-        errs.push_back("parameters violate condition middleWidth < 0");
+        errs.emplace_back("parameters violate condition middleWidth < 0");
     if (m_right < 0.0)
-        errs.push_back("parameters violate condition rightWidth < 0");
+        errs.emplace_back("parameters violate condition rightWidth < 0");
     if (!errs.empty())
         return jointError(errs);
     m_validated = true;
diff --git a/Param/Node/INode.cpp b/Param/Node/INode.cpp
index e2b8cb2699ba395abec34b33d140656d3db6cd48..da46caf2333d2970923f30cb4996340511d36496 100644
--- a/Param/Node/INode.cpp
+++ b/Param/Node/INode.cpp
@@ -68,6 +68,6 @@ std::string INode::jointError(const std::vector<std::string> errs) const
 void INode::validateOrThrow() const
 {
     const std::string err = validate();
-    if (err != "")
+    if (!err.empty())
         throw std::runtime_error(err);
 }
diff --git a/Resample/Processed/ReSample.cpp b/Resample/Processed/ReSample.cpp
index 8c686021d88f7f6b2e369bd1bd8c950d07f04db7..69700a38f29c28439b7c84791bed039a174212d7 100644
--- a/Resample/Processed/ReSample.cpp
+++ b/Resample/Processed/ReSample.cpp
@@ -353,11 +353,11 @@ ReSample ReSample::make(const MultiLayer& sample)
 //...
 
 ReSample::ReSample(const MultiLayer& sample, bool polarized,
-                   OwningVector<const ReLayout>&& relayouts, const SliceStack& refined_stack)
+                   OwningVector<const ReLayout>&& relayouts, SliceStack refined_stack)
     : m_sample(sample)
     , m_polarized(polarized)
     , m_relayouts(std::move(relayouts))
-    , m_stack(refined_stack)
+    , m_stack(std::move(refined_stack))
 {
 }
 
diff --git a/Resample/Processed/ReSample.h b/Resample/Processed/ReSample.h
index 27c286bd4d788516c11f649caba3e654545bef15..f0be50801f2d82ffca1408ed7085d73b5cfb2af6 100644
--- a/Resample/Processed/ReSample.h
+++ b/Resample/Processed/ReSample.h
@@ -61,7 +61,7 @@ public:
 
 private:
     ReSample(const MultiLayer& sample, bool polarized, OwningVector<const ReLayout>&& layouts,
-             const SliceStack& refined_stack);
+             SliceStack refined_stack);
     const MultiLayer& m_sample;
     const bool m_polarized;
     const OwningVector<const ReLayout> m_relayouts;
diff --git a/Resample/Processed/Slicer.cpp b/Resample/Processed/Slicer.cpp
index f69769edb21570b6b12f7bad23dfc833c3ea3f69..2148db6cf824427e0733ee87b3c0b95f1aa52b75 100644
--- a/Resample/Processed/Slicer.cpp
+++ b/Resample/Processed/Slicer.cpp
@@ -116,8 +116,8 @@ IFormFactor* doSlice(const IFormFactor* ff, double dz_bottom, double dz_top)
     if (const auto* f = dynamic_cast<const TruncatedSpheroid*>(ff)) {
         return new TruncatedSpheroid(f->radius(), f->untruncated_height() - dz_bottom,
                                      f->heightFlattening(), dz_top + f->removedTop());
-    } else
-        throw std::runtime_error("Slicing of " + ff->className() + " not supported");
+    }
+    throw std::runtime_error("Slicing of " + ff->className() + " not supported");
 }
 
 ReParticle* createParticleSlice(const IFormFactor* ff, ZLimits limits, const R3& position,
@@ -216,8 +216,9 @@ OwningVector<IReParticle> Compute::Slicing::particlesInSlice(const IParticle* pa
         OwningVector<IReParticle> result;
         result.emplace_back(particleSlice.release());
         return result;
+    }
 
-    } else if (const auto* p = dynamic_cast<const CoreAndShell*>(particle)) {
+    if (const auto* p = dynamic_cast<const CoreAndShell*>(particle)) {
         const Particle* core = p->coreParticle();
         const Particle* shell = p->shellParticle();
         ASSERT(core && shell);
@@ -261,11 +262,12 @@ OwningVector<IReParticle> Compute::Slicing::particlesInSlice(const IParticle* pa
         result.emplace_back(sliced_core);
         result.emplace_back(sliced_shell);
         return result;
+    }
 
-    } else if (dynamic_cast<const Compound*>(particle)) {
+    if (dynamic_cast<const Compound*>(particle))
         throw std::runtime_error("Compound does not yet support slicing");
 
-    } else if (const auto* p = dynamic_cast<const Mesocrystal*>(particle)) {
+    if (const auto* p = dynamic_cast<const Mesocrystal*>(particle)) {
         const Crystal* crystal = &p->particleStructure();
         const IFormFactor* meso_formfactor = p->outerShape();
         ASSERT(crystal && meso_formfactor);
@@ -302,7 +304,6 @@ OwningVector<IReParticle> Compute::Slicing::particlesInSlice(const IParticle* pa
         OwningVector<IReParticle> result;
         result.emplace_back(mc.release());
         return result;
-
-    } else
-        ASSERT(false);
+    }
+    ASSERT(false);
 }
diff --git a/Resample/Slice/ProfileHelper.cpp b/Resample/Slice/ProfileHelper.cpp
index 69f4cd42c3247f93f2f5530b9b3e3e872366fe60..b385e380a3b53c5d76d0959f3804061f0fd5a293 100644
--- a/Resample/Slice/ProfileHelper.cpp
+++ b/Resample/Slice/ProfileHelper.cpp
@@ -46,15 +46,13 @@ complex_t quantity(const Material& mat, std::string q)
 {
     if (q == SLD)
         return mat.refractiveIndex_or_SLD();
-    else if (q == X)
+    if (q == X)
         return mat.magnetization().x();
-    else if (q == Y)
+    if (q == Y)
         return mat.magnetization().y();
-    else if (q == Z)
+    if (q == Z)
         return mat.magnetization().z();
-    else
-        ASSERT(false);
-    return {};
+    ASSERT(false);
 }
 
 } // namespace
diff --git a/Resample/Swig/MultiLayerFuncs.cpp b/Resample/Swig/MultiLayerFuncs.cpp
index d85449155e405278d4d494214bab6363453a43ca..f996e5c05899ede3091990cc09e6a8d42e0da3ac 100644
--- a/Resample/Swig/MultiLayerFuncs.cpp
+++ b/Resample/Swig/MultiLayerFuncs.cpp
@@ -24,7 +24,7 @@ ProfileHelper helper(const MultiLayer& sample)
     SimulationOptions options;
     options.setUseAvgMaterials(true);
     const ReSample resample = ReSample::make(sample, options);
-    return ProfileHelper(resample.averageSlices());
+    return {resample.averageSlices()};
 }
 
 } // namespace
diff --git a/Sample/HardParticle/HorizontalCylinder.cpp b/Sample/HardParticle/HorizontalCylinder.cpp
index 55472fa39357dadd1a6422d45ca0d6829d543c86..0f4227661fd4d88d7d334ac9caa3918309f1f3a8 100644
--- a/Sample/HardParticle/HorizontalCylinder.cpp
+++ b/Sample/HardParticle/HorizontalCylinder.cpp
@@ -80,7 +80,7 @@ std::string HorizontalCylinder::validate() const
     if (m_slice_top > m_radius)
         errs.push_back("slice_top=" + std::to_string(m_slice_top) + "<R");
     if (m_slice_bottom >= m_slice_top)
-        errs.push_back("parameters violate condition bottom<top");
+        errs.emplace_back("parameters violate condition bottom<top");
     if (!errs.empty())
         return jointError(errs);
 
diff --git a/Sample/HardParticle/Sphere.cpp b/Sample/HardParticle/Sphere.cpp
index e453b99bcfe715d464dc7ebc46d269167ec55356..4cfccb7dc99114422dea45e65a069687e0393d74 100644
--- a/Sample/HardParticle/Sphere.cpp
+++ b/Sample/HardParticle/Sphere.cpp
@@ -18,8 +18,6 @@
 #include "Sample/HardParticle/TruncatedSphere.h"
 #include "Sample/LibFF/SomeFormFactors.h"
 #include "Sample/Scattering/Rotations.h"
-#include <numbers>
-using std::numbers::pi;
 
 Sphere::Sphere(const std::vector<double> P, bool position_at_center)
     : IFormFactor(P)
diff --git a/Sample/HardParticle/TruncatedSphere.cpp b/Sample/HardParticle/TruncatedSphere.cpp
index 81ada1780bc609503af1370f628eadad76cbf7b8..72b7e4413728a8462031e195076b21f00284cc0c 100644
--- a/Sample/HardParticle/TruncatedSphere.cpp
+++ b/Sample/HardParticle/TruncatedSphere.cpp
@@ -64,9 +64,9 @@ std::string TruncatedSphere::validate() const
     requestGt0(errs, m_untruncated_height, "untruncated_height");
     requestGe0(errs, m_dh, "dh");
     if (m_untruncated_height > 2. * m_radius)
-        errs.push_back("parameters violate condition H>2R");
+        errs.emplace_back("parameters violate condition H>2R");
     if (m_dh > m_untruncated_height)
-        errs.push_back("parameters violate condition dH<=H");
+        errs.emplace_back("parameters violate condition dH<=H");
     if (!errs.empty())
         return jointError(errs);
 
diff --git a/Sample/HardParticle/TruncatedSpheroid.cpp b/Sample/HardParticle/TruncatedSpheroid.cpp
index b75e76e6d6aac43426595334010dd3b81cb9d018..594ab349c7f1ab63912a221ec8c597148253b7fa 100644
--- a/Sample/HardParticle/TruncatedSpheroid.cpp
+++ b/Sample/HardParticle/TruncatedSpheroid.cpp
@@ -67,9 +67,9 @@ std::string TruncatedSpheroid::validate() const
     requestGt0(errs, m_fp, "height_flattening");
     requestGe0(errs, m_dh, "dh");
     if (m_untruncated_height > 2 * m_radius * m_fp)
-        errs.push_back("parameters violate condition H>2R*flattening");
+        errs.emplace_back("parameters violate condition H>2R*flattening");
     if (m_dh > m_untruncated_height)
-        errs.push_back("parameters violate condition dH<=H");
+        errs.emplace_back("parameters violate condition dH<=H");
     if (!errs.empty())
         return jointError(errs);
 
diff --git a/Sample/Lattice/BakeLattice.cpp b/Sample/Lattice/BakeLattice.cpp
index 230aea34cb5516d2bfc68d6708ef2f58159e689e..c644341c7e7babc7ec0852034dad0df422466dba 100644
--- a/Sample/Lattice/BakeLattice.cpp
+++ b/Sample/Lattice/BakeLattice.cpp
@@ -20,7 +20,7 @@ Lattice3D bake::CubicLattice(double a)
     R3 a1(a, 0.0, 0.0);
     R3 a2(0.0, a, 0.0);
     R3 a3(0.0, 0.0, a);
-    return Lattice3D(a1, a2, a3);
+    return {a1, a2, a3};
 }
 
 Lattice3D bake::FCCLattice(double a)
@@ -29,7 +29,7 @@ Lattice3D bake::FCCLattice(double a)
     R3 a1(0.0, b, b);
     R3 a2(b, 0.0, b);
     R3 a3(b, b, 0.0);
-    return Lattice3D(a1, a2, a3);
+    return {a1, a2, a3};
 }
 
 Lattice3D bake::HexagonalLattice(double a, double c)
@@ -37,7 +37,7 @@ Lattice3D bake::HexagonalLattice(double a, double c)
     R3 a1(a, 0.0, 0.0);
     R3 a2(-a / 2.0, std::sqrt(3.0) * a / 2.0, 0.0);
     R3 a3(0.0, 0.0, c);
-    return Lattice3D(a1, a2, a3);
+    return {a1, a2, a3};
 }
 
 Lattice3D bake::HCPLattice(double a, double c)
@@ -45,7 +45,7 @@ Lattice3D bake::HCPLattice(double a, double c)
     R3 a1(a, 0.0, 0.0);
     R3 a2(-a / 2.0, std::sqrt(3.0) * a / 2.0, 0);
     R3 a3(a / 2.0, a / std::sqrt(3.0) / 2.0, c / 2.0);
-    return Lattice3D(a1, a2, a3);
+    return {a1, a2, a3};
 }
 
 Lattice3D bake::TetragonalLattice(double a, double c)
@@ -53,7 +53,7 @@ Lattice3D bake::TetragonalLattice(double a, double c)
     R3 a1(a, 0.0, 0.0);
     R3 a2(0.0, a, 0.0);
     R3 a3(0.0, 0.0, c);
-    return Lattice3D(a1, a2, a3);
+    return {a1, a2, a3};
 }
 
 Lattice3D bake::BCTLattice(double a, double c)
@@ -61,5 +61,5 @@ Lattice3D bake::BCTLattice(double a, double c)
     R3 a1(a, 0.0, 0.0);
     R3 a2(0.0, a, 0.0);
     R3 a3(a / 2.0, a / 2.0, c / 2.0);
-    return Lattice3D(a1, a2, a3);
+    return {a1, a2, a3};
 }
diff --git a/Sample/Material/IMaterialImpl.cpp b/Sample/Material/IMaterialImpl.cpp
index 06bf3882589baf84b93e006ba6cf954a616e746e..bd91c353712644c6ea80545de905f49c0ad09f09 100644
--- a/Sample/Material/IMaterialImpl.cpp
+++ b/Sample/Material/IMaterialImpl.cpp
@@ -30,7 +30,7 @@ constexpr double magnetization_prefactor = (gamma_n * r_e / 2.0 / mu_B) * 1e-18;
 C3 OrthogonalToBaseVector(C3 base, const R3 vector)
 {
     if (base.mag2() == 0.0)
-        return C3();
+        return {};
     C3 projection = (base.dot(vector) / base.mag2()) * base;
     return vector.complex() - projection;
 }
@@ -38,8 +38,8 @@ C3 OrthogonalToBaseVector(C3 base, const R3 vector)
 } // namespace
 
 
-IMaterialImpl::IMaterialImpl(const std::string& name, R3 magnetization)
-    : m_name(name)
+IMaterialImpl::IMaterialImpl(std::string name, R3 magnetization)
+    : m_name(std::move(name))
     , m_magnetization(magnetization)
 {
 }
diff --git a/Sample/Material/IMaterialImpl.h b/Sample/Material/IMaterialImpl.h
index 8916fcfd1bb27cfef61d42af5872b009792bc5fc..051ca170e812cd393179792b90baf0695768d915 100644
--- a/Sample/Material/IMaterialImpl.h
+++ b/Sample/Material/IMaterialImpl.h
@@ -31,7 +31,7 @@ enum class MATERIAL_TYPES { InvalidMaterialType = -1, RefractiveMaterial = 0, Ma
 class IMaterialImpl {
 public:
     //! Constructs basic material with name and magnetization
-    IMaterialImpl(const std::string& name, R3 magnetization);
+    IMaterialImpl(std::string name, R3 magnetization);
 
     virtual ~IMaterialImpl() = default;
 
diff --git a/Sample/Material/Material.cpp b/Sample/Material/Material.cpp
index 1fcc53f6e5bdd559fd09ff9fc0a8dac8e42d5bc3..b026e6e6c73a31850b39339c5fbcafda00a1c0f9 100644
--- a/Sample/Material/Material.cpp
+++ b/Sample/Material/Material.cpp
@@ -42,7 +42,7 @@ Material& Material::operator=(const Material& other)
 Material Material::inverted() const
 {
     std::unique_ptr<IMaterialImpl> material_impl(m_material_impl->inverted());
-    return Material(std::move(material_impl));
+    return {std::move(material_impl)};
 }
 
 complex_t Material::refractiveIndex(double wavelength) const
@@ -108,7 +108,7 @@ SpinMatrix Material::polarizedSubtrSLD(const WavevectorInfo& wavevectors) const
 Material Material::rotatedMaterial(const RotMatrix& transform) const // TODO param:=rotation
 {
     std::unique_ptr<IMaterialImpl> material_impl(m_material_impl->rotatedMaterial(transform));
-    return Material(std::move(material_impl));
+    return {std::move(material_impl)};
 }
 
 std::ostream& operator<<(std::ostream& ostr, const Material& m)
diff --git a/Sample/Material/MaterialBySLDImpl.cpp b/Sample/Material/MaterialBySLDImpl.cpp
index 2da5694c93331585d87855c394bd267ebc3d0a58..c50e716d18136723212dd5775abccbf0a1bb7e84 100644
--- a/Sample/Material/MaterialBySLDImpl.cpp
+++ b/Sample/Material/MaterialBySLDImpl.cpp
@@ -61,7 +61,7 @@ complex_t MaterialBySLDImpl::refractiveIndex2(double wavelength) const
 //! Returns underlying material SLD in AA^-2
 complex_t MaterialBySLDImpl::refractiveIndex_or_SLD() const
 {
-    return complex_t(m_sld_real * square_angstroms, m_sld_imag * square_angstroms);
+    return {m_sld_real * square_angstroms, m_sld_imag * square_angstroms};
 }
 
 //! Returns (\f$ \pi/\lambda^2 \f$ - sld), sld (in \f$nm^{-2}\f$) being the scattering length
@@ -86,5 +86,5 @@ std::string MaterialBySLDImpl::print() const
 //! Returns the scattering length density in \f$ nm^{-2} \f$
 complex_t MaterialBySLDImpl::sld() const
 {
-    return complex_t(m_sld_real, -m_sld_imag);
+    return {m_sld_real, -m_sld_imag};
 }
diff --git a/Sample/Material/MaterialFactoryFuncs.cpp b/Sample/Material/MaterialFactoryFuncs.cpp
index 0e506faec87657dae4fa9cb9989e885254bd88ea..075ecd731444fe850b56a7db3fad13d0cdbe1414 100644
--- a/Sample/Material/MaterialFactoryFuncs.cpp
+++ b/Sample/Material/MaterialFactoryFuncs.cpp
@@ -28,7 +28,7 @@ Material RefractiveMaterial(const std::string& name, double delta, double beta,
 {
     std::unique_ptr<RefractiveMaterialImpl> mat_impl(
         new RefractiveMaterialImpl(name, delta, beta, magnetization));
-    return Material(std::move(mat_impl));
+    return {std::move(mat_impl)};
 }
 
 Material Vacuum()
@@ -42,7 +42,7 @@ Material MaterialBySLD(const std::string& name, double sld_real, double sld_imag
     constexpr double inv_sq_angstroms = 1.0 / (Units::angstrom * Units::angstrom);
     std::unique_ptr<MaterialBySLDImpl> mat_impl(new MaterialBySLDImpl(
         name, sld_real * inv_sq_angstroms, sld_imag * inv_sq_angstroms, magnetization));
-    return Material(std::move(mat_impl));
+    return {std::move(mat_impl)};
 }
 
 Material MaterialBySLD()
diff --git a/Sample/Material/MaterialUtil.cpp b/Sample/Material/MaterialUtil.cpp
index 3721e9ab25c8b03713487064560de7f688307e1e..59b9f11d09eed763103bc6e70946a1bfbd16a3b7 100644
--- a/Sample/Material/MaterialUtil.cpp
+++ b/Sample/Material/MaterialUtil.cpp
@@ -119,10 +119,10 @@ Material MaterialUtil::averagedMaterial(const std::string& name, const std::vect
     if (type == MATERIAL_TYPES::RefractiveMaterial) {
         avgeData = std::conj(1.0 - std::sqrt(1.0 + avgeData));
         return RefractiveMaterial(name, avgeData.real(), avgeData.imag(), avgeMagn);
-    } else if (type == MATERIAL_TYPES::MaterialBySLD) {
+    }
+    if (type == MATERIAL_TYPES::MaterialBySLD)
         return MaterialBySLD(name, avgeData.real(), avgeData.imag(), avgeMagn);
-    } else
-        ASSERT(false);
+    ASSERT(false);
 }
 
 // Tested by Tests/Unit/Sim/Sample/MaterialTest.cpp
diff --git a/Sample/Material/RefractiveMaterialImpl.cpp b/Sample/Material/RefractiveMaterialImpl.cpp
index 85436c1fb3b035232f7e7e48f51e846c762d0820..1a51ec9f052b88af503836a8282689f89844a199 100644
--- a/Sample/Material/RefractiveMaterialImpl.cpp
+++ b/Sample/Material/RefractiveMaterialImpl.cpp
@@ -35,7 +35,7 @@ RefractiveMaterialImpl* RefractiveMaterialImpl::clone() const
 
 complex_t RefractiveMaterialImpl::refractiveIndex(double) const
 {
-    return complex_t(1.0 - m_delta, m_beta);
+    return {1.0 - m_delta, m_beta};
 }
 
 complex_t RefractiveMaterialImpl::refractiveIndex2(double) const
@@ -46,7 +46,7 @@ complex_t RefractiveMaterialImpl::refractiveIndex2(double) const
 
 complex_t RefractiveMaterialImpl::refractiveIndex_or_SLD() const
 {
-    return complex_t(m_delta, m_beta);
+    return {m_delta, m_beta};
 }
 
 complex_t RefractiveMaterialImpl::scalarSubtrSLD(double lambda0) const
diff --git a/Sample/Multilayer/MultiLayer.cpp b/Sample/Multilayer/MultiLayer.cpp
index 4cd70779bd92906f4ba5f77430300be710601fe9..a08bd90a98c93a40e80145c2ead9ea94849c2f6c 100644
--- a/Sample/Multilayer/MultiLayer.cpp
+++ b/Sample/Multilayer/MultiLayer.cpp
@@ -147,7 +147,7 @@ std::string MultiLayer::validate() const
     std::vector<std::string> errs;
     if (MaterialUtil::checkMaterialTypes(containedMaterials())
         == MATERIAL_TYPES::InvalidMaterialType)
-        errs.push_back("Sample contains incompatible material definitions");
+        errs.emplace_back("Sample contains incompatible material definitions");
 
     for (size_t i = 0; i < m_layers.size(); ++i) {
         std::string err = m_layers[i]->validate();
diff --git a/Sim/Contrib/GISASSpecularContribution.cpp b/Sim/Contrib/GISASSpecularContribution.cpp
index fd42495e6024bc40f8e9d3ab45ef80d29f4db37e..fa78a1d78afcf0af5a4084e77596cedd1c004e54 100644
--- a/Sim/Contrib/GISASSpecularContribution.cpp
+++ b/Sim/Contrib/GISASSpecularContribution.cpp
@@ -44,12 +44,11 @@ double Compute::gisasSpecularContribution(const ReSample& re_sample, const Diffu
         const SpinMatrix& anaMatrix = ele.analyzer();
 
         return Compute::magneticR(R, polMatrix, anaMatrix) * geom_factor;
+    }
 
-    } else {
-        const auto* flux = dynamic_cast<const ScalarFlux*>(ele.fluxIn(0));
-        ASSERT(flux);
+    const auto* flux = dynamic_cast<const ScalarFlux*>(ele.fluxIn(0));
+    ASSERT(flux);
 
-        const complex_t R = flux->getScalarR();
-        return Compute::scalarR(R) * geom_factor;
-    }
+    const complex_t R = flux->getScalarR();
+    return Compute::scalarR(R) * geom_factor;
 }
diff --git a/Sim/Export/PyFmt2.cpp b/Sim/Export/PyFmt2.cpp
index d2bd4cfc788cb29f990c0a443e1121e637e53dd2..b8a6aef0f209b10e4d09df7aa3658c8cb7fed3c5 100644
--- a/Sim/Export/PyFmt2.cpp
+++ b/Sim/Export/PyFmt2.cpp
@@ -27,9 +27,6 @@
 #include "Param/Distrib/Distributions.h"
 #include "Param/Distrib/ParameterDistribution.h"
 #include <iomanip>
-#include <numbers>
-
-using std::numbers::pi;
 
 //! Returns fixed Python code snippet that defines the function "simulate".
 
diff --git a/Sim/Export/SampleToPython.cpp b/Sim/Export/SampleToPython.cpp
index 0f3dd72697c9da6485b1f134aa53adc217331767..af326692eea90a2419d1c1a038bf9f1d7b6067f3 100644
--- a/Sim/Export/SampleToPython.cpp
+++ b/Sim/Export/SampleToPython.cpp
@@ -557,5 +557,3 @@ std::string SampleToPython::sampleCode(const MultiLayer& sample)
 }
 
 SampleToPython::SampleToPython() = default;
-
-SampleToPython::~SampleToPython() = default;
diff --git a/Sim/Export/SampleToPython.h b/Sim/Export/SampleToPython.h
index e0c5363fe1728dfe63d9881c2a0845bba1888d68..e68c52257465698411047d8dc2a8bb1f378434ec 100644
--- a/Sim/Export/SampleToPython.h
+++ b/Sim/Export/SampleToPython.h
@@ -28,7 +28,7 @@ class MultiLayer;
 class SampleToPython {
 public:
     SampleToPython();
-    ~SampleToPython();
+    ~SampleToPython() = default;
 
     std::string sampleCode(const MultiLayer& sample);
 };
diff --git a/Sim/Fitting/SimDataPair.cpp b/Sim/Fitting/SimDataPair.cpp
index d076e32236164762fd4eea57e6b56394899ecdf5..fda76323f78ac1fe6c827273ff51209f82093d30 100644
--- a/Sim/Fitting/SimDataPair.cpp
+++ b/Sim/Fitting/SimDataPair.cpp
@@ -68,7 +68,7 @@ Datafield convertData(const ScatteringSimulation& simulation, const Datafield& d
         throw std::runtime_error(
             "FitObject::init_dataset: Detector and experimental data have different shape");
 
-    return Datafield(*roi_data);
+    return {*roi_data};
 }
 
 } // namespace
@@ -100,7 +100,7 @@ SimDataPair::SimDataPair(simulation_builder_t builder, const Datafield& raw_data
     validate();
 }
 
-SimDataPair::SimDataPair(SimDataPair&& other) = default;
+SimDataPair::SimDataPair(SimDataPair&& other) noexcept = default;
 
 SimDataPair::~SimDataPair() = default;
 
diff --git a/Sim/Fitting/SimDataPair.h b/Sim/Fitting/SimDataPair.h
index 6399c9f0d40b0a60c16dac67efcff19cda3ec91a..dcc9731d5c370da0f1ead9969fc4d0ae72ef8cca 100644
--- a/Sim/Fitting/SimDataPair.h
+++ b/Sim/Fitting/SimDataPair.h
@@ -33,7 +33,7 @@ public:
     SimDataPair(simulation_builder_t builder, const Datafield& raw_data,
                 std::unique_ptr<Datafield>&& raw_stdv, std::unique_ptr<Datafield>&& user_weights);
 
-    SimDataPair(SimDataPair&& other);
+    SimDataPair(SimDataPair&& other) noexcept;
 
     ~SimDataPair();
 
diff --git a/Sim/Scan/AlphaScan.cpp b/Sim/Scan/AlphaScan.cpp
index 293740ba0bd7d4370ec9679ae68b5fe4ffb80a7a..ec14f22f89248ee8004c1bff97e49528b6344b10 100644
--- a/Sim/Scan/AlphaScan.cpp
+++ b/Sim/Scan/AlphaScan.cpp
@@ -72,9 +72,9 @@ AlphaScan* AlphaScan::clone() const
         result->m_alpha_distrib.reset(m_alpha_distrib->clone());
 
     if (m_beamPolarization)
-        result->m_beamPolarization.reset(new R3(*m_beamPolarization));
+        result->m_beamPolarization = std::make_unique<R3>(*m_beamPolarization);
     if (m_polAnalyzer)
-        result->m_polAnalyzer.reset(new PolFilter(*m_polAnalyzer));
+        result->m_polAnalyzer = std::make_unique<PolFilter>(*m_polAnalyzer);
 
     return result;
 }
diff --git a/Sim/Scan/LambdaScan.cpp b/Sim/Scan/LambdaScan.cpp
index 145cde63ba092ff8c423ac31061b2556c3f24d78..c89de389cb4a313210ece4d78dea2cafb23a09ef 100644
--- a/Sim/Scan/LambdaScan.cpp
+++ b/Sim/Scan/LambdaScan.cpp
@@ -41,8 +41,8 @@ LambdaScan::LambdaScan(double alpha_i, Scale* lambdaScale)
             "of acceptable range.");
 }
 
-LambdaScan::LambdaScan(double alpha_i, std::vector<double> lambdaList)
-    : LambdaScan(alpha_i, newListScan("qs", std::move(lambdaList)))
+LambdaScan::LambdaScan(double alpha_i, std::vector<double> lambdaScale)
+    : LambdaScan(alpha_i, newListScan("qs", std::move(lambdaScale)))
 {
 }
 
diff --git a/Sim/Scan/QzScan.cpp b/Sim/Scan/QzScan.cpp
index 2d2d4efb78c7a4ca79ab55f252a805429d6c6ec2..adc62841ae0d8399f90544042df72c1010170e1e 100644
--- a/Sim/Scan/QzScan.cpp
+++ b/Sim/Scan/QzScan.cpp
@@ -65,9 +65,9 @@ QzScan* QzScan::clone() const
     result->setOffset(m_offset);
     // TODO merge with same code in AlphaScan
     if (m_beamPolarization)
-        result->m_beamPolarization.reset(new R3(*m_beamPolarization));
+        result->m_beamPolarization = std::make_unique<R3>(*m_beamPolarization);
     if (m_polAnalyzer)
-        result->m_polAnalyzer.reset(new PolFilter(*m_polAnalyzer));
+        result->m_polAnalyzer = std::make_unique<PolFilter>(*m_polAnalyzer);
     return result;
 }
 
diff --git a/Sim/Simulation/DepthprobeSimulation.cpp b/Sim/Simulation/DepthprobeSimulation.cpp
index 0f253678ebf580575dc4cdd5bd9dd69b6257325c..61b84d5ee00c864249b3f5f6fceeca5229872cb6 100644
--- a/Sim/Simulation/DepthprobeSimulation.cpp
+++ b/Sim/Simulation/DepthprobeSimulation.cpp
@@ -53,7 +53,7 @@ DepthprobeSimulation::~DepthprobeSimulation() = default;
 
 Frame DepthprobeSimulation::simCoordSystem() const
 {
-    return Frame(m_scan->coordinateAxis()->clone(), m_z_axis->clone());
+    return {m_scan->coordinateAxis()->clone(), m_z_axis->clone()};
 }
 
 std::vector<const INode*> DepthprobeSimulation::nodeChildren() const
diff --git a/Sim/Simulation/ISimulation.cpp b/Sim/Simulation/ISimulation.cpp
index 5b152a378fa16af6ffd6124027cc526c1aba3643..aa1088ab268afdc164e0019fd6d298c702afd1fc 100644
--- a/Sim/Simulation/ISimulation.cpp
+++ b/Sim/Simulation/ISimulation.cpp
@@ -245,7 +245,7 @@ void ISimulation::runSingleSimulation(const ReSample& re_sample, size_t batch_st
                     }
                 } catch (const std::exception& ex) {
                     mutex.lock();
-                    failure_messages.push_back(ex.what());
+                    failure_messages.emplace_back(ex.what());
                     mutex.unlock();
                 }
             }));
diff --git a/Tests/Unit/Device/Shape2DTest.cpp b/Tests/Unit/Device/Shape2DTest.cpp
index e7d3668a200e040aef1729a1caa2c7d2e45a243f..c3c1a35904bc378cdb81fac472c46dfcd3122677 100644
--- a/Tests/Unit/Device/Shape2DTest.cpp
+++ b/Tests/Unit/Device/Shape2DTest.cpp
@@ -1,7 +1,5 @@
 #include "Base/Axis/Bin.h"
 #include "Base/Const/Units.h"
-#include <numbers>
-using std::numbers::pi;
 #include "Device/Mask/Ellipse.h"
 #include "Device/Mask/Line.h"
 #include "Device/Mask/Rectangle.h"
diff --git a/Tests/Unit/Device/SphericalDetectorTest.cpp b/Tests/Unit/Device/SphericalDetectorTest.cpp
index f322d2e67048ee5e030f061213820390fcae893c..bff6dbea4986618d731ee41c1d4c17d197b6003e 100644
--- a/Tests/Unit/Device/SphericalDetectorTest.cpp
+++ b/Tests/Unit/Device/SphericalDetectorTest.cpp
@@ -16,8 +16,8 @@
 // Construction of the detector with axes.
 TEST(SphericalDetectorTest, constructionWithAxes)
 {
-    auto axis0 = newEquiDivision("axis0", 10, 0.0, 10.0);
-    auto axis1 = newEquiDivision("axis1", 20, 0.0, 20.0);
+    auto* axis0 = newEquiDivision("axis0", 10, 0.0, 10.0);
+    auto* axis1 = newEquiDivision("axis1", 20, 0.0, 20.0);
     SphericalDetector detector(Frame(axis0->clone(), axis1->clone()));
 
     // checking dimension and axes
diff --git a/Tests/Unit/Numeric/FourierTransformTest.cpp b/Tests/Unit/Numeric/FourierTransformTest.cpp
index ad63441a4d459c3496ba7a1d9b09ed41796a5b10..f09306bda8d0c4e0c5b704053824e016f3ec174a 100644
--- a/Tests/Unit/Numeric/FourierTransformTest.cpp
+++ b/Tests/Unit/Numeric/FourierTransformTest.cpp
@@ -1,6 +1,4 @@
 #include "Base/Math/FourierTransform.h"
-#include <numbers>
-using std::numbers::pi;
 #include "Device/Data/Datafield.h"
 #include "Tests/GTestWrapper/google_test.h"
 
diff --git a/Tests/Unit/Numeric/MultiQTest.cpp b/Tests/Unit/Numeric/MultiQTest.cpp
index 3f97a7e8a8914f97ca371d079be40a32146ac757..f4067562baca9ddfb878cfc17c8cfa954c8c8ff9 100644
--- a/Tests/Unit/Numeric/MultiQTest.cpp
+++ b/Tests/Unit/Numeric/MultiQTest.cpp
@@ -1,8 +1,6 @@
 #include "Tests/Unit/Numeric/MultiQTest.h"
 #include "Tests/GTestWrapper/google_test.h"
 
-using ::testing::Combine;
-using ::testing::Values;
 using ::testing::internal::ParamGenerator;
 
 namespace formfactorTest {
diff --git a/Tests/Unit/Resample/RTTest.cpp b/Tests/Unit/Resample/RTTest.cpp
index 7a9aa30e0f0f9dfe7c51bbb9bdd13556a6a65eb0..60fcee5de6ddeb911aed6163618300df8f07da88 100644
--- a/Tests/Unit/Resample/RTTest.cpp
+++ b/Tests/Unit/Resample/RTTest.cpp
@@ -1,5 +1,3 @@
-#include <numbers>
-using std::numbers::pi;
 #include "Resample/Flux/ScalarFlux.h"
 #include "Resample/Processed/ReSample.h"
 #include "Resample/Specular/ComputeFluxScalar.h"
diff --git a/Tests/Unit/Sample/CoreAndShellTest.cpp b/Tests/Unit/Sample/CoreAndShellTest.cpp
index 173844f7eba32124bf9fa4fc066228f05d0fbc39..970f50eb48d960a2aba717523080ea85a1a04208 100644
--- a/Tests/Unit/Sample/CoreAndShellTest.cpp
+++ b/Tests/Unit/Sample/CoreAndShellTest.cpp
@@ -1,7 +1,5 @@
 #include "Sample/Particle/CoreAndShell.h"
 #include "Base/Const/Units.h"
-#include <numbers>
-using std::numbers::pi;
 #include "Sample/HardParticle/HardParticles.h"
 #include "Sample/Material/MaterialFactoryFuncs.h"
 #include "Sample/Particle/Particle.h"
diff --git a/Tests/Unit/Sample/Lattice2DTest.cpp b/Tests/Unit/Sample/Lattice2DTest.cpp
index 3bb65f5355c84afa96a83eed57e14270c75480a2..2c70b46aaf76a4a76b7be04ddc229fbf96dd8f59 100644
--- a/Tests/Unit/Sample/Lattice2DTest.cpp
+++ b/Tests/Unit/Sample/Lattice2DTest.cpp
@@ -1,6 +1,4 @@
 #include "Sample/Lattice/Lattice2D.h"
-#include <numbers>
-using std::numbers::pi;
 #include "Tests/GTestWrapper/google_test.h"
 
 TEST(Lattice2DTest, basicLatticeClone)
diff --git a/Tests/Unit/Sample/MultiLayerTest.cpp b/Tests/Unit/Sample/MultiLayerTest.cpp
index fa3b7c9255f1dd85f74d4c2d286f7bf5a3cab555..3b4e85bacf787dd56a7149189e218c8b4de1759a 100644
--- a/Tests/Unit/Sample/MultiLayerTest.cpp
+++ b/Tests/Unit/Sample/MultiLayerTest.cpp
@@ -6,8 +6,6 @@
 #include "Sample/Material/MaterialFactoryFuncs.h"
 #include "Sample/Multilayer/Layer.h"
 #include "Tests/GTestWrapper/google_test.h"
-#include <numbers>
-using std::numbers::pi;
 
 class MultiLayerTest : public ::testing::Test {
 protected:
diff --git a/Tests/Unit/Sample/ParticleCompositionTest.cpp b/Tests/Unit/Sample/ParticleCompositionTest.cpp
index 66225c96187105aa7cd24f4e8ed5dd2c9f01a96c..948a653aa1df0b51e95831e7eb32e2c3650a875e 100644
--- a/Tests/Unit/Sample/ParticleCompositionTest.cpp
+++ b/Tests/Unit/Sample/ParticleCompositionTest.cpp
@@ -1,5 +1,3 @@
-#include <numbers>
-using std::numbers::pi;
 #include "Sample/HardParticle/Sphere.h"
 #include "Sample/Material/MaterialFactoryFuncs.h"
 #include "Sample/Particle/Compound.h"
diff --git a/Tests/Unit/Sim/ParticleLayoutTest.cpp b/Tests/Unit/Sim/ParticleLayoutTest.cpp
index 6a1ee06e0950a933fae0fa2a4c0730b7311bf052..4bb04eb9862ea6ee67bc549e033d1009f9a81dee 100644
--- a/Tests/Unit/Sim/ParticleLayoutTest.cpp
+++ b/Tests/Unit/Sim/ParticleLayoutTest.cpp
@@ -9,10 +9,7 @@
 #include "Sample/Scattering/Rotations.h"
 #include "Tests/GTestWrapper/google_test.h"
 
-class ParticleLayoutTest : public ::testing::Test {
-protected:
-    ~ParticleLayoutTest() override = default;
-};
+class ParticleLayoutTest : public ::testing::Test {};
 
 TEST_F(ParticleLayoutTest, ParticleLayoutInitial)
 {
diff --git a/auto/Wrap/libBornAgainBase.py b/auto/Wrap/libBornAgainBase.py
index 8d82259c11e920a7b29670ffb93b83c6a42d61d3..988a0ee86751c3c56240af925ddf89146f8cd30c 100644
--- a/auto/Wrap/libBornAgainBase.py
+++ b/auto/Wrap/libBornAgainBase.py
@@ -1855,7 +1855,7 @@ class Scale(object):
     __repr__ = _swig_repr
 
     def __init__(self, coord, bins):
-        r"""__init__(Scale self, Coordinate const & coord, std::vector< Bin1D,std::allocator< Bin1D > > const & bins) -> Scale"""
+        r"""__init__(Scale self, Coordinate const & coord, std::vector< Bin1D,std::allocator< Bin1D > > bins) -> Scale"""
         _libBornAgainBase.Scale_swiginit(self, _libBornAgainBase.new_Scale(coord, bins))
 
     def clone(self):
@@ -1933,9 +1933,9 @@ class Scale(object):
         """
         return _libBornAgainBase.Scale_clipped(self, *args)
 
-    def __eq__(self, right):
-        r"""__eq__(Scale self, Scale right) -> bool"""
-        return _libBornAgainBase.Scale___eq__(self, right)
+    def __eq__(self, other):
+        r"""__eq__(Scale self, Scale other) -> bool"""
+        return _libBornAgainBase.Scale___eq__(self, other)
 
     def unit(self):
         r"""unit(Scale self) -> std::string"""
@@ -1954,19 +1954,19 @@ class Scale(object):
 _libBornAgainBase.Scale_swigregister(Scale)
 
 def GenericScale(name, limits):
-    r"""GenericScale(std::string const & name, vdouble1d_t limits) -> Scale"""
+    r"""GenericScale(std::string name, vdouble1d_t limits) -> Scale"""
     return _libBornAgainBase.GenericScale(name, limits)
 
 def ListScan(name, points):
-    r"""ListScan(std::string const & name, vdouble1d_t points) -> Scale"""
+    r"""ListScan(std::string name, vdouble1d_t points) -> Scale"""
     return _libBornAgainBase.ListScan(name, points)
 
 def EquiDivision(name, N, start, end):
-    r"""EquiDivision(std::string const & name, size_t N, double start, double end) -> Scale"""
+    r"""EquiDivision(std::string name, size_t N, double start, double end) -> Scale"""
     return _libBornAgainBase.EquiDivision(name, N, start, end)
 
 def EquiScan(name, N, start, end):
-    r"""EquiScan(std::string const & name, size_t N, double start, double end) -> Scale"""
+    r"""EquiScan(std::string name, size_t N, double start, double end) -> Scale"""
     return _libBornAgainBase.EquiScan(name, N, start, end)
 class Frame(ICloneable):
     r"""Proxy of C++ Frame class."""
diff --git a/auto/Wrap/libBornAgainBase_wrap.cpp b/auto/Wrap/libBornAgainBase_wrap.cpp
index d2c5a188dc221f51227d0614a21574f9a60697ed..c3847bfa04c3bc9d9f4d41201294521b7c789af9 100644
--- a/auto/Wrap/libBornAgainBase_wrap.cpp
+++ b/auto/Wrap/libBornAgainBase_wrap.cpp
@@ -25785,10 +25785,10 @@ SWIGINTERN PyObject *Bin1D_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject
 SWIGINTERN PyObject *_wrap_new_Scale(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   Coordinate *arg1 = 0 ;
-  std::vector< Bin1D,std::allocator< Bin1D > > *arg2 = 0 ;
+  SwigValueWrapper< std::vector< Bin1D,std::allocator< Bin1D > > > arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  void *argp2 = 0 ;
+  void *argp2 ;
   int res2 = 0 ;
   PyObject *swig_obj[2] ;
   Scale *result = 0 ;
@@ -25802,17 +25802,22 @@ SWIGINTERN PyObject *_wrap_new_Scale(PyObject *self, PyObject *args) {
     SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_Scale" "', argument " "1"" of type '" "Coordinate const &""'"); 
   }
   arg1 = reinterpret_cast< Coordinate * >(argp1);
-  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_std__vectorT_Bin1D_std__allocatorT_Bin1D_t_t,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "new_Scale" "', argument " "2"" of type '" "std::vector< Bin1D,std::allocator< Bin1D > > const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_Scale" "', argument " "2"" of type '" "std::vector< Bin1D,std::allocator< Bin1D > > const &""'"); 
+  {
+    res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_std__vectorT_Bin1D_std__allocatorT_Bin1D_t_t,  0  | 0);
+    if (!SWIG_IsOK(res2)) {
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "new_Scale" "', argument " "2"" of type '" "std::vector< Bin1D,std::allocator< Bin1D > >""'"); 
+    }  
+    if (!argp2) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_Scale" "', argument " "2"" of type '" "std::vector< Bin1D,std::allocator< Bin1D > >""'");
+    } else {
+      std::vector< Bin1D,std::allocator< Bin1D > > * temp = reinterpret_cast< std::vector< Bin1D,std::allocator< Bin1D > > * >(argp2);
+      arg2 = *temp;
+      if (SWIG_IsNewObj(res2)) delete temp;
+    }
   }
-  arg2 = reinterpret_cast< std::vector< Bin1D,std::allocator< Bin1D > > * >(argp2);
   {
     try {
-      result = (Scale *)new Scale((Coordinate const &)*arg1,(std::vector< Bin1D,std::allocator< Bin1D > > const &)*arg2);
+      result = (Scale *)new Scale((Coordinate const &)*arg1,arg2);
     } catch (const std::exception& ex) {
       // message shown in the Python interpreter
       const std::string msg {
@@ -26760,9 +26765,8 @@ SWIGINTERN PyObject *Scale_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *ar
 
 SWIGINTERN PyObject *_wrap_GenericScale(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
-  std::string *arg1 = 0 ;
+  std::string arg1 ;
   std::vector< double,std::allocator< double > > *arg2 = 0 ;
-  int res1 = SWIG_OLDOBJ ;
   int res2 = SWIG_OLDOBJ ;
   PyObject *swig_obj[2] ;
   SwigValueWrapper< Scale > result;
@@ -26770,14 +26774,12 @@ SWIGINTERN PyObject *_wrap_GenericScale(PyObject *self, PyObject *args) {
   if (!SWIG_Python_UnpackTuple(args, "GenericScale", 2, 2, swig_obj)) SWIG_fail;
   {
     std::string *ptr = (std::string *)0;
-    res1 = SWIG_AsPtr_std_string(swig_obj[0], &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GenericScale" "', argument " "1"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "GenericScale" "', argument " "1"" of type '" "std::string const &""'"); 
+    int res = SWIG_AsPtr_std_string(swig_obj[0], &ptr);
+    if (!SWIG_IsOK(res) || !ptr) {
+      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "GenericScale" "', argument " "1"" of type '" "std::string""'"); 
     }
-    arg1 = ptr;
+    arg1 = *ptr;
+    if (SWIG_IsNewObj(res)) delete ptr;
   }
   {
     std::vector< double,std::allocator< double > > *ptr = (std::vector< double,std::allocator< double > > *)0;
@@ -26792,7 +26794,7 @@ SWIGINTERN PyObject *_wrap_GenericScale(PyObject *self, PyObject *args) {
   }
   {
     try {
-      result = GenericScale((std::string const &)*arg1,(std::vector< double,std::allocator< double > > const &)*arg2);
+      result = GenericScale(SWIG_STD_MOVE(arg1),(std::vector< double,std::allocator< double > > const &)*arg2);
     } catch (const std::exception& ex) {
       // message shown in the Python interpreter
       const std::string msg {
@@ -26802,11 +26804,9 @@ SWIGINTERN PyObject *_wrap_GenericScale(PyObject *self, PyObject *args) {
     }
   }
   resultobj = SWIG_NewPointerObj((new Scale(result)), SWIGTYPE_p_Scale, SWIG_POINTER_OWN |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
   if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
   if (SWIG_IsNewObj(res2)) delete arg2;
   return NULL;
 }
@@ -26814,9 +26814,8 @@ fail:
 
 SWIGINTERN PyObject *_wrap_ListScan(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
-  std::string *arg1 = 0 ;
+  std::string arg1 ;
   std::vector< double,std::allocator< double > > *arg2 = 0 ;
-  int res1 = SWIG_OLDOBJ ;
   int res2 = SWIG_OLDOBJ ;
   PyObject *swig_obj[2] ;
   SwigValueWrapper< Scale > result;
@@ -26824,14 +26823,12 @@ SWIGINTERN PyObject *_wrap_ListScan(PyObject *self, PyObject *args) {
   if (!SWIG_Python_UnpackTuple(args, "ListScan", 2, 2, swig_obj)) SWIG_fail;
   {
     std::string *ptr = (std::string *)0;
-    res1 = SWIG_AsPtr_std_string(swig_obj[0], &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ListScan" "', argument " "1"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "ListScan" "', argument " "1"" of type '" "std::string const &""'"); 
+    int res = SWIG_AsPtr_std_string(swig_obj[0], &ptr);
+    if (!SWIG_IsOK(res) || !ptr) {
+      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "ListScan" "', argument " "1"" of type '" "std::string""'"); 
     }
-    arg1 = ptr;
+    arg1 = *ptr;
+    if (SWIG_IsNewObj(res)) delete ptr;
   }
   {
     std::vector< double,std::allocator< double > > *ptr = (std::vector< double,std::allocator< double > > *)0;
@@ -26846,7 +26843,7 @@ SWIGINTERN PyObject *_wrap_ListScan(PyObject *self, PyObject *args) {
   }
   {
     try {
-      result = ListScan((std::string const &)*arg1,(std::vector< double,std::allocator< double > > const &)*arg2);
+      result = ListScan(SWIG_STD_MOVE(arg1),(std::vector< double,std::allocator< double > > const &)*arg2);
     } catch (const std::exception& ex) {
       // message shown in the Python interpreter
       const std::string msg {
@@ -26856,11 +26853,9 @@ SWIGINTERN PyObject *_wrap_ListScan(PyObject *self, PyObject *args) {
     }
   }
   resultobj = SWIG_NewPointerObj((new Scale(result)), SWIGTYPE_p_Scale, SWIG_POINTER_OWN |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
   if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
   if (SWIG_IsNewObj(res2)) delete arg2;
   return NULL;
 }
@@ -26868,11 +26863,10 @@ fail:
 
 SWIGINTERN PyObject *_wrap_EquiDivision(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
-  std::string *arg1 = 0 ;
+  std::string arg1 ;
   size_t arg2 ;
   double arg3 ;
   double arg4 ;
-  int res1 = SWIG_OLDOBJ ;
   size_t val2 ;
   int ecode2 = 0 ;
   double val3 ;
@@ -26885,14 +26879,12 @@ SWIGINTERN PyObject *_wrap_EquiDivision(PyObject *self, PyObject *args) {
   if (!SWIG_Python_UnpackTuple(args, "EquiDivision", 4, 4, swig_obj)) SWIG_fail;
   {
     std::string *ptr = (std::string *)0;
-    res1 = SWIG_AsPtr_std_string(swig_obj[0], &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "EquiDivision" "', argument " "1"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "EquiDivision" "', argument " "1"" of type '" "std::string const &""'"); 
+    int res = SWIG_AsPtr_std_string(swig_obj[0], &ptr);
+    if (!SWIG_IsOK(res) || !ptr) {
+      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "EquiDivision" "', argument " "1"" of type '" "std::string""'"); 
     }
-    arg1 = ptr;
+    arg1 = *ptr;
+    if (SWIG_IsNewObj(res)) delete ptr;
   }
   ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2);
   if (!SWIG_IsOK(ecode2)) {
@@ -26911,7 +26903,7 @@ SWIGINTERN PyObject *_wrap_EquiDivision(PyObject *self, PyObject *args) {
   arg4 = static_cast< double >(val4);
   {
     try {
-      result = EquiDivision((std::string const &)*arg1,SWIG_STD_MOVE(arg2),arg3,arg4);
+      result = EquiDivision(SWIG_STD_MOVE(arg1),SWIG_STD_MOVE(arg2),arg3,arg4);
     } catch (const std::exception& ex) {
       // message shown in the Python interpreter
       const std::string msg {
@@ -26921,21 +26913,18 @@ SWIGINTERN PyObject *_wrap_EquiDivision(PyObject *self, PyObject *args) {
     }
   }
   resultobj = SWIG_NewPointerObj((new Scale(result)), SWIGTYPE_p_Scale, SWIG_POINTER_OWN |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
   return NULL;
 }
 
 
 SWIGINTERN PyObject *_wrap_EquiScan(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
-  std::string *arg1 = 0 ;
+  std::string arg1 ;
   size_t arg2 ;
   double arg3 ;
   double arg4 ;
-  int res1 = SWIG_OLDOBJ ;
   size_t val2 ;
   int ecode2 = 0 ;
   double val3 ;
@@ -26948,14 +26937,12 @@ SWIGINTERN PyObject *_wrap_EquiScan(PyObject *self, PyObject *args) {
   if (!SWIG_Python_UnpackTuple(args, "EquiScan", 4, 4, swig_obj)) SWIG_fail;
   {
     std::string *ptr = (std::string *)0;
-    res1 = SWIG_AsPtr_std_string(swig_obj[0], &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "EquiScan" "', argument " "1"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "EquiScan" "', argument " "1"" of type '" "std::string const &""'"); 
+    int res = SWIG_AsPtr_std_string(swig_obj[0], &ptr);
+    if (!SWIG_IsOK(res) || !ptr) {
+      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "EquiScan" "', argument " "1"" of type '" "std::string""'"); 
     }
-    arg1 = ptr;
+    arg1 = *ptr;
+    if (SWIG_IsNewObj(res)) delete ptr;
   }
   ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2);
   if (!SWIG_IsOK(ecode2)) {
@@ -26974,7 +26961,7 @@ SWIGINTERN PyObject *_wrap_EquiScan(PyObject *self, PyObject *args) {
   arg4 = static_cast< double >(val4);
   {
     try {
-      result = EquiScan((std::string const &)*arg1,SWIG_STD_MOVE(arg2),arg3,arg4);
+      result = EquiScan(SWIG_STD_MOVE(arg1),SWIG_STD_MOVE(arg2),arg3,arg4);
     } catch (const std::exception& ex) {
       // message shown in the Python interpreter
       const std::string msg {
@@ -26984,10 +26971,8 @@ SWIGINTERN PyObject *_wrap_EquiScan(PyObject *self, PyObject *args) {
     }
   }
   resultobj = SWIG_NewPointerObj((new Scale(result)), SWIGTYPE_p_Scale, SWIG_POINTER_OWN |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
   return NULL;
 }
 
@@ -30335,7 +30320,7 @@ static PyMethodDef SwigMethods[] = {
 	 { "Bin1D_clipped_or_nil", _wrap_Bin1D_clipped_or_nil, METH_VARARGS, "Bin1D_clipped_or_nil(Bin1D self, double lower, double upper) -> std::optional< Bin1D >"},
 	 { "delete_Bin1D", _wrap_delete_Bin1D, METH_O, "delete_Bin1D(Bin1D self)"},
 	 { "Bin1D_swigregister", Bin1D_swigregister, METH_O, NULL},
-	 { "new_Scale", _wrap_new_Scale, METH_VARARGS, "new_Scale(Coordinate const & coord, std::vector< Bin1D,std::allocator< Bin1D > > const & bins) -> Scale"},
+	 { "new_Scale", _wrap_new_Scale, METH_VARARGS, "new_Scale(Coordinate const & coord, std::vector< Bin1D,std::allocator< Bin1D > > bins) -> Scale"},
 	 { "Scale_clone", _wrap_Scale_clone, METH_O, "Scale_clone(Scale self) -> Scale"},
 	 { "Scale_axisLabel", _wrap_Scale_axisLabel, METH_O, "Scale_axisLabel(Scale self) -> std::string"},
 	 { "Scale_size", _wrap_Scale_size, METH_O, "Scale_size(Scale self) -> size_t"},
@@ -30357,17 +30342,17 @@ static PyMethodDef SwigMethods[] = {
 		"Scale_clipped(Scale self, double lower, double upper) -> Scale\n"
 		"Scale_clipped(Scale self, pvacuum_double_t bounds) -> Scale\n"
 		""},
-	 { "Scale___eq__", _wrap_Scale___eq__, METH_VARARGS, "Scale___eq__(Scale self, Scale right) -> bool"},
+	 { "Scale___eq__", _wrap_Scale___eq__, METH_VARARGS, "Scale___eq__(Scale self, Scale other) -> bool"},
 	 { "Scale_unit", _wrap_Scale_unit, METH_O, "Scale_unit(Scale self) -> std::string"},
 	 { "Scale_plottableScale", _wrap_Scale_plottableScale, METH_O, "Scale_plottableScale(Scale self) -> Scale"},
 	 { "Scale_rescaledScale", _wrap_Scale_rescaledScale, METH_VARARGS, "Scale_rescaledScale(Scale self, std::string const & unit) -> Scale"},
 	 { "delete_Scale", _wrap_delete_Scale, METH_O, "delete_Scale(Scale self)"},
 	 { "Scale_swigregister", Scale_swigregister, METH_O, NULL},
 	 { "Scale_swiginit", Scale_swiginit, METH_VARARGS, NULL},
-	 { "GenericScale", _wrap_GenericScale, METH_VARARGS, "GenericScale(std::string const & name, vdouble1d_t limits) -> Scale"},
-	 { "ListScan", _wrap_ListScan, METH_VARARGS, "ListScan(std::string const & name, vdouble1d_t points) -> Scale"},
-	 { "EquiDivision", _wrap_EquiDivision, METH_VARARGS, "EquiDivision(std::string const & name, size_t N, double start, double end) -> Scale"},
-	 { "EquiScan", _wrap_EquiScan, METH_VARARGS, "EquiScan(std::string const & name, size_t N, double start, double end) -> Scale"},
+	 { "GenericScale", _wrap_GenericScale, METH_VARARGS, "GenericScale(std::string name, vdouble1d_t limits) -> Scale"},
+	 { "ListScan", _wrap_ListScan, METH_VARARGS, "ListScan(std::string name, vdouble1d_t points) -> Scale"},
+	 { "EquiDivision", _wrap_EquiDivision, METH_VARARGS, "EquiDivision(std::string name, size_t N, double start, double end) -> Scale"},
+	 { "EquiScan", _wrap_EquiScan, METH_VARARGS, "EquiScan(std::string name, size_t N, double start, double end) -> Scale"},
 	 { "new_Frame", _wrap_new_Frame, METH_VARARGS, "\n"
 		"Frame(std::vector< Scale const *,std::allocator< Scale const * > > && axes)\n"
 		"Frame(Scale const *&& ax0)\n"
diff --git a/auto/Wrap/libBornAgainDevice.py b/auto/Wrap/libBornAgainDevice.py
index f297cc4aebc759b4ab56ca4552d8c74d03db5a71..c7171461e374348fb51efd0a1888be4ea992039a 100644
--- a/auto/Wrap/libBornAgainDevice.py
+++ b/auto/Wrap/libBornAgainDevice.py
@@ -2064,7 +2064,7 @@ class Datafield(object):
 
     def __init__(self, *args):
         r"""
-        __init__(Datafield self, std::string const & title, Frame frame, vdouble1d_t values={}, vdouble1d_t errSigmas={}) -> Datafield
+        __init__(Datafield self, std::string title, Frame frame, vdouble1d_t values={}, vdouble1d_t errSigmas={}) -> Datafield
         __init__(Datafield self, Frame frame, vdouble1d_t values={}, vdouble1d_t errSigmas={}) -> Datafield
         __init__(Datafield self, std::vector< Scale const *,std::allocator< Scale const * > > && axes, vdouble1d_t values={}, vdouble1d_t errSigmas={}) -> Datafield
         __init__(Datafield self, Datafield arg2) -> Datafield
diff --git a/auto/Wrap/libBornAgainDevice_wrap.cpp b/auto/Wrap/libBornAgainDevice_wrap.cpp
index a2b4dc3efc377bd500f57cd4d5a9f7e0714997f8..088a26b55fb3c3620667a9e3a105458420dd9e1f 100644
--- a/auto/Wrap/libBornAgainDevice_wrap.cpp
+++ b/auto/Wrap/libBornAgainDevice_wrap.cpp
@@ -28894,11 +28894,10 @@ fail:
 
 SWIGINTERN PyObject *_wrap_new_Datafield__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) {
   PyObject *resultobj = 0;
-  std::string *arg1 = 0 ;
+  std::string arg1 ;
   Frame *arg2 = (Frame *) 0 ;
   std::vector< double,std::allocator< double > > *arg3 = 0 ;
   std::vector< double,std::allocator< double > > *arg4 = 0 ;
-  int res1 = SWIG_OLDOBJ ;
   void *argp2 = 0 ;
   int res2 = 0 ;
   int res3 = SWIG_OLDOBJ ;
@@ -28908,14 +28907,12 @@ SWIGINTERN PyObject *_wrap_new_Datafield__SWIG_0(PyObject *self, Py_ssize_t nobj
   if ((nobjs < 4) || (nobjs > 4)) SWIG_fail;
   {
     std::string *ptr = (std::string *)0;
-    res1 = SWIG_AsPtr_std_string(swig_obj[0], &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_Datafield" "', argument " "1"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_Datafield" "', argument " "1"" of type '" "std::string const &""'"); 
+    int res = SWIG_AsPtr_std_string(swig_obj[0], &ptr);
+    if (!SWIG_IsOK(res) || !ptr) {
+      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "new_Datafield" "', argument " "1"" of type '" "std::string""'"); 
     }
-    arg1 = ptr;
+    arg1 = *ptr;
+    if (SWIG_IsNewObj(res)) delete ptr;
   }
   res2 = SWIG_ConvertPtr(swig_obj[1], &argp2,SWIGTYPE_p_Frame, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
@@ -28946,7 +28943,7 @@ SWIGINTERN PyObject *_wrap_new_Datafield__SWIG_0(PyObject *self, Py_ssize_t nobj
   }
   {
     try {
-      result = (Datafield *)new Datafield((std::string const &)*arg1,(Frame const *)arg2,(std::vector< double,std::allocator< double > > const &)*arg3,(std::vector< double,std::allocator< double > > const &)*arg4);
+      result = (Datafield *)new Datafield(arg1,(Frame const *)arg2,(std::vector< double,std::allocator< double > > const &)*arg3,(std::vector< double,std::allocator< double > > const &)*arg4);
     } catch (const std::exception& ex) {
       // message shown in the Python interpreter
       const std::string msg {
@@ -28956,12 +28953,10 @@ SWIGINTERN PyObject *_wrap_new_Datafield__SWIG_0(PyObject *self, Py_ssize_t nobj
     }
   }
   resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Datafield, SWIG_POINTER_NEW |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
   if (SWIG_IsNewObj(res3)) delete arg3;
   if (SWIG_IsNewObj(res4)) delete arg4;
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
   if (SWIG_IsNewObj(res3)) delete arg3;
   if (SWIG_IsNewObj(res4)) delete arg4;
   return NULL;
@@ -28970,10 +28965,9 @@ fail:
 
 SWIGINTERN PyObject *_wrap_new_Datafield__SWIG_1(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) {
   PyObject *resultobj = 0;
-  std::string *arg1 = 0 ;
+  std::string arg1 ;
   Frame *arg2 = (Frame *) 0 ;
   std::vector< double,std::allocator< double > > *arg3 = 0 ;
-  int res1 = SWIG_OLDOBJ ;
   void *argp2 = 0 ;
   int res2 = 0 ;
   int res3 = SWIG_OLDOBJ ;
@@ -28982,14 +28976,12 @@ SWIGINTERN PyObject *_wrap_new_Datafield__SWIG_1(PyObject *self, Py_ssize_t nobj
   if ((nobjs < 3) || (nobjs > 3)) SWIG_fail;
   {
     std::string *ptr = (std::string *)0;
-    res1 = SWIG_AsPtr_std_string(swig_obj[0], &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_Datafield" "', argument " "1"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_Datafield" "', argument " "1"" of type '" "std::string const &""'"); 
+    int res = SWIG_AsPtr_std_string(swig_obj[0], &ptr);
+    if (!SWIG_IsOK(res) || !ptr) {
+      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "new_Datafield" "', argument " "1"" of type '" "std::string""'"); 
     }
-    arg1 = ptr;
+    arg1 = *ptr;
+    if (SWIG_IsNewObj(res)) delete ptr;
   }
   res2 = SWIG_ConvertPtr(swig_obj[1], &argp2,SWIGTYPE_p_Frame, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
@@ -29009,7 +29001,7 @@ SWIGINTERN PyObject *_wrap_new_Datafield__SWIG_1(PyObject *self, Py_ssize_t nobj
   }
   {
     try {
-      result = (Datafield *)new Datafield((std::string const &)*arg1,(Frame const *)arg2,(std::vector< double,std::allocator< double > > const &)*arg3);
+      result = (Datafield *)new Datafield(arg1,(Frame const *)arg2,(std::vector< double,std::allocator< double > > const &)*arg3);
     } catch (const std::exception& ex) {
       // message shown in the Python interpreter
       const std::string msg {
@@ -29019,11 +29011,9 @@ SWIGINTERN PyObject *_wrap_new_Datafield__SWIG_1(PyObject *self, Py_ssize_t nobj
     }
   }
   resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Datafield, SWIG_POINTER_NEW |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
   if (SWIG_IsNewObj(res3)) delete arg3;
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
   if (SWIG_IsNewObj(res3)) delete arg3;
   return NULL;
 }
@@ -29031,9 +29021,8 @@ fail:
 
 SWIGINTERN PyObject *_wrap_new_Datafield__SWIG_2(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) {
   PyObject *resultobj = 0;
-  std::string *arg1 = 0 ;
+  std::string arg1 ;
   Frame *arg2 = (Frame *) 0 ;
-  int res1 = SWIG_OLDOBJ ;
   void *argp2 = 0 ;
   int res2 = 0 ;
   Datafield *result = 0 ;
@@ -29041,14 +29030,12 @@ SWIGINTERN PyObject *_wrap_new_Datafield__SWIG_2(PyObject *self, Py_ssize_t nobj
   if ((nobjs < 2) || (nobjs > 2)) SWIG_fail;
   {
     std::string *ptr = (std::string *)0;
-    res1 = SWIG_AsPtr_std_string(swig_obj[0], &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_Datafield" "', argument " "1"" of type '" "std::string const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_Datafield" "', argument " "1"" of type '" "std::string const &""'"); 
+    int res = SWIG_AsPtr_std_string(swig_obj[0], &ptr);
+    if (!SWIG_IsOK(res) || !ptr) {
+      SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "new_Datafield" "', argument " "1"" of type '" "std::string""'"); 
     }
-    arg1 = ptr;
+    arg1 = *ptr;
+    if (SWIG_IsNewObj(res)) delete ptr;
   }
   res2 = SWIG_ConvertPtr(swig_obj[1], &argp2,SWIGTYPE_p_Frame, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
@@ -29057,7 +29044,7 @@ SWIGINTERN PyObject *_wrap_new_Datafield__SWIG_2(PyObject *self, Py_ssize_t nobj
   arg2 = reinterpret_cast< Frame * >(argp2);
   {
     try {
-      result = (Datafield *)new Datafield((std::string const &)*arg1,(Frame const *)arg2);
+      result = (Datafield *)new Datafield(arg1,(Frame const *)arg2);
     } catch (const std::exception& ex) {
       // message shown in the Python interpreter
       const std::string msg {
@@ -29067,10 +29054,8 @@ SWIGINTERN PyObject *_wrap_new_Datafield__SWIG_2(PyObject *self, Py_ssize_t nobj
     }
   }
   resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Datafield, SWIG_POINTER_NEW |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
   return NULL;
 }
 
@@ -29610,9 +29595,9 @@ SWIGINTERN PyObject *_wrap_new_Datafield(PyObject *self, PyObject *args) {
 fail:
   SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'new_Datafield'.\n"
     "  Possible C/C++ prototypes are:\n"
-    "    Datafield::Datafield(std::string const &,Frame const *,std::vector< double,std::allocator< double > > const &,std::vector< double,std::allocator< double > > const &)\n"
-    "    Datafield::Datafield(std::string const &,Frame const *,std::vector< double,std::allocator< double > > const &)\n"
-    "    Datafield::Datafield(std::string const &,Frame const *)\n"
+    "    Datafield::Datafield(std::string,Frame const *,std::vector< double,std::allocator< double > > const &,std::vector< double,std::allocator< double > > const &)\n"
+    "    Datafield::Datafield(std::string,Frame const *,std::vector< double,std::allocator< double > > const &)\n"
+    "    Datafield::Datafield(std::string,Frame const *)\n"
     "    Datafield::Datafield(Frame const *,std::vector< double,std::allocator< double > > const &,std::vector< double,std::allocator< double > > const &)\n"
     "    Datafield::Datafield(Frame const *,std::vector< double,std::allocator< double > > const &)\n"
     "    Datafield::Datafield(Frame const *)\n"
@@ -40988,7 +40973,7 @@ static PyMethodDef SwigMethods[] = {
 		""},
 	 { "FindPeaks", _wrap_FindPeaks, METH_VARARGS, "FindPeaks(Datafield data, double sigma=2, std::string const & option={}, double threshold=0.05) -> vector_pvacuum_double_t"},
 	 { "new_Datafield", _wrap_new_Datafield, METH_VARARGS, "\n"
-		"Datafield(std::string const & title, Frame frame, vdouble1d_t values={}, vdouble1d_t errSigmas={})\n"
+		"Datafield(std::string title, Frame frame, vdouble1d_t values={}, vdouble1d_t errSigmas={})\n"
 		"Datafield(Frame frame, vdouble1d_t values={}, vdouble1d_t errSigmas={})\n"
 		"Datafield(std::vector< Scale const *,std::allocator< Scale const * > > && axes, vdouble1d_t values={}, vdouble1d_t errSigmas={})\n"
 		"Datafield(Datafield arg1)\n"