diff --git a/Base/Vector/RotMatrix.cpp b/Base/Vector/RotMatrix.cpp
deleted file mode 100644
index a4bda31cfbcda4399f4dab5075b532f9aaca841b..0000000000000000000000000000000000000000
--- a/Base/Vector/RotMatrix.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-//  ************************************************************************************************
-//
-//  BornAgain: simulate and fit reflection and scattering
-//
-//! @file      Base/Vector/RotMatrix.cpp
-//! @brief     Implements class RotMatrix.
-//!
-//! @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/Vector/RotMatrix.h"
-
-RotMatrix::RotMatrix(double x_, double y_, double z_, double s_)
-    : x(x_)
-    , y(y_)
-    , z(z_)
-    , s(s_)
-{
-}
-
-RotMatrix::RotMatrix()
-    : RotMatrix(0, 0, 0, 1)
-{
-}
-
-RotMatrix RotMatrix::AroundX(double phi)
-{
-    return {sin(phi / 2), 0, 0, cos(phi / 2)};
-}
-
-RotMatrix RotMatrix::AroundY(double phi)
-{
-    return {0, sin(phi / 2), 0, cos(phi / 2)};
-}
-
-RotMatrix RotMatrix::AroundZ(double phi)
-{
-    return {0, 0, sin(phi / 2), cos(phi / 2)};
-}
-
-RotMatrix RotMatrix::EulerZXZ(double alpha, double beta, double gamma)
-{
-    RotMatrix zrot = AroundZ(alpha);
-    RotMatrix xrot = AroundX(beta);
-    RotMatrix zrot2 = AroundZ(gamma);
-    return zrot * xrot * zrot2;
-}
-
-std::array<double, 3> RotMatrix::zxzEulerAngles() const
-{
-    double m00 = (-1 + 2 * x * x + 2 * s * s);
-    double m02 = 2 * (x * z + y * s);
-    double m10 = 2 * (y * x + z * s);
-    double m12 = 2 * (y * z - x * s);
-    double m20 = 2 * (z * x - y * s);
-    double m21 = 2 * (z * y + x * s);
-    double m22 = (-1 + 2 * z * z + 2 * s * s);
-
-    const double beta = std::acos(m22);
-
-    if (std::abs(m22) == 1.0) // second z angle is zero or pi
-        return {std::atan2(m10, m00), beta, 0.};
-    return {std::atan2(m02, -m12), beta, std::atan2(m20, m21)};
-}
-
-RotMatrix RotMatrix::Inverse() const
-{
-    return {-x, -y, -z, s};
-}
-
-template <class U>
-U RotMatrix::transformed(const U& v) const
-{
-    auto xf = (-1 + 2 * x * x + 2 * s * s) * v.x() + 2 * (x * y - z * s) * v.y()
-              + 2 * (x * z + y * s) * v.z();
-    auto yf = (-1 + 2 * y * y + 2 * s * s) * v.y() + 2 * (y * z - x * s) * v.z()
-              + 2 * (y * x + z * s) * v.x();
-    auto zf = (-1 + 2 * z * z + 2 * s * s) * v.z() + 2 * (z * x - y * s) * v.x()
-              + 2 * (z * y + x * s) * v.y();
-
-    return U(xf, yf, zf);
-}
-
-template R3 RotMatrix::transformed<R3>(const R3& v) const;
-template C3 RotMatrix::transformed<C3>(const C3& v) const;
-
-RotMatrix RotMatrix::operator*(const RotMatrix& o) const
-{
-    return {s * o.x + x * o.s + y * o.z - z * o.y, s * o.y + y * o.s + z * o.x - x * o.z,
-            s * o.z + z * o.s + x * o.y - y * o.x, s * o.s - x * o.x - y * o.y - z * o.z};
-}
-
-bool RotMatrix::operator==(const RotMatrix& o) const
-{
-    return x == o.x && y == o.y && z == o.z && s == o.s;
-}
-
-bool RotMatrix::isIdentity() const
-{
-    return x == 0 && y == 0 && z == 0;
-}
-
-bool RotMatrix::isXRotation() const
-{
-    return y == 0 && z == 0;
-}
-
-bool RotMatrix::isYRotation() const
-{
-    return z == 0 && x == 0;
-}
-
-bool RotMatrix::isZRotation() const
-{
-    return x == 0 && y == 0;
-}
-
-std::optional<double> RotMatrix::angleAroundCoordAxis(int iAxis) const
-{
-    if (iAxis == 0 && isXRotation())
-        return 2 * atan2(x, s);
-    if (iAxis == 1 && isYRotation())
-        return 2 * atan2(y, s);
-    if (iAxis == 2 && isZRotation())
-        return 2 * atan2(z, s);
-    return {};
-}
diff --git a/Base/Vector/RotMatrix.h b/Base/Vector/RotMatrix.h
index 324e9110142cfbb3208d51a280d8a52c46cc8ba1..a38c9b654112e013e60801f7320f93507f2e86a0 100644
--- a/Base/Vector/RotMatrix.h
+++ b/Base/Vector/RotMatrix.h
@@ -15,62 +15,8 @@
 #ifndef BORNAGAIN_BASE_VECTOR_ROTMATRIX_H
 #define BORNAGAIN_BASE_VECTOR_ROTMATRIX_H
 
-#include <array>
-#include <heinz/Vectors3D.h>
-#include <optional>
+#include <heinz/Rotations3D.h>
 
-//! Rotation matrix in three dimensions. Represents group SO(3).
-//! Internal parameterization based on quaternions.
-
-class RotMatrix {
-public:
-    //! Constructs unit transformation
-    RotMatrix();
-
-    //! Destructor
-    ~RotMatrix() = default;
-
-    //! Creates rotation around x-axis
-    static RotMatrix AroundX(double phi);
-
-    //! Creates rotation around y-axis
-    static RotMatrix AroundY(double phi);
-
-    //! Creates rotation around z-axis
-    static RotMatrix AroundZ(double phi);
-
-    //! Creates rotation defined by Euler angles
-    static RotMatrix EulerZXZ(double alpha, double beta, double gamma);
-
-    //! Calculates the Euler angles corresponding to the rotation
-    std::array<double, 3> zxzEulerAngles() const;
-
-    //! Returns the inverse transformation.
-    RotMatrix Inverse() const;
-
-    //! Return transformed vector _v_.
-    template <class U>
-    U transformed(const U& v) const;
-
-    //! Composes two transformations
-    RotMatrix operator*(const RotMatrix&) const;
-
-    //! Provides equality operator
-    bool operator==(const RotMatrix&) const;
-
-    //! Determine if the transformation is trivial (identity)
-    bool isIdentity() const;
-
-    bool isXRotation() const;
-    bool isYRotation() const;
-    bool isZRotation() const;
-
-    std::optional<double> angleAroundCoordAxis(int iAxis) const;
-
-private:
-    RotMatrix(double x_, double y_, double z_, double s_);
-
-    double x, y, z, s;
-};
+using RotMatrix = Rotation3D<double>;
 
 #endif // BORNAGAIN_BASE_VECTOR_ROTMATRIX_H
diff --git a/Base/Vector/WavevectorInfo.cpp b/Base/Vector/WavevectorInfo.cpp
index 3265282d1b43cf83b646732dbb882f488cb8b9ba..289e46f2925a863e2458f4bf35f7058c0e4b3e3e 100644
--- a/Base/Vector/WavevectorInfo.cpp
+++ b/Base/Vector/WavevectorInfo.cpp
@@ -13,7 +13,6 @@
 //  ************************************************************************************************
 
 #include "Base/Vector/WavevectorInfo.h"
-#include "Base/Vector/RotMatrix.h"
 
 WavevectorInfo::WavevectorInfo(C3 ki, C3 kf, double wavelength)
     : m_ki(ki)
diff --git a/Base/Vector/WavevectorInfo.h b/Base/Vector/WavevectorInfo.h
index 279c1b5cf0a856715aad552c6631bce528b526f4..e774a3f49d0a17541126fec3f96ac91571f0565b 100644
--- a/Base/Vector/WavevectorInfo.h
+++ b/Base/Vector/WavevectorInfo.h
@@ -21,8 +21,7 @@
 #define BORNAGAIN_BASE_VECTOR_WAVEVECTORINFO_H
 
 #include <heinz/Vectors3D.h>
-
-class RotMatrix;
+#include "Base/Vector/RotMatrix.h"
 
 //! Holds all wavevector information relevant for calculating form factors.
 
diff --git a/GUI/Model/Sample/RotationItems.h b/GUI/Model/Sample/RotationItems.h
index 04858c15a59f8f3dfccf52417dd87bc1beef3ea8..dbe25c93b58a8c1e46eaaa1b2687c4666bd94f52 100644
--- a/GUI/Model/Sample/RotationItems.h
+++ b/GUI/Model/Sample/RotationItems.h
@@ -16,10 +16,9 @@
 #define BORNAGAIN_GUI_MODEL_SAMPLE_ROTATIONITEMS_H
 
 #include "GUI/Model/Descriptor/DoubleProperty.h"
+#include "Sample/Scattering/Rotations.h"
 #include <memory>
 
-class IRotation;
-class RotMatrix;
 class Streamer;
 
 using std::unique_ptr;
diff --git a/Resample/Particle/ReParticle.cpp b/Resample/Particle/ReParticle.cpp
index 7dac2129f1256642c7ad5d4bde2bda9498d4e6ee..3b779bbef7b246967fa29c6735f4d7f042030bb9 100644
--- a/Resample/Particle/ReParticle.cpp
+++ b/Resample/Particle/ReParticle.cpp
@@ -13,7 +13,6 @@
 //  ************************************************************************************************
 
 #include "Resample/Particle/ReParticle.h"
-#include "Base/Vector/RotMatrix.h"
 #include "Base/Vector/WavevectorInfo.h" // debug
 #include "Sample/Material/Material.h"
 #include "Sample/Material/MaterialFactoryFuncs.h"
diff --git a/Resample/Particle/ReParticle.h b/Resample/Particle/ReParticle.h
index c3d93233ae3775873028165a0176fe4a2180be6c..797589036a258071aebb9923db5cd8a16ac88996 100644
--- a/Resample/Particle/ReParticle.h
+++ b/Resample/Particle/ReParticle.h
@@ -21,12 +21,12 @@
 #define BORNAGAIN_RESAMPLE_PARTICLE_REPARTICLE_H
 
 #include "Resample/Particle/IReParticle.h"
