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