diff --git a/Core/include/ACTS/Digitization/CartesianSegmentation.hpp b/Core/include/ACTS/Digitization/CartesianSegmentation.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..787bee5ba5916f386caa9a5e67a30728e7219f67
--- /dev/null
+++ b/Core/include/ACTS/Digitization/CartesianSegmentation.hpp
@@ -0,0 +1,154 @@
+// This file is part of the ACTS project.
+//
+// Copyright (C) 2016 ACTS project team
+//
+// 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/.
+
+#ifndef ACTS_DIGITIZATION_CARTESIANSEGMENTATION_H
+#define ACTS_DIGITIZATION_CARTESIANSEGMENTATION_H
+
+#include <memory>
+#include "ACTS/Digitization/DigitizationCell.hpp"
+#include "ACTS/Digitization/Segmentation.hpp"
+#include "ACTS/Surfaces/PlanarBounds.hpp"
+#include "ACTS/Utilities/BinUtility.hpp"
+#include "ACTS/Utilities/Definitions.hpp"
+
+namespace Acts {
+
+/// @brief Segmentation Base class
+///
+/// Segementation class for generic pixel, strixels and strip segmentations 
+/// in a cartesian frame, this uses a cartesian X/Y local surface definition  
+/// 
+/// The calculation can be done in full 3D, i.e. the segments of the path through
+/// the planar module are calculated in a 3D model - or in 2D, when the entire 
+/// calculation is done on the projective surface. When the 2D option is used,
+/// segmentation surfaces are not created. The 2D calculation is faster and uses
+/// less memory, however, effects witin the sensor volume can not be easily integrated  
+///
+/// Conventions:
+///   - 3D positions are within the 3D frame of the module
+///   - 2D positions are corrected to the readout surface
+///     they need to be corrected by the lorentzShift
+///     for the parameter surface in the center of the surface)
+///
+class CartesianSegmentation : public Segmentation
+{
+public:
+  /// Constructor for all same-size pixels or strips 
+  /// (in cas numCellsY is set to 1)
+  ///
+  /// @param rBounds are the rectangle bounds of the sensitive volume
+  /// @param numCellsX is the number of cells in X 
+  /// @param numCellsY is the number of cells in Y
+  CartesianSegmentation(std::shared_ptr<const PlanarBounds> rBounds,
+                        size_t numCellsX,
+                        size_t numCellsY = 1);
+
+  /// @todo contructor from BinUtilities for more complex readouts
+  /// 
+  /// @param bUtility is the bin Utility, 
+  //  it will define the RectangleBounds if none are provided
+  /// @param rBounds are the rectangle bounds if provided for memory optimisation
+  ///
+  /// @note if both RectangleBounds and BinUtility are provided, no check is done
+  /// for consitency
+  CartesianSegmentation(std::shared_ptr<BinUtility> bUtility,
+                        std::shared_ptr<const PlanarBounds> rBounds = nullptr);
+                            
+  /// Virtual Destructor 
+  virtual ~CartesianSegmentation();
+
+  /// @copydoc Acts::Segmentation::createSegmentationSurfaces
+  ///
+  /// Create the segmentation surfaces in X and Y for rectangular shapes
+  /// These are needed for a full three dimensional module 
+  void
+  createSegmentationSurfaces(SurfacePtrVector& boundarySurfaces,
+                             SurfacePtrVector& segmentationSurfacesX,
+                             SurfacePtrVector& segmentationSurfacesY,
+                             double            halfThickness,
+                             int               readoutDirection = 1.,
+                             double lorentzAngle = 0.) const final;
+
+  /// @copydoc Segmentation::cell
+  const DigitizationCell
+  cell(const Vector3D& position) const final;
+
+  /// @copydoc Segmentation::cell
+  const DigitizationCell
+  cell(const Vector2D& position) const final;
+
+  /// @copydoc Segmentation::cellPosition
+  const Vector2D
+  cellPosition(const DigitizationCell& cId) const final;
+
+  /// Fill the associated digitsation cell from this start and end position
+  /// correct for lorentz effect if needed
+  ///
+  /// @copydoc Segmentation::digitizationStep
+  const DigitizationStep
+  digitizationStep(const Vector3D& start,
+                   const Vector3D& end,
+                   double          halfThickness,
+                   int             readoutDirection = 1,
+                   double          lorentzAngle     = 0.) const final;
+
+  /// return the surface bounds by reference
+  /// specialization for Rectangle Bounds
+  const PlanarBounds&
+  moduleBounds() const final;
+  
+  /// return the bin utility that defines the
+  /// readout segmentation 
+  const BinUtility&
+  binUtility() const final;
+
+private:
+  template <class T>
+  const DigitizationCell
+  cellT(const T& position) const;
+
+  std::shared_ptr<const PlanarBounds> m_activeBounds;  /// active area size
+  std::shared_ptr<BinUtility>         m_binUtility;    /// bin Utility
+  
+};
+
+inline const PlanarBounds&
+CartesianSegmentation::moduleBounds() const
+{
+  return (*(m_activeBounds.get()));
+}
+
+inline const BinUtility&
+CartesianSegmentation::binUtility() const
+{
+    return (*(m_binUtility.get()));
+}
+
+
+template <class T>
+const DigitizationCell
+CartesianSegmentation::cellT(const T& position) const
+{
+  return DigitizationCell(m_binUtility->bin(position, 0),
+                          m_binUtility->bin(position, 1));
+}
+
+inline const DigitizationCell
+CartesianSegmentation::cell(const Vector3D& position) const
+{
+  return cellT<Vector3D>(position);
+}
+
+inline const DigitizationCell
+CartesianSegmentation::cell(const Vector2D& position) const
+{
+  return cellT<Vector2D>(position);
+}
+}
+
+#endif
diff --git a/Core/include/ACTS/Digitization/DigitizationModule.hpp b/Core/include/ACTS/Digitization/DigitizationModule.hpp
index 0bf83c2ab936fb04ae7cf5b60308b0ad4f6dc244..91e8dd89b4456069ab4c01d9a4973246fb6235b6 100644
--- a/Core/include/ACTS/Digitization/DigitizationModule.hpp
+++ b/Core/include/ACTS/Digitization/DigitizationModule.hpp
@@ -24,16 +24,13 @@ typedef std::vector<SurfacePtr>        SurfacePtrVector;
 ///
 /// Class that holds the surfaces for a planar digitization detector module.
 ///
-/// It needs a descriptor to design different pixel/strixels/strip setups (with
-/// a segmentation class)
+/// It needs a descriptor to design different pixel/strixels/strip setups 
+/// (with a segmentation class) in order to define the readout segmentation
 ///
-/// The digitizaiton is done in the local frame of the surface and binning can
-/// be done
-/// in local x and local y direction.
+/// The digitizaiton is done in the local frame of the surface.
 ///
 /// The lorentz angle is assumed to be only in x-direction and constant for the
-/// module,
-/// it is measured from the local z-direction towards the local x-direction.
+/// module, it is measured from the local z-direction towards the local x-direction.
 ///
 /// The readout direction defines the charge drift either:
 /// a) towards the surface at -halfThickness if readout is defined at -1
@@ -121,10 +118,9 @@ public:
   segmentationSurfacesY() const;
 
 private:
-  double m_halfThickness;
-  int m_readoutDirection;  ///< defines if the readout is along (+1) / (-1) wrt
-                           /// the z axis
-  double m_lorentzAngle;   ///< the lorentz angle
+  double m_halfThickness;    ///< half thickness of the module
+  int m_readoutDirection;    ///< readout is along (+1) / (-1) wrt local z axis
+  double m_lorentzAngle;     ///< the lorentz angle
   double m_tanLorentzAngle;  ///< and the tangent of it
 
   std::shared_ptr<const Segmentation>
diff --git a/Core/include/ACTS/Digitization/PolarSegmentation.hpp b/Core/include/ACTS/Digitization/PolarSegmentation.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..1c1f40b6702f9df90065fcbe5dd21c2d7711c4d7
--- /dev/null
+++ b/Core/include/ACTS/Digitization/PolarSegmentation.hpp
@@ -0,0 +1,199 @@
+// This file is part of the ACTS project.
+//
+// Copyright (C) 2016 ACTS project team
+//
+// 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/.
+
+// #ifndef ACTS_DIGITIZATION_POLARSEGMENTATION_H
+// #define ACTS_DIGITIZATION_POLARSEGMENTATION_H
+// 
+// #include <memory>
+// #include "ACTS/Digitization/DigitizationCell.hpp"
+// #include "ACTS/Digitization/Segmentation.hpp"
+// #include "ACTS/Surfaces/TrapezoidBounds.hpp"
+// #include "ACTS/Utilities/BinUtility.hpp"
+// #include "ACTS/Utilities/Definitions.hpp"
+
+// namespace Acts {
+// 
+// /// @class TrapezoidSegmentation class
+// ///
+// ///  Segementation class for generic pixel, strixels and strip segmentations on
+// ///  a trapezoidal shape
+// ///
+// ///  Conventions:
+// ///    - 3D positions are within the 3D frame of the module
+// ///    - 2D positions are corrected to the readout surface
+// ///      (the lorentzShift is not taken into account fro trapezoidal elements
+// ///      yet @TODO)
+// ///
+// class TrapezoidSegmentation : public Segmentation
+// {
+// public:
+//   /// Constructor for all same-size pixels or strips
+//   // (in case numCellsY is set to 1)/
+//   TrapezoidSegmentation(std::shared_ptr<const TrapezoidBounds>,
+//                         size_t numCellsX,
+//                         size_t numCellsY = 1);
+// 
+//   /// TODO contructor from BinUtilities for more complex readouts
+// 
+//   /// Virtual Destructor
+//   virtual ~TrapezoidSegmentation();
+// 
+//   /// @copydoc Acts::Segmentation::createSegmentationSurfaces
+//   void
+//   createSegmentationSurfaces(SurfacePtrVector& boundarySurfaces,
+//                              SurfacePtrVector& segmentationSurfacesX,
+//                              SurfacePtrVector& segmentationSurfacesY,
+//                              double            halfThickness,
+//                              int               readoutDirection = 1.,
+//                              double            lorentzAngle = 0.) const override;
+// 
+//   /// @copydoc Segmentation::cell
+//   const DigitizationCell
+//   cell(const Vector3D& position) const override;
+// 
+//   /// @copydoc Segmentation::cell
+//   const DigitizationCell
+//   cell(const Vector2D& position) const override;
+// 
+//   /// @copydoc Segmentation::cellPosition
+//   const Vector2D
+//   cellPosition(const DigitizationCell& cId) const override;
+// 
+//   /// @copydoc Segmentation::digitizationStep
+//   const DigitizationStep
+//   digitizationStep(const Vector3D& start,
+//                    const Vector3D& end,
+//                    double          halfThickness,
+//                    int             readoutDirection = 1,
+//                    double          lorentzAngle     = 0.) const override;
+// 
+//   /// return the surface bounds by reference
+//   /// specification for TrapezoidBounds
+//   const TrapezoidBounds&
+//   moduleBounds() const override;
+// 
+//   /// Return the simple binning parameters
+//   size_t
+//   numCellsX() const;
+// 
+//   /// Return the simple binning parameters
+//   size_t
+//   numCellsY() const;
+// 
+// private:
+//   /// private helper method - templated
+//   template <class T>
+//   const DigitizationCell
+//   cellT(const T& position) const;
+// 
+//   /// Return the local pitch X at Y
+//   double
+//   PitchX(const Vector2D& localPos) const;
+// 
+//   /// Return the local sinStereo
+//   double
+//   sinStereoLocal(const Vector2D& localPos) const;
+// 
+//   /// Return the projected x value on the y=0
+//   double
+//   projectLocX(const Vector2D& localPos) const;
+// 
+//   /// Return the radius correponding to the given module
+//   double
+//   radius() const;
+// 
+//   std::shared_ptr<const TrapezoidBounds> m_activeBounds;
+//   std::unique_ptr<BinUtility>            m_binUtility;
+//   size_t                                 m_binsX;
+//   size_t                                 m_binsY;
+// };
+// 
+// inline const TrapezoidBounds&
+// TrapezoidSegmentation::moduleBounds() const
+// {
+//   return (*(m_activeBounds.get()));
+// }
+// 
+// inline size_t
+// TrapezoidSegmentation::numCellsX() const
+// {
+//   return m_binsX;
+// }
+// 
+// inline size_t
+// TrapezoidSegmentation::numCellsY() const
+// {
+//   return m_binsY;
+// }
+// 
+// template <class T>
+// const DigitizationCell
+// TrapezoidSegmentation::cellT(const T& position) const
+// {
+//   if (m_binsX == 1)
+//     return DigitizationCell(0, m_binUtility->bin(position, 0));
+//   else if (m_binsY == 1)
+//     return DigitizationCell(m_binUtility->bin(position, 0), 0);
+//   return DigitizationCell(m_binUtility->bin(position, 0),
+//                           m_binUtility->bin(position, 1));
+// }
+// 
+// inline const DigitizationCell
+// TrapezoidSegmentation::cell(const Vector3D& position) const
+// {
+//   Vector3D CorrPosition = position;
+//   CorrPosition.x() = projectLocX(Vector2D(CorrPosition.x(), CorrPosition.y()));
+//   return cellT<Vector3D>(CorrPosition);
+// }
+// 
+// inline const DigitizationCell
+// TrapezoidSegmentation::cell(const Vector2D& position) const
+// {
+//   Vector2D corrPosition = position;
+//   corrPosition[0] = projectLocX(Vector2D(corrPosition[0], corrPosition[1]));
+//   return cellT<Vector2D>(corrPosition);
+// }
+// 
+// double
+// TrapezoidSegmentation::radius() const
+// {
+//   return m_activeBounds->halflengthY()
+//       / (m_activeBounds->maxHalflengthX() - m_activeBounds->minHalflengthX())
+//       * (m_activeBounds->maxHalflengthX() + m_activeBounds->minHalflengthX());
+// }
+// 
+// double
+// TrapezoidSegmentation::sinStereoLocal(const Vector2D& localPos) const
+// {
+//   double oneOverRadius = 1. / radius();
+//   double x             = localPos.x();
+//   double y             = localPos.y();
+//   return -x * oneOverRadius
+//       / sqrt((1 + y * oneOverRadius) * (1 + y * oneOverRadius)
+//              + x * oneOverRadius * x * oneOverRadius);
+// }
+// 
+// double
+// TrapezoidSegmentation::PitchX(const Vector2D& localPos) const
+// {
+//   double tanPhi
+//       = (m_activeBounds->maxHalflengthX() - m_activeBounds->minHalflengthX())
+//       / m_activeBounds->halflengthY();
+//   double lengthXatHit = (radius() + localPos[1]) * tanPhi;
+//   return lengthXatHit / float(m_binsX);
+// }
+// 
+// double
+// TrapezoidSegmentation::projectLocX(const Vector2D& localPos) const
+// {
+//   return -radius() * tan(asin(sinStereoLocal(localPos)));
+// }
+// }
+// 
+// #endif
+// 
\ No newline at end of file
diff --git a/Core/include/ACTS/Digitization/RectangularSegmentation.hpp b/Core/include/ACTS/Digitization/RectangularSegmentation.hpp
deleted file mode 100644
index 4aef25d59185a933e0759b821f435375109bb222..0000000000000000000000000000000000000000
--- a/Core/include/ACTS/Digitization/RectangularSegmentation.hpp
+++ /dev/null
@@ -1,147 +0,0 @@
-// This file is part of the ACTS project.
-//
-// Copyright (C) 2016 ACTS project team
-//
-// 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/.
-
-#ifndef ACTS_DIGITIZATION_RECTANGULARSEGMENTATION_H
-#define ACTS_DIGITIZATION_RECTANGULARSEGMENTATION_H
-
-#include <memory>
-#include "ACTS/Digitization/DigitizationCell.hpp"
-#include "ACTS/Digitization/Segmentation.hpp"
-#include "ACTS/Surfaces/RectangleBounds.hpp"
-#include "ACTS/Utilities/BinUtility.hpp"
-#include "ACTS/Utilities/Definitions.hpp"
-
-namespace Acts {
-
-/// @brief Segmentation Base class
-///
-/// Segementation class for generic pixel, strixels and strip segmentations on a
-/// rectangle shape
-///
-/// Conventions:
-///   - 3D positions are within the 3D frame of the module
-///   - 2D positions are corrected to the readout surface
-///     they need to be corrected by the lorentzShift
-///     for the parameter surface in the center of the surface)
-///
-class RectangularSegmentation : public Segmentation
-{
-public:
-  /// Constructor for all same-size pixels or strips (in cas numCellsY is set to
-  /// 1)
-  RectangularSegmentation(std::shared_ptr<const RectangleBounds>,
-                          size_t numCellsX,
-                          size_t numCellsY = 1);
-
-  /// @todo contructor from BinUtilities for more complex readouts
-
-  /// Virtual Destructor */
-  virtual ~RectangularSegmentation();
-
-  /// @copydoc Acts::Segmentation::createSegmentationSurfaces
-  ///
-  /// Create the segmentation surfaces in X and Y for rectangular shapes
-  void
-  createSegmentationSurfaces(SurfacePtrVector& boundarySurfaces,
-                             SurfacePtrVector& segmentationSurfacesX,
-                             SurfacePtrVector& segmentationSurfacesY,
-                             double            halfThickness,
-                             int               readoutDirection = 1.,
-                             double lorentzAngle = 0.) const override;
-
-  /// @copydoc Segmentation::cell
-  const DigitizationCell
-  cell(const Vector3D& position) const override;
-
-  /// @copydoc Segmentation::cell
-  const DigitizationCell
-  cell(const Vector2D& position) const override;
-
-  /// @copydoc Segmentation::cellPosition
-  const Vector2D
-  cellPosition(const DigitizationCell& cId) const override;
-
-  /// Fill the associated digitsation cell from this start and end positio
-  /// correct for lorentz effect if needed
-  ///
-  /// @copydoc Segmentation::digitizationStep
-  const DigitizationStep
-  digitizationStep(const Vector3D& start,
-                   const Vector3D& end,
-                   double          halfThickness,
-                   int             readoutDirection = 1,
-                   double          lorentzAngle     = 0.) const override;
-
-  /// return the surface bounds by reference
-  /// specialization for Rectangle Bounds
-  const RectangleBounds&
-  moduleBounds() const override;
-
-  /// Return the simple binning parameters
-  size_t
-  numCellsX() const;
-
-  /// Return the simple binning parameters
-  size_t
-  numCellsY() const;
-
-private:
-  template <class T>
-  const DigitizationCell
-  cellT(const T& position) const;
-
-  std::shared_ptr<const RectangleBounds> m_activeBounds;  /// active area size
-  std::unique_ptr<BinUtility>            m_binUtility;    /// bin Utility
-  size_t                                 m_binsX;  /// number of bins in X
-  size_t                                 m_binsY;  /// number of bins in Y
-};
-
-inline const RectangleBounds&
-RectangularSegmentation::moduleBounds() const
-{
-  return (*(m_activeBounds.get()));
-}
-
-inline size_t
-RectangularSegmentation::numCellsX() const
-{
-  return m_binsX;
-}
-
-inline size_t
-RectangularSegmentation::numCellsY() const
-{
-  return m_binsY;
-}
-
-template <class T>
-const DigitizationCell
-RectangularSegmentation::cellT(const T& position) const
-{
-  if (m_binsX == 1)
-    return DigitizationCell(0, m_binUtility->bin(position, 0));
-  else if (m_binsY == 1)
-    return DigitizationCell(m_binUtility->bin(position, 0), 0);
-  return DigitizationCell(m_binUtility->bin(position, 0),
-                          m_binUtility->bin(position, 1));
-}
-
-inline const DigitizationCell
-RectangularSegmentation::cell(const Vector3D& position) const
-{
-  return cellT<Vector3D>(position);
-}
-
-inline const DigitizationCell
-RectangularSegmentation::cell(const Vector2D& position) const
-{
-  return cellT<Vector2D>(position);
-}
-}
-
-#endif
diff --git a/Core/include/ACTS/Digitization/Segmentation.hpp b/Core/include/ACTS/Digitization/Segmentation.hpp
index c2dae28c9610e057cdd9a9a37d75fc6bfe061f66..b17d37037089e94ae2913da1689de5267f4ffdfd 100644
--- a/Core/include/ACTS/Digitization/Segmentation.hpp
+++ b/Core/include/ACTS/Digitization/Segmentation.hpp
@@ -18,6 +18,7 @@ namespace Acts {
 
 class SurfaceBounds;
 class Surface;
+class BinUtility;
 typedef std::shared_ptr<const Surface> SurfacePtr;
 typedef std::vector<SurfacePtr>        SurfacePtrVector;
 
@@ -29,18 +30,20 @@ typedef std::vector<SurfacePtr>        SurfacePtrVector;
 /// module
 ///
 /// Since the segmentation description might be identical for many elements
-/// while
-/// the lorentz angle may change, lorentzAngle and readoutDirection are provided
-/// and th the segmenation class only creates the surfaces for the module, but
-/// hosts the binning information.
+/// while the lorentz angle may change, lorentzAngle and readoutDirection 
+/// are provided and th the segmenation class only creates the surfaces for the module,
+/// but hosts the binning information.
 ///
 class Segmentation
 {
 public:
   /// Virtual Destructor
   virtual ~Segmentation() {}
+  
   /// Create the segmentation surfaces in X
   ///
+  /// This method is only used if the full 3D digitization is done
+  ///
   /// @param boundarySurfaces vector to be filled
   /// @param segmentationSurfacesX are the segmetation boundaries in X
   /// @param segmentationSurfacesY are the segmetation boundaries in Y
@@ -100,9 +103,14 @@ public:
                    int             readoutDirection,
                    double          lorentzAngle) const = 0;
 
-  // return the surface bounds by reference
+  /// return the surface bounds by reference
   virtual const SurfaceBounds&
   moduleBounds() const = 0;
+  
+  /// return the bin utility that defines the readout
+  virtual const BinUtility&
+  binUtility() const = 0;
+  
 };
 }  // end of namespace Acts
 
