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
9
10#include "G4Event.hh"
11#include "G4Step.hh"
12#include "G4StepPoint.hh"
13#include "G4TouchableHistory.hh"
14#include "G4Track.hh"
15
16#include <memory>
17
18namespace G4UA
19{
20
21 //---------------------------------------------------------------------------
22 // Constructor
23 //---------------------------------------------------------------------------
26 IMessageSvc* msgSvc, MSG::Level level)
27 : AthMessaging(msgSvc, "MCTruthSteppingAction"),
28 m_isInitialized(false),
29 m_volumeCollectionMap(volCollMap)
30 {
31 msg().setLevel(level);
32 }
33
34 //---------------------------------------------------------------------------
35 // Setup the recording envelopes
36 //---------------------------------------------------------------------------
38 {
39 ATH_MSG_DEBUG("Setting up " << m_volumeCollectionMap.size() <<
40 " recording envelopes:");
42 for(const auto& volCollPair : m_volumeCollectionMap) {
43 ATH_MSG_DEBUG(" " << volCollPair.first << ", " << volCollPair.second);
44
45 // Construct the helper in place on the vector
46 m_recordingEnvelopes.emplace_back(volCollPair.first, volCollPair.second);
47 RecordingEnvelope& recEnvelope = m_recordingEnvelopes.back();
48
49 // Make sure the RecEnvelope can initialize properly
50 if(!recEnvelope.Initialize()) {
51 //FIXME - should this be an error?
52 ATH_MSG_WARNING("Envelope volume " << recEnvelope.GetVolumeName() <<
53 " not found in geometry!");
54 ATH_MSG_WARNING("TrackRecordCollection " <<
55 recEnvelope.GetTrackRecordCollectionName() <<
56 " will NOT be recorded");
57 // Throw away uninitialized RecordingEnvelope
58 m_recordingEnvelopes.pop_back();
59 }
60 }
61 if (m_recordingEnvelopes.size() == 0) {
62 ATH_MSG_WARNING("No recording envelopes found!");
63 }
64 }
65
66 //---------------------------------------------------------------------------
67 // Beginning of event
68 //---------------------------------------------------------------------------
70 {
71 // First time initialization
72 if(!m_isInitialized) {
74 if (m_recordingEnvelopes.size() == 0) {
75 ATH_MSG_WARNING("No recording envelopes found!");
76 }
77 m_isInitialized = true;
78 }
79 // Every event initialization
80 for (auto& recEnvelope : m_recordingEnvelopes) {
81 if(auto* eventInfo = static_cast<AtlasG4EventUserInfo*>( event->GetUserInformation())){
82 recEnvelope.BeginOfEvent(eventInfo->GetHitCollectionMap()->Find<TrackRecordCollection>(recEnvelope.GetTrackRecordCollectionName()));
83 }
84 }
85 }
86
87 //---------------------------------------------------------------------------
88 // Process one tracking step
89 //---------------------------------------------------------------------------
91 {
93
94 if (m_recordingEnvelopes.size() == 0) return;
95 TrackHelper trackHelper(aStep->GetTrack());
96 if (trackHelper.IsSecondary()) return;
97
98 G4StepPoint* preStep = aStep->GetPreStepPoint();
99 G4StepPoint* postStep = aStep->GetPostStepPoint();
100
101 G4VPhysicalVolume* preVol = preStep->GetPhysicalVolume();
102 G4VPhysicalVolume* postVol = postStep->GetPhysicalVolume();
103
104 if (preVol == postVol) return;
105
106 const G4TouchableHistory* preTHist = static_cast<const G4TouchableHistory*>(preStep->GetTouchable());
107 const G4TouchableHistory* postTHist = static_cast<const G4TouchableHistory*>(postStep->GetTouchable());
108 const int preStepVolDepth = preTHist->GetHistoryDepth();
109 const int postStepVolDepth = postTHist->GetHistoryDepth();
110
111 for (auto& recEnvelope : m_recordingEnvelopes)
112 {
113 const int envelopeLevel = recEnvelope.GetLevel();
114 if (envelopeLevel <= preStepVolDepth)
115 {
116 //NB preTHist->GetVolume(preStepVolDepth) would just give us the World volume.
117 const G4LogicalVolume* logicalVolume1 =
118 preTHist->GetVolume(preStepVolDepth-envelopeLevel)->GetLogicalVolume();
119 if (logicalVolume1 != recEnvelope.GetLogicalVolume()) continue;
120
121 if (envelopeLevel <= postStepVolDepth &&
122 logicalVolume1 == postTHist->GetVolume(postStepVolDepth-envelopeLevel)
123 ->GetLogicalVolume())
124 {
125 continue;
126 }
127
128 // We have a track crossing a recording envelope
129 // volume boundary, so make a TrackRecord
130 recEnvelope.AddTrackRecord(aStep);
131
132 // Done with this volume.
133 break;
134 }
135 }
136 }
137
139 {
140 if (!aStep) {
141 return;
142 }
143
144 TrackHelper parentHelper(aStep->GetTrack());
145 TrackInformation* parentInfo = parentHelper.GetTrackInformation();
146 HepMC::GenParticlePtr primaryGenParticle = parentInfo ? parentInfo->GetPrimaryGenParticle() : nullptr;
147 if (!primaryGenParticle) {
148 return;
149 }
150
151 const std::vector<const G4Track*>* secondaries = aStep->GetSecondaryInCurrentStep();
152 if (!secondaries) {
153 return;
154 }
155
156 for (const G4Track* secondary : *secondaries) {
157 if (!secondary || secondary->GetUserInformation()) {
158 continue;
159 }
160
161 auto trackInfo = std::make_unique<TrackInformation>();
162 trackInfo->SetPrimaryGenParticle(primaryGenParticle);
163 trackInfo->SetClassification(TrackInformation::Secondary);
164 secondary->SetUserInformation(trackInfo.release());
165 }
166 }
167
168} // 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.
void setupRecEnvelopes()
Setup the list of RecordingEnvelope helpers.
std::vector< RecordingEnvelope > m_recordingEnvelopes
List of RecordingEnvelope helpers to invoke.
MCTruthSteppingAction(const VolumeCollectionMap_t &collMap, IMessageSvc *msgSvc, MSG::Level level)
Construct the action with specified volumes and output collections.
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.
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 IsSecondary() const
Implementation of VTrackInformation.
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