From 202bd291b163360ffd18818592710dc893f068b8 Mon Sep 17 00:00:00 2001 From: Markus Frank <markus.frank@cern.ch> Date: Thu, 11 Dec 2014 19:56:37 +0000 Subject: [PATCH] Allow for string constants in lcdd define section --- DDCore/include/DD4hep/BasicGrammar.h | 7 + DDCore/include/DD4hep/Callback.h | 133 +++++++++++++++--- DDCore/include/DD4hep/Dictionary.h | 7 + DDCore/include/DD4hep/GeoHandler.h | 2 +- DDCore/include/DD4hep/Handle.h | 19 ++- DDCore/include/DD4hep/Objects.h | 20 ++- DDCore/include/DD4hep/Plugins.h | 7 +- DDCore/include/DD4hep/Primitives.h | 27 ++-- DDCore/include/DD4hep/Readout.h | 2 +- DDCore/include/DD4hep/Segmentations.h | 2 +- DDCore/include/DD4hep/Shapes.h | 8 ++ DDCore/include/DD4hep/ToStream.h | 2 +- DDCore/include/DD4hep/VolumeManager.h | 2 +- .../include/DD4hep/objects/ObjectsInterna.h | 22 +++ DDCore/include/XML/Evaluator.h | 14 ++ DDCore/include/XML/XMLElements.h | 2 + DDCore/src/BasicGrammar.cpp | 17 +-- DDCore/src/Evaluator/Evaluator.cpp | 40 +++++- DDCore/src/GeometryTreeDump.h | 3 +- DDCore/src/Handle.cpp | 43 +++--- DDCore/src/ObjectExtensions.cpp | 25 ++-- DDCore/src/Objects.cpp | 18 ++- DDCore/src/ObjectsInterna.cpp | 14 ++ DDCore/src/Primitives.cpp | 33 ++--- DDCore/src/Shapes.cpp | 107 ++++++++++++++ DDCore/src/SimpleGDMLWriter.h | 4 +- DDCore/src/SurfaceInstaller.cpp | 34 +++-- DDCore/src/ToStream.cpp | 21 ++- DDCore/src/XML/DocumentHandler.cpp | 7 +- DDCore/src/XML/XMLElements.cpp | 43 +++++- DDCore/src/plugins/Compact2Objects.cpp | 15 +- DDCore/src/plugins/LCDDConverter.h | 6 +- DDCore/src/plugins/StandardPlugins.cpp | 3 + 33 files changed, 556 insertions(+), 153 deletions(-) diff --git a/DDCore/include/DD4hep/BasicGrammar.h b/DDCore/include/DD4hep/BasicGrammar.h index 0aae6ca5f..d52e1b6c7 100644 --- a/DDCore/include/DD4hep/BasicGrammar.h +++ b/DDCore/include/DD4hep/BasicGrammar.h @@ -18,6 +18,13 @@ namespace DD4hep { /// Base class describing string evaluation to C++ objects using boost::spirit /** + * Grammar object handle the boost::spirit conversion between strings and numeric + * values/objects. Numeric objects could be atomic (int, long, float, double, etc) + * or complex (vector<int>, vector<float>...). This way e.g. a vector<int> may + * be converted into a list<double>. The conversion though requires an intermediate + * string representation. For this reason the conversion mechanism is relatively + * slow and hence should not be used inside number-crunching algorithms. + * * \author M.Frank * \version 1.0 * \date 13.08.2013 diff --git a/DDCore/include/DD4hep/Callback.h b/DDCore/include/DD4hep/Callback.h index 2b1aa2765..9c383609d 100644 --- a/DDCore/include/DD4hep/Callback.h +++ b/DDCore/include/DD4hep/Callback.h @@ -22,6 +22,12 @@ namespace DD4hep { /// Definition of the generic callback structure for member functions /** + * The callback structure allows to wrap any member function with up to + * 3 arguments into an abstract objects, which could later be called + * using the argument list. The pointer to the hosting objects is stored + * in the callback object. The callback objects in this sense behaves + * very similar to a static function. + * * \author M.Frank * \date 01/03/2013 * \version 1.0 @@ -39,36 +45,43 @@ namespace DD4hep { void* par; func_t call; mfunc_t func; + /// Default constructor Callback() : par(0), call(0) { func.first = func.second = 0; } + /// Constructor with object initialization Callback(void* p) : par(p), call(0) { func.first = func.second = 0; } + /// Initializing constructor Callback(void* p, void* mf, func_t c) : par(p), call(c) { func = *(mfunc_t*) mf; } - + /// Check validity of the callback object operator bool() const { return (call && par && func.first); } + /// Execute the callback with the required number of user parameters unsigned long execute(const void* user_param[]) const { return (*this) ? call(par, &func, user_param) : 0; } - + /// Template cast function used internally by the wrapper for type conversion to the object's type template <typename T> static T* cast(void* p) { return (T*) p; - } + } + /// Template const cast function used internally by the wrapper for type conversion to the object's type template <typename T> static const T* c_cast(const void* p) { return (const T*) p; } /// Wrapper around a C++ member function pointer /** + * Generic wrapper around a object member function. + * * \author M.Frank * \date 01/03/2013 * \version 1.0 @@ -93,15 +106,16 @@ namespace DD4hep { return func.ptr; } }; - // - // Callback with no arguments - // + + /** Callback setup with no arguments */ + /// Callback setup function for Callbacks with member functions taking no arguments template <typename T> const Callback& _make(ulong (*fptr)(void* o, const void* f, const void* u[]), T pmf) { typename Wrapper<T>::Functor f(pmf); func = f.ptr; call = fptr; return *this; } + /// Callback setup function for Callbacks with member functions with explicit return type taking no arguments template <typename R, typename T> const Callback& make(R (T::*pmf)()) { typedef R (T::*pfunc_t)(); struct _Wrapper : public Wrapper<pfunc_t> { @@ -111,6 +125,7 @@ namespace DD4hep { }; return _make(_Wrapper::call, pmf); } + /// Callback setup function for Callbacks with const member functions with explicit return type taking no arguments template <typename R, typename T> const Callback& make(R (T::*pmf)() const) { typedef R (T::*pfunc_t)() const; struct _Wrapper : public Wrapper<pfunc_t> { @@ -120,6 +135,7 @@ namespace DD4hep { }; return _make(_Wrapper::call, pmf); } + /// Callback setup function for Callbacks with void member functions taking no arguments template <typename T> const Callback& make(void (T::*pmf)()) { typedef void (T::*pfunc_t)() const; struct _Wrapper : public Wrapper<pfunc_t> { @@ -130,6 +146,7 @@ namespace DD4hep { }; return _make(_Wrapper::call, pmf); } + /// Callback setup function for Callbacks with const void member functions taking no arguments template <typename T> const Callback& make(void (T::*pmf)() const) { typedef void (T::*pfunc_t)() const; struct _Wrapper : public Wrapper<pfunc_t> { @@ -140,9 +157,9 @@ namespace DD4hep { }; return _make(_Wrapper::call, pmf); } - // - // Callback with 1 argument - // + + /** Callbacks with 1 argument */ + /// Callback setup function for Callbacks with member functions with explicit return type taking 1 argument template <typename R, typename T, typename A> const Callback& make(R (T::*pmf)(A)) { typedef R (T::*pfunc_t)(A); struct _Wrapper : public Wrapper<pfunc_t> { @@ -152,6 +169,7 @@ namespace DD4hep { }; return _make(_Wrapper::call, pmf); } + /// Callback setup function for Callbacks with const member functions with explicit return type taking 1 argument template <typename R, typename T, typename A> const Callback& make(R (T::*pmf)(A) const) { typedef R (T::*pfunc_t)(A) const; struct _Wrapper : public Wrapper<pfunc_t> { @@ -161,6 +179,7 @@ namespace DD4hep { }; return _make(_Wrapper::call, pmf); } + /// Callback setup function for Callbacks with void member functions taking 1 argument template <typename T, typename A> const Callback& make(void (T::*pmf)(A)) { typedef void (T::*pfunc_t)(const A); struct _Wrapper : public Wrapper<pfunc_t> { @@ -171,6 +190,7 @@ namespace DD4hep { }; return _make(_Wrapper::call, pmf); } + /// Callback setup function for Callbacks with const void member functions taking 1 argument template <typename T, typename A> const Callback& make(void (T::*pmf)(A) const) { typedef void (T::*pfunc_t)(const A) const; struct _Wrapper : public Wrapper<pfunc_t> { @@ -181,9 +201,10 @@ namespace DD4hep { }; return _make(_Wrapper::call, pmf); } - // - // Callback with 2 arguments - // + + /** Callback with 2 arguments */ + + /// Callback setup function for Callbacks with member functions with explicit return type taking 2 arguments template <typename R, typename T, typename A0, typename A1> const Callback& make(R (T::*pmf)(A0, A1)) { typedef R (T::*pfunc_t)(A0, A1); typedef Wrapper<pfunc_t> _W; @@ -194,6 +215,7 @@ namespace DD4hep { }; return _make(_Wrapper::call, pmf); } + /// Callback setup function for Callbacks with const member functions with explicit return type taking 2 arguments template <typename R, typename T, typename A0, typename A1> const Callback& make(R (T::*pmf)(A0, A1) const) { typedef R (T::*pfunc_t)(A0, A1); typedef Wrapper<pfunc_t> _W; @@ -204,6 +226,7 @@ namespace DD4hep { }; return _make(_Wrapper::call, pmf); } + /// Callback setup function for Callbacks with const void member functions taking 2 arguments template <typename T, typename A0, typename A1> const Callback& make(void (T::*pmf)(A0, A1)) { typedef void (T::*pfunc_t)(A0, A1); typedef Wrapper<pfunc_t> _W; @@ -215,6 +238,7 @@ namespace DD4hep { }; return _make(_Wrapper::call, pmf); } + /// Callback setup function for Callbacks with const void member functions taking 2 arguments template <typename T, typename A0, typename A1> const Callback& make(void (T::*pmf)(A0, A1) const) { typedef void (T::*pfunc_t)(A0, A1); typedef Wrapper<pfunc_t> _W; @@ -226,9 +250,10 @@ namespace DD4hep { }; return _make(_Wrapper::call, pmf); } - // - // Callback with 3 arguments - // + + /** Callback setup for callbacks with 3 arguments */ + + /// Callback setup function for Callbacks with member functions with explicit return type taking 3 arguments template <typename R, typename T, typename A0, typename A1, typename A2> const Callback& make(R (T::*pmf)(A0, A1, A2)) { typedef R (T::*pfunc_t)(A0, A1, A2); typedef Wrapper<pfunc_t> _W; @@ -239,6 +264,7 @@ namespace DD4hep { }; return _make(_Wrapper::call, pmf); } + /// Callback setup function for Callbacks with const member functions with explicit return type taking 3 arguments template <typename R, typename T, typename A0, typename A1, typename A2> const Callback& make( R (T::*pmf)(A0, A1, A2) const) { typedef R (T::*pfunc_t)(A0, A1, A2); @@ -250,6 +276,7 @@ namespace DD4hep { }; return _make(_Wrapper::call, pmf); } + /// Callback setup function for Callbacks with const void member functions taking 3 arguments template <typename T, typename A0, typename A1, typename A2> const Callback& make(void (T::*pmf)(A0, A1, A2)) { typedef void (T::*pfunc_t)(A0, A1, A2); typedef Wrapper<pfunc_t> _W; @@ -261,6 +288,7 @@ namespace DD4hep { }; return _make(_Wrapper::call, pmf); } + /// Callback setup function for Callbacks with const void member functions taking 3 arguments template <typename T, typename A0, typename A1, typename A2> const Callback& make(void (T::*pmf)(A0, A1, A2) const) { typedef void (T::*pfunc_t)(A0, A1, A2); typedef Wrapper<pfunc_t> _W; @@ -294,9 +322,13 @@ namespace DD4hep { /// Definition of an actor on sequences of callbacks /** - * @author M.Frank - * @date 01/03/2013 - * @version 0.1 + * A callback sequence is a set of callbacks with identical signature, so that + * the can be called consecutively using the same arguments. + * + * \author M.Frank + * \date 01/03/2013 + * \version 0.1 + * \ingroup DD4HEP */ struct CallbackSequence { typedef std::vector<Callback> Callbacks; @@ -321,9 +353,11 @@ namespace DD4hep { bool empty() const { return callbacks.empty(); } + /// Clear the sequence and remove all callbacks void clear() { callbacks.clear(); } + /// Generically Add a new callback to the sequence depending on the location arguments void add(const Callback& cb,Location where) { if ( where == CallbackSequence::FRONT ) callbacks.insert(callbacks.begin(),cb); @@ -341,21 +375,84 @@ namespace DD4hep { /// Check the compatibility of two typed objects. The test is the result of a dynamic_cast static void checkTypes(const std::type_info& typ1, const std::type_info& typ2, void* test); + /** Callback setup for callbacks with no arguments */ + /// Add a new callback to a member function with explicit return type and no arguments template <typename TYPE, typename R, typename OBJECT> void add(TYPE* pointer, R (OBJECT::*pmf)(),Location where=CallbackSequence::END) { checkTypes(typeid(TYPE), typeid(OBJECT), dynamic_cast<OBJECT*>(pointer)); add(Callback(pointer).make(pmf),where); } + /// Add a new callback to a const member function with explicit return type and no arguments + template <typename TYPE, typename R, typename OBJECT> + void add(TYPE* pointer, R (OBJECT::*pmf)() const,Location where=CallbackSequence::END) { + checkTypes(typeid(TYPE), typeid(OBJECT), dynamic_cast<OBJECT*>(pointer)); + add(Callback(pointer).make(pmf),where); + } + /// Add a new callback to a void member function with no arguments + template <typename TYPE, typename OBJECT> + void add(TYPE* pointer, void (OBJECT::*pmf)(),Location where=CallbackSequence::END) { + checkTypes(typeid(TYPE), typeid(OBJECT), dynamic_cast<OBJECT*>(pointer)); + add(Callback(pointer).make(pmf),where); + } + /// Add a new callback to a const void member function and no arguments + template <typename TYPE, typename OBJECT> + void add(TYPE* pointer, void (OBJECT::*pmf)() const,Location where=CallbackSequence::END) { + checkTypes(typeid(TYPE), typeid(OBJECT), dynamic_cast<OBJECT*>(pointer)); + add(Callback(pointer).make(pmf),where); + } + + /** Callback setup for callbacks with 1 argument */ + /// Add a new callback to a member function with explicit return type and 1 argument template <typename TYPE, typename R, typename OBJECT, typename A> void add(TYPE* pointer, R (OBJECT::*pmf)(A),Location where=CallbackSequence::END) { checkTypes(typeid(TYPE), typeid(OBJECT), dynamic_cast<OBJECT*>(pointer)); add(Callback(pointer).make(pmf),where); } + /// Add a new callback to a void member function and 1 argument + template <typename TYPE, typename OBJECT, typename A> + void add(TYPE* pointer, void (OBJECT::*pmf)(A),Location where=CallbackSequence::END) { + checkTypes(typeid(TYPE), typeid(OBJECT), dynamic_cast<OBJECT*>(pointer)); + add(Callback(pointer).make(pmf),where); + } + /// Add a new callback to a const member function with explicit return type and 1 argument + template <typename TYPE, typename R, typename OBJECT, typename A> + void add(TYPE* pointer, R (OBJECT::*pmf)(A) const,Location where=CallbackSequence::END) { + checkTypes(typeid(TYPE), typeid(OBJECT), dynamic_cast<OBJECT*>(pointer)); + add(Callback(pointer).make(pmf),where); + } + /// Add a new callback to a const void member function and 1 argument + template <typename TYPE, typename OBJECT, typename A> + void add(TYPE* pointer, void (OBJECT::*pmf)(A) const,Location where=CallbackSequence::END) { + checkTypes(typeid(TYPE), typeid(OBJECT), dynamic_cast<OBJECT*>(pointer)); + add(Callback(pointer).make(pmf),where); + } + + + /** Callback setup for callbacks with 2 arguments */ + /// Add a new callback to a member function with explicit return type and 2 arguments template <typename TYPE, typename R, typename OBJECT, typename A1, typename A2> void add(TYPE* pointer, R (OBJECT::*pmf)(A1, A2),Location where=CallbackSequence::END) { checkTypes(typeid(TYPE), typeid(OBJECT), dynamic_cast<OBJECT*>(pointer)); add(Callback(pointer).make(pmf),where); } + /// Add a new callback to a const member function with explicit return type and 2 arguments + template <typename TYPE, typename R, typename OBJECT, typename A1, typename A2> + void add(TYPE* pointer, R (OBJECT::*pmf)(A1, A2) const,Location where=CallbackSequence::END) { + checkTypes(typeid(TYPE), typeid(OBJECT), dynamic_cast<OBJECT*>(pointer)); + add(Callback(pointer).make(pmf),where); + } + /// Add a new callback to a void member function with 2 arguments + template <typename TYPE, typename OBJECT, typename A1, typename A2> + void add(TYPE* pointer, void (OBJECT::*pmf)(A1, A2),Location where=CallbackSequence::END) { + checkTypes(typeid(TYPE), typeid(OBJECT), dynamic_cast<OBJECT*>(pointer)); + add(Callback(pointer).make(pmf),where); + } + /// Add a new callback to a const void member function with 2 arguments + template <typename TYPE, typename OBJECT, typename A1, typename A2> + void add(TYPE* pointer, void (OBJECT::*pmf)(A1, A2) const,Location where=CallbackSequence::END) { + checkTypes(typeid(TYPE), typeid(OBJECT), dynamic_cast<OBJECT*>(pointer)); + add(Callback(pointer).make(pmf),where); + } }; /// Execution overload for callbacks with no arguments diff --git a/DDCore/include/DD4hep/Dictionary.h b/DDCore/include/DD4hep/Dictionary.h index a5d85ac53..b87d76304 100644 --- a/DDCore/include/DD4hep/Dictionary.h +++ b/DDCore/include/DD4hep/Dictionary.h @@ -110,22 +110,29 @@ template class DD4hep::Geometry::Handle<TNamed>; // Objects.h #pragma link C++ class DD4hep::Geometry::Author+; #pragma link C++ class vector<DD4hep::Geometry::Author>+; + #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::Geometry::Constant+; +#pragma link C++ class DD4hep::Geometry::ConstantObject+; +#pragma link C++ class DD4hep::Geometry::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::Geometry::Material+; #pragma link C++ class vector<DD4hep::Geometry::Material>+; #pragma link C++ class DD4hep::Geometry::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::Geometry::AlignmentEntry+; #pragma link C++ class DD4hep::Geometry::Limit+; #pragma link C++ class set<DD4hep::Geometry::Limit>+; diff --git a/DDCore/include/DD4hep/GeoHandler.h b/DDCore/include/DD4hep/GeoHandler.h index db870c0f4..d930734ce 100644 --- a/DDCore/include/DD4hep/GeoHandler.h +++ b/DDCore/include/DD4hep/GeoHandler.h @@ -136,7 +136,7 @@ namespace DD4hep { * \version 1.0 * \ingroup DD4HEP_GEOMETRY */ - struct GeoScan { + class GeoScan { protected: /// Data holder GeoHandler::Data* m_data; diff --git a/DDCore/include/DD4hep/Handle.h b/DDCore/include/DD4hep/Handle.h index 579a8281c..a2354f142 100644 --- a/DDCore/include/DD4hep/Handle.h +++ b/DDCore/include/DD4hep/Handle.h @@ -143,8 +143,10 @@ namespace DD4hep { return left * _toDouble(right); } - /// Enter name value pair to the dictionary. \"valye\" must be a numerical expression, which is evaluated \ingroup DD4HEP_GEOMETRY + /// 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); long num_object_validations(); void increment_object_validations(); @@ -186,9 +188,13 @@ namespace DD4hep { */ 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; - /// Reference to the actual element. + + /// Single and only data member: Reference to the actual element. T* m_element; /// Defaulot constructor Handle() @@ -293,19 +299,22 @@ namespace DD4hep { releasePtr(h.m_element); } /// Functor to destroy handles and delete the cached object \ingroup DD4HEP_GEOMETRY - template <typename T> struct DestroyHandle { + 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> struct ReleaseHandle { + 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> struct DestroyHandles { + template <typename M> class DestroyHandles { + public: M& object; DestroyHandles(M& m) : object(m) { diff --git a/DDCore/include/DD4hep/Objects.h b/DDCore/include/DD4hep/Objects.h index 7ca2cc283..117d0c5ee 100644 --- a/DDCore/include/DD4hep/Objects.h +++ b/DDCore/include/DD4hep/Objects.h @@ -14,6 +14,7 @@ #include "DD4hep/Handle.h" #include "DD4hep/NamedObject.h" +// Forward declarations class TMap; class TGeoElement; class TGeoMaterial; @@ -23,6 +24,8 @@ class TGeoRotation; class TGeoTranslation; class TGeoPhysicalNode; class TGeoIdentity; + +// ROOT include files #include "TGeoPhysicalNode.h" #include "Math/Vector3D.h" #include "Math/Transform3D.h" @@ -57,13 +60,14 @@ namespace DD4hep { class IDDescriptor; class VisAttrObject; class HeaderObject; + class ConstantObject; class RegionObject; class LimitSetObject; /** Access to identity transformation */ TGeoIdentity* identityTransform(); - /// Handle class describing an author identity + /// Handle class describing an author entity /** * \author M.Frank * \version 1.0 @@ -176,27 +180,29 @@ namespace DD4hep { * \version 1.0 * \ingroup DD4HEP_GEOMETRY */ - class Constant: public Ref_t { + class Constant: public Handle<ConstantObject> { public: /// Definition of the implementation type - typedef NamedObject Object; + typedef ConstantObject Object; /// Default constructor Constant() - : Ref_t() { + : Handle<ConstantObject> () { } /// Constructorto be used for assignment from a handle Constant(const Constant& e) - : Ref_t(e) { + : Handle<ConstantObject> (e) { } /// Constructor to be used when reading the already parsed DOM tree template <typename Q> Constant(const Handle<Q>& e) - : Ref_t(e) { + : Handle<ConstantObject> (e) { } /// Constructor to be used when creating a new DOM tree Constant(const std::string& name); /// Constructor to be used when creating a new DOM tree - Constant(const std::string& name, const std::string& val); + Constant(const std::string& name, const std::string& val, const std::string& typ="number"); + /// Access the constant + std::string type() const; /// String representation of this object std::string toString() const; }; diff --git a/DDCore/include/DD4hep/Plugins.h b/DDCore/include/DD4hep/Plugins.h index 54df4f337..72dd8bf20 100644 --- a/DDCore/include/DD4hep/Plugins.h +++ b/DDCore/include/DD4hep/Plugins.h @@ -16,6 +16,7 @@ /// Namespace for the AIDA detector description toolkit namespace DD4hep { + // Forward declarations typedef ROOT::Reflex::PluginService PluginService; /// Helper to debug plugin manager calls @@ -38,7 +39,7 @@ namespace DD4hep { std::string missingFactory(const std::string& name) const; }; -} /* End namespace DD4hep */ -#endif +} /* End namespace DD4hep */ -#endif /* DD4HEP_PLUGINS_H */ +#endif /* __CINT__ */ +#endif /* DD4HEP_PLUGINS_H */ diff --git a/DDCore/include/DD4hep/Primitives.h b/DDCore/include/DD4hep/Primitives.h index ecebfac5a..1dbc74efc 100644 --- a/DDCore/include/DD4hep/Primitives.h +++ b/DDCore/include/DD4hep/Primitives.h @@ -143,14 +143,16 @@ namespace DD4hep { deletePtr(p); } /// Functor to delete objects from heap and reset the pointer - template <typename T> struct DestroyObject { + template <typename T> class DestroyObject { + public: void operator()(T& p) const { destroyObject(p); } }; /// Operator to select second element of a pair - template <typename T> struct Select2nd { + template <typename T> class Select2nd { + public: typedef T arg_t; typedef typename T::second_type result_t; /// Operator function @@ -161,7 +163,8 @@ namespace DD4hep { { return Select2nd<typename T::value_type>(); } /// Operator to select the first element of a pair - template <typename T> struct Select1st { + template <typename T> class Select1st { + public: typedef T arg_t; typedef typename T::first_type result_t; /// Operator function @@ -173,7 +176,8 @@ namespace DD4hep { /// map Functor to delete objects from heap - template <typename M> struct DestroyObjects { + template <typename M> class DestroyObjects { + public: M& object; DestroyObjects(M& m) : object(m) { @@ -196,7 +200,8 @@ namespace DD4hep { } /// map Functor to delete objects from heap - template <typename M> struct DestroyFirst { + template <typename M> class DestroyFirst { + public: M& object; DestroyFirst(M& m) : object(m) { @@ -226,13 +231,15 @@ namespace DD4hep { } /// Functor to release objects from heap and reset the pointer - template <typename T> struct ReleaseObject { + template <typename T> class ReleaseObject { + public: void operator()(T& p) const { releasePtr(p); } }; /// Map Functor to release objects from heap - template <typename M> struct ReleaseObjects { + template <typename M> class ReleaseObjects { + public: M& object; ReleaseObjects(M& m) : object(m) { @@ -258,7 +265,8 @@ namespace DD4hep { } /// Functor to delete objects from heap and reset the pointer - template <typename T> struct ReferenceObject { + template <typename T> class ReferenceObject { + public: typedef T arg_t; T operator()(T p) const { if ( p ) p->addRef(); @@ -266,7 +274,8 @@ namespace DD4hep { } }; /// Functor to delete objects from heap and reset the pointer - template <typename M> struct ReferenceObjects { + template <typename M> class ReferenceObjects { + public: typedef typename M::second_type result_t; result_t operator()(const M& p) const { return ReferenceObject<result_t>()(p.second); diff --git a/DDCore/include/DD4hep/Readout.h b/DDCore/include/DD4hep/Readout.h index bdd515c51..dc2f183fe 100644 --- a/DDCore/include/DD4hep/Readout.h +++ b/DDCore/include/DD4hep/Readout.h @@ -35,7 +35,7 @@ namespace DD4hep { * \version 1.0 * \ingroup DD4HEP_GEOMETRY */ - struct Readout: public Handle<ReadoutObject> { + class Readout: public Handle<ReadoutObject> { public: /// Implementation type typedef ReadoutObject Object; diff --git a/DDCore/include/DD4hep/Segmentations.h b/DDCore/include/DD4hep/Segmentations.h index db4b59946..361cc5516 100644 --- a/DDCore/include/DD4hep/Segmentations.h +++ b/DDCore/include/DD4hep/Segmentations.h @@ -82,7 +82,7 @@ namespace DD4hep { * \version 1.0 * \ingroup DD4HEP_GEOMETRY */ - struct Segmentation: public Handle<SegmentationObject> { + class Segmentation: public Handle<SegmentationObject> { public: typedef SegmentationObject Object; typedef DDSegmentation::Segmentation BaseSegmentation; diff --git a/DDCore/include/DD4hep/Shapes.h b/DDCore/include/DD4hep/Shapes.h index 7659b4e94..9192acf94 100644 --- a/DDCore/include/DD4hep/Shapes.h +++ b/DDCore/include/DD4hep/Shapes.h @@ -37,6 +37,9 @@ namespace DD4hep { // Forward declarations + /// Pretty print of solid attributes + std::string toStringSolid(const TGeoShape* shape, int precision=2); + /// Base class for Solid (shape) objects /** * Generic handle holding an object of base TGeoShape. @@ -89,6 +92,11 @@ namespace DD4hep { T* operator->() const { return this->m_element; } + + /// Conversion to string for pretty print + std::string toString(int precision=2) const { + return toStringSolid(this->m_element,precision); + } }; typedef Solid_type<TGeoShape> Solid; diff --git a/DDCore/include/DD4hep/ToStream.h b/DDCore/include/DD4hep/ToStream.h index d690f2875..a584152f5 100644 --- a/DDCore/include/DD4hep/ToStream.h +++ b/DDCore/include/DD4hep/ToStream.h @@ -22,7 +22,7 @@ #include "Math/Vector4D.h" // ============================================================================ -/** @file DD4hepKernel/ToStream.h +/** @file DD4hep/ToStream.h * implemenattiono fvarioud functions for streaming. * this functionality is essenital for usag eof varuodu types as property for * the various DD4hep components diff --git a/DDCore/include/DD4hep/VolumeManager.h b/DDCore/include/DD4hep/VolumeManager.h index a023fd51a..f5c643745 100644 --- a/DDCore/include/DD4hep/VolumeManager.h +++ b/DDCore/include/DD4hep/VolumeManager.h @@ -62,7 +62,7 @@ namespace DD4hep { * \version 1.0 * \ingroup DD4HEP_GEOMETRY */ - struct VolumeManager: public Handle<VolumeManagerObject> { + class VolumeManager: public Handle<VolumeManagerObject> { public: typedef DD4hep::VolumeID VolumeID; typedef VolumeID VolIdentifier; diff --git a/DDCore/include/DD4hep/objects/ObjectsInterna.h b/DDCore/include/DD4hep/objects/ObjectsInterna.h index 28667566e..2b57bea93 100644 --- a/DDCore/include/DD4hep/objects/ObjectsInterna.h +++ b/DDCore/include/DD4hep/objects/ObjectsInterna.h @@ -52,6 +52,28 @@ namespace DD4hep { HeaderObject& operator=(const HeaderObject&) { return *this; } }; + /// Concrete object implementation for the Constant handle + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_GEOMETRY + */ + class ConstantObject: public NamedObject { + public: + /// Constant type + std::string m_type; + /// Standard constructor + ConstantObject(const std::string& nam, const std::string& val, const std::string& typ); + /// Default destructor + virtual ~ConstantObject(); + private: + /// Private copy constructor + ConstantObject(const ConstantObject&) : NamedObject() {} + /// Private assignment operator + ConstantObject& operator=(const ConstantObject&) { return *this; } + }; + /// Concrete object implementation of the VisAttr Handle /** * diff --git a/DDCore/include/XML/Evaluator.h b/DDCore/include/XML/Evaluator.h index cd24242bd..8260759c0 100644 --- a/DDCore/include/XML/Evaluator.h +++ b/DDCore/include/XML/Evaluator.h @@ -91,6 +91,20 @@ namespace XmlTools { */ void print_error() const; + /** + * Adds to the dictionary a string constant + * + * @param name name of the variable. + * @param value value assigned to the variable. + */ + void setEnviron(const char* name, const char* value); + /** + * Lookup the dictionary for a string constant + * + * @param name name of the variable. + * @param value value assigned to the variable. + */ + const char* getEnviron(const char* name); /** * Adds to the dictionary a variable with given value. * If a variable with such a name already exist in the dictionary, diff --git a/DDCore/include/XML/XMLElements.h b/DDCore/include/XML/XMLElements.h index 3ac19a1da..34693e07d 100644 --- a/DDCore/include/XML/XMLElements.h +++ b/DDCore/include/XML/XMLElements.h @@ -124,6 +124,8 @@ namespace DD4hep { void _toDictionary(const XmlChar* name, float value); /// Helper function to populate the evaluator dictionary \ingroup DD4HEP_XML void _toDictionary(const XmlChar* name, double value); + /// Helper function to lookup environment from the expression evaluator + std::string getEnviron(const std::string& env); /// Conversion function from raw unicode string to bool \ingroup DD4HEP_XML bool _toBool(const XmlChar* value); diff --git a/DDCore/src/BasicGrammar.cpp b/DDCore/src/BasicGrammar.cpp index 2e481dd7b..1ba3a9cec 100644 --- a/DDCore/src/BasicGrammar.cpp +++ b/DDCore/src/BasicGrammar.cpp @@ -15,28 +15,25 @@ // C/C++ include files #include <stdexcept> -using namespace std; -using namespace DD4hep; - /// Default constructor -BasicGrammar::BasicGrammar() { +DD4hep::BasicGrammar::BasicGrammar() { } /// Default destructor -BasicGrammar::~BasicGrammar() { +DD4hep::BasicGrammar::~BasicGrammar() { } /// Error callback on invalid conversion -void BasicGrammar::invalidConversion(const string& value, const type_info& to) { - string to_name = typeName(to); +void DD4hep::BasicGrammar::invalidConversion(const std::string& value, const std::type_info& to) { + std::string to_name = typeName(to); throw unrelated_value_error(to, "The Property data conversion of '" + value + "' to type " + to_name + " is not defined."); } /// Error callback on invalid conversion -void BasicGrammar::invalidConversion(const type_info& from, const type_info& to) { - string to_name = typeName(to); - string from_name = typeName(from); +void DD4hep::BasicGrammar::invalidConversion(const std::type_info& from, const std::type_info& to) { + std::string to_name = typeName(to); + std::string from_name = typeName(from); throw unrelated_type_error(from, to, "The Property data conversion from type " + from_name + " to " + to_name + " is not implemented."); } diff --git a/DDCore/src/Evaluator/Evaluator.cpp b/DDCore/src/Evaluator/Evaluator.cpp index 34fc22f0a..6b4cbf29e 100644 --- a/DDCore/src/Evaluator/Evaluator.cpp +++ b/DDCore/src/Evaluator/Evaluator.cpp @@ -16,7 +16,7 @@ //--------------------------------------------------------------------------- struct Item { - enum { UNKNOWN, VARIABLE, EXPRESSION, FUNCTION } what; + enum { UNKNOWN, VARIABLE, EXPRESSION, FUNCTION, STRING } what; double variable; string expression; void *function; @@ -665,6 +665,44 @@ void Evaluator::print_error() const { } } +//--------------------------------------------------------------------------- +void Evaluator::setEnviron(const char* name, const char* value) { + Struct* s = (Struct *)p; + string prefix = "${"; + string item_name = prefix + string(name) + string("}"); + dic_type::iterator iter = (s->theDictionary).find(item_name); + Item item; + item.what = Item::STRING; + item.expression = value; + item.function = 0; + item.variable = 0; + //std::cout << " ++++++++++++++++++++++++++++ Saving env:" << name << " = " << value << std::endl; + if (iter != (s->theDictionary).end()) { + iter->second = item; + if (item_name == name) { + s->theStatus = EVAL::WARNING_EXISTING_VARIABLE; + }else{ + s->theStatus = EVAL::WARNING_EXISTING_FUNCTION; + } + }else{ + (s->theDictionary)[item_name] = item; + s->theStatus = EVAL::OK; + } +} +//--------------------------------------------------------------------------- +const char* Evaluator::getEnviron(const char* name) { + Struct* s = (Struct *)p; + string item_name = name; + //std::cout << " ++++++++++++++++++++++++++++ Try to resolve env:" << name << std::endl; + dic_type::iterator iter = (s->theDictionary).find(item_name); + if (iter == (s->theDictionary).end()) { + s->theStatus = EVAL::ERROR_UNKNOWN_VARIABLE; + return 0; + } + s->theStatus = EVAL::OK; + return iter->second.expression.c_str(); +} + //--------------------------------------------------------------------------- void Evaluator::setVariable(const char * name, double value) { setItem("", name, Item(value), (Struct *)p); } diff --git a/DDCore/src/GeometryTreeDump.h b/DDCore/src/GeometryTreeDump.h index 399b4f0a6..e833949df 100644 --- a/DDCore/src/GeometryTreeDump.h +++ b/DDCore/src/GeometryTreeDump.h @@ -29,7 +29,8 @@ namespace DD4hep { * \version 1.0 * \ingroup DD4HEP_GEOMETRY */ - struct GeometryTreeDump: public GeoHandler { + class GeometryTreeDump: public GeoHandler { + public: GeometryTreeDump() { } /// Standard destructor diff --git a/DDCore/src/Handle.cpp b/DDCore/src/Handle.cpp index 1fc3ea21a..7b39fa7b7 100644 --- a/DDCore/src/Handle.cpp +++ b/DDCore/src/Handle.cpp @@ -64,7 +64,7 @@ long DD4hep::Geometry::_toLong(const string& value) { } bool DD4hep::Geometry::_toBool(const string& value) { - return value == "true"; + return value == "true" || value == "yes"; } float DD4hep::Geometry::_toFloat(const string& value) { @@ -104,22 +104,33 @@ template <> double DD4hep::Geometry::_multiply<double>(const string& left, const } void DD4hep::Geometry::_toDictionary(const string& name, const string& value) { - string n = name, v = value; - size_t idx = v.find("(int)"); - if (idx != string::npos) - v.erase(idx, 5); - idx = v.find("(float)"); - if (idx != string::npos) - v.erase(idx, 7); - while (v[0] == ' ') - v.erase(0, 1); - double result = eval.evaluate(v.c_str()); - if (eval.status() != XmlTools::Evaluator::OK) { - cerr << value << ": "; - eval.print_error(); - throw runtime_error("DD4hep: Severe error during expression evaluation " + name + "=" + 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) { + if ( typ == "string" ) { + eval.setEnviron(name.c_str(),value.c_str()); + return; + } + else { + string n = name, v = value; + size_t idx = v.find("(int)"); + if (idx != string::npos) + v.erase(idx, 5); + idx = v.find("(float)"); + if (idx != string::npos) + v.erase(idx, 7); + while (v[0] == ' ') + v.erase(0, 1); + double result = eval.evaluate(v.c_str()); + if (eval.status() != XmlTools::Evaluator::OK) { + cerr << value << ": "; + eval.print_error(); + throw runtime_error("DD4hep: Severe error during expression evaluation " + name + "=" + value); + } + eval.setVariable(n.c_str(), result); } - eval.setVariable(n.c_str(), result); } template <typename T> static inline string __to_string(T value, const char* fmt) { diff --git a/DDCore/src/ObjectExtensions.cpp b/DDCore/src/ObjectExtensions.cpp index ed2e187fc..0eefb3a88 100644 --- a/DDCore/src/ObjectExtensions.cpp +++ b/DDCore/src/ObjectExtensions.cpp @@ -15,19 +15,18 @@ // C/C++ include files #include <stdexcept> -using namespace std; using namespace DD4hep; namespace { static int s_extensionID = 0; - ObjectExtensions::ExtensionMap* extensionContainer(const type_info& typ) { - static map<const type_info*, ObjectExtensions::ExtensionMap> s_map; + ObjectExtensions::ExtensionMap* extensionContainer(const std::type_info& typ) { + static std::map<const std::type_info*, ObjectExtensions::ExtensionMap> s_map; return &s_map[&typ]; } } /// Default constructor -ObjectExtensions::ObjectExtensions(const type_info& parent_type) { +ObjectExtensions::ObjectExtensions(const std::type_info& parent_type) { extensionMap = extensionContainer(parent_type); InstanceCount::increment(this); } @@ -57,7 +56,7 @@ void ObjectExtensions::clear(bool destroy) { /// Copy object extensions from another object void ObjectExtensions::copyFrom(const Extensions& ext, void* arg) { for (Extensions::const_iterator i = ext.begin(); i != ext.end(); ++i) { - const type_info* info = (*i).first; + const std::type_info* info = (*i).first; ExtensionMap::const_iterator j = extensionMap->find(info); const Entry& e = (*j).second; extensions[info] = (*(e.copy))((*i).second, arg); @@ -65,12 +64,12 @@ void ObjectExtensions::copyFrom(const Extensions& ext, void* arg) { } /// Add an extension object to the detector element -void* ObjectExtensions::addExtension(void* ptr, const type_info& info, destruct_t dtor) { +void* ObjectExtensions::addExtension(void* ptr, const std::type_info& info, destruct_t dtor) { return addExtension(ptr, info, 0, dtor); } /// Add an extension object to the detector element -void* ObjectExtensions::addExtension(void* ptr, const type_info& info, copy_t ctor, destruct_t dtor) { +void* ObjectExtensions::addExtension(void* ptr, const std::type_info& info, copy_t ctor, destruct_t dtor) { Extensions::iterator j = extensions.find(&info); if (j == extensions.end()) { ExtensionMap::iterator i = extensionMap->find(&info); @@ -84,7 +83,7 @@ void* ObjectExtensions::addExtension(void* ptr, const type_info& info, copy_t ct } return extensions[&info] = ptr; } - throw runtime_error("DD4hep: addExtension: Object already has an extension of type:" + typeName(info) + "."); + throw std::runtime_error("DD4hep: addExtension: Object already has an extension of type:" + typeName(info) + "."); } /// Remove an existing extension object from the instance @@ -103,26 +102,26 @@ void* ObjectExtensions::removeExtension(const std::type_info& info, bool destroy extensions.erase(j); return ptr; } - throw runtime_error("DD4hep: removeExtension: The object of type " + typeName(info) + " is not present."); + throw std::runtime_error("DD4hep: removeExtension: The object of type " + typeName(info) + " is not present."); } /// Access an existing extension object from the detector element -void* ObjectExtensions::extension(const type_info& info) const { +void* ObjectExtensions::extension(const std::type_info& info) const { Extensions::const_iterator j = extensions.find(&info); if (j != extensions.end()) { return (*j).second; } - throw runtime_error("DD4hep: extension: Object has no extension of type:" + typeName(info) + "."); + throw std::runtime_error("DD4hep: extension: Object has no extension of type:" + typeName(info) + "."); } /// Access an existing extension object from the detector element -void* ObjectExtensions::extension(const type_info& info, bool alert) const { +void* ObjectExtensions::extension(const std::type_info& info, bool alert) const { Extensions::const_iterator j = extensions.find(&info); if (j != extensions.end()) { return (*j).second; } else if ( !alert ) return 0; - throw runtime_error("DD4hep: extension: Object has no extension of type:" + typeName(info) + "."); + throw std::runtime_error("DD4hep: extension: Object has no extension of type:" + typeName(info) + "."); } diff --git a/DDCore/src/Objects.cpp b/DDCore/src/Objects.cpp index 3e7bc4a1b..322660107 100644 --- a/DDCore/src/Objects.cpp +++ b/DDCore/src/Objects.cpp @@ -132,19 +132,29 @@ void Header::setComment(const std::string& new_comment) { } /// Constructor to be used when creating a new DOM tree -Constant::Constant(const string& nam, const string& val) { - m_element = new NamedObject(nam.c_str(), val.c_str()); +Constant::Constant(const string& nam, const string& val, const string& typ) { + m_element = new Object(nam, val, typ); } /// Constructor to be used when creating a new DOM tree Constant::Constant(const string& name) { - m_element = new NamedObject(name.c_str(), ""); + m_element = new Object(name.c_str(), "", "number"); +} + +/// Access the constant +string Constant::type() const { + if ( isValid() ) { + return m_element->type; + } + throw runtime_error("DD4hep: Attempt to access internals from invalid Constant handle!"); } /// String representation of this object string Constant::toString() const { stringstream os; - os << m_element->GetName() << " \"" << m_element->GetTitle() << "\" Value:" << _toDouble(m_element->GetTitle()); + os << m_element->GetName() << " \"" << m_element->GetTitle() << "\" "; + if ( m_element->m_type == "string" ) os << "Value:" << m_element->GetTitle(); + else os << "Value:" << _toDouble(m_element->GetTitle()); return os.str(); } diff --git a/DDCore/src/ObjectsInterna.cpp b/DDCore/src/ObjectsInterna.cpp index 3c10d405b..68b0d2057 100644 --- a/DDCore/src/ObjectsInterna.cpp +++ b/DDCore/src/ObjectsInterna.cpp @@ -41,6 +41,20 @@ HeaderObject::~HeaderObject() { InstanceCount::decrement(this); } +DD4HEP_INSTANTIATE_HANDLE_NAMED(ConstantObject); + +/// Standard constructor +ConstantObject::ConstantObject(const string& nam, const string& val, const string& typ) + : NamedObject(nam.c_str(), val.c_str()) { + m_type = typ; + InstanceCount::increment(this); +} + +/// Default destructor +ConstantObject::~ConstantObject() { + InstanceCount::decrement(this); +} + DD4HEP_INSTANTIATE_HANDLE_NAMED(RegionObject); /// Standard constructor diff --git a/DDCore/src/Primitives.cpp b/DDCore/src/Primitives.cpp index 803c5f6c0..7ef516706 100644 --- a/DDCore/src/Primitives.cpp +++ b/DDCore/src/Primitives.cpp @@ -25,14 +25,11 @@ using abi::__dynamic_cast; #endif #endif -using namespace std; -using namespace DD4hep; - static const std::string __typeinfoName(const std::type_info& tinfo) { const char* class_name = tinfo.name(); std::string result; #ifdef WIN32 - size_t off = 0; + std::size_t off = 0; if ( ::strncmp(class_name, "class ", 6) == 0 ) { // The returned name is prefixed with "class " off = 6; @@ -135,7 +132,7 @@ static const std::string __typeinfoName(const std::type_info& tinfo) { } else { char buff[16 * 1024]; - size_t len = sizeof(buff); + std::size_t len = sizeof(buff); int status = 0; result = __cxxabiv1::__cxa_demangle(class_name, buff, &len, &status); } @@ -146,27 +143,27 @@ static const std::string __typeinfoName(const std::type_info& tinfo) { return result; } -string DD4hep::typeName(const type_info& typ) { +std::string DD4hep::typeName(const std::type_info& typ) { return __typeinfoName(typ); } -void DD4hep::invalidHandleError(const type_info& type) { - throw runtime_error("Attempt to access invalid object of type "+typeName(type)+" [Invalid Handle]"); +void DD4hep::invalidHandleError(const std::type_info& type) { + throw std::runtime_error("Attempt to access invalid object of type "+typeName(type)+" [Invalid Handle]"); } -void DD4hep::invalidHandleAssignmentError(const type_info& from, const type_info& to) { - string msg = "Wrong assingment from "; +void DD4hep::invalidHandleAssignmentError(const std::type_info& from, const std::type_info& to) { + std::string msg = "Wrong assingment from "; msg += typeName(from); msg += " to "; msg += typeName(to); msg += " not possible!!"; - throw runtime_error(msg); + throw std::runtime_error(msg); } /// Throw exception when handles are check for validity void DD4hep::notImplemented(const std::string& msg) { - string m = "The requested feature " + msg + " is not implemented!"; - throw runtime_error(m); + 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) { @@ -176,7 +173,7 @@ void DD4hep::typeinfoCheck(const std::type_info& typ1, const std::type_info& typ } /// Initializing Constructor -ComponentCast::ComponentCast(const std::type_info& t, destroy_t d, cast_t c) +DD4hep::ComponentCast::ComponentCast(const std::type_info& t, destroy_t d, cast_t c) : type(t), destroy(d), cast(c) { #ifdef __APPLE__ abi_class = 0; @@ -189,7 +186,7 @@ ComponentCast::ComponentCast(const std::type_info& t, destroy_t d, cast_t c) } /// Defautl destructor -ComponentCast::~ComponentCast() { +DD4hep::ComponentCast::~ComponentCast() { } #if 0 @@ -218,7 +215,7 @@ static inline void* cast_wrap(const void* p, #endif /// Apply cast using typeinfo instead of dynamic_cast -void* ComponentCast::apply_dynCast(const ComponentCast& to, const void* ptr) const { +void* DD4hep::ComponentCast::apply_dynCast(const ComponentCast& to, const void* ptr) const { if (&to == this) { return (void*) ptr; } @@ -256,7 +253,7 @@ void* ComponentCast::apply_dynCast(const ComponentCast& to, const void* ptr) con } /// Apply cast using typeinfo instead of dynamic_cast -void* ComponentCast::apply_upCast(const ComponentCast& to, const void* ptr) const { +void* DD4hep::ComponentCast::apply_upCast(const ComponentCast& to, const void* ptr) const { if (&to == this) { return (void*) ptr; } @@ -264,7 +261,7 @@ void* ComponentCast::apply_upCast(const ComponentCast& to, const void* ptr) cons } /// Apply cast using typeinfo instead of dynamic_cast -void* ComponentCast::apply_downCast(const ComponentCast& to, const void* ptr) const { +void* DD4hep::ComponentCast::apply_downCast(const ComponentCast& to, const void* ptr) const { if (&to == this) { return (void*) ptr; } diff --git a/DDCore/src/Shapes.cpp b/DDCore/src/Shapes.cpp index 6f3613c88..8e480c79d 100644 --- a/DDCore/src/Shapes.cpp +++ b/DDCore/src/Shapes.cpp @@ -15,7 +15,9 @@ #include <stdexcept> // ROOT includes +#include "TClass.h" #include "TGeoShape.h" +#include "TGeoHype.h" #include "TGeoPcon.h" #include "TGeoPgon.h" #include "TGeoTube.h" @@ -33,6 +35,111 @@ using namespace std; using namespace DD4hep::Geometry; +/// Pretty print of solid attributes +std::string DD4hep::Geometry::toStringSolid(const TGeoShape* shape, int precision) { + stringstream log; + + if ( !shape ) { + return "[Invalid shape]"; + } + + TClass* cl = shape->IsA(); + int prec = log.precision(); + log.setf(ios::fixed,ios::floatfield); + log << setprecision(precision); + log << cl->GetName(); + if ( cl == TGeoBBox::Class() ) { + TGeoBBox* s = (TGeoBBox*) shape; + log << " x:" << s->GetDX() + << " y:" << s->GetDY() + << " z:" << s->GetDZ(); + } + else if (cl == TGeoTube::Class()) { + const TGeoTube* s = (const TGeoTube*) shape; + log << " rmin:" << s->GetRmin() << " rmax:" << s->GetRmax() << " dz:" << s->GetDz(); + } + else if (cl == TGeoTubeSeg::Class()) { + const TGeoTubeSeg* s = (const TGeoTubeSeg*) shape; + log << " rmin:" << s->GetRmin() << " rmax:" << s->GetRmax() << " dz:" << s->GetDz() + << " Phi1:" << s->GetPhi1() << " Phi2:" << s->GetPhi2(); + } + else if (cl == TGeoTrd1::Class()) { + const TGeoTrd1* s = (const TGeoTrd1*) shape; + log << " x1:" << s->GetDx1() << " x2:" << s->GetDx2() << " y:" << s->GetDy() << " z:" << s->GetDz(); + } + else if (cl == TGeoTrd2::Class()) { + const TGeoTrd2* s = (const TGeoTrd2*) shape; + log << " x1:" << s->GetDx1() << " x2:" << s->GetDx2() + << " y1:" << s->GetDy1() << " y2:" << s->GetDy2() << " z:" << s->GetDz(); + } + else if (cl == TGeoHype::Class()) { + const TGeoHype* s = (const TGeoHype*) shape; + log << " rmin:" << s->GetRmin() << " rmax:" << s->GetRmax() << " dz:" << s->GetDz() + << " StIn:" << s->GetStIn() << " StOut:" << s->GetStOut(); + } + else if (cl == TGeoPgon::Class()) { + const TGeoPgon* s = (const TGeoPgon*) shape; + log << " Phi1:" << s->GetPhi1() << " dPhi:" << s->GetDphi() + << " NEdges:" << s->GetNedges() << " Nz:" << s->GetNz(); + for(int i=0, n=s->GetNz(); i<n; ++i) { + log << " i=" << i << " z:" << s->GetZ(i) + << " r:[" << s->GetRmin(i) << "," << s->GetRmax(i) << "]"; + } + } + else if (cl == TGeoPcon::Class()) { + const TGeoPcon* s = (const TGeoPcon*) shape; + log << " Phi1:" << s->GetPhi1() << " dPhi:" << s->GetDphi() << " Nz:" << s->GetNz(); + for(int i=0, n=s->GetNz(); i<n; ++i) { + log << " i=" << i << " z:" << s->GetZ(i) + << " r:[" << s->GetRmin(i) << "," << s->GetRmax(i) << "]"; + } + } + else if (cl == TGeoConeSeg::Class()) { + const TGeoConeSeg* s = (const TGeoConeSeg*) shape; + log << " rmin1:" << s->GetRmin1() << " rmax1:" << s->GetRmax1() + << " rmin2:" << s->GetRmin2() << " rmax2:" << s->GetRmax2() + << " dz:" << s->GetDz() + << " Phi1:" << s->GetPhi1() << " Phi2:" << s->GetPhi2(); + } + else if (cl == TGeoParaboloid::Class()) { + const TGeoParaboloid* s = (const TGeoParaboloid*) shape; + log << " dz:" << s->GetDz() << " RLo:" << s->GetRlo() << " Rhi:" << s->GetRhi(); + } + else if (cl == TGeoSphere::Class()) { + const TGeoSphere* s = (const TGeoSphere*) shape; + log << " rmin:" << s->GetRmin() << " rmax:" << s->GetRmax() + << " Phi1:" << s->GetPhi1() << " Phi2:" << s->GetPhi2() + << " Theta1:" << s->GetTheta1() << " Theta2:" << s->GetTheta2(); + } + else if (cl == TGeoTorus::Class()) { + const TGeoTorus* s = (const TGeoTorus*) shape; + log << " rmin:" << s->GetRmin() << " rmax:" << s->GetRmax() << " r:" << s->GetR() + << " Phi1:" << s->GetPhi1() << " dPhi:" << s->GetDphi(); + } + else if (cl == TGeoTrap::Class()) { + const TGeoTrap* s = (const TGeoTrap*) shape; + log << " dz:" << s->GetDz() << " Theta:" << s->GetTheta() << " Phi:" << s->GetPhi() + << " H1:" << s->GetH1() << " Bl1:" << s->GetBl1() << " Tl1:" << s->GetTl1() << " Alpha1:" << s->GetAlpha1() + << " H2:" << s->GetH2() << " Bl2:" << s->GetBl2() << " Tl2:" << s->GetTl2() << " Alpha2:" << s->GetAlpha2(); + } + else if (shape->IsA() == TGeoCompositeShape::Class()) { + const TGeoCompositeShape* s = (const TGeoCompositeShape*) shape; + const TGeoBoolNode* boolean = s->GetBoolNode(); + const TGeoShape* left = boolean->GetLeftShape(); + const TGeoShape* right = boolean->GetRightShape(); + TGeoBoolNode::EGeoBoolType oper = boolean->GetBooleanOperator(); + if (oper == TGeoBoolNode::kGeoSubtraction) + log << "Subtraction: "; + else if (oper == TGeoBoolNode::kGeoUnion) + log << "Union: "; + else if (oper == TGeoBoolNode::kGeoIntersection) + log << "Intersection: "; + log << " Left:" << toStringSolid(left) << " Right:" << toStringSolid(right); + } + log << setprecision(prec); + return log.str(); +} + template <typename T> void Solid_type<T>::_setDimensions(double* param) { this->ptr()->SetDimensions(param); this->ptr()->ComputeBBox(); diff --git a/DDCore/src/SimpleGDMLWriter.h b/DDCore/src/SimpleGDMLWriter.h index 27816abb1..10106331e 100644 --- a/DDCore/src/SimpleGDMLWriter.h +++ b/DDCore/src/SimpleGDMLWriter.h @@ -29,8 +29,8 @@ namespace DD4hep { * \version 1.0 * \ingroup DD4HEP_GEOMETRY */ - struct SimpleGDMLWriter: public GeoHandler { - + class SimpleGDMLWriter: public GeoHandler { + public: /// Reference to output stream std::ostream& m_output; diff --git a/DDCore/src/SurfaceInstaller.cpp b/DDCore/src/SurfaceInstaller.cpp index 29de01640..bc13fbb10 100644 --- a/DDCore/src/SurfaceInstaller.cpp +++ b/DDCore/src/SurfaceInstaller.cpp @@ -6,11 +6,13 @@ // Author : M.Frank // //==================================================================== +#include "DD4hep/Shapes.h" #include "DD4hep/Printout.h" #include "DD4hep/SurfaceInstaller.h" // C/C++ include files #include <stdexcept> +// ROOT includes #include "TClass.h" using namespace std; @@ -79,26 +81,30 @@ void SurfaceInstaller::install(DetElement component, PlacedVolume pv) { printout(INFO,m_det.name(),log.str()); log.str(""); log << " " << " Matrices[" << all_nodes.size() << "]: "; - log << pv->GetVolume()->GetShape()->IsA()->GetName() << " "; for(PlacementPath::const_reverse_iterator i=all_nodes.rbegin(); i!=all_nodes.rend(); ++i) { - log << (void*)((*i)->GetMatrix()) << " "; - if ( i+1 == all_nodes.rend() ) log << "( -> " << (*i)->GetName() << ")"; + PlacedVolume placed = *i; + log << (void*)(placed->GetMatrix()) << " "; + if ( placed->GetUserExtension() ) { + const PlacedVolume::VolIDs& vid = placed.volIDs(); + for(PlacedVolume::VolIDs::const_iterator j=vid.begin(); j!=vid.end(); ++j) { + log << (*j).first << ":" << (*j).second << " "; + } + } + log << " "; + if ( i+1 == all_nodes.rend() ) log << "( -> " << placed->GetName() << ")"; } // Get the module element: - TClass* cl = pv->GetVolume()->GetShape()->IsA(); printout(INFO,m_det.name(),log.str()); log.str(""); + Volume vol = pv.volume(); log << " " - << " Sensitive:" << (pv.volume().isSensitive() ? "YES" : "NO ") - << " Shape: " << cl->GetName(); - TGeoBBox* box = (TGeoBBox*)pv.volume()->GetShape(); - if ( cl == TGeoBBox::Class() ) { - log << " [" << (void*)box << "]" - << " x:" << box->GetDX() - << " y:" << box->GetDY() - << " z:" << box->GetDZ(); - } + << " Sensitive: " << (vol.isSensitive() ? "YES" : "NO ") + << " Volume: " << (void*)vol.ptr() << " " + << " Shape: " << vol.solid().toString(); + printout(INFO,m_det.name(),log.str()); + return; } + cout << component.name() << ": " << pv.name() << endl; } /// Scan through tree of volume placements @@ -114,5 +120,3 @@ void SurfaceInstaller::scan() { scan(m_det); } -typedef DD4hep::SurfaceInstaller TestSurfacesPlugin; -DECLARE_SURFACE_INSTALLER(TestSurfaces,TestSurfacesPlugin) diff --git a/DDCore/src/ToStream.cpp b/DDCore/src/ToStream.cpp index 99dbdfd3f..a48fa7495 100644 --- a/DDCore/src/ToStream.cpp +++ b/DDCore/src/ToStream.cpp @@ -21,28 +21,27 @@ namespace { XmlTools::Evaluator& eval(DD4hep::g4Evaluator()); } -using namespace std; //============================================================================== namespace DD4hep { namespace Parsers { - template <typename T> T evaluate_string(const string& /* value */) { + template <typename T> T evaluate_string(const std::string& /* value */) { throw "Bad undefined call"; } - template <> double evaluate_string<double>(const string& value) { + template <> double evaluate_string<double>(const std::string& value) { double result = eval.evaluate(value.c_str()); if (eval.status() != XmlTools::Evaluator::OK) { - cerr << value << ": "; + std::cerr << value << ": "; eval.print_error(); - throw runtime_error("DD4hep::Properties: Severe error during expression evaluation of " + value); + throw std::runtime_error("DD4hep::Properties: Severe error during expression evaluation of " + value); } return result; } - template <> float evaluate_string<float>(const string& value) { + template <> float evaluate_string<float>(const std::string& value) { double result = eval.evaluate(value.c_str()); if (eval.status() != XmlTools::Evaluator::OK) { - cerr << value << ": "; + std::cerr << value << ": "; eval.print_error(); - throw runtime_error("DD4hep::Properties: Severe error during expression evaluation of " + value); + throw std::runtime_error("DD4hep::Properties: Severe error during expression evaluation of " + value); } return (float) result; } @@ -51,7 +50,7 @@ namespace DD4hep { namespace Parsers { // ============================================================================ // print XYZ-point -ostream& DD4hep::Utils::toStream(const ROOT::Math::XYZPoint& obj, ostream& s) { +std::ostream& DD4hep::Utils::toStream(const ROOT::Math::XYZPoint& obj, std::ostream& s) { s << "( "; toStream(obj.X () , s ); s << " , "; @@ -63,7 +62,7 @@ ostream& DD4hep::Utils::toStream(const ROOT::Math::XYZPoint& obj, ostream& s) } // ============================================================================ // print XYZ-vector -ostream& DD4hep::Utils::toStream(const ROOT::Math::XYZVector& obj, ostream& s) { +std::ostream& DD4hep::Utils::toStream(const ROOT::Math::XYZVector& obj, std::ostream& s) { s << "( "; toStream(obj.X () , s ); s << " , "; @@ -75,7 +74,7 @@ ostream& DD4hep::Utils::toStream(const ROOT::Math::XYZVector& obj, ostream& s) } // ============================================================================ // print LorentzVector -ostream& DD4hep::Utils::toStream(const ROOT::Math::PxPyPzEVector& obj, ostream& s){ +std::ostream& DD4hep::Utils::toStream(const ROOT::Math::PxPyPzEVector& obj, std::ostream& s){ s << "( "; toStream(obj.Px () , s , 12 ); s << " , "; diff --git a/DDCore/src/XML/DocumentHandler.cpp b/DDCore/src/XML/DocumentHandler.cpp index 83b7a0152..59e91bede 100644 --- a/DDCore/src/XML/DocumentHandler.cpp +++ b/DDCore/src/XML/DocumentHandler.cpp @@ -167,7 +167,8 @@ DocumentHandler::~DocumentHandler() { static string uri(Handle_t base, const XMLCh* fname) { xercesc::DOMElement* e = (xercesc::DOMElement*) base.ptr(); xercesc::XMLURL base_url(e->getBaseURI()); - xercesc::XMLURL ref_url(base_url, fname); + string bbb = _toString(fname); + xercesc::XMLURL ref_url(base_url, Strng_t(bbb)); return _toString(ref_url.getURLText()); } @@ -176,7 +177,7 @@ Document DocumentHandler::load(Handle_t base, const XMLCh* fname) const { return load(path); } -Document DocumentHandler::load(const string& fname) const { +Document DocumentHandler::load(const std::string& fname) const { printout(DEBUG,"DocumentHandler","+++ Loading document URI: %s",fname.c_str()); XMLURL xerurl = (const XMLCh*) Strng_t(fname); string path = _toString(xerurl.getPath()); @@ -307,7 +308,7 @@ Document DocumentHandler::load(Handle_t base, const XmlChar* fname) const { return load(fname); } -Document DocumentHandler::load(const string& fname) const { +Document DocumentHandler::load(const std::string& fname) const { printout(INFO,"DocumentHandler","+++ Loading document URI: %s",fname.c_str()); TiXmlDocument* doc = new TiXmlDocument(_clean_fname(fname).c_str()); bool result = false; diff --git a/DDCore/src/XML/XMLElements.cpp b/DDCore/src/XML/XMLElements.cpp index 681d3ba3b..00d9da8ef 100644 --- a/DDCore/src/XML/XMLElements.cpp +++ b/DDCore/src/XML/XMLElements.cpp @@ -29,6 +29,10 @@ namespace DD4hep { // Static storage namespace { XmlTools::Evaluator& eval(DD4hep::evaluator()); + string _checkEnviron(const string& env) { + string r = getEnviron(env); + return r.empty() ? env : r; + } } // Shortcuts @@ -81,8 +85,8 @@ namespace { } } XmlChar* DD4hep::XML::XmlString::replicate(const XmlChar* c) {return c ? ::strdup(c) : 0;} -XmlChar* DD4hep::XML::XmlString::transcode(const char* c) {return c ? ::strdup(c) : 0;} -void DD4hep::XML::XmlString::release(char** p) {if(p && *p) {::free(*p); *p=0;}} +XmlChar* DD4hep::XML::XmlString::transcode(const char* c) {return c ? ::strdup(c) : 0;} +void DD4hep::XML::XmlString::release(char** p) {if(p && *p) {::free(*p); *p=0;}} #else #include "xercesc/util/XMLString.hpp" @@ -156,10 +160,14 @@ namespace { return 0; } } + string DD4hep::XML::_toString(const XmlChar *toTranscode) { char *buff = XmlString::transcode(toTranscode); string tmp(buff == 0 ? "" : buff); XmlString::release(&buff); + if ( tmp.length()<3 ) return tmp; + if ( !(tmp[0] == '$' && tmp[1] == '{') ) return tmp; + tmp = _checkEnviron(tmp); return tmp; } #endif @@ -191,12 +199,16 @@ template <typename T> static inline string __to_string(T value, const char* fmt) /// Do-nothing version. Present for completeness and argument interchangeability std::string DD4hep::XML::_toString(const char* s) { - return string(s ? s : ""); + if ( !s || *s == 0 ) return ""; + else if ( !(*s == '$' && *(s+1) == '{') ) return s; + return _checkEnviron(s); } /// Do-nothing version. Present for completeness and argument interchangeability std::string DD4hep::XML::_toString(const std::string& s) { - return s; + if ( s.length() < 3 || s[0] != '$' ) return s; + else if ( !(s[0] == '$' && s[1] == '{') ) return s; + return _checkEnviron(s); } /// Format unsigned long integer to string with atrbitrary format @@ -312,6 +324,7 @@ void DD4hep::XML::_toDictionary(const XmlChar* name, T value) { const XmlChar* item_value = item; _toDictionary(name, item_value); } + #ifndef DD4HEP_USE_TINYXML template void DD4hep::XML::_toDictionary(const XmlChar* name, const char* value); #endif @@ -325,6 +338,28 @@ template void DD4hep::XML::_toDictionary(const XmlChar* name, short value); template void DD4hep::XML::_toDictionary(const XmlChar* name, float value); template void DD4hep::XML::_toDictionary(const XmlChar* name, double value); +/// Evaluate string constant using environment stored in the evaluator +string DD4hep::XML::getEnviron(const string& env) { + size_t id1 = env.find("${"); + size_t id2 = env.rfind("}"); + if ( id1 == string::npos || id2 == string::npos ) { + return ""; + } + else { + string v = env.substr(0,id2+1); + const char* ret = eval.getEnviron(v.c_str()); + if (eval.status() != XmlTools::Evaluator::OK) { + cerr << env << ": "; + eval.print_error(); + throw runtime_error("DD4hep: Severe error during environment lookup of " + env); + } + v = env.substr(0,id1); + v += ret; + v += env.substr(id2+1); + return v; + } +} + template <typename B> static inline string i_add(const string& a, B b) { string r = a; diff --git a/DDCore/src/plugins/Compact2Objects.cpp b/DDCore/src/plugins/Compact2Objects.cpp index 86e467395..95e63a2df 100644 --- a/DDCore/src/plugins/Compact2Objects.cpp +++ b/DDCore/src/plugins/Compact2Objects.cpp @@ -247,10 +247,12 @@ template <> void Converter<Plugin>::operator()(xml_h e) const { */ template <> void Converter<Constant>::operator()(xml_h e) const { xml_ref_t constant(e); - NamedObject* obj = new NamedObject(constant.attr < string > (_U(name)).c_str(), constant.attr < string > (_U(value)).c_str()); - Ref_t cons(obj); - _toDictionary(obj->GetName(), obj->GetTitle()); - lcdd.addConstant(cons); + string nam = constant.attr < string > (_U(name)); + string val = constant.attr < string > (_U(value)); + string typ = constant.hasAttr(_U(type)) ? constant.attr<string>(_U(type)) : "number"; + Constant c(nam, val, typ); + _toDictionary(nam, val, typ); + lcdd.addConstant(c); } /** Convert compact constant objects (defines) * @@ -864,13 +866,14 @@ template <> void Converter<Compact>::operator()(xml_h element) const { ++num_calls; xml_elt_t compact(element); + + xml_coll_t(compact, _U(define)).for_each(_U(include), Converter < DetElementInclude > (lcdd)); + xml_coll_t(compact, _U(define)).for_each(_U(constant), Converter < Constant > (lcdd)); xml_coll_t(compact, _U(includes)).for_each(_U(gdmlFile), Converter < GdmlFile > (lcdd)); if (element.hasChild(_U(info))) (Converter < Header > (lcdd))(xml_h(compact.child(_U(info)))); - xml_coll_t(compact, _U(define)).for_each(_U(include), Converter < DetElementInclude > (lcdd)); - xml_coll_t(compact, _U(define)).for_each(_U(constant), Converter < Constant > (lcdd)); xml_coll_t(compact, _U(materials)).for_each(_U(element), Converter < Atom > (lcdd)); xml_coll_t(compact, _U(materials)).for_each(_U(material), Converter < Material > (lcdd)); xml_coll_t(compact, _U(properties)).for_each(_U(attributes), Converter < Property > (lcdd)); diff --git a/DDCore/src/plugins/LCDDConverter.h b/DDCore/src/plugins/LCDDConverter.h index 6976b4726..fdf96d5ce 100644 --- a/DDCore/src/plugins/LCDDConverter.h +++ b/DDCore/src/plugins/LCDDConverter.h @@ -42,7 +42,8 @@ namespace DD4hep { * \version 1.0 * \ingroup DD4HEP_GEOMETRY */ - struct LCDDConverter: public GeoHandler { + class LCDDConverter: public GeoHandler { + public: typedef XML::XmlElement XmlElement; typedef std::map<Atom, XmlElement*> ElementMap; typedef std::map<Material, XmlElement*> MaterialMap; @@ -62,7 +63,8 @@ namespace DD4hep { * \version 1.0 * \ingroup DD4HEP_GEOMETRY */ - struct GeometryInfo: public GeoHandler::GeometryInfo { + class GeometryInfo: public GeoHandler::GeometryInfo { + public: ElementMap xmlElements; MaterialMap xmlMaterials; SolidMap xmlSolids; diff --git a/DDCore/src/plugins/StandardPlugins.cpp b/DDCore/src/plugins/StandardPlugins.cpp index 940650a81..8217c9c9e 100644 --- a/DDCore/src/plugins/StandardPlugins.cpp +++ b/DDCore/src/plugins/StandardPlugins.cpp @@ -259,3 +259,6 @@ static long exec_SimpleGDMLWriter(LCDD& lcdd, int argc, char** argv) { DECLARE_APPLY(DD4hepSimpleGDMLWriter,exec_SimpleGDMLWriter) +#include "DD4hep/SurfaceInstaller.h" +typedef SurfaceInstaller TestSurfacesPlugin; +DECLARE_SURFACE_INSTALLER(TestSurfaces,TestSurfacesPlugin) -- GitLab