diff --git a/Core/include/ACTS/Digitization/TrapezoidSegmentation.hpp b/Core/include/ACTS/Digitization/TrapezoidSegmentation.hpp
deleted file mode 100644
index bbf6e7172865be0425bd8c1c58e45a38ffa735b1..0000000000000000000000000000000000000000
--- a/Core/include/ACTS/Digitization/TrapezoidSegmentation.hpp
+++ /dev/null
@@ -1,198 +0,0 @@
-// This file is part of the ACTS project.
-//
-// Copyright (C) 2016 ACTS project team
-//
-// 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/.
-
-#ifndef ACTS_DIGITIZATION_TRAPEZOIDSEGMENTATION_H
-#define ACTS_DIGITIZATION_TRAPEZOIDSEGMENTATION_H
-
-#include <memory>
-#include "ACTS/Digitization/DigitizationCell.hpp"
-#include "ACTS/Digitization/Segmentation.hpp"
-#include "ACTS/Surfaces/TrapezoidBounds.hpp"
-#include "ACTS/Utilities/BinUtility.hpp"
-#include "ACTS/Utilities/Definitions.hpp"
-
-namespace Acts {
-
-///* @class Segmentation Base class
-///
-///  Segementation class for generic pixel, strixels and strip segmentations on
-///  a trapezoidal shape
-///
-///  Conventions:
-///    - 3D positions are within the 3D frame of the module
-///    - 2D positions are corrected to the readout surface
-///      (the lorentzShift is not taken into account fro trapezoidal elements
-///      yet @TODO)
-///
-class TrapezoidSegmentation : public Segmentation
-{
-public:
-  /// Constructor for all same-size pixels or strips
-  // (in case numCellsY is set to 1)/
-  TrapezoidSegmentation(std::shared_ptr<const TrapezoidBounds>,
-                        size_t numCellsX,
-                        size_t numCellsY = 1);
-
-  /// TODO contructor from BinUtilities for more complex readouts
-
-  /// Virtual Destructor
-  virtual ~TrapezoidSegmentation();
-
-  /// @copydoc Acts::Segmentation::createSegmentationSurfaces
-  void
-  createSegmentationSurfaces(SurfacePtrVector& boundarySurfaces,
-                             SurfacePtrVector& segmentationSurfacesX,
-                             SurfacePtrVector& segmentationSurfacesY,
-                             double            halfThickness,
-                             int               readoutDirection = 1.,
-                             double lorentzAngle = 0.) const override;
-
-  /// @copydoc Segmentation::cell
-  const DigitizationCell
-  cell(const Vector3D& position) const override;
-
-  /// @copydoc Segmentation::cell
-  const DigitizationCell
-  cell(const Vector2D& position) const override;
-
-  /// @copydoc Segmentation::cellPosition
-  const Vector2D
-  cellPosition(const DigitizationCell& cId) const override;
-
-  /// @copydoc Segmentation::digitizationStep
-  const DigitizationStep
-  digitizationStep(const Vector3D& start,
-                   const Vector3D& end,
-                   double          halfThickness,
-                   int             readoutDirection = 1,
-                   double          lorentzAngle     = 0.) const override;
-
-  /// return the surface bounds by reference
-  /// specification for TrapezoidBounds
-  const TrapezoidBounds&
-  moduleBounds() const override;
-
-  /// Return the simple binning parameters
-  size_t
-  numCellsX() const;
-
-  /// Return the simple binning parameters
-  size_t
-  numCellsY() const;
-
-private:
-  /// private helper method - templated
-  template <class T>
-  const DigitizationCell
-  cellT(const T& position) const;
-
-  /// Return the local pitch X at Y
-  double
-  PitchX(const Vector2D& localPos) const;
-
-  /// Return the local sinStereo
-  double
-  sinStereoLocal(const Vector2D& localPos) const;
-
-  /// Return the projected x value on the y=0
-  double
-  projectLocX(const Vector2D& localPos) const;
-
-  /// Return the radius correponding to the given module
-  double
-  radius() const;
-
-  std::shared_ptr<const TrapezoidBounds> m_activeBounds;
-  std::unique_ptr<BinUtility>            m_binUtility;
-  size_t                                 m_binsX;
-  size_t                                 m_binsY;
-};
-
-inline const TrapezoidBounds&
-TrapezoidSegmentation::moduleBounds() const
-{
-  return (*(m_activeBounds.get()));
-}
-
-inline size_t
-TrapezoidSegmentation::numCellsX() const
-{
-  return m_binsX;
-}
-
-inline size_t
-TrapezoidSegmentation::numCellsY() const
-{
-  return m_binsY;
-}
-
-template <class T>
-const DigitizationCell
-TrapezoidSegmentation::cellT(const T& position) const
-{
-  if (m_binsX == 1)
-    return DigitizationCell(0, m_binUtility->bin(position, 0));
-  else if (m_binsY == 1)
-    return DigitizationCell(m_binUtility->bin(position, 0), 0);
-  return DigitizationCell(m_binUtility->bin(position, 0),
-                          m_binUtility->bin(position, 1));
-}
-
-inline const DigitizationCell
-TrapezoidSegmentation::cell(const Vector3D& position) const
-{
-  Vector3D CorrPosition = position;
-  CorrPosition.x() = projectLocX(Vector2D(CorrPosition.x(), CorrPosition.y()));
-  return cellT<Vector3D>(CorrPosition);
-}
-
-inline const DigitizationCell
-TrapezoidSegmentation::cell(const Vector2D& position) const
-{
-  Vector2D corrPosition = position;
-  corrPosition[0] = projectLocX(Vector2D(corrPosition[0], corrPosition[1]));
-  return cellT<Vector2D>(corrPosition);
-}
-
-double
-TrapezoidSegmentation::radius() const
-{
-  return m_activeBounds->halflengthY()
-      / (m_activeBounds->maxHalflengthX() - m_activeBounds->minHalflengthX())
-      * (m_activeBounds->maxHalflengthX() + m_activeBounds->minHalflengthX());
-}
-
-double
-TrapezoidSegmentation::sinStereoLocal(const Vector2D& localPos) const
-{
-  double oneOverRadius = 1. / radius();
-  double x             = localPos.x();
-  double y             = localPos.y();
-  return -x * oneOverRadius
-      / sqrt((1 + y * oneOverRadius) * (1 + y * oneOverRadius)
-             + x * oneOverRadius * x * oneOverRadius);
-}
-
-double
-TrapezoidSegmentation::PitchX(const Vector2D& localPos) const
-{
-  double tanPhi
-      = (m_activeBounds->maxHalflengthX() - m_activeBounds->minHalflengthX())
-      / m_activeBounds->halflengthY();
-  double lengthXatHit = (radius() + localPos[1]) * tanPhi;
-  return lengthXatHit / float(m_binsX);
-}
-
-double
-TrapezoidSegmentation::projectLocX(const Vector2D& localPos) const
-{
-  return -radius() * tan(asin(sinStereoLocal(localPos)));
-}
-}
-
-#endif
diff --git a/Core/include/ACTS/EventData/ParticleDefinitions.hpp b/Core/include/ACTS/EventData/ParticleDefinitions.hpp
index 00d251555544962ddea299a23aa1ed0d7336d5a8..07868b8a44e175a8d3a98e72a10fe05dc71b4076 100644
--- a/Core/include/ACTS/EventData/ParticleDefinitions.hpp
+++ b/Core/include/ACTS/EventData/ParticleDefinitions.hpp
@@ -307,6 +307,11 @@ public:
   shift(const Vector3D& shift)
   { m_vertex += shift; }
 
+  /// assign the barcode
+  void
+  assign(barcode_type barcode)
+  { m_barcode = barcode; }
+    
   /** return the momentum */
   const Vector3D&
   vertex() const
