ATLAS Offline Software
Loading...
Searching...
No Matches
TrackProcessorUserActionFullG4.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5// class header
7
8// ISF includes
11
13
14// ISF Geant4 includes
17
18// Athena includes
20
21#include "MCTruth/TrackHelper.h"
22
24
25// Geant4 includes
26#include "G4ParticleDefinition.hh"
27#include "G4DynamicParticle.hh"
28#include "G4TouchableHistory.hh"
29#include "G4Step.hh"
30#include "G4TransportationManager.hh"
31#include "G4LogicalVolumeStore.hh"
32
33#include <iostream>
34
35namespace G4UA{
36
37 namespace iGeant4{
38
41 m_entryLayerToolQuick(nullptr),
42 m_geoIDSvcQuick(nullptr),
43 m_currentTrack(nullptr)
44 {
45
46 if(4<m_config.verboseLevel)
47 {
48 G4cout << "create TrackProcessorUserActionFullG4" << G4endl;
49 }
50
52
53 if ( !m_config.entryLayerTool.empty() ) {
54 if ( m_config.entryLayerTool.retrieve().isFailure()) {
55 G4ExceptionDescription description;
56 description << G4String("TrackProcessorUserActionFullG4: ") + "Could not retrieve ISF Entry Layer Tool: " << m_config.entryLayerTool;
57 G4Exception("G4UA::iGeant4::TrackProcessorUserActionFullG4", "NoISFEntryLayerTool", FatalException, description);
58 return; //The G4Exception call above should abort the job, but Coverity does not seem to pick this up.
59 }
60 m_entryLayerToolQuick = &(*m_config.entryLayerTool);
61 }
62
63 if ( !m_config.geoIDSvc.empty() ) {
64 if (m_config.geoIDSvc.retrieve().isFailure()) {
65 G4ExceptionDescription description;
66 description << G4String("TrackProcessorUserActionFullG4: ") + "Could not retrieve ISF GeoID Svc: " << m_config.geoIDSvc;
67 G4Exception("G4UA::iGeant4::TrackProcessorUserActionFullG4", "NoISFGeoIDSvc", FatalException, description);
68 return; //The G4Exception call above should abort the job, but Coverity does not seem to pick this up.
69 }
70
71 m_geoIDSvcQuick = &(*m_config.geoIDSvc);
72 }
73
74 m_entryLayerMap["CALO::CALO"] = m_config.truthVolLevel+1;
75 m_entryLayerMap["MUONQ02::MUONQ02"] = m_config.truthVolLevel+1;
76 m_entryLayerMap[m_config.isITkGeometry ? "ITK::ITK" : "IDET::IDET"] = m_config.truthVolLevel+1;
77
78 }
79
81 {
82 G4Track* aTrack = aStep->GetTrack();
83 //int aTrackID = aTrack->GetTrackID(); // Only used in DEBUG messages
84 G4TrackStatus aTrackStatus = aTrack->GetTrackStatus();
85
86 const G4StepPoint *preStep = aStep->GetPreStepPoint();
87 const G4StepPoint *postStep = aStep->GetPostStepPoint();
88
89
92 truthVolLevel,
94 if ( curISP->nextGeoID()!=nextG4GeoID ) {
95 curISP->setNextGeoID( nextG4GeoID );
96 }
97
98 // check if dead track
99 if ( aTrackStatus==fStopAndKill ) {
100 // ATH_MSG_DEBUG("Stepping dead G4Track, returning. TrackLength="<<aTrack->GetTrackLength()<<
101 // " TrackEkin="<<aTrack->GetKineticEnergy()<<" TrackID="<<aTrackID);
102 return;
103 }
104
105 const G4VPhysicalVolume *preVol = preStep->GetPhysicalVolume();
106 const G4VPhysicalVolume *postVol = postStep->GetPhysicalVolume();
107
108 // check if particle left detector volume
109 if ( postVol==0 ) {
110 // ATH_MSG_DEBUG("G4Step not in physical volume, returning. TrackLength="<<
111 // aTrack->GetTrackLength()<<" TrackEkin="<<aTrack->GetKineticEnergy()<<
112 // " TrackID="<<aTrackID);
113 // left world
114 return;
115 }
116
117 // check if particle is within same physical volume
118 if ( preVol==postVol ) {
119 // ATH_MSG_DEBUG("G4Track stays inside current volume");
120 return;
121 }
122
123 //
124 // this point is only reached if particle has crossed
125 // a sub-det boundary in the Geant4-only mode
126 //
127
128 TrackHelper tHelp(aTrack);
129
130 // only process particle at entry layer if primary or registered secondary
131
132 if ( ! tHelp.IsSecondary() ) {
133
134 // get entry layer
135 ISF::EntryLayer layer = entryLayer(aStep);
136
137 if (layer!=ISF::fUnsetEntryLayer) {
138
139
141 m_config.truthVolLevel,
143
145 *curISP,
146 nullptr // truthBinding
147 );
148 tmpISP->setNextGeoID(nextGeoID);
150
151 auto generationZeroBarcode = tHelp.GetBarcode(); // FIXME barcode-based
152 tmpISP->setBarcode(generationZeroBarcode); // FIXME barcode-based
153 auto generationZeroID = tHelp.GetUniqueID();
154 tmpISP->setId(generationZeroID);
155
156 tmpISP->setNextGeoID( nextGeoID );
157
158 // inform the entry layer tool about this particle
159 m_entryLayerToolQuick->registerParticle( *tmpISP, layer);
160
161 delete tmpISP;
162 }
163
164 }
165
166 return;
167 }
168
170 {
171 //
172 // this is the same prescription for getting the entry layer as in
173 // MCTruth/MCTruthSteppingAction
174 //
175
176 const G4StepPoint *preStep =aStep->GetPreStepPoint();
177 const G4StepPoint *postStep=aStep->GetPostStepPoint();
178
179 const G4TouchableHistory *preTHist=static_cast<const G4TouchableHistory*>(preStep->GetTouchable());
180 const G4TouchableHistory *postTHist=static_cast<const G4TouchableHistory*>(postStep->GetTouchable());
181 int nLev1 = preTHist->GetHistoryDepth();
182 int nLev2 = postTHist->GetHistoryDepth();
183
184 std::map<std::string, int, std::less<std::string> >::const_iterator it;
185
186 std::string vname1;
187 bool pass=false;
188 for (it=m_entryLayerMap.begin(); it!=m_entryLayerMap.end(); ++it) {
189
190 int il=(*it).second;
191
192 if (il<=(nLev1+1)) {
193 vname1=preTHist->GetVolume(nLev1-il+1)->GetName();
194
195 if (vname1!=(*it).first) continue;
196
197 if (il<=(nLev2+1)) {
198 if (vname1 == static_cast<const std::string&>(postTHist->GetVolume(nLev2-il+1)->GetName()))
199 {
200 continue;
201 }
202 }
203
204 pass=true;
205 break;
206 }
207 }
208
209
211 if (pass) {
212 if (!m_config.isITkGeometry && vname1=="IDET::IDET") layer=ISF::fAtlasCaloEntry;
213 else if ( m_config.isITkGeometry && vname1=="ITK::ITK") layer=ISF::fAtlasCaloEntry;
214 else if (vname1=="CALO::CALO") layer=ISF::fAtlasMuonEntry;
215 else if (vname1=="MUONQ02::MUONQ02") layer=ISF::fAtlasMuonExit;
216 }
217
218 return layer;
219 }
220
222 // reset geoId, call upstream method
224 m_currentTrack = aTrack;
226 return;
227 }
228
229 } // iGeant4
230
231} //G4UA
if(febId1==febId2)
virtual void PreUserTrackingAction(const G4Track *) override
std::map< std::string, int, std::less< std::string > > m_entryLayerMap
ISF::IEntryLayerTool * m_entryLayerToolQuick
access to the ISF Entry Layer tool which is used to record entry-layer collections
ISF::IGeoIDSvc * m_geoIDSvcQuick
access to the central ISF GeoID serice
void ISFSteppingAction(const G4Step *, ISF::ISFParticle *curISP) override final
Called by the base class after the G4Track->ISFParticle association has been established.
virtual void PreUserTrackingAction(const G4Track *) override final
The generic ISF particle definition,.
Definition ISFParticle.h:42
void setNextSimID(SimSvcID simID)
register the next SimSvcID
void setBarcode(int bc)
set a new barcode
void setId(int id)
set a new unique ID
void setNextGeoID(AtlasDetDescr::AtlasRegion geoID)
register the next AtlasDetDescr::AtlasRegion
AtlasDetDescr::AtlasRegion nextGeoID() const
next geoID the particle will be simulated in
bool IsSecondary() const
int GetBarcode() const
int GetUniqueID() const
static AtlasDetDescr::AtlasRegion nextGeoId(const G4Step *aStep, int truthVolLevel, ISF::IGeoIDSvc *geoIDSvc)
static ISF::ISFParticle * convertG4TrackToISFParticle(const G4Track &aTrack, const ISF::ISFParticle &parent, ISF::TruthBinding *truth=nullptr)
convert the given G4Track into an ISFParticle
AtlasRegion
A simple enum of ATLAS regions and sub-detectors.
Definition AtlasRegion.h:21
@ fUndefinedSimID
Definition SimSvcID.h:32
EntryLayer
Identifiers for the TrackRecordCollections on the boundaries between CaloEntry: Inner Detector - Calo...
Definition EntryLayer.h:31
@ fAtlasMuonExit
Definition EntryLayer.h:39
@ fUnsetEntryLayer
Definition EntryLayer.h:33
@ fAtlasCaloEntry
Definition EntryLayer.h:37
@ fAtlasMuonEntry
Definition EntryLayer.h:38