From 6b06b0fdf4d03e5697030e6868939cb941e69805 Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (laptop)" <j.wuttke@fz-juelich.de>
Date: Wed, 27 Mar 2013 21:43:09 +0100
Subject: [PATCH] Transform3D splitted into interface class ITransform3D and
 specific implementation RotationZ_3D. Raw material for all other transforms
 temporarily moved to UnusedTransform3D.h. Status: Core compiles,
 FunctionalTests not yet.

---
 App/src/StandardSamples.cpp                   |   1 -
 App/src/TestDetectorResolution.cpp            |   1 -
 App/src/TestFittingModule3.cpp                |   1 -
 Core/Algorithms/inc/StrategyBuilder.h         |  22 +-
 .../src/LayerDecoratorDWBASimulation.cpp      |   4 +-
 Core/Algorithms/src/StrategyBuilder.cpp       |  60 ++--
 Core/Core.pro                                 |   5 +-
 .../inc/FormFactorDecoratorTransformation.h   |  14 +-
 Core/Geometry/inc/BasicVector3D.h             |   6 +-
 Core/Geometry/inc/ITransform3D.h              |  49 +++
 Core/Geometry/inc/Rotate3D.h                  |  56 ++++
 Core/Geometry/inc/Transform3D.h               | 280 ------------------
 Core/Geometry/inc/UnusedTransform3D.h         | 207 +++++++++++++
 Core/Geometry/src/BasicVector3D.cpp           |  68 +----
 Core/Geometry/src/Transform3D.cpp             | 129 --------
 Core/Samples/inc/DiffuseParticleInfo.h        |  12 +-
 Core/Samples/inc/IClusteredParticles.h        |   1 -
 Core/Samples/inc/ParticleDecoration.h         |   4 +-
 Core/Samples/inc/ParticleInfo.h               |  16 +-
 Core/Samples/inc/PositionParticleInfo.h       |   4 +-
 Core/Samples/src/Crystal.cpp                  |   2 +-
 Core/Samples/src/DiffuseParticleInfo.cpp      |  26 --
 Core/Samples/src/ParticleDecoration.cpp       |  49 +--
 Core/Samples/src/ParticleInfo.cpp             |  17 +-
 Core/Samples/src/PositionParticleInfo.cpp     |  16 +-
 .../TestCore/IsGISAXS01/IsGISAXS01.cpp        |   1 -
 .../TestCore/IsGISAXS09/IsGISAXS09.cpp        |  36 ++-
 Tests/UnitTests/TestCore/KVectorTest.h        |  29 +-
 28 files changed, 483 insertions(+), 633 deletions(-)
 create mode 100644 Core/Geometry/inc/ITransform3D.h
 create mode 100644 Core/Geometry/inc/Rotate3D.h
 delete mode 100644 Core/Geometry/inc/Transform3D.h
 create mode 100644 Core/Geometry/inc/UnusedTransform3D.h
 delete mode 100644 Core/Samples/src/DiffuseParticleInfo.cpp

diff --git a/App/src/StandardSamples.cpp b/App/src/StandardSamples.cpp
index 5a3b3273f81..33ed02da743 100644
--- a/App/src/StandardSamples.cpp
+++ b/App/src/StandardSamples.cpp
@@ -19,7 +19,6 @@
 #include "Units.h"
 #include "Particle.h"
 #include "FormFactors.h"
-#include "Transform3D.h"
 #include "ParticleDecoration.h"
 #include "InterferenceFunctionNone.h"
 #include "LayerDecorator.h"
diff --git a/App/src/TestDetectorResolution.cpp b/App/src/TestDetectorResolution.cpp
index 8ed5058625f..6484aece7ab 100644
--- a/App/src/TestDetectorResolution.cpp
+++ b/App/src/TestDetectorResolution.cpp
@@ -22,7 +22,6 @@
 #include "MultiLayer.h"
 #include "MaterialManager.h"
 #include "LayerDecorator.h"
-#include "ParticleDecoration.h"
 #include "MathFunctions.h"
 #include "ResolutionFunction2DSimple.h"
 
diff --git a/App/src/TestFittingModule3.cpp b/App/src/TestFittingModule3.cpp
index 3aca3420808..eda97ffa555 100644
--- a/App/src/TestFittingModule3.cpp
+++ b/App/src/TestFittingModule3.cpp
@@ -31,7 +31,6 @@
 #include "MultiLayer.h"
 #include "OutputDataFunctions.h"
 #include "Particle.h"
-#include "ParticleDecoration.h"
 #include "ResolutionFunction2DSimple.h"
 #include "Units.h"
 
