From 78884f3ac3b3aea26a0d9e2f1c5d54aae9e74cfc Mon Sep 17 00:00:00 2001
From: Christian Grefe <Christian.Grefe@cern.ch>
Date: Thu, 6 Nov 2014 16:13:07 +0000
Subject: [PATCH] Added the subdetector extension

---
 DDRec/include/DDRec/API/IDDecoder.h           |   5 +
 DDRec/include/DDRec/API/LayeredSubdetector.h  |   3 +
 DDRec/include/DDRec/API/Subdetector.h         |  58 ++++-
 .../DDRec/Extensions/SubdetectorExtension.h   |  58 +++++
 .../Extensions/SubdetectorExtensionImpl.h     | 104 +++++++++
 DDRec/src/Subdetector.cpp                     |  42 ----
 DDRec/src/SubdetectorExtensionImpl.cpp        | 201 ++++++++++++++++++
 7 files changed, 420 insertions(+), 51 deletions(-)
 create mode 100644 DDRec/include/DDRec/Extensions/SubdetectorExtension.h
 create mode 100644 DDRec/include/DDRec/Extensions/SubdetectorExtensionImpl.h
 delete mode 100644 DDRec/src/Subdetector.cpp
 create mode 100644 DDRec/src/SubdetectorExtensionImpl.cpp

diff --git a/DDRec/include/DDRec/API/IDDecoder.h b/DDRec/include/DDRec/API/IDDecoder.h
index e41fb126c..1d555b1d9 100644
--- a/DDRec/include/DDRec/API/IDDecoder.h
+++ b/DDRec/include/DDRec/API/IDDecoder.h
@@ -24,6 +24,11 @@ namespace DDRec {
 typedef DDSegmentation::CellID CellID;
 typedef DDSegmentation::VolumeID VolumeID;
 
+/**
+ * Combines functionality of the VolumeManager and Segmentation classes to provide a
+ * high level interface for position to cell ID and cell ID to position conversions
+ * and related information.
+ */
 class IDDecoder {
 public:
 	/**
diff --git a/DDRec/include/DDRec/API/LayeredSubdetector.h b/DDRec/include/DDRec/API/LayeredSubdetector.h
index 2bbf83aee..5faceec65 100644
--- a/DDRec/include/DDRec/API/LayeredSubdetector.h
+++ b/DDRec/include/DDRec/API/LayeredSubdetector.h
@@ -20,11 +20,13 @@ namespace DDRec {
 
 class LayeredSubdetector: public virtual Geometry::DetElement, public LayeringExtension {
 public:
+	/// Default constructor
 	LayeredSubdetector(const Geometry::DetElement& det) :
 			Geometry::DetElement(det) {
 		getLayeringExtension();
 	}
 
+	/// Destructor
 	virtual ~LayeredSubdetector() {
 		// does not own the extension!
 	}
@@ -108,6 +110,7 @@ protected:
 	LayeringExtension* _layering;
 
 private:
+	/// Helper method to retrieve the extension
 	void getLayeringExtension() {
 		_layering = this->isValid() ? this->extension<LayeringExtension>() : 0;
 		if (not _layering) {
diff --git a/DDRec/include/DDRec/API/Subdetector.h b/DDRec/include/DDRec/API/Subdetector.h
index 597171a6c..e9cde2c76 100644
--- a/DDRec/include/DDRec/API/Subdetector.h
+++ b/DDRec/include/DDRec/API/Subdetector.h
@@ -11,33 +11,73 @@
 #define SUBDETECTOR_H_
 
 #include "DD4hep/Detector.h"
+#include "DDRec/Extensions/SubdetectorExtension.h"
 
 namespace DD4hep {
 namespace DDRec {
 
 class Subdetector: public virtual Geometry::DetElement {
 public:
+	/// Default constructor
 	Subdetector(const Geometry::DetElement& det) :
 		Geometry::DetElement(det) {
-
+		getSubdetectorExtension();
 	}
+
+	/// Destructor
 	virtual ~Subdetector() {
-		// nothing to do
+		// does not own the extension!
+	}
+
+	/// Is this a barrel detector
+	bool isBarrel() const {
+		return _subdetector->isBarrel();
+	}
+
+	/// Is this an endcap detector
+	bool isEndcap() const {
+		return _subdetector->isEndcap();
 	}
 
-	bool isBarrel() const;
+	/// Access to the inner radius
+	double getRMin() const {
+		return _subdetector->getRMin();
+	}
 
-	bool isEndcap() const;
+	/// Access to the outer radius
+	double getRMax() const {
+		return _subdetector->getRMax();
+	}
 
-	double getRMin() const;
+	/// Access to the lower z extent
+	double getZMin() const {
+		return _subdetector->getZMin();
+	}
 
-	double getRMax() const;
+	/// Access to the upper z extent
+	double getZMax() const {
+		return _subdetector->getZMax();
+	}
 
-	double getZMin() const;
+	/// Access to the number of sides
+	/* Describes the number of corners for a polygon.
+	 * Returns 0 in case of a circular shape
+	 */
+	int getNSides() const {
+		return _subdetector->getNSides();
+	}
 
-	double getZMax() const;
+protected:
+	SubdetectorExtension* _subdetector;
 
-	int getNSides() const;
+private:
+	/// Helper method to retrieve the extension
+	void getSubdetectorExtension() {
+		_subdetector = this->isValid() ? this->extension<SubdetectorExtension>() : 0;
+		if (not _subdetector) {
+			throw invalid_detector_element("Found no extension of type \"SubdetectorExtension\"", Geometry::DetElement(*this));
+		}
+	}
 };
 
 } /* namespace DDRec */
