From ceeef3b783eb7b74f52b12967e50840b5df25201 Mon Sep 17 00:00:00 2001
From: Markus FRANK <Markus.Frank@cern.ch>
Date: Tue, 2 Mar 2021 12:01:23 +0100
Subject: [PATCH] Modernize loop handling according to C++ 17 standards

---
 DDG4/include/DDG4/Geant4Action.h              |  72 ++--
 DDG4/include/DDG4/Geant4Converter.h           |   1 -
 DDG4/src/Geant4Converter.cpp                  | 317 +++++-------------
 DDG4/src/Geant4Kernel.cpp                     |  79 ++---
 DDG4/src/Geant4Mapping.cpp                    |   7 +-
 DDG4/src/Geant4Particle.cpp                   |  44 +--
 DDG4/src/Geant4ParticleHandler.cpp            |  40 +--
 DDG4/src/Geant4PhysicsList.cpp                | 118 +++----
 examples/CMakeLists.txt                       |   2 +-
 .../compact/MultiShape_MS3D_jeep-original.xml |  56 ++++
 10 files changed, 290 insertions(+), 446 deletions(-)
 create mode 100644 examples/DDCAD/compact/MultiShape_MS3D_jeep-original.xml

diff --git a/DDG4/include/DDG4/Geant4Action.h b/DDG4/include/DDG4/Geant4Action.h
index 053a5cc8c..6fb9b6e3e 100644
--- a/DDG4/include/DDG4/Geant4Action.h
+++ b/DDG4/include/DDG4/Geant4Action.h
@@ -195,66 +195,56 @@ namespace dd4hep {
         }
         /// NON-CONST actions
         template <typename R, typename Q> void operator()(R (Q::*pmf)()) {
-          if (m_v.empty())
-            return;
-          for (typename _V::iterator i = m_v.begin(); i != m_v.end(); ++i)
-            ((*i)->*pmf)();
+          if ( !m_v.empty() )
+	    for (const auto& o : m_v)
+	      (o->*pmf)();
         }
         template <typename R, typename Q, typename A0> void operator()(R (Q::*pmf)(A0), A0 a0) {
-          if (m_v.empty())
-            return;
-          for (typename _V::iterator i = m_v.begin(); i != m_v.end(); ++i)
-            ((*i)->*pmf)(a0);
+          if ( !m_v.empty() )
+	    for (const auto& o : m_v)
+	      (o->*pmf)(a0);
         }
         template <typename R, typename Q, typename A0, typename A1> void operator()(R (Q::*pmf)(A0, A1), A0 a0, A1 a1) {
-          if (m_v.empty())
-            return;
-          for (typename _V::iterator i = m_v.begin(); i != m_v.end(); ++i)
-            ((*i)->*pmf)(a0, a1);
+          if ( !m_v.empty() )
+	    for (const auto& o : m_v)
+	      (o->*pmf)(a0, a1);
         }
         /// CONST actions
         template <typename R, typename Q> void operator()(R (Q::*pmf)() const) const {
-          if (m_v.empty())
-            return;
-          for (typename _V::const_iterator i = m_v.begin(); i != m_v.end(); ++i)
-            ((*i)->*pmf)();
+          if ( !m_v.empty() )
+	    for (const auto& o : m_v)
+	      (o->*pmf)();
         }
         template <typename R, typename Q, typename A0> void operator()(R (Q::*pmf)(A0) const, A0 a0) const {
-          if (m_v.empty())
-            return;
-          for (typename _V::const_iterator i = m_v.begin(); i != m_v.end(); ++i)
-            ((*i)->*pmf)(a0);
+          if ( !m_v.empty() )
+	    for (const auto& o : m_v)
+	      (o->*pmf)(a0);
         }
-        template <typename R, typename Q, typename A0, typename A1> void operator()(R (Q::*pmf)(A0, A1) const, A0 a0,
-                                                                                    A1 a1) const {
-          if (m_v.empty())
-            return;
-          for (typename _V::const_iterator i = m_v.begin(); i != m_v.end(); ++i)
-            ((*i)->*pmf)(a0, a1);
+        template <typename R, typename Q, typename A0, typename A1> void operator()(R (Q::*pmf)(A0, A1) const, A0 a0, A1 a1) const {
+	  if ( !m_v.empty() )
+	    for (const auto& o : m_v)
+	      (o->*pmf)(a0, a1);
         }
         /// CONST filters
         template <typename Q> bool filter(bool (Q::*pmf)() const) const {
-          if (!m_v.empty())
-            return true;
-          for (typename _V::const_iterator i = m_v.begin(); i != m_v.end(); ++i)
-            if (!((*i)->*pmf)())
-              return false;
+          if ( !m_v.empty() )
+	    for (const auto& o : m_v)
+	      if ( !(o->*pmf)() )
+		return false;
           return true;
         }
         template <typename Q, typename A0> bool filter(bool (Q::*pmf)(A0) const, A0 a0) const {
-          if (m_v.empty())
-            return true;
-          for (typename _V::const_iterator i = m_v.begin(); i != m_v.end(); ++i)
-            if (!((*i)->*pmf)(a0))
-              return false;
+          if ( !m_v.empty() )
+	    for (const auto& o : m_v)
+	      if ( !(o->*pmf)(a0) )
+		return false;
           return true;
         }
         template <typename Q, typename A0, typename A1> bool filter(bool (Q::*pmf)(A0, A1) const, A0 a0, A1 a1) const {
-          if (m_v.empty())
-            return true;
-          for (typename _V::const_iterator i = m_v.begin(); i != m_v.end(); ++i)
-            if (!((*i)->*pmf)(a0, a1))
-              return false;
+          if ( !m_v.empty() )
+	    for (const auto& o : m_v)
+	      if ( !(o->*pmf)(a0,a1) )
+		return false;
           return true;
         }
       };
