9#include <simulation/kernel/TrackingAction.h>
10#include <simulation/kernel/UserInfo.h>
11#include <simulation/kernel/SensitiveDetectorBase.h>
12#include <simulation/dataobjects/MCParticleTrajectory.h>
13#include <framework/logging/Logger.h>
14#include <framework/gearbox/Unit.h>
16#include <G4TrackingManager.hh>
18#include <G4ParticleDefinition.hh>
19#include <G4ParticleTypes.hh>
20#include <G4EmProcessSubType.hh>
21#include <G4DecayProcessType.hh>
23#include <G4ParticleTable.hh>
26using namespace Belle2::Simulation;
65 if (track->GetCurrentStepNumber() > 0)
68 const G4DynamicParticle* dynamicParticle = track->GetDynamicParticle();
73 const bool isPrimary = dynamicParticle->GetPrimaryParticle() !=
nullptr;
74 bool neutral_llp =
false;
76 const G4PrimaryParticle* primaryParticle = dynamicParticle->GetPrimaryParticle();
77 if (primaryParticle->GetUserInformation() !=
nullptr) {
78 const_cast<G4Track*
>(track)->SetUserInformation(
new TrackInfo(
ParticleInfo::getInfo(*primaryParticle)));
80 if (primaryParticle->GetParticleDefinition() == G4ParticleTable::GetParticleTable()->FindParticle(
"LongLivedNeutralParticle")) {
84 B2WARNING(track->GetDefinition()->GetPDGEncoding() <<
" has no MCParticle user information !");
91 G4ThreeVector dpMom = dynamicParticle->GetMomentum() / CLHEP::MeV *
Unit::MeV;
98 G4ThreeVector trVtxPos = track->GetVertexPosition() / CLHEP::mm *
Unit::mm;
105 currParticle.
setPDG(dynamicParticle->GetPDGcode());
108 currParticle.
setMomentum(dpMom.x(), dpMom.y(), dpMom.z());
116 }
else if (track->GetCreatorProcess() !=
nullptr) {
118 const int& processSubType = track->GetCreatorProcess()->GetProcessSubType();
122 if (processSubType >=
static_cast<int>(DECAY) && processSubType <=
static_cast<int>(DECAY_External))
134 (
m_storeTrajectories == 2 && track->GetDefinition() != G4OpticalPhoton::OpticalPhotonDefinition())) {
135 TrackInfo& info =
dynamic_cast<TrackInfo&
>(*track->GetUserInformation());
139 }
catch (CouldNotFindUserInfo& exc) {
146 G4StepPoint* postStep = track->GetStep()->GetPostStepPoint();
158 const bool producedInRegion = producedInBarrel || producedInEndCap;
160 G4ThreeVector decVtx = postStep->GetPosition() / CLHEP::mm *
Unit::mm;
163 const bool hasTraveledDistance = distance >
165 const bool isEM = ((currParticle.
getPDG() == 11) || (currParticle.
getPDG() == -11) || (currParticle.
getPDG() == 22));
166 const bool isNuclei = (currParticle.
getPDG() > 100'000'000'0);
168 B2DEBUG(10,
"Particle: " << currParticle.
getIndex() <<
"Particle pdg: " << currParticle.
getPDG() <<
"current ignore flag: " <<
169 currParticle.
getIgnore() <<
" produced in Region: " <<
170 producedInRegion <<
" above threshold: " <<
171 isAboveKinematicThreshold
172 <<
" traveled distance: " << hasTraveledDistance <<
" is EM: " << isEM <<
" is Nuclei: " << isNuclei <<
" seen in ECL: " <<
179 " Do Not Store Nuclei: "
184 if (isAboveKinematicThreshold) {
186 if (!producedInRegion) {
200 if (hasTraveledDistance) {
218 if (!isEM || !isNuclei) {
230 B2DEBUG(10,
"Ignore Flag: " << currParticle.
getIgnore());
232 for (G4Track* daughterTrack : *fpTrackingManager->GimmeSecondaries()) {
236 if (daughterTrack->GetDynamicParticle()->GetPrimaryParticle() == NULL &&
237 daughterTrack->GetUserInformation() == NULL) {
239 const_cast<G4Track*
>(daughterTrack)->SetUserInformation(
new TrackInfo(daughterParticle));
244 if (daughterTrack->GetDefinition() == G4OpticalPhoton::OpticalPhotonDefinition()) {
250 if (track->GetDefinition() == G4OpticalPhoton::OpticalPhotonDefinition()) {
251 TrackInfo* currInfo =
dynamic_cast<TrackInfo*
>(track->GetUserInformation());
252 TrackInfo* daughterInfo =
dynamic_cast<TrackInfo*
>(daughterTrack->GetUserInformation());
256 }
else if (daughterTrack->GetCreatorProcess()->GetProcessSubType() == fBremsstrahlung) {
263 }
else if (daughterTrack->GetCreatorProcess()->GetProcessSubType() == fGammaConversion) {
282 if (track->GetTrackStatus() == fSuspend)
286 if (postStep->GetStepStatus() == fWorldBoundary) {
291 if (track->GetKineticEnergy() <= 0.0) {
296 G4ThreeVector decVtx = postStep->GetPosition() / CLHEP::mm *
Unit::mm;
303 MCParticleTrajectory* tr =
dynamic_cast<TrackInfo*
>(track->GetUserInformation())->getTrajectory();
308 }
catch (CouldNotFindUserInfo& exc) {
Class to represent Particle data in graph.
void decaysInto(GraphParticle &daughter)
Tells the graph that this particle decays into daughter.
void setTrackID(int trackID)
Set the track ID for the particle.
void setIgnore(bool ignore=true)
Set or remove the ignore flag.
bool getIgnore() const
Get the ignore flag.
Class to build, validate and sort a particle decay chain.
Class to save the full simulated trajectory of a particle.
void simplify(float distanceTolerance)
Simplify the trajectory using the Ramer-Douglas-Peuker algorithm.
A Class to store the Monte Carlo particle information.
@ c_LeftDetector
bit 2: Particle left the detector (the simulation volume).
@ c_StoppedInDetector
bit 3: Particle was stopped in the detector (the simulation volume).
void setDecayTime(float time)
Set decay time.
void setMass(float mass)
Set particle mass.
void setDecayVertex(const ROOT::Math::XYZVector &vertex)
Set decay vertex.
int getIndex() const
Get 1-based index of the particle in the corresponding MCParticle list.
ROOT::Math::XYZVector getDecayVertex() const
Return decay vertex.
void addStatus(unsigned short int bitmask)
Add bitmask to current status.
void setEnergy(float energy)
Set energy.
bool hasSeenInDetector(Const::DetectorSet set) const
Return if the seen-in flag for a specific subdetector is set or not.
ROOT::Math::XYZVector getProductionVertex() const
Return production vertex position.
void setValidVertex(bool valid)
Set indication whether vertex and time information is valid or just default.
void setProductionVertex(const ROOT::Math::XYZVector &vertex)
Set production vertex position.
void setSecondaryPhysicsProcess(int physicsProcess)
Sets the physics process type of a secondary particle.
void setPDG(int pdg)
Set PDG code of the particle.
int getPDG() const
Return PDG code of particle.
float getProductionTime() const
Return production time in ns.
ROOT::Math::XYZVector getMomentum() const
Return momentum.
void setMomentum(const ROOT::Math::XYZVector &momentum)
Set particle momentum.
void setProductionTime(float time)
Set production time.
@ c_negativeWeight
Flip the sign of the weight to become negative if the original element got re-attributed.
static void registerMCParticleRelation(const std::string &name, RelationArray::EConsolidationAction ignoreAction=RelationArray::c_negativeWeight)
Register an relation involving MCParticles.
virtual ~TrackingAction()
Destructor.
double m_regionZBackward
Region backward z limit.
bool m_ignoreSecondaries
do not store secondaries in MCParticles
bool m_doNotStoreNuclei
use is Nuclei check
MCParticleGraph & m_mcParticleGraph
Reference to the MCParticle graph which is updated by the tracking action.
bool m_doNotStoreEMParticles
use is EM check
TrackingAction(MCParticleGraph &mcParticleGraph)
Constructor.
double m_distanceThreshold
distance threshold
double m_pairConversionsEnergyCut
kinetic energy cut for stored e+ or e- from pair conversions [MeV]
void setStoreTrajectories(int store, double distanceTolerance)
Sets the trajectory option to enable storing of the simulated particle trajectories.
RelationArray m_relMCTrajectories
RelationArry for the relation between MCParticles and Trajectories.
bool m_useDetailedParticleMatching
use detailed particle matching logic to filter secondaries
bool m_useSeenInECL
use seen in ECL check
StoreArray< MCParticleTrajectory > m_storeMCTrajectories
Store array for the Trajectories.
double m_distanceTolerance
distance tolerance to merge trajectory points
void PreUserTrackingAction(const G4Track *track)
Checks if the particle associated to the track is already in the MCParticle list.
double m_secondariesEnergyCut
kinetic energy cut for stored secondaries [MeV]
double m_kineticEnergyThreshold
kinetic energy threshold
double m_regionRho
Region rho limit.
void PostUserTrackingAction(const G4Track *track)
Updates the data of the MCParticle associated with the Geant4 track.
bool m_ignorePairConversions
do not store e+ or e- from pair conversions in MCparticles
bool m_ignoreBremsstrahlungPhotons
do not store bremsstrahlung photons in MCParticles
bool m_ignoreOpticalPhotons
do not store optical photons in MCParticles
double m_bremsstrahlungPhotonsEnergyCut
kinetic energy cut for stored bremsstrahlung photons [MeV]
double m_regionZForward
Region forward z limit.
int m_storeTrajectories
Store trajectories for 0=none, 1=primary or 2=all particles.
void setFraction(double fraction)
Store optical photon propagation fraction (used for performance speed-ups)
void setStatus(int status)
Set status of optical photon (used for performance speed-ups)
double getFraction()
Get optical photon propagation fraction (used for performance speed-ups) status=0: fraction=1 status=...
static MCParticleGraph::GraphParticle & getInfo(Carrier &obj)
int getStatus()
Get status of optical photon (used for performance speed-ups) 0 initial 1 prescaled in StackingAction...
Accessor to arrays stored in the data store.
bool registerRelationTo(const StoreArray< TO > &toArray, DataStore::EDurability durability=DataStore::c_Event, DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut, const std::string &namedRelation="") const
Register a relation to the given StoreArray.
static const double mm
[millimeters]
static const double MeV
[megaelectronvolt]
Abstract base class for different kinds of events.