diff --git a/Core/Algorithms/inc/StrategyBuilder.h b/Core/Algorithms/inc/StrategyBuilder.h
index 357e36471ae..08eff44eda6 100644
--- a/Core/Algorithms/inc/StrategyBuilder.h
+++ b/Core/Algorithms/inc/StrategyBuilder.h
@@ -35,12 +35,18 @@ class IFormFactor;
 class LayerDecoratorStrategyBuilder
 {
  public:
-    LayerDecoratorStrategyBuilder(const LayerDecorator& decorated_layer,
-            const Simulation& simulation, const SimulationParameters& sim_params);
+    /* out-of-place implementation required due to LayerDecorator */
+    LayerDecoratorStrategyBuilder(
+        const LayerDecorator& decorated_layer,
+        const Simulation& simulation,
+        const SimulationParameters& sim_params);
+
+    /* out-of-place implementation required due to LayerDecorator */
     virtual ~LayerDecoratorStrategyBuilder();
 
     //! Sets R and T coefficient map for DWBA simulation
-    void setReflectionTransmissionFunction(const IDoubleToPairOfComplexMap& rt_map);
+    void setReflectionTransmissionFunction(
+        const IDoubleToPairOfComplexMap& rt_map);
 
     //! Creates a strategy object which is able to calculate the scattering for fixed k_f
     virtual IInterferenceFunctionStrategy *createStrategy();
@@ -58,8 +64,10 @@ class LayerDecoratorStrategyBuilder
     //! retrieve wavelength from simulation
     double getWavelength();
     //! Creates formfactor info for single particle
-    FormFactorInfo *createFormFactorInfo(const ParticleInfo *p_particle_info,
-            complex_t n_ambient_refractive_index, complex_t factor) const;
+    FormFactorInfo *createFormFactorInfo(
+        const ParticleInfo *p_particle_info,
+        complex_t n_ambient_refractive_index,
+        complex_t factor) const;
 
     SafePointerVector<FormFactorInfo> m_ff_infos;
     SafePointerVector<IInterferenceFunction> m_ifs;
@@ -68,8 +76,10 @@ class LayerDecoratorStrategyBuilder
 class FormFactorInfo : public ICloneable
 {
  public:
-    FormFactorInfo();
+    FormFactorInfo()
+        : mp_ff(0), m_pos_x(0.0), m_pos_y(0.0), m_abundance(0.0) {}
     ~FormFactorInfo();
+    /* out-of-place implementation required due to IFormFactor */
     virtual FormFactorInfo *clone() const;
     IFormFactor *mp_ff;
     double m_pos_x, m_pos_y;
diff --git a/Core/Algorithms/src/LayerDecoratorDWBASimulation.cpp b/Core/Algorithms/src/LayerDecoratorDWBASimulation.cpp
index 18eaa02da43..7dc39d3066c 100644
--- a/Core/Algorithms/src/LayerDecoratorDWBASimulation.cpp
+++ b/Core/Algorithms/src/LayerDecoratorDWBASimulation.cpp
@@ -66,7 +66,7 @@ std::vector<IFormFactor *> LayerDecoratorDWBASimulation::createDWBAFormFactors()
     for (size_t particle_index=0; particle_index<number_of_particles; ++particle_index) {
         Particle *p_particle = p_decoration->getParticleInfo(particle_index)->getParticle()->clone();
         double depth = p_decoration->getParticleInfo(particle_index)->getDepth();
-        const Geometry::Transform3D *transform = p_decoration->getParticleInfo(particle_index)->getTransform3D();
+        const Geometry::ITransform3D *transform = p_decoration->getParticleInfo(particle_index)->getITransform3D();
 
         p_particle->setAmbientRefractiveIndex(n_layer);
         complex_t wavevector_scattering_factor = M_PI/getWaveLength()/getWaveLength();
@@ -74,7 +74,7 @@ std::vector<IFormFactor *> LayerDecoratorDWBASimulation::createDWBAFormFactors()
         IFormFactor *ff_particle = p_particle->createFormFactor();
         IFormFactor  *ff_transformed(0);
         if(transform) {
-            ff_transformed = new FormFactorDecoratorTransformation(ff_particle, new Geometry::Transform3D(*transform));
+            ff_transformed = new FormFactorDecoratorTransformation(ff_particle, new Geometry::ITransform3D(*transform));
         } else{
             ff_transformed = ff_particle;
         }
diff --git a/Core/Algorithms/src/StrategyBuilder.cpp b/Core/Algorithms/src/StrategyBuilder.cpp
index f7537b4413a..c96e90e940e 100644
--- a/Core/Algorithms/src/StrategyBuilder.cpp
+++ b/Core/Algorithms/src/StrategyBuilder.cpp
@@ -28,10 +28,10 @@
 LayerDecoratorStrategyBuilder::LayerDecoratorStrategyBuilder(
         const LayerDecorator& decorated_layer, const Simulation& simulation,
         const SimulationParameters& sim_params)
-: mp_layer_decorator(decorated_layer.clone())
-, mp_simulation(simulation.clone())
-, m_sim_params(sim_params)
-, mp_RT_function(0)
+  : mp_layer_decorator(decorated_layer.clone())
+  , mp_simulation(simulation.clone())
+  , m_sim_params(sim_params)
+  , mp_RT_function(0)
 {
 }
 
@@ -42,6 +42,7 @@ LayerDecoratorStrategyBuilder::~LayerDecoratorStrategyBuilder()
     delete mp_RT_function;
 }
 
+
 void LayerDecoratorStrategyBuilder::setReflectionTransmissionFunction(
         const IDoubleToPairOfComplexMap& rt_map)
 {
@@ -76,7 +77,8 @@ IInterferenceFunctionStrategy* LayerDecoratorStrategyBuilder::createStrategy()
             throw Exceptions::ClassInitializationException(
                     "SSCA requires a strictly positive coupling value");
         }
-        p_result = new SizeSpacingCorrelationApproximationStrategy(m_sim_params, kappa);
+        p_result = new SizeSpacingCorrelationApproximationStrategy(
+            m_sim_params, kappa);
         break;
     }
     case SimulationParameters::ISGISAXSMOR:
@@ -102,11 +104,16 @@ void LayerDecoratorStrategyBuilder::collectFormFactorInfos()
     double wavelength = getWavelength();
     complex_t wavevector_scattering_factor = M_PI/wavelength/wavelength;
     size_t number_of_particles = p_decoration->getNumberOfParticles();
-    for (size_t particle_index=0; particle_index<number_of_particles; ++particle_index) {
-        const ParticleInfo *p_particle_info = p_decoration->getParticleInfo(particle_index);
-        FormFactorInfo *p_ff_info = createFormFactorInfo(p_particle_info, n_layer,
-                wavevector_scattering_factor);
-        p_ff_info->m_abundance = p_decoration->getAbundanceFractionOfParticle(particle_index);
+    for (size_t particle_index =
+             0; particle_index<number_of_particles; ++particle_index) {
+        const ParticleInfo *p_particle_info =
+            p_decoration->getParticleInfo(particle_index);
+        FormFactorInfo *p_ff_info =
+            createFormFactorInfo(p_particle_info,
+                                 n_layer,
+                                 wavevector_scattering_factor);
+        p_ff_info->m_abundance =
+            p_decoration->getAbundanceFractionOfParticle(particle_index);
         m_ff_infos.push_back(p_ff_info);
     }
     return;
@@ -129,12 +136,14 @@ double LayerDecoratorStrategyBuilder::getWavelength()
 }
 
 FormFactorInfo *LayerDecoratorStrategyBuilder::createFormFactorInfo(
-        const ParticleInfo *p_particle_info, complex_t n_ambient_refractive_index,
+        const ParticleInfo *p_particle_info,
+        complex_t n_ambient_refractive_index,
         complex_t factor) const
 {
     FormFactorInfo *p_result = new FormFactorInfo;
     Particle *p_particle_clone = p_particle_info->getParticle()->clone();
-    const Geometry::Transform3D *p_transform = p_particle_info->getTransform3D();
+    const Geometry::ITransform3D *p_transform =
+        p_particle_info->getITransform3D();
 
     // formfactor
     p_particle_clone->setAmbientRefractiveIndex(n_ambient_refractive_index);
@@ -142,7 +151,8 @@ FormFactorInfo *LayerDecoratorStrategyBuilder::createFormFactorInfo(
     delete p_particle_clone;
     IFormFactor *ff_transformed(0);
     if(p_transform) {
-        ff_transformed = new FormFactorDecoratorTransformation(ff_particle, new Geometry::Transform3D(*p_transform));
+        ff_transformed = new FormFactorDecoratorTransformation(
+            ff_particle, new Geometry::ITransform3D(*p_transform));
     } else{
         ff_transformed = ff_particle;
     }
@@ -159,7 +169,8 @@ FormFactorInfo *LayerDecoratorStrategyBuilder::createFormFactorInfo(
                     "R and T coefficients are necessary for DWBA");
         }
         double depth = p_particle_info->getDepth();
-        FormFactorDWBAConstZ *p_dwba_ff = new FormFactorDWBAConstZ(ff_transformed, depth);
+        FormFactorDWBAConstZ *p_dwba_ff =
+            new FormFactorDWBAConstZ(ff_transformed, depth);
         p_dwba_ff->setReflectionTransmissionFunction(*mp_RT_function);
         p_ff_framework = p_dwba_ff;
         break;
@@ -167,10 +178,12 @@ FormFactorInfo *LayerDecoratorStrategyBuilder::createFormFactorInfo(
     default:
         throw Exceptions::RuntimeErrorException("Framework must be BA or DWBA");
     }
-    FormFactorDecoratorFactor *p_ff = new FormFactorDecoratorFactor(p_ff_framework, factor);
+    FormFactorDecoratorFactor *p_ff =
+        new FormFactorDecoratorFactor(p_ff_framework, factor);
     p_result->mp_ff = p_ff;
     // Other info (position and abundance
-    const PositionParticleInfo *p_pos_particle_info = dynamic_cast<const PositionParticleInfo *>(p_particle_info);
+    const PositionParticleInfo *p_pos_particle_info =
+        dynamic_cast<const PositionParticleInfo *>(p_particle_info);
     if (p_pos_particle_info) {
         kvector_t position = p_pos_particle_info->getPosition();
         p_result->m_pos_x = position.x();
@@ -180,18 +193,11 @@ FormFactorInfo *LayerDecoratorStrategyBuilder::createFormFactorInfo(
     return p_result;
 }
 
-FormFactorInfo::FormFactorInfo()
-: mp_ff(0)
-, m_pos_x(0.0)
-, m_pos_y(0.0)
-, m_abundance(0.0)
-{
-}
+// =============================================================================
+// Implementation of FormFactorInfo
+// =============================================================================
 
-FormFactorInfo::~FormFactorInfo()
-{
-    delete mp_ff;
-}
+FormFactorInfo::~FormFactorInfo() { delete mp_ff; }
 
 FormFactorInfo* FormFactorInfo::clone() const
 {
diff --git a/Core/Core.pro b/Core/Core.pro
index b2aa4f54be8..3e4303d6b13 100644
--- a/Core/Core.pro
+++ b/Core/Core.pro
@@ -13,7 +13,6 @@ QMAKE_EXTENSION_SHLIB = so # making standard *.so extension
 # -----------------------------------------------------------------------------
 SOURCES += \
     Geometry/src/BasicVector3D.cpp \
-    Geometry/src/Transform3D.cpp \
     \
     Tools/src/AxisBin.cpp \
     Tools/src/AxisDouble.cpp \
@@ -91,7 +90,6 @@ SOURCES += \
     FormFactors/src/IFormFactorBorn.cpp \
     \
     Samples/src/Crystal.cpp \
-    Samples/src/DiffuseParticleInfo.cpp \
     Samples/src/ICompositeIterator.cpp \
     Samples/src/ICompositeSample.cpp \
     Samples/src/ISample.cpp \
@@ -129,7 +127,8 @@ SOURCES += \
 
 HEADERS += \
     Geometry/inc/BasicVector3D.h \
-    Geometry/inc/Transform3D.h \
+    Geometry/inc/ITransform3D.h \
+    Geometry/inc/Rotate3D.h \
     \
     Tools/inc/AxisBin.h \
     Tools/inc/AxisDouble.h \
diff --git a/Core/FormFactors/inc/FormFactorDecoratorTransformation.h b/Core/FormFactors/inc/FormFactorDecoratorTransformation.h
index cd40da484d3..a0636146dc4 100644
--- a/Core/FormFactors/inc/FormFactorDecoratorTransformation.h
+++ b/Core/FormFactors/inc/FormFactorDecoratorTransformation.h
@@ -17,7 +17,7 @@
 #define FORMFACTORDECORATORTRANSFORMATION_H
 
 #include "IFormFactorDecorator.h"
-#include "Transform3D.h"
+#include "ITransform3D.h"
 
 //! Equip a Formfactor with a rotation.
 
@@ -26,14 +26,14 @@ class FormFactorDecoratorTransformation : public IFormFactorDecorator
  public:
     //! Constructor, setting formfactor and rotation.
     FormFactorDecoratorTransformation(
-        IFormFactor *p_form_factor, Geometry::Transform3D *transform)
+        IFormFactor *p_form_factor, Geometry::ITransform3D *transform)
         : IFormFactorDecorator(p_form_factor)
         , mp_transform(transform)
         , mp_inverse_transform(0)
     {
         setName("FormFactorDecoratorTransformation");
         mp_inverse_transform =
-            new Geometry::Transform3D(mp_transform->inverse());
+            new Geometry::ITransform3D(mp_transform->inverse());
     }
 
     virtual ~FormFactorDecoratorTransformation()
@@ -44,8 +44,8 @@ class FormFactorDecoratorTransformation : public IFormFactorDecorator
 
     virtual FormFactorDecoratorTransformation *clone() const
     {
-        Geometry::Transform3D *p_new_transform =
-            new Geometry::Transform3D(*mp_transform);
+        Geometry::ITransform3D *p_new_transform =
+            new Geometry::ITransform3D(*mp_transform);
         return new FormFactorDecoratorTransformation(
             mp_form_factor->clone(), p_new_transform);
     }
@@ -59,8 +59,8 @@ class FormFactorDecoratorTransformation : public IFormFactorDecorator
     { return mp_form_factor->getNumberOfStochasticParameters(); }
 
  protected:
-    Geometry::Transform3D *mp_transform;
-    Geometry::Transform3D *mp_inverse_transform;
+    Geometry::ITransform3D *mp_transform;
+    Geometry::ITransform3D *mp_inverse_transform;
 };
 
 
diff --git a/Core/Geometry/inc/BasicVector3D.h b/Core/Geometry/inc/BasicVector3D.h
index d3c0217f609..0006c29f8fa 100644
--- a/Core/Geometry/inc/BasicVector3D.h
+++ b/Core/Geometry/inc/BasicVector3D.h
@@ -7,9 +7,9 @@
 //!
 //! Forked from CLHEP/Geometry by E. Chernyaev <Evgueni.Tcherniaev@cern.ch>,
 //! then reduced to rotations and mostly rewritten; point and vector semantics
-//! is no longer represented by class type; transforms are now methods of
-//! Transform3D and not of BasicVector3D; child classes allow for accelerated
-//! rotations around coordinate axes.
+//! is no longer represented by class type; transforms are no longer methods of
+//! BasicVector3D; there is a new interface ITransform3D, and all transforms
+//! are implemented in child classes therof.
 //!
 //! @homepage   http://apps.jcns.fz-juelich.de/BornAgain
 //! @license    GNU General Public License v3 or higher (see COPYING)
diff --git a/Core/Geometry/inc/ITransform3D.h b/Core/Geometry/inc/ITransform3D.h
new file mode 100644
index 00000000000..6e7f00a4e06
--- /dev/null
+++ b/Core/Geometry/inc/ITransform3D.h
@@ -0,0 +1,49 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file       Geometry/inc/ITransform3D.h
+//! @brief      Defines interface class ITransform3D.
+//!
+//! @homepage   http://apps.jcns.fz-juelich.de/BornAgain
+//! @license    GNU General Public License v3 or higher (see COPYING)
+//! @copyright  Forschungszentrum Jülich GmbH 2013
+//! @authors    C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#ifndef GEOMETRY_ITRANSFROM3D_H
+#define GEOMETRY_ITRANSFROM3D_H
+
+#include "BasicVector3D.h"
+
+namespace Geometry {
+
+//! Interface to vector transforms in three dimensions.
+
+class ITransform3D {
+ public:
+    //! Default constructor, sets the identity transformation.
+    ITransform3D() {}
+
+    virtual ~ITransform3D() {}
+
+    //! Returns the inverse transformation.
+    virtual ITransform3D inverse() const
+    { return *this; }
+    
+    //! Return transformed vector _v_.
+    virtual BasicVector3D<double>
+        transformed(const BasicVector3D<double>& v) const
+    { return v; }
+
+    //! Return transformed vector _v_.
+    virtual BasicVector3D<complex_t>
+        transformed(const BasicVector3D<complex_t>& v) const
+    { return v; }
+
+};
+ 
+}  // namespace Geometry
+
+#endif /* GEOMETRY_ITRANSFROM3D_H */
diff --git a/Core/Geometry/inc/Rotate3D.h b/Core/Geometry/inc/Rotate3D.h
new file mode 100644
index 00000000000..82e0dd48551
--- /dev/null
+++ b/Core/Geometry/inc/Rotate3D.h
@@ -0,0 +1,56 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file       Geometry/inc/Rotate3D.h
+//! @brief      Defines and implements class Rotate3D.
+//!
+//! @homepage   http://apps.jcns.fz-juelich.de/BornAgain
+//! @license    GNU General Public License v3 or higher (see COPYING)
+//! @copyright  Forschungszentrum Jülich GmbH 2013
+//! @authors    C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#ifndef GEOMETRY_ROTATE3D_H
+#define GEOMETRY_ROTATE3D_H
+
+#include "ITransform3D.h"
+
+namespace Geometry {
+
+//! Rotation around z axis.
+
+class RotateZ_3D : public ITransform3D {
+ public:
+    //! Constructs a rotation by angle _a_.
+
+    //! QUESTION: How can we construct identity transform for a=0?
+    //!
+    RotateZ_3D(double a)
+        : m_ca( std::cos(a) ), m_sa( std::sin(a) ) {}
+
+    //! Return inverse transform.
+    RotateZ_3D inverse() const
+    {
+        RotateZ_3D ret;
+        ret.sa = - ret.sa;
+        return ret;
+    }
+
+    //! Return rotated vector _v_.
+    template<class T>
+    BasicVector3D<T> transformed(const BasicVector3D<T>& v) const
+    {
+        return BasicVector3D<T>( ca*v.x - sa*v.y,
+                                 sa*v.x + ca*vx,
+                                 v.z              );
+    }
+
+ private:
+    double m_ca, m_sa;
+}
+
+}  // namespace Geometry
+
+#endif /* GEOMETRY_ROTATE3D_H */
diff --git a/Core/Geometry/inc/Transform3D.h b/Core/Geometry/inc/Transform3D.h
deleted file mode 100644
index e96c3d441d7..00000000000
--- a/Core/Geometry/inc/Transform3D.h
+++ /dev/null
@@ -1,280 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file       Geometry/inc/Transform3D.h
-//! @brief      Defines class Transform3D.
-//!
-//! For historic note, see BasicVector3D.h.
-//!
-//! @homepage   http://apps.jcns.fz-juelich.de/BornAgain
-//! @license    GNU General Public License v3 or higher (see COPYING)
-//! @copyright  Forschungszentrum Jülich GmbH 2013
-//! @authors    C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke
-//
-// ************************************************************************** //
-
-#ifndef GEOMETRY_TRANSFROM3D_H
-#define GEOMETRY_TRANSFROM3D_H
-
-#include <cmath>
-#include "BasicVector3D.h"
-
-// remnants of CLHEP:
-#define Point3D  BasicVector3D
-
-namespace Geometry {
-
-// ************************************************************************** //
-//  Main class Transform3D
-// ************************************************************************** //
-
-//! Rotate vectors in three dimensions.
-
-//! Uses a 3x3 double-precision transform matrix to store rotations
-//! (and potentially rescalings and inversions).
-//!
-//! Rotations:
-//!   Rotate3D(m)              - rotation given by CLHEP::HepRotation "m";
-//!   Rotate3D(ang,v)          - rotation through the angle "ang" around
-//!                              vector "v";
-//!   Rotate3D(ang,p1,p2)      - rotation through the angle "ang"
-//!                              counterclockwise around the axis given by
-//!                              two points p1->p2;
-//!   RotateX3D(ang)           - rotation around X-axis;
-//!   RotateY3D(ang)           - rotation around Y-axis;
-//!   RotateZ3D(ang)           - rotation around Z-axis;
-//!
-//! Inverse transformation:
-//!   m.inverse() or           - returns inverse transformation;
-//!
-//! @author <Evgueni.Tcherniaev@cern.ch> 1996-2003
-//!
-class Transform3D {
- protected:
-    // 3x3  Transformation Matrix
-    double xx_, xy_, xz_,     
-           yx_, yy_, yz_,
-           zx_, zy_, zz_;
-
-    //! Protected constructor.
-    Transform3D(double XX, double XY, double XZ,
-                double YX, double YY, double YZ,
-                double ZX, double ZY, double ZZ)
-        : xx_(XX), xy_(XY), xz_(XZ),
-          yx_(YX), yy_(YY), yz_(YZ),
-          zx_(ZX), zy_(ZY), zz_(ZZ) {}
-
-    //! Sets transformation matrix.
-    void setTransform(double XX, double XY, double XZ,
-                      double YX, double YY, double YZ,
-                      double ZX, double ZY, double ZZ) {
-        xx_ = XX; xy_ = XY; xz_ = XZ;
-        yx_ = YX; yy_ = YY; yz_ = YZ;
-        zx_ = ZX; zy_ = ZY; zz_ = ZZ;
-    }
-
- public:
-    //! Helper class for implemention of C-style subscripting r[i][j] 
-    class Transform3D_row {
-      public:
-        inline Transform3D_row(const Transform3D&, int);
-        inline double operator [] (int) const;
-      private:
-        const Transform3D& rr;
-        int ii;
-    };
-
-    //! Default constructor - sets the Identity transformation.
-    Transform3D()
-        : xx_(1), xy_(0), xz_(0),
-          yx_(0), yy_(1), yz_(0),
-          zx_(0), zy_(0), zz_(1) {}
-  
-    //! Copy constructor.
-    Transform3D(const Transform3D& m)
-        : xx_(m.xx_), xy_(m.xy_), xz_(m.xz_),
-          yx_(m.yx_), yy_(m.yy_), yz_(m.yz_),
-          zx_(m.zx_), zy_(m.zy_), zz_(m.zz_) {}
-
-    //! Destructor.
-    //! Virtual for now as some persistency mechanism needs that,
-    //! in future releases this might go away again.
-    virtual ~Transform3D() {}
-
-    //! Returns object of the helper class for C-style subscripting r[i][j]
-    inline const Transform3D_row operator [] (int) const; 
-
-    //! Fortran-style subscripting: returns (i,j) element of the matrix.
-    double operator () (int, int) const;
-
-    //! Returns xx-element of the transformation matrix.
-    double xx() const { return xx_; }
-    //! Returns xy-element of the transformation matrix.
-    double xy() const { return xy_; }
-    //! Returns xz-element of the transformation matrix.
-    double xz() const { return xz_; }
-    //! Returns yx-element of the transformation matrix.
-    double yx() const { return yx_; }
-    //! Returns yy-element of the transformation matrix.
-    double yy() const { return yy_; }
-    //! Returns yz-element of the transformation matrix.
-    double yz() const { return yz_; }
-    //! Returns zx-element of the transformation matrix.
-    double zx() const { return zx_; }
-    //! Returns zy-element of the transformation matrix.
-    double zy() const { return zy_; }
-    //! Returns zz-element of the transformation matrix.
-    double zz() const { return zz_; }
-    
-    //! Assignment.
-    Transform3D& operator=(const Transform3D&m) {
-        xx_= m.xx_; xy_= m.xy_; xz_= m.xz_;
-        yx_= m.yx_; yy_= m.yy_; yz_= m.yz_;
-        zx_= m.zx_; zy_= m.zy_; zz_= m.zz_;
-        return *this;
-    }
-
-    //! Sets the Identity transformation.
-    void setIdentity() { 
-        xy_= xz_= yx_= yz_= zx_= zy_= 0; xx_= yy_= zz_= 1;
-    }
-    
-    //! Returns the inverse transformation.
-    Transform3D inverse() const;
-    
-    //! Concatenation of transforms. Read efficiency warning!
-    //!
-    //! Warning:
-    //! Do not use this function for one-time computations:
-    //! Transform3D*Transform3D is roughly 3 times slower than
-    //! Transform3D*Vector3D. Therefore prefer v2 = m3*(m2*(m1*v1))
-    //! over v2 = m3*m2*m1*v1. (The latter expression is written
-    //! without parentheses because operator* is left associative).
-    //!
-    //! Use of Transform3D*Transform3D is reasonable when the
-    //! resulting transformation will be used several times.
-    //!
-    Transform3D operator*(const Transform3D& b) const;
-
-    //! Return transformed (typically: rotated) vector _v_.
-    template<class T>
-    BasicVector3D<T> transformed(const BasicVector3D<T>& v) const
-    {
-        return BasicVector3D<T>(xx()*v.x() + xy()*v.y() + xz()*v.z(),
-                                yx()*v.x() + yy()*v.y() + yz()*v.z(),
-                                zx()*v.x() + zy()*v.y() + zz()*v.z());
-    }
-
-};
-
-// ************************************************************************** //
-//   Rotations
-// ************************************************************************** //
-
-//! A rotation of 3D geometrical objects (points, vectors, normals).
-
-//! This class provides additional constructors for Transform3D
-//! and should not be used as a separate class.
-//! 
-//! Example of use:
-//! @code
-//!   Transform3D m;
-//!   m = Rotate3D(30.*deg, HepVector3D(1.,1.,1.));
-//! @endcode
-//!
-//! @author <Evgueni.Tcherniaev@cern.ch> 1996-2003
-//!
-class Rotate3D : public Transform3D {
- public:
-    //! Default constructor: sets the Identity transformation.
-    Rotate3D() : Transform3D() {}
-    
-    //! Construct rotation by angle a around axis p1->p2.
-    Rotate3D(double a,
-	     const Point3D<double>& p1,
-	     const Point3D<double>& p2);
-    
-    //! Constructor from angle and axis.
-
-    //! @param a angle of rotation
-    //! @param v axis of rotation
-    inline Rotate3D(double a, const BasicVector3D<double>& v)
-    //  TODO(C++11): simplify using delegating constructor
-    { *this = Rotate3D(a, Point3D<double>(0., 0., 0.),
-                       Point3D<double>(v.x(),v.y(),v.z()) ); }
-};
-
-//! A rotation of 3D geometrical objects around the x-axis.
-
-//! Should not be instantiated: see Rotate3D for example of use.
-//!
-//! @author <Evgueni.Tcherniaev@cern.ch>
-//!
-class RotateX3D : public Rotate3D {
- public:
-    //! Default constructor: sets the Identity transformation.
-    RotateX3D() : Rotate3D() {}
-    
-    //! Constructs a rotation around x-axis by angle a.
-    RotateX3D(double a) {
-        double cosa = std::cos(a), sina = std::sin(a); 
-        setTransform(1.,0.,0., 0.,cosa,-sina, 0.,sina,cosa);
-    }
-};
-
-//! A rotation of 3D geometrical objects around the y-axis.
-
-//! Should not be instantiated: see Rotate3D for example of use.
-//!
-//! @author <Evgueni.Tcherniaev@cern.ch>
-//!
-class RotateY3D : public Rotate3D {
- public:
-    //! Default constructor: sets the Identity transformation.
-    RotateY3D() : Rotate3D() {}
-    
-    //! Constructs a rotation around y-axis by angle a.
-    RotateY3D(double a) {
-        double cosa = std::cos(a), sina = std::sin(a); 
-        setTransform(cosa,0.,sina, 0.,1.,0., -sina,0.,cosa);
-    }
-};
-
-//! A rotation of 3D geometrical objects around the z-axis.
-
-//! Should not be instantiated: see Rotate3D for example of use.
-//!
-//! @author <Evgueni.Tcherniaev@cern.ch>
-//!
-class RotateZ3D : public Rotate3D {
- public:
-    //! Default constructor: sets the Identity transformation.
-    RotateZ3D() : Rotate3D() {}
-    
-    //! Constructs a rotation around z-axis by angle a.
-    RotateZ3D(double a) {
-        double cosa = std::cos(a), sina = std::sin(a); 
-        setTransform(cosa,-sina,0., sina,cosa,0., 0.,0.,1.);
-    }
-};
-
-// ************************************************************************** //
-//  Inlines that involve both Transform3D and Transform3D_row
-// ************************************************************************** //
-
-inline
-Transform3D::Transform3D_row::Transform3D_row(const Transform3D&  r, int i)
-    : rr(r), ii(i) {}
-
-inline
-double Transform3D::Transform3D_row::operator[](int jj) const
-    { return rr(ii,jj); }
-
-inline
-const Transform3D::Transform3D_row Transform3D::operator[](int i) const
-    { return Transform3D_row(*this, i); }
-
-}  // namespace Geometry
-
-#endif /* GEOMETRY_TRANSFROM3D_H */
diff --git a/Core/Geometry/inc/UnusedTransform3D.h b/Core/Geometry/inc/UnusedTransform3D.h
new file mode 100644
index 00000000000..46efa227ac6
--- /dev/null
+++ b/Core/Geometry/inc/UnusedTransform3D.h
@@ -0,0 +1,207 @@
+// ************************************************************************** //
+//
+//  BornAgain: simulate and fit scattering at grazing incidence
+//
+//! @file       Geometry/src/Transform3D.cpp
+//! @brief      Implements class Transform3D.
+//!
+//! For historic note, see BasicVector3D.h.
+//!
+//! @homepage   http://apps.jcns.fz-juelich.de/BornAgain
+//! @license    GNU General Public License v3 or higher (see COPYING)
+//! @copyright  Forschungszentrum Jülich GmbH 2013
+//! @authors    C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke
+//
+// ************************************************************************** //
+
+#include <iostream>
+#include <cmath>	// double std::abs()
+#include <stdlib.h>	// int std::abs()
+#include "Transform3D.h"
+#include "Exceptions.h"
+
+namespace Geometry {
+
+//! @brief Constructs a rotation by angle _a_
+//!        around an axis pointing from _p1_ to _p2_.
+
+//! @author E. Chernyaev 1996 (CLHEP/Geometry)
+//!
+Transform3D::Transform3D(double a,
+                         const BasicVector3D<double>& p1,
+                         const BasicVector3D<double>& p2)
+{
+    if (a == 0)
+        return Transform3D();  // identity transform
+
+    double cx = p2.x()-p1.x(), cy = p2.y()-p1.y(), cz = p2.z()-p1.z();
+    double ll = std::sqrt(cx*cx + cy*cy + cz*cz);
+    if (ll == 0)
+        throw RuntimeErrorException(
+            "Transform3D::Transform3D(a,p1,p2) -> "
+            "Error: no rotation axis given (zero length)");
+    double cosa = std::cos(a);
+    double sina = std::sin(a);
+    cx /= ll; cy /= ll; cz /= ll;
+    
+    xx_ = (1-cosa)*cx*cx + cosa;
+    xy_ = (1-cosa)*cx*cy - sina*cz;
+    xz_ = (1-cosa)*cx*cz + sina*cy;
+
+    yx_ = (1-cosa)*cy*cx + sina*cz;
+    yy_ = (1-cosa)*cy*cy + cosa;
+    yz_ = (1-cosa)*cy*cz - sina*cx;
+
+    zx_ = (1-cosa)*cz*cx - sina*cy;
+    zy_ = (1-cosa)*cz*cy + sina*cx;
+    zz_ = (1-cosa)*cz*cz + cosa;
+}
+
+//! Returns the inverse transformation.
+
+//! @author E. Chernyaev 1996 (CLHEP/Geometry)
+//!
+Transform3D Transform3D::inverse() const
+{
+    double detxx = yy_*zz_-yz_*zy_;
+    double detxy = yx_*zz_-yz_*zx_;
+    double detxz = yx_*zy_-yy_*zx_;
+    double det   = xx_*detxx - xy_*detxy + xz_*detxz;
+    if (det == 0)
+        throw RuntimeErrorException( "Transform3D::inverse() -> "
+                                     "Error: zero determinant" );
+    det = 1./det; detxx *= det; detxy *= det; detxz *= det;
+    double detyx = (xy_*zz_ - xz_*zy_)*det;
+    double detyy = (xx_*zz_ - xz_*zx_)*det;
+    double detyz = (xx_*zy_ - xy_*zx_)*det;
+    double detzx = (xy_*yz_ - xz_*yy_)*det;
+    double detzy = (xx_*yz_ - xz_*yx_)*det;
+    double detzz = (xx_*yy_ - xy_*yx_)*det;
+    return *this = Transform3D( detxx, -detyx,  detzx,
+                                -detxy,  detyy, -detzy,
+                                detxz, -detyz,  detzz );
+}
+
+}  // namespace Geometry
+
+
+
+
+    //! @brief Constructs a rotation by angle _a_
+    //!        around an axis pointing from _p1_ to _p2_.
+    Transform3D(double a,
+                const BasicVector3D<double>& p1,
+                const BasicVector3D<double>& p2);
+
+    //! Constructs a rotation by angle _a_ around axis _v_.
+    Transform3D(double a, const BasicVector3D<double>& v)
+    //  TODO(C++11): simplify using delegating constructor
+    {
+        *this = Transform3D(a,
+                            BasicVector3D<double>(0., 0., 0.),
+                            BasicVector3D<double>(v.x(),v.y(),v.z()) );
+    }
+
+    //! Copy constructor.
+    Transform3D(const Transform3D& m)
+        : xx_(m.xx_), xy_(m.xy_), xz_(m.xz_),
+          yx_(m.yx_), yy_(m.yy_), yz_(m.yz_),
+          zx_(m.zx_), zy_(m.zy_), zz_(m.zz_) {}
+
+    //! Destructor.
+    virtual ~Transform3D() {}
+
+    //! Assignment.
+    Transform3D& operator=(const Transform3D&m) {
+        xx_= m.xx_; xy_= m.xy_; xz_= m.xz_;
+        yx_= m.yx_; yy_= m.yy_; yz_= m.yz_;
+        zx_= m.zx_; zy_= m.zy_; zz_= m.zz_;
+        return *this;
+    }
+
+    //! Returns xx-element of the transformation matrix.
+    double xx() const { return xx_; }
+    //! Returns xy-element of the transformation matrix.
+    double xy() const { return xy_; }
+    //! Returns xz-element of the transformation matrix.
+    double xz() const { return xz_; }
+    //! Returns yx-element of the transformation matrix.
+    double yx() const { return yx_; }
+    //! Returns yy-element of the transformation matrix.
+    double yy() const { return yy_; }
+    //! Returns yz-element of the transformation matrix.
+    double yz() const { return yz_; }
+    //! Returns zx-element of the transformation matrix.
+    double zx() const { return zx_; }
+    //! Returns zy-element of the transformation matrix.
+    double zy() const { return zy_; }
+    //! Returns zz-element of the transformation matrix.
+    double zz() const { return zz_; }
+    
+    //! Sets the Identity transformation.
+    void setIdentity() { 
+        xy_= xz_= yx_= yz_= zx_= zy_= 0; xx_= yy_= zz_= 1;
+    }
+    
+    //! Returns the inverse transformation.
+    Transform3D inverse() const;
+    
+    //! Return transformed (typically: rotated) vector _v_.
+    virtual BasicVector3D<double> transformed(const BasicVector3D<double>& v) const
+    {
+        return BasicVector3D<double>(
+            xx()*v.x() + xy()*v.y() + xz()*v.z(),
+            yx()*v.x() + yy()*v.y() + yz()*v.z(),
+            zx()*v.x() + zy()*v.y() + zz()*v.z());
+    }
+
+ protected:
+    // 3x3  Transformation Matrix
+    double xx_, xy_, xz_,     
+           yx_, yy_, yz_,
+           zx_, zy_, zz_;
+
+    //! Constructor to set all 9 matrix elements, for internal use only.
+    Transform3D(double XX, double XY, double XZ,
+                double YX, double YY, double YZ,
+                double ZX, double ZY, double ZZ)
+        : xx_(XX), xy_(XY), xz_(XZ),
+          yx_(YX), yy_(YY), yz_(YZ),
+          zx_(ZX), zy_(ZY), zz_(ZZ) {}
+};
+
+//! A rotation of 3D geometrical objects around the x-axis.
+
+//! Should not be instantiated: see Rotate3D for example of use.
+//!
+//! @author <Evgueni.Tcherniaev@cern.ch>
+//!
+class RotateX3D : public Transform3D {
+ public:
+    //! Default constructor: sets the identity transformation.
+    RotateX3D() : Transform3D() {}
+    
+    //! Constructs a rotation around x-axis by angle a.
+    RotateX3D(double a) {
+        double cosa = std::cos(a), sina = std::sin(a); 
+        setTransform(1.,0.,0., 0.,cosa,-sina, 0.,sina,cosa);
+    }
+};
+
+//! A rotation of 3D geometrical objects around the y-axis.
+
+//! Should not be instantiated: see Transform3D for example of use.
+//!
+//! @author <Evgueni.Tcherniaev@cern.ch>
+//!
+class RotateY3D : public Transform3D {
+ public:
+    //! Default constructor: sets the identity transformation.
+    RotateY3D() : Transform3D() {}
+    
+    //! Constructs a rotation around y-axis by angle a.
+    RotateY3D(double a) {
+        double cosa = std::cos(a), sina = std::sin(a); 
+        setTransform(cosa,0.,sina, 0.,1.,0., -sina,0.,cosa);
+    }
+};
diff --git a/Core/Geometry/src/BasicVector3D.cpp b/Core/Geometry/src/BasicVector3D.cpp
index 8ab8d1bd747..c6e073cd86a 100644
--- a/Core/Geometry/src/BasicVector3D.cpp
+++ b/Core/Geometry/src/BasicVector3D.cpp
@@ -5,7 +5,7 @@
 //! @file       Geometry/src/BasicVector3D.cpp
 //! @brief      Implements template class BasicVector3D.
 //!
-//! For historic note, see BasicVector3D.h.
+//! Using code from CLHEP/Geometry by E. Chernyaev, see BasicVector3D.h.
 //!
 //! @homepage   http://apps.jcns.fz-juelich.de/BornAgain
 //! @license    GNU General Public License v3 or higher (see COPYING)
@@ -17,7 +17,6 @@
 #include <math.h>
 #include <iostream>
 #include "BasicVector3D.h"
-#include "Transform3D.h"
 
 typedef std::complex<double> complex_t;
 
@@ -154,69 +153,4 @@ double BasicVector3D<double>::angle(const BasicVector3D<double>& v) const
     return std::acos(cosa);
 }
 
