From d16f1ac729dc40baa33360ebcc2a189980a7a451 Mon Sep 17 00:00:00 2001
From: Markus Frank <Markus.Frank@cern.ch>
Date: Tue, 26 Jun 2018 15:52:29 +0200
Subject: [PATCH] Add example how to build special sensitive detector and
 attach it to DDG4

---
 examples/AlignDet/CMakeLists.txt              |  36 ++--
 examples/CMakeLists.txt                       |   1 +
 examples/ClientTests/scripts/FCC_Hcal.py      |   2 +-
 examples/DDG4/CMakeLists.txt                  |   2 +
 examples/DDG4_MySensDet/CMakeLists.txt        |  54 ++++++
 examples/DDG4_MySensDet/README.txt            |   8 +
 .../DDG4_MySensDet/scripts/MyTrackerSD.py     |  87 ++++++++++
 .../DDG4_MySensDet/scripts/MyTrackerSD_sim.py |  56 +++++++
 .../DDG4_MySensDet/src/MyTrackerSDAction.cpp  | 158 ++++++++++++++++++
 9 files changed, 385 insertions(+), 19 deletions(-)
 create mode 100644 examples/DDG4_MySensDet/CMakeLists.txt
 create mode 100644 examples/DDG4_MySensDet/README.txt
 create mode 100644 examples/DDG4_MySensDet/scripts/MyTrackerSD.py
 create mode 100644 examples/DDG4_MySensDet/scripts/MyTrackerSD_sim.py
 create mode 100644 examples/DDG4_MySensDet/src/MyTrackerSDAction.cpp

diff --git a/examples/AlignDet/CMakeLists.txt b/examples/AlignDet/CMakeLists.txt
index 9c0b330da..c921e924a 100644
--- a/examples/AlignDet/CMakeLists.txt
+++ b/examples/AlignDet/CMakeLists.txt
@@ -19,9 +19,9 @@ dd4hep_package ( AlignDet MAJOR 0 MINOR 0 PATCH 1
   OPTIONAL       XERCESC
   INCLUDE_DIRS   include
   )
