From 9f142b8d4caad59970244e593cac170bf5d262c4 Mon Sep 17 00:00:00 2001
From: Leonhard Reichenbach <leonhard.reichenbach@cern.ch>
Date: Mon, 29 Jul 2024 14:53:59 +0200
Subject: [PATCH] put common stuff into helper functions

---
 DDG4/plugins/Geant4TCUserParticleHandler.cpp  | 52 ++------------
 DDG4/plugins/Geant4TVUserParticleHandler.cpp  | 48 +------------
 .../Geant4UserParticleHandlerHelper.cpp       | 71 +++++++++++++++++++
 .../plugins/Geant4UserParticleHandlerHelper.h | 36 ++++++++++
 4 files changed, 115 insertions(+), 92 deletions(-)
 create mode 100644 DDG4/plugins/Geant4UserParticleHandlerHelper.cpp
 create mode 100644 DDG4/plugins/Geant4UserParticleHandlerHelper.h

diff --git a/DDG4/plugins/Geant4TCUserParticleHandler.cpp b/DDG4/plugins/Geant4TCUserParticleHandler.cpp
index 425ae2686..60fd6a7ea 100644
--- a/DDG4/plugins/Geant4TCUserParticleHandler.cpp
+++ b/DDG4/plugins/Geant4TCUserParticleHandler.cpp
@@ -1,5 +1,5 @@
 //==========================================================================
-//  AIDA Detector description implementation 
+//  AIDA Detector description implementation
 //--------------------------------------------------------------------------
 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
 // All rights reserved.
@@ -72,7 +72,7 @@ namespace dd4hep {
 #endif // DD4HEP_DDG4_GEANT4TCUSERPARTICLEHANDLER_H
 
 //====================================================================
-//  AIDA Detector description implementation 
+//  AIDA Detector description implementation
 //--------------------------------------------------------------------
 //
 //  Author     : M.Frank
@@ -82,6 +82,7 @@ namespace dd4hep {
 //#include <DDG4/Geant4TCUserParticleHandler.h>
 #include <DDG4/Geant4Particle.h>
 #include <DDG4/Factories.h>
+#include "Geant4UserParticleHandlerHelper.h"
 
 
 using namespace dd4hep::sim;
@@ -106,16 +107,6 @@ void Geant4TCUserParticleHandler::end(const G4Track* /* track */, Particle& p)
     && z_prod <= m_zTrackerMax
   )  ;
 
-  dd4hep::detail::ReferenceBitMask<int> reason(p.reason);
-
-  if( reason.isSet(G4PARTICLE_PRIMARY) ) {
-    //do nothing
-  } else if( starts_in_trk_vol && ! reason.isSet(G4PARTICLE_ABOVE_ENERGY_THRESHOLD) )  {
-    // created in tracking volume but below energy cut
-    p.reason = 0;
-    return;
-  }
-
   double r_end  = std::sqrt(p.vex*p.vex + p.vey*p.vey);
   double z_end  = p.vez;
   bool ends_in_trk_vol =  ( r_end <= m_rTracker
@@ -123,41 +114,8 @@ void Geant4TCUserParticleHandler::end(const G4Track* /* track */, Particle& p)
      && z_end <= m_zTrackerMax
   ) ;
 
-  // created and ended in calo but not primary particle
-  //
-  // we can have particles from the generator only in the calo, if we have a
-  // long particle with preassigned decay, we need to keep the reason or the
-  // MChistory will not be updated later on
-  if( not reason.isSet(G4PARTICLE_PRIMARY) ) {
-    if( !starts_in_trk_vol ) {
-      if( !ends_in_trk_vol ){
-	p.reason = 0;
-      }
-      //fg: dont keep backscatter that did not create a tracker hit
-      else if( ! reason.isSet(G4PARTICLE_CREATED_TRACKER_HIT) ) {
-	p.reason = 0;
-      }
-    }
-  }
-
-  // Set the simulator status bits
-  dd4hep::detail::ReferenceBitMask<int> simStatus(p.status);
-
-  if( ends_in_trk_vol ) {
-    simStatus.set(G4PARTICLE_SIM_DECAY_TRACKER);
-  }
-
-  // if the particle doesn't end in the tracker volume it must have ended in the calorimeter
-  if( not ends_in_trk_vol && not simStatus.isSet(G4PARTICLE_SIM_LEFT_DETECTOR) ) {
-    simStatus.set(G4PARTICLE_SIM_DECAY_CALO);
-  }
-
-  if( not starts_in_trk_vol && ends_in_trk_vol ) {
-    simStatus.set(G4PARTICLE_SIM_BACKSCATTER);
-  }
-
-  return ;
-
+  setReason(p, starts_in_trk_vol, ends_in_trk_vol);
+  setSimulatorStatus(p, starts_in_trk_vol, ends_in_trk_vol);
 }
 
 /// Post-event action callback
