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
13
14#include "G4Event.hh"
15#include "G4Step.hh"
16#include "G4StepPoint.hh"
17#include "G4TouchableHistory.hh"
18#include "G4Track.hh"
19
20#include <memory>
21
22namespace G4UA
23{
24
25 //---------------------------------------------------------------------------
26 // Constructor
27 //---------------------------------------------------------------------------
30 int secondarySavingLevel,
31 int subDetVolLevel,
32 ISF::ITruthSvc& truthRecordSvc,
33 ISF::IGeoIDSvc& geoIDSvc,
34 IMessageSvc* msgSvc, MSG::Level level)
35 : AthMessaging(msgSvc, "MCTruthSteppingAction"),
36 m_isInitialized(false),
37 m_secondarySavingLevel(secondarySavingLevel),
38 m_subDetVolLevel(subDetVolLevel),
39 m_truthRecordSvc(truthRecordSvc),
40 m_geoIDSvc(geoIDSvc),
41 m_volumeCollectionMap(volCollMap)
42 {
43 msg().setLevel(level);
44 }
45
46 //---------------------------------------------------------------------------
47 // Setup the recording envelopes
48 //---------------------------------------------------------------------------
50 {
51 ATH_MSG_DEBUG("Setting up " << m_volumeCollectionMap.size() <<
52 " recording envelopes:");
54 for(const auto& volCollPair : m_volumeCollectionMap) {
55 ATH_MSG_DEBUG(" " << volCollPair.first << ", " << volCollPair.second);
56
57 // Construct the helper in place on the vector
58 m_recordingEnvelopes.emplace_back(volCollPair.first, volCollPair.second);
59 RecordingEnvelope& recEnvelope = m_recordingEnvelopes.back();
60
61 // Make sure the RecEnvelope can initialize properly
62 if(!recEnvelope.Initialize()) {
63 //FIXME - should this be an error?
64 ATH_MSG_WARNING("Envelope volume " << recEnvelope.GetVolumeName() <<
65 " not found in geometry!");
66 ATH_MSG_WARNING("TrackRecordCollection " <<
67 recEnvelope.GetTrackRecordCollectionName() <<
68 " will NOT be recorded");
69 // Throw away uninitialized RecordingEnvelope
70 m_recordingEnvelopes.pop_back();
71 }
72 }
73 if (m_recordingEnvelopes.size() == 0) {
74 ATH_MSG_WARNING("No recording envelopes found!");
75 }
76 }
77
78 //---------------------------------------------------------------------------
79 // Beginning of event
80 //---------------------------------------------------------------------------
82 {
83 // First time initialization
84 if(!m_isInitialized) {
86 if (m_recordingEnvelopes.size() == 0) {
87 ATH_MSG_WARNING("No recording envelopes found!");
88 }
89 m_isInitialized = true;
90 }
91 // Every event initialization
92 for (auto& recEnvelope : m_recordingEnvelopes) {
93 if(auto* eventInfo = static_cast<AtlasG4EventUserInfo*>( event->GetUserInformation())){
94 recEnvelope.BeginOfEvent(eventInfo->GetHitCollectionMap()->Find<TrackRecordCollection>(recEnvelope.GetTrackRecordCollectionName()));
95 }
96 }
97 }
98
99 //---------------------------------------------------------------------------
100 // Process one tracking step
101 //---------------------------------------------------------------------------
103 {
104 TrackHelper trackHelper(aStep->GetTrack());
105 const std::vector<const G4Track*>* secondaries = aStep->GetSecondaryInCurrentStep();
106
107 // info must be propagated to secondaries before MC truth incident can be created
109
110 // A saved primary is reclassified, but its old trajectory stayed active.
111 const bool processTruth =
112 trackHelper.IsPrimary() || trackHelper.IsRegeneratedPrimary() ||
113 (trackHelper.IsRegisteredSecondary() && m_secondarySavingLevel > 1);
114
115 if (secondaries && !secondaries->empty() && processTruth) {
116 createTruthIncident(aStep);
117 }
118
119 if (m_recordingEnvelopes.size() == 0) return;
120 if (trackHelper.IsSecondary()) return;
121
122 G4StepPoint* preStep = aStep->GetPreStepPoint();
123 G4StepPoint* postStep = aStep->GetPostStepPoint();
124
125 G4VPhysicalVolume* preVol = preStep->GetPhysicalVolume();
126 G4VPhysicalVolume* postVol = postStep->GetPhysicalVolume();
127
128 if (preVol == postVol) return;
129
130 const G4TouchableHistory* preTHist = static_cast<const G4TouchableHistory*>(preStep->GetTouchable());
131 const G4TouchableHistory* postTHist = static_cast<const G4TouchableHistory*>(postStep->GetTouchable());
132 const int preStepVolDepth = preTHist->GetHistoryDepth();
133 const int postStepVolDepth = postTHist->GetHistoryDepth();
134
135 for (auto& recEnvelope : m_recordingEnvelopes)
136 {
137 const int envelopeLevel = recEnvelope.GetLevel();
138 if (envelopeLevel <= preStepVolDepth)
139 {
140 //NB preTHist->GetVolume(preStepVolDepth) would just give us the World volume.
141 const G4LogicalVolume* logicalVolume1 =
142 preTHist->GetVolume(preStepVolDepth-envelopeLevel)->GetLogicalVolume();
143 if (logicalVolume1 != recEnvelope.GetLogicalVolume()) continue;
144
145 if (envelopeLevel <= postStepVolDepth &&
146 logicalVolume1 == postTHist->GetVolume(postStepVolDepth-envelopeLevel)
147 ->GetLogicalVolume())
148 {
149 continue;
150 }
151
152 // We have a track crossing a recording envelope
153 // volume boundary, so make a TrackRecord
154 recEnvelope.AddTrackRecord(aStep);
155
156 // Done with this volume.
157 break;
158 }
159 }
160 }
161
162 void MCTruthSteppingAction::createTruthIncident(const G4Step* aStep) const
163 {
164 const AtlasDetDescr::AtlasRegion geoID =
166 iGeant4::Geant4TruthIncident truth(aStep, geoID);
167 m_truthRecordSvc.registerTruthIncident(truth);
168 }
169
171 {
172 if (!aStep) {
173 return;
174 }
175
176 TrackHelper parentHelper(aStep->GetTrack());
177 TrackInformation* parentInfo = parentHelper.GetTrackInformation();
178 HepMC::GenParticlePtr primaryGenParticle = parentInfo ? parentInfo->GetPrimaryGenParticle() : nullptr;
179 if (!primaryGenParticle) {
180 return;
181 }
182
183 const std::vector<const G4Track*>* secondaries = aStep->GetSecondaryInCurrentStep();
184 if (!secondaries) {
185 return;
186 }
187
188 for (const G4Track* secondary : *secondaries) {
189 if (!secondary || secondary->GetUserInformation()) {
190 continue;
191 }
192
193 auto trackInfo = std::make_unique<TrackInformation>();
194 trackInfo->SetPrimaryGenParticle(primaryGenParticle);
195 trackInfo->SetClassification(TrackInformation::Secondary);
196 secondary->SetUserInformation(trackInfo.release());
197 }
198 }
199
200} // namespace G4UA
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_WARNING(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.
ISF::IGeoIDSvc & m_geoIDSvc
ISF GeoID Service used to identify the next detector region.
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.
ISF::ITruthSvc & m_truthRecordSvc
ISF Truth Service used to register truth incidents.
void createTruthIncident(const G4Step *) const
Create and register a truth incident for the current step.
virtual void UserSteppingAction(const G4Step *) override final
Process one particle step.
MCTruthSteppingAction(const VolumeCollectionMap_t &collMap, int secondarySavingLevel, int subDetVolLevel, ISF::ITruthSvc &truthRecordSvc, ISF::IGeoIDSvc &geoIDSvc, IMessageSvc *msgSvc, MSG::Level level)
Construct the action with specified volumes and output collections.
The interface to chose between the sub geometry services, realized as an AlgTool since it does not ha...
Definition IGeoIDSvc.h:41
@ class ITruthSvc
Definition ITruthSvc.h:29
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.
HepMC::ConstGenParticlePtr GetPrimaryGenParticle() const
return a pointer to the GenParticle used to create the initial G4PrimaryParticle from which the curre...
ISF_Geant4 specific implementation of the ISF::ITruthIncident.
static AtlasDetDescr::AtlasRegion nextGeoId(const G4Step *aStep, int truthVolLevel, ISF::IGeoIDSvc *geoIDSvc)
AtlasRegion
A simple enum of ATLAS regions and sub-detectors.
Definition AtlasRegion.h:21
HepMC3::GenParticlePtr GenParticlePtr
Definition GenParticle.h:19