+#include "Base/Vector/RotMatrix.h"
 #include <heinz/Vectors3D.h>
 #include <memory>
 
 class IFormFactor;
 class Material;
-class RotMatrix;
 
 //! A reprocessed simple particle, with shape m_ff.
 
diff --git a/Sample/Lattice/Lattice3D.cpp b/Sample/Lattice/Lattice3D.cpp
index 537294dd5d29f661ffd62faf97cd538fc67535ef..cd3847fef8df5d9c45961b594bc26d4e544027f6 100644
--- a/Sample/Lattice/Lattice3D.cpp
+++ b/Sample/Lattice/Lattice3D.cpp
@@ -14,7 +14,6 @@
 
 #include "Sample/Lattice/Lattice3D.h"
 #include "Base/Math/Constants.h"
-#include "Base/Vector/RotMatrix.h"
 #include "Sample/Lattice/ISelectionRule.h"
 #include <gsl/gsl_linalg.h>
 
diff --git a/Sample/Lattice/Lattice3D.h b/Sample/Lattice/Lattice3D.h
index c5f6325956713049f2faa9f360831c36760f36da..3e0b564bd1628fb34fa9bcb1ec1bbab20d414394 100644
--- a/Sample/Lattice/Lattice3D.h
+++ b/Sample/Lattice/Lattice3D.h
@@ -16,12 +16,12 @@
 #define BORNAGAIN_SAMPLE_LATTICE_LATTICE3D_H
 
 #include "Param/Node/INode.h"
+#include "Base/Vector/RotMatrix.h"
 #include <heinz/Vectors3D.h>
 #include <memory>
 #include <vector>
 
 class ISelectionRule;
-class RotMatrix;
 
 //! A Bravais lattice, characterized by three basis vectors, and optionally an ISelectionRule.
 
diff --git a/Sample/Material/BaseMaterialImpl.h b/Sample/Material/BaseMaterialImpl.h
index c84326dbfbafa95436eda863b09ed01d035a4c6f..6f16c40578012fa415200bd4d38533c9d06b017c 100644
--- a/Sample/Material/BaseMaterialImpl.h
+++ b/Sample/Material/BaseMaterialImpl.h
@@ -22,8 +22,8 @@
 
 #include <heinz/Complex.h>
 #include <heinz/Vectors3D.h>
+#include "Base/Vector/RotMatrix.h"
 
-class RotMatrix;
 class SpinMatrix;
 class WavevectorInfo;
 
diff --git a/Sample/Material/MagneticMaterialImpl.cpp b/Sample/Material/MagneticMaterialImpl.cpp
index 22c2b48f1987ab3b57b5645898461daac712ae9b..6eb249c22da9f6be6243af6ce720cf0421843cd8 100644
--- a/Sample/Material/MagneticMaterialImpl.cpp
+++ b/Sample/Material/MagneticMaterialImpl.cpp
@@ -15,7 +15,6 @@
 #include "Sample/Material/MagneticMaterialImpl.h"
 #include "Base/Const/PhysicalConstants.h"
 #include "Base/Spin/SpinMatrix.h"
-#include "Base/Vector/RotMatrix.h"
 #include "Base/Vector/WavevectorInfo.h"
 #include "Sample/Material/MaterialUtils.h"
 #include <memory>
diff --git a/Sample/Material/MagneticMaterialImpl.h b/Sample/Material/MagneticMaterialImpl.h
index 97c5207d7393ca9da5c23a57aad1f907dd1eb1c6..fe563ced9f191e05e2a9f87bd90f8ed103d79a26 100644
--- a/Sample/Material/MagneticMaterialImpl.h
+++ b/Sample/Material/MagneticMaterialImpl.h
@@ -21,8 +21,8 @@
 #define BORNAGAIN_SAMPLE_MATERIAL_MAGNETICMATERIALIMPL_H
 
 #include "Sample/Material/BaseMaterialImpl.h"
+#include "Base/Vector/RotMatrix.h"
 
-class RotMatrix;
 class WavevectorInfo;
 
 //! Basic implementation for magnetized material.
diff --git a/Sample/Material/Material.cpp b/Sample/Material/Material.cpp
index b8607e932cd73a98a9ed8d1384070776c5e97b2f..401a1b397bddf24d34a675aebaef2cf781b83dbb 100644
--- a/Sample/Material/Material.cpp
+++ b/Sample/Material/Material.cpp
@@ -15,7 +15,6 @@
 #include "Sample/Material/Material.h"
 #include "Base/Spin/SpinMatrix.h"
 #include "Base/Util/Assert.h"
-#include "Base/Vector/RotMatrix.h"
 #include "Base/Vector/WavevectorInfo.h"
 #include <typeinfo>
 
diff --git a/Sample/Material/Material.h b/Sample/Material/Material.h
index 46b734e99f38cd34c277d1a665824bec696f813b..fabdc818581d2a3f43bf977750b52f7b428dbcda 100644
--- a/Sample/Material/Material.h
+++ b/Sample/Material/Material.h
@@ -17,6 +17,7 @@
 
 #include <heinz/Complex.h>
 #include <heinz/Vectors3D.h>
+#include "Base/Vector/RotMatrix.h"
 #include <memory>
 #include <ostream>
 #include <vector>
@@ -25,7 +26,6 @@
 #include "Sample/Material/BaseMaterialImpl.h"
 #endif // SWIG
 
-class RotMatrix;
 class SpinMatrix;
 class WavevectorInfo;
 
diff --git a/Sample/Scattering/Rotations.cpp b/Sample/Scattering/Rotations.cpp
index 9083f76523a66b33fe1d9065be5c03f177bc3aaf..417e7bcd0ee7e2c61042131a1876607b62d31e68 100644
--- a/Sample/Scattering/Rotations.cpp
+++ b/Sample/Scattering/Rotations.cpp
@@ -14,7 +14,6 @@
 
 #include "Sample/Scattering/Rotations.h"
 #include "Base/Util/Assert.h"
-#include "Base/Vector/RotMatrix.h"
 
 //  ************************************************************************************************
 //  interface IRotation
diff --git a/Sample/Scattering/Rotations.h b/Sample/Scattering/Rotations.h
index 1b688df06e4428ddde48782ccaf8a9cd3387fa5d..6029467470de7dfc8f530fd32e0b923537c68954 100644
--- a/Sample/Scattering/Rotations.h
+++ b/Sample/Scattering/Rotations.h
@@ -16,11 +16,10 @@
 #define BORNAGAIN_SAMPLE_SCATTERING_ROTATIONS_H
 
 #include "Base/Types/ICloneable.h"
+#include "Base/Vector/RotMatrix.h"
 #include "Param/Node/INode.h"
 #include <heinz/Vectors3D.h>
 
-class RotMatrix;
-
 #ifndef USER_API
 
 //! Abstract base class for rotations.
diff --git a/Tests/Unit/Base/RotMatrixTest.cpp b/Tests/Unit/Base/RotMatrixTest.cpp
deleted file mode 100644
index bfdfda9cdda06d6bd11ce50a78fc2ffed414abda..0000000000000000000000000000000000000000
--- a/Tests/Unit/Base/RotMatrixTest.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-#include "Base/Vector/RotMatrix.h"
-#include "Tests/GTestWrapper/google_test.h"
-
-class RotMatrixTest : public ::testing::Test {
-protected:
-    const double epsilon = 1e-12;
-
-    const double w0 = M_PI / 5;
-    const double w1 = M_PI / 7;
-    const double w2 = M_PI / 11;
-
-    const RotMatrix mEul = RotMatrix::EulerZXZ(w0, w1, w2);
-
-    void InversionTest(const RotMatrix& mRot, const R3& a0)
-    {
-
-        const RotMatrix mInv = mRot.Inverse();
-
-        const R3 a1 = mRot.transformed(a0);
-        const R3 a2 = mInv.transformed(a1);
-
-        EXPECT_NEAR(a2.x(), a0.x(), epsilon);
-        EXPECT_NEAR(a2.y(), a0.y(), epsilon);
-        EXPECT_NEAR(a2.z(), a0.z(), epsilon);
-    }
-};
-
-
-TEST_F(RotMatrixTest, RotateY)
-{
-    const R3 a(std::sqrt(3.) / 2., 2., 0.5);
-    const RotMatrix m2 = RotMatrix::AroundY(M_PI / 6.);
-    const R3 v = m2.transformed(a);
-
-    EXPECT_NEAR(v.x(), 1.0, epsilon);
-    EXPECT_DOUBLE_EQ(v.y(), 2.0);
-    EXPECT_NEAR(v.z(), 0.0, epsilon);
-}
-
-TEST_F(RotMatrixTest, RotateZ)
-{
-    const R3 a(0.5, std::sqrt(3.) / 2., 2.);
-    const RotMatrix m3 = RotMatrix::AroundZ(M_PI / 6.);
-    const R3 v = m3.transformed(a);
-
-    EXPECT_NEAR(v.x(), 0.0, epsilon);
-    EXPECT_NEAR(v.y(), 1.0, epsilon);
-    EXPECT_DOUBLE_EQ(v.z(), 2.0);
-
-    const RotMatrix m4 = m3.Inverse();
-    const R3 w = m4.transformed(v);
-
-    EXPECT_NEAR(w.x(), a.x(), epsilon);
-    EXPECT_NEAR(w.y(), a.y(), epsilon);
-    EXPECT_NEAR(w.z(), a.z(), epsilon);
-}
-
-TEST_F(RotMatrixTest, RecoverEulerAngles)
-{
-    auto angles = mEul.zxzEulerAngles();
-
-    EXPECT_NEAR(angles[0], w0, epsilon);
-    EXPECT_NEAR(angles[1], w1, epsilon);
-    EXPECT_NEAR(angles[2], w2, epsilon);
-}
-
-TEST_F(RotMatrixTest, InvertXMatrix)
-{
-    InversionTest(RotMatrix::AroundX(M_PI / 7.), R3(4, 5, 6));
-}
-
-TEST_F(RotMatrixTest, InvertYMatrix)
-{
-    InversionTest(RotMatrix::AroundY(M_PI / 7.), R3(4, 5, 6));
-}
-
-TEST_F(RotMatrixTest, InvertZMatrix)
-{
-    InversionTest(RotMatrix::AroundZ(M_PI / 7.), R3(4, 5, 6));
-}
-
-TEST_F(RotMatrixTest, InvertEulerMatrix)
-{
-    InversionTest(mEul, R3(3, 4, 7));
-}
diff --git a/auto/Wrap/doxygenBase.i b/auto/Wrap/doxygenBase.i
index d8ee61c1553d053c032aac902b3e86ce2538dd8f..30e6d5661633ad43a878d93acc12ab02eb7254bf 100644
--- a/auto/Wrap/doxygenBase.i
+++ b/auto/Wrap/doxygenBase.i
@@ -952,57 +952,6 @@ RectangularPixel::solidAngle";
 RectangularPixel::createAxis";
 
 