-// ----------------------------------------------------------------------------
-// Rotations
-// ----------------------------------------------------------------------------
-
-template<>
-BasicVector3D<double> BasicVector3D<double>::rotatedX(double a) const
-{
-    double sina = std::sin(a);
-    double cosa = std::cos(a);
-    return BasicVector3D<double>( x(),
-                                  y()*cosa-z()*sina,
-                                  z()*cosa+y()*sina );
-}
-
-template<>
-BasicVector3D<double> BasicVector3D<double>::rotatedY(double a) const
-{
-    double sina = std::sin(a);
-    double cosa = std::cos(a);
-    return BasicVector3D<double>( x()*cosa+z()*sina,
-                                  y(),
-                                  z()*cosa-x()*sina );
-}
-
-template<>
-BasicVector3D<double> BasicVector3D<double>::rotatedZ(double a) const
-{
-    double sina = std::sin(a);
-    double cosa = std::cos(a);
-    return BasicVector3D( x()*cosa-y()*sina,
-                          y()*cosa+x()*sina,
-                          z() );
-}
-
-template<>
-BasicVector3D<double> BasicVector3D<double>::rotated(
-        double a, const BasicVector3D<double>& v) const
-{
-    if (a  == 0) return *this;
-    double cx = v.x(), cy = v.y(), cz = v.z();
-    double ll = std::sqrt(cx*cx + cy*cy + cz*cz);
-    if (ll == 0) {
-        std::cerr << "BasicVector<double>::rotate() : zero axis" << std::endl;
-        return *this;
-    }
-    double cosa = std::cos(a), sina = std::sin(a);
-    cx /= ll; cy /= ll; cz /= ll;
-
-    double xx = (1-cosa)*cx*cx + cosa;
-    double xy = (1-cosa)*cx*cy - sina*cz;
-    double xz = (1-cosa)*cx*cz + sina*cy;
-
-    double yx = (1-cosa)*cy*cx + sina*cz;
-    double yy = (1-cosa)*cy*cy + cosa;
-    double yz = (1-cosa)*cy*cz - sina*cx;
-
-    double zx = (1-cosa)*cz*cx - sina*cy;
-    double zy = (1-cosa)*cz*cy + sina*cx;
-    double zz = (1-cosa)*cz*cz + cosa;
-
-    return BasicVector3D( xx*x()+xy*y()+xz*z(),
-                          yx*x()+yy*y()+yz*z(),
-                          zx*x()+zy*y()+zz*z() );
-}
-
 }  // namespace Geometry
