From b9e0b5db088c74ceb31e564f38d1a7ba001c6590 Mon Sep 17 00:00:00 2001
From: Christian Grefe <Christian.Grefe@cern.ch>
Date: Tue, 4 Nov 2014 17:02:06 +0000
Subject: [PATCH] Removed old version of reconstruction interface and added new
 one

---
 DDRec/include/DDRec/API/Calorimeter.h         |  31 +++
 DDRec/include/DDRec/API/Exceptions.h          |  70 +++++
 DDRec/include/DDRec/API/IDDecoder.h           | 125 +++++++++
 DDRec/include/DDRec/API/LayeredSubdetector.h  | 121 +++++++++
 DDRec/include/DDRec/API/Subdetector.h         |  46 ++++
 DDRec/include/DDRec/API/Tracker.h             |  42 +++
 DDRec/include/DDRec/BarrelDetector.h          |  30 ---
 DDRec/include/DDRec/Calorimeter.h             |  29 --
 .../DDRec/CylindricalBarrelCalorimeter.h      |  25 --
 DDRec/include/DDRec/CylindricalCalorimeter.h  |  25 --
 DDRec/include/DDRec/CylindricalDetector.h     |  43 ---
 .../DDRec/CylindricalEndcapCalorimeter.h      |  25 --
 DDRec/include/DDRec/EndcapDetector.h          |  29 --
 .../DDRec/Extensions/CalorimeterExtension.h   |  24 ++
 .../DDRec/Extensions/LayeringExtension.h      |  87 ++++++
 .../DDRec/Extensions/LayeringExtensionImpl.h  | 127 +++++++++
 .../DDRec/Extensions/TrackerExtension.h       |  24 ++
 DDRec/include/DDRec/LayerStack.h              |  58 ----
 DDRec/include/DDRec/LayeredSubdetector.h      |  77 ------
 .../DDRec/PolyhedralBarrelCalorimeter.h       |  25 --
 DDRec/include/DDRec/PolyhedralCalorimeter.h   |  25 --
 DDRec/include/DDRec/PolyhedralDetector.h      |  44 ----
 .../DDRec/PolyhedralEndcapCalorimeter.h       |  25 --
 DDRec/include/DDRec/VertexBarrelDetector.h    |  30 ---
 DDRec/src/IDDecoder.cpp                       | 217 +++++++++++++++
 DDRec/src/LayerStack.cpp                      | 162 ------------
 DDRec/src/LayeredSubdetector.cpp              |  20 --
 DDRec/src/LayeringExtensionImpl.cpp           | 247 ++++++++++++++++++
 DDRec/src/Subdetector.cpp                     |  42 +++
 DDRec/src/VertexBarrelDetector.cpp            |  14 -
 30 files changed, 1203 insertions(+), 686 deletions(-)
 create mode 100644 DDRec/include/DDRec/API/Calorimeter.h
 create mode 100644 DDRec/include/DDRec/API/Exceptions.h
 create mode 100644 DDRec/include/DDRec/API/IDDecoder.h
 create mode 100644 DDRec/include/DDRec/API/LayeredSubdetector.h
 create mode 100644 DDRec/include/DDRec/API/Subdetector.h
 create mode 100644 DDRec/include/DDRec/API/Tracker.h
 delete mode 100644 DDRec/include/DDRec/BarrelDetector.h
 delete mode 100644 DDRec/include/DDRec/Calorimeter.h
 delete mode 100644 DDRec/include/DDRec/CylindricalBarrelCalorimeter.h
 delete mode 100644 DDRec/include/DDRec/CylindricalCalorimeter.h
 delete mode 100644 DDRec/include/DDRec/CylindricalDetector.h
 delete mode 100644 DDRec/include/DDRec/CylindricalEndcapCalorimeter.h
 delete mode 100644 DDRec/include/DDRec/EndcapDetector.h
 create mode 100644 DDRec/include/DDRec/Extensions/CalorimeterExtension.h
 create mode 100644 DDRec/include/DDRec/Extensions/LayeringExtension.h
 create mode 100644 DDRec/include/DDRec/Extensions/LayeringExtensionImpl.h
 create mode 100644 DDRec/include/DDRec/Extensions/TrackerExtension.h
 delete mode 100644 DDRec/include/DDRec/LayerStack.h
 delete mode 100644 DDRec/include/DDRec/LayeredSubdetector.h
 delete mode 100644 DDRec/include/DDRec/PolyhedralBarrelCalorimeter.h
 delete mode 100644 DDRec/include/DDRec/PolyhedralCalorimeter.h
 delete mode 100644 DDRec/include/DDRec/PolyhedralDetector.h
 delete mode 100644 DDRec/include/DDRec/PolyhedralEndcapCalorimeter.h
 delete mode 100644 DDRec/include/DDRec/VertexBarrelDetector.h
 create mode 100644 DDRec/src/IDDecoder.cpp
 delete mode 100644 DDRec/src/LayerStack.cpp
 delete mode 100644 DDRec/src/LayeredSubdetector.cpp
 create mode 100644 DDRec/src/LayeringExtensionImpl.cpp
 create mode 100644 DDRec/src/Subdetector.cpp
 delete mode 100644 DDRec/src/VertexBarrelDetector.cpp