-// File: classRotMatrix.xml
-%feature("docstring") RotMatrix "
-
-Rotation matrix in three dimensions. Represents group SO(3). Internal parameterization based on quaternions.
-
-C++ includes: RotMatrix.h
-";
-
-%feature("docstring")  RotMatrix::RotMatrix "RotMatrix::RotMatrix()
-RotMatrix::RotMatrix
-Constructs unit transformation. 
-";
-
-%feature("docstring")  RotMatrix::~RotMatrix "RotMatrix::~RotMatrix()=default
-RotMatrix::~RotMatrix
-Destructor. 
-";
-
-%feature("docstring")  RotMatrix::zxzEulerAngles "std::array< double, 3 > RotMatrix::zxzEulerAngles() const
-RotMatrix::zxzEulerAngles
-Calculates the Euler angles corresponding to the rotation. 
-";
-
-%feature("docstring")  RotMatrix::Inverse "RotMatrix RotMatrix::Inverse() const
-RotMatrix::Inverse
-Returns the inverse transformation. 
-";
-
-%feature("docstring")  RotMatrix::transformed "template C3 RotMatrix::transformed< C3 >(const U &v) const
-RotMatrix::transformed
-Return transformed vector  v. 
-";
-
-%feature("docstring")  RotMatrix::isIdentity "bool RotMatrix::isIdentity() const
-RotMatrix::isIdentity
-Determine if the transformation is trivial (identity) 
-";
-
-%feature("docstring")  RotMatrix::isXRotation "bool RotMatrix::isXRotation() const
-RotMatrix::isXRotation";
-
-%feature("docstring")  RotMatrix::isYRotation "bool RotMatrix::isYRotation() const
-RotMatrix::isYRotation";
-
-%feature("docstring")  RotMatrix::isZRotation "bool RotMatrix::isZRotation() const
-RotMatrix::isZRotation";
-
-%feature("docstring")  RotMatrix::angleAroundCoordAxis "std::optional< double > RotMatrix::angleAroundCoordAxis(int iAxis) const
-RotMatrix::angleAroundCoordAxis";
-
-
 // File: classSphericalPixel.xml
 %feature("docstring") SphericalPixel "
 
@@ -1820,9 +1769,6 @@ This templated function is used in catalogs in form of a function pointer 'creat
 ";
 
 
-// File: RotMatrix_8cpp.xml
-
-
 // File: RotMatrix_8h.xml
 
 
diff --git a/auto/Wrap/libBornAgainBase.py b/auto/Wrap/libBornAgainBase.py
index 3b4773c98e16df80ad4f10d1534f10ebd471e413..6f6b67656354ec847cf6e5b6e0f47c6c3f2b2c45 100644
--- a/auto/Wrap/libBornAgainBase.py
+++ b/auto/Wrap/libBornAgainBase.py
@@ -1874,139 +1874,6 @@ deg = cvar.deg
 tesla = cvar.tesla
 gauss = cvar.gauss
 
-class RotMatrix(object):
-    r"""
-
-
-    Rotation matrix in three dimensions. Represents group SO(3). Internal parameterization based on quaternions.
-
-    C++ includes: RotMatrix.h
-
-    """
-
-    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
-    __repr__ = _swig_repr
-
-    def __init__(self):
-        r"""
-        __init__(RotMatrix self) -> RotMatrix
-        RotMatrix::RotMatrix()
-        RotMatrix::RotMatrix
-        Constructs unit transformation. 
-
-        """
-        _libBornAgainBase.RotMatrix_swiginit(self, _libBornAgainBase.new_RotMatrix())
-    __swig_destroy__ = _libBornAgainBase.delete_RotMatrix
-
-    @staticmethod
-    def AroundX(phi):
-        r"""AroundX(double phi) -> RotMatrix"""
-        return _libBornAgainBase.RotMatrix_AroundX(phi)
-
-    @staticmethod
-    def AroundY(phi):
-        r"""AroundY(double phi) -> RotMatrix"""
-        return _libBornAgainBase.RotMatrix_AroundY(phi)
-
-    @staticmethod
-    def AroundZ(phi):
-        r"""AroundZ(double phi) -> RotMatrix"""
-        return _libBornAgainBase.RotMatrix_AroundZ(phi)
-
-    @staticmethod
-    def EulerZXZ(alpha, beta, gamma):
-        r"""EulerZXZ(double alpha, double beta, double gamma) -> RotMatrix"""
-        return _libBornAgainBase.RotMatrix_EulerZXZ(alpha, beta, gamma)
-
-    def zxzEulerAngles(self):
-        r"""
-        zxzEulerAngles(RotMatrix self) -> std::array< double,3 >
-        std::array< double, 3 > RotMatrix::zxzEulerAngles() const
-        RotMatrix::zxzEulerAngles
-        Calculates the Euler angles corresponding to the rotation. 
-
-        """
-        return _libBornAgainBase.RotMatrix_zxzEulerAngles(self)
-
-    def Inverse(self):
-        r"""
-        Inverse(RotMatrix self) -> RotMatrix
-        RotMatrix RotMatrix::Inverse() const
-        RotMatrix::Inverse
-        Returns the inverse transformation. 
-
-        """
-        return _libBornAgainBase.RotMatrix_Inverse(self)
-
-    def __mul__(self, arg2):
-        r"""__mul__(RotMatrix self, RotMatrix arg2) -> RotMatrix"""
-        return _libBornAgainBase.RotMatrix___mul__(self, arg2)
-
-    def __eq__(self, arg2):
-        r"""__eq__(RotMatrix self, RotMatrix arg2) -> bool"""
-        return _libBornAgainBase.RotMatrix___eq__(self, arg2)
-
-    def isIdentity(self):
-        r"""
-        isIdentity(RotMatrix self) -> bool
-        bool RotMatrix::isIdentity() const
-        RotMatrix::isIdentity
-        Determine if the transformation is trivial (identity) 
-
-        """
-        return _libBornAgainBase.RotMatrix_isIdentity(self)
-
-    def isXRotation(self):
-        r"""
-        isXRotation(RotMatrix self) -> bool
-        bool RotMatrix::isXRotation() const
-        RotMatrix::isXRotation
-        """
-        return _libBornAgainBase.RotMatrix_isXRotation(self)
-
-    def isYRotation(self):
-        r"""
-        isYRotation(RotMatrix self) -> bool
-        bool RotMatrix::isYRotation() const
-        RotMatrix::isYRotation
-        """
-        return _libBornAgainBase.RotMatrix_isYRotation(self)
-
-    def isZRotation(self):
-        r"""
-        isZRotation(RotMatrix self) -> bool
-        bool RotMatrix::isZRotation() const
-        RotMatrix::isZRotation
-        """
-        return _libBornAgainBase.RotMatrix_isZRotation(self)
-
-    def angleAroundCoordAxis(self, iAxis):
-        r"""
-        angleAroundCoordAxis(RotMatrix self, int iAxis) -> std::optional< double >
-        std::optional< double > RotMatrix::angleAroundCoordAxis(int iAxis) const
-        RotMatrix::angleAroundCoordAxis
-        """
-        return _libBornAgainBase.RotMatrix_angleAroundCoordAxis(self, iAxis)
-
-# Register RotMatrix in _libBornAgainBase:
-_libBornAgainBase.RotMatrix_swigregister(RotMatrix)
-
-def RotMatrix_AroundX(phi):
-    r"""RotMatrix_AroundX(double phi) -> RotMatrix"""
-    return _libBornAgainBase.RotMatrix_AroundX(phi)
-
-def RotMatrix_AroundY(phi):
-    r"""RotMatrix_AroundY(double phi) -> RotMatrix"""
-    return _libBornAgainBase.RotMatrix_AroundY(phi)
-
-def RotMatrix_AroundZ(phi):
-    r"""RotMatrix_AroundZ(double phi) -> RotMatrix"""
-    return _libBornAgainBase.RotMatrix_AroundZ(phi)
-
-def RotMatrix_EulerZXZ(alpha, beta, gamma):
-    r"""RotMatrix_EulerZXZ(double alpha, double beta, double gamma) -> RotMatrix"""
-    return _libBornAgainBase.RotMatrix_EulerZXZ(alpha, beta, gamma)
-
 class Bin1D(object):
     r"""Proxy of C++ Bin1D class."""
 
