From c0c608c25f77ab81d361fd26e33c5a7ac9345694 Mon Sep 17 00:00:00 2001
From: Christian Grefe <Christian.Grefe@cern.ch>
Date: Mon, 16 Sep 2013 08:57:44 +0000
Subject: [PATCH] First try of a segmentation package For now completely
 decoupled from DDCore only uses BitField64 from there. Part of the code
 should replace the Geometry::Segmentation classes

---
 CMakeLists.txt                                |  1 +
 DDSegmentation/CMakeLists.txt                 | 32 +++++++++
 .../DDSegmentation/CartesianSegmentation.h    | 29 ++++++++
 .../DDSegmentation/CartesianXYSegmentation.h  | 54 ++++++++++++++
 .../DDSegmentation/CartesianXYZSegmentation.h | 43 +++++++++++
 .../include/DDSegmentation/CellIDDecoder.h    | 71 +++++++++++++++++++
 .../DDSegmentation/CellIDDecoderFactory.h     | 43 +++++++++++
 .../include/DDSegmentation/Segmentation.h     | 41 +++++++++++
 DDSegmentation/src/CartesianSegmentation.cpp  | 38 ++++++++++
 .../src/CartesianXYSegmentation.cpp           | 51 +++++++++++++
 .../src/CartesianXYZSegmentation.cpp          | 50 +++++++++++++
 DDSegmentation/src/Segmentation.cpp           | 36 ++++++++++
 12 files changed, 489 insertions(+)
 create mode 100644 DDSegmentation/CMakeLists.txt
 create mode 100644 DDSegmentation/include/DDSegmentation/CartesianSegmentation.h
 create mode 100644 DDSegmentation/include/DDSegmentation/CartesianXYSegmentation.h
 create mode 100644 DDSegmentation/include/DDSegmentation/CartesianXYZSegmentation.h
 create mode 100644 DDSegmentation/include/DDSegmentation/CellIDDecoder.h
 create mode 100644 DDSegmentation/include/DDSegmentation/CellIDDecoderFactory.h
 create mode 100644 DDSegmentation/include/DDSegmentation/Segmentation.h
 create mode 100644 DDSegmentation/src/CartesianSegmentation.cpp
 create mode 100644 DDSegmentation/src/CartesianXYSegmentation.cpp
 create mode 100644 DDSegmentation/src/CartesianXYZSegmentation.cpp
 create mode 100644 DDSegmentation/src/Segmentation.cpp

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 387d48db4..ea76225cb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -58,6 +58,7 @@ ENDIF()
 
 #---Packages------------------------------------------------------------------------
 add_subdirectory(DDCore)
+add_subdirectory(DDSegmentation)
 
 if(DD4HEP_WITH_GEANT4)
   add_subdirectory(DDG4)
