From 13cb06e1589ba09c4c4aa8bf9194b54cdb0a6ac2 Mon Sep 17 00:00:00 2001
From: Andre Sailer <andre.philippe.sailer@cern.ch>
Date: Thu, 19 Jan 2023 17:54:52 +0100
Subject: [PATCH] Examples: add test for steppingaction with suspend to test
 ParticleHandler

---
 DDG4/src/Geant4ParticleHandler.cpp       |  5 +-
 examples/DDG4/CMakeLists.txt             |  8 +++
 examples/DDG4/scripts/TestStepping.py    | 86 ++++++++++++++++++++++++
 examples/DDG4/src/TestSteppingAction.cpp | 59 ++++++++++++++++
 4 files changed, 155 insertions(+), 3 deletions(-)
 create mode 100644 examples/DDG4/scripts/TestStepping.py
 create mode 100644 examples/DDG4/src/TestSteppingAction.cpp

diff --git a/DDG4/src/Geant4ParticleHandler.cpp b/DDG4/src/Geant4ParticleHandler.cpp
index 3820503fd..4fd39c54a 100644
--- a/DDG4/src/Geant4ParticleHandler.cpp
+++ b/DDG4/src/Geant4ParticleHandler.cpp
@@ -115,9 +115,8 @@ bool Geant4ParticleHandler::adopt(Geant4Action* action)    {
 void Geant4ParticleHandler::clear()  {
   detail::releaseObjects(m_particleMap);
   m_particleMap.clear();
-  //m_suspendedPM should already be empty and cleared...
-  detail::releaseObjects(m_suspendedPM);
-  m_suspendedPM.clear();
+  // m_suspendedPM should already be empty and cleared...
+  assert(m_suspendedPM.empty() && "There was something wrong with the particle record treatment, please open a bug report!");
   m_equivalentTracks.clear();
 }
 
diff --git a/examples/DDG4/CMakeLists.txt b/examples/DDG4/CMakeLists.txt
index ca4290a5c..23d18e39d 100644
--- a/examples/DDG4/CMakeLists.txt
+++ b/examples/DDG4/CMakeLists.txt
@@ -96,6 +96,14 @@ if (DD4HEP_USE_GEANT4)
     REGEX_FAIL " ERROR ;EXCEPTION;Exception"
   )
   #
+  # Test G4 stepping action
+  dd4hep_add_test_reg( DDG4_TestSteppingAction
+    COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_DDG4.sh"
+    EXEC_ARGS  ${Python_EXECUTABLE} ${DDG4examples_INSTALL}/scripts/TestStepping.py -batch -events 3
+    REGEX_PASS " Track Calls Suspended: [1-9][0-9]*"
+    REGEX_FAIL " ERROR ;EXCEPTION;Exception"
+  )
+  #
   # Test G4 command UI
   dd4hep_add_test_reg( DDG4_UIManager
     COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_DDG4.sh"
diff --git a/examples/DDG4/scripts/TestStepping.py b/examples/DDG4/scripts/TestStepping.py
new file mode 100644
index 000000000..54cc739b9
--- /dev/null
+++ b/examples/DDG4/scripts/TestStepping.py
@@ -0,0 +1,86 @@
+# ==========================================================================
+#  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, unicode_literals
+import logging
+#
+logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
+logger = logging.getLogger(__name__)
+#
+#
+"""
+
+   dd4hep simulation example setup using the python configuration
+
+"""
+
+
+def run():
+  import os
+  import DDG4
+  from DDG4 import OutputLevel as Output
+  from g4units import GeV, keV
+
+  kernel = DDG4.Kernel()
+  install_dir = os.environ['DD4hepExamplesINSTALL']
+  kernel.loadGeometry(str("file:" + install_dir + "/examples/ClientTests/compact/SiliconBlock.xml"))
+
+  DDG4.importConstants(kernel.detectorDescription(), debug=False)
+  geant4 = DDG4.Geant4(kernel, tracker='Geant4TrackerCombineAction')
+  geant4.printDetectors()
+  # Configure UI
+  geant4.setupUI(typ="tcsh", vis=False, macro=None, ui=False)
+
+  # Configure 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
+  act.DebugSurfaces = True
+
+  # Setup particle gun
+  gun = geant4.setupGun("Gun", particle='gamma', energy=1 * GeV, multiplicity=1)
+  gun.direction = (0.0, 0.0, 1.0)
+  gun.OutputLevel = generator_output_level
+  kernel.NumEvents = 2
+  # Instantiate the stepping action
+  stepping = DDG4.SteppingAction(kernel, 'TestSteppingAction/MyStepper')
+  kernel.steppingAction().add(stepping)
+
+  # And handle the simulation particles.
+  part = DDG4.GeneratorAction(kernel, "Geant4ParticleHandler/ParticleHandler")
+  kernel.generatorAction().adopt(part)
+  part.SaveProcesses = ['conv', 'Decay']
+  part.MinimalKineticEnergy = 1 * keV
+  part.KeepAllParticles = False
+  part.PrintEndTracking = True
+  part.enableUI()
+
+  # Now build the physics list:
+  phys = geant4.setupPhysics('QGSP_BERT')
+  phys.dump()
+  # Start the engine...
+  geant4.execute()
+
+
+if __name__ == "__main__":
+  run()
diff --git a/examples/DDG4/src/TestSteppingAction.cpp b/examples/DDG4/src/TestSteppingAction.cpp
new file mode 100644
index 000000000..8c2693dce
--- /dev/null
+++ b/examples/DDG4/src/TestSteppingAction.cpp
@@ -0,0 +1,59 @@
+//==========================================================================
+//  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.
+//
+//==========================================================================
+
+// Framework include files
+#include "DDG4/Geant4SteppingAction.h"
+
+#include <G4Step.hh>
+#include <G4TrackStatus.hh>
+
+/// Namespace for the AIDA detector description toolkit
+namespace dd4hep {
+
+  /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
+  namespace sim {
+    
+    /// Class to count steps and suspend tracks every 5 steps
+    /** Class to count steps and suspens tracks every 5 steps
+     * Count steps and suspend
+     *
+     *  \version 1.0
+     *  \ingroup DD4HEP_SIMULATION
+     */
+    class TestSteppingAction : public Geant4SteppingAction {
+      std::size_t m_calls_steps { 0UL };
+      std::size_t m_calls_suspended { 0UL };
+    
+    public:
+      /// Standard constructor
+      TestSteppingAction(Geant4Context* context, const std::string& nam)
+	: Geant4SteppingAction(context, nam) 
+      {
+      }
+      /// Default destructor
+      virtual ~TestSteppingAction()   {
+	info("+++ Track Calls Steps: %ld", m_calls_steps);
+	info("+++ Track Calls Suspended: %ld", m_calls_suspended);
+      }
+      /// stepping callback
+      virtual void operator()(const G4Step* step, G4SteppingManager*) {
+        if(m_calls_steps % 5 == 0 ) {
+          ++m_calls_suspended;
+          step->GetTrack()->SetTrackStatus(fSuspend);
+        }
+	++m_calls_steps;
+      }
+    };
+  }    // End namespace sim
+}      // End namespace dd4hep
+
+#include "DDG4/Factories.h"
+DECLARE_GEANT4ACTION_NS(dd4hep::sim,TestSteppingAction)
-- 
GitLab