From 08c718c5ab95566ba9660fd8a688d47952a34da2 Mon Sep 17 00:00:00 2001 From: Markus Frank <markus.frank@cern.ch> Date: Wed, 10 Feb 2016 16:49:22 +0000 Subject: [PATCH] First version of conditions implementation --- DDCond/CMakeLists.txt | 2 +- DDCond/include/DDCond/ConditionValidator.h | 44 -- DDCond/include/DDCond/ConditionsDataLoader.h | 86 +++ DDCond/include/DDCond/ConditionsEntry.h | 63 ++ DDCond/include/DDCond/ConditionsHandler.h | 76 -- DDCond/include/DDCond/ConditionsInterna.h | 245 +++++++ DDCond/include/DDCond/ConditionsManager.h | 168 +++++ DDCond/include/DDCond/ConditionsPool.h | 155 ++++ DDCond/include/DDCond/ConditionsStack.h | 75 -- DDCond/include/DDCond/ConditionsTransaction.h | 57 -- DDCond/src/ConditionTest.cpp | 121 ---- DDCond/src/ConditionsDataLoader.cpp | 50 ++ DDCond/src/ConditionsEntry.cpp | 50 ++ DDCond/src/ConditionsExample.cpp | 164 +++++ DDCond/src/ConditionsHandler.cpp | 121 ---- DDCond/src/ConditionsInterna.cpp | 679 ++++++++++++++++++ DDCond/src/ConditionsLinearPool.cpp | 272 +++++++ DDCond/src/ConditionsManager.cpp | 194 +++++ DDCond/src/ConditionsMultiLoader.cpp | 174 +++++ DDCond/src/ConditionsParser.cpp | 268 +++---- DDCond/src/ConditionsPool.cpp | 76 ++ DDCond/src/ConditionsStack.cpp | 116 --- DDCond/src/ConditionsTest.cpp | 233 ++++++ DDCond/src/ConditionsTest.h | 65 ++ DDCond/src/ConditionsTransaction.cpp | 41 -- DDCond/src/ConditionsXmlLoader.cpp | 186 +++++ .../include/DD4hep}/ComponentProperties.h | 47 +- .../include/DD4hep}/ComponentProperties_inl.h | 4 +- DDCore/include/DD4hep/Conditions.h | 160 +++-- DDCore/include/DD4hep/Detector.h | 25 +- DDCore/include/DD4hep/DetectorSelector.h | 4 + DDCore/include/DD4hep/Dictionary.h | 114 +-- DDCore/include/DD4hep/Errors.h | 55 ++ DDCore/include/DD4hep/Factories.h | 25 +- DDCore/include/DD4hep/Handle.h | 542 +++++++------- DDCore/include/DD4hep/Handle.inl | 64 +- DDCore/include/DD4hep/LCDD.h | 5 +- DDCore/include/DD4hep/Mutex.h | 42 ++ DDCore/include/DD4hep/PluginCreators.h | 64 ++ DDCore/include/DD4hep/Plugins.h | 4 +- DDCore/include/DD4hep/Primitives.h | 125 +++- DDCore/include/DD4hep/Printout.h | 6 +- DDCore/include/DD4hep/World.h | 75 ++ .../DD4hep/objects/ConditionsInterna.h | 256 +++---- .../include/DD4hep/objects/DetectorInterna.h | 39 +- {DDG4 => DDCore}/src/ComponentProperties.cpp | 24 +- DDCore/src/Conditions.cpp | 160 +++-- DDCore/src/ConditionsInterna.cpp | 144 ++-- DDCore/src/Detector.cpp | 31 +- DDCore/src/DetectorInterna.cpp | 37 +- DDCore/src/Errors.cpp | 34 + DDCore/src/Handle.cpp | 80 +-- DDCore/src/LCDDImp.cpp | 18 +- DDCore/src/LCDDImp.h | 6 +- DDCore/src/LCDDLoad.cpp | 2 +- DDCore/src/PluginCreators.cpp | 62 ++ DDCore/src/Plugins.cpp | 1 + DDCore/src/Primitives.cpp | 128 ++-- DDCore/src/VolumeManager.cpp | 2 +- .../src/World.cpp | 24 +- DDCore/src/plugins/Compact2Objects.cpp | 2 +- DDCore/src/plugins/LCDDFields.cpp | 16 +- DDCore/src/plugins/PluginInvoker.cpp | 4 +- DDDetectors/src/CaloFaceBarrel_surfaces.cpp | 6 +- DDDetectors/src/CaloFaceEndcap_surfaces.cpp | 2 +- DDDetectors/src/GenericSurfaceInstaller.cpp | 2 +- DDDetectors/src/SiTrackerBarrel_surfaces.cpp | 2 +- DDDetectors/src/SurfaceExamplePlugin.cpp | 2 +- DDG4/include/DDG4/Geant4Action.h | 2 +- DDG4/include/DDG4/Geant4Handle.h | 2 +- DDG4/include/DDG4/Geant4UIMessenger.h | 4 +- DDG4/plugins/Geant4FieldTrackingSetup.cpp | 4 +- DDG4/python/DD4hep.py | 5 +- DDG4/python/DDG4.py | 1 + UtilityApps/src/run_plugin.h | 69 +- doc/CompileAllOptionPermutations.sh | 7 +- doc/release.notes | 6 + 77 files changed, 4666 insertions(+), 1660 deletions(-) delete mode 100644 DDCond/include/DDCond/ConditionValidator.h create mode 100644 DDCond/include/DDCond/ConditionsDataLoader.h create mode 100644 DDCond/include/DDCond/ConditionsEntry.h delete mode 100644 DDCond/include/DDCond/ConditionsHandler.h create mode 100644 DDCond/include/DDCond/ConditionsInterna.h create mode 100644 DDCond/include/DDCond/ConditionsManager.h create mode 100644 DDCond/include/DDCond/ConditionsPool.h delete mode 100644 DDCond/include/DDCond/ConditionsStack.h delete mode 100644 DDCond/include/DDCond/ConditionsTransaction.h delete mode 100644 DDCond/src/ConditionTest.cpp create mode 100644 DDCond/src/ConditionsDataLoader.cpp create mode 100644 DDCond/src/ConditionsEntry.cpp create mode 100644 DDCond/src/ConditionsExample.cpp delete mode 100644 DDCond/src/ConditionsHandler.cpp create mode 100644 DDCond/src/ConditionsInterna.cpp create mode 100644 DDCond/src/ConditionsLinearPool.cpp create mode 100644 DDCond/src/ConditionsManager.cpp create mode 100644 DDCond/src/ConditionsMultiLoader.cpp create mode 100644 DDCond/src/ConditionsPool.cpp delete mode 100644 DDCond/src/ConditionsStack.cpp create mode 100644 DDCond/src/ConditionsTest.cpp create mode 100644 DDCond/src/ConditionsTest.h delete mode 100644 DDCond/src/ConditionsTransaction.cpp create mode 100644 DDCond/src/ConditionsXmlLoader.cpp rename {DDG4/include/DDG4 => DDCore/include/DD4hep}/ComponentProperties.h (85%) rename {DDG4/include/DDG4 => DDCore/include/DD4hep}/ComponentProperties_inl.h (98%) create mode 100644 DDCore/include/DD4hep/Errors.h create mode 100644 DDCore/include/DD4hep/Mutex.h create mode 100644 DDCore/include/DD4hep/PluginCreators.h create mode 100644 DDCore/include/DD4hep/World.h rename {DDG4 => DDCore}/src/ComponentProperties.cpp (93%) create mode 100644 DDCore/src/Errors.cpp create mode 100644 DDCore/src/PluginCreators.cpp rename DDCond/src/ConditionValidator.cpp => DDCore/src/World.cpp (61%) diff --git a/DDCond/CMakeLists.txt b/DDCond/CMakeLists.txt index 6d0d8bba3..d27c519a6 100644 --- a/DDCond/CMakeLists.txt +++ b/DDCond/CMakeLists.txt @@ -10,7 +10,7 @@ # #========================================================================== dd4hep_package( DDCond - USES DDCore + USES BOOST DDCore INCLUDE_DIRS include INSTALL_INCLUDES include/DDCond) diff --git a/DDCond/include/DDCond/ConditionValidator.h b/DDCond/include/DDCond/ConditionValidator.h deleted file mode 100644 index 5b7410ea4..000000000 --- a/DDCond/include/DDCond/ConditionValidator.h +++ /dev/null @@ -1,44 +0,0 @@ -// $Id: $ -//========================================================================== -// AIDA Detector description implementation for LCD -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see $DD4hepINSTALL/LICENSE. -// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. -// -// Author : M.Frank -// -//========================================================================== -#ifndef DD4HEP_GEOMETRY_CONDITIONVALIDATOR_H -#define DD4HEP_GEOMETRY_CONDITIONVALIDATOR_H - -// Framework includes -#include "DDCond/Condition.h" - -/// Namespace for the AIDA detector description toolkit -namespace DD4hep { - - /// Namespace for the geometry part of the AIDA detector description toolkit - namespace Geometry { - - /// Conditions validation class. - /** - * \author M.Frank - * \version 1.0 - * \ingroup DD4HEP_CONDITIONS - */ - class ConditionValidator { - public: - - /// Standard constructor - ConditionValidator(); - /// Validate detector subtree and return conditions out of date - bool validate(DetElement subtree, std::vector<Condition>& tobe_updated); - - }; - - } /* End namespace Geometry */ -} /* End namespace DD4hep */ -#endif /* DD4HEP_GEOMETRY_CONDITIONVALIDATOR_H */ diff --git a/DDCond/include/DDCond/ConditionsDataLoader.h b/DDCond/include/DDCond/ConditionsDataLoader.h new file mode 100644 index 000000000..2b6bcd2dd --- /dev/null +++ b/DDCond/include/DDCond/ConditionsDataLoader.h @@ -0,0 +1,86 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +#ifndef DDCOND_CONDITIONSDATALOADER_H +#define DDCOND_CONDITIONSDATALOADER_H + +// Framework include files +#include "DD4hep/Conditions.h" +#include "DD4hep/NamedObject.h" +#include "DD4hep/ComponentProperties.h" +#include "DDCond/ConditionsManager.h" + +// C/C++ include files +#include <list> +#include <set> + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Conditions { + + // Forward declarations + class Entry; + class ConditionsDataLoader; + typedef std::list<Entry*> ConditionsStack; + + /// Interface for a generic conditions loader + /** + * Common function for all loader. + * + * \author M.Frank + * \version 1.0 + */ + class ConditionsDataLoader : public NamedObject, public PropertyConfigurable { + public: + typedef std::vector<std::string> Sources; + typedef ConditionsDataLoader base_t; + + protected: + /// Reference to main detector description object + LCDD& m_lcdd; + /// Reference to conditions manager used to queue update requests + ConditionsManager m_mgr; + /// Property: input data source definitions + Sources m_sources; + + protected: + /// Queue update to manager. + Condition queueUpdate(Entry* data); + /// Push update to manager. + void pushUpdates(); + + public: + /// Default constructor + ConditionsDataLoader(LCDD& lcdd, ConditionsManager mgr, const std::string nam); + /// Default destructor + virtual ~ConditionsDataLoader(); + /// Add data source definition to loader + void addSource(const std::string& source); + /// Load a condition set given a Detector Element and the conditions name according to their validity + virtual size_t load(DetElement det, + const std::string& cond, + const IOV& req_validity, + RangeConditions& conditions) = 0; + /// Load a condition set given a Detector Element and the conditions name according to their validity + virtual size_t load_range(DetElement det, + const std::string& cond, + const IOV& req_validity, + RangeConditions& conditions) = 0; + }; + + } /* End namespace Conditions */ +} /* End namespace DD4hep */ + +#endif /* DDCOND_CONDITIONSDATALOADER_H */ diff --git a/DDCond/include/DDCond/ConditionsEntry.h b/DDCond/include/DDCond/ConditionsEntry.h new file mode 100644 index 000000000..e34b6dc2c --- /dev/null +++ b/DDCond/include/DDCond/ConditionsEntry.h @@ -0,0 +1,63 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +#ifndef DDCOND_CONDITIONSENTRY_H +#define DDCOND_CONDITIONSENTRY_H + +// Framework include files +#include "DD4hep/NamedObject.h" +#include "DD4hep/Detector.h" + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Conditions { + + // Forward declarations + class Entry; + + /// The intermediate conditions data used to populate the DetElement conditions + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class Entry : public NamedObject { + public: + /// Reference to the detector element + DetElement detector; + /// The actual conditions data + std::string value; + /// The validity string to be interpreted by the updating engine + std::string validity; + /// Hash value of the name for fast identification + int hash; + /// Default constructor + Entry() {} + /// Initializing constructor + Entry(const DetElement& det, const std::string& nam, const std::string& typ, const std::string& valid, int hash); + /// Copy constructor + Entry(const Entry& c); + /// Default destructor + virtual ~Entry(); + /// Assignment operator + Entry& operator=(const Entry& c); + }; + + + } /* End namespace Conditions */ +} /* End namespace DD4hep */ + +#endif /* DDCOND_CONDITIONSENTRY_H */ diff --git a/DDCond/include/DDCond/ConditionsHandler.h b/DDCond/include/DDCond/ConditionsHandler.h deleted file mode 100644 index 4fe6835ca..000000000 --- a/DDCond/include/DDCond/ConditionsHandler.h +++ /dev/null @@ -1,76 +0,0 @@ -// $Id: $ -//========================================================================== -// AIDA Detector description implementation for LCD -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see $DD4hepINSTALL/LICENSE. -// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. -// -// Author : M.Frank -// -//========================================================================== -#ifndef DD4HEP_CONDITIONS_CONDITIONSHANDLER_H -#define DD4HEP_CONDITIONS_CONDITIONSHANDLER_H - -// Framework include files -#include "DDCond/ConditionsStack.h" - -/// Namespace for the AIDA detector description toolkit -namespace DD4hep { - - /// Namespace for the geometry part of the AIDA detector description toolkit - namespace Geometry { - - /// Forward declarations - class ConditionsStack; - class LCDD; - - /// Class caching all known conditions operations for one LCDD instance. - /** - * Internally the instances are fragmented to subdetectors defined - * by the next-to-top level detector elements. - * - * \author M.Frank - * \version 1.0 - * \ingroup DD4HEP_CONDITIONS - */ - class ConditionsHandler { - friend class LCDD; - - protected: - LCDD& m_lcdd; - /// Reference count - int m_refCount; - - protected: - /// Default constructor - ConditionsHandler(LCDD& lcdd); - /// Default destructor - virtual ~ConditionsHandler(); - /// Population entry: Apply a complete stack of ordered conditionss to the geometry structure - void apply(ConditionsStack& stack); - - public: - /// Create and install a new instance tree - static void install(LCDD& lcdd); - /// Unregister and delete a tree instance - static void uninstall(LCDD& lcdd); - - /// Functor callback - static void triggerUpdate(DetElement detector); - - /// Add reference count - int addRef(); - /// Release object. If reference count goes to NULL, automatic deletion is triggered. - int release(); - /// Open a new transaction stack (Note: only one stack allowed!) - void openTransaction(); - /// Close existing transaction stack and apply all conditionss - void closeTransaction(); - }; - - } /* End namespace Geometry */ -} /* End namespace DD4hep */ -#endif /* DD4HEP_CONDITIONS_CONDITIONSHANDLER_H */ diff --git a/DDCond/include/DDCond/ConditionsInterna.h b/DDCond/include/DDCond/ConditionsInterna.h new file mode 100644 index 000000000..1abb02878 --- /dev/null +++ b/DDCond/include/DDCond/ConditionsInterna.h @@ -0,0 +1,245 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +#ifndef DDCOND_CONDITIONSINTERNA_H +#define DDCOND_CONDITIONSINTERNA_H + +// Framework include files +#include "DD4hep/Mutex.h" +#include "DD4hep/Memory.h" +#include "DD4hep/Conditions.h" +#include "DDCond/ConditionsPool.h" +#include "DDCond/ConditionsDataLoader.h" + +// C/C++ include files +#include <set> +#include <list> + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Conditions { + + class Entry; + class IOVPool; + class ConditionsPool; + class ConditionsDataLoader; + typedef std::pair<RangeConditions,bool> RangeStatus; + + using Geometry::LCDD; + using Geometry::DetElement; + + /// Conditions internal namespace declaration + /** Internally defined datastructures are not presented to the + * user directly, but are used by dedicated views. + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + namespace Interna { + + /// The data class behind a conditions manager handle + /** + * For convenience, the class definition is here. + * See ConditionsManager.cpp for the implementation. + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class ConditionsManagerObject : public NamedObject, public PropertyConfigurable { + public: + friend class ConditionsDataLoader; + + typedef dd4hep_ptr<ConditionsDataLoader> Loader; + typedef std::vector<IOVType> IOVTypes; + typedef std::vector<IOVPool*> TypedConditionPool; + + typedef std::map<IOV::Key, ReplacementPool*> ReplacementCache; + typedef std::vector<ReplacementPool*> FreePools; + + public: + /// Property: maximal number of IOV types to be handled + int m_maxIOVTypes; + /// Property: ConditionsPool constructor type (default: empty. MUST BE SET!) + std::string m_poolType; + /// Property: UpdatePool constructor type (default: DD4hep_ConditionsLinearUpdatePool) + std::string m_updateType; + /// Property: ReplacementPool constructor type (default: DD4hep_ConditionsLinearReplacementPool) + std::string m_replType; + /// Property: Conditions loader type (default: "multi" -> DD4hep_Conditions_multi_Loader) + std::string m_loaderType; + + + /// Reference to main detector description object + LCDD& m_lcdd; + IOVTypes m_iovTypes; + TypedConditionPool m_pool; + /// Lock to protect the update/delayed conditions pool + dd4hep_mutex_t m_updateLock; + /// Lock to protect the pool of all known conditions + dd4hep_mutex_t m_poolLock; + /// Reference to data loader + Loader m_loader; + /// Reference to update conditions pool + dd4hep_ptr<UpdatePool> m_updatePool; + /// Public access: if locked, DetElements stay intact and are not altered + int locked; + + protected: + /// Retrieve a condition set given a Detector Element and the conditions name according to their validity + bool __find(DetElement detector, + const std::string& condition_name, + const IOV& req_validity, + RangeConditions& conditions); + + /// Retrieve a condition set given a Detector Element and the conditions name according to their validity + bool __find_range(DetElement detector, + const std::string& condition_name, + const IOV& req_validity, + RangeConditions& conditions); + + /// Load a condition set given a Detector Element and the conditions name according to their validity + bool __load_immediate(DetElement detector, + const std::string& condition_name, + const IOV& req_validity, + RangeConditions& conditions); + /// Load a condition set given a Detector Element and the conditions name according to their validity + bool __load_range_immediate(DetElement detector, + const std::string& condition_name, + const IOV& req_validity, + RangeConditions& conditions); + /// Register a set of new managed condition for an IOV range. Called by __load_immediate + void __register_immediate(RangeConditions& c); + + /// Push registered set of conditions to the corresponding detector elements + void __push_immediate(RangeConditions& rc); + + public: + /// Set a single conditions value to be managed. + /// Requires EXTERNALLY held lock on update pool! + Condition __queue_update(Entry* data); + + public: + /// Standard constructor + ConditionsManagerObject(LCDD& lcdd); + + /// Default destructor + virtual ~ConditionsManagerObject(); + + void initialize(); + + /// Register new IOV type if it does not (yet) exist. + /** Returns (false,pointer) if IOV existed and + * (true,pointer) if new IOV was registered to the manager. + */ + std::pair<bool, const IOVType*> registerIOVType(size_t iov_type, const std::string& iov_name); + + /// Access IOV by its type + const IOVType* iovType (size_t iov_type) const; + + /// Access IOV by its name + const IOVType* iovType (const std::string& iov_name) const; + + /// Register IOV using new string data + ConditionsPool* registerIOV(const std::string& data); + /// Register IOV with type and key + ConditionsPool* registerIOV(const IOVType& typ, IOV::Key key); + + + /// Prepare all updates to the clients with the defined IOV + void prepare(const IOV& required_validity); + + /// Enable all updates to the clients with the defined IOV + void enable(const IOV& required_validity); + + /// Validate the conditions set and age all unused conditions + void validate(const IOV& iov); + + /// Age conditions, which are no longer used and to be removed eventually + void age(); + + /// Clean conditions, which are above the age limit. + void clean(); + + /// Full cleanup of all managed conditions. + void clear(); + + /// Push all pending updates to the conditions store. + /** Note: + * This does not yet make the new conditions availible to the clients + */ + void pushUpdates(); + + /// Register a new managed condition. + /** The condition is created externally by the user. + * Lengthy and tedious procedure. + */ + void registerCondition(Condition c); + + /// Retrieve a condition set given a Detector Element and the conditions name according to their validity + Condition get(DetElement detector, + const std::string& condition_name, + const IOV& req_validity); + + /// Retrieve a condition given a Detector Element and the conditions name + RangeConditions getRange(DetElement detector, + const std::string& condition_name, + const IOV& req_range_validity); + }; + } /* End namespace Interna */ + + /// Pool of conditions satisfying one IOV type (epoch, run, fill, etc) + /** + * Purely internal class to the conditions manager implementation. + * Not at all to be accessed by clients! + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class IOVPool { + public: + typedef ConditionsPool* Entry; + typedef std::map<std::pair<int,int>, Entry > Entries; + Entries entries; + public: + /// Default constructor + IOVPool(); + /// Default destructor + virtual ~IOVPool(); + /// Retrieve a condition set given a Detector Element and the conditions name according to their validity + void __find(DetElement detector, + const std::string& condition_name, + const IOV& req_validity, + RangeConditions& result); + /// Retrieve a condition set given a Detector Element and the conditions name according to their validity + void __find_range(DetElement detector, + const std::string& condition_name, + const IOV& req_validity, + RangeConditions& result); + /// Select all ACTIVE conditions, which do no longer match the IOV requirement + void __select_expired(const IOV& required_validity, + RangeConditions& result); + void __update_expired(Interna::ConditionsManagerObject* caller, + ConditionsPool* pool, + RangeConditions& expired, + const IOV& required_validity); + }; + + } /* End namespace Conditions */ +} /* End namespace DD4hep */ + +#endif /* DDCOND_CONDITIONSINTERNA_H */ diff --git a/DDCond/include/DDCond/ConditionsManager.h b/DDCond/include/DDCond/ConditionsManager.h new file mode 100644 index 000000000..99ecf36bb --- /dev/null +++ b/DDCond/include/DDCond/ConditionsManager.h @@ -0,0 +1,168 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +#ifndef DDCOND_CONDITIONSMANAGER_H +#define DDCOND_CONDITIONSMANAGER_H + +// Framework include files +#include "DD4hep/Conditions.h" +#include "DD4hep/ComponentProperties.h" + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Conditions { + + // Forward declarations + class Entry; + class ConditionsDataLoader; + + /// Conditions internal namespace + namespace Interna { + class ConditionsManagerObject; + } + + /// Manager class for condition handles + /** + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class ConditionsManager : public Handle<Interna::ConditionsManagerObject> { + public: + + /// Standard object type + typedef Interna::ConditionsManagerObject Object; + typedef ConditionsDataLoader Loader; + typedef std::vector<IOVType*> IOVTypes; + typedef std::map<DetElement,Container> DetectorConditions; + typedef std::map<IOVType*,Container> TypeConditions; + + public: + + /// Static accessor if installed as an extension + /** + * Note: + * + * There may very well be several instances of a + * conditions manager. Do not think this is a sort of + * 'static constructor'. This woul dbe a big mistake!. + */ + template <typename T> static ConditionsManager from(T& host); + + /// Initializing constructor + ConditionsManager(LCDD& lcdd); + + /// Default constructor + ConditionsManager() : Handle<Object>() {} + + /// Constructor to be used with valid pointer to object + ConditionsManager(Object* p) : Handle<Object>(p) {} + + /// Constructor to assing handle of the same type + template <typename Q> ConditionsManager(const ConditionsManager& c) + : Handle<Object>(c) { + } + + /// Constructor to be used assigning from different type + template <typename Q> ConditionsManager(const Handle<Q>& e) + : Handle<Object>(e) { + } + + /// Default destructor + ~ConditionsManager(); + + /// Access to properties + Property& operator[](const std::string& property_name) const; + + /// Access to the property manager + PropertyManager& properties() const; + + /// Access the conditions loader + Handle<Loader> loader() const; + + /// Access the availible/known IOV types + const IOVTypes& iovTypes() const; + + /// Register new IOV type if it does not (yet) exist. + /** Returns (false,pointer) if IOV existed and + * (true,pointer) if new IOV was registered to the manager. + */ + std::pair<bool, const IOVType*> registerIOVType(size_t iov_type, const std::string& iov_name); + + /// Access IOV by its type + const IOVType* iovType (size_t iov_type) const; + + /// Access IOV by its name + const IOVType* iovType (const std::string& iov_name) const; + + /// Lock the internal data structures. This disables calls to "register", etc. + void lock(); + + /// Unlock the internal data structures. This enables calls to "register", etc. + void unlock(); + + /// Age conditions, which are no longer used and to be removed eventually + void age(); + + /// Clean conditions, which are above the age limit. + void clean(); + + /// Full cleanup of all managed conditions. + void clear(); + + /// Push all pending updates to the conditions store. + /** Note: + * This does not yet make the new conditions availible to the clients + */ + void pushUpdates(); + + /// Prepare all updates to the clients with the defined IOV + void prepare(const IOV& required_validity); + + /// Enable all updates to the clients with the defined IOV + void enable(const IOV& required_validity); + + /// Retrieve a condition given a Detector Element and the conditions name + Condition get(DetElement detector, + const std::string& condition_name, + const IOV& req_validity); + + /// Retrieve a condition given a Detector Element path and the conditions name + Condition get(const std::string& detector_path, + const std::string& condition_name, + const IOV& req_validity); + + /// Retrieve a condition given the conditions path = <Detector Element path>.<conditions name> + Condition get(const std::string& conditions_path, + const IOV& req_validity); + + /// Retrieve a condition given a Detector Element and the conditions name + RangeConditions getRange(DetElement detector, + const std::string& condition_name, + const IOV& req_range_validity); + + /// Retrieve a condition given a Detector Element path and the conditions name + RangeConditions getRange(const std::string& detector_path, + const std::string& condition_name, + const IOV& req_range_validity); + + /// Retrieve a condition given the conditions path = <Detector Element path>.<conditions name> + RangeConditions getRange(const std::string& conditions_path, + const IOV& req_range_validity); + }; + + } /* End namespace Geometry */ +} /* End namespace DD4hep */ +#endif /* DDCOND_CONDITIONSMANAGER_H */ diff --git a/DDCond/include/DDCond/ConditionsPool.h b/DDCond/include/DDCond/ConditionsPool.h new file mode 100644 index 000000000..e65a8cd82 --- /dev/null +++ b/DDCond/include/DDCond/ConditionsPool.h @@ -0,0 +1,155 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +#ifndef DDCOND_CONDITIONSPOOL_H +#define DDCOND_CONDITIONSPOOL_H + +// Framework include files +#include "DD4hep/Mutex.h" +#include "DD4hep/Conditions.h" +#include "DD4hep/NamedObject.h" +#include "DD4hep/objects/ConditionsInterna.h" + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Conditions { + + // Forward declarations + class Entry; + class ConditionsPool; + class ReplacementPool; + + /// Class implementing the conditions collection for a given IOV type + /** + * Implementation is mostly virtual, to allow to switch between + * different implementations, which allow for different lookup + * and store optimizations and/or various caches. + * The interface only represents the basic functionality required. + * + * For convenience, the class definition is here. + * See ConditionsManager.cpp for the implementation. + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class ConditionsPool : public NamedObject { + + public: + enum { AGE_NONE = 0, + AGE_ANY = 9999999, + AGE_EXPIRED = 12345678 + }; + + const IOVType* iovType; + IOV* iov; + /// Temporary buffer + ReplacementPool* updates; + int age_value; + + protected: + + /// Unconditionally create a new condition from the input data + /** + * Common function for all pools..... + * \author M.Frank + * \version 1.0 + */ + virtual Condition create(ConditionsPool* pool, const Entry* cond); + + /// Check if detector and name match + bool match(const DetElement::Object* det, int hash, const Condition::Object* c) const { + return det == c->detector.ptr() && hash == c->hash; + } + + public: + /// Default constructor + ConditionsPool(); + /// Default destructor. Note: pool must be cleared by the subclass! + virtual ~ConditionsPool(); + /// Register a new condition to this pool + virtual void insert(Condition cond) = 0; + /// Register a new condition to this pool. May overload for performance reasons. + virtual void insert(RangeConditions& cond) = 0; + /// Full cleanup of all managed conditions. + virtual void clear() = 0; + /// Check if a condition exists in the pool + virtual Condition exists(DetElement, const std::string&) const { + return Condition(); + } + /// Check if a condition exists in the pool + virtual Condition exists(Condition) const { + return Condition(); + } + /// Select the conditions matching the DetElement and the conditions name + virtual void select(DetElement det, const std::string& cond_name, RangeConditions& result) = 0; + /// Select all conditions contained + virtual void select_all(RangeConditions& result) = 0; + /// Select the conditons, used also by the DetElement of the condition + virtual void select_used(RangeConditions& result) = 0; + }; + + /// Interface for conditions pool optimized to host conditions updates. + /** + * Common function for all pools..... + * + * \author M.Frank + * \version 1.0 + */ + class UpdatePool : public ConditionsPool { + + public: + typedef std::vector<Condition> ConditionEntries; + /// Update container specification + typedef std::map<const IOV*, ConditionEntries> UpdateEntries; + + public: + /// Default constructor + UpdatePool(); + /// Default destructor. + virtual ~UpdatePool(); + /// Adopt all entries sorted by IOV. Entries will be removed from the pool + virtual void popEntries(UpdateEntries& entries) = 0; + /// Register a new condition to this pool + virtual void insert(Condition cond) = 0; + /// Register a new condition to this pool. May overload for performance reasons. + virtual void insert(RangeConditions& cond) = 0; + /// Register a new condition to this pool + virtual Condition insert(ConditionsPool* pool, Entry* cond) = 0; + /// Select the conditions matching the DetElement and the conditions name + virtual void select_range(DetElement det, + const std::string& cond_name, + const IOV& req_validity, + RangeConditions& result) = 0; + }; + + class ReplacementPool : public ConditionsPool { + public: + /// Default constructor + ReplacementPool(); + /// Default destructor. + virtual ~ReplacementPool(); + /// Register a new condition to this pool + virtual void insert(Condition cond) = 0; + /// Register a new condition to this pool. May overload for performance reasons. + virtual void insert(RangeConditions& cond) = 0; + /// Pop conditions. May overloade for performance reasons! + virtual void popEntries(RangeConditions& entries) = 0; + }; + + } /* End namespace Conditions */ +} /* End namespace DD4hep */ + +#endif /* DDCOND_CONDITIONSPOOL_H */ diff --git a/DDCond/include/DDCond/ConditionsStack.h b/DDCond/include/DDCond/ConditionsStack.h deleted file mode 100644 index 09722b7d8..000000000 --- a/DDCond/include/DDCond/ConditionsStack.h +++ /dev/null @@ -1,75 +0,0 @@ -// $Id: $ -//========================================================================== -// AIDA Detector description implementation for LCD -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see $DD4hepINSTALL/LICENSE. -// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. -// -// Author : M.Frank -// -//========================================================================== -#ifndef DD4HEP_CONDITIONS_CONDITIONSSTACK_H -#define DD4HEP_CONDITIONS_CONDITIONSSTACK_H - -// Framework include files -#include "DD4hep/Detector.h" -#include "DD4hep/Memory.h" - -/// Namespace for the AIDA detector description toolkit -namespace DD4hep { - - /// Namespace for the geometry part of the AIDA detector description toolkit - namespace Geometry { - - namespace ConditionsInterna { - // Forward declarations - class Entry; - } - - /// Implementation of a stack of conditions assembled before application - /** - * \author M.Frank - * \version 1.0 - * \ingroup DD4HEP_CONDITIONS - */ - class ConditionsStack { - public: - typedef ConditionsInterna::Entry Entry; - typedef std::map<std::string,Entry*> Stack; - - protected: - /// The subdetector specific map of conditions caches - Stack m_stack; - - /// Standard constructor - ConditionsStack(); - - public: - /// Standard destructor - virtual ~ConditionsStack(); - - /// Static client accessor - static ConditionsStack& get(); - /// Create an conditions stack instance. The creation of a second instance will be refused. - static void create(); - /// Check existence of conditions stack - static bool exists(); - /// Push new entry into the stack - void insert(dd4hep_ptr<Entry>& data); - /// Clear data content and remove the slignment stack - void release(); - /// Access size of the conditions stack - size_t size() const { return m_stack.size(); } - /// Retrieve an conditions entry of the current stack - dd4hep_ptr<Entry> pop(); - /// Get all path entries to be aligned. Note: transient! - std::vector<const Entry*> entries() const; - }; - - } /* End namespace Geometry */ -} /* End namespace DD4hep */ - -#endif /* DD4HEP_CONDITIONS_CONDITIONSSTACK_H */ diff --git a/DDCond/include/DDCond/ConditionsTransaction.h b/DDCond/include/DDCond/ConditionsTransaction.h deleted file mode 100644 index 9cb211859..000000000 --- a/DDCond/include/DDCond/ConditionsTransaction.h +++ /dev/null @@ -1,57 +0,0 @@ -// $Id: $ -//========================================================================== -// AIDA Detector description implementation for LCD -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see $DD4hepINSTALL/LICENSE. -// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. -// -// Author : M.Frank -// -//========================================================================== -#ifndef DD4HEP_CONDITIONS_CONDITIONSTRANSACTION_H -#define DD4HEP_CONDITIONS_CONDITIONSTRANSACTION_H - -// Framework include files -#include "DD4hep/Primitives.h" - -/// Namespace for the AIDA detector description toolkit -namespace DD4hep { - - namespace XML { class Handle_t; } - - /// Namespace for the geometry part of the AIDA detector description toolkit - namespace Geometry { - - // Forward declarations - class LCDD; - class ConditionsHandler; - - /// Manage conditions transaction to the handler for a given LCDD instance - /** - * \date 01/04/2014 - * \author M.Frank - * \version 1.0 - * \ingroup DD4HEP_CONDITIONS - */ - class ConditionsTransaction { - public: - - /// Internal flag to remember transaction contexts - bool flag; - /// Reference to the current LCDD instance - LCDD& lcdd; - /// Reference to the conditions handler - ConditionsHandler* m_handler; - - /// Default constructor - ConditionsTransaction(LCDD& l, const XML::Handle_t& e); - /// Default destructor - ~ConditionsTransaction(); - }; - - } /* End namespace Geometry */ -} /* End namespace DD4hep */ -#endif /* DD4HEP_CONDITIONS_CONDITIONSTRANSACTION_H */ diff --git a/DDCond/src/ConditionTest.cpp b/DDCond/src/ConditionTest.cpp deleted file mode 100644 index a9bf27c5c..000000000 --- a/DDCond/src/ConditionTest.cpp +++ /dev/null @@ -1,121 +0,0 @@ -// $Id: $ -//========================================================================== -// AIDA Detector description implementation for LCD -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see $DD4hepINSTALL/LICENSE. -// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. -// -// Author : M.Frank -// -//========================================================================== - -// Framework include files -#include "DD4hep/LCDD.h" -#include "DD4hep/Printout.h" -#include "DD4hep/Conditions.h" -#include "DD4hep/DetFactoryHelper.h" - -using namespace std; -using namespace DD4hep; -using namespace DD4hep::Geometry; - -namespace { - - /// Dump the conditions of one detectpr element - void dump_element(DetElement elt) { - string test = "ConditionsTest1"; - Conditions conds = elt.conditions(); - printout(INFO,test,"DetElement:%s # of conditons:%d",elt.path().c_str(),int(conds.count())); - const Conditions::Entries& entries = conds.entries(); - for(Conditions::Entries::const_iterator i=entries.begin(); i!=entries.end(); ++i) { - Condition c((*i).second); - string type = c.type(); - printout(INFO,test," %s Condition[%s]: %s [%s] Validity:%s", - c.detector().path().c_str(), type.c_str(), c.name().c_str(), - c.value().c_str(), c.validity().c_str()); - - if ( type == "alignment" ) { - c.bind<string>(); - } - else if ( type == "temperature" ) { - c.bind<double>(); - printout(INFO,test," %s : double value:%g ", - c.name().c_str(), c.get<double>()); - } - else if ( type == "pressure" ) { - c.bind<double>(); - printout(INFO,test," %s : double value:%g [%g hPa]", - c.name().c_str(), c.get<double>(), - _multiply(c.get<double>(),"1.0/hPa")); - } - else if ( type == "whatever" ) { - c.bind<vector<double> >(); - const vector<double>& v = c.get<vector<double> >(); - printout(INFO,test," %s : vector<double> size:%d = %s", - c.name().c_str(), int(v.size()), c.block().str().c_str()); - } - printout(INFO,test, " Type: %s",typeName(c.typeInfo()).c_str()); - } - } - - /// Dump conditions tree of a detector element - void dump_conditions(DetElement elt) { - Conditions conds = elt.conditions(); - const DetElement::Children& children = elt.children(); - if ( !conds.isValid() ) - printout(INFO,"ConditionsTest1","DetElement:%s NO CONDITIONS present",elt.path().c_str()); - else - dump_element(elt); - for(DetElement::Children::const_iterator j=children.begin(); j!=children.end(); ++j) - dump_conditions((*j).second); - } - - /// Test execution function - long conditions_test(LCDD& lcdd, int argc, char** argv) { - DetElement det = lcdd.world(); - string args = ""; - for(int i=0; i<argc; ++i) { args += argv[i], args += " "; }; - printout(INFO,"ConditionsTest1","Args: %s",args.c_str()); - dump_conditions(det); - return 1; - } -} - -DECLARE_APPLY(ConditionsTest1,conditions_test) - - -namespace { - - struct Callee { - int m_param; - Callee() : m_param(0) {} - void call(unsigned long tags, DetElement& det, void* param) { - if ( DetElement::CONDITIONS_CHANGED == (tags&DetElement::CONDITIONS_CHANGED) ) - printout(INFO,"Callee","+++ Conditions update %s param:%p",det.path().c_str(),param); - if ( DetElement::PLACEMENT_CHANGED == (tags&DetElement::PLACEMENT_CHANGED) ) - printout(INFO,"Callee","+++ Alignment update %s param:%p",det.path().c_str(),param); - } - }; - - /// Callback conditions tree of a detector element - void callback_install(DetElement elt, Callee* c) { - Position local, global; - const DetElement::Children& children = elt.children(); - elt.localToWorld(local, global); - elt.callAtUpdate(DetElement::CONDITIONS_CHANGED|DetElement::PLACEMENT_CHANGED,c,&Callee::call); - for(DetElement::Children::const_iterator j=children.begin(); j!=children.end(); ++j) - callback_install((*j).second,c); - } - - /// Test execution function - long callback_test(LCDD& lcdd, int /* argc */, char** /* argv */) { - DetElement det = lcdd.world(); - callback_install(det, new Callee()); - return 1; - } -} - -DECLARE_APPLY(CallbackInstallTest,callback_test) diff --git a/DDCond/src/ConditionsDataLoader.cpp b/DDCond/src/ConditionsDataLoader.cpp new file mode 100644 index 000000000..a01293b16 --- /dev/null +++ b/DDCond/src/ConditionsDataLoader.cpp @@ -0,0 +1,50 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include "DD4hep/Handle.inl" +#include "DD4hep/Printout.h" +#include "DDCond/ConditionsInterna.h" +#include "DDCond/ConditionsDataLoader.h" + +using std::string; +using namespace DD4hep::Conditions; + +DD4HEP_INSTANTIATE_HANDLE_NAMED(ConditionsDataLoader); + +/// Default constructor +ConditionsDataLoader::ConditionsDataLoader(LCDD& lcdd, ConditionsManager mgr, const string nam) + : NamedObject(nam,"ConditionsDataLoader"), m_lcdd(lcdd), m_mgr(mgr) { + if ( m_mgr.isValid() ) return; + except("ConditionsDataLoader","+++ Cannot create without a valid conditions manager handle!"); +} + +/// Default destructor +ConditionsDataLoader::~ConditionsDataLoader() { +} + +/// Add data source definition to loader +void ConditionsDataLoader::addSource(const string& source) { + m_sources.push_back(source); +} + +/// Queue update to manager. +Condition ConditionsDataLoader::queueUpdate(Entry* data) { + return m_mgr->__queue_update(data); +} + +/// Push update to manager. +void ConditionsDataLoader::pushUpdates() { + m_mgr->pushUpdates(); +} diff --git a/DDCond/src/ConditionsEntry.cpp b/DDCond/src/ConditionsEntry.cpp new file mode 100644 index 000000000..ca90bdc2e --- /dev/null +++ b/DDCond/src/ConditionsEntry.cpp @@ -0,0 +1,50 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include "DD4hep/InstanceCount.h" +#include "DDCond/ConditionsEntry.h" + +using std::string; +using namespace DD4hep::Conditions; + +/// Initializing constructor +Entry::Entry(const DD4hep::Geometry::DetElement& det, const string& nam, const string& typ, const string& valid, int h) + : NamedObject(nam,typ), detector(det), value(), validity(valid), hash(h) +{ + InstanceCount::increment(this); +} + +/// Copy constructor +Entry::Entry(const Entry& c) + : NamedObject(c), detector(c.detector), value(c.value), validity(c.validity) +{ + InstanceCount::increment(this); +} + +/// Default destructor +Entry::~Entry() { + InstanceCount::decrement(this); +} + +/// Assignment operator +Entry& Entry::operator=(const Entry& c) { + if ( this != &c ) { + this->NamedObject::operator=(c); + detector = c.detector; + value = c.value; + validity = c.validity; + } + return *this; +} diff --git a/DDCond/src/ConditionsExample.cpp b/DDCond/src/ConditionsExample.cpp new file mode 100644 index 000000000..b9cab82ca --- /dev/null +++ b/DDCond/src/ConditionsExample.cpp @@ -0,0 +1,164 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include "ConditionsTest.h" + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::Conditions; +using Geometry::LCDD; +using Geometry::Position; +using Geometry::DetElement; + +namespace { + + + void print_tpc_discrete_conditions(Test::TestEnv& env, int epoch_min, int epoch_max, int run_min, int run_max) { + IOV iov_epoch(env.epoch), iov_run(env.run); + iov_epoch.keyData.first = epoch_min; + iov_epoch.keyData.second = epoch_max; + iov_run.keyData.first = run_min; + iov_run.keyData.second = run_max; + + env.manager.prepare(iov_run); + env.manager.enable(iov_run); + env.manager.prepare(iov_epoch); + env.manager.enable(iov_epoch); + + Condition cond = env.manager.get(env.detector,"AmbientTemperature",iov_epoch); + Test::print_condition<void>(cond); + cond = env.detector.condition("AmbientTemperature",iov_epoch); + Test::check_discrete_condition(cond, iov_epoch); + Test::print_condition<void>(cond); + cond = env.detector.condition("ExternalPressure",iov_epoch); + Test::check_discrete_condition(cond, iov_epoch); + Test::print_condition<void>(cond); + cond = env.detector.condition("SomeMultiParams",iov_epoch); + Test::check_discrete_condition(cond, iov_epoch); + Test::print_condition<void>(cond); + printout(INFO,"Example","SUCCESS: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + printout(INFO,"Example","SUCCESS: +++ Conditions access OK for iov:%s!",iov_epoch.str().c_str()); + printout(INFO,"Example","SUCCESS: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + + cond = env.detector.condition("alignment",iov_run); + Test::check_discrete_condition(cond, iov_run); + Test::print_condition<void>(cond); + cond = env.detector.condition("TPC_A_align",iov_run); + Test::check_discrete_condition(cond, iov_run); + Test::print_condition<void>(cond); + cond = env.daughter("TPC_SideA").condition("alignment",iov_run); + Test::check_discrete_condition(cond, iov_run); + Test::print_condition<void>(cond); + printout(INFO,"Example","SUCCESS: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + printout(INFO,"Example","SUCCESS: +++ DISCRETE Conditions access OK for iov:%s!",iov_run.str().c_str()); + printout(INFO,"Example","SUCCESS: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + } + + void print_tpc_discrete_conditions(Test::TestEnv& env) { + print_tpc_discrete_conditions(env, 1396887257, 1396887257, 563543, 563543); + print_tpc_discrete_conditions(env, 1396887257, 1396887257, 234567, 234567); + print_tpc_discrete_conditions(env, 1396887257, 1396887257, 563543, 563543); + } + + void print_tpc_range_conditions(Test::TestEnv& env, int run_min, int run_max) { + RangeConditions cond; + IOV iov_run(env.run); + iov_run.keyData.first = run_min; + iov_run.keyData.second = run_max; + try { + cond = env.manager.getRange(env.detector,"TPC_A_align",iov_run); + Test::print_conditions<void>(cond); + printout(INFO,"Example","SUCCESS: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + printout(INFO,"Example","SUCCESS: +++ RANGE Conditions access OK for iov:%s!",iov_run.str().c_str()); + printout(INFO,"Example","SUCCESS: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + } + catch(const std::exception& e) { + printout(INFO,"Example","FAILED: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + printout(INFO,"Example","FAILED: +++ RANGE Conditions access FAILED for iov:%s!",iov_run.str().c_str()); + printout(INFO,"Example","FAILED: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + } + } + + int example1(LCDD& lcdd, int, char** ) { + printout(INFO,"Example1","+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + printout(INFO,"Example1","+++ Executing Conditions example No. 1: Test conditions access"); + printout(INFO,"Example1","+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + Test::TestEnv env(lcdd, "TPC"); + + env.add_xml_data_source("/examples/Conditions/xml/TPC.xml"); + env.add_xml_data_source("/examples/Conditions/xml/TPC_run_563543.xml"); + env.add_xml_data_source("/examples/Conditions/xml/TPC_run_234567.xml"); + print_tpc_discrete_conditions(env); + env.dump_conditions_pools(); + + print_tpc_range_conditions(env,234567,563543); // Should fail ! + print_tpc_range_conditions(env,123456,563543); // Should fail ! + + env.add_xml_data_source("/examples/Conditions/xml/TPC_run_filler.xml"); + env.add_xml_data_source("/examples/Conditions/xml/TPC_run_123456.xml"); + print_tpc_range_conditions(env,123456,900000); // Now it should succeed + return 1; + } + + int example2(LCDD& lcdd, int argc, char** argv) { + printout(INFO,"Example2","+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + printout(INFO,"Example2","+++ Executing Conditions example No. 2: Dump conditions tree"); + printout(INFO,"Example2","+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + DetElement det = lcdd.world(); + string args = ""; + for(int i=0; i<argc; ++i) { args += argv[i], args += " "; }; + printout(INFO,"Example2","Args: %s",args.c_str()); + Test::TestEnv::dump_conditions_tree(det); + return 1; + } + + struct Callee { + int m_param; + Callee() : m_param(0) {} + void call(unsigned long tags, DetElement& det, void* param) { + if ( (tags&DetElement::CONDITIONS_CHANGED) ) + printout(INFO,"Callee","+++ Conditions update %s param:%p",det.path().c_str(),param); + if ( (tags&DetElement::PLACEMENT_CHANGED) ) + printout(INFO,"Callee","+++ Alignment update %s param:%p",det.path().c_str(),param); + } + }; + + /// Callback conditions tree of a detector element + void callback_install(DetElement elt, Callee* c) { + Position local, global; + const DetElement::Children& children = elt.children(); + elt.localToWorld(local, global); + elt.callAtUpdate(DetElement::CONDITIONS_CHANGED|DetElement::PLACEMENT_CHANGED,c,&Callee::call); + for(DetElement::Children::const_iterator j=children.begin(); j!=children.end(); ++j) + callback_install((*j).second,c); + } + + int DD4hep_CallbackInstallTest(LCDD& lcdd, int argc, char** argv) { + printout(INFO,"Example3","+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + printout(INFO,"Example3","+++ Executing DD4hepCallbackInstallTest: Install user callbacks"); + printout(INFO,"Example3","+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + string args = ""; + for(int i=0; i<argc; ++i) { args += argv[i], args += " "; }; + printout(INFO,"Example3","Args: %s",args.c_str()); + DetElement det = lcdd.world(); + callback_install(det, new Callee()); + return 1; + } +} + + +DECLARE_APPLY(DD4hepConditionsAccessTest,example1) +DECLARE_APPLY(DD4hepConditionsTreeDump,example2) +DECLARE_APPLY(DD4hepCallbackInstallTest,DD4hep_CallbackInstallTest) diff --git a/DDCond/src/ConditionsHandler.cpp b/DDCond/src/ConditionsHandler.cpp deleted file mode 100644 index cb0b2acaf..000000000 --- a/DDCond/src/ConditionsHandler.cpp +++ /dev/null @@ -1,121 +0,0 @@ -// $Id: $ -//========================================================================== -// AIDA Detector description implementation for LCD -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see $DD4hepINSTALL/LICENSE. -// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. -// -// Author : M.Frank -// -//========================================================================== - -// Framework include files -#include "DD4hep/LCDD.h" -#include "DD4hep/Printout.h" -#include "DD4hep/DetectorTools.h" -#include "DDCond/ConditionsHandler.h" -#include "DDCond/ConditionsOperators.h" -#include "DD4hep/objects/DetectorInterna.h" -#include "DD4hep/objects/ConditionsInterna.h" - -using namespace std; -using namespace DD4hep; -using namespace DD4hep::Geometry; -typedef ConditionsStack::Entry Entry; - -/// Default constructor -ConditionsHandler::ConditionsHandler(LCDD& lcdd) - : m_lcdd(lcdd), m_refCount(1) -{ -} - -/// Default destructor -ConditionsHandler::~ConditionsHandler() { - printout(INFO,"ConditionsHandler","+++ Destroy cache"); -} - -/// Add reference count -int ConditionsHandler::addRef() { - return ++m_refCount; -} - -/// Release object. If reference count goes to NULL, automatic deletion is triggered. -int ConditionsHandler::release() { - int value = --m_refCount; - if ( value == 0 ) { - delete this; - } - return value; -} - -/// Open a new transaction stack (Note: only one stack allowed!) -void ConditionsHandler::openTransaction() { - /// Check if transaction already present. If not, open, else issue an error - if ( !ConditionsStack::exists() ) { - ConditionsStack::create(); - return; - } - string msg = "Request to open a second conditions transaction stack -- not allowed!"; - string err = format("Conditions<conditions>",msg); - printout(FATAL,"ConditionsHandler",msg); - throw runtime_error(err); -} - -/// Close existing transaction stack and apply all conditions -void ConditionsHandler::closeTransaction() { - /// Check if transaction is open. If yes, close it and apply conditions stack. - /// If no transaction is active, ignore the staement, but issue a warning. - if ( ConditionsStack::exists() ) { - ConditionsStack& stack = ConditionsStack::get(); - printout(DEBUG,"ConditionsHandler","+++ Closing conditions transaction...."); - apply(stack); - stack.release(); - printout(INFO,"ConditionsHandler","Conditions were applied...."); - return; - } - printout(WARNING,"Conditions<conditions>", - "Request to close a non-existing conditons transaction."); -} - -/// Create and install a new instance tree -void ConditionsHandler::install(LCDD& lcdd) { - ConditionsHandler* cache = lcdd.extension<ConditionsHandler>(false); - if ( !cache ) { - lcdd.addExtension<ConditionsHandler>(new ConditionsHandler(lcdd)); - } -} - -/// Unregister and delete a tree instance -void ConditionsHandler::uninstall(LCDD& lcdd) { - if ( lcdd.extension<ConditionsHandler>(false) ) { - lcdd.removeExtension<ConditionsHandler>(true); - } -} - -void ConditionsHandler::triggerUpdate(DetElement det) { - printout(DEBUG,"ConditionsHandler","+++ Trigger conditions update for %s",det.path().c_str()); - det._data().update(DetElement::CONDITIONS_CHANGED,(void*)0x1); -} - -/// Apply a complete stack of ordered conditionss to the geometry structure -void ConditionsHandler::apply(ConditionsStack& stack) { - typedef set<DetElement> Updates; - Updates updates; - - printout(DEBUG,"ConditionsHandler","+++ Apply conditions ...."); - while(stack.size() > 0) { - Entry* data = stack.pop().release(); - DetElement det = data->detector; - /// Do something! - printout(DEBUG,"ConditionsHandler","+++ %s name:%s type:%s value:%s Validity:%s", - det.path().c_str(), data->name.c_str(), data->type.c_str(), - data->value.c_str(), data->validity.c_str()); - det.conditions().set(data); - updates.insert(det); - } - // Now trigger update callbacks for all detector elements with changed conditions: - for_each(updates.begin(), updates.end(), triggerUpdate); -} diff --git a/DDCond/src/ConditionsInterna.cpp b/DDCond/src/ConditionsInterna.cpp new file mode 100644 index 000000000..f7c3be8af --- /dev/null +++ b/DDCond/src/ConditionsInterna.cpp @@ -0,0 +1,679 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include "DD4hep/LCDD.h" +#include "DD4hep/Errors.h" +#include "DD4hep/Memory.h" +#include "DD4hep/Plugins.h" +#include "DD4hep/Printout.h" +#include "DD4hep/World.h" +#include "DD4hep/Handle.inl" +#include "DD4hep/DetectorTools.h" +#include "DD4hep/InstanceCount.h" +#include "DD4hep/PluginCreators.h" +#include "DD4hep/DetFactoryHelper.h" +#include "DD4hep/objects/DetectorInterna.h" +#include "DD4hep/objects/ConditionsInterna.h" + +#include "DDCond/ConditionsPool.h" +#include "DDCond/ConditionsEntry.h" +#include "DDCond/ConditionsManager.h" +#include "DDCond/ConditionsDataLoader.h" +#include "DDCond/ConditionsInterna.h" + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::Conditions; +using namespace DD4hep::Conditions::Interna; + +typedef UpdatePool::UpdateEntries Updates; + +DD4HEP_INSTANTIATE_HANDLE_NAMED(Interna::ConditionsManagerObject); + +#define NO_AGE 0 + +namespace { + int s_debug = INFO; + + int install_cond_mgr (Geometry::LCDD& lcdd, int /* argc */, char** /* argv */) { + typedef Interna::ConditionsManagerObject ConditionsManagerObject; + Handle<ConditionsManagerObject> mgr(lcdd.extension<ConditionsManagerObject>(false)); + if ( !mgr.isValid() ) { + ConditionsManager mgr_handle(lcdd); + lcdd.addExtension<ConditionsManagerObject>(mgr_handle.ptr()); + printout(INFO,"ConditionsManager","+++ Successfully installed conditions manager instance."); + } + return 1; + } +} +DECLARE_APPLY(DD4hepConditionsManagerInstaller,install_cond_mgr) + +namespace { + + template <typename T> const IOVType* check_iov_type(const ConditionsManagerObject* o, const IOV* iov); + + template <> const IOVType* check_iov_type<void>(const ConditionsManagerObject* o, const IOV* iov) { + if ( iov ) { + const IOVType* typ = iov->iovType ? iov->iovType : o->iovType(iov->type); + if ( typ ) { + if ( iov->type == typ->type ) { + if ( typ->type < o->m_pool.size() ) { + if ( o->m_pool[typ->type] != 0 ) { + return typ; + } + } + } + } + } + return 0; + } + + struct Range {}; + struct Discrete {}; + + template <> const IOVType* check_iov_type<Discrete>(const ConditionsManagerObject* o, const IOV* iov) { + const IOVType* typ = check_iov_type<void>(o,iov); + if ( typ && !iov->has_range() ) return typ; + return 0; + } + template <> const IOVType* check_iov_type<Range>(const ConditionsManagerObject* o, const IOV* iov) { + const IOVType* typ = check_iov_type<void>(o,iov); + if ( typ && iov->has_range() ) return typ; + return 0; + } + template <typename T> void __check_values__(const ConditionsManagerObject* o, + Geometry::DetElement det, + const std::string& cond, + const IOV* iov) + { + if ( !iov ) { + except("ConditionsManager","+++ Invalid IOV to access condition: %s.%s. [Null-reference]", + det.path().c_str(), cond.c_str()); + } + const IOVType* typ = check_iov_type<T>(o,iov); + if ( !typ ) { + // Severe: We have an unknown IOV type. This is not allowed, + // because we do not known hot to handle it..... + except("ConditionsManager","+++ Invalid IOV type [%d] to access condition: %s.%s.", + iov->type, det.path().c_str(), cond.c_str()); + } + if ( !det.isValid() ) { + except("ConditionsManager","+++ Attempt to use the conditions manager %s for " + "an unknown detector element [Invalid Handle].", cond.c_str()); + } + } + + + bool is_range_complete(const IOV& iov, const RangeConditions& conditions) { + if ( !conditions.empty() ) { + // We need to check if the entire range is covered. + // For every key.second we must find a key.first, which is at least as big + IOV::Key test=iov.keyData; + /// The range may be returned unordered. Hence, + /// we have to try to match at most conditions.size() times until we really know + for(size_t j = 0; j < conditions.size(); ++j ) { + for(RangeConditions::const_iterator i=conditions.begin(); i!=conditions.end(); ++i) { + const IOV::Key& k = (*i)->iov->key(); + if ( k.first <= test.first+1 && k.second >= test.first ) test.first = k.second; + if ( k.first+1 <= test.second && k.second >= test.second ) test.second = k.first; + //printout(INFO,"Test","IOV: %d,%d --> %d,%d",k.first,k.second, test.first, test.second); + if ( test.first >= test.second ) return true; + } + if ( test.first <= iov.keyData.first && test.second >= iov.keyData.second ) return false; + } + } + return false; + } + + void __print(const char* prefix, Condition c) { + if ( s_debug > INFO ) { + printout(INFO,"ConditionsManager","+++ %s %s.%s [%s] = %s", + prefix, c->detector.path().c_str(), c.name().c_str(), + c->iov->str().c_str(), c->value.c_str()); + } + } + /// Helper class to be injected into the world object to allow loading from DetElements directly..... + struct lcdd_cond_loader : public ConditionsLoader { + ConditionsManager m_manager; + lcdd_cond_loader(ConditionsManager m) : m_manager(m) {} + virtual ~lcdd_cond_loader() {} + /// Access the conditions loading + virtual Condition get(Geometry::DetElement element, const std::string& key, const IOV& iov) { + return m_manager->get(element, key, iov); + } + }; + + +} + +/// Default constructor +IOVPool::IOVPool() { +} + +/// Default destructor +IOVPool::~IOVPool() { +} + +static inline bool key_contains_range(const IOV::Key& key, const IOV::Key& test) { + return key.first <= test.first && key.second >= test.second; +} + +void IOVPool::__find(DetElement detector, + const std::string& condition_name, + const IOV& req_validity, + RangeConditions& result) +{ + for(Entries::const_iterator i=entries.begin(); i!=entries.end(); ++i) { + if ( key_contains_range((*i).first, req_validity.key()) ) { + (*i).second->select(detector, condition_name, result); + } + } +} + +void IOVPool::__find_range(DetElement detector, + const std::string& condition_name, + const IOV& req_validity, + RangeConditions& result) +{ + const IOV::Key& range = req_validity.key(); + for(Entries::const_iterator i=entries.begin(); i!=entries.end(); ++i) { + const IOV::Key& key = (*i).first; + if ( IOV::key_is_contained(key,range) ) + // IOV test contained in key. Take it! + (*i).second->select(detector, condition_name, result); + else if ( IOV::key_overlaps_lower_end(key,range) ) + // IOV overlap on test on the lower end of key + (*i).second->select(detector, condition_name, result); + else if ( IOV::key_overlaps_higher_end(key,range) ) + // IOV overlap of test on the higher end of key + (*i).second->select(detector, condition_name, result); + } +} + +/// Select all ACTIVE conditions, which do no longer match the IOV requirement +void IOVPool::__select_expired(const IOV& required_validity, RangeConditions& result) { + for(Entries::const_iterator i=entries.begin(); i!=entries.end(); ++i) { + ConditionsPool* pool = (*i).second; + if ( !key_contains_range((*i).first, required_validity.key()) ) { + if ( pool->age_value == ConditionsPool::AGE_NONE ) { + // Now check the content: + pool->select_used(result); + } + ++pool->age_value; + continue; + } + pool->age_value = 0; + } +} + +/// Select all ACTIVE conditions, which do no longer match the IOV requirement +void IOVPool::__update_expired(Interna::ConditionsManagerObject* caller, + ConditionsPool* new_pool, + RangeConditions& updates, + const IOV& required_validity) { + RangeConditions upda; + for(RangeConditions::const_iterator i=updates.begin(); i!=updates.end(); ++i) { + Condition::Object* condition = (*i).ptr(); + + Condition c = new_pool->exists(condition); + if ( c.isValid() ) { + upda.push_back(c); + continue; + } + size_t items = caller->m_loader->load(condition->detector,condition->name,required_validity,upda); + if ( items < 1 ) { + // Error: no such condition + except("ConditionsManager","+++ update_expired: Cannot update condition %s.%s [%s] to iov:%s.", + condition->detector.path().c_str(), condition->name.c_str(), + condition->iov->str().c_str(), required_validity.str().c_str()); + } + } + updates = upda; +} + +/// Standard constructor +ConditionsManagerObject::ConditionsManagerObject(LCDD& lcdd) + : NamedObject(), m_lcdd(lcdd), m_iovTypes(), m_pool(), + m_updateLock(), m_poolLock(), m_loader(), + m_updatePool(), + locked(0) +{ + InstanceCount::increment(this); + declareProperty("MaxIOVTypes", m_maxIOVTypes=32); + declareProperty("PoolType", m_poolType = ""); + declareProperty("UpdatePoolType", m_updateType = "DD4hep_ConditionsLinearUpdatePool"); + declareProperty("ReplacementPoolType", m_replType = "DD4hep_ConditionsLinearReplacementPool"); + declareProperty("LoaderType", m_loaderType = "multi"); + m_iovTypes.resize(m_maxIOVTypes,IOVType()); + m_pool.resize(m_maxIOVTypes,0); +} + +/// Default destructor +ConditionsManagerObject::~ConditionsManagerObject() { + for_each(m_pool.begin(), m_pool.end(), DestroyObject<IOVPool*>()); + InstanceCount::decrement(this); +} + +void ConditionsManagerObject::initialize() { + if ( !m_updatePool.get() ) { + string typ = "DD4hep_Conditions_"+m_loaderType+"_Loader"; + char* argv[] = {(char*)"ConditionsDataLoader", (char*)this, 0}; + m_loader.adopt(createPlugin<ConditionsDataLoader>(typ,m_lcdd,2,argv)); + + m_updatePool.adopt(createPlugin<UpdatePool>(m_updateType,m_lcdd)); + if ( !m_updatePool.get() ) { + except("ConditionsManager","+++ The update pool of type %s cannot be created. [%s]", + m_updateType.c_str(),Errors::noSys().c_str()); + } + Ref_t ref(m_updatePool.get()); + ref->SetName("updates"); + ref->SetTitle("updates"); + Geometry::World world(m_lcdd.world()); + world->conditionsLoader = new lcdd_cond_loader(ConditionsManager(this)); + } +} + +/// Register new IOV type if it does not (yet) exist. +pair<bool, const IOVType*> ConditionsManagerObject::registerIOVType(size_t iov_type, const string& iov_name) { + if ( iov_type<m_iovTypes.size() ) { + IOVType& t = m_iovTypes[iov_type]; + bool eq_type = t.type == iov_type; + bool eq_name = t.name == iov_name; + if ( eq_type && eq_name ) { + return make_pair(false,&t); + } + else if ( t.type != 0 && eq_type && !eq_name ) { + except("ConditionsManager","Cannot register IOV %s. Type %d already in use!", + iov_name.c_str(), iov_type); + } + t.name = iov_name; + t.type = iov_type; + m_pool[t.type] = new IOVPool(); + return make_pair(true,&t); + } + except("ConditionsManager","Cannot register IOV section %d of type %d. Value out of bounds: [%d,%d]", + iov_name.c_str(), iov_type, 0, int(m_iovTypes.size())); + return make_pair(false,(IOVType*)0); +} + +/// Access IOV by its type +const IOVType* ConditionsManagerObject::iovType (size_t iov_type) const { + if ( iov_type<m_iovTypes.size() ) { + const IOVType& t = m_iovTypes[iov_type]; + if ( t.type == iov_type ) return &t; + } + except("ConditionsManager","Request to access an unregistered IOV type: %d.", iov_type); + return 0; +} + +/// Access IOV by its name +const IOVType* ConditionsManagerObject::iovType (const string& iov_name) const { + for( IOVTypes::const_iterator i=m_iovTypes.begin(); i != m_iovTypes.end(); ++i) + if ( (*i).name == iov_name ) return &(*i); + except("ConditionsManager","Request to access an unregistered IOV type: %s.", iov_name.c_str()); + return 0; +} + +/// Register IOV using new string data +ConditionsPool* ConditionsManagerObject::registerIOV(const string& data) { + size_t id1 = data.find(','); + size_t id2 = data.find('#'); + if ( id2 == string::npos ) { + except("ConditionsManager","+++ Unknown IOV string representation: %s",data.c_str()); + } + string iov_name = data.substr(id2+1); + IOV::Key key; + int nents = 0; + if ( id1 != string::npos ) + nents = ::sscanf(data.c_str(),"%d,%d#",&key.first,&key.second) == 2 ? 2 : 0; + else { + nents = ::sscanf(data.c_str(),"%d#",&key.first) == 1 ? 1 : 0; + key.second = key.first; + } + if ( nents == 0 ) { + except("ConditionsManager", + "+++ Failed to read keys from IOV string representation: %s",data.c_str()); + } + + // Check if this IOV type is known + const IOVType* typ = iovType(iov_name); + if ( !typ ) { + // Severe: We have an unknown IOV type. This is not allowed, + // because we do not known hot to handle it..... + except("ConditionsManager","+++ Unknown IOV type requested from data: %s. [%s]", + data.c_str(),Errors::invalidArg().c_str()); + } + // IOV read and checked. Now register it. + return registerIOV(*typ, key); +} + +/// Register IOV with type and key +ConditionsPool* ConditionsManagerObject::registerIOV(const IOVType& typ, IOV::Key key) { + + // IOV read and checked. Now register it, but always locked! + IOVPool* pool = m_pool[typ.type]; + dd4hep_lock_t lock(m_poolLock); + if ( !pool ) { + m_pool[typ.type] = pool = new IOVPool(); + } + IOVPool::Entries::const_iterator i = pool->entries.find(key); + if ( i != pool->entries.end() ) { + return (*i).second; + } + ConditionsPool* cond_pool = createPlugin<ConditionsPool>(m_poolType,m_lcdd); + IOV* iov = new IOV(&typ); + iov->type = typ.type; + iov->keyData = key; + cond_pool->iov = iov; + pool->entries.insert(make_pair(key,cond_pool)); + return cond_pool; +} + +/// Set a single conditions value to be managed. +/// Requires external lock on update pool! +Condition ConditionsManagerObject::__queue_update(Entry* e) { + if ( e ) { + ConditionsPool* p = registerIOV(e->validity); + Condition c = m_updatePool->insert(p, e); + if ( s_debug > INFO ) { + printout(INFO,"Conditions","+++ Loaded condition: %s.%s to %s [%s] V: %s", + c.detector().path().c_str(), c.name().c_str(), c->value.c_str(), + c->type.c_str(),c->validity.c_str()); + } + return c; + } + return Condition(); +} + +/// Age conditions, which are no longer used and to be removed eventually +void ConditionsManagerObject::age() { + //call_member_func(m_pool, &ConditionsPool::age); +} + +/// Clean conditions, which are above the age limit. +void ConditionsManagerObject::clean() { + //call_member_func(m_pool, &ConditionsPool::clean); +} + +/// Full cleanup of all managed conditions. +void ConditionsManagerObject::clear() { + //call_member_func(m_pool, &ConditionsPool::clear); +} + +/// Push all pending updates to the conditions store +void ConditionsManagerObject::pushUpdates() { + Updates entries; { + dd4hep_lock_t lock(m_updateLock); + m_updatePool->popEntries(entries); + } + // Lock global pool so that no other updates happen in the meanwhile + // which could kill the pool's containers + dd4hep_lock_t lock(m_poolLock); + for(Updates::const_iterator iov_iter=entries.begin(); iov_iter!=entries.end(); ++iov_iter) { + typedef UpdatePool::ConditionEntries _E; + const _E& ents = (*iov_iter).second; + if ( !ents.empty() ) { + for(_E::const_iterator j=ents.begin(); j != ents.end(); ++j) { + (*j)->pool->insert(*j); + __print("__register(2):",*j); + } + //for_each(ents.begin(), ents.end(), [](_E::reference c) { c->pool->insert(c); }); + //for_each(ents.begin(), ents.end(), [](_E::reference c) { __print("__register(2):",c); }); + } + } +} + +/// Prepare all updates to the clients with the defined IOV +void ConditionsManagerObject::prepare(const IOV& required_validity) { + const IOVType* typ = check_iov_type<Discrete>(this, &required_validity); + if ( typ ) { + ConditionsPool* cp = 0; + IOVPool* pool = m_pool[typ->type]; + if ( pool ) {{ + dd4hep_lock_t lock(m_poolLock); + cp = registerIOV(*typ, required_validity.key()); + if ( !cp->updates ) + cp->updates = createPlugin<ReplacementPool>(m_replType,m_lcdd); + } + /// First push any pending updates and register them to pending pools... + pushUpdates(); + RangeConditions updates; + pool->__select_expired(required_validity, updates); + pool->__update_expired(this, cp, updates, required_validity); + cp->updates->insert(updates); + } + return; + } + except("ConditionsManager","+++ Unknown IOV type requested to enable conditions. [%s]", + Errors::invalidArg().c_str()); +} + +/// Enable all updates to the clients with the defined IOV +void ConditionsManagerObject::enable(const IOV& required_validity) { + if ( !locked ) { + IOVPool* pool = m_pool[required_validity.type]; + if ( pool ) { + ReplacementPool* rep_pool = 0; + pushUpdates(); + { + dd4hep_lock_t lock(m_poolLock); + IOVPool::Entries::iterator i = pool->entries.find(required_validity.key()); + if ( i == pool->entries.end() ) { + except("ConditionsManager","+++ Unknown IOV [%s] requested to enable conditions. [%s]", + required_validity.str().c_str(), Errors::invalidArg().c_str()); + } + rep_pool = (*i).second->updates; + } + RangeConditions entries; + rep_pool->popEntries(entries); + __push_immediate(entries); + return; + } + except("ConditionsManager","+++ Unknown IOV type requested to enable conditions. [%s]", + Errors::invalidArg().c_str()); + } + except("ConditionsManager","+++ Cannot enable new conditions for IOV:%s in locked state! [%s]", + required_validity.str().c_str(), Errors::invalidArg().c_str()); +} + +/// Register a new managed condition +void ConditionsManagerObject::registerCondition(Condition c) { + dd4hep_ptr<ConditionObject> cond(c.ptr()); + if ( !cond.get() ) { + except("ConditionsManager","+++ Failed to register invalid handle."); + } + if ( !locked ) { + DetElement det = cond->detector; + IOV* iov = const_cast<IOV*>(cond->iov); + + // Check arguments. This also checks the existence of the proper pool + __check_values__<Discrete>(this,det,c.name(),iov); + IOVPool* pool = m_pool[iov->type]; + { // We are now modifying the pool: need to lock any access + dd4hep_lock_t lock(m_poolLock); + IOVPool::Entries::iterator it = pool->entries.find(iov->keyData); + if ( it != pool->entries.end() ) { + (*it).second->insert(c); + return; + } + ConditionsPool* cp = createPlugin<ConditionsPool>(m_poolType,m_lcdd); + pool->entries.insert(make_pair(iov->keyData,cp)); + cp->insert(c); + } + return; + } + except("ConditionsManager","+++ You cannot register new conditions while the conditions manager is locked!"); +} + +/// Retrieve a condition set given a Detector Element and the conditions name according to their validity +bool ConditionsManagerObject::__find(DetElement det, + const std::string& cond, + const IOV& req_validity, + RangeConditions& conditions) { + IOVPool* p = 0; + { + dd4hep_lock_t locked_action(m_poolLock); + p = m_pool[req_validity.type]; // Already checked by upper level! + p->__find(det, cond, req_validity, conditions); + } + { + dd4hep_lock_t locked_action(m_updateLock); + m_updatePool->select_range(det, cond, req_validity, conditions); + } + return !conditions.empty(); +} + +/// Retrieve a condition set given a Detector Element and the conditions name according to their validity +bool ConditionsManagerObject::__find_range(DetElement det, + const std::string& cond, + const IOV& req_validity, + RangeConditions& conditions) +{ + IOVPool* p = 0; + { + dd4hep_lock_t locked_action(m_poolLock); + p = m_pool[req_validity.type]; // Existence alread checked! + p->__find_range(det, cond, req_validity, conditions); + } + { + dd4hep_lock_t locked_action(m_updateLock); + m_updatePool->select_range(det, cond, req_validity, conditions); + } + return is_range_complete(req_validity,conditions); +} + +/// Register a new managed condition. +void ConditionsManagerObject::__register_immediate(RangeConditions& rc) { + // We modify the pool. For this we need a lock, + // since this may happen during the event processing in parallel + dd4hep_lock_t locked_action(m_poolLock); + for(RangeConditions::iterator i=rc.begin(); i != rc.end(); ++i) { + Condition c = *i; + if ( !c->pool ) { + except("ConditionsManager","+++ __register_immediate: Invalid pool. [Fatal, Internal or Usage Error]"); + } + if ( s_debug > INFO ) { + printout(INFO,"ConditionsManager","+++ __register(1): %s.%s [%s]", + c->detector.path().c_str(), c.name().c_str(), c->iov->str().c_str()); + } + c->pool->insert(c); + } +} + +/// Push registered set of conditions to the corresponding detector elements +void ConditionsManagerObject::__push_immediate(RangeConditions& rc) { + for(RangeConditions::iterator i=rc.begin(); i!=rc.end(); ++i) { + Condition::Object* c = (*i).ptr(); + Interna::ConditionContainer* cnt = c->detector.conditions().ptr(); + if ( s_debug > INFO ) { + printout(INFO,"ConditionsManager","Register condition %s.%s [%s] = %s to Conditions::Container....", + c->detector.path().c_str(), c->name.c_str(), c->iov->str().c_str(), c->value.c_str()); + } + cnt->add(c); + } +} + +/// Load a condition set given a Detector Element and the conditions name according to their validity +bool ConditionsManagerObject::__load_immediate(DetElement det, + const std::string& cond, + const IOV& req_validity, + RangeConditions& conditions) +{ + const IOV& iov = req_validity; + { + dd4hep_lock_t locked_action(m_updateLock); + m_loader->load(det, cond, iov, conditions); + } + if ( conditions.size() == 0 ) { + except("ConditionsManager","+++ Condition %s.%s for the requested IOV %s do not exist.", + det.path().c_str(), cond.c_str(), iov.str().c_str()); + } + __push_immediate(conditions); + return true; +} + +/// Load a condition set given a Detector Element and the conditions name according to their validity +bool ConditionsManagerObject::__load_range_immediate(DetElement det, + const std::string& cond, + const IOV& req_validity, + RangeConditions& conditions) +{ + const IOV& iov = req_validity; + { + dd4hep_lock_t locked_action(m_updateLock); + m_loader->load_range(det, cond, iov, conditions); + } + if ( conditions.size() == 0 ) { + except("ConditionsManager","+++ Condition %s.%s for the requested IOV %s do not exist.", + det.path().c_str(), cond.c_str(), iov.str().c_str()); + } + __push_immediate(conditions); + conditions.clear(); + return __find_range(det, cond, iov, conditions); +} + +/// Retrieve a condition given a Detector Element and the conditions name +Condition +ConditionsManagerObject::get(DetElement det, const string& cond, const IOV& req_validity) +{ + RangeConditions conditions; + const IOV& iov = req_validity; + __check_values__<Discrete>(this, det, cond, &iov); + bool rc = __find(det, cond, iov, conditions); + if ( !rc ) { + rc = __load_immediate(det, cond, iov, conditions); + } + if ( !rc ) { + except("ConditionsManager","+++ Condition %s.%s for the requested IOV %s do not exist.", + det.path().c_str(), cond.c_str(), iov.str().c_str()); + } + else if ( conditions.size() > 1 ) { + printout(ERROR,"ConditionsManager","+++ Condition %s.%s is ambiguous for IOV %s:", + det.path().c_str(), cond.c_str(), iov.str().c_str()); + for(RangeConditions::const_iterator i=conditions.begin(); i!=conditions.end(); ++i) { + Condition c = *i; + printout(ERROR,"ConditionsManager","+++ %s.%s [%s] = %s", + c->detector.path().c_str(), c.name().c_str(), c->iov->str().c_str(), c->value.c_str()); + } + except("ConditionsManager","+++ Condition %s.%s is ambiguous for IOV %s:", + det.path().c_str(), cond.c_str(), iov.str().c_str()); + } + if ( conditions.size() == 1 ) { + conditions[0]->flags |= ConditionObject::ACTIVE; + return conditions[0]; + } + return Condition(); +} + +/// Retrieve a condition given a Detector Element and the conditions name +RangeConditions +ConditionsManagerObject::getRange(DetElement det, + const std::string& cond, + const IOV& req_range_validity) +{ + RangeConditions conditions; + const IOV& iov = req_range_validity; + __check_values__<Range>(this, det, cond, &iov); + bool rc = __find_range(det, cond, iov, conditions); + if ( rc ) { + return conditions; + } + rc = __load_range_immediate(det, cond, iov, conditions); + if ( !rc ) { + except("ConditionsManager","+++ Conditions %s.%s for IOV %s do not exist.", + det.path().c_str(), cond.c_str(), iov.str().c_str()); + } + return conditions; +} diff --git a/DDCond/src/ConditionsLinearPool.cpp b/DDCond/src/ConditionsLinearPool.cpp new file mode 100644 index 000000000..54fc79604 --- /dev/null +++ b/DDCond/src/ConditionsLinearPool.cpp @@ -0,0 +1,272 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +#ifndef DDCOND_CONDITIONSLINEARPOOL_H +#define DDCOND_CONDITIONSLINEARPOOL_H + +// Framework include files +#include "DDCond/ConditionsPool.h" + +// C/C++ include files +#include <list> + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Conditions { + + /// Class implementing the conditions collection for a given IOV type + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_GEOMETRY + * \ingroup DD4HEP_CONDITIONS + */ + template<typename MAPPING, typename BASE> + class ConditionsLinearPool : public BASE { + protected: + typedef MAPPING Mapping; + Mapping m_conditions; + + public: + /// Default constructor + ConditionsLinearPool(); + + /// Default destructor + virtual ~ConditionsLinearPool(); + + /// Register a new condition to this pool + virtual void insert(Condition condition) { + m_conditions.insert(m_conditions.end(),condition.ptr()); + } + + /// Register a new condition to this pool. May overload for performance reasons. + virtual void insert(RangeConditions& new_entries) { + for(RangeConditions::iterator i=new_entries.begin(); i!=new_entries.end(); ++i) + m_conditions.insert(m_conditions.end(),(*i).ptr()); + } + + /// Register a new condition to this pool + virtual Condition insert(ConditionsPool* pool, Entry* cond) { + MAPPING& m = this->ConditionsLinearPool<MAPPING,BASE>::m_conditions; + Condition c = this->create(pool, cond); + m.insert(m.end(),c.ptr()); + return c; + } + + /// Full cleanup of all managed conditions. + virtual void clear() { + for_each(m_conditions.begin(), m_conditions.end(), DD4hep::deleteObject<Condition::Object>); + m_conditions.clear(); + } + + /// Check if a condition exists in the pool + virtual Condition exists(DetElement det, const std::string& cond_name) const { + if ( !m_conditions.empty() ) { + int hash = DD4hep::hash32(cond_name); + DetElement::Object* ptr = det.ptr(); + for(typename Mapping::const_iterator i=m_conditions.begin(); i!=m_conditions.end(); ++i) + if ( this->ConditionsPool::match(ptr,hash,(*i)) ) return *i; + } + return Condition(); + } + + /// Check if a condition exists in the pool + virtual Condition exists(Condition test) const { + int hash = DD4hep::hash32(test->name); + DetElement::Object* ptr = test->detector.ptr(); + for(typename Mapping::const_iterator i=m_conditions.begin(); i!=m_conditions.end(); ++i) { + if ( this->ConditionsPool::match(ptr,hash,(*i)) ) return *i; + } + return Condition(); + } + + /// Select the conditions matching the DetElement and the conditions name + virtual void select(DetElement det, const std::string& cond_name, RangeConditions& result) { + if ( !m_conditions.empty() ) { + int hash = DD4hep::hash32(cond_name); + DetElement::Object* ptr = det.ptr(); + for(typename Mapping::const_iterator i=m_conditions.begin(); i!=m_conditions.end(); ++i) + if ( this->ConditionsPool::match(ptr,hash,(*i)) ) result.push_back(*i); + } + } + + /// Select the conditons, used also by the DetElement of the condition + virtual void select_used(RangeConditions& result) { + for(typename Mapping::const_iterator i=m_conditions.begin(); i!=m_conditions.end(); ++i) { + Condition::Object* c = *i; + if ( (c->flags & Interna::ConditionObject::ACTIVE) ) result.push_back(c); +#if 0 + // Too slow. Simple check the conditions flag. If it is set to ACTIVE, take it. + const Container::Entries& cond = c->detector->conditions->elements(); + Container::Entries::const_iterator k=cond.find(c->hash); + if ( k != cond.end() ) { + if ( (*k).second->pool == this ) { + result.push_back(c); + } + } +#endif + } + } + + /// Select the conditons, used also by the DetElement of the condition + virtual void select_all(RangeConditions& result) { + for(typename Mapping::const_iterator i=m_conditions.begin(); i!=m_conditions.end(); ++i) + result.push_back(*i); + } + + /// Select the conditions matching the DetElement and the conditions name + virtual void select_range(DetElement det, + const std::string& cond_name, + const IOV& req, + RangeConditions& result) + { + if ( !m_conditions.empty() ) { + unsigned int req_typ = req.iovType ? req.iovType->type : req.type; + const IOV::Key& req_key = req.key(); + int hash = DD4hep::hash32(cond_name); + DetElement::Object* ptr = det.ptr(); + for(typename Mapping::const_iterator i=m_conditions.begin(); i!=m_conditions.end(); ++i) { + if ( this->ConditionsPool::match(ptr,hash,(*i)) ) { + const IOV* _iov = (*i)->iov; + unsigned int typ = _iov->iovType ? _iov->iovType->type : _iov->type; + if ( req_typ == typ ) { + if ( IOV::key_is_contained(_iov->key(),req_key) ) + // IOV test contained in key. Take it! + result.push_back(*i); + else if ( IOV::key_overlaps_lower_end(_iov->key(),req_key) ) + // IOV overlap on test on the lower end of key + result.push_back(*i); + else if ( IOV::key_overlaps_higher_end(_iov->key(),req_key) ) + // IOV overlap of test on the higher end of key + result.push_back(*i); + } + } + } + } + } + + }; + + + template<typename MAPPING> class ConditionsLinearReplacementPool + : public ConditionsLinearPool<MAPPING,ReplacementPool> + { + public: + /// Default constructor + ConditionsLinearReplacementPool() : ConditionsLinearPool<MAPPING,ReplacementPool>() {} + + /// Default destructor + virtual ~ConditionsLinearReplacementPool() {} + /// Full cleanup of all managed conditions. + virtual void clear() { + this->ConditionsLinearPool<MAPPING,ReplacementPool>::m_conditions.clear(); + } + + /// Pop conditions. May overloade for performance reasons! + virtual void popEntries(RangeConditions& entries) { + MAPPING& m = this->ConditionsLinearPool<MAPPING,ReplacementPool>::m_conditions; + if ( !m.empty() ) { + for(typename MAPPING::iterator i=m.begin(); i!=m.end(); ++i) + entries.push_back((*i)); + m.clear(); + } + } + }; + + + template<typename MAPPING> class ConditionsLinearUpdatePool + : public ConditionsLinearPool<MAPPING,UpdatePool> + { + public: + /// Default constructor + ConditionsLinearUpdatePool() : ConditionsLinearPool<MAPPING,UpdatePool>() {} + + /// Default destructor + virtual ~ConditionsLinearUpdatePool() {} + + /// Adopt all entries sorted by IOV. Entries will be removed from the pool + virtual void popEntries(UpdatePool::UpdateEntries& entries) { + MAPPING& m = this->ConditionsLinearPool<MAPPING,UpdatePool>::m_conditions; + if ( !m.empty() ) { + for(typename MAPPING::iterator i=m.begin(); i!=m.end(); ++i) { + Interna::ConditionObject* o = *i; + entries[o->iov].push_back(Condition(o)); + } + m.clear(); + } + } + }; + + + } /* End namespace Conditions */ +} /* End namespace DD4hep */ +#endif // DDCOND_CONDITIONSLINEARPOOL_H + +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +//#include "DDCond/ConditionsLinearPool.h" +#include "DD4hep/InstanceCount.h" +#include "DD4hep/objects/DetectorInterna.h" +#include "DD4hep/objects/ConditionsInterna.h" + +using namespace DD4hep::Conditions; + +/// Default constructor +template<typename MAPPING, typename BASE> +ConditionsLinearPool<MAPPING,BASE>::ConditionsLinearPool() : BASE() { + InstanceCount::increment(this); +} + +/// Default destructor +template<typename MAPPING, typename BASE> +ConditionsLinearPool<MAPPING,BASE>::~ConditionsLinearPool() { + clear(); + InstanceCount::decrement(this); +} + +#include "DD4hep/Factories.h" +namespace { + void* create_vector_pool(DD4hep::Geometry::LCDD&, int, char**) + { return new ConditionsLinearPool<std::vector<Condition::Object*> , ConditionsPool>(); } + void* create_list_pool(DD4hep::Geometry::LCDD&, int, char**) + { return new ConditionsLinearPool<std::list<Condition::Object*> , ConditionsPool>(); } + void* create_replacement_pool(DD4hep::Geometry::LCDD&, int, char**) { + ReplacementPool* pool = new ConditionsLinearReplacementPool<std::vector<Condition::Object*> >(); + return pool; + } + void* create_update_pool(DD4hep::Geometry::LCDD&, int, char**) { + UpdatePool* pool = new ConditionsLinearUpdatePool<std::vector<Condition::Object*> >(); + return pool; + } +} +DECLARE_LCDD_CONSTRUCTOR(DD4hep_ConditionsLinearPool, create_vector_pool) +DECLARE_LCDD_CONSTRUCTOR(DD4hep_ConditionsLinearListPool, create_list_pool) +DECLARE_LCDD_CONSTRUCTOR(DD4hep_ConditionsLinearVectorPool,create_vector_pool) +DECLARE_LCDD_CONSTRUCTOR(DD4hep_ConditionsLinearReplacementPool, create_replacement_pool) +DECLARE_LCDD_CONSTRUCTOR(DD4hep_ConditionsLinearUpdatePool, create_update_pool) diff --git a/DDCond/src/ConditionsManager.cpp b/DDCond/src/ConditionsManager.cpp new file mode 100644 index 000000000..488797a58 --- /dev/null +++ b/DDCond/src/ConditionsManager.cpp @@ -0,0 +1,194 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include "DD4hep/LCDD.h" +#include "DD4hep/Errors.h" +#include "DD4hep/Printout.h" +#include "DD4hep/DetectorTools.h" + +#include "DDCond/ConditionsInterna.h" +#include "DDCond/ConditionsManager.h" + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::Conditions; + + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Conditions { + + /// Access specialization + template <> ConditionsManager ConditionsManager::from<LCDD>(LCDD& host) { + Object* obj = host.extension<Object>(); + if ( obj ) return ConditionsManager(obj); + except("ConditionsManager","+++ Failed to access manager from LCDD."); + return ConditionsManager(); + } + } +} + +/// Default constructor +ConditionsManager::ConditionsManager(LCDD& lcdd) { + assign(new Object(lcdd), "ConditionsManager",""); +} + +/// Default destructor +ConditionsManager::~ConditionsManager() { + access()->clear(); +} + +/// Access to the property manager +PropertyManager& ConditionsManager::properties() const { + return access()->properties(); +} + +/// Access to properties +Property& ConditionsManager::operator[](const std::string& property_name) const { + return access()->properties().property(property_name); +} + +/// Access the conditions loader +Handle<ConditionsManager::Loader> ConditionsManager::loader() const { + return Handle<Loader>(access()->m_loader.get()); +} + +/// Register new IOV type if it does not (yet) exist. +pair<bool, const IOVType*> +ConditionsManager::registerIOVType(size_t iov_type, const string& iov_name) { + return access()->registerIOVType(iov_type, iov_name); +} + +/// Access IOV by its type +const IOVType* ConditionsManager::iovType (size_t iov_type) const { + return access()->iovType(iov_type); +} + +/// Access IOV by its name +const IOVType* ConditionsManager::iovType (const string& iov_name) const { + return access()->iovType(iov_name); +} + +/// Age conditions, which are no longer used and to be removed eventually +void ConditionsManager::age() { + access()->age(); +} + +/// Clean conditions, which are above the age limit. +void ConditionsManager::clean() { + access()->clean(); +} + +/// Full cleanup of all managed conditions. +void ConditionsManager::clear() { + access()->clear(); +} + +/// Retrieve a condition given a Detector Element and the conditions name +Condition +ConditionsManager::get(DetElement detector, + const string& cond, + const IOV& req_validity) +{ + return access()->get(detector, cond, req_validity); +} + +/// Retrieve a condition given a Detector Element path and the conditions name +Condition +ConditionsManager::get(const string& detector_path, + const string& cond, + const IOV& req_validity) +{ + Interna::ConditionsManagerObject* o = access(); + DetElement detector = Geometry::DetectorTools::findDaughterElement(o->m_lcdd.world(), detector_path); + return o->get(detector, cond, req_validity); +} + +/// Push all pending updates to the conditions store +void ConditionsManager::pushUpdates() { + access()->pushUpdates(); +} + +/// Lock the internal data structures. This disables calls to "register", etc. +void ConditionsManager::lock() { + access()->locked = 1; +} + +/// Unlock the internal data structures. This enables calls to "register", etc. +void ConditionsManager::unlock() { + access()->locked = 0; +} + +/// Enable all updates to the clients with the defined IOV +void ConditionsManager::enable(const IOV& required_validity) { + access()->enable(required_validity); +} + +/// Prepare all updates to the clients with the defined new IOV. Changes are not yet applied +void ConditionsManager::prepare(const IOV& required_validity) { + access()->prepare(required_validity); +} + +/// Retrieve a condition given the conditions path = <Detector Element path>.<conditions name> +Condition +ConditionsManager::get(const string& conditions_path, const IOV& req_validity) +{ + size_t idx = conditions_path.rfind("."); + if ( idx != string::npos ) { + string detector_path = conditions_path.substr(0,idx); + string condition_name = conditions_path.substr(idx+1, string::npos); + return this->get(detector_path,condition_name, req_validity); + } + except("ConditionsManager","+++ Badly formed conditions path %s. [%s]", + conditions_path.c_str(),Errors::linkRange().c_str()); + return Condition(); +} + +/// Retrieve a condition given a Detector Element and the conditions name +RangeConditions +ConditionsManager::getRange(DetElement detector, + const std::string& condition_name, + const IOV& req_range_validity) +{ + return access()->getRange(detector, condition_name, req_range_validity); +} + +/// Retrieve a condition given a Detector Element path and the conditions name +RangeConditions +ConditionsManager::getRange(const std::string& detector_path, + const std::string& condition_name, + const IOV& req_range_validity) +{ + Interna::ConditionsManagerObject* o = access(); + DetElement detector = Geometry::DetectorTools::findDaughterElement(o->m_lcdd.world(), detector_path); + return o->getRange(detector, condition_name, req_range_validity); +} + +/// Retrieve a condition given the conditions path = <Detector Element path>.<conditions name> +RangeConditions +ConditionsManager::getRange(const std::string& conditions_path, + const IOV& req_range_validity) +{ + size_t idx = conditions_path.rfind("."); + if ( idx != string::npos ) { + string detector_path = conditions_path.substr(0,idx); + string condition_name = conditions_path.substr(idx+1, string::npos); + return this->getRange(detector_path,condition_name, req_range_validity); + } + except("ConditionsManager","+++ Badly formed conditions path %s. [%s]", + conditions_path.c_str(),Errors::linkRange().c_str()); + return RangeConditions(); +} diff --git a/DDCond/src/ConditionsMultiLoader.cpp b/DDCond/src/ConditionsMultiLoader.cpp new file mode 100644 index 000000000..fff24204b --- /dev/null +++ b/DDCond/src/ConditionsMultiLoader.cpp @@ -0,0 +1,174 @@ +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// \author Markus Frank +// \date 2016-02-02 +// \version 1.0 +// +//========================================================================== +// $Id$ +#ifndef DD4HEP_CONDITIONS_MULTICONDITONSLOADER_H +#define DD4HEP_CONDITIONS_MULTICONDITONSLOADER_H + +// Framework include files +#include "DDCond/ConditionsDataLoader.h" + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Conditions { + + // Forward declarations + class ConditionsHandler; + + /// Implementation of a stack of conditions assembled before application + /** + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class ConditionsMultiLoader : public ConditionsDataLoader { + typedef std::map<std::string, ConditionsDataLoader*> Loaders; + typedef std::map<std::string, ConditionsDataLoader*> OpenSources; + + Loaders m_loaders; + OpenSources m_openSources; + + public: + /// Default constructor + ConditionsMultiLoader(LCDD& lcdd, ConditionsManager mgr, const std::string& nam); + /// Default destructor + virtual ~ConditionsMultiLoader(); + /// Load a condition set given a Detector Element and the conditions name according to their validity + virtual size_t load(DetElement det, + const std::string& cond, + const IOV& req_validity, + RangeConditions& conditions); + /// Load a condition set given a Detector Element and the conditions name according to their validity + virtual size_t load_range(DetElement det, + const std::string& cond, + const IOV& req_validity, + RangeConditions& conditions); + size_t load_source(const std::string& nam, + DetElement det, + const std::string& cond, + const IOV& req_validity, + RangeConditions& conditions); + }; + } /* End namespace Geometry */ +} /* End namespace DD4hep */ + +#endif /* DD4HEP_CONDITIONS_MULTICONDITONSLOADER_H */ + +//#include "ConditionsMultiLoader.h" +#include "DD4hep/Printout.h" +#include "DD4hep/Factories.h" +#include "DD4hep/PluginCreators.h" + +// Forward declartions +using std::string; +using namespace DD4hep::Conditions; + +namespace { + void* create_loader(DD4hep::Geometry::LCDD& lcdd, int argc, char** argv) { + const char* name = argc>0 ? argv[0] : "MULTILoader"; + Interna::ConditionsManagerObject* mgr = (Interna::ConditionsManagerObject*)(argc>0 ? argv[1] : 0); + return new ConditionsMultiLoader(lcdd,ConditionsManager(mgr),name); + } +} +DECLARE_LCDD_CONSTRUCTOR(DD4hep_Conditions_multi_Loader,create_loader) + +/// Standard constructor, initializes variables +ConditionsMultiLoader::ConditionsMultiLoader(LCDD& lcdd, ConditionsManager mgr, const string& nam) +: ConditionsDataLoader(lcdd, mgr, nam) +{ +} + +/// Default Destructor +ConditionsMultiLoader::~ConditionsMultiLoader() { +} + +size_t ConditionsMultiLoader::load_source(const std::string& nam, + DetElement det, + const std::string& cond, + const IOV& req_validity, + RangeConditions& conditions) +{ + size_t idx = nam.find(':'); + if ( idx == string::npos ) { + except("ConditionsMultiLoader","Invalid data source specification: "+nam); + } + string ident = nam.substr(0,idx); + Loaders::iterator ild = m_loaders.find(ident); + ConditionsDataLoader* loader = 0; + if ( ild == m_loaders.end() ) { + string typ = "DD4hep_Conditions_"+ident+"_Loader"; + string fac = ident+"_ConditionsDataLoader"; + char* argv[] = {(char*)fac.c_str(), (char*)m_mgr.ptr(), 0}; + loader = createPlugin<ConditionsDataLoader>(typ,m_lcdd,2,argv); + if ( !loader ) { + except("ConditionsMultiLoader", + "Failed to create conditions loader of type: "+typ+" to read:"+nam); + } + } + else { + loader = (*ild).second; + } + loader->addSource(nam.substr(idx+1)); + m_loaders[ident] = loader; + m_openSources[nam] = loader; + size_t items = loader->load(det, cond, req_validity, conditions); + if ( items > 0 ) { + return items; + } + return 0; +} + +/// Load a condition set given a Detector Element and the conditions name according to their validity +size_t ConditionsMultiLoader::load_range(DetElement det, + const std::string& cond, + const IOV& req_validity, + RangeConditions& conditions) { + size_t len = conditions.size(); + // No better idea: Must chack all sources to find the required condition + for(Sources::const_iterator i=m_sources.begin(); i != m_sources.end(); ++i) { + const string& nam = *i; + OpenSources::iterator iop = m_openSources.find(nam); + if ( iop == m_openSources.end() ) { + load_source(nam, det, cond, req_validity, conditions); + continue; + } + (*iop).second->load(det, cond, req_validity, conditions); + } + return conditions.size() - len; +} + + +size_t ConditionsMultiLoader::load(DetElement det, + const std::string& cond, + const IOV& req_validity, + RangeConditions& conditions) { + size_t len = conditions.size(); + // No better idea: Must chack all sources to find the required condition + for(Sources::const_iterator i=m_sources.begin(); i != m_sources.end(); ++i) { + const string& nam = *i; + size_t items = 0; + OpenSources::iterator iop = m_openSources.find(nam); + if ( iop == m_openSources.end() ) { + items = load_source(nam, det, cond, req_validity, conditions); + if ( items > 0 ) { + return items; + } + continue; + } + items = (*iop).second->load(det, cond, req_validity, conditions); + if ( items > 0 ) return items; + } + return conditions.size() - len; +} diff --git a/DDCond/src/ConditionsParser.cpp b/DDCond/src/ConditionsParser.cpp index 96b87c365..e5a2f42eb 100644 --- a/DDCond/src/ConditionsParser.cpp +++ b/DDCond/src/ConditionsParser.cpp @@ -17,14 +17,13 @@ #include "XML/Conversions.h" #include "XML/XMLElements.h" #include "XML/DocumentHandler.h" +#include "DD4hep/Printout.h" #include "DD4hep/DetectorTools.h" #include "DD4hep/DetFactoryHelper.h" -#include "DD4hep/objects/ConditionsInterna.h" #include "DDCond/ConditionsTags.h" -#include "DDCond/ConditionsStack.h" -#include "DDCond/ConditionsHandler.h" -#include "DDCond/ConditionsTransaction.h" +#include "DDCond/ConditionsEntry.h" +#include "DDCond/ConditionsDataLoader.h" // C/C++ include files #include <stdexcept> @@ -46,144 +45,157 @@ namespace DD4hep { template <> void Converter<conditions>::operator()(xml_h seq) const; } -using namespace std; using namespace DD4hep; -using namespace DD4hep::Geometry; -typedef ConditionsStack::Entry Entry; +using namespace DD4hep::Conditions; +using Geometry::DetElement; +using std::string; -/// Helper: Extract the validity from the xml element -string _getValidity(xml_h elt) { - if ( !elt.ptr() ) - return "Infinite"; - else if ( !elt.hasAttr(_U(validity)) ) - return _getValidity(elt.parent()); - return elt.attr<string>(_U(validity)); -} +namespace { + struct ConversionArg { + DetElement detector; + ConditionsStack* stack; + ConversionArg(DetElement det, ConditionsStack* s) : detector(det), stack(s) {} + }; -/// Helper: Extract the required detector element from the parsing information -DetElement _getDetector(void* param, xml_h e) { - DetElement detector = param ? *(DetElement*)param : DetElement(); - string subpath = e.hasAttr(_U(path)) ? e.attr<string>(_U(path)) : string(); - return subpath.empty() ? detector : DetectorTools::findDaughterElement(detector,subpath); -} + /// Helper: Extract the validity from the xml element + string _getValidity(xml_h elt) { + if ( !elt.ptr() ) + return "Infinite"; + else if ( !elt.hasAttr(_U(validity)) ) + return _getValidity(elt.parent()); + return elt.attr<string>(_U(validity)); + } -/// Helper: Extract the string value from the xml element -Entry* _createStackEntry(void* param, xml_h element) { - xml_comp_t e(element); - DetElement elt = _getDetector(param, element); - string name = e.hasAttr(_U(name)) ? e.nameStr() : e.tag(); - return new Entry(elt,name,e.tag(),_getValidity(element)); -} + ConversionArg* _getArgs(void* param) { + ConversionArg* arg = (ConversionArg*)param; + return arg; + } + /// Helper: Extract the required detector element from the parsing information + DetElement _getDetector(void* param, xml_h e) { + ConversionArg* arg = _getArgs(param); + DetElement detector = arg ? arg->detector : DetElement(); + string subpath = e.hasAttr(_U(path)) ? e.attr<string>(_U(path)) : string(); + return subpath.empty() ? detector : Geometry::DetectorTools::findDaughterElement(detector,subpath); + } -/** Convert arbitrary conditon objects containing standard tags - * - * Function entry expects as a parameter a valid DetElement handle - * pointing to the subdetector, which detector elements should be - * realigned. - * - * <temperature path="/world/TPC" name="AbientTemperatur" value="20.9*Celcius"/> - * <temperature path="TPC" name="AbientTemperatur" value="20.9*Celcius"/> - * <temperature name="AbientTemperatur" value="20.9*Celcius"/> - * - * <temperature name="AbientTemperatur" value="20.9*Kelvin"/> - * <pressure name="external_pressure" value="980*hPa"/> - * <include ref="..."/> - * - * The object tag name is passed as the conditons type to the system. - * The data payload may either be specified as an attribute to the - * element or as text (data payload as the inner XML of the element). - * - * These items have: - * - a name defining the condition within the detector element - * - a value interpreted as a double. In XML the value may be dressed with a unit - * which will be correctly treated by the expression evaluator - * - a path (optionally). attribute_values are ALWAYS treated within the context - * of the containing detector element. If pathes are relative, they are - * relative to the embedding element. If pathes are absolute, the embedding - * element is ignored. - * - * @author M.Frank - * @version 1.0 - * @date 01/04/2014 - */ -template <> void Converter<arbitrary>::operator()(xml_h e) const { - xml_comp_t elt(e); - string tag = elt.tag(); - if ( tag == "open_transaction" ) - return; - else if ( tag == "close_transaction" ) - return; - else if ( tag == "include" ) - Converter<include>(lcdd,param)(e); - else if ( tag == "conditions" ) - Converter<conditions>(lcdd,param)(e); - else if ( tag == "detelement" ) - Converter<conditions>(lcdd,param)(e); - else if ( tag == "subdetectors" ) - xml_coll_t(e,_U(star)).for_each(Converter<conditions>(lcdd,param)); - else if ( tag == "detelements" ) - xml_coll_t(e,_U(star)).for_each(Converter<conditions>(lcdd,param)); - else { - dd4hep_ptr<Entry> val(_createStackEntry(param,e)); - val->value = elt.hasAttr(_U(value)) ? elt.valueStr() : e.text(); - ConditionsStack::get().insert(val); + /// Helper: Extract the string value from the xml element + Entry* _createStackEntry(void* param, xml_h element) { + xml_comp_t e(element); + DetElement elt = _getDetector(param, element); + string name = e.hasAttr(_U(name)) ? e.nameStr() : e.tag(); + return new Entry(elt,name,e.tag(),_getValidity(element),hash32(name)); } -} -/** Convert include objects - * - * @author M.Frank - * @version 1.0 - * @date 01/04/2014 - */ -template <> void Converter<include>::operator()(xml_h element) const { - XML::DocumentHolder doc(XML::DocumentHandler().load(element, element.attr_value(_U(ref)))); - xml_coll_t(doc.root(),_U(star)).for_each(Converter<arbitrary>(lcdd,param)); -} + /** Convert arbitrary conditon objects containing standard tags + * + * Function entry expects as a parameter a valid DetElement handle + * pointing to the subdetector, which detector elements should be + * realigned. + * + * <temperature path="/world/TPC" name="AbientTemperatur" value="20.9*Celcius"/> + * <temperature path="TPC" name="AbientTemperatur" value="20.9*Celcius"/> + * <temperature name="AbientTemperatur" value="20.9*Celcius"/> + * + * <temperature name="AbientTemperatur" value="20.9*Kelvin"/> + * <pressure name="external_pressure" value="980*hPa"/> + * <include ref="..."/> + * + * The object tag name is passed as the conditons type to the system. + * The data payload may either be specified as an attribute to the + * element or as text (data payload as the inner XML of the element). + * + * These items have: + * - a name defining the condition within the detector element + * - a value interpreted as a double. In XML the value may be dressed with a unit + * which will be correctly treated by the expression evaluator + * - a path (optionally). attribute_values are ALWAYS treated within the context + * of the containing detector element. If pathes are relative, they are + * relative to the embedding element. If pathes are absolute, the embedding + * element is ignored. + * + * @author M.Frank + * @version 1.0 + * @date 01/04/2014 + */ + template <> void Converter<arbitrary>::operator()(xml_h e) const { + xml_comp_t elt(e); + string tag = elt.tag(); + if ( tag == "open_transaction" ) + return; + else if ( tag == "close_transaction" ) + return; + else if ( tag == "include" ) + Converter<include>(lcdd,param)(e); + else if ( tag == "conditions" ) + Converter<conditions>(lcdd,param)(e); + else if ( tag == "detelement" ) + Converter<conditions>(lcdd,param)(e); + else if ( tag == "subdetectors" ) + xml_coll_t(e,_U(star)).for_each(Converter<conditions>(lcdd,param)); + else if ( tag == "detelements" ) + xml_coll_t(e,_U(star)).for_each(Converter<conditions>(lcdd,param)); + else if ( tag == "alignment" ) { + dd4hep_ptr<Entry> val(_createStackEntry(param,e)); + val->value = elt.attr<string>(_U(ref)); + _getArgs(param)->stack->push_back(val.release()); + } + else { + dd4hep_ptr<Entry> val(_createStackEntry(param,e)); + val->value = elt.hasAttr(_U(value)) ? elt.valueStr() : e.text(); + _getArgs(param)->stack->push_back(val.release()); + } + } -/** Convert objects containing standard conditions tags - * - * Function entry expects as a parameter a valid DetElement handle - * pointing to the subdetector, which detector elements should be - * realigned. A absolute or relative DetElement path may be supplied by - * the element as an attribute: - * - * <conditions path="/world/TPC/TPC_SideA/TPC_SideA_sector02"> - * ... - * </conditions> - * - * @author M.Frank - * @version 1.0 - * @date 01/04/2014 - */ -template <> void Converter<conditions>::operator()(xml_h e) const { - DetElement elt = _getDetector(param,e); - xml_coll_t(e,_U(star)).for_each(Converter<arbitrary>(lcdd,&elt)); -} + /** Convert include objects + * + * @author M.Frank + * @version 1.0 + * @date 01/04/2014 + */ + template <> void Converter<include>::operator()(xml_h element) const { + XML::DocumentHolder doc(XML::DocumentHandler().load(element, element.attr_value(_U(ref)))); + xml_coll_t(doc.root(),_U(star)).for_each(Converter<arbitrary>(lcdd,param)); + } -/** Basic entry point to read conditions files - * - * @author M.Frank - * @version 1.0 - * @date 01/04/2014 - */ -static long setup_Conditions(lcdd_t& lcdd, const xml_h& e) { - ConditionsHandler::install(lcdd); - ConditionsTransaction tr(lcdd, e); - DetElement top = lcdd.world(); - (DD4hep::Converter<DD4hep::conditions>(lcdd,&top))(e); - return 1; + /** Convert objects containing standard conditions tags + * + * Function entry expects as a parameter a valid DetElement handle + * pointing to the subdetector, which detector elements should be + * realigned. A absolute or relative DetElement path may be supplied by + * the element as an attribute: + * + * <conditions path="/world/TPC/TPC_SideA/TPC_SideA_sector02"> + * ... + * </conditions> + * + * @author M.Frank + * @version 1.0 + * @date 01/04/2014 + */ + template <> void Converter<conditions>::operator()(xml_h e) const { + ConversionArg* arg = _getArgs(param); + DetElement elt = arg->detector; + arg->detector = _getDetector(param,e); + xml_coll_t(e,_U(star)).for_each(Converter<arbitrary>(lcdd,param)); + arg->detector = elt; + } } -DECLARE_XML_DOC_READER(conditions,setup_Conditions) -/** Basic entry point to install the conditions handler in a LCDD instance +/** Basic entry point to read conditions files * * @author M.Frank * @version 1.0 * @date 01/04/2014 */ -static long install_Conditions(lcdd_t& lcdd, int, char**) { - ConditionsHandler::install(lcdd); - return 1; +static void* setup_Conditions(lcdd_t& lcdd, int argc, char** argv) { + if ( argc == 2 ) { + xml_h e = xml_h::Elt_t(argv[0]); + ConditionsStack* stack = (ConditionsStack*)argv[1]; + ConversionArg args(lcdd.world(), stack); + (DD4hep::Converter<DD4hep::conditions>(lcdd,&args))(e); + return &lcdd; + } + except("XML_DOC_READER","Invalid number of arguments to interprete conditions."); + return 0; } -DECLARE_APPLY(DD4hepConditionsInstall,install_Conditions) +DECLARE_LCDD_CONSTRUCTOR(XMLConditionsParser,setup_Conditions) diff --git a/DDCond/src/ConditionsPool.cpp b/DDCond/src/ConditionsPool.cpp new file mode 100644 index 000000000..df9aadebf --- /dev/null +++ b/DDCond/src/ConditionsPool.cpp @@ -0,0 +1,76 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include "DD4hep/Handle.inl" +#include "DD4hep/InstanceCount.h" +#include "DD4hep/objects/ConditionsInterna.h" + +#include "DDCond/ConditionsPool.h" +#include "DDCond/ConditionsEntry.h" + +using std::string; +using namespace DD4hep::Conditions; + +DD4HEP_INSTANTIATE_HANDLE_NAMED(ConditionsPool); + +/// Default constructor +ConditionsPool::ConditionsPool() + : NamedObject(), iovType(0), iov(0), updates(0), age_value(AGE_NONE) +{ + InstanceCount::increment(this); +} + +/// Default destructor +ConditionsPool::~ConditionsPool() { + DD4hep::deletePtr(updates); + // Should, but cannot clear here, since clear is a virtual overload. + InstanceCount::decrement(this); +} + +/// Unconditionally create a new condition from the input data +Condition ConditionsPool::create(ConditionsPool* pool, const Entry* entry) { + Condition condition(entry->name,entry->type); + Condition::Object* c = condition.ptr(); + //c->name = entry->name; + // c->type = entry->type; + c->value = entry->value; + c->comment = "----"; + c->address = "----"; + c->validity = entry->validity; + c->detector = entry->detector; + c->iov = pool->iov; + c->pool = pool; + return c; +} + +/// Insert a set of conditions +RangeConditions& conditions(); + +/// Default constructor +UpdatePool::UpdatePool() : ConditionsPool() +{ +} + +/// Default destructor +UpdatePool::~UpdatePool() { +} + +/// Default constructor +ReplacementPool::ReplacementPool() : ConditionsPool() { +} + +/// Default destructor. +ReplacementPool::~ReplacementPool() { +} diff --git a/DDCond/src/ConditionsStack.cpp b/DDCond/src/ConditionsStack.cpp deleted file mode 100644 index 6e75c3808..000000000 --- a/DDCond/src/ConditionsStack.cpp +++ /dev/null @@ -1,116 +0,0 @@ -// $Id: $ -//========================================================================== -// AIDA Detector description implementation for LCD -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see $DD4hepINSTALL/LICENSE. -// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. -// -// Author : M.Frank -// -//========================================================================== - -// Framework include files -#include "DD4hep/Printout.h" -#include "DD4hep/InstanceCount.h" -#include "DDCond/ConditionsStack.h" -#include "DD4hep/objects/ConditionsInterna.h" - -using namespace std; -using namespace DD4hep; -using namespace DD4hep::Geometry; - -static dd4hep_ptr<ConditionsStack>& _stack() { - static dd4hep_ptr<ConditionsStack> s; - return s; -} -static dd4hep_ptr<ConditionsStack>& _stack(ConditionsStack* obj) { - dd4hep_ptr<ConditionsStack>& s = _stack(); - dd4hep_ptr<ConditionsStack> n(obj); - s = n; - return s; -} - -/// Standard constructor -ConditionsStack::ConditionsStack() { - InstanceCount::increment(this); -} - -/// Standard destructor -ConditionsStack::~ConditionsStack() { - destroyObjects(m_stack)(); - InstanceCount::decrement(this); -} - -/// Static client accessor -ConditionsStack& ConditionsStack::get() { - if ( _stack().get() ) return *_stack(); - throw runtime_error("ConditionsStack> Stack not allocated -- may not be retrieved!"); -} - -/// Create an conditions stack instance. The creation of a second instance will be refused. -void ConditionsStack::create() { - if ( _stack().get() ) { - throw runtime_error("ConditionsStack> Stack already allocated. Multiple copies are not allowed!"); - } - _stack(new ConditionsStack()); -} - -/// Check existence of conditions stack -bool ConditionsStack::exists() { - return _stack().get() != 0; -} - -/// Clear data content and remove the slignment stack -void ConditionsStack::release() { - if ( _stack().get() ) { - _stack(0); - return; - } - throw runtime_error("ConditionsStack> Attempt to delete non existing stack."); -} - -/// Retrieve an conditions entry of the current stack -dd4hep_ptr<ConditionsStack::Entry> ConditionsStack::pop() { - Stack::iterator i = m_stack.begin(); - if ( i != m_stack.end() ) { - dd4hep_ptr<ConditionsStack::Entry> e((*i).second); - m_stack.erase(i); - return e; - } - throw runtime_error("ConditionsStack> pop: Conditions stack is empty. Check size first!"); -} - -/// Get all pathes to be aligned -vector<const ConditionsStack::Entry*> ConditionsStack::entries() const { - vector<const ConditionsStack::Entry*> result; - result.reserve(m_stack.size()); - for(Stack::const_iterator i=m_stack.begin(); i != m_stack.end(); ++i) - result.push_back((*i).second); - return result; -} - -/// Push new entry into the stack -void ConditionsStack::insert(dd4hep_ptr<Entry>& data) { - if ( data.get() && !data->name.empty() ) { - DetElement det = data->detector; - // Need to make some checks BEFORE insertion - if ( !det.isValid() ) { - throw runtime_error("ConditionsStack> Invalid conditions data [No such detector]"); - } - string path = det.path()+'!'+data->name; - Stack::const_iterator i = m_stack.find(path); - printout(DEBUG,"ConditionsStack","+++ %s name:%s type:%s value:%s Validity:%s", - det.path().c_str(), data->name.c_str(), data->type.c_str(), - data->value.c_str(), data->validity.c_str()); - if ( i == m_stack.end() ) { - m_stack.insert(make_pair(path,data.release())); - return; - } - throw runtime_error("ConditionsStack> The data with path "+path+ - " cannot be set twice in one transaction. [Intended inhibit]"); - } - throw runtime_error("ConditionsStack> Attempt to apply an invalid conditions data."); -} diff --git a/DDCond/src/ConditionsTest.cpp b/DDCond/src/ConditionsTest.cpp new file mode 100644 index 000000000..f4aa8128e --- /dev/null +++ b/DDCond/src/ConditionsTest.cpp @@ -0,0 +1,233 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include "DD4hep/DetectorTools.h" +#include "ConditionsTest.h" +#include <vector> + +using namespace std; +using namespace DD4hep::Conditions; + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Conditions { + + /// Namespace for test environments in DDCond + namespace Test { + + template <typename T> void print_bound_condition(Condition c, const char* norm) {} + + template<typename T> void __print_bound_val(Condition c, const char* norm, const char* fmt) { + const char* test = c.detector().name(); + char text_format[1024]; + c.bind<T>(); + T value = c.get<T>(); + if ( norm ) { + T val = _multiply(c.get<T>(),norm); + ::snprintf(text_format,sizeof(text_format)," Bound value %%s : value:%s [%s] Type: %%s",fmt,fmt); + printout(INFO,test,text_format, c.name().c_str(), value, val, typeName(c.typeInfo()).c_str()); + return; + } + ::snprintf(text_format,sizeof(text_format)," Bound value %%s : value:%s Type: %%s",fmt); + printout(INFO,test,text_format, c.name().c_str(), value, typeName(c.typeInfo()).c_str()); + } + + template <> void print_bound_value<string>(Condition c, const char*) { + const char* test = c.detector().name(); + c.bind<string>(); + printout(INFO,test," Bound value %s : string value:%s Type: %s", + c.name().c_str(), c.get<string>().c_str(),typeName(c.typeInfo()).c_str()); + } + + template <> void print_bound_value<short>(Condition c, const char* norm) + { __print_bound_val<short>(c, norm, "%d"); } + + template <> void print_bound_value<int>(Condition c, const char* norm) + { __print_bound_val<int>(c, norm, "%d"); } + + template <> void print_bound_value<long>(Condition c, const char* norm) + { __print_bound_val<long>(c, norm, "%d"); } + + template <> void print_bound_value<unsigned short>(Condition c, const char* norm) + { __print_bound_val<unsigned short>(c, norm, "%d"); } + + template <> void print_bound_value<unsigned int>(Condition c, const char* norm) + { __print_bound_val<unsigned int>(c, norm, "%d"); } + + template <> void print_bound_value<unsigned long>(Condition c, const char* norm) + { __print_bound_val<unsigned long>(c, norm, "%d"); } + + template <> void print_bound_value<float>(Condition c, const char* norm) + { __print_bound_val<float>(c, norm, "%g"); } + + template <> void print_bound_value<double>(Condition c, const char* norm) + { __print_bound_val<double>(c, norm, "%g"); } + + template <> void print_bound_value<vector<double> >(Condition c, const char*) { + const char* test = c.detector().name(); + c.bind<vector<double> >(); + const vector<double>& v = c.get<vector<double> >(); + printout(INFO,test," Bound value %s : size:%d = %s Type: %s", + c.name().c_str(), int(v.size()), c.block().str().c_str(), + typeName(c.typeInfo()).c_str()); + } + + template <> void print_condition<void>(Condition c) { + const char* test = c.detector().name(); + string type = c.type(); + printout(INFO,test,"%-32s [%16s] : %s [%s] ", + (c.detector().path()+"."+c.name()).c_str(),c.type().c_str(), + c.value().c_str(),c.validity().c_str()); + if ( type == "alignment" ) + print_bound_value<string>(c); + else if ( type == "temperature" ) + print_bound_value<double>(c); + else if ( type == "pressure" ) + print_bound_value<double>(c,"1.0/hPa"); + else if ( type == "whatever" ) + print_bound_value<vector<double> >(c); + else if ( type == "short" ) + print_bound_value<short>(c); + else if ( type == "integer" ) + print_bound_value<int>(c); + else if ( type == "long" ) + print_bound_value<long>(c); + else if ( type == "unsigned short" ) + print_bound_value<unsigned short>(c); + else if ( type == "unsigned integer" ) + print_bound_value<unsigned int>(c); + else if ( type == "unsigned long" ) + print_bound_value<unsigned long>(c); + else if ( type == "double" ) + print_bound_value<double>(c); + else if ( type == "double" ) + print_bound_value<double>(c); + else if ( type == "vector<double>" ) + print_bound_value<vector<double> >(c); + } + + template <typename T> void print_conditions(const RangeConditions& rc) { + for(RangeConditions::const_iterator k=rc.begin(); k != rc.end(); ++k) + print_condition<T>(*k); + } + + template void print_conditions<void>(const RangeConditions& rc); + + + void check_discrete_condition(Condition c, const IOV& iov) { + const IOV* i = c->iov; + if ( i->is_discrete() ) { + if ( iov.contains(*i) ) { + return; + } + except("Example", "+++ The condition %s.%s [%s] is not fully contained in iov:%s", + c->detector.path().c_str(), c->name.c_str(), i->str().c_str(), iov.str().c_str()); + } + except("Example", "+++ The condition %s.%s [%s] has no discrete type matching iov:%s", + c->detector.path().c_str(), c->name.c_str(), i->str().c_str(), iov.str().c_str()); + } + } + } +} + +Test::TestEnv::TestEnv(LCDD& _lcdd, const string& detector_name) + : lcdd(_lcdd), detector(), manager() +{ + manager = ConditionsManager::from(lcdd); + manager["LoaderType"] = "multi"; + manager["PoolType"] = "DD4hep_ConditionsLinearPool"; + manager["UpdatePoolType"] = "DD4hep_ConditionsLinearUpdatePool"; + manager["ReplacementPoolType"] = "DD4hep_ConditionsLinearReplacementPool"; + manager->initialize(); + detector = lcdd.detector(detector_name); + if ( detector.isValid() ) { + pair<bool, const IOVType*> e = manager.registerIOVType(0, "epoch"); + pair<bool, const IOVType*> r = manager.registerIOVType(1, "run"); + loader = manager.loader(); + if ( e.first && r.first ) { + epoch = e.second; + run = r.second; + return; + } + invalidHandleError<IOVType>(); + } + invalidHandleError<DetElement>(); +} + +/// Find daughter element of the detector object +DetElement Test::TestEnv::daughter(const string& sub_path) const { + return DD4hep::Geometry::DetectorTools::findDaughterElement(detector,sub_path); +} + +void Test::TestEnv::add_xml_data_source(const string& file) { + string source = "xml:"+string(::getenv("DD4hepINSTALL"))+file; + this->loader->addSource(source); +} + + +void Test::TestEnv::dump_conditions_pools() +{ + typedef RangeConditions _R; + typedef IOVPool::Entries _E; + typedef Interna::ConditionsManagerObject::TypedConditionPool _P; + int cnt = 0; + _P& p = this->manager->m_pool; + for(_P::const_iterator i=p.begin(); i != p.end(); ++i, ++cnt) { + IOVPool* pool = (*i); + if ( pool ) { + const _E& e = pool->entries; + const IOVType* typ = this->manager->iovType(cnt); + printout(INFO,"Example","+++ IOVPool for type %s", typ->str().c_str()); + for (_E::const_iterator j=e.begin(); j != e.end(); ++j) { + _R rc; + ConditionsPool* cp = (*j).second; + cp->select_all(rc); + printout(INFO,"Example","+++ Conditions for pool with IOV: %s age:%d", + cp->iov->str().c_str(), cp->age_value); + print_conditions<void>(rc); + } + } + } + printout(INFO,"Example","SUCCESS: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + printout(INFO,"Example","SUCCESS: +++ Conditions pools successfully dumped"); + printout(INFO,"Example","SUCCESS: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); +} + +/// Dump the conditions of one detectpr element +void Test::TestEnv::dump_detector_element(DetElement elt) +{ + Container conds = elt.conditions(); + printout(INFO,"conditions","DetElement:%s # of conditons:%d",elt.path().c_str(),int(conds.count())); + const Container::Entries& entries = conds.entries(); + for(Container::Entries::const_iterator i=entries.begin(); i!=entries.end(); ++i) { + Condition cond((*i).second); + print_condition<void>(cond); + } +} + +/// Dump conditions tree of a detector element +void Test::TestEnv::dump_conditions_tree(DetElement elt) +{ + Container conds = elt.conditions(); + const DetElement::Children& children = elt.children(); + if ( !conds.isValid() ) + printout(INFO,"conditions_tree","DetElement:%s NO CONDITIONS present",elt.path().c_str()); + else + dump_detector_element(elt); + for(DetElement::Children::const_iterator j=children.begin(); j!=children.end(); ++j) + dump_conditions_tree((*j).second); +} diff --git a/DDCond/src/ConditionsTest.h b/DDCond/src/ConditionsTest.h new file mode 100644 index 000000000..6ee5128d8 --- /dev/null +++ b/DDCond/src/ConditionsTest.h @@ -0,0 +1,65 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +#ifndef DDCOND_CONDITIONSTEST_H +#define DDCOND_CONDITIONSTEST_H + +// Framework include files +#include "DD4hep/LCDD.h" +#include "DD4hep/Printout.h" +#include "DD4hep/Conditions.h" +#include "DD4hep/DetFactoryHelper.h" + +#include "DDCond/ConditionsManager.h" +#include "DDCond/ConditionsInterna.h" + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Conditions { + + /// Namespace for test environments in DDCond + namespace Test { + + using Geometry::LCDD; + using Geometry::Position; + using Geometry::DetElement; + + struct TestEnv { + LCDD& lcdd; + DetElement detector; + ConditionsManager manager; + Handle<ConditionsDataLoader> loader; + const IOVType* epoch; + const IOVType* run; + + TestEnv(LCDD& _lcdd, const std::string& detector_name); + /// Find daughter element of the detector object + DetElement daughter(const std::string& sub_path) const; + + void add_xml_data_source(const std::string& file); + void dump_conditions_pools(); + static void dump_detector_element(DetElement elt); + static void dump_conditions_tree(DetElement elt); + + }; + + template <typename T> void print_condition(Condition condition); + template <typename T> void print_bound_value(Condition condition, const char* norm=0); + template <typename T> void print_conditions(const RangeConditions& rc); + void check_discrete_condition(Condition c, const IOV& iov); + } + } +} +#endif // DDCOND_CONDITIONSTEST_H diff --git a/DDCond/src/ConditionsTransaction.cpp b/DDCond/src/ConditionsTransaction.cpp deleted file mode 100644 index 3247263c9..000000000 --- a/DDCond/src/ConditionsTransaction.cpp +++ /dev/null @@ -1,41 +0,0 @@ -// $Id: $ -//========================================================================== -// AIDA Detector description implementation for LCD -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see $DD4hepINSTALL/LICENSE. -// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. -// -// Author : M.Frank -// -//========================================================================== - -// Framework include files -#include "DD4hep/LCDD.h" -#include "DDCond/ConditionsTags.h" -#include "DDCond/ConditionsHandler.h" -#include "DDCond/ConditionsTransaction.h" - -using namespace DD4hep; -using namespace DD4hep::Geometry; - -/// Default constructor -ConditionsTransaction::ConditionsTransaction(LCDD& l, const XML::Handle_t& e) : lcdd(l) { - flag = e.hasChild(_U(close_transaction)); - /// First check if a transaction is to be opened - m_handler = lcdd.extension<Geometry::ConditionsHandler>(); - m_handler->addRef(); - if ( e.hasChild(_U(open_transaction)) ) { - m_handler->openTransaction(); - } -} -/// Default destructor -ConditionsTransaction::~ConditionsTransaction() { - /// Last check if a transaction is to be closed - if ( flag ) { - lcdd.extension<Geometry::ConditionsHandler>()->closeTransaction(); - } - m_handler->release(); -} diff --git a/DDCond/src/ConditionsXmlLoader.cpp b/DDCond/src/ConditionsXmlLoader.cpp new file mode 100644 index 000000000..06febf215 --- /dev/null +++ b/DDCond/src/ConditionsXmlLoader.cpp @@ -0,0 +1,186 @@ +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// \author Markus Frank +// \date 2016-02-02 +// \version 1.0 +// +//========================================================================== +// $Id$ +#ifndef DD4HEP_CONDITIONS_XMLCONDITONSLOADER_H +#define DD4HEP_CONDITIONS_XMLCONDITONSLOADER_H + +// Framework include files +#include "DDCond/ConditionsDataLoader.h" + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Conditions { + + /// Implementation of a stack of conditions assembled before application + /** + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class ConditionsXmlLoader : public ConditionsDataLoader { + typedef std::vector<Condition> Buffer; + Buffer m_buffer; + + public: + /// Default constructor + ConditionsXmlLoader(LCDD& lcdd, ConditionsManager mgr, const std::string& nam); + /// Default destructor + virtual ~ConditionsXmlLoader(); + /// Load a condition set given a Detector Element and the conditions name according to their validity + virtual size_t load(DetElement det, + const std::string& cond, + const IOV& req_validity, + RangeConditions& conditions); + /// Load a condition set given a Detector Element and the conditions name according to their validity + virtual size_t load_range(DetElement det, + const std::string& cond, + const IOV& req_validity, + RangeConditions& conditions); + size_t load_source (const std::string& nam, + DetElement det, + const std::string& cond, + const IOV& req_validity, + RangeConditions& conditions); + }; + + } /* End namespace Geometry */ +} /* End namespace DD4hep */ + +#endif /* DD4HEP_CONDITIONS_XMLCONDITONSLOADER_H */ + +//#include "ConditionsXmlLoader.h" +#include "DD4hep/Printout.h" +#include "DD4hep/Factories.h" +#include "DD4hep/PluginCreators.h" +#include "XML/XMLElements.h" +#include "XML/DocumentHandler.h" +#include "DDCond/ConditionsInterna.h" +#include "DDCond/ConditionsEntry.h" + +// C/C++ include files +#include <string> + +// Forward declartions +using std::string; +using namespace DD4hep; +using namespace DD4hep::Conditions; + +namespace { + void* create_loader(DD4hep::Geometry::LCDD& lcdd, int argc, char** argv) { + const char* name = argc>0 ? argv[0] : "XMLLoader"; + Interna::ConditionsManagerObject* mgr = (Interna::ConditionsManagerObject*)(argc>0 ? argv[1] : 0); + return new ConditionsXmlLoader(lcdd,ConditionsManager(mgr),name); + } +} +DECLARE_LCDD_CONSTRUCTOR(DD4hep_Conditions_xml_Loader,create_loader) + +/// Standard constructor, initializes variables +ConditionsXmlLoader::ConditionsXmlLoader(LCDD& lcdd, ConditionsManager mgr, const std::string& nam) +: ConditionsDataLoader(lcdd, mgr, nam) +{ +} + +/// Default Destructor +ConditionsXmlLoader::~ConditionsXmlLoader() { +} + +size_t ConditionsXmlLoader::load_source(const std::string& nam, + DetElement det, + const std::string& cond, + const IOV& req_validity, + RangeConditions& conditions) +{ + size_t len = conditions.size(); + string fac = "XMLConditionsParser"; + XML::DocumentHolder doc(XML::DocumentHandler().load(nam)); + XML::Handle_t handle = doc.root(); + ConditionsStack stack; + char* argv[] = { (char*)handle.ptr(), (char*)&stack, 0}; + void* result = DD4hep::createPlugin(fac, m_lcdd, 2, argv, 0); + if ( result == &m_lcdd ) { // All OK. + for (ConditionsStack::iterator c=stack.begin(); c!=stack.end(); ++c) { + Entry* e = (*c); + Condition condition = queueUpdate(e); + delete e; + if ( condition.isValid() ) { + if ( det == condition.detector() && cond == condition.name() ) { + if ( req_validity.contains(condition.iov()) ) { + conditions.push_back(condition); + continue; + } + } + m_buffer.push_back(condition); + } + } + } + m_sources.erase(m_sources.begin()); + stack.clear(); + return conditions.size()-len; +} + +size_t ConditionsXmlLoader::load(DetElement det, + const std::string& cond, + const IOV& req_validity, + RangeConditions& conditions) +{ + size_t len = conditions.size(); + if ( m_buffer.empty() && !m_sources.empty() ) { + return load_source(*(m_sources.begin()), det, cond, req_validity, conditions); + } + for (Buffer::iterator j=m_buffer.begin(); j!=m_buffer.end(); ++j) { + Condition condition = *j; + if ( det == condition->detector && cond == condition->name ) { + if ( req_validity.contains(*condition->iov) ) { + conditions.push_back(condition); + m_buffer.erase(j); + return conditions.size()-len; + } + } + } + if ( !m_sources.empty() ) { + return load_source(*(m_sources.begin()), det, cond, req_validity, conditions); + } + return conditions.size()-len; +} + +size_t ConditionsXmlLoader::load_range(DetElement det, + const std::string& cond, + const IOV& req_validity, + RangeConditions& conditions) +{ + size_t len = conditions.size(); + while ( !m_sources.empty() ) { + load_source(*(m_sources.begin()), det, cond, req_validity, conditions); + } + std::vector<Condition> keep; + for (size_t j=0; j<m_buffer.size(); ++j) { + Condition condition = m_buffer[j]; + if ( det == condition->detector && cond == condition->name ) { + const IOV* iov = condition->iov; + if ( IOV::same_type(req_validity,*iov) ) { + if ( IOV::key_is_contained(req_validity.key(),iov->key()) || + IOV::key_overlaps_lower_end(req_validity.key(),iov->key()) || + IOV::key_overlaps_higher_end(req_validity.key(),iov->key()) ) { + conditions.push_back(condition); + continue; + } + } + } + keep.push_back(condition); + } + m_buffer = keep; + return conditions.size()-len; +} diff --git a/DDG4/include/DDG4/ComponentProperties.h b/DDCore/include/DD4hep/ComponentProperties.h similarity index 85% rename from DDG4/include/DDG4/ComponentProperties.h rename to DDCore/include/DD4hep/ComponentProperties.h index 488acaa8d..e757b3519 100644 --- a/DDG4/include/DDG4/ComponentProperties.h +++ b/DDCore/include/DD4hep/ComponentProperties.h @@ -1,4 +1,4 @@ -// $Id: $ +// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- @@ -16,7 +16,8 @@ #define DD4HEP_DDG4_COMPONENTPROPERTIES_H // Framework include files -#include "DDG4/ComponentUtils.h" +#include "DD4hep/Primitives.h" +#include "DD4hep/Exceptions.h" // C/C++ include files #include <algorithm> @@ -232,6 +233,46 @@ namespace DD4hep { void dump() const; }; -} // End namespace DD4hep + /// Property object as base class for all objects supporting properties + /** + * \author M.Frank + * \version 1.0 + */ + class PropertyConfigurable { + protected: + /// Property pool + PropertyManager m_properties; + + public: + /// Standard constructor + PropertyConfigurable(); + /// Default destructor + virtual ~PropertyConfigurable(); + /// Access to the properties of the object + PropertyManager& properties() { + return m_properties; + } + /// Check property for existence + bool hasProperty(const std::string& name) const; + /// Access single property + Property& property(const std::string& name); + /// Declare property + template <typename T> void declareProperty(const std::string& nam, T& val); + /// Declare property + template <typename T> void declareProperty(const char* nam, T& val); + }; + /// Declare property + template <typename T> + void PropertyConfigurable::declareProperty(const std::string& nam, T& val) { + m_properties.add(nam, val); + } + + /// Declare property + template <typename T> + void PropertyConfigurable::declareProperty(const char* nam, T& val) { + m_properties.add(nam, val); + } + +} // End namespace DD4hep #endif // DD4HEP_DDG4_COMPONENTPROPERTIES_H diff --git a/DDG4/include/DDG4/ComponentProperties_inl.h b/DDCore/include/DD4hep/ComponentProperties_inl.h similarity index 98% rename from DDG4/include/DDG4/ComponentProperties_inl.h rename to DDCore/include/DD4hep/ComponentProperties_inl.h index f75708de6..587fb0d95 100644 --- a/DDG4/include/DDG4/ComponentProperties_inl.h +++ b/DDCore/include/DD4hep/ComponentProperties_inl.h @@ -1,4 +1,4 @@ -// $Id: $ +// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- @@ -16,7 +16,7 @@ // Framework include files #include "DD4hep/BasicGrammar.h" -#include "DDG4/ComponentProperties.h" +#include "DD4hep/ComponentProperties.h" // C/C++ include files #include <sstream> diff --git a/DDCore/include/DD4hep/Conditions.h b/DDCore/include/DD4hep/Conditions.h index 70e0338a4..94a2f47d9 100644 --- a/DDCore/include/DD4hep/Conditions.h +++ b/DDCore/include/DD4hep/Conditions.h @@ -17,6 +17,9 @@ // Framework include files #include "DD4hep/Handle.h" +// C/C++ include files +#include <vector> + /// Namespace for the AIDA detector description toolkit namespace DD4hep { @@ -25,18 +28,99 @@ namespace DD4hep { /// Namespace for the geometry part of the AIDA detector description toolkit namespace Geometry { - // Forward declarations class DetElement; + class LCDD; + } + + /// Namespace for the conditions part of the AIDA detector description toolkit + namespace Conditions { + + // The DetElement is a central object. We alias it here. + using Geometry::DetElement; + using Geometry::LCDD; + + // Forward declarations + class ConditionsManager; + class ConditionsLoader; + class IOVType; + class IOV; /// Conditions intrnal namespace - namespace ConditionsInterna { + namespace Interna { class ConditionContainer; class ConditionObject; - class Entry; - class IOV; } + class IOVType { + public: + enum { UNKNOWN_IOV = ~0x0 } _IOVTypes; + + unsigned int type; + std::string name; + IOVType() : type(UNKNOWN_IOV), name() {} + ~IOVType() {} + std::string str() const; + }; + + /// Class describing the interval of validty + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class IOV { + friend class Condition; + private: + /// No IOC copies! + explicit IOV(const IOV&) {} + /// Initializing constructor: Does not set reference to IOVType ! + explicit IOV(); + public: + /// Key definition + typedef std::pair<int,int> Key; + + const IOVType* iovType; + Key keyData; + int optData; + /// IOV buffer type: Must be a bitmap! + unsigned int type; + + /// Initializing constructor + explicit IOV(const IOVType* typ); + /// Standard Destructor + ~IOV(); + /// Move the data content: 'from' will be reset to NULL + void move(IOV& from); + /// Create string representation of the IOV + std::string str() const; + /// Check if the IOV corresponds to a range + bool has_range() const { return keyData.first != keyData.second; } + /// Check if the IOV corresponds to a range + bool is_discrete() const { return keyData.first == keyData.second; } + /// Get the local key of the IOV + Key key() const { return keyData; } + /// Check for validity containment + /** Check if the caller 'iov' is of the same type and the range + * is fully conained by the caller. + */ + bool contains(const IOV& iov) const; + static bool same_type(const IOV& iov, const IOV& test) { + unsigned int typ1 = iov.iovType ? iov.iovType->type : iov.type; + unsigned int typ2 = test.iovType ? test.iovType->type : test.type; + return typ1 == typ2; + } + static bool key_is_contained(const IOV::Key& key, const IOV::Key& test) + { return key.first >= test.first && key.second <= test.second; } + static bool key_overlaps_lower_end(const IOV::Key& key, const IOV::Key& test) + { return key.first <= test.second && key.first >= test.first; } + static bool key_overlaps_higher_end(const IOV::Key& key, const IOV::Key& test) + { return key.second >= test.first && key.second <= test.second; } + + }; + + /// Class describing an opaque conditions data block /** * Access methods are templated. Once the access is fixed @@ -44,23 +128,25 @@ namespace DD4hep { * * \author M.Frank * \version 1.0 - * \ingroup DD4HEP_GEOMETRY * \ingroup DD4HEP_CONDITIONS */ class Block { /// Access only through the conditions class! friend class Condition; + private: protected: /// Standard initializing constructor Block(); /// Standard Destructor virtual ~Block(); + protected: /// Data type const BasicGrammar* grammar; /// Pointer to object data void* pointer; + public: /// Create data block from string representation void fromString(const std::string& rep); @@ -79,15 +165,13 @@ namespace DD4hep { * * \author M.Frank * \version 1.0 - * \ingroup DD4HEP_GEOMETRY * \ingroup DD4HEP_CONDITIONS */ - class Condition: public Handle<ConditionsInterna::ConditionObject> { + class Condition: public Handle<Interna::ConditionObject> { public: - typedef ConditionsInterna::ConditionObject Object; - typedef ConditionsInterna::Entry Entry; - typedef ConditionsInterna::IOV IOV; + typedef Interna::ConditionObject Object; + public: /// Default constructor Condition(); /// Copy constructor @@ -99,7 +183,7 @@ namespace DD4hep { : Handle<Object>(e) { } /// Initializing constructor - Condition(const std::string& name); + Condition(const std::string& name, const std::string& type); /// Assignment operator Condition& operator=(const Condition& c); @@ -111,9 +195,9 @@ namespace DD4hep { /** Interval of validity */ /// Access the IOV type - int iovType() const; + const IOVType& iovType() const; /// Access the IOV block - IOV& iov() const; + const IOV& iov() const; /** Direct data items in string form */ /// Access the name of the condition @@ -129,8 +213,7 @@ namespace DD4hep { /// Access the address string [e.g. database identifier] const std::string& address() const; /// Access the hosting detector element - DetElement detector() const; - + Geometry::DetElement detector() const; /** Conditions meta-data */ /// Access to the type information @@ -139,8 +222,6 @@ namespace DD4hep { const BasicGrammar& descriptor() const; /** Conditions handling */ - /// Replace the data block of the condition with a new value. Free old data - Condition& replace(Entry* new_condition); /// Re-evaluate the conditions data according to the previous bound type definition Condition& rebind(); @@ -176,49 +257,44 @@ namespace DD4hep { * * \author M.Frank * \version 1.0 - * \ingroup DD4HEP_GEOMETRY * \ingroup DD4HEP_CONDITIONS */ - class Conditions : public Handle<ConditionsInterna::ConditionContainer> { + class Container : public Handle<Interna::ConditionContainer> { public: /// Standard object type - typedef ConditionsInterna::ConditionContainer Object; - /// Local helper definition - typedef ConditionsInterna::Entry Entry; - + typedef Interna::ConditionContainer Object; /// Definition of the conditions container of this detector element - typedef std::map<std::string, Condition> Entries; + //typedef std::map<std::string, Condition> Entries; + typedef std::map<int, Condition> Entries; + public: /// Default constructor - Conditions(); + Container(); /// Constructor to be used when reading the already parsed object - template <typename Q> Conditions(const Conditions& c) - : Handle<Object>(c) { - } + template <typename Q> Container(const Container& c) : Handle<Object>(c) {} /// Constructor to be used when reading the already parsed object - template <typename Q> Conditions(const Handle<Q>& e) - : Handle<Object>(e) { - } + template <typename Q> Container(const Handle<Q>& e) : Handle<Object>(e) {} /// Access the number of conditons available for this detector element size_t count() const; /// Access the full map of conditons Entries& entries() const; - /// Clear all conditions. Auto-delete of all existing entries + /// Clear all attached DetElement conditions. void removeElements() const; - /** Set a single conditions value (eventually existing entries are overwritten) - * Note: Passing a valid handle also passes ownership!!! - * - * Failure return 0 in case an invalid handle is present - * Successful insertion returns 1 - * Successful overwriting an existing value returns 3 - */ - int set(Entry* data); + /// Access to condition objects. No loading undertaken. The condition must be present + Condition operator[](const std::string& key); + /// Access to condition objects directly by their hash key. + /// No loading undertaken. The condition must be present + Condition operator[](int hash_key); }; /// Default constructor - inline Conditions::Conditions() : Handle<Object>() { + inline Container::Container() : Handle<Object>() { } - } /* End namespace Geometry */ + // Utility type definitions + typedef std::vector<Condition> RangeConditions; + typedef std::pair<RangeConditions,bool> RangeStatus; + + } /* End namespace Conditions */ } /* End namespace DD4hep */ #endif /* DD4HEP_GEOMETRY_CONDITION_H */ diff --git a/DDCore/include/DD4hep/Detector.h b/DDCore/include/DD4hep/Detector.h index d54c285e0..90d7c95b9 100644 --- a/DDCore/include/DD4hep/Detector.h +++ b/DDCore/include/DD4hep/Detector.h @@ -196,6 +196,9 @@ namespace DD4hep { /// Extensions destructor type typedef void (*destruct_t)(void*); + typedef Conditions::IOV IOV; + typedef Conditions::Condition Condition; + typedef Conditions::Container ConditionsContainer; typedef std::map<std::string, DetElement> Children; typedef std::map<const std::type_info*, void*> Extensions; @@ -237,27 +240,19 @@ namespace DD4hep { public: /// Default constructor - DetElement() - : RefObject() { - } + DetElement() : RefObject() { } /// Constructor to hold handled object - DetElement(Object* object_ptr) - : RefObject(object_ptr) { - } + DetElement(Object* object_ptr) : RefObject(object_ptr) { } /// Clone constructor DetElement(Object* data, const std::string& name, const std::string& type); /// Templated constructor for handle conversions - template <typename Q> DetElement(const Handle<Q>& e) - : RefObject(e) { - } + template <typename Q> DetElement(const Handle<Q>& e) : RefObject(e) {} /// Constructor to copy handle - DetElement(const DetElement& e) - : RefObject(e) { - } + DetElement(const DetElement& e) : RefObject(e) { } #ifdef __MAKECINT__ /// Constructor to copy handle @@ -381,7 +376,11 @@ namespace DD4hep { /// Access to the survey alignment information Alignment surveyAlignment() const; /// Access to the conditions information - Conditions conditions() const; + ConditionsContainer conditions() const; + /// Access to the conditions information. No loading undertaken. The condition must be present + Condition condition(const std::string& key) const; + /// Access to condition objects. If not present, load condition. + Condition condition(const std::string& key, const IOV& iov); /// Set detector element for reference transformations. Will delete existing reference trafo. DetElement& setReference(DetElement reference); diff --git a/DDCore/include/DD4hep/DetectorSelector.h b/DDCore/include/DD4hep/DetectorSelector.h index 6da55ecb0..e8d9221d0 100644 --- a/DDCore/include/DD4hep/DetectorSelector.h +++ b/DDCore/include/DD4hep/DetectorSelector.h @@ -47,12 +47,16 @@ namespace DD4hep { public: /// Result set definition typedef std::vector<DetElement> Result; +#ifndef __CINT__ /// Reference to main detector description object LCDD& lcdd; +#endif public: +#ifndef __CINT__ /// Default constructor DetectorSelector(LCDD& _lcdd) : lcdd(_lcdd) {} +#endif /// Default destructor ~DetectorSelector() {} diff --git a/DDCore/include/DD4hep/Dictionary.h b/DDCore/include/DD4hep/Dictionary.h index 547670943..1bedef44a 100644 --- a/DDCore/include/DD4hep/Dictionary.h +++ b/DDCore/include/DD4hep/Dictionary.h @@ -20,6 +20,7 @@ #define DD4HEP_GEOMETRY_DICTIONARY_H #include "XML/Evaluator.h" +#include "DD4hep/World.h" #include "DD4hep/LCDDData.h" #include "DD4hep/Conditions.h" #include "DD4hep/FieldTypes.h" @@ -63,33 +64,34 @@ using namespace std; #pragma link C++ namespace DD4hep; #pragma link C++ namespace DD4hep::Geometry; +#pragma link C++ namespace DD4hep::Conditions; #pragma link C++ namespace DD4hep::DDSegmentation; #ifndef __ROOTCLING__ template pair<unsigned int, string>; -template class DD4hep::Geometry::Handle<DD4hep::NamedObject>; -template class pair< string, DD4hep::Geometry::Handle<DD4hep::NamedObject> >; -template class map< string, DD4hep::Geometry::Handle<DD4hep::NamedObject> >; +template class DD4hep::Handle<DD4hep::NamedObject>; +template class pair< string, DD4hep::Handle<DD4hep::NamedObject> >; +template class map< string, DD4hep::Handle<DD4hep::NamedObject> >; #endif #pragma link C++ class pair<unsigned int,string>+; #pragma link C++ class DD4hep::NamedObject+; #pragma link C++ class DD4hep::Geometry::Ref_t+; -#pragma link C++ class DD4hep::Geometry::Handle<DD4hep::NamedObject>+; -#pragma link C++ class pair<string, DD4hep::Geometry::Handle<DD4hep::NamedObject> >+; -#pragma link C++ class map<string, DD4hep::Geometry::Handle<DD4hep::NamedObject> >+; -#pragma link C++ class map<string, DD4hep::Geometry::Handle<DD4hep::NamedObject> >::iterator; -#pragma link C++ class map<string, DD4hep::Geometry::Handle<DD4hep::NamedObject> >::const_iterator; +#pragma link C++ class DD4hep::Handle<DD4hep::NamedObject>+; +#pragma link C++ class pair<string, DD4hep::Handle<DD4hep::NamedObject> >+; +#pragma link C++ class map<string, DD4hep::Handle<DD4hep::NamedObject> >+; +#pragma link C++ class map<string, DD4hep::Handle<DD4hep::NamedObject> >::iterator; +#pragma link C++ class map<string, DD4hep::Handle<DD4hep::NamedObject> >::const_iterator; #ifdef R__MACOSX // We only need these declarations for the clang compiler -#pragma link C++ function operator==( const map<string, DD4hep::Geometry::Handle<DD4hep::NamedObject> >::iterator&,const map<string, DD4hep::Geometry::Handle<DD4hep::NamedObject> >::iterator& ); -#pragma link C++ function operator!=( const map<string, DD4hep::Geometry::Handle<DD4hep::NamedObject> >::iterator&,const map<string, DD4hep::Geometry::Handle<DD4hep::NamedObject> >::iterator& ); +#pragma link C++ function operator==( const map<string, DD4hep::Handle<DD4hep::NamedObject> >::iterator&,const map<string, DD4hep::Handle<DD4hep::NamedObject> >::iterator& ); +#pragma link C++ function operator!=( const map<string, DD4hep::Handle<DD4hep::NamedObject> >::iterator&,const map<string, DD4hep::Handle<DD4hep::NamedObject> >::iterator& ); #endif #pragma link C++ class DD4hep::ObjectExtensions+; -template class DD4hep::Geometry::Handle<TNamed>; -#pragma link C++ class DD4hep::Geometry::Handle<TNamed>+; +template class DD4hep::Handle<TNamed>; +#pragma link C++ class DD4hep::Handle<TNamed>+; #pragma link C++ class DD4hep::Geometry::LCDD+; #pragma link C++ class DD4hep::Geometry::LCDDData+; @@ -108,26 +110,26 @@ template class DD4hep::Geometry::Handle<TNamed>; #pragma link C++ class DD4hep::Geometry::VolumeManager+; #pragma link C++ class DD4hep::Geometry::VolumeManagerObject+; #pragma link C++ class DD4hep::Geometry::VolumeManagerContext+; -#pragma link C++ class DD4hep::Geometry::Handle<DD4hep::Geometry::VolumeManagerObject>+; +#pragma link C++ class DD4hep::Handle<DD4hep::Geometry::VolumeManagerObject>+; #pragma link C++ class DD4hep::Geometry::CartesianField+; #pragma link C++ class DD4hep::Geometry::CartesianField::Object+; -#pragma link C++ class DD4hep::Geometry::Handle<DD4hep::Geometry::CartesianField::Object>+; +#pragma link C++ class DD4hep::Handle<DD4hep::Geometry::CartesianField::Object>+; #pragma link C++ class DD4hep::Geometry::OverlayedField+; #pragma link C++ class DD4hep::Geometry::OverlayedField::Object+; -#pragma link C++ class DD4hep::Geometry::Handle<DD4hep::Geometry::OverlayedField::Object>+; +#pragma link C++ class DD4hep::Handle<DD4hep::Geometry::OverlayedField::Object>+; // FieldTypes.h #pragma link C++ class DD4hep::Geometry::ConstantField+; -#pragma link C++ class DD4hep::Geometry::Handle<DD4hep::Geometry::ConstantField>+; +#pragma link C++ class DD4hep::Handle<DD4hep::Geometry::ConstantField>+; #pragma link C++ class DD4hep::Geometry::SolenoidField+; -#pragma link C++ class DD4hep::Geometry::Handle<DD4hep::Geometry::SolenoidField>+; +#pragma link C++ class DD4hep::Handle<DD4hep::Geometry::SolenoidField>+; #pragma link C++ class DD4hep::Geometry::DipoleField+; -#pragma link C++ class DD4hep::Geometry::Handle<DD4hep::Geometry::DipoleField>+; +#pragma link C++ class DD4hep::Handle<DD4hep::Geometry::DipoleField>+; #pragma link C++ class DD4hep::Geometry::IDDescriptor+; #pragma link C++ class DD4hep::Geometry::IDDescriptorObject+; -#pragma link C++ class DD4hep::Geometry::Handle<DD4hep::Geometry::IDDescriptorObject>+; +#pragma link C++ class DD4hep::Handle<DD4hep::Geometry::IDDescriptorObject>+; // Objects.h #pragma link C++ class DD4hep::Geometry::Author+; @@ -135,25 +137,25 @@ template class DD4hep::Geometry::Handle<TNamed>; #pragma link C++ class DD4hep::Geometry::Header+; #pragma link C++ class DD4hep::Geometry::HeaderObject+; -#pragma link C++ class DD4hep::Geometry::Handle<DD4hep::Geometry::HeaderObject>+; +#pragma link C++ class DD4hep::Handle<DD4hep::Geometry::HeaderObject>+; #pragma link C++ class DD4hep::Geometry::Constant+; #pragma link C++ class DD4hep::Geometry::ConstantObject+; -#pragma link C++ class DD4hep::Geometry::Handle<DD4hep::Geometry::ConstantObject>+; +#pragma link C++ class DD4hep::Handle<DD4hep::Geometry::ConstantObject>+; #pragma link C++ class vector<DD4hep::Geometry::Constant>+; #pragma link C++ class DD4hep::Geometry::Atom+; #pragma link C++ class vector<DD4hep::Geometry::Atom>+; -#pragma link C++ class DD4hep::Geometry::Handle<TGeoElement>+; +#pragma link C++ class DD4hep::Handle<TGeoElement>+; #pragma link C++ class DD4hep::Geometry::Material+; #pragma link C++ class vector<DD4hep::Geometry::Material>+; -#pragma link C++ class DD4hep::Geometry::Handle<TGeoMedium>+; +#pragma link C++ class DD4hep::Handle<TGeoMedium>+; #pragma link C++ class DD4hep::Geometry::VisAttr+; #pragma link C++ class vector<DD4hep::Geometry::VisAttr>+; #pragma link C++ class DD4hep::Geometry::VisAttrObject+; -#pragma link C++ class DD4hep::Geometry::Handle<DD4hep::Geometry::VisAttrObject>+; +#pragma link C++ class DD4hep::Handle<DD4hep::Geometry::VisAttrObject>+; #pragma link C++ class DD4hep::Geometry::AlignmentEntry+; #pragma link C++ class DD4hep::Geometry::Limit+; @@ -162,39 +164,41 @@ template class DD4hep::Geometry::Handle<TNamed>; #pragma link C++ class DD4hep::Geometry::LimitSet+; #pragma link C++ class vector<DD4hep::Geometry::LimitSet>+; #pragma link C++ class DD4hep::Geometry::LimitSetObject+; -#pragma link C++ class DD4hep::Geometry::Handle<DD4hep::Geometry::LimitSetObject>+; +#pragma link C++ class DD4hep::Handle<DD4hep::Geometry::LimitSetObject>+; #pragma link C++ class DD4hep::Geometry::Region+; #pragma link C++ class DD4hep::Geometry::RegionObject+; -#pragma link C++ class DD4hep::Geometry::Handle<DD4hep::Geometry::RegionObject>+; +#pragma link C++ class DD4hep::Handle<DD4hep::Geometry::RegionObject>+; #pragma link C++ class vector<DD4hep::Geometry::Region>+; // Readout.h #pragma link C++ class vector<pair<size_t,string> >+; #pragma link C++ class DD4hep::Geometry::Segmentation+; #pragma link C++ class DD4hep::Geometry::SegmentationObject+; -#pragma link C++ class DD4hep::Geometry::Handle<DD4hep::Geometry::SegmentationObject>+; +#pragma link C++ class DD4hep::Handle<DD4hep::Geometry::SegmentationObject>+; #pragma link C++ class DD4hep::Geometry::Readout+; #pragma link C++ class DD4hep::Geometry::ReadoutObject+; -#pragma link C++ class DD4hep::Geometry::Handle<DD4hep::Geometry::ReadoutObject>+; +#pragma link C++ class DD4hep::Handle<DD4hep::Geometry::ReadoutObject>+; #pragma link C++ class vector<DD4hep::Geometry::Readout>+; #pragma link C++ class vector<DD4hep::Geometry::IDDescriptor>+; #pragma link C++ class DD4hep::Geometry::Alignment+; -#pragma link C++ class DD4hep::Geometry::Handle<TGeoPhysicalNode>+; +#pragma link C++ class DD4hep::Handle<TGeoPhysicalNode>+; -#pragma link C++ class DD4hep::Geometry::Condition+; -#pragma link C++ class vector<DD4hep::Geometry::Condition>+; -#pragma link C++ class DD4hep::Geometry::ConditionsInterna::ConditionObject+; -#pragma link C++ class DD4hep::Geometry::Handle<DD4hep::Geometry::ConditionsInterna::ConditionObject>+; +#pragma link C++ class DD4hep::Conditions::Condition+; +#pragma link C++ class vector<DD4hep::Conditions::Condition>+; +#pragma link C++ class DD4hep::Conditions::Interna::ConditionObject+; +#pragma link C++ class DD4hep::Handle<DD4hep::Conditions::Interna::ConditionObject>+; -#pragma link C++ class DD4hep::Geometry::Conditions+; -#pragma link C++ class DD4hep::Geometry::ConditionsInterna::ConditionContainer+; -#pragma link C++ class DD4hep::Geometry::Handle<DD4hep::Geometry::ConditionsInterna::ConditionContainer>+; +#pragma link C++ class DD4hep::Conditions::Container+; +#pragma link C++ class DD4hep::Conditions::Interna::ConditionContainer+; +#pragma link C++ class DD4hep::Handle<DD4hep::Conditions::Interna::ConditionContainer>+; // DetElement.h +#pragma link C++ class DD4hep::Geometry::World+; +#pragma link C++ class DD4hep::Geometry::WorldObject+; #pragma link C++ class DD4hep::Geometry::DetElement+; #pragma link C++ class DD4hep::Geometry::DetElementObject+; -#pragma link C++ class DD4hep::Geometry::Handle<DD4hep::Geometry::DetElementObject>+; +#pragma link C++ class DD4hep::Handle<DD4hep::Geometry::DetElementObject>+; #pragma link C++ class vector<DD4hep::Geometry::DetElement>+; #pragma link C++ class pair<string,DD4hep::Geometry::DetElement>+; #pragma link C++ class map<string,DD4hep::Geometry::DetElement>+; @@ -209,14 +213,14 @@ template class DD4hep::Geometry::Handle<TNamed>; #pragma link C++ class DD4hep::Geometry::SensitiveDetector+; #pragma link C++ class DD4hep::Geometry::SensitiveDetectorObject+; -#pragma link C++ class DD4hep::Geometry::Handle<DD4hep::Geometry::SensitiveDetectorObject>+; +#pragma link C++ class DD4hep::Handle<DD4hep::Geometry::SensitiveDetectorObject>+; #pragma link C++ class vector<DD4hep::Geometry::SensitiveDetector>+; // Volume.h #pragma link C++ class DD4hep::Geometry::Volume+; #pragma link C++ class DD4hep::Geometry::VolumeExtension+; #pragma link C++ class vector<DD4hep::Geometry::Volume>+; -#pragma link C++ class DD4hep::Geometry::Handle<TGeoVolume>+; +#pragma link C++ class DD4hep::Handle<TGeoVolume>+; #pragma link C++ class DD4hep::Geometry::PlacedVolume+; #ifndef __ROOTCLING__ @@ -228,70 +232,70 @@ template vector<pair<string, int> >::iterator; #pragma link C++ class DD4hep::Geometry::PlacedVolumeExtension::VolIDs+; #pragma link C++ class DD4hep::Geometry::PlacedVolumeExtension+; #pragma link C++ class vector<DD4hep::Geometry::PlacedVolume>+; -#pragma link C++ class DD4hep::Geometry::Handle<TGeoNode>+; +#pragma link C++ class DD4hep::Handle<TGeoNode>+; #pragma link C++ class vector<TGeoNode*>+; #pragma link C++ class vector<TGeoVolume*>+; // Shapes.h -#pragma link C++ class DD4hep::Geometry::Handle<TGeoShape>+; +#pragma link C++ class DD4hep::Handle<TGeoShape>+; #pragma link C++ class DD4hep::Geometry::Solid_type<TGeoShape>+; #pragma link C++ class DD4hep::Geometry::Polycone+; #pragma link C++ class DD4hep::Geometry::Solid_type<TGeoPcon>+; -#pragma link C++ class DD4hep::Geometry::Handle<TGeoPcon>+; +#pragma link C++ class DD4hep::Handle<TGeoPcon>+; #pragma link C++ class DD4hep::Geometry::ConeSegment+; #pragma link C++ class DD4hep::Geometry::Solid_type<TGeoConeSeg>+; -#pragma link C++ class DD4hep::Geometry::Handle<TGeoConeSeg>+; +#pragma link C++ class DD4hep::Handle<TGeoConeSeg>+; #pragma link C++ class DD4hep::Geometry::Box+; #pragma link C++ class DD4hep::Geometry::Solid_type<TGeoBBox>+; -#pragma link C++ class DD4hep::Geometry::Handle<TGeoBBox>+; +#pragma link C++ class DD4hep::Handle<TGeoBBox>+; #pragma link C++ class DD4hep::Geometry::Torus+; #pragma link C++ class DD4hep::Geometry::Solid_type<TGeoTorus>+; -#pragma link C++ class DD4hep::Geometry::Handle<TGeoTorus>+; +#pragma link C++ class DD4hep::Handle<TGeoTorus>+; #pragma link C++ class DD4hep::Geometry::Cone+; #pragma link C++ class DD4hep::Geometry::Solid_type<TGeoCone>+; -#pragma link C++ class DD4hep::Geometry::Handle<TGeoCone>+; +#pragma link C++ class DD4hep::Handle<TGeoCone>+; #pragma link C++ class DD4hep::Geometry::Tube+; #pragma link C++ class DD4hep::Geometry::Solid_type<TGeoTubeSeg>+; -#pragma link C++ class DD4hep::Geometry::Handle<TGeoTubeSeg>+; +#pragma link C++ class DD4hep::Handle<TGeoTubeSeg>+; #pragma link C++ class DD4hep::Geometry::EllipticalTube+; #pragma link C++ class DD4hep::Geometry::Solid_type<TGeoEltu>+; -#pragma link C++ class DD4hep::Geometry::Handle<TGeoEltu>+; +#pragma link C++ class DD4hep::Handle<TGeoEltu>+; #pragma link C++ class DD4hep::Geometry::Trap+; #pragma link C++ class DD4hep::Geometry::Solid_type<TGeoTrap>+; -#pragma link C++ class DD4hep::Geometry::Handle<TGeoTrap>+; +#pragma link C++ class DD4hep::Handle<TGeoTrap>+; #pragma link C++ class DD4hep::Geometry::Trapezoid+; #pragma link C++ class DD4hep::Geometry::Solid_type<TGeoTrd2>+; -#pragma link C++ class DD4hep::Geometry::Handle<TGeoTrd2>+; +#pragma link C++ class DD4hep::Handle<TGeoTrd2>+; #pragma link C++ class DD4hep::Geometry::Sphere+; #pragma link C++ class DD4hep::Geometry::Solid_type<TGeoSphere>+; -#pragma link C++ class DD4hep::Geometry::Handle<TGeoSphere>+; +#pragma link C++ class DD4hep::Handle<TGeoSphere>+; #pragma link C++ class DD4hep::Geometry::Paraboloid+; #pragma link C++ class DD4hep::Geometry::Solid_type<TGeoParaboloid>+; -#pragma link C++ class DD4hep::Geometry::Handle<TGeoParaboloid>+; +#pragma link C++ class DD4hep::Handle<TGeoParaboloid>+; #pragma link C++ class DD4hep::Geometry::Hyperboloid+; #pragma link C++ class DD4hep::Geometry::Solid_type<TGeoHype>+; -#pragma link C++ class DD4hep::Geometry::Handle<TGeoHype>+; +#pragma link C++ class DD4hep::Handle<TGeoHype>+; #pragma link C++ class DD4hep::Geometry::PolyhedraRegular+; #pragma link C++ class DD4hep::Geometry::Solid_type<TGeoPgon>+; -#pragma link C++ class DD4hep::Geometry::Handle<TGeoPgon>+; +#pragma link C++ class DD4hep::Handle<TGeoPgon>+; #pragma link C++ class DD4hep::Geometry::BooleanSolid+; #pragma link C++ class DD4hep::Geometry::Solid_type<TGeoCompositeShape>+; -#pragma link C++ class DD4hep::Geometry::Handle<TGeoCompositeShape>+; +#pragma link C++ class DD4hep::Handle<TGeoCompositeShape>+; #pragma link C++ class DD4hep::Geometry::SubtractionSolid+; #pragma link C++ class DD4hep::Geometry::UnionSolid+; diff --git a/DDCore/include/DD4hep/Errors.h b/DDCore/include/DD4hep/Errors.h new file mode 100644 index 000000000..c5efa43d7 --- /dev/null +++ b/DDCore/include/DD4hep/Errors.h @@ -0,0 +1,55 @@ +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// \author Markus Frank +// \date 2016-02-02 +// \version 1.0 +// +//========================================================================== +// $Id$ +#ifndef DD4HEP_ERRORS_H +#define DD4HEP_ERRORS_H 1 + +// C/C++ include files +#include <string> + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Utility namespace: Errors + namespace Errors { + + /// System error string for EPERM. Sets errno accordingly + std::string noPermission(); + + /// System error string for ENOENT. Sets errno accordingly + std::string noEntry(); + + /// System error string for EIO. Sets errno accordingly + std::string ioError(); + + /// System error string for EINVAL. Sets errno accordingly + std::string invalidArg(); + + /// System error string for ENOKEY. Sets errno accordingly + std::string noKey(); + + /// System error string for ENOSYS. Sets errno accordingly + std::string noSys(); + + /// System error string for ECANCELED. Sets errno accordingly + std::string cancelled(); + + /// System error string for ELNRNG. Sets errno accordingly + std::string linkRange(); + + + } + +} /* End namespace DD4hep */ +#endif // DD4HEP_ERRORS_H diff --git a/DDCore/include/DD4hep/Factories.h b/DDCore/include/DD4hep/Factories.h index bb4453787..215e2cde9 100644 --- a/DDCore/include/DD4hep/Factories.h +++ b/DDCore/include/DD4hep/Factories.h @@ -50,6 +50,10 @@ namespace DD4hep { public: static void* create(const char* arg); }; + template <typename T> class LCDDConstructionFactory : public PluginFactoryBase { + public: + static void* create(lcdd_t& lcdd, int argc, char** argv); + }; /// Template class with a generic signature to apply LCDD plugins /** @@ -147,14 +151,22 @@ namespace { DD4HEP_PLUGIN_FACTORY_ARGS_1(void*,const char*) { return DD4hep::ConstructionFactory<P>::create(a0); } + DD4HEP_PLUGIN_FACTORY_ARGS_1(ns::Named*,ns::LCDD*) { return DD4hep::TranslationFactory<P>::create(*a0).ptr(); } + + DD4HEP_PLUGIN_FACTORY_ARGS_3(void*,ns::LCDD*,int,char**) + { return DD4hep::LCDDConstructionFactory<P>::create(*a0,a1,a2); } + DD4HEP_PLUGIN_FACTORY_ARGS_3(long,ns::LCDD*,int,char**) { return make_return<long>(DD4hep::ApplyFactory<P>::create(*a0,a1,a2)); } + DD4HEP_PLUGIN_FACTORY_ARGS_2(ns::Named*,ns::LCDD*,ns::xml_h*) { return DD4hep::XMLElementFactory<P>::create(*a0,*a1).ptr(); } + DD4HEP_PLUGIN_FACTORY_ARGS_2(long,ns::LCDD*,ns::xml_h*) { return make_return<long>(DD4hep::XMLDocumentReaderFactory<P>::create(*a0,*a1)); } + DD4HEP_PLUGIN_FACTORY_ARGS_3(ns::Named*,ns::LCDD*,ns::xml_h*,ns::ref_t*) { return DD4hep::DetElementFactory<P>::create(*a0,*a1,*a2).ptr(); } } @@ -172,29 +184,40 @@ namespace { #define DECLARE_NAMED_DETELEMENT_FACTORY(n,x) namespace DD4hep \ { DD4HEP_PLUGINSVC_FACTORY(n::x,x,DD4hep::NamedObject*(Geometry::LCDD*,XML::Handle_t*,Geometry::Ref_t*),__LINE__) } +// Call function of the type [long (*func)(const char* arg)] #define DECLARE_APPLY(name,func) DD4HEP_OPEN_PLUGIN(DD4hep,name) { \ template <> long ApplyFactory<name>::create(lcdd_t& l,int n,char** a) {return func(l,n,a);} \ DD4HEP_PLUGINSVC_FACTORY(name,name,long(Geometry::LCDD*,int,char**),__LINE__)} +// Call function of the type [void* (*func)(const char* arg)] #define DECLARE_CONSTRUCTOR(name,func) DD4HEP_OPEN_PLUGIN(DD4hep,name) { \ template <> void* ConstructionFactory<name>::create(const char* n) { return func(n);} \ DD4HEP_PLUGINSVC_FACTORY(name,name,void*(const char*),__LINE__) } +// Call function of the type [void* (*func)(lcdd_t& lcdd, int argc,char** argv)] +#define DECLARE_LCDD_CONSTRUCTOR(name,func) DD4HEP_OPEN_PLUGIN(DD4hep,name) { \ + template <> void* LCDDConstructionFactory<name>::create(lcdd_t& l, int n,char** a) { return func(l,n,a);} \ + DD4HEP_PLUGINSVC_FACTORY(name,name,void*(Geometry::LCDD*,int,char**),__LINE__) } + +// Call function of the type [void* (*func)(lcdd_t& lcdd)] #define DECLARE_TRANSLATION(name,func) DD4HEP_OPEN_PLUGIN(DD4hep,name) { \ template <> Geometry::Ref_t TranslationFactory<name>::create(lcdd_t& l) {return func(l);} \ DECLARE_NAMED_TRANSLATION_FACTORY(Geometry,name) } +// Call function of the type [void* (*func)(lcdd_t& lcdd, xml_h handle)] #define DECLARE_XMLELEMENT(name,func) DD4HEP_OPEN_PLUGIN(DD4hep,xml_element_##name) {\ template <> Geometry::Ref_t XMLElementFactory<xml_element_##name>::create(lcdd_t& l,xml_h e) {return func(l,e);} \ DD4HEP_PLUGINSVC_FACTORY(xml_element_##name,name,NamedObject*(Geometry::LCDD*,XML::Handle_t*),__LINE__) } +// Call function of the type [long (*func)(lcdd_t& lcdd, xml_h handle)] #define DECLARE_XML_DOC_READER(name,func) DD4HEP_OPEN_PLUGIN(DD4hep,xml_document_##name) { \ template <> long XMLDocumentReaderFactory<xml_document_##name>::create(lcdd_t& l,xml_h e) {return func(l,e);} \ DD4HEP_PLUGINSVC_FACTORY(xml_document_##name,name##_XML_reader,long(Geometry::LCDD*,XML::Handle_t*),__LINE__) } +// Call function of the type [NamedObject* (*func)(lcdd_t& lcdd, xml_h handle, ref_t reference)] #define DECLARE_XML_PROCESSOR_BASIC(name,func,deprecated) DD4HEP_OPEN_PLUGIN(DD4hep,det_element_##name) {\ template <> Geometry::Ref_t DetElementFactory< det_element_##name >::create(lcdd_t& l,xml_h e,ref_t h) \ - { if (deprecated) Geometry::warning_deprecated_xml_factory(#name); return func(l,e,h);} \ + { if (deprecated) warning_deprecated_xml_factory(#name); return func(l,e,h);} \ DD4HEP_PLUGINSVC_FACTORY(det_element_##name,name,NamedObject*(Geometry::LCDD*,XML::Handle_t*,Geometry::Ref_t*),__LINE__) } #define DECLARE_XML_PROCESSOR(name,func) DECLARE_XML_PROCESSOR_BASIC(name,func,0) diff --git a/DDCore/include/DD4hep/Handle.h b/DDCore/include/DD4hep/Handle.h index 467f21c25..eb0f71f4d 100644 --- a/DDCore/include/DD4hep/Handle.h +++ b/DDCore/include/DD4hep/Handle.h @@ -11,8 +11,10 @@ // Author : M.Frank // //========================================================================== -#ifndef DD4HEP_ELEMENTS_H -#define DD4HEP_ELEMENTS_H +#ifndef DD4HEP_HANDLE_H +#define DD4HEP_HANDLE_H + +// Framework include files #include "DD4hep/config.h" #include "DD4hep/Primitives.h" @@ -44,298 +46,300 @@ namespace DD4hep { // Forward declarations class NamedObject; - /// Namespace for the geometry part of the AIDA detector description toolkit - namespace Geometry { + long num_object_validations(); + void increment_object_validations(); + /// Function tp print warning about deprecated factory usage. Used by Plugin mechanism. + void warning_deprecated_xml_factory(const char* name); - // Forward declarations - class LCDD; - /// String conversions: boolean value to string \ingroup DD4HEP_GEOMETRY - std::string _toString(bool value); - /// String conversions: integer value to string \ingroup DD4HEP_GEOMETRY - std::string _toString(int value, const char* fmt = "%d"); - /// String conversions: float value to string \ingroup DD4HEP_GEOMETRY - std::string _toString(float value, const char* fmt = "%.17e"); - /// String conversions: double value to string \ingroup DD4HEP_GEOMETRY - std::string _toString(double value, const char* fmt = "%.17e"); - /// Pointer to text conversion - std::string _ptrToString(const void* p, const char* fmt = "%p"); - /// Format any pointer (64 bits) to string \ingroup DD4HEP_XML - template <typename T> std::string _toString(const T* p, const char* fmt = "%p") - { return _ptrToString((void*)p, fmt); } + /// Access to the magic word, which is protecting some objects against memory corruptions \ingroup DD4HEP_GEOMETRY + inline unsigned long long int magic_word() { + return 0xFEEDAFFEDEADFACEULL; + } + - /// String conversions: string to boolean value \ingroup DD4HEP_GEOMETRY - bool _toBool(const std::string& value); - /// String conversions: string to integer value \ingroup DD4HEP_GEOMETRY - int _toInt(const std::string& value); - /// String conversions: string to long integer value \ingroup DD4HEP_GEOMETRY - long _toLong(const std::string& value); - /// String conversions: string to float value \ingroup DD4HEP_GEOMETRY - float _toFloat(const std::string& value); - /// String conversions: string to double value \ingroup DD4HEP_GEOMETRY - double _toDouble(const std::string& value); + /// Handle: a templated class like a shared pointer, which allows specialized access to tgeometry objects. + /** + * The Handle is the base class to access all objects in DD4hep. + * Objects, which consist ONLY of data are NEVER passed directly. + * They are ALWAYS passed using handles. Such handles are 'handy' ;-). + * Assignment is to and from different handles is possible using concrete + * type checking. + * + * Real benefits can result from sophisticated handle subclasses, which can + * implement any desired user functionality with out compromising the + * object's data content. This leads to very flexible implementations, + * where the same data may be shared by many handle implementations + * providing different functionality to the clients. + * + * In this sense, is the consequent use of handles to access data nothing + * else then the consequent application of component oriented programming + * using local objects from the heap. + * + * Note: + * If you cannot live with this approach, it is better you get hands of this + * software package, because you will try to consequently fight the framework, + * which will frustrate you (and also me). + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_GEOMETRY + */ + template <typename T> class Handle { + public: + /** Type definitions and class specific abbreviations and forward declarations */ + /// Extern accessible definition of the contained element type + typedef T Implementation; + /// Declaration of 'self' + typedef Handle<Implementation> handle_t; - /// Void helper function to support formalisms \ingroup DD4HEP_GEOMETRY - inline bool _toBool(bool value) { - return value; + /// Single and only data member: Reference to the actual element. + T* m_element; + /// Defaulot constructor + Handle() + : m_element(0) { } - /// Void helper function to support formalisms \ingroup DD4HEP_GEOMETRY - inline int _toInt(int value) { - return value; + /// Initializing constructor from pointer + Handle(T* e) + : m_element(e) { } - /// Void helper function to support formalisms \ingroup DD4HEP_GEOMETRY - inline long _toLong(long value) { - return value; + /// Copy constructor + Handle(const Handle<T>& e) + : m_element(e.m_element) { } - /// Void helper function to support formalisms \ingroup DD4HEP_GEOMETRY - inline float _toFloat(float value) { - return value; + /// Initializing constructor from unrelated pointer with type checking + template <typename Q> Handle(Q* e) + : m_element((T*) e) { + verifyObject(); } - /// Void helper function to support formalisms \ingroup DD4HEP_GEOMETRY - inline double _toDouble(double value) { - return value; + /// Initializing constructor from unrelated handle with type checking + template <typename Q> Handle(const Handle<Q>& e) + : m_element((T*) e.m_element) { + verifyObject(); } - - /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY - template <class T> T _multiply(const std::string& left, T right); - /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY - template <class T> T _multiply(T left, const std::string& right); - /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY - template <class T> T _multiply(const std::string& left, const std::string& right); - - /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY - template <> int _multiply<int>(const std::string& left, const std::string& right); - /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY - template <> inline int _multiply<int>(int left, const std::string& right) { - return left * _toInt(right); + /// Assignment operator + Handle<T>& operator=(const Handle<T>& e) { + m_element = e.m_element; + return *this; } - /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY - template <> inline int _multiply<int>(const std::string& left, int right) { - return _toInt(left) * right; + /// Boolean operator == used for RB tree insertions + bool operator==(const Handle<T>& e) const { + return m_element == e.m_element; } - - /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY - template <> long _multiply<long>(const std::string& left, const std::string& right); - /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY - template <> inline long _multiply<long>(long left, const std::string& right) { - return left * _toLong(right); + /// Boolean operator < used for RB tree insertions + bool operator<(const Handle<T>& e) const { + return m_element < e.m_element; } - /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY - template <> inline long _multiply<long>(const std::string& left, long right) { - return _toLong(left) * right; + /// Boolean operator > used for RB tree insertions + bool operator>(const Handle<T>& e) const { + return m_element > e.m_element; } - - /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY - template <> float _multiply<float>(const std::string& left, const std::string& right); - /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY - template <> inline float _multiply<float>(float left, const std::string& right) { - return left * _toFloat(right); + /// Check the validity of the object held by the handle + bool isValid() const { + return 0 != m_element; + } + /// Check the validity of the object held by the handle + bool operator!() const { + return 0 == m_element; + } + /// Release the object held by the handle + Handle<T>& clear() { + m_element = 0; + return *this; + } + /// Access the held object using the -> operator + T* operator->() const { + return m_element; + } + /// Automatic type conversion to an object references + operator T&() const { + return *m_element; + } + /// Access the held object using the * operator + T& operator*() const { + return *m_element; + } + /// Access to the held object + T* ptr() const { + return m_element; } - /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY - template <> inline float _multiply<float>(const std::string& left, float right) { - return _toFloat(left) * right; + /// Access to an unrelated object type + template <typename Q> Q* _ptr() const { + return (Q*) m_element; } + /// Access to an unrelated object type + template <typename Q> Q* data() const { + return (Q*) m_element; + } + /// Access to an unrelated object type + template <typename Q> Q& object() const { + return *(Q*) m_element; + } + /// Checked object access. Throws invalid handle runtime exception + T* access() const; + /// Verify the object type after a (re-)assignment + void verifyObject() const; + /// Access the object name (or "" if not supported by the object) + const char* name() const; + /// Helper routine called when unrelated types are assigned. + static void bad_assignment(const std::type_info& from, const std::type_info& to); + /// Assign a new named object. Note: object references must be managed by the user + void assign(Implementation* n, const std::string& nam, const std::string& title); + }; + /// Default Ref_t definition describing named objects \ingroup DD4HEP_GEOMETRY + typedef Handle<NamedObject> Ref_t; - /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY - template <> double _multiply<double>(const std::string& left, const std::string& right); - /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY - template <> inline double _multiply<double>(const std::string& left, double right) { - return _toDouble(left) * right; + /// Helper to delete objects from heap and reset the handle \ingroup DD4HEP_GEOMETRY + template <typename T> inline void destroyHandle(T& h) { + deletePtr(h.m_element); + } + /// Helper to delete objects from heap and reset the handle \ingroup DD4HEP_GEOMETRY + template <typename T> inline void releaseHandle(T& h) { + releasePtr(h.m_element); + } + /// Functor to destroy handles and delete the cached object \ingroup DD4HEP_GEOMETRY + template <typename T> class DestroyHandle { + public: + void operator()(T p) const { + destroyHandle(p); + } + }; + /// Functor to destroy handles and delete the cached object \ingroup DD4HEP_GEOMETRY + template <typename T> class ReleaseHandle { + public: + void operator()(T p) const { + releaseHandle(p); + } + }; + /// map Functor to destroy handles and delete the cached object \ingroup DD4HEP_GEOMETRY + template <typename M> class DestroyHandles { + public: + M& object; + DestroyHandles(M& m) + : object(m) { } - /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY - template <> inline double _multiply<double>(double left, const std::string& right) { - return left * _toDouble(right); + ~DestroyHandles() { + object.clear(); } + void operator()(std::pair<typename M::key_type, typename M::mapped_type> p) const { + DestroyHandle<typename M::mapped_type>()(p.second); + } + }; + /// Functional created of map destruction functors + template <typename M> DestroyHandles<M> destroyHandles(M& m) { + return DestroyHandles<M>(m); + } - /// Enter name value pair to the dictionary. \"value\" must be a numerical expression, which is evaluated \ingroup DD4HEP_GEOMETRY - void _toDictionary(const std::string& name, const std::string& value); - /// Enter name value pair to the dictionary. \ingroup DD4HEP_GEOMETRY - void _toDictionary(const std::string& name, const std::string& value, const std::string& typ); + /// String conversions: boolean value to string \ingroup DD4HEP_GEOMETRY + std::string _toString(bool value); + /// String conversions: integer value to string \ingroup DD4HEP_GEOMETRY + std::string _toString(int value, const char* fmt = "%d"); + /// String conversions: float value to string \ingroup DD4HEP_GEOMETRY + std::string _toString(float value, const char* fmt = "%.17e"); + /// String conversions: double value to string \ingroup DD4HEP_GEOMETRY + std::string _toString(double value, const char* fmt = "%.17e"); + /// Pointer to text conversion + std::string _ptrToString(const void* p, const char* fmt = "%p"); + /// Format any pointer (64 bits) to string \ingroup DD4HEP_XML + template <typename T> std::string _toString(const T* p, const char* fmt = "%p") + { return _ptrToString((void*)p, fmt); } - long num_object_validations(); - void increment_object_validations(); - /// Function tp print warning about deprecated factory usage. Used by Plugin mechanism. - void warning_deprecated_xml_factory(const char* name); + /// String conversions: string to boolean value \ingroup DD4HEP_GEOMETRY + bool _toBool(const std::string& value); + /// String conversions: string to integer value \ingroup DD4HEP_GEOMETRY + int _toInt(const std::string& value); + /// String conversions: string to long integer value \ingroup DD4HEP_GEOMETRY + long _toLong(const std::string& value); + /// String conversions: string to float value \ingroup DD4HEP_GEOMETRY + float _toFloat(const std::string& value); + /// String conversions: string to double value \ingroup DD4HEP_GEOMETRY + double _toDouble(const std::string& value); + /// Void helper function to support formalisms \ingroup DD4HEP_GEOMETRY + inline bool _toBool(bool value) { + return value; + } + /// Void helper function to support formalisms \ingroup DD4HEP_GEOMETRY + inline int _toInt(int value) { + return value; + } + /// Void helper function to support formalisms \ingroup DD4HEP_GEOMETRY + inline long _toLong(long value) { + return value; + } + /// Void helper function to support formalisms \ingroup DD4HEP_GEOMETRY + inline float _toFloat(float value) { + return value; + } + /// Void helper function to support formalisms \ingroup DD4HEP_GEOMETRY + inline double _toDouble(double value) { + return value; + } - /// Access to the magic word, which is protecting some objects against memory corruptions \ingroup DD4HEP_GEOMETRY - inline unsigned long long int magic_word() { - return 0xFEEDAFFEDEADFACEULL; - } + /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY + template <class T> T _multiply(const std::string& left, T right); + /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY + template <class T> T _multiply(T left, const std::string& right); + /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY + template <class T> T _multiply(const std::string& left, const std::string& right); - /// Handle: a templated class like a shared pointer, which allows specialized access to tgeometry objects. - /** - * The Handle is the base class to access all objects in DD4hep. - * Objects, which consist ONLY of data are NEVER passed directly. - * They are ALWAYS passed using handles. Such handles are 'handy' ;-). - * Assignment is to and from different handles is possible using concrete - * type checking. - * - * Real benefits can result from sophisticated handle subclasses, which can - * implement any desired user functionality with out compromising the - * object's data content. This leads to very flexible implementations, - * where the same data may be shared by many handle implementations - * providing different functionality to the clients. - * - * In this sense, is the consequent use of handles to access data nothing - * else then the consequent application of component oriented programming - * using local objects from the heap. - * - * Note: - * If you cannot live with this approach, it is better you get hands of this - * software package, because you will try to consequently fight the framework, - * which will frustrate you (and also me). - * - * \author M.Frank - * \version 1.0 - * \ingroup DD4HEP_GEOMETRY - */ - template <typename T> class Handle { - public: - /** Type definitions and class specific abbreviations and forward declarations */ - /// Extern accessible definition of the contained element type - typedef T Implementation; - /// Declaration of 'self' - typedef Handle<Implementation> handle_t; + /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY + template <> int _multiply<int>(const std::string& left, const std::string& right); + /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY + template <> inline int _multiply<int>(int left, const std::string& right) { + return left * _toInt(right); + } + /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY + template <> inline int _multiply<int>(const std::string& left, int right) { + return _toInt(left) * right; + } - /// Single and only data member: Reference to the actual element. - T* m_element; - /// Defaulot constructor - Handle() - : m_element(0) { - } - /// Initializing constructor from pointer - Handle(T* e) - : m_element(e) { - } - /// Copy constructor - Handle(const Handle<T>& e) - : m_element(e.m_element) { - } - /// Initializing constructor from unrelated pointer with type checking - template <typename Q> Handle(Q* e) - : m_element((T*) e) { - verifyObject(); - } - /// Initializing constructor from unrelated handle with type checking - template <typename Q> Handle(const Handle<Q>& e) - : m_element((T*) e.m_element) { - verifyObject(); - } - /// Assignment operator - Handle<T>& operator=(const Handle<T>& e) { - m_element = e.m_element; - return *this; - } - /// Boolean operator == used for RB tree insertions - bool operator==(const Handle<T>& e) const { - return m_element == e.m_element; - } - /// Boolean operator < used for RB tree insertions - bool operator<(const Handle<T>& e) const { - return m_element < e.m_element; - } - /// Boolean operator > used for RB tree insertions - bool operator>(const Handle<T>& e) const { - return m_element > e.m_element; - } - /// Check the validity of the object held by the handle - bool isValid() const { - return 0 != m_element; - } - /// Check the validity of the object held by the handle - bool operator!() const { - return 0 == m_element; - } - /// Release the object held by the handle - Handle<T>& clear() { - m_element = 0; - return *this; - } - /// Access the held object using the -> operator - T* operator->() const { - return m_element; - } - /// Automatic type conversion to an object references - operator T&() const { - return *m_element; - } - /// Access the held object using the * operator - T& operator*() const { - return *m_element; - } - /// Access to the held object - T* ptr() const { - return m_element; - } - /// Access to an unrelated object type - template <typename Q> Q* _ptr() const { - return (Q*) m_element; - } - /// Access to an unrelated object type - template <typename Q> Q* data() const { - return (Q*) m_element; - } - /// Access to an unrelated object type - template <typename Q> Q& object() const { - return *(Q*) m_element; - } - /// Checked object access. Throws invalid handle runtime exception - T* access() const; - /// Verify the object type after a (re-)assignment - void verifyObject() const; - /// Access the object name (or "" if not supported by the object) - const char* name() const; - /// Helper routine called when unrelated types are assigned. - static void bad_assignment(const std::type_info& from, const std::type_info& to); - /// Assign a new named object. Note: object references must be managed by the user - void assign(Implementation* n, const std::string& nam, const std::string& title); - }; - /// Default Ref_t definition describing named objects \ingroup DD4HEP_GEOMETRY - typedef Handle<NamedObject> Ref_t; + /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY + template <> long _multiply<long>(const std::string& left, const std::string& right); + /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY + template <> inline long _multiply<long>(long left, const std::string& right) { + return left * _toLong(right); + } + /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY + template <> inline long _multiply<long>(const std::string& left, long right) { + return _toLong(left) * right; + } - /// Helper to delete objects from heap and reset the handle \ingroup DD4HEP_GEOMETRY - template <typename T> inline void destroyHandle(T& h) { - deletePtr(h.m_element); - } - /// Helper to delete objects from heap and reset the handle \ingroup DD4HEP_GEOMETRY - template <typename T> inline void releaseHandle(T& h) { - releasePtr(h.m_element); - } - /// Functor to destroy handles and delete the cached object \ingroup DD4HEP_GEOMETRY - template <typename T> class DestroyHandle { - public: - void operator()(T p) const { - destroyHandle(p); - } - }; - /// Functor to destroy handles and delete the cached object \ingroup DD4HEP_GEOMETRY - template <typename T> class ReleaseHandle { - public: - void operator()(T p) const { - releaseHandle(p); - } - }; - /// map Functor to destroy handles and delete the cached object \ingroup DD4HEP_GEOMETRY - template <typename M> class DestroyHandles { - public: - M& object; - DestroyHandles(M& m) - : object(m) { - } - ~DestroyHandles() { - object.clear(); - } - void operator()(std::pair<typename M::key_type, typename M::mapped_type> p) const { - DestroyHandle<typename M::mapped_type>()(p.second); - } - }; - /// Functional created of map destruction functors - template <typename M> DestroyHandles<M> destroyHandles(M& m) { - return DestroyHandles<M>(m); - } + /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY + template <> float _multiply<float>(const std::string& left, const std::string& right); + /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY + template <> inline float _multiply<float>(float left, const std::string& right) { + return left * _toFloat(right); + } + /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY + template <> inline float _multiply<float>(const std::string& left, float right) { + return _toFloat(left) * right; + } + + /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY + template <> double _multiply<double>(const std::string& left, const std::string& right); + /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY + template <> inline double _multiply<double>(const std::string& left, double right) { + return _toDouble(left) * right; + } + /// Generic multiplication using the evaluator: result = left * right \ingroup DD4HEP_GEOMETRY + template <> inline double _multiply<double>(double left, const std::string& right) { + return left * _toDouble(right); + } + + /// Enter name value pair to the dictionary. \"value\" must be a numerical expression, which is evaluated \ingroup DD4HEP_GEOMETRY + void _toDictionary(const std::string& name, const std::string& value); + /// Enter name value pair to the dictionary. \ingroup DD4HEP_GEOMETRY + void _toDictionary(const std::string& name, const std::string& value, const std::string& typ); + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Geometry { + using DD4hep::Handle; + using DD4hep::Ref_t; + // Forward declarations + class LCDD; } /* End namespace Geometry */ -} /* End namespace DD4hep */ -#endif /* DD4HEP_ELEMENTS_H */ +} /* End namespace DD4hep */ +#endif /* DD4HEP_HANDLE_H */ diff --git a/DDCore/include/DD4hep/Handle.inl b/DDCore/include/DD4hep/Handle.inl index 56ed2146d..e6bdeb0c6 100644 --- a/DDCore/include/DD4hep/Handle.inl +++ b/DDCore/include/DD4hep/Handle.inl @@ -18,9 +18,6 @@ /// Namespace for the AIDA detector description toolkit namespace DD4hep { - /// Namespace for the geometry part of the AIDA detector description toolkit - namespace Geometry { - /// Helper routine called when unrelated types are assigned. template <typename T> void Handle<T>::bad_assignment(const std::type_info& from, const std::type_info& to) { invalidHandleAssignmentError(from,to); @@ -47,42 +44,41 @@ namespace DD4hep { return 0; // We have thrown an exception before - does not harm! } - } /* End namespace Geometry */ } /* End namespace DD4hep */ #define DD4HEP_INSTANTIATE_HANDLE(X) \ - namespace DD4hep { namespace Geometry { \ - template <> void Handle<X>::verifyObject() const { \ - increment_object_validations(); \ - if (m_element && dynamic_cast<X*>((TObject*)m_element) == 0) { \ - bad_assignment(typeid(*m_element), typeid(X)); \ - } \ - }}} \ - template class DD4hep::Geometry::Handle<X> + namespace DD4hep { \ + template <> void Handle<X>::verifyObject() const { \ + increment_object_validations(); \ + if (m_element && dynamic_cast<X*>((TObject*)m_element) == 0) { \ + bad_assignment(typeid(*m_element), typeid(X)); \ + } \ + }} \ + template class DD4hep::Handle<X> #define DD4HEP_INSTANTIATE_HANDLE_NAMED(X) \ - namespace DD4hep { namespace Geometry { \ - template <> const char* Handle<X>::name() const \ - { return this->m_element ? this->m_element->name.c_str() : ""; } \ - template <> void \ - Handle<X>::assign(X* p, const std::string& n, const std::string& t) { \ - this->m_element = p; \ - p->name = n; \ - p->type = t; \ - } \ - template <> void Handle<X>::verifyObject() const { \ - increment_object_validations(); \ - if (m_element && dynamic_cast<X*>((NamedObject*)m_element) == 0) { \ - bad_assignment(typeid(*m_element), typeid(X)); \ - } \ - }}} \ - template class DD4hep::Geometry::Handle<X> + namespace DD4hep { \ + template <> const char* Handle<X>::name() const \ + { return this->m_element ? this->m_element->name.c_str() : ""; } \ + template <> void \ + Handle<X>::assign(X* p, const std::string& n, const std::string& t){\ + this->m_element = p; \ + p->name = n; \ + p->type = t; \ + } \ + template <> void Handle<X>::verifyObject() const { \ + increment_object_validations(); \ + if (m_element && dynamic_cast<X*>((NamedObject*)m_element) == 0) {\ + bad_assignment(typeid(*m_element), typeid(X)); \ + } \ + }} \ + template class DD4hep::Handle<X> #define DD4HEP_INSTANTIATE_HANDLE_UNNAMED(X) \ - namespace DD4hep { namespace Geometry { \ - template <> void \ - Handle<X>::assign(X* n, const std::string&, const std::string&) \ - { this->m_element = n;} \ - template <> const char* Handle<X>::name() const { return ""; } \ - }} \ + namespace DD4hep { \ + template <> void \ + Handle<X>::assign(X* n, const std::string&, const std::string&) \ + { this->m_element = n;} \ + template <> const char* Handle<X>::name() const { return ""; } \ + } \ DD4HEP_INSTANTIATE_HANDLE(X) diff --git a/DDCore/include/DD4hep/LCDD.h b/DDCore/include/DD4hep/LCDD.h index 49e0c2b87..829e94368 100644 --- a/DDCore/include/DD4hep/LCDD.h +++ b/DDCore/include/DD4hep/LCDD.h @@ -165,8 +165,11 @@ namespace DD4hep { - The sensitive type of a detector is set in the 'detector constructor'. - Not sensitive detector structures have the name 'passive' - Compounds (ie. nested detectors) are of type 'compound' + - If throw_exc is set to true, an exception is thrown if the type + is not present. Otherwise an empty detector container is returned. */ - virtual const std::vector<DetElement>& detectors(const std::string& type) = 0; + virtual const std::vector<DetElement>& detectors(const std::string& type, + bool throw_exc=false) = 0; /// Access a set of subdetectors according to several sensitive types. virtual std::vector<DetElement> detectors(const std::string& type1, diff --git a/DDCore/include/DD4hep/Mutex.h b/DDCore/include/DD4hep/Mutex.h new file mode 100644 index 000000000..28c05eed9 --- /dev/null +++ b/DDCore/include/DD4hep/Mutex.h @@ -0,0 +1,42 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +#ifndef DD4HEP_MUTEX_H +#define DD4HEP_MUTEX_H + +// C/C++ include files +#if __cplusplus >= 201103L +#include <mutex> +#endif + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { +#if __cplusplus >= 201103L + typedef std::recursive_mutex dd4hep_mutex_t; + typedef std::lock_guard<dd4hep_mutex_t> dd4hep_lock_t; +#else + struct dd4hep_mutex_t { + dd4hep_mutex_t() {} + ~dd4hep_mutex_t() {} + int lock() { return 0;} + int trylock() { return 0;} + int unlock() { return 0;} + }; + struct dd4hep_lock_t { + dd4hep_lock_t(dd4hep_mutex_t&, bool=true) {} + ~dd4hep_lock_t() {} + }; +#endif +} +#endif // DD4HEP_MUTEX_H diff --git a/DDCore/include/DD4hep/PluginCreators.h b/DDCore/include/DD4hep/PluginCreators.h new file mode 100644 index 000000000..68aef2dd3 --- /dev/null +++ b/DDCore/include/DD4hep/PluginCreators.h @@ -0,0 +1,64 @@ +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// \author Markus Frank +// \date 2016-01-29 +// \version 1.0 +// +//========================================================================== +// $Id$ +#ifndef DD4HEP_PLUGINCREATORS_H +#define DD4HEP_PLUGINCREATORS_H 1 + +// Framework include files +#include "DD4hep/Primitives.h" + +// C/C++ include files +#include <string> + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Geometry { + // Forward declarations + class LCDD; + } + + /// Handler for factories of type: ConstructionFactory + /** Signature: void* create(const char* arg); + * + * An exception is thrown in the event the object cannot be created. + * The object is properly casted before given to the caller. + */ + void* createPlugin(const std::string& factory, Geometry::LCDD& lcdd, void* (*cast)(void*)); + void* createPlugin(const std::string& factory, Geometry::LCDD& lcdd, const std::string& arg, void* (*cast)(void*)); + void* createPlugin(const std::string& factory, Geometry::LCDD& lcdd, int argc, char** argv, void* (*cast)(void*)); + + /// Handler for factories of type: ConstructionFactory with casted return type + template <typename T> T* createPlugin(const std::string& factory, Geometry::LCDD& lcdd) { + typedef T plugin_t; + struct __cast{ static void* cast(void* p) { return &dynamic_cast<plugin_t&>(*(plugin_t*)p); } }; + return (plugin_t*)createPlugin(factory, lcdd, __cast::cast); + } + /// Handler for factories of type: ConstructionFactory with casted return type + template <typename T> T* createPlugin(const std::string& factory, Geometry::LCDD& lcdd, const std::string& arg) { + typedef T plugin_t; + struct __cast{ static void* cast(void* p) { return &dynamic_cast<plugin_t&>(*(plugin_t*)p); } }; + return (plugin_t*)createPlugin(factory, lcdd, arg, __cast::cast); + } + /// Handler for factories of type: ConstructionFactory with casted return type + template <typename T> T* createPlugin(const std::string& factory, Geometry::LCDD& lcdd, int argc, char** argv) { + typedef T plugin_t; + struct __cast{ static void* cast(void* p) { return &dynamic_cast<plugin_t&>(*(plugin_t*)p); } }; + return (plugin_t*)createPlugin(factory, lcdd, argc, argv, __cast::cast); + } + +} /* End namespace DD4hep */ + +#endif // DD4HEP_PLUGINCREATORS_H diff --git a/DDCore/include/DD4hep/Plugins.h b/DDCore/include/DD4hep/Plugins.h index adec0e847..e5bb38b13 100644 --- a/DDCore/include/DD4hep/Plugins.h +++ b/DDCore/include/DD4hep/Plugins.h @@ -25,10 +25,10 @@ namespace DD4hep { class NamedObject; + template <typename T> class Handle; /// Namespace for the geometry part of the AIDA detector description toolkit namespace Geometry { - template <typename T> class Handle; class LCDD; } /// Namespace for the AIDA detector description toolkit supporting XML utilities @@ -42,7 +42,7 @@ namespace DD4hep { /// Factory base class implementing some utilities struct PluginFactoryBase { typedef Geometry::LCDD lcdd_t; - typedef Geometry::Handle<NamedObject> ref_t; + typedef Handle<NamedObject> ref_t; typedef XML::Handle_t xml_h; typedef XML::Element xml_e; typedef std::string str_t; diff --git a/DDCore/include/DD4hep/Primitives.h b/DDCore/include/DD4hep/Primitives.h index ab62b5096..9e2d862a3 100644 --- a/DDCore/include/DD4hep/Primitives.h +++ b/DDCore/include/DD4hep/Primitives.h @@ -42,21 +42,24 @@ namespace DD4hep { hash ^= (hash >> 11); hash += (hash << 15); return hash; } + inline unsigned int hash32(const std::string& key) { + return hash32(key.c_str()); + } /// ABI information about type names std::string typeName(const std::type_info& type); - void typeinfoCheck(const std::type_info& typ1, const std::type_info& typ2, const std::string& text = ""); + void typeinfoCheck(const std::type_info& typ1, const std::type_info& typ2, const std::string& text = "") throw(std::exception); /// Throw exception when handles are check for validity - void invalidHandleError(const std::type_info& type); + void invalidHandleError(const std::type_info& type) throw(std::exception); /// Throw exception when handles are badly assigned - void invalidHandleAssignmentError(const std::type_info& from, const std::type_info& to); + void invalidHandleAssignmentError(const std::type_info& from, const std::type_info& to) throw(std::exception); /// Throw exception when handles are check for validity - template <typename T> void invalidHandleError() { + template <typename T> void invalidHandleError() throw(std::exception) { invalidHandleError(typeid(T)); } /// Throw exception when handles are check for validity - void notImplemented(const std::string& msg); + void notImplemented(const std::string& msg) throw(std::exception); /// Class to perform dynamic casts using unknown pointers. /** @class ComponentCast Primitives.h DD4hep/Primitives.h @@ -103,11 +106,11 @@ namespace DD4hep { } /// Apply cast using typeinfo instead of dynamic_cast - void* apply_dynCast(const ComponentCast& to, const void* ptr) const; + void* apply_dynCast(const ComponentCast& to, const void* ptr) const throw(std::exception); /// Apply cast using typeinfo instead of dynamic_cast - void* apply_upCast(const ComponentCast& to, const void* ptr) const; + void* apply_upCast(const ComponentCast& to, const void* ptr) const throw(std::exception); /// Apply cast using typeinfo instead of dynamic_cast - void* apply_downCast(const ComponentCast& to, const void* ptr) const; + void* apply_downCast(const ComponentCast& to, const void* ptr) const throw(std::exception); }; @@ -294,6 +297,112 @@ namespace DD4hep { return ReferenceObjects<typename M::value_type>(); } + /// Member function call-functor with no arguments + template <typename R, typename T> struct ApplyMemFunc { + typedef R (T::*memfunc_t)(); + memfunc_t func; + ApplyMemFunc(memfunc_t f) : func(f) {} + void operator()(T* p) const { if (p) { (p->*func)(); } } + }; + + /// Member function call-functor with 1 argument + template <typename R, typename T, typename A1> struct ApplyMemFunc1 { + typedef R (T::*memfunc_t)(A1 a1); + memfunc_t func; + A1& arg1; + ApplyMemFunc1(memfunc_t f, A1& a1) : func(f), arg1(a1) {} + void operator()(T* p) const { if ( p ) { (p->*func)(arg1); } } + }; + + /// Member function call-functor with 2 arguments + template <typename R, typename T, typename A1, typename A2> struct ApplyMemFunc2 { + typedef R (T::*memfunc_t)(A1 a1, A2 a2); + memfunc_t func; + A1& arg1; + A2& arg2; + ApplyMemFunc2(memfunc_t f, A1& a1, A2& a2) : func(f), arg1(a1), arg2(a2) {} + void operator()( T* p) const { if ( p ) { (p->*func)(arg1, arg2); } } + }; + + /// Member function call-functor with no arguments (const version) + template <typename R, typename T> struct ApplyMemFuncConst { + typedef R (T::*memfunc_t)() const; + memfunc_t func; + ApplyMemFuncConst(memfunc_t f) : func(f) {} + void operator()(const T* p) const { if ( p ) { (p->*func)(); } } + }; + + /// Member function call-functor with 1 argument (const version) + template <typename R, typename T, typename A1> struct ApplyMemFuncConst1 { + typedef R (T::*memfunc_t)(A1 a1) const; + memfunc_t func; + A1& arg1; + ApplyMemFuncConst1(memfunc_t f, A1& a1) : func(f), arg1(a1) {} + void operator()(const T* p) const { if ( p ) { (p->*func)(arg1); } } + }; + + /// Member function call-functor with 2 arguments (const version) + template <typename R, typename T, typename A1, typename A2> struct ApplyMemFuncConst2 { + typedef R (T::*memfunc_t)(A1 a1, A2 a2) const; + memfunc_t func; + A1& arg1; + A2& arg2; + ApplyMemFuncConst2(memfunc_t f, A1& a1, A2& a2) : func(f), arg1(a1), arg2(a2) {} + void operator()(const T* p) const { if ( p ) { (p->*func)(arg1, arg2); } } + }; + + template <typename C, typename R, typename T> + void call_member_func(C& object, R (T::*pmf)()) + { std::for_each(object.begin(),object.end(),ApplyMemFunc<R,T>(pmf)); } + + template <typename C, typename R, typename T> + void call_member_func(C& object, R (T::*pmf)() const) + { std::for_each(object.begin(),object.end(),ApplyMemFuncConst<R,T>(pmf)); } + + template <typename C, typename R, typename T, typename A1> + void call_member_func(C& object, R (T::*pmf)(A1 a1), A1 a1) + { std::for_each(object.begin(),object.end(),ApplyMemFunc1<R,T,A1>(pmf,a1)); } + + template <typename C, typename R, typename T, typename A1> + void call_member_func(C& object, R (T::*pmf)(A1 a1) const, A1 a1) + { std::for_each(object.begin(),object.end(),ApplyMemFuncConst1<R,T,A1>(pmf,a1)); } + + + template <typename C, typename R, typename T, typename A1, typename A2> + void call_member_func(C& object, R (T::*pmf)(A1 a1,A2 a2), A1 a1, A2 a2) + { std::for_each(object.begin(),object.end(),ApplyMemFunc2<R,T,A1,A2>(pmf,a1,a1)); } + + template <typename C, typename R, typename T, typename A1, typename A2> + void call_member_func(C& object, R (T::*pmf)(A1 a1,A2 a2) const, A1 a1, A2 a2) + { std::for_each(object.begin(),object.end(),ApplyMemFuncConst2<R,T,A1,A2>(pmf,a1,a2)); } + + /// Generic map Functor to act on second element + template <typename M, typename FCN> class Apply2nd { + public: + const FCN& func; + Apply2nd(const FCN& f) : func(f) { } + void operator()(std::pair<typename M::key_type const, typename M::mapped_type>& p) const + { (func)(p.second); } + }; + + template <typename C, typename FCN> Apply2nd<C,FCN> apply__2nd_value(C&,const FCN& func) + { return Apply2nd<C,FCN>(func); } + + template <typename C, typename R, typename T> + void apply2nd(C& object, R (T::*pmf)()) + { std::for_each(object.begin(),object.end(),apply__2nd_value(object,ApplyMemFunc<R,T>(pmf))); } + + template <typename C, typename R, typename T, typename A1> + void apply2nd(C object, R (T::*pmf)(A1 a1), A1 a1) + { std::for_each(object.begin(),object.end(),apply__2nd_value(object,ApplyMemFunc1<R,T,A1>(pmf,a1))); } + + template <typename C, typename R, typename T> + void apply2nd(C& object, R (T::*pmf)() const) + { std::for_each(object.begin(),object.end(),apply__2nd_value(object,ApplyMemFuncConst<R,T>(pmf))); } + + template <typename C, typename R, typename T, typename A1> + void apply2nd(C object, R (T::*pmf)(A1 a1) const, A1 a1) + { std::for_each(object.begin(),object.end(),apply__2nd_value(object,ApplyMemFuncConst1<R,T,A1>(pmf,a1))); } /// Data structure to manipulate a bitmask held by reference and represented by an integer /** diff --git a/DDCore/include/DD4hep/Printout.h b/DDCore/include/DD4hep/Printout.h index f2ed650a2..858a65793 100644 --- a/DDCore/include/DD4hep/Printout.h +++ b/DDCore/include/DD4hep/Printout.h @@ -32,6 +32,8 @@ namespace DD4hep { // Forward declarations class NamedObject; + template <typename T> class Handle; + typedef Handle<NamedObject> Ref_t; /// Namespace for the geometry part of the AIDA detector description toolkit namespace Geometry { @@ -41,8 +43,6 @@ namespace DD4hep { class VisAttr; class DetElement; class PlacedVolume; - template <typename T> class Handle; - typedef Handle<NamedObject> Ref_t; } enum PrintLevel { @@ -233,7 +233,7 @@ namespace DD4hep { */ template <typename T> struct PrintMap { typedef T item_type; - typedef const std::map<std::string, Geometry::Ref_t> cont_type; + typedef const std::map<std::string, Ref_t> cont_type; /// Reference to the detector description object const Geometry::LCDD* lcdd; diff --git a/DDCore/include/DD4hep/World.h b/DDCore/include/DD4hep/World.h new file mode 100644 index 000000000..7b53db9e0 --- /dev/null +++ b/DDCore/include/DD4hep/World.h @@ -0,0 +1,75 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +#ifndef DD4HEP_WORLD_H +#define DD4HEP_WORLD_H + +// Framework include files +#include "DD4hep/Detector.h" +#include "DD4hep/Conditions.h" + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Geometry { + + // Forward declarations + class WorldObject; + + /// Handle class to hold the information of the top DetElement object 'world' + /** + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_GEOMETRY + */ + class World : public Handle<WorldObject> { + protected: + /// Internal object type + typedef WorldObject Object; + /// Definition of the base handle type + typedef Handle<Object> RefObject; + /// Conditions stuff + typedef Conditions::IOV IOV; + typedef Conditions::Condition Condition; + + public: + /// Default constructor + World() : RefObject() { } + + /// Copy from named handle + World(const RefObject& sd) : RefObject(sd) {} + + /// Copy from handle + World(const World& sd) : RefObject(sd) {} + + /// Templated constructor for handle conversions + template <typename Q> World(const Handle<Q>& e) : RefObject(e) {} + + /// Assignment operator + World& operator=(const World& sd) { + m_element = sd.m_element; + return *this; + } +#ifndef __CINT__ + LCDD& lcdd() const; +#endif + /// Access the conditions loading + Condition getCondition(DetElement child,const std::string& key, const IOV& iov) const; + }; + + } /* End namespace Geometry */ +} /* End namespace DD4hep */ + +#endif /* DD4HEP_DETECTOR_H */ diff --git a/DDCore/include/DD4hep/objects/ConditionsInterna.h b/DDCore/include/DD4hep/objects/ConditionsInterna.h index 5f46f354b..c649b30d4 100644 --- a/DDCore/include/DD4hep/objects/ConditionsInterna.h +++ b/DDCore/include/DD4hep/objects/ConditionsInterna.h @@ -16,6 +16,7 @@ // Framework include files #include "DD4hep/Detector.h" +#include "DD4hep/Conditions.h" #include "DD4hep/BasicGrammar.h" #include "DD4hep/NamedObject.h" @@ -27,131 +28,108 @@ namespace DD4hep { /// Namespace for the geometry part of the AIDA detector description toolkit namespace Geometry { - // Forward declarations class DetElement; + class DetElementObject; + } + + /// Namespace for the conditions part of the AIDA detector description toolkit + namespace Conditions { + + // Forward declarations + class ConditionsLoader; + class ConditionsPool; class Condition; + class IOVType; + class IOV; - /// Conditions internal namespace declaration - /** Internally defined datastructures are not presented to the - * user directly, but are used by dedicated views. + /// Class describing an opaque conditions data block + /** * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS */ - namespace ConditionsInterna { - class ConditionContainer; - class ConditionObject; - class Entry; - class IOV; - - /// Class describing the interval of validty - /** - * - * \author M.Frank - * \version 1.0 - * \ingroup DD4HEP_GEOMETRY - */ - class IOV { - friend class Condition; - public: - enum { - UNKNOWN_IOV = 1<<0 - } _IOVTypes; - /// IOV buffer type: Must be a bitmap! - int type; - int data[4]; - int _spare; - /// Initializing constructor - IOV(int t=UNKNOWN_IOV); - /// Standard Destructor - ~IOV(); - /// Move the data content: 'from' will be reset to NULL - void move(IOV& from); - /// Create IOV data from string representation - void fromString(const std::string& rep); - /// Create string representation of the IOV - std::string str(); - }; - - /// Class describing an opaque conditions data block - /** - * - * \author M.Frank - * \version 1.0 - * \ingroup DD4HEP_GEOMETRY - */ - class BlockData : public Block { - friend class Condition; - friend class Object; + class BlockData : public Block { + friend class Condition; + friend class Object; - private: - enum { - PLAIN_DATA = 1<<0, - ALLOC_DATA = 1<<1, - BOUND_DATA = 1<<2 - } _DataTypes; - /// Data buffer: plain data are allocated directly on this buffer - unsigned int data[16]; - /// Destructor function -- only set if the object is valid - void (*destruct)(void*); - /// Constructor function -- only set if the object is valid - void (*copy)(void*,const void*); + private: + enum { + PLAIN_DATA = 1<<0, + ALLOC_DATA = 1<<1, + BOUND_DATA = 1<<2 + } _DataTypes; + /// Data buffer: plain data are allocated directly on this buffer + unsigned int data[16]; + /// Destructor function -- only set if the object is valid + void (*destruct)(void*); + /// Constructor function -- only set if the object is valid + void (*copy)(void*,const void*); - public: - /// Data buffer type: Must be a bitmap! - int type; + public: + /// Data buffer type: Must be a bitmap! + int type; - /// Standard initializing constructor - BlockData(); - /// Standard Destructor - ~BlockData(); - /// Move the data content: 'from' will be reset to NULL - void move(BlockData& from); - /// Set data value - void bind(const BasicGrammar* grammar, - void (*ctor)(void*,const void*), - void (*dtor)(void*)); - /// Set data value - void assign(const void* ptr,const std::type_info& typ); - }; + /// Standard initializing constructor + BlockData(); + /// Standard Destructor + ~BlockData(); + /// Move the data content: 'from' will be reset to NULL + void move(BlockData& from); + /// Set data value + void bind(const BasicGrammar* grammar, + void (*ctor)(void*,const void*), + void (*dtor)(void*)); + /// Set data value + void assign(const void* ptr,const std::type_info& typ); + }; - /// The intermediate conditions data - /** - * - * \author M.Frank - * \version 1.0 - * \ingroup DD4HEP_GEOMETRY + /// The data class behind a conditions container handle. + /** + * See ConditionsInterna.cpp for the implementation. + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS */ - class Entry : public NamedObject { - public: - /// Reference to the detector element - DetElement detector; - /// Conditions type (was the tag in the XML) - std::string type; - /// The actual conditions data - std::string value; - /// The validity string to be interpreted by the updating engine - std::string validity; - /// Default constructor - Entry() {} - /// Initializing constructor - Entry(const DetElement& det, const std::string& nam, const std::string& typ, const std::string& valid); - /// Copy constructor - Entry(const Entry& c); - /// Default destructor - virtual ~Entry(); - /// Assignment operator - Entry& operator=(const Entry& c); - }; + class ConditionsLoader { + protected: + /// Protected destructor + virtual ~ConditionsLoader(); + public: + /// Access the conditions loading + virtual Condition get(Geometry::DetElement element, const std::string& key, const IOV& iov) = 0; + }; + /// Conditions internal namespace declaration + /** Internally defined datastructures are not presented to the + * user directly, but are used by dedicated views. + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + namespace Interna { + + // Forward declarations + class ConditionContainer; + class ConditionObject; + /// The data class behind a conditions handle. /** + * See ConditionsInterna.cpp for the implementation. * - * \author M.Frank - * \version 1.0 - * \ingroup DD4HEP_GEOMETRY + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS */ class ConditionObject : public NamedObject { public: + enum ConditionState { + INACTIVE = 0, + ACTIVE = 1 + }; /// Condition value (in string form) std::string value; /// Condition validity (in string form) @@ -161,42 +139,75 @@ namespace DD4hep { /// Comment string std::string comment; /// The detector element - DetElement detector; + Geometry::DetElement detector; /// Data block BlockData data; + /// Reference to conditions pool + ConditionsPool* pool; /// Interval of validity - IOV iov; + const IOV* iov; + /// Hash value of the name + int hash; + /// Flags + int flags; + /// Reference count + int refCount; /// Standard constructor ConditionObject(); /// Standard Destructor virtual ~ConditionObject(); /// Move data content: 'from' will be reset to NULL ConditionObject& move(ConditionObject& from); + /// Access safely the IOV + const IOV* iov_data() const; + /// Access safely the IOV-type + const IOVType* iov_type() const; }; /// The data class behind a conditions container handle. /** + * See ConditionsInterna.cpp for the implementation. * - * \author M.Frank - * \version 1.0 - * \ingroup DD4HEP_GEOMETRY + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS */ class ConditionContainer : public NamedObject { - public: -#ifndef __CINT__ - /// Container definition - typedef std::map<std::string, DD4hep::Geometry::Condition> Entries; -#endif - std::map<std::string,DD4hep::Geometry::Condition> entries; + private: + // We only allow creation and deletion by the central detector element + friend class Geometry::DetElement; + friend class Geometry::DetElementObject; + /// Standard constructor ConditionContainer(); /// Default destructor virtual ~ConditionContainer(); + + public: /// Clear all conditions. Auto-delete of all existing entries + void lock(); + void unlock(); void removeElements(); + void add(Condition condition); + void remove(int condition_hash); + size_t size() const { return entries.size(); } +#ifdef __CINT__ + Handle<NamedObject> detector; +#else + typedef Container::Entries Entries; + Entries& elements() { return entries; } + const Entries& elements() const { return entries; } + public: + /// The hosting detector element + DetElement detector; +#endif + private: + /// Conditions container declaration + Container::Entries entries; + // std::map<std::string,Condition> entries; }; - } /* End namespace ConditionsInterna */ + } /* End namespace Interna */ template <typename T> static void copyObject(void* t, const void* s) { *((T*)t) = *((const T*)s); @@ -218,7 +229,7 @@ namespace DD4hep { /// Bind the data of the conditions object to a given format. template <typename T> Condition& Condition::bind() { Object* o = access(); - ConditionsInterna::BlockData& b = o->data; + BlockData& b = o->data; b.bind(&BasicGrammar::instance<T>(),copyObject<T>,destructObject<T>); new(b.pointer) T(); if ( !o->value.empty() ) b.fromString(o->value); @@ -232,11 +243,12 @@ namespace DD4hep { template <typename T> const T& Condition::get() const { return access()->data.get<T>(); } - } /* End namespace Geometry */ + + } /* End namespace Conditions */ } /* End namespace DD4hep */ #define DD4HEP_DEFINE_CONDITIONS_TYPE(x) \ - namespace DD4hep { namespace Geometry { \ + namespace DD4hep { namespace Conditions { \ template Condition& Condition::bind<x>(); \ template x& Condition::get<x>(); \ template const x& Condition::get<x>() const; \ diff --git a/DDCore/include/DD4hep/objects/DetectorInterna.h b/DDCore/include/DD4hep/objects/DetectorInterna.h index d10fdeb06..043ebe6fa 100644 --- a/DDCore/include/DD4hep/objects/DetectorInterna.h +++ b/DDCore/include/DD4hep/objects/DetectorInterna.h @@ -80,7 +80,10 @@ namespace DD4hep { typedef /* DD4hep::Geometry:: */ DetElement::Children Children; typedef /* DD4hep::Geometry:: */ DetElement::Extensions Extensions; typedef std::pair<Callback,unsigned long> UpdateCall; - typedef std::vector<UpdateCall> UpdateCallbacks; + typedef std::vector<UpdateCall> UpdateCallbacks; + typedef DetElement::ConditionsContainer ConditionsContainer; + typedef DetElement::Condition Condition; + typedef Conditions::IOV IOV; enum DetFlags { HAVE_WORLD_TRAFO = 1<<0, @@ -133,7 +136,7 @@ namespace DD4hep { /// Alignment entries for lower level volumes, which are NOT attached to daughter DetElements std::vector<Alignment> volume_surveys; /// The detector elements condition entry - Conditions conditions; + ConditionsContainer conditions; //@} //@{ Cached information of the detector element /// Intermediate buffer to store the transformation to the world coordination system @@ -167,6 +170,38 @@ namespace DD4hep { void revalidate(TGeoHMatrix* parent_world_trafo); }; + /// Data class with properties of a detector element + /** + * + * \author M.Frank + * \version 1.0 + * + * \ingroup DD4HEP DD4HEP_GEOMETRY + */ + class WorldObject: public DetElementObject { + public: + typedef Conditions::ConditionsLoader ConditionsLoader; + + /// Reference to the LCDD instance object + LCDD* lcdd; + + /// Conditions loader for this LCDD instance + ConditionsLoader* conditionsLoader; + + public: + //@{ Public methods to ease the usage of the data. */ + /// Default constructor + WorldObject() : DetElementObject(), lcdd(0), conditionsLoader(0) {} +#ifndef __CINT__ + /// Initializing constructor + WorldObject(LCDD& lcdd, const std::string& nam); +#endif + /// Internal object destructor: release extension object(s) + virtual ~WorldObject(); + /// Access the conditions loading + Condition getCondition(DetElement child, const std::string& key, const IOV& iov); + }; + } /* End namespace Geometry */ } /* End namespace DD4hep */ #endif /* DD4HEP_GEOMETRY_DETECTORINTERNA_H */ diff --git a/DDG4/src/ComponentProperties.cpp b/DDCore/src/ComponentProperties.cpp similarity index 93% rename from DDG4/src/ComponentProperties.cpp rename to DDCore/src/ComponentProperties.cpp index 8ecfaa630..6d7e41eed 100644 --- a/DDG4/src/ComponentProperties.cpp +++ b/DDCore/src/ComponentProperties.cpp @@ -1,4 +1,4 @@ -// $Id: $ +// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- @@ -15,7 +15,7 @@ // Framework include files #include "DD4hep/Printout.h" #include "DD4hep/BasicGrammar.h" -#include "DDG4/ComponentProperties.h" +#include "DD4hep/ComponentProperties.h" // C/C++ include files #include <stdexcept> @@ -215,6 +215,24 @@ void PropertyManager::dump() const { } } +/// Standard PropertyConfigurable constructor +PropertyConfigurable::PropertyConfigurable() { +} + +/// Default PropertyConfigurable destructor +PropertyConfigurable::~PropertyConfigurable() { +} + +/// Check property for existence +bool PropertyConfigurable::hasProperty(const string& nam) const { + return m_properties.exists(nam); +} + +/// Access single property +Property& PropertyConfigurable::property(const string& nam) { + return properties()[nam]; +} + namespace DD4hep { namespace Parsers { int parse(Property& result, const std::string& input) { @@ -239,7 +257,7 @@ namespace DD4hep { #include "Math/Vector4D.h" #include "DD4hep/objects/BasicGrammar_inl.h" -#include "DDG4/ComponentProperties_inl.h" +#include "DD4hep/ComponentProperties_inl.h" DD4HEP_DEFINE_PARSER_GRAMMAR_TYPE(Property) namespace DD4hep { diff --git a/DDCore/src/Conditions.cpp b/DDCore/src/Conditions.cpp index baa24ca64..0f5da68ca 100644 --- a/DDCore/src/Conditions.cpp +++ b/DDCore/src/Conditions.cpp @@ -20,25 +20,58 @@ #include "DD4hep/objects/ConditionsInterna.h" using namespace std; -using namespace DD4hep; -using namespace DD4hep::Geometry; - -namespace { - void set_condition_values(Condition::Object* c, const Condition::Entry* e) { - c->type = e->type; - c->value = e->value; - c->comment = "----"; - c->address = "----"; - c->validity = e->validity; - c->detector = e->detector; +using namespace DD4hep::Conditions; + +std::string IOVType::str() const { + char text[256]; + ::snprintf(text,sizeof(text),"%s(%d)",name.c_str(),int(type)); + return text; +} + +/// Initializing constructor: Does not set reference to IOVType ! +IOV::IOV() : iovType(0), keyData(0,0), optData(0) { + type = int(IOVType::UNKNOWN_IOV); +} + +/// Initializing constructor +IOV::IOV(const IOVType* typ) : iovType(typ), keyData(0,0), optData(0) { + type = typ ? typ->type : int(IOVType::UNKNOWN_IOV); +} + +/// Standard Destructor +IOV::~IOV() { +} + +/// Move the data content: 'from' will be reset to NULL +void IOV::move(IOV& from) { + ::memcpy(this,&from,sizeof(IOV)); + from.keyData.first = from.keyData.second = from.optData = 0; + from.type = int(IOVType::UNKNOWN_IOV); + from.iovType = 0; +} + +/// Create string representation of the IOV +string IOV::str() const { + char text[256]; + if ( iovType ) { + ::snprintf(text,sizeof(text),"%s(%d):[%d-%d]", + iovType->name.c_str(),int(iovType->type),keyData.first, keyData.second); } - Condition make_condition(const Condition::Entry* e) { - Condition c(e->name); - set_condition_values(c.ptr(),e); - return c; + else { + ::snprintf(text,sizeof(text),"%d:[%d-%d]",type,keyData.first, keyData.second); } + return text; } +/// Check for validity containment +bool IOV::contains(const IOV& iov) const { + if ( key_is_contained(iov.keyData,keyData) ) { + unsigned int typ1 = iov.iovType ? iov.iovType->type : iov.type; + unsigned int typ2 = iovType ? iovType->type : type; + return typ1 == typ2; + } + return false; +} /// Standard initializing constructor Block::Block() : grammar(0), pointer(0) { @@ -49,7 +82,7 @@ Block::~Block() { } /// Create data block from string representation -void Block::fromString(const std::string& rep) { +void Block::fromString(const string& rep) { if ( pointer && grammar ) { grammar->fromString(pointer,rep); return; @@ -58,7 +91,7 @@ void Block::fromString(const std::string& rep) { } /// Create string representation of the data block -std::string Block::str() { +string Block::str() { if ( pointer && grammar ) { return grammar->str(pointer); } @@ -66,8 +99,10 @@ std::string Block::str() { } /// Initializing constructor -Condition::Condition(const string& nam) : Handle<Object>() { - assign(new ConditionsInterna::ConditionObject(),nam,"condition"); +Condition::Condition(const string& nam,const string& typ) : Handle<Object>() { + Object* o = new Object(); + assign(o,nam,typ); + o->hash = hash32(nam); } /// Assignment operator @@ -87,13 +122,13 @@ Block& Condition::block() const { } /// Access the IOV type -int Condition::iovType() const { - return access()->iov.type; +const IOVType& Condition::iovType() const { + return *(access()->iov_type()); } /// Access the IOV block -Condition::IOV& Condition::iov() const { - return access()->iov; +const IOV& Condition::iov() const { + return *(access()->iov_data()); } /// Access the name of the condition @@ -148,81 +183,54 @@ const DD4hep::BasicGrammar& Condition::descriptor() const { return *g; } -/// Replace the data block of the condition with a new value. Free old data -Condition& Condition::replace(Entry* new_condition) { - set_condition_values(access(),new_condition); - return rebind(); -} - /// Re-evaluate the conditions data according to the previous bound type definition Condition& Condition::rebind() { Object* o = access(); o->data.fromString(o->value); - o->iov.fromString(o->validity); + //o->iov->fromString(o->validity); printout(INFO,"Condition","+++ condition:%s : %s rebinding value:%s", detector().path().c_str(), name().c_str(), o->value.c_str()); return *this; } /// Clear all conditions. Auto-delete of all existing entries -void Conditions::removeElements() const { +void Container::removeElements() const { if ( !isValid() ) { - invalidHandleError<Conditions>(); + invalidHandleError<Container>(); } data<Object>()->removeElements(); } /// Access the number of conditons available for this detector element -size_t Conditions::count() const { +size_t Container::count() const { if ( !isValid() ) { - invalidHandleError<Conditions>(); + invalidHandleError<Container>(); } - return data<Object>()->entries.size(); + return data<Object>()->size(); } /// Access the full map of conditons -Conditions::Entries& Conditions::entries() const { +Container::Entries& Container::entries() const { if ( !isValid() ) { - invalidHandleError<Conditions>(); + invalidHandleError<Container>(); } - return data<Object>()->entries; -} - -/** Set a single conditions value (eventually existing entries are overwritten) - * Note: Passing a valid handle also passes ownership!!! - * - * Failure return 0 in case an invalid handle is present - * Successful insertion returns 1 - * Successful overwriting an existing value returns 3 - */ -int Conditions::set(Entry* cond) { - int status = 0; - if ( cond ) { - Condition c; - Object* o = 0; - status = 1; - if ( isValid() ) { - o = data<Object>(); - Entries::iterator i = o->entries.find(cond->name); - if ( i != o->entries.end() ) { - (*i).second.replace(cond); - c = (*i).second; - status = 2; - } - } - else { - DetElement det(cond->detector); - assign(o=new ConditionsInterna::ConditionContainer(),cond->name,cond->detector.name()); - det._data().conditions = *this; // Ugly. Need to fix this.... - } - if ( status == 1 ) { - c = make_condition(cond); - o->entries.insert(make_pair(cond->name,c)); - } - printout(INFO,"Conditions","+++ %s condition:%s : %s value:%s", - (status==1) ? "Added NEW" : "Replaced existing", - c.detector().path().c_str(), c.name().c_str(), c->value.c_str()); - delete cond; + return data<Object>()->elements(); +} + +/// Access to condition objects +Condition Container::operator[](const std::string& key) { + return this->operator[](hash32(key)); +} + +/// Access to condition objects +Condition Container::operator[](int condition_hash) { + Object* c = ptr(); + if ( !c ) { + invalidHandleError<Container>(); } - return status; + Entries::iterator i=c->elements().find(condition_hash); + if ( i != c->elements().end() ) return (*i).second; + except("ConditionContainer", + "No condition with key 0x%08X present!",condition_hash); + return Condition(); } diff --git a/DDCore/src/ConditionsInterna.cpp b/DDCore/src/ConditionsInterna.cpp index b54d50356..110190759 100644 --- a/DDCore/src/ConditionsInterna.cpp +++ b/DDCore/src/ConditionsInterna.cpp @@ -13,46 +13,23 @@ //========================================================================== // Framework includes +#include "DD4hep/Mutex.h" #include "DD4hep/Handle.inl" #include "DD4hep/Printout.h" #include "DD4hep/Detector.h" +#include "DD4hep/DetectorTools.h" #include "DD4hep/InstanceCount.h" #include "DD4hep/objects/ConditionsInterna.h" using namespace std; -using namespace DD4hep; -using namespace DD4hep::Geometry; -using namespace DD4hep::Geometry::ConditionsInterna; +using namespace DD4hep::Conditions; -DD4HEP_INSTANTIATE_HANDLE_NAMED(ConditionsInterna::ConditionObject); -DD4HEP_INSTANTIATE_HANDLE_NAMED(ConditionsInterna::ConditionContainer); - -/// Initializing constructor -IOV::IOV(int t) : type(t) { - data[0]=data[1]=data[2]=data[3]=0; +namespace { + DD4hep::dd4hep_mutex_t s_conditionsMutex; } -/// Standard Destructor -IOV::~IOV() { -} - -/// Move the data content: 'from' will be reset to NULL -void IOV::move(IOV& from) { - ::memcpy(this,&from,sizeof(IOV)); - from.data[0]=from.data[1]=from.data[2]=from.data[3]=0; - from.type = UNKNOWN_IOV; -} - -/// Create IOV data from string representation -void IOV::fromString(const std::string& rep) { - notImplemented("void IOV::fromString(const std::string& rep): "+rep); -} - -/// Create string representation of the IOV -std::string IOV::str() { - notImplemented("void IOV::fromString(const std::string& rep)"); - return ""; -} +DD4HEP_INSTANTIATE_HANDLE_NAMED(Interna::ConditionObject); +DD4HEP_INSTANTIATE_HANDLE_NAMED(Interna::ConditionContainer); /// Standard initializing constructor BlockData::BlockData() : Block(), destruct(0), copy(0), type(0) { @@ -67,7 +44,7 @@ BlockData::~BlockData() { pointer = 0; grammar = 0; } - +#if 0 /// Move the data content: 'from' will be reset to NULL void BlockData::move(BlockData& from) { pointer = from.pointer; @@ -83,7 +60,7 @@ void BlockData::move(BlockData& from) { from.pointer = 0; from.grammar = 0; } - +#endif /// Set data value void BlockData::bind(const BasicGrammar* g, void (*ctor)(void*,const void*), void (*dtor)(void*)) { if ( !grammar ) { @@ -114,76 +91,89 @@ void BlockData::assign(const void* ptr, const type_info& typ) { } /// Standard constructor -ConditionObject::ConditionObject() : NamedObject(), detector(), data(), iov() { +Interna::ConditionObject::ConditionObject() + : NamedObject(), detector(), data(), iov(0), hash(0), flags(0), refCount(0) +{ InstanceCount::increment(this); } /// Standard Destructor -ConditionObject::~ConditionObject() { +Interna::ConditionObject::~ConditionObject() { InstanceCount::decrement(this); } -/// Assignment operator -ConditionObject& ConditionObject::move(ConditionObject& c) { - if ( this != &c ) { - name = c.name; - type = c.type; - address = c.address; - comment = c.comment; - detector = c.detector; - data.move(c.data); - iov.move(c.iov); - } +/// Move data content: 'from' will be reset to NULL +Interna::ConditionObject& Interna::ConditionObject::move(ConditionObject& /* from */) { return *this; } -/// Initializing constructor -Entry::Entry(const DetElement& det, const string& nam, - const string& typ, const string& valid) - : NamedObject(nam), detector(det), type(typ), value(), validity(valid) -{ - InstanceCount::increment(this); +/// Access safely the IOV +const IOV* Interna::ConditionObject::iov_data() const { + if ( iov ) return iov; + invalidHandleError<IOV>(); + return 0; } -/// Copy constructor -Entry::Entry(const Entry& c) - : NamedObject(c), detector(c.detector), type(c.type), value(c.value), validity(c.validity) -{ +/// Access safely the IOV-type +const IOVType* Interna::ConditionObject::iov_type() const { + if ( iov && iov->iovType ) return iov->iovType; + invalidHandleError<IOVType>(); + return 0; +} + +/// Standard constructor +Interna::ConditionContainer::ConditionContainer() : NamedObject(), entries() { InstanceCount::increment(this); } /// Default destructor -Entry::~Entry() { +Interna::ConditionContainer::~ConditionContainer() { + removeElements(); InstanceCount::decrement(this); } -/// Assignment operator -Entry& Entry::operator=(const Entry& c) { - if ( this != &c ) { - this->NamedObject::operator=(c); - detector = c.detector; - type = c.type; - value = c.value; - validity = c.validity; +/// Clear all attached conditions. +void Interna::ConditionContainer::removeElements() { + dd4hep_lock_t locked_call(s_conditionsMutex); + for(Entries::iterator i=entries.begin(); i!=entries.end();++i) + (*i).second->flags &= ~(ConditionObject::ACTIVE); + entries.clear(); +} + +void Interna::ConditionContainer::add(Condition condition) { + ConditionObject* o = condition.ptr(); + if ( o ) { + if ( !o->hash ) o->hash = hash32(condition.name()); + dd4hep_lock_t locked_call(s_conditionsMutex); + Entries::iterator i=entries.find(o->hash); + o->flags |= ConditionObject::ACTIVE; + if ( i != entries.end() ) { + (*i).second->flags &= ~(ConditionObject::ACTIVE); + (*i).second = o; + return; + } + entries[o->hash] = o; + return; } - return *this; + invalidHandleError<Condition>(); } -/// Standard constructor -ConditionContainer::ConditionContainer() : NamedObject() { - InstanceCount::increment(this); +void Interna::ConditionContainer::remove(int condition_hash) { + dd4hep_lock_t locked_call(s_conditionsMutex); + Entries::iterator i=entries.find(condition_hash); + if ( i != entries.end() ) { + (*i).second->flags &= ~(ConditionObject::ACTIVE); + } } -/// Default destructor -ConditionContainer::~ConditionContainer() { - removeElements(); - InstanceCount::decrement(this); +void Interna::ConditionContainer::lock() { + s_conditionsMutex.lock(); } -/// Clear all conditions. Auto-delete of all existing entries -void ConditionContainer::removeElements() { - for(Entries::iterator i=entries.begin(); i != entries.end(); ++i) - delete (*i).second.ptr(); - entries.clear(); +void Interna::ConditionContainer::unlock() { + s_conditionsMutex.unlock(); } +/// Protected destructor +ConditionsLoader::~ConditionsLoader() { +} diff --git a/DDCore/src/Detector.cpp b/DDCore/src/Detector.cpp index 5742b477a..99559930a 100644 --- a/DDCore/src/Detector.cpp +++ b/DDCore/src/Detector.cpp @@ -14,7 +14,9 @@ // Framework include files #include "DD4hep/objects/DetectorInterna.h" +#include "DD4hep/objects/ConditionsInterna.h" #include "DD4hep/DetectorTools.h" +#include "DD4hep/World.h" #include "DD4hep/LCDD.h" using namespace std; @@ -139,8 +141,29 @@ Alignment DetElement::surveyAlignment() const { } /// Access to the conditions information -Conditions DetElement::conditions() const { - return access()->conditions; +DetElement::ConditionsContainer DetElement::conditions() const { + Object* o = access(); + if ( o->conditions.isValid() ) return o->conditions; + o->conditions.assign(new ConditionsContainer::Object(),"conditions",""); + o->conditions->detector = *this; + return o->conditions; +} + +/// Access to the conditions information +DetElement::Condition +DetElement::condition(const std::string& key) const { + return access()->conditions[key]; +} + +/// Access to condition objects. If not present, load condition. +DetElement::Condition +DetElement::condition(const std::string& key, const IOV& iov) { + typedef DetElement::ConditionsContainer::Object::Entries _E; + _E& ents = conditions()->entries; + _E::iterator i = ents.find(hash32(key)); + if ( i != ents.end() ) return (*i).second; + World world(Geometry::DetectorTools::topElement(*this)); + return world.getCondition(*this,key,iov); } const DetElement::Children& DetElement::children() const { @@ -163,8 +186,8 @@ DetElement DetElement::parent() const { return (o) ? o->parent : 0; } -void DetElement::check(bool condition, const string& msg) const { - if (condition) { +void DetElement::check(bool cond, const string& msg) const { + if (cond) { throw runtime_error("DD4hep: " + msg); } } diff --git a/DDCore/src/DetectorInterna.cpp b/DDCore/src/DetectorInterna.cpp index 98965a2ec..80fa958fc 100644 --- a/DDCore/src/DetectorInterna.cpp +++ b/DDCore/src/DetectorInterna.cpp @@ -22,6 +22,14 @@ #include "TGeoMatrix.h" #include "TGeoManager.h" #include "DD4hep/objects/DetectorInterna.h" +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + /// Namespace for the conditions part of the AIDA detector description toolkit + namespace Conditions { + // Forward declarations + class ConditionsManager; + } +} using namespace std; using namespace DD4hep; @@ -29,6 +37,7 @@ using namespace DD4hep::Geometry; typedef DetectorTools::PlacementPath PlacementPath; typedef DetectorTools::ElementPath ElementPath; +DD4HEP_INSTANTIATE_HANDLE_NAMED(WorldObject); DD4HEP_INSTANTIATE_HANDLE_NAMED(DetElementObject); DD4HEP_INSTANTIATE_HANDLE_NAMED(SensitiveDetectorObject); @@ -85,7 +94,8 @@ DetElementObject::DetElementObject(const std::string& nam, int ident) DetElementObject::~DetElementObject() { for_each(children.begin(), children.end(), destroyHandles(children)); deletePtr (referenceTrafo); - destroyHandle(conditions); + if ( conditions.isValid() ) delete conditions.ptr(); + conditions = ConditionsContainer(); alignment.clear(); placement.clear(); idealPlace.clear(); @@ -102,7 +112,7 @@ DetElementObject* DetElementObject::clone(int new_id, int flg) const { obj->flag = 0; obj->combineHits = combineHits; obj->alignment = Alignment(); - obj->conditions = Conditions(); + obj->conditions = ConditionsContainer(); obj->parent = DetElement(); if ( (flg & DetElement::COPY_PLACEMENT) == DetElement::COPY_PLACEMENT ) { obj->placement = placement; @@ -259,8 +269,29 @@ void DetElementObject::update(unsigned int tags, void* param) { revalidate(parent_world_trafo); } for(UpdateCallbacks::const_iterator i=updateCalls.begin(); i != updateCalls.end(); ++i) { - if ( (tags&((*i).second)) == tags ) { + if ( (tags&((*i).second)) ) { (*i).first.execute(args); } } } + +/// Initializing constructor +WorldObject::WorldObject(LCDD& _lcdd, const string& nam) + : DetElementObject(nam,0), lcdd(&_lcdd), conditionsLoader(0) +{ +} + +/// Internal object destructor: release extension object(s) +WorldObject::~WorldObject() { +} + +/// Access the conditions loading +DetElement::Condition +WorldObject::getCondition(DetElement child,const string& key, const IOV& iov) { + if ( conditionsLoader ) { + return conditionsLoader->get(child,key,iov); + } + + except("Conditions","+++ No ConditionsLoader registered to this LCDD instance!"); + return DetElement::Condition(); +} diff --git a/DDCore/src/Errors.cpp b/DDCore/src/Errors.cpp new file mode 100644 index 000000000..e4d3c0f16 --- /dev/null +++ b/DDCore/src/Errors.cpp @@ -0,0 +1,34 @@ +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// \author Markus Frank +// \date 2016-02-02 +// \version 1.0 +// +//========================================================================== +// $Id$ + +// Framework include files +#include "DD4hep/Errors.h" + +// C/C++ includes +#include <cerrno> +#include <cstring> + +#define IMPLEMENT(x,y) std::string x () { return ::strerror( errno = y ); } + +namespace DD4hep { namespace Errors { + IMPLEMENT(noPermission,EPERM) // 1 + IMPLEMENT(noEntry,ENOENT) // 2 + IMPLEMENT(ioError,EIO) // 5 + IMPLEMENT(invalidArg,EINVAL) // 22 + IMPLEMENT(noSys,ENOSYS) // 38 + IMPLEMENT(linkRange,ELNRNG) // 48 + IMPLEMENT(cancelled,ECANCELED) // 125 + IMPLEMENT(noKey,ENOKEY) // 126 + }} diff --git a/DDCore/src/Handle.cpp b/DDCore/src/Handle.cpp index 33e520f55..7eaad7e86 100644 --- a/DDCore/src/Handle.cpp +++ b/DDCore/src/Handle.cpp @@ -36,7 +36,7 @@ using namespace std; using namespace DD4hep; using namespace DD4hep::Geometry; -int DD4hep::Geometry::_toInt(const string& value) { +int DD4hep::_toInt(const string& value) { string s(value); size_t idx = s.find("(int)"); if (idx != string::npos) @@ -52,7 +52,7 @@ int DD4hep::Geometry::_toInt(const string& value) { return (int) result; } -long DD4hep::Geometry::_toLong(const string& value) { +long DD4hep::_toLong(const string& value) { string s(value); size_t idx = s.find("(int)"); if (idx != string::npos) @@ -68,11 +68,11 @@ long DD4hep::Geometry::_toLong(const string& value) { return (long) result; } -bool DD4hep::Geometry::_toBool(const string& value) { +bool DD4hep::_toBool(const string& value) { return value == "true" || value == "yes"; } -float DD4hep::Geometry::_toFloat(const string& value) { +float DD4hep::_toFloat(const string& value) { double result = eval.evaluate(value.c_str()); if (eval.status() != XmlTools::Evaluator::OK) { cerr << value << ": "; @@ -82,7 +82,7 @@ float DD4hep::Geometry::_toFloat(const string& value) { return (float) result; } -double DD4hep::Geometry::_toDouble(const string& value) { +double DD4hep::_toDouble(const string& value) { double result = eval.evaluate(value.c_str()); if (eval.status() != XmlTools::Evaluator::OK) { cerr << value << ": "; @@ -92,28 +92,28 @@ double DD4hep::Geometry::_toDouble(const string& value) { return result; } -template <> int DD4hep::Geometry::_multiply<int>(const string& left, const string& right) { +template <> int DD4hep::_multiply<int>(const string& left, const string& right) { return (int) _toDouble(left + "*" + right); } -template <> long DD4hep::Geometry::_multiply<long>(const string& left, const string& right) { +template <> long DD4hep::_multiply<long>(const string& left, const string& right) { return (long) _toDouble(left + "*" + right); } -template <> float DD4hep::Geometry::_multiply<float>(const string& left, const string& right) { +template <> float DD4hep::_multiply<float>(const string& left, const string& right) { return _toFloat(left + "*" + right); } -template <> double DD4hep::Geometry::_multiply<double>(const string& left, const string& right) { +template <> double DD4hep::_multiply<double>(const string& left, const string& right) { return _toDouble(left + "*" + right); } -void DD4hep::Geometry::_toDictionary(const string& name, const string& value) { +void DD4hep::_toDictionary(const string& name, const string& value) { _toDictionary(name, value, "number"); } /// Enter name value pair to the dictionary. \ingroup DD4HEP_GEOMETRY -void DD4hep::Geometry::_toDictionary(const std::string& name, const std::string& value, const std::string& typ) { +void DD4hep::_toDictionary(const std::string& name, const std::string& value, const std::string& typ) { if ( typ == "string" ) { eval.setEnviron(name.c_str(),value.c_str()); return; @@ -144,45 +144,43 @@ template <typename T> static inline string __to_string(T value, const char* fmt) return text; } -string DD4hep::Geometry::_toString(bool value) { +string DD4hep::_toString(bool value) { return value ? "true" : "false"; } -string DD4hep::Geometry::_toString(int value, const char* fmt) { +string DD4hep::_toString(int value, const char* fmt) { return __to_string(value, fmt); } -string DD4hep::Geometry::_toString(float value, const char* fmt) { +string DD4hep::_toString(float value, const char* fmt) { return __to_string(value, fmt); } -string DD4hep::Geometry::_toString(double value, const char* fmt) { +string DD4hep::_toString(double value, const char* fmt) { return __to_string(value, fmt); } -string DD4hep::Geometry::_ptrToString(const void* value, const char* fmt) { +string DD4hep::_ptrToString(const void* value, const char* fmt) { return __to_string(value, fmt); } namespace DD4hep { - namespace Geometry { - static long s_numVerifies = 0; + static long s_numVerifies = 0; - long num_object_validations() { - return s_numVerifies; - } - void increment_object_validations() { - ++s_numVerifies; - } - void warning_deprecated_xml_factory(const char* name) { - const char* edge = "++++++++++++++++++++++++++++++++++++++++++"; - size_t len = ::strlen(name); - cerr << edge << edge << edge << endl; - cerr << "++ The usage of the factory: \"" << name << "\" is DEPRECATED due to naming conventions." - << setw(53-len) << right << "++" << endl; - cerr << "++ Please use \"DD4hep_" << name << "\" instead." << setw(93-len) << right << "++" << endl; - cerr << edge << edge << edge << endl; - } + long num_object_validations() { + return s_numVerifies; + } + void increment_object_validations() { + ++s_numVerifies; + } + void warning_deprecated_xml_factory(const char* name) { + const char* edge = "++++++++++++++++++++++++++++++++++++++++++"; + size_t len = ::strlen(name); + cerr << edge << edge << edge << endl; + cerr << "++ The usage of the factory: \"" << name << "\" is DEPRECATED due to naming conventions." + << setw(53-len) << right << "++" << endl; + cerr << "++ Please use \"DD4hep_" << name << "\" instead." << setw(93-len) << right << "++" << endl; + cerr << edge << edge << edge << endl; } } @@ -190,16 +188,14 @@ namespace DD4hep { typedef DDSegmentation::Segmentation _Segmentation; //INSTANTIATE_UNNAMED(_Segmentation); namespace DD4hep { - namespace Geometry { - template <> void Handle<_Segmentation>::assign(_Segmentation* s, const std::string& n, const std::string&) { - this->m_element = s; - s->setName(n); - } - template <> const char* Handle<_Segmentation>::name() const { - return this->m_element ? this->m_element->name().c_str() : ""; - } - template class DD4hep::Geometry::Handle<_Segmentation>; + template <> void Handle<_Segmentation>::assign(_Segmentation* s, const std::string& n, const std::string&) { + this->m_element = s; + s->setName(n); + } + template <> const char* Handle<_Segmentation>::name() const { + return this->m_element ? this->m_element->name().c_str() : ""; } + template class DD4hep::Handle<_Segmentation>; } #include "DD4hep/LCDD.h" diff --git a/DDCore/src/LCDDImp.cpp b/DDCore/src/LCDDImp.cpp index e9fceac0a..245f98200 100644 --- a/DDCore/src/LCDDImp.cpp +++ b/DDCore/src/LCDDImp.cpp @@ -19,6 +19,7 @@ #include "DD4hep/LCDDHelper.h" #include "DD4hep/InstanceCount.h" #include "DD4hep/objects/VolumeManagerInterna.h" +#include "DD4hep/objects/DetectorInterna.h" #include "LCDDImp.h" // C/C++ include files @@ -50,10 +51,6 @@ using namespace DD4hep::Geometry; using namespace DD4hep; using namespace std; namespace { - struct TopDetElement: public DetElement { - TopDetElement(const string& nam) : DetElement(nam,/* "structure", */0) { - } - }; struct TypePreserve { LCDDBuildType& m_t; TypePreserve(LCDDBuildType& t) @@ -331,12 +328,13 @@ vector<string> LCDDImp::detectorTypes() const { } /// Access a set of subdetectors according to the sensitive type. -const vector<DetElement>& LCDDImp::detectors(const string& type) { +const vector<DetElement>& LCDDImp::detectors(const string& type, bool throw_exc) { if ( m_manager->IsClosed() ) { - // DetectorTypeMap::const_iterator i=m_detectorTypes.find(type); - // if ( i != m_detectorTypes.end() ) return (*i).second; - // throw runtime_error("detectors("+type+"): Detectors of this type do not exist in the current setup!"); - + if ( throw_exc ) { + DetectorTypeMap::const_iterator i=m_detectorTypes.find(type); + if ( i != m_detectorTypes.end() ) return (*i).second; + throw runtime_error("detectors("+type+"): Detectors of this type do not exist in the current setup!"); + } // return empty vector instead of exception return m_detectorTypes[ type ] ; } @@ -503,7 +501,7 @@ void LCDDImp::init() { m_materialVacuum = material("Vacuum"); Volume world_vol("world_volume", worldSolid, m_materialAir); - m_world = TopDetElement("world"); + m_world = DetElement(new WorldObject(*this,"world")); m_worldVol = world_vol; // Set the world volume to invisible. VisAttr worldVis("WorldVis"); diff --git a/DDCore/src/LCDDImp.h b/DDCore/src/LCDDImp.h index a04f2743d..206d55ecf 100644 --- a/DDCore/src/LCDDImp.h +++ b/DDCore/src/LCDDImp.h @@ -258,8 +258,10 @@ namespace DD4hep { - The sensitive type of a detector is set in the 'detector constructor'. - Not sensitive detector structures have the name 'passive' - Compounds (ie. nested detectors) are of type 'compound' + - If throw_exc is set to true, an exception is thrown if the type + is not present. Otherwise an empty detector container is returned. */ - virtual const std::vector<DetElement>& detectors(const std::string& type); + virtual const std::vector<DetElement>& detectors(const std::string& type, bool throw_exc); /// Access a set of subdetectors according to several sensitive types. virtual std::vector<DetElement> detectors(const std::string& type1, @@ -275,7 +277,7 @@ namespace DD4hep { * includeFlag set but none of the properties given in excludeFlag */ virtual std::vector<DetElement> detectors(unsigned int includeFlag, - unsigned int excludeFlag=0 ) const ; + unsigned int excludeFlag=0 ) const ; #define __R return *this diff --git a/DDCore/src/LCDDLoad.cpp b/DDCore/src/LCDDLoad.cpp index 63f4a051d..b46eca4b5 100644 --- a/DDCore/src/LCDDLoad.cpp +++ b/DDCore/src/LCDDLoad.cpp @@ -86,7 +86,7 @@ void LCDDLoad::processXMLElement(const std::string& xmlfile, const XML::Handle_t long result = PluginService::Create<long>(type, m_lcdd, &handle); if (0 == result) { PluginDebug dbg; - result = PluginService::Create<long>(type, m_lcdd, &xml_root); + result = PluginService::Create<long>(type, m_lcdd, &handle); if ( 0 == result ) { throw runtime_error("DD4hep: Failed to locate plugin to interprete files of type" " \"" + tag + "\" - no factory:" + type + ". " + dbg.missingFactory(type)); diff --git a/DDCore/src/PluginCreators.cpp b/DDCore/src/PluginCreators.cpp new file mode 100644 index 000000000..d33a5d0be --- /dev/null +++ b/DDCore/src/PluginCreators.cpp @@ -0,0 +1,62 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include "DD4hep/PluginCreators.h" +#include "DD4hep/Primitives.h" +#include "DD4hep/Printout.h" +#include "DD4hep/Plugins.h" + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + static inline ComponentCast* component(void* p) { return (ComponentCast*)p; } + + void* createPlugin(const std::string& factory, Geometry::LCDD& lcdd, int argc, char** argv, void* (*cast)(void*)) + { + void* object = PluginService::Create<void*>(factory, &lcdd, argc, argv); + if ( !object ) { + PluginDebug dbg; + object = PluginService::Create<void*>(factory, &lcdd, argc, argv); + if ( !object ) { + except("ConditionsManager","DD4hep: plugin: Failed to locate plugin %s. [%s].", + factory.c_str(), dbg.missingFactory(factory).c_str()); + } + } + if ( cast ) { + void* obj = cast(object); + if ( obj ) return obj; + invalidHandleAssignmentError(typeid(cast),typeid(*component(object))); + } + return object; + } + + /// Handler for factories of type: ConstructionFactory + void* createPlugin(const std::string& factory, Geometry::LCDD& lcdd, void* (*cast)(void*)) + { + char* argv[] = {0}; + int argc = 0; + return createPlugin(factory, lcdd, argc, argv, cast); + } + /// Handler for factories of type: ConstructionFactory + void* createPlugin(const std::string& factory, + Geometry::LCDD& lcdd, + const std::string& arg, + void* (*cast)(void*)) { + char* argv[] = { (char*)arg.c_str(), 0 }; + int argc = 1; + return createPlugin(factory, lcdd, argc, argv, cast); + } + +} diff --git a/DDCore/src/Plugins.cpp b/DDCore/src/Plugins.cpp index 9693d413f..996b81e80 100644 --- a/DDCore/src/Plugins.cpp +++ b/DDCore/src/Plugins.cpp @@ -158,3 +158,4 @@ DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(long, (Geometry::LCDD*)) DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(long, (Geometry::LCDD*, const Geometry::GeoHandler*, const std::map<std::string,std::string>*)) DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(long, ()) DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(void*, (const char*)) +DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(void*, (Geometry::LCDD*,int,char**)) diff --git a/DDCore/src/Primitives.cpp b/DDCore/src/Primitives.cpp index b8577ae92..680e18c8a 100644 --- a/DDCore/src/Primitives.cpp +++ b/DDCore/src/Primitives.cpp @@ -152,11 +152,16 @@ std::string DD4hep::typeName(const std::type_info& typ) { return __typeinfoName(typ); } -void DD4hep::invalidHandleError(const std::type_info& type) { +void DD4hep::invalidHandleError(const std::type_info& type) + throw(std::exception) +{ throw std::runtime_error("Attempt to access invalid object of type "+typeName(type)+" [Invalid Handle]"); } -void DD4hep::invalidHandleAssignmentError(const std::type_info& from, const std::type_info& to) { +void DD4hep::invalidHandleAssignmentError(const std::type_info& from, + const std::type_info& to) + throw(std::exception) +{ std::string msg = "Wrong assingment from "; msg += typeName(from); msg += " to "; @@ -166,12 +171,16 @@ void DD4hep::invalidHandleAssignmentError(const std::type_info& from, const std: } /// Throw exception when handles are check for validity -void DD4hep::notImplemented(const std::string& msg) { +void DD4hep::notImplemented(const std::string& msg) + throw(std::exception) +{ std::string m = "The requested feature " + msg + " is not implemented!"; throw std::runtime_error(m); } -void DD4hep::typeinfoCheck(const std::type_info& typ1, const std::type_info& typ2, const std::string& text) { +void DD4hep::typeinfoCheck(const std::type_info& typ1, const std::type_info& typ2, const std::string& text) + throw(std::exception) +{ if (typ1 != typ2) { throw unrelated_type_error(typ1, typ2, text); } @@ -220,7 +229,9 @@ static inline void* cast_wrap(const void* p, #endif /// Apply cast using typeinfo instead of dynamic_cast -void* DD4hep::ComponentCast::apply_dynCast(const ComponentCast& to, const void* ptr) const { +void* DD4hep::ComponentCast::apply_dynCast(const ComponentCast& to, const void* ptr) const + throw(std::exception) +{ if (&to == this) { return (void*) ptr; } @@ -229,65 +240,70 @@ void* DD4hep::ComponentCast::apply_dynCast(const ComponentCast& to, const void* void *r = (*to.cast)(ptr); if (r) return r; - { - // Now try the up-cast - r = (*cast)(ptr); - if (r) return r; + // Now try the up-cast + r = (*cast)(ptr); + if (r) return r; + throw unrelated_type_error(type, to.type, "Failed to apply abi dynamic cast operation!"); #else - void* r = (void*)ptr; - if ( to.abi_class ) { - bool cast_worked = type.__do_upcast((const class_t*)to.abi_class,&r); - if ( cast_worked ) return r; - r = (void*)ptr; - cast_worked = to.type.__do_upcast((const class_t*)abi_class,&r); - if ( cast_worked ) return r; + void* r = (void*)ptr; + if ( to.abi_class ) { + bool cast_worked = type.__do_upcast((const class_t*)to.abi_class,&r); + if ( cast_worked ) return r; + r = (void*)ptr; + cast_worked = to.type.__do_upcast((const class_t*)abi_class,&r); + if ( cast_worked ) return r; #if 0 - const class_t* src_type = (const class_t*)to.abi_class; - if (src_type) { - // First try down cast - void *r = cast_wrap(ptr, src_type, (const class_t*) abi_class, -1); - if ( r ) return r; - // Now try the up-cast - r = cast_wrap(ptr, (const class_t*) abi_class, src_type, -1); - if (r) return r; + const class_t* src_type = (const class_t*)to.abi_class; + if (src_type) { + // First try down cast + void *r = cast_wrap(ptr, src_type, (const class_t*) abi_class, -1); + if ( r ) return r; + // Now try the up-cast + r = cast_wrap(ptr, (const class_t*) abi_class, src_type, -1); + if (r) return r; + } #endif + throw unrelated_type_error(type, to.type, "Failed to apply abi dynamic cast operation!"); + } + throw unrelated_type_error(type, to.type, "Target type is not an abi class type!"); #endif - throw unrelated_type_error(type, to.type, "Failed to apply abi dynamic cast operation!"); - } - throw unrelated_type_error(type, to.type, "Target type is not an abi class type!"); - } - - /// Apply cast using typeinfo instead of dynamic_cast - void* DD4hep::ComponentCast::apply_upCast(const ComponentCast& to, const void* ptr) const { - if (&to == this) { - return (void*) ptr; - } - return apply_dynCast(to, ptr); - } +} - /// Apply cast using typeinfo instead of dynamic_cast - void* DD4hep::ComponentCast::apply_downCast(const ComponentCast& to, const void* ptr) const { - if (&to == this) { - return (void*) ptr; - } +/// Apply cast using typeinfo instead of dynamic_cast +void* DD4hep::ComponentCast::apply_upCast(const ComponentCast& to, const void* ptr) const + throw(std::exception) +{ + if (&to == this) { + return (void*) ptr; + } + return apply_dynCast(to, ptr); +} + +/// Apply cast using typeinfo instead of dynamic_cast +void* DD4hep::ComponentCast::apply_downCast(const ComponentCast& to, const void* ptr) const + throw(std::exception) +{ + if (&to == this) { + return (void*) ptr; + } #ifdef __APPLE__ - void *r = (*to.cast)(ptr); - if (r) return r; - { + void *r = (*to.cast)(ptr); + if (r) return r; + throw unrelated_type_error(type, to.type, "Failed to apply abi dynamic cast operation!"); #else - if ( to.abi_class ) { - // Since we have to cast a 'to' pointer up to the real pointer - // no virtual inheritance can be supported! - void* r = (void*)ptr; - bool cast_worked = type.__do_upcast((const class_t*)to.abi_class,&r); - if ( cast_worked ) return r; + if ( to.abi_class ) { + // Since we have to cast a 'to' pointer up to the real pointer + // no virtual inheritance can be supported! + void* r = (void*)ptr; + bool cast_worked = type.__do_upcast((const class_t*)to.abi_class,&r); + if ( cast_worked ) return r; #if 0 - void *r = cast_wrap(ptr, src_type, (const class_t*)abi_class, -1); - if (r) return r; + void *r = cast_wrap(ptr, src_type, (const class_t*)abi_class, -1); + if (r) return r; #endif + throw unrelated_type_error(type, to.type, "Failed to apply abi dynamic cast operation!"); + } + throw unrelated_type_error(type, to.type, "Target type is not an abi class type!"); #endif - throw unrelated_type_error(type, to.type, "Failed to apply abi dynamic cast operation!"); - } - throw unrelated_type_error(type, to.type, "Target type is not an abi class type!"); - } +} diff --git a/DDCore/src/VolumeManager.cpp b/DDCore/src/VolumeManager.cpp index e18dfd4c8..8f0b5fa31 100644 --- a/DDCore/src/VolumeManager.cpp +++ b/DDCore/src/VolumeManager.cpp @@ -1,4 +1,4 @@ -// $Id: $ +// $Id:$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCond/src/ConditionValidator.cpp b/DDCore/src/World.cpp similarity index 61% rename from DDCond/src/ConditionValidator.cpp rename to DDCore/src/World.cpp index 23deff009..57ba6168f 100644 --- a/DDCond/src/ConditionValidator.cpp +++ b/DDCore/src/World.cpp @@ -1,4 +1,4 @@ -// $Id: $ +// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- @@ -12,22 +12,20 @@ // //========================================================================== -#if 0 // Framework include files -#include "DDCond/ConditionValidator.h" +#include "DD4hep/objects/DetectorInterna.h" +#include "DD4hep/World.h" -using namespace std; -using namespace DD4hep; +using std::string; using namespace DD4hep::Geometry; - -/// Standard constructor -ConditionValidator::ConditionValidator() { +/// Access the conditions loading +World::Condition World::getCondition(DetElement child,const string& key, const IOV& iov) const { + return access()->getCondition(child,key,iov); } -/// Validate detector subtree and return conditions out of date -bool ConditionValidator::validate(DetElement subtree, std::vector<Condition>& tobe_updated) -{ - return true; +/// Access the detector descrion tree +LCDD& World::lcdd() const { + return *(access()->lcdd); } -#endif + diff --git a/DDCore/src/plugins/Compact2Objects.cpp b/DDCore/src/plugins/Compact2Objects.cpp index 34a0f57e1..5d98d0955 100644 --- a/DDCore/src/plugins/Compact2Objects.cpp +++ b/DDCore/src/plugins/Compact2Objects.cpp @@ -576,7 +576,7 @@ template <> void Converter<Readout>::operator()(xml_h e) const { std::vector<std::string> elements = DD4hep::DDSegmentation::splitString(parameterString); for (std::vector<std::string>::const_iterator j = elements.begin(); j != elements.end(); ++j) { if ((*j).empty()) continue; - valueVector.push_back(DD4hep::Geometry::_toDouble((*j))); + valueVector.push_back(DD4hep::_toDouble((*j))); } typedef DD4hep::DDSegmentation::TypedSegmentationParameter< std::vector<double> > ParDouVec; diff --git a/DDCore/src/plugins/LCDDFields.cpp b/DDCore/src/plugins/LCDDFields.cpp index dcb135780..5de3a0d94 100644 --- a/DDCore/src/plugins/LCDDFields.cpp +++ b/DDCore/src/plugins/LCDDFields.cpp @@ -43,13 +43,13 @@ static Ref_t convert_solenoid(LCDD&, xml_h field, Ref_t object) { field.setAttr(_U(lunit), "mm"); field.setAttr(_U(funit), "tesla"); ::snprintf(text, sizeof(text), "%g/mm", s->outerRadius); - field.setAttr(_U(outer_radius), _toDouble(text)); + field.setAttr(_U(outer_radius), DD4hep::_toDouble(text)); ::snprintf(text, sizeof(text), "%g/mm", s->innerRadius); - field.setAttr(_U(inner_radius), _toDouble(text)); + field.setAttr(_U(inner_radius), DD4hep::_toDouble(text)); ::snprintf(text, sizeof(text), "%g/tesla", s->innerField); - field.setAttr(_U(inner_field), _toDouble(text)); + field.setAttr(_U(inner_field), DD4hep::_toDouble(text)); ::snprintf(text, sizeof(text), "%g/tesla", s->outerField); - field.setAttr(_U(outer_field), _toDouble(text)); + field.setAttr(_U(outer_field), DD4hep::_toDouble(text)); field.setAttr(_U(zmin), s->minZ); field.setAttr(_U(zmax), s->maxZ); return object; @@ -63,15 +63,15 @@ static Ref_t convert_dipole(LCDD&, xml_h field, Ref_t object) { field.setAttr(_U(lunit), "mm"); field.setAttr(_U(funit), "tesla"); ::snprintf(text, sizeof(text), "%g/mm", s->rmax); - field.setAttr(_U(rmax), _toDouble(text)); + field.setAttr(_U(rmax), DD4hep::_toDouble(text)); ::snprintf(text, sizeof(text), "%g/mm", s->zmax); - field.setAttr(_U(zmax), _toDouble(text)); + field.setAttr(_U(zmax), DD4hep::_toDouble(text)); ::snprintf(text, sizeof(text), "%g/mm", s->zmin); - field.setAttr(_U(zmin), _toDouble(text)); + field.setAttr(_U(zmin), DD4hep::_toDouble(text)); DipoleField::Coefficents::const_iterator i = s->coefficents.begin(); for (; i != s->coefficents.end(); ++i) { xml_elt_t coeff = xml_elt_t(doc, _U(dipole_coeff)); - coeff.setValue(_toString(*i)); + coeff.setValue(DD4hep::_toString(*i)); field.append(coeff); } return object; diff --git a/DDCore/src/plugins/PluginInvoker.cpp b/DDCore/src/plugins/PluginInvoker.cpp index 9047300bc..4c461a945 100644 --- a/DDCore/src/plugins/PluginInvoker.cpp +++ b/DDCore/src/plugins/PluginInvoker.cpp @@ -74,7 +74,7 @@ template <> void Converter<plugin>::operator()(xml_h e) const { xml_coll_t(e,"arg").for_each(Converter<arg>(lcdd,&args)); for(vector<string>::const_iterator i=args.begin(); i!=args.end();++i) cargs.push_back((*i).c_str()); - printout(INFO,"Converter<plugin>","+++ Now executing plugin:%s [%d args]",nam.c_str(),int(cargs.size())); + printout(INFO,"ConverterPlugin","+++ Now executing plugin:%s [%d args]",nam.c_str(),int(cargs.size())); lcdd.apply(nam.c_str(),int(cargs.size()),(char**)&cargs[0]); } @@ -84,7 +84,7 @@ template <> void Converter<plugin>::operator()(xml_h e) const { * @version 1.0 * @date 01/04/2014 */ -template <> void Converter<include_file>::operator()(xml_h element) const { +template <> void Converter<include_file>::operator()(xml_h element) const { XML::DocumentHolder doc(XML::DocumentHandler().load(element, element.attr_value(_U(ref)))); xml_h node = doc.root(); string tag = node.tag(); diff --git a/DDDetectors/src/CaloFaceBarrel_surfaces.cpp b/DDDetectors/src/CaloFaceBarrel_surfaces.cpp index 2233db2d9..bf36e82dd 100644 --- a/DDDetectors/src/CaloFaceBarrel_surfaces.cpp +++ b/DDDetectors/src/CaloFaceBarrel_surfaces.cpp @@ -88,9 +88,9 @@ namespace{ char* ptr = ::strchr(argv[i],'='); if ( ptr ) { std::string name( argv[i] , ptr ) ; - double value = DD4hep::Geometry::_toDouble(++ptr); + double value = DD4hep::_toDouble(++ptr); - printout(DD4hep::DEBUG,"DD4hep_CaloFaceBarrelSurfacePlugin", "argument[%d] = %s = %f" , i, name.c_str() , value ) ; + printout(DD4hep::DEBUG,"DD4hep_CaloFaceBarrelSurfacePlugin", "argument[%d] = %s = %f" , i, name.c_str() , value ) ; if( name=="length" ) data.length = value ; else if( name=="radius" ) data.radius = value ; @@ -99,7 +99,7 @@ namespace{ else if( name=="systemID") data.systemID = value ; else if( name=="encoding") data.encoding = ptr ; else { - printout(DD4hep::WARNING,"DD4hep_CaloFaceBarrelSurfacePlugin", "unknown parameter: %s ", name.c_str() ) ; + printout(DD4hep::WARNING,"DD4hep_CaloFaceBarrelSurfacePlugin", "unknown parameter: %s ", name.c_str() ) ; } } } diff --git a/DDDetectors/src/CaloFaceEndcap_surfaces.cpp b/DDDetectors/src/CaloFaceEndcap_surfaces.cpp index 09cb46209..0813f0943 100644 --- a/DDDetectors/src/CaloFaceEndcap_surfaces.cpp +++ b/DDDetectors/src/CaloFaceEndcap_surfaces.cpp @@ -93,7 +93,7 @@ namespace{ char* ptr = ::strchr(argv[i],'='); if ( ptr ) { std::string name( argv[i] , ptr ) ; - double value = DD4hep::Geometry::_toDouble(++ptr); + double value = DD4hep::_toDouble(++ptr); printout(DD4hep::DEBUG,"DD4hep_CaloFaceEndcapSurfacePlugin", "argument[%d] = %s = %f" , i, name.c_str() , value ) ; diff --git a/DDDetectors/src/GenericSurfaceInstaller.cpp b/DDDetectors/src/GenericSurfaceInstaller.cpp index 6a6333d9e..d8e74aaaa 100644 --- a/DDDetectors/src/GenericSurfaceInstaller.cpp +++ b/DDDetectors/src/GenericSurfaceInstaller.cpp @@ -96,7 +96,7 @@ namespace{ char* ptr = ::strchr(argv[i],'='); if ( ptr ) { std::string name( argv[i] , ptr ) ; - value = DD4hep::Geometry::_toDouble(++ptr); + value = DD4hep::_toDouble(++ptr); std::cout << "DD4hep_GenericSurfaceInstallerPlugin: argument[" << i << "] = " << name << " = " << value << std::endl; if( name=="dimension" ) data.dimension = value ; diff --git a/DDDetectors/src/SiTrackerBarrel_surfaces.cpp b/DDDetectors/src/SiTrackerBarrel_surfaces.cpp index f9d566c12..63c64339d 100644 --- a/DDDetectors/src/SiTrackerBarrel_surfaces.cpp +++ b/DDDetectors/src/SiTrackerBarrel_surfaces.cpp @@ -33,7 +33,7 @@ namespace{ char* ptr = ::strchr(argv[i],'='); if ( ptr ) { std::string name( argv[i] , ptr ) ; - double value = DD4hep::Geometry::_toDouble(++ptr); + double value = DD4hep::_toDouble(++ptr); if( name=="dimension" ) data.dimension = value ; std::cout << "DD4hep_SiTrackerBarrelSurfacePlugin: argument[" << i << "] = " << name << " = " << value << std::endl; diff --git a/DDDetectors/src/SurfaceExamplePlugin.cpp b/DDDetectors/src/SurfaceExamplePlugin.cpp index 294357c68..9bdc88c7a 100644 --- a/DDDetectors/src/SurfaceExamplePlugin.cpp +++ b/DDDetectors/src/SurfaceExamplePlugin.cpp @@ -27,7 +27,7 @@ namespace { double value = -1; char* ptr = ::strchr(argv[i],'='); if ( ptr ) { - value = DD4hep::Geometry::_toDouble(++ptr); + value = DD4hep::_toDouble(++ptr); } std::cout << "SurfaceExamplePlugin: argument[" << i << "] = " << argv[i] << " value = " << value << std::endl; diff --git a/DDG4/include/DDG4/Geant4Action.h b/DDG4/include/DDG4/Geant4Action.h index 7080256c8..a21b00df9 100644 --- a/DDG4/include/DDG4/Geant4Action.h +++ b/DDG4/include/DDG4/Geant4Action.h @@ -16,9 +16,9 @@ // //========================================================================== #include "DD4hep/Printout.h" +#include "DD4hep/ComponentProperties.h" #include "DDG4/Geant4Context.h" #include "DDG4/Geant4Callback.h" -#include "DDG4/ComponentProperties.h" // Geant4 forward declarations class G4Run; diff --git a/DDG4/include/DDG4/Geant4Handle.h b/DDG4/include/DDG4/Geant4Handle.h index fba05d189..86bafa087 100644 --- a/DDG4/include/DDG4/Geant4Handle.h +++ b/DDG4/include/DDG4/Geant4Handle.h @@ -16,7 +16,7 @@ #define DD4HEP_DDG4_GEANT4SETUP_H // Framework include files -#include "DDG4/ComponentProperties.h" +#include "DD4hep/ComponentProperties.h" #include "DD4hep/LCDD.h" // C/C++ include files diff --git a/DDG4/include/DDG4/Geant4UIMessenger.h b/DDG4/include/DDG4/Geant4UIMessenger.h index 1a997f456..3f38b5812 100644 --- a/DDG4/include/DDG4/Geant4UIMessenger.h +++ b/DDG4/include/DDG4/Geant4UIMessenger.h @@ -16,8 +16,8 @@ #define DD4HEP_DDG4_GEANT4UIMESSENGER_H // Framework include files -#include "DDG4/ComponentProperties.h" -#include "DDG4/Geant4Callback.h" +#include "DD4hep/ComponentProperties.h" +#include "DD4hep/Callback.h" #include "G4UImessenger.hh" #include "G4UIdirectory.hh" diff --git a/DDG4/plugins/Geant4FieldTrackingSetup.cpp b/DDG4/plugins/Geant4FieldTrackingSetup.cpp index 98ccab460..93f0d5257 100644 --- a/DDG4/plugins/Geant4FieldTrackingSetup.cpp +++ b/DDG4/plugins/Geant4FieldTrackingSetup.cpp @@ -176,7 +176,7 @@ namespace { } double Geant4SetupPropertyMap::toDouble(const string& key) const { - return Geometry::_toDouble(this->value(key)); + return _toDouble(this->value(key)); } } @@ -236,7 +236,7 @@ static long setup_fields(lcdd_t& lcdd, const DD4hep::Geometry::GeoHandler& /* cn lcdd_t::PropertyValues::const_iterator iV = values.find("min_chord_step"); eq_typ = pm.value("equation"); stepper_typ = pm.value("stepper"); - min_chord_step = Geometry::_toDouble((iV==values.end()) ? string("1e-2 * mm") : (*iV).second); + min_chord_step = _toDouble((iV==values.end()) ? string("1e-2 * mm") : (*iV).second); if ( pm["eps_min"] ) eps_min = pm.toDouble("eps_min"); if ( pm["eps_max"] ) eps_max = pm.toDouble("eps_max"); if ( pm["delta_chord"] ) delta_chord = pm.toDouble("delta_chord"); diff --git a/DDG4/python/DD4hep.py b/DDG4/python/DD4hep.py index 16d4a1a78..e9cf76a5a 100644 --- a/DDG4/python/DD4hep.py +++ b/DDG4/python/DD4hep.py @@ -87,6 +87,7 @@ OutputLevel = _Levels() Core = DD4hep Geo = DD4hep.Geometry Geometry = DD4hep.Geometry +Conditions = DD4hep.Conditions import_root('XmlTools') import_namespace_item('XmlTools','Evaluator') @@ -121,9 +122,11 @@ def import_geometry(): #// Readout.h import_namespace_item('Geo','Readout') import_namespace_item('Geo','Alignment') - import_namespace_item('Geo','Conditions') + import_namespace_item('Conditions','Condition') + import_namespace_item('Conditions','Container') #// DetElement.h + import_namespace_item('Geo','World') import_namespace_item('Geo','DetElement') import_namespace_item('Geo','SensitiveDetector') diff --git a/DDG4/python/DDG4.py b/DDG4/python/DDG4.py index 471c0299b..ddd15b288 100644 --- a/DDG4/python/DDG4.py +++ b/DDG4/python/DDG4.py @@ -469,6 +469,7 @@ class Geant4: def printDetectors(self): print '+++ List of sensitive detectors:' for i in self.lcdd.detectors(): + print i.second.ptr().GetName() o = DetElement(i.second.ptr()) sd = self.lcdd.sensitiveDetector(o.name()) if sd.isValid(): diff --git a/UtilityApps/src/run_plugin.h b/UtilityApps/src/run_plugin.h index 994e45db9..03c32a783 100644 --- a/UtilityApps/src/run_plugin.h +++ b/UtilityApps/src/run_plugin.h @@ -76,7 +76,8 @@ namespace { " -build_type <number/string> Specify the build type \n" " [OPTIONAL] MUST come immediately after the -compact input.\n" " Default for each file is: BUILD_DEFAULT [=1] \n" - " Allowed values: BUILD_SIMU [=1], BUILD_RECO [=2], BUILD_DISPLAY [=3] or BUILD_ENVELOPE [=4]\n" + " Allowed: BUILD_SIMU [=1], BUILD_RECO [=2], \n" + " BUILD_DISPLAY [=3] or BUILD_ENVELOPE [=4] \n" " -destroy [OPTIONAL] Force destruction of the LCDD instance \n" " before exiting the application \n" " -volmgr [OPTIONAL] Load and populate phys.volume manager to \n" @@ -84,7 +85,11 @@ namespace { " -print <number/string> Specify output level. Default: INFO(=3) \n" " [OPTIONAL] Allowed values: VERBOSE(=1), DEBUG(=2), \n" " INFO(=3), WARNING(=4), ERROR(=5), FATAL(=6) \n" - " The lower the level, the more printout... \n"; + " The lower the level, the more printout... \n" + " -plugin <name> <args> Execute plugin <name> after loading geometry. \n" + " All arguments following until the next '-' \n" + " are considered as arguments to the plugin. \n" + " "; return cout; } @@ -100,14 +105,15 @@ namespace { } struct Args { - bool volmgr, dry_run, destroy; + bool volmgr, dry_run, destroy, interpreter; int print; std::vector<const char*> geo_files, build_types; - + std::vector<std::vector<const char*> > plugins; Args() { volmgr = false; dry_run = false; destroy = false; + interpreter = true; print = DD4hep::INFO; } int handle(int& i, int argc, char** argv) { @@ -127,12 +133,56 @@ namespace { DD4hep::setPrintLevel(DD4hep::PrintLevel(print = decodePrintLevel(argv[++i]))); else if ( strncmp(argv[i],"-destroy",5)==0 ) destroy = true; + else if ( strncmp(argv[i],"-no-destroy",8)==0 ) + destroy = false; else if ( strncmp(argv[i],"-volmgr",4)==0 ) volmgr = true; + else if ( strncmp(argv[i],"-no-volmgr",7)==0 ) + volmgr = false; + else if ( strncmp(argv[i],"-interpreter",6)==0 ) + interpreter = true; + else if ( strncmp(argv[i],"-no-interpreter",7)==0 ) + interpreter = false; + else if ( strncmp(argv[i],"-plugin",5)==0 ) { + // Need to interprete plugin args here locally..... + plugins.push_back(std::vector<const char*>()); + plugins.back().push_back(argv[++i]); + for(; i<argc; ++i) { + if ( argv[i][0]=='-' ) { --i; break; } + plugins.back().push_back(argv[i]); + } + } else return 0; return 1; } + + long run(LCDD& lcdd, const char* name) { + pair<int, char**> a(0,0); + long result; + for(size_t i=0; i<plugins.size(); ++i) { + std::vector<const char*>& plug=plugins[i]; + result = run_plugin(lcdd,plug[0],plug.size()-1,(char**)(plug.size()>1 ? &plug[1] : 0)); + if ( result == EINVAL ) { + cout << "FAILED to execute DD4hep plugin: '" << plug[0] + << "' with args (" << (plug.size()-1) << ") :[ "; + for(size_t j=1; j<plug.size(); ++j) { + cout << plug[j] << " "; + } + cout << "]" << endl; + usage_default(name); + } + cout << "Executed DD4hep plugin: '" << plug[0] + << "' with args (" << (plug.size()-1) << ") :[ "; + for(size_t j=1; j<plug.size(); ++j) { + cout << plug[j] << " "; + } + cout << "]" << endl; + } + result = run_plugin(lcdd,name,a.first,a.second); + return result; + } + int decodePrintLevel(const std::string& val) { switch(::toupper(val[0])) { case '1': @@ -196,11 +246,16 @@ namespace { // Create an interactive ROOT application if ( !args.dry_run ) { + long result = 0; pair<int, char**> a(0,0); - TRint app(name, &a.first, a.second); - long result = run_plugin(lcdd,name,a.first,a.second); + if ( args.interpreter ) { + TRint app(name, &a.first, a.second); + result = args.run(lcdd,name); + if ( result != EINVAL ) app.Run(); + } + else + result = args.run(lcdd,name); if ( result == EINVAL ) usage_default(name); - app.Run(); } else { cout << "The geometry was loaded. Application now exiting." << endl; diff --git a/doc/CompileAllOptionPermutations.sh b/doc/CompileAllOptionPermutations.sh index 8c7d604bb..11f2ab2c1 100755 --- a/doc/CompileAllOptionPermutations.sh +++ b/doc/CompileAllOptionPermutations.sh @@ -7,7 +7,8 @@ INSTALL_XERCESC=${SW}/xercesc; INSTALL_G4=${SW}/g4_10.01.p02_dbg/lib/Geant4-10.1.2; CHECKOUT=${dir_name}/../../DD4hep.trunk/checkout; GEANT_VERSION=10.01.p02; -ROOT_VERSION=6.04.00; +ROOT_VERSION=5.34.25 +##ROOT_VERSION=6.04.00; # ============================================================================== # Parse arguments # ============================================================================== @@ -131,7 +132,7 @@ build_all() OPTS="`make_opt ${DOGEANT4} -DDD4HEP_USE_GEANT4 -DGeant4_DIR=${INSTALL_G4}`\ `make_opt ${DOLCIO} -DDD4HEP_USE_LCIO -DLCIO_DIR=${INSTALL_LCIO}` \ `make_opt ${DOXERCESC} -DDD4HEP_USE_XERCESC -DXERCESC_ROOT_DIR=${INSTALL_XERCESC}` \ - -DDD4HEP_NO_REFLEX=ON -DDD4HEP_USE_CXX11=ON \ + -DDD4HEP_NO_REFLEX=ON -DDD4HEP_USE_CXX11=OFF \ -DROOTSYS=${ROOTSYS} -DCMAKE_INSTALL_PREFIX=${WORK_DIR}/DD4hep"; CMD="cd ${dir_name}/$folder ; cmake ${OPTS} ${CHECKOUT};"; make_build; @@ -142,7 +143,7 @@ build_all() OPTS_ex="`make_opt ${DOGEANT4} -DDD4HEP_USE_GEANT4 -DGeant4_DIR=${INSTALL_G4}`\ `make_opt ${DOLCIO} -DDD4HEP_USE_LCIO -DLCIO_DIR=${INSTALL_LCIO}` \ `make_opt ${DOXERCESC} -DDD4HEP_USE_XERCESC -DXERCESC_ROOT_DIR=${INSTALL_XERCESC}` \ - -DDD4HEP_NO_REFLEX=ON -DDD4HEP_USE_CXX11=ON \ + -DDD4HEP_NO_REFLEX=ON -DDD4HEP_USE_CXX11=OFF \ -DROOTSYS=${ROOTSYS}"; source ${DD4hep_DIR}/bin/thisdd4hep.sh; CMD="cd ${WORK_DIR}/EX; cmake ${OPTS} -DDD4hep_DIR=${DD4hep_DIR} ${CHECKOUT}/examples;"; diff --git a/doc/release.notes b/doc/release.notes index c6f1b789a..980b30294 100644 --- a/doc/release.notes +++ b/doc/release.notes @@ -3,6 +3,12 @@ DD4hep ---- Release Notes ================================= +2016-02-10 M.Frank + DDCond + First implementation of conditions access. Required some movements of files + from DDG4 (Properties) and some changes in the core conditions implementation. + The basic infrastructure is now present. Don't know yet however how buggy it is... + 2016-02-03 N.Nikiforou DDDetectors - Added plugin DD4hep_GenericSurfaceInstallerPlugin, copied from lcgeo -- GitLab