#ifndef TCTHGeom_hxx_seen #define TCTHGeom_hxx_seen #include #include #include #include "EoaGeomInfo.hxx" #include #include #include #include "IGeomBase.hxx" #include "IGeomIdManager.hxx" #include #include #include #include #include #include "IGeomInfo.hxx" namespace COMET { OA_EXCEPTION(ENoCTH,EoaGeomInfo); class ICTHGeom; class ICTHGeomVisitor; }; /// Summary of the CTH Geometry. This contains useful /// information about the CTH geometry which is derived from the ROOT /// TGeoManager geometry description of the CyDet. This must /// accessed through IGeomInfo::CTH(). ICTHGeom is a "singleton" object /// that is managed by the IGeomInfo class which really is a singleton. /// Define counter Id as follows; /// counterId = fNumLayers * fNumSegments * module + fNumSegments * layer + segmentId /// , and for light-guide section, /// counterId = counterId(non-LG) + fNumCounters class COMET::ICTHGeom : public COMET::IGeomBase { friend class ICTHGeomVisitor; private: /// Type def to hold a mapping from index to (TGeoNode ID, TGeoNode*) typedef std::map > IGeoNodeList_t; public: /// Constructor ICTHGeom(); /// Destructor ~ICTHGeom(); /// Build the counter map from the CTH Geometry void BuildGeomMap(); /// Clear CTH geometry information void Clear(); /// Fill CTH geometry information void Fill(); /// Printout geometry information void ls(const char* opt); /// @name CTH Array Information /// Get information about the whole CTH counter array. /// @{ /// Get the total number of modules. int GetNumberOfModules() const {return fNumberOfModules;} /// Get the total number of counters. int GetNumberOfCounters() const {return fNumberOfCounters;} /// Get the number of segments. int GetNumberOfLayers() const {return fNumberOfLayers;} /// Get the number of segments. int GetNumberOfSegments() const {return fNumberOfSegments;} /// @} TGeoNode* CounterToNode(int counter) const; /// @name Counter Information int GetCounterNodeId(int counter) const {return fCounterMap.at(counter);} int GetModuleId(int counter) const { int mod=-1; if(counter>=fNumberOfCounters) { mod = (counter>=fNumberOfCounters+fNumberOfLayers*fNumberOfSegments)? 1 : 0; } else { mod = (counter>=fNumberOfLayers*fNumberOfSegments)? 1 : 0; } return mod; } int GetSegmentId(int counter) const { return counter%fNumberOfSegments; } int GetLayerType(int counter) const { int lg = (counter>=fNumberOfCounters)? 1 : 0; int mod = GetModuleId(counter); int counterNew = counter - lg*fNumberOfCounters - mod*fNumberOfLayers*fNumberOfSegments; int type = (counterNew>=fNumberOfSegments)? 1 : 0; return type; } /// !!TO BE IMPLEMENTED //double GetCounterLength(int counter) const; //double GetCounterWidth(int counter) const; //double GetCounterThick(int counter) const; //TVector3 GetCounterPosition(int counter) const; /// @} /// @name Index Conversion /// Convert from one type of geometrical index to another /// User interface to ICTHWireManager functions. /// /// @{ /// Convert the geometry info to a counter number int GetCounterId(int module, int type, int segId, int lg) const { int counter = lg*fNumberOfCounters + module * fNumberOfLayers * fNumberOfSegments + type * fNumberOfSegments + segId; if (counter < 0) counter = -1; return counter; } /// Find the counter ID from the component type and segment ID int GetCounterId(int component, int segId) const { int mod = component%2; int lg = (int)(component/4); int type = (component/2)%2; return GetCounterId(mod,type,segId,lg); } /// Convert a global channel number into a counter number. /// This will return -1 if the channel is not in the CTH. int ChannelToCounterId(int channel) const {return channel;} /// Convert a counter number to a global channel number. /// This will return -1 if the counter is not in the CTH. int CounterIdToChannel(int counter) const { // no channels assigned to light-guide section if(counter>=fNumberOfCounters) return (counter-fNumberOfCounters); else return counter; } /// @} /// @name Channel conversion /// Function to convert channel to position/geometry and vice versa /// Here "channel" only refers the "sensitive" volumes, excluding the light guide, /// this doesn't distinguish whether this is a light-guide part in Cherenkov layer, /// but just returns the node of non-light-guide sections /// /// @{ /// Convert a global channel number into a module TGeoNode. /// This will return NULL if the channel is not in the CTH. TGeoNode* ChannelToCounterNode(int channel) const; /// Convert a global channel number into a global channel position. /// This will return false if the channel is not a CTH counter. bool ChannelToGlobalPosition(int channel, TVector3& global) const; /// Convert a global position into a global channel number. /// This will return false if the channel is not a CTH counter. bool GlobalPositionToChannel(const TVector3& global, int& channel) const; /// @} /// @name Geometry ID Functions /// Get geometry info based on geometry IDs. /// These default to -1 if the geometry ID is invalid /// /// @{ /// Get the counter index int GeomIdToCounterId(const COMET::IGeometryId& id) const { if (!COMET::GeomId::CTH::IsCTH(id)) return -1; int module,segId,scint,lg; GetGeometryInfo(id,module,scint,segId,lg); return GetCounterId(module, scint, segId, lg); } /// Get the module id (upstream/downstream) int GeomIdToModule(const COMET::IGeometryId& id) const { if (!COMET::GeomId::CTH::IsCTH(id)) return -1; else return COMET::GeomId::CTH::GetModule(id); } /// Get the layer type int GeomIdToLayerType(const COMET::IGeometryId& id) const { if (!COMET::GeomId::CTH::IsCTH(id)) return -1; else return COMET::GeomId::CTH::GetScintillator(id); } /// Get the segment index int GeomIdToSegmentId(const COMET::IGeometryId& id) const { if (!COMET::GeomId::CTH::IsCTH(id)) return -1; else return COMET::GeomId::CTH::GetSegmentId(id); } /// Getter for both layer ID and counter ID bool GetGeometryInfo(const COMET::IGeometryId& id, int& module, int& scint, int& segId, int& lg) const; /// Convert from channel to IGeometryId bool ChannelToGeomId(int channel, COMET::IGeometryId& id) const; /// Convert a global channel number into a module TGeoNode. /// This will return NULL if the channel is not in the CTH. TGeoNode* GeomIdToCounterNode(const COMET::IGeometryId& id) const; /// Convert a global channel number into a global channel position. /// This will return false if the channel is not a CTH counter. /// Global position is defined as the center of counter position in global coordinate bool GeomIdToGlobalPosition(const COMET::IGeometryId& id, TVector3& global) const; /// Convert a global position into a global channel number. /// This will return false if the channel is not a CTH counter. bool GlobalPositionToGeomId(const TVector3& global, COMET::IGeometryId& id) const ; /// @} /// @name counter TGeoNode getters /// Get the ith counter TGeoNode ID int GetCounterNodeID(unsigned int counter) const { if(counter >= fCounterMap.size()) return -1; return fCounterMap.at(counter); } /// @} /// Get CTH local coordinates from global coordinates TVector3 LocalToMaster(int nodeId, const TVector3& local) const; /// Get global coordinates from CTH local coordinates TVector3 MasterToLocal(int nodeId, const TVector3& global) const; /// Get the name of i-th component type TString GetComponentType(unsigned int i) const { if (i>=fComponentType.size()) return ""; else return fComponentType.at(i); } private: /// Temporary list of TGeoNode for all sensitive counters IGeoNodeList_t fCounters; /// Map to convert counter ID to TGeoNode ID (including light guide) std::vector < int > fCounterMap; /// List of CTH node names std::vector < TString > fComponentType; int fNumberOfCounters; ///! Number of total counters int fNumberOfModules; ///! Upstream or Downstream, to be fixed to 2 int fNumberOfSegments; ///! Maximum number of segments in phi int fNumberOfLayers; ///! Number of layers fixed to 2 int fNumberOfScintUS; ///! Number of upstream scintillators int fNumberOfScintDS; ///! Number of downstream scintillators int fNumberOfCherenUS; ///! Number of upstream Cherenkov radiators int fNumberOfCherenDS; ///! Number of downstream Cherenkov radiators }; #endif