diff --git a/DDCore/include/DD4hep/Primitives.h b/DDCore/include/DD4hep/Primitives.h index 0b4ccce097867c90eb79ebdd7d7be64c863070e3..239b7a7a34a499d9b8f907bf7b870d50c64e7ad3 100644 --- a/DDCore/include/DD4hep/Primitives.h +++ b/DDCore/include/DD4hep/Primitives.h @@ -17,7 +17,7 @@ */ namespace DD4hep { - // Put here global basic type defintiions derived from primitive types of the DD4hep namespace + // Put here global basic type definitions derived from primitive types of the DD4hep namespace typedef unsigned long long int VolumeID; /// Helper to delete objects from heap and reset the pointer. Saves many many lines of code diff --git a/DDCore/include/DD4hep/Readout.h b/DDCore/include/DD4hep/Readout.h index 328c5eef663bd511eaaa9ba350822df5e98f5557..9830fa13003e112dea43e3f6a5e1c0b080c1e53b 100644 --- a/DDCore/include/DD4hep/Readout.h +++ b/DDCore/include/DD4hep/Readout.h @@ -72,14 +72,6 @@ namespace DD4hep { void setSegmentation(const Segmentation& segment) const; /// Access segmentation structure Segmentation segmentation() const; - - /// ID decoder interface - PlacedVolume getPlacement(const long64& cellID) const; - 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; }; /** @class Alignment Readoutn.h DD4hep/lcdd/Readout.h diff --git a/DDCore/include/DD4hep/Segmentations.h b/DDCore/include/DD4hep/Segmentations.h index 8e7ccb26fc660266a1ffe3c1c3aed25efbe96245..c95e1ff966744e9c4ee5a10210bcd6300573a91b 100644 --- a/DDCore/include/DD4hep/Segmentations.h +++ b/DDCore/include/DD4hep/Segmentations.h @@ -10,9 +10,10 @@ #define DD4HEP_GEOMETRY_SEGMENTATIONS_H // Framework include files +#include "DD4hep/Objects.h" #include "DD4hep/Handle.h" #include "DD4hep/IDDescriptor.h" -#include "DDSegmentation/CartesianGridXYZ.h" +#include "DDSegmentation/Segmentation.h" // C/C++ include files #include <cmath> @@ -44,15 +45,19 @@ namespace DD4hep { * @author M.Frank * @version 1.0 */ - struct Object { + struct Object : public BaseSegmentation { /// Magic word to check object integrity unsigned long magic; /// Flag to use segmentation for hit positioning unsigned char useForHitPosition; /// Reference to base segmentation BaseSegmentation* segmentation; + /// determine the local position based on the cell ID + DDSegmentation::Position 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; /// Standard constructor - Object(); + Object(BaseSegmentation* s = 0); /// Default destructor virtual ~Object(); }; @@ -72,6 +77,11 @@ namespace DD4hep { template <typename Q> Segmentation(const Handle<Q>& e) : Handle<Implementation>(e) { } + /// Constructor to used when creating a new object + Segmentation(BaseSegmentation* s, const std::string& nam, const std::string& typ) : + Handle<Implementation>() { + assign(new Object(s), nam, typ); + } /// Access flag for hit positioning bool useForHitPosition() const; /// Accessor: Segmentation type @@ -80,224 +90,12 @@ namespace DD4hep { void setType(const std::string& new_type); /// Access segmentation object BaseSegmentation* segmentation() const; + /// Access to the parameters + DDSegmentation::Parameters parameters() const; /// determine the local position based on the cell ID - std::vector<double> getLocalPosition(const long64& cellID) const; + Position position(const long64& cellID) const; /// determine the cell ID based on the local position - long64 getCellID(double x, double y, double z) const; - }; - - /** @class SegmentationParams Segmentations.h DD4hep/Segmentations.h - * - * @author M.Frank - * @version 1.0 - */ - struct SegmentationParams: public Segmentation { - public: - /// Segmentation parameter definition - typedef std::pair<std::string, double> Parameter; - /// Segmentation parameter container definition - typedef std::vector<Parameter> Parameters; - /// Constructor to be used when reading the already parsed object - SegmentationParams(const Segmentation& e) - : Segmentation(e) { - } - /// Segmentation type - std::string type() const; - /// Access to the parameters - Parameters parameters() const; - }; - - /** @class ProjectiveCylinder Segmentations.h DD4hep/Segmentations.h - * - * @author M.Frank - * @version 1.0 - */ - struct ProjectiveCylinder: public Segmentation { - - struct Data: public Object, public BaseSegmentation { - int nphi; - int ntheta; - int nz; - /// Default constructor - Data(BitField64* decoder = 0) - : Object(), BaseSegmentation(decoder), nphi(0), ntheta(0), nz(0) { - segmentation = this; - } - /// Default destructor - virtual ~Data(); - /// determine the position based on the cell ID - virtual std::vector<double> getPosition(const long64& cellID) const; - /// 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 - virtual long64 getCellID(double x, double y, double z) const; - }; - /// Constructor to be used when reading the already parsed object - template <typename Q> ProjectiveCylinder(const Handle<Q>& e) - : Segmentation(e) { - } - /// Constructor to create a new segmentation object - ProjectiveCylinder(LCDD& lcdd); - /// Accessors: get number of bins in theta - int thetaBins() const; - /// Accessors: get number of bins in phi - int phiBins() const; - /// Accessors: get number of bins in z - int zBins() const; - /// Accessors: set number of bins in theta - void setThetaBins(int value); - /// Accessors: set number of bins in phi - void setPhiBins(int value); - /// Accessors: set number of bins in Z - void setZBins(int value); - }; - - /** @class NonProjectiveCylinder Segmentations.h DD4hep/Segmentations.h - * - * @author M.Frank - * @version 1.0 - */ - struct NonProjectiveCylinder: public Segmentation { - struct Data: public Object, public BaseSegmentation { - double grid_size_phi; - double grid_size_theta; - double grid_size_z; - /// Default constructor - Data(BitField64* decoder = 0) - : Object(), BaseSegmentation(decoder) { - grid_size_phi = grid_size_theta = grid_size_z = 0; - segmentation = this; - } - /// Default destructor - virtual ~Data(); - /// determine the position based on the cell ID - virtual std::vector<double> getPosition(const long64& cellID) const; - /// 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 - virtual long64 getCellID(double x, double y, double z) const; - }; - /// Constructor to be used when reading the already parsed object - template <typename Q> NonProjectiveCylinder(const Handle<Q>& e) - : Segmentation(e) { - } - /// Constructor to create a new segmentation object - NonProjectiveCylinder(LCDD& lcdd); - /// Accessors: get size of bins in Z - double gridSizeZ() const; - /// Accessors: get size of bins in phi - double gridSizePhi() const; - /// Accessors: set number of bins in theta - void setThetaBinSize(double value); - /// Accessors: set grid size in Y - void setPhiBinSize(double value); - }; - - /** @class ProjectiveZPlane Segmentations.h DD4hep/Segmentations.h - * - * @author M.Frank - * @version 1.0 - */ - struct ProjectiveZPlane: public Segmentation { - struct Data: public Object, public BaseSegmentation { - int nphi; - int ntheta; - int nz; - /// Default constructor - Data(BitField64* decoder = 0) - : Object(), BaseSegmentation(decoder) { - nphi = ntheta = nz = 0; - segmentation = this; - } - /// Default destructor - virtual ~Data(); - /// determine the position based on the cell ID - virtual std::vector<double> getPosition(const long64& cellID) const; - /// 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 - virtual long64 getCellID(double x, double y, double z) const; - }; - /// Constructor to be used when reading the already parsed object - template <typename Q> ProjectiveZPlane(const Handle<Q>& e) - : Segmentation(e) { - } - /// Constructor to create a new segmentation object - ProjectiveZPlane(LCDD& lcdd); - /// Accessors: get number of bins in theta - int thetaBins() const; - /// Accessors: get number of bins in phi - int phiBins() const; - /// Accessors: set number of bins in theta - void setThetaBins(int value); - /// Accessors: set grid size in Y - void setPhiBins(int value); - }; - - /** @class GridXY Segmentations.h DD4hep/Segmentations.h - * - * @author M.Frank - * @version 1.0 - */ - struct GridXY: public Segmentation { - struct Data: public Object, public DDSegmentation::CartesianGridXY { - /// Default constructor - Data(BitField64* decoder = 0) - : Object(), DDSegmentation::CartesianGridXY(decoder) { - segmentation = this; - } - /// Default destructor - virtual ~Data(); - }; - /// Constructor to be used when reading the already parsed object - template <typename Q> GridXY(const Handle<Q>& e) - : Segmentation(e) { - } - /// Constructor to create a new segmentation object - GridXY(LCDD& lcdd, const std::string& typ); - /// Accessors: set grid size in X - void setGridSizeX(double value); - /// Accessors: set grid size in Y - void setGridSizeY(double value); - /// Accessors: get grid size in X - double getGridSizeX() const; - /// Accessors: get grid size in Y - double getGridSizeY() const; - }; - - /** @class GridXYZ Segmentations.h DD4hep/Segmentations.h - * - * @author M.Frank - * @version 1.0 - */ - struct GridXYZ: public Segmentation { - struct Data: public Object, public DDSegmentation::CartesianGridXYZ { - /// Default constructor - Data(BitField64* decoder = 0) - : Object(), DDSegmentation::CartesianGridXYZ(decoder) { - segmentation = this; - } - /// Default destructor - virtual ~Data(); - }; - /// Constructor to be used when reading the already parsed object - template <typename Q> GridXYZ(const Handle<Q>& e) - : GridXY(e) { - } - /// Constructor to be used when creating a new object. - GridXYZ(LCDD& lcdd, const std::string& typ); - /// Accessors: set grid size in X - void setGridSizeX(double value); - /// Accessors: set grid size in Y - void setGridSizeY(double value); - /// Accessors: set grid size in Z - void setGridSizeZ(double value); - /// Accessors: get grid size in X - double getGridSizeX() const; - /// Accessors: get grid size in Y - double getGridSizeY() const; - /// Accessors: get grid size in Z - double getGridSizeZ() const; + long64 cellID(const Position& localPosition, const Position& globalPosition, const long64& volumeID) const; }; } /* End namespace Geometry */ diff --git a/DDCore/src/Readout.cpp b/DDCore/src/Readout.cpp index 32a634ef2aa729ba9da47adcf0a1741b60b4c10a..3c5b1cba50493d1e369f014c0a8f3b4da9273e2e 100644 --- a/DDCore/src/Readout.cpp +++ b/DDCore/src/Readout.cpp @@ -75,39 +75,6 @@ Segmentation Readout::segmentation() const { return object<Object>().segmentation; } -/// full ID decoder interface -PlacedVolume Readout::getPlacement(const long64& cellID) const { - VolumeManager volMan = LCDD::getInstance().volumeManager(); - return volMan.lookupPlacement(cellID); -} - -DetElement Readout::getSubDetector(const long64& cellID) const { - VolumeManager volMan = LCDD::getInstance().volumeManager(); - return volMan.lookupDetector(cellID); -} - -DetElement Readout::getDetectorElement(const long64& cellID) const { - VolumeManager volMan = LCDD::getInstance().volumeManager(); - 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()->getPosition(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()->getPosition(cellID); - return Position(v[0], v[1], v[2]); -} - -const TGeoMatrix& Readout::getWorldTransformation(const long64& cellID) const { - VolumeManager volMan = LCDD::getInstance().volumeManager(); - return volMan.worldTransformation(cellID); -} - /// Standard constructor Alignment::Object::Object() { InstanceCount::increment(this); diff --git a/DDCore/src/Segementations.cpp b/DDCore/src/Segementations.cpp index 6adc202fd9e60b0774b9ae42369eded259b45f50..87bdc2815f6c7cc22000337052bd7dace0f562e4 100644 --- a/DDCore/src/Segementations.cpp +++ b/DDCore/src/Segementations.cpp @@ -16,22 +16,9 @@ using namespace std; using namespace DD4hep; using namespace DD4hep::Geometry; -namespace { - void not_implemented_call(const char* tag) { - throw runtime_error(tag); - } - template <typename T> T& _obj(const DDSegmentation::Segmentation* ptr) { - // ---> This would be so much more efficient, but sissies refused.... - // T* p = (T*)(((const char*)ptr) - sizeof(Segmentation::Object)); - // return *p; - const T* p = dynamic_cast<const T*>(ptr); - return *(T*)p; - } -} - /// Standard constructor -Segmentation::Object::Object() - : magic(magic_word()), useForHitPosition(0), segmentation(0) { +Segmentation::Object::Object(BaseSegmentation* s) + : magic(magic_word()), useForHitPosition(0), segmentation(s) { InstanceCount::increment(this); } @@ -40,23 +27,28 @@ Segmentation::Object::~Object() { InstanceCount::decrement(this); } +/// determine the local position based on the cell ID +DDSegmentation::Position 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 { + return segmentation->cellID(localPosition,globalPosition, volumeID); +} + /// Accessor: Segmentation type std::string Segmentation::type() const { return segmentation()->type(); } bool Segmentation::useForHitPosition() const { - return _obj<Object>(ptr()).useForHitPosition != 0; -} - -/// Segmentation type -string SegmentationParams::type() const { - return _obj<Object>(ptr()).segmentation->type(); + return object<Object>().useForHitPosition != 0; } /// Access to the parameters -SegmentationParams::Parameters SegmentationParams::parameters() const { - Object& o = _obj<Object>(ptr()); +DDSegmentation::Parameters Segmentation::parameters() const { + Object& o = object<Object>(); if (o.segmentation != 0) { return o.segmentation->parameters(); } @@ -65,7 +57,7 @@ SegmentationParams::Parameters SegmentationParams::parameters() const { /// Access segmentation object DD4hep::DDSegmentation::Segmentation* Segmentation::segmentation() const { - Object& o = _obj<Object>(ptr()); + Object& o = object<Object>(); if (o.segmentation != 0) return o.segmentation; throw runtime_error( @@ -73,222 +65,12 @@ DD4hep::DDSegmentation::Segmentation* Segmentation::segmentation() const { + " knows no implementation object [This is no longer allowed in the presence of DDSegmentation]"); } -/// Default destructor -ProjectiveCylinder::Data::~Data() { -} - -/// determine the local position based on the cell ID -std::vector<double> ProjectiveCylinder::Data::getPosition(const long64& cellID) const { - not_implemented_call("ProjectiveCylinder::Data::getLocalPosition"); - return vector<double>(); -} - -/// determine the local position based on the cell ID -std::vector<double> ProjectiveCylinder::Data::getLocalPosition(const long64& cellID) const { - not_implemented_call("ProjectiveCylinder::Data::getLocalPosition"); - return vector<double>(); -} - -/// determine the cell ID based on the local position -long64 ProjectiveCylinder::Data::getCellID(double x, double y, double z) const { - not_implemented_call("ProjectiveCylinder::Data::getCellID"); - return 0; -} - -/// Constructor to create a new segmentation object -ProjectiveCylinder::ProjectiveCylinder(LCDD&) - : Segmentation(new Data(), "segmentation", "projective_cylinder") { -} - -/// Accessors: get number of bins in theta -int ProjectiveCylinder::thetaBins() const { - return _obj<Data>(ptr()).ntheta; -} - -/// Accessors: get number of bins in phi -int ProjectiveCylinder::phiBins() const { - return _obj<Data>(ptr()).nphi; -} - -/// Accessors: get number of bins in z -int ProjectiveCylinder::zBins() const { - return _obj<Data>(ptr()).nz; -} - -/// Accessors: set number of bins in theta -void ProjectiveCylinder::setThetaBins(int value) { - _obj<Data>(ptr()).ntheta = value; -} - -/// Accessors: set grid size in Y -void ProjectiveCylinder::setPhiBins(int value) { - _obj<Data>(ptr()).nphi = value; -} - -/// Accessors: set number of bins in Z -void ProjectiveCylinder::setZBins(int value) { - _obj<Data>(ptr()).nz = value; -} - -/// Default destructor -NonProjectiveCylinder::Data::~Data() { -} - -/// determine the local position based on the cell ID -std::vector<double> NonProjectiveCylinder::Data::getPosition(const long64& cellID) const { - not_implemented_call("NonProjectiveCylinder::Data::getLocalPosition"); - return vector<double>(); -} - -/// determine the local position based on the cell ID -std::vector<double> NonProjectiveCylinder::Data::getLocalPosition(const long64& cellID) const { - not_implemented_call("NonProjectiveCylinder::Data::getLocalPosition"); - return vector<double>(); -} - -/// determine the cell ID based on the local position -long64 NonProjectiveCylinder::Data::getCellID(double x, double y, double z) const { - not_implemented_call("NonProjectiveCylinder::Data::getCellID"); - return 0; -} - -/// Constructor to create a new segmentation object -NonProjectiveCylinder::NonProjectiveCylinder(LCDD&) - : Segmentation(new Data(), "segmentation", "nonprojective_cylinder") { -} - -/// Accessors: get size of bins in Z -double NonProjectiveCylinder::gridSizeZ() const { - return _obj<Data>(ptr()).grid_size_z; -} - -/// Accessors: get size of bins in phi -double NonProjectiveCylinder::gridSizePhi() const { - return _obj<Data>(ptr()).grid_size_phi; -} - -/// Accessors: set number of bins in theta -void NonProjectiveCylinder::setThetaBinSize(double value) { - _obj<Data>(ptr()).grid_size_phi = value; -} - -/// Accessors: set grid size in Y -void NonProjectiveCylinder::setPhiBinSize(double value) { - _obj<Data>(ptr()).grid_size_z = value; -} - -/// Default destructor -ProjectiveZPlane::Data::~Data() { -} - /// determine the local position based on the cell ID -std::vector<double> ProjectiveZPlane::Data::getLocalPosition(const long64& cellID) const { - not_implemented_call("ProjectiveZPlane::Data::getLocalPosition"); - return vector<double>(); -} - -/// determine the local position based on the cell ID -std::vector<double> ProjectiveZPlane::Data::getPosition(const long64& cellID) const { - not_implemented_call("ProjectiveZPlane::Data::getLocalPosition"); - return vector<double>(); +Position Segmentation::position(const long64& cellID) const { + return Position(segmentation()->position(cellID)); } /// determine the cell ID based on the local position -long64 ProjectiveZPlane::Data::getCellID(double x, double y, double z) const { - not_implemented_call("ProjectiveZPlane::Data::getCellID"); - return 0; -} - -/// Constructor to be used when creating a new object. -ProjectiveZPlane::ProjectiveZPlane(LCDD&) - : Segmentation(new Data(), "segmentation", "projective_zplane") { -} - -/// Accessors: get number of bins in phi -int ProjectiveZPlane::phiBins() const { - return _obj<Data>(ptr()).nphi; -} - -/// Accessors: get number of bins in theta -int ProjectiveZPlane::thetaBins() const { - return _obj<Data>(ptr()).ntheta; -} - -/// Accessors: set number of bins in theta -void ProjectiveZPlane::setThetaBins(int value) { - _obj<Data>(ptr()).ntheta = value; -} - -/// Accessors: set grid size in Y -void ProjectiveZPlane::setPhiBins(int value) { - _obj<Data>(ptr()).nphi = value; -} - -/// Default destructor -GridXY::Data::~Data() { -} - -/// Constructor to be used when creating a new object. -GridXY::GridXY(LCDD&, const std::string& typ) - : Segmentation(new Data(), "segmentation", typ) { -} - -/// Accessors: get grid size in X -double GridXY::getGridSizeX() const { - return _obj<Data>(ptr()).getGridSizeX(); -} - -/// Accessors: get grid size in Y -double GridXY::getGridSizeY() const { - return _obj<Data>(ptr()).getGridSizeY(); -} - -/// Accessors: set grid size in X -void GridXY::setGridSizeX(double value) { - _obj<Data>(ptr()).setGridSizeX(value); -} - -/// Accessors: set grid size in Y -void GridXY::setGridSizeY(double value) { - _obj<Data>(ptr()).setGridSizeY(value); -} - -/// Default destructor -GridXYZ::Data::~Data() { -} - -/// Constructor to be used when creating a new object. -GridXYZ::GridXYZ(LCDD&, const std::string& typ) - : Segmentation(new Data(), "segmentation", typ) { - assign(new Data(), "segmentation", typ); -} - -/// Accessors: get grid size in X -double GridXYZ::getGridSizeX() const { - return _obj<Data>(ptr()).getGridSizeX(); -} - -/// Accessors: get grid size in Y -double GridXYZ::getGridSizeY() const { - return _obj<Data>(ptr()).getGridSizeY(); -} - -/// Accessors: get grid size in Z -double GridXYZ::getGridSizeZ() const { - return _obj<Data>(ptr()).getGridSizeZ(); -} - -/// Accessors: set grid size in X -void GridXYZ::setGridSizeX(double value) { - _obj<Data>(ptr()).setGridSizeX(value); -} - -/// Accessors: set grid size in Y -void GridXYZ::setGridSizeY(double value) { - _obj<Data>(ptr()).setGridSizeY(value); -} - -/// Accessors: set grid size in Z -void GridXYZ::setGridSizeZ(double value) { - _obj<Data>(ptr()).setGridSizeZ(value); +long64 Segmentation::cellID(const Position& localPosition, const Position& globalPosition, const long64& volumeID) const { + return segmentation()->cellID(localPosition, globalPosition, volumeID); } diff --git a/DDCore/src/plugins/Compact2Objects.cpp b/DDCore/src/plugins/Compact2Objects.cpp index 182e460fceaaee402dfd388ed7a8a94383c2fa1c..b2cf444e953d1f9bdcd446aa291f1ebd7a9cf122 100644 --- a/DDCore/src/plugins/Compact2Objects.cpp +++ b/DDCore/src/plugins/Compact2Objects.cpp @@ -15,9 +15,7 @@ #include "DD4hep/Plugins.h" #include "XML/DocumentHandler.h" #include "XML/Conversions.h" - -#include "DDSegmentation/CartesianGridXY.h" -#include "DDSegmentation/CartesianGridXYZ.h" +#include "DDSegmentation/SegmentationFactory.h" // Root/TGeo include files #include "TGeoManager.h" @@ -68,84 +66,6 @@ namespace { } -static Ref_t create_GridXYZ(lcdd_t& lcdd, xml_h e) { - GridXYZ obj(lcdd, "grid_xyz"); - if (e.hasAttr(_U(gridSizeX))) - obj.setGridSizeX(e.attr<float>(_U(gridSizeX))); - if (e.hasAttr(_U(gridSizeY))) - obj.setGridSizeY(e.attr<float>(_U(gridSizeY))); - if (e.hasAttr(_U(gridSizeZ))) - obj.setGridSizeZ(e.attr<float>(_U(gridSizeZ))); - return obj; -} -DECLARE_XMLELEMENT(GridXYZ,create_GridXYZ); - -static Ref_t create_GlobalGridXY(lcdd_t& lcdd, xml_h e) { - GridXY obj(lcdd, "global_grid_xy"); - if (e.hasAttr(_U(gridSizeX))) - obj.setGridSizeX(e.attr<float>(_U(gridSizeX))); - if (e.hasAttr(_U(gridSizeY))) - obj.setGridSizeY(e.attr<float>(_U(gridSizeY))); - return obj; -} -DECLARE_XMLELEMENT(GlobalGridXY,create_GlobalGridXY); - -static Ref_t create_CartesianGridXY(lcdd_t& lcdd, xml_h e) { - GridXY obj(lcdd, "cartesian_grid_xy"); - if (e.hasAttr(_U(gridSizeX))) - obj.setGridSizeX(e.attr<double>(_U(gridSizeX))); - if (e.hasAttr(_U(gridSizeY))) - obj.setGridSizeY(e.attr<double>(_U(gridSizeY))); - return obj; -} -DECLARE_XMLELEMENT(CartesianGridXY,create_CartesianGridXY); - -namespace DD4hep { - namespace Geometry { - typedef GridXY RegularNgonCartesianGridXY; - } -} -DECLARE_XMLELEMENT(RegularNgonCartesianGridXY,create_CartesianGridXY); - -namespace DD4hep { - namespace Geometry { - typedef GridXYZ CartesianGridXYZ; - typedef GridXY EcalBarrelCartesianGridXY; - } -} -DECLARE_XMLELEMENT(CartesianGridXYZ,create_CartesianGridXY); -DECLARE_XMLELEMENT(EcalBarrelCartesianGridXY,create_CartesianGridXY); - -static Ref_t create_ProjectiveCylinder(lcdd_t& lcdd, xml_h e) { - ProjectiveCylinder obj(lcdd); - if (e.hasAttr(_U(phiBins))) - obj.setPhiBins(e.attr<int>(_U(phiBins))); - if (e.hasAttr(_U(thetaBins))) - obj.setThetaBins(e.attr<int>(_U(thetaBins))); - return obj; -} -DECLARE_XMLELEMENT(ProjectiveCylinder,create_ProjectiveCylinder); - -static Ref_t create_NonProjectiveCylinder(lcdd_t& lcdd, xml_h e) { - NonProjectiveCylinder obj(lcdd); - if (e.hasAttr(_U(gridSizePhi))) - obj.setThetaBinSize(e.attr<double>(_U(gridSizePhi))); - if (e.hasAttr(_U(gridSizeZ))) - obj.setPhiBinSize(e.attr<double>(_U(gridSizeZ))); - return obj; -} -DECLARE_XMLELEMENT(NonProjectiveCylinder,create_NonProjectiveCylinder); - -static Ref_t create_ProjectiveZPlane(lcdd_t& lcdd, xml_h e) { - ProjectiveZPlane obj(lcdd); - if (e.hasAttr(_U(phiBins))) - obj.setThetaBins(e.attr<int>(_U(phiBins))); - if (e.hasAttr(_U(thetaBins))) - obj.setPhiBins(e.attr<int>(_U(thetaBins))); - return obj; -} -DECLARE_XMLELEMENT(ProjectiveZPlane,create_ProjectiveZPlane); - static Ref_t create_ConstantField(lcdd_t& /* lcdd */, xml_h e) { CartesianField obj; xml_comp_t field(e), strength(e.child(_U(strength))); @@ -520,12 +440,24 @@ template <> void Converter<Readout>::operator()(xml_h e) const { Ref_t idSpec; if (seg) { // Segmentation is not mandatory! + typedef DDSegmentation::Segmentation BaseSegmentation; string type = seg.attr < string > (_U(type)); - Ref_t segment(PluginService::Create<TNamed*>(type, &lcdd, &seg)); - if (!segment.isValid()) { - PluginDebug dbg; - PluginService::Create<TNamed*>(type, &lcdd, &seg); - throw_print("FAILED to create segmentation:" + type + ". " + dbg.missingFactory(type)); + BaseSegmentation* s = DDSegmentation::SegmentationFactory::instance()->create(type); + if (not s) { + throw_print("FAILED to create segmentation: " + type + ". Missing factory method for: " + type + "!"); + } + Segmentation segment(s, name, type); + if (segment.isValid()) { + DDSegmentation::Parameters parameters = s->parameters(); + DDSegmentation::Parameters::iterator it; + for (it = parameters.begin(); it != parameters.end(); ++it) { + DDSegmentation::Parameter p = *it; + if (seg.hasAttr(Unicode(p->name()))) { + p->value() = seg.attr<double>(Unicode(p->name())); + } else if (not p->isOptional()) { + throw_print("FAILED to create segmentation: " + type + ". Missing mandatory parameter: " + p->name() + "!"); + } + } } ro.setSegmentation(segment); } diff --git a/DDCore/src/plugins/LCDDConverter.cpp b/DDCore/src/plugins/LCDDConverter.cpp index 0fadea41f849fc38dae34537a064ce04fcf8b7b5..3bfb0351fae1e9a3a5a55e1a590c928e825c3957 100644 --- a/DDCore/src/plugins/LCDDConverter.cpp +++ b/DDCore/src/plugins/LCDDConverter.cpp @@ -800,21 +800,20 @@ xml_h LCDDConverter::handleLimitSet(const std::string& name, const TNamed* limit xml_h LCDDConverter::handleSegmentation(Segmentation seg) const { xml_h xml; if (seg.isValid()) { - typedef SegmentationParams::Parameters _P; + typedef DDSegmentation::Parameters _P; string typ = seg.type(); - SegmentationParams par(seg); - _P p = par.parameters(); + _P p = seg.parameters(); xml = xml_elt_t(data().doc, Unicode(typ)); for (_P::const_iterator i = p.begin(); i != p.end(); ++i) { const _P::value_type& v = *i; - if (v.first == "lunit") { - string val = v.second == _toDouble("mm") ? "mm" : v.second == _toDouble("cm") ? "cm" : - v.second == _toDouble("m") ? "m" : v.second == _toDouble("micron") ? "micron" : - v.second == _toDouble("nanometer") ? "namometer" : "??"; - xml.setAttr(Unicode(v.first), Unicode(val)); + if (v->name() == "lunit") { + string val = v->value() == _toDouble("mm") ? "mm" : v->value() == _toDouble("cm") ? "cm" : + v->value() == _toDouble("m") ? "m" : v->value() == _toDouble("micron") ? "micron" : + v->value() == _toDouble("nanometer") ? "namometer" : "??"; + xml.setAttr(Unicode(v->name()), Unicode(val)); continue; } - xml.setAttr(Unicode(v.first), v.second); + xml.setAttr(Unicode(v->name()), v->value()); } } return xml; diff --git a/DDSegmentation/include/DDSegmentation/CartesianGrid.h b/DDSegmentation/include/DDSegmentation/CartesianGrid.h index 1df3494d5da72a961263c9e1fa8af4904cf971d0..f04409902f09e70c6904a99bebe612c246ab077c 100644 --- a/DDSegmentation/include/DDSegmentation/CartesianGrid.h +++ b/DDSegmentation/include/DDSegmentation/CartesianGrid.h @@ -15,11 +15,11 @@ namespace DDSegmentation { class CartesianGrid: public Segmentation { public: - /// destructor + /// Destructor virtual ~CartesianGrid(); protected: - /// default constructor using an arbitrary type - template <typename TYPE> CartesianGrid(TYPE cellEncoding); + /// Default constructor used by derived classes passing the encoding string + CartesianGrid(const std::string& cellEncoding = ""); }; } /* namespace DDSegmentation */ diff --git a/DDSegmentation/include/DDSegmentation/CartesianGridXY.h b/DDSegmentation/include/DDSegmentation/CartesianGridXY.h index 52cd121e09670bd560ffbc878e2d7400166e6090..5e470e1165f76876b348bd0683b71e1a9efa4adc 100644 --- a/DDSegmentation/include/DDSegmentation/CartesianGridXY.h +++ b/DDSegmentation/include/DDSegmentation/CartesianGridXY.h @@ -15,38 +15,37 @@ namespace DDSegmentation { 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., const std::string& xField = "x", const std::string& yField = "y"); + /// Default constructor passing the encoding string + CartesianGridXY(const std::string& cellEncoding = ""); /// destructor virtual ~CartesianGridXY(); /// determine the position based on the cell ID - virtual std::vector<double> getPosition(const long64& cellID) const; + virtual Position position(const CellID& cellID) const; /// determine the cell ID based on the position - virtual long64 getCellID(double x, double y, double z) const; + virtual CellID cellID(const Position& localPosition, const Position& globalPosition, const VolumeID& volumeID) const; /// access the grid size in X - double getGridSizeX() const { + double gridSizeX() const { return _gridSizeX; } /// access the grid size in Y - double getGridSizeY() const { + double gridSizeY() const { return _gridSizeY; } /// access the coordinate offset in X - double getOffsetX() const { + double offsetX() const { return _offsetX; } /// access the coordinate offset in Y - double getOffsetY() const { + double offsetY() const { return _offsetY; } /// access the field name used for X - std::string getFieldNameX() const { + const std::string& fieldNameX() const { return _xId; } /// access the field name used for Y - std::string getFieldNameY() const { + const std::string& fieldNameY() const { return _yId; } /// set the grid size in X @@ -73,8 +72,6 @@ public: void setFieldNameY(const std::string& name) { _yId = name; } - /// access the set of parameters for this segmentation - Parameters parameters() const; protected: /// the grid size in X diff --git a/DDSegmentation/include/DDSegmentation/CartesianGridXYZ.h b/DDSegmentation/include/DDSegmentation/CartesianGridXYZ.h index 981dd8f0eeff8e357cf819083507a2afbabbc8e5..b28840df31811be5dc1cccf31d4caed6e8f3ce89 100644 --- a/DDSegmentation/include/DDSegmentation/CartesianGridXYZ.h +++ b/DDSegmentation/include/DDSegmentation/CartesianGridXYZ.h @@ -16,26 +16,24 @@ namespace DDSegmentation { 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., const std::string& xField = "x", - const std::string& yField = "y", const std::string& zField = "z"); + CartesianGridXYZ(const std::string& cellEncoding); /// destructor virtual ~CartesianGridXYZ(); /// determine the position based on the cell ID - virtual std::vector<double> getPosition(const long64& cellID) const; + virtual Position position(const CellID& cellID) const; /// determine the cell ID based on the position - virtual long64 getCellID(double x, double y, double z) const; + virtual CellID cellID(const Position& localPosition, const Position& globalPosition, const VolumeID& volumeID) const; /// access the grid size in Z - double getGridSizeZ() const { + double gridSizeZ() const { return _gridSizeZ; } /// access the coordinate offset in Z - double getOffsetZ() const { + double offsetZ() const { return _offsetZ; } /// access the field name used for Z - std::string getFieldNameZ() const { + const std::string& fieldNameZ() const { return _zId; } /// set the grid size in Z @@ -50,8 +48,6 @@ public: void setFieldNameZ(const std::string& name) { _zId = name; } - /// access the set of parameters for this segmentation - Parameters parameters() const; protected: /// the grid size in Z diff --git a/DDSegmentation/include/DDSegmentation/CartesianGridXZ.h b/DDSegmentation/include/DDSegmentation/CartesianGridXZ.h index 5e4c813496150b48545988b1959333819b8a6af2..02ab684ef5e1857804198c9d382b4117dcfcd417 100644 --- a/DDSegmentation/include/DDSegmentation/CartesianGridXZ.h +++ b/DDSegmentation/include/DDSegmentation/CartesianGridXZ.h @@ -16,37 +16,36 @@ 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"); + CartesianGridXZ(const std::string& cellEncoding); /// destructor virtual ~CartesianGridXZ(); /// determine the local based on the cell ID - virtual std::vector<double> getPosition(const long64& cellID) const; + virtual Position position(const CellID& cellID) const; /// determine the cell ID based on the position - virtual long64 getCellID(double x, double y, double z) const; + virtual CellID cellID(const Position& localPosition, const Position& globalPosition, const VolumeID& volumeID) const; /// access the grid size in X - double getGridSizeX() const { + double gridSizeX() const { return _gridSizeX; } /// access the grid size in Z - double getGridSizeZ() const { + double gridSizeZ() const { return _gridSizeZ; } /// access the coordinate offset in X - double getOffsetX() const { + double offsetX() const { return _offsetX; } /// access the coordinate offset in Z - double getOffsetZ() const { + double offsetZ() const { return _offsetZ; } /// access the field name used for X - std::string getFieldNameX() const { + const std::string& fieldNameX() const { return _xId; } /// access the field name used for Z - std::string getFieldNameZ() const { + const std::string& fieldNameZ() const { return _zId; } /// set the grid size in X @@ -73,8 +72,6 @@ public: 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 diff --git a/DDSegmentation/include/DDSegmentation/CylindricalSegmentation.h b/DDSegmentation/include/DDSegmentation/CylindricalSegmentation.h index 1aaafa6140a2ab929ef315bcc14ef854fd40c7d7..5d12401d6891f012414423519d412e21137f94fd 100644 --- a/DDSegmentation/include/DDSegmentation/CylindricalSegmentation.h +++ b/DDSegmentation/include/DDSegmentation/CylindricalSegmentation.h @@ -20,28 +20,9 @@ public: /// destructor virtual ~CylindricalSegmentation(); - /// determine the radius based on the cell ID - double 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; + CylindricalSegmentation(const std::string& cellEncoding); }; diff --git a/DDSegmentation/include/DDSegmentation/ProjectiveCylinder.h b/DDSegmentation/include/DDSegmentation/ProjectiveCylinder.h index 6b58a7060b849ac721092d7153369b37ee66ef31..f2c61bae838f27bb04b8324870becacc03e9bcbb 100644 --- a/DDSegmentation/include/DDSegmentation/ProjectiveCylinder.h +++ b/DDSegmentation/include/DDSegmentation/ProjectiveCylinder.h @@ -16,42 +16,40 @@ 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"); + ProjectiveCylinder(const std::string& cellEncoding); /// destructor virtual ~ProjectiveCylinder(); /// determine the position based on the cell ID - virtual std::vector<double> getPosition(const long64& cellID) const; + virtual Position position(const CellID& cellID) const; /// determine the cell ID based on the position - virtual long64 getCellID(double x, double y, double z) const; + virtual CellID cellID(const Position& localPosition, const Position& globalPosition, const VolumeID& volumeID) const; /// determine the polar angle theta based on the cell ID - double getTheta(const long64& cellID) const; + double theta(const long64& cellID) const; /// determine the azimuthal angle phi based on the cell ID - double getPhi(const long64& cellID) const; + double phi(const long64& cellID) const; /// access the number of bins in theta - int getThetaBins() const { + int thetaBins() const { return _thetaBins; } /// access the number of bins in theta - int getPhiBins() const { + int phiBins() const { return _phiBins; } /// access the coordinate offset in theta - double getOffsetTheta() const { + double offsetTheta() const { return _offsetTheta; } /// access the coordinate offset in phi - double getOffsetPhi() const { + double offsetPhi() const { return _offsetPhi; } /// access the field name used for theta - std::string getFieldNameTheta() const { + std::string fieldNameTheta() const { return _thetaID; } /// access the field name used for phi - std::string getFieldNamePhi() const { + std::string fieldNamePhi() const { return _phiID; } /// set the number of bins in theta @@ -78,14 +76,12 @@ public: 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; + double _thetaBins; /// the number of bins in phi - int _phiBins; + double _phiBins; /// the coordinate offset in theta double _offsetTheta; /// the coordinate offset in phi diff --git a/DDSegmentation/include/DDSegmentation/Segmentation.h b/DDSegmentation/include/DDSegmentation/Segmentation.h index c1d5c730ec134b9f407a1e9787b254e3895f5ac8..59beb6753d867d5ae70e26236d85797cd645fea7 100644 --- a/DDSegmentation/include/DDSegmentation/Segmentation.h +++ b/DDSegmentation/include/DDSegmentation/Segmentation.h @@ -9,7 +9,10 @@ #define DDSegmentation_SEGMENTATION_H_ #include "DDSegmentation/BitField64.h" +#include "DDSegmentation/SegmentationFactory.h" +#include "DDSegmentation/SegmentationParameter.h" +#include <map> #include <utility> #include <string> #include <vector> @@ -17,81 +20,128 @@ namespace DD4hep { namespace DDSegmentation { -/// Segmentation parameter definition -typedef std::pair<std::string,double> Parameter; -/// Segmentation parameter container definition -typedef std::vector<Parameter> Parameters; +typedef SegmentationParameter* Parameter; +typedef std::vector<Parameter> Parameters; +/// Useful typedefs to differentiate cell IDs and volume IDs +typedef long long int CellID; +typedef long long int VolumeID; + +/// Simple container for a physics vector +struct Position { + /// Default constructor + Position(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) { + X = v.x(); + Y = v.y(); + Z = v.Z(); + } + /// Access to x value (required for use with ROOT GenVector) + double x() const { + return X; + } + /// Access to y value (required for use with ROOT GenVector) + double y() const { + return Y; + } + /// Access to z value (required for use with ROOT GenVector) + double z() const { + return Z; + } + double X, Y, Z; +}; + +/// Base class for all segmentations class Segmentation { public: - /// default constructor using an arbitrary type - template <typename TYPE> Segmentation(TYPE cellEncoding); - /// destructor + /// Destructor virtual ~Segmentation(); - /// 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 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 + /// Determine the local position based on the cell ID + virtual Position position(const CellID& cellID) const = 0; + /// Determine the cell ID based on the position + virtual CellID cellID(const Position& localPosition, const Position& globalPosition, + const VolumeID& volumeID) const = 0; + /// Access the encoding string std::string fieldDescription() const { return _decoder->fieldDescription(); } - /// access the segmentation name - std::string name() const { + /// Access the segmentation name + const std::string& name() const { return _name; } /// Set the segmentation name void setName(const std::string& value) { _name = value; } - /// access the segmentation type - std::string type() const { + /// Access the segmentation type + const std::string& type() const { return _type; } /// Set the segmentation type - void setType(const std::string& value) { + void setType(const std::string& value) { + //FIXME: Should not be able to change the type! _type = value; } - /// access the underlying decoder + /// Access the description of the segmentation + const std::string& description() const { + return _description; + } + /// Access the underlying decoder BitField64* decoder() { return _decoder; } - /// set the underlying decoder + /// Set the underlying decoder void setDecoder(BitField64* decoder); - /// access the set of parameters for this segmentation - Parameters parameters() const; + /// Access the set of parameters +// Parameters parameters() const; + /// Access to parameter by name + SegmentationParameter* parameter(const std::string& parameterName); + /// Access to parameter by name + const SegmentationParameter* parameter(const std::string& parameterName) const; + /// Access to parameter value by name + double parameterValue(const std::string& parameterName) const; + /// Set the parameter value by name + void setParameterValue(const std::string& parameterName, double value); + /// Access to all parameters + std::vector<SegmentationParameter*> parameters(); + /// Access to all parameters + std::vector<const SegmentationParameter*> parameters() const; protected: - /// the cell ID encoder and decoder + /// Default constructor used by derived classes passing the encoding string + Segmentation(const std::string& cellEncoding = ""); + + /// Add a parameter to this segmentation. Used by derived classes to define their parameters + void registerParameter(const std::string& name, const std::string& description, double& parameter, double defaultValue = 0., bool isOptional = false); + /// Helper method to convert a bin number to a 1D position + double binToPosition(CellID 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; + + /// The cell ID encoder and decoder mutable BitField64* _decoder; - /// keeps track of the decoder ownership + /// Keeps track of the decoder ownership bool _ownsDecoder; - /// the segmentation name + /// The segmentation name std::string _name; - /// the segmentation type + /// The segmentation type std::string _type; - /// distinguish between local and global coordinate systems - bool _isLocal; + /// The description of the segmentation + std::string _description; - /// 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; +private: + /// The parameters for this segmentation + std::map<std::string, SegmentationParameter*> _parameters; }; +/// Macro to instantiate a new SegmentationCreator by its type name +#define REGISTER_SEGMENTATION(classname) \ + static const SegmentationCreator<classname> classname##_creator(#classname); + } /* namespace DDSegmentation */ } /* namespace DD4hep */ #endif /* DDSegmentation_SEGMENTATION_H_ */ diff --git a/DDSegmentation/include/DDSegmentation/SegmentationFactory.h b/DDSegmentation/include/DDSegmentation/SegmentationFactory.h new file mode 100644 index 0000000000000000000000000000000000000000..8991cba888f8fb348f3b6db7474f9607862fff72 --- /dev/null +++ b/DDSegmentation/include/DDSegmentation/SegmentationFactory.h @@ -0,0 +1,77 @@ +/* + * SegmentationFactory.h + * + * Factory and helper classes to allow instantiation of segmentations by name. + * + * Created on: Dec 15, 2013 + * Author: Christian Grefe, CERN + */ + +#ifndef DDSegmentation_SEGMENTATIONFACTORY_H_ +#define DDSegmentation_SEGMENTATIONFACTORY_H_ + +#include "DDSegmentation/Segmentation.h" + +#include <map> +#include <vector> +#include <string> + +namespace DD4hep { +namespace DDSegmentation { + +/// Forward declaration required because of circular dependency +class Segmentation; +class SegmentationCreatorBase; + +/// Base class for the SegmentationCreator objects. Allows to use the factory without template. +class SegmentationCreatorBase { +public: + /// Default constructor. Takes the class name as argument and takes care of registration with the factory + SegmentationCreatorBase(const std::string& name); + /// Destructor + virtual ~SegmentationCreatorBase() {}; + /// Create a new object + virtual Segmentation* create() const = 0; +}; + +/// Concrete class to create segmentation objects. Every segmentation needs to instantiate a static instance of this. +template<class TYPE> class SegmentationCreator : public SegmentationCreatorBase { +public: + /// Default constructor. Takes the class name as argument which should match the class type + SegmentationCreator<TYPE>(const std::string& name) : SegmentationCreatorBase(name) {}; + /// Destructor + virtual ~SegmentationCreator() {}; + /// Create a new object of the given type. + Segmentation* create() const {return new TYPE("");}; +}; + +/// Factory for creating segmentation objects by type name +class SegmentationFactory { + /// Allow SegmentationCreators to register themselves with the factory + friend class SegmentationCreatorBase; +public: + /// Access to the global factory instance + static SegmentationFactory* instance(); + /// Create a new segmentation object with the given type name. Returns NULL if type name is unknown. + Segmentation* create(const std::string& name) const; + /// Access to the list of registered segmentations + std::vector<std::string> registeredSegmentations() const; +protected: + /// Default constructor + SegmentationFactory() {}; + /// Copy constructor + SegmentationFactory(const SegmentationFactory&) {}; + /// Destructor + virtual ~SegmentationFactory() {}; + /// Registers a new SegmentationCreator with the factory + void registerSegmentation(const std::string& name, SegmentationCreatorBase* creator); + /// Map to store SegmentationCreators by name + std::map<std::string, SegmentationCreatorBase*> _segmentations; +private: + /// The global factory instance + static SegmentationFactory* _instance; +}; + +} /* namespace DDSegmentation */ +} /* namespace DD4hep */ +#endif /* DDSegmentation_SEGMENTATIONFACTORY_H_ */ diff --git a/DDSegmentation/include/DDSegmentation/SegmentationParameter.h b/DDSegmentation/include/DDSegmentation/SegmentationParameter.h new file mode 100644 index 0000000000000000000000000000000000000000..1b9e09f44e6dba915bc780628f8bc69363e3a0c3 --- /dev/null +++ b/DDSegmentation/include/DDSegmentation/SegmentationParameter.h @@ -0,0 +1,53 @@ +/* + * SegmentationParameter.h + * + * Helper class to hold a segmentation parameter with its description. + * + * Created on: Dec 16, 2013 + * Author: Christian Grefe, CERN + */ + +#ifndef DDSegmentation_SEGMENTATIONPARAMETER_H_ +#define DDSegmentation_SEGMENTATIONPARAMETER_H_ + +#include <string> + +namespace DD4hep { +namespace DDSegmentation { + +/// Class to hold a segmentation parameter with its description +class SegmentationParameter { +public: + /// Default constructor + SegmentationParameter(const std::string& name, const std::string& description, double& parameter, + double defaultValue = 0., bool isOptional = false); + /// Destructor + virtual ~SegmentationParameter() {}; + /// Access to the parameter name + const std::string& name() const; + /// Access to the parameter description + const std::string& description() const; + /// Access to the parameter value + double& value(); + /// Access to the parameter value + double value() const; + /// Check if this parameter is optional + bool isOptional() const; + /// Printable version + std::string toString() const; +protected: + /// The parameter name + std::string _name; + /// The parameter description + std::string _description; + /// The parameter value + double& _parameter; + /// The parameter default value + double _defaultValue; + /// Store if parameter is optional + bool _isOptional; +}; + +} /* namespace DDSegmentation */ +} /* namespace DD4hep */ +#endif /* DDSegmentation_SEGMENTATIONPARAMETER_H_ */ diff --git a/DDSegmentation/include/DDSegmentation/SegmentationUtil.h b/DDSegmentation/include/DDSegmentation/SegmentationUtil.h index 267b405706f331291645b92dc6d912329f9e600d..a310a7f449a39d0522dcd61053919ad319e33aa1 100644 --- a/DDSegmentation/include/DDSegmentation/SegmentationUtil.h +++ b/DDSegmentation/include/DDSegmentation/SegmentationUtil.h @@ -13,13 +13,13 @@ namespace DD4hep { namespace DDSegmentation { -namespace SegmentationUtil { +namespace Util { /////////////////////////////////////////////////////////////////////// /// Conventions /// /// - x, y, z are the Cartesian coordinates /// /// - r is the magnitude in the xy-plane /// -/// - rho is the magnitude /// +/// - mag is the magnitude /// /////////////////////////////////////////////////////////////////////// @@ -29,270 +29,70 @@ namespace SegmentationUtil { /// 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); +double magFromXYZ(const Position& position) { + return std::sqrt(position.X * position.X + position.Y * position.Y + position.Z * position.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]); +double radiusFromXYZ(const Position& position) { + return std::sqrt(position.X * position.X + position.Y * position.Y); } -/// 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]); +double thetaFromXYZ(const Position& position) { + return std::acos(position.Z / radiusFromXYZ(position)); } - -/// 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]); +double phiFromXYZ(const Position& position) { + return std::atan2(position.Y, position.X); } - ///////////////////////////////////////////////////////////// /// 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]); +Position positionFromRPhiZ(double r, double phi, double z) { + return Position(r * std::cos(phi), r * std::sin(phi), z); } - /// calculates the radius in xyz from cylindrical coordinates -template <typename TYPE> TYPE getRhoFromRPhiZ(TYPE r, TYPE phi, TYPE z) { +double magFromRPhiZ(double r, double phi, double 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) { +double xFromRPhiZ(double r, double phi, double 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) { +double yFromRPhiZ(double r, double phi, double 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) { +double thetaFromRPhiZ(double r, double phi, double 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]); +Position positionFromRThetaPhi(double r, double theta, double phi) { + return Position(r * std::cos(phi), r * std::sin(phi), r * std::tan(theta)); } -/// 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]); +Position 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)); } -/// 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 Util */ } /* namespace DDSegmentation */ } /* namespace DD4hep */ diff --git a/DDSegmentation/src/CartesianGrid.cpp b/DDSegmentation/src/CartesianGrid.cpp index 55b97022051fa0e7408518444d7c4930bcbff67e..6e9d97947a3dcf42686343ad3510836f2e4e8e93 100644 --- a/DDSegmentation/src/CartesianGrid.cpp +++ b/DDSegmentation/src/CartesianGrid.cpp @@ -12,33 +12,13 @@ namespace DDSegmentation { using std::string; -/// default constructor using an encoding string -template<> CartesianGrid::CartesianGrid(const string& cellEncoding) : +/// Default constructor used by derived classes passing the encoding string +CartesianGrid::CartesianGrid(const string& cellEncoding) : Segmentation(cellEncoding) { - } -/// default constructor using an encoding string -template<> CartesianGrid::CartesianGrid(string cellEncoding) : - Segmentation(cellEncoding) { - -} - -/// default constructor using an encoding string -template<> CartesianGrid::CartesianGrid(const char* cellEncoding) : - Segmentation(cellEncoding) { - -} - -/// default constructor using an existing decoder -template<> CartesianGrid::CartesianGrid(BitField64* decoder) : - Segmentation(decoder) { - -} - -/// destructor +/// Destructor CartesianGrid::~CartesianGrid() { - } } /* namespace DDSegmentation */ diff --git a/DDSegmentation/src/CartesianGridXY.cpp b/DDSegmentation/src/CartesianGridXY.cpp index 33a8059ffd48a177c3021639f83f118e0a3ca029..a345ada3f0b7a760a448bc7e7a131669bffc687b 100644 --- a/DDSegmentation/src/CartesianGridXY.cpp +++ b/DDSegmentation/src/CartesianGridXY.cpp @@ -10,40 +10,22 @@ namespace DD4hep { namespace DDSegmentation { -using std::make_pair; using std::string; -using std::vector; /// default constructor using an encoding string -template<> CartesianGridXY::CartesianGridXY(const string& cellEncoding, double gridSizeX, double gridSizeY, double offsetX, - 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 encoding string -template<> CartesianGridXY::CartesianGridXY(string cellEncoding, double gridSizeX, double gridSizeY, double offsetX, - 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"; -} +CartesianGridXY::CartesianGridXY(const string& cellEncoding) : + CartesianGrid(cellEncoding) { + // define type and description + _type = "CartesianGridXY"; + _description = "Cartesian segmentation in the local XY-plane"; -/// default constructor using an encoding string -template<> CartesianGridXY::CartesianGridXY(const char* cellEncoding, double gridSizeX, double gridSizeY, double offsetX, - 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 -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"; + // register all necessary parameters + registerParameter("gridSizeX", "Cell size in X", _gridSizeX, 1.); + registerParameter("gridSizeY", "Cell size in Y", _gridSizeY, 1.); + registerParameter("offsetX", "Cell offset in X", _offsetX, 0., true); + registerParameter("offsetY", "Cell offset in Y", _offsetY, 0., true); + _xId = "x"; + _yId = "y"; } /// destructor @@ -52,32 +34,23 @@ CartesianGridXY::~CartesianGridXY() { } /// determine the position based on the cell ID -vector<double> CartesianGridXY::getPosition(const long64& cellID) const { +Position CartesianGridXY::position(const CellID& cellID) const { _decoder->setValue(cellID); - vector<double> localPosition(3); - localPosition[0] = binToPosition((*_decoder)[_xId].value(), _gridSizeX, _offsetX); - localPosition[1] = binToPosition((*_decoder)[_yId].value(), _gridSizeY, _offsetY); - localPosition[2] = 0.; - return localPosition; + Position 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 -long64 CartesianGridXY::getCellID(double x, double y, double z) const { +CellID CartesianGridXY::cellID(const Position& localPosition, const Position& globalPosition, const VolumeID& volumeID) const { _decoder->reset(); - (*_decoder)[_xId] = positionToBin(x, _gridSizeX, _offsetX); - (*_decoder)[_yId] = positionToBin(y, _gridSizeY, _offsetY); + (*_decoder)[_xId] = positionToBin(localPosition.X, _gridSizeX, _offsetX); + (*_decoder)[_yId] = positionToBin(localPosition.Y, _gridSizeY, _offsetY); return _decoder->getValue(); } -/// access the set of parameters for this segmentation -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; -} +REGISTER_SEGMENTATION(CartesianGridXY) } /* namespace DDSegmentation */ } /* namespace DD4hep */ diff --git a/DDSegmentation/src/CartesianGridXYZ.cpp b/DDSegmentation/src/CartesianGridXYZ.cpp index 393685b23ef9ac041ba6b8d440b62a95766befd5..52484839970226e506848a818fd488287b7d81b3 100644 --- a/DDSegmentation/src/CartesianGridXYZ.cpp +++ b/DDSegmentation/src/CartesianGridXYZ.cpp @@ -10,40 +10,19 @@ namespace DD4hep { namespace DDSegmentation { -using std::make_pair; using std::string; -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, 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 encoding string -template<> CartesianGridXYZ::CartesianGridXYZ(string cellEncoding, double gridSizeX, double gridSizeY, double gridSizeZ, - 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"; -} +CartesianGridXYZ::CartesianGridXYZ(const string& cellEncoding) : + CartesianGridXY(cellEncoding) { + // define type and description + _type = "CartesianGridXYZ"; + _description = "Cartesian segmentation in the local coordinates"; -/// default constructor using an encoding string -template<> CartesianGridXYZ::CartesianGridXYZ(const char* cellEncoding, double gridSizeX, double gridSizeY, double gridSizeZ, - 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 -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"; + // register all necessary parameters + registerParameter("gridSizeZ", "Cell size in Z", _gridSizeZ, 1.); + registerParameter("offsetZ", "Cell offset in Z", _offsetZ, 0., true); + _zId = "z"; } /// destructor @@ -52,35 +31,25 @@ CartesianGridXYZ::~CartesianGridXYZ() { } /// determine the position based on the cell ID -vector<double> CartesianGridXYZ::getPosition(const long64& cellID) const { +Position CartesianGridXYZ::position(const CellID& cellID) const { _decoder->setValue(cellID); - vector<double> localPosition(3); - localPosition[0] = binToPosition((*_decoder)[_xId].value(), _gridSizeX, _offsetX); - localPosition[1] = binToPosition((*_decoder)[_yId].value(), _gridSizeY, _offsetY); - localPosition[2] = binToPosition((*_decoder)[_zId].value(), _gridSizeZ, _offsetZ); - return localPosition; + Position 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); + return position; } /// determine the cell ID based on the position -long64 CartesianGridXYZ::getCellID(double x, double y, double z) const { +CellID CartesianGridXYZ::cellID(const Position& localPosition, const Position& globalPosition, const VolumeID& volumeID) const { _decoder->reset(); - (*_decoder)[_xId] = positionToBin(x, _gridSizeX, _offsetX); - (*_decoder)[_yId] = positionToBin(y, _gridSizeY, _offsetY); - (*_decoder)[_zId] = positionToBin(z, _gridSizeZ, _offsetZ); + (*_decoder)[_xId] = positionToBin(localPosition.X, _gridSizeX, _offsetX); + (*_decoder)[_yId] = positionToBin(localPosition.Y, _gridSizeY, _offsetY); + (*_decoder)[_zId] = positionToBin(localPosition.Z, _gridSizeZ, _offsetZ); return _decoder->getValue(); } -/// access the set of parameters for this segmentation -Parameters CartesianGridXYZ::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("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; -} +REGISTER_SEGMENTATION(CartesianGridXYZ) } /* namespace DDSegmentation */ } /* namespace DD4hep */ diff --git a/DDSegmentation/src/CartesianGridXZ.cpp b/DDSegmentation/src/CartesianGridXZ.cpp index 8c46746b9276e20f6aad1c0e658f872b8ed4f407..61ec209c1dafe80cef21d3a9131ef3e70a441841 100644 --- a/DDSegmentation/src/CartesianGridXZ.cpp +++ b/DDSegmentation/src/CartesianGridXZ.cpp @@ -15,35 +15,19 @@ 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"; -} +CartesianGridXZ::CartesianGridXZ(const string& cellEncoding) : + CartesianGrid(cellEncoding) { + // define type and description + _type = "CartesianGridXY"; + _description = "Cartesian segmentation in the local XY-plane"; -/// 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"; + // register all necessary parameters + registerParameter("gridSizeX", "Cell size in X", _gridSizeX, 1.); + registerParameter("gridSizeZ", "Cell size in Z", _gridSizeZ, 1.); + registerParameter("offsetX", "Cell offset in X", _offsetX, 0., true); + registerParameter("offsetZ", "Cell offset in Z", _offsetZ, 0., true); + _xId = "x"; + _zId = "y"; } /// destructor @@ -52,32 +36,24 @@ CartesianGridXZ::~CartesianGridXZ() { } /// determine the position based on the cell ID -vector<double> CartesianGridXZ::getPosition(const long64& cellID) const { +Position CartesianGridXZ::position(const CellID& 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; + Position 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 -long64 CartesianGridXZ::getCellID(double x, double y, double z) const { +CellID CartesianGridXZ::cellID(const Position& localPosition, const Position& globalPosition, const VolumeID& volumeID) const { _decoder->reset(); - (*_decoder)[_xId] = positionToBin(x, _gridSizeX, _offsetX); - (*_decoder)[_zId] = positionToBin(z, _gridSizeZ, _offsetZ); + (*_decoder)[_xId] = positionToBin(localPosition.X, _gridSizeX, _offsetX); + (*_decoder)[_zId] = positionToBin(localPosition.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; -} +REGISTER_SEGMENTATION(CartesianGridXZ) } /* namespace DDSegmentation */ } /* namespace DD4hep */ diff --git a/DDSegmentation/src/CylindricalSegmentation.cpp b/DDSegmentation/src/CylindricalSegmentation.cpp index ad79bb1709ed7ead6fb550ca33f2f1f8e7f015d4..f14443cc6397c624fecaf189e09c57c8c9baff98 100644 --- a/DDSegmentation/src/CylindricalSegmentation.cpp +++ b/DDSegmentation/src/CylindricalSegmentation.cpp @@ -7,59 +7,20 @@ #include "DDSegmentation/CylindricalSegmentation.h" -#include <sstream> -#include <stdexcept> +using std::string; 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; +CylindricalSegmentation::CylindricalSegmentation(const string& cellEncoding) : + Segmentation(cellEncoding) { } - /// destructor CylindricalSegmentation::~CylindricalSegmentation() { } -/// determine the radius based on the cell ID -double 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 index 686bc588b94beb9705bfea702f198d2163af3b32..6793435a876190fb3311492985cf7bb20b5022ca 100644 --- a/DDSegmentation/src/ProjectiveCylinder.cpp +++ b/DDSegmentation/src/ProjectiveCylinder.cpp @@ -15,40 +15,21 @@ 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"; -} +ProjectiveCylinder::ProjectiveCylinder(const string& cellEncoding) : + CylindricalSegmentation(cellEncoding) { + // define type and description + _type = "ProjectiveCylinder"; + _description = "Projective segmentation in the global coordinates"; -/// 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"; + // register all necessary parameters + registerParameter("thetaBins", "Number of bins theta", _thetaBins, 1.); + registerParameter("phiBins", "Number of bins phi", _phiBins, 1.); + registerParameter("offsetTheta", "Angular offset in theta", _offsetTheta, 0., true); + registerParameter("offsetPhi", "Angular offset in phi", _offsetPhi, 0., true); + _thetaID = "theta"; + _phiID = "phi"; } /// destructor @@ -57,29 +38,28 @@ ProjectiveCylinder::~ProjectiveCylinder() { } /// determine the local based on the cell ID -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); +Position ProjectiveCylinder::position(const long64& cellID) const { + return Util::positionFromRThetaPhi(1.0, theta(cellID), phi(cellID)); } /// determine the cell ID based on the position -long64 ProjectiveCylinder::getCellID(double x, double y, double z) const { +CellID ProjectiveCylinder::cellID(const Position& localPosition, const Position& globalPosition, const VolumeID& volumeID) const { // TODO return 0; } /// determine the polar angle theta based on the cell ID -double ProjectiveCylinder::getTheta(const long64& cellID) const { +double ProjectiveCylinder::theta(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 { +double ProjectiveCylinder::phi(const long64& cellID) const { int phiIndex = (*_decoder)[_phiID].value(); return 2. * M_PI * ((double) phiIndex + 0.5) / (double) _phiBins; } +REGISTER_SEGMENTATION(ProjectiveCylinder) + } /* namespace DDSegmentation */ } /* namespace DD4hep */ diff --git a/DDSegmentation/src/Segmentation.cpp b/DDSegmentation/src/Segmentation.cpp index 29a4fe3ad48e1d2c1f0c5f1eeabf90b2c0ae9a81..ce91a8c3f994f6e6a897e67b01c99037e9e6732c 100644 --- a/DDSegmentation/src/Segmentation.cpp +++ b/DDSegmentation/src/Segmentation.cpp @@ -7,86 +7,125 @@ #include "DDSegmentation/Segmentation.h" +#include <iostream> +#include <sstream> #include <stdexcept> namespace DD4hep { namespace DDSegmentation { +using std::cerr; +using std::endl; +using std::map; using std::string; +using std::stringstream; using std::vector; -/// default constructor using an encoding string -template<> Segmentation::Segmentation(std::string cellEncoding) { - _decoder = new BitField64(cellEncoding); - _ownsDecoder = true; - _type = "segmentation"; - _isLocal = true; +/// Default constructor used by derived classes passing the encoding string +Segmentation::Segmentation(const string& cellEncoding) : + _name("Segmentation"), _type("Segmentation"), _decoder(new BitField64(cellEncoding)), _ownsDecoder(true) { } -/// default constructor using an encoding string -template<> Segmentation::Segmentation(const std::string& cellEncoding) { - _decoder = new BitField64(cellEncoding); - _ownsDecoder = true; - _type = "segmentation"; - _isLocal = true; -} - -/// default constructor using an encoding string -template<> Segmentation::Segmentation(const char* cellEncoding) { - _decoder = new BitField64(cellEncoding); - _ownsDecoder = true; - _type = "segmentation"; - _isLocal = true; +/// Destructor +Segmentation::~Segmentation() { + if (_ownsDecoder and _decoder != 0) { + delete _decoder; + } + map<string, SegmentationParameter*>::iterator it; + for (it = _parameters.begin(); it != _parameters.end(); ++it) { + SegmentationParameter* p = it->second; + if (p) { + delete p; + p = 0; + } + } } -/// default constructor using an existing decoder -template<> Segmentation::Segmentation(BitField64* decoder) { +/// Set the underlying decoder +void Segmentation::setDecoder(BitField64* decoder) { + if (_ownsDecoder and _decoder != 0) { + std::cout << _decoder << std::endl; + delete _decoder; + } _decoder = decoder; _ownsDecoder = false; - _type = "segmentation"; - _isLocal = true; } -/// destructor -Segmentation::~Segmentation() { - if (_ownsDecoder and _decoder != 0) { - delete _decoder; +/// Access to parameter by name +SegmentationParameter* Segmentation::parameter(const std::string& parameterName) { + map<string, SegmentationParameter*>::iterator it; + it = _parameters.find(parameterName); + if (it != _parameters.end()) { + return it->second; } + stringstream s; + s << "Unknown parameter " << parameterName << " for segmentation type " << _type; + throw std::runtime_error(s.str()); } - -/// 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!"); +/// Access to parameter by name +const SegmentationParameter* Segmentation::parameter(const std::string& parameterName) const { + map<string, SegmentationParameter*>::const_iterator it; + it = _parameters.find(parameterName); + if (it != _parameters.end()) { + return it->second; } - return getCellID(position[0], position[1], position[2]); + stringstream s; + s << "Unknown parameter " << parameterName << " for segmentation type " << _type; + throw std::runtime_error(s.str()); } -/// determine the cell ID based on the position -long64 Segmentation::getCellID(const double* position) const { - return getCellID(position[0], position[1], position[2]); +/// Access to parameter values by name +double Segmentation::parameterValue(const std::string& parameterName) const { + return this->parameter(parameterName)->value(); } -/// set the underlying decoder -void Segmentation::setDecoder(BitField64* decoder) { - if (_ownsDecoder and _decoder != 0) { - delete _decoder; +/// Set the parameter value by name +void Segmentation::setParameterValue(const std::string& parameterName, double value) { + this->parameter(parameterName)->value() = value; +} + +/// Access to all parameters +//Parameters Segmentation::parameters() const { +// Parameters parameters; +// map<string, SegmentationParameter*>::const_iterator it; +// for (it = _parameters.begin(); it != _parameters.end(); ++it) { +// parameters.push_back(std::make_pair(it->first, it->second->value())); +// } +// return parameters; +//} + +/// Access to all parameters +vector<SegmentationParameter*> Segmentation::parameters() { + vector<SegmentationParameter*> parameters; + map<string, SegmentationParameter*>::iterator it; + for (it = _parameters.begin(); it != _parameters.end(); ++it) { + parameters.push_back(it->second); } - _decoder = decoder; - _ownsDecoder = false; + return parameters; +} + +/// Access to all parameters +vector<const SegmentationParameter*> Segmentation::parameters() const { + vector<const SegmentationParameter*> parameters; + map<string, SegmentationParameter*>::const_iterator it; + for (it = _parameters.begin(); it != _parameters.end(); ++it) { + parameters.push_back(it->second); + } + return parameters; } -/// access the set of parameters for this segmentation -Parameters Segmentation::parameters() const { - return Parameters(); +/// Add a parameter to this segmentation. Used by derived classes to define their parameters +void Segmentation::registerParameter(const std::string& name, const std::string& description, double& parameter, double defaultValue, bool isOptional) { + _parameters[name] = new SegmentationParameter(name, description, parameter, defaultValue, isOptional); } -/// helper method to convert a bin number to a 1D position + +/// Helper method to convert a bin number to a 1D position double Segmentation::binToPosition(long64 bin, double cellSize, double offset) const { return bin * cellSize + offset; } -/// helper method to convert a 1D position to a cell ID +/// Helper method to convert a 1D position to a cell ID int Segmentation::positionToBin(double position, double cellSize, double offset) const { if (cellSize == 0.) { throw std::runtime_error("Invalid cell size: 0.0"); diff --git a/DDSegmentation/src/SegmentationFactory.cpp b/DDSegmentation/src/SegmentationFactory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..491527e610d5cf9457e8532e7a0b7d4f8b3e5f9c --- /dev/null +++ b/DDSegmentation/src/SegmentationFactory.cpp @@ -0,0 +1,59 @@ +/* + * SegmentationFactory.cpp + * + * Created on: Dec 15, 2013 + * Author: Christian Grefe, CERN + */ + +#include "DDSegmentation/SegmentationFactory.h" + +namespace DD4hep { +namespace DDSegmentation { + +using std::map; +using std::vector; +using std::string; + +/// Default constructor. Takes the class name as argument and takes care of registration with the factory +SegmentationCreatorBase::SegmentationCreatorBase(const string& name) { + SegmentationFactory::instance()->registerSegmentation(name, this); +} + +/// Initialize the global factory instance +SegmentationFactory* SegmentationFactory::_instance = 0; + +/// Access to the global factory instance +SegmentationFactory* SegmentationFactory::instance() { + if (not _instance) { + _instance = new SegmentationFactory(); + } + return _instance; +} + +/// Create a new segmentation object with the given type name. Returns NULL if type name is unknown. +Segmentation* SegmentationFactory::create(const string& name) const { + map<string, SegmentationCreatorBase*>::const_iterator it; + it = _segmentations.find(name); + if (it != _segmentations.end()) { + return it->second->create(); + } + return 0; +} + +/// Access to the list of registered segmentations +vector<string> SegmentationFactory::registeredSegmentations() const { + vector<string> segmentationNames; + map<string, SegmentationCreatorBase*>::const_iterator it; + for (it = _segmentations.begin(); it != _segmentations.end(); ++ it) { + segmentationNames.push_back(it->first); + } + return segmentationNames; +} + +/// Registers a new SegmentationCreator with the factory +void SegmentationFactory::registerSegmentation(const string& name, SegmentationCreatorBase* creator) { + _segmentations[name] = creator; +} + +} /* namespace DDSegmentation */ +} /* namespace DD4hep */ diff --git a/DDSegmentation/src/SegmentationParameter.cpp b/DDSegmentation/src/SegmentationParameter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a172d9b70ebda4828fdb551b333ecd945fce2179 --- /dev/null +++ b/DDSegmentation/src/SegmentationParameter.cpp @@ -0,0 +1,62 @@ +/* + * SegmentationParameter.cpp + * + * Created on: Dec 16, 2013 + * Author: Christian Grefe, CERN + */ + +#include "DDSegmentation/SegmentationParameter.h" + +#include <sstream> + +namespace DD4hep { +namespace DDSegmentation { + +using std::string; +using std::stringstream; + +/// Default constructor +SegmentationParameter::SegmentationParameter(const string& name, const string& description, double& parameter, + double defaultValue, bool isOptional) : + _name(name), _description(description), _parameter(parameter), _defaultValue(defaultValue), _isOptional( + isOptional) { + _parameter = defaultValue; +} + +/// Access to the parameter name +const string& SegmentationParameter::name() const { + return _name; +} + +/// Access to the parameter description +const string& SegmentationParameter::SegmentationParameter::description() const { + return _description; +} + +/// Access to the parameter value +double& SegmentationParameter::value() { + return _parameter; +} + +/// Access to the parameter value +double SegmentationParameter::value() const { + return _parameter; +} + +/// Check if this parameter is optional +bool SegmentationParameter::isOptional() const { + return _isOptional; +} + +/// Printable version +string SegmentationParameter::toString() const { + stringstream s; + s << _name << " = " << _parameter; + if (not _description.empty()) { + s << " (" << _description << ")"; + } + return s.str(); +} + +} /* namespace DDSegmentation */ +} /* namespace DD4hep */ diff --git a/examples/CLICSiD/compact/BarrelCalorimeter.xml b/examples/CLICSiD/compact/BarrelCalorimeter.xml index 84a73e42c5a4e0fafa9b5790ea9789ae2692c2ff..88f952b7e2d02236a62c0a06c6a9f95ae4a95006 100644 --- a/examples/CLICSiD/compact/BarrelCalorimeter.xml +++ b/examples/CLICSiD/compact/BarrelCalorimeter.xml @@ -396,7 +396,7 @@ <readouts> <readout name="MuonBarrelHits"> - <segmentation type="RegularNgonCartesianGridXY" gridSizeX="3.0*cm" gridSizeY="3.0*cm" /> + <segmentation type="CartesianGridXY" gridSizeX="3.0*cm" gridSizeY="3.0*cm" /> <id>system:8,barrel:3,module:4,layer:8,slice:5,x:32:-16,y:-16</id> </readout> <!-- diff --git a/examples/Segmentation/CMakeLists.txt b/examples/Segmentation/CMakeLists.txt index 2bf12ba95f68c3bece2ec5969f94d09ba21e0f9b..fb1cfa6c026e06bea4df357feb19f58fa8bef95f 100644 --- a/examples/Segmentation/CMakeLists.txt +++ b/examples/Segmentation/CMakeLists.txt @@ -63,9 +63,6 @@ endif() add_executable(Segmentation SegmentationTest.cpp ${sources}) -MESSAGE( STATUS "${DD4hep_LIBRARIES}" ) -MESSAGE( STATUS "${ROOT_LIBRARIES}" ) - target_link_libraries(Segmentation ${DD4hep_LIBRARIES} ) #---Rootmap generation-------------------------------------------------------------- diff --git a/examples/Segmentation/SegmentationTest.cpp b/examples/Segmentation/SegmentationTest.cpp index e4bea2ce1d5599a7745ad24c55f8d18d58a01375..238c30dfe6b49f57c08e17384a9edcbd3fcb309c 100644 --- a/examples/Segmentation/SegmentationTest.cpp +++ b/examples/Segmentation/SegmentationTest.cpp @@ -7,7 +7,8 @@ #include "DD4hep/LCDD.h" -#include "DDSegmentation/BitField64.h" +#include "DDSegmentation/SegmentationFactory.h" +#include "DDSegmentation/SegmentationParameter.h" using namespace std; using namespace DD4hep; @@ -16,23 +17,20 @@ using namespace DDSegmentation; int main(int argc, char** argv) { - LCDD& lcdd = LCDD::getInstance(); - lcdd.fromCompact(argv[1]); - lcdd.apply("DD4hepVolumeManager",0,0); - - Readout ro = lcdd.readout("MuonBarrelHits"); - - BitField64 idEncoder(ro.idSpec().fieldDescription()); - idEncoder["system"] = 10; - idEncoder["barrel"] = 0; - idEncoder["layer"] = 15; - idEncoder["module"] = 8; - idEncoder["slice"] = 11; - idEncoder["x"] = 13; - idEncoder["y"] = -10; - long64 cellID = idEncoder.getValue(); - Position gp = ro.getPosition(cellID); - std::cout << "Global position: " << gp.x() << ", " << gp.y() << ", " << gp.z() << std::endl; - + SegmentationFactory* f = SegmentationFactory::instance(); + + cout << "Registered Segmentations:" << std::endl; + vector<string> segmentations = f->registeredSegmentations(); + vector<string>::const_iterator it; + for (it = segmentations.begin(); it != segmentations.end(); ++it) { + string typeName = *it; + DDSegmentation::Segmentation* s = f->create(typeName); + cout << "\t" << typeName << ", " << s->type() << endl; + Parameters parameters = s->parameters(); + Parameters::iterator it; + for (it = parameters.begin(); it != parameters.end(); ++it) { + cout << "\t\t" << it->first << " = " << it->second << endl; + } + } return 0; };