ATLAS Offline Software
Loading...
Searching...
No Matches
AdaptiveVertexFitter.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5
6/***************************************************************************
7 AdaptiveVertexFitter.cxx - Description in header file
8 ***************************************************************************/
9
11
20
21//xAOD includes
22#include "xAODTracking/Vertex.h"
25
26namespace Trk
27{
28
29 AdaptiveVertexFitter::AdaptiveVertexFitter(const std::string& t, const std::string& n, const IInterface* p) :
30 base_class(t,n,p),
33 m_initialError(0.0001),
34 m_onlyzseed(false),
35 m_doSmoothing(true)
36 {
37 declareProperty("MaxIterations", m_maxIterations);
38 declareProperty("MaxDistToLinPoint", m_maxDistToLinPoint);
39 declareProperty("InitialError",m_initialError);
40 declareProperty("onlyzseed",m_onlyzseed);
41 declareProperty("DoSmoothing",m_doSmoothing);
42 declareInterface<IVertexFitter>(this);
43 }
44
46
48 {
49 StatusCode s = AlgTool::initialize();
50 if (s.isFailure())
51 {
52 msg(MSG::FATAL) << "AlgTool::initialize() failed" << endmsg;
53 return StatusCode::FAILURE;
54 }
55 if ( m_SeedFinder.retrieve().isFailure() ) {
56 msg(MSG::FATAL) << "Failed to retrieve tool " << m_SeedFinder << endmsg;
57 return StatusCode::FAILURE;
58 }
59 msg(MSG::INFO) << "Retrieved tool " << m_SeedFinder << endmsg;
60
61
62 if ( m_LinearizedTrackFactory.retrieve().isFailure() ) {
63 msg(MSG::FATAL) << "Failed to retrieve tool " << m_LinearizedTrackFactory << endmsg;
64 return StatusCode::FAILURE;
65 }
66 msg(MSG::INFO) << "Retrieved tool " << m_LinearizedTrackFactory << endmsg;
67
68
69 if ( m_TrackCompatibilityEstimator.retrieve().isFailure() ) {
70 msg(MSG::FATAL) << "Failed to retrieve tool " << m_TrackCompatibilityEstimator << endmsg;
71 return StatusCode::FAILURE;
72 }
73 msg(MSG::INFO) << "Retrieved tool " << m_TrackCompatibilityEstimator << endmsg;
74
75
76 if ( m_ImpactPoint3dEstimator.retrieve().isFailure() ) {
77 msg(MSG::FATAL) << "Failed to retrieve tool " << m_ImpactPoint3dEstimator << endmsg;
78 return StatusCode::FAILURE;
79 }
80 msg(MSG::INFO) << "Retrieved tool " << m_ImpactPoint3dEstimator << endmsg;
81
82
83 if ( m_VertexUpdator.retrieve().isFailure() ) {
84 msg(MSG::FATAL) << "Failed to retrieve tool " << m_VertexUpdator << endmsg;
85 return StatusCode::FAILURE;
86 }
87 msg(MSG::INFO) << "Retrieved tool " << m_VertexUpdator << endmsg;
88
89
90 //loading smoother in case required
92 {
93 if ( m_VertexSmoother.retrieve().isFailure() ) {
94 msg(MSG::FATAL) << "Failed to retrieve tool " << m_VertexSmoother << endmsg;
95 return StatusCode::FAILURE;
96 }
97 msg(MSG::INFO) << "Retrieved tool " << m_VertexSmoother << endmsg;
98
99 }//end of smoothing options
100
101 if ( m_AnnealingMaker.retrieve().isFailure() ) {
102 msg(MSG::FATAL) << "Failed to retrieve tool " << m_AnnealingMaker << endmsg;
103 return StatusCode::FAILURE;
104 }
105 msg(MSG::INFO) << "Retrieved tool " << m_AnnealingMaker << endmsg;
106
107
108 return StatusCode::SUCCESS;
109 }
110
111
112 std::unique_ptr<xAOD::Vertex>
114 const std::vector<const Trk::TrackParameters*>& perigeeList,
115 const std::vector<const Trk::NeutralParameters*>& neutralPerigeeList,
116 const xAOD::Vertex& constraint, // initialized to xAOD::Vertex()
117 const Amg::Vector3D& startingPoint, // initialized to Amg::Vector3D()
118 bool IsConstraint, // initialized to false
119 bool IsStartingPoint) const // initialized to false
120 {
121
122 //check the number of tracks
123 if ( (perigeeList.size() + neutralPerigeeList.size())<2 && !IsConstraint ) {
124 msg(MSG::WARNING) << "Not enough tracks (>2) to fit in this event (without constraint)." << endmsg;
125 return nullptr;
126 }
127 if ((perigeeList.size() + neutralPerigeeList.size())<1 && IsConstraint) {
128 msg(MSG::WARNING) << "Not enough tracks (>1) to fit in this event (with constraint)." << endmsg;
129 return nullptr;
130 }
131
132
133 Amg::Vector3D SeedPoint;
134 //now find the best point for seeding and linearization of the tracks
135 if (IsStartingPoint) {
136 SeedPoint=startingPoint;
137 } else {
138 if (perigeeList.size()>1) {
139 if (IsConstraint) {
140 SeedPoint=m_SeedFinder->findSeed(perigeeList,&constraint);
141 } else {
142 SeedPoint=m_SeedFinder->findSeed(perigeeList);
143 }
144 }
145 else if (IsConstraint) {
146 SeedPoint=constraint.position();
147 }
148 else {
149 SeedPoint.setZero();
150 }
151 }
152
153 //in case m_onlyzseed is on, just use only the z component given by the seed finder
154 if (m_onlyzseed&&IsConstraint) {
155 SeedPoint=constraint.position();
156 }
157
158
159 //now create a Global Position with the linearized track and the linearization point
160 //which in this case is taken from the found seed for the vertex
161 //use the linPoint to linearize tracks
162
163 std::vector<VxTrackAtVertex> theLinTracks;
164
165 std::vector<const Trk::TrackParameters*>::const_iterator perigeesBegin=perigeeList.begin();
166 std::vector<const Trk::TrackParameters*>::const_iterator perigeesEnd=perigeeList.end();
167
168 ATH_MSG_DEBUG("Inside fitter with track perigee parameters.");
169 ATH_MSG_DEBUG("Seed point: " << SeedPoint);
170 int myDebugNTrk(0);
171
172 for (std::vector<const Trk::TrackParameters*>::const_iterator perigeesIter=perigeesBegin;perigeesIter!=perigeesEnd;++perigeesIter) {
173 // const MeasuredPerigee* castToMP=dynamic_cast<const MeasuredPerigee*>(*perigeesIter);
174 // if (castToMP==0) {
175 // msg << MSG::ERROR << "Cast to MeasuredPerigee not successfull. Treatment of neutrals not supported. Skipping track..." << endmsg;
176 // continue;
177 // }
178
179 ATH_MSG_DEBUG("Track #" << myDebugNTrk++ << ". TrackParameters: x = " << (*perigeesIter)->position().x() << ", y = "<< (*perigeesIter)->position().y() <<", z = "<< (*perigeesIter)->position().z() << ". Covariance: " << *(*perigeesIter)->covariance());
180
181 VxTrackAtVertex* LinTrackToAdd = new VxTrackAtVertex(0., nullptr, nullptr, (*perigeesIter), nullptr); //TODO: Must think now about when to delete this memory! -David S.
182
183 //m_LinearizedTrackFactory->linearize(*LinTrackToAdd,SeedPoint); why linearize it? maybe you don't need it at all!!!!! <19-05-2006>
184 bool success=m_ImpactPoint3dEstimator->addIP3dAtaPlane(*LinTrackToAdd,SeedPoint);
185 if (!success)
186 {
187 msg(MSG::DEBUG) << "Adding compatibility to vertex information failed. Newton distance finder didn't converge..." << endmsg;
188 }
189
190 theLinTracks.push_back(*LinTrackToAdd);
191
192 delete LinTrackToAdd; //TODO: is here ok?
193
194 }
195
196 std::vector<const Trk::NeutralParameters*>::const_iterator neutralPerigeesBegin=neutralPerigeeList.begin();
197 std::vector<const Trk::NeutralParameters*>::const_iterator neutralPerigeesEnd =neutralPerigeeList.end();
198
199 ATH_MSG_DEBUG("Inside fitter with neutral perigee parameters.");
200 ATH_MSG_DEBUG("Seed point: " << SeedPoint);
201 int myDebugNNeutral(0);
202 for (std::vector<const Trk::NeutralParameters*>::const_iterator neutralPerigeesIter=neutralPerigeesBegin;neutralPerigeesIter!=neutralPerigeesEnd;++neutralPerigeesIter) {
203
204 ATH_MSG_DEBUG("Neutral #" << myDebugNNeutral++ << ". NeutralParameters: x = " << (*neutralPerigeesIter)->position().x() << ", y = "<< (*neutralPerigeesIter)->position().y() <<", z = "<< (*neutralPerigeesIter)->position().z());
205 ATH_MSG_DEBUG(" Covariance: " << *(*neutralPerigeesIter)->covariance());
206 ATH_MSG_DEBUG(" Momentum: x = " << (*neutralPerigeesIter)->momentum().x() << ", y = "<< (*neutralPerigeesIter)->momentum().y() <<", z = "<< (*neutralPerigeesIter)->momentum().z());
207
208 VxTrackAtVertex* LinTrackToAdd = new VxTrackAtVertex(0., nullptr, nullptr, nullptr, (*neutralPerigeesIter) ); //TODO: Must think now about when to delete this memory! -David S.
209
210 bool success = m_ImpactPoint3dEstimator->addIP3dAtaPlane(*LinTrackToAdd,SeedPoint);
211 if (!success)
212 {
213 msg(MSG::DEBUG) << "Adding compatibility to vertex information failed. Newton distance finder didn't converge..." << endmsg;
214 }
215
216 theLinTracks.push_back(*LinTrackToAdd);
217
218 delete LinTrackToAdd; //TODO: is here ok?
219 }
220
221
222
223 //Initialize the vertex seed with an arbitrary great error matrix (just starting point,
224 //not really prior information in it)
225 if(msgLvl(MSG::VERBOSE))
226 {
227 msg(MSG::VERBOSE) << "Error at the beginning is set to " << m_initialError << endmsg;
228 }
229
230
231
232
233 xAOD::Vertex ConstraintVertex;
234 ConstraintVertex.makePrivateStore();
235 //use the previous prior vertex info for the initial vertex if there
236 if (IsConstraint ) {
237 ConstraintVertex.setPosition( constraint.position() );
238 ConstraintVertex.setCovariancePosition( constraint.covariancePosition() );
239 ConstraintVertex.setFitQuality( 0., 0. );
240 } else {
241 AmgSymMatrix(3) startingCovMatrix;
242 startingCovMatrix.setIdentity();
243 startingCovMatrix = startingCovMatrix / m_initialError;
244 //now initialize with starting position and covariance matrix
245 ConstraintVertex.setPosition( SeedPoint );
246 ConstraintVertex.setCovariancePosition( startingCovMatrix );
247 ConstraintVertex.setFitQuality( 0., -3. );
248 }
249
250 //now put the linearizedtracks into VxTrackAtVertex
251 return dothefit(ConstraintVertex,SeedPoint,theLinTracks);
252
253
254 }
255
256 std::unique_ptr<xAOD::Vertex>
258 const std::vector<const Trk::Track*>& VectorTrk,
259 const xAOD::Vertex& constraint, // initialized to xAOD::Vertex()
260 const Amg::Vector3D& startingPoint, // initialized to Amg::Vector3D()
261 bool IsConstraint, // initialized to false
262 bool IsStartingPoint) const
263 { // initialized to false
264
265 ATH_MSG_DEBUG("Called Adaptive vertex with Trk::Track. N. Tracks = " << VectorTrk.size());
266
267 std::vector<const Trk::TrackParameters*> perigeeList;
268 for (const auto *iter : VectorTrk) {
269 if (std::isnan(iter->perigeeParameters()->parameters()[Trk::d0])) {
270 continue;
271 }
272 perigeeList.push_back(iter->perigeeParameters());
273 }
274
275 std::unique_ptr<xAOD::Vertex> FittedVertex = _fit(perigeeList,constraint,startingPoint,IsConstraint,IsStartingPoint);
276
277 if (FittedVertex==nullptr) {
278 return FittedVertex;
279 }
280
281 //these following lines are really absurd... Why has this to be the case... <19-06-2006>
282 //We need a link which can be dynamically to a Track or a TrackParticle....... )-:
283
284 const std::vector<const Trk::Track*>::const_iterator trkbegin=VectorTrk.begin();
285 const std::vector<const Trk::Track*>::const_iterator trkend=VectorTrk.end();
286
287 const std::vector<VxTrackAtVertex>::iterator vtxbegin=FittedVertex->vxTrackAtVertex().begin();
288 const std::vector<VxTrackAtVertex>::iterator vtxend=FittedVertex->vxTrackAtVertex().end();
289
290 for (std::vector<const Trk::Track*>::const_iterator trkiter=trkbegin;trkiter!=trkend;++trkiter)
291 {
292 for (std::vector<Trk::VxTrackAtVertex>::iterator vtxiter=vtxbegin;vtxiter!=vtxend;++vtxiter)
293 {
294 if(((*trkiter)->perigeeParameters()->momentum() -
295 (*vtxiter).initialPerigee()->momentum()).mag()< 1e-8 &&
296 ((*trkiter)->perigeeParameters()->position() -
297 (*vtxiter).initialPerigee()->position()).mag()< 1e-8)
298 {
299
301 link.setElement(*trkiter);
302 LinkToTrack * linkTT = new LinkToTrack(link);
303 (*vtxiter).setOrigTrack(linkTT);
304 }
305 }
306 }
307
308 //*******************************************************************
309 // TODO: Starting from a vector of Trk::Tracks, can't store
310 // separately from the vxTrackAtVertex vector the links to the
311 // original tracks in xAOD::Vertex (only links to xAOD::TrackParticles and
312 // xAOD::NeutralParticles can be stored)
313 //*******************************************************************
314
315 return FittedVertex;
316 }
317
318 std::unique_ptr<xAOD::Vertex>
320 const xAOD::Vertex& ConstraintVertex,
321 const Amg::Vector3D& SeedVertex,
322 std::vector<Trk::VxTrackAtVertex>& myLinTracks) const
323 {
324
325 //now reset the annealing maker
327 m_AnnealingMaker->reset(astate);
328
329 //Count the steps for the fit and the number of relinearizations needed in the fit
330 int num_steps(0);
331
332
333 auto ActualVertex = std::make_unique<xAOD::Vertex>();
334 ActualVertex->makePrivateStore(); // xAOD::VertexContainer will take ownership of AuxStore when ActualVertex is added to it
335 ActualVertex->setPosition( ConstraintVertex.position() );
336 ActualVertex->setCovariancePosition( ConstraintVertex.covariancePosition() / m_AnnealingMaker->getWeight(astate, 1.) );
337 ActualVertex->setFitQuality( ConstraintVertex.chiSquared(), ConstraintVertex.numberDoF() );
338 ActualVertex->vxTrackAtVertex() = myLinTracks;
339 ActualVertex->setVertexType(xAOD::VxType::NotSpecified); // to mimic the initialization present in the old EDM constructor
340
341 Amg::Vector3D NewVertex = SeedVertex;
342
343 Amg::Vector3D ActualSeedPosition = SeedVertex;
344
345 if(msgLvl(MSG::VERBOSE))
346 {
347 msg(MSG::VERBOSE) << "Num max of steps is " << m_maxIterations << endmsg;
348 msg(MSG::VERBOSE) << "m_AnnealingMaker->isEquilibrium() is " << m_AnnealingMaker->isEquilibrium(astate) << endmsg;
349 }
350
351 std::vector<Trk::VxTrackAtVertex>::iterator lintracksBegin = ActualVertex->vxTrackAtVertex().begin();
352 std::vector<Trk::VxTrackAtVertex>::iterator lintracksEnd = ActualVertex->vxTrackAtVertex().end();
353
354 std::vector<Trk::VxTrackAtVertex>::iterator iter;
355
356 bool relinearization = false;
357
358 do {
359
360 ActualVertex->setPosition( ConstraintVertex.position() );
361 ActualVertex->setCovariancePosition( ConstraintVertex.covariancePosition() / m_AnnealingMaker->getWeight(astate, 1.) );
362 ActualVertex->setFitQuality( ConstraintVertex.chiSquared(), ConstraintVertex.numberDoF() );
363
364 if(msgLvl(MSG::DEBUG))
365 {
366 msg(MSG::DEBUG) << "Correction applied to constraint weight is: " << m_AnnealingMaker->getWeight(astate, 1.) << endmsg;
367 }
368
369 //To reweight here through an extrapolation is not ideal, but maybe I'll change this in the future...
370 if(msgLvl(MSG::DEBUG))
371 {
372 msg(MSG::DEBUG) << "New fit step: step number " << num_steps << endmsg;
373 }
374
375 //consider relinearization if you are too far away from the old lin point
376
377
378 relinearization=false;
379 if ( (ActualSeedPosition - SeedVertex).perp() > m_maxDistToLinPoint ) {
380 relinearization=true;
381 if(msgLvl(MSG::DEBUG))
382 {
383 msg(MSG::DEBUG) << "Actual vertex too far away from linearization point: have to linearize tracks again" << endmsg;
384 }
385
386 //collect all measured perigees
387
388 for (iter=lintracksBegin;iter!=lintracksEnd;++iter) {
389 //m_LinearizedTrackFactory->linearize(*iter,ActualPosition);
390 bool success=m_ImpactPoint3dEstimator->addIP3dAtaPlane(*iter,NewVertex);
391 if (!success)
392 {
393 msg(MSG::DEBUG) << "Adding compatibility to vertex information failed. Newton distance finder didn't converge..." << endmsg;
394 }
395 }
396
397 }
398
399
400 lintracksBegin=ActualVertex->vxTrackAtVertex().begin();
401 lintracksEnd=ActualVertex->vxTrackAtVertex().end();
402
403 //now reweight tracks (find chi2 compatibility with actual vertex position)
404 for (iter=lintracksBegin;iter!=lintracksEnd;++iter) {
405
406 //estimate the compatibility of the track to the vertex and store it in iter->linState()->m_vtxCompatibility
407 m_TrackCompatibilityEstimator->estimate(*iter,NewVertex);
408
409 //use the obtained estimate and ask the Annealing Maker what is the corresponding weight at the actual temperature step
410 iter->setWeight( m_AnnealingMaker->getWeight( astate, iter->vtxCompatibility() ) );
411 if(msgLvl(MSG::VERBOSE))
412 {
413 msg(MSG::VERBOSE) << "Before annealing: " << iter->vtxCompatibility() <<
414 " Annealing RESULT is:" << iter->weight() << " at T: " <<
415 m_AnnealingMaker->actualTemp(astate) << endmsg;
416 }
417
418
419 }
420
421 //now update with all the tracks info
422 for (iter=lintracksBegin;iter!=lintracksEnd;++iter) {
423 if(msgLvl(MSG::VERBOSE))
424 {
425 msg(MSG::VERBOSE) << "Updating vertex with a new track" << endmsg;
426 }
427 try {
428
429 if ( iter->weight() > 1e-3 ) {
430 //now take care if linearization has been done at least once
431 //or if vertex has changed so much so that you need relinearization!
432 if ( iter->linState() == nullptr) {
433 //linearization has not been done so far: do it now!
434 if(msgLvl(MSG::VERBOSE))
435 {
436 msg(MSG::VERBOSE) << "Linearizing track for the first time" << endmsg;
437 }
438
439 m_LinearizedTrackFactory->linearize( *iter, ActualVertex->position() );
440 ATH_MSG_DEBUG( "Linearized track to Seed Point. " << *iter );
441 } else if (relinearization) {
442 //do it again in case of updated vertex too far from previous one
443 if(msgLvl(MSG::VERBOSE))
444 {
445 msg(MSG::VERBOSE) << "Relinearizing track " << endmsg;
446 }
447
448 m_LinearizedTrackFactory->linearize( *iter, NewVertex );
449 ActualSeedPosition=NewVertex;
450 ATH_MSG_DEBUG("Linearized track to new seed Point " << NewVertex << ". " << *iter );
451 }
452 m_VertexUpdator->add(*ActualVertex.get(),*iter);
453 } else {
454 if(msgLvl(MSG::VERBOSE))
455 {
456 msg(MSG::VERBOSE) << "Weight lower than 1e-3, so the track will not be considered anymore" << endmsg;
457 }
458
459 }
460 } catch (...) {
461 msg(MSG::WARNING) << "You have just lost a track" << endmsg;
462 }
463 }
464
465 //show some info about the position
466 if(msgLvl(MSG::DEBUG))
467 {
468 msg(MSG::DEBUG) << "New position x: " << ActualVertex->position().x() << " y: " << ActualVertex->position().y()
469 << " z: " << ActualVertex->position().z() << endmsg;
470 }
471
472
473 NewVertex = ActualVertex->position();
474
475 //now go one step down in the annealing process (lower the temperature - single step)
476 if(msgLvl(MSG::VERBOSE))
477 {
478 msg(MSG::VERBOSE) << "Now calling one step of annealing" << endmsg;
479 }
480
481 m_AnnealingMaker->anneal(astate);
482 num_steps+=1;
483
484 //continue to fit until max iteration number has been reached or "thermal equilibrium"
485 //has been obtained in the annealing process
486
487 } while (num_steps<m_maxIterations && !(m_AnnealingMaker->isEquilibrium(astate)) );
488
489 //Here smooth the vertex (refitting of the track)
490
491 //without smoothing... for the moment...
492 if(m_doSmoothing) {
493 m_VertexSmoother->smooth(*ActualVertex);
494 } else {
495 for (iter=lintracksBegin;iter!=lintracksEnd;++iter) {
496 // const MeasuredPerigee* castToMP=dynamic_cast<const MeasuredPerigee*>(iter->initialPerigee());
497 // if (castToMP==0) {
498 // msg(MSG::WARNING) << "Couldn't cast a track to MeasuredPerigee to smooth it. Neutrals not supported. " <<
499 // " Skipping track. .. " << endmsg;
500 // continue;
501 // }
502 if ( iter->initialPerigee() )
503 iter->setPerigeeAtVertex( ( iter->initialPerigee() )->clone() );
504 else if ( iter->initialNeutralPerigee() )
505 iter->setPerigeeAtVertex( ( iter->initialNeutralPerigee() )->clone() );
506 }
507 }
508
509 if(msgLvl(MSG::DEBUG))
510 {
511 msg(MSG::DEBUG) << "chi2: " << ActualVertex->chiSquared()
512 << "the ndf of the vertex is at fit end: " << ActualVertex->numberDoF() << endmsg;
513 }
514
515
516 //Give back all info into the ActualVertex xAOD::Vertex
517 return ActualVertex;
518 }
519
520 std::unique_ptr<xAOD::Vertex>
522 const EventContext& /*ctx*/,
523 const std::vector<const Trk::TrackParameters*>& perigeeList,
524 const std::vector<const Trk::NeutralParameters*>& neutralPerigeeList,
525 const Amg::Vector3D& startingPoint) const
526 {
527
528 return _fit(perigeeList,neutralPerigeeList,xAOD::Vertex(),startingPoint,false,true);
529 }
530
531 std::unique_ptr<xAOD::Vertex>
533 const EventContext& /*ctx*/,
534 const std::vector<const Trk::TrackParameters*>& perigeeList,
535 const std::vector<const Trk::NeutralParameters*>& neutralPerigeeList,
536 const xAOD::Vertex& constraint) const
537 {
538 return _fit(perigeeList,neutralPerigeeList,constraint,Amg::Vector3D::Zero(),true);
539 }
540
541 std::unique_ptr<xAOD::Vertex>
543 const EventContext& /*ctx*/,
544 const std::vector<const Trk::TrackParameters*>& perigeeList,
545 const std::vector<const Trk::NeutralParameters*>& neutralPerigeeList,
546 const xAOD::Vertex& constraint,
547 const Amg::Vector3D& startingPoint) const
548 {
549 return _fit(perigeeList,neutralPerigeeList,constraint,startingPoint,true,true);
550 }
551
552 std::unique_ptr<xAOD::Vertex>
554 const EventContext& /*ctx*/,
555 const std::vector<const Trk::TrackParameters*>& perigeeList,
556 const std::vector<const Trk::NeutralParameters*>& neutralPerigeeList) const
557 {
558 return _fit(perigeeList,neutralPerigeeList,xAOD::Vertex(),Amg::Vector3D(),false,false);
559 }
560
561 std::unique_ptr<xAOD::Vertex>
563 const EventContext& ctx,
564 const std::vector<const Trk::TrackParameters*>& perigeeList,
565 const Amg::Vector3D& startingPoint) const
566 {
567 const std::vector<const Trk::NeutralParameters*> neutralPerigeeList;
568 return fit(ctx, perigeeList, neutralPerigeeList, startingPoint);
569 }
570
571 std::unique_ptr<xAOD::Vertex>
573 const EventContext& ctx,
574 const std::vector<const Trk::TrackParameters*>& perigeeList,
575 const xAOD::Vertex& constraint) const
576 {
577 const std::vector<const Trk::NeutralParameters*> neutralPerigeeList;
578 return fit(ctx, perigeeList, neutralPerigeeList, constraint);
579 }
580
581 std::unique_ptr<xAOD::Vertex>
583 const EventContext& ctx,
584 const std::vector<const Trk::TrackParameters*>& perigeeList,
585 const xAOD::Vertex& constraint,
586 const Amg::Vector3D& startingPoint) const
587 {
588 const std::vector<const Trk::NeutralParameters*> neutralPerigeeList;
589 return fit(ctx, perigeeList, neutralPerigeeList, constraint, startingPoint);
590 }
591
592 std::unique_ptr<xAOD::Vertex>
594 const EventContext& ctx,
595 const std::vector<const Trk::TrackParameters*> & perigeeList) const
596 {
597 const std::vector<const Trk::NeutralParameters*> neutralPerigeeList;
598 return fit(ctx,perigeeList,neutralPerigeeList);
599 }
600
601 std::unique_ptr<xAOD::Vertex>
603 const std::vector<const Trk::TrackParameters*> & perigeeList,
604 const xAOD::Vertex& constraint,
605 const Amg::Vector3D & startingPoint,
606 bool IsConstraint,
607 bool IsStartingPoint) const
608 {
609 const std::vector<const Trk::NeutralParameters*> neutralPerigeeList;
610 return _fit(perigeeList, neutralPerigeeList, constraint, startingPoint, IsConstraint, IsStartingPoint);
611 }
612
613//xAOD interfaced methods. Required to un-block the current situation
614// with the xAOD tracking design.
615
616 std::unique_ptr<xAOD::Vertex>
618 const EventContext& /*ctx*/,
619 const std::vector<const xAOD::TrackParticle*>& vectorTrk,
620 const std::vector<const xAOD::NeutralParticle*>& vectorNeut,
621 const Amg::Vector3D& startingPoint) const
622 {
623
624 if (vectorTrk.empty()) {
625 msg(MSG::INFO) << "Empty vector of tracks passed" << endmsg;
626 return nullptr;
627 }
628
629 if (vectorNeut.empty()) {
630 msg(MSG::VERBOSE) << "Empty vector of neutrals passed" << endmsg;
631 }
632
633 // making a list of perigee out of the vector of tracks
634 std::vector<const Trk::TrackParameters*> measuredPerigees;
635
636 for (const auto *i : vectorTrk) {
637 const Trk::TrackParameters* tmpMeasPer = &(i->perigeeParameters());
638
639 if (tmpMeasPer != nullptr)
640 measuredPerigees.push_back(tmpMeasPer);
641 else
642 msg(MSG::INFO)
643 << "Failed to dynamic_cast this track parameters to perigee"
644 << endmsg; // TODO: Failed to implicit cast the perigee parameters to
645 // track parameters?
646 }
647
648 // making a list of perigee out of the vector of neutrals
649 std::vector<const Trk::NeutralParameters*> measuredNeutralPerigees;
650
651 for (const auto *i : vectorNeut) {
652 const Trk::NeutralParameters* tmpMeasPer = &(i->perigeeParameters());
653
654 if (tmpMeasPer != nullptr)
655 measuredNeutralPerigees.push_back(tmpMeasPer);
656 else
657 msg(MSG::INFO)
658 << "Failed to dynamic_cast this neutral parameters to perigee"
659 << endmsg; // TODO: Failed to implicit cast the perigee parameters to
660 // neutral parameters?
661 }
662
663 std::unique_ptr<xAOD::Vertex> fittedVertex = _fit(
664 measuredPerigees,
665 measuredNeutralPerigees,
666 xAOD::Vertex(),
667 startingPoint,
668 false,
669 true);
670
671 // assigning the input tracks to the fitted vertex through VxTrackAtVertices
672 if (fittedVertex == nullptr) {
673 return fittedVertex;
674 }
675
676 if (fittedVertex
677 ->vxTrackAtVertexAvailable()) // TODO: I don't think
678 // vxTrackAtVertexAvailable() does the
679 // same thing as a null pointer check!
680 {
681 if (!fittedVertex->vxTrackAtVertex().empty()) {
682 for (unsigned int i = 0; i < vectorTrk.size(); ++i) {
683
685 const xAOD::TrackParticleContainer* cont =
686 dynamic_cast<const xAOD::TrackParticleContainer*>(
687 vectorTrk[i]->container());
688 if (cont) {
689 if (!linkTT->toIndexedElement(*cont, vectorTrk[i]->index())) {
690 msg(MSG::WARNING)
691 << "Failed to set the EL for this particle correctly" << endmsg;
692 }
693 } else {
694 msg(MSG::WARNING)
695 << "Failed to identify a container for this TP" << endmsg;
696 } // end of the dynamic cast check
697
698 // vxtrackatvertex takes ownership!
699 (fittedVertex->vxTrackAtVertex())[i].setOrigTrack(linkTT);
700 } // end of loop for setting orig tracks in.
701
702 for (unsigned int i = 0; i < vectorNeut.size(); ++i) {
705 dynamic_cast<const xAOD::NeutralParticleContainer*>(
706 vectorNeut[i]->container());
707 if (cont) {
708 if (!linkTT->toIndexedElement(*cont, vectorNeut[i]->index())) {
709 msg(MSG::WARNING)
710 << "Failed to set the EL for this particle correctly" << endmsg;
711 }
712 } else {
713 msg(MSG::WARNING)
714 << "Failed to identify a container for this TP" << endmsg;
715 } // end of the dynamic cast check
716
717 // vxtrackatvertex takes ownership!
718 (fittedVertex->vxTrackAtVertex())[i + vectorTrk.size()].setOrigTrack(
719 linkTT);
720 } // end of loop for setting orig neutrals in.
721
722 } // end of protection against unsuccessfull updates (no tracks were
723 // added)
724 } // end of vector of tracks check
725
726 // now set links to xAOD::TrackParticles directly in the xAOD::Vertex
727 unsigned int VTAVsize = fittedVertex->vxTrackAtVertex().size();
728 for (unsigned int i = 0; i < VTAVsize; ++i) {
729 Trk::VxTrackAtVertex* VTAV = &(fittedVertex->vxTrackAtVertex().at(i));
730 // TODO: Will this pointer really hold 0 if no VxTrackAtVertex is found?
731 if (not VTAV) {
732 ATH_MSG_WARNING(" Trying to set link to xAOD::TrackParticle. The "
733 "VxTrackAtVertex is not found");
734 continue;
735 }
736
737 Trk::ITrackLink* trklink = VTAV->trackOrParticleLink();
738
739 // See if the trklink is to an xAOD::TrackParticle
740 Trk::LinkToXAODTrackParticle* linkToXAODTP =
741 dynamic_cast<Trk::LinkToXAODTrackParticle*>(trklink);
742 if (linkToXAODTP) {
743
744 // Now set the new link to the xAOD vertex
745 fittedVertex->addTrackAtVertex(*linkToXAODTP, VTAV->weight());
746
747 } else {
748
749 // See if the trklink is to an xAOD::NeutralParticle
750 Trk::LinkToXAODNeutralParticle* linkToXAODTPneutral =
751 dynamic_cast<Trk::LinkToXAODNeutralParticle*>(trklink);
752 if (!linkToXAODTPneutral) {
754 "Skipping track. Trying to set link to something else than "
755 "xAOD::TrackParticle or xAOD::NeutralParticle.");
756 } else {
757 // Now set the newlink to the new xAOD vertex
758 fittedVertex->addNeutralAtVertex(*linkToXAODTPneutral,
759 VTAV->weight());
760 }
761 }
762 } // end of loop
763
764 return fittedVertex;
765
766 }//end of the xAOD starting point fit method
767
768 std::unique_ptr<xAOD::Vertex>
770 const EventContext& /*ctx*/,
771 const std::vector<const xAOD::TrackParticle*>& vectorTrk,
772 const std::vector<const xAOD::NeutralParticle*>& vectorNeut,
773 const xAOD::Vertex& constraint) const
774 {
775
776 if(vectorTrk.empty())
777 {
778 msg(MSG::INFO)<<"Empty vector of tracks passed"<<endmsg;
779 return nullptr;
780 }
781
782 if(vectorNeut.empty())
783 {
784 msg(MSG::INFO)<<"Empty vector of neutrals passed"<<endmsg;
785 }
786
787 //making a list of perigee out of the vector of tracks
788 std::vector<const Trk::TrackParameters*> measuredPerigees;
789
790 for(const auto *i : vectorTrk)
791 {
792 const Trk::TrackParameters * tmpMeasPer = &(i->perigeeParameters());
793
794 if(tmpMeasPer!=nullptr) measuredPerigees.push_back(tmpMeasPer);
795 else msg(MSG::INFO)<<"Failed to dynamic_cast this track parameters to perigee"<<endmsg; //TODO: Failed to implicit cast the perigee parameters to track parameters?
796 }
797
798 //making a list of perigee out of the vector of neutrals
799 std::vector<const Trk::NeutralParameters*> measuredNeutralPerigees;
800
801 for(const auto *i : vectorNeut)
802 {
803 const Trk::NeutralParameters * tmpMeasPer = &(i->perigeeParameters());
804
805 if(tmpMeasPer!=nullptr) measuredNeutralPerigees.push_back(tmpMeasPer);
806 else msg(MSG::INFO)<<"Failed to dynamic_cast this neutral parameters to perigee"<<endmsg; //TODO: Failed to implicit cast the perigee parameters to neutral parameters?
807 }
808
809
810 std::unique_ptr<xAOD::Vertex> fittedVertex = _fit(measuredPerigees, measuredNeutralPerigees, constraint, Amg::Vector3D(),true);
811
812
813 //assigning the input tracks to the fitted vertex through VxTrackAtVertices
814 {
815 if( fittedVertex->vxTrackAtVertexAvailable() ) // TODO: I don't think vxTrackAtVertexAvailable() does the same thing as a null pointer check
816 {
817 if(!fittedVertex->vxTrackAtVertex().empty())
818 {
819 for(unsigned int i = 0; i <vectorTrk.size(); ++i)
820 {
821
823 const xAOD::TrackParticleContainer* cont = dynamic_cast< const xAOD::TrackParticleContainer* >( vectorTrk[ i ]->container() );
824 if( cont )
825 {
826 if( ! linkTT->toIndexedElement( *cont, vectorTrk[ i ]->index() ) )
827 {
828 msg(MSG::WARNING)<<"Failed to set the EL for this particle correctly"<<endmsg;
829 }
830 } else {
831 msg(MSG::WARNING)<<"Failed to identify a container for this TP"<<endmsg;
832 }//end of the dynamic cast check
833
834
835 // vxtrackatvertex takes ownership!
836 ( fittedVertex->vxTrackAtVertex() )[i].setOrigTrack(linkTT);
837 }//end of loop for setting orig tracks in.
838
839 for(unsigned int i = 0; i <vectorNeut.size(); ++i)
840 {
842 const xAOD::NeutralParticleContainer* cont = dynamic_cast< const xAOD::NeutralParticleContainer* >( vectorNeut[ i ]->container() );
843 if( cont )
844 {
845 if( ! linkTT->toIndexedElement( *cont, vectorNeut[ i ]->index() ) )
846 {
847 msg(MSG::WARNING)<<"Failed to set the EL for this particle correctly"<<endmsg;
848 }
849 } else {
850 msg(MSG::WARNING)<<"Failed to identify a container for this NP"<<endmsg;
851 }//end of the dynamic cast check
852
853 // vxtrackatvertex takes ownership!
854 ( fittedVertex->vxTrackAtVertex() )[vectorTrk.size()+i].setOrigTrack(linkTT);
855 }//end of loop for setting orig neutrals in.
856
857 }//end of protection against unsuccessfull updates (no tracks were added)
858 }//end of vector of tracks check
859 }
860
861
862 //now set links to xAOD::TrackParticles directly in the xAOD::Vertex
863 unsigned int VTAVsize = fittedVertex->vxTrackAtVertex().size();
864 for (unsigned int i = 0 ; i < VTAVsize ; ++i)
865 {
866 Trk::VxTrackAtVertex* VTAV = &( fittedVertex->vxTrackAtVertex().at(i) );
867 //TODO: Will this pointer really hold 0 if no VxTrackAtVertex is found?
868 if (not VTAV){
869 ATH_MSG_WARNING (" Trying to set link to xAOD::TrackParticle. The VxTrackAtVertex is not found");
870 continue;
871 }
872
873 Trk::ITrackLink* trklink = VTAV->trackOrParticleLink();
874
875 // See if the trklink is to an xAOD::TrackParticle
876 Trk::LinkToXAODTrackParticle* linkToXAODTP = dynamic_cast<Trk::LinkToXAODTrackParticle*>(trklink);
877 if (linkToXAODTP)
878 {
879
880 //Now set the new link to the xAOD vertex
881 fittedVertex->addTrackAtVertex(*linkToXAODTP, VTAV->weight());
882
883 } else {
884
885 // See if the trklink is to an xAOD::NeutralParticle
886 Trk::LinkToXAODNeutralParticle* linkToXAODTPneutral = dynamic_cast<Trk::LinkToXAODNeutralParticle*>(trklink);
887 if (!linkToXAODTPneutral) {
888 ATH_MSG_WARNING ("Skipping track. Trying to set link to something else than xAOD::TrackParticle or xAOD::NeutralParticle.");
889 } else {
890 //Now set the new link to the new xAOD vertex
891 fittedVertex->addNeutralAtVertex(*linkToXAODTPneutral, VTAV->weight());
892 }
893
894 }
895 } //end of loop
896
897 return fittedVertex;
898
899 }//end of the xAOD constrained fit method
900
901
902}//end of namespace Trk definitions
Scalar perp() const
perp method - perpendicular length
#define endmsg
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
#define AmgSymMatrix(dim)
virtual ~AdaptiveVertexFitter()
destructor
std::unique_ptr< xAOD::Vertex > _fit(const std::vector< const Trk::TrackParameters * > &perigeeList, const std::vector< const Trk::NeutralParameters * > &neutralPerigeeList=std::vector< const Trk::NeutralParameters * >(), const xAOD::Vertex &constraint=xAOD::Vertex(), const Amg::Vector3D &startingPoint=Amg::Vector3D(), bool IsConstraint=false, bool IsStartingPoint=false) const
Internal method for fitting a list of TrackParameters and NeutralParameters, with or without constrai...
ToolHandle< Trk::IVertexTrackCompatibilityEstimator > m_TrackCompatibilityEstimator
double m_initialError
Initial error in form of diagonal elements of the inverse of the covariance matrix (name is misleadin...
ToolHandle< Trk::IImpactPoint3dEstimator > m_ImpactPoint3dEstimator
bool m_doSmoothing
True if smoothing after fit iterations has to be performed: otherwise the Smoother AlgoTool provided ...
AdaptiveVertexFitter(const std::string &t, const std::string &n, const IInterface *p)
default constructor due to Athena interface
bool m_onlyzseed
Variable is true if seeding has to be performed only on the z direction.
ToolHandle< Trk::IVertexSmoother > m_VertexSmoother
virtual std::unique_ptr< xAOD::Vertex > fit(const EventContext &ctx, const std::vector< const xAOD::TrackParticle * > &vectorTrk, const std::vector< const xAOD::NeutralParticle * > &vectorNeut, const Amg::Vector3D &startingPoint) const override
Interface for xAOD::TrackParticle with starting point.
virtual StatusCode initialize() override
ToolHandle< Trk::IVertexAnnealingMaker > m_AnnealingMaker
ToolHandle< Trk::IVertexSeedFinder > m_SeedFinder
std::unique_ptr< xAOD::Vertex > dothefit(const xAOD::Vertex &ConstraintVertex, const Amg::Vector3D &SeedVertex, std::vector< VxTrackAtVertex > &myLinTracks) const
Internal method, called by the two _fit internal functions, in order to perform the fit,...
ToolHandle< Trk::IVertexUpdator > m_VertexUpdator
ToolHandle< Trk::IVertexLinearizedTrackFactory > m_LinearizedTrackFactory
double m_maxDistToLinPoint
Maximum distance of linearization point of track to actual fitted vertex before needing to relineariz...
long int m_maxIterations
Number of maximum iterations.
AUTO - An Undocumented Tracking Object.
Definition LinkToTrack.h:20
Element link to XAOD NeutralParticle.
Element link to XAOD TrackParticle.
The VxTrackAtVertex is a common class for all present TrkVertexFitters The VxTrackAtVertex is designe...
double weight(void) const
Information about the weight of track in fit (given back by annealing): weight=ndf/2.
const ITrackLink * trackOrParticleLink(void) const
void setCovariancePosition(const AmgSymMatrix(3)&covariancePosition)
Sets the vertex covariance matrix.
float numberDoF() const
Returns the number of degrees of freedom of the vertex fit as float.
void setPosition(const Amg::Vector3D &position)
Sets the 3-position.
float chiSquared() const
Returns the of the vertex fit as float.
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
Ensure that the ATLAS eigen extensions are properly loaded.
ParametersBase< NeutralParametersDim, Neutral > NeutralParameters
@ d0
Definition ParamDefs.h:63
ParametersBase< TrackParametersDim, Charged > TrackParameters
@ NotSpecified
Default value, no explicit type set.
NeutralParticleContainer_v1 NeutralParticleContainer
Definition of the current "NeutralParticle container version".
Vertex_v1 Vertex
Define the latest version of the vertex class.
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
MsgStream & msg
Definition testRead.cxx:32