diff --git a/DDG4/plugins/Geant4TVUserParticleHandler.cpp b/DDG4/plugins/Geant4TVUserParticleHandler.cpp
index 35b6a2165..46c155446 100644
--- a/DDG4/plugins/Geant4TVUserParticleHandler.cpp
+++ b/DDG4/plugins/Geant4TVUserParticleHandler.cpp
@@ -85,6 +85,7 @@ namespace dd4hep {
 #include <DDG4/Factories.h>
 #include <DDG4/Geant4Particle.h>
 #include <DDG4/Geant4Kernel.h>
+#include "Geant4UserParticleHandlerHelper.h"
 
 
 using namespace dd4hep::sim;
@@ -103,54 +104,11 @@ void Geant4TVUserParticleHandler::end(const G4Track* /* track */, Particle& p)
   std::array<double, 3> start_point = {p.vsx, p.vsy, p.vsz};
   bool starts_in_trk_vol = m_trackingVolume.ptr()->Contains(start_point.data());
 
-  dd4hep::detail::ReferenceBitMask<int> reason(p.reason);
-
-  if( reason.isSet(G4PARTICLE_PRIMARY) ) {
-    //do nothing
-  } else if( starts_in_trk_vol && ! reason.isSet(G4PARTICLE_ABOVE_ENERGY_THRESHOLD) )  {
-    // created in tracking volume but below energy cut
-    p.reason = 0;
-    return;
-  }
-
   std::array<double, 3> end_point = {p.vex, p.vey, p.vez};
   bool ends_in_trk_vol = m_trackingVolume.ptr()->Contains(end_point.data());
 
-  // created and ended in calo but not primary particle
-  //
-  // we can have particles from the generator only in the calo, if we have a
-  // long particle with preassigned decay, we need to keep the reason or the
-  // MChistory will not be updated later on
-  if( not reason.isSet(G4PARTICLE_PRIMARY) ) {
-    if( !starts_in_trk_vol ) {
-      if( !ends_in_trk_vol ){
-	p.reason = 0;
-      }
-      //fg: dont keep backscatter that did not create a tracker hit
-      else if( ! reason.isSet(G4PARTICLE_CREATED_TRACKER_HIT) ) {
-	p.reason = 0;
-      }
-    }
-  }
-
-  // Set the simulator status bits
-  dd4hep::detail::ReferenceBitMask<int> simStatus(p.status);
-
-  if( ends_in_trk_vol ) {
-    simStatus.set(G4PARTICLE_SIM_DECAY_TRACKER);
-  }
-
-  // if the particle doesn't end in the tracker volume it must have ended in the calorimeter
-  if( not ends_in_trk_vol && not simStatus.isSet(G4PARTICLE_SIM_LEFT_DETECTOR) ) {
-    simStatus.set(G4PARTICLE_SIM_DECAY_CALO);
-  }
-
-  if( not starts_in_trk_vol && ends_in_trk_vol ) {
-    simStatus.set(G4PARTICLE_SIM_BACKSCATTER);
-  }
-
-  return ;
-
+  setReason(p, starts_in_trk_vol, ends_in_trk_vol);
+  setSimulatorStatus(p, starts_in_trk_vol, ends_in_trk_vol);
 }
 
 /// Post-event action callback
