LDMX Software
simcore::TrackMap Class Reference

Defines a map of particle ancestry and particles to be saved. More...

#include <TrackMap.h>

Public Member Functions

void insert (const G4Track *track)
 Add a record in the map for the input track.
 
bool contains (const G4Track *track) const
 Check if the passed track has already been inserted into the track map.
 
bool isDescendant (int trackID, int ancestorID, int maximum_depth) const
 Check if the track with the given ID is a descendant of the track with the given ancestor ID up to a given depth.
 
int findIncident (int trackID) const
 Find a trajectory's nearest parent that is incident on the calorimeter region.
 
bool isSaved (int trackID) const
 Return true if the given track ID is saved i.e.
 
void save (const G4Track *track)
 Add a track to be stored into output map.
 
void traceAncestry ()
 Trace the ancestry for the particles that will be stored.
 
void clear ()
 Clear the internal maps.
 
std::map< int, ldmx::SimParticle > & getParticleMap ()
 Get the map of particles to be stored in output event.
 

Private Member Functions

bool isInCalorimeterRegion (const G4Track *track) const
 Was the input track generated inside the calorimeter region?
 

Private Attributes

std::unordered_map< int, std::pair< int, bool > > ancestry_
 ancestry map of particles in event (child -> parent)
 
std::unordered_map< int, std::vector< int > > descendents_
 descendents map of particles in event (parent -> children)
 
std::map< int, ldmx::SimParticle > particle_map_
 map of SimParticles that will be stored
 

Detailed Description

Defines a map of particle ancestry and particles to be saved.

This class keeps track of the ancestry (child -> parent) and descendents (parent -> children) of ALL particles generated in an event. This allows the particles that are chosen to be saved (via the TrackMap::save method) to have their parent and children faithfully recorded in the output file.

Definition at line 25 of file TrackMap.h.

Member Function Documentation

◆ clear()

void simcore::TrackMap::clear ( )

Clear the internal maps.

This should be called at the beginning of an event. The maps need to persist through the end of the event so that they are available to be written to the output file.

Definition at line 128 of file TrackMap.cxx.

128 {
129 ancestry_.clear();
130 descendents_.clear();
131 particle_map_.clear();
132}
std::unordered_map< int, std::pair< int, bool > > ancestry_
ancestry map of particles in event (child -> parent)
Definition TrackMap.h:129
std::unordered_map< int, std::vector< int > > descendents_
descendents map of particles in event (parent -> children)
Definition TrackMap.h:132
std::map< int, ldmx::SimParticle > particle_map_
map of SimParticles that will be stored
Definition TrackMap.h:135

References ancestry_, descendents_, and particle_map_.

Referenced by simcore::g4user::EventAction::BeginOfEventAction().

◆ contains()

bool simcore::TrackMap::contains ( const G4Track * track) const
inline

Check if the passed track has already been inserted into the track map.

Definition at line 37 of file TrackMap.h.

37 {
38 return ancestry_.find(track->GetTrackID()) != ancestry_.end();
39 }

References ancestry_.

Referenced by simcore::g4user::TrackingAction::PreUserTrackingAction().

◆ findIncident()

int simcore::TrackMap::findIncident ( int trackID) const

Find a trajectory's nearest parent that is incident on the calorimeter region.

We assume that the primary particles have a parent ID of 0.

If this track ID does not have such a trajectory, then the track ID of the primary in its parentage is returned.

Parameters
trackIDThe track ID to search its parentage for the incident

Definition at line 36 of file TrackMap.cxx.

36 {
37 int curr_track_id = trackID;
38 bool found_incident{false};
39 while (not found_incident) {
40 auto& [parentID, inCalRegion] = ancestry_.at(curr_track_id);
41 if (not inCalRegion or parentID == 0) {
42 // current track ID is nearest ancestor
43 // originating outside cal region
44 // or is a primary particle
45 found_incident = true;
46 } else {
47 // still in cal region, keep going
48 curr_track_id = parentID;
49 }
50 }
51 return curr_track_id;
52}

References ancestry_.

◆ getParticleMap()