diff --git a/DDG4/include/DDG4/Geant4Converter.h b/DDG4/include/DDG4/Geant4Converter.h
index 67f3d0989..d5e097178 100644
--- a/DDG4/include/DDG4/Geant4Converter.h
+++ b/DDG4/include/DDG4/Geant4Converter.h
@@ -101,7 +101,6 @@ namespace dd4hep {
 
       /// Convert the geometry type volume placement into the corresponding Geant4 object(s).
       virtual void* handlePlacement(const std::string& name, const TGeoNode* node) const;
-      virtual void* handlePlacement2(const std::pair<const TGeoNode*,const TGeoNode*>& node) const;
       virtual void* handleAssembly(const std::string& name, const TGeoNode* node) const;
 
       /// Convert the geometry type field into the corresponding Geant4 object(s).
diff --git a/DDG4/src/Geant4Converter.cpp b/DDG4/src/Geant4Converter.cpp
index 122478a49..9a0369c36 100644
--- a/DDG4/src/Geant4Converter.cpp
+++ b/DDG4/src/Geant4Converter.cpp
@@ -359,7 +359,7 @@ Geant4Converter::~Geant4Converter() {
 /// Handle the conversion of isotopes
 void* Geant4Converter::handleIsotope(const string& /* name */, const TGeoIsotope* iso) const {
   G4Isotope* g4i = data().g4Isotopes[iso];
-  if (!g4i) {
+  if ( !g4i )  {
     double a_conv = (CLHEP::g / CLHEP::mole);
     g4i = new G4Isotope(iso->GetName(), iso->GetZ(), iso->GetN(), iso->GetA()*a_conv);
     printout(debugElements ? ALWAYS : outputLevel,
@@ -373,7 +373,7 @@ void* Geant4Converter::handleIsotope(const string& /* name */, const TGeoIsotope
 /// Handle the conversion of elements
 void* Geant4Converter::handleElement(const string& name, const Atom element) const {
   G4Element* g4e = data().g4Elements[element];
-  if (!g4e) {
+  if ( !g4e ) {
     PrintLevel lvl = debugElements ? ALWAYS : outputLevel;
     if (element->GetNisotopes() > 0) {
       g4e = new G4Element(name, element->GetTitle(), element->GetNisotopes());
@@ -407,9 +407,9 @@ void* Geant4Converter::handleMaterial(const string& name, Material medium) const
     TGeoMaterial* material = medium->GetMaterial();
     G4State state   = kStateUndefined;
     double  density = material->GetDensity() * (CLHEP::gram / CLHEP::cm3);
-    if (density < 1e-25)
+    if ( density < 1e-25 )
       density = 1e-25;
-    switch (material->GetState()) {
+    switch ( material->GetState() ) {
     case TGeoMaterial::kMatStateSolid:
       state = kStateSolid;
       break;
@@ -424,7 +424,7 @@ void* Geant4Converter::handleMaterial(const string& name, Material medium) const
       state = kStateUndefined;
       break;
     }
-    if (material->IsMixture()) {
+    if ( material->IsMixture() )  {
       double A_total = 0.0;
       double W_total = 0.0;
       TGeoMixture* mix = (TGeoMixture*) material;
@@ -602,7 +602,7 @@ void* Geant4Converter::handleSolid(const string& name, const TGeoShape* shape) c
       except("Geant4Converter","++ TGeoScaledShape are only supported by Geant4 for versions >= 10.3");
 #endif
     }
-    else if (isa == TGeoCompositeShape::Class())   {
+    else if ( isa == TGeoCompositeShape::Class() )   {
       const TGeoCompositeShape* sh = (const TGeoCompositeShape*) shape;
       const TGeoBoolNode* boolean = sh->GetBoolNode();
       TGeoBoolNode::EGeoBoolType oper = boolean->GetBooleanOperator();
@@ -648,7 +648,7 @@ void* Geant4Converter::handleSolid(const string& name, const TGeoShape* shape) c
         }
       }
 
-      if (matrix->IsRotation()) {
+      if ( matrix->IsRotation() ) {
         MyTransform3D transform(matrix->GetTranslation(),matrix->GetRotationMatrix());
         if (oper == TGeoBoolNode::kGeoSubtraction)
           solid = new G4SubtractionSolid(name, left, right, transform);
@@ -669,7 +669,7 @@ void* Geant4Converter::handleSolid(const string& name, const TGeoShape* shape) c
       }
     }
 
-    if (!solid)
+    if ( !solid )
       except("Geant4Converter","++ Failed to handle unknown solid shape: %s of type %s",
              name.c_str(), isa->GetName());
     printout(lvl,"Geant4Converter","++ Successessfully converted shape [%p] of type:%s to %s.",
@@ -690,67 +690,56 @@ void* Geant4Converter::handleVolume(const string& name, const TGeoVolume* volume
     return 0;
   }
   else if (volIt == info.g4Volumes.end() ) {
-    const TGeoVolume* v = volume;
-    string      n       = v->GetName();
-    TGeoMedium* med     = v->GetMedium();
-    TGeoShape*  sh      = v->GetShape();
+    string      n       = volume->GetName();
+    TGeoMedium* med     = volume->GetMedium();
+    TGeoShape*  sh      = volume->GetShape();
     G4VSolid*   solid   = (G4VSolid*) handleSolid(sh->GetName(), sh);
-    G4Material* medium  = 0;
-    bool        is_assembly = sh->IsA() == TGeoShapeAssembly::Class() || v->IsA() == TGeoVolumeAssembly::Class();
-
-    LimitSet lim = _v.limitSet();
-    G4UserLimits* user_limits = 0;
-    if (lim.isValid()) {
-      user_limits = info.g4Limits[lim];
-      if (!user_limits) {
-        throw runtime_error("G4Cnv::volume[" + name + "]:    + FATAL Failed to "
-                            "access Geant4 user limits.");
-      }
-    }
-    VisAttr vis = _v.visAttributes();
-    G4VisAttributes* vis_attr = 0;
-    if (vis.isValid()) {
-      vis_attr = (G4VisAttributes*)handleVis(vis.name(), vis);
-    }
-    Region reg = _v.region();
-    G4Region* region = 0;
-    if (reg.isValid()) {
-      region = info.g4Regions[reg];
-      if (!region) {
-        throw runtime_error("G4Cnv::volume[" + name + "]:    + FATAL Failed to "
-                            "access Geant4 region.");
-      }
-    }
-    printout(lvl, "Geant4Converter", "++ Convert Volume %-32s: %p %s/%s assembly:%s",
-             n.c_str(), v, sh->IsA()->GetName(), v->IsA()->GetName(), yes_no(is_assembly));
+    bool        is_assembly = sh->IsA() == TGeoShapeAssembly::Class() || volume->IsA() == TGeoVolumeAssembly::Class();
 
-    if (is_assembly) {
+    printout(lvl, "Geant4Converter", "++ Convert Volume %-32s: %p %s/%s assembly:%s",
+             n.c_str(), volume, sh->IsA()->GetName(), volume->IsA()->GetName(), yes_no(is_assembly));
+    
+    if ( is_assembly ) {
       //info.g4AssemblyVolumes[v] = new Geant4AssemblyVolume();
-      return 0;
+      return nullptr;
+    }
+    Region        reg    = _v.region();
+    LimitSet      lim    = _v.limitSet();
+    VisAttr       vis    = _v.visAttributes();
+    G4Region*     region = reg.isValid() ? info.g4Regions[reg] : nullptr;
+    G4UserLimits* limits = lim.isValid() ? info.g4Limits[lim]  : nullptr;
+    G4Material*   medium = (G4Material*) handleMaterial(med->GetName(), Material(med));
+    /// Check all pre-conditions
+    if ( !solid )   {
+      except("G4Converter","++ No Geant4 Solid present for volume:" + n);
     }
-    medium = (G4Material*) handleMaterial(med->GetName(), Material(med));
-    if (!solid) {
-      throw runtime_error("G4Converter: No Geant4 Solid present for volume:" + n);
+    else if ( !medium )   {
+      except("G4Converter","++ No Geant4 material present for volume:" + n);
     }
-    if (!medium) {
-      throw runtime_error("G4Converter: No Geant4 material present for volume:" + n);
+    else if ( reg.isValid() && !region )  {
+      except("G4Cnv::volume["+name+"]"," ++ Failed to access Geant4 region %s.",reg.name());
     }
-    if (user_limits) {
+    else if ( lim.isValid() && !limits )  {
+      except("G4Cnv::volume["+name+"]","++ FATAL Failed to access Geant4 user limits %s.",lim.name());
+    }
+    else if ( limits )   {
       printout(lvl, "Geant4Converter", "++ Volume     + Apply LIMITS settings:%-24s to volume %s.",
                lim.name(), _v.name());
     }
-    G4LogicalVolume* vol = new G4LogicalVolume(solid, medium, n, 0, 0, user_limits);
-    if (region) {
+
+    G4VisAttributes* vattr = vis.isValid() ? (G4VisAttributes*)handleVis(vis.name(), vis) : nullptr;
+    G4LogicalVolume* g4vol = new G4LogicalVolume(solid, medium, n, 0, 0, limits);
+    if ( region )   {
       printout(lvl, "Geant4Converter", "++ Volume     + Apply REGION settings: %s to volume %s.",
                reg.name(), _v.name());
-      vol->SetRegion(region);
-      region->AddRootLogicalVolume(vol);
+      g4vol->SetRegion(region);
+      region->AddRootLogicalVolume(g4vol);
     }
-    if (vis_attr) {
-      vol->SetVisAttributes(vis_attr);
+    if ( vattr )   {
+      g4vol->SetVisAttributes(vattr);
     }
-    info.g4Volumes[v] = vol;
-    printout(lvl, "Geant4Converter", "++ Volume     + %s converted: %p ---> G4: %p", n.c_str(), v, vol);
+    info.g4Volumes[volume] = g4vol;
+    printout(lvl, "Geant4Converter", "++ Volume     + %s converted: %p ---> G4: %p", n.c_str(), volume, g4vol);
   }
   return nullptr;
 }
@@ -758,19 +747,18 @@ void* Geant4Converter::handleVolume(const string& name, const TGeoVolume* volume
 /// Dump logical volume in GDML format to output stream
 void* Geant4Converter::collectVolume(const string& /* name */, const TGeoVolume* volume) const {
   Geant4GeometryInfo& info = data();
-  const TGeoVolume* v = volume;
-  Volume _v(v);
-  Region reg = _v.region();
-  LimitSet lim = _v.limitSet();
-  SensitiveDetector det = _v.sensitiveDetector();
-
-  if (lim.isValid())
-    info.limits[lim].insert(v);
-  if (reg.isValid())
-    info.regions[reg].insert(v);
-  if (det.isValid())
-    info.sensitives[det].insert(v);
-  return (void*) v;
+  Volume              _v(volume);
+  Region              reg = _v.region();
+  LimitSet            lim = _v.limitSet();
+  SensitiveDetector   det = _v.sensitiveDetector();
+
+  if ( lim.isValid() )
+    info.limits[lim].insert(volume);
+  if ( reg.isValid() )
+    info.regions[reg].insert(volume);
+  if ( det.isValid() )
+    info.sensitives[det].insert(volume);
+  return (void*)volume;
 }
 
 /// Dump volume placement in GDML format to output stream
@@ -858,10 +846,10 @@ void* Geant4Converter::handlePlacement(const string& name, const TGeoNode* node)
     return 0;
   }
   //g4 = nullptr;
-  if (!g4) {
+  if ( !g4 ) {
     TGeoVolume* mot_vol = node->GetMotherVolume();
     TGeoMatrix* tr = node->GetMatrix();
-    if (!tr) {
+    if ( !tr ) {
       except("Geant4Converter",
 	     "++ Attempt to handle placement without transformation:%p %s of type %s vol:%p",
 	     node, node->GetName(), node->IsA()->GetName(), vol);
@@ -889,17 +877,17 @@ void* Geant4Converter::handlePlacement(const string& name, const TGeoNode* node)
                  "to mother %s Tr:x=%8.3f y=%8.3f z=%8.3f",
                  vol->GetName(), mot_vol->GetName(),
                  transform.dx(), transform.dy(), transform.dz());
-        return 0;
+        return nullptr;
       }
       G4Scale3D        scale;
       G4Rotate3D       rot;
       G4Translate3D    trans;
+      transform.getDecomposition(scale, rot, trans);
       if ( node_is_assembly )   {
         //
         // Node is an assembly:
         // Imprint the assembly. The mother MUST already be transformed.
         //
-	transform.getDecomposition(scale, rot, trans);
         printout(lvl, "Geant4Converter", "++ Assembly: makeImprint: dau:%-12s %s in mother %-12s "
                  "Tr:x=%8.1f y=%8.1f z=%8.1f   Scale:x=%4.2f y=%4.2f z=%4.2f",
                  node->GetName(), node_is_reflected ? "(REFLECTED)" : "",
@@ -910,7 +898,7 @@ void* Geant4Converter::handlePlacement(const string& name, const TGeoNode* node)
         Geant4AssemblyVolume::Chain chain;
         chain.emplace_back(node);
         ass->imprint(info,node,chain,ass,(*volIt).second, transform, copy, checkOverlaps);
-        return 0;
+        return nullptr;
       }
       else if ( node != info.manager->GetTopNode() && volIt == info.g4Volumes.end() )  {
         throw logic_error("Geant4Converter: Invalid mother volume found!");
@@ -925,7 +913,6 @@ void* Geant4Converter::handlePlacement(const string& name, const TGeoNode* node)
                                                false,     // no boolean operations
                                                copy,      // its copy number
                                                checkOverlaps);
-      transform.getDecomposition(scale, rot, trans);
       printout(debugReflections||debugPlacements ? ALWAYS : lvl, "Geant4Converter",
 	       "++ Place %svolume %-12s in mother %-12s "
 	       "Tr:x=%8.1f y=%8.1f z=%8.1f   Scale:x=%4.2f y=%4.2f z=%4.2f",
@@ -955,126 +942,12 @@ void* Geant4Converter::handlePlacement(const string& name, const TGeoNode* node)
   return g4;
 }
 
-void* Geant4Converter::handlePlacement2(const std::pair<const TGeoNode*,const TGeoNode*>& n) const   {
-  const TGeoNode* par_node = n.first;
-  const TGeoNode* node = n.second;
-  Geant4GeometryInfo& info = data();
-  PrintLevel lvl = debugPlacements ? ALWAYS : outputLevel;
-  Geant4GeometryMaps::PlacementMap::const_iterator g4it = info.g4Placements.find(node);
-  G4VPhysicalVolume* g4 = (g4it == info.g4Placements.end()) ? 0 : (*g4it).second;
-  TGeoVolume* vol = node->GetVolume();
-  Volume _v(vol);
-
-  if ( _v.testFlagBit(Volume::VETO_SIMU) )  {
-    printout(lvl, "Geant4Converter", "++ Placement %s not converted [Veto'ed for simulation]",node->GetName());
-    return 0;
-  }
-  g4 = nullptr;
-  if (!g4) {
-    TGeoVolume* mot_vol = par_node ? par_node->GetVolume() : node->GetMotherVolume();
-    TGeoMatrix* tr = node->GetMatrix();
-    if (!tr) {
-      except("Geant4Converter",
-	     "++ Attempt to handle placement without transformation:%p %s of type %s vol:%p",
-	     node, node->GetName(), node->IsA()->GetName(), vol);
-    }
-    else if (0 == vol) {
-      except("Geant4Converter", "++ Unknown G4 volume:%p %s of type %s ptr:%p",
-	     node, node->GetName(), node->IsA()->GetName(), vol);
-    }
-    else {
-      int           copy               = node->GetNumber();
-      bool          node_is_reflected  = is_left_handed(tr);
-      bool          node_is_assembly   = vol->IsA() == TGeoVolumeAssembly::Class();
-      bool          mother_is_assembly = mot_vol ? mot_vol->IsA() == TGeoVolumeAssembly::Class() : false;
-      MyTransform3D transform(tr->GetTranslation(),tr->IsRotation() ? tr->GetRotationMatrix() : s_identity_rot);
-      Geant4GeometryMaps::VolumeMap::const_iterator volIt = info.g4Volumes.find(mot_vol);
-
-      if ( mother_is_assembly )   {
-        //
-        // Mother is an assembly:
-        // Nothing to do here, because:
-        // -- placed volumes were already added before in "handleAssembly"
-        // -- imprint cannot be made, because this requires a logical volume as a mother
-        //
-        printout(lvl, "Geant4Converter", "+++ Assembly: **** : dau:%s "
-                 "to mother %s Tr:x=%8.3f y=%8.3f z=%8.3f",
-                 vol->GetName(), mot_vol->GetName(),
-                 transform.dx(), transform.dy(), transform.dz());
-        return 0;
-      }
-      G4Scale3D        scale;
-      G4Rotate3D       rot;
-      G4Translate3D    trans;
-      if ( node_is_assembly )   {
-        //
-        // Node is an assembly:
-        // Imprint the assembly. The mother MUST already be transformed.
-        //
-	transform.getDecomposition(scale, rot, trans);
-        printout(lvl, "Geant4Converter", "+++ Assembly: makeImprint: dau:%-12s %s in mother %-12s "
-                 "Tr:x=%8.1f y=%8.1f z=%8.1f   Scale:x=%4.2f y=%4.2f z=%4.2f",
-                 node->GetName(), node_is_reflected ? "(REFLECTED)" : "",
-		 mot_vol ? mot_vol->GetName() : "<unknown>",
-                 transform.dx(), transform.dy(), transform.dz(),
-		 scale.xx(), scale.yy(), scale.zz());
-        Geant4AssemblyVolume* ass = (Geant4AssemblyVolume*)info.g4AssemblyVolumes[node];
-        Geant4AssemblyVolume::Chain chain;
-        chain.emplace_back(node);
-        ass->imprint(info,node,chain,ass,(*volIt).second, transform, copy, checkOverlaps);
-        return 0;
-      }
-      else if ( node != info.manager->GetTopNode() && volIt == info.g4Volumes.end() )  {
-        throw logic_error("Geant4Converter: Invalid mother volume found!");
-      }
-      G4LogicalVolume* g4vol = info.g4Volumes[vol];
-      G4LogicalVolume* g4mot = info.g4Volumes[mot_vol];
-      G4PhysicalVolumesPair pvPlaced =
-        G4ReflectionFactory::Instance()->Place(transform, // no rotation
-                                               node->GetName(),      // its name
-                                               g4vol,     // its logical volume
-                                               g4mot,     // its mother (logical) volume
-                                               false,     // no boolean operations
-                                               copy,      // its copy number
-                                               checkOverlaps);
-      transform.getDecomposition(scale, rot, trans);
-      printout(debugReflections||debugPlacements ? ALWAYS : lvl, "Geant4Converter",
-	       "++ Place %svolume %-12s in mother %-12s "
-	       "Tr:x=%8.1f y=%8.1f z=%8.1f   Scale:x=%4.2f y=%4.2f z=%4.2f",
-	       node_is_reflected ? "REFLECTED " : "", _v.name(),
-	       mot_vol ? mot_vol->GetName() : "<unknown>",
-	       transform.dx(), transform.dy(), transform.dz(),
-	       scale.xx(), scale.yy(), scale.zz());
-      // First 2 cases can be combined.
-      // Leave them separated for debugging G4ReflectionFactory for now...
-      if ( node_is_reflected  && !pvPlaced.second )
-        return info.g4Placements[node] = pvPlaced.first;
-      else if ( !node_is_reflected && !pvPlaced.second )
-        return info.g4Placements[node] = pvPlaced.first;
-      //G4LogicalVolume* g4refMoth = G4ReflectionFactory::Instance()->GetReflectedLV(g4mot);
-      // Now deal with valid pvPlaced.second ...
-      if ( node_is_reflected )
-        return info.g4Placements[node] = pvPlaced.first;
-      else if ( !node_is_reflected )
-        return info.g4Placements[node] = pvPlaced.first;
-      g4 = pvPlaced.second ? pvPlaced.second : pvPlaced.first;
-    }
-    info.g4Placements[node] = g4;
-    printout(ERROR, "Geant4Converter", "++ DEAD code. Should not end up here!");
-  }
-  else {
-    printout(ERROR, "Geant4Converter", "++ Attempt to DOUBLE-place physical volume: %s No:%d",
-	     node->GetName(), node->GetNumber());
-  }
-  return g4;
-}
-
 /// Convert the geometry type region into the corresponding Geant4 object(s).
 void* Geant4Converter::handleRegion(Region region, const set<const TGeoVolume*>& /* volumes */) const {
   G4Region* g4 = data().g4Regions[region];
-  if (!g4) {
+  if ( !g4 ) {
     PrintLevel lvl = debugRegions ? ALWAYS : outputLevel;
-    Region r = region;
+    Region     r   = region;
     g4 = new G4Region(r.name());
 
     // create region info with storeSecondaries flag
@@ -1098,7 +971,7 @@ void* Geant4Converter::handleRegion(Region region, const set<const TGeoVolume*>&
       printout(lvl, "Geant4Converter", "++ %s: Using default cut: %f [mm]",
                r.name(), r.cut()*CLHEP::mm/units::mm);
     }
-    for (const auto& nam : limits )  {
+    for( const auto& nam : limits )  {
       LimitSet ls = m_detDesc.limitSet(nam);
       if (ls.isValid()) {
         const LimitSet::Set& cts = ls.cuts();
@@ -1150,7 +1023,7 @@ void* Geant4Converter::handleRegion(Region region, const set<const TGeoVolume*>&
 /// Convert the geometry type LimitSet into the corresponding Geant4 object(s).
 void* Geant4Converter::handleLimitSet(LimitSet limitset, const set<const TGeoVolume*>& /* volumes */) const {
   G4UserLimits* g4 = data().g4Limits[limitset];
-  if (!g4) {
+  if ( !g4 ) {
     struct LimitPrint  {
       const LimitSet& ls;
       LimitPrint(const LimitSet& lset) : ls(lset) {}
@@ -1214,36 +1087,25 @@ void* Geant4Converter::handleVis(const string& /* name */, VisAttr attr) const {
 void Geant4Converter::handleProperties(Detector::Properties& prp) const {
   map < string, string > processors;
   static int s_idd = 9999999;
-  string id;
-  for (Detector::Properties::const_iterator i = prp.begin(); i != prp.end(); ++i) {
-    const string& nam = (*i).first;
-    const Detector::PropertyValues& vals = (*i).second;
-    if (nam.substr(0, 6) == "geant4") {
-      Detector::PropertyValues::const_iterator id_it = vals.find("id");
-      if (id_it != vals.end()) {
-        id = (*id_it).second;
-      }
-      else {
-        char txt[32];
-        ::snprintf(txt, sizeof(txt), "%d", ++s_idd);
-        id = txt;
-      }
+  for( const auto& [nam, vals] : prp ) {
+    if ( nam.substr(0, 6) == "geant4" ) {
+      auto id_it = vals.find("id");
+      string id = (id_it == vals.end()) ? _toString(++s_idd,"%d") : (*id_it).second;
       processors.emplace(id, nam);
     }
   }
-  for (map<string, string>::const_iterator i = processors.begin(); i != processors.end(); ++i) {
+  for( const auto& p : processors ) {
     const GeoHandler* hdlr = this;
-    string nam = (*i).second;
-    const Detector::PropertyValues& vals = prp[nam];
+    const Detector::PropertyValues& vals = prp[p.second];
     string type = vals.find("type")->second;
-    string tag = type + "_Geant4_action";
+    string tag  = type + "_Geant4_action";
     Detector* detPtr = const_cast<Detector*>(&m_detDesc);
     long result = PluginService::Create<long>(tag, detPtr, hdlr, &vals);
     if (0 == result) {
       throw runtime_error("Failed to locate plugin to interprete files of type"
                           " \"" + tag + "\" - no factory:" + type);
     }
-    result = *(long*) result;
+    result = *(long*)result;
     if (result != 1) {
       throw runtime_error("Failed to invoke the plugin " + tag + " of type " + type);
     }
@@ -1257,7 +1119,7 @@ void* Geant4Converter::handleMaterialProperties(TObject* matrix) const    {
   TGDMLMatrix* gdmlMat = (TGDMLMatrix*)matrix;
   Geant4GeometryInfo& info = data();
   Geant4GeometryInfo::PropertyVector* g4 = info.g4OpticalProperties[gdmlMat];
-  if (!g4) {
+  if ( !g4 ) {
     PrintLevel lvl = debugMaterials ? ALWAYS : outputLevel;
     g4 = new Geant4GeometryInfo::PropertyVector();
     size_t rows = gdmlMat->GetRows();
@@ -1265,7 +1127,7 @@ void* Geant4Converter::handleMaterialProperties(TObject* matrix) const    {
     g4->title   = gdmlMat->GetTitle();
     g4->bins.reserve(rows);
     g4->values.reserve(rows);
-    for(size_t i=0; i<rows; ++i)  {
+    for( size_t i=0; i<rows; ++i )   {
       g4->bins.emplace_back(gdmlMat->Get(i,0)  /*   *CLHEP::eV/units::eV   */);
       g4->values.emplace_back(gdmlMat->Get(i,1));
     }
@@ -1371,7 +1233,7 @@ void* Geant4Converter::handleOpticalSurface(TObject* surface) const    {
   TGeoOpticalSurface* optSurf    = (TGeoOpticalSurface*)surface;
   Geant4GeometryInfo& info = data();
   G4OpticalSurface*   g4   = info.g4OpticalSurfaces[optSurf];
-  if (!g4) {
+  if ( !g4 ) {
     G4SurfaceType          type   = geant4_surface_type(optSurf->GetType());
     G4OpticalSurfaceModel  model  = geant4_surface_model(optSurf->GetModel());
     G4OpticalSurfaceFinish finish = geant4_surface_finish(optSurf->GetFinish());
@@ -1430,7 +1292,7 @@ void* Geant4Converter::handleSkinSurface(TObject* surface) const   {
   TGeoSkinSurface*    surf = (TGeoSkinSurface*)surface;
   Geant4GeometryInfo& info = data();
   G4LogicalSkinSurface* g4 = info.g4SkinSurfaces[surf];
-  if (!g4) {
+  if ( !g4 ) {
     G4OpticalSurface* optSurf  = info.g4OpticalSurfaces[OpticalSurface(surf->GetSurface())];
     G4LogicalVolume*  v = info.g4Volumes[surf->GetVolume()];
     g4 = new G4LogicalSkinSurface(surf->GetName(), v, optSurf);
@@ -1447,7 +1309,7 @@ void* Geant4Converter::handleBorderSurface(TObject* surface) const   {
   TGeoBorderSurface*    surf = (TGeoBorderSurface*)surface;
   Geant4GeometryInfo&   info = data();
   G4LogicalBorderSurface* g4 = info.g4BorderSurfaces[surf];
-  if (!g4) {
+  if ( !g4 ) {
     G4OpticalSurface*  optSurf = info.g4OpticalSurfaces[OpticalSurface(surf->GetSurface())];
     G4VPhysicalVolume* n1 = info.g4Placements[surf->GetNode1()];
     G4VPhysicalVolume* n2 = info.g4Placements[surf->GetNode2()];
@@ -1506,14 +1368,13 @@ string printSolid(G4VSolid* sol) {
 /// Print G4 placement
 void* Geant4Converter::printPlacement(const string& name, const TGeoNode* node) const {
   Geant4GeometryInfo& info = data();
-  G4VPhysicalVolume* g4 = info.g4Placements[node];
-  G4LogicalVolume* vol = info.g4Volumes[node->GetVolume()];
-  G4LogicalVolume* mot = info.g4Volumes[node->GetMotherVolume()];
-  G4VSolid* sol = vol->GetSolid();
-  G4ThreeVector tr = g4->GetObjectTranslation();
-
+  G4VPhysicalVolume*  g4   = info.g4Placements[node];
+  G4LogicalVolume*    vol  = info.g4Volumes[node->GetVolume()];
+  G4LogicalVolume*    mot  = info.g4Volumes[node->GetMotherVolume()];
+  G4VSolid*           sol  = vol->GetSolid();
+  G4ThreeVector       tr   = g4->GetObjectTranslation();
   G4VSensitiveDetector* sd = vol->GetSensitiveDetector();
-  if (!sd)  {
+  if ( !sd )  {
     return g4;
   }
   stringstream str;
@@ -1586,13 +1447,6 @@ Geant4Converter& Geant4Converter::create(DetElement top) {
   // We do not have to handle defines etc.
   // All positions and the like are not really named.
   // Hence, start creating the G4 objects for materials, solids and log volumes.
-
-  //outputLevel = WARNING;
-  //setPrintLevel(VERBOSE);
-  //debugMaterials  = true;
-  //debugElements   = true;
-  //debugReflections  = true;
-  //debugPlacements   = true;
 #if ROOT_VERSION_CODE >= ROOT_VERSION(6,17,0)
   handleArray(this, geo.manager->GetListOfGDMLMatrices(), &Geant4Converter::handleMaterialProperties);
   handleArray(this, geo.manager->GetListOfOpticalSurfaces(), &Geant4Converter::handleOpticalSurface);
@@ -1612,7 +1466,6 @@ Geant4Converter& Geant4Converter::create(DetElement top) {
   handleRMap(this, *m_data,     &Geant4Converter::handleAssembly);
   // Now place all this stuff appropriately
   handleRMap(this, *m_data,     &Geant4Converter::handlePlacement);
-  //handleRMap_(this, *m_places,   &Geant4Converter::handlePlacement2);
 #if ROOT_VERSION_CODE >= ROOT_VERSION(6,17,0)
   /// Handle concrete surfaces
   handleArray(this, geo.manager->GetListOfSkinSurfaces(),   &Geant4Converter::handleSkinSurface);
diff --git a/DDG4/src/Geant4Kernel.cpp b/DDG4/src/Geant4Kernel.cpp
index 4abc60110..fecd4e766 100644
--- a/DDG4/src/Geant4Kernel.cpp
+++ b/DDG4/src/Geant4Kernel.cpp
@@ -63,10 +63,8 @@ Geant4Kernel::PhaseSelector& Geant4Kernel::PhaseSelector::operator=(const PhaseS
 
 /// Phase access to the map
 Geant4ActionPhase& Geant4Kernel::PhaseSelector::operator[](const std::string& nam) const {
-  Geant4ActionPhase* action_phase = m_kernel->getPhase(nam);
-  if ( action_phase ) {
+  if( Geant4ActionPhase* action_phase = m_kernel->getPhase(nam) )
     return *action_phase;
-  }
   throw runtime_error(format("Geant4Kernel", "Attempt to access the nonexisting phase '%s'", nam.c_str()));
 }
 
@@ -176,8 +174,7 @@ Geant4Kernel& Geant4Kernel::createWorker()   {
 
 /// Access worker instance by it's identifier
 Geant4Kernel& Geant4Kernel::worker(unsigned long identifier, bool create_if)    {
-  Workers::iterator i = m_workers.find(identifier);
-  if ( i != m_workers.end() )   {
+  if ( Workers::iterator i=m_workers.find(identifier); i != m_workers.end() )   {
     return *((*i).second);
   }
   else if ( identifier == m_id )  {
@@ -217,9 +214,8 @@ void Geant4Kernel::printProperties()  const  {
   printout(ALWAYS,"Geant4Kernel","UI:           %s", m_uiName.c_str());
   printout(ALWAYS,"Geant4Kernel","NumEvents:    %ld",m_numEvent);
   printout(ALWAYS,"Geant4Kernel","NumThreads:   %d", m_numThreads);
-  for(ClientOutputLevels::const_iterator i=m_clientLevels.begin(); i!=m_clientLevels.end();++i)  {
-    printout(ALWAYS,"Geant4Kernel","OutputLevel[%s]:  %d",(*i).first.c_str(),(*i).second);
-  }
+  for( const auto& [name, level] : m_clientLevels )
+    printout(ALWAYS,"Geant4Kernel","OutputLevel[%s]:  %d", name.c_str(), level);
 }
 
 /// Check property for existence
@@ -239,8 +235,8 @@ void Geant4Kernel::setOutputLevel(const std::string object, PrintLevel new_level
 
 /// Retrieve the global output level of a named object.
 dd4hep::PrintLevel Geant4Kernel::getOutputLevel(const std::string object) const   {
-  ClientOutputLevels::const_iterator i=m_clientLevels.find(object);
-  if ( i != m_clientLevels.end() ) return (PrintLevel)(*i).second;
+  if( auto i=m_clientLevels.find(object); i != m_clientLevels.end() )
+    return (PrintLevel)(*i).second;
   return dd4hep::PrintLevel(dd4hep::printLevel()-1);
 }
 
@@ -347,10 +343,9 @@ int Geant4Kernel::terminate() {
  *  Only register those, you later need to retrieve by name.
  */
 Geant4Kernel& Geant4Kernel::registerGlobalAction(Geant4Action* action) {
-  if (action) {
-    string nam = action->name();
-    GlobalActions::const_iterator i = m_globalActions.find(nam);
-    if (i == m_globalActions.end()) {
+  if( action ) {
+    const string& nam = action->name();
+    if( auto i=m_globalActions.find(nam); i == m_globalActions.end() ) {
       action->addRef();
       m_globalActions[nam] = action;
       printout(INFO,"Geant4Kernel","++ Registered global action %s of type %s",
@@ -366,16 +361,14 @@ Geant4Kernel& Geant4Kernel::registerGlobalAction(Geant4Action* action) {
 }
 
 /// Retrieve action from repository
-Geant4Action* Geant4Kernel::globalAction(const std::string& action_name, bool throw_if_not_present) {
-  GlobalActions::iterator i = m_globalActions.find(action_name);
-  if (i == m_globalActions.end()) {
-    if (throw_if_not_present) {
-       except("Geant4Kernel", "DDG4: The action '%s' is not globally "
-              "registered. [Action-Missing]", action_name.c_str());
-    }
-    return 0;
+Geant4Action* Geant4Kernel::globalAction(const std::string& nam, bool throw_if_not_present) {
+  if( auto i=m_globalActions.find(nam); i != m_globalActions.end() )
+    return (*i).second;
+  if( throw_if_not_present )   {
+    except("Geant4Kernel", "DDG4: The action '%s' is not globally "
+	   "registered. [Action-Missing]", nam.c_str());
   }
-  return (*i).second;
+  return nullptr;
 }
 
 /// Register filter by name to be retrieved when setting up and connecting filter objects
@@ -384,10 +377,9 @@ Geant4Action* Geant4Kernel::globalAction(const std::string& action_name, bool th
  *  Only register those, you later need to retrieve by name.
  */
 Geant4Kernel& Geant4Kernel::registerGlobalFilter(Geant4Action* filter) {
-  if (filter) {
-    string nam = filter->name();
-    GlobalActions::const_iterator i = m_globalFilters.find(nam);
-    if (i == m_globalFilters.end()) {
+  if( filter )   {
+    const string& nam = filter->name();
+    if( auto i=m_globalFilters.find(nam); i == m_globalFilters.end()) {
       filter->addRef();
       m_globalFilters[nam] = filter;
       return *this;
@@ -402,21 +394,18 @@ Geant4Kernel& Geant4Kernel::registerGlobalFilter(Geant4Action* filter) {
 
 /// Retrieve filter from repository
 Geant4Action* Geant4Kernel::globalFilter(const std::string& filter_name, bool throw_if_not_present) {
-  GlobalActions::iterator i = m_globalFilters.find(filter_name);
-  if (i == m_globalFilters.end()) {
-    if (throw_if_not_present) {
-      except("Geant4Kernel", "DDG4: The filter '%s' is not already globally "
-             "registered. [Filter-Missing]", filter_name.c_str());
-    }
-    return 0;
+  if( auto i=m_globalFilters.find(filter_name); i != m_globalFilters.end())
+    return (*i).second;
+  if (throw_if_not_present) {
+    except("Geant4Kernel", "DDG4: The filter '%s' is not already globally "
+	   "registered. [Filter-Missing]", filter_name.c_str());
   }
-  return (*i).second;
+  return nullptr;
 }
 
 /// Execute phase action if it exists
 bool Geant4Kernel::executePhase(const std::string& nam, const void** arguments)  const   {
-  Phases::const_iterator i = m_phases.find(nam);
-  if (i != m_phases.end())   {
+  if( auto i=m_phases.find(nam); i != m_phases.end() )   {
     (*i).second->execute(arguments);
     return true;
   }
@@ -424,13 +413,11 @@ bool Geant4Kernel::executePhase(const std::string& nam, const void** arguments)
 }
 
 /// Access phase by name
-Geant4ActionPhase* Geant4Kernel::getPhase(const std::string& nam) {
-  Phases::const_iterator i = m_phases.find(nam);
-  if (i != m_phases.end()) {
+Geant4ActionPhase* Geant4Kernel::getPhase(const std::string& nam)   {
+  if( auto i=m_phases.find(nam); i != m_phases.end() )
     return (*i).second;
-  }
   except("Geant4Kernel", "DDG4: The Geant4 action phase '%s' does not exist. [No-Entry]", nam.c_str());
-  return 0;
+  return nullptr;
 }
 
 /// Add a new phase to the phase
@@ -441,8 +428,7 @@ Geant4ActionPhase* Geant4Kernel::addSimplePhase(const std::string& name, bool th
 /// Add a new phase
 Geant4ActionPhase* Geant4Kernel::addPhase(const std::string& nam, const type_info& arg0, const type_info& arg1,
                                           const type_info& arg2, bool throw_on_exist) {
-  Phases::const_iterator i = m_phases.find(nam);
-  if (i == m_phases.end()) {
+  if( auto i=m_phases.find(nam); i == m_phases.end() )   {
     Geant4ActionPhase* p = new Geant4ActionPhase(workerContext(), nam, arg0, arg1, arg2);
     m_phases.emplace(nam, p);
     return p;
@@ -450,13 +436,12 @@ Geant4ActionPhase* Geant4Kernel::addPhase(const std::string& nam, const type_inf
   else if (throw_on_exist) {
     except("Geant4Kernel", "DDG4: The Geant4 action phase %s already exists. [Already-Exists]", nam.c_str());
   }
-  return (*i).second;
+  return nullptr;
 }
 
 /// Remove an existing phase from the phase. If not existing returns false
 bool Geant4Kernel::removePhase(const std::string& nam) {
-  Phases::iterator i = m_phases.find(nam);
-  if (i != m_phases.end()) {
+  if( auto i=m_phases.find(nam); i != m_phases.end() )   {
     delete (*i).second;
     m_phases.erase(i);
     return true;
diff --git a/DDG4/src/Geant4Mapping.cpp b/DDG4/src/Geant4Mapping.cpp
index 39d71acaa..5582b9b3e 100644
--- a/DDG4/src/Geant4Mapping.cpp
+++ b/DDG4/src/Geant4Mapping.cpp
@@ -84,8 +84,9 @@ Geant4VolumeManager Geant4Mapping::volumeManager() const {
 PlacedVolume Geant4Mapping::placement(const G4VPhysicalVolume* node) const {
   checkValidity();
   const Geant4GeometryMaps::PlacementMap& pm = m_dataPtr->g4Placements;
-  for (Geant4GeometryMaps::PlacementMap::const_iterator i = pm.begin(); i != pm.end(); ++i)
-    if ((*i).second == node)
-      return PlacedVolume((*i).first);
+  for( const auto& entry : pm )  {
+    if ( entry.second == node )
+      return PlacedVolume(entry.first);
+  }
   return PlacedVolume(0);
 }
diff --git a/DDG4/src/Geant4Particle.cpp b/DDG4/src/Geant4Particle.cpp
index a257a2fdb..313fe9abc 100644
--- a/DDG4/src/Geant4Particle.cpp
+++ b/DDG4/src/Geant4Particle.cpp
@@ -106,8 +106,8 @@ Geant4Particle& Geant4Particle::get_data(Geant4Particle& c)   {
 
 /// Remove daughter from set
 void Geant4Particle::removeDaughter(int id_daughter)  {
-  std::set<int>::iterator j = daughters.find(id_daughter);
-  if ( j != daughters.end() ) daughters.erase(j);
+  if ( std::set<int>::iterator j = daughters.find(id_daughter); j != daughters.end() )
+    daughters.erase(j);
 }
 
 /// Access the Geant4 particle definition object (expensive!)
@@ -124,11 +124,8 @@ const G4ParticleDefinition* Geant4ParticleHandle::definition() const   {
 
 /// Access to the Geant4 particle name
 std::string Geant4ParticleHandle::particleName() const   {
-  const G4ParticleDefinition* def = definition();
-  if ( def )   {
-    //particle->definition = def;
+  if ( const G4ParticleDefinition* def = definition() )
     return def->GetParticleName();
-  }
 #if 0
   TDatabasePDG* db = TDatabasePDG::Instance();
   TParticlePDG* pdef = db->GetParticle(particle->pdgID);
@@ -141,11 +138,8 @@ std::string Geant4ParticleHandle::particleName() const   {
 
 /// Access to the Geant4 particle type
 std::string Geant4ParticleHandle::particleType() const   {
-  const G4ParticleDefinition* def = definition();
-  if ( def )   {
-    //particle->definition = def;
+  if ( const G4ParticleDefinition* def = definition() )
     return def->GetParticleType();
-  }
 #if 0
   TDatabasePDG* db = TDatabasePDG::Instance();
   TParticlePDG* pdef = db->GetParticle(particle->pdgID);
@@ -223,13 +217,11 @@ void Geant4ParticleHandle::offset(int off)  const   {
 
   temp = p->daughters;
   p->daughters.clear();
-  for(std::set<int>::iterator i=temp.begin(); i != temp.end(); ++i)
-    p->daughters.insert((*i)+off);
+  for(auto i : temp) p->daughters.insert(i+off);
 
   temp = p->parents;
   p->parents.clear();
-  for(std::set<int>::iterator i=temp.begin(); i != temp.end(); ++i)
-    p->parents.insert((*i)+off);
+  for(auto i : temp ) p->parents.insert(i+off);
 }
 
 /// Output type 1:+++ <tag>   10 def:0xde4eaa8 [gamma     ,   gamma] reason:      20 E:+1.017927e+03  \#Par:  1/4    \#Dau:  2
@@ -241,8 +233,8 @@ void Geant4ParticleHandle::dump1(int level, const std::string& src, const char*
     ::snprintf(text,sizeof(text),"/%d",*(p->parents.begin()));
   else if ( p->parents.size() >  1 )   {
     text[0]='/';text[1]=0;
-    for(std::set<int>::const_iterator i=p->parents.begin(); i!=p->parents.end(); ++i)
-      ::snprintf(text+strlen(text),sizeof(text)-strlen(text),"%d ",*i);
+    for(int  i : p->parents )
+      ::snprintf(text+strlen(text),sizeof(text)-strlen(text),"%d ",i);
   }
   printout((dd4hep::PrintLevel)level,src,
            "+++ %s %4d def [%-11s,%8s] reason:%8d E:%+.2e %3s #Dau:%3d #Par:%3d%-5s",
@@ -285,8 +277,8 @@ void Geant4ParticleHandle::dumpWithVertex(int level, const std::string& src, con
     ::snprintf(text,sizeof(text),"/%d",*(p->parents.begin()));
   else if ( p->parents.size() >  1 )   {
     text[0]='/';text[1]=0;
-    for(std::set<int>::const_iterator i=p->parents.begin(); i!=p->parents.end(); ++i)
-      ::snprintf(text+strlen(text),sizeof(text)-strlen(text),"%d ",*i);
+    for(int i : p->parents )
+      ::snprintf(text+strlen(text),sizeof(text)-strlen(text),"%d ",i);
   }
   printout((dd4hep::PrintLevel)level,src,
            "+++ %s ID:%3d %-12s status:%08X PDG:%6d Vtx:(%+.2e,%+.2e,%+.2e)[mm] "
@@ -308,8 +300,8 @@ void Geant4ParticleHandle::dumpWithMomentum(int level, const std::string& src, c
     ::snprintf(text,sizeof(text),"/%d",*(p->parents.begin()));
   else if ( p->parents.size() >  1 )   {
     text[0]='/';text[1]=0;
-    for(std::set<int>::const_iterator i=p->parents.begin(); i!=p->parents.end(); ++i)
-      ::snprintf(text+strlen(text),sizeof(text)-strlen(text),"%d ",*i);
+    for(int i : p->parents )
+      ::snprintf(text+strlen(text),sizeof(text)-strlen(text),"%d ",i);
   }
   printout((dd4hep::PrintLevel)level,src,
            "+++%s ID:%3d %-12s stat:%08X PDG:%6d Mom:(%+.2e,%+.2e,%+.2e)[MeV] "
@@ -330,8 +322,8 @@ void Geant4ParticleHandle::dumpWithMomentumAndVertex(int level, const std::strin
     ::snprintf(text,sizeof(text),"/%d",*(p->parents.begin()));
   else if ( p->parents.size() >  1 )   {
     text[0]='/';text[1]=0;
-    for(std::set<int>::const_iterator i=p->parents.begin(); i!=p->parents.end(); ++i)
-      ::snprintf(text+strlen(text),sizeof(text)-strlen(text),"%d ",*i);
+    for(int i : p->parents )
+      ::snprintf(text+strlen(text),sizeof(text)-strlen(text),"%d ",i);
   }
   printout((dd4hep::PrintLevel)level,src,
            "+++%s %3d %-12s stat:%08X PDG:%6d Mom:(%+.2e,%+.2e,%+.2e)[MeV] "
@@ -471,8 +463,8 @@ void Geant4ParticleMap::dump()  const  {
 
   cnt = 0;
   cout << "Particle map:" << endl;
-  for(Geant4ParticleMap::ParticleMap::const_iterator i=m->particleMap.begin(); i!=m->particleMap.end();++i)  {
-    ::snprintf(text,sizeof(text)," [%-4d:%p]",(*i).second->id,(void*)(*i).second);
+  for( const auto& p : m->particleMap )  {
+    ::snprintf(text,sizeof(text)," [%-4d:%p]",p.second->id,(void*)p.second);
     cout << text;
     if ( ++cnt == 8 ) {
       cout << endl;
@@ -483,8 +475,8 @@ void Geant4ParticleMap::dump()  const  {
 
   cnt = 0;
   cout << "Equivalents:" << endl;
-  for(Geant4ParticleMap::TrackEquivalents::const_iterator i=m->equivalentTracks.begin(); i!=m->equivalentTracks.end();++i)  {
-    ::snprintf(text,sizeof(text)," [%-5d : %-5d]",(*i).first,(*i).second);
+  for( const auto& p : m->equivalentTracks )  {
+    ::snprintf(text,sizeof(text)," [%-5d : %-5d]",p.first,p.second);
     cout << text;
     if ( ++cnt == 8 ) {
       cout << endl;
diff --git a/DDG4/src/Geant4ParticleHandler.cpp b/DDG4/src/Geant4ParticleHandler.cpp
index 8ec8c91cc..b725d3d40 100644
--- a/DDG4/src/Geant4ParticleHandler.cpp
+++ b/DDG4/src/Geant4ParticleHandler.cpp
@@ -98,8 +98,7 @@ Geant4ParticleHandler& Geant4ParticleHandler::operator=(const Geant4ParticleHand
 bool Geant4ParticleHandler::adopt(Geant4Action* action)    {
   if ( action )   {
     if ( !m_userHandler )  {
-      Geant4UserParticleHandler* h = dynamic_cast<Geant4UserParticleHandler*>(action);
-      if ( h )  {
+      if ( Geant4UserParticleHandler* h = dynamic_cast<Geant4UserParticleHandler*>(action) )  {
         m_userHandler = h;
         m_userHandler->addRef();
         return true;
@@ -357,10 +356,10 @@ void Geant4ParticleHandler::end(const G4Track* track)   {
     m_equivalentTracks[g4_id] = pid;
     // Need to find the last stored particle and OR this particle's mask
     // with the mask of the last stored particle
-    TrackEquivalents::const_iterator iequiv, iend = m_equivalentTracks.end();
+    auto iend = m_equivalentTracks.end(), iequiv=m_equivalentTracks.end();
     ParticleMap::iterator ip;
     for(ip=m_particleMap.find(pid); ip == m_particleMap.end(); ip=m_particleMap.find(pid))  {
-      if ((iequiv=m_equivalentTracks.find(pid)) == iend) break;  // ERROR
+      if (iequiv=m_equivalentTracks.find(pid); iequiv == iend) break;  // ERROR
       pid = (*iequiv).second;
     }
     if ( ip != m_particleMap.end() )
@@ -615,8 +614,7 @@ int Geant4ParticleHandler::recombineParents()  {
       //continue;
     }
     else if ( mask.isSet(G4PARTICLE_KEEP_PROCESS) )  {
-      ParticleMap::iterator ip = m_particleMap.find(p->g4Parent);
-      if ( ip != m_particleMap.end() )   {
+      if(ParticleMap::iterator ip = m_particleMap.find(p->g4Parent); ip != m_particleMap.end() )   {
         Particle* parent_part = (*ip).second;
         PropertyMask parent_mask(parent_part->reason);
         if ( parent_mask.isSet(G4PARTICLE_ABOVE_ENERGY_THRESHOLD) )   {
@@ -631,10 +629,9 @@ int Geant4ParticleHandler::recombineParents()  {
     /// Remove this track from the list and also do the cleanup in the parent's children list
     if ( remove_me )  {
       int g4_id = (*i).first;
-      ParticleMap::iterator ip = m_particleMap.find(p->g4Parent);
       remove.insert(g4_id);
       m_equivalentTracks[g4_id] = p->g4Parent;
-      if ( ip != m_particleMap.end() )   {
+      if(ParticleMap::iterator ip = m_particleMap.find(p->g4Parent); ip != m_particleMap.end() )   {
         Particle* parent_part = (*ip).second;
         PropertyMask(parent_part->reason).set(mask.value());
         parent_part->steps += p->steps;
@@ -646,9 +643,8 @@ int Geant4ParticleHandler::recombineParents()  {
       }
     }
   }
-  for(set<int>::const_iterator r=remove.begin(); r!=remove.end();++r)  {
-    ParticleMap::iterator ir = m_particleMap.find(*r);
-    if ( ir != m_particleMap.end() )  {
+  for( int r : remove )  {
+    if( auto ir = m_particleMap.find(r); ir != m_particleMap.end() )  {
       (*ir).second->release();
       m_particleMap.erase(ir);
     }
@@ -661,15 +657,15 @@ void Geant4ParticleHandler::checkConsistency()  const   {
   int num_errors = 0;
 
   /// First check the consistency of the particle map itself
-  for(ParticleMap::const_iterator j, i=m_particleMap.begin(); i!=m_particleMap.end(); ++i)  {
-    Geant4ParticleHandle p((*i).second);
+  for(const auto [idx, particle] : m_particleMap )  {
+    Geant4ParticleHandle p(particle);
     PropertyMask mask(p->reason);
     PropertyMask status(p->status);
     set<int>& daughters = p->daughters;
+    ParticleMap::const_iterator j;
     // For all particles, the set of daughters must be contained in the record.
-    for(set<int>::const_iterator id=daughters.begin(); id!=daughters.end(); ++id)   {
-      int id_dau = *id;
-      if ( (j=m_particleMap.find(id_dau)) == m_particleMap.end() )   {
+    for( int id_dau : daughters )   {
+      if ( j=m_particleMap.find(id_dau); j == m_particleMap.end() )   {
         ++num_errors;
         error("+++ Particle:%d Daughter %d is not in particle map!",p->id,id_dau);
       }
@@ -677,12 +673,11 @@ void Geant4ParticleHandler::checkConsistency()  const   {
     // We assume that particles from the generator have consistent parents
     // For all other particles except the primaries, the parent must be contained in the record.
     if ( !mask.isSet(G4PARTICLE_PRIMARY) && !status.anySet(G4PARTICLE_GEN_STATUS) )  {
-      TrackEquivalents::const_iterator eq_it = m_equivalentTracks.find(p->g4Parent);
       bool in_map = false, in_parent_list = false;
-      int parent_id = -1;
-      if ( eq_it != m_equivalentTracks.end() )   {
+      int  parent_id = -1;
+      if( auto eq_it=m_equivalentTracks.find(p->g4Parent); eq_it != m_equivalentTracks.end() )   {
         parent_id = (*eq_it).second;
-        in_map = (j=m_particleMap.find(parent_id)) != m_particleMap.end();
+        in_map    = (j=m_particleMap.find(parent_id)) != m_particleMap.end();
         in_parent_list = p->parents.find(parent_id) != p->parents.end();
       }
       if ( !in_map || !in_parent_list )  {
@@ -690,8 +685,8 @@ void Geant4ParticleHandler::checkConsistency()  const   {
         parent_list[0] = 0;
         ++num_errors;
         p.dumpWithMomentum(ERROR,name(),"INCONSISTENCY");
-        for(set<int>::const_iterator ip=p->parents.begin(); ip!=p->parents.end();++ip)
-          ::snprintf(parent_list+strlen(parent_list),sizeof(parent_list)-strlen(parent_list),"%d ",*ip);
+        for( int ip : p->parents )
+          ::snprintf(parent_list+strlen(parent_list),sizeof(parent_list)-strlen(parent_list),"%d ",ip);
         error("+++ Particle:%d Parent %d (G4id:%d)  In record:%s In parent list:%s [%s]",
               p->id,parent_id,p->g4Parent,yes_no(in_map),yes_no(in_parent_list),parent_list);
       }
@@ -713,7 +708,6 @@ void Geant4ParticleHandler::setVertexEndpointBit() {
     if( p->parents.empty() ) {
       continue;
     }
-
     Geant4Particle *parent(pm[ *p->parents.begin() ]);
     const double X( parent->vex - p->vsx );
     const double Y( parent->vey - p->vsy );
diff --git a/DDG4/src/Geant4PhysicsList.cpp b/DDG4/src/Geant4PhysicsList.cpp
index 0ebc668a7..696a5411b 100644
--- a/DDG4/src/Geant4PhysicsList.cpp
+++ b/DDG4/src/Geant4PhysicsList.cpp
@@ -107,26 +107,21 @@ void Geant4PhysicsList::dump()    {
   if ( !m_physics.empty() && !m_particles.empty() && !m_processes.empty() )  {
     printout(ALWAYS,name(),"+++ Geant4PhysicsList Dump");
   }
-  for (PhysicsConstructors::const_iterator i = m_physics.begin(); i != m_physics.end(); ++i)
-    printout(ALWAYS,name(),"+++ PhysicsConstructor:           %s",(*i).c_str());
-  for (ParticleConstructors::const_iterator i = m_particles.begin(); i != m_particles.end(); ++i)
-    printout(ALWAYS,name(),"+++ ParticleConstructor:          %s",(*i).c_str());
-  for (ParticleConstructors::const_iterator i = m_particlegroups.begin(); i != m_particlegroups.end(); ++i)
-    printout(ALWAYS,name(),"+++ ParticleGroupConstructor:     %s",(*i).c_str());
-  for (PhysicsProcesses::const_iterator i = m_discreteProcesses.begin(); i != m_discreteProcesses.end(); ++i)  {
-    const string& part_name = (*i).first;
-    const ParticleProcesses& procs = (*i).second;
+  for ( const auto& p : m_physics)
+    printout(ALWAYS,name(),"+++ PhysicsConstructor:           %s",p.c_str());
+  for ( const auto& p : m_particles )
+    printout(ALWAYS,name(),"+++ ParticleConstructor:          %s",p.c_str());
+  for ( const auto& p : m_particlegroups )
+    printout(ALWAYS,name(),"+++ ParticleGroupConstructor:     %s",p.c_str());
+  for ( const auto& [part_name,procs] : m_discreteProcesses )   {
     printout(ALWAYS,name(),"+++ DiscretePhysicsProcesses of particle  %s",part_name.c_str());
     for (ParticleProcesses::const_iterator ip = procs.begin(); ip != procs.end(); ++ip)  {
       printout(ALWAYS,name(),"+++        Process    %s", (*ip).name.c_str());
     }
   }
-  for (PhysicsProcesses::const_iterator i = m_processes.begin(); i != m_processes.end(); ++i)  {
-    const string& part_name = (*i).first;
-    const ParticleProcesses& procs = (*i).second;
+  for ( const auto& [part_name, procs] : m_processes )  {
     printout(ALWAYS,name(),"+++ PhysicsProcesses of particle  %s",part_name.c_str());
-    for (ParticleProcesses::const_iterator ip = procs.begin(); ip != procs.end(); ++ip)  {
-      const Process& p = (*ip);
+    for ( const Process& p : procs )    {
       printout(ALWAYS,name(),"+++        Process    %s  ordAtRestDoIt=%d ordAlongSteptDoIt=%d ordPostStepDoIt=%d",
                p.name.c_str(),p.ordAtRestDoIt,p.ordAlongSteptDoIt,p.ordPostStepDoIt);
     }
@@ -174,40 +169,32 @@ void Geant4PhysicsList::addPhysicsConstructor(const std::string& phys_name)  {
 
 /// Access processes for one particle type
 Geant4PhysicsList::ParticleProcesses& Geant4PhysicsList::processes(const string& nam)  {
-  PhysicsProcesses::iterator i = m_processes.find(nam);
-  if (i != m_processes.end())  {
+  if (auto i = m_processes.find(nam); i != m_processes.end())
     return (*i).second;
-  }
   auto ret = m_processes.emplace(nam, ParticleProcesses());
   return (*(ret.first)).second;
 }
 
 /// Access processes for one particle type (CONST)
 const Geant4PhysicsList::ParticleProcesses& Geant4PhysicsList::processes(const string& nam) const {
-  PhysicsProcesses::const_iterator i = m_processes.find(nam);
-  if (i != m_processes.end())  {
+  if (auto i = m_processes.find(nam); i != m_processes.end())
     return (*i).second;
-  }
   except("Failed to access the physics process '%s' [Unknown-Process]", nam.c_str());
   throw runtime_error("Failed to access the physics process"); // never called anyway
 }
 
 /// Access discrete processes for one particle type
 Geant4PhysicsList::ParticleProcesses& Geant4PhysicsList::discreteProcesses(const string& nam)  {
-  PhysicsProcesses::iterator i = m_discreteProcesses.find(nam);
-  if (i != m_discreteProcesses.end())  {
+  if (auto i = m_discreteProcesses.find(nam); i != m_discreteProcesses.end())
     return (*i).second;
-  }
   pair<PhysicsProcesses::iterator, bool> ret = m_discreteProcesses.emplace(nam, ParticleProcesses());
   return (*(ret.first)).second;
 }
 
 /// Access discrete processes for one particle type (CONST)
 const Geant4PhysicsList::ParticleProcesses& Geant4PhysicsList::discreteProcesses(const string& nam) const {
-  PhysicsProcesses::const_iterator i = m_discreteProcesses.find(nam);
-  if (i != m_discreteProcesses.end())  {
+  if (auto i = m_discreteProcesses.find(nam); i != m_discreteProcesses.end())
     return (*i).second;
-  }
   except("Failed to access the physics process '%s' [Unknown-Process]", nam.c_str());
   throw runtime_error("Failed to access the physics process"); // never called anyway
 }
@@ -215,8 +202,7 @@ const Geant4PhysicsList::ParticleProcesses& Geant4PhysicsList::discreteProcesses
 /// Add PhysicsConstructor by name
 void Geant4PhysicsList::adoptPhysicsConstructor(Geant4Action* action)  {
   if ( 0 != action )   {
-    G4VPhysicsConstructor* p = dynamic_cast<G4VPhysicsConstructor*>(action);
-    if ( p )   {
+    if ( G4VPhysicsConstructor* p = dynamic_cast<G4VPhysicsConstructor*>(action) )  {
       PhysicsConstructor ctor(action->name());
       ctor.pointer = p;
       action->addRef();
@@ -231,15 +217,13 @@ void Geant4PhysicsList::adoptPhysicsConstructor(Geant4Action* action)  {
 /// Callback to construct particle decays
 void Geant4PhysicsList::constructPhysics(G4VModularPhysicsList* physics_pointer)  {
   debug("constructPhysics %p", physics_pointer);
-  for (PhysicsConstructors::iterator i=m_physics.begin(); i != m_physics.end(); ++i)  {
-    PhysicsConstructors::value_type& ctor = *i;
+  for ( auto& ctor : m_physics )   {
     if ( 0 == ctor.pointer )   {
-      G4VPhysicsConstructor* p = PluginService::Create<G4VPhysicsConstructor*>(ctor);
-      if (!p)  {
-        except("Failed to create the physics entities "
-               "for the G4VPhysicsConstructor '%s'", ctor.c_str());
+      if ( G4VPhysicsConstructor* p = PluginService::Create<G4VPhysicsConstructor*>(ctor) )  {
+	ctor.pointer = p;
+	continue;
       }
-      ctor.pointer = p;
+      except("Failed to create the physics for G4VPhysicsConstructor '%s'", ctor.c_str());
     }
     physics_pointer->RegisterPhysics(ctor.pointer);
     info("Registered Geant4 physics constructor %s to physics list", ctor.c_str());
@@ -250,10 +234,9 @@ void Geant4PhysicsList::constructPhysics(G4VModularPhysicsList* physics_pointer)
 void Geant4PhysicsList::constructParticles(G4VUserPhysicsList* physics_pointer)   {
   debug("constructParticles %p", physics_pointer);
   /// Now define all particles
-  for (ParticleConstructors::const_iterator i = m_particles.begin(); i != m_particles.end(); ++i)   {
-    const ParticleConstructors::value_type& ctor = *i;
+  for ( const auto& ctor : m_particles )   {
     G4ParticleDefinition* def = PluginService::Create<G4ParticleDefinition*>(ctor);
-    if (!def)  {
+    if ( !def )  {
       /// Check if we have here a particle group constructor
       long* result = (long*) PluginService::Create<long>(ctor);
       if (!result || *result != 1L)   {
@@ -263,8 +246,7 @@ void Geant4PhysicsList::constructParticles(G4VUserPhysicsList* physics_pointer)
     }
   }
   /// Now define all particles
-  for (ParticleConstructors::const_iterator i = m_particlegroups.begin(); i != m_particlegroups.end(); ++i)  {
-    const ParticleConstructors::value_type& ctor = *i;
+  for ( const auto& ctor : m_particlegroups )  {
     /// Check if we have here a particle group constructor
     long* result = (long*) PluginService::Create<long>(ctor);
     if (!result || *result != 1L)  {
@@ -277,50 +259,42 @@ void Geant4PhysicsList::constructParticles(G4VUserPhysicsList* physics_pointer)
 /// Callback to construct processes (uses the G4 particle table)
 void Geant4PhysicsList::constructProcesses(G4VUserPhysicsList* physics_pointer)   {
   debug("constructProcesses %p", physics_pointer);
-  for (PhysicsProcesses::const_iterator i = m_discreteProcesses.begin(); i != m_discreteProcesses.end(); ++i)  {
-    const string& part_name = (*i).first;
-    const ParticleProcesses& procs = (*i).second;
+  for ( const auto& [part_name, procs] : m_discreteProcesses )  {
     vector<G4ParticleDefinition*> defs(Geant4ParticleHandle::g4DefinitionsRegEx(part_name));
-    if (defs.empty())  {
+    if ( defs.empty() )  {
       except("Particle:%s Cannot find the corresponding entry in the particle table.", part_name.c_str());
     }
-    for (vector<G4ParticleDefinition*>::const_iterator id = defs.begin(); id != defs.end(); ++id)  {
-      G4ParticleDefinition* particle = *id;
+    for ( G4ParticleDefinition* particle : defs )   {
       G4ProcessManager* mgr = particle->GetProcessManager();
-      for (ParticleProcesses::const_iterator ip = procs.begin(); ip != procs.end(); ++ip)  {
-        const Process& p = (*ip);
-        G4VProcess* g4 = PluginService::Create<G4VProcess*>(p.name);
-        if (!g4)  {   // Error no factory for this process
-          except("Particle:%s -> [%s] Cannot create discrete physics process %s", 
-                 part_name.c_str(), particle->GetParticleName().c_str(), p.name.c_str());
-        }
-        mgr->AddDiscreteProcess(g4);
-        info("Particle:%s -> [%s] added discrete process %s", 
-             part_name.c_str(), particle->GetParticleName().c_str(), p.name.c_str());
+      for ( const Process& p : procs )  {
+        if ( G4VProcess* g4 = PluginService::Create<G4VProcess*>(p.name) )   {
+	  mgr->AddDiscreteProcess(g4);
+	  info("Particle:%s -> [%s] added discrete process %s", 
+	       part_name.c_str(), particle->GetParticleName().c_str(), p.name.c_str());
+	  continue;
+	}
+	except("Particle:%s -> [%s] Cannot create discrete physics process %s", 
+	       part_name.c_str(), particle->GetParticleName().c_str(), p.name.c_str());
       }
     }
   }
-  for (PhysicsProcesses::const_iterator i = m_processes.begin(); i != m_processes.end(); ++i)  {
-    const string& part_name = (*i).first;
-    const ParticleProcesses& procs = (*i).second;
+  for ( const auto& [part_name, procs] : m_processes )   {
     vector<G4ParticleDefinition*> defs(Geant4ParticleHandle::g4DefinitionsRegEx(part_name));
     if (defs.empty())  {
       except("Particle:%s Cannot find the corresponding entry in the particle table.", part_name.c_str());
     }
-    for (vector<G4ParticleDefinition*>::const_iterator id = defs.begin(); id != defs.end(); ++id)  {
-      G4ParticleDefinition* particle = *id;
+    for ( G4ParticleDefinition* particle : defs )   {
       G4ProcessManager* mgr = particle->GetProcessManager();
-      for (ParticleProcesses::const_iterator ip = procs.begin(); ip != procs.end(); ++ip)  {
-        const Process& p = (*ip);
-        G4VProcess* g4 = PluginService::Create<G4VProcess*>(p.name);
-        if (!g4)  {   // Error no factory for this process
-          except("Particle:%s -> [%s] Cannot create physics process %s", 
-                 part_name.c_str(), particle->GetParticleName().c_str(), p.name.c_str());
-        }
-        mgr->AddProcess(g4, p.ordAtRestDoIt, p.ordAlongSteptDoIt, p.ordPostStepDoIt);
-        info("Particle:%s -> [%s] added process %s with flags (%d,%d,%d)", 
-             part_name.c_str(), particle->GetParticleName().c_str(), p.name.c_str(),
-             p.ordAtRestDoIt, p.ordAlongSteptDoIt, p.ordPostStepDoIt);
+      for ( const Process& p : procs )  {
+        if ( G4VProcess* g4 = PluginService::Create<G4VProcess*>(p.name) )   {
+	  mgr->AddProcess(g4, p.ordAtRestDoIt, p.ordAlongSteptDoIt, p.ordPostStepDoIt);
+	  info("Particle:%s -> [%s] added process %s with flags (%d,%d,%d)", 
+	       part_name.c_str(), particle->GetParticleName().c_str(), p.name.c_str(),
+	       p.ordAtRestDoIt, p.ordAlongSteptDoIt, p.ordPostStepDoIt);
+	  continue;
+	}
+	except("Particle:%s -> [%s] Cannot create physics process %s", 
+	       part_name.c_str(), particle->GetParticleName().c_str(), p.name.c_str());
       }
     }
   }
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 23b87c2a6..abb2c61e9 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -55,7 +55,7 @@ FOREACH(DDExample IN LISTS DD4HEP_EXAMPLES)
   add_subdirectory(${DDExample})
 ENDFOREACH()
 
-###add_subdirectory(DDUpgrade)
+add_subdirectory(DDUpgrade)
 
 if(APPLE)
   SET ( ENV{DD4HEP_LIBRARY_PATH} $ENV{DYLD_LIBRARY_PATH} )
diff --git a/examples/DDCAD/compact/MultiShape_MS3D_jeep-original.xml b/examples/DDCAD/compact/MultiShape_MS3D_jeep-original.xml
new file mode 100644
index 000000000..57328ac49
--- /dev/null
+++ b/examples/DDCAD/compact/MultiShape_MS3D_jeep-original.xml
@@ -0,0 +1,56 @@
+<lccdd>
+<!-- #==========================================================================
+     #  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.
+     #
+     #==========================================================================
+-->
+
+  <includes>
+    <gdmlFile ref="../../ClientTests/compact/CheckShape.xml"/>
+  </includes>
+
+  <detectors>
+    <detector id="1" name="Shape_OBJ" type="DD4hep_TestShape_Creator">
+      <check>
+        <shape type="CAD_MultiVolume" ref="${DD4hepExamplesINSTALL}/examples/DDCAD/models/MS3D/jeep1.ms3d" unit="cm">
+
+          <!--      Envelope definition
+                    This is optional: By default the child volumes are placed in an assembly.
+          -->
+          <envelope name="Garage" material="Air" vis="Shape_grey">
+            <shape type="Box" dx="10*cm" dy="10*cm" dz="10*cm"/>
+          </envelope>
+
+          <!--      Transformation defining the positioning of all sub-volumes within the envelope  -->
+          <position x="-5*cm" y="0" z="0"/>
+          <rotation x="0" y="0" z="-pi/2*rad"/>
+
+          <!--      These are the 4 wheels  -->
+          <volume id="0" name="Wheel1" material="Iron" vis="Shape4_vis">
+          </volume>
+          <volume id="1" name="Wheel2" material="Iron" vis="Shape4_vis">
+          </volume>
+          <volume id="2" name="Wheel3" material="Iron" vis="Shape4_vis">
+          </volume>
+          <volume id="3" name="Wheel4" material="Iron" vis="Shape4_vis">
+          </volume>
+
+          <!--      This is the rest of the jeep  -->
+          <volume id="4" name="E" material="Iron" vis="Shape4_vis">
+          </volume>
+          <volume id="5" name="F" material="Iron" vis="Shape4_vis">
+          </volume>
+          <volume id="6" name="C" material="Iron" vis="Shape4_vis">
+          </volume>
+        </shape>
+      </check>
+
+    </detector>
+  </detectors>
+</lccdd>
-- 
GitLab