ATLAS Offline Software
Loading...
Searching...
No Matches
AdaptiveVertexFitter.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 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
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
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 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
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 xAOD::Vertex* ActualVertex = new 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 ActualVertex=m_VertexUpdator->add(*ActualVertex,*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
522 const std::vector<const Trk::TrackParameters*>& perigeeList,
523 const std::vector<const Trk::NeutralParameters*>& neutralPerigeeList,
524 const Amg::Vector3D& startingPoint) const
525 {
526
527 return _fit(perigeeList,neutralPerigeeList,xAOD::Vertex(),startingPoint,false,true);
528 }
529
532 const std::vector<const Trk::TrackParameters*>& perigeeList,
533 const std::vector<const Trk::NeutralParameters*>& neutralPerigeeList,
534 const xAOD::Vertex& constraint) const
535 {
536 return _fit(perigeeList,neutralPerigeeList,constraint,Amg::Vector3D::Zero(),true);
537 }
538
541 const std::vector<const Trk::TrackParameters*>& perigeeList,
542 const std::vector<const Trk::NeutralParameters*>& neutralPerigeeList,
543 const xAOD::Vertex& constraint,
544 const Amg::Vector3D& startingPoint) const
545 {
546 return _fit(perigeeList,neutralPerigeeList,constraint,startingPoint,true,true);
547 }
548
551 const std::vector<const Trk::TrackParameters*>& perigeeList,
552 const std::vector<const Trk::NeutralParameters*>& neutralPerigeeList) const
553 {
554 return _fit(perigeeList,neutralPerigeeList,xAOD::Vertex(),Amg::Vector3D(),false,false);
555 }
556
559 const std::vector<const Trk::TrackParameters*>& perigeeList,
560 const Amg::Vector3D& startingPoint) const
561 {
562 const std::vector<const Trk::NeutralParameters*> neutralPerigeeList;
563 return fit(perigeeList, neutralPerigeeList, startingPoint);
564 }
565
568 const std::vector<const Trk::TrackParameters*>& perigeeList,
569 const xAOD::Vertex& constraint) const
570 {
571 const std::vector<const Trk::NeutralParameters*> neutralPerigeeList;
572 return fit(perigeeList, neutralPerigeeList, constraint);
573 }
574
577 const std::vector<const Trk::TrackParameters*>& perigeeList,
578 const xAOD::Vertex& constraint,
579 const Amg::Vector3D& startingPoint) const
580 {
581 const std::vector<const Trk::NeutralParameters*> neutralPerigeeList;
582 return fit(perigeeList, neutralPerigeeList, constraint, startingPoint);
583 }
584
585 xAOD::Vertex * AdaptiveVertexFitter::fit(const std::vector<const Trk::TrackParameters*> & perigeeList) const
586 {
587 const std::vector<const Trk::NeutralParameters*> neutralPerigeeList;
588 return fit(perigeeList,neutralPerigeeList);
589 }
590
591 xAOD::Vertex * AdaptiveVertexFitter::_fit(const std::vector<const Trk::TrackParameters*> & perigeeList,
592 const xAOD::Vertex& constraint,
593 const Amg::Vector3D & startingPoint,
594 bool IsConstraint,
595 bool IsStartingPoint) const {
596 const std::vector<const Trk::NeutralParameters*> neutralPerigeeList;
597 return _fit(perigeeList, neutralPerigeeList, constraint, startingPoint, IsConstraint, IsStartingPoint);
598 }
599
600//xAOD interfaced methods. Required to un-block the current situation
601// with the xAOD tracking design.
602
605 const std::vector<const xAOD::TrackParticle*>& vectorTrk,
606 const std::vector<const xAOD::NeutralParticle*>& vectorNeut,
607 const Amg::Vector3D& startingPoint) const
608 {
609
610 if (vectorTrk.empty()) {
611 msg(MSG::INFO) << "Empty vector of tracks passed" << endmsg;
612 return nullptr;
613 }
614
615 if (vectorNeut.empty()) {
616 msg(MSG::VERBOSE) << "Empty vector of neutrals passed" << endmsg;
617 }
618
619 // making a list of perigee out of the vector of tracks
620 std::vector<const Trk::TrackParameters*> measuredPerigees;
621
622 for (const auto *i : vectorTrk) {
623 const Trk::TrackParameters* tmpMeasPer = &(i->perigeeParameters());
624
625 if (tmpMeasPer != nullptr)
626 measuredPerigees.push_back(tmpMeasPer);
627 else
628 msg(MSG::INFO)
629 << "Failed to dynamic_cast this track parameters to perigee"
630 << endmsg; // TODO: Failed to implicit cast the perigee parameters to
631 // track parameters?
632 }
633
634 // making a list of perigee out of the vector of neutrals
635 std::vector<const Trk::NeutralParameters*> measuredNeutralPerigees;
636
637 for (const auto *i : vectorNeut) {
638 const Trk::NeutralParameters* tmpMeasPer = &(i->perigeeParameters());
639
640 if (tmpMeasPer != nullptr)
641 measuredNeutralPerigees.push_back(tmpMeasPer);
642 else
643 msg(MSG::INFO)
644 << "Failed to dynamic_cast this neutral parameters to perigee"
645 << endmsg; // TODO: Failed to implicit cast the perigee parameters to
646 // neutral parameters?
647 }
648
649 xAOD::Vertex* fittedVertex = _fit(measuredPerigees,
650 measuredNeutralPerigees,
651 xAOD::Vertex(),
652 startingPoint,
653 false,
654 true);
655
656 // assigning the input tracks to the fitted vertex through VxTrackAtVertices
657 if (fittedVertex == nullptr) {
658 return fittedVertex;
659 }
660
661 if (fittedVertex
662 ->vxTrackAtVertexAvailable()) // TODO: I don't think
663 // vxTrackAtVertexAvailable() does the
664 // same thing as a null pointer check!
665 {
666 if (!fittedVertex->vxTrackAtVertex().empty()) {
667 for (unsigned int i = 0; i < vectorTrk.size(); ++i) {
668
670 const xAOD::TrackParticleContainer* cont =
671 dynamic_cast<const xAOD::TrackParticleContainer*>(
672 vectorTrk[i]->container());
673 if (cont) {
674 if (!linkTT->toIndexedElement(*cont, vectorTrk[i]->index())) {
675 msg(MSG::WARNING)
676 << "Failed to set the EL for this particle correctly" << endmsg;
677 }
678 } else {
679 msg(MSG::WARNING)
680 << "Failed to identify a container for this TP" << endmsg;
681 } // end of the dynamic cast check
682
683 // vxtrackatvertex takes ownership!
684 (fittedVertex->vxTrackAtVertex())[i].setOrigTrack(linkTT);
685 } // end of loop for setting orig tracks in.
686
687 for (unsigned int i = 0; i < vectorNeut.size(); ++i) {
690 dynamic_cast<const xAOD::NeutralParticleContainer*>(
691 vectorNeut[i]->container());
692 if (cont) {
693 if (!linkTT->toIndexedElement(*cont, vectorNeut[i]->index())) {
694 msg(MSG::WARNING)
695 << "Failed to set the EL for this particle correctly" << endmsg;
696 }
697 } else {
698 msg(MSG::WARNING)
699 << "Failed to identify a container for this TP" << endmsg;
700 } // end of the dynamic cast check
701
702 // vxtrackatvertex takes ownership!
703 (fittedVertex->vxTrackAtVertex())[i + vectorTrk.size()].setOrigTrack(
704 linkTT);
705 } // end of loop for setting orig neutrals in.
706
707 } // end of protection against unsuccessfull updates (no tracks were
708 // added)
709 } // end of vector of tracks check
710
711 // now set links to xAOD::TrackParticles directly in the xAOD::Vertex
712 unsigned int VTAVsize = fittedVertex->vxTrackAtVertex().size();
713 for (unsigned int i = 0; i < VTAVsize; ++i) {
714 Trk::VxTrackAtVertex* VTAV = &(fittedVertex->vxTrackAtVertex().at(i));
715 // TODO: Will this pointer really hold 0 if no VxTrackAtVertex is found?
716 if (not VTAV) {
717 ATH_MSG_WARNING(" Trying to set link to xAOD::TrackParticle. The "
718 "VxTrackAtVertex is not found");
719 continue;
720 }
721
722 Trk::ITrackLink* trklink = VTAV->trackOrParticleLink();
723
724 // See if the trklink is to an xAOD::TrackParticle
725 Trk::LinkToXAODTrackParticle* linkToXAODTP =
726 dynamic_cast<Trk::LinkToXAODTrackParticle*>(trklink);
727 if (linkToXAODTP) {
728
729 // Now set the new link to the xAOD vertex
730 fittedVertex->addTrackAtVertex(*linkToXAODTP, VTAV->weight());
731
732 } else {
733
734 // See if the trklink is to an xAOD::NeutralParticle
735 Trk::LinkToXAODNeutralParticle* linkToXAODTPneutral =
736 dynamic_cast<Trk::LinkToXAODNeutralParticle*>(trklink);
737 if (!linkToXAODTPneutral) {
739 "Skipping track. Trying to set link to something else than "
740 "xAOD::TrackParticle or xAOD::NeutralParticle.");
741 } else {
742 // Now set the newlink to the new xAOD vertex
743 fittedVertex->addNeutralAtVertex(*linkToXAODTPneutral,
744 VTAV->weight());
745 }
746 }
747 } // end of loop
748
749 return fittedVertex;
750
751 }//end of the xAOD starting point fit method
752
755 const std::vector<const xAOD::TrackParticle*>& vectorTrk,
756 const std::vector<const xAOD::NeutralParticle*>& vectorNeut,
757 const xAOD::Vertex& constraint) const
758 {
759
760 if(vectorTrk.empty())
761 {
762 msg(MSG::INFO)<<"Empty vector of tracks passed"<<endmsg;
763 return nullptr;
764 }
765
766 if(vectorNeut.empty())
767 {
768 msg(MSG::INFO)<<"Empty vector of neutrals passed"<<endmsg;
769 }
770
771 //making a list of perigee out of the vector of tracks
772 std::vector<const Trk::TrackParameters*> measuredPerigees;
773
774 for(const auto *i : vectorTrk)
775 {
776 const Trk::TrackParameters * tmpMeasPer = &(i->perigeeParameters());
777
778 if(tmpMeasPer!=nullptr) measuredPerigees.push_back(tmpMeasPer);
779 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?
780 }
781
782 //making a list of perigee out of the vector of neutrals
783 std::vector<const Trk::NeutralParameters*> measuredNeutralPerigees;
784
785 for(const auto *i : vectorNeut)
786 {
787 const Trk::NeutralParameters * tmpMeasPer = &(i->perigeeParameters());
788
789 if(tmpMeasPer!=nullptr) measuredNeutralPerigees.push_back(tmpMeasPer);
790 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?
791 }
792
793
794 xAOD::Vertex* fittedVertex = _fit(measuredPerigees, measuredNeutralPerigees, constraint, Amg::Vector3D(),true);
795
796
797 //assigning the input tracks to the fitted vertex through VxTrackAtVertices
798 {
799 if( fittedVertex->vxTrackAtVertexAvailable() ) // TODO: I don't think vxTrackAtVertexAvailable() does the same thing as a null pointer check
800 {
801 if(!fittedVertex->vxTrackAtVertex().empty())
802 {
803 for(unsigned int i = 0; i <vectorTrk.size(); ++i)
804 {
805
807 const xAOD::TrackParticleContainer* cont = dynamic_cast< const xAOD::TrackParticleContainer* >( vectorTrk[ i ]->container() );
808 if( cont )
809 {
810 if( ! linkTT->toIndexedElement( *cont, vectorTrk[ i ]->index() ) )
811 {
812 msg(MSG::WARNING)<<"Failed to set the EL for this particle correctly"<<endmsg;
813 }
814 } else {
815 msg(MSG::WARNING)<<"Failed to identify a container for this TP"<<endmsg;
816 }//end of the dynamic cast check
817
818
819 // vxtrackatvertex takes ownership!
820 ( fittedVertex->vxTrackAtVertex() )[i].setOrigTrack(linkTT);
821 }//end of loop for setting orig tracks in.
822
823 for(unsigned int i = 0; i <vectorNeut.size(); ++i)
824 {
826 const xAOD::NeutralParticleContainer* cont = dynamic_cast< const xAOD::NeutralParticleContainer* >( vectorNeut[ i ]->container() );
827 if( cont )
828 {
829 if( ! linkTT->toIndexedElement( *cont, vectorNeut[ i ]->index() ) )
830 {
831 msg(MSG::WARNING)<<"Failed to set the EL for this particle correctly"<<endmsg;
832 }
833 } else {
834 msg(MSG::WARNING)<<"Failed to identify a container for this NP"<<endmsg;
835 }//end of the dynamic cast check
836
837 // vxtrackatvertex takes ownership!
838 ( fittedVertex->vxTrackAtVertex() )[vectorTrk.size()+i].setOrigTrack(linkTT);
839 }//end of loop for setting orig neutrals in.
840
841 }//end of protection against unsuccessfull updates (no tracks were added)
842 }//end of vector of tracks check
843 }
844
845
846 //now set links to xAOD::TrackParticles directly in the xAOD::Vertex
847 unsigned int VTAVsize = fittedVertex->vxTrackAtVertex().size();
848 for (unsigned int i = 0 ; i < VTAVsize ; ++i)
849 {
850 Trk::VxTrackAtVertex* VTAV = &( fittedVertex->vxTrackAtVertex().at(i) );
851 //TODO: Will this pointer really hold 0 if no VxTrackAtVertex is found?
852 if (not VTAV){
853 ATH_MSG_WARNING (" Trying to set link to xAOD::TrackParticle. The VxTrackAtVertex is not found");
854 continue;
855 }
856
857 Trk::ITrackLink* trklink = VTAV->trackOrParticleLink();
858
859 // See if the trklink is to an xAOD::TrackParticle
860 Trk::LinkToXAODTrackParticle* linkToXAODTP = dynamic_cast<Trk::LinkToXAODTrackParticle*>(trklink);
861 if (linkToXAODTP)
862 {
863
864 //Now set the new link to the xAOD vertex
865 fittedVertex->addTrackAtVertex(*linkToXAODTP, VTAV->weight());
866
867 } else {
868
869 // See if the trklink is to an xAOD::NeutralParticle
870 Trk::LinkToXAODNeutralParticle* linkToXAODTPneutral = dynamic_cast<Trk::LinkToXAODNeutralParticle*>(trklink);
871 if (!linkToXAODTPneutral) {
872 ATH_MSG_WARNING ("Skipping track. Trying to set link to something else than xAOD::TrackParticle or xAOD::NeutralParticle.");
873 } else {
874 //Now set the new link to the new xAOD vertex
875 fittedVertex->addNeutralAtVertex(*linkToXAODTPneutral, VTAV->weight());
876 }
877
878 }
879 } //end of loop
880
881 return fittedVertex;
882
883 }//end of the xAOD constrained fit method
884
885
886}//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)
void makePrivateStore()
Create a new (empty) private store for this object.
virtual ~AdaptiveVertexFitter()
destructor
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 StatusCode initialize() override
ToolHandle< Trk::IVertexAnnealingMaker > m_AnnealingMaker
ToolHandle< Trk::IVertexSeedFinder > m_SeedFinder
virtual xAOD::Vertex * fit(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.
ToolHandle< Trk::IVertexUpdator > m_VertexUpdator
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::IVertexLinearizedTrackFactory > m_LinearizedTrackFactory
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,...
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.
void addTrackAtVertex(const ElementLink< TrackParticleContainer > &tr, float weight=1.0)
Add a new track to the vertex.
void addNeutralAtVertex(const ElementLink< NeutralParticleContainer > &tr, float weight=1.0)
Add a new neutral to the vertex.
void setVertexType(VxType::VertexType vType)
Set the type of the vertex.
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.
bool vxTrackAtVertexAvailable() const
Check if VxTrackAtVertices are attached to the object.
float chiSquared() const
Returns the of the vertex fit as float.
std::vector< Trk::VxTrackAtVertex > & vxTrackAtVertex()
Non-const access to the VxTrackAtVertex vector.
void setFitQuality(float chiSquared, float numberDoF)
Set the 'Fit Quality' information.
const Amg::Vector3D & position() const
Returns the 3-pos.
Eigen::Matrix< double, 3, 1 > Vector3D
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