ATLAS Offline Software
Loading...
Searching...
No Matches
VertexSignificance.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
7#include <algorithm>
8#include <cmath>
9
10namespace Analysis {
11
12 double get3DSignificance(const xAOD::Vertex& priVertex,
13 const std::vector<const xAOD::Vertex*>& secVertex,
14 const Amg::Vector3D& jetDirection) {
15
16 std::vector<Amg::Vector3D> positions;
17 std::vector<AmgSymMatrix(3)> weightMatrices;
18 // If multiple secondary vertices were reconstructed, then a common (weighted) position will be used
19 // in the signed decay length significance calculation
20 Amg::Vector3D weightTimesPosition(0.,0.,0.);
21 AmgSymMatrix(3) sumWeights;
22 sumWeights.setZero();
23
24 for (const auto& vtx : secVertex) {
25 positions.push_back(vtx->position());
26 weightMatrices.push_back(vtx->covariancePosition().inverse());
27 weightTimesPosition += weightMatrices.back()*positions.back();
28 sumWeights += weightMatrices.back();
29 }
30
31 // now we have the sum of the weights, let's invert this matrix to get the mean covariance matrix
32 bool invertible;
33 AmgSymMatrix(3) meanCovariance;
34 meanCovariance.setZero();
35 sumWeights.computeInverseWithCheck(meanCovariance, invertible);
36 if (!invertible) return 0.;
37
38 // calculate the weighted mean secondary vertex position
39 Amg::Vector3D meanPosition = meanCovariance*weightTimesPosition;
40
41 // add the mean covariance matrix of the secondary vertices to that of the primary vertex
42 // this is the covariance matrix for the decay length
43 AmgSymMatrix(3) covariance = meanCovariance + priVertex.covariancePosition();
44
45 const Amg::Vector3D decayVector = meanPosition - priVertex.position();
46 const double decaylength = decayVector.norm();
47 if (decaylength == 0.) return 0.; //Safety
48
49 const Amg::Vector3D gradient = decayVector / decaylength;
50 const double decaylength_err2 = gradient.dot(covariance * gradient);
51 if (decaylength_err2 <= 0.) return 0.; //Something is wrong
52
53 double decaylength_significance = decaylength / std::sqrt(decaylength_err2);
54
55 // get sign from projection on jet axis
56 if (decayVector.dot(jetDirection) < 0.) decaylength_significance *= -1.;
57
58 return decaylength_significance;
59 }
60
61 double get3DSignificanceCorr(const xAOD::Vertex& priVertex,
62 const std::vector<const xAOD::Vertex*>& secVertex,
63 const Amg::Vector3D& jetDirection) {
64
65 std::vector<double> Sig3D(0);
66 bool success=true;
67 AmgSymMatrix(3) Wgt;
68
69 for (const auto & svrt : secVertex)
70 {
71 Amg::Vector3D SVmPV = svrt->position()-priVertex.position();
72 AmgSymMatrix(3) SVmPVCov = svrt->covariancePosition()+priVertex.covariancePosition();
73 SVmPVCov.computeInverseWithCheck(Wgt, success);
74 if( !success || Wgt(0,0)<=0. || Wgt(1,1)<=0. || Wgt(2,2)<=0. )continue; //Inversion failure
75 double significance = SVmPV.transpose()*Wgt*SVmPV;
76 if(significance <= 0.) continue; //Something is still wrong!
77 significance = std::sqrt(significance);
78 if(SVmPV.dot(jetDirection)<0.) significance *= -1.;
79 Sig3D.push_back(significance);
80 }
81
82 if(Sig3D.size()==0) return 0.;
83
84 return *std::max_element(Sig3D.begin(),Sig3D.end());
85 }
86
87}
#define AmgSymMatrix(dim)
const Amg::Vector3D & position() const
Returns the 3-pos.
Eigen::Matrix< double, 3, 1 > Vector3D
The namespace of all packages in PhysicsAnalysis/JetTagging.
double get3DSignificanceCorr(const xAOD::Vertex &priVertex, const std::vector< const xAOD::Vertex * > &secVertex, const Amg::Vector3D &jetDirection)
Largest signed significance of the individual secondary vertices with respect to the primary vertex.
double get3DSignificance(const xAOD::Vertex &priVertex, const std::vector< const xAOD::Vertex * > &secVertex, const Amg::Vector3D &jetDirection)
Signed decay length significance of the weighted mean of the secondary vertices with respect to the p...
Vertex_v1 Vertex
Define the latest version of the vertex class.