diff --git a/auto/Wrap/libBornAgainBase_wrap.cpp b/auto/Wrap/libBornAgainBase_wrap.cpp
index cc38b40043fd51a87bcddb72d6c362932009dad8..91cb83fda3742fd5e66215f1512b2d8382204fa7 100644
--- a/auto/Wrap/libBornAgainBase_wrap.cpp
+++ b/auto/Wrap/libBornAgainBase_wrap.cpp
@@ -3106,7 +3106,7 @@ namespace Swig {
 #define SWIGTYPE_p_IAxis swig_types[6]
 #define SWIGTYPE_p_ICloneable swig_types[7]
 #define SWIGTYPE_p_PointwiseAxis swig_types[8]
-#define SWIGTYPE_p_RotMatrix swig_types[9]
+#define SWIGTYPE_p_Rotation3DT_double_t swig_types[9]
 #define SWIGTYPE_p_ThreadInfo swig_types[10]
 #define SWIGTYPE_p_VariableBinAxis swig_types[11]
 #define SWIGTYPE_p_Vec3T_double_t swig_types[12]
@@ -3134,31 +3134,29 @@ namespace Swig {
 #define SWIGTYPE_p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t swig_types[34]
 #define SWIGTYPE_p_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t swig_types[35]
 #define SWIGTYPE_p_std__allocatorT_unsigned_long_t swig_types[36]
-#define SWIGTYPE_p_std__arrayT_double_3_t swig_types[37]
-#define SWIGTYPE_p_std__complexT_double_t swig_types[38]
-#define SWIGTYPE_p_std__invalid_argument swig_types[39]
-#define SWIGTYPE_p_std__lessT_std__string_t swig_types[40]
-#define SWIGTYPE_p_std__mapT_std__string_double_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_double_t_t_t swig_types[41]
-#define SWIGTYPE_p_std__optionalT_double_t swig_types[42]
-#define SWIGTYPE_p_std__pairT_double_double_t swig_types[43]
-#define SWIGTYPE_p_std__vectorT_IAxis_p_std__allocatorT_IAxis_p_t_t swig_types[44]
-#define SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t swig_types[45]
-#define SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t swig_types[46]
-#define SWIGTYPE_p_std__vectorT_std__complexT_double_t_std__allocatorT_std__complexT_double_t_t_t swig_types[47]
-#define SWIGTYPE_p_std__vectorT_std__pairT_double_double_t_std__allocatorT_std__pairT_double_double_t_t_t swig_types[48]
-#define SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t swig_types[49]
-#define SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t swig_types[50]
-#define SWIGTYPE_p_std__vectorT_std__vectorT_int_std__allocatorT_int_t_t_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t_t swig_types[51]
-#define SWIGTYPE_p_std__vectorT_unsigned_int_std__allocatorT_unsigned_int_t_t swig_types[52]
-#define SWIGTYPE_p_std__vectorT_unsigned_long_std__allocatorT_unsigned_long_t_t swig_types[53]
-#define SWIGTYPE_p_swig__SwigPyIterator swig_types[54]
-#define SWIGTYPE_p_unsigned_char swig_types[55]
-#define SWIGTYPE_p_unsigned_int swig_types[56]
-#define SWIGTYPE_p_unsigned_long_long swig_types[57]
-#define SWIGTYPE_p_unsigned_short swig_types[58]
-#define SWIGTYPE_p_value_type swig_types[59]
-static swig_type_info *swig_types[61];
-static swig_module_info swig_module = {swig_types, 60, 0, 0, 0, 0};
+#define SWIGTYPE_p_std__complexT_double_t swig_types[37]
+#define SWIGTYPE_p_std__invalid_argument swig_types[38]
+#define SWIGTYPE_p_std__lessT_std__string_t swig_types[39]
+#define SWIGTYPE_p_std__mapT_std__string_double_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_double_t_t_t swig_types[40]
+#define SWIGTYPE_p_std__pairT_double_double_t swig_types[41]
+#define SWIGTYPE_p_std__vectorT_IAxis_p_std__allocatorT_IAxis_p_t_t swig_types[42]
+#define SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t swig_types[43]
+#define SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t swig_types[44]
+#define SWIGTYPE_p_std__vectorT_std__complexT_double_t_std__allocatorT_std__complexT_double_t_t_t swig_types[45]
+#define SWIGTYPE_p_std__vectorT_std__pairT_double_double_t_std__allocatorT_std__pairT_double_double_t_t_t swig_types[46]
+#define SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t swig_types[47]
+#define SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t swig_types[48]
+#define SWIGTYPE_p_std__vectorT_std__vectorT_int_std__allocatorT_int_t_t_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t_t swig_types[49]
+#define SWIGTYPE_p_std__vectorT_unsigned_int_std__allocatorT_unsigned_int_t_t swig_types[50]
+#define SWIGTYPE_p_std__vectorT_unsigned_long_std__allocatorT_unsigned_long_t_t swig_types[51]
+#define SWIGTYPE_p_swig__SwigPyIterator swig_types[52]
+#define SWIGTYPE_p_unsigned_char swig_types[53]
+#define SWIGTYPE_p_unsigned_int swig_types[54]
+#define SWIGTYPE_p_unsigned_long_long swig_types[55]
+#define SWIGTYPE_p_unsigned_short swig_types[56]
+#define SWIGTYPE_p_value_type swig_types[57]
+static swig_type_info *swig_types[59];
+static swig_module_info swig_module = {swig_types, 58, 0, 0, 0, 0};
 #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
 #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
 
@@ -24608,397 +24606,6 @@ SWIGINTERN PyObject *Direction_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject
   return SWIG_Python_InitShadowInstance(args);
 }
 
-SWIGINTERN PyObject *_wrap_new_RotMatrix(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  RotMatrix *result = 0 ;
-  
-  if (!SWIG_Python_UnpackTuple(args, "new_RotMatrix", 0, 0, 0)) SWIG_fail;
-  result = (RotMatrix *)new RotMatrix();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_RotMatrix, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_delete_RotMatrix(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  RotMatrix *arg1 = (RotMatrix *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_RotMatrix, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_RotMatrix" "', argument " "1"" of type '" "RotMatrix *""'"); 
-  }
-  arg1 = reinterpret_cast< RotMatrix * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_RotMatrix_AroundX(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  double arg1 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  PyObject *swig_obj[1] ;
-  RotMatrix result;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  ecode1 = SWIG_AsVal_double(swig_obj[0], &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "RotMatrix_AroundX" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  result = RotMatrix::AroundX(arg1);
-  resultobj = SWIG_NewPointerObj((new RotMatrix(static_cast< const RotMatrix& >(result))), SWIGTYPE_p_RotMatrix, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_RotMatrix_AroundY(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  double arg1 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  PyObject *swig_obj[1] ;
-  RotMatrix result;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  ecode1 = SWIG_AsVal_double(swig_obj[0], &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "RotMatrix_AroundY" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  result = RotMatrix::AroundY(arg1);
-  resultobj = SWIG_NewPointerObj((new RotMatrix(static_cast< const RotMatrix& >(result))), SWIGTYPE_p_RotMatrix, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_RotMatrix_AroundZ(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  double arg1 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  PyObject *swig_obj[1] ;
-  RotMatrix result;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  ecode1 = SWIG_AsVal_double(swig_obj[0], &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "RotMatrix_AroundZ" "', argument " "1"" of type '" "double""'");
-  } 
-  arg1 = static_cast< double >(val1);
-  result = RotMatrix::AroundZ(arg1);
-  resultobj = SWIG_NewPointerObj((new RotMatrix(static_cast< const RotMatrix& >(result))), SWIGTYPE_p_RotMatrix, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_RotMatrix_EulerZXZ(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  double arg1 ;
-  double arg2 ;
-  double arg3 ;
-  double val1 ;
-  int ecode1 = 0 ;
-  double val2 ;
-  int ecode2 = 0 ;
-  double val3 ;
-  int ecode3 = 0 ;
-  PyObject *swig_obj[3] ;
-  RotMatrix result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "RotMatrix_EulerZXZ", 3, 3, swig_obj)) SWIG_fail;
-  ecode1 = SWIG_AsVal_double(swig_obj[0], &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "RotMatrix_EulerZXZ" "', 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 '" "RotMatrix_EulerZXZ" "', argument " "2"" of type '" "double""'");
-  } 
-  arg2 = static_cast< double >(val2);
-  ecode3 = SWIG_AsVal_double(swig_obj[2], &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "RotMatrix_EulerZXZ" "', argument " "3"" of type '" "double""'");
-  } 
-  arg3 = static_cast< double >(val3);
-  result = RotMatrix::EulerZXZ(arg1,arg2,arg3);
-  resultobj = SWIG_NewPointerObj((new RotMatrix(static_cast< const RotMatrix& >(result))), SWIGTYPE_p_RotMatrix, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_RotMatrix_zxzEulerAngles(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  RotMatrix *arg1 = (RotMatrix *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  std::array< double,3 > result;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_RotMatrix, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "RotMatrix_zxzEulerAngles" "', argument " "1"" of type '" "RotMatrix const *""'"); 
-  }
-  arg1 = reinterpret_cast< RotMatrix * >(argp1);
-  result = ((RotMatrix const *)arg1)->zxzEulerAngles();
-  resultobj = SWIG_NewPointerObj((new std::array< double,3 >(static_cast< const std::array< double,3 >& >(result))), SWIGTYPE_p_std__arrayT_double_3_t, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_RotMatrix_Inverse(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  RotMatrix *arg1 = (RotMatrix *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  RotMatrix result;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_RotMatrix, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "RotMatrix_Inverse" "', argument " "1"" of type '" "RotMatrix const *""'"); 
-  }
-  arg1 = reinterpret_cast< RotMatrix * >(argp1);
-  result = ((RotMatrix const *)arg1)->Inverse();
-  resultobj = SWIG_NewPointerObj((new RotMatrix(static_cast< const RotMatrix& >(result))), SWIGTYPE_p_RotMatrix, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_RotMatrix___mul__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  RotMatrix *arg1 = (RotMatrix *) 0 ;
-  RotMatrix *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject *swig_obj[2] ;
-  RotMatrix result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "RotMatrix___mul__", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_RotMatrix, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "RotMatrix___mul__" "', argument " "1"" of type '" "RotMatrix const *""'"); 
-  }
-  arg1 = reinterpret_cast< RotMatrix * >(argp1);
-  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_RotMatrix,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "RotMatrix___mul__" "', argument " "2"" of type '" "RotMatrix const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "RotMatrix___mul__" "', argument " "2"" of type '" "RotMatrix const &""'"); 
-  }
-  arg2 = reinterpret_cast< RotMatrix * >(argp2);
-  result = ((RotMatrix const *)arg1)->operator *((RotMatrix const &)*arg2);
-  resultobj = SWIG_NewPointerObj((new RotMatrix(static_cast< const RotMatrix& >(result))), SWIGTYPE_p_RotMatrix, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  PyErr_Clear();
-  Py_INCREF(Py_NotImplemented);
-  return Py_NotImplemented;
-}
-
-
-SWIGINTERN PyObject *_wrap_RotMatrix___eq__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  RotMatrix *arg1 = (RotMatrix *) 0 ;
-  RotMatrix *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, "RotMatrix___eq__", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_RotMatrix, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "RotMatrix___eq__" "', argument " "1"" of type '" "RotMatrix const *""'"); 
-  }
-  arg1 = reinterpret_cast< RotMatrix * >(argp1);
-  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_RotMatrix,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "RotMatrix___eq__" "', argument " "2"" of type '" "RotMatrix const &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "RotMatrix___eq__" "', argument " "2"" of type '" "RotMatrix const &""'"); 
-  }
-  arg2 = reinterpret_cast< RotMatrix * >(argp2);
-  result = (bool)((RotMatrix const *)arg1)->operator ==((RotMatrix 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_RotMatrix_isIdentity(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  RotMatrix *arg1 = (RotMatrix *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  bool result;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_RotMatrix, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "RotMatrix_isIdentity" "', argument " "1"" of type '" "RotMatrix const *""'"); 
-  }
-  arg1 = reinterpret_cast< RotMatrix * >(argp1);
-  result = (bool)((RotMatrix const *)arg1)->isIdentity();
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_RotMatrix_isXRotation(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  RotMatrix *arg1 = (RotMatrix *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  bool result;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_RotMatrix, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "RotMatrix_isXRotation" "', argument " "1"" of type '" "RotMatrix const *""'"); 
-  }
-  arg1 = reinterpret_cast< RotMatrix * >(argp1);
-  result = (bool)((RotMatrix const *)arg1)->isXRotation();
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_RotMatrix_isYRotation(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  RotMatrix *arg1 = (RotMatrix *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  bool result;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_RotMatrix, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "RotMatrix_isYRotation" "', argument " "1"" of type '" "RotMatrix const *""'"); 
-  }
-  arg1 = reinterpret_cast< RotMatrix * >(argp1);
-  result = (bool)((RotMatrix const *)arg1)->isYRotation();
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_RotMatrix_isZRotation(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  RotMatrix *arg1 = (RotMatrix *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  bool result;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_RotMatrix, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "RotMatrix_isZRotation" "', argument " "1"" of type '" "RotMatrix const *""'"); 
-  }
-  arg1 = reinterpret_cast< RotMatrix * >(argp1);
-  result = (bool)((RotMatrix const *)arg1)->isZRotation();
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_RotMatrix_angleAroundCoordAxis(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  RotMatrix *arg1 = (RotMatrix *) 0 ;
-  int arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int val2 ;
-  int ecode2 = 0 ;
-  PyObject *swig_obj[2] ;
-  std::optional< double > result;
-  
-  if (!SWIG_Python_UnpackTuple(args, "RotMatrix_angleAroundCoordAxis", 2, 2, swig_obj)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_RotMatrix, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "RotMatrix_angleAroundCoordAxis" "', argument " "1"" of type '" "RotMatrix const *""'"); 
-  }
-  arg1 = reinterpret_cast< RotMatrix * >(argp1);
-  ecode2 = SWIG_AsVal_int(swig_obj[1], &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "RotMatrix_angleAroundCoordAxis" "', argument " "2"" of type '" "int""'");
-  } 
-  arg2 = static_cast< int >(val2);
-  result = ((RotMatrix const *)arg1)->angleAroundCoordAxis(arg2);
-  resultobj = SWIG_NewPointerObj((new std::optional< double >(static_cast< const std::optional< double >& >(result))), SWIGTYPE_p_std__optionalT_double_t, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *RotMatrix_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_RotMatrix, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *RotMatrix_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  return SWIG_Python_InitShadowInstance(args);
-}
-
 SWIGINTERN PyObject *_wrap_new_Bin1D__SWIG_0(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) {
   PyObject *resultobj = 0;
   Bin1D *result = 0 ;
@@ -29689,69 +29296,6 @@ static PyMethodDef SwigMethods[] = {
 	 { "delete_Direction", _wrap_delete_Direction, METH_O, "delete_Direction(Direction self)"},
 	 { "Direction_swigregister", Direction_swigregister, METH_O, NULL},
 	 { "Direction_swiginit", Direction_swiginit, METH_VARARGS, NULL},
-	 { "new_RotMatrix", _wrap_new_RotMatrix, METH_NOARGS, "\n"
-		"new_RotMatrix() -> RotMatrix\n"
-		"RotMatrix::RotMatrix()\n"
-		"RotMatrix::RotMatrix\n"
-		"Constructs unit transformation. \n"
-		"\n"
-		""},
-	 { "delete_RotMatrix", _wrap_delete_RotMatrix, METH_O, "\n"
-		"delete_RotMatrix(RotMatrix self)\n"
-		"RotMatrix::~RotMatrix()=default\n"
-		"RotMatrix::~RotMatrix\n"
-		"Destructor. \n"
-		"\n"
-		""},
-	 { "RotMatrix_AroundX", _wrap_RotMatrix_AroundX, METH_O, "RotMatrix_AroundX(double phi) -> RotMatrix"},
-	 { "RotMatrix_AroundY", _wrap_RotMatrix_AroundY, METH_O, "RotMatrix_AroundY(double phi) -> RotMatrix"},
-	 { "RotMatrix_AroundZ", _wrap_RotMatrix_AroundZ, METH_O, "RotMatrix_AroundZ(double phi) -> RotMatrix"},
-	 { "RotMatrix_EulerZXZ", _wrap_RotMatrix_EulerZXZ, METH_VARARGS, "RotMatrix_EulerZXZ(double alpha, double beta, double gamma) -> RotMatrix"},
-	 { "RotMatrix_zxzEulerAngles", _wrap_RotMatrix_zxzEulerAngles, METH_O, "\n"
-		"RotMatrix_zxzEulerAngles(RotMatrix self) -> std::array< double,3 >\n"
-		"std::array< double, 3 > RotMatrix::zxzEulerAngles() const\n"
-		"RotMatrix::zxzEulerAngles\n"
-		"Calculates the Euler angles corresponding to the rotation. \n"
-		"\n"
-		""},
-	 { "RotMatrix_Inverse", _wrap_RotMatrix_Inverse, METH_O, "\n"
-		"RotMatrix_Inverse(RotMatrix self) -> RotMatrix\n"
-		"RotMatrix RotMatrix::Inverse() const\n"
-		"RotMatrix::Inverse\n"
-		"Returns the inverse transformation. \n"
-		"\n"
-		""},
-	 { "RotMatrix___mul__", _wrap_RotMatrix___mul__, METH_VARARGS, "RotMatrix___mul__(RotMatrix self, RotMatrix arg2) -> RotMatrix"},
-	 { "RotMatrix___eq__", _wrap_RotMatrix___eq__, METH_VARARGS, "RotMatrix___eq__(RotMatrix self, RotMatrix arg2) -> bool"},
-	 { "RotMatrix_isIdentity", _wrap_RotMatrix_isIdentity, METH_O, "\n"
-		"RotMatrix_isIdentity(RotMatrix self) -> bool\n"
-		"bool RotMatrix::isIdentity() const\n"
-		"RotMatrix::isIdentity\n"
-		"Determine if the transformation is trivial (identity) \n"
-		"\n"
-		""},
-	 { "RotMatrix_isXRotation", _wrap_RotMatrix_isXRotation, METH_O, "\n"
-		"RotMatrix_isXRotation(RotMatrix self) -> bool\n"
-		"bool RotMatrix::isXRotation() const\n"
-		"RotMatrix::isXRotation\n"
-		""},
-	 { "RotMatrix_isYRotation", _wrap_RotMatrix_isYRotation, METH_O, "\n"
-		"RotMatrix_isYRotation(RotMatrix self) -> bool\n"
-		"bool RotMatrix::isYRotation() const\n"
-		"RotMatrix::isYRotation\n"
-		""},
-	 { "RotMatrix_isZRotation", _wrap_RotMatrix_isZRotation, METH_O, "\n"
-		"RotMatrix_isZRotation(RotMatrix self) -> bool\n"
-		"bool RotMatrix::isZRotation() const\n"
-		"RotMatrix::isZRotation\n"
-		""},
-	 { "RotMatrix_angleAroundCoordAxis", _wrap_RotMatrix_angleAroundCoordAxis, METH_VARARGS, "\n"
-		"RotMatrix_angleAroundCoordAxis(RotMatrix self, int iAxis) -> std::optional< double >\n"
-		"std::optional< double > RotMatrix::angleAroundCoordAxis(int iAxis) const\n"
-		"RotMatrix::angleAroundCoordAxis\n"
-		""},
-	 { "RotMatrix_swigregister", RotMatrix_swigregister, METH_O, NULL},
-	 { "RotMatrix_swiginit", RotMatrix_swiginit, METH_VARARGS, NULL},
 	 { "new_Bin1D", _wrap_new_Bin1D, METH_VARARGS, "\n"
 		"Bin1D()\n"
 		"new_Bin1D(double lower, double upper) -> Bin1D\n"
@@ -30459,7 +30003,7 @@ static swig_type_info _swigt__p_Frame = {"_p_Frame", "Frame *", 0, 0, (void*)0,
 static swig_type_info _swigt__p_IAxis = {"_p_IAxis", "IAxis *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_ICloneable = {"_p_ICloneable", "ICloneable *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_PointwiseAxis = {"_p_PointwiseAxis", "PointwiseAxis *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_RotMatrix = {"_p_RotMatrix", "RotMatrix *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_Rotation3DT_double_t = {"_p_Rotation3DT_double_t", "RotMatrix *|Rotation3D< double > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_ThreadInfo = {"_p_ThreadInfo", "ThreadInfo *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_VariableBinAxis = {"_p_VariableBinAxis", "VariableBinAxis *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Vec3T_double_t = {"_p_Vec3T_double_t", "R3 *|Vec3< double > *", 0, 0, (void*)0, 0};
@@ -30487,12 +30031,10 @@ static swig_type_info _swigt__p_std__allocatorT_std__string_t = {"_p_std__alloca
 static swig_type_info _swigt__p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t = {"_p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t", "std::vector< std::vector< double > >::allocator_type *|std::allocator< std::vector< double,std::allocator< double > > > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t = {"_p_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t", "std::vector< std::vector< int > >::allocator_type *|std::allocator< std::vector< int,std::allocator< int > > > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__allocatorT_unsigned_long_t = {"_p_std__allocatorT_unsigned_long_t", "std::vector< unsigned long >::allocator_type *|std::allocator< unsigned long > *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__arrayT_double_3_t = {"_p_std__arrayT_double_3_t", "std::array< double,3 > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__complexT_double_t = {"_p_std__complexT_double_t", "complex_t *|std::complex< double > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__invalid_argument = {"_p_std__invalid_argument", "std::invalid_argument *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__lessT_std__string_t = {"_p_std__lessT_std__string_t", "std::less< std::string > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__mapT_std__string_double_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_double_t_t_t = {"_p_std__mapT_std__string_double_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_double_t_t_t", "std::map< std::string,double,std::less< std::string >,std::allocator< std::pair< std::string const,double > > > *|std::map< std::string,double > *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__optionalT_double_t = {"_p_std__optionalT_double_t", "std::optional< double > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__pairT_double_double_t = {"_p_std__pairT_double_double_t", "std::pair< double,double > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__vectorT_IAxis_p_std__allocatorT_IAxis_p_t_t = {"_p_std__vectorT_IAxis_p_std__allocatorT_IAxis_p_t_t", "std::vector< IAxis *,std::allocator< IAxis * > > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__vectorT_double_std__allocatorT_double_t_t = {"_p_std__vectorT_double_std__allocatorT_double_t_t", "std::vector< double,std::allocator< double > > *|std::vector< double > *", 0, 0, (void*)0, 0};
@@ -30521,7 +30063,7 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_IAxis,
   &_swigt__p_ICloneable,
   &_swigt__p_PointwiseAxis,
-  &_swigt__p_RotMatrix,
+  &_swigt__p_Rotation3DT_double_t,
   &_swigt__p_ThreadInfo,
   &_swigt__p_VariableBinAxis,
   &_swigt__p_Vec3T_double_t,
@@ -30549,12 +30091,10 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t,
   &_swigt__p_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t,
   &_swigt__p_std__allocatorT_unsigned_long_t,
-  &_swigt__p_std__arrayT_double_3_t,
   &_swigt__p_std__complexT_double_t,
   &_swigt__p_std__invalid_argument,
   &_swigt__p_std__lessT_std__string_t,
   &_swigt__p_std__mapT_std__string_double_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_double_t_t_t,
-  &_swigt__p_std__optionalT_double_t,
   &_swigt__p_std__pairT_double_double_t,
   &_swigt__p_std__vectorT_IAxis_p_std__allocatorT_IAxis_p_t_t,
   &_swigt__p_std__vectorT_double_std__allocatorT_double_t_t,
@@ -30583,7 +30123,7 @@ static swig_cast_info _swigc__p_Frame[] = {  {&_swigt__p_Frame, 0, 0, 0},{0, 0,
 static swig_cast_info _swigc__p_IAxis[] = {  {&_swigt__p_PointwiseAxis, _p_PointwiseAxisTo_p_IAxis, 0, 0},  {&_swigt__p_IAxis, 0, 0, 0},  {&_swigt__p_VariableBinAxis, _p_VariableBinAxisTo_p_IAxis, 0, 0},  {&_swigt__p_ConstKBinAxis, _p_ConstKBinAxisTo_p_IAxis, 0, 0},  {&_swigt__p_CustomBinAxis, _p_CustomBinAxisTo_p_IAxis, 0, 0},  {&_swigt__p_FixedBinAxis, _p_FixedBinAxisTo_p_IAxis, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_ICloneable[] = {  {&_swigt__p_ICloneable, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_PointwiseAxis[] = {  {&_swigt__p_PointwiseAxis, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_RotMatrix[] = {  {&_swigt__p_RotMatrix, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_Rotation3DT_double_t[] = {  {&_swigt__p_Rotation3DT_double_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_ThreadInfo[] = {  {&_swigt__p_ThreadInfo, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_VariableBinAxis[] = {  {&_swigt__p_VariableBinAxis, 0, 0, 0},  {&_swigt__p_ConstKBinAxis, _p_ConstKBinAxisTo_p_VariableBinAxis, 0, 0},  {&_swigt__p_CustomBinAxis, _p_CustomBinAxisTo_p_VariableBinAxis, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_Vec3T_double_t[] = {  {&_swigt__p_Vec3T_double_t, 0, 0, 0},{0, 0, 0, 0}};
@@ -30611,12 +30151,10 @@ static swig_cast_info _swigc__p_std__allocatorT_std__string_t[] = {  {&_swigt__p
 static swig_cast_info _swigc__p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t[] = {  {&_swigt__p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t[] = {  {&_swigt__p_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__allocatorT_unsigned_long_t[] = {  {&_swigt__p_std__allocatorT_unsigned_long_t, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__arrayT_double_3_t[] = {  {&_swigt__p_std__arrayT_double_3_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__complexT_double_t[] = {  {&_swigt__p_std__complexT_double_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__invalid_argument[] = {  {&_swigt__p_std__invalid_argument, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__lessT_std__string_t[] = {  {&_swigt__p_std__lessT_std__string_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__mapT_std__string_double_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_double_t_t_t[] = {  {&_swigt__p_std__mapT_std__string_double_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_double_t_t_t, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__optionalT_double_t[] = {  {&_swigt__p_std__optionalT_double_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__pairT_double_double_t[] = {  {&_swigt__p_std__pairT_double_double_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__vectorT_IAxis_p_std__allocatorT_IAxis_p_t_t[] = {  {&_swigt__p_std__vectorT_IAxis_p_std__allocatorT_IAxis_p_t_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__vectorT_double_std__allocatorT_double_t_t[] = {  {&_swigt__p_std__vectorT_double_std__allocatorT_double_t_t, 0, 0, 0},{0, 0, 0, 0}};
@@ -30645,7 +30183,7 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_IAxis,
   _swigc__p_ICloneable,
   _swigc__p_PointwiseAxis,
-  _swigc__p_RotMatrix,
+  _swigc__p_Rotation3DT_double_t,
   _swigc__p_ThreadInfo,
   _swigc__p_VariableBinAxis,
   _swigc__p_Vec3T_double_t,
@@ -30673,12 +30211,10 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t,
   _swigc__p_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t,
   _swigc__p_std__allocatorT_unsigned_long_t,
-  _swigc__p_std__arrayT_double_3_t,
   _swigc__p_std__complexT_double_t,
   _swigc__p_std__invalid_argument,
   _swigc__p_std__lessT_std__string_t,
   _swigc__p_std__mapT_std__string_double_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_double_t_t_t,
-  _swigc__p_std__optionalT_double_t,
   _swigc__p_std__pairT_double_double_t,
   _swigc__p_std__vectorT_IAxis_p_std__allocatorT_IAxis_p_t_t,
   _swigc__p_std__vectorT_double_std__allocatorT_double_t_t,
diff --git a/auto/Wrap/libBornAgainResample_wrap.cpp b/auto/Wrap/libBornAgainResample_wrap.cpp
index e2030323dd9894ca8c7302a635e4ccb875b03ace..67ec7f30b64ff7eaec9d056c958cbf2bc424abe6 100644
--- a/auto/Wrap/libBornAgainResample_wrap.cpp
+++ b/auto/Wrap/libBornAgainResample_wrap.cpp
@@ -3098,56 +3098,57 @@ namespace Swig {
 /* -------- TYPES TABLE (BEGIN) -------- */
 
 #define SWIGTYPE_p_MultiLayer swig_types[0]
-#define SWIGTYPE_p_SimulationOptions swig_types[1]
-#define SWIGTYPE_p_ThreadInfo swig_types[2]
-#define SWIGTYPE_p_Vec3T_double_t swig_types[3]
-#define SWIGTYPE_p_Vec3T_int_t swig_types[4]
-#define SWIGTYPE_p_Vec3T_std__complexT_double_t_t swig_types[5]
-#define SWIGTYPE_p_allocator_type swig_types[6]
-#define SWIGTYPE_p_char swig_types[7]
-#define SWIGTYPE_p_difference_type swig_types[8]
-#define SWIGTYPE_p_first_type swig_types[9]
-#define SWIGTYPE_p_int swig_types[10]
-#define SWIGTYPE_p_key_type swig_types[11]
-#define SWIGTYPE_p_long_long swig_types[12]
-#define SWIGTYPE_p_mapped_type swig_types[13]
-#define SWIGTYPE_p_p_PyObject swig_types[14]
-#define SWIGTYPE_p_second_type swig_types[15]
-#define SWIGTYPE_p_short swig_types[16]
-#define SWIGTYPE_p_signed_char swig_types[17]
-#define SWIGTYPE_p_size_type swig_types[18]
-#define SWIGTYPE_p_std__allocatorT_Vec3T_double_t_t swig_types[19]
-#define SWIGTYPE_p_std__allocatorT_double_t swig_types[20]
-#define SWIGTYPE_p_std__allocatorT_int_t swig_types[21]
-#define SWIGTYPE_p_std__allocatorT_std__complexT_double_t_t swig_types[22]
-#define SWIGTYPE_p_std__allocatorT_std__pairT_double_double_t_t swig_types[23]
-#define SWIGTYPE_p_std__allocatorT_std__pairT_std__string_const_double_t_t swig_types[24]
-#define SWIGTYPE_p_std__allocatorT_std__string_t swig_types[25]
-#define SWIGTYPE_p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t swig_types[26]
-#define SWIGTYPE_p_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t swig_types[27]
-#define SWIGTYPE_p_std__allocatorT_unsigned_long_t swig_types[28]
-#define SWIGTYPE_p_std__complexT_double_t swig_types[29]
-#define SWIGTYPE_p_std__invalid_argument swig_types[30]
-#define SWIGTYPE_p_std__lessT_std__string_t swig_types[31]
-#define SWIGTYPE_p_std__mapT_std__string_double_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_double_t_t_t swig_types[32]
-#define SWIGTYPE_p_std__pairT_double_double_t swig_types[33]
-#define SWIGTYPE_p_std__vectorT_Vec3T_double_t_std__allocatorT_Vec3T_double_t_t_t swig_types[34]
-#define SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t swig_types[35]
-#define SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t swig_types[36]
-#define SWIGTYPE_p_std__vectorT_std__complexT_double_t_std__allocatorT_std__complexT_double_t_t_t swig_types[37]
-#define SWIGTYPE_p_std__vectorT_std__pairT_double_double_t_std__allocatorT_std__pairT_double_double_t_t_t swig_types[38]
-#define SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t swig_types[39]
-#define SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t swig_types[40]
-#define SWIGTYPE_p_std__vectorT_std__vectorT_int_std__allocatorT_int_t_t_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t_t swig_types[41]
-#define SWIGTYPE_p_std__vectorT_unsigned_long_std__allocatorT_unsigned_long_t_t swig_types[42]
-#define SWIGTYPE_p_swig__SwigPyIterator swig_types[43]
-#define SWIGTYPE_p_unsigned_char swig_types[44]
-#define SWIGTYPE_p_unsigned_int swig_types[45]
-#define SWIGTYPE_p_unsigned_long_long swig_types[46]
-#define SWIGTYPE_p_unsigned_short swig_types[47]
-#define SWIGTYPE_p_value_type swig_types[48]
-static swig_type_info *swig_types[50];
-static swig_module_info swig_module = {swig_types, 49, 0, 0, 0, 0};
+#define SWIGTYPE_p_Rotation3DT_double_t swig_types[1]
+#define SWIGTYPE_p_SimulationOptions swig_types[2]
+#define SWIGTYPE_p_ThreadInfo swig_types[3]
+#define SWIGTYPE_p_Vec3T_double_t swig_types[4]
+#define SWIGTYPE_p_Vec3T_int_t swig_types[5]
+#define SWIGTYPE_p_Vec3T_std__complexT_double_t_t swig_types[6]
+#define SWIGTYPE_p_allocator_type swig_types[7]
+#define SWIGTYPE_p_char swig_types[8]
+#define SWIGTYPE_p_difference_type swig_types[9]
+#define SWIGTYPE_p_first_type swig_types[10]
+#define SWIGTYPE_p_int swig_types[11]
+#define SWIGTYPE_p_key_type swig_types[12]
+#define SWIGTYPE_p_long_long swig_types[13]
+#define SWIGTYPE_p_mapped_type swig_types[14]
+#define SWIGTYPE_p_p_PyObject swig_types[15]
+#define SWIGTYPE_p_second_type swig_types[16]
+#define SWIGTYPE_p_short swig_types[17]
+#define SWIGTYPE_p_signed_char swig_types[18]
+#define SWIGTYPE_p_size_type swig_types[19]
+#define SWIGTYPE_p_std__allocatorT_Vec3T_double_t_t swig_types[20]
+#define SWIGTYPE_p_std__allocatorT_double_t swig_types[21]
+#define SWIGTYPE_p_std__allocatorT_int_t swig_types[22]
+#define SWIGTYPE_p_std__allocatorT_std__complexT_double_t_t swig_types[23]
+#define SWIGTYPE_p_std__allocatorT_std__pairT_double_double_t_t swig_types[24]
+#define SWIGTYPE_p_std__allocatorT_std__pairT_std__string_const_double_t_t swig_types[25]
+#define SWIGTYPE_p_std__allocatorT_std__string_t swig_types[26]
+#define SWIGTYPE_p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t swig_types[27]
+#define SWIGTYPE_p_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t swig_types[28]
+#define SWIGTYPE_p_std__allocatorT_unsigned_long_t swig_types[29]
+#define SWIGTYPE_p_std__complexT_double_t swig_types[30]
+#define SWIGTYPE_p_std__invalid_argument swig_types[31]
+#define SWIGTYPE_p_std__lessT_std__string_t swig_types[32]
+#define SWIGTYPE_p_std__mapT_std__string_double_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_double_t_t_t swig_types[33]
+#define SWIGTYPE_p_std__pairT_double_double_t swig_types[34]
+#define SWIGTYPE_p_std__vectorT_Vec3T_double_t_std__allocatorT_Vec3T_double_t_t_t swig_types[35]
+#define SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t swig_types[36]
+#define SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t swig_types[37]
+#define SWIGTYPE_p_std__vectorT_std__complexT_double_t_std__allocatorT_std__complexT_double_t_t_t swig_types[38]
+#define SWIGTYPE_p_std__vectorT_std__pairT_double_double_t_std__allocatorT_std__pairT_double_double_t_t_t swig_types[39]
+#define SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t swig_types[40]
+#define SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t swig_types[41]
+#define SWIGTYPE_p_std__vectorT_std__vectorT_int_std__allocatorT_int_t_t_std__allocatorT_std__vectorT_int_std__allocatorT_int_t_t_t_t swig_types[42]
+#define SWIGTYPE_p_std__vectorT_unsigned_long_std__allocatorT_unsigned_long_t_t swig_types[43]
+#define SWIGTYPE_p_swig__SwigPyIterator swig_types[44]
+#define SWIGTYPE_p_unsigned_char swig_types[45]
+#define SWIGTYPE_p_unsigned_int swig_types[46]
+#define SWIGTYPE_p_unsigned_long_long swig_types[47]
+#define SWIGTYPE_p_unsigned_short swig_types[48]
+#define SWIGTYPE_p_value_type swig_types[49]
+static swig_type_info *swig_types[51];
+static swig_module_info swig_module = {swig_types, 50, 0, 0, 0, 0};
 #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
 #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
 
@@ -28380,6 +28381,7 @@ static PyMethodDef SwigMethods_proxydocs[] = {
 /* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */
 
 static swig_type_info _swigt__p_MultiLayer = {"_p_MultiLayer", "MultiLayer *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_Rotation3DT_double_t = {"_p_Rotation3DT_double_t", "RotMatrix *|Rotation3D< double > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_SimulationOptions = {"_p_SimulationOptions", "SimulationOptions *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_ThreadInfo = {"_p_ThreadInfo", "ThreadInfo *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Vec3T_double_t = {"_p_Vec3T_double_t", "std::vector< Vec3< double > >::value_type *|R3 *|Vec3< double > *", 0, 0, (void*)0, 0};
@@ -28431,6 +28433,7 @@ static swig_type_info _swigt__p_value_type = {"_p_value_type", "value_type *", 0
 
 static swig_type_info *swig_type_initial[] = {
   &_swigt__p_MultiLayer,
+  &_swigt__p_Rotation3DT_double_t,
   &_swigt__p_SimulationOptions,
   &_swigt__p_ThreadInfo,
   &_swigt__p_Vec3T_double_t,
@@ -28482,6 +28485,7 @@ static swig_type_info *swig_type_initial[] = {
 };
 
 static swig_cast_info _swigc__p_MultiLayer[] = {  {&_swigt__p_MultiLayer, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_Rotation3DT_double_t[] = {  {&_swigt__p_Rotation3DT_double_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_SimulationOptions[] = {  {&_swigt__p_SimulationOptions, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_ThreadInfo[] = {  {&_swigt__p_ThreadInfo, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_Vec3T_double_t[] = {  {&_swigt__p_Vec3T_double_t, 0, 0, 0},{0, 0, 0, 0}};
@@ -28533,6 +28537,7 @@ static swig_cast_info _swigc__p_value_type[] = {  {&_swigt__p_value_type, 0, 0,
 
 static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_MultiLayer,
+  _swigc__p_Rotation3DT_double_t,
   _swigc__p_SimulationOptions,
   _swigc__p_ThreadInfo,
   _swigc__p_Vec3T_double_t,
diff --git a/auto/Wrap/libBornAgainSample.py b/auto/Wrap/libBornAgainSample.py
index 0828947e11d2919c2bcbd6d83304d89fc9a1dde2..a734f6a1a306b0b787fe99e345ad8ec7626a802a 100644
--- a/auto/Wrap/libBornAgainSample.py
+++ b/auto/Wrap/libBornAgainSample.py
@@ -2516,7 +2516,7 @@ class Material(object):
 
     def rotatedMaterial(self, transform):
         r"""
-        rotatedMaterial(Material self, RotMatrix transform) -> Material
+        rotatedMaterial(Material self, RotMatrix const & transform) -> Material
         Material Material::rotatedMaterial(const RotMatrix &transform) const
         Material::rotatedMaterial
         """
@@ -2797,7 +2797,7 @@ class IRotation(libBornAgainBase.ICloneable, libBornAgainParam.INode):
 
     @staticmethod
     def createRotation(transform):
-        r"""createRotation(RotMatrix transform) -> IRotation"""
+        r"""createRotation(RotMatrix const & transform) -> IRotation"""
         return _libBornAgainSample.IRotation_createRotation(transform)
 
     def clone(self):
@@ -2859,7 +2859,7 @@ class IRotation(libBornAgainBase.ICloneable, libBornAgainParam.INode):
 _libBornAgainSample.IRotation_swigregister(IRotation)
 
 def IRotation_createRotation(transform):
-    r"""IRotation_createRotation(RotMatrix transform) -> IRotation"""
+    r"""IRotation_createRotation(RotMatrix const & transform) -> IRotation"""
     return _libBornAgainSample.IRotation_createRotation(transform)
 
 
@@ -10232,7 +10232,7 @@ class Lattice3D(libBornAgainParam.INode):
 
     def rotated(self, rotMatrix):
         r"""
-        rotated(Lattice3D self, RotMatrix rotMatrix) -> Lattice3D
+        rotated(Lattice3D self, RotMatrix const & rotMatrix) -> Lattice3D
         Lattice3D Lattice3D::rotated(const RotMatrix &rotMatrix) const
         Lattice3D::rotated
         Creates rotated lattice. 
diff --git a/auto/Wrap/libBornAgainSample_wrap.cpp b/auto/Wrap/libBornAgainSample_wrap.cpp
index de2c988187521118a76f7f1e96bd1b0e4c70be95..cb2f0ac958d9c997b3a1be728200d505095ffc5f 100644
--- a/auto/Wrap/libBornAgainSample_wrap.cpp
+++ b/auto/Wrap/libBornAgainSample_wrap.cpp
@@ -3183,7 +3183,7 @@ namespace Swig {
 #define SWIGTYPE_p_Pyramid3 swig_types[83]
 #define SWIGTYPE_p_Pyramid4 swig_types[84]
 #define SWIGTYPE_p_Pyramid6 swig_types[85]
-#define SWIGTYPE_p_RotMatrix swig_types[86]
+#define SWIGTYPE_p_Rotation3DT_double_t swig_types[86]
 #define SWIGTYPE_p_RotationEuler swig_types[87]
 #define SWIGTYPE_p_RotationX swig_types[88]
 #define SWIGTYPE_p_RotationY swig_types[89]
@@ -32046,7 +32046,7 @@ SWIGINTERN PyObject *_wrap_Material_rotatedMaterial(PyObject *SWIGUNUSEDPARM(sel
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Material_rotatedMaterial" "', argument " "1"" of type '" "Material const *""'"); 
   }
   arg1 = reinterpret_cast< Material * >(argp1);
-  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_RotMatrix,  0  | 0);
+  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_Rotation3DT_double_t,  0  | 0);
   if (!SWIG_IsOK(res2)) {
     SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Material_rotatedMaterial" "', argument " "2"" of type '" "RotMatrix const &""'"); 
   }
@@ -33490,7 +33490,7 @@ SWIGINTERN PyObject *_wrap_IRotation_createRotation(PyObject *SWIGUNUSEDPARM(sel
   
   if (!args) SWIG_fail;
   swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_RotMatrix,  0  | 0);
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_Rotation3DT_double_t,  0  | 0);
   if (!SWIG_IsOK(res1)) {
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IRotation_createRotation" "', argument " "1"" of type '" "RotMatrix const &""'"); 
   }
@@ -33498,7 +33498,7 @@ SWIGINTERN PyObject *_wrap_IRotation_createRotation(PyObject *SWIGUNUSEDPARM(sel
     SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IRotation_createRotation" "', argument " "1"" of type '" "RotMatrix const &""'"); 
   }
   arg1 = reinterpret_cast< RotMatrix * >(argp1);
-  result = (IRotation *)IRotation::createRotation((RotMatrix const &)*arg1);
+  result = (IRotation *)IRotation::createRotation((Rotation3D< double > const &)*arg1);
   resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_IRotation, 0 |  0 );
   return resultobj;
 fail:
@@ -33568,7 +33568,7 @@ SWIGINTERN PyObject *_wrap_IRotation_rotMatrix(PyObject *SWIGUNUSEDPARM(self), P
   }
   arg1 = reinterpret_cast< IRotation * >(argp1);
   result = ((IRotation const *)arg1)->rotMatrix();
-  resultobj = SWIG_NewPointerObj((new RotMatrix(static_cast< const RotMatrix& >(result))), SWIGTYPE_p_RotMatrix, SWIG_POINTER_OWN |  0 );
+  resultobj = SWIG_NewPointerObj((new RotMatrix(static_cast< const RotMatrix& >(result))), SWIGTYPE_p_Rotation3DT_double_t, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -33817,7 +33817,7 @@ SWIGINTERN PyObject *_wrap_IdentityRotation_rotMatrix(PyObject *SWIGUNUSEDPARM(s
   }
   arg1 = reinterpret_cast< IdentityRotation * >(argp1);
   result = ((IdentityRotation const *)arg1)->rotMatrix();
-  resultobj = SWIG_NewPointerObj((new RotMatrix(static_cast< const RotMatrix& >(result))), SWIGTYPE_p_RotMatrix, SWIG_POINTER_OWN |  0 );
+  resultobj = SWIG_NewPointerObj((new RotMatrix(static_cast< const RotMatrix& >(result))), SWIGTYPE_p_Rotation3DT_double_t, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -34091,7 +34091,7 @@ SWIGINTERN PyObject *_wrap_RotationX_rotMatrix(PyObject *SWIGUNUSEDPARM(self), P
   }
   arg1 = reinterpret_cast< RotationX * >(argp1);
   result = ((RotationX const *)arg1)->rotMatrix();
-  resultobj = SWIG_NewPointerObj((new RotMatrix(static_cast< const RotMatrix& >(result))), SWIGTYPE_p_RotMatrix, SWIG_POINTER_OWN |  0 );
+  resultobj = SWIG_NewPointerObj((new RotMatrix(static_cast< const RotMatrix& >(result))), SWIGTYPE_p_Rotation3DT_double_t, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -34342,7 +34342,7 @@ SWIGINTERN PyObject *_wrap_RotationY_rotMatrix(PyObject *SWIGUNUSEDPARM(self), P
   }
   arg1 = reinterpret_cast< RotationY * >(argp1);
   result = ((RotationY const *)arg1)->rotMatrix();
-  resultobj = SWIG_NewPointerObj((new RotMatrix(static_cast< const RotMatrix& >(result))), SWIGTYPE_p_RotMatrix, SWIG_POINTER_OWN |  0 );
+  resultobj = SWIG_NewPointerObj((new RotMatrix(static_cast< const RotMatrix& >(result))), SWIGTYPE_p_Rotation3DT_double_t, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -34593,7 +34593,7 @@ SWIGINTERN PyObject *_wrap_RotationZ_rotMatrix(PyObject *SWIGUNUSEDPARM(self), P
   }
   arg1 = reinterpret_cast< RotationZ * >(argp1);
   result = ((RotationZ const *)arg1)->rotMatrix();
-  resultobj = SWIG_NewPointerObj((new RotMatrix(static_cast< const RotMatrix& >(result))), SWIGTYPE_p_RotMatrix, SWIG_POINTER_OWN |  0 );
+  resultobj = SWIG_NewPointerObj((new RotMatrix(static_cast< const RotMatrix& >(result))), SWIGTYPE_p_Rotation3DT_double_t, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -34918,7 +34918,7 @@ SWIGINTERN PyObject *_wrap_RotationEuler_rotMatrix(PyObject *SWIGUNUSEDPARM(self
   }
   arg1 = reinterpret_cast< RotationEuler * >(argp1);
   result = ((RotationEuler const *)arg1)->rotMatrix();
-  resultobj = SWIG_NewPointerObj((new RotMatrix(static_cast< const RotMatrix& >(result))), SWIGTYPE_p_RotMatrix, SWIG_POINTER_OWN |  0 );
+  resultobj = SWIG_NewPointerObj((new RotMatrix(static_cast< const RotMatrix& >(result))), SWIGTYPE_p_Rotation3DT_double_t, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -58626,7 +58626,7 @@ SWIGINTERN PyObject *_wrap_Lattice3D_rotated(PyObject *SWIGUNUSEDPARM(self), PyO
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Lattice3D_rotated" "', argument " "1"" of type '" "Lattice3D const *""'"); 
   }
   arg1 = reinterpret_cast< Lattice3D * >(argp1);
-  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_RotMatrix,  0  | 0);
+  res2 = SWIG_ConvertPtr(swig_obj[1], &argp2, SWIGTYPE_p_Rotation3DT_double_t,  0  | 0);
   if (!SWIG_IsOK(res2)) {
     SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Lattice3D_rotated" "', argument " "2"" of type '" "RotMatrix const &""'"); 
   }
@@ -61070,7 +61070,7 @@ static PyMethodDef SwigMethods[] = {
 		"\n"
 		""},
 	 { "Material_rotatedMaterial", _wrap_Material_rotatedMaterial, METH_VARARGS, "\n"
-		"Material_rotatedMaterial(Material self, RotMatrix transform) -> Material\n"
+		"Material_rotatedMaterial(Material self, RotMatrix const & transform) -> Material\n"
 		"Material Material::rotatedMaterial(const RotMatrix &transform) const\n"
 		"Material::rotatedMaterial\n"
 		""},
@@ -61230,7 +61230,7 @@ static PyMethodDef SwigMethods[] = {
 	 { "disown_IFormFactor", _wrap_disown_IFormFactor, METH_O, NULL},
 	 { "IFormFactor_swigregister", IFormFactor_swigregister, METH_O, NULL},
 	 { "IFormFactor_swiginit", IFormFactor_swiginit, METH_VARARGS, NULL},
-	 { "IRotation_createRotation", _wrap_IRotation_createRotation, METH_O, "IRotation_createRotation(RotMatrix transform) -> IRotation"},
+	 { "IRotation_createRotation", _wrap_IRotation_createRotation, METH_O, "IRotation_createRotation(RotMatrix const & transform) -> IRotation"},
 	 { "IRotation_clone", _wrap_IRotation_clone, METH_O, "\n"
 		"IRotation_clone(IRotation self) -> IRotation\n"
 		"IRotation * IRotation::clone() const override=0\n"
@@ -65474,7 +65474,7 @@ static PyMethodDef SwigMethods[] = {
 		"Lattice3D::className\n"
 		""},
 	 { "Lattice3D_rotated", _wrap_Lattice3D_rotated, METH_VARARGS, "\n"
-		"Lattice3D_rotated(Lattice3D self, RotMatrix rotMatrix) -> Lattice3D\n"
+		"Lattice3D_rotated(Lattice3D self, RotMatrix const & rotMatrix) -> Lattice3D\n"
 		"Lattice3D Lattice3D::rotated(const RotMatrix &rotMatrix) const\n"
 		"Lattice3D::rotated\n"
 		"Creates rotated lattice. \n"
@@ -66920,7 +66920,7 @@ static swig_type_info _swigt__p_Pyramid2 = {"_p_Pyramid2", "Pyramid2 *", 0, 0, (
 static swig_type_info _swigt__p_Pyramid3 = {"_p_Pyramid3", "Pyramid3 *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Pyramid4 = {"_p_Pyramid4", "Pyramid4 *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_Pyramid6 = {"_p_Pyramid6", "Pyramid6 *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_RotMatrix = {"_p_RotMatrix", "RotMatrix *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_Rotation3DT_double_t = {"_p_Rotation3DT_double_t", "RotMatrix *|Rotation3D< double > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_RotationEuler = {"_p_RotationEuler", "RotationEuler *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_RotationX = {"_p_RotationX", "RotationX *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_RotationY = {"_p_RotationY", "RotationY *", 0, 0, (void*)0, 0};
@@ -67081,7 +67081,7 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_Pyramid3,
   &_swigt__p_Pyramid4,
   &_swigt__p_Pyramid6,
-  &_swigt__p_RotMatrix,
+  &_swigt__p_Rotation3DT_double_t,
   &_swigt__p_RotationEuler,
   &_swigt__p_RotationX,
   &_swigt__p_RotationY,
@@ -67242,7 +67242,7 @@ static swig_cast_info _swigc__p_Pyramid2[] = {  {&_swigt__p_Pyramid2, 0, 0, 0},{
 static swig_cast_info _swigc__p_Pyramid3[] = {  {&_swigt__p_Pyramid3, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_Pyramid4[] = {  {&_swigt__p_Pyramid4, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_Pyramid6[] = {  {&_swigt__p_Pyramid6, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_RotMatrix[] = {  {&_swigt__p_RotMatrix, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_Rotation3DT_double_t[] = {  {&_swigt__p_Rotation3DT_double_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_RotationEuler[] = {  {&_swigt__p_RotationEuler, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_RotationX[] = {  {&_swigt__p_RotationX, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_RotationY[] = {  {&_swigt__p_RotationY, 0, 0, 0},{0, 0, 0, 0}};
@@ -67403,7 +67403,7 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_Pyramid3,
   _swigc__p_Pyramid4,
   _swigc__p_Pyramid6,
-  _swigc__p_RotMatrix,
+  _swigc__p_Rotation3DT_double_t,
   _swigc__p_RotationEuler,
   _swigc__p_RotationX,
   _swigc__p_RotationY,
diff --git a/cmake/BornAgain/Dependences.cmake b/cmake/BornAgain/Dependences.cmake
index 207667f3b8c2bca18b25588fa1e84c4265037d2d..2b1640f895b9314091224aef780cfce2329f0fd5 100644
--- a/cmake/BornAgain/Dependences.cmake
+++ b/cmake/BornAgain/Dependences.cmake
@@ -4,7 +4,7 @@ if(WIN32)
     set(CMAKE_FIND_LIBRARY_SUFFIXES .dll.a .lib)
 endif()
 
-find_package(LibHeinz 0.1.3 REQUIRED CONFIG)
+find_package(LibHeinz 0.2.0 REQUIRED CONFIG)
 message(STATUS "LibHeinz: found=${LibHeinz_FOUND}, include_dirs=${LibHeinz_INCLUDE_DIR}, "
     "version=${LibHeinz_VERSION}")