diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/ExtendedAlignableTransform.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/ExtendedAlignableTransform.h new file mode 100755 index 0000000000000000000000000000000000000000..37e427afc36abc4d2449ccd5a255c1ff5afe41f0 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/ExtendedAlignableTransform.h @@ -0,0 +1,56 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// ExtendedAlignableTransform.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef INDETREADOUTGEOMETRY_EXTENDEDALIGNABLETRANSFORM_H +#define INDETREADOUTGEOMETRY_EXTENDEDALIGNABLETRANSFORM_H + +#include "GeoModelKernel/GeoAlignableTransform.h" +#include "GeoModelKernel/GeoVFullPhysVol.h" + +namespace InDetDD { + + /** @class ExtendedAlignableTransform + + Class to hold alignable transform plus a pointer to the child volume and + optionally a frame volume. + + @author: Grant Gorfine + - modified & maintained: Nick Styles & Andreas Salzburger + */ + + class ExtendedAlignableTransform + { + + public: + + ExtendedAlignableTransform(GeoAlignableTransform * alignableTransform, + const GeoVFullPhysVol * child, + const GeoVFullPhysVol * frame = 0) + : m_alignableTransform(alignableTransform), + m_child(child), + m_frame(frame) + {}; + + GeoAlignableTransform * alignableTransform() {return m_alignableTransform;} + const GeoVFullPhysVol * child() {return m_child;} + const GeoVFullPhysVol * frame() {return m_frame;} + + private: + + GeoAlignableTransform * m_alignableTransform; + const GeoVFullPhysVol * m_child; + const GeoVFullPhysVol * m_frame; + + }; + + +} // end namespace + +#endif // InDetDDINDETREADOUTGEOMETRY_EXTENDEDALIGNABLETRANSFORM_H diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/InDetDD_Defs.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/InDetDD_Defs.h new file mode 100755 index 0000000000000000000000000000000000000000..8cdbff5313863b5644899906c8ab6e0783819fdb --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/InDetDD_Defs.h @@ -0,0 +1,20 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// InDetDD_Defs.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef INDETREADOUTGEOMETRY_INDETDD_Defs_H +#define INDETREADOUTGEOMETRY_INDETDD_Defs_H + + +namespace InDetDD { + enum FrameType {local, global, other}; + enum CarrierType {holes, electrons}; +} + +#endif // INDETREADOUTGEOMETRY_INDETDD_DEFS_H diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/InDetDetectorManager.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/InDetDetectorManager.h new file mode 100755 index 0000000000000000000000000000000000000000..5c97d50cf088137fe3f6edb6edee787f7489a726 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/InDetDetectorManager.h @@ -0,0 +1,151 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// InDetDectorManager.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef INDETREADOUTGEOMETRY_INDETDETECTORMANAGER_H +#define INDETREADOUTGEOMETRY_INDETDETECTORMANAGER_H + +// Amg +#include "GeoPrimitives/GeoPrimitives.h" +// GeoModel stuff +#include "GeoModelKernel/GeoVDetectorManager.h" +#include "InDetReadoutGeometry/InDetDD_Defs.h" +#include "InDetReadoutGeometry/Version.h" +#include "CLHEP/Geometry/Transform3D.h" +// Message Stream Member +#include "AthenaKernel/MsgStreamMember.h" + +// IOV SVC for alignment: +#include "AthenaKernel/IIOVSvc.h" + +class StoreGateSvc; +class AlignableTransform; +class Identifier; +class AtlasDetectorID; + +#include <string> +#include <map> +#include <set> + +namespace InDetDD { + + /** @class InDetDetectorManager + + Virtual base class for all ID detector managers. + + It implements the processKey() method for alingment + which calls the setAlignableTransformDelta() method which + is specified in the extended classes. This method supports both, + local and global delta's in the frame and translates it to the + underlying GeoModel transform. As GeoModel (CLHEP) and tracking + (Amg) use different geo libraries, these are the methods that + act as the CLHEP <--> Amg interface + + @author: Grant Gorfine + - modified & maintained: Nick Styles & Andreas Salzburger + */ + class InDetDetectorManager : public GeoVDetectorManager { + + public: + + // Constructor + InDetDetectorManager(StoreGateSvc * detStore, const std::string & name); + + // Destructor + virtual ~InDetDetectorManager(); + + + /** Get version information */ + const Version & getVersion() const; + const std::string & getLayout() const; // eg Initial, Final, TestBeam + void setVersion(const Version & version); + + /** Alignment access */ + void addChannel(const std::string & key, int level, FrameType frame); + void addFolder(const std::string & key); + void addSpecialFolder(const std::string & key); + StatusCode align( IOVSVC_CALLBACK_ARGS ) const; + + /** Invalidate cache for all detector elements */ + virtual void invalidateAll() const = 0; + + /** Update all caches */ + virtual void updateAll() const = 0; + + /** Check identifier is for this detector */ + virtual bool identifierBelongs(const Identifier & id) const = 0; + + /** Declaring the Message method for further use */ + MsgStream& msg (MSG::Level lvl) const { return m_msg.get() << lvl; } + + /** Declaring the Method providing Verbosity Level */ + bool msgLvl (MSG::Level lvl) const { return m_msg.get().level() <= lvl; } + + protected: + StoreGateSvc * m_detStore; + + private: + /** @class LevelInfo + Private helper class definition. + */ + class LevelInfo { + + private: + int m_level; + FrameType m_type; + + public: + LevelInfo(): m_level(-1), m_type(InDetDD::global) {}; + LevelInfo(int level, FrameType frame): m_level(level), m_type(frame) {}; + + int level() const {return m_level;} + FrameType frame() const {return m_type;} + bool isGlobalDelta() const {return m_type == InDetDD::global;} + bool isLocalDelta() const {return m_type == InDetDD::local;} + bool isValid() const {return (m_level >= 0);} + + }; + + /** Retrieve level information */ + const LevelInfo & getLevel(const std::string & key) const; + + /** Process the alignment container, calls processKey */ + bool processAlignmentContainer(const std::string & key) const; + + /** Called by processAlignmentContainer, + applies only one key on the transform Collections */ + bool processKey(const std::string key, + const AlignableTransform* transformCollection) const; + + /** Set method applying the delta transform (in global or local frame) + onto the geoModel transform : CLHEP <--> Amg interface */ + virtual bool setAlignableTransformDelta(int level, + const Identifier & id, + const Amg::Transform3D & delta, + FrameType frame) const = 0; + + virtual bool processSpecialAlignment(const std::string & key) const; + + virtual const AtlasDetectorID* getIdHelper() const = 0; + + //Declaring private message stream member. + mutable Athena::MsgStreamMember m_msg; + + Version m_version; + std::map<std::string, LevelInfo> m_keys; + std::set<std::string> m_folders; + std::set<std::string> m_specialFolders; + + mutable bool m_suppressWarnings; + + }; + +} // namespace InDetDD + +#endif // INDETREADOUTGEOMETRY_INDETDETECTORMANAGER_H diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/PixelDetectorManager.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/PixelDetectorManager.h new file mode 100755 index 0000000000000000000000000000000000000000..6bc5b6a458eb68cbd460f16ba13edbe104fd2622 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/PixelDetectorManager.h @@ -0,0 +1,168 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// PixelDectorManager.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef InDetReadoutGeometry_PixelDetectorManager_h +#define InDetReadoutGeometry_PixelDetectorManager_h 1 + +#include "GeoModelKernel/GeoVPhysVol.h" + +#include "InDetReadoutGeometry/SiDetectorManager.h" +#include "InDetReadoutGeometry/SiDetectorElementCollection.h" +#include "InDetReadoutGeometry/InDetDD_Defs.h" + +#include "InDetIdentifier/PixelID.h" + +#include <map> + +class StoreGateSvc; +class Identifier; +class IdentifierHash; +class GeoAlignableTransform; +class GeoVFullPhysVol; +class GeoVPhysVol; + +namespace InDetDD { + + class PixelModuleDesign; + class SiDetectorElement; + class ExtendedAlignableTransform; + + /** @class PixelDetectorManager + + Dedicated detector manager extending the functionality of the SiDetectorManager + with dedicated pixel information, access. + + @author: Grant Gorfine + - modified and maintained by Nick Styles & Andreas Salzburger + */ + + class PixelDetectorManager : public SiDetectorManager { + + public: + + /** Constructor */ + PixelDetectorManager(StoreGateSvc* detStore); + + /** Destructor */ + ~PixelDetectorManager(); + + /** Access to raw geometry: */ + virtual unsigned int getNumTreeTops() const; + virtual PVConstLink getTreeTop(unsigned int i) const; + + /** Add a Tree top: */ + void addTreeTop(PVLink); + + // + // Access Readout Elements + // + /** access to individual elements : via Identifier */ + virtual SiDetectorElement * getDetectorElement(const Identifier &id) const; + + /** access to individual elements : via IdentifierHash */ + virtual SiDetectorElement * getDetectorElement(const IdentifierHash &idHash) const; + + /** access to individual elements : via element identification */ + SiDetectorElement * getDetectorElement(int barrel_endcap, + int layer_wheel, + int phi_module, + int eta_module) const; + + /** access to whole collection via Iterators */ + virtual const SiDetectorElementCollection * getDetectorElementCollection() const; + virtual SiDetectorElementCollection::const_iterator getDetectorElementBegin() const; + virtual SiDetectorElementCollection::const_iterator getDetectorElementEnd() const; + + /** Add elememts */ + virtual void addDetectorElement(SiDetectorElement * element); + + /** Add alignable transforms. No access to these, they will be changed by manager: */ + virtual void addAlignableTransform (int level, + const Identifier &id, + GeoAlignableTransform *xf, + const GeoVFullPhysVol * child); + + /** As above but does a dynamic_cast to GeoVFullPhysVol */ + virtual void addAlignableTransform (int level, + const Identifier &id, + GeoAlignableTransform *xf, + const GeoVPhysVol * child); + + // DEPRECATED + virtual void addAlignableTransform (int, + const Identifier &, + GeoAlignableTransform *) {}; // For backward compatibility + + + /** Initialize the neighbours. This can only be done when all elements are built. */ + virtual void initNeighbours(); + + /** Methods to query which manager we have */ + virtual bool isPixel() const {return true;} + + /** Check identifier is for this detector */ + virtual bool identifierBelongs(const Identifier & id) const; + + + /** Layers built. Deprecated. Recommend to access via numerology (see SiDetectorManager) + Warning: decodes in "human-readable", e.g. using 3 out of 3 pixel layers yiels 111, the laset two out of 3 in 110, etc. + */ + unsigned int getBarrelLayers() const ; + + /** Layers built. Deprecated. Recommend to access via numerology (see SiDetectorManager) + Warning: decodes in "human-readable", e.g. using 3 out of 3 pixel layers yiels 111, the laset two out of 3 in 110, etc. + */ + unsigned int getEndcapLayers() const; + + /** Access to module design, Casts to PixelModuleDesign */ + virtual const PixelModuleDesign * getPixelDesign(int i) const; + + private: + + /** implements the main alignment update for delta transforms in different frames, + it translates into the LocalDelta or GlobalDelta function of SiDetectorManager + */ + virtual bool setAlignableTransformDelta(int level, + const Identifier & id, + const Amg::Transform3D & delta, + FrameType frame) const; + + + /** prevent copy and assignment */ + const PixelDetectorManager & operator=(const PixelDetectorManager &right); + PixelDetectorManager(const PixelDetectorManager &right); + + + virtual const PixelID * getIdHelper() const; + + // data members + std::vector<PVLink> m_volume; + SiDetectorElementCollection m_elementCollection; + typedef std::map<Identifier, ExtendedAlignableTransform *> AlignableTransformMap; + std::vector< AlignableTransformMap > m_higherAlignableTransforms; + std::vector< ExtendedAlignableTransform *> m_alignableTransforms; + const PixelID* m_idHelper; + + }; + +} // namespace InDetDD + +#ifndef GAUDI_NEUTRAL +#include "CLIDSvc/CLASS_DEF.h" +CLASS_DEF(InDetDD::PixelDetectorManager, 18429566, 1) + +#endif + +#endif + + + + + diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/PixelDiodeMap.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/PixelDiodeMap.h new file mode 100755 index 0000000000000000000000000000000000000000..aa1a63c405d6230efbfdc6782b7a3e701103dfb8 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/PixelDiodeMap.h @@ -0,0 +1,195 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// PixelDiodeMap.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Pixel Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef INDETREADOUTGEOMETRY_PIXELDIODEMAP_H +#define INDETREADOUTGEOMETRY_PIXELDIODEMAP_H + +// STL classes +#include <vector> +#include <list> + +// Data member classes +#include "InDetReadoutGeometry/PixelDiodeMatrix.h" + +// Input/output classes +#include "InDetReadoutGeometry/SiCellId.h" +#include "InDetReadoutGeometry/SiDiodesParameters.h" + +namespace InDetDD { + +class SiCellId; +class PixelDiodeMatrix; + + /** @class PixelDiodeMap + + Class used to describe the diode segmentation of a pixel module + - to get the position and size of a PixelDiode object + - to get a PixelDiode object containing a space point + - to get a PixelDiode object from a PixelModulePosition + + @author: David Calvet + - modified Davide Costanzo. Replace PixelModulePosition with SiCellId + - modified: Grant Gorfine, Andreas Salzburger + */ + + class PixelDiodeMap { + + public: + + /** Constructor from Diode matrix description */ + PixelDiodeMap(const PixelDiodeMatrix * diodeMatrix); + + /** Copy constructor: */ + PixelDiodeMap(const PixelDiodeMap &map); + + /** Destructor */ + ~PixelDiodeMap(); + + /** Assignment operator */ + PixelDiodeMap &operator=(const PixelDiodeMap &map); + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /** Get diodes parameters (position and size): */ + SiDiodesParameters parameters(const SiCellId & diodeId) const; + + /** cell id for a given local position */ + SiCellId cellIdOfPosition(const Amg::Vector2D & localPosition) const; + + /** Check if cellId is within range */ + SiCellId cellIdInRange(const SiCellId & cellId) const; + + /** Get the neighbouring PixelDiodes of a given PixelDiode: + Cell for which the neighbours must be found + List of cells which are neighbours of the given one */ + void neighboursOfCell(const SiCellId & cellId, + std::vector<SiCellId> &neighbours) const; + + /** Compute the intersection length of two diodes: + return: the intersection length when the two diodes are projected on one + of the two axis, or 0 in case of no intersection or problem + nput: the two diodes for which the intersection length is computed */ + double intersectionLength(const SiCellId &diode1, const SiCellId &diode2) const; + + // Global sensor size: + double leftColumn() const; + double rightColumn() const; + double leftRow() const; + double rightRow() const; + + double width() const; + double length() const; + + // Number of cells in each direction. + int phiDiodes() const; + int etaDiodes() const; + + // Total number of diodes: + int diodes() const; + + /////////////////////////////////////////////////////////////////// + // Non-const methods: + /////////////////////////////////////////////////////////////////// + /** Set general layout flag. This can be set to true to allow handling + of more complex layouts where cells are not lined up with each other + such as bricking. Probably never will be needed. */ + void setGeneralLayout() {m_generalLayout = true;} + + /////////////////////////////////////////////////////////////////// + // Private methods: + /////////////////////////////////////////////////////////////////// + private: + + /** Compute the intersection length along one direction: + return 0 if no intersection + x1,x2 are the centers + dx1,dx2 are the full lengths */ + double intersectionLength1D(const double x1,const double dx1, + const double x2,const double dx2) const; + + /** Slower method. Called by neighboursOfCell if m_generalLayout set. */ + void neighboursOfCellGeneral(const SiCellId & cellId, + std::vector<SiCellId> &neighbours) const; + + /** Slower method. Called by intersectionLength if m_generalLayout set. */ + double intersectionLengthGeneral(const SiCellId &diode1, + const SiCellId &diode2) const; + + + /////////////////////////////////////////////////////////////////// + // Private data: + /////////////////////////////////////////////////////////////////// + private: + const PixelDiodeMatrix * m_matrix; //!< diode matrix + bool m_generalLayout; //!< Flag set to allow for dealing wth more general layouts. + }; + + /////////////////////////////////////////////////////////////////// + // Inline methods: + /////////////////////////////////////////////////////////////////// + + inline double PixelDiodeMap::length() const + { + return m_matrix->etaWidth(); + } + + inline double PixelDiodeMap::width() const + { + return m_matrix->phiWidth(); + } + + inline double PixelDiodeMap::leftColumn() const + { + return -0.5*length(); + } + + inline double PixelDiodeMap::rightColumn() const + { + return 0.5*length(); + } + + inline double PixelDiodeMap::leftRow() const + { + return -0.5*width(); + } + + inline double PixelDiodeMap::rightRow() const + { + return 0.5*width(); + } + + inline int PixelDiodeMap::diodes() const + { + return phiDiodes() * etaDiodes(); + } + + inline int PixelDiodeMap::phiDiodes() const + { + return m_matrix->phiCells(); + } + + inline int PixelDiodeMap::etaDiodes() const + { + return m_matrix->etaCells(); + } + + inline SiCellId PixelDiodeMap::cellIdInRange(const SiCellId & cellId) const + { + if (!cellId.isValid() || + cellId.phiIndex() <0 || cellId.phiIndex() >= phiDiodes() || + cellId.etaIndex() <0 || cellId.etaIndex() >= etaDiodes()) return SiCellId(); // Invalid + return cellId; + } + +} // namespace InDetDD + +#endif // INDETREADOUTGEOMETRY_PIXELDIODEMAP_H diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/PixelDiodeMatrix.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/PixelDiodeMatrix.h new file mode 100755 index 0000000000000000000000000000000000000000..35190f3655b9c0bab6c733b8ef997c356e9b6e7d --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/PixelDiodeMatrix.h @@ -0,0 +1,181 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// PixelDiodeMatrix.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef INDETREADOUTGEOMETRY_PIXELDIODEMATRIX_H +#define INDETREADOUTGEOMETRY_PIXELDIODEMATRIX_H + +#include "InDetReadoutGeometry/SiCellId.h" +#include "GeoModelKernel/RCBase.h" +#include "TrkDetElementBase/TrkDetElementBase.h" + +namespace InDetDD { + + /** @class PixelDiodeMatrix + + Class used to describe the segmentation of the pixel and allow for conversion between cell id and position. + + The class PixelDiodeMatrix represents what it calls a cell. In the context + of this class a cell can either be just a simple cell as one would normally + think of a pixel cell (eg a 50x400um or 50x600um cell) or it can be a + container of multiple cells. To allow for different size cells and layout, + it contains a lower cell, an upper cell and multiple middle + cells. The middle cells are all the same (so all have the same size), but + the upper and lower cells can be different and can have different size or be left out + if they are not needed. The direction of replication is also specified (eta + or phi direction). The size of the cells in the direction orthoganal to the + replication direction must all be the same (there is no check for this though). + + To help understand the structure and its use, consider the current pixel + geometry. The pixel module has two cell sizes short and long cells. These + are refered to as normal and big bellow. The long cells are in the region + at the edge of the the FE chips in order to cover the gap between FE chips. + + The assembly of this structure is done when building the sensitive detector + in GeoModel in the class GeoPixelSiCrystal. + + - normalCell (short pixel cell) 50x400um + - bigCell (long pixel cell): 50x600um + + - singleChipRow (represents one row associated to a FE) + - Size: phiWidth = 50um, etaWidth = 600*2+400*16) um = 7.6 CLHEP::mm + - upper cell: bigCell + - middle cells: 16 x normalCell + - lower cell: bigcell + - direction: eta + + - singleRow (represents a row of cells covering the full length of the + module) + - Size: phiWidth = 50um, etaWidth = 8 * (600*2+400*16) um = 60.8 CLHEP::mm + - upper cell: none + - middle cells: 8 x singleChipRow + - lower cell: none + - direction: eta + + - fullMatrix (represents the full module) + - Size: phiWidth = 50 * 328 um = 16.4 CLHEP::mm, etaWidth = 60.8 CLHEP::mm + - upper cell: none + - middle cells: 328 x singleRow + - lower cell: non + - direction: phi + + Each cell knows its total size and total number of child cells in the phi and eta + direction. This is determined by totaling up these quantities + when the object is constructed. + + The structure allows for efficient navigation from cell number to + position and vice-versa. There are two main methods which allow for this navigation: + cellIdOfPosition() (from cell id to position) and positionOfCell() (from position to cell id). + + As it is assumed that child cells fill up completely its parent, there is + no range check in these methods. The methods are called from PixelDiodeMap + where it first checks that is within range of the top level cell (refered to + as the top level matrix). + + See the description of these methods for more details. + + @image html pixeldiodematrix.gif + + @author Grant Gorfine + - modified & maintained: Nick Styles, Andreas Salzburger + **/ + + class PixelDiodeMatrix: public RCBase { + + public: + + enum Direction {phiDir, etaDir}; + + /// Constructor for just a single cell. + PixelDiodeMatrix(double phiWidth, double etaWidth); + + /** Constructor with multiple matrices. + There may be zero or one lower matrix (pointer can be 0). + Multiple (numCells) middle matrics (must pass a non zero pointer). + There may be zero or one upper matrix (pointer can be 0). + These must all have the same width and cells in the non replicating direction. */ + PixelDiodeMatrix(Direction direction, // phi or eta + const PixelDiodeMatrix * lowerCell, + const PixelDiodeMatrix * middleCells, + int numCells, + const PixelDiodeMatrix * upperCells); + + /// Destructor + ~PixelDiodeMatrix(); + + /** Return cell Id corresponding to a relative position within the matrix. + The cellId is modified and returns the id relative to the passed cellId. + That is, it adds the relative cellId to the cellId passed to the function. + A pointer to the correspond cell is returned. This can be used to get the + size of the cell. */ + const PixelDiodeMatrix * cellIdOfPosition(const Amg::Vector2D & position, SiCellId & cellId) const; + + /** Return position correspong to cell with relative id withing the matrix. + Returns the relative position added to the position passed in. + A pointer to the correspond cell is returned. This can be used to get the + size of the cell. */ + const PixelDiodeMatrix * positionOfCell(const SiCellId & cellId, Amg::Vector2D & position) const; + + /** Width in phi (x) direction.*/ + double phiWidth() const; + + /** Width in eta (y) direction. */ + double etaWidth() const; + + /** Number of cells in phi (x) direction. */ + int phiCells() const; + + /** Number of cells in eta (y) direction. */ + int etaCells() const; + + /** Query wether the matrix is just a single cell. Mainly for internal use. */ + bool singleCell() const; + + private: + double m_phiWidth; + double m_etaWidth; + int m_phiCells; + int m_etaCells; + Direction m_direction; + int m_numCells; // number of MiddleCells along m_direction direction. + const PixelDiodeMatrix * m_lowerCell; + const PixelDiodeMatrix * m_middleCells; + const PixelDiodeMatrix * m_upperCell; + bool m_singleCell; + + }; + + inline double PixelDiodeMatrix::phiWidth() const + { + return m_phiWidth; + } + + inline double PixelDiodeMatrix::etaWidth() const + { + return m_etaWidth; + } + + inline int PixelDiodeMatrix::phiCells() const + { + return m_phiCells; + } + + inline int PixelDiodeMatrix::etaCells() const + { + return m_etaCells; + } + + inline bool PixelDiodeMatrix::singleCell() const + { + return m_singleCell; + } + +} // end namespace + +#endif //INDETREADOUTGEOMETRY_PIXELDIODEMATRIX_H diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/PixelModuleDesign.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/PixelModuleDesign.h new file mode 100755 index 0000000000000000000000000000000000000000..e9c1274098be6a6ea3cc4ae187813b44b0e9e069 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/PixelModuleDesign.h @@ -0,0 +1,341 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// PixelModuleDesign.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Pixel Detector software +/////////////////////////////////////////////////////////////////// + + +#ifndef INDETREADOUTGEOMETRY_PIXELMODULEDESIGN_H +#define INDETREADOUTGEOMETRY_PIXELMODULEDESIGN_H + +// Base class +#include "InDetReadoutGeometry/SiDetectorDesign.h" + +// Data member classes +#include "InDetReadoutGeometry/PixelDiodeMap.h" +#include "InDetReadoutGeometry/PixelReadoutScheme.h" + +// Other includes +#include "InDetIdentifier/PixelID.h" + +namespace Trk{ + class RectangleBounds; + class SurfaceBounds; +} + +namespace InDetDD { + + class PixelDiodeMatrix; + + /** @class PixelModuleDesign + Class used to describe the design of a module + (diode segmentation and readout scheme) + + - to get the PixelReadoutCell connected to a PixelDiode + - to get the list of PixelDiodes connected to a PixelReadoutCell + + @author Alessandro Fornaini + - modified: Grant Gorfine, Nick Styles, Andreas Salzburger + */ + class PixelModuleDesign : public SiDetectorDesign { + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + /////////////////////////////////////////////////////////////////// + // Constructors/destructor: + /////////////////////////////////////////////////////////////////// + + /** Constructor with parameters: + local axis corresponding to eta direction + local axis corresponding to phi direction + local axis corresponding to depth direction + thickness of silicon sensor + number of circuits in one circuit column + number of circuits in one circuit row + number of cell columns per circuit + number of cell rows per circuit + number of diode columns connected to one circuit + number of diode rows connected to one circuit */ + + PixelModuleDesign(const double thickness, + const int circuitsPerColumn, + const int circuitsPerRow, + const int cellColumnsPerCircuit, + const int cellRowsPerCircuit, + const int diodeColumnsPerCircuit, + const int diodeRowsPerCircuit, + const PixelDiodeMatrix * matrix, + InDetDD::CarrierType carrierType, + int readoutSide = -1, + bool is3D=false); + + // Destructor: + virtual ~PixelModuleDesign(); + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /** Returns distance to nearest detector active edge + +ve = inside + -ve = outside */ + virtual void distanceToDetectorEdge(const SiLocalPosition & localPosition, + double & etaDist, double & phiDist) const; + + /** readout or diode id -> position, size */ + virtual SiDiodesParameters parameters(const SiCellId & cellId) const; + virtual SiLocalPosition localPositionOfCell(const SiCellId & cellId) const; + + /** readout id -> id of connected diodes */ + virtual int numberOfConnectedCells(const SiReadoutCellId & readoutId) const; + virtual SiCellId connectedCell(const SiReadoutCellId & readoutId, int number) const; + + /** If cell is ganged return the other cell, otherwise return an invalid id. */ + virtual SiCellId gangedCell(const SiCellId & cellId) const; + + /** diode id -> readout id */ + virtual SiReadoutCellId readoutIdOfCell(const SiCellId & cellId) const; + + /** position -> id */ + virtual SiReadoutCellId readoutIdOfPosition(const SiLocalPosition & localPos) const; + virtual SiCellId cellIdOfPosition(const SiLocalPosition & localPos) const; + + /** Check if cell is in range. Returns the original cellId if it is in range, otherwise it returns an invalid id. */ + virtual SiCellId cellIdInRange(const SiCellId & cellId) const; + + /** Helper method for stereo angle computation */ + virtual HepGeom::Vector3D<double> phiMeasureSegment(const SiLocalPosition&) const; + + /** Special method for SCT (irrelevant here): */ + virtual std::pair<SiLocalPosition,SiLocalPosition> endsOfStrip(const SiLocalPosition &position) const; + + /** Given row and column index of a diode, return position of diode center + ALTERNATIVE/PREFERED way is to use localPositionOfCell(const SiCellId & cellId) or + rawLocalPositionOfCell method in SiDetectorElement. + DEPRECATED */ + SiLocalPosition positionFromColumnRow(const int column, const int row) const; + + /** Get the neighbouring diodes of a given diode: + Cell for which the neighbours must be found + List of cells which are neighbours of the given one */ + virtual void neighboursOfCell(const SiCellId & cellId, + std::vector<SiCellId> &neighbours) const; + + /** Compute the intersection length of two diodes: + return: the intersection length when the two diodes are projected on one + of the two axis, or 0 in case of no intersection or problem + input: the two diodes for which the intersection length is computed */ + double intersectionLength(const SiCellId &diode1, const SiCellId &diode2) const; + + /** Global sensor size: */ + double sensorLeftColumn() const; + double sensorRightColumn() const; + double sensorLeftRow() const; + double sensorRightRow() const; + + /** Total number of diodes: */ + int numberOfDiodes() const; + + /** Total number of circuits:*/ + int numberOfCircuits() const; + + /** Number of cell columns per circuit:*/ + int columnsPerCircuit() const; + + /** Number of cell rows per circuit:*/ + int rowsPerCircuit() const; + + /** Number of cell columns per module:*/ + int columns() const; + + /** Number of cell rows per module:*/ + int rows() const; + + /** Method to calculate length of a module*/ + virtual double length() const; + + /** Method to calculate average width of a module*/ + virtual double width() const; + + /** Method to calculate minimum width of a module*/ + virtual double minWidth() const; + + /** Method to calculate maximum width of a module*/ + virtual double maxWidth() const; + + /** Pitch in phi direction*/ + virtual double phiPitch() const; + + /** Pitch in phi direction*/ + virtual double phiPitch(const SiLocalPosition & localPosition) const; + + /** Pitch in eta direction*/ + virtual double etaPitch() const; + + /** Method to calculate eta width from a column range*/ + double widthFromColumnRange(const int colMin, const int colMax) const; + + /** Method to calculate phi width from a row range*/ + double widthFromRowRange(const int rowMin, const int rowMax) const; + + /** Test if near bond gap within tolerances + Only relevant for SCT. Always returns false for pixels.*/ + virtual bool nearBondGap(const SiLocalPosition & localPosition, double etaTol) const; + + /** Return true if hit local direction is the same as readout direction.*/ + virtual bool swapHitPhiReadoutDirection() const; + virtual bool swapHitEtaReadoutDirection() const; + + /** Element boundary*/ + virtual const Trk::SurfaceBounds & bounds() const; + + virtual bool is3D() const; + + /////////////////////////////////////////////////////////////////// + // Non-const methods: + /////////////////////////////////////////////////////////////////// + + + /** Add a new multiple connection for rows: + lower diode row for which the connection scheme is given + vector containing, for each diode, the readout cell row number + to which the corresponding diode is connected */ + void addMultipleRowConnection(const int lowerRow, + const std::vector<int> &connections); + + /** Indicate that it is a more complex layout where cells are not + lined up with each other. Eg bricking. Probably never will be needed. */ + void setGeneralLayout(); + + /////////////////////////////////////////////////////////////////// + // Private methods: + /////////////////////////////////////////////////////////////////// + private: + + PixelModuleDesign(); + + // Copy constructor: + PixelModuleDesign(const PixelModuleDesign &design); + + // Assignment operator: + PixelModuleDesign &operator=(const PixelModuleDesign &design); + + + /////////////////////////////////////////////////////////////////// + // Private data: + /////////////////////////////////////////////////////////////////// + private: + PixelDiodeMap m_diodeMap; + PixelReadoutScheme m_readoutScheme; + mutable Trk::RectangleBounds * m_bounds; + bool m_is3D; + + }; + + /////////////////////////////////////////////////////////////////// + // Inline methods: + /////////////////////////////////////////////////////////////////// + + inline void PixelModuleDesign::addMultipleRowConnection(const int lowerRow, + const std::vector<int> &connections) + { + m_readoutScheme.addMultipleRowConnection(lowerRow,connections); + } + + inline double PixelModuleDesign::sensorLeftColumn() const + { + return m_diodeMap.leftColumn(); + } + + inline double PixelModuleDesign::sensorRightColumn() const + { + return m_diodeMap.rightColumn(); + } + + inline double PixelModuleDesign::sensorLeftRow() const + { + return m_diodeMap.leftRow(); + } + + inline double PixelModuleDesign::sensorRightRow() const + { + return m_diodeMap.rightRow(); + } + + inline int PixelModuleDesign::numberOfDiodes() const + { + return m_diodeMap.diodes(); + } + + inline int PixelModuleDesign::numberOfCircuits() const + { + return m_readoutScheme.numberOfCircuits(); + } + + inline int PixelModuleDesign::columnsPerCircuit() const + { + return m_readoutScheme.columnsPerCircuit(); + } + + inline int PixelModuleDesign::rowsPerCircuit() const + { + return m_readoutScheme.rowsPerCircuit(); + } + + inline int PixelModuleDesign::columns() const + { + return m_readoutScheme.columns(); + } + + inline int PixelModuleDesign::rows() const + { + return m_readoutScheme.rows(); + } + + inline bool PixelModuleDesign::nearBondGap(const SiLocalPosition &, double) const + { + // No bond gap in pixel module + return false; + } + + inline bool PixelModuleDesign::swapHitPhiReadoutDirection() const + { + return true; + } + + inline bool PixelModuleDesign::swapHitEtaReadoutDirection() const + { + return true; + } + + + inline void PixelModuleDesign::neighboursOfCell(const SiCellId & cellId, + std::vector<SiCellId> &neighbours) const + { + return m_diodeMap.neighboursOfCell(cellId, neighbours); + } + + inline double PixelModuleDesign::intersectionLength(const SiCellId &diode1, + const SiCellId &diode2) const + { + return m_diodeMap.intersectionLength(diode1, diode2); + } + + + + inline bool PixelModuleDesign::is3D() const + { + return m_is3D; + } + + +} // namespace InDetDD + +#endif // INDETREADOUTGEOMETRY_PIXELMODULEDESIGN_H diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/PixelMultipleConnection1D.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/PixelMultipleConnection1D.h new file mode 100755 index 0000000000000000000000000000000000000000..9c5c49abf46b598223ab2ccfa31c2b34d370dc4b --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/PixelMultipleConnection1D.h @@ -0,0 +1,128 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// PixelMultipleConnection1D.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Pixel Detector software +/////////////////////////////////////////////////////////////////// + + +#ifndef INDETREADOUTGEOMETRY_PIXELMULTIPLECONNECTION1D_H +#define INDETREADOUTGEOMETRY_PIXELMULTIPLECONNECTION1D_H + +#include <vector> + +namespace InDetDD { + + /** @class PixelMultipleConnection1D + + Class used to handle connection of multiple diodes to the same readout cell + + @author: David Calvet + @modifed: Grant Gorfine, Andreas Salzburger + */ + + class PixelMultipleConnection1D { + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + PixelMultipleConnection1D(); + + /** Constructor with parameters: + lower diode index for which the connection scheme is given + vector containing, for each diode, the readout cell number to which + the corresponding diode is connected */ + PixelMultipleConnection1D(const int lowerIndex, const std::vector<int> &connections); + + + void set(const int lowerIndex, const std::vector<int> &connections); + + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /** Check if the readout cell is in the range; Also for index of gangedCell. */ + bool outsideReadout(const int index) const; + + /** Check if the diode is in the range: */ + bool outsideDiode(const int cell) const; + + /** Return the number of diodes that are connected to this readout cell, Must check outsideReadout first. */ + int numberOfConnectedCells(const int index) const; + + /** Return the diode index corresponding the this readout. + number 0 will return the primary cell (ie diode index = readout cell index) + Must check outsideReadout first.*/ + int connectedCell(const int index, unsigned int number) const; + + /** Return readout cell id of this diode, Must check outsideDiode first. */ + int readoutOfDiode(const int index) const; + + /** If the diode is gnaged return the other diode. If the diode is not ganged return the same diode. + Must check outsideReadout first. */ + int gangedCell(const int index) const; + + /////////////////////////////////////////////////////////////////// + // Private data: + /////////////////////////////////////////////////////////////////// + private: + int m_lowerDiode; //!< lower diode index to which it applies + int m_upperDiode; //!< upper diode index to which it applies + int m_lowerReadout; //!< lower cell to which it applies + int m_upperReadout; //!< upper cell to which it applies + std::vector< std::vector<int> > m_readoutToDiode; //!< connection table readout -> diodes + std::vector<int> m_diodeToReadout; //!< connection table diode -> readout + std::vector<int> m_diodeGanged; //!< connection table diode -> other diode. + + /////////////////////////////////////////////////////////////////// + // Private methods: + /////////////////////////////////////////////////////////////////// + void debugPrintout(); + +}; + +/////////////////////////////////////////////////////////////////// +// Inline methods: +/////////////////////////////////////////////////////////////////// + +inline bool PixelMultipleConnection1D::outsideReadout(const int readout) const +{ + return (readout<m_lowerReadout || readout>m_upperReadout); +} + + +inline bool PixelMultipleConnection1D::outsideDiode(const int diode) const +{ + return (diode<m_lowerDiode || diode>m_upperDiode); +} + + +inline int PixelMultipleConnection1D::numberOfConnectedCells(const int index) const +{ + return m_readoutToDiode[index - m_lowerReadout].size(); +} + +inline int PixelMultipleConnection1D::connectedCell(const int index, unsigned int number) const +{ + return m_readoutToDiode[index - m_lowerReadout][number]; +} + +inline int PixelMultipleConnection1D::readoutOfDiode(const int index) const +{ + return m_diodeToReadout[index - m_lowerDiode]; +} + +inline int PixelMultipleConnection1D::gangedCell(const int index) const +{ + return m_diodeGanged[index - m_lowerReadout]; +} + +} // namespace InDetDD + +#endif // INDETREADOUTGEOMETRY_PIXELMULTIPLECONNECTION1D_H diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/PixelReadoutScheme.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/PixelReadoutScheme.h new file mode 100755 index 0000000000000000000000000000000000000000..fb5762dd199fcfee98bdf338b24213e2dd6f39cc --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/PixelReadoutScheme.h @@ -0,0 +1,157 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// PixelReadoutScheme.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Pixel Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef INDETREADOUTGEOMETRY_PIXELREADOUTSCHEME_H +#define INDETREADOUTGEOMETRY_PIXELREADOUTSCHEME_H + +// Data member classes +#include "InDetReadoutGeometry/PixelMultipleConnection1D.h" + +// Input and output classes +#include "InDetReadoutGeometry/SiReadoutCellId.h" +#include "InDetReadoutGeometry/SiCellId.h" + +namespace InDetDD { + + /** @class PixelReadoutScheme + + Class used to describe the connection scheme of a diode matrix + to a set of readout circuits + - to get the readout cell connected to a diode + - to get the list of diodes connected to a readout cell + + @author David Calvet + - modified on 5/10/04 Davide Costanzo. Replace PixelModulePosition with SiCellId + - modified: Grant Gorfine, Andreas Salzburger + */ + + class PixelReadoutScheme { + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + /////////////////////////////////////////////////////////////////// + // Constructors/destructor: + /////////////////////////////////////////////////////////////////// + + /** Constructor with parameters: + + number of circuits in one circuit column + number of circuits in one circuit row + number of cell columns per circuit + number of cell rows per circuit + number of diode columns connected to one circuit + number of diode rows connected to one circuit */ + PixelReadoutScheme(const int circuitsPerColumn,const int circuitsPerRow, + const int cellColumnsPerCircuit, + const int cellRowsPerCircuit, + const int diodeColumnsPerCircuit, + const int diodeRowsPerCircuit); + + /** Destructor: */ + ~PixelReadoutScheme(); + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /** total number of circuits: */ + int numberOfCircuits() const; + + /** number of cell columns per circuit: */ + int columnsPerCircuit() const; + + /** number of cell rows per circuit:*/ + int rowsPerCircuit() const; + + /** number of cell columns per module:*/ + int columns() const; + + /** number of cell rows per module:*/ + int rows() const; + + /** number of cells connected to this readout.*/ + int numberOfConnectedCells(const SiReadoutCellId & readoutId) const; + + /** Cell ids of cell connected to this readout.*/ + SiCellId connectedCell(const SiReadoutCellId & readoutId, unsigned int number) const; + + /** Readout id of this diode.*/ + SiReadoutCellId readoutIdOfCell(const SiCellId & cellId) const; + + /** If cell is ganged return the other cell, otherwise return an invalid id.*/ + SiCellId gangedCell(const SiCellId & cellId) const; + + /////////////////////////////////////////////////////////////////// + // Non-const methods: + /////////////////////////////////////////////////////////////////// + + /** Add a new multiple connection for rows: + lower diode row for which the connection scheme is given + vector containing, for each diode, the readout cell row number + to which the corresponding diode is connected */ + void addMultipleRowConnection(const int lowerRow, const std::vector<int> &connections); + + /////////////////////////////////////////////////////////////////// + // Private methods: + /////////////////////////////////////////////////////////////////// + private: + + PixelReadoutScheme(); + + /////////////////////////////////////////////////////////////////// + // Private data: + /////////////////////////////////////////////////////////////////// + private: + PixelMultipleConnection1D m_rowConnections; //!< multiple connections for rows + int m_numberOfCircuits; //!< total number of circuits + int m_columnsPerCircuit; //!< number of cell columns per circuit + int m_rowsPerCircuit; //!< number of cell rows per circuit + int m_columns; //!< Number of columns + int m_rows; //!< Number of rows + +}; + +/////////////////////////////////////////////////////////////////// +// Inline methods: +/////////////////////////////////////////////////////////////////// +inline PixelReadoutScheme::~PixelReadoutScheme() +{} + +inline int PixelReadoutScheme::numberOfCircuits() const +{ + return m_numberOfCircuits; +} + +inline int PixelReadoutScheme::columnsPerCircuit() const +{ + return m_columnsPerCircuit; +} + +inline int PixelReadoutScheme::rowsPerCircuit() const +{ + return m_rowsPerCircuit; +} + +inline int PixelReadoutScheme::columns() const +{ + return m_columns; +} + +inline int PixelReadoutScheme::rows() const +{ + return m_rows; +} + +} // namespace InDetDD + +#endif // INDETREADOUTGEOMETRY_PIXELREADOUTSCHEME_H diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SCT_BarrelModuleSideDesign.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SCT_BarrelModuleSideDesign.h new file mode 100755 index 0000000000000000000000000000000000000000..6e34388ff54fcb3ca5761b6493eb7f44f93e2fa8 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SCT_BarrelModuleSideDesign.h @@ -0,0 +1,224 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SCT_BarrelModuleSideDesign.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef INDETREADOUTGEOMETRY_SCT_BARRELMODULESIDEDESIGN_H +#define INDETREADOUTGEOMETRY_SCT_BARRELMODULESIDEDESIGN_H + +// Base class +#include "InDetReadoutGeometry/SCT_ModuleSideDesign.h" + +namespace Trk{ + class RectangleBounds; + class SurfaceBounds; +} + +namespace InDetDD { + + class SiDiodesParameters; + + /** @class SCT_BarrelModuleSideDesign + + Barrel module design description for the SCT. + + @author Szymon Gadomski, Alessandro Fornaini + - modified: Grant Gorfine, Andreas Salzburger + */ + + class SCT_BarrelModuleSideDesign : public SCT_ModuleSideDesign { + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + /** Copy constructor:*/ + SCT_BarrelModuleSideDesign(const SCT_BarrelModuleSideDesign &design); + + /** Constructor with parameters: + strip pitch, 80 um in barrel SCT + strip length + geom position on G4 volume, care needed + geom position on G4 volume, care needed + includes detector edge and gap between decetors*/ + SCT_BarrelModuleSideDesign(const double thickness, + const int crystals, + const int diodes, + const int cells, + const int shift, + const bool swapStripReadout, + InDetDD::CarrierType carrierType, + const double stripPitch, + const double stripLength, + const double xEtaStripPatternCentre, + const double xPhiStripPatternCentre, + const double totalDeadLength, + int readoutSide = -1); + + /** Destructor: */ + ~SCT_BarrelModuleSideDesign(); + + /** Assignment operator: */ + SCT_BarrelModuleSideDesign &operator=(const SCT_BarrelModuleSideDesign &design); + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /** strip pitch */ + virtual double stripPitch() const; + + /** strip length */ + double stripLength() const; + + /** centre of the strip pattern in eta */ + double etaStripPatternCentre() const; + + /** centre of the strip pattern in phi*/ + double phiStripPatternCentre() const; + + /** Returns distance to nearest detector active edge + +ve = inside + -ve = outside */ + virtual void distanceToDetectorEdge(const SiLocalPosition & localPosition, double & etaDist, double & phiDist) const; + + /** Test if near bond gap within tolerances */ + virtual bool nearBondGap(const SiLocalPosition & localPosition, double etaTol) const; + + /** check if the position is in active area */ + virtual bool inActiveArea(const SiLocalPosition &chargePos, bool checkBondGap = true) const; + + /** distance to the nearest diode in units of pitch, from 0.0 to 0.5, + this method should be fast as it is called for every surface charge + in the SCT_SurfaceChargesGenerator + an active area check, done in the Generator anyway, is removed here*/ + virtual double scaledDistanceToNearestDiode(const SiLocalPosition &chargePos) const; + + /** give the strip pitch (dependence on position needed for forward) */ + virtual double stripPitch(const SiLocalPosition & chargePos) const; + + /** readout or diode id -> position, size */ + virtual SiDiodesParameters parameters(const SiCellId & cellId) const; + virtual SiLocalPosition localPositionOfCell(const SiCellId & cellId) const; + virtual SiLocalPosition localPositionOfCluster(const SiCellId & cellId, int clusterSize) const; + + /** position -> id */ + virtual SiCellId cellIdOfPosition(const SiLocalPosition & localPos) const; + + /** this method returns the ends of the strip */ + virtual std::pair<SiLocalPosition,SiLocalPosition> endsOfStrip(const SiLocalPosition &position) const; + + /** method for stereo angle computation - returns a vector parallel to the strip being hit */ + virtual HepGeom::Vector3D<double> phiMeasureSegment(const SiLocalPosition & ) const; + + /** Method to calculate length of a module*/ + virtual double length() const; + + /** Method to calculate average width of a module */ + virtual double width() const; + + /** Method to calculate minimum width of a module */ + virtual double minWidth() const; + + /** Method to calculate maximum width of a module */ + virtual double maxWidth() const; + + /** give length of dead area */ + virtual double deadAreaLength() const; + + /** give upper boundary of dead area */ + virtual double deadAreaUpperBoundary() const; + + /** give lower boundary of dead area */ + virtual double deadAreaLowerBoundary() const; + + /** Pitch in phi direction */ + virtual double phiPitch() const; + + /* Pitch in phi direction */ + virtual double phiPitch(const SiLocalPosition & localPosition) const; + + /** Pitch in eta direction */ + virtual double etaPitch() const; + + /** Return the surface bounds */ + virtual const Trk::SurfaceBounds & bounds() const; + + private: + + SCT_BarrelModuleSideDesign(); + + /////////////////////////////////////////////////////////////////// + // Private data: + /////////////////////////////////////////////////////////////////// + + private: + double m_stripPitch; //!< strip pitch, 80 um in barrel SCT + double m_stripLength; //!< strip length + double m_xEtaStripPatternCentre; //!< geom position on G4 volume, care needed + double m_xPhiStripPatternCentre; //!< geom position on G4 volume, care needed + double m_totalDeadLength; //!< includes detector edge and gap between decetors + double m_xPhiAbsSize; //!< size in xPhi/2 for active area + double m_xEtaAbsSizeLow, m_xEtaAbsSizeHigh; //!< active area in xEta + Trk::RectangleBounds * m_bounds; //!< surface bound description + }; + + /////////////////////////////////////////////////////////////////// + // Inline methods: + /////////////////////////////////////////////////////////////////// + inline double SCT_BarrelModuleSideDesign::stripPitch() const + { + return m_stripPitch; + } + + // this method is non trivial in forward, but in barrel it can + // be an inline function + inline double SCT_BarrelModuleSideDesign::stripPitch(const SiLocalPosition &) const + { + return m_stripPitch; + } + + + inline double SCT_BarrelModuleSideDesign::stripLength() const + { + return m_stripLength; + } + + inline double SCT_BarrelModuleSideDesign::etaStripPatternCentre() const + { + return m_xEtaStripPatternCentre; + } + + inline double SCT_BarrelModuleSideDesign::phiStripPatternCentre() const + { + return m_xPhiStripPatternCentre; + } + + // Same as stripPitch + inline double SCT_BarrelModuleSideDesign::phiPitch(const SiLocalPosition &) const + { + return m_stripPitch; + } + + // Same as stripPitch + inline double SCT_BarrelModuleSideDesign::phiPitch() const + { + return m_stripPitch; + } + + // Same as active length + inline double SCT_BarrelModuleSideDesign::etaPitch() const + { + return length(); + } + +} // namespace InDetDD + +#endif // INDETREADOUTGEOMETRY_SCT_BARRELMODULESIDEDESIGN_H + diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SCT_DetectorManager.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SCT_DetectorManager.h new file mode 100755 index 0000000000000000000000000000000000000000..925a40cc14c66de81b8ebb5023294fa7ada5aa19 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SCT_DetectorManager.h @@ -0,0 +1,143 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SCT_DetectorManager.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef INDETREADOUTGEOMETRY_SCT_DETECTORMANAGER_H +#define INDETREADOUTGEOMETRY_SCT_DETECTORMANAGER_H + +#include "GeoPrimitives/GeoPrimitives.h" + +#include "GeoModelKernel/GeoVPhysVol.h" + +#include "InDetReadoutGeometry/SiDetectorManager.h" +#include "InDetReadoutGeometry/SiDetectorElementCollection.h" +#include "InDetReadoutGeometry/InDetDD_Defs.h" + +#include "InDetIdentifier/SCT_ID.h" + +class StoreGateSvc; +class Identifier; +class IdentifierHash; +class GeoAlignableTransform; +class GeoVFullPhysVol; +class GeoVPhysVol; + +namespace InDetDD { + + class SiDetectorElement; + class ExtendedAlignableTransform; + class SCT_ModuleSideDesign; + + /** @class SCT_DetectorManager + + Dedicated detector manager extending the functionality of the SiDetectorManager + with dedicated SCT information, access. + + @author: Grant Gorfine + - modified and maintained by Nick Styles & Andreas Salzburger + */ + + class SCT_DetectorManager : public SiDetectorManager { + + public: + + // Constructor + SCT_DetectorManager( StoreGateSvc* detStore ); + + // Destructor + virtual ~SCT_DetectorManager(); + + /** Access Raw Geometry */ + virtual unsigned int getNumTreeTops() const; + virtual PVConstLink getTreeTop(unsigned int i) const; + /** Add tree top */ + void addTreeTop(PVLink); + + + // + // Access Readout Elements + // + + /** access to individual elements via Identifier */ + virtual SiDetectorElement * getDetectorElement(const Identifier &id) const; + + /** access to individual elements via IdentifierHash */ + virtual SiDetectorElement * getDetectorElement(const IdentifierHash &idHash) const; + + /** access to individual elements via module numbering schema */ + SiDetectorElement * getDetectorElement(int barrel_endcap, int layer_wheel, int phi_module, int eta_module, int side) const; + + /** access to whole collectiom via iterators */ + virtual const SiDetectorElementCollection * getDetectorElementCollection() const; + virtual SiDetectorElementCollection::const_iterator getDetectorElementBegin() const; + virtual SiDetectorElementCollection::const_iterator getDetectorElementEnd() const; + + /** Add elememts during construction */ + virtual void addDetectorElement(SiDetectorElement * element); + + /** Add alignable transforms. No access to these, they will be changed by manager: */ + virtual void addAlignableTransform (int level, + const Identifier &id, + GeoAlignableTransform *xf, + const GeoVFullPhysVol * child); + + /** As above but does a dynamic_cast to GeoVFullPhysVol */ + virtual void addAlignableTransform (int level, + const Identifier &id, + GeoAlignableTransform *xf, + const GeoVPhysVol * child); + + // DEPRECATED + virtual void addAlignableTransform (int, const Identifier &, GeoAlignableTransform *) {}; // For backward compatibility + + /** Initialize the neighbours. This can only be done when all elements are built. */ + virtual void initNeighbours(); + + /** Methods to query which manager we have */ + virtual bool isPixel() const {return false;} + + /** Check identifier is for this detector */ + virtual bool identifierBelongs(const Identifier & id) const; + + /** Access to module design, casts to SCT_ModuleSideDesign */ + const SCT_ModuleSideDesign * getSCT_Design(int i) const; + + private: + /** implements the main alignment update for delta transforms in different frames, + it translates into the LocalDelta or GlobalDelta function of SiDetectorManager + */ + virtual bool setAlignableTransformDelta(int level, + const Identifier & id, + const Amg::Transform3D & delta, + FrameType frame) const; + + /** Prevent copy and assignment */ + const SCT_DetectorManager & operator=(const SCT_DetectorManager &right); + SCT_DetectorManager(const SCT_DetectorManager &right); + + virtual const SCT_ID * getIdHelper() const; + + // Private member data + std::vector<PVLink> m_volume; + SiDetectorElementCollection m_elementCollection; + typedef std::map<Identifier, ExtendedAlignableTransform *> AlignableTransformMap; + std::vector< AlignableTransformMap > m_higherAlignableTransforms; + std::vector< ExtendedAlignableTransform *> m_alignableTransforms; + std::vector< ExtendedAlignableTransform *> m_moduleAlignableTransforms; + const SCT_ID* m_idHelper; + }; + +} // namespace InDetDD + +#ifndef GAUDI_NEUTRAL +#include "CLIDSvc/CLASS_DEF.h" +CLASS_DEF(InDetDD::SCT_DetectorManager, 72488296, 1) +#endif + +#endif // INDETREADOUTGEOMETRY_SCT_DETECTORMANAGER_H diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SCT_ForwardFrameTransformation.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SCT_ForwardFrameTransformation.h new file mode 100755 index 0000000000000000000000000000000000000000..c0781b019f093b6f4006a4d9d8a3daf698a8bdeb --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SCT_ForwardFrameTransformation.h @@ -0,0 +1,108 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SCT_ForwardFrameTransformation.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef INDETREADOUTGEOMETRY_SCT_FORWARDFRAMETRANSFORMATION_H +#define INDETREADOUTGEOMETRY_SCT_FORWARDFRAMETRANSFORMATION_H + +namespace InDetDD { + +class SCT_ForwardPolarPosition; +class SiLocalPosition; + + + /** @class SCT_ForwardFrameTransformation + + Class that connect cartesian and pokar coordinates + + @author: Grant Gorfine + - modified & maintained : Andreas Salzburger */ + + class SCT_ForwardFrameTransformation { + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + /** Copy constructor: */ + SCT_ForwardFrameTransformation(const SCT_ForwardFrameTransformation &frame); + + /** Constructor with parameters: + eta coordinate of module center + phi coordinate of module center + r from module center to beam */ + SCT_ForwardFrameTransformation(const double etaCenter,const double phiCenter, + const double radius); + + /** Destructor: */ + ~SCT_ForwardFrameTransformation(); + + /** Assignment operator: */ + SCT_ForwardFrameTransformation &operator=(const SCT_ForwardFrameTransformation &frame); + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /** eta coordinate of module center: */ + double etaCenter() const; + + /** phi coordinate of modulecenter: */ + double phiCenter() const; + + /** r from module center to beam:*/ + double radius() const; + + /** create a SCT_ForwardPolarPosition from a SiLocalPosition */ + SCT_ForwardPolarPosition polarFromCartesian(const SiLocalPosition& cartesian) const; + + /** create a SiLocalPosition from a SCT_ForwardPolarPosition */ + SiLocalPosition cartesianFromPolar(const SCT_ForwardPolarPosition& polar) const; + + /////////////////////////////////////////////////////////////////// + // Private methods: + /////////////////////////////////////////////////////////////////// + private: + + SCT_ForwardFrameTransformation(); + + /////////////////////////////////////////////////////////////////// + // Private data: + /////////////////////////////////////////////////////////////////// + private: + double m_etaCenter; //!< eta coordinate of module center + double m_phiCenter; //!< phi coordinate of module center + double m_radius; //!< r from module center to beam +}; + +/////////////////////////////////////////////////////////////////// +// Inline methods: +/////////////////////////////////////////////////////////////////// +inline SCT_ForwardFrameTransformation::~SCT_ForwardFrameTransformation() +{} + +inline double SCT_ForwardFrameTransformation::etaCenter() const +{ + return m_etaCenter; +} + +inline double SCT_ForwardFrameTransformation::phiCenter() const +{ + return m_phiCenter; +} + +inline double SCT_ForwardFrameTransformation::radius() const +{ + return m_radius; +} + +} // namespace InDetDD + +#endif // INDETREADOUTGEOMETRY_SCT_FORWARDFRAMETRANSFORMATION_H diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SCT_ForwardModuleSideDesign.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SCT_ForwardModuleSideDesign.h new file mode 100755 index 0000000000000000000000000000000000000000..bce84103d2422cfd475cdb9f40bb1f3e6ce9a4b4 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SCT_ForwardModuleSideDesign.h @@ -0,0 +1,214 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SCT_ForwardModuleSideDesign.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef INDETREADOUTGEOMETRY_SCT_FORWARDMODULESIDEDESIGN_H +#define INDETREADOUTGEOMETRY_SCT_FORWARDMODULESIDEDESIGN_H + +// Base class +#include "InDetReadoutGeometry/SCT_ModuleSideDesign.h" + +//Data member classes +#include "InDetReadoutGeometry/SCT_ForwardFrameTransformation.h" +#include "InDetReadoutGeometry/SCT_ForwardModuleSideGeometry.h" + +namespace Trk{ + class TrapezoidBounds; + class SurfaceBounds; +} + + +namespace InDetDD { + + /** + @class SCT_ForwardModuleSideDesign + + Design descriptor for forward modules in the SCT, + carries the bounds, and readout information. + + @author Grant Gorfine + - modified & maintained: Nick Styles, Andreas Salzburger + */ + + class SCT_ForwardModuleSideDesign : public SCT_ModuleSideDesign { + + public: + + /** Constructor with parameters: + local axis corresponding to eta direction + local axis corresponding to phi direction + local axis corresponding to depth direction + thickness of silicon sensor + number of crystals within module side + number of diodes within crystal + number of cells within module side + index of diode connected to cell with index 0 + r from inner crystal center to beam + inner crystal half height + r from outer crystal (if present) center to beam + outer crystal (if present) half height + strip step in angle (same for both crystals) + eta coordinate of crystal center + phi coordinate of crystal center */ + SCT_ForwardModuleSideDesign(const double thickness, + const int crystals,const int diodes, + const int cells,const int shift, + const bool swapStripReadout, + InDetDD::CarrierType carrierType, + const double radius1,const double halfHeight1, + const double radius2,const double halfHeight2, + const double step, + const double etaCenter,const double phiCenter, + int readoutSide = -1); + + /** Destructor: */ + virtual ~SCT_ForwardModuleSideDesign(); + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /** Returns distance to nearest detector active edge + +ve = inside + -ve = outside */ + virtual void distanceToDetectorEdge(const SiLocalPosition & localPosition, + double & etaDist, double & phiDist) const; + + /** Test if near bond gap within tolerances */ + virtual bool nearBondGap(const SiLocalPosition & localPosition, double etaTol) const; + + /** check if the position is in active area */ + virtual bool inActiveArea(const SiLocalPosition &chargePos, bool checkBondGap = true) const; + + /** give distance to the nearest diode in units of pitch, from 0.0 to 0.5, + this method should be fast as it is called for every surface charge + in the SCT_SurfaceChargesGenerator */ + virtual double scaledDistanceToNearestDiode(const SiLocalPosition &chargePos) const; + + /** give the strip pitch (dependence on position needed for forward) */ + virtual double stripPitch(const SiLocalPosition & chargePos) const; + + /** give the strip pitch (For Forward returns pitch at center) */ + virtual double stripPitch() const; + + /** readout or diode id -> position, size */ + virtual SiDiodesParameters parameters(const SiCellId & cellId) const; + virtual SiLocalPosition localPositionOfCell(const SiCellId & cellId) const; + virtual SiLocalPosition localPositionOfCluster(const SiCellId & cellId, int clusterSize) const; + + /** position -> id */ + virtual SiCellId cellIdOfPosition(const SiLocalPosition & localPos) const; + + /** this method returns the ends of the strip */ + virtual std::pair<SiLocalPosition,SiLocalPosition> endsOfStrip(const SiLocalPosition &position) const; + + /** method for stereo angle computation - returns a vector parallel to the strip being hit */ + virtual HepGeom::Vector3D<double> phiMeasureSegment(const SiLocalPosition &position) const; + + /** Nominal center radius of double wafer. */ + double radius() const; + + /** Method to calculate length of a module */ + virtual double length() const; + + /** Method to calculate average width of a module */ + virtual double width() const; + + /** Method to calculate minimum width of a module */ + virtual double minWidth() const; + + /** Method to calculate maximum width of a module */ + virtual double maxWidth() const; + + /** give length of dead area */ + virtual double deadAreaLength() const; + + /** give upper boundary of dead area */ + virtual double deadAreaUpperBoundary() const; + + /** give lower boundary of dead area */ + virtual double deadAreaLowerBoundary() const; + + /** Pitch in phi direction */ + virtual double phiPitch() const; + + /** Pitch in phi direction */ + virtual double phiPitch(const SiLocalPosition & localPosition) const; + + /** Pitch in eta direction */ + virtual double etaPitch() const; + + /** Angular pitch */ + double angularPitch() const; + + /** Shape of element */ + virtual DetectorShape shape() const; + + /** Element boundary */ + virtual const Trk::SurfaceBounds & bounds() const; + + private: + + /** Forbidden default constructor */ + SCT_ForwardModuleSideDesign(); + + /** Copy constructor: */ + SCT_ForwardModuleSideDesign(const SCT_ForwardModuleSideDesign &design); + + /** Assignment operator: */ + SCT_ForwardModuleSideDesign &operator=(const SCT_ForwardModuleSideDesign &design); + + /////////////////////////////////////////////////////////////////// + // Private data: + /////////////////////////////////////////////////////////////////// + + private: + SCT_ForwardModuleSideGeometry m_geometry; //!< geometry of module side + SCT_ForwardFrameTransformation m_frame; //!< polar / cartesian frame transformation + Trk::TrapezoidBounds * m_bounds; + }; + + + /////////////////////////////////////////////////////////////////// + // Inline methods: + /////////////////////////////////////////////////////////////////// + + + inline double SCT_ForwardModuleSideDesign::radius() const + { + return m_geometry.radius(); + } + + // Same as stripPitch + inline double SCT_ForwardModuleSideDesign::phiPitch(const SiLocalPosition & localPosition) const + { + return stripPitch(localPosition); + } + + // Same as stripPitch + inline double SCT_ForwardModuleSideDesign::phiPitch() const + { + return stripPitch(); + } + + // Same as active length + inline double SCT_ForwardModuleSideDesign::etaPitch() const + { + return length(); + } + + // Same as active length + inline double SCT_ForwardModuleSideDesign::angularPitch() const + { + return m_geometry.angularPitch(); + } + +} // namespace InDetDD + +#endif // INDETREADOUTGEOMETRY_SCT_FORWARDMODULESIDEDESIGN_H diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SCT_ForwardModuleSideGeometry.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SCT_ForwardModuleSideGeometry.h new file mode 100755 index 0000000000000000000000000000000000000000..50a75064e9511041c4f5a84e8314b6f988e2455b --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SCT_ForwardModuleSideGeometry.h @@ -0,0 +1,211 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SCT_ForwardModuleSideGeometry.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef INDETREADOUTGEOMETRY_SCT_FORWARDMODULESIDEGEOMETRY_H +#define INDETREADOUTGEOMETRY_SCT_FORWARDMODULESIDEGEOMETRY_H + +#include "InDetReadoutGeometry/SiLocalPosition.h" +#include "InDetReadoutGeometry/SCT_ForwardPolarPosition.h" + +namespace InDetDD { + + /** + @class SCT_ForwardModuleSideGeometry + + Geometry descriptor holding strig number, + crystel inner and outer half length & radius. + + @author Grant Gorfine + + */ + + class SCT_ForwardModuleSideGeometry { + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + /** Constructor with parameters: + r from inner crystal center to beam + inner crystal half height + r from outer crystal (if present) center to beam + outer crystal (if present) half height + number of strips (same for both crystals) + strip step in angle (same for both crystals) + number of crystals per module side */ + + SCT_ForwardModuleSideGeometry(const double radius1, const double halfHeight1, + const double radius2, const double halfHeight2, + const int strips, const double step, + const int nCrystals); + + /** Destructor: */ + ~SCT_ForwardModuleSideGeometry(); + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /** Nominal center radius of double wafer. */ + double radius() const; + + /** r from inner crystal center to beam:*/ + double radius1() const; + + /** inner crystal half height: */ + double halfHeight1() const; + + /** r from outer crystal (if present) center to beam: */ + double radius2() const; + + /** outer crystal (if present) half height: */ + double halfHeight2() const; + + /** number of strips (same for both crystals): */ + int strips() const; + + /** strip step in angle (same for both crystals): */ + double step() const; + double angularPitch() const; + + /** number of crystals per module side */ + int nCrystals() const; + + void distanceToDetectorEdge(const SiLocalPosition & localPosition, + const SCT_ForwardPolarPosition &polarPos, + double & etaDist, double & phiDist) const; + + /** Test if near bond gap within tolerances */ + bool nearBondGap(const SiLocalPosition & localPosition, double etaTol) const; + + /** check if position is in active area */ + bool inActiveArea(const SiLocalPosition & chargePosition, bool checkBondGap = true) const; + + /** DEPRECATED */ + bool inActiveArea(const SCT_ForwardPolarPosition &polarPos) const; + + /** give the strip pitch (dependence on position needed for forward) */ + double stripPitch(const SCT_ForwardPolarPosition &polarPos) const; + + /** give distance to the nearest diode in units of pitch, from 0.0 to 0.5, + this method should be fast as it is called for every surface charge + in the SCT_SurfaceChargesGenerator */ + double scaledDistanceToNearestDiode(const SCT_ForwardPolarPosition& polarPos) const; + + /** Method to calculate length of a module*/ + double length() const; + + /** Method to calculate average width of a module*/ + double width() const; + + /** Method to calculate minimum width of a module*/ + double minWidth() const; + + /** Method to calculate maximum width of a module */ + double maxWidth() const; + + /** give length of dead area */ + double deadAreaLength() const; + + /** give upper boundary of dead area */ + double deadAreaUpperBoundary() const; + + /** give lower boundary of dead area */ + double deadAreaLowerBoundary() const; + + /////////////////////////////////////////////////////////////////// + // Private methods: + /////////////////////////////////////////////////////////////////// + private: + + SCT_ForwardModuleSideGeometry(); + + /////////////////////////////////////////////////////////////////// + // Private data: + /////////////////////////////////////////////////////////////////// + private: + double m_radius; //!< r from nominal element center to beam + double m_radius1; //!< r from inner crystal center to beam + double m_halfHeight1; //!< inner crystal half height + double m_radius2; //!< r from outer crystal (if present) center to beam + double m_halfHeight2; //!< outer crystal (if present) half height + int m_strips; //!< number of strips (same for both crystals) + double m_step; //!< strip step in angle (same for both crystals) + int m_nCrystals; //!< number of crystals per module side + double m_leftSide; //!< left border of module in angle + double m_rightSide; //!< right border of module in angle + double m_upperSide1; //!< upper side of crystal 1 + double m_lowerSide1; //!< lower side of crystal 1 + double m_upperSide2; //!< upper side of crystal 2 + double m_lowerSide2; //!< lower side of crystal 2 + + double m_halfLength; //!< top = +halfLength, bot = -halfLength + double m_deadRegionUpper; //!< relative to center of detector. + double m_deadRegionLower; //!< relative to center of detector. + double m_tangent; //!< tan(theta) at edge = (halfWidth) / (radius) + +}; + +/////////////////////////////////////////////////////////////////// +// Inline methods: +/////////////////////////////////////////////////////////////////// +inline SCT_ForwardModuleSideGeometry::~SCT_ForwardModuleSideGeometry() +{} + +inline double SCT_ForwardModuleSideGeometry::radius1() const +{ + return m_radius1; +} + +inline double SCT_ForwardModuleSideGeometry::radius() const +{ + return m_radius; +} + +inline double SCT_ForwardModuleSideGeometry::halfHeight1() const +{ + return m_halfHeight1; +} + +inline double SCT_ForwardModuleSideGeometry::radius2() const +{ + return m_radius2; +} + +inline double SCT_ForwardModuleSideGeometry::halfHeight2() const +{ + return m_halfHeight2; +} + +inline int SCT_ForwardModuleSideGeometry::strips() const +{ + return m_strips; +} + +inline double SCT_ForwardModuleSideGeometry::step() const +{ + return m_step; +} + +inline double SCT_ForwardModuleSideGeometry::angularPitch() const +{ + return m_step; +} + +inline int SCT_ForwardModuleSideGeometry::nCrystals() const +{ + return m_nCrystals; +} + +} // namespace InDetDD + +#endif // INDETREADOUTGEOMETRY_SCT_FORWARDMODULESIDEGEOMETRY_H + diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SCT_ForwardPolarPosition.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SCT_ForwardPolarPosition.h new file mode 100755 index 0000000000000000000000000000000000000000..a3d72d88f67b0417fdf978a165d75399688e670a --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SCT_ForwardPolarPosition.h @@ -0,0 +1,88 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SCT_ForwardPolarPosition.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef INDETREADOUTGEOMETRY_SCT_FORWARDPOLARPOSITION_H +#define INDETREADOUTGEOMETRY_SCT_FORWARDPOLARPOSITION_H + +#include <string> + +namespace InDetDD { + + /** @class SCT_ForwardPolarPosition + + 2D position in polar coordinates for the polar frame in + the SCT endcaps. + + @author Grant Gorfine + */ + class SCT_ForwardPolarPosition { + + public: + + // Implicit constructor + SCT_ForwardPolarPosition(); + + // Copy constructor: + SCT_ForwardPolarPosition(const SCT_ForwardPolarPosition &polar); + + /** Constructor with parameters: + r coordinate of point + theta coordinate of point */ + SCT_ForwardPolarPosition(const double r,const double theta); + + // Destructor: + virtual ~SCT_ForwardPolarPosition(); + + // Assignment operator: + SCT_ForwardPolarPosition &operator=(const SCT_ForwardPolarPosition &polar); + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /** r coordinate of point: */ + double r() const; + + /** theta coordinate of point: */ + double theta() const; + + //Comparison operator + virtual bool operator==(const SCT_ForwardPolarPosition &polar) const; + + //Print method: + virtual std::string print() const; + + /////////////////////////////////////////////////////////////////// + // Private data: + /////////////////////////////////////////////////////////////////// + private: + double m_r; // r coordinate of point + double m_theta; // theta coordinate of point + }; + + /////////////////////////////////////////////////////////////////// + // Inline methods: + /////////////////////////////////////////////////////////////////// + + inline double SCT_ForwardPolarPosition::r() const + { + return m_r; + } + + inline double SCT_ForwardPolarPosition::theta() const + { + return m_theta; + } + +} // namespace InDetDD + +#endif // INDETREADOUTGEOMETRY_SCT_FORWARDPOLARPOSITION_H + + diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SCT_ModuleSideDesign.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SCT_ModuleSideDesign.h new file mode 100755 index 0000000000000000000000000000000000000000..84681b1dbe8afd83ff3535a59254e5faee8c5618 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SCT_ModuleSideDesign.h @@ -0,0 +1,227 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SCT_ModuleSideDesign.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + + +#ifndef INDETREADOUTGEOMETRY_SCT_MODULESIDEDESIGN_H +#define INDETREADOUTGEOMETRY_SCT_MODULESIDEDESIGN_H + +// Base class +#include "InDetReadoutGeometry/SiDetectorDesign.h" + +// Data member class +#include "InDetReadoutGeometry/SCT_ReadoutScheme.h" + +// Other includes +#include "InDetIdentifier/SCT_ID.h" + +namespace InDetDD { + + /** @class SCT_ModuleSideDesign + + Base class for the SCT module side design, + extended by the Forward and Barrel module design + + @author Alessandro Fornaini, Grant Gorfine + */ + + class SCT_ModuleSideDesign : public SiDetectorDesign { + + public: + + /** Constructor with parameters: + local axis corresponding to eta direction + local axis corresponding to phi direction + local axis corresponding to depth direction + thickness of silicon sensor + number of crystals within module side + number of diodes within crystal + number of cells within module side + index of diode connected to cell with index 0 */ + SCT_ModuleSideDesign(const double thickness, + const bool phiSymmetric, + const bool etaSymmetric, + const bool depthSymmetric, + const int crystals, + const int diodes, + const int cells, + const int shift, + const bool swapStripReadout, + InDetDD::CarrierType carrierType, + int readoutSide); + + /** Destructor: */ + virtual ~SCT_ModuleSideDesign(); + + /** readout id -> id of connected diodes + Not particularly useful for the SCT but implemented to keep a uniform interface. */ + virtual int numberOfConnectedCells(const SiReadoutCellId & readoutId) const; + virtual SiCellId connectedCell(const SiReadoutCellId & readoutId, int number) const; + + /** If cell is ganged return the other cell, otherwise return an invalid id. + Not particularly useful for the SCT but implemented to keep a uniform interface. + For SCT always returns an invalid id. */ + virtual SiCellId gangedCell(const SiCellId & cellId) const; + + /** diode id -> readout id */ + virtual SiReadoutCellId readoutIdOfCell(const SiCellId & cellId) const; + + /** position -> id */ + virtual SiReadoutCellId readoutIdOfPosition(const SiLocalPosition & localPos) const; + + /** id -> position */ + virtual SiLocalPosition localPositionOfCell(const SiCellId & cellId) const = 0; + virtual SiLocalPosition localPositionOfCluster(const SiCellId & cellId, int cluserSize) const = 0; + + /** Check if cell is in range. Returns the original cellId if it is in range, otherwise it returns an invalid id. */ + virtual SiCellId cellIdInRange(const SiCellId & cellId) const; + + /** Get the neighbouring diodes of a given diode: + Cell for which the neighbours must be found + List of cells which are neighbours of the given one */ + virtual void neighboursOfCell(const SiCellId & cellId, + std::vector<SiCellId> &neighbours) const; + + /** check if the position is in active area */ + virtual bool inActiveArea(const SiLocalPosition &chargePos, bool checkBondGap = true) const = 0; + + /** give distance to the nearest diode in units of pitch, from 0.0 to 0.5, + this method should be fast as it is called for every surface charge + in the SCT_SurfaceChargesGenerator */ + virtual double scaledDistanceToNearestDiode(const SiLocalPosition &chargePos) const = 0; + + /** give the strip pitch (dependence on position needed for forward) */ + virtual double stripPitch(const SiLocalPosition & chargePos) const = 0; + + /** give the strip pitch (For Forward returns pitch at center) */ + virtual double stripPitch() const = 0; + + /** give the ends of strips */ + virtual std::pair<SiLocalPosition,SiLocalPosition> + endsOfStrip(const SiLocalPosition &position) const = 0; + + /** gives position of strip center + ALTERNATIVE/PREFERED way is to use localPositionOfCell(const SiCellId & cellId) or + rawLocalPositionOfCell method in SiDetectorElement. + DEPRECATED */ + virtual SiLocalPosition positionFromStrip(const int stripNumber) const; + + /** give length of dead area */ + virtual double deadAreaLength() const = 0; + + /** give upper boundary of dead area */ + virtual double deadAreaUpperBoundary() const = 0; + + /** give lower boundary of dead area */ + virtual double deadAreaLowerBoundary() const = 0; + + /** number of crystals within module side: */ + int crystals() const; + + /** number of strips within crystal: */ + int diodes() const; + + /** number of readout stips within module side: */ + int cells() const; + + /** number of edge strips before first readout strip. */ + int shift() const; + + /** Return true if hit local direction is the same as readout direction. */ + virtual bool swapHitPhiReadoutDirection() const; + virtual bool swapHitEtaReadoutDirection() const; + + private: + + SCT_ModuleSideDesign(); + + // Copy constructor: + SCT_ModuleSideDesign(const SCT_ModuleSideDesign &design); + + // Assignment operator: + SCT_ModuleSideDesign &operator=(const SCT_ModuleSideDesign &design); + + + /////////////////////////////////////////////////////////////////// + // Private data: + /////////////////////////////////////////////////////////////////// + private: + SCT_ReadoutScheme m_scheme; //!< connection between diodes and readout cells + bool m_swapStripReadout; //!< Flag to indicate if readout direction is opposite + //!< to hit local phi direction + + + }; + + /////////////////////////////////////////////////////////////////// + // Inline methods: + /////////////////////////////////////////////////////////////////// + inline int SCT_ModuleSideDesign::crystals() const + { + return m_scheme.crystals(); + } + + inline int SCT_ModuleSideDesign::diodes() const + { + return m_scheme.diodes(); + } + + inline int SCT_ModuleSideDesign::cells() const + { + return m_scheme.cells(); + } + + inline int SCT_ModuleSideDesign::shift() const + { + return m_scheme.shift(); + } + + + inline int SCT_ModuleSideDesign::numberOfConnectedCells(const SiReadoutCellId & readoutId) const + { + return m_scheme.numberOfConnectedCells(readoutId); + } + + inline SiCellId SCT_ModuleSideDesign::connectedCell(const SiReadoutCellId & readoutId, int number) const + { + return m_scheme.connectedCell(readoutId, number); + } + + inline SiCellId SCT_ModuleSideDesign::gangedCell(const SiCellId &) const + { + // No ganged cells in SCT so always return invalid id. + return SiCellId(); + } + + inline SiReadoutCellId SCT_ModuleSideDesign::readoutIdOfCell(const SiCellId & cellId) const + { + return m_scheme.readoutIdOfCell(cellId); + } + + inline SiReadoutCellId SCT_ModuleSideDesign::readoutIdOfPosition(const SiLocalPosition & localPos) const + { + // Get the cellId then convert it to a readoutId. + // NEED to think about active area and bond gap check + return readoutIdOfCell(cellIdOfPosition(localPos)); + } + + inline bool SCT_ModuleSideDesign::swapHitPhiReadoutDirection() const + { + return m_swapStripReadout; + } + + inline bool SCT_ModuleSideDesign::swapHitEtaReadoutDirection() const + { + return false; + } + +} // namespace InDetDD + +#endif // INDETREADOUTGEOMETRY_SCT_MODULESIDEDESIGN_H + diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SCT_ReadoutScheme.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SCT_ReadoutScheme.h new file mode 100755 index 0000000000000000000000000000000000000000..132a750f01eff5039cf89b2acb1729622a45010b --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SCT_ReadoutScheme.h @@ -0,0 +1,142 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SCT_ReadoutScheme.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef INDETREADOUTGEOMETRY_SCT_READOUTSCHEME_H +#define INDETREADOUTGEOMETRY_SCT_READOUTSCHEME_H + +#include "InDetReadoutGeometry/SiCellId.h" +#include "InDetReadoutGeometry/SiReadoutCellId.h" + +#include <list> + +namespace InDetDD { + + /** @class SCT_ReadoutScheme + + Definition of the readout scheme in the SCT detector describing, + number of sides, cells, crystals per module. + + @author Alessandro Fornaini, Grant Gorfine + */ + + class SCT_ReadoutScheme { + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + // Copy constructor: + SCT_ReadoutScheme(const SCT_ReadoutScheme &scheme); + + // Constructor with parameters: + // number of crystals within module side + // number of diodes within crystal + // number of cells within module side + // index of diode connected to cell with index 0 + SCT_ReadoutScheme(const int crystals,const int diodes, + const int cells,const int shift); + + // Destructor: + ~SCT_ReadoutScheme(); + + // Assignment operator: + SCT_ReadoutScheme &operator=(const SCT_ReadoutScheme &scheme); + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + // number of crystals within module side: + int crystals() const; + + // number of diodes within crystal: + int diodes() const; + + // number of cells within module side: + int cells() const; + + // index of diode connected to cell with index 0: + int shift() const; + + // readout id -> id of connected diodes + int numberOfConnectedCells(const SiReadoutCellId & readoutId) const; + SiCellId connectedCell(const SiReadoutCellId & readoutId, int number) const; + + // diode id -> readout id + SiReadoutCellId readoutIdOfCell(const SiCellId & cellId) const; + + + + /////////////////////////////////////////////////////////////////// + // Non-const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Private methods: + /////////////////////////////////////////////////////////////////// + private: + + SCT_ReadoutScheme(); + + /////////////////////////////////////////////////////////////////// + // Private data: + /////////////////////////////////////////////////////////////////// + private: + int m_crystals; // number of crystals within module side + int m_diodes; // number of diodes within crystal + int m_cells; // number of cells within module side + int m_shift; // index of diode connected to cell with index 0 +}; + +/////////////////////////////////////////////////////////////////// +// Inline methods: +/////////////////////////////////////////////////////////////////// +inline SCT_ReadoutScheme::~SCT_ReadoutScheme() +{} + +inline int SCT_ReadoutScheme::crystals() const +{ + return m_crystals; +} + +inline int SCT_ReadoutScheme::diodes() const +{ + return m_diodes; +} + +inline int SCT_ReadoutScheme::cells() const +{ + return m_cells; +} + +inline int SCT_ReadoutScheme::shift() const +{ + return m_shift; +} + +inline int SCT_ReadoutScheme::numberOfConnectedCells(const SiReadoutCellId & readoutId) const +{ + // Assume an in range readout id is used. No checks are made. + // Always 1 to 1 correspondence in SCT + return (readoutId.isValid()) ? 1 : 0; +} + + +inline SiCellId SCT_ReadoutScheme::connectedCell(const SiReadoutCellId & readoutId, int) const +{ + // Assume a valid readout id is used. + // Always 1 to 1 correspondence in SCT + return readoutId; // Allowed to convert a SiReadoutCellId to a SiCellId. +} + +} // namespace InDetDD + +#endif // INDETREADOUTGEOMETRY_SCT_READOUTSCHEME_H diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiCellId.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiCellId.h new file mode 100755 index 0000000000000000000000000000000000000000..29648bfd6a858677789fd80d2cb5fa4b86b10157 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiCellId.h @@ -0,0 +1,168 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SiCellId.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef INDETREADOUTGEOMETRY_SICELLID_H +#define INDETREADOUTGEOMETRY_SICELLID_H + +#include <iostream> + +namespace InDetDD { + + /** @class SiCellId + + Identifier for the strip or pixel cell. + Just the strip number for SCT or phi_index, eta_index for pixel. + Packs the numbers in an int. + Supports negative indices and is initialized in an invalid state + when using the default constructor. + + @author Grant Gorfine + */ + + class SiCellId { + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + /// Constructor. Set in invalid state. + SiCellId(); + /// Construct with strip number. + SiCellId(int strip); + /// Construct with phi, eta index. + SiCellId(int phiIndex, int etaIndex); + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + // Get the indices + // NB. phiIndex() and strip() are equivalent. + /// Get eta index. + int etaIndex() const; + /// Get phi index. Equivalent to strip(). + int phiIndex() const; + /// Get strip number. Equivalent to phiIndex(). + int strip() const; + + /// Test if its in a valid state + bool isValid() const; + + /// Test equality. + bool operator==(const SiCellId & other) const; + /// Test inequality. + bool operator!=(const SiCellId & other) const; + + /// Operator for sorting + bool operator<(const SiCellId & other) const; + + unsigned int word() const { return m_word; } + +private: + unsigned int m_word; + + // Masks and shift values. + // bits 0 - 15 : phi_index + // bits 16 - 30 : eta_index + // bit 31 : valid flag + enum MaskAndShiftConstants { + PHI_MASK = 0x0000ffff, + PHI_NEG = 0x00008000, // (PHI_MASK >> 1 + 1) + ETA_MASK = 0x00007fff, + ETA_SHIFT = 16, + ETA_NEG = 0x40000000, // ((ETA_MASK >> 1 + 1) << ETA_SHIFT) + VALID = 0x80000000 + }; + +}; + +} // namespace InDetDD + + +// Global +std::ostream & operator << (std::ostream & os, const InDetDD::SiCellId & cellId); + + + +namespace InDetDD { + +/////////////////////////////////////////////////////////////////// +// Inline methods: +/////////////////////////////////////////////////////////////////// +inline SiCellId::SiCellId() +{ + // set in invalid state + // This sets the invalid bit plus set phi and eta index to there most negative value + m_word = VALID | ETA_NEG | PHI_NEG ; +} + +inline SiCellId::SiCellId(int phiIndex, int etaIndex) +{ + // The negative check is not really necessary if negative numbers are represented as twos complement but + // I don't think that assumption is guaranteed to be portable. + if (phiIndex < 0) phiIndex = PHI_MASK + phiIndex + 1; // For negative number store as two's complement + if (etaIndex < 0) etaIndex = ETA_MASK + etaIndex + 1; + m_word = (phiIndex & PHI_MASK) | ((etaIndex & ETA_MASK) << ETA_SHIFT); +} + +inline SiCellId::SiCellId(int strip) +{ + if (strip < 0) strip = PHI_MASK + strip + 1; + m_word = strip & PHI_MASK; +} + +inline int SiCellId::etaIndex() const +{ + if (m_word & ETA_NEG) { // Negative index + return ((m_word >> ETA_SHIFT) & ETA_MASK) - ETA_MASK - 1; + } + return (m_word >> ETA_SHIFT) & ETA_MASK; +} + +inline int SiCellId::phiIndex() const +{ + if (m_word & PHI_NEG) { // Negative index + return (m_word & PHI_MASK) - PHI_MASK - 1; + } + return (m_word & PHI_MASK); + +} + +inline int SiCellId::strip() const +{ + return phiIndex(); +} + +inline bool SiCellId::isValid() const +{ + return !(m_word & VALID); +} + +inline bool SiCellId::operator==(const SiCellId & other) const +{ + return (m_word == other.m_word); +} + +inline bool SiCellId::operator!=(const SiCellId & other) const +{ + return (m_word != other.m_word); +} + +inline bool SiCellId::operator<(const SiCellId & other) const +{ + return (m_word < other.m_word); +} + + +} // namespace InDetDD + + +#endif // INDETREADOUTGEOMETRY_SICELLID_H diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiCommonItems.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiCommonItems.h new file mode 100755 index 0000000000000000000000000000000000000000..4999443b4792eb5c6cc27ef1a972c043bd7e426e --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiCommonItems.h @@ -0,0 +1,84 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SiCommonItems.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef INDETREADOUTGEOMETRY_SICOMMONITEMS_H +#define INDETREADOUTGEOMETRY_SICOMMONITEMS_H + +class AtlasDetectorID; + +// Message Stream Member +#include "AthenaKernel/MsgStreamMember.h" +#include "GaudiKernel/ServiceHandle.h" +#include "CLHEP/Geometry/Transform3D.h" +#include "GeoModelKernel/RCBase.h" +#include "InDetCondServices/ISiLorentzAngleSvc.h" + +namespace InDetDD { + + /** @class SiCommonItems + + Helper class to concentrate common items, such as the pointer to the IdHelper, + the lorentzAngle service or the information about the solenoidal frame. + + To be used for Pixel and SCT. + + @author: Grant Gorfine + mondified & maintained: Nick Styles, Andreas Salzburger + */ + + class SiCommonItems: public RCBase + { + + public: + + SiCommonItems(const AtlasDetectorID* const idHelper); + + const AtlasDetectorID* getIdHelper() const; + const HepGeom::Transform3D & solenoidFrame() const; + void setSolenoidFrame(const HepGeom::Transform3D & transform) const; + void setLorentzAngleSvc(const ServiceHandle<ISiLorentzAngleSvc> & lorentzAngleSvc); + ISiLorentzAngleSvc * lorentzAngleSvc() const; + + //Declaring the Message method for further use + MsgStream& msg (MSG::Level lvl) const { return m_msg.get() << lvl; } + + //Declaring the Method providing Verbosity Level + bool msgLvl (MSG::Level lvl) const { return m_msg.get().level() <= lvl; } + + private: + + //Declaring private message stream member. + mutable Athena::MsgStreamMember m_msg; + + const AtlasDetectorID* m_idHelper; + mutable HepGeom::Transform3D m_solenoidFrame; + ServiceHandle<ISiLorentzAngleSvc> m_lorentzAngleSvcHandle; + mutable ISiLorentzAngleSvc * m_lorentzAngleSvc; + mutable bool m_lorentzAngleSvcInit; + + }; + + + inline const AtlasDetectorID* SiCommonItems::getIdHelper() const + { + return m_idHelper; + } + + + inline const HepGeom::Transform3D & SiCommonItems::solenoidFrame() const + { + return m_solenoidFrame; + } + + + +} // End namespace InDetDD + +#endif // INDETREADOUTGEOMETRY_SICOMMONITEMSS_H diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiDetectorDesign.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiDetectorDesign.h new file mode 100755 index 0000000000000000000000000000000000000000..9b9e698b4ce099f29b663b2b479671a3bda4d824 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiDetectorDesign.h @@ -0,0 +1,308 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SiDetectorDesign.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef INDETREADOUTGEOMETRY_SIDETECTORDESIGN_H +#define INDETREADOUTGEOMETRY_SIDETECTORDESIGN_H + +// Input/output classes +#include "InDetReadoutGeometry/SiDiodesParameters.h" +#include "InDetReadoutGeometry/InDetDD_Defs.h" +#include "CLHEP/Geometry/Point3D.h" +#include "CLHEP/Geometry/Vector3D.h" +#include "AtlasDetDescr/AtlasDetectorID.h" +#include "GeoModelKernel/RCBase.h" +#include "InDetDD_Defs.h" + +#include <list> +#include <vector> + + +class Identifier; + +namespace Trk{ + class SurfaceBounds; +} + +namespace InDetDD { + + class SiReadoutCellId; + class SiCellId; + class SiDiode; + class SiReadoutCell; + class SiLocalPosition; + class SiIntersect; + + enum DetectorShape {Box=0,Trapezoid,Other}; + + /** @class SiDetectorDesign + + Base class for the detector design classes for Pixel and SCT. + These hold the local description of the detector elements which are + shared by a number of detector elements. + + @author A. Calvet, Grant Gorfine + */ + + class SiDetectorDesign: public RCBase { + + public: + enum Axis {xAxis=0,yAxis,zAxis}; + + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + /** Constructor + @param thickness: Thickness of sensor + @param phiSymmetric, etaSymmetric, depthSymmetric: Flag to indicate if + element is symmetric about these axes. ie for rectangular sensor they + are all true, for trapezoidal sensor etaSymmetric + is false. They can also be used to force element not to swap directions. + @param carrierType: Carrier type that drifts to readout + (ie electrons for pixels and holes for SCT) + @param readoutSide: Readout side, +ve = positive Depth Side, -ve = negative Depth Side */ + SiDetectorDesign(double thickness, + bool phiSymmetric, + bool etaSymmetric, + bool depthSymmetric, + InDetDD::CarrierType carrierType, + int readoutSide); + + + /** Destructor: */ + virtual ~SiDetectorDesign(); + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /** Test if point is in the active part of the detector with specified tolerances */ + SiIntersect inDetector(const SiLocalPosition & localPosition, double phiTol, double etaTol) const; + + /** Test if near bond gap within tolerances, only relevant for SCT. */ + virtual bool nearBondGap(const SiLocalPosition & localPosition, double etaTol) const = 0; + + /** local axis corresponding to eta direction: */ + Axis etaAxis() const; + + /** local axis corresponding to phi direction: */ + Axis phiAxis() const; + + /** local axis corresponding to depth direction: */ + Axis depthAxis() const; + + bool phiSymmetric() const; + bool etaSymmetric() const; + bool depthSymmetric() const; + + /** ReadoutSide. +1 = postive depth side, -1 = negative depth side. */ + int readoutSide() const; + + /** Override default symmetries to prevent swapping of axes. + NB. Flags can be changed from true to false but not false to true. */ + void setSymmetry(bool phiSymmetric, bool etaSymmetric, bool depthSymmetric); + + + /////////////////////////////////////////////////////////////////// + // Pure virtual methods: + /////////////////////////////////////////////////////////////////// + + /** Returns distance to nearest detector active edge + +ve = inside + -ve = outside */ + virtual void distanceToDetectorEdge(const SiLocalPosition & localPosition, + double & etaDist, double & phiDist) const = 0; + + + + /** Helper method for stereo angle computation, DEPRECATED */ + virtual HepGeom::Vector3D<double> phiMeasureSegment(const SiLocalPosition &position) const =0; + + /** Special method for SCT to retrieve the two ends of a "strip" */ + virtual std::pair<SiLocalPosition,SiLocalPosition> endsOfStrip(const SiLocalPosition &position) const =0; + + /** Method to calculate length of a module */ + virtual double length() const =0; + + /** Method to calculate average width of a module */ + virtual double width() const = 0; + + /** Method to calculate minimum width of a module */ + virtual double minWidth() const = 0; + + /** Method to calculate maximum width of a module */ + virtual double maxWidth() const = 0; + + /** Method which returns thickness of the silicon wafer */ + double thickness() const; + + /** Pitch in phi direction */ + virtual double phiPitch() const = 0; + + /** Pitch in phi direction */ + virtual double phiPitch(const SiLocalPosition & localPosition) const = 0; + + //** Pitch in eta direction */ + virtual double etaPitch() const = 0; + + /** Return carrier type (ie electrons or holes) */ + InDetDD::CarrierType carrierType() const; + + /** Return true if hit local direction is the same as readout direction. */ + virtual bool swapHitPhiReadoutDirection() const = 0; + virtual bool swapHitEtaReadoutDirection() const = 0; + + /** Shape of element */ + virtual DetectorShape shape() const; + + /** Element boundary */ + virtual const Trk::SurfaceBounds & bounds() const = 0; + + + /////////////////////////////////////////////////////////// + // + // The following will replace existing methods but are not all implemented yet + // + + /** readout or diode id -> position, size */ + virtual SiDiodesParameters parameters(const SiCellId & cellId) const = 0; + + /** readout or diode id -> position. */ + virtual SiLocalPosition localPositionOfCell(const SiCellId & cellId) const = 0; + + /** number of connected cells. Generally 1 except for ganged pixels which will be 2. */ + virtual int numberOfConnectedCells(const SiReadoutCellId & readoutId) const = 0; + + /** readout id -> id of connected diodes. + parameter number = 0 will refer to the primary diode and in general the + cell number will be the same. + NB. SiCellId cellId = connectedCell(readoutId, 0) will in general be equivalent to + SiCellId cellId = readoutId */ + virtual SiCellId connectedCell(const SiReadoutCellId & readoutId, int number) const = 0; + + /** If cell is ganged return the id of the other cell which shares the readout + for this cell, otherwise return an invalid id. */ + virtual SiCellId gangedCell(const SiCellId & cellId) const = 0; + + /** diode id -> readout id + NB assignment of a SiReadoutCellId to a SiCellId is allowed so you are can + pass SiReadoutCellId variables to functions expecting a SiCellId. */ + virtual SiReadoutCellId readoutIdOfCell(const SiCellId & cellId) const = 0; + + /** position -> id */ + virtual SiReadoutCellId readoutIdOfPosition(const SiLocalPosition & localPos) const = 0; + + /** position -> id */ + virtual SiCellId cellIdOfPosition(const SiLocalPosition & localPos) const = 0; + + /** Get the neighbouring diodes of a given diode: + Cell for which the neighbours must be found + List of cells which are neighbours of the given one */ + virtual void neighboursOfCell(const SiCellId & cellId, + std::vector<SiCellId> &neighbours) const = 0; + + /** Check if cell is in range. Returns the original cellId if it is in range, otherwise it returns an invalid id. */ + virtual SiCellId cellIdInRange(const SiCellId & cellId) const = 0; + + + /////////////////////////////////////////////////////////////////// + // Private methods: + /////////////////////////////////////////////////////////////////// + private: + + SiDetectorDesign(); + + /////////////////////////////////////////////////////////////////// + // Private data: + /////////////////////////////////////////////////////////////////// + private: + Axis m_etaAxis; //!< local axis corresponding to eta direction + Axis m_phiAxis; //!< local axis corresponding to phi direction + Axis m_depthAxis; //!< local axis corresponding to depth direction + double m_thickness; //!< thickness of silicon sensor + InDetDD::CarrierType m_carrierType; //!< carrier type that drifts towards readout + //!< (ie holes fro SCT and electrons for pixel) + bool m_phiSymmetric; + bool m_etaSymmetric; + bool m_depthSymmetric; + + bool m_readoutSidePosDepth; //!< Control which side readout is on. + //!< true = positive Depth Side, false = negative Depth Side + + // Disallow Copy and assignment; + SiDetectorDesign(const SiDetectorDesign &design); + SiDetectorDesign &operator=(const SiDetectorDesign &design); + + }; + + /////////////////////////////////////////////////////////////////// + // Inline methods: + /////////////////////////////////////////////////////////////////// + inline SiDetectorDesign::Axis SiDetectorDesign::etaAxis() const + { + return m_etaAxis; + } + + inline SiDetectorDesign::Axis SiDetectorDesign::phiAxis() const + { + return m_phiAxis; + } + + inline SiDetectorDesign::Axis SiDetectorDesign::depthAxis() const + { + return m_depthAxis; + } + + inline double SiDetectorDesign::thickness() const + { + return m_thickness; + } + + inline InDetDD::CarrierType SiDetectorDesign::carrierType() const + { + return m_carrierType; + } + + inline bool SiDetectorDesign::phiSymmetric() const + { + return m_phiSymmetric; + } + + inline bool SiDetectorDesign::etaSymmetric() const + { + return m_etaSymmetric; + } + + inline bool SiDetectorDesign::depthSymmetric() const + { + return m_depthSymmetric; + } + + inline int SiDetectorDesign::readoutSide() const + { + return (m_readoutSidePosDepth) ? +1 : -1; + } + + + +} // namespace InDetDD + +#endif // INDETREADOUTGEOMETRY_SIDETECTORDESIGN_H + + + + + + + + + diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiDetectorElement.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiDetectorElement.h new file mode 100755 index 0000000000000000000000000000000000000000..887a5afb9ffcca192d5da73225b96a1bd3daa633 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiDetectorElement.h @@ -0,0 +1,980 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SiDetectorElement.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef INDETREADOUTGEOMETRY_SIDETECTORELEMENT_H +#define INDETREADOUTGEOMETRY_SIDETECTORELEMENT_H + +// Base class. +#include "TrkDetElementBase/TrkDetElementBase.h" + +// Data member classes +#include "Identifier/Identifier.h" +#include "Identifier/IdentifierHash.h" +#include "InDetReadoutGeometry/SiDetectorDesign.h" +#include "InDetReadoutGeometry/SiLocalPosition.h" +#include "TrkEventPrimitives/ParamDefs.h" +#include "InDetReadoutGeometry/SiIntersect.h" +#include "InDetReadoutGeometry/SiCommonItems.h" +#include "InDetReadoutGeometry/SiCellId.h" +#include "InDetReadoutGeometry/InDetDD_Defs.h" +#include "CLHEP/Geometry/Point3D.h" +#include "GeoPrimitives/CLHEPtoEigenConverter.h" + +class AtlasDetectorID; +class GeoVFullPhysVol; + +namespace Trk{ + class Surface; + class SurfaceBounds; +} + +namespace InDetDD { + + class SiReadoutCellId; + + /** + + @class SiDetectorElement + + Class to hold geometrical description of a silicon detector element. + A detector element is a module in the pixels and one side of a module in the SCT. + This class is shared between the Pixel and SCT detector since there is a lot of commonality. + + @par Coordinate Frames. + + The following coordinate frames are used in these elements. + + - Global frame:\n + Currently global frame in G4/GeoModel. Probably eventually + will be global frame most suitable for reconstruction + (eg solenoid axis). + + - Local hit frame:\n + Local frame for hits. It is the same as local frame in G4 and GeoModel. + I also refer to this as the local simulation frame. + By convention elements are orientated such that: + - hitDepth = local x + - hitPhi = local y + - hitEta = local z + . + Directions of these correspond to the physical wafer. Consequently hitDepth and hitPhi axes go in + different directions depending on the orientation of the module. + The readout side is determined from design()->readoutSide(). + + - Local reconstruction frame:\n + - distPhi = local x + - distEta = local y + - distDepth = local z + . + The directions of the axes are defined as + - distPhi in direction of increasing phi + - distEta in direction of increasing z in barrel and increasing r in endcap. + - distDepth (normal) choosen to give right-handed coordinate. + => away from intersection point for barrel, decreasing z for endcap + + @par Overview of Methods + + Methods are grouped into the the following categories + + - Identification + - Navigation + - Transformation/Orientation + - Module Frame + - Element Extent + - Design methods + - Intersection Tests + - Lorentz Correction + - Readout cell id + - Miscellaneous + - Cache handling. + + + @author Grant Gorfine + - modified & maintained: Nick Styles, Andreas Salzburger + + */ + + class SiDetectorElement : public Trk::TrkDetElementBase { + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + enum Axis {xAxis=0, yAxis, zAxis}; + enum SiliconAxis {hitDepth = xAxis, hitPhi = yAxis, hitEta = zAxis}; + + /// Constructor: + SiDetectorElement(const Identifier &id, + const SiDetectorDesign *design, + const GeoVFullPhysVol *geophysvol, + SiCommonItems * commonItems); + + /// Destructor: + virtual ~SiDetectorElement(); + + + /////////////////////////////////////////////////////////////////// + // + /// @name Identification + /// Methods to identify the element and identifier manipulation. + // + /////////////////////////////////////////////////////////////////// + + //@{ + + /// identifier of this detector element: + virtual Identifier identify() const; + + /// identifier hash + virtual IdentifierHash identifyHash() const; + + /// Returns the id helper + const AtlasDetectorID* getIdHelper() const; + + bool isPixel() const; + bool isSCT() const; + bool isBarrel() const; + bool isEndcap() const; + bool isBlayer() const; + bool isInnermostPixelLayer() const; + bool isNextToInnermostPixelLayer() const; + bool isDBM() const; + + // Identfier <-> SiCellId (ie strip number or pixel eta_index,phi_index) + + /// Identfier from SiCellId (ie strip number or pixel eta_index,phi_index) + Identifier identifierFromCellId(const SiCellId & cellId) const; + + /// SiCellId from Identifier + SiCellId cellIdFromIdentifier(const Identifier & identifier) const; + + //@} + + + /////////////////////////////////////////////////////////////////// + // + /// @name Navigation + /// Methods to access neighbours. + // + /////////////////////////////////////////////////////////////////// + + //@{ + const SiDetectorElement * nextInEta() const; + const SiDetectorElement * prevInEta() const; + const SiDetectorElement * nextInPhi() const; + const SiDetectorElement * prevInPhi() const; + const SiDetectorElement * otherSide() const; // Useful for SCT only + //@} + + /////////////////////////////////////////////////////////////////// + // + /// @name Transformation/Orientation + // + /////////////////////////////////////////////////////////////////// + + //@{ + // Position + /// Local (simulation/hit frame) to global transform + virtual const HepGeom::Transform3D & transformHit() const; + /// Local (reconstruction frame) to global transform + const Amg::Transform3D & transform() const; + /// Default Local (reconstruction frame) to global transform + /// ie with no misalignment. + const HepGeom::Transform3D defTransformCLHEP() const; + const Amg::Transform3D defTransform() const; + /// Center in global coordinates + const Amg::Vector3D & center() const; + + const HepGeom::Transform3D & transformCLHEP() const; + + /// Simulation/Hit local frame to reconstruction local frame. 2D. + // TODO: Will change order of parameters at some point. + Amg::Vector2D hitLocalToLocal(double xEta, double xPhi) const; + /// Same as previuos method but 3D. + HepGeom::Point3D<double> hitLocalToLocal3D(const HepGeom::Point3D<double> & hitPosition) const; + + /// Transform to go from local reconstruction frame to local hit frame. + const HepGeom::Transform3D recoToHitTransform() const; + + /// Directions of hit depth,phi,eta axes relative to reconstruction local position + /// axes (LocalPosition). Returns +/-1. + double hitDepthDirection() const; + /// See previous method. + double hitPhiDirection() const; + /// See previous method. + double hitEtaDirection() const; + + // To determine if readout direction between online and offline needs swapping, see methods + // swapPhiReadoutDirection() and swapEtaReadoutDirection() below in "Readout Cell id" section + + + // Orientation. + // Directions. + // phiAxis - in same direction as increasing phi and identifier phi_index/strip. + // NB. This requires some flipping of axes with repsect to the hits. + // etaAxis - in direction of increasing z in the barrel and increasing r in the endcap. + // normal - choosen to give right-handed coordinate frame (x=normal,y=phiAxis,z=etaAxis) + // NB. This requires some flipping of axes with repsect to the hits. + + /// Get reconstruction local phi axes in global frame. + /// In same direction as increasing phi and identifier phi_index/strip. + const Amg::Vector3D & phiAxis() const; + const HepGeom::Vector3D<double> & phiAxisCLHEP() const; + /// Get reconstruction local eta axes in global frame. + /// In direction of increasing z in the barrel and increasing r in the endcap. + const Amg::Vector3D & etaAxis() const; + const HepGeom::Vector3D<double> & etaAxisCLHEP() const; + /// Get reconstruction local normal axes in global frame. Choosen to give right-handed coordinate frame. + const Amg::Vector3D & normal() const; + + /// transform a hit local position into a global position: + HepGeom::Point3D<double> globalPositionHit(const HepGeom::Point3D<double> &simulationLocalPos) const; + Amg::Vector3D globalPositionHit(const Amg::Vector3D &simulationLocalPos) const; + + /// transform a reconstruction local position into a global position: + HepGeom::Point3D<double> globalPosition(const HepGeom::Point3D<double> &localPos) const; + Amg::Vector3D globalPosition(const Amg::Vector3D &localPos) const; + + /// as in previous method but for 2D local position + HepGeom::Point3D<double> globalPositionCLHEP(const Amg::Vector2D &localPos) const; + + Amg::Vector3D globalPosition(const Amg::Vector2D &localPos) const; + + /// transform a global position into a 2D local position (reconstruction frame) + Amg::Vector2D localPosition(const HepGeom::Point3D<double> & globalPosition) const; + + Amg::Vector2D localPosition(const Amg::Vector3D& globalPosition) const; + + /// Compute sin(tilt angle) at a given position: + /// at center + double sinTilt() const; // At center + /// at given local position + double sinTilt(const Amg::Vector2D &localPos) const; + /// at given global position + double sinTilt(const HepGeom::Point3D<double> &globalPosition) const; + + /// Compute sin(stereo angle) at a given position: at center + double sinStereo() const; // At center + /// at given local position + double sinStereo(const Amg::Vector2D &localPos) const; + /// at given global position + double sinStereo(const HepGeom::Point3D<double> &globalPosition) const; + + /// Check if it is the stereo side (useful for SCT) + bool isStereo() const; + + /// Angle of strip in local frame with respect to the etaAxis. + /// Zero for all elements except trapezoidal detectors (ie SCT forward modules). + double sinStereoLocal(const Amg::Vector2D &localPos) const; + /// See previous method + double sinStereoLocal(const HepGeom::Point3D<double> &globalPos) const; + + /// Element Surface + virtual const Trk::Surface & surface() const; + + //@} + + + /** + + @name Module Frame + Methods to help work with the module frame. + This is mainly of of use in the SCT where the module frame can + in general be different from the element frame. It is actully + defined as the frame of one of the sides (currently the axial + side), but using these methods one does not need to make any + assumptions about what the actual frame is. In the following + methods the local element frame is the local reconstruction + frame of this element. + */ + + //@{ + + /// Module to global frame transform. + /// Includes misalignment. The module frame is defined to be the + /// local reconstruction frame of the axial layer in the SCT. For + /// the pixel it is the same as the element. + //const HepGeom::Transform3D & moduleTransform() const; + const Amg::Transform3D & moduleTransform() const; + + /// Default module to global frame transform, ie with no misalignment. + /// The module frame is defined to be the + /// local reconstruction frame of the axial layer in the SCT. For + /// the pixel it is the same as the element. + Amg::Transform3D defModuleTransform() const; + + + /// Take a transform of the local element frame and return its equivalent in the module frame. + //HepGeom::Transform3D localToModuleFrame(const HepGeom::Transform3D & localTransform) const; + Amg::Transform3D localToModuleFrame(const Amg::Transform3D & localTransform) const; + + /// Transformation from local element to module frame. This can be + /// used to take a local position in the element frame and transform + /// it to a position in the module frame. If one is already in the + /// module frame it will return the Identity transform. + //HepGeom::Transform3D localToModuleTransform() const; + Amg::Transform3D localToModuleTransform() const; + + /// Check if the element and module frame are the same. + bool isModuleFrame() const; + + + //@} + + /////////////////////////////////////////////////////////////////// + // + /// @name Element Extent + /// Methods to get extent of element in r,phi and z. + /////////////////////////////////////////////////////////////////// + + //@{ + // Extent in r,z and phi + double rMin() const; + double rMax() const; + double zMin() const; + double zMax() const; + double phiMin() const; + double phiMax() const; + + /// Method for building up region of interest table. + /// Get eta/phi extent for the element. Returns min/max eta and phi + /// and r (for barrel) or z (for endcap) Takes as input the vertex + /// spread in z (-deltaZ to +deltaZ) + void getEtaPhiRegion(double deltaZ, + double &etaMin, double &etaMax, + double &phiMin, double &phiMax, + double &rz) const; + //@} + + /////////////////////////////////////////////////////////////////// + // + /// @name Design methods + // + /////////////////////////////////////////////////////////////////// + //@{ + + /// access to the local description: + const SiDetectorDesign &design() const; + + // Methods from design + double width() const; // Width in phi direction. For the SCT endcap it returns the average width. + double minWidth() const; // Min, max width. Needed for the SCT endcap. + double maxWidth() const; + double length() const; // Length in eta direction (z - barrel, r - endcap) + double thickness() const; + + InDetDD::CarrierType carrierType() const; // carrier type for readout. ie holes for SCT + // and electrons for pixels. + virtual const Trk::SurfaceBounds & bounds() const; + + // Pitch + // + // NOTE: phiPitch is ambiguous for the Forward SCT where it varies along the strip. + // etaPitch is ambiguous for the pixel which has long pixels between FE chips. + // + // For these cases: + // + // phiPitch: For SCT Forward returns pitch at center. + // etaPitch: For pixel returns average pitch. (Active_length/number_of_cells) + // + // All return pitch in distance units. + // + double etaPitch() const; + double phiPitch() const; + double phiPitch(const Amg::Vector2D &) const; // Useful for SCT Forward. + //@} + + /////////////////////////////////////////////////////////////////// + // + /// @name Intersection Tests + // + /////////////////////////////////////////////////////////////////// + + //@{ + // Test if near bond gap within tolerances + bool nearBondGap(Amg::Vector2D localPosition, double etaTol) const; + bool nearBondGap(HepGeom::Point3D<double> globalPosition, double etaTol) const; + + // Test that it is in the active region + // Intersect has 3 states + // bool SiIntersect::in() const // definitely in + // bool SiIntersect::out() const // definitely out + // bool SiIntersect::nearBoundary() const // near a boundary within the tolerances + // bool SiIntersect::mayIntersect() const // in() OR nearBoundary() + SiIntersect inDetector(const Amg::Vector2D & localPosition, double phiTol, double etaTol) const; + SiIntersect inDetector(const HepGeom::Point3D<double> & globalPosition, double phiTol, double etaTol) const; + //@} + + /////////////////////////////////////////////////////////////////// + // + /// @name Lorentz Correction + // + /////////////////////////////////////////////////////////////////// + //@{ + + /// tan(Lorentz angle). Component in phi direction (hit frame) + double getTanLorentzAnglePhi() const; + + /// Same as getTanLorentzAnglePhi() + double getTanLorentzAngle() const; + + /// tan(Lorentz angle). Component in eta direction (hit frame) + double getTanLorentzAngleEta() const; + + /// Lorentz shift in distPhi (reconstruction local frame) + double getLorentzCorrection() const; + + /// Correct a local position (reconstruction frame) for the Lorentz angle: + /// Users generally shouldn't need to call this as localPositionOfCell() returns the Lorentz corrected position. + Amg::Vector2D correctLocalPosition(const Amg::Vector2D &position) const; + //@} + + /////////////////////////////////////////////////////////////////// + // + /// @name Readout cell id + /// Cell id's are the strip number in SCT and phi_index,eta_index in the pixel + /// as defined in the offline identifier. Their direction runs in the distPhi, distEta + /// direction in the Reconstruction local frame. + /// + /// For methods taking a SiCellId (basically phi,eta index for pixel or strip for SCT) you + /// can do the following fro example: + /// - For pixel\n + /// localPositionOfCell(SiCellId(phi_index,eta_index));\n + /// - For SCT\n + /// localPositionOfCell(SiCellId(strip));\n + // + /////////////////////////////////////////////////////////////////// + //@{ + + /// Determine if readout direction between online and offline needs swapping. + /// Returns true if online and offline numbers run in opposite directions. + /// For strip/phi_index + bool swapPhiReadoutDirection() const; + /// For eta_index (only relevant for pixel) + bool swapEtaReadoutDirection() const; + + /// Full identifier of the cell for a given position: + /// assumes a raw local position (no Lorentz shift) + Identifier identifierOfPosition(const Amg::Vector2D &localPos) const; + /// As in previous method but returns SiCellId + SiCellId cellIdOfPosition(const Amg::Vector2D &localPos) const; + + + /// Returns position (center) of cell. These are corrected for the Lorentz shift + Amg::Vector2D localPositionOfCell(const SiCellId & cellId) const; + /// As above + Amg::Vector2D localPositionOfCell(const Identifier & id) const; + + /// Returns position (center) of cell. These are the raw positions *NOT* corrected for the Lorentz shift + Amg::Vector2D rawLocalPositionOfCell(const SiCellId & cellId) const; + /// As above + Amg::Vector2D rawLocalPositionOfCell(const Identifier & id) const; + + /// Test if readout cell has more than one diode associated with it. + /// Number of cells sharing the same readout as this cell. + /// ie generally 1 except for ganged pixels which will be 2. + int numberOfConnectedCells(const SiCellId cellId) const; + /// Get the cell ids sharing the readout for this cell. + /// number = 0 will return the primary readout cell id. + SiCellId connectedCell(const SiCellId cellId, int number) const; + + /// If cell is ganged return the id of the other cell which shares the readout + /// for this cell, otherwise return an invalid id. + /// This is a more convenient (and slightly faster) alternative than + /// using the above two methods. + /// Only relevant for pixel. For SCT always returns an invalid ID. + SiCellId gangedCell(const SiCellId & cellId) const; + + //@} + + /////////////////////////////////////////////////////////////////// + // + /// @name Miscellaneous + // + /////////////////////////////////////////////////////////////////// + //@{ + /// Special method for SCT to retrieve the two ends of a "strip" + /// Returned coordinates are in global frame. + //std::pair<HepGeom::Point3D<double>,HepGeom::Point3D<double> > endsOfStrip(const Amg::Vector2D &position) const; + std::pair<Amg::Vector3D,Amg::Vector3D > endsOfStrip(const Amg::Vector2D &position) const; + //@} + + /////////////////////////////////////////////////////////////////// + // + /// @name Cache handling. + // + /////////////////////////////////////////////////////////////////// + //@{. + // - Methods to handle invalidating and updating caches. The cached values include values that are affected by alignment + // Surface are only created on demand. The method updateAllCaches also creates the surfaces as well as calling updateCache. + // Conditions cache contains Lorentz angle related quantities. + + /// Signal that cached values are no longer valid. + /// Invalidate general cache + void invalidate() const; + + /// invalidate conditions cache + void invalidateConditions() const; + + /// Recalculate all cached values. + void updateCache() const; + + /// Recalculate subset of cached values. + void updateConditionsCache() const; + + /// Update all caches including surfaces. + void updateAllCaches() const; + + + + + //@} + + /////////////////////////////////////////////////////////////////// + // + /// @name Methods to satisfy TrkDetElementBase interface + // + /////////////////////////////////////////////////////////////////// + //{@ + virtual const Amg::Transform3D & transform(const Identifier&) const {return transform();} + virtual const Trk::Surface& surface (const Identifier&) const {return surface();} + virtual const Amg::Vector3D& center (const Identifier&) const {return center();} + virtual const Amg::Vector3D& normal (const Identifier&) const {return normal();} + virtual const Trk::SurfaceBounds & bounds(const Identifier&) const {return bounds();} + //@} + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + public: + + + /////////////////////////////////////////////////////////////////// + /// @name Non-const methods: + /// These are not needed by most clients. + /////////////////////////////////////////////////////////////////// + //@{ + // Set neighbours. + + void setNextInEta(const SiDetectorElement *); + void setPrevInEta(const SiDetectorElement *); + void setNextInPhi(const SiDetectorElement *); + void setPrevInPhi(const SiDetectorElement *); + void setOtherSide(const SiDetectorElement *); // For SCT only + + //@} + + /////////////////////////////////////////////////////////////////// + // Private methods: + /////////////////////////////////////////////////////////////////// + + private: + + // Common code for constructors. + void commonConstructor(); + + + // Calculate extent in r,z and phi. The values are cached and there + // are rMin(), rMax etc methods. + void getExtent(double &rMin, double &rMax, + double &zMin, double &zMax, + double &phiMin, double &phiMax) const; + + // Return the four corners of an element in local coordinates. + // Pass it an array of length 4. + // This function is used by getEtaPhiRegion() + void getCorners(HepGeom::Point3D<double> *corners) const; + + // Get eta and phi coresponding to a point in local coordinates. + // Requires as input the vertex spread. Returns etaMin, etaMax, and phi. + // This function is used by getEtaPhiRegion() + void getEtaPhiPoint(const HepGeom::Point3D<double> & point, double deltaZ, + double &etaMin, double &etaMax, double &phi) const; + + + //Declaring the Message method for further use + MsgStream& msg (MSG::Level lvl) const { return m_commonItems->msg(lvl);} + + //Declaring the Method providing Verbosity Level + bool msgLvl (MSG::Level lvl) const { return m_commonItems->msgLvl(lvl);} + + + /////////////////////////////////////////////////////////////////// + // Private methods: + /////////////////////////////////////////////////////////////////// + private: + + // Don't allow copying. + SiDetectorElement(); + SiDetectorElement(const SiDetectorElement&); + SiDetectorElement &operator=(const SiDetectorElement&); + + + + /////////////////////////////////////////////////////////////////// + // Protected data: + /////////////////////////////////////////////////////////////////// + protected: + + Identifier m_id; // identifier of this detector element + IdentifierHash m_idHash; // hash id + const SiDetectorDesign *m_design; // local description of this detector element + //const AtlasDetectorID* m_idHelper; // id helper + SiCommonItems * m_commonItems; + + const SiDetectorElement * m_nextInEta; + const SiDetectorElement * m_prevInEta; + const SiDetectorElement * m_nextInPhi; + const SiDetectorElement * m_prevInPhi; + const SiDetectorElement * m_otherSide; + + bool m_isPixel; + bool m_isBarrel; + bool m_isDBM; + + // + // Cached values. + // + + // Directions of axes. These are true if the hit/simulation and reconstruction local frames are + // in the same direction and false if they are opposite. + mutable bool m_depthDirection; // Direction of depth axis. + // Also direction of readout implant (n+ for pixel, p+ for SCT). + mutable bool m_phiDirection; // + mutable bool m_etaDirection; // + + mutable bool m_cacheValid; // Alignment associated quatities. + mutable bool m_conditionsCacheValid; // Lorentz angle related values. + mutable bool m_firstTime; + mutable bool m_isStereo; + + mutable Amg::Transform3D m_transform; + mutable HepGeom::Transform3D m_transformCLHEP; + + + mutable Amg::Vector3D m_normal; + mutable HepGeom::Vector3D<double> m_normalCLHEP; + mutable Amg::Vector3D m_etaAxis; + mutable Amg::Vector3D m_phiAxis; + mutable HepGeom::Vector3D<double> m_etaAxisCLHEP; + mutable HepGeom::Vector3D<double> m_phiAxisCLHEP; + mutable Amg::Vector3D m_center; + mutable HepGeom::Vector3D<double> m_centerCLHEP; + + mutable double m_minZ; + mutable double m_maxZ; + mutable double m_minR; + mutable double m_maxR; + mutable double m_minPhi; + mutable double m_maxPhi; + + mutable double m_tanLorentzAnglePhi; + mutable double m_tanLorentzAngleEta; + mutable double m_lorentzCorrection; + + mutable Trk::Surface * m_surface; + + }; + + /////////////////////////////////////////////////////////////////// + // Inline methods: + /////////////////////////////////////////////////////////////////// + + inline bool SiDetectorElement::isEndcap() const + { + return (!isBarrel()&&!isDBM()); + } + + + inline HepGeom::Point3D<double> SiDetectorElement::globalPositionHit(const HepGeom::Point3D<double> &localPos) const + { + return transformHit()*localPos; + } + + inline Amg::Vector3D SiDetectorElement::globalPosition(const Amg::Vector2D &localPos) const + { + if (!m_cacheValid) updateCache(); + return m_center + localPos[Trk::distEta] * m_etaAxis + localPos[Trk::distPhi] * m_phiAxis; + + } + + inline Amg::Vector3D SiDetectorElement::globalPositionHit(const Amg::Vector3D &localPos) const + { + return Amg::CLHEPTransformToEigen(transformHit()) * localPos; + } + + inline HepGeom::Point3D<double> SiDetectorElement::globalPositionCLHEP(const Amg::Vector2D &localPos) const + { + if (!m_cacheValid) updateCache(); + return m_centerCLHEP + localPos[Trk::distEta] * m_etaAxisCLHEP + localPos[Trk::distPhi] * m_phiAxisCLHEP; + + } + //here + inline Amg::Vector3D SiDetectorElement::globalPosition(const Amg::Vector3D &localPos) const + { + return transform() * localPos; + } + + inline HepGeom::Point3D<double> SiDetectorElement::globalPosition(const HepGeom::Point3D<double> &localPos) const + { + return transformCLHEP() * localPos; + } + + inline Amg::Vector2D SiDetectorElement::localPosition(const HepGeom::Point3D<double> & globalPosition) const + { + if (!m_cacheValid) updateCache(); + HepGeom::Vector3D<double> relativePos = globalPosition - m_centerCLHEP; + return Amg::Vector2D(relativePos.dot(m_phiAxisCLHEP), relativePos.dot(m_etaAxisCLHEP)); + } + + inline Amg::Vector2D SiDetectorElement::localPosition(const Amg::Vector3D & globalPosition) const{ + if (!m_cacheValid) updateCache(); + Amg::Vector3D relativePos = globalPosition - m_center; + return Amg::Vector2D(relativePos.dot(m_phiAxis), relativePos.dot(m_etaAxis)); +} + + inline const SiDetectorDesign &SiDetectorElement::design() const + { + return *m_design; + } + + inline const AtlasDetectorID* SiDetectorElement::getIdHelper() const + { + return m_commonItems->getIdHelper(); + } + + inline Identifier SiDetectorElement::identify() const + { + return m_id; + } + + inline IdentifierHash SiDetectorElement::identifyHash() const + { + return m_idHash; + } + + + inline double SiDetectorElement::hitDepthDirection() const + { + if (!m_cacheValid) updateCache(); + return (m_depthDirection) ? 1. : -1.; + } + + inline double SiDetectorElement::hitPhiDirection() const + { + if (!m_cacheValid) updateCache(); + return (m_phiDirection) ? 1. : -1.; + } + + inline double SiDetectorElement::hitEtaDirection() const + { + if (!m_cacheValid) updateCache(); + return (m_etaDirection) ? 1. : -1.; + } + + inline InDetDD::CarrierType SiDetectorElement::carrierType() const + { + return m_design->carrierType(); + } + + inline SiCellId SiDetectorElement::gangedCell(const SiCellId & cellId) const + { + return m_design->gangedCell(cellId); + } + + inline void SiDetectorElement::invalidate() const + { + m_cacheValid = false; + // Conditions cache invalidation is done by SiLorentzAngleSvc. + } + + inline void SiDetectorElement::invalidateConditions() const + { + m_conditionsCacheValid = false; + } + + inline void SiDetectorElement::updateAllCaches() const + { + if (!m_cacheValid) updateCache(); + if (!m_conditionsCacheValid) updateConditionsCache(); + if (!m_surface) surface(); + } + + + inline double SiDetectorElement::rMin() const + { + if (!m_cacheValid) updateCache(); + return m_minR; + } + + inline double SiDetectorElement::rMax() const + { + if (!m_cacheValid) updateCache(); + return m_maxR; + } + + inline double SiDetectorElement::zMin() const + { + if (!m_cacheValid) updateCache(); + return m_minZ; + } + + inline double SiDetectorElement::zMax() const + { + if (!m_cacheValid) updateCache(); + return m_maxZ; + } + + inline double SiDetectorElement::phiMin() const + { + if (!m_cacheValid) updateCache(); + return m_minPhi; + } + + inline double SiDetectorElement::phiMax() const + { + if (!m_cacheValid) updateCache(); + return m_maxPhi; + } + + inline double SiDetectorElement::width() const + { + return m_design->width(); + } + + inline double SiDetectorElement::minWidth() const + { + return m_design->minWidth(); + } + + inline double SiDetectorElement::maxWidth() const + { + return m_design->maxWidth(); + } + + inline double SiDetectorElement::length() const + { + return m_design->length(); + } + + inline double SiDetectorElement::thickness() const + { + return m_design->thickness(); + } + + inline double SiDetectorElement::etaPitch() const + { + return m_design->etaPitch(); + } + + inline double SiDetectorElement::phiPitch() const + { + return m_design->phiPitch(); + } + + inline double SiDetectorElement::phiPitch(const Amg::Vector2D & localPosition) const + { + return m_design->phiPitch(localPosition); + } + + inline const SiDetectorElement * SiDetectorElement::nextInEta() const + { + return m_nextInEta; + } + + inline const SiDetectorElement * SiDetectorElement::prevInEta() const + { + return m_prevInEta; + } + + inline const SiDetectorElement * SiDetectorElement::nextInPhi() const + { + return m_nextInPhi; + } + + inline const SiDetectorElement * SiDetectorElement::prevInPhi() const + { + return m_prevInPhi; + } + + inline const SiDetectorElement * SiDetectorElement::otherSide() const + { + return m_otherSide; + } + + inline void SiDetectorElement::setNextInEta(const SiDetectorElement * element) + { + m_nextInEta = element; + } + + inline void SiDetectorElement::setPrevInEta(const SiDetectorElement * element) + { + m_prevInEta = element; + } + + inline void SiDetectorElement::setNextInPhi(const SiDetectorElement * element) + { + m_nextInPhi = element; + } + + inline void SiDetectorElement::setPrevInPhi(const SiDetectorElement * element) + { + m_prevInPhi = element; + } + + inline void SiDetectorElement::setOtherSide(const SiDetectorElement * element) // For SCT only + { + m_otherSide = element; + } + + inline bool SiDetectorElement::swapPhiReadoutDirection() const + { + // equivalent to (m_design->swapHitPhiReadoutDirection() xor !m_phiDirection) + return ((!m_design->swapHitPhiReadoutDirection() && !m_phiDirection) + || (m_design->swapHitPhiReadoutDirection() && m_phiDirection)); + } + + inline bool SiDetectorElement::swapEtaReadoutDirection() const + { + // equivalent to (m_design->swapHitEtaReadoutDirection() xor !m_etaDirection) + return ((!m_design->swapHitEtaReadoutDirection() && !m_etaDirection) + || (m_design->swapHitEtaReadoutDirection() && m_etaDirection)); + } + + inline double SiDetectorElement::getTanLorentzAnglePhi() const + { + if (!m_conditionsCacheValid) updateConditionsCache(); + return m_tanLorentzAnglePhi; + } + + // Same as getTanLorentzAnglePhi() + inline double SiDetectorElement::getTanLorentzAngle() const + { + if (!m_conditionsCacheValid) updateConditionsCache(); + return m_tanLorentzAnglePhi; + } + + inline double SiDetectorElement::getTanLorentzAngleEta() const + { + if (!m_conditionsCacheValid) updateConditionsCache(); + return m_tanLorentzAngleEta; + } + + inline double SiDetectorElement::getLorentzCorrection() const + { + if (!m_conditionsCacheValid) updateConditionsCache(); + return m_lorentzCorrection; + } + +} // namespace InDetDD + +#endif // INDETREADOUTGEOMETRY_SIDETECTORELEMENT_H + diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiDetectorElementCollection.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiDetectorElementCollection.h new file mode 100755 index 0000000000000000000000000000000000000000..a4fbe702d932e408e0a5c05c4b4a49fe9f1a9c0f --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiDetectorElementCollection.h @@ -0,0 +1,33 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SiDetectorElementCollection.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + + +#ifndef INDETREADOUTGEOMETRY_SIDETECTORELEMENTCOLLECTION_H +#define INDETREADOUTGEOMETRY_SIDETECTORELEMENTCOLLECTION_H + +#include <vector> + +namespace InDetDD { + + class SiDetectorElement; + + /** @class SiDetectorElementCollection + + Class to hold the SiDetectorElement objects to be put in the detector store + + @author Grant Gorfine + */ + + class SiDetectorElementCollection : public std::vector<SiDetectorElement *> +{}; + +} // namespace InDetDD + +#endif // INDETREADOUTGEOMETRY_SIDETECTORELEMENTCOLLECTION_H diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiDetectorManager.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiDetectorManager.h new file mode 100755 index 0000000000000000000000000000000000000000..5cb5a74228eceee024355fd5c4999d2b7f675791 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiDetectorManager.h @@ -0,0 +1,162 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SiDetectorManager.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef INDETREADOUTGEOMETRY_SIDETECTORMANAGER_H +#define INDETREADOUTGEOMETRY_SIDETECTORMANAGER_H + +#include "InDetReadoutGeometry/InDetDetectorManager.h" + +#include "InDetReadoutGeometry/SiDetectorElementCollection.h" +#include "InDetReadoutGeometry/InDetDD_Defs.h" +#include "InDetReadoutGeometry/SiNumerology.h" + +// Amg stuff +#include "GeoPrimitives/GeoPrimitives.h" + +// IOV SVC for alignment: +#include "AthenaKernel/IIOVSvc.h" + +#include "CLHEP/Geometry/Transform3D.h" + +#include <string> +#include <map> + +class StoreGateSvc; +class Identifier; +class IdentifierHash; +class AtlasDetectorID; +class GeoAlignableTransform; + +namespace InDetDD { + +class SiDetectorElement; +class SiDetectorDesign; +class ExtendedAlignableTransform; +class SiNumerology; + + /** @class SiDetectorManager + + Base class for Pixel and SCT Detector managers. + + The Detector manager has methods to retrieve the Identifier + helper and methods to retrieve the detector elements. It also + manages the alignment with methods to register the call backs + and infrastructure to associate the alignment transforms with + the appropriate alignable transform in GeoModel. + There is also access to the layout (Initial, Final, TestBeam) and + and version information. + + @author: Grant Gorfine + - modified and maintained by Nick Styles & Andreas Salzburger + */ + + class SiDetectorManager : public InDetDetectorManager { + + + public: + + // Constructor + SiDetectorManager(StoreGateSvc * detStore, const std::string & name); + + // Destructor + virtual ~SiDetectorManager() {}; + + + // + // Access Readout Elements + // + + /** access to individual elements using Identifier or IdentiferHash */ + virtual SiDetectorElement * getDetectorElement(const Identifier &id) const = 0; + virtual SiDetectorElement * getDetectorElement(const IdentifierHash &idHash) const = 0; + + /** access to whole collectiom */ + virtual const SiDetectorElementCollection * getDetectorElementCollection() const = 0; + virtual SiDetectorElementCollection::const_iterator getDetectorElementBegin() const = 0; + virtual SiDetectorElementCollection::const_iterator getDetectorElementEnd() const = 0; + + + /** Add elememts */ + virtual void addDetectorElement(SiDetectorElement * element) = 0; + + /** Initialize the neighbours. This can only be done when all elements are built */ + virtual void initNeighbours() = 0; + + /** Get tag used in dictionary */ + const std::string & tag() const; + + /** Methods to query which manager we have */ + virtual bool isPixel() const = 0; + bool isSCT() const {return !isPixel();} + + /** Add alignable transforms. No access to these, they will be changed by manager: */ + virtual void addAlignableTransform (int level, const Identifier &id, GeoAlignableTransform *xf) = 0; + void addKey(const std::string & key, int level); // DEPRECATED - kept for compatibilty with Lisbon CondDB + void addKey(const std::string & key, int level, bool globalDelta); // DEPRECATED - kept for compatibilty with Lisbon CondDB + void addKey(const std::string & key, int level, FrameType frame); // DEPRECATED use addChannel + + // Call back for alignment updates: + // DEPRECATED - now registered in Tool. + StatusCode alignmentCallback( IOVSVC_CALLBACK_ARGS ); + + /** Invalidate cache for all detector elements */ + virtual void invalidateAll() const; + + /** Update all caches */ + virtual void updateAll() const; + + + /** Helper method to set delta transform from a global delta - Amg interface*/ + bool setAlignableTransformGlobalDelta(ExtendedAlignableTransform * extXF, + const Amg::Transform3D & delta) const; + + /** Helper method to set delta transform from a local delta - Amg interface */ + bool setAlignableTransformLocalDelta(ExtendedAlignableTransform * extXF, + const Amg::Transform3D & localToGlobalXF, + const Amg::Transform3D & delta) const; + + /** Access to module design */ + void addDesign(const SiDetectorDesign *); + int numDesigns() const; + const SiDetectorDesign * getDesign(int i) const; + + /** Access Numerology */ + const SiNumerology & numerology() const {return m_numerology;} + SiNumerology & numerology() {return m_numerology;} + + private: + //** Prevent copy and assignment */ + const SiDetectorManager & operator=(const SiDetectorManager &right); + SiDetectorManager(const SiDetectorManager &right); + + /** This method is called by the InDetDetectorManager */ + virtual bool setAlignableTransformDelta(int level, + const Identifier & id, + const Amg::Transform3D & delta, + FrameType frame) const = 0; + + + + std::string m_tag; + SiNumerology m_numerology; + std::vector< const SiDetectorDesign *> m_designs; + + }; + + +} // namespace InDetDD + +#ifndef GAUDI_NEUTRAL +#include "CLIDSvc/CLASS_DEF.h" + +CLASS_DEF(InDetDD::SiDetectorManager, 1441401, 1) +#endif + +#endif // INDETREADOUTGEOMETRY_SIDETECTORMANAGER_H diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiDiodesParameters.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiDiodesParameters.h new file mode 100755 index 0000000000000000000000000000000000000000..6460550ca07f9e284549ceb161a7d58a007ce9b7 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiDiodesParameters.h @@ -0,0 +1,148 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SiDiodesParameters.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef INDETREADOUTGEOMETRY_SIDIODESPARAMETERS_H +#define INDETREADOUTGEOMETRY_SIDIODESPARAMETERS_H + +// Data members classes +#include "InDetReadoutGeometry/SiLocalPosition.h" + +namespace InDetDD { + + /** @class SiDiodesParameters + Class to handle the position of the centre and the width of a + diode or a cluster of diodes + Version 1.1 15/08/2001 David Calvet + */ + + class SiDiodesParameters { + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + /** Implicit constructor: */ + SiDiodesParameters(); + + /** Copy constructor: */ + SiDiodesParameters(const SiDiodesParameters ¶meters); + + /** Constructor with parameters: + position of the diodes centre + width of the diodes */ + SiDiodesParameters(const SiLocalPosition ¢re, + const SiLocalPosition &width); + + /** Destructor: */ + ~SiDiodesParameters(); + + /** Assignment operator: */ + SiDiodesParameters &operator=(const SiDiodesParameters ¶meters); + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /** position of the diodes centre: */ + SiLocalPosition centre() const; + + /** width of the diodes: */ + SiLocalPosition width() const; + SiLocalPosition halfWidth() const; + + /** boundaries of the diodes: */ + double xEtaMin() const; + double xEtaMax() const; + double xPhiMin() const; + double xPhiMax() const; + double xDepthMin() const; + double xDepthMax() const; + + /////////////////////////////////////////////////////////////////// + // Non-const methods: + /////////////////////////////////////////////////////////////////// + + void centre(const SiLocalPosition ¢re); + + void width(const SiLocalPosition &width); + + /////////////////////////////////////////////////////////////////// + // Private data: + /////////////////////////////////////////////////////////////////// + private: + SiLocalPosition m_centre; //!< position of the diodes centre + SiLocalPosition m_width; //!< width of the diodes + }; + +/////////////////////////////////////////////////////////////////// +// Inline methods: +/////////////////////////////////////////////////////////////////// +inline SiDiodesParameters::~SiDiodesParameters() +{} + +inline SiLocalPosition SiDiodesParameters::centre() const +{ + return m_centre; +} + +inline SiLocalPosition SiDiodesParameters::width() const +{ + return m_width; +} + +inline SiLocalPosition SiDiodesParameters::halfWidth() const +{ + return m_width/2; +} + +inline double SiDiodesParameters::xEtaMin() const +{ + return m_centre.xEta()-m_width.xEta()/2; +} + +inline double SiDiodesParameters::xEtaMax() const +{ + return m_centre.xEta()+m_width.xEta()/2; +} + +inline double SiDiodesParameters::xPhiMin() const +{ + return m_centre.xPhi()-m_width.xPhi()/2; +} + +inline double SiDiodesParameters::xPhiMax() const +{ + return m_centre.xPhi()+m_width.xPhi()/2; +} + +inline double SiDiodesParameters::xDepthMin() const +{ + return m_centre.xDepth()-m_width.xDepth()/2; +} + +inline double SiDiodesParameters::xDepthMax() const +{ + return m_centre.xDepth()+m_width.xDepth()/2; +} + +inline void SiDiodesParameters::centre(const SiLocalPosition ¢re) +{ + m_centre=centre; +} + +inline void SiDiodesParameters::width(const SiLocalPosition &width) +{ + m_width=width; +} + +} // namespace InDetDD + +#endif // INDETREADOUTGEOMETRY_SIDIODESPARAMETERS_H diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiIntersect.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiIntersect.h new file mode 100755 index 0000000000000000000000000000000000000000..4cabb39b818cc3c33927166d215660e18dbb469b --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiIntersect.h @@ -0,0 +1,94 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SiIntersect.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef INDETREADOUTGEOMETRY_SIINTERSECT_H +#define INDETREADOUTGEOMETRY_SIINTERSECT_H + +namespace InDetDD { + + /** @class SiIntersect + + class to run intersection tests + + @author Grant Gorfine + */ + + class SiIntersect { + + public: + + enum IntersectState {OUT = 0, BOUNDARY = 1, IN = 2}; + + SiIntersect(IntersectState state = OUT); + + bool in() const; // Definitely in + bool out() const; // Definitely out + bool nearBoundary() const; // Near boundary within tolerences + bool mayIntersect() const; // in() || nearBoundary() + operator bool() const; // Equivalent to mayIntersect(). + + void setIn(); + void setOut(); + void setNearBoundary(); + + private: + IntersectState m_state; + + }; + +inline SiIntersect::SiIntersect(IntersectState state) + : m_state(state) +{} + +inline bool SiIntersect::in() const +{ + return (m_state == IN); +} + +inline bool SiIntersect::out() const +{ + return (m_state == OUT); +} + +inline bool SiIntersect::nearBoundary() const +{ + return (m_state == BOUNDARY); +} + + +inline bool SiIntersect::mayIntersect() const +{ + return (m_state == BOUNDARY || m_state == IN); +} + +inline SiIntersect::operator bool() const +{ + return mayIntersect(); +} + +inline void SiIntersect::setIn() +{ + m_state = IN; +} + +inline void SiIntersect::setOut() +{ + m_state = OUT; +} + +inline void SiIntersect::setNearBoundary() +{ + m_state = BOUNDARY; +} + +} // namespace InDetDD + +#endif //INDETREADOUTGEOMETRY_SIINTERSECT_H + diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiLocalPosition.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiLocalPosition.h new file mode 100755 index 0000000000000000000000000000000000000000..df4d9c7b13b0c7dfe46faa0a24d58ac0cfd0b66f --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiLocalPosition.h @@ -0,0 +1,185 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SiLocalPosition.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef INDETREADOUTGEOMETRY_SILOCALPOSITION_H +#define INDETREADOUTGEOMETRY_SILOCALPOSITION_H + +#include "GeoPrimitives/GeoPrimitives.h" +#include "TrkEventPrimitives/ParamDefs.h" + +namespace Trk { + enum ExtraLocalPosParam {distDepth = 2}; // These will be defined in Trk soon. +} + +namespace InDetDD { + + /** @class SiLocalPosition + Class to represent a position in the natural frame of a silicon sensor, for Pixel and SCT + For Pixel: eta=column, phi=row + + Version 2.1 01/08/2001 David Calvet + */ + + class SiLocalPosition { + + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + /** Implicit constructor: */ + SiLocalPosition(); + + /** Copy constructor: */ + SiLocalPosition(const SiLocalPosition &position); + + /** This allows one to pass a Amg::Vector2D to a SiLocalPosition */ + SiLocalPosition(const Amg::Vector2D &position); + + /** Constructor with parameters: + position along eta direction + position along phi direction + position along depth direction (default is 0) */ + SiLocalPosition(const double xEta,const double xPhi, + const double xDepth=0); + + /** Destructor: */ + ~SiLocalPosition(); + + /** Assignment operator: */ + SiLocalPosition &operator=(const SiLocalPosition &position); + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /** position along eta direction:*/ + double xEta() const; + + /** position along phi direction:*/ + double xPhi() const; + + /** position along depth direction: */ + double xDepth() const; + + /** positions for Pixel: */ + double xColumn() const; + double xRow() const; + + /////////////////////////////////////////////////////////////////// + // Non-const methods: + /////////////////////////////////////////////////////////////////// + + void xEta(const double xEta); + + void xPhi(const double xPhi); + + void xDepth(const double xDepth); + + // for Pixel: + void xColumn(const double xColumn); + void xRow(const double xRow); + + // addition of positions: + SiLocalPosition &operator+=(const SiLocalPosition &position); + + // so we can go from SiLocalPosition to Trk::LocalPosition + operator Amg::Vector2D(void) const; + + + // scaling: + SiLocalPosition &operator*=(const double factor); + SiLocalPosition &operator/=(const double factor); + + /////////////////////////////////////////////////////////////////// + // Private data: + /////////////////////////////////////////////////////////////////// + + private: + double m_xEta; //!< position along eta direction + double m_xPhi; //!< position along phi direction + double m_xDepth; //!< position along depth direction + }; + +/////////////////////////////////////////////////////////////////// +// Inline methods: +/////////////////////////////////////////////////////////////////// +inline SiLocalPosition::~SiLocalPosition() +{} + +inline double SiLocalPosition::xEta() const +{ + return m_xEta; +} + +inline double SiLocalPosition::xPhi() const +{ + return m_xPhi; +} + +inline double SiLocalPosition::xDepth() const +{ + return m_xDepth; +} + +inline double SiLocalPosition::xColumn() const +{ + return m_xEta; +} + +inline double SiLocalPosition::xRow() const +{ + return m_xPhi; +} + +inline void SiLocalPosition::xEta(const double xEta) +{ + m_xEta=xEta; +} + +inline void SiLocalPosition::xPhi(const double xPhi) +{ + m_xPhi=xPhi; +} + +inline void SiLocalPosition::xDepth(const double xDepth) +{ + m_xDepth=xDepth; +} + +inline void SiLocalPosition::xColumn(const double xColumn) +{ + m_xEta=xColumn; +} + +inline void SiLocalPosition::xRow(const double xRow) +{ + m_xPhi=xRow; +} + +/////////////////////////////////////////////////////////////////// +// Binary operators: +/////////////////////////////////////////////////////////////////// +SiLocalPosition operator+(const SiLocalPosition &position1, + const SiLocalPosition &position2); + +SiLocalPosition operator*(const SiLocalPosition &position,const double factor); + +inline SiLocalPosition operator*(const double factor,const SiLocalPosition &position) +{ + return position*factor; +} + +SiLocalPosition operator/(const SiLocalPosition &position,const double factor); + +} // namespace InDetDD + +#endif // INDETREADOUTGEOMETRY_SILOCALPOSITION_H diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiNumerology.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiNumerology.h new file mode 100755 index 0000000000000000000000000000000000000000..f52f015470e0438d42884100a57e4b76db4cd945 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiNumerology.h @@ -0,0 +1,154 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SiNumerology.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + + +#ifndef INDETREADOUTGEOMETRY_SINUMEROLOGY_H +#define INDETREADOUTGEOMETRY_SINUMEROLOGY_H + +#include <vector> + +namespace InDetDD { + + /** @class SiNumerology + + Class to extract numerology for Pixel and SCT. For example number of layers, disks, sectors, rings, etc. + See InnerDetector/InDetExample/InDetDetDescrExample/src/SiReadSiDetectorElements.cxx for example of usage. + + @author Grant Gorfine + */ + + class SiNumerology { + + + public: + + /** Constructor: */ + SiNumerology(); + + // Accessors: + + /** Number of barrels. Normally 1. */ + int numBarrels() const; + + /** Number of endcaps. Normally 2. */ + int numEndcaps() const; + + /** Barrel/endcap identifier for each barrel. Normally barrelId(0) = 0 */ + int barrelId(int index) const; + + /** Barrel/endcap identifier for each endcap. Normally endcapId(0) returns 2, endcapId(1) returns -2 */ + int endcapId(int index) const; + + /** Number of layers */ + int numLayers() const; + + /** Number of disks */ + int numDisks() const; + + /** Number of rings (ie eta_module) in a disk */ + int numRingsForDisk(int disk) const; + + /** Number of sectors in phi for a layer */ + int numPhiModulesForLayer(int layer) const; + + /** Number of sectors in phi for a ring in a disk */ + int numPhiModulesForDiskRing(int disk, int ring) const; + + /** Number of sectors in phi for a ring in a disk */ + int numEtaModulesForLayer(int layer) const; + + /** First eta_module number for a layer */ + int beginEtaModuleForLayer(int layer) const; + + /** Last eta_module number + 1 */ + int endEtaModuleForLayer(int layer) const; + + /** Check if eta_module=0 exists */ + bool skipEtaZeroForLayer(int layer) const; + + // Check presence of layer/disk + /** Check if layer exists */ + bool useLayer(int layer) const; + + /** Check if disk exists */ + bool useDisk(int disk) const; + + // Maximums + /** Maximum number of modules in a barrel stave */ + int maxNumBarrelEta() const; + + /** Maximum number of rings in a disk */ + int maxNumEndcapRings() const; + + /** Maximum number of strips. Same as maxNumPhiCells() */ + int maxNumStrips() const; + + /** Maximum number of cells in phi direction. Same as maxNumStrips() */ + int maxNumPhiCells() const; + + /** Maximum number of cells in eta direction. 0 for SCT. */ + int maxNumEtaCells() const; + + // Modifiers: + void addBarrel(int id); + void addEndcap(int id); + void setNumLayers(int nLayers); + void setNumDisks(int nDisks); + void setNumRingsForDisk(int disk, int nRings); + void setNumPhiModulesForLayer(int layer, int nPhiModules); + void setNumPhiModulesForDiskRing(int disk, int ring, int nPhiModules); + void setNumEtaModulesForLayer(int layer, int nEtaModules); + void setMaxNumEtaCells(int cells); + void setMaxNumPhiCells(int cells); + + // DBM + int numDisksDBM() const; + int numBarrelDBM() const; + bool useDiskDBM(int disk) const; + int numRingsForDiskDBM(int currentdisk) const; + int numPhiModulesForDiskRingDBM(int disk, int ring) const; + int numEndcapsDBM() const; + int endcapIdDBM(int index) const; + + void setNumDisksDBM(int nDisks); + void setNumBarrelDBM(int nBarrel); + void setNumPhiModulesForDiskRingDBM(int disk, int ring, int nPhiModules); + void addEndcapDBM(int id); + + private: + + int m_numLayers; + int m_numDisks; + int m_maxPhiCells; + int m_maxEtaCells; + int m_maxNumBarrelEta; + int m_maxNumEndcapRings; + int m_maxNumBarrelPhiModules; + int m_maxNumEndcapPhiModules; + + std::vector<int> m_barrelIds; + std::vector<int> m_endcapIds; + std::vector<int> m_phiModulesForLayer; + std::vector<int> m_ringsForDisk; + std::vector<std::vector<int> > m_phiModulesForDiskRing; + std::vector<int> m_etaModulesForLayer; + + int m_numDisksDBM; + int m_numBarrelDBM; + std::vector<int> m_endcapIdsDBM; + std::vector<std::vector<int> > m_phiModulesForDiskRingDBM; + int m_maxNumEndcapPhiModulesDBM; + }; + +}// End namespace + +#include "SiNumerology.icc" + +#endif // INDETREADOUTGEOMETRY_SINUMEROLOGY_H diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiNumerology.icc b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiNumerology.icc new file mode 100644 index 0000000000000000000000000000000000000000..614cc853d31d22a5e5dd8c7d082b1b3642f09f9a --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiNumerology.icc @@ -0,0 +1,146 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +namespace InDetDD { + +inline int SiNumerology::numBarrels() const +{ + return m_barrelIds.size(); +} + +inline int SiNumerology::numEndcaps() const +{ + return m_endcapIds.size(); +} + +inline int SiNumerology::barrelId(int index) const +{ + return m_barrelIds[index]; +} + +inline int SiNumerology::endcapId(int index) const +{ + return m_endcapIds[index]; +} + +inline int SiNumerology::numLayers() const +{ + return m_numLayers; +} + +inline int SiNumerology::numDisks() const +{ + return m_numDisks; +} + +inline int SiNumerology::numRingsForDisk(int disk) const +{ + return m_ringsForDisk[disk]; +} + +inline int SiNumerology::numPhiModulesForLayer(int layer) const +{ + return m_phiModulesForLayer[layer]; +} + +inline int SiNumerology::numPhiModulesForDiskRing(int disk, int ring) const +{ + return m_phiModulesForDiskRing[disk][ring]; +} + +inline int SiNumerology::numEtaModulesForLayer(int layer) const +{ + return m_etaModulesForLayer[layer]; +} + +inline int SiNumerology::beginEtaModuleForLayer(int layer) const +{ + // Assume symmetric about zero. + return -m_etaModulesForLayer[layer]/2; +} + +inline int SiNumerology::endEtaModuleForLayer(int layer) const +{ + // Assume symmetric about zero. + return m_etaModulesForLayer[layer]/2+1; +} + +inline bool SiNumerology::skipEtaZeroForLayer(int layer) const +{ + // If even then no module at eta = 0. + return !(m_etaModulesForLayer[layer]%2); +} + +inline int SiNumerology::maxNumBarrelEta() const +{ + return m_maxNumBarrelEta; +} + +inline int SiNumerology::maxNumEndcapRings() const +{ + return m_maxNumEndcapRings; +} + +inline int SiNumerology::maxNumStrips() const +{ + return m_maxPhiCells; +} + +inline int SiNumerology::maxNumPhiCells() const +{ + return m_maxPhiCells; +} + +inline int SiNumerology::maxNumEtaCells() const +{ + return m_maxEtaCells; +} + + +inline bool SiNumerology::useLayer(int layer) const +{ + return (m_phiModulesForLayer[layer] != 0); +} + +inline bool SiNumerology::useDisk(int disk) const +{ + return (m_ringsForDisk[disk] != 0); +} + +inline int SiNumerology::numBarrelDBM() const +{ + return 0; +} + +inline int SiNumerology::numDisksDBM() const +{ + return m_numDisksDBM; +} + +inline bool SiNumerology::useDiskDBM(int disk) const +{ + return (disk<numDisksDBM())?1:0; +} + +inline int SiNumerology::numRingsForDiskDBM(int /*currentdisk*/) const +{ + return 1; +} + +inline int SiNumerology::numPhiModulesForDiskRingDBM(int disk, int ring) const +{ + return m_phiModulesForDiskRingDBM[disk][ring]; +} + +inline int SiNumerology::numEndcapsDBM() const +{ + return m_endcapIdsDBM.size(); +} + +inline int SiNumerology::endcapIdDBM(int index) const +{ + return m_endcapIdsDBM[index]; +} + +} // End namespace diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiReadoutCellId.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiReadoutCellId.h new file mode 100755 index 0000000000000000000000000000000000000000..fd4463700fbf23dfd787f8bb25c4754c68ed09c9 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SiReadoutCellId.h @@ -0,0 +1,77 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SiReadoutCellId.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef INDETREADOUTGEOMETRY_SIREADOUTCELLID_H +#define INDETREADOUTGEOMETRY_SIREADOUTCELLID_H + +// Base class +#include "InDetReadoutGeometry/SiCellId.h" + +namespace InDetDD { + + /** @class SiReadoutCellId + + Identifier for the strip or pixel readout cell. + + SiReadoutCellId behaves identically to its base class. Its only + introduced to provide some type safety and distiguish between + diodes (base class) and readout cells (this class). This is since + more than one diode can be connected to a readout cell. + + The following conversion is legal + + SiReadoutCellId -> SiCellId OK + + However the oppoisite is not allowed + + SiCellId -> SiReadoutCellId NOT ALLOWED + + since a SiCellId might not have direct readout out (eg for an + edge strip or ganged pixel). + + @author Grant Gorfine + */ + + class SiReadoutCellId : public SiCellId { + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + // Allow construction from base class + // explicit SiReadoutCellId(const SiCellIdentifier &); + + SiReadoutCellId(); // Set in invalid state. + SiReadoutCellId(int strip); + SiReadoutCellId(int phiIndex, int etaIndex); + +}; + +/////////////////////////////////////////////////////////////////// +// Inline methods: +/////////////////////////////////////////////////////////////////// + +inline SiReadoutCellId::SiReadoutCellId() + : SiCellId() +{} + +inline SiReadoutCellId::SiReadoutCellId(int phiIndex, int etaIndex) + : SiCellId(phiIndex, etaIndex) +{} + +inline SiReadoutCellId::SiReadoutCellId(int strip) + : SiCellId(strip) +{} + + +} // namespace InDetDD + +#endif // INDETREADOUTGEOMETRY_SIREADOUTCELLID_H diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SurfaceCache.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SurfaceCache.h new file mode 100755 index 0000000000000000000000000000000000000000..826c2ba05cc53e47806096a8bfd8fe49da01a53a --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/SurfaceCache.h @@ -0,0 +1,84 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SurfaceCache.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef InDetReadoutGeometry_SurfaceCache_h +#define InDetReadoutGeometry_SurfaceCache_h + +#include "GeoPrimitives/GeoPrimitives.h" +#include "TrkSurfaces/SurfaceBounds.h" + +namespace InDetDD { + + /** @class SurfaceCache + + This class is for internal use in InDetReadoutGeometry. + It holds all the cached values related to the element surface. + + It's a simple class to still alllow the + Trk::Surface::transform() { m_associatedDetectorElement->transform() } + method to work, hence, it basically copies the Trk::Surface structure. + + The surface cache class alows also to store 0 pointers, + indicating the the holder of the cache has a commonly shared object, + e.g. the straw bounds of all straws in one detector element. + + @author: Grant Gorfine, Andreas Salzburger + */ + + class SurfaceCache + { + + public: + SurfaceCache(const Amg::Transform3D* transform, + const Amg::Vector3D* center, + const Amg::Vector3D* normal, + const Trk::SurfaceBounds* bounds); + + ~SurfaceCache(); + + const Amg::Transform3D* transform() {return (m_transform);} + + const Amg::Vector3D* center() {return (m_center);} + + const Amg::Vector3D* normal() {return (m_normal);} + + const Trk::SurfaceBounds* bounds() {return (m_bounds);} + + private: + const Amg::Transform3D* m_transform; + const Amg::Vector3D* m_center; + const Amg::Vector3D* m_normal; + const Trk::SurfaceBounds* m_bounds; + + }; + + inline SurfaceCache::SurfaceCache(const Amg::Transform3D* transform, + const Amg::Vector3D* center, + const Amg::Vector3D* normal, + const Trk::SurfaceBounds* bounds) + : m_transform(transform), + m_center(center), + m_normal(normal), + m_bounds(bounds) + {} + + + inline SurfaceCache::~SurfaceCache() + { + delete m_transform; + delete m_center; + delete m_normal; + delete m_bounds; + } + +} // end namespace + + +#endif // InDetReadoutGeometry_SurfaceCache_h diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_BarrelCode.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_BarrelCode.h new file mode 100755 index 0000000000000000000000000000000000000000..e8a4b9bd5206fc334b0345a917292081f0fbb11e --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_BarrelCode.h @@ -0,0 +1,145 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// TRT_BarrelCode.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef TRT_BarrelCode_h +#define TRT_BarrelCode_h 1 + +#include <iostream> + +// Include the string class header +#include <string> + +namespace InDetDD { + + /** @class TRT_BarrelCode + + bit definitions to decode TRT straws in barrel + */ + + class TRT_BarrelCode + { + public: + + typedef enum { MODULE_A = 0, + MODULE_B = 1, + MODULE_C = 2 } Module; + + TRT_BarrelCode(); + TRT_BarrelCode( unsigned int isPositive, unsigned int moduleIndex, unsigned phiIndex, unsigned int strawLayerIndex); + + TRT_BarrelCode( const TRT_BarrelCode & right ); + ~TRT_BarrelCode(); + + const TRT_BarrelCode & operator=( const TRT_BarrelCode & right ); + + bool operator < (const TRT_BarrelCode & right) const; + bool operator > (const TRT_BarrelCode & right) const; + bool operator== (const TRT_BarrelCode & right) const; + bool operator!= (const TRT_BarrelCode & right) const; + + unsigned int isPosZ() const; + unsigned int getModuleIndex() const; + unsigned int getPhiIndex() const; + unsigned int getStrawLayerIndex() const; + unsigned int getKey() const; + std::string getName() const; + + private: + + // Define key as a bit string: + // bit 0 Z (negative=0 or positive=1) + // bit 1-2 Module Index (0-2) + // bit 3-7 Phi Index + // bit 8-12 StrawLayer Index + + unsigned short int _key; + + static const int Z_MASK; + static const int MODULE_MASK; + static const int PHI_MASK; + static const int STRAWLAYER_MASK; + + + static const int Z_SHIFT; + static const int MODULE_SHIFT; + static const int PHI_SHIFT; + static const int STRAWLAYER_SHIFT; + + }; + + + + inline unsigned int TRT_BarrelCode::isPosZ() const { + unsigned int ret = _key; + return (ret >> Z_SHIFT) & Z_MASK; + } + + inline unsigned int TRT_BarrelCode::getModuleIndex() const{ + unsigned int ret = _key; + return (ret >> MODULE_SHIFT) & MODULE_MASK; + } + + inline unsigned int TRT_BarrelCode::getPhiIndex() const{ + unsigned int ret = _key; + return (ret >> PHI_SHIFT) & PHI_MASK; + } + + inline unsigned int TRT_BarrelCode::getStrawLayerIndex() const { + unsigned int ret = _key; + return (ret >> STRAWLAYER_SHIFT) & STRAWLAYER_MASK; + } + + inline unsigned int TRT_BarrelCode::getKey() const { + return _key; + } + + + inline bool TRT_BarrelCode::operator==(const TRT_BarrelCode &right) const + { + return (getKey() == right.getKey()); + } + + inline bool TRT_BarrelCode::operator!=(const TRT_BarrelCode &right) const + { + return (getKey() != right.getKey()); + } + + inline bool TRT_BarrelCode::operator<(const TRT_BarrelCode &right) const + { + return (getKey() < right.getKey()); + } + + inline bool TRT_BarrelCode::operator>(const TRT_BarrelCode &right) const + { + return (getKey() > right.getKey()); + } +} // End InDetDD namespace + + +inline std::ostream & operator << (std::ostream & os, const InDetDD::TRT_BarrelCode & code) { + // Plus/minus + if (code.isPosZ()) os << '+'; + else os << '-'; + // Module + unsigned int mod = code.getModuleIndex(); + if (mod==0) os << 'A'; + else if (mod==1) os << 'B'; + else if (mod==2) os << 'C'; + else os << "?"; + // Phi Index: + os << code.getPhiIndex(); + // Separator: + os << '/'; + // StrawLayer: + os << code.getStrawLayerIndex(); + return os; +} + +#endif diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_BarrelDescriptor.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_BarrelDescriptor.h new file mode 100755 index 0000000000000000000000000000000000000000..4fb3533e853489f3fd3ba71faeb0ab822cd3e925 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_BarrelDescriptor.h @@ -0,0 +1,117 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// TRT_BarrelDescriptor.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef TRT_BarrelDescriptor_h +#define TRT_BarrelDescriptor_h 1 +#include "GeoModelKernel/RCBase.h" +#include "GeoModelKernel/GeoXF.h" +#include <vector> + +namespace Trk{ + class CylinderBounds; + class SurfaceBounds; +} + +namespace InDetDD { + + /** @class TRT_BarrelDescriptor + + Local Straw Positions (from the center of the module.) + + The center of the module is defined like this: + + .--------. + / \ / + / \ / + / o \ / + /_______\/ + + */ + + class TRT_BarrelDescriptor : public RCBase + { + + public: + + /** Constructor: */ + TRT_BarrelDescriptor(); + + /** Add a new straw at position x, y: */ + void addStraw(double xPos, double yPos); + + /** Sets the transform field for straws and offset. Ownership is not passed. */ + void setStrawTransformField(const GeoXF::Function *xf, size_t offsetInto); + + /** Get X Position: */ + inline double & strawXPos (unsigned int i); + inline const double & strawXPos (unsigned int i) const; + + /** Get Y Position: */ + inline double & strawYPos (unsigned int i); + inline const double & strawYPos (unsigned int i) const; + + /** Get the number of straws: */ + inline unsigned int nStraws() const; + + /** Get the length of the straws: */ + inline const double & strawLength() const; + inline double & strawLength(); + inline void strawLength(double newLength); + + /** Get inner tube radius of the straw */ + inline double innerTubeRadius() const; + + /** Dead part */ + inline const double & strawZDead() const; + inline double & strawZDead(); + inline void strawZDead(double zDead); + + /** Position of center of active region. */ + inline const double & strawZPos() const; + inline double & strawZPos(); + inline void strawZPos(double Pos); + + /** Get the tranformation field, which we do not own: + Does not include the z shift which is different for pos and + negative barrel: */ + inline const GeoXF::Function *getStrawTransform() const; + + /** Get the offset into the transformation field: */ + inline size_t getStrawTransformOffset() const; + + /** Get Bounds */ + const Trk::SurfaceBounds & strawBounds() const; + + protected: + + virtual ~TRT_BarrelDescriptor(); + + private: + + TRT_BarrelDescriptor(const TRT_BarrelDescriptor &right); + const TRT_BarrelDescriptor & operator=(const TRT_BarrelDescriptor &right); + + std::vector<double> _x; + std::vector<double> _y; + double _length; + double _zDead; + double _zPos; + double m_innerTubeRadius; + const GeoXF::Function *_f; + size_t _o; + + mutable Trk::CylinderBounds * m_bounds; + + }; +} +#include "TRT_BarrelDescriptor.icc" +#endif + + diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_BarrelDescriptor.icc b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_BarrelDescriptor.icc new file mode 100755 index 0000000000000000000000000000000000000000..d7a5247ecd62cc4f89597e089c6270050c807b62 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_BarrelDescriptor.icc @@ -0,0 +1,78 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +namespace InDetDD { +inline double & TRT_BarrelDescriptor::strawXPos (unsigned int i) { + return _x[i]; +} + +inline const double & TRT_BarrelDescriptor::strawXPos (unsigned int i) const { + return _x[i]; +} + +inline double & TRT_BarrelDescriptor::strawYPos (unsigned int i) { + return _y[i]; +} +inline const double & TRT_BarrelDescriptor::strawYPos (unsigned int i) const { + return _y[i]; +} + +inline unsigned int TRT_BarrelDescriptor::nStraws() const { + return _x.size(); +} + +inline const double & TRT_BarrelDescriptor::strawLength() const { + return _length; +} + +inline double & TRT_BarrelDescriptor::strawLength() { + return _length; +} + +inline void TRT_BarrelDescriptor::strawLength(double newLength) { + _length = newLength; +} + + +inline double TRT_BarrelDescriptor::innerTubeRadius() const +{ + return m_innerTubeRadius; +} + + +inline const double & TRT_BarrelDescriptor::strawZDead() const { + return _zDead; +} + +inline double & TRT_BarrelDescriptor::strawZDead() { + return _zDead; +} + +inline void TRT_BarrelDescriptor::strawZDead(double zDead) { + _zDead = zDead; +} + +inline const double & TRT_BarrelDescriptor::strawZPos() const { + return _zPos; +} + +inline double & TRT_BarrelDescriptor::strawZPos() { + return _zPos; +} + +inline void TRT_BarrelDescriptor::strawZPos(double zPos) { + _zPos = zPos; +} + +inline const GeoXF::Function * TRT_BarrelDescriptor::getStrawTransform() const { + return _f; +} + +inline size_t TRT_BarrelDescriptor::getStrawTransformOffset() const { + return _o; +} + + + +} diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_BarrelElement.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_BarrelElement.h new file mode 100755 index 0000000000000000000000000000000000000000..4ebb5443a8b2d8f564a70c0b2c0f3a7c123e8541 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_BarrelElement.h @@ -0,0 +1,163 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// TRT_BarrelElement.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef TRT_BarrelElement_h +#define TRT_BarrelElement_h 1 +#include "InDetReadoutGeometry/TRT_BarrelCode.h" +#include "InDetReadoutGeometry/TRT_BarrelDescriptor.h" +#include "InDetReadoutGeometry/TRT_BaseElement.h" + +class TRT_ID; + +namespace Trk{ + class Surface; + class SurfaceBounds; +} + +class SurfaceCache; + +namespace InDetDD { + + class TRT_BarrelConditions; + + /** @class TRT_BarrelElement + + Extended TRT_BaseElement to describe a TRT readout element, + this is a planar layer with n ( order of 20 ) straws, in one + of the 32 sectors of the TRT barrel. + + The number of straws described by this readout element can be + retrieved by nStraws() + + @author: Grant Gorfine + - modified & maintained: Nick Styles, Andreas Salzburger + */ + + class TRT_BarrelElement : public TRT_BaseElement { + + public: + + /** Constructor: */ + TRT_BarrelElement(const GeoVFullPhysVol *volume, + const TRT_BarrelDescriptor *descriptor, + bool isPositive, + unsigned int modIndex, + unsigned int phiIndex, + unsigned int strawLayIndex, + const TRT_ID * idHelper, + const TRT_Conditions * conditions); + + /** Destructor: */ + virtual ~TRT_BarrelElement(); + + /** Type information */ + virtual TRT_BaseElement::Type type() const {return TRT_BaseElement::BARREL;} + + /** Returns a pointer to conditions data. This includes + information on dead and noisy wires, as well as wire + sags. */ + const TRT_BarrelConditions * getConditionsData() const; + + /** Returns a pointer to a descriptor, giving common + information on module construction: */ + const TRT_BarrelDescriptor * getDescriptor() const; + + /** Get X Position: + DEPRECATED. Please use starwCenter(i).x() */ + inline double strawXPos (unsigned int i) const; + + /** Get Y Position: + DEPRECATED. Please use starwCenter(i).y() */ + inline double strawYPos (unsigned int i) const; + + /** Get Z Position: (active center) + DEPRECATED. Please use starwCenter(i).z() */ + inline double strawZPos (unsigned int i) const; + + /** Default Local -> global transform of the straw (ie before alignment corrections) */ + virtual HepGeom::Transform3D defStrawTransform(int straw) const; + + /** Get the number of straws: */ + virtual unsigned int nStraws() const; + + /** Get the length of the straws (active length): */ + virtual const double & strawLength() const; + + /** StrawDirection. +1 if axis is in same direction as local coordinate, -1 otherwise. */ + virtual int strawDirection() const; + + /** Returns the next-in-phi detector element, or zero if none (forseeing gaps, in other words). */ + const TRT_BarrelElement * nextInPhi() const; + + /** Returns the previous-in-phi detector element, or zero if none (forseeing gaps, in other words). */ + const TRT_BarrelElement * previousInPhi() const; + + /** Returns the next-in-R detector element, or zero if none. */ + const TRT_BarrelElement * nextInR() const; + + /** Returns the next-in-R detector element, or zero if none. */ + const TRT_BarrelElement * previousInR() const; + + /** Sets the next-in-phi detector. */ + void setNextInPhi(const TRT_BarrelElement *element); + + /** Sets the previous-in-phi detector. */ + void setPreviousInPhi(const TRT_BarrelElement *element); + + /** Sets the next-in-r detector. */ + void setNextInR(const TRT_BarrelElement *element); + + /** Sets the previous-in-r detector. */ + void setPreviousInR(const TRT_BarrelElement *element); + + /** Doomed (?): */ + const TRT_BarrelCode & getCode() const; + + /** Surface bounds */ + virtual const Trk::SurfaceBounds & strawBounds() const; + + private: + + /** Illegal Operations: */ + TRT_BarrelElement(const TRT_BarrelElement &right); + const TRT_BarrelElement & operator=(const TRT_BarrelElement &right); + + protected: + /** These transforms are effectively to the local coord + system of a straw derived from GeoModel -> hence CLHEP */ + HepGeom::Transform3D calculateStrawTransform(int straw) const; + HepGeom::Transform3D calculateLocalStrawTransform(int straw) const; + + /** return the surface of the element */ + const Trk::Surface & elementSurface() const; + + /** create the cache for the element */ + void createSurfaceCache() const; + + protected: + // Protected Member data: + TRT_BarrelCode _code; + const TRT_BarrelDescriptor *_descriptor; + const TRT_BarrelElement *_nextInPhi; + const TRT_BarrelElement *_previousInPhi; + const TRT_BarrelElement *_nextInR; + const TRT_BarrelElement *_previousInR; + + mutable Trk::Surface* m_surface; + + }; + + +} + +#include "TRT_BarrelElement.icc" +#endif + + diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_BarrelElement.icc b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_BarrelElement.icc new file mode 100755 index 0000000000000000000000000000000000000000..d7afd0e8b052dc8391221a85b3bfc2db55ae8730 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_BarrelElement.icc @@ -0,0 +1,59 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "InDetIdentifier/TRT_ID.h" + +namespace InDetDD { + +inline const TRT_BarrelElement * TRT_BarrelElement::nextInPhi() const +{ + return _nextInPhi; +} + +inline const TRT_BarrelElement * TRT_BarrelElement::previousInPhi() const +{ + return _previousInPhi; +} + +inline const TRT_BarrelElement * TRT_BarrelElement::nextInR() const +{ + return _nextInR; +} + +inline const TRT_BarrelElement * TRT_BarrelElement::previousInR() const +{ + return _previousInR; +} + +inline const TRT_BarrelCode & TRT_BarrelElement::getCode() const +{ + return _code; +} + + +// Get X Position - should not be used anymore +inline double TRT_BarrelElement::strawXPos (unsigned int straw) const { + return strawCenter(straw).x(); +} + +// Get Y Position - should not be used anymore +inline double TRT_BarrelElement::strawYPos (unsigned int straw) const { + return strawCenter(straw).y(); +} + +// Get Z Position - should not be used anymore +inline double TRT_BarrelElement::strawZPos (unsigned int straw) const { + return strawCenter(straw).z(); +} + +// Get the number of straws: +inline unsigned int TRT_BarrelElement::nStraws() const { + return _descriptor->nStraws(); +} + +// Get the length of the straws: +inline const double & TRT_BarrelElement::strawLength() const { + return _descriptor->strawLength(); +} +} diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_BaseElement.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_BaseElement.h new file mode 100755 index 0000000000000000000000000000000000000000..8fe2e4e0fc580a7dee8bfe0c24485d0b142bf9d9 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_BaseElement.h @@ -0,0 +1,235 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// TRT_BaseElement.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef TRT_BaseElement_h +#define TRT_BaseElement_h 1 + +#include "TrkDetElementBase/TrkDetElementBase.h" + +#include "Identifier/IdentifierHash.h" +#include "Identifier/Identifier.h" + +#include "GeoPrimitives/GeoPrimitives.h" +#include "CLHEP/Geometry/Transform3D.h" +#include "CLHEP/Geometry/Point3D.h" + +#include <vector> + +namespace Trk { + class Surface; + class StraightLineSurface; +} + + +class TRT_ID; + +namespace InDetDD { + + class SurfaceCache; + class TRT_Conditions; + + /** @class TRT_BaseElement + + Virtual base class of TRT readout elements. + Differently to the Silicon readout elements, the TRT readoutelements describe multiple readout surfaces, + i.e. several straws that are described by a surface, such as e.g. a planar sector surface in the barrel, + or a disc surface in the endcap. + + @author Grant Gorfine + - modified& maintained: Andreas Salzburger, Nick Styles + + */ + + class TRT_BaseElement : public Trk::TrkDetElementBase { + + public: + + enum Type {BARREL, ENDCAP}; + + /** Constructor: */ + TRT_BaseElement(const GeoVFullPhysVol *volume, const Identifier& id, const TRT_ID* idHelper, const TRT_Conditions* conditions); + + /** Destructor: */ + virtual ~TRT_BaseElement(); + + /** Type information: returns BARREL or ENDCAP */ + virtual TRT_BaseElement::Type type() const = 0; + + /** identifier of this detector element: */ + virtual Identifier identify() const; + + /** identifier hash */ + virtual IdentifierHash identifyHash() const; + + // --- GeoModel transformation forwards ----------------------------------------------------- // + + /** Get Default Transform (of module in barrel, layer in endcap) from GeoModel before alignment corrections: CLHEP */ + const HepGeom::Transform3D& defTransform() const; + + /** Default Local -> global transform of the straw (ie before alignment corrections) : CLHEP */ + virtual HepGeom::Transform3D defStrawTransform(int straw) const = 0; + + /** This is an alias to strawTransform(int straw) */ + const HepGeom::Transform3D getAbsoluteTransform(int straw) const; + + // ---- Surface & Tracking information cache ------------------------------------------------ // + // (a) Element Surface section - accesses the m_surfaceCache store + + /** Element Surface: access to the Surface (straw layer) */ + virtual const Trk::Surface& surface () const; + + /** Straw layer bounds */ + virtual const Trk::SurfaceBounds& bounds() const; + + /** Element Surface: Get Transform of element in Tracking frame: Amg */ + virtual const Amg::Transform3D& transform() const; + + /** Element Surface: center of a straw layer. */ + virtual const Amg::Vector3D& center() const; + + /** Element Surface: normal of a straw layer */ + virtual const Amg::Vector3D& normal() const; + + // (b) Straw Surface section - accesses the vector<SurfaceCache> m_strawSurfacesCache store + + /** Straw Surface: access to the surface via identifier */ + virtual const Trk::Surface& surface (const Identifier& id) const; + + /** Straw Surface: access to the bounds via Identifier */ + virtual const Trk::SurfaceBounds& bounds(const Identifier& id) const; + + /** Straw Surface: access to the transform of individual straw in Tracking frame: Amg */ + virtual const Amg::Transform3D& transform(const Identifier& id) const; + + /** Straw transform - fast access in array, in Tracking frame: Amg */ + /** Straw Surface: access to the transform of individual straw in Tracking frame: Amg */ + virtual const Amg::Transform3D& strawTransform(unsigned int straw) const; + + /** Straw Surface: Center of a straw using Identifier + Straw center and straw axis can be obtained by the following: + (The straw center is the center of the active region) + Amg::Transform3D& transform = element->strawTransform(straw); + Amb::Vector3D& center = element->strawCenter(); + double r = element->strawCenter()->perp(); + double phi = element->strawCenter()->phi(); + Amg::Vector3D strawAxis = element->strawTransform(straw)* Vector3D(0,0,1) * strawDirection() */ + + virtual const Amg::Vector3D& center(const Identifier& id) const; + + /** Normal of a straw. (Not very meaningful). */ + virtual const Amg::Vector3D& normal(const Identifier& id) const; + + /** Straw Surface: access to the surface via integer */ + const Trk::StraightLineSurface& strawSurface(int straw) const; + + /** Straw Surface: Local -> global transform of the straw via integer */ + const Amg::Transform3D& strawTransform(int straw) const; + + /** Straw Surface: Local -> global transform of the straw via integer */ + const Amg::Vector3D& strawCenter(int straw) const; + + /** Straw axis. Always in direction of increasing eta. + +ve z direction in barrel (for both +ve and -ve half) + Away from beam pipe in -ve z endcap, + Towards beam pipe in +ve endcap. */ + Amg::Vector3D strawAxis(int straw) const; + + /** Number of straws in the element. */ + virtual unsigned int nStraws() const = 0; + + /** Active straw length */ + virtual const double& strawLength() const = 0; + + /** StrawDirection. +1 if axis is in same direction as local z axis, -1 otherwise. */ + virtual int strawDirection() const = 0; + + // ---- CLHEP methods ---- to be checked if needed --------------------------------------------- (start) + // the cache changed to Amg, hence CLHEP methods don't return by reverence anymore + + /** Element Surface: Get Transform of element in Tracking frame - CLHEP converted */ + virtual const HepGeom::Transform3D transformCLHEP() const; + + /** Element Surface: Straw center - CLHEP converted*/ + virtual const HepGeom::Point3D<double> centerCLHEP() const; + + /** Element Surface: Normal of a straw layer - CLHEP converted */ + virtual const HepGeom::Vector3D<double> normalCLHEP() const; + + /** Straw Surface : get Transform of individual straw in Tracking frame - CLHEP converted */ + virtual const HepGeom::Transform3D transformCLHEP(const Identifier& id) const; + + /** Straw Surface : Center of a straw using Identifier - CLHEP converted */ + virtual const HepGeom::Point3D<double> centerCLHEP(const Identifier& id) const; + + /** Straw Surface : Center of a straw using Identifier - CLHEP converted */ + virtual const HepGeom::Vector3D<double> normalCLHEP(const Identifier& id) const; + + // ---- CLHEP methods ---- to be checked if needed --------------------------------------------- (end) + + /** Invalidate cache */ + void invalidate() const; + + /** Update all caches */ + void updateAllCaches() const; + + /** Return the TRT_Conditions object associated to this Detector element */ + const TRT_Conditions* conditions() const; + + + protected: + /** to be overloaded by the extended classes */ + virtual HepGeom::Transform3D calculateStrawTransform(int straw) const = 0; + + /** the straw bounds */ + virtual const Trk::SurfaceBounds& strawBounds() const = 0; + + /** creates surface for detector element, to be implemented in derived class */ + virtual const Trk::Surface& elementSurface() const = 0; + + /** create the surface cache of the detector element, to be implementd in the deried class */ + virtual void createSurfaceCache() const = 0; + + /** create the surface & surface cache for the straw */ + void createSurfaceCache(Identifier id) const; + + /** invalidate action on the cache */ + virtual void invalidateOther() const {}; + + private: + + /** Illegal operations: */ + TRT_BaseElement(const TRT_BaseElement&right); + const TRT_BaseElement& operator=(const TRT_BaseElement&right); + + /** Helper method for cache dealing */ + void deleteCache() const; + + protected: + + Identifier m_id; + IdentifierHash m_idHash; + const TRT_ID* m_idHelper; + const TRT_Conditions* m_conditions; + + // Amg cache for the straw surfaces + mutable std::vector<Trk::StraightLineSurface*>* m_strawSurfaces; + mutable std::vector<SurfaceCache*>* m_strawSurfacesCache; + + //!< helper element surface for the cache + mutable SurfaceCache* m_surfaceCache; + + }; + +} + +#include "TRT_BaseElement.icc" +#endif + + diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_BaseElement.icc b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_BaseElement.icc new file mode 100755 index 0000000000000000000000000000000000000000..828631ffe639d43c00fb32dde2a0a5adf0a6d0bc --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_BaseElement.icc @@ -0,0 +1,12 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +namespace InDetDD { + +inline const HepGeom::Transform3D & TRT_BaseElement::defTransform() const +{ + return getMaterialGeom()->getDefAbsoluteTransform(); +} + +} diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_Conditions.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_Conditions.h new file mode 100755 index 0000000000000000000000000000000000000000..2c1551d6694b4d7ce8905b6d0c28cfd5d1159b30 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_Conditions.h @@ -0,0 +1,49 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// TRT_Conditions.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef INDETREADOUTGEOMETRY_TRT_CONDITIONS_H +#define INDETREADOUTGEOMETRY_TRT_CONDITIONS_H + +#include "GeoModelKernel/RCBase.h" +#include "CLHEP/Geometry/Transform3D.h" + +namespace TRTCond { + class StrawDxContainer; +} + +namespace InDetDD { + + /** @class TRT_Conditions + + This class is a interface to conditions objects. There is a single instance shared by all TRT elements + */ + + class TRT_Conditions : public RCBase { + + public: + + TRT_Conditions(); + + const TRTCond::StrawDxContainer* dxContainer() const; + void setDxContainer(const TRTCond::StrawDxContainer* container); + + const HepGeom::Transform3D & solenoidFrame() const; + void setSolenoidFrame(const HepGeom::Transform3D & frame); + + private: + mutable const TRTCond::StrawDxContainer* m_dxContainer; + mutable HepGeom::Transform3D m_solenoidFrame; + + }; + +} // end namespace + +#endif // INDETREADOUTGEOMETRY_TRT_CONDITIONS_H + diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_DetElementCollection.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_DetElementCollection.h new file mode 100755 index 0000000000000000000000000000000000000000..c85a8381727930d91b301807fc2b844e086dfeb4 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_DetElementCollection.h @@ -0,0 +1,28 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SiDetectorElementCollection.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + + +#ifndef INDETREADOUTGEOMETRY_TRT_DETELEMENTCOLLECTION_H +#define INDETREADOUTGEOMETRY_TRT_DETELEMENTCOLLECTION_H + +#include <vector> + +namespace InDetDD { + +class TRT_BaseElement; + +/// Class to hold collection of TRT detector elements. + +class TRT_DetElementCollection : public std::vector<const TRT_BaseElement *> +{}; + +} // namespace InDetDD + +#endif // INDETREADOUTGEOMETRY_TRT_DETELEMENTCOLLECTION_H diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_DetectorManager.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_DetectorManager.h new file mode 100755 index 0000000000000000000000000000000000000000..bb6df7eba3888905f478a5e7effa436e38bb3604 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_DetectorManager.h @@ -0,0 +1,265 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// TRT_DetectorManager.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef TRT_DetectorManager_h +#define TRT_DetectorManager_h 1 +#include "InDetReadoutGeometry/InDetDetectorManager.h" +#include "InDetReadoutGeometry/TRT_BarrelElement.h" +#include "InDetReadoutGeometry/TRT_EndcapElement.h" +#include "InDetReadoutGeometry/Version.h" +#include "InDetReadoutGeometry/TRT_DetElementCollection.h" +#include "GeoModelKernel/GeoVPhysVol.h" +#include "InDetIdentifier/TRT_ID.h" +#include "GeoModelKernel/GeoXF.h" +#include "AthenaKernel/IIOVSvc.h" + +#include "CLHEP/Geometry/Transform3D.h" + +#include "InDetReadoutGeometry/InDetDD_Defs.h" + +#include <vector> +#include <string> +#include <map> + +class Identifier; +class GeoAlignableTransform; +class StoreGateSvc; + +namespace InDetDD { + + class TRT_Numerology; + class ExtendedAlignableTransform; + + + + /** class TRT_DetectorManager + + The Detector Manager for all TRT Detector elements, + it acts as the interface to the detector elements which can be retrieved + from the TRT_DetectorManager either via numerology or Identifier access. + + In addition, the alignable transforms are set via Identifer and forwarded + to the GeoModel class; hence, we are sitting at the interface between + CLHEP and AMG. + + @author Grant Gorfine + modified & maintined: Nick Styles, Andreas Salzburger + + */ + + class TRT_DetectorManager : public InDetDetectorManager { + + public: + + // Constructor + TRT_DetectorManager(StoreGateSvc * detStore = 0); + + // Destructor + ~TRT_DetectorManager(); + + /** Access Raw Geometry:-------------------------------------------------------*/ + virtual unsigned int getNumTreeTops() const; // + virtual PVConstLink getTreeTop(unsigned int i) const; // + //-----------------------------------------------------------------------------// + + /** Get the ID helper: --------------------------------------------------------*/ + void setIdHelper(const TRT_ID * idHelper, bool owns=true); // + //-----------------------------------------------------------------------------// + + + //** Get and set information about gasType. -----------------------------------*/ + enum ActiveGasType { unknown, oldgas, newgas }; // + ActiveGasType gasType() const; // + void setGasType(const ActiveGasType &); // + //-----------------------------------------------------------------------------// + + /** Get and set information about digitization version ------------------------*/ + unsigned int digitizationVersion() const; // + std::string digitizationVersionName() const; // + void setDigitizationVersion(const unsigned int &, const std::string& name ); // + //-----------------------------------------------------------------------------// + + /** Access Numerological information:------------------------------------------*/ + TRT_Numerology *getNumerology(); // + const TRT_Numerology * getNumerology() const; // + //-----------------------------------------------------------------------------// + + + /** Access Elements Generically------------------------------------------------*/ + const TRT_BaseElement *getElement(Identifier id) const; // Slow // + const TRT_BaseElement *getElement(IdentifierHash id) const; // Fast // + //-----------------------------------------------------------------------------// + + + /** Access to Whole Collection of Elements -------------------------------------*/ + const TRT_DetElementCollection * getDetectorElementCollection() const; + TRT_DetElementCollection::const_iterator getDetectorElementBegin() const; + TRT_DetElementCollection::const_iterator getDetectorElementEnd() const; + + //-----------------------------------------------------------------------------// + + + /** Access Barrel Elements:------------------(Fast)----------------------------*/ + const TRT_BarrelElement *getBarrelElement(unsigned int positive, // + unsigned int moduleIndex, // + unsigned int phiIndex, // + unsigned int strawLayerIndex) const; // + TRT_BarrelElement *getBarrelElement(unsigned int positive, // + unsigned int moduleIndex, // + unsigned int phiIndex, // + unsigned int strawLayerIndex); // + // // + //-----------------------------------------------------------------------------// + + + /** Access Endcap Elements:------------------(Fast)-----------------------------*/ + const TRT_EndcapElement *getEndcapElement(unsigned int positive, // + unsigned int wheelIndex, // + unsigned int strawLayerIndex, // + unsigned int phiIndex) const; // + TRT_EndcapElement *getEndcapElement(unsigned int positive, // + unsigned int wheelIndex, // + unsigned int strawLayerIndex, // + unsigned int phiIndex); // + // // + //-----------------------------------------------------------------------------// + + /** Conditions interface (mostly for internal use):----------------------------*/ + void setConditions(TRT_Conditions * conditions); // + const TRT_Conditions * conditions() const; // + //-----------------------------------------------------------------------------// + + + // This is for Detector Descriptors -------------------------------------------// + void addTreeTop(PVLink); // + // // + // Manage the barrel elements: // + void manageBarrelElement(TRT_BarrelElement *barrel); // + // // + // Manage the endcap elements: // + void manageEndcapElement(TRT_EndcapElement *endcap); // + // // + //-----------------------------------------------------------------------------// + + //-----------------------------------------------------------------------------// + // // + // Transform of straw relative to module. Stored as a tranformation field // + // to make this compact. Note , GeoXF::Function * is a pointer to a so- // + // called "TRANSFUNCTION". Functions are delete when the manager is deleted. // + // // + void setBarrelTransformField(size_t i, const GeoXF::Function *field); // + const GeoXF::Function *barrelTransformField(size_t i) const; // + void setEndcapTransformField(size_t i, const GeoXF::Function *field); // + const GeoXF::Function *endcapTransformField(size_t i) const; // + // // + //-----------------------------------------------------------------------------// + + // Alignment stuff + // DEPRECATED - kept for compatibilty with Lisbon CondDB + void addKey(const std::string & key, int level); + // DEPRECATED use addChannel + void addKey(const std::string & key, int level, FrameType frame); + + + + /** Add alignable transforms: GeoModel/CLHEP based */ + void addAlignableTransform (int level, + const Identifier &id, + GeoAlignableTransform *transform, + const GeoVFullPhysVol * child = 0, + const GeoVFullPhysVol * frameVol = 0); + + /** Add alignable transforms: GeoModel/CLHEP based */ + void addAlignableTransform (int level, + const Identifier &id, + GeoAlignableTransform *transform, + const GeoVPhysVol * child = 0, + const GeoVPhysVol * frameVol = 0); + + /** Set alignable transforms: Amg based */ + virtual bool setAlignableTransformDelta(int level, + const Identifier & id, + const Amg::Transform3D & delta, + FrameType frame) const; + + /** Set alignable transforms: Amg based */ + bool setAlignableTransformAnyFrameDelta(ExtendedAlignableTransform * extXF, + const Amg::Transform3D & delta, + FrameType frame) const; + + + /** Invalidate cache for all detector elements */ + virtual void invalidateAll() const; + + /** Update all caches. */ + virtual void updateAll() const; + + + /** Check identifier is for this detector */ + virtual bool identifierBelongs(const Identifier & id) const; + + /** Call back for alignment updates, DEPRECATED. Now registered in tool. */ + StatusCode alignmentCallback( IOVSVC_CALLBACK_ARGS ); + + + private: + + + // Illegal operations:---------------------------------------------------------// + // // + const TRT_DetectorManager & operator=(const TRT_DetectorManager &right); // + TRT_DetectorManager(const TRT_DetectorManager &right); // + // // + //-----------------------------------------------------------------------------// + + + // Private member data:--------------------------------------------------------// + std::vector<PVLink> volume; // + // // + enum {NMODMAX=3}; // + enum {NWHEELMAX=18}; // + enum {NPHIMAX=32}; // + enum {NSTRAWLAYMAXBR=30}; // + enum {NSTRAWLAYMAXEC=16}; // + // // + TRT_BarrelElement *barrelArray[2][NMODMAX][NPHIMAX][NSTRAWLAYMAXBR]; // + TRT_EndcapElement *endcapArray[2][NWHEELMAX][NSTRAWLAYMAXEC][NPHIMAX]; // + TRT_DetElementCollection m_elements; // + // // + TRT_Numerology *_numerology; // + const TRT_ID *m_idHelper; // + bool _ownsIdHelper; // + const GeoXF::Function *_barrelXF[3]; // + const GeoXF::Function *_endcapXF[3]; // + // // + ActiveGasType m_gasType; // + unsigned int m_digvers; // + std::string m_digversname; // + + TRT_Conditions * m_conditions; + + // Alignment stuff + typedef std::map<Identifier, ExtendedAlignableTransform *> AlignableTransformMap; + std::vector< AlignableTransformMap > m_alignableTransforms; + + // here temporarily + virtual const TRT_ID *getIdHelper() const; // + virtual bool processSpecialAlignment(const std::string & key) const; + + //-----------------------------------------------------------------------------// + }; +} +#ifndef GAUDI_NEUTRAL +#include "CLIDSvc/CLASS_DEF.h" +CLASS_DEF(InDetDD::TRT_DetectorManager, 10907524, 1) +#endif +#endif + + diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_EndcapCode.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_EndcapCode.h new file mode 100755 index 0000000000000000000000000000000000000000..1572ca3b4f99f242335be864f81a419e673bf41f --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_EndcapCode.h @@ -0,0 +1,141 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SiDetectorElementCollection.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef TRT_EndcapCode_h +#define TRT_EndcapCode_h 1 + +#include <iostream> + +// Include the string class header +#include <string> + +namespace InDetDD { + + /** @class TRT_EndcapCode + + bit definitions to decode TRT straws in endcap + */ + + class TRT_EndcapCode + { + public: + + + TRT_EndcapCode(); + TRT_EndcapCode( unsigned int isPositive, + unsigned int wheelIndex, + unsigned int strawLayerIndex, + unsigned int phiIndex); + + TRT_EndcapCode( const TRT_EndcapCode & right ); + ~TRT_EndcapCode(); + + const TRT_EndcapCode & operator=( const TRT_EndcapCode & right ); + + bool operator < (const TRT_EndcapCode & right) const; + bool operator > (const TRT_EndcapCode & right) const; + bool operator== (const TRT_EndcapCode & right) const; + bool operator!= (const TRT_EndcapCode & right) const; + + unsigned int isPosZ() const; + unsigned int getWheelIndex() const; + unsigned int getStrawLayerIndex() const; + unsigned int getPhiIndex() const; + unsigned int getKey() const; + std::string getName() const; + + private: + + + // Define key as a bit string: + // bit 0 Z (negative=0 or positive=1) + // bit 1-2 Wheel Index (0-2) + // bit 3-7 StrawLayer Index + // bit 8-12 Phi position (0-31) + + unsigned short int _key; + + static const int Z_MASK; + static const int WHEEL_MASK; + static const int STRAWLAYER_MASK; + static const int PHIPOS_MASK; + + static const int Z_SHIFT; + static const int WHEEL_SHIFT; + static const int STRAWLAYER_SHIFT; + static const int PHIPOS_SHIFT; + + }; + + + + inline unsigned int TRT_EndcapCode::isPosZ() const { + unsigned int ret = _key; + return (ret >> Z_SHIFT) & Z_MASK; + } + + inline unsigned int TRT_EndcapCode::getWheelIndex() const{ + unsigned int ret = _key; + return (ret >> WHEEL_SHIFT) & WHEEL_MASK; + } + + + inline unsigned int TRT_EndcapCode::getStrawLayerIndex() const { + unsigned int ret = _key; + return (ret >> STRAWLAYER_SHIFT) & STRAWLAYER_MASK; + } + + inline unsigned int TRT_EndcapCode::getPhiIndex() const { + unsigned int ret = _key; + return (ret >> PHIPOS_SHIFT) & PHIPOS_MASK; + } + + inline unsigned int TRT_EndcapCode::getKey() const { + return _key; + } + + + inline bool TRT_EndcapCode::operator==(const TRT_EndcapCode &right) const + { + return (getKey() == right.getKey()); + } + + inline bool TRT_EndcapCode::operator!=(const TRT_EndcapCode &right) const + { + return (getKey() != right.getKey()); + } + + inline bool TRT_EndcapCode::operator<(const TRT_EndcapCode &right) const + { + return (getKey() < right.getKey()); + } + + inline bool TRT_EndcapCode::operator>(const TRT_EndcapCode &right) const + { + return (getKey() > right.getKey()); + } +} // End InDetDD namespace + + +inline std::ostream & operator << (std::ostream & os, const InDetDD::TRT_EndcapCode & code) { + // Plus/minus + if (code.isPosZ()) os << '+'; + else os << '-'; + // Wheel + unsigned int wheel = code.getWheelIndex(); + os << wheel << "/"; + // StrawLayer: + os << code.getStrawLayerIndex()<< "/"; + // Phi + os << code.getPhiIndex(); + return os; +} + +#endif diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_EndcapDescriptor.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_EndcapDescriptor.h new file mode 100755 index 0000000000000000000000000000000000000000..10c5ccf1a514cc1935e61f75a39818b1975f75c6 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_EndcapDescriptor.h @@ -0,0 +1,124 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SiDetectorElementCollection.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef TRT_EndcapDescriptor_h +#define TRT_EndcapDescriptor_h 1 +#include "GeoModelKernel/RCBase.h" +#include "GeoModelKernel/GeoXF.h" + +namespace Trk{ + class CylinderBounds; + class SurfaceBounds; +} + +namespace InDetDD { + + /** class TRT_EndcapDescriptor + + Helper class to access GeoModel infromation and calculation for straws + */ + + class TRT_EndcapDescriptor : public RCBase + + { + + public: + + /** Constructor */ + TRT_EndcapDescriptor(); + + /** Sets the transform field for straws and offset. We do not own the function: */ + void setStrawTransformField(const GeoXF::Function *xf, size_t offsetInto); + + /** The number of straws in a module: */ + unsigned int &nStraws(); + inline const unsigned int &nStraws() const; + + /** The straw pitch (angular!!) */ + double &strawPitch(); + inline const double &strawPitch() const; + + /** The starting phi (angular!!) */ + double &startPhi(); + inline const double &startPhi() const; + + //** The straw length: */ + double &strawLength(); + inline const double &strawLength() const; + + /** The inner radius: */ + double &innerRadius(); + inline const double &innerRadius() const; + + /** Get inner tube radius of the straw */ + inline double innerTubeRadius() const; + + /** Get the tranformation field, which we do not own: */ + inline const GeoXF::Function *getStrawTransform() const; + + /** Get the offset into the transformation field: */ + inline size_t getStrawTransformOffset() const; + + /** Get Bounds */ + const Trk::SurfaceBounds & strawBounds() const; + + protected: + + + virtual ~TRT_EndcapDescriptor(); + + + private: + + // Illegal to copy: + TRT_EndcapDescriptor(const TRT_EndcapDescriptor &right); + + + // Illegal to assign: + const TRT_EndcapDescriptor & operator=(const TRT_EndcapDescriptor &right); + + + // Number of straws in the module. + unsigned int _nStraws; + + // (Angular) straw pitch + double _strawPitch; + + // Starting phi: + double _startPhi; + + // Straw length: + double _strawLength; + + // Inner radius of straw: + double _innerRadius; + + // Inner tube radius of straw. + double m_innerTubeRadius; + + // The straw transformation field: + const GeoXF::Function *_f; + + // And offset: + size_t _o; + + // Bounds + mutable Trk::CylinderBounds * m_bounds; + + + }; +} + + +#include "TRT_EndcapDescriptor.icc" + + + +#endif diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_EndcapDescriptor.icc b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_EndcapDescriptor.icc new file mode 100755 index 0000000000000000000000000000000000000000..77d6879732090dde08e8ff84c91e38f9b968ffb4 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_EndcapDescriptor.icc @@ -0,0 +1,45 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +namespace InDetDD { + +// The number of straws in a module: +inline const unsigned int &TRT_EndcapDescriptor::nStraws() const { + return _nStraws; +} + +inline const double &TRT_EndcapDescriptor::strawPitch() const { + return _strawPitch; +} + +inline const double &TRT_EndcapDescriptor::startPhi() const { + return _startPhi; +} + + +inline const double &TRT_EndcapDescriptor::strawLength() const { + return _strawLength; +} + +inline double TRT_EndcapDescriptor::innerTubeRadius() const +{ + return m_innerTubeRadius; +} + +inline const double &TRT_EndcapDescriptor::innerRadius() const { + return _innerRadius; +} + +inline const GeoXF::Function * TRT_EndcapDescriptor::getStrawTransform() const { + return _f; +} + +inline size_t TRT_EndcapDescriptor::getStrawTransformOffset() const { + return _o; +} + + + +} + diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_EndcapElement.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_EndcapElement.h new file mode 100755 index 0000000000000000000000000000000000000000..f647e81bb47e97ce2855bfa752eafaf342fc0e32 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_EndcapElement.h @@ -0,0 +1,138 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// TRT_EndcapElement.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef TRT_EndcapElement_h +#define TRT_EndcapElement_h 1 +#include "InDetReadoutGeometry/TRT_EndcapCode.h" +#include "InDetReadoutGeometry/TRT_BaseElement.h" +#include "InDetReadoutGeometry/TRT_EndcapDescriptor.h" + +class TRT_ID; + +namespace Trk{ + class SurfaceBounds; +} + +namespace InDetDD { + + class TRT_EndcapConditions; + + /** @class TRT_EndcapElement + + Extended class of a TRT_BaseElement to describe a readout elment in the endcap. + It secifies the strawTransfrom methods by getting the information from GeoModel + + The readout element in the EC is a wheel with straws radially placed on it. + + The number of straws described by this readout element can be + retrieved by nStraws() + + @author: Grant Gorfine + - modified & maintained: Nick Styles, Andreas Salzburger + + */ + + + class TRT_EndcapElement : public TRT_BaseElement { + + public: + /** Constructor */ + TRT_EndcapElement(const GeoVFullPhysVol *volume, + const TRT_EndcapDescriptor *descriptor, + bool isPositive, + unsigned int wheelIndex, + unsigned int strawLayIndex, + unsigned int phiIndex, + const TRT_ID * idHelper, + const TRT_Conditions * conditions); + + /** Destructor: */ + virtual ~TRT_EndcapElement(); + + /** Type information: */ + virtual TRT_BaseElement::Type type() const {return TRT_BaseElement::ENDCAP;} + + /** Default Local -> global transform of the straw (ie before alignment corrections) */ + virtual HepGeom::Transform3D defStrawTransform(int straw) const; + + /** Number of straws in the element */ + virtual unsigned int nStraws() const; + + /** Active straw length */ + virtual const double & strawLength() const; + + /** StrawDirection. +1 if axis is in same direction as local coordinate, -1 otherwise. */ + virtual int strawDirection() const; + + /** Returns a pointer to conditions data. This includes + information on dead and noisy wires, as well as wire + sags. */ + const TRT_EndcapConditions * getConditionsData() const; + + /** Returns a pointer to a descriptor, giving common + information on module construction */ + const TRT_EndcapDescriptor * getDescriptor() const; + + /** Next in Z: */ + const TRT_EndcapElement * nextInZ() const; + + /** Prev in Z: */ + const TRT_EndcapElement * previousInZ() const; + + /** Set Next in Z */ + void setNextInZ(const TRT_EndcapElement *element); + + /** Set Previous in Z */ + void setPreviousInZ(const TRT_EndcapElement *element); + + /** Doomed (??) */ + const TRT_EndcapCode & getCode() const; + + // Surface bounds + virtual const Trk::SurfaceBounds & strawBounds() const; + + + protected: + /** These transforms are effectively to the local coord + system of a straw derived from GeoModel -> hence CLHEP */ + HepGeom::Transform3D calculateStrawTransform(int straw) const; + HepGeom::Transform3D calculateLocalStrawTransform(int straw) const; + + /** return the surface of the element */ + const Trk::Surface & elementSurface() const; + + /** create the cache for the element */ + void createSurfaceCache() const; + + /** create the cache for the straw of identifier id */ + void createSurfaceCache(Identifier id) const; + + private: + + // Illegal Operations: + TRT_EndcapElement(const TRT_EndcapElement &right); + const TRT_EndcapElement & operator=(const TRT_EndcapElement &right); + + // Private Member Data: + TRT_EndcapCode _code; + const TRT_EndcapDescriptor *_descriptor; + const TRT_EndcapElement *_nextInZ; + const TRT_EndcapElement *_previousInZ; + + mutable Trk::Surface * m_surface; + + }; + +} + +#include "TRT_EndcapElement.icc" +#endif + + diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_EndcapElement.icc b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_EndcapElement.icc new file mode 100755 index 0000000000000000000000000000000000000000..d94b0eebb694b2da0298ee6a1aab06b29dc5cd81 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_EndcapElement.icc @@ -0,0 +1,20 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +namespace InDetDD { + inline const TRT_EndcapElement * TRT_EndcapElement::nextInZ() const + { + return _nextInZ; + } + + inline const TRT_EndcapElement * TRT_EndcapElement::previousInZ() const + { + return _previousInZ; + } + + inline const TRT_EndcapCode & TRT_EndcapElement::getCode() const + { + return _code; + } +} diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_Numerology.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_Numerology.h new file mode 100755 index 0000000000000000000000000000000000000000..39d5b9cb5cbf1b2cbdbaf495b7f4e8e958430699 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_Numerology.h @@ -0,0 +1,62 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// TRT_Numerology.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef _TRTNUMEROLOGY_H_ +#define _TRTNUMEROLOGY_H_ + +namespace InDetDD { + + /** @class TRT_Numerology + + Helper class to organize the straw elements on + TRT readout elements. + + */ + class TRT_Numerology { + + public: + + // Constructor: + TRT_Numerology(); + + // Destructor: + ~TRT_Numerology(); + + // Modifiers: + void setNBarrelLayers(unsigned int module, unsigned int nLayers); + void setNEndcapLayers(unsigned int wheel, unsigned int nLayers); + + void setNBarrelRings (unsigned int ring ); + void setNBarrelPhi (unsigned int phi ); + void setNEndcapWheels(unsigned int wheel); + void setNEndcapPhi (unsigned int phi ); + + // Accessors: + inline unsigned int getNBarrelLayers(unsigned int iMod ) const; + inline unsigned int getNEndcapLayers(unsigned int iWheel) const; + + inline unsigned int getNBarrelRings () const; + inline unsigned int getNBarrelPhi () const; + inline unsigned int getNEndcapWheels() const; + inline unsigned int getNEndcapPhi () const; + + private: + + unsigned int _nlayerBarrel[3]; + unsigned int _nlayerEndcap[18]; + + unsigned int _nringBarrel; + unsigned int _nphiBarrel; + unsigned int _nwheelEndcap; + unsigned int _nphiEndcap; + }; +} +#include "TRT_Numerology.icc" +#endif diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_Numerology.icc b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_Numerology.icc new file mode 100755 index 0000000000000000000000000000000000000000..877ddaa504a9ab4586008aa91e00ab778eebdbd5 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/TRT_Numerology.icc @@ -0,0 +1,30 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +namespace InDetDD { +inline unsigned int TRT_Numerology::getNBarrelLayers (unsigned int iMod) const { + return _nlayerBarrel[iMod]; +} + + +inline unsigned int TRT_Numerology::getNEndcapLayers (unsigned int iWheel) const { + return _nlayerEndcap[iWheel]; +} + +inline unsigned int TRT_Numerology::getNBarrelRings() const { + return _nringBarrel; +} + +inline unsigned int TRT_Numerology::getNBarrelPhi() const { + return _nphiBarrel; +} + +inline unsigned int TRT_Numerology::getNEndcapWheels() const { + return _nwheelEndcap; +} + +inline unsigned int TRT_Numerology::getNEndcapPhi() const { + return _nphiEndcap; +} +} diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/Version.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/Version.h new file mode 100755 index 0000000000000000000000000000000000000000..1493133da4bbaa9ec07ef34b4494c1bce7b4c209 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/InDetReadoutGeometry/Version.h @@ -0,0 +1,91 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//////////////////////////////////////////////////////////// +// Version.h +//////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +//////////////////////////////////////////////////////////// + +#ifndef INDETREADOUTGEOMETRY_VERSION +#define INDETREADOUTGEOMETRY_VERSION + +#include <string> + +namespace InDetDD { + + /** @class Version + + Class to hold version information consisting of tag, name layout and description as strings, + such as their integer regpresentation in the major-minor-tag scheme + */ + + class Version { + + public: + + /** Constructor. */ + Version(const std::string & tag, + const std::string & name, + const std::string & layout, + const std::string & description, + int major, + int minor, + int patch); + + /** Constructor. DEPRECATED */ + Version(const std::string & name, + const std::string & layout, + const std::string & description, + int major, + int minor, + int patch); + + /** Empty Constructor */ + Version(); + + /** Version tag */ + const std::string & tag() const; + + /** Version label */ + const std::string & name() const; + + /** Layout (eg Initial, Final, TestBeam) */ + const std::string & layout() const; + + /** Description or comment. */ + const std::string & description() const; + + /** Major version number */ + int majorNum() const; + + /** Minor version number */ + int minorNum() const; + + /** Patch version number */ + int patchNum() const; + + /** Print out version number (eg. 2.00.00) */ + std::string versionNumber() const; + + /** Full Description + For example, + Version: SCT-DC1-00, Name: DC1, Layout: Final, Code Version: 2.00.00, Description: DC1 Geometry */ + std::string fullDescription() const; + + + private: + + std::string m_tag; + std::string m_name; + std::string m_layout; + std::string m_description; + int m_major; + int m_minor; + int m_patch; + }; + +} // namespace InDetDD + +#endif // INDETREADOUTGEOMETRY_VERSION diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/README b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/README new file mode 100755 index 0000000000000000000000000000000000000000..89969ca86c7aa930dcb9f03c0c2b925173969964 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/README @@ -0,0 +1,10 @@ +Package: offline/InnerDetector/InDetDetDescr/InDetReadoutGeometry + +Responsible: Grant Gorfine <Grant.Gorfine@nikhef.nl> + +Description: Detector description managers and readout elements for Pixel + SCT and TRT. + +Dependencies: Identifier, InDetIdentifier, GeoModelKernel, IdDictDetDescr, StoreGate + +Last modified: October 1, 2003 by Grant Gorfine diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/cmt/requirements b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/cmt/requirements new file mode 100755 index 0000000000000000000000000000000000000000..27f823090cae11d5f03a40342a5ef0d26ba7f93b --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/cmt/requirements @@ -0,0 +1,35 @@ +package InDetReadoutGeometry + +manager Grant Gorfine <Grant.Gorfine> + +private + +use DetDescrConditions DetDescrConditions-* DetectorDescription/DetDescrCond +use IdDictDetDescr IdDictDetDescr-* DetectorDescription +use TRT_ConditionsData TRT_ConditionsData-* InnerDetector/InDetConditions +use StoreGate StoreGate-* Control + +public + +use AtlasPolicy AtlasPolicy-* +use AtlasCLHEP AtlasCLHEP-* External +use GaudiInterface GaudiInterface-* External +use AthenaKernel AthenaKernel-* Control +use CLIDSvc CLIDSvc-* Control +use Identifier Identifier-* DetectorDescription +use AtlasDetDescr AtlasDetDescr-* DetectorDescription +use GeoModelKernel GeoModelKernel-* DetectorDescription/GeoModel +use InDetIdentifier InDetIdentifier-* InnerDetector/InDetDetDescr +use InDetCondServices InDetCondServices-* InnerDetector/InDetConditions +use TrkDetElementBase TrkDetElementBase-* Tracking/TrkDetDescr +use TrkSurfaces TrkSurfaces-* Tracking/TrkDetDescr +use TrkEventPrimitives TrkEventPrimitives-* Tracking/TrkEvent +use GeoPrimitives GeoPrimitives-* DetectorDescription + +apply_pattern default_installed_library + +private +macro DOXYGEN_IMAGE_PATH "../doc/images" + + + diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/doc/images/pixeldiodematrix.gif b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/doc/images/pixeldiodematrix.gif new file mode 100644 index 0000000000000000000000000000000000000000..4beda4026c20db8c7f1eb22931a132d2bfbf844d Binary files /dev/null and b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/doc/images/pixeldiodematrix.gif differ diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/doc/mainpage.h b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/doc/mainpage.h new file mode 100755 index 0000000000000000000000000000000000000000..170f513437a985bc4a134ff2040203c59de1612f --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/doc/mainpage.h @@ -0,0 +1,73 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + +@mainpage InDetReadoutGeometry Package + +@authors Grant Gorfine, Joe Boudreau, Thomas Kittlemann, + Davide Costanzo, David Calvet, Alessandro Fornaini + +@section InDetReadoutGeometryIntro Introduction + +This package contains the readout classes for +the inner detector. These are mainly used by digitization and +reconstruction. + + +- Managers: + The Detector managers contain methods to access the Identifier helpers and detector elements. + + +- Detector Elements: +The detector element is the object where geometrical information of the readout elements is obtained: + - Pixel: The silicon sensor in a pixel module. + - SCT: One side of the module. (One or two silicon wafers wire bonded together) + - TRT: A straw layer (contains several straws). + +- Design and Descriptor Classes: +As well as the detector element there are design and descriptor classes which contain information common to several elements. + + +@section InDetReadoutGeometryClassOverview Class Overview + +Described here are just the classes that clients will +normally use. + +- Managers: + - InDetDD::SiDetectorManager: Base class for Pixel and SCT managers. + - InDetDD::PixelDetectorManager: The Pixel detector manager. + - InDetDD::SCT_DetectorManager: The SCT detector manager. + - InDetDD::TRT_DetectorManager: The TRT detector manager. + +- Detector Elements, Design and Descriptor Classes: + - InDetDD::SiDetectorElement: Pixel and SCT share a common detector element class. This class contains most of the methods needed by reconstruction clients. + - InDetDD::SiDetectorDesign: Base class for design. + - InDetDD::PixelModuleDesign: + - InDetDD::SCT_ModuleSideDesign: + - InDetDD::SCT_BarrelModuleSideDesign: + - InDetDD::SCT_ForwardModuleSideDesign: + - InDetDD::TRT_BaseElement: + - InDetDD::TRT_BarrelElement: + - InDetDD::TRT_EndcapElement: + - InDetDD::TRT_BarrelDescriptor: + - InDetDD::TRT_EndcapDescriptor: + + +- Other: + - InDetDD::SiCellId: Strip number for SCT or phi_index, eta_index for pixel. + - InDetDD::Version: Version information + - InDetDD::TRT_Numerology: TRT numerology + - InDetDD::SiNumerology: Pixel and SCT numerology + +@section InDetReadoutGeometryUsage Usage Notes +The managers are retrieved from storegate. Their names are Pixel, SCT and TRT. +From the manager, one can get the id helpers and access the detector elements using various methods. + +@section InDetReadoutGeometryReq Requirements + + +@include requirements + +*/ diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/doc/pixeldiodematrix.fig b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/doc/pixeldiodematrix.fig new file mode 100644 index 0000000000000000000000000000000000000000..7d59c0f42b235875e8830eff8604883373cbdc10 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/doc/pixeldiodematrix.fig @@ -0,0 +1,104 @@ +#FIG 3.2 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 2475 450 2475 5130 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 2565 450 2565 5130 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 2385 450 2385 5130 +2 2 0 2 0 7 50 -1 -1 0.000 0 0 7 0 0 5 + 630 450 2655 450 2655 5130 630 5130 630 450 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 810 450 810 5130 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 900 450 900 5130 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 720 450 720 5130 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3420 1125 3510 1125 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3420 1800 3510 1800 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3420 2475 3510 2475 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3420 3150 3510 3150 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3420 3825 3510 3825 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3420 4500 3510 4500 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3420 5175 3510 5175 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 4545 5625 4680 5625 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 4545 5175 4680 5175 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 4545 4725 4680 4725 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 4545 1125 4680 1125 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 4545 1575 4680 1575 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 4545 2025 4680 2025 +2 1 1 1 0 7 50 -1 -1 4.000 0 0 7 0 0 2 + 2700 495 3375 450 +2 1 1 1 0 7 50 -1 -1 4.000 0 0 7 0 0 2 + 3555 495 4500 450 +2 1 1 1 0 7 50 -1 -1 4.000 0 0 7 0 0 2 + 3555 1080 4455 6300 +2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 5940 1035 4725 765 +2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 5895 2745 4725 1350 +2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 5850 2700 4770 1800 +2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 5895 1080 4725 5985 +2 1 1 1 0 11 50 -1 20 4.000 0 0 7 0 0 2 + 2700 5085 3375 5850 +2 2 0 1 0 23 50 -1 20 0.000 0 0 -1 0 0 5 + 4545 1125 4680 1125 4680 1575 4545 1575 4545 1125 +2 2 0 1 0 23 50 -1 20 0.000 0 0 -1 0 0 5 + 4545 1575 4680 1575 4680 2025 4545 2025 4545 1575 +2 2 0 1 0 23 50 -1 20 0.000 0 0 -1 0 0 5 + 4545 4725 4680 4725 4680 5175 4545 5175 4545 4725 +2 2 0 1 0 23 50 -1 20 0.000 0 0 -1 0 0 5 + 4545 5175 4680 5175 4680 5625 4545 5625 4545 5175 +2 2 0 1 0 12 50 -1 20 0.000 0 0 -1 0 0 5 + 4545 450 4680 450 4680 1125 4545 1125 4545 450 +2 2 0 1 0 12 50 -1 20 0.000 0 0 -1 0 0 5 + 4545 5625 4680 5625 4680 6300 4545 6300 4545 5625 +2 2 0 2 11 7 48 -1 -1 0.000 0 0 7 0 0 5 + 4545 450 4680 450 4680 6300 4545 6300 4545 450 +2 2 0 2 4 11 52 -1 20 0.000 0 0 7 0 0 5 + 3420 450 3510 450 3510 5850 3420 5850 3420 450 +2 2 0 2 0 12 50 -1 20 0.000 0 0 7 0 0 5 + 5985 450 6075 450 6075 1755 5985 1755 5985 450 +2 2 0 2 0 23 50 -1 20 0.000 0 0 7 0 0 5 + 5985 2295 6075 2295 6075 3150 5985 3150 5985 2295 +2 2 0 1 0 30 52 -1 20 0.000 0 0 -1 0 0 5 + 2385 450 2655 450 2655 5130 2385 5130 2385 450 +2 2 0 1 0 30 52 -1 20 0.000 0 0 -1 0 0 5 + 630 450 900 450 900 5130 630 5130 630 450 +4 0 0 50 -1 0 42 0.0000 4 60 360 1440 2295 ...\001 +4 0 0 50 -1 16 12 0.0000 4 135 750 1260 180 fullMatrix\001 +4 0 0 50 -1 16 12 0.0000 4 180 1245 4410 225 singleChipRow\001 +4 0 0 50 -1 16 12 0.0000 4 180 855 3150 225 singleRow\001 +4 0 0 50 -1 0 42 1.5708 4 60 360 4635 3555 ...\001 +4 0 0 50 -1 16 12 0.0000 4 135 195 3600 900 x8\001 +4 0 0 50 -1 16 12 0.0000 4 135 405 2745 2250 x328\001 +4 0 0 50 -1 16 12 0.0000 4 135 300 4815 2340 x16\001 +4 0 0 50 -1 16 16 0.0000 4 180 1305 5580 5310 Not to scale\001 +4 0 0 50 -1 16 12 0.0000 4 180 585 6210 1080 bigCell\001 +4 0 0 50 -1 16 12 0.0000 4 135 885 6165 2700 normalCell\001 diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/InDetDetectorManager.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/InDetDetectorManager.cxx new file mode 100755 index 0000000000000000000000000000000000000000..cd74b3ebd1e121957f6eaafdd71c2fb206a7e7b6 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/InDetDetectorManager.cxx @@ -0,0 +1,279 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + + +#include "InDetReadoutGeometry/InDetDetectorManager.h" + +#include "StoreGate/StoreGateSvc.h" +#include "DetDescrConditions/AlignableTransformContainer.h" +#include "DetDescrConditions/AlignableTransform.h" +#include "AtlasDetDescr/AtlasDetectorID.h" +#include "GeoPrimitives/CLHEPtoEigenConverter.h" + +namespace InDetDD +{ + + InDetDetectorManager::InDetDetectorManager(StoreGateSvc * detStore, const std::string & name) + : m_detStore(detStore), + m_msg(name+"DetectorManager"), + m_suppressWarnings(false) + { + setName(name); + } + + // Destructor + InDetDetectorManager::~InDetDetectorManager() + {} + + + const Version& InDetDetectorManager::getVersion() const + { + return m_version; + } + + const std::string& InDetDetectorManager::getLayout() const + { + return m_version.layout(); + } + + void InDetDetectorManager::setVersion(const Version & version) + { + m_version = version; + + // Since default alignments are for final layout, Pixel Rome-Initial + // layout will result in several (harmless) WARNING message. We suppress these. + // Also the SR1 layout produce warnings due to missing parts. We suppress these also. + m_suppressWarnings = ( (getName() == "Pixel" && + (version.tag() == "Pixel-01" || version.tag() == "Pixel-DC2-Initial-00")) + || version.layout() == "SR1" || version.layout() == "SR1-EndcapC"); + + } + + void InDetDetectorManager::addChannel(const std::string & key, int level, FrameType frame) + { + if (msgLvl(MSG::DEBUG)) { + std::string frameStr = "other"; + if (frame == InDetDD::global) frameStr = "global"; + if (frame == InDetDD::local) frameStr = "local"; + msg(MSG::DEBUG) << "Registering alignment channel with key " << key << ", level " << level + << ", with frame " << frameStr << "." <<endreq; + } + m_keys[key] = LevelInfo(level, frame); + } + + void InDetDetectorManager::addFolder(const std::string & key) + { + m_folders.insert(key); + } + + void InDetDetectorManager::addSpecialFolder(const std::string & key) + { + m_specialFolders.insert(key); + } + + + // Return the level in the hierarchy (user defined) corresponding to the key. + const InDetDetectorManager::LevelInfo& InDetDetectorManager::getLevel(const std::string & key) const + { + static LevelInfo invalidLevel; + std::map<std::string, LevelInfo>::const_iterator iter; + iter = m_keys.find(key); + if (iter == m_keys.end()) return invalidLevel; + return iter->second; + } + + + StatusCode InDetDetectorManager::align( IOVSVC_CALLBACK_ARGS_P(I,keys) ) const + { + (void) I; // avoid warning about unused parameter + + if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << "AlignmentCallback called " << endreq; + + if (!getIdHelper()) return StatusCode::SUCCESS; + + bool alignmentChange = false; + + // If dummy arguments + if (keys.empty()) { + + // Regular alignments. Loop through folder keys. Normally only one. + for (std::set<std::string>::const_iterator iterFolders = m_folders.begin(); + iterFolders != m_folders.end(); + ++iterFolders) { + try { + bool status = processAlignmentContainer(*iterFolders); + alignmentChange = (alignmentChange || status); + } + catch(std::runtime_error& err) { + // alignments should always exist so we return fatal if we could not process the alignment for this key + msg(MSG::FATAL) << err.what() << endreq; + return StatusCode::FAILURE; + } + } + // Detector specific aligments + for (std::set<std::string>::const_iterator iterFolders = m_specialFolders.begin(); + iterFolders != m_specialFolders.end(); + ++iterFolders) { + try { + bool status = processSpecialAlignment(*iterFolders); + alignmentChange = (alignmentChange || status); + } catch(std::runtime_error& err) { + // keys are empty when running simualtion. It is normal for detector specific aligments not to exist. + if (msgLvl(MSG::INFO)) msg(MSG::INFO) << err.what() << endreq; + // We continue as detector specific aligments don't always exist. + } + } + + } else { + // Loop over all the keys. + for (std::list<std::string>::const_iterator itr=keys.begin(); itr!=keys.end(); ++itr) { + + const std::string & key = *itr; + + if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << " Processing call back key " << key << endreq; + + if ( m_folders.find(key) != m_folders.end() ) { + + try { + // Regular alignemnts + bool status = processAlignmentContainer(key); + alignmentChange = (alignmentChange || status); + } catch(std::runtime_error& err) { + // alignments should always exist so we return fatal if we could not process the alignment for this key + msg(MSG::FATAL) << err.what() << endreq; + return StatusCode::FAILURE; + } + + } else if ( m_specialFolders.find(key) != m_specialFolders.end() ) { + try { + // Detector specific alignments + bool status = processSpecialAlignment(key); + alignmentChange = (alignmentChange || status); + } + catch(std::runtime_error& err) { + // Should always exist if the folder was requested so we return fatal if we could not process the alignment for this key + msg(MSG::FATAL) << err.what() << endreq; + return StatusCode::FAILURE; + } + } else { + // Should not be any other keys specified in call back. + msg(MSG::ERROR) << "Unrecognized key in call back." << endreq; + return StatusCode::SUCCESS; + } + } + } + + // We invalidate all the elements if at least one alignment changed. + if (alignmentChange) { + invalidateAll(); + } + + return StatusCode::SUCCESS; + } + + + + bool InDetDetectorManager::processAlignmentContainer(const std::string & key) const + { + bool alignmentChange = false; + + if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << "Dealing with key as container" << endreq; + const AlignableTransformContainer* container; + if (StatusCode::SUCCESS!=m_detStore->retrieve(container, key)) { + msg(MSG::ERROR) << "Cannot find AlignableTransformContainer for key " + << key << " - no misalignment" << endreq; + // This should not occur in normal situations so we force job to abort. + throw std::runtime_error("Unable to apply Inner Detector alignments"); + } + // Check if container is empty - this can occur if it is an invalid IOV. + if (container->empty()) { + msg(MSG::ERROR) << "AlignableTransformContainer for key " + << key << " is empty. Probably due to out of range IOV" << endreq; + // This should not occur in normal situations so we force job to abort. + throw std::runtime_error("Unable to apply Inner Detector alignments."); + } + // loop over all the AlignableTransform objects in the collection + for (DataVector<AlignableTransform>::const_iterator pat=container->begin(); + pat!=container->end();++pat) { + bool status = processKey((*pat)->tag(),*pat); + alignmentChange = (alignmentChange || status); + } + return alignmentChange; + } + + bool InDetDetectorManager::processKey(const std::string key, const AlignableTransform* transformCollection) const + { + bool alignmentChange = false; + + // From the key determine what level in hierarchy we are dealing with. + // returns -1 if unrecognized. + const LevelInfo & levelInfo = getLevel(key); + if (msgLvl(MSG::DEBUG)) { + if (levelInfo.isValid()) { + if (msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << "Processing channel: " << key << endreq; + } else { + msg(MSG::DEBUG) << "Channel " << key << " not registered in this manager" << endreq; + } + } + // return silently if unrecognised - this can happen in container mode + // when a single container holds transforms for both pixel and SCT + if (!levelInfo.isValid() ) return false; + + + //Loop over the effected nodes. + for (AlignableTransform::AlignTransMem_citr trans_iter = transformCollection->begin(); + trans_iter != transformCollection->end(); + ++trans_iter) { + if (msgLvl(MSG::VERBOSE)) { + msg(MSG::VERBOSE) << "Get alignment for identifier " + << getIdHelper()->show_to_string(trans_iter->identify()) + << " at level " << levelInfo.level() << endreq; + } + // The delta in the conditions DB is not necessarily the same as what is needed in the + // alignable transform. At the moment we support global frame, local frame or an alternative frame + // The setAlignableTransformDelta method takes care of this correction - this is CLHEP <--> Amg interfaced + bool status = setAlignableTransformDelta(levelInfo.level(), + trans_iter->identify(), + Amg::CLHEPTransformToEigen(trans_iter->transform()), + levelInfo.frame()); + + alignmentChange = (alignmentChange || status); + + if (!status) { + if (!identifierBelongs(trans_iter->identify())) { + // Its probably OK. Eg /Indet/Align/ID contains alse pixel and sct ids. + if (msgLvl(MSG::DEBUG)) { + msg(MSG::DEBUG) << "Cannot set AlignableTransform for identifier." + << " Probably OK if its /Indet/Align/ID folder. " + << getIdHelper()->show_to_string(trans_iter->identify()) + << " at level " << levelInfo.level() << endreq; + } + } else { + if (m_suppressWarnings) { + if (msgLvl(MSG::DEBUG)) { + msg(MSG::DEBUG) << "WARNING: Cannot set AlignableTransform for identifier " + << getIdHelper()->show_to_string(trans_iter->identify()) + << " at level " << levelInfo.level() << endreq; + } + } else { + msg(MSG::WARNING) << "Cannot set AlignableTransform for identifier " + << getIdHelper()->show_to_string(trans_iter->identify()) + << " at level " << levelInfo.level() << endreq; + msg(MSG::WARNING) << "Subsequent WARNINGS will be printed at DEBUG level." << endreq; + m_suppressWarnings = true; + } + } + } + } + return alignmentChange; + } + + // We provide a default implementation of any detector specific alignment. + bool InDetDetectorManager::processSpecialAlignment(const std::string &) const + { + return false; + } + + +} // namespace InDetDD diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/PixelDetectorManager.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/PixelDetectorManager.cxx new file mode 100755 index 0000000000000000000000000000000000000000..941dcef681b0d2a24a4050a65a9594a1b37d501a --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/PixelDetectorManager.cxx @@ -0,0 +1,306 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + + +#include "InDetReadoutGeometry/PixelDetectorManager.h" +#include "InDetIdentifier/PixelID.h" +#include "Identifier/Identifier.h" +#include "Identifier/IdentifierHash.h" +#include "InDetReadoutGeometry/SiDetectorElementCollection.h" +#include "InDetReadoutGeometry/SiDetectorElement.h" +#include "InDetReadoutGeometry/ExtendedAlignableTransform.h" +#include "InDetReadoutGeometry/PixelModuleDesign.h" +#include "StoreGate/StoreGateSvc.h" + +namespace InDetDD { + + const int FIRST_HIGHER_LEVEL = 1; + + + PixelDetectorManager::PixelDetectorManager(StoreGateSvc* detStore) + : SiDetectorManager(detStore, "Pixel"), + m_idHelper(0) + { + + // + // Initialized the Identifier helper. + // + + StatusCode sc = detStore->retrieve(m_idHelper,"PixelID"); + if (sc.isFailure() ) { + msg(MSG::ERROR) << "Could not retrieve Pixel id helper" << endreq; + } + + // Initialize the collections. + if (m_idHelper) { + m_elementCollection.resize(m_idHelper->wafer_hash_max()); + m_alignableTransforms.resize(m_idHelper->wafer_hash_max()); + } + } + + + PixelDetectorManager::~PixelDetectorManager() + { + // Clean up + SiDetectorElementCollection::iterator iter; + for (iter = m_elementCollection.begin(); iter != m_elementCollection.end(); ++iter){ + delete *iter; + } + + for (size_t i=0; i < m_volume.size(); i++) { + m_volume[i]->unref(); + } + + for (size_t j=0; j < m_higherAlignableTransforms.size(); j++){ + AlignableTransformMap::iterator iterMap; + for (iterMap = m_higherAlignableTransforms[j].begin(); + iterMap != m_higherAlignableTransforms[j].end(); + ++iterMap) { + delete iterMap->second; + } + } + + for (size_t k=0; k < m_alignableTransforms.size(); k++){ + delete m_alignableTransforms[k]; + } + } + + + + unsigned int PixelDetectorManager::getNumTreeTops() const + { + return m_volume.size(); + } + + PVConstLink PixelDetectorManager::getTreeTop(unsigned int i) const + { + return m_volume[i]; + } + + void PixelDetectorManager::addTreeTop(PVLink vol){ + vol->ref(); + m_volume.push_back(vol); + } + + + SiDetectorElement* PixelDetectorManager::getDetectorElement(const Identifier & id) const + { + // NB the id helpers implementation for getting a hash is not optimal. + // Essentially does a binary search. + // Make sure it is a wafer Id + Identifier waferId = id; +#ifndef __IDENTIFIER_64BIT__ + // pixel ids have special treatement. It is possible to distinguish between + // a wafer id and a pixel cell id by checking bit 32, which is set for a pixel cell id. + if (id.is_valid() && (id.get_compact() & 0x80000000)) { + waferId = m_idHelper->wafer_id(id); + } +#else + waferId = m_idHelper->wafer_id(id); +#endif /* __IDENTIFIER_64BIT__ */ + IdentifierHash idHash = m_idHelper->wafer_hash(waferId); + if (idHash.is_valid()) { + return m_elementCollection[idHash]; + } else { + return 0; + } + } + + + SiDetectorElement* PixelDetectorManager::getDetectorElement(const IdentifierHash & idHash) const + { + return m_elementCollection[idHash]; + } + + SiDetectorElement* PixelDetectorManager::getDetectorElement(int barrel_endcap, int layer_wheel, int phi_module, int eta_module) const + { + return getDetectorElement(m_idHelper->wafer_id(barrel_endcap, layer_wheel, phi_module, eta_module)); + } + + + const SiDetectorElementCollection* PixelDetectorManager::getDetectorElementCollection() const + { + return &m_elementCollection; + } + + SiDetectorElementCollection::const_iterator PixelDetectorManager::getDetectorElementBegin() const + { + return m_elementCollection.begin(); + } + + SiDetectorElementCollection::const_iterator PixelDetectorManager::getDetectorElementEnd() const + { + return m_elementCollection.end(); + } + + + void PixelDetectorManager::addDetectorElement(SiDetectorElement * element) + { + IdentifierHash idHash = element->identifyHash(); + if (idHash >= m_elementCollection.size()) + throw std::runtime_error("PixelDetectorManager: Error adding detector element."); + m_elementCollection[idHash] = element; + } + + void PixelDetectorManager::initNeighbours() + { + SiDetectorElementCollection::iterator iter; + + // Loop over all elements and set the neighbours + for (iter = m_elementCollection.begin(); iter != m_elementCollection.end(); ++iter){ + + SiDetectorElement * element = *iter; + if (element) { + + IdentifierHash idHash = element->identifyHash(); + IdentifierHash idHashOther; + + int result; + // If no neighbour, result != 0 in which case we leave neighbour as null + result = m_idHelper->get_next_in_eta(idHash, idHashOther); + if (result==0) element->setNextInEta(m_elementCollection[idHashOther]); + + result = m_idHelper->get_prev_in_eta(idHash, idHashOther); + if (result==0) element->setPrevInEta(m_elementCollection[idHashOther]); + + result = m_idHelper->get_next_in_phi(idHash, idHashOther); + if (result==0) element->setNextInPhi(m_elementCollection[idHashOther]); + + result = m_idHelper->get_prev_in_phi(idHash, idHashOther); + if (result==0) element->setPrevInPhi(m_elementCollection[idHashOther]); + } + } + } + + + const PixelID* PixelDetectorManager::getIdHelper() const + { + return m_idHelper; + } + + unsigned int PixelDetectorManager::getBarrelLayers() const + { + unsigned int barrelLayers = 0; + for (int i = numerology().numLayers() - 1; i >= 0; --i) { + barrelLayers *= 10; + barrelLayers += numerology().useLayer(i); + } + return barrelLayers; + } + + unsigned int PixelDetectorManager::getEndcapLayers() const + { + unsigned int endcapLayers = 0; + for (int i = numerology().numDisks() - 1; i >= 0; --i) { + endcapLayers *= 10; + endcapLayers += numerology().useDisk(i); + } + return endcapLayers; + } + + + bool PixelDetectorManager::setAlignableTransformDelta(int level, + const Identifier & id, + const Amg::Transform3D & delta, + FrameType frame) const + { + + if (level == 0) { // At the element level - local shift + + // We retrieve it via a hashId. + IdentifierHash idHash = m_idHelper->wafer_hash(id); + if (!idHash.is_valid()) return false; + + if (frame == InDetDD::global) { + + return setAlignableTransformGlobalDelta(m_alignableTransforms[idHash], delta); + + } else if (frame == InDetDD::local) { + + const SiDetectorElement * element = m_elementCollection[idHash]; + if (!element) return false; + + // Its a local transform + return setAlignableTransformLocalDelta(m_alignableTransforms[idHash], element->transform(), delta); + } else { + // other not supported + msg(MSG::WARNING) << "Frames other than global or local are not supported." << endreq; + return false; + } + + } else { // higher level + + if (frame != InDetDD::global) { + msg(MSG::WARNING) << "Non global shift at higher levels is not possible." << endreq; + return false; + } + + int index = level - FIRST_HIGHER_LEVEL; // level 0 is treated separately. + if (index >= static_cast<int>(m_higherAlignableTransforms.size())) return false; + + // We retrieve it from a map. + AlignableTransformMap::const_iterator iter; + iter = m_higherAlignableTransforms[index].find(id); + if (iter == m_higherAlignableTransforms[index].end()) return false; + + // Its a global transform + return setAlignableTransformGlobalDelta(iter->second, delta); + } + + } + + + void PixelDetectorManager::addAlignableTransform (int level, + const Identifier & id, + GeoAlignableTransform *transform, + const GeoVPhysVol * child) + { + if (m_idHelper) { + + const GeoVFullPhysVol * childFPV = dynamic_cast<const GeoVFullPhysVol *>(child); + if (!childFPV) { + msg(MSG::ERROR) << "Child of alignable transform is not a full physical volume" + << endreq; + } else { + addAlignableTransform (level, id, transform, childFPV); + } + } + } + + void PixelDetectorManager::addAlignableTransform (int level, + const Identifier & id, + GeoAlignableTransform *transform, + const GeoVFullPhysVol * child) + { + if (m_idHelper) { + if (level == 0) { + IdentifierHash idHash = m_idHelper->wafer_hash(id); + if (idHash.is_valid()) { + m_alignableTransforms[idHash]= new ExtendedAlignableTransform(transform, child); + } + } else { + // Higher levels are saved in a map. NB the index is level-1 as level=0 is treated above. + int index = level - FIRST_HIGHER_LEVEL; + if (index >= static_cast<int>(m_higherAlignableTransforms.size())) m_higherAlignableTransforms.resize(index+1); + m_higherAlignableTransforms[index][id] = new ExtendedAlignableTransform(transform, child); + } + } + } + + bool PixelDetectorManager::identifierBelongs(const Identifier & id) const + { + return getIdHelper()->is_pixel(id); + } + + + + const PixelModuleDesign* PixelDetectorManager::getPixelDesign(int i) const + { + return dynamic_cast<const PixelModuleDesign *>(getDesign(i)); + } + + +} // namespace InDetDD + + diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/PixelDiodeMap.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/PixelDiodeMap.cxx new file mode 100755 index 0000000000000000000000000000000000000000..7d6514a887118d7669d4cd317933b7e43755320c --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/PixelDiodeMap.cxx @@ -0,0 +1,299 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// PixelDiodeMap.cxx +// Implementation file for class PixelDiodeMap +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Pixel Detector software +/////////////////////////////////////////////////////////////////// +// Version 4.2 14/08/2001 David Calvet +// Modified: Grant Gorfine +/////////////////////////////////////////////////////////////////// + +#include "InDetReadoutGeometry/PixelDiodeMap.h" +#include "InDetReadoutGeometry/PixelDiodeMatrix.h" +#include "InDetReadoutGeometry/SiCellId.h" + +#include <cmath> +#include <algorithm> + +namespace InDetDD { + + + +// Implicit constructor: +PixelDiodeMap::PixelDiodeMap(const PixelDiodeMatrix * matrix) : + m_matrix(matrix), + m_generalLayout(false) +{ + m_matrix->ref(); +} + +PixelDiodeMap::~PixelDiodeMap() +{ + m_matrix->unref(); +} + + + SiCellId PixelDiodeMap::cellIdOfPosition(const Amg::Vector2D & localPos) const +{ + using std::abs; + using Trk::distPhi; + using Trk::distEta; + + // Check that we are in the bounds of the top level matrix + // NB. edge is included in bounds. + + double halfWidth = 0.5*width(); + double halfLength = 0.5*length(); + if ( (abs(localPos[distPhi]) > halfWidth) || + (abs(localPos[distEta]) > halfLength) ) { + return SiCellId(); // Invalid Id. + } + + // position relative to bottom left corner. + Amg::Vector2D relativePos = localPos + Amg::Vector2D(halfWidth, halfLength); + + // The cellId returned will be added to this so we must start with 0,0. + SiCellId cellId(0,0); + + const PixelDiodeMatrix * cell = m_matrix->cellIdOfPosition(relativePos, cellId); + + // return invalid Id if there was a problem (don't expect this to be the case). + if (!cell) { + return SiCellId(); // Invalid id. + } + + return cellId; + +} + + +// Get diodes parameters (position and size): +SiDiodesParameters +PixelDiodeMap::parameters(const SiCellId & cellId) const +{ + + // Check we are in range + + if (!cellId.isValid() || + (cellId.phiIndex() < 0) || + (cellId.phiIndex() >= m_matrix->phiCells()) || + (cellId.etaIndex() < 0) || + (cellId.etaIndex() >= m_matrix->etaCells())) { + return SiDiodesParameters(); + } + + double halfWidth = 0.5*width(); + double halfLength = 0.5*length(); + + // + // Position is relative to left bottom corner. + // + Amg::Vector2D position(-halfWidth, -halfLength); + const PixelDiodeMatrix * cell = m_matrix->positionOfCell(cellId, position); + + if (cell) { + + // get size + Amg::Vector2D size(cell->phiWidth(), cell->etaWidth()); + + // return parameters + return SiDiodesParameters(position,size); + } + + // return something in case of failure. + return SiDiodesParameters(); +} + +void PixelDiodeMap::neighboursOfCell(const SiCellId & cellId, + std::vector<SiCellId> &neighbours) const +{ + neighbours.clear(); + + if (!cellId.isValid()) return; + + // If non regular layout revert to slower method + if (m_generalLayout) return neighboursOfCellGeneral(cellId, neighbours); + + neighbours.reserve(8); + // neighbours easily determined from cell number + // normally 8 neighbours 4 edge and 4 corners + + int phiIndex = cellId.phiIndex(); + int etaIndex = cellId.etaIndex(); + + // M = minus + // P = plus + int phiM = phiIndex-1; + int phiP = phiIndex+1; + int etaM = etaIndex-1; + int etaP = etaIndex+1; + + // -,0 + if (phiM >= 0) neighbours.push_back(SiCellId(phiM,etaIndex)); + // -,- + if (phiM >= 0 && etaM >= 0) neighbours.push_back(SiCellId(phiM,etaM)); + // 0,- + if (etaM >= 0) neighbours.push_back(SiCellId(phiIndex,etaM)); + // +,- + if (phiP < phiDiodes() && etaM >= 0) neighbours.push_back(SiCellId(phiP,etaM)); + // +,0 + if (phiP < phiDiodes()) neighbours.push_back(SiCellId(phiP,etaIndex)); + // -,+ + if (phiM >= 0 && etaP < etaDiodes()) neighbours.push_back(SiCellId(phiM,etaP)); + // 0,+ + if (etaP < etaDiodes()) neighbours.push_back(SiCellId(phiIndex,etaP)); + // +,+ + if (phiP < phiDiodes() && etaP < etaDiodes()) neighbours.push_back(SiCellId(phiP,etaP)); +} + +// Get the neighbouring PixelDiodes of a given PixelDiode: +// This will work for more complex layouts such as bricking. Probably never really needed but +// since the code was here I keep it available. +void PixelDiodeMap::neighboursOfCellGeneral(const SiCellId & cellId, + std::vector<SiCellId> &neighbours) const +{ + // extract the diode spatial parameters + const SiDiodesParameters params=parameters(cellId); + const SiLocalPosition diodeCenter=params.centre(); + const SiLocalPosition diodeSize=params.width(); + const double ¢erColumn=diodeCenter.xColumn(); + const double ¢erRow=diodeCenter.xRow(); + const double halfSizeColumn=diodeSize.xColumn()/2; + const double halfSizeRow=diodeSize.xRow()/2; + + // parameter + const double epsilon=0.01; + + // compute the points to check + const double left1=centerColumn-halfSizeColumn*(1+epsilon); + const double right1=centerColumn+halfSizeColumn*(1+epsilon); + const double left2=centerColumn-halfSizeColumn*(1-epsilon); + const double right2=centerColumn+halfSizeColumn*(1-epsilon); + const double top1=centerRow+halfSizeRow*(1+epsilon); + const double bot1=centerRow-halfSizeRow*(1+epsilon); + const double top2=centerRow+halfSizeRow*(1-epsilon); + const double bot2=centerRow-halfSizeRow*(1-epsilon); + + // build the list of positions to check + std::vector<SiLocalPosition> positions; + positions.reserve(12); + SiLocalPosition position; + position.xRow(bot1); position.xColumn(left2); positions.push_back(position); + position.xRow(bot1); position.xColumn(left1); positions.push_back(position); + position.xRow(bot2); position.xColumn(left1); positions.push_back(position); + position.xRow(top2); position.xColumn(left1); positions.push_back(position); + position.xRow(top1); position.xColumn(left1); positions.push_back(position); + position.xRow(top1); position.xColumn(left2); positions.push_back(position); + position.xRow(bot1); position.xColumn(right2); positions.push_back(position); + position.xRow(bot1); position.xColumn(right1); positions.push_back(position); + position.xRow(bot2); position.xColumn(right1); positions.push_back(position); + position.xRow(top2); position.xColumn(right1); positions.push_back(position); + position.xRow(top1); position.xColumn(right1); positions.push_back(position); + position.xRow(top1); position.xColumn(right2); positions.push_back(position); + + // build the list of neighbours + neighbours.reserve(8); + + // loop on all positions to check + for(std::vector<SiLocalPosition>::const_iterator p_position=positions.begin() ; + p_position!=positions.end() ; ++p_position) { + + // get the PixelDiode for this position + SiCellId cellId_neighb = cellIdOfPosition(*p_position); + + if (cellId.isValid()) { + // check if the diode is already in the list + //bool found=false; + std::vector<SiCellId>::const_iterator foundIter + = std::find(neighbours.begin(), neighbours.end(), cellId_neighb ); + + // If not found add this diode to the list + if (foundIter == neighbours.end()) neighbours.push_back(cellId_neighb); + + } + } +} + + +// Compute the intersection length of two diodes: +double PixelDiodeMap::intersectionLength(const SiCellId &diode1, + const SiCellId &diode2) const +{ + if(!diode1.isValid() || !diode2.isValid()) return 0; + // If non regular layout revert to slower method + if (m_generalLayout) return intersectionLengthGeneral(diode1, diode2); + + const SiLocalPosition size = parameters(diode1).width(); + + int phiIndexDelta = std::abs(diode1.phiIndex() - diode2.phiIndex()); + int etaIndexDelta = std::abs(diode1.etaIndex() - diode2.etaIndex()); + + // Intersection length is just the length or width of the diode depending on which neighbour. + if (phiIndexDelta == 1 && etaIndexDelta == 0) return size.xEta(); + if (phiIndexDelta == 0 && etaIndexDelta == 1) return size.xPhi(); + // Will return 0 if it is a corner neighbour or if its not a neighbour or if they are oth the same diode. + return 0; +} + +// Compute the intersection length of two diodes: +// This will work for more complex layouts such as bricking. Probably never really needed but +// since the code was here I keep it available. +double PixelDiodeMap::intersectionLengthGeneral(const SiCellId &diode1, + const SiCellId &diode2) const + +{ + const SiDiodesParameters params1=parameters(diode1); + const SiDiodesParameters params2=parameters(diode2); + const SiLocalPosition center1=params1.centre(); + const SiLocalPosition center2=params2.centre(); + const SiLocalPosition size1=params1.width(); + const SiLocalPosition size2=params2.width(); + + // compute intersection length on column direction + const double intersectionColumn=intersectionLength1D(center1.xColumn(), + size1.xColumn(), + center2.xColumn(), + size2.xColumn()); + // compute intersection length on row direction + const double intersectionRow=intersectionLength1D(center1.xRow(), + size1.xRow(), + center2.xRow(), + size2.xRow()); + + // return the real intersection + // (if both directions intersect, there is a problem) + if (intersectionColumn>0) { + if (intersectionRow>0) return 0; + return intersectionColumn; + } else { + return intersectionRow; + } +} + +// Compute the intersection length along one direction: +double PixelDiodeMap::intersectionLength1D(const double x1,const double dx1, + const double x2,const double dx2) const +{ + // compute distance between the two centers + double distance=std::abs(x1-x2); + + // compute theoretical intersection + double intersection=(dx1+dx2)/2-distance; + + // if intersection if negative, no intersection + if (intersection<-1e-10) return intersection; + else if (intersection<1e-10) return 0; + else { + // intersection cannot exceed size + if (intersection>dx1) intersection=dx1; + if (intersection>dx2) intersection=dx2; + return intersection; + } +} + +} // namespace InDetDD + diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/PixelDiodeMatrix.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/PixelDiodeMatrix.cxx new file mode 100755 index 0000000000000000000000000000000000000000..95f21a1cf999db54dc35d045508787e7db793c57 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/PixelDiodeMatrix.cxx @@ -0,0 +1,325 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "InDetReadoutGeometry/PixelDiodeMatrix.h" +#include "InDetReadoutGeometry/SiCellId.h" +#include "TrkEventPrimitives/ParamDefs.h" + +#include <cassert> + +namespace InDetDD { + +PixelDiodeMatrix::PixelDiodeMatrix(double phiWidth, double etaWidth) + : m_phiWidth(phiWidth), + m_etaWidth(etaWidth), + m_phiCells(1), + m_etaCells(1), + m_direction(phiDir), // Irrelevant + m_numCells(0), + m_lowerCell(0), + m_middleCells(0), + m_upperCell(0), + m_singleCell(true) +{} + +PixelDiodeMatrix::PixelDiodeMatrix(Direction direction, // phi or eta + const PixelDiodeMatrix * lowerCell, + const PixelDiodeMatrix * middleCells, + int numCells, + const PixelDiodeMatrix * upperCell) + : m_phiWidth(0), + m_etaWidth(0), + m_phiCells(0), + m_etaCells(0), + m_direction(direction), + m_numCells(numCells), + m_lowerCell(lowerCell), + m_middleCells(middleCells), + m_upperCell(upperCell), + m_singleCell(false) +{ + // middleCells must be non zero. + assert(m_middleCells); + + // Increment ref counts + if (m_lowerCell) m_lowerCell->ref(); + if (m_middleCells) m_middleCells->ref(); + if (m_upperCell) m_upperCell->ref(); + + if (m_direction == phiDir) { + + // In eta direction widths must be all the same. + if (m_middleCells){ + m_etaWidth = m_middleCells->etaWidth(); + m_etaCells = m_middleCells->etaCells(); + } + // Check lower and upper are consistent + // TODO. + + if (m_lowerCell) { + m_phiWidth += m_lowerCell->phiWidth(); + m_phiCells += m_lowerCell->phiCells(); + } + + if (m_middleCells){ + m_phiWidth += m_numCells * m_middleCells->phiWidth(); + m_phiCells += m_numCells * m_middleCells->phiCells(); + } + + if (m_upperCell) { + m_phiWidth += m_upperCell->phiWidth(); + m_phiCells += m_upperCell->phiCells(); + } + + } else { // eta Direction + + // In phi direction widths must be all the same. + if (m_middleCells){ + m_phiWidth = m_middleCells->phiWidth(); + m_phiCells = m_middleCells->phiCells(); + } + // Check lower and upper are consistent + // TODO. + + if (m_lowerCell) { + m_etaWidth += m_lowerCell->etaWidth(); + m_etaCells += m_lowerCell->etaCells(); + } + + if (m_middleCells){ + m_etaWidth += m_numCells * m_middleCells->etaWidth(); + m_etaCells += m_numCells * m_middleCells->etaCells(); + } + + if (m_upperCell) { + m_etaWidth += m_upperCell->etaWidth(); + m_etaCells += m_upperCell->etaCells(); + } + + } + +} + +PixelDiodeMatrix:: ~PixelDiodeMatrix() +{ + // unref the point the pointers. + if (m_lowerCell) m_lowerCell->unref(); + if (m_middleCells) m_middleCells->unref(); + if (m_upperCell) m_upperCell->unref(); +} + +const PixelDiodeMatrix * +PixelDiodeMatrix::cellIdOfPosition(const Amg::Vector2D & relPosition, SiCellId & cellId) const + + /// Description. + /// Overview of algoritm: + /// + /// - Before calling this method on the top level matrix the 2D position is + /// calculated relative to the bottom left corner. + /// - The method cellIdOfPosition is always called with the position relative to + /// bottom left of the cell and the cell id of bottom left child cell. + /// For the top level matrix this is the position (-halfWidth, -halfLength) and a starting + /// cell id of (0,0). + /// - It first checks if it is in the lower cell (if it exists). + /// - If not, it determines which cell by dividing the position relative to + /// the start of the cell array by the pitch in that direction. + /// - If it is beyond the range of the middle cells it is taken as being in + /// the upper cell. + /// - The cell number is added to the cellId that is passed to the method + /// - Once the cell is determined the function is called recursively until it + /// reaches a single cell. + /// + +{ + using Trk::distPhi; + using Trk::distEta; + + if (m_singleCell) { + return this; + } + + double relPosDir = 0; // Relative position along m_direction + int startIndex = 0; + double pitch = 0; + int middleCells = 0; + + if (m_direction == phiDir) { + + relPosDir = relPosition[distPhi]; + pitch = m_middleCells->phiWidth(); + middleCells = m_middleCells->phiCells(); + + if (m_lowerCell) { + if (relPosDir < m_lowerCell->phiWidth()) { + return m_lowerCell->cellIdOfPosition(relPosition, cellId); + } else { + relPosDir -= m_lowerCell->phiWidth(); + startIndex += m_lowerCell->phiCells(); + } + } + } else { // etaDir + + relPosDir = relPosition[distEta]; + pitch = m_middleCells->etaWidth(); + middleCells = m_middleCells->etaCells(); + + if (m_lowerCell) { + if (relPosDir < m_lowerCell->etaWidth()) { + return m_lowerCell->cellIdOfPosition(relPosition, cellId); + } else { + relPosDir -= m_lowerCell->etaWidth(); + startIndex += m_lowerCell->etaCells(); + } + } + } + + + int index = static_cast<int>((relPosDir) / pitch); + + if (index < 0) index = 0; // Make sure its in range (in case of rounding errors) + const PixelDiodeMatrix * nextCell = 0; + + if (m_upperCell && (index >= m_numCells)) { + // We are in the upper cell. + index = m_numCells; + nextCell = m_upperCell; + } else { + // We are in the middle cells + // Make sure its in range (in case of rounding errors) + if (index >= m_numCells) index = m_numCells - 1; + nextCell = m_middleCells; + } + + + relPosDir -= index * pitch; + startIndex += index * middleCells; + + int newPhiIndex = cellId.phiIndex(); + int newEtaIndex = cellId.etaIndex(); + const PixelDiodeMatrix * cell = 0; + + if (m_direction == phiDir) { + if (nextCell->singleCell()) { + newPhiIndex += startIndex; + cell = nextCell; + } else { + Amg::Vector2D newRelPos(relPosDir, relPosition[distEta]); + SiCellId relId(0,0); + cell = nextCell->cellIdOfPosition(newRelPos, relId); + newPhiIndex += startIndex + relId.phiIndex(); + newEtaIndex += relId.etaIndex(); + } + } else { + if (nextCell->singleCell()) { + newEtaIndex += startIndex; + cell = nextCell; + } else { + Amg::Vector2D newRelPos(relPosition[distPhi], relPosDir); + SiCellId relId(0,0); + cell = nextCell->cellIdOfPosition(newRelPos, relId); + newPhiIndex += relId.phiIndex(); + newEtaIndex += startIndex + relId.etaIndex(); + } + } + + cellId = SiCellId(newPhiIndex, newEtaIndex); + return cell; +} + + + +const PixelDiodeMatrix * +PixelDiodeMatrix::positionOfCell(const SiCellId & cellId, Amg::Vector2D & position) const + + /// Description. + /// Overview of algoritm: + /// + /// - It starts with the position of the bottom left corner of the cell. + /// For the full matrix this is (-halfwidth,-halflength) + /// - It first checks if is in the lower cell (if it exists). + /// - If not it determines the bottom edge of the cell by multiplying the cell + /// number by the pitch. + /// - If it is beyond the range of the middle cells it is taken as being in + /// the upper cell. + /// - This position is then passed recursively to the same method until it + /// reaches a single cell. + /// - At the end the 2D position is then transformed to the position + /// relative to the module center. + +{ + using Trk::distPhi; + using Trk::distEta; + + if (m_singleCell) { + position[distPhi] += 0.5*m_phiWidth; + position[distEta] += 0.5*m_etaWidth; + return this; + } + + int relIndex = 0; // Relative index along m_direction + double pitch = 0; + int middleCells = 0; + double startPos = 0; + + if (m_direction == phiDir) { + + relIndex = cellId.phiIndex(); + pitch = m_middleCells->phiWidth(); + middleCells = m_middleCells->phiCells(); + + if (m_lowerCell) { + if (relIndex < m_lowerCell->phiCells()) { + return m_lowerCell->positionOfCell(cellId, position); + } else { + relIndex -= m_lowerCell->phiCells(); + startPos += m_lowerCell->phiWidth(); + } + } + + } else { // etaDir + + relIndex = cellId.etaIndex(); + pitch = m_middleCells->etaWidth(); + middleCells = m_middleCells->etaCells(); + + if (m_lowerCell) { + if (relIndex < m_lowerCell->etaCells()) { + return m_lowerCell->positionOfCell(cellId, position); + } else { + relIndex -= m_lowerCell->etaCells(); + startPos += m_lowerCell->etaWidth(); + } + } + } + + int index = relIndex / middleCells; + if (index > m_numCells) index = m_numCells; + relIndex -= index * middleCells; + startPos += index * pitch; + + const PixelDiodeMatrix * nextCell = 0; + + if (m_upperCell && (index == m_numCells)) { + // We are in the upper cell. + nextCell = m_upperCell; + } else { + // We are in the middle cells + nextCell = m_middleCells; + } + + const PixelDiodeMatrix * cell = 0; + if (m_direction == phiDir) { + SiCellId relId(relIndex,cellId.etaIndex()); + position[distPhi] += startPos; + cell = nextCell->positionOfCell(relId, position); + } else { + SiCellId relId(cellId.phiIndex(),relIndex); + position[distEta] += startPos; + cell = nextCell->positionOfCell(relId, position); + } + + return cell; +} + +} // end namespace diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/PixelModuleDesign.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/PixelModuleDesign.cxx new file mode 100755 index 0000000000000000000000000000000000000000..573c1cf92e9a239533da66c934c010067632d191 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/PixelModuleDesign.cxx @@ -0,0 +1,252 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// PixelModuleDesign.cxx +// Implementation file for class PixelModuleDesign +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Pixel Detector software +/////////////////////////////////////////////////////////////////// +// Version 1.9 18/03/2002 Alessandro Fornaini +// Modified: Grant Gorfine +/////////////////////////////////////////////////////////////////// + +#include "InDetReadoutGeometry/PixelModuleDesign.h" +#include "Identifier/Identifier.h" +#include "InDetReadoutGeometry/SiCellId.h" +#include "InDetReadoutGeometry/SiReadoutCellId.h" +#include "TrkSurfaces/RectangleBounds.h" + +#include <cmath> + +namespace InDetDD { + +using std::abs; + +// Constructor with parameters: + +PixelModuleDesign::PixelModuleDesign(const double thickness, + const int circuitsPerColumn, + const int circuitsPerRow, + const int cellColumnsPerCircuit, + const int cellRowsPerCircuit, + const int diodeColumnsPerCircuit, + const int diodeRowsPerCircuit, + const PixelDiodeMatrix * matrix, + InDetDD::CarrierType carrierType, + int readoutSide, + bool is3D) : + + SiDetectorDesign(thickness, + true, true, true, // phi,eta,depth axes symmetric + carrierType, + readoutSide), + m_diodeMap(matrix), + m_readoutScheme(circuitsPerColumn,circuitsPerRow, + cellColumnsPerCircuit,cellRowsPerCircuit, + diodeColumnsPerCircuit,diodeRowsPerCircuit), + m_bounds(0), + m_is3D(is3D) +{ + // m_bounds = new Trk::RectangleBounds(0.5*width(), 0.5*length()); +} + +// Destructor: +PixelModuleDesign::~PixelModuleDesign() +{ + delete m_bounds; +} + +// Returns distance to nearest detector edge +// +ve = inside +// -ve = outside +void +PixelModuleDesign::distanceToDetectorEdge(const SiLocalPosition & localPosition, + double & etaDist, double & phiDist) const +{ + // This assume element is centered at 0,0 + // As the calculation is symmetric around 0,0 we only have to test it for one side. + double xEta = abs(localPosition.xEta()); + double xPhi = abs(localPosition.xPhi()); + + double xEtaEdge = 0.5*length(); + double xPhiEdge = 0.5*width(); + + // Distance to top/bottom + etaDist = xEtaEdge - xEta; + + // Distance to right/left edge + phiDist = xPhiEdge - xPhi; + +} + +SiDiodesParameters PixelModuleDesign::parameters(const SiCellId & cellId) const +{ + return m_diodeMap.parameters(cellId); +} + +SiLocalPosition PixelModuleDesign::localPositionOfCell(const SiCellId & cellId) const +{ + return m_diodeMap.parameters(cellId).centre(); +} + + +// Helper method for stereo angle computation +HepGeom::Vector3D<double> PixelModuleDesign::phiMeasureSegment(const SiLocalPosition&) const +{ + HepGeom::Vector3D<double> segment; + segment[etaAxis()]=1; + return segment; +} + +// Special method for SCT (irrelevant here): +std::pair<SiLocalPosition,SiLocalPosition> PixelModuleDesign::endsOfStrip(const SiLocalPosition &position) const +{ + return std::pair<SiLocalPosition,SiLocalPosition>(position,position); +} + + +// Methods to calculate length of a module +double PixelModuleDesign::length() const +{ + return m_diodeMap.length(); +} + +// Methods to calculate average width of a module +double PixelModuleDesign::width() const +{ + return m_diodeMap.width(); +} + +// Methods to calculate minimum width of a module +double PixelModuleDesign::minWidth() const +{ + return width(); +} + +// Methods to calculate maximum width of a module +double PixelModuleDesign::maxWidth() const +{ + return width(); +} + + +// Method to calculate eta width from a column range +double PixelModuleDesign::widthFromColumnRange(const int colMin, const int colMax) const +{ + SiCellId idMin(0, colMin); + SiCellId idMax(0, colMax); + + double minEta = parameters(idMin).xEtaMin(); + double maxEta = parameters(idMax).xEtaMax(); + + return fabs(maxEta-minEta); +} + +// Method to calculate phi width from a row range +double PixelModuleDesign::widthFromRowRange(const int rowMin, const int rowMax) const +{ + + SiCellId idMin(rowMin, 0); + SiCellId idMax(rowMax, 0); + double minPhi = parameters(idMin).xPhiMin(); + double maxPhi = parameters(idMax).xPhiMax(); + + return fabs(maxPhi-minPhi); +} + +// Pitch in phi direction +double +PixelModuleDesign::phiPitch() const +{ + // Average pitch. + return width() / rows(); +} + +// Pitch in phi direction +double +PixelModuleDesign::phiPitch(const SiLocalPosition &) const +{ + // Cheat since we know its constant. + return phiPitch(); +} + +// Pitch in eta direction +double +PixelModuleDesign::etaPitch() const +{ + // Average pitch + return length() / columns(); +} + +SiCellId PixelModuleDesign::cellIdOfPosition(const SiLocalPosition & localPosition) const +{ + return m_diodeMap.cellIdOfPosition(localPosition); +} + + +int PixelModuleDesign::numberOfConnectedCells(const SiReadoutCellId & readoutId) const +{ + return m_readoutScheme.numberOfConnectedCells(readoutId); +} + +SiCellId +PixelModuleDesign::connectedCell(const SiReadoutCellId & readoutId, int number) const +{ + return m_readoutScheme.connectedCell(readoutId, number); +} + +SiCellId +PixelModuleDesign::gangedCell(const SiCellId & cellId) const +{ + return m_readoutScheme.gangedCell(cellId); +} + +SiReadoutCellId +PixelModuleDesign::readoutIdOfCell(const SiCellId & cellId) const +{ + return m_readoutScheme.readoutIdOfCell(cellId); +} + + +SiReadoutCellId +PixelModuleDesign::readoutIdOfPosition(const SiLocalPosition & localPos) const +{ + return m_readoutScheme.readoutIdOfCell(m_diodeMap.cellIdOfPosition(localPos)); +} + +// Given row and column index of diode, returns position of diode center +// ALTERNATIVE/PREFERED way is to use localPositionOfCell(const SiCellId & cellId) or +// rawLocalPositionOfCell method in SiDetectorElement. +// DEPRECATED (but used in numerous places) +SiLocalPosition PixelModuleDesign::positionFromColumnRow(const int column, const int row) const +{ + return localPositionOfCell(SiCellId(row,column)); +} + + +const Trk::SurfaceBounds & +PixelModuleDesign::bounds() const +{ + // We create on demand as width and length are 0 when PixeModuleDesign first gets + // created. + if (!m_bounds) m_bounds = new Trk::RectangleBounds(0.5*width(), 0.5*length()); + return *m_bounds; +} + + + +void PixelModuleDesign::setGeneralLayout() +{ + m_diodeMap.setGeneralLayout(); +} + +SiCellId +PixelModuleDesign::cellIdInRange(const SiCellId & cellId) const +{ + return m_diodeMap.cellIdInRange(cellId); +} + + +} // namespace InDetDD diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/PixelMultipleConnection1D.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/PixelMultipleConnection1D.cxx new file mode 100755 index 0000000000000000000000000000000000000000..d2f6d11c8158fc5019f44298828c640c14ebc7d5 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/PixelMultipleConnection1D.cxx @@ -0,0 +1,141 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// PixelMultipleConnection1D.cxx +// Implementation file for class PixelMultipleConnection1D +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Pixel Detector software +/////////////////////////////////////////////////////////////////// +// Version 1.1 05/04/2001 David Calvet +// 06/02/2008 Grant Gorfine +/////////////////////////////////////////////////////////////////// + +#include "InDetReadoutGeometry/PixelMultipleConnection1D.h" +#include <iostream> + +namespace InDetDD { + +// Constructor with parameters: +PixelMultipleConnection1D::PixelMultipleConnection1D(const int lowerIndex, + const std::vector<int> &connections) + : m_lowerDiode(0), + m_upperDiode(-1), + m_lowerReadout(0), + m_upperReadout(-1) +{ + set(lowerIndex, connections); +} + +PixelMultipleConnection1D::PixelMultipleConnection1D() + : m_lowerDiode(0), + m_upperDiode(-1), + m_lowerReadout(0), + m_upperReadout(-1) +{} + +void +PixelMultipleConnection1D::set(const int lowerIndex, + const std::vector<int> &connections) +{ + + // extract lower and upper diode and readout cell numbers from connections vector + bool firstDiode = true; + bool firstReadout = true; + for(unsigned int index = 0; index < connections.size(); ++index) { + int readout = connections[index]; + int diode = lowerIndex + index; + if (firstDiode && readout != diode) { + m_lowerDiode = diode; + m_upperDiode = diode; + firstDiode = false; + } + if (firstReadout) { + m_lowerReadout=readout; + m_upperReadout=readout; + firstReadout = false; + } + if (readout<m_lowerReadout) m_lowerReadout=readout; + if (readout>m_upperReadout) m_upperReadout=readout; + if (readout != diode && diode < m_lowerDiode) m_lowerDiode = diode; + if (readout != diode && diode > m_upperDiode) m_upperDiode = diode; + } + + // Fource readout range to be include diode range (this is generally already the case) + if (m_lowerReadout > m_lowerDiode) m_lowerReadout = m_lowerDiode; + if (m_upperReadout < m_upperDiode) m_upperReadout = m_upperDiode; + + m_diodeToReadout.resize(m_upperDiode - m_lowerDiode + 1); + m_readoutToDiode.resize(m_upperReadout - m_lowerReadout + 1); + + // First fill primary cell. ie diode and readout the same. + for(unsigned int index = 0; index < connections.size(); ++index) { + int readout = connections[index]; + int diode = lowerIndex + index; + if (readout == diode) m_readoutToDiode[readout-m_lowerReadout].push_back(diode); + } + + + // Now the rest of readoutToDiode ie diode and readout not the same. + // Fill also diodeToReadout + for(unsigned int index = 0; index < connections.size(); ++index) { + int readout = connections[index]; + int diode = lowerIndex + index; + if (readout != diode) m_readoutToDiode[readout - m_lowerReadout].push_back(diode); + if (diode >= m_lowerDiode && diode <= m_upperDiode) m_diodeToReadout[diode - m_lowerDiode] = readout; + } + + // Created ganged map. If the diode is ganged it points to the other diode. + m_diodeGanged.resize(m_upperReadout - m_lowerReadout + 1); + for(int iDiode = m_lowerReadout; iDiode <= m_upperReadout; iDiode++) { + // Fill with the same index which indicates its not ganged. + m_diodeGanged[iDiode - m_lowerReadout] = iDiode; + int readout = iDiode; + if (!outsideDiode(iDiode)) readout = readoutOfDiode(iDiode); + if (numberOfConnectedCells(readout) >= 2) { + int cell0 = connectedCell(readout, 0); + int cell1 = connectedCell(readout, 1); + if (iDiode == cell0) { + m_diodeGanged[iDiode - m_lowerReadout] = cell1; + } else { + m_diodeGanged[iDiode - m_lowerReadout] = cell0; + } + } + } + + // For debugging only + //debugPrintout(); +} + +void PixelMultipleConnection1D::debugPrintout() +{ + // Debug printout + std::cout << "m_lowerDiode = " << m_lowerDiode << std::endl; + std::cout << "m_upperDiode = " << m_upperDiode << std::endl; + std::cout << "m_lowerReadout = " << m_lowerReadout << std::endl; + std::cout << "m_upperReadout = " << m_upperReadout << std::endl; + std::cout << "m_readoutToDiode: "; + for (unsigned int i = 0; i < m_readoutToDiode.size(); i++) { + std::cout << "(" << m_lowerReadout + i << ": "; + for (unsigned int j = 0; j < m_readoutToDiode[i].size(); j++) { + std::cout << m_readoutToDiode[i][j] << " "; + } + std::cout << ") "; + } + std::cout << std::endl; + + for (unsigned int i = 0; i < m_diodeToReadout.size(); i++) { + std::cout << "(" << m_lowerDiode + i << ": " << m_diodeToReadout[i] << ") "; + } + std::cout << std::endl; + + for (unsigned int i = 0; i < m_diodeGanged.size(); i++) { + std::cout << "(" << m_lowerReadout + i << ": " << m_diodeGanged[i] << ") "; + } + std::cout << std::endl; +} + + + +} // namespace InDetDD diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/PixelReadoutScheme.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/PixelReadoutScheme.cxx new file mode 100755 index 0000000000000000000000000000000000000000..e0e80ff52f89927dfe7263b1590a45c40bba2ff8 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/PixelReadoutScheme.cxx @@ -0,0 +1,104 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// PixelReadoutScheme.cxx +// Implementation file for class PixelReadoutScheme +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Pixel Detector software +/////////////////////////////////////////////////////////////////// +// Version 2.1 08/06/2001 David Calvet +// Modified: Grant Gorfine +/////////////////////////////////////////////////////////////////// + +#include "InDetReadoutGeometry/PixelReadoutScheme.h" +#include "InDetReadoutGeometry/SiCellId.h" +#include "InDetReadoutGeometry/SiReadoutCellId.h" + +namespace InDetDD { + +// Constructor with parameters: +PixelReadoutScheme::PixelReadoutScheme(const int circuitsPerColumn, + const int circuitsPerRow, + const int cellColumnsPerCircuit, + const int cellRowsPerCircuit, + const int diodeColumnsPerCircuit, + const int diodeRowsPerCircuit) : + m_numberOfCircuits(circuitsPerColumn*circuitsPerRow), + m_columnsPerCircuit(cellColumnsPerCircuit), + m_rowsPerCircuit(cellRowsPerCircuit), + m_columns(circuitsPerRow*diodeColumnsPerCircuit), + m_rows(circuitsPerColumn*diodeRowsPerCircuit) +{} + + + +// Number of cells connected to this readout. 2 means its ganged. +int +PixelReadoutScheme::numberOfConnectedCells(const SiReadoutCellId & readoutId) const +{ + if (!readoutId.isValid()) return 0; + + // Do quick check to see if it is outside ganged pixel range. + int phiIndex = readoutId.phiIndex(); + if (m_rowConnections.outsideReadout(phiIndex)) return 1; + + return m_rowConnections.numberOfConnectedCells(phiIndex); + +} + +// Id of diodes connected to this readout. 0 is the primary cell. +SiCellId +PixelReadoutScheme::connectedCell(const SiReadoutCellId & readoutId, unsigned int number) const +{ + if (!readoutId.isValid()) return SiCellId(); + + // Do quick check to see if it is outside ganged pixel range. + int phiIndex = readoutId.phiIndex(); + if (m_rowConnections.outsideReadout(phiIndex)) return readoutId; + + int numConnected = m_rowConnections.numberOfConnectedCells(phiIndex); + if (!numConnected || static_cast<int>(number) >= numConnected) return SiCellId(); + + int newPhiIndex = m_rowConnections.connectedCell(phiIndex, number); + return SiCellId(newPhiIndex, readoutId.etaIndex()); +} + +// Id of the readout cell for this diode. +SiReadoutCellId +PixelReadoutScheme::readoutIdOfCell(const SiCellId & cellId) const +{ + if (!cellId.isValid()) return SiReadoutCellId(); + + int phiIndex = cellId.phiIndex(); + int newPhiIndex = phiIndex; + if (!m_rowConnections.outsideDiode(phiIndex)) { + newPhiIndex = m_rowConnections.readoutOfDiode(phiIndex); + } + + return SiReadoutCellId(newPhiIndex, cellId.etaIndex()); + +} + +SiCellId +PixelReadoutScheme::gangedCell(const SiCellId & cellId) const +{ + if (!cellId.isValid()) return cellId; + int phiIndex = cellId.phiIndex(); + if (m_rowConnections.outsideReadout(phiIndex)) return SiCellId(); // Invalid ID + int newPhiIndex = m_rowConnections.gangedCell(phiIndex); + if (newPhiIndex == phiIndex) return SiCellId(); // Invalid ID + return SiCellId(newPhiIndex, cellId.etaIndex()); +} + + +void PixelReadoutScheme::addMultipleRowConnection(const int lowerIndex, + const std::vector<int> &connections) +{ + + m_rowConnections.set(lowerIndex, connections); +} + + +} // namespace InDetDD diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SCT_BarrelModuleSideDesign.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SCT_BarrelModuleSideDesign.cxx new file mode 100755 index 0000000000000000000000000000000000000000..c699ed8363a09199792258dff0f8c51e1103eb10 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SCT_BarrelModuleSideDesign.cxx @@ -0,0 +1,279 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SCT_BarrelModuleSideDesign.cxx +// Implementation file for class SCT_BarrelModuleSideDesign +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// +// +/////////////////////////////////////////////////////////////////// +// Version 1.0a 31/5/2001 Class creator tool +// Version 1.0 9/6/2001 Szymon Gadomski +// Version 1.0.1 20/6/2001 Alessandro Fornaini +// 3/8/2001 Szymon Gadomski: restored correct calculation +// in the new diode e.t.c., inActiveArea made fast +// 15/08/2001 SG: works with new SiDiodesParameters, tested +// 28/08/2001 SG: endsOfStrip method added +// 29/10/2001 AF: phiMeasureSegment added +// Modified: Grant Gorfine +/////////////////////////////////////////////////////////////////// + +#include "InDetReadoutGeometry/SCT_BarrelModuleSideDesign.h" +#include "InDetReadoutGeometry/SiDiodesParameters.h" + +#include "CLHEP/Units/SystemOfUnits.h" +#include "CLHEP/Geometry/Vector3D.h" + +#include "TrkSurfaces/RectangleBounds.h" + +#include <cmath> + +namespace InDetDD { + +using std::abs; + +// Constructor with parameters: +SCT_BarrelModuleSideDesign::SCT_BarrelModuleSideDesign(const double thickness, + const int crystals, + const int diodes, + const int cells, + const int shift, + const bool swapStripReadout, + InDetDD::CarrierType carrierType, + const double stripPitch, + const double stripLength, + const double xEtaStripPatternCentre, + const double xPhiStripPatternCentre, + const double totalDeadLength, + int readoutSide) : + SCT_ModuleSideDesign(thickness, + true, true, true, // phi,eta,depth axes symmetric + crystals,diodes,cells,shift,swapStripReadout,carrierType,readoutSide), + m_stripPitch(stripPitch), + m_stripLength(stripLength), + m_xEtaStripPatternCentre(xEtaStripPatternCentre), + m_xPhiStripPatternCentre(xPhiStripPatternCentre), + m_totalDeadLength(totalDeadLength) +{ + m_xPhiAbsSize = 0.5*m_stripPitch*diodes; + if(crystals==1) { + m_xEtaAbsSizeLow = m_totalDeadLength/2; + if (m_xEtaAbsSizeLow == 0) m_xEtaAbsSizeLow = -1.0 * CLHEP::mm; // Anything negative will do + m_xEtaAbsSizeHigh = m_stripLength/2; + } + else if(crystals==2) { + m_xEtaAbsSizeLow = m_totalDeadLength/2; + m_xEtaAbsSizeHigh = m_stripLength + m_totalDeadLength/2; + } else { + std::cout << "wrong number of crystals!\n"; + m_xEtaAbsSizeLow = m_xEtaAbsSizeHigh = m_xPhiAbsSize = 0.0; + } + + m_bounds = new Trk::RectangleBounds(0.5*width(), 0.5*length()); +} + + +SCT_BarrelModuleSideDesign::~SCT_BarrelModuleSideDesign() +{ + delete m_bounds; +} + +// Returns distance to nearest detector edge +// +ve = inside +// -ve = outside +void +SCT_BarrelModuleSideDesign::distanceToDetectorEdge(const SiLocalPosition & localPosition, + double & etaDist, double & phiDist) const +{ + // As the calculation is symmetric around 0,0 we only have to test it for one side. + double xEta = abs(localPosition.xEta() - m_xEtaStripPatternCentre); + double xPhi = abs(localPosition.xPhi() - m_xPhiStripPatternCentre); + + double xEtaEdge = 0.5 * length(); + double xPhiEdge = 0.5 * width(); + + // Distance to top/bottom + etaDist = xEtaEdge - xEta; + + // Distance to right/left edge + phiDist = xPhiEdge - xPhi; + +} + + +bool SCT_BarrelModuleSideDesign::nearBondGap(const SiLocalPosition & localPosition, double etaTol) const +{ + // Symmetric around xEta = 0 so we can use absolute value. + if (m_totalDeadLength==0) return false; + return ( abs(localPosition.xEta()) < 0.5*m_totalDeadLength + etaTol); +} + +// check if the position is in active area +bool SCT_BarrelModuleSideDesign::inActiveArea(const SiLocalPosition &chargePos, + bool checkBondGap) const +{ + // in Phi + if (abs(chargePos.xPhi()-m_xPhiStripPatternCentre) > m_xPhiAbsSize) return false; + + // in Eta + double relEta = fabs(chargePos.xEta() - m_xEtaStripPatternCentre); + if (relEta > m_xEtaAbsSizeHigh) return false; + + // bond gap + return !(checkBondGap && (relEta < m_xEtaAbsSizeLow)); +} + + +// distance to the nearest diode in units of pitch, from 0.0 to 0.5, +// this method should be fast as it is called for every surface charge +// in the SCT_SurfaceChargesGenerator +// an active area check, done in the Generator anyway, is removed here +double SCT_BarrelModuleSideDesign::scaledDistanceToNearestDiode(const SiLocalPosition &chargePos) const +{ + double dstrip=fabs(chargePos.xPhi()-m_xPhiStripPatternCentre)/m_stripPitch; + dstrip=dstrip-static_cast<double>(int(dstrip))-0.5; + // the above -0.5 is because we have an even number of strips, centre of detector + // is in the middle of an interstrip gap + return fabs(dstrip); +} + +std::pair<SiLocalPosition,SiLocalPosition> SCT_BarrelModuleSideDesign::endsOfStrip(const SiLocalPosition &position) const +{ + // this method returns the ends of the strip + // assume input xPhi + + SiLocalPosition end1(m_xEtaStripPatternCentre+m_xEtaAbsSizeHigh,position.xPhi()); + SiLocalPosition end2(m_xEtaStripPatternCentre-m_xEtaAbsSizeHigh,position.xPhi()); + + std::pair<SiLocalPosition,SiLocalPosition> two_ends(end1,end2); + return two_ends; +} + + +double SCT_BarrelModuleSideDesign::length() const +{ + return crystals()*m_stripLength+m_totalDeadLength; +} + +double SCT_BarrelModuleSideDesign::width() const +{ + return m_stripPitch*diodes(); +} + +double SCT_BarrelModuleSideDesign::minWidth() const +{ + return width(); +} + +double SCT_BarrelModuleSideDesign::maxWidth() const +{ + return width(); +} + + +// method for stereo angle computation - returns a vector parallel to the +// strip being hit +HepGeom::Vector3D<double> SCT_BarrelModuleSideDesign::phiMeasureSegment(const SiLocalPosition& ) const +{ + HepGeom::Vector3D<double> segment; + segment[etaAxis()]=1; + return segment; +} + +// give length of dead area +double SCT_BarrelModuleSideDesign::deadAreaLength() const +{ + return m_totalDeadLength; +} + +// give upper boundary of dead area (origin in module centre) +double SCT_BarrelModuleSideDesign::deadAreaUpperBoundary() const +{ + return m_totalDeadLength/2; +} +// give lower boundary of dead area (origin in module centre) +double SCT_BarrelModuleSideDesign::deadAreaLowerBoundary() const +{ + return -m_totalDeadLength/2; +} + + + +SiLocalPosition +SCT_BarrelModuleSideDesign::localPositionOfCell(const SiCellId & cellId) const +{ + + // NB. No check is made that cellId is valid or in the correct range. + + int strip = cellId.strip(); + + // center of cluster (in units of number of strips) from detector center + double clusterCenter = strip - 0.5*cells() + 0.5; + + double xPhi=m_xPhiStripPatternCentre + m_stripPitch * clusterCenter; + + // Return the position. + // no matter how many crystals we have, xEta of the position is in the centre! + return SiLocalPosition(m_xEtaStripPatternCentre, xPhi); +} + +SiLocalPosition +SCT_BarrelModuleSideDesign::localPositionOfCluster(const SiCellId & cellId, int clusterSize) const +{ + // This method returns the position of the centre of the cluster starting at cellId.strip() + + // NB. No check is made that cellId is valid or in the correct range. + + if (clusterSize < 1) clusterSize = 1; + + int strip = cellId.strip(); + + // center of cluster (in units of number of strips) from detector center + double clusterCenter = strip - 0.5*cells() + 0.5; + if (clusterSize>1) clusterCenter += 0.5 * (clusterSize-1); + + double xPhi=m_xPhiStripPatternCentre + m_stripPitch * clusterCenter; + + // Return the position. + // no matter how many crystals we have, xEta of the position is in the centre! + return SiLocalPosition(m_xEtaStripPatternCentre, xPhi); +} + + +SiDiodesParameters +SCT_BarrelModuleSideDesign::parameters(const SiCellId & cellId) const +{ + // NB. We treat the two crytals as one. + SiLocalPosition center=localPositionOfCell(cellId); + double xPhiSize=m_stripPitch; + double xEtaSize=2*m_xEtaAbsSizeHigh; + SiLocalPosition width(xEtaSize,xPhiSize); + return SiDiodesParameters(center,width); +} + +SiCellId +SCT_BarrelModuleSideDesign::cellIdOfPosition(const SiLocalPosition & localPosition) const +{ + // NB We do not distinguish between the two crystals anymore. + // Check if we are in the active region. No bondgap check. + if (!inActiveArea(localPosition, false)) return SiCellId(); // return an invalid id + double xPhi=localPosition.xPhi(); + double dstrip=(xPhi-m_xPhiStripPatternCentre)/m_stripPitch+0.5*diodes(); + if (dstrip < 0) return SiCellId(); // return an invalid id + int strip = static_cast<int>(dstrip); + if (strip > diodes()) return SiCellId();// return an invalid id if strip # greater than number of diodes. + return SiCellId(strip-shift()); // strip numbering starts from first readout strip. + // Those to the left will have negative numbers. + +} + +const Trk::SurfaceBounds & +SCT_BarrelModuleSideDesign::bounds() const +{ + return *m_bounds; +} + +} // namespace InDetDD diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SCT_DetectorManager.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SCT_DetectorManager.cxx new file mode 100755 index 0000000000000000000000000000000000000000..c3f95f8b098aeecf98c244b9ebb276338800dfcd --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SCT_DetectorManager.cxx @@ -0,0 +1,316 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "InDetReadoutGeometry/SCT_DetectorManager.h" +#include "InDetIdentifier/SCT_ID.h" +#include "Identifier/Identifier.h" +#include "Identifier/IdentifierHash.h" +#include "InDetReadoutGeometry/SiDetectorElementCollection.h" +#include "InDetReadoutGeometry/SiDetectorElement.h" +#include "InDetReadoutGeometry/ExtendedAlignableTransform.h" +#include "InDetReadoutGeometry/SCT_ModuleSideDesign.h" +#include "StoreGate/StoreGateSvc.h" + +#include "GeoPrimitives/CLHEPtoEigenConverter.h" + +#include <iostream> +namespace InDetDD { + + const int FIRST_HIGHER_LEVEL = 2; + + SCT_DetectorManager::SCT_DetectorManager( StoreGateSvc* detStore ) + : SiDetectorManager(detStore, "SCT"), + m_idHelper(0) + { + // + // Initialized the Identifier helper. + // + StatusCode sc = detStore->retrieve(m_idHelper, "SCT_ID"); + if (sc.isFailure() ) { + msg(MSG::ERROR) << "Could not retrieve SCT id helper" << endreq; + } + // Initialize the collections. + if (m_idHelper) { + m_elementCollection.resize(m_idHelper->wafer_hash_max()); + m_alignableTransforms.resize(m_idHelper->wafer_hash_max()); + m_moduleAlignableTransforms.resize(m_idHelper->wafer_hash_max()/2); + } + } + + + SCT_DetectorManager::~SCT_DetectorManager() + { + // Clean up + SiDetectorElementCollection::iterator iter; + for (iter = m_elementCollection.begin(); iter != m_elementCollection.end(); ++iter){ + delete *iter; + } + + for (size_t i=0; i < m_volume.size(); i++) { + m_volume[i]->unref(); + } + + for (size_t j=0; j < m_higherAlignableTransforms.size(); j++){ + AlignableTransformMap::iterator iterMap; + for (iterMap = m_higherAlignableTransforms[j].begin(); + iterMap != m_higherAlignableTransforms[j].end(); + ++iterMap) { + delete iterMap->second; + } + } + + for (size_t k=0; k < m_alignableTransforms.size(); k++){ + delete m_alignableTransforms[k]; + } + + for (size_t l=0; l < m_moduleAlignableTransforms.size(); l++){ + delete m_moduleAlignableTransforms[l]; + } + } + + unsigned int SCT_DetectorManager::getNumTreeTops() const + { + return m_volume.size(); + } + + PVConstLink SCT_DetectorManager::getTreeTop(unsigned int i) const + { + return m_volume[i]; + } + + void SCT_DetectorManager::addTreeTop(PVLink vol){ + vol->ref(); + m_volume.push_back(vol); + } + + + SiDetectorElement* SCT_DetectorManager::getDetectorElement(const Identifier & id) const + { + // NB the id helpers implementation for getting a hash is not optimal. + // Essentially does a binary search. + // Make sure it is a wafer Id + Identifier waferId = m_idHelper->wafer_id(id); + IdentifierHash idHash = m_idHelper->wafer_hash(waferId); + if (idHash.is_valid()) { + return m_elementCollection[idHash]; + } else { + return 0; + } + } + + SiDetectorElement* SCT_DetectorManager::getDetectorElement(const IdentifierHash & idHash) const + { + return m_elementCollection[idHash]; + } + + SiDetectorElement* SCT_DetectorManager::getDetectorElement(int barrel_endcap, int layer_wheel, int phi_module, int eta_module, int side) const + { + return getDetectorElement(m_idHelper->wafer_id(barrel_endcap, layer_wheel, phi_module, eta_module, side)); + } + + + const SiDetectorElementCollection* SCT_DetectorManager::getDetectorElementCollection() const + { + return &m_elementCollection; + } + + SiDetectorElementCollection::const_iterator SCT_DetectorManager::getDetectorElementBegin() const + { + return m_elementCollection.begin(); + } + + SiDetectorElementCollection::const_iterator SCT_DetectorManager::getDetectorElementEnd() const + { + return m_elementCollection.end(); + } + + + void SCT_DetectorManager::addDetectorElement(SiDetectorElement * element) + { + IdentifierHash idHash = element->identifyHash(); + if (idHash >= m_elementCollection.size()) + throw std::runtime_error("SCT_DetectorManager: Error adding detector element."); + m_elementCollection[idHash] = element; + } + + void SCT_DetectorManager::initNeighbours() + { + SiDetectorElementCollection::iterator iter; + + // Loop over all elements and set the neighbours + for (iter = m_elementCollection.begin(); iter != m_elementCollection.end(); ++iter){ + + SiDetectorElement * element = *iter; + if (element) { + + IdentifierHash idHash = element->identifyHash(); + IdentifierHash idHashOther; + + int result; + // If no neighbour, result != 0 in which case we leave neighbour as null + result = m_idHelper->get_next_in_eta(idHash, idHashOther); + if (result==0) element->setNextInEta(m_elementCollection[idHashOther]); + + result = m_idHelper->get_prev_in_eta(idHash, idHashOther); + if (result==0) element->setPrevInEta(m_elementCollection[idHashOther]); + + result = m_idHelper->get_next_in_phi(idHash, idHashOther); + if (result==0) element->setNextInPhi(m_elementCollection[idHashOther]); + + result = m_idHelper->get_prev_in_phi(idHash, idHashOther); + if (result==0) element->setPrevInPhi(m_elementCollection[idHashOther]); + + result = m_idHelper->get_other_side(idHash, idHashOther); + if (result==0) element->setOtherSide(m_elementCollection[idHashOther]); + } + } + } + + + const SCT_ID* SCT_DetectorManager::getIdHelper() const + { + return m_idHelper; + } + + + bool SCT_DetectorManager::setAlignableTransformDelta(int level, + const Identifier & id, + const Amg::Transform3D & delta, + FrameType frame) const + { + + if (level == 0) { // 0 - At the element level + + // We retrieve it via a hashId. + IdentifierHash idHash = m_idHelper->wafer_hash(id); + if (!idHash.is_valid()) return false; + + if (frame == InDetDD::global) { // global shift + // Its a global transform + return setAlignableTransformGlobalDelta(m_alignableTransforms[idHash], delta); + + } else if (frame == InDetDD::local) { // local shift + + const SiDetectorElement * element = m_elementCollection[idHash]; + if (!element) return false; + + // Its a local transform + return setAlignableTransformLocalDelta(m_alignableTransforms[idHash], element->transform(), delta); + + } else { + // other not supported + msg(MSG::WARNING) << "Frames other than global or local are not supported." << endreq; + return false; + } + + } else if (level == 1) { // module level + + // We retrieve it via a hashId. + IdentifierHash idHash = m_idHelper->wafer_hash(id); + if (!idHash.is_valid()) return false; + + int idModuleHash = idHash / 2; + + if (idHash%2) { + msg(MSG::WARNING) << "Side 1 wafer id used for module id" << endreq; + return false; + } + + if (frame == InDetDD::global) { // global shift + // Its a global transform + return setAlignableTransformGlobalDelta(m_moduleAlignableTransforms[idModuleHash], delta); + } else if (frame == InDetDD::local) { // local shift + const SiDetectorElement * element = m_elementCollection[idHash]; + if (!element) return false; + // Its a local transform + return setAlignableTransformLocalDelta(m_moduleAlignableTransforms[idModuleHash],element->defModuleTransform(), delta); + + } else { + // other not supported + msg(MSG::WARNING) << "Frames other than global or local are not supported." << endreq; + return false; + } + + } else { // higher level + + if (frame != InDetDD::global) { + msg(MSG::WARNING) << "Non global shift at higher levels is not supported." << endreq; + return false; + } + + int index = level - FIRST_HIGHER_LEVEL; // level 0 and 1 is treated separately. + if (index >= static_cast<int>(m_higherAlignableTransforms.size())) return false; + + // We retrieve it from a map. + AlignableTransformMap::const_iterator iter; + iter = m_higherAlignableTransforms[index].find(id); + if (iter == m_higherAlignableTransforms[index].end()) return false; + + // Its a global transform + return setAlignableTransformGlobalDelta(iter->second, delta); + } + + } + + void SCT_DetectorManager::addAlignableTransform (int level, + const Identifier & id, + GeoAlignableTransform *transform, + const GeoVPhysVol * child) + { + if (m_idHelper) { + + const GeoVFullPhysVol * childFPV = dynamic_cast<const GeoVFullPhysVol *>(child); + if (!childFPV) { + msg(MSG::ERROR) << "Child of alignable transform is not a full physical volume" + << endreq; + } else { + addAlignableTransform (level, id, transform, childFPV); + } + } + } + + void SCT_DetectorManager::addAlignableTransform (int level, + const Identifier & id, + GeoAlignableTransform *transform, + const GeoVFullPhysVol * child) + { + if (m_idHelper) { + if (level == 0) { + // Element + IdentifierHash idHash = m_idHelper->wafer_hash(id); + if (idHash.is_valid()) { + m_alignableTransforms[idHash]= new ExtendedAlignableTransform(transform, child); + } + } else if (level == 1) { + // Module + IdentifierHash idHash = m_idHelper->wafer_hash(id); + if (idHash.is_valid()) { + m_moduleAlignableTransforms[idHash/2]=new ExtendedAlignableTransform(transform, child); + } + + } else { + + // Higher levels are saved in a map. NB level=0,1 is treated above. + int index = level - FIRST_HIGHER_LEVEL; // level 0 and 1 is treated separately. + if (index >= static_cast<int>(m_higherAlignableTransforms.size())) m_higherAlignableTransforms.resize(index+1); + m_higherAlignableTransforms[index][id] = new ExtendedAlignableTransform(transform, child); + } + } + } + + bool + SCT_DetectorManager::identifierBelongs(const Identifier & id) const + { + return getIdHelper()->is_sct(id); + } + + + const SCT_ModuleSideDesign* SCT_DetectorManager::getSCT_Design(int i) const + { + return dynamic_cast<const SCT_ModuleSideDesign *>(getDesign(i)); + } + + + +} // namespace InDetDD diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SCT_ForwardFrameTransformation.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SCT_ForwardFrameTransformation.cxx new file mode 100755 index 0000000000000000000000000000000000000000..518a47fdb04138d42a788e6177a89560d110c32a --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SCT_ForwardFrameTransformation.cxx @@ -0,0 +1,70 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SCT_ForwardFrameTransformation.cxx +// Implementation file for class SCT_ForwardFrameTransformation +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// +// Version 1.4 09/7/2001 Alessandro Fornaini +/////////////////////////////////////////////////////////////////// + +#include "InDetReadoutGeometry/SCT_ForwardFrameTransformation.h" +#include "InDetReadoutGeometry/SCT_ForwardPolarPosition.h" +#include "InDetReadoutGeometry/SiLocalPosition.h" +#include <cmath> + +namespace InDetDD { + +// Copy constructor: +SCT_ForwardFrameTransformation::SCT_ForwardFrameTransformation(const SCT_ForwardFrameTransformation &frame) : + m_etaCenter(frame.m_etaCenter), + m_phiCenter(frame.m_phiCenter), + m_radius(frame.m_radius) +{} + +// Constructor with parameters: +SCT_ForwardFrameTransformation::SCT_ForwardFrameTransformation(const double etaCenter,const double phiCenter,const double radius) : + m_etaCenter(etaCenter), + m_phiCenter(phiCenter), + m_radius(radius) +{ + //check if parameters are consistent + if (m_radius<0) m_radius=0; +} + + +// Assignment operator: +SCT_ForwardFrameTransformation &SCT_ForwardFrameTransformation::operator=(const SCT_ForwardFrameTransformation &frame) +{ + if (this!=&frame) { + m_etaCenter=frame.m_etaCenter; + m_phiCenter=frame.m_phiCenter; + m_radius=frame.m_radius; + } else {} + return *this; +} + + +// create a SCT_ForwardPolarPosition from a SiLocalPosition +SCT_ForwardPolarPosition SCT_ForwardFrameTransformation::polarFromCartesian(const SiLocalPosition &cartesian) const +{ + const double deltaPhi = cartesian.xPhi()-m_phiCenter; + const double deltaEta = cartesian.xEta()-m_etaCenter+m_radius; + const double r = sqrt(deltaPhi*deltaPhi+deltaEta*deltaEta); + if (r<=0) return SCT_ForwardPolarPosition(); + const double theta = asin((cartesian.xPhi()-m_phiCenter)/r); + return SCT_ForwardPolarPosition(r,theta); +} + +// create a SiLocalPosition from a SCT_ForwardPolarPosition +SiLocalPosition SCT_ForwardFrameTransformation::cartesianFromPolar(const SCT_ForwardPolarPosition &polar) const +{ + const double phi = m_phiCenter + polar.r()*sin(polar.theta()); + const double eta = m_etaCenter + polar.r()*cos(polar.theta()) - m_radius; + return SiLocalPosition(eta, phi); +} + +} // namespace InDetDD diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SCT_ForwardModuleSideDesign.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SCT_ForwardModuleSideDesign.cxx new file mode 100755 index 0000000000000000000000000000000000000000..b7f21ec2df4daeba549ad22f8d32ca2f01f78285 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SCT_ForwardModuleSideDesign.cxx @@ -0,0 +1,285 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SCT_ForwardModuleSideDesign.cxx +// Implementation file for class SCT_ForwardModuleSideDesign +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// +// Version 1.16 29/10/2001 Alessandro Fornaini +// Modified: Grant Gorfine +/////////////////////////////////////////////////////////////////// + +#include "InDetReadoutGeometry/SCT_ForwardModuleSideDesign.h" +#include "CLHEP/Units/SystemOfUnits.h" +#include "CLHEP/Geometry/Vector3D.h" +#include "InDetReadoutGeometry/SiDiodesParameters.h" +#include "TrkSurfaces/TrapezoidBounds.h" + +namespace InDetDD { + +// Constructor with parameters: +SCT_ForwardModuleSideDesign::SCT_ForwardModuleSideDesign(const double thickness, + const int crystals, + const int diodes, + const int cells, + const int shift, + const bool swapStripReadout, + InDetDD::CarrierType carrierType, + const double radius1, + const double halfHeight1, + const double radius2, + const double halfHeight2, + const double step, + const double etaCenter, + const double phiCenter, + int readoutSide) : + SCT_ModuleSideDesign(thickness, + true, // phi + false, // eta: For trapezoid we cant swap z (xEta) axis. + true, // depth + crystals,diodes,cells,shift,swapStripReadout,carrierType,readoutSide), + m_geometry(radius1,halfHeight1,radius2,halfHeight2,diodes,step,crystals), + m_frame(etaCenter,phiCenter,radius1) +{ + if (crystals > 1) { + double radius = 0.5 * (radius1 + radius2 + halfHeight2 - halfHeight1); + m_frame=SCT_ForwardFrameTransformation(etaCenter,phiCenter,radius); + } + m_bounds = new Trk::TrapezoidBounds(0.5*minWidth(), 0.5*maxWidth(), 0.5*length()); +} + +// Destructor: +SCT_ForwardModuleSideDesign::~SCT_ForwardModuleSideDesign() +{ + delete m_bounds; +} + +void +SCT_ForwardModuleSideDesign::distanceToDetectorEdge(const SiLocalPosition & localPosition, + double & etaDist, double & phiDist) const +{ + m_geometry.distanceToDetectorEdge(localPosition, + m_frame.polarFromCartesian(localPosition), + etaDist, phiDist); +} + +bool +SCT_ForwardModuleSideDesign::nearBondGap(const SiLocalPosition & localPosition, double etaTol) const +{ + return m_geometry.nearBondGap(localPosition, etaTol); +} + +// check if the position is in active area +bool SCT_ForwardModuleSideDesign::inActiveArea(const SiLocalPosition &chargePos, bool checkBondGap) const +{ + //const SCT_ForwardPolarPosition polar=m_frame.polarFromCartesian(chargePos); + //return m_geometry.inActiveArea(m_frame.polarFromCartesian(chargePos)); + return m_geometry.inActiveArea(chargePos, checkBondGap); +} + +// give distance to the nearest diode in units of pitch, from 0.0 to 0.5, +// this method should be fast as it is called for every surface charge +// in the SCT_SurfaceChargesGenerator +double SCT_ForwardModuleSideDesign::scaledDistanceToNearestDiode(const SiLocalPosition &chargePos) const +{ + const SCT_ForwardPolarPosition polar=m_frame.polarFromCartesian(chargePos); + return m_geometry.scaledDistanceToNearestDiode(polar);; +} + + +// give the strip pitch (dependence on position needed for forward) +double SCT_ForwardModuleSideDesign::stripPitch(const SiLocalPosition & chargePos) const +{ + const SCT_ForwardPolarPosition polar=m_frame.polarFromCartesian(chargePos); + // No longer make inActive check + // if (!m_geometry.inActiveArea(polar)) return 0; + return m_geometry.stripPitch(polar); +} + +// give the strip pitch (dependence on position needed for forward) +double SCT_ForwardModuleSideDesign::stripPitch() const +{ + // Use center. + const SCT_ForwardPolarPosition polarCenter(m_frame.radius(), 0); + // No longer make inActive check + // if (!m_geometry.inActiveArea(polar)) return 0; + return m_geometry.stripPitch(polarCenter); +} + + + +// this method returns the extremities of a strip passing by the point +std::pair<SiLocalPosition,SiLocalPosition> SCT_ForwardModuleSideDesign::endsOfStrip(const SiLocalPosition &position) const +{ + const SCT_ForwardPolarPosition polarPosition = + m_frame.polarFromCartesian(position); + const double theta = polarPosition.theta(); + const double innerRadius = (m_geometry.radius1()-m_geometry.halfHeight1())/cos(theta); + double outerRadius; + if (crystals()==1) { + outerRadius = (m_geometry.radius1()+m_geometry.halfHeight1())/cos(theta); + } else { + outerRadius = (m_geometry.radius2()+m_geometry.halfHeight2())/cos(theta); + } + const SCT_ForwardPolarPosition innerPointPolar = SCT_ForwardPolarPosition(innerRadius,theta); + const SCT_ForwardPolarPosition outerPointPolar = SCT_ForwardPolarPosition(outerRadius,theta); + const SiLocalPosition innerPoint = m_frame.cartesianFromPolar(innerPointPolar); + const SiLocalPosition outerPoint = m_frame.cartesianFromPolar(outerPointPolar); + + return std::pair<SiLocalPosition,SiLocalPosition>(innerPoint,outerPoint); +} + + +// method for stereo angle computation - returns a vector parallel to the +// strip being hit +HepGeom::Vector3D<double> SCT_ForwardModuleSideDesign::phiMeasureSegment(const SiLocalPosition &position) const +{ + const SCT_ForwardPolarPosition secondPolarPosition(0,0); + const SiLocalPosition secondPosition = m_frame.cartesianFromPolar(secondPolarPosition); + + HepGeom::Vector3D<double> notUnitVector; + notUnitVector[phiAxis()]=position.xPhi()-secondPosition.xPhi(); + notUnitVector[etaAxis()]=position.xEta()-secondPosition.xEta(); + + return notUnitVector.unit(); +} + +double SCT_ForwardModuleSideDesign::length() const +{ + return m_geometry.length(); +} + +double SCT_ForwardModuleSideDesign::width() const +{ + return m_geometry.width(); +} + +double SCT_ForwardModuleSideDesign::minWidth() const +{ + return m_geometry.minWidth(); +} + +double SCT_ForwardModuleSideDesign::maxWidth() const +{ + return m_geometry.maxWidth(); +} + +double SCT_ForwardModuleSideDesign::deadAreaLength() const +{ + return m_geometry.deadAreaLength(); +} + +double SCT_ForwardModuleSideDesign::deadAreaUpperBoundary() const +{ + return m_geometry.deadAreaUpperBoundary(); +} + +double SCT_ForwardModuleSideDesign::deadAreaLowerBoundary() const +{ + return m_geometry.deadAreaLowerBoundary(); +} + +//this method returns the position of the centre of a strips +SiLocalPosition +SCT_ForwardModuleSideDesign::localPositionOfCell(const SiCellId & cellId) const +{ + // This method returns the position of the centre of the cell + + // NB. No check is made that cellId is valid or in the correct range. + + int strip = cellId.strip(); + + double clusterCenter = strip - 0.5*cells() + 0.5; + + const double theta = m_geometry.angularPitch()*clusterCenter; + const double r = radius() / cos(theta); + + // positions in polar coordinates and then cartesian + const SCT_ForwardPolarPosition polarPosition(r, theta); + return m_frame.cartesianFromPolar(polarPosition); +} + +//this method returns the position of the centre of the cluster of strips +SiLocalPosition +SCT_ForwardModuleSideDesign::localPositionOfCluster(const SiCellId & cellId, + int clusterSize) const +{ + // This method returns the position of the centre of the cluster starting at cellId.strip() + + // NB. No check is made that cellId is valid or in the correct range. + + if (clusterSize < 1) clusterSize = 1; + + int strip = cellId.strip(); + + double clusterCenter = strip - 0.5*cells() + 0.5; + if (clusterSize>1) clusterCenter += 0.5 * (clusterSize-1); + + const double theta = angularPitch()*clusterCenter; + const double r = radius() / cos(theta); + + // positions in polar coordinates and then cartesian + const SCT_ForwardPolarPosition polarPosition(r,theta); + return m_frame.cartesianFromPolar(polarPosition); +} + +SiDiodesParameters +SCT_ForwardModuleSideDesign::parameters(const SiCellId & cellId) const +{ + int strip = cellId.strip(); + + double clusterCenter = strip - 0.5*cells() + 0.5; + + const double theta = m_geometry.angularPitch()*clusterCenter; + const double r = radius() / cos(theta); + + // positions in polar coordinates and then cartesian + const SCT_ForwardPolarPosition polarPosition(r, theta); + SiLocalPosition center = m_frame.cartesianFromPolar(polarPosition); + + // The strip is not rectangular put we return pitch at radius. + double stripWidth = angularPitch()*r; + double stripLength = length() / cos(theta); + + SiLocalPosition width(stripLength, stripWidth); + return SiDiodesParameters(center, width); +} + + +SiCellId +SCT_ForwardModuleSideDesign::cellIdOfPosition(const SiLocalPosition & localPosition) const +{ + // NB We do not distinguish between the two crystals anymore. + // Check if we are in the active region. No bondgap check. + if (!inActiveArea(localPosition, false)) return SiCellId(); // return an invalid id + + const SCT_ForwardPolarPosition polar = m_frame.polarFromCartesian(localPosition); + double theta = polar.theta(); + + double dstrip = theta/angularPitch() + 0.5*diodes(); + + if (dstrip < 0) return SiCellId(); // return an invalid id + int strip = static_cast<int>(dstrip); + if (strip > diodes()) return SiCellId();// return an invalid id if strip # greater + // than number of diodes. + return SiCellId(strip-shift()); // strip numbering starts from first readout strip. + // Those to the left will have negative numbers. +} + + +DetectorShape +SCT_ForwardModuleSideDesign::shape() const +{ + return InDetDD::Trapezoid; +} + +const Trk::SurfaceBounds & +SCT_ForwardModuleSideDesign::bounds() const +{ + return *m_bounds; +} + +} // namespace InDetDD diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SCT_ForwardModuleSideGeometry.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SCT_ForwardModuleSideGeometry.cxx new file mode 100755 index 0000000000000000000000000000000000000000..f6298d8125f7a60a57d2e03da34a0a26cc25988b --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SCT_ForwardModuleSideGeometry.cxx @@ -0,0 +1,221 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SCT_ForwardModuleSideGeometry.cxx +// Implementation file for class SCT_ForwardModuleSideGeometry +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// +// Version 1.6 09/7/2001 Alessandro Fornaini +/////////////////////////////////////////////////////////////////// + +#include "InDetReadoutGeometry/SCT_ForwardModuleSideGeometry.h" +#include <cmath> + +namespace InDetDD { + +using std::abs; + +// Constructor with parameters: +SCT_ForwardModuleSideGeometry::SCT_ForwardModuleSideGeometry(const double radius1, + const double halfHeight1, + const double radius2, + const double halfHeight2, + const int strips, + const double step, + const int nCrystals ) : + m_radius1(radius1), + m_halfHeight1(halfHeight1), + m_radius2(radius2), + m_halfHeight2(halfHeight2), + m_strips(strips), + m_step(step) , + m_nCrystals(nCrystals), + m_leftSide(step*strips*(-0.5)), + m_rightSide(step*strips*0.5), + m_upperSide1(radius1+halfHeight1), + m_lowerSide1(radius1-halfHeight1), + m_upperSide2(radius2+halfHeight2), + m_lowerSide2(radius2-halfHeight2) + + +{ + if (m_radius1<0) m_radius1=0.0; + if (m_halfHeight1<0) m_halfHeight1=0.0; + if (m_radius2<0) m_radius2=0.0; + if (m_halfHeight2<0) m_halfHeight2=0.0; + if (m_strips<0) m_strips=0; + if (m_step<0) m_step=0.0; + if (m_nCrystals==0) m_nCrystals=1; + if (m_nCrystals<2) { + m_radius2=0; + m_halfHeight2=0; + } + + if (m_nCrystals==1) { + m_radius = m_radius1; + m_halfLength = m_halfHeight1; + } else { + m_radius = 0.5 * (m_radius1 + m_radius2 + m_halfHeight2 - m_halfHeight1); + m_halfLength = 0.5 * (m_radius2 + m_halfHeight2 - m_radius1 + m_halfHeight1); + } + + m_tangent = tan(m_rightSide); + + if (m_nCrystals==1) { + m_deadRegionUpper = 0; + m_deadRegionLower = 0; + } else { + m_deadRegionUpper = m_radius2 - m_halfHeight2 - m_radius; + m_deadRegionLower = m_radius1 + m_halfHeight1 - m_radius; + } + +} + + + +// Returns distance to nearest detector edge +// +ve = inside +// -ve = outside +void +SCT_ForwardModuleSideGeometry::distanceToDetectorEdge(const SiLocalPosition & localPosition, + const SCT_ForwardPolarPosition & polar, + double & etaDist, double & phiDist) const +{ + + // Distance to top/bottom. + // Calculation symmetric around zero so we can use abs. + etaDist = m_halfLength - abs(localPosition.xEta()); + + // For phi distance use r*phiDiff. + phiDist = polar.r() * (m_rightSide - abs(polar.theta())); + +} + + +bool SCT_ForwardModuleSideGeometry::nearBondGap(const SiLocalPosition & localPosition, double etaTol) const +{ + if (m_nCrystals == 1) return false; // No bond gap (eg for truncated middle detectors) + + return ((localPosition.xEta() < m_deadRegionUpper + etaTol ) && + (localPosition.xEta() > m_deadRegionLower - etaTol)); + +} + + +// check if the position is in active area +bool SCT_ForwardModuleSideGeometry::inActiveArea(const SiLocalPosition &chargePos, + bool checkBondGap) const +{ + double xEta = chargePos.xEta(); + double xPhi = chargePos.xPhi(); + + if (abs(xEta) > m_halfLength) return false; + + if (checkBondGap && m_nCrystals > 1) { + // Check if in bond gap + if (xEta > m_deadRegionLower && xEta < m_deadRegionUpper) return false; + } + + // edge at xEta + double edge = (xEta + m_radius) * m_tangent; + + return (abs(xPhi) < edge); +} + +// DEPRECATED +// check if the position is in active area +bool SCT_ForwardModuleSideGeometry::inActiveArea(const SCT_ForwardPolarPosition + &polarPos ) const +{ + bool conditionTheta=false; + bool conditionEtaOne=false; + bool conditionEtaTwo=false; + if (polarPos.r()*cos(polarPos.theta())<m_upperSide1 && + polarPos.r()*cos(polarPos.theta())>m_lowerSide1) + conditionEtaOne=true; + if (polarPos.r()*cos(polarPos.theta())<m_upperSide2 && + polarPos.r()*cos(polarPos.theta())>m_lowerSide2) + conditionEtaTwo=true; + if (polarPos.theta()<m_rightSide && + polarPos.theta()>m_leftSide) conditionTheta=true; + return (conditionEtaOne || conditionEtaTwo) && conditionTheta; +} + +// give the strip pitch (dependence on position needed for forward) +double SCT_ForwardModuleSideGeometry::stripPitch(const SCT_ForwardPolarPosition + &polarPos) const +{ + return 2.0*polarPos.r()*fabs(sin(m_step*0.5)); +} + +// give distance to the nearest diode in units of pitch, from 0.0 to 0.5, +// this method should be fast as it is called for every surface charge +// in the SCT_SurfaceChargesGenerator +double SCT_ForwardModuleSideGeometry::scaledDistanceToNearestDiode(const SCT_ForwardPolarPosition &polarPos) const +{ + int stripIndex; + if (polarPos.theta()>0) stripIndex = + static_cast<int>(polarPos.theta()/m_step); + else stripIndex = static_cast<int>(polarPos.theta()/m_step-1); + const double thetaStrip = (stripIndex+0.5)*m_step; + const double pitch = 2.0*polarPos.r()*fabs(sin(m_step*0.5)); + return polarPos.r()*fabs(sin(polarPos.theta()-thetaStrip))/pitch; +} + +// Method to calculate length of a module +double SCT_ForwardModuleSideGeometry::length() const +{ + return 2 * m_halfLength; +} + +// Method to calculate average width of a module +double SCT_ForwardModuleSideGeometry::width() const +{ + return 2 * m_radius * m_tangent; +} + +// Method to calculate minimum width of a module +double SCT_ForwardModuleSideGeometry::minWidth() const +{ + return 2 * m_lowerSide1 * m_tangent; +} + +// Method to calculate maximum width of a module +double SCT_ForwardModuleSideGeometry::maxWidth() const +{ + if (m_nCrystals==1) { + return 2 * m_upperSide1 * m_tangent; + } + else { + return 2 * m_upperSide2 * m_tangent; + } +} + +// give length of dead area +double SCT_ForwardModuleSideGeometry::deadAreaLength() const +{ + if (m_nCrystals==1) { + return 0; + } else { + return m_deadRegionUpper - m_deadRegionLower; + } + +} + + +// give upper boundary of dead area +double SCT_ForwardModuleSideGeometry::deadAreaUpperBoundary() const +{ + return m_deadRegionUpper; +} + +// give lower boundary of dead area +double SCT_ForwardModuleSideGeometry::deadAreaLowerBoundary() const +{ + return m_deadRegionLower; +} + +} // namespace InDetDD diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SCT_ForwardPolarPosition.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SCT_ForwardPolarPosition.cxx new file mode 100755 index 0000000000000000000000000000000000000000..d41578573c5f32847cb8769482416b0bfe9c9e6f --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SCT_ForwardPolarPosition.cxx @@ -0,0 +1,69 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SCT_ForwardPolarPosition.cxx +// Implementation file for class SCT_ForwardPolarPosition +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// +// Version 1.0a 1/6/2001 Class creator tool +/////////////////////////////////////////////////////////////////// + +#include "InDetReadoutGeometry/SCT_ForwardPolarPosition.h" +#include <new> +#include <sstream> + +namespace InDetDD { + +// Implicit constructor: +SCT_ForwardPolarPosition::SCT_ForwardPolarPosition() : + m_r(0), + m_theta(0) +{} + +// Copy constructor: +SCT_ForwardPolarPosition::SCT_ForwardPolarPosition(const SCT_ForwardPolarPosition &polar) : + m_r(polar.m_r), + m_theta(polar.m_theta) +{} + +// Constructor with parameters: +SCT_ForwardPolarPosition::SCT_ForwardPolarPosition(const double r,const double theta) : + m_r(r), + m_theta(theta) +{ + //check if parameters are consistent + if (m_r<0) m_r=0; +} + +// Destructor: +SCT_ForwardPolarPosition::~SCT_ForwardPolarPosition() +{} + +// Assignment operator: +SCT_ForwardPolarPosition &SCT_ForwardPolarPosition::operator=(const SCT_ForwardPolarPosition &polar) +{ + if (this!=&polar) { + m_r=polar.m_r; + m_theta=polar.m_theta; + } else {} + return *this; +} + +//Comparison operator +bool SCT_ForwardPolarPosition::operator==(const SCT_ForwardPolarPosition &polar) const +{ + return (m_r==polar.m_r && m_theta==polar.m_theta); +} + +//Print method: +std::string SCT_ForwardPolarPosition::print() const +{ + std::ostringstream out; + out<<"r = "<<m_r<<" theta = "<<m_theta; + return out.str(); +} + +} // namespace InDetDD diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SCT_ModuleSideDesign.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SCT_ModuleSideDesign.cxx new file mode 100755 index 0000000000000000000000000000000000000000..7829b5a29a17d4a90fea7840168fcd315fa14542 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SCT_ModuleSideDesign.cxx @@ -0,0 +1,92 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SCT_ModuleSideDesign.cxx +// Implementation file for class SCT_ModuleSideDesign +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// +// Version 1.2 03/7/2001 Alessandro Fornaini +// Modified: Grant Gorfine +/////////////////////////////////////////////////////////////////// + +#include "InDetReadoutGeometry/SCT_ModuleSideDesign.h" +#include "Identifier/Identifier.h" + +namespace InDetDD { + + +// Constructor with parameters: +// local axis corresponding to eta direction +// local axis corresponding to phi direction +// local axis corresponding to depth direction +// thickness of silicon sensor +// number of crystals within module side +// number of diodes within crystal +// number of cells within module side +// index of diode connected to cell with index 0 + + +SCT_ModuleSideDesign::SCT_ModuleSideDesign(const double thickness, + const bool phiSymmetric, + const bool etaSymmetric, + const bool depthSymmetric, + const int crystals, + const int diodes, + const int cells, + const int shift, + const bool swapStripReadout, + InDetDD::CarrierType carrierType, + int readoutSide) : + SiDetectorDesign(thickness, + phiSymmetric, etaSymmetric, depthSymmetric, + carrierType, + readoutSide), + m_scheme(crystals,diodes,cells,shift), + m_swapStripReadout(swapStripReadout) +{} + + + +// Destructor: +SCT_ModuleSideDesign::~SCT_ModuleSideDesign() +{} + + +void SCT_ModuleSideDesign::neighboursOfCell(const SiCellId & cellId, + std::vector<SiCellId> &neighbours) const +{ + neighbours.clear(); + neighbours.reserve(2); + + if (!cellId.isValid()) return; + + int strip = cellId.strip(); + int stripM = strip - 1; + int stripP = strip + 1; + + if(stripM >= m_scheme.shift()) neighbours.push_back(stripM); + if(stripP < m_scheme.diodes()+m_scheme.shift()) neighbours.push_back(stripP); + +} + +// This method returns the position of the centre of a strip +// ALTERNATIVE/PREFERED way is to use localPositionOfCell(const SiCellId & cellId) or +// rawLocalPositionOfCell method in SiDetectorElement. +// DEPRECATED (but used in numerous places) +SiLocalPosition SCT_ModuleSideDesign::positionFromStrip(const int stripNumber) const +{ + return localPositionOfCell(SiCellId(stripNumber)); +} + +/// Check if cell is in range. Returns the original cellId if it is in range, otherwise it returns an invalid id. +SiCellId SCT_ModuleSideDesign::cellIdInRange(const SiCellId & cellId) const +{ + if (!cellId.isValid() || + cellId.strip() <0 || cellId.strip() >= cells()) return SiCellId(); // Invalid + return cellId; +} + +} // namespace InDetDD diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SCT_ReadoutScheme.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SCT_ReadoutScheme.cxx new file mode 100755 index 0000000000000000000000000000000000000000..bfbe2afd05be4cb6d851bdbc9bc0b58fa634cf43 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SCT_ReadoutScheme.cxx @@ -0,0 +1,67 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SCT_ReadoutScheme.cxx +// Implementation file for class SCT_ReadoutScheme +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// +// Version 1.0 23/5/2001 Alessandro Fornaini +// Modified: Grant Gorfine +/////////////////////////////////////////////////////////////////// + +#include "InDetReadoutGeometry/SCT_ReadoutScheme.h" + +namespace InDetDD { + +// Copy constructor: +SCT_ReadoutScheme::SCT_ReadoutScheme(const SCT_ReadoutScheme &scheme) : + m_crystals(scheme.m_crystals), + m_diodes(scheme.m_diodes), + m_cells(scheme.m_cells), + m_shift(scheme.m_shift) +{} + +// Constructor with parameters: +SCT_ReadoutScheme::SCT_ReadoutScheme(const int crystals,const int diodes, + const int cells,const int shift) : + m_crystals(crystals), + m_diodes(diodes), + m_cells(cells), + m_shift(shift) +{ + //check if parameters are consistent + if (m_crystals<1) m_crystals=1; + if (m_diodes<0) m_diodes=0; + if (m_cells<0) m_cells=0; +} + +// Assignment operator: +SCT_ReadoutScheme &SCT_ReadoutScheme::operator=(const SCT_ReadoutScheme &scheme) +{ + if (this!=&scheme) { + m_crystals=scheme.m_crystals; + m_diodes=scheme.m_diodes; + m_cells=scheme.m_cells; + m_shift=scheme.m_shift; + } else {} + return *this; +} + + +// diode id -> readout id +SiReadoutCellId +SCT_ReadoutScheme::readoutIdOfCell(const SiCellId & cellId) const +{ + // readout cell and diode numbering are the same. + // The range can be different due to the unconnected edge strips (if m_shift != 0). + if (!cellId.isValid()) return SiReadoutCellId(); // return an invalid id. + int strip = cellId.strip(); + // I think this should be >= m_cells. But need to check if this has any implications. + if (strip < 0 || strip > m_cells) return SiReadoutCellId(); // return an invalid id. + return SiReadoutCellId(strip); +} + +} // namespace InDetDD diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SiCellId.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SiCellId.cxx new file mode 100755 index 0000000000000000000000000000000000000000..8ac51f4d72dae3762adc9ce21699bb21367f9256 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SiCellId.cxx @@ -0,0 +1,15 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "InDetReadoutGeometry/SiCellId.h" + +std::ostream & operator << (std::ostream & os, const InDetDD::SiCellId & cellId) +{ + if (cellId.isValid()){ + return os << "[" << cellId.phiIndex() << "." << cellId.etaIndex() << "]"; + } else { + return os << "[INVALID]"; + } +} + diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SiCommonItems.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SiCommonItems.cxx new file mode 100755 index 0000000000000000000000000000000000000000..0ad156edd241548d2cc9bbb7d7b19a2fec762fc8 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SiCommonItems.cxx @@ -0,0 +1,48 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "InDetReadoutGeometry/SiCommonItems.h" + +#include "InDetCondServices/ISiLorentzAngleSvc.h" + +namespace InDetDD { + +SiCommonItems::SiCommonItems(const AtlasDetectorID* const idHelper) + : m_msg("SiDetectorElement"), + m_idHelper(idHelper), + m_lorentzAngleSvcHandle("", "SiDetectorElement"), + m_lorentzAngleSvc(0), + m_lorentzAngleSvcInit(false) +{} + +void +SiCommonItems::setSolenoidFrame(const HepGeom::Transform3D & transform) const +{ + m_solenoidFrame = transform; +} + +void +SiCommonItems::setLorentzAngleSvc(const ServiceHandle<ISiLorentzAngleSvc> & lorentzAngleSvc) +{ + m_lorentzAngleSvcHandle = lorentzAngleSvc; +} + +ISiLorentzAngleSvc * +SiCommonItems::lorentzAngleSvc() const +{ + if (!m_lorentzAngleSvcInit) { + if (!m_lorentzAngleSvcHandle.empty()) { + StatusCode sc = m_lorentzAngleSvcHandle.retrieve(); + if (sc.isFailure()) { + msg(MSG::ERROR) << "InDetReadoutGeometry ERROR: Could not locate Lorentz angle service: " << m_lorentzAngleSvcHandle.name() << endreq; + } + } + m_lorentzAngleSvc = &*m_lorentzAngleSvcHandle; + m_lorentzAngleSvcInit = true; + } + return m_lorentzAngleSvc; +} + + +} // End namespace InDetDD diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SiDetectorDesign.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SiDetectorDesign.cxx new file mode 100755 index 0000000000000000000000000000000000000000..28a6f368f6cc38261126f4c821794734ea6b2f75 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SiDetectorDesign.cxx @@ -0,0 +1,102 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SiDetectorDesign.cxx +// Implementation file for class SiDetectorDesign +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// +// Version 3.0 05/05/2001 David Calvet +// Modified: Grant Gorfine +/////////////////////////////////////////////////////////////////// + +#include "InDetReadoutGeometry/SiDetectorDesign.h" +#include "InDetReadoutGeometry/SiIntersect.h" + +namespace InDetDD { + +// Constructor with parameters: +SiDetectorDesign::SiDetectorDesign(double thickness, + bool phiSymmetric, + bool etaSymmetric, + bool depthSymmetric, + InDetDD::CarrierType carrierType, + int readoutSide) : + m_etaAxis(zAxis), + m_phiAxis(yAxis), + m_depthAxis(xAxis), + m_thickness(thickness), + m_carrierType(carrierType), + m_phiSymmetric(phiSymmetric), + m_etaSymmetric(etaSymmetric), + m_depthSymmetric(depthSymmetric), + m_readoutSidePosDepth(readoutSide > 0) + +{} + +// Destructor: +SiDetectorDesign::~SiDetectorDesign() +{} + +SiIntersect +SiDetectorDesign::inDetector(const SiLocalPosition & localPosition, double phiTol, double etaTol) const +{ + double etaDist=0; + double phiDist=0; + + distanceToDetectorEdge(localPosition, etaDist, phiDist); + + SiIntersect state; + + if (phiDist < -phiTol || etaDist < -etaTol) { + state.setOut(); + return state; + } + + if (phiDist > phiTol && etaDist > etaTol) { + state.setIn(); + return state; + } + + // Near boundary. + state.setNearBoundary(); + return state; +} + + + +void SiDetectorDesign::setSymmetry(bool phiSymmetric, bool etaSymmetric, bool depthSymmetric) +{ + // Flags can be changed from true to false but not false to true. + if (m_phiSymmetric) { + m_phiSymmetric = phiSymmetric; + } else if (phiSymmetric) { + std::cout << "SiDetectorDesign: WARNING! Attempt to allow swapping of xPhi axis direction ignored." + << std::endl; + } + + if (m_etaSymmetric) { + m_etaSymmetric = etaSymmetric; + } else if (etaSymmetric) { + std::cout << "SiDetectorDesign: WARNING! Attempt to allow swapping of xEta axis direction ignored." + << std::endl; + } + + if (m_depthSymmetric) { + m_depthSymmetric = depthSymmetric; + } else if (depthSymmetric) { + std::cout << "SiDetectorDesign: WARNING! Attempt to allow swapping of xDepth axis direction ignored." + << std::endl; + } +} + +DetectorShape +SiDetectorDesign::shape() const +{ + // Default is Box. + return InDetDD::Box; +} + +} // namespace InDetDD diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SiDetectorElement.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SiDetectorElement.cxx new file mode 100755 index 0000000000000000000000000000000000000000..75527e3453e11d6e88022d9509aa62988eb9ebd6 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SiDetectorElement.cxx @@ -0,0 +1,1114 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SiDetectorElement.cxx +// Implementation file for class SiDetectorElement +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// +// Authors: Grant Gorfine +// Based on version developed by David Calvet. +/////////////////////////////////////////////////////////////////// + +#include "InDetReadoutGeometry/SiDetectorElement.h" + +#include "InDetIdentifier/PixelID.h" +#include "InDetIdentifier/SCT_ID.h" + +#include "GeoModelKernel/GeoVFullPhysVol.h" +#include "AtlasDetDescr/AtlasDetectorID.h" + +#include "CLHEP/Geometry/Point3D.h" +#include "CLHEP/Geometry/Vector3D.h" +#include "CLHEP/Vector/ThreeVector.h" +#include "CLHEP/Units/PhysicalConstants.h" // for M_PI +#include "CLHEP/Units/SystemOfUnits.h" +//#include "GeoPrimitives/CLHEPtoEigenConverter.h" + +#include "InDetReadoutGeometry/SiCellId.h" +#include "InDetReadoutGeometry/SiReadoutCellId.h" + +#include "InDetReadoutGeometry/SiCommonItems.h" + +#include "TrkSurfaces/PlaneSurface.h" +#include "TrkSurfaces/SurfaceBounds.h" + +#include "InDetCondServices/ISiLorentzAngleSvc.h" + + + +#include <cmath> +#include <cassert> + +namespace InDetDD { + +using Trk::distPhi; +using Trk::distEta; +using Trk::distDepth; + +// Constructor with parameters: +SiDetectorElement::SiDetectorElement(const Identifier &id, + const SiDetectorDesign *design, + const GeoVFullPhysVol *geophysvol, + SiCommonItems * commonItems) : + TrkDetElementBase(geophysvol), + m_id(id), + m_design(design), + m_commonItems(commonItems), + m_nextInEta(0), + m_prevInEta(0), + m_nextInPhi(0), + m_prevInPhi(0), + m_otherSide(0), + m_cacheValid(false), + m_conditionsCacheValid(false), + m_firstTime(true), + m_isStereo(false), + m_tanLorentzAnglePhi(0), + m_tanLorentzAngleEta(0), + m_lorentzCorrection(0), + m_surface(0) +{ + commonConstructor(); +} + +void +SiDetectorElement::commonConstructor() +{ + + if (!m_id.is_valid()) throw std::runtime_error("SiDetectorElement: Invalid identifier"); + + // Set booleans for wether we are pixel/sct barrel/endcap + m_isPixel = getIdHelper()->is_pixel(m_id); + if (!m_isPixel && !getIdHelper()->is_sct(m_id)){ + if(msgLvl(MSG::WARNING)) msg(MSG::WARNING) << "Element id is not for pixel or SCT" << endreq; + } + + // Set IdHash. Also set m_isBarrel. + m_isDBM=false; + if (isPixel()) { + const PixelID* pixelId = dynamic_cast<const PixelID *>(getIdHelper()); + if(pixelId){ + m_isBarrel = pixelId->is_barrel(m_id); + m_idHash = pixelId->wafer_hash(m_id); + + if(pixelId->is_dbm(m_id)){ + m_isBarrel=false; + m_isDBM=true; + } + } + } else { + const SCT_ID* sctId = dynamic_cast<const SCT_ID *>(getIdHelper()); + if(sctId){ + m_isBarrel = sctId->is_barrel(m_id); + m_idHash = sctId->wafer_hash(m_id); + } + } + + if (!m_idHash.is_valid()) throw std::runtime_error("SiDetectorElement: Unable to set IdentifierHash"); + + // Increase the reference count of the SiDetectorDesign objects. + m_design->ref(); + + // Increase the reference count of the SiCommonItems objects. + m_commonItems->ref(); + + // Should we reference count the geophysvol as well? + +} + + +// Destructor: +SiDetectorElement::~SiDetectorElement() +{ + delete m_surface; + + // The design is reference counted so that it will not be deleted until the last element is deleted. + m_design->unref(); + + m_commonItems->unref(); + +} + +void +SiDetectorElement::updateCache() const +{ + + m_cacheValid = true; + + bool firstTimeTmp = m_firstTime; + m_firstTime = false; + + const HepGeom::Transform3D & geoTransform = transformHit(); + + m_centerCLHEP = geoTransform * HepGeom::Point3D<double>(0,0,0); + + m_center = Amg::Vector3D(m_centerCLHEP[0],m_centerCLHEP[1],m_centerCLHEP[2]); + + // + // Determine directions depth, eta and phi axis in reconstruction local frame + // ie depth away from interaction point + // phi in direction of increasing phi + // eta in direction of increasing z in barrel, and increasing r in endcap + // + + // depthAxis, phiAxis, and etaAxis are defined to be x,y,z respectively for all detectors for hit local frame. + // depthAxis, phiAxis, and etaAxis are defined to be z,x,y respectively for all detectors for reco local frame. + static const HepGeom::Vector3D<double> localAxes[3] = { + HepGeom::Vector3D<double>(1,0,0), + HepGeom::Vector3D<double>(0,1,0), + HepGeom::Vector3D<double>(0,0,1) + }; + + static const HepGeom::Vector3D<double> & localHitPhiAxis = localAxes[hitPhi]; // Defined to be same as y axis + static const HepGeom::Vector3D<double> & localHitEtaAxis = localAxes[hitEta]; // Defined to be same as z axis + static const HepGeom::Vector3D<double> & localHitDepthAxis = localAxes[hitDepth]; // Defined to be same as x axis + + static const HepGeom::Vector3D<double> & localRecoPhiAxis = localAxes[distPhi]; // Defined to be same as x axis + static const HepGeom::Vector3D<double> & localRecoEtaAxis = localAxes[distEta]; // Defined to be same as y axis + static const HepGeom::Vector3D<double> & localRecoDepthAxis = localAxes[distDepth]; // Defined to be same as z axis + + // We only need to calculate the rough orientation once. + //For it to change would require extreme unrealistic misalignment changes. + if (firstTimeTmp) { + // Determine the unit vectors in global frame + HepGeom::Vector3D<double> globalDepthAxis(geoTransform * localHitDepthAxis); + HepGeom::Vector3D<double> globalPhiAxis (geoTransform * localHitPhiAxis); + HepGeom::Vector3D<double> globalEtaAxis (geoTransform * localHitEtaAxis); + + // Set the nominal eta,phi,normal and check the actual ones are close to these and determine the sign. + + // unit radial vector + HepGeom::Vector3D<double> unitR(m_center.x(), m_center.y(), 0); + // TODO: Check if r = 0. + unitR.setMag(1); + + HepGeom::Vector3D<double> nominalEta; + HepGeom::Vector3D<double> nominalNormal; + HepGeom::Vector3D<double> nominalPhi(-unitR.y(), unitR.x(), 0); + + // In Barrel like geometry, the etaAxis is along increasing z, and normal is in increasing radial direction. + // In Endcap like geometry, the etaAxis is along increasing r, and normal is in decreasing z direction, + // We base whether it is barrel like or endcap like by the orientation of the local z axis of the + // the element. This allows the use of endcap identifiers in a TB setup. A warning message is issued however if + // the orientation and identifier are not consistent (ie a barrel like orientation with an endcap identifier). + + bool barrelLike = true; + nominalEta.setZ(1); + if (std::abs(globalEtaAxis.dot(nominalEta)) < 0.5) { // Check that it is in roughly the right direction. + barrelLike = false; + } + + if (isBarrel() && !barrelLike) { + if(msgLvl(MSG::WARNING)) msg(MSG::WARNING) << "Element has endcap like orientation with barrel identifier." + << endreq; + } else if (!isBarrel() && barrelLike) { + if(msgLvl(MSG::WARNING)) msg(MSG::WARNING) << "Element has barrel like orientation with endcap identifier." + << endreq; + } + + if (barrelLike) { + nominalEta.setZ(1); + nominalNormal = unitR; + } else { // endcap like + nominalNormal.setZ(-1); + nominalEta = unitR; + } + + // Determine if axes are to have there directions swapped. + + // + // Depth axis. + // + double depthDir = globalDepthAxis.dot(nominalNormal); + m_depthDirection = true; + if (depthDir < 0) { + if (m_design->depthSymmetric()) { + m_depthDirection = false; + } else { + if(msgLvl(MSG::WARNING)) msg(MSG::WARNING) << "Unable to swap local depth axis." << endreq; + } + } + if (std::abs(depthDir) < 0.5) { // Check that it is in roughly the right direction. + msg(MSG::ERROR) << "Orientation of local depth axis does not follow correct convention." << endreq; + // throw std::runtime_error("Orientation of local depth axis does not follow correct convention."); + m_depthDirection = true; // Don't swap. + } + + // + // Phi axis + // + double phiDir = globalPhiAxis.dot(nominalPhi); + m_phiDirection = true; + if (phiDir < 0) { + if (m_design->phiSymmetric()) { + m_phiDirection = false; + } else { + if(msgLvl(MSG::WARNING)) msg(MSG::WARNING) << "Unable to swap local xPhi axis." << endreq; + } + } + + if (std::abs(phiDir) < 0.5) { // Check that it is in roughly the right direction. + msg(MSG::ERROR) << "Orientation of local xPhi axis does not follow correct convention." << endreq; + // throw std::runtime_error("Orientation of local xPhi axis does not follow correct convention."); + m_phiDirection = true; // Don't swap. + } + + // + // Eta axis + // + double etaDir = globalEtaAxis.dot(nominalEta); + m_etaDirection = true; + if (etaDir < 0) { + if (m_design->etaSymmetric()) { + m_etaDirection = false; + } else { + if(msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << "Unable to swap local xEta axis." << endreq; + } + } + if (std::abs(etaDir) < 0.5) { // Check that it is in roughly the right direction. + msg(MSG::ERROR) << "Orientation of local xEta axis does not follow correct convention." << endreq; + // throw std::runtime_error("Orientation of local xEta axis does not follow correct convention."); + m_etaDirection = true; // Don't swap + } + } // end if (m_firstTime) + + + m_transformCLHEP = geoTransform * recoToHitTransform(); + //m_transform = m_commonItems->solenoidFrame() * geoTransform * recoToHitTransform(); + m_transform = Amg::CLHEPTransformToEigen(m_transformCLHEP); + + // Check that local frame is right-handed. (ie transform has no reflection) + // This can be done by checking that the determinant is >0. + if (firstTimeTmp) { // Only need to check this once. + HepGeom::Transform3D & t = m_transformCLHEP; + double det = t(0,0) * (t(1,1)*t(2,2) - t(1,2)*t(2,1)) - + t(0,1) * (t(1,0)*t(2,2) - t(1,2)*t(2,0)) + + t(0,2) * (t(1,0)*t(2,1) - t(1,1)*t(2,0)); + if (det < 0) { + if (m_design->depthSymmetric()) { + if(msgLvl(MSG::DEBUG)) + msg(MSG::DEBUG) << "Local frame is left-handed, Swapping depth axis to make it right handed." + << endreq; + m_depthDirection = !m_depthDirection; + m_transformCLHEP = geoTransform * recoToHitTransform(); + m_transform = Amg::CLHEPTransformToEigen(m_transformCLHEP); + //m_transform = m_commonItems->solenoidFrame() * geoTransform * recoToHitTransform(); + } else { + if(msgLvl(MSG::WARNING)) msg(MSG::WARNING) << "Local frame is left-handed." << endreq; + } + } + } + + + // Initialize various cached members + // The unit vectors + m_normalCLHEP = m_transformCLHEP * localRecoDepthAxis; + m_normal = Amg::Vector3D( m_normalCLHEP[0], m_normalCLHEP[1], m_normalCLHEP[2]); + + + m_phiAxisCLHEP = m_transformCLHEP * localRecoPhiAxis; + m_etaAxisCLHEP = m_transformCLHEP * localRecoEtaAxis; + + m_phiAxis = Amg::Vector3D(m_phiAxisCLHEP[0],m_phiAxisCLHEP[1],m_phiAxisCLHEP[2]); + m_etaAxis = Amg::Vector3D(m_etaAxisCLHEP[0],m_etaAxisCLHEP[1],m_etaAxisCLHEP[2]); + + getExtent(m_minR, m_maxR, m_minZ, m_maxZ, m_minPhi, m_maxPhi); + + // Determin isStereo + if (firstTimeTmp) { + if (isSCT() && m_otherSide) { + double sinStereoThis = std::abs(sinStereo()); + double sinStereoOther = std::abs(m_otherSide->sinStereo()); + if (sinStereoThis == sinStereoOther) { + // If they happend to be equal then set side0 as axial and side1 as stereo. + const SCT_ID* sctId = dynamic_cast<const SCT_ID *>(getIdHelper()); + if(sctId){ + int side = sctId->side(m_id); + m_isStereo = (side == 1); + } + } else { + // set the stereo side as the one with largest absolute sinStereo. + m_isStereo = (sinStereoThis > sinStereoOther); + } + } else { + m_isStereo = false; + } + } + +} + + +void +SiDetectorElement::updateConditionsCache() const +{ + m_conditionsCacheValid = true; + + // + // Lorentz Angle related stuff + // + + if (m_commonItems->lorentzAngleSvc()) { + m_tanLorentzAnglePhi = m_commonItems->lorentzAngleSvc()->getTanLorentzAngle(m_idHash); + m_tanLorentzAngleEta = m_commonItems->lorentzAngleSvc()->getTanLorentzAngleEta(m_idHash); + m_lorentzCorrection = m_commonItems->lorentzAngleSvc()->getLorentzShift(m_idHash); + } else { + // Set to zero + m_tanLorentzAnglePhi = 0; + m_tanLorentzAngleEta = 0; + m_lorentzCorrection = 0; + } +} + + +const HepGeom::Transform3D & +SiDetectorElement::transformHit() const +{ + return getMaterialGeom()->getAbsoluteTransform(); +} + +const Amg::Transform3D & +SiDetectorElement::transform() const +{ + if (!m_cacheValid) updateCache(); + return m_transform; +} + +const HepGeom::Transform3D & +SiDetectorElement::transformCLHEP() const +{ + //if (!m_cacheValid) updateCache(); + //return m_transform; + //stuff to get the CLHEP version of the local to global transform. + if (!m_cacheValid) updateCache(); + return m_transformCLHEP; + +} +const HepGeom::Transform3D +SiDetectorElement::defTransformCLHEP() const +{ + return getMaterialGeom()->getDefAbsoluteTransform() * recoToHitTransform(); +} + +const Amg::Transform3D +SiDetectorElement::defTransform() const +{ + HepGeom::Transform3D tmpTransform = getMaterialGeom()->getDefAbsoluteTransform() * recoToHitTransform(); + return Amg::CLHEPTransformToEigen(tmpTransform); +} + +const HepGeom::Transform3D +SiDetectorElement::recoToHitTransform() const +{ + + // Determine the reconstruction local (LocalPosition) to global transform. + + if (m_firstTime) updateCache(); + + // global = transform * recoLocal + // = transfromHit * hitLocal + // = transformHit * recoToHitTransform * recoLocal + // recoToHitTransform takes recoLocal to hitLocal + // x,y,z -> y,z,x + // equiv to a rotation around Y of 90 deg followed by a rotation around X of 90deg + // + // recoToHit is static as it needs to be calculated once only. + // We use the HepGeom::Transform3D constructor which takes one coordinates system to another where the + // coordinate system is defined by it center and two axes. + // distPhi, distEta are the reco local axes and hitPhi and hitEta are the hit local axes. + // It assume phi, eta, depth makes a right handed system which is the case. + static const HepGeom::Vector3D<double> localAxes[3] = { + HepGeom::Vector3D<double>(1,0,0), + HepGeom::Vector3D<double>(0,1,0), + HepGeom::Vector3D<double>(0,0,1) + }; + static const HepGeom::Transform3D recoToHit(HepGeom::Point3D<double>(0,0,0),localAxes[distPhi],localAxes[distEta], + HepGeom::Point3D<double>(0,0,0),localAxes[hitPhi],localAxes[hitEta]); + + // Swap direction of axis as appropriate + CLHEP::Hep3Vector scale(1,1,1); + if (!m_phiDirection) scale[distPhi] = -1; + if (!m_etaDirection) scale[distEta] = -1; + if (!m_depthDirection) scale[distDepth] = -1; + return recoToHit * HepGeom::Scale3D(scale[0],scale[1],scale[2]); +} + +const Amg::Transform3D & +SiDetectorElement::moduleTransform() const +{ + return (isModuleFrame()) ? transform() : m_otherSide->transform(); +} + + Amg::Transform3D + SiDetectorElement::defModuleTransform() const +{ + return (isModuleFrame()) ? defTransform() : m_otherSide->defTransform(); +} + + +// Take a transform in the local reconstruction and return it in the module frame +// For a given transform l in frame A. The equivalent transform in frame B is +// B.inverse() * A * l * A.inverse() * B +// Here A is the local to global transform of the element and B is the local to global +// transform of the module. +// If we are already in the module frame then there is nothing to do, we just return the +// transform that is input. Otherwise we use the above formula. +Amg::Transform3D +SiDetectorElement::localToModuleFrame(const Amg::Transform3D & localTransform) const +{ + if (isModuleFrame()) { + return localTransform; + } else { + return m_otherSide->transform().inverse() * transform() * localTransform * transform().inverse() * m_otherSide->transform(); + } +} + +Amg::Transform3D +SiDetectorElement::localToModuleTransform() const +{ + if (isModuleFrame()) { + return Amg::Transform3D(); // Identity + } else { + return m_otherSide->transform().inverse() * transform(); + } +} + + +bool +SiDetectorElement::isModuleFrame() const +{ + // The module frame is the axial side. + // NB isStereo returns false for the pixel and so + // isModuleFrame is always true for the pixel. + + return !isStereo(); +} + + +const Amg::Vector3D & +SiDetectorElement::center() const +{ + if (!m_cacheValid) updateCache(); + return m_center; +} + +const Amg::Vector3D & +SiDetectorElement::normal() const +{ + if (!m_cacheValid) updateCache(); + return m_normal; +} + +const HepGeom::Vector3D<double> & +SiDetectorElement::etaAxisCLHEP() const +{ + if (!m_cacheValid) updateCache(); + return m_etaAxisCLHEP; +} + +const HepGeom::Vector3D<double> & +SiDetectorElement::phiAxisCLHEP() const +{ + if (!m_cacheValid) updateCache(); + return m_phiAxisCLHEP; +} + +const Amg::Vector3D & +SiDetectorElement::etaAxis() const +{ + if (!m_cacheValid) updateCache(); + return m_etaAxis; +} + +const Amg::Vector3D & +SiDetectorElement::phiAxis() const +{ + if (!m_cacheValid) updateCache(); + return m_phiAxis; +} + +Amg::Vector2D +SiDetectorElement::hitLocalToLocal(double xEta, double xPhi) const // Will change order to phi,eta +{ + if (!m_cacheValid) updateCache(); + if (!m_etaDirection) xEta = -xEta; + if (!m_phiDirection) xPhi = -xPhi; + return Amg::Vector2D(xPhi, xEta); +} + +HepGeom::Point3D<double> +SiDetectorElement::hitLocalToLocal3D(const HepGeom::Point3D<double> & hitPosition) const +{ + // Equiv to transform().inverse * transformHit() * hitPosition + if (!m_cacheValid) updateCache(); + double xDepth = hitPosition[hitDepth]; + double xPhi = hitPosition[hitPhi]; + double xEta = hitPosition[hitEta]; + if (!m_depthDirection) xDepth = -xDepth; + if (!m_phiDirection) xPhi = -xPhi; + if (!m_etaDirection) xEta = -xEta; + return HepGeom::Point3D<double>(xPhi, xEta, xDepth); +} + + +bool SiDetectorElement::isPixel() const +{ + return m_isPixel; +} + +bool SiDetectorElement::isSCT() const +{ + return !m_isPixel; +} + +bool SiDetectorElement::isBarrel() const +{ + return m_isBarrel; +} + +bool SiDetectorElement::isDBM() const +{ + return m_isDBM; +} + +bool SiDetectorElement::isBlayer() const +{ + if (isPixel() && isBarrel()) { + const PixelID* p_pixelId = static_cast<const PixelID *>(getIdHelper()); + return (0==p_pixelId->layer_disk(m_id)); + } else { + return false; + } +} + +bool SiDetectorElement::isInnermostPixelLayer() const +{ + if (isPixel() && isBarrel()) { + const PixelID* p_pixelId = static_cast<const PixelID *>(getIdHelper()); + return (0==p_pixelId->layer_disk(m_id)); + } else { + return false; + } +} + +bool SiDetectorElement::isNextToInnermostPixelLayer() const +{ + if (isPixel() && isBarrel()) { + const PixelID* p_pixelId = static_cast<const PixelID *>(getIdHelper()); + return (1==p_pixelId->layer_disk(m_id)); + } else { + return false; + } +} + + + Amg::Vector2D SiDetectorElement::correctLocalPosition(const Amg::Vector2D &position) const +{ + Amg::Vector2D correctedPosition(position); + correctedPosition[distPhi] += getLorentzCorrection(); + return correctedPosition; +} + +// compute sin(tilt angle) at center: +double SiDetectorElement::sinTilt() const +{ + if (!m_cacheValid) updateCache(); + + // Tilt is defined as the angle between a refVector and the sensor normal. + // In barrel refVector = unit vector radial. + // in endcap it is assumed there is no tilt. + // sinTilt = (refVector cross normal) . z + + // tilt angle is not defined for the endcap + if (isEndcap()) return 0; + + // Angle between normal and radial vector. + // HepGeom::Vector3D<double> refVector(m_center.x(), m_center.y(), 0); + // return (refVector.cross(m_normal)).z()/refVector.mag(); + // or the equivalent + return (m_center.x() * m_normal.y() - m_center.y() * m_normal.x()) / m_center.perp(); +} + + double SiDetectorElement::sinTilt(const Amg::Vector2D &localPos) const +{ + if (!m_cacheValid) updateCache(); + + // tilt angle is not defined for the endcap + if (isEndcap()) return 0; + + HepGeom::Point3D<double> point=globalPositionCLHEP(localPos); + return sinTilt(point); +} + +double SiDetectorElement::sinTilt(const HepGeom::Point3D<double> &globalPos) const +{ + if (!m_cacheValid) updateCache(); + + // It is assumed that the global position is already in the plane of the element. + + // tilt angle is not defined for the endcap + if (isEndcap()) return 0; + + // Angle between normal and radial vector. + //HepGeom::Vector3D<double> refVector(globalPos.x(), globalPos.y(), 0); + //return (refVector.cross(m_normal)).z()/refVector.mag(); + // or the equivalent + return (globalPos.x() * m_normal.y() - globalPos.y() * m_normal.x()) / globalPos.perp(); +} + +double SiDetectorElement::sinStereo() const +{ + + if (!m_cacheValid) updateCache(); + + // Stereo is the angle between a refVector and a vector along the strip/pixel in eta direction. + // I'm not sure how the sign should be defined. I've defined it here + // with rotation sense respect to normal, + // where normal is away from IP in barrel and in -ve z direction in endcap + + // In Barrel refVector = unit vector along z axis, + // in endcap refVector = unit vector radial. + // + // sinStereo = (refVector cross stripAxis) . normal + // = (refVector cross etaAxis) . normal + // = refVector . (etaAxis cross normal) + // = refVector . phiAxis + // + // in Barrel we use + // sinStereo = refVector . phiAxis + // = phiAxis.z() + // + // in endcap we use + // sinStereo = (refVector cross etaAxis) . normal + // = -(center cross etaAxis) . zAxis + // = (etaAxis cross center). z() + + double sinStereo; + if (isBarrel()) { + sinStereo = m_phiAxis.z(); + } else { // endcap + sinStereo = (m_center.y() * m_etaAxis.x() - m_center.x() * m_etaAxis.y()) / m_center.perp(); + } + return sinStereo; +} + + double SiDetectorElement::sinStereo(const Amg::Vector2D &localPos) const +{ + if (!m_cacheValid) updateCache(); + + HepGeom::Point3D<double> point=globalPositionCLHEP(localPos); + return sinStereo(point); +} + +double SiDetectorElement::sinStereo(const HepGeom::Point3D<double> &globalPos) const +{ + // + // sinStereo = (refVector cross stripAxis) . normal + // + + if (!m_cacheValid) updateCache(); + + double sinStereo; + if (isBarrel()) { + if (m_design->shape() != InDetDD::Trapezoid) { + sinStereo = m_phiAxis.z(); + } else { // trapezoid + assert (minWidth() != maxWidth()); + double radius = width() * length() / (maxWidth() - minWidth()); + HepGeom::Vector3D<double> stripAxis = radius * m_etaAxisCLHEP + globalPos - m_centerCLHEP; + sinStereo = (stripAxis.x() * m_normal.y() - stripAxis.y() * m_normal.x()) / stripAxis.mag(); + } + } else { // endcap + if (m_design->shape() != InDetDD::Trapezoid) { + sinStereo = (globalPos.y() * m_etaAxis.x() - globalPos.x() * m_etaAxis.y()) / globalPos.perp(); + } else { // trapezoid + // double radius = m_center.perp(); // Really want nominal r. + assert (minWidth() != maxWidth()); + double radius = width() * length() / (maxWidth() - minWidth()); + // HepGeom::Vector3D<double> stripAxis = radius * m_etaAxis + globalPos - m_center; + // Only need projection in xy plane. + double stripAxisX = globalPos.x() - m_center.x() + m_etaAxis.x()*radius; + double stripAxisY = globalPos.y() - m_center.y() + m_etaAxis.y()*radius; + double norm = 1./(radius*sqrt(stripAxisX*stripAxisX + stripAxisY*stripAxisY)); + sinStereo = norm * (stripAxisX * globalPos.y() - stripAxisY * globalPos.x()); + } + } + return sinStereo; +} + +bool +SiDetectorElement::isStereo() const +{ + if (m_firstTime) updateCache(); + return m_isStereo; +} + + +double +SiDetectorElement::sinStereoLocal(const Amg::Vector2D &localPos) const +{ + // The equation below will work for rectangle detectors as well in which + // case it will return 0. But we return zero immediately as there is no point doing the calculation. + if (m_design->shape() == InDetDD::Box) return 0; + double oneOverRadius = (maxWidth() - minWidth()) / (width() * length()); + double x = localPos[distPhi]; + double y = localPos[distEta]; + return -x*oneOverRadius / sqrt( (1+y*oneOverRadius)*(1+y*oneOverRadius) + x*oneOverRadius*x*oneOverRadius ); +} + + +double +SiDetectorElement::sinStereoLocal(const HepGeom::Point3D<double> &globalPos) const +{ + return sinStereoLocal(localPosition(globalPos)); +} + +// Special method for SCT to retrieve the two ends of a "strip" + std::pair<Amg::Vector3D,Amg::Vector3D> SiDetectorElement::endsOfStrip(const Amg::Vector2D &position) const +{ + const std::pair<Amg::Vector2D,Amg::Vector2D> localEnds= + m_design->endsOfStrip(position); + return std::pair<Amg::Vector3D,Amg::Vector3D >(globalPosition(localEnds.first), + globalPosition(localEnds.second)); +} + + +const Trk::Surface & +SiDetectorElement::surface() const +{ + if (!m_surface) m_surface = new Trk::PlaneSurface(*this); + return *m_surface; +} + +const Trk::SurfaceBounds & +SiDetectorElement::bounds() const +{ + return m_design->bounds(); +} + +// Get min/max or r, z,and phi +void SiDetectorElement::getExtent(double &rMin, double &rMax, + double &zMin, double &zMax, + double &phiMin, double &phiMax) const +{ + + HepGeom::Point3D<double> corners[4]; + getCorners(corners); + + bool first = true; + + double phiOffset = 0.; + + for (int i = 0; i < 4; i++) { + + HepGeom::Point3D<double> globalPoint = globalPosition(corners[i]); + + double rPoint = globalPoint.perp(); + double zPoint = globalPoint.z(); + double phiPoint = globalPoint.phi(); + + // Use first point to initializa min/max values. + if (first) { + + // Put phi in a range so that we are not near -180/+180 division. + // Do this by adding an offset if phi > 90 CLHEP::deg or < -90 CLHEP::deg. + // This offset is later removed. + if (phiPoint < -0.5 * M_PI) { + phiOffset = -0.5 * M_PI; + } else if (phiPoint > 0.5 * M_PI) { + phiOffset = 0.5 * M_PI; + } + phiMin = phiMax = phiPoint - phiOffset; + rMin = rMax = rPoint; + zMin = zMax = zPoint; + + } else { + phiPoint -= phiOffset; + // put phi back in -M_PI < phi < +M_PI range + if (phiPoint < -M_PI) phiPoint += 2. * M_PI; + if (phiPoint > M_PI) phiPoint -= 2. * M_PI; + phiMin = std::min(phiMin, phiPoint); + phiMax = std::max(phiMax, phiPoint); + rMin = std::min(rMin, rPoint); + rMax = std::max(rMax, rPoint); + zMin = std::min(zMin, zPoint); + zMax = std::max(zMax, zPoint); + } + first = false; + } + + // put phi back in -M_PI < phi < +M_PI range + phiMin += phiOffset; + phiMax += phiOffset; + if (phiMin < -M_PI) phiMin += 2. * M_PI; + if (phiMin > M_PI) phiMin -= 2. * M_PI; + if (phiMax < -M_PI) phiMax += 2. * M_PI; + if (phiMax > M_PI) phiMax -= 2. * M_PI; +} + + + +// Get eta/phi extent. Returns min/max eta and phi and r (for barrel) +// or z (for endcap) Takes as input the vertex spread in z (+-deltaZ). +// Gets 4 corners of the sensor and calculates eta phi for each corner +// for both +/- vertex spread. The returned phi is between -M_PI and M_PI +// with the direction minPhi to maxPhi always in the positive sense, +// so if the element extends across the -180/180 boundary then minPhi will +// be greater than maxPhi. +void SiDetectorElement::getEtaPhiRegion(double deltaZ, double &etaMin, double &etaMax, double &phiMin, + double &phiMax, double &rz) const +{ + if (!m_cacheValid) updateCache(); + + HepGeom::Point3D<double> corners[4]; + getCorners(corners); + + bool first = true; + + double phiOffset = 0.; + + for (int i = 0; i < 4; i++) { + double etaMinPoint; + double etaMaxPoint; + double phiPoint; + + // Get the eta phi value for this corner. + getEtaPhiPoint(corners[i], deltaZ, etaMinPoint, etaMaxPoint, phiPoint); + + if (first) { // Use the first point to initialize the min/max values. + + // Put phi in a range so that we are not near -180/+180 division. + // Do this by adding an offset if phi > 90 CLHEP::deg or < -90 CLHEP::deg. + // This offset is later removed. + if (phiPoint < -0.5 * M_PI) { + phiOffset = -0.5 * M_PI; + } else if (phiPoint > 0.5 * M_PI) { + phiOffset = 0.5 * M_PI; + } + phiMin = phiMax = phiPoint - phiOffset; + etaMin = etaMinPoint; + etaMax = etaMaxPoint; + } else { + phiPoint -= phiOffset; + // put phi back in -M_PI < phi < +M_PI range + if (phiPoint < -M_PI) phiPoint += 2. * M_PI; + if (phiPoint > M_PI) phiPoint -= 2. * M_PI; + phiMin = std::min(phiMin, phiPoint); + phiMax = std::max(phiMax, phiPoint); + etaMin = std::min(etaMin, etaMinPoint); + etaMax = std::max(etaMax, etaMaxPoint); + } + first = false; + } + + // put phi back in -M_PI < phi < +M_PI range + phiMin += phiOffset; + phiMax += phiOffset; + if (phiMin < -M_PI) phiMin += 2. * M_PI; + if (phiMin > M_PI) phiMin -= 2. * M_PI; + if (phiMax < -M_PI) phiMax += 2. * M_PI; + if (phiMax > M_PI) phiMax -= 2. * M_PI; + + // Calculate rz = r (barrel) or z (endcap) + // Use center of sensor ((0,0,0) in local coordinates) for determining this. + // HepGeom::Point3D<double> globalCenter = globalPosition(HepGeom::Point3D<double>(0,0,0)); + if (isBarrel()) { + rz = center().perp(); // r + } else { + rz = center().z(); // z + } + +} + +// Gets eta phi for a point given in local coordinates. deltaZ is specified to +// account for the vertex spread. phi is independent of this vertex +// spread. etaMax will correspond to zMin (-deltaZ) and etaMin will +// correspond to zMax (+deltaZ). +void SiDetectorElement::getEtaPhiPoint(const HepGeom::Point3D<double> & point, double deltaZ, + double &etaMin, double &etaMax, double &phi) const +{ + // Get the point in global coordinates. + HepGeom::Point3D<double> globalPoint = globalPosition(point); + + double r = globalPoint.perp(); + double z = globalPoint.z(); + + double thetaMin = atan2(r,(z + deltaZ)); + etaMax = -log(tan(0.5 * thetaMin)); + double thetaMax = atan2(r,(z - deltaZ)); + etaMin = -log(tan(0.5 * thetaMax)); + + phi = globalPoint.phi(); +} + +void SiDetectorElement::getCorners(HepGeom::Point3D<double> *corners) const +{ + if (!m_cacheValid) updateCache(); + + // This makes the assumption that the forward SCT detectors are orientated such that + // the positive etaAxis corresponds to the top of the detector where the width is largest. + // This is currently always the case. + // For the SCT barrel and pixel detectors minWidth and maxWidth are the same and so should + // work for all orientations. + + double minWidth = m_design->minWidth(); + double maxWidth = m_design->maxWidth(); + double length = m_design->length(); + + // Lower left + corners[0][distPhi] = -0.5 * minWidth; + corners[0][distEta] = -0.5 * length; + corners[0][distDepth] = 0.; + + // Lower right + corners[1][distPhi] = 0.5 * minWidth; + corners[1][distEta] = -0.5 * length; + corners[1][distDepth] = 0.; + + // Upper Right + corners[2][distPhi] = 0.5 * maxWidth; + corners[2][distEta] = 0.5 * length; + corners[2][distDepth] = 0.; + + // Upper left + corners[3][distPhi] = -0.5 * maxWidth; + corners[3][distEta] = 0.5 * length; + corners[3][distDepth] = 0.; +} + +SiIntersect +SiDetectorElement::inDetector(const Amg::Vector2D & localPosition, + double phiTol, double etaTol) const +{ + return m_design->inDetector(localPosition, phiTol, etaTol); +} + + +SiIntersect +SiDetectorElement::inDetector(const HepGeom::Point3D<double> & globalPosition, double phiTol, double etaTol) const +{ + return m_design->inDetector(localPosition(globalPosition), phiTol, etaTol); +} + +bool +SiDetectorElement::nearBondGap(Amg::Vector2D localPosition, double etaTol) const +{ + return m_design->nearBondGap(localPosition, etaTol); +} + +bool +SiDetectorElement::nearBondGap(HepGeom::Point3D<double> globalPosition, double etaTol) const +{ + return m_design->nearBondGap(localPosition(globalPosition), etaTol); +} + + + Amg::Vector2D +SiDetectorElement::localPositionOfCell(const SiCellId &cellId) const +{ + Amg::Vector2D pos(m_design->localPositionOfCell(cellId)); + return correctLocalPosition(pos); +} + +Amg::Vector2D +SiDetectorElement::localPositionOfCell(const Identifier & id) const +{ + SiCellId cellId = cellIdFromIdentifier(id); + Amg::Vector2D pos(m_design->localPositionOfCell(cellId)); + return correctLocalPosition(pos); +} + +Amg::Vector2D +SiDetectorElement::rawLocalPositionOfCell(const SiCellId &cellId) const +{ + return m_design->localPositionOfCell(cellId); +} + +Amg::Vector2D +SiDetectorElement::rawLocalPositionOfCell(const Identifier & id) const +{ + SiCellId cellId = cellIdFromIdentifier(id); + return m_design->localPositionOfCell(cellId); +} + +int +SiDetectorElement::numberOfConnectedCells(const SiCellId cellId) const +{ + SiReadoutCellId readoutId = m_design->readoutIdOfCell(cellId); + return m_design->numberOfConnectedCells(readoutId); +} + +SiCellId +SiDetectorElement::connectedCell(const SiCellId cellId, int number) const +{ + SiReadoutCellId readoutId = m_design->readoutIdOfCell(cellId); + return m_design->connectedCell(readoutId, number); +} + + +SiCellId +SiDetectorElement::cellIdOfPosition(const Amg::Vector2D &localPosition) const +{ + return m_design->cellIdOfPosition(localPosition); +} + +Identifier +SiDetectorElement::identifierOfPosition(const Amg::Vector2D &localPosition) const +{ + SiCellId cellId = m_design->cellIdOfPosition(localPosition); + return identifierFromCellId(cellId); +} + +Identifier +SiDetectorElement::identifierFromCellId(const SiCellId & cellId) const +{ + Identifier id; // Will be initialized in an invalid state. + + // If something fails it returns the id in an invalid state. + + if (cellId.isValid()) { + + if (isPixel()){ + const PixelID * pixelIdHelper = static_cast<const PixelID *>(getIdHelper()); + if (pixelIdHelper) { + id = pixelIdHelper->pixel_id(m_id, cellId.phiIndex(), cellId.etaIndex()); + } + } else { + const SCT_ID * sctIdHelper = static_cast<const SCT_ID *>(getIdHelper()); + if (sctIdHelper) { + id = sctIdHelper->strip_id(m_id, cellId.strip()); + } + } + } + + return id; +} + +SiCellId +SiDetectorElement::cellIdFromIdentifier(const Identifier & identifier) const +{ + SiCellId cellId; // Initialized in invalid state. + + // If something fails it returns the cellId in an invalid state. + + if (identifier.is_valid()) { + + if (isPixel()){ + const PixelID * pixelIdHelper = static_cast<const PixelID *>(getIdHelper()); + if (pixelIdHelper) { + cellId = SiCellId(pixelIdHelper->phi_index(identifier), pixelIdHelper->eta_index(identifier)); + } + } else { + const SCT_ID * sctIdHelper = static_cast<const SCT_ID *>(getIdHelper()); + if (sctIdHelper) { + cellId = SiCellId(sctIdHelper->strip(identifier)); + } + } + } + + return cellId; +} + +} // namespace InDetDD diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SiDetectorManager.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SiDetectorManager.cxx new file mode 100755 index 0000000000000000000000000000000000000000..f58d896a5f6be0317f4622fb2341503bb57d2aa8 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SiDetectorManager.cxx @@ -0,0 +1,191 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + + +#include "GeoPrimitives/CLHEPtoEigenConverter.h" + +#include "InDetReadoutGeometry/SiDetectorManager.h" +#include "AtlasDetDescr/AtlasDetectorID.h" +#include "IdDictDetDescr/IdDictManager.h" +#include "StoreGate/StoreGateSvc.h" + +#include "GeoModelKernel/GeoXF.h" +#include "CLHEP/GenericFunctions/Variable.hh" +#include "GeoModelKernel/GeoAlignableTransform.h" +#include "DetDescrConditions/AlignableTransformContainer.h" +#include "InDetReadoutGeometry/SiDetectorElementCollection.h" +#include "InDetReadoutGeometry/SiDetectorElement.h" +#include "InDetReadoutGeometry/ExtendedAlignableTransform.h" + +#include <iostream> + +namespace InDetDD +{ + + SiDetectorManager::SiDetectorManager(StoreGateSvc * detStore, const std::string & name) + : InDetDetectorManager(detStore, name) + { + // Add default folder + addFolder("/Indet/Align"); + } + + const std::string& SiDetectorManager::tag() const + { + return m_tag; + } + +// Non const version needed when it is registered to IOVSvc + StatusCode SiDetectorManager::alignmentCallback( IOVSVC_CALLBACK_ARGS_P(I,keys) ) { + return align(I,keys); + } + + void SiDetectorManager::invalidateAll() const + { + for (SiDetectorElementCollection::const_iterator element_iter = getDetectorElementBegin(); + element_iter != getDetectorElementEnd(); + ++element_iter) { + + if (*element_iter) { + (*element_iter)->invalidate(); + } + } + } + + void SiDetectorManager::updateAll() const + { + for (SiDetectorElementCollection::const_iterator element_iter = getDetectorElementBegin(); + element_iter != getDetectorElementEnd(); + ++element_iter) { + if (*element_iter) { + (*element_iter)->updateAllCaches(); + } + } + } + + +// Register the call back for this key and the corresponding level in +// in the hierarchy. +// DEPRECATED + void SiDetectorManager::addKey(const std::string & key, int level) + { + bool globalDelta = (level != 0); // local delta for level == 0 + addKey(key, level, globalDelta); + } + + + +// Register the call back for this key and the corresponding level in +// in the hierarchy. Also specify whether its a global or local delta. +// DEPRECATED + void SiDetectorManager::addKey(const std::string & key, int level, bool globalDelta) + { + if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << "Registering alignmentCallback with key " << key << endreq; + const DataHandle<AlignableTransform> transformCollection; + StatusCode sc = m_detStore->regFcn(&SiDetectorManager::alignmentCallback, this, transformCollection, key); + if (sc.isFailure()) { + if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << "Unable to register call back using old method. This is OK if you are using COOL." << endreq; + } + FrameType frame = (globalDelta) ? InDetDD::global : InDetDD::local; + addKey(key, level, frame); + } + + + void SiDetectorManager::addKey(const std::string & key, int level, FrameType frame) + { + addChannel(key, level, frame); + } + + + bool SiDetectorManager::setAlignableTransformLocalDelta(ExtendedAlignableTransform * extXF, + const Amg::Transform3D & localToGlobalXF, + const Amg::Transform3D & delta) const + { + // ATTENTION -------------------------------------------------------- (A.S.) + // CLHEP < -- > AMG interface method + + // Sets the alignable transform delta when the supplied delta is in the local + // reconstruction frame + + // If the default transform to the local recostruction frame is + // T = A*B*C*D*E + // and the alignable transform is C with delta c and the delat in the local frame is l, then + // A*B*C*c*D*E = A*B*C*D*E*l + // c = (D*E) * l * (D*E).inverse() + // c = (A*B*C).inverse * T * l * T.inverse() * (A*B*C) + + // To get default transform up and including the alignable transform, + // we assume the next volume down is a fullphys volume and so its + // transform is the transform we want (ie A*B*C in the above example). + + if (!extXF) return false; + + const GeoVFullPhysVol* child = extXF->child(); + if (child && extXF->alignableTransform()) { + // the definitiv absolut transform is in CLHEP -> do the calculation in CLHEP + HepGeom::Transform3D localToGlobalXFCLHEP = Amg::EigenTransformToCLHEP(localToGlobalXF); + const HepGeom::Transform3D& transform = child->getDefAbsoluteTransform(); + // calucluate the corrected delta according to the formula above + HepGeom::Transform3D correctedDelta = transform.inverse()*localToGlobalXFCLHEP // (A*B*C).inverse() * T + * Amg::EigenTransformToCLHEP(delta) // l + * localToGlobalXFCLHEP.inverse() * transform; // T.inverse() * (A*B*C) + extXF->alignableTransform()->setDelta(correctedDelta); + return true; + } else { + return false; + } + } + + bool SiDetectorManager::setAlignableTransformGlobalDelta(ExtendedAlignableTransform * extXF, + const Amg::Transform3D& delta) const { + // ATTENTION -------------------------------------------------------- (A.S.) + // CLHEP < -- > AMG interface method + + // Sets the alignable transform delta when the supplied delta is in the global frame. + + // If the default transform down to the alignable transform is + // T = A*B*C + // and the alignable transform is C with delta c and the delta in the global frame is g, then + // A*B*C*c = g*A*B*C + // T*c = g*T + // c = T.inverse() * g * T + + // To get default transform up and including the alignable transform, + // we assume the next volume down is a fullphys volume and so its + // transform is the transform we want (ie T=A*B*C in the above example). + + + if (!extXF) return false; + + const GeoVFullPhysVol * child = extXF->child(); + if (child && extXF->alignableTransform()) { + // do the calculation in CLHEP + const HepGeom::Transform3D& transform = child->getDefAbsoluteTransform(); + extXF->alignableTransform()->setDelta(transform.inverse() * Amg::EigenTransformToCLHEP(delta) * transform); + return true; + } else { + return false; + } + } + + + void SiDetectorManager::addDesign(const SiDetectorDesign * design) + { + m_designs.push_back(design); + } + + int SiDetectorManager::numDesigns() const + { + return m_designs.size(); + } + + + const SiDetectorDesign* SiDetectorManager::getDesign(int i) const + { + return m_designs[i]; + } + + + + +}// namespace InDetDD diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SiDiodesParameters.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SiDiodesParameters.cxx new file mode 100755 index 0000000000000000000000000000000000000000..0fdc6da16f0d1dbb49e9183c9d9c8a4e94cd8aa9 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SiDiodesParameters.cxx @@ -0,0 +1,47 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SiDiodesParameters.cxx +// Implementation file for class SiDiodesParameters +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// +// Version 1.0 14/08/2001 David Calvet +/////////////////////////////////////////////////////////////////// + +#include "InDetReadoutGeometry/SiDiodesParameters.h" + +namespace InDetDD { + +// Implicit constructor: +SiDiodesParameters::SiDiodesParameters() : + m_centre(), + m_width() +{} + +// Copy constructor: +SiDiodesParameters::SiDiodesParameters(const SiDiodesParameters ¶meters) : + m_centre(parameters.m_centre), + m_width(parameters.m_width) +{} + +// Constructor with parameters: +SiDiodesParameters::SiDiodesParameters(const SiLocalPosition ¢re, + const SiLocalPosition &width) : + m_centre(centre), + m_width(width) +{} + +// Assignment operator: +SiDiodesParameters &SiDiodesParameters::operator=(const SiDiodesParameters ¶meters) +{ + if (this!=¶meters) { + m_centre=parameters.m_centre; + m_width=parameters.m_width; + } else {} + return *this; +} + +} // namespace InDetDD diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SiLocalPosition.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SiLocalPosition.cxx new file mode 100755 index 0000000000000000000000000000000000000000..79df41ff1e66507ba2c3087d59308508e7d10e6c --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SiLocalPosition.cxx @@ -0,0 +1,114 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SiLocalPosition.cxx +// Implementation file for class SiLocalPosition +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// +// Version 2.1 01/08/2001 David Calvet +/////////////////////////////////////////////////////////////////// + +#include "InDetReadoutGeometry/SiLocalPosition.h" + +namespace InDetDD { + +// Implicit constructor: +SiLocalPosition::SiLocalPosition() : + m_xEta(0), + m_xPhi(0), + m_xDepth(0) +{} + +// Copy constructor: +SiLocalPosition::SiLocalPosition(const SiLocalPosition &position) : + m_xEta(position.m_xEta), + m_xPhi(position.m_xPhi), + m_xDepth(position.m_xDepth) +{} + +// Constructor with parameters: +SiLocalPosition::SiLocalPosition(const double xEta,const double xPhi, + const double xDepth) : + m_xEta(xEta), + m_xPhi(xPhi), + m_xDepth(xDepth) +{} + +SiLocalPosition::SiLocalPosition(const Amg::Vector2D &position) + : m_xEta(position[Trk::distEta]), + m_xPhi(position[Trk::distPhi]), + m_xDepth(0) +{} + + +SiLocalPosition::operator Amg::Vector2D(void) const +{ + return Amg::Vector2D(m_xPhi, m_xEta); +} + +// Assignment operator: +SiLocalPosition &SiLocalPosition::operator=(const SiLocalPosition &position) +{ + if (this!=&position) { + m_xEta=position.m_xEta; + m_xPhi=position.m_xPhi; + m_xDepth=position.m_xDepth; + } else {} + return *this; +} + +// addition of positions: +SiLocalPosition &SiLocalPosition::operator+=(const SiLocalPosition &position) +{ + m_xEta+=position.m_xEta; + m_xPhi+=position.m_xPhi; + m_xDepth+=position.m_xDepth; + return *this; +} + +// scaling: +SiLocalPosition &SiLocalPosition::operator*=(const double factor) +{ + m_xEta*=factor; + m_xPhi*=factor; + m_xDepth*=factor; + return *this; +} + +// scaling: +SiLocalPosition &SiLocalPosition::operator/=(const double factor) +{ + if (0!=factor) { + m_xEta/=factor; + m_xPhi/=factor; + m_xDepth/=factor; + } else {} + return *this; +} + +SiLocalPosition operator+(const SiLocalPosition &position1, + const SiLocalPosition &position2) +{ + SiLocalPosition result(position1); + result+=position2; + return result; +} + +SiLocalPosition operator*(const SiLocalPosition &position,const double factor) +{ + SiLocalPosition result(position); + result*=factor; + return result; +} + +SiLocalPosition operator/(const SiLocalPosition &position,const double factor) +{ + SiLocalPosition result(position); + result/=factor; + return result; +} + +} // namespace InDetDD diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SiNumerology.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SiNumerology.cxx new file mode 100644 index 0000000000000000000000000000000000000000..d3eb9ec5e6fd613552046ad0e71b28a6513a9407 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/SiNumerology.cxx @@ -0,0 +1,120 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "InDetReadoutGeometry/SiNumerology.h" + + +namespace InDetDD { + +SiNumerology::SiNumerology() + : m_numLayers(0), + m_numDisks(0), + m_maxPhiCells(0), + m_maxEtaCells(0), + m_maxNumBarrelEta(0), + m_maxNumEndcapRings(0), + m_maxNumBarrelPhiModules(0), + m_maxNumEndcapPhiModules(0), + m_numDisksDBM(0), + m_numBarrelDBM(0), + m_maxNumEndcapPhiModulesDBM(0) +{} + + +void SiNumerology::setNumLayers(int nLayers) +{ + m_phiModulesForLayer.resize(nLayers); + m_etaModulesForLayer.resize(nLayers); + m_numLayers = nLayers; +} + + +void SiNumerology::setNumDisks(int nDisks) +{ + m_numDisks = nDisks; + m_ringsForDisk.resize(nDisks); + m_phiModulesForDiskRing.resize(nDisks); +} + +void SiNumerology::setNumRingsForDisk(int disk, int nRings) +{ + m_ringsForDisk[disk] = nRings; + m_phiModulesForDiskRing[disk].resize(nRings); + m_maxNumEndcapRings = std::max(m_maxNumEndcapRings, nRings); +} + +void SiNumerology::setNumPhiModulesForDiskRing(int disk, int ring, int nPhiModules) +{ + m_phiModulesForDiskRing[disk][ring] = nPhiModules; + m_maxNumEndcapPhiModules = std::max(m_maxNumEndcapPhiModules, nPhiModules); +} + +void SiNumerology::setNumPhiModulesForLayer(int layer, int nPhiModules) +{ + m_phiModulesForLayer[layer] = nPhiModules; + m_maxNumBarrelPhiModules = std::max(m_maxNumBarrelPhiModules, nPhiModules); +} + +void SiNumerology::setNumEtaModulesForLayer(int layer, int nEtaModules) +{ + m_etaModulesForLayer[layer] = nEtaModules; + m_maxNumBarrelEta = std::max(m_maxNumBarrelEta, nEtaModules); +} + +void SiNumerology::setMaxNumPhiCells(int cells) +{ + m_maxPhiCells = std::max(m_maxPhiCells,cells); +} + +void SiNumerology::setMaxNumEtaCells(int cells) +{ + m_maxEtaCells = std::max(m_maxEtaCells,cells); +} + + +void SiNumerology::addBarrel(int id) +{ + m_barrelIds.push_back(id); +} + +void SiNumerology::addEndcap(int id) +{ + m_endcapIds.push_back(id); +} + +// DBM +void SiNumerology::setNumDisksDBM(int nDisks) +{ + m_numDisksDBM = nDisks; + if(nDisks>0){ + m_phiModulesForDiskRingDBM.resize(nDisks); + for(int disk=0; disk<nDisks; disk++) + m_phiModulesForDiskRingDBM[disk].resize(1); + return; + } + + m_endcapIdsDBM.clear(); + m_phiModulesForDiskRingDBM.clear(); + m_maxNumEndcapPhiModulesDBM = 0; + m_phiModulesForDiskRingDBM.clear(); + +} + +void SiNumerology::setNumBarrelDBM(int nBarrel) +{ + m_numBarrelDBM = nBarrel; +} + +void SiNumerology::setNumPhiModulesForDiskRingDBM(int disk, int ring, int nPhiModules) +{ + m_phiModulesForDiskRingDBM[disk][ring] = nPhiModules; + m_maxNumEndcapPhiModulesDBM = std::max(m_maxNumEndcapPhiModules, nPhiModules); +} + +void SiNumerology::addEndcapDBM(int id) +{ + m_endcapIdsDBM.push_back(id); +} + +} // End namespace diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_BarrelCode.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_BarrelCode.cxx new file mode 100755 index 0000000000000000000000000000000000000000..75818558cab462de7856602545a0f3b8d4cf1933 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_BarrelCode.cxx @@ -0,0 +1,72 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "InDetReadoutGeometry/TRT_BarrelCode.h" +#include <string> +#include <sstream> + +namespace InDetDD { +// +// Mask +// +const int TRT_BarrelCode::Z_MASK = 0x00000001; // lowest six bits +const int TRT_BarrelCode::MODULE_MASK = 0x00000003; // lowest two +const int TRT_BarrelCode::PHI_MASK = 0x0000001F; // lowest five +const int TRT_BarrelCode::STRAWLAYER_MASK = 0x0000001F; // lowest five + +// +// Shifts +// +const int TRT_BarrelCode::Z_SHIFT = 0; +const int TRT_BarrelCode::MODULE_SHIFT = 1; +const int TRT_BarrelCode::PHI_SHIFT = 3; +const int TRT_BarrelCode::STRAWLAYER_SHIFT = 8; + + + + + +TRT_BarrelCode::TRT_BarrelCode() +{ + _key = 0; +} + +TRT_BarrelCode::TRT_BarrelCode(unsigned isPos, unsigned moduleIndex, unsigned phiIndex, unsigned strawLayerIndex) + : + _key ((( isPos & Z_MASK ) << Z_SHIFT) | + (( moduleIndex & MODULE_MASK ) << MODULE_SHIFT) | + (( phiIndex & PHI_MASK ) << PHI_SHIFT) | + (( strawLayerIndex & STRAWLAYER_MASK ) << STRAWLAYER_SHIFT)) +{ +} + +TRT_BarrelCode::TRT_BarrelCode(const TRT_BarrelCode &right) +{ + _key = right.getKey(); +} + + + + +TRT_BarrelCode::~TRT_BarrelCode() +{ +} + + +const TRT_BarrelCode & TRT_BarrelCode::operator=(const TRT_BarrelCode &right) +{ + _key = right.getKey(); + return *this; +} + + + +std::string TRT_BarrelCode::getName() const { + + std::ostringstream outputStream; + outputStream << this; + return outputStream.str(); +} + +} diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_BarrelDescriptor.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_BarrelDescriptor.cxx new file mode 100755 index 0000000000000000000000000000000000000000..2205aacf289eb5301d8e79ef58c1e5a21094595a --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_BarrelDescriptor.cxx @@ -0,0 +1,53 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "InDetReadoutGeometry/TRT_BarrelDescriptor.h" + +#include "TrkSurfaces/CylinderBounds.h" + +#include "CLHEP/Units/SystemOfUnits.h" + +namespace InDetDD { + +TRT_BarrelDescriptor::TRT_BarrelDescriptor() + : _length(0), + _zDead(0), + _zPos(0), + m_innerTubeRadius(2*CLHEP::mm), // FIXME: Hardwired for now!! + _f(NULL), + _o(0), + m_bounds(0) + +{ +} + + +TRT_BarrelDescriptor::~TRT_BarrelDescriptor() +{ + delete m_bounds; +} + + +void TRT_BarrelDescriptor::addStraw(double xPos, double yPos) { + + _x.push_back(xPos); + _y.push_back(yPos); + +} + + +void TRT_BarrelDescriptor::setStrawTransformField(const GeoXF::Function *xf, size_t offsetInto) { + _f=xf; + _o=offsetInto; +} + +const Trk::SurfaceBounds & +TRT_BarrelDescriptor::strawBounds() const +{ + if (!m_bounds) m_bounds = new Trk::CylinderBounds(m_innerTubeRadius, 0.5*_length); + return *m_bounds; +} + + +} diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_BarrelElement.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_BarrelElement.cxx new file mode 100755 index 0000000000000000000000000000000000000000..bb3d0af903c03618de9384de315fd7b47edd9a8c --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_BarrelElement.cxx @@ -0,0 +1,240 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "Identifier/Identifier.h" +#include "InDetReadoutGeometry/SurfaceCache.h" +#include "InDetReadoutGeometry/TRT_BarrelElement.h" +#include "InDetReadoutGeometry/TRT_Conditions.h" + +#include "TrkSurfaces/RectangleBounds.h" +#include "TrkSurfaces/PlaneSurface.h" + +#include "InDetIdentifier/TRT_ID.h" + +#include "TRT_ConditionsData/ExpandedIdentifier.h" +#include "TRT_ConditionsData/StrawDxContainer.h" + +namespace InDetDD { + +TRT_BarrelElement::TRT_BarrelElement(const GeoVFullPhysVol *volume, + const TRT_BarrelDescriptor *descriptor, + bool isPositive, + unsigned int modIndex, + unsigned int phiIndex, + unsigned int strawLayIndex, + const TRT_ID * idHelper, + const TRT_Conditions * conditions) + : + TRT_BaseElement(volume, + idHelper->layer_id((isPositive ? 1:-1), phiIndex, modIndex, strawLayIndex), + idHelper, conditions), + _code(isPositive,modIndex,phiIndex,strawLayIndex), + _descriptor(descriptor), + _nextInPhi(NULL), + _previousInPhi(NULL), + _nextInR(NULL), + _previousInR(NULL), + m_surface(0) + +{ + _descriptor->ref(); +} + + +TRT_BarrelElement::~TRT_BarrelElement() +{ + _descriptor->unref(); + delete m_surface; +} + + +const TRT_BarrelConditions * TRT_BarrelElement::getConditionsData() const +{ + return NULL; +} + +const TRT_BarrelDescriptor * TRT_BarrelElement::getDescriptor() const +{ + return _descriptor; +} + +void TRT_BarrelElement::setNextInPhi(const TRT_BarrelElement *element) +{ + _nextInPhi=element; +} + +void TRT_BarrelElement::setPreviousInPhi(const TRT_BarrelElement *element) +{ + _previousInPhi=element; +} + +void TRT_BarrelElement::setNextInR(const TRT_BarrelElement *element) +{ + _nextInR=element; +} + +void TRT_BarrelElement::setPreviousInR(const TRT_BarrelElement *element) +{ + _previousInR=element; +} + + + +HepGeom::Transform3D TRT_BarrelElement::calculateStrawTransform(int straw) const +{ + // NB The tranformation to a straw is reconstructed here precisely as + // it was ... hopefully... in the factory. One could eliminate this + // requirement and make the code a little more robust in this regard but + // at the cost of doubling the descriptors. (One descriptor now suffices + // for both positive and negative endcaps). + //std::cout << "In calculateStrawTransform" << std::endl; + + const GeoXF::Function *f= _descriptor->getStrawTransform(); + if (f) { + size_t offsetInto = _descriptor->getStrawTransformOffset(); + double zPos = -_descriptor->strawZPos(); + double zAng = _code.isPosZ() ? M_PI : 0; + return getMaterialGeom()->getAbsoluteTransform()*((*f)(straw+offsetInto)) + * HepGeom::RotateY3D(zAng)*HepGeom::TranslateZ3D(zPos) + * calculateLocalStrawTransform(straw); + ////return conditions()->solenoidFrame() + //// * getMaterialGeom()->getAbsoluteTransform()*((*f)(straw+offsetInto)) + //// * HepGeom::RotateY3D(zAng)*HepGeom::TranslateZ3D(zPos) + //// * calculateLocalStrawTransform(straw); + } else { + std::cout << "calculateStrawTransform: f is 0 !!!!" << std::endl; + return HepGeom::Transform3D(); + } +} + +HepGeom::Transform3D TRT_BarrelElement::calculateLocalStrawTransform(int straw) const +{ + const TRTCond::StrawDxContainer* container = conditions()->dxContainer(); + HepGeom::Transform3D rc ; + if(!container) { + // std::cout << " TRT_BarrelElement: no local transform found " << std::endl; + } else { + // important note: dx1 moves the 'negative' wire endpoint end dx2 + // the 'positive' wire endpoint in the local straw frame. In the + // global frame, 'dx1' corresponds to the readout side and 'dx2' + // to the wire joint side for both sides of the barrel. + + int bec = getCode().isPosZ() ? +1 : -1 ; + int layer = getCode().getModuleIndex(); + int phimodule = getCode().getPhiIndex(); + int strawlayer = getCode().getStrawLayerIndex(); + TRTCond::ExpandedIdentifier id = TRTCond::ExpandedIdentifier + (bec,layer,phimodule,strawlayer,straw,TRTCond::ExpandedIdentifier::STRAW); + double dx1 = container->getDx1(id); + double dx2 = container->getDx2(id); + double ang = (dx2-dx1)/strawLength(); + double dx = (dx2+dx1)/2.; + rc = HepGeom::TranslateX3D(dx)*HepGeom::RotateY3D(ang) ; + } + return rc ; +} + + +HepGeom::Transform3D TRT_BarrelElement::defStrawTransform(int straw) const +{ + // Same as calculateStrawTransform, except we use getDefAbsoluteTransform() + // rather than getAbsoluteTransform() + + // NB The tranformation to a straw is reconstructed here precisely as + // it was ... hopefully... in the factory. One could eliminate this + // requirement and make the code a little more robust in this regard but + // at the cost of doubling the descriptors. (One descriptor now suffices + // for both positive and negative endcaps). + + const GeoXF::Function *f= _descriptor->getStrawTransform(); + if (f) { + size_t offsetInto = _descriptor->getStrawTransformOffset(); + double zPos = -_descriptor->strawZPos(); + double zAng = _code.isPosZ() ? M_PI : 0; + return getMaterialGeom()->getDefAbsoluteTransform()*((*f)(straw+offsetInto))* HepGeom::RotateY3D(zAng)*HepGeom::TranslateZ3D(zPos); + } else { + std::cout << "calculateStrawTransform: f is 0 !!!!" << std::endl; + return HepGeom::Transform3D(); + } + +} + + +const Trk::SurfaceBounds& TRT_BarrelElement::strawBounds() const +{ + return _descriptor->strawBounds(); +} + +const Trk::Surface& TRT_BarrelElement::elementSurface() const +{ + if (!m_surface) m_surface = new Trk::PlaneSurface(*this); + return *m_surface; +} + +void TRT_BarrelElement::createSurfaceCache() const +{ + // Calculate the surface from the two end straws. + int firstStraw = 0; + int lastStraw = nStraws() - 1; + + const Amg::Vector3D& centerFirstStraw = center(m_idHelper->straw_id(identify(), firstStraw)); + const Amg::Vector3D& centerLastStraw = center(m_idHelper->straw_id(identify(), lastStraw)); + + // Calculate center as the average position of the end straws. + Amg::Vector3D* center = new Amg::Vector3D(0.5*(centerFirstStraw+centerLastStraw)); + + Amg::Vector3D phiAxis = centerLastStraw - centerFirstStraw; + double width = phiAxis.mag(); + phiAxis = phiAxis.normalized(); + double elementWidth = width + 2 * _descriptor->innerTubeRadius(); // Add the straw tube radius + + // Get local z-axis. This is roughly in +ve global z direction (exactly if no misalignment) + // We could probably use any straw for this but we average the first and last straw and renormalize + // to a unit vector. + Amg::Vector3D etaAxis = 0.5*(strawAxis(firstStraw) + strawAxis(lastStraw)); + etaAxis = etaAxis.normalized(); + + // Calculate normal. This will point away from the beam line based + // on the assumption that the straw numbering goes in the direction + // of increasing phi and the straw axis is in +ve z direction. + Amg::Vector3D* normal = new Amg::Vector3D(phiAxis.cross( etaAxis )); // phi cross z + + // Transform from local to global. + // local x axis -> phiAxis + // local y axis -> etaAxis + // local z axis -> cross product of local x and local y + // translation -> center + + // This constructor takes three points in the two coordinate systems. + Amg::Transform3D* transform = new Amg::Transform3D(); + + Amg::RotationMatrix3D rotation; + rotation.col(0) = phiAxis; + rotation.col(1) = etaAxis; + rotation.col(2) = (*normal); + + (*transform) = Amg::Translation3D(*center) * rotation; + + // create the element bounds + Trk::RectangleBounds * elementBounds = new Trk::RectangleBounds(0.5*elementWidth, 0.5*strawLength()); + // create the surface cache + m_surfaceCache = new SurfaceCache(transform, center, normal, elementBounds); + // creaete the surface (only if needed, links are still ok even if cache update) + if (!m_surface) m_surface = new Trk::PlaneSurface(*this); + +} + + +int TRT_BarrelElement::strawDirection() const +{ + // Return +1 if the straw local axis is in the same direction as the z axis, -1 otherwise. + // The straw axis by convention goes in the direction away from the readout. + // So for -ve endcap this is the positive z direction (we return +1) and in the + // +ve endcap its in the -ve z direction (we return -1). + // + return !(_code.isPosZ()) ? +1 : -1; +} + + +} // end namespace diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_BaseElement.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_BaseElement.cxx new file mode 100755 index 0000000000000000000000000000000000000000..f1510c83cca30261e194a29a61e69ca62aec00da --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_BaseElement.cxx @@ -0,0 +1,340 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "InDetReadoutGeometry/SurfaceCache.h" +#include "InDetReadoutGeometry/TRT_BaseElement.h" +#include "InDetReadoutGeometry/TRT_Conditions.h" + +#include "CLHEP/Geometry/Transform3D.h" +#include "CLHEP/Geometry/Point3D.h" +#include "CLHEP/Geometry/Vector3D.h" +#include "GeoPrimitives/CLHEPtoEigenConverter.h" + +#include "InDetIdentifier/TRT_ID.h" + +#include "TrkSurfaces/StraightLineSurface.h" +#include "TrkSurfaces/Surface.h" + +#include <vector> + +namespace InDetDD { + + + TRT_BaseElement::TRT_BaseElement(const GeoVFullPhysVol *volume, const Identifier & id, const TRT_ID * idHelper, const TRT_Conditions * conditions) : + Trk::TrkDetElementBase(volume), + m_id(id), + m_idHelper(idHelper), + m_conditions(conditions), + m_strawSurfaces(0), + m_strawSurfacesCache(0), + m_surfaceCache(0) + { + m_idHash = m_idHelper->straw_layer_hash(id); + m_conditions->ref(); + } + + Identifier TRT_BaseElement::identify() const + { + return m_id; + } + + IdentifierHash TRT_BaseElement::identifyHash() const + { + return m_idHash; + } + + // [0] GeoModel / CLHEP Access + const HepGeom::Transform3D TRT_BaseElement::getAbsoluteTransform(int straw) const + { + return Amg::EigenTransformToCLHEP(strawTransform(straw)); + } + + // [A] description of the current detector element : Amg first, then CLHEP converted methods + const Trk::Surface& TRT_BaseElement::surface() const + { + return elementSurface(); + } + + const Trk::SurfaceBounds& TRT_BaseElement::bounds() const + { + if (!m_surfaceCache) createSurfaceCache(); + return *(m_surfaceCache->bounds()); + } + + const Amg::Transform3D& TRT_BaseElement::transform() const + { + if (!m_surfaceCache) createSurfaceCache(); + return *(m_surfaceCache->transform()); + } + + + const Amg::Vector3D& TRT_BaseElement::center() const + { + if (!m_surfaceCache) createSurfaceCache(); + return *(m_surfaceCache->center()); + } + + const Amg::Vector3D& TRT_BaseElement::normal() const + { + if (!m_surfaceCache) createSurfaceCache(); + return *(m_surfaceCache->normal()); + } + + // [B] Description of the individual straws + const Trk::Surface& TRT_BaseElement::surface(const Identifier& id) const + { + int straw = m_idHelper->straw(id); + // Create vector of all straws. + if (!m_strawSurfaces) + m_strawSurfaces = new std::vector<Trk::StraightLineSurface*>(nStraws(), 0); + Trk::Surface * surfacePtr = (*m_strawSurfaces)[straw]; + if (!surfacePtr) { + createSurfaceCache(id); + surfacePtr = (*m_strawSurfaces)[straw]; + } + return *surfacePtr; + } + + const Trk::SurfaceBounds& TRT_BaseElement::bounds(const Identifier&) const + { + return strawBounds(); + } + + const Amg::Transform3D& TRT_BaseElement::transform(const Identifier & id) const + { + int straw = m_idHelper->straw(id); + if (!m_strawSurfacesCache) m_strawSurfacesCache = new std::vector<SurfaceCache*>(nStraws(), 0); + SurfaceCache* sCachePtr = (*m_strawSurfacesCache)[straw]; + if (!sCachePtr) { + createSurfaceCache(id); + sCachePtr = (*m_strawSurfacesCache)[straw]; + } + // forward the transform of the cache + return *(sCachePtr->transform()); + } + + const Amg::Transform3D& TRT_BaseElement::strawTransform(unsigned int straw) const + { + if (!m_strawSurfacesCache) m_strawSurfacesCache = new std::vector<SurfaceCache*>(nStraws(), 0); + SurfaceCache* sCachePtr = (*m_strawSurfacesCache)[straw]; + if (!sCachePtr) { + Identifier id = m_idHelper->straw_id(identify(), straw); + createSurfaceCache(id); + sCachePtr = (*m_strawSurfacesCache)[straw]; + } + // forward the transform of the cache + return *(sCachePtr->transform()); + } + + + const Amg::Vector3D& TRT_BaseElement::normal(const Identifier&) const + { + // Not sure if the normal of the straw is ever used. + // nor is there a well defined normal. + // This wont be corrected for alignments. + // Just return the element normal + return normal(); + } + + const Amg::Vector3D& TRT_BaseElement::center(const Identifier & id) const + { + int straw = m_idHelper->straw(id); + if (!m_strawSurfacesCache) m_strawSurfacesCache = new std::vector<SurfaceCache*>(nStraws(), 0); + SurfaceCache* sCachePtr = (*m_strawSurfacesCache)[straw]; + if (!sCachePtr) { + createSurfaceCache(id); + sCachePtr = (*m_strawSurfacesCache)[straw]; + } + // forward the transform of the cache + return *(sCachePtr->center()); + } + + const Trk::StraightLineSurface& TRT_BaseElement::strawSurface(int straw) const + { + // Create vector of all straws. + if (!m_strawSurfaces) + m_strawSurfaces = new std::vector<Trk::StraightLineSurface *>(nStraws(), 0); + Trk::StraightLineSurface* surfacePtr = (*m_strawSurfaces)[straw]; + if (!surfacePtr) { + // get the straw identifier to the given straw number and element identifier + Identifier id = m_idHelper->straw_id(identify(), straw); + createSurfaceCache(id); + surfacePtr = (*m_strawSurfaces)[straw]; + } + return *surfacePtr; + } + + const Amg::Transform3D& TRT_BaseElement::strawTransform(int straw) const + { + if (!m_strawSurfacesCache) m_strawSurfacesCache = new std::vector<SurfaceCache*>(nStraws(), 0); + SurfaceCache* sCachePtr = (*m_strawSurfacesCache)[straw]; + if (!sCachePtr) { + Identifier id = m_idHelper->straw_id(identify(), straw); + createSurfaceCache(id); + sCachePtr = (*m_strawSurfacesCache)[straw]; + } + // forward the transform of the cache + return *(sCachePtr->transform()); + } + + const Amg::Vector3D& TRT_BaseElement::strawCenter(int straw) const + { + if (!m_strawSurfacesCache) m_strawSurfacesCache = new std::vector<SurfaceCache*>(nStraws(), 0); + SurfaceCache* sCachePtr = (*m_strawSurfacesCache)[straw]; + if (!sCachePtr) { + Identifier id = m_idHelper->straw_id(identify(), straw); + createSurfaceCache(id); + sCachePtr = (*m_strawSurfacesCache)[straw]; + } + // forward the transform of the cache + return *(sCachePtr->center()); + } + + Amg::Vector3D TRT_BaseElement::strawAxis(int straw) const + { + return ( strawTransform(straw).linear()*Amg::Vector3D::UnitZ()*strawDirection() ); + } + + /// ----- can be removed after full Amg migration ----------------------- (start) + // [A] in CLHEP + + const HepGeom::Transform3D TRT_BaseElement::transformCLHEP() const + { + return Amg::EigenTransformToCLHEP((*m_surfaceCache->transform())); + } + + const HepGeom::Point3D<double> TRT_BaseElement::centerCLHEP() const + { + + const Amg::Vector3D& cCenter = center(); + return HepGeom::Point3D<double>(cCenter.x(),cCenter.y(),cCenter.z()); + } + + const HepGeom::Vector3D<double> TRT_BaseElement::normalCLHEP() const + { + const Amg::Vector3D& cNormal = normal(); + return HepGeom::Vector3D<double>(cNormal.x(),cNormal.y(),cNormal.z()); + } + + // [B] in CLHEP + + const HepGeom::Transform3D TRT_BaseElement::transformCLHEP(const Identifier & id) const + { + return Amg::EigenTransformToCLHEP(transform(id)); + } + + const HepGeom::Point3D<double> TRT_BaseElement::centerCLHEP(const Identifier & id) const + { + const Amg::Vector3D cCenter = center(id); + return HepGeom::Point3D<double>(cCenter.x(),cCenter.y(),cCenter.z()); + } + + const HepGeom::Vector3D<double> TRT_BaseElement::normalCLHEP(const Identifier&) const + { + // Not sure if the normal of the straw is ever used. + // nor is there a well defined normal. + // This wont be corrected for alignments. + // Just return the element normal + return normalCLHEP(); + } + + /// ----- can be removed after full Amg migration ----------------------- (end) + + + void TRT_BaseElement::createSurfaceCache(Identifier id) const + { + + // should not happen, but worth the protection + if (!m_strawSurfacesCache) m_strawSurfacesCache = new std::vector<SurfaceCache*>(nStraws(),0); + if (!m_strawSurfaces) m_strawSurfaces = new std::vector<Trk::StraightLineSurface*>(nStraws(), 0); + + int straw = m_idHelper->straw(id); + + // get the StrawTransform from GeoModel + HepGeom::Transform3D cStrawTransform = calculateStrawTransform(straw); + + // convert neccessary parts to Amg + Amg::Transform3D* sTransform = new Amg::Transform3D(Amg::CLHEPTransformToEigen(cStrawTransform)); + Amg::Vector3D* sCenter = new Amg::Vector3D(sTransform->translation()); + + // create the surface cache & fill it + SurfaceCache* sSurfaceCache = new SurfaceCache(sTransform, sCenter, 0, 0); + (*m_strawSurfacesCache)[straw] = sSurfaceCache; + + // creaete the surface only if needed (the links are still intact) + if (!(*m_strawSurfaces)[straw]){ + Trk::StraightLineSurface* sSurface = new Trk::StraightLineSurface(*this, id); + (*m_strawSurfaces)[straw] = sSurface; + + } + } + + + void TRT_BaseElement::invalidate() const + { + // Invalidate the caches + // Call and barrel or endcap specific invalidation + invalidateOther(); + // Its enough to delete and zero the caches. + deleteCache(); + } + + void TRT_BaseElement::deleteCache() const + { + // invalidates the cache, surface object can still live + + // for all straws + if (m_strawSurfacesCache) { + for (size_t i=0; i<m_strawSurfacesCache->size(); i++) { + delete (*m_strawSurfacesCache)[i]; + (*m_strawSurfacesCache)[i] = 0; + } + } + delete m_strawSurfacesCache; + m_strawSurfacesCache = 0; + + // for the element surface + delete m_surfaceCache; + m_surfaceCache = 0; + } + + + void TRT_BaseElement::updateAllCaches() const + { + // delete the caches first + deleteCache(); + // Strawlayer caches + if (!m_surfaceCache) createSurfaceCache(); + // Loop over all straws and request items that get cached. + for (unsigned int iStraw=0; iStraw < nStraws(); iStraw++) { + Identifier strawId = m_idHelper->straw_id(identify(),iStraw); + createSurfaceCache(strawId); + } + + } + + const TRT_Conditions* TRT_BaseElement::conditions() const + { + return m_conditions; + } + + + + TRT_BaseElement::~TRT_BaseElement() + { + // delete the information about the straws + if (m_strawSurfaces) { + for (size_t i=0; i<m_strawSurfaces->size(); i++) { + delete (*m_strawSurfaces)[i]; + } + } + delete m_strawSurfaces; + deleteCache(); + + m_conditions->unref(); + + } + + +} diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_Conditions.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_Conditions.cxx new file mode 100755 index 0000000000000000000000000000000000000000..ac5974f9876776e127434bf86cdca341ced76359 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_Conditions.cxx @@ -0,0 +1,37 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "InDetReadoutGeometry/TRT_Conditions.h" + +namespace InDetDD { + +TRT_Conditions::TRT_Conditions() + : m_dxContainer(0) +{} + +const TRTCond::StrawDxContainer* +TRT_Conditions::dxContainer() const +{ + return m_dxContainer; +} + +void +TRT_Conditions::setDxContainer(const TRTCond::StrawDxContainer* container) +{ + m_dxContainer = container; +} + +const HepGeom::Transform3D & +TRT_Conditions::solenoidFrame() const +{ + return m_solenoidFrame; +} + +void +TRT_Conditions::setSolenoidFrame(const HepGeom::Transform3D & frame) +{ + m_solenoidFrame = frame; +} + +} // end namespace diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_DetectorManager.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_DetectorManager.cxx new file mode 100755 index 0000000000000000000000000000000000000000..be2a82378f2af97735f83c6e09d0e93d4ec6d2c4 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_DetectorManager.cxx @@ -0,0 +1,642 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "InDetReadoutGeometry/TRT_DetectorManager.h" +#include "InDetReadoutGeometry/TRT_Numerology.h" +#include "InDetReadoutGeometry/TRT_BarrelCode.h" +#include "InDetReadoutGeometry/TRT_EndcapCode.h" +#include "InDetReadoutGeometry/TRT_BarrelElement.h" +#include "InDetReadoutGeometry/TRT_EndcapElement.h" +#include "InDetReadoutGeometry/ExtendedAlignableTransform.h" +#include "InDetReadoutGeometry/InDetDD_Defs.h" +#include "InDetReadoutGeometry/TRT_Conditions.h" + +#include "GeoModelKernel/GeoXF.h" +#include "GeoModelKernel/GeoAlignableTransform.h" + +#include "GeoPrimitives/CLHEPtoEigenConverter.h" + +#include "DetDescrConditions/AlignableTransform.h" +#include "DetDescrConditions/AlignableTransformContainer.h" + +#include "StoreGate/StoreGateSvc.h" + +#include "GaudiKernel/Bootstrap.h" +#include "GaudiKernel/ISvcLocator.h" + +#include "TRT_ConditionsData/StrawDxContainer.h" + +namespace InDetDD { + + const int FIRST_HIGHER_LEVEL = 1; + + TRT_DetectorManager::TRT_DetectorManager(StoreGateSvc * detStore) + :InDetDetectorManager(detStore, "TRT"), + _numerology(new TRT_Numerology()), + m_idHelper(NULL), + _ownsIdHelper(false), + m_gasType(unknown), + m_digvers(9999), + m_digversname("ERROR:DIGVERSNOTSET!"), + m_conditions(0) + { + + // If detstore no passed then get it from bootstrap. + if (m_detStore == 0) { + StatusCode sc = Gaudi::svcLocator()->service("DetectorStore", m_detStore); + if (sc.isFailure()) msg(MSG::ERROR) << "Could not locate DetectorStore" << endreq; + } + + // + // NULL out barrel and endcap arrays: + // + for (unsigned int ec=0;ec<2;ec++) { + for (unsigned int mod=0;mod<NMODMAX;mod++) { + for (unsigned int phi=0; phi<NPHIMAX;phi++) { + for (unsigned int sLay=0;sLay<NSTRAWLAYMAXBR;sLay++) { + barrelArray[ec][mod][phi][sLay]=NULL; + } + } + } + } + for (unsigned int ec=0;ec<2;ec++) { + for (unsigned int whe=0;whe<NWHEELMAX;whe++) { + for (unsigned int sLay=0;sLay<NSTRAWLAYMAXEC;sLay++) { + for(unsigned int phi=0;phi<NPHIMAX;phi++) { + endcapArray[ec][whe][sLay][phi]=NULL; + } + } + } + } + _barrelXF[0]=_barrelXF[1]=_barrelXF[2]=NULL; + _endcapXF[0]=_endcapXF[1]=_endcapXF[2]=NULL; + } + + + + TRT_Numerology * TRT_DetectorManager::getNumerology() { + return _numerology; + } + + const TRT_Numerology * TRT_DetectorManager::getNumerology() const { + return _numerology; + } + + TRT_DetectorManager::~TRT_DetectorManager() + { + for (size_t i=0;i<volume.size();i++) { + volume[i]->unref(); + } + for (unsigned int ec=0;ec<2;ec++) { + for (unsigned int mod=0;mod<NMODMAX;mod++) { + for (unsigned int phi=0; phi<NPHIMAX;phi++) { + for (unsigned int sLay=0;sLay<NSTRAWLAYMAXBR;sLay++) { + delete barrelArray[ec][mod][phi][sLay]; + } + } + } + } + for (unsigned int ec=0;ec<2;ec++) { + for (unsigned int whe=0;whe<NWHEELMAX;whe++) { + for (unsigned int sLay=0;sLay<NSTRAWLAYMAXEC;sLay++) { + for(unsigned int phi=0;phi<NPHIMAX;phi++) { + delete endcapArray[ec][whe][sLay][phi]; + } + } + } + } + delete _numerology; + if (_ownsIdHelper) delete m_idHelper; + for (int i=0;i<3;i++) delete _barrelXF[i]; + for (int i=0;i<3;i++) delete _endcapXF[i]; + + + for (unsigned int i = 0; i < m_alignableTransforms.size(); i++) { + AlignableTransformMap& m = m_alignableTransforms[i]; + for (AlignableTransformMap::iterator j = m.begin(); j != m.end(); ++j) { + delete j->second; + } + } + + if (m_conditions) m_conditions->unref(); + + } + + + unsigned int TRT_DetectorManager::getNumTreeTops() const + { + return volume.size(); + } + + PVConstLink TRT_DetectorManager::getTreeTop(unsigned int i) const + { + return volume[i]; + } + + void TRT_DetectorManager::addTreeTop(PVLink vol){ + vol->ref(); + volume.push_back(vol); + } + + // Manage the barrel elements: + void TRT_DetectorManager::manageBarrelElement(TRT_BarrelElement *barrel) { + + if ( barrelArray + [barrel->getCode().isPosZ()] + [barrel->getCode().getModuleIndex()] + [barrel->getCode().getPhiIndex()] + [barrel->getCode().getStrawLayerIndex()] ) { + + //Element already added - complain! + if(msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << "manageBarrelElement: Overriding existing element"<<endreq; + }; + + barrelArray + [barrel->getCode().isPosZ()] + [barrel->getCode().getModuleIndex()] + [barrel->getCode().getPhiIndex()] + [barrel->getCode().getStrawLayerIndex()] + =barrel; + + // Add the barrel element to the hash vector: + if (m_idHelper) { + Identifier id = m_idHelper->layer_id(barrel->getCode().isPosZ() ? +1 : -1, + barrel->getCode().getPhiIndex(), + barrel->getCode().getModuleIndex(), + barrel->getCode().getStrawLayerIndex()); + IdentifierHash hashId = m_idHelper->straw_layer_hash(id); + if (hashId.is_valid()) { + if (m_elements.size() <= hashId) { + m_elements.resize(static_cast<unsigned int>(hashId) + 1); + } + if (m_elements[hashId]) { + //Element already added - complain! + if(msgLvl(MSG::DEBUG)) + msg(MSG::DEBUG) << "manageBarrelElement: Overriding existing element for hashID"<<endreq; + } + m_elements[hashId]=barrel; + } else { + msg(MSG::WARNING) << "manageBarrelElement: Invalid identifier" << endreq; + } + + } + + } + + // Manage the endcap elements: + void TRT_DetectorManager::manageEndcapElement(TRT_EndcapElement *endcap) { + + if ( endcapArray + [endcap->getCode().isPosZ()] + [endcap->getCode().getWheelIndex()] + [endcap->getCode().getStrawLayerIndex()] + [endcap->getCode().getPhiIndex()] ) { + + //Element already added - complain! + if(msgLvl(MSG::DEBUG)) + msg(MSG::DEBUG) << "manageEndcapElement: Overriding existing element"<<endreq; + }; + + endcapArray + [endcap->getCode().isPosZ()] + [endcap->getCode().getWheelIndex()] + [endcap->getCode().getStrawLayerIndex()] + [endcap->getCode().getPhiIndex()] + =endcap; + + if (m_idHelper) { + Identifier id = m_idHelper->layer_id(endcap->getCode().isPosZ() ? +2 : -2, + endcap->getCode().getPhiIndex(), + endcap->getCode().getWheelIndex(), + endcap->getCode().getStrawLayerIndex()); + + IdentifierHash hashId = m_idHelper->straw_layer_hash(id); + if (hashId.is_valid()) { + if (m_elements.size() <= hashId) { + m_elements.resize(static_cast<unsigned int>(hashId) + 1); + } + if (m_elements[hashId]) { + //Element already added - complain! + if(msgLvl(MSG::DEBUG)) + msg(MSG::DEBUG) << "manageEndcapElement: Overriding existing element for hashID"<<endreq; + } + m_elements[hashId]=endcap; + } else { + msg(MSG::WARNING) << "manageEndcapElement: Invalid identifier" << endreq; + } + } + } + + const TRT_BarrelElement *TRT_DetectorManager::getBarrelElement(unsigned int positive, + unsigned int moduleIndex, + unsigned int phiIndex, + unsigned int strawLayerIndex) const { + if ( positive >= 2 || moduleIndex >= NMODMAX + || phiIndex>=NPHIMAX || strawLayerIndex >= NSTRAWLAYMAXBR) return 0; + + return barrelArray[positive][moduleIndex][phiIndex][strawLayerIndex]; + } + + + + TRT_BarrelElement *TRT_DetectorManager::getBarrelElement(unsigned int positive, + unsigned int moduleIndex, + unsigned int phiIndex, + unsigned int strawLayerIndex){ + if ( positive >= 2 || moduleIndex >= NMODMAX + || phiIndex>=NPHIMAX || strawLayerIndex >= NSTRAWLAYMAXBR) return 0; + + return barrelArray[positive][moduleIndex][phiIndex][strawLayerIndex]; + } + + + + + + const TRT_EndcapElement *TRT_DetectorManager::getEndcapElement(unsigned int positive, + unsigned int wheelIndex, + unsigned int strawLayerIndex, + unsigned int phiIndex) const { + + if ( positive >= 2 || wheelIndex >= NWHEELMAX + || phiIndex>=NPHIMAX || strawLayerIndex >= NSTRAWLAYMAXEC) return 0; + + return endcapArray[positive][wheelIndex][strawLayerIndex][phiIndex]; + } + + + TRT_EndcapElement *TRT_DetectorManager::getEndcapElement(unsigned int positive, + unsigned int wheelIndex, + unsigned int strawLayerIndex, + unsigned int phiIndex) { + + if ( positive >= 2 || wheelIndex >= NWHEELMAX + || phiIndex>=NPHIMAX || strawLayerIndex >= NSTRAWLAYMAXEC) return 0; + + return endcapArray[positive][wheelIndex][strawLayerIndex][phiIndex]; + } + + const TRT_ID *TRT_DetectorManager::getIdHelper() const { + return m_idHelper; + } + + + void TRT_DetectorManager::setIdHelper(const TRT_ID *idHelper, bool owns) { + m_idHelper=idHelper; + _ownsIdHelper=owns; + } + + + + const TRT_BaseElement *TRT_DetectorManager::getElement(Identifier id) const { + // Make sure it is a straw_layer id + Identifier strawLayerId = m_idHelper->layer_id(id); + IdentifierHash hashId = m_idHelper->straw_layer_hash(strawLayerId); + if (hashId>=m_elements.size()) return 0; + return m_elements[hashId]; + } + + const TRT_BaseElement *TRT_DetectorManager::getElement(IdentifierHash id) const { + if (id>=m_elements.size()) return 0; + return m_elements[id]; + } + + + const TRT_DetElementCollection * TRT_DetectorManager::getDetectorElementCollection() const { + return &m_elements; + } + + TRT_DetElementCollection::const_iterator TRT_DetectorManager::getDetectorElementBegin() const { + return m_elements.begin(); + } + + TRT_DetElementCollection::const_iterator TRT_DetectorManager::getDetectorElementEnd() const { + return m_elements.end(); + } + + + void TRT_DetectorManager::setBarrelTransformField(size_t i, const GeoXF::Function * f){ + if (_barrelXF[i]!=f) delete _barrelXF[i]; + _barrelXF[i] = f; + } + + const GeoXF::Function * TRT_DetectorManager::barrelTransformField(size_t i) const { + return _barrelXF[i]; + } + + void TRT_DetectorManager::setEndcapTransformField(size_t i, const GeoXF::Function *f) { + if (_endcapXF[i]!=f) delete _endcapXF[i]; + _endcapXF[i]=f; + } + + const GeoXF::Function *TRT_DetectorManager::endcapTransformField(size_t i) const{ + return _endcapXF[i]; + } + + + TRT_DetectorManager::ActiveGasType TRT_DetectorManager::gasType() const + { + return m_gasType; + } + + void TRT_DetectorManager::setGasType(const ActiveGasType & activeGasType) + { + m_gasType = activeGasType; + } + + unsigned int TRT_DetectorManager::digitizationVersion() const + { + return m_digvers; + } + + std::string TRT_DetectorManager::digitizationVersionName() const + { + return m_digversname; + } + + void TRT_DetectorManager::setDigitizationVersion(const unsigned int & dv, const std::string& name ) + { + m_digvers = dv; m_digversname = name; + } + + // Register the call back for this key and the corresponding level in + // in the hierarchy. + // DEPRECATED + void TRT_DetectorManager::addKey(const std::string & key, int level) + { + if(msgLvl(MSG::DEBUG)) + msg(MSG::DEBUG) << "Registering alignmentCallback with key " << key << ", at level " << level + << endreq; + + const DataHandle<AlignableTransform> transformCollection; + m_detStore->regFcn(&TRT_DetectorManager::alignmentCallback, this, transformCollection, key); + addKey(key, level, InDetDD::other); + } + + void TRT_DetectorManager::addKey(const std::string & key, int level, FrameType frame) + { + addChannel(key, level, frame); + } + + void TRT_DetectorManager::addAlignableTransform (int level, + const Identifier &id, + GeoAlignableTransform *transform, + const GeoVPhysVol * child, + const GeoVPhysVol * frameVol) + { + if (m_idHelper) { + // Check if child and frame are actually full physical volumes. + // if they are non zero. + const GeoVFullPhysVol * childFPV = 0; + if (child) { + childFPV = dynamic_cast<const GeoVFullPhysVol *>(child); + } + const GeoVFullPhysVol * frameFPV = 0; + if (frameVol) { + frameFPV = dynamic_cast<const GeoVFullPhysVol *>(frameVol); + } + if (child && !childFPV) { + msg(MSG::ERROR) + << "Child of alignable transform is not a full physical volume" + << endreq; + } else if (frameVol && !frameFPV) { + msg(MSG::ERROR) + << "Frame for alignable transform is not a full physical volume" + << endreq; + } else { + addAlignableTransform (level, id, transform, childFPV, frameFPV); + } + } + } + + void TRT_DetectorManager::addAlignableTransform (int level, + const Identifier &id, + GeoAlignableTransform *transform, + const GeoVFullPhysVol *child, + const GeoVFullPhysVol *frameVol) + { + if (m_idHelper) { + if (level == 0) { + // Nothing implemented. Reserved in case we want alignable straws. + } else { + + ExtendedAlignableTransform * extAlignableTransform = new ExtendedAlignableTransform(transform, child, frameVol); + if(msgLvl(MSG::VERBOSE)) { + msg(MSG::VERBOSE) << "TRT: Adding alignment at level " << level << " " << m_idHelper->show_to_string(id); + if (child && !frameVol) { + msg(MSG::VERBOSE) << " using global frame"; + } else if (!child || child == frameVol ) { + msg(MSG::VERBOSE) << " using local frame"; + } else { + msg(MSG::VERBOSE) << " using other frame"; + } + msg(MSG::VERBOSE) << endreq; + } + // Save in map + int index = level - FIRST_HIGHER_LEVEL; // level 0 treated separately. + if (index >= static_cast<int>(m_alignableTransforms.size())) m_alignableTransforms.resize(index+1); + m_alignableTransforms[index][id] = extAlignableTransform; + } + } + } + + bool TRT_DetectorManager::setAlignableTransformDelta(int level, + const Identifier & id, + const Amg::Transform3D & delta, + FrameType frame) const + { + if (level == 0) { + // Nothing implemented. Reserved in case we want alignable straws + return false; + } else { + + int index = level - FIRST_HIGHER_LEVEL; // level 0 treated separately. + if (index >= static_cast<int>(m_alignableTransforms.size())) return false; + + // We retrieve it from a map. + AlignableTransformMap::const_iterator iter; + iter = m_alignableTransforms[index].find(id); + if (iter == m_alignableTransforms[index].end()) return false; + + return setAlignableTransformAnyFrameDelta(iter->second, delta, frame); + + } + } + + bool TRT_DetectorManager::setAlignableTransformAnyFrameDelta(ExtendedAlignableTransform * extXF, + const Amg::Transform3D & delta, + FrameType frame) const + { + //--------------------- + // For Local: + //--------------------- + // The geomodel alignable transform delta is already a local delta so we just pass it directly + + //--------------------- + // For global frame + //--------------------- + // Sets the alignable transform delta when the supplied delta is in the global frame. + + // If the default transform down to the alignable transform is + // T = A*B*C + // and the alignable transform is C with delta c and the delta in the global frame is g, then + // A*B*C*c = g*A*B*C + // T*c = g*T + // c = T.inverse() * g * T + + // To get default transform up and including the alignable transform, + // we assume the next volume down is a fullphys volume and so its + // transform is the transform we want (ie T=A*B*C in the above example). + + //--------------------- + // For Other frame + //--------------------- + // Sets the alignable transform delta when the supplied delta is in the frame of the + // volume "frameVol". + + // If the default transform down to the alignable transform is + // T = A*B*C + // and the alignable transform is C with delta c and the delta g is expressed in the frame A, then + // A*B*C*c = A*g*B*C + // c = (BC).inverse * g * (BC) + // BC = A.inverse() * T + // C = T.inverse() * A * g * A.inverse() * T + + // To get default transform up and including the alignable transform, + // we assume the next volume down is a fullphys volume and so its + // transform is the transform we want (ie T=A*B*C in the above example). + // The Transform to the frame is T = A which we get from the fullphys volume frameVol. + + if (!extXF) return false; + if (!extXF->alignableTransform()) return false; + + const GeoVFullPhysVol * child = extXF->child(); + const GeoVFullPhysVol * frameVol = extXF->frame(); + + FrameType newFrame = frame; + // If frame is other then check if "other" is actually local or global + if (frame == InDetDD::other) { + if (child && !frameVol) { + // frame = 0 indicates to use global frame + newFrame = InDetDD::global; + } else if (!child || child == frameVol){ + // if child is 0 or the they are the same volumes then its local + newFrame = InDetDD::local; + } // else its "other" already. + } + + if (newFrame == InDetDD::global) { // Global + if (!child) { + msg(MSG::ERROR) << "global frame specified, but child == 0" << endreq; + } else { + const HepGeom::Transform3D & childXF = child->getDefAbsoluteTransform(); + extXF->alignableTransform()->setDelta(childXF.inverse() * Amg::EigenTransformToCLHEP(delta) * childXF); + } + + } else if (frame == InDetDD::local) { // Local + // if its a local frame then no transform necessary. We set it directly. + extXF->alignableTransform()->setDelta(Amg::EigenTransformToCLHEP(delta)); + + } else { // Other frame + // if child or frame is zero it will have been set to local or global above + const HepGeom::Transform3D & xfChild = child->getDefAbsoluteTransform(); + const HepGeom::Transform3D & xfFrame = frameVol->getDefAbsoluteTransform(); + extXF->alignableTransform()->setDelta(xfChild.inverse() * xfFrame * Amg::EigenTransformToCLHEP(delta) * xfFrame.inverse() * xfChild); + } + + return true; + } + + + StatusCode TRT_DetectorManager::alignmentCallback( IOVSVC_CALLBACK_ARGS_P(I,keys) ) + { + return align(I, keys); + } + + + // We invalidate all the elements if at least one alignment changed. + void TRT_DetectorManager::invalidateAll() const + { + for (TRT_DetElementCollection::const_iterator element_iter = getDetectorElementBegin(); + element_iter != getDetectorElementEnd(); + ++element_iter) { + + if (*element_iter) { + (*element_iter)->invalidate(); + } + } + } + + void TRT_DetectorManager::updateAll() const + { + for (TRT_DetElementCollection::const_iterator element_iter = getDetectorElementBegin(); + element_iter != getDetectorElementEnd(); + ++element_iter) { + + if (*element_iter) { + (*element_iter)->updateAllCaches(); + } + } + } + + + bool TRT_DetectorManager::identifierBelongs(const Identifier & id) const + { + return getIdHelper()->is_trt(id); + } + + + bool TRT_DetectorManager::processSpecialAlignment(const std::string & key) const + { + if(msgLvl(MSG::DEBUG)) + msg(MSG::DEBUG) << "Processing TRT fine alignment." << endreq; + + const TRTCond::StrawDxContainer* container = 0; + StatusCode sc = StatusCode::FAILURE; + if (m_detStore->contains<TRTCond::StrawDxContainer>(key)) { + sc = m_detStore->retrieve(container, key); + } + + if (sc.isFailure()) { + if (msgLvl(MSG::INFO)) + msg(MSG::INFO) << "Cannot find StrawDxContainer for key " + << key << " - no fine alignment " << endreq; + throw std::runtime_error("Unable to apply TRT fine alignment. This is normal for simulation"); + //return false; + } else { + + // Loop trough all barrel elements and pass container. + + m_conditions->setDxContainer(container); + + for (TRT_DetElementCollection::const_iterator element_iter = getDetectorElementBegin(); + element_iter != getDetectorElementEnd(); + ++element_iter) { + const TRT_BaseElement * element = *element_iter; + if (element) { + element->invalidate(); + } + } + return false; // we return false as we have already invalidated the elements + } + } + + + void TRT_DetectorManager::setConditions(TRT_Conditions * conditions) + { + // Should only be set once. + if (m_conditions) { + msg(MSG::WARNING) << "TRT_DetectorManager: Attempt to reset TRT_Conditions" << endreq; + return; + } + m_conditions = conditions; + m_conditions->ref(); + } + + const TRT_Conditions* TRT_DetectorManager::conditions() const + { + return m_conditions; + } + +} // namespace InDetDD diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_EndcapCode.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_EndcapCode.cxx new file mode 100755 index 0000000000000000000000000000000000000000..b9e32123d79e7e30f3467a96f7ae0fabd7120a7f --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_EndcapCode.cxx @@ -0,0 +1,69 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "InDetReadoutGeometry/TRT_EndcapCode.h" +#include <string> +#include <sstream> + +namespace InDetDD { + +// +// Mask +// +const int TRT_EndcapCode::Z_MASK = 0x00000001; // lowest six bits +const int TRT_EndcapCode::WHEEL_MASK = 0x0000001F; // lowest five +const int TRT_EndcapCode::STRAWLAYER_MASK = 0x0000001F; // lowest five +const int TRT_EndcapCode::PHIPOS_MASK = 0x0000001F; + +// +// Shifts +// +const int TRT_EndcapCode::Z_SHIFT = 0; +const int TRT_EndcapCode::WHEEL_SHIFT = 1; +const int TRT_EndcapCode::STRAWLAYER_SHIFT = 6; +const int TRT_EndcapCode::PHIPOS_SHIFT = 11; + +TRT_EndcapCode::TRT_EndcapCode() +{ + _key = 0; +} + +TRT_EndcapCode::TRT_EndcapCode(unsigned isPos, unsigned wheelIndex, unsigned strawLayerIndex, unsigned int phiIndex) + : + _key ((( isPos & Z_MASK ) << Z_SHIFT) | + (( wheelIndex & WHEEL_MASK ) << WHEEL_SHIFT) | + (( strawLayerIndex & STRAWLAYER_MASK ) << STRAWLAYER_SHIFT) | + (( phiIndex & PHIPOS_MASK ) << PHIPOS_SHIFT)) +{ +} + +TRT_EndcapCode::TRT_EndcapCode(const TRT_EndcapCode &right) +{ + _key = right.getKey(); +} + + + + +TRT_EndcapCode::~TRT_EndcapCode() +{ +} + + +const TRT_EndcapCode & TRT_EndcapCode::operator=(const TRT_EndcapCode &right) +{ + _key = right.getKey(); + return *this; +} + + + +std::string TRT_EndcapCode::getName() const { + + std::ostringstream outputStream; + outputStream << this; + return outputStream.str(); +} + +} diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_EndcapDescriptor.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_EndcapDescriptor.cxx new file mode 100755 index 0000000000000000000000000000000000000000..4f22b1133299fef0ddf8af9dfb5f35f8978eb039 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_EndcapDescriptor.cxx @@ -0,0 +1,71 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "InDetReadoutGeometry/TRT_EndcapDescriptor.h" + +#include "TrkSurfaces/CylinderBounds.h" + +#include "CLHEP/Units/SystemOfUnits.h" + +namespace InDetDD { + + + +TRT_EndcapDescriptor::TRT_EndcapDescriptor(): + _nStraws(0), + _strawPitch(0), + _startPhi(0), + _strawLength(0), + _innerRadius(0), + m_innerTubeRadius(2*CLHEP::mm), // FIXME: Hardwired for now!! + _f(NULL), + _o(0), + m_bounds(0) +{ + +} + + +TRT_EndcapDescriptor::~TRT_EndcapDescriptor() +{ + delete m_bounds; +} + + + +void TRT_EndcapDescriptor::setStrawTransformField(const GeoXF::Function *xf, size_t offsetInto) { + _f=xf; + _o=offsetInto; +} + + + +unsigned int &TRT_EndcapDescriptor::nStraws() { + return _nStraws; +} + +double & TRT_EndcapDescriptor::strawPitch() { + return _strawPitch; +} + +double & TRT_EndcapDescriptor::startPhi() { + return _startPhi; +} + +double & TRT_EndcapDescriptor::strawLength() { + return _strawLength; +} + +double & TRT_EndcapDescriptor::innerRadius() { + return _innerRadius; +} + +const Trk::SurfaceBounds & +TRT_EndcapDescriptor::strawBounds() const +{ + if (!m_bounds) m_bounds = new Trk::CylinderBounds(m_innerTubeRadius, 0.5*_strawLength); + return *m_bounds; +} + +} diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_EndcapElement.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_EndcapElement.cxx new file mode 100755 index 0000000000000000000000000000000000000000..c9c905884c9b72624a7585871f14531e0082500e --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_EndcapElement.cxx @@ -0,0 +1,260 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "InDetReadoutGeometry/TRT_EndcapElement.h" +#include "InDetReadoutGeometry/SurfaceCache.h" +#include "InDetReadoutGeometry/TRT_Conditions.h" + +#include "InDetIdentifier/TRT_ID.h" +#include "Identifier/Identifier.h" + +#include "GeoPrimitives/GeoPrimitives.h" +#include "GeoPrimitives/CLHEPtoEigenConverter.h" + +#include "CLHEP/Geometry/Transform3D.h" + +#include "TrkSurfaces/DiscBounds.h" +#include "TrkSurfaces/DiscSurface.h" + +#include "TRT_ConditionsData/ExpandedIdentifier.h" +#include "TRT_ConditionsData/StrawDxContainer.h" + + +namespace InDetDD { + + TRT_EndcapElement::TRT_EndcapElement(const GeoVFullPhysVol *volume, + const TRT_EndcapDescriptor *descriptor, + bool isPositive, + unsigned int wheelIndex, + unsigned int strawLayIndex, + unsigned int phiIndex, + const TRT_ID * idHelper, + const TRT_Conditions * conditions) : + TRT_BaseElement(volume, + idHelper->layer_id((isPositive ? 2:-2), phiIndex, wheelIndex, strawLayIndex), + idHelper, conditions), + _code(isPositive,wheelIndex,strawLayIndex,phiIndex), + _descriptor(descriptor), + _nextInZ(NULL), + _previousInZ(NULL), + m_surface(0) + + { + _descriptor->ref(); + } + + + TRT_EndcapElement::~TRT_EndcapElement() + { + _descriptor->unref(); + delete m_surface; + } + + unsigned int TRT_EndcapElement::nStraws() const + { + return _descriptor->nStraws(); + } + + const double & TRT_EndcapElement::strawLength() const + { + return _descriptor->strawLength(); + } + + + const TRT_EndcapConditions * TRT_EndcapElement::getConditionsData() const + { + return NULL; + } + + const TRT_EndcapDescriptor * TRT_EndcapElement::getDescriptor() const + { + return _descriptor; + } + + void TRT_EndcapElement::setNextInZ(const TRT_EndcapElement *element) + { + _nextInZ=element; + } + + void TRT_EndcapElement::setPreviousInZ(const TRT_EndcapElement *element) + { + _previousInZ=element; + } + + + HepGeom::Transform3D TRT_EndcapElement::calculateStrawTransform(int straw) const + { + // NB The tranformation to a straw is reconstructed here precisely as + // it was ... hopefully... in the factory. One could eliminate this + // requirement and make the code a little more robust in this regard but + // at the cost of doubling the descriptors. (One descriptor now suffices + // for both positive and negative endcaps). + const GeoXF::Function *f= _descriptor->getStrawTransform(); + + if (f) { + int istraw = _code.isPosZ() ? straw : _descriptor->nStraws()-1 - straw; + + size_t offsetInto = _descriptor->getStrawTransformOffset(); + + return getMaterialGeom()->getAbsoluteTransform()*((*f)(istraw+offsetInto)) * calculateLocalStrawTransform(straw); + ////return conditions()->solenoidFrame() + //// * getMaterialGeom()->getAbsoluteTransform()*((*f)(istraw+offsetInto)); + + } else { + + // Will not work properly with alignments. + std::cout << "ALTERNATIVE METHOD" << std::endl; + + double phi = _descriptor->startPhi() + _descriptor->strawPitch() * straw; + double r = _descriptor->innerRadius() + 0.5 * _descriptor->strawLength() ; + CLHEP::Hep3Vector pos(r*cos(phi), r*sin(phi), (getMaterialGeom()->getAbsoluteTransform()*HepGeom::Point3D<double>()).z()); + CLHEP::HepRotation rot; + // Axis (in local (0,0,1)) points towards beam axis. + rot.rotateY(-0.5*M_PI); // Make it point along -ve X. + rot.rotateZ(phi); + return HepGeom::Transform3D(rot, pos); + } + + } + + // The L3 Alignment + HepGeom::Transform3D TRT_EndcapElement::calculateLocalStrawTransform(int straw) const + { + const TRTCond::StrawDxContainer* container = conditions()->dxContainer(); + HepGeom::Transform3D rc ; + if (container) { + + // important note: dx1 moves the 'negative' wire endpoint end dx2 + // the 'positive' wire endpoint in the local straw frame. + // In the global frame, 'dx1' corresponds to the readout side and 'dx2' + // to the side closest the beampipe. + + int bec = getCode().isPosZ() ? +2 : -2 ; + int wheel = getCode().getWheelIndex(); + int phimodule = getCode().getPhiIndex(); + int strawlayer = getCode().getStrawLayerIndex(); + TRTCond::ExpandedIdentifier id = TRTCond::ExpandedIdentifier(bec + ,wheel + ,phimodule + ,strawlayer + ,straw + ,TRTCond::ExpandedIdentifier::STRAW); + + double dx1 = container->getDx1(id); + double dx2 = container->getDx2(id); + double ang = (dx2-dx1)/strawLength(); + double dy = -1*(dx2+dx1)/2.; + + // In the local straw frame: + // - the z-axis is along the straw and points toward the beampipe + // - the x-axis is along global-z and away from the interaction point + // (locX = globZ A-side / locX = -1 *gobZ C-side) + // - the y-axis is along global phi_hat direction determined by the other 2. + // (clockwise C-side, counter clockwise A-Side) + rc = HepGeom::TranslateY3D(dy)*HepGeom::RotateX3D(ang) ; + } + return rc ; + } + + HepGeom::Transform3D TRT_EndcapElement::defStrawTransform(int straw) const + { + // Same as calculateStrawTransform, except we use getDefAbsoluteTransform() + // rather than getAbsoluteTransform() + + // NB The tranformation to a straw is reconstructed here precisely as + // it was ... hopefully... in the factory. One could eliminate this + // requirement and make the code a little more robust in this regard but + // at the cost of doubling the descriptors. (One descriptor now suffices + // for both positive and negative endcaps). + + const GeoXF::Function *f= _descriptor->getStrawTransform(); + + if (f) { + + int istraw = _code.isPosZ() ? straw : _descriptor->nStraws()-1 - straw; + + size_t offsetInto = _descriptor->getStrawTransformOffset(); + return getMaterialGeom()->getDefAbsoluteTransform()*((*f)(istraw+offsetInto)); + + } else { + + double phi = _descriptor->startPhi() + _descriptor->strawPitch() * straw; + double r = _descriptor->innerRadius() + 0.5 * _descriptor->strawLength() ; + CLHEP::Hep3Vector pos(r*cos(phi), r*sin(phi), (getMaterialGeom()->getDefAbsoluteTransform()*HepGeom::Point3D<double>()).z()); + CLHEP::HepRotation rot; + rot.rotateY(-0.5*M_PI); // Make it point along -ve X. + rot.rotateZ(phi); + return HepGeom::Transform3D(rot, pos); + } + + } + + const Trk::SurfaceBounds& TRT_EndcapElement::strawBounds() const + { + return _descriptor->strawBounds(); + } + + const Trk::Surface& TRT_EndcapElement::elementSurface() const + { + if (!m_surface) m_surface = new Trk::DiscSurface(*this); + return *m_surface; + } + + void TRT_EndcapElement::createSurfaceCache() const + { + // Calculate the surface + double phiCenter = _descriptor->startPhi() + _descriptor->strawPitch() * 0.5*(nStraws()-1); + double phiHalfWidth = 0.5 * _descriptor->strawPitch() * nStraws(); + double rMin = _descriptor->innerRadius(); + double rMax = rMin +_descriptor->strawLength(); + + // The transform of the endcap is a translation in z for no + // misalignement. For the -ve endcap there is also a 180deg rotation + // around the y axis. getAbsoluteTransform() will also include the + // misalignment. + // + // To get the transform of the element we have to first rotate + // around z to the phi center of the element. We want the local z + // to point in the same direction for both endcaps (approximately + // global z axis). For the negative endcap we therefore have to + // rotate 180 CLHEP::deg around the Y axis. + + // We need to rotate to phi center before we apply the + // misalignment. However, in the negative endcap the the phi + // location is inverted (due to 180 rotation around y axis). This is + // taken care of by the extra 180 CLHEP::deg rotation around Y that we do + // to get the z axis pointing in the correct direction. + + Amg::Transform3D * transform = 0; + if (_code.isPosZ()) + transform = new Amg::Transform3D(Amg::CLHEPTransformToEigen( (getMaterialGeom()->getAbsoluteTransform() * HepGeom::RotateZ3D(phiCenter)))); + else + transform = new Amg::Transform3D(Amg::CLHEPTransformToEigen( (getMaterialGeom()->getAbsoluteTransform() * HepGeom::RotateY3D(180*CLHEP::deg) * HepGeom::RotateZ3D(phiCenter)))); + + // create the igredients and the cache + Trk::DiscBounds* bounds = new Trk::DiscBounds(rMin, rMax, phiHalfWidth); + Amg::Vector3D* center = new Amg::Vector3D(transform->translation()); + Amg::Vector3D* normal = new Amg::Vector3D(transform->rotation().col(2)); + m_surfaceCache = new SurfaceCache(transform, center, normal, bounds); + // create the surface if needed + if (!m_surface) m_surface = new Trk::DiscSurface(*this); + + } + + + + int TRT_EndcapElement::strawDirection() const + { + // Return +1 if the straw local axis is in the same direction as increasing eta direction, + // -1 otherwise. + // The straw axis by convention goes in the direction away from the readout. This is + // towards the beam pipe. For +ve endcap it is what we want. For -ve endcap it is oppposite. + // + // + return (_code.isPosZ()) ? +1 : -1; + } + +} // end namespace + + diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_Numerology.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_Numerology.cxx new file mode 100755 index 0000000000000000000000000000000000000000..aa7ee5b73519cf159b5337bdf3efc4bfe65ccb93 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/TRT_Numerology.cxx @@ -0,0 +1,50 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "InDetReadoutGeometry/TRT_Numerology.h" +namespace InDetDD { + +TRT_Numerology::TRT_Numerology() : + _nringBarrel(0), + _nphiBarrel(0), + _nwheelEndcap(0), + _nphiEndcap(0) +{ + // Zero out the arrays + for (int i = 0; i < 3; i++) { + _nlayerBarrel[i] = 0; + } + for (int j = 0; j < 18; j++) { + _nlayerEndcap[j] = 0; + } +} + +TRT_Numerology::~TRT_Numerology() { +} + +void TRT_Numerology::setNBarrelLayers(unsigned int module, unsigned int nLayers) { + _nlayerBarrel[module]=nLayers; +} + +void TRT_Numerology::setNEndcapLayers(unsigned int wheel, unsigned int nLayers) { + _nlayerEndcap[wheel]=nLayers; +} + +void TRT_Numerology::setNBarrelRings(unsigned int ring) { + _nringBarrel = ring; +} + +void TRT_Numerology::setNBarrelPhi(unsigned int phi) { + _nphiBarrel = phi; +} + +void TRT_Numerology::setNEndcapWheels(unsigned int wheel) { + _nwheelEndcap = wheel; +} + +void TRT_Numerology::setNEndcapPhi(unsigned int phi) { + _nphiEndcap = phi; +} +} + diff --git a/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/Version.cxx b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/Version.cxx new file mode 100755 index 0000000000000000000000000000000000000000..44e21ba143cb21385b3184623153acd45fcb5594 --- /dev/null +++ b/InnerDetector/InDetDetDescr/InDetReadoutGeometry/src/Version.cxx @@ -0,0 +1,121 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "InDetReadoutGeometry/Version.h" + +#include <sstream> +#include <string> +#include <iomanip> + +namespace InDetDD { + +Version::Version(const std::string & tag, + const std::string & name, + const std::string & layout, + const std::string & description, + int major, + int minor, + int patch) + : m_tag(tag), + m_name(name), + m_layout(layout), + m_description(description), + m_major(major), + m_minor(minor), + m_patch(patch) +{} + +// For backward compatibility +Version::Version(const std::string & name, + const std::string & layout, + const std::string & description, + int major, + int minor, + int patch) + : m_tag("-"), + m_name(name), + m_layout(layout), + m_description(description), + m_major(major), + m_minor(minor), + m_patch(patch) +{} + + + +Version::Version() + : m_major(0), + m_minor(0), + m_patch(0) +{} + +const std::string & +Version::tag() const +{ + return m_tag; +} + +const std::string & +Version::name() const +{ + return m_name; +} + +const std::string & +Version::layout() const +{ + return m_layout; +} + +const std::string & +Version::description() const +{ + return m_description; +} + +int +Version::majorNum() const +{ + return m_major; +} + +int +Version::minorNum() const +{ + return m_minor; +} + +int +Version::patchNum() const +{ + return m_patch; +} + +std::string +Version::versionNumber() const +{ + std::ostringstream ostr; + ostr << m_major + << "." << std::setfill('0') << std::setw(2) << m_minor + << "." << std::setfill('0') << std::setw(2) << m_patch; + return ostr.str(); +} + +std::string +Version::fullDescription() const +{ + + // Output of the form + // Version: SCT-DC1-00, Name: DC1, Layout: Final, Code Version: 02.01.01, Description: DC1 Geometry + + std::ostringstream ostr; + ostr << "Version: " << m_tag << ", Name: " << m_name << ", Layout: " << m_layout + << ", Code Version: " << versionNumber(); + if (!m_description.empty()) { + ostr << ", Description: " << m_description; + } + return ostr.str(); +} + +} // namespace InDetDD