From a46d898598e7e375b4cd4e4941bd553658b207c8 Mon Sep 17 00:00:00 2001
From: Markus Frank <Markus.Frank@cern.ch>
Date: Mon, 29 Oct 2018 16:40:53 +0100
Subject: [PATCH] Fix changes supporting multiple instances

---
 DDCore/src/DetectorData.cpp           | 54 ++++++++++++++-------------
 DDG4/include/DDG4/Geant4PhysicsList.h | 13 ++++++-
 DDG4/src/Geant4PhysicsList.cpp        | 16 +++++++-
 examples/CLICSiD/scripts/CLICSid.py   |  4 +-
 4 files changed, 57 insertions(+), 30 deletions(-)

diff --git a/DDCore/src/DetectorData.cpp b/DDCore/src/DetectorData.cpp
index 3aa011587..8d299f9ad 100644
--- a/DDCore/src/DetectorData.cpp
+++ b/DDCore/src/DetectorData.cpp
@@ -270,38 +270,40 @@ void DetectorData::clearData()   {
 
 /// Adopt all data from source structure
 void DetectorData::adoptData(DetectorData& source, bool clr)   {
-  m_inhibitConstants = source.m_inhibitConstants;
+  m_inhibitConstants   = source.m_inhibitConstants;
   m_extensions.move(source.m_extensions);
-  m_manager          = source.m_manager;
-  m_readouts         = source.m_readouts;
-  m_idDict           = source.m_idDict;
-  m_limits           = source.m_limits;
-  m_regions          = source.m_regions;
-  m_detectors        = source.m_detectors;
-  m_sensitive        = source.m_sensitive;
-  m_display          = source.m_display;
-  m_fields           = source.m_fields;
-  m_define           = source.m_define;
+  m_manager            = source.m_manager;
+  m_readouts           = source.m_readouts;
+  m_idDict             = source.m_idDict;
+  m_limits             = source.m_limits;
+  m_regions            = source.m_regions;
+  m_detectors          = source.m_detectors;
+  m_sensitive          = source.m_sensitive;
+  m_display            = source.m_display;
+  m_fields             = source.m_fields;
+  m_define             = source.m_define;
 
-  m_detectorParents  = source.m_detectorParents;
-  m_world            = source.m_world;
-  m_trackers         = source.m_trackers;
-  m_worldVol         = source.m_worldVol;
-  m_trackingVol      = source.m_trackingVol;
-  m_parallelWorldVol = source.m_parallelWorldVol;
-  m_materialAir      = source.m_materialAir;
-  m_materialVacuum   = source.m_materialVacuum;
-  m_invisibleVis     = source.m_invisibleVis;
-  m_field            = source.m_field;
-  m_header           = source.m_header;
-  m_properties       = source.m_properties;
-  //m_extensions     = source.m_extensions;
-  m_volManager       = source.m_volManager;
+  m_detectorParents    = source.m_detectorParents;
+  m_world              = source.m_world;
+  World w              = m_world;
+  w->description       = dynamic_cast<Detector*>(this);
+  m_trackers           = source.m_trackers;
+  m_worldVol           = source.m_worldVol;
+  m_trackingVol        = source.m_trackingVol;
+  m_parallelWorldVol   = source.m_parallelWorldVol;
+  m_materialAir        = source.m_materialAir;
+  m_materialVacuum     = source.m_materialVacuum;
+  m_invisibleVis       = source.m_invisibleVis;
+  m_field              = source.m_field;
+  m_header             = source.m_header;
+  m_properties         = source.m_properties;
+  //m_extensions       = source.m_extensions;
+  m_volManager         = source.m_volManager;
 
   // Update world element
   m_world.setPlacement(m_manager->GetTopNode());
   // Need to update some global stuff
   if ( gGeoManager != m_manager ) delete gGeoManager;
-  gGeoManager       = m_manager;
+  gGeoManager         = m_manager;
   if ( clr ) source.clearData();
 }
diff --git a/DDG4/include/DDG4/Geant4PhysicsList.h b/DDG4/include/DDG4/Geant4PhysicsList.h
index 8b865a91d..91aea5d47 100644
--- a/DDG4/include/DDG4/Geant4PhysicsList.h
+++ b/DDG4/include/DDG4/Geant4PhysicsList.h
@@ -101,8 +101,9 @@ namespace dd4hep {
       typedef std::vector<PhysicsConstructor> PhysicsConstructors;
 
       PhysicsProcesses     m_processes;
-      ParticleConstructors m_particles;
       PhysicsConstructors  m_physics;
+      ParticleConstructors m_particles;
+      ParticleConstructors m_particlegroups;
 
     public:
       /// Standard constructor with initailization parameters
@@ -133,6 +134,14 @@ namespace dd4hep {
       const ParticleConstructors& particles() const {
         return m_particles;
       }
+      /// Access all physics particlegroups
+      ParticleConstructors& particlegroups() {
+        return m_particlegroups;
+      }
+      /// Access all physics particlegroups
+      const ParticleConstructors& particlegroups() const {
+        return m_particlegroups;
+      }
       /// Access all physics constructors
       PhysicsConstructors& physics() {
         return m_physics;
@@ -144,6 +153,8 @@ namespace dd4hep {
 
       /// Add physics particle constructor by name
       void addParticleConstructor(const std::string& part_name);
+      /// Add physics particle group constructor by name (Leptons, Bosons, Mesons, etc.)
+      void addParticleGroup(const std::string& part_name);
       /// Add particle process by name with arguments
       void addParticleProcess(const std::string& part_name, const std::string& proc_name,
                               int ordAtRestDoIt,int ordAlongSteptDoIt,int ordPostStepDoIt);
diff --git a/DDG4/src/Geant4PhysicsList.cpp b/DDG4/src/Geant4PhysicsList.cpp
index 47bd6ccfd..c07fa6a3d 100644
--- a/DDG4/src/Geant4PhysicsList.cpp
+++ b/DDG4/src/Geant4PhysicsList.cpp
@@ -128,6 +128,11 @@ void Geant4PhysicsList::addParticleConstructor(const std::string& part_name)   {
   particles().push_back(part_name);
 }
 
+/// Add physics particle constructor by name
+void Geant4PhysicsList::addParticleGroup(const std::string& part_name)   {
+  particlegroups().push_back(part_name);
+}
+
 /// Add particle process by name with arguments
 void Geant4PhysicsList::addParticleProcess(const std::string& part_name,
                                            const std::string& proc_name,
@@ -215,8 +220,17 @@ void Geant4PhysicsList::constructParticles(G4VUserPhysicsList* physics_pointer)
       if (!result || *result != 1L) {
         except("Failed to create particle type '%s' result=%d", ctor.c_str(), result);
       }
+      info("Constructed Geant4 particle %s [using signature long (*)()]",ctor.c_str());
+    }
+  }
+  /// Now define all particles
+  for (ParticleConstructors::const_iterator i = m_particlegroups.begin(); i != m_particlegroups.end(); ++i) {
+    const ParticleConstructors::value_type& ctor = *i;
+    /// Check if we have here a particle group constructor
+    long* result = (long*) PluginService::Create<long>(ctor);
+    if (!result || *result != 1L) {
+      except("Failed to create particle type '%s' result=%d", ctor.c_str(), result);
     }
-    info("Constructed Geant4 particle %s [using signature long (*)()]",ctor.c_str());
   }
 }
 
diff --git a/examples/CLICSiD/scripts/CLICSid.py b/examples/CLICSiD/scripts/CLICSid.py
index a7d8ee7a6..eae570acc 100644
--- a/examples/CLICSiD/scripts/CLICSid.py
+++ b/examples/CLICSiD/scripts/CLICSid.py
@@ -37,9 +37,9 @@ class CLICSid:
     phys = self.geant4.setupPhysics(model)
     ph = DDG4.PhysicsList(self.kernel,'Geant4PhysicsList/Myphysics')
     # Add bosons to the model (redundant if already implemented by the model)
-    ph.addParticleConstructor('G4BosonConstructor')
+    ph.addParticleGroup('G4BosonConstructor')
     # Add leptons to the model (redundant if already implemented by the model)
-    ph.addParticleConstructor('G4LeptonConstructor')
+    ph.addParticleGroup('G4LeptonConstructor')
     # Add multiple scattering in the material
     ph.addParticleProcess('e[+-]','G4eMultipleScattering',-1,1,1)
     # Add optical physics (RICH dets etc)
-- 
GitLab