diff --git a/Core/include/ACTS/Extrapolation/ExtrapolationCell.hpp b/Core/include/ACTS/Extrapolation/ExtrapolationCell.hpp
index 26fee716f99464665f486c8d7e3435696d38ad93..2d2321b451727dbf3435668891099fbbc55c9a31 100644
--- a/Core/include/ACTS/Extrapolation/ExtrapolationCell.hpp
+++ b/Core/include/ACTS/Extrapolation/ExtrapolationCell.hpp
@@ -41,8 +41,8 @@ class ExtrapolationMode
 {
 public:
   enum eMode {
-    Destination = 1,  // try to hit the destination, if not other means to stop
-    Propagation = 2,  // any propagation but the final one to destinaion
+    Destination             = 1,  // try to hit the destination, if not other means to stop
+    Propagation             = 2,  // any propagation but the final one to destinaion
     StopWithPathLimit       = 3,   // stop when the path limit is reached
     StopWithMaterialLimitX0 = 4,   // stop when  material limit is reached in X0
     StopWithMaterialLimitL0 = 5,   // stop when material limit is reached in L0
@@ -119,11 +119,11 @@ public:
     SuccessMaterialLimit   = 5,  // successful : material limit reached
     Recovered              = 6,  // successful : recovered
     FailureDestination     = 7,  // failure    : could not reach destination
-    FailureLoop       = 8,   // failure    : loop or oscillation between volumes
-    FailureNavigation = 9,   // failure    : general navigation failure
-    FailureUpdateKill = 10,  // failure    : updated track under threshold
-    FailureConfiguration = 11,  // failure    : general configuration failure
-    LeftKnownWorld       = 12   // successful ? failure ? if we just knew ...
+    FailureLoop            = 8,   // failure    : loop or oscillation between volumes
+    FailureNavigation      = 9,   // failure    : general navigation failure
+    FailureUpdateKill      = 10,  // failure    : updated track under threshold
+    FailureConfiguration   = 11,  // failure    : general configuration failure
+    LeftKnownWorld         = 12   // successful ? failure ? if we just knew ...
   };
 
   /// the actual code
diff --git a/Core/include/ACTS/Extrapolation/detail/RungeKuttaEngine.ipp b/Core/include/ACTS/Extrapolation/detail/RungeKuttaEngine.ipp
index 03a3a82168523ec2fe75a7be642317b7c83c66f6..8290021fd6ad54349adbfded2a93d7a9cd2d87f9 100644
--- a/Core/include/ACTS/Extrapolation/detail/RungeKuttaEngine.ipp
+++ b/Core/include/ACTS/Extrapolation/detail/RungeKuttaEngine.ipp
@@ -27,7 +27,7 @@ Acts::RungeKuttaEngine<MagneticField>::propagateRungeKuttaT(
   EX_MSG_VERBOSE(eCell.navigationStep,
                  "propagate",
                  "<T> ",
-                 "propagateRungeKuttaT called.");
+                 "propagateRungeKuttaT called");
 
   // bail out if you can't transform into global frame
   if (!m_rkUtils.transformLocalToGlobal(
diff --git a/Core/include/ACTS/Extrapolation/detail/StaticEngine.ipp b/Core/include/ACTS/Extrapolation/detail/StaticEngine.ipp
index 1be6b7aa0d709fba92e9fa8133ca7467ee3cd1c3..80819dd7b5467710e0a7ae1da7cb61cd4a9044ff 100644
--- a/Core/include/ACTS/Extrapolation/detail/StaticEngine.ipp
+++ b/Core/include/ACTS/Extrapolation/detail/StaticEngine.ipp
@@ -132,7 +132,8 @@ Acts::StaticEngine::extrapolateT(Acts::ExtrapolationCell<T>& eCell,
         eCell.navigationStep,
         "layer",
         "loop",
-        "processing layer with index : " << eCell.leadLayer->geoID().value());
+        "processing layer with index : "
+            << eCell.leadLayer->geoID().value(GeometryID::layer_mask));
     // resolve the approach surface situation
     // -  it is the approaching surface for all layers but the very first one
     // (where it's the parameter surface)
@@ -409,12 +410,13 @@ Acts::StaticEngine::resolveLayerT(ExtrapolationCell<T>& eCell,
     // limit
     // - Recovered        : layer was not hit, so can be ignored in the layer to
     // layer loop
-    eCode = m_cfg.propagationEngine->propagate(eCell,
-                                               *eCell.leadLayerSurface,
-                                               pDir,
-                                               ExtrapolationMode::CollectPassive,
-                                               true,
-                                               eCell.sensitiveCurvilinear);
+    eCode
+        = m_cfg.propagationEngine->propagate(eCell,
+                                             *eCell.leadLayerSurface,
+                                             pDir,
+                                             ExtrapolationMode::CollectPassive,
+                                             true,
+                                             eCell.sensitiveCurvilinear);
     CHECK_ECODE_SUCCESS_NODEST(eCell, eCode);
     // the extrapolation to the initial layer did not succeed - skip this layer
     // in the layer-to-layer loop
@@ -501,11 +503,12 @@ Acts::StaticEngine::resolveLayerT(ExtrapolationCell<T>& eCell,
     // the surfaces will be sorted
     for (auto& csf : cSurfaces) {
       // get the surface
-      auto surface = csf.object;
-      geo_id_value sensitiveID  = surface->geoID().value(GeometryID::sensitive_mask);
-      geo_id_value surfaceID     = sensitiveID ? 0 :
-                                  surface->geoID().value(GeometryID::approach_mask);
-                                  
+      auto         surface = csf.object;
+      geo_id_value sensitiveID
+          = surface->geoID().value(GeometryID::sensitive_mask);
+      geo_id_value surfaceID
+          = sensitiveID ? 0 : surface->geoID().value(GeometryID::approach_mask);
+
       // the surface to try
       EX_MSG_VERBOSE(eCell.navigationStep,
                      "surface",
@@ -513,11 +516,11 @@ Acts::StaticEngine::resolveLayerT(ExtrapolationCell<T>& eCell,
                      "trying candidate surfaces with straight line path length "
                          << csf.intersection.pathLength);
       // indicate if the surface is active or not
-      EX_MSG_VERBOSE(eCell.navigationStep,
-                     "surface",
-                     surfaceID,
-                     (surface->associatedDetectorElement() ? "is active"
-                                                          : "is passive"));
+      EX_MSG_VERBOSE(
+          eCell.navigationStep,
+          "surface",
+          surfaceID,
+          (surface->associatedDetectorElement() ? "is active" : "is passive"));
       // record the parameters as sensitive or passive depending on the surface
       Acts::ExtrapolationMode::eMode emode
           = surface->associatedDetectorElement()
@@ -538,14 +541,13 @@ Acts::StaticEngine::resolveLayerT(ExtrapolationCell<T>& eCell,
       CHECK_ECODE_SUCCESS_NODEST(eCell, eCode);
       // check if the propagation was successful
       if (eCode.inProgress()) {
-        EX_MSG_VERBOSE(eCell.navigationStep,
-                       "layer",
-                       layerValue,
-                       "successfully hit "
-                           << (surface->associatedDetectorElement()
-                                   ? "active"
-                                   : "passive")
-                           << " sub structure surface.");
+        EX_MSG_VERBOSE(
+            eCell.navigationStep,
+            "layer",
+            layerValue,
+            "successfully hit "
+                << (surface->associatedDetectorElement() ? "active" : "passive")
+                << " sub structure surface.");
         // check if the surface holds material and hence needs to be processed
         if (csf.object->associatedMaterial()) {
           // screen output
@@ -628,7 +630,7 @@ Acts::StaticEngine::resolveLayerT(ExtrapolationCell<T>& eCell,
   return Acts::ExtrapolationCode::InProgress;
 }
 
-/// handle the failure - as configured 
+/// handle the failure - as configured
 template <class T>
 Acts::ExtrapolationCode
 Acts::StaticEngine::handleReturnT(ExtrapolationCode     eCode,
diff --git a/Core/include/ACTS/Extrapolation/detail/StaticNavigationEngine.ipp b/Core/include/ACTS/Extrapolation/detail/StaticNavigationEngine.ipp
index e468200ffb2bf4831d984a5f6fb3b8b51f950e5d..430cfadb186631a8e0c8be30dde6f318b2b7258a 100644
--- a/Core/include/ACTS/Extrapolation/detail/StaticNavigationEngine.ipp
+++ b/Core/include/ACTS/Extrapolation/detail/StaticNavigationEngine.ipp
@@ -96,6 +96,16 @@ Acts::StaticNavigationEngine::resolveBoundaryT(
     // and return the code yielded by the handleBoundaryT
     return eCode;
   }
+  // bail-out in case no boundary has been found for Fatras mode
+  if (eCell.checkConfigurationMode(ExtrapolationMode::FATRAS)){
+    EX_MSG_VERBOSE(eCell.navigationStep,
+                   "navigation",
+                   "",
+                   "Fatras loop protection.");
+    // get out of this, we will not simulate loopers  
+    return ExtrapolationCode::SuccessPathLimit;
+  }
+  
   // [2] ------------------------ slow boundary access : take all boundary
   // surfaces and simply try --------------
   EX_MSG_VERBOSE(eCell.navigationStep,
diff --git a/Core/include/ACTS/Surfaces/DiamondBounds.hpp b/Core/include/ACTS/Surfaces/DiamondBounds.hpp
index ffa248fe82b3b1bc67b9f03bc7a8b95553874dbc..e44cfb1c0775851f0fe5c4dc13e145f43539518c 100644
--- a/Core/include/ACTS/Surfaces/DiamondBounds.hpp
+++ b/Core/include/ACTS/Surfaces/DiamondBounds.hpp
@@ -15,6 +15,7 @@
 
 #include <cmath>
 #include "ACTS/Surfaces/PlanarBounds.hpp"
+#include "ACTS/Surfaces/RectangleBounds.hpp"
 #include "ACTS/Utilities/Definitions.hpp"
 #include "ACTS/Utilities/ParameterDefinitions.hpp"
 
@@ -115,7 +116,7 @@ public:
   /// This method returns the opening angle alpha in point A'
   double
   alpha2() const;
-
+  
   /// Inside check for the bounds object driven by the boundary check directive
   /// Each Bounds has a method inside, which checks if a LocalPosition is inside
   /// the bounds  Inside can be called without/with tolerances.
@@ -163,6 +164,10 @@ public:
   virtual const std::vector<Vector2D>
   vertices() const override;
 
+  // Bounding box representation
+  virtual const RectangleBounds& 
+  boundingBox() const final; 
+  
   /// Output Method for std::ostream
   ///
   /// @param sl is the ostream in which it is dumped
@@ -183,8 +188,9 @@ private:
   initCache();
 
   std::vector<TDD_real_t> m_valueStore;  ///< internal parameter store
-  TDD_real_t              m_alpha1;  ///< internal parameter cache for alpha1
-  TDD_real_t              m_alpha2;  ///< internal parameter cahce for alpha2
+  TDD_real_t              m_alpha1;      ///< internal parameter cache for alpha1
+  TDD_real_t              m_alpha2;      ///< internal parameter cache for alpha2
+  RectangleBounds         m_boundingBox; ///< internal bounding box cache
 };
 
 inline DiamondBounds*
@@ -359,6 +365,12 @@ DiamondBounds::vertices() const
   return vertices;
 }
 
+inline const RectangleBounds& 
+DiamondBounds::boundingBox() const
+{
+  return m_boundingBox;
+}
+
 }  // end of namespace
 
 #endif  // ACTS_SURFACES_DIAMONDBOUNDS_H
diff --git a/Core/include/ACTS/Surfaces/EllipseBounds.hpp b/Core/include/ACTS/Surfaces/EllipseBounds.hpp
index 4f6558a77f2509095e48071a74eb7dbd0fe904c2..f560d40da39b190ce8184a456969bfb0fe33fafc 100644
--- a/Core/include/ACTS/Surfaces/EllipseBounds.hpp
+++ b/Core/include/ACTS/Surfaces/EllipseBounds.hpp
@@ -16,6 +16,7 @@
 #include <cmath>
 #include <cstdlib>
 #include "ACTS/Surfaces/PlanarBounds.hpp"
+#include "ACTS/Surfaces/RectangleBounds.hpp"
 #include "ACTS/Utilities/Definitions.hpp"
 
 namespace Acts {
@@ -64,7 +65,10 @@ public:
   /// Copy constructor
   ///
   /// @param ebo is the source bounds for the copy
-  EllipseBounds(const EllipseBounds& ebo) : PlanarBounds(ebo) {}
+  EllipseBounds(const EllipseBounds& ebo)
+   : PlanarBounds(ebo),
+     m_boundingBox(0.,0.)
+  {}
   
   /// Destructor
   virtual ~EllipseBounds();
@@ -153,6 +157,10 @@ public:
   /// Return the vertices - or, the points of the extremas
   virtual const std::vector<Vector2D>
   vertices() const override;
+  
+  // Bounding box representation
+  virtual const RectangleBounds& 
+  boundingBox() const final; 
 
   /// This method returns the halfPhiSector which is covered by the disc
   double
@@ -173,12 +181,15 @@ private:
 
   /// helper function for squaring
   ///
-  /// @param x is the input for squaring
+  /// @param x is the input for squaring ? Why do we need this ?
   inline double
   square(double x) const
   {
     return x * x;
   };
+  
+  RectangleBounds         m_boundingBox;  ///< internal bounding box cache
+  
 };
 
 inline EllipseBounds*
@@ -303,6 +314,12 @@ EllipseBounds::vertices() const
   return vertices;
 }
 
+inline const RectangleBounds& 
+EllipseBounds::boundingBox() const
+{
+  return m_boundingBox;
+} 
+
 }  // end of namespace
 
 #endif  // ACTS_SURFACES_ELLIPSEBOUNDS_H
diff --git a/Core/include/ACTS/Surfaces/InfiniteBounds.hpp b/Core/include/ACTS/Surfaces/InfiniteBounds.hpp
index 865761c848a01799dcd65d3556f65479aeaf78e7..d0d4e0953e1722160dbf2d2491f85ddd61ae7bae 100644
--- a/Core/include/ACTS/Surfaces/InfiniteBounds.hpp
+++ b/Core/include/ACTS/Surfaces/InfiniteBounds.hpp
@@ -28,8 +28,10 @@ class InfiniteBounds : public SurfaceBounds
 public:
   /// Default Constructor
   InfiniteBounds() {}
+  
   /// Destructor
   ~InfiniteBounds() {}
+  
   /// Return SurfaceBounds type for persistency mainly
   virtual SurfaceBounds::BoundsType
   type() const final
diff --git a/Core/include/ACTS/Surfaces/PlanarBounds.hpp b/Core/include/ACTS/Surfaces/PlanarBounds.hpp
index eaac6f6358a44655eea4105e652909df6a50aab3..ac94fc6bb19d818edafde55b9f233ddeef162b51 100644
--- a/Core/include/ACTS/Surfaces/PlanarBounds.hpp
+++ b/Core/include/ACTS/Surfaces/PlanarBounds.hpp
@@ -16,6 +16,9 @@
 #include "ACTS/Surfaces/SurfaceBounds.hpp"
 
 namespace Acts {
+  
+/// forward declare rectangle bounds as boundary box
+class RectangleBounds;
 ///
 /// @class PlanarBounds
 ///
@@ -29,8 +32,10 @@ public:
   ///
   /// @param sStore is the store size for the initialisation
   PlanarBounds(size_t sStore = 0) : SurfaceBounds(sStore) {}
+  
   /// Destructor
   virtual ~PlanarBounds() {}
+  
   /// Virtual Constructor
   virtual PlanarBounds*
   clone() const = 0;
@@ -38,6 +43,11 @@ public:
   /// Return the vertices - or, the points of the extremas
   virtual const std::vector<Vector2D>
   vertices() const = 0;
+  
+  // Bounding box parameters
+  virtual const RectangleBounds& 
+  boundingBox() const = 0; 
+  
 };
 
 }  // end of namespace
diff --git a/Core/include/ACTS/Surfaces/RectangleBounds.hpp b/Core/include/ACTS/Surfaces/RectangleBounds.hpp
index ca3efe4d180182b79308145d6f681d83491fa9c3..adb077911345a958444228efd93aa24691256b6a 100644
--- a/Core/include/ACTS/Surfaces/RectangleBounds.hpp
+++ b/Core/include/ACTS/Surfaces/RectangleBounds.hpp
@@ -47,6 +47,7 @@ public:
   ///
   /// @param recbo are the source bounds
   RectangleBounds(const RectangleBounds& recbo) : PlanarBounds(recbo) {}
+  
   /// Destructor
   virtual ~RectangleBounds();
 
@@ -116,13 +117,17 @@ public:
 
   /// Return the vertices - or, the points of the extremas
   virtual const std::vector<Vector2D>
-  vertices() const override;
+  vertices() const final;
+
+  // Bounding box representation
+  virtual const RectangleBounds& 
+  boundingBox() const final;
 
   /// Output Method for std::ostream
   ///
   /// @param sl is the ostream for the dump
   virtual std::ostream&
-  dump(std::ostream& sl) const override;
+  dump(std::ostream& sl) const final;
 
 private:
   /// Private helper method
@@ -255,6 +260,12 @@ RectangleBounds::vertices() const
   return vertices;
 }
 
+inline const RectangleBounds& 
+RectangleBounds::boundingBox() const
+{
+  return (*this);
+} 
+
 }  // end of namespace
 
 #endif  // ACTS_SURFACES_RECTANGLEBOUNDS_H
diff --git a/Core/include/ACTS/Surfaces/TrapezoidBounds.hpp b/Core/include/ACTS/Surfaces/TrapezoidBounds.hpp
index de6fff1fdacf92b9b748c6c3621bd514de9cfef5..124b90e60dbe8be63d34f8e40d94f8886c84a237 100644
--- a/Core/include/ACTS/Surfaces/TrapezoidBounds.hpp
+++ b/Core/include/ACTS/Surfaces/TrapezoidBounds.hpp
@@ -15,6 +15,7 @@
 
 #include <cmath>
 #include "ACTS/Surfaces/PlanarBounds.hpp"
+#include "ACTS/Surfaces/RectangleBounds.hpp"
 #include "ACTS/Utilities/Definitions.hpp"
 #include "ACTS/Utilities/ParameterDefinitions.hpp"
 
@@ -60,18 +61,21 @@ public:
   /// Copy constructor
   ///
   /// @param trabo are the source bounds for assignment
-  TrapezoidBounds(const TrapezoidBounds& trabo) : PlanarBounds(trabo) {}
+  TrapezoidBounds(const TrapezoidBounds& trabo)
+   : PlanarBounds(trabo),
+     m_boundingBox(0.,0.)
+  {}
   
   /// Destructor
   virtual ~TrapezoidBounds();
 
   /// Virtual constructor
   virtual TrapezoidBounds*
-  clone() const override;
+  clone() const final;
 
   /// Return the type of the bounds for persistency
   virtual BoundsType
-  type() const override
+  type() const final
   {
     return SurfaceBounds::Trapezoid;
   }
@@ -151,7 +155,7 @@ public:
   ///
   /// @return boolean indicator for the success of this operation
   virtual bool
-  inside(const Vector2D& lpos, const BoundaryCheck& bcheck) const override;
+  inside(const Vector2D& lpos, const BoundaryCheck& bcheck) const final;
 
   /// This method checks inside bounds in loc0
   /// @note loc0/loc1 correspond to the natural coordinates of the surface
@@ -163,7 +167,7 @@ public:
   ///
   /// @return boolean indicator for the success of this operation
   virtual bool
-  insideLoc0(const Vector2D& lpos, double tol0 = 0.) const override;
+  insideLoc0(const Vector2D& lpos, double tol0 = 0.) const final;
 
   /// This method checks inside bounds in loc0
   /// @note loc0/loc1 correspond to the natural coordinates of the surface
@@ -175,7 +179,7 @@ public:
   ///
   /// @return boolean indicator for the success of this operation
   virtual bool
-  insideLoc1(const Vector2D& lpos, double tol1 = 0.) const override;
+  insideLoc1(const Vector2D& lpos, double tol1 = 0.) const final;
 
   /// Minimal distance to boundary ( > 0 if outside and <=0 if inside)
   ///
@@ -183,17 +187,21 @@ public:
   ///
   /// @return is a signed distance parameter
   virtual double
-  distanceToBoundary(const Vector2D& lpos) const override;
+  distanceToBoundary(const Vector2D& lpos) const final;
 
   /// Return the vertices - or, the points of the extremas
   virtual const std::vector<Vector2D>
-  vertices() const override;
+  vertices() const final;
+  
+  // Bounding box representation
+  virtual const RectangleBounds& 
+  boundingBox() const final;
 
   /// Output Method for std::ostream
   ///
   /// @param sl is the ostream to be dumped into
   virtual std::ostream&
-  dump(std::ostream& sl) const override;
+  dump(std::ostream& sl) const final;
 
 private:
   /// private helper method for inside check
@@ -242,8 +250,10 @@ private:
   isAbove(const Vector2D& lpos, double tol0, double tol1, double k, double d)
       const;
 
-  TDD_real_t m_alpha;  ///< private cache of angle alpha
-  TDD_real_t m_beta;   ///< private cahce of angle beta
+  TDD_real_t              m_alpha;        ///< private cache of angle alpha
+  TDD_real_t              m_beta;         ///< private cache of angle beta
+  RectangleBounds         m_boundingBox;  ///< internal bounding box cache
+  
 };
 
 inline TrapezoidBounds*
@@ -391,6 +401,13 @@ TrapezoidBounds::vertices() const
   return vertices;
 }
 
+inline const RectangleBounds& 
+TrapezoidBounds::boundingBox() const
+{
+  return m_boundingBox;
+} 
+
+
 }  // end of namespace
 
 #endif  // ACTS_SURFACES_TRAPEZOIDBOUNDS_H