diff --git a/DDG4/plugins/Geant4UserParticleHandlerHelper.cpp b/DDG4/plugins/Geant4UserParticleHandlerHelper.cpp
new file mode 100644
index 000000000..de6f7920b
--- /dev/null
+++ b/DDG4/plugins/Geant4UserParticleHandlerHelper.cpp
@@ -0,0 +1,71 @@
+
+//==========================================================================
+//  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
+//
+//==========================================================================
+
+#include "Geant4UserParticleHandlerHelper.h"
+#include <DDG4/Geant4Particle.h>
+#include <DDG4/Geant4UserParticleHandler.h>
+
+// using namespace dd4hep::sim;
+
+namespace dd4hep::sim {
+
+void setReason(Geant4Particle& p, bool starts_in_trk_vol, bool ends_in_trk_vol) {
+
+  dd4hep::detail::ReferenceBitMask<int> reason(p.reason);
+
+  if( reason.isSet(G4PARTICLE_PRIMARY) ) {
+    //do nothing
+  } else if( starts_in_trk_vol && ! reason.isSet(G4PARTICLE_ABOVE_ENERGY_THRESHOLD) )  {
+    // created in tracking volume but below energy cut
+    p.reason = 0;
+    return;
+  }
+
+  // created and ended in calo but not primary particle
+  //
+  // we can have particles from the generator only in the calo, if we have a
+  // long particle with preassigned decay, we need to keep the reason or the
+  // MChistory will not be updated later on
+  if( not reason.isSet(G4PARTICLE_PRIMARY) ) {
+    if( !starts_in_trk_vol ) {
+      if( !ends_in_trk_vol ){
+	p.reason = 0;
+      }
+      //fg: dont keep backscatter that did not create a tracker hit
+      else if( ! reason.isSet(G4PARTICLE_CREATED_TRACKER_HIT) ) {
+	p.reason = 0;
+      }
+    }
+  }
+}
+
+void setSimulatorStatus(Geant4Particle& p, bool starts_in_trk_vol, bool ends_in_trk_vol) {
+  // Set the simulator status bits
+  dd4hep::detail::ReferenceBitMask<int> simStatus(p.status);
+
+  if( ends_in_trk_vol ) {
+    simStatus.set(G4PARTICLE_SIM_DECAY_TRACKER);
+  }
+
+  // if the particle doesn't end in the tracker volume it must have ended in the calorimeter
+  if( not ends_in_trk_vol && not simStatus.isSet(G4PARTICLE_SIM_LEFT_DETECTOR) ) {
+    simStatus.set(G4PARTICLE_SIM_DECAY_CALO);
+  }
+
+  if( not starts_in_trk_vol && ends_in_trk_vol ) {
+    simStatus.set(G4PARTICLE_SIM_BACKSCATTER);
+  }
+}
+
+}
\ No newline at end of file
diff --git a/DDG4/plugins/Geant4UserParticleHandlerHelper.h b/DDG4/plugins/Geant4UserParticleHandlerHelper.h
new file mode 100644
index 000000000..4497dc0de
--- /dev/null
+++ b/DDG4/plugins/Geant4UserParticleHandlerHelper.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
+//
+//==========================================================================
+
+#ifndef DDG4_GEANT4USERPARTICLEHANDLERHELPER_H
+#define DDG4_GEANT4USERPARTICLEHANDLERHELPER_H
+
+/// Namespace for the AIDA detector description toolkit
+namespace dd4hep {
+
+  /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
+  namespace sim {
+
+    // Forward declarations
+    class Geant4Particle;
+
+    /// determines if particle should be kept and sets p.reason = 0 otherwise
+    void setReason(Geant4Particle& p, bool starts_in_trk_volume, bool ends_in_trk_volume);
+
+    /// determines if particle has ended in the tracker, calorimeter or if it is backscatter and sets simulator status accordingly
+    void setSimulatorStatus(Geant4Particle& p, bool starts_in_trk_volume, bool ends_in_trk_volume);
+
+  }
+}
+
+#endif // DDG4_GEANT4USERPARTICLEHANDLERHELPER_H
\ No newline at end of file
-- 
GitLab