ATLAS Offline Software
Loading...
Searching...
No Matches
MCTruthSteppingAction.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
10
11#include "G4Event.hh"
12#include "G4Step.hh"
13#include "G4StepPoint.hh"
14#include "G4TouchableHistory.hh"
15#include "G4Track.hh"
16
17#include <memory>
18
19namespace G4UA
20{
21
22 //---------------------------------------------------------------------------
23 // Constructor
24 //---------------------------------------------------------------------------
27 int secondarySavingLevel,
28 int subDetVolLevel,
29 IMessageSvc* msgSvc, MSG::Level level)
30 : AthMessaging(msgSvc, "MCTruthSteppingAction"),
31 m_isInitialized(false),
32 m_secondarySavingLevel(secondarySavingLevel),
33 m_subDetVolLevel(subDetVolLevel),
34 m_volumeCollectionMap(volCollMap)
35 {
36 msg().setLevel(level);
37 }
38
39 //---------------------------------------------------------------------------
40 // Setup the recording envelopes
41 //---------------------------------------------------------------------------
43 {
44 ATH_MSG_DEBUG("Setting up " << m_volumeCollectionMap.size() <<
45 " recording envelopes:");
47 for(const auto& volCollPair : m_volumeCollectionMap) {
48 ATH_MSG_DEBUG(" " << volCollPair.first << ", " << volCollPair.second);
49
50 // Construct the helper in place on the vector
51 m_recordingEnvelopes.emplace_back(volCollPair.first, volCollPair.second);
52 RecordingEnvelope& recEnvelope = m_recordingEnvelopes.back();
53
54 // Make sure the RecEnvelope can initialize properly
55 if(!recEnvelope.Initialize()) {
56 //FIXME - should this be an error?
57 ATH_MSG_WARNING("Envelope volume " << recEnvelope.GetVolumeName() <<
58 " not found in geometry!");
59 ATH_MSG_WARNING("TrackRecordCollection " <<
60 recEnvelope.GetTrackRecordCollectionName() <<
61 " will NOT be recorded");
62 // Throw away uninitialized RecordingEnvelope
63 m_recordingEnvelopes.pop_back();
64 }
65 }
66 if (m_recordingEnvelopes.size() == 0) {
67 ATH_MSG_WARNING("No recording envelopes found!");
68 }
69 }
70
71 //---------------------------------------------------------------------------
72 // Beginning of event
73 //---------------------------------------------------------------------------
75 {
76 // First time initialization
77 if(!m_isInitialized) {
79 if (m_recordingEnvelopes.size() == 0) {
80 ATH_MSG_WARNING("No recording envelopes found!");
81 }
82 m_isInitialized = true;
83 }
84 // Every event initialization
85 for (auto& recEnvelope : m_recordingEnvelopes) {
86 if(auto* eventInfo = static_cast<AtlasG4EventUserInfo*>( event->GetUserInformation())){
87 recEnvelope.BeginOfEvent(eventInfo->GetHitCollectionMap()->Find<TrackRecordCollection>(recEnvelope.GetTrackRecordCollectionName()));
88 }
89 }
90 }
91
92 //---------------------------------------------------------------------------
93 // Process one tracking step
94 //---------------------------------------------------------------------------
96 {
97 TrackHelper trackHelper(aStep->GetTrack());
98 const std::vector<const G4Track*>* secondaries = aStep->GetSecondaryInCurrentStep();
99
100 // info must be propagated to secondaries before MC truth incident can be created
102
103 // A saved primary is reclassified, but its old trajectory stayed active.
104 const bool processTruth =
105 trackHelper.IsPrimary() || trackHelper.IsRegeneratedPrimary() ||
106 (trackHelper.IsRegisteredSecondary() && m_secondarySavingLevel > 1);
107
108 if (secondaries && !secondaries->empty() && processTruth) {
109 const TruthStrategyManager& sManager =
111 sManager.CreateTruthIncident(aStep, m_subDetVolLevel);
112 }
113
114 if (m_recordingEnvelopes.size() == 0) return;
115 if (trackHelper.IsSecondary()) return;
116
117 G4StepPoint* preStep = aStep->GetPreStepPoint();
118 G4StepPoint* postStep = aStep->GetPostStepPoint();
119
120 G4VPhysicalVolume* preVol = preStep->GetPhysicalVolume();
121 G4VPhysicalVolume* postVol = postStep->GetPhysicalVolume();
122
123 if (preVol == postVol) return;
124
125 const G4TouchableHistory* preTHist = static_cast<const G4TouchableHistory*>(preStep->GetTouchable());
126 const G4TouchableHistory* postTHist = static_cast<const G4TouchableHistory*>(postStep->GetTouchable());
127 const int preStepVolDepth = preTHist->GetHistoryDepth();
128 const int postStepVolDepth = postTHist->GetHistoryDepth();
129
130 for (auto& recEnvelope : m_recordingEnvelopes)
131 {
132 const int envelopeLevel = recEnvelope.GetLevel();
133 if (envelopeLevel <= preStepVolDepth)
134 {
135 //NB preTHist->GetVolume(preStepVolDepth) would just give us the World volume.
136 const G4LogicalVolume* logicalVolume1 =
137 preTHist->GetVolume(preStepVolDepth-envelopeLevel)->GetLogicalVolume();
138 if (logicalVolume1 != recEnvelope.GetLogicalVolume()) continue;
139
140 if (envelopeLevel <= postStepVolDepth &&
141 logicalVolume1 == postTHist->GetVolume(postStepVolDepth-envelopeLevel)
142 ->GetLogicalVolume())
143 {
144 continue;
145 }
146
147 // We have a track crossing a recording envelope
148 // volume boundary, so make a TrackRecord
149 recEnvelope.AddTrackRecord(aStep);
150
151 // Done with this volume.
152 break;
153 }
154 }
155 }
156
158 {
159 if (!aStep) {
160 return;
161 }
162
163 TrackHelper parentHelper(aStep->GetTrack());
164 TrackInformation* parentInfo = parentHelper.GetTrackInformation();
165 HepMC::GenParticlePtr primaryGenParticle = parentInfo ? parentInfo->GetPrimaryGenParticle() : nullptr;
166 if (!primaryGenParticle) {
167 return;
168 }
169
170 const std::vector<const G4Track*>* secondaries = aStep->GetSecondaryInCurrentStep();
171 if (!secondaries) {
172 return;
173 }
174
175 for (const G4Track* secondary : *secondaries) {
176 if (!secondary || secondary->GetUserInformation()) {
177 continue;
178 }
179
180 auto trackInfo = std::make_unique<TrackInformation>();
181 trackInfo->SetPrimaryGenParticle(primaryGenParticle);
182 trackInfo->SetClassification(TrackInformation::Secondary);
183 secondary->SetUserInformation(trackInfo.release());
184 }
185 }
186
187} // namespace G4UA
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
AtlasHitsVector< TrackRecord > TrackRecordCollection
MsgStream & msg() const
The standard message stream.
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
This class is attached to G4Event objects as UserInformation.
std::map< std::string, std::string > VolumeCollectionMap_t
Map of volume name to output TrackRecordCollection name.
bool m_isInitialized
Used to delay initialization until the event loop, after geo is ready.
int m_subDetVolLevel
The level in the G4 volume hierarchy at which we find the sub-detector.
int m_secondarySavingLevel
The saving level for secondaries.
void setupRecEnvelopes()
Setup the list of RecordingEnvelope helpers.
std::vector< RecordingEnvelope > m_recordingEnvelopes
List of RecordingEnvelope helpers to invoke.
VolumeCollectionMap_t m_volumeCollectionMap
Map of volume name to output collection name.
void propagatePrimaryInfoToSecondaries(const G4Step *) const
Propagate parent primary truth attribution to ordinary secondaries.
MCTruthSteppingAction(const VolumeCollectionMap_t &collMap, int secondarySavingLevel, int subDetVolLevel, IMessageSvc *msgSvc, MSG::Level level)
Construct the action with specified volumes and output collections.
virtual void BeginOfEventAction(const G4Event *) override final
Called at the start of each G4 event.
virtual void UserSteppingAction(const G4Step *) override final
Process one particle step.
Responsible for finding the G4LogicalVolume pointer for each recording envelope and for creating and ...
const std::string & GetTrackRecordCollectionName() const
Returns the name of the TrackRecordCollection to which tracks crossing this recording envelope should...
const std::string & GetVolumeName() const
Returns the name of the recording envelope volume.
bool Initialize()
Finds the pointer to the G4LogicalVolume called m_envelopeVolumeName and the number of levels beneath...
TrackInformation * GetTrackInformation()
Return concrete TrackInformation when callers need fields that are not part of the VTrackInformation ...
bool IsPrimary() const
bool IsSecondary() const
bool IsRegisteredSecondary() const
bool IsRegeneratedPrimary() const
Implementation of VTrackInformation.
Singleton class for creating truth incidents.
bool CreateTruthIncident(const G4Step *, int subDetVolLevel) const
Returns true if any of the truth strategies return true.
static const TruthStrategyManager & GetStrategyManager()
Retrieve the (const) singleton instance.
HepMC::ConstGenParticlePtr GetPrimaryGenParticle() const
return a pointer to the GenParticle used to create the initial G4PrimaryParticle from which the curre...
HepMC3::GenParticlePtr GenParticlePtr
Definition GenParticle.h:19