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