diff --git a/Core/Geometry/src/Transform3D.cpp b/Core/Geometry/src/Transform3D.cpp
index 05a54d0706a..e69de29bb2d 100644
--- a/Core/Geometry/src/Transform3D.cpp
+++ b/Core/Geometry/src/Transform3D.cpp
@@ -1,129 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file       Geometry/src/Transform3D.cpp
-//! @brief      Implements class Transform3D.
-//!
-//! For historic note, see BasicVector3D.h.
-//!
-//! @homepage   http://apps.jcns.fz-juelich.de/BornAgain
-//! @license    GNU General Public License v3 or higher (see COPYING)
-//! @copyright  Forschungszentrum Jülich GmbH 2013
-//! @authors    C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke
-//
-// ************************************************************************** //
-
-#include <iostream>
-#include <cmath>	// double std::abs()
-#include <stdlib.h>	// int std::abs()
-#include "Transform3D.h"
-
-namespace Geometry {
-
-double Transform3D::operator () (int i, int j) const
-{
-    if (i == 0) {
-        if (j == 0) { return xx_; }
-        if (j == 1) { return xy_; }
-        if (j == 2) { return xz_; }
-    } else if (i == 1) {
-        if (j == 0) { return yx_; }
-        if (j == 1) { return yy_; }
-        if (j == 2) { return yz_; }
-    } else if (i == 2) {
-        if (j == 0) { return zx_; }
-        if (j == 1) { return zy_; }
-        if (j == 2) { return zz_; }
-    } else if (i == 3) {
-        if (j == 0) { return 0.0; }
-        if (j == 1) { return 0.0; }
-        if (j == 2) { return 0.0; }
-    }
-    std::cerr << "Transform3D subscripting: bad indeces "
-              << "(" << i << "," << j << ")" << std::endl;
-    return 0.0;
-}
-
-//! Concatenation of transforms. Read efficiency warning!
-
-Transform3D Transform3D::operator*(const Transform3D&  b) const
-{
-    return Transform3D
-        (xx_*b.xx_+xy_*b.yx_+xz_*b.zx_,
-         xx_*b.xy_+xy_*b.yy_+xz_*b.zy_,
-         xx_*b.xz_+xy_*b.yz_+xz_*b.zz_, 
-         yx_*b.xx_+yy_*b.yx_+yz_*b.zx_,
-         yx_*b.xy_+yy_*b.yy_+yz_*b.zy_,
-         yx_*b.xz_+yy_*b.yz_+yz_*b.zz_, 
-         zx_*b.xx_+zy_*b.yx_+zz_*b.zx_,
-         zx_*b.xy_+zy_*b.yy_+zz_*b.zy_,
-         zx_*b.xz_+zy_*b.yz_+zz_*b.zz_ );
-}
-
-//! Returns the inverse transformation.
-//!
-//! @author E. Chernyaev 1996
-
-Transform3D Transform3D::inverse() const
-{
-    double detxx = yy_*zz_-yz_*zy_;
-    double detxy = yx_*zz_-yz_*zx_;
-    double detxz = yx_*zy_-yy_*zx_;
-    double det   = xx_*detxx - xy_*detxy + xz_*detxz;
-    if (det == 0) {
-        std::cerr << "Transform3D::inverse error: zero determinant" <<
-            std::endl;
-        return Transform3D();
-    }
-    det = 1./det; detxx *= det; detxy *= det; detxz *= det;
-    double detyx = (xy_*zz_ - xz_*zy_)*det;
-    double detyy = (xx_*zz_ - xz_*zx_)*det;
-    double detyz = (xx_*zy_ - xy_*zx_)*det;
-    double detzx = (xy_*yz_ - xz_*yy_)*det;
-    double detzy = (xx_*yz_ - xz_*yx_)*det;
-    double detzz = (xx_*yy_ - xy_*yx_)*det;
-    return Transform3D
-            (detxx, -detyx,  detzx,
-             -detxy,  detyy, -detzy,
-             detxz, -detyz,  detzz );
-}
-
-//! Construct rotation by angle a around axis p1->p2.
-//!
-//! @author E. Chernyaev 1996
-
-Rotate3D::Rotate3D(double a,
-                   const Point3D<double>&  p1,
-                   const Point3D<double>&  p2)
-        : Transform3D()
-{
-    if (a == 0) return;
-
-    double cx = p2.x()-p1.x(), cy = p2.y()-p1.y(), cz = p2.z()-p1.z();
-    double ll = std::sqrt(cx*cx + cy*cy + cz*cz);
-    if (ll == 0) {
-        std::cerr << "Rotate3D: zero axis" << std::endl;
-    } else {
-        double cosa = std::cos(a), sina = std::sin(a);
-        cx /= ll; cy /= ll; cz /= ll;
-
-        double txx = cosa + (1-cosa)*cx*cx;
-        double txy =        (1-cosa)*cx*cy - sina*cz;
-        double txz =        (1-cosa)*cx*cz + sina*cy;
-
-        double tyx =        (1-cosa)*cy*cx + sina*cz;
-        double tyy = cosa + (1-cosa)*cy*cy;
-        double tyz =        (1-cosa)*cy*cz - sina*cx;
-
-        double tzx =        (1-cosa)*cz*cx - sina*cy;
-        double tzy =        (1-cosa)*cz*cy + sina*cx;
-        double tzz = cosa + (1-cosa)*cz*cz;
-
-        setTransform(txx, txy, txz,
-                     tyx, tyy, tyz,
-                     tzx, tzy, tzz);
-    }
-}
-
-}  // namespace Geometry
diff --git a/Core/Samples/inc/DiffuseParticleInfo.h b/Core/Samples/inc/DiffuseParticleInfo.h
index 957ae3c8a23..cc7d877a53f 100644
--- a/Core/Samples/inc/DiffuseParticleInfo.h
+++ b/Core/Samples/inc/DiffuseParticleInfo.h
@@ -3,7 +3,7 @@
 //  BornAgain: simulate and fit scattering at grazing incidence
 //
 //! @file      Samples/inc/DiffuseParticleInfo.h
