ATLAS Offline Software
Loading...
Searching...
No Matches
IterativePriVtxFinderTool.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// ATHENA
8#include "GaudiKernel/IInterface.h"
13
14
15// ACTS
16#include "Acts/Propagator/Navigator.hpp"
17#include "Acts/Propagator/EigenStepper.hpp"
18#include "Acts/Propagator/Propagator.hpp"
19#include "Acts/Utilities/AnnealingUtility.hpp"
20#include "Acts/Vertexing/TrackAtVertex.hpp"
21
22// STL
23#include <iostream>
24#include <memory>
25
26namespace
27{
28 // Helper struct for vertex signal compatibility
29 struct VertexAndSignalComp {
30 xAOD::Vertex* first;
31 double second;
32 VertexAndSignalComp(xAOD::Vertex* p1, double p2)
33 : first(p1), second(p2) {}
34 bool
35 operator < (const VertexAndSignalComp& other) const
36 {return second > other.second;}
37 };
38 } //anonymous namespace
39
40
43{
44 using namespace std::literals::string_literals;
45
46 ATH_CHECK(m_beamSpotKey.initialize());
47 ATH_CHECK(m_trkFilter.retrieve());
48
49 m_logger = makeActsAthenaLogger(this, "Acts");
50
51 ATH_MSG_INFO("Initializing ACTS Iterative Vertex Finder tool");
52 ATH_CHECK(m_ctxProvider.initialize());
53 ATH_CHECK( m_trackingGeometrySvc.retrieve() );
54 std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry
55 = m_trackingGeometrySvc->trackingGeometry();
56
57 Acts::Navigator navigator( Acts::Navigator::Config{ std::move(trackingGeometry) },
58 logger().cloneWithSuffix("Navigator"));
59
60 m_bField = std::make_shared<ATLASMagneticFieldWrapper>();
61 auto stepper = Acts::EigenStepper<>(m_bField);
62 m_propagator = std::make_shared<Propagator>(std::move(stepper),
63 std::move(navigator),
64 logger().cloneWithSuffix("Prop"));
65 // IP Estimator
66 Acts::ImpactPointEstimator::Config ipEstCfg(m_bField, m_propagator);
67 ipEstCfg.maxIterations = m_ipEstMaxIterations;
68 ipEstCfg.precision = m_ipEstPrecision;
69 Acts::ImpactPointEstimator ipEst(ipEstCfg,
70 logger().cloneWithSuffix("ImpactPointEstimator"));
71
72 // Linearizer for Acts::BoundParameters type test
73 TrackLinearizer::Config ltConfig;
74 ltConfig.bField = m_bField;
75 ltConfig.propagator = m_propagator;
76 m_linearizer.emplace(ltConfig, logger().cloneWithSuffix("Linearizer"));
77
78 // Full Billoir Vertex fitter setup
79 VertexFitter::Config fitterCfg;
80 fitterCfg.maxIterations = m_fitterMaxIterations;
81 fitterCfg.extractParameters.connect<&TrackWrapper::extractParameters>();
82 fitterCfg.trackLinearizer.connect<&TrackLinearizer::linearizeTrack>(&*m_linearizer);
83 VertexFitter fitter(fitterCfg, logger().cloneWithSuffix("Fitter"));
84
85
86 // Seed finder setup
87 // Set up Gaussian track density
88 Acts::GaussianTrackDensity::Config trackDensityConfig;
89 trackDensityConfig.d0MaxSignificance = m_gaussianMaxD0Significance;
90 trackDensityConfig.z0MaxSignificance = m_gaussianMaxZ0Significance;
91 trackDensityConfig.extractParameters.connect<&TrackWrapper::extractParameters>();
92 Acts::GaussianTrackDensity trackDensity(trackDensityConfig);
93
94 // Vertex seed finder
95 VertexSeedFinder::Config seedFinderConfig{trackDensity};
96 auto seedFinder = std::make_shared<VertexSeedFinder>(seedFinderConfig);
97
98 // Iterative Vertex Finder setup
99 VertexFinder::Config finderConfig(std::move(fitter),
100 std::move(seedFinder),
101 std::move(ipEst));
102 finderConfig.significanceCutSeeding = m_significanceCutSeeding;
103 finderConfig.maximumChi2cutForSeeding = m_maximumChi2cutForSeeding;
104 finderConfig.maxVertices = m_maxVertices;
105 finderConfig.createSplitVertices = m_createSplitVertices;
106 finderConfig.splitVerticesTrkInvFraction = m_splitVerticesTrkInvFraction;
107 finderConfig.reassignTracksAfterFirstFit = m_reassignTracksAfterFirstFit;
108 finderConfig.doMaxTracksCut = m_doMaxTracksCut;
109 finderConfig.maxTracks = m_maxTracks;
110 finderConfig.cutOffTrackWeight = m_cutOffTrackWeight;
111 finderConfig.extractParameters.connect<&TrackWrapper::extractParameters>();
112 finderConfig.trackLinearizer.connect<&TrackLinearizer::linearizeTrack>(&*m_linearizer);
113 m_vertexFinder = std::make_shared<VertexFinder>(std::move(finderConfig), logger().cloneWithSuffix("Finder"));
114
115 ATH_MSG_INFO("ACTS Iterative Vertex Finder tool successfully initialized");
116 return StatusCode::SUCCESS;
117}
118
119std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
121 const TrackCollection* trackTES) const
122{
123
125 const Trk::RecVertex& beamposition(beamSpotHandle->beamVtx());
126
127 std::vector<std::unique_ptr<Trk::ITrackLink>> selectedTracks;
128
129 typedef DataVector<Trk::Track>::const_iterator TrackDataVecIter;
130
131 bool selectionPassed;
132 for (TrackDataVecIter itr = (*trackTES).begin(); itr != (*trackTES).end(); ++itr) {
134 selectionPassed = static_cast<bool>(m_trkFilter->accept(**itr, &beamposition));
135 } else {
136 Trk::Vertex null(Amg::Vector3D(0, 0, 0));
137 selectionPassed = static_cast<bool>(m_trkFilter->accept(**itr, &null));
138 }
139 if (selectionPassed) {
141 link.setElement(*itr);
142 auto trkPtr = std::make_unique<Trk::LinkToTrack>(link);
143 trkPtr->setStorableObject(*trackTES);
144 selectedTracks.push_back(std::move(trkPtr));
145 }
146 }
147
148 std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*> returnContainers = findVertex(ctx, std::move(selectedTracks));
149
150 return returnContainers;
151}
152
153std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
155 const xAOD::TrackParticleContainer* trackParticles) const
156{
157
158 std::vector<std::unique_ptr<Trk::ITrackLink>> selectedTracks;
160 xAOD::Vertex beamposition;
161 beamposition.makePrivateStore();
162 beamposition.setPosition(beamSpotHandle->beamVtx().position());
163 beamposition.setCovariancePosition(beamSpotHandle->beamVtx().covariancePosition());
164
165 typedef DataVector<xAOD::TrackParticle>::const_iterator TrackParticleDataVecIter;
166
167 bool selectionPassed;
168 for (TrackParticleDataVecIter itr = (*trackParticles).begin(); itr != (*trackParticles).end(); ++itr) {
170 selectionPassed = static_cast<bool>(m_trkFilter->accept(**itr, &beamposition));
171 } else {
172 xAOD::Vertex null;
173 null.makePrivateStore();
174 null.setPosition(Amg::Vector3D(0, 0, 0));
175 AmgSymMatrix(3) vertexError;
176 vertexError.setZero();
177 null.setCovariancePosition(vertexError);
178 selectionPassed = static_cast<bool>(m_trkFilter->accept(**itr, &null));
179 }
180
181 if (selectionPassed) {
183 link.setElement(*itr);
184 auto trkPtr = std::make_unique<Trk::LinkToXAODTrackParticle>(link);
185 trkPtr->setStorableObject(*trackParticles);
186 selectedTracks.push_back(std::move(trkPtr));
187 }
188 }
189
190 std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*> returnContainers = findVertex(ctx, std::move(selectedTracks));
191
192 return returnContainers;
193}
194
195std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
197 const std::vector<std::unique_ptr<Trk::ITrackLink>>& trackVector) const
198{
199
200 using namespace Acts::UnitLiterals;
201
202 // Vertex finding algorithm begins
204
205 // The output vertex containers
206 xAOD::VertexContainer* theVertexContainer = new xAOD::VertexContainer;
207 xAOD::VertexAuxContainer* theVertexAuxContainer = new xAOD::VertexAuxContainer;
208 theVertexContainer->setStore(theVertexAuxContainer);
209
210 // bail out early with only Dummy vertex if multiplicity cut is applied and exceeded
211 if((m_doMaxTracksCut && (trackVector.size() > m_maxTracks)) || trackVector.empty()) {
212 ATH_MSG_WARNING(trackVector.size()
213 << " tracks - exceeds maximum (" << m_maxTracks
214 << "), skipping vertexing and returning only dummy...");
215 xAOD::Vertex* dummyxAODVertex = new xAOD::Vertex;
216 theVertexContainer->push_back(
217 dummyxAODVertex); // have to add vertex to container here first so it can use its aux store
218 dummyxAODVertex->setPosition(beamSpotHandle->beamVtx().position());
219 dummyxAODVertex->setCovariancePosition(
220 beamSpotHandle->beamVtx().covariancePosition());
221 dummyxAODVertex->vxTrackAtVertex() = std::vector<Trk::VxTrackAtVertex>();
222 dummyxAODVertex->setVertexType(xAOD::VxType::NoVtx);
223 return std::make_pair(theVertexContainer, theVertexAuxContainer);
224 }
225
226 const Acts::Vector3& beamSpotPos = beamSpotHandle->beamVtx().position();
227 Acts::Vertex beamSpotConstraintVtx(beamSpotPos);
228 beamSpotConstraintVtx.setCovariance(beamSpotHandle->beamVtx().covariancePosition());
229
230 std::shared_ptr<Acts::PerigeeSurface> perigeeSurface =
231 Acts::Surface::makeShared<Acts::PerigeeSurface>(
232 Amg::toIsometry3D((trackVector[0])->parameters()->associatedSurface().transform()));
233
234 // Get the magnetic field context
235 const Acts::MagneticFieldContext magFieldContext = m_ctxProvider.getMagneticFieldContext(ctx);
236 const Acts::GeometryContext geoContext = m_ctxProvider.getGeometryContext(ctx);
237
238 // Convert tracks to Acts::BoundParameters
239 std::vector<TrackWrapper> allTracks;
240
241 for (const auto& trk : trackVector) {
242
243 const auto& trkParams = trk->parameters();
244 const auto& params = trkParams->parameters();
245
246 Acts::BoundVector actsParams;
247 actsParams << params(0), params(1), params(2), params(3), params(4)*1./(1_MeV), 0.;
248
249 if(trkParams->covariance() == nullptr){
250 continue;
251 }
252 auto cov = *(trkParams->covariance());
253
254 // TODO: check if the following works as well:
255 // cov->col(4) *= 1./1_MeV;
256 // cov->row(4) *= 1./1_MeV;
257 Acts::BoundMatrix covMat;
258 covMat << cov(0,0) , cov(0,1) , cov(0,2) , cov(0,3) , cov(0,4) *1./(1_MeV), 0
259 , cov(1,0) , cov(1,1) , cov(1,2) , cov(1,3) , cov(1,4) *1./(1_MeV) , 0
260 , cov(2,0) , cov(2,1) , cov(2,2) , cov(2,3) , cov(2,4) *1./(1_MeV) , 0
261 , cov(3,0) , cov(3,1) , cov(3,2) , cov(3,3) , cov(3,4) *1./(1_MeV) , 0
262 , cov(4,0) *1./(1_MeV) , cov(4,1) *1./(1_MeV) , cov(4,2) *1./(1_MeV) , cov(4,3) *1./(1_MeV) , cov(4,4) *1./(1_MeV*1_MeV), 0
263 , 0. , 0. , 0. , 0., 0., 1.;
264
265 allTracks.emplace_back(trk.get(),Acts::BoundTrackParameters(perigeeSurface, actsParams, covMat, Acts::ParticleHypothesis::pion()));
266 }
267
268 std::vector<Acts::InputTrack> allTrackPtrs;
269 allTrackPtrs.reserve(allTracks.size());
270
271for(const auto& trk : allTracks){
272 allTrackPtrs.emplace_back(&trk);
273 }
274
275 Acts::VertexingOptions vertexingOptions(geoContext,
276 magFieldContext);
277
279 beamSpotConstraintVtx.setPosition(Acts::Vector3::Zero());
280 beamSpotConstraintVtx.setCovariance(Acts::SquareMatrix<3>::Zero());
281 }
282 vertexingOptions.useConstraintInFit = m_useBeamConstraint;
283
284 //Adding 4th dimensional timing info to vertex constraint as needed by ACTS
285 Acts::Vector4 vtxConstraintPos;
286 Acts::SquareMatrix4 vtxConstraintCov;
287
288 auto beamSpotCov = beamSpotHandle->beamVtx().covariancePosition();
289
290 vtxConstraintPos << beamSpotPos(0), beamSpotPos(1), beamSpotPos(2), 0.;
291 vtxConstraintCov << beamSpotCov(0,0), beamSpotCov(0,1), beamSpotCov(0,2), 0.
292 , beamSpotCov(1,0), beamSpotCov(1,1), beamSpotCov(1,2), 0.
293 , beamSpotCov(2,0), beamSpotCov(2,1), beamSpotCov(2,2), 0.
294 , 0., 0., 0., 1.;
295
296 vertexingOptions.constraint.setFullPosition(vtxConstraintPos);
297 vertexingOptions.constraint.setFullCovariance(vtxConstraintCov);
298
299 auto finderState = m_vertexFinder->makeState(magFieldContext);
300
301 auto findResult = m_vertexFinder->find(allTrackPtrs, vertexingOptions, finderState);
302
303 if(!findResult.ok()){
304 xAOD::Vertex* dummyxAODVertex = new xAOD::Vertex;
305 theVertexContainer->push_back(dummyxAODVertex);
306 dummyxAODVertex->setPosition(beamSpotHandle->beamVtx().position());
307 dummyxAODVertex->setCovariancePosition(beamSpotHandle->beamVtx().covariancePosition());
308 dummyxAODVertex->vxTrackAtVertex() = std::vector<Trk::VxTrackAtVertex>();
309 dummyxAODVertex->setVertexType(xAOD::VxType::NoVtx);
310
311 return std::make_pair(theVertexContainer, theVertexAuxContainer);
312 }
313
314 std::vector<Acts::Vertex> allVertices = *findResult;
315
316 for(const auto& vtx : allVertices){
317 xAOD::Vertex* xAODVtx = new xAOD::Vertex;
318 xAODVtx->makePrivateStore();
319 xAODVtx->setPosition(vtx.position());
320 xAODVtx->setCovariancePosition(vtx.covariance());
321 xAODVtx->setFitQuality(vtx.fitQuality().first, vtx.fitQuality().second);
322
323 const auto& tracks = vtx.tracks();
324 std::vector<Trk::VxTrackAtVertex>* trkAtVtxVec = &(xAODVtx->vxTrackAtVertex());
325 for(const auto& trk : tracks){
326
327 Trk::Perigee* fittedPerigee = actsBoundToTrkPerigee(trk.fittedParams, beamSpotPos);
328 //Trk::Perigee* originalPerigee = actsBoundToTrkPerigee((trk.originalParams)->parameters(), beamSpotPos);
329 const TrackWrapper* originalParams = trk.originalParams.template as<TrackWrapper>();
330
331 //Trk::VxTrackAtVertex trkAtVtx(trk.chi2Track, fittedPerigee, originalPerigee);
332 Trk::VxTrackAtVertex trkAtVtx(originalParams->trackLink()->clone());
333 trkAtVtx.setPerigeeAtVertex(fittedPerigee);
334 trkAtVtx.setTrackQuality(Trk::FitQuality(trk.chi2Track, trk.ndf));
335 trkAtVtx.setVtxCompatibility(trk.vertexCompatibility);
336 trkAtVtx.setWeight(trk.trackWeight);
337 trkAtVtxVec->push_back(std::move(trkAtVtx));
338
339 const Trk::LinkToXAODTrackParticle* linkToXAODTP =
340 dynamic_cast<const Trk::LinkToXAODTrackParticle*>(originalParams->trackLink());
341 if (linkToXAODTP) {
342 xAODVtx->addTrackAtVertex(*linkToXAODTP, trk.trackWeight);
343 }
344 }
345
346 theVertexContainer->push_back(xAODVtx);
347 }
348
350 if (!theVertexContainer->empty()) {
351 xAOD::Vertex* primaryVtx = theVertexContainer->front();
352 if (!primaryVtx->vxTrackAtVertex().empty()) {
354 xAOD::Vertex* dummyxAODVertex = new xAOD::Vertex;
355 theVertexContainer->push_back(dummyxAODVertex);
356 dummyxAODVertex->setPosition(primaryVtx->position());
357 dummyxAODVertex->setCovariancePosition(primaryVtx->covariancePosition());
358 dummyxAODVertex->vxTrackAtVertex() = std::vector<Trk::VxTrackAtVertex>();
359 dummyxAODVertex->setVertexType(xAOD::VxType::NoVtx);
360 } else {
362 }
363 } else {
364 xAOD::Vertex* dummyxAODVertex = new xAOD::Vertex;
365 theVertexContainer->push_back(dummyxAODVertex);
366 dummyxAODVertex->setPosition(beamSpotHandle->beamVtx().position());
367 dummyxAODVertex->setCovariancePosition(beamSpotHandle->beamVtx().covariancePosition());
368 dummyxAODVertex->vxTrackAtVertex() = std::vector<Trk::VxTrackAtVertex>();
369 dummyxAODVertex->setVertexType(xAOD::VxType::NoVtx);
370 }
371
372 // loop over the pile up to set it as pile up (EXCLUDE first and last
373 // vertex, do not do that in split mode)
374 for (unsigned int i = 0; i < theVertexContainer->size() - 1; i++) {
375
377 " Vtx: " << i << " x= " << (*theVertexContainer)[i]->position().x()
378 << " y= " << (*theVertexContainer)[i]->position().y() << " z= "
379 << (*theVertexContainer)[i]->position().z() << " ntracks= "
380 << (*theVertexContainer)[i]->vxTrackAtVertex().size()
381 << " chi2= " << (*theVertexContainer)[i]->chiSquared()
382 << " ndf = " << (*theVertexContainer)[i]->numberDoF());
383 if (i > 0) {
384 (*theVertexContainer)[i]->setVertexType(xAOD::VxType::PileUp);
385 }
386 }
387 }
388
389 return std::make_pair(theVertexContainer, theVertexAuxContainer);
390}
391
393ActsTrk::IterativePriVtxFinderTool::actsBoundToTrkPerigee(const Acts::BoundTrackParameters& bound,
394 const Acts::Vector3& surfCenter) const {
395 using namespace Acts::UnitLiterals;
396 AmgSymMatrix(5) cov = AmgSymMatrix(5)(bound.covariance()->block<5,5>(0,0));
397 cov.col(Trk::qOverP) *= 1_MeV;
398 cov.row(Trk::qOverP) *= 1_MeV;
399 Acts::Vector<5> params = bound.parameters().head<5>();
400 params[Trk::qOverP] *= 1_MeV;
401
402 return new Trk::Perigee(params, Trk::PerigeeSurface(surfCenter), std::move(cov));
403}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_INFO(x,...)
bool operator<(const DataVector< T > &a, const DataVector< T > &b)
Vector ordering relation.
#define AmgSymMatrix(dim)
size_t size() const
Number of registered mappings.
DataVector< Trk::Track > TrackCollection
This typedef represents a collection of Trk::Track objects.
std::unique_ptr< const Acts::Logger > makeActsAthenaLogger(IMessageSvc *svc, const std::string &name, int level, std::optional< std::string > parent_name)
Definition Logger.cxx:64
#define y
#define x
#define z
static Acts::BoundTrackParameters extractParameters(const Acts::InputTrack &input)
ContextUtility m_ctxProvider
Auxiliary class to access the magnetic field, geometry and calibration context.
std::shared_ptr< Propagator > m_propagator
virtual std::pair< xAOD::VertexContainer *, xAOD::VertexAuxContainer * > findVertex(const EventContext &ctx, const TrackCollection *trackTES) const override
std::optional< TrackLinearizer > m_linearizer
std::unique_ptr< const Acts::Logger > m_logger
logging instance
Trk::Perigee * actsBoundToTrkPerigee(const Acts::BoundTrackParameters &bound, const Acts::Vector3 &surfCenter) const
std::shared_ptr< ATLASMagneticFieldWrapper > m_bField
std::shared_ptr< VertexFinder > m_vertexFinder
ToolHandle< InDet::IInDetTrackSelectionTool > m_trkFilter
UnsignedIntegerProperty m_splitVerticesTrkInvFraction
ServiceHandle< ActsTrk::ITrackingGeometrySvc > m_trackingGeometrySvc
Acts::FullBilloirVertexFitter VertexFitter
SG::ReadCondHandleKey< InDet::BeamSpotData > m_beamSpotKey
DataModel_detail::const_iterator< DataVector > const_iterator
Standard const_iterator.
Definition DataVector.h:861
value_type push_back(value_type pElem)
Add an element to the end of the collection.
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.
bool empty() const noexcept
Returns true if the collection is empty.
Class to represent and store fit qualities from track reconstruction in terms of and number of degre...
Definition FitQuality.h:97
Element link to XAOD TrackParticle.
Class describing the Line to which the Perigee refers to.
Trk::RecVertex inherits from Trk::Vertex.
Definition RecVertex.h:44
This class is a simplest representation of a vertex candidate.
The VxTrackAtVertex is a common class for all present TrkVertexFitters The VxTrackAtVertex is designe...
void setTrackQuality(const FitQuality &trkQuality)
Set methods for various components.
void setPerigeeAtVertex(TrackParameters *perigee)
Setting up parameters at vertex.
void setWeight(const double)
Set method for a weight.
void setVtxCompatibility(const double)
void setCovariancePosition(const AmgSymMatrix(3)&covariancePosition)
Sets the vertex covariance matrix.
void addTrackAtVertex(const ElementLink< TrackParticleContainer > &tr, float weight=1.0)
Add a new track to the vertex.
void setVertexType(VxType::VertexType vType)
Set the type of the vertex.
void setPosition(const Amg::Vector3D &position)
Sets the 3-position.
std::vector< Trk::VxTrackAtVertex > & vxTrackAtVertex()
Non-const access to the VxTrackAtVertex vector.
void setFitQuality(float chiSquared, float numberDoF)
Set the 'Fit Quality' information.
const Amg::Vector3D & position() const
Returns the 3-pos.
Amg::Isometry3D toIsometry3D(const Isometry3D &iso)
Eigen::Matrix< double, 3, 1 > Vector3D
::StatusCode StatusCode
StatusCode definition for legacy code.
@ PriVtx
Primary Vertex.
Definition VertexType.h:27
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
@ qOverP
perigee
Definition ParamDefs.h:67
VertexType
Vertex types.
@ PileUp
Pile-up vertex.
@ NoVtx
Dummy vertex. TrackParticle was not used in vertex fit.
VertexAuxContainer_v1 VertexAuxContainer
Definition of the current jet auxiliary container.
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".