diff --git a/DDCore/include/DD4hep/VolumeManager.h b/DDCore/include/DD4hep/VolumeManager.h
index 9a477813bdc0b35bab86c3b9e28426876f9b1efe..532a42393cafd2ad081eb2f9c61c3cf16f8aea5b 100644
--- a/DDCore/include/DD4hep/VolumeManager.h
+++ b/DDCore/include/DD4hep/VolumeManager.h
@@ -76,6 +76,14 @@ namespace dd4hep {
     PlacedVolume elementPlacement()  const;
     /// Access the transformation to the closest detector element
     const TGeoHMatrix& toElement()  const;
+    /// Transform local coordinates to the DetElement coordinates
+    Position localToElement(const double local[3])  const;
+    /// Transform local coordinates to the DetElement coordinates
+    Position localToElement(const Position& local)  const;
+    /// Transform local coordinates to the world coordinates
+    Position localToWorld(const double local[3])  const;
+    /// Transform local coordinates to the world coordinates
+    Position localToWorld(const Position& local)  const;
   };
 
   /// Class to support the retrieval of detector elements and volumes given a valid identifier
diff --git a/DDCore/src/VolumeManager.cpp b/DDCore/src/VolumeManager.cpp
index 603eee3b9e2abc964aaba2891ab3b4a5ab2a08da..25744142cac4c44fada7f650d67ea1c53e48e919 100644
--- a/DDCore/src/VolumeManager.cpp
+++ b/DDCore/src/VolumeManager.cpp
@@ -327,6 +327,34 @@ const TGeoHMatrix& VolumeManagerContext::toElement()  const   {
   return ext->toElement;
 }
 
