From 2157cb80f7902d2e09c53ed794b03ef762bf7990 Mon Sep 17 00:00:00 2001 From: Markus Frank <markus.frank@cern.ch> Date: Wed, 29 Jun 2016 16:00:10 +0000 Subject: [PATCH] Add conditions loading --- DDDB/CMakeLists.txt | 2 +- DDDB/include/DDDB/DDDBConditionData.h | 59 ++ DDDB/include/DDDB/DDDBConditionsLoader.h | 67 ++ DDDB/include/DDDB/DDDBConversion.h | 83 +- .../DDDB/{Dimension.h => DDDBDimension.h} | 0 DDDB/include/DDDB/DDDBFileReader.h | 4 +- DDDB/include/DDDB/DDDBHelper.h | 14 +- DDDB/include/DDDB/DDDBReaderContext.h | 56 ++ DDDB/include/DDDB/DDDBTags.h | 123 +-- DDDB/src/CondDB2DDDB.cpp | 713 +++++++++++++----- DDDB/src/DDDB2Objects.cpp | 310 +++++--- DDDB/src/DDDBConditionData.cpp | 78 ++ DDDB/src/DDDBConditionsLoader.cpp | 152 ++++ DDDB/src/DDDBConditionsUpdate.cpp | 38 + DDDB/src/DDDBConversion.cpp | 103 ++- DDDB/src/{Dimension.cpp => DDDBDimension.cpp} | 2 +- DDDB/src/DDDBFileReader.cpp | 58 +- DDDB/src/DDDBHelper.cpp | 12 +- DDDB/src/DDDBvis.cpp | 2 +- 19 files changed, 1413 insertions(+), 463 deletions(-) create mode 100644 DDDB/include/DDDB/DDDBConditionData.h create mode 100644 DDDB/include/DDDB/DDDBConditionsLoader.h rename DDDB/include/DDDB/{Dimension.h => DDDBDimension.h} (100%) create mode 100644 DDDB/include/DDDB/DDDBReaderContext.h create mode 100644 DDDB/src/DDDBConditionData.cpp create mode 100644 DDDB/src/DDDBConditionsLoader.cpp create mode 100644 DDDB/src/DDDBConditionsUpdate.cpp rename DDDB/src/{Dimension.cpp => DDDBDimension.cpp} (99%) diff --git a/DDDB/CMakeLists.txt b/DDDB/CMakeLists.txt index 5f35059c0..ea2b727bf 100644 --- a/DDDB/CMakeLists.txt +++ b/DDDB/CMakeLists.txt @@ -10,7 +10,7 @@ # #========================================================================== dd4hep_package( DDDB - USES DDCore + USES DDCore DDCond [BOOST REQUIRED COMPONENTS filesystem] INCLUDE_DIRS include INSTALL_INCLUDES include/DDDB) diff --git a/DDDB/include/DDDB/DDDBConditionData.h b/DDDB/include/DDDB/DDDBConditionData.h new file mode 100644 index 000000000..cff1b4fb9 --- /dev/null +++ b/DDDB/include/DDDB/DDDBConditionData.h @@ -0,0 +1,59 @@ +// $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 +// +//========================================================================== +// +// DDDB is a detector description convention developed by the LHCb experiment. +// For further information concerning the DTD, please see: +// http://lhcb-comp.web.cern.ch/lhcb-comp/Frameworks/DetDesc/Documents/lhcbDtd.pdf +// +//========================================================================== +#ifndef DD4HEP_DDDB_DDDBCONDITIONDATA_H +#define DD4HEP_DDDB_DDDBCONDITIONDATA_H + +// Framework includes +#include "DD4hep/objects/ConditionsInterna.h" + +// C/C++ include files +#include <map> + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace of the DDDB conversion stuff + namespace DDDB { + + // Forward declarations + class Document; + + /// CondDB reader context to support intervals of validity + /** + * \author M.Frank + * \version 1.0 + * \date 31/03/2016 + * \ingroup DD4HEP_DDDB + */ + class DDDBConditionData { + public: + typedef Conditions::BlockData Data; + typedef std::map<std::string, Data> Params; + Document* document; + Params params; + int classID; + /// Default constructor + DDDBConditionData(); + /// Default destructor + virtual ~DDDBConditionData(); + }; + } /* End namespace DDDB */ +} /* End namespace DD4hep */ +#endif /* DD4HEP_DDDB_CONDITIONDATA_H */ diff --git a/DDDB/include/DDDB/DDDBConditionsLoader.h b/DDDB/include/DDDB/DDDBConditionsLoader.h new file mode 100644 index 000000000..943227cf6 --- /dev/null +++ b/DDDB/include/DDDB/DDDBConditionsLoader.h @@ -0,0 +1,67 @@ +// 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_DDDB_DDDBCONDITONSLOADER_H +#define DD4HEP_DDDB_DDDBCONDITONSLOADER_H + +// Framework include files +#include "DDCond/ConditionsListener.h" +#include "DDCond/ConditionsDataLoader.h" +#include "XML/UriReader.h" + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace DDDB { + + /// Implementation of a stack of conditions assembled before application + /** + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class DDDBConditionsLoader + : public Conditions::ConditionsDataLoader, public Conditions::ConditionsListener + { + XML::UriReader* m_resolver; + + public: + /// Default constructor + DDDBConditionsLoader(Geometry::LCDD& lcdd, Conditions::ConditionsManager mgr, const std::string& nam); + /// Default destructor + virtual ~DDDBConditionsLoader(); + /// Load a condition set given a Detector Element and the conditions name according to their validity + virtual size_t load(Geometry::DetElement det, + const std::string& cond, + const Conditions::IOV& req_validity, + Conditions::RangeConditions& conditions); + /// Load a condition set given a Detector Element and the conditions name according to their validity + virtual size_t load_range(Geometry::DetElement det, + const std::string& cond, + const Conditions::IOV& req_validity, + Conditions::RangeConditions& conditions); + /// Update a range of conditions according to the required IOV + virtual size_t update(const Conditions::IOV& req_validity, + Conditions::RangeConditions& conditions, + Conditions::IOV& iov_intersection); + + /// ConditionsListener overload: onRegister new condition + virtual void onRegisterCondition(Conditions::Condition cond, void* param); + + }; + } /* End namespace DDDB */ +} /* End namespace DD4hep */ + +#endif /* DD4HEP_DDDB_DDDBCONDITONSLOADER_H */ diff --git a/DDDB/include/DDDB/DDDBConversion.h b/DDDB/include/DDDB/DDDBConversion.h index f50387256..b99b2bf11 100644 --- a/DDDB/include/DDDB/DDDBConversion.h +++ b/DDDB/include/DDDB/DDDBConversion.h @@ -22,6 +22,8 @@ /// Framework include files #include "DD4hep/Objects.h" +#include "DD4hep/objects/ConditionsInterna.h" +#include "DDDB/DDDBReaderContext.h" /// C/C++ include files #include <string> @@ -38,19 +40,7 @@ namespace DD4hep { struct Shape; struct LogVol; struct Catalog; - - struct LogVolRef {}; - struct ElementRef {}; - struct MaterialRef {}; - struct CatalogRef {}; - struct ConditionRef {}; - struct ConditionInfo {}; - struct DetElem {}; - struct DetElemRef {}; - struct Param {}; - struct Parameter {}; - struct ParamVector {}; - struct GeometryInfo {}; + struct Document; using Geometry::VisAttr; using Geometry::Position; @@ -64,46 +54,39 @@ namespace DD4hep { struct Named { typedef std::map<std::string, std::string> StringMap; typedef std::map<std::string, std::pair<std::string,std::string > > StringPairMap; - std::string name, id; - int refCount; - Named() : refCount(0) {} - Named(const std::string& c) : name(c), id(), refCount(0) {} - Named(const Named& c) : name(c.name), id(c.id), refCount(0) {} - Named& operator=(const Named& c) { - if ( this != &c ) { - name=c.name; - id=c.id; - } - return *this; - } - virtual ~Named() {} + std::string name, id; + Document* document; + int refCount; + + /// Default constructor + Named(); + /// Initializing constructor + Named(const std::string& c); + /// Copy constructor + Named(const Named& c); + /// Default destructor + virtual ~Named(); + /// Assignment operator + Named& operator=(const Named& c); + /// Assign document + void setDocument(Document* doc); + const char* c_name() const { return name.c_str(); } const char* c_id() const { return id.c_str(); } void release() { if ( --refCount <= 0 ) delete this; } }; - struct ConditionParam { - std::string type, data; - ConditionParam() : type(), data() {} - ConditionParam(const ConditionParam& c) : type(c.type), data(c.data) {} - ConditionParam& operator=(const ConditionParam& c) { - if ( &c != this ) { - type = c.type; - data = c.data; - } - return *this; - } - }; - struct Condition : public Named { - typedef std::map<std::string, ConditionParam*> Params; - std::string classID, path; - Params params; - Params paramVectors; + /// Structure supporting basic XML document information + /** \ingroup DD4HEP_DDDB + */ + struct Document : public Named { + DDDBReaderContext context; /// Default constructor - Condition(); + Document(); /// Default destructor - virtual ~Condition(); - Condition* addRef() { ++refCount; return this; } + virtual ~Document(); + /// Reference count mechanism + Document* addRef() { ++refCount; return this; } }; /// Intermediate structure representing author's data @@ -523,7 +506,9 @@ namespace DD4hep { * \ingroup DD4HEP_DDDB */ struct dddb { + typedef std::pair<long long int, long long int> iov_t; typedef std::map<std::string,std::string> Refs; + typedef std::map<std::string,Document*> Documents; typedef std::map<std::string,LogVol*> Volumes; typedef std::map<std::string,PhysVol*> Placements; typedef std::map<std::string,Catalog*> Catalogs; @@ -531,7 +516,7 @@ namespace DD4hep { typedef std::map<std::string,Element*> Elements; typedef std::map<std::string,Material*> Materials; typedef std::map<std::string,Shape*> Shapes; - typedef std::map<std::string,Condition*> Conditions; + typedef std::map<std::string,Conditions::Condition::Object*> Conditions; /// Default constructor dddb(); @@ -540,6 +525,8 @@ namespace DD4hep { /// World dimensions Box world; + /// Inventory of input documents + Documents documents; /// Inventory of isotopes Isotopes isotopes; /// Inventory of elements @@ -559,12 +546,14 @@ namespace DD4hep { /// Detector element hierarchy Catalog *top, *structure, *geometry; }; + struct dddb_conditions {}; template <typename T> struct Increment { static int& counter() { static int cnt=0; return cnt; } Increment() { ++counter(); } ~Increment() { --counter(); } }; + } /* End namespace DDDB */ /// Specialized printout method. Not all above object types are supported. diff --git a/DDDB/include/DDDB/Dimension.h b/DDDB/include/DDDB/DDDBDimension.h similarity index 100% rename from DDDB/include/DDDB/Dimension.h rename to DDDB/include/DDDB/DDDBDimension.h diff --git a/DDDB/include/DDDB/DDDBFileReader.h b/DDDB/include/DDDB/DDDBFileReader.h index 7622b4f32..bd3be452b 100644 --- a/DDDB/include/DDDB/DDDBFileReader.h +++ b/DDDB/include/DDDB/DDDBFileReader.h @@ -51,7 +51,9 @@ namespace DD4hep { /// Access data match const std::string& match() const { return m_match; } /// Resolve a given URI to a string containing the data - virtual bool load(const std::string& system_id, std::string& buffer); + virtual bool load(const std::string& system_id, UserContext* ctxt, std::string& buffer); + /// Read raw XML object from the database / file + virtual int getObject(const std::string& system_id, UserContext* ctxt, std::string& data); protected: std::string m_directory; diff --git a/DDDB/include/DDDB/DDDBHelper.h b/DDDB/include/DDDB/DDDBHelper.h index 0771a5372..c98218be9 100644 --- a/DDDB/include/DDDB/DDDBHelper.h +++ b/DDDB/include/DDDB/DDDBHelper.h @@ -39,6 +39,7 @@ namespace DD4hep { /// Namespace of the DDDB conversion stuff namespace DDDB { + /// Forward declarations class dddb; /// Class supporting the interface of the LHCb conditions database to DD4hep @@ -51,6 +52,7 @@ namespace DD4hep { class DDDBHelper { public: typedef std::vector<std::pair<std::string, Geometry::VisAttr> > VisAttrs; + public: /// Standard constructor DDDBHelper(Geometry::LCDD& lcdd); @@ -60,11 +62,11 @@ namespace DD4hep { /// Access XML reader object XML::UriReader* xmlReader() const { return m_xmlReader; } /// Set XML reader object - void setXmlReader(XML::UriReader* rdr) { m_xmlReader = rdr; } + void setXmlReader(XML::UriReader* rdr) { m_xmlReader = rdr; } /// Access local database representation - dddb* geometry() const { return m_geometry; } + dddb* detectorDescription() const { return m_detDesc; } /// Set XML reader object - void setGeometry(dddb* geo); + void setDetectorDescription(dddb* geo); /// Access visualization attribute for a given volume by path Geometry::VisAttr visAttr(const std::string& path) const; /// Add visualization attribute @@ -73,9 +75,13 @@ namespace DD4hep { void addVisAttr(const std::string& path, Geometry::VisAttr attr); public: + /// Reference to main detector description instance Geometry::LCDD& m_lcdd; + /// Reference to XML entity resolver XML::UriReader* m_xmlReader; - dddb* m_geometry; + /// Reference to extracted detector description information + dddb* m_detDesc; + /// Optional container of visualization attributes VisAttrs m_visAttrs; }; diff --git a/DDDB/include/DDDB/DDDBReaderContext.h b/DDDB/include/DDDB/DDDBReaderContext.h new file mode 100644 index 000000000..859b43406 --- /dev/null +++ b/DDDB/include/DDDB/DDDBReaderContext.h @@ -0,0 +1,56 @@ +// $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 +// +//========================================================================== +// +// DDDB is a detector description convention developed by the LHCb experiment. +// For further information concerning the DTD, please see: +// http://lhcb-comp.web.cern.ch/lhcb-comp/Frameworks/DetDesc/Documents/lhcbDtd.pdf +// +//========================================================================== +#ifndef DD4HEP_DDDB_DDDBREADERCONTEXT_H +#define DD4HEP_DDDB_DDDBREADERCONTEXT_H + +// Framework includes +#include "XML/UriReader.h" + + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace of the DDDB conversion stuff + namespace DDDB { + + /// CondDB reader context to support intervals of validity + /** + * \author M.Frank + * \version 1.0 + * \date 31/03/2016 + * \ingroup DD4HEP_DDDB + */ + class DDDBReaderContext : public XML::UriReader::UserContext { + public: + long long int event_time, valid_since, valid_until; + std::string doc, channel; + /// Standard constructor + DDDBReaderContext() : event_time(0), valid_since(0), valid_until(0) {} + /// Copy constructor + DDDBReaderContext(const DDDBReaderContext& c) + : XML::UriReader::UserContext(c), + event_time(c.event_time), + valid_since(c.valid_since), + valid_until(c.valid_until), + channel(c.channel) {} + }; + } /* End namespace DDDB */ +} /* End namespace DD4hep */ +#endif /* DD4HEP_DDDB_DDDBREADERCONTEXT_H */ diff --git a/DDDB/include/DDDB/DDDBTags.h b/DDDB/include/DDDB/DDDBTags.h index 39630da83..7445ab9ac 100644 --- a/DDDB/include/DDDB/DDDBTags.h +++ b/DDDB/include/DDDB/DDDBTags.h @@ -33,56 +33,87 @@ namespace DD4hep { namespace DDDB { UNICODE(DDDB); UNICODE(DDDB_VIS); - UNICODE(elementref); - UNICODE(materialref); + + UNICODE(address); + UNICODE(alp1); + UNICODE(alp2); + UNICODE(catalog); UNICODE(catalogref); - UNICODE(href); - UNICODE(npath); - UNICODE(detelem); - UNICODE(detelemref); + UNICODE(classID); UNICODE(condition); UNICODE(conditionref); UNICODE(conditioninfo); + UNICODE(component); + UNICODE(cons); + + UNICODE(deltaPhiAngle); + UNICODE(deltaThetaAngle); + UNICODE(detelem); + UNICODE(detelemref); + + UNICODE(elementref); + + UNICODE(fractionmass); + UNICODE(geometryinfo); + + UNICODE(href); + + UNICODE(lambda); + + UNICODE(innerRadius); + UNICODE(innerRadiusMZ); + UNICODE(innerRadiusPZ); + UNICODE(ionization); + UNICODE(isotoperef); + UNICODE(item); + + UNICODE(key); + UNICODE(keytype); + UNICODE(lvname); UNICODE(logvolref); - UNICODE(paramVector); - UNICODE(userParameter); - UNICODE(fractionmass); + + UNICODE(map); + UNICODE(materialref); + UNICODE(natoms); - UNICODE(radlen); - UNICODE(ionization); - UNICODE(lambda); - UNICODE(component); - UNICODE(address); - UNICODE(isotoperef); - UNICODE(symbol); - UNICODE(state); - UNICODE(support); - UNICODE(volumes); - UNICODE(vismapping); + UNICODE(npath); + UNICODE(number); + UNICODE(number1); + UNICODE(number2); + UNICODE(number3); + + UNICODE(paramVector); UNICODE(posXYZ); + + UNICODE(radlen); UNICODE(rotXYZ); UNICODE(rotX); UNICODE(rotY); UNICODE(rotZ); - UNICODE(cons); + + UNICODE(symbol); + UNICODE(state); + UNICODE(support); + + UNICODE(tubs); UNICODE(transformation); UNICODE(version); UNICODE(author); - UNICODE(number); - UNICODE(number1); - UNICODE(number2); - UNICODE(number3); - UNICODE(alp1); - UNICODE(alp2); - UNICODE(x); - UNICODE(y); - UNICODE(z); + + UNICODE(outerRadius); + UNICODE(outerRadiusMZ); + UNICODE(outerRadiusPZ); + + UNICODE(paramphysvol); + UNICODE(paramphysvol2D); + UNICODE(phiAngle); + UNICODE(sizeX); UNICODE(sizeX1); UNICODE(sizeX2); @@ -92,24 +123,26 @@ namespace DD4hep { UNICODE(sizeY1); UNICODE(sizeY2); UNICODE(sizeZ); - UNICODE(outerRadius); - UNICODE(outerRadiusMZ); - UNICODE(outerRadiusPZ); - UNICODE(innerRadius); - UNICODE(innerRadiusMZ); - UNICODE(innerRadiusPZ); - UNICODE(tabprops); - UNICODE(paramphysvol); - UNICODE(paramphysvol2D); - UNICODE(phiAngle); + UNICODE(specific); UNICODE(startPhiAngle); - UNICODE(deltaPhiAngle); - UNICODE(thetaAngle); UNICODE(startThetaAngle); - UNICODE(deltaThetaAngle); - UNICODE(classID); - //UNICODE(); + UNICODE(tabprops); + UNICODE(thetaAngle); + + UNICODE(userParameter); + + UNICODE(val); + UNICODE(value); + UNICODE(valuetype); + UNICODE(volumes); + UNICODE(vismapping); + + UNICODE(x); + UNICODE(y); + UNICODE(z); + + //UNICODE(); } /* End namespace DDDB */ } /* End namespace DD4hep */ diff --git a/DDDB/src/CondDB2DDDB.cpp b/DDDB/src/CondDB2DDDB.cpp index 0457d55ab..a2faa266e 100644 --- a/DDDB/src/CondDB2DDDB.cpp +++ b/DDDB/src/CondDB2DDDB.cpp @@ -20,9 +20,10 @@ // Framework includes #include "DDDB/DDDBTags.h" -#include "DDDB/Dimension.h" +#include "DDDB/DDDBDimension.h" #include "DDDB/DDDBHelper.h" #include "DDDB/DDDBConversion.h" +#include "DDDB/DDDBConditionData.h" // C/C++ include files #include "boost/filesystem/path.hpp" @@ -37,14 +38,34 @@ namespace DD4hep { /// Keep all in here anonymous. Does not have to be visible outside. namespace { + typedef Conditions::BlockData BlockData; + typedef Conditions::Condition Condition; + typedef DDDB::DDDBConditionData::Params ConditionParams; + struct LogVolRef {}; + struct ElementRef {}; + struct MaterialRef {}; + struct CatalogRef {}; + struct ConditionRef {}; + struct DetElemRef {}; + + struct ConditionInfo {}; + struct DetElem {}; + struct Param {}; + struct Parameter {}; + struct GeometryInfo {}; + struct ConditionParam {}; + struct ConditionParamMap {}; + struct ConditionParamVector {}; + struct ConditionParamSpecific {}; + /// Main processing context /** \ingroup DD4HEP_DDDB */ - struct Context { + class Context { private: template <typename T,typename Q> - void collect_id(Q& container, const string& id, T* object) { + void collect_id(Q& container, const string& id, T* object) const { typename Q::const_iterator i=container.find(id); if ( i != container.end() ) { if ( object == (*i).second ) return; @@ -56,7 +77,7 @@ namespace DD4hep { print(object); } template <typename T,typename Q> - void collect_p(Q& container, const string& path, T* object) { + void collect_p(Q& container, const string& path, T* object) const { typename Q::const_iterator i=container.find(path); if ( i != container.end() ) { if ( object == (*i).second ) return; @@ -67,71 +88,76 @@ namespace DD4hep { } public: - typedef set<string> StringSet; /// Local processing environment /** \ingroup DD4HEP_DDDB */ - struct Locals { - string doc_path, obj_path, xml_path; - Locals() {} - Locals(const Locals& c) : doc_path(c.doc_path), obj_path(c.obj_path), xml_path(c.xml_path) {} + class Locals { + public: + string doc_path, obj_path; + Document* xml_doc; + Locals() : doc_path(), obj_path(), xml_doc(0) {} + Locals(const Locals& c) : doc_path(c.doc_path), obj_path(c.obj_path), xml_doc(c.xml_doc) {} Locals& operator=(const Locals& c) { doc_path = c.doc_path; obj_path = c.obj_path; - xml_path = c.xml_path; + xml_doc = c.xml_doc; return *this; } }; /// Helper class to preserve local processing environment /** \ingroup DD4HEP_DDDB */ - struct PreservedLocals : public Locals { + class PreservedLocals : public Locals { + public: Context* context; PreservedLocals(Context* c) : Locals(c->locals), context(c) {} - ~PreservedLocals() { context->locals = *this; } + ~PreservedLocals() { context->locals = *this; } }; + public: lcdd_t& lcdd; - DDDBHelper* hlp; + XML::UriReader* resolver; dddb* geo; - StringSet files; Locals locals; - bool print_xml; - bool print_docs; - bool print_materials; - bool print_logvol; - bool print_shapes; - bool print_physvol; - bool print_params; - bool print_detelem; - bool print_detelem_ref; - bool print_detelem_xml; - bool print_condition; - bool print_condition_ref; - bool print_catalog; - bool print_catalog_ref; + bool print_xml; + bool print_docs; + bool print_materials; + bool print_logvol; + bool print_shapes; + bool print_physvol; + bool print_params; + bool print_detelem; + bool print_detelem_ref; + bool print_detelem_xml; + bool print_condition; + bool print_condition_ref; + bool print_catalog; + bool print_catalog_ref; /// Default constructor - Context(lcdd_t& l) : lcdd(l), hlp(0), geo(0), - print_xml(false), - print_docs(false), - print_materials(false), - print_logvol(false), - print_shapes(false), - print_physvol(false), - print_params(false), - print_detelem(false), - print_detelem_ref(false), - print_detelem_xml(false), - print_condition(false), - print_condition_ref(false), - print_catalog(false), - print_catalog_ref(false) + Context(lcdd_t& l) + : lcdd(l), resolver(0), geo(0), + print_xml(false), + print_docs(false), + print_materials(false), + print_logvol(false), + print_shapes(false), + print_physvol(false), + print_params(false), + print_detelem(false), + print_detelem_ref(false), + print_detelem_xml(false), + print_condition(false), + print_condition_ref(false), + print_catalog(false), + print_catalog_ref(false) { } /// Default destructor - ~Context() { } - /// Printout helpers + ~Context() { + } + + /** Printout helpers */ void print(const Isotope* obj) const { if ( print_materials ) dddb_print(obj); } void print(const Element* obj) const { if ( print_materials ) dddb_print(obj); } void print(const Material* obj) const { if ( print_materials ) dddb_print(obj); } @@ -139,8 +165,9 @@ namespace DD4hep { void print(const PhysVol* obj) const { if ( print_physvol ) dddb_print(obj); } void print(const LogVol* obj) const { if ( print_logvol ) dddb_print(obj); } void print(const Catalog* obj) const { if ( print_catalog ) dddb_print(obj); } - void print(const Condition* obj) const { if ( print_condition ) dddb_print(obj); } - /// Data collection helpers for indexing by object identifier + void print(const Document* obj) const { if ( print_docs ) dddb_print(obj); } + + /** Data collection helpers for indexing by object identifier */ void collect(const string& id, Catalog* obj) { collect_id(geo->catalogs, id, obj); } void collect(const string& id, Shape* obj) { collect_id(geo->shapes, id, obj); } void collect(const string& id, PhysVol* obj) { collect_id(geo->placements, id, obj); } @@ -148,23 +175,31 @@ namespace DD4hep { void collect(const string& id, Isotope* obj) { collect_id(geo->isotopes, id, obj); } void collect(const string& id, Element* obj) { collect_id(geo->elements, id, obj); } void collect(const string& id, Material* obj) { collect_id(geo->materials, id, obj); } - void collect(const string& id, Condition* obj) { collect_id(geo->conditions, id, obj); } - /// Data collection helpers for indexing by path + void collect(const string& id, Condition& object) { + dddb::Conditions::const_iterator i=geo->conditions.find(id); + if ( i != geo->conditions.end() ) { + if ( object.ptr() == (*i).second ) return; + printout(ERROR,"collect","++ Duplicate ID: %s %p <-> %p", + id.c_str(), object.ptr(), (*i).second); + } + geo->conditions[id] = object.ptr(); + } + + /** Data collection helpers for indexing by path */ void collectPath(const string& path, Element* obj) { collect_p(geo->elementPaths, path, obj); } void collectPath(const string& path, Material* obj) { collect_p(geo->materialPaths, path, obj); } void collectPath(const string& path, PhysVol* obj) { collect_p(geo->placementPaths, path, obj); } void collectPath(const string& path, LogVol* obj) { collect_p(geo->volumePaths, path, obj); } void collectPath(const string& path, Catalog* obj) { collect_p(geo->catalogPaths, path, obj); } - void collectPath(const string& path, Condition* obj) { collect_p(geo->conditionPaths, path, obj); } - }; - - /// Helper class to count call depths - /** \ingroup DD4HEP_DDDB - */ - template <typename T> struct Increment { - static int& counter() { static int cnt=0; return cnt; } - Increment() { ++counter(); } - ~Increment() { --counter(); } + void collectPath(const string& path, Condition& object) { + dddb::Conditions::const_iterator i=geo->conditionPaths.find(path); + if ( i != geo->conditionPaths.end() ) { + if ( object.ptr() == (*i).second ) return; + printout(ERROR,"collectPath","++ Duplicate ID: %s %p <-> %p", + path.c_str(), object.ptr(), (*i).second); + } + geo->conditionPaths[path] = object.ptr(); + } }; /// Converter to incept processing exceptions @@ -292,6 +327,7 @@ namespace DD4hep { id1.c_str(), id2.c_str(), path.c_str(), obj.c_str(), opt.c_str()); } + template <typename ACTION=dddb> void load_dddb_entity(Context* context, Catalog* catalog, xml_h element, @@ -299,7 +335,7 @@ namespace DD4hep { bool print=false); /// Helper to locate objects in a map using string identifiers - template <typename Q> bool find(const string& id, const Q& container) { + template <typename Q> bool _find(const string& id, const Q& container) { return container.find(id) != container.end(); } @@ -377,71 +413,290 @@ namespace DD4hep { } } - /// Specialized conversion of <author/> entities - template <> void Conv<Author>::convert(xml_h element) const { - string* context = _option<string>(); - if ( element.hasAttr(_U(author)) ) *context = element.attr<string>(_U(author)); + template<typename KEY, typename VAL> + static void insert_map_item(const KEY& k, const string& val, BlockData& block) { + typedef std::map<KEY,VAL> map_t; + map_t& m = block.get<map_t>(); + VAL v; + if ( !BasicGrammar::instance<VAL>().fromString(&v, val) ) { + except("Condition::map","++ Failed to convert conditions map entry."); + } + m.insert(make_pair(k,v)); } - /// Specialized conversion of <version/> entities - template <> void Conv<Version>::convert(xml_h element) const { - string* context = _option<string>(); - if ( element.hasAttr(_U(version)) ) *context = element.attr<string>(_U(version)); + template<typename KEY> + static void insert_map_key(const string& key_val, const string& val_type, + const string& val, BlockData& block) + { + KEY key; + BasicGrammar::instance<KEY>().fromString(&key, key_val); + if ( val_type.substr(0,5) == "short" ) + insert_map_item<KEY,short>(key,val,block); + else if ( val_type.substr(0,3) == "int" ) + insert_map_item<KEY,int>(key,val,block); + else if ( val_type.substr(0,4) == "long" ) + insert_map_item<KEY,long>(key,val,block); + else if ( val_type.substr(0,5) == "float" ) + insert_map_item<KEY,float>(key,val,block); + else if ( val_type.substr(0,6) == "double" ) + insert_map_item<KEY,double>(key,val,block); + else if ( val_type.substr(0,6) == "string" ) + insert_map_item<KEY,string>(key,val,block); + else if ( val_type == "std::string" ) + insert_map_item<KEY,string>(key,val,block); + else { + printout(INFO,"Param","++ Unknown conditions parameter type:%s data:%s", + val_type.c_str(),val.c_str()); + insert_map_item<KEY,string>(key,val,block); + } } - /// Specialized conversion of <param/> entities - template <> void Conv<Param>::convert(xml_h element) const { - Catalog* det = _option<Catalog>(); - string name = element.attr<string>(_U(name)); - string type = element.hasAttr(_U(type)) ? element.attr<string>(_U(type)) : string("int"); - string value = element.text(); - det->params[name] = make_pair(type,value); + template<typename KEY> + static void bind_map(const string& val_type, BlockData& block) { + if ( val_type.substr(0,5) == "short" ) + block.bind< map<KEY,short> >(); + else if ( val_type.substr(0,3) == "int" ) + block.bind< map<KEY,int> >(); + else if ( val_type.substr(0,4) == "long" ) + block.bind< map<KEY,long> >(); + else if ( val_type.substr(0,5) == "float" ) + block.bind< map<KEY,float> >(); + else if ( val_type.substr(0,6) == "double" ) + block.bind< map<KEY,double> >(); + else if ( val_type.substr(0,6) == "string" ) + block.bind< map<KEY,string> >(); + else if ( val_type == "std::string" ) + block.bind< map<KEY,string> >(); + else { + block.bind< map<KEY,string> >(); + } } - /// Specialized conversion of <ConditionInfo/> entities - template <> void Conv<ConditionInfo>::convert(xml_h element) const { - Catalog* det = _option<Catalog>(); - string name = element.attr<string>(_U(name)); - string cond = element.attr<string>(_LBU(condition)); - det->conditioninfo[name] = cond; + static void extractMap(xml_h element, BlockData& block) { + dddb_dim_t e = element; + string n = e.nameStr(); + string key_type = e.attr<string>(_LBU(keytype)); + string val_type = e.attr<string>(_LBU(valuetype)); + + if ( key_type.substr(0,5) == "short" ) + bind_map<short>(val_type,block); + else if ( key_type.substr(0,3) == "int" ) + bind_map<int>(val_type,block); + else if ( key_type.substr(0,4) == "long" ) + bind_map<long>(val_type,block); + else if ( key_type.substr(0,5) == "float" ) + bind_map<float>(val_type,block); + else if ( key_type.substr(0,6) == "double" ) + bind_map<double>(val_type,block); + else if ( key_type.substr(0,6) == "string" ) + bind_map<string>(val_type,block); + else if ( key_type == "std::string" ) + bind_map<string>(val_type,block); + else { + printout(INFO,"Param","++ Unknown MAP-conditions key-type:%s",key_type.c_str()); + bind_map<string>(val_type,block); + } + + for(xml_coll_t i(e,_LBU(item)); i; ++i) { + string key = i.attr<string>(_LBU(key)); + string val = i.attr<string>(_LBU(value)); + if ( key_type.substr(0,5) == "short" ) + insert_map_key<short>(key,val_type,val,block); + else if ( key_type.substr(0,3) == "int" ) + insert_map_key<int>(key,val_type,val,block); + else if ( key_type.substr(0,4) == "long" ) + insert_map_key<long>(key,val_type,val,block); + else if ( key_type.substr(0,5) == "float" ) + insert_map_key<float>(key,val_type,val,block); + else if ( key_type.substr(0,6) == "double" ) + insert_map_key<double>(key,val_type,val,block); + else if ( key_type.substr(0,6) == "string" ) + insert_map_key<string>(key,val_type,val,block); + else if ( key_type == "std::string" ) + insert_map_key<string>(key,val_type,val,block); + else { + printout(INFO,"Param","++ Unknown MAP-conditions key-type:%s",key_type.c_str()); + insert_map_key<string>(key,val_type,val,block); + } + } } /// Specialized conversion of <param/> and <paramVector> entities template <> void Conv<ConditionParam>::convert(xml_h element) const { - Condition::Params* c = _option<Condition::Params>(); - string n = element.attr<string>(_U(name)); - ConditionParam* p = new ConditionParam(); - p->type = element.hasAttr(_U(type)) ? element.attr<string>(_U(type)) : string("int"); - p->data = element.text(); - c->insert(make_pair(n,p)); + string nam = element.attr<string>(_U(name)); + string typ = element.hasAttr(_U(type)) ? element.attr<string>(_U(type)) : string("int"); + string data = element.text(); + pair<string,BlockData> block; + block.first = nam; + + if ( typ.substr(0,5) == "short" ) + block.second.set<short>(data); + else if ( typ.substr(0,3) == "int" ) + block.second.set<int>(data); + else if ( typ.substr(0,4) == "long" ) + block.second.set<long>(data); + else if ( typ.substr(0,5) == "float" ) + block.second.set<float>(data); + else if ( typ.substr(0,6) == "double" ) + block.second.set<double>(data); + else if ( typ.substr(0,6) == "string" ) + block.second.set<string>(data); + else if ( typ == "std::string" ) + block.second.set<string>(data); + else if ( typ == "Histo1D" ) + block.second.set<string>(data); + else if ( typ == "Histo2D" ) + block.second.set<string>(data); + else { + printout(INFO,"Param","++ Unknown conditions parameter type:%s data:%s",typ.c_str(),data.c_str()); + block.second.set<string>(data); + } + ConditionParams* par = _option<ConditionParams>(); + pair<ConditionParams::iterator,bool> res = par->insert(block); + if ( !res.second ) { + printout(INFO,"ParamVector","++ Failed to insert condition parameter:%s",nam.c_str()); + } + } + + /// Specialized conversion of <param/> and <paramVector> entities + template <> void Conv<ConditionParamVector>::convert(xml_h element) const { + string nam = element.attr<string>(_U(name)); + string typ = element.hasAttr(_U(type)) ? element.attr<string>(_U(type)) : string("int"); + string data = element.text(); + pair<string,BlockData> block; + string d = "["+data+" "; + size_t idx, idq; + + block.first = nam; + for(idx = d.find_first_not_of(' ',1); idx != string::npos;) { + if ( ::isspace(d[idx]) ) d[idx] = ' '; + idx = d.find_first_not_of(' ',++idx); + } + for(idx = d.find_first_not_of(' ',1); idx != string::npos; ++idx) { + if ( d[idx] != ' ' && ::isspace(d[idx]) ) d[idx] = ' '; + idq = d.find_first_of(' ',idx); + if ( idq != string::npos ) { + idx = d.find_first_not_of(' ',idq); + if ( idx == string::npos ) break; + if ( d[idx] != ' ' && ::isspace(d[idx]) ) d[idx] = ' '; + d[idq] = ','; + continue; + } + break; + } + d[d.length()-1] = ']'; + if ( typ.substr(0,5) == "short" ) + block.second.set<vector<short> >(d); + else if ( typ.substr(0,3) == "int" ) + block.second.set<vector<int> >(d); + else if ( typ.substr(0,4) == "long" ) + block.second.set<vector<long> >(d); + else if ( typ.substr(0,5) == "float" ) + block.second.set<vector<float> >(d); + else if ( typ.substr(0,6) == "double" ) + block.second.set<vector<double> >(d); + else if ( typ.substr(0,6) == "string" ) + block.second.set<vector<string> >(d); + else if ( typ == "std::string" ) + block.second.set<vector<string> >(d); + else { + printout(INFO,"ParamVector","++ Unknown conditions parameter type:%s",typ.c_str()); + block.second.set<vector<string> >(d); + } + ConditionParams* par = _option<ConditionParams>(); + pair<ConditionParams::iterator,bool> res = par->insert(block); + if ( !res.second ) { + printout(INFO,"ParamVector","++ Failed to insert condition parameter:%s",nam.c_str()); + } + } + + /// Specialized conversion of <map/> conditions entities + template <> void Conv<ConditionParamMap>::convert(xml_h element) const { + string nam = element.attr<string>(_U(name)); + pair<string,BlockData> block; + block.first = nam; + extractMap(element,block.second); + + ConditionParams* par = _option<ConditionParams>(); + pair<ConditionParams::iterator,bool> res = par->insert(block); + if ( !res.second ) + printout(INFO,"ParamMap","++ Failed to insert map-condition:%s",nam.c_str()); + } + + /// Specialized conversion of <specific/> conditions entities + template <> void Conv<ConditionParamSpecific>::convert(xml_h element) const { + string nam = element.parent().attr<string>(_U(name)); + pair<string,BlockData> block; + stringstream str; + + XML::dump_tree(element, str); + block.second.set<string>(str.str()); + block.first = nam; + + ConditionParams* par = _option<ConditionParams>(); + pair<ConditionParams::iterator,bool> res = par->insert(block); + if ( !res.second ) { + printout(INFO,"ParamVector","++ Failed to insert condition entry:%s of type <specific/>",nam.c_str()); + } } /// Specialized conversion of <condition/> entities template <> void Conv<Condition>::convert(xml_h element) const { Context* context = _param<Context>(); Catalog* catalog = _option<Catalog>(); + Document* doc = context->locals.xml_doc; string name = element.attr<string>(_U(name)); string id = object_href(element,name); string path = object_path(context,name); - Condition* cond = new Condition(); - static int num_param = 0, num_paramVector = 0; - - cond->id = id; - cond->name = name; - cond->path = path; - cond->classID = element.attr<string>(_LBU(classID)); - xml_coll_t(element,_U(param)).for_each(Conv<ConditionParam>(lcdd,context,&cond->params)); - xml_coll_t(element,_LBU(paramVector)).for_each(Conv<ConditionParam>(lcdd,context,&cond->paramVectors)); - context->collect(cond->id, cond); + static int num_param = 0, num_vector = 0, num_map = 0, num_spec = 0; + + Condition cond(name,"DDDB"); + cond->address = id; + cond->value = doc->name; + cond->validity = ""; + cond->hash = hash32(cond->value); + if ( element.hasAttr(_U(comment)) ) { + cond->comment = element.attr<string>(_U(comment)); + } + + DDDBConditionData& d = cond.bind<DDDBConditionData>(); + d.document = doc->addRef(); + if ( element.hasAttr(_LBU(classID)) ) { + d.classID = element.attr<int>(_LBU(classID)); + } + Conv<ConditionParam> object_cnv(lcdd,context,&d.params); + xml_coll_t(element,_U(param)).for_each(object_cnv); + + Conv<ConditionParamVector> vector_cnv(lcdd,context,&d.params); + xml_coll_t(element,_LBU(paramVector)).for_each(vector_cnv); + + Conv<ConditionParamMap> map_cnv(lcdd,context,&d.params); + xml_coll_t(element,_LBU(map)).for_each(map_cnv); + + Conv<ConditionParamSpecific> specific_cnv(lcdd,context,&d.params); + xml_coll_t(element,_LBU(specific)).for_each(specific_cnv); + + for(xml_coll_t iter(element,_U(star)); iter; ++iter) { + string tag = iter.tag(); + string nam = iter.hasAttr(_U(name)) ? iter.attr<string>(_U(name)) : string(); + if ( context->print_condition ) { + printout(INFO,"ParamMap","++ Condition:%s -> %s",path.c_str(),nam.c_str()); + } + if ( tag == "param" ) { ++num_param; continue; } + if ( tag == "paramVector" ) { ++num_vector; continue; } + if ( tag == "map" ) { ++num_map; continue; } + if ( tag == "specific" ) { ++num_spec; continue; } + printout(INFO,"Condition","++ Unknown conditions tag:%s obj:%s id:%s", + tag.c_str(), path.c_str(), id.c_str()); + } + context->collect(id, cond); if ( catalog ) { - context->collectPath(cond->path, cond); + context->collectPath(path, cond); } - num_param += int(cond->params.size()); - num_paramVector += int(cond->paramVectors.size()); + num_param += int(d.params.size()); if ( (context->geo->conditions.size()%500) == 0 ) { - printout(INFO,"Condition","++ Processed %d conditions....last:%s Number of Params: Scalar: %d Vectors: %d", - int(context->geo->conditions.size()), path.c_str(), - num_param, num_paramVector); + printout(INFO,"Condition","++ Processed %d conditions....last:%s Number of Params: %d Vec:%d Map:%d Spec:%d", + int(context->geo->conditions.size()), path.c_str(), num_param, num_vector, num_map, num_spec); } } @@ -463,7 +718,7 @@ namespace DD4hep { } return; } - Condition* cond = (*i).second; + Condition cond((*i).second); path = object_path(context,cond->name); context->collectPath(path, cond); if ( context->print_condition_ref ) { @@ -471,19 +726,49 @@ namespace DD4hep { } } + /// Specialized conversion of <author/> entities + template <> void Conv<Author>::convert(xml_h element) const { + string* context = _option<string>(); + if ( element.hasAttr(_U(author)) ) *context = element.attr<string>(_U(author)); + } + + /// Specialized conversion of <version/> entities + template <> void Conv<Version>::convert(xml_h element) const { + string* context = _option<string>(); + if ( element.hasAttr(_U(version)) ) *context = element.attr<string>(_U(version)); + } + + /// Specialized conversion of <param/> entities + template <> void Conv<Param>::convert(xml_h element) const { + Catalog* det = _option<Catalog>(); + string name = element.attr<string>(_U(name)); + string type = element.hasAttr(_U(type)) ? element.attr<string>(_U(type)) : string("int"); + string value = element.text(); + det->params[name] = make_pair(type,value); + } + + /// Specialized conversion of <ConditionInfo/> entities + template <> void Conv<ConditionInfo>::convert(xml_h element) const { + Catalog* det = _option<Catalog>(); + string name = element.attr<string>(_U(name)); + string cond = element.attr<string>(_LBU(condition)); + det->conditioninfo[name] = cond; + } + /// Specialized conversion of <isotope/> entities template <> void Conv<Isotope>::convert(xml_h element) const { Context* context = _param<Context>(); dddb_dim_t x_i = element; string name = x_i.nameStr(); string id = object_path(context,name); - if ( !find(id, context->geo->isotopes) ) { + if ( !_find(id, context->geo->isotopes) ) { Isotope* i = new Isotope(); i->name = name; i->A = x_i.A(-1.0); i->Z = x_i.Z(-1.0); i->density = x_i.density(-1.0); context->collect(id, i); + i->setDocument(context->locals.xml_doc); } } @@ -509,7 +794,7 @@ namespace DD4hep { dddb_dim_t x_elem = element; string name = x_elem.nameStr(); string id = object_href(element, name); - if ( !find(id, context->geo->elements) ) { + if ( !_find(id, context->geo->elements) ) { Element* e = new Element(); dddb_dim_t atom = x_elem.child(_U(atom),false); e->id = id; @@ -534,6 +819,7 @@ namespace DD4hep { } context->collect(e->id, e); context->collectPath(e->path, e); + e->setDocument(context->locals.xml_doc); } } @@ -573,7 +859,7 @@ namespace DD4hep { dddb_dim_t x_mat = element; string name = x_mat.nameStr(); string id = object_href(element, name); - if ( !find(id, context->geo->materials) ) { + if ( !_find(id, context->geo->materials) ) { Material* m = new Material(); m->name = name; m->id = id; @@ -589,6 +875,7 @@ namespace DD4hep { xml_coll_t(element, _U(component)).for_each(Conv<MaterialComponent>(lcdd,context,m)); context->collect(m->id, m); // We collect materials by NAME!!! context->collect(m->name, m); + m->setDocument(context->locals.xml_doc); if ( catalog ) context->collectPath(m->path, m); } } @@ -891,7 +1178,7 @@ namespace DD4hep { Context* context = _param<Context>(); string name = element.attr<string>(_U(name)); string id = object_href(element, name); - if ( !find(id, context->geo->volumes) ) { + if ( !_find(id, context->geo->volumes) ) { Catalog* catalog = _option<Catalog>(); string material; LogVol* vol = new LogVol; @@ -941,6 +1228,8 @@ namespace DD4hep { } // Now collect the information vol->shape = id; + s->setDocument(context->locals.xml_doc); + vol->setDocument(context->locals.xml_doc); context->collect(id, s); context->collect(id, vol); if ( catalog ) context->collectPath(vol->path, vol); @@ -971,11 +1260,12 @@ namespace DD4hep { dddb_dim_t x_vol = element; string name = x_vol.nameStr(); string id = object_href(element, name); - if ( !find(id, context->geo->placements) ) { + if ( !_find(id, context->geo->placements) ) { PhysVol* vol = new PhysVol(); this->fill(element, vol); context->collect(id, vol); context->collectPath(vol->path,vol); + vol->setDocument(context->locals.xml_doc); if ( optional ) { _option<LogVol>()->physvols.push_back(vol); } @@ -1072,6 +1362,7 @@ namespace DD4hep { det->path = path; det->id = id; det->support = parent; + det->setDocument(context->locals.xml_doc); if ( context->print_detelem ) { printout(INFO,"DetElem"," xml:%s id=%s [%s/%s] doc:%s obj:%s / %s", element.parent().tag().c_str(), @@ -1130,6 +1421,7 @@ namespace DD4hep { catalog->level = Increment<Catalog>::counter(); catalog->type = "Logical"; catalog->support = ""; + catalog->setDocument(context->locals.xml_doc); context->collect(id, catalog); context->collectPath(catalog->path, catalog); if ( catalog->path == "/dd" ) { @@ -1168,20 +1460,17 @@ namespace DD4hep { /// Specialized conversion of <DDDB/> entities template <> void Conv<dddb>::convert(xml_h element) const { - Context* context = _param<Context>(); Catalog* catalog = 0; + Context* context = _param<Context>(); Context::PreservedLocals locals(context); xml_coll_t(element, _U(parameter)).for_each(Conv<Parameter>(lcdd,context,catalog)); xml_coll_t(element, _U(isotope)).for_each(Conv<Isotope>(lcdd,context,catalog)); xml_coll_t(element, _U(element)).for_each(Conv<Element>(lcdd,context,catalog)); xml_coll_t(element, _U(material)).for_each(Conv<Material>(lcdd,context,catalog)); xml_coll_t(element, _U(logvol)).for_each(Conv<LogVol>(lcdd,context,catalog)); - // catalog = _option<Catalog>(); xml_coll_t(element, _LBU(condition)).for_each(Conv<Condition>(lcdd,context,catalog)); - catalog = 0; xml_coll_t(element, _LBU(detelem)).for_each(Conv<DetElem>(lcdd,context,catalog)); xml_coll_t(element, _LBU(catalog)).for_each(Conv<Catalog>(lcdd,context,catalog)); - xml_coll_t(element, _LBU(detelemref)).for_each(Conv<DetElemRef>(lcdd,context,catalog)); xml_coll_t(element, _LBU(elementref)).for_each(Conv<ElementRef>(lcdd,context,catalog)); xml_coll_t(element, _LBU(materialref)).for_each(Conv<MaterialRef>(lcdd,context,catalog)); @@ -1191,6 +1480,17 @@ namespace DD4hep { xml_coll_t(element, _LBU(detelemref)).for_each(Conv<DetElemRef>(lcdd,context,catalog)); } + /// Specialized conversion of <DDDB/> entities + template <> void Conv<dddb_conditions>::convert(xml_h element) const { + Catalog* catalog = 0; + Context* context = _param<Context>(); + Context::PreservedLocals locals(context); + xml_coll_t(element, _LBU(condition)).for_each(Conv<Condition>(lcdd,context,catalog)); + xml_coll_t(element, _LBU(catalog)).for_each(Conv<Catalog>(lcdd,context,catalog)); + xml_coll_t(element, _LBU(conditionref)).for_each(Conv<ConditionRef>(lcdd,context,catalog)); + xml_coll_t(element, _LBU(catalogref)).for_each(Conv<CatalogRef>(lcdd,context,catalog)); + } + void apply_trafo(int apply, Position& pos, RotationZYX& rot, Transform3D& trafo, Transform3D& tr) { switch(apply) { case 99: { @@ -1303,41 +1603,32 @@ namespace DD4hep { } return p; } - void load_dddb_entity(Context* context, - Catalog* catalog, - xml_h element, + + template <typename ACTION=dddb> + void load_dddb_entity(Context* context, + Catalog* catalog, + xml_h element, const string& ref, bool prt) { size_t hash = ref.find("#"); if ( hash != 0 ) { try { - string doc_path = reference_href(element,ref); + string doc_path = element.ptr() ? reference_href(element,ref) : ref; if ( ref == "conddb:/Conditions/Online" ) doc_path = reference_href(element,ref); hash = doc_path.find('#'); if ( hash != string::npos ) doc_path = doc_path.substr(0,hash); #if 0 - if ( doc_path.find("/Conditions/") != string::npos ) { - printout(INFO, "load_dddb", "SKIPPING DOC %s", doc_path.c_str()); - return; - } - if ( doc_path.find("conddb:/TrackfitGeometry") != string::npos ) { - printout(INFO, "load_dddb", "SKIPPING DOC %s", doc_path.c_str()); - return; - } if ( doc_path.find("conddb:/Rich") != string::npos ) { printout(INFO, "load_dddb", "SKIPPING DOC %s", doc_path.c_str()); return; } #endif - if ( context->files.find(doc_path) != context->files.end() ) + dddb::Documents& docs = context->geo->documents; + if ( _find(doc_path,docs) ) return; - context->files.insert(doc_path); - if ( context->print_docs ) { - printout(INFO, "load_dddb", "Loading DOC path %s parent:%s", - doc_path.c_str(), context->locals.xml_path.c_str()); - } + size_t idx = doc_path.find('['); size_t idq = doc_path.find(']'); string key, fp = doc_path; @@ -1345,22 +1636,37 @@ namespace DD4hep { key = doc_path.substr(idx+1,idq-idx-1); fp = doc_path.substr(0,idx); } - xml_doc_holder_t doc(xml_handler_t().load(fp, context->hlp->xmlReader())); + XML::UriReader* rdr = context->resolver; + DDDBReaderContext* ctx = (DDDBReaderContext*)rdr->context(); + Document* xml_doc = new Document(); + xml_doc->id = doc_path; + xml_doc->name = context->locals.obj_path; + xml_doc->context.doc = xml_doc->id; + xml_doc->context.event_time = ctx->event_time; + xml_doc->context.valid_since = 0; + xml_doc->context.valid_until = 0; + docs.insert(make_pair(doc_path,xml_doc->addRef())); + XML::UriContextReader reader(rdr, &xml_doc->context); + xml_doc_holder_t doc(xml_handler_t().load(fp, &reader)); xml_h e = doc.root(); + context->print(xml_doc); if ( e ) { if ( !key.empty() ) { stringstream str; XML::dump_tree(e, str); string buffer = str.str(); - while( (idx=buffer.find("-KEY-")) != string::npos ) { + while( (idx=buffer.find("-KEY-")) != string::npos ) buffer.replace(idx,5,key); - } - doc.assign(xml_handler_t().parse(buffer.c_str(), buffer.length(), doc_path.c_str(), context->hlp->xmlReader())); + doc.assign(xml_handler_t().parse(buffer.c_str(), + buffer.length(), + doc_path.c_str(), + &reader)); e = doc.root(); } Context::PreservedLocals locals(context); context->locals.doc_path = doc_path; - Conv<dddb> converter(context->lcdd, context, catalog); + context->locals.xml_doc = xml_doc; + Conv<ACTION> converter(context->lcdd, context, catalog); context->print_condition = prt; if ( prt || context->print_xml ) XML::dump_tree(e); converter(e); @@ -1375,12 +1681,26 @@ namespace DD4hep { } } - void config_context(Context& context) { - context.locals.doc_path = "conddb://lhcb.xml"; - context.locals.obj_path = "/"; - context.locals.xml_path = "/"; + void config_context(Context& context, + XML::UriReader* rdr, + const std::string& doc_path, + const std::string& obj_path) { + DDDBReaderContext* ctx = (DDDBReaderContext*)rdr->context(); + Document* doc = new Document(); + doc->name = obj_path; + doc->id = doc_path; + doc->context.event_time = ctx->event_time; + doc->context.valid_since = ctx->valid_since; + doc->context.valid_until = ctx->valid_until; + context.resolver = rdr; + context.geo = new dddb(); + context.locals.doc_path = doc_path; + context.locals.obj_path = obj_path; + context.locals.xml_doc = doc; + context.geo->documents.insert(make_pair("Initial_dummy_doc",doc->addRef())); context.print_xml = false; - context.print_docs = false; + + context.print_docs = true; context.print_materials = false; context.print_logvol = false; context.print_shapes = false; @@ -1394,55 +1714,78 @@ namespace DD4hep { context.print_catalog = false; context.print_catalog_ref = false; } - } -} -/// Plugin entry point. -static long create_dddb(lcdd_t& lcdd, xml_h element) { - DDDBHelper* helper = lcdd.extension<DDDBHelper>(false); - if ( helper ) { - Context context(lcdd); - context.hlp = helper; - context.geo = new dddb(); - config_context(context); - - /// Convert the XML information - Conv<dddb> converter(lcdd, &context); - converter( element ); - checkParents( &context ); - fixCatalogs( &context ); - /// Transfer ownership from local context to the helper - helper->setGeometry( context.geo ); - context.geo = 0; - return 1; + /// Plugin entry point. + template <typename ACTION> + long load_dddb_objects(lcdd_t& lcdd, int argc, char** argv) { + DDDBHelper* hlp = lcdd.extension<DDDBHelper>(false); + if ( hlp ) { + Context ctxt(lcdd); + string sys_id = "conddb://lhcb.xml"; + string obj_path = "/"; + XML::UriReader* rdr = hlp->xmlReader(); + if ( argc == 0 ) { + return 0; + } + if ( argc >= 1 && argv[0] != 0 ) { + rdr = (XML::UriReader*)argv[0]; + } + if ( argc >= 2 && argv[1] != 0 ) { + sys_id = argv[1]; + } + if ( argc >= 3 && argv[2] != 0 ) { + obj_path = argv[2]; + } + if ( argc >= 4 && argv[3] != 0 ) { + long evt_time = *(long*)argv[3]; + DDDBReaderContext* ctx = (DDDBReaderContext*)rdr->context(); + ctx->event_time = evt_time; + } + config_context(ctxt, rdr, sys_id, obj_path); + load_dddb_entity<ACTION>(&ctxt,0,0,ctxt.locals.doc_path); + checkParents( &ctxt ); + fixCatalogs( &ctxt ); + /// Transfer ownership from local context to the helper + hlp->setDetectorDescription( ctxt.geo ); + ctxt.geo = 0; + return 1; + } + except("DDDB","+++ Failed to access cool. No DDDBHelper object defined. Run plugin DDDBInstallHelper."); + return 0; + } } - except("DDDB","+++ Failed to access cool. No DDDBHelper object defined. Run plugin DDDBInstallHelper."); - return 0; -} -DECLARE_XML_DOC_READER(DDDB,create_dddb) -/// Plugin entry point. -static long create_dddb_file(lcdd_t& lcdd, xml_h element) { - DDDBHelper* helper = lcdd.extension<DDDBHelper>(false); - if ( helper ) { - Context context(lcdd); - context.hlp = helper; - context.geo = new dddb(); - config_context(context); - /// Convert the XML information - Conv<dddb> converter(lcdd, &context); - converter(element); - checkParents( &context ); - fixCatalogs( &context ); - /// Transfer ownership from local context to the helper - helper->setGeometry(context.geo); - context.geo = 0; - return 1; + namespace DDDB { + long load_dddb_from_uri(lcdd_t& lcdd, int argc, char** argv) { + return load_dddb_objects<dddb>(lcdd,argc,argv); + } + long load_dddb_conditions_from_uri(lcdd_t& lcdd, int argc, char** argv) { + return load_dddb_objects<dddb_conditions>(lcdd,argc,argv); + } + /// Plugin entry point. + long load_dddb_from_handle(lcdd_t& lcdd, xml_h element) { + DDDBHelper* helper = lcdd.extension<DDDBHelper>(false); + if ( helper ) { + Context context(lcdd); + config_context(context, helper->xmlReader(), "conddb://lhcb.xml", "/"); + /// Convert the XML information + Conv<dddb> converter(lcdd, &context); + converter( element ); + checkParents( &context ); + fixCatalogs( &context ); + /// Transfer ownership from local context to the helper + helper->setDetectorDescription( context.geo ); + context.geo = 0; + return 1; + } + except("DDDB","+++ Failed to access cool. No DDDBHelper object defined. Run plugin DDDBInstallHelper."); + return 0; + } } - except("DDDB","+++ Failed to access cool. No DDDBHelper object defined. Run plugin DDDBInstallHelper."); - return 0; } -DECLARE_XML_DOC_READER(DDDB_file,create_dddb_file) +DECLARE_XML_DOC_READER(DDDB,load_dddb_from_handle) +DECLARE_APPLY(DDDBLoader,load_dddb_from_uri) +DECLARE_APPLY(DDDBConditionsLoader,load_dddb_conditions_from_uri) /// Plugin entry point. static long install_helper(lcdd_t& lcdd, int argc, char** argv) { diff --git a/DDDB/src/DDDB2Objects.cpp b/DDDB/src/DDDB2Objects.cpp index f2790ee38..a3151ff89 100644 --- a/DDDB/src/DDDB2Objects.cpp +++ b/DDDB/src/DDDB2Objects.cpp @@ -20,12 +20,18 @@ // Framework includes #include "DDDB/DDDBTags.h" -#include "DDDB/Dimension.h" +#include "DDDB/DDDBDimension.h" #include "DDDB/DDDBHelper.h" #include "DDDB/DDDBConversion.h" +#include "DDDB/DDDBConditionData.h" + #include "DD4hep/LCDD.h" #include "DD4hep/DetectorTools.h" -#include "DD4hep/objects/ConditionsInterna.h" +#include "DD4hep/InstanceCount.h" + +#include "DDCond/ConditionsManager.h" +#include "DDCond/ConditionsIOVPool.h" +#include "DDCond/ConditionsInterna.h" // ROOT include files #include "TGeoManager.h" @@ -44,23 +50,30 @@ using namespace DD4hep::DDDB; /// Namespace for the AIDA detector description toolkit namespace DD4hep { + /// Keep all in here anonymous. Does not have to be visible outside. namespace { + struct DetElem {}; + typedef Conditions::Interna::ConditionObject GeoCondition; - typedef Geometry::PlacedVolume GeoPlacement; - typedef Geometry::Volume GeoVolume; - typedef Geometry::Material GeoMaterial; - typedef Geometry::Solid GeoSolid; - typedef Geometry::DetElement DetElement; + typedef Conditions::ConditionsManager ConditionsManager; + typedef Conditions::IOVType IOVType; + typedef Geometry::PlacedVolume GeoPlacement; + typedef Geometry::Volume GeoVolume; + typedef Geometry::Material GeoMaterial; + typedef Geometry::Solid GeoSolid; + typedef Geometry::DetElement DetElement; const double SMALL = 1e-10; /// Helper class to facilitate conversion. Purely local. struct Context { + typedef set<string> StringSet; + Context(Geometry::LCDD& l, dddb* g) - : lcdd(l), geo(g), helper(0), + : lcdd(l), geo(g), helper(0), epoch(0), max_volume_depth(9999), print_materials(false), print_volumes(false), @@ -70,11 +83,12 @@ namespace DD4hep { print_params(false), print_detelem(false), print_conditions(false), - print_vis(false) + print_vis(false), + conditions_only(false) { } ~Context() { - printout(INFO,"Context","Destructor calling...."); + //printout(INFO,"Context","Destructor calling...."); } template <typename T, typename Q> static const Q find(const typename std::map<T,Q>& m, const T& match) { @@ -95,30 +109,34 @@ namespace DD4hep { typedef std::map<std::string, DetElement> DetectorMap; typedef std::map<std::string, TGeoVolume*> VolumeMap; typedef std::map<DetElement, Catalog*> DetectorElements; - typedef std::map<Condition*, GeoCondition*> Conditions; - - Isotopes isotopes; - Elements elements; - Materials materials; - Shapes shapes; - Volumes volumes; - VolumeMap volumePaths; - Placements placements; - DetElement detectors; - DetectorMap catalogPaths; - DetectorElements detelements; - Conditions conditions; - GeoVolume lvDummy; - int max_volume_depth; - bool print_materials; - bool print_volumes; - bool print_logvol; - bool print_shapes; - bool print_physvol; - bool print_params; - bool print_detelem; - bool print_conditions; - bool print_vis; + typedef std::map<std::string, DetElement> DetConditions; + + Isotopes isotopes; + Elements elements; + Materials materials; + Shapes shapes; + Volumes volumes; + VolumeMap volumePaths; + Placements placements; + DetElement detectors; + DetectorMap catalogPaths; + DetectorElements detelements; + DetConditions detconditions; + GeoVolume lvDummy; + ConditionsManager manager; + const IOVType* epoch; + int max_volume_depth; + bool print_materials; + bool print_volumes; + bool print_logvol; + bool print_shapes; + bool print_physvol; + bool print_params; + bool print_detelem; + bool print_conditions; + bool print_vis; + bool conditions_only; + static GeoPlacement placement(DetElement de) { if ( de.isValid() ) { GeoPlacement p = de.placement(); @@ -164,12 +182,6 @@ namespace DD4hep { } }; - template <typename T> struct Increment { - static int& counter() { static int cnt=0; return cnt; } - Increment() { ++counter(); } - ~Increment() { --counter(); } - }; - template <typename T> struct CNV : Converter<T,T*> { public: /// Initializing constructor of the functor with initialization of the user parameter @@ -197,8 +209,10 @@ namespace DD4hep { } } }; + } - template <> void* CNV<Condition>::convert(Condition *object) const; + namespace { + template <> void* CNV<GeoCondition>::convert(GeoCondition *object) const; template <> void* CNV<Isotope>::convert(Isotope *object) const; template <> void* CNV<Element>::convert(Element *object) const; template <> void* CNV<Material>::convert(Material *object) const; @@ -214,16 +228,20 @@ namespace DD4hep { template <> template <> GeoVolume CNV<LogVol>::get<GeoVolume>(const string& obj) const; /// Convert single condition objects - template <> void* CNV<Condition>::convert(Condition *object) const { + template <> void* CNV<GeoCondition>::convert(GeoCondition *obj) const { Context* context = _param<Context>(); - GeoCondition* cond = Context::find(context->conditions, object); - if ( !cond ) { - cond = new GeoCondition(); - cond->value = "";//object->data; - cond->address = object->id; - context->conditions.insert(make_pair(object, cond)); - } - return cond; + Conditions::Condition cond = obj; + if ( cond.isValid() ) { + typedef Conditions::IOV::Key _K; + DDDBConditionData& d = cond.get<DDDBConditionData>(); + Document* doc = d.document; + string cond_path = doc->name+"/"+obj->name; + _K::first_type since = doc->context.valid_since; + _K::second_type until = doc->context.valid_until; + _K iov_key(since,until); + context->manager.registerUnlocked(context->epoch, iov_key, cond); + } + return cond.ptr(); } /// Convert single isotope objects @@ -535,9 +553,9 @@ namespace DD4hep { /// Convert logical volumes template <> void* CNV<LogVol>::convert(LogVol *object) const { struct VolumeDepth {}; + Increment<VolumeDepth> depth; Context* context = _param<Context>(); GeoVolume mother = Context::find(context->volumes, object); - Increment<VolumeDepth> depth; if ( !mother.isValid() ) { if ( depth.counter() >= context->max_volume_depth ) { @@ -577,7 +595,6 @@ namespace DD4hep { context->volumePaths[object->path] = mother.ptr(); // Now place all daughter volumes for(auto i=object->physvols.begin(); i!=object->physvols.end(); ++i) { - int num_places = 0; PhysVol* pv = *i; GeoPlacement place = context->find(context->placements, pv); if ( !place.isValid() ) { @@ -587,6 +604,7 @@ namespace DD4hep { " Unknown daughter vol:%s.",pv->c_id(), pv->logvol.c_str()); continue; } + int num_places = 0; const char* pv_name = pv->name.c_str(); switch(pv->type) { case PhysVol::PHYSVOL_REGULAR: { @@ -876,8 +894,15 @@ namespace DD4hep { context->volumePaths[lp] = gv.ptr(); } #endif + if ( !object->condition.empty() ) { + Context::DetConditions::iterator i = context->detconditions.find(object->condition); + if ( i != context->detconditions.end() ) { + printout(ERROR,"CNV<DetElem>","++ DetElement %s has multiple conditions assigned: %s + %s", + det.name(), (*i).first.c_str(), object->condition.c_str()); + } + context->detconditions.insert(make_pair(object->condition,det)); + } if ( context->print_detelem ) { - support = context->detelements[parent_element]; printout(INFO,"CNV<Catalog>","++ Converting catalog %p -> %p [cref:%d/%d lref:%d/%d lv:%s [%p] sup:%s np:%s] %s ", (void*)object, det.ptr(), int(object->catalogrefs.size()), @@ -925,7 +950,6 @@ namespace DD4hep { printout(INFO,"CNV<DE>:lvol","++ DE:%s ref[%2d]: ??????", object->path.c_str(), cnt); } if ( vol && !object->npath.empty() ) { - support = context->detelements[parent_element]; for(int i=0; i<vol->GetNdaughters(); ++i) { TGeoNode* dau = vol->GetNode(i); printout(INFO,"CNV<DE>:npath","++ DE:%s npath:%s Dau[%2d]: %s", @@ -938,81 +962,121 @@ namespace DD4hep { } template <> void* CNV<dddb>::convert(dddb *obj) const { - Context* context = _param<Context>(); - Increment<to_type> incr; - for_each(obj->isotopes.begin(), obj->isotopes.end(), cnv<Isotope>()); - printout(INFO,"DDDB2Object","++ Converted %d isotopes.",int(obj->isotopes.size())); - for_each(obj->elements.begin(), obj->elements.end(), cnv<Element>()); - printout(INFO,"DDDB2Object","++ Converted %d elements.",int(obj->elements.size())); - //for_each(obj->materials.begin(), obj->materials.end(), cnv<Material>()); - //printout(INFO,"DDDB2Object","++ Converted %d materials.",int(obj->materials.size())); - if ( !context->lvDummy.isValid() ) { - lcdd.manager().SetVisLevel(context->max_volume_depth); - context->lvDummy = GeoVolume("Dummy",Geometry::Box(0.0001,0.0001, 0.0001),lcdd.vacuum()); - context->lvDummy.setVisAttributes(lcdd.invisible()); - } - //for_each(obj->shapes.begin(), obj->shapes.end(), cnv<Shape>()); - //printout(INFO,"DDDB2Object","++ Converted %d shapes.",int(obj->shapes.size())); - //for_each(obj->volumes.begin(), obj->volumes.end(), cnv<LogVol>()); - //printout(INFO,"DDDB2Object","++ Converted %d volumes.",int(obj->volumes.size())); - //for_each(obj->placements.begin(),obj->placements.end(), cnv<PhysVol>()); - //printout(INFO,"DDDB2Object","++ Converted %d placements.",int(obj->placements.size())); - for_each(obj->conditions.begin(),obj->conditions.end(), cnv<Condition>()); - printout(INFO,"DDDB2Object","++ Converted %d conditions.",int(obj->conditions.size())); - cnv<Catalog>().convert( obj->top ); - if ( 0 == incr.counter() ) { - lcdd.endDocument(); + Context* context = _param<Context>(); + if ( !context->conditions_only ) { + GeoVolume world = lcdd.worldVolume(); + + for_each(obj->isotopes.begin(), obj->isotopes.end(), cnv<Isotope>()); + printout(INFO,"DDDB2Object","++ Converted %d isotopes.",int(obj->isotopes.size())); + for_each(obj->elements.begin(), obj->elements.end(), cnv<Element>()); + printout(INFO,"DDDB2Object","++ Converted %d elements.",int(obj->elements.size())); + //for_each(obj->materials.begin(), obj->materials.end(), cnv<Material>()); + //printout(INFO,"DDDB2Object","++ Converted %d materials.",int(obj->materials.size())); + //for_each(obj->shapes.begin(), obj->shapes.end(), cnv<Shape>()); + //printout(INFO,"DDDB2Object","++ Converted %d shapes.",int(obj->shapes.size())); + //for_each(obj->volumes.begin(), obj->volumes.end(), cnv<LogVol>()); + //printout(INFO,"DDDB2Object","++ Converted %d volumes.",int(obj->volumes.size())); + //for_each(obj->placements.begin(),obj->placements.end(), cnv<PhysVol>()); + //printout(INFO,"DDDB2Object","++ Converted %d placements.",int(obj->placements.size())); + + if ( obj->top ) { + if ( !context->lvDummy.isValid() ) { + lcdd.manager().SetVisLevel(context->max_volume_depth); + context->lvDummy = GeoVolume("Dummy",Geometry::Box(0.0001,0.0001, 0.0001),lcdd.vacuum()); + context->lvDummy.setVisAttributes(lcdd.invisible()); + } + if ( !world.isValid() ) { + string top = "/dd/Geometry/LHCb/lvLHCb"; + const LogVol* lv = Context::find(obj->volumePaths,top); + if ( !lv ) { + except("DDDB2DD4hep","++ No World volume defined."); + } + const Shape* s = Context::find(obj->shapes,lv->id); + if ( !s ) { + except("DDDB2DD4hep","++ No Shape for the world volume defined."); + } + obj->world = s->s.box; + } + cnv<Catalog>().convert(obj->top); + if ( !world.isValid() && lcdd.worldVolume().isValid() ) { + lcdd.endDocument(); + } + if ( !context->manager.isValid() ) { + Conditions::ConditionsManager manager = Conditions::ConditionsManager::from(lcdd); + manager["PoolType"] = "DD4hep_ConditionsLinearPool"; + manager["LoaderType"] = "dddb"; + manager["UserPoolType"] = "DD4hep_ConditionsLinearUserPool"; + manager["UpdatePoolType"] = "DD4hep_ConditionsLinearUpdatePool"; + manager->initialize(); + pair<bool,const Conditions::IOVType*> e = manager.registerIOVType(0, "epoch"); + context->manager = manager; + context->epoch = e.second; + } + } + } + if ( !context->manager.isValid() ) { + Conditions::ConditionsManager manager = Conditions::ConditionsManager::from(lcdd); + pair<bool,const Conditions::IOVType*> e = manager.registerIOVType(0, "epoch"); + context->manager = manager; + context->epoch = e.second; } + for_each(obj->conditions.begin(),obj->conditions.end(), cnv<GeoCondition>()); + //printout(INFO,"DDDB2Object","++ Converted %d conditions.",int(obj->conditions.size())); return obj; } } - /// Namespace for the AIDA detector description toolkit supporting XML utilities - namespace DDDB { - } /* End namespace DDDB */ -} /* End namespace DD4hep */ + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace DDDB { + long dddb_2_dd4hep(Geometry::LCDD& lcdd, int , char** ) { + DDDBHelper* helper = lcdd.extension<DDDBHelper>(false); + if ( helper ) { + Context context(lcdd, helper->detectorDescription()); + context.helper = helper; + context.print_materials = false; + context.print_logvol = false; + context.print_shapes = false; + context.print_physvol = false; + context.print_volumes = false; + context.print_params = false; + context.print_detelem = false; + context.print_conditions = false; + context.print_vis = false; + context.max_volume_depth = 9; - -static long dddb_2_dd4hep(Geometry::LCDD& lcdd, int , char** ) { - DDDBHelper* helper = lcdd.extension<DDDBHelper>(false); - if ( helper ) { - Context context(lcdd, helper->geometry()); - context.helper = helper; - context.print_materials = false; - context.print_logvol = false; - context.print_shapes = false; - context.print_physvol = false; - context.print_volumes = false; - context.print_params = false; - context.print_detelem = false; - context.print_conditions = false; - context.print_vis = false; - context.max_volume_depth = 9; - - CNV<dddb> cnv(lcdd,&context); - string top = "/dd/Geometry/LHCb/lvLHCb"; - const LogVol* lv = Context::find(context.geo->volumePaths,top); - if ( !lv ) { - except("DDDB2DD4hep","++ No World volume defined."); + CNV<dddb> cnv(lcdd,&context); + cnv(make_pair(string("World"),context.geo)); + printout(INFO,"DDDB","++ Converted %8d isotopes.", int(context.isotopes.size())); + printout(INFO,"DDDB","++ Converted %8d elements.", int(context.elements.size())); + printout(INFO,"DDDB","++ Converted %8d materials.", int(context.materials.size())); + printout(INFO,"DDDB","++ Converted %8d shapes.", int(context.shapes.size())); + printout(INFO,"DDDB","++ Converted %8d logical volumes.", int(context.volumes.size())); + printout(INFO,"DDDB","++ Converted %8d placements.", int(context.placements.size())); + printout(INFO,"DDDB","++ Converted %8d detector elements.",int(context.detelements.size())); + printout(INFO,"DDDB","++ Converted %8d conditions.", int(context.geo->conditions.size())); + helper->setDetectorDescription(0); + return 1; + } + except("DDDB","++ No DDDBHelper instance installed. Geometry conversion failed!"); + return 1; } - const Shape* s = Context::find(context.geo->shapes,lv->id); - if ( !s ) { - except("DDDB2DD4hep","++ No Shape for the world volume defined."); + long dddb_conditions_2_dd4hep(Geometry::LCDD& lcdd, int , char** ) { + DDDBHelper* helper = lcdd.extension<DDDBHelper>(false); + if ( helper ) { + Context context(lcdd, helper->detectorDescription()); + context.helper = helper; + context.print_conditions = false; + context.conditions_only = true; + CNV<dddb> cnv(lcdd,&context); + cnv(make_pair(string(),context.geo)); + helper->setDetectorDescription(0); + return 1; + } + except("DDDB","++ No DDDBHelper instance installed. Geometry conversion failed!"); + return 1; } - context.geo->world = s->s.box; - cnv(make_pair(string("World"),context.geo)); - printout(INFO,"DDDB2DD4hep","++ Converted %8d isotopes.", int(context.isotopes.size())); - printout(INFO,"DDDB2DD4hep","++ Converted %8d elements.", int(context.elements.size())); - printout(INFO,"DDDB2DD4hep","++ Converted %8d materials.", int(context.materials.size())); - printout(INFO,"DDDB2DD4hep","++ Converted %8d shapes.", int(context.shapes.size())); - printout(INFO,"DDDB2DD4hep","++ Converted %8d logical volumes.", int(context.volumes.size())); - printout(INFO,"DDDB2DD4hep","++ Converted %8d placements.", int(context.placements.size())); - printout(INFO,"DDDB2DD4hep","++ Converted %8d detector elements.",int(context.detelements.size())); - printout(INFO,"DDDB2DD4hep","++ Converted %8d conditions.", int(context.conditions.size())); - helper->setGeometry(0); - return 1; - } - except("DDDB2DD4hep","++ No DDDBHelper instance installed. Geometry conversion failed!"); - return 1; -} + + } /* End namespace DDDB */ +} /* End namespace DD4hep */ DECLARE_APPLY(DDDB2DD4hep,dddb_2_dd4hep) +DECLARE_APPLY(DDDBConditions2DD4hep,dddb_conditions_2_dd4hep) diff --git a/DDDB/src/DDDBConditionData.cpp b/DDDB/src/DDDBConditionData.cpp new file mode 100644 index 000000000..deb7615d1 --- /dev/null +++ b/DDDB/src/DDDBConditionData.cpp @@ -0,0 +1,78 @@ +// $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 +// +//========================================================================== +// +// DDDB is a detector description convention developed by the LHCb experiment. +// For further information concerning the DTD, please see: +// http://lhcb-comp.web.cern.ch/lhcb-comp/Frameworks/DetDesc/Documents/lhcbDtd.pdf +// +//========================================================================== + +// Framework includes +#include "DD4hep/Printout.h" +#include "DDDB/DDDBConversion.h" +#include "DDDB/DDDBConditionData.h" + +using namespace DD4hep; + +/// Default constructor +DDDB::DDDBConditionData::DDDBConditionData() : document(0) { +} + +/// Default destructor +DDDB::DDDBConditionData::~DDDBConditionData() { + if ( document ) document->release(); + document = 0; +} + +typedef DDDB::DDDBConditionData data_t; + +/// print Conditions object +std::ostream& operator << (std::ostream& s, const data_t& data) { + struct _Print { + void operator()(const data_t::Params::value_type& obj) const { + printout(INFO,"Condition","++ %-16s %-8s -> %s", + obj.first.c_str(), + typeName(obj.second.typeInfo()).c_str(), + obj.second.str().c_str()); + } + }; + if ( !data.params.empty() ) { + for_each(data.params.begin(), data.params.end(),_Print()); + } + return s; +} + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + /// Do NOTHING version! Function present to formally satisfy code. User implementation required + int __eval_none(data_t*, const std::string&) { + return 1; + } + /// Namespace for the AIDA detector for utilities using boost::spirit parsers + namespace Parsers { + int parse(data_t& data,const std::string& input) { + if ( data.params.empty() || input.empty() ) { + return 0; + } + return 1; + } + } +} + +#include "DD4hep/ToStream.h" +#include "DD4hep/objects/BasicGrammar_inl.h" +#include "DD4hep/objects/ConditionsInterna.h" + +DD4HEP_DEFINE_PARSER_GRAMMAR(data_t,__eval_none) +DD4HEP_DEFINE_CONDITIONS_TYPE(data_t) diff --git a/DDDB/src/DDDBConditionsLoader.cpp b/DDDB/src/DDDBConditionsLoader.cpp new file mode 100644 index 000000000..3f6637763 --- /dev/null +++ b/DDDB/src/DDDBConditionsLoader.cpp @@ -0,0 +1,152 @@ +// 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 "DDDB/DDDBConditionsLoader.h" +#include "DDDB/DDDBReaderContext.h" +#include "DDDB/DDDBHelper.h" +#include "DD4hep/Printout.h" +#include "DD4hep/Factories.h" +#include "DD4hep/Operators.h" +#include "DD4hep/objects/ConditionsInterna.h" +#include "DDCond/ConditionsInterna.h" + +// C/C++ include files +#include <set> + +// Forward declartions +using namespace std; +using namespace DD4hep::DDDB; +using DD4hep::Geometry::LCDD; +using DD4hep::Geometry::DetElement; +using DD4hep::Conditions::IOV; +using DD4hep::Conditions::Condition; +using DD4hep::Conditions::ConditionsManager; +using DD4hep::Conditions::Interna::ConditionsManagerObject; +using DD4hep::Conditions::ConditionsDataLoader; +using DD4hep::Conditions::ConditionsListener; +using DD4hep::Conditions::RangeConditions; + +namespace { + void* create_loader(LCDD& lcdd, int argc, char** argv) { + const char* name = argc>0 ? argv[0] : "DDDBLoader"; + ConditionsManagerObject* m = (ConditionsManagerObject*)(argc>0 ? argv[1] : 0); + return new DDDBConditionsLoader(lcdd,ConditionsManager(m),name); + } +} +DECLARE_LCDD_CONSTRUCTOR(DD4hep_Conditions_dddb_Loader,create_loader) + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace DDDB { + /// Plugin entry point. + long load_dddb_conditions_from_uri(LCDD& lcdd, int argc, char** argv); + long dddb_conditions_2_dd4hep(LCDD& lcdd, int argc, char** argv); + + long load_dddb_from_uri(LCDD& lcdd, int argc, char** argv); + long dddb_2_dd4hep(LCDD& lcdd, int argc, char** argv); + } /* End namespace DDDB */ +} /* End namespace DD4hep */ + +/// Standard constructor, initializes variables +DDDBConditionsLoader::DDDBConditionsLoader(LCDD& lcdd, ConditionsManager mgr, const string& nam) +: Conditions::ConditionsDataLoader(lcdd, mgr, nam) +{ + DDDBHelper* helper = lcdd.extension<DDDBHelper>(); // Ensures object existence! + m_resolver = helper->xmlReader(); +} + +/// Default Destructor +DDDBConditionsLoader::~DDDBConditionsLoader() { +} + +/// Load a condition set given a Detector Element and the conditions name according to their validity +size_t DDDBConditionsLoader::load_range(DetElement det, + const string& cond, + const IOV& req_validity, + RangeConditions& conditions) { + return 0; +} + +size_t DDDBConditionsLoader::load(DetElement det, + const string& cond, + const IOV& req_validity, + RangeConditions& conditions) { + return 0; +} + +/// ConditionsListener overload: onRegister new condition +void DDDBConditionsLoader::onRegisterCondition(Condition cond, void* param) { + pair<RangeConditions*,IOV*>* arg = (pair<RangeConditions*,IOV*>*)param; + RangeConditions* range = arg->first; + Condition::Object* c = cond.ptr(); + RangeConditions::iterator i=std::find_if(range->begin(),range->end(),byName(cond)); + if ( i != range->end() ) { + (*i) = cond; + printout(DEBUG,"DDDB","++ Got MATCH: %-40s [%08X] --> %s.", + (c->value+"/"+c->name).c_str(), c->hash, c->address.c_str()); + arg->second->iov_intersection(cond.iov()); + return; + } + printout(INFO,"DDDB","++ Got update: %-40s [%08X] --> %s.", + (c->value+"/"+c->name).c_str(), c->hash, c->address.c_str()); +} + +/// Update a range of conditions according to the required IOV +size_t DDDBConditionsLoader::update(const IOV& req_iov, + RangeConditions& conditions, + IOV& conditions_validity) +{ + pair<RangeConditions*,IOV*> arg(&conditions,&conditions_validity); + pair<ConditionsListener*,void*> call(this,&arg); + map<string,Condition::Object*> urls; + DDDBReaderContext local; + + local.event_time = req_iov.keyData.first; + local.valid_since = 0; + local.valid_until = 0; + m_mgr->callOnRegister(call,true); + + XML::UriContextReader local_reader(m_resolver, &local); + /// First collect all required URIs + for(RangeConditions::const_iterator i=conditions.begin(); i!=conditions.end(); ++i) { + Condition::Object* c = (*i).ptr(); + size_t idx = c->address.find('#'); + string url = (idx == string::npos) ? c->address : c->address.substr(0,idx); + printout(INFO,"DDDB","++ Need to update: %-40s [%08X] --> %s", + (c->value+"/"+c->name).c_str(), c->hash, url.c_str()); + urls.insert(make_pair(url,c)); + } + /// Now load them. In the callbacks we can check if we got all required conditions + for(map<string,Condition::Object*>::const_iterator j=urls.begin(); j!=urls.end(); ++j) { + const string& sys_id = (*j).first; + const string& obj_path = (*j).second->value; + const void* argv_conddb[] = {&local_reader, sys_id.c_str(), obj_path.c_str(), 0}; + long result = load_dddb_conditions_from_uri(m_lcdd, 3, (char**)argv_conddb); + if ( 0 == result ) { + except("DDDB","++ Failed to load conditions from URI:%s",sys_id.c_str()); + } + const void* argv_dddb[] = {"conditions_only", 0}; + result = dddb_conditions_2_dd4hep(m_lcdd, 1, (char**)argv_dddb); + if ( 0 == result ) { + except("DDDB","++ Failed to process conditions from URI:%s",sys_id.c_str()); + } + } + m_mgr->callOnRegister(call,false); + + return 0; +} diff --git a/DDDB/src/DDDBConditionsUpdate.cpp b/DDDB/src/DDDBConditionsUpdate.cpp new file mode 100644 index 000000000..c6be64536 --- /dev/null +++ b/DDDB/src/DDDBConditionsUpdate.cpp @@ -0,0 +1,38 @@ +// 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/Printout.h" +#include "DD4hep/DetFactoryHelper.h" +#include "DDCond/ConditionsInterna.h" + +using namespace DD4hep; +using namespace DD4hep::Conditions; + +/// Plugin entry point. +static long update_dddb_conditions(lcdd_t& /* lcdd */, int argc, char** argv) { + if ( argc > 0 ) { + time_t evt_time = *(long*)argv[0]; + char c_evt[64]; + struct tm evt; + ::gmtime_r(&evt_time, &evt); + ::strftime(c_evt,sizeof(c_evt),"%T %F",&evt); + printout(INFO,"DDDB","+++ ConditionsUpdate: Updating DDDB conditions... event time:%s", c_evt); + return 1; + } + except("DDDB","+++ Failed update DDDB conditions. No event time argument given!"); + return 0; +} +DECLARE_APPLY(DDDBConditionsUpdate,update_dddb_conditions) diff --git a/DDDB/src/DDDBConversion.cpp b/DDDB/src/DDDBConversion.cpp index 934d6c71a..fc0a21c9a 100644 --- a/DDDB/src/DDDBConversion.cpp +++ b/DDDB/src/DDDBConversion.cpp @@ -64,10 +64,66 @@ namespace DD4hep { releaseObjects(placements)(); releaseObjects(placementPaths)(); - releaseObjects(conditions)(); + conditions.clear(); + conditionPaths.clear(); + //releaseObjects(conditions)(); + //releaseObjects(conditionPaths)(); releaseObjects(catalogs)(); releaseObjects(catalogPaths)(); - printout(INFO,"dddb","++ All intermediate objects deleted!"); + releaseObjects(documents)(); + printout(DEBUG,"dddb","++ All intermediate objects deleted!"); + InstanceCount::decrement(this); + } + + /// Default constructor + DDDB::Named::Named() + : name(), id(), document(0), refCount(0) + { + } + + /// Initializing constructor + DDDB::Named::Named(const std::string& c) + : name(c), id(), document(0), refCount(0) + { + } + + /// Copy constructor + DDDB::Named::Named(const Named& c) + : name(c.name), id(c.id), document(c.document), refCount(0) + { + if ( document ) document->addRef(); + } + + /// Default destructor + DDDB::Named::~Named() { + if ( document ) document->release(); + } + + /// Assignment operator + DDDB::Named& DDDB::Named::operator=(const Named& c) { + if ( this != &c ) { + setDocument(c.document); + name = c.name; + id = c.id; + } + return *this; + } + + /// Assign document + void DDDB::Named::setDocument(Document* doc) { + if ( doc ) doc->addRef(); + if ( document ) document->release(); + document = doc; + } + + /// Default constructor + DDDB::Document::Document() : Named(), context() { + InstanceCount::increment(this); + } + + /// Default destructor + DDDB::Document::~Document() { + //printout(INFO,"Document","Delete doc %s",c_id()); InstanceCount::decrement(this); } @@ -136,16 +192,6 @@ namespace DD4hep { InstanceCount::decrement(this); } - /// Default constructor - DDDB::Condition::Condition() : Named() { - InstanceCount::increment(this); - } - - /// Default destructor - DDDB::Condition::~Condition() { - InstanceCount::decrement(this); - } - /// Default constructor DDDB::Shape::Shape() : type(0), zplanes(), boolean_ops() { ::memset(&s.box,0,sizeof(s)); @@ -321,18 +367,27 @@ namespace DD4hep { printout(INFO,"Detector", "++ %-12s name:%s id:%s", "",obj->c_name(),obj->c_id()); } - template <> void dddb_print(const DDDB::Condition* obj) { - stringstream p; + template <> void dddb_print(const DDDB::Document* obj) { CHECK_OBJECT(obj); - - p << "Par [" << obj->params.size() << "]: "; - for(auto i=obj->params.begin(); i != obj->params.end(); ++i) - p << (*i).first << "[" << (*i).second->type << "] "; - p << "Vec [" << obj->paramVectors.size() << "]: "; - for(auto i=obj->paramVectors.begin(); i != obj->paramVectors.end(); ++i) - p << (*i).first << "[" << (*i).second->type << "] "; - printout(INFO,"Condition", "++ %-12s: [%s] id:%s path:%s", - obj->name.c_str(), obj->classID.c_str(), obj->c_id(), obj->path.c_str()); - printout(INFO,"Condition", " --> %s",p.str().c_str()); + char c_since[64], c_until[64], c_evt[64]; + struct tm since, until, evt; + time_t t_evt = obj->context.event_time; + time_t t_since = obj->context.valid_since; + time_t t_until = obj->context.valid_until; + + ::gmtime_r(&t_evt,&evt); + ::gmtime_r(&t_since,&since); + ::gmtime_r(&t_until,&until); + ::strftime(c_evt,sizeof(c_evt),"%T %F",&evt); + ::strftime(c_since,sizeof(c_since),"%T %F",&since); + ::strftime(c_until,sizeof(c_until),"%T %F",&until); +#if 0 + printout(INFO,"Document", "++ %8ld [%8ld - %8ld] %s", + long(double(obj->context.event_time)/1e9), + long(double(obj->context.valid_since)/1e9), + long(double(obj->context.valid_until)/1e9), + obj->c_id()); +#endif + printout(INFO,"Document", "++ %s [%s - %s] %s",c_evt,c_since,c_until,obj->c_id()); } } diff --git a/DDDB/src/Dimension.cpp b/DDDB/src/DDDBDimension.cpp similarity index 99% rename from DDDB/src/Dimension.cpp rename to DDDB/src/DDDBDimension.cpp index 525a4ed4c..efb3365a1 100644 --- a/DDDB/src/Dimension.cpp +++ b/DDDB/src/DDDBDimension.cpp @@ -20,7 +20,7 @@ // Framework includes #include "XML/XMLDimension.inl" -#include "DDDB/Dimension.h" +#include "DDDB/DDDBDimension.h" #include "DDDB/DDDBTags.h" using namespace DD4hep::XML; diff --git a/DDDB/src/DDDBFileReader.cpp b/DDDB/src/DDDBFileReader.cpp index 5b6c5c8ab..f0c97c427 100644 --- a/DDDB/src/DDDBFileReader.cpp +++ b/DDDB/src/DDDBFileReader.cpp @@ -41,44 +41,52 @@ using namespace std; using namespace DD4hep; using namespace DD4hep::DDDB; +int DDDBFileReader::getObject(const string& system_id, + UserContext* /* ctxt */, + string& buffer) +{ + string path = m_directory+system_id; + struct stat buff; + if ( 0 == ::stat(path.c_str(), &buff) ) { + int fid = ::open(path.c_str(), O_RDONLY); + int done = 0, len = buff.st_size; + char* b = new char[len+1]; + b[0] = 0; + while ( done<len ) { + int sc = ::read(fid, b+done, buff.st_size-done); + if ( sc >= 0 ) { done += sc; continue; } + break; + } + ::close(fid); + b[done] = 0; + buffer = b; + delete [] b; + if ( done>=len ) return 1; + } + return 0; +} + /// Resolve a given URI to a string containing the data -bool DDDBFileReader::load(const string& system_id, string& buffer) { +bool DDDBFileReader::load(const string& system_id, + UserContext* ctxt, + string& buffer) +{ if ( system_id.substr(0,m_match.length()) == m_match ) { string mm = m_match + "//"; const string& sys = system_id; string id = sys.c_str() + (sys.substr(0,mm.length()) == mm ? 9 : 7); // Extract the COOL field name from the condition path // "conddb:/path/to/field@folder" - string data_field_name = "data"; // default value string::size_type at_pos = id.find('@'); if ( at_pos != id.npos ) { string::size_type slash_pos = id.rfind('/',at_pos); - if ( slash_pos+1 < at_pos ) { // item name is not null - data_field_name = id.substr(slash_pos+1,at_pos - (slash_pos +1)); - } // if I have "/@", I should use the default ("data") // always remove '@' from the path id = id.substr(0,slash_pos+1) + id.substr(at_pos+1); } - - string path = m_directory+id; - struct stat buff; - if ( 0 == ::stat(path.c_str(), &buff) ) { - int fid = ::open(path.c_str(), O_RDONLY); - int done = 0, len = buff.st_size; - char* b = new char[len+1]; - b[0] = 0; - while ( done<len ) { - int sc = ::read(fid, b+done, buff.st_size-done); - if ( sc >= 0 ) { done += sc; continue; } - break; - } - ::close(fid); - b[done] = 0; - buffer = b; - delete [] b; - if ( done>=len ) return true; - } - printout(ERROR,"DDDBFileReader","++ Fialed to resolve system id: %s [%s]", + // GET: 1458055061070516000 /lhcb.xml 0 0 SUCCESS + int ret = getObject(id, ctxt, buffer); + if ( ret == 1 ) return true; + printout(ERROR,"DDDBFileReader","++ Failed to resolve system id: %s [%s]", id.c_str(), ::strerror(errno)); } return false; diff --git a/DDDB/src/DDDBHelper.cpp b/DDDB/src/DDDBHelper.cpp index cb203c059..0dfe8bc1f 100644 --- a/DDDB/src/DDDBHelper.cpp +++ b/DDDB/src/DDDBHelper.cpp @@ -37,20 +37,20 @@ namespace { /// Standard constructor DDDBHelper::DDDBHelper(Geometry::LCDD& l) - : m_lcdd(l), m_xmlReader(0), m_geometry(0) + : m_lcdd(l), m_xmlReader(0), m_detDesc(0) { } /// Default destructor DDDBHelper::~DDDBHelper() { - deletePtr(m_geometry); + deletePtr(m_detDesc); m_visAttrs.clear(); } -/// Attach geometry information -void DDDBHelper::setGeometry(dddb* geo) { - deletePtr(m_geometry); - m_geometry = geo; +/// Attach detectorDescription information +void DDDBHelper::setDetectorDescription(dddb* geo) { + deletePtr(m_detDesc); + m_detDesc = geo; } /// Access visualization attribute for a given volume by path diff --git a/DDDB/src/DDDBvis.cpp b/DDDB/src/DDDBvis.cpp index 158c62f64..5d727f690 100644 --- a/DDDB/src/DDDBvis.cpp +++ b/DDDB/src/DDDBvis.cpp @@ -20,7 +20,7 @@ // Framework includes #include "DDDB/DDDBTags.h" -#include "DDDB/Dimension.h" +#include "DDDB/DDDBDimension.h" #include "DDDB/DDDBHelper.h" // C/C++ include files -- GitLab