diff --git a/DDCore/include/DD4hep/Detector.h b/DDCore/include/DD4hep/Detector.h index 16fffc5bc37cc13edfe63d2be8b9f19beeaeb1bf..95a57da98c7ef68879d09a300e42e9b73606c313 100644 --- a/DDCore/include/DD4hep/Detector.h +++ b/DDCore/include/DD4hep/Detector.h @@ -26,6 +26,7 @@ #include "DD4hep/NamedObject.h" #include "DD4hep/Segmentations.h" #include "DD4hep/VolumeManager.h" +#include "DD4hep/OpticalSurfaceManager.h" #include "DD4hep/ExtensionEntry.h" #include "DD4hep/BuildType.h" @@ -124,6 +125,9 @@ namespace dd4hep { /// Return handle to the VolumeManager virtual VolumeManager volumeManager() const = 0; + /// Access the optical surface manager + virtual OpticalSurfaceManager surfaceManager() const = 0; + /// Accessor to the map of header entries virtual Header header() const = 0; /// Accessor to the header entry @@ -269,7 +273,7 @@ namespace dd4hep { virtual Detector& addDetector(const Handle<NamedObject>& detector) = 0; /// Add a field component by named reference to the detector description virtual Detector& addField(const Handle<NamedObject>& field) = 0; - + /// Deprecated call (use fromXML): Read compact geometry description or alignment file virtual void fromCompact(const std::string& fname, DetectorBuildType type = BUILD_DEFAULT) = 0; /// Read any geometry description or alignment file diff --git a/DDCore/include/DD4hep/OpticalSurfaceManager.h b/DDCore/include/DD4hep/OpticalSurfaceManager.h new file mode 100644 index 0000000000000000000000000000000000000000..ddb4c316feb3b996a1f4be99e1aee47d2a9ca88d --- /dev/null +++ b/DDCore/include/DD4hep/OpticalSurfaceManager.h @@ -0,0 +1,72 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +#ifndef DD4HEP_DDCORE_OPTICALSURFACEMANAGER_H +#define DD4HEP_DDCORE_OPTICALSURFACEMANAGER_H + +// Framework include files +#include "DD4hep/OpticalSurfaces.h" + +// ROOT include files +#include "TGeoManager.h" + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Class to support the handling of optical surfaces. + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CORE + */ + class OpticalSurfaceManager: public Handle<TGeoManager> { + public: + typedef TGeoManager Object; + + public: + /// Default constructor + OpticalSurfaceManager() = default; + /// Copy constructor + OpticalSurfaceManager(const OpticalSurfaceManager& e) = default; + /// Constructor taking object pointer + OpticalSurfaceManager(TGeoManager* obj) : Handle<Object>(obj) { } + /// Constructor from same-type handle + OpticalSurfaceManager(const Handle<Object>& e) : Handle<Object>(e) { } + /// Constructor from arbitrary handle + template <typename Q> + OpticalSurfaceManager(const Handle<Q>& e) : Handle<Object>(e) { } + /// Initializing constructor. + OpticalSurfaceManager(Detector& description); + /// Assignment operator + OpticalSurfaceManager& operator=(const OpticalSurfaceManager& m) = default; + + /// static accessor calling DD4hepOpticalSurfaceManagerPlugin if necessary + static OpticalSurfaceManager getOpticalSurfaceManager(Detector& description); + +#if ROOT_VERSION_CODE > ROOT_VERSION(6,16,0) + /// Access skin surface by its identifier + SkinSurface getSkinSurface(DetElement de, const std::string& nam) const; + /// Access border surface by its identifier + BorderSurface getBorderSurface(DetElement de, const std::string& nam) const; + /// Access optical surface data by its identifier + OpticalSurface getSurface(DetElement de, const std::string& nam) const; + /// Add skin surface to manager + void addSkinSurface(SkinSurface surf) const; + /// Add border surface to manager + void addBorderSurface(BorderSurface surf) const; + /// Add optical surface data to manager + void addSurface(OpticalSurface surf) const; +#endif + }; +} /* End namespace dd4hep */ +#endif /* DD4HEP_DDCORE_OPTICALSURFACEMANAGER_H */ diff --git a/DDCore/include/DD4hep/OpticalSurfaces.h b/DDCore/include/DD4hep/OpticalSurfaces.h new file mode 100644 index 0000000000000000000000000000000000000000..556fb2406d942fed649d977be5a58ca0829f4499 --- /dev/null +++ b/DDCore/include/DD4hep/OpticalSurfaces.h @@ -0,0 +1,143 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +#ifndef DD4HEP_DDCORE_OPTICALSURFACES_H +#define DD4HEP_DDCORE_OPTICALSURFACES_H + +// Framework include files +#include "DD4hep/Volumes.h" +#include "DD4hep/DetElement.h" + +#if ROOT_VERSION_CODE > ROOT_VERSION(6,16,0) + +// ROOT include files +#include "TGeoOpticalSurface.h" + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Class to support the handling of optical surfaces. + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CORE + */ + class OpticalSurface : public Handle<TGeoOpticalSurface> { + public: + typedef TGeoOpticalSurface Object; + typedef Object Finish; + typedef Object Model; + typedef Object Type; + typedef Object::ESurfaceModel EModel; + typedef Object::ESurfaceFinish EFinish; + typedef Object::ESurfaceType EType; + + public: + /// Default constructor + OpticalSurface() = default; + /// Copy constructor + OpticalSurface(const OpticalSurface& e) = default; + /// Constructor taking object pointer + OpticalSurface(Object* obj) : Handle<Object>(obj) { } + /// Constructor from same-type handle + OpticalSurface(const Handle<Object>& e) : Handle<Object>(e) { } + /// Constructor from arbitrary handle + template <typename Q> + OpticalSurface(const Handle<Q>& e) : Handle<Object>(e) { } + /// Initializing constructor. + OpticalSurface(Detector& description, + const std::string& name, + EModel model = Model::kMglisur, + EFinish finish = Finish::kFpolished, + EType type = Type::kTdielectric_dielectric, + double value = 1.0); + + /// Assignment operator + OpticalSurface& operator=(const OpticalSurface& m) = default; + }; + + /// Class to support the handling of optical surfaces. + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CORE + */ + class SkinSurface : public Handle<TGeoSkinSurface> { + public: + typedef TGeoSkinSurface Object; + + public: + /// Default constructor + SkinSurface() = default; + /// Copy constructor + SkinSurface(const SkinSurface& e) = default; + /// Constructor taking object pointer + SkinSurface(Object* obj) : Handle<Object>(obj) { } + /// Constructor from same-type handle + SkinSurface(const Handle<Object>& e) : Handle<Object>(e) { } + /// Constructor from arbitrary handle + template <typename Q> + SkinSurface(const Handle<Q>& e) : Handle<Object>(e) { } + /// Initializing constructor. + SkinSurface(DetElement de, const std::string& nam, OpticalSurface surf, Volume vol); + + /// Assignment operator + SkinSurface& operator=(const SkinSurface& m) = default; + + /// Access surface data + OpticalSurface surface() const; + /// Access the node of the skin surface + Volume volume() const; + }; + + /// Class to support the handling of optical surfaces. + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CORE + */ + class BorderSurface : public Handle<TGeoBorderSurface> { + public: + typedef TGeoBorderSurface Object; + + public: + /// Default constructor + BorderSurface() = default; + /// Copy constructor + BorderSurface(const BorderSurface& e) = default; + /// Constructor taking object pointer + BorderSurface(Object* obj) : Handle<Object>(obj) { } + /// Constructor from same-type handle + BorderSurface(const Handle<Object>& e) : Handle<Object>(e) { } + /// Constructor from arbitrary handle + template <typename Q> + BorderSurface(const Handle<Q>& e) : Handle<Object>(e) { } + /// Initializing constructor: Creates the object and registers it to the manager + BorderSurface(DetElement de, const std::string& nam, OpticalSurface surf, PlacedVolume left, PlacedVolume right); + + /// Assignment operator + BorderSurface& operator=(const BorderSurface& m) = default; + /// Access surface data + OpticalSurface surface() const; + /// Access the left node of the border surface + PlacedVolume left() const; + /// Access the right node of the border surface + PlacedVolume right() const; + }; + + +} /* End namespace dd4hep */ +#endif /* ROOT_VERSION */ +#endif /* DD4HEP_DDCORE_OPTICALSURFACES_H */ diff --git a/DDCore/include/DD4hep/PropertyTable.h b/DDCore/include/DD4hep/PropertyTable.h new file mode 100644 index 0000000000000000000000000000000000000000..06f00209c5ca0bcf29af149ea5ca51c3d3923aa7 --- /dev/null +++ b/DDCore/include/DD4hep/PropertyTable.h @@ -0,0 +1,64 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +#ifndef DD4HEP_DDCORE_PROPERTYTABLE_H +#define DD4HEP_DDCORE_PROPERTYTABLE_H + +#include "RVersion.h" +#if ROOT_VERSION_CODE > ROOT_VERSION(6,16,0) + +// Framework include files +#include "DD4hep/Handle.h" + +// ROOT include files +#include "TGDMLMatrix.h" + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Class to support the handling of optical surfaces. + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CORE + */ + class PropertyTable : public Handle<TGDMLMatrix> { + public: + typedef TGDMLMatrix Object; + + public: + /// Default constructor + PropertyTable() = default; + /// Copy constructor + PropertyTable(const PropertyTable& e) = default; + /// Constructor from same-type handle + PropertyTable(const Handle<Object>& e) : Handle<Object>(e) { } + /// Constructor from arbitray handle + template <typename Q> + PropertyTable(const Handle<Q>& e) : Handle<Object>(e) { } + /// Initializing constructor using object pointer + PropertyTable(Object* obj) : Handle<Object>(obj) { } + /// Initializing constructor. + PropertyTable(Detector& description, + const std::string& table_name, + const std::string& property_name, + size_t num_rows, + size_t num_cols); + + /// Assignment operator + PropertyTable& operator=(const PropertyTable& m) = default; + }; + +} /* End namespace dd4hep */ +#endif /* ROOT_VERSION */ +#endif /* DD4HEP_DDCORE_PROPERTYTABLE_H */ diff --git a/DDCore/include/DD4hep/Volumes.h b/DDCore/include/DD4hep/Volumes.h index b5cd215235a7bd54d234c15d2a0064ed770394a9..9606331e2e60318f0b5d89581fb47f0dee0477a2 100644 --- a/DDCore/include/DD4hep/Volumes.h +++ b/DDCore/include/DD4hep/Volumes.h @@ -167,7 +167,7 @@ namespace dd4hep { PlacedVolume(const PlacedVolume& e) = default; /// Copy assignment from other handle type template <typename T> PlacedVolume(const Handle<T>& e) : Handle<TGeoNode>(e) { } - /// Constructor to be used when reading the already parsed DOM tree + /// Constructor taking implementation object pointer PlacedVolume(const TGeoNode* e) : Handle<TGeoNode>(e) { } /// Assignment operator (must match copy constructor) PlacedVolume& operator=(const PlacedVolume& v) = default; diff --git a/DDCore/include/XML/UnicodeValues.h b/DDCore/include/XML/UnicodeValues.h index b6affce1eb9eb3d1544a6e85869804b68f0b7aec..d6d022711b583a03b9e820d6ddf4ebe64c360226 100644 --- a/DDCore/include/XML/UnicodeValues.h +++ b/DDCore/include/XML/UnicodeValues.h @@ -56,6 +56,7 @@ UNICODE (barrel); UNICODE (barrel_envelope); UNICODE (beampipe); UNICODE (beta); +UNICODE (bordersurface); UNICODE (box); UNICODE (build); @@ -74,6 +75,7 @@ UNICODE (close_geometry); UNICODE (cm); UNICODE (coefficient); UNICODE (coefficients); +UNICODE (coldim); UNICODE (color); UNICODE (collection); UNICODE (collections); @@ -150,6 +152,7 @@ UNICODE (fields); UNICODE (field_name); UNICODE (file); UNICODE (files); +UNICODE (finish); UNICODE (first); UNICODE (firstposition); UNICODE (firstrotation); @@ -262,9 +265,12 @@ UNICODE (M); UNICODE (material); UNICODE (materialref); UNICODE (materials); +UNICODE (matrices); +UNICODE (matrix); UNICODE (member); UNICODE (MeV); UNICODE (mm); +UNICODE (model); UNICODE (module); UNICODE (modules); UNICODE (module_component); @@ -300,6 +306,7 @@ UNICODE (O); UNICODE (offset); UNICODE (open); UNICODE (operation); +UNICODE (opticalsurface); UNICODE (overlap); UNICODE (outer); UNICODE (outer_field); @@ -352,6 +359,7 @@ UNICODE (positionRPhiZ); UNICODE (pressure); UNICODE (projective_cylinder); UNICODE (projective_zplane); +UNICODE (property); UNICODE (properties); UNICODE (psi); @@ -424,6 +432,7 @@ UNICODE (showDaughters); UNICODE (size); UNICODE (signed); UNICODE (skew); +UNICODE (skinsurface); UNICODE (slice); UNICODE (slices); UNICODE (solid); @@ -452,6 +461,8 @@ UNICODE (strength); UNICODE (structure); UNICODE (subtraction); UNICODE (support); +UNICODE (surface); +UNICODE (surfaces); UNICODE (system); UNICODE (symbol); diff --git a/DDCore/include/XML/XMLElements.h b/DDCore/include/XML/XMLElements.h index c88a987dcfe0eaf94cd056a9b7086cb673e358b6..e8ed1587cb8630b9e6d1f8754837f04d5217a930 100644 --- a/DDCore/include/XML/XMLElements.h +++ b/DDCore/include/XML/XMLElements.h @@ -816,6 +816,10 @@ namespace dd4hep { return m_element.hasAttr(name); } /// Access attribute with implicit return type conversion + template <class T> T attr(const XmlAttr* att) const { + return m_element.attr<T>(att); + } + /// Access attribute with implicit return type conversion template <class T> T attr(const XmlChar* tag_value) const { return m_element.attr<T>(tag_value); } diff --git a/DDCore/src/DetectorImp.h b/DDCore/src/DetectorImp.h index 0a7a8f144e2c691f424d8d23443fe10f8c33645e..9d2dd46723de6355e5591f9126b25f4237549dfe 100644 --- a/DDCore/src/DetectorImp.h +++ b/DDCore/src/DetectorImp.h @@ -177,6 +177,11 @@ namespace dd4hep { virtual VolumeManager volumeManager() const override { return m_volManager; } + /// Access the optical surface manager + virtual OpticalSurfaceManager surfaceManager() const override { + return OpticalSurfaceManager(m_manager); + } + /// Return handle to the combined electromagentic field description. virtual OverlayedField field() const override { return m_field; diff --git a/DDCore/src/OpticalSurfaceManager.cpp b/DDCore/src/OpticalSurfaceManager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3473c16456a88e9c5f82d0aa29c59a37fce6746a --- /dev/null +++ b/DDCore/src/OpticalSurfaceManager.cpp @@ -0,0 +1,83 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include "DD4hep/OpticalSurfaceManager.h" +#include "DD4hep/Detector.h" +#include "DD4hep/Printout.h" +#include "DD4hep/detail/Handle.inl" + +// C/C++ includes +#include <sstream> +#include <iomanip> + +DD4HEP_INSTANTIATE_HANDLE(TGeoManager); + +using namespace std; +using namespace dd4hep; + +/// static accessor calling DD4hepOpticalSurfaceManagerPlugin if necessary +OpticalSurfaceManager OpticalSurfaceManager::getOpticalSurfaceManager(Detector& description) { + return description.surfaceManager(); +} + +#if ROOT_VERSION_CODE > ROOT_VERSION(6,16,0) + +/// Access skin surface by its identifier +SkinSurface OpticalSurfaceManager::getSkinSurface(DetElement de, const string& nam) const { + if ( de.isValid() ) { + string n = de.path() + '#' + nam; + return access()->GetSkinSurface(n.c_str()); + } + except("SkinSurface", + "++ Cannot access SkinSurface %s without valid detector element!",nam.c_str()); + return SkinSurface(); +} + +/// Access border surface by its identifier +BorderSurface OpticalSurfaceManager::getBorderSurface(DetElement de, const string& nam) const { + if ( de.isValid() ) { + string n = de.path() + '#' + nam; + return access()->GetBorderSurface(n.c_str()); + } + except("BorderSurface", + "++ Cannot access BorderSurface %s without valid detector element!",nam.c_str()); + return BorderSurface(); +} + +/// Access optical surface data by its identifier +OpticalSurface OpticalSurfaceManager::getSurface(DetElement de, const string& nam) const { + if ( de.isValid() ) { + string n = de.path() + '#' + nam; + return access()->GetOpticalSurface(n.c_str()); + } + except("OpticalSurface", + "++ Cannot access OpticalSurface %s without valid detector element!",nam.c_str()); + return OpticalSurface(); +} + +/// Add skin surface to manager +void OpticalSurfaceManager::addSkinSurface(SkinSurface surf) const { + access()->AddSkinSurface(surf.ptr()); +} + +/// Add border surface to manager +void OpticalSurfaceManager::addBorderSurface(BorderSurface surf) const { + access()->AddBorderSurface(surf.ptr()); +} + +/// Add optical surface data to manager +void OpticalSurfaceManager::addSurface(OpticalSurface surf) const { + access()->AddOpticalSurface(surf.ptr()); +} +#endif diff --git a/DDCore/src/OpticalSurfaces.cpp b/DDCore/src/OpticalSurfaces.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3d6dfa9adb871a37d5d485c467e218af46dc4716 --- /dev/null +++ b/DDCore/src/OpticalSurfaces.cpp @@ -0,0 +1,112 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include "DD4hep/OpticalSurfaces.h" +#include "DD4hep/NamedObject.h" +#include "DD4hep/Detector.h" +#include "DD4hep/Printout.h" +#include "DD4hep/World.h" + +#include "DD4hep/detail/Handle.inl" + +// C/C++ includes +#include <sstream> +#include <iomanip> + +using namespace std; +using namespace dd4hep; + +#if ROOT_VERSION_CODE > ROOT_VERSION(6,16,0) + +DD4HEP_INSTANTIATE_HANDLE(TGeoSkinSurface); +DD4HEP_INSTANTIATE_HANDLE(TGeoBorderSurface); +DD4HEP_INSTANTIATE_HANDLE(TGeoOpticalSurface); + +/// Initializing constructor. +OpticalSurface::OpticalSurface(Detector& description, + const string& nam, + EModel model, + EFinish finish, + EType type, + double value) +{ + unique_ptr<Object> s(new Object(nam.c_str(), model, finish, type, value)); + description.manager().AddOpticalSurface(m_element=s.release()); +} + +/// Initializing constructor: Creates the object and registers it to the manager +SkinSurface::SkinSurface(DetElement de, const string& nam, OpticalSurface surf, Volume vol) +{ + if ( de.isValid() ) { + string n = de.path() + '#' + nam; + if ( vol.isValid() ) { + if ( surf.isValid() ) { + World wrld = de.world(); + unique_ptr<Object> s(new Object(n.c_str(), surf->GetName(), surf.ptr(), vol.ptr())); + wrld.detectorDescription().manager().AddSkinSurface(m_element=s.release()); + return; + } + except("SkinSurface","++ Cannot create SkinSurface %s without valid optical surface!",n.c_str()); + } + except("SkinSurface","++ Cannot create SkinSurface %s without valid volume!",n.c_str()); + } + except("SkinSurface", + "++ Cannot create SkinSurface %s which is not connected to a valid detector element!",nam.c_str()); +} + +/// Access surface data +OpticalSurface SkinSurface::surface() const { + return (TGeoOpticalSurface*)(access()->GetSurface()); +} + +/// Access the node of the skin surface +Volume SkinSurface::volume() const { + return access()->GetVolume(); +} + +/// Initializing constructor: Creates the object and registers it to the manager +BorderSurface::BorderSurface(DetElement de, const string& nam, OpticalSurface surf, PlacedVolume lft, PlacedVolume rht) +{ + if ( de.isValid() ) { + string n = de.path() + '#' + nam; + if ( lft.isValid() && rht.isValid() ) { + if ( surf.isValid() ) { + World wrld = de.world(); + unique_ptr<Object> s(new Object(n.c_str(), surf->GetName(), surf.ptr(), lft.ptr(), rht.ptr())); + wrld.detectorDescription().manager().AddBorderSurface(m_element=s.release()); + return; + } + except("BorderSurface","++ Cannot create BorderSurface %s without valid optical surface!",n.c_str()); + } + except("BorderSurface","++ Cannot create BorderSurface %s without valid placements!",n.c_str()); + } + except("BorderSurface", + "++ Cannot create BorderSurface %s which is not connected to a valid detector element!",nam.c_str()); +} + +/// Access surface data +OpticalSurface BorderSurface::surface() const { + return (TGeoOpticalSurface*)(access()->GetSurface()); +} + +/// Access the left node of the border surface +PlacedVolume BorderSurface::left() const { + return (TGeoNode*)access()->GetNode1(); +} + +/// Access the right node of the border surface +PlacedVolume BorderSurface::right() const { + return access()->GetNode2(); +} +#endif diff --git a/DDCore/src/PropertyTable.cpp b/DDCore/src/PropertyTable.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6bc9fecaab6912103857198e5272d8cb399032ca --- /dev/null +++ b/DDCore/src/PropertyTable.cpp @@ -0,0 +1,44 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include "DD4hep/PropertyTable.h" +#include "DD4hep/NamedObject.h" +#include "DD4hep/Detector.h" +#include "DD4hep/Printout.h" + +#include "DD4hep/detail/Handle.inl" + +// C/C++ includes +#include <sstream> +#include <iomanip> + +using namespace std; +using namespace dd4hep; + +#if ROOT_VERSION_CODE > ROOT_VERSION(6,16,0) + +DD4HEP_INSTANTIATE_HANDLE(TGDMLMatrix); + +/// Initializing constructor. +PropertyTable::PropertyTable(Detector& description, + const string& table_name, + const string& property_name, + size_t num_rows, + size_t num_cols) +{ + unique_ptr<Object> s(new Object(table_name.c_str(), num_rows, num_cols)); + s->SetTitle(property_name.c_str()); + description.manager().AddGDMLMatrix(m_element=s.release()); +} +#endif diff --git a/DDCore/src/plugins/Compact2Objects.cpp b/DDCore/src/plugins/Compact2Objects.cpp index 0f914784abf532686aa9aa779fff47d6189e624f..037d7a54a2f00ec028f27c936f4ad6cd233dcbf4 100644 --- a/DDCore/src/plugins/Compact2Objects.cpp +++ b/DDCore/src/plugins/Compact2Objects.cpp @@ -15,6 +15,9 @@ #include "DD4hep/DetFactoryHelper.h" #include "DD4hep/DetectorTools.h" #include "DD4hep/MatrixHelpers.h" +#include "DD4hep/PropertyTable.h" +#include "DD4hep/OpticalSurfaces.h" +#include "DD4hep/OpticalSurfaceManager.h" #include "DD4hep/IDDescriptor.h" #include "DD4hep/DD4hepUnits.h" #include "DD4hep/FieldTypes.h" @@ -72,6 +75,10 @@ namespace dd4hep { template <> void Converter<Property>::operator()(xml_h element) const; template <> void Converter<CartesianField>::operator()(xml_h element) const; template <> void Converter<SensitiveDetector>::operator()(xml_h element) const; +#if ROOT_VERSION_CODE > ROOT_VERSION(6,16,0) + template <> void Converter<OpticalSurface>::operator()(xml_h element) const; + template <> void Converter<PropertyTable>::operator()(xml_h element) const; +#endif template <> void Converter<DetElement>::operator()(xml_h element) const; template <> void Converter<GdmlFile>::operator()(xml_h element) const; template <> void Converter<JsonFile>::operator()(xml_h element) const; @@ -443,28 +450,35 @@ template <> void Converter<Material>::operator()(xml_h e) const { #if ROOT_VERSION_CODE >= ROOT_VERSION(6,12,0) mix->ComputeDerivedQuantities(); #endif - //fg: calling SetDensity for TGeoMixture results in incorrect radLen and intLen ( computed only from first element ) - // // Update estimated density if not provided. - // if ( has_density ) { - // mix->SetDensity(dens_val); - // } - // else if (!has_density && mix && 0 == mix->GetDensity()) { - // double dens = 0.0; - // for (composites.reset(), ifrac=0; composites; ++composites, ++ifrac) { - // string nam = composites.attr<string>(_U(ref)); - // comp_mat = mgr.GetMaterial(nam.c_str()); - // dens += composites.attr<double>(_U(n)) * comp_mat->GetDensity(); - // } - // for (fractions.reset(); fractions; ++fractions) { - // string nam = fractions.attr<string>(_U(ref)); - // comp_mat = mgr.GetMaterial(nam.c_str()); - // dens += composites.attr<double>(_U(n)) * comp_mat->GetDensity(); - // } - // printout(WARNING, "Compact", "++ Material: %s with NO density. " - // "Set density to %7.3 g/cm**3", matname, dens); - // mix->SetDensity(dens); - // } - +#if ROOT_VERSION_CODE > ROOT_VERSION(6,16,0) + /// In case there were material properties specified: convert them here + for(xml_coll_t properties(x_mat, _U(property)); properties; ++properties) { + xml_elt_t p = properties; + if ( p.hasAttr(_U(ref)) ) { + string ref = p.attr<string>(_U(ref)); + TGDMLMatrix* m = mgr.GetGDMLMatrix(ref.c_str()); + if ( m ) { + //TODO: mat->AddProperty(p.attr<string>(_U(name)).c_str(), m); + mat->AddProperty(p.attr<string>(_U(name)).c_str(), ref.c_str()); + continue; + } + // ERROR + throw_print("Compact2Objects[ERROR]: Converting material:" + mname + " Property missing: " + ref); + } + } +#endif + xml_h temp = x_mat.child(_U(T), false); + if ( temp.ptr() ) { + double temp_val = temp.attr<double>(_U(value)); + double temp_unit = temp.attr<double>(_U(unit), 1.0 /* _toDouble("kelvin") */); + mat->SetTemperature(temp_val*temp_unit); + } + xml_h pressure = x_mat.child(_U(P), false); + if ( pressure.ptr() ) { + double pressure_val = pressure.attr<double>(_U(value)); + double pressure_unit = pressure.attr<double>(_U(unit),1.0 /* _toDouble("pascal") */); + mat->SetPressure(pressure_val*pressure_unit); + } } TGeoMedium* medium = mgr.GetMedium(matname); if (0 == medium) { @@ -591,6 +605,51 @@ template <> void Converter<Atom>::operator()(xml_h e) const { } } +#if ROOT_VERSION_CODE > ROOT_VERSION(6,16,0) +/** Convert compact optical surface objects (defines) + * + * + */ +template <> void Converter<OpticalSurface>::operator()(xml_h element) const { + xml_attr_t attr; + xml_elt_t e = element; + OpticalSurface::EModel model = OpticalSurface::Model::kMglisur; + OpticalSurface::EFinish finish = OpticalSurface::Finish::kFpolished; + OpticalSurface::EType type = OpticalSurface::Type::kTdielectric_metal; + Double_t value = 0; + if ( (attr=e.attr<xml_attr_t>(_U(type))) ) type = OpticalSurface::Type::StringToType(e.attr<string>(attr).c_str()); + if ( (attr=e.attr<xml_attr_t>(_U(model))) ) model = OpticalSurface::Model::StringToModel(e.attr<string>(attr).c_str()); + if ( (attr=e.attr<xml_attr_t>(_U(finish))) ) finish = OpticalSurface::Finish::StringToFinish(e.attr<string>(attr).c_str()); + if ( (attr=e.attr<xml_attr_t>(_U(value))) ) value = e.attr<double>(attr); + OpticalSurface surf(description, e.attr<string>(_U(name)), model, finish, type, value); + for (xml_coll_t props(e, _U(property)); props; ++props) { + surf->AddProperty(props.attr<string>(_U(name)).c_str(), props.attr<string>(_U(ref)).c_str()); + } +} + +/** Convert compact property table objects (defines) + * + * <matrix coldim="2" name="RINDEX0xf5972d0" values="1.5e-06 1.0013 1. ...."/> + * + */ +template <> void Converter<PropertyTable>::operator()(xml_h e) const { + string val; + vector<float> values; + size_t cols = e.attr<long>(_U(coldim)); + stringstream str(e.attr<string>(_U(values))); + + values.reserve(1024); + while ( !str.eof() ) { + str >> val; + values.push_back(_toDouble(val)); + } + /// Create table and register table + PropertyTable table(description, e.attr<string>(_U(name)), "", values.size()/cols, cols); + for (size_t i=0, n=values.size(); i<n; ++i) + table->Set(i/cols, i%cols, values[i]); +} +#endif + /** Convert compact visualization attribute to Detector visualization attribute * * <vis name="SiVertexBarrelModuleVis" @@ -863,7 +922,7 @@ template <> void Converter<LimitSet>::operator()(xml_h e) const { * ... </properties> */ template <> void Converter<Property>::operator()(xml_h e) const { - string name = e.attr<string>(_U(name)); + string name = e.attr<string>(_U(name)); Detector::Properties& prp = description.properties(); if ( name.empty() ) throw_print("Failed to convert properties. No name given!"); @@ -1284,9 +1343,15 @@ template <> void Converter<Compact>::operator()(xml_h element) const { xml_coll_t(compact, _U(materials)).for_each(_U(element), Converter<Atom>(description)); xml_coll_t(compact, _U(materials)).for_each(_U(material), Converter<Material>(description)); xml_coll_t(compact, _U(properties)).for_each(_U(attributes), Converter<Property>(description)); +#if ROOT_VERSION_CODE > ROOT_VERSION(6,16,0) + /// These two must be parsed early, because they are needed by the detector constructors + xml_coll_t(compact, _U(properties)).for_each(_U(matrix), Converter<PropertyTable>(description)); + xml_coll_t(compact, _U(surfaces)).for_each(_U(opticalsurface), Converter<OpticalSurface>(description)); +#endif + xml_coll_t(compact, _U(display)).for_each(_U(include), Converter<DetElementInclude>(description)); xml_coll_t(compact, _U(display)).for_each(_U(vis), Converter<VisAttr>(description)); - + if (element.hasChild(_U(world))) (Converter<World>(description))(xml_h(compact.child(_U(world)))); diff --git a/DDG4/include/DDG4/Geant4Converter.h b/DDG4/include/DDG4/Geant4Converter.h index 938b63def84726045e5e2674b465b6427938c7aa..b3fd7ffa902bae695e9abd13db386f7dd7a63457 100644 --- a/DDG4/include/DDG4/Geant4Converter.h +++ b/DDG4/include/DDG4/Geant4Converter.h @@ -66,6 +66,19 @@ namespace dd4hep { /// Create geometry conversion Geant4Converter& create(DetElement top); +#if ROOT_VERSION_CODE > ROOT_VERSION(6,16,0) + /// Convert the geometry type material into the corresponding Geant4 object(s). + virtual void* handleMaterialProperties(TObject* matrix) const; + + /// Convert the optical surface to Geant4 + void* handleOpticalSurface(TObject* surface) const; + + /// Convert the skin surface to Geant4 + void* handleSkinSurface(TObject* surface) const; + + /// Convert the border surface to Geant4 + void* handleBorderSurface(TObject* surface) const; +#endif /// Convert the geometry type material into the corresponding Geant4 object(s). virtual void* handleMaterial(const std::string& name, Material medium) const; diff --git a/DDG4/include/DDG4/Geant4GeometryInfo.h b/DDG4/include/DDG4/Geant4GeometryInfo.h index af0cde3f3941e61827feb7c10ca2bbbc7aecdecc..398809e19f0600bface01be6af5f3ed925c7ccbb 100644 --- a/DDG4/include/DDG4/Geant4GeometryInfo.h +++ b/DDG4/include/DDG4/Geant4GeometryInfo.h @@ -18,6 +18,7 @@ #include "DD4hep/Objects.h" #include "DD4hep/Printout.h" #include "DD4hep/GeoHandler.h" +#include "DD4hep/PropertyTable.h" #include "DDG4/Geant4Primitives.h" // C/C++ include files @@ -39,8 +40,12 @@ class G4Region; class G4UserLimits; class G4VisAttributes; class G4VPhysicalVolume; +class G4OpticalSurface; +class G4LogicalSkinSurface; +class G4LogicalBorderSurface; class G4AssemblyVolume; class G4VSensitiveDetector; +class G4PhysicsOrderedFreeVector; /// Namespace for the AIDA detector description toolkit namespace dd4hep { @@ -94,6 +99,19 @@ namespace dd4hep { Geant4GeometryMaps::PlacementMap g4Placements; Geant4GeometryMaps::AssemblyMap g4AssemblyVolumes; Geant4GeometryMaps::VolumeImprintMap g4VolumeImprints; + struct PropertyVector { + std::vector<double> bins; + std::vector<double> values; + std::string name, title; + PropertyVector() = default; + ~PropertyVector() = default; + }; +#if ROOT_VERSION_CODE > ROOT_VERSION(6,16,0) + std::map<PropertyTable, PropertyVector*> g4OpticalProperties; + std::map<OpticalSurface, G4OpticalSurface*> g4OpticalSurfaces; + std::map<SkinSurface, G4LogicalSkinSurface*> g4SkinSurfaces; + std::map<BorderSurface, G4LogicalBorderSurface*> g4BorderSurfaces; +#endif std::map<Region, G4Region*> g4Regions; std::map<VisAttr, G4VisAttributes*> g4Vis; std::map<LimitSet, G4UserLimits*> g4Limits; diff --git a/DDG4/src/Geant4Converter.cpp b/DDG4/src/Geant4Converter.cpp index b5ff59e343dd528e00bec42079ce28c5ccaf468d..66ebe6342932c3475985d9da0d4891911f431d56 100644 --- a/DDG4/src/Geant4Converter.cpp +++ b/DDG4/src/Geant4Converter.cpp @@ -17,6 +17,7 @@ #include "DD4hep/Volumes.h" #include "DD4hep/Printout.h" #include "DD4hep/DD4hepUnits.h" +#include "DD4hep/PropertyTable.h" #include "DD4hep/detail/ObjectsInterna.h" #include "DD4hep/detail/DetectorInterna.h" @@ -87,6 +88,10 @@ #include "G4ElectroMagneticField.hh" #include "G4FieldManager.hh" #include "G4ReflectionFactory.hh" +#include "G4OpticalSurface.hh" +#include "G4LogicalSkinSurface.hh" +#include "G4LogicalBorderSurface.hh" +#include "G4MaterialPropertiesTable.hh" #include "CLHEP/Units/SystemOfUnits.h" // C/C++ include files @@ -340,7 +345,8 @@ void* Geant4Converter::handleElement(const string& name, const Atom element) con /// Dump material in GDML format to output stream void* Geant4Converter::handleMaterial(const string& name, Material medium) const { - G4Material* mat = data().g4Materials[medium]; + Geant4GeometryInfo& info = data(); + G4Material* mat = info.g4Materials[medium]; if (!mat) { PrintLevel lvl = debugMaterials ? ALWAYS : outputLevel; mat = G4Material::GetMaterial(name, false); @@ -395,11 +401,29 @@ void* Geant4Converter::handleMaterial(const string& name, Material medium) const mat = new G4Material(name, z, a, density, state, material->GetTemperature(), material->GetPressure()); } +#if ROOT_VERSION_CODE > ROOT_VERSION(6,16,0) + /// Attach the material properties if any + G4MaterialPropertiesTable* tab = 0; + TListIter propIt(&material->GetProperties()); + for(TObject* obj=*propIt; obj; obj = propIt.Next()) { + TNamed* n = (TNamed*)obj; + TGDMLMatrix *matrix = info.manager->GetGDMLMatrix(n->GetTitle()); + if ( 0 == tab ) { + tab = new G4MaterialPropertiesTable(); + mat->SetMaterialPropertiesTable(tab); + } + Geant4GeometryInfo::PropertyVector* v = + (Geant4GeometryInfo::PropertyVector*)handleMaterialProperties(matrix); + G4MaterialPropertyVector* vec = + new G4MaterialPropertyVector(&v->bins[0], &v->values[0], v->bins.size()); + tab->AddProperty(n->GetName(), vec); + } +#endif stringstream str; str << (*mat); printout(lvl, "Geant4Converter", "++ Created G4 %s", str.str().c_str()); } - data().g4Materials[medium] = mat; + info.g4Materials[medium] = mat; } return mat; } @@ -1025,6 +1049,184 @@ void Geant4Converter::handleProperties(Detector::Properties& prp) const { } } +#if ROOT_VERSION_CODE > ROOT_VERSION(6,16,0) +/// Convert the geometry type material into the corresponding Geant4 object(s). +void* Geant4Converter::handleMaterialProperties(TObject* matrix) const { + TGDMLMatrix* m = (TGDMLMatrix*)matrix; + Geant4GeometryInfo& info = data(); + Geant4GeometryInfo::PropertyVector* g4 = info.g4OpticalProperties[m]; + if (!g4) { + g4 = new Geant4GeometryInfo::PropertyVector(); + size_t rows = m->GetRows(); + g4->name = m->GetName(); + g4->title = m->GetTitle(); + g4->bins.reserve(rows); + g4->values.reserve(rows); + for(size_t i=0; i<rows; ++i) { + g4->bins.push_back(m->Get(0,i) /* *CLHEP::eV/units::eV */); + g4->values.push_back(m->Get(1,i)); + } + info.g4OpticalProperties[m] = g4; + } + return g4; +} + +static G4OpticalSurfaceFinish geant4_surface_finish(TGeoOpticalSurface::ESurfaceFinish f) { +#define TO_G4_FINISH(x) case TGeoOpticalSurface::kF##x : return x; + switch(f) { + TO_G4_FINISH(polished); // smooth perfectly polished surface + TO_G4_FINISH(polishedfrontpainted); // smooth top-layer (front) paint + TO_G4_FINISH(polishedbackpainted); // same is 'polished' but with a back-paint + + TO_G4_FINISH(ground); // rough surface + TO_G4_FINISH(groundfrontpainted); // rough top-layer (front) paint + TO_G4_FINISH(groundbackpainted); // same as 'ground' but with a back-paint + + TO_G4_FINISH(polishedlumirrorair); // mechanically polished surface, with lumirror + TO_G4_FINISH(polishedlumirrorglue); // mechanically polished surface, with lumirror & meltmount + TO_G4_FINISH(polishedair); // mechanically polished surface + TO_G4_FINISH(polishedteflonair); // mechanically polished surface, with teflon + TO_G4_FINISH(polishedtioair); // mechanically polished surface, with tio paint + TO_G4_FINISH(polishedtyvekair); // mechanically polished surface, with tyvek + TO_G4_FINISH(polishedvm2000air); // mechanically polished surface, with esr film + TO_G4_FINISH(polishedvm2000glue); // mechanically polished surface, with esr film & meltmount + + TO_G4_FINISH(etchedlumirrorair); // chemically etched surface, with lumirror + TO_G4_FINISH(etchedlumirrorglue); // chemically etched surface, with lumirror & meltmount + TO_G4_FINISH(etchedair); // chemically etched surface + TO_G4_FINISH(etchedteflonair); // chemically etched surface, with teflon + TO_G4_FINISH(etchedtioair); // chemically etched surface, with tio paint + TO_G4_FINISH(etchedtyvekair); // chemically etched surface, with tyvek + TO_G4_FINISH(etchedvm2000air); // chemically etched surface, with esr film + TO_G4_FINISH(etchedvm2000glue); // chemically etched surface, with esr film & meltmount + + TO_G4_FINISH(groundlumirrorair); // rough-cut surface, with lumirror + TO_G4_FINISH(groundlumirrorglue); // rough-cut surface, with lumirror & meltmount + TO_G4_FINISH(groundair); // rough-cut surface + TO_G4_FINISH(groundteflonair); // rough-cut surface, with teflon + TO_G4_FINISH(groundtioair); // rough-cut surface, with tio paint + TO_G4_FINISH(groundtyvekair); // rough-cut surface, with tyvek + TO_G4_FINISH(groundvm2000air); // rough-cut surface, with esr film + TO_G4_FINISH(groundvm2000glue); // rough-cut surface, with esr film & meltmount + + // for DAVIS model + TO_G4_FINISH(Rough_LUT); // rough surface + TO_G4_FINISH(RoughTeflon_LUT); // rough surface wrapped in Teflon tape + TO_G4_FINISH(RoughESR_LUT); // rough surface wrapped with ESR + TO_G4_FINISH(RoughESRGrease_LUT); // rough surface wrapped with ESR and coupled with opical grease + TO_G4_FINISH(Polished_LUT); // polished surface + TO_G4_FINISH(PolishedTeflon_LUT); // polished surface wrapped in Teflon tape + TO_G4_FINISH(PolishedESR_LUT); // polished surface wrapped with ESR + TO_G4_FINISH(PolishedESRGrease_LUT); // polished surface wrapped with ESR and coupled with opical grease + TO_G4_FINISH(Detector_LUT); // polished surface with optical grease + default: + printout(ERROR,"Geant4Surfaces","++ Unknown finish style: %d [%s]. Assume polished!", + int(f), TGeoOpticalSurface::FinishToString(f)); + return polished; + } +#undef TO_G4_FINISH +} + +static G4SurfaceType geant4_surface_type(TGeoOpticalSurface::ESurfaceType t) { +#define TO_G4_TYPE(x) case TGeoOpticalSurface::kT##x : return x; + switch(t) { + TO_G4_TYPE(dielectric_metal); // dielectric-metal interface + TO_G4_TYPE(dielectric_dielectric); // dielectric-dielectric interface + TO_G4_TYPE(dielectric_LUT); // dielectric-Look-Up-Table interface + TO_G4_TYPE(dielectric_LUTDAVIS); // dielectric-Look-Up-Table DAVIS interface + TO_G4_TYPE(dielectric_dichroic); // dichroic filter interface + TO_G4_TYPE(firsov); // for Firsov Process + TO_G4_TYPE(x_ray); // for x-ray mirror process + default: + printout(ERROR,"Geant4Surfaces","++ Unknown finish style: %d [%s]. Assume polished!", + int(t), TGeoOpticalSurface::TypeToString(t)); + return dielectric_metal; + } +#undef TO_G4_TYPE +} + +static G4OpticalSurfaceModel geant4_surface_model(TGeoOpticalSurface::ESurfaceModel m) { +#define TO_G4_MODEL(x) case TGeoOpticalSurface::kM##x : return x; + switch(m) { + TO_G4_MODEL(glisur); // original GEANT3 model + TO_G4_MODEL(unified); // UNIFIED model + TO_G4_MODEL(LUT); // Look-Up-Table model + TO_G4_MODEL(DAVIS); // DAVIS model + TO_G4_MODEL(dichroic); // dichroic filter + default: + printout(ERROR,"Geant4Surfaces","++ Unknown finish style: %d [%s]. Assume polished!", + int(m), TGeoOpticalSurface::ModelToString(m)); + return glisur; + } +#undef TO_G4_MODEL +} + +/// Convert the optical surface to Geant4 +void* Geant4Converter::handleOpticalSurface(TObject* surface) const { + TGeoOpticalSurface* s = (TGeoOpticalSurface*)surface; + Geant4GeometryInfo& info = data(); + G4OpticalSurface* g4 = info.g4OpticalSurfaces[s]; + if (!g4) { + G4SurfaceType type = geant4_surface_type(s->GetType()); + G4OpticalSurfaceModel model = geant4_surface_model(s->GetModel()); + G4OpticalSurfaceFinish finish = geant4_surface_finish(s->GetFinish()); + g4 = new G4OpticalSurface(s->GetName(), model, finish, type, s->GetValue()); + g4->SetSigmaAlpha(s->GetSigmaAlpha()); + // not implemented: g4->SetPolish(s->GetPolish()); + G4MaterialPropertiesTable* tab = 0; + TListIter it(&s->GetProperties()); + for(TObject* obj = *it; obj; obj = it.Next()) { + TNamed* n = (TNamed*)obj; + TGDMLMatrix *matrix = info.manager->GetGDMLMatrix(n->GetTitle()); + if ( 0 == tab ) { + tab = new G4MaterialPropertiesTable(); + g4->SetMaterialPropertiesTable(tab); + } + Geant4GeometryInfo::PropertyVector* v = + (Geant4GeometryInfo::PropertyVector*)handleMaterialProperties(matrix); + if ( !v ) { // Error! + except("Geant4OpticalSurface","++ Failed to convert opt.surface %s. Property table %s is not defined!", + s->GetName(), n->GetTitle()); + } + G4MaterialPropertyVector* vec = + new G4MaterialPropertyVector(&v->bins[0], &v->values[0], v->bins.size()); + tab->AddProperty(n->GetName(), vec); + } + info.g4OpticalSurfaces[s] = g4; + } + return g4; +} + +/// Convert the skin surface to Geant4 +void* Geant4Converter::handleSkinSurface(TObject* surface) const { + TGeoSkinSurface* surf = (TGeoSkinSurface*)surface; + Geant4GeometryInfo& info = data(); + G4LogicalSkinSurface* g4 = info.g4SkinSurfaces[surf]; + if (!g4) { + G4OpticalSurface* s = info.g4OpticalSurfaces[OpticalSurface(surf->GetSurface())]; + G4LogicalVolume* v = info.g4Volumes[surf->GetVolume()]; + g4 = new G4LogicalSkinSurface(surf->GetName(), v, s); + info.g4SkinSurfaces[surf] = g4; + } + return g4; +} + +/// Convert the border surface to Geant4 +void* Geant4Converter::handleBorderSurface(TObject* surface) const { + TGeoBorderSurface* surf = (TGeoBorderSurface*)surface; + Geant4GeometryInfo& info = data(); + G4LogicalBorderSurface* g4 = info.g4BorderSurfaces[surf]; + if (!g4) { + G4OpticalSurface* s = info.g4OpticalSurfaces[OpticalSurface(surf->GetSurface())]; + G4VPhysicalVolume* n1 = info.g4Placements[surf->GetNode1()]; + G4VPhysicalVolume* n2 = info.g4Placements[surf->GetNode2()]; + g4 = new G4LogicalBorderSurface(surf->GetName(), n1, n2, s); + info.g4BorderSurfaces[surf] = g4; + } + return g4; +} +#endif + /// Convert the geometry type SensitiveDetector into the corresponding Geant4 object(s). void Geant4Converter::printSensitive(SensitiveDetector sens_det, const set<const TGeoVolume*>& /* volumes */) const { Geant4GeometryInfo& info = data(); @@ -1104,12 +1306,19 @@ template <typename O, typename C, typename F> void handleRefs(const O* o, const (o->*pmf)("", *i); } } + template <typename O, typename C, typename F> void handle(const O* o, const C& c, F pmf) { for (typename C::const_iterator i = c.begin(); i != c.end(); ++i) { (o->*pmf)((*i)->GetName(), *i); } } +template <typename O, typename F> void handleArray(const O* o, const TObjArray* c, F pmf) { + TObjArrayIter arr(c); + for(TObject* i = *arr; i; i=arr.Next()) + (o->*pmf)(i); +} + template <typename O, typename C, typename F> void handleMap(const O* o, const C& c, F pmf) { for (typename C::const_iterator i = c.begin(); i != c.end(); ++i) (o->*pmf)((*i).first, (*i).second); @@ -1137,20 +1346,30 @@ Geant4Converter& Geant4Converter::create(DetElement top) { //outputLevel = WARNING; //setPrintLevel(VERBOSE); - handle(this, geo.volumes, &Geant4Converter::collectVolume); - handle(this, geo.solids, &Geant4Converter::handleSolid); +#if ROOT_VERSION_CODE > ROOT_VERSION(6,16,0) + handleArray(this, geo.manager->GetListOfGDMLMatrices(), &Geant4Converter::handleMaterialProperties); + handleArray(this, geo.manager->GetListOfOpticalSurfaces(), &Geant4Converter::handleOpticalSurface); +#endif + + handle(this, geo.volumes, &Geant4Converter::collectVolume); + handle(this, geo.solids, &Geant4Converter::handleSolid); printout(outputLevel, "Geant4Converter", "++ Handled %ld solids.", geo.solids.size()); - handleRefs(this, geo.vis, &Geant4Converter::handleVis); + handleRefs(this, geo.vis, &Geant4Converter::handleVis); printout(outputLevel, "Geant4Converter", "++ Handled %ld visualization attributes.", geo.vis.size()); - handleMap(this, geo.limits, &Geant4Converter::handleLimitSet); + handleMap(this, geo.limits, &Geant4Converter::handleLimitSet); printout(outputLevel, "Geant4Converter", "++ Handled %ld limit sets.", geo.limits.size()); - handleMap(this, geo.regions, &Geant4Converter::handleRegion); + handleMap(this, geo.regions, &Geant4Converter::handleRegion); printout(outputLevel, "Geant4Converter", "++ Handled %ld regions.", geo.regions.size()); - handle(this, geo.volumes, &Geant4Converter::handleVolume); + handle(this, geo.volumes, &Geant4Converter::handleVolume); printout(outputLevel, "Geant4Converter", "++ Handled %ld volumes.", geo.volumes.size()); - handleRMap(this, *m_data, &Geant4Converter::handleAssembly); + handleRMap(this, *m_data, &Geant4Converter::handleAssembly); // Now place all this stuff appropriately - handleRMap(this, *m_data, &Geant4Converter::handlePlacement); + handleRMap(this, *m_data, &Geant4Converter::handlePlacement); +#if ROOT_VERSION_CODE > ROOT_VERSION(6,16,0) + /// Handle concrete surfaces + handleArray(this, geo.manager->GetListOfSkinSurfaces(), &Geant4Converter::handleSkinSurface); + handleArray(this, geo.manager->GetListOfBorderSurfaces(), &Geant4Converter::handleBorderSurface); +#endif //==================== Fields handleProperties(m_detDesc.properties()); if ( printSensitives ) {