+/// Transform local coordinates to the DetElement coordinates
+Position VolumeManagerContext::localToElement(const double local[3])  const   {
+  double elt[3];
+  toElement().LocalToMaster(local, elt);
+  return { elt[0], elt[1], elt[2] };
+}
+
+/// Transform local coordinates to the DetElement coordinates
+Position VolumeManagerContext::localToElement(const Position& local)  const   {
+  double loc[3];
+  local.GetCoordinates(loc);
+  return localToElement(loc);
+}
+
+/// Transform local coordinates to the world coordinates
+Position VolumeManagerContext::localToWorld(const double local[3])  const   {
+  double elt[3];
+  toElement().LocalToMaster(local, elt);
+  return element.nominal().localToWorld(elt);
+}
+
+/// Transform local coordinates to the world coordinates
+Position VolumeManagerContext::localToWorld(const Position& local)  const   {
+  double l[3];
+  local.GetCoordinates(l);
+  return localToWorld(l);
+}
+
 /// Initializing constructor to create a new object
 VolumeManager::VolumeManager(const Detector& description, const string& nam, DetElement elt, Readout ro, int flags) {
   printout(INFO, "VolumeManager", " - populating volume ids - be patient ..."  );
diff --git a/DDCore/src/plugins/Compact2Objects.cpp b/DDCore/src/plugins/Compact2Objects.cpp
index 498b215fb4455e47e130ee7e270a8fd07974d122..9c5ba437fc1e5f86524a29d508ba4094988b2ed2 100644
--- a/DDCore/src/plugins/Compact2Objects.cpp
+++ b/DDCore/src/plugins/Compact2Objects.cpp
@@ -1098,6 +1098,14 @@ template <> void Converter<Readout>::operator()(xml_h e) const {
   description.addReadout(ro);
 }
 
+static long load_readout(Detector& description, xml_h element) {
+  Converter<Readout> converter(description);
+  converter(element);
+  return 1;
+}
+DECLARE_XML_DOC_READER(readout,load_readout)
+
+
 /** Specialized converter for compact LimitSet objects.
  *
  *      <limitset name="....">
diff --git a/DDDigi/ddg4/DigiDDG4Input.cpp b/DDDigi/ddg4/DigiDDG4Input.cpp
index 5366b7ba25f758ae96ca69697e1779d4487a8a64..f887b0a4183ed30d5c63513420bd4d8a6c25aac0 100644
--- a/DDDigi/ddg4/DigiDDG4Input.cpp
+++ b/DDDigi/ddg4/DigiDDG4Input.cpp
@@ -82,12 +82,12 @@ namespace  {
 static void* convert_sim_geant4calorimeter_hits()     {
   return ddg4_hit_convert_function<sim::Geant4Calorimeter::Hit>("DDG4 calorimeter hits");
 }
-DECLARE_CREATE(DD4hep_DDDigiConverter_vector_dd4hep_sim_Geant4Calorimeter_Hit_,convert_sim_geant4calorimeter_hits);
+DECLARE_CREATE(DD4hep_DDDigiConverter_vector_dd4hep_sim_Geant4Calorimeter_Hit_,convert_sim_geant4calorimeter_hits)
 
 static void* convert_sim_geant4tracker_hits()     {
   return ddg4_hit_convert_function<sim::Geant4Tracker::Hit>("DDG4 tracker hits");
 }
-DECLARE_CREATE(DD4hep_DDDigiConverter_vector_dd4hep_sim_Geant4Tracker_Hit_,convert_sim_geant4tracker_hits);
+DECLARE_CREATE(DD4hep_DDDigiConverter_vector_dd4hep_sim_Geant4Tracker_Hit_,convert_sim_geant4tracker_hits)
 
 static void* convert_sim_geant4particles()     {
   func_t* cnv = new func_t([] (DataSegment& segment, int mask, const char* name, void* ptr)  {
@@ -118,4 +118,4 @@ static void* convert_sim_geant4particles()     {
     });
   return cnv;
 }
-DECLARE_CREATE(DD4hep_DDDigiConverter_vector_dd4hep_sim_Geant4Particle_,convert_sim_geant4particles);
+DECLARE_CREATE(DD4hep_DDDigiConverter_vector_dd4hep_sim_Geant4Particle_,convert_sim_geant4particles)
diff --git a/DDDigi/include/DDDigi/DigiAction.h b/DDDigi/include/DDDigi/DigiAction.h
index dcb1ed3bf22317ed2d38483cc5e5b92195599fa6..e274ebb2ef80adaef271917e75fe6cdb2a88732b 100644
--- a/DDDigi/include/DDDigi/DigiAction.h
+++ b/DDDigi/include/DDDigi/DigiAction.h
@@ -105,7 +105,9 @@ namespace dd4hep {
       long               m_refCount    = 1;
       /// Default property: Output level
       int                m_outputLevel = 3;
-
+      ///
+      std::vector<void*> m_opt_properties;
+      
     protected:
       /// Define standard assignments and constructors
       DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiAction);
@@ -133,7 +135,11 @@ namespace dd4hep {
         m_name = new_name;
       }
       /// Access to the properties of the object
-      PropertyManager& properties() {
+      PropertyManager& properties()  {
+        return m_properties;
+      }
+      /// Access to the properties of the object (CONST)
+      const PropertyManager& properties()   const  {
         return m_properties;
       }
       /// Access the output level
@@ -147,10 +153,16 @@ namespace dd4hep {
       template <typename T> DigiAction& declareProperty(const std::string& nam, T& val);
       /// Declare property
       template <typename T> DigiAction& declareProperty(const char* nam, T& val);
+      /// Declare property
+      template <typename T> DigiAction& addProperty(const std::string& nam, T& val);
+      /// Declare property
+      template <typename T> DigiAction& addProperty(const char* nam, T& val);
       /// Check property for existence
       bool hasProperty(const std::string& name) const;
       /// Access single property
       Property& property(const std::string& name);
+      /// Access single property (CONST)
+      const Property& property(const std::string& name)  const;
 
       /// Support for messages with variable output level using output level
       void print(const char* fmt, ...) const;
@@ -183,6 +195,23 @@ namespace dd4hep {
       m_properties.add(nam, val);
       return *this;
     }
+    /// Declare property
+    template <typename T> DigiAction& DigiAction::addProperty(const std::string& nam, T& val) {
+      void* ptr = ::operator new(sizeof(T));
+      T* prop = new(ptr) T(val);
+      m_properties.add(nam, *prop);
+      m_opt_properties.emplace_back(ptr);
+      return *this;
+    }
+
+    /// Declare property
+    template <typename T> DigiAction& DigiAction::addProperty(const char* nam, T& val) {
+      void* ptr = ::operator new(sizeof(T));
+      T* prop = new(ptr) T(val);
+      m_properties.add(nam, *prop);
+      m_opt_properties.emplace_back(ptr);
+      return *this;
+    }
   }    // End namespace digi
 }      // End namespace dd4hep
 
diff --git a/DDDigi/include/DDDigi/DigiContainerProcessor.h b/DDDigi/include/DDDigi/DigiContainerProcessor.h
index 075848e245755e91def3e1e96a90c851de2f7d5b..6cfaf3ff1f16b5fe4e82736b3b262c4664f8eb67 100644
--- a/DDDigi/include/DDDigi/DigiContainerProcessor.h
+++ b/DDDigi/include/DDDigi/DigiContainerProcessor.h
@@ -10,8 +10,8 @@
 // Author     : M.Frank
 //
 //==========================================================================
-#ifndef DDDIGI_DIGIMULTICONTAINERPROCESSOR_H
-#define DDDIGI_DIGIMULTICONTAINERPROCESSOR_H
+#ifndef DDDIGI_DIGICONTAINERPROCESSOR_H
+#define DDDIGI_DIGICONTAINERPROCESSOR_H
 
 // Framework include files
 #include <DDDigi/DigiData.h>
@@ -42,7 +42,10 @@ namespace dd4hep {
      */
     class DigiContainerProcessor : public DigiAction   {
     public:
-      using segment_t = DataSegment;
+      using segment_t  = DataSegment;
+      using context_t  = DigiContext;
+      using action_t   = DigiAction;
+      using property_t = PropertyManager;
       struct input_t  {
 	/// Input data key
 	Key             key;
@@ -50,21 +53,18 @@ namespace dd4hep {
 	std::any&       data;
       };
       struct output_t  {
-	/// Lock for secure output merging
-	//std::mutex&     lock;
-	/// Handle to output 
-	//std::any&       data;
 	int             mask;
 	segment_t&      data;
       };
-
       struct work_t  {
 	/// Event processing context
-	DigiContext&    context;
+	context_t&  context;
 	/// Input data
-	input_t         input;
+	input_t     input;
 	/// Output data
-	output_t&       output;
+	output_t&   output;
+	/// Optional properties
+	const property_t& properties;
 
 	/// Basic check if input data are present
 	bool has_input()  const    {  return this->input.data.has_value();  }
@@ -78,22 +78,8 @@ namespace dd4hep {
 	template <typename DATA> DATA* get_input(bool exc=false);
 	/// Access input data by type
 	template <typename DATA> const DATA* get_input(bool exc=false)  const;
-#if 0
-	/// Basic check if input data are present
-	bool has_output()  const   {  return this->output.data.has_value();  }
-	/// String form of the output data type
-	std::string output_type_name()  const;
-	/// Access the output data type
-	const std::type_info& output_type()  const;
-	/// Access output data by type
-	template <typename DATA> DATA* get_output();
-
-	/// Merge output data (thread safe, locked)
-	void merge_output(DepositVector&& data);
-	/// Merge output data (thread safe, locked)
-	void emplace_output(CellID cell, EnergyDeposit&& deposit);
-#endif
       };
+
     protected:
       /// Define standard assignments and constructors
       DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiContainerProcessor);
@@ -129,12 +115,12 @@ namespace dd4hep {
 
     protected:
       /// Property to steer parallel processing
-      bool m_parallel { false };
+      bool               m_parallel { false };
 
-      /// Array of sub-workers
-      workers_t          m_workers;
       /// Lock for output merging
       mutable std::mutex m_output_lock;
+      /// Array of sub-workers
+      workers_t          m_workers;
 
     protected:
       /// Define standard assignments and constructors
@@ -142,6 +128,9 @@ namespace dd4hep {
       /// Default destructor
       virtual ~DigiContainerSequence();
 
+      /// Get hold of the registered processor for a given container
+      worker_t* need_registered_worker(Key item_key)  const;
+
     public:
       /// Standard constructor
       DigiContainerSequence(const DigiKernel& kernel, const std::string& name);
@@ -164,9 +153,11 @@ namespace dd4hep {
 
     protected:
       /// Argument structure for client calls
+      using action_t    = DigiAction;
       using self_t      = DigiContainerSequenceAction;
       using processor_t = DigiContainerProcessor;
       using output_t    = processor_t::output_t;
+      using property_t  = processor_t::property_t;
       struct work_item_t  {
 	Key key;
 	std::any* data;
@@ -175,7 +166,8 @@ namespace dd4hep {
 	DigiContext&             context;
 	std::vector<work_item_t> input_items;
 	output_t&                output;
-	const self_t*            parent;
+	const property_t&        properties;
+	const self_t&            parent;
       };
       using worker_t         = DigiParallelWorker<processor_t, work_t>;
       using workers_t        = DigiParallelWorkers<worker_t>;
@@ -197,11 +189,11 @@ namespace dd4hep {
       /// Property: Input data segment name
       std::string        m_output_segment { "outputs" };
       /// Property: event mask for output data
-      int                m_output_mask   { 0x0 };
+      int                m_output_mask    { 0x0 };
 
       /// Lock for output merging
       mutable std::mutex m_output_lock;
-
+      
     protected:
       /// Define standard assignments and constructors
       DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiContainerSequenceAction);
@@ -211,6 +203,9 @@ namespace dd4hep {
       /// Initialization callback
       virtual void initialize();
 
+      /// Get hold of the registered processor for a given container
+      worker_t* need_registered_worker(Key item_key)  const;
+
     public:
       /// Standard constructor
       DigiContainerSequenceAction(const DigiKernel& kernel, const std::string& name);
@@ -236,13 +231,15 @@ namespace dd4hep {
       using worker_keys_t = std::vector<std::vector<Key> >;
       using work_items_t  = std::vector<std::pair<Key, std::any*> >;
       using output_t      = processor_t::output_t;
+      using property_t    = processor_t::property_t;
 
       /// Argument structure required to support multiple client calls
       struct work_t  {
-	DigiContext&    context;
-	work_items_t&   items;
-	output_t&       output;
-	const self_t&   parent;
+	DigiContext&      context;
+	work_items_t&     items;
+	output_t&         output;
+	const property_t& properties;
+	const self_t&     parent;
       };
       using worker_t      = DigiParallelWorker<processor_t, work_t>;
       using workers_t     = DigiParallelWorkers<worker_t>;
@@ -262,11 +259,12 @@ namespace dd4hep {
       std::set<Key>      m_work_items;
       /// Set of keys required by each worker
       worker_keys_t      m_worker_keys;
-      /// Array of sub-workers
-      workers_t          m_workers;
       /// Lock for output merging
       mutable std::mutex m_output_lock;
 
+      /// Array of sub-workers
+      workers_t          m_workers;
+
     protected:
        /// Define standard assignments and constructors
       DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiMultiContainerProcessor);
@@ -289,4 +287,4 @@ namespace dd4hep {
     };
   }    // End namespace digi
 }      // End namespace dd4hep
-#endif // DDDIGI_DIGIMULTICONTAINERPROCESSOR_H
+#endif // DDDIGI_DIGICONTAINERPROCESSOR_H
diff --git a/DDDigi/include/DDDigi/DigiContext.h b/DDDigi/include/DDDigi/DigiContext.h
index 398d3a75d44ca282d1aade24752cb9a78e7f643f..cbd03bb3aa8eece54907a6cde4102d58be1e4c0c 100644
--- a/DDDigi/include/DDDigi/DigiContext.h
+++ b/DDDigi/include/DDDigi/DigiContext.h
@@ -95,7 +95,10 @@ namespace dd4hep {
     protected:
       /// Reference to the random engine for this event
       std::shared_ptr<DigiRandomGenerator> m_random;
-
+      /// Set the random generator
+      void set_random_generator(std::shared_ptr<DigiRandomGenerator>& rndm)   {
+	m_random = rndm;
+      }
 
     protected:
       /// Inhibit default constructor
diff --git a/DDDigi/include/DDDigi/DigiData.h b/DDDigi/include/DDDigi/DigiData.h
index bf0f6a062255e5e3a73a220464d706851e423b3e..881a489533ea242a530787f54681932428d2deaa 100644
--- a/DDDigi/include/DDDigi/DigiData.h
+++ b/DDDigi/include/DDDigi/DigiData.h
@@ -220,7 +220,7 @@ namespace dd4hep {
     inline SegmentEntry::SegmentEntry(const std::string& nam, Key::mask_type msk)
       : name(nam)
     {
-      key.set_mask(msk);
+      key.set(nam, msk);
     }
 
     /// Particle definition for digitization
@@ -343,8 +343,9 @@ namespace dd4hep {
       double         length      { 0 };
       /// Total energy deposit
       double         deposit     { 0 };
-
+      /// Optional flag for user masks
       long           flag        { 0 };
+      /// Source mask of this deposit
       Key::mask_type mask        { 0 };
 
       /// Sources contributing to this deposit
diff --git a/DDDigi/include/DDDigi/DigiParallelWorkerGroup.h b/DDDigi/include/DDDigi/DigiParallelWorkerGroup.h
index e9e51ad76d58142f0fb33e7700fe3bbdb69da266..f1ca58a3c4128965f1ee3f357ecb36a67ae477bf 100644
--- a/DDDigi/include/DDDigi/DigiParallelWorkerGroup.h
+++ b/DDDigi/include/DDDigi/DigiParallelWorkerGroup.h
@@ -55,6 +55,10 @@ namespace dd4hep {
       ~DigiParallelWorkerGroup();
       /// Access the worker array. As long as the object persists it shall not be altered
       operator ParallelWorker*const* ();
+      /// Access specific worker array from group: actors are locked while group exists
+      std::vector<typename DigiParallelWorkers<T>::worker_t*>   actors()    {
+	return workers.actors;
+      }
     };
     
     /// Initializin constructor: aquire worker's semaphore
diff --git a/DDDigi/include/DDDigi/DigiParallelWorkers.h b/DDDigi/include/DDDigi/DigiParallelWorkers.h
index 18dea5ad8173c8d6a934eed0cbb09368e47e5a5f..33f9c8fcb629dbd9f60ebf67b6ac736fa2050ecf 100644
--- a/DDDigi/include/DDDigi/DigiParallelWorkers.h
+++ b/DDDigi/include/DDDigi/DigiParallelWorkers.h
@@ -51,6 +51,7 @@ namespace dd4hep {
     private:
       mutable std::vector<worker_t*>   actors;
       mutable DigiSemaphore            semaphore;
+      std::unique_lock<std::mutex> can_modify()  const;
 
     public:
       /// Default constructor
@@ -66,16 +67,12 @@ namespace dd4hep {
       /// Default destructor
       virtual ~DigiParallelWorkers();
 
-      std::unique_lock<std::mutex> can_modify()  const;
       /// Return array protected worker group
       group_t get_group()  const;
 
-      /// NOT thread-safe stuff. Do not use during event processing unless you are sequential
-      const std::vector<worker_t*>& get() const { return actors; }
       std::size_t size()  const;
       bool empty()  const;
       bool insert(worker_t* entry)  const;
-      ParallelWorker*const* get_calls()   const;
     };
 
     template <typename T> inline
@@ -108,12 +105,6 @@ namespace dd4hep {
       bool DigiParallelWorkers<T>::empty() const   {
       return actors.empty();
     }
-
-    template <typename T> inline
-      ParallelWorker*const* DigiParallelWorkers<T>::get_calls()  const  {
-      return (ParallelWorker**)&this->actors.at(0);
-    }
-
     template <typename T> inline typename DigiParallelWorkers<T>::group_t
       DigiParallelWorkers<T>::get_group()  const  {
       return group_t(*this);
diff --git a/DDDigi/include/DDDigi/DigiRandomGenerator.h b/DDDigi/include/DDDigi/DigiRandomGenerator.h
index f7fc4c0cc88c002ea4a98aa760d481d6c8fa7ce8..92f05c2631f101b7cd933e679e59f7c596e198b6 100644
--- a/DDDigi/include/DDDigi/DigiRandomGenerator.h
+++ b/DDDigi/include/DDDigi/DigiRandomGenerator.h
@@ -67,8 +67,8 @@ namespace dd4hep {
       double landau  (double mean = 0.0, double sigma = 1.0)  const;
       double breitWigner(double mean = 0.0, double gamma = 1.0)  const;
       double poisson(double mean)  const;
-      void	 rannor(float& a, float& b)   const;
-      void	 rannor(double& a, double& b)   const;
+      void   rannor(float& a, float& b)   const;
+      void   rannor(double& a, double& b)   const;
       void   sphere(double& x, double& y, double& z, double r)   const;
       void   circle(double &x, double &y, double r)  const;
     };
diff --git a/DDDigi/plugins/DigiCellMultiplicyCounter.cpp b/DDDigi/plugins/DigiCellMultiplicyCounter.cpp
index 843c735aade5540143eb4ba6dd75cbdcb30b5d3b..e00d47980bfe1d79fbe9dba89120c2797ba97230 100644
--- a/DDDigi/plugins/DigiCellMultiplicyCounter.cpp
+++ b/DDDigi/plugins/DigiCellMultiplicyCounter.cpp
@@ -17,7 +17,6 @@
 
 /// Namespace for the AIDA detector description toolkit
 namespace dd4hep {
-
   /// Namespace for the Digitization part of the AIDA detector description toolkit
   namespace digi {
 
diff --git a/DDDigi/plugins/DigiDepositMapCreator.cpp b/DDDigi/plugins/DigiDepositMapCreator.cpp
index d420822d33477f4dc8d8c87338ed3d3c4dbf686e..233a1f70a58639504acb22edfefcaadd95880bd7 100644
--- a/DDDigi/plugins/DigiDepositMapCreator.cpp
+++ b/DDDigi/plugins/DigiDepositMapCreator.cpp
@@ -38,18 +38,14 @@ namespace dd4hep {
 
       template <typename T> void create_deposits(const T& cont, work_t& work)  const  {
 	Key key(cont.name, work.output.mask);
-	DepositMapping* mapping = work.output.data.pointer<DepositMapping>(key);
-	if ( !mapping )   {
-	  DepositMapping m(cont.name, work.output.mask);
-	  work.output.data.put(m.key, std::move(m));
-	  mapping = work.output.data.pointer<DepositMapping>(key);
-	}
-	std::size_t start = mapping->size();
+	DepositMapping m(cont.name, work.output.mask);
+	std::size_t start = m.size();
 	for( const auto& dep : cont )
-	  mapping->data.emplace(dep.first, EnergyDeposit());
-	std::size_t end   = mapping->size();
+	  m.data.emplace(dep.first, EnergyDeposit());
+	std::size_t end   = m.size();
+	work.output.data.put(m.key, std::move(m));
 	info("+++ %-32s added %6ld entries (now: %6ld) from mask: %04X to mask: %04X",
-	     cont.name.c_str(), end-start, end, cont.key.mask(), mapping->key.mask());
+	     cont.name.c_str(), end-start, end, cont.key.mask(), m.key.mask());
       }
       /// Main functional callback
       virtual void execute(DigiContext&, work_t& work)  const override final  {
diff --git a/DDDigi/plugins/DigiDepositWeightedPosition.cpp b/DDDigi/plugins/DigiDepositWeightedPosition.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..512d13bb7d5b604ef04d070efde33f73e61160de
--- /dev/null
+++ b/DDDigi/plugins/DigiDepositWeightedPosition.cpp
@@ -0,0 +1,64 @@
+//==========================================================================
+//  AIDA Detector description implementation 
+//--------------------------------------------------------------------------
+// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+// All rights reserved.
+//
+// For the licensing terms see $DD4hepINSTALL/LICENSE.
+// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+//
+// Author     : M.Frank
+//
+//==========================================================================
+
+// Framework include files
+#include <DDDigi/DigiContext.h>
+#include <DDDigi/DigiContainerProcessor.h>
+
+/// Namespace for the AIDA detector description toolkit
+namespace dd4hep {
+
+  /// Namespace for the Digitization part of the AIDA detector description toolkit
+  namespace digi {
+
+    /// Actor to select energy deposits according to the supplied segmentation
+    /** Actor to select energy deposits according to the supplied segmentation
+     *
+     *  The selected deposits are placed in the output container
+     *  supplied by the arguments.
+     *
+     *  \author  M.Frank
+     *  \version 1.0
+     *  \ingroup DD4HEP_DIGITIZATION
+     */
+    class DigiDepositWeightedPosition : public DigiContainerProcessor   {
+    public:
+      /// Standard constructor
+      using DigiContainerProcessor::DigiContainerProcessor;
+
+      template <typename T> void create_deposits(const T& cont, work_t& work)  const  {
+	Key key(cont.name, work.output.mask);
+	DepositMapping m(cont.name, work.output.mask);
+	std::size_t start = m.size();
+	for( const auto& dep : cont )
+	  m.data.emplace(dep.first, EnergyDeposit());
+	std::size_t end   = m.size();
+	work.output.data.put(m.key, std::move(m));
+	info("+++ %-32s added %6ld entries (now: %6ld) from mask: %04X to mask: %04X",
+	     cont.name.c_str(), end-start, end, cont.key.mask(), m.key.mask());
+      }
+      /// Main functional callback
+      virtual void execute(DigiContext&, work_t& work)  const override final  {
+	if ( const auto* m = work.get_input<DepositMapping>() )
+	  create_deposits(*m, work);
+	else if ( const auto* v = work.get_input<DepositVector>() )
+	  create_deposits(*v, work);
+	else
+	  except("Request to handle unknown data type: %s", work.input_type_name().c_str());
+      }
+    };
+  }    // End namespace digi
+}      // End namespace dd4hep
+
+#include <DDDigi/DigiFactories.h>
+DECLARE_DIGIACTION_NS(dd4hep::digi,DigiDepositWeightedPosition)
diff --git a/DDDigi/plugins/DigiIPCreate.cpp b/DDDigi/plugins/DigiIPCreate.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e92ba6eb8f08faf09b408db496ad7d5092eef95e
--- /dev/null
+++ b/DDDigi/plugins/DigiIPCreate.cpp
@@ -0,0 +1,58 @@
+//==========================================================================
+//  AIDA Detector description implementation 
+//--------------------------------------------------------------------------
+// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+// All rights reserved.
+//
+// For the licensing terms see $DD4hepINSTALL/LICENSE.
+// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+//
+// Author     : M.Frank
+//
+//==========================================================================
+
+// Framework include files
+#include <DDDigi/DigiData.h>
+#include <DDDigi/DigiEventAction.h>
+
+/// C/C++ include files
+#include <cmath>
+
+/// Namespace for the AIDA detector description toolkit
+namespace dd4hep {
+  /// Namespace for the Digitization part of the AIDA detector description toolkit
+  namespace digi {
+
+    class DigiIPCreate : public DigiEventAction  {
+      Position  m_offset_ip;
+      Position  m_sigma_ip;
+      mutable Position m_interaction_point;
+    public:
+      /// Standard constructor
+      DigiIPCreate(const DigiKernel& krnl, const std::string& nam)
+	: DigiEventAction(krnl, nam)
+      {
+	declareProperty("offset_ip", m_offset_ip);
+	declareProperty("sigma_ip",  m_sigma_ip);
+	declareProperty("interaction_point", m_interaction_point);
+      }
+      /// Main functional callback
+      virtual void execute(DigiContext& context)   const  override final  {
+	auto& rndm = context.randomGenerator();
+	double theta  = rndm.uniform(0.0, M_PI);       // theta  = [0,pi]
+	double phi    = rndm.uniform(0.0, 2.0*M_PI);   // phi    = [0,2*pi]	
+	double radius = rndm.uniform(0.0, 1.0);        // radius = [0,1]
+	radius = std::sqrt( -std::log(radius) );       // radius in a gaussian distribution
+
+	double st = std::sin(theta);
+	double xx = radius * st * std::cos(phi) * m_sigma_ip.X() + m_offset_ip.X();
+	double yy = radius * st * std::sin(phi) * m_sigma_ip.Y() + m_offset_ip.Y();
+	double zz = radius * std::cos(theta) * m_sigma_ip.Z() + m_offset_ip.Z();
+	m_interaction_point = Position(xx, yy, zz);
+      }
+    };
+  }    // End namespace digi
+}      // End namespace dd4hep
+
+#include <DDDigi/DigiFactories.h>
+DECLARE_DIGIACTION_NS(dd4hep::digi,DigiIPCreate)
diff --git a/DDDigi/plugins/DigiIPMover.cpp b/DDDigi/plugins/DigiIPMover.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2a3c25836adc28951a4ef877becff0b455cec77f
--- /dev/null
+++ b/DDDigi/plugins/DigiIPMover.cpp
@@ -0,0 +1,78 @@
+//==========================================================================
+//  AIDA Detector description implementation 
+//--------------------------------------------------------------------------
+// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+// All rights reserved.
+//
+// For the licensing terms see $DD4hepINSTALL/LICENSE.
+// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+//
+// Author     : M.Frank
+//
+//==========================================================================
+
+// Framework include files
+#include <DDDigi/DigiData.h>
+#include <DDDigi/DigiContainerProcessor.h>
+
+#include <iostream>
+
+/// Namespace for the AIDA detector description toolkit
+namespace dd4hep {
+  /// Namespace for the Digitization part of the AIDA detector description toolkit
+  namespace digi {
+
+    class DigiIPMover : public DigiContainerProcessor  {
+      DigiAction* m_ip_creator { nullptr };
+      std::string m_ip_property;
+
+    public:
+      /// Standard constructor
+      DigiIPMover(const DigiKernel& krnl, const std::string& nam)
+	: DigiContainerProcessor(krnl, nam)
+      {
+	declareProperty("ip_property", m_ip_property);
+	declareProperty("ip_creator", m_ip_creator);
+      }
+      /// Move IP location of deposits
+      template <typename T> std::size_t move_deposits(T& cont, const Position& delta)  const  {
+	info("+++ %-32s [%6ld] IP: x:%7.3f y:%7.3f z:%7.3f", 
+	     cont.name.c_str(), cont.size(), delta.X(), delta.Y(), delta.Z());
+	for( auto& dep : cont )
+	  dep.second.position += delta;
+	return cont.size();
+      }
+      /// Move IP location of MC particles
+      template <typename T> std::size_t move_particles(T& cont, const Position& delta)  const  {
+	info("+++ %-32s [%6ld] IP: x:%7.3f y:%7.3f z:%7.3f", 
+	     cont.name.c_str(), cont.size(), delta.X(), delta.Y(), delta.Z());
+	for( auto& p : cont )   {
+	  auto& part = p.second;
+	  part.end_position   += delta;
+	  part.start_position += delta;
+	}
+	return cont.size();
+      }
+      /// Main functional callback
+      virtual void execute(DigiContext&, work_t& work)  const  override  {
+	Position delta;
+	if ( m_ip_creator )   {
+	  m_ip_creator->property(m_ip_property).value(delta);
+	  if ( auto* m = work.get_input<DepositMapping>() )
+	    move_deposits(*m, delta);
+	  else if ( auto* v = work.get_input<DepositVector>() )
+	    move_deposits(*v, delta);
+	  else if ( auto* p = work.get_input<ParticleMapping>() )
+	    move_particles(*p, delta);
+	  else
+	    except("Request to handle unknown data type: %s", work.input_type_name().c_str());
+	  return;
+	}
+	except("+++ No IP creator action known. Did you set the properties: ip_creator and ip_property?");
+      }
+    };
+  }    // End namespace digi
+}      // End namespace dd4hep
+
+#include <DDDigi/DigiFactories.h>
+DECLARE_DIGIACTION_NS(dd4hep::digi,DigiIPMover)
diff --git a/DDDigi/plugins/DigiIPRandomizer.cpp b/DDDigi/plugins/DigiIPRandomizer.cpp
deleted file mode 100644
index 39ec5180874262474c9e1adfa71ad81dd40ddff5..0000000000000000000000000000000000000000
--- a/DDDigi/plugins/DigiIPRandomizer.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-//==========================================================================
-//  AIDA Detector description implementation 
-//--------------------------------------------------------------------------
-// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
-// All rights reserved.
-//
-// For the licensing terms see $DD4hepINSTALL/LICENSE.
-// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
-//
-// Author     : M.Frank
-//
-//==========================================================================
-
-// Framework include files
-#include <DD4hep/InstanceCount.h>
-#include <DDDigi/DigiData.h>
-#include <DDDigi/DigiContext.h>
-#include <DDDigi/DigiEventAction.h>
-#include <DDDigi/DigiParallelWorker.h>
-
-
-/// Namespace for the AIDA detector description toolkit
-namespace dd4hep {
-
-  /// Namespace for the Digitization part of the AIDA detector description toolkit
-  namespace digi {
-
-    /// Default base class for all Digitizer actions and derivates thereof.
-    /**
-     *  This is a utility class supporting properties, output and access to
-     *  event and run objects through the context.
-     *
-     *  \author  M.Frank
-     *  \version 1.0
-     *  \ingroup DD4HEP_DIGITIZATION
-     */
-    class DigiIPRandomizer : public DigiEventAction   {
-    protected:
-      /// Property: Masks to act on
-      int              m_mask   { 0 };
-      /// Property: Input data segment name
-      std::string      m_input  { };
-
-      struct worker_args  {
-	std::size_t num_hit  { 0 };
-	std::size_t num_particle  { 0 };
-	std::any*   container { nullptr };
-	worker_args(std::any* p) : container(p) {}
-      };
-      struct work_t {
-	DigiContext& context;
-	Position     ip_move;
-	std::vector<worker_args> args;
-      };
-      class work_definition_t;
-      using self_t  = DigiIPRandomizer;
-      using Worker  = DigiParallelWorker<self_t,work_t>;
-      using Workers = DigiParallelWorkers<Worker>;
-
-      /// Worker objects to be submitted to the kernel
-      Workers m_workers;
-
-    protected:
-      /// Define standard assignments and constructors
-      DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiIPRandomizer);
-
-      /// Default destructor
-      virtual ~DigiIPRandomizer()  {
-	InstanceCount::decrement(this);
-      }
-
-      Position ip_displacement()  const  {
-	return Position(0,0,0);
-      }
-
-    public:
-      /// Standard constructor
-      DigiIPRandomizer(const DigiKernel& krnl, const std::string& nam)
-	: DigiEventAction(krnl, nam)
-      {
-	declareProperty("mask", m_mask);
-	declareProperty("input_segment", m_input = "inputs");
-	InstanceCount::increment(this);
-      }
-      /// Main functional callback
-      virtual void execute(DigiContext& context)  const  final  {
-	auto& inputs = context.event->get_segment(m_input);
-	std::vector<worker_args> collection_args;
-	collection_args.reserve(inputs.size());
-	for ( auto& i : inputs )     {
-	  Key key(i.first);
-	  if ( key.mask() == m_mask )   {
-	    collection_args.emplace_back(worker_args(&i.second));
-	  }
-	}
-	work_t data  { context, ip_displacement(), collection_args };
-	for( auto& c : collection_args )   {
-	  if ( DepositMapping* m = std::any_cast<DepositMapping>(c.container) )    {
-	    for( auto& dep : *m )
-	      dep.second.position += data.ip_move;
-	    c.num_hit += m->size();
-	  }
-	  else if ( DepositVector* v = std::any_cast<DepositVector>(c.container) )    {
-	    for( auto& dep : *v )
-	      dep.second.position += data.ip_move;
-	    c.num_hit += v->size();
-	  }
-	  else if ( ParticleMapping* parts = std::any_cast<ParticleMapping>(c.container) )    {
-	    for( auto& p : *parts )   {
-	      auto& part = p.second;
-	      part.end_position   += data.ip_move;
-	      part.start_position += data.ip_move;
-	    }
-	    c.num_particle += parts->size();
-	  }
-	}
-	std::size_t num_hit = 0;
-	std::size_t num_particle = 0;
-	for( const auto& c : collection_args )   {
-	  num_hit += c.num_hit;
-	  num_particle += c.num_particle;
-	}
-	info("%s+++ Moved coordinates of %6ld hits ans %6ld particles", 
-	     context.event->id(), num_hit, num_particle);
-      }
-    };
-  }    // End namespace digi
-}      // End namespace dd4hep
-
-#include <DDDigi/DigiFactories.h>
-DECLARE_DIGIACTION_NS(dd4hep::digi,DigiIPRandomizer)
diff --git a/DDDigi/plugins/DigiResegment.cpp b/DDDigi/plugins/DigiResegment.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e70ac5eb741161f77d8f96f062ed19ae37b1f22c
--- /dev/null
+++ b/DDDigi/plugins/DigiResegment.cpp
@@ -0,0 +1,157 @@
+//==========================================================================
+//  AIDA Detector description implementation 
+//--------------------------------------------------------------------------
+// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+// All rights reserved.
+//
+// For the licensing terms see $DD4hepINSTALL/LICENSE.
+// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+//
+// Author     : M.Frank
+//
+//==========================================================================
+
+// Framework include files
+#include <DDDigi/DigiKernel.h>
+#include <DDDigi/DigiContext.h>
+#include <DDDigi/DigiContainerProcessor.h>
+
+#include <DD4hep/Detector.h>
+#include <DD4hep/Readout.h>
+#include <DD4hep/DetElement.h>
+#include <DD4hep/IDDescriptor.h>
+#include <DD4hep/Segmentations.h>
+#include <DD4hep/DetectorLoad.h>
+
+/// Namespace for the AIDA detector description toolkit
+namespace dd4hep {
+
+  /// Namespace for the Digitization part of the AIDA detector description toolkit
+  namespace digi {
+
+    /// Actor to select energy deposits according to the supplied segmentation
+    /** Actor to select energy deposits according to the supplied segmentation
+     *
+     *  The selected deposits are placed in the output container
+     *  supplied by the arguments.
+     *
+     *  \author  M.Frank
+     *  \version 1.0
+     *  \ingroup DD4HEP_DIGITIZATION
+     */
+    class DigiResegment : public DigiContainerProcessor   {
+    protected:
+      std::string  m_detector_name { };
+      std::string  m_readout_name  { };
+      std::string  m_readout_descriptor { };
+      bool         m_debug              { false };
+
+      Readout      m_new_readout  { };
+      Segmentation m_new_segment  { };
+      IDDescriptor m_new_id_desc  { };
+      Readout      m_org_readout  { };
+      Segmentation m_org_segment  { };
+      IDDescriptor m_org_id_desc  { };
+      DetElement   m_detector { };
+      VolumeManager m_volmgr  { };
+    public:
+      /// Standard constructor
+      DigiResegment(const DigiKernel& krnl, const std::string& nam)
+	: DigiContainerProcessor(krnl, nam)
+      {
+	declareProperty("debug",      m_debug);
+	declareProperty("detector",   m_detector_name);
+	declareProperty("readout",    m_readout_name);
+	declareProperty("descriptor", m_readout_descriptor);
+	m_kernel.register_initialize(Callback(this).make(&DigiResegment::initialize));
+      }
+
+      void initialize()   {
+	auto& detector = m_kernel.detectorDescription();
+	if ( m_readout_descriptor.empty() )   {
+	  except("+++ Invalid ID descriptor %s", m_readout_descriptor.c_str());
+	}
+	DetectorLoad loader(detector);
+	loader.processXMLString(m_readout_descriptor.c_str());
+	m_new_readout = detector.readout(m_readout_name);
+	if ( !m_new_readout.isValid() )  {
+	  except("+++ Invalid resegmentation readout for %s", m_readout_name.c_str());
+	}
+	m_new_id_desc = m_new_readout.idSpec();
+	m_new_segment = m_new_readout.segmentation();
+
+
+	m_detector = detector.detector(m_detector_name);
+	if ( !m_detector.isValid() )   {
+	  except("+++ Cannot locate subdetector: %s", m_detector_name.c_str());
+	}
+	m_org_readout = detector.sensitiveDetector(m_detector_name).readout();
+	if ( !m_org_readout.isValid() )  {
+	  except("+++ Invalid resegmentation readout for %s", m_readout_name.c_str());
+	}
+	m_org_id_desc = m_org_readout.idSpec();
+	m_org_segment = m_org_readout.segmentation();
+
+	m_volmgr = detector.volumeManager();
+	if ( !m_volmgr.isValid() )   {
+	  detector.apply("DD4hepVolumeManager",0,nullptr);
+	}
+	m_volmgr = detector.volumeManager();
+	if ( !m_volmgr.isValid() )   {
+	  except("+++ Cannot locate volume manager!");
+	}
+	info("+++ Successfully initialized resegmentation action.");
+      }
+
+      template <typename T> void resegment_deposits(const T& cont, work_t& work)  const  {
+	Key key(cont.name, work.output.mask);
+	DepositVector m(cont.name, work.output.mask);
+	std::size_t start = m.size();
+	for( const auto& dep : cont )   {
+	  CellID cell = dep.first;
+	  auto*  ctxt = m_volmgr.lookupContext(cell);
+	  if ( !ctxt )   {
+	    error("+++ Cannot locate volume context for cell %016lX", cell);
+	  }
+	  else   {
+	    VolumeID volID     = m_org_segment.volumeID(cell);
+	    Position org_local = m_org_segment.position(cell);
+	    Position global    = ctxt->localToWorld(org_local);
+	    CellID   new_cell  = m_new_segment.cellID(org_local, global, volID);
+	    Position new_local = m_new_segment.position(new_cell);
+	    if ( m_debug )   {
+	      info("+++ Cell: %016lX -> %016lX DE: %-20s "
+		   "Pos global: %8.2f %8.2f %8.2f  local: %8.2f %8.2f %8.2f -> %8.2f %8.2f %8.2f",
+		   cell, new_cell, ctxt->element.name(), 
+		   global.X(), global.Y(), global.Z(),
+		   org_local.X(), org_local.Y(), org_local.Z(),
+		   new_local.X(), new_local.Y(), new_local.Z()
+		   );
+	    }
+	    EnergyDeposit d(dep.second);
+	    d.position = global;
+	    d.momentum = dep.second.momentum;
+	    m.emplace(new_cell, std::move(d));
+	  }
+	}
+	std::size_t end   = m.size();
+	work.output.data.put(m.key, std::move(m));
+	info("+++ %-32s added %6ld entries (now: %6ld) from mask: %04X to mask: %04X",
+	     cont.name.c_str(), end-start, end, cont.key.mask(), m.key.mask());
+      }
+
+      /// Main functional callback
+      virtual void execute(DigiContext&, work_t& work)  const override final  {
+	if ( const auto* m = work.get_input<DepositMapping>() )
+	  resegment_deposits(*m, work);
+	else if ( const auto* v = work.get_input<DepositVector>() )
+	  resegment_deposits(*v, work);
+	else
+	  except("Request to handle unknown data type: %s", work.input_type_name().c_str());
+      }
+    };
+  }    // End namespace digi
+}      // End namespace dd4hep
+
+#include <DDDigi/DigiFactories.h>
+DECLARE_DIGIACTION_NS(dd4hep::digi,DigiResegment)
diff --git a/DDDigi/plugins/DigiSegmentDepositExtractor.cpp b/DDDigi/plugins/DigiSegmentDepositExtractor.cpp
index ac3788d30bb034868695a24b1c694c46f0ee5f08..3bb3b4e69d37374c5c9b855941e1ce05de2cec21 100644
--- a/DDDigi/plugins/DigiSegmentDepositExtractor.cpp
+++ b/DDDigi/plugins/DigiSegmentDepositExtractor.cpp
@@ -17,7 +17,6 @@
 
 /// Namespace for the AIDA detector description toolkit
 namespace dd4hep {
-
   /// Namespace for the Digitization part of the AIDA detector description toolkit
   namespace digi {
 
diff --git a/DDDigi/plugins/DigiSegmentDepositPrint.cpp b/DDDigi/plugins/DigiSegmentDepositPrint.cpp
index e4046cfe8feb851fc4eed362bea7fdfb71952de2..471201ecfacba642be1ad0ab8c269240272ae7fd 100644
--- a/DDDigi/plugins/DigiSegmentDepositPrint.cpp
+++ b/DDDigi/plugins/DigiSegmentDepositPrint.cpp
@@ -17,7 +17,6 @@
 
 /// Namespace for the AIDA detector description toolkit
 namespace dd4hep {
-
   /// Namespace for the Digitization part of the AIDA detector description toolkit
   namespace digi {
 
diff --git a/DDDigi/python/DDDigiDict.C b/DDDigi/python/DDDigiDict.C
index 9ba59a6a1e40a066019a3b9e66d048ab1157c2a4..9d39b3223ee120afbb98be209aea0feaf1aed0ad 100644
--- a/DDDigi/python/DDDigiDict.C
+++ b/DDDigi/python/DDDigiDict.C
@@ -47,6 +47,9 @@ namespace dd4hep {
   /// Namespace for the Digitization part of the AIDA detector description toolkit
   namespace digi {
 
+    template <typename VAL>
+    int add_action_property(DigiAction* action, const std::string& name, VAL value);
+
 #define ACTIONHANDLE(x)                                                                   \
     struct x##Handle  {                                                                   \
       Digi##x* action;                                                                    \
@@ -106,6 +109,35 @@ namespace dd4hep {
         }
         return 0;
       }
+
+#define MKVAL auto val = value
+
+#define ADD_PROPERTY(n,X)						\
+      static int add##n       (DigiAction* action, const std::string& name, const X value) \
+      {	return add_action_property(action, name, value); }		\
+      static int addVector##n (DigiAction* action, const std::string& name, std::vector<X> value) \
+      {	MKVAL; return add_action_property(action, name, val); }	\
+      static int addList##n   (DigiAction* action, const std::string& name, std::list<X> value) \
+      {	MKVAL; return add_action_property(action, name, val); }		\
+      static int addSet##n    (DigiAction* action, const std::string& name, std::set<X> value) \
+      {	MKVAL; return add_action_property(action, name, val); }		\
+      static int addMapped##n (DigiAction* action, const std::string& name, std::map<std::string,X> value) \
+      {	MKVAL; return add_action_property(action, name, val); }
+      ADD_PROPERTY(Property,int)
+      ADD_PROPERTY(Property,short)
+      ADD_PROPERTY(Property,size_t)
+      ADD_PROPERTY(Property,double)
+
+      ADD_PROPERTY(Property,std::string)
+
+      static int addPositionProperty(DigiAction* action, const std::string& name, const std::string value)     {
+	Position pos;
+	Property pr(pos);
+	pr.str(value);
+	return add_action_property(action, name, pos);
+      }
+      //ADD_PROPERTY(PositionProperty,dd4hep::Position)
+
       static PropertyResult getPropertyKernel(DigiKernel* kernel, const std::string& name)  {
         if ( kernel->hasProperty(name) )  {
           return PropertyResult(kernel->property(name).str(),1);
diff --git a/DDDigi/python/dddigi.py b/DDDigi/python/dddigi.py
index 323d6d9d0dd6a9b96682d14363cf0d5b2a5bd22b..c38dffca50a770b105b9cbb01eb7af9fcb11d720 100644
--- a/DDDigi/python/dddigi.py
+++ b/DDDigi/python/dddigi.py
@@ -158,6 +158,36 @@ def _setKernelProperty(self, name, value):
   raise KeyError(msg)
 
 
+# ---------------------------------------------------------------------------
+def _add_property(self, name, value):
+  Interface.addProperty(self.get(), str(name), value)
+
+
+# ---------------------------------------------------------------------------
+def _add_position_property(self, name, value):
+  Interface.addPositionProperty(self.get(), str(name), str(value))
+
+
+# ---------------------------------------------------------------------------
+def _add_set_property(self, name, value):
+  Interface.addSetProperty(self.get(), str(name), value)
+
+
+# ---------------------------------------------------------------------------
+def _add_list_property(self, name, value):
+  Interface.addListProperty(self.get(), str(name), value)
+
+
+# ---------------------------------------------------------------------------
+def _add_vector_property(self, name, value):
+  Interface.addVectorProperty(self.get(), str(name), value)
+
+
+# ---------------------------------------------------------------------------
+def _add_mapped_property(self, name, value):
+  Interface.addMappedProperty(self.get(), str(name), value)
+
+
 # ---------------------------------------------------------------------------
 def _kernel_terminate(self):
   return self.get().terminate()
@@ -169,7 +199,12 @@ Kernel.__setattr__ = _setKernelProperty
 Kernel.terminate = _kernel_terminate
 # ---------------------------------------------------------------------------
 ActionHandle = digi.ActionHandle
-
+ActionHandle.add_property = _add_property
+ActionHandle.add_position_property = _add_position_property
+ActionHandle.add_set_property = _add_set_property
+ActionHandle.add_list_property = _add_list_property
+ActionHandle.add_vector_property = _add_vector_property
+ActionHandle.add_mapped_property = _add_mapped_property
 
 # ---------------------------------------------------------------------------
 def TestAction(kernel, nam, sleep=0):
@@ -205,8 +240,8 @@ def _adopt_processor_action(self, action, container):
     proc = Interface.toContainerProcessor(action.get())
     attr(proc, container)
   else:
-    proc = action ##Interface.toContainerProcessor(action)
-    print(str(proc.__class__))
+    proc = action
+    # print(str(proc.__class__))
   attr(proc, container)
   # print('ContainerProcessor succesfully adopted')
 # ---------------------------------------------------------------------------
diff --git a/DDDigi/src/DigiAction.cpp b/DDDigi/src/DigiAction.cpp
index 4443ba1379fd4f514eb54e513903c2001c97cabe..faff69356e16bd1e5a7e5e8461961bdf40cef33e 100644
--- a/DDDigi/src/DigiAction.cpp
+++ b/DDDigi/src/DigiAction.cpp
@@ -47,6 +47,9 @@ DigiAction::DigiAction(const DigiKernel& krnl, const std::string& nam)
 
 /// Default destructor
 DigiAction::~DigiAction() {
+  for(auto* ptr : m_opt_properties)
+    ::operator delete(ptr);
+  m_opt_properties.clear();
   InstanceCount::decrement(this);
 }
 
@@ -83,6 +86,11 @@ dd4hep::Property& DigiAction::property(const std::string& nam)   {
   return properties()[nam];
 }
 
+/// Access single property
+const dd4hep::Property& DigiAction::property(const std::string& nam)   const  {
+  return properties()[nam];
+}
+
 /// Support for messages with variable output level using output level
 void DigiAction::print(const char* fmt, ...) const   {
   int level = std::max(int(outputLevel()),(int)VERBOSE);
@@ -105,34 +113,42 @@ std::string DigiAction::format(const char* fmt, ...) const {
 
 /// Support of debug messages.
 void DigiAction::debug(const char* fmt, ...) const {
-  va_list args;
-  va_start(args, fmt);
-  dd4hep::printout(dd4hep::DEBUG, m_name, fmt, args);
-  va_end(args);
+  if ( std::max(int(outputLevel()),(int)VERBOSE) >= DEBUG )  {
+    va_list args;
+    va_start(args, fmt);
+    dd4hep::printout(dd4hep::DEBUG, m_name, fmt, args);
+    va_end(args);
+  }
 }
 
 /// Support of info messages.
 void DigiAction::info(const char* fmt, ...) const {
-  va_list args;
-  va_start(args, fmt);
-  dd4hep::printout(dd4hep::INFO, m_name, fmt, args);
-  va_end(args);
+  if ( std::max(int(outputLevel()),(int)VERBOSE) >= INFO )  {
+    va_list args;
+    va_start(args, fmt);
+    dd4hep::printout(dd4hep::INFO, m_name, fmt, args);
+    va_end(args);
+  }
 }
 
 /// Support of warning messages.
 void DigiAction::warning(const char* fmt, ...) const {
-  va_list args;
-  va_start(args, fmt);
-  dd4hep::printout(dd4hep::WARNING, m_name, fmt, args);
-  va_end(args);
+  if ( std::max(int(outputLevel()),(int)VERBOSE) >= WARNING )  {
+    va_list args;
+    va_start(args, fmt);
+    dd4hep::printout(dd4hep::WARNING, m_name, fmt, args);
+    va_end(args);
+  }
 }
 
 /// Action to support error messages.
 void DigiAction::error(const char* fmt, ...) const {
-  va_list args;
-  va_start(args, fmt);
-  dd4hep::printout(dd4hep::ERROR, m_name, fmt, args);
-  va_end(args);
+  if ( std::max(int(outputLevel()),(int)VERBOSE) >= ERROR )  {
+    va_list args;
+    va_start(args, fmt);
+    dd4hep::printout(dd4hep::ERROR, m_name, fmt, args);
+    va_end(args);
+  }
 }
 
 /// Action to support error messages.
@@ -161,3 +177,70 @@ void DigiAction::except(const char* fmt, ...) const {
   va_end(args);
   throw std::runtime_error(err);
 }
+
+/// Namespace for the AIDA detector description toolkit
+namespace dd4hep {
+
+  /// Namespace for the Digitization part of the AIDA detector description toolkit
+  namespace digi {
+    template <typename VAL>
+    int add_action_property(DigiAction* action, const std::string& name, VAL value)   {
+      action->addProperty(name, value);
+      printout(INFO, "addProperty", "+++ Added property %s of type %s",
+	       name.c_str(), typeName(typeid(VAL)).c_str());
+      return 1;
+    }
+
+#define ADD_SINGLE_PROPERTY(X)						\
+    template int add_action_property<X>(DigiAction* action, const std::string& name, X value);
+
+#define ADD_MAPPED_PROPERTY(K,X)					\
+    template int add_action_property<std::map<std::string,X> >(DigiAction* action, const std::string& name, std::map<K,X> value);
+
+#define ADD_PROPERTY(X) \
+    ADD_SINGLE_PROPERTY(X)						\
+    ADD_SINGLE_PROPERTY(std::set<X>)					\
+    ADD_SINGLE_PROPERTY(std::list<X>)					\
+    ADD_SINGLE_PROPERTY(std::vector<X>)					\
+    ADD_MAPPED_PROPERTY(std::string,X)
+
+    ADD_PROPERTY(int)
+    ADD_PROPERTY(float)
+    ADD_PROPERTY(double)
+    ADD_PROPERTY(std::string)
+    ADD_PROPERTY(dd4hep::Position)
+
+    ADD_SINGLE_PROPERTY(size_t)
+  }
+}
+
+#include "DD4hep/GrammarUnparsed.h"
+namespace dd4hep   {
+
+  static bool _from_string(const BasicGrammar&, void* ptr, const std::string& value)    {
+    static constexpr const char MATCH[] = " object at 0x";
+    size_t idx = value.find(MATCH);
+    if ( idx != std::string::npos )    {
+      void* p = 0;
+      const char* cptr = value.c_str()+idx+strlen(MATCH)-2;
+      if ( 1 == ::sscanf(cptr,"%p", &p) )   {
+	*(void**)ptr = p;
+	return true;
+      }
+    }
+    dd4hep::except("FAIL","FAIL");
+    return false;
+  }
+
+  template <> const GrammarRegistry& GrammarRegistry::pre_note<DigiAction*>(int)   {
+    BasicGrammar::specialization_t spec;
+    spec.bind = nullptr;
+    spec.copy = nullptr;
+    spec.eval = nullptr;
+    spec.str  = nullptr;
+    spec.fromString = _from_string;
+    return pre_note_specs<DigiAction*>(spec);
+  }
+}
+
+static auto s_registry = dd4hep::GrammarRegistry::pre_note<DigiAction*>(1);
diff --git a/DDDigi/src/DigiContainerCombine.cpp b/DDDigi/src/DigiContainerCombine.cpp
index 8d9ec05859a6044c0564dd24e9af6a459306f52a..eaa84a2ad65f50628f8add3351a79e5aa2db00a3 100644
--- a/DDDigi/src/DigiContainerCombine.cpp
+++ b/DDDigi/src/DigiContainerCombine.cpp
@@ -66,7 +66,7 @@ public:
       cnt = output.merge(std::move(input));
     else
       cnt = output.insert(input);
-    combine->info(this->format, thr, input.name.c_str(), input.key.values.mask, cnt, "deposits"); 
+    combine->debug(this->format, thr, input.name.c_str(), input.key.values.mask, cnt, "deposits"); 
     this->cnt_depos += cnt;
     this->cnt_conts++;
   }
@@ -96,7 +96,7 @@ public:
       if ( keys[j].item() == key.item() )   {
 	ParticleMapping* next = std::any_cast<ParticleMapping>(work[j]);
 	std::size_t cnt = out.merge(std::move(*next));
-	combine->info(format, thr, next->name.c_str(), keys[j].mask(), cnt, "particles"); 
+	combine->debug(format, thr, next->name.c_str(), keys[j].mask(), cnt, "particles"); 
 	cnt_parts += cnt;
 	cnt_conts++;
 	work[j]->reset();
@@ -190,7 +190,7 @@ void DigiContainerCombine::initialize()    {
 /// Initializing function: compute values which depend on properties
 void DigiContainerCombine::have_workers(size_t count)  const   {
   if ( m_workers.size() < count )   {
-    auto lock = m_workers.can_modify();
+    auto group = m_workers.get_group(); // Lock worker group
     for(size_t i=m_workers.size(); i <= count; ++i)
       m_workers.insert(new Worker(nullptr, i));
   }
diff --git a/DDDigi/src/DigiContainerProcessor.cpp b/DDDigi/src/DigiContainerProcessor.cpp
index fe22e51ed4c5bf18cbe6166d43444616aebd96d9..02b1af906501c3c8035073448af2e5cd27e9a96e 100644
--- a/DDDigi/src/DigiContainerProcessor.cpp
+++ b/DDDigi/src/DigiContainerProcessor.cpp
@@ -58,23 +58,6 @@ namespace dd4hep {
       }
       return nullptr;
     }
-#if 0
-    template <typename T> T* DigiContainerProcessor::work_t::get_output()   {
-      if ( !output.data.has_value() )  {
-	T data;
-	output.data = std::move(data);
-      }
-      T* v = std::any_cast<T>(&output.data);
-      if ( v )   {
-	return v;
-      }
-      dd4hep::except("DigiContainerProcessor",
-		     "+++ Cannot access output. Invalid data handle of type: %s",
-		     output_type_name().c_str());
-      return nullptr;
-    }
-#endif
-
   }    // End namespace digi
 }      // End namespace dd4hep
 
@@ -95,33 +78,6 @@ std::string DigiContainerProcessor::work_t::input_type_name()  const   {
   return typeName(input.data.type());
 }
 
-#if 0
-template       DepositVector*   DigiContainerProcessor::work_t::get_output();
-template       DepositMapping*  DigiContainerProcessor::work_t::get_output();
-template       ParticleMapping* DigiContainerProcessor::work_t::get_output();
-
-/// output data type
-const std::type_info& DigiContainerProcessor::work_t::output_type()  const   {
-  return output.data.type();
-}
-
-/// String form of the output data type
-std::string DigiContainerProcessor::work_t::output_type_name()  const   {
-  return typeName(input.data.type());
-}
-
-/// Merge output data
-void DigiContainerProcessor::work_t::merge_output(DepositVector&& data)   {
-  std::lock_guard<std::mutex> lock(output.lock);
-  this->get_output<DepositVector>()->merge(std::move(data));
-}
-
-void DigiContainerProcessor::work_t::emplace_output(CellID cell, EnergyDeposit&& data)   {
-  std::lock_guard<std::mutex> lock(output.lock);
-  this->get_output<DepositVector>()->emplace(cell, std::move(data));
-}
-#endif
-
 /// Standard constructor
 DigiContainerProcessor::DigiContainerProcessor(const DigiKernel& kernel, const std::string& name)   
   : DigiAction(kernel, name)
@@ -169,7 +125,7 @@ void DigiContainerSequence::adopt_processor(DigiContainerProcessor* action)   {
 
 /// Main functional callback if specific work is known
 void DigiContainerSequence::execute(DigiContext& /* context */, work_t& work)  const   {
-  m_kernel.submit(m_workers.get_calls(), m_workers.size(), &work, m_parallel);
+  m_kernel.submit(m_workers.get_group(), m_workers.size(), &work, m_parallel);
 }
 
 /// Worker adaptor for caller DigiContainerSequence
@@ -184,10 +140,10 @@ template <> void DigiParallelWorker<DigiContainerProcessor,
 DigiContainerSequenceAction::DigiContainerSequenceAction(const DigiKernel& krnl, const std::string& nam)
   : DigiEventAction(krnl, nam)
 {
-  declareProperty("input_mask",    m_input_mask);
-  declareProperty("input_segment", m_input_segment);
-  declareProperty("output_mask",      m_output_mask);
-  declareProperty("output_segment",   m_output_segment);
+  declareProperty("input_mask",     m_input_mask);
+  declareProperty("input_segment",  m_input_segment);
+  declareProperty("output_mask",    m_output_mask);
+  declareProperty("output_segment", m_output_segment);
   m_kernel.register_initialize(Callback(this).make(&DigiContainerSequenceAction::initialize));
   InstanceCount::increment(this);
 }
@@ -242,6 +198,19 @@ void DigiContainerSequenceAction::adopt_processor(DigiContainerProcessor* action
   }
 }
 
+/// Get hold of the registered processor for a given container
+DigiContainerSequenceAction::worker_t*
+DigiContainerSequenceAction::need_registered_worker(Key item_key)   const  {
+  Key key;
+  key.set_item(item_key.item());
+  auto it = m_registered_workers.find(key.item());
+  if ( it != m_registered_workers.end() )  {
+    return it->second;
+  }
+  except("No worker registered for input: %016lX", key.key);
+  return nullptr;
+}
+
 /// Main functional callback if specific work is known
 void DigiContainerSequenceAction::execute(DigiContext& context)  const   {
   auto& event   = *context.event;
@@ -249,14 +218,14 @@ void DigiContainerSequenceAction::execute(DigiContext& context)  const   {
   auto& outputs = event.get_segment(m_output_segment);
   std::vector<ParallelWorker*> event_workers;
   output_t output { m_output_mask, outputs };
-  work_t   args   { context, {}, output, this };
+  work_t   args   { context, {}, output, m_properties, *this };
 
   args.input_items.resize(m_workers.size(), {0, nullptr});
   event_workers.reserve(inputs.size());
   for( auto& i : inputs )   {
     Key key(i.first);
     if ( key.mask() == m_input_mask )   {
-      auto it = m_registered_workers.find(key);
+      auto it = m_registered_workers.find(key.item());
       if ( it != m_registered_workers.end() )  {
 	worker_t* w = it->second;
 	event_workers.emplace_back(w);
@@ -275,7 +244,7 @@ template <> void DigiParallelWorker<DigiContainerProcessor,
 				    std::size_t>::execute(void* data) const  {
   calldata_t* args  = reinterpret_cast<calldata_t*>(data);
   auto& item = args->input_items[this->options];
-  DigiContainerProcessor::work_t  work { args->context, { item.key, *item.data }, args->output };
+  DigiContainerProcessor::work_t work {args->context, {item.key, *item.data}, args->output, args->properties};
   action->execute(args->context, work);
 }
 
@@ -336,10 +305,10 @@ void DigiMultiContainerProcessor::execute(DigiContext& context)  const  {
     }
   }
   if ( !work_items.empty() )   {
-    auto&    outputs = event.get_segment(m_output_segment);
-    output_t output { m_output_mask, outputs };
-    work_t   args   { context, work_items, output, *this };
-    m_kernel.submit(m_workers.get_calls(), m_workers.size(), &args, m_parallel);
+    auto& outputs = event.get_segment(m_output_segment);
+    output_t   output { m_output_mask, outputs };
+    work_t     args   { context, work_items, output, properties(), *this };
+    m_kernel.submit(m_workers.get_group(), m_workers.size(), &args, m_parallel);
   }
 }
 
@@ -348,17 +317,18 @@ template <> void DigiParallelWorker<DigiContainerProcessor,
 				    DigiMultiContainerProcessor::work_t,
 				    std::size_t>::execute(void* data) const  {
   calldata_t* arg   = reinterpret_cast<calldata_t*>(data);
-  const auto& keys  = arg->parent.worker_keys(this->options);
-  const auto& masks = arg->parent.input_masks();
+  const auto& par   = arg->parent;
+  const auto& keys  = par.worker_keys(this->options);
+  const auto& masks = par.input_masks();
   for( const auto& item : arg->items )  {
     Key key = item.first;
     if ( masks.empty() || std::find(masks.begin(), masks.end(), key.mask()) != masks.end() )  {
       if ( keys.empty() )  {
-	DigiContainerProcessor::work_t  work {arg->context, {key, *item.second }, arg->output };
+	DigiContainerProcessor::work_t  work {arg->context, {key, *item.second }, arg->output, arg->properties };
 	action->execute(work.context, work);
       }
       else if ( std::find(keys.begin(), keys.end(), Key(key.item())) != keys.end() )    {
-	DigiContainerProcessor::work_t  work {arg->context, {key, *item.second }, arg->output };
+	DigiContainerProcessor::work_t  work {arg->context, {key, *item.second }, arg->output, arg->properties };
 	action->execute(work.context, work);
       }
     }
diff --git a/DDDigi/src/DigiKernel.cpp b/DDDigi/src/DigiKernel.cpp
index 3c480bedcf8e09aed575f14e985556a7591c2c10..01a3b5a234b8eb09029f53b1619f5e7f19d2babe 100644
--- a/DDDigi/src/DigiKernel.cpp
+++ b/DDDigi/src/DigiKernel.cpp
@@ -27,6 +27,8 @@
 #include <tbb/tbb.h>
 #endif
 
+#include <TRandom.h>
+
 // C/C++ include files
 #include <stdexcept>
 #include <algorithm>
@@ -88,6 +90,10 @@ public:
   DigiActionSequence*   eventAction         { nullptr };
   /// The main data output action sequence
   DigiActionSequence*   outputAction        { nullptr };
+
+  /// Random generator
+  TRandom* root_random;
+  std::shared_ptr<DigiRandomGenerator> random  {};
   /// TBB initializer (If TBB is used)
   void*                 tbbInit             { nullptr };
   /// Property: Output level
@@ -151,6 +157,7 @@ public:
         int ev_num = kernel.internals->numEvents - todo;
 	std::unique_ptr<DigiContext> context = 
 	  std::make_unique<DigiContext>(this->kernel,std::make_unique<DigiEvent>(ev_num));
+	context->set_random_generator(this->kernel.internals->random);
         kernel.executeEvent(std::move(context));
       }
     }
@@ -179,6 +186,9 @@ DigiKernel::DigiKernel(Detector& description_ref)
   internals->inputAction->setExecuteParallel(false);
   internals->eventAction->setExecuteParallel(false);
   internals->outputAction->setExecuteParallel(false);
+  internals->root_random = new TRandom();
+  internals->random = std::make_shared<DigiRandomGenerator>();
+  internals->random->engine = [this] {  return this->internals->root_random->Uniform(1.0);  };
   InstanceCount::increment(this);
 }
 
diff --git a/DDDigi/src/DigiSegmentSplitter.cpp b/DDDigi/src/DigiSegmentSplitter.cpp
index f0cce33a9b094f7fb1b7cdc645db2578900579ec..ab2a1db77e6635712e52399031cb162e8477ea42 100644
--- a/DDDigi/src/DigiSegmentSplitter.cpp
+++ b/DDDigi/src/DigiSegmentSplitter.cpp
@@ -64,7 +64,8 @@ void DigiSegmentSplitter::initialize()   {
   /// 1) Check if the workers were pre-configured
   if ( !m_workers.empty() )    {
     bool bad = false;
-    const auto& workers = m_workers.get();
+    auto group = m_workers.get_group();
+    const auto& workers = group.actors();
     /// Create the processors:
     for( auto& p : m_splits )   {
       auto split_id = p.second.second;
diff --git a/DDDigi/src/DigiStoreDump.cpp b/DDDigi/src/DigiStoreDump.cpp
index f01ae514524a98f17e73503c6e0637561096ed6a..1b56b216a0e26bcf82576912dfd2bd9139649156 100644
--- a/DDDigi/src/DigiStoreDump.cpp
+++ b/DDDigi/src/DigiStoreDump.cpp
@@ -47,7 +47,7 @@ void dd4hep::digi::DigiStoreDump::dump(const std::string& tag,
   std::string str;
   std::vector<std::string> records;
   using detail::str_replace;
-  info("%s+---- %s segment: %ld entries", event.id(), tag.c_str(), data_segment.size());
+  info("%s+--- %-12s segment: %ld entries", event.id(), tag.c_str(), data_segment.size());
   std::lock_guard<std::mutex> lock(data_segment.lock);
   for ( const auto& e : data_segment )     {
     Key key {e.first};
@@ -59,22 +59,22 @@ void dd4hep::digi::DigiStoreDump::dump(const std::string& tag,
     typ = str_replace(str_replace(typ,"std::",""),"dd4hep::","");
     typ = str_replace(str_replace(typ,"sim::",""),"digi::","");
     if ( const auto* mapping = std::any_cast<DepositMapping>(&data) )   {
-      str = this->format("%s|---- %4X %08X %-32s: %6ld hits      [%s]", 
+      str = this->format("%s|----  %4X %08X %-32s: %6ld hits      [%s]", 
 			 event.id(), key.values.mask, key.values.item,
 			 nam.c_str(), mapping->size(), typ.c_str());
     }
     else if ( const auto* vector = std::any_cast<DepositVector>(&data) )   {
-      str = this->format("%s|---- %4X %08X %-32s: %6ld hits      [%s]", 
+      str = this->format("%s|----  %4X %08X %-32s: %6ld hits      [%s]", 
 			 event.id(), key.values.mask, key.values.item,
 			 nam.c_str(), vector->size(), typ.c_str());
     }
     else if ( const auto* parts = std::any_cast<ParticleMapping>(&data) )   {
-      str = this->format("%s|---- %4X %08X %-32s: %6ld particles [%s]", 
+      str = this->format("%s|----  %4X %08X %-32s: %6ld particles [%s]", 
 			 event.id(), key.values.mask, key.values.item,
 			 nam.c_str(), parts->size(), typ.c_str());
     }
     else   {
-      str = this->format("%s|---- %4X %08X %-32s: %s", 
+      str = this->format("%s|----  %4X %08X %-32s: %s", 
 			 event.id(), key.values.mask, key.values.item, 
 			 nam.c_str(), typ.c_str());
     }
diff --git a/DDDigi/src/noise/DigiSignalProcessorSequence.cpp b/DDDigi/src/noise/DigiSignalProcessorSequence.cpp
index f5d54c266ca8045aa204cf585f97ef3bf52a3f56..e31b10428fbd2d7b26c5f7aaf09e38a76989a6b7 100644
--- a/DDDigi/src/noise/DigiSignalProcessorSequence.cpp
+++ b/DDDigi/src/noise/DigiSignalProcessorSequence.cpp
@@ -55,7 +55,8 @@ void DigiSignalProcessorSequence::adopt(DigiSignalProcessor* action)    {
 double DigiSignalProcessorSequence::operator()(DigiCellContext& context)  const   {
   CallData args { context, 0e0 };
   double result = context.data.signal;
-  for ( const auto* p : m_actors.get() )  {
+  auto group = m_actors.get_group();
+  for ( const auto* p : group.actors() )  {
     args.value = 0e0;
     p->execute(&args);
     result += args.value;
diff --git a/examples/DDDigi/scripts/TestDepositCount.py b/examples/DDDigi/scripts/TestDepositCount.py
new file mode 100644
index 0000000000000000000000000000000000000000..6aa866e76c0882e850b38da321dea5906a64e80b
--- /dev/null
+++ b/examples/DDDigi/scripts/TestDepositCount.py
@@ -0,0 +1,32 @@
+# ==========================================================================
+#  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.
+#
+# ==========================================================================
+from __future__ import absolute_import
+
+
+def run():
+  import DigiTest
+  digi = DigiTest.Test(geometry=None)
+
+  input = digi.input_action('DigiParallelActionSequence/Reader')
+  # ========================================================================================================
+  digi.info('Created SIGNAL input')
+  signal = input.adopt_action('DigiSequentialActionSequence/Signal')
+  reader = signal.adopt_action('DigiROOTInput/SignalReader', mask=0x0, input=[digi.next_input()])
+  sequence = signal.adopt_action('DigiContainerSequenceAction/Counter',
+                                 parallel=True, input_mask=0x0, input_segment='inputs')
+  count = digi.create_action('DigiCellMultiplicityCounter/CellCounter')
+  sequence.adopt_container_processor(count, digi.containers())
+  # ========================================================================================================
+  digi.run_checked(num_events=7, num_threads=7, parallel=3)
+
+
+if __name__ == '__main__':
+  run()
diff --git a/examples/DDDigi/scripts/TestHitProcessing.py b/examples/DDDigi/scripts/TestHitProcessing.py
index ea61322503284434e4a9f86e143ee22e123774fb..b21d9faf4523710265aa749fd4f8b87293399da5 100644
--- a/examples/DDDigi/scripts/TestHitProcessing.py
+++ b/examples/DDDigi/scripts/TestHitProcessing.py
@@ -25,14 +25,12 @@ def run():
   # ========================================================================================================
   overlay = input.adopt_action('DigiSequentialActionSequence/Overlay-1')
   evtreader = overlay.adopt_action('DigiROOTInput/Read-1', mask=0x1, input=[digi.next_input()])
-  hist_drop = overlay.adopt_action('DigiHitHistoryDrop/Drop-1', masks=[evtreader.mask])
-  digi.check_creation([overlay, evtreader, hist_drop])
+  digi.check_creation([overlay, evtreader])
   digi.info('Created input.overlay-1')
   # ========================================================================================================
   overlay = input.adopt_action('DigiSequentialActionSequence/Overlay-2')
   evtreader = overlay.adopt_action('DigiROOTInput/Read-2', mask=0x2, input=[digi.next_input()])
-  hist_drop = overlay.adopt_action('DigiHitHistoryDrop/Drop-2', masks=[evtreader.mask])
-  digi.check_creation([overlay, evtreader, hist_drop])
+  digi.check_creation([overlay, evtreader])
   digi.info('Created input.overlay-2')
   # ========================================================================================================
   event = digi.event_action('DigiSequentialActionSequence/EventAction')
@@ -43,17 +41,21 @@ def run():
                                output_segment='deposits',
                                erase_combined=False)
   combine.erase_combined = True
-  dump = event.adopt_action('DigiStoreDump/StoreDump')
-  proc = event.adopt_action('DigiContainerSequenceAction/HitP1', parallel=True, input_mask=0xFEED, input_segment='deposits')
+  proc = event.adopt_action('DigiContainerSequenceAction/HitP1',
+                            parallel=True,
+                            input_mask=0xFEED,
+                            input_segment='deposits')
   count = digi.create_action('DigiCellMultiplicityCounter/CellCounter')
   proc.adopt_container_processor(count, digi.containers())
-  proc = event.adopt_action('DigiContainerSequenceAction/HitP2', parallel=True,
+  proc = event.adopt_action('DigiContainerSequenceAction/HitP2',
+                            parallel=True,
                             input_mask=0xFEED,
                             input_segment='deposits',
-                            output_mask = 0x0,
+                            output_mask=0x0,
                             output_segment='output')
-  count = digi.create_action('DigiDepositMapCreator/CellCreator')
+  count = digi.create_action('DigiDepositWeightedPosition/CellCreator')
   proc.adopt_container_processor(count, digi.containers())
+  dump = event.adopt_action('DigiStoreDump/StoreDump')
 
   digi.check_creation([combine, dump, proc])
   digi.info('Created event.dump')
diff --git a/examples/DDDigi/scripts/TestIPMove.py b/examples/DDDigi/scripts/TestIPMove.py
new file mode 100644
index 0000000000000000000000000000000000000000..f5435bb3626fd1f8b95b56d9cad4da7341e6aa27
--- /dev/null
+++ b/examples/DDDigi/scripts/TestIPMove.py
@@ -0,0 +1,39 @@
+# ==========================================================================
+#  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.
+#
+# ==========================================================================
+from __future__ import absolute_import
+
+
+def run():
+  import DigiTest
+  digi = DigiTest.Test(geometry=None)
+
+  input = digi.input_action('DigiParallelActionSequence/READER')
+  # ========================================================================================================
+  digi.info('Created SIGNAL input')
+  signal = input.adopt_action('DigiSequentialActionSequence/Signal')
+  reader = signal.adopt_action('DigiROOTInput/SignalReader', mask=0x0, input=[digi.next_input()])
+  set_ip = signal.adopt_action('DigiIPCreate/SignalIP')
+  set_ip.offset_ip = [1, 2, 3]
+  set_ip.sigma_ip  = [.5, .5, 3.0]
+  move_seq = signal.adopt_action('DigiContainerSequenceAction/MoveSignal',
+                                 parallel=True, input_mask=0x0, input_segment='inputs')
+  mover = digi.create_action('DigiIPMover/MoveIPSignal')
+  mover.ip_property = 'interaction_point'
+  mover.ip_creator = set_ip.get()
+  conts = [c for c in digi.containers()]
+  conts.append('MCParticles')
+  move_seq.adopt_container_processor(mover, conts)
+  # ========================================================================================================
+  digi.run_checked(num_events=7, num_threads=7, parallel=3)
+
+
+if __name__ == '__main__':
+  run()
diff --git a/examples/DDDigi/scripts/TestProperties.py b/examples/DDDigi/scripts/TestProperties.py
new file mode 100644
index 0000000000000000000000000000000000000000..be4d294d357cbfc6ae1fa6887cc66f8d0f602207
--- /dev/null
+++ b/examples/DDDigi/scripts/TestProperties.py
@@ -0,0 +1,92 @@
+# ==========================================================================
+#  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.
+#
+# ==========================================================================
+from __future__ import absolute_import
+
+
+def yes_no(val):
+  if val:
+    return "YES"
+  return "NO "
+
+def run():
+  import DigiTest
+  digi = DigiTest.Test(geometry=None)
+  input = digi.input_action('DigiParallelActionSequence/Test')
+
+  input.add_property('property_int', 1)
+  print('property: has_property =    %s'%(yes_no(input.hasProperty('property_int')),))
+  print('property: property_int =    %s'%(str(input.property_int),))
+  input.property_int = 123456
+  print('property: property_int =    %s'%(str(input.property_int),))
+
+  input.add_vector_property('property_vector_int', [1,2,3])
+  print('property: has_property =           %s'%(yes_no(input.hasProperty('property_vector_int')),))
+  print('property: property_vector_int =    %s'%(str(input.property_vector_int),))
+  input.property_vector_int = [1,2,3,4,5,6,7,8,9,0]
+  print('property: property_vector_int =    %s'%(str(input.property_vector_int),))
+
+  input.add_list_property('property_list_int', [1,2,3])
+  print('property: has_property =           %s'%(yes_no(input.hasProperty('property_list_int')),))
+  print('property: property_list_int =      %s'%(str(input.property_list_int),))
+  input.property_list_int = [1,2,3,4,5,6,7,8,9,0]
+  print('property: property_list_int =      %s'%(str(input.property_list_int),))
+
+  input.add_set_property('property_set_int', [1,2,3])
+  print('property: has_property =           %s'%(yes_no(input.hasProperty('property_set_int')),))
+  print('property: property_set_int =       %s'%(str(input.property_set_int),))
+  input.property_set_int = [1,2,3,4,5,6,7,8,9,0]
+  print('property: property_set_int =       %s'%(str(input.property_set_int),))
+
+  input.add_property('property_double', 1.0)
+  print('property: has_property =           %s'%(yes_no(input.hasProperty('property_double')),))
+  print('property: property_double =        %s'%(str(input.property_double),))
+  input.property_double = 123456.7
+  print('property: property_double =        %s'%(str(input.property_double),))
+
+  input.add_vector_property('property_vector_double', [1.1,2,3])
+  print('property: has_property =           %s'%(yes_no(input.hasProperty('property_vector_double')),))
+  print('property: property_vector_double = %s'%(str(input.property_vector_double),))
+  input.property_vector_double = [1.5,2,3,4,5,6,7,8,9,0]
+  print('property: property_vector_double = %s'%(str(input.property_vector_double),))
+
+  input.add_list_property('property_list_double', [1.1,2,3])
+  print('property: has_property =           %s'%(yes_no(input.hasProperty('property_list_double')),))
+  print('property: property_list_double =   %s'%(str(input.property_list_double),))
+  input.property_list_double = [1.5,2,3,4,5,6,7,8,9,0]
+  print('property: property_list_double =   %s'%(str(input.property_list_double),))
+
+  input.add_set_property('property_set_double', [1.1,2,3])
+  print('property: has_property =           %s'%(yes_no(input.hasProperty('property_set_double')),))
+  print('property: property_set_double =    %s'%(str(input.property_set_double),))
+  input.property_set_double = [1.5,2,3,4,5,6,7,8,9,0]
+  print('property: property_set_double =    %s'%(str(input.property_set_double),))
+
+  input.add_property('property_string', "string_1")
+  print('property: has_property =           %s'%(yes_no(input.hasProperty('property_string')),))
+  print('property: property_string =        %s'%(input.property_string,))
+  input.property_string = "string_1123456"
+  print('property: property_string =        %s'%(input.property_string,))
+
+  input.add_vector_property('property_vector_string', ["string1","string2","string3"])
+  print('property: has_property =           %s'%(yes_no(input.hasProperty('property_vector_string')),))
+  print('property: property_vector_string = %s'%(input.property_vector_string,))
+  input.property_vector_string = ["string1","string2","string3","string4","string5","string6"]
+  print('property: property_vector_string = %s'%(input.property_vector_string,))
+
+  input.add_position_property('property_position', (1.,2.,3.))
+  print('property: has_property =           %s'%(yes_no(input.hasProperty('property_position')),))
+  print('property: property_position =      %s'%(input.property_position,))
+  input.property_position = (111.1, 222.2, 333.3)
+  print('property: property_position =      %s'%(input.property_position,))
+
+
+if __name__ == '__main__':
+  run()
diff --git a/examples/DDDigi/scripts/TestResegmentation.py b/examples/DDDigi/scripts/TestResegmentation.py
new file mode 100644
index 0000000000000000000000000000000000000000..ed42aa1ee9369471072d756a95fa16f934dce973
--- /dev/null
+++ b/examples/DDDigi/scripts/TestResegmentation.py
@@ -0,0 +1,47 @@
+# ==========================================================================
+#  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.
+#
+# ==========================================================================
+from __future__ import absolute_import
+
+
+def run():
+  import DigiTest
+  digi = DigiTest.Test(geometry=None)
+  digi.load_geo()
+  input = digi.input_action('DigiParallelActionSequence/READER')
+  # ========================================================================
+  digi.info('Created SIGNAL input')
+  signal = input.adopt_action('DigiROOTInput/SignalReader', mask=0x0, input=[digi.next_input()])
+  digi.check_creation([signal])
+  # ========================================================================
+  event = digi.event_action('DigiSequentialActionSequence/EventAction')
+  seq = event.adopt_action('DigiContainerSequenceAction/ResegmentSeq',
+                           parallel=True, 
+                           input_mask=0x0, input_segment='inputs',
+                           output_mask=0xFEED, output_segment='outputs')
+  resegment = digi.create_action('DigiResegment/Resegment')
+  resegment.detector = 'EcalBarrel'
+  resegment.readout  = 'NewEcalBarrelHits'
+  resegment.descriptor = """
+  <readout name="NewEcalBarrelHits">
+    <segmentation type="CartesianGridXY" grid_size_x="10" grid_size_y="10" />
+    <id>system:8,barrel:3,module:4,layer:6,slice:5,x:32:-16,y:-16</id>
+  </readout>        
+  """
+  seq.adopt_container_processor(resegment,'EcalBarrelHits')
+  dump = event.adopt_action('DigiStoreDump/StoreDump')
+
+  digi.info('Created event.dump')
+  # ========================================================================
+  digi.run_checked(num_events=3, num_threads=5, parallel=3)
+
+
+if __name__ == '__main__':
+  run()
diff --git a/examples/DDDigi/scripts/TestSpillover.py b/examples/DDDigi/scripts/TestSpillover.py
index e3ef4562d806ede03f2fd1dbeb5a6b8447383775..6745adb40ce62ee76148881cd480b1580fa9cf45 100644
--- a/examples/DDDigi/scripts/TestSpillover.py
+++ b/examples/DDDigi/scripts/TestSpillover.py
@@ -28,60 +28,62 @@ def run():
   spillover = input.adopt_action('DigiSequentialActionSequence/Spillover-25')
   evtreader = spillover.adopt_action('DigiROOTInput/Reader-25ns', mask=0x1, input=[digi.next_input()])
   attenuate = spillover.adopt_action('DigiAttenuatorSequence/Att-25ns',
-                                     t0=-25 * ns, 
+                                     t0=-25 * ns,
                                      signal_decay='exponential',
                                      processor_type='DigiAttenuator',
-                                     mask=evtreader.mask,
+                                     input_mask=evtreader.mask,
+                                     input_segment='inputs',
                                      containers=attenuation)
   hist_drop = spillover.adopt_action('DigiHitHistoryDrop/Drop-25ns', masks=[evtreader.mask])
   digi.check_creation([spillover, evtreader, attenuate, hist_drop])
-  digi.info('Created input.spillover25')
+  digi.info('Created input.spillover-25')
   # ========================================================================================================
   spillover = input.adopt_action('DigiSequentialActionSequence/Spillover-50')
   evtreader = spillover.adopt_action('DigiROOTInput/Reader-50ns', mask=0x2, input=[digi.next_input()])
   attenuate = spillover.adopt_action('DigiAttenuatorSequence/Att-50ns',
-                                     t0=-50 * ns, mask=evtreader.mask, containers=attenuation)
+                                     t0=-50 * ns, input_mask=evtreader.mask, containers=attenuation)
   hist_drop = spillover.adopt_action('DigiHitHistoryDrop/Drop-50ns', masks=[evtreader.mask])
   digi.check_creation([spillover, evtreader, attenuate, hist_drop])
-  digi.info('Created input.spillover50')
+  digi.info('Created input.spillover-50')
   # ========================================================================================================
   spillover = input.adopt_action('DigiSequentialActionSequence/Spillover-75')
   evtreader = spillover.adopt_action('DigiROOTInput/Reader-75ns', mask=0x3, input=[digi.next_input()])
   attenuate = spillover.adopt_action('DigiAttenuatorSequence/Att-75ns',
-                                     t0=-75 * ns, mask=evtreader.mask, containers=attenuation)
+                                     t0=-75 * ns, input_mask=evtreader.mask, containers=attenuation)
   hist_drop = spillover.adopt_action('DigiHitHistoryDrop/Drop-75ns', masks=[evtreader.mask])
   digi.check_creation([spillover, evtreader, attenuate, hist_drop])
-  digi.info('Created input.spillover75')
+  digi.info('Created input.spillover-75')
   # ========================================================================================================
   digi.info('Creating spillover sequence for LATER bunch crossings.....')
   # ========================================================================================================
   spillover = input.adopt_action('DigiSequentialActionSequence/Spillover+25')
   evtreader = spillover.adopt_action('DigiROOTInput/Reader+25ns', mask=0x4, input=[digi.next_input()])
   attenuate = spillover.adopt_action('DigiAttenuatorSequence/Att+25ns',
-                                     t0=25 * ns, mask=evtreader.mask, containers=attenuation)
+                                     t0=25 * ns, input_mask=evtreader.mask, containers=attenuation)
   hist_drop = spillover.adopt_action('DigiHitHistoryDrop/Drop+25ns', masks=[evtreader.mask])
   digi.check_creation([spillover, evtreader, attenuate, hist_drop])
-  digi.info('Created input.spillover25')
+  digi.info('Created input.spillover+25')
   # ========================================================================================================
   spillover = input.adopt_action('DigiSequentialActionSequence/Spillover+50')
   evtreader = spillover.adopt_action('DigiROOTInput/Reader+50ns', mask=0x5, input=[digi.next_input()])
   attenuate = spillover.adopt_action('DigiAttenuatorSequence/Att+50ns',
-                                     t0=50 * ns, mask=evtreader.mask, containers=attenuation)
+                                     t0=50 * ns, input_mask=evtreader.mask, containers=attenuation)
   hist_drop = spillover.adopt_action('DigiHitHistoryDrop/Drop_50ns', masks=[evtreader.mask])
   digi.check_creation([spillover, evtreader, attenuate, hist_drop])
-  digi.info('Created input.spillover50')
+  digi.info('Created input.spillover+50')
   # ========================================================================================================
   spillover = input.adopt_action('DigiSequentialActionSequence/Spillover+75')
   evtreader = spillover.adopt_action('DigiROOTInput/Reader+75ns', mask=0x6, input=[digi.next_input()])
   attenuate = spillover.adopt_action('DigiAttenuatorSequence/Att+75ns',
-                                     t0=75 * ns, mask=evtreader.mask, containers=attenuation)
+                                     t0=75 * ns, input_mask=evtreader.mask, containers=attenuation)
   hist_drop = spillover.adopt_action('DigiHitHistoryDrop/Drop+75ns', masks=[evtreader.mask])
   digi.check_creation([spillover, evtreader, attenuate, hist_drop])
-  digi.info('Created input.spillover75')
+  digi.info('Created input.spillover+75')
   # ========================================================================================================
   event = digi.event_action('DigiSequentialActionSequence/EventAction')
   combine = event.adopt_action('DigiContainerCombine/Combine',
                                input_masks=[0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6],
+                               input_segment='inputs',
                                output_mask=0xFEED,
                                output_segment='deposits')
   combine.erase_combined = True  # Not thread-safe! only do in SequentialActionSequence