#ifndef __IECALMapPointer__ #define __IECALMapPointer__ #include #include "TVector3.h" #include "IChannelId.hxx" #include "EoaGeomInfo.hxx" #include "IECALChannelMap.hxx" namespace COMET { template class IECALMapPointer; class IGeometryId; OA_EXCEPTION(EInvalidPointerComparison_Between_DiffMaps, EoaGeomInfo); } // For avoiding mutual reference with IGeomInfo TVector3 _IECALMapPointer_GetGlobalPosition(const COMET::IChannelId* chanId); TVector3 _IECALMapPointer_GetLocalPosition (const COMET::IChannelId* chanId); //=================================================================== // IECALMapPointer //=================================================================== template class COMET::IECALMapPointer { private: typedef std::vector ITMapCol; typedef std::vector ITMap; ITMap* fpMap; const std::vector< std::vector >* fpIndexChanIdMap; int fSizeX, fSizeY; int fX, fY; ///< Pointing index T fDummy; ///< Dummy object returned when outside of map is referred. private: inline bool Contains(const int x, const int y) const { if(not fpMap || not fpIndexChanIdMap) return false; return (x >= 0 && x < fSizeX && y >= 0 && y < fSizeY); } public: IECALMapPointer() : fpIndexChanIdMap(NULL), fpMap(NULL) {} IECALMapPointer(ITMap* pMap, const std::vector< std::vector >* pICMap) : fpIndexChanIdMap(pICMap), fDummy(T()) { SetMap(pMap); } ~IECALMapPointer() {} void SetMap(ITMap* pMap); void SetDummy(const T& dummy){ fDummy = dummy; } int GetX() const {return fX;} int GetY() const {return fY;} void GetXY(int& x, int&y) const { x=fX; y=fY; } T* operator -> () {return ( Contains(fX,fY)? &((*fpMap)[fX][fY]) : &fDummy );} T& operator * () {return ( Contains(fX,fY)? (*fpMap)[fX][fY] : fDummy ); } const T* operator -> () const {return ( Contains(fX,fY)? &((*fpMap)[fX][fY]) : &fDummy );} const T& operator * () const {return ( Contains(fX,fY)? (*fpMap)[fX][fY] : fDummy ); } void operator += (const int dx); void operator -= (const int dx) {this->operator+=(-dx);} void operator ++ () {this->operator+=(+1);} void operator -- () {this->operator+=(-1);} void operator ++ (int) {this->operator+=(+1);} void operator -- (int) {this->operator+=(-1);} /// Comparator for std::set bool operator < (const IECALMapPointer& right) const { if( fpMap != right.fpMap ) throw COMET::EInvalidPointerComparison_Between_DiffMaps(); return ( (fY*fSizeX + fX) < (right.fY*right.fSizeX + right.fX) ); } void GoTo(const int x, const int y) {fX = x; fY = y;} void Shift(const int dx, const int dy) {fX+=dx; fY+=dy;} void ShiftX(const int dx) {Shift(dx,0);} void ShiftY(const int dy) {Shift(0,dy);} bool IsIn() const {return Contains(fX,fY);} void Reset() { fX = fY = 0; } /// This supposes to be used after using only Reset() and operator++ bool IsEnd() const {return (fY >= fSizeY); } IECALMapPointer GetNeighbor(const int dx, const int dy) { IECALMapPointer ret = *this; ret.Shift(dx, dy); return ret; } /// Return the channel id at this point const COMET::IChannelId* GetChannelId() const { if(fpIndexChanIdMap && Contains(fX, fY)) return (*fpIndexChanIdMap)[fX][fY]; else return NULL; } /// Return the geometry id at this point /// The returned pointer's destination will be changed by next calling const COMET::IGeometryId* GetGeometryId() const { COMET::IChannelId* chanId = GetChannelId(); if(chanId){ static COMET::IGeometryId geomId; if(COMET::IECALChannelMap::Get().GetGeometryId(geomId, (COMET::IECALChannelId)*chanId)) return &geomId; } return NULL; } /// Return the global position at this point TVector3 GetGlobalPosition() const { return _IECALMapPointer_GetGlobalPosition(GetChannelId()); } /// Return the ECAL-local position at this point TVector3 GetLocalPosition() const { return _IECALMapPointer_GetLocalPosition(GetChannelId()); } }; template void COMET::IECALMapPointer::SetMap(ITMap* pMap) { fpMap = pMap; fSizeX = fpMap->size(); if(fSizeX>0) fSizeY = fpMap->at(0).size(); else fSizeY = 0; Reset(); } template void COMET::IECALMapPointer::operator += (const int dx) { if(0 == dx) return; else if (0 < dx){ if(fSizeX <= fX + dx) fY++; } else{ if(0 > fX + dx) fY--; } fX = (fSizeX + fX + dx) % fSizeX; } // ------------------------------------------------------------- // Comparators for std::set // ------------------------------------------------------------- template bool operator < (const COMET::IECALMapPointer& left, const COMET::IECALMapPointer& right) { return left.operator < (right); } template bool operator == (const COMET::IECALMapPointer& left, const COMET::IECALMapPointer& right) { return (not left.operator < (right)) && (not right.operator < (left)); } #endif