diff --git a/DDSegmentation/CMakeLists.txt b/DDSegmentation/CMakeLists.txt
new file mode 100644
index 000000000..843d317f0
--- /dev/null
+++ b/DDSegmentation/CMakeLists.txt
@@ -0,0 +1,32 @@
+cmake_minimum_required(VERSION 2.8.3 FATAL_ERROR)
+
+include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/include 
+                     ${CMAKE_SOURCE_DIR}/DDCore/include 
+                     ${ROOT_INCLUDE_DIR})
+
+file(GLOB sources src/*.cpp)
+include(DD4hep_XML_setup)
+
+add_library(DDSegmentation SHARED ${sources})
+target_link_libraries(DDSegmentation ${DD4hep_LIBRARIES} ${ROOT_LIBRARIES})
+
+SET_TARGET_PROPERTIES( DDSegmentation PROPERTIES VERSION ${DD4hep_VERSION} SOVERSION ${DD4hep_SOVERSION})
+
+#---Rootmap generation--------------------------------------------------------------
+if(APPLE)
+  dd4hep_generate_rootmap_apple(DDSegmentation)
+else()
+  dd4hep_generate_rootmap(DDSegmentation)
+endif()
+#--- install target-------------------------------------
+
+install(DIRECTORY include/DDSegmentation
+  DESTINATION include
+  PATTERN ".svn" EXCLUDE )
+
+install(TARGETS DDSegmentation
+  RUNTIME DESTINATION bin
+  LIBRARY DESTINATION lib
+  )
+# to do: add corresponding uninstall...
+#-------------------------------------------------------
\ No newline at end of file
diff --git a/DDSegmentation/include/DDSegmentation/CartesianSegmentation.h b/DDSegmentation/include/DDSegmentation/CartesianSegmentation.h
new file mode 100644
index 000000000..d52209eea
--- /dev/null
+++ b/DDSegmentation/include/DDSegmentation/CartesianSegmentation.h
@@ -0,0 +1,29 @@
+/*
+ * CartesianSegmentation.h
+ *
+ *  Created on: Jun 28, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#ifndef CARTESIANSEGMENTATION_H_
+#define CARTESIANSEGMENTATION_H_
+
+#include "DDSegmentation/Segmentation.h"
+
+namespace DD4hep {
+namespace DDSegmentation {
+
+class CartesianSegmentation: public Segmentation {
+public:
+	virtual ~CartesianSegmentation();
+protected:
+	CartesianSegmentation(const std::string& cellEncoding);
+	CartesianSegmentation(const BitField64& decoder);
+
+	double binToPosition(long64 bin, double cellSize, double offset) const;
+	int positionToBin(double position, double cellSize, double offset) const;
+};
+
+} /* namespace Segmentation */
+} /* namespace DD4hep */
+#endif /* CARTESIANSEGMENTATION_H_ */
diff --git a/DDSegmentation/include/DDSegmentation/CartesianXYSegmentation.h b/DDSegmentation/include/DDSegmentation/CartesianXYSegmentation.h
new file mode 100644
index 000000000..32e0bed4f
--- /dev/null
+++ b/DDSegmentation/include/DDSegmentation/CartesianXYSegmentation.h
@@ -0,0 +1,54 @@
+/*
+ * CartesianXYSegmentation.h
+ *
+ *  Created on: Jun 28, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#ifndef CARTESIANXYSEGMENTATION_H_
+#define CARTESIANXYSEGMENTATION_H_
+
+#include "DDSegmentation/CartesianSegmentation.h"
+
+namespace DD4hep {
+namespace DDSegmentation {
+
+class CartesianXYSegmentation: public CartesianSegmentation {
+public:
+	CartesianXYSegmentation(const std::string& cellEncoding, double cellSizeX, double cellSizeY, double offsetX = 0.,
+			double offsetY = 0.);
+	CartesianXYSegmentation(const BitField64& decoder, double cellSizeX, double cellSizeY, double offsetX = 0.,
+			double offsetY = 0.);
+	virtual ~CartesianXYSegmentation();
+
+
+	virtual std::vector<double> getLocalPosition(const long64& cellID) const;
+
+	virtual long64 getCellID(double x, double y, double z) const;
+
+	double getCellSizeX() const {
+		return _cellSizeX;
+	}
+
+	double getCellSizeY() const {
+		return _cellSizeY;
+	}
+
+	double getOffsetX() const {
+		return _offsetX;
+	}
+
+	double getOffsetY() const {
+		return _offsetY;
+	}
+
+protected:
+	double _cellSizeX;
+	double _offsetX;
+	double _cellSizeY;
+	double _offsetY;
+};
+
+} /* namespace Segmentation */
+} /* namespace DD4hep */
+#endif /* CARTESIANXYSEGMENTATION_H_ */
diff --git a/DDSegmentation/include/DDSegmentation/CartesianXYZSegmentation.h b/DDSegmentation/include/DDSegmentation/CartesianXYZSegmentation.h
new file mode 100644
index 000000000..d0914f03b
--- /dev/null
+++ b/DDSegmentation/include/DDSegmentation/CartesianXYZSegmentation.h
@@ -0,0 +1,43 @@
+/*
+ * CartesianXYZSegmentation.h
+ *
+ *  Created on: Jun 28, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#ifndef CARTESIANXYZSEGMENTATION_H_
+#define CARTESIANXYZSEGMENTATION_H_
+
+#include "DDSegmentation/CartesianXYSegmentation.h"
+
+namespace DD4hep {
+namespace DDSegmentation {
+
+class CartesianXYZSegmentation: public CartesianXYSegmentation {
+public:
+	CartesianXYZSegmentation(const std::string& cellEncoding, double cellSizeX, double cellSizeY, double cellSizeZ,
+			double offsetX = 0., double offsetY = 0., double offsetZ = 0.);
+	CartesianXYZSegmentation(const BitField64& decoder, double cellSizeX, double cellSizeY, double cellSizeZ, double offsetX =
+			0., double offsetY = 0., double offsetZ = 0.);
+	virtual ~CartesianXYZSegmentation();
+
+	virtual std::vector<double> getLocalPosition(const long64& cellID) const;
+
+	virtual long64 getCellID(double x, double y, double z) const;
+
+	double getCellSizeZ() const {
+		return _cellSizeZ;
+	}
+
+	double getOffsetZ() const {
+		return _offsetZ;
+	}
+
+protected:
+	double _cellSizeZ;
+	double _offsetZ;
+};
+
+} /* namespace Segmentation */
+} /* namespace DD4hep */
+#endif /* CARTESIANXYZSEGMENTATION_H_ */
diff --git a/DDSegmentation/include/DDSegmentation/CellIDDecoder.h b/DDSegmentation/include/DDSegmentation/CellIDDecoder.h
new file mode 100644
index 000000000..139c7704d
--- /dev/null
+++ b/DDSegmentation/include/DDSegmentation/CellIDDecoder.h
@@ -0,0 +1,71 @@
+/*
+ * CellIDDecoder.h
+ * This is an example of mixing the segmentation interface with the volume manager. Could move into Readout class.
+ *  Created on: Sep 16, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#ifndef CELLIDDECODER_H_
+#define CELLIDDECODER_H_
+
+#include "DD4hep/VolumeManager.h"
+#include "DD4hep/Objects.h"
+#include "DD4hep/TGeoUnits.h"
+#include "DDSegmentation/Segmentation.h"
+
+namespace DD4hep {
+namespace DDSegmentation {
+
+class CellIDDecoder {
+public:
+	CellIDDecoder(const Geometry::VolumeManager& volManager, const Segmentation* segmentation) : _volManager(volManager), _segmentation(segmentation) {
+
+	}
+
+	virtual ~CellIDDecoder() {
+		delete _segmentation;
+	}
+
+	Geometry::PlacedVolume getPlacement(const long& cellID) const {
+		return _volManager.lookupPlacement(cellID);
+	}
+
+	Geometry::DetElement getSubDetector(const long& cellID) const {
+		return _volManager.lookupDetector(cellID);
+	}
+
+	Geometry::DetElement getDetectorElement(const long& cellID) const {
+		return _volManager.lookupDetElement(cellID);
+	}
+
+	Geometry::Position getPosition(const long64& cellID) const {
+		double global[3] = {0., 0., 0.};
+		_volManager.worldTransformation(cellID).LocalToMaster(&(_segmentation->getLocalPosition(cellID))[0], global);
+		return Geometry::Position(global[0]/tgeo::mm, global[1]/tgeo::mm, global[2]/tgeo::mm);
+	}
+
+	const TGeoMatrix& getWorldTransformation(const long& cellID) const {
+		return _volManager.worldTransformation(cellID);
+	}
+
+	Geometry::Position getLocalPosition(const long64& cellID) const {
+		std::vector<double> v = _segmentation->getLocalPosition(cellID);
+		return Geometry::Position(v[0], v[1], v[2]);
+	}
+
+	long64 getCellID(double x, double y, double z) const {
+		return _segmentation->getCellID(x, y, z);
+	}
+
+	std::string fieldDescription() const {
+		return _segmentation->fieldDescription();
+	}
+
+protected:
+	const Segmentation* _segmentation;
+	const Geometry::VolumeManager _volManager;
+};
+
+} /* namespace DDSegmentation */
+} /* namespace DD4hep */
+#endif /* CELLIDDECODER_H_ */
diff --git a/DDSegmentation/include/DDSegmentation/CellIDDecoderFactory.h b/DDSegmentation/include/DDSegmentation/CellIDDecoderFactory.h
new file mode 100644
index 000000000..b242cb8a6
--- /dev/null
+++ b/DDSegmentation/include/DDSegmentation/CellIDDecoderFactory.h
@@ -0,0 +1,43 @@
+/*
+ * CellIDDecoderFactory.h
+ *
+ * This class would be obsolete if Geometry::Segmentation would directly use the DDSegmentation classes
+ *
+ *  Created on: Sep 16, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#ifndef CELLIDDECODERFACTORY_H_
+#define CELLIDDECODERFACTORY_H_
+
+#include "DD4hep/LCDD.h"
+#include "DD4hep/Segmentations.h"
+#include "DDSegmentation/CartesianXYSegmentation.h"
+
+#include <iostream>
+#include <string>
+
+namespace DD4hep {
+namespace DDSegmentation {
+
+namespace CellIDDecoderFactory {
+CellIDDecoder getCellIDDecoder(const std::string& collectionName) {
+	Geometry::LCDD& lcdd = Geometry::LCDD::getInstance();
+	Geometry::VolumeManager volManager = lcdd.volumeManager();
+	Geometry::Readout readout = lcdd.readout(collectionName);
+	Geometry::Segmentation s = readout.segmentation();
+	Segmentation* segmentation;
+	std::string type = s.type();
+	if (type == "grid_xyz") {
+		Geometry::GridXYZ g = (Geometry::GridXY) s;
+		segmentation = new CartesianXYSegmentation(readout.idSpec().fieldDescription(), g.getGridSizeX(), g.getGridSizeY());
+	} else {
+	    throw std::runtime_error("The segmentation type "+type+" is not supported by CellIDDecoderFactory.");
+	}
+	return CellIDDecoder(volManager, segmentation);
+}
+}
+
+} /* namespace DDSegmentation */
+} /* namespace DD4hep */
+#endif /* CELLIDDECODERFACTORY_H_ */
diff --git a/DDSegmentation/include/DDSegmentation/Segmentation.h b/DDSegmentation/include/DDSegmentation/Segmentation.h
new file mode 100644
index 000000000..140f9ab3e
--- /dev/null
+++ b/DDSegmentation/include/DDSegmentation/Segmentation.h
@@ -0,0 +1,41 @@
+/*
+ * Segmentation.h
+ *
+ *  Created on: Jun 27, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#ifndef SEGMENTATION_H_
+#define SEGMENTATION_H_
+
+#include "DD4hep/BitField64.h"
+
+#include <string>
+#include <vector>
+
+namespace DD4hep {
+namespace DDSegmentation {
+
+class Segmentation {
+public:
+	Segmentation(const std::string& cellEncoding);
+	Segmentation(const BitField64& decoder);
+	virtual ~Segmentation();
+
+	virtual std::vector<double> getLocalPosition(const long64& cellID) const = 0;
+
+	virtual long64 getCellID(double x, double y, double z) const = 0;
+	long64 getCellID(const std::vector<double>& localPosition) const;
+	long64 getCellID(const double* localPosition) const;
+
+	std::string fieldDescription() const {
+		return _decoder.fieldDescription();
+	}
+
+protected:
+	mutable BitField64 _decoder;
+};
+
+} /* namespace Segmentation */
+} /* namespace DD4hep */
+#endif /* SEGMENTATION_H_ */
diff --git a/DDSegmentation/src/CartesianSegmentation.cpp b/DDSegmentation/src/CartesianSegmentation.cpp
new file mode 100644
index 000000000..c55b585e4
--- /dev/null
+++ b/DDSegmentation/src/CartesianSegmentation.cpp
@@ -0,0 +1,38 @@
+/*
+ * CartesianSegmentation.cpp
+ *
+ *  Created on: Jun 28, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#include "DDSegmentation/CartesianSegmentation.h"
+
+namespace DD4hep {
+namespace DDSegmentation {
+
+using std::string;
+
+CartesianSegmentation::CartesianSegmentation(const string& cellEncoding) :
+		Segmentation(cellEncoding) {
+
+}
+
+CartesianSegmentation::CartesianSegmentation(const BitField64& decoder) :
+		Segmentation(decoder) {
+
+}
+
+CartesianSegmentation::~CartesianSegmentation() {
+
+}
+
+double CartesianSegmentation::binToPosition(long64 bin, double cellSize, double offset) const {
+	return bin * cellSize + offset;
+}
+
+int CartesianSegmentation::positionToBin(double position, double cellSize, double offset) const {
+	return int((position + 0.5 * cellSize - offset)/cellSize);
+}
+
+} /* namespace Segmentation */
+} /* namespace DD4hep */
diff --git a/DDSegmentation/src/CartesianXYSegmentation.cpp b/DDSegmentation/src/CartesianXYSegmentation.cpp
new file mode 100644
index 000000000..acbbcef20
--- /dev/null
+++ b/DDSegmentation/src/CartesianXYSegmentation.cpp
@@ -0,0 +1,51 @@
+/*
+ * CartesianXYSegmentation.cpp
+ *
+ *  Created on: Jun 28, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#include "DDSegmentation/CartesianXYSegmentation.h"
+
+namespace DD4hep {
+namespace DDSegmentation {
+
+using std::string;
+using std::vector;
+
+CartesianXYSegmentation::CartesianXYSegmentation(const string& cellEncoding, double cellSizeX, double cellSizeY,
+		double offsetX, double offsetY) :
+		CartesianSegmentation(cellEncoding), _cellSizeX(cellSizeX), _cellSizeY(cellSizeY), _offsetX(offsetX), _offsetY(
+				offsetY) {
+
+}
+
+CartesianXYSegmentation::CartesianXYSegmentation(const BitField64& decoder, double cellSizeX, double cellSizeY,
+		double offsetX, double offsetY) :
+		CartesianSegmentation(decoder), _cellSizeX(cellSizeX), _cellSizeY(cellSizeY), _offsetX(offsetX), _offsetY(
+				offsetY) {
+
+}
+
+CartesianXYSegmentation::~CartesianXYSegmentation() {
+
+}
+
+vector<double> CartesianXYSegmentation::getLocalPosition(const long64& cellID) const {
+	_decoder.setValue(cellID);
+	vector<double> localPosition(3);
+	localPosition[0] = binToPosition(_decoder["x"].value(), _cellSizeX, _offsetX);
+	localPosition[1] = binToPosition(_decoder["y"].value(), _cellSizeY, _offsetY);
+	localPosition[2] = 0.;
+	return localPosition;
+}
+
+long64 CartesianXYSegmentation::getCellID(double x, double y, double z) const {
+	_decoder.reset();
+	_decoder["x"] = positionToBin(x, _cellSizeX, _offsetX);
+	_decoder["y"] = positionToBin(y, _cellSizeY, _offsetY);
+	return _decoder.getValue();
+}
+
+} /* namespace Segmentation */
+} /* namespace DD4hep */
diff --git a/DDSegmentation/src/CartesianXYZSegmentation.cpp b/DDSegmentation/src/CartesianXYZSegmentation.cpp
new file mode 100644
index 000000000..fbc8171bd
--- /dev/null
+++ b/DDSegmentation/src/CartesianXYZSegmentation.cpp
@@ -0,0 +1,50 @@
+/*
+ * CartesianXYZSegmentation.cpp
+ *
+ *  Created on: Jun 28, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#include "DDSegmentation/CartesianXYZSegmentation.h"
+
+namespace DD4hep {
+namespace DDSegmentation {
+
+using std::string;
+using std::vector;
+
+CartesianXYZSegmentation::CartesianXYZSegmentation(const string& cellEncoding, double cellSizeX, double cellSizeY, double cellSizeZ,
+		double offsetX, double offsetY, double offsetZ) :
+		CartesianXYSegmentation(cellEncoding, cellSizeX, cellSizeY, offsetX, offsetY), _cellSizeZ(cellSizeZ), _offsetZ(offsetZ) {
+
+}
+
+CartesianXYZSegmentation::CartesianXYZSegmentation(const BitField64& decoder, double cellSizeX, double cellSizeY, double cellSizeZ,
+		double offsetX, double offsetY, double offsetZ) :
+		CartesianXYSegmentation(decoder, cellSizeX, cellSizeY, offsetX, offsetY), _cellSizeZ(cellSizeZ), _offsetZ(offsetZ) {
+
+}
+
+CartesianXYZSegmentation::~CartesianXYZSegmentation() {
+
+}
+
+vector<double> CartesianXYZSegmentation::getLocalPosition(const long64& cellID) const {
+	_decoder.setValue(cellID);
+	vector<double> localPosition;
+	localPosition[0] = binToPosition(_decoder["x"].value(), _cellSizeX, _offsetX);
+	localPosition[1] = binToPosition(_decoder["y"].value(), _cellSizeY, _offsetY);
+	localPosition[2] = binToPosition(_decoder["z"].value(), _cellSizeZ, _offsetZ);
+	return localPosition;
+}
+
+long64 CartesianXYZSegmentation::getCellID(double x, double y, double z) const {
+	_decoder.reset();
+	_decoder["x"] = positionToBin(x, _cellSizeX, _offsetX);
+	_decoder["y"] = positionToBin(y, _cellSizeY, _offsetY);
+	_decoder["z"] = positionToBin(z, _cellSizeZ, _offsetZ);
+	return _decoder.getValue();
+}
+
+} /* namespace Segmentation */
+} /* namespace DD4hep */
diff --git a/DDSegmentation/src/Segmentation.cpp b/DDSegmentation/src/Segmentation.cpp
new file mode 100644
index 000000000..37fa60419
--- /dev/null
+++ b/DDSegmentation/src/Segmentation.cpp
@@ -0,0 +1,36 @@
+/*
+ * Segmentation.cpp
+ *
+ *  Created on: Jun 27, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#include "DDSegmentation/Segmentation.h"
+
+namespace DD4hep {
+namespace DDSegmentation {
+
+using std::string;
+using std::vector;
+
+Segmentation::Segmentation(const string& cellEncoding) : _decoder(cellEncoding) {
+}
+
+Segmentation::Segmentation(const BitField64& decoder) : _decoder(decoder.fieldDescription()) {
+
+}
+
+Segmentation::~Segmentation() {
+
+}
+
+long64 Segmentation::getCellID(const vector<double>& localPosition) const {
+	return getCellID(localPosition[0], localPosition[1], localPosition[2]);
+}
+
+long64 Segmentation::getCellID(const double* localPosition) const {
+	return getCellID(localPosition[0], localPosition[1], localPosition[2]);
+}
+
+} /* namespace Segmentation */
+} /* namespace DD4hep */
-- 
GitLab