-
-dd4hep_add_plugin( AlignDetExample SOURCES src/*.cpp  )
-dd4hep_install_dir( compact DESTINATION examples/AlignDet )
+set(AlignDet_INSTALL ${CMAKE_INSTALL_PREFIX}/examples/AlignDet)
+dd4hep_add_plugin(   AlignDetExample SOURCES src/*.cpp  )
+dd4hep_install_dir(  compact DESTINATION ${AlignDet_INSTALL} )
 dd4hep_configure_scripts( AlignDet DEFAULT_SETUP WITH_TESTS)
 
 #
@@ -29,7 +29,7 @@ dd4hep_configure_scripts( AlignDet DEFAULT_SETUP WITH_TESTS)
 dd4hep_add_test_reg( AlignDet_Telescope_dump_geometry
   COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh"
   EXEC_ARGS  geoPluginRun -volmgr -destroy 
-  -compact file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/Telescope.xml 
+  -compact file:${AlignDet_INSTALL}/compact/Telescope.xml 
   -plugin DD4hep_DetectorDump
   REGEX_PASS "/world/Telescope/module_9 NumDau\\:1 VolID\\:00000903 Place"
   REGEX_FAIL " ERROR ;EXCEPTION;Exception"
@@ -39,7 +39,7 @@ dd4hep_add_test_reg( AlignDet_Telescope_dump_geometry
 dd4hep_add_test_reg( AlignDet_Telescope_populate
   COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh"
   EXEC_ARGS  geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample_populate 
-     -input file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/Telescope.xml -iovs 10
+     -input file:${AlignDet_INSTALL}/compact/Telescope.xml -iovs 10
   REGEX_PASS "Summary          INFO  Processed a total 190 conditions \\(S:190,L:0,C:0,M:0\\) and \\(C:190,M:0\\) alignments. Created:200"
   REGEX_FAIL " ERROR ;EXCEPTION;Exception"
   )
@@ -48,7 +48,7 @@ dd4hep_add_test_reg( AlignDet_Telescope_populate
 dd4hep_add_test_reg( AlignDet_Telescope_read_xml
   COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh"
   EXEC_ARGS  geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample_read_xml 
-     -input  file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/Telescope.xml 
+     -input  file:${AlignDet_INSTALL}/compact/Telescope.xml 
      -deltas file:${CMAKE_INSTALL_PREFIX}/examples/Conditions/data/repository.xml 
   REGEX_PASS "20 conditions in slice. \\(T:20,S:20,L:0,C:0,M:0\\) Alignments accessed: 20 \\(A:19,M:0\\) for IOV:run\\(1\\)"
   REGEX_FAIL " ERROR ;EXCEPTION;Exception"
@@ -58,7 +58,7 @@ dd4hep_add_test_reg( AlignDet_Telescope_read_xml
 dd4hep_add_test_reg( AlignDet_Telescope_dump_xml
   COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh"
   EXEC_ARGS  geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample_read_xml 
-  -input file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/Telescope.xml 
+  -input file:${AlignDet_INSTALL}/compact/Telescope.xml 
   -delta file:${CMAKE_INSTALL_PREFIX}/examples/Conditions/data/repository.xml 
   -plugin DD4hep_ConditionsXMLRepositoryWriter -iov_type run -iov_value 1500
   REGEX_PASS "Summary: Converted 33 conditions. 0 conditions without recipe"
@@ -69,7 +69,7 @@ dd4hep_add_test_reg( AlignDet_Telescope_dump_xml
 dd4hep_add_test_reg( AlignDet_Telescope_write_xml
   COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh"
   EXEC_ARGS  geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample_read_xml 
-  -input file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/Telescope.xml 
+  -input file:${AlignDet_INSTALL}/compact/Telescope.xml 
   -delta file:${CMAKE_INSTALL_PREFIX}/examples/Conditions/data/repository.xml 
   -plugin DD4hep_ConditionsXMLRepositoryWriter -iov_type run -iov_value 1500 -manager -output new_cond.xml
   REGEX_PASS "Successfully wrote 33 conditions \\(0 unconverted\\) to file: new_cond.xml"
@@ -80,7 +80,7 @@ dd4hep_add_test_reg( AlignDet_Telescope_write_xml
 dd4hep_add_test_reg( AlignDet_Telescope_stress
   COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh"
   EXEC_ARGS  geoPluginRun  -volmgr -destroy -plugin DD4hep_AlignmentExample_stress 
-      -input file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/Telescope.xml -iovs 20 -runs 111
+      -input file:${AlignDet_INSTALL}/compact/Telescope.xml -iovs 20 -runs 111
   REGEX_PASS "Summary: Total 4598 conditions used \\(S:4598,L:0,C:0,M:0\\) \\(A:380,M:0\\)"
   REGEX_FAIL " ERROR ;EXCEPTION;Exception"
   )
@@ -89,7 +89,7 @@ dd4hep_add_test_reg( AlignDet_Telescope_stress
 dd4hep_add_test_reg( AlignDet_Telescope_align_new
   COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh"
   EXEC_ARGS  geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample_align_telescope 
-     -input  file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/Telescope.xml 
+     -input  file:${AlignDet_INSTALL}/compact/Telescope.xml 
      -setup  file:${CMAKE_INSTALL_PREFIX}/examples/Conditions/data/manager.xml 
   REGEX_PASS "World transformation of: /world/Telescope/module_3/sensor  Tr:\\( 3.9e\\+02,       0,     4.9 \\[cm\\]\\)"
   REGEX_FAIL " ERROR ;EXCEPTION;Exception"
@@ -99,7 +99,7 @@ dd4hep_add_test_reg( AlignDet_Telescope_align_new
 dd4hep_add_test_reg( AlignDet_Telescope_align_nominal
   COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh"
   EXEC_ARGS  geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample_nominal
-     -input  file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/Telescope.xml 
+     -input  file:${AlignDet_INSTALL}/compact/Telescope.xml 
   REGEX_PASS "Printed 20, scanned 20 and computed a total of 20 alignments \\(C:20,M:0\\)"
   REGEX_FAIL " ERROR ;EXCEPTION;Exception"
   )
@@ -108,7 +108,7 @@ dd4hep_add_test_reg( AlignDet_Telescope_align_nominal
 dd4hep_add_test_reg( AlignDet_Telescope_readback_xml
   COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh"
   EXEC_ARGS  geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample_read_xml
-  -input  file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/Telescope.xml
+  -input  file:${AlignDet_INSTALL}/compact/Telescope.xml
   -deltas file:./new_cond.xml
   REGEX_PASS "33 conditions in slice. \\(T:33,S:33,L:0,C:0,M:0\\) Alignments accessed: 20 \\(A:19,M:0\\) for IOV:run\\(1\\)"
   REGEX_FAIL " ERROR ;EXCEPTION;Exception"
@@ -136,7 +136,7 @@ dd4hep_add_test_reg( AlignDet_CLICSiD_align_nominal_LONGTEST
 dd4hep_add_test_reg( AlignDet_AlephTPC_load
   COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh"
   EXEC_ARGS  geoPluginRun
-             -input file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/AlephTPC.xml
+             -input file:${AlignDet_INSTALL}/compact/AlephTPC.xml
              -destroy -no-interpreter -plugin DD4hep_GlobalAlignmentInstall
   REGEX_PASS "189 nodes/ 24 volume UID's in Detector Geometry"
   REGEX_FAIL " ERROR ;EXCEPTION;Exception"
@@ -146,10 +146,10 @@ dd4hep_add_test_reg( AlignDet_AlephTPC_load
 dd4hep_add_test_reg( AlignDet_AlephTPC_global_align
   COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh"
   EXEC_ARGS  geoPluginRun
-             -input file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/AlephTPC.xml
+             -input file:${AlignDet_INSTALL}/compact/AlephTPC.xml
              -destroy -no-interpreter
              -plugin DD4hep_GlobalAlignmentInstall
-             -plugin DD4hep_XMLLoader file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/AlephTPC_alignment.xml BUILD_DEFAULT
+             -plugin DD4hep_XMLLoader file:${AlignDet_INSTALL}/compact/AlephTPC_alignment.xml BUILD_DEFAULT
   REGEX_PASS "Successfully parsed XML: AlephTPC_alignment.xml"
   REGEX_FAIL " ERROR ;EXCEPTION;Exception"
   )
@@ -158,11 +158,11 @@ dd4hep_add_test_reg( AlignDet_AlephTPC_global_align
 dd4hep_add_test_reg( AlignDet_AlephTPC_global_reset
   COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh"
   EXEC_ARGS  geoPluginRun
-             -input file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/AlephTPC.xml
+             -input file:${AlignDet_INSTALL}/compact/AlephTPC.xml
              -destroy -no-interpreter
              -plugin DD4hep_GlobalAlignmentInstall
-             -plugin DD4hep_XMLLoader file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/AlephTPC_alignment.xml
-             -plugin DD4hep_XMLLoader file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/AlephTPC_reset.xml
+             -plugin DD4hep_XMLLoader file:${AlignDet_INSTALL}/compact/AlephTPC_alignment.xml
+             -plugin DD4hep_XMLLoader file:${AlignDet_INSTALL}/compact/AlephTPC_reset.xml
   REGEX_PASS "Successfully parsed XML: AlephTPC_reset.xml"
   REGEX_FAIL " ERROR ;EXCEPTION;Exception"
   )
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index c06eea95d..5a3025c4f 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -53,6 +53,7 @@ dd4hep_enable_tests (
   DDG4
   Persistency
   SimpleDetector
+  DDG4_MySensDet
   )
 #
 # XercesC dependent stuff
diff --git a/examples/ClientTests/scripts/FCC_Hcal.py b/examples/ClientTests/scripts/FCC_Hcal.py
index 87460f699..6ce04c323 100644
--- a/examples/ClientTests/scripts/FCC_Hcal.py
+++ b/examples/ClientTests/scripts/FCC_Hcal.py
@@ -26,7 +26,7 @@ def run():
   geant4.setupCshUI()
 
   # Configure field
-  field = geant4.setupfield(prt=True)
+  field = geant4.setupTrackingField(prt=True)
   # Configure I/O
   evt_root = geant4.setupROOTOutput('RootOutput','FCC_'+time.strftime('%Y-%m-%d_%H-%M'),mc_truth=False)
   # Setup particle gun
diff --git a/examples/DDG4/CMakeLists.txt b/examples/DDG4/CMakeLists.txt
index 7ca766b24..ed1ceb715 100644
--- a/examples/DDG4/CMakeLists.txt
+++ b/examples/DDG4/CMakeLists.txt
@@ -20,6 +20,8 @@ dd4hep_package ( DDG4 MAJOR 0 MINOR 0 PATCH 1
 #---Geant4 Testsing-----------------------------------------------------------------
 #
 if (DD4HEP_USE_GEANT4)
+  #
+  dd4hep_set_compiler_flags()
   #
   #----  Dictionary of classes to be written to the ROOT file   --------------------
   dd4hep_add_dictionary(G__DDG4UserDict
diff --git a/examples/DDG4_MySensDet/CMakeLists.txt b/examples/DDG4_MySensDet/CMakeLists.txt
new file mode 100644
index 000000000..020c2bd44
--- /dev/null
+++ b/examples/DDG4_MySensDet/CMakeLists.txt
@@ -0,0 +1,54 @@
+#==========================================================================
+#  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.
+#
+#==========================================================================
+cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
+include ( ${DD4hep_DIR}/cmake/DD4hep.cmake )
+
+#-----------------------------------------------------------------------------------
+dd4hep_configure_output ()
+dd4hep_package ( DDG4_MySensDet MAJOR 0 MINOR 0 PATCH 1
+  USES  [GEANT4 REQUIRED]
+  [ROOT   REQUIRED COMPONENTS Geom GenVector RIO]
+  [DD4hep REQUIRED COMPONENTS DDCore DDG4]
+)
+set(DDG4_MySensDet_INSTALL ${CMAKE_INSTALL_PREFIX}/examples/DDG4_MySensDet)
+dd4hep_install_dir(scripts  DESTINATION ${DDG4_MySensDet_INSTALL} )
+dd4hep_configure_scripts(DDG4_MySensDet DEFAULT_SETUP WITH_TESTS)
+#
+#---Geant4 Testsing-----------------------------------------------------------------
+#
+if (DD4HEP_USE_GEANT4)
+  #
+  dd4hep_set_compiler_flags()
+  #----  Example of a client library with user defined plugins  --------------------
+  dd4hep_add_plugin( DDG4_MySensDet
+    SOURCES   src/*.cpp
+    USES      [GEANT4 REQUIRED]
+              [ROOT   REQUIRED COMPONENTS Geom GenVector RIO]
+              [DD4hep REQUIRED COMPONENTS DDCore DDG4]
+    )
+
+  # Geant4 material scan. From position=0,0,0 to end-of-world 
+  dd4hep_add_test_reg( DDG4_MySensDet_g4material_scan_SiliconBlock_LONGTEST
+    COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_DDG4_MySensDet.sh"
+    EXEC_ARGS  python ${DD4hep_DIR}/python/g4MaterialScan.py
+               --compact=file:${CMAKE_INSTALL_PREFIX}/examples/ClientTests/compact/SiliconBlock.xml
+               "--position=0,0,0" "--direction=0,1,0"
+    REGEX_PASS " Terminate Geant4 and delete associated actions."
+  )
+             
+  dd4hep_add_test_reg( DDG4_MySensDet_sim_SiliconBlock_LONGTEST
+    COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_DDG4_MySensDet.sh"
+    EXEC_ARGS  python ${DDG4_MySensDet_INSTALL}/scripts/MyTrackerSD_sim.py 
+               --compact=file:${CMAKE_INSTALL_PREFIX}/examples/ClientTests/compact/SiliconBlock.xml
+    REGEX_PASS NONE
+    REGEX_FAIL "Exception;EXCEPTION;ERROR;Error" )
+
+endif()
diff --git a/examples/DDG4_MySensDet/README.txt b/examples/DDG4_MySensDet/README.txt
new file mode 100644
index 000000000..9f2bb062c
--- /dev/null
+++ b/examples/DDG4_MySensDet/README.txt
@@ -0,0 +1,8 @@
+This is an example how to implement a specialized sensitive detector in DDG4.
+The sensitive detector is called MyTrackerSD.
+As a hit class it uses the Geant4TrackerHit class.
+
+1) The example should illustrate how to setup the factory for a specialized sensitive detector action
+2) In the scripts area there is a simple example to illustrate how to setup a small
+   simulation and use this factory. (scripts/MyTrackerSD_sim.py)
+   
diff --git a/examples/DDG4_MySensDet/scripts/MyTrackerSD.py b/examples/DDG4_MySensDet/scripts/MyTrackerSD.py
new file mode 100644
index 000000000..a8db6afda
--- /dev/null
+++ b/examples/DDG4_MySensDet/scripts/MyTrackerSD.py
@@ -0,0 +1,87 @@
+#
+#
+import os, sys, time, DDG4
+from DDG4 import OutputLevel as Output
+from SystemOfUnits import *
+#
+#
+"""
+
+   dd4hep simulation example setup using the python configuration
+
+   @author  M.Frank
+   @version 1.0
+
+"""
+def run():
+  kernel = DDG4.Kernel()
+  install_dir = os.environ['DD4hepExamplesINSTALL']
+  kernel.loadGeometry("file:"+install_dir+"/examples/ClientTests/compact/SiliconBlock.xml")
+
+  DDG4.importConstants(kernel.detectorDescription(),debug=False)
+
+  # =======================================================================================
+  # ===> This is actually the ONLY difference to ClientTests/scripts/SiliconBlock.py
+  # =======================================================================================
+  geant4 = DDG4.Geant4(kernel,tracker='MyTrackerSDAction')
+
+  geant4.printDetectors()
+  # Configure UI
+  if len(sys.argv)>1:
+    geant4.setupCshUI(macro=sys.argv[1])
+  else:
+    geant4.setupCshUI()
+
+  # Configure field
+  field = geant4.setupTrackingField(prt=True)
+  # Configure Event actions
+  prt = DDG4.EventAction(kernel,'Geant4ParticlePrint/ParticlePrint')
+  prt.OutputLevel = Output.DEBUG
+  prt.OutputType  = 3 # Print both: table and tree
+  kernel.eventAction().adopt(prt)
+
+  generator_output_level = Output.INFO
+
+  # Configure G4 geometry setup
+  seq,act = geant4.addDetectorConstruction("Geant4DetectorGeometryConstruction/ConstructGeo")
+  act.DebugMaterials = True
+  act.DebugElements  = False
+  act.DebugVolumes   = True
+  act.DebugShapes    = True
+
+  # Configure I/O
+  evt_root = geant4.setupROOTOutput('RootOutput','SiliconBlock_'+time.strftime('%Y-%m-%d_%H-%M'))
+
+  # Setup particle gun
+  gun = geant4.setupGun("Gun",particle='mu-',energy=20*GeV,multiplicity=1)
+  gun.OutputLevel = generator_output_level
+
+  # And handle the simulation particles.
+  part = DDG4.GeneratorAction(kernel,"Geant4ParticleHandler/ParticleHandler")
+  kernel.generatorAction().adopt(part)
+  part.SaveProcesses = ['Decay']
+  part.MinimalKineticEnergy = 100*MeV
+  part.OutputLevel = Output.INFO #generator_output_level
+  part.enableUI()
+  user = DDG4.Action(kernel,"Geant4TCUserParticleHandler/UserParticleHandler")
+  user.TrackingVolume_Zmax = 3.0*m
+  user.TrackingVolume_Rmax = 3.0*m
+  user.enableUI()
+  part.adopt(user)
+
+  geant4.setupTracker('SiliconBlockUpper')
+  geant4.setupTracker('SiliconBlockDown')
+
+  # Now build the physics list:
+  phys = geant4.setupPhysics('QGSP_BERT')
+  ph = DDG4.PhysicsList(kernel,'Geant4PhysicsList/Myphysics')
+  ph.addParticleConstructor('G4Geantino')
+  ph.addParticleConstructor('G4BosonConstructor')
+  ph.enableUI()
+  phys.adopt(ph)
+  phys.dump()
+
+  geant4.execute()
+
+if __name__ == "__main__":
+  run()
diff --git a/examples/DDG4_MySensDet/scripts/MyTrackerSD_sim.py b/examples/DDG4_MySensDet/scripts/MyTrackerSD_sim.py
new file mode 100644
index 000000000..22da4a4ae
--- /dev/null
+++ b/examples/DDG4_MySensDet/scripts/MyTrackerSD_sim.py
@@ -0,0 +1,56 @@
+#
+#
+import os, sys, time, DDG4, dd4hep
+from DDG4 import OutputLevel as Output
+from SystemOfUnits import *
+#
+#
+"""
+
+   dd4hep simulation example setup using the python configuration
+
+   @author  M.Frank
+   @version 1.0
+
+"""
+def run():
+  kernel = DDG4.Kernel()
+  install_dir = os.environ['DD4hepExamplesINSTALL']
+  kernel.loadGeometry("file:"+install_dir+"/examples/ClientTests/compact/SiliconBlock.xml")
+  DDG4.importConstants(kernel.detectorDescription(),debug=False)
+  # =======================================================================================
+  # ===> This is actually the ONLY difference to ClientTests/scripts/SiliconBlock.py
+  # =======================================================================================
+  geant4 = DDG4.Geant4(kernel,tracker='MyTrackerSDAction')
+
+  geant4.printDetectors()
+  kernel.NumEvents = 5
+  kernel.UI = ''
+
+  # Configure field
+  field = geant4.setupTrackingField(prt=True)
+  # Configure Event actions
+  prt = DDG4.EventAction(kernel,'Geant4ParticlePrint/ParticlePrint')
+  prt.OutputLevel = Output.WARNING
+  prt.OutputType  = 3 # Print both: table and tree
+  kernel.eventAction().adopt(prt)
+
+  # Configure I/O
+  evt_root = geant4.setupROOTOutput('RootOutput','MySD_'+time.strftime('%Y-%m-%d_%H-%M'),mc_truth=False)
+  # Setup particle gun
+  gun = geant4.setupGun("Gun",particle='mu-',energy=5*GeV,multiplicity=1,Standalone=True,position=(0,0,0))
+  geant4.setupTracker('SiliconBlockUpper')
+  geant4.setupTracker('SiliconBlockDown')
+  # Now build the physics list:
+  phys = kernel.physicsList()
+  phys.extends = 'QGSP_BERT'
+  phys.enableUI()
+  phys.dump()
+  # run
+  kernel.configure()
+  kernel.initialize()
+  kernel.run()
+  kernel.terminate()
+
+if __name__ == "__main__":
+  run()
diff --git a/examples/DDG4_MySensDet/src/MyTrackerSDAction.cpp b/examples/DDG4_MySensDet/src/MyTrackerSDAction.cpp
new file mode 100644
index 000000000..f960ea8c1
--- /dev/null
+++ b/examples/DDG4_MySensDet/src/MyTrackerSDAction.cpp
@@ -0,0 +1,158 @@
+//==========================================================================
+//  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/Geant4SensDetAction.inl"
+#include "DDG4/Factories.h"
+
+using namespace CLHEP;
+
+namespace {
+  class MyTrackerSD {
+  public:
+    /// This is the hit definition.
+    /** I took here the same definition of the default Geant4Tracker class,
+     *  (see DDG4/Geant4Data.h)  but it could be anything else as well
+     *
+     *  \author  M.Frank
+     *  \version 1.0
+     *  \ingroup DD4HEP_SIMULATION
+     */
+    class MyHit : public dd4hep::sim::Geant4HitData {
+    public:
+      /// Hit position
+      dd4hep::Position      position;
+      /// Hit direction
+      dd4hep::Direction     momentum;
+      /// Length of the track segment contributing to this hit
+      double        length = 0;
+      /// Monte Carlo / Geant4 information
+      Contribution  truth;
+      /// Energy deposit in the tracker hit
+      double        energyDeposit = 0;
+    public:
+      /// Default constructor
+      MyHit() = default;
+      /// Initializing constructor
+      MyHit(int track_id, int pdg_id, double deposit, double time_stamp)
+      : length(0.0), truth(track_id, pdg_id, deposit, time_stamp, 0.), energyDeposit(deposit) {}
+      /// Default destructor
+      virtual ~MyHit() = default;
+      /// Assignment operator
+      MyHit& operator=(const MyHit& c)  {
+        if ( &c != this )  {
+          position = c.position;
+          momentum = c.momentum;
+          length = c.length;
+          truth = c.truth;
+        }
+        return *this;
+      }
+      /// Clear hit content
+      MyHit& clear() {
+        position.SetXYZ(0, 0, 0);
+        momentum.SetXYZ(0, 0, 0);
+        length = 0.0;
+        truth.clear();
+        return *this;
+      }
+
+      /// Store Geant4 point and step information into tracker hit structure.
+      MyHit& storePoint(const G4Step* step, const G4StepPoint* pnt) {
+        G4Track* trk = step->GetTrack();
+        G4ThreeVector pos = pnt->GetPosition();
+        G4ThreeVector mom = pnt->GetMomentum();
+
+        truth.trackID = trk->GetTrackID();
+        truth.pdgID   = trk->GetDefinition()->GetPDGEncoding();
+        truth.deposit = step->GetTotalEnergyDeposit();
+        truth.time    = trk->GetGlobalTime();
+        position.SetXYZ(pos.x(), pos.y(), pos.z());
+        momentum.SetXYZ(mom.x(), mom.y(), mom.z());
+        length = 0;
+        return *this;
+      }
+    };
+    
+    // If we need special data to personalize the action, be put it here
+    int mumDeposits = 0;
+    double integratedDeposit = 0;
+  };
+}
+
+/// Namespace for the AIDA detector description toolkit
+namespace dd4hep {
+
+  /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
+  namespace sim   {
+
+    // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+    //               Geant4SensitiveAction<MyTrackerSD>
+    // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+    /** \addtogroup Geant4SDActionPlugin
+     *
+     * @{
+     * \package MyTrackerSDAction
+     * \brief Sensitive detector meant for tracking detectors, will produce one hit per step
+     *
+     * @}
+     */
+
+    /// Define collections created by this sensitivie action object
+    template <> void Geant4SensitiveAction<MyTrackerSD>::defineCollections()    {
+      m_collectionID = declareReadoutFilteredCollection<MyTrackerSD::MyHit>();
+    }
+
+    /// Method for generating hit(s) using the information of G4Step object.
+    template <> bool Geant4SensitiveAction<MyTrackerSD>::process(G4Step* step,G4TouchableHistory* /*hist*/ ) {
+      Geant4StepHandler h(step);
+      Position prePos    = h.prePos();
+      Position postPos   = h.postPos();
+      Position direction = postPos - prePos;
+      Position position  = mean_direction(prePos,postPos);
+      double   hit_len   = direction.R();
+
+      // Somehow extract here the physics you want
+      MyTrackerSD::MyHit* hit = new MyTrackerSD::MyHit(h.trkID(), h.trkPdgID(), h.deposit(), h.track->GetGlobalTime());
+      HitContribution contrib = MyTrackerSD::MyHit::extractContribution(step);
+      hit->cellID        = cellID(step);
+      hit->energyDeposit = contrib.deposit;
+      hit->position      = position;
+      hit->momentum      = 0.5*(h. preMom() + h.postMom());
+      hit->length        = hit_len;
+      collection(m_collectionID)->add(hit);
+      mark(h.track);
+      if ( 0 == hit->cellID )  {
+        hit->cellID        = volumeID(step);
+        except("+++ Invalid CELL ID for hit!");
+      }
+      printP1("Hit with deposit:%f  Pos:%f %f %f ID=%016X",
+            step->GetTotalEnergyDeposit(),position.X(),position.Y(),position.Z(),
+            (void*)hit->cellID);
+      Geant4TouchableHandler handler(step);
+      print("    Geant4 path:%s",handler.path().c_str());
+
+      // Do something with my personal data (can be also something more clever ;-):
+      m_userData.integratedDeposit += contrib.deposit;
+      ++m_userData.mumDeposits;
+      return true;
+    }
+
+  }
+}
+
+//--- Factory declaration
+namespace dd4hep { namespace sim {
+    typedef Geant4SensitiveAction<MyTrackerSD> MyTrackerSDAction;
+  }}
+DECLARE_GEANT4SENSITIVE(MyTrackerSDAction)
-- 
GitLab