std::map< int, ldmx::SimParticle > & simcore::TrackMap::getParticleMap ( )
inline

Get the map of particles to be stored in output event.

Definition at line 98 of file TrackMap.h.

98{ return particle_map_; }

References particle_map_.

Referenced by simcore::UserAction::getCurrentParticleMap().

◆ insert()

void simcore::TrackMap::insert ( const G4Track * track)

Add a record in the map for the input track.

Parameters
trackG4Track to insert

Definition at line 30 of file TrackMap.cxx.

30 {
31 ancestry_[track->GetTrackID()] =
32 std::make_pair(track->GetParentID(), isInCalorimeterRegion(track));
33 descendents_[track->GetParentID()].push_back(track->GetTrackID());
34}
bool isInCalorimeterRegion(const G4Track *track) const
Was the input track generated inside the calorimeter region?
Definition TrackMap.cxx:134

References ancestry_, descendents_, and isInCalorimeterRegion().

Referenced by simcore::g4user::TrackingAction::PreUserTrackingAction().

◆ isDescendant()

bool simcore::TrackMap::isDescendant ( int trackID,
int ancestorID,
int maximum_depth ) const

Check if the track with the given ID is a descendant of the track with the given ancestor ID up to a given depth.

Definition at line 10 of file TrackMap.cxx.

11 {
12 int current_depth{0};
13 int current_track{trackID};
14 // Walk the tree until we either no longer have a parent or we reach the
15 // desired depth
16 while (current_depth < maximum_depth &&
17 (ancestry_.find(current_track) != ancestry_.end())) {
18 // See if we have encountered the parent of the current track
19 //
20 // operator[] is not const, so we need to use at()
21 current_track = ancestry_.at(current_track).first;
22 if (current_track == ancestorID) {
23 // If one of the parents is the track of interest, we are done!
24 return true;
25 }
26 current_depth++;
27 }
28 return false;
29}

References ancestry_.

◆ isInCalorimeterRegion()

bool simcore::TrackMap::isInCalorimeterRegion ( const G4Track * track) const
private

Was the input track generated inside the calorimeter region?

We rely on the fact that the calorimeter region is named 'CalorimeterRegion' and no other region names contain the string 'Calorimeter'

Definition at line 134 of file TrackMap.cxx.

134 {
135 auto region{track->GetLogicalVolumeAtVertex()->GetRegion()->GetName()};
136 return region.contains("Calorimeter");
137}

Referenced by insert().

◆ isSaved()

bool simcore::TrackMap::isSaved ( int trackID) const
inline

Return true if the given track ID is saved i.e.

will be stored in output file

Parameters
trackIDThe track ID.
Returns
True if the track ID has been inserted in output particle map

Definition at line 65 of file TrackMap.h.

65 {
66 return particle_map_.find(trackID) != particle_map_.end();
67 }

References particle_map_.

◆ save()

void simcore::TrackMap::save ( const G4Track * track)

Add a track to be stored into output map.

Note
We assume that the track is at the end of processing so that its current kinematics can be labeled as the "end-point" kinematics.
Parameters
trackG4Track to store into output

Definition at line 54 of file TrackMap.cxx.

