#ifndef TCDCGeom_hxx_seen #define TCDCGeom_hxx_seen #include #include #include #include #include "EoaGeomInfo.hxx" #include #include #include "IGeomInfo.hxx" #include "IG4HitGas.hxx" #include "IGeomBase.hxx" #include "IGeomIdManager.hxx" #include "IOADatabase.hxx" #include namespace COMET { OA_EXCEPTION(ENoCDC,EoaGeomInfo); class ICDCGeom; class ICDCGeomVisitor; class ICDCWireManager; enum ECDCHitVolume { kCDCOut = 0, kCDCCell = 1, kCDCSenseWire = 2, kCDCFieldWire = 3 }; const int kMaxNumWires = 20000;// Maximum number of sense wires const int kMaxNumLayers = 20; // Maximum number of layers }; /// Summary of the CDC Geometry. This contains useful /// information about the CDC geometry which is derived from the ROOT /// TGeoManager geometry description of the CyDet. This must /// accessed through IGeomInfo::CDC(). ICDCGeom is a "singleton" object /// that is managed by the IGeomInfo class which really is a singleton. class COMET::ICDCGeom : public COMET::IGeomBase { friend class ICDCGeomVisitor; private: /// Type def to hold a mapping from index to (TGeoNode ID, TGeoNode*) typedef std::map > IGeoNodeList_t; public: /// Constructor ICDCGeom(); /// Destructor ~ICDCGeom(); /// Build the wire map from the CDC Geometry void BuildWireMap(); /// Clear CDC geometry information void Clear(); /// Fill CDC geometry information void Fill(); /// Printout geometry information void ls(const char* opt) const; /// @name CDC Wire Array Information /// Get information about the whole CDC wire array. /// User interface to ICDCWireManager functions. /// /// @{ /// Get the number of layers. int GetNumberOfLayers() const; /// Get the number of sense wires. int GetNumberOfWires() const; /// Get the number of sense wires in a layer. int GetNumberOfWiresPerLayer(int layer) const; /// Get the first wire index in a layer. int GetFirstWireIndexAt(int layer) const; /// Get the list of wires in a layer bool GetWiresInLayer(int layer, std::vector& list) const; /// @} /// @name Wire Information /// Get wire information based on wire ID /// User interface to ICDCWireManager functions. /// /// @{ /// Convert a wire number to a TGeoNode ID /// Returns -1 if wire is not valid int GetWireNode(int wire) const; /// Get cell Id just based on the wire number /// Returns -1 if wire is not valid int GetCellId(int wire) const; /// Convert a wire number to a layer. /// Returns -1 if wire is not valid int GetLayer(int wire) const; /// Convert a wire number to the connected RECBE board. /// This will return -1 if the wire is not a CDC wire int GetBoard(int wire) const; /// Get a length of wire from a wire number. /// This will return 1e9 if the channel is not CDC wire. double GetWireLength(int wire) const; /// Get a global position of wire from a wire number. /// This will return false if the channel is not CDC wire. TVector3 GetWirePosition(int wire) const; /// Get a global end0 position of wire from a wire number. /// This will return false if the channel is not CDC wire. TVector3 GetWireEnd0(int wire) const; /// Get a global end1 position of wire from a wire number. /// This will return false if the channel is not CDC wire. TVector3 GetWireEnd1(int wire) const; /// Get a global direction of wire from a wire number. /// This will return false if the channel is not CDC wire. TVector3 GetWireDirection(int wire) const; /// @} /// @name Index Conversion /// Convert from one type of geometrical index to another /// User interface to ICDCWireManager functions. /// /// @{ /// Convert the layer and cell number to a wire number int GetWireId(int layer, int cellID) const; /// Convert a global channel number into a wire number. /// This will return -1 if the channel is not in the CDC. int ChannelToWire(int channel) const; /// Convert a wire number to a global channel number. /// This will return -1 if the wire is not in the CDC. int WireToChannel(int wire) const; /// @} /// @name Channel conversion /// Function to convert channel to position/geometry and vice versa /// User interface to ICDCWireManager functions. /// /// @{ /// Convert a global channel number into a module TGeoNode. /// This will return NULL if the channel is not in the CDC. const TGeoNode* ChannelToModuleNode(int channel) const; /// Convert a global channel number into a global channel position. /// This will return false if the channel is not a CDC wire. 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 CDC wire. COMET::ECDCHitVolume GlobalPositionToChannel(const TVector3& global, int& channel) const; /// @} /// @name Distance Information /// Getters to do with channel ID and distance /// /// @{ /// Convert a global position into a distance from a wire /// This will return false if the wire number is invalid or local position is too far from a wire bool GetDistanceFromWire(const TVector3& global, int wire, TVector3& local) const; /// Convert a distance from a wire into global position /// This will return false if the wire number is invalid or local position is too far from a wire bool GetGlobalFromWireDistance(const TVector3& local, int wire, TVector3& global) const; /// Get a local xy position of wire from a wire number. /// This will return false if the channel is not CDC wire. bool GetWirePositionXY(int wire, double zpos, TVector2& xypos) const; /// Calculate point of closest approach between a segment and a line (wire). /// Returns the points on the wire (pocaW) and on the segment (pocaT) /// which are closest. Also returns the side of the wire on which the /// segment lies via the lr parameter. bool CalcSegToWire(const TVector3& pre, const TVector3& post, int wire, TVector3& pocaW, TVector3& pocaT, int & lr) const; /// Calculate the dot product between position and momentum in the local /// coordinate system. This gives an effective measure of whether a track /// is moving inwards or outwards in the CDC. double GetInOut(const TVector3& position, const TVector3& momentum) const; /// /// @} /// @name Geometry ID Functions /// Get geometry info based on geometry IDs. /// These default to -1 if the geometry ID is invalid /// /// @{ /// Get the layer index int GeomIdToLayer(const COMET::IGeometryId& id) const; /// Get the wire index index int GeomIdToWire(const COMET::IGeometryId& id) const; /// Get the cell index int GeomIdToCell(const COMET::IGeometryId& id) const; /// Getter for both layer ID and wire ID bool GetGeometryInfo(const COMET::IGeometryId& id, int& layer, int& wire) const; /// Get the TGeoNode ID int GeomIdToNodeId(const COMET::IGeometryId& id) 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 CDC. const TGeoNode* GeomIdToModuleNode(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 CDC wire. /// Global position is defined as the center of wire 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 CDC wire. bool GlobalPositionToGeomId(const TVector3& global, COMET::IGeometryId& id) const; /// @} /// @name Wire and Layer TGeoNode getters /// Functions that deal with the TGeoNodes of /// /// @{ /// Get the ith sense layer TGeoNode* const TGeoNode* GetSenseLayer(unsigned int i) const { if(i >= fSenseLayers.size()) return NULL; return fSenseLayers.at(i).second; } /// Get the ith sense layer TGeoNode ID int GetSenseLayerNodeID(unsigned int i) const { if(i >= fSenseLayers.size()) return -1; return fSenseLayers.at(i).first; } /// Get the ith sense wire TGeoNode* const TGeoNode* GetSenseWire(unsigned int i) const { if(i >= fSenseWires.size()) return NULL; return fSenseWires.at(i).second; } /// Get the ith sense wire TGeoNode ID int GetSenseWireNodeID(unsigned int i) const { if(i >= fSenseWires.size()) return -1; return fSenseWires.at(i).first; } /// Get the ith sense wire radius double GetSenseWireRadius(unsigned int i=0) const { return COMET::IOADatabase::Get().GeomId().NodeSize(GetSenseWire(i),COMET::IGeomIdManager::kTube).X(); } /// Get the ith field wire TGeoNode* const TGeoNode* GetFieldWire(unsigned int i) const { if(i >= fFieldWires.size()) return NULL; return fFieldWires.at(i).second; } /// Get the ith field wire TGeoNode ID int GetFieldWireNodeID(unsigned int i) const { if(i >= fFieldWires.size()) return -1; return fFieldWires.at(i).first; } /// Get the ith field wire radius double GetFieldWireRadius(unsigned int i=0) const { return COMET::IOADatabase::Get().GeomId().NodeSize(GetFieldWire(i),COMET::IGeomIdManager::kTube).X(); } /// @} /// Get CDC local coordinates from global coordinates TVector3 LocalPosition_to_GlobalPosition(const TVector3& local) const; /// Get global coordinates from CDC local coordinates TVector3 GlobalPosition_to_LocalPosition(const TVector3& global) const; /// Get momentum in CDC local coordinates from momentum in global coordinates TVector3 LocalMomentum_to_GlobalMomentum(const TVector3& local) const; /// Get momentum in global coordinates from momentum in CDC local coordinates TVector3 GlobalMomentum_to_LocalMomentum(const TVector3& global) const; private: /// Wire manager for the CDC sense wires COMET::ICDCWireManager *fCDCWireManager; /// List of TGeoNode for sense layers keyed by layer ID IGeoNodeList_t fSenseLayers; /// List of TGeoNode for sense wires keyed by sense wire ID IGeoNodeList_t fSenseWires; /// List of TGeoNode for field wires keyed by field wire ID IGeoNodeList_t fFieldWires; /// TGeoNode for the innermost layer (used for local-global coordinates translation) int fInnerMostLayerNodeId; /// Temporary map to store map from layer ID, wire ID to TGeoNode ID std::vector < std::vector < int > > fWireMap; /// Node ID for the detector solenoid int fDetSolNodeId; }; #endif