ATLAS Offline Software
Loading...
Searching...
No Matches
PoorMansIpAugmenterAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
5
7
10
14
16
17// NOTE: would be nice to include this to access track parameters, but
18// it's not in all builds.
19//
20// #include "TrkEventPrimitives/ParamDefs.h"
21
22namespace Pmt {
23 // copied from
24 // https://acode-browser1.usatlas.bnl.gov/lxr/source/athena/Tracking/TrkEvent/TrkEventPrimitives/TrkEventPrimitives/ParamDefs.h,
25 // which isn't included in some builds.
26 enum ParamDefs {
27 // Track defining parameters
28 d0 = 0,
29 z0 = 1,
30 phi0 = 2,
31 theta = 3,
32 qOverP = 4,
33 // Cartesian
34 x = 0,
35 y = 1,
36 z = 2,
37 };
38
39 // I'm pretty sure I can get x, y, z, beamspot perigee points from
40 // x = -sin(phi) * d0
41 // y = cos(phi) * d0
42 // z = z0
43 Eigen::Vector3d getPosition(
44 const xAOD::TrackParticle& trk) {
45 double d0 = trk.d0();
46 double phi = trk.phi();
47 return Amg::Vector3D(
48 d0 * -std::sin(phi),
49 d0 * std::cos(phi),
50 trk.z0());
51 }
52
53 // this one is going to be harder, there's some lead here:
54 // https://acode-browser1.usatlas.bnl.gov/lxr/source/athena/Tracking/TrkVertexFitter/TrkVertexFitterUtils/src/TrackToVertexIPEstimator.cxx
56 const Eigen::Matrix2d& vtxCov) {
57
58 // start with the track part
59 double trackComponent = trk.definingParametersCovMatrixDiagVec().at(
60 Pmt::d0);
61
62 // now do the vertex part
63 double phi = trk.phi();
64 // The sign seems inverted below, but maybe that doesn't
65 // matter. I'm just following TrackToVertexIPEstimator...
66 Eigen::Vector2d vtxJacobian(-std::sin(phi), std::cos(phi));
67 double vertexComponent = vtxJacobian.transpose()*vtxCov*vtxJacobian;
68
69 return std::sqrt(trackComponent + vertexComponent);
70
71 }
72
74 const xAOD::Vertex& vtx) {
75
76 // first two elements of the vertex covariance is xy
77 Eigen::Matrix2d vtxCov = vtx.covariancePosition().block<2,2>(0,0);
78 return getSigmaD0(trk, vtxCov);
79
80 }
81
83 const xAOD::EventInfo& evt) {
84 Eigen::Matrix2d bsCov;
85 // based on what I read in the beamspot code [1] and some code
86 // that copies it to the EventInfo [2] I'm pretty sure the
87 // beamPosSigmaX and beamPosSigmaY need to be squared in the
88 // covariance matrix, whereas beamPosSigmaXY does not.
89 //
90 // [1]: https://acode-browser1.usatlas.bnl.gov/lxr/source/athena/InnerDetector/InDetConditions/BeamSpotConditionsData/src/BeamSpotData.cxx
91 // [2]: https://acode-browser1.usatlas.bnl.gov/lxr/source/athena/Simulation/BeamEffects/src/BeamSpotFixerAlg.cxx#0068
92 bsCov(0, 0) = std::pow(evt.beamPosSigmaX(),2);
93 bsCov(0, 1) = evt.beamPosSigmaXY();
94 bsCov(1, 0) = evt.beamPosSigmaXY();
95 bsCov(1, 1) = std::pow(evt.beamPosSigmaY(),2);
96 return getSigmaD0(trk, bsCov);
97 }
98
99
101 double vxZCov) {
102
103 // first do the track part
104 const auto& fullCov = trk.definingParametersCovMatrix();
105 Eigen::Matrix2d trkCov;
106 trkCov(0,0)=fullCov(Pmt::z0, Pmt::z0);
107 trkCov(0,1)=fullCov(Pmt::z0, Pmt::theta);
108 trkCov(1,0)=fullCov(Pmt::theta, Pmt::z0);
109 trkCov(1,1)=fullCov(Pmt::theta, Pmt::theta);
110 double theta = trk.theta();
111 Eigen::Vector2d trkJacobian(
112 std::sin(theta),
113 trk.z0()*std::cos(theta));
114 double trackComponent = trkJacobian.transpose()*trkCov*trkJacobian;
115
116 // now do the vertex part
117 double vertexComponent = std::sin(theta)*vxZCov*std::sin(theta);
118
119 return std::sqrt(trackComponent + vertexComponent);
120
121 }
123 const xAOD::Vertex& vtx) {
124 double vxZCov = vtx.covariancePosition()(Pmt::z,Pmt::z);
125 return getSigmaZ0SinTheta(trk, vxZCov);
126 }
127
128}
129
130namespace FlavorTagDiscriminants {
131
133 const std::string& name, ISvcLocator* loc )
134 : AthReentrantAlgorithm(name, loc) {}
135
137 ATH_MSG_INFO( "Inizializing " << name() << "... " );
139 ATH_MSG_INFO( "Running modified PoorMansIpAugmenter with d0 correction!" );
140 }
141 // Initialize Container keys
142 ATH_MSG_DEBUG( "Inizializing containers:" );
145 ATH_MSG_DEBUG( " ** " << m_eventInfoKey );
146
147 ATH_CHECK( m_TrackContainerKey.initialize() );
148 ATH_CHECK( m_eventInfoKey.initialize() );
149
150 bool use_vertices = !m_VertexContainerKey.empty();
151 ATH_CHECK( m_VertexContainerKey.initialize(use_vertices) );
152
153 // Prepare decorators
154 m_dec_d0_sigma = m_TrackContainerKey.key() + "." + m_prefix.value() + m_dec_d0_sigma.key();
155 m_dec_z0_sigma = m_TrackContainerKey.key() + "." + m_prefix.value() + m_dec_z0_sigma.key();
156
157 m_dec_track_pos = m_TrackContainerKey.key() + "." + m_prefix.value() + m_dec_track_pos.key();
158 m_dec_track_mom = m_TrackContainerKey.key() + "." + m_prefix.value() + m_dec_track_mom.key();
159 m_dec_invalid = m_TrackContainerKey.key() + "." + m_prefix.value() + m_dec_invalid.key();
160
161 // Initialize decorators
162 ATH_MSG_DEBUG( "Inizializing decorators:" );
163 ATH_MSG_DEBUG( " ** " << m_dec_d0_sigma );
164 ATH_MSG_DEBUG( " ** " << m_dec_z0_sigma );
165 ATH_MSG_DEBUG( " ** " << m_dec_track_pos );
166 ATH_MSG_DEBUG( " ** " << m_dec_track_mom );
167 ATH_MSG_DEBUG( " ** " << m_dec_invalid );
168
169 CHECK( m_dec_d0_sigma.initialize() );
170 CHECK( m_dec_z0_sigma.initialize() );
171 CHECK( m_dec_track_pos.initialize() );
172 CHECK( m_dec_track_mom.initialize() );
173 CHECK( m_dec_invalid.initialize() );
174
176 "Accessors for beamspot:" <<
177 " ** " << m_beam_sigma_x <<
178 " ** " << m_beam_sigma_y <<
179 " ** " << m_beam_sigma_z <<
180 " ** " << m_beam_cov_xy <<
181 "");
182
183 CHECK( m_beam_sigma_x.initialize() );
184 CHECK( m_beam_sigma_y.initialize() );
185 CHECK( m_beam_sigma_z.initialize() );
186 CHECK( m_beam_cov_xy.initialize() );
187
188 return StatusCode::SUCCESS;
189 }
190
191 StatusCode PoorMansIpAugmenterAlg::execute(const EventContext& ctx) const {
192 ATH_MSG_DEBUG( "Executing " << name() << "... " );
193
195 CHECK( event_info.isValid() );
196
197 const xAOD::Vertex* primary = nullptr;
198 if (!m_VertexContainerKey.empty()) {
201 CHECK( verteces.isValid() );
202 primary = getPrimaryVertex( *verteces );
203 if ( primary == nullptr ) {
204 ATH_MSG_FATAL("No primary vertex found");
205 return StatusCode::FAILURE;
206 }
207 }
208
211 CHECK( tracks.isValid() );
212 ATH_MSG_DEBUG( "Retrieved " << tracks->size() << " input tracks..." );
213
215
218
220 m_dec_track_pos, ctx);
222 m_dec_track_mom, ctx);
223
225
227 m_beam_sigma_x, ctx);
229 m_beam_sigma_y, ctx);
231 m_beam_sigma_z, ctx);
233 m_beam_cov_xy, ctx);
234
235 // now decorate the tracks
236 for (const xAOD::TrackParticle *trk: *tracks) {
237
238 const xAOD::EventInfo& evt = *event_info;
239 float d0_sigma2 = trk->definingParametersCovMatrixDiagVec().at(Pmt::d0);
241 trk->phi(),
242 beam_sigma_x(evt),
243 beam_sigma_y(evt),
244 beam_cov_xy(evt));
245 float full_d0_sigma = std::sqrt(d0_sigma2 + bs_d0_sigma2);
246 ATH_MSG_DEBUG("track d0Uncertainty: " << std::sqrt(d0_sigma2));
247 ATH_MSG_DEBUG("beamspot d0Uncertainty: " << std::sqrt(bs_d0_sigma2));
248 ATH_MSG_DEBUG("combined d0Uncertainty: " << full_d0_sigma);
249
250 decor_d0_sigma(*trk) = full_d0_sigma;
251 if (primary) {
252 decor_z0_sigma(*trk) = Pmt::getSigmaZ0SinTheta(*trk, *primary);
253 } else {
254 // if we don't have a primary we take the beamspot z
255 // uncertainty
256 double vxZCov = std::pow(beam_sigma_z(evt), 2);
257 decor_z0_sigma(*trk) = Pmt::getSigmaZ0SinTheta(*trk, vxZCov);
258 }
259
260 // the primary vertex position is absolute, whereas the track
261 // perigee parameters are all relative to the beamspot.
262
263
264 // If m_d0_modification (Gaudi property) is true, the beamspot (x,y) is
265 // subtracted from the primary vertex position, modifying d0
266 // relative to the beamspot.
267 // If false, only z0 is made relative to the beamspot,
268 // leaving d0 unmodified (existing PoorMansIp behaviour).
269 // In both cases, z0 is made relative to the beamspot.
270
271 const Amg::Vector3D primary_relative_to_beamspot(
272 m_d0_modification && primary ? primary->position().x() - trk->vx() : 0,
273 m_d0_modification && primary ? primary->position().y() - trk->vy() : 0,
274 primary ? primary->position().z() - trk->vz() : 0);
275 const Amg::Vector3D position = (
276 Pmt::getPosition(*trk) - primary_relative_to_beamspot);
277
278 auto trkp4 = trk->p4();
279 const Amg::Vector3D momentum(trkp4.Px(), trkp4.Py(), trkp4.Pz());
280
282 "track_displacement (x,y,z)= ("
283 << position.x() << ", " << position.y() << ", " << position.z()
284 << ")");
286 "track_momentum (x,y,z)= ("
287 << momentum.x() << ", " << momentum.y() << ", " << momentum.z()
288 << ")");
289
290 std::vector<float> out_vec_pos(
291 position.data(), position.data() + position.size());
292 std::vector<float> out_vec_mom(
293 momentum.data(), momentum.data() + momentum.size());
294
295 decor_track_pos (*trk) = out_vec_pos;
296 decor_track_mom (*trk) = out_vec_mom;
297
298 // all tracks are valid for now, but downstream code requires
299 // this decoration.
300 decor_invalid(*trk) = 0;
301 }
302
303 return StatusCode::SUCCESS;
304 }
305
307 return StatusCode::SUCCESS;
308 }
309
311 const xAOD::VertexContainer& vertexCollection ) const {
312 if ( vertexCollection.size() == 0 ) {
313 ATH_MSG_DEBUG( "Input vertex collection has size 0!" );
314 return nullptr;
315 }
316
317 for ( const xAOD::Vertex *vertex : vertexCollection ) {
318 if ( vertex->vertexType() == xAOD::VxType::PriVtx ) {
319 return vertex;
320 }
321 }
322
323 // this is taken from BTagTool, should be the beam spot if nothing
324 // else exists.
325 return vertexCollection.front();
326 }
327
328}
329
330
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
#define CHECK(...)
Evaluate an expression and check for errors.
Handle class for reading a decoration on an object.
Handle class for adding a decoration to an object.
An algorithm that can be simultaneously executed in multiple threads.
const T * front() const
Access the first element in the collection as an rvalue.
size_type size() const noexcept
Returns the number of elements in the collection.
SG::ReadDecorHandleKey< xAOD::EventInfo > m_beam_cov_xy
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_TrackContainerKey
SG::WriteDecorHandleKey< xAOD::TrackParticleContainer > m_dec_track_pos
SG::WriteDecorHandleKey< xAOD::TrackParticleContainer > m_dec_z0_sigma
const xAOD::Vertex * getPrimaryVertex(const xAOD::VertexContainer &) const
SG::ReadDecorHandleKey< xAOD::EventInfo > m_beam_sigma_x
SG::ReadHandleKey< xAOD::VertexContainer > m_VertexContainerKey
SG::WriteDecorHandleKey< xAOD::TrackParticleContainer > m_dec_track_mom
SG::ReadDecorHandleKey< xAOD::EventInfo > m_beam_sigma_z
virtual StatusCode execute(const EventContext &) const override
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
SG::ReadDecorHandleKey< xAOD::EventInfo > m_beam_sigma_y
SG::WriteDecorHandleKey< xAOD::TrackParticleContainer > m_dec_invalid
PoorMansIpAugmenterAlg(const std::string &name, ISvcLocator *pSvcLocator)
SG::WriteDecorHandleKey< xAOD::TrackParticleContainer > m_dec_d0_sigma
Handle class for reading a decoration on an object.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
Handle class for adding a decoration to an object.
float z0() const
Returns the parameter.
const std::vector< float > & definingParametersCovMatrixDiagVec() const
Returns the diagonal elements of the defining parameters covariance matrix.
float theta() const
Returns the parameter, which has range 0 to .
virtual double phi() const override final
The azimuthal angle ( ) of the particle (has range to .).
const ParametersCovMatrix_t definingParametersCovMatrix() const
Returns the 5x5 symmetric matrix containing the defining parameters covariance matrix.
float d0() const
Returns the parameter.
Eigen::Matrix< double, 3, 1 > Vector3D
double getSigmaD0(const xAOD::TrackParticle &trk, const Eigen::Matrix2d &vtxCov)
double getSigmaD0WithRespectToBeamspot(const xAOD::TrackParticle &trk, const xAOD::EventInfo &evt)
double getSigmaZ0SinTheta(const xAOD::TrackParticle &trk, double vxZCov)
Eigen::Vector3d getPosition(const xAOD::TrackParticle &trk)
double d0UncertaintyBeamSpot2(double track_phi0, double beam_sigma_x, double beam_sigma_y, double beam_sigma_xy)
calculate the squared d0 uncertainty component due to the size of the beam spot.
@ PriVtx
Primary vertex.
EventInfo_v1 EventInfo
Definition of the latest event info version.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
VertexContainer_v1 VertexContainer
Definition of the current "Vertex container version".
Vertex_v1 Vertex
Define the latest version of the vertex class.
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".