diff --git a/Control/CxxUtils/share/OptionalContainer_test.ref b/Control/CxxUtils/share/OptionalContainer_test.ref old mode 100644 new mode 100755 diff --git a/InnerDetector/InDetDetDescr/PixelGeoModelXml/CMakeLists.txt b/InnerDetector/InDetDetDescr/PixelGeoModelXml/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..767118d225c3af1cdbcec4e3fb05a0e8635f8727 --- /dev/null +++ b/InnerDetector/InDetDetDescr/PixelGeoModelXml/CMakeLists.txt @@ -0,0 +1,49 @@ +################################################################################ +# Package: PixelGeoModelXml +################################################################################ + +# Declare the package name: +atlas_subdir( PixelGeoModelXml ) + +# Declare the package's dependencies: +atlas_depends_on_subdirs( PUBLIC + Control/AthenaKernel + Database/AthenaPOOL/RDBAccessSvc + DetectorDescription/GeoModelXml + DetectorDescription/GeoModel/GeoModelUtilities + GaudiKernel + InnerDetector/InDetDetDescr/InDetGeoModelUtils + InnerDetector/InDetDetDescr/PixelReadoutGeometry + InnerDetector/InDetDetDescr/PixelReadoutGeometry + InnerDetector/InDetDetDescr/InDetReadoutGeometry + InnerDetector/InDetSimEvent + PRIVATE + Control/CLIDSvc + Control/SGTools + Control/StoreGate + Database/AthenaPOOL/AthenaPoolUtilities + DetectorDescription/DetDescrCond/DetDescrConditions + DetectorDescription/GeoModel/GeoModelInterfaces + DetectorDescription/GeometryDBSvc + DetectorDescription/Identifier + InnerDetector/InDetDetDescr/InDetIdentifier + Tools/PathResolver ) + +# External dependencies: +find_package( Boost COMPONENTS filesystem thread system ) +find_package( CORAL COMPONENTS CoralBase CoralKernel RelationalAccess ) + +# Component(s) in the package: +atlas_add_library( PixelGeoModelXmlLib + src/*.cxx + PUBLIC_HEADERS PixelGeoModelXml + INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ${CORAL_INCLUDE_DIRS} + LINK_LIBRARIES ${Boost_LIBRARIES} ${CORAL_LIBRARIES} AthenaKernel GeoModelXml GeoModelUtilities GaudiKernel InDetGeoModelUtils InDetReadoutGeometry PixelReadoutGeometry PixelReadoutGeometry StoreGateLib InDetSimEvent + PRIVATE_LINK_LIBRARIES SGTools AthenaPoolUtilities DetDescrConditions Identifier InDetIdentifier PathResolver) + +atlas_add_component( PixelGeoModelXml + src/components/*.cxx + LINK_LIBRARIES SGTools StoreGateLib SGtests AthenaPoolUtilities DetDescrConditions Identifier InDetIdentifier PixelGeoModelXmlLib ) + +# Install files from the package: +atlas_install_python_modules( python/*.py ) diff --git a/InnerDetector/InDetDetDescr/PixelGeoModelXml/PixelGeoModelXml/ITkPixelDetectorTool.h b/InnerDetector/InDetDetDescr/PixelGeoModelXml/PixelGeoModelXml/ITkPixelDetectorTool.h new file mode 100644 index 0000000000000000000000000000000000000000..e2c7d441be59b1a254bb8521bdd9349cd512691d --- /dev/null +++ b/InnerDetector/InDetDetDescr/PixelGeoModelXml/PixelGeoModelXml/ITkPixelDetectorTool.h @@ -0,0 +1,52 @@ + +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef PixelGeoModelXml_ITKPIXELDETECTORTOOL_H +#define PixelGeoModelXml_ITKPIXELDETECTORTOOL_H +// +// Create an Athena Tool; handle Athena services and Tools needed for +// building the Pixel geometry. Then create the geometry using the PixelDetectorFactory. +// This is the entry to the PixelGeoModelXml package. +// +#include "GeoModelUtilities/GeoModelTool.h" +#include "GaudiKernel/ServiceHandle.h" +#include "GaudiKernel/ToolHandle.h" + +#include <string> + +class IGeoModelSvc; +class IRDBAccessSvc; +class IGeoDbTagSvc; +class IGeometryDBSvc; + +namespace InDetDD { + class PixelDetectorManager; + class AthenaComps; + class SiCommonItems; +} + +class ITkPixelDetectorTool : public GeoModelTool { + public: + ITkPixelDetectorTool(const std::string &type, const std::string &name, const IInterface *parent); + virtual ~ITkPixelDetectorTool(); + StatusCode create() override final; + StatusCode clear() override final; + StatusCode registerCallback() override final; + virtual StatusCode align(IOVSVC_CALLBACK_ARGS_P(I,keys)) override; + + private: + std::string m_detectorName; + bool m_alignable; + std::string m_gmxFilename; + const InDetDD::PixelDetectorManager *m_manager; + InDetDD::AthenaComps *m_athenaComps; + InDetDD::SiCommonItems *m_commonItems; + ServiceHandle<IGeoModelSvc> m_geoModelSvc; + ServiceHandle<IRDBAccessSvc> m_rdbAccessSvc; + ServiceHandle<IGeometryDBSvc> m_geometryDBSvc; + ServiceHandle< IGeoDbTagSvc > m_geoDbTagSvc; +}; + +#endif // PixelGeoModelXml_ITKPIXELDETECTORTOOL_H diff --git a/InnerDetector/InDetDetDescr/PixelGeoModelXml/PixelGeoModelXml/ModuleTree.h b/InnerDetector/InDetDetDescr/PixelGeoModelXml/PixelGeoModelXml/ModuleTree.h new file mode 100644 index 0000000000000000000000000000000000000000..e34a88d7d6a797c01329698a4b178ce2f75630b2 --- /dev/null +++ b/InnerDetector/InDetDetDescr/PixelGeoModelXml/PixelGeoModelXml/ModuleTree.h @@ -0,0 +1,65 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef PIXEL_GEOMODELXML_MODULETREE_H +#define PIXEL_GEOMODELXML_MODULETREE_H +// +// For "numerology". Create a nested set of maps. Bottom layer of leaves are module information. +// Order is barrelEndcap/layerDisk/etaModule/phiModule; each of these has a map of integer-key (the +// value of the integer index) and value -- a map to the next layer down. +// +// User should only create the top level item, a ModuleTree, and Modules (which are copied: user deletes his own copy). +// add(bec, layer, phi, eta, Module) for each module. +// +// Then the number of items at a given layer can be found from the nXxxxxs member functions of each sub-layer. +// +#include <map> +#include <string> +#include <sstream> + +// Error message build up is spread in many routines; instead of cerr, build up a string. Caller can +// print this string with Athena message service. Make it static to give it internal linkage. +static std::ostringstream errmsg; + +class Module { +public: + Module(int unsigned hashId): m_hashId(hashId) {} + unsigned int hashId() {return m_hashId;} + void setHashId(unsigned int hashId) {m_hashId = hashId;} +private: + unsigned int m_hashId; +}; + +class PhiModule: public std::map<int, Module> { +public: + bool add(int phi, Module &module); + Module & operator[](int phi) {return at(phi);} + int nPhiModules() const {return size();} +}; + +class EtaModule: public std::map<int, PhiModule> { +public: + bool add(int eta, int phi, Module &module); + PhiModule & operator[](int eta) {return at(eta);} + int nEtaModules() const {return size();} +}; + +class LayerDisk: public std::map<int, EtaModule> { +public: + bool add(int ld, int eta, int phi, Module &module); + EtaModule & operator[](int ld) {return at(ld);} + int nLayers() const {return size();} +}; + +class BarrelEndcap: public std::map<int, LayerDisk> { +public: + bool add(int bec, int ld, int eta, int phi, Module &module, std::string &errorMessage); + LayerDisk & operator[](int bec) {return at(bec);} + int nParts() const {return size();} +}; + +class ModuleTree: public BarrelEndcap { // Just a more descriptive name for the class. +}; + +#endif diff --git a/InnerDetector/InDetDetDescr/PixelGeoModelXml/PixelGeoModelXml/PixelDetectorFactory.h b/InnerDetector/InDetDetDescr/PixelGeoModelXml/PixelGeoModelXml/PixelDetectorFactory.h new file mode 100644 index 0000000000000000000000000000000000000000..7a689ecfc6bf85dfcf01fc7358677519945b3ee6 --- /dev/null +++ b/InnerDetector/InDetDetDescr/PixelGeoModelXml/PixelGeoModelXml/PixelDetectorFactory.h @@ -0,0 +1,50 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef PixelGeoModelXml_PIXELDETECTORFACTORY_H +#define PixelGeoModelXml_PIXELDETECTORFACTORY_H +// +// Main routine to build the GeoModel geometry, and handle the GeometryManager and +// DetectorManager. +// +#include "InDetGeoModelUtils/InDetDetectorFactoryBase.h" +#include "PixelReadoutGeometry/PixelDetectorManager.h" +#include "PixelGeoModelXml/ModuleTree.h" + +namespace InDetDD {class AthenaComps; class SiCommonItems;} +class GeoPhysVol; + +namespace InDetDDSLHC { + class PixelOptions; + + class PixelDetectorFactory : public InDetDD::DetectorFactoryBase { + public: + PixelDetectorFactory(InDetDD::AthenaComps *athenaComps, + InDetDD::SiCommonItems *commonItems, + PixelOptions &options); + virtual ~PixelDetectorFactory(); + // Creation of geometry: + virtual void create(GeoPhysVol *world); + // Access to the results: + virtual InDetDD::PixelDetectorManager * getDetectorManager() const; + // Print out how many of each layer/eta/phi etc. have been set up. + void doNumerology(); + // Get the xml from the database instead of a file. Returns gzipped xml as a string. + std::string getBlob(); + // Determine which alignment folders are loaded to decide if we register old or new folders + //virtual InDetDD::AlignFolderType getAlignFolderType() const; + + private: + // Copy and assignments operations illegal and so are made private + PixelDetectorFactory(PixelDetectorFactory &right); + PixelDetectorFactory & operator=(PixelDetectorFactory &right); + + InDetDD::PixelDetectorManager *m_detectorManager; + InDetDD::AthenaComps *m_athenaComps; + InDetDD::SiCommonItems *m_commonItems; + PixelOptions *m_options; + ModuleTree m_moduleTree; + }; +} +#endif diff --git a/InnerDetector/InDetDetDescr/PixelGeoModelXml/PixelGeoModelXml/PixelGmxInterface.h b/InnerDetector/InDetDetDescr/PixelGeoModelXml/PixelGeoModelXml/PixelGmxInterface.h new file mode 100644 index 0000000000000000000000000000000000000000..bc80f6c8359123aa03da36f8448a3e872a7f6ce1 --- /dev/null +++ b/InnerDetector/InDetDetDescr/PixelGeoModelXml/PixelGeoModelXml/PixelGmxInterface.h @@ -0,0 +1,80 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef PIXELGEOMODELXML_PIXELGMXINTERFACE_H +#define PIXELGEOMODELXML_PIXELGMXINTERFACE_H + +#include "GeoModelXml/GmxInterface.h" +//#include "GaudiKernel/MsgStream.h" + +#include <map> +#include <memory> +// For template functions getparm(s):----------- +#include <string> +#include <cstdlib> +#include <iostream> +#include <sstream> +//---------------------------------------------- + +#include "PixelGeoModelXml/ModuleTree.h" + +class MsgStream; +namespace InDetDD {class SiDetectorDesign; class PixelDetectorManager; class SiCommonItems;} + +class PixelGmxInterface: public GmxInterface { + public: + PixelGmxInterface(InDetDD::PixelDetectorManager *detectorManager, InDetDD::SiCommonItems *commonItems, ModuleTree *moduleTree); + ~PixelGmxInterface(); + int moduleId(std::map<std::string, int> &index); + void addModuleType(std::string clas, std::string typeName, std::map<std::string, std::string> parameters); + void addModule(std::string typeName, std::map<std::string, int> &index, int sequentialId, + GeoVFullPhysVol *fpv); + // void addAlignable(int level, std::map<std::string, int> &index, GeoVFullPhysVol *fpv, GeoAlignableTransform *transform); + void makePixelModule(std::string typeName, std::map<std::string, std::string> &par); + + template <typename T> void getparm(const std::string typeName, const std::string name, + const std::map<std::string, std::string> &par, T &value) { + std::map<std::string, std::string>::const_iterator found; + if ((found = par.find(name)) != par.end()) { + std::istringstream(found->second) >> value; + } + else{ + std::string errMessage("PixelGmxInterface::addModuleType: Error: missing parameter " + name + " for " + typeName); + throw std::runtime_error(errMessage); + } + } + + template <typename T, typename A> void getparms(const std::string typeName, const std::string name, + const std::map<std::string, std::string> &par, std::vector<T, A> &vec) { + std::map<std::string, std::string>::const_iterator found; + if ((found = par.find(name)) != par.end()) { + T value; + std::string strVal(found->second); + strVal.erase(strVal.find_last_not_of(" \t\n\r\f\v") + 1); // Pixel trailing white space or you get an extra 0 + std::istringstream inString(strVal); + do { + inString >> value; + vec.push_back(value); + } + while (inString.good()); + } + else { + std::string errMessage("PixelGmxInterface::addModuleType: Error: missing parameters " + name + " for " + typeName); + throw std::runtime_error(errMessage); + } + } + + std::string getstr(const std::string typeName, const std::string name, const std::map<std::string, std::string> &par); + + private: + std::map<std::string, int> m_geometryMap; + InDetDD::PixelDetectorManager *m_detectorManager; + InDetDD::SiCommonItems *m_commonItems; + ModuleTree *m_moduleTree; + std::unique_ptr<MsgStream> m_log; +}; + + + +#endif // PIXELGEOMODELXML_PIXELGMXINTERFACE_H diff --git a/InnerDetector/InDetDetDescr/PixelGeoModelXml/PixelGeoModelXml/PixelOptions.h b/InnerDetector/InDetDetDescr/PixelGeoModelXml/PixelGeoModelXml/PixelOptions.h new file mode 100644 index 0000000000000000000000000000000000000000..53b2c9b333b8926986cf511b7bd31eba6270e349 --- /dev/null +++ b/InnerDetector/InDetDetDescr/PixelGeoModelXml/PixelGeoModelXml/PixelOptions.h @@ -0,0 +1,74 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef PixelGeoModelXml_PixelOptions_H +#define PixelGeoModelXml_PixelOptions_H +#include <string> + +namespace InDetDDSLHC { + // + // Class to store run time options. + // + class PixelOptions { + public: + PixelOptions(); + bool alignable() const; + bool alignAtModuleLevel() const; + std::string gmxFilename() const; + std::string detectorName() const; + void setAlignable(bool flag = true); + void setAlignAtModuleLevel(bool flag = true); + void setGmxFilename(std::string filename); + void setDetectorName(std::string detectorname); + + private: + bool m_alignable; + bool m_alignModule; + std::string m_gmxFilename; + std::string m_detectorName; + }; + + // Inlined methods + + inline PixelOptions::PixelOptions() : + m_alignable(true), + m_alignModule(true), + m_gmxFilename(""), + m_detectorName("ITkPixel") + {} + + inline bool PixelOptions::alignable() const { + return m_alignable; + } + + inline bool PixelOptions::alignAtModuleLevel() const { + return m_alignModule; + } + + inline std::string PixelOptions::gmxFilename() const { + return m_gmxFilename; + } + + inline std::string PixelOptions::detectorName() const { + return m_detectorName; + } + + inline void PixelOptions::setAlignable(bool flag) { + m_alignable = flag; + } + + inline void PixelOptions::setAlignAtModuleLevel(bool flag) { + m_alignModule = flag; + } + + inline void PixelOptions::setGmxFilename(std::string filename) { + m_gmxFilename = filename; + } + + inline void PixelOptions::setDetectorName(std::string detectorname) { + m_detectorName = detectorname; + } + +} +#endif // PixelGeoModelXml_PixelOptions_H diff --git a/InnerDetector/InDetDetDescr/PixelGeoModelXml/python/ITkPixelGeoModelConfig.py b/InnerDetector/InDetDetDescr/PixelGeoModelXml/python/ITkPixelGeoModelConfig.py new file mode 100644 index 0000000000000000000000000000000000000000..4ac34754bc035330b80913c1ad0a611c527651d5 --- /dev/null +++ b/InnerDetector/InDetDetDescr/PixelGeoModelXml/python/ITkPixelGeoModelConfig.py @@ -0,0 +1,18 @@ +# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + +from AthenaConfiguration.ComponentFactory import CompFactory +#Comment to avoid python compilation warnings until block below is re-added +#from IOVDbSvc.IOVDbSvcConfig import addFoldersSplitOnline + +def ITkPixelGeometryCfg( flags ): + from AtlasGeoModel.GeoModelConfig import GeoModelCfg + acc = GeoModelCfg( flags ) + geoModelSvc=acc.getPrimary() + GeometryDBSvc=CompFactory.GeometryDBSvc + acc.addService(GeometryDBSvc("ITkGeometryDBSvc")) + PixelDetectorTool=CompFactory.ITkPixelDetectorTool + ITkPixelDetectorTool = PixelDetectorTool() + #ITkPixelDetectorTool.useDynamicAlignFolders = flags.GeoModel.Align.Dynamic + ITkPixelDetectorTool.Alignable = False # make this a flag? Set true as soon as decided on folder structure + ITkPixelDetectorTool.DetectorName = "ITkPixel" + geoModelSvc.DetectorTools += [ ITkPixelDetectorTool ] diff --git a/InnerDetector/InDetDetDescr/PixelGeoModelXml/src/ITkPixelDetectorTool.cxx b/InnerDetector/InDetDetDescr/PixelGeoModelXml/src/ITkPixelDetectorTool.cxx new file mode 100644 index 0000000000000000000000000000000000000000..6263ec716c166114679915c1d172cb4db66ca00b --- /dev/null +++ b/InnerDetector/InDetDetDescr/PixelGeoModelXml/src/ITkPixelDetectorTool.cxx @@ -0,0 +1,223 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#include "PixelGeoModelXml/ITkPixelDetectorTool.h" +#include "PixelGeoModelXml/PixelDetectorFactory.h" +#include "PixelGeoModelXml/PixelOptions.h" +#include "PixelReadoutGeometry/PixelDetectorManager.h" +#include "InDetGeoModelUtils/InDetDDAthenaComps.h" +#include "InDetReadoutGeometry/SiCommonItems.h" +#include "GeoModelUtilities/GeoModelExperiment.h" +#include "GeoModelInterfaces/IGeoModelSvc.h" +#include "GeoModelUtilities/DecodeVersionKey.h" +#include "StoreGate/StoreGateSvc.h" +#include "GeometryDBSvc/IGeometryDBSvc.h" +#include "RDBAccessSvc/IRDBAccessSvc.h" +#include "RDBAccessSvc/IRDBRecord.h" +#include "RDBAccessSvc/IRDBRecordset.h" +#include "DetDescrConditions/AlignableTransformContainer.h" +#include "SGTools/DataProxy.h" + +using InDetDD::PixelDetectorManager; +using InDetDD::SiDetectorManager; + +ITkPixelDetectorTool::ITkPixelDetectorTool(const std::string &type, + const std::string &name, + const IInterface *parent) : + GeoModelTool(type, name, parent), + m_detectorName("ITkPixel"), + m_alignable(false), + m_gmxFilename(""), + m_manager(0), + m_athenaComps(0), + m_commonItems(0), + m_geoModelSvc("GeoModelSvc", name), + m_rdbAccessSvc("RDBAccessSvc", name), + m_geometryDBSvc("InDetGeometryDBSvc", name), + m_geoDbTagSvc{"GeoDbTagSvc", name} + + { +// +// Get parameter values from jobOptions file +// + declareProperty("DetectorName", m_detectorName); + declareProperty("Alignable", m_alignable); + declareProperty("GmxFilename", m_gmxFilename); + declareProperty("RDBAccessSvc", m_rdbAccessSvc); + declareProperty("GeometryDBSvc", m_geometryDBSvc); + declareProperty("GeoModelSvc", m_geoModelSvc); + declareProperty("GeoDbTagSvc", m_geoDbTagSvc); + +} + +ITkPixelDetectorTool::~ITkPixelDetectorTool() { + delete m_athenaComps; + delete m_commonItems; +} + +StatusCode ITkPixelDetectorTool::create() { +// +// Retrieve all services except LorentzAngleSvc, which has to be done later +// + + // Get the detector configuration. + ATH_CHECK(m_geoDbTagSvc.retrieve()); + ATH_CHECK(m_rdbAccessSvc.retrieve()); + ATH_CHECK(m_geometryDBSvc.retrieve()); + GeoModelExperiment *theExpt; + ATH_CHECK(detStore()->retrieve(theExpt, "ATLAS")); + const PixelID *idHelper; + ATH_CHECK(detStore()->retrieve(idHelper, "PixelID")); + +// +// Get their interfaces to pass to the DetectorFactory +// + m_athenaComps = new InDetDD::AthenaComps("PixelGeoModelXml"); + m_athenaComps->setDetStore(&*(detStore())); + m_athenaComps->setRDBAccessSvc(&*m_rdbAccessSvc); + m_athenaComps->setGeometryDBSvc(&*m_geometryDBSvc); + m_athenaComps->setGeoDbTagSvc(&*m_geoDbTagSvc); + + + m_commonItems = new InDetDD::SiCommonItems(idHelper); +// +// Get options from python +// + InDetDDSLHC::PixelOptions options; + options.setAlignable(m_alignable); + options.setGmxFilename(m_gmxFilename); + options.setDetectorName(m_detectorName); +// +// Get the version +// + DecodeVersionKey versionKey(&*m_geoModelSvc, "Pixel"); + if (versionKey.tag() == "AUTO"){ + ATH_MSG_ERROR( "Atlas version tag is AUTO. You must set a version-tag like ATLAS_P2_ITK-00-00-00." ); + return StatusCode::FAILURE; + } + if (versionKey.custom()) + ATH_MSG_INFO( "Building custom "); + else + ATH_MSG_INFO( "Building "); + ATH_MSG_INFO( "Pixel SLHC with Version Tag: "<< versionKey.tag() << " at Node: " << versionKey.node() ); +// +// Get the Database Access Service and from there the pixel version tag +// + std::string pixelVersionTag = m_rdbAccessSvc->getChildTag("Pixel", versionKey.tag(), versionKey.node()); + ATH_MSG_INFO( "Pixel Version: " << pixelVersionTag << " Package Version: " << PACKAGE_VERSION ); +// +// Check if pixel version tag is empty. If so, then the pixel cannot be built. +// This may or may not be intentional. We just issue an INFO message. +// + if (pixelVersionTag.empty()) { + ATH_MSG_INFO( "No Pixel Version. PixelSLHC will not be built." ); + return StatusCode::SUCCESS; + } +// +// Create the PixelDetectorFactory +// + // The * converts a ConstPVLink to a ref to a GeoVPhysVol + // The & takes the address of the GeoVPhysVol + GeoPhysVol *world = &*theExpt->getPhysVol(); + InDetDDSLHC::PixelDetectorFactory thePixel(m_athenaComps, m_commonItems, options); + thePixel.create(world); +// +// Get the manager from the factory and store it in the detector store. +// + m_manager = thePixel.getDetectorManager(); + + if (!m_manager) { + ATH_MSG_ERROR( "PixelDetectorManager not found; not created in PixelDetectorFactory?" ); + return(StatusCode::FAILURE); + } + + StatusCode sc; + sc = detStore()->record(m_manager, m_manager->getName()); + if (sc.isFailure() ) { + ATH_MSG_ERROR( "Could not register PixelDetectorManager" ); + return StatusCode::FAILURE; + } + theExpt->addManager(m_manager); + + // Create a symLink to the SiDetectorManager base class so it can be accessed as either SiDetectorManager or + // PixelDetectorManager + const SiDetectorManager *siDetManager = m_manager; + sc = detStore()->symLink(m_manager, siDetManager); + if(sc.isFailure()){ + ATH_MSG_ERROR( "Could not make link between PixelDetectorManager and SiDetectorManager" ); + return StatusCode::FAILURE; + } +// +// And retrieve the LorentzAngleService. Has to be after the symLink just made, +// which has to be after the manager is made by the DetectorFactory. +// +// if (m_lorentzAngleSvc.empty()) { +// ATH_MSG_INFO( "Lorentz angle service not requested." ); +// } +// else { +// sc = m_lorentzAngleSvc.retrieve(); +// if (sc.isFailure()) { +// ATH_MSG_INFO( "Could not retrieve Lorentz angle service:" << m_lorentzAngleSvc ); +// } +// else { +// ATH_MSG_INFO( "Lorentz angle service retrieved: " << m_lorentzAngleSvc ); +// } +// } + + return StatusCode::SUCCESS; +} + +StatusCode ITkPixelDetectorTool::clear() { + SG::DataProxy* proxy = detStore()->proxy(ClassID_traits<InDetDD::PixelDetectorManager>::ID(),m_manager->getName()); + if(proxy) { + proxy->reset(); + m_manager = 0; + } + return StatusCode::SUCCESS; +} + +StatusCode ITkPixelDetectorTool::registerCallback() { +// +// Register call-back for software alignment +// + StatusCode sc = StatusCode::FAILURE; + if (m_alignable) { + std::string folderName = "/Indet/Align"; + if (detStore()->contains<AlignableTransformContainer>(folderName)) { + ATH_MSG_DEBUG( "Registering callback on AlignableTransformContainer with folder " << folderName ); + const DataHandle<AlignableTransformContainer> atc; + sc = detStore()->regFcn(&IGeoModelTool::align, dynamic_cast<IGeoModelTool *>(this), atc, folderName); + if(sc.isFailure()) { + ATH_MSG_ERROR( "Could not register callback on AlignableTransformContainer with folder " << + folderName ); + } + } + else { + ATH_MSG_WARNING( "Unable to register callback on AlignableTransformContainer with folder " << + folderName << ", Alignment disabled (only if no Run2 scheme is loaded)!" ); + } + } + else { + ATH_MSG_INFO( "Alignment disabled. No callback registered" ); + // We return failure otherwise it will try and register a GeoModelSvc callback associated with this callback. + } + return sc; +} + +StatusCode ITkPixelDetectorTool::align(IOVSVC_CALLBACK_ARGS_P(I, keys)) { +// +// The call-back routine, which just calls the real call-back routine from the manager. +// + if (!m_manager) { + ATH_MSG_WARNING( "Manager does not exist" ); + return StatusCode::FAILURE; + } + if (m_alignable) { + return m_manager->align(I, keys); + } + else { + ATH_MSG_DEBUG( "Alignment disabled. No alignments applied" ); + return StatusCode::SUCCESS; + } +} diff --git a/InnerDetector/InDetDetDescr/PixelGeoModelXml/src/ModuleTree.cxx b/InnerDetector/InDetDetDescr/PixelGeoModelXml/src/ModuleTree.cxx new file mode 100644 index 0000000000000000000000000000000000000000..02831bcb2139d6b1aa21721ab7d235cace544fa8 --- /dev/null +++ b/InnerDetector/InDetDetDescr/PixelGeoModelXml/src/ModuleTree.cxx @@ -0,0 +1,56 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#include "PixelGeoModelXml/ModuleTree.h" + +using namespace std; + +bool PhiModule::add(int phi, Module &module) { + if (count(phi) == 0) { + insert(pair<int, Module>(phi, module)); + return true; + } + else { + errmsg << "ModuleTree ERROR: request to add a second copy of module ignored. Identifier = " << + module.hashId() <<"; phi = " << phi; + return false; + } +} + +bool EtaModule::add(int eta, int phi, Module &module) { + if (count(eta) == 0) { + insert(pair<int, PhiModule>(eta, PhiModule())); + } + if (!(*this)[eta].add(phi, module)) { + errmsg << "; eta = " << eta; + return false; + } + return true; +} + +bool LayerDisk::add(int ld, int eta, int phi, Module &module) { + if (count(ld) == 0) { + insert(pair<int, EtaModule>(ld, EtaModule())); + } + if (!(*this)[ld].add(eta, phi, module)) { + errmsg << "; ld = " << ld; + return false; + } + return true; +} + +bool BarrelEndcap::add(int bec, int ld, int eta, int phi, Module &module, string &errorMessage) { + errorMessage = ""; + errmsg.str(""); + errmsg.str().clear(); + if (count(bec) == 0) { + insert(pair<int, LayerDisk>(bec, LayerDisk())); + } + if (!(*this)[bec].add(ld, eta, phi, module)) { + errmsg << "; bec = " << bec; + errorMessage = errmsg.str(); + return false; + } + return true; +} diff --git a/InnerDetector/InDetDetDescr/PixelGeoModelXml/src/PixelDetectorFactory.cxx b/InnerDetector/InDetDetDescr/PixelGeoModelXml/src/PixelDetectorFactory.cxx new file mode 100644 index 0000000000000000000000000000000000000000..3dac427c6e718233ada4b2e71c603b2485852059 --- /dev/null +++ b/InnerDetector/InDetDetDescr/PixelGeoModelXml/src/PixelDetectorFactory.cxx @@ -0,0 +1,176 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#include "PixelGeoModelXml/PixelDetectorFactory.h" + +#include <string> +#include <sstream> + +#include "StoreGate/StoreGateSvc.h" // For alignment getAlignableFolderType() +#include "AthenaPoolUtilities/CondAttrListCollection.h" +#include "DetDescrConditions/AlignableTransformContainer.h" + +#include "InDetGeoModelUtils/InDetDDAthenaComps.h" +#include "GeoModelKernel/GeoPhysVol.h" +#include "GeoModelInterfaces/IGeoModelSvc.h" +#include "GeoModelUtilities/DecodeVersionKey.h" + +#include "InDetReadoutGeometry/SiCommonItems.h" +#include "PixelReadoutGeometry/PixelDetectorManager.h" +#include "InDetReadoutGeometry/Version.h" +#include "PixelReadoutGeometry/PixelModuleDesign.h" + +#include "RDBAccessSvc/IRDBAccessSvc.h" +#include "RDBAccessSvc/IRDBRecordset.h" +#include "RDBAccessSvc/IRDBRecord.h" + +#include "PixelGeoModelXml/PixelOptions.h" +#include "GeoModelXml/Gmx2Geo.h" +#include "PixelGeoModelXml/PixelGmxInterface.h" +#include "GeoModelXml/GmxInterface.h" + +#include "PathResolver/PathResolver.h" + +using namespace std; + +namespace InDetDDSLHC { + + PixelDetectorFactory::PixelDetectorFactory(InDetDD::AthenaComps *athenaComps, + InDetDD::SiCommonItems *commonItems, + PixelOptions &options) : + InDetDD::DetectorFactoryBase(athenaComps), + m_athenaComps(athenaComps), + m_commonItems(commonItems), + m_options(&options) { + // + // Create the detector manager... should allow the name to be set + // + m_detectorManager = new InDetDD::PixelDetectorManager(detStore(),m_options->detectorName()); + // + // Set Detector Manager pixel version information + // + //At some point we may want to decouple also this DB stuff, and make this ITkStrip specific? + DecodeVersionKey versionKey(geoDbTagSvc(), "Pixel"); + IRDBRecordset_ptr switchSet = rdbAccessSvc()->getRecordsetPtr("PixelSwitches", versionKey.tag(), versionKey.node()); + const IRDBRecord *switches = (*switchSet)[0]; + string layout = "SLHC"; + if (!switches->isFieldNull("LAYOUT")) { + layout = switches->getString("LAYOUT"); + } + string description = "Test geometry"; + if (!switches->isFieldNull("DESCRIPTION")) { + description = switches->getString("DESCRIPTION"); + } + string versionTag = rdbAccessSvc()->getChildTag("Pixel", versionKey.tag(), versionKey.node()); + string versionName = switches->getString("VERSIONNAME"); + int versionMajorNumber = 0; + int versionMinorNumber = 0; + int versionPatchNumber = 0; + InDetDD::Version version(versionTag, versionName, layout, description, versionMajorNumber, + versionMinorNumber, versionPatchNumber); + m_detectorManager->setVersion(version); + } + + PixelDetectorFactory::~PixelDetectorFactory() { + // NB the detector manager (m_detectorManager) is stored in the detector store by the Tool and so we don't delete it. + } + + void PixelDetectorFactory::create(GeoPhysVol *world) { + ATH_MSG_INFO( "C R E A T E W O R L D" ); + + ATH_MSG_INFO( m_detectorManager->getVersion().fullDescription() ); + PixelGmxInterface gmxInterface(m_detectorManager, m_commonItems, &m_moduleTree); + // To set up solid geometry only, without having to worry about sensitive detectors etc., and get loads of debug output, + // comment out above line and uncomment the following line; also, switch header files above. + // GmxInterface gmxInterface; + + int flags(0); + string gmxInput; + + if (m_options->gmxFilename() == "") { + ATH_MSG_INFO( "gmxFilename not set; getting .gmx from Geometry database Blob" + ); + flags = 0x1; // Lowest bit ==> string; next bit implies gzip'd but we decided not to gzip + gmxInput = getBlob(); + string dtdFile = '"' + PathResolver::find_file("geomodel.dtd", "DATAPATH") + '"'; + ATH_MSG_INFO( "dtdFile = " << dtdFile ); + size_t index = gmxInput.find("\"geomodel.dtd\""); + if (index != string::npos) { + gmxInput.replace(index, 14, dtdFile); + } + else { + cerr << "Did not find string geomodel.dtd in the gmx input string.\n"; + } + } + else { + flags = 0; + gmxInput = PathResolver::find_file(m_options->gmxFilename(), "DATAPATH"); + if (gmxInput == "") { // File not found + string errMessage("PixelDetectorFactory::create: Unable to find file " + m_options->gmxFilename() + + " with PathResolver; check filename and DATAPATH environment variable"); + throw runtime_error(errMessage); + } + } + + Gmx2Geo gmx2Geo(gmxInput, world, gmxInterface, flags); + // + // Add the tree-top to the detector manager. This also makes it appear as Pixel in VP1. + // It is probably the last (most recently added) thing in the world PV so loop from the + // back looking for our subdetector name. + + // + unsigned int nChildren = world->getNChildVols(); + + for (int iChild = nChildren - 1; iChild>=0; --iChild) { + if (world->getNameOfChildVol(iChild) == "Pixel") { + // The * converts from a ConstPVLink to a reference to a GeoVPhysVol; + // the & takes its address. + m_detectorManager->addTreeTop(&*world->getChildVol(iChild)); + break; + } + } + + doNumerology(); + + m_detectorManager->initNeighbours(); + + } + + string PixelDetectorFactory::getBlob() { + DecodeVersionKey versionKey(geoDbTagSvc(), "Pixel"); + std::string versionTag = versionKey.tag(); + std::string versionNode = versionKey.node(); + ATH_MSG_INFO( "getBlob: versionTag = " << versionTag ); + ATH_MSG_INFO( "getBlob: versionNode = " << versionNode ); + + IRDBAccessSvc *accessSvc = m_athenaComps->rdbAccessSvc(); + // ADA accessSvc->connect(); + IRDBRecordset_ptr recordSetPixel = accessSvc->getRecordsetPtr("ITKXDD", versionTag, versionNode); + if (!recordSetPixel || recordSetPixel->size() == 0) { + ATH_MSG_FATAL( "getBlob: Unable to obtain Pixel recordSet" ); + throw runtime_error("getBlob: Unable to obtain Pixel recordSet"); + } + const IRDBRecord *recordPixel = (*recordSetPixel)[0]; + string pixelString = recordPixel->getString("XMLCLOB"); + // ADA accessSvc->disconnect(); + + return pixelString; + } + + InDetDD::PixelDetectorManager * PixelDetectorFactory::getDetectorManager() const { + return m_detectorManager; + } + + void PixelDetectorFactory::doNumerology() { + InDetDD::SiNumerology n; + + ATH_MSG_INFO( "\n\nPixel Numerology:\n===============\n\nNumber of parts is " << m_moduleTree.nParts() ); + + } + + + + +} + diff --git a/InnerDetector/InDetDetDescr/PixelGeoModelXml/src/PixelGmxInterface.cxx b/InnerDetector/InDetDetDescr/PixelGeoModelXml/src/PixelGmxInterface.cxx new file mode 100644 index 0000000000000000000000000000000000000000..e8080c3552370f34deb5b3bca3480af2fa94ccfb --- /dev/null +++ b/InnerDetector/InDetDetDescr/PixelGeoModelXml/src/PixelGmxInterface.cxx @@ -0,0 +1,202 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#include "PixelGeoModelXml/PixelGmxInterface.h" + +#include <cstdlib> +#include <sstream> + +#include "InDetSimEvent/SiHitIdHelper.h" + +#include "GaudiKernel/ServiceHandle.h" +#include "GaudiKernel/IMessageSvc.h" +#include "GaudiKernel/MsgStream.h" + +#include "PixelReadoutGeometry/PixelDetectorManager.h" +#include "PixelReadoutGeometry/PixelModuleDesign.h" +#include "PixelReadoutGeometry/PixelDiodeMatrix.h" +#include "PixelReadoutGeometry/PixelMultipleConnection1D.h" +#include "InDetReadoutGeometry/SiDetectorDesign.h" +#include "InDetReadoutGeometry/SiDetectorElement.h" +#include "InDetReadoutGeometry/SiCommonItems.h" + +const int PixelHitIndex = 0; + +using namespace std; + +PixelGmxInterface::PixelGmxInterface(InDetDD::PixelDetectorManager *detectorManager, InDetDD::SiCommonItems *commonItems, ModuleTree *moduleTree): + m_detectorManager(detectorManager), + m_commonItems(commonItems), + m_moduleTree(moduleTree) { + // Logging: ref https://wiki.bnl.gov/dayabay/index.php?title=Logging + // Turn on logging in job-options with: MessageSvc.setDebug += {"PixelGmxInterface"} + ServiceHandle<IMessageSvc> msgh("MessageSvc", "PixelGmxInterface"); + + m_log = std::make_unique<MsgStream>(&(*msgh), "PixelGmxInterface"); +} + +PixelGmxInterface::~PixelGmxInterface() { +} + +int PixelGmxInterface::moduleId(map<string, int> &index){ + // + // Return the Simulation HitID (nothing to do with "ATLAS Identifiers" aka "Offline Identifiers") + + int hitIdOfModule = SiHitIdHelper::GetHelper()->buildHitId(PixelHitIndex, index["barrel_endcap"], index["layer_wheel"], + index["eta_module"], index["phi_module"], index["side"]); + + *m_log << MSG::DEBUG << "Index list: " << index["barrel_endcap"] << " " << index["layer_wheel"] << " " << + index["eta_module"] << " " << index["phi_module"] << " " << index["side"] << endmsg; + *m_log << MSG::DEBUG << "hitIdOfModule = " << std::hex << hitIdOfModule << std::dec << endmsg; + *m_log << MSG::DEBUG << " bec = " << SiHitIdHelper::GetHelper()->getBarrelEndcap(hitIdOfModule) << + " lay = " << SiHitIdHelper::GetHelper()->getLayerDisk(hitIdOfModule) << + " eta = " << SiHitIdHelper::GetHelper()->getEtaModule(hitIdOfModule) << + " phi = " << SiHitIdHelper::GetHelper()->getPhiModule(hitIdOfModule) << + " side = " << SiHitIdHelper::GetHelper()->getSide(hitIdOfModule) << endmsg; + return hitIdOfModule; +} + + +void PixelGmxInterface::addModuleType(string clas, string typeName, map<string, string> parameters){ + + *m_log << MSG::DEBUG << "PixelGmxInterface::addModuleType called for class " << clas << " typeName " << typeName << + endmsg; + if (clas == "PixelModule") { + makePixelModule(typeName, parameters); + } + else { + *m_log << MSG::ERROR << "PixelGmxInterface::addModuleType: unrecognised module class, " << clas << endmsg; + *m_log << MSG::ERROR << "No module design created" << endmsg; + } +} + +void PixelGmxInterface::makePixelModule(string typeName, map<string, string> &par){ + // + // Get all parameters. + // This comes from PixelModuleDesign + // + double thickness(2.075); + int circuitsPerColumn(10); + int circuitsPerRow(10); + int cellColumnsPerCircuit(10); + int cellRowsPerCircuit(10); + int diodeColumnsPerCircuit(10); + int diodeRowsPerCircuit(10); + std::shared_ptr<InDetDD::PixelDiodeMatrix> matrix; + InDetDD::CarrierType carrier(InDetDD::electrons); + int readoutSide(-1); + bool is3D(false); + + string car = getstr(typeName, "carrierType", par); + if (car == "electrons") { + carrier = InDetDD::electrons; + } + else if (car == "holes") { + carrier = InDetDD::holes; + } + else { + *m_log << MSG::FATAL << + "PixelGmxInterface::makePixelModule: Error: parameter carrierType should be electrons or holes for " << + typeName << endmsg; + throw runtime_error("PixelGmxInterface::makePixelModule: Error: parameter carrierType should be electrons or holes for " + + typeName); + } + string ros = getstr(typeName, "readoutSide", par); + if (ros == "+") { + readoutSide = 1; + } + else if (ros == "-") { + readoutSide = -1; + } + else { + *m_log << MSG::FATAL << + "PixelGmxInterface::makePixelModule: Error: parameter readoutSide should be + or - for " << typeName << endmsg; + throw runtime_error("PixelGmxInterface::makePixelModule: Error: parameter readoutSide should be + or - for " + typeName); + } + getparm(typeName, "thickness", par, thickness); + getparm(typeName, "circuitsPerColumn", par, circuitsPerColumn); + getparm(typeName, "circuitsPerRow", par, circuitsPerRow); + getparm(typeName, "cellColumnsPerCircuit", par, cellColumnsPerCircuit); + getparm(typeName, "cellRowsPerCircuit", par, cellRowsPerCircuit); + getparm(typeName, "diodeColumnsPerCircuit", par, diodeColumnsPerCircuit); + getparm(typeName, "diodeRowsPerCircuit", par, diodeRowsPerCircuit); + // getparm(typeName, "matrix", par, matrix); + getparm(typeName, "is3D", par, is3D); + + // + // Make Module Design and add to DetectorManager + // + std::unique_ptr<InDetDD::PixelModuleDesign> design=std::make_unique<InDetDD::PixelModuleDesign>(thickness, + circuitsPerColumn, circuitsPerRow, + cellColumnsPerCircuit, cellRowsPerCircuit, + diodeColumnsPerCircuit, diodeRowsPerCircuit, + matrix, + carrier, + readoutSide, is3D); + m_detectorManager->addDesign(std::move(design)); + + // Add to map for addModule routine + m_geometryMap[typeName] = m_detectorManager->numDesigns() -1; +} + +string PixelGmxInterface::getstr(const string typeName, const string name, const map<string, string> &par) { + map<string, string>::const_iterator found; + if ((found = par.find(name)) != par.end()) { + return found->second; + } + else { + *m_log << MSG::FATAL << "PixelGmxInterface::addModuleType: Error: missing parameter " << name << " for " << + typeName << endmsg; + throw runtime_error("PixelGmxInterface::addModuleType: Error: missing parameter " + name + " for " + typeName); + } + +} + +void PixelGmxInterface::addModule(string typeName, map<string, int> &index, int /*sensitiveId*/, GeoVFullPhysVol *fpv) { + // + // Get the ATLAS "Offline" wafer identifier + // + const PixelID *pixelIdHelper = dynamic_cast<const PixelID *> (m_commonItems->getIdHelper()); + Identifier id = pixelIdHelper->wafer_id(index["barrel_endcap"], index["layer_wheel"], index["phi_module"], + index["eta_module"]); + IdentifierHash hashId = pixelIdHelper->wafer_hash(id); + // + // Now do our best to check if this is a valid id. If either the gmx file is wrong, or the xml file + // defining the allowed id's is wrong, you can get disallowed id's. These cause a crash later + // if allowed through. To do the check, we ask for the hash-id of this id. Invalid ids give a + // special invalid hash-id (0xFFFFFFFF). But we don't exit the run, to help debug things quicker. + // + if (!hashId.is_valid()) { + *m_log << MSG::ERROR <<"Invalid id for sensitive module " << typeName << " volume with indices \n"; + for (map<string, int>::iterator i = index.begin(); i != index.end(); ++i) { + *m_log << MSG::ERROR << i->first << " = " << i->second << "; "; + } + *m_log << MSG::ERROR << + "\nRefusing to make it into a sensitive element. Incompatible gmx and identifier-xml files." << endmsg; + return; + } + // + // Create the detector element and add to the DetectorManager + // + const InDetDD::SiDetectorDesign *design = m_detectorManager->getDesign(m_geometryMap[typeName]); + + if (!design) { + *m_log << MSG::FATAL << "PixelGmxInterface::addSensor: Error: Readout sensor type " << typeName << + " not found.\n" << endmsg; + throw runtime_error("PixelGmxInterface::addSensor: Error: Readout sensor type " + typeName + " not found."); + } + InDetDD::SiDetectorElement *detector = new InDetDD::SiDetectorElement(id, design, fpv, m_commonItems); + m_detectorManager->addDetectorElement(detector); + // + // Build up a map-structure for numerology + // + Module module((unsigned int) hashId); + string errorMessage(""); + if (!m_moduleTree->add(index["barrel_endcap"], index["layer_wheel"], index["eta_module"], + index["phi_module"], module, errorMessage)) { + *m_log << MSG::ERROR << errorMessage << endmsg; + } + return; +} + diff --git a/InnerDetector/InDetDetDescr/PixelGeoModelXml/src/components/PixelGeoModelXml_entries.cxx b/InnerDetector/InDetDetDescr/PixelGeoModelXml/src/components/PixelGeoModelXml_entries.cxx new file mode 100644 index 0000000000000000000000000000000000000000..d03297782e2c48f5b5a41b23423ab532c129bc50 --- /dev/null +++ b/InnerDetector/InDetDetDescr/PixelGeoModelXml/src/components/PixelGeoModelXml_entries.cxx @@ -0,0 +1,3 @@ +#include "PixelGeoModelXml/ITkPixelDetectorTool.h" + +DECLARE_COMPONENT( ITkPixelDetectorTool )