Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Geant4TVUserParticleHandler #1303

Merged
merged 3 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 5 additions & 47 deletions DDG4/plugins/Geant4TCUserParticleHandler.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//==========================================================================
// AIDA Detector description implementation
// AIDA Detector description implementation
//--------------------------------------------------------------------------
// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
// All rights reserved.
Expand Down Expand Up @@ -72,7 +72,7 @@ namespace dd4hep {
#endif // DD4HEP_DDG4_GEANT4TCUSERPARTICLEHANDLER_H

//====================================================================
// AIDA Detector description implementation
// AIDA Detector description implementation
//--------------------------------------------------------------------
//
// Author : M.Frank
Expand All @@ -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;
Expand All @@ -106,58 +107,15 @@ 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
&& z_end >= (m_zTrackerMin == -1e100? -m_zTrackerMax : m_zTrackerMin)
&& 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
Expand Down
118 changes: 118 additions & 0 deletions DDG4/plugins/Geant4TVUserParticleHandler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
//==========================================================================
// 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
//
//==========================================================================

/** \addtogroup Geant4Action
*
@{
\package Geant4TVUserParticleHandler
* \brief Rejects to keep particles, which are created outside a tracking cylinder.
*
*
@}
*/

#ifndef DD4HEP_DDG4_GEANT4TVUSERPARTICLEHANDLER_H
#define DD4HEP_DDG4_GEANT4TVUSERPARTICLEHANDLER_H

// Framework include files
#include <DD4hep/Primitives.h>
#include <DD4hep/Volumes.h>
#include <DDG4/Geant4UserParticleHandler.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 {

/// Rejects to keep particles, which are created outside a tracking volume.
/** Geant4TVUserParticleHandler
*
* TV stands for TrackingVolume ;-)
*
* @author M.Frank
* @version 1.0
*/
class Geant4TVUserParticleHandler : public Geant4UserParticleHandler {
Volume m_trackingVolume;

public:
/// Standard constructor
Geant4TVUserParticleHandler(Geant4Context* context, const std::string& nam);

/// Default destructor
virtual ~Geant4TVUserParticleHandler() {}

/// Post-track action callback
/** Allow the user to force the particle handling in the post track action
* set the reason mask to NULL in order to drop the particle.
* The parent's reasoning mask will be or'ed with the particle's mask
* to preserve the MC truth for the hit creation.
* The default implementation is empty.
*
* Note: The particle passed is a temporary and will be copied if kept.
*/
virtual void end(const G4Track* track, Particle& particle);

/// Post-event action callback: avoid warning (...) was hidden [-Woverloaded-virtual]
virtual void end(const G4Event* event);

};
} // End namespace sim
} // End namespace dd4hep

#endif // DD4HEP_DDG4_GEANT4TVUSERPARTICLEHANDLER_H

//====================================================================
// AIDA Detector description implementation
//--------------------------------------------------------------------
//
// Author : M.Frank
//
//====================================================================
// Framework include files
//#include <DDG4/Geant4TVUserParticleHandler.h>
#include <DDG4/Factories.h>
#include <DDG4/Geant4Particle.h>
#include <DDG4/Geant4Kernel.h>
#include "Geant4UserParticleHandlerHelper.h"


using namespace dd4hep::sim;
DECLARE_GEANT4ACTION(Geant4TVUserParticleHandler)

/// Standard constructor
Geant4TVUserParticleHandler::Geant4TVUserParticleHandler(Geant4Context* ctxt, const std::string& nam)
: Geant4UserParticleHandler(ctxt,nam)
{
m_trackingVolume = ctxt->kernel().detectorDescription().trackingVolume();
}

/// Post-track action callback
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());

std::array<double, 3> end_point = {p.vex, p.vey, p.vez};
bool ends_in_trk_vol = m_trackingVolume.ptr()->Contains(end_point.data());

setReason(p, starts_in_trk_vol, ends_in_trk_vol);
setSimulatorStatus(p, starts_in_trk_vol, ends_in_trk_vol);
}

/// Post-event action callback
void Geant4TVUserParticleHandler::end(const G4Event* /* event */) {

}

71 changes: 71 additions & 0 deletions DDG4/plugins/Geant4UserParticleHandlerHelper.cpp
Original file line number Diff line number Diff line change
@@ -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);
}
}

}
36 changes: 36 additions & 0 deletions DDG4/plugins/Geant4UserParticleHandlerHelper.h
Original file line number Diff line number Diff line change
@@ -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
10 changes: 9 additions & 1 deletion DDG4/python/DDSim/Helper/ParticleHandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def setupUserParticleHandler(self, part, kernel, DDG4):
if not self.userParticleHandler:
return

if self.userParticleHandler not in ["Geant4TCUserParticleHandler"]:
if self.userParticleHandler not in ["Geant4TCUserParticleHandler", "Geant4TVUserParticleHandler"]:
logger.error("unknown UserParticleHandler: %r" % self.userParticleHandler)
exit(1)

Expand Down Expand Up @@ -153,4 +153,12 @@ def setupUserParticleHandler(self, part, kernel, DDG4):

part.adopt(user)

elif self.userParticleHandler == "Geant4TVUserParticleHandler":
if not kernel.detectorDescription().trackingVolume().isValid():
logger.error("Geant4TVUserParticleHandler requested but no tracking_volume defined in the XML")
exit(1)

user = DDG4.Action(kernel, "%s/UserParticleHandler" % self.userParticleHandler)
part.adopt(user)

return
Loading