diff --git a/DDCore/include/Parsers/Primitives.h b/DDCore/include/Parsers/Primitives.h
index 77230c610321d315150bac8f8a575d04e72bd1ad..49dfe4ff6e22009d5db41bf718f70510b4de78aa 100644
--- a/DDCore/include/Parsers/Primitives.h
+++ b/DDCore/include/Parsers/Primitives.h
@@ -213,6 +213,12 @@ namespace dd4hep {
       /// Definition of the vector type
       typedef std::vector<value_t>              vector_t;
 
+      /// Definition of the bool mapped type
+      typedef std::pair<bool,value_t>           bool_pair_t;
+      /// Definition of the char mapped type
+      typedef std::pair<char,value_t>           char_pair_t;
+      /// Definition of the unsigned char mapped type
+      typedef std::pair<unsigned char,value_t>  uchar_pair_t;
       /// Definition of the short integer mapped type
       typedef std::pair<short,value_t>          short_pair_t;
       /// Definition of the unsigned short integer mapped type
@@ -226,6 +232,10 @@ namespace dd4hep {
       /// Definition of the unsigned long integer mapped type
       typedef std::pair<unsigned long,value_t>  ulong_pair_t;
       /// Definition of the size_t mapped type
+      typedef std::pair<float,value_t>          float_pair_t;
+      /// Definition of the size_t mapped type
+      typedef std::pair<double,value_t>         double_pair_t;
+      /// Definition of the size_t mapped type
       typedef std::pair<size_t,value_t>         size_pair_t;
       /// Definition of the string mapped type
       typedef std::pair<std::string,value_t>    string_pair_t;
diff --git a/DDCore/src/GrammarTypes.cpp b/DDCore/src/GrammarTypes.cpp
index 0a7136e49fde54da9f5e0a19205a7972be5c06f1..1aac7af070520b80b70bf55759d5ad695750708b 100644
--- a/DDCore/src/GrammarTypes.cpp
+++ b/DDCore/src/GrammarTypes.cpp
@@ -60,3 +60,7 @@ DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(bool,eval_item)
 DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(float,eval_item)
 DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(double,eval_item)
 DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(std::string,eval_item)
+
+DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(__LINE__,1,dd4hep::detail::Primitive<bool>::bool_pair_t,eval_pair)
+DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(__LINE__,2,dd4hep::detail::Primitive<float>::float_pair_t,eval_pair)
+DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(__LINE__,5,dd4hep::detail::Primitive<double>::double_pair_t,eval_pair)
diff --git a/DDDigi/include/DDDigi/DigiAttenuator.h b/DDDigi/include/DDDigi/DigiAttenuator.h
index 4082a7084e8e8a560107313ec1916b44475b47d2..b5ed824d6efd0a63b71896814cacbd68fcb8405e 100644
--- a/DDDigi/include/DDDigi/DigiAttenuator.h
+++ b/DDDigi/include/DDDigi/DigiAttenuator.h
@@ -58,13 +58,14 @@ namespace dd4hep {
       /// Default destructor
       virtual ~DigiAttenuator();
       /// Attenuator callback for single container
-      template <typename T> std::size_t attenuate(T& cont) const;
+      template <typename DEPOSITS> std::size_t
+      attenuate(DEPOSITS& cont, const predicate_t& predicate) const;
 
     public:
       /// Standard constructor
       DigiAttenuator(const DigiKernel& kernel, const std::string& nam);
       /// Main functional callback adapter
-      virtual void execute(DigiContext& context, work_t& work)  const override;
+      virtual void execute(DigiContext& context, work_t& work, const predicate_t& predicate)  const override;
     };
 
     /// Default base class for all Digitizer actions and derivates thereof.
diff --git a/DDDigi/include/DDDigi/DigiContainerProcessor.h b/DDDigi/include/DDDigi/DigiContainerProcessor.h
index 6ac2044b4e09a7777a2b466630b9aad75eba2912..621370e94b3a6c96d0569010a499a01e9743b419 100644
--- a/DDDigi/include/DDDigi/DigiContainerProcessor.h
+++ b/DDDigi/include/DDDigi/DigiContainerProcessor.h
@@ -14,6 +14,7 @@
 #define DDDIGI_DIGICONTAINERPROCESSOR_H
 
 // Framework include files
+#include <DD4hep/Callback.h>
 #include <DDDigi/DigiData.h>
 #include <DDDigi/DigiEventAction.h>
 #include <DDDigi/DigiParallelWorker.h>
@@ -28,11 +29,12 @@ namespace dd4hep {
   namespace digi {
 
     /// Forward declarations
-    class DigiContainerProcessor;
     class DigiContainerSequence;
+    class DigiContainerProcessor;
+    class DigiSegmentProcessContext;
     class DigiContainerSequenceAction;
     class DigiMultiContainerProcessor;
-
+    
     /// Worker base class to analyse containers from the input segment in parallel
     /**
      *
@@ -42,29 +44,45 @@ namespace dd4hep {
      */
     class DigiContainerProcessor : public DigiAction   {
     public:
-      using segment_t  = DataSegment;
-      using context_t  = DigiContext;
-      using action_t   = DigiAction;
-      using property_t = PropertyManager;
+      using segment_t      = DataSegment;
+      using context_t      = DigiContext;
+      using action_t       = DigiAction;
+      using property_t     = PropertyManager;
+      using segmentation_t = DigiSegmentProcessContext;
+
+      /// Input definition
       struct input_t  {
 	/// Input data key
 	Key             key;
 	/// Input deposits
 	std::any&       data;
       };
+
+      /// Output handle definition
       struct output_t  {
 	int             mask;
 	segment_t&      data;
       };
+
+      /// Hit processing predicate
+      struct predicate_t  {
+	Callback              callback;
+	const segmentation_t& segmentation;
+	predicate_t(const segmentation_t& s) : segmentation(s) {}
+	predicate_t(const Callback& cb, const segmentation_t& s) : callback(cb), segmentation(s) {}
+	/// Check if a deposit should be processed
+	bool operator()(const std::pair<const CellID, EnergyDeposit>& deposit)   const;
+      };
+
       struct work_t  {
 	/// Event processing context
-	context_t&  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;
+	const property_t&  properties;
 
 	/// Basic check if input data are present
 	bool has_input()  const    {  return this->input.data.has_value();  }
@@ -84,17 +102,16 @@ namespace dd4hep {
       /// Define standard assignments and constructors
       DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiContainerProcessor);
 
-    private:
-      /// Main functional callback if specific work is known.
-      virtual void execute(DigiContext& context, Key key, std::any& data)  const;
-
     public:
+      /// Access to default callback
+      static const predicate_t& accept_all();
+
       /// Standard constructor
       DigiContainerProcessor(const DigiKernel& kernel, const std::string& name);
       /// Default destructor
       virtual ~DigiContainerProcessor();
       /// Main functional callback adapter
-      virtual void execute(DigiContext& context, work_t& work)  const;
+      virtual void execute(DigiContext& context, work_t& work, const predicate_t& predicate)  const;
     };
 
     /// Worker class act on containers in an event identified by input masks and container name
@@ -114,6 +131,7 @@ namespace dd4hep {
       friend class DigiParallelWorker<processor_t,work_t>;
 
     protected:
+      /**  Member variables                           */
       /// Property to steer parallel processing
       bool               m_parallel { false };
       /// Array of sub-workers
@@ -136,7 +154,7 @@ namespace dd4hep {
       /// Adopt new parallel worker
       virtual void adopt_processor(DigiContainerProcessor* action);
       /// Main functional callback adapter
-      virtual void execute(DigiContext& context, work_t& work)  const;
+      virtual void execute(DigiContext& context, work_t& work, const predicate_t& predicate)  const;
     };
 
     /// Worker base class to analyse containers from the input segment in parallel
diff --git a/DDDigi/include/DDDigi/DigiData.h b/DDDigi/include/DDDigi/DigiData.h
index f31d7715e44d5563931664b2752507f1508bde42..2ae18985ade8eb8a6960f978a22d24c12d318b58 100644
--- a/DDDigi/include/DDDigi/DigiData.h
+++ b/DDDigi/include/DDDigi/DigiData.h
@@ -469,7 +469,9 @@ namespace dd4hep {
       enum { 
 	KILLED             = 1 << 0,
 	ENERGY_SMEARED     = 1 << 1,
-	POSITION_SMEARED   = 1 << 2
+	POSITION_SMEARED   = 1 << 2,
+	TIME_SMEARED       = 1 << 3,
+        RECALIBRATED       = 1 << 4
       };
 
       /// Hit position
@@ -480,6 +482,8 @@ namespace dd4hep {
       double         length      { 0 };
       /// Total energy deposit
       double         deposit     { 0 };
+      /// Proper creation time of the deposit with rescpect to beam crossing
+      double         time        { 0 };
       /// Optional flag for user masks
       long           flag        { 0 };
       /// Source mask of this deposit
diff --git a/DDDigi/include/DDDigi/DigiSegmentProcessor.h b/DDDigi/include/DDDigi/DigiSegmentProcessor.h
deleted file mode 100644
index d768ade556bd28996ea050b887661204a5db0da8..0000000000000000000000000000000000000000
--- a/DDDigi/include/DDDigi/DigiSegmentProcessor.h
+++ /dev/null
@@ -1,123 +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
-//
-//==========================================================================
-#ifndef DDDIGI_DIGISEGMENTPROCESSOR_H
-#define DDDIGI_DIGISEGMENTPROCESSOR_H
-
-// Framework include files
-#include <DDDigi/DigiData.h>
-#include <DDDigi/DigiContainerProcessor.h>
-#include <DDDigi/DigiSegmentationTool.h>
-
-/// Namespace for the AIDA detector description toolkit
-namespace dd4hep {
-
-  /// Namespace for the Digitization part of the AIDA detector description toolkit
-  namespace digi {
-
-    /// Forward declarations
-    class DigiSegmentProcessor;
-    class DigiSegmentSequence;
-
-    /// Default base class to process parts of a subdetector segmentation data
-    /**
-     *  This is a utility class supporting properties, output and access to
-     *  event and run objects through the context.
-     *
-     *  Default base class to process parts of a subdetector segmentation data.
-     *
-     *  \author  M.Frank
-     *  \version 1.0
-     *  \ingroup DD4HEP_DIGITAZATION
-     */
-    class DigiSegmentProcessor : public DigiContainerProcessor   {
-    public:
-      /// Segmentation split context
-      using segment_t = DigiSegmentContext;
-      using deposit_cell_t = std::pair<CellID,EnergyDeposit>;
-      using predicate_t = std::unary_function<deposit_cell_t, bool>;
-
-      struct accept_all_t : public predicate_t  {
-	accept_all_t() = default;
-	inline bool operator()(const deposit_cell_t& ) const  {
-	  return true;
-	}
-      };
-      struct accept_segment_t : public predicate_t  {
-	const segment_t& segment;
-        accept_segment_t(const segment_t& s) : segment(s) {}
-	inline bool operator()(const deposit_cell_t& depo) const  {
-	  return this->segment.matches(depo.first);
-	}
-      };
-
-      segment_t  segment  { };
-
-    protected:
-      /// Define standard assignments and constructors
-      DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiSegmentProcessor);
-
-    public:
-      /// Standard constructor
-      DigiSegmentProcessor(const DigiKernel& kernel, const std::string& name);
-      /// Default destructor
-      virtual ~DigiSegmentProcessor();
-      /// Main functional callback if specific work is known
-      virtual void execute(DigiContext& context, work_t& data)  const override;
-    };
-
-    /// Sequencer class to process parts of a subdetector segmentation data
-    /**
-     *  This is a utility class supporting properties, output and access to
-     *  event and run objects through the context.
-     *
-     *  The sequencer calls all registered processors for the contaiers registered.
-     *  The sequencer manages a set of workers all acting on the same data segment
-     *  being a part of the data of a collection
-     *
-     *  \author  M.Frank
-     *  \version 1.0
-     *  \ingroup DD4HEP_DIGITIZATION
-     */
-    class DigiSegmentSequence : public DigiSegmentProcessor  {
-    protected:
-      /// Property to steer parallel processing
-      bool m_parallel { false };
-
-    protected:
-      using self_t = DigiSegmentSequence;
-      using processor_t = DigiSegmentProcessor;
-      using worker_t  = DigiParallelWorker<processor_t,work_t,VolumeID>;
-      using workers_t = DigiParallelWorkers<worker_t>;
-      friend class DigiParallelWorker<processor_t,work_t,VolumeID>;
-
-      /// Array of sub-workers
-      workers_t         m_workers;
-
-    protected:
-      /// Define standard assignments and constructors
-      DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiSegmentSequence);
-      /// Default destructor
-      virtual ~DigiSegmentSequence();
-
-    public:
-      /// Standard constructor
-      DigiSegmentSequence(const DigiKernel& kernel, const std::string& name);
-      /// Adopt new parallel worker
-      virtual void adopt_processor(DigiContainerProcessor* action);
-      /// Main functional callback if specific work is known
-      virtual void execute(DigiContext& context, work_t& work)  const  override;
-    };
-
-  }    // End namespace digi
-}      // End namespace dd4hep
-#endif // DDDIGI_DIGISEGMENTPROCESSOR_H
diff --git a/DDDigi/include/DDDigi/DigiSegmentSplitter.h b/DDDigi/include/DDDigi/DigiSegmentSplitter.h
index df720166574d037e546b9dd8e30e78fb0bd24621..901854cc3dc54d50504b7b7c4c4495b6682dd183 100644
--- a/DDDigi/include/DDDigi/DigiSegmentSplitter.h
+++ b/DDDigi/include/DDDigi/DigiSegmentSplitter.h
@@ -15,7 +15,7 @@
 
 // Framework include files
 #include <DDDigi/DigiEventAction.h>
-#include <DDDigi/DigiSegmentProcessor.h>
+#include <DDDigi/DigiContainerProcessor.h>
 #include <DDDigi/DigiSegmentationTool.h>
 #include <DDDigi/DigiParallelWorker.h>
 
@@ -25,6 +25,58 @@ namespace dd4hep {
   /// Namespace for the Digitization part of the AIDA detector description toolkit
   namespace digi {
 
+    /// Segmentation split context
+    /**
+     *  
+     *  
+     *
+     *  \author  M.Frank
+     *  \version 1.0
+     *  \ingroup DD4HEP_DIGITIZATION
+     */
+    class DigiSegmentProcessContext : public DigiSegmentContext  {
+    public:
+      using predicate_t = DigiContainerProcessor::predicate_t;
+      predicate_t predicate  { {}, *this };
+      uint32_t    id         { 0 };
+
+    public:
+      /// Default constructor
+      DigiSegmentProcessContext() = default;
+      /// Default move constructor
+      DigiSegmentProcessContext(DigiSegmentProcessContext&& copy) = default;
+      /// Default copy constructor
+      DigiSegmentProcessContext(const DigiSegmentContext& copy);
+      /// Default copy constructor
+      DigiSegmentProcessContext(const DigiSegmentProcessContext& copy) = default;
+      /// Default destructor
+      virtual ~DigiSegmentProcessContext() = default;
+      /// Default move assignment
+      DigiSegmentProcessContext& operator=(const DigiSegmentContext& copy);
+      /// Default move assignment
+      DigiSegmentProcessContext& operator=(DigiSegmentProcessContext&& copy) = default;
+      /// Default copy assignment
+      DigiSegmentProcessContext& operator=(const DigiSegmentProcessContext& copy) = default;
+
+      /// Full identifier (field + id)
+      std::string identifier()  const;
+      /// Check a given cell id if it matches this selection
+      bool matches(uint64_t cell)  const  {
+	return this->split_id(cell) == this->id;
+      }
+    };
+
+    struct accept_segment_t : public DigiContainerProcessor::predicate_t  {
+      using segmentation_t = DigiSegmentProcessContext;
+      accept_segment_t(const segmentation_t& s) : predicate_t( { this }, s) {
+	auto fptr = &accept_segment_t::operator();
+	callback.make(fptr);
+      }
+      inline bool operator()(const std::pair<const CellID, EnergyDeposit>& depo) const  {
+	return this->segmentation.matches(depo.first);
+      }
+    };
+
     /// Default base class for all Digitizer actions and derivates thereof.
     /**
      *  This is a utility class supporting properties, output and access to
@@ -34,14 +86,19 @@ namespace dd4hep {
      *  \version 1.0
      *  \ingroup DD4HEP_DIGITIZATION
      */
-    class DigiSegmentSplitter : public DigiContainerSequence   {
+    class DigiSegmentSplitter : public DigiContainerProcessor   {
     protected:
       using self_t      = DigiSegmentSplitter;
       using split_t     = std::pair<DetElement, VolumeID>;
       using splits_t    = std::map<VolumeID, split_t>;
-      friend class DigiParallelWorker<processor_t, work_t, VolumeID>;
-      
+      using segment_t   = DigiSegmentProcessContext;
+      using processor_t = DigiContainerProcessor;
+      using worker_t    = DigiParallelWorker<processor_t,work_t, segment_t>;
+      using workers_t   = DigiParallelWorkers<worker_t>;
+      friend class DigiParallelWorker<processor_t, work_t, segment_t>;
+
     protected:
+      /**  Object properties                          */
       /// Property: Split element of the ID descriptor
       std::string          m_processor_type;
       /// Name of the subdetector to be handed
@@ -51,7 +108,7 @@ namespace dd4hep {
       /// Property: Flag if processors should be shared
       bool                 m_share_processor   { true };
 
-      /**  Member variables  */
+      /**  Member variables                           */
       /// Segmentation too instance
       mutable DigiSegmentationTool m_split_tool;
       /// Segmentation split context
@@ -60,6 +117,12 @@ namespace dd4hep {
       std::vector<Key>     m_keys;
       /// Split elements used to parallelize the processing
       splits_t             m_splits;
+      /// Property to steer parallel processing
+      bool                 m_parallel { false };
+      /// Array of sub-workers
+      workers_t            m_workers;
+      /// Lock for output merging
+      mutable std::mutex   m_output_lock;
 
     protected:
       /// Default destructor
@@ -67,8 +130,12 @@ namespace dd4hep {
 
       /// Initialization function
       void initialize();
-      /// Adopt new parallel worker: INHIBITED: will throw exception
-      virtual void adopt_processor(DigiContainerProcessor* action) override final;
+
+    public:
+      /// Adopt new parallel worker handling single split identifier
+      virtual void adopt_segment_processor(DigiContainerProcessor* action, int split_id);
+      /// Adopt new parallel worker handling multiple split-identifiers
+      virtual void adopt_segment_processor(DigiContainerProcessor* action, const std::vector<int>&  ids);
 
     public:
       /// Standard constructor
@@ -76,7 +143,7 @@ namespace dd4hep {
       /// Access the readout collection keys
       std::vector<std::string> collection_names()   const;
       /// Main functional callback
-      virtual void execute(DigiContext& context, work_t& work)  const  override;
+      virtual void execute(DigiContext& context, work_t& work, const predicate_t& predicate)  const  override;
     };
   }    // End namespace digi
 }      // End namespace dd4hep
diff --git a/DDDigi/include/DDDigi/DigiSegmentationTool.h b/DDDigi/include/DDDigi/DigiSegmentationTool.h
index 6dc38300e5f824eca783d303f5e0f21bd9d862c4..6ef34f1449240cac3b69052824598bb62bd0afde 100644
--- a/DDDigi/include/DDDigi/DigiSegmentationTool.h
+++ b/DDDigi/include/DDDigi/DigiSegmentationTool.h
@@ -48,15 +48,25 @@ namespace dd4hep {
       int32_t                offset     { 0 };
       int32_t                width      { 0 };
       int32_t                max_split  { 0 };
-      uint32_t               id         { 0 };
 
     public:
+      /// Default constructor
+      DigiSegmentContext() = default;
+      /// Default move constructor
+      DigiSegmentContext(DigiSegmentContext&& copy) = default;
+      /// Default copy constructor
+      DigiSegmentContext(const DigiSegmentContext& copy) = default;
+      /// Default destructor
+      virtual ~DigiSegmentContext() = default;
+      /// Default move assignment
+      DigiSegmentContext& operator=(DigiSegmentContext&& copy) = default;
+      /// Default copy assignment
+      DigiSegmentContext& operator=(const DigiSegmentContext& copy) = default;
+
       /// Split field name
       const std::string& name()  const;
       /// Split field name
       const char* cname()  const;
-      /// Full identifier (field + id)
-      std::string identifier()  const;
       
       /// Get the identifier of the cell to be split
       uint32_t split_id(uint64_t cell)  const  {
@@ -70,10 +80,6 @@ namespace dd4hep {
       uint64_t detector_id(uint64_t cell)  const  {
 	return (cell & this->det_mask);
       }
-      /// Check a given cell id if it matches this selection
-      bool matches(uint64_t cell)  const  {
-	return this->split_id(cell) == this->id;
-      }
     };
 
     /// Tool to handle segmentation manipulations
diff --git a/DDDigi/plugins/Components.cpp b/DDDigi/plugins/Components.cpp
index 3d7c772e1c274794e67cee9a8de1ba5b831cf77b..c375684435a55aaf68fddf16422a047919bf9219 100644
--- a/DDDigi/plugins/Components.cpp
+++ b/DDDigi/plugins/Components.cpp
@@ -60,10 +60,6 @@ DECLARE_DIGIACTION_NS(dd4hep::digi,DigiContainerCombine)
 #include <DDDigi/DigiContainerDrop.h>
 DECLARE_DIGIACTION_NS(dd4hep::digi,DigiContainerDrop)
 
-#include <DDDigi/DigiSegmentProcessor.h>
-DECLARE_DIGIACTION_NS(dd4hep::digi,DigiSegmentProcessor)
-DECLARE_DIGIACTION_NS(dd4hep::digi,DigiSegmentSequence)
-
 #include <DDDigi/DigiSegmentSplitter.h>
 DECLARE_DIGIACTION_NS(dd4hep::digi,DigiSegmentSplitter)
 
diff --git a/DDDigi/plugins/DigiCellMultiplicyCounter.cpp b/DDDigi/plugins/DigiCellMultiplicyCounter.cpp
index 125c26c5b9265ef9d33e67094c09f654cfe9877e..ae4635d4570828dbe783436020ba780e8ae76607 100644
--- a/DDDigi/plugins/DigiCellMultiplicyCounter.cpp
+++ b/DDDigi/plugins/DigiCellMultiplicyCounter.cpp
@@ -45,7 +45,7 @@ namespace dd4hep {
 	     tag, cont.name.c_str(), cont.size(), entries.size());
       }
       /// Main functional callback
-      virtual void execute(DigiContext& context, work_t& work)  const override final  {
+      virtual void execute(DigiContext& context, work_t& work, const predicate_t&)  const override final  {
 	if ( const auto* m = work.get_input<DepositMapping>() )
 	  count_deposits(context.event->id(), *m);
 	else if ( const auto* v = work.get_input<DepositVector>() )
diff --git a/DDDigi/plugins/DigiDepositDropKilled.cpp b/DDDigi/plugins/DigiDepositDropKilled.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..60ba5b2e61af6e36641b1dc7c03f1c0041233255
--- /dev/null
+++ b/DDDigi/plugins/DigiDepositDropKilled.cpp
@@ -0,0 +1,91 @@
+//==========================================================================
+//  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/DigiContainerProcessor.h>
+#include <DD4hep/InstanceCount.h>
+#include <DD4hep/DD4hepUnits.h>
+
+/// C/C++ include files
+#include <limits>
+
+/// Namespace for the AIDA detector description toolkit
+namespace dd4hep {
+
+  /// Namespace for the Digitization part of the AIDA detector description toolkit
+  namespace digi {
+
+    /// Actor to drop energy deposits of a container having the "KILLED" flag
+    /**
+     *
+     *
+     *  \author  M.Frank
+     *  \version 1.0
+     *  \ingroup DD4HEP_DIGITIZATION
+     */
+    class DigiDepositDropKilled : public DigiContainerProcessor   {
+    protected:
+      /// Property: Flag to update existing container in-place or create a new container
+      bool   m_update_in_place            { true  };
+
+    public:
+      /// Standard constructor
+      DigiDepositDropKilled(const DigiKernel& krnl, const std::string& nam)
+	: DigiContainerProcessor(krnl, nam)
+      {
+	declareProperty("update_in_place",            m_update_in_place = true);
+	InstanceCount::increment(this);
+      }
+
+      /// Default destructor
+      virtual ~DigiDepositDropKilled() {
+	InstanceCount::decrement(this);
+      }
+      template <typename T> std::size_t length(const T* m)  const {  return m->size(); }
+      /// Main functional callback
+      virtual void execute(DigiContext& context, work_t& work, const predicate_t&)  const override final  {
+	std::size_t killed = 0, total = 0, i = 0;
+	if ( auto* v = work.get_input<DepositVector>() )   {
+	  total = length(v);
+	  for( auto iter = v->begin(); iter != v->end(); ++iter, ++i )   {
+	    if ( v->at(i).flag&EnergyDeposit::KILLED )   {
+	      v->remove(iter);
+	      iter = v->begin() + (--i);
+	    }
+	  }
+	  killed = total - length(v);
+	}
+	else if ( auto* m = work.get_input<DepositMapping>() )   {
+	  CellID last_cell = ~0x0LL;
+	  total = length(m);
+	  for( auto iter = m->begin(); iter != m->end(); ++iter )   {
+	    if ( iter->second.flag&EnergyDeposit::KILLED )   {
+	      m->remove(iter);
+	      iter = (last_cell != ~0x0LL) ? m->data.find(last_cell) : m->begin();
+	      continue;
+	    }
+	    last_cell = iter->first;
+	  }
+	  killed = total - length(v);
+	}
+	else   {
+	  except("Request to handle unknown data type: %s", work.input_type_name().c_str());
+	}
+	info("%s+++ Killed %6ld out of %6ld deposit entries from container: %s",context.event->id(), killed, total);
+      }
+    };
+  }    // End namespace digi
+}      // End namespace dd4hep
+
+#include <DDDigi/DigiFactories.h>
+DECLARE_DIGIACTION_NS(dd4hep::digi,DigiDepositDropKilled)
diff --git a/DDDigi/plugins/DigiDepositMapCreator.cpp b/DDDigi/plugins/DigiDepositMapCreator.cpp
index fd637cb98c65e958b1ffd01c59de98bf17d3cb64..86765d0e18e4d0edbce90f55f1e3340b5ec3f9dc 100644
--- a/DDDigi/plugins/DigiDepositMapCreator.cpp
+++ b/DDDigi/plugins/DigiDepositMapCreator.cpp
@@ -35,23 +35,27 @@ namespace dd4hep {
       /// Standard constructor
       using DigiContainerProcessor::DigiContainerProcessor;
 
-      template <typename T> void create_deposits(const char* tag, const T& cont, work_t& work)  const  {
+      template <typename T> void
+      create_deposits(const char* tag, const T& cont, work_t& work, const predicate_t& predicate)  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());
+	for( const auto& dep : cont )   {
+	  if ( predicate(dep) )    {
+	    m.data.emplace(dep.first, EnergyDeposit());
+	  }
+	}
 	std::size_t end   = m.size();
 	work.output.data.put(m.key, std::move(m));
 	info("%s+++ %-32s added %6ld entries (now: %6ld) from mask: %04X to mask: %04X",
 	     tag, cont.name.c_str(), end-start, end, cont.key.mask(), m.key.mask());
       }
       /// Main functional callback
-      virtual void execute(DigiContext& context, work_t& work)  const override final  {
+      virtual void execute(DigiContext& context, work_t& work, const predicate_t& predicate)  const override final  {
 	if ( const auto* m = work.get_input<DepositMapping>() )
-	  create_deposits(context.event->id(), *m, work);
+	  create_deposits(context.event->id(), *m, work, predicate);
 	else if ( const auto* v = work.get_input<DepositVector>() )
-	  create_deposits(context.event->id(), *v, work);
+	  create_deposits(context.event->id(), *v, work, predicate);
 	else
 	  except("Request to handle unknown data type: %s", work.input_type_name().c_str());
       }
diff --git a/DDDigi/plugins/DigiDepositRecalibEnergy.cpp b/DDDigi/plugins/DigiDepositRecalibEnergy.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..490a23b1fbdcad1a08e4ac7b6bc24529f833c50d
--- /dev/null
+++ b/DDDigi/plugins/DigiDepositRecalibEnergy.cpp
@@ -0,0 +1,119 @@
+//==========================================================================
+//  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/DigiContainerProcessor.h>
+#include <DD4hep/InstanceCount.h>
+#include <DD4hep/DD4hepUnits.h>
+
+/// C/C++ include files
+
+/// Namespace for the AIDA detector description toolkit
+namespace dd4hep {
+
+  /// Namespace for the Digitization part of the AIDA detector description toolkit
+  namespace digi {
+
+    /// Actor to smear timing information of energy deposits
+    /**
+     *
+     *
+     *  \author  M.Frank
+     *  \version 1.0
+     *  \ingroup DD4HEP_DIGITIZATION
+     */
+    class DigiDepositRecalibEnergy : public DigiContainerProcessor   {
+    protected:
+      /// Property: Polynomial parameters to recalibrate the energy
+      std::vector<double> m_polynomial        {  };
+      /// Property: Energy base point to compute delta(energy)
+      double              m_e0                { 0e0 };
+      /// Property: Flag to update existing container in-place or create a new container
+      bool                m_update_in_place   { true };
+
+    public:
+      /// Standard constructor
+      DigiDepositRecalibEnergy(const DigiKernel& krnl, const std::string& nam)
+	: DigiContainerProcessor(krnl, nam)
+      {
+	declareProperty("e0", m_e0);
+	declareProperty("parameters" , m_polynomial);
+	InstanceCount::increment(this);
+      }
+
+      /// Default destructor
+      virtual ~DigiDepositRecalibEnergy() {
+	InstanceCount::decrement(this);
+      }
+
+      /// Create deposit mapping with updates on same cellIDs
+      template <typename T> void recalibrate_deposit_energy(DigiContext& context,
+							    T& cont,
+							    work_t& work,
+							    const predicate_t& predicate)  const  {
+	T output_cont(cont.name, work.output.mask);
+	std::size_t updated = 0UL;
+	std::size_t created = 0UL;
+	std::size_t killed  = 0UL;
+
+	info("%s+++ Recalibrarting deposit container: %s %6ld entries",
+	     context.event->id(), cont.name.c_str(), cont.size());
+	for( auto& dep : cont )    {
+	  if ( predicate(dep) )   {
+	    double deposit = dep.second.deposit;
+	    double delta_E = deposit - m_e0;
+	    double fac     = 1e0;
+	    for( double param : m_polynomial )   {
+	      deposit += param * fac;
+	      fac     *= delta_E;
+	    }
+	    if ( m_update_in_place )   {
+	      EnergyDeposit& d = dep.second;
+	      d.deposit = deposit;
+	      d.flag |= EnergyDeposit::RECALIBRATED;
+	      ++updated;
+	    }
+	    else if ( !(dep.second.flag&EnergyDeposit::KILLED) )  {
+	      EnergyDeposit d(dep.second);
+	      d.deposit = deposit;
+	      d.flag |= EnergyDeposit::RECALIBRATED;
+	      output_cont.emplace(dep.first, std::move(d));
+	      ++created;
+	    }
+	    else  {
+	      ++killed;
+	    }
+	  }
+	}
+	if ( !m_update_in_place )   {
+	  work.output.data.put(output_cont.key, std::move(output_cont));
+	}
+	info("%s+++ %-32s Smearing: created %6ld updated %6ld killed %6ld entries from mask: %04X",
+	     context.event->id(), cont.name.c_str(), created, updated, killed, cont.key.mask());
+      }
+
+      /// Main functional callback
+      virtual void execute(DigiContext& context, work_t& work, const predicate_t& predicate)  const override final  {
+	if ( auto* v = work.get_input<DepositVector>() )
+	  recalibrate_deposit_energy(context, *v, work, predicate);
+	else if ( auto* m = work.get_input<DepositMapping>() )
+	  recalibrate_deposit_energy(context, *m, work, predicate);
+	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,DigiDepositRecalibEnergy)
diff --git a/DDDigi/plugins/DigiDepositSmearEnergy.cpp b/DDDigi/plugins/DigiDepositSmearEnergy.cpp
index b76f7453041d2c1f24bda5e9e2362c8ca374d751..3aaa47538d5c18ebb90e77ae61e436930ca0a40a 100644
--- a/DDDigi/plugins/DigiDepositSmearEnergy.cpp
+++ b/DDDigi/plugins/DigiDepositSmearEnergy.cpp
@@ -75,8 +75,6 @@ namespace dd4hep {
       double m_pair_ionization_energy     { 0e0 };
       /// Property: Flag to use ionization fluctuation smearing (poisson ~ # e-ion-pairs)
       bool   m_ionization_fluctuation     { false };
-      /// Property: Flag to drop killed entries from the deposits
-      bool   m_drop_killed                { false };
       /// Property: Flag to update existing container in-place or create a new container
       bool   m_update_in_place            { true  };
 
@@ -85,7 +83,6 @@ namespace dd4hep {
       DigiDepositSmearEnergy(const DigiKernel& krnl, const std::string& nam)
 	: DigiContainerProcessor(krnl, nam)
       {
-	declareProperty("drop_killed",                m_drop_killed = false);
 	declareProperty("deposit_cutoff",             m_deposit_cutoff);
 	declareProperty("intrinsic_fluctuation",      m_intrinsic_fluctuation = 0e0);
 	declareProperty("instrumentation_resolution", m_instrumentation_resolution = 0e0);
@@ -101,24 +98,9 @@ namespace dd4hep {
 	InstanceCount::decrement(this);
       }
 
-      template <typename T> std::size_t drop_killed_entries(T& cont)   const  {
-	//CellID last_cell = 0UL;
-	std::size_t killed = 0;
-	for( auto iter = cont.begin(); iter != cont.end(); ++iter )   {
-	  auto& dep = iter->second;
-	  if ( dep.flag&EnergyDeposit::KILLED )   {
-	    cont.remove(iter);
-	    iter = cont.begin(); // (last_cell != 0UL) ? cont.find(last_cell) : cont.begin();
-	    ++killed;
-	    continue;
-	  }
-	  //last_cell = iter->first;
-	}
-	return killed;
-      }
-
       /// Create deposit mapping with updates on same cellIDs
-      template <typename T> void smear_deposit_energy(DigiContext& context, T& cont, work_t& work)  const  {
+      template <typename T> void
+      smear(DigiContext& context, T& cont, work_t& work, const predicate_t& predicate)  const  {
 	auto& random = context.randomGenerator();
 	T output_cont(cont.name, work.output.mask);
 	std::size_t killed = 0UL;
@@ -130,80 +112,76 @@ namespace dd4hep {
 		context.event->id(), cont.name.c_str(), cont.size());
 	}
 	for( auto& dep : cont )    {
-	  CellID cell = dep.first;
-	  const EnergyDeposit& depo = dep.second;
-	  double deposit = depo.deposit;
-	  if ( deposit >= m_deposit_cutoff )   {
-	    double delta_E = 0e0;
-	    double energy  = deposit / dd4hep::GeV; // E in units of GeV
-	    double sigma_E_systematic   = m_systematic_resolution * energy;
-	    double sigma_E_intrin_fluct = m_intrinsic_fluctuation * std::sqrt(energy);
-	    double sigma_E_instrument   = m_instrumentation_resolution / dd4hep::GeV;
-	    double delta_ion = 0e0, num_pairs = 0e0;
-	    constexpr static double eps = std::numeric_limits<double>::epsilon();
-	    if ( sigma_E_systematic > eps )   {
-	      delta_E += sigma_E_systematic * random.gaussian(0e0, 1e0);
-	    }
-	    if ( sigma_E_intrin_fluct > eps )   {
-	      delta_E += sigma_E_intrin_fluct * random.gaussian(0e0, 1e0);
-	    }
-	    if ( sigma_E_instrument > eps )   {
-	      delta_E += sigma_E_instrument * random.gaussian(0e0, 1e0);
-	    }
-	    if ( m_ionization_fluctuation )   {
-	      num_pairs = energy / (m_pair_ionization_energy/dd4hep::GeV);
-	      delta_ion = energy * (random.poisson(num_pairs)/num_pairs);
-	      delta_E += delta_ion;
-	    }
-	    if ( dd4hep::isActivePrintLevel(outputLevel()) )   {
-	      print("+++ %016lX [GeV] E:%9.2e [%9.2e %9.2e] intrin_fluct:%9.2e systematic:%9.2e instrument:%9.2e ioni:%9.2e/%.0f %s",
-		    cell, energy, deposit/dd4hep::GeV, delta_E,
-		    sigma_E_intrin_fluct, sigma_E_systematic, sigma_E_instrument, delta_ion, num_pairs,
-		    deposit < m_deposit_cutoff ? "KILLED" : "");
-	    }
-	    /// delta_E is in GeV
-	    if ( deposit > m_deposit_cutoff )  {
-	      if ( m_update_in_place )   {
-		EnergyDeposit& d = dep.second;
-		d.deposit = deposit + (delta_E * dd4hep::GeV);
-		d.flag |= EnergyDeposit::ENERGY_SMEARED;
-		++updated;
+	  if ( predicate(dep) )   {
+	    CellID cell = dep.first;
+	    const EnergyDeposit& depo = dep.second;
+	    double deposit = depo.deposit;
+	    if ( deposit >= m_deposit_cutoff )   {
+	      double delta_E = 0e0;
+	      double energy  = deposit / dd4hep::GeV; // E in units of GeV
+	      double sigma_E_systematic   = m_systematic_resolution * energy;
+	      double sigma_E_intrin_fluct = m_intrinsic_fluctuation * std::sqrt(energy);
+	      double sigma_E_instrument   = m_instrumentation_resolution / dd4hep::GeV;
+	      double delta_ion = 0e0, num_pairs = 0e0;
+	      constexpr static double eps = std::numeric_limits<double>::epsilon();
+	      if ( sigma_E_systematic > eps )   {
+		delta_E += sigma_E_systematic * random.gaussian(0e0, 1e0);
 	      }
-	      else   {
-		EnergyDeposit d(depo);
-		d.deposit = deposit + (delta_E * dd4hep::GeV);
-		d.flag |= EnergyDeposit::ENERGY_SMEARED;	
-		output_cont.emplace(cell, EnergyDeposit(depo));
-		++created;
+	      if ( sigma_E_intrin_fluct > eps )   {
+		delta_E += sigma_E_intrin_fluct * random.gaussian(0e0, 1e0);
+	      }
+	      if ( sigma_E_instrument > eps )   {
+		delta_E += sigma_E_instrument * random.gaussian(0e0, 1e0);
+	      }
+	      if ( m_ionization_fluctuation )   {
+		num_pairs = energy / (m_pair_ionization_energy/dd4hep::GeV);
+		delta_ion = energy * (random.poisson(num_pairs)/num_pairs);
+		delta_E += delta_ion;
+	      }
+	      if ( dd4hep::isActivePrintLevel(outputLevel()) )   {
+		print("+++ %016lX [GeV] E:%9.2e [%9.2e %9.2e] intrin_fluct:%9.2e systematic:%9.2e instrument:%9.2e ioni:%9.2e/%.0f %s",
+		      cell, energy, deposit/dd4hep::GeV, delta_E,
+		      sigma_E_intrin_fluct, sigma_E_systematic, sigma_E_instrument, delta_ion, num_pairs,
+		      deposit < m_deposit_cutoff ? "KILLED" : "");
+	      }
+	      /// delta_E is in GeV
+	      if ( deposit > m_deposit_cutoff )  {
+		if ( m_update_in_place )   {
+		  EnergyDeposit& d = dep.second;
+		  d.deposit = deposit + (delta_E * dd4hep::GeV);
+		  d.flag |= EnergyDeposit::ENERGY_SMEARED;
+		  ++updated;
+		}
+		else   {
+		  EnergyDeposit d(depo);
+		  d.deposit = deposit + (delta_E * dd4hep::GeV);
+		  d.flag |= EnergyDeposit::ENERGY_SMEARED;	
+		  output_cont.emplace(cell, EnergyDeposit(depo));
+		  ++created;
+		}
+		continue;
 	      }
-	      continue;
 	    }
-	  }
-	  else if ( !m_update_in_place )   {
-	    EnergyDeposit& d = dep.second;
-	    d.flag |= EnergyDeposit::KILLED;
-	    ++killed;
+	    else if ( !m_update_in_place )   {
+	      EnergyDeposit& d = dep.second;
+	      d.flag |= EnergyDeposit::KILLED;
+	      ++killed;
+	    }
 	  }
 	}
-
 	if ( !m_update_in_place )   {
 	  work.output.data.put(output_cont.key, std::move(output_cont));
 	}
-
-	killed = (m_drop_killed && m_update_in_place && killed > 0) 
-	  ? drop_killed_entries(cont)
-	  : killed;
-
 	info("%s+++ %-32s Smearing: created %6ld updated %6ld killed %6ld entries from mask: %04X",
 	     context.event->id(), cont.name.c_str(), created, updated, killed, cont.key.mask());
       }
 
       /// Main functional callback
-      virtual void execute(DigiContext& context, work_t& work)  const override final  {
+      virtual void execute(DigiContext& context, work_t& work, const predicate_t& predicate)  const override final  {
 	if ( auto* v = work.get_input<DepositVector>() )
-	  smear_deposit_energy(context, *v, work);
+	  smear(context, *v, work, predicate);
 	else if ( auto* m = work.get_input<DepositMapping>() )
-	  smear_deposit_energy(context, *m, work);
+	  smear(context, *m, work, predicate);
 	else
 	  except("Request to handle unknown data type: %s", work.input_type_name().c_str());
       }
diff --git a/DDDigi/plugins/DigiDepositSmearPositionResolution.cpp b/DDDigi/plugins/DigiDepositSmearPositionResolution.cpp
index 960d65c268af41edf056f43f2627a1394b47530c..5c82012e054bddaa3e0219d6268cc44a8087421a 100644
--- a/DDDigi/plugins/DigiDepositSmearPositionResolution.cpp
+++ b/DDDigi/plugins/DigiDepositSmearPositionResolution.cpp
@@ -65,7 +65,8 @@ namespace dd4hep {
       }
 
       /// Create deposit mapping with updates on same cellIDs
-      template <typename T> void smear_deposit_position(DigiContext& context, T& cont, work_t& work)  const  {
+      template <typename T> void
+      smear(DigiContext& context, T& cont, work_t& work, const predicate_t& predicate)  const  {
 	T output_cont(cont.name, work.output.mask);
 	auto& random = context.randomGenerator();
 	std::size_t killed = 0UL;
@@ -78,45 +79,46 @@ namespace dd4hep {
 	}
 	VolumeManager volMgr = m_kernel.detectorDescription().volumeManager();
 	for( auto& dep : cont )    {
-	  CellID cell = dep.first;
-	  const EnergyDeposit& depo = dep.second;
-	  double deposit = depo.deposit;
-	  if ( deposit >= m_deposit_cutoff )   {
-	    auto*     ctxt = volMgr.lookupContext(cell);
-	    Position  local_pos = ctxt->worldToLocal(depo.position);
-	    double    delta_u   = m_resolution_u * random.gaussian();
-	    double    delta_v   = m_resolution_v * random.gaussian();
-	    Position  delta_pos(delta_u, delta_v, 0e0);
-	    Position  oldpos = depo.position;
-	    Position  newpos = ctxt->localToWorld(local_pos + delta_pos);
+	  if ( predicate(dep) )   {
+	    CellID cell = dep.first;
+	    const EnergyDeposit& depo = dep.second;
+	    double deposit = depo.deposit;
+	    if ( deposit >= m_deposit_cutoff )   {
+	      auto*     ctxt = volMgr.lookupContext(cell);
+	      Position  local_pos = ctxt->worldToLocal(depo.position);
+	      double    delta_u   = m_resolution_u * random.gaussian();
+	      double    delta_v   = m_resolution_v * random.gaussian();
+	      Position  delta_pos(delta_u, delta_v, 0e0);
+	      Position  oldpos = depo.position;
+	      Position  newpos = ctxt->localToWorld(local_pos + delta_pos);
 
-	    delta_pos = newpos - oldpos;
-	    info("+++ %016lX Smeared position [%9.2e %9.2e %9.2e] by [%9.2e %9.2e %9.2e] to [%9.2e %9.2e %9.2e] [mm]",
-		 oldpos.X(), oldpos.Y(), oldpos.Z(), delta_pos.X(), delta_pos.Y(), delta_pos.Z(),
-		 newpos.X(), newpos.Y(), newpos.Z());
+	      delta_pos = newpos - oldpos;
+	      info("+++ %016lX Smeared position [%9.2e %9.2e %9.2e] by [%9.2e %9.2e %9.2e] to [%9.2e %9.2e %9.2e] [mm]",
+		   oldpos.X(), oldpos.Y(), oldpos.Z(), delta_pos.X(), delta_pos.Y(), delta_pos.Z(),
+		   newpos.X(), newpos.Y(), newpos.Z());
 
-	    /// Update / create deposit with smeared position
-	    if ( m_update_in_place )   {
-	      EnergyDeposit& d = dep.second;
-	      d.position = newpos;
-	      d.flag |= EnergyDeposit::POSITION_SMEARED;
-	      ++updated;
+	      /// Update / create deposit with smeared position
+	      if ( m_update_in_place )   {
+		EnergyDeposit& d = dep.second;
+		d.position = newpos;
+		d.flag |= EnergyDeposit::POSITION_SMEARED;
+		++updated;
+	      }
+	      else   {
+		EnergyDeposit d(depo);
+		d.position = newpos;
+		d.flag |= EnergyDeposit::POSITION_SMEARED;
+		output_cont.emplace(cell, std::move(d));
+		++created;
+	      }
 	    }
-	    else   {
-	      EnergyDeposit d(depo);
-	      d.position = newpos;
-	      d.flag |= EnergyDeposit::POSITION_SMEARED;
-	      output_cont.emplace(cell, std::move(d));
-	      ++created;
+	    else if ( !m_update_in_place )   {
+	      EnergyDeposit& d = dep.second;
+	      d.flag |= EnergyDeposit::KILLED;
+	      ++killed;
 	    }
 	  }
-	  else if ( !m_update_in_place )   {
-	    EnergyDeposit& d = dep.second;
-	    d.flag |= EnergyDeposit::KILLED;
-	    ++killed;
-	  }
 	}
-
 	if ( !m_update_in_place )   {
 	  work.output.data.put(output_cont.key, std::move(output_cont));
 	}
@@ -125,11 +127,11 @@ namespace dd4hep {
       }
 
       /// Main functional callback
-      virtual void execute(DigiContext& context, work_t& work)  const override final  {
+      virtual void execute(DigiContext& context, work_t& work, const predicate_t& predicate)  const override final  {
 	if ( auto* v = work.get_input<DepositVector>() )
-	  smear_deposit_position(context, *v, work);
+	  smear(context, *v, work, predicate);
 	else if ( auto* m = work.get_input<DepositMapping>() )
-	  smear_deposit_position(context, *m, work);
+	  smear(context, *m, work, predicate);
 	else
 	  except("Request to handle unknown data type: %s", work.input_type_name().c_str());
       }
diff --git a/DDDigi/plugins/DigiDepositSmearPositionTrack.cpp b/DDDigi/plugins/DigiDepositSmearPositionTrack.cpp
index 652ae28da8a61ec2c6bf2b1bb76a412ab34e0c51..25aad28fedea174844a58d4a01afdf9ac897c684 100644
--- a/DDDigi/plugins/DigiDepositSmearPositionTrack.cpp
+++ b/DDDigi/plugins/DigiDepositSmearPositionTrack.cpp
@@ -65,7 +65,8 @@ namespace dd4hep {
       }
 
       /// Create deposit mapping with updates on same cellIDs
-      template <typename T> void smear_deposit_position(DigiContext& context, T& cont, work_t& work)  const  {
+      template <typename T> void
+      smear(DigiContext& context, T& cont, work_t& work, const predicate_t& predicate)  const  {
 	constexpr double eps = detail::numeric_epsilon;
 	T output_cont(cont.name, work.output.mask);
 	auto& random = context.randomGenerator();
@@ -80,55 +81,56 @@ namespace dd4hep {
 	}
 	VolumeManager volMgr = m_kernel.detectorDescription().volumeManager();
 	for( auto& dep : cont )    {
-	  CellID cell = dep.first;
-	  const EnergyDeposit& depo = dep.second;
-	  double deposit = depo.deposit;
-	  if ( deposit >= m_deposit_cutoff )   {
-	    auto*     ctxt = volMgr.lookupContext(cell);
-	    Direction part_momentum = depo.history.average_particle_momentum(ev);
-	    Position  local_pos = ctxt->worldToLocal(depo.position);
-	    Position  local_dir = ctxt->worldToLocal(part_momentum).unit();
-	    double    cos_u   = local_dir.Dot(Position(1,0,0));
-	    double    sin_u   = std::sqrt(1e0 - cos_u*cos_u);
-	    double    tan_u   = sin_u/(std::abs(cos_u)>eps ? cos_u : eps);
-	    double    delta_u = tan_u * m_resolution_u * random.gaussian();
-
-	    double    cos_v   = local_dir.Dot(Position(0,1,0));
-	    double    sin_v   = std::sqrt(1e0 - cos_v*cos_v);
-	    double    tan_v   = sin_v/(std::abs(cos_v)>eps ? cos_v : eps);
-	    double    delta_v = tan_v * m_resolution_v * random.gaussian();
-
-	    Position  delta_pos(delta_u, delta_v, 0e0);
-	    Position  oldpos = depo.position;
-	    Position  newpos = ctxt->localToWorld(local_pos + delta_pos);
-
-	    delta_pos = newpos - oldpos;
-	    info("+++ %016lX Smeared position [%9.2e %9.2e %9.2e] by [%9.2e %9.2e %9.2e] to [%9.2e %9.2e %9.2e] [mm]",
-		 oldpos.X(), oldpos.Y(), oldpos.Z(), delta_pos.X(), delta_pos.Y(), delta_pos.Z(),
-		 newpos.X(), newpos.Y(), newpos.Z());
-
-	    /// Update / create deposit with smeared position
-	    if ( m_update_in_place )   {
-	      EnergyDeposit& d = dep.second;
-	      d.position = newpos;
-	      d.flag |= EnergyDeposit::POSITION_SMEARED;
-	      ++updated;
+	  if ( predicate(dep) )   {
+	    CellID cell = dep.first;
+	    const EnergyDeposit& depo = dep.second;
+	    double deposit = depo.deposit;
+	    if ( deposit >= m_deposit_cutoff )   {
+	      auto*     ctxt = volMgr.lookupContext(cell);
+	      Direction part_momentum = depo.history.average_particle_momentum(ev);
+	      Position  local_pos = ctxt->worldToLocal(depo.position);
+	      Position  local_dir = ctxt->worldToLocal(part_momentum).unit();
+	      double    cos_u   = local_dir.Dot(Position(1,0,0));
+	      double    sin_u   = std::sqrt(1e0 - cos_u*cos_u);
+	      double    tan_u   = sin_u/(std::abs(cos_u)>eps ? cos_u : eps);
+	      double    delta_u = tan_u * m_resolution_u * random.gaussian();
+
+	      double    cos_v   = local_dir.Dot(Position(0,1,0));
+	      double    sin_v   = std::sqrt(1e0 - cos_v*cos_v);
+	      double    tan_v   = sin_v/(std::abs(cos_v)>eps ? cos_v : eps);
+	      double    delta_v = tan_v * m_resolution_v * random.gaussian();
+
+	      Position  delta_pos(delta_u, delta_v, 0e0);
+	      Position  oldpos = depo.position;
+	      Position  newpos = ctxt->localToWorld(local_pos + delta_pos);
+
+	      delta_pos = newpos - oldpos;
+	      info("+++ %016lX Smeared position [%9.2e %9.2e %9.2e] by [%9.2e %9.2e %9.2e] to [%9.2e %9.2e %9.2e] [mm]",
+		   oldpos.X(), oldpos.Y(), oldpos.Z(), delta_pos.X(), delta_pos.Y(), delta_pos.Z(),
+		   newpos.X(), newpos.Y(), newpos.Z());
+
+	      /// Update / create deposit with smeared position
+	      if ( m_update_in_place )   {
+		EnergyDeposit& d = dep.second;
+		d.position = newpos;
+		d.flag |= EnergyDeposit::POSITION_SMEARED;
+		++updated;
+	      }
+	      else   {
+		EnergyDeposit d(depo);
+		d.position = newpos;
+		d.flag |= EnergyDeposit::POSITION_SMEARED;
+		output_cont.emplace(cell, std::move(d));
+		++created;
+	      }
 	    }
-	    else   {
-	      EnergyDeposit d(depo);
-	      d.position = newpos;
-	      d.flag |= EnergyDeposit::POSITION_SMEARED;
-	      output_cont.emplace(cell, std::move(d));
-	      ++created;
+	    else if ( !m_update_in_place )   {
+	      EnergyDeposit& d = dep.second;
+	      d.flag |= EnergyDeposit::KILLED;
+	      ++killed;
 	    }
 	  }
-	  else if ( !m_update_in_place )   {
-	    EnergyDeposit& d = dep.second;
-	    d.flag |= EnergyDeposit::KILLED;
-	    ++killed;
-	  }
 	}
-
 	if ( !m_update_in_place )   {
 	  work.output.data.put(output_cont.key, std::move(output_cont));
 	}
@@ -137,11 +139,11 @@ namespace dd4hep {
       }
 
       /// Main functional callback
-      virtual void execute(DigiContext& context, work_t& work)  const override final  {
+      virtual void execute(DigiContext& context, work_t& work, const predicate_t& predicate)  const override final  {
 	if ( auto* v = work.get_input<DepositVector>() )
-	  smear_deposit_position(context, *v, work);
+	  smear(context, *v, work, predicate);
 	else if ( auto* m = work.get_input<DepositMapping>() )
-	  smear_deposit_position(context, *m, work);
+	  smear(context, *m, work, predicate);
 	else
 	  except("Request to handle unknown data type: %s", work.input_type_name().c_str());
       }
diff --git a/DDDigi/plugins/DigiDepositSmearTime.cpp b/DDDigi/plugins/DigiDepositSmearTime.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7925d1f82dfb8f31de661b9e77e0137dd370e730
--- /dev/null
+++ b/DDDigi/plugins/DigiDepositSmearTime.cpp
@@ -0,0 +1,116 @@
+//==========================================================================
+//  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/DigiContainerProcessor.h>
+#include <DD4hep/InstanceCount.h>
+#include <DD4hep/DD4hepUnits.h>
+
+/// C/C++ include files
+#include <limits>
+
+/// Namespace for the AIDA detector description toolkit
+namespace dd4hep {
+
+  /// Namespace for the Digitization part of the AIDA detector description toolkit
+  namespace digi {
+
+    /// Actor to smear timing information of energy deposits
+    /**
+     *
+     *
+     *  \author  M.Frank
+     *  \version 1.0
+     *  \ingroup DD4HEP_DIGITIZATION
+     */
+    class DigiDepositSmearTime : public DigiContainerProcessor   {
+    protected:
+      using limit_t = std::numeric_limits<double>;
+      /// Property: Intrinsic energy resolution constant (gaussian ~ std::sqrt(energy))
+      double m_resolution_time                { 0e0 };
+      /// Property: Time window within the smeared deposits shall be accepted
+      std::pair<double, double> m_window_time { limit_t::min(), limit_t::max() };
+      /// Property: Flag to update existing container in-place or create a new container
+      bool   m_update_in_place                { true };
+
+    public:
+      /// Standard constructor
+      DigiDepositSmearTime(const DigiKernel& krnl, const std::string& nam)
+	: DigiContainerProcessor(krnl, nam)
+      {
+	declareProperty("resolution_time", m_resolution_time);
+	declareProperty("window_time",     m_window_time);
+	InstanceCount::increment(this);
+      }
+
+      /// Default destructor
+      virtual ~DigiDepositSmearTime() {
+	InstanceCount::decrement(this);
+      }
+
+      /// Create deposit mapping with updates on same cellIDs
+      template <typename T> void
+      smear(DigiContext& context, T& cont, work_t& work, const predicate_t& predicate)  const  {
+	auto& random = context.randomGenerator();
+	T output_cont(cont.name, work.output.mask);
+	std::size_t killed  = 0UL;
+	std::size_t updated = 0UL;
+	std::size_t created = 0UL;
+
+	info("%s+++ TIME smearing deposit container: %s %6ld entries",
+	     context.event->id(), cont.name.c_str(), cont.size());
+	for( auto& dep : cont )    {
+	  if ( predicate(dep) )   {
+	    int flag = EnergyDeposit::TIME_SMEARED;
+	    double delta_T = m_resolution_time * random.gaussian();
+	    if ( delta_T < m_window_time.first || delta_T > m_window_time.second )   {
+	      flag |= EnergyDeposit::KILLED;
+	      ++killed;
+	    }
+	    if ( m_update_in_place )   {
+	      EnergyDeposit& d = dep.second;
+	      d.time += delta_T;
+	      d.flag |= flag;
+	      ++updated;
+	    }
+	    else if ( !(flag&EnergyDeposit::KILLED) )  {
+	      EnergyDeposit d(dep.second);
+	      d.time += delta_T;
+	      d.flag |= flag;
+	      output_cont.emplace(dep.first, std::move(d));
+	      ++created;
+	    }
+	  }
+	}
+	if ( !m_update_in_place )   {
+	  work.output.data.put(output_cont.key, std::move(output_cont));
+	}
+	info("%s+++ %-32s Smearing: created %6ld updated %6ld killed %6ld entries from mask: %04X",
+	     context.event->id(), cont.name.c_str(), created, updated, killed, cont.key.mask());
+      }
+
+      /// Main functional callback
+      virtual void execute(DigiContext& context, work_t& work, const predicate_t& predicate)  const override final  {
+	if ( auto* v = work.get_input<DepositVector>() )
+	  smear(context, *v, work, predicate);
+	else if ( auto* m = work.get_input<DepositMapping>() )
+	  smear(context, *m, work, predicate);
+	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,DigiDepositSmearTime)
diff --git a/DDDigi/plugins/DigiDepositWeightedPosition.cpp b/DDDigi/plugins/DigiDepositWeightedPosition.cpp
index 7de2ee4e716028c082667cf8db72157d8929ef91..4bde23c5af4449c5ca588e6398b4f18018db8bba 100644
--- a/DDDigi/plugins/DigiDepositWeightedPosition.cpp
+++ b/DDDigi/plugins/DigiDepositWeightedPosition.cpp
@@ -54,22 +54,25 @@ namespace dd4hep {
       }
 
       /// Create deposit mapping with updates on same cellIDs
-      template <typename T> void create_deposits(const char* tag, const T& cont, work_t& work)  const  {
+      template <typename T> void
+      create_deposits(const char* tag, const T& cont, work_t& work, const predicate_t& predicate)  const  {
 	Key key(cont.name, work.output.mask);
 	DepositMapping m(cont.name, work.output.mask);
 	std::size_t dropped = 0UL, updated = 0UL, added = 0UL;
 	for( const auto& dep : cont )    {
-	  const EnergyDeposit& depo = dep.second;
-	  if ( depo.deposit >= m_cutoff )   {
-	    CellID cell = dep.first;
-	    auto   iter = m.data.find(cell);
-	    if ( iter == m.data.end() )
-	      m.data.emplace(dep.first, depo), ++added;
-	    else
-	      iter->second.update_deposit_weighted(depo), ++updated;
-	    continue;
+	  if ( predicate(dep) )   {
+	    const EnergyDeposit& depo = dep.second;
+	    if ( depo.deposit >= m_cutoff )   {
+	      CellID cell = dep.first;
+	      auto   iter = m.data.find(cell);
+	      if ( iter == m.data.end() )
+		m.data.emplace(dep.first, depo), ++added;
+	      else
+		iter->second.update_deposit_weighted(depo), ++updated;
+	      continue;
+	    }
+	    ++dropped;
 	  }
-	  ++dropped;
 	}
 	info("%s+++ %-32s added %6ld updated %6ld dropped %6ld entries (now: %6ld) from mask: %04X to mask: %04X",
 	     tag, cont.name.c_str(), added, updated, dropped, m.size(), cont.key.mask(), m.key.mask());
@@ -77,11 +80,11 @@ namespace dd4hep {
       }
 
       /// Main functional callback
-      virtual void execute(DigiContext& context, work_t& work)  const override final  {
+      virtual void execute(DigiContext& context, work_t& work, const predicate_t& predicate)  const override final  {
 	if ( const auto* v = work.get_input<DepositVector>() )
-	  create_deposits(context.event->id(), *v, work);
+	  create_deposits(context.event->id(), *v, work, predicate);
 	else if ( const auto* m = work.get_input<DepositMapping>() )
-	  create_deposits(context.event->id(), *m, work);
+	  create_deposits(context.event->id(), *m, work, predicate);
 	else
 	  except("%s+++ Request to handle unknown data type: %s", 
 		 context.event->id(), work.input_type_name().c_str());
diff --git a/DDDigi/plugins/DigiHitHistoryDrop.cpp b/DDDigi/plugins/DigiHitHistoryDrop.cpp
index 652129098a2027e16a894e715e2e93f485154d64..5b3c663dc064e47c7f1b786c4e39b568e1e1ea9d 100644
--- a/DDDigi/plugins/DigiHitHistoryDrop.cpp
+++ b/DDDigi/plugins/DigiHitHistoryDrop.cpp
@@ -63,8 +63,8 @@ namespace dd4hep {
       std::pair<std::size_t, std::size_t> drop_history(T& cont)  const  {
 	std::size_t num_drop_hit = 0;
 	std::size_t num_drop_particle = 0;
-	for( auto& c : cont )    {
-	  auto ret = c.second.history.drop();
+	for( auto& dep : cont )    {
+	  auto ret = dep.second.history.drop();
 	  num_drop_hit += ret.first;
 	  num_drop_particle += ret.second;
 	}
@@ -76,16 +76,16 @@ namespace dd4hep {
 	auto& inputs = context.event->get_segment(m_input);
 	std::size_t num_drop_hit = 0;
 	std::size_t num_drop_particle = 0;
-	for ( auto& i : inputs )     {
+	for( auto& i : inputs )     {
 	  Key key(i.first);
 	  auto im = std::find(m_masks.begin(), m_masks.end(), key.mask());
-	  if ( im != m_masks.end() )   {
-	    if ( DepositMapping* m = std::any_cast<DepositMapping>(&i.second) )    {
+	  if( im != m_masks.end() )   {
+	    if( DepositMapping* m = std::any_cast<DepositMapping>(&i.second) )    {
 	      auto ret = drop_history(*m);
 	      num_drop_hit += ret.first;
 	      num_drop_particle += ret.second;
 	    }
-	    if ( DepositVector* m = std::any_cast<DepositVector>(&i.second) )    {
+	    if( DepositVector* m = std::any_cast<DepositVector>(&i.second) )    {
 	      auto ret = drop_history(*m);
 	      num_drop_hit += ret.first;
 	      num_drop_particle += ret.second;
diff --git a/DDDigi/plugins/DigiIPMover.cpp b/DDDigi/plugins/DigiIPMover.cpp
index 0aa07c56e22560eed083a7bd3c75fb1f65c108f1..804089bf03ba8a329f039d869b7152aaa83a4606 100644
--- a/DDDigi/plugins/DigiIPMover.cpp
+++ b/DDDigi/plugins/DigiIPMover.cpp
@@ -11,14 +11,16 @@
 //
 //==========================================================================
 
-// Framework include files
+/// Framework include files
 #include <DDDigi/DigiData.h>
 #include <DDDigi/DigiContainerProcessor.h>
 
+/// C/C++ include files
 #include <iostream>
 
 /// Namespace for the AIDA detector description toolkit
 namespace dd4hep {
+  
   /// Namespace for the Digitization part of the AIDA detector description toolkit
   namespace digi {
 
@@ -32,21 +34,29 @@ namespace dd4hep {
      */
     class DigiIPMover : public DigiContainerProcessor  {
     public:
+
       /// Standard constructor
       DigiIPMover(const DigiKernel& krnl, const std::string& nam)
 	: DigiContainerProcessor(krnl, nam)
       {
       }
+
       /// Move IP location of deposits
-      template <typename T> std::size_t move_deposits(const char* tag, T& cont, const Position& delta)  const  {
+      template <typename DEPOSITS> std::size_t
+      move_deposits(const char* tag, DEPOSITS& cont, const Position& delta, const predicate_t& predicate)  const  {
 	info("%s+++ %-32s [%6ld] IP: x:%7.3f y:%7.3f z:%7.3f", 
 	     tag, cont.name.c_str(), cont.size(), delta.X(), delta.Y(), delta.Z());
-	for( auto& dep : cont )
-	  dep.second.position += delta;
+	for( auto& dep : cont )   {
+	  if( predicate(dep) )   {
+	    dep.second.position += delta;
+	  }
+	}
 	return cont.size();
       }
+
       /// Move IP location of MC particles
-      template <typename T> std::size_t move_particles(const char* tag, T& cont, const Position& delta)  const  {
+      template <typename PARTICLES> std::size_t
+      move_particles(const char* tag, PARTICLES& cont, const Position& delta)  const  {
 	info("%s+++ %-32s [%6ld] IP: x:%7.3f y:%7.3f z:%7.3f", 
 	     tag, cont.name.c_str(), cont.size(), delta.X(), delta.Y(), delta.Z());
 	for( auto& p : cont )   {
@@ -56,14 +66,15 @@ namespace dd4hep {
 	}
 	return cont.size();
       }
+
       /// Main functional callback
-      virtual void execute(DigiContext& context, work_t& work)  const  override  {
+      virtual void execute(DigiContext& context, work_t& work, const predicate_t& predicate)  const  override  {
 	const char* tag = context.event->id();
 	Position  delta = property("interaction_point").value<Position>();
 	if ( auto* m = work.get_input<DepositMapping>() )
-	  move_deposits(tag, *m, delta);
+	  move_deposits(tag, *m, delta, predicate);
 	else if ( auto* v = work.get_input<DepositVector>() )
-	  move_deposits(tag, *v, delta);
+	  move_deposits(tag, *v, delta, predicate);
 	else if ( auto* p = work.get_input<ParticleMapping>() )
 	  move_particles(tag, *p, delta);
 	else
diff --git a/DDDigi/plugins/DigiResegment.cpp b/DDDigi/plugins/DigiResegment.cpp
index e70ac5eb741161f77d8f96f062ed19ae37b1f22c..c34298d75cb7a77755aef287710a4db3eb4c53f2 100644
--- a/DDDigi/plugins/DigiResegment.cpp
+++ b/DDDigi/plugins/DigiResegment.cpp
@@ -103,35 +103,38 @@ namespace dd4hep {
 	info("+++ Successfully initialized resegmentation action.");
       }
 
-      template <typename T> void resegment_deposits(const T& cont, work_t& work)  const  {
+      template <typename T> void
+      resegment_deposits(const T& cont, work_t& work, const predicate_t& predicate)  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()
-		   );
+	  if( predicate(dep) )   {
+	    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));
 	    }
-	    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();
@@ -141,11 +144,11 @@ namespace dd4hep {
       }
 
       /// Main functional callback
-      virtual void execute(DigiContext&, work_t& work)  const override final  {
+      virtual void execute(DigiContext&, work_t& work, const predicate_t& predicate)  const override final  {
 	if ( const auto* m = work.get_input<DepositMapping>() )
-	  resegment_deposits(*m, work);
+	  resegment_deposits(*m, work, predicate);
 	else if ( const auto* v = work.get_input<DepositVector>() )
-	  resegment_deposits(*v, work);
+	  resegment_deposits(*v, work, predicate);
 	else
 	  except("Request to handle unknown data type: %s", work.input_type_name().c_str());
       }
diff --git a/DDDigi/plugins/DigiSegmentDepositExtractor.cpp b/DDDigi/plugins/DigiSegmentDepositExtractor.cpp
index 7ee93ee136647773d4148e5f562467c22e7a1d29..48c81e463c7899cf84b0664e3211c493cb81f138 100644
--- a/DDDigi/plugins/DigiSegmentDepositExtractor.cpp
+++ b/DDDigi/plugins/DigiSegmentDepositExtractor.cpp
@@ -13,7 +13,7 @@
 
 // Framework include files
 #include <DDDigi/DigiContext.h>
-#include <DDDigi/DigiSegmentProcessor.h>
+#include <DDDigi/DigiContainerProcessor.h>
 
 /// Namespace for the AIDA detector description toolkit
 namespace dd4hep {
@@ -30,31 +30,31 @@ namespace dd4hep {
      *  \version 1.0
      *  \ingroup DD4HEP_DIGITIZATION
      */
-    class DigiSegmentDepositExtractor : public DigiSegmentProcessor   {
+    class DigiSegmentDepositExtractor : public DigiContainerProcessor   {
     public:
       /// Standard constructor
       DigiSegmentDepositExtractor(const DigiKernel& kernel, const std::string& nam)
-	: DigiSegmentProcessor(kernel, nam) {}
+	: DigiContainerProcessor(kernel, nam) {}
 
-      template <typename T> void copy_deposits(const T& cont, work_t& work)  const  {
+      template <typename T> void copy_deposits(const T& cont, work_t& work, const predicate_t& predicate)  const  {
 	DepositVector deposits(cont.name, work.output.mask);
 	for( const auto& dep : cont )   {
-	  CellID        cell = dep.first;
-	  EnergyDeposit depo = dep.second;
-	  deposits.data.emplace_back(cell, std::move(depo));
+	  if( predicate(dep) )   {
+	    CellID        cell = dep.first;
+	    EnergyDeposit depo = dep.second;
+	    deposits.data.emplace_back(cell, std::move(depo));
+	  }
 	}
         work.output.data.put(deposits.key, std::move(deposits));
       }
       /// Main functional callback
-      virtual void execute(DigiContext&, work_t& work)  const override final  {
-	if ( segment.matches(work.input.key.value()) )   {
-	  if ( const auto* m = work.get_input<DepositMapping>() )
-	    copy_deposits(*m, work);
-	  else if ( const auto* v = work.get_input<DepositVector>() )
-	    copy_deposits(*v, work);
-	  else
-	    except("Request to handle unknown data type: %s", work.input_type_name().c_str());
-	}
+      virtual void execute(DigiContext&, work_t& work, const predicate_t& predicate)  const override final  {
+	if ( const auto* m = work.get_input<DepositMapping>() )
+	  copy_deposits(*m, work, predicate);
+	else if ( const auto* v = work.get_input<DepositVector>() )
+	  copy_deposits(*v, work, predicate);
+	else
+	  except("Request to handle unknown data type: %s", work.input_type_name().c_str());
       }
     };
   }    // End namespace digi
diff --git a/DDDigi/plugins/DigiSegmentDepositPrint.cpp b/DDDigi/plugins/DigiSegmentDepositPrint.cpp
index a97281da960e58fdd975978c241aed403b31ec0a..db28f56d0dcc3bdccc8eccfa4f8d7d18820a68e1 100644
--- a/DDDigi/plugins/DigiSegmentDepositPrint.cpp
+++ b/DDDigi/plugins/DigiSegmentDepositPrint.cpp
@@ -13,10 +13,12 @@
 
 // Framework include files
 #include <DDDigi/DigiContext.h>
-#include <DDDigi/DigiSegmentProcessor.h>
+#include <DDDigi/DigiSegmentSplitter.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 {
 
@@ -27,33 +29,38 @@ namespace dd4hep {
      *  \version 1.0
      *  \ingroup DD4HEP_SIMULATION
      */
-    class DigiSegmentDepositPrint : public DigiSegmentProcessor   {
+    class DigiSegmentDepositPrint : public DigiContainerProcessor   {
     public:
       /// Standard constructor
       DigiSegmentDepositPrint(const DigiKernel& kernel, const std::string& nam)
-	: DigiSegmentProcessor(kernel, nam) {}
+	: DigiContainerProcessor(kernel, nam) {}
 
       /// Single container printout
-      template <typename T> void print_deposits(const char* fmt, const T& cont)  const   {
-	for(const auto& dep : cont)   {
-	  if( this->segment.matches(dep.first) )   {
-	    info(fmt, segment.split_id(dep.first), dep.first,
+      template <typename T> void
+      print(const char* fmt, const T& cont, const predicate_t& predicate)  const   {
+	for( const auto& dep : cont )   {
+	  if( predicate(dep) )   {
+	    info(fmt, predicate.segmentation.split_id(dep.first), dep.first,
 		 dep.second.history.hits.size(), 
 		 dep.second.history.particles.size(),
 		 dep.second.deposit);
 	  }
 	}
       }
+
       /// Main functional callback
-      virtual void execute(DigiContext& context, work_t& work)  const override final  {
+      virtual void execute(DigiContext& context, work_t& work, const predicate_t& predicate)  const override final  {
 	char format[256];
 	::snprintf(format, sizeof(format), 
-		   "%s[%s] %s-id: %%d [processor:%d] Cell: %%016lX mask: %016lX  hist:%%4ld hits %%4ld parts. entries deposit: %%f", 
-		   context.event->id(), segment.idspec.name(), segment.cname(), segment.id, segment.split_mask);
+		   "%s[%s] %s-id: %%d [processor:%d] Cell: %%016lX mask: %016lX  "
+		   "hist:%%4ld hits %%4ld parts. entries deposit: %%f", 
+		   context.event->id(),
+		   predicate.segmentation.idspec.name(), predicate.segmentation.cname(),
+		   predicate.segmentation.id, predicate.segmentation.split_mask);
 	if ( const auto* m = work.get_input<DepositMapping>() )
-	  print_deposits(format, *m);
+	  print(format, *m, predicate);
 	else if ( const auto* v = work.get_input<DepositVector>() )
-	  print_deposits(format, *v);
+	  print(format, *v, predicate);
 	else
 	  error("+++ Request to dump an invalid container %s", Key::key_name(work.input.key).c_str());
       }
diff --git a/DDDigi/plugins/DigiSimpleADCResponse.cpp b/DDDigi/plugins/DigiSimpleADCResponse.cpp
index 540901261a7b54192a8e02f325c667e9e4afc99f..5f5c52cec1106a36a4864f752cb658c51f227794 100644
--- a/DDDigi/plugins/DigiSimpleADCResponse.cpp
+++ b/DDDigi/plugins/DigiSimpleADCResponse.cpp
@@ -12,7 +12,8 @@
 //==========================================================================
 
 // Framework include files
-#include <DDDigi/DigiSegmentProcessor.h>
+#include <DDDigi/DigiContainerProcessor.h>
+#include <DDDigi/DigiSegmentSplitter.h>
 
 /// C/C++ include files
 #include <cmath>
@@ -23,19 +24,20 @@ namespace dd4hep {
   /// Namespace for the Digitization part of the AIDA detector description toolkit
   namespace digi {
 
-    class DigiSimpleADCResponse : public DigiSegmentProcessor  {
-      std::string m_response_postfix   { ".adc" };
-      std::string m_history_postfix    { ".hist" };
-      double      m_use_segmentation   { false  };
-      double      m_signal_cutoff      { std::numeric_limits<double>::epsilon() };
-      double      m_signal_saturation  { std::numeric_limits<double>::max() };
-      double      m_adc_offset         { 0e0  };
-      std::size_t m_adc_resolution     { 1024 };
-
-    public:
+    class DigiSimpleADCResponse : public DigiContainerProcessor  {
+      using segmentation_t = DigiSegmentProcessContext;
+      std::string    m_response_postfix   { ".adc" };
+      std::string    m_history_postfix    { ".hist" };
+      double         m_use_segmentation   { false  };
+      double         m_signal_cutoff      { std::numeric_limits<double>::epsilon() };
+      double         m_signal_saturation  { std::numeric_limits<double>::max() };
+      double         m_adc_offset         { 0e0  };
+      std::size_t    m_adc_resolution     { 1024 };
+      
+      public:
       /// Standard constructor
       DigiSimpleADCResponse(const DigiKernel& krnl, const std::string& nam)
-	: DigiSegmentProcessor(krnl, nam)
+	: DigiContainerProcessor(krnl, nam)
       {
 	declareProperty("cutoff",           m_signal_cutoff);
 	declareProperty("saturation",       m_signal_saturation);
@@ -46,8 +48,8 @@ namespace dd4hep {
 
       /// Create container with ADC counts and register it to the output segment
       template <typename T, typename P>
-      void create_adc_counts(const char* tag, const T& input, work_t& work, const P& predicate)  const  {
-	std::string postfix = m_use_segmentation ? "."+segment.identifier() : std::string();
+      void emulate_adc(const char* tag, const T& input, work_t& work, const P& predicate)  const  {
+	std::string postfix = m_use_segmentation ? "."+predicate.segmentation.identifier() : std::string();
 	std::string history_name  = input.name + postfix + m_history_postfix;
 	std::string response_name = input.name + postfix + m_response_postfix;
 	DetectorHistory  history (history_name, work.output.mask);
@@ -68,24 +70,26 @@ namespace dd4hep {
         work.output.data.put(response.key, std::move(response));
         work.output.data.put(history.key,  std::move(history));
       }
+
       /// Create container with ADC counts and register it to the output segment
       template <typename P>
-      void create_adc_counts(DigiContext& context, work_t& work, const P& predicate)  const  {
+      void emulate_adc(DigiContext& context, work_t& work, const P& predicate)  const  {
 	const char* tag = context.event->id();
 	if ( const auto* m = work.get_input<DepositMapping>() )
-	  create_adc_counts(tag, *m, work, predicate);
+	  emulate_adc(tag, *m, work, predicate);
 	else if ( const auto* v = work.get_input<DepositVector>() )
-	  create_adc_counts(tag, *v, work, predicate);
+	  emulate_adc(tag, *v, work, predicate);
 	else
 	  except("%s+++ Request to handle unknown data type: %s",
 		 tag, work.input_type_name().c_str());
       }
+
       /// Main functional callback
-      virtual void execute(DigiContext& context, work_t& work)  const override final  {
+      virtual void execute(DigiContext& context, work_t& work, const predicate_t& predicate)  const final  {
 	if ( !m_use_segmentation )
-	  create_adc_counts(context, work, accept_all_t());
-	else if ( segment.matches(work.input.key.value()) )
-	  create_adc_counts(context, work, accept_segment_t(segment));
+	  emulate_adc(context, work, accept_all());
+	else if ( predicate.segmentation.matches(work.input.key.value()) )
+	  emulate_adc(context, work, accept_segment_t(predicate.segmentation));
       }
     };
   }    // End namespace digi
diff --git a/DDDigi/python/DDDigiDict.C b/DDDigi/python/DDDigiDict.C
index 7458ef7a9bde75795cb21e512ece78c447937c73..56b77864a307bd4254354c302d8f20bd174caae6 100644
--- a/DDDigi/python/DDDigiDict.C
+++ b/DDDigi/python/DDDigiDict.C
@@ -191,7 +191,6 @@ namespace dd4hep {
 #include <DDDigi/DigiSynchronize.h>
 #include <DDDigi/DigiInputAction.h>
 #include <DDDigi/DigiSegmentSplitter.h>
-#include <DDDigi/DigiSegmentProcessor.h>
 #include <DDDigi/DigiActionSequence.h>
 #include <DDDigi/DigiSignalProcessor.h>
 
@@ -225,8 +224,6 @@ using namespace std;
 #pragma link C++ class dd4hep::digi::DigiContainerSequenceAction;
 #pragma link C++ class dd4hep::digi::DigiMultiContainerProcessor;
 
-#pragma link C++ class dd4hep::digi::DigiSegmentProcessor;
-#pragma link C++ class dd4hep::digi::DigiSegmentSequence;
 #pragma link C++ class dd4hep::digi::DigiSegmentSplitter;
 
 /// Digi data item wrappers
diff --git a/DDDigi/python/dddigi.py b/DDDigi/python/dddigi.py
index 87b582e3ad7f26382d33480307586e0136828f19..8f7b02ebaac642bb212184b996463f7dcc2bde64 100644
--- a/DDDigi/python/dddigi.py
+++ b/DDDigi/python/dddigi.py
@@ -243,11 +243,19 @@ def _adopt_event_action(self, action):
 # ---------------------------------------------------------------------------
 
 
-def _adopt_container_processor(self, action, container):
+def _adopt_container_processor(self, action, processor_argument):
   " Helper to convert DigiActions objects to DigiEventAction "
   attr = getattr(_get_action(self), 'adopt_processor')
   proc = Interface.toContainerProcessor(_get_action(action))
-  attr(proc, container)
+  attr(proc, processor_argument)
+# ---------------------------------------------------------------------------
+
+
+def _adopt_segment_processor(self, action, processor_argument):
+  " Helper to convert DigiActions objects to DigiEventAction "
+  attr = getattr(_get_action(self), '__adopt_segment_processor')
+  proc = Interface.toContainerProcessor(_get_action(action))
+  attr(proc, processor_argument)
 # ---------------------------------------------------------------------------
 
 
@@ -301,8 +309,12 @@ def _props(obj, **extensions):
   cls = getattr(current, obj)
   for extension in extensions.items():
     call = extension[0]
+    # print('TRY: Overloading: '+str(cls)+' '+call+' to __'+call+' '+str(hasattr(cls, call)))
     if hasattr(cls, call):
+      # print('Overloading: '+str(cls)+' '+call+' to __'+call)
       setattr(cls, '__' + call, getattr(cls, call))
+    else:
+      print('FAILED: Overloading: '+str(cls)+' '+call+' to __'+call+' '+str(hasattr(cls, call)))
     setattr(cls, call, extension[1])
   cls.__getattr__ = _get
   cls.__setattr__ = _set
@@ -333,6 +345,7 @@ _props('DigiParallelActionSequence', adopt_action=_adopt_sequence_action)
 _props('DigiSequentialActionSequence', adopt_action=_adopt_sequence_action)
 _props('DigiContainerSequenceAction', adopt_container_processor=_adopt_container_processor)
 _props('DigiMultiContainerProcessor', adopt_processor=_adopt_processor)
+_props('DigiSegmentSplitter', adopt_segment_processor=_adopt_segment_processor)
 #
 # Need to import digitize late, since it cross includes dddigi
 Digitize = None
diff --git a/DDDigi/src/DigiAttenuator.cpp b/DDDigi/src/DigiAttenuator.cpp
index 42f4746f38983b00a914d8e0d5dbdb44bbecbfe1..df9c9a12e3d984b9f105b75d2fa3c6d27e31dc90 100644
--- a/DDDigi/src/DigiAttenuator.cpp
+++ b/DDDigi/src/DigiAttenuator.cpp
@@ -43,23 +43,26 @@ DigiAttenuator::~DigiAttenuator() {
 }
 
 /// Attenuator callback for single container
-template <typename T> std::size_t DigiAttenuator::attenuate(T& cont) const {
-  for( auto& c : cont )   {
-    auto& depo = c.second;
-    depo.deposit *= m_factor;
-    for( auto& h : depo.history.hits ) h.weight *= m_factor;
-    for( auto& h : depo.history.particles ) h.weight *= m_factor;
+template <typename T> std::size_t
+DigiAttenuator::attenuate(T& cont, const predicate_t& predicate) const {
+  for( auto& dep : cont )   {
+    if ( predicate(dep) )   {
+      auto& depo = dep.second;
+      depo.deposit *= m_factor;
+      for( auto& h : depo.history.hits ) h.weight *= m_factor;
+      for( auto& h : depo.history.particles ) h.weight *= m_factor;
+    }
   }
   return cont.size();
 }
 
 /// Main functional callback adapter
-void DigiAttenuator::execute(DigiContext& context, work_t& work)  const   {
+void DigiAttenuator::execute(DigiContext& context, work_t& work, const predicate_t& predicate)  const   {
   std::size_t count = 0;
   if ( auto* m = work.get_input<DepositMapping>() )
-    count = this->attenuate(*m);
+    count = this->attenuate(*m, predicate);
   else if ( auto* v = work.get_input<DepositVector>() )
-    count = this->attenuate(*v);
+    count = this->attenuate(*v, predicate);
   Key key { work.input.key };
   std::string nam = Key::key_name(key)+":";
   info("%s+++ %-32s mask:%04X item: %08X Attenuated %6ld hits by %8.5f",
diff --git a/DDDigi/src/DigiContainerProcessor.cpp b/DDDigi/src/DigiContainerProcessor.cpp
index df186c91bd84893aef2a624f61a754a41f016f90..040a7731b44e47a5d0a69706027ab8636bcd52d9 100644
--- a/DDDigi/src/DigiContainerProcessor.cpp
+++ b/DDDigi/src/DigiContainerProcessor.cpp
@@ -17,6 +17,7 @@
 #include <DDDigi/DigiKernel.h>
 #include <DDDigi/DigiContext.h>
 #include <DDDigi/DigiContainerProcessor.h>
+#include <DDDigi/DigiSegmentSplitter.h>
 
 /// C/C++ include files
 #include <sstream>
@@ -78,6 +79,25 @@ std::string DigiContainerProcessor::work_t::input_type_name()  const   {
   return typeName(input.data.type());
 }
 
+/// Access to default callback 
+const DigiContainerProcessor::predicate_t& DigiContainerProcessor::accept_all()  {
+  struct true_t  {
+    bool use(const std::pair<const CellID, EnergyDeposit>&)  const {
+      return true;
+    }
+  };
+  static true_t s_y { };
+  static segmentation_t s_seg {};
+  static predicate_t   s_true { Callback(&s_y).make(&true_t::use), s_seg };
+  return s_true;
+}
+
+/// Check if a deposit should be processed
+bool DigiContainerProcessor::predicate_t::operator()(const std::pair<const CellID, EnergyDeposit>& deposit)   const   {
+  const void* args[] = { &deposit };
+  return this->callback.execute(args);
+}
+
 /// Standard constructor
 DigiContainerProcessor::DigiContainerProcessor(const DigiKernel& kernel, const std::string& name)   
   : DigiAction(kernel, name)
@@ -90,15 +110,10 @@ DigiContainerProcessor::~DigiContainerProcessor() {
   InstanceCount::decrement(this);
 }
 
-/// Main functional callback 
-void DigiContainerProcessor::execute(DigiContext& context, work_t& work)  const  {
-  this->execute(context, work.input.key, work.input.data);
-}
-
 /// Main functional callback if specific work is known
-void DigiContainerProcessor::execute(DigiContext& context, Key key, std::any& /* data */)  const    {
-  info("%s+++ %p Using container: %016lX  --> %04X %08X %s",
-       context.event->id(), (void*)this, key.value(), key.mask(), key.item(), Key::key_name(key).c_str());
+void DigiContainerProcessor::execute(DigiContext&       /* context   */,
+				     work_t&            /* work      */,
+				     const predicate_t& /* predicate */)  const   {
 }
 
 /// Standard constructor
@@ -124,8 +139,9 @@ 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(context, m_workers.get_group(), m_workers.size(), &work, m_parallel);
+void DigiContainerSequence::execute(DigiContext& context, work_t& work, const predicate_t& /* predicate */)  const   {
+  auto group = m_workers.get_group();
+  m_kernel.submit(context, group, m_workers.size(), &work, m_parallel);
 }
 
 /// Worker adaptor for caller DigiContainerSequence
@@ -133,7 +149,7 @@ template <> void DigiParallelWorker<DigiContainerProcessor,
 				    DigiContainerSequence::work_t,
 				    std::size_t>::execute(void* data) const  {
   calldata_t* args  = reinterpret_cast<calldata_t*>(data);
-  action->execute(args->context, *args);
+  action->execute(args->context, *args, action->accept_all());
 }
 
 /// Standard constructor
@@ -242,7 +258,7 @@ template <> void DigiParallelWorker<DigiContainerProcessor,
   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, args->properties};
-  action->execute(args->context, work);
+  action->execute(args->context, work, action->accept_all());
 }
 
 /// Standard constructor
@@ -373,12 +389,12 @@ template <> void DigiParallelWorker<DigiContainerProcessor,
       tag = "mask accepted";
       if ( keys.empty() )  {
 	DigiContainerProcessor::work_t  work {arg->context, {key, *item.second }, arg->output, arg->properties };
-	action->execute(work.context, work);
+	action->execute(work.context, work, action->accept_all());
 	continue;
       }
       else if ( std::find(keys.begin(), keys.end(), key) != keys.end() )    {
 	DigiContainerProcessor::work_t  work {arg->context, {key, *item.second }, arg->output, arg->properties };
-	action->execute(work.context, work);
+	action->execute(work.context, work, action->accept_all());
 	continue;
       }
       tag = "no keys matching";
diff --git a/DDDigi/src/DigiHandle.cpp b/DDDigi/src/DigiHandle.cpp
index 64aefbab59217828a77bcd755a13c4564999b6c4..1099d011d975f2741a0e9e615d60c79b26370ec5 100644
--- a/DDDigi/src/DigiHandle.cpp
+++ b/DDDigi/src/DigiHandle.cpp
@@ -20,7 +20,6 @@
 #include <DDDigi/DigiKernel.h>
 #include <DDDigi/DigiInputAction.h>
 #include <DDDigi/DigiEventAction.h>
-#include <DDDigi/DigiSegmentProcessor.h>
 #include <DDDigi/DigiSignalProcessor.h>
 
 // C/C++ include files
@@ -69,10 +68,6 @@ namespace dd4hep {
       return PluginService::Create<DigiAction*>(t, &kernel, n);
     }
 
-    template <> DigiSegmentProcessor* _raw_create<DigiSegmentProcessor>(const std::string& t, const DigiKernel& kernel, const std::string& n)    {
-      return PluginService::Create<DigiSegmentProcessor*>(t, &kernel, n);
-    }
-
     template <> DigiSignalProcessor* _raw_create<DigiSignalProcessor>(const std::string& t, const DigiKernel& kernel, const std::string& n)    {
       return PluginService::Create<DigiSignalProcessor*>(t, &kernel, n);
     }
@@ -202,7 +197,6 @@ namespace dd4hep {
     template class DigiHandle<DigiAction>;
     template class DigiHandle<DigiInputAction>;
     template class DigiHandle<DigiEventAction>;
-    template class DigiHandle<DigiSegmentProcessor>;
     template class DigiHandle<DigiSynchronize>;
     template class DigiHandle<DigiActionSequence>;
     template class DigiHandle<DigiSignalProcessor>;
diff --git a/DDDigi/src/DigiSegmentProcessor.cpp b/DDDigi/src/DigiSegmentProcessor.cpp
deleted file mode 100644
index 9ce3a2e120f28bca87700d616d1ced13b52d2848..0000000000000000000000000000000000000000
--- a/DDDigi/src/DigiSegmentProcessor.cpp
+++ /dev/null
@@ -1,74 +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/DigiKernel.h>
-#include <DDDigi/DigiSegmentProcessor.h>
-
-using namespace dd4hep::digi;
-
-/// Standard constructor
-DigiSegmentProcessor::DigiSegmentProcessor(const DigiKernel& krnl, const std::string& nam)
-  : DigiContainerProcessor(krnl, nam)
-{
-  InstanceCount::increment(this);
-}
-
-/// Default destructor
-DigiSegmentProcessor::~DigiSegmentProcessor() {
-  InstanceCount::decrement(this);
-}
-
-/// Main functional callback if specific work is known
-void DigiSegmentProcessor::execute(DigiContext& /* context */, work_t& /* args */)  const   {
-}
-
-template <> void DigiParallelWorker<DigiSegmentProcessor,
-				    DigiSegmentSequence::work_t,
-				    dd4hep::VolumeID>::execute(void* args) const  {
-  calldata_t* work = reinterpret_cast<calldata_t*>(args);
-  action->execute(work->context, *work);
-}
-
-/// Standard constructor
-DigiSegmentSequence::DigiSegmentSequence(const DigiKernel& krnl, const std::string& nam)
-  : DigiSegmentProcessor(krnl, nam)
-{
-  InstanceCount::increment(this);
-}
-
-/// Default destructor
-DigiSegmentSequence::~DigiSegmentSequence() {
-  InstanceCount::decrement(this);
-}
-
-/// Adopt new parallel worker
-void DigiSegmentSequence::adopt_processor(DigiContainerProcessor* action)   {
-  if ( !action )  {
-    except("+++ FAILED: attempt to add invalid processor!");
-  }
-  auto* proc = dynamic_cast<DigiSegmentProcessor*>(action);
-  if ( !proc )   {
-    error("+++ FAILED: Attempt to add processor %s of type %s",
-	  action->c_name(), typeName(typeid(*action)).c_str());
-    except("+++ DigiSegmentSplitter do ONLY accept processors of type DigiSegmentProcessor!");
-  }
-  proc->segment = segment;
-  m_workers.insert(new worker_t(proc, proc->segment.id));
-}
-
-/// Main functional callback
-void DigiSegmentSequence::execute(DigiContext& context, work_t& work) const {
-  m_kernel.submit(context, m_workers.get_group(), m_workers.size(), &work, m_parallel);
-}
diff --git a/DDDigi/src/DigiSegmentSplitter.cpp b/DDDigi/src/DigiSegmentSplitter.cpp
index 8b22c28c7db107a843b2cead53b125e34c36aa81..4944c8c63368b65e43b34790c77c1a9463d7e93b 100644
--- a/DDDigi/src/DigiSegmentSplitter.cpp
+++ b/DDDigi/src/DigiSegmentSplitter.cpp
@@ -21,9 +21,39 @@
 
 using namespace dd4hep::digi;
 
+/// Default copy constructor
+DigiSegmentProcessContext::DigiSegmentProcessContext(const DigiSegmentContext& copy)
+  : DigiSegmentContext(copy)
+{
+}
+
+/// Full identifier (field + id)
+std::string DigiSegmentProcessContext::identifier()  const   {
+  std::stringstream str;
+  if ( this->field )   {
+    str << this->field->name() << "." << this->id;
+  }
+  return str.str();
+}
+
+/// Default move assignment
+DigiSegmentProcessContext&
+DigiSegmentProcessContext::operator=(const DigiSegmentContext& copy)   {
+  this->DigiSegmentContext::operator=(copy);
+  return *this;
+}
+
+/// Worker adaptor for caller DigiContainerSequence
+template <> void DigiParallelWorker<DigiContainerProcessor,
+				    DigiContainerProcessor::work_t,
+				    DigiSegmentProcessContext>::execute(void* ptr) const  {
+  calldata_t* args  = reinterpret_cast<calldata_t*>(ptr);
+  action->execute(args->context, *args, this->options.predicate);
+}
+
 /// Standard constructor
 DigiSegmentSplitter::DigiSegmentSplitter(const DigiKernel& kernel, const std::string& nam)
-  : DigiContainerSequence(kernel, nam),
+  : DigiContainerProcessor(kernel, nam),
     m_split_tool(kernel.detectorDescription())
 {
   declareProperty("detector",        m_detector_name);
@@ -70,11 +100,17 @@ void DigiSegmentSplitter::initialize()   {
     for( auto& p : m_splits )   {
       auto split_id = p.second.second;
       bool ok = false;
-      for( const auto* w : workers )   {
-	if ( VolumeID(w->options) == split_id )  { ok = true; break; }
+      for( auto* w : workers )   {
+	if ( w->options.id == split_id )  {
+	  auto& segment    = w->options;
+          segment          = m_split_context;
+	  segment.id       = p.second.second;
+	  ok = true;
+	  break;
+	}
       }
       if ( !ok )   {
-	error("+++ Missing processor for plit ID: %08ld", split_id);
+	error("+++ Missing processor for split ID: %08ld", split_id);
 	bad = true;
       }
     }
@@ -88,37 +124,43 @@ void DigiSegmentSplitter::initialize()   {
   /// IF NOT:
   /// 2) Create the processors using the 'processor_type' option
   for( auto& p : m_splits )   {
-    ::snprintf(text, sizeof(text), "_%05X", m_split_context.split_id(p.first));
+    ::snprintf(text, sizeof(text), "_%05X",
+	       m_split_context.split_id(p.first));
     std::string nam = this->name() + text;
-    auto* proc = createAction<DigiSegmentProcessor>(m_processor_type, m_kernel, nam);
+    auto* proc = createAction<DigiContainerProcessor>(m_processor_type, m_kernel, nam);
     if ( !proc )   {
-      except("+++ Failed to create split worker: %s/%s", m_processor_type.c_str(), nam.c_str());
+      except("+++ Failed to create split worker: %s/%s",
+	     m_processor_type.c_str(), nam.c_str());
     }
-    proc->segment          = m_split_context;
-    proc->segment.detector = p.second.first;
-    proc->segment.id       = p.second.second;
-    m_workers.insert(new worker_t(proc, proc->segment.id));
+    auto* w = new worker_t(proc, m_split_context);
+    auto& segment    = w->options;
+    segment.detector = p.second.first;
+    segment.id       = p.second.second;
+    m_workers.insert(w);
     ++count;
   }
   info("+++ Detector splitter is now fully initialized!");
 }
 
-/// Adopt new parallel worker
-void DigiSegmentSplitter::adopt_processor(DigiContainerProcessor* action)   {
+/// Adopt new parallel worker handling a single split identifier
+void DigiSegmentSplitter::adopt_segment_processor(DigiContainerProcessor* action, int split_id)   {
   if ( !action )  {
     except("+++ FAILED: attempt to add invalid processor!");
   }
-  auto* proc = dynamic_cast<DigiSegmentProcessor*>(action);
-  if ( !proc )   {
-    error("+++ FAILED: Attempt to add processor %s of type %s",
-	  action->c_name(), typeName(typeid(*action)).c_str());
-    except("+++ DigiSegmentSplitter do ONLY accept processors of type DigiSegmentProcessor!");
+  auto* w = new worker_t(action, m_split_context);
+  w->options.id = split_id;
+  m_workers.insert(w);
+}
+
+/// Adopt new parallel worker handling multiple split-identifiers
+void DigiSegmentSplitter::adopt_segment_processor(DigiContainerProcessor* action, const std::vector<int>&  ids)   {
+  for( int split_id : ids )   {
+    adopt_segment_processor(action, split_id);
   }
-  m_workers.insert(new worker_t(proc, m_workers.size()));
 }
 
 /// Main functional callback
-void DigiSegmentSplitter::execute(DigiContext& context, work_t& work)  const    {
+void DigiSegmentSplitter::execute(DigiContext& context, work_t& work, const predicate_t& /* predicate */)  const    {
   Key key = work.input_key();
   Key unmasked_key;
   unmasked_key.set_item(key.item());
diff --git a/DDDigi/src/DigiSegmentationTool.cpp b/DDDigi/src/DigiSegmentationTool.cpp
index a41d92856ce13e7ff9f402c7cddabe34837a31f7..2355590da8bb96b229736febd1252159a609f06e 100644
--- a/DDDigi/src/DigiSegmentationTool.cpp
+++ b/DDDigi/src/DigiSegmentationTool.cpp
@@ -46,19 +46,15 @@ namespace  {
 
 /// Split field name
 const string& DigiSegmentContext::name()  const  {
-  return this->field->name();
+  if ( this->field )  {
+    return this->field->name();
+  }
+  throw std::runtime_error("Invalid field name!");
 }
 
 /// Split field name
 const char* DigiSegmentContext::cname()  const  {
-  return this->field->name().c_str();
-}
-
-/// Full identifier (field + id)
-string DigiSegmentContext::identifier()  const  {
-  std::stringstream str;
-  str << this->field->name() << "." << this->id;
-  return str.str();
+  return this->field ? this->field->name().c_str() : "";
 }
 
 /// Initializing constructor
@@ -185,16 +181,25 @@ DigiSegmentationTool::split_segmentation(const string& split_by)  const
   const auto& ids = this->detector.placement().volIDs();
   VolumeID    vid = this->iddescriptor.encode(ids);
   VolumeID    msk = this->iddescriptor.get_mask(ids);
+  const auto* fld = this->iddescriptor.field(split_by);
   const char* det = this->detector.name();
 
+  if ( !fld )   {
+    except("DigiSegmentationTool","Field discriminator %s does not exist in ID descriptor %s",
+	   split_by.c_str(), this->iddescriptor.name());
+  }
   ::scan_detector(*this, split_by, segmentation_splits, this->detector, vid, msk);
   printout(INFO,"DigiSegmentationTool",
 	   "%-24s has %ld parallel entries when splitting by \"%s\"",
 	   det, segmentation_splits.size(), split_by.c_str());
-  stringstream str;
-  for( const auto& id : segmentation_splits )
-    str << setw(16) << hex << setfill('0') << id.first << " ";
+  stringstream str1, str2;
+  for( const auto& id : segmentation_splits )  {
+    str1 << setw(16) << hex << setfill('0') << id.first << " ";
+    str2 << setw(16) << hex << setfill(' ') << ((id.first&fld->mask())>>fld->offset()) << " ";
+  }
   printout(INFO,"DigiSegmentationTool","%-24s --> Parallel Entries: %s",
-	   det, str.str().c_str());
+	   det, str1.str().c_str());
+  printout(INFO,"DigiSegmentationTool","%-24s --> %-12s ids: %s",
+	   "", split_by.c_str(), str2.str().c_str());
   return segmentation_splits;
 }
diff --git a/DDParsers/include/Parsers/spirit/ParsersFactory.h b/DDParsers/include/Parsers/spirit/ParsersFactory.h
index 95830c06e7b4cf532b2d6284b5b3e81ab1b45e63..0e8fb8f9d1301a0753c90569196dbbe2700221c2 100644
--- a/DDParsers/include/Parsers/spirit/ParsersFactory.h
+++ b/DDParsers/include/Parsers/spirit/ParsersFactory.h
@@ -76,11 +76,19 @@ namespace dd4hep {
 // ============================================================================
 #define PARSERS_DEF_FOR_SINGLE(Type)                                    \
   namespace dd4hep  {                                                   \
-  namespace Parsers  {                                                  \
-    template <> int parse(Type& result, const std::string& input)       \
-    {  return parse_(result, input);  }                                 \
-    template <> std::ostream& toStream(const Type& obj, std::ostream& s) \
-    {  return toStream_(obj, s); }}}
+    namespace Parsers  {						\
+      template <> int parse(Type& result, const std::string& input)	\
+	{  return parse_(result, input);  }				\
+      template <> std::ostream& toStream(const Type& obj, std::ostream& s) \
+	{  return toStream_(obj, s); }}}
+// ============================================================================
+#define PARSERS_DEF_FOR_PAIR(First,Second)				\
+  namespace dd4hep  {                                                   \
+    namespace Parsers  {						\
+      template <> int parse(std::pair<First,Second>& result, const std::string& input) \
+	{  return parse_(result, input);  }				\
+      template <> std::ostream& toStream(const std::pair<First,Second>& obj, std::ostream& s) \
+	{  return toStream_(obj, s); }}}
 // ============================================================================
 
 #endif // PARSERS_SPIRIT_PARSERSFACTORY_H
diff --git a/DDParsers/src/Spirit/ParsersStandardMisc1.cpp b/DDParsers/src/Spirit/ParsersStandardMisc1.cpp
index 5538fe6069f6cd48a9a1ab60d726bf4e2b265fce..dfbedc6dbf878303939fceda12c6ce71499e5f7b 100755
--- a/DDParsers/src/Spirit/ParsersStandardMisc1.cpp
+++ b/DDParsers/src/Spirit/ParsersStandardMisc1.cpp
@@ -10,15 +10,19 @@
 //==========================================================================
 #include "Parsers/spirit/ParsersStandardMiscCommon.h"
 
+PARSERS_DEF_FOR_PAIR(bool,bool)
+PARSERS_DEF_FOR_PAIR(float,float)
+PARSERS_DEF_FOR_PAIR(double,double)
+PARSERS_DEF_FOR_PAIR(double,int)
+PARSERS_DEF_FOR_PAIR(double,long)
+PARSERS_DEF_FOR_PAIR(double,size_t)
+
 /// Namespace for the AIDA detector description toolkit
 namespace dd4hep {
+
   /// Namespace for the AIDA detector for utilities using boost::spirit parsers
   namespace Parsers {
 
-    template <> int parse(std::pair<double,double>& result, const std::string& input) {
-      return parse_(result, input);
-    }
-
     template <> int parse(std::vector<std::pair<double, double> >& result, const std::string& input) {
       return parse_(result, input);
     }
diff --git a/examples/DDDigi/scripts/TestSegmentationSplit2.py b/examples/DDDigi/scripts/TestSegmentationSplit2.py
new file mode 100644
index 0000000000000000000000000000000000000000..88d1dc237074f45aa40d5fee28edea2fb7a78c05
--- /dev/null
+++ b/examples/DDDigi/scripts/TestSegmentationSplit2.py
@@ -0,0 +1,50 @@
+# ==========================================================================
+#  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('DigiDDG4ROOT/SignalReader', mask=0x0, input=[digi.next_input()])
+  digi.check_creation([signal])
+  # ========================================================================
+  event = digi.event_action('DigiSequentialActionSequence/EventAction')
+  split_action = event.adopt_action('DigiContainerSequenceAction/SplitSequence',
+                                    parallel=True,
+                                    input_mask=0x0,
+                                    input_segment='inputs',
+                                    output_segment='deposits',
+                                    output_mask=0xFEED)
+  splitter = digi.create_action('DigiSegmentSplitter/Splitter',
+                                parallel=True,
+                                split_by='layer',
+                                detector='SiTrackerBarrel')
+  printer = digi.create_action('DigiSegmentDepositPrint/P1')
+  splitter.get().adopt_segment_processor(printer, 1)
+  printer = digi.create_action('DigiSegmentDepositPrint/P2')
+  splitter.adopt_segment_processor(printer, [2, 3, 4])
+  printer = digi.create_action('DigiSegmentDepositPrint/P3')
+  splitter.adopt_segment_processor(printer, [5])
+  split_action.adopt_container_processor(splitter, splitter.collection_names())
+
+  event.adopt_action('DigiStoreDump/StoreDump')
+  digi.info('Created event.dump')
+  # ========================================================================
+  digi.run_checked(num_events=1, num_threads=10, parallel=3)
+
+
+if __name__ == '__main__':
+  run()