-//! @brief     Defines class DiffuseParticleInfo.
+//! @brief     Defines and implements class DiffuseParticleInfo.
 //!
 //! @homepage  http://apps.jcns.fz-juelich.de/BornAgain
 //! @license   GNU General Public License v3 or higher (see COPYING)
@@ -24,9 +24,13 @@ class DiffuseParticleInfo: public ParticleInfo
 {
  public:
     DiffuseParticleInfo(
-        Particle *p_particle, Geometry::Transform3D *transform=0,
-        double depth=0, double abundance=0);
-    virtual ~DiffuseParticleInfo();
+        Particle *p_particle, Geometry::ITransform3D *transform=0,
+        double depth=0, double abundance=0)
+        : ParticleInfo(p_particle, transform, depth, abundance)
+        , m_number_per_meso(0.0)
+    {}
+
+    virtual ~DiffuseParticleInfo() {}
 
     //! scale abundance
     void scaleAbundance(double factor) { m_abundance *= factor; }
diff --git a/Core/Samples/inc/IClusteredParticles.h b/Core/Samples/inc/IClusteredParticles.h
index a8cee06e222..bcd48793e85 100644
--- a/Core/Samples/inc/IClusteredParticles.h
+++ b/Core/Samples/inc/IClusteredParticles.h
@@ -19,7 +19,6 @@
 #include "IFormFactor.h"
 #include "ICompositeSample.h"
 #include "ParticleInfo.h"
