#ifndef TECALCrystalManager_hxx #define TECALCrystalManager_hxx #include #include #include #include class TGeoManager; class TGeoNode; class TVector2; class TVector3; namespace COMET { class IECALCrystalManager; class IECALCrystalInfo; class IChannelId; class IECALGeom; class IECALCrystalInfoMap; struct IECALCrystalNeighborIndex; } //========================================================================= // ICrystalNeighborIndex //========================================================================= struct COMET::IECALCrystalNeighborIndex { /// @enum The correct index of fNeighbors /// /// Seen from the downstream side in the detector solenoid coordinate: /// +Y (Top) /// [1] [2] [3] /// -X <- [4] - [5] -> +X (beam comming from -Z) /// [6] [7] [8] /// -Y (Bottom) enum IIndex { kNone = 0, ///< None kTL = 1, ///< Top left kTC = 2, ///< Top centre kTR = 3, ///< Top right kML = 4, ///< Middle left kMR = 5, ///< Middle right kBL = 6, ///< Bottom left kBC = 7, ///< Bottom centre kBR = 8 ///< Bottom right } fIndex; IECALCrystalNeighborIndex(IIndex index = kNone) : fIndex(index) {} bool operator == (const IECALCrystalNeighborIndex& rhs) const{ return static_cast(fIndex) == static_cast(rhs.fIndex); } bool operator != (const IECALCrystalNeighborIndex& rhs) const{ return static_cast(fIndex) != static_cast(rhs.fIndex); } bool operator < (const IECALCrystalNeighborIndex& rhs) const{ return static_cast(fIndex) < static_cast(rhs.fIndex); } static IECALCrystalNeighborIndex Get(const int dx, const int dy); }; //========================================================================= // IECALCrystalInfo //========================================================================= class COMET::IECALCrystalInfo { public: /// Pointer mapping of the adjoinning crystals typedef std::map INeighbors; private: int fNodeId; int fSequenceId; COMET::IGeometryId fGeomId; int fBlockId; int fCrystalId; TVector3 fPosition; ///< Global position TVector2 f2dPosition; ///< 2 dimensional position on the ECAL plane /// Index on the 2d map int fIdxX, fIdxY; /// List of links to the adjoining crystals. See INeighbors. INeighbors fNeighbors; public: IECALCrystalInfo(); virtual ~IECALCrystalInfo(); public: int GetNodeId() const {return fNodeId;} int GetSequenceId() const {return fSequenceId;} COMET::IGeometryId GetGeometryId() const {return fGeomId;} int GetBlockId() const {return fBlockId;} int GetCrystalId() const {return fCrystalId;} TVector3 GetPosition() const {return fPosition;} TVector2 Get2dPosition() const {return f2dPosition;} int GetIdxX() const {return fIdxX;} int GetIdxY() const {return fIdxY;} void GetIdx(int& idxX, int& idxY) const { idxX = fIdxX; idxY = fIdxY; } /// Return pointer to a neighbor crystal info. const IECALCrystalInfo* GetNeighbor(IECALCrystalNeighborIndex idx) const { return (fNeighbors.find(idx) == fNeighbors.end())? NULL : fNeighbors.find(idx)->second; } const IECALCrystalInfo* GetNeighbor(const int dx, const int dy) const; const INeighbors& GetNeighbors() const {return fNeighbors;} int GetNumberOfNeighbors() const {return static_cast(fNeighbors.size());} void SetNodeId (const int nodeId) {fNodeId = nodeId;} void SetSequenceId (const int sequenceId) {fSequenceId = sequenceId;} void SetGeometryId (const COMET::IGeometryId& geomId) {fGeomId = geomId;} void SetBlockId (const int blockId) {fBlockId = blockId;} void SetCrystalId (const int crystalId) {fCrystalId = crystalId;} void SetPosition (const TVector3& position); /// Do not use as possible to avoid different global and 2d positions. void Set2dPosition (const TVector2& position){f2dPosition = position;} /// Set 2d Position from global position, while this is called by SetPosition(). /// Do not use as possible to avoid different global and 2d positions. void Set2dPosition (const TVector3& globalPosition); void SetIdx(const int idxX, const int idxY){ if(idxX >= 0) fIdxX = idxX; if(idxY >= 0) fIdxY = idxY; } void SetNeighbor(const IECALCrystalNeighborIndex idx, const IECALCrystalInfo* info){ if(idx != IECALCrystalNeighborIndex::kNone && info) fNeighbors[idx] = info; } }; //========================================================================= // IECALCrystalManager //========================================================================= class COMET::IECALCrystalManager { public: typedef std::vector < std::vector < int > > INodeIdMap; typedef std::vector ICrystalInfoContainer; typedef std::map ISequenceIdMap; private: int fNumberOfChannels; ///< All crystals int fNumberOfBlocks; ///< All blocks int fNumberOfCrystals; ///< Crystals per block INodeIdMap fNodeIdMap; ICrystalInfoContainer fCrystalInfo; ISequenceIdMap fSequenceIdMap; ///< Map of (NodeId, SequenceId) COMET::IECALCrystalInfoMap* fCrystalInfoMap; ///< Mapping of crystals for clustering public: IECALCrystalManager(); virtual ~IECALCrystalManager(); /// Initialise the ECAL configuration (number of blocks, and crystals) /// from the ROOT geometry and geometry id. int Init(const INodeIdMap& nodeMap); /// Similar with IGeomIdManager::GetGeometryId(), but adittionally special care is taken for ECAL bool GetGeomIdFromGlobalPosition(const TVector3& global, IGeometryId& id) const; /// Similar with IGeomIdManager::GetGeometryId(), but adittionally special care is taken for ECAL bool GetGeomIdFromGlobalPosition(const double* global, IGeometryId& id) const; /// Get geometry Id corresponding to the sequence Id bool GetGeomIdFromSequenceId(const int sequenceId, IGeometryId& id) const; int GetSequenceIdFromECAL (const int block, const int crystal) const; int GetSequenceIdFromGlobalPosition (const TVector3& global) const; int GetSequenceIdFromGlobalPosition (const double* global) const; int GetSequenceIdFromNodeId (const int nodeId) const; int GetSequenceIdFromChannelId (const IChannelId& chanId) const; int GetSequenceIdFromGeomId (const IGeometryId& geomId) const; int GetBlockIdFromSequenceId (const int sequenceId) const; int GetCrystalIdFromSequenceId (const int sequenceId) const; TGeoNode* GetNode (const int block, const int crystal) const; TVector3 GetCrystalPosition (const int sequenceId) const; TVector3 GetCrystalPosition (const IGeometryId& id) const; TVector3 GetCrystalPosition (const int block, const int crystal) const; int GetBlockIdFromGeomId (const IGeometryId& id) const; int GetCrystalIdFromGeomId (const IGeometryId& id) const; int GetNumberOfChannels () const {return fNumberOfChannels;} int GetNumberOfBlocks () const {return fNumberOfBlocks;} int GetNumberOfCrystals () const {return fNumberOfCrystals;} /// Return only const pointer to the crystal map const COMET::IECALCrystalInfoMap& GetCrystalInfoMap() const; bool SetNodeIdMap (const INodeIdMap& nodeMap); private: /// Make the copy constructor private. IECALCrystalManager(const IECALCrystalManager&) {MayNotUse("Copy Constructor");} /// return the CrystalInfo @ `wire`, return NULL if `wire` is out of range bool GetCrystalInfo(const int sequenceId, COMET::IECALCrystalInfo& info) const; }; #endif