diff --git a/DDCore/include/DD4hep/Primitives.h b/DDCore/include/DD4hep/Primitives.h index 239b7a7a34a499d9b8f907bf7b870d50c64e7ad3..518580a62ddf4f7247e293c057917164a2c59fc7 100644 --- a/DDCore/include/DD4hep/Primitives.h +++ b/DDCore/include/DD4hep/Primitives.h @@ -9,6 +9,8 @@ #ifndef DD4HEP_DD4HEP_PRIMITIVES_H #define DD4HEP_DD4HEP_PRIMITIVES_H +#include "DDSegmentation/Segmentation.h" + // C/C++ include files #include <algorithm> @@ -18,7 +20,8 @@ namespace DD4hep { // Put here global basic type definitions derived from primitive types of the DD4hep namespace - typedef unsigned long long int VolumeID; + typedef DDSegmentation::CellID CellID; + typedef DDSegmentation::VolumeID VolumeID; /// Helper to delete objects from heap and reset the pointer. Saves many many lines of code template <typename T> inline void deletePtr(T*& p) { diff --git a/DDCore/include/DD4hep/Segmentations.h b/DDCore/include/DD4hep/Segmentations.h index ccc86f11093118118adb4563cdec8488ceb9d020..ecc7f3dd92e42f1ce0925745cc2d410cd1f84314 100644 --- a/DDCore/include/DD4hep/Segmentations.h +++ b/DDCore/include/DD4hep/Segmentations.h @@ -54,9 +54,9 @@ namespace DD4hep { /// Flag to use segmentation for hit positioning unsigned char useForHitPosition; /// determine the local position based on the cell ID - DDSegmentation::Position position(const long64& cellID) const; + DDSegmentation::Vector3D position(const long64& cellID) const; /// determine the cell ID based on the local position - long64 cellID(const DDSegmentation::Position& localPosition, const DDSegmentation::Position& globalPosition, const long64& volumeID) const; + long64 cellID(const DDSegmentation::Vector3D& localPosition, const DDSegmentation::Vector3D& globalPosition, const long64& volumeID) const; /// Standard constructor Object(BaseSegmentation* s = 0); /// Default destructor diff --git a/DDCore/src/Segmentations.cpp b/DDCore/src/Segmentations.cpp index 7f390ccf389de51a99bbe8fbd9db48f251b4753d..962e5c7cfc57e51aee6cd7568fb73403becbe144 100644 --- a/DDCore/src/Segmentations.cpp +++ b/DDCore/src/Segmentations.cpp @@ -34,12 +34,12 @@ Segmentation::Object::~Object() { } /// determine the local position based on the cell ID -DDSegmentation::Position Segmentation::Object::position(const long64& cellID) const { +DDSegmentation::Vector3D Segmentation::Object::position(const long64& cellID) const { return segmentation->position(cellID); } /// determine the cell ID based on the local position -long64 Segmentation::Object::cellID(const DDSegmentation::Position& localPosition, const DDSegmentation::Position& globalPosition, const long64& volumeID) const { +long64 Segmentation::Object::cellID(const DDSegmentation::Vector3D& localPosition, const DDSegmentation::Vector3D& globalPosition, const long64& volumeID) const { return segmentation->cellID(localPosition, globalPosition, volumeID); } diff --git a/DDSegmentation/include/DDSegmentation/CartesianGridXY.h b/DDSegmentation/include/DDSegmentation/CartesianGridXY.h index 5e470e1165f76876b348bd0683b71e1a9efa4adc..e8adf981b7be38e939e732bf930a612495c0d8b9 100644 --- a/DDSegmentation/include/DDSegmentation/CartesianGridXY.h +++ b/DDSegmentation/include/DDSegmentation/CartesianGridXY.h @@ -21,9 +21,9 @@ public: virtual ~CartesianGridXY(); /// determine the position based on the cell ID - virtual Position position(const CellID& cellID) const; + virtual Vector3D position(const CellID& cellID) const; /// determine the cell ID based on the position - virtual CellID cellID(const Position& localPosition, const Position& globalPosition, const VolumeID& volumeID) const; + virtual CellID cellID(const Vector3D& localPosition, const Vector3D& globalPosition, const VolumeID& volumeID) const; /// access the grid size in X double gridSizeX() const { return _gridSizeX; diff --git a/DDSegmentation/include/DDSegmentation/CartesianGridXYZ.h b/DDSegmentation/include/DDSegmentation/CartesianGridXYZ.h index b28840df31811be5dc1cccf31d4caed6e8f3ce89..2365dd4ec22e5f2c3266228e56613fb1f788bedb 100644 --- a/DDSegmentation/include/DDSegmentation/CartesianGridXYZ.h +++ b/DDSegmentation/include/DDSegmentation/CartesianGridXYZ.h @@ -21,9 +21,9 @@ public: virtual ~CartesianGridXYZ(); /// determine the position based on the cell ID - virtual Position position(const CellID& cellID) const; + virtual Vector3D position(const CellID& cellID) const; /// determine the cell ID based on the position - virtual CellID cellID(const Position& localPosition, const Position& globalPosition, const VolumeID& volumeID) const; + virtual CellID cellID(const Vector3D& localPosition, const Vector3D& globalPosition, const VolumeID& volumeID) const; /// access the grid size in Z double gridSizeZ() const { return _gridSizeZ; diff --git a/DDSegmentation/include/DDSegmentation/CartesianGridXZ.h b/DDSegmentation/include/DDSegmentation/CartesianGridXZ.h index 02ab684ef5e1857804198c9d382b4117dcfcd417..d0febe4e59004873b194cf926fd1350d93989414 100644 --- a/DDSegmentation/include/DDSegmentation/CartesianGridXZ.h +++ b/DDSegmentation/include/DDSegmentation/CartesianGridXZ.h @@ -21,9 +21,9 @@ public: virtual ~CartesianGridXZ(); /// determine the local based on the cell ID - virtual Position position(const CellID& cellID) const; + virtual Vector3D position(const CellID& cellID) const; /// determine the cell ID based on the position - virtual CellID cellID(const Position& localPosition, const Position& globalPosition, const VolumeID& volumeID) const; + virtual CellID cellID(const Vector3D& localPosition, const Vector3D& globalPosition, const VolumeID& volumeID) const; /// access the grid size in X double gridSizeX() const { return _gridSizeX; diff --git a/DDSegmentation/include/DDSegmentation/ProjectiveCylinder.h b/DDSegmentation/include/DDSegmentation/ProjectiveCylinder.h index f2c61bae838f27bb04b8324870becacc03e9bcbb..56e5447efb3b2bc3311e27f4af913e791d3ea5ac 100644 --- a/DDSegmentation/include/DDSegmentation/ProjectiveCylinder.h +++ b/DDSegmentation/include/DDSegmentation/ProjectiveCylinder.h @@ -21,9 +21,9 @@ public: virtual ~ProjectiveCylinder(); /// determine the position based on the cell ID - virtual Position position(const CellID& cellID) const; + virtual Vector3D position(const CellID& cellID) const; /// determine the cell ID based on the position - virtual CellID cellID(const Position& localPosition, const Position& globalPosition, const VolumeID& volumeID) const; + virtual CellID cellID(const Vector3D& localPosition, const Vector3D& globalPosition, const VolumeID& volumeID) const; /// determine the polar angle theta based on the cell ID double theta(const long64& cellID) const; /// determine the azimuthal angle phi based on the cell ID diff --git a/DDSegmentation/include/DDSegmentation/Segmentation.h b/DDSegmentation/include/DDSegmentation/Segmentation.h index 84f477bb156c5f19115f336c8fc4b20b83c1c325..08fade05ab99c365a5e9b5b081b373a38753e96e 100644 --- a/DDSegmentation/include/DDSegmentation/Segmentation.h +++ b/DDSegmentation/include/DDSegmentation/Segmentation.h @@ -27,6 +27,10 @@ typedef TypedSegmentationParameter<int>* IntParameter; typedef TypedSegmentationParameter<float>* FloatParameter; typedef TypedSegmentationParameter<double>* DoubleParameter; typedef TypedSegmentationParameter<std::string>* StringParameter; +typedef TypedSegmentationParameter<std::vector<int> >* IntVecParameter; +typedef TypedSegmentationParameter<std::vector<float> >* FloatVecParameter; +typedef TypedSegmentationParameter<std::vector<double> >* DoubleVecParameter; +typedef TypedSegmentationParameter<std::vector<std::string> >* StringVecParameter; typedef SegmentationParameter::UnitType UnitType; /// Useful typedefs to differentiate cell IDs and volume IDs @@ -34,13 +38,13 @@ typedef long long int CellID; typedef long long int VolumeID; /// Simple container for a physics vector -struct Position { +struct Vector3D { /// Default constructor - Position(double x = 0., double y = 0., double z = 0.) : + Vector3D(double x = 0., double y = 0., double z = 0.) : X(x), Y(y), Z(z) { } /// Constructor using a foreign vector class. Requires methods x(), y() and z() - template<typename T> Position(const T& v) { + template<typename T> Vector3D(const T& v) { X = v.x(); Y = v.y(); Z = v.Z(); @@ -67,9 +71,9 @@ public: virtual ~Segmentation(); /// Determine the local position based on the cell ID - virtual Position position(const CellID& cellID) const = 0; + virtual Vector3D position(const CellID& cellID) const = 0; /// Determine the cell ID based on the position - virtual CellID cellID(const Position& localPosition, const Position& globalPosition, + virtual CellID cellID(const Vector3D& localPosition, const Vector3D& globalPosition, const VolumeID& volumeID) const = 0; /// Determine the volume ID from the full cell ID by removing all local fields virtual VolumeID volumeID(const CellID& cellID) const; @@ -116,8 +120,10 @@ protected: /// Add a parameter to this segmentation. Used by derived classes to define their parameters template<typename TYPE> void registerParameter(const std::string& name, const std::string& description, - TYPE& parameter, const TYPE& defaultValue, UnitType unitType = SegmentationParameter::NoUnit, bool isOptional = false) { - _parameters[name] = new TypedSegmentationParameter<TYPE>(name, description, parameter, defaultValue, unitType, isOptional); + TYPE& parameter, const TYPE& defaultValue, UnitType unitType = SegmentationParameter::NoUnit, + bool isOptional = false) { + _parameters[name] = new TypedSegmentationParameter<TYPE>(name, description, parameter, defaultValue, unitType, + isOptional); } /// Add a cell identifier to this segmentation. Used by derived classes to define their required identifiers void registerIdentifier(const std::string& name, const std::string& description, std::string& identifier, diff --git a/DDSegmentation/include/DDSegmentation/SegmentationParameter.h b/DDSegmentation/include/DDSegmentation/SegmentationParameter.h index 099fbdf9269047d2805743b171a6e51cab20d25e..d435ecb02ae0939db924c7b5be79eaf99173a280 100644 --- a/DDSegmentation/include/DDSegmentation/SegmentationParameter.h +++ b/DDSegmentation/include/DDSegmentation/SegmentationParameter.h @@ -13,50 +13,81 @@ #include <sstream> #include <string> #include <typeinfo> +#include <vector> namespace DD4hep { namespace DDSegmentation { /// Helper class to extract type names -template <typename TYPE> struct TypeName { +template<typename TYPE> struct TypeName { static const char* name() { return typeid(TYPE).name(); } }; /// Specialization for int type -template <> struct TypeName<int> { +template<> struct TypeName<int> { static const char* name() { return "int"; } }; /// Specialization for float type -template <> struct TypeName<float> { +template<> struct TypeName<float> { static const char* name() { return "float"; } }; /// Specialization for double type -template <> struct TypeName<double> { +template<> struct TypeName<double> { static const char* name() { return "double"; } }; /// Specialization for string type -template <> struct TypeName<std::string> { +template<> struct TypeName<std::string> { static const char* name() { return "string"; } }; +/// Specialization for int vector type +template<> struct TypeName<std::vector<int> > { + static const char* name() { + return "intvec"; + } +}; + +/// Specialization for float vector type +template<> struct TypeName<std::vector<float> > { + static const char* name() { + return "floatvec"; + } +}; + +/// Specialization for double vector type +template<> struct TypeName<std::vector<double> > { + static const char* name() { + return "doublevec"; + } +}; + +/// Specialization for string vector type +template<> struct TypeName<std::vector<std::string> > { + static const char* name() { + return "stringvec"; + } +}; + /// Class to hold a segmentation parameter with its description class SegmentationParameter { public: /// Defines the parameter unit type (useful to convert to default set of units) - enum UnitType {NoUnit, LengthUnit, AngleUnit}; + enum UnitType { + NoUnit, LengthUnit, AngleUnit + }; /// Destructor virtual ~SegmentationParameter() { } @@ -95,7 +126,8 @@ public: } protected: /// Default constructor used by derived classes - SegmentationParameter(const std::string& name, const std::string& description, UnitType unitType = NoUnit, bool isOptional = false) : + SegmentationParameter(const std::string& name, const std::string& description, UnitType unitType = NoUnit, + bool isOptional = false) : _name(name), _description(description), _unitType(unitType), _isOptional(isOptional) { } /// The parameter name @@ -112,7 +144,8 @@ template<typename TYPE> class TypedSegmentationParameter: public SegmentationPar public: /// Default constructor TypedSegmentationParameter(const std::string& name, const std::string& description, TYPE& value, - const TYPE& defaultValue, SegmentationParameter::UnitType unitType = SegmentationParameter::NoUnit, bool isOptional = false) : + const TYPE& defaultValue, SegmentationParameter::UnitType unitType = SegmentationParameter::NoUnit, + bool isOptional = false) : SegmentationParameter(name, description, unitType, isOptional), _value(value), _defaultValue(defaultValue) { _value = defaultValue; } @@ -163,6 +196,91 @@ protected: TYPE _defaultValue; }; +template<typename TYPE> class TypedSegmentationParameter<std::vector<TYPE> > : public SegmentationParameter { +public: + /// Default constructor + TypedSegmentationParameter(const std::string& name, const std::string& description, std::vector<TYPE>& value, + const std::vector<TYPE>& defaultValue, SegmentationParameter::UnitType unitType = + SegmentationParameter::NoUnit, bool isOptional = false) : + SegmentationParameter(name, description, unitType, isOptional), _value(value), _defaultValue(defaultValue) { + _value = defaultValue; + } + + /// Access to the parameter value + const std::vector<TYPE>& typedValue() const { + return _value; + } + + /// Set the parameter value + void setTypedValue(const std::vector<TYPE>& value) { + _value = value; + } + + /// Access to the parameter default value + const std::vector<TYPE>& typedDefaultValue() const { + return _defaultValue; + } + + /// Access to the parameter type + std::string type() const { + std::stringstream s; + s << TypeName<TYPE>::name() << "Vec"; + return s.str() ; + } + + /// Access to the parameter value in string representation + std::string value() const { + std::stringstream s; + typename std::vector<TYPE>::const_iterator it = _value.begin(); + for (; it != _value.end(); ++it) { + s << *it; + s << " "; + } + return s.str(); + } + + /// Set the parameter value in string representation + void setValue(const std::string& value) { + std::vector<std::string> elements = splitString(value); + _value.clear(); + for (std::vector<std::string>::const_iterator it = elements.begin(); it != elements.end(); ++it) { + if (not it->empty()) { + TYPE entry; + std::stringstream s; + s << *it; + s >> entry; + _value.push_back(entry); + } + } + } + + /// Access to the parameter default value in string representation + std::string defaultValue() const { + std::stringstream s; + typename std::vector<TYPE>::const_iterator it = _defaultValue.begin(); + for (; it != _defaultValue.end(); ++it) { + s << *it; + s << " "; + } + return s.str(); + } + +protected: + std::vector<TYPE>& _value; + std::vector<TYPE> _defaultValue; + + /// Helper method to split string into tokens + std::vector<std::string> splitString(const std::string& s, char delimiter = ' ') { + std::vector<std::string> elements; + std::stringstream ss(s); + std::string item; + while (std::getline(ss, item, delimiter)) { + elements.push_back(item); + } + return elements; + } +}; + } /* namespace DDSegmentation */ } /* namespace DD4hep */ #endif /* DDSegmentation_SEGMENTATIONPARAMETER_H_ */ diff --git a/DDSegmentation/include/DDSegmentation/SegmentationUtil.h b/DDSegmentation/include/DDSegmentation/SegmentationUtil.h index a310a7f449a39d0522dcd61053919ad319e33aa1..5f8798b2c0cfd1d9eb9d47031ebcaf072c3ba903 100644 --- a/DDSegmentation/include/DDSegmentation/SegmentationUtil.h +++ b/DDSegmentation/include/DDSegmentation/SegmentationUtil.h @@ -29,22 +29,22 @@ namespace Util { /// calculates the radius in xyz from Cartesian coordinates -double magFromXYZ(const Position& position) { +double magFromXYZ(const Vector3D& position) { return std::sqrt(position.X * position.X + position.Y * position.Y + position.Z * position.Z); } /// calculates the radius in the xy-plane from Cartesian coordinates -double radiusFromXYZ(const Position& position) { +double radiusFromXYZ(const Vector3D& position) { return std::sqrt(position.X * position.X + position.Y * position.Y); } /// calculates the polar angle theta from Cartesian coordinates -double thetaFromXYZ(const Position& position) { +double thetaFromXYZ(const Vector3D& position) { return std::acos(position.Z / radiusFromXYZ(position)); } /// calculates the azimuthal angle phi from Cartesian coordinates -double phiFromXYZ(const Position& position) { +double phiFromXYZ(const Vector3D& position) { return std::atan2(position.Y, position.X); } @@ -53,8 +53,8 @@ double phiFromXYZ(const Position& position) { ///////////////////////////////////////////////////////////// /// calculates the Cartesian position from cylindrical coordinates -Position positionFromRPhiZ(double r, double phi, double z) { - return Position(r * std::cos(phi), r * std::sin(phi), z); +Vector3D positionFromRPhiZ(double r, double phi, double z) { + return Vector3D(r * std::cos(phi), r * std::sin(phi), z); } /// calculates the radius in xyz from cylindrical coordinates @@ -82,14 +82,14 @@ double thetaFromRPhiZ(double r, double phi, double z) { ///////////////////////////////////////////////////////////// /// calculates the Cartesian position from spherical coordinates -Position positionFromRThetaPhi(double r, double theta, double phi) { - return Position(r * std::cos(phi), r * std::sin(phi), r * std::tan(theta)); +Vector3D positionFromRThetaPhi(double r, double theta, double phi) { + return Vector3D(r * std::cos(phi), r * std::sin(phi), r * std::tan(theta)); } /// calculates the Cartesian position from spherical coordinates -Position positionFromMagThetaPhi(double mag, double theta, double phi) { +Vector3D positionFromMagThetaPhi(double mag, double theta, double phi) { double r = mag * sin(theta); - return Position(r * std::cos(phi), r * std::sin(phi), mag * std::cos(theta)); + return Vector3D(r * std::cos(phi), r * std::sin(phi), mag * std::cos(theta)); } } /* namespace Util */ diff --git a/DDSegmentation/include/DDSegmentation/TiledLayerSegmentation.h b/DDSegmentation/include/DDSegmentation/TiledLayerSegmentation.h new file mode 100644 index 0000000000000000000000000000000000000000..94aed501b04ac7775d291ba218cd1a5710b26d21 --- /dev/null +++ b/DDSegmentation/include/DDSegmentation/TiledLayerSegmentation.h @@ -0,0 +1,116 @@ +/* + * TiledLayerSegmentation.h + * + * Created on: Mar 10, 2014 + * Author: cgrefe + */ + +#ifndef DDSegmentation_TILEDLAYERSEGMENTATION_H_ +#define DDSegmentation_TILEDLAYERSEGMENTATION_H_ + +#include "DDSegmentation/Segmentation.h" + +// C/C++ includes +#include <string> +#include <vector> + +namespace DD4hep { +namespace DDSegmentation { + +class TiledLayerSegmentation: public Segmentation { +public: + /// Helper class to store x and y dimensions of a layer + struct LayerDimensions { + LayerDimensions(double x = 1., double y = 1.) : + x(x), y(y) {} + double x, y; + }; + + /// Default constructor passing the encoding string + TiledLayerSegmentation(const std::string& cellEncoding = ""); + /// destructor + virtual ~TiledLayerSegmentation(); + + /// 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 default grid size in X + double gridSizeX() const { + return _gridSizeX; + } + /// access the default grid size in Y + double gridSizeY() const { + return _gridSizeY; + } + + /// access the actual grid size in X for a given layer + double layerGridSizeX(int layerIndex) const; + /// access the actual grid size in Y for a given layer + double layerGridSizeY(int layerIndex) const; + + /// access the encoding field name used for X + const std::string& identifierX() const { + return _identifierX; + } + /// access the encoding field name used for Y + const std::string& identifierY() const { + return _identifierY; + } + /// access the encoding field name used for Y + const std::string& identifierLayer() const { + return _identifierLayer; + } + + /// access to the dimensions of the given layer + LayerDimensions layerDimensions(int layerIndex) const; + + /// set the default grid size in X + void setGridSizeX(double cellSize) { + _gridSizeX = cellSize; + } + /// set the default grid size in Y + void setGridSizeY(double cellSize) { + _gridSizeY = cellSize; + } + + /// set the encoding field name used for X + void setIdentifierX(const std::string& name) { + _identifierX = name; + } + /// set the encoding field name used for Y + void setIdentifierY(const std::string& name) { + _identifierY = name; + } + /// set the encoding field name used for layer + void setIdentifierLayer(const std::string& name) { + _identifierLayer = name; + } + + /// set the dimensions of the given layer + void setLayerDimensions(int layerIndex, double x, double y); + + + +protected: + double _gridSizeX; /// default grid size in X + double _gridSizeY; /// default grid size in Y + std::string _identifierX; /// encoding field used for X + std::string _identifierY; /// encoding field used for Y + std::string _identifierLayer; /// encoding field used for the layer + std::vector<int> _layerIndices; /// list of valid layer identifiers + std::vector<double> _layerDimensionsX; /// list of layer x dimensions + std::vector<double> _layerDimensionsY; /// list of layer y dimensions + + /// helper method to calculate optimal cell size based on total size + static double calculateOptimalCellSize(double nominalCellSize, double totalSize); + /// helper method to calculate offset of bin 0 based on the total size + static double calculateOffset(double cellSize, double totalSize); +}; + +} /* namespace DDSegmentation */ +} /* namespace DD4hep */ + +#endif /* TILEDLAYERSEGMENTATION_H_ */ diff --git a/DDSegmentation/src/CartesianGridXY.cpp b/DDSegmentation/src/CartesianGridXY.cpp index fef07f52e5349b17b248ae54c265475f6312521d..d8e5c3b0b0e4d084ea46563670cba33979f5d873 100644 --- a/DDSegmentation/src/CartesianGridXY.cpp +++ b/DDSegmentation/src/CartesianGridXY.cpp @@ -34,16 +34,16 @@ CartesianGridXY::~CartesianGridXY() { } /// determine the position based on the cell ID -Position CartesianGridXY::position(const CellID& cellID) const { +Vector3D CartesianGridXY::position(const CellID& cellID) const { _decoder->setValue(cellID); - Position position; + Vector3D position; position.X = binToPosition((*_decoder)[_xId].value(), _gridSizeX, _offsetX); position.Y = binToPosition((*_decoder)[_yId].value(), _gridSizeY, _offsetY); return position; } /// determine the cell ID based on the position -CellID CartesianGridXY::cellID(const Position& localPosition, const Position& globalPosition, const VolumeID& volumeID) const { +CellID CartesianGridXY::cellID(const Vector3D& localPosition, const Vector3D& globalPosition, const VolumeID& volumeID) const { _decoder->setValue(volumeID); (*_decoder)[_xId] = positionToBin(localPosition.X, _gridSizeX, _offsetX); (*_decoder)[_yId] = positionToBin(localPosition.Y, _gridSizeY, _offsetY); diff --git a/DDSegmentation/src/CartesianGridXYZ.cpp b/DDSegmentation/src/CartesianGridXYZ.cpp index 85b20c709c5d49bdc80be800641d416a7844c3c8..6ce8c65b9aa32a0e2d4010071aa4016b651f10a8 100644 --- a/DDSegmentation/src/CartesianGridXYZ.cpp +++ b/DDSegmentation/src/CartesianGridXYZ.cpp @@ -31,9 +31,9 @@ CartesianGridXYZ::~CartesianGridXYZ() { } /// determine the position based on the cell ID -Position CartesianGridXYZ::position(const CellID& cellID) const { +Vector3D CartesianGridXYZ::position(const CellID& cellID) const { _decoder->setValue(cellID); - Position position; + Vector3D position; position.X = binToPosition((*_decoder)[_xId].value(), _gridSizeX, _offsetX); position.Y = binToPosition((*_decoder)[_yId].value(), _gridSizeY, _offsetY); position.Z = binToPosition((*_decoder)[_zId].value(), _gridSizeZ, _offsetZ); @@ -41,7 +41,7 @@ Position CartesianGridXYZ::position(const CellID& cellID) const { } /// determine the cell ID based on the position -CellID CartesianGridXYZ::cellID(const Position& localPosition, const Position& globalPosition, const VolumeID& volumeID) const { +CellID CartesianGridXYZ::cellID(const Vector3D& localPosition, const Vector3D& globalPosition, const VolumeID& volumeID) const { _decoder->setValue(volumeID); (*_decoder)[_xId] = positionToBin(localPosition.X, _gridSizeX, _offsetX); (*_decoder)[_yId] = positionToBin(localPosition.Y, _gridSizeY, _offsetY); diff --git a/DDSegmentation/src/CartesianGridXZ.cpp b/DDSegmentation/src/CartesianGridXZ.cpp index 4a5ef64f8f4e96c69fa8bd25c18534c158ee7ced..e5f599695258feb097f31ed1417581350bde05c5 100644 --- a/DDSegmentation/src/CartesianGridXZ.cpp +++ b/DDSegmentation/src/CartesianGridXZ.cpp @@ -36,17 +36,17 @@ CartesianGridXZ::~CartesianGridXZ() { } /// determine the position based on the cell ID -Position CartesianGridXZ::position(const CellID& cellID) const { +Vector3D CartesianGridXZ::position(const CellID& cellID) const { _decoder->setValue(cellID); vector<double> localPosition(3); - Position position; + Vector3D position; position.X = binToPosition((*_decoder)[_xId].value(), _gridSizeX, _offsetX); position.Z = binToPosition((*_decoder)[_zId].value(), _gridSizeZ, _offsetZ); return position; } /// determine the cell ID based on the position -CellID CartesianGridXZ::cellID(const Position& localPosition, const Position& globalPosition, const VolumeID& volumeID) const { +CellID CartesianGridXZ::cellID(const Vector3D& localPosition, const Vector3D& globalPosition, const VolumeID& volumeID) const { _decoder->setValue(volumeID); (*_decoder)[_xId] = positionToBin(localPosition.X, _gridSizeX, _offsetX); (*_decoder)[_zId] = positionToBin(localPosition.Z, _gridSizeZ, _offsetZ); diff --git a/DDSegmentation/src/ProjectiveCylinder.cpp b/DDSegmentation/src/ProjectiveCylinder.cpp index e06f6ee0bc9960d652a3bd3298b16370d31fcd2c..cdbf281cc83cb1cc94f148c03e97a82bd0c956a0 100644 --- a/DDSegmentation/src/ProjectiveCylinder.cpp +++ b/DDSegmentation/src/ProjectiveCylinder.cpp @@ -40,12 +40,12 @@ ProjectiveCylinder::~ProjectiveCylinder() { } /// determine the local based on the cell ID -Position ProjectiveCylinder::position(const long64& cellID) const { +Vector3D ProjectiveCylinder::position(const long64& cellID) const { return Util::positionFromRThetaPhi(1.0, theta(cellID), phi(cellID)); } /// determine the cell ID based on the position -CellID ProjectiveCylinder::cellID(const Position& localPosition, const Position& globalPosition, const VolumeID& volumeID) const { +CellID ProjectiveCylinder::cellID(const Vector3D& localPosition, const Vector3D& globalPosition, const VolumeID& volumeID) const { _decoder->setValue(volumeID); double theta = thetaFromXYZ(globalPosition); double phi = phiFromXYZ(globalPosition); diff --git a/DDSegmentation/src/TiledLayerSegmentation.cpp b/DDSegmentation/src/TiledLayerSegmentation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..567f9571d099a4a7e9363b10956d83539763adf3 --- /dev/null +++ b/DDSegmentation/src/TiledLayerSegmentation.cpp @@ -0,0 +1,138 @@ +/* + * TiledLayerSegmentation.cpp + * + * Created on: Mar 10, 2014 + * Author: cgrefe + */ + +#include "DDSegmentation/TiledLayerSegmentation.h" + +// C/C++ includes +#include <algorithm> +#include <sstream> +#include <stdexcept> + +namespace DD4hep { +namespace DDSegmentation { + +using std::find; +using std::runtime_error; +using std::string; +using std::stringstream; +using std::vector; + +TiledLayerSegmentation::TiledLayerSegmentation(const string& cellEncoding) : + Segmentation(cellEncoding) { + _type = "TiledLayerSegmentation"; + _description = "Cartesian segmentation using optimal tiling depending on the layer dimensions"; + + // register all necessary parameters + registerParameter("grid_size_x", "Default cell size in X", _gridSizeX, 1., SegmentationParameter::LengthUnit); + registerParameter("grid_size_y", "Default cell size in Y", _gridSizeY, 1., SegmentationParameter::LengthUnit); + registerIdentifier("identifier_x", "Cell encoding identifier for X", _identifierX, "x"); + registerIdentifier("identifier_y", "Cell encoding identifier for Y", _identifierY, "y"); + registerParameter("identifier_layer", "Cell encoding identifier for layer", _identifierLayer, string("layer"), + SegmentationParameter::NoUnit, true); + registerParameter("layer_identifiers", "List of valid layer identifiers", _layerIndices, vector<int>(), + SegmentationParameter::NoUnit, true); + registerParameter("x_dimensions", "List of layer x dimensions", _layerDimensionsX, vector<double>(), + SegmentationParameter::NoUnit, true); + registerParameter("y_dimensions", "List of layer y dimensions", _layerDimensionsY, vector<double>(), + SegmentationParameter::NoUnit, true); + +} + +TiledLayerSegmentation::~TiledLayerSegmentation() { +} + +/// access the actual grid size in X for a given layer +double TiledLayerSegmentation::layerGridSizeX(int layerIndex) const { + // should be cached in a map if calculateOptimalCellSize is expensive + return calculateOptimalCellSize(_gridSizeX, layerDimensions(layerIndex).x); +} + +/// access the actual grid size in Y for a given layer +double TiledLayerSegmentation::layerGridSizeY(int layerIndex) const { + // should be cached in a map if calculateOptimalCellSize is expensive + return calculateOptimalCellSize(_gridSizeY, layerDimensions(layerIndex).y); +} + +/// set the dimensions of the given layer +void TiledLayerSegmentation::setLayerDimensions(int layerIndex, double x, double y) { + // a bit clumsy since we use three vectors instead of a map<int, LayerDimensions> + if (_layerIndices.size() != _layerDimensionsX.size() or _layerIndices.size() != _layerDimensionsY.size()) { + throw runtime_error( + "TiledLayerSegmentation::setLayerDimensions: inconsistent size of layer parameter vectors."); + } + vector<int>::iterator it = find(_layerIndices.begin(), _layerIndices.end(), layerIndex); + if (it == _layerIndices.end()) { + _layerIndices.push_back(layerIndex); + _layerDimensionsX.push_back(x); + _layerDimensionsY.push_back(y); + } else { + size_t index = it - _layerIndices.begin(); + _layerDimensionsX[index] = x; + _layerDimensionsY[index] = y; + } +} + +/// access to the dimensions of the given layer +TiledLayerSegmentation::LayerDimensions TiledLayerSegmentation::layerDimensions(int layerIndex) const { + // a bit clumsy since we use three vectors instead of a map<int, LayerDimensions> + if (_layerIndices.size() != _layerDimensionsX.size() or _layerIndices.size() != _layerDimensionsY.size()) { + throw runtime_error( + "TiledLayerSegmentation::layerDimensions: inconsistent size of layer parameter vectors."); + } + vector<int>::const_iterator it = find(_layerIndices.begin(), _layerIndices.end(), layerIndex); + if (it == _layerIndices.end()) { + stringstream message; + message << "TiledLayerSegmentation::layerDimensions: invalid layer index " << layerIndex; + throw runtime_error(message.str()); + } else { + size_t index = it - _layerIndices.begin(); + return LayerDimensions(_layerDimensionsX[index], _layerDimensionsY[index]); + } +} + +/// determine the position based on the cell ID +Vector3D TiledLayerSegmentation::position(const CellID& cellID) const { + _decoder->setValue(cellID); + int layerIndex = (*_decoder)[_identifierLayer]; + double cellSizeX = layerGridSizeX(layerIndex); + double cellSizeY = layerGridSizeY(layerIndex); + LayerDimensions dimensions = layerDimensions(layerIndex); + double offsetX = calculateOffset(cellSizeX, dimensions.x); + double offsetY = calculateOffset(cellSizeY, dimensions.y); + double localX = binToPosition((*_decoder)[_identifierX], cellSizeX, offsetX); + double localY = binToPosition((*_decoder)[_identifierY], cellSizeY, offsetY); + return Vector3D(localX, localY, 0.); +} +/// determine the cell ID based on the position +CellID TiledLayerSegmentation::cellID(const Vector3D& localPosition, const Vector3D& globalPosition, + const VolumeID& volumeID) const { + _decoder->setValue(volumeID); + int layerIndex = (*_decoder)[_identifierLayer]; + double cellSizeX = layerGridSizeX(layerIndex); + double cellSizeY = layerGridSizeY(layerIndex); + LayerDimensions dimensions = layerDimensions(layerIndex); + double offsetX = calculateOffset(cellSizeX, dimensions.x); + double offsetY = calculateOffset(cellSizeY, dimensions.y); + (*_decoder)[_identifierX] = positionToBin(localPosition.x(), cellSizeX, offsetX); + (*_decoder)[_identifierY] = positionToBin(localPosition.y(), cellSizeY, offsetY); + return _decoder->getValue(); +} + +/// helper method to calculate optimal cell size based on total size +double TiledLayerSegmentation::calculateOptimalCellSize(double nominalCellSize, double totalSize) { + // TODO: implement algorithm to calculate optimal cell size + return 1.; +} + +/// helper method to calculate offset of bin 0 based on the total size +double TiledLayerSegmentation::calculateOffset(double cellSize, double totalSize) { + // TODO: implement algorithm to calculate placement of bin 0 + return 0.; +} + +} /* namespace DDSegmentation */ +} /* namespace DD4hep */