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