diff --git a/Core/include/ACTS/Surfaces/TriangleBounds.hpp b/Core/include/ACTS/Surfaces/TriangleBounds.hpp
index b779b83d7ab7614c17009c98a02d2af09ac65b95..65de69e3543fbde5ddef24213750a039f7642311 100644
--- a/Core/include/ACTS/Surfaces/TriangleBounds.hpp
+++ b/Core/include/ACTS/Surfaces/TriangleBounds.hpp
@@ -15,6 +15,7 @@
 
 #include <utility>
 #include "ACTS/Surfaces/PlanarBounds.hpp"
+#include "ACTS/Surfaces/RectangleBounds.hpp"
 #include "ACTS/Utilities/Definitions.hpp"
 #include "ACTS/Utilities/ParameterDefinitions.hpp"
 
@@ -51,7 +52,10 @@ public:
   /// Copy constructor
   ///
   /// @param tribo are the source bounds for assignment
-  TriangleBounds(const TriangleBounds& tribo) : PlanarBounds(tribo) {}
+  TriangleBounds(const TriangleBounds& tribo)
+    : PlanarBounds(tribo)
+    , m_boundingBox(0.,0.)
+  {}
   
   /// Destructor
   virtual ~TriangleBounds();
@@ -64,15 +68,15 @@ public:
 
   /// Virtual constructor
   virtual TriangleBounds*
-  clone() const override;
+  clone() const final;
 
   /// Return the type of the bounds for persistency
   virtual BoundsType
-  type() const override
+  type() const final
   {
     return SurfaceBounds::Triangle;
   }
-
+  
   /// This method checks if the provided local coordinates are inside the
   /// surface bounds
   ///
@@ -81,7 +85,7 @@ public:
   ///
   /// @return boolean indicator for the success of this operation
   virtual bool
-  inside(const Vector2D& lpos, const BoundaryCheck& bcheck) const override;
+  inside(const Vector2D& lpos, const BoundaryCheck& bcheck) const final;
 
   /// This method checks if the provided local coordinate 1 is inside the
   /// surface bounds
@@ -91,7 +95,7 @@ public:
   ///
   /// @return boolean indicator for the success of this operation
   virtual bool
-  insideLoc0(const Vector2D& lpos, double tol0 = 0.) const override;
+  insideLoc0(const Vector2D& lpos, double tol0 = 0.) const final;
 
   /// This method checks if the provided local coordinate 2 is inside the
   /// surface bounds
@@ -101,7 +105,7 @@ public:
   ///
   /// @return boolean indicator for the success of this operation
   virtual bool
-  insideLoc1(const Vector2D& lpos, double tol1 = 0.) const override;
+  insideLoc1(const Vector2D& lpos, double tol1 = 0.) const final;
 
   /// Minimal distance to boundary ( > 0 if outside and <=0 if inside)
   ///
@@ -109,17 +113,21 @@ public:
   ///
   /// @return is a signed distance parameter
   virtual double
-  distanceToBoundary(const Vector2D& lpos) const override;
+  distanceToBoundary(const Vector2D& lpos) const final;
 
   /// This method returns the coordinates of vertices
   const std::vector<Vector2D>
-  vertices() const override;
+  vertices() const final;
+  
+  // Bounding box representation
+  virtual const RectangleBounds& 
+  boundingBox() const final; 
 
   /// Output Method for std::ostream
   ///
   /// @param sl is the ostream to be dumped into
   virtual std::ostream&
-  dump(std::ostream& sl) const override;
+  dump(std::ostream& sl) const final;
 
 private:
   /// Private helper method
@@ -131,6 +139,9 @@ private:
   /// @return boolean indicator for the success of this operation
   bool
   inside(const Vector2D& lpos, double tol0, double tol1) const;
+  
+  RectangleBounds         m_boundingBox; ///< internal bounding box cache
+
 };
 
 inline TriangleBounds*
@@ -258,6 +269,12 @@ TriangleBounds::vertices() const
   return vertices;
 }
 
+inline const RectangleBounds& 
+TriangleBounds::boundingBox() const
+{
+  return m_boundingBox;
+}
+
 }  // end of namespace
 
 #endif  // ACTS_SURFACESRECTANGLEBOUNDS_H
diff --git a/Core/src/Digitization/RectangleSegmentation.cpp b/Core/src/Digitization/CartesianSegmentation.cpp
similarity index 71%
rename from Core/src/Digitization/RectangleSegmentation.cpp
rename to Core/src/Digitization/CartesianSegmentation.cpp
index ff54681cb60682843dd8126a30205b7c59d88a36..ccd685fc19999886464753e2b7d1264421954f72 100644
--- a/Core/src/Digitization/RectangleSegmentation.cpp
+++ b/Core/src/Digitization/CartesianSegmentation.cpp
@@ -7,51 +7,48 @@
 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 ///////////////////////////////////////////////////////////////////
-// RectangularSegmentation.cpp, ACTS project
+// CartesianSegmentation.cpp, ACTS project
 ///////////////////////////////////////////////////////////////////
 
-#include <cmath>
-#include "ACTS/Digitization/RectangularSegmentation.hpp"
+#include "ACTS/Digitization/CartesianSegmentation.hpp"
 #include "ACTS/Surfaces/PlaneSurface.hpp"
 #include "ACTS/Surfaces/RectangleBounds.hpp"
 #include "ACTS/Utilities/Helpers.hpp"
 
-Acts::RectangularSegmentation::RectangularSegmentation(
-    std::shared_ptr<const Acts::RectangleBounds> mBounds,
-    size_t                                       numCellsX,
-    size_t                                       numCellsY)
-  : m_activeBounds(mBounds)
-  , m_binUtility(nullptr)
-  , m_binsX(numCellsX)
-  , m_binsY(numCellsY)
+Acts::CartesianSegmentation::CartesianSegmentation(
+    std::shared_ptr<const PlanarBounds> mBounds,
+    size_t                              numCellsX,
+    size_t                              numCellsY)
+  : m_activeBounds(mBounds), m_binUtility(nullptr)
 {
-  // first the x dimension if needed
-  if (numCellsX > 1)
-    m_binUtility = std::make_unique<BinUtility>(numCellsX,
-                                                -mBounds->halflengthX(),
-                                                mBounds->halflengthX(),
-                                                Acts::open,
-                                                Acts::binX);
-  // use y dimension if needed
-  if (numCellsY > 1) {
-    BinUtility yBinUtility(numCellsY,
-                           -mBounds->halflengthY(),
-                           mBounds->halflengthY(),
-                           Acts::open,
-                           Acts::binY);
-    if (m_binUtility)
-      (*m_binUtility) += yBinUtility;
-    else
-      m_binUtility = std::make_unique<BinUtility>(yBinUtility);
-  }
+  m_binUtility = std::make_shared<BinUtility>(numCellsX,
+                                              -mBounds->boundingBox().halflengthX(),
+                                              mBounds->boundingBox().halflengthX(),
+                                              Acts::open,
+                                              Acts::binX);
+  (*m_binUtility) += BinUtility(numCellsY,
+                                -mBounds->boundingBox().halflengthY(),
+                                mBounds->boundingBox().halflengthY(),
+                                Acts::open,
+                                Acts::binY);
+}
+
+Acts::CartesianSegmentation::CartesianSegmentation(
+    std::shared_ptr<BinUtility>            bUtility,
+    std::shared_ptr<const PlanarBounds> mBounds)
+  : m_activeBounds(mBounds), m_binUtility(bUtility)
+{
+  if (!m_activeBounds)
+    m_activeBounds = std::make_shared<const RectangleBounds>(
+        m_binUtility->max(0), m_binUtility->max(1));
 }
 
-Acts::RectangularSegmentation::~RectangularSegmentation()
+Acts::CartesianSegmentation::~CartesianSegmentation()
 {
 }
 
 void
-Acts::RectangularSegmentation::createSegmentationSurfaces(
+Acts::CartesianSegmentation::createSegmentationSurfaces(
     SurfacePtrVector& boundarySurfaces,
     SurfacePtrVector& segmentationSurfacesX,
     SurfacePtrVector& segmentationSurfacesY,
@@ -71,7 +68,7 @@ Acts::RectangularSegmentation::createSegmentationSurfaces(
   // - they share the RectangleBounds only if the lorentzAngle is 0
   // otherwise only the readout surface has full length bounds like the module
   std::shared_ptr<const PlanarBounds> moduleBounds(new RectangleBounds(
-      m_activeBounds->halflengthX(), m_activeBounds->halflengthY()));
+      m_activeBounds->boundingBox().halflengthX(), m_activeBounds->boundingBox().halflengthY()));
   // - they are separated by half a thickness in z
   auto readoutPlaneTransform
       = std::make_shared<Transform3D>(Transform3D::Identity());
@@ -92,10 +89,10 @@ Acts::RectangularSegmentation::createSegmentationSurfaces(
   } else {
     // lorentz reduced Bounds
     double lorentzReducedHalfX
-        = m_activeBounds->halflengthX() - std::abs(lorentzPlaneShiftX);
+        = m_activeBounds->boundingBox().halflengthX() - fabs(lorentzPlaneShiftX);
     std::shared_ptr<const PlanarBounds> lorentzReducedBounds(
         new RectangleBounds(lorentzReducedHalfX,
-                            m_activeBounds->halflengthY()));
+                            m_activeBounds->boundingBox().halflengthY()));
     counterPlaneBounds = lorentzReducedBounds;
     // now we shift the counter plane in position - this depends on lorentz
     // angle
