From 37a8db9ee99810ff9d2420a8b6ef338e19ab801f Mon Sep 17 00:00:00 2001
From: Markus Frank <Markus.Frank@cern.ch>
Date: Wed, 10 Aug 2022 13:30:14 +0200
Subject: [PATCH] Fix Volume extension persistency problem

---
 DDCore/include/DD4hep/Volumes.h |  3 +--
 DDCore/src/RootDictionary.h     |  4 ++++
 DDCore/src/Volumes.cpp          | 33 +++++++++++++++++++--------------
 3 files changed, 24 insertions(+), 16 deletions(-)

diff --git a/DDCore/include/DD4hep/Volumes.h b/DDCore/include/DD4hep/Volumes.h
index 68bad1fb2..b7e8a2a1e 100644
--- a/DDCore/include/DD4hep/Volumes.h
+++ b/DDCore/include/DD4hep/Volumes.h
@@ -318,8 +318,7 @@ namespace dd4hep {
     /// Reference to the reflected volume (or to the original volume for reflections)
     Handle<TGeoVolume>  reflected;
     /// Reference to properties
-    using Properties = std::map<std::string, std::string>;
-    std::unique_ptr<Properties> properties;
+    TList* properties  { nullptr };
 
     /// Default destructor
     virtual ~VolumeExtension();
diff --git a/DDCore/src/RootDictionary.h b/DDCore/src/RootDictionary.h
index ef693b8d4..624035011 100644
--- a/DDCore/src/RootDictionary.h
+++ b/DDCore/src/RootDictionary.h
@@ -175,6 +175,7 @@ template class dd4hep::Handle<TNamed>;
 #pragma link C++ class dd4hep::VolumeManagerContext+;
 #pragma link C++ class dd4hep::detail::VolumeManagerContextExtension+;
 #pragma link C++ class dd4hep::Handle<dd4hep::detail::VolumeManagerObject>+;
+#pragma link C++ class pair<Long64_t,dd4hep::VolumeManager>+;
 #pragma link C++ class map<dd4hep::DetElement,dd4hep::VolumeManager>+;
 #pragma link C++ class map<dd4hep::VolumeID,dd4hep::VolumeManager>+;
 #pragma link C++ class map<dd4hep::VolumeID,dd4hep::VolumeManagerContext*>+;
@@ -262,6 +263,7 @@ template class dd4hep::Handle<TNamed>;
 #pragma link C++ class dd4hep::AlignmentCondition+;
 #pragma link C++ class dd4hep::detail::AlignmentObject+;
 #pragma link C++ class dd4hep::Handle<dd4hep::detail::AlignmentObject>+;
+#pragma link C++ class pair<dd4hep::DetElement,dd4hep::AlignmentCondition>+;
 //#pragma link C++ class dd4hep::Grammar<dd4hep::detail::AlignmentObject>+;
 
 #pragma link C++ class dd4hep::align::GlobalAlignment+;
@@ -294,6 +296,8 @@ template class dd4hep::Handle<TNamed>;
 #pragma link C++ class dd4hep::DetectorProcessor+;
 #pragma link C++ class dd4hep::DetectorScanner+;
 
+#pragma link C++ class pair<dd4hep::DetElement,dd4hep::VolumeManager>+;
+
 #ifdef R__MACOSX
 // We only need these declarations for the clang compiler
 #pragma link C++ function operator==( const map<string, dd4hep::DetElement >::iterator&,const map<string, dd4hep::DetElement >::iterator& );
diff --git a/DDCore/src/Volumes.cpp b/DDCore/src/Volumes.cpp
index dd6e430f6..15b4c4611 100644
--- a/DDCore/src/Volumes.cpp
+++ b/DDCore/src/Volumes.cpp
@@ -521,6 +521,7 @@ VolumeExtension::VolumeExtension()
 
 /// Default destructor
 VolumeExtension::~VolumeExtension() {
+  detail::deletePtr(properties);
   region.clear();
   limits.clear();
   vis.clear();
@@ -548,8 +549,13 @@ void VolumeExtension::copy(const VolumeExtension& c) {
     vis        = c.vis;
     sens_det   = c.sens_det;
     referenced = c.referenced;
-    if ( c.properties )  {
-      properties = std::make_unique<Properties>(*c.properties);
+    detail::deletePtr(properties);
+    if ( c.properties )    {
+      properties = new TList();
+      properties->SetOwner();
+      TIter next(properties);
+      TNamed *property;
+      while ((property = (TNamed*)next())) properties->Add(new TNamed(*property));
     }
   }
 }
@@ -1257,18 +1263,19 @@ bool Volume::isSensitive() const {
 
 /// Check for existence of properties
 bool Volume::hasProperties()  const   {
-  return _data(*this)->properties.get() != nullptr;
+  return _data(*this)->properties != nullptr;
 }
 
 /// Add Volume property (name-value pair)
 void Volume::addProperty(const string& nam, const string& val) const  {
   auto* o = _data(*this);
-  if ( !o->properties.get() )   {
-    o->properties = make_unique<VolumeExtension::Properties>();
+  if ( !o->properties )   {
+    o->properties = new TList();
+    o->properties->SetOwner();
   }
-  auto ip = o->properties->find(nam);
-  if ( ip == o->properties->end() )   {
-    o->properties->emplace(nam, val);
+  TNamed *prop = (TNamed*)o->properties->FindObject(nam.c_str());
+  if ( !prop )   {
+    o->properties->Add(new TNamed(nam.c_str(), val.c_str()));
     return;
   }
   except("Volume::addProperty", "Volume: '%s' Property '%s' is already set!",
@@ -1278,14 +1285,12 @@ void Volume::addProperty(const string& nam, const string& val) const  {
 /// Access property value. Returns default_value if the property is not present
 string Volume::getProperty(const string& nam, const string& default_val)   const {
   const auto* o = _data(*this);
-  if ( !o->properties.get() )   {
+  if ( !o->properties )   {
     return default_val;
   }
-  auto ip = o->properties->find(nam);
-  if ( ip == o->properties->end() )   {
-    return default_val;
-  }
-  return (*ip).second;
+  TNamed *prop = (TNamed*)o->properties->FindObject(nam.c_str());
+  if ( prop ) return prop->GetTitle();
+  return default_val;
 }
 
 /// Constructor to be used when creating a new assembly object
-- 
GitLab