ATLAS Offline Software
Loading...
Searching...
No Matches
GeantFollowerHelper.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6// GeantFollowerHelper.cxx, (c) ATLAS Detector Software
8
9// StoreGate
11#include "TTree.h"
12#include "GaudiKernel/ITHistSvc.h"
13// CLHEP
14#include "CLHEP/Units/SystemOfUnits.h"
15#include "CLHEP/Geometry/Transform3D.h"
16// Trk
19// Amg
21
22// constructor
23Trk::GeantFollowerHelper::GeantFollowerHelper(const std::string& t, const std::string& n, const IInterface* p) :
24 base_class(t,n,p),
28 m_parameterCache(nullptr),
29 m_tX0Cache(0.),
30 m_validationTreeName("G4Follower_"+n),
31 m_validationTreeDescription("Output of the G4Follower_"),
32 m_validationTreeFolder("/val/G4Follower_"+n),
33 m_validationTree(nullptr)
34{
35 // properties
36 declareProperty("Extrapolator", m_extrapolator);
37 declareProperty("ExtrapolateDirectly", m_extrapolateDirectly);
38 declareProperty("ExtrapolateIncrementally", m_extrapolateIncrementally);
39}
40
41// destructor
43= default;
44
45// Athena standard methods
46// initialize
48{
49 m_treeData = std::make_unique<TreeData>();
50
51 if (m_extrapolator.retrieve().isFailure()){
52 ATH_MSG_ERROR("Could not retrieve Extrapolator " << m_extrapolator << " . Abort.");
53 return StatusCode::FAILURE;
54 }
55
56 // create the new Tree
58
59 m_validationTree->Branch("InitX", &m_treeData->m_t_x, "initX/F");
60 m_validationTree->Branch("InitY", &m_treeData->m_t_y, "initY/F");
61 m_validationTree->Branch("InitZ", &m_treeData->m_t_z, "initZ/F");
62 m_validationTree->Branch("InitTheta", &m_treeData->m_t_theta, "initTheta/F");
63 m_validationTree->Branch("InitEta", &m_treeData->m_t_eta, "initEta/F");
64 m_validationTree->Branch("InitPhi", &m_treeData->m_t_phi, "initPhi/F");
65 m_validationTree->Branch("InitP", &m_treeData->m_t_p, "initP/F");
66 m_validationTree->Branch("InitPdg", &m_treeData->m_t_pdg, "initPdg/I");
67 m_validationTree->Branch("InitCharge", &m_treeData->m_t_charge, "initQ/F");
68
69 m_validationTree->Branch("G4Steps", &m_treeData->m_g4_steps, "g4steps/I");
70 m_validationTree->Branch("G4StepP", m_treeData->m_g4_p, "g4stepP[g4steps]/F");
71 m_validationTree->Branch("G4StepEta", m_treeData->m_g4_eta, "g4stepEta[g4steps]/F");
72 m_validationTree->Branch("G4StepTheta", m_treeData->m_g4_theta, "g4stepTheta[g4steps]/F");
73 m_validationTree->Branch("G4StepPhi", m_treeData->m_g4_phi, "g4stepPhi[g4steps]/F");
74 m_validationTree->Branch("G4StepX", m_treeData->m_g4_x, "g4stepX[g4steps]/F");
75 m_validationTree->Branch("G4StepY", m_treeData->m_g4_y, "g4stepY[g4steps]/F");
76 m_validationTree->Branch("G4StepZ", m_treeData->m_g4_z, "g4stepZ[g4steps]/F");
77 m_validationTree->Branch("G4AccumTX0", m_treeData->m_g4_tX0, "g4stepAccTX0[g4steps]/F");
78 m_validationTree->Branch("G4StepT", m_treeData->m_g4_t, "g4stepTX[g4steps]/F");
79 m_validationTree->Branch("G4StepX0", m_treeData->m_g4_X0, "g4stepX0[g4steps]/F");
80
81 m_validationTree->Branch("TrkStepStatus",m_treeData->m_trk_status, "trkstepStatus[g4steps]/I");
82 m_validationTree->Branch("TrkStepP", m_treeData->m_trk_p, "trkstepP[g4steps]/F");
83 m_validationTree->Branch("TrkStepEta", m_treeData->m_trk_eta, "trkstepEta[g4steps]/F");
84 m_validationTree->Branch("TrkStepTheta", m_treeData->m_trk_theta, "trkstepTheta[g4steps]/F");
85 m_validationTree->Branch("TrkStepPhi", m_treeData->m_trk_phi, "trkstepPhi[g4steps]/F");
86 m_validationTree->Branch("TrkStepX", m_treeData->m_trk_x, "trkstepX[g4steps]/F");
87 m_validationTree->Branch("TrkStepY", m_treeData->m_trk_y, "trkstepY[g4steps]/F");
88 m_validationTree->Branch("TrkStepZ", m_treeData->m_trk_z, "trkstepZ[g4steps]/F");
89 m_validationTree->Branch("TrkStepLocX", m_treeData->m_trk_lx, "trkstepLX[g4steps]/F");
90 m_validationTree->Branch("TrkStepLocY", m_treeData->m_trk_ly, "trkstepLY[g4steps]/F");
91
92 // now register the Tree
93 SmartIF<ITHistSvc> tHistSvc{Gaudi::svcLocator()->service("THistSvc")};
94 if ( !tHistSvc ) {
95 ATH_MSG_ERROR( "Could not find Hist Service -> Switching ValidationMode Off !" );
96 delete m_validationTree; m_validationTree = nullptr;
97 }
98 if ((tHistSvc->regTree(m_validationTreeFolder, m_validationTree)).isFailure()) {
99 ATH_MSG_ERROR( "Could not register the validation Tree -> Switching ValidationMode Off !" );
100 delete m_validationTree; m_validationTree = nullptr;
101 }
102
103 ATH_MSG_INFO("initialize() successful" );
104 return StatusCode::SUCCESS;
105}
106
108{
109 return StatusCode::SUCCESS;
110}
111
113{
114 m_treeData->m_t_x = 0.;
115 m_treeData->m_t_y = 0.;
116 m_treeData->m_t_z = 0.;
117 m_treeData->m_t_theta = 0.;
118 m_treeData->m_t_eta = 0.;
119 m_treeData->m_t_phi = 0.;
120 m_treeData->m_t_p = 0.;
121 m_treeData->m_t_charge = 0.;
122 m_treeData->m_t_pdg = 0;
123 m_treeData->m_g4_steps = 0;
124 m_tX0Cache = 0.;
125}
126
127void Trk::GeantFollowerHelper::trackParticle(const G4ThreeVector& pos,
128 const G4ThreeVector& mom,
129 int pdg, double charge,
130 float t, float X0)
131{
132 // construct the initial parameters
133 Amg::Vector3D npos(pos.x(),pos.y(),pos.z());
134 Amg::Vector3D nmom(mom.x(),mom.y(),mom.z());
135 if (!m_treeData->m_g4_steps){
136 ATH_MSG_INFO("Initial step ... preparing event cache.");
137 m_treeData->m_t_x = pos.x();
138 m_treeData->m_t_y = pos.y();
139 m_treeData->m_t_z = pos.z();
140 m_treeData->m_t_theta = mom.theta();
141 m_treeData->m_t_eta = mom.eta();
142 m_treeData->m_t_phi = mom.phi();
143 m_treeData->m_t_p = mom.mag();
144 m_treeData->m_t_charge = charge;
145 m_treeData->m_t_pdg = pdg;
146 m_treeData->m_g4_steps = -1;
147 m_tX0Cache = 0.;
149 return;
150 }
151
152 // jumping over inital step
153 m_treeData->m_g4_steps = (m_treeData->m_g4_steps == -1) ? 0 : m_treeData->m_g4_steps;
154
155 if (!m_parameterCache){
156 ATH_MSG_WARNING("No Parameters available. Bailing out.");
157 return;
158 }
159
160 if ( m_treeData->m_g4_steps >= MAXPROBES) {
161 ATH_MSG_WARNING("Maximum number of " << MAXPROBES << " reached, step is ignored.");
162 return;
163 }
164 // parameters of the G4 step point
165 Trk::CurvilinearParameters* g4Parameters = new Trk::CurvilinearParameters(npos, nmom, m_treeData->m_t_charge);
166 // destination surface
167 const Trk::PlaneSurface& destinationSurface = g4Parameters->associatedSurface();
168 // extrapolate to the destination surface
169 const EventContext& ctx = Gaudi::Hive::currentContext();
170 auto trkParameters = m_extrapolateDirectly ?
171 m_extrapolator->extrapolateDirectly(ctx,
173 destinationSurface,
174 Trk::alongMomentum,false):
175 m_extrapolator->extrapolate(ctx,
177 destinationSurface,
178 Trk::alongMomentum,false);
179 // fill the geant information and the trk information
180 m_treeData->m_g4_p[m_treeData->m_g4_steps] = mom.mag();
181 m_treeData->m_g4_eta[m_treeData->m_g4_steps] = mom.eta();
182 m_treeData->m_g4_theta[m_treeData->m_g4_steps] = mom.theta();
183 m_treeData->m_g4_phi[m_treeData->m_g4_steps] = mom.phi();
184 m_treeData->m_g4_x[m_treeData->m_g4_steps] = pos.x();
185 m_treeData->m_g4_y[m_treeData->m_g4_steps] = pos.y();
186 m_treeData->m_g4_z[m_treeData->m_g4_steps] = pos.z();
187 float tX0 = X0 > 10e-5 ? t/X0 : 0.;
188 m_tX0Cache += tX0;
189 m_treeData->m_g4_tX0[m_treeData->m_g4_steps] = m_tX0Cache;
190 m_treeData->m_g4_t[m_treeData->m_g4_steps] = t;
191 m_treeData->m_g4_X0[m_treeData->m_g4_steps] = X0;
192
193 m_treeData->m_trk_status[m_treeData->m_g4_steps] = trkParameters ? 1 : 0;
194 m_treeData->m_trk_p[m_treeData->m_g4_steps] = trkParameters ? trkParameters->momentum().mag() : 0.;
195 m_treeData->m_trk_eta[m_treeData->m_g4_steps] = trkParameters ? trkParameters->momentum().eta() : 0.;
196 m_treeData->m_trk_theta[m_treeData->m_g4_steps] = trkParameters ? trkParameters->momentum().theta() : 0.;
197 m_treeData->m_trk_phi[m_treeData->m_g4_steps] = trkParameters ? trkParameters->momentum().phi() : 0.;
198 m_treeData->m_trk_x[m_treeData->m_g4_steps] = trkParameters ? trkParameters->position().x() : 0.;
199 m_treeData->m_trk_y[m_treeData->m_g4_steps] = trkParameters ? trkParameters->position().y() : 0.;
200 m_treeData->m_trk_z[m_treeData->m_g4_steps] = trkParameters ? trkParameters->position().z() : 0.;
201 m_treeData->m_trk_lx[m_treeData->m_g4_steps] = trkParameters ? trkParameters->parameters()[Trk::locX] : 0.;
202 m_treeData->m_trk_ly[m_treeData->m_g4_steps] = trkParameters ? trkParameters->parameters()[Trk::locY] : 0.;
203
204 // update the parameters if needed/configured
205 if (m_extrapolateIncrementally && trkParameters) {
206 delete m_parameterCache;
207 m_parameterCache = trkParameters.release();
208 }
209 // delete cache and increment
210 delete g4Parameters;
211 ++m_treeData->m_g4_steps;
212}
213
215{
216 // fill the validation tree
217 m_validationTree->Fill();
218 delete m_parameterCache;
219}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
double charge(const T &p)
Definition AtlasPID.h:1003
virtual const S & associatedSurface() const override final
Access to the Surface method.
static constexpr int MAXPROBES
virtual void beginEvent() override
std::string m_validationTreeName
validation tree name - to be acessed by this from root
virtual StatusCode initialize() override
GeantFollowerHelper(const std::string &, const std::string &, const IInterface *)
virtual void trackParticle(const G4ThreeVector &pos, const G4ThreeVector &mom, int pdg, double charge, float t, float X0) override
virtual void endEvent() override
virtual StatusCode finalize() override
std::unique_ptr< TreeData > m_treeData
TTree * m_validationTree
Root Validation Tree.
const TrackParameters * m_parameterCache
std::string m_validationTreeFolder
stream/folder to for the TTree to be written out
ToolHandle< IExtrapolator > m_extrapolator
std::string m_validationTreeDescription
validation tree description - second argument in TTree
Class for a planaer rectangular or trapezoidal surface in the ATLAS detector.
Eigen::Matrix< double, 3, 1 > Vector3D
@ alongMomentum
CurvilinearParametersT< TrackParametersDim, Charged, PlaneSurface > CurvilinearParameters
@ locY
local cartesian
Definition ParamDefs.h:38
@ locX
Definition ParamDefs.h:37