diff --git a/DDRec/include/DDRec/API/Calorimeter.h b/DDRec/include/DDRec/API/Calorimeter.h
new file mode 100644
index 000000000..3c9c69d0b
--- /dev/null
+++ b/DDRec/include/DDRec/API/Calorimeter.h
@@ -0,0 +1,31 @@
+/*
+ * Calorimeter.h
+ *
+ * Basic reconstruction interface for calorimeters
+ *
+ *  Created on: Dec 11, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#ifndef DDRec_CALORIMETER_H_
+#define DDRec_CALORIMETER_H_
+
+#include "DDRec/API/LayeredSubdetector.h"
+#include "DDRec/API/Subdetector.h"
+
+namespace DD4hep {
+namespace DDRec {
+
+class Calorimeter: public LayeredSubdetector, public Subdetector {
+public:
+	Calorimeter(const Geometry::DetElement& det) :
+		Geometry::DetElement(det), LayeredSubdetector(det), Subdetector(det) {
+
+	}
+
+	virtual ~Calorimeter() {}
+};
+
+} /* namespace DDRec */
+} /* namespace DD4hep */
+#endif /* DDRec_CALORIMETER_H_ */
diff --git a/DDRec/include/DDRec/API/Exceptions.h b/DDRec/include/DDRec/API/Exceptions.h
new file mode 100644
index 000000000..8ad8e12a8
--- /dev/null
+++ b/DDRec/include/DDRec/API/Exceptions.h
@@ -0,0 +1,70 @@
+/*
+ * Exceptions.h
+ *
+ * Collection of Exception classes used in DDRec
+ *
+ *  Created on: Oct 31, 2014
+ *      Author: Christian Grefe, Bonn University
+ */
+
+#ifndef DDRec_EXCEPTIONS_H_
+#define DDRec_EXCEPTIONS_H_
+
+#include "DD4hep/Detector.h"
+#include "DD4hep/Objects.h"
+
+#include "DDSegmentation/Segmentation.h"
+
+#include <stdexcept>
+#include <string>
+#include <strstream>
+
+namespace DD4hep {
+namespace DDRec {
+
+class invalid_cell_id: public std::invalid_argument {
+public:
+	invalid_cell_id(const std::string& msg, const DDSegmentation::CellID& cellID = 0) :
+			std::invalid_argument(createMsg(msg, cellID)) {
+	}
+private:
+	static std::string createMsg(const std::string& msg, const DDSegmentation::CellID& cellID) {
+		std::stringstream s;
+		s << msg;
+		if (cellID)
+			s << " (" << cellID << ")";
+		return s.str();
+	}
+};
+
+class invalid_position: public std::invalid_argument {
+public:
+	invalid_position(const std::string& msg, const Geometry::Position& position) :
+			std::invalid_argument(createMsg(msg, position)) {
+	}
+private:
+	static std::string createMsg(const std::string& msg, const Geometry::Position& position) {
+		std::stringstream s;
+		s << msg << " " << position;
+		return s.str();
+	}
+};
+
+class invalid_detector_element: public std::invalid_argument {
+public:
+	invalid_detector_element(const std::string& msg, const Geometry::DetElement& det) :
+			std::invalid_argument(createMsg(msg, det)) {
+	}
+private:
+	static std::string createMsg(const std::string& msg, const Geometry::DetElement& det) {
+		std::stringstream s;
+		s << msg;
+		if (det.isValid())
+			s << " (" <<det.name() << ")";
+		return s.str();
+	}
+};
+
+} /* namespace DD4Rec */
+} /* namespace DD4hep */
+#endif /* DDRec_EXCEPTIONS_H_ */
diff --git a/DDRec/include/DDRec/API/IDDecoder.h b/DDRec/include/DDRec/API/IDDecoder.h
new file mode 100644
index 000000000..e41fb126c
--- /dev/null
+++ b/DDRec/include/DDRec/API/IDDecoder.h
@@ -0,0 +1,125 @@
+/*
+ * IDDecoder.h
+ *
+ *  Created on: Dec 12, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#ifndef IDDECODER_H_
+#define IDDECODER_H_
+
+#include "DD4hep/Readout.h"
+#include "DD4hep/VolumeManager.h"
+
+#include "DDSegmentation/Segmentation.h"
+
+#include <set>
+#include <string>
+
+class TGeoManager;
+
+namespace DD4hep {
+namespace DDRec {
+
+typedef DDSegmentation::CellID CellID;
+typedef DDSegmentation::VolumeID VolumeID;
+
+class IDDecoder {
+public:
+	/**
+	 * Default constructor using the name of the corresponding readout collection
+	 */
+	IDDecoder(const std::string& collectionName);
+
+	/**
+	 * Default constructor using a readout object
+	 */
+	IDDecoder(const Geometry::Readout& readout);
+
+	/**
+	 * Destructor
+	 */
+	virtual ~IDDecoder();
+
+	/**
+	 * Returns the cell ID from the local position in the given volume ID.
+	 */
+	CellID cellIDFromLocal(const Geometry::Position& local, const VolumeID volumeID) const;
+
+	/**
+	 * Returns the global cell ID from a given global position
+	 */
+	CellID cellID(const Geometry::Position& global) const;
+
+	/**
+	 * Returns the global position from a given cell ID
+	 */
+	Geometry::Position position(const CellID& cellID) const;
+
+	/*
+	 * Returns the local position from a given cell ID
+	 */
+	Geometry::Position localPosition(const CellID& cellID) const;
+
+	/*
+	 * Returns the volume ID of a given cell ID
+	 */
+	VolumeID volumeID(const CellID& cellID) const;
+
+	/*
+	 * Returns the volume ID of a given global position
+	 */
+	VolumeID volumeID(const Geometry::Position& global) const;
+
+	/*
+	 * Returns the placement for a given cell ID
+	 */
+	Geometry::PlacedVolume placement(const CellID& cellID) const;
+
+	/*
+	 * Returns the placement for a given global position
+	 */
+	Geometry::PlacedVolume placement(const Geometry::Position& global) const;
+
+	/*
+	 * Returns the subdetector for a given cell ID
+	 */
+	Geometry::DetElement subDetector(const CellID& cellID) const;
+
+	/*
+	 * Returns the subdetector for a given global position
+	 */
+	Geometry::DetElement subDetector(const Geometry::Position& global) const;
+
+	/*
+	 * Returns the closest detector element in the hierarchy for a given cell ID
+	 */
+	Geometry::DetElement detectorElement(const CellID& cellID) const;
+
+	/*
+	 * Returns the closest detector element in the hierarchy for a given global position
+	 */
+	Geometry::DetElement detectorElement(const Geometry::Position& global) const;
+
+	/*
+	 * Calculates the neighbours of the given cell ID and adds them to the list of neighbours
+	 */
+	void neighbours(const CellID& cellID, std::set<CellID>& neighbours) const;
+
+	/*
+	 * Checks if the given cell IDs are neighbours
+	 */
+	bool areNeighbours(const CellID& cellID, const CellID& otherCellID) const;
+
+protected:
+	Geometry::Readout _readout;
+	Geometry::VolumeManager _volumeManager;
+	TGeoManager* _tgeoMgr;
+
+	// helper method to get the closest daughter DetElement to the position starting from the given DetElement
+	static Geometry::DetElement getClosestDaughter(const Geometry::DetElement& det, const Geometry::Position& position);
+};
+
+} /* namespace DDRec */
+} /* namespace DD4hep */
+#endif /* IDDECODER_H_ */
diff --git a/DDRec/include/DDRec/API/LayeredSubdetector.h b/DDRec/include/DDRec/API/LayeredSubdetector.h
new file mode 100644
index 000000000..2bbf83aee
--- /dev/null
+++ b/DDRec/include/DDRec/API/LayeredSubdetector.h
@@ -0,0 +1,121 @@
+/*
+ * LayeredSubdetector.h
+ *
+ * Basic reconstruction interface for layered subdetectors
+ *
+ *  Created on: Dec 11, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#ifndef DDRec_LAYEREDSUBDETECTOR_H_
+#define DDRec_LAYEREDSUBDETECTOR_H_
+
+#include "DDRec/API/Exceptions.h"
+#include "DDRec/Extensions/LayeringExtension.h"
+
+#include "DD4hep/Detector.h"
+
+namespace DD4hep {
+namespace DDRec {
+
+class LayeredSubdetector: public virtual Geometry::DetElement, public LayeringExtension {
+public:
+	LayeredSubdetector(const Geometry::DetElement& det) :
+			Geometry::DetElement(det) {
+		getLayeringExtension();
+	}
+
+	virtual ~LayeredSubdetector() {
+		// does not own the extension!
+	}
+
+	int numberOfLayers() const {
+		return _layering->numberOfLayers();
+	}
+
+	int numberOfSensors(int layerIndex = 0) const {
+		return _layering->numberOfSensors(layerIndex);
+	}
+
+	Geometry::DetElement layer(int layerIndex) const {
+		return _layering->layer(layerIndex);
+	}
+
+	const std::vector<Geometry::DetElement>& sensors(int layerIndex = 0) const {
+		return _layering->sensors(layerIndex);
+	}
+
+	const std::vector<Geometry::DetElement>& absorbers(int layerIndex = 0) const {
+		return _layering->absorbers(layerIndex);
+	}
+
+	double totalThickness() const {
+		return _layering->totalThickness();
+	}
+
+	double totalRadiationLength() const {
+		return _layering->totalRadiationLength();
+	}
+
+	double totalInteractionLength() const {
+		return _layering->totalInteractionLength();
+	}
+
+	double thickness(int layerIndex = 0) const {
+		return _layering->thickness(layerIndex);
+	}
+
+	double radiationLength(int layerIndex = 0) const {
+		return _layering->radiationLength(layerIndex);
+	}
+
+	double interactionLength(int layerIndex = 0) const {
+		return _layering->interactionLength(layerIndex);
+	}
+
+	/// Access the total thickness of all non-sensitive elements of the layer with the given index
+	double absorberThickness(int layerIndex) const {
+		return _layering->absorberThickness(layerIndex);
+	}
+
+	/// Access the total radiation length of all non-sensitive elements of the layer with the given index
+	double absorberRadiationLength(int layerIndex) const {
+		return _layering->absorberRadiationLength(layerIndex);
+	}
+
+	/// Access the total nuclear interaction length of all non-sensitive elements of the layer with the given index
+	double absorberInteractionLength(int layerIndex) const {
+		return _layering->absorberInteractionLength(layerIndex);
+	}
+
+	/// Access the total thickness of all sensitive elements of the layer with the given index
+	virtual double sensorThickness(int layerIndex) const {
+		return _layering->sensorThickness(layerIndex);
+	}
+
+	/// Access the total radiation length of all sensitive elements of the layer with the given index
+	double sensorRadiationLength(int layerIndex) const {
+		return _layering->sensorRadiationLength(layerIndex);
+	}
+
+	/// Access the total nuclear interaction length of all sensitive elements of the layer with the given index
+	double sensorInteractionLength(int layerIndex) const {
+		return _layering->sensorInteractionLength(layerIndex);
+	}
+
+
+protected:
+	LayeringExtension* _layering;
+
+private:
+	void getLayeringExtension() {
+		_layering = this->isValid() ? this->extension<LayeringExtension>() : 0;
+		if (not _layering) {
+			throw invalid_detector_element("Found no extension of type \"LayeringExtension\"", Geometry::DetElement(*this));
+		}
+	}
+};
+
+} /* namespace DDRec */
+} /* namespace DD4hep */
+#endif /* DDReconstruction_LAYEREDSUBDETECTOR_H_ */
diff --git a/DDRec/include/DDRec/API/Subdetector.h b/DDRec/include/DDRec/API/Subdetector.h
new file mode 100644
index 000000000..597171a6c
--- /dev/null
+++ b/DDRec/include/DDRec/API/Subdetector.h
@@ -0,0 +1,46 @@
+/*
+ * Subdetector.h
+ *
+ * Basic reconstruction interface for generic subdetectors
+ *
+ *  Created on: Apr 3, 2014
+ *      Author: Christian Grefe, CERN
+ */
+
+#ifndef SUBDETECTOR_H_
+#define SUBDETECTOR_H_
+
+#include "DD4hep/Detector.h"
+
+namespace DD4hep {
+namespace DDRec {
+
+class Subdetector: public virtual Geometry::DetElement {
+public:
+	Subdetector(const Geometry::DetElement& det) :
+		Geometry::DetElement(det) {
+
+	}
+	virtual ~Subdetector() {
+		// nothing to do
+	}
+
+	bool isBarrel() const;
+
+	bool isEndcap() const;
+
+	double getRMin() const;
+
+	double getRMax() const;
+
+	double getZMin() const;
+
+	double getZMax() const;
+
+	int getNSides() const;
+};
+
+} /* namespace DDRec */
+} /* namespace DD4hep */
+
+#endif /* SUBDETECTOR_H_ */
diff --git a/DDRec/include/DDRec/API/Tracker.h b/DDRec/include/DDRec/API/Tracker.h
new file mode 100644
index 000000000..3d54af66a
--- /dev/null
+++ b/DDRec/include/DDRec/API/Tracker.h
@@ -0,0 +1,42 @@
+/*
+ * Tracker.h
+ *
+ * Basic reconstruction interface for tracking detectors
+ *
+ *  Created on: Dec 11, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#ifndef DDReconstruction_TRACKER_H_
+#define DDReconstruction_TRACKER_H_
+
+#include "DDRec/API/LayeredSubdetector.h"
+#include "DDRec/Extensions/TrackerExtension.h"
+#include "DD4hep/Detector.h"
+
+namespace DD4hep {
+namespace DDRec {
+
+class Tracker: public LayeredSubdetector {
+public:
+	Tracker(const Geometry::DetElement& det) :
+	Geometry::DetElement(det) {
+		getTrackerExtension();
+	}
+
+	virtual ~Tracker() {
+		// does not own the extension!
+	}
+
+protected:
+	TrackerExtension* _tracker;
+
+private:
+	void getTrackerExtension() {
+		_tracker = this->isValid() ? this->extension<TrackerExtension>() : 0;
+	}
+};
+
+} /* namespace DDRec */
+} /* namespace DD4hep */
+#endif /* DDReconstruction_TRACKER_H_ */
diff --git a/DDRec/include/DDRec/BarrelDetector.h b/DDRec/include/DDRec/BarrelDetector.h
deleted file mode 100644
index 3ef9b1695..000000000
--- a/DDRec/include/DDRec/BarrelDetector.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * BarrelDetector.h
- *
- *  Created on: Apr 3, 2013
- *      Author: Christian Grefe, CERN
- */
-
-#ifndef BARRELDETECTOR_H_
-#define BARRELDETECTOR_H_
-
-#include "DD4hep/Detector.h"
-
-namespace DD4hep {
-
-  namespace DDRec {
-    class BarrelDetector: virtual public Geometry::DetElement {
-
-    public:
-      typedef Geometry::DetElement DetElement;
-      BarrelDetector(const DetElement& e) : DetElement(e) {};
-      virtual ~BarrelDetector() {}
-
-      bool isBarrel() const {
-	return true;
-      }
-    };
-
-  } /* namespace DDRec */
-} /* namespace DD4hep */
-#endif /* BARRELDETECTOR_H_ */
diff --git a/DDRec/include/DDRec/Calorimeter.h b/DDRec/include/DDRec/Calorimeter.h
deleted file mode 100644
index 22a349993..000000000
--- a/DDRec/include/DDRec/Calorimeter.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Calorimeter.h
- *
- *  Created on: Mar 27, 2013
- *      Author: Christian Grefe, CERN
- */
-
-#ifndef CALORIMETER_H_
-#define CALORIMETER_H_
-
-#include "DDRec/LayeredSubdetector.h"
-
-namespace DD4hep {
-
-namespace DDRec {
-
-class Calorimeter: public LayeredSubdetector {
-
-public:
-	Calorimeter(const DetElement& e) : DetElement(e), LayeredSubdetector(e) {}
-	virtual ~Calorimeter() {}
-
-	virtual bool isCalorimeter() const {
-		return true;
-	}
-};
-}
-} /* namespace DD4hep */
-#endif /* CALORIMETER_H_ */
diff --git a/DDRec/include/DDRec/CylindricalBarrelCalorimeter.h b/DDRec/include/DDRec/CylindricalBarrelCalorimeter.h
deleted file mode 100644
index 11de520ba..000000000
--- a/DDRec/include/DDRec/CylindricalBarrelCalorimeter.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * CylindricalBarrelCalorimeter.h
- *
- *  Created on: Apr 17, 2013
- *      Author: Christian Grefe, CERN
- */
-
-#ifndef CYLINDRICALBARRELCALORIMETER_H_
-#define CYLINDRICALBARRELCALORIMETER_H_
-
-#include "DDRec/CylindricalCalorimeter.h"
-#include "DDRec/BarrelDetector.h"
-
-namespace DD4hep {
-namespace DDRec {
-
-class CylindricalBarrelCalorimeter: public CylindricalCalorimeter, public BarrelDetector {
-public:
-	CylindricalBarrelCalorimeter(const DetElement& e) : DetElement(e), CylindricalCalorimeter(e), BarrelDetector(e) {}
-	virtual ~CylindricalBarrelCalorimeter() {}
-};
-
-} /* namespace DDRec */
-} /* namespace DD4hep */
-#endif /* CYLINDRICALBARRELCALORIMETER_H_ */
diff --git a/DDRec/include/DDRec/CylindricalCalorimeter.h b/DDRec/include/DDRec/CylindricalCalorimeter.h
deleted file mode 100644
index 718fa834c..000000000
--- a/DDRec/include/DDRec/CylindricalCalorimeter.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * CylindricalCalorimeter.h
- *
- *  Created on: Apr 17, 2013
- *      Author: Christian Grefe, CERN
- */
-
-#ifndef CYLINDRICALCALORIMETER_H_
-#define CYLINDRICALCALORIMETER_H_
-
-#include "DDRec/CylindricalDetector.h"
-#include "DDRec/Calorimeter.h"
-
-namespace DD4hep {
-namespace DDRec {
-
-class CylindricalCalorimeter: public Calorimeter, public CylindricalDetector {
-public:
-	CylindricalCalorimeter(const DetElement& e) : DetElement(e), Calorimeter(e), CylindricalDetector(e) {}
-	virtual ~CylindricalCalorimeter() {}
-};
-
-} /* namespace DDRec */
-} /* namespace DD4hep */
-#endif /* CYLINDRICALCALORIMETER_H_ */
diff --git a/DDRec/include/DDRec/CylindricalDetector.h b/DDRec/include/DDRec/CylindricalDetector.h
deleted file mode 100644
index 53a3a81f5..000000000
--- a/DDRec/include/DDRec/CylindricalDetector.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * CylindricalDetector.h
- *
- *  Created on: Apr 16, 2013
- *      Author: Christian Grefe, CERN
- */
-
-#ifndef CYLINDRICALDETECTOR_H_
-#define CYLINDRICALDETECTOR_H_
-
-#include "DD4hep/Detector.h"
-#include "DD4hep/Shapes.h"
-
-namespace DD4hep {
-namespace DDRec {
-
-class CylindricalDetector: virtual public DetElement {
-public:
-	CylindricalDetector(const DetElement& e) : DetElement(e) {}
-	virtual ~CylindricalDetector() {}
-
-	double getRMin() const {
-		return getCylinder()->GetRmin();
-	}
-	double getRMax() const {
-		return getCylinder()->GetRmax();
-	}
-	double getZMin() const {
-		return -getCylinder()->GetDZ() / 2.;
-	}
-	double getZMax() const {
-		return getCylinder()->GetDZ() / 2.;
-	}
-
-protected:
-	 Tube getCylinder() const {
-		return Tube(volume().solid());
-	}
-};
-
-} /* namespace DDRec */
-} /* namespace DD4hep */
-#endif /* CYLINDRICALDETECTOR_H_ */
diff --git a/DDRec/include/DDRec/CylindricalEndcapCalorimeter.h b/DDRec/include/DDRec/CylindricalEndcapCalorimeter.h
deleted file mode 100644
index 7d86c3199..000000000
--- a/DDRec/include/DDRec/CylindricalEndcapCalorimeter.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * CylindricalEndcapCalorimeter.h
- *
- *  Created on: Apr 17, 2013
- *      Author: Christian Grefe, CERN
- */
-
-#ifndef CYLINDRICALENDCAPCALORIMETER_H_
-#define CYLINDRICALENDCAPCALORIMETER_H_
-
-#include "DDRec/CylindricalCalorimeter.h"
-#include "DDRec/EndcapDetector.h"
-
-namespace DD4hep {
-namespace DDRec {
-
-class CylindricalEndcapCalorimeter: public CylindricalCalorimeter, public EndcapDetector {
-public:
-	CylindricalEndcapCalorimeter(const DetElement& e) : DetElement(e), CylindricalCalorimeter(e), EndcapDetector(e) {}
-	virtual ~CylindricalEndcapCalorimeter() {}
-};
-
-} /* namespace DDRec */
-} /* namespace DD4hep */
-#endif /* CYLINDRICALENDCAPCALORIMETER_H_ */
diff --git a/DDRec/include/DDRec/EndcapDetector.h b/DDRec/include/DDRec/EndcapDetector.h
deleted file mode 100644
index 1a27b9209..000000000
--- a/DDRec/include/DDRec/EndcapDetector.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * EndcapDetector.h
- *
- *  Created on: Apr 16, 2013
- *      Author: Christian Grefe, CERN
- */
-
-#ifndef ENDCAPDETECTOR_H_
-#define ENDCAPDETECTOR_H_
-
-#include "DD4hep/Detector.h"
-
-namespace DD4hep {
-  namespace DDRec {
-
-    class EndcapDetector: virtual public Geometry::DetElement {
-    public:
-      typedef Geometry::DetElement DetElement;
-    EndcapDetector(const DetElement& e) : DetElement(e) {}
-      virtual ~EndcapDetector() {}
-
-      bool isEndcap() const {
-	return true;
-      }
-    };
-
-  } /* namespace DDRec */
-} /* namespace DD4hep */
-#endif /* ENDCAPDETECTOR_H_ */
diff --git a/DDRec/include/DDRec/Extensions/CalorimeterExtension.h b/DDRec/include/DDRec/Extensions/CalorimeterExtension.h
new file mode 100644
index 000000000..249c68c67
--- /dev/null
+++ b/DDRec/include/DDRec/Extensions/CalorimeterExtension.h
@@ -0,0 +1,24 @@
+/*
+ * CalorimeterExtension.h
+ *
+ * Abstract extension used by the Calorimeter class.
+ *
+ *  Created on: Dec 11, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#ifndef DDRec_CALORIMETEREXTENSION_H_
+#define DDRec_CALORIMETEREXTENSION_H_
+
+namespace DD4hep {
+namespace DDRec {
+
+class CalorimeterExtension {
+public:
+	CalorimeterExtension();
+	virtual ~CalorimeterExtension();
+};
+
+} /* namespace DDRec */
+} /* namespace DD4hep */
+#endif /* DDRec_CALORIMETEREXTENSION_H_ */
diff --git a/DDRec/include/DDRec/Extensions/LayeringExtension.h b/DDRec/include/DDRec/Extensions/LayeringExtension.h
new file mode 100644
index 000000000..65e8e3505
--- /dev/null
+++ b/DDRec/include/DDRec/Extensions/LayeringExtension.h
@@ -0,0 +1,87 @@
+/*
+ * LayeringExtension.h
+ *
+ * Abstract extension used by the LayeredSubdetector class.
+ *
+ *  Created on: Dec 11, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#ifndef DDRec_LAYERINGEXTENSION_H_
+#define DDRec_LAYERINGEXTENSION_H_
+
+#include "DD4hep/Detector.h"
+
+namespace DD4hep {
+namespace DDRec {
+
+/**
+ * Class describing the layer structure of a sub detector.
+ * The information for one layer corresponds to a typical module
+ * if, for example, a layer consists of multiple modules.
+ */
+class LayeringExtension {
+public:
+	/// Destructor
+	virtual ~LayeringExtension() {
+	}
+
+	/// Access to the total number of layers
+	virtual int numberOfLayers() const = 0;
+
+	/// Access to the total number of sensors in a given layer index
+	virtual int numberOfSensors(int layerIndex) const = 0;
+
+	/// Access to the layer DetElement for the given index
+	virtual Geometry::DetElement layer(int layerIndex) const = 0;
+
+	/// Access to the sensitive DetElements of a given layer index
+	virtual const std::vector<Geometry::DetElement>& sensors(int layerIndex) const = 0;
+
+	/// Access to the non-sensitive DetElements of a given layer index
+	virtual const std::vector<Geometry::DetElement>& absorbers(int layerIndex) const = 0;
+
+	/// Access the total thickness of the sub detector
+	virtual double totalThickness() const = 0;
+
+	/// Access the total radiation length of the sub detector
+	virtual double totalRadiationLength() const = 0;
+
+	/// Access the total nuclear interaction length of the sub detector
+	virtual double totalInteractionLength() const = 0;
+
+	/// Access the total thickness of the layer with the given index
+	virtual double thickness(int layerIndex) const = 0;
+
+	/// Access the total radiation length of the layer with the given index
+	virtual double radiationLength(int layerIndex) const = 0;
+
+	/// Access the total nuclear interaction length of the layer with the given index
+	virtual double interactionLength(int layerIndex) const = 0;
+
+	/// Access the total thickness of all non-sensitive elements of the layer with the given index
+	virtual double absorberThickness(int layerIndex) const = 0;
+
+	/// Access the total radiation length of all non-sensitive elements of the layer with the given index
+	virtual double absorberRadiationLength(int layerIndex) const = 0;
+
+	/// Access the total nuclear interaction length of all non-sensitive elements of the layer with the given index
+	virtual double absorberInteractionLength(int layerIndex) const = 0;
+
+	/// Access the total thickness of all sensitive elements of the layer with the given index
+	virtual double sensorThickness(int layerIndex) const = 0;
+
+	/// Access the total radiation length of all sensitive elements of the layer with the given index
+	virtual double sensorRadiationLength(int layerIndex) const = 0;
+
+	/// Access the total nuclear interaction length of all sensitive elements of the layer with the given index
+	virtual double sensorInteractionLength(int layerIndex) const = 0;
+
+protected:
+	LayeringExtension() {
+	}
+};
+
+} /* namespace DDRec */
+} /* namespace DD4hep */
+#endif /* DDRec_LAYERINGEXTENSION_H_ */
diff --git a/DDRec/include/DDRec/Extensions/LayeringExtensionImpl.h b/DDRec/include/DDRec/Extensions/LayeringExtensionImpl.h
new file mode 100644
index 000000000..e3bbd0805
--- /dev/null
+++ b/DDRec/include/DDRec/Extensions/LayeringExtensionImpl.h
@@ -0,0 +1,127 @@
+/*
+ * LayeringExtensionImpl.h
+ *
+ * Simple implementation of the LayeringExtension interface.
+ *
+ *  Created on: Mar 6, 2014
+ *      Author: Christian Grefe, CERN
+ */
+
+#ifndef DDRec_LAYERINGEXTENSIONIMPL_H_
+#define DDRec_LAYERINGEXTENSIONIMPL_H_
+
+// DDRec
+#include "DDRec/Extensions/LayeringExtension.h"
+
+// DD4hep
+#include "DD4hep/Detector.h"
+
+// C++
+#include <map>
+#include <vector>
+
+class TGeoManager;
+
+namespace DD4hep {
+namespace DDRec {
+
+class LayeringExtensionImpl: public LayeringExtension {
+public:
+	/// Default constructor
+	LayeringExtensionImpl();
+
+	/// Copy constructor
+	LayeringExtensionImpl(const LayeringExtensionImpl& e, const Geometry::DetElement& d) {};
+
+	/// Destructor
+	virtual ~LayeringExtensionImpl();
+
+	/// Access to the total number of layers
+	virtual int numberOfLayers() const;
+
+	/// Access to the total number of sensors in a given layer index
+	virtual int numberOfSensors(int layerIndex) const;
+
+	/// Access to the layer DetElement for the given index
+	virtual Geometry::DetElement layer(int layerIndex) const;
+
+	/// Access to the sensitive DetElements of a given layer index
+	virtual const std::vector<Geometry::DetElement>& sensors(int layerIndex) const;
+
+	/// Access to the non-sensitive DetElements of a given layer index
+	virtual const std::vector<Geometry::DetElement>& absorbers(int layerIndex) const;
+
+	/// Access the total thickness of the sub detector
+	virtual double totalThickness() const;
+
+	/// Access the total radiation length of the sub detector
+	virtual double totalRadiationLength() const;
+
+	/// Access the total nuclear interaction length of the sub detector
+	virtual double totalInteractionLength() const;
+
+	/// Access the total thickness of the layer with the given index
+	virtual double thickness(int layerIndex) const;
+
+	/// Access the total radiation length of the layer with the given index
+	virtual double radiationLength(int layerIndex) const;
+
+	/// Access the total nuclear interaction length of the layer with the given index
+	virtual double interactionLength(int layerIndex) const;
+
+	/// Access the total thickness of all non-sensitive elements of the layer with the given index
+	virtual double absorberThickness(int layerIndex) const;
+
+	/// Access the total radiation length of all non-sensitive elements of the layer with the given index
+	virtual double absorberRadiationLength(int layerIndex) const;
+
+	/// Access the total nuclear interaction length of all non-sensitive elements of the layer with the given index
+	virtual double absorberInteractionLength(int layerIndex) const;
+
+	/// Access the total thickness of all sensitive elements of the layer with the given index
+	virtual double sensorThickness(int layerIndex) const;
+
+	/// Access the total radiation length of all sensitive elements of the layer with the given index
+	virtual double sensorRadiationLength(int layerIndex) const;
+
+	/// Access the total nuclear interaction length of all sensitive elements of the layer with the given index
+	virtual double sensorInteractionLength(int layerIndex) const;
+
+	/// Stores the layer information for the given layer index
+	void setLayer(int layerIndex, Geometry::DetElement layer, const Geometry::Position& normal);
+
+protected:
+	/// Helper class to store layer attributes
+	struct LayerAttributes {
+		LayerAttributes();
+		Geometry::DetElement layer;
+		Geometry::Position normal;
+		std::vector<Geometry::DetElement> sensors;
+		std::vector<Geometry::DetElement> absorbers;
+		double thickness;
+		double radiationLength;
+		double interactionLength;
+		double absorberThickness;
+		double absorberRadiationLength;
+		double absorberInteractionLength;
+		double sensorThickness;
+		double sensorRadiationLength;
+		double sensorInteractionLength;
+		bool isCalculated;
+		/// Helper method to calculate attributes from layer
+		void calculate();
+	private:
+		double addElement(const Geometry::DetElement& det);
+		TGeoManager* _tgeoManager;
+	};
+
+	mutable std::map<int, LayerAttributes> _layerMap; /// Map to store layer attributes
+
+	/// Helper method to check validity of layer entry
+	void checkMap(int layerIndex) const;
+};
+
+} /* namespace DDRec */
+} /* namespace DD4hep */
+
+#endif /* DDReconstruction_LAYERINGEXTENSIONIMPL_H_ */
diff --git a/DDRec/include/DDRec/Extensions/TrackerExtension.h b/DDRec/include/DDRec/Extensions/TrackerExtension.h
new file mode 100644
index 000000000..d97a520b0
--- /dev/null
+++ b/DDRec/include/DDRec/Extensions/TrackerExtension.h
@@ -0,0 +1,24 @@
+/*
+ * TrackerExtension.h
+ *
+ * Abstract extension used by the Tracker class.
+ *
+ *  Created on: Dec 11, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#ifndef DDRec_TRACKEREXTENSION_H_
+#define DDRec_TRACKEREXTENSION_H_
+
+namespace DD4hep {
+namespace DDRec {
+
+class TrackerExtension {
+public:
+	TrackerExtension();
+	virtual ~TrackerExtension();
+};
+
+} /* namespace DDRec */
+} /* namespace DD4hep */
+#endif /* DDRec_TRACKEREXTENSION_H_ */
diff --git a/DDRec/include/DDRec/LayerStack.h b/DDRec/include/DDRec/LayerStack.h
deleted file mode 100644
index 49f4c376e..000000000
--- a/DDRec/include/DDRec/LayerStack.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * LayerStack.h
- *
- *  Created on: Apr 18, 2013
- *      Author: Christian Grefe, CERN
- */
-
-#ifndef LAYERSTACK_H_
-#define LAYERSTACK_H_
-
-#include "DD4hep/Detector.h"
-
-#include <vector>
-
-namespace DD4hep {
-  namespace DDRec {
-
-    class LayerStack {
-    public:
-      typedef Geometry::DetElement DetElement;
-      LayerStack(const DetElement& det);
-      LayerStack(const LayerStack& layerStack, const DetElement& det);
-      virtual ~LayerStack();
-      virtual int getNumberOfLayers() const = 0;
-      virtual int getNumberOfModules(int layerIndex = 1) const = 0;
-      virtual DetElement getModule(int layerIndex = 1, int moduleIndex = 1) const = 0;
-      double getThickness(int layerIndex = 1, int moduleIndex = 1) const;
-      double getRadiationLengths(int layerIndex = 1, int moduleIndex = 1) const;
-      double getInteractionLengths(int layerIndex = 1, int moduleIndex = 1) const;
-      double getTotalThickness(int moduleIndex = 1) const;
-      double getTotalInteractionLengths(int moduleIndex = 1) const;
-      double getTotalRadiationLengths(int moduleIndex = 1) const;
-      virtual int getNumberOfSlices(int layerIndex = 1, int moduleIndex = 1) const = 0;
-      virtual DetElement getSlice(int layerIndex = 1, int moduleIndex = 1, int sliceIndex = 1) const = 0;
-      virtual int getNumberOfSensors(int layerIndex = 1, int moduleIndex = 1) const = 0;
-      virtual DetElement getSensor(int layerIndex = 1, int moduleIndex = 1, int sensorIndex = 1) const = 0;
-
-    protected:
-      DetElement det;
-    };
-
-    class PolyhedralCalorimeterLayerStack: public LayerStack {
-    public:
-      PolyhedralCalorimeterLayerStack(const DetElement& det);
-      PolyhedralCalorimeterLayerStack(const PolyhedralCalorimeterLayerStack& layerStack, const DetElement& det);
-      virtual ~PolyhedralCalorimeterLayerStack();
-      int getNumberOfLayers() const;
-      int getNumberOfModules(int layerIndex = 1) const;
-      DetElement getModule(int layerIndex = 1, int moduleIndex = 1) const;
-      int getNumberOfSlices(int layerIndex = 1, int moduleIndex = 1) const;
-      DetElement getSlice(int layerIndex = 1, int moduleIndex = 1, int sliceIndex = 1) const;
-      int getNumberOfSensors(int layerIndex = 1, int moduleIndex = 1) const;
-      DetElement getSensor(int layerIndex = 1, int moduleIndex = 1, int sensorIndex = 1) const;
-    };
-
-  } /* namespace DDRec */
-} /* namespace DD4hep */
-#endif /* LAYERSTACK_H_ */
diff --git a/DDRec/include/DDRec/LayeredSubdetector.h b/DDRec/include/DDRec/LayeredSubdetector.h
deleted file mode 100644
index 7882d2594..000000000
--- a/DDRec/include/DDRec/LayeredSubdetector.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * LayeredSubdetector.h
- *
- *  Created on: Mar 27, 2013
- *      Author: Christian Grefe, CERN
- */
-
-#ifndef LAYEREDSUBDETECTOR_H_
-#define LAYEREDSUBDETECTOR_H_
-
-#include "DDRec/LayerStack.h"
-
-namespace DD4hep {
-  namespace DDRec {
-
-    class LayeredSubdetector: virtual public Geometry::DetElement {
-    public:
-      typedef Geometry::DetElement DetElement;
-      LayeredSubdetector(const DetElement& e);
-      virtual ~LayeredSubdetector();
-
-      inline bool isLayered() const {
-	return true;
-      }
-
-      inline int getNumberOfLayers() const {
-	return layerStack->getNumberOfLayers();
-      }
-
-      inline int getNumberOfSensors(int layerIndex, int moduleIndex = 1) const {
-	return layerStack->getNumberOfSensors(layerIndex, moduleIndex);
-      }
-
-      inline DetElement getSensor(int layerIndex, int moduleIndex = 1, int sensorIndex = 1) const {
-	return layerStack->getSensor(layerIndex, moduleIndex, sensorIndex);
-      }
-
-      inline double getLayerThickness(int layerIndex, int moduleIndex = 1) const {
-	return layerStack->getThickness(layerIndex, moduleIndex);
-      }
-
-      inline double getInteractionLengths(int layerIndex, int moduleIndex = 1) const {
-	return layerStack->getInteractionLengths(layerIndex, moduleIndex);
-      }
-
-      inline double getRadiationLengths(int layerIndex, int moduleIndex = 1) const {
-	return layerStack->getRadiationLengths(layerIndex, moduleIndex);
-      }
-
-      inline double getMipEnergyLoss(int /* layerIndex */, int /* moduleIndex */ = 1) const {
-	return 0.;
-      }
-
-      inline double getTotalThickness(int moduleIndex = 1) const {
-	return layerStack->getTotalThickness(moduleIndex);
-      }
-
-      inline double getTotalInteractionLengths(int moduleIndex = 1) const {
-	return layerStack->getTotalInteractionLengths(moduleIndex);
-      }
-
-      inline double getTotalRadiationLengths(int moduleIndex = 1) const {
-	return layerStack->getTotalRadiationLengths(moduleIndex);
-      }
-
-    protected:
-      LayerStack* layerStack;
-
-    private:
-      void getExtension();
-
-    };
-
-  } /* namespace DDRec */
-} /* namespace DD4hep */
-
-#endif /* LAYEREDSUBDETECTOR_H_ */
diff --git a/DDRec/include/DDRec/PolyhedralBarrelCalorimeter.h b/DDRec/include/DDRec/PolyhedralBarrelCalorimeter.h
deleted file mode 100644
index bcdef3a44..000000000
--- a/DDRec/include/DDRec/PolyhedralBarrelCalorimeter.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * PolyhedralBarrelCalorimeter.h
- *
- *  Created on: Apr 3, 2013
- *      Author: Christian Grefe, CERN
- */
-
-#ifndef POLYHEDRALBARRELCALORIMETER_H_
-#define POLYHEDRALBARRELCALORIMETER_H_
-
-#include "DDRec/BarrelDetector.h"
-#include "DDRec/PolyhedralCalorimeter.h"
-
-namespace DD4hep {
-namespace DDRec {
-
-class PolyhedralBarrelCalorimeter: public BarrelDetector, public PolyhedralCalorimeter {
-public:
-	PolyhedralBarrelCalorimeter(const DetElement& e) : DetElement(e), BarrelDetector(e), PolyhedralCalorimeter(e) {}
-	virtual ~PolyhedralBarrelCalorimeter() {}
-};
-
-} /* namespace DDRec */
-} /* namespace DD4hep */
-#endif /* POLYHEDRALBARRELCALORIMETER_H_ */
diff --git a/DDRec/include/DDRec/PolyhedralCalorimeter.h b/DDRec/include/DDRec/PolyhedralCalorimeter.h
deleted file mode 100644
index e3ca95bab..000000000
--- a/DDRec/include/DDRec/PolyhedralCalorimeter.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * PolyhedralCalorimeter.h
- *
- *  Created on: Apr 17, 2013
- *      Author: Christian Grefe, CERN
- */
-
-#ifndef POLYHEDRALCALORIMETER_H_
-#define POLYHEDRALCALORIMETER_H_
-
-#include "DDRec/PolyhedralDetector.h"
-#include "DDRec/Calorimeter.h"
-
-namespace DD4hep {
-namespace DDRec {
-
-class PolyhedralCalorimeter: public PolyhedralDetector, public Calorimeter {
-public:
-	PolyhedralCalorimeter(const DetElement& e) : DetElement(e), Calorimeter(e), PolyhedralDetector(e) {}
-	virtual ~PolyhedralCalorimeter() {}
-};
-
-} /* namespace DDRec */
-} /* namespace DD4hep */
-#endif /* POLYHEDRALCALORIMETER_H_ */
diff --git a/DDRec/include/DDRec/PolyhedralDetector.h b/DDRec/include/DDRec/PolyhedralDetector.h
deleted file mode 100644
index 95f827e41..000000000
--- a/DDRec/include/DDRec/PolyhedralDetector.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * PolyhedralDetector.h
- *
- *  Created on: Apr 3, 2013
- *      Author: Christian Grefe, CERN
- */
-
-#ifndef POLYHEDRALDETECTOR_H_
-#define POLYHEDRALDETECTOR_H_
-
-#include "DD4hep/Detector.h"
-
-namespace DD4hep {
-  namespace DDRec {
-    class PolyhedralDetector : virtual public Geometry::DetElement {
-    public:
-      typedef Geometry::DetElement DetElement;
-      PolyhedralDetector(const DetElement& e) : DetElement(e) {}
-      virtual ~PolyhedralDetector() {}
-
-      int getNSides() const {
-	return getPolyhedra()->GetNedges();
-      }
-      double getRMin() const {
-	return getPolyhedra()->GetRmin(0);
-      }
-      double getRMax() const {
-	return getPolyhedra()->GetRmax(0);
-      }
-      double getZMin() const {
-	return getPolyhedra()->GetZ(0);
-      }
-      double getZMax() const {
-	return getPolyhedra()->GetZ(1);
-      }
-
-    protected:
-      PolyhedraRegular getPolyhedra() const {
-	return PolyhedraRegular(volume().solid());
-      }
-    };
-  } /* namespace DDRec */
-} /* namespace DD4hep */
-#endif /* POLYHEDRALDETECTOR_H_ */
diff --git a/DDRec/include/DDRec/PolyhedralEndcapCalorimeter.h b/DDRec/include/DDRec/PolyhedralEndcapCalorimeter.h
deleted file mode 100644
index 1529a6466..000000000
--- a/DDRec/include/DDRec/PolyhedralEndcapCalorimeter.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * PolyhedralEndcapCalorimeter.h
- *
- *  Created on: Apr 16, 2013
- *      Author: Christian Grefe, CERN
- */
-
-#ifndef POLYHEDRALENDCAPCALORIMETER_H_
-#define POLYHEDRALENDCAPCALORIMETER_H_
-
-#include "DDRec/EndcapDetector.h"
-#include "DDRec/PolyhedralCalorimeter.h"
-
-namespace DD4hep {
-namespace DDRec {
-
-class PolyhedralEndcapCalorimeter: public EndcapDetector, public PolyhedralCalorimeter {
-public:
-	PolyhedralEndcapCalorimeter(const DetElement& e) : DetElement(e), EndcapDetector(e), PolyhedralCalorimeter(e) {}
-	virtual ~PolyhedralEndcapCalorimeter() {}
-};
-
-} /* namespace DDRec */
-} /* namespace DD4hep */
-#endif /* POLYHEDRALENDCAPCALORIMETER_H_ */
diff --git a/DDRec/include/DDRec/VertexBarrelDetector.h b/DDRec/include/DDRec/VertexBarrelDetector.h
deleted file mode 100644
index 53989f0fc..000000000
--- a/DDRec/include/DDRec/VertexBarrelDetector.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * VertexBarrelDetector.h
- *
- *  Created on: 17/02/2014
- *      Author: Markus Frank, CERN
- */
-#ifndef VERTEXBARRELDETECTOR_H_
-#define VERTEXBARRELDETECTOR_H_
-
-#include "DDRec/BarrelDetector.h"
-#include "DDRec/LayeredSubdetector.h"
-
-namespace DD4hep {
-  namespace DDRec {
-
-    class VertexBarrelDetector
-      : virtual public BarrelDetector, 
-      virtual public LayeredSubdetector
-      {
-    public:
-	typedef Geometry::DetElement DetElement;
-      /// Constructor from handle
-      VertexBarrelDetector(const DetElement& e);
-      /// Standard destructor
-      virtual ~VertexBarrelDetector();
-    };
-
-  } /* namespace DDRec */
-} /* namespace DD4hep */
-#endif /* VERTEXBARRELDETECTOR_H_ */
diff --git a/DDRec/src/IDDecoder.cpp b/DDRec/src/IDDecoder.cpp
new file mode 100644
index 000000000..9c8b1ce48
--- /dev/null
+++ b/DDRec/src/IDDecoder.cpp
@@ -0,0 +1,217 @@
+/*
+ * IDDecoder.cpp
+ *
+ *  Created on: Dec 12, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#include "DDRec/API/IDDecoder.h"
+#include "DD4hep/LCDD.h"
+#include "DD4hep/VolumeManager.h"
+
+namespace DD4hep {
+namespace DDRec {
+
+using Geometry::DetElement;
+using Geometry::LCDD;
+using Geometry::PlacedVolume;
+using Geometry::Position;
+using Geometry::Readout;
+using Geometry::Solid;
+using Geometry::VolumeManager;
+using Geometry::Volume;
+using std::set;
+
+/**
+ * Default constructor using the name of the corresponding readout collection
+ */
+IDDecoder::IDDecoder(const std::string& collectionName) {
+	LCDD& lcdd = LCDD::getInstance();
+	_readout = lcdd.readout(collectionName);
+	_volumeManager = lcdd.volumeManager();
+	if (not _volumeManager.isValid()) {
+		_volumeManager = VolumeManager(lcdd, "volman", lcdd.world(), Readout(), VolumeManager::TREE);
+	}
+	_tgeoMgr = Geometry::LCDD::getInstance().world().volume()->GetGeoManager();
+}
+
+/**
+ * Default constructor using a readout object
+ */
+IDDecoder::IDDecoder(const Readout& readout) {
+	LCDD& lcdd = LCDD::getInstance();
+	_readout = readout;
+	_volumeManager = lcdd.volumeManager();
+	if (not _volumeManager.isValid()) {
+		_volumeManager = VolumeManager(lcdd, "volman", lcdd.world(), Readout(), VolumeManager::TREE);
+	}
+	_tgeoMgr = Geometry::LCDD::getInstance().world().volume()->GetGeoManager();
+}
+
+/**
+ * Destructor
+ */
+IDDecoder::~IDDecoder() {
+}
+
+/**
+ * Returns the cell ID from the local position in the given volume ID.
+ */
+CellID IDDecoder::cellIDFromLocal(const Position& local, const VolumeID volumeID) const {
+	double l[3];
+	double g[3];
+	local.GetCoordinates(l);
+	// FIXME: direct lookup of transformations seems to be broken
+	//const TGeoMatrix& localToGlobal = _volumeManager.worldTransformation(volumeID);
+	const TGeoMatrix& localToGlobal = this->detectorElement(volumeID).worldTransformation();
+	localToGlobal.LocalToMaster(l, g);
+	Position global(g[0], g[1], g[2]);
+	return _readout.segmentation().cellID(local, global, volumeID);
+}
+
+/**
+ * Returns the global cell ID from a given global position
+ */
+CellID IDDecoder::cellID(const Position& global) const {
+	VolumeID volID = volumeID(global);
+	double l[3];
+	double g[3];
+	global.GetCoordinates(g);
+	// FIXME: direct lookup of transformations seems to be broken
+	//const TGeoMatrix& localToGlobal = _volumeManager.worldTransformation(volID);
+	const TGeoMatrix& localToGlobal = this->detectorElement(volID).worldTransformation();
+	localToGlobal.MasterToLocal(g, l);
+	Position local(l[0], l[1], l[2]);
+	return _readout.segmentation().cellID(local, global, volID);
+}
+
+/**
+ * Returns the global position from a given cell ID
+ */
+Position IDDecoder::position(const CellID& cellID) const {
+	double l[3];
+	double g[3];
+	Position local = _readout.segmentation().position(cellID);
+	local.GetCoordinates(l);
+	// FIXME: direct lookup of transformations seems to be broken
+	//const TGeoMatrix& localToGlobal = _volumeManager.worldTransformation(cellID);
+	const TGeoMatrix& localToGlobal = this->detectorElement(cellID).worldTransformation();
+	localToGlobal.LocalToMaster(l, g);
+	return Position(g[0], g[1], g[2]);
+}
+
+/*
+ * Returns the local position from a given cell ID
+ */
+Position IDDecoder::localPosition(const CellID& cellID) const {
+	return _readout.segmentation().position(cellID);
+}
+
+/*
+ * Returns the volume ID of a given cell ID
+ */
+VolumeID IDDecoder::volumeID(const CellID& cellID) const {
+	return _readout.segmentation()->volumeID(cellID);
+}
+
+/*
+ * Returns the volume ID of a given global position
+ */
+VolumeID IDDecoder::volumeID(const Position& position) const {
+	DetElement det = detectorElement(position);
+	return det.volumeID();
+}
+
+/*
+ * Returns the placement for a given cell ID
+ */
+PlacedVolume IDDecoder::placement(const CellID& cellID) const {
+	return _volumeManager.lookupPlacement(cellID);
+}
+
+/*
+ * Returns the placement for a given global position
+ */
+PlacedVolume IDDecoder::placement(const Position& position) const {
+	return placement(volumeID(position));
+}
+
+/*
+ * Returns the subdetector for a given cell ID
+ */
+DetElement IDDecoder::subDetector(const CellID& cellID) const {
+	return _volumeManager.lookupDetector(cellID);
+}
+
+/*
+ * Returns the subdetector for a given global position
+ */
+DetElement IDDecoder::subDetector(const Position& position) const {
+	return subDetector(volumeID(position));
+}
+
+/*
+ * Returns the closest detector element in the hierarchy for a given cell ID
+ */
+DetElement IDDecoder::detectorElement(const CellID& cellID) const {
+	return _volumeManager.lookupDetElement(cellID);
+}
+
+/*
+ * Returns the closest detector element in the hierarchy for a given global position
+ */
+DetElement IDDecoder::detectorElement(const Position& position) const {
+	Geometry::DetElement world = Geometry::LCDD::getInstance().world();
+	Geometry::DetElement det = getClosestDaughter(world, position);
+	// Fixme: check if this is valid, otherwise throw exception
+	return det;
+}
+
+/*
+ * Calculates the neighbours of the given cell ID and adds them to the list of neighbours
+ */
+void IDDecoder::neighbours(const CellID& cellID, set<CellID>& neighbours) const {
+	_readout.segmentation()->neighbours(cellID, neighbours);
+}
+
+/*
+ * Checks if the given cell IDs are neighbours
+ */
+bool IDDecoder::areNeighbours(const CellID& cellID, const CellID& otherCellID) const {
+	set<CellID> neighbours;
+	_readout.segmentation()->neighbours(cellID, neighbours);
+	return neighbours.count(otherCellID) != 0;
+}
+
+Geometry::DetElement IDDecoder::getClosestDaughter(const Geometry::DetElement& det,
+		const Geometry::Position& position) {
+	Geometry::DetElement result;
+
+	// check if we have a shape and see if we are inside
+	if (det.volume().isValid() and det.volume().solid().isValid()) {
+		double globalPosition[3] = { position.x(), position.y(), position.z() };
+		double localPosition[3] = { 0., 0., 0. };
+		det.worldTransformation().MasterToLocal(globalPosition, localPosition);
+		if (det.volume().solid()->Contains(localPosition)) {
+			result = det;
+		} else {
+			// assuming that any daughter shape would be inside this shape
+			return Geometry::DetElement();
+		}
+	}
+
+	const DetElement::Children& children = det.children();
+	DetElement::Children::const_iterator it = children.begin();
+	while (it != children.end()) {
+		Geometry::DetElement daughterDet = getClosestDaughter(it->second, position);
+		if (daughterDet.isValid()) {
+			result = daughterDet;
+			break;
+		}
+		++it;
+	}
+	return result;
+}
+
+} /* namespace DDRec */
+} /* namespace DD4hep */
diff --git a/DDRec/src/LayerStack.cpp b/DDRec/src/LayerStack.cpp
deleted file mode 100644
index e3db80084..000000000
--- a/DDRec/src/LayerStack.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Layer.cpp
- *
- *  Created on: Apr 18, 2013
- *      Author: Christian Grefe, CERN
- */
-
-#include "DDRec/LayerStack.h"
-#include "DDRec/Exceptions.h"
-#include "DD4hep/Shapes.h"
-
-#include <sstream>
-
-using namespace DD4hep::Geometry;
-using namespace DD4hep::DDRec;
-using std::stringstream;
-
-LayerStack::LayerStack(const DetElement& d) : det(d) {
-
-}
-
-LayerStack::LayerStack(const LayerStack& /* layerStack */, const DetElement& d) 
-: det(d) 
-{
-
-}
-
-LayerStack::~LayerStack() {
-
-}
-
-double LayerStack::getThickness(int layerIndex, int moduleIndex) const {
-  double thickness = 0.;
-  for (int sliceIndex = 0; sliceIndex < getNumberOfSlices(layerIndex, moduleIndex); sliceIndex++) {
-    thickness += Box(getSlice(layerIndex, moduleIndex, sliceIndex+1).volume().solid())->GetDZ();
-  }
-  return thickness;
-}
-
-double LayerStack::getRadiationLengths(int layerIndex, int moduleIndex) const {
-  double radiationLengths = 0.;
-  for (int sliceIndex = 0; sliceIndex < getNumberOfSlices(layerIndex, moduleIndex); sliceIndex++) {
-    radiationLengths += Box(getSlice(layerIndex, moduleIndex, sliceIndex+1).volume().solid())->GetDZ() / getSlice(layerIndex, moduleIndex).volume().material().radLength();
-  }
-  return radiationLengths;
-}
-
-double LayerStack::getInteractionLengths(int layerIndex, int moduleIndex) const {
-  double interactionLengths = 0.;
-  for (int sliceIndex = 0; sliceIndex < getNumberOfSlices(layerIndex, moduleIndex); sliceIndex++) {
-    interactionLengths += Box(getSlice(layerIndex, moduleIndex, sliceIndex+1).volume().solid())->GetDZ() / getSlice(layerIndex, moduleIndex).volume().material().intLength();
-  }
-  return interactionLengths;
-}
-
-double LayerStack::getTotalThickness(int moduleIndex) const {
-  double thickness = 0.;
-  for (int layerIndex = 0; layerIndex < getNumberOfLayers(); layerIndex++) {
-    thickness += getThickness(layerIndex+1, moduleIndex);
-  }
-  return thickness;
-}
-
-double LayerStack::getTotalInteractionLengths(int moduleIndex) const {
-  double interactionLengths = 0.;
-  for (int layerIndex = 0; layerIndex < getNumberOfLayers(); layerIndex++) {
-    interactionLengths += getInteractionLengths(layerIndex+1, moduleIndex);
-  }
-  return interactionLengths;
-}
-
-double LayerStack::getTotalRadiationLengths(int moduleIndex) const {
-  double radiationLengths = 0.;
-  for (int layerIndex = 0; layerIndex < getNumberOfLayers(); layerIndex++) {
-    radiationLengths += getRadiationLengths(layerIndex+1, moduleIndex);
-  }
-  return radiationLengths;
-}
-
-PolyhedralCalorimeterLayerStack::PolyhedralCalorimeterLayerStack(const DetElement& det) : LayerStack(det) {
-
-}
-
-PolyhedralCalorimeterLayerStack::PolyhedralCalorimeterLayerStack(const PolyhedralCalorimeterLayerStack& layerStack, const DetElement& det) : LayerStack(layerStack, det) {
-
-}
-
-PolyhedralCalorimeterLayerStack::~PolyhedralCalorimeterLayerStack() {
-
-}
-
-int PolyhedralCalorimeterLayerStack::getNumberOfLayers() const {
-  stringstream moduleName;
-  moduleName << "stave1";
-  DetElement module = det.child(moduleName.str());
-  if (not module.isValid()) {
-    std::cerr << "Invalid module name " << moduleName.str() << std::endl;
-    return 0;
-  }
-  return module.children().size();
-}
-
-int PolyhedralCalorimeterLayerStack::getNumberOfModules(int /* layerIndex */) const {
-  return det.children().size();
-}
-
-DetElement PolyhedralCalorimeterLayerStack::getModule(int layerIndex, int moduleIndex) const {
-  stringstream moduleName;
-  moduleName << "stave" << moduleIndex;
-  DetElement module = det.child(moduleName.str());
-  if (not module.isValid()) {
-    std::cerr << "Invalid module name " << moduleName.str() << std::endl;
-    return DetElement();
-  }
-  stringstream layerName;
-  layerName << "layer" << layerIndex;
-  DetElement layer = module.child(layerName.str());
-  if (not layer.isValid()) {
-    std::cerr << "Invalid layer name " << layerName.str() << std::endl;
-    return DetElement();
-  }
-  return layer;
-}
-
-int PolyhedralCalorimeterLayerStack::getNumberOfSlices(int layerIndex, int moduleIndex) const {
-  return getModule(layerIndex, moduleIndex).children().size();
-}
-
-DetElement PolyhedralCalorimeterLayerStack::getSlice(int layerIndex, int moduleIndex, int sliceIndex) const {
-  stringstream sliceName;
-  sliceName << "slice" << sliceIndex;
-  DetElement slice = getModule(layerIndex, moduleIndex).child(sliceName.str());
-  if (not slice.isValid()) {
-    std::cerr << "Invalid slice name " << sliceName.str() << std::endl;
-    return DetElement();
-  }
-  return getModule(layerIndex, moduleIndex).child(sliceName.str());
-}
-
-int PolyhedralCalorimeterLayerStack::getNumberOfSensors(int layerIndex, int moduleIndex) const {
-  int nSensors = 0;
-  for (int sliceIndex = 0; sliceIndex < getNumberOfSlices(layerIndex, moduleIndex); sliceIndex++) {
-    if (getSlice(layerIndex, moduleIndex, sliceIndex+1).volume().isSensitive()) {
-      nSensors++;
-    }
-  }
-  return nSensors;
-}
-
-DetElement PolyhedralCalorimeterLayerStack::getSensor(int layerIndex, int moduleIndex, int sensorIndex) const {
-  int nSensors = 0;
-  for (int sliceIndex = 0; sliceIndex < getNumberOfSlices(layerIndex, moduleIndex); sliceIndex++) {
-    DetElement slice = getSlice(layerIndex, moduleIndex, sliceIndex+1);
-    if (slice.volume().isSensitive()) {
-      nSensors++;
-    }
-    if (nSensors == sensorIndex) {
-      return slice;
-    }
-  }
-  throw OutsideGeometryException("No sensor with index " + sensorIndex);
-}
diff --git a/DDRec/src/LayeredSubdetector.cpp b/DDRec/src/LayeredSubdetector.cpp
deleted file mode 100644
index 7d1612953..000000000
--- a/DDRec/src/LayeredSubdetector.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#include "DDRec/LayeredSubdetector.h"
-
-using namespace DD4hep::Geometry;
-using namespace DD4hep::DDRec;
-
-LayeredSubdetector::LayeredSubdetector(const DetElement& e)
- : DetElement(e) 
-{
-  getExtension();
-}
-
-LayeredSubdetector::~LayeredSubdetector() {
-}
-
-void LayeredSubdetector::getExtension() {
-  layerStack = isValid() ? extension<LayerStack>() : 0;
-  if (layerStack == 0) {
-    std::cout << "Failed to get the extension" << std::endl;
-  }
-}
diff --git a/DDRec/src/LayeringExtensionImpl.cpp b/DDRec/src/LayeringExtensionImpl.cpp
new file mode 100644
index 000000000..4e7259e21
--- /dev/null
+++ b/DDRec/src/LayeringExtensionImpl.cpp
@@ -0,0 +1,247 @@
+/*
+ * LayeringExtensionImpl.cpp
+ *
+ *  Created on: Mar 6, 2014
+ *      Author: cgrefe
+ */
+
+#include "DDRec/Extensions/LayeringExtensionImpl.h"
+
+#include "DD4hep/LCDD.h"
+
+#include "TGeoManager.h"
+
+namespace DD4hep {
+namespace DDRec {
+
+using Geometry::DetElement;
+
+using std::vector;
+using std::map;
+
+/// Default constructor
+LayeringExtensionImpl::LayeringExtensionImpl() {
+}
+
+/// Copy constructor
+//LayeringExtensionImpl::LayeringExtensionImpl(const LayeringExtensionImpl& e, const DetElement& d) {}
+
+/// Destructor
+LayeringExtensionImpl::~LayeringExtensionImpl() {
+}
+
+/// Access to the total number of layers
+int LayeringExtensionImpl::numberOfLayers() const {
+	return _layerMap.size();
+}
+
+/// Access to the total number of sensors in a given layer index
+int LayeringExtensionImpl::numberOfSensors(int layerIndex) const {
+	checkMap(layerIndex);
+	return _layerMap.at(layerIndex).sensors.size();
+}
+
+/// Access to the layer DetElement for the given index
+DetElement LayeringExtensionImpl::layer(int layerIndex) const {
+	checkMap(layerIndex);
+	return _layerMap.at(layerIndex).layer;
+}
+
+/// Access to the sensitive DetElements of a given layer index
+const vector<DetElement>& LayeringExtensionImpl::sensors(int layerIndex) const {
+	checkMap(layerIndex);
+	return _layerMap.at(layerIndex).sensors;
+}
+
+/// Access to the non-sensitive DetElements of a given layer index
+const vector<DetElement>& LayeringExtensionImpl::absorbers(int layerIndex) const {
+	checkMap(layerIndex);
+	return _layerMap.at(layerIndex).absorbers;
+}
+
+/// Access the total thickness of the sub detector
+double LayeringExtensionImpl::totalThickness() const {
+	map<int, LayerAttributes>::iterator it = _layerMap.begin();
+	double thickness = 0.;
+	while (it != _layerMap.end()) {
+		LayerAttributes& attributes = it->second;
+		if (not attributes.isCalculated) {
+			attributes.calculate();
+		}
+		thickness += attributes.thickness;
+		++it;
+	}
+	return thickness;
+}
+
+/// Access the total radiation length of the sub detector
+double LayeringExtensionImpl::totalRadiationLength() const {
+	map<int, LayerAttributes>::iterator it = _layerMap.begin();
+	double radiationLength = 0.;
+	while (it != _layerMap.end()) {
+		LayerAttributes& attributes = it->second;
+		if (not attributes.isCalculated) {
+			attributes.calculate();
+		}
+		radiationLength += attributes.radiationLength;
+		++it;
+	}
+	return radiationLength;
+}
+
+/// Access the total nuclear interaction length of the sub detector
+double LayeringExtensionImpl::totalInteractionLength() const {
+	map<int, LayerAttributes>::iterator it = _layerMap.begin();
+	double interactionLength = 0.;
+	while (it != _layerMap.end()) {
+		LayerAttributes& attributes = it->second;
+		if (not attributes.isCalculated) {
+			attributes.calculate();
+		}
+		interactionLength += attributes.interactionLength;
+		++it;
+	}
+	return interactionLength;
+}
+
+/// Access the total thickness of the layer with the given index
+double LayeringExtensionImpl::thickness(int layerIndex) const {
+	checkMap(layerIndex);
+	return _layerMap.at(layerIndex).thickness;
+}
+
+/// Access the total radiation length of the layer with the given index
+double LayeringExtensionImpl::radiationLength(int layerIndex) const {
+	checkMap(layerIndex);
+	return _layerMap.at(layerIndex).radiationLength;
+}
+
+/// Access the total nuclear interaction length of the layer with the given index
+double LayeringExtensionImpl::interactionLength(int layerIndex) const {
+	checkMap(layerIndex);
+	return _layerMap.at(layerIndex).interactionLength;
+}
+
+/// Access the total thickness of all non-sensitive elements of the layer with the given index
+double LayeringExtensionImpl::absorberThickness(int layerIndex) const {
+	checkMap(layerIndex);
+	return _layerMap.at(layerIndex).absorberThickness;
+}
+
+/// Access the total radiation length of all non-sensitive elements of the layer with the given index
+double LayeringExtensionImpl::absorberRadiationLength(int layerIndex) const {
+	checkMap(layerIndex);
+	return _layerMap.at(layerIndex).absorberRadiationLength;
+}
+
+/// Access the total nuclear interaction length of all non-sensitive elements of the layer with the given index
+double LayeringExtensionImpl::absorberInteractionLength(int layerIndex) const {
+	checkMap(layerIndex);
+	return _layerMap.at(layerIndex).absorberInteractionLength;
+}
+
+/// Access the total thickness of all sensitive elements of the layer with the given index
+double LayeringExtensionImpl::sensorThickness(int layerIndex) const {
+	checkMap(layerIndex);
+	return _layerMap.at(layerIndex).sensorThickness;
+}
+
+/// Access the total radiation length of all sensitive elements of the layer with the given index
+double LayeringExtensionImpl::sensorRadiationLength(int layerIndex) const {
+	checkMap(layerIndex);
+	return _layerMap.at(layerIndex).sensorRadiationLength;
+}
+
+/// Access the total nuclear interaction length of all sensitive elements of the layer with the given index
+double LayeringExtensionImpl::sensorInteractionLength(int layerIndex) const {
+	checkMap(layerIndex);
+	return _layerMap.at(layerIndex).sensorInteractionLength;
+}
+
+/// Stores the layer information for the given layer index
+void LayeringExtensionImpl::setLayer(int layerIndex, Geometry::DetElement layer, const Geometry::Position& normal) {
+	LayerAttributes& layerAttributes = _layerMap[layerIndex];
+	layerAttributes.layer = layer;
+	layerAttributes.normal = normal.Unit();
+	layerAttributes.isCalculated = false;
+}
+
+/// Helper method to check validity of layer entry
+void LayeringExtensionImpl::checkMap(int layerIndex) const {
+	map<int, LayerAttributes>::iterator it;
+	it = _layerMap.find(layerIndex);
+	if (it == _layerMap.end()) {
+		// TODO throw exception
+	}
+	if (not it->second.isCalculated) {
+		it->second.calculate();
+	}
+}
+
+LayeringExtensionImpl::LayerAttributes::LayerAttributes() :
+		thickness(0.), radiationLength(0.), interactionLength(0.), absorberThickness(0.), absorberRadiationLength(0.), absorberInteractionLength(
+				0.), sensorThickness(0.), sensorRadiationLength(0.), sensorInteractionLength(0.), isCalculated(false) {
+	_tgeoManager = Geometry::LCDD::getInstance().world().volume()->GetGeoManager();
+}
+
+void LayeringExtensionImpl::LayerAttributes::calculate() {
+	// reset all values
+	sensors.clear();
+	absorbers.clear();
+	thickness = 0.;
+	radiationLength = 0.;
+	interactionLength = 0.;
+	absorberThickness = 0.;
+	absorberRadiationLength = 0.;
+	absorberInteractionLength = 0.;
+	sensorThickness = 0.;
+	sensorRadiationLength = 0.;
+	sensorInteractionLength = 0.;
+	// add all children recursively starting from top
+	addElement(this->layer);
+	isCalculated = true;
+}
+
+double LayeringExtensionImpl::LayerAttributes::addElement(const DetElement& det) {
+	double daughterThickness = 0.;
+	double thisThickness = 0.;
+
+	const DetElement::Children& children = det.children();
+	DetElement::Children::const_iterator it = children.begin();
+	while (it != children.end()) {
+		daughterThickness += addElement(it->second);
+		++it;
+	}
+
+	Geometry::Volume volume = det.volume();
+	if (volume.isValid() and volume.solid().isValid()) {
+		Geometry::Solid solid = volume.solid();
+		Geometry::Material material = volume.material();
+		double origin[3] = { 0., 0., 0. };
+		double direction[3] = { normal.x(), normal.y(), normal.z() };
+		double reverse_direction[3] = { -normal.x(), -normal.y(), -normal.z() };
+		thisThickness = solid->DistFromInside(origin, direction) + solid->DistFromInside(origin, reverse_direction);
+		// if daughters had volumes with thicknesses subtract those
+		double effectiveThickness = thisThickness - daughterThickness;
+		double radLength = effectiveThickness / material.radLength();
+		double intLength = effectiveThickness / material.intLength();
+		thickness += effectiveThickness;
+		interactionLength += intLength;
+		radiationLength += radLength;
+		if (volume.isSensitive()) {
+			sensorThickness += thickness;
+			sensorInteractionLength += intLength;
+			sensorRadiationLength += radLength;
+			sensors.push_back(det);
+		} else {
+			absorbers.push_back(det);
+			absorberThickness += thickness;
+			absorberInteractionLength += intLength;
+			absorberRadiationLength += radLength;
+		}
+	}
+	return thisThickness;
+}
+
+} /* namespace DDRec */
+} /* namespace DD4hep */
diff --git a/DDRec/src/Subdetector.cpp b/DDRec/src/Subdetector.cpp
new file mode 100644
index 000000000..245d99a9d
--- /dev/null
+++ b/DDRec/src/Subdetector.cpp
@@ -0,0 +1,42 @@
+/*
+ * Subdetector.cpp
+ *
+ *  Created on: Apr 3, 2014
+ *      Author: cgrefe
+ */
+
+#include "DDRec/API/Subdetector.h"
+
+namespace DD4hep {
+namespace DDRec {
+
+bool Subdetector::isBarrel() const {
+	return true;
+}
+
+bool Subdetector::isEndcap() const {
+	return false;
+}
+
+double Subdetector::getRMin() const {
+	return 100.;
+}
+
+double Subdetector::getRMax() const {
+	return 200.;
+}
+
+double Subdetector::getZMin() const {
+	return 300.;
+}
+
+double Subdetector::getZMax() const {
+	return 400.;
+}
+
+int Subdetector::getNSides() const {
+	return 8;
+}
+
+} /* namespace DDRec */
+} /* namespace DD4hep */
diff --git a/DDRec/src/VertexBarrelDetector.cpp b/DDRec/src/VertexBarrelDetector.cpp
deleted file mode 100644
index f4c939cec..000000000
--- a/DDRec/src/VertexBarrelDetector.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-#include "DDRec/VertexBarrelDetector.h"
-
-using namespace DD4hep::Geometry;
-using namespace DD4hep::DDRec;
-
-/// Constructor from handle
-VertexBarrelDetector::VertexBarrelDetector(const DetElement& e) 
-  : BarrelDetector(e), LayeredSubdetector(e) 
-{
-}
-
-/// Standard destructor
-VertexBarrelDetector::~VertexBarrelDetector() {
-}
-- 
GitLab