@@ -112,19 +109,19 @@ Acts::RectangularSegmentation::createSegmentationSurfaces(
   // (B) - bin X and lorentz surfaces
   // -----------------------------------------------------------
   // easy stuff first, constant pitch size and
-  double pitchX = 2. * m_activeBounds->halflengthX() / m_binsX;
+  double pitchX = 2. * m_activeBounds->boundingBox().halflengthX() / m_binUtility->bins(0);
 
   // now, let's create the shared bounds of all surfaces marking x bins - choice
   // fixes orientation of the matrix
   std::shared_ptr<const PlanarBounds> xBinBounds(
-      new RectangleBounds(m_activeBounds->halflengthY(), halfThickness));
+      new RectangleBounds(m_activeBounds->boundingBox().halflengthY(), halfThickness));
   // now, let's create the shared bounds of all surfaces marking lorentz planes
   double lorentzPlaneHalfX = std::abs(halfThickness / cos(lorentzAngle));
   // teh bounds of the lorentz plane
   std::shared_ptr<const PlanarBounds> lorentzPlaneBounds = (lorentzAngle == 0.)
       ? xBinBounds
       : std::shared_ptr<const PlanarBounds>(new RectangleBounds(
-            m_activeBounds->halflengthY(), lorentzPlaneHalfX));
+            m_activeBounds->boundingBox().halflengthY(), lorentzPlaneHalfX));
 
   // now the rotation matrix for the xBins
   RotationMatrix3D xBinRotationMatrix;
