diff --git a/DDCore/include/DD4hep/detail/ObjectsInterna.h b/DDCore/include/DD4hep/detail/ObjectsInterna.h
index 9cfce7c7be5e67783d7c6efd857777b4bcca3505..c0f98d6e3ce3eaeab8f1380ef954c475b7f24923 100644
--- a/DDCore/include/DD4hep/detail/ObjectsInterna.h
+++ b/DDCore/include/DD4hep/detail/ObjectsInterna.h
@@ -88,9 +88,9 @@ namespace dd4hep {
   class VisAttrObject: public NamedObject {
   public:
     unsigned long magic;
-    TColor* col;
-    int color;
-    float alpha;
+    TColor*       col;
+    int           color;
+    float         alpha;
     unsigned char drawingStyle, lineStyle, showDaughters, visible;
     /// Standard constructor
     VisAttrObject();
@@ -169,11 +169,11 @@ namespace dd4hep {
   class ReadoutObject: public NamedObject {
   public:
     /// Handle to the readout segmentation
-    Segmentation segmentation;  //! not ROOT-persistent
+    Segmentation  segmentation;  //! not ROOT-persistent
     /// Handle to the volume
-    Volume readoutWorld;
+    Volume        readoutWorld;
     /// Handle to the field descriptor
-    IDDescriptor id;
+    IDDescriptor  id;
     /// Hit collection container (if defined)
     std::vector<HitCollection> hits;
     /// Standard constructor
@@ -195,9 +195,9 @@ namespace dd4hep {
     typedef std::vector<std::pair<std::string, const BitFieldElement*> > FieldMap;
     typedef std::vector<std::pair<size_t, std::string> >         FieldIDs;
     /// Map of id-fields in the descriptor
-    FieldMap fieldMap;
+    FieldMap      fieldMap;
     /// String map of id descriptors
-    FieldIDs fieldIDs;
+    FieldIDs      fieldIDs;
     /// Decoder object
     BitFieldCoder decoder;
     
diff --git a/DDCore/src/plugins/Compact2Objects.cpp b/DDCore/src/plugins/Compact2Objects.cpp
index d0e6555073cfe67a6e0f3a3dcc03f7246d7a3bac..391849e7ca184b05d72ad3bdf83c1f81f16941c3 100644
--- a/DDCore/src/plugins/Compact2Objects.cpp
+++ b/DDCore/src/plugins/Compact2Objects.cpp
@@ -595,11 +595,11 @@ template <> void Converter<VisAttr>::operator()(xml_h e) const {
  *
  */
 template <> void Converter<Region>::operator()(xml_h elt) const {
-  xml_dim_t  e = elt;
-  Region     region(e.nameStr());
-  vector<string>&limits = region.limits();
-  xml_attr_t cut = elt.attr_nothrow(_U(cut));
-  xml_attr_t threshold = elt.attr_nothrow(_U(threshold));
+  xml_dim_t       e = elt;
+  Region          region(e.nameStr());
+  vector<string>& limits       = region.limits();
+  xml_attr_t      cut          = elt.attr_nothrow(_U(cut));
+  xml_attr_t      threshold    = elt.attr_nothrow(_U(threshold));
   xml_attr_t store_secondaries = elt.attr_nothrow(_U(store_secondaries));
   double ene = e.eunit(1.0), len = e.lunit(1.0);
 
diff --git a/cmake/DD4hepBuild.cmake b/cmake/DD4hepBuild.cmake
index 386b0004b69e32883ed00cfc4a766428ea091541..797a6095fd4398a83415c55ac344c22cd2aeba3e 100644
--- a/cmake/DD4hepBuild.cmake
+++ b/cmake/DD4hepBuild.cmake
@@ -1249,7 +1249,7 @@ function( dd4hep_add_dictionary dictionary )
   if ( "${enabled}" STREQUAL "OFF" )
     dd4hep_skipmsg ( "${tag} DISBALED -- package is not built!" )
   else()
-    cmake_parse_arguments(ARG "" "" "SOURCES;EXCLUDE;LINKDEF;OPTIONS;OPTIONAL;INCLUDES" ${ARGN} )
+    cmake_parse_arguments(ARG "" "" "SOURCES;EXCLUDE;LINKDEF;OPTIONS;OPTIONAL;INCLUDES;OUTPUT" ${ARGN} )
     dd4hep_print ( "|++> ${tag} Building dictionary ..." ) 
     if("${ARG_LINKDEF}" STREQUAL "")
       set(ARG_LINKDEF "${CMAKE_SOURCE_DIR}/DDCore/include/ROOT/LinkDef.h")
@@ -1311,14 +1311,16 @@ function( dd4hep_add_dictionary dictionary )
     dd4hep_debug ( "${tag}  Unparsed:'${ARG_UNPARSED_ARGUMENTS}'" ) 
     dd4hep_debug ( "${tag}  Sources: '${CMAKE_CURRENT_SOURCE_DIR}'" ) 
     #
+    set ( output_dir ${CMAKE_CURRENT_BINARY_DIR}/../lib )
+    if ( NOT "${ARG_OUTPUT}" STREQUAL "" )
+      set ( output_dir ${ARG_OUTPUT} )
+    endif()
     add_custom_command(OUTPUT ${dictionary}.cxx
       COMMAND ${ROOT_rootcling_CMD} -cint -f ${dictionary}.cxx
-      -s ${CMAKE_CURRENT_BINARY_DIR}/../lib/${dictionary} -inlineInputHeader -c -p ${ARG_OPTIONS} ${comp_defs} -std=c++${CMAKE_CXX_STANDARD} ${inc_dirs} ${headers} ${linkdefs}
+      -s ${output_dir}/${dictionary} -inlineInputHeader -c -p ${ARG_OPTIONS} ${comp_defs} -std=c++${CMAKE_CXX_STANDARD} ${inc_dirs} ${headers} ${linkdefs}
       DEPENDS ${headers} ${linkdefs} )
     #  Install the binary to the destination directory
-    #set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/../lib/${dictionary}_rdict.pcm PROPERTIES GENERATED TRUE )
-    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/../lib/${dictionary}_rdict.pcm DESTINATION lib)
-    #set_source_files_properties( ${dictionary}.h ${dictionary}.cxx PROPERTIES GENERATED TRUE )
+    install(FILES ${output_dir}/${dictionary}_rdict.pcm DESTINATION lib)
     endif()
 endfunction()
 
diff --git a/examples/ClientTests/CMakeLists.txt b/examples/ClientTests/CMakeLists.txt
index f7d19a0c463c45a9ac834e47ac442ad81635154a..6d229804101ffbbb96f9ca85a0ee82ebe226bd2e 100644
--- a/examples/ClientTests/CMakeLists.txt
+++ b/examples/ClientTests/CMakeLists.txt
@@ -233,4 +233,12 @@ if (DD4HEP_USE_GEANT4)
       REGEX_PASS NONE
       REGEX_FAIL "Exception;EXCEPTION;ERROR;Error" )
   endforeach(script)
+
+  dd4hep_add_test_reg( ClientTests_sim_UserAnalysis
+    COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh"
+    EXEC_ARGS  python ${CMAKE_CURRENT_SOURCE_DIR}/scripts/MiniTelEnergyDeposits.py batch
+    REQUIRES   DDG4 Geant4
+    REGEX_PASS "Entries :      200 "
+    REGEX_FAIL "Exception;EXCEPTION;ERROR;Error" )
+
 endif(DD4HEP_USE_GEANT4)
diff --git a/examples/ClientTests/scripts/MiniTelEnergyDeposits.py b/examples/ClientTests/scripts/MiniTelEnergyDeposits.py
new file mode 100644
index 0000000000000000000000000000000000000000..3a6c40d3b25204c65998a26eb9b0eadf6df3a1ef
--- /dev/null
+++ b/examples/ClientTests/scripts/MiniTelEnergyDeposits.py
@@ -0,0 +1,67 @@
+import os, sys, time, DDG4
+from DDG4 import OutputLevel as Output
+from SystemOfUnits import *
+#
+#
+"""
+
+   dd4hep example setup using the python configuration
+
+   \author  M.Frank
+   \version 1.0
+
+"""
+def run():
+  kernel = DDG4.Kernel()
+  install_dir = os.environ['DD4hepINSTALL']
+  kernel.setOutputLevel('Geant4Converter',Output.DEBUG)
+  kernel.setOutputLevel('Gun',Output.INFO)
+  kernel.loadGeometry("file:"+install_dir+"/examples/ClientTests/compact/MiniTel.xml")
+
+  geant4 = DDG4.Geant4(kernel)
+  geant4.printDetectors()
+  geant4.setupCshUI()
+  if len(sys.argv) >= 2 and sys.argv[1] =="batch":
+    kernel.NumEvents = 200
+    kernel.UI = ''
+
+  # Configure field
+  field = geant4.setupTrackingField(prt=True)
+  # Setup particle gun
+  geant4.setupGun("Gun",particle='pi-',energy=100*GeV,multiplicity=1)
+  # Now the calorimeters
+  seq,act = geant4.setupTracker('MyLHCBdetector1')
+  seq,act = geant4.setupTracker('MyLHCBdetector2')
+  seq,act = geant4.setupTracker('MyLHCBdetector3')
+  seq,act = geant4.setupTracker('MyLHCBdetector4')
+  act.OutputLevel = 4
+  seq,act = geant4.setupTracker('MyLHCBdetector5')
+  seq,act = geant4.setupTracker('MyLHCBdetector6')
+  seq,act = geant4.setupTracker('MyLHCBdetector7')
+  seq,act = geant4.setupTracker('MyLHCBdetector8')
+  seq,act = geant4.setupTracker('MyLHCBdetector9')
+  seq,act = geant4.setupTracker('MyLHCBdetector10')
+
+  # And handle the simulation particles.
+  part = DDG4.GeneratorAction(kernel,"Geant4ParticleHandler/ParticleHandler")
+  kernel.generatorAction().adopt(part)
+  part.SaveProcesses = ['conv','Decay']
+  part.MinimalKineticEnergy = 1*MeV
+  part.OutputLevel = 5 # generator_output_level
+  part.enableUI()
+
+  hit_tuple = DDG4.EventAction(kernel,'HitTupleAction/MiniTelTuple',True)
+  hit_tuple.OutputFile = 'MiniTel_EnergyDeposits_'+time.strftime('%Y-%m-%d_%H-%M')+'.root'
+  hit_tuple.Collections = ['*']
+  kernel.eventAction().add(hit_tuple)
+
+
+  # Now build the physics list:
+  phys = kernel.physicsList()
+  phys.extends = 'QGSP_BERT'
+  phys.enableUI()
+  # and run
+  geant4.execute()
+
+if __name__ == "__main__":
+  run()
diff --git a/examples/DDG4/CMakeLists.txt b/examples/DDG4/CMakeLists.txt
index 7985b31ef8a7be2a8a406432a484d578451d736e..6555e6789b054fc372c555d08437f15af84a656b 100644
--- a/examples/DDG4/CMakeLists.txt
+++ b/examples/DDG4/CMakeLists.txt
@@ -20,6 +20,22 @@ dd4hep_package ( DDG4 MAJOR 0 MINOR 0 PATCH 1
 #---Geant4 Testsing-----------------------------------------------------------------
 #
 if (DD4HEP_USE_GEANT4)
+  #
+  #----  Dictionary of classes to be written to the ROOT file   --------------------
+  dd4hep_add_dictionary(G__DDG4UserDict
+  SOURCES ${DD4hep_DIR}/include/ROOT/Warnings.h src/Dictionary.h
+  LINKDEF ${DD4hep_DIR}/include/ROOT/LinkDef.h
+  OUTPUT  ${CMAKE_CURRENT_BINARY_DIR}/lib
+  )
+  #----  Example of a client library with user defined plugins  --------------------
+  dd4hep_add_plugin( DDG4UserLib
+    GENERATED G__DDG4UserDict.cxx
+    SOURCES   src/*.cpp
+    USES      [GEANT4 REQUIRED]
+              [ROOT   REQUIRED COMPONENTS Geom GenVector RIO]
+              [DD4hep REQUIRED COMPONENTS DDCore DDG4]
+    )
+  #
   #
   dd4hep_install_dir(data DESTINATION ${DD4hep_DIR}/examples/DDG4 )
   #
diff --git a/examples/DDG4/src/Dictionary.h b/examples/DDG4/src/Dictionary.h
new file mode 100644
index 0000000000000000000000000000000000000000..e6b8d1d1b86be0077f7ccc7fc238e3d470442e0f
--- /dev/null
+++ b/examples/DDG4/src/Dictionary.h
@@ -0,0 +1,36 @@
+//==========================================================================
+//  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
+//
+//==========================================================================
+// -------------------------------------------------------------------------
+// Regular dd4hep dictionaries
+// -------------------------------------------------------------------------
+#ifdef DD4HEP_DICTIONARY_MODE
+
+#include <map>
+#include <vector>
+
+#pragma link off all globals;
+#pragma link off all classes;
+#pragma link off all functions;
+
+
+using namespace std;
+
+// Define here the classes we want to write to the output file:
+#pragma link C++ class std::vector<double>+;
+#pragma link C++ class std::pair<double, std::vector<double> >+;
+
+/// This is to make ROOT happy....
+struct Disctionary {};
+
+
+#endif   // DD4HEP_DICTIONARY_MODE
diff --git a/examples/DDG4/src/HitTupleAction.cpp b/examples/DDG4/src/HitTupleAction.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b77d1a0ed4a2fd58a591927a6b16307527fc9441
--- /dev/null
+++ b/examples/DDG4/src/HitTupleAction.cpp
@@ -0,0 +1,226 @@
+//==========================================================================
+//  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 DD4HEP_DDG4_HITTUPLEACTION_H
+#define DD4HEP_DDG4_HITTUPLEACTION_H
+
+// Framework include files
+#include "DDG4/Geant4EventAction.h"
+
+// Forward declarations
+class G4VHitsCollection;
+class TFile;
+class TTree;
+class TBranch;
+
+/// Namespace example name of the user
+namespace myanalysis {
+
+  // Forward declarations
+  class Geant4ParticleMap;
+    
+  /// Class to measure the energy of escaping tracks
+  /** Class to measure the energy of escaping tracks of a detector using Geant 4
+   * Measure escaping energy....
+   *
+   *  \author  M.Frank
+   *  \version 1.0
+   *  \ingroup DD4HEP_SIMULATION
+   */
+  class HitTupleAction : public dd4hep::sim::Geant4EventAction {
+  public:
+    typedef std::vector<std::string> CollectionNames;
+    /// Property: collection names to be dumped 
+    CollectionNames m_containers;
+    /// Property: Output file name
+    std::string     m_outFileName;
+    /// ROOT TFile instance
+    TFile*          m_outFile = 0;
+    /// Tree object within the file
+    TTree*          m_outTree = 0;
+    /// We want to write a separate branch for all deposits of one container(sub-detector)
+    typedef std::pair<double, std::vector<double> > Data;
+    /// The intermediate storage of the hit deposits to be written to ROOT
+    std::map<std::string, std::pair<TBranch*, Data> > m_deposits;
+    
+  public:
+    /// Standard constructor
+    HitTupleAction(dd4hep::sim::Geant4Context* context, const std::string& nam);
+    /// Default destructor
+    virtual ~HitTupleAction();
+    /// Begin-of-run callback: Open output file
+    void beginRun(const G4Run* run);
+    /// End-of-run callback: Close output file
+    void endRun(const G4Run* run);
+    /// Geant4EventAction interface: Begin-of-event callback
+    virtual void begin(const G4Event* event)  override;
+    /// Geant4EventAction interface: End-of-event callback
+    virtual void end(const G4Event* event)  override;
+  };
+}      // End namespace dd4hep
+#endif /* DD4HEP_DDG4_HITTUPLEACTION_H */
+
+//====================================================================
+//  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 "DDG4/Geant4DataDump.h"
+#include "DDG4/Geant4RunAction.h"
+#include "DDG4/Geant4HitCollection.h"
+
+// Geant 4 includes
+#include "G4HCofThisEvent.hh"
+#include "G4Event.hh"
+
+// ROOT include files
+#include "TFile.h"
+#include "TTree.h"
+#include "TROOT.h"
+#include "TClass.h"
+#include "TBranch.h"
+
+using namespace std;
+using namespace dd4hep;
+using namespace dd4hep::sim;
+
+/// Standard constructor
+myanalysis::HitTupleAction::HitTupleAction(Geant4Context* ctxt, const string& nam)
+  : Geant4EventAction(ctxt, nam), m_containers{"*"}
+{
+  m_needsControl = true;
+  m_containers.push_back("*");
+  declareProperty("OutputFile",   m_outFileName);
+  declareProperty("Collections",  m_containers);
+  runAction().callAtBegin(this,  &HitTupleAction::beginRun);
+  runAction().callAtEnd(this,    &HitTupleAction::endRun);
+}
+
+/// Default destructor
+myanalysis::HitTupleAction::~HitTupleAction() {
+}
+
+/// Begin-of-run callback: Open output file
+void myanalysis::HitTupleAction::beginRun(const G4Run* /* run */)   {
+}
+
+/// End-of-run callback: Close output file
+void myanalysis::HitTupleAction::endRun(const G4Run* /* run */)    {
+  if ( m_outFile )   {
+    if ( m_outTree )   {
+      m_outTree->Write();
+      m_outTree->Print();
+    }
+    m_outFile->Write();
+    m_outFile->Close();
+    delete m_outFile;
+    m_outFile = 0;
+  }
+}
+
+/// Geant4EventAction interface: Begin-of-event callback
+void myanalysis::HitTupleAction::begin(const G4Event* /* event */)   {
+}
+
+/// Geant4EventAction interface: End-of-event callback
+void myanalysis::HitTupleAction::end(const G4Event* event)    {
+  G4HCofThisEvent* hce = event->GetHCofThisEvent();
+  if ( hce )  {
+    int nCol = hce->GetNumberOfCollections();
+    if ( nCol <= 0 )   {
+      return;
+    }
+    else if ( !m_outFile )   {
+      //                      Name                   Option      Title
+      m_outFile = TFile::Open(m_outFileName.c_str(), "RECREATE", "DDG4 User file");
+      if ( m_outFile && !m_outFile->IsZombie() )   {
+        m_outTree = new TTree("DDG4 User Test","DDG4 data");
+        printout(ALWAYS,"HitTupleAction","+++ Successfully opened ROOT file %s and created TTree:%s",
+                 m_outFile->GetName(), "DDG4 User Test");
+        if ( m_containers.size() == 1 && (m_containers[0] == "*" || m_containers[0] == "ALL") )  {
+          m_containers.clear();
+          for (int i = 0; i < nCol; ++i)
+            m_containers.push_back(hce->GetHC(i)->GetName());
+        }
+        // Seperate loop. We need fixed addresses when creating the branches
+        for(const auto& c : m_containers)   {
+          m_deposits[c].first = 0;
+          m_deposits[c].second.first = 0e0;
+          m_deposits[c].second.second.clear();
+        }
+        for(const auto& c : m_containers)   {
+          std::pair<TBranch*, Data>& e = m_deposits[c];
+          TClass* cl = gROOT->GetClass(typeid(Data));
+          e.first = m_outTree->Branch(c.c_str(), cl->GetName(), (void*)0);
+          e.first->SetAutoDelete(false);
+          printout(ALWAYS,"HitTupleAction","+++ Prepare hit branch %s in root file.",c.c_str());
+        }
+      }
+      else   {
+        except("HitTupleAction","Failed to open ROOT N-tuple file: "+m_outFileName);
+      }
+    }
+    for ( auto& e : m_deposits )  {
+      e.second.first->SetAddress(0);
+    }
+    for (int i = 0; i < nCol; ++i) {
+      G4VHitsCollection* hc = hce->GetHC(i);
+      const string& nam = hc->GetName();
+      if ( find(m_containers.begin(),m_containers.end(),nam) != m_containers.end() )   {
+        Geant4HitCollection* coll = dynamic_cast<Geant4HitCollection*>(hc);
+        if ( coll )    {
+          std::pair<TBranch*, Data>& e = m_deposits[nam];
+          size_t nhits = coll->GetSize();
+          Data* d = &e.second;
+
+          e.second.first = 0e0;
+          e.second.second.clear();
+          e.first->SetAddress(&d);
+          for ( size_t j=0; j<nhits; ++j )   {
+            double dep = 0e0;
+            Geant4HitData* h = coll->hit(j);
+            Geant4Tracker::Hit* trk_hit = dynamic_cast<Geant4Tracker::Hit*>(h);
+            if ( 0 != trk_hit )   {
+              dep = trk_hit->truth.deposit;
+            }
+            else  {
+              Geant4Calorimeter::Hit* cal_hit = dynamic_cast<Geant4Calorimeter::Hit*>(h);
+              if ( 0 != cal_hit )
+                dep = cal_hit->energyDeposit;
+              else
+                continue;
+            }
+            if ( dep > 0 )  {
+              e.second.first += dep;
+              e.second.second.push_back(dep);
+            }
+          }
+        }
+      }
+    }
+    m_outTree->Fill();
+    return;
+  }
+  warning("+++ [Event:%d] The value of G4HCofThisEvent is NULL.",event->GetEventID());
+}
+
+#include "DDG4/Factories.h"
+DECLARE_GEANT4ACTION_NS(myanalysis,HitTupleAction)