diff --git a/DDRec/include/DDRec/Extensions/SubdetectorExtension.h b/DDRec/include/DDRec/Extensions/SubdetectorExtension.h
new file mode 100644
index 000000000..b883372a6
--- /dev/null
+++ b/DDRec/include/DDRec/Extensions/SubdetectorExtension.h
@@ -0,0 +1,58 @@
+/*
+ * LayeringExtension.h
+ *
+ * Abstract extension used by the LayeredSubdetector class.
+ *
+ *  Created on: Dec 11, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#ifndef DDRec_SUBDETECTOREXTENSION_H_
+#define DDRec_SUBDETECTOREXTENSION_H_
+
+#include "DD4hep/Detector.h"
+
+namespace DD4hep {
+namespace DDRec {
+
+/**
+ * Class describing general parameters of a subdetector.
+ */
+class SubdetectorExtension {
+public:
+	/// Destructor
+	virtual ~SubdetectorExtension() {
+	}
+
+	/// Is this a barrel detector
+	virtual bool isBarrel() const = 0;
+
+	/// Is this an endcap detector
+	virtual bool isEndcap() const = 0;
+
+	/// Access to the inner radius
+	virtual double getRMin() const = 0;
+
+	/// Access to the outer radius
+	virtual double getRMax() const = 0;
+
+	/// Access to the lower z extent
+	virtual double getZMin() const = 0;
+
+	/// Access to the upper z extent
+	virtual double getZMax() const = 0;
+
+	/// Access to the number of sides
+	/* Describes the number of corners for a polygon.
+	 * Returns 0 in case of a circular shape
+	 */
+	virtual int getNSides() const = 0;
+
+protected:
+	SubdetectorExtension() {
+	}
+};
+
+} /* namespace DDRec */
+} /* namespace DD4hep */
+#endif /* DDRec_SUBDETECTOREXTENSION_H_ */
diff --git a/DDRec/include/DDRec/Extensions/SubdetectorExtensionImpl.h b/DDRec/include/DDRec/Extensions/SubdetectorExtensionImpl.h
new file mode 100644
index 000000000..0a37fa2b3
--- /dev/null
+++ b/DDRec/include/DDRec/Extensions/SubdetectorExtensionImpl.h
@@ -0,0 +1,104 @@
+/*
+ * SubdetectorExtensionImpl.h
+ *
+ * Basic implementation of the SubdetectorExtension
+ *
+ *  Created on: Nov 6, 2014
+ *      Author: Christian Grefe, Bonn University
+ */
+
+#ifndef DDRec_SUBDETECTOREXTENSIONIMPL_H_
+#define DDRec_SUBDETECTOREXTENSIONIMPL_H_
+
+#include "DDRec/Extensions/SubdetectorExtension.h"
+#include "DD4hep/Detector.h"
+
+namespace DD4hep {
+namespace DDRec {
+
+/**
+ * Class describing general parameters of a subdetector.
+ * By default information is retrieved from the DetElement if possible.
+ * Values can be set manually which will superseed the information from
+ * the DetElement.
+ */
+class SubdetectorExtensionImpl: public SubdetectorExtension {
+public:
+	/// Default constructor using a top level DetElement
+	SubdetectorExtensionImpl(const Geometry::DetElement& det);
+
+	/// Copy constructor
+	SubdetectorExtensionImpl(const SubdetectorExtensionImpl& e, const Geometry::DetElement& d);
+
+	/// Destructor
+	virtual ~SubdetectorExtensionImpl();
+
+	/// Is this a barrel detector
+	virtual bool isBarrel() const;
+
+	/// Is this an endcap detector
+	virtual bool isEndcap() const;
+
+	/// Access to the inner radius
+	virtual double getRMin() const;
+
+	/// Access to the outer radius
+	virtual double getRMax() const;
+
+	/// Access to the lower z extent
+	virtual double getZMin() const;
+
+	/// Access to the upper z extent
+	virtual double getZMax() const;
+
+	/// Access to the number of sides
+	/* Describes the number of corners for a polygon.
+	 * Returns 0 in case of a circular shape
+	 */
+	virtual int getNSides() const;
+
+	/// Sets the top level detector element used to determine shape information
+	void setDetectorElement(const Geometry::DetElement& det);
+
+	/// Sets the isBarrel flag
+	void setIsBarrel(bool value);
+
+	/// Sets the isEndcap flag
+	void setIsEndcap(bool value);
+
+	/// Sets the value for the inner radius
+	void setRMin(double value);
+
+	/// Sets the value for the outer radius
+	void setRMax(double value);
+
+	/// Sets the value for the inner z extent
+	void setZMin(double value);
+
+	/// Sets the value for the outer z extent
+	void setZMax(double value);
+
+	/// Sets the number of sides
+	void setNSides(int value);
+
+protected:
+	Geometry::DetElement det;
+	bool _isBarrel;
+	bool _isEndcap;
+	double _rMin;
+	bool _setRMin;
+	double _rMax;
+	bool _setRMax;
+	double _zMin;
+	bool _setZMin;
+	double _zMax;
+	bool _setZMax;
+	int _nSides;
+	bool _setNSides;
+
+	void resetAll();
+};
+
+} /* namespace DDRec */
+} /* namespace DD4hep */
+#endif /* DDRec_SUBDETECTOREXTENSIONIMPL_H_ */
diff --git a/DDRec/src/Subdetector.cpp b/DDRec/src/Subdetector.cpp
deleted file mode 100644
index 245d99a9d..000000000
--- a/DDRec/src/Subdetector.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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/SubdetectorExtensionImpl.cpp b/DDRec/src/SubdetectorExtensionImpl.cpp
new file mode 100644
index 000000000..f74bd1c4f
--- /dev/null
+++ b/DDRec/src/SubdetectorExtensionImpl.cpp
@@ -0,0 +1,201 @@
+/*
+ * SubdetectorExtensionImpl.cpp
+ *
+ *  Created on: Nov 6, 2014
+ *      Author: Christian Grefe, Bonn University
+ */
+
+#include "DDRec/Extensions/SubdetectorExtensionImpl.h"
+
+#include "DD4hep/LCDD.h"
+
+namespace DD4hep {
+namespace DDRec {
+
+using Geometry::DetElement;
+
+/// Constructor using a top level DetElement
+SubdetectorExtensionImpl::SubdetectorExtensionImpl(const Geometry::DetElement& det) {
+	this->resetAll();
+	this->det = det;
+}
+
+/// Copy constructor
+SubdetectorExtensionImpl::SubdetectorExtensionImpl(const SubdetectorExtensionImpl& e, const Geometry::DetElement& d) {
+	this->det = d;
+	this->setIsBarrel(e.isBarrel());
+	this->setIsEndcap(e.isEndcap());
+	if (e._setRMin) {
+		this->setRMin(e.getRMin());
+	}
+	if (e._setRMax) {
+		this->setRMax(e.getRMax());
+	}
+	if (e._setZMin) {
+		this->setZMin(e.getZMin());
+	}
+	if (e._setZMax) {
+		this->setZMax(e.getZMax());
+	}
+	if (e._setNSides) {
+		this->setNSides(e.getNSides());
+	}
+}
+
+/// Destructor
+SubdetectorExtensionImpl::~SubdetectorExtensionImpl() {
+	// nothing to do
+}
+
+/// Is this a barrel detector
+bool SubdetectorExtensionImpl::isBarrel() const {
+	/// Fixme: could use IDDecoder to figure this out
+	return _isBarrel;
+}
+
+/// Is this an endcap detector
+bool SubdetectorExtensionImpl::isEndcap() const {
+	/// Fixme: could use IDDecoder to figure this out
+	return _isEndcap;
+}
+
+/// Access to the inner radius
+double SubdetectorExtensionImpl::getRMin() const {
+	if (_setRMin) {
+		return _rMin;
+	}
+	if (det.isValid() and det.volume().isValid() and det.volume().solid().isValid()) {
+		Geometry::Solid solid = det.volume().solid();
+		Geometry::Tube tube(solid);
+		if (tube.isValid()) {
+			return tube->GetRmin();
+		}
+	}
+	return 0.;
+}
+
+/// Access to the outer radius
+double SubdetectorExtensionImpl::getRMax() const {
+	if (_setRMax) {
+		return _rMax;
+	}
+	if (det.isValid() and det.volume().isValid() and det.volume().solid().isValid()) {
+		Geometry::Solid solid = det.volume().solid();
+		Geometry::Tube tube(solid);
+		if (tube.isValid()) {
+			return tube->GetRmax();
+		}
+	}
+	return 0.;
+}
+
+/// Access to the lower z extent
+double SubdetectorExtensionImpl::getZMin() const {
+	if (_setZMin) {
+		return _zMin;
+	}
+	if (det.isValid() and det.volume().isValid() and det.volume().solid().isValid()) {
+		Geometry::Solid solid = det.volume().solid();
+		Geometry::Box box(solid);
+		if (box.isValid()) {
+			return box->GetDZ();
+		}
+	}
+	return 0.;
+}
+
+/// Access to the upper z extent
+double SubdetectorExtensionImpl::getZMax() const {
+	if (_setZMax) {
+		return _zMax;
+	}
+	if (det.isValid() and det.volume().isValid() and det.volume().solid().isValid()) {
+		Geometry::Solid solid = det.volume().solid();
+		Geometry::Box box(solid);
+		if (box.isValid()) {
+			return box->GetDZ();
+		}
+	}
+	return 0.;
+}
+
+/// Access to the number of sides
+/* Describes the number of corners for a polygon.
+ * Returns 0 in case of a circular shape
+ */
+int SubdetectorExtensionImpl::getNSides() const {
+	if (_setNSides) {
+		return _nSides;
+	}
+	if (det.isValid() and det.volume().isValid() and det.volume().solid().isValid()) {
+		Geometry::Solid solid = det.volume().solid();
+		Geometry::PolyhedraRegular polyhedra(solid);
+		if (polyhedra.isValid()) {
+			return polyhedra->GetNedges();
+		}
+	}
+	return 0;
+}
+
+/// Sets the top level detector element used to determine shape information
+void SubdetectorExtensionImpl::setDetectorElement(const Geometry::DetElement& det) {
+	this->det = det;
+}
+
+/// Sets the isBarrel flag
+void SubdetectorExtensionImpl::setIsBarrel(bool value) {
+	_isBarrel = value;
+}
+
+/// Sets the isEndcap flag
+void SubdetectorExtensionImpl::setIsEndcap(bool value) {
+	_isEndcap = value;
+}
+
+/// Sets the value for the inner radius
+void SubdetectorExtensionImpl::setRMin(double value) {
+	_setRMin = true;
+	_rMin = value;
+}
+
+/// Sets the value for the outer radius
+void SubdetectorExtensionImpl::setRMax(double value) {
+	_setRMax = true;
+	_rMax = value;
+}
+
+/// Sets the value for the inner z extent
+void SubdetectorExtensionImpl::setZMin(double value) {
+	_setZMin = true;
+	_zMin = value;
+}
+
+/// Sets the value for the outer z extent
+void SubdetectorExtensionImpl::setZMax(double value) {
+	_setZMax = true;
+	_zMax = value;
+}
+
+/// Sets the number of sides
+void SubdetectorExtensionImpl::setNSides(int value) {
+	_setNSides = true;
+	_nSides = value;
+}
+
+void SubdetectorExtensionImpl::resetAll() {
+	_isBarrel = false;
+	_isEndcap = false;
+	_rMin = 0.;
+	_setRMin = false;
+	_rMax = 0.;
+	_setRMax = false;
+	_zMin = 0.;
+	_setZMin = false;
+	_zMax = 0.;
+	_setZMax = false;
+	_nSides = 0;
+	_setNSides = false;
+}
+
+} /* namespace DDRec */
+} /* namespace DD4hep */
-- 
GitLab