diff --git a/CMakeLists.txt b/CMakeLists.txt index 0fafefc1b4d047b8a19b3938fdaf4df8a0e2616d..165d96d02263a8634525d3349977b154c3a5e235 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,8 @@ cmake_minimum_required(VERSION 3.6) set( ATLAS_PROJECT Athena CACHE STRING "The name of the project to build against" ) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + find_package( Athena ) atlas_ctest_setup() diff --git a/DetectorDescription/GeoModel/FaserGeoModel/data/geomDB.sql b/DetectorDescription/GeoModel/FaserGeoModel/data/geomDB.sql index 0f946e43155c49967bbff74adfe7abac4ab3f6c3..c1084b35afdb3fb5cfd5e7e5c9048d67e7e88a7c 100644 --- a/DetectorDescription/GeoModel/FaserGeoModel/data/geomDB.sql +++ b/DetectorDescription/GeoModel/FaserGeoModel/data/geomDB.sql @@ -170,6 +170,18 @@ CREATE TABLE IF NOT EXISTS "SCINTMATCOMPONENTS_DATA2TAG" ( "SCINTMATCOMPONENTS_TAG_ID" SLONGLONG, "SCINTMATCOMPONENTS_DATA_ID" SLONGLONG ); +DROP TABLE IF EXISTS "FASERCOMMON_DATA"; +CREATE TABLE IF NOT EXISTS "FASERCOMMON_DATA" ( + "FASERCOMMON_DATA_ID" SLONGLONG UNIQUE, + "CONFIG" TEXT , + "GEOTYPE" TEXT , + "STRIPGEOTYPE" TEXT +); +DROP TABLE IF EXISTS "FASERCOMMON_DATA2TAG"; +CREATE TABLE IF NOT EXISTS "FASERCOMMON_DATA2TAG" ( + "FASERCOMMON_TAG_ID" SLONGLONG, + "FASERCOMMON_DATA_ID" SLONGLONG +); -- -- Part 2a: HVS data -- @@ -187,8 +199,9 @@ INSERT INTO "HVS_NODE" VALUES (1001, "ScintPlate", 1, 0, NULL); INSERT INTO "HVS_NODE" VALUES (1002, "ScintStation", 1, 0, NULL); INSERT INTO "HVS_NODE" VALUES (1003, "ScintMaterials", 1, 0, NULL); INSERT INTO "HVS_NODE" VALUES (1004, "ScintMatComponents", 1, 0, NULL); +INSERT INTO "HVS_NODE" VALUES (110, "FaserCommon", 0, 0, NULL); -- Data for the HVS_TAG2NODE table -INSERT INTO "HVS_TAG2NODE" VALUES (0, "FASER-00", 100000, NULL, 0, 0, 1549238400000000000, NULL, 0); +INSERT INTO "HVS_TAG2NODE" VALUES (0, "FASER-00", 100000, NULL, 0, 0, 1549238400000000000, NULL, 1); INSERT INTO "HVS_TAG2NODE" VALUES (1, "Scintillator-00", 100001, NULL, 0, 0, 1549238400000000000, NULL, 1); INSERT INTO "HVS_TAG2NODE" VALUES (2, "Tracker-00", 100002, NULL, 0, 0, 1549238400000000000, NULL, 1); INSERT INTO "HVS_TAG2NODE" VALUES (3, "Calorimeter-00", 100003, NULL, 0, 0, 1549238400000000000, NULL, 1); @@ -201,6 +214,7 @@ INSERT INTO "HVS_TAG2NODE" VALUES (1001, "ScintPlate-00", 100009, NULL, 0, 0, 15 INSERT INTO "HVS_TAG2NODE" VALUES (1002, "ScintStation-00", 100010, NULL, 0, 0, 1549238400000000000, NULL, 1); INSERT INTO "HVS_TAG2NODE" VALUES (1003, "ScintMaterials-00", 100011, NULL, 0, 0, 1549238400000000000, NULL, 1); INSERT INTO "HVS_TAG2NODE" VALUES (1004, "ScintMatComponents-00", 100012, NULL, 0, 0, 1549238400000000000, NULL, 1); +INSERT INTO "HVS_TAG2NODE" VALUES (110, "FaserCommon-00", 100013, NULL, 0, 0, 1549324800000000000, NULL, 1); -- Data for the HVS_LTAG2LTAG table INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 100000, 1, 100001); INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 100000, 2, 100002); @@ -214,6 +228,7 @@ INSERT INTO "HVS_LTAG2LTAG" VALUES (1, 100001, 1001, 100009); INSERT INTO "HVS_LTAG2LTAG" VALUES (1, 100001, 1002, 100010); INSERT INTO "HVS_LTAG2LTAG" VALUES (1, 100001, 1003, 100011); INSERT INTO "HVS_LTAG2LTAG" VALUES (1, 100001, 1004, 100012); +INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 100000, 110, 100013); -- Data for the HVS_TAGCACHE table INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "FASER", "FASER-00", 100000); INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "Scintillator", "Scintillator-00", 100001); @@ -228,6 +243,7 @@ INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "ScintPlate", "ScintPlate INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "ScintStation", "ScintStation-00", 100010); INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "ScintMaterials", "ScintMaterials-00", 100011); INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "ScintMatComponents", "ScintMatComponents-00", 100012); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "FaserCommon", "FaserCommon-00", 100013); -- -- -- Part 2b: Content (Leaf node) data @@ -787,4 +803,8 @@ INSERT INTO "SCINTMATCOMPONENTS_DATA" VALUES (0, 0, "Carbon", 0.475); INSERT INTO "SCINTMATCOMPONENTS_DATA" VALUES (1, 0, "Hydrogen", 0.525); INSERT INTO "SCINTMATCOMPONENTS_DATA2TAG" VALUES (100012, 0); INSERT INTO "SCINTMATCOMPONENTS_DATA2TAG" VALUES (100012, 1); +-- +-- +INSERT INTO "FASERCOMMON_DATA" VALUES (0, "RUN3", "UNDEFINED", "UNDEFINED"); +INSERT INTO "FASERCOMMON_DATA2TAG" VALUES (100013, 0); COMMIT; diff --git a/DetectorDescription/GeoModel/GeoModelInterfaces/CMakeLists.txt b/DetectorDescription/GeoModel/GeoModelInterfaces/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..9240ff541a90bd70cb5f6787745c187af2ae6e50 --- /dev/null +++ b/DetectorDescription/GeoModel/GeoModelInterfaces/CMakeLists.txt @@ -0,0 +1,15 @@ +################################################################################ +# Package: GeoModelInterfaces +################################################################################ + +# Declare the package name: +atlas_subdir( GeoModelInterfaces ) + +# Declare the package's dependencies: +atlas_depends_on_subdirs( PUBLIC + Control/AthenaKernel + GaudiKernel ) + +# Install files from the package: +atlas_install_headers( GeoModelInterfaces ) + diff --git a/DetectorDescription/GeoModel/GeoModelInterfaces/GeoModelInterfaces/AbsMaterialManager.h b/DetectorDescription/GeoModel/GeoModelInterfaces/GeoModelInterfaces/AbsMaterialManager.h new file mode 100644 index 0000000000000000000000000000000000000000..5d32183e356749b771e19c7b59cecb242bbe2526 --- /dev/null +++ b/DetectorDescription/GeoModel/GeoModelInterfaces/GeoModelInterfaces/AbsMaterialManager.h @@ -0,0 +1,49 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef GEOMODELINTERFACES_ABSMATERIALMANAGER_H +#define GEOMODELINTERFACES_ABSMATERIALMANAGER_H +//---------------------------------------------------------// +// // +// class AbsMaterialManager abstract base class for a // +// material manager. // +// // +// Joe Boudreau March 2003 // +// // +//---------------------------------------------------------// +#include <string> +#include <iostream> +#include <iosfwd> + +class GeoMaterial; +class GeoElement; +class AbsMaterialManager { + + public: + + // Constructor: + AbsMaterialManager() {}; + + // Destructor: + virtual ~AbsMaterialManager() {}; + + // Query the material: + virtual GeoMaterial *getMaterial(const std::string & name) =0; + virtual const GeoMaterial *getMaterial(const std::string & name) const =0; + + // Query the elements: + virtual GeoElement *getElement(const std::string & name) = 0; + virtual const GeoElement *getElement(const std::string & name) const = 0; + + // Query the elements (by atomic number): + virtual GeoElement *getElement(unsigned int atomicNumber) = 0; + virtual const GeoElement *getElement(unsigned int atomicNumber) const = 0; + + virtual std::ostream & printAll(std::ostream & o=std::cout) const = 0; + + +}; + + +#endif diff --git a/DetectorDescription/GeoModel/GeoModelInterfaces/GeoModelInterfaces/IGeoAlignTool.h b/DetectorDescription/GeoModel/GeoModelInterfaces/GeoModelInterfaces/IGeoAlignTool.h new file mode 100644 index 0000000000000000000000000000000000000000..9a321391ff686281a68713a0fc93e3b94bf2f143 --- /dev/null +++ b/DetectorDescription/GeoModel/GeoModelInterfaces/GeoModelInterfaces/IGeoAlignTool.h @@ -0,0 +1,41 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// ***************************************************************************** +// ** +// ** This abstract interface is used by CaloDetDescr/CaloAlignTool. +// ** The main purpose of this interface is to register align() function +// ** as a callback on Cond DB objects at initialization time. +// ** GeoModelSvc instantiates CaloAlignTool after GeoModelSvc::align() has +// ** been registered, by this way it is guaranteed that +// ** CaloAlignTool::align() gets called after LArDetectorTool::align() and +// ** TileDetectorTool::align() +// ** +// ***************************************************************************** + +#ifndef GEOMODELINTERFACES_IGEOALIGNTOOL_H +#define GEOMODELINTERFACES_IGEOALIGNTOOL_H + +#include "GaudiKernel/IAlgTool.h" +#include "AthenaKernel/IOVSvcDefs.h" + +static const InterfaceID IID_IGeoAlignTool( "IGeoAlignTool", 1, 0 ); + +class IGeoAlignTool : virtual public IAlgTool +{ +public: + + /// Retrieve Interface ID + static const InterfaceID& interfaceID() { return IID_IGeoAlignTool; } + + virtual StatusCode align(IOVSVC_CALLBACK_ARGS) = 0; +}; + + +#endif + + + + + diff --git a/DetectorDescription/GeoModel/GeoModelInterfaces/GeoModelInterfaces/IGeoDbTagSvc.h b/DetectorDescription/GeoModel/GeoModelInterfaces/GeoModelInterfaces/IGeoDbTagSvc.h new file mode 100644 index 0000000000000000000000000000000000000000..7b7a6722a62ca7b9385a1c424bdf7adef86a884d --- /dev/null +++ b/DetectorDescription/GeoModel/GeoModelInterfaces/GeoModelInterfaces/IGeoDbTagSvc.h @@ -0,0 +1,49 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef GEOMODELINTERFACES_IGEODBTAGSVC_H +#define GEOMODELINTERFACES_IGEODBTAGSVC_H + +// Include Files +#include "GaudiKernel/IInterface.h" +#include <string> + +namespace GeoModel { + enum GeoConfig { + GEO_RUN1, + GEO_RUN2, + GEO_RUN3, + GEO_RUN4, + GEO_ITk, + GEO_TESTBEAM + }; +} + +static const InterfaceID IID_IGeoDbTagSvc("IGeoDbTagSvc", 1, 0); + +class IGeoDbTagSvc : virtual public IInterface { + public: + // Retrieve interface ID + static const InterfaceID& interfaceID() {return IID_IGeoDbTagSvc;} + + virtual const std::string & faserVersion() const =0; + virtual const std::string & scintVersion() const =0; + // virtual const std::string & SCT_Version() const =0; + // virtual const std::string & caloVersion() const =0; + // virtual const std::string & magFieldVersion() const =0; + // virtual const std::string & cavernInfraVersion() const =0; + + virtual const std::string & scintVersionOverride() const =0; + // virtual const std::string & SCT_VersionOverride() const =0; + // virtual const std::string & caloVersionOverride() const =0; + // virtual const std::string & magFieldVersionOverride() const =0; + // virtual const std::string & cavernInfraVersionOverride() const =0; + + virtual GeoModel::GeoConfig geoConfig() const = 0; +}; + +#endif // GEOMODELINTERFACES_IGEODBTAGSVC_H + + + diff --git a/DetectorDescription/GeoModel/GeoModelInterfaces/GeoModelInterfaces/IGeoModelSvc.h b/DetectorDescription/GeoModel/GeoModelInterfaces/GeoModelInterfaces/IGeoModelSvc.h new file mode 100644 index 0000000000000000000000000000000000000000..a6bda8e0508411869fdcbd18dbf6c401625199ef --- /dev/null +++ b/DetectorDescription/GeoModel/GeoModelInterfaces/GeoModelInterfaces/IGeoModelSvc.h @@ -0,0 +1,67 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef GEOMODELINTERFACES_IGEOMODELSVC_H +#define GEOMODELINTERFACES_IGEOMODELSVC_H + +// Include Files +#include "GeoModelInterfaces/IGeoDbTagSvc.h" +#include "GaudiKernel/IInterface.h" +#include "GaudiKernel/StatusCode.h" +#include "AthenaKernel/IOVSvcDefs.h" +#include <string> + +// Forward declarations +class IIncidentListener; +class Incident; +class IGeoModelTool; + +class IGeoModelSvc : virtual public IInterface { + +public: + + /// Retrieve interface ID + static const InterfaceID& interfaceID(); + + + virtual const std::string & faserVersion() const =0; + virtual const std::string & scintVersion() const =0; + // virtual const std::string & SCT_Version() const =0; + // virtual const std::string & caloVersion() const =0; + // virtual const std::string & magFieldVersion() const =0; + // virtual const std::string & cavernInfraVersion() const =0; + + virtual const std::string & scintVersionOverride() const =0; + // virtual const std::string & SCT_VersionOverride() const =0; + // virtual const std::string & caloVersionOverride() const =0; + // virtual const std::string & magFieldVersionOverride() const =0; + // virtual const std::string & cavernInfraVersionOverride() const =0; + + virtual GeoModel::GeoConfig geoConfig() const = 0; + + // Callback functions + virtual StatusCode align (IOVSVC_CALLBACK_ARGS) = 0; + virtual StatusCode compareTags (IOVSVC_CALLBACK_ARGS) = 0; + + // Access to subsystem tool for callback registration + virtual const IGeoModelTool* getTool(std::string toolName) const = 0; + + // Release GeoModel tree from memory + virtual StatusCode clear() = 0; +}; + +inline +const InterfaceID& +IGeoModelSvc::interfaceID() { + + static const InterfaceID IID(1011, 1, 1); + + return IID; +} + + +#endif // GEOMODELINTERFACES_GEOMODELSVC_H + + + diff --git a/DetectorDescription/GeoModel/GeoModelInterfaces/GeoModelInterfaces/IGeoModelTool.h b/DetectorDescription/GeoModel/GeoModelInterfaces/GeoModelInterfaces/IGeoModelTool.h new file mode 100644 index 0000000000000000000000000000000000000000..307d858b20dba55a69db3a041515800832a52530 --- /dev/null +++ b/DetectorDescription/GeoModel/GeoModelInterfaces/GeoModelInterfaces/IGeoModelTool.h @@ -0,0 +1,38 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef GEOMODELINTERFACES_IGEOMODELTOOL_H +#define GEOMODELINTERFACES_IGEOMODELTOOL_H + +#include "GaudiKernel/IAlgTool.h" +#include "AthenaKernel/IOVSvcDefs.h" + +static const InterfaceID IID_IGeoModelTool( "IGeoModelTool", 1, 0 ); + +class IGeoModelTool : public virtual IAlgTool { +public: + + /// Retrieve Interface ID + static const InterfaceID& interfaceID( ) { return IID_IGeoModelTool; } + + // Abstract interface method(s) + virtual StatusCode create() = 0; + + // This method is designed to perform following tasks: + // 1. Release detector manager from the Detector Store + // 2. Do any extra clean up tasks if necessary + virtual StatusCode clear() = 0; + + // Register callback function on ConDB object + virtual StatusCode registerCallback() = 0; + + // Callback function itself + virtual StatusCode align(IOVSVC_CALLBACK_ARGS) = 0; + +}; + +#endif // GEOMODELINTERFACES_IGEOMODELTOOL_H + + + diff --git a/DetectorDescription/GeoModel/GeoModelInterfaces/GeoModelInterfaces/IGeoSubDetTool.h b/DetectorDescription/GeoModel/GeoModelInterfaces/GeoModelInterfaces/IGeoSubDetTool.h new file mode 100644 index 0000000000000000000000000000000000000000..52437ad15e8ed394cb627e54a715f1475c2185b9 --- /dev/null +++ b/DetectorDescription/GeoModel/GeoModelInterfaces/GeoModelInterfaces/IGeoSubDetTool.h @@ -0,0 +1,37 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef GEOMODELINTERFACES_IGEOSUBDETTOOL_H +#define GEOMODELINTERFACES_IGEOSUBDETTOOL_H + +#include "GaudiKernel/IAlgTool.h" +#include "AthenaKernel/IOVSvcDefs.h" + +class StoreGateSvc; +class GeoVPhysVol; + +static const InterfaceID IID_IGeoSubDetTool( "IGeoSubDetTool", 1, 0 ); + +class IGeoSubDetTool : public virtual IAlgTool { +public: + + /// Retrieve Interface ID + static const InterfaceID& interfaceID( ) { return IID_IGeoSubDetTool; } + + + // Build subdetector in parent + virtual StatusCode build( GeoVPhysVol* parent ) = 0; + + // Register callback function on ConDB object + virtual StatusCode registerCallback( StoreGateSvc* detStore ) = 0; + + // Callback function itself + virtual StatusCode align(IOVSVC_CALLBACK_ARGS) = 0; + +}; + +#endif // GEOMODELINTERFACES_IGEOSUBDETTOOL_H + + + diff --git a/DetectorDescription/GeoModel/GeoModelInterfaces/GeoModelInterfaces/StoredMaterialManager.h b/DetectorDescription/GeoModel/GeoModelInterfaces/GeoModelInterfaces/StoredMaterialManager.h new file mode 100644 index 0000000000000000000000000000000000000000..f988dacd2aa970502408fb39dfa3e31224987042 --- /dev/null +++ b/DetectorDescription/GeoModel/GeoModelInterfaces/GeoModelInterfaces/StoredMaterialManager.h @@ -0,0 +1,58 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef GEOMODELINTERFACES_STOREDMATERIALMANAGER_H +#define GEOMODELINTERFACES_STOREDMATERIALMANAGER_H +//---------------------------------------------------------// +// // +// class StoredMaterialManager This class hold one or more// +// material managers and makes them storeable, under // +// storegate: // +// // +// Joe Boudreau March 2003 // +// // +//---------------------------------------------------------// +#include "GeoModelInterfaces/AbsMaterialManager.h" +#include "AthenaKernel/CLASS_DEF.h" +#include <map> +class StoredMaterialManager:public AbsMaterialManager +{ + public: + typedef std::map<std::string, GeoMaterial* > MaterialMap; + typedef MaterialMap::const_iterator MaterialMapIterator; + + // Constructor: + StoredMaterialManager() {}; + + // Destructor: + virtual ~StoredMaterialManager() {}; + + // Query the material: + virtual GeoMaterial* getMaterial(const std::string& name) = 0; + virtual const GeoMaterial* getMaterial(const std::string& name) const = 0; + + // Query the elements: + virtual GeoElement* getElement(const std::string& name) = 0; + virtual const GeoElement* getElement(const std::string& name) const = 0; + + // Query the elements (by atomic number): + virtual GeoElement* getElement(unsigned int atomicNumber) = 0; + virtual const GeoElement* getElement(unsigned int atomicNumber) const = 0; + + // Add new material + virtual void addMaterial(const std::string& space, GeoMaterial* material) = 0; + virtual void addMaterial(const std::string& space, GeoMaterial* material) const = 0; + + virtual MaterialMapIterator begin() const = 0; + virtual MaterialMapIterator end() const = 0; + + // Number of materials in the manager + virtual size_t size() = 0; + + virtual std::ostream& printAll(std::ostream & o=std::cout) const = 0; +}; + +CLASS_DEF(StoredMaterialManager, 9896,1) + +#endif diff --git a/DetectorDescription/GeoModel/GeoModelSvc/CMakeLists.txt b/DetectorDescription/GeoModel/GeoModelSvc/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..2ae87919c5dad2126b8211c032be1c05b1b2f262 --- /dev/null +++ b/DetectorDescription/GeoModel/GeoModelSvc/CMakeLists.txt @@ -0,0 +1,41 @@ +################################################################################ +# Package: GeoModelSvc +################################################################################ + +# Declare the package name: +atlas_subdir( GeoModelSvc ) + +# Declare the package's dependencies: +atlas_depends_on_subdirs( PRIVATE + Control/CxxUtils + Control/AthenaBaseComps + Control/AthenaKernel + Control/SGTools + Control/StoreGate + Database/RDBAccessSvc + DetectorDescription/GeoModel/GeoModelInterfaces + DetectorDescription/GeoModel/GeoModelUtilities + Event/EventInfo + Event/EventInfoMgt + GaudiKernel ) + +# External dependencies: +find_package( Boost COMPONENTS filesystem thread system ) +find_package( CORAL COMPONENTS CoralBase CoralKernel RelationalAccess ) + + +find_package( GeoModel ) + +# Component(s) in the package: +atlas_add_component( GeoModelSvc + src/GeoModelSvc.cxx + src/GeoDbTagSvc.cxx + src/RDBMaterialManager.cxx + src/components/GeoModelSvc_entries.cxx + INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ${CORAL_INCLUDE_DIRS} ${GEOMODEL_INCLUDE_DIRS} + LINK_LIBRARIES ${Boost_LIBRARIES} ${CORAL_LIBRARIES} ${GEOMODEL_LIBRARIES} AthenaBaseComps CxxUtils AthenaKernel SGTools StoreGateLib SGtests GeoModelUtilities EventInfo GaudiKernel ) + +# Install files from the package: +atlas_install_headers( GeoModelSvc ) +atlas_install_joboptions( share/*.py ) + diff --git a/DetectorDescription/GeoModel/GeoModelSvc/src/GeoDbTagSvc.cxx b/DetectorDescription/GeoModel/GeoModelSvc/src/GeoDbTagSvc.cxx new file mode 100644 index 0000000000000000000000000000000000000000..f0ba30fbd157518ac52399563f168c8d06159aac --- /dev/null +++ b/DetectorDescription/GeoModel/GeoModelSvc/src/GeoDbTagSvc.cxx @@ -0,0 +1,110 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "GeoDbTagSvc.h" +#include "RDBMaterialManager.h" +#include "GaudiKernel/ServiceHandle.h" + +#include "RDBAccessSvc/IRDBAccessSvc.h" +#include "RDBAccessSvc/IRDBRecordset.h" +#include "RDBAccessSvc/IRDBRecord.h" + +GeoDbTagSvc::GeoDbTagSvc(const std::string& name,ISvcLocator* svc) + : AthService(name,svc) + , m_geoConfig(GeoModel::GEO_RUN3) +{ +} + +GeoDbTagSvc::~GeoDbTagSvc() +{ +} + +StatusCode GeoDbTagSvc::initialize() +{ + ATH_MSG_DEBUG("initialize()"); + return StatusCode::SUCCESS; +} + +StatusCode GeoDbTagSvc::finalize() +{ + ATH_MSG_DEBUG("finalize()"); + return StatusCode::SUCCESS; +} + +// Query the interfaces. +// Input: riid, Requested interface ID +// ppvInterface, Pointer to requested interface +// Return: StatusCode indicating SUCCESS or FAILURE. +// N.B. Don't forget to release the interface after use!!! +StatusCode GeoDbTagSvc::queryInterface(const InterfaceID& riid, void** ppvInterface) +{ + if(IGeoDbTagSvc::interfaceID().versionMatch(riid)) { + *ppvInterface = (IGeoDbTagSvc*)this; + addRef(); + return StatusCode::SUCCESS; + } else { + // Interface is not directly available: try out a base class + return AthService::queryInterface(riid, ppvInterface); + } +} + +StatusCode GeoDbTagSvc::setupTags() +{ + ATH_MSG_DEBUG("setupTags()"); + + // Check if the Atlas version has already been set + if(m_FaserVersion.empty()) { + ATH_MSG_FATAL("FASER tag not set!"); + return StatusCode::FAILURE; + } + + // Get RDBAccessSvc + ServiceHandle<IRDBAccessSvc> rdbAccessSvc("RDBAccessSvc", name()); + if(rdbAccessSvc.retrieve().isFailure()) { + ATH_MSG_FATAL("Failed to retrieve RDBAccessSvc"); + return StatusCode::FAILURE; + } + + // Get subsystem tags + m_ScintVersion = (m_ScintVersionOverride.empty() + ? rdbAccessSvc->getChildTag("Scintillator", m_FaserVersion, "FASER") + : m_ScintVersionOverride); + + // m_SCT_Version = (m_SCT_VersionOverride.empty() + // ? rdbAccessSvc->getChildTag("SCT",m_InDetVersion,"InnerDetector") + // : m_SCT_VersionOverride); + + // m_CaloVersion = (m_CaloVersionOverride.empty() + // ? rdbAccessSvc->getChildTag("Calorimeter",m_AtlasVersion,"ATLAS") + // : m_CaloVersionOverride); + + // m_MagFieldVersion = (m_MagFieldVersionOverride.empty() + // ? rdbAccessSvc->getChildTag("MagneticField",m_AtlasVersion,"ATLAS") + // : m_MagFieldVersionOverride); + + // m_CavernInfraVersion = (m_CavernInfraVersionOverride.empty() + // ? rdbAccessSvc->getChildTag("CavernInfra",m_AtlasVersion,"ATLAS") + // : m_CavernInfraVersionOverride); + + // Retrieve geometry config information (RUN1, RUN2, etc...) + IRDBRecordset_ptr faserCommonRec = rdbAccessSvc->getRecordsetPtr("FaserCommon", m_FaserVersion, "FASER"); + if(faserCommonRec->size()==0) { + m_geoConfig = GeoModel::GEO_RUN3; + } + else { + std::string configVal = (*faserCommonRec)[0]->getString("CONFIG"); + if(configVal=="RUN3") + m_geoConfig = GeoModel::GEO_RUN3; + else if(configVal=="RUN4") + m_geoConfig = GeoModel::GEO_RUN4; + else if(configVal=="TESTBEAM") + m_geoConfig = GeoModel::GEO_TESTBEAM; + else { + ATH_MSG_FATAL("Unexpected value for geometry config read from the database: " << configVal); + return StatusCode::FAILURE; + } + } + + return StatusCode::SUCCESS; +} diff --git a/DetectorDescription/GeoModel/GeoModelSvc/src/GeoDbTagSvc.h b/DetectorDescription/GeoModel/GeoModelSvc/src/GeoDbTagSvc.h new file mode 100644 index 0000000000000000000000000000000000000000..f31902469f5e1f4d8ae50f47856b73401a7a8010 --- /dev/null +++ b/DetectorDescription/GeoModel/GeoModelSvc/src/GeoDbTagSvc.h @@ -0,0 +1,74 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef GEOMODELSVC_GEODBTAGSVC_H +#define GEOMODELSVC_GEODBTAGSVC_H + +#include "GeoModelInterfaces/IGeoDbTagSvc.h" +#include "AthenaBaseComps/AthService.h" + +template <class TYPE> class SvcFactory; + +class GeoDbTagSvc : public AthService, virtual public IGeoDbTagSvc +{ + friend class GeoModelSvc; + + public: + virtual StatusCode initialize(); + virtual StatusCode finalize(); + + virtual StatusCode queryInterface( const InterfaceID& riid, void** ppvInterface ); + + friend class SvcFactory<GeoDbTagSvc>; + + GeoDbTagSvc(const std::string& name, ISvcLocator* svc); + virtual ~GeoDbTagSvc(); + + protected: + + void setFaserVersion(const std::string& tag) { m_FaserVersion=tag; } + void setScintVersionOverride(const std::string& tag) { m_ScintVersionOverride=tag; } + // void setSCT_VersionOverride(const std::string& tag) { m_SCT_VersionOverride=tag; } + // void setCaloVersionOverride(const std::string& tag) { m_CaloVersionOverride=tag; } + // void setMagFieldVersionOverride(const std::string& tag) { m_MagFieldVersionOverride=tag; } + // void setCavernInfraVersionOverride(const std::string& tag) { m_CavernInfraVersionOverride=tag; } + + StatusCode setupTags(); + + private: + // ______________________________ IGeoDbTagSvc ____________________________________ + const std::string & faserVersion() const { return m_FaserVersion; } + const std::string & scintVersionOverride() const { return m_ScintVersionOverride; } + // const std::string & SCT_VersionOverride() const { return m_SCT_VersionOverride; } + // const std::string & caloVersionOverride() const { return m_CaloVersionOverride; } + // const std::string & magFieldVersionOverride() const { return m_MagFieldVersionOverride; } + // const std::string & cavernInfraVersionOverride() const { return m_CavernInfraVersionOverride; } + + const std::string & scintVersion() const { return m_ScintVersion; } + // const std::string & SCT_Version() const { return m_SCT_Version; } + // const std::string & caloVersion() const { return m_CaloVersion; } + // const std::string & magFieldVersion() const { return m_MagFieldVersion; } + // const std::string & cavernInfraVersion() const { return m_CavernInfraVersion; } + + GeoModel::GeoConfig geoConfig() const { return m_geoConfig; } + + // _________________________ Private data Members _______________________________ + std::string m_FaserVersion; + + std::string m_ScintVersion; + // std::string m_SCT_Version; + // std::string m_CaloVersion; + // std::string m_MagFieldVersion; + // std::string m_CavernInfraVersion; + + std::string m_ScintVersionOverride; + // std::string m_SCT_VersionOverride; + // std::string m_CaloVersionOverride; + // std::string m_MagFieldVersionOverride; + // std::string m_CavernInfraVersionOverride; + + GeoModel::GeoConfig m_geoConfig; +}; + +#endif // GEOMODELSVC_GEODBTAGSVC_H diff --git a/DetectorDescription/GeoModel/GeoModelSvc/src/GeoModelSvc.cxx b/DetectorDescription/GeoModel/GeoModelSvc/src/GeoModelSvc.cxx new file mode 100644 index 0000000000000000000000000000000000000000..5ebef709218fe6149c05102958b315b9abcc1660 --- /dev/null +++ b/DetectorDescription/GeoModel/GeoModelSvc/src/GeoModelSvc.cxx @@ -0,0 +1,576 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "GeoModelKernel/GeoBox.h" +#include "GeoModelKernel/GeoLogVol.h" +#include "GeoModelKernel/GeoPhysVol.h" +#include "GeoModelKernel/GeoMaterial.h" +#include "GeoModelKernel/GeoVolumeCursor.h" +#include "GeoModelUtilities/GeoModelExperiment.h" +#include "GeoModelSvc.h" +#include "RDBMaterialManager.h" +#include "GeoDbTagSvc.h" +#include "GeoModelInterfaces/IGeoAlignTool.h" +#include "GaudiKernel/ISvcLocator.h" +#include "GaudiKernel/IConversionSvc.h" +#include "GaudiKernel/SystemOfUnits.h" +#include "CxxUtils/make_unique.h" + +#include "RDBAccessSvc/IRDBAccessSvc.h" +#include "RDBAccessSvc/IRDBRecordset.h" +#include "RDBAccessSvc/IRDBRecord.h" + +#include "EventInfo/TagInfo.h" + +#include "GeoModelKernel/GeoPerfUtils.h" +#include <fstream> + +#include "AthenaKernel/ClassID_traits.h" +#include "SGTools/DataProxy.h" + +GeoModelSvc::GeoModelSvc(const std::string& name,ISvcLocator* svc) + : AthService(name,svc), + m_detectorTools(this), + m_pSvcLocator(svc), + m_toolSvc("ToolSvc",name), + m_detStore("DetectorStore",name), + m_tagInfoMgr("TagInfoMgr",name), + m_geoDbTagSvc("GeoDbTagSvc",name), + m_FaserVersion("AUTO"), + m_printMaterials(false), + m_callBackON(true), + m_ignoreTagDifference(false), + m_useTagInfo(true), + m_useCaloAlign(false), + m_statisticsToFile(false), + m_supportedGeometry(0), + m_ignoreTagSupport(false) +{ + declareProperty( "DetectorTools", m_detectorTools); + declareProperty( "PrintMaterials", m_printMaterials); + declareProperty( "FaserVersion", m_FaserVersion); + declareProperty( "ScintVersionOverride", m_ScintVersionOverride); + // declareProperty( "SCT_VersionOverride", m_SCT_VersionOverride); + // declareProperty( "CaloVersionOverride", m_CaloVersionOverride); + // declareProperty( "MagFieldVersionOverride", m_MagFieldVersionOverride); + // declareProperty( "CavernInfraVersionOverride", m_CavernInfraVersionOverride); + declareProperty( "AlignCallbacks", m_callBackON); + declareProperty( "IgnoreTagDifference", m_ignoreTagDifference); + declareProperty( "UseTagInfo", m_useTagInfo); + declareProperty( "StatisticsToFile", m_statisticsToFile); + declareProperty( "SupportedGeometry", m_supportedGeometry); + declareProperty( "IgnoreTagSupport", m_ignoreTagSupport); +} + +GeoModelSvc::~GeoModelSvc() +{ +} + +StatusCode GeoModelSvc::initialize() +{ + if(m_supportedGeometry==0) { + ATH_MSG_FATAL("The Supported Geometry flag was not set in Job Options! Exiting ..."); + return StatusCode::FAILURE; + } + + ATH_CHECK( m_detStore.retrieve() ); + ATH_CHECK( m_toolSvc.retrieve() ); + + // --- Sebastien + // clients (detector tools) are assuming the DetDescrCnvSvc has been + // correctly initialized. + // We ensure this is indeed correct by manually initialize it so there is + // no more service-ordering problem triggered by jobO mix-up + ServiceHandle<IConversionSvc> conversionSvc("DetDescrCnvSvc", this->name()); + ATH_CHECK( conversionSvc.retrieve() ); + // --- Sebastien + + ATH_CHECK( m_detectorTools.retrieve() ); + + ToolHandleArray< IGeoModelTool >::iterator itPriv = m_detectorTools.begin(), + itPrivEnd = m_detectorTools.end(); + + // **** **** **** TagInfo **** **** **** + std::string tagInfoKey = ""; + + if(m_useTagInfo) { + // get the key + ATH_CHECK( m_tagInfoMgr.retrieve() ); + tagInfoKey = m_tagInfoMgr->tagInfoKey(); + } + + // build regular geometry + ATH_CHECK( geoInit() ); + + if(!m_callBackON) { + // _________________ Align functions NOT registered as callbacks _____________ + + // Apply possible alignments to detectors. + // Dummy parameters for the callback + int par1 = 0; + std::list<std::string> par2; + for(; itPriv!=itPrivEnd; ++itPriv) { + if((*itPriv)->align(par1,par2) != StatusCode::SUCCESS) { + ATH_MSG_DEBUG("align() failed for the tool " << (*itPriv)->name()); + } + } + + // Fill in the contents of TagInfo + if(m_useTagInfo) { + ATH_CHECK(fillTagInfo()); + } + } + else { + // _________________ Align functions NOT registered as callbacks _____________ + + // We want to register IGeoModelSvc::align() even if no alignment callback is registered by + // subsystem tools, such that clients like CaloTowerBuilder can simply go after IGeoModelSvc::align() + bool alignRegistered = false; + + // Register align() functions for all Tools + for (; itPriv!=itPrivEnd; ++itPriv) { + IGeoModelTool* theTool = &(**itPriv); + + if(StatusCode::SUCCESS != theTool->registerCallback()) { + ATH_MSG_DEBUG("IGeoModelTool::align() was not registerred on CondDB object for the tool " << theTool->name()); + } + else { + if(StatusCode::SUCCESS == m_detStore->regFcn(&IGeoModelTool::align,theTool, + &IGeoModelSvc::align,dynamic_cast<IGeoModelSvc*>(this))) { + ATH_MSG_DEBUG("IGeoModelSvc::align() callback registered for the tool " << theTool->name()); + alignRegistered = true; + + // Set useCaloAlign flag if the successful tool is LAr + if((*itPriv).typeAndName().find("LAr")!=std::string::npos) { + m_useCaloAlign = true; + } + } + else { + ATH_MSG_DEBUG("Unable to register callback on IGeoModelSvc::align() for the tool " << theTool->name()); + } + } + } + + // Retrieve a tool for Calo Alignments + if(m_useCaloAlign) { + IGeoAlignTool* calo_align{nullptr}; + if(m_toolSvc->retrieveTool("CaloAlignTool",calo_align)!=StatusCode::SUCCESS) { + ATH_MSG_INFO("Unable to retrieve CaloAlignTool. No Calo alignments in this job"); + } + else { + ATH_MSG_DEBUG("CaloAligntTool retrieved successfully"); + } + } + + // Register a callback on TagInfo in order to compare geometry configurations defined in job options + // to the one read from the input file + if(m_useTagInfo) { + const DataHandle<TagInfo> tagInfoH; + if(m_detStore->regFcn(&IGeoModelSvc::compareTags,dynamic_cast<IGeoModelSvc*>(this), tagInfoH, tagInfoKey) != StatusCode::SUCCESS) { + ATH_MSG_WARNING("Cannot register compareTags function for key " << tagInfoKey); + } + else { + ATH_MSG_DEBUG("Registered compareTags callback for key: " << tagInfoKey); + + if(!alignRegistered) { + // There is no successfull alignment callback registration from subsystems + // Register IGeoModelSvc::align() after IGeoModelSvc::compareTags() then + if(m_detStore->regFcn(&IGeoModelSvc::compareTags,dynamic_cast<IGeoModelSvc*>(this), + &IGeoModelSvc::align,dynamic_cast<IGeoModelSvc*>(this)) == StatusCode::SUCCESS) { + ATH_MSG_DEBUG("Registered IGeoModelSvc::align() after IGeoModelSvc::compareTags()"); + } + else { + ATH_MSG_WARNING("Cannot register IGeoModelSvc::align() after IGeoModelSvc::compareTags()"); + } + } + } + + // Fill in the contents of TagInfo + ATH_CHECK(fillTagInfo()); + } + } + + return StatusCode::SUCCESS; +} + +StatusCode GeoModelSvc::finalize() +{ + return StatusCode::SUCCESS; +} + +// Query the interfaces. +// Input: riid, Requested interface ID +// ppvInterface, Pointer to requested interface +// Return: StatusCode indicating SUCCESS or FAILURE. +// N.B. Don't forget to release the interface after use!!! +StatusCode GeoModelSvc::queryInterface(const InterfaceID& riid, void** ppvInterface) +{ + if(IGeoModelSvc::interfaceID().versionMatch(riid)) { + *ppvInterface = (IGeoModelSvc*)this; + addRef(); + return StatusCode::SUCCESS; + } + else { + // Interface is not directly available: try out a base class + return AthService::queryInterface(riid, ppvInterface); + } +} + +StatusCode GeoModelSvc::geoInit() +{ + ATH_MSG_DEBUG("** Building geometry configuration: "); + ATH_MSG_DEBUG("* FASER tag: " << m_FaserVersion); + ATH_MSG_DEBUG("* Scint tag: " << m_ScintVersionOverride); + // ATH_MSG_DEBUG("* SCT tag: " << m_SCT_VersionOverride); + // ATH_MSG_DEBUG("* Calo tag: " << m_CaloVersionOverride); + // ATH_MSG_DEBUG("* MagField tag: " << m_MagFieldVersionOverride); + // ATH_MSG_DEBUG("* CavernInfra tag: " << m_CavernInfraVersionOverride); + + // GetRDBAccessSvc and open connection to DB + ServiceHandle<IRDBAccessSvc> rdbAccess("RDBAccessSvc",name()); + ATH_CHECK( rdbAccess.retrieve() ); + + if(!rdbAccess->connect()) { + ATH_MSG_ERROR("Unable to connect to the Geometry DB"); + return StatusCode::FAILURE; + } + + // Check the existence of FASER tag in the database + if(rdbAccess->getChildTag("FASER",m_FaserVersion,"FASER")=="") { + ATH_MSG_FATAL(" *** *** Wrong FASER layout: " << m_FaserVersion << " *** ***"); + ATH_MSG_FATAL(" Either FASER geometry tag has been misspelled, or the DB Release does not contain the geometry specified."); + ATH_MSG_FATAL(" In latter case please update DB Release version"); + return StatusCode::FAILURE; + } + + if(!m_ignoreTagSupport) { + RDBTagDetails faserTagDetails = rdbAccess->getTagDetails(m_FaserVersion); + const coral::AttributeSpecification& supportedSpec = faserTagDetails["SUPPORTED"].specification(); + if(supportedSpec.type()==typeid(bool)) { + if(!faserTagDetails["SUPPORTED"].data<bool>()) { + ATH_MSG_FATAL(" *** *** FASER layout " << m_FaserVersion << " is OBSOLETE and can NOT be supported any more! *** ***"); + return StatusCode::FAILURE; + } + } + else if(supportedSpec.type()==typeid(int)) { + if(faserTagDetails["SUPPORTED"].data<int>()<m_supportedGeometry) { + ATH_MSG_FATAL(" *** *** FASER layout " << m_FaserVersion + << " is OBSOLETE in rel " << m_supportedGeometry + << " and can NOT be supported any more! *** ***"); + return StatusCode::FAILURE; + } + } + } + + // Create a material manager + StoredMaterialManager *theMaterialManager{nullptr}; + try{ + theMaterialManager = new RDBMaterialManager(m_pSvcLocator); + } + catch(std::runtime_error& e) { + ATH_MSG_FATAL(e.what()); + return StatusCode::FAILURE; + } + ATH_CHECK( m_detStore->record(theMaterialManager,"MATERIALS") ); + + // Setup the GeoDbTagSvc + ATH_CHECK( m_geoDbTagSvc.retrieve() ); + + GeoDbTagSvc* dbTagSvc = dynamic_cast<GeoDbTagSvc*>(m_geoDbTagSvc.operator->()); + if(dbTagSvc==nullptr) { + ATH_MSG_FATAL("Unable to dyn-cast the IGeoDbTagSvc pointer to GeoDbTagSvc"); + return StatusCode::FAILURE; + } + + dbTagSvc->setFaserVersion(m_FaserVersion); + dbTagSvc->setScintVersionOverride(m_ScintVersionOverride); + // dbTagSvc->setSCT_VersionOverride(m_SCT_VersionOverride); + // dbTagSvc->setCaloVersionOverride(m_CaloVersionOverride); + // dbTagSvc->setMagFieldVersionOverride(m_MagFieldVersionOverride); + // dbTagSvc->setCavernInfraVersionOverride(m_CavernInfraVersionOverride); + + if(dbTagSvc->setupTags().isFailure()) { + ATH_MSG_FATAL("Failed to setup subsystem tags"); + return StatusCode::FAILURE; + } + + // Build the world node from which everything else will be suspended + const GeoMaterial* air = theMaterialManager->getMaterial("std::Air"); + const GeoBox* worldBox = new GeoBox(1000*Gaudi::Units::cm,1000*Gaudi::Units::cm, 1000*Gaudi::Units::cm); + const GeoLogVol* worldLog = new GeoLogVol("WorldLog", worldBox, air); + GeoPhysVol *worldPhys=new GeoPhysVol(worldLog); + + // Create FaserExperiment and register it within the transient detector store + GeoModelExperiment* theExperiment = new GeoModelExperiment(worldPhys); + ATH_CHECK( m_detStore->record(theExperiment,"FASER") ); + + int mem,cpu; + std::unique_ptr<std::ofstream> geoModelStats; + if(m_statisticsToFile) { + geoModelStats = CxxUtils::make_unique<std::ofstream>("GeoModelStatistics"); + *geoModelStats << "Detector Configuration flag = " << m_FaserVersion << std::endl; + } + + // Loop over all tools + ToolHandleArray< IGeoModelTool >::iterator itPriv = m_detectorTools.begin(), + itPrivEnd = m_detectorTools.end(); + + for(; itPriv!=itPrivEnd; ++itPriv) { + IGeoModelTool* theTool = &(**itPriv); + + mem = GeoPerfUtils::getMem(); + cpu = GeoPerfUtils::getCpu(); + + if(theTool->create().isFailure()) { + ATH_MSG_ERROR("Unable to create detector " << theTool->name()); + return StatusCode::FAILURE; + } + + if(m_statisticsToFile) { + *geoModelStats << theTool->name() << "\t SZ= " + << GeoPerfUtils::getMem() - mem << "Kb \t Time = " << (GeoPerfUtils::getCpu() - cpu) * 0.01 << "S" << std::endl; + } + else { + ATH_MSG_INFO(theTool->name() << "\t SZ= " + << GeoPerfUtils::getMem() - mem << "Kb \t Time = " << (GeoPerfUtils::getCpu() - cpu) * 0.01 << "S"); + } + } + + if(m_statisticsToFile) { + geoModelStats->close(); + } + + // Close DB connection + rdbAccess->shutdown(); + if(m_printMaterials) + theMaterialManager->printAll(); + + return StatusCode::SUCCESS; +} + +StatusCode GeoModelSvc::align(IOVSVC_CALLBACK_ARGS) +{ + ATH_MSG_DEBUG("GeoModelSvc::align() called"); + return StatusCode::SUCCESS; +} + +StatusCode GeoModelSvc::compareTags(IOVSVC_CALLBACK_ARGS) +{ + bool tagsMatch = true; + + ATH_MSG_DEBUG("GeoModelSvc::compareTags() callback trigerred"); + + // Get TagInfo and retrieve tags + const TagInfo* tagInfo = 0; + ATH_CHECK( m_detStore->retrieve(tagInfo) ); + + TagInfo::NameTagPairVec pairs; + tagInfo->getInputTags(pairs); + for( const auto& pair : pairs ) { + std::string tagPairName = pair.first; + if(tagPairName=="GeoAtlas") { + // ** Two possible cases need to be taken into account + // ** + // ** 1. The retrieved FASER tag is following naming schema FASER-...-XX-YY-ZZ + // ** where '...' can be anything, it may also containg one or more '-'. + // ** If this is the case, then we need to check whether the job option tag + // ** is also following the same schema and they have the same 'FASER-...-XX' part + // ** + // ** 2. The retrieved FASER tag is not following the schema mentioned above + // ** If this is the case, we just need to check the exact match + std::vector<std::string> tokensTagInfo, tokensJobOpt; + + // Parse Tag Info tag + std::string::size_type startpos = 0; + std::string currStr = pair.second; + for(std::string::size_type endpos=currStr.find("-"); endpos!=std::string::npos; endpos=currStr.find("-",startpos)) { + tokensTagInfo.push_back(currStr.substr(startpos,endpos-startpos)); + startpos = endpos+1; + } + tokensTagInfo.push_back(currStr.substr(startpos)); + + size_t tokensTagInfoSize = tokensTagInfo.size(); + bool tagInfoFollowsTheScheme = (tokensTagInfoSize>=5 + && tokensTagInfo[tokensTagInfoSize-1].size()==2 + && tokensTagInfo[tokensTagInfoSize-2].size()==2 + && tokensTagInfo[tokensTagInfoSize-3].size()==2); + + if(tagInfoFollowsTheScheme) { + // Parse Job Options tag + startpos = 0; + currStr = m_FaserVersion; + for(std::string::size_type endpos=currStr.find("-"); endpos!=std::string::npos; endpos=currStr.find("-",startpos)) { + tokensJobOpt.push_back(currStr.substr(startpos,endpos-startpos)); + startpos = endpos+1; + } + tokensJobOpt.push_back(currStr.substr(startpos)); + + size_t tokensJobOptSize = tokensJobOpt.size(); + bool jobOptFollowsTheScheme = (tokensJobOptSize>=5 + && tokensJobOpt[tokensJobOptSize-1].size()==2 + && tokensJobOpt[tokensJobOptSize-2].size()==2 + && tokensJobOpt[tokensJobOptSize-3].size()==2); + if(jobOptFollowsTheScheme) { + tagsMatch = (pair.second.substr(0,currStr.size()-6)==m_FaserVersion.substr(0,m_FaserVersion.size()-6)); + } + else { + tagsMatch = false; + } + } + else {// Check for the exact match + tagsMatch = m_FaserVersion == pair.second; + } + } + else if(tagPairName=="GeoScint") + tagsMatch = m_ScintVersionOverride == pair.second; + // else if(tagPairName=="GeoSCT") + // tagsMatch = m_SCT_VersionOverride == pair.second; + + if(!tagsMatch) break; + } + + if(!tagsMatch) { + msg((m_ignoreTagDifference? MSG::WARNING : MSG::ERROR)) + << "*** *** Geometry configured through jobOptions does not match TagInfo tags! *** ***" << endmsg; + ATH_MSG_INFO("** Job Option configuration: "); + ATH_MSG_INFO("* FASER tag: " << m_FaserVersion); + ATH_MSG_INFO("* Scint tag: " << m_ScintVersionOverride); + // ATH_MSG_INFO("* SCT tag: " << m_SCT_VersionOverride); + // ATH_MSG_INFO("* Calo tag: " << m_CaloVersionOverride); + // ATH_MSG_INFO("* MagField tag: " << m_MagFieldVersionOverride); + // ATH_MSG_INFO("* CavernInfra tag: " << m_CavernInfraVersionOverride); + ATH_MSG_INFO("** TAG INFO configuration: "); + for (const auto& pair : pairs) { + std::string tagPairName = pair.first; + if(tagPairName=="GeoFaser") + ATH_MSG_INFO("* FASER tag: " << pair.second); + else if(tagPairName=="GeoScint") + ATH_MSG_INFO("*Scint tag: " << pair.second); + // else if(tagPairName=="GeoSCT") + // ATH_MSG_INFO("*SCT tag: " << pair.second); + // else if(tagPairName=="GeoCalo") + // ATH_MSG_INFO("*Calo tag: " << pair.second); + // else if(tagPairName=="GeoMagField") + // ATH_MSG_INFO("*MagField tag: " << pair.second); + // else if(tagPairName=="GeoCavernInfra") + // ATH_MSG_INFO("*CavernInfra tag: " << pair.second); + } + + if(!m_ignoreTagDifference) { + ATH_MSG_INFO("*** *** Please fix geometry tag settings *** ***"); + return StatusCode::FAILURE; + } + } + else + ATH_MSG_DEBUG("Geometry configurations in jobOptions and TagInfo are consistent"); + + return StatusCode::SUCCESS; +} + +/********************************************************************************** + ** Private Member Functions + **********************************************************************************/ +StatusCode GeoModelSvc::fillTagInfo() const +{ + if(m_FaserVersion == "") { + ATH_MSG_ERROR("FASER version is empty"); + return StatusCode::FAILURE; + } + + if(m_tagInfoMgr->addTag("GeoFaser",m_FaserVersion).isFailure()) { + ATH_MSG_ERROR("GeoModelSvc Faser tag: " << m_FaserVersion << " not added to TagInfo "); + return StatusCode::FAILURE; + } + + if(m_ScintVersionOverride != "") { + if(m_tagInfoMgr->addTag("GeoScint",m_ScintVersionOverride).isFailure()) { + ATH_MSG_ERROR("GeoModelSvc Scint tag: " << m_ScintVersionOverride << " not added to TagInfo "); + return StatusCode::FAILURE; + } + } + + // if(m_SCT_VersionOverride != "") { + // if(m_tagInfoMgr->addTag("GeoSCT",m_SCT_VersionOverride).isFailure()) { + // ATH_MSG_ERROR("GeoModelSvc SCT tag: " << m_SCT_VersionOverride << " not added to TagInfo "); + // return StatusCode::FAILURE; + // } + // } + + // if(m_CaloVersionOverride != "") { + // if(m_tagInfoMgr->addTag("GeoCalo",m_CaloVersionOverride).isFailure()) { + // ATH_MSG_ERROR("GeoModelSvc Calo tag: " << m_CaloVersionOverride << " not added to TagInfo "); + // return StatusCode::FAILURE; + // } + // } + + // if(m_MagFieldVersionOverride != "") { + // if(m_tagInfoMgr->addTag("GeoMagField",m_MagFieldVersionOverride).isFailure()) { + // ATH_MSG_ERROR("GeoModelSvc MagField tag: " << m_MagFieldVersionOverride << " not added to TagInfo "); + // return StatusCode::FAILURE; + // } + // } + + // if(m_CavernInfraVersionOverride != "") { + // if(m_tagInfoMgr->addTag("GeoCavernInfra",m_CavernInfraVersionOverride).isFailure()) { + // ATH_MSG_ERROR("GeoModelSvc CavernInfra tag: " << m_CavernInfraVersionOverride << " not added to TagInfo "); + // return StatusCode::FAILURE; + // } + // } + return StatusCode::SUCCESS; +} + +const IGeoModelTool* GeoModelSvc::getTool(std::string toolName) const +{ + ToolHandleArray< IGeoModelTool >::const_iterator itPriv = m_detectorTools.begin(); + + for(; itPriv!=m_detectorTools.end(); itPriv++) { + const IGeoModelTool* theTool = &(**itPriv); + if(theTool->name().find(toolName)!=std::string::npos) + return theTool; + } + + return 0; +} + +StatusCode GeoModelSvc::clear() +{ + ATH_MSG_DEBUG("In clear()"); + + // Call clear() for all tools + ToolHandleArray< IGeoModelTool >::iterator itPriv = m_detectorTools.begin(); + for(; itPriv!=m_detectorTools.end(); itPriv++) { + IGeoModelTool* theTool = &(**itPriv); + if(theTool->clear().isFailure()) { + ATH_MSG_ERROR("clear() failed for the tool: " << theTool->name()); + return StatusCode::FAILURE; + } else { + ATH_MSG_DEBUG(theTool->name() << " tool released"); + } + } + + // Delete GeoModelExperiment - cascade delete of the entire GeoModel tree + std::vector<std::string>::const_iterator it; + std::vector<std::string> sgkeysExp; + m_detStore->keys<GeoModelExperiment>(sgkeysExp); + for(it=sgkeysExp.begin(); it!=sgkeysExp.end(); it++) { + SG::DataProxy* proxy = m_detStore->proxy(ClassID_traits<GeoModelExperiment>::ID(),*it); + if(proxy) { + proxy->reset(); + ATH_MSG_DEBUG(*it << " GeoModel experiment released"); + } + } + + // Release stored material manager + std::vector<std::string> sgkeysMat; + m_detStore->keys<StoredMaterialManager>(sgkeysMat); + for(it=sgkeysMat.begin(); it!=sgkeysMat.end(); it++) { + SG::DataProxy* proxy = m_detStore->proxy(ClassID_traits<StoredMaterialManager>::ID(),*it); + if(proxy) { + proxy->reset(); + ATH_MSG_DEBUG(*it << " material manager released"); + } + } + + return StatusCode::SUCCESS; +} diff --git a/DetectorDescription/GeoModel/GeoModelSvc/src/GeoModelSvc.h b/DetectorDescription/GeoModel/GeoModelSvc/src/GeoModelSvc.h new file mode 100644 index 0000000000000000000000000000000000000000..ba7a19b560a9ceb386e53af0bf8c6b4c7bf0b387 --- /dev/null +++ b/DetectorDescription/GeoModel/GeoModelSvc/src/GeoModelSvc.h @@ -0,0 +1,112 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef GEOMODELSVC_GEOMODELSVC_H +#define GEOMODELSVC_GEOMODELSVC_H + +#include "GeoModelKernel/GeoPVConstLink.h" +#include "GeoModelInterfaces/IGeoModelSvc.h" +#include "GeoModelInterfaces/IGeoDbTagSvc.h" +#include "GeoModelInterfaces/IGeoModelTool.h" +#include "GaudiKernel/ServiceHandle.h" +#include "GaudiKernel/IToolSvc.h" +#include "GaudiKernel/ToolHandle.h" +#include "GaudiKernel/Property.h" +#include "AthenaBaseComps/AthService.h" +#include "StoreGate/StoreGateSvc.h" +#include "EventInfoMgt/ITagInfoMgr.h" +#include <fstream> + +class ISvcLocator; + +template <class TYPE> class SvcFactory; + +class GeoModelSvc : public AthService, virtual public IGeoModelSvc { + +public: + + virtual StatusCode initialize(); + virtual StatusCode finalize(); + + // Query the interfaces. + // Input: riid, Requested interface ID + // ppvInterface, Pointer to requested interface + // Return: StatusCode indicating SUCCESS or FAILURE. + // N.B. Don't forget to release the interface after use!!! + virtual StatusCode queryInterface( const InterfaceID& riid, void** ppvInterface ); + + virtual StatusCode align (IOVSVC_CALLBACK_ARGS); + virtual StatusCode compareTags (IOVSVC_CALLBACK_ARGS); + + virtual const IGeoModelTool* getTool(std::string toolName) const; + + virtual StatusCode clear(); + + friend class SvcFactory<GeoModelSvc>; + + // Standard Constructor + GeoModelSvc(const std::string& name, ISvcLocator* svc); + + // Standard Destructor + virtual ~GeoModelSvc(); + + +protected: + + // StatusCode append( IGeoModelTool* pddTool, + // std::vector<IGeoModelTool*>* theTools ); + // StatusCode decodeNames( StringArrayProperty& theNames, + // std::vector<IGeoModelTool*>* theTools ); + +private: + + ToolHandleArray< IGeoModelTool > m_detectorTools; // Detector Tools + + ISvcLocator* m_pSvcLocator; + + ServiceHandle<IToolSvc> m_toolSvc; + ServiceHandle<StoreGateSvc> m_detStore; + ServiceHandle<ITagInfoMgr> m_tagInfoMgr; + ServiceHandle<IGeoDbTagSvc> m_geoDbTagSvc; + + std::string m_FaserVersion; + + std::string m_ScintVersionOverride; + // std::string m_SCT_VersionOverride; + // std::string m_CaloVersionOverride; + // std::string m_MagFieldVersionOverride; + // std::string m_CavernInfraVersionOverride; + + bool m_printMaterials; // Print the contents of the Material Manager at the end of geoInit + bool m_callBackON; // Register callback for Detector Tools + bool m_ignoreTagDifference; // Keep going if TagInfo and property tags are different + // when geometry configured manually + bool m_useTagInfo; // Flag for TagInfo usage + bool m_useCaloAlign; // Flag for using alignments for Calo + bool m_statisticsToFile; // Flag for generating GeoModelStatistics file in the run directory + + int m_supportedGeometry; // Supported geometry flag is set in jobOpt and is equal to major release version + bool m_ignoreTagSupport; // If true then don't check SUPPORT flag for ATLAS tag + + const std::string & faserVersion() const {return m_FaserVersion; } + const std::string & scintVersionOverride() const {return m_ScintVersionOverride ;} + // const std::string & SCT_VersionOverride() const {return m_SCT_VersionOverride ;} + // const std::string & muonVersionOverride() const {return m_MuonVersionOverride ;} + // const std::string & caloVersionOverride() const {return m_CaloVersionOverride ;} + // const std::string & magFieldVersionOverride() const {return m_MagFieldVersionOverride ;} + // const std::string & cavernInfraVersionOverride() const {return m_CavernInfraVersionOverride ;} + + const std::string & scintVersion() const {return m_geoDbTagSvc->scintVersion(); } + // const std::string & SCT_Version() const {return m_geoDbTagSvc->SCT_Version(); } + // const std::string & caloVersion() const {return m_geoDbTagSvc->caloVersion(); } + // const std::string & magFieldVersion() const {return m_geoDbTagSvc->magFieldVersion(); } + // const std::string & cavernInfraVersion() const {return m_geoDbTagSvc->cavernInfraVersion(); } + + GeoModel::GeoConfig geoConfig() const {return m_geoDbTagSvc->geoConfig();} + + StatusCode geoInit (); + StatusCode fillTagInfo() const; +}; + +#endif // GEOMODELSVC_GEOMODELSVC_H diff --git a/DetectorDescription/GeoModel/GeoModelSvc/src/RDBMaterialManager.cxx b/DetectorDescription/GeoModel/GeoModelSvc/src/RDBMaterialManager.cxx new file mode 100644 index 0000000000000000000000000000000000000000..23386d1073a2fb84ab00aa2911e37e5a961e2a28 --- /dev/null +++ b/DetectorDescription/GeoModel/GeoModelSvc/src/RDBMaterialManager.cxx @@ -0,0 +1,961 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "RDBMaterialManager.h" +#include "GeoModelUtilities/DecodeVersionKey.h" +#include "GeoModelInterfaces/IGeoModelSvc.h" + +#include "GeoModelKernel/GeoMaterial.h" +#include "GeoModelKernel/GeoElement.h" +#include "GeoModelKernel/Units.h" + +#include "StoreGate/StoreGate.h" +#include "StoreGate/DataHandle.h" + +#include "RDBAccessSvc/IRDBAccessSvc.h" +#include "RDBAccessSvc/IRDBRecordset.h" +#include "RDBAccessSvc/IRDBRecord.h" + +#include "AthenaKernel/getMessageSvc.h" +#include "GaudiKernel/IMessageSvc.h" +#include "GaudiKernel/ISvcLocator.h" +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/SystemOfUnits.h" +#include "AthenaBaseComps/AthCheckMacros.h" + +#include <algorithm> +#include <iostream> +#include <stdexcept> + +bool RDBMaterialManager::s_specialMaterials = false; + +//---------------------------Help find elements in the list-----------------------// +class NameEquals { // +public: // + NameEquals(const std::string & name):m_name(name){} // + bool operator() (const GeoElement *e) const {return m_name==e->getName();} // +private: // + std::string m_name; // +}; // +//--------------------------------------------------------------------------------// + +//---------------------------Help find elements in the list-----------------------// +class NumberEquals { // +public: // + NumberEquals(unsigned int number):m_number(number){} // + bool operator() (const GeoElement *e) const {return m_number==e->getZ();} // +private: // + unsigned int m_number; // +}; // +//--------------------------------------------------------------------------------// + +int CheckElement(std::string &name) +{ + if(name.find("::",0) == std::string::npos) { + return 1; + } + else { + return 0; + } +} + +int printElement ( GeoElement* &p_element) +{ + std::string name = p_element->getName(); + std::string symbol = p_element->getSymbol(); + double a = p_element->getA(); + double z = p_element->getZ(); + + std::cout << " ***** CheckElement(): Print the Element: " << name << std::endl; + std::cout << " ***** The Element: name, symbol, A, Z " << std::endl; + std::cout << " ***** "<<name <<" "<<symbol <<" "<< a * (Gaudi::Units::mole / GeoModelKernelUnits::gram) <<" "<< z <<" " << std::endl; + + return 1; +} + +int printElement ( const GeoElement* &p_element) +{ + std::string name = p_element->getName(); + std::string symbol = p_element->getSymbol(); + double a = p_element->getA(); + double z = p_element->getZ(); + + std::cout << " ***** PrintElement(): Print the Element: " << name << std::endl; + std::cout << " ***** The Element: name, symbol, A, Z " << std::endl; + std::cout << " ***** "<<name <<" "<<symbol <<" "<< a * (Gaudi::Units::mole / GeoModelKernelUnits::gram) <<" "<< z <<" " << std::endl; + + return 1; +} + +int printMaterial ( GeoMaterial* &p_material) +{ + std::string name = p_material->getName(); + double density = p_material->getDensity() * (Gaudi::Units::cm3 / GeoModelKernelUnits::gram); + + std::cout << " ***** PrintMaterial(): Print the Material: " << name << std::endl; + std::cout << " ***** The Material: name, density " << std::endl; + std::cout << " ***** "<< name <<" "<<density <<" " << std::endl; + + return 1; +} + +int printFullMaterial ( GeoMaterial* &p_material) +{ + std::string name = p_material->getName(); + double density = p_material->getDensity() * (Gaudi::Units::cm3 / GeoModelKernelUnits::gram); + + std::cout << " ***** PrintFullMaterial(): Print the Material: " << name << std::endl; + std::cout << " ***** The Material: name, density" << std::endl; + std::cout << " ***** "<< name <<" "<<density <<" " << std::endl; + + p_material->lock(); + int element_number = p_material->getNumElements(); + + + if ( element_number == 0){ + std::cout << " ***** No Elements now in this printMaterial( ) " << std::endl; + return 1; + } + else { + element_number = p_material->getNumElements(); + + for(int i =0; i< element_number;i ++) + { + const GeoElement* tmp_element = p_material->getElement(i); + double element_fraction = p_material->getFraction(i); + + std::cout<<" ***** ***** Number: " << i << " Fraction: " << element_fraction<< std::endl; + printElement( tmp_element); + } + } + return 1; +} + + + +RDBMaterialManager::RDBMaterialManager(ISvcLocator* pSvcLocator) +{ + if(!readMaterialsFromDB(pSvcLocator).isSuccess()) { + throw std::runtime_error("RDBMaterialManager failed to read Geometry DB"); + } +} + +StatusCode RDBMaterialManager::readMaterialsFromDB(ISvcLocator* pSvcLocator) +{ + IGeoModelSvc* iGeoModel; + IRDBAccessSvc* iAccessSvc; + MsgStream log(Athena::getMessageSvc(), "GeoModelSvc::RDBMaterialManager"); + + ATH_CHECK(pSvcLocator->service("GeoModelSvc",iGeoModel)); + ATH_CHECK(pSvcLocator->service("RDBAccessSvc",iAccessSvc)); + + // --- Standard materials, elements + DecodeVersionKey keyFaser(iGeoModel, "FASER"); + m_elements = iAccessSvc->getRecordsetPtr("Elements",keyFaser.tag(),keyFaser.node()); + if(m_elements->size()==0) { + if(log.level()<=MSG::WARNING) + log << MSG::WARNING << " Getting Elements with default tag" <<endmsg; + m_elements = iAccessSvc->getRecordsetPtr("Elements","Materials-00","Materials"); + } + m_stdmatcomponents = iAccessSvc->getRecordsetPtr("StdMatComponents",keyFaser.tag(),keyFaser.node()); + if(m_stdmatcomponents->size()==0) { + if(log.level()<=MSG::WARNING) + log << MSG::WARNING << " Getting StdMatComponents with default tag" <<endmsg; + m_stdmatcomponents = iAccessSvc->getRecordsetPtr("StdMatComponents","Materials-00","Materials"); + } + m_stdmaterials = iAccessSvc->getRecordsetPtr("StdMaterials",keyFaser.tag(),keyFaser.node()); + if(m_stdmaterials->size()==0) { + if(log.level()<=MSG::WARNING) + log << MSG::WARNING << " Getting StdMaterials with default tag" <<endmsg; + m_stdmaterials = iAccessSvc->getRecordsetPtr("StdMaterials","Materials-00","Materials"); + } + + // --- Pixel materials + DecodeVersionKey keyScintillator(iGeoModel, "Scintillator"); + m_scintmatcomponents = iAccessSvc->getRecordsetPtr("ScintMatComponents",keyScintillator.tag(),keyScintillator.node()); + if(m_scintmatcomponents->size()==0) { + if(log.level()<=MSG::WARNING) + log << MSG::WARNING << " Getting ScintMatComponents with default tag" <<endmsg; + m_scintmatcomponents = iAccessSvc->getRecordsetPtr("ScintMatComponents","ScintMatComponents-00"); + } + m_scintmaterials = iAccessSvc->getRecordsetPtr("PixMaterials",keyScintillator.tag(),keyScintillator.node()); + if(m_scintmaterials->size()==0) { + if(log.level()<=MSG::WARNING) + log << MSG::WARNING << " Getting ScintMaterials with default tag" <<endmsg; + m_scintmaterials = iAccessSvc->getRecordsetPtr("ScintMaterials","ScintMaterials-00"); + } + + // --- SCT materials + // DecodeVersionKey keySCT(iGeoModel, "SCT"); + // m_sctmatcomponents = iAccessSvc->getRecordsetPtr("SCTMatComponents",keySCT.tag(),keySCT.node()); + // if(m_sctmatcomponents->size()==0) { + // if(log.level()<=MSG::WARNING) + // log << MSG::WARNING << " Getting SCTMatComponents with default tag" <<endmsg; + // m_sctmatcomponents = iAccessSvc->getRecordsetPtr("SCTMatComponents","SCTMatComponents-00"); + // } + + // m_sctmaterials = iAccessSvc->getRecordsetPtr("SCTMaterials",keySCT.tag(),keySCT.node()); + // if(m_sctmaterials->size()==0) { + // if(log.level()<=MSG::WARNING) + // log << MSG::WARNING << " Getting SCTMaterials with default tag" <<endmsg; + // m_sctmaterials = iAccessSvc->getRecordsetPtr("SCTMaterials","SCTMaterials-00"); + // } + + // --- InDet common materials + // DecodeVersionKey keyInDet(iGeoModel, "InnerDetector"); + // m_indetmatcomponents = iAccessSvc->getRecordsetPtr("InDetMatComponents",keyInDet.tag(),keyInDet.node()); + // if(m_indetmatcomponents->size()==0) { + // if(log.level()<=MSG::WARNING) + // log << MSG::WARNING << " Getting InDetMatComponents with default tag" <<endmsg; + // m_indetmatcomponents = iAccessSvc->getRecordsetPtr("InDetMatComponents","InDetMatComponents-00"); + // } + + // m_indetmaterials = iAccessSvc->getRecordsetPtr("InDetMaterials",keyInDet.tag(),keyInDet.node()); + // if(m_indetmaterials->size()==0) { + // if(log.level()<=MSG::WARNING) + // log << MSG::WARNING << " Getting InDetMaterials with default tag" <<endmsg; + // m_indetmaterials = iAccessSvc->getRecordsetPtr("InDetMaterials","InDetMaterials-00"); + // } + + return StatusCode::SUCCESS; +} + +// Destructor: +RDBMaterialManager::~RDBMaterialManager() { + + // Unreference the materials: + std::map< std::string, GeoMaterial * >::iterator m, begin = m_materialMap.begin(),end = m_materialMap.end(); + for (m=begin;m!=end;m++) (*m).second->unref(); + + // Unreference the elements: + for (size_t i=0;i<m_elementVector.size();i++) m_elementVector[i]->unref(); + +} + +GeoMaterial* RDBMaterialManager::searchMaterialMap(const std::string & name) +{ + MsgStream log(Athena::getMessageSvc(), "GeoModelSvc::RDBMaterialManager"); + + std::map< std::string, GeoMaterial * >::const_iterator m = m_materialMap.find(std::string(name)); + std::map< std::string, GeoMaterial * >::const_iterator end = m_materialMap.end(); + + if (m!=end) { + if(log.level()==MSG::VERBOSE) + log << MSG::VERBOSE << " ***** in searchMaterialMap(): search sucess " << endmsg; + return (*m).second; + } + else { + if(log.level()==MSG::VERBOSE) + log << MSG::VERBOSE << " ***** in searchMaterialMap(): search fail " << endmsg; + return NULL; + } +} + +GeoMaterial* RDBMaterialManager::searchMaterialMap(const std::string & name) const +{ + MsgStream log(Athena::getMessageSvc(), "GeoModelSvc::RDBMaterialManager"); + + std::map< std::string, GeoMaterial * >::const_iterator m = m_materialMap.find(std::string(name)); + std::map< std::string, GeoMaterial * >::const_iterator end = m_materialMap.end(); + if (m!=end) { + if(log.level()==MSG::VERBOSE) + log << MSG::VERBOSE << " ***** in searchMaterialMap(): search sucess " << endmsg; + return (*m).second; + } + else { + if(log.level()==MSG::VERBOSE) + log << MSG::VERBOSE << " ***** in searchMaterialMap(): search fail " << endmsg; + return NULL; + } +} + + +GeoElement *RDBMaterialManager::searchElementVector(const std::string & name) +{ + MsgStream log(Athena::getMessageSvc(), "GeoModelSvc::RDBMaterialManager"); + + NameEquals matchByName(name); + std::vector<GeoElement *>::const_iterator e=std::find_if(m_elementVector.begin(), m_elementVector.end(),matchByName); + + if (e!=m_elementVector.end()) { + if(log.level()==MSG::VERBOSE) + log << MSG::VERBOSE << " ***** in searchElementVector() search succes " << endmsg; + return *e; + } + else { + if(log.level()==MSG::VERBOSE) + log << MSG::VERBOSE << " ***** in searchElementVector() search fail " << endmsg; + return NULL; + } +} + + +GeoElement *RDBMaterialManager::searchElementVector(const std::string & name) const +{ + MsgStream log(Athena::getMessageSvc(), "GeoModelSvc::RDBMaterialManager"); + + NameEquals matchByName(name); + std::vector<GeoElement *>::const_iterator e=std::find_if(m_elementVector.begin(), m_elementVector.end(),matchByName); + + if (e!=m_elementVector.end()) { + if(log.level()==MSG::VERBOSE) + log << MSG::VERBOSE << " ***** in searchElementVector() search succes " << endmsg; + return *e; + } + else { + if(log.level()==MSG::VERBOSE) + log << MSG::VERBOSE << " ***** in searchElementVector() search fail " << endmsg; + return NULL; + } +} + + +GeoElement *RDBMaterialManager::searchElementVector(const unsigned int atomicNumber) +{ + MsgStream log(Athena::getMessageSvc(), "GeoModelSvc::RDBMaterialManager"); + + NumberEquals matchByNumber(atomicNumber); + std::vector<GeoElement *>::const_iterator e=std::find_if(m_elementVector.begin(), m_elementVector.end(), matchByNumber); + + if (e!=m_elementVector.end()) { + if(log.level()==MSG::VERBOSE) + log << MSG::VERBOSE << " ***** in searchElementVector(atomicNumber) search succes " << endmsg; + return *e; + } + else { + if(log.level()==MSG::VERBOSE) + log << MSG::VERBOSE << " ***** in searchElementVector(atomicNumber) search succes " << endmsg; + return NULL; + } +} + +GeoElement *RDBMaterialManager::searchElementVector(const unsigned int atomicNumber) const +{ + MsgStream log(Athena::getMessageSvc(), "GeoModelSvc::RDBMaterialManager"); + + NumberEquals matchByNumber(atomicNumber); + std::vector<GeoElement *>::const_iterator e=std::find_if(m_elementVector.begin(), m_elementVector.end(), matchByNumber); + + if (e!=m_elementVector.end()) { + if(log.level()==MSG::VERBOSE) + log << MSG::VERBOSE << " ***** in searchElementVector(atomicNumber) search succes " << endmsg; + return *e; + } + else { + if(log.level()==MSG::VERBOSE) + log << MSG::VERBOSE << " ***** in searchElementVector(atomicNumber) search succes " << endmsg; + return NULL; + } +} + +GeoMaterial* RDBMaterialManager::getMaterial(const std::string & name) { + + unsigned int ind, com_ind; + + std::string material_name; + std::string tmp_name; + long material_id = 0; + double material_density = 0; + + + std::string component_name; + double component_fraction; + int component_id; + + std::string detector; + std::string tmp_det; + std::string data_id; + + + std::string matcomponents_table; + + if(!s_specialMaterials) + { + buildSpecialMaterials(); + s_specialMaterials = true; + } + + GeoMaterial* pmaterial; + + GeoMaterial* p_com_material; + GeoElement* p_com_element; + + IRDBRecordset_ptr tmp_materials; + IRDBRecordset_ptr tmp_matcomponents; + + MsgStream log(Athena::getMessageSvc(), "GeoModelSvc::RDBMaterialManager"); + if(log.level()<=MSG::DEBUG) + log << MSG::DEBUG << " ***** getMaterial( ): " << name << endmsg; + + + pmaterial = NULL; + pmaterial = searchMaterialMap( name); + if (pmaterial!= NULL) + return pmaterial; + + if(name.find("std",0) == 0) + { + detector = "std"; + tmp_materials = m_stdmaterials; + tmp_matcomponents = m_stdmatcomponents; + data_id = "STDMATERIALS_DATA_ID"; + } + else if(name.find("scint",0) == 0) + { + detector = "scint"; + tmp_materials = m_scintmaterials; + tmp_matcomponents = m_scintmatcomponents; + data_id = "SCINTMATERIALS_DATA_ID"; + } + // else if(name.find("sct",0) == 0) + // { + // detector = "sct"; + // tmp_materials = m_sctmaterials; + // tmp_matcomponents = m_sctmatcomponents; + // data_id = "SCTMATERIALS_DATA_ID"; + // } + // else if(name.find("indet",0) == 0) + // { + // detector = "indet"; + // tmp_materials = m_indetmaterials; + // tmp_matcomponents = m_indetmatcomponents; + // data_id = "INDETMATERIALS_DATA_ID"; + // } + else {return 0 ;} + + for( ind = 0; ind < tmp_materials->size(); ind++) + { + const IRDBRecord* rec = (*tmp_materials)[ind]; + tmp_name = detector+"::"+rec->getString("NAME"); + + if( name == tmp_name){ + + material_name = rec->getString("NAME"); + material_id = rec->getLong(data_id); + material_density = rec->getDouble("DENSITY"); + + if(log.level()<=MSG::DEBUG) + log << MSG::DEBUG << " ***** Material: name id density: " << material_name <<" " << material_id <<" "<< material_density << endmsg; + break; + } + } + + if (ind == tmp_materials->size()) + return NULL; + + pmaterial = new GeoMaterial( material_name,material_density * (GeoModelKernelUnits::gram / Gaudi::Units::cm3)); + + + bool firstComponent = true; + bool hasSubMaterial = false; + bool calculateFraction = false; + double totalFraction = 0.; + std::vector < GeoElement* > elementComponents; + std::vector <double> elementFractions; + + for( com_ind = 0; com_ind <tmp_matcomponents->size(); com_ind++) + { + const IRDBRecord* com_rec = (*tmp_matcomponents)[com_ind]; + + component_id = com_rec->getLong("MATERIAL_ID"); + if( component_id == material_id) + { + component_name = com_rec->getString("COMPNAME"); + component_fraction = com_rec->getDouble("FRACTION"); + + if(firstComponent) + { + firstComponent = false; + if(component_fraction>=1.) + calculateFraction = true; + } + + if( CheckElement( component_name) == 1) + { + p_com_element = getElement(component_name); + + if(calculateFraction) + { + totalFraction += component_fraction*p_com_element->getA(); + elementComponents.push_back(p_com_element); + elementFractions.push_back(component_fraction); + } + else + pmaterial->add( p_com_element, component_fraction); + + } + else{ + hasSubMaterial = true; + p_com_material = getMaterial(component_name); + + pmaterial->add(p_com_material, component_fraction); + + } + } + } + + if(calculateFraction && hasSubMaterial && elementComponents.size()>0) + std::cerr << material_name << " description should be changed. Please indicate the exact fraction for elements\n"; + + if(calculateFraction && !elementComponents.empty()) { + const double inv_totalFraction = 1. / totalFraction; + for(unsigned i=0; i<elementComponents.size(); i++) + pmaterial->add(elementComponents[i],elementFractions[i]*elementComponents[i]->getA() * inv_totalFraction); + } + + // a table to keep the memory allocation, and easy for delete + addMaterial(detector,pmaterial); + + /* { + printFullMaterial ( pmaterial); + printAll( std:: cout); + } + */ + return pmaterial; +} + +const GeoMaterial* RDBMaterialManager:: getMaterial(const std::string &name) const{ + + unsigned int ind, com_ind; + + std::string material_name; + std::string tmp_name; + long material_id = 0; + double material_density = 0; + + + std::string component_name; + double component_fraction; + int component_id; + + std::string detector; + std::string tmp_det; + std::string data_id; + + + std::string matcomponents_table; + + if(!s_specialMaterials) + { + buildSpecialMaterials(); + s_specialMaterials = true; + } + + + GeoMaterial* pmaterial; + + GeoMaterial* p_com_material; + GeoElement* p_com_element; + + IRDBRecordset_ptr tmp_materials; + IRDBRecordset_ptr tmp_matcomponents; + + MsgStream log(Athena::getMessageSvc(), "GeoModelSvc::RDBMaterialManager"); + if(log.level()<=MSG::DEBUG) + log << MSG::DEBUG << " ***** getMaterial( ): " << name << endmsg; + + pmaterial = NULL; + pmaterial = searchMaterialMap( name); + if (pmaterial!= NULL) + return pmaterial; + + if(name.find("std",0) == 0) + { + detector = "std"; + tmp_materials = m_stdmaterials; + tmp_matcomponents = m_stdmatcomponents; + data_id = "STDMATERIALS_DATA_ID"; + } + else if(name.find("scint",0) == 0) + { + detector = "scint"; + tmp_materials = m_scintmaterials; + tmp_matcomponents = m_scintmatcomponents; + data_id = "SCINTMATERIALS_DATA_ID"; + } + // else if(name.find("sct",0) == 0) + // { + // detector = "sct"; + // tmp_materials = m_sctmaterials; + // tmp_matcomponents = m_sctmatcomponents; + // data_id = "SCTMATERIALS_DATA_ID"; + // } + // else if(name.find("indet",0) == 0) + // { + // detector = "indet"; + // tmp_materials = m_indetmaterials; + // tmp_matcomponents = m_indetmatcomponents; + // data_id = "INDETMATERIALS_DATA_ID"; + // } + else {return 0 ;} + + for( ind = 0; ind < tmp_materials->size(); ind++) + { + const IRDBRecord* rec = (*tmp_materials)[ind]; + tmp_name = detector+"::"+rec->getString("NAME"); + + if( name == tmp_name){ + material_name = rec->getString("NAME"); + material_id = rec->getLong(data_id); + material_density = rec->getDouble("DENSITY"); + + if(log.level()<=MSG::DEBUG) + log << MSG::DEBUG << " ***** Material: name id density: " << material_name <<" " << material_id <<" "<< material_density << endmsg; + break; + } + } + + if (ind == tmp_materials->size()) + return NULL; + + pmaterial = new GeoMaterial( material_name,material_density * (GeoModelKernelUnits::gram / Gaudi::Units::cm3)); + + bool firstComponent = true; + bool hasSubMaterial = false; + bool calculateFraction = false; + double totalFraction = 0.; + std::vector < GeoElement* > elementComponents; + std::vector <double> elementFractions; + + for( com_ind = 0; com_ind <tmp_matcomponents->size(); com_ind++) + { + const IRDBRecord* com_rec = (*tmp_matcomponents)[com_ind]; + + component_id = com_rec->getLong("MATERIAL_ID"); + if( component_id == material_id) + { + component_name = com_rec->getString("COMPNAME"); + component_fraction = com_rec->getDouble("FRACTION"); + + if(firstComponent) + { + firstComponent = false; + if(component_fraction>=1.) + calculateFraction = true; + } + + if( CheckElement( component_name) == 1) + { + p_com_element = (GeoElement *)(getElement(component_name)); + + if(calculateFraction) + { + totalFraction += component_fraction*p_com_element->getA(); + elementComponents.push_back(p_com_element); + elementFractions.push_back(component_fraction); + } + else + pmaterial->add( p_com_element, component_fraction); + + } + else{ + hasSubMaterial = true; + p_com_material = (GeoMaterial *)getMaterial(component_name); + + pmaterial->add(p_com_material, component_fraction); + + } + } + } + + if(calculateFraction && hasSubMaterial && elementComponents.size()>0) + std::cerr << material_name << " description should be changed. Please indicate the exact fraction for elements\n"; + + if(calculateFraction && !elementComponents.empty()) { + double inv_totalFraction = 1. / totalFraction; + for(unsigned i=0; i<elementComponents.size(); i++) + pmaterial->add(elementComponents[i],elementFractions[i]*elementComponents[i]->getA() * inv_totalFraction); + } + + // a table to keep the memory allocation, and easy for delete + addMaterial(detector,pmaterial); + + return pmaterial; +} + + +const GeoElement *RDBMaterialManager::getElement(const std::string & name) const{ + + unsigned int ind; + + std::string element_name; + std::string element_symbol; + std::string tmp_name; + + double element_a; + double element_z; + + GeoElement *pelement; + + pelement = NULL; + pelement = searchElementVector( name); + if (pelement != NULL) + return pelement; + + MsgStream log(Athena::getMessageSvc(), "GeoModelSvc::RDBMaterialManager"); + if(log.level()==MSG::VERBOSE) + log << MSG::VERBOSE << " ***** getElement(): " << name <<endmsg; + + for(ind = 0; ind < m_elements->size(); ind++) + { + const IRDBRecord* rec = (*m_elements)[ind]; + + tmp_name = rec->getString("NAME"); + + if( name == tmp_name) + { + element_name = rec->getString("NAME"); + element_symbol = rec->getString("SYMBOL"); + element_a = rec->getDouble("A"); + element_z = rec->getDouble("Z"); + + pelement = new GeoElement( element_name , element_symbol ,element_z , element_a *(GeoModelKernelUnits::gram/Gaudi::Units::mole)); + + // a table to keep the memory allocation, and easy for delete + pelement->ref(); + m_elementVector.push_back( pelement); + + break; + } + } + if (ind == m_elements->size()) return NULL; + + return pelement; + +} + + +const GeoElement *RDBMaterialManager::getElement(unsigned int atomicNumber) const { + + unsigned int ind; + + std::string element_name; + std::string element_symbol; + + double element_a; + double element_z; + + GeoElement* pelement(0); + + MsgStream log(Athena::getMessageSvc(), "GeoModelSvc::RDBMaterialManager"); + if(log.level()==MSG::VERBOSE) + log << MSG::VERBOSE << " ***** const getElement(atomicNumber) const : " << atomicNumber <<endmsg; + + for(ind = 0; ind < m_elements->size(); ind++) + { + const IRDBRecord* rec = (*m_elements)[ind]; + + if(atomicNumber == rec->getDouble("A")) + { + element_name = rec->getString("NAME"); + element_symbol = rec->getString("SYMBOL"); + element_a = rec->getDouble("A"); + element_z = rec->getDouble("Z"); + + pelement = new GeoElement( element_name , element_symbol ,element_z , element_a *(GeoModelKernelUnits::gram/Gaudi::Units::mole)); + + // a table to keep the memory allocation, and easy for delete + pelement->ref(); + m_elementVector.push_back( pelement); + + break; + } + } + if (ind == m_elements->size()) return NULL; + + return pelement; +} + + +GeoElement *RDBMaterialManager::getElement(const std::string & name) { + + unsigned int ind; + + std::string element_name; + std::string element_symbol; + std::string tmp_name; + + double element_a; + double element_z; + + GeoElement *pelement; + + MsgStream log(Athena::getMessageSvc(), "GeoModelSvc::RDBMaterialManager"); + if(log.level()==MSG::VERBOSE) + log << MSG::VERBOSE << " ***** getElement(): " << element_name <<endmsg; + + pelement = NULL; + pelement = searchElementVector( name); + if (pelement != NULL) + return pelement; + + for(ind = 0; ind < m_elements->size(); ind++) + { + const IRDBRecord* rec = (*m_elements)[ind]; + + tmp_name = rec->getString("NAME"); + + if( name == tmp_name) + { + element_name = rec->getString("NAME"); + element_symbol = rec->getString("SYMBOL"); + element_a = rec->getDouble("A"); + element_z = rec->getDouble("Z"); + + pelement = new GeoElement( element_name , element_symbol ,element_z , element_a *(GeoModelKernelUnits::gram/Gaudi::Units::mole)); + + // a table to keep the memory allocation, and easy for delete + pelement->ref(); + m_elementVector.push_back( pelement); + break; + + } + } + if (ind == m_elements->size()) return NULL; + + return pelement; +} + + +GeoElement *RDBMaterialManager::getElement(unsigned int atomicNumber) { + + unsigned int ind; + + std::string element_name; + std::string element_symbol; + + double element_a; + double element_z; + + GeoElement* pelement(0); + + MsgStream log(Athena::getMessageSvc(), "GeoModelSvc::RDBMaterialManager"); + if(log.level()==MSG::VERBOSE) + log << MSG::VERBOSE << " ***** getElement(atomicNumber): " << element_name <<endmsg; + + for(ind = 0; ind < m_elements->size(); ind++) + { + const IRDBRecord* rec = (*m_elements)[ind]; + + if(atomicNumber == rec->getDouble("A")) + { + element_name = rec->getString("NAME"); + element_symbol = rec->getString("SYMBOL"); + element_a = rec->getDouble("A"); + element_z = rec->getDouble("Z"); + + pelement = new GeoElement( element_name , element_symbol ,element_z , element_a *(GeoModelKernelUnits::gram/Gaudi::Units::mole)); + + // a table to keep the memory allocation, and easy for delete + pelement->ref(); + m_elementVector.push_back( pelement); + + break; + } + } + if (ind == m_elements->size()) return NULL; + + return pelement; +} + +void RDBMaterialManager::addMaterial(const std::string & space, GeoMaterial *material) { + + MsgStream log(Athena::getMessageSvc(), "GeoModelSvc::RDBMaterialManager"); + if(log.level()==MSG::VERBOSE) + log << MSG::VERBOSE << " ***** RDBMaterialManager::addMaterial() "<<endmsg; + + std::string key = space + std::string("::")+ std::string(material->getName()); + // Check whether we already have materials with the same space::name defined + if(m_materialMap.find(key)!=m_materialMap.end()) + log << MSG::WARNING << " Attempt to redefine material " << key << "!. The existing instance is kept. Please choose another name for new material" << endmsg; + else { + material->lock(); + material->ref(); + m_materialMap[key]=material; + } +} + +void RDBMaterialManager::addMaterial(const std::string & space, GeoMaterial *material) const { + + MsgStream log(Athena::getMessageSvc(), "GeoModelSvc::RDBMaterialManager"); + if(log.level()==MSG::VERBOSE) + log << MSG::VERBOSE << " ***** RDBMaterialManager::addMaterial() "<<endmsg; + + std::string key = space + std::string("::")+ std::string(material->getName()); + // Check whether we already have materials with the same space::name defined + if(m_materialMap.find(key)!=m_materialMap.end()) + log << MSG::WARNING << " Attempt to redefine material " << key << "!. The existing instance is kept. Please choose another name for new material" << endmsg; + else { + material->lock(); + material->ref(); + m_materialMap[key]=material; + } +} + +StoredMaterialManager::MaterialMapIterator RDBMaterialManager::begin() const +{ + return m_materialMap.begin(); +} + +StoredMaterialManager::MaterialMapIterator RDBMaterialManager::end() const +{ + return m_materialMap.end(); +} + +size_t RDBMaterialManager::size() +{ + return m_materialMap.size(); +} + +std::ostream & RDBMaterialManager::printAll(std::ostream & o) const +{ + o << "============Material Manager Element List========================" << std::endl; + std::vector<GeoElement *>::const_iterator e; + for (e=m_elementVector.begin();e!= m_elementVector.end();e++) + { + o << (*e)->getSymbol() << '\t' << (*e)->getZ() << '\t' << (*e)->getA() * (Gaudi::Units::mole / GeoModelKernelUnits::gram) << '\t' << (*e)->getName() << std::endl; + } + std::map<std::string, GeoMaterial *>::const_iterator m; + + for (m=m_materialMap.begin();m!=m_materialMap.end();m++) + { + o << "Material: " << (*m).first << " Density " << (*m).second->getDensity() * (Gaudi::Units::cm3 / GeoModelKernelUnits::gram) << std::endl; + for (size_t i = 0; i< (*m).second->getNumElements();i++) + { + o <<" ***** ***** "<< int ((*m).second->getFraction(i)*100) << "% \t" << (*m).second->getElement(i)->getName() << std::endl; + } + } + + return o; +} + +void RDBMaterialManager::buildSpecialMaterials() +{ + // Create special materials + GeoElement* ethElement = new GeoElement("Ether","ET",500.0,0.0); + ethElement->ref(); + m_elementVector.push_back(ethElement); + GeoMaterial* ether = new GeoMaterial("Ether",0.0); + ether->add(ethElement,1.); + addMaterial("special",ether); + // "Alternative" assembly material + GeoMaterial* hu = new GeoMaterial("HyperUranium",0.0); + hu->add(ethElement,1.); + addMaterial("special",hu); +} + +void RDBMaterialManager::buildSpecialMaterials() const +{ + // Create special materials + GeoElement* ethElement = new GeoElement("Ether","ET",500.0,0.0); + ethElement->ref(); + m_elementVector.push_back(ethElement); + GeoMaterial* ether = new GeoMaterial("Ether",0.0); + ether->add(ethElement,1.); + addMaterial("special",ether); + // "Alternative" assembly material + GeoMaterial* hu = new GeoMaterial("HyperUranium",0.0); + hu->add(ethElement,1.); + addMaterial("special",hu); +} diff --git a/DetectorDescription/GeoModel/GeoModelSvc/src/RDBMaterialManager.h b/DetectorDescription/GeoModel/GeoModelSvc/src/RDBMaterialManager.h new file mode 100644 index 0000000000000000000000000000000000000000..d0904e16ba2123dad67a3a62acb2a92265b4e74a --- /dev/null +++ b/DetectorDescription/GeoModel/GeoModelSvc/src/RDBMaterialManager.h @@ -0,0 +1,94 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef _RDBMATERIALMANAGER_H_ +#define _RDBMATERIALMANAGER_H_ +//---------------------------------------------------------// +// // +// class RDBMaterialManager This is a material manager // +// which gets its material from RDB. // +// // +// Joe Boudreau March 2003 // +// // +// Heavily modified for FASER // +// // +//---------------------------------------------------------// +#include "GeoModelInterfaces/StoredMaterialManager.h" +#include "RDBAccessSvc/IRDBAccessSvc.h" + +#include <string> +#include <map> +#include <vector> +#include <iosfwd> + +class GeoMaterial; +class ISvcLocator; + + +class RDBMaterialManager: public StoredMaterialManager { + + public: + + // Constructor: + RDBMaterialManager(ISvcLocator* pSvcLocator); + + // Destructor: + virtual ~RDBMaterialManager(); + + // Query the material: + virtual GeoMaterial *getMaterial(const std::string &name) ; + virtual const GeoMaterial *getMaterial(const std::string &name) const; + + + // Query the elements: + virtual const GeoElement *getElement(const std::string & name) const; + virtual GeoElement *getElement(const std::string & name); + + // Query the elements (by atomic number): + virtual const GeoElement *getElement(unsigned int atomicNumber) const; + virtual GeoElement *getElement(unsigned int atomicNumber); + + // Add new material + virtual void addMaterial(const std::string& space, GeoMaterial* material); + virtual void addMaterial(const std::string& space, GeoMaterial* material) const; + + virtual StoredMaterialManager::MaterialMapIterator begin() const; + virtual StoredMaterialManager::MaterialMapIterator end() const; + + // Number of materials in the manager + virtual size_t size(); + + virtual std::ostream & printAll(std::ostream & o=std::cout) const; + + private: + static bool s_specialMaterials; + + StatusCode readMaterialsFromDB(ISvcLocator* pSvcLocator); + + void buildSpecialMaterials(); + void buildSpecialMaterials() const; + + GeoElement *searchElementVector (const std::string & name); + GeoElement *searchElementVector (const std::string & name) const; + + GeoElement *searchElementVector (const unsigned int atomicNumber); + GeoElement *searchElementVector (const unsigned int atomicNumber) const; + + GeoMaterial *searchMaterialMap (const std::string & name); + GeoMaterial *searchMaterialMap (const std::string & name) const; + + // For DataBase connection and Query + IRDBRecordset_ptr m_elements; + + IRDBRecordset_ptr m_stdmaterials; + IRDBRecordset_ptr m_stdmatcomponents; + IRDBRecordset_ptr m_scintmaterials; + IRDBRecordset_ptr m_scintmatcomponents; + + mutable std::vector < GeoElement *> m_elementVector; + mutable StoredMaterialManager::MaterialMap m_materialMap; +}; + + +#endif diff --git a/DetectorDescription/GeoModel/GeoModelSvc/src/components/GeoModelSvc_entries.cxx b/DetectorDescription/GeoModel/GeoModelSvc/src/components/GeoModelSvc_entries.cxx new file mode 100644 index 0000000000000000000000000000000000000000..eda713dbfd8ad653043574a80c2a6f3ce576ddd4 --- /dev/null +++ b/DetectorDescription/GeoModel/GeoModelSvc/src/components/GeoModelSvc_entries.cxx @@ -0,0 +1,6 @@ +#include "../GeoModelSvc.h" +#include "../GeoDbTagSvc.h" + +DECLARE_COMPONENT( GeoModelSvc ) +DECLARE_COMPONENT( GeoDbTagSvc ) +