#ifndef TBGEOMETRYSVC_H #define TBGEOMETRYSVC_H #include <map> // Gaudi #include "GaudiKernel/Service.h" #include "GaudiKernel/Bootstrap.h" #include "GaudiKernel/Transform3DTypes.h" // Local #include "TbKernel/ITbGeometrySvc.h" #include "TbKernel/TbModule.h" template <class TYPE> class SvcFactory; /** @class TbGeometrySvc TbGeometrySvc.h * Implementation of the testbeam geometry service. * */ class TbGeometrySvc : public extends1<Service, ITbGeometrySvc> { public: /// Constructor TbGeometrySvc(const std::string& name, ISvcLocator* svc); /// Destructor virtual ~TbGeometrySvc(); virtual StatusCode initialize(); virtual StatusCode finalize(); /// Transform a point in the local frame of a plane to global coordinates virtual Gaudi::XYZPoint localToGlobal(const Gaudi::XYZPoint& p, const unsigned int i) { return m_modules[i]->transform() * p; } /// Transform a point in the global frame to the local frame of a plane virtual Gaudi::XYZPoint globalToLocal(const Gaudi::XYZPoint& p, const unsigned int i) { return m_modules[i]->inverse() * p; } /// Calculate the local x, y coordinates of a given pixel virtual bool pixelToPoint(const unsigned int scol, const unsigned int row, const unsigned int plane, double& x, double& y); /// Calculate the pixel and inter-pixel position of a given local point virtual bool pointToPixel(const double x, const double y, const unsigned int plane, unsigned int& scol, unsigned int& row); /// Calculate the intercept of a track with a telescope plane virtual Gaudi::XYZPoint intercept(const LHCb::TbTrack* t, const unsigned int i); /// Return a pointer to the module object for a given plane index virtual TbModule* module(const unsigned int i) { return m_modules[i]; } /// Return a pointer to the module object of a given plane identifier virtual TbModule* module(const std::string& det); /// Return the list of modules virtual const std::vector<TbModule*>& modules() { return m_modules; } virtual unsigned int deviceIndex(const std::string& det) { auto p = m_deviceIndex.find(det); return p != m_deviceIndex.end() ? p->second : 999; } virtual unsigned int plane(const std::string& det) { auto p = m_planes.find(det); return p != m_planes.end() ? p->second : 999; } virtual unsigned int nDevices() const { return m_nDevices; } bool readConditions(const std::string& filename, std::vector<TbModule*>& modules); virtual void printAlignment(const std::vector<TbModule*>& modules); virtual void setModule(unsigned int i, TbModule* module) { m_modules[i] = module; } private: /// Allow SvcFactory to instantiate the service. friend class SvcFactory<TbGeometrySvc>; /// Transforms for each plane std::vector<TbModule*> m_modules; /// Map of plane names and their indices in the list std::map<std::string, unsigned int> m_moduleIndex; /// Map of device ids to their chip names std::map<std::string, unsigned int> m_deviceIndex; /// Map of device names to their planes indices std::map<std::string, unsigned int> m_planes; unsigned int m_nDevices; /// Cached x-coordinates of pixels on sensor tiles. std::vector<double> m_xTriple; /// Pointer to message stream mutable MsgStream* m_msg; /// On-demand access to message stream MsgStream& msg() const { if (!m_msg) m_msg = new MsgStream(msgSvc(), name()); return *m_msg; } /// Calculate the intercept of a straight line with a telescope plane Gaudi::XYZPoint intercept(const Gaudi::XYZPoint& p, const Gaudi::XYZVector& t, const unsigned int i) { const Gaudi::XYZVector n = m_modules[i]->normal(); const double s = n.Dot(m_modules[i]->centre() - p) / n.Dot(t); return p + s * t; } }; #endif