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