From 5f3a7445cfb5cadf1c9ece2381fe18a19238f795 Mon Sep 17 00:00:00 2001 From: Dave Casper <dcasper@uci.edu> Date: Mon, 5 Aug 2019 18:33:02 -0700 Subject: [PATCH] Work in progress on DetectorManager --- .../ScintDetectorManager.h | 154 +++++++ .../ScintDetectorManagerBase.h | 204 +++++++++ .../ScintReadoutGeometry/ScintNumerology.h | 77 ++++ .../ScintReadoutGeometry/Version.h | 91 ++++ .../VetoDetectorManager.h | 65 +-- .../src/ScintDetectorManager.cxx | 149 ++++++ .../src/ScintDetectorManagerBase.cxx | 424 ++++++++++++++++++ .../ScintReadoutGeometry/src/Version.cxx | 121 +++++ 8 files changed, 1253 insertions(+), 32 deletions(-) create mode 100644 Scintillator/ScintDetDescr/ScintReadoutGeometry/ScintReadoutGeometry/ScintDetectorManager.h create mode 100644 Scintillator/ScintDetDescr/ScintReadoutGeometry/ScintReadoutGeometry/ScintDetectorManagerBase.h create mode 100644 Scintillator/ScintDetDescr/ScintReadoutGeometry/ScintReadoutGeometry/ScintNumerology.h create mode 100644 Scintillator/ScintDetDescr/ScintReadoutGeometry/ScintReadoutGeometry/Version.h create mode 100644 Scintillator/ScintDetDescr/ScintReadoutGeometry/src/ScintDetectorManager.cxx create mode 100644 Scintillator/ScintDetDescr/ScintReadoutGeometry/src/ScintDetectorManagerBase.cxx create mode 100644 Scintillator/ScintDetDescr/ScintReadoutGeometry/src/Version.cxx diff --git a/Scintillator/ScintDetDescr/ScintReadoutGeometry/ScintReadoutGeometry/ScintDetectorManager.h b/Scintillator/ScintDetDescr/ScintReadoutGeometry/ScintReadoutGeometry/ScintDetectorManager.h new file mode 100644 index 000000000..103cd6e50 --- /dev/null +++ b/Scintillator/ScintDetDescr/ScintReadoutGeometry/ScintReadoutGeometry/ScintDetectorManager.h @@ -0,0 +1,154 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// ScintDetectorManager.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef SCINTREADOUTGEOMETRY_SCINTDETECTORMANAGER_H +#define SCINTREADOUTGEOMETRY_SCINTDETECTORMANAGER_H + +#include "ScintReadoutGeometry/ScintDetectorManagerBase.h" + +#include "ScintReadoutGeometry/ScintDetectorElementCollection.h" +#include "ScintReadoutGeometry/ScintDD_Defs.h" +#include "ScintReadoutGeometry/ScintNumerology.h" + +// Amg stuff +#include "GeoPrimitives/GeoPrimitives.h" + +#include "CLHEP/Geometry/Transform3D.h" + +#include <string> +#include <map> + +class StoreGateSvc; +class Identifier; +class IdentifierHash; +class FaserDetectorID; +class GeoAlignableTransform; +class GeoVAlignmentStore; + +namespace InDetDD { + +class ScintDetectorElement; +class ScintDetectorDesign; +class ExtendedAlignableTransform; +class ScintNumerology; + + /** @class ScintDetectorManager + + Base class for Scintillator 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. + + @author: Grant Gorfine + - modified and maintained by Nick Styles & Andreas Salzburger + */ + + class ScintDetectorManager : public ScintDetectorManagerBase { + + + public: + + // Constructor + ScintDetectorManager(StoreGateSvc * detStore, const std::string & name); + + // Destructor + virtual ~ScintDetectorManager() {}; + + + // + // Access Readout Elements + // + + /** access to individual elements using Identifier or IdentiferHash */ + virtual ScintDetectorElement * getDetectorElement(const Identifier &id) const = 0; + virtual ScintDetectorElement * getDetectorElement(const IdentifierHash &idHash) const = 0; + + /** access to whole collectiom */ + virtual const ScintDetectorElementCollection * getDetectorElementCollection() const = 0; + virtual ScintDetectorElementCollection::const_iterator getDetectorElementBegin() const = 0; + virtual ScintDetectorElementCollection::const_iterator getDetectorElementEnd() const = 0; + + + /** Add elememts */ + virtual void addDetectorElement(ScintDetectorElement * 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; + + /** 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, + GeoVAlignmentStore* alignStore=nullptr) 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, + GeoVAlignmentStore* alignStore=nullptr) const; + + /** Access to module design */ + void addDesign(const ScintDetectorDesign *); + int numDesigns() const; + const ScintDetectorDesign * getDesign(int i) const; + + /** Access Numerology */ + const ScintNumerology & numerology() const {return m_numerology;} + ScintNumerology & numerology() {return m_numerology;} + + private: + //** Prevent copy and assignment */ + const ScintDetectorManager & operator=(const ScintDetectorManager &right); + ScintDetectorManager(const ScintDetectorManager &right); + + /** This method is called by the InDetDetectorManager */ + virtual bool setAlignableTransformDelta(int level, + const Identifier & id, + const Amg::Transform3D & delta, + FrameType frame, + GeoVAlignmentStore* alignStore) const = 0; + + + + std::string m_tag; + ScintNumerology m_numerology; + std::vector< const ScintDetectorDesign *> m_designs; + + }; + + +} // namespace InDetDD + +#ifndef GAUDI_NEUTRAL +#include "AthenaKernel/CLASS_DEF.h" + +CLASS_DEF(InDetDD::SiDetectorManager, 1441401, 1) +#endif + +#endif // SCINTREADOUTGEOMETRY_SCINTDETECTORMANAGER_H diff --git a/Scintillator/ScintDetDescr/ScintReadoutGeometry/ScintReadoutGeometry/ScintDetectorManagerBase.h b/Scintillator/ScintDetDescr/ScintReadoutGeometry/ScintReadoutGeometry/ScintDetectorManagerBase.h new file mode 100644 index 000000000..905a7802e --- /dev/null +++ b/Scintillator/ScintDetDescr/ScintReadoutGeometry/ScintReadoutGeometry/ScintDetectorManagerBase.h @@ -0,0 +1,204 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// ScintDectorManagerBase.h (was InDetDetectorManager.h) +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef SCINTREADOUTGEOMETRY_SCINTDETECTORMANAGERBASE_H +#define SCINTREADOUTGEOMETRY_SCINTDETECTORMANAGERBASE_H + +// Amg +#include "GeoPrimitives/GeoPrimitives.h" +// GeoModel stuff +#include "GeoModelKernel/GeoVDetectorManager.h" +#include "ScintReadoutGeometry/ScintDD_Defs.h" +#include "ScintReadoutGeometry/Version.h" +#include "CLHEP/Geometry/Transform3D.h" +// Message Stream Member +#include "AthenaKernel/MsgStreamMember.h" + +// IOV SVC for alignment: +#include "AthenaKernel/IIOVSvc.h" + +#include "DetDescrConditions/AlignableTransformContainer.h" + +#include "CxxUtils/checker_macros.h" + +#include <atomic> +#include <string> +#include <map> +#include <set> +#include <list> + +class StoreGateSvc; +class AlignableTransform; +class Identifier; +class FaserDetectorID; +class GeoVAlignmentStore; +class CondAttrListCollection; + +// mutable Athena::MsgStreamMember issues warnings. +ATLAS_NO_CHECK_FILE_THREAD_SAFETY; + +namespace ScintDD { + + typedef std::map<std::string, const void*> RawAlignmentObjects; + + /** @class ScintDetectorManagerBase + + Virtual base class for all Scintillator 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 ScintDetectorManagerBase : public GeoVDetectorManager { + + public: + + // Constructor + ScintDetectorManagerBase(StoreGateSvc * detStore, const std::string & name); + + // Destructor + virtual ~ScintDetectorManagerBase(); + + + /** 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); + void addGlobalFolder(const std::string & key); + void addAlignFolderType(const AlignFolderType alignfolder); + + StatusCode align( IOVSVC_CALLBACK_ARGS ) const; + + StatusCode align(const RawAlignmentObjects& alignObjects, GeoVAlignmentStore* alignStore) 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; } + + AlignFolderType m_alignfoldertype; + + 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);} + + }; + + class AlignInfo { + + private: + AlignFolderType m_aligntype; + + public: + AlignInfo(): m_aligntype(InDetDD::none) {}; + AlignInfo(AlignFolderType alignfolder): m_aligntype(alignfolder) {}; + AlignFolderType AlignFolder() const {return m_aligntype;} + bool isValidAlign() const {return (m_aligntype != InDetDD::none);} + + }; + + + /** Retrieve level information */ + const LevelInfo & getLevel(const std::string & key) const; + + /** return align folder string to use **/ + // ScintDD::AlignFolderType getAlignInfo(); + + /** Process the alignment container, calls processKey */ + bool processAlignmentContainer(const std::string & key) const; + bool processAlignmentContainer(const AlignableTransformContainer* container, GeoVAlignmentStore* alignStore) const; + + /** Called by processAlignmentContainer, + applies only one key on the transform Collections */ + bool processKey(const std::string key, + const AlignableTransform* transformCollection, + GeoVAlignmentStore* alignStore=nullptr) 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, + GeoVAlignmentStore* alignStore=nullptr) const = 0; + + virtual bool processSpecialAlignment(const std::string & key, + InDetDD::AlignFolderType alignfolder) const = 0; + + virtual bool processSpecialAlignment(const std::string& key, + const CondAttrListCollection* obj=nullptr, + GeoVAlignmentStore* alignStore=nullptr) const = 0; + + bool processGlobalAlignmentContainer(const std::string & key, + const CondAttrListCollection* obj=nullptr, + GeoVAlignmentStore* alignStore=nullptr) const; + + virtual bool processGlobalAlignment(const std::string & key, int level, FrameType frame, + const CondAttrListCollection* obj=nullptr, + GeoVAlignmentStore* alignStore=nullptr) const; + + virtual const FaserDetectorID* 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; + std::set<std::string> m_globalFolders; // new time-dependent global folders + + static const LevelInfo s_invalidLevel; + }; + +} // namespace ScintDD + +#endif // SCINTREADOUTGEOMETRY_SCINTDETECTORMANAGERBASE_H diff --git a/Scintillator/ScintDetDescr/ScintReadoutGeometry/ScintReadoutGeometry/ScintNumerology.h b/Scintillator/ScintDetDescr/ScintReadoutGeometry/ScintReadoutGeometry/ScintNumerology.h new file mode 100644 index 000000000..98fdd4661 --- /dev/null +++ b/Scintillator/ScintDetDescr/ScintReadoutGeometry/ScintReadoutGeometry/ScintNumerology.h @@ -0,0 +1,77 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// ScintNumerology.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + + +#ifndef SCINTREADOUTGEOMETRY_SCINTNUMEROLOGY_H +#define SCINTREADOUTGEOMETRY_SCINTNUMEROLOGY_H + +#include <vector> + +namespace ScintDD { + + /** @class ScintNumerology + + Class to extract numerology for Veto, Trigger and Preshower. For example number of stations, plates, pmts, etc. + See InnerDetector/InDetExample/InDetDetDescrExample/src/SiReadSiDetectorElements.cxx for example of usage. + + @author Grant Gorfine + */ + + class ScintNumerology { + + + public: + + /** Constructor: */ + ScintNumerology(); + + // Accessors: + + /** Number of stations */ + int numStations() const; + + /** Number of plates in a station */ + int numPlatesForStation(int station) const; + + /** Number of pmts for plate */ + int numPmtsForPlate(int station, int plate) const; + + // Check presence of station + /** Check if station exists */ + bool useStation(int station) const; + + // Maximums + /** Maximum number of plates in a station */ + int maxNumPlates() const; + + /** Maximum number of pmts on a plate */ + int maxNumPmts() const; + + // Modifiers: + void setNumStations(int nStations); + void setNumPlatesForStation(int station, int nPlates); + void setNumPmtsForPlate(int station, int plate, int nPmts); + + private: + + int m_numStations; + int m_maxNumStationPlates; + int m_maxNumPlatePmts; + + std::vector<int> m_platesForStation; + std::vector<std::vector<int> > m_pmtsForPlate; + + }; + +}// End namespace + +#include "ScintNumerology.icc" + +#endif // SCINTREADOUTGEOMETRY_SCINTNUMEROLOGY_H diff --git a/Scintillator/ScintDetDescr/ScintReadoutGeometry/ScintReadoutGeometry/Version.h b/Scintillator/ScintDetDescr/ScintReadoutGeometry/ScintReadoutGeometry/Version.h new file mode 100644 index 000000000..0792d719a --- /dev/null +++ b/Scintillator/ScintDetDescr/ScintReadoutGeometry/ScintReadoutGeometry/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 SCINTREADOUTGEOMETRY_VERSION +#define SCINTREADOUTGEOMETRY_VERSION + +#include <string> + +namespace ScintDD { + + /** @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 // SCINTREADOUTGEOMETRY_VERSION diff --git a/Scintillator/ScintDetDescr/ScintReadoutGeometry/ScintReadoutGeometry/VetoDetectorManager.h b/Scintillator/ScintDetDescr/ScintReadoutGeometry/ScintReadoutGeometry/VetoDetectorManager.h index 8b55f5013..acec381d0 100644 --- a/Scintillator/ScintDetDescr/ScintReadoutGeometry/ScintReadoutGeometry/VetoDetectorManager.h +++ b/Scintillator/ScintDetDescr/ScintReadoutGeometry/ScintReadoutGeometry/VetoDetectorManager.h @@ -15,11 +15,11 @@ #include "GeoModelKernel/GeoVPhysVol.h" -#include "ScintReadoutGeometry/SiDetectorManager.h" -#include "ScintReadoutGeometry/SiDetectorElementCollection.h" +#include "ScintReadoutGeometry/ScintDetectorManager.h" +#include "ScintReadoutGeometry/ScintDetectorElementCollection.h" #include "ScintReadoutGeometry/ScintDD_Defs.h" -#include "InDetIdentifier/SCT_ID.h" +#include "ScintIdentifier/VetoID.h" class StoreGateSvc; class Identifier; @@ -30,30 +30,30 @@ class GeoVPhysVol; class GeoVAlignmentStore; class CondAttrListCollection; -namespace InDetDD { +namespace ScintDD { - class SiDetectorElement; + class ScintDetectorElement; class ExtendedAlignableTransform; - class SCT_ModuleSideDesign; + class VetoDetectorDesign; - /** @class SCT_DetectorManager + /** @class VetoDetectorManager - Dedicated detector manager extending the functionality of the SiDetectorManager - with dedicated SCT information, access. + Dedicated detector manager extending the functionality of the ScintDetectorManager + with dedicated Veto information, access. @author: Grant Gorfine - modified and maintained by Nick Styles & Andreas Salzburger */ - class SCT_DetectorManager : public SiDetectorManager { + class VetoDetectorManager : public ScintDetectorManager { public: // Constructor - SCT_DetectorManager( StoreGateSvc* detStore ); + VetoDetectorManager( StoreGateSvc* detStore ); // Destructor - virtual ~SCT_DetectorManager(); + virtual ~VetoDetectorManager(); /** Access Raw Geometry */ virtual unsigned int getNumTreeTops() const override; @@ -67,21 +67,21 @@ namespace InDetDD { // /** access to individual elements via Identifier */ - virtual SiDetectorElement * getDetectorElement(const Identifier &id) const override; + virtual ScintDetectorElement * getDetectorElement(const Identifier &id) const override; /** access to individual elements via IdentifierHash */ - virtual SiDetectorElement * getDetectorElement(const IdentifierHash &idHash) const override; + virtual ScintDetectorElement * getDetectorElement(const IdentifierHash &idHash) const override; /** 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; + ScintDetectorElement * getDetectorElement(int station, int plate) const; /** access to whole collectiom via iterators */ - virtual const SiDetectorElementCollection * getDetectorElementCollection() const override; - virtual SiDetectorElementCollection::const_iterator getDetectorElementBegin() const override; - virtual SiDetectorElementCollection::const_iterator getDetectorElementEnd() const override; + virtual const ScintDetectorElementCollection * getDetectorElementCollection() const override; + virtual ScintDetectorElementCollection::const_iterator getDetectorElementBegin() const override; + virtual ScintDetectorElementCollection::const_iterator getDetectorElementEnd() const override; /** Add elememts during construction */ - virtual void addDetectorElement(SiDetectorElement * element) override; + virtual void addDetectorElement(ScintDetectorElement * element) override; /** Add alignable transforms. No access to these, they will be changed by manager: */ virtual void addAlignableTransform (int level, @@ -100,15 +100,16 @@ namespace InDetDD { /** Initialize the neighbours. This can only be done when all elements are built. */ virtual void initNeighbours() override; - - /** Methods to query which manager we have */ - virtual bool isPixel() const override {return false;} - + + // /** Methods to query which manager we have */ + // virtual bool isPixel() const = 0; + // bool isSCT() const {return !isPixel();} + /** Check identifier is for this detector */ virtual bool identifierBelongs(const Identifier & id) const override; - /** Access to module design, casts to SCT_ModuleSideDesign */ - const SCT_ModuleSideDesign * getSCT_Design(int i) const; + /** Access to module design, casts to VetoDetectorDesign */ + const VetoDetectorDesign * getVetoDesign(int i) const; /** Process new global DB folders for L1 and L2 **/ virtual @@ -127,7 +128,7 @@ namespace InDetDD { private: /** implements the main alignment update for delta transforms in different frames, - it translates into the LocalDelta or GlobalDelta function of SiDetectorManager + it translates into the LocalDelta or GlobalDelta function of ScintDetectorManager */ virtual bool setAlignableTransformDelta(int level, const Identifier & id, @@ -136,19 +137,19 @@ namespace InDetDD { GeoVAlignmentStore* alignStore) const override; /** Prevent copy and assignment */ - const SCT_DetectorManager & operator=(const SCT_DetectorManager &right); - SCT_DetectorManager(const SCT_DetectorManager &right); + const VetoDetectorManager & operator=(const VetoDetectorManager &right); + VetoDetectorManager(const VetoDetectorManager &right); - virtual const SCT_ID * getIdHelper() const override; + virtual const VetoID* getIdHelper() const override; // Private member data std::vector<PVLink> m_volume; - SiDetectorElementCollection m_elementCollection; + ScintDetectorElementCollection 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; + const VetoID* m_idHelper; /** This variable switches the how the local alignment corrections are applied If true they will be calcualted on top of all of other corrections but in the default reference frame @@ -163,7 +164,7 @@ namespace InDetDD { #ifndef GAUDI_NEUTRAL #include "AthenaKernel/CLASS_DEF.h" -CLASS_DEF(InDetDD::SCT_DetectorManager, 72488296, 1) +CLASS_DEF(ScintDD::VetoDetectorManager, 184318568, 1) #endif #endif // SCINTREADOUTGEOMETRY_VETODETECTORMANAGER_H diff --git a/Scintillator/ScintDetDescr/ScintReadoutGeometry/src/ScintDetectorManager.cxx b/Scintillator/ScintDetDescr/ScintReadoutGeometry/src/ScintDetectorManager.cxx new file mode 100644 index 000000000..5b2c721b3 --- /dev/null +++ b/Scintillator/ScintDetDescr/ScintReadoutGeometry/src/ScintDetectorManager.cxx @@ -0,0 +1,149 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + + +#include "GeoPrimitives/CLHEPtoEigenConverter.h" + +#include "ScintReadoutGeometry/ScintDetectorManager.h" +#include "FaserDetDescr/FaserDetectorID.h" +#include "IdDictDetDescr/IdDictManager.h" +#include "StoreGate/StoreGateSvc.h" + +#include "GeoModelKernel/GeoXF.h" +#include "GeoGenericFunctions/Variable.h" +#include "GeoModelKernel/GeoAlignableTransform.h" +#include "DetDescrConditions/AlignableTransformContainer.h" +#include "ScintReadoutGeometry/ScintDetectorElementCollection.h" +#include "ScintReadoutGeometry/ScintDetectorElement.h" +#include "ScintReadoutGeometry/ExtendedAlignableTransform.h" + +#include <iostream> + +namespace ScintDD +{ + + ScintDetectorManager::ScintDetectorManager(StoreGateSvc * detStore, const std::string & name) + : ScintDetectorManagerBase(detStore, name) + { + // Add default folder + addFolder("/Scint/Align"); + } + + const std::string& ScintDetectorManager::tag() const + { + return m_tag; + } + + void ScintDetectorManager::invalidateAll() const + { + for (ScintDetectorElementCollection::const_iterator element_iter = getDetectorElementBegin(); + element_iter != getDetectorElementEnd(); + ++element_iter) { + + if (*element_iter) { + (*element_iter)->invalidate(); + } + } + } + + void ScintDetectorManager::updateAll() const + { + for (ScintDetectorElementCollection::const_iterator element_iter = getDetectorElementBegin(); + element_iter != getDetectorElementEnd(); + ++element_iter) { + if (*element_iter) { + (*element_iter)->updateAllCaches(); + } + } + } + + bool ScintDetectorManager::setAlignableTransformLocalDelta(ExtendedAlignableTransform * extXF, + const Amg::Transform3D & localToGlobalXF, + const Amg::Transform3D & delta, + GeoVAlignmentStore* alignStore) 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 + const GeoTrf::Transform3D& transform = child->getDefAbsoluteTransform(alignStore); + // calucluate the corrected delta according to the formula above + GeoTrf::Transform3D correctedDelta = transform.inverse()*localToGlobalXF // (A*B*C).inverse() * T + * delta // l + * localToGlobalXF.inverse() * transform; // T.inverse() * (A*B*C) + extXF->alignableTransform()->setDelta(correctedDelta, alignStore); + return true; + } else { + return false; + } + } + + bool ScintDetectorManager::setAlignableTransformGlobalDelta(ExtendedAlignableTransform * extXF, + const Amg::Transform3D& delta, + GeoVAlignmentStore* alignStore) 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 GeoTrf::Transform3D& transform = child->getDefAbsoluteTransform(alignStore); + extXF->alignableTransform()->setDelta(transform.inverse() * delta * transform, alignStore); + return true; + } else { + return false; + } + } + + void ScintDetectorManager::addDesign(const ScintDetectorDesign * design) + { + m_designs.push_back(design); + } + + int ScintDetectorManager::numDesigns() const + { + return m_designs.size(); + } + + + const ScintDetectorDesign* ScintDetectorManager::getDesign(int i) const + { + return m_designs[i]; + } + +}// namespace ScintDD diff --git a/Scintillator/ScintDetDescr/ScintReadoutGeometry/src/ScintDetectorManagerBase.cxx b/Scintillator/ScintDetDescr/ScintReadoutGeometry/src/ScintDetectorManagerBase.cxx new file mode 100644 index 000000000..43d4fb3f3 --- /dev/null +++ b/Scintillator/ScintDetDescr/ScintReadoutGeometry/src/ScintDetectorManagerBase.cxx @@ -0,0 +1,424 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + + +#include "ScintReadoutGeometry/ScintDetectorManagerBase.h" + +#include "StoreGate/StoreGateSvc.h" +#include "DetDescrConditions/AlignableTransform.h" +#include "FaserDetDescr/FaserDetectorID.h" +#include "GeoPrimitives/CLHEPtoEigenConverter.h" +#include "AthenaPoolUtilities/CondAttrListCollection.h" +#include "AthenaBaseComps/AthMsgStreamMacros.h" + +#include <map> + +namespace ScintDD +{ + + ScintDetectorManagerBase::ScintDetectorManagerBase(StoreGateSvc * detStore, const std::string & name) + : m_alignfoldertype{none},m_detStore(detStore), + m_msg(name+"DetectorManager") + { + setName(name); + } + + // Destructor + ScintDetectorManagerBase::~ScintDetectorManagerBase() + {} + + + const Version& ScintDetectorManagerBase::getVersion() const + { + return m_version; + } + + const std::string& ScintDetectorManagerBase::getLayout() const + { + return m_version.layout(); + } + + void ScintDetectorManagerBase::setVersion(const Version & version) + { + m_version = version; + } + + void ScintDetectorManagerBase::addChannel(const std::string & key, int level, FrameType frame) + { + std::string frameStr = "other"; + if (frame == ScintDD::global) frameStr = "global"; + if (frame == ScintDD::local) frameStr = "local"; + ATH_MSG_INFO("Registering alignment channel with key " << key << ", level " << level + << ", with frame " << frameStr << "."); + m_keys[key] = LevelInfo(level, frame); + } + + void ScintDetectorManagerBase::addFolder(const std::string & key) + { + m_folders.insert(key); + } + + void ScintDetectorManagerBase::addSpecialFolder(const std::string & key) + { + m_specialFolders.insert(key); + } + + void ScintDetectorManagerBase::addGlobalFolder(const std::string & key) + { + m_globalFolders.insert(key); + } + + void ScintDetectorManagerBase::addAlignFolderType(const AlignFolderType alignfolder) + { + m_alignfoldertype = alignfolder; + } + + // Return the level in the hierarchy (user defined) corresponding to the key. + const ScintDetectorManagerBase::LevelInfo& ScintDetectorManagerBase::getLevel(const std::string & key) const + { + std::map<std::string, LevelInfo>::const_iterator iter; + iter = m_keys.find(key); + if (iter == m_keys.end()) return s_invalidLevel; + return iter->second; + } + + StatusCode ScintDetectorManagerBase::align( IOVSVC_CALLBACK_ARGS_P(I,keys) ) const + { + + (void) I; // avoid warning about unused parameter + + ATH_MSG_DEBUG("AlignmentCallback called "); + + if (!getIdHelper()) return StatusCode::SUCCESS; + + bool alignmentChange = false; + const AlignInfo &aligninfo = AlignInfo(m_alignfoldertype); + + // If dummy arguments + if (keys.empty()) { + + + // New global aligment folders should be processed first + for (std::set<std::string>::const_iterator iterFolders = m_globalFolders.begin(); + iterFolders != m_globalFolders.end(); + ++iterFolders) { + + try { + bool status = processGlobalAlignmentContainer(*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. + ATH_MSG_FATAL(err.what()); + return StatusCode::FAILURE; + } + } + + // 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 + ATH_MSG_FATAL(err.what()); + 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, aligninfo.AlignFolder()); + alignmentChange = (alignmentChange || status); + } catch(std::runtime_error& err) { + // keys are empty when running simualtion. It is normal for detector specific aligments not to exist. + ATH_MSG_INFO(err.what()); + // 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; + + ATH_MSG_DEBUG(" Processing call back key " << key); + + if ( m_globalFolders.find(key) != m_globalFolders.end() ) { + + try { + // New global alignemnts + bool status = processGlobalAlignmentContainer(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 + ATH_MSG_FATAL(err.what()); + return StatusCode::FAILURE; + } + + } else 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 + ATH_MSG_FATAL(err.what()); + return StatusCode::FAILURE; + } + + } else if ( m_specialFolders.find(key) != m_specialFolders.end() ) { + try { + // Detector specific alignments + bool status = processSpecialAlignment(key, aligninfo.AlignFolder()); + 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 + ATH_MSG_FATAL(err.what()); + return StatusCode::FAILURE; + } + } else { + // Should not be any other keys specified in call back. + ATH_MSG_ERROR("Unrecognized key in call back."); + return StatusCode::RECOVERABLE; + } + } + } + + // We invalidate all the elements if at least one alignment changed. + if (alignmentChange) { + invalidateAll(); + } + + return StatusCode::SUCCESS; + } + + StatusCode ScintDetectorManagerBase::align(const RawAlignmentObjects& alignObjects, GeoVAlignmentStore* alignStore) const + { + + ATH_MSG_DEBUG("align() called from an alignment CondAlg"); + if (!getIdHelper()) return StatusCode::SUCCESS; // To Do: is it really a success? + + bool alignmentChange = false; + // const AlignInfo &aligninfo = AlignInfo(m_alignfoldertype); + + for(const auto& alignObj : alignObjects) { + const std::string& key = alignObj.first; + + ATH_MSG_DEBUG(" Processing folder " << key); + + if(m_globalFolders.find(key)!=m_globalFolders.end()) { + try { + // New global alignemnts + const CondAttrListCollection* obj = static_cast<const CondAttrListCollection*>(alignObj.second); + bool status = processGlobalAlignmentContainer(key,obj,alignStore); + 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 + ATH_MSG_FATAL(err.what()); + return StatusCode::FAILURE; + } + } + else if(m_folders.find(key)!=m_folders.end()) { + try { + // Regular alignemnts + const AlignableTransformContainer* container = static_cast<const AlignableTransformContainer*>(alignObj.second); + bool status = processAlignmentContainer(container,alignStore); + 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 + ATH_MSG_FATAL(err.what()); + return StatusCode::FAILURE; + } + } + else if(m_specialFolders.find(key)!=m_specialFolders.end()) { + try { + // Detector specific alignments + const CondAttrListCollection *obj = + static_cast<const CondAttrListCollection*>(alignObj.second); + bool status = processSpecialAlignment(key, obj, alignStore); + 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 + ATH_MSG_FATAL(err.what()); + return StatusCode::FAILURE; + } + } + else { + // Should not be any other keys specified in raw alignment object. + ATH_MSG_ERROR("Unrecognized folder name."); + return StatusCode::RECOVERABLE; + } + } + // To Do: custom caching is not going to work in MT + /* + if(alignmentChange) invalidateAll(); + */ + + return StatusCode::SUCCESS; + } + + bool ScintDetectorManagerBase::processAlignmentContainer(const std::string & key) const + { + bool alignmentChange = false; + + ATH_MSG_DEBUG("Dealing with key as container"); + const AlignableTransformContainer* container; + if (StatusCode::SUCCESS!=m_detStore->retrieve(container, key)) { + ATH_MSG_ERROR("Cannot find AlignableTransformContainer for key " + << key << " - no misalignment"); + // This should not occur in normal situations so we force job to abort. + throw std::runtime_error("Unable to apply Scintillator alignments"); + } + // Check if container is empty - this can occur if it is an invalid IOV. + if (container->empty()) { + ATH_MSG_ERROR("AlignableTransformContainer for key " + << key << " is empty. Probably due to out of range IOV"); + // This should not occur in normal situations so we force job to abort. + throw std::runtime_error("Unable to apply Scintillator 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 ScintDetectorManagerBase::processAlignmentContainer(const AlignableTransformContainer* container, GeoVAlignmentStore* alignStore) const + { + bool alignmentChange = false; + + // Check if container is empty - this can occur if it is an invalid IOV. + if (container->empty()) { + ATH_MSG_ERROR("AlignableTransformContainer " + << " is empty. Probably due to out of range IOV"); // To Do: add key to this printout for making it more informative + // This should not occur in normal situations so we force job to abort. + throw std::runtime_error("Unable to apply Scintillator alignments."); + } + // loop over all the AlignableTransform objects in the collection + // use only the last ones. + std::map<const std::string, const AlignableTransform*> stringToTransform; + for (DataVector<AlignableTransform>::const_iterator pat=container->begin(); + pat!=container->end();++pat) { + stringToTransform[(*pat)->tag()] = *pat; + } + for (std::pair<const std::string, const AlignableTransform*> value: stringToTransform) { + bool status = processKey(value.first, value.second, alignStore); + alignmentChange = (alignmentChange || status); + } + return alignmentChange; + } + + bool ScintDetectorManagerBase::processKey(const std::string key, + const AlignableTransform* transformCollection, + GeoVAlignmentStore* alignStore) 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 (levelInfo.isValid()) { + ATH_MSG_VERBOSE("Processing channel: " << key); + } else { + ATH_MSG_DEBUG("Channel " << key << " not registered in this manager"); + } + // 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) { + ATH_MSG_DEBUG( "Get alignment for identifier " + << getIdHelper()->show_to_string(trans_iter->identify()) + << " at level " << levelInfo.level()); + + // 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(), + alignStore); + + alignmentChange = (alignmentChange || status); + + if (!status) { + if (!identifierBelongs(trans_iter->identify())) { + ATH_MSG_DEBUG("Cannot set AlignableTransform for identifier." + << getIdHelper()->show_to_string(trans_iter->identify()) + << " at level " << levelInfo.level()); + } else { + ATH_MSG_WARNING("Cannot set AlignableTransform for identifier " + << getIdHelper()->show_to_string(trans_iter->identify()) + << " at level " << levelInfo.level()); + ATH_MSG_WARNING("Subsequent WARNINGS will be printed at DEBUG level."); + } + } + } + return alignmentChange; + } + + // We provide a default implementation of any detector specific alignment. + bool ScintDetectorManagerBase::processGlobalAlignmentContainer(const std::string & key, + const CondAttrListCollection* obj, + GeoVAlignmentStore* alignStore) const + { + bool alignmentChange = false; + + ATH_MSG_DEBUG("processing GlobalAlignmentContainer with key: " << key); + // From the key determine what level in hierarchy we are dealing with. + // returns -1 if unrecognized. + const LevelInfo & levelInfo = getLevel(key); + if (levelInfo.isValid()) { + ATH_MSG_VERBOSE("Processing channel: " << key); + } else { + ATH_MSG_DEBUG("Channel " << key << " not registered in this manager"); + } + // 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; + + // Within detector specific code + bool status = processGlobalAlignment(key, levelInfo.level(), levelInfo.frame(), obj, alignStore); + + alignmentChange = (alignmentChange || status); + + return alignmentChange; + + } + + // We provide a default implementation of any detector specific alignment. + bool ScintDetectorManagerBase::processGlobalAlignment(const std::string &, int /*level*/, FrameType /*frame*/, + const CondAttrListCollection* /*obj*/, GeoVAlignmentStore* /*alignStore*/) const + { + return false; + } + + + // We provide a default implementation of any detector specific alignment. + bool ScintDetectorManagerBase::processSpecialAlignment(const std::string &, ScintDD::AlignFolderType) const + { + return false; + } + + const ScintDetectorManagerBase::LevelInfo ScintDetectorManagerBase::s_invalidLevel; + +} // namespace ScintDD diff --git a/Scintillator/ScintDetDescr/ScintReadoutGeometry/src/Version.cxx b/Scintillator/ScintDetDescr/ScintReadoutGeometry/src/Version.cxx new file mode 100644 index 000000000..64751aca5 --- /dev/null +++ b/Scintillator/ScintDetDescr/ScintReadoutGeometry/src/Version.cxx @@ -0,0 +1,121 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "ScintReadoutGeometry/Version.h" + +#include <sstream> +#include <string> +#include <iomanip> + +namespace ScintDD { + +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 ScintDD -- GitLab