diff --git a/DDCore/include/DD4hep/Readout.h b/DDCore/include/DD4hep/Readout.h index e8c7d1da1812e9cddb7e884ed9b014961b2c8738..2083f7211923d9793ad924b3c50d1152cbeb95af 100644 --- a/DDCore/include/DD4hep/Readout.h +++ b/DDCore/include/DD4hep/Readout.h @@ -74,7 +74,6 @@ namespace DD4hep { DetElement getSubDetector(const long64& cellID) const; DetElement getDetectorElement(const long64& cellID) const; Position getPosition(const long64& cellID) const; - Position getLocalPosition(const long64& cellID) const; const TGeoMatrix& getWorldTransformation(const long64& cellID) const; }; diff --git a/DDCore/src/Readout.cpp b/DDCore/src/Readout.cpp index e66580aa345f13131b15cb23cbe7ac56005661ca..240eb572874b7db13868bfc05629042387155666 100644 --- a/DDCore/src/Readout.cpp +++ b/DDCore/src/Readout.cpp @@ -90,14 +90,14 @@ DetElement Readout::getDetectorElement(const long64& cellID) const { return volMan.lookupDetElement(cellID); } Position Readout::getPosition(const long64& cellID) const { - double global[3] = {0., 0., 0.}; VolumeManager volMan = LCDD::getInstance().volumeManager(); - volMan.worldTransformation(cellID).LocalToMaster(&(segmentation().segmentation()->getLocalPosition(cellID))[0], global); - return Position(global[0]/tgeo::mm, global[1]/tgeo::mm, global[2]/tgeo::mm); -} -Position Readout::getLocalPosition(const long64& cellID) const { - std::vector<double> v = segmentation().segmentation()->getLocalPosition(cellID); - return Position(v[0], v[1], v[2]); + std::vector<double> position = segmentation().segmentation()->getPosition(cellID); + if (segmentation().segmentation()->isLocal()) { + double global[3] = {0., 0., 0.}; + volMan.worldTransformation(cellID).LocalToMaster(&position[0], global); + return Position(global[0]/tgeo::mm, global[1]/tgeo::mm, global[2]/tgeo::mm); + } + return Position(position[0]/tgeo::mm, position[1]/tgeo::mm, position[2]/tgeo::mm); } const TGeoMatrix& Readout::getWorldTransformation(const long64& cellID) const { VolumeManager volMan = LCDD::getInstance().volumeManager(); diff --git a/DDSegmentation/include/DDSegmentation/CartesianGrid.h b/DDSegmentation/include/DDSegmentation/CartesianGrid.h index 1a3a13212458668104f843b31dc8d7c9e534efd5..1df3494d5da72a961263c9e1fa8af4904cf971d0 100644 --- a/DDSegmentation/include/DDSegmentation/CartesianGrid.h +++ b/DDSegmentation/include/DDSegmentation/CartesianGrid.h @@ -20,13 +20,6 @@ public: protected: /// default constructor using an arbitrary type template <typename TYPE> CartesianGrid(TYPE cellEncoding); - /// default constructor using an existing decoder - CartesianGrid(BitField64* decoder); - - /// helper method to convert a bin number to a 1D position - double binToPosition(long64 bin, double cellSize, double ofset) const; - /// helper method to convert a 1D position to a cell ID - int positionToBin(double position, double cellSize, double offset) const; }; } /* namespace DDSegmentation */ diff --git a/DDSegmentation/include/DDSegmentation/CartesianGridXY.h b/DDSegmentation/include/DDSegmentation/CartesianGridXY.h index 42e1fd3ef4e1ea9b3e261d22af3f987da147dd45..52cd121e09670bd560ffbc878e2d7400166e6090 100644 --- a/DDSegmentation/include/DDSegmentation/CartesianGridXY.h +++ b/DDSegmentation/include/DDSegmentation/CartesianGridXY.h @@ -17,16 +17,13 @@ class CartesianGridXY: public CartesianGrid { public: /// default constructor using an arbitrary type template <typename TYPE> CartesianGridXY(TYPE cellEncoding, double gridSizeX = 1., double gridSizeY = 1., double offsetX = 0., - double offsetY = 0., std::string xField = "x", std::string yField = "y"); - /// default constructor using an existing decoder - CartesianGridXY(BitField64* decoder, double gridSizeX = 1., double gridSizeY = 1., double offsetX = 0., - double offsetY = 0., std::string xField = "x", std::string yField = "y"); + double offsetY = 0., const std::string& xField = "x", const std::string& yField = "y"); /// destructor virtual ~CartesianGridXY(); - /// determine the local position based on the cell ID - virtual std::vector<double> getLocalPosition(const long64& cellID) const; - /// determine the cell ID based on the local position + /// determine the position based on the cell ID + virtual std::vector<double> getPosition(const long64& cellID) const; + /// determine the cell ID based on the position virtual long64 getCellID(double x, double y, double z) const; /// access the grid size in X double getGridSizeX() const { @@ -69,11 +66,11 @@ public: _offsetY = offset; } /// set the field name used for X - void setFieldNameX(std::string name) { + void setFieldNameX(const std::string& name) { _xId = name; } /// set the field name used for Y - void setFieldNameY(std::string name) { + void setFieldNameY(const std::string& name) { _yId = name; } /// access the set of parameters for this segmentation diff --git a/DDSegmentation/include/DDSegmentation/CartesianGridXYZ.h b/DDSegmentation/include/DDSegmentation/CartesianGridXYZ.h index 8e9a3c2ed0faf25e53f6be164d0efc8bf0ad0547..981dd8f0eeff8e357cf819083507a2afbabbc8e5 100644 --- a/DDSegmentation/include/DDSegmentation/CartesianGridXYZ.h +++ b/DDSegmentation/include/DDSegmentation/CartesianGridXYZ.h @@ -17,18 +17,14 @@ class CartesianGridXYZ: public CartesianGridXY { public: /// default constructor using an arbitrary type template <typename TYPE> CartesianGridXYZ(TYPE cellEncoding, double gridSizeX = 1., double gridSizeY = 1., double gridSizeZ = 1., - double offsetX = 0., double offsetY = 0., double offsetZ = 0., std::string xField = "x", - std::string yField = "y", std::string zField = "z"); - /// default constructor using an existing decoder - CartesianGridXYZ(BitField64* decoder, double gridSizeX = 1., double gridSizeY = 1., double gridSizeZ = 1., double offsetX = - 0., double offsetY = 0., double offsetZ = 0., std::string xField = "x", std::string yField = "y", - std::string zField = "z"); + double offsetX = 0., double offsetY = 0., double offsetZ = 0., const std::string& xField = "x", + const std::string& yField = "y", const std::string& zField = "z"); /// destructor virtual ~CartesianGridXYZ(); - /// determine the local position based on the cell ID - virtual std::vector<double> getLocalPosition(const long64& cellID) const; - /// determine the cell ID based on the local position + /// determine the position based on the cell ID + virtual std::vector<double> getPosition(const long64& cellID) const; + /// determine the cell ID based on the position virtual long64 getCellID(double x, double y, double z) const; /// access the grid size in Z double getGridSizeZ() const { @@ -51,7 +47,7 @@ public: _offsetZ = offset; } /// set the field name used for Z - void setFieldNameZ(std::string name) { + void setFieldNameZ(const std::string& name) { _zId = name; } /// access the set of parameters for this segmentation diff --git a/DDSegmentation/include/DDSegmentation/CartesianGridXZ.h b/DDSegmentation/include/DDSegmentation/CartesianGridXZ.h new file mode 100644 index 0000000000000000000000000000000000000000..5e4c813496150b48545988b1959333819b8a6af2 --- /dev/null +++ b/DDSegmentation/include/DDSegmentation/CartesianGridXZ.h @@ -0,0 +1,96 @@ +/* + * CartesianGridXY.h + * + * Created on: Jun 28, 2013 + * Author: Christian Grefe, CERN + */ + +#ifndef DDSegmentation_CARTESIANGRIDXZ_H_ +#define DDSegmentation_CARTESIANGRIDXZ_H_ + +#include "DDSegmentation/CartesianGrid.h" + +namespace DD4hep { +namespace DDSegmentation { + +class CartesianGridXZ: public CartesianGrid { +public: + /// default constructor using an arbitrary type + template <typename TYPE> CartesianGridXZ(TYPE cellEncoding, double gridSizeX = 1., double gridSizeZ = 1., double offsetX = 0., + double offsetZ = 0., const std::string& xField = "x", const std::string& zField = "z"); + /// destructor + virtual ~CartesianGridXZ(); + + /// determine the local based on the cell ID + virtual std::vector<double> getPosition(const long64& cellID) const; + /// determine the cell ID based on the position + virtual long64 getCellID(double x, double y, double z) const; + /// access the grid size in X + double getGridSizeX() const { + return _gridSizeX; + } + /// access the grid size in Z + double getGridSizeZ() const { + return _gridSizeZ; + } + /// access the coordinate offset in X + double getOffsetX() const { + return _offsetX; + } + /// access the coordinate offset in Z + double getOffsetZ() const { + return _offsetZ; + } + /// access the field name used for X + std::string getFieldNameX() const { + return _xId; + } + /// access the field name used for Z + std::string getFieldNameZ() const { + return _zId; + } + /// set the grid size in X + void setGridSizeX(double cellSize) { + _gridSizeX = cellSize; + } + /// set the grid size in Z + void setGridSizeZ(double cellSize) { + _gridSizeZ = cellSize; + } + /// set the coordinate offset in X + void setOffsetX(double offset) { + _offsetX = offset; + } + /// set the coordinate offset in Z + void setOffsetZ(double offset) { + _offsetZ = offset; + } + /// set the field name used for X + void setFieldNameX(const std::string& name) { + _xId = name; + } + /// set the field name used for Y + void setFieldNameZ(const std::string& name) { + _zId = name; + } + /// access the set of parameters for this segmentation + Parameters parameters() const; + +protected: + /// the grid size in X + double _gridSizeX; + /// the coordinate offset in X + double _offsetX; + /// the grid size in Z + double _gridSizeZ; + /// the coordinate offset in Z + double _offsetZ; + /// the field name used for X + std::string _xId; + /// the field name used for Z + std::string _zId; +}; + +} /* namespace DDSegmentation */ +} /* namespace DD4hep */ +#endif /* DDSegmentation_CARTESIANGRIDXZ_H_ */ diff --git a/DDSegmentation/include/DDSegmentation/CylindricalSegmentation.h b/DDSegmentation/include/DDSegmentation/CylindricalSegmentation.h new file mode 100644 index 0000000000000000000000000000000000000000..f492d805d28c1e0b6d8d5e2c20246a7d84b340eb --- /dev/null +++ b/DDSegmentation/include/DDSegmentation/CylindricalSegmentation.h @@ -0,0 +1,50 @@ +/* + * CylindricalSegmentation.h + * + * Created on: Oct 31, 2013 + * Author: Christian Grefe, CERN + */ + +#ifndef DDSegmentation_CYLINDRICALSEGMENTATION_H_ +#define DDSegmentation_CYLINDRICALSEGMENTATION_H_ + +#include "DDSegmentation/Segmentation.h" + +#include <map> + +namespace DD4hep { +namespace DDSegmentation { + +class CylindricalSegmentation: public Segmentation { +public: + /// destructor + virtual ~CylindricalSegmentation(); + + /// determine the radius based on the cell ID + std::string getRadius(const long64& cellID) const; + /// access the field name used for layer + std::string getFieldNameLayer() const { + return _layerID; + } + /// set the field name used for the layer + void setFieldNameLayer(const std::string& name) { + _layerID = name; + } + /// set the radius of the given layer index + void setLayerRadius(int layerIndex, double radius) { + _layerRadiusMap[layerIndex] = radius; + } +protected: + /// default constructor using an arbitrary type + template <typename TYPE> CylindricalSegmentation(TYPE cellEncoding, const std::string& layerField = "layer"); + /// default constructor using an existing decoder + CylindricalSegmentation(BitField64* decoder); + /// store layer radii + std::map<int, double> _layerRadiusMap; + std::string _layerID; +}; + + +} /* namespace DDSegmentation */ +} /* namespace DD4hep */ +#endif /* DDSegmentation_CYLINDRICALSEGMENTATION_H_ */ diff --git a/DDSegmentation/include/DDSegmentation/ProjectiveCylinder.h b/DDSegmentation/include/DDSegmentation/ProjectiveCylinder.h new file mode 100644 index 0000000000000000000000000000000000000000..6b58a7060b849ac721092d7153369b37ee66ef31 --- /dev/null +++ b/DDSegmentation/include/DDSegmentation/ProjectiveCylinder.h @@ -0,0 +1,101 @@ +/* + * ProjectiveCylinder.h + * + * Created on: Oct 31, 2013 + * Author: Christian Grefe, CERN + */ + +#ifndef PROJECTIVECYLINDER_H_ +#define PROJECTIVECYLINDER_H_ + +#include "CylindricalSegmentation.h" + +namespace DD4hep { +namespace DDSegmentation { + +class ProjectiveCylinder: public CylindricalSegmentation { +public: + /// default constructor using an arbitrary type + template<typename TYPE> ProjectiveCylinder(TYPE cellEncoding, int thetaBins = 1, int phiBins = 1, + double offsetTheta = 0., double offsetPhi = 0., const std::string& thetaField = "theta", + const std::string& phiField = "phi", const std::string& layerField = "layer"); + /// destructor + virtual ~ProjectiveCylinder(); + + /// determine the position based on the cell ID + virtual std::vector<double> getPosition(const long64& cellID) const; + /// determine the cell ID based on the position + virtual long64 getCellID(double x, double y, double z) const; + /// determine the polar angle theta based on the cell ID + double getTheta(const long64& cellID) const; + /// determine the azimuthal angle phi based on the cell ID + double getPhi(const long64& cellID) const; + /// access the number of bins in theta + int getThetaBins() const { + return _thetaBins; + } + /// access the number of bins in theta + int getPhiBins() const { + return _phiBins; + } + /// access the coordinate offset in theta + double getOffsetTheta() const { + return _offsetTheta; + } + /// access the coordinate offset in phi + double getOffsetPhi() const { + return _offsetPhi; + } + /// access the field name used for theta + std::string getFieldNameTheta() const { + return _thetaID; + } + /// access the field name used for phi + std::string getFieldNamePhi() const { + return _phiID; + } + /// set the number of bins in theta + void setThetaBins(int bins) { + _thetaBins = bins; + } + /// set the number of bins in phi + void setPhiBins(int bins) { + _phiBins = bins; + } + /// set the coordinate offset in theta + void setOffsetTheta(double offset) { + _offsetTheta = offset; + } + /// set the coordinate offset in phi + void setOffsetPhi(double offset) { + _offsetPhi = offset; + } + /// set the field name used for theta + void setFieldNameTheta(const std::string& name) { + _thetaID = name; + } + /// set the field name used for phi + void setFieldNamePhi(const std::string& name) { + _phiID = name; + } + /// access the set of parameters for this segmentation + Parameters parameters() const; + +protected: + /// the number of bins in theta + int _thetaBins; + /// the number of bins in phi + int _phiBins; + /// the coordinate offset in theta + double _offsetTheta; + /// the coordinate offset in phi + double _offsetPhi; + /// the field name used for theta + std::string _thetaID; + /// the field name used for phi + std::string _phiID; +}; + +} /* namespace DDSegmentation */ +} /* namespace DD4hep */ +#endif /* PROJECTIVECYLINDER_H_ */ diff --git a/DDSegmentation/include/DDSegmentation/Segmentation.h b/DDSegmentation/include/DDSegmentation/Segmentation.h index 3a17412040492d9107b70495e5a01c7aa5da107b..da499f12047bd3766529d1a6aa643cef29a1795a 100644 --- a/DDSegmentation/include/DDSegmentation/Segmentation.h +++ b/DDSegmentation/include/DDSegmentation/Segmentation.h @@ -26,19 +26,25 @@ class Segmentation { public: /// default constructor using an arbitrary type template <typename TYPE> Segmentation(TYPE cellEncoding); - /// default constructor using an existing decoder - Segmentation(BitField64* decoder); /// destructor virtual ~Segmentation(); - /// determine the local position based on the cell ID - virtual std::vector<double> getLocalPosition(const long64& cellID) const = 0; - /// determine the cell ID based on the local position + /// determine the position based on the cell ID + virtual std::vector<double> getPosition(const long64& cellID) const = 0; + /// determine the cell ID based on the position virtual long64 getCellID(double x, double y, double z) const = 0; - /// determine the cell ID based on the local position - long64 getCellID(const std::vector<double>& localPosition) const; - /// determine the cell ID based on the local position - long64 getCellID(const double* localPosition) const; + /// determine the cell ID based on the position + long64 getCellID(const std::vector<double>& position) const; + /// determine the cell ID based on the position + long64 getCellID(const double* position) const; + /// check if it is a local segmentation + bool isLocal() const { + return _isLocal; + } + /// set if the segmentation is using local coordinates + void setLocal(bool isLocal) { + _isLocal = isLocal; + } /// access the encoding string std::string fieldDescription() const { return _decoder->fieldDescription(); @@ -63,6 +69,13 @@ protected: bool _ownsDecoder; /// the segmentation type std::string _type; + /// distinguish between local and global coordinate systems + bool _isLocal; + + /// helper method to convert a bin number to a 1D position + double binToPosition(long64 bin, double cellSize, double offset = 0.) const; + /// helper method to convert a 1D position to a cell ID + int positionToBin(double position, double cellSize, double offset = 0.) const; }; } /* namespace DDSegmentation */ diff --git a/DDSegmentation/include/DDSegmentation/SegmentationUtil.h b/DDSegmentation/include/DDSegmentation/SegmentationUtil.h new file mode 100644 index 0000000000000000000000000000000000000000..267b405706f331291645b92dc6d912329f9e600d --- /dev/null +++ b/DDSegmentation/include/DDSegmentation/SegmentationUtil.h @@ -0,0 +1,299 @@ +/* + * SegmentationUtil.h + * + * Created on: Oct 31, 2013 + * Author: Christian Grefe, CERN + */ + +#ifndef DDSegmentation_SEGMENTATIONUTIL_H_ +#define DDSegmentation_SEGMENTATIONUTIL_H_ + +#include <cmath> +#include <vector> + +namespace DD4hep { +namespace DDSegmentation { +namespace SegmentationUtil { + +/////////////////////////////////////////////////////////////////////// +/// Conventions /// +/// - x, y, z are the Cartesian coordinates /// +/// - r is the magnitude in the xy-plane /// +/// - rho is the magnitude /// +/////////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////// +/// Conversions from Cartesian to cylindrical/spherical coordinates /// +/////////////////////////////////////////////////////////////////////// + + +/// calculates the radius in xyz from Cartesian coordinates +template <typename TYPE> TYPE getRhoFromXYZ(TYPE x, TYPE y, TYPE z) { + return std::sqrt(x * x + y * y + z * z); +} +/// calculates the radius in xyz from Cartesian coordinates +template <typename TYPE> TYPE getRhoFromXYZ(std::vector<TYPE> position) { + return getRhoFromXYZ(position[0], position[1], position[2]); +} +/// calculates the radius in xyz from Cartesian coordinates +template <typename TYPE> TYPE getRhoFromXYZ(const std::vector<TYPE>& position) { + return getRhoFromXYZ(position[0], position[1], position[2]); +} +/// calculates the radius in xyz from Cartesian coordinates +template <typename TYPE> TYPE getRhoFromXYZ(TYPE* position) { + return getRhoFromXYZ(position[0], position[1], position[2]); +} +/// calculates the radius in xyz from Cartesian coordinates +template <typename TYPE> TYPE getRhoFromXYZ(const TYPE* position) { + return getRhoFromXYZ(position[0], position[1], position[2]); +} + + +/// calculates the radius in the xy-plane from Cartesian coordinates +template <typename TYPE> TYPE getRadiusFromXYZ(TYPE x, TYPE y, TYPE z) { + return std::sqrt(x * x + y * y); +} +/// calculates the radius in the xy-plane from Cartesian coordinates +template <typename TYPE> TYPE getRadiusFromXYZ(std::vector<TYPE> position) { + return getRadiusFromXYZ(position[0], position[1], position[2]); +} +/// calculates the radius in the xy-plane from Cartesian coordinates +template <typename TYPE> TYPE getRadiusFromXYZ(const std::vector<TYPE>& position) { + return getRadiusFromXYZ(position[0], position[1], position[2]); +} +/// calculates the radius in the xy-plane from Cartesian coordinates +template <typename TYPE> TYPE getRadiusFromXYZ(TYPE* position) { + return getRadiusFromXYZ(position[0], position[1], position[2]); +} +/// calculates the radius in the xy-plane from Cartesian coordinates +template <typename TYPE> TYPE getRadiusFromXYZ(const TYPE* position) { + return getRadiusFromXYZ(position[0], position[1], position[2]); +} + + +/// calculates the polar angle theta from Cartesian coordinates +template <typename TYPE> TYPE getThetaFromXYZ(TYPE x, TYPE y, TYPE z) { + TYPE r = getRadiusFromXYZ(x, y, z); + return std::acos(z / r); +} +/// calculates the polar angle theta from Cartesian coordinates +template <typename TYPE> TYPE getThetaFromXYZ(std::vector<TYPE> position) { + return getThetaFromXYZ(position[0], position[1], position[2]); +} +/// calculates the polar angle theta from Cartesian coordinates +template <typename TYPE> TYPE getThetaFromXYZ(const std::vector<TYPE>& position) { + return getThetaFromXYZ(position[0], position[1], position[2]); +} +/// calculates the polar angle theta from Cartesian coordinates +template <typename TYPE> TYPE getThetaFromXYZ(TYPE* position) { + return getThetaFromXYZ(position[0], position[1], position[2]); +} +/// calculates the polar angle theta from Cartesian coordinates +template <typename TYPE> TYPE getThetaFromXYZ(const TYPE* position) { + return getThetaFromXYZ(position[0], position[1], position[2]); +} + + +/// calculates the azimuthal angle phi from Cartesian coordinates +template <typename TYPE> TYPE getPhiFromXYZ(TYPE x, TYPE y, TYPE z) { + return std::atan2(y, x); +} +/// calculates the azimuthal angle phi from Cartesian coordinates +template <typename TYPE> TYPE getPhiFromXYZ(std::vector<TYPE> position) { + return getPhiFromXYZ(position[0], position[1], position[2]); +} +/// calculates the azimuthal angle phi from Cartesian coordinates +template <typename TYPE> TYPE getPhiFromXYZ(const std::vector<TYPE>& position) { + return getPhiFromXYZ(position[0], position[1], position[2]); +} +/// calculates the azimuthal angle phi from Cartesian coordinates +template <typename TYPE> TYPE getPhiFromXYZ(TYPE* position) { + return getPhiFromXYZ(position[0], position[1], position[2]); +} +/// calculates the azimuthal angle phi from Cartesian coordinates +template <typename TYPE> TYPE getPhiFromXYZ(const TYPE* position) { + return getPhiFromXYZ(position[0], position[1], position[2]); +} + + +///////////////////////////////////////////////////////////// +/// Conversions from cylindrical to Cartesian coordinates /// +///////////////////////////////////////////////////////////// + +/// calculates the Cartesian position from cylindrical coordinates +template <typename TYPE> std::vector<TYPE> getPositionFromRPhiZ(TYPE r, TYPE phi, TYPE z) { + std::vector<double> position(3); + position[0] = getXFromRPhiZ(r, phi, z); + position[1] = getYFromRPhiZ(r, phi, z); + position[2] = z; + return position; +} +/// calculates the Cartesian position from cylindrical coordinates +template <typename TYPE> std::vector<TYPE> getPositionFromRPhiZ(std::vector<TYPE> position) { + return getPositionFromRPhiZ(position[0], position[1], position[2]); +} +/// calculates the Cartesian position from cylindrical coordinates +template <typename TYPE> std::vector<TYPE> getPositionFromRPhiZ(const std::vector<TYPE>& position) { + return getPositionFromRPhiZ(position[0], position[1], position[2]); +} +/// calculates the Cartesian position from cylindrical coordinates +template <typename TYPE> std::vector<TYPE> getPositionFromRPhiZ(TYPE* position) { + return getPositionFromRPhiZ(position[0], position[1], position[2]); +} +/// calculates the Cartesian position from cylindrical coordinates +template <typename TYPE> std::vector<TYPE> getPositionFromRPhiZ(const TYPE* position) { + return getPositionFromRPhiZ(position[0], position[1], position[2]); +} + + +/// calculates the radius in xyz from cylindrical coordinates +template <typename TYPE> TYPE getRhoFromRPhiZ(TYPE r, TYPE phi, TYPE z) { + return std::sqrt(r * r + z * z); +} +/// calculates the radius in xyz from cylindrical coordinates +template <typename TYPE> TYPE getRhoFromRPhiZ(std::vector<TYPE> position) { + return getRhoFromRPhiZ(position[0], position[1], position[2]); +} +/// calculates the radius in xyz from cylindrical coordinates +template <typename TYPE> TYPE getRhoFromRPhiZ(const std::vector<TYPE>& position) { + return getRhoFromRPhiZ(position[0], position[1], position[2]); +} +/// calculates the radius in xyz from cylindrical coordinates +template <typename TYPE> TYPE getRhoFromRPhiZ(TYPE* position) { + return getRhoFromRPhiZ(position[0], position[1], position[2]); +} +/// calculates the radius in xyz from cylindrical coordinates +template <typename TYPE> TYPE getRhoFromRPhiZ(const TYPE* position) { + return getRhoFromRPhiZ(position[0], position[1], position[2]); +} + + +/// calculates x from cylindrical coordinates +template <typename TYPE> TYPE getXFromRPhiZ(TYPE r, TYPE phi, TYPE z) { + return r * std::cos(phi); +} +/// calculates x from cylindrical coordinates +template <typename TYPE> TYPE getXFromRPhiZ(std::vector<TYPE> position) { + return getXFromRPhiZ(position[0], position[1], position[2]); +} +/// calculates x from cylindrical coordinates +template <typename TYPE> TYPE getXFromRPhiZ(const std::vector<TYPE>& position) { + return getXFromRPhiZ(position[0], position[1], position[2]); +} +/// calculates x from cylindrical coordinates +template <typename TYPE> TYPE getXFromRPhiZ(TYPE* position) { + return getXFromRPhiZ(position[0], position[1], position[2]); +} +/// calculates x from cylindrical coordinates +template <typename TYPE> TYPE getXFromRPhiZ(const TYPE* position) { + return getXFromRPhiZ(position[0], position[1], position[2]); +} + + +/// calculates y from cylindrical coordinates +template <typename TYPE> TYPE getYFromRPhiZ(TYPE r, TYPE phi, TYPE z) { + return r * std::sin(phi); +} +/// calculates y from cylindrical coordinates +template <typename TYPE> TYPE getYFromRPhiZ(std::vector<TYPE> position) { + return getYFromRPhiZ(position[0], position[1], position[2]); +} +/// calculates y from cylindrical coordinates +template <typename TYPE> TYPE getYFromRPhiZ(const std::vector<TYPE>& position) { + return getYFromRPhiZ(position[0], position[1], position[2]); +} +/// calculates y from cylindrical coordinates +template <typename TYPE> TYPE getYFromRPhiZ(TYPE* position) { + return getYFromRPhiZ(position[0], position[1], position[2]); +} +/// calculates y from cylindrical coordinates +template <typename TYPE> TYPE getYFromRPhiZ(const TYPE* position) { + return getYFromRPhiZ(position[0], position[1], position[2]); +} + + +/// calculates the polar angle theta from cylindrical coordinates +template <typename TYPE> TYPE getThetaFromRPhiZ(TYPE r, TYPE phi, TYPE z) { + return r * std::atan(z / r); +} +/// calculates the polar angle theta from cylindrical coordinates +template <typename TYPE> TYPE getThetaFromRPhiZ(std::vector<TYPE> position) { + return getThetaFromRPhiZ(position[0], position[1], position[2]); +} +/// calculates the polar angle theta from cylindrical coordinates +template <typename TYPE> TYPE getThetaFromRPhiZ(const std::vector<TYPE>& position) { + return getThetaFromRPhiZ(position[0], position[1], position[2]); +} +/// calculates the polar angle theta from cylindrical coordinates +template <typename TYPE> TYPE getThetaFromRPhiZ(TYPE* position) { + return getThetaFromRPhiZ(position[0], position[1], position[2]); +} +/// calculates the polar angle theta from cylindrical coordinates +template <typename TYPE> TYPE getThetaFromRPhiZ(const TYPE* position) { + return getThetaFromRPhiZ(position[0], position[1], position[2]); +} + + +///////////////////////////////////////////////////////////// +/// Conversions from spherical to Cartesian coordinates /// +///////////////////////////////////////////////////////////// + +/// calculates the Cartesian position from spherical coordinates +template <typename TYPE> std::vector<TYPE> getPositionFromRThetaPhi(TYPE r, TYPE theta, TYPE phi) { + std::vector<double> position(3); + position[0] = r * std::cos(phi); + position[1] = r * std::sin(phi); + position[2] = r * std::tan(theta); + return position; +} +/// calculates the Cartesian position from spherical coordinates +template <typename TYPE> std::vector<TYPE> getPositionFromRThetaPhi(std::vector<TYPE> position) { + return getPositionFromRThetaPhi(position[0], position[1], position[2]); +} +/// calculates the Cartesian position from spherical coordinates +template <typename TYPE> std::vector<TYPE> getPositionFromRThetaPhi(const std::vector<TYPE>& position) { + return getPositionFromRThetaPhi(position[0], position[1], position[2]); +} +/// calculates the Cartesian position from spherical coordinates +template <typename TYPE> std::vector<TYPE> getPositionFromRThetaPhi(TYPE* position) { + return getPositionFromRThetaPhi(position[0], position[1], position[2]); +} +/// calculates the Cartesian position from spherical coordinates +template <typename TYPE> std::vector<TYPE> getPositionFromRThetaPhi(const TYPE* position) { + return getPositionFromRThetaPhi(position[0], position[1], position[2]); +} + + +/// calculates the Cartesian position from spherical coordinates +template <typename TYPE> std::vector<TYPE> getPositionFromRhoThetaPhi(TYPE rho, TYPE theta, TYPE phi) { + std::vector<double> position(3); + double r = rho * sin(theta); + position[0] = r * std::cos(phi); + position[1] = r * std::sin(phi); + position[2] = rho * std::cos(theta); + return position; +} +/// calculates the Cartesian position from spherical coordinates +template <typename TYPE> std::vector<TYPE> getPositionFromRhoThetaPhi(std::vector<TYPE> position) { + return getPositionFromRhoThetaPhi(position[0], position[1], position[2]); +} +/// calculates the Cartesian position from spherical coordinates +template <typename TYPE> std::vector<TYPE> getPositionFromRhoThetaPhi(const std::vector<TYPE>& position) { + return getPositionFromRhoThetaPhi(position[0], position[1], position[2]); +} +/// calculates the Cartesian position from spherical coordinates +template <typename TYPE> std::vector<TYPE> getPositionFromRhoThetaPhi(TYPE* position) { + return getPositionFromRhoThetaPhi(position[0], position[1], position[2]); +} +/// calculates the Cartesian position from spherical coordinates +template <typename TYPE> std::vector<TYPE> getPositionFromRhoThetaPhi(const TYPE* position) { + return getPositionFromRhoThetaPhi(position[0], position[1], position[2]); +} + + +} /* namespace SegmentationUtil */ +} /* namespace DDSegmentation */ +} /* namespace DD4hep */ + +#endif /* DDSegmentation_SEGMENTATIONUTIL_H_ */ diff --git a/DDSegmentation/src/CartesianGrid.cpp b/DDSegmentation/src/CartesianGrid.cpp index 1c137444f6444a91670df1108ac5803e892787c1..55b97022051fa0e7408518444d7c4930bcbff67e 100644 --- a/DDSegmentation/src/CartesianGrid.cpp +++ b/DDSegmentation/src/CartesianGrid.cpp @@ -7,8 +7,6 @@ #include "DDSegmentation/CartesianGrid.h" -#include <stdexcept> - namespace DD4hep { namespace DDSegmentation { @@ -33,7 +31,7 @@ template<> CartesianGrid::CartesianGrid(const char* cellEncoding) : } /// default constructor using an existing decoder -CartesianGrid::CartesianGrid(BitField64* decoder) : +template<> CartesianGrid::CartesianGrid(BitField64* decoder) : Segmentation(decoder) { } @@ -43,18 +41,5 @@ CartesianGrid::~CartesianGrid() { } -/// helper method to convert a bin number to a 1D position -double CartesianGrid::binToPosition(long64 bin, double cellSize, double offset) const { - return bin * cellSize + offset; -} - -/// helper method to convert a 1D position to a cell ID -int CartesianGrid::positionToBin(double position, double cellSize, double offset) const { - if (cellSize == 0.) { - throw std::runtime_error("Invalid cell size: 0.0"); - } - return int((position + 0.5 * cellSize - offset)/cellSize); -} - } /* namespace DDSegmentation */ } /* namespace DD4hep */ diff --git a/DDSegmentation/src/CartesianGridXY.cpp b/DDSegmentation/src/CartesianGridXY.cpp index 33ab1d5f416c3a76478d052b70c4ab1d83b773cc..33a8059ffd48a177c3021639f83f118e0a3ca029 100644 --- a/DDSegmentation/src/CartesianGridXY.cpp +++ b/DDSegmentation/src/CartesianGridXY.cpp @@ -16,7 +16,7 @@ using std::vector; /// default constructor using an encoding string template<> CartesianGridXY::CartesianGridXY(const string& cellEncoding, double gridSizeX, double gridSizeY, double offsetX, - double offsetY, string xField, string yField) : + double offsetY, const string& xField, const string& yField) : CartesianGrid(cellEncoding), _gridSizeX(gridSizeX), _gridSizeY(gridSizeY), _offsetX(offsetX), _offsetY(offsetY), _xId( xField), _yId(yField) { _type = "grid_xy"; @@ -24,7 +24,7 @@ template<> CartesianGridXY::CartesianGridXY(const string& cellEncoding, double g /// default constructor using an encoding string template<> CartesianGridXY::CartesianGridXY(string cellEncoding, double gridSizeX, double gridSizeY, double offsetX, - double offsetY, string xField, string yField) : + double offsetY, const string& xField, const string& yField) : CartesianGrid(cellEncoding), _gridSizeX(gridSizeX), _gridSizeY(gridSizeY), _offsetX(offsetX), _offsetY(offsetY), _xId( xField), _yId(yField) { _type = "grid_xy"; @@ -32,15 +32,15 @@ template<> CartesianGridXY::CartesianGridXY(string cellEncoding, double gridSize /// default constructor using an encoding string template<> CartesianGridXY::CartesianGridXY(const char* cellEncoding, double gridSizeX, double gridSizeY, double offsetX, - double offsetY, string xField, string yField) : + double offsetY, const string& xField, const string& yField) : CartesianGrid(cellEncoding), _gridSizeX(gridSizeX), _gridSizeY(gridSizeY), _offsetX(offsetX), _offsetY(offsetY), _xId( xField), _yId(yField) { _type = "grid_xy"; } /// default constructor using an existing decoder -CartesianGridXY::CartesianGridXY(BitField64* decoder, double gridSizeX, double gridSizeY, double offsetX, - double offsetY, string xField, string yField) : +template<> CartesianGridXY::CartesianGridXY(BitField64* decoder, double gridSizeX, double gridSizeY, double offsetX, + double offsetY, const string& xField, const string& yField) : CartesianGrid(decoder), _gridSizeX(gridSizeX), _gridSizeY(gridSizeY), _offsetX(offsetX), _offsetY(offsetY), _xId( xField), _yId(yField) { _type = "grid_xy"; @@ -51,8 +51,8 @@ CartesianGridXY::~CartesianGridXY() { } -/// determine the local position based on the cell ID -vector<double> CartesianGridXY::getLocalPosition(const long64& cellID) const { +/// determine the position based on the cell ID +vector<double> CartesianGridXY::getPosition(const long64& cellID) const { _decoder->setValue(cellID); vector<double> localPosition(3); localPosition[0] = binToPosition((*_decoder)[_xId].value(), _gridSizeX, _offsetX); @@ -61,7 +61,7 @@ vector<double> CartesianGridXY::getLocalPosition(const long64& cellID) const { return localPosition; } -/// determine the cell ID based on the local position +/// determine the cell ID based on the position long64 CartesianGridXY::getCellID(double x, double y, double z) const { _decoder->reset(); (*_decoder)[_xId] = positionToBin(x, _gridSizeX, _offsetX); @@ -74,6 +74,8 @@ Parameters CartesianGridXY::parameters() const { Parameters parameters; parameters.push_back(make_pair("grid_size_x", _gridSizeX)); parameters.push_back(make_pair("grid_size_y", _gridSizeY)); + parameters.push_back(make_pair("offset_x", _offsetX)); + parameters.push_back(make_pair("offset_y", _offsetY)); return parameters; } diff --git a/DDSegmentation/src/CartesianGridXYZ.cpp b/DDSegmentation/src/CartesianGridXYZ.cpp index 4a21e554d4806e67c87fbd7774e8d97e9bb8a3c4..393685b23ef9ac041ba6b8d440b62a95766befd5 100644 --- a/DDSegmentation/src/CartesianGridXYZ.cpp +++ b/DDSegmentation/src/CartesianGridXYZ.cpp @@ -16,7 +16,7 @@ using std::vector; /// default constructor using an encoding string template<> CartesianGridXYZ::CartesianGridXYZ(const string& cellEncoding, double gridSizeX, double gridSizeY, double gridSizeZ, - double offsetX, double offsetY, double offsetZ, string xField, string yField, string zField) : + double offsetX, double offsetY, double offsetZ, const string& xField, const string& yField, const string& zField) : CartesianGridXY(cellEncoding, gridSizeX, gridSizeY, offsetX, offsetY, xField, yField), _gridSizeZ(gridSizeZ), _offsetZ( offsetZ), _zId(zField) { _type = "grid_xyz"; @@ -24,7 +24,7 @@ template<> CartesianGridXYZ::CartesianGridXYZ(const string& cellEncoding, double /// default constructor using an encoding string template<> CartesianGridXYZ::CartesianGridXYZ(string cellEncoding, double gridSizeX, double gridSizeY, double gridSizeZ, - double offsetX, double offsetY, double offsetZ, string xField, string yField, string zField) : + double offsetX, double offsetY, double offsetZ, const string& xField, const string& yField, const string& zField) : CartesianGridXY(cellEncoding, gridSizeX, gridSizeY, offsetX, offsetY, xField, yField), _gridSizeZ(gridSizeZ), _offsetZ( offsetZ), _zId(zField) { _type = "grid_xyz"; @@ -32,15 +32,15 @@ template<> CartesianGridXYZ::CartesianGridXYZ(string cellEncoding, double gridSi /// default constructor using an encoding string template<> CartesianGridXYZ::CartesianGridXYZ(const char* cellEncoding, double gridSizeX, double gridSizeY, double gridSizeZ, - double offsetX, double offsetY, double offsetZ, string xField, string yField, string zField) : + double offsetX, double offsetY, double offsetZ, const string& xField, const string& yField, const string& zField) : CartesianGridXY(cellEncoding, gridSizeX, gridSizeY, offsetX, offsetY, xField, yField), _gridSizeZ(gridSizeZ), _offsetZ( offsetZ), _zId(zField) { _type = "grid_xyz"; } /// default constructor using an existing decoder -CartesianGridXYZ::CartesianGridXYZ(BitField64* decoder, double gridSizeX, double gridSizeY, double gridSizeZ, - double offsetX, double offsetY, double offsetZ, string xField, string yField, string zField) : +template<> CartesianGridXYZ::CartesianGridXYZ(BitField64* decoder, double gridSizeX, double gridSizeY, double gridSizeZ, + double offsetX, double offsetY, double offsetZ, const string& xField, const string& yField, const string& zField) : CartesianGridXY(decoder, gridSizeX, gridSizeY, offsetX, offsetY, xField, yField), _gridSizeZ(gridSizeZ), _offsetZ( offsetZ), _zId(zField) { _type = "grid_xyz"; @@ -51,8 +51,8 @@ CartesianGridXYZ::~CartesianGridXYZ() { } -/// determine the local position based on the cell ID -vector<double> CartesianGridXYZ::getLocalPosition(const long64& cellID) const { +/// determine the position based on the cell ID +vector<double> CartesianGridXYZ::getPosition(const long64& cellID) const { _decoder->setValue(cellID); vector<double> localPosition(3); localPosition[0] = binToPosition((*_decoder)[_xId].value(), _gridSizeX, _offsetX); @@ -61,7 +61,7 @@ vector<double> CartesianGridXYZ::getLocalPosition(const long64& cellID) const { return localPosition; } -/// determine the cell ID based on the local position +/// determine the cell ID based on the position long64 CartesianGridXYZ::getCellID(double x, double y, double z) const { _decoder->reset(); (*_decoder)[_xId] = positionToBin(x, _gridSizeX, _offsetX); @@ -76,6 +76,9 @@ Parameters CartesianGridXYZ::parameters() const { parameters.push_back(make_pair("grid_size_x", _gridSizeX)); parameters.push_back(make_pair("grid_size_y", _gridSizeY)); parameters.push_back(make_pair("grid_size_z", _gridSizeZ)); + parameters.push_back(make_pair("offset_x", _offsetX)); + parameters.push_back(make_pair("offset_y", _offsetY)); + parameters.push_back(make_pair("offset_z", _offsetZ)); return parameters; } diff --git a/DDSegmentation/src/CartesianGridXZ.cpp b/DDSegmentation/src/CartesianGridXZ.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8c46746b9276e20f6aad1c0e658f872b8ed4f407 --- /dev/null +++ b/DDSegmentation/src/CartesianGridXZ.cpp @@ -0,0 +1,83 @@ +/* + * CartesianGridXY.cpp + * + * Created on: Jun 28, 2013 + * Author: Christian Grefe, CERN + */ + +#include "DDSegmentation/CartesianGridXZ.h" + +namespace DD4hep { +namespace DDSegmentation { + +using std::make_pair; +using std::string; +using std::vector; + +/// default constructor using an encoding string +template<> CartesianGridXZ::CartesianGridXZ(const string& cellEncoding, double gridSizeX, double gridSizeZ, double offsetX, + double offsetZ, const string& xField, const string& zField) : + CartesianGrid(cellEncoding), _gridSizeX(gridSizeX), _gridSizeZ(gridSizeZ), _offsetX(offsetX), _offsetZ(offsetZ), _xId( + xField), _zId(zField) { + _type = "grid_xz"; +} + +/// default constructor using an encoding string +template<> CartesianGridXZ::CartesianGridXZ(string cellEncoding, double gridSizeX, double gridSizeZ, double offsetX, + double offsetZ, const string& xField, const string& zField) : + CartesianGrid(cellEncoding), _gridSizeX(gridSizeX), _gridSizeZ(gridSizeZ), _offsetX(offsetX), _offsetZ(offsetZ), _xId( + xField), _zId(zField) { + _type = "grid_xz"; +} + +/// default constructor using an encoding string +template<> CartesianGridXZ::CartesianGridXZ(const char* cellEncoding, double gridSizeX, double gridSizeZ, double offsetX, + double offsetZ, const string& xField, const string& zField) : + CartesianGrid(cellEncoding), _gridSizeX(gridSizeX), _gridSizeZ(gridSizeZ), _offsetX(offsetX), _offsetZ(offsetZ), _xId( + xField), _zId(zField) { + _type = "grid_xz"; +} + +/// default constructor using an existing decoder +template<> CartesianGridXZ::CartesianGridXZ(BitField64* decoder, double gridSizeX, double gridSizeZ, double offsetX, + double offsetZ, const string& xField, const string& zField) : + CartesianGrid(decoder), _gridSizeX(gridSizeX), _gridSizeZ(gridSizeZ), _offsetX(offsetX), _offsetZ(offsetZ), _xId( + xField), _zId(zField) { + _type = "grid_xz"; +} + +/// destructor +CartesianGridXZ::~CartesianGridXZ() { + +} + +/// determine the position based on the cell ID +vector<double> CartesianGridXZ::getPosition(const long64& cellID) const { + _decoder->setValue(cellID); + vector<double> localPosition(3); + localPosition[0] = binToPosition((*_decoder)[_xId].value(), _gridSizeX, _offsetX); + localPosition[1] = 0.; + localPosition[2] = binToPosition((*_decoder)[_zId].value(), _gridSizeZ, _offsetZ); + return localPosition; +} + +/// determine the cell ID based on the position +long64 CartesianGridXZ::getCellID(double x, double y, double z) const { + _decoder->reset(); + (*_decoder)[_xId] = positionToBin(x, _gridSizeX, _offsetX); + (*_decoder)[_zId] = positionToBin(z, _gridSizeZ, _offsetZ); + return _decoder->getValue(); +} + +/// access the set of parameters for this segmentation +Parameters CartesianGridXZ::parameters() const { + Parameters parameters; + parameters.push_back(make_pair("grid_size_x", _gridSizeX)); + parameters.push_back(make_pair("grid_size_z", _gridSizeZ)); + parameters.push_back(make_pair("offset_x", _offsetX)); + parameters.push_back(make_pair("offset_z", _offsetZ)); + return parameters; +} + +} /* namespace DDSegmentation */ +} /* namespace DD4hep */ diff --git a/DDSegmentation/src/CylindricalSegmentation.cpp b/DDSegmentation/src/CylindricalSegmentation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d3b16631996e03a5255949c7ab51670fe3d54feb --- /dev/null +++ b/DDSegmentation/src/CylindricalSegmentation.cpp @@ -0,0 +1,65 @@ +/* + * CylindricalSegmentation.cpp + * + * Created on: Oct 31, 2013 + * Author: Christian Grefe, CERN + */ + +#include "DDSegmentation/CylindricalSegmentation.h" + +#include <sstream> +#include <stdexcept> + +namespace DD4hep { +namespace DDSegmentation { + +using std::map; +using std::runtime_error; +using std::string; +using std::stringstream; + +/// default constructor using an encoding string +template<> CylindricalSegmentation::CylindricalSegmentation(const string& cellEncoding, const string& layerField) : + Segmentation(cellEncoding), _layerID(layerField) { + _isLocal = false; +} + +/// default constructor using an encoding string +template<> CylindricalSegmentation::CylindricalSegmentation(string cellEncoding, const string& layerField) : + Segmentation(cellEncoding), _layerID(layerField) { + _isLocal = false; +} + +/// default constructor using an encoding string +template<> CylindricalSegmentation::CylindricalSegmentation(const char* cellEncoding, const string& layerField) : + Segmentation(cellEncoding), _layerID(layerField) { + _isLocal = false; +} + +/// default constructor using an existing decoder +template<> CylindricalSegmentation::CylindricalSegmentation(BitField64* decoder, const string& layerField) : + Segmentation(decoder), _layerID(layerField) { + _isLocal = false; +} + + +/// destructor +CylindricalSegmentation::~CylindricalSegmentation() { + +} + +/// determine the radius based on the cell ID +string CylindricalSegmentation::getRadius(const long64& cellID) const { + _decoder->setValue(cellID); + int layer = (*_decoder)[_layerID]; + map<int, double>::const_iterator itMap = _layerRadiusMap.find(layer); + if (itMap == _layerRadiusMap.end()) { + stringstream message; + message << "getRadius(): Invalid layer index " << layer << " from cell ID " << cellID; + throw runtime_error(message.str()); + } + return itMap->second; +} + +} /* namespace DDSegmentation */ +} /* namespace DD4hep */ diff --git a/DDSegmentation/src/ProjectiveCylinder.cpp b/DDSegmentation/src/ProjectiveCylinder.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b5bacda6cae8b119b1a8dc08eee41a37d9fd122e --- /dev/null +++ b/DDSegmentation/src/ProjectiveCylinder.cpp @@ -0,0 +1,85 @@ +/* + * ProjectiveCylinder.cpp + * + * Created on: Oct 31, 2013 + * Author: Christian Grefe, CERN + */ + +#include "DDSegmentation/ProjectiveCylinder.h" +#include "DDSegmentation/SegmentationUtil.h" + +#define _USE_MATH_DEFINES +#include <cmath> + +namespace DD4hep { +namespace DDSegmentation { + +using std::string; +using SegmentationUtil::getPositionFromRThetaPhi; + +/// default constructor using an encoding string +template<> ProjectiveCylinder::ProjectiveCylinder(const string& cellEncoding, int thetaBins, int phiBins, + double offsetTheta, double offsetPhi, const string& thetaField, const string& phiField, + const string& layerField) : + CylindricalSegmentation(cellEncoding, layerField), _thetaBins(thetaBins), _phiBins(phiBins), _offsetTheta( + offsetTheta), _offsetPhi(offsetPhi), _thetaID(thetaField), _phiID(phiField) { + _type = "projective_cylinder"; +} + +/// default constructor using an encoding string +template<> ProjectiveCylinder::ProjectiveCylinder(string cellEncoding, int thetaBins, int phiBins, double offsetTheta, + double offsetPhi, const string& thetaField, const string& phiField, const string& layerField) : + CylindricalSegmentation(cellEncoding, layerField), _thetaBins(thetaBins), _phiBins(phiBins), _offsetTheta( + offsetTheta), _offsetPhi(offsetPhi), _thetaID(thetaField), _phiID(phiField) { + _type = "projective_cylinder"; +} + +/// default constructor using an encoding string +template<> ProjectiveCylinder::ProjectiveCylinder(const char* cellEncoding, int thetaBins, int phiBins, + double offsetTheta, double offsetPhi, const string& thetaField, const string& phiField, + const string& layerField) : + CylindricalSegmentation(cellEncoding, layerField), _thetaBins(thetaBins), _phiBins(phiBins), _offsetTheta( + offsetTheta), _offsetPhi(offsetPhi), _thetaID(thetaField), _phiID(phiField) { + _type = "projective_cylinder"; +} + +/// default constructor using an existing decoder +template<> ProjectiveCylinder::ProjectiveCylinder(BitField64* decoder, int thetaBins, int phiBins, double offsetTheta, + double offsetPhi, const string& thetaField, const string& phiField, const string& layerField) : + CylindricalSegmentation(decoder, layerField), _thetaBins(thetaBins), _phiBins(phiBins), _offsetTheta( + offsetTheta), _offsetPhi(offsetPhi), _thetaID(thetaField), _phiID(phiField) { + _type = "projective_cylinder"; +} + +/// destructor +ProjectiveCylinder::~ProjectiveCylinder() { + +} + +/// determine the local based on the cell ID +virtual std::vector<double> ProjectiveCylinder::getPosition(const long64& cellID) const { + double r = getRadius(cellID); + double theta = getTheta(cellID); + double phi = getPhi(cellID); + return getPositionFromRThetaPhi(r, theta, phi); +} + +/// determine the cell ID based on the position +virtual long64 ProjectiveCylinder::getCellID(double x, double y, double z) const { + // TODO + return 0; +} + +/// determine the polar angle theta based on the cell ID +double ProjectiveCylinder::getTheta(const long64& cellID) const { + int thetaIndex = (*_decoder)[_thetaID].value(); + return M_PI * ((double) thetaIndex + 0.5) / (double) _thetaBins; +} +/// determine the azimuthal angle phi based on the cell ID +double ProjectiveCylinder::getPhi(const long64& cellID) const { + int phiIndex = (*_decoder)[_phiID].value(); + return 2. * M_PI * ((double) phiIndex + 0.5) / (double) _phiBins; +} + +} /* namespace DDSegmentation */ +} /* namespace DD4hep */ diff --git a/DDSegmentation/src/Segmentation.cpp b/DDSegmentation/src/Segmentation.cpp index 5efba3ac61510288bfafd072753ce39e12485ba2..0604f1136fdffe2244d79324afd1123689397136 100644 --- a/DDSegmentation/src/Segmentation.cpp +++ b/DDSegmentation/src/Segmentation.cpp @@ -20,6 +20,7 @@ template<> Segmentation::Segmentation(std::string cellEncoding) { _decoder = new BitField64(cellEncoding); _ownsDecoder = true; _type = "segmentation"; + _isLocal = true; } /// default constructor using an encoding string @@ -27,6 +28,7 @@ template<> Segmentation::Segmentation(const std::string& cellEncoding) { _decoder = new BitField64(cellEncoding); _ownsDecoder = true; _type = "segmentation"; + _isLocal = true; } /// default constructor using an encoding string @@ -34,13 +36,15 @@ template<> Segmentation::Segmentation(const char* cellEncoding) { _decoder = new BitField64(cellEncoding); _ownsDecoder = true; _type = "segmentation"; + _isLocal = true; } /// default constructor using an existing decoder -Segmentation::Segmentation(BitField64* decoder) { +template<> Segmentation::Segmentation(BitField64* decoder) { _decoder = decoder; _ownsDecoder = false; _type = "segmentation"; + _isLocal = true; } /// destructor @@ -50,17 +54,17 @@ Segmentation::~Segmentation() { } } -/// determine the cell ID based on the local position -long64 Segmentation::getCellID(const vector<double>& localPosition) const { - if (localPosition.size() != 3) { +/// determine the cell ID based on the position +long64 Segmentation::getCellID(const vector<double>& position) const { + if (position.size() != 3) { throw std::runtime_error("Vector size has to be 3!"); } - return getCellID(localPosition[0], localPosition[1], localPosition[2]); + return getCellID(position[0], position[1], position[2]); } -/// determine the cell ID based on the local position -long64 Segmentation::getCellID(const double* localPosition) const { - return getCellID(localPosition[0], localPosition[1], localPosition[2]); +/// determine the cell ID based on the position +long64 Segmentation::getCellID(const double* position) const { + return getCellID(position[0], position[1], position[2]); } /// set the underlying decoder @@ -77,5 +81,18 @@ Parameters Segmentation::parameters() const { return Parameters(); } +/// helper method to convert a bin number to a 1D position +double CartesianGrid::binToPosition(long64 bin, double cellSize, double offset) const { + return bin * cellSize + offset; +} + +/// helper method to convert a 1D position to a cell ID +int CartesianGrid::positionToBin(double position, double cellSize, double offset) const { + if (cellSize == 0.) { + throw std::runtime_error("Invalid cell size: 0.0"); + } + return int((position + 0.5 * cellSize - offset)/cellSize); +} + } /* namespace DDSegmentation */ } /* namespace DD4hep */ diff --git a/examples/Segmentation/SegmentationTest.cpp b/examples/Segmentation/SegmentationTest.cpp index 5777b8680fe6f3f15e9b3ea0b579f662aa9097d3..e4bea2ce1d5599a7745ad24c55f8d18d58a01375 100644 --- a/examples/Segmentation/SegmentationTest.cpp +++ b/examples/Segmentation/SegmentationTest.cpp @@ -31,9 +31,7 @@ int main(int argc, char** argv) { idEncoder["x"] = 13; idEncoder["y"] = -10; long64 cellID = idEncoder.getValue(); - Position lp = ro.getLocalPosition(cellID); Position gp = ro.getPosition(cellID); - std::cout << "Local position: " << lp.x() << ", " << lp.y() << ", " << lp.z() << std::endl; std::cout << "Global position: " << gp.x() << ", " << gp.y() << ", " << gp.z() << std::endl; return 0;