54 {
55 // create sim particle in map, keep reference to the newly created particle
56 ldmx::SimParticle& particle{particle_map_[track->GetTrackID()]};
57
58 // TODO: default gen status?
59 particle.setGenStatus(0);
60
61 // Update the gen status from the primary particle.
62 if (track->GetDynamicParticle()->GetPrimaryParticle() != nullptr) {
63 G4VUserPrimaryParticleInformation* primary_info =
64 track->GetDynamicParticle()->GetPrimaryParticle()->GetUserInformation();
65 if (primary_info != nullptr) {
66 particle.setGenStatus(
67 ((UserPrimaryParticleInformation*)primary_info)->getHepEvtStatus());
68 }
69 }
70
71 auto particle_def{track->GetDefinition()};
72
73 particle.setPdgID(particle_def->GetPDGEncoding());
74 particle.setCharge(particle_def->GetPDGCharge());
75 particle.setMass(track->GetDynamicParticle()->GetMass());
76 particle.setEnergy(track->GetVertexKineticEnergy() +
77 track->GetDynamicParticle()->GetMass());
78
79 auto track_info{UserTrackInformation::get(track)};
80 particle.setVertexVolume(track_info->getVertexVolume());
81 particle.setInteractionMaterial(track->GetMaterial()->GetName());
82
83 auto vert{track->GetVertexPosition()};
84 particle.setVertex(vert.x(), vert.y(), vert.z());
85 particle.setTime(track_info->getVertexTime());
86
87 auto init_momentum{track_info->getInitialMomentum()};
88 particle.setMomentum(init_momentum.x(), init_momentum.y(), init_momentum.z());
89
90 const G4VProcess* process{track->GetCreatorProcess()};
91 if (process) {
92 const G4String& name{process->GetProcessName()};
93 particle.setProcessType(ldmx::SimParticle::findProcessType(name));
94 } else {
95 if (track->GetParentID() == 0) {
96 particle.setProcessType(ldmx::SimParticle::ProcessType::Primary);
97 } else {
98 particle.setProcessType(ldmx::SimParticle::ProcessType::unknown);
99 }
100 }
101
102 // track's current kinematics is its end point kinematics
103 // because we are assuming this track is being stopped/killed
104
105 auto momentum{track->GetMomentum()};
106 particle.setEndPointMomentum(momentum.x(), momentum.y(), momentum.z());
107
108 auto end_pt{track->GetPosition()};
109 particle.setEndPoint(end_pt.x(), end_pt.y(), end_pt.z());
110}
Class representing a simulated particle.
Definition SimParticle.h:25
static ProcessType findProcessType(std::string processName)
Get the process type enum from a G4VProcess name.
void setGenStatus(const int &gen_status)
Set the generator status of this particle.
static UserTrackInformation * get(const G4Track *track)
get

References ldmx::SimParticle::findProcessType(), simcore::UserTrackInformation::get(), particle_map_, and ldmx::SimParticle::setGenStatus().

Referenced by simcore::g4user::TrackingAction::PostUserTrackingAction().

◆ traceAncestry()

void simcore::TrackMap::traceAncestry ( )

Trace the ancestry for the particles that will be stored.

This should be done at the end of the event before writing the particle map to the event bus and involves looping through the particles that will be saved.

Use [] instead of at() for descendents_ so that if it wasn't previously created, we will just silently create an empty vector and move on.

Definition at line 112 of file TrackMap.cxx.

112 {
113 for (auto& [id, particle] : particle_map_) {
114 particle.addParent(ancestry_.at(id).first);
115
122 for (auto& child : descendents_[id]) {
123 particle.addDaughter(child);
124 }
125 }
126}

References ancestry_, descendents_, and particle_map_.

Member Data Documentation

◆ ancestry_

std::unordered_map<int, std::pair<int, bool> > simcore::TrackMap::ancestry_
private

ancestry map of particles in event (child -> parent)

Primary particles are given a "parent" ID of 0 to reflect that they don't have a parent. This is the default in Geant4 and we assume that holds here.

This is helpful for the findIncident method which looks up through a track's history to find the first ancestor which originated outside of the calorimeter region.

The key value is a pair where the first entry is the parent track ID and the second entry is whether the child track is in the calorimeter region.

See also
isInCalorimeterRegion for how we check if a track originated in the calorimeter region.

Definition at line 129 of file TrackMap.h.

Referenced by clear(), contains(), findIncident(), insert(), isDescendant(), and traceAncestry().

◆ descendents_

std::unordered_map<int, std::vector<int> > simcore::TrackMap::descendents_
private

descendents map of particles in event (parent -> children)

Definition at line 132 of file TrackMap.h.

Referenced by clear(), insert(), and traceAncestry().

◆ particle_map_

std::map<int, ldmx::SimParticle> simcore::TrackMap::particle_map_
private

map of SimParticles that will be stored

Definition at line 135 of file TrackMap.h.

Referenced by clear(), getParticleMap(), isSaved(), save(), and traceAncestry().


The documentation for this class was generated from the following files: