From eaea3109fadda76851bc715753e6ebe431335280 Mon Sep 17 00:00:00 2001
From: Shaojun Lu <shaojun.lu@desy.de>
Date: Wed, 20 Apr 2016 08:19:43 +0000
Subject: [PATCH]  Added a WaferGridXY cartesian segmentation for SiWEcal. The
 SiWEcal include both Normal wafer and Magic wafer depending on the layer
 dimensions. Implemented a new algorithm to transfor the SiWEcal04 sensitive
 driver into DD4hep framework. This algorithm works for both Normal and Magic
 wafer design.

---
 .../include/DDSegmentation/WaferGridXY.h      | 132 ++++++++++++++++++
 DDSegmentation/src/WaferGridXY.cpp            | 113 +++++++++++++++
 2 files changed, 245 insertions(+)
 create mode 100644 DDSegmentation/include/DDSegmentation/WaferGridXY.h
 create mode 100644 DDSegmentation/src/WaferGridXY.cpp

diff --git a/DDSegmentation/include/DDSegmentation/WaferGridXY.h b/DDSegmentation/include/DDSegmentation/WaferGridXY.h
new file mode 100644
index 000000000..0bbd1dd8f
--- /dev/null
+++ b/DDSegmentation/include/DDSegmentation/WaferGridXY.h
@@ -0,0 +1,132 @@
+/*
+ * WaferGridXY.h
+ *
+ *  Created on: April 19, 2016
+ *      Author: S. Lu, DESY
+ */
+
+#ifndef DDSegmentation_WAFERGRIDXY_H_
+#define DDSegmentation_WAFERGRIDXY_H_
+
+#include "DDSegmentation/CartesianGrid.h"
+
+#define MAX_LAYERS 100
+#define MAX_WAFERS 100
+
+namespace DD4hep {
+namespace DDSegmentation {
+
+class WaferGridXY: public CartesianGrid {
+public:
+	/// Default constructor passing the encoding string
+	WaferGridXY(const std::string& cellEncoding = "");
+	/// destructor
+	virtual ~WaferGridXY();
+
+	/// determine the position based on the cell ID
+	virtual Vector3D position(const CellID& cellID) const;
+	/// determine the cell ID based on the position
+	virtual CellID cellID(const Vector3D& localPosition, const Vector3D& globalPosition, const VolumeID& volumeID) const;
+	/// access the grid size in X
+	double gridSizeX() const {
+		return _gridSizeX;
+	}
+	/// access the grid size in Y
+	double gridSizeY() const {
+		return _gridSizeY;
+	}
+	/// access the coordinate offset in X
+	double offsetX() const {
+		return _offsetX;
+	}
+	/// access the coordinate offset in Y
+	double offsetY() const {
+		return _offsetY;
+	}
+        /// access the coordinate waferOffset for inLayer in X
+	double waferOffsetX(int inLayer, int inWafer) const {
+	  return  _waferOffsetX[inLayer][inWafer];
+	}
+        /// access the coordinate waferOffset for inLayer in Y
+	double waferOffsetY(int inLayer, int inWafer) const {
+	  return  _waferOffsetY[inLayer][inWafer];
+	}
+
+	/// access the field name used for X
+	const std::string& fieldNameX() const {
+		return _xId;
+	}
+	/// access the field name used for Y
+	const std::string& fieldNameY() const {
+		return _yId;
+	}
+	/// set the grid size in X
+	void setGridSizeX(double cellSize) {
+		_gridSizeX = cellSize;
+	}
+	/// set the grid size in Y
+	void setGridSizeY(double cellSize) {
+		_gridSizeY = cellSize;
+	}
+	/// set the coordinate offset in X
+	void setOffsetX(double offset) {
+		_offsetX = offset;
+	}
+	/// set the coordinate offset in Y
+	void setOffsetY(double offset) {
+		_offsetY = offset;
+	}
+        /// set the coordinate waferOffset for inlayer in X
+        void setWaferOffsetX(int inLayer,int inWafer, double offset) {
+          _waferOffsetX[inLayer][inWafer] = offset;
+        }
+        /// set the coordinate waferOffset for inLayer in Y
+        void setWaferOffsetY(int inLayer,int inWafer, double offset) {
+          _waferOffsetY[inLayer][inWafer] = offset;
+        }
+
+	/// set the field name used for X
+	void setFieldNameX(const std::string& fieldName) {
+		_xId = fieldName;
+	}
+	/// set the field name used for Y
+	void setFieldNameY(const std::string& fieldName) {
+		_yId = fieldName;
+	}
+	/** \brief Returns a vector<double> of the cellDimensions of the given cell ID
+	    in natural order of dimensions, e.g., dx/dy/dz, or dr/r*dPhi
+
+	    Returns a vector of the cellDimensions of the given cell ID
+	    \param cellID is ignored as all cells have the same dimension
+	    \return std::vector<double> size 2:
+	    -# size in x
+	    -# size in y
+	*/
+	virtual std::vector<double> cellDimensions(const CellID& cellID) const;
+
+protected:
+	/// the grid size in X
+	double _gridSizeX;
+	/// the coordinate offset in X
+	double _offsetX;
+	/// the grid size in Y
+	double _gridSizeY;
+	/// the coordinate offset in Y
+	double _offsetY;
+        /// list of wafer x offset for each layer
+	double _waferOffsetX[MAX_LAYERS][MAX_WAFERS];
+        /// list of wafer y offset for each layer
+	double _waferOffsetY[MAX_LAYERS][MAX_WAFERS];
+	/// the field name used for X
+	std::string _xId;
+	/// the field name used for Y
+	std::string _yId;
+        /// encoding field used for the layer
+        std::string _identifierLayer; 
+        /// encoding field used for the wafer
+        std::string _identifierWafer; 
+};
+
+} /* namespace DDSegmentation */
+} /* namespace DD4hep */
+#endif /* DDSegmentation_WAFERGRIDXY_H_ */
diff --git a/DDSegmentation/src/WaferGridXY.cpp b/DDSegmentation/src/WaferGridXY.cpp
new file mode 100644
index 000000000..46e592490
--- /dev/null
+++ b/DDSegmentation/src/WaferGridXY.cpp
@@ -0,0 +1,113 @@
+/*
+ * WaferGridXY.cpp
+ *
+ *  Created on: April 19, 2016
+ *      Author: S. Lu, DESY
+ */
+
+#include "DDSegmentation/WaferGridXY.h"
+
+namespace DD4hep {
+namespace DDSegmentation {
+
+/// default constructor using an encoding string
+WaferGridXY::WaferGridXY(const std::string& cellEncoding) :
+		CartesianGrid(cellEncoding) {
+	// define type and description
+	_type = "WaferGridXY";
+	_description = "Cartesian segmentation in the local XY-plane for both Normal wafer and Magic wafer(depending on the layer dimensions)";
+
+	// register all necessary parameters
+	registerParameter("grid_size_x", "Cell size in X", _gridSizeX, 1., SegmentationParameter::LengthUnit);
+	registerParameter("grid_size_y", "Cell size in Y", _gridSizeY, 1., SegmentationParameter::LengthUnit);
+	registerParameter("offset_x", "Cell offset in X", _offsetX, 0., SegmentationParameter::LengthUnit, true);
+	registerParameter("offset_y", "Cell offset in Y", _offsetY, 0., SegmentationParameter::LengthUnit, true);
+	registerIdentifier("identifier_x", "Cell ID identifier for X", _xId, "x");
+	registerIdentifier("identifier_y", "Cell ID identifier for Y", _yId, "y");
+        registerParameter("identifier_layer", "Cell encoding identifier for layer", _identifierLayer, std::string("layer"),
+                        SegmentationParameter::NoUnit, true);
+        registerParameter("identifier_wafer", "Cell encoding identifier for wafer", _identifierWafer, std::string("wafer"),
+                        SegmentationParameter::NoUnit, true);
+}
+
+/// destructor
+WaferGridXY::~WaferGridXY() {
+
+}
+
+/// determine the position based on the cell ID
+Vector3D WaferGridXY::position(const CellID& cID) const {
+	_decoder->setValue(cID);
+        unsigned int _layerIndex;
+        unsigned int _waferIndex;
+	Vector3D cellPosition;
+
+        _layerIndex = (*_decoder)[_identifierLayer];
+        _waferIndex = (*_decoder)[_identifierWafer];
+
+	if ( _waferOffsetX[_layerIndex][_waferIndex] > 0 || _waferOffsetX[_layerIndex][_waferIndex] < 0 )
+	  {
+	    cellPosition.X = binToPosition((*_decoder)[_xId].value(), _gridSizeX, _offsetX+_waferOffsetX[_layerIndex][_waferIndex]);
+	  }
+	else
+	  {
+	    cellPosition.X = binToPosition((*_decoder)[_xId].value(), _gridSizeX, _offsetX);
+	  }
+
+	if ( _waferOffsetY[_layerIndex][_waferIndex] > 0 || _waferOffsetY[_layerIndex][_waferIndex] < 0 )
+	  {
+	    cellPosition.Y = binToPosition((*_decoder)[_yId].value(), _gridSizeY, _offsetY+_waferOffsetY[_layerIndex][_waferIndex]);
+	  }
+	else
+	  {
+	    cellPosition.Y = binToPosition((*_decoder)[_yId].value(), _gridSizeY, _offsetY);
+	  }
+
+	return cellPosition;
+}
+
+/// determine the cell ID based on the position
+  CellID WaferGridXY::cellID(const Vector3D& localPosition, const Vector3D& /* globalPosition */, const VolumeID& vID) const {
+	_decoder->setValue(vID);
+        unsigned int _layerIndex;
+        unsigned int _waferIndex;
+
+        _layerIndex = (*_decoder)[_identifierLayer];
+        _waferIndex = (*_decoder)[_identifierWafer];
+
+	if ( _waferOffsetX[_layerIndex][_waferIndex] > 0 || _waferOffsetX[_layerIndex][_waferIndex] < 0 )
+	  {
+	    (*_decoder)[_xId] = positionToBin(localPosition.X, _gridSizeX, _offsetX+_waferOffsetX[_layerIndex][_waferIndex]);
+	  }
+	else
+	  {
+	    (*_decoder)[_xId] = positionToBin(localPosition.X, _gridSizeX, _offsetX);
+	  }
+
+	if ( _waferOffsetY[_layerIndex][_waferIndex] > 0 ||  _waferOffsetY[_layerIndex][_waferIndex] < 0)
+	  {
+	    (*_decoder)[_yId] = positionToBin(localPosition.Y, _gridSizeY, _offsetY+_waferOffsetY[_layerIndex][_waferIndex]);
+	  }
+	else
+	  {
+	    (*_decoder)[_yId] = positionToBin(localPosition.Y, _gridSizeY, _offsetY);
+	  }
+
+	return _decoder->getValue();
+}
+
+std::vector<double> WaferGridXY::cellDimensions(const CellID&) const {
+#if __cplusplus >= 201103L
+  return {_gridSizeX, _gridSizeY};
+#else
+  std::vector<double> cellDims(2,0.0);
+  cellDims[0] = _gridSizeX;
+  cellDims[1] = _gridSizeY;
+  return cellDims;
+#endif
+}
+
+REGISTER_SEGMENTATION(WaferGridXY)
+
+} /* namespace DDSegmentation */
+} /* namespace DD4hep */
-- 
GitLab