diff --git a/DDCore/include/DD4hep/Volumes.h b/DDCore/include/DD4hep/Volumes.h
index 98ea1231e488ed108f4c8e315bf5f8f91c25593e..81bda5cd15af9625b23bb2d9e2381ad9d1dffee6 100644
--- a/DDCore/include/DD4hep/Volumes.h
+++ b/DDCore/include/DD4hep/Volumes.h
@@ -375,6 +375,7 @@ namespace dd4hep {
     enum ReplicationAxis  {
       REPLICATED    = 1UL << 4,
       PARAMETERIZED = 1UL << 5,
+      Undefined     = 1UL << 7,
       X_axis        = 1UL << 8,
       Y_axis        = 1UL << 9,
       Z_axis        = 1UL << 10,
diff --git a/DDCore/include/Parsers/detail/Dimension.h b/DDCore/include/Parsers/detail/Dimension.h
index 98b4ad2d709bc95b71dd647e0cfc4fafbddf0f2d..6ccb6819d3c06b8c2b1de8c841f2b06635400fe8 100644
--- a/DDCore/include/Parsers/detail/Dimension.h
+++ b/DDCore/include/Parsers/detail/Dimension.h
@@ -102,13 +102,13 @@ namespace dd4hep {
       double gamma() const;
       /// Access rotation constants: angle
       double gamma(double default_value) const;
-      /// Access rotation constants: angle
+      /// Access rotation constants: delta
       double delta() const;
-      /// Access rotation constants: angle
+      /// Access rotation constants: delta
       double delta(double default_value) const;
-      /// Access rotation constants: angle
+      /// Access rotation constants: epsilon
       double epsilon() const;
-      /// Access rotation constants: angle
+      /// Access rotation constants: epsilon
       double epsilon(double default_value) const;
       /// Access rotation constants: theta
       double theta() const;
@@ -191,9 +191,13 @@ namespace dd4hep {
       double c() const;
       /// Access parameters: c
       double c(double default_value) const;
-      ///Access parameters: distance
+      /// Access rotation constants: dist
+      double dist() const;
+      /// Access rotation constants: dist
+      double dist(double default_value) const;
+      /// Access parameters: distance
       double distance() const;
-      ///Access parameters: distance
+      /// Access parameters: distance
       double distance(double default_value) const;
       /// Access parameters: fraction
       double fraction()  const;
@@ -525,6 +529,8 @@ namespace dd4hep {
       /// Access attribute values: offset
       double offset(double default_value) const;
 
+      /// Access attribute values: count
+      int count() const;
       /// Access attribute values: item
       int item() const;
       /// Access attribute values: items
@@ -575,6 +581,8 @@ namespace dd4hep {
       double phi_tilt() const;
       /// Access attribute values: nphi
       int    nphi() const;
+      /// Access attribute values: replicate
+      int    replicate() const;
       /// Access attribute values: rc
       double rc() const;
 
diff --git a/DDCore/include/Parsers/detail/Dimension.imp b/DDCore/include/Parsers/detail/Dimension.imp
index f22e6cc03025a375febeae6553b6447ffc4e4620..e9c27e70326b0050b3860579370f3f23f3cf2ff8 100644
--- a/DDCore/include/Parsers/detail/Dimension.imp
+++ b/DDCore/include/Parsers/detail/Dimension.imp
@@ -83,6 +83,7 @@ XML_ATTR_ACCESSOR(double, inner_z)
 XML_ATTR_ACCESSOR_DOUBLE(a)
 XML_ATTR_ACCESSOR_DOUBLE(b)
 XML_ATTR_ACCESSOR_DOUBLE(c)
+XML_ATTR_ACCESSOR_DOUBLE(dist)
 XML_ATTR_ACCESSOR_DOUBLE(distance)
 XML_ATTR_ACCESSOR_DOUBLE(g)
 XML_ATTR_ACCESSOR_DOUBLE(A)
@@ -151,7 +152,9 @@ XML_ATTR_ACCESSOR(double, gap)
 XML_ATTR_ACCESSOR(double, z_length)
 XML_ATTR_ACCESSOR(double, zhalf)
 XML_ATTR_ACCESSOR(double, phi_tilt)
+XML_ATTR_ACCESSOR(int, count)
 XML_ATTR_ACCESSOR(int, nphi)
+XML_ATTR_ACCESSOR(int, replicate)
 XML_ATTR_ACCESSOR(double, rc)
 XML_ATTR_ACCESSOR(int, nz)
 XML_ATTR_ACCESSOR(int, key)
diff --git a/DDCore/include/XML/UnicodeValues.h b/DDCore/include/XML/UnicodeValues.h
index 0e088210ff1cf9482b4a79812a6554b7194e8508..89d4ec706704eb648d2a89f1af67c6b056ef75a9 100644
--- a/DDCore/include/XML/UnicodeValues.h
+++ b/DDCore/include/XML/UnicodeValues.h
@@ -52,6 +52,7 @@ UNICODE (attribute);
 UNICODE (attributes);
 UNICODE (aunit);
 UNICODE (author);
+UNICODE (axis);
 
 UNICODE (b);
 UNICODE (B);
@@ -64,7 +65,6 @@ UNICODE (box);
 UNICODE (build);
 
 UNICODE (c);
-UNICODE (distance);
 UNICODE (C);
 UNICODE (calorimeter);
 UNICODE (cartesian_grid_xy);
@@ -95,6 +95,7 @@ UNICODE (connected);
 UNICODE (cons);
 UNICODE (constant);
 UNICODE (correction);
+UNICODE (count);
 UNICODE (create);
 UNICODE (crossing_angle);
 UNICODE (cut);
@@ -121,6 +122,8 @@ UNICODE (dipole_coeff);
 UNICODE (disk);
 UNICODE (disks);
 UNICODE (display);
+UNICODE (dist);
+UNICODE (distance);
 UNICODE (division);
 UNICODE (dr);
 UNICODE (drawing_style);
@@ -402,6 +405,7 @@ UNICODE (region);
 UNICODE (regions);
 UNICODE (regionref);
 UNICODE (repeat);
+UNICODE (replicate);
 UNICODE (rhi);
 UNICODE (ring);
 UNICODE (rlo);
diff --git a/DDCore/src/Volumes.cpp b/DDCore/src/Volumes.cpp
index 00a38f6f4f148ac2504802d575492716819b3c85..582428c600d460ab03d9812eba783550bafdd990 100644
--- a/DDCore/src/Volumes.cpp
+++ b/DDCore/src/Volumes.cpp
@@ -1001,6 +1001,8 @@ PlacedVolume Volume::paramVolume3D(const Transform3D& start,
   data->params->addref();
   data->params->flags = PARAMETERIZED;
   data->params->start = start;
+  data->params->trafo1D.first  = trafo_1;
+  data->params->trafo1D.second = count_1;
   data->params->trafo2D.first  = trafo_2;
   data->params->trafo2D.second = count_2;
   data->params->trafo3D.first  = trafo_3;
diff --git a/DDG4/examples/initAClick.C b/DDG4/examples/initAClick.C
index 77d8c2e8bbed07a4acd73a04532b5516af31d157..f712a13ee38e8220131a358197512c9e686345bd 100644
--- a/DDG4/examples/initAClick.C
+++ b/DDG4/examples/initAClick.C
@@ -84,21 +84,22 @@ int initAClick(const char* command=0)  {
 #ifndef __APPLE__
   libs += " -lCore -lMathCore -pthread -lm -ldl -rdynamic";
 #endif
-  libs += " " +dd4hep+"/lib/libDD4hepGaudiPluginMgr." + ext;
-  libs += " " +dd4hep+"/lib/libDDCore."+ ext;
-  libs += " " +dd4hep+"/lib/libDDG4."+ ext;
+  //libs += " " +dd4hep+"/lib/libDD4hepGaudiPluginMgr." + ext;
+  //libs += " " +dd4hep+"/lib/libDDCore."+ ext;
+  //libs += " " +dd4hep+"/lib/libDDG4."+ ext;
+  libs += " -L" +dd4hep+"/lib ";  // -lDD4hepGaudiPluginMgr -lDDCore -lDDG4";
 #ifdef __APPLE__
-  gSystem->Load("libDD4hepGaudiPluginMgr");
+  int ret = gSystem->Load("libDD4hepGaudiPluginMgr");
+#else
+  //int ret = gSystem->Load("libDDG4Plugins");
+  int ret = gSystem->Load("libDD4hepGaudiPluginMgr");
 #endif
   gSystem->AddIncludePath(inc.c_str());
   gSystem->AddLinkedLibs(libs.c_str());
   std::cout << "+++ Includes:   " << gSystem->GetIncludePath() << std::endl;
   std::cout << "+++ Linked libs:" << gSystem->GetLinkedLibs()  << std::endl;
-  int ret = 0;  // gSystem->Load("libDDG4Plugins");
-  if ( 0 == ret )   {
-    if ( command )  {
-      processCommand(command, true);
-    }
+  if ( command )  {
+    processCommand(command, true);
   }
   return ret;
 }
diff --git a/DDG4/include/DDG4/Geant4Helpers.h b/DDG4/include/DDG4/Geant4Helpers.h
index 827e07e1d20aec86811391fa10a190b83a1bfa62..791017bb0a9590733928cc01da71413e7e465388 100644
--- a/DDG4/include/DDG4/Geant4Helpers.h
+++ b/DDG4/include/DDG4/Geant4Helpers.h
@@ -69,8 +69,15 @@ namespace dd4hep {
     
     /// These conversions automatically apply the conversion from CM to MM!
 
-    G4Transform3D g4Transform(const double translation[]);
-    G4Transform3D g4Transform(const double translation[], const double rotation[]);
+    void          g4Transform(const double* translation, const double* rotation, G4Transform3D& transform);
+    void          g4Transform(const Position& pos, const Rotation3D& rot, G4Transform3D& transform);
+    void          g4Transform(const double* translation, G4Transform3D& transform);
+    void          g4Transform(const Transform3D& matrix, G4Transform3D& transform);
+    void          g4Transform(const TGeoMatrix* matrix, G4Transform3D& transform);
+    void          g4Transform(const TGeoMatrix& matrix, G4Transform3D& transform);
+
+    G4Transform3D g4Transform(const double* translation);
+    G4Transform3D g4Transform(const double* translation, const double* rotation);
 
     G4Transform3D g4Transform(const Transform3D& matrix);
     G4Transform3D g4Transform(const Position& pos, const Rotation3D& rot);
diff --git a/DDG4/include/DDG4/Geant4PlacementParameterisation.h b/DDG4/include/DDG4/Geant4PlacementParameterisation.h
index d9c45b42689b99bc303b8d2da9f4e9d0761e5e7b..641e20e8eb3ca8257f5d18e42846517ecc23aa02 100644
--- a/DDG4/include/DDG4/Geant4PlacementParameterisation.h
+++ b/DDG4/include/DDG4/Geant4PlacementParameterisation.h
@@ -62,18 +62,22 @@ namespace dd4hep {
       using Translations = std::vector<G4ThreeVector>;
       using Dimensions   = std::vector<Dimension>;
 
-      /// Setup parameters
+      /// Setup parameters: Reference to the DD4hep placement handle
+      PlacedVolume         m_placement;
+      /// Setup parameters: Reference to the DD4hep placement parameters
+      const Parameters&    m_params;
+      /// Setup parameters: Initial parameterisation position
       Dimension            m_start          {  };
+      /// Setup parameters: Dimensional parameter setup
       Dimensions           m_dimensions     {  };
-      EAxis                m_axis           { kUndefined };
 
+      /// Axis definition
+      EAxis                m_axis           { kUndefined };
+      /// Total number of parameterized cells
+      size_t               m_num_cells      { 0UL };
       /// Optimization flag for simple parameteristions
       bool                 m_have_rotation  { false };
 
-      /// Reference to the DD4hep placement handle
-      PlacedVolume         m_placement;
-      const Parameters&    m_params;
-
       /// Cached rotations and translations for complex parameterisations
       mutable Rotations    m_rotations;
       mutable Translations m_translations;
diff --git a/DDG4/src/Geant4Converter.cpp b/DDG4/src/Geant4Converter.cpp
index 794693e6f8dc5e4b5045b5c5115aacbc419a7337..c86bd3e7fb29975d3730b9e2010851c33227bba5 100644
--- a/DDG4/src/Geant4Converter.cpp
+++ b/DDG4/src/Geant4Converter.cpp
@@ -31,8 +31,7 @@
 #include "Geant4ShapeConverter.h"
 
 // ROOT includes
-#include <TMath.h>
-#include <TROOT.h>
+#include <TClass.h>
 #include <TGeoBoolNode.h>
 
 // Geant4 include files
@@ -53,7 +52,6 @@
 
 #include <G4Region.hh>
 #include <G4Element.hh>
-#include <G4Element.hh>
 #include <G4Isotope.hh>
 #include <G4Material.hh>
 #include <G4UserLimits.hh>
@@ -594,7 +592,8 @@ void* Geant4Converter::handleSolid(const string& name, const TGeoShape* shape) c
       }
 
       if ( matrix->IsRotation() ) {
-        G4Transform3D transform(g4Transform(matrix));
+        G4Transform3D transform;
+	g4Transform(matrix, transform);
         if (oper == TGeoBoolNode::kGeoSubtraction)
           solid = new G4SubtractionSolid(name, left, right, transform);
         else if (oper == TGeoBoolNode::kGeoUnion)
@@ -728,8 +727,9 @@ void* Geant4Converter::handleAssembly(const string& name, const TGeoNode* node)
       TGeoNode*     dau     = mot_vol->GetNode(i);
       TGeoVolume*   dau_vol = dau->GetVolume();
       TGeoMatrix*   tr      = dau->GetMatrix();
-      G4Transform3D transform(g4Transform(tr));
+      G4Transform3D transform;
 
+      g4Transform(tr, transform);
       if ( is_left_handed(tr) )   {
         G4Scale3D     scale;
         G4Rotate3D    rot;
@@ -808,9 +808,10 @@ void* Geant4Converter::handlePlacement(const string& name, const TGeoNode* node)
       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;
-      G4Transform3D transform(g4Transform(tr));
+      G4Transform3D transform;
       Geant4GeometryMaps::VolumeMap::const_iterator volIt = info.g4Volumes.find(mot_vol);
 
+      g4Transform(tr, transform);
       if ( mother_is_assembly )   {
         //
         // Mother is an assembly:
@@ -871,6 +872,15 @@ void* Geant4Converter::handlePlacement(const string& name, const TGeoNode* node)
 	else
 	  except("Geant4Converter",
 		 "++ Replication around unknown axis is not implemented. flags: %16X", flags);
+	auto* g4pv = new G4PVReplica(name,      // its name
+				     g4vol,     // its logical volume
+				     g4mot,     // its mother (logical) volume
+				     axis,      // its replication axis
+				     count,     // Number of replicas
+				     width,     // Distanve between 2 replicas
+				     offset);   // Placement offset in axis direction
+	pvPlaced = { g4pv, nullptr };
+#if 0
 	pvPlaced =
 	  G4ReflectionFactory::Instance()->Replicate(name,      // its name
 						     g4vol,     // its logical volume
@@ -881,6 +891,7 @@ void* Geant4Converter::handlePlacement(const string& name, const TGeoNode* node)
 						     offset);   // Placement offset in axis direction
 	/// Update replica list to avoid additional conversions...
 	auto* g4pv = pvPlaced.second ? pvPlaced.second : pvPlaced.first;
+#endif
 	for( auto& handle : pv_data->params->placements )
 	  info.g4Placements[handle.ptr()] = g4pv;
       }
@@ -899,12 +910,12 @@ void* Geant4Converter::handlePlacement(const string& name, const TGeoNode* node)
       }
       else    {
 	pvPlaced =
-	  G4ReflectionFactory::Instance()->Place(transform, // no rotation
-						 name,      // its name
-						 g4vol,     // its logical volume
-						 g4mot,     // its mother (logical) volume
-						 false,     // no boolean operations
-						 copy,      // its copy number
+	  G4ReflectionFactory::Instance()->Place(transform,     // no rotation
+						 name,          // its name
+						 g4vol,         // its logical volume
+						 g4mot,         // its mother (logical) volume
+						 false,         // no boolean operations
+						 copy,          // its copy number
 						 checkOverlaps);
       }
       printout(debugReflections||debugPlacements ? ALWAYS : lvl, "Geant4Converter",
diff --git a/DDG4/src/Geant4Helpers.cpp b/DDG4/src/Geant4Helpers.cpp
index 7b905b86747e44266bab7a4de53fb91a9d5b53b4..5e5f3fcd05972cf3f4407732b26d786e8fff5a5b 100644
--- a/DDG4/src/Geant4Helpers.cpp
+++ b/DDG4/src/Geant4Helpers.cpp
@@ -26,10 +26,13 @@ namespace  {
   
   /// Overload to access protected constructor
   struct MyTransform3D : public G4Transform3D {
-    MyTransform3D(double XX, double XY, double XZ, double DX, double YX, double YY, double YZ, double DY, double ZX, double ZY,
-                  double ZZ, double DZ)
+#if 0
+    MyTransform3D(double XX, double XY, double XZ, double DX,
+		  double YX, double YY, double YZ, double DY,
+		  double ZX, double ZY, double ZZ, double DZ)
       : G4Transform3D(XX, XY, XZ, DX, YX, YY, YZ, DY, ZX, ZY, ZZ, DZ) {
     }
+#endif
     MyTransform3D(const double* t, const double* r)
       : G4Transform3D(r[0],r[1],r[2],t[0]*CM_2_MM,r[3],r[4],r[5],t[1]*CM_2_MM,r[6],r[7],r[8],t[2]*CM_2_MM)  {
     }
@@ -42,12 +45,9 @@ namespace  {
   class MyG4RotationMatrix : public G4RotationMatrix   {
   public:
     MyG4RotationMatrix() : G4RotationMatrix() {}
-    MyG4RotationMatrix(const double* r)
-      : G4RotationMatrix(r[0],r[1],r[2],r[3],r[4],r[5],r[6],r[7],r[8])  {
+    MyG4RotationMatrix(const double* r) : G4RotationMatrix(r[0],r[1],r[2],r[3],r[4],r[5],r[6],r[7],r[8])  {
     }
   };
-  const double identity[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
-
 }
 
 G4RotationMatrix dd4hep::sim::g4Rotation(const TGeoMatrix* matrix)   {
@@ -76,15 +76,22 @@ G4RotationMatrix dd4hep::sim::g4Rotation(const RotationZYX& rot)   {
   return g4Rotation(Rotation3D(rot));
 }
 
-
 G4Transform3D dd4hep::sim::g4Transform(const double translation[])    {
   return MyTransform3D(translation);
 }
 
-G4Transform3D dd4hep::sim::g4Transform(const double translation[], const double rotation[])    {
+G4Transform3D dd4hep::sim::g4Transform(const double* translation, const double* rotation)    {
   return MyTransform3D(translation, rotation);
 }
 
+void dd4hep::sim::g4Transform(const double translation[], G4Transform3D& transform)    {
+  transform = MyTransform3D(translation);
+}
+
+void dd4hep::sim::g4Transform(const double* translation, const double* rotation, G4Transform3D& transform)    {
+  transform = MyTransform3D(translation, rotation);
+}
+
 G4Transform3D dd4hep::sim::g4Transform(const TGeoMatrix& matrix)   {
   return g4Transform(&matrix);
 }
@@ -95,6 +102,16 @@ G4Transform3D dd4hep::sim::g4Transform(const TGeoMatrix* matrix)   {
     : g4Transform(matrix->GetTranslation());
 }
 
+void dd4hep::sim::g4Transform(const TGeoMatrix* matrix, G4Transform3D& transform)   {
+  matrix->IsRotation()
+    ? g4Transform(matrix->GetTranslation(), matrix->GetRotationMatrix(), transform)
+    : g4Transform(matrix->GetTranslation(), transform);
+}
+
+void dd4hep::sim::g4Transform(const TGeoMatrix& matrix, G4Transform3D& transform)   {
+  g4Transform(&matrix, transform);
+}
+
 G4Transform3D dd4hep::sim::g4Transform(const TGeoTranslation& translation, const TGeoRotation& rotation)   {
   return g4Transform(&translation, &rotation);
 }
@@ -111,6 +128,12 @@ G4Transform3D dd4hep::sim::g4Transform(const Position& pos, const Rotation3D& ro
   return g4Transform(t, r);
 }
 
+void dd4hep::sim::g4Transform(const Position& pos, const Rotation3D& rot, G4Transform3D& transform)   {
+  double r[9], t[3] = {pos.X(), pos.Y(), pos.Z()};
+  rot.GetComponents(r, r+9);
+  g4Transform(t, r, transform);
+}
+
 G4Transform3D dd4hep::sim::g4Transform(const Position& pos, const RotationZYX& rot)   {
   return g4Transform(pos, Rotation3D(rot));
 }
@@ -122,6 +145,13 @@ G4Transform3D dd4hep::sim::g4Transform(const Transform3D& matrix)   {
   return g4Transform(pos, rot);
 }
 
+void dd4hep::sim::g4Transform(const Transform3D& matrix, G4Transform3D& transform)   {
+  Position pos;
+  Rotation3D rot;
+  matrix.GetDecomposition(rot, pos);
+  g4Transform(pos, rot, transform);
+}
+
 /// Generate parameterised placements in 2 dimension according to transformation delta
 G4Transform3D
 dd4hep::sim::generate_placements(const G4Transform3D& start,
diff --git a/DDG4/src/Geant4PlacementParameterisation.cpp b/DDG4/src/Geant4PlacementParameterisation.cpp
index 3261c0485caf6a375105cfcff5e61dc5792069f9..429174d533af36eedc286369b01cd4850d7cbc73 100644
--- a/DDG4/src/Geant4PlacementParameterisation.cpp
+++ b/DDG4/src/Geant4PlacementParameterisation.cpp
@@ -20,39 +20,45 @@
 // Geant4 include files
 #include <G4Transform3D.hh>
 
-    /// Initializing constructor
+/// Initializing constructor
 dd4hep::sim::Geant4PlacementParameterisation::Geant4PlacementParameterisation(PlacedVolume pv)
   : G4VPVParameterisation(), m_placement(pv), m_params(*pv.data()->params)
 {
+  G4Transform3D tr;
   auto& dim = m_dimensions;
-  G4Transform3D start = g4Transform(m_params.start);
-  G4Transform3D tr(g4Transform(m_params.trafo1D.first));
-  m_start = {tr, 0UL};
-  m_have_rotation = false;
+  g4Transform(m_params.start, m_start.delta);
+  m_start.translation = m_start.delta.getTranslation();
+  
+  g4Transform(m_params.trafo1D.first, tr);
   dim.emplace_back(Dimension(tr, m_params.trafo1D.second));
-  m_have_rotation |= dim.back().delta.getRotation().isIdentity();
+
+  m_have_rotation  = false;
+  m_have_rotation |= !dim.back().delta.getRotation().isIdentity();
+  m_num_cells      = m_params.trafo1D.second;
   if ( m_params.trafo2D.second > 0 )   {
-    tr = g4Transform(m_params.trafo2D.first);
+    g4Transform(m_params.trafo2D.first, tr);
     dim.emplace_back(Dimension(tr, m_params.trafo2D.second));
-    m_have_rotation |= dim.back().delta.getRotation().isIdentity();
+    m_have_rotation |= !dim.back().delta.getRotation().isIdentity();
+    m_num_cells     *= m_params.trafo2D.second;
   }
   if ( m_params.trafo3D.second > 0 )   {
-    tr = g4Transform(m_params.trafo3D.first);
+    g4Transform(m_params.trafo3D.first, tr);
     dim.emplace_back(Dimension(tr, m_params.trafo3D.second));
-    m_have_rotation |= dim.back().delta.getRotation().isIdentity();
+    m_have_rotation |= !dim.back().delta.getRotation().isIdentity();
+    m_num_cells     *= m_params.trafo3D.second;
   }
   if ( m_have_rotation )    {
     auto callback = std::bind(&Geant4PlacementParameterisation::operator(),
-			      *this, std::placeholders::_1);
+			      this, std::placeholders::_1);
     if ( dim.size() == 1 )
-      generate_placements(start,
+      generate_placements(m_start.delta,
 			  dim[0].delta, dim[0].count, callback);
     else if ( dim.size() == 2 )
-      generate_placements(start,
+      generate_placements(m_start.delta,
 			  dim[0].delta, dim[0].count,
 			  dim[1].delta, dim[1].count, callback);
     else if ( dim.size() == 3 )
-      generate_placements(start,
+      generate_placements(m_start.delta,
 			  dim[0].delta, dim[0].count,
 			  dim[1].delta, dim[1].count,
 			  dim[2].delta, dim[2].count, callback);
@@ -61,37 +67,35 @@ dd4hep::sim::Geant4PlacementParameterisation::Geant4PlacementParameterisation(Pl
 
 /// Access number of replicas
 std::size_t dd4hep::sim::Geant4PlacementParameterisation::count()  const   {
-  std::size_t ncell = 1;
-  for(const auto& d : m_dimensions) ncell *= d.count;
-  return ncell;
+  return m_num_cells;
 }
 
 /// Callback to store resulting rotation
 void dd4hep::sim::Geant4PlacementParameterisation::operator()(const G4Transform3D& transform)   {
-  m_translations.emplace_back(transform.getTranslation());
+  this->m_translations.emplace_back(transform.getTranslation());
   if ( this->m_have_rotation )   {
     G4RotationMatrix rot = transform.inverse().getRotation();
-    m_rotations.emplace_back(rot);
+    this->m_rotations.emplace_back(rot);
   }
 }
 
 /// G4VPVParameterisation overload: Callback to place sub-volumes
 void dd4hep::sim::Geant4PlacementParameterisation::ComputeTransformation(const G4int copy, G4VPhysicalVolume *pv) const  {
   const auto& dim = m_dimensions;
-  std::size_t nd = dim.size();
+  std::size_t nd  = dim.size();
   if ( !m_have_rotation )    {
     G4ThreeVector tra = m_start.translation;
     if ( nd >= 1 )   {
-      std::size_t dim1 = nd == 1 ? copy : (nd == 2 ? copy%dim[1].count : (nd == 3 ? copy%(dim[1].count*dim[2].count) : 0));
-      tra = dim[0].translation * dim1;
+      std::size_t d1 = (nd == 1) ? copy : (nd >= 2 ? copy%dim[1].count : 0);
+      tra = tra + (dim[0].translation * d1);
     }
     if ( nd >= 2 )   {
-      std::size_t dim2 = nd == 3 ? copy%dim[2].count / dim[0].count : (nd==2 ? copy / dim[0].count : 0);
-      tra = tra + dim[1].translation * dim2;
+      std::size_t d2 = (nd == 2) ? copy / dim[0].count : (nd >= 3 ? copy%dim[2].count / dim[0].count : 0);
+      tra = tra + (dim[1].translation * d2);
     }
     if ( nd >= 3 )   {
-      std::size_t dim3 = nd == 3 ? copy / (dim[0].count*dim[1].count) : 0;
-      tra = tra + dim[2].translation * dim3;
+      std::size_t d3 = (nd == 3) ? copy / (dim[0].count*dim[1].count) : 0;
+      tra = tra + (dim[2].translation * d3);
     }
     pv->SetTranslation(tra);
     return;
diff --git a/examples/ClientTests/CMakeLists.txt b/examples/ClientTests/CMakeLists.txt
index b16248d1b16e5fac19c368d46486ebb659aba466..584584ceb2eccce32bca822250be6b9d79e55a71 100644
--- a/examples/ClientTests/CMakeLists.txt
+++ b/examples/ClientTests/CMakeLists.txt
@@ -276,6 +276,7 @@ dd4hep_add_test_reg( ClientTests_Check_reflection_matrices
 #
 foreach (test Assemblies BoxTrafos CaloEndcapReflection IronCylinder LheD_tracker MagnetFields  
     MiniTel SectorBarrelCalorimeter SiliconBlock NestedSimple NestedDetectors 
+    ParamVolume1D ParamVolume2D ParamVolume3D
     MultiCollections MultiSegmentations )
 
   # Test materials in volumes. Test here the proper access to the materials from the volumes,
@@ -310,6 +311,7 @@ endforeach()
 # MaterialTester no geometry
 # SectorBarrelCalorimeter is bad
 foreach (test Assemblies BoxTrafos CaloEndcapReflection LheD_tracker MagnetFields MiniTel SiliconBlock 
+	 ParamVolume1D ParamVolume2D ParamVolume3D
          NestedSimple NestedDetectors MultiCollections )
   #
   # Test material scans in [origine to 10 meters in y]
@@ -435,12 +437,23 @@ if (DD4HEP_USE_GEANT4)
   else()
     # Geant4 full simulation checks of multi-collection/segmentation detectors
     dd4hep_print("|++> Geant4 fast simulation tests enabled for Geant4 ${Geant4_VERSION}")
-    foreach(script SiliconBlockGFlash SiliconBlockFastSim )
+    foreach(script SiliconBlockGFlash SiliconBlockFastSim)
       dd4hep_add_test_reg( ClientTests_sim_${script}_LONGTEST
         COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh"
         EXEC_ARGS  ${Python_EXECUTABLE} ${ClientTestsEx_INSTALL}/scripts/${script}.py -batch -events 2
+		   -geometry ${ClientTestsEx_INSTALL}/compact/${script}.xml -batch -events 2
         REGEX_PASS "Event 1 Begin event action. Access event related information"
         REGEX_FAIL "Exception;EXCEPTION;ERROR;Error" )
     endforeach(script)
+    #
+    foreach(script ParamVolume1D ParamVolume2D ParamVolume3D)
+      dd4hep_add_test_reg( ClientTests_sim_${script}_LONGTEST
+        COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh"
+        EXEC_ARGS  ${Python_EXECUTABLE} ${ClientTestsEx_INSTALL}/scripts/ParamVolume.py
+    		   -geometry ${script}.xml -batch -events 2
+        REGEX_PASS "Event 1 Begin event action. Access event related information"
+        REGEX_FAIL "Exception;EXCEPTION;ERROR;Error" )
+    endforeach(script)
+    #
   endif()
 endif(DD4HEP_USE_GEANT4)
diff --git a/examples/ClientTests/compact/ParamVolume1D.xml b/examples/ClientTests/compact/ParamVolume1D.xml
index 7d8937cbe7b2aed69f8240e91a34093e0599e8f8..5e2b900f1faf6ba8790cf64c5b4e5909f04c8822 100644
--- a/examples/ClientTests/compact/ParamVolume1D.xml
+++ b/examples/ClientTests/compact/ParamVolume1D.xml
@@ -41,7 +41,7 @@
   </limits>
 
   <detectors>
-    <detector id="1" name="Param1D_1" type="DD4hep_ParamVolume" vis="VisibleGreen" limits="param_limits">
+    <detector id="1" name="Param1D_1" type="DD4hep_ParamVolume" vis="VisibleGreen" readout="Hits1" limits="param_limits">
       <box x="20*cm" y="15*cm" z="150*cm" material="Air"/>
       <param x="15*cm" y="10*cm" z="2*cm" material="Iron" vis="VisibleRed" limits="param_limits">
 	<transformation>
@@ -58,7 +58,8 @@
       <position x="0" y="0" z="175*cm"/>
       <rotation x="0" y="0" z="0"/>
     </detector>
-    <detector id="2" name="Param1D_2" type="DD4hep_ParamVolume" vis="VisibleGreen" limits="param_limits">
+
+    <detector id="2" name="Param1D_2" type="DD4hep_ParamVolume" vis="VisibleGreen" readout="Hits2" limits="param_limits">
       <box x="20*cm" y="100*cm" z="15*cm" material="Air"/>
       <param x="15*cm" y="2*cm" z="10*cm" material="Iron" vis="VisibleBlue" limits="param_limits">
 	<transformation>
@@ -75,7 +76,8 @@
       <position x="0" y="130*cm" z="0*cm"/>
       <rotation x="0" y="0" z="0"/>
     </detector>
-    <detector id="3" name="Param1D_3" type="DD4hep_ParamVolume" vis="VisibleGreen" limits="param_limits">
+
+    <detector id="3" name="Param1D_3" type="DD4hep_ParamVolume" vis="VisibleGreen" readout="Hits3" limits="param_limits">
       <box x="100*cm" y="20*cm"  z="15*cm" material="Air"/>
       <param x="2*cm" y="15*cm" z="10*cm" material="Iron" vis="VisibleYellow" limits="param_limits">
 	<transformation>
@@ -93,7 +95,7 @@
       <rotation x="0" y="0" z="0"/>
     </detector>
 
-    <detector id="4" name="Param1D_4" type="DD4hep_ParamVolume" vis="VisibleGreen" limits="param_limits">
+    <detector id="4" name="Param1D_4" type="DD4hep_ParamVolume" vis="VisibleGreen" readout="Hits4" limits="param_limits">
       <box x="100*cm" y="20*cm"  z="15*cm" material="Air"/>
       <param x="2*cm" y="15*cm" z="10*cm" material="Iron" vis="VisibleViolet" limits="param_limits">
 	<transformation>
@@ -134,19 +136,19 @@
   <readouts>
     <readout name="Hits1">
       <segmentation type="CartesianGridXY" grid_size_x="1*cm" grid_size_y="1*cm"/>
-      <id>system:6,x:12:-6,y:24:-6</id> 
+      <id>system:6,volume:16,x:32:-6,y:48:-6</id> 
     </readout>
     <readout name="Hits2">
       <segmentation type="CartesianGridXY" grid_size_x="1*cm" grid_size_y="1*cm"/>
-      <id>system:6,x:12:-6,y:24:-6</id> 
+      <id>system:6,volume:16,x:32:-6,y:48:-6</id> 
     </readout>
     <readout name="Hits3">
       <segmentation type="CartesianGridXY" grid_size_x="1*cm" grid_size_y="1*cm"/>
-      <id>system:6,x:12:-6,y:24:-6</id> 
+      <id>system:6,volume:16,x:32:-6,y:48:-6</id> 
     </readout>
     <readout name="Hits4">
       <segmentation type="CartesianGridXY" grid_size_x="1*cm" grid_size_y="1*cm"/>
-      <id>system:6,side:2,x:12:-6,y:24:-6</id> 
+      <id>system:6,volume:16,x:32:-6,y:48:-6</id> 
     </readout>
   </readouts>
 
diff --git a/examples/ClientTests/compact/ParamVolume2D.xml b/examples/ClientTests/compact/ParamVolume2D.xml
index 037aab00e7c16a5ca6777b87da2c3772930348f2..988e9ee591439431e18588400a9f99266c991d60 100644
--- a/examples/ClientTests/compact/ParamVolume2D.xml
+++ b/examples/ClientTests/compact/ParamVolume2D.xml
@@ -67,7 +67,7 @@
   <readouts>
     <readout name="Hits1">
       <segmentation type="CartesianGridXY" grid_size_x="1*cm" grid_size_y="1*cm"/>
-      <id>system:6,x:12:-6,y:24:-6</id> 
+      <id>system:6,volume:16,x:32:-6,y:48:-6</id> 
     </readout>
   </readouts>
 
diff --git a/examples/ClientTests/compact/ParamVolume3D.xml b/examples/ClientTests/compact/ParamVolume3D.xml
index a9229f80cae51e69ff712d9c569ab5356a0d5e0f..5768c06af52d8206df29ca156dc8ebd1c6ce3bf3 100644
--- a/examples/ClientTests/compact/ParamVolume3D.xml
+++ b/examples/ClientTests/compact/ParamVolume3D.xml
@@ -58,18 +58,18 @@
 	<transformation>
 	  <!-- Parameterisation in dimension 1 with 20 placements -->
 	  <dim_x repeat="20">
-	    <position x="0*cm" y="0*cm" z="10*cm"/>
-	    <rotation x="0" y="0" z="0"/>
+	    <position x="10*cm" y="0*cm" z="0*cm"/>
+	    <rotation x="0"     y="0"    z="0"/>
 	  </dim_x>
 	  <!-- Parameterisation in dimension 2 with 20 placements -->
 	  <dim_y repeat="20">
 	    <position x="0*cm" y="10*cm" z="0*cm"/>
-	    <rotation x="0" y="0" z="0"/>
+	    <rotation x="0"    y="0"     z="0"/>
 	  </dim_y>
 	  <!-- Parameterisation in dimension 3 with 20 placements -->
 	  <dim_z repeat="20">
-	    <position x="10*cm" y="0*cm" z="0*cm"/>
-	    <rotation x="0" y="0" z="0"/>
+	    <position x="0*cm" y="0*cm" z="10*cm"/>
+	    <rotation x="0"    y="0"    z="0"/>
 	  </dim_z>
 	</transformation>
       </param>
diff --git a/examples/ClientTests/compact/ReplicateVolume.xml b/examples/ClientTests/compact/ReplicateVolume.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a42f2cce8340806906a8912ee559b49ce2b4a932
--- /dev/null
+++ b/examples/ClientTests/compact/ReplicateVolume.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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="${DD4hepINSTALL}/DDDetectors/compact/elements.xml"/>
+    <gdmlFile  ref="${DD4hepINSTALL}/DDDetectors/compact/materials.xml"/>
+  </includes>
+
+  <define>
+    <constant name="world_size" value="30*m"/>
+    <constant name="world_x" value="world_size"/>
+    <constant name="world_y" value="world_size"/>
+    <constant name="world_z" value="world_size"/>
+  </define>
+
+  <display>
+    <vis name="Invisible" showDaughters="false" visible="false"/>
+    <vis name="InvisibleWithChildren" showDaughters="true" visible="false"/>
+    <vis name="VisibleRed"    r="1.0" g="0.0" b="0.0" showDaughters="true" visible="true"/>
+    <vis name="VisibleBlue"   r="0.0" g="0.0" b="1.0" showDaughters="false" visible="true"/>
+    <vis name="VisibleYellow" r="1.0" g="1.0" b="0.0" showDaughters="false" visible="true"/>
+    <vis name="VisibleViolet" r="1.0" g="0.0" b="1.0" showDaughters="false" visible="true"/>
+    <vis name="VisibleGreen" alpha="0.1" r="0.0" g="1.0" b="0.0" drawingStyle="solid" lineStyle="solid" showDaughters="true" visible="true"/>
+  </display>
+
+  <limits>
+    <limitset name="param_limits">
+      <limit name="step_length_max" particles="*" value="5.0" unit="mm" />
+    </limitset>
+  </limits>
+
+  <detectors>
+    <detector id="1" name="Param3D_1" type="DD4hep_ParamVolume" vis="VisibleGreen" readout="Hits3D" limits="param_limits">
+      <!-- Mother volume dimensions  -->
+      <box x="120*cm" y="120*cm" z="120*cm" material="Air"/>
+      <!-- Mother volume placement in the world -->
+      <position x="0*cm" y="0*cm" z="-120*cm"/>
+      <rotation x="0" y="0" z="0"/>
+
+      <!-- Parameterisation arguments -->
+      <param x="15*cm" y="10*cm" z="2*cm" material="Iron" vis="VisibleRed" limits="param_limits">
+	<start>
+	  <!-- Parameterisation start position in the mother volume frame  -->
+	  <position x="0*cm" y="0*cm" z="0*cm"/>
+	  <rotation x="0" y="0" z="0"/>
+	</start>
+	<replicate count="1" distance="10*cm" start="0*cm" axis="z"/>
+      </param>
+    </detector>
+  </detectors>
+  
+  <readouts>
+    <readout name="Hits3D">
+      <segmentation type="CartesianGridXY" grid_size_x="1*mm" grid_size_y="1*mm"/>
+      <id>system:6,volume:16,x:32:-6,y:48:-6</id> 
+    </readout>
+  </readouts>
+
+  <fields>
+    <field name="GlobalSolenoid" type="solenoid" 
+	   inner_field="5.0*tesla"
+	   outer_field="-1.5*tesla" 
+	   zmax="2*m"
+	   outer_radius="3*m">
+    </field>
+  </fields>
+
+</lccdd>
diff --git a/examples/ClientTests/src/ParamVolume_geo.cpp b/examples/ClientTests/src/ParamVolume_geo.cpp
index 123936f38c895b5077c40e15f48bf9bd6d7467e4..79492220a506c0b4b8e9d0929178889b74a82803 100644
--- a/examples/ClientTests/src/ParamVolume_geo.cpp
+++ b/examples/ClientTests/src/ParamVolume_geo.cpp
@@ -44,36 +44,57 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s
   xml_comp_t x_param = x_det.child(_U(param));
   Box        box     (x_param.x(), x_param.y(), x_param.z());
   Volume     box_vol (x_det.nameStr()+"_param", box, description.material(x_param.materialStr()));
-  xml_dim_t  x_trafo = x_param.transformation();
-  xml_dim_t  x_dim_x = x_trafo.child(_U(dim_x));
-  Transform3D start, trafo1;
   PlacedVolume pv;
 
-  if ( x_param.hasChild(_U(start)) )   {
-    start = get_trafo(x_param.child(_U(start)));
+  if ( x_param.hasChild(_U(replicate)) )   {
+    xml_dim_t x_repl = x_param.child(_U(replicate));
+    std::string   ax = x_repl.attr<std::string>(_U(axis));
+    Volume::ReplicationAxis axis = Volume::Undefined;
+    ax[0] = ::toupper(ax[0]);
+    if ( ax[0] == 'X' ) axis = Volume::X_axis;
+    if ( ax[0] == 'Y' ) axis = Volume::Y_axis;
+    if ( ax[0] == 'Z' ) axis = Volume::Z_axis;
+    if ( ax[0] == 'R' ) axis = Volume::Rho_axis;
+    if ( ax[0] == 'P' ) axis = Volume::Phi_axis;
+    pv = envelope_vol.replicate(box_vol, axis,
+				x_repl.count(),
+				x_repl.distance(),
+				x_repl.start());
   }
+  else if ( x_param.hasChild(_U(transformation)) )   {
+    xml_dim_t  x_dim_x, x_dim_y, x_dim_z, x_trafo = x_param.transformation();
+    Transform3D start, trafo1, trafo2, trafo3;
 
-  trafo1 = get_trafo(x_trafo.child(_U(dim_x)));
+    if ( x_param.hasChild(_U(start)) )   {
+      start = get_trafo(x_param.child(_U(start)));
+    }
+    if ( x_trafo.hasChild(_U(dim_x)) )    {
+      x_dim_x = x_trafo.child(_U(dim_x));
+      trafo1 = get_trafo(x_dim_x);
+    }
+    if ( x_trafo.hasChild(_U(dim_y)) )    {
+      x_dim_y = x_trafo.child(_U(dim_y));
+      trafo2 = get_trafo(x_dim_y);
+    }
+    if ( x_trafo.hasChild(_U(dim_z)) )    {
+      x_dim_z = x_trafo.child(_U(dim_z));
+      trafo3 = get_trafo(x_dim_z);
+    }
 
-  if ( x_trafo.hasChild(_U(dim_y)) && x_trafo.hasChild(_U(dim_z)) )    {
-    xml_dim_t   x_dim_y = x_trafo.child(_U(dim_y));
-    xml_dim_t   x_dim_z = x_trafo.child(_U(dim_z));
-    Transform3D trafo2 = get_trafo(x_dim_y);
-    Transform3D trafo3 = get_trafo(x_dim_z);
-    pv = envelope_vol.paramVolume3D(start, box_vol, 
-				    x_dim_x.repeat(), trafo1,
-				    x_dim_y.repeat(), trafo2,
-				    x_dim_z.repeat(), trafo3);
-  }
-  else if ( x_trafo.hasChild(_U(dim_y)) )    {
-    xml_dim_t   x_dim_y = x_trafo.child(_U(dim_y));
-    Transform3D trafo2 = get_trafo(x_dim_y);
-    pv = envelope_vol.paramVolume2D(start, box_vol, 
-				    x_dim_x.repeat(), trafo1, 
-				    x_dim_y.repeat(), trafo2);
-  }
-  else   {
-    pv = envelope_vol.paramVolume1D(start, box_vol, x_dim_x.repeat(), trafo1);
+    if ( x_trafo.hasChild(_U(dim_y)) && x_trafo.hasChild(_U(dim_z)) )    {
+      pv = envelope_vol.paramVolume3D(start, box_vol, 
+				      x_dim_x.repeat(), trafo1,
+				      x_dim_y.repeat(), trafo2,
+				      x_dim_z.repeat(), trafo3);
+    }
+    else if ( x_trafo.hasChild(_U(dim_y)) )    {
+      pv = envelope_vol.paramVolume2D(start, box_vol, 
+				      x_dim_x.repeat(), trafo1, 
+				      x_dim_y.repeat(), trafo2);
+    }
+    else   {
+      pv = envelope_vol.paramVolume1D(start, box_vol, x_dim_x.repeat(), trafo1);
+    }
   }
   if ( sens.isValid() )   {
     sens.setType("calorimeter");