From 08f4ed88b90d8d1eab9bae45cddc3ffe1e9a77ff Mon Sep 17 00:00:00 2001
From: Andreas Salzburger <Andreas.Salzburger@cern.ch>
Date: Wed, 25 Mar 2020 17:48:21 +0100
Subject: [PATCH] first volume bounds set

---
 .../Acts/Geometry/CuboidVolumeBounds.hpp      | 107 ++++---
 .../Geometry/CutoutCylinderVolumeBounds.hpp   |  27 +-
 .../Acts/Geometry/CylinderVolumeBounds.hpp    |  15 +-
 .../Geometry/DoubleTrapezoidVolumeBounds.hpp  | 242 ---------------
 .../Geometry/GenericCuboidVolumeBounds.hpp    |  11 +-
 .../Acts/Geometry/TrapezoidVolumeBounds.hpp   |  15 +-
 Core/include/Acts/Geometry/VolumeBounds.hpp   |  48 ++-
 Core/include/Acts/Surfaces/SurfaceBounds.hpp  |   4 +-
 Core/src/Geometry/CMakeLists.txt              |   1 -
 Core/src/Geometry/CuboidVolumeBounds.cpp      |  75 ++---
 Core/src/Geometry/CylinderVolumeBounds.cpp    |   3 -
 .../Geometry/DoubleTrapezoidVolumeBounds.cpp  | 287 ------------------
 Tests/UnitTests/Core/Geometry/CMakeLists.txt  |   2 +-
 .../Core/Geometry/CuboidVolumeBoundsTests.cpp |  90 ++++++
 .../DoubleTrapezoidVolumeBoundsTests.cpp      |  54 ----
 15 files changed, 258 insertions(+), 723 deletions(-)
 delete mode 100644 Core/include/Acts/Geometry/DoubleTrapezoidVolumeBounds.hpp
 delete mode 100644 Core/src/Geometry/DoubleTrapezoidVolumeBounds.cpp
 create mode 100644 Tests/UnitTests/Core/Geometry/CuboidVolumeBoundsTests.cpp
 delete mode 100644 Tests/UnitTests/Core/Geometry/DoubleTrapezoidVolumeBoundsTests.cpp

diff --git a/Core/include/Acts/Geometry/CuboidVolumeBounds.hpp b/Core/include/Acts/Geometry/CuboidVolumeBounds.hpp
index 7c9622f3f..0c1ed841e 100644
--- a/Core/include/Acts/Geometry/CuboidVolumeBounds.hpp
+++ b/Core/include/Acts/Geometry/CuboidVolumeBounds.hpp
@@ -1,6 +1,6 @@
 // This file is part of the Acts project.
 //
-// Copyright (C) 2016-2018 CERN for the benefit of the Acts project
+// Copyright (C) 2016-2020 CERN for the benefit of the Acts project
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -8,12 +8,15 @@
 
 #pragma once
 
-#include <cmath>
 #include "Acts/Geometry/Volume.hpp"
 #include "Acts/Geometry/VolumeBounds.hpp"
 #include "Acts/Utilities/BoundingBox.hpp"
 #include "Acts/Utilities/Definitions.hpp"
 
