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::BoundSquareMatrix 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::ActsSquareMatrix<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::ActsVector<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)
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.
void makePrivateStore()
Create a new (empty) private store for this object.
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".