-#include "Transform3D.h"
 #include "Exceptions.h"
 #include "DiffuseParticleInfo.h"
 
diff --git a/Core/Samples/inc/ParticleDecoration.h b/Core/Samples/inc/ParticleDecoration.h
index c206ab667b0..dec01e865c0 100644
--- a/Core/Samples/inc/ParticleDecoration.h
+++ b/Core/Samples/inc/ParticleDecoration.h
@@ -37,10 +37,10 @@ class ParticleDecoration : public IDecoration
 
     //! Adds particle giving depth and transformation
     void addParticle(
-        Particle *p_particle, Geometry::Transform3D *p_transform=0,
+        Particle *p_particle, Geometry::ITransform3D *p_transform=0,
         double depth=0, double abundance=1.0);
     void addParticle(
-        const Particle& particle, const Geometry::Transform3D& transform,
+        const Particle& particle, const Geometry::ITransform3D& transform,
         double depth=0, double abundance=1.0);
 
     //! Adds particle giving depth
diff --git a/Core/Samples/inc/ParticleInfo.h b/Core/Samples/inc/ParticleInfo.h
index 5d487d03944..989b609fe85 100644
--- a/Core/Samples/inc/ParticleInfo.h
+++ b/Core/Samples/inc/ParticleInfo.h
@@ -18,7 +18,7 @@
 
 #include "ICompositeSample.h"
 #include "Particle.h"
-#include "Transform3D.h"
+#include "ITransform3D.h"
 
 //! Holds additional information about particle (used in ParticleDecoration).
 