+#include <array>
+#include <cmath>
+#include <vector>
+
 namespace Acts {
 
 class RectangleBounds;
@@ -44,35 +47,52 @@ class Surface;
 
 class CuboidVolumeBounds : public VolumeBounds {
  public:
-  /// @enum BoundValues for readability
-  enum BoundValues { bv_halfX = 0, bv_halfY = 1, bv_halfZ = 2, bv_length = 3 };
+  /// @enum BoundValues for streaming and access
+  enum BoundValues : int {
+    eHalfLengthX = 0,
+    eHalfLengthY = 1,
+    eHalfLengthZ = 2,
+    eSize = 3
+  };
 
-  /// Default Constructor
-  CuboidVolumeBounds();
+  CuboidVolumeBounds() = delete;
 
   /// Constructor - the box boundaries
   ///
   /// @param halex is the half length of the cube in x
   /// @param haley is the half length of the cube in y
   /// @param halez is the half length of the cube in z
-  CuboidVolumeBounds(double halex, double haley, double halez);
+  CuboidVolumeBounds(double halex, double haley, double halez) noexcept(false);
+
+  /// Constructor - from a fixed size array
+  ///
+  /// @param values iw the bound values
+  CuboidVolumeBounds(const std::array<double, eSize>& values) noexcept(false)
+      : m_values(values) {
+    checkConsistency();
+  }
 
   /// Copy Constructor
   ///
   /// @param bobo is the source volume bounds to be copied
   CuboidVolumeBounds(const CuboidVolumeBounds& bobo);
 
-  /// Destructor
-  ~CuboidVolumeBounds() override;
-
   /// Assignment operator
   ///
   /// @param bobo is the source volume bounds to be assigned
   CuboidVolumeBounds& operator=(const CuboidVolumeBounds& bobo);
 
-  /// Virtual constructor
+  ~CuboidVolumeBounds() override = default;
+
   CuboidVolumeBounds* clone() const override;
 
+  VolumeBounds::BoundsType type() const final { return VolumeBounds::eCuboid; }
+
+  /// Return the bound values as dynamically sized vector
+  ///
+  /// @return this returns a copy of the internal values
+  std::vector<double> values() const final;
+
   /// This method checks if position in the 3D volume
   /// frame is inside the cylinder
   ///
@@ -95,42 +115,30 @@ class CuboidVolumeBounds : public VolumeBounds {
                                   const Vector3D& envelope = {0, 0, 0},
                                   const Volume* entity = nullptr) const final;
 
-  /// This method returns the halflength in local x
-  double halflengthX() const;
-
-  /// This method returns the halflength in local y
-  double halflengthY() const;
-
-  /// This method returns the halflength in local z
-  double halflengthZ() const;
-
   /// Output Method for std::ostream
   ///
   /// @param sl is ostream operator to be dumped into
   std::ostream& toStream(std::ostream& sl) const override;
 
+  /// Access to the bound values
+  /// @param bValue the class nested enum for the array access
+  double get(BoundValues bValue) const { return m_values[bValue]; }
+
  private:
   /// Templated dumpT method
   template <class T>
   T& dumpT(T& dt) const;
 
-  /// This method returns the associated RecantleBounds of the face PlaneSurface
-  /// parallel to local xy plane
-  std::shared_ptr<const RectangleBounds> faceXYRectangleBounds() const;
-
-  /// This method returns the associated RecantleBounds of the face PlaneSurface
-  /// parallel to local yz plane
-  std::shared_ptr<const RectangleBounds> faceYZRectangleBounds() const;
+  /// The bound values ordered in a fixed size array
+  std::array<double, eSize> m_values;
 
-  /// This method returns the associated RecantleBounds of the face PlaneSurface
-  // parallel to local zx plane
-  std::shared_ptr<const RectangleBounds> faceZXRectangleBounds() const;
+  std::shared_ptr<const RectangleBounds> m_xyBounds = nullptr;
+  std::shared_ptr<const RectangleBounds> m_yzBounds = nullptr;
+  std::shared_ptr<const RectangleBounds> m_zxBounds = nullptr;
 
-  /// The bound values
-  std::vector<double> m_values;
-  std::shared_ptr<const RectangleBounds> m_xyBounds;
-  std::shared_ptr<const RectangleBounds> m_yzBounds;
-  std::shared_ptr<const RectangleBounds> m_zxBounds;
+  /// Check the input values for consistency,
+  /// will throw a logic_exception if consistency is not given
+  void checkConsistency() noexcept(false);
 };
 
 inline CuboidVolumeBounds* CuboidVolumeBounds::clone() const {
@@ -138,30 +146,31 @@ inline CuboidVolumeBounds* CuboidVolumeBounds::clone() const {
 }
 
 inline bool CuboidVolumeBounds::inside(const Vector3D& pos, double tol) const {
-  return (std::abs(pos.x()) <= m_values.at(bv_halfX) + tol &&
-          std::abs(pos.y()) <= m_values.at(bv_halfY) + tol &&
-          std::abs(pos.z()) <= m_values.at(bv_halfZ) + tol);
-}
-
-inline double CuboidVolumeBounds::halflengthX() const {
-  return m_values.at(bv_halfX);
+  return (std::abs(pos.x()) <= get(eHalfLengthX) + tol &&
+          std::abs(pos.y()) <= get(eHalfLengthY) + tol &&
+          std::abs(pos.z()) <= get(eHalfLengthZ) + tol);
 }
 
-inline double CuboidVolumeBounds::halflengthY() const {
-  return m_values.at(bv_halfY);
+inline std::vector<double> CuboidVolumeBounds::values() const {
+  std::vector<double> valvector;
+  valvector.insert(valvector.begin(), m_values.begin(), m_values.end());
+  return valvector;
 }
 
-inline double CuboidVolumeBounds::halflengthZ() const {
-  return m_values.at(bv_halfZ);
+inline void CuboidVolumeBounds::checkConsistency() noexcept(false) {
+  if (get(eHalfLengthX) * get(eHalfLengthY) * get(eHalfLengthZ) <= 0.) {
+    throw std::invalid_argument(
+        "CuboidVolumeBounds: invalid input, zero or negative.");
+  }
 }
 
 template <class T>
 T& CuboidVolumeBounds::dumpT(T& dt) const {
   dt << std::setiosflags(std::ios::fixed);
   dt << std::setprecision(5);
-  dt << "Acts::CuboidVolumeBounds: (halfX, halfY, halfZ) = ";
-  dt << "(" << m_values.at(bv_halfX) << ", " << m_values.at(bv_halfY) << ", "
-     << m_values.at(bv_halfZ) << ")";
+  dt << "Acts::CuboidVolumeBounds: (halfLengthX, halfLengthY, halfLengthZ) = ";
+  dt << "(" << get(eHalfLengthX) << ", " << get(eHalfLengthY) << ", "
+     << get(eHalfLengthZ) << ")";
   return dt;
 }
 }  // namespace Acts
\ No newline at end of file
diff --git a/Core/include/Acts/Geometry/CutoutCylinderVolumeBounds.hpp b/Core/include/Acts/Geometry/CutoutCylinderVolumeBounds.hpp
index 90c9aff56..a582f4018 100644
--- a/Core/include/Acts/Geometry/CutoutCylinderVolumeBounds.hpp
+++ b/Core/include/Acts/Geometry/CutoutCylinderVolumeBounds.hpp
@@ -27,12 +27,23 @@ class IVisualization;
 /// |    |---------|    | rmed
 /// |    |         |    |
 /// ------         ------ rmin
-///       -- dz2 --
-/// -------- dz1 -------
+///       -- hlZc --
+/// --------- hlZ -------
 ///
 ///
 class CutoutCylinderVolumeBounds : public VolumeBounds {
  public:
+  /// @enum BoundValues for streaming and access
+  enum BoundValues : int {
+    eMinR = 0,
+    eMedR = 1,
+    eHalfLengthZcutout = 2,
+    eHalfLengthZ = 3,
+    eSize = 4
+  };
+
+  CutoutCylinderVolumeBounds() = delete;
+
   /// Constructor from defining parameters
   ///
   /// @param rmin Minimum radius at the "choke points"
@@ -44,13 +55,19 @@ class CutoutCylinderVolumeBounds : public VolumeBounds {
                              double dz2)
       : m_rmin(rmin), m_rmed(rmed), m_rmax(rmax), m_dz1(dz1), m_dz2(dz2) {}
 
-  /// Virtual default constructor
   ~CutoutCylinderVolumeBounds() override = default;
 
-  /// Clone method.
-  /// @return Pointer to a copy of the shape
   VolumeBounds* clone() const override;
 
+  VolumeBounds::BoundsType type() const final {
+    return VolumeBounds::eCutoutCylinder;
+  }
+
+  /// Return the bound values as dynamically sized vector
+  ///
+  /// @return this returns a copy of the internal values
+  std::vector<double> values() const final { return {}; };
+
   /// Inside method to test whether a point is inside the shape
   ///
   /// @param gpos The point to test
diff --git a/Core/include/Acts/Geometry/CylinderVolumeBounds.hpp b/Core/include/Acts/Geometry/CylinderVolumeBounds.hpp
index 1ed77ae62..fd63b762c 100644
--- a/Core/include/Acts/Geometry/CylinderVolumeBounds.hpp
+++ b/Core/include/Acts/Geometry/CylinderVolumeBounds.hpp
@@ -79,8 +79,7 @@ class CylinderVolumeBounds : public VolumeBounds {
     bv_length = 4
   };
 
-  /// Default Constructor
-  CylinderVolumeBounds();
+  CylinderVolumeBounds() = delete;
 
   /// Constructor - full cylinder
   ///
@@ -121,15 +120,21 @@ class CylinderVolumeBounds : public VolumeBounds {
   /// @param cylbo is the source cylinder volume bounds for the copy
   CylinderVolumeBounds(const CylinderVolumeBounds& cylbo);
 
-  /// Destructor
   ~CylinderVolumeBounds() override;
 
-  /// Assignment operator
   CylinderVolumeBounds& operator=(const CylinderVolumeBounds& cylbo);
 
-  /// Virtual constructor
   CylinderVolumeBounds* clone() const override;
 
+  VolumeBounds::BoundsType type() const final {
+    return VolumeBounds::eCylinder;
+  }
+
+  /// Return the bound values as dynamically sized vector
+  ///
+  /// @return this returns a copy of the internal values
+  std::vector<double> values() const final { return {}; };
+
   /// This method checks if position in the 3D volume
   /// frame is inside the cylinder
   ///
diff --git a/Core/include/Acts/Geometry/DoubleTrapezoidVolumeBounds.hpp b/Core/include/Acts/Geometry/DoubleTrapezoidVolumeBounds.hpp
deleted file mode 100644
index 3355393eb..000000000
--- a/Core/include/Acts/Geometry/DoubleTrapezoidVolumeBounds.hpp
+++ /dev/null
@@ -1,242 +0,0 @@
-// This file is part of the Acts project.
-//
-// Copyright (C) 2016-2018 CERN for the benefit of the Acts project
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-///////////////////////////////////////////////////////////////////
-// DoubleTrapezoidVolumeBounds.h, Acts project
-///////////////////////////////////////////////////////////////////
-
-#pragma once
-#include "Acts/Geometry/Volume.hpp"
-#include "Acts/Geometry/VolumeBounds.hpp"
-#include "Acts/Utilities/BoundingBox.hpp"
-#include "Acts/Utilities/Definitions.hpp"
-
-namespace Acts {
-
-class Surface;
-class RectangleBounds;
-class TrapezoidBounds;
-class DiamondBounds;
-
-/// @class DoubleTrapezoidVolumeBounds
-///
-/// Bounds for a double trapezoidal shaped Volume, the decomposeToSurfaces
-/// method
-/// creates a
-/// vector of 8 surfaces:
-///
-///  BoundarySurfaceFace [index]:
-///
-///  - negativeFaceXY     [0] : Diamond Acts::PlaneSurface,
-///                             parallel to \f$ xy \f$ plane at negative \f$z\f$
-///  - positiveFaceXY     [1] : Diamond Acts::PlaneSurface,
-///                             parallel to \f$ xy \f$ plane at positive \f$z\f$
-///  - trapezoidFaceAlpha1 [2] : Rectangular  Acts::PlaneSurface,
-///                              attached to [0] and [1] at negative \f$ x \f$
-/// (associated to alpha1)
-///  - trapezoidFaceBeta1  [3] : Rectangular  Acts::PlaneSurface,
-///                             attached to [0] and [1] at positive \f$ x \f$
-/// (associated to beta1)
-///  - trapezoidFaceAlpha2 [5] : Rectangular  Acts::PlaneSurface,
-///                              attached to [0] and [1] at negative \f$ x \f$
-/// (associated to alpha2)
-///  - trapezoidFaceBeta2  [6] : Rectangular  Acts::PlaneSurface,
-///                              attached to [0] and [1] at positive \f$ x \f$
-/// (associated to beta2)
-///  - negativeFaceZX     [4] : Rectangular  Acts::PlaneSurface,
-///                             parallel to \f$ zx \f$ plane at negative \f$y\f$
-///  - positiveFaceZX     [5] : Rectangular  Acts::PlaneSurface,
-///                             parallel to \f$ zx \f$ plane at positive \f$y\f$
-///
-///  @image html DoubleTrapezoidVolumeBounds_decomp.gif
-
-class DoubleTrapezoidVolumeBounds : public VolumeBounds {
- public:
-  /// @enum BoundValues for readability
-  enum BoundValues {
-    bv_minHalfX = 0,
-    bv_medHalfX = 1,
-    bv_maxHalfX = 2,
-    bv_halfY1 = 3,
-    bv_halfY2 = 4,
-    bv_halfZ = 5,
-    bv_alpha1 = 6,
-    bv_alpha2 = 7,
-    bv_length = 8
-  };
-
-  /// Default Constructor
-  DoubleTrapezoidVolumeBounds();
-
-  /// Constructor - the double trapezoid boundaries (
-  /// symmetric trapezoid/diamond
-  ///
-  /// @param minhalex half length in x at minimum y
-  /// @param medhalex half length in x aty = 0
-  /// @param maxhalex half length in x at maximum x
-  /// @param haley1 first half length in y (to negative)
-  /// @param haley2 second half length in y (to positive)
-  /// @param halez half length in z
-  DoubleTrapezoidVolumeBounds(double minhalex, double medhalex, double maxhalex,
-                              double haley1, double haley2, double halez);
-
-  /// Copy Constructor
-  ///
-  /// @param trabo is the source bounds
-  DoubleTrapezoidVolumeBounds(const DoubleTrapezoidVolumeBounds& trabo);
-
-  /// Destructor
-  ~DoubleTrapezoidVolumeBounds() override;
-
-  /// Assignment operator
-  ///
-  /// @param trabo is the source bounds
-  DoubleTrapezoidVolumeBounds& operator=(
-      const DoubleTrapezoidVolumeBounds& trabo);
-
-  /// Virtual constructor
-  DoubleTrapezoidVolumeBounds* clone() const override;
-
-  /// This method checks if position in the 3D volume frame
-  /// is inside the cylinder
-  ///
-  /// @param pos is the global position to be checked for inside
-  /// @param tol is the tolerance parametere
-  bool inside(const Vector3D& pos, double tol = 0.) const override;
-
-  /// decompose into boundary surfaces
-  ///
-  /// @param transformPtr is the transform applied by the volume
-  ///
-  /// @return a vector of surfaces to be used as boundary surfaces
-  std::vector<std::shared_ptr<const Surface>> decomposeToSurfaces(
-      const Transform3D* transformPtr) const override;
-
-  /// Construct bounding box for this shape
-  /// @param trf Optional transform
-  /// @param envelope Optional envelope to add / subtract from min/max
-  /// @param entity Entity to associate this bounding box with
-  /// @return Constructed bounding box
-  Volume::BoundingBox boundingBox(const Transform3D* trf = nullptr,
-                                  const Vector3D& envelope = {0, 0, 0},
-                                  const Volume* entity = nullptr) const final;
-
-  /// This method returns the X halflength at minimal Y
-  double minHalflengthX() const;
-
-  /// This method returns the (maximal) halflength in local x
-  double medHalflengthX() const;
-
-  /// This method returns the X halflength at maximal Y (local coordinates)
-  double maxHalflengthX() const;
-
-  /// This method returns the halflength1 in local y
-  double halflengthY1() const;
-
-  /// This method returns the halflength2 in local y
-  double halflengthY2() const;
-
-  /// This method returns the halflength in local z
-  double halflengthZ() const;
-
-  /// This method returns the opening angle in point A (negative local x)
-  double alpha1() const;
-
-  /// This method returns the opening angle in point A' (negative local x)
-  double alpha2() const;
-
-  /// Output Method for std::ostream
-  std::ostream& toStream(std::ostream& sl) const override;
-
- private:
-  /// dump method
-  ///
-  /// @tparam dT is the output stream to be dumped into
-  template <class T>
-  T& dumpT(T& dT) const;
-
-  /// This method returns the associated DoubleTrapezoidBounds of the face
-  /// PlaneSurface parallel to local xy plane
-  DiamondBounds* faceXYDiamondBounds() const;
-
-  /// This method returns the associated RecantleBounds of the face PlaneSurface
-  /// attached to alpha (negative local x)
-  RectangleBounds* faceAlpha1RectangleBounds() const;
-
-  /// This method returns the associated RecantleBounds of the face PlaneSurface
-  /// attached to alpha (negative local x)
-  RectangleBounds* faceAlpha2RectangleBounds() const;
-
-  /// This method returns the associated RecantleBounds of the face PlaneSurface
-  /// attached to beta (positive local x)
-  RectangleBounds* faceBeta1RectangleBounds() const;
-
-  /// This method returns the associated RecantleBounds of the face PlaneSurface
-  /// attached to beta (positive local x)
-  RectangleBounds* faceBeta2RectangleBounds() const;
-
-  /// This method returns the associated RecantleBounds of the face PlaneSurface
-  /// parallel to local zx plane, negative local y
-  RectangleBounds* faceZXRectangleBoundsBottom() const;
-
-  /// This method returns the associated RecantleBounds of the face PlaneSurface
-  /// parallel to local zx plane, positive local y
-  RectangleBounds* faceZXRectangleBoundsTop() const;
-
-  std::vector<double> m_values;  ///< the internal store
-};
-
-inline DoubleTrapezoidVolumeBounds* DoubleTrapezoidVolumeBounds::clone() const {
-  return new DoubleTrapezoidVolumeBounds(*this);
-}
-
-inline double DoubleTrapezoidVolumeBounds::minHalflengthX() const {
-  return m_values.at(bv_minHalfX);
-}
-
-inline double DoubleTrapezoidVolumeBounds::medHalflengthX() const {
-  return m_values.at(bv_medHalfX);
-}
-
-inline double DoubleTrapezoidVolumeBounds::maxHalflengthX() const {
-  return m_values.at(bv_maxHalfX);
-}
-
-inline double DoubleTrapezoidVolumeBounds::halflengthY1() const {
-  return m_values.at(bv_halfY1);
-}
-
-inline double DoubleTrapezoidVolumeBounds::halflengthY2() const {
-  return m_values.at(bv_halfY2);
-}
-
-inline double DoubleTrapezoidVolumeBounds::halflengthZ() const {
-  return m_values.at(bv_halfZ);
-}
-
-inline double DoubleTrapezoidVolumeBounds::alpha1() const {
-  return m_values.at(bv_alpha1);
-}
-
-inline double DoubleTrapezoidVolumeBounds::alpha2() const {
-  return m_values.at(bv_alpha2);
-}
-
-template <class T>
-T& DoubleTrapezoidVolumeBounds::dumpT(T& dT) const {
-  dT << std::setiosflags(std::ios::fixed);
-  dT << std::setprecision(5);
-  dT << "Acts::DoubleTrapezoidVolumeBounds: (minhalfX, medhalfX, maxhalfX, "
-        "halfY1, halfY2, halfZ) = ";
-  dT << "(" << m_values.at(bv_minHalfX) << ", " << m_values.at(bv_medHalfX)
-     << ", " << m_values.at(bv_maxHalfX);
-  dT << ", " << m_values.at(bv_halfY1) << ", " << m_values.at(bv_halfY2) << ", "
-     << m_values.at(bv_halfZ) << ")";
-  return dT;
-}
-}  // namespace Acts
\ No newline at end of file
diff --git a/Core/include/Acts/Geometry/GenericCuboidVolumeBounds.hpp b/Core/include/Acts/Geometry/GenericCuboidVolumeBounds.hpp
index 9d0df1e93..c11355965 100644
--- a/Core/include/Acts/Geometry/GenericCuboidVolumeBounds.hpp
+++ b/Core/include/Acts/Geometry/GenericCuboidVolumeBounds.hpp
@@ -33,10 +33,17 @@ class GenericCuboidVolumeBounds : public VolumeBounds {
 
   ~GenericCuboidVolumeBounds() override = default;
 
-  ///  clone() method to make deep copy in Volume copy constructor and for
-  /// assigment operator  of the Surface class.
   VolumeBounds* clone() const override;
 
+  VolumeBounds::BoundsType type() const final {
+    return VolumeBounds::eGenericCuboid;
+  }
+
+  /// Return the bound values as dynamically sized vector
+  ///
+  /// @return this returns a copy of the internal values
+  std::vector<double> values() const final { return {}; };
+
   /// Checking if position given in volume frame is inside
   ///
   /// @param gpos is the global position to be checked
diff --git a/Core/include/Acts/Geometry/TrapezoidVolumeBounds.hpp b/Core/include/Acts/Geometry/TrapezoidVolumeBounds.hpp
index eb2320d96..6e7f8e040 100644
--- a/Core/include/Acts/Geometry/TrapezoidVolumeBounds.hpp
+++ b/Core/include/Acts/Geometry/TrapezoidVolumeBounds.hpp
@@ -86,16 +86,23 @@ class TrapezoidVolumeBounds : public VolumeBounds {
   /// @param trabo The object to be copied
   TrapezoidVolumeBounds(const TrapezoidVolumeBounds& trabo);
 
-  /// Destructor
-  ~TrapezoidVolumeBounds() override;
-
   /// Assignment operator
   /// @param trabo The object to be assigned
   TrapezoidVolumeBounds& operator=(const TrapezoidVolumeBounds& trabo);
 
-  /// Virtual constructor
+  ~TrapezoidVolumeBounds() override;
+
   TrapezoidVolumeBounds* clone() const override;
 
+  VolumeBounds::BoundsType type() const final {
+    return VolumeBounds::eTrapezoid;
+  }
+
+  /// Return the bound values as dynamically sized vector
+  ///
+  /// @return this returns a copy of the internal values
+  std::vector<double> values() const final { return {}; };
+
   /// This method checks if position in the 3D volume frame
   /// is inside the cylinder
   ///
diff --git a/Core/include/Acts/Geometry/VolumeBounds.hpp b/Core/include/Acts/Geometry/VolumeBounds.hpp
index c39a141b9..968b61e8c 100644
--- a/Core/include/Acts/Geometry/VolumeBounds.hpp
+++ b/Core/include/Acts/Geometry/VolumeBounds.hpp
@@ -15,20 +15,6 @@
 #include "Acts/Utilities/BoundingBox.hpp"
 #include "Acts/Utilities/Definitions.hpp"
 
-#ifndef VOLUMEBOUNDS_boundValues_FILL
-#define VOLUMEBOUNDS_boundValues_FILL(val) m_values[bv_##val] = val
-#endif
-
-#ifndef VOLUMEBOUNDS_boundValues_ACCESS
-#define VOLUMEBOUNDS_boundValues_ACCESS(val) \
-  double val() const { return m_values[bv_##val]; }
-#endif
-
-#ifndef VOLUMEBOUNDS_DERIVED_ACCESS
-#define VOLUMEBOUNDS_DERIVED_ACCESS(derived) \
-  double derived() const { return m_##derived; }
-#endif
-
 namespace Acts {
 
 class Surface;
@@ -39,6 +25,7 @@ using VolumeBoundsPtr = std::shared_ptr<const VolumeBounds>;
 
 using SurfacePtr = std::shared_ptr<const Surface>;
 using SurfacePtrVector = std::vector<SurfacePtr>;
+
 /// @class VolumeBounds
 ///
 /// Pure Absract Base Class for Volume bounds.
@@ -55,16 +42,38 @@ using SurfacePtrVector = std::vector<SurfacePtr>;
 /// Surfaces into BoundarySurfaces.
 class VolumeBounds {
  public:
-  /// Default Constructor*/
+  // @enum BoundsType
+  /// This is nested to the VolumeBounds, as also SurfaceBounds will have
+  /// Bounds Type.
+  enum BoundsType : int {
+    eCone = 0,
+    eCuboid = 1,
+    eCutoutCylinder = 2,
+    eCylinder = 3,
+    eGenericCuboid = 4,
+    eTrapezoid = 5,
+    eOther = 6
+  };
+
   VolumeBounds() = default;
 
-  /// Destructor
   virtual ~VolumeBounds() = default;
 
   ///  clone() method to make deep copy in Volume copy constructor and for
   /// assigment operator  of the Surface class.
   virtual VolumeBounds* clone() const = 0;
 
+  /// Return the bounds type - for persistency optimization
+  ///
+  /// @return is a BoundsType enum
+  virtual BoundsType type() const = 0;
+
+  /// Access method for bound values, this is a dynamically sized
+  /// vector containing the parameters needed to describe these bounds
+  ///
+  /// @return of the stored values for this SurfaceBounds object
+  virtual std::vector<double> values() const = 0;
+
   /// Checking if position given in volume frame is inside
   ///
   /// @param gpos is the global position to be checked
@@ -125,4 +134,11 @@ inline double VolumeBounds::binningBorder(BinningValue /*bValue*/) const {
 /// Overload of << operator for std::ostream for debug output
 std::ostream& operator<<(std::ostream& sl, const VolumeBounds& vb);
 
+inline bool operator==(const VolumeBounds& lhs, const VolumeBounds& rhs) {
+  if (&lhs == &rhs) {
+    return true;
+  }
+  return (lhs.type() == rhs.type()) && (lhs.values() == rhs.values());
+}
+
 }  // namespace Acts
diff --git a/Core/include/Acts/Surfaces/SurfaceBounds.hpp b/Core/include/Acts/Surfaces/SurfaceBounds.hpp
index 75a72e784..6e16f30e2 100644
--- a/Core/include/Acts/Surfaces/SurfaceBounds.hpp
+++ b/Core/include/Acts/Surfaces/SurfaceBounds.hpp
@@ -26,8 +26,8 @@ namespace Acts {
 class SurfaceBounds {
  public:
   /// @enum BoundsType
-  ///
-  /// This enumerator simplifies the persistency and bounds identification
+  /// This is nested to the SurfaceBounds, as also VolumeBounds will have
+  /// Bounds Type.
   enum BoundsType : int {
     eCone = 0,
     eCylinder = 1,
diff --git a/Core/src/Geometry/CMakeLists.txt b/Core/src/Geometry/CMakeLists.txt
index f4669b6d2..3e053e26f 100644
--- a/Core/src/Geometry/CMakeLists.txt
+++ b/Core/src/Geometry/CMakeLists.txt
@@ -13,7 +13,6 @@ target_sources_local(
     CylinderVolumeHelper.cpp
     Extent.cpp
     DiscLayer.cpp
-    DoubleTrapezoidVolumeBounds.cpp
     GenericApproachDescriptor.cpp
     GenericCuboidVolumeBounds.cpp
     GeometryID.cpp
diff --git a/Core/src/Geometry/CuboidVolumeBounds.cpp b/Core/src/Geometry/CuboidVolumeBounds.cpp
index 219c233ef..b36a9987c 100644
--- a/Core/src/Geometry/CuboidVolumeBounds.cpp
+++ b/Core/src/Geometry/CuboidVolumeBounds.cpp
@@ -1,36 +1,28 @@
 // This file is part of the Acts project.
 //
-// Copyright (C) 2016-2018 CERN for the benefit of the Acts project
+// Copyright (C) 2016-2020 CERN for the benefit of the Acts project
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 #include "Acts/Geometry/CuboidVolumeBounds.hpp"
-#include <cmath>
-#include <iostream>
 #include "Acts/Surfaces/PlaneSurface.hpp"
 #include "Acts/Surfaces/RectangleBounds.hpp"
 #include "Acts/Surfaces/Surface.hpp"
 #include "Acts/Utilities/BoundingBox.hpp"
 
-Acts::CuboidVolumeBounds::CuboidVolumeBounds()
-    : VolumeBounds(), m_values(bv_length, 0.) {}
+#include <cmath>
+#include <iostream>
 
 Acts::CuboidVolumeBounds::CuboidVolumeBounds(double halex, double haley,
                                              double halez)
     : VolumeBounds(),
-      m_values(bv_length, 0.),
-      m_xyBounds(nullptr),
-      m_yzBounds(nullptr),
-      m_zxBounds(nullptr) {
-  m_values.at(bv_halfX) = halex;
-  m_values.at(bv_halfY) = haley;
-  m_values.at(bv_halfZ) = halez;
-
-  m_xyBounds = faceXYRectangleBounds();
-  m_yzBounds = faceYZRectangleBounds();
-  m_zxBounds = faceZXRectangleBounds();
+      m_values({halex, haley, halez}),
+      m_xyBounds(std::make_shared<const RectangleBounds>(halex, haley)),
+      m_yzBounds(std::make_shared<const RectangleBounds>(haley, halez)),
+      m_zxBounds(std::make_shared<const RectangleBounds>(halez, halex)) {
+  checkConsistency();
 }
 
 Acts::CuboidVolumeBounds::CuboidVolumeBounds(const CuboidVolumeBounds& bobo)
@@ -40,8 +32,6 @@ Acts::CuboidVolumeBounds::CuboidVolumeBounds(const CuboidVolumeBounds& bobo)
       m_yzBounds(bobo.m_yzBounds),
       m_zxBounds(bobo.m_zxBounds) {}
 
-Acts::CuboidVolumeBounds::~CuboidVolumeBounds() = default;
-
 Acts::CuboidVolumeBounds& Acts::CuboidVolumeBounds::operator=(
     const CuboidVolumeBounds& bobo) {
   if (this != &bobo) {
@@ -66,12 +56,12 @@ Acts::SurfacePtrVector Acts::CuboidVolumeBounds::decomposeToSurfaces(
   //   (1) - at negative local z
   tTransform =
       new Transform3D(transform * AngleAxis3D(M_PI, Vector3D(0., 1., 0.)) *
-                      Translation3D(Vector3D(0., 0., halflengthZ())));
+                      Translation3D(Vector3D(0., 0., get(eHalfLengthZ))));
   rSurfaces.push_back(Surface::makeShared<PlaneSurface>(
       std::shared_ptr<const Transform3D>(tTransform), m_xyBounds));
   //   (2) - at positive local z
-  tTransform = new Transform3D(transform *
-                               Translation3D(Vector3D(0., 0., halflengthZ())));
+  tTransform = new Transform3D(
+      transform * Translation3D(Vector3D(0., 0., get(eHalfLengthZ))));
   rSurfaces.push_back(Surface::makeShared<PlaneSurface>(
       std::shared_ptr<const Transform3D>(tTransform), m_xyBounds));
   // face surfaces yz -------------------------------------
@@ -79,57 +69,38 @@ Acts::SurfacePtrVector Acts::CuboidVolumeBounds::decomposeToSurfaces(
   //   (3) - at negative local x
   tTransform =
       new Transform3D(transform * AngleAxis3D(M_PI, Vector3D(0., 0., 1.)) *
-                      Translation3D(Vector3D(halflengthX(), 0., 0)) *
+                      Translation3D(Vector3D(get(eHalfLengthX), 0., 0)) *
                       AngleAxis3D(0.5 * M_PI, Vector3D(0., 1., 0)) *
                       AngleAxis3D(0.5 * M_PI, Vector3D(0., 0., 1.)));
   rSurfaces.push_back(Surface::makeShared<PlaneSurface>(
       std::shared_ptr<const Transform3D>(tTransform), m_yzBounds));
   //   (4) - at positive local x
-  tTransform = new Transform3D(transform *
-                               Translation3D(Vector3D(halflengthX(), 0., 0.)) *
-                               AngleAxis3D(0.5 * M_PI, Vector3D(0., 1., 0.)) *
-                               AngleAxis3D(0.5 * M_PI, Vector3D(0., 0., 1.)));
+  tTransform = new Transform3D(
+      transform * Translation3D(Vector3D(get(eHalfLengthX), 0., 0.)) *
+      AngleAxis3D(0.5 * M_PI, Vector3D(0., 1., 0.)) *
+      AngleAxis3D(0.5 * M_PI, Vector3D(0., 0., 1.)));
   rSurfaces.push_back(Surface::makeShared<PlaneSurface>(
       std::shared_ptr<const Transform3D>(tTransform), m_yzBounds));
   // face surfaces zx -------------------------------------
   //   (5) - at negative local y
   tTransform =
       new Transform3D(transform * AngleAxis3D(M_PI, Vector3D(1., 0., 0.)) *
-                      Translation3D(Vector3D(0., halflengthY(), 0.)) *
+                      Translation3D(Vector3D(0., get(eHalfLengthY), 0.)) *
                       AngleAxis3D(-0.5 * M_PI, Vector3D(0., 1., 0.)) *
                       AngleAxis3D(-0.5 * M_PI, Vector3D(1., 0., 0.)));
   rSurfaces.push_back(Surface::makeShared<PlaneSurface>(
       std::shared_ptr<const Transform3D>(tTransform), m_zxBounds));
   //   (6) - at positive local y
-  tTransform = new Transform3D(transform *
-                               Translation3D(Vector3D(0., halflengthY(), 0.)) *
-                               AngleAxis3D(-0.5 * M_PI, Vector3D(0., 1., 0.)) *
-                               AngleAxis3D(-0.5 * M_PI, Vector3D(1., 0., 0.)));
+  tTransform = new Transform3D(
+      transform * Translation3D(Vector3D(0., get(eHalfLengthY), 0.)) *
+      AngleAxis3D(-0.5 * M_PI, Vector3D(0., 1., 0.)) *
+      AngleAxis3D(-0.5 * M_PI, Vector3D(1., 0., 0.)));
   rSurfaces.push_back(Surface::makeShared<PlaneSurface>(
       std::shared_ptr<const Transform3D>(tTransform), m_zxBounds));
   // return the surfaces
   return rSurfaces;
 }
 
-std::shared_ptr<const Acts::RectangleBounds>
-Acts::CuboidVolumeBounds::faceXYRectangleBounds() const {
-  return std::make_shared<const RectangleBounds>(m_values.at(bv_halfX),
-                                                 m_values.at(bv_halfY));
-}
-
-std::shared_ptr<const Acts::RectangleBounds>
-Acts::CuboidVolumeBounds::faceYZRectangleBounds() const {
-  return std::make_shared<const RectangleBounds>(m_values.at(bv_halfY),
-                                                 m_values.at(bv_halfZ));
-}
-
-std::shared_ptr<const Acts::RectangleBounds>
-Acts::CuboidVolumeBounds::faceZXRectangleBounds() const {
-  return std::make_shared<const RectangleBounds>(m_values.at(bv_halfZ),
-                                                 m_values.at(bv_halfX));
-}
-
-// ostream operator overload
 std::ostream& Acts::CuboidVolumeBounds::toStream(std::ostream& sl) const {
   return dumpT(sl);
 }
@@ -137,8 +108,8 @@ std::ostream& Acts::CuboidVolumeBounds::toStream(std::ostream& sl) const {
 Acts::Volume::BoundingBox Acts::CuboidVolumeBounds::boundingBox(
     const Acts::Transform3D* trf, const Vector3D& envelope,
     const Volume* entity) const {
-  Vector3D vmin(-halflengthX(), -halflengthY(), -halflengthZ());
-  Vector3D vmax(halflengthX(), halflengthY(), halflengthZ());
+  Vector3D vmin(-get(eHalfLengthX), -get(eHalfLengthY), -get(eHalfLengthZ));
+  Vector3D vmax(get(eHalfLengthX), get(eHalfLengthY), get(eHalfLengthZ));
 
   Volume::BoundingBox box(entity, vmin - envelope, vmax + envelope);
   return trf == nullptr ? box : box.transformed(*trf);
diff --git a/Core/src/Geometry/CylinderVolumeBounds.cpp b/Core/src/Geometry/CylinderVolumeBounds.cpp
index 6e0dd1c22..12fc0d7cd 100644
--- a/Core/src/Geometry/CylinderVolumeBounds.cpp
+++ b/Core/src/Geometry/CylinderVolumeBounds.cpp
@@ -24,9 +24,6 @@
 
 const double Acts::CylinderVolumeBounds::s_numericalStable = 10e-2;
 
-Acts::CylinderVolumeBounds::CylinderVolumeBounds()
-    : VolumeBounds(), m_values(4, 0.) {}
-
 Acts::CylinderVolumeBounds::CylinderVolumeBounds(double radius, double halez)
     : VolumeBounds(), m_values(4, 0.) {
   m_values.at(bv_innerRadius) = 0.;
diff --git a/Core/src/Geometry/DoubleTrapezoidVolumeBounds.cpp b/Core/src/Geometry/DoubleTrapezoidVolumeBounds.cpp
deleted file mode 100644
index 9df847635..000000000
--- a/Core/src/Geometry/DoubleTrapezoidVolumeBounds.cpp
+++ /dev/null
@@ -1,287 +0,0 @@
-// This file is part of the Acts project.
-//
-// Copyright (C) 2016-2018 CERN for the benefit of the Acts project
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-///////////////////////////////////////////////////////////////////
-// DoubleTrapezoidVolumeBounds.cpp, Acts project
-///////////////////////////////////////////////////////////////////
-
-#include "Acts/Geometry/DoubleTrapezoidVolumeBounds.hpp"
-
-#include <cmath>
-#include <iomanip>
-#include <iostream>
-#include "Acts/Surfaces/DiamondBounds.hpp"
-#include "Acts/Surfaces/PlaneSurface.hpp"
-#include "Acts/Surfaces/RectangleBounds.hpp"
-
-Acts::DoubleTrapezoidVolumeBounds::DoubleTrapezoidVolumeBounds()
-    : VolumeBounds(), m_values(bv_length, 0.) {}
-
-Acts::DoubleTrapezoidVolumeBounds::DoubleTrapezoidVolumeBounds(
-    double minhalex, double medhalex, double maxhalex, double haley1,
-    double haley2, double halez)
-    : VolumeBounds(), m_values(bv_length, 0.) {
-  m_values.at(bv_minHalfX) = minhalex;
-  m_values.at(bv_medHalfX) = medhalex;
-  m_values.at(bv_maxHalfX) = maxhalex;
-  m_values.at(bv_halfY1) = haley1;
-  m_values.at(bv_halfY2) = haley2;
-  m_values.at(bv_halfZ) = halez;
-  m_values.at(bv_alpha1) =
-      atan2(m_values.at(bv_medHalfX) - m_values.at(bv_minHalfX),
-            2. * m_values.at(bv_halfY1));
-  m_values.at(bv_alpha2) =
-      atan2(m_values.at(bv_medHalfX) - m_values.at(bv_maxHalfX),
-            2. * m_values.at(bv_halfY2));
-}
-
-Acts::DoubleTrapezoidVolumeBounds::DoubleTrapezoidVolumeBounds(
-    const Acts::DoubleTrapezoidVolumeBounds& trabo)
-    : VolumeBounds(), m_values(trabo.m_values) {}
-
-Acts::DoubleTrapezoidVolumeBounds::~DoubleTrapezoidVolumeBounds() = default;
-
-Acts::DoubleTrapezoidVolumeBounds& Acts::DoubleTrapezoidVolumeBounds::operator=(
-    const Acts::DoubleTrapezoidVolumeBounds& trabo) {
-  if (this != &trabo) {
-    m_values = trabo.m_values;
-  }
-  return *this;
-}
-
-std::vector<std::shared_ptr<const Acts::Surface>>
-Acts::DoubleTrapezoidVolumeBounds::decomposeToSurfaces(
-    const Transform3D* transformPtr) const {
-  std::vector<std::shared_ptr<const Surface>> rSurfaces;
-
-  // the transform
-  Transform3D transform =
-      (transformPtr == nullptr) ? Transform3D::Identity() : (*transformPtr);
-
-  // face surfaces xy
-  RotationMatrix3D diamondRotation(transform.rotation());
-  Vector3D diamondX(diamondRotation.col(0));
-  Vector3D diamondY(diamondRotation.col(1));
-  Vector3D diamondZ(diamondRotation.col(2));
-  Vector3D diamondCenter(transform.translation());
-
-  const Transform3D* tTransform = nullptr;
-
-  //   (1) - at negative local z
-  tTransform =
-      new Transform3D(transform * AngleAxis3D(M_PI, Vector3D(0., 1., 0.)) *
-                      Translation3D(Vector3D(0., 0., halflengthZ())));
-  rSurfaces.push_back(Surface::makeShared<PlaneSurface>(
-      std::shared_ptr<const Transform3D>(tTransform),
-      std::shared_ptr<const PlanarBounds>(faceXYDiamondBounds())));
-  //   (2) - at positive local z
-  tTransform = new Transform3D(transform *
-                               Translation3D(Vector3D(0., 0., halflengthZ())));
-  rSurfaces.push_back(Surface::makeShared<PlaneSurface>(
-      std::shared_ptr<const Transform3D>(tTransform),
-      std::shared_ptr<const PlanarBounds>(faceXYDiamondBounds())));
-  // face surfaces yz
-  // transmute cyclical
-  //   (3) - at point A, attached to alpha opening angle
-  Vector3D A(diamondCenter - minHalflengthX() * diamondX -
-             2 * halflengthY1() * diamondY);
-  AngleAxis3D alpha1ZRotation(alpha1(), Vector3D(0., 0., 1.));
-  RotationMatrix3D alpha1Rotation(
-      diamondRotation * alpha1ZRotation *
-      AngleAxis3D(-0.5 * M_PI, Vector3D(0., 1., 0.)) *
-      AngleAxis3D(0.5 * M_PI, Vector3D(0., 0., 1.)));
-  RectangleBounds* faceAlpha1Bounds = faceAlpha1RectangleBounds();
-  Vector3D faceAlpha1Position(A + alpha1Rotation.col(0) *
-                                      faceAlpha1Bounds->halfLengthX());
-  tTransform =
-      new Transform3D(Translation3D(faceAlpha1Position) * alpha1Rotation);
-  rSurfaces.push_back(Surface::makeShared<PlaneSurface>(
-      std::shared_ptr<const Transform3D>(tTransform),
-      std::shared_ptr<const PlanarBounds>(faceAlpha1Bounds)));
-  //   (4) - at point B, attached to beta opening angle
-  Vector3D B(diamondCenter + minHalflengthX() * diamondX -
-             2 * halflengthY1() * diamondY);
-  AngleAxis3D beta1ZRotation(-alpha1(), Vector3D(0., 0., 1.));
-  RotationMatrix3D beta1Rotation(diamondRotation * beta1ZRotation *
-                                 AngleAxis3D(0.5 * M_PI, Vector3D(0., 1., 0.)) *
-                                 AngleAxis3D(0.5 * M_PI, Vector3D(0., 0., 1.)));
-  RectangleBounds* faceBeta1Bounds = faceBeta1RectangleBounds();
-  Vector3D faceBeta1Position(B + beta1Rotation.col(0) *
-                                     faceBeta1Bounds->halfLengthX());
-  tTransform =
-      new Transform3D(Translation3D(faceBeta1Position) * beta1Rotation);
-  rSurfaces.push_back(Surface::makeShared<PlaneSurface>(
-      std::shared_ptr<const Transform3D>(tTransform),
-      std::shared_ptr<const PlanarBounds>(faceBeta1Bounds)));
-  // face surfaces yz
-  // transmute cyclical
-  //   (5) - at point A', attached to alpha opening angle
-  Vector3D AA(diamondCenter - maxHalflengthX() * diamondX +
-              2 * halflengthY2() * diamondY);
-  AngleAxis3D alpha2ZRotation(-alpha2(), Vector3D(0., 0., 1.));
-  RotationMatrix3D alpha2Rotation(
-      diamondRotation * alpha2ZRotation *
-      AngleAxis3D(-0.5 * M_PI, Vector3D(0., 1., 0.)) *
-      AngleAxis3D(-0.5 * M_PI, Vector3D(0., 0., 1.)));
-  RectangleBounds* faceAlpha2Bounds = faceAlpha2RectangleBounds();
-  Vector3D faceAlpha2Position(AA + alpha2Rotation.col(0) *
-                                       faceAlpha2Bounds->halfLengthX());
-  tTransform =
-      new Transform3D(Translation3D(faceAlpha2Position) * alpha2Rotation);
-  rSurfaces.push_back(Surface::makeShared<PlaneSurface>(
-      std::shared_ptr<const Transform3D>(tTransform),
-      std::shared_ptr<const PlanarBounds>(faceAlpha2Bounds)));
-  //   (6) - at point B', attached to beta opening angle
-  Vector3D BB(diamondCenter + maxHalflengthX() * diamondX +
-              2 * halflengthY2() * diamondY);
-  AngleAxis3D beta2ZRotation(alpha2(), Vector3D(0., 0., 1.));
-  RotationMatrix3D beta2Rotation(
-      diamondRotation * beta2ZRotation *
-      AngleAxis3D(0.5 * M_PI, Vector3D(0., 1., 0.)) *
-      AngleAxis3D(-0.5 * M_PI, Vector3D(0., 0., 1.)));
-  RectangleBounds* faceBeta2Bounds = faceBeta2RectangleBounds();
-  Vector3D faceBeta2Position(BB + beta2Rotation.col(0) *
-                                      faceBeta2Bounds->halfLengthX());
-  tTransform =
-      new Transform3D(Translation3D(faceBeta2Position) * beta2Rotation);
-  rSurfaces.push_back(Surface::makeShared<PlaneSurface>(
-      std::shared_ptr<const Transform3D>(tTransform),
-      std::shared_ptr<const PlanarBounds>(faceBeta2Bounds)));
-  // face surfaces zx
-  //   (7) - at negative local y
-  tTransform =
-      new Transform3D(transform * AngleAxis3D(M_PI, Vector3D(1., 0., 0.)) *
-                      Translation3D(Vector3D(0., 2 * halflengthY1(), 0.)) *
-                      AngleAxis3D(-0.5 * M_PI, Vector3D(0., 1., 0.)) *
-                      AngleAxis3D(-0.5 * M_PI, Vector3D(1., 0., 0.)));
-  rSurfaces.push_back(Surface::makeShared<PlaneSurface>(
-      std::shared_ptr<const Transform3D>(tTransform),
-      std::shared_ptr<const PlanarBounds>(faceZXRectangleBoundsBottom())));
-  //   (8) - at positive local y
-  tTransform = new Transform3D(
-      transform * Translation3D(Vector3D(0., 2 * halflengthY2(), 0.)) *
-      AngleAxis3D(-0.5 * M_PI, Vector3D(0., 1., 0.)) *
-      AngleAxis3D(-0.5 * M_PI, Vector3D(1., 0., 0.)));
-  rSurfaces.push_back(Surface::makeShared<PlaneSurface>(
-      std::shared_ptr<const Transform3D>(tTransform),
-      std::shared_ptr<const PlanarBounds>(faceZXRectangleBoundsTop())));
-
-  return rSurfaces;
-}
-
-// faces in xy
-Acts::DiamondBounds* Acts::DoubleTrapezoidVolumeBounds::faceXYDiamondBounds()
-    const {
-  return new DiamondBounds(m_values.at(bv_minHalfX), m_values.at(bv_medHalfX),
-                           m_values.at(bv_maxHalfX), 2 * m_values.at(bv_halfY1),
-                           2 * m_values.at(bv_halfY2));
-}
-
-Acts::RectangleBounds*
-Acts::DoubleTrapezoidVolumeBounds::faceAlpha1RectangleBounds() const {
-  return new RectangleBounds(
-      m_values.at(bv_halfY1) / cos(m_values.at(bv_alpha1)),
-      m_values.at(bv_halfZ));
-}
-
-Acts::RectangleBounds*
-Acts::DoubleTrapezoidVolumeBounds::faceAlpha2RectangleBounds() const {
-  return new RectangleBounds(
-      m_values.at(bv_halfY2) / cos(m_values.at(bv_alpha2)),
-      m_values.at(bv_halfZ));
-}
-
-Acts::RectangleBounds*
-Acts::DoubleTrapezoidVolumeBounds::faceBeta1RectangleBounds() const {
-  return new RectangleBounds(
-      m_values.at(bv_halfY1) / cos(m_values.at(bv_alpha1)),
-      m_values.at(bv_halfZ));
-}
-
-Acts::RectangleBounds*
-Acts::DoubleTrapezoidVolumeBounds::faceBeta2RectangleBounds() const {
-  return new RectangleBounds(
-      m_values.at(bv_halfY2) / cos(m_values.at(bv_alpha2)),
-      m_values.at(bv_halfZ));
-}
-
-Acts::RectangleBounds*
-Acts::DoubleTrapezoidVolumeBounds::faceZXRectangleBoundsBottom() const {
-  return new RectangleBounds(m_values.at(bv_halfZ), m_values.at(bv_minHalfX));
-}
-
-Acts::RectangleBounds*
-Acts::DoubleTrapezoidVolumeBounds::faceZXRectangleBoundsTop() const {
-  return new RectangleBounds(m_values.at(bv_halfZ), m_values.at(bv_maxHalfX));
-}
-
-bool Acts::DoubleTrapezoidVolumeBounds::inside(const Vector3D& pos,
-                                               double tol) const {
-  if (std::abs(pos.z()) > m_values.at(bv_halfZ) + tol) {
-    return false;
-  }
-  if (pos.y() < -2 * m_values.at(bv_halfY1) - tol) {
-    return false;
-  }
-  if (pos.y() > 2 * m_values.at(bv_halfY2) - tol) {
-    return false;
-  }
-  DiamondBounds* faceXYBounds = faceXYDiamondBounds();
-  Vector2D locp(pos.x(), pos.y());
-  bool inside(faceXYBounds->inside(locp, BoundaryCheck(true, true, tol, tol)));
-  delete faceXYBounds;
-  return inside;
-}
-
-// ostream operator overload
-std::ostream& Acts::DoubleTrapezoidVolumeBounds::toStream(
-    std::ostream& sl) const {
-  return dumpT<std::ostream>(sl);
-}
-
-Acts::Volume::BoundingBox Acts::DoubleTrapezoidVolumeBounds::boundingBox(
-    const Transform3D* trf, const Vector3D& envelope,
-    const Volume* entity) const {
-  float minx = minHalflengthX();
-  float medx = medHalflengthX();
-  float maxx = maxHalflengthX();
-  float haley1 = 2 * halflengthY1();
-  float haley2 = 2 * halflengthY2();
-  float halez = halflengthZ();
-
-  std::array<Vector3D, 12> vertices = {{
-      {-minx, -haley1, -halez},
-      {+minx, -haley1, -halez},
-      {+medx, 0, -halez},
-      {-medx, 0, -halez},
-      {-maxx, +haley2, -halez},
-      {+maxx, +haley2, -halez},
-      {-minx, -haley1, +halez},
-      {+minx, -haley1, +halez},
-      {+medx, 0, +halez},
-      {-medx, 0, +halez},
-      {-maxx, +haley2, +halez},
-      {+maxx, +haley2, +halez},
-  }};
-
-  Transform3D transform = Transform3D::Identity();
-  if (trf != nullptr) {
-    transform = *trf;
-  }
-
-  Vector3D vmin = transform * vertices[0];
-  Vector3D vmax = transform * vertices[0];
-
-  for (size_t i = 1; i < 12; i++) {
-    const Vector3D vtx = transform * vertices[i];
-    vmin = vmin.cwiseMin(vtx);
-    vmax = vmax.cwiseMax(vtx);
-  }
-
-  return {entity, vmin - envelope, vmax + envelope};
-}
diff --git a/Tests/UnitTests/Core/Geometry/CMakeLists.txt b/Tests/UnitTests/Core/Geometry/CMakeLists.txt
index 7535c5ce5..0273c7637 100644
--- a/Tests/UnitTests/Core/Geometry/CMakeLists.txt
+++ b/Tests/UnitTests/Core/Geometry/CMakeLists.txt
@@ -1,11 +1,11 @@
 add_unittest(AlignmentContextTests AlignmentContextTests.cpp)
+add_unittest(CuboidVolumeBoundsTests CuboidVolumeBoundsTests.cpp)
 add_unittest(CuboidVolumeBuilderTests CuboidVolumeBuilderTests.cpp)
 add_unittest(CutoutCylinderVolumeBoundsTests CutoutCylinderVolumeBoundsTests.cpp)
 add_unittest(CylinderLayerTests CylinderLayerTests.cpp)
 add_unittest(CylinderVolumeBoundsTests CylinderVolumeBoundsTests.cpp)
 add_unittest(CylinderVolumeBuilderTests CylinderVolumeBuilderTests.cpp)
 add_unittest(DiscLayerTests DiscLayerTests.cpp)
-add_unittest(DoubleTrapezoidVolumeBoundsTests DoubleTrapezoidVolumeBoundsTests.cpp)
 add_unittest(ExtentTests ExtentTests.cpp)
 add_unittest(GenericApproachDescriptorTests GenericApproachDescriptorTests.cpp)
 add_unittest(GenericCuboidVolumeBoundsTests GenericCuboidVolumeBoundsTests.cpp)
diff --git a/Tests/UnitTests/Core/Geometry/CuboidVolumeBoundsTests.cpp b/Tests/UnitTests/Core/Geometry/CuboidVolumeBoundsTests.cpp
new file mode 100644
index 000000000..b3b3da779
--- /dev/null
+++ b/Tests/UnitTests/Core/Geometry/CuboidVolumeBoundsTests.cpp
@@ -0,0 +1,90 @@
+// This file is part of the Acts project.
+//
+// Copyright (C) 2019 CERN for the benefit of the Acts project
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <boost/test/unit_test.hpp>
+
+#include "Acts/Geometry/CuboidVolumeBounds.hpp"
+#include "Acts/Geometry/GeometryContext.hpp"
+#include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
+#include "Acts/Utilities/Definitions.hpp"
+
+namespace Acts {
+namespace Test {
+
+GeometryContext gctx = GeometryContext();
+
+double hx{10.}, hy{20.}, hz{30.};
+
+BOOST_AUTO_TEST_SUITE(Geometry)
+
+BOOST_AUTO_TEST_CASE(CuboidVolumeConstruction) {
+  // Test Construction
+  CuboidVolumeBounds box(hx, hy, hz);
+
+  // Test copy construction
+  CuboidVolumeBounds copied(box);
+  BOOST_CHECK_EQUAL(box, copied);
+
+  // Test assigned
+  CuboidVolumeBounds assigned = box;
+  BOOST_CHECK_EQUAL(box, assigned);
+}
+
+BOOST_AUTO_TEST_CASE(CuboidVolumeRecreation) {
+  CuboidVolumeBounds original(hx, hy, hz);
+  auto valvector = original.values();
+  std::array<double, CuboidVolumeBounds::eSize> values;
+  std::copy_n(valvector.begin(), CuboidVolumeBounds::eSize, values.begin());
+  CuboidVolumeBounds recreated(values);
+  BOOST_CHECK_EQUAL(original, recreated);
+}
+
+BOOST_AUTO_TEST_CASE(CuboidVolumeException) {
+  // Test exception negative x
+  BOOST_CHECK_THROW(CuboidVolumeBounds(-hx, hy, hz), std::logic_error);
+
+  // Test exception negative y
+  BOOST_CHECK_THROW(CuboidVolumeBounds(hx, -hy, hz), std::logic_error);
+
+  // Test exception negative z
+  BOOST_CHECK_THROW(CuboidVolumeBounds(hx, hy, -hz), std::logic_error);
+}
+
+BOOST_AUTO_TEST_CASE(CuboidVolumeProperties) {
+  CuboidVolumeBounds box(hx, hy, hz);
+  // Test the type
+  BOOST_TEST(box.type() == VolumeBounds::eCuboid);
+  // Test the halflength x
+  CHECK_CLOSE_ABS(box.get(CuboidVolumeBounds::eHalfLengthX), hx, s_epsilon);
+  // Test the halflength y
+  CHECK_CLOSE_ABS(box.get(CuboidVolumeBounds::eHalfLengthY), hy, s_epsilon);
+  // Test the halflength z
+  CHECK_CLOSE_ABS(box.get(CuboidVolumeBounds::eHalfLengthZ), hz, s_epsilon);
+  // Test the streaming
+  std::vector<double> refvalues = {hx, hy, hz};
+  BOOST_TEST(box.values() == refvalues);
+
+  // Inside position
+  Vector3D inside({5., 10., 8.});
+  // Outside positions  in x, y, z
+  std::vector<Vector3D> outsides = {
+      {20., 1., -2.}, {1., -30., 2.}, {-1., 2., 100.}};
+
+  // Inside position
+  BOOST_TEST(box.inside(inside, s_onSurfaceTolerance));
+
+  // Outside position
+  for (const auto& outside : outsides) {
+    BOOST_TEST(!box.inside(outside, s_onSurfaceTolerance));
+  }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+}  // namespace Test
+}  // namespace Acts
diff --git a/Tests/UnitTests/Core/Geometry/DoubleTrapezoidVolumeBoundsTests.cpp b/Tests/UnitTests/Core/Geometry/DoubleTrapezoidVolumeBoundsTests.cpp
deleted file mode 100644
index 78e69b8f7..000000000
--- a/Tests/UnitTests/Core/Geometry/DoubleTrapezoidVolumeBoundsTests.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-// This file is part of the Acts project.
-//
-// Copyright (C) 2019 CERN for the benefit of the Acts project
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#include <boost/test/unit_test.hpp>
-
-#include "Acts/Geometry/DoubleTrapezoidVolumeBounds.hpp"
-#include "Acts/Surfaces/PlanarBounds.hpp"
-#include "Acts/Surfaces/PlaneSurface.hpp"
-#include "Acts/Surfaces/Surface.hpp"
-#include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
-#include "Acts/Utilities/BoundingBox.hpp"
-#include "Acts/Utilities/Definitions.hpp"
-
-namespace tt = boost::test_tools;
-
-namespace Acts {
-
-namespace Test {
-BOOST_AUTO_TEST_SUITE(Volumes)
-
-BOOST_AUTO_TEST_CASE(bounding_box_creation) {
-  float tol = 1e-4;
-
-  DoubleTrapezoidVolumeBounds dtvb(5, 10, 8, 4, 7, 3);
-
-  auto bb = dtvb.boundingBox();
-  CHECK_CLOSE_ABS(bb.max(), Vector3D(10, 14, 3), tol);
-  CHECK_CLOSE_ABS(bb.min(), Vector3D(-10, -8, -3), tol);
-
-  Transform3D trf;
-
-  trf = Translation3D(Vector3D(0, 30, 20));
-
-  bb = dtvb.boundingBox(&trf);
-  CHECK_CLOSE_ABS(bb.max(), Vector3D(10, 44, 23), tol);
-  CHECK_CLOSE_ABS(bb.min(), Vector3D(-10, 22, 17), tol);
-
-  trf = AngleAxis3D(M_PI / 2., Vector3D(-2, 4, 5).normalized());
-
-  bb = dtvb.boundingBox(&trf);
-  CHECK_CLOSE_ABS(bb.max(), Vector3D(8.9517, 11.7462, 10.263), tol);
-  CHECK_CLOSE_ABS(bb.min(), Vector3D(-14.7572, -7.9101, -9.85174), tol);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-
-}  // namespace Test
-
-}  // namespace Acts
-- 
GitLab