#ifndef __IECALCrystalMap__ #define __IECALCrystalMap__ #include #include #include "TH2.h" #include "IECALChannelId.hxx" #include "EoaGeomInfo.hxx" #include "IECALCrystalManager.hxx" #include "IECALMapPointer.hxx" namespace COMET { class IECALCrystalInfo; class IECALCrystalMapBase; template class IECALCrystalMap; class IECALCrystalInfoMap; class IECALWritableCrystalInfoMap; OA_EXCEPTION(ENoChanIdIndexMapSet, EoaGeomInfo); OA_EXCEPTION(EInvalidECALChannelId, EoaGeomInfo); OA_EXCEPTION(EInvalidIndexOnMap, EoaGeomInfo); } //=================================================================== // IECALCrsytalMapBase //=================================================================== class COMET::IECALCrystalMapBase { protected: struct IIndex { int x, y; IIndex(int _x = 0, int _y = 0) : x(_x), y(_y) {} }; typedef std::map IChanIdIndexMap; typedef std::vector< std::vector< const COMET::IChannelId* > > IIndexChanIdMap; /// Size of the map (should be set by IECALCrystalMap). int fSizeX, fSizeY; /// Pointer to ChanIdIndexMap, set by IECALCrystalInfoMap::CreateMapWith() const IChanIdIndexMap* fpChanIdIndexMap; /// Pointer to IndexChanIdMap, set by IECALCrystalInfoMap::CreateMapWith() const IIndexChanIdMap* fpIndexChanIdMap; protected: /// Constructor IECALCrystalMapBase(int sizeX = 0, int sizeY = 0, const IChanIdIndexMap* pCIMap = NULL, const IIndexChanIdMap* pICMap = NULL) : fSizeX(sizeX), fSizeY(sizeY), fpChanIdIndexMap(pCIMap), fpIndexChanIdMap(pICMap) {} /// Destructor virtual ~IECALCrystalMapBase() {} /// Set pointer to the map, ChannelId -> index (x,y) /// that is needed for IECALCrystalMap::GetPointerAt() void SetChanIdIndexMap(const IChanIdIndexMap* map){ fpChanIdIndexMap = map; } /// Set pointer to the map, index (x,y) -> ChannelId void SetIndexChanIdMap(const IIndexChanIdMap* map){ fpIndexChanIdMap = map; } public: bool IsValid() const {return (not fpChanIdIndexMap || not fpIndexChanIdMap || 0==fSizeX || 0==fSizeY)? false:true; } int GetSizeX() const {return fSizeX;} int GetSizeY() const {return fSizeY;} /// Create a histogram of the map TH2* CreateHistogram(const char* name, const char* title) { if(IsValid()) return new TH2D(name, title, fSizeX, 0, fSizeX, fSizeY, 0, fSizeY); return NULL; } }; //=================================================================== // IECALCrsytalMap //=================================================================== template class COMET::IECALCrystalMap : public COMET::IECALCrystalMapBase { public: typedef T ContentType; typedef COMET::IECALMapPointer Pointer; protected: typedef std::vector< T > ITVector; typedef std::vector< ITVector > IMap; IMap fMap; ///< Map public: /// Constructor IECALCrystalMap(int sizeX = 0, int sizeY = 0, T* initValue = NULL, const IChanIdIndexMap* pCIMap = NULL, const IIndexChanIdMap* pICMap = NULL) : IECALCrystalMapBase(sizeX, sizeY, pCIMap, pICMap) { if(initValue) fMap = IMap(GetSizeX(), ITVector(GetSizeY(), *initValue)); else fMap = IMap(GetSizeX(), ITVector(GetSizeY())); } public: virtual ~IECALCrystalMap() {} /// Return true the given indices are valid for for the map. inline bool IsValidIndex(const int idxX, const int idxY) const { return (idxX >=0 && idxX < GetSizeX() && idxY >=0 && idxY < GetSizeY()); } /// Get crystal info at the given index virtual T Get(const int idxX, const int idxY) const { if(IsValidIndex(idxX,idxY)) return fMap[idxX][idxY]; throw EInvalidIndexOnMap(); } /// Operator interfacing to Get() virtual T operator() (const int idxX, const int idxY) const { return Get(idxX, idxY); } /// Operator to access like array ITVector& operator [] (const int& index){ return fMap[index]; } /// Return a map pointer Pointer GetPointer() { return Pointer(&fMap, fpIndexChanIdMap); } /// Return the map pointer of ChannelId on the map Pointer GetPointerAt(const COMET::IChannelId& chanId) { if(not fpChanIdIndexMap) throw ENoChanIdIndexMapSet(); typename IChanIdIndexMap::const_iterator it = fpChanIdIndexMap->find(chanId); if(it == fpChanIdIndexMap->end()) throw EInvalidECALChannelId(); // NO ECAL Channel Pointer point(&fMap, fpIndexChanIdMap); point.GoTo(it->second.x, it->second.y); return point; } /// Fill data to the given histogram (the histogram is not reset.) void FillToHist(TH2* hist) { for(int x=0; xFill(x, y, fMap[x][y]); } } } }; //=================================================================== // IECALCrsytalInfoMap //=================================================================== class COMET::IECALCrystalInfoMap : public COMET::IECALCrystalMap { protected: IChanIdIndexMap fChanIdIndexMap; IIndexChanIdMap fIndexChanIdMap; IChanIdIndexMap fBlockChanIdIndexMap; IIndexChanIdMap fBlockIndexChanIdMap; public: IECALCrystalInfoMap(); virtual ~IECALCrystalInfoMap(); /// Make a map of the same size with class T for any analytic purposes template COMET::IECALCrystalMap CreateMapWith(newT* initValue = NULL) const { return COMET::IECALCrystalMap(GetSizeX(), GetSizeY(), initValue, &fChanIdIndexMap, &fIndexChanIdMap); } /// Make a map for blocks with class T for any analytic purposes template COMET::IECALCrystalMap CreateBlockMapWith(newT* initValue = NULL) const { return COMET::IECALCrystalMap(GetSizeX()/2, GetSizeY()/2, initValue, &fBlockChanIdIndexMap, &fBlockIndexChanIdMap); } }; //=================================================================== // IECALWritableCrsytalInfoMap //=================================================================== class COMET::IECALWritableCrystalInfoMap : public COMET::IECALCrystalInfoMap { friend class COMET::IECALCrystalManager; private: /// Create a map from ICrystalInfoContainer. /// Constructor is private but only IECALCrystalManager can call. IECALWritableCrystalInfoMap(COMET::IECALCrystalManager::ICrystalInfoContainer& container); ~IECALWritableCrystalInfoMap(); private: /// Build Map and map 2d-indices and neighbors to each ICrystalInfo bool BuildMap(COMET::IECALCrystalManager::ICrystalInfoContainer& container); /// Set info at (x,y) of the map. bool Set(const int idxX, const int idxY, IECALCrystalInfo* info){ if(not IsValidIndex(idxX, idxY)) return false; fMap[idxX][idxY] = info; return true; } }; #endif