@@ -26,10 +26,10 @@ class ParticleInfo : public ICompositeSample
 {
  public:
     ParticleInfo(Particle *p_particle,
-                 Geometry::Transform3D *transform=0,
+                 Geometry::ITransform3D *transform=0,
                  double depth=0, double abundance=0);
     ParticleInfo(const Particle& p_particle,
-                 const Geometry::Transform3D& transform,
+                 const Geometry::ITransform3D& transform,
                  double depth=0, double abundance=0);
     virtual ~ParticleInfo();
 
@@ -39,12 +39,14 @@ class ParticleInfo : public ICompositeSample
     const Particle *getParticle() const { return mp_particle; }
 
     //! Returns transformation.
-    const Geometry::Transform3D *getTransform3D() const { return mp_transform; }
+    const Geometry::ITransform3D *getITransform3D() const
+    { return mp_transform; }
 
     //! Sets transformation.
-    void setTransform(const Geometry::Transform3D& transform) {
+    void setTransform(const Geometry::ITransform3D& transform)
+    {
         delete mp_transform;
-        mp_transform = new Geometry::Transform3D(transform);
+        mp_transform = new Geometry::ITransform3D(transform);
     }
 
     //! Returns depth.
@@ -63,7 +65,7 @@ class ParticleInfo : public ICompositeSample
     virtual void init_parameters();
 
     Particle *mp_particle;
-    Geometry::Transform3D *mp_transform;
+    Geometry::ITransform3D *mp_transform;
     double m_depth;
     double m_abundance;
 };
diff --git a/Core/Samples/inc/PositionParticleInfo.h b/Core/Samples/inc/PositionParticleInfo.h
index e12e85f3a2e..e040f44a9c2 100644
--- a/Core/Samples/inc/PositionParticleInfo.h
+++ b/Core/Samples/inc/PositionParticleInfo.h
@@ -27,11 +27,11 @@ class PositionParticleInfo : public ParticleInfo
 {
  public:
     PositionParticleInfo(
-        Particle *p_particle, Geometry::Transform3D *p_transform,
+        Particle *p_particle, Geometry::ITransform3D *p_transform,
         kvector_t position, double abundance=0);
 
     PositionParticleInfo(
-        const Particle& particle, const Geometry::Transform3D& transform,
+        const Particle& particle, const Geometry::ITransform3D& transform,
         kvector_t position, double abundance=0);
 
     PositionParticleInfo(
diff --git a/Core/Samples/src/Crystal.cpp b/Core/Samples/src/Crystal.cpp
index 286ccb2a3a4..90d22f93c1b 100644
--- a/Core/Samples/src/Crystal.cpp
+++ b/Core/Samples/src/Crystal.cpp
@@ -64,7 +64,7 @@ std::vector<DiffuseParticleInfo*>* Crystal::createDiffuseParticleInfo(
     double parent_height = parent_info.getParticle()->getSimpleFormFactor()->getHeight();
     double parent_depth = parent_info.getDepth();
 
-    const Geometry::Transform3D *p_parent_transform = parent_info.getTransform3D();
+    const Geometry::ITransform3D *p_parent_transform = parent_info.getITransform3D();
 
     double nbr_unit_cells = parent_volume/primitive_cell_volume;
 
diff --git a/Core/Samples/src/DiffuseParticleInfo.cpp b/Core/Samples/src/DiffuseParticleInfo.cpp
deleted file mode 100644
index 18013d32709..00000000000
--- a/Core/Samples/src/DiffuseParticleInfo.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-// ************************************************************************** //
-//
-//  BornAgain: simulate and fit scattering at grazing incidence
-//
-//! @file      Samples/src/DiffuseParticleInfo.cpp
-//! @brief     Implements class DiffuseParticleInfo.
-//!
-//! @homepage  http://apps.jcns.fz-juelich.de/BornAgain
-//! @license   GNU General Public License v3 or higher (see COPYING)
-//! @copyright Forschungszentrum Jülich GmbH 2013
-//! @authors   Scientific Computing Group at MLZ Garching
-//! @authors   C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke 
-//
-// ************************************************************************** //
-
-#include "DiffuseParticleInfo.h"
-
-DiffuseParticleInfo::DiffuseParticleInfo(Particle* p_particle, Geometry::Transform3D *transform, double depth, double abundance)
-: ParticleInfo(p_particle, transform, depth, abundance)
-, m_number_per_meso(0.0)
-{
-}
-
-DiffuseParticleInfo::~DiffuseParticleInfo()
-{
-}
diff --git a/Core/Samples/src/ParticleDecoration.cpp b/Core/Samples/src/ParticleDecoration.cpp
index 61dc3b20777..25029d5a082 100644
--- a/Core/Samples/src/ParticleDecoration.cpp
+++ b/Core/Samples/src/ParticleDecoration.cpp
@@ -22,20 +22,22 @@
 
 
 ParticleDecoration::ParticleDecoration()
-: m_total_abundance(0.0)
+  : m_total_abundance(0.0)
 {
     setName("ParticleDecoration");
 }
 
-ParticleDecoration::ParticleDecoration(Particle* p_particle, double depth, double abundance)
-: m_total_abundance(0.0)
+ParticleDecoration::ParticleDecoration(
+    Particle* p_particle, double depth, double abundance)
+  : m_total_abundance(0.0)
 {
     setName("ParticleDecoration");
     addParticle(p_particle, 0, depth, abundance);
 }
 
-ParticleDecoration::ParticleDecoration(const Particle& p_particle, double depth, double abundance)
-: m_total_abundance(0.0)
+ParticleDecoration::ParticleDecoration(
+    const Particle& p_particle, double depth, double abundance)
+  : m_total_abundance(0.0)
 {
     setName("ParticleDecoration");
     addParticle(p_particle.clone(), 0, depth, abundance);
@@ -43,9 +45,8 @@ ParticleDecoration::ParticleDecoration(const Particle& p_particle, double depth,
 
 ParticleDecoration::~ParticleDecoration()
 {
-    for (size_t i=0; i<m_particles.size(); ++i) {
+    for (size_t i=0; i<m_particles.size(); ++i)
         delete m_particles[i];
-    }
 }
 
 ParticleDecoration* ParticleDecoration::clone() const
@@ -58,7 +59,8 @@ ParticleDecoration* ParticleDecoration::clone() const
     }
 
     for (size_t i=0; i<m_interference_functions.size(); ++i) {
-        p_new->addAndRegisterInterferenceFunction(m_interference_functions[i]->clone());
+        p_new->addAndRegisterInterferenceFunction(
+            m_interference_functions[i]->clone());
     }
 
     p_new->m_total_abundance = m_total_abundance;
@@ -82,16 +84,19 @@ void ParticleDecoration::addParticle(const Particle& p_particle,
 }
 
 void ParticleDecoration::addParticle(const Particle& p_particle,
-        const Geometry::Transform3D& transform, double depth, double abundance)
+        const Geometry::ITransform3D& transform, double depth, double abundance)
 {
-    addParticle(p_particle.clone(), new Geometry::Transform3D(transform), depth, abundance);
+    addParticle(p_particle.clone(),
+                new Geometry::ITransform3D(transform),
+                depth, abundance);
 }
 
 // main function to add particle
 void ParticleDecoration::addParticle(Particle* p_particle,
-        Geometry::Transform3D *transform, double depth, double abundance)
+        Geometry::ITransform3D *transform, double depth, double abundance)
 {
-    addAndRegisterParticleInfo( new ParticleInfo(p_particle, transform, depth, abundance) );
+    addAndRegisterParticleInfo(
+        new ParticleInfo(p_particle, transform, depth, abundance) );
 }
 
 //! Adds particle info
@@ -108,7 +113,9 @@ const ParticleInfo* ParticleDecoration::getParticleInfo(size_t index) const
     if (index<m_particles.size()) {
         return m_particles[index];
     }
-    throw OutOfBoundsException("ParticleDecoration::getParticleInfo() -> Error! Not so many interference functions in this decoration.");
+    throw OutOfBoundsException(
+        "ParticleDecoration::getParticleInfo() -> "
+        "Error! Not so many interference functions in this decoration.");
 }
 
 double ParticleDecoration::getAbundanceFractionOfParticle(size_t index) const
@@ -118,20 +125,24 @@ double ParticleDecoration::getAbundanceFractionOfParticle(size_t index) const
 
 //! Adds interference functions
 
-void ParticleDecoration::addInterferenceFunction(IInterferenceFunction* p_interference_function)
+void ParticleDecoration::addInterferenceFunction(
+    IInterferenceFunction* p_interference_function)
 {
     addAndRegisterInterferenceFunction(p_interference_function);
 }
 
-void ParticleDecoration::addInterferenceFunction(const IInterferenceFunction& interference_function)
+void ParticleDecoration::addInterferenceFunction(
+    const IInterferenceFunction& interference_function)
 {
     addAndRegisterInterferenceFunction(interference_function.clone());
 }
 
-const IInterferenceFunction* ParticleDecoration::getInterferenceFunction(size_t index) const
+const IInterferenceFunction* ParticleDecoration::getInterferenceFunction(
+    size_t index) const
 {
-    if (index<m_interference_functions.size()) {
+    if (index<m_interference_functions.size())
         return m_interference_functions[index];
-    }
-    throw OutOfBoundsException("ParticleDecoration::getInterferenceFunction() -> Not so many interference functions in this decoration.");
+    throw OutOfBoundsException(
+        "ParticleDecoration::getInterferenceFunction() ->"
+        "Not so many interference functions in this decoration.");
 }
diff --git a/Core/Samples/src/ParticleInfo.cpp b/Core/Samples/src/ParticleInfo.cpp
index 79ebfbd20c4..7887da56291 100644
--- a/Core/Samples/src/ParticleInfo.cpp
+++ b/Core/Samples/src/ParticleInfo.cpp
@@ -15,7 +15,7 @@
 
 #include "ParticleInfo.h"
 
-ParticleInfo::ParticleInfo(Particle* p_particle, Geometry::Transform3D *transform, double depth, double abundance)
+ParticleInfo::ParticleInfo(Particle* p_particle, Geometry::ITransform3D *transform, double depth, double abundance)
     : mp_particle(p_particle)
     , mp_transform(transform)
     , m_depth(depth)
@@ -26,9 +26,13 @@ ParticleInfo::ParticleInfo(Particle* p_particle, Geometry::Transform3D *transfor
     init_parameters();
 }
 
-ParticleInfo::ParticleInfo(const Particle& p_particle, const Geometry::Transform3D& transform, double depth, double abundance)
+ParticleInfo::ParticleInfo(
+    const Particle& p_particle,
+    const Geometry::ITransform3D& transform,
+    double depth,
+    double abundance)
     : mp_particle(p_particle.clone())
-    , mp_transform(new Geometry::Transform3D(transform))
+    , mp_transform(new Geometry::ITransform3D(transform))
     , m_depth(depth)
     , m_abundance(abundance)
 {
@@ -52,7 +56,8 @@ void ParticleInfo::init_parameters()
 
 ParticleInfo *ParticleInfo::clone() const
 {
-    Geometry::Transform3D *transform(0);
-    if(mp_transform) transform = new Geometry::Transform3D(*mp_transform);
-    return new ParticleInfo(mp_particle->clone(), transform, m_depth, m_abundance);
+    Geometry::ITransform3D *transform(0);
+    if(mp_transform) transform = new Geometry::ITransform3D(*mp_transform);
+    return new ParticleInfo(
+        mp_particle->clone(), transform, m_depth, m_abundance);
 }
diff --git a/Core/Samples/src/PositionParticleInfo.cpp b/Core/Samples/src/PositionParticleInfo.cpp
index 461b9aa613b..0f29125a6fe 100644
--- a/Core/Samples/src/PositionParticleInfo.cpp
+++ b/Core/Samples/src/PositionParticleInfo.cpp
@@ -17,7 +17,7 @@
 #include <iostream>
 
 PositionParticleInfo::PositionParticleInfo(
-    Particle* p_particle, Geometry::Transform3D* p_transform,
+    Particle* p_particle, Geometry::ITransform3D* p_transform,
     kvector_t position, double abundance)
     : ParticleInfo(p_particle, p_transform, position.z(), abundance)
     , m_pos_x(position.x())
@@ -28,9 +28,9 @@ PositionParticleInfo::PositionParticleInfo(
 }
 
 PositionParticleInfo::PositionParticleInfo(
-    const Particle& particle, const Geometry::Transform3D& transform,
+    const Particle& particle, const Geometry::ITransform3D& transform,
     kvector_t position, double abundance)
-    : ParticleInfo(particle.clone(), new Geometry::Transform3D(transform),
+    : ParticleInfo(particle.clone(), new Geometry::ITransform3D(transform),
                    position.z(), abundance)
     , m_pos_x(position.x())
     , m_pos_y(position.y())
@@ -61,8 +61,8 @@ PositionParticleInfo::PositionParticleInfo(
 
 PositionParticleInfo* PositionParticleInfo::clone() const
 {
-    Geometry::Transform3D *p_transform(0);
-    if(mp_transform) p_transform = new Geometry::Transform3D(*mp_transform);
+    Geometry::ITransform3D *p_transform(0);
+    if(mp_transform) p_transform = new Geometry::ITransform3D(*mp_transform);
     kvector_t position(m_pos_x, m_pos_y, -m_depth);
     return new PositionParticleInfo(
         mp_particle->clone(), p_transform, position, m_abundance);
@@ -78,7 +78,7 @@ void PositionParticleInfo::setPosition(kvector_t position)
 void PositionParticleInfo::init_parameters()
 {
     getParameterPool()->clear();
-    getParameterPool()->registerParameter("x_position",& m_pos_x);
-    getParameterPool()->registerParameter("y_position",& m_pos_y);
-    getParameterPool()->registerParameter("z_position",& m_depth);
+    getParameterPool()->registerParameter("x_position", &m_pos_x);
+    getParameterPool()->registerParameter("y_position", &m_pos_y);
+    getParameterPool()->registerParameter("z_position", &m_depth);
 }
diff --git a/Tests/FunctionalTests/TestCore/IsGISAXS01/IsGISAXS01.cpp b/Tests/FunctionalTests/TestCore/IsGISAXS01/IsGISAXS01.cpp
index ddbfb8da7f3..aa30fe5b93c 100644
--- a/Tests/FunctionalTests/TestCore/IsGISAXS01/IsGISAXS01.cpp
+++ b/Tests/FunctionalTests/TestCore/IsGISAXS01/IsGISAXS01.cpp
@@ -7,7 +7,6 @@
 #include "MaterialManager.h"
 #include "MultiLayer.h"
 #include "OutputDataIOFactory.h"
-#include "ParticleDecoration.h"
 #include "Simulation.h"
 #include "Units.h"
 #include "Utils.h"
diff --git a/Tests/FunctionalTests/TestCore/IsGISAXS09/IsGISAXS09.cpp b/Tests/FunctionalTests/TestCore/IsGISAXS09/IsGISAXS09.cpp
index 48fdcb7f46b..f11bcdc9757 100644
--- a/Tests/FunctionalTests/TestCore/IsGISAXS09/IsGISAXS09.cpp
+++ b/Tests/FunctionalTests/TestCore/IsGISAXS09/IsGISAXS09.cpp
@@ -38,15 +38,21 @@ void FunctionalTests::IsGISAXS09::runpyramidZ0()
 {
     // building sample
     MultiLayer multi_layer;
-    const IMaterial *p_air_material = MaterialManager::getHomogeneousMaterial("Air", 1.0, 0.0);
-    const IMaterial *p_substrate_material = MaterialManager::getHomogeneousMaterial("Substrate", 1.0-6e-6, 2e-8);
+    const IMaterial *p_air_material =
+        MaterialManager::getHomogeneousMaterial("Air", 1.0, 0.0);
+    const IMaterial *p_substrate_material =
+        MaterialManager::getHomogeneousMaterial("Substrate", 1.0-6e-6, 2e-8);
     Layer air_layer;
     air_layer.setMaterial(p_air_material);
     Layer substrate_layer;
     substrate_layer.setMaterial(p_substrate_material);
 
     complex_t n_particle(1.0-6e-4, 2e-8);
-    ParticleDecoration particle_decoration(new Particle(n_particle, new FormFactorPyramid(5*Units::nanometer, 5*Units::nanometer, Units::deg2rad(54.73 ) ) ) );
+    ParticleDecoration particle_decoration(
+        new Particle(n_particle,
+                     new FormFactorPyramid(5*Units::nanometer,
+                                           5*Units::nanometer,
+                                           Units::deg2rad(54.73 ) ) ) );
     particle_decoration.addInterferenceFunction(new InterferenceFunctionNone());
     LayerDecorator air_layer_decorator(air_layer, particle_decoration);
 
@@ -55,8 +61,11 @@ void FunctionalTests::IsGISAXS09::runpyramidZ0()
 
     // building simulation
     Simulation simulation;
-    simulation.setDetectorParameters(100, 0.0*Units::degree, 2.0*Units::degree, 100, 0.0*Units::degree, 2.0*Units::degree, true);
-    simulation.setBeamParameters(1.0*Units::angstrom, -0.2*Units::degree, 0.0*Units::degree);
+    simulation.setDetectorParameters(
+        100, 0.0*Units::degree, 2.0*Units::degree,
+        100, 0.0*Units::degree, 2.0*Units::degree, true);
+    simulation.setBeamParameters(
+        1.0*Units::angstrom, -0.2*Units::degree, 0.0*Units::degree);
     simulation.setSample(multi_layer);
 
     // running simulation
@@ -70,8 +79,10 @@ void FunctionalTests::IsGISAXS09::runpyramidZ45()
 {
     // building sample
     MultiLayer multi_layer;
-    const IMaterial *p_air_material = MaterialManager::getHomogeneousMaterial("Air", 1.0, 0.0);
-    const IMaterial *p_substrate_material = MaterialManager::getHomogeneousMaterial("Substrate", 1.0-6e-6, 2e-8);
+    const IMaterial *p_air_material =
+        MaterialManager::getHomogeneousMaterial("Air", 1.0, 0.0);
+    const IMaterial *p_substrate_material =
+        MaterialManager::getHomogeneousMaterial("Substrate", 1.0-6e-6, 2e-8);
     Layer air_layer;
     air_layer.setMaterial(p_air_material);
     Layer substrate_layer;
@@ -79,9 +90,14 @@ void FunctionalTests::IsGISAXS09::runpyramidZ45()
 
     complex_t n_particle(1.0-6e-4, 2e-8);
     const double angle_around_z = 45.*Units::degree;
-    Particle *pyramid = new Particle(n_particle, new FormFactorPyramid(5*Units::nanometer, 5*Units::nanometer, Units::deg2rad(54.73)) );
-
-    Geometry::Transform3D *transform = new Geometry::RotateZ3D(angle_around_z);
+    Particle *pyramid = new Particle(
+        n_particle,
+        new FormFactorPyramid(5*Units::nanometer,
+                              5*Units::nanometer,
+                              Units::deg2rad(54.73)) );
+
+    Geometry::ITransform3D *transform =
+        new Geometry::RotateZ_3D(angle_around_z);
 
     ParticleDecoration particle_decoration;
 
diff --git a/Tests/UnitTests/TestCore/KVectorTest.h b/Tests/UnitTests/TestCore/KVectorTest.h
index 578fa12cbcf..c4ca961a040 100644
--- a/Tests/UnitTests/TestCore/KVectorTest.h
+++ b/Tests/UnitTests/TestCore/KVectorTest.h
@@ -107,26 +107,9 @@ TEST_F(KVectorTest, BasicTransformation)
 {
     const double epsilon=1e-12;
     kvector_t a,v;
-    // rotations
-    a = kvector_t(2., 0.5, std::sqrt(3.)/2.);
-    v = a.rotatedX(M_PI/6.);
-    EXPECT_DOUBLE_EQ( v.x(), 2.0);
-    ASSERT_NEAR(      v.y(), 0.0, epsilon);
-    ASSERT_NEAR(      v.z(), 1.0, epsilon );
-
-    a = kvector_t(std::sqrt(3.)/2., 2., 0.5);
-    v = a.rotatedY(M_PI/6.);
-    ASSERT_NEAR(      v.x(), 1.0, epsilon );
-    EXPECT_DOUBLE_EQ( v.y(), 2.0 );
-    ASSERT_NEAR(      v.z(), 0.0, epsilon );
-
-    a = kvector_t(0.5, std::sqrt(3.)/2., 2.);
-    v = a.rotatedZ(M_PI/6.);
-    ASSERT_NEAR(      v.x(), 0.0, epsilon );
-    ASSERT_NEAR(      v.y(), 1.0, epsilon );
-    EXPECT_DOUBLE_EQ( v.z(), 2.0 );
 
     // rotation via transformation
+/* currently neither implemented, nor needed
     a = kvector_t(2., 0.5, std::sqrt(3.)/2.);
     Geometry::Transform3D m1 = Geometry::RotateX3D(M_PI/6.);
     v = m1.transformed(a);
@@ -140,14 +123,21 @@ TEST_F(KVectorTest, BasicTransformation)
     ASSERT_NEAR(      v.x(), 1.0, epsilon );
     EXPECT_DOUBLE_EQ( v.y(), 2.0 );
     ASSERT_NEAR(      v.z(), 0.0, epsilon );
+*/
 
     a = kvector_t(0.5, std::sqrt(3.)/2., 2.);
-    Geometry::Transform3D m3 = Geometry::RotateZ3D(M_PI/6.);
+    Geometry::ITransform3D m3 = Geometry::RotateZ_3D(M_PI/6.);
     v = m3.transformed(a);
     ASSERT_NEAR(      v.x(), 0.0, epsilon );
     ASSERT_NEAR(      v.y(), 1.0, epsilon );
     EXPECT_DOUBLE_EQ( v.z(), 2.0 );
+    Geometry::Transform3D m4_inverse = m4.inverse();
+    v = m4_inverse.transformed(v);
+    ASSERT_NEAR( v.x(), a.x(), epsilon );
+    ASSERT_NEAR( v.y(), a.y(), epsilon );
+    ASSERT_NEAR( v.z(), a.z(), epsilon );
 
+/* currently neither implemented, nor needed
     // rotation around vector
     a = kvector_t(1, 1, std::sqrt(2));
     Geometry::Transform3D m4 =
@@ -162,6 +152,7 @@ TEST_F(KVectorTest, BasicTransformation)
     ASSERT_NEAR( v.x(), a.x(), epsilon );
     ASSERT_NEAR( v.y(), a.y(), epsilon );
     ASSERT_NEAR( v.z(), a.z(), epsilon );
+*/
 }
 
 #endif // KVECTORTEST_H
-- 
GitLab