From 6d6964b346b323e226eb9d858a9c7ef256953f47 Mon Sep 17 00:00:00 2001 From: Markus Frank <Markus.Frank@cern.ch> Date: Fri, 8 Nov 2019 18:31:11 +0100 Subject: [PATCH] Fix Geant4 conversion for Polyhedra and Polycone if start_phi != 0 (Issue https://github.com/AIDASoft/DD4hep/issues/578) --- DDCond/src/ConditionsContent.cpp | 6 +- DDCond/src/ConditionsDependencyHandler.cpp | 9 +- DDCore/include/DD4hep/ConditionDerived.h | 2 +- DDCore/include/DD4hep/Conditions.h | 4 +- DDCore/include/DD4hep/Shapes.h | 85 +++++++++++- DDCore/include/DD4hep/config.h | 19 ++- .../include/DD4hep/detail/ConditionsInterna.h | 4 +- DDCore/include/DD4hep/detail/ShapesInterna.h | 76 +++++++++++ DDCore/include/Parsers/detail/Dimension.h | 30 +++-- DDCore/include/Parsers/detail/Dimension.imp | 4 + DDCore/include/XML/UnicodeValues.h | 4 + DDCore/src/ConditionDerived.cpp | 4 +- DDCore/src/Conditions.cpp | 10 +- DDCore/src/ConditionsInterna.cpp | 4 +- DDCore/src/GeoDictionary.h | 5 + DDCore/src/Handle.cpp | 3 + DDCore/src/ShapeTags.h | 1 + DDCore/src/ShapeUtilities.cpp | 49 ++++++- DDCore/src/Shapes.cpp | 8 ++ DDCore/src/ShapesInterna.cpp | 77 +++++++++++ DDCore/src/plugins/ShapePlugins.cpp | 75 +++++++---- .../Geant4DetectorGeometryConstruction.cpp | 121 +++++++++++++++++- DDG4/src/Geant4Converter.cpp | 28 ++-- DDG4/src/Geant4ShapeConverter.cpp | 10 +- examples/ClientTests/CMakeLists.txt | 2 +- .../compact/Check_Shape_Polyhedra.xml | 20 +++ .../compact/Check_Shape_TwistedTube.xml | 20 +++ examples/ClientTests/ref/Ref_Polyhedra.txt | 15 +++ examples/ClientTests/scripts/Check_shape.py | 48 ++++--- .../ClientTests/scripts/Check_shape_dump.mac | 2 + .../DDDB/src/plugins/DDDBDerivedCondTest.cpp | 18 +-- 31 files changed, 650 insertions(+), 113 deletions(-) create mode 100644 DDCore/include/DD4hep/detail/ShapesInterna.h create mode 100644 DDCore/src/ShapesInterna.cpp create mode 100644 examples/ClientTests/compact/Check_Shape_Polyhedra.xml create mode 100644 examples/ClientTests/compact/Check_Shape_TwistedTube.xml create mode 100644 examples/ClientTests/ref/Ref_Polyhedra.txt create mode 100644 examples/ClientTests/scripts/Check_shape_dump.mac diff --git a/DDCond/src/ConditionsContent.cpp b/DDCond/src/ConditionsContent.cpp index d66ada4ae..c83a276b3 100644 --- a/DDCond/src/ConditionsContent.cpp +++ b/DDCond/src/ConditionsContent.cpp @@ -126,9 +126,13 @@ ConditionsContent::addDependency(ConditionDependency* dep) return *(ret.first); } ConditionKey::KeyMaker km(dep->target.hash); +#if defined(DD4HEP_CONDITIONS_DEBUG) DetElement de(dep->detector); - dep->release(); const char* path = de.isValid() ? de.path().c_str() : "(global)"; +#else + const char* path = ""; +#endif + dep->release(); except("DeConditionsRequests", "++ Dependency already exists: %s [%08X] [%016llX]", path, km.values.item_key, km.hash); diff --git a/DDCond/src/ConditionsDependencyHandler.cpp b/DDCond/src/ConditionsDependencyHandler.cpp index e34b758eb..602b023dc 100644 --- a/DDCond/src/ConditionsDependencyHandler.cpp +++ b/DDCond/src/ConditionsDependencyHandler.cpp @@ -248,9 +248,14 @@ void ConditionsDependencyHandler::do_callback(Work* work) { // during the construction tries to access this one. // ---> Classic dead-lock except("DependencyHandler", - "++ Handler caught in infinite recursion loop. DE:%s Key:%s", + "++ Handler caught in infinite recursion loop. Key:%s %c%s%c", work->context.dependency->target.toString().c_str(), - work->context.dependency->detector.path().c_str()); +#if defined(DD4HEP_CONDITIONS_DEBUG) + '[',work->context.dependency->detector.path().c_str(),']' +#else + ' ',"",' ' +#endif + ); } ++work->callstack; work->condition = (*dep->callback)(dep->target, work->context).ptr(); diff --git a/DDCore/include/DD4hep/ConditionDerived.h b/DDCore/include/DD4hep/ConditionDerived.h index 921eec820..54f8f95f1 100644 --- a/DDCore/include/DD4hep/ConditionDerived.h +++ b/DDCore/include/DD4hep/ConditionDerived.h @@ -348,7 +348,7 @@ namespace dd4hep { ConditionDependency(); /// Access the dependency key Condition::key_type key() const { return target.hash; } -#ifdef DD4HEP_CONDITIONS_DEBUG +#if defined(DD4HEP_CONDITIONS_DEBUG) || defined(DD4HEP_CONDITIONKEY_HAVE_NAME) /// Access the dependency key const char* name() const { return target.name.c_str(); } #endif diff --git a/DDCore/include/DD4hep/Conditions.h b/DDCore/include/DD4hep/Conditions.h index 162099f88..151782777 100644 --- a/DDCore/include/DD4hep/Conditions.h +++ b/DDCore/include/DD4hep/Conditions.h @@ -181,7 +181,7 @@ namespace dd4hep { /// Access the type field of the condition const std::string& type() const; -#if !defined(DD4HEP_MINIMAL_CONDITIONS) +#if defined(DD4HEP_CONDITIONS_DEBUG) || !defined(DD4HEP_MINIMAL_CONDITIONS) /// Access the value field of the condition as a string const std::string& value() const; /// Access the comment field of the condition @@ -244,7 +244,7 @@ namespace dd4hep { */ class ConditionKey { public: -#ifdef DD4HEP_CONDITIONS_DEBUG +#if defined(DD4HEP_CONDITIONS_DEBUG) || defined(DD4HEP_CONDITIONKEY_HAVE_NAME) /// Optional string identifier. Helps debugging a lot! std::string name; #endif diff --git a/DDCore/include/DD4hep/Shapes.h b/DDCore/include/DD4hep/Shapes.h index f284302c3..54aa7a7ef 100644 --- a/DDCore/include/DD4hep/Shapes.h +++ b/DDCore/include/DD4hep/Shapes.h @@ -590,11 +590,11 @@ namespace dd4hep { /// Class describing a elliptical tube shape /** - * TGeoEltu - cylindrical tube class. It takes 3 parameters : - * Semi axis of ellipsis in x and y and half-length dz. + * This is actually no TGeo shape. This implementation is a placeholder + * for the Geant4 implementation G4TwistedTube. + * In root it is implemented by a simple tube segment. + * When converted to geant4 it will become a G4TwistedTube. * - * For any further documentation please see the following ROOT documentation: - * \see http://root.cern.ch/root/html/TGeoElTu.html * * \author M.Frank * \version 1.0 @@ -640,6 +640,83 @@ namespace dd4hep { EllipticalTube& setDimensions(double a, double b, double dz); }; + /// Class describing a twisted tube shape + /** + * TGeoEltu - cylindrical tube class. It takes 3 parameters : + * Semi axis of ellipsis in x and y and half-length dz. + * + * For any further documentation please see the following ROOT documentation: + * \see http://root.cern.ch/root/html/TGeoElTu.html + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CORE + */ + class TwistedTube : public Solid_type<TGeoTubeSeg> { + protected: + /// Internal helper method to support TwistedTube object construction + void make(const std::string& nam, double twist_angle, double rmin, double rmax, + double zneg, double zpos, int nsegments, double totphi); + + public: + /// Default constructor + TwistedTube() = default; + /// Move Constructor + TwistedTube(TwistedTube&& e) = default; + /// Copy Constructor + TwistedTube(const TwistedTube& e) = default; + /// Constructor to be used with an existing object + template <typename Q> TwistedTube(const Q* p) : Solid_type<Object>(p) { } + /// Constructor to assign an object + template <typename Q> TwistedTube(const Handle<Q>& e) : Solid_type<Object>(e) { } + + /// Constructor to create a new anonymous tube object with attribute initialization + TwistedTube(double twist_angle, double rmin, double rmax, + double dz, double dphi) + { this->make("", twist_angle, rmin, rmax, -dz, dz, 1, dphi); } + /// Constructor to create a new anonymous tube object with attribute initialization + TwistedTube(double twist_angle, double rmin, double rmax, + double dz, int nsegments, double totphi) + { this->make("", twist_angle, rmin, rmax, -dz, dz, nsegments, totphi); } + /// Constructor to create a new anonymous tube object with attribute initialization + TwistedTube(double twist_angle, double rmin, double rmax, + double zneg, double zpos, double totphi) + { this->make("", twist_angle, rmin, rmax, zneg, zpos, 1, totphi); } + /// Constructor to create a new anonymous tube object with attribute initialization + TwistedTube(double twist_angle, double rmin, double rmax, + double zneg, double zpos, int nsegments, double totphi) + { this->make("", twist_angle, rmin, rmax, zneg, zpos, nsegments, totphi); } + + /// Constructor to create a new anonymous tube object with attribute initialization + TwistedTube(const std::string& nam, double twist_angle, double rmin, double rmax, + double dz, double dphi) + { this->make(nam, twist_angle, rmin, rmax, -dz, dz, 1, dphi); } + /// Constructor to create a new anonymous tube object with attribute initialization + TwistedTube(const std::string& nam, double twist_angle, double rmin, double rmax, + double dz, int nsegments, double totphi) + { this->make(nam, twist_angle, rmin, rmax, -dz, dz, nsegments, totphi); } + /// Constructor to create a new anonymous tube object with attribute initialization + TwistedTube(const std::string& nam, double twist_angle, double rmin, double rmax, + double zneg, double zpos, double totphi) + { this->make(nam, twist_angle, rmin, rmax, zneg, zpos, 1, totphi); } + /// Constructor to create a new anonymous tube object with attribute initialization + TwistedTube(const std::string& nam, double twist_angle, double rmin, double rmax, + double zneg, double zpos, int nsegments, double totphi) + { this->make(nam, twist_angle, rmin, rmax, zneg, zpos, nsegments, totphi); } + + /// Constructor to create a new identified tube object with attribute initialization + template <typename A, typename B, typename DZ> + TwistedTube(const std::string& nam, const A& a, const B& b, const DZ& dz) + { this->make(nam, _toDouble(a), _toDouble(b), _toDouble(dz)); } + + /// Move Assignment operator + TwistedTube& operator=(TwistedTube&& copy) = default; + /// Copy Assignment operator + TwistedTube& operator=(const TwistedTube& copy) = default; + /// Set the tube dimensions + TwistedTube& setDimensions(double a, double b, double dz); + }; + /// Class describing a trap shape /** * For any further documentation please see the following ROOT documentation: diff --git a/DDCore/include/DD4hep/config.h b/DDCore/include/DD4hep/config.h index e80a1e492..9b861a2f1 100644 --- a/DDCore/include/DD4hep/config.h +++ b/DDCore/include/DD4hep/config.h @@ -15,10 +15,17 @@ #define DD4HEP_INSTANCE_COUNTS 1 #define DD4HEP_USE_SAFE_CAST 1 + +/// Enable to have more debugging information for conditions and keys +/// If enabled it overrides DD4HEP_MINIMAL_CONDITIONS and sets it to true +/// If enabled it overrides DD4HEP_CONDITIONKEY_HAVE_NAME and sets it to true +#define DD4HEP_CONDITIONS_DEBUG 1 + /// Enable this if you want to minimize the footprint of conditions //#define DD4HEP_MINIMAL_CONDITIONS 1 +/// Enable flag to store conditions names to keys (needs some support from user code!) +//#define DD4HEP_CONDITIONKEY_HAVE_NAME 1 -#define DD4HEP_CONDITIONS_DEBUG 1 /// Valid implementations of the Gaudi plugin service are 1 and 2 #define DD4HEP_PLUGINSVC_VERSION 2 @@ -33,9 +40,15 @@ /// Namespace for the AIDA detector description toolkit namespace dd4hep { + /// Namespace for the conditions part of the AIDA detector description toolkit + namespace cond { + } /* End namespace cond */ + /// Namespace for implementation details of the AIDA detector description toolkit namespace detail { - + /// Namespace for the AIDA detector description matrix helpers + namespace matrix { + } /* End namespace matrix */ } /* End namespace detail */ -} /* End namespace dd4hep */ +} /* End namespace dd4hep */ #endif /* DD4HEP_CONFIG_H */ diff --git a/DDCore/include/DD4hep/detail/ConditionsInterna.h b/DDCore/include/DD4hep/detail/ConditionsInterna.h index ef3f8d728..c5764e2cb 100644 --- a/DDCore/include/DD4hep/detail/ConditionsInterna.h +++ b/DDCore/include/DD4hep/detail/ConditionsInterna.h @@ -57,14 +57,14 @@ namespace dd4hep { * \ingroup DD4HEP_CONDITIONS */ class ConditionObject -#if !defined(DD4HEP_MINIMAL_CONDITIONS) +#if defined(DD4HEP_CONDITIONS_DEBUG) || !defined(DD4HEP_MINIMAL_CONDITIONS) : public NamedObject #endif { public: /// Condition value (in string form) std::string value; -#if !defined(DD4HEP_MINIMAL_CONDITIONS) +#if defined(DD4HEP_CONDITIONS_DEBUG) || !defined(DD4HEP_MINIMAL_CONDITIONS) /// Condition validity (in string form) std::string validity; /// Condition address diff --git a/DDCore/include/DD4hep/detail/ShapesInterna.h b/DDCore/include/DD4hep/detail/ShapesInterna.h new file mode 100644 index 000000000..55ace5724 --- /dev/null +++ b/DDCore/include/DD4hep/detail/ShapesInterna.h @@ -0,0 +1,76 @@ +//========================================================================== +// 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_SHAPESINTERNA_H +#define DD4HEP_DDCORE_SHAPESINTERNA_H + +// Framework include files +#include "DD4hep/Shapes.h" + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Concrete object implementation for the Header handle + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CORE + */ + class TwistedTubeObject: public TGeoTubeSeg { + private: + /// Inhibit move constructor + TwistedTubeObject(TwistedTubeObject&&) = delete; + /// Inhibit copy constructor + TwistedTubeObject(const TwistedTubeObject&) = delete; + /// Inhibit move assignment + TwistedTubeObject& operator=(TwistedTubeObject&&) = delete; + /// Inhibit copy assignment + TwistedTubeObject& operator=(const TwistedTubeObject&) = delete; + public: + double fPhiTwist {0}; // Twist angle from -fZHalfLength to fZHalfLength + double fNegativeEndz {0}; // -ve z endplate + double fPositiveEndz {0}; // +ve z endplate + int fNsegments {0}; // Number of segments in totalPhi + + public: + /// Standard constructor + TwistedTubeObject() = default; + /// Initializing constructor + TwistedTubeObject(const char* pName, + double twistedangle, // Twisted angle + double endinnerrad, // Inner radius at endcap + double endouterrad, // Outer radius at endcap + double negativeEndz, // -ve z endplate + double positiveEndz, // +ve z endplate + int nseg, // Number of segments in totalPhi + double totphi); // Total angle of all segments + /// Default destructor + virtual ~TwistedTubeObject() = default; + /// Access twist angle + double GetPhiTwist () const { return fPhiTwist; } + /// Access the negative z + double GetNegativeEndZ() const { return fNegativeEndz; } + /// Access the positive z + double GetPositiveEndZ() const { return fPositiveEndz; } + /// Access the number of segments + int GetNsegments() const { return fNsegments; } + + /// in case shape has some negative parameters, these has to be computed in order to fit the mother + virtual TGeoShape *GetMakeRuntimeShape(TGeoShape *mother, TGeoMatrix * /*mat*/) const override; + /// print shape parameters + virtual void InspectShape() const override; + + ClassDefOverride(TwistedTubeObject,0); + }; +} /* End namespace dd4hep */ +#endif /* DD4HEP_DDCORE_SHAPESINTERNA_H */ diff --git a/DDCore/include/Parsers/detail/Dimension.h b/DDCore/include/Parsers/detail/Dimension.h index 4ec720438..0723a291f 100644 --- a/DDCore/include/Parsers/detail/Dimension.h +++ b/DDCore/include/Parsers/detail/Dimension.h @@ -155,6 +155,10 @@ namespace dd4hep { double startphi() const; /// Access rotation constants: startphi double startphi(double default_value) const; + /// Access rotation constants: twist + double twist() const; + /// Access rotation constants: twist + double twist(double default_value) const; /// Access parameters: a double a() const; @@ -364,9 +368,17 @@ namespace dd4hep { double dz() const; /// Access parameters: dz, if not present returns default double dz(double default_value) const; - /// Access min/max parameters: zmax + /// Access pos/neg parameters: zpos + double zpos() const; + /// Access pos/neg parameters: zpos + double zpos(double default_value) const; + /// Access pos/neg parameters: zneg + double zneg() const; + /// Access pos/neg parameters: zneg + double zneg(double default_value) const; + /// Access min/max parameters: zmin double zmin() const; - /// Access min/max parameters: zmax + /// Access min/max parameters: zmin double zmin(double default_value) const; /// Access min/max parameters: zmax double zmax() const; @@ -449,6 +461,8 @@ namespace dd4hep { /// Access attribute values: nmodules int nmodules() const; + /// Access attribute values: nsegments + int nsegments() const; /// Access attribute values: nModules int nModules() const; /// Access attribute values: RowID @@ -576,17 +590,17 @@ namespace dd4hep { /// Access min/max parameters: lunit double lunit(double default_value) const; - /// Access rotation constants: temperature + /// Access constants: temperature double temperature() const; - /// Access rotation constants: temperature + /// Access constants: temperature double temperature(double default_value) const; - /// Access rotation constants: pressure + /// Access constants: pressure double pressure() const; - /// Access rotation constants: pressure + /// Access constants: pressure double pressure(double default_value) const; - /// Access rotation constants: density + /// Access constants: density double density() const; - /// Access rotation constants: density + /// Access constants: density double density(double default_value) const; /// Access child element with tag "dimensions" as Dimension object diff --git a/DDCore/include/Parsers/detail/Dimension.imp b/DDCore/include/Parsers/detail/Dimension.imp index 636cb512b..8bf5d2b6d 100644 --- a/DDCore/include/Parsers/detail/Dimension.imp +++ b/DDCore/include/Parsers/detail/Dimension.imp @@ -55,6 +55,8 @@ XML_ATTR_ACCESSOR_DOUBLE(dz) XML_ATTR_ACCESSOR_DOUBLE(z0) XML_ATTR_ACCESSOR_DOUBLE(z1) XML_ATTR_ACCESSOR_DOUBLE(z2) +XML_ATTR_ACCESSOR_DOUBLE(zpos) +XML_ATTR_ACCESSOR_DOUBLE(zneg) XML_ATTR_ACCESSOR_DOUBLE(zmin) XML_ATTR_ACCESSOR_DOUBLE(zmax) XML_ATTR_ACCESSOR_DOUBLE(z_offset) @@ -109,6 +111,7 @@ XML_ATTR_ACCESSOR_DOUBLE(phi1) XML_ATTR_ACCESSOR_DOUBLE(phi2) XML_ATTR_ACCESSOR_DOUBLE(deltaphi) XML_ATTR_ACCESSOR_DOUBLE(startphi) +XML_ATTR_ACCESSOR_DOUBLE(twist) XML_ATTR_ACCESSOR(double, length) XML_ATTR_ACCESSOR(double, width) @@ -163,6 +166,7 @@ XML_ATTR_ACCESSOR(bool, nocore) XML_ATTR_ACCESSOR_BOOL(nocore) XML_ATTR_ACCESSOR(int, nmodules) +XML_ATTR_ACCESSOR(int, nsegments) XML_ATTR_ACCESSOR(int, nModules) XML_ATTR_ACCESSOR(int, RowID) XML_ATTR_ACCESSOR(int, nPads) diff --git a/DDCore/include/XML/UnicodeValues.h b/DDCore/include/XML/UnicodeValues.h index a09cb70cd..b5dd9437b 100644 --- a/DDCore/include/XML/UnicodeValues.h +++ b/DDCore/include/XML/UnicodeValues.h @@ -298,6 +298,7 @@ UNICODE (ntheta); UNICODE (number); UNICODE (numsides); UNICODE (nsides); +UNICODE (nsegments); UNICODE (nsides_inner); UNICODE (nsides_outer); UNICODE (nz); @@ -488,6 +489,7 @@ UNICODE (true); UNICODE (tube); UNICODE (tubes); UNICODE (tubs); +UNICODE (twist); UNICODE (type); UNICODE (types); UNICODE (tx); @@ -581,6 +583,8 @@ UNICODE (z4); UNICODE (Zeff); UNICODE (zhalf); UNICODE (zmin); +UNICODE (zneg); +UNICODE (zpos); UNICODE (zmax); UNICODE (zplane); UNICODE (zstart); diff --git a/DDCore/src/ConditionDerived.cpp b/DDCore/src/ConditionDerived.cpp index e5401f9d1..777d28d53 100644 --- a/DDCore/src/ConditionDerived.cpp +++ b/DDCore/src/ConditionDerived.cpp @@ -55,7 +55,7 @@ Condition ConditionUpdateContext::condition(const ConditionKey& key_value) cons iov->iov_intersection(c.iov()); return c; } -#ifdef DD4HEP_CONDITIONS_DEBUG +#if defined(DD4HEP_CONDITIONS_DEBUG) || defined(DD4HEP_CONDITIONKEY_HAVE_NAME) except("ConditionUpdateCall:","Failed to access non-existing condition:"+key_value.name); #else ConditionKey::KeyMaker key(key_value.hash); @@ -117,7 +117,7 @@ ConditionResolver::~ConditionResolver() { /// Throw exception on conditions access failure void ConditionUpdateContext::accessFailure(const ConditionKey& key_value) const { -#ifdef DD4HEP_CONDITIONS_DEBUG +#if defined(DD4HEP_CONDITIONS_DEBUG) || defined(DD4HEP_CONDITIONKEY_HAVE_NAME) except("ConditionUpdateCall", "%s [%016llX]: FAILED to access non-existing item:%s [%016llX]", dependency->target.name.c_str(), dependency->target.hash, diff --git a/DDCore/src/Conditions.cpp b/DDCore/src/Conditions.cpp index 1e6689714..15a457e9e 100644 --- a/DDCore/src/Conditions.cpp +++ b/DDCore/src/Conditions.cpp @@ -23,6 +23,14 @@ using namespace std; using namespace dd4hep; +#if defined(DD4HEP_CONDITIONS_DEBUG) && !defined(DD4HEP_CONDITIONKEY_HAVE_NAME) +#define DD4HEP_CONDITIONKEY_HAVE_NAME 1 +#endif + +#if defined(DD4HEP_CONDITIONS_DEBUG) && defined(DD4HEP_MINIMAL_CONDITIONS) +#undef DD4HEP_MINIMAL_CONDITIONS +#endif + /// Initializing constructor for a pure, undecorated conditions object Condition::Condition(key_type hash_key) : Handle<Object>() { @@ -269,7 +277,7 @@ string ConditionKey::toString() const { dd4hep::ConditionKey::KeyMaker key(hash); char text[64]; ::snprintf(text,sizeof(text),"%08X-%08X",key.values.det_key, key.values.item_key); -#if !defined(DD4HEP_MINIMAL_CONDITIONS) +#if defined(DD4HEP_CONDITIONS_DEBUG) || defined(DD4HEP_CONDITIONKEY_HAVE_NAME) if ( !name.empty() ) { stringstream str; str << "(" << name << ") " << text; diff --git a/DDCore/src/ConditionsInterna.cpp b/DDCore/src/ConditionsInterna.cpp index 3393cd5c7..eca1e178e 100644 --- a/DDCore/src/ConditionsInterna.cpp +++ b/DDCore/src/ConditionsInterna.cpp @@ -20,7 +20,7 @@ using namespace std; using namespace dd4hep; -#if defined(DD4HEP_MINIMAL_CONDITIONS) +#if !defined(DD4HEP_CONDITIONS_DEBUG) && defined(DD4HEP_MINIMAL_CONDITIONS) DD4HEP_INSTANTIATE_HANDLE_UNNAMED(detail::ConditionObject); #else DD4HEP_INSTANTIATE_HANDLE_NAMED(detail::ConditionObject); @@ -44,7 +44,7 @@ detail::ConditionObject::ConditionObject() } /// Standard constructor -#if defined(DD4HEP_MINIMAL_CONDITIONS) +#if !defined(DD4HEP_CONDITIONS_DEBUG) && defined(DD4HEP_MINIMAL_CONDITIONS) detail::ConditionObject::ConditionObject(const string& ,const string& ) : data() #else diff --git a/DDCore/src/GeoDictionary.h b/DDCore/src/GeoDictionary.h index 3bc5f3791..2b5892d69 100644 --- a/DDCore/src/GeoDictionary.h +++ b/DDCore/src/GeoDictionary.h @@ -20,6 +20,7 @@ #include "DD4hep/Volumes.h" #include "DD4hep/Shapes.h" #include "DD4hep/VolumeProcessor.h" +#include "DD4hep/detail/ShapesInterna.h" // C/C++ include files #include <vector> @@ -132,5 +133,9 @@ template vector<pair<string, int> >::iterator; #pragma link C++ class dd4hep::PlacedVolumeProcessor+; #pragma link C++ class dd4hep::PlacedVolumeScanner+; +#pragma link C++ class dd4hep::TwistedTube+; +#pragma link C++ class dd4hep::Solid_type<dd4hep::TwistedTubeObject>+; +#pragma link C++ class dd4hep::TwistedTubeObject+; + #endif // __CINT__ #endif /* DD4HEP_DDCORE_ROOTDICTIONARY_H */ diff --git a/DDCore/src/Handle.cpp b/DDCore/src/Handle.cpp index d320e905a..01504728e 100644 --- a/DDCore/src/Handle.cpp +++ b/DDCore/src/Handle.cpp @@ -372,6 +372,7 @@ DD4HEP_INSTANTIATE_HANDLE(TGeoNodeOffset); #include "TGeoVolume.h" #include "TGeoCompositeShape.h" #include "TGeoShapeAssembly.h" +#include "DD4hep/detail/ShapesInterna.h" DD4HEP_INSTANTIATE_HANDLE(TGeoVolumeAssembly,TGeoVolume,TGeoAtt); DD4HEP_INSTANTIATE_HANDLE(TGeoVolumeMulti,TGeoVolume,TGeoAtt); DD4HEP_INSTANTIATE_HANDLE(TGeoVolume,TGeoAtt,TAttLine,TAtt3D); @@ -392,6 +393,8 @@ DD4HEP_INSTANTIATE_SHAPE_HANDLE(TGeoHype,TGeoTube); DD4HEP_INSTANTIATE_SHAPE_HANDLE(TGeoEltu,TGeoTube); DD4HEP_INSTANTIATE_SHAPE_HANDLE(TGeoTubeSeg,TGeoTube); DD4HEP_INSTANTIATE_SHAPE_HANDLE(TGeoCtub,TGeoTubeSeg,TGeoTube); +using dd4hep::TwistedTubeObject; +DD4HEP_INSTANTIATE_SHAPE_HANDLE(TwistedTubeObject,TGeoTubeSeg); DD4HEP_INSTANTIATE_SHAPE_HANDLE(TGeoTrap,TGeoArb8); DD4HEP_INSTANTIATE_SHAPE_HANDLE(TGeoGtra,TGeoArb8); diff --git a/DDCore/src/ShapeTags.h b/DDCore/src/ShapeTags.h index fe8757407..b46d9cdf5 100644 --- a/DDCore/src/ShapeTags.h +++ b/DDCore/src/ShapeTags.h @@ -26,6 +26,7 @@ #define PARABOLOID_TAG "Paraboloid" #define HYPERBOLOID_TAG "Hyperboloid" #define ELLIPTICALTUBE_TAG "EllipticalTube" +#define TWISTEDTUBE_TAG "TwistedTube" #define SPHERE_TAG "Sphere" #define TORUS_TAG "Torus" #define TRAP_TAG "Trap" diff --git a/DDCore/src/ShapeUtilities.cpp b/DDCore/src/ShapeUtilities.cpp index 1daeb2ab7..bf0569bad 100644 --- a/DDCore/src/ShapeUtilities.cpp +++ b/DDCore/src/ShapeUtilities.cpp @@ -18,6 +18,7 @@ #include "DD4hep/MatrixHelpers.h" #include "DD4hep/DD4hepUnits.h" #include "DD4hep/Printout.h" +#include "DD4hep/detail/ShapesInterna.h" #include "ShapeTags.h" // C/C++ include files @@ -82,7 +83,9 @@ namespace dd4hep { return check_shape_type<TGeoConeSeg>(solid) || check_shape_type<TGeoCone>(solid); } template <> bool isInstance<Tube>(const Handle<TGeoShape>& solid) { - return check_shape_type<TGeoTubeSeg>(solid) || check_shape_type<TGeoCtub>(solid); + return check_shape_type<TGeoTubeSeg>(solid) + || check_shape_type<TGeoCtub>(solid) + || check_shape_type<TwistedTubeObject>(solid); } template <> bool isInstance<Polycone>(const Handle<TGeoShape>& solid) { return check_shape_type<TGeoPcon>(solid) || check_shape_type<TGeoPgon>(solid); @@ -94,6 +97,9 @@ namespace dd4hep { } return false; } + template <> bool isInstance<TwistedTube>(const Handle<TGeoShape>& solid) { + return check_shape_type<TwistedTubeObject>(solid); + } template <> bool isInstance<TruncatedTube>(const Handle<TGeoShape>& solid) { return check_shape_type<TGeoCompositeShape>(solid) && ::strcmp(solid->GetTitle(), TRUNCATEDTUBE_TAG) == 0; @@ -143,6 +149,10 @@ namespace dd4hep { template bool isA<Polycone>(const Handle<TGeoShape>& solid); template bool isA<EightPointSolid>(const Handle<TGeoShape>& solid); + template <> bool isA<TwistedTube>(const Handle<TGeoShape>& solid) { + return check_shape_type<TwistedTubeObject>(solid) + && ::strcmp(solid->GetTitle(), TWISTEDTUBE_TAG) == 0; + } template <> bool isA<TruncatedTube>(const Handle<TGeoShape>& solid) { return check_shape_type<TGeoCompositeShape>(solid) && ::strcmp(solid->GetTitle(), TRUNCATEDTUBE_TAG) == 0; @@ -219,6 +229,12 @@ namespace dd4hep { const TGeoTubeSeg* sh = get_ptr<TGeoTubeSeg>(shape); return { sh->GetRmin(), sh->GetRmax(), sh->GetDz(), sh->GetPhi1()*units::deg, sh->GetPhi2()*units::deg }; } + template <> vector<double> dimensions<TwistedTubeObject>(const TGeoShape* shape) { + const TwistedTubeObject* sh = get_ptr<TwistedTubeObject>(shape); + return { sh->GetPhiTwist(), sh->GetRmin(), sh->GetRmax(), + sh->GetNegativeEndZ(), sh->GetPositiveEndZ(), + double(sh->GetNsegments()), sh->GetPhi2()*units::deg }; + } template <> vector<double> dimensions<TGeoCtub>(const TGeoShape* shape) { const TGeoCtub* sh = get_ptr<TGeoCtub>(shape); const Double_t* lo = sh->GetNlow(); @@ -353,6 +369,7 @@ namespace dd4hep { template vector<double> dimensions<ConeSegment> (const Handle<TGeoShape>& shape); template vector<double> dimensions<Tube> (const Handle<TGeoShape>& shape); template vector<double> dimensions<CutTube> (const Handle<TGeoShape>& shape); + template vector<double> dimensions<TwistedTube> (const Handle<TGeoShape>& shape); template vector<double> dimensions<EllipticalTube> (const Handle<TGeoShape>& shape); template vector<double> dimensions<Cone> (const Handle<TGeoShape>& shape); template vector<double> dimensions<Trap> (const Handle<TGeoShape>& shape); @@ -418,6 +435,8 @@ namespace dd4hep { return dimensions<TGeoBBox>(shape.ptr()); else if (cl == TGeoHalfSpace::Class()) return dimensions<TGeoHalfSpace>(shape.ptr()); + else if (cl == TGeoPgon::Class()) + return dimensions<TGeoPgon>(shape.ptr()); else if (cl == TGeoPcon::Class()) return dimensions<TGeoPcon>(shape.ptr()); else if (cl == TGeoConeSeg::Class()) @@ -432,6 +451,8 @@ namespace dd4hep { return dimensions<TGeoCtub>(shape.ptr()); else if (cl == TGeoEltu::Class()) return dimensions<TGeoEltu>(shape.ptr()); + else if (cl == TwistedTubeObject::Class()) + return dimensions<TwistedTubeObject>(shape.ptr()); else if (cl == TGeoTrd1::Class()) return dimensions<TGeoTrd1>(shape.ptr()); else if (cl == TGeoTrd2::Class()) @@ -550,6 +571,24 @@ namespace dd4hep { pars[4] /= units::deg; Solid(sh)._setDimensions(&pars[0]); } + template <> void set_dimensions(TwistedTubeObject* sh, const std::vector<double>& params) { + if ( params.size() != 7 ) { + invalidSetDimensionCall(sh,params); + } + auto pars = params; + sh->fPhiTwist = pars[0]/units::deg; + sh->fNegativeEndz = pars[3]; + sh->fPositiveEndz = pars[4]; + sh->fNsegments = (int)pars[5]; + + pars[0] = pars[1]; + pars[1] = pars[2]; + pars[2] = (pars[3]+pars[4])/2.0; + pars[3] = 0.0; + pars[4] = pars[6]; + pars.resize(5); + set_dimensions((TGeoTubeSeg*)sh, pars); + } template <> void set_dimensions(TGeoCtub* sh, const std::vector<double>& params) { if ( params.size() != 11 ) { invalidSetDimensionCall(sh,params); @@ -615,7 +654,7 @@ namespace dd4hep { } template <> void set_dimensions(TGeoPgon* sh, const std::vector<double>& params) { auto pars = params; - if ( params.size() != 3 + 3*size_t(params[2]) ) { + if ( params.size() < 4 || params.size() != 4 + 3*size_t(params[3]) ) { invalidSetDimensionCall(sh,params); } pars[0] /= units::deg; @@ -624,7 +663,7 @@ namespace dd4hep { } template <> void set_dimensions(TGeoXtru* sh, const std::vector<double>& params) { auto pars = params; - if ( params.size() != 1 + 4*size_t(params[0]) ) { + if ( params.size() < 1 || params.size() != 1 + 4*size_t(params[0]) ) { invalidSetDimensionCall(sh,params); } Solid(sh)._setDimensions(&pars[0]); @@ -697,6 +736,8 @@ namespace dd4hep { { set_dimensions(shape.ptr(), params); } template <> void set_dimensions(CutTube shape, const std::vector<double>& params) { set_dimensions(shape.ptr(), params); } + template <> void set_dimensions(TwistedTube shape, const std::vector<double>& params) + { set_dimensions(shape.ptr(), params); } template <> void set_dimensions(EllipticalTube shape, const std::vector<double>& params) { set_dimensions(shape.ptr(), params); } template <> void set_dimensions(Trap shape, const std::vector<double>& params) @@ -899,6 +940,8 @@ namespace dd4hep { set_dimensions(CutTube(shape), params); else if (cl == TGeoEltu::Class()) set_dimensions(EllipticalTube(shape), params); + else if (cl == TwistedTubeObject::Class()) + set_dimensions(TwistedTube(shape), params); else if (cl == TGeoTrd1::Class()) set_dimensions(Trd1(shape), params); else if (cl == TGeoTrd2::Class()) diff --git a/DDCore/src/Shapes.cpp b/DDCore/src/Shapes.cpp index 893a073dc..6e604d9df 100644 --- a/DDCore/src/Shapes.cpp +++ b/DDCore/src/Shapes.cpp @@ -18,6 +18,7 @@ #include "DD4hep/MatrixHelpers.h" #include "DD4hep/DD4hepUnits.h" #include "DD4hep/Printout.h" +#include "DD4hep/detail/ShapesInterna.h" #include "ShapeTags.h" // C/C++ include files @@ -436,6 +437,13 @@ void EllipticalTube::make(const string& nam, double a, double b, double dz) { _assign(new TGeoEltu(nam.c_str(), a, b, dz), "", ELLIPTICALTUBE_TAG, true); } +/// Internal helper method to support TwistedTube object construction +void TwistedTube::make(const std::string& nam, double twist_angle, double rmin, double rmax, + double zneg, double zpos, int nsegments, double totphi) { + _assign(new TwistedTubeObject(nam.c_str(), twist_angle, rmin, rmax, zneg, zpos, nsegments, totphi/units::deg), + "", TWISTEDTUBE_TAG, true); +} + /// Constructor to be used when creating a new object with attribute initialization void Trd1::make(const string& nam, double x1, double x2, double y, double z) { _assign(new TGeoTrd1(nam.c_str(), x1, x2, y, z ), "", TRD1_TAG, true); diff --git a/DDCore/src/ShapesInterna.cpp b/DDCore/src/ShapesInterna.cpp new file mode 100644 index 000000000..30da0c302 --- /dev/null +++ b/DDCore/src/ShapesInterna.cpp @@ -0,0 +1,77 @@ +//========================================================================== +// 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 includes +#include "DD4hep/Printout.h" +#include "DD4hep/detail/ShapesInterna.h" + +// C/C++ include files +#include <climits> +#include <iomanip> +#include <cstdio> + +using namespace std; +using namespace dd4hep; + +ClassImp(dd4hep::TwistedTubeObject) + +/// Initializing constructor +TwistedTubeObject::TwistedTubeObject(const char* pName, + double twistedangle, // Twisted angle + double innerrad, // Inner radius at endcap + double outerrad, // Outer radius at endcap + double negativeEndz, // -ve z endplate + double positiveEndz, // +ve z endplate + int nseg, // Number of segments in totalPhi + double totphi) // Total angle of all segments + : TGeoTubeSeg(pName, innerrad, outerrad, (-negativeEndz+positiveEndz)/2.0, 0, totphi), + fPhiTwist(twistedangle), fNegativeEndz(negativeEndz), fPositiveEndz(positiveEndz), fNsegments(nseg) +{ +} + + +/// print shape parameters +void TwistedTubeObject::InspectShape() const { + printf("*** Shape TwistedTubeObject %s: ***\n", GetName()); + printf(" Rmin = %11.5f\n", GetRmin()); + printf(" Rmax = %11.5f\n", GetRmax()); + printf(" dz = %11.5f\n", GetDz()); + printf(" phi1 = %11.5f\n", GetPhi1()); + printf(" phi2 = %11.5f\n", GetPhi2()); + printf(" negativeEndz = %11.5f\n", GetNegativeEndZ()); + printf(" positiveEndz = %11.5f\n", GetPositiveEndZ()); + printf(" Nsegemnts = %11.d\n", GetNsegments()); + printf(" Bounding box:\n"); + TGeoBBox::InspectShape(); +} + +/// in case shape has some negative parameters, these has to be computed in order to fit the mother + +TGeoShape *TwistedTubeObject::GetMakeRuntimeShape(TGeoShape *mother, TGeoMatrix * /*mat*/) const +{ + if (!TestShapeBit(kGeoRunTimeShape)) return 0; + if (!mother->TestShapeBit(kGeoTube)) { + Error("GetMakeRuntimeShape", "Invalid mother for shape %s", GetName()); + return 0; + } + Double_t rmin = fRmin; + Double_t rmax = fRmax; + if (fRmin<0) + rmin = ((TGeoTube*)mother)->GetRmin(); + if ((fRmax<0) || (fRmax<=fRmin)) + rmax = ((TGeoTube*)mother)->GetRmax(); + + return (new TwistedTubeObject(GetName(), GetPhiTwist(), rmin, rmax, + GetNegativeEndZ(), GetPositiveEndZ(), + GetNsegments(), GetPhi2())); +} diff --git a/DDCore/src/plugins/ShapePlugins.cpp b/DDCore/src/plugins/ShapePlugins.cpp index 1c1014d71..25976c16c 100644 --- a/DDCore/src/plugins/ShapePlugins.cpp +++ b/DDCore/src/plugins/ShapePlugins.cpp @@ -15,6 +15,7 @@ #include "DD4hep/DetFactoryHelper.h" #include "DD4hep/Printout.h" #include "XML/Utilities.h" +#include "../ShapeTags.h" #include "TGeoShapeAssembly.h" #include "TSystem.h" #include "TClass.h" @@ -101,6 +102,28 @@ static Handle<TObject> create_Tube(Detector&, xml_h element) { } DECLARE_XML_SHAPE(Tube__shape_constructor,create_Tube) +static Handle<TObject> create_TwistedTube(Detector&, xml_h element) { + xml_dim_t e(element); + Solid solid; + int nseg = 1; + double zpos = 0.0, zneg = 0.0; + if ( element.attr_nothrow(_U(nsegments)) ) { + nseg = e.nsegments(); + } + if ( element.attr_nothrow(_U(dz)) ) { + zneg = -1.0*(zpos = e.dz()); + } + else { + zpos = e.zpos(); + zneg = e.zneg(); + } + solid = TwistedTube(e.twist(0.0), e.rmin(0.0),e.rmax(),zpos, zneg, nseg, e.deltaphi(2*M_PI)); + + if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<string>(_U(name)).c_str()); + return solid; +} +DECLARE_XML_SHAPE(TwistedTube__shape_constructor,create_TwistedTube) + static Handle<TObject> create_CutTube(Detector&, xml_h element) { xml_dim_t e(element); Solid solid = CutTube(e.rmin(0.0),e.rmax(),e.dz(), @@ -545,53 +568,59 @@ static Ref_t create_shape(Detector& description, xml_h e, Ref_t /* sens */) { printout(INFO,"TestShape","Created successfull shape of type: %s", shape.typeStr().c_str()); bool instance_test = false; - if ( 0 == strcasecmp(solid->GetTitle(),"box") ) + if ( 0 == strcasecmp(solid->GetTitle(),BOX_TAG) ) instance_test = isInstance<Box>(solid); - else if ( 0 == strcasecmp(solid->GetTitle(),"Tube") ) + else if ( 0 == strcasecmp(solid->GetTitle(),TUBE_TAG) ) instance_test = isInstance<Tube>(solid); - else if ( 0 == strcasecmp(solid->GetTitle(),"CutTube") ) + else if ( 0 == strcasecmp(solid->GetTitle(),CUTTUBE_TAG) ) instance_test = isInstance<CutTube>(solid); - else if ( 0 == strcasecmp(solid->GetTitle(),"Cone") ) + else if ( 0 == strcasecmp(solid->GetTitle(),CONE_TAG) ) instance_test = isInstance<Cone>(solid); - else if ( 0 == strcasecmp(solid->GetTitle(),"Trd1") ) + else if ( 0 == strcasecmp(solid->GetTitle(),TRD1_TAG) ) instance_test = isInstance<Trd1>(solid); - else if ( 0 == strcasecmp(solid->GetTitle(),"Trd2") ) + else if ( 0 == strcasecmp(solid->GetTitle(),TRD2_TAG) ) instance_test = isInstance<Trd2>(solid); - else if ( 0 == strcasecmp(solid->GetTitle(),"Torus") ) + else if ( 0 == strcasecmp(solid->GetTitle(),TORUS_TAG) ) instance_test = isInstance<Torus>(solid); - else if ( 0 == strcasecmp(solid->GetTitle(),"Sphere") ) + else if ( 0 == strcasecmp(solid->GetTitle(),SPHERE_TAG) ) instance_test = isInstance<Sphere>(solid); - else if ( 0 == strcasecmp(solid->GetTitle(),"HalfSpace") ) + else if ( 0 == strcasecmp(solid->GetTitle(),HALFSPACE_TAG) ) instance_test = isInstance<HalfSpace>(solid); - else if ( 0 == strcasecmp(solid->GetTitle(),"ConeSegment") ) + else if ( 0 == strcasecmp(solid->GetTitle(),CONESEGMENT_TAG) ) instance_test = isInstance<ConeSegment>(solid); - else if ( 0 == strcasecmp(solid->GetTitle(),"Paraboloid") ) + else if ( 0 == strcasecmp(solid->GetTitle(),PARABOLOID_TAG) ) instance_test = isInstance<Paraboloid>(solid); - else if ( 0 == strcasecmp(solid->GetTitle(),"Hyperboloid") ) + else if ( 0 == strcasecmp(solid->GetTitle(),HYPERBOLOID_TAG) ) instance_test = isInstance<Hyperboloid>(solid); else if ( 0 == strcasecmp(solid->GetTitle(),"PolyhedraRegular") ) instance_test = isInstance<PolyhedraRegular>(solid); - else if ( 0 == strcasecmp(solid->GetTitle(),"Polyhedra") ) + else if ( 0 == strcasecmp(solid->GetTitle(),POLYHEDRA_TAG) ) instance_test = isInstance<Polyhedra>(solid); - else if ( 0 == strcasecmp(solid->GetTitle(),"EllipticalTube") ) + else if ( 0 == strcasecmp(solid->GetTitle(),ELLIPTICALTUBE_TAG) ) instance_test = isInstance<EllipticalTube>(solid); - else if ( 0 == strcasecmp(solid->GetTitle(),"ExtrudedPolygon") ) + else if ( 0 == strcasecmp(solid->GetTitle(),EXTRUDEDPOLYGON_TAG) ) instance_test = isInstance<ExtrudedPolygon>(solid); - else if ( 0 == strcasecmp(solid->GetTitle(),"Polycone") ) + else if ( 0 == strcasecmp(solid->GetTitle(),POLYCONE_TAG) ) instance_test = isInstance<Polycone>(solid); - else if ( 0 == strcasecmp(solid->GetTitle(),"EightPointSolid") ) { + else if ( 0 == strcasecmp(solid->GetTitle(),TWISTEDTUBE_TAG) ) { + instance_test = isInstance<TwistedTube>(solid); + instance_test &= isInstance<Tube>(solid); + instance_test &= isA<TwistedTube>(solid); + instance_test &= !isA<Tube>(solid); + } + else if ( 0 == strcasecmp(solid->GetTitle(),EIGHTPOINTSOLID_TAG) ) { instance_test = isInstance<EightPointSolid>(solid); instance_test &= !isInstance<Trap>(solid); instance_test &= isA<EightPointSolid>(solid); instance_test &= !isA<Trap>(solid); } - else if ( 0 == strcasecmp(solid->GetTitle(),"Trap") ) { + else if ( 0 == strcasecmp(solid->GetTitle(),TRAP_TAG) ) { instance_test = isInstance<EightPointSolid>(solid); instance_test &= isInstance<Trap>(solid); instance_test &= isA<Trap>(solid); instance_test &= !isA<EightPointSolid>(solid); } - else if ( 0 == strcasecmp(solid->GetTitle(),"SubtractionSolid") ) { + else if ( 0 == strcasecmp(solid->GetTitle(),SUBTRACTION_TAG) ) { instance_test = isInstance<BooleanSolid>(solid); instance_test &= isInstance<SubtractionSolid>(solid); instance_test &= !isA<IntersectionSolid>(solid); @@ -599,7 +628,7 @@ static Ref_t create_shape(Detector& description, xml_h e, Ref_t /* sens */) { instance_test &= isA<SubtractionSolid>(solid); instance_test &= !isA<PseudoTrap>(solid); } - else if ( 0 == strcasecmp(solid->GetTitle(),"UnionSolid") ) { + else if ( 0 == strcasecmp(solid->GetTitle(),UNION_TAG) ) { instance_test = isInstance<BooleanSolid>(solid); instance_test &= isInstance<UnionSolid>(solid); instance_test &= !isA<IntersectionSolid>(solid); @@ -607,7 +636,7 @@ static Ref_t create_shape(Detector& description, xml_h e, Ref_t /* sens */) { instance_test &= !isA<SubtractionSolid>(solid); instance_test &= !isA<PseudoTrap>(solid); } - else if ( 0 == strcasecmp(solid->GetTitle(),"IntersectionSolid") ) { + else if ( 0 == strcasecmp(solid->GetTitle(),INTERSECTION_TAG) ) { instance_test = isInstance<BooleanSolid>(solid); instance_test &= isInstance<IntersectionSolid>(solid); instance_test &= isA<IntersectionSolid>(solid); @@ -615,7 +644,7 @@ static Ref_t create_shape(Detector& description, xml_h e, Ref_t /* sens */) { instance_test &= !isA<SubtractionSolid>(solid); instance_test &= !isA<PseudoTrap>(solid); } - else if ( 0 == strcasecmp(solid->GetTitle(),"TruncatedTube") ) { + else if ( 0 == strcasecmp(solid->GetTitle(),TRUNCATEDTUBE_TAG) ) { instance_test = isInstance<BooleanSolid>(solid); instance_test &= isInstance<TruncatedTube>(solid); instance_test &= isA<TruncatedTube>(solid); @@ -624,7 +653,7 @@ static Ref_t create_shape(Detector& description, xml_h e, Ref_t /* sens */) { instance_test &= !isA<UnionSolid>(solid); instance_test &= !isA<SubtractionSolid>(solid); } - else if ( 0 == strcasecmp(solid->GetTitle(),"PseudoTrap") ) { + else if ( 0 == strcasecmp(solid->GetTitle(),PSEUDOTRAP_TAG) ) { instance_test = isInstance<BooleanSolid>(solid); instance_test &= isInstance<PseudoTrap>(solid); instance_test &= isA<PseudoTrap>(solid); diff --git a/DDG4/plugins/Geant4DetectorGeometryConstruction.cpp b/DDG4/plugins/Geant4DetectorGeometryConstruction.cpp index ea035da34..3666b6b37 100644 --- a/DDG4/plugins/Geant4DetectorGeometryConstruction.cpp +++ b/DDG4/plugins/Geant4DetectorGeometryConstruction.cpp @@ -58,6 +58,15 @@ namespace dd4hep { int m_geoInfoPrintLevel; /// Property: G4 GDML dump file name (default: empty. If non empty, dump) std::string m_dumpGDML; + /// Property: DD4hep path to volume to be printed (default: empty) + std::string m_volumePath; + + /// Write GDML file + int writeGDML(); + /// Print geant4 volume + int printVolume(); + /// Check geant4 volume + int checkVolume(); public: /// Initializing constructor for DDG4 @@ -66,23 +75,32 @@ namespace dd4hep { virtual ~Geant4DetectorGeometryConstruction(); /// Geometry construction callback. Called at "Construct()" void constructGeo(Geant4DetectorConstructionContext* ctxt); + /// Install command control messenger to write GDML file from command prompt. + virtual void installCommandMessenger() override; }; } // End namespace sim } // End namespace dd4hep // Framework include files -#include "DD4hep/InstanceCount.h" -#include "DD4hep/Printout.h" -#include "DD4hep/Detector.h" +#include <DD4hep/InstanceCount.h> +#include <DD4hep/DetectorTools.h> +#include "DD4hep/DD4hepUnits.h" +#include <DD4hep/Printout.h> +#include <DD4hep/Detector.h> #include "DDG4/Geant4HierarchyDump.h" +#include "DDG4/Geant4UIMessenger.h" #include "DDG4/Geant4Converter.h" #include "DDG4/Geant4Kernel.h" #include "DDG4/Factories.h" // Geant4 include files +#include <G4LogicalVolume.hh> #include "G4PVPlacement.hh" +#include <G4Material.hh> +#include <G4VSolid.hh> + //#ifdef GEANT4_HAS_GDML #include "G4GDMLParser.hh" //#endif @@ -94,7 +112,7 @@ DECLARE_GEANT4ACTION(Geant4DetectorGeometryConstruction) /// Initializing constructor for other clients Geant4DetectorGeometryConstruction::Geant4DetectorGeometryConstruction(Geant4Context* ctxt, const string& nam) - : Geant4DetectorConstruction(ctxt,nam) +: Geant4DetectorConstruction(ctxt,nam) { declareProperty("DebugMaterials", m_debugMaterials); declareProperty("DebugElements", m_debugElements); @@ -110,6 +128,7 @@ Geant4DetectorGeometryConstruction::Geant4DetectorGeometryConstruction(Geant4Con declareProperty("DumpHierarchy", m_dumpHierarchy); declareProperty("DumpGDML", m_dumpGDML=""); + declareProperty("VolumePath", m_volumePath=""); InstanceCount::increment(this); } @@ -143,19 +162,111 @@ void Geant4DetectorGeometryConstruction::constructGeo(Geant4DetectorConstruction Geant4HierarchyDump dmp(ctxt->description); dmp.dump("",w); } + ctxt->world = w; + if ( !m_dumpGDML.empty() || ::getenv("DUMP_GDML") ) writeGDML(); + enableUI(); +} + +/// Print geant4 volume +int Geant4DetectorGeometryConstruction::printVolume() { + if ( !m_volumePath.empty() ) { + Detector& det = context()->kernel().detectorDescription(); + PlacedVolume top = det.world().placement(); + PlacedVolume pv = detail::tools::findNode(top, m_volumePath); + if ( pv.isValid() ) { + auto& g4map = Geant4Mapping::instance().data(); + auto it = g4map.g4Volumes.find(pv.volume()); + if ( it != g4map.g4Volumes.end() ) { + const G4LogicalVolume* vol = (*it).second; + auto* sol = vol->GetSolid(); + string txt; + stringstream str; + str << *(vol->GetMaterial()) << endl; + str << *sol; + stringstream istr(str.str()); + printP2("+++ Dump of ROOT solid: %s", m_volumePath.c_str()); + pv.volume().solid()->InspectShape(); + printP2("+++ Dump of GEANT4 solid: %s", m_volumePath.c_str()); + while(istr.good()) { + getline(istr,txt); + printP2(txt.c_str()); + } + printP2("Shape: %s cubic volume: %8.3g mm^3 area: %8.3g mm^2", + sol->GetName().c_str(), sol->GetCubicVolume(), sol->GetSurfaceArea()); + return 1; + } + } + warning("+++ printVolume: FAILED to find the volume %s from the top volume",m_volumePath.c_str()); + } + warning("+++ printVolume: Property VolumePath not set. [Ignored]"); + return 0; +} + +/// Check geant4 volume +int Geant4DetectorGeometryConstruction::checkVolume() { + if ( !m_volumePath.empty() ) { + Detector& det = context()->kernel().detectorDescription(); + PlacedVolume top = det.world().placement(); + PlacedVolume pv = detail::tools::findNode(top, m_volumePath); + if ( pv.isValid() ) { + auto& g4map = Geant4Mapping::instance().data(); + auto it = g4map.g4Volumes.find(pv.volume()); + if ( it != g4map.g4Volumes.end() ) { + const G4LogicalVolume* vol = (*it).second; + auto* g4_sol = vol->GetSolid(); + Box rt_sol = pv.volume().solid(); + G4ThreeVector pMin, pMax; + double conv = (dd4hep::centimeter/CLHEP::centimeter)/2.0; + g4_sol->BoundingLimits(pMin,pMax); + printP2("Geant4 Shape: %s cubic volume: %8.3g mm^3 area: %8.3g mm^2", + g4_sol->GetName().c_str(), g4_sol->GetCubicVolume(), g4_sol->GetSurfaceArea()); + printP2("Geant4 Bounding box extends: %8.3g %8.3g %8.3g", + (pMax.x()-pMin.x())*conv, (pMax.y()-pMin.y())*conv, (pMax.z()-pMin.z())*conv); + printP2("ROOT Bounding box dimensions: %8.3g %8.3g %8.3g", + rt_sol->GetDX(), rt_sol->GetDY(), rt_sol->GetDZ()); + + return 1; + } + } + warning("+++ checkVolume: FAILED to find the volume %s from the top volume",m_volumePath.c_str()); + } + warning("+++ checkVolume: Property VolumePath not set. [Ignored]"); + return 0; +} + +/// Write GDML file +int Geant4DetectorGeometryConstruction::writeGDML() { + G4VPhysicalVolume* w = context()->world(); //#ifdef GEANT4_HAS_GDML if ( !m_dumpGDML.empty() ) { G4GDMLParser parser; parser.Write(m_dumpGDML.c_str(), w); + info("+++ writeGDML: Wrote GDML file: %s", m_dumpGDML.c_str()); + return 1; } else { const char* gdml_dmp = ::getenv("DUMP_GDML"); if ( gdml_dmp ) { G4GDMLParser parser; parser.Write(gdml_dmp, w); + info("+++ writeGDML: Wrote GDML file: %s", gdml_dmp); + return 1; } } + warning("+++ writeGDML: Neither property DumpGDML nor environment DUMP_GDML set. No file written!"); //#endif - ctxt->world = w; + return 0; +} + +/// Install command control messenger to write GDML file from command prompt. +void Geant4DetectorGeometryConstruction::installCommandMessenger() { + this->Geant4DetectorConstruction::installCommandMessenger(); + m_control->addCall("writeGDML", "GDML: write geometry to file: '"+m_dumpGDML+"' [uses property DumpGDML]", + Callback(this).make(&Geant4DetectorGeometryConstruction::writeGDML)); + m_control->addCall("printVolume", "Print Geant4 volume properties [uses property VolumePath]", + Callback(this).make(&Geant4DetectorGeometryConstruction::printVolume)); + m_control->addCall("checkVolume", "Check Geant4 volume properties [uses property VolumePath]", + Callback(this).make(&Geant4DetectorGeometryConstruction::checkVolume)); } + diff --git a/DDG4/src/Geant4Converter.cpp b/DDG4/src/Geant4Converter.cpp index efc6f6b5d..4aed87219 100644 --- a/DDG4/src/Geant4Converter.cpp +++ b/DDG4/src/Geant4Converter.cpp @@ -107,26 +107,16 @@ void Geant4AssemblyVolume::imprint(Geant4GeometryInfo& info, G4int copyNumBase, G4bool surfCheck ) { - TGeoVolume* vol = parent->GetVolume(); static int level=0; - ++level; - - - unsigned int numberOfDaughters; + TGeoVolume* vol = parent->GetVolume(); + unsigned int numberOfDaughters = + (copyNumBase == 0) ? pMotherLV->GetNoDaughters() : copyNumBase; - if( copyNumBase == 0 ) - { - numberOfDaughters = pMotherLV->GetNoDaughters(); - } - else - { - numberOfDaughters = copyNumBase; - } + ++level; // We start from the first available index // numberOfDaughters++; - ImprintsCountPlus(); vector<G4AssemblyTriplet> triplets = pAssembly->fTriplets; @@ -1028,20 +1018,20 @@ void* Geant4Converter::handleLimitSet(LimitSet limitset, const set<const TGeoVol /// Convert the geometry visualisation attributes to the corresponding Geant4 object(s). void* Geant4Converter::handleVis(const string& /* name */, VisAttr attr) const { Geant4GeometryInfo& info = data(); - G4VisAttributes* g4 = info.g4Vis[attr]; - if (!g4) { + G4VisAttributes* g4 = info.g4Vis[attr]; + if ( !g4 ) { float red = 0, green = 0, blue = 0; - int style = attr.lineStyle(); + int style = attr.lineStyle(); attr.rgb(red, green, blue); g4 = new G4VisAttributes(attr.visible(), G4Colour(red, green, blue, attr.alpha())); //g4->SetLineWidth(attr->GetLineWidth()); g4->SetDaughtersInvisible(!attr.showDaughters()); - if (style == VisAttr::SOLID) { + if ( style == VisAttr::SOLID ) { g4->SetLineStyle(G4VisAttributes::unbroken); g4->SetForceWireframe(false); g4->SetForceSolid(true); } - else if (style == VisAttr::WIREFRAME || style == VisAttr::DASHED) { + else if ( style == VisAttr::WIREFRAME || style == VisAttr::DASHED ) { g4->SetLineStyle(G4VisAttributes::dashed); g4->SetForceSolid(false); g4->SetForceWireframe(true); diff --git a/DDG4/src/Geant4ShapeConverter.cpp b/DDG4/src/Geant4ShapeConverter.cpp index e79d2edb8..31d5c2723 100644 --- a/DDG4/src/Geant4ShapeConverter.cpp +++ b/DDG4/src/Geant4ShapeConverter.cpp @@ -144,28 +144,26 @@ namespace dd4hep { template <> G4VSolid* convertShape<TGeoPgon>(const TGeoShape* shape) { const TGeoPgon* sh = (const TGeoPgon*) shape; - double phi_start = sh->GetPhi1() * DEGREE_2_RAD; - double phi_total = (sh->GetDphi() + sh->GetPhi1()) * DEGREE_2_RAD; vector<double> rmin, rmax, z; for (Int_t i = 0; i < sh->GetNz(); ++i) { rmin.emplace_back(sh->GetRmin(i) * CM_2_MM); rmax.emplace_back(sh->GetRmax(i) * CM_2_MM); z.emplace_back(sh->GetZ(i) * CM_2_MM); } - return new G4Polyhedra(sh->GetName(), phi_start, phi_total, sh->GetNedges(), sh->GetNz(), &z[0], &rmin[0], &rmax[0]); + return new G4Polyhedra(sh->GetName(), sh->GetPhi1() * DEGREE_2_RAD, sh->GetDphi() * DEGREE_2_RAD, + sh->GetNedges(), sh->GetNz(), &z[0], &rmin[0], &rmax[0]); } template <> G4VSolid* convertShape<TGeoPcon>(const TGeoShape* shape) { const TGeoPcon* sh = (const TGeoPcon*) shape; - double phi_start = sh->GetPhi1() * DEGREE_2_RAD; - double phi_total = (sh->GetDphi() + sh->GetPhi1()) * DEGREE_2_RAD; vector<double> rmin, rmax, z; for (Int_t i = 0; i < sh->GetNz(); ++i) { rmin.emplace_back(sh->GetRmin(i) * CM_2_MM); rmax.emplace_back(sh->GetRmax(i) * CM_2_MM); z.emplace_back(sh->GetZ(i) * CM_2_MM); } - return new G4Polycone(sh->GetName(), phi_start, phi_total, sh->GetNz(), &z[0], &rmin[0], &rmax[0]); + return new G4Polycone(sh->GetName(), sh->GetPhi1() * DEGREE_2_RAD, sh->GetDphi() * DEGREE_2_RAD, + sh->GetNz(), &z[0], &rmin[0], &rmax[0]); } template <> G4VSolid* convertShape<TGeoCone>(const TGeoShape* shape) { diff --git a/examples/ClientTests/CMakeLists.txt b/examples/ClientTests/CMakeLists.txt index 5da5b90e6..9c72d472f 100644 --- a/examples/ClientTests/CMakeLists.txt +++ b/examples/ClientTests/CMakeLists.txt @@ -191,7 +191,7 @@ dd4hep_add_test_reg( ClientTests_Save_ROOT_MiniTel_LONGTEST # Test basic shapes by comparing mesh vertices with reference file foreach (test Box Cone ConeSegment Tube ElTube CutTube Hyperboloid Paraboloid EightPointSolid Eightpoint_Reflect_Volume Eightpoint_Reflect_DetElement - Polycone PseudoTrap PseudoTrap2 Sphere Torus + Polycone Polyheadra PseudoTrap PseudoTrap2 Sphere Torus Trap Trd1 Trd2 TruncatedTube ExtrudedPolygon) dd4hep_add_test_reg( ClientTests_Check_Shape_${test} COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh" diff --git a/examples/ClientTests/compact/Check_Shape_Polyhedra.xml b/examples/ClientTests/compact/Check_Shape_Polyhedra.xml new file mode 100644 index 000000000..cfa0079c7 --- /dev/null +++ b/examples/ClientTests/compact/Check_Shape_Polyhedra.xml @@ -0,0 +1,20 @@ +<lccdd> + <includes> + <gdmlFile ref="CheckShape.xml"/> + </includes> + + <detectors> + <detector id="1" name="Shape_Test" type="DD4hep_TestShape_Creator"> + <check vis="Shape1_vis"> + <shape type="Polyhedra" numsides="1" startphi="-10*degree" deltaphi="20*degree"> + <plane rmin="1775*mm" rmax="1851.5*mm" z="0*mm"/> + <plane rmin="1775*mm" rmax="1851.5*mm" z="3082.39*mm"/> + <plane rmin="1851.5*mm" rmax="1851.5*mm" z="3215.42*mm"/> + </shape> + <position x="30*cm" y="30*cm" z="50*cm"/> + <rotation x="0" y="0" z="0"/> + </check> + <test type="DD4hep_Mesh_Verifier" ref="${DD4hepExamplesINSTALL}/examples/ClientTests/ref/Ref_Polyhedra.txt" create="CheckShape_create"/> + </detector> + </detectors> +</lccdd> diff --git a/examples/ClientTests/compact/Check_Shape_TwistedTube.xml b/examples/ClientTests/compact/Check_Shape_TwistedTube.xml new file mode 100644 index 000000000..56431eacb --- /dev/null +++ b/examples/ClientTests/compact/Check_Shape_TwistedTube.xml @@ -0,0 +1,20 @@ +<lccdd> + <includes> + <gdmlFile ref="CheckShape.xml"/> + </includes> + + <detectors> + <detector id="1" name="Shape_TwistedTube" type="DD4hep_TestShape_Creator"> + <check vis="Shape1_vis"> + <shape type="TwistedTube" twist="20*degree" rmin="10*cm" rmax="30*cm" dz="40*cm" deltaphi="45*degree" /> + <position x="30" y="30" z="30"/> + <rotation x="0" y="0" z="0"/> + </check> +<a> + <test type="DD4hep_Mesh_Verifier" ref="${DD4hepExamplesINSTALL}/examples/ClientTests/ref/Ref_TwistedTube.txt" create="CheckShape_create"/> +</a> + <test type="DD4hep_Mesh_Verifier" ref="${DD4hepExamplesINSTALL}/examples/ClientTests/ref/Ref_TwistedTube.txt" create="1"/> + + </detector> + </detectors> +</lccdd> diff --git a/examples/ClientTests/ref/Ref_Polyhedra.txt b/examples/ClientTests/ref/Ref_Polyhedra.txt new file mode 100644 index 000000000..9704ce336 --- /dev/null +++ b/examples/ClientTests/ref/Ref_Polyhedra.txt @@ -0,0 +1,15 @@ +ShapeCheck[0] TGeoPgon 12 Mesh-points: +TGeoPgon Polyhedra N(mesh)=12 N(vert)=12 N(seg)=20 N(pols)=10 +TGeoPgon 0 Local ( 177.50, -31.30, 0.00) Global ( 207.50, -1.30, 50.00) +TGeoPgon 1 Local ( 177.50, 31.30, 0.00) Global ( 207.50, 61.30, 50.00) +TGeoPgon 2 Local ( 185.15, -32.65, 0.00) Global ( 215.15, -2.65, 50.00) +TGeoPgon 3 Local ( 185.15, 32.65, 0.00) Global ( 215.15, 62.65, 50.00) +TGeoPgon 4 Local ( 177.50, -31.30, 308.24) Global ( 207.50, -1.30, 358.24) +TGeoPgon 5 Local ( 177.50, 31.30, 308.24) Global ( 207.50, 61.30, 358.24) +TGeoPgon 6 Local ( 185.15, -32.65, 308.24) Global ( 215.15, -2.65, 358.24) +TGeoPgon 7 Local ( 185.15, 32.65, 308.24) Global ( 215.15, 62.65, 358.24) +TGeoPgon 8 Local ( 185.15, -32.65, 321.54) Global ( 215.15, -2.65, 371.54) +TGeoPgon 9 Local ( 185.15, 32.65, 321.54) Global ( 215.15, 62.65, 371.54) +TGeoPgon 10 Local ( 185.15, -32.65, 321.54) Global ( 215.15, -2.65, 371.54) +TGeoPgon 11 Local ( 185.15, 32.65, 321.54) Global ( 215.15, 62.65, 371.54) +TGeoPgon Bounding box: dx= 6.60 dy= 32.65 dz= 160.77 Origin: x= 181.40 y= 0.00 z= 160.77 diff --git a/examples/ClientTests/scripts/Check_shape.py b/examples/ClientTests/scripts/Check_shape.py index 214474711..1ed692dc6 100644 --- a/examples/ClientTests/scripts/Check_shape.py +++ b/examples/ClientTests/scripts/Check_shape.py @@ -15,29 +15,39 @@ def run(): kernel = DDG4.Kernel() # Configure UI geant4 = DDG4.Geant4(kernel, tracker='Geant4TrackerCombineAction') - geant4.setupCshUI(vis=True) - if len(sys.argv) >= 2 and sys.argv[1] == "batch": - kernel.UI = '' - elif len(sys.argv) >= 3 and (sys.argv[1] == "batch" or sys.argv[2] == "batch"): - kernel.UI = '' - elif len(sys.argv) == 2 and sys.argv[1] != "batch": - kernel.loadGeometry(sys.argv[1]) - elif len(sys.argv) == 3 and sys.argv[1] != "batch": - kernel.loadGeometry(sys.argv[2]) - elif len(sys.argv) == 3 and sys.argv[2] != "batch": - kernel.loadGeometry(sys.argv[1]) - # + geo = None + vis = False + batch = False + #pdb.set_trace() + for i in xrange(len(sys.argv)): + c = sys.argv[i].upper() + if c.find('BATCH') < 2 and c.find('BATCH') >= 0: batch = True + if c[:4] == '-GEO': geo = sys.argv[i+1] + if c[:4] == '-VIS': vis = True + + ui = geant4.setupCshUI(ui=None,vis=vis) + if batch: kernel.UI = '' + print('Geometry:'+str(geo)) + kernel.loadGeometry(geo) # Configure field geant4.setupTrackingField(prt=True) # Now build the physics list: - phys = kernel.physicsList() - phys.extends = 'QGSP_BERT' - phys.enableUI() - phys.dump() - + geant4.setupPhysics('') + kernel.physicsList().enableUI() DDG4.setPrintLevel(DDG4.OutputLevel.DEBUG) - geant4.execute() - + # + # '/ddg4/ConstructGeometry/DumpGDML test.gdml', + # '/ddg4/ConstructGeometry/writeGDML', + ui.Commands = [ + '/ddg4/ConstructGeometry/VolumePath /world_volume_1/Shape_Test_0/Shape_Test_vol_0_0', + '/ddg4/ConstructGeometry/printVolume', + 'exit' + ] + kernel.NumEvents = 0 + kernel.configure() + kernel.initialize() + kernel.run() + kernel.terminate() if __name__ == "__main__": run() diff --git a/examples/ClientTests/scripts/Check_shape_dump.mac b/examples/ClientTests/scripts/Check_shape_dump.mac new file mode 100644 index 000000000..66a5efcc4 --- /dev/null +++ b/examples/ClientTests/scripts/Check_shape_dump.mac @@ -0,0 +1,2 @@ +/ddg4/ConstructGeometry/VolumePath /world_volume_1/Shape_Test_0/Shape_Test_vol_0_0 +/ddg4/ConstructGeometry/printVolume diff --git a/examples/DDDB/src/plugins/DDDBDerivedCondTest.cpp b/examples/DDDB/src/plugins/DDDBDerivedCondTest.cpp index ead7d6920..b87cf2221 100644 --- a/examples/DDDB/src/plugins/DDDBDerivedCondTest.cpp +++ b/examples/DDDB/src/plugins/DDDBDerivedCondTest.cpp @@ -81,8 +81,8 @@ namespace { virtual ~ConditionUpdate1() { } /// Interface to client Callback in order to update the condition virtual Condition operator()(const ConditionKey& key, ConditionUpdateContext& ) override final { - printout(context.level,"ConditionUpdate1","++ Building dependent condition: %s",key.name.c_str()); - Condition target(key.name,"Alignment"); + printout(context.level,"ConditionUpdate1","++ Building dependent condition: %s",key.toString().c_str()); + Condition target("","Alignment"); target.bind<AlignmentData>(); return target; } @@ -99,7 +99,7 @@ namespace { catch(const exception& exc) { ++context.numFail1; printout(ERROR,"ConditionUpdate2","++ Failed to build condition %s: %s", - ctxt.key(0).name.c_str(), exc.what()); + ctxt.key(0).toString().c_str(), exc.what()); } } }; @@ -120,8 +120,8 @@ namespace { virtual ~ConditionUpdate2() { } /// Interface to client Callback in order to update the condition virtual Condition operator()(const ConditionKey& key, ConditionUpdateContext&) override final { - printout(context.level,"ConditionUpdate2","++ Building dependent condition: %s",key.name.c_str()); - Condition target(key.name,"Alignment"); + printout(context.level,"ConditionUpdate2","++ Building dependent condition: %s",key.toString().c_str()); + Condition target("","Alignment"); target.bind<AlignmentData>(); return target; } @@ -140,7 +140,7 @@ namespace { catch(const exception& exc) { ++context.numFail2; printout(ERROR,"ConditionUpdate2","++ Failed to build condition %s: %s", - ctxt.key(0).name.c_str(), exc.what()); + ctxt.key(0).toString().c_str(), exc.what()); } } }; @@ -161,8 +161,8 @@ namespace { virtual ~ConditionUpdate3() { } /// Interface to client Callback in order to update the condition virtual Condition operator()(const ConditionKey& key, ConditionUpdateContext&) override final { - printout(context.level,"ConditionUpdate3","++ Building dependent condition: %s",key.name.c_str()); - Condition target(key.name,"Alignment"); + printout(context.level,"ConditionUpdate3","++ Building dependent condition: %s",key.toString().c_str()); + Condition target("","Alignment"); target.bind<AlignmentData>(); return target; } @@ -183,7 +183,7 @@ namespace { catch(const exception& exc) { ++context.numFail3; printout(ERROR,"ConditionUpdate3","++ Failed to build condition %s: %s", - ctxt.key(0).name.c_str(), exc.what()); + ctxt.key(0).toString().c_str(), exc.what()); } } }; -- GitLab