@@ -139,13 +136,13 @@ Acts::RectangularSegmentation::createSegmentationSurfaces(
 
   // reserve, it's always (number of bins-1) as the boundaries are within the
   // boundarySurfaces
-  segmentationSurfacesX.reserve(m_binsX);
+  segmentationSurfacesX.reserve(m_binUtility->bins(0));
   // create and fill them
-  for (size_t ibinx = 0; ibinx <= m_binsX; ++ibinx) {
+  for (size_t ibinx = 0; ibinx <= m_binUtility->bins(0); ++ibinx) {
     // the current step x position
-    double cPosX = -m_activeBounds->halflengthX() + ibinx * pitchX;
-    // (i) this is the low/high boundary --- ( ibin == 0/m_binsX )
-    if (!ibinx || ibinx == m_binsX) {
+    double cPosX = -m_activeBounds->boundingBox().halflengthX() + ibinx * pitchX;
+    // (i) this is the low/high boundary --- ( ibin == 0/m_binUtility->bins(0) )
+    if (!ibinx || ibinx == m_binUtility->bins(0)) {
       // check if it a straight boundary or not: always straight for no lorentz
       // angle,
       // and either the first boundary or the last dependening on lorentz &
@@ -153,7 +150,8 @@ Acts::RectangularSegmentation::createSegmentationSurfaces(
       bool boundaryStraight
           = (lorentzAngle == 0.
              || (!ibinx && readoutDirection * lorentzAngle > 0.)
-             || (ibinx == m_binsX && readoutDirection * lorentzAngle < 0));
+             || (ibinx == m_binUtility->bins(0)
+                 && readoutDirection * lorentzAngle < 0));
       // set the low boundary parameters : position & rotation
       Vector3D boundaryXPosition = boundaryStraight
           ? Vector3D(cPosX, 0., 0.)
@@ -192,22 +190,22 @@ Acts::RectangularSegmentation::createSegmentationSurfaces(
   yBinRotationMatrix.col(1) = Vector3D::UnitZ();
   yBinRotationMatrix.col(2) = Vector3D(0., -1., 0.);
   // easy stuff first, constant pitch in Y
-  double pitchY = 2. * m_activeBounds->halflengthY() / m_binsY;
+  double pitchY = 2. * m_activeBounds->boundingBox().halflengthY() / m_binUtility->bins(1);
   // let's create the shared bounds of all surfaces marking y bins
   std::shared_ptr<const PlanarBounds> yBinBounds(
-      new RectangleBounds(m_activeBounds->halflengthX(), halfThickness));
+      new RectangleBounds(m_activeBounds->boundingBox().halflengthX(), halfThickness));
   // reserve, it's always (number of bins-1) as the boundaries are within the
   // boundarySurfaces
-  segmentationSurfacesY.reserve(m_binsY);
-  for (size_t ibiny = 0; ibiny <= m_binsY; ++ibiny) {
+  segmentationSurfacesY.reserve(m_binUtility->bins(1));
+  for (size_t ibiny = 0; ibiny <= m_binUtility->bins(1); ++ibiny) {
     // the position of the bin surface
-    double   binPosY = -m_activeBounds->halflengthY() + ibiny * pitchY;
+    double   binPosY = -m_activeBounds->boundingBox().halflengthY() + ibiny * pitchY;
     Vector3D binSurfaceCenter(0., binPosY, 0.);
     // the binning transform
     auto binTransform = std::make_shared<Transform3D>(
         getTransformFromRotTransl(yBinRotationMatrix, binSurfaceCenter));
     // these are the boundaries
-    if (ibiny == 0 || ibiny == m_binsY)
+    if (ibiny == 0 || ibiny == m_binUtility->bins(1))
       boundarySurfaces.push_back(std::shared_ptr<PlaneSurface>(
           new PlaneSurface(binTransform, yBinBounds)));
     else  // these are the bin boundaries
@@ -217,26 +215,25 @@ Acts::RectangularSegmentation::createSegmentationSurfaces(
 }
 
 const Acts::Vector2D
-Acts::RectangularSegmentation::cellPosition(const DigitizationCell& dCell) const
+Acts::CartesianSegmentation::cellPosition(const DigitizationCell& dCell) const
 {
-  // @TODO add protection agains 1D binUtility for Y
-  double bX
-      = m_binsX > 1 ? m_binUtility->binningData()[0].center(dCell.first) : 0.;
-  double bY
-      = m_binsY > 1 ? m_binUtility->binningData()[1].center(dCell.second) : 0.;
-  return Vector2D(bX, bY);
-
+  double bX = m_binUtility->bins(0) > 1
+      ? m_binUtility->binningData()[0].center(dCell.first)
+      : 0.;
+  double bY = m_binUtility->bins(1) > 1
+      ? m_binUtility->binningData()[1].center(dCell.second)
+      : 0.;
   return Vector2D(bX, bY);
 }
 
 /** Get the digitization cell from 3D position, it used the projection to the
  * readout surface to estimate the 2D positon */
 const Acts::DigitizationStep
-Acts::RectangularSegmentation::digitizationStep(const Vector3D& startStep,
-                                                const Vector3D& endStep,
-                                                double          halfThickness,
-                                                int    readoutDirection,
-                                                double lorentzAngle) const
+Acts::CartesianSegmentation::digitizationStep(const Vector3D& startStep,
+                                              const Vector3D& endStep,
+                                              double          halfThickness,
+                                              int             readoutDirection,
+                                              double lorentzAngle) const
 {
   Vector3D stepCenter = 0.5 * (startStep + endStep);
   // take the full drift length
diff --git a/Core/src/Digitization/PlanarModuleStepper.cpp b/Core/src/Digitization/PlanarModuleStepper.cpp
index 688148820a7c09452a855539286e7daf70782f93..e587014638554d36ea64e6e221d96e4efe1506d1 100644
--- a/Core/src/Digitization/PlanarModuleStepper.cpp
+++ b/Core/src/Digitization/PlanarModuleStepper.cpp
@@ -76,8 +76,8 @@ Acts::PlanarModuleStepper::cellSteps(const Acts::DigitizationModule& dmodule,
 {
   // first, intersect the boundary surfaces
   auto boundarySurfaces = dmodule.boundarySurfaces();
-  // intersect them - fast exit for cases where readout and counter readout are
-  // hit
+  // intersect them - fast exit for cases where 
+  // readout and counter readout are hit
   Vector3D intersection3D(moduleIntersection.x(), moduleIntersection.y(), 0.);
   size_t   attempts = 0;
   // the collected intersections
@@ -105,8 +105,8 @@ Acts::PlanarModuleStepper::cellSteps(const Acts::DigitizationModule& dmodule,
     else if (attempts > 2 && boundaryIntersections.size() == 3)
       break;
   }
-  // post-process if we have more than 2 intersections, only first or last can
-  // be wrong after resorting
+  // post-process if we have more than 2 intersections
+  // only first or last can be wrong after resorting
   if (boundaryIntersections.size() > 2) {
     ACTS_VERBOSE("More than 2 Boundary Surfaces intersected, this is an edge "
                  "case, resolving ... ");
diff --git a/Core/src/Digitization/TrapezoidSegmentation.cpp b/Core/src/Digitization/PolarSegmentation.cpp
similarity index 97%
rename from Core/src/Digitization/TrapezoidSegmentation.cpp
rename to Core/src/Digitization/PolarSegmentation.cpp
index 650a0a47d71c3901fcc3ba67998793c71895fd4b..d5b8967d16973cc9c56985619978034a46d57769 100644
--- a/Core/src/Digitization/TrapezoidSegmentation.cpp
+++ b/Core/src/Digitization/PolarSegmentation.cpp
@@ -10,8 +10,8 @@
 // TrapezoidSegmentation.cpp, ACTS project
 ///////////////////////////////////////////////////////////////////
 
-#include "ACTS/Digitization/TrapezoidSegmentation.hpp"
-#include <cmath>
+/*
+#include "ACTS/Digitization/PolarSegmentation.hpp"
 #include "ACTS/Surfaces/PlaneSurface.hpp"
 #include "ACTS/Surfaces/RectangleBounds.hpp"
 #include "ACTS/Surfaces/TrapezoidBounds.hpp"
@@ -182,8 +182,7 @@ Acts::TrapezoidSegmentation::cellPosition(const DigitizationCell& dCell) const
   return Vector2D(bX, bY);
 }
 
-/** Get the digitization cell from 3D position, it used the projection to the
- * readout surface to estimate the 2D positon */
+// Get the digitization cell from 3D position, it used the projection to the readout surface to estimate the 2D positon
 const Acts::DigitizationStep
 Acts::TrapezoidSegmentation::digitizationStep(const Vector3D& startStep,
                                               const Vector3D& endStep,
@@ -211,3 +210,4 @@ Acts::TrapezoidSegmentation::digitizationStep(const Vector3D& startStep,
                           stepCenterProjected,
                           cellCenter);
 }
+*/
diff --git a/Core/src/Extrapolation/ExtrapolationEngine.cpp b/Core/src/Extrapolation/ExtrapolationEngine.cpp
index ec25be437f1154a04eb6f6fb66d3a75827db75d0..5f3909f841665fcd1044587713c5b9742847e6bc 100644
--- a/Core/src/Extrapolation/ExtrapolationEngine.cpp
+++ b/Core/src/Extrapolation/ExtrapolationEngine.cpp
@@ -44,7 +44,6 @@ Acts::ExtrapolationEngine::setLogger(std::unique_ptr<Logger> newLogger)
   m_logger = std::move(newLogger);
 }
 
-/** charged extrapolation */
 Acts::ExtrapolationCode
 Acts::ExtrapolationEngine::extrapolate(ExCellCharged&       ecCharged,
                                        const Surface*       sf,
diff --git a/Core/src/Extrapolation/MaterialEffectsEngine.cpp b/Core/src/Extrapolation/MaterialEffectsEngine.cpp
index 2dc40757feeeacc0773075fd6d124ac3aac95a82..d3ecc6dee859796990d2db5fa4811b8219d66d86 100644
--- a/Core/src/Extrapolation/MaterialEffectsEngine.cpp
+++ b/Core/src/Extrapolation/MaterialEffectsEngine.cpp
@@ -68,7 +68,7 @@ Acts::MaterialEffectsEngine::handleMaterial(
     EX_MSG_DEBUG(
         ++eCell.navigationStep,
         "layer",
-        mLayer->geoID().value(),
+        mLayer->geoID().value(GeometryID::layer_mask),
         "handleMaterial for neutral parameters called - collect material.");
     // path correction
     double pathCorrection
@@ -82,7 +82,7 @@ Acts::MaterialEffectsEngine::handleMaterial(
     if (mFactor == 0.) {
       EX_MSG_VERBOSE(eCell.navigationStep,
                      "layer",
-                     mLayer->geoID().value(),
+                     mLayer->geoID().value(GeometryID::layer_mask),
                      "material collection with "
                          << (matupstage > 0. ? "pre " : "post ")
                          << "factor 0.");
@@ -93,7 +93,7 @@ Acts::MaterialEffectsEngine::handleMaterial(
     // screen output
     EX_MSG_VERBOSE(eCell.navigationStep,
                    "layer",
-                   mLayer->geoID().value(),
+                   mLayer->geoID().value(GeometryID::layer_mask),
                    "material update with corr factor = " << pathCorrection);
     // get the actual material bin
     const MaterialProperties* materialProperties
@@ -107,7 +107,7 @@ Acts::MaterialEffectsEngine::handleMaterial(
       if (eCell.checkConfigurationMode(ExtrapolationMode::CollectMaterial)) {
         EX_MSG_VERBOSE(eCell.navigationStep,
                        "layer",
-                       mLayer->geoID().value(),
+                       mLayer->geoID().value(GeometryID::layer_mask),
                        "collecting material of [t/X0] = " << thicknessInX0);
         eCell.stepMaterial(*mSurface,
                            eCell.leadLayer,
@@ -117,7 +117,7 @@ Acts::MaterialEffectsEngine::handleMaterial(
       } else {
         EX_MSG_VERBOSE(eCell.navigationStep,
                        "layer",
-                       mLayer->geoID().value(),
+                       mLayer->geoID().value(GeometryID::layer_mask),
                        "adding material of [t/X0] = " << thicknessInX0);
         eCell.addMaterial(pathCorrection, materialProperties);
       }
@@ -142,21 +142,21 @@ Acts::MaterialEffectsEngine::handleMaterial(
   if (mSurface && mSurface->associatedMaterial()) {
     EX_MSG_DEBUG(++eCell.navigationStep,
                  "layer",
-                 mLayer->geoID().value(),
-                 "handleMaterial for charged parameters called.");
+                 mLayer->geoID().value(GeometryID::layer_mask),
+                 "handleMaterial for charged parameters called - apply correction.");
     // update the track parameters
     updateTrackParameters(*eCell.leadParameters, eCell, dir, matupstage);
 
     // check if material filling was requested
     // if (eCell.checkConfigurationMode(ExtrapolationMode::CollectMaterial)){
     //    EX_MSG_VERBOSE(eCell.navigationStep, "layer",
-    //    mLayer->geoID().value(), "collecting material of [t/X0] = " <<
+    //    mLayer->geoID().value(GeometryID::layer_mask), "collecting material of [t/X0] = " <<
     //    thicknessInX0);
     //    eCell.stepMaterial(*mSurface, eCell.leadLayer,
     //    eCell.leadParameters->position(), pathCorrection, materialProperties);
     //} else {
     //    EX_MSG_VERBOSE(eCell.navigationStep, "layer",
-    //    mLayer->geoID().value(), "adding material of [t/X0] = " <<
+    //    mLayer->geoID().value(GeometryID::layer_mask), "adding material of [t/X0] = " <<
     //    thicknessInX0);
     //    eCell.addMaterial(pathCorrection, materialProperties);
     // }
@@ -195,7 +195,7 @@ Acts::MaterialEffectsEngine::updateTrackParameters(
   if (mFactor == 0.) {
     EX_MSG_VERBOSE(eCell.navigationStep,
                    "layer",
-                   mLayer->geoID().value(),
+                   mLayer->geoID().value(GeometryID::layer_mask),
                    "material update with "
                        << (matupstage > 0. ? "pre " : "post ")
                        << "factor 0. No update done.");
@@ -206,7 +206,7 @@ Acts::MaterialEffectsEngine::updateTrackParameters(
   // screen output
   EX_MSG_VERBOSE(eCell.navigationStep,
                  "layer",
-                 mLayer->geoID().value(),
+                 mLayer->geoID().value(GeometryID::layer_mask),
                  "material update with corr factor = " << pathCorrection);
   // get the actual material bin
   const MaterialProperties* materialProperties
@@ -270,7 +270,7 @@ Acts::MaterialEffectsEngine::updateTrackParameters(
     if (eCell.leadParameters != &eCell.startParameters) {
       EX_MSG_VERBOSE(eCell.navigationStep,
                      "layer",
-                     mLayer->geoID().value(),
+                     mLayer->geoID().value(GeometryID::layer_mask),
                      "material update on non-initial parameters.");
       // @todo how to update parameters
       // parameters.updateParameters(uParameters,uCovariance);
@@ -278,7 +278,7 @@ Acts::MaterialEffectsEngine::updateTrackParameters(
       EX_MSG_VERBOSE(
           eCell.navigationStep,
           "layer",
-          mLayer->geoID().value(),
+          mLayer->geoID().value(GeometryID::layer_mask),
           "material update on initial parameters, creating new ones.");
       // create new parameters
       const Surface& tSurface = parameters.associatedSurface();
@@ -292,7 +292,7 @@ Acts::MaterialEffectsEngine::updateTrackParameters(
     if (eCell.checkConfigurationMode(ExtrapolationMode::CollectMaterial)) {
       EX_MSG_VERBOSE(eCell.navigationStep,
                      "layer",
-                     mLayer->geoID().value(),
+                     mLayer->geoID().value(GeometryID::layer_mask),
                      "collecting material of [t/X0] = " << thicknessInX0);
       eCell.stepMaterial(*mSurface,
                          mLayer,
@@ -302,7 +302,7 @@ Acts::MaterialEffectsEngine::updateTrackParameters(
     } else {
       EX_MSG_VERBOSE(eCell.navigationStep,
                      "layer",
-                     mLayer->geoID().value(),
+                     mLayer->geoID().value(GeometryID::layer_mask),
                      "adding material of [t/X0] = " << thicknessInX0);
       eCell.addMaterial(pathCorrection, materialProperties);
     }
diff --git a/Core/src/Surfaces/DiamondBounds.cpp b/Core/src/Surfaces/DiamondBounds.cpp
index 632006fd4968d721c84b5b5ab2d1f8a4121ae974..8762bf437460d75f4b13cb6755435df2c8364e57 100644
--- a/Core/src/Surfaces/DiamondBounds.cpp
+++ b/Core/src/Surfaces/DiamondBounds.cpp
@@ -20,16 +20,23 @@ Acts::DiamondBounds::DiamondBounds(double minhalex,
                                    double maxhalex,
                                    double haley1,
                                    double haley2)
-  : PlanarBounds(DiamondBounds::bv_length), m_alpha1(0.), m_alpha2(0.)
+  : PlanarBounds(DiamondBounds::bv_length)
+  , m_alpha1(0.)
+  , m_alpha2(0.)
+  , m_boundingBox(0.,0.)
 {
   m_valueStore.at(DiamondBounds::bv_minHalfX) = minhalex;
   m_valueStore.at(DiamondBounds::bv_medHalfX) = medhalex;
   m_valueStore.at(DiamondBounds::bv_maxHalfX) = maxhalex;
   m_valueStore.at(DiamondBounds::bv_halfY1)   = haley1;
   m_valueStore.at(DiamondBounds::bv_halfY2)   = haley2;
-  if (minhalex > maxhalex)
-    std::swap(m_valueStore.at(DiamondBounds::bv_minHalfX),
-              m_valueStore.at(DiamondBounds::bv_maxHalfX));
+  double mx = minhalex > medhalex ? 
+              ( minhalex > maxhalex ? minhalex : maxhalex ) :
+  ( medhalex > maxhalex ? medhalex : maxhalex );
+  double my = haley1 > haley2 ? haley1 : haley2;
+  // the boundary box is being set
+  m_boundingBox = RectangleBounds(mx,my);
+  // init the cache 
   initCache();
 }
 
@@ -39,6 +46,7 @@ Acts::DiamondBounds::DiamondBounds(const DiamondBounds& diabo)
   , m_valueStore(diabo.m_valueStore)
   , m_alpha1(diabo.m_alpha1)
   , m_alpha2(diabo.m_alpha2)
+  , m_boundingBox(diabo.m_boundingBox)
 {
 }
 
@@ -51,40 +59,43 @@ Acts::DiamondBounds&
 Acts::DiamondBounds::operator=(const DiamondBounds& diabo)
 {
   if (this != &diabo) {
-    m_valueStore = diabo.m_valueStore;
-    m_alpha1     = diabo.m_alpha1;
-    m_alpha2     = diabo.m_alpha2;
+    m_valueStore  = diabo.m_valueStore;
+    m_alpha1      = diabo.m_alpha1;
+    m_alpha2      = diabo.m_alpha2;
+    m_boundingBox = diabo.m_boundingBox;
   }
   return *this;
 }
 
 bool
-Acts::DiamondBounds::operator==(const Acts::SurfaceBounds& sbo) const
+Acts::DiamondBounds::operator==(const SurfaceBounds& sbo) const
 {
   // fast exit
   if (&sbo == this) return true;
   // check the type first not to compare apples with oranges
-  const Acts::DiamondBounds* diabo
-      = dynamic_cast<const Acts::DiamondBounds*>(&sbo);
+  const DiamondBounds* diabo
+      = dynamic_cast<const DiamondBounds*>(&sbo);
   if (!diabo) return false;
   return (m_valueStore == diabo->m_valueStore);
 }
 
 // checking if inside bounds (Full symmetrical Diamond)
 bool
-Acts::DiamondBounds::inside(const Acts::Vector2D& locpo,
-                            double                tol1,
-                            double                tol2) const
+Acts::DiamondBounds::inside(const Vector2D& locpo,
+                            double          tol0,
+                            double          tol1) const
 {
-  return insideFull(locpo, tol1, tol2);
+  return insideFull(locpo, tol0, tol1);
 }
 
 // checking if inside bounds (Full symmetrical Diamond)
 bool
-Acts::DiamondBounds::insideFull(const Acts::Vector2D& locpo,
-                                double                tol1,
-                                double                tol2) const
+Acts::DiamondBounds::insideFull(const Vector2D& locpo,
+                                double          tol0,
+                                double          tol1) const
 {
+  // @todo updat with bounding box
+  
   // the cases:
   // (0)
   if (!m_valueStore.at(DiamondBounds::bv_halfY1)
@@ -92,20 +103,20 @@ Acts::DiamondBounds::insideFull(const Acts::Vector2D& locpo,
     return false;
   // (1)
   if (locpo[Acts::eLOC_Y]
-      < -2. * m_valueStore.at(DiamondBounds::bv_halfY1) - tol2)
+      < -2. * m_valueStore.at(DiamondBounds::bv_halfY1) - tol1)
     return false;
   if (locpo[Acts::eLOC_Y]
-      > 2. * m_valueStore.at(DiamondBounds::bv_halfY2) + tol2)
+      > 2. * m_valueStore.at(DiamondBounds::bv_halfY2) + tol1)
     return false;
   // (2)
-  if (std::abs(locpo[Acts::eLOC_X])
-      > (m_valueStore.at(DiamondBounds::bv_medHalfX) + tol1))
+  if (fabs(locpo[Acts::eLOC_X])
+      > (m_valueStore.at(DiamondBounds::bv_medHalfX) + tol0))
     return false;
   // (3)
   if (std::abs(locpo[Acts::eLOC_X])
       < (fmin(m_valueStore.at(DiamondBounds::bv_minHalfX),
               m_valueStore.at(DiamondBounds::bv_maxHalfX))
-         - tol1))
+         - tol0))
     return true;
   // (4)
   /** use basic calculation of a straight line */
diff --git a/Core/src/Surfaces/EllipseBounds.cpp b/Core/src/Surfaces/EllipseBounds.cpp
index 22d2dd7799252aa86c99ea93ad1bab5d376a08c1..c82b11cfc15e7ca188dde5da283b0ce6b50c310d 100644
--- a/Core/src/Surfaces/EllipseBounds.cpp
+++ b/Core/src/Surfaces/EllipseBounds.cpp
@@ -21,7 +21,8 @@ Acts::EllipseBounds::EllipseBounds(double minradX,
                                    double maxradY,
                                    double avephi,
                                    double hphisec)
-  : Acts::PlanarBounds(EllipseBounds::bv_length)
+  : PlanarBounds(EllipseBounds::bv_length),
+    m_boundingBox(0.,0.)
 {
   m_valueStore.at(EllipseBounds::bv_rMinX)         = minradX;
   m_valueStore.at(EllipseBounds::bv_rMinY)         = minradY;
@@ -29,14 +30,10 @@ Acts::EllipseBounds::EllipseBounds(double minradX,
   m_valueStore.at(EllipseBounds::bv_rMaxY)         = maxradY;
   m_valueStore.at(EllipseBounds::bv_averagePhi)    = avephi;
   m_valueStore.at(EllipseBounds::bv_halfPhiSector) = hphisec;
-  if (m_valueStore.at(EllipseBounds::bv_rMinX)
-      > m_valueStore.at(EllipseBounds::bv_rMaxX))
-    std::swap(m_valueStore.at(EllipseBounds::bv_rMinX),
-              m_valueStore.at(EllipseBounds::bv_rMaxX));
-  if (m_valueStore.at(EllipseBounds::bv_rMinY)
-      > m_valueStore.at(EllipseBounds::bv_rMaxY))
-    std::swap(m_valueStore.at(EllipseBounds::bv_rMinY),
-              m_valueStore.at(EllipseBounds::bv_rMaxY));
+  double mx = minradX > maxradX ? minradX : maxradX;
+  double my = minradY > maxradY ? minradY : maxradY;
+  m_boundingBox = RectangleBounds(mx,my);
+
 }
 
 Acts::EllipseBounds::~EllipseBounds()
@@ -46,7 +43,10 @@ Acts::EllipseBounds::~EllipseBounds()
 Acts::EllipseBounds&
 Acts::EllipseBounds::operator=(const EllipseBounds& ebo)
 {
-  if (this != &ebo) PlanarBounds::operator=(ebo);
+  if (this != &ebo) {
+    PlanarBounds::operator=(ebo);
+    m_boundingBox = ebo.m_boundingBox;
+  }
   return *this;
 }
 
diff --git a/Core/src/Surfaces/TrapezoidBounds.cpp b/Core/src/Surfaces/TrapezoidBounds.cpp
index 842a82a2a5a7d7699e4c65fdbd57f3c2d6cf5ee8..0328dbf1802fccd11d3a8934d989dc513f674bda 100644
--- a/Core/src/Surfaces/TrapezoidBounds.cpp
+++ b/Core/src/Surfaces/TrapezoidBounds.cpp
@@ -18,22 +18,30 @@
 Acts::TrapezoidBounds::TrapezoidBounds(double minhalex,
                                        double maxhalex,
                                        double haley)
-  : Acts::PlanarBounds(TrapezoidBounds::bv_length), m_alpha(0.), m_beta(0.)
+  : PlanarBounds(TrapezoidBounds::bv_length)
+  , m_alpha(0.)
+  , m_beta(0.)
+  , m_boundingBox(0.,0.)
 {
   m_valueStore.at(TrapezoidBounds::bv_minHalfX) = std::abs(minhalex);
   m_valueStore.at(TrapezoidBounds::bv_maxHalfX) = std::abs(maxhalex);
   m_valueStore.at(TrapezoidBounds::bv_halfY)    = std::abs(haley);
-  if (m_valueStore.at(TrapezoidBounds::bv_minHalfX)
-      > m_valueStore.at(TrapezoidBounds::bv_maxHalfX))
-    std::swap(m_valueStore.at(TrapezoidBounds::bv_minHalfX),
-              m_valueStore.at(TrapezoidBounds::bv_maxHalfX));
+  // find the maximum at for the bounding box  
+  double mx = m_valueStore.at(TrapezoidBounds::bv_minHalfX) > 
+              m_valueStore.at(TrapezoidBounds::bv_maxHalfX) ?
+              m_valueStore.at(TrapezoidBounds::bv_minHalfX) :
+              m_valueStore.at(TrapezoidBounds::bv_maxHalfX);
+  m_boundingBox = RectangleBounds(mx, m_valueStore.at(TrapezoidBounds::bv_halfY));
 }
 
 Acts::TrapezoidBounds::TrapezoidBounds(double minhalex,
                                        double haley,
                                        double alpha,
                                        double beta)
-  : Acts::PlanarBounds(TrapezoidBounds::bv_length), m_alpha(alpha), m_beta(beta)
+  : PlanarBounds(TrapezoidBounds::bv_length)
+  , m_alpha(alpha)
+  , m_beta(beta)
+  , m_boundingBox(0.,0.)
 {
   double gamma = (alpha > beta) ? (alpha - 0.5 * M_PI) : (beta - 0.5 * M_PI);
   // now fill them
@@ -41,6 +49,12 @@ Acts::TrapezoidBounds::TrapezoidBounds(double minhalex,
   m_valueStore.at(TrapezoidBounds::bv_maxHalfX) = minhalex
       + (2. * m_valueStore.at(TrapezoidBounds::bv_halfY)) * tan(gamma);
   m_valueStore.at(TrapezoidBounds::bv_halfY) = std::abs(haley);
+  // find the maximum for the bounding box
+  double mx = m_valueStore.at(TrapezoidBounds::bv_minHalfX) > 
+              m_valueStore.at(TrapezoidBounds::bv_maxHalfX) ?
+              m_valueStore.at(TrapezoidBounds::bv_minHalfX) :
+              m_valueStore.at(TrapezoidBounds::bv_maxHalfX);
+  m_boundingBox = RectangleBounds(mx, m_valueStore.at(TrapezoidBounds::bv_halfY));
 }
 
 Acts::TrapezoidBounds::~TrapezoidBounds()
@@ -54,6 +68,7 @@ Acts::TrapezoidBounds::operator=(const TrapezoidBounds& trabo)
     PlanarBounds::operator=(trabo);
     m_alpha               = trabo.m_alpha;
     m_beta                = trabo.m_beta;
+    m_boundingBox         = trabo.m_boundingBox;
   }
   return *this;
 }
@@ -74,15 +89,15 @@ Acts::TrapezoidBounds::insideFull(const Acts::Vector2D& lpos,
 {
   // the cases:
   // the cases:
-  double fabsX = std::abs(lpos[Acts::eLOC_X]);
-  double fabsY = std::abs(lpos[Acts::eLOC_Y]);
+  double std::absX = std::abs(lpos[Acts::eLOC_X]);
+  double std::absY = std::abs(lpos[Acts::eLOC_Y]);
   // (1) a fast FALSE
-  if (fabsY > (m_valueStore.at(TrapezoidBounds::bv_halfY) + tol1)) return false;
+  if (std::absY > (m_valueStore.at(TrapezoidBounds::bv_halfY) + tol1)) return false;
   // (2) a fast FALSE
-  if (fabsX > (m_valueStore.at(TrapezoidBounds::bv_maxHalfX) + tol0))
+  if (std::absX > (m_valueStore.at(TrapezoidBounds::bv_maxHalfX) + tol0))
     return false;
   // (3) a fast TRUE
-  if (fabsX < (m_valueStore.at(TrapezoidBounds::bv_minHalfX) - tol0))
+  if (std::absX < (m_valueStore.at(TrapezoidBounds::bv_minHalfX) - tol0))
     return true;
   // (4) particular case - a rectangle
   if (m_valueStore.at(TrapezoidBounds::bv_maxHalfX)
diff --git a/Core/src/Surfaces/TriangleBounds.cpp b/Core/src/Surfaces/TriangleBounds.cpp
index 23d327a0371a5c565a988470a3f97dda4e0af0a2..17e2174cb9360491a07547a3f2dab6ffd8ee82c6 100644
--- a/Core/src/Surfaces/TriangleBounds.cpp
+++ b/Core/src/Surfaces/TriangleBounds.cpp
@@ -15,13 +15,18 @@
 #include <iostream>
 
 Acts::TriangleBounds::TriangleBounds(const std::vector<Vector2D>& vertices)
-  : Acts::PlanarBounds()
+  : PlanarBounds()
+  , m_boundingBox(0.,0.)
 {
   m_valueStore.reserve(6);
+  double mx, my = 0.;
   for (auto& v : vertices) {
     m_valueStore.push_back(v.x());
     m_valueStore.push_back(v.y());
+    mx =  (fabs(v.x()) > mx)? fabs(v.x()) : mx;
+    my =  (fabs(v.y()) > my)? fabs(v.y()) : my;
   }
+  m_boundingBox = RectangleBounds(mx, my);
 }
 
 Acts::TriangleBounds::~TriangleBounds()
@@ -31,7 +36,10 @@ Acts::TriangleBounds::~TriangleBounds()
 Acts::TriangleBounds&
 Acts::TriangleBounds::operator=(const TriangleBounds& tribo)
 {
-  if (this != &tribo) Acts::PlanarBounds::operator=(tribo);
+  if (this != &tribo) {
+    PlanarBounds::operator=(tribo);
+    m_boundingBox = tribo.m_boundingBox;
+  }
   return *this;
 }
 
diff --git a/Examples/include/ACTS/Examples/GenericDetectorElement.hpp b/Examples/include/ACTS/Examples/GenericDetectorElement.hpp
index 59a96c679bb3e70f9707255613734b1af4af0258..7e565e0c9e9c1110d38730260e47254ec503a21c 100644
--- a/Examples/include/ACTS/Examples/GenericDetectorElement.hpp
+++ b/Examples/include/ACTS/Examples/GenericDetectorElement.hpp
@@ -13,10 +13,8 @@
 #ifndef AGD_GENERICDETECTORELEMENT_GENERICDETECTORELEMENT
 #define AGD_GENERICDETECTORELEMENT_GENERICDETECTORELEMENT 1
 
-// Algebra and Identifier
 #include "ACTS/Utilities/Definitions.hpp"
 #include "ACTS/Utilities/Identifier.hpp"
-// Geometry module
 #include "ACTS/Detector/DetectorElementBase.hpp"
 
 namespace Acts {
@@ -25,6 +23,7 @@ class Surface;
 class PlanarBounds;
 class DiscBounds;
 class SurfaceMaterial;
+class DigitizationModule;
 
 /// @class GenericDetectorElement
 ///
@@ -47,6 +46,8 @@ public:
                          std::shared_ptr<const PlanarBounds>    pBounds,
                          double                                 thickness,
                          std::shared_ptr<const SurfaceMaterial> material
+                         = nullptr,
+                         std::shared_ptr<const DigitizationModule> dModule
                          = nullptr);
 
   /// Constructor for single sided detector element
@@ -96,6 +97,10 @@ public:
   double
   thickness() const override;
 
+  /// Returning the digitization module
+  std::shared_ptr<const DigitizationModule>
+  digitizationModule() const;
+
 private:
   /// the element representation
   /// identifier
@@ -104,6 +109,7 @@ private:
   std::shared_ptr<Transform3D> m_elementTransform;
   /// the surface represented by it
   std::shared_ptr<const Surface> m_elementSurface;
+
   /// the element thickness
   double m_elementThickness;
 
@@ -112,6 +118,9 @@ private:
   /// store either
   std::shared_ptr<const PlanarBounds> m_elementPlanarBounds;
   std::shared_ptr<const DiscBounds>   m_elementDiscBounds;
+
+  // the digitization module
+  std::shared_ptr<const DigitizationModule> m_digitizationModule;
 };
 
 inline Identifier
@@ -144,6 +153,12 @@ GenericDetectorElement::thickness() const
   return m_elementThickness;
 }
 
+inline std::shared_ptr<const DigitizationModule>
+GenericDetectorElement::digitizationModule() const
+{
+  return m_digitizationModule;
+}
+
 }  // end of ns
 
 #endif
diff --git a/Examples/include/ACTS/Examples/GenericLayerBuilder.hpp b/Examples/include/ACTS/Examples/GenericLayerBuilder.hpp
index b0db29ad76be55bc748d021922e2ac826beda072..4dcc7ed4ee6a4c4c133ee8901bb4e87733c3b1df 100644
--- a/Examples/include/ACTS/Examples/GenericLayerBuilder.hpp
+++ b/Examples/include/ACTS/Examples/GenericLayerBuilder.hpp
@@ -68,6 +68,14 @@ public:
     std::vector<double> centralModuleHalfY;
     /// the module bounds: local z -> thickness
     std::vector<double> centralModuleThickness;
+    /// the central volume readout schema
+    std::vector<size_t> centralModuleReadoutBinsX;
+    /// the central volume readout schema
+    std::vector<size_t> centralModuleReadoutBinsY;
+    /// the central volume readout schema
+    std::vector<int> centralModuleReadoutSide;
+    /// the central volume readout schema
+    std::vector<double> centralModuleLorentzAngle;
     /// the module material @todo change to surface material
     std::vector<Material> centralModuleMaterial;
     /// the module front side stereo (if exists)
@@ -100,6 +108,14 @@ public:
     std::vector<std::vector<double>> posnegModuleHalfY;
     /// the module bounds: local z -> thickness
     std::vector<std::vector<double>> posnegModuleThickness;
+    /// the central volume readout schema
+    std::vector<std::vector<size_t>> posnegModuleReadoutBinsX;
+    /// the central volume readout schema
+    std::vector<std::vector<size_t>> posnegModuleReadoutBinsY;
+    /// the central volume readout schema
+    std::vector<std::vector<int>>    posnegModuleReadoutSide;
+    /// the central volume readout schema
+    std::vector<std::vector<double>> posnegModuleLorentzAngle;
     /// the module material @todo change to surface material
     std::vector<std::vector<Material>> posnegModuleMaterial;
     /// the module front side stereo (if exists)
diff --git a/Examples/src/GenericDetector.ipp b/Examples/src/GenericDetector.ipp
index cd5c0c342c3536eb9dd4d3d3a7e2b0ff4991ad9e..632158bf23aca6672cbaf980b1def47495d016a9 100644
--- a/Examples/src/GenericDetector.ipp
+++ b/Examples/src/GenericDetector.ipp
@@ -6,7 +6,6 @@
 // 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/.
 
-
 //-------------------------------------------------------------------------------------
 // beam pipe
 //-------------------------------------------------------------------------------------
@@ -67,7 +66,10 @@ if (stage == 0) {
   plbConfig.centralModuleHalfX                = {8.4};
   plbConfig.centralModuleHalfY                = {32.};
   plbConfig.centralModuleThickness            = {0.15};
-  plbConfig.centralModuleMaterial             = {pcMaterial};
+  plbConfig.centralModuleReadoutBinsX         = {336};
+  plbConfig.centralModuleReadoutBinsY         = {1280};
+  plbConfig.centralModuleReadoutSide          = {-1};
+  plbConfig.centralModuleLorentzAngle         = {0.12};
 } else {
   // configure the central barrel
   plbConfig.centralLayerBinMultipliers = {1, 1};
@@ -86,6 +88,11 @@ if (stage == 0) {
   plbConfig.centralModuleThickness = {0.15, 0.15, 0.15, 0.15};
   plbConfig.centralModuleMaterial
       = {pcMaterial, pcMaterial, pcMaterial, pcMaterial};
+
+  plbConfig.centralModuleReadoutBinsX = {336, 336, 336, 336};
+  plbConfig.centralModuleReadoutBinsY = {1280, 1280, 1280, 1280};
+  plbConfig.centralModuleReadoutSide  = {-1, -1, -1, -1};
+  plbConfig.centralModuleLorentzAngle = {0.12, 0.12, 0.12, 0.12};
 }
 // no frontside/backside
 plbConfig.centralModuleFrontsideStereo = {};
@@ -112,11 +119,15 @@ if (stage == 0) {
   plbConfig.posnegLayerMaterialConcentration = {1};
   plbConfig.posnegLayerMaterialProperties    = {pcmProperties};
   plbConfig.posnegModuleMinHalfX             = {{8.4}};
-  plbConfig.posnegModuleMaxHalfX             = {};
-  plbConfig.posnegModuleHalfY                = {{42.}};
-  plbConfig.posnegModulePhiBins              = {{48}};
-  plbConfig.posnegModuleThickness            = {{0.15}};
-  plbConfig.posnegModuleMaterial             = {{pcMaterial}};
+  plbConfig.posnegModuleMaxHalfX = {};
+  plbConfig.posnegModuleHalfY    = {{42.}};
+  plbConfig.posnegModulePhiBins = {{48}};
+  plbConfig.posnegModuleThickness = {{0.15}};
+  plbConfig.posnegModuleReadoutBinsX = {{336}};
+  plbConfig.posnegModuleReadoutBinsY = {{1680}};
+  plbConfig.posnegModuleReadoutSide = {{-1}};
+  plbConfig.posnegModuleLorentzAngle = {{0.12}};
+  plbConfig.posnegModuleMaterial = {{pcMaterial}};
 } else {
   // STAGE > 0 - pixel endcap detector
   // configure the endcaps
@@ -126,11 +137,15 @@ if (stage == 0) {
   plbConfig.posnegLayerMaterialConcentration = {1, 1, 1, 1};
   plbConfig.posnegLayerMaterialProperties
       = {pcmProperties, pcmProperties, pcmProperties, pcmProperties};
-  plbConfig.posnegModuleMinHalfX  = {{8.4}, {8.4}, {8.4}, {8.4}};
-  plbConfig.posnegModuleMaxHalfX  = {};
-  plbConfig.posnegModuleHalfY     = {{42.}, {42.}, {42.}, {42.}};
-  plbConfig.posnegModulePhiBins   = {{48}, {48}, {48}, {48}};
+  plbConfig.posnegModuleMinHalfX = {{8.4}, {8.4}, {8.4}, {8.4}};
+  plbConfig.posnegModuleMaxHalfX = {};
+  plbConfig.posnegModuleHalfY    = {{42.}, {42.}, {42.}, {42.}};
+  plbConfig.posnegModulePhiBins = {{48}, {48}, {48}, {48}};
   plbConfig.posnegModuleThickness = {{0.15}, {0.15}, {0.15}, {0.15}};
+  plbConfig.posnegModuleReadoutBinsX = {{336}, {336}, {336}, {336}};
+  plbConfig.posnegModuleReadoutBinsY = {{1680}, {1680}, {1680}, {1680}};
+  plbConfig.posnegModuleReadoutSide  = {{-1}, {-1}, {-1}, {-1}};
+  plbConfig.posnegModuleLorentzAngle = {{0.}, {0.}, {0.}, {0.}};
   plbConfig.posnegModuleMaterial
       = {{pcMaterial}, {pcMaterial}, {pcMaterial}, {pcMaterial}};
 }
@@ -187,7 +202,7 @@ if (stage > 1) {
   pstConfig.centralLayerHalflengthZ = std::vector<double>(1, 1200.);
   pstConfig.centralLayerThickness   = std::vector<double>(1, 1.8);
   pstConfig.centralLayerMaterial = {Material(352.8, 407., 9.012, 4., 1.848e-3)};
-  auto pstBuilder                = std::make_shared<PassiveLayerBuilder>(
+  auto pstBuilder = std::make_shared<PassiveLayerBuilder>(
       pstConfig, getDefaultLogger("PstBuilder", layerLLevel));
   // create the volume for the beam pipe
   CylinderVolumeBuilder::Config pstvolConfig;
@@ -226,10 +241,16 @@ if (stage > 1) {
   sslbConfig.centralLayerMaterialProperties
       = {ssmProperties, ssmProperties, ssmProperties};
   sslbConfig.centralModuleBinningSchema = {{42, 12}, {64, 12}, {84, 12}};
-  sslbConfig.centralModuleTiltPhi       = {-0.15, -0.15, -0.15};
-  sslbConfig.centralModuleHalfX         = {18.2, 18.2, 18.2};
-  sslbConfig.centralModuleHalfY         = {68., 68., 68.};
-  sslbConfig.centralModuleThickness     = {0.25, 0.25, 0.25};
+  sslbConfig.centralModuleTiltPhi   = {-0.15, -0.15, -0.15};
+  sslbConfig.centralModuleHalfX     = {18.2, 18.2, 18.2};
+  sslbConfig.centralModuleHalfY     = {68., 68., 68.};
+  sslbConfig.centralModuleThickness = {0.25, 0.25, 0.25};
+  
+  sslbConfig.centralModuleReadoutBinsX = { 728, 728, 728 }; // 50 um pitch
+  sslbConfig.centralModuleReadoutBinsY = { 85, 85, 85 }; // 1.6 mm strixels
+  sslbConfig.centralModuleReadoutSide  = { 1,  1,  1};
+  sslbConfig.centralModuleLorentzAngle = { 0.12, 0.12, 0.12 };
+  
   sslbConfig.centralModuleMaterial
       = {ssMaterial, ssMaterial, ssMaterial, ssMaterial};
   sslbConfig.centralModuleFrontsideStereo = {-0.02, -0.02, -0.02};
@@ -248,10 +269,17 @@ if (stage > 1) {
   }
   sslbConfig.centralModulePositions = centralModulePositions;
 
-  // configure the endcaps
-  std::vector<double>   mrMinHx    = {16.4, 24.2, 32.2};
-  std::vector<double>   mrMaxHx    = {24.2, 32.2, 40.0};
-  std::vector<double>   mrHy       = {48., 48., 48.};
+  // configure the endcaps 
+  std::vector<double>   mrMinHx    = { 16.4, 24.2, 32.2 };
+  std::vector<double>   mrMaxHx    = { 24.2, 32.2, 40.0 };
+  std::vector<double>   mrHy       = { 48., 48., 48. };
+  
+  // simplified strixels readout
+  std::vector<size_t>  mrReadoutBinsX  = { 968 , 1288, 1600}; // 50 um pitch
+  std::vector<size_t>  mrReadoutBinsY  = { 60, 60, 60 }; // 1.6 mm strixels
+  std::vector<int>     mrReadoutSide   = { 1, 1, 1 };
+  std::vector<double>  mrLorentzAngle  = { 0., 0., 0. };
+  
   std::vector<int>      mPhiBins   = {42, 58, 72};
   std::vector<double>   mThickness = {0.2, 0.2, 0.2};
   std::vector<Material> mMaterial  = {ssMaterial, ssMaterial, ssMaterial};
@@ -276,6 +304,17 @@ if (stage > 1) {
       = std::vector<std::vector<int>>(nposnegs, mPhiBins);
   sslbConfig.posnegModuleThickness
       = std::vector<std::vector<double>>(nposnegs, mThickness);
+  
+  sslbConfig.posnegModuleReadoutBinsX
+      = std::vector<std::vector<size_t>>(nposnegs, mrReadoutBinsX);
+  sslbConfig.posnegModuleReadoutBinsY
+      = std::vector<std::vector<size_t>>(nposnegs, mrReadoutBinsY);
+  sslbConfig.posnegModuleReadoutSide
+      = std::vector<std::vector<int>>(nposnegs, mrReadoutSide);
+  sslbConfig.posnegModuleLorentzAngle
+      = std::vector<std::vector<double>>(nposnegs, mrLorentzAngle);
+  
+  
   sslbConfig.posnegModuleMaterial
       = std::vector<std::vector<Material>>(nposnegs, mMaterial);
   sslbConfig.posnegModuleFrontsideStereo
@@ -350,6 +389,12 @@ if (stage > 2) {
   lslbConfig.centralModuleThickness            = {0.25, 0.25, 0.25};
   lslbConfig.centralModuleMaterial
       = {lsMaterial, lsMaterial, lsMaterial, lsMaterial};
+  
+  lslbConfig.centralModuleReadoutBinsX    = { 840, 840  }; // 100 um pitch
+  lslbConfig.centralModuleReadoutBinsY    = { 2, 2  }; //2 strips
+  lslbConfig.centralModuleReadoutSide     = { 1,  1 };
+  lslbConfig.centralModuleLorentzAngle    = { 0.08, 0.08 };
+  
   lslbConfig.centralModuleFrontsideStereo = {-0.02, -0.02};
   lslbConfig.centralModuleBacksideStereo  = {0.02, 0.02};
   lslbConfig.centralModuleBacksideGap     = {2., 2.};
@@ -375,7 +420,13 @@ if (stage > 2) {
   std::vector<Material> mMaterial  = {lsMaterial, lsMaterial, lsMaterial};
   std::vector<double>   mfStereo   = {-0.02, -0.02, -0.02};
   std::vector<double>   mbStereo   = {0.02, 0.02, 0.02};
-  std::vector<double>   mfbGap     = {2., 2., 2.};
+  std::vector<double>   mfbGap     = {4., 4., 4.};
+
+  std::vector<size_t>  mrReadoutBinsX  = { 1120 , 1120, 1120}; // 100 um pitch
+  std::vector<size_t>  mrReadoutBinsY  = { 2, 2, 2 }; // 2 strips
+  std::vector<int>     mrReadoutSide   = { 1, 1, 1 };
+  std::vector<double>  mrLorentzAngle  = { 0., 0., 0. };
+
 
   // endcap
   lslbConfig.posnegLayerBinMultipliers = {1, 2};
@@ -395,6 +446,16 @@ if (stage > 2) {
       = std::vector<std::vector<int>>(nposnegs, mPhiBins);
   lslbConfig.posnegModuleThickness
       = std::vector<std::vector<double>>(nposnegs, mThickness);
+  
+  lslbConfig.posnegModuleReadoutBinsX
+      = std::vector<std::vector<size_t>>(nposnegs, mrReadoutBinsX);
+  lslbConfig.posnegModuleReadoutBinsY
+      = std::vector<std::vector<size_t>>(nposnegs, mrReadoutBinsY);
+  lslbConfig.posnegModuleReadoutSide
+      = std::vector<std::vector<int>>(nposnegs, mrReadoutSide);
+  lslbConfig.posnegModuleLorentzAngle
+      = std::vector<std::vector<double>>(nposnegs, mrLorentzAngle);  
+  
   lslbConfig.posnegModuleMaterial
       = std::vector<std::vector<Material>>(nposnegs, mMaterial);
   lslbConfig.posnegModuleFrontsideStereo
@@ -432,4 +493,4 @@ if (stage > 2) {
       lsvbConfig, getDefaultLogger("LStripVolumeBuilder", volumeLLevel));
   // add to the list of builders
   volumeBuilders.push_back(lstripVolumeBuilder);
-}
\ No newline at end of file
+}
diff --git a/Examples/src/GenericDetectorElement.cpp b/Examples/src/GenericDetectorElement.cpp
index bd63db1cb5b1344155e7b31dfc87791294dc72e1..10bf56e1a46944d9fbd2d97a733226c5ff2726a3 100644
--- a/Examples/src/GenericDetectorElement.cpp
+++ b/Examples/src/GenericDetectorElement.cpp
@@ -17,11 +17,12 @@
 #include "ACTS/Surfaces/PlaneSurface.hpp"
 
 Acts::GenericDetectorElement::GenericDetectorElement(
-    const Identifier                             identifier,
-    std::shared_ptr<Acts::Transform3D>           transform,
-    std::shared_ptr<const Acts::PlanarBounds>    pBounds,
-    double                                       thickness,
-    std::shared_ptr<const Acts::SurfaceMaterial> material)
+    const Identifier                       identifier,
+    std::shared_ptr<Transform3D>           transform,
+    std::shared_ptr<const PlanarBounds>    pBounds,
+    double                                 thickness,
+    std::shared_ptr<const SurfaceMaterial> material,
+    std::shared_ptr<const DigitizationModule> dModule)
   : DetectorElementBase()
   , m_elementIdentifier(std::move(identifier))
   , m_elementTransform(std::move(transform))
@@ -30,6 +31,7 @@ Acts::GenericDetectorElement::GenericDetectorElement(
   , m_elementSurfaces({m_elementSurface})
   , m_elementPlanarBounds(std::move(pBounds))
   , m_elementDiscBounds(nullptr)
+  , m_digitizationModule(dModule)
 {
   m_elementSurface->setAssociatedMaterial(material);
 }
diff --git a/Examples/src/GenericLayerBuilder.cpp b/Examples/src/GenericLayerBuilder.cpp
index ede63340164a0ba7a77efbd9359bd8f52d8b3fb1..b29e143cb451ef7a098accbdc6090a67fe714d70 100644
--- a/Examples/src/GenericLayerBuilder.cpp
+++ b/Examples/src/GenericLayerBuilder.cpp
@@ -27,6 +27,8 @@
 #include "ACTS/Utilities/BinUtility.hpp"
 #include "ACTS/Utilities/BinnedArray.hpp"
 #include "ACTS/Utilities/Helpers.hpp"
+#include "ACTS/Digitization/CartesianSegmentation.hpp"
+#include "ACTS/Digitization/DigitizationModule.hpp"
 
 Acts::GenericLayerBuilder::GenericLayerBuilder(
     const Acts::GenericLayerBuilder::Config& glbConfig,
@@ -104,6 +106,26 @@ Acts::GenericLayerBuilder::constructLayers()
                  << " )");
 
       sVector.reserve(nCetralModules);
+
+      // prepartion :
+      // create digitizaiton module
+      std::shared_ptr<const DigitizationModule> moduleDigitizationPtr = nullptr;
+      if (m_cfg.centralModuleReadoutBinsX.size()) {
+        // create the CartesianSegmentation
+        std::shared_ptr<const Segmentation> moduleSegmentation
+            = std::make_shared<const CartesianSegmentation>(
+                moduleBounds,
+                m_cfg.centralModuleReadoutBinsX.at(icl),
+                m_cfg.centralModuleReadoutBinsY.at(icl));
+        // now create the digitzation module
+        moduleDigitizationPtr = std::make_shared<const DigitizationModule>(
+            moduleSegmentation,
+            m_cfg.centralModuleThickness.at(icl),
+            m_cfg.centralModuleReadoutSide.at(icl),
+            m_cfg.centralModuleLorentzAngle.at(icl));
+      }
+
+      // prepartation :
       // create the Module material from input
       std::shared_ptr<const SurfaceMaterial> moduleMaterialPtr = nullptr;
       if (m_cfg.centralModuleMaterial.size()) {
@@ -161,7 +183,8 @@ Acts::GenericLayerBuilder::constructLayers()
                                          moduleTransform,
                                          moduleBounds,
                                          moduleThickness,
-                                         moduleMaterialPtr);
+                                         moduleMaterialPtr,
+                                         moduleDigitizationPtr);
         // register the surface
         sVector.push_back(&module->surface());
         // store the module
@@ -191,7 +214,8 @@ Acts::GenericLayerBuilder::constructLayers()
                                            moduleTransform,
                                            moduleBounds,
                                            moduleThickness,
-                                           moduleMaterialPtr);
+                                           moduleMaterialPtr,
+                                           moduleDigitizationPtr);
           // register the backside as bin member
           std::vector<const DetectorElementBase*> bsbinmember = {module};
           std::vector<const DetectorElementBase*> binmember   = {bsmodule};
@@ -275,14 +299,40 @@ Acts::GenericLayerBuilder::constructLayers()
       for (auto& discModulePositions : m_cfg.posnegModulePositions.at(ipnl)) {
         ACTS_VERBOSE("- building ring " << ipnR << " for this pair.");
         // now prepare all the shared stuff
-        // (1) module specifications
+        // (0) module specifications
         double moduleThickness = m_cfg.posnegModuleThickness.at(ipnl).at(ipnR);
         double moduleMinHalfX  = m_cfg.posnegModuleMinHalfX.at(ipnl).at(ipnR);
         double moduleMaxHalfX  = m_cfg.posnegModuleMaxHalfX.size()
             ? m_cfg.posnegModuleMaxHalfX.at(ipnl).at(ipnR)
             : 0.;
         double moduleHalfY = m_cfg.posnegModuleHalfY.at(ipnl).at(ipnR);
-        // (2) module material
+        // (1) module bounds
+        // create the bounds
+        PlanarBounds* pBounds = nullptr;
+        if (moduleMaxHalfX != 0. && moduleMinHalfX != moduleMaxHalfX)
+        pBounds = new TrapezoidBounds(
+                                      moduleMinHalfX, moduleMaxHalfX, moduleHalfY);
+        else
+        pBounds = new RectangleBounds(moduleMinHalfX, moduleHalfY);
+        // now create the shared bounds from it
+        std::shared_ptr<const PlanarBounds> moduleBounds(pBounds);
+        // (2) create digitizaiton module
+        std::shared_ptr<const DigitizationModule> moduleDigitizationPtr = nullptr;
+        if (m_cfg.posnegModuleReadoutBinsX.size()) {
+          // create the CartesianSegmentation
+          std::shared_ptr<const Segmentation> moduleSegmentation
+              = std::make_shared<const CartesianSegmentation>(
+                  moduleBounds,
+                  m_cfg.posnegModuleReadoutBinsX.at(ipnl).at(ipnR),
+                  m_cfg.posnegModuleReadoutBinsY.at(ipnl).at(ipnR));
+          // now create the digitzation module
+          moduleDigitizationPtr = std::make_shared<const DigitizationModule>(
+              moduleSegmentation,
+              moduleThickness,
+              m_cfg.posnegModuleReadoutSide.at(ipnl).at(ipnR),
+              m_cfg.posnegModuleLorentzAngle.at(ipnl).at(ipnR));
+        }
+        // (3) module material
         // create the Module material from input
         std::shared_ptr<const SurfaceMaterial> moduleMaterialPtr = nullptr;
         if (m_cfg.posnegModuleMaterial.size()) {
@@ -292,16 +342,7 @@ Acts::GenericLayerBuilder::constructLayers()
           moduleMaterialPtr = std::shared_ptr<const SurfaceMaterial>(
               new HomogeneousSurfaceMaterial(moduleMaterialProperties));
         }
-        // (3) module bounds
-        // create the bounds
-        PlanarBounds* pBounds = nullptr;
-        if (moduleMaxHalfX != 0. && moduleMinHalfX != moduleMaxHalfX)
-          pBounds = new TrapezoidBounds(
-              moduleMinHalfX, moduleMaxHalfX, moduleHalfY);
-        else
-          pBounds = new RectangleBounds(moduleMinHalfX, moduleHalfY);
-        // now create the shared bounds from it
-        std::shared_ptr<const PlanarBounds> moduleBounds(pBounds);
+
         // low loop over the phi positions and build the stuff
         for (auto& ringModulePosition : discModulePositions) {
           // the module transform from the position
@@ -346,13 +387,15 @@ Acts::GenericLayerBuilder::constructLayers()
                                            nModuleTransform,
                                            moduleBounds,
                                            moduleThickness,
-                                           moduleMaterialPtr);
+                                           moduleMaterialPtr,
+                                           moduleDigitizationPtr);
           GenericDetectorElement* pmodule
               = new GenericDetectorElement(pModuleIdentifier,
                                            pModuleTransform,
                                            moduleBounds,
                                            moduleThickness,
-                                           moduleMaterialPtr);
+                                           moduleMaterialPtr,
+                                           moduleDigitizationPtr);
           // memory management - we need a detector store to hold them somewhere
           // @todo add detector store facility
           m_posnegModule.push_back(nmodule);
@@ -390,13 +433,15 @@ Acts::GenericLayerBuilder::constructLayers()
                                              nModuleTransform,
                                              moduleBounds,
                                              moduleThickness,
-                                             moduleMaterialPtr);
+                                             moduleMaterialPtr,
+                                             moduleDigitizationPtr);
             GenericDetectorElement* bspmodule
                 = new GenericDetectorElement(pModuleIdentifier,
                                              pModuleTransform,
                                              moduleBounds,
                                              moduleThickness,
-                                             moduleMaterialPtr);
+                                             moduleMaterialPtr,
+                                             moduleDigitizationPtr);
             // register the backside of the binmembers
             std::vector<const DetectorElementBase*> bspbinmember = {pmodule};
             std::vector<const DetectorElementBase*> pbinmember   = {bspmodule};