ATLAS Offline Software
Loading...
Searching...
No Matches
JetFitterRoutines.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 JetFitterRoutines.h - Description
7 -------------------
8
9 begin : Februar 2007
10 authors: Giacinto Piacquadio (University of Freiburg),
11 Christian Weiser (University of Freiburg)
12 email : nicola.giacinto.piacquadio@cern.ch,
13 christian.weiser@cern.ch
14 changes: new!
15
16 2007 (c) Atlas Detector Software
17
18 Look at the header file for more information.
19
20 ***************************************************************************/
21
22
23
24// to get AmgMatrix plugin:
26
28#include "VxVertex/RecVertex.h"
41
44
45
48
49#include <TMath.h>
50#include <cmath>
51#include <sstream>
52#include <iostream>
53#include <algorithm>
54
55
56
57namespace Trk
58{
59
60 JetFitterRoutines::JetFitterRoutines(const std::string& t, const std::string& n, const IInterface* p) :
61 AthAlgTool(t,n,p),
62 m_initializationHelper("Trk::JetFitterInitializationHelper", this),
63 m_helper("Trk::JetFitterHelper", this),
64 m_updator("Trk::KalmanVertexOnJetAxisUpdator", this),
65 m_smoother("Trk::KalmanVertexOnJetAxisSmoother", this),
66 m_minDistanceFinder("Trk::TrkDistanceFinderNeutralCharged/TrkDistanceFinderNeutralCharged", this),
67 m_minDistanceFinderNeutral("Trk::TrkDistanceFinderNeutralNeutral/TrkDistanceFinderNeutralNeutral", this),
68 m_fast(false),
69 m_maxDRshift(.5),
71 m_maxR(1150.),//max R of ID
72 m_maxZ(2727.)//max Z of ID
73 {
74 declareProperty("KalmanVertexOnJetAxisUpdator",m_updator);
75 declareProperty("KalmanVertexOnJetAxisSmoother",m_smoother);
76 declareProperty("JetFitterHelper",m_helper);
77 declareProperty("JetFitterInitializationHelper",m_initializationHelper);
78 declareProperty("JetFitterMinimumDistanceFinder",m_minDistanceFinder);
79 declareProperty("JetFitterMinimumDistanceFinderNeutral",m_minDistanceFinderNeutral);
80 declareProperty("ID_maxR",m_maxR);
81 declareProperty("ID_maxZ",m_maxZ);
82 declareInterface< JetFitterRoutines >(this) ;
83 declareProperty("BeFast",m_fast);
84 declareProperty("maxDRshift",m_maxDRshift);
85 declareProperty("noPrimaryVertexRefit",m_noPrimaryVertexRefit);
86
87 }
88
89
90
92
93
95
96 AthAlgTool::initialize().ignore();
98
99 //retrieving the udator itself
100 ATH_CHECK( m_helper.retrieve() );
101
102 ATH_CHECK( m_initializationHelper.retrieve() );
103
104 ATH_CHECK( m_minDistanceFinder.retrieve() );
105
107
108 ATH_CHECK( m_updator.retrieve() );
109
110 ATH_CHECK( m_smoother.retrieve() );
111
112 return StatusCode::SUCCESS;
113 }
114
115
117
118 ATH_MSG_DEBUG ("initializingToMinDistancesToJetAxis is now implemented! Will converge faster!!! Neutrals are fully supported...");
119
120 VertexPositions & linVertexPositions=myJetCandidate->getLinearizationVertexPositions();
121 Amg::VectorX linPositions=linVertexPositions.position();
122
123
124 const Trk::RecVertexPositions & recVtxPosition=myJetCandidate->getRecVertexPositions();
125 const Amg::VectorX & recPosition=recVtxPosition.position();
126
127 Amg::Vector3D a(recPosition[Trk::jet_xv],
128 recPosition[Trk::jet_yv],
129 recPosition[Trk::jet_zv]);
130
131 auto const sinRecJetTheta = std::sin(recPosition[Trk::jet_theta]);
132 auto const sinRecJetPhi = std::sin(recPosition[Trk::jet_phi]);
133 auto const cosRecJetTheta = std::cos(recPosition[Trk::jet_theta]);
134 auto const cosRecJetPhi = std::cos(recPosition[Trk::jet_phi]);
135
136 auto const absRecJetTheta = std::abs(recPosition[Trk::jet_theta]);
137 auto const abssinRecJetTheta = std::abs(sinRecJetTheta);
138 auto const abscosRecJetTheta = std::abs(cosRecJetTheta);
139
140 Amg::Vector3D b(cosRecJetPhi*sinRecJetTheta,
141 sinRecJetPhi*sinRecJetTheta,
142 cosRecJetTheta);
143
144 NeutralTrack myJetAxis(a,b);
145
146 //Yes, but the seeding is more than just speed!
147 const std::vector<VxVertexOnJetAxis*> & associatedVertices=myJetCandidate->getVerticesOnJetAxis();
148
149 const std::vector<VxVertexOnJetAxis*>::const_iterator VtxBegin=associatedVertices.begin();
150 const std::vector<VxVertexOnJetAxis*>::const_iterator VtxEnd=associatedVertices.end();
151
152 if (associatedVertices.empty()) {//Was that your intention? to be checked... 15.03.2007
154 const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
155 if (!readHandle.isValid() or !fieldCondObj) {
156 std::stringstream msg;
157 msg << "Failed to retrieve magmnetic field conditions data " << m_fieldCacheCondObjInputKey.key() << ".";
158 throw std::runtime_error(msg.str());
159 }
160 MagField::AtlasFieldCache fieldCache;
161 fieldCondObj->getInitializedCache (fieldCache);
162 for (std::vector<VxVertexOnJetAxis*>::const_iterator VtxIter=VtxBegin;VtxIter!=VtxEnd;++VtxIter) {
163 VxVertexOnJetAxis* myVertex=(*VtxIter);
164 if (myVertex!=nullptr) {
165
166 const std::vector<VxTrackAtVertex*> & tracksAtVertex=myVertex->getTracksAtVertex();
167 if (tracksAtVertex.size()>1) {
168 ATH_MSG_DEBUG( "Warning in JetFitterInitializationHelper.Number of tracks at vertex is bigger than one, "
169 << "even during initialization phase. Skipping this vertex (already initialized)..." );
170 }
171 else if (tracksAtVertex.empty())
172 {
173 ATH_MSG_WARNING( "No track at vertex. Internal fitter error. Contact author (GP) ... " );
174 }
175 else
176 {
177 ATH_MSG_VERBOSE( " TrackAtVertexSize is: " << tracksAtVertex.size() );
178 ATH_MSG_VERBOSE( " pointer to first element: " << tracksAtVertex[0] );
179 ATH_MSG_VERBOSE( " pointer to initialPerigee: " << tracksAtVertex[0]->initialPerigee() );
180
181 // RS 19.04.2011 try to fix coverity defect 22750
182 const Trk::Perigee* ptr = dynamic_cast<const Trk::Perigee*>((tracksAtVertex[0]->initialPerigee()));
183 if (ptr)
184 {
185
186 double distOnAxis=-999.;
187 std::pair<Amg::Vector3D,double> result;
188 try {
189 result=m_minDistanceFinder->getPointAndDistance(myJetAxis,*ptr,distOnAxis, fieldCache);
190
191 double R=distOnAxis*sinRecJetTheta;
192 double Z=distOnAxis*cosRecJetTheta;
193
194 if (std::abs(R)>m_maxR)
195 {
196
197 if (absRecJetTheta>1e-8)
198 {
199 ATH_MSG_DEBUG( " Closest distance of track to jet axis is outside ID envelope, R=" << R << ", setting to R= " << m_maxR );
200 distOnAxis=m_maxR /abssinRecJetTheta;
201 }
202 }
203
204 Z=distOnAxis*cosRecJetTheta;
205 if (std::abs(Z)>m_maxZ)
206 {
207 if (abscosRecJetTheta>1e-8)
208 {
209 ATH_MSG_DEBUG( " Closest distance of track to jet axis is outside ID envelope, Z=" << Z << ", setting to Z= " << m_maxZ );
210 distOnAxis=m_maxZ / cosRecJetTheta;
211 }
212 }
213
214 linPositions[numRow(myVertex->getNumVertex())]=distOnAxis;
215
216
217 } catch (Error::NewtonProblem e) {
218 ATH_MSG_WARNING( "Problem with Newton finder " << e.p );
219 } catch (...) {
220 ATH_MSG_ERROR( "Could not catch error " );
221 }
222 ATH_MSG_DEBUG ("initializingToMinDistancesToJetAxis for vertex number... " <<
223 myVertex->getNumVertex() << " to distance " << distOnAxis <<
224 " distance to axis " << result.second);
225 }
226 // FIXME THIS PART IS DEAD IN NEW TRACKING EDM:
227 else if (dynamic_cast<const Trk::NeutralPerigee*>((tracksAtVertex[0]->initialPerigee()))!=nullptr)
228 {
229 double distOnAxis=-999.;
230 std::pair<Amg::Vector3D,double> result;
231
232 const Trk::NeutralPerigee * neutralTrack =
233 dynamic_cast<const Trk::NeutralPerigee*>((tracksAtVertex[0]->initialPerigee()));
234
235 NeutralTrack myNeutralTrack(neutralTrack->position(),neutralTrack->momentum());
236
237 result=m_minDistanceFinderNeutral->getPointAndDistance(myJetAxis,myNeutralTrack,distOnAxis);
238
239 double R=distOnAxis*sinRecJetTheta;
240 double Z=distOnAxis*cosRecJetTheta;
241
242 if (std::abs(R)>m_maxR)
243 {
244
245 if (absRecJetTheta>1e-8)
246 {
247 ATH_MSG_DEBUG( " Closest distance of track to jet axis is outside ID envelope, R=" << R << ", setting to R= " << m_maxR );
248 distOnAxis=m_maxR / abssinRecJetTheta;
249 }
250 }
251
252 Z=distOnAxis*cosRecJetTheta;
253 if (std::abs(Z)>m_maxZ)
254 {
255 if (abscosRecJetTheta>1e-8)
256 {
257 ATH_MSG_DEBUG( " Closest distance of track to jet axis is outside ID envelope, Z=" << Z << ", setting to Z= " << m_maxZ );
258 distOnAxis=m_maxZ / cosRecJetTheta;
259 }
260 }
261
262 linPositions[numRow(myVertex->getNumVertex())]=distOnAxis;
263 ATH_MSG_DEBUG( "initializingToMinDistancesToJetAxis for vertex from NEUTRAL number... " <<
264 myVertex->getNumVertex() << " to distance " <<
265 distOnAxis << " distance to axis " << result.second );
266
267 }
268 else
269 {
270 ATH_MSG_WARNING( "Could not cast to neither CHARGED or NEUTRAL! This error is not FATAL" );
271 }
272 }
273 } else {
274 ATH_MSG_WARNING( "Warning in JetFitterInitializationHelper.Inconsistency found. Pointer to VxVertexOnJetAxis should be different from zero. Skipping track..." );
275 throw ("Warning in JetFitterInitializationHelper.Inconsistency found. Pointer to VxVertexOnJetAxis should be different from zero. Skipping track...");
276 }
277 }
278
279 linVertexPositions.setPosition(linPositions);
280
281 } else {
282 ATH_MSG_DEBUG ("No Associated Vertices found! no initialization to minimum distance is possible.");
283 }
284 }
285
287 int num_maxiterations,//default 20
288 bool treat_sign_flip,//default true
289 int num_signflip_maxiterations,//default 10
290 double deltachi2_convergence) const {//default 0.001
291
292 bool isInitialized=this->checkJetCandidate(myJetCandidate);
293
294 if (!isInitialized) {
295 ATH_MSG_DEBUG ("JetFitter found the candidate was not correctly initialized. Not proceeding with the fitt...");
296 return;
297 }
298
299
300
301 //linearization is DONE. now do fit with all the vertices (updating them through the knowledge coming from all the tracks parameters)
302
303 int num_iteration_signflip=0;
304 double lastchi2=-99.;
305 bool converged=false;
306
307 if (treat_sign_flip) {
308 do {
309
311
312 ATH_MSG_DEBUG( myJetCandidate->getRecVertexPositions() );
313
314 //linearization position is now stored in a different VertexPositions attached to the VxJetCandidate...
315 m_initializationHelper->linearizeAllTracks(myJetCandidate,true);
316
317 //now update all vertices with the new information
318 updateAllVertices(myJetCandidate);
319
320 //now do the chi2 update of all tracks after end of fit iterations
321 //(this permits to invert the big weight matrix only once at the end!!)
322 // updateChi2AllVertices(myJetCandidate);
323
324 num_iteration_signflip+=1;
325
326 const RecVertexPositions & myRecPosition=myJetCandidate->getRecVertexPositions();
327
328 const FitQuality & myFitQuality=myRecPosition.fitQuality();
329
330 double actualchi2=myFitQuality.chiSquared();
331
332 auto const absActLastChi2 = std::abs(actualchi2-lastchi2);
333
334#ifdef JetFitterRoutines_DEBUG
335 ATH_MSG_DEBUG( " last chi2 " << lastchi2 << " actual chi2 " << actualchi2 << " difference " <<
336 absActLastChi2<< " < " << deltachi2_convergence << " ? " << " ndf " << myFitQuality.numberDoF() );
337#endif
338
339 if (absActLastChi2<deltachi2_convergence) {
340 converged=true;
341 } else {
342
343 //GP 12.3.2012 Check that no vertex is outside the ID acceptance
345
346 }
347
348 lastchi2=actualchi2;
349
350 } while ((!converged)&&num_iteration_signflip<num_signflip_maxiterations);
351
352
353 if (converged) {
354 ATH_MSG_VERBOSE( " For sign flip treatment there was convergence after " << num_iteration_signflip );
355 }
356 }
357
358 // if (msgSvc()->outputLevel()== MSG::DEBUG||msgSvc()->outputLevel()== MSG::VERBOSE) {
359#ifdef JetFitterRoutines_DEBUG
360 ATH_MSG_DEBUG( "JetFitterRoutines: after convergence with sign flip treatment: " << myJetCandidate->getRecVertexPositions() );
361#endif
362 // }
363
364 int num_iteration=0;
365 lastchi2=-99.;
366 converged=false;
367
368 do {
369
370
372
373
374 //linearization position is now stored in a different VertexPositions attached to the VxJetCandidate...
375 m_initializationHelper->linearizeAllTracks(myJetCandidate,false);
376
377 //now update all vertices with the new information
378 updateAllVertices(myJetCandidate);
379
380 //now do the chi2 update of all tracks after end of fit iterations
381 //(this permits to invert the big weight matrix only once at the end!!)
382 // updateChi2AllVertices(myJetCandidate);
383
384 num_iteration+=1;
385
386 const RecVertexPositions & myRecPosition=myJetCandidate->getRecVertexPositions();
387
388 ATH_MSG_VERBOSE( " num_iteration (full fit): " << num_iteration << " det " << myRecPosition.covariancePosition().determinant() << " recVertex " << myJetCandidate->getRecVertexPositions() );
389
390 const FitQuality & myFitQuality=myRecPosition.fitQuality();
391 double actualchi2=myFitQuality.chiSquared();
392
393 auto const absActLastChi2 = std::abs(actualchi2-lastchi2);
394
395 // if (msgSvc()->outputLevel()== MSG::VERBOSE) {
396#ifdef JetFitterRoutines_DEBUG
397 ATH_MSG_DEBUG( " without sign flip: last chi2 " << lastchi2 << " actual chi2 " << actualchi2 << " difference " <<
398 absActLastChi2 << " < " << deltachi2_convergence << " ? " << " ndf " << myFitQuality.numberDoF() );
399#endif
400 // }
401
402 if (absActLastChi2<deltachi2_convergence) {
403 converged=true;
404 } else {
405 //now set the linearization position for the next step to the actual fitted vertex
406 //GP 12.3.2012 Check that no vertex is outside the ID acceptance
408 //OLD myJetCandidate->setLinearizationVertexPositions(myJetCandidate->getRecVertexPositions());
409 }
410 lastchi2=actualchi2;
411
412 } while ((!converged)&&num_iteration<num_maxiterations);
413
414 if (converged) {
415 ATH_MSG_VERBOSE( " Fit without sign flip treatment there was convergence after " << num_iteration );
416 }
417
418 // if (msgSvc()->outputLevel()== MSG::VERBOSE) {
419 #ifdef JetFitterRoutines_DEBUG
420 ATH_MSG_DEBUG( "JetFitterRoutines: after convergence without sign flip treatment: " << myJetCandidate->getRecVertexPositions() );
421 #endif
422 // }
423 if (num_iteration>=num_maxiterations)
424 {
425 ATH_MSG_DEBUG( "There wasn't convergence in JetFitter after: " << num_maxiterations );
426 }
427
428 //now only the smoothing is missing as a last step... (updated momenta, chi2 + ndf of clusters,...)
429
430 smoothAllVertices(myJetCandidate);
431
432 Trk::VxJetFitterDebugInfo * & myDebugInfo=myJetCandidate->getDebugInfo();
433 if (myDebugInfo!=nullptr) {
434 delete myDebugInfo;
435 }
436 myDebugInfo=new VxJetFitterDebugInfo();
437 myDebugInfo->setNumFitIterations(num_iteration);
438 myDebugInfo->setSignFlipNumFitIterations(num_iteration_signflip);
439
440 }
441
442
444
445// ATH_MSG_DEBUG( " Updating PV " );
446
447 int n_iteration=0;
448
449
451 //new iteration
452 VxVertexOnJetAxis* myPrimary=myJetCandidate->getPrimaryVertex();
453 const std::vector<VxTrackAtVertex*> & primaryVectorTracks=myPrimary->getTracksAtVertex();
454
455 const std::vector<VxTrackAtVertex*>::const_iterator primaryVectorTracksBegin=primaryVectorTracks.begin();
456 const std::vector<VxTrackAtVertex*>::const_iterator primaryVectorTracksEnd=primaryVectorTracks.end();
457
458 for (std::vector<VxTrackAtVertex*>::const_iterator primaryVectorIter=primaryVectorTracksBegin;
459 primaryVectorIter!=primaryVectorTracksEnd;++primaryVectorIter) {
460
461 ATH_MSG_VERBOSE( " RecVertexPositions before update " << myJetCandidate->getRecVertexPositions() );
462
463 if ((!m_fast)) {
464 m_updator->add(*primaryVectorIter,myPrimary,myJetCandidate);
465 } else {
466 m_updator->addWithFastUpdate(*primaryVectorIter,myPrimary,myJetCandidate);
467 }
468
469 const RecVertexPositions & myRecPosition=myJetCandidate->getRecVertexPositions();
470
471 ATH_MSG_VERBOSE( " Determinant after PRIMARY VTX update: " << n_iteration << " det: " << myRecPosition.covariancePosition().determinant() << " recVertex " << myJetCandidate->getRecVertexPositions() );
472 }
473 }
474
475 n_iteration=0;
476
477 // const RecVertexPositions & myRecPositionBeg=myJetCandidate->getRecVertexPositions();
478
479 const std::vector<VxVertexOnJetAxis*> & associatedVertices=myJetCandidate->getVerticesOnJetAxis();
480
481 const std::vector<VxVertexOnJetAxis*>::const_iterator VtxBegin=associatedVertices.begin();
482 const std::vector<VxVertexOnJetAxis*>::const_iterator VtxEnd=associatedVertices.end();
483
484 for (std::vector<VxVertexOnJetAxis*>::const_iterator VtxIter=VtxBegin;VtxIter!=VtxEnd;++VtxIter) {
485
486// ATH_MSG_DEBUG( " Updating an SV along jet axis " );
487
488 const std::vector<VxTrackAtVertex*> & tracksAtVertex=(*VtxIter)->getTracksAtVertex();
489
490 const std::vector<VxTrackAtVertex*>::const_iterator TracksBegin=tracksAtVertex.begin();
491 const std::vector<VxTrackAtVertex*>::const_iterator TracksEnd=tracksAtVertex.end();
492
493 for (std::vector<VxTrackAtVertex*>::const_iterator TrackVectorIter=TracksBegin;
494 TrackVectorIter!=TracksEnd;++TrackVectorIter) {
495
496 ATH_MSG_VERBOSE( " RecVertexPositions before update " << myJetCandidate->getRecVertexPositions() );
497
498 if (!m_fast) {
499 m_updator->add(*TrackVectorIter,*VtxIter,myJetCandidate);
500 } else {
501 m_updator->addWithFastUpdate(*TrackVectorIter,*VtxIter,myJetCandidate);
502 }
503
504 n_iteration+=1;
505
506 const RecVertexPositions & myRecPosition=myJetCandidate->getRecVertexPositions();
507
508 ATH_MSG_VERBOSE( " Determinant after sec update: " << n_iteration << " det: " << myRecPosition.covariancePosition().determinant() << " recVertex " << myJetCandidate->getRecVertexPositions() );
509 }
510 }
511
512 myJetCandidate->getRecVertexPositions().finalizePosition();
513 }
514
516 //new iteration
517 VxVertexOnJetAxis* myPrimary=myJetCandidate->getPrimaryVertex();
518
519 if (!m_fast) {
520 m_smoother->update(myPrimary,myJetCandidate);
521 } else {
522 m_smoother->fastUpdate(myPrimary,myJetCandidate);
523 }
524
525 const std::vector<VxVertexOnJetAxis*> & associatedVertices=myJetCandidate->getVerticesOnJetAxis();
526
527 const std::vector<VxVertexOnJetAxis*>::const_iterator VtxBegin=associatedVertices.begin();
528 const std::vector<VxVertexOnJetAxis*>::const_iterator VtxEnd=associatedVertices.end();
529
530 for (std::vector<VxVertexOnJetAxis*>::const_iterator VtxIter=VtxBegin;VtxIter!=VtxEnd;++VtxIter) {
531 if (!m_fast) {
532 m_smoother->update(*VtxIter,myJetCandidate);
533 } else {
534 m_smoother->fastUpdate(*VtxIter,myJetCandidate);
535 }
536 }
537 }
538
539
540
541
543
544 int sizeprimary(0);
545
546 //check if primaryvertex exists
547 const VxVertexOnJetAxis* myPrimary=myJetCandidate->getPrimaryVertex();
548 if (myPrimary==nullptr) {
549 ATH_MSG_WARNING( "No primary vertex found in VxJetCandidate class. Initialization was not done correctly..." );
550 return false;
551 }
552
553 bool ok = true;
554 if (myPrimary->getNumVertex() != -10) {
555 ATH_MSG_WARNING("Numvertex of primary vertex not correctly initialized. "
556 "Not proceeding with the fit!");
557 return false;
558 }
559
560 const std::vector<VxTrackAtVertex*>& primaryVectorTracks =
561 myPrimary->getTracksAtVertex();
562
563 sizeprimary = primaryVectorTracks.size();
564 ok = std::ranges::none_of(primaryVectorTracks,[](const auto* track) { return track == nullptr; });
565 if (not ok){
566 ATH_MSG_WARNING("At least one of the VxTrackAtVertex is a null pointer. Not "
567 "proceeding with the fit!");
568 return false;
569 }
570
571 // end if else rimary==0
572
573 // check std::vector<VxVertexOnJetAxis*> (if pointers are not empty and if
574 // all associated tracks are not empty)
575 const std::vector<VxVertexOnJetAxis*>& tracksOfVertex =
576 myJetCandidate->getVerticesOnJetAxis();
577
578 auto badVertex = [](VxVertexOnJetAxis* pVertex) {
579 return (pVertex == nullptr) or (pVertex->getNumVertex() < 0);
580 };
581 ok =
582 (std::find_if(tracksOfVertex.begin(), tracksOfVertex.end(), badVertex) ==
583 tracksOfVertex.end());
584 if (not ok) {
586 "One of the VxTrackAtVertex is a null pointer or uninitialized. Not "
587 "proceeding with the fit!"); // Two error messages combined into one
588 }
589 if (not ok) {
590 return false;
591 }
592
593 //now check if there is some track at least to do the fit...
594
595 if (tracksOfVertex.empty()&&sizeprimary==0) {
596 ATH_MSG_DEBUG( "No tracks at primary, no tracks on jet axis. Not proceeding with the fit!" );
597 return false;
598 }
599
600 //now check if the number of tracks corrisponds to the number of components of the recVertexPositions
601 const Trk::RecVertexPositions & myRecVertexPositions=myJetCandidate->getRecVertexPositions();
602
603 const Amg::VectorX& myPosition=myRecVertexPositions.position();
604
605 if (static_cast<unsigned int>(tracksOfVertex.size()+5)!=static_cast<unsigned int>(myPosition.rows())) {
606 ATH_MSG_WARNING ( "The position matrix has " << myPosition.rows()
607 << " components while " << tracksOfVertex.size()+5
608 << " are expected. Not proceeding with the fit " );
609 }
610
611 const Amg::MatrixX & myErrorMatrix=myRecVertexPositions.covariancePosition();
612
613 //check if symMatrix and myPosition are compatible (size matches)
614 if (myPosition.rows()!=myErrorMatrix.rows()) {
615 ATH_MSG_WARNING ("The dimension of the position vector and the covariance matrix does not match. Not performing fit...");
616 return false;
617 }
618
619 //check if all the diagonal values of the covariance matrix are not zero
620 for (int i=0;i<myPosition.rows();i++) {
621 if (std::abs(myErrorMatrix(i,i))<1e-20) {
622 ATH_MSG_WARNING ("Value of cov matrix component n. " << i << " has a value smaller than 1e-8. Not considered as possible. Not performing fit...");
623 return false;
624 }
625 }
626
627 //well, more checks in the future!!!
628
629 return true;
630
631 }//end method
632
633
634 std::pair<double,bool> JetFitterRoutines::fastProbabilityOfMerging(const VxVertexOnJetAxis* firstVertex,
635 const VxVertexOnJetAxis* secondVertex,
636 const VxJetCandidate* myJetCandidate) const {
637 //this method is for evaluating the probability of merging in a very fast (and rough) way
638 //if above a threshold you should think about evaluating the "fullProbabilityOfMerging" :-)
639
640 const VxVertexOnJetAxis * PrimaryVertex=myJetCandidate->getPrimaryVertex();
641
642 if (firstVertex==PrimaryVertex) {
643 return fastProbabilityOfMergingWithPrimary(secondVertex,myJetCandidate);
644 }
645 if (secondVertex==PrimaryVertex) {
646 return fastProbabilityOfMergingWithPrimary(firstVertex,myJetCandidate);
647 }
648
649 return fastProbabilityOfMergingNoPrimary(firstVertex,secondVertex,myJetCandidate);
650
651 }
652
653
655 const VxJetCandidate* myJetCandidate) const {
656
657
658 //first get a copy of all vertex positions (this you can't avoid I fear...)
659 RecVertexPositions copyOfRecVertexPositions(myJetCandidate->getRecVertexPositions());
660
661
662 double oldchi2=copyOfRecVertexPositions.fitQuality().chiSquared();
663 double oldndf=copyOfRecVertexPositions.fitQuality().numberDoF();
664
665 //#ifdef JetFitterRoutines_DEBUG2
666 const Amg::VectorX & positionVector=copyOfRecVertexPositions.position();
667 const Amg::MatrixX & positionCov=copyOfRecVertexPositions.covariancePosition();
668 double phiold=positionVector(Trk::jet_phi);
669 double thetaold=positionVector(Trk::jet_theta);
670 double phierr=std::sqrt(positionCov(Trk::jet_phi,Trk::jet_phi));
671 double thetaerr=std::sqrt(positionCov(Trk::jet_theta,Trk::jet_theta));
672
673 //now do the merging of the second cluster to the primary vertex...
674 m_helper->performKalmanConstraintToBePrimaryVertex(copyOfRecVertexPositions,
675 *otherVertex);
676
677 double phinew=positionVector[Trk::jet_phi];
678 double thetanew=positionVector[Trk::jet_theta];
679 bool isshifted=
680 std::pow((phinew-phiold)/phierr,2)+std::pow((thetanew-thetaold)/thetaerr,2)>m_maxDRshift*m_maxDRshift;
681
682 double chi2 = myJetCandidate->getPrimaryVertex()->fitQuality().chiSquared() +
683 otherVertex->fitQuality().chiSquared() +
684 copyOfRecVertexPositions.fitQuality().chiSquared()-oldchi2;
685
686 double ndf = copyOfRecVertexPositions.fitQuality().numberDoF()-oldndf +
687 myJetCandidate->getPrimaryVertex()->fitQuality().numberDoF() +
688 otherVertex->fitQuality().numberDoF();
689
690 if (chi2<0||ndf<0) {
691 ATH_MSG_WARNING (" In the compatibility estimation chi2: " << chi2 << " ndf " << ndf << " giving back 0 prob ");
692 return std::pair<double,bool>(0,isshifted);
693 }
694
695 return std::pair<double,bool>(TMath::Prob(chi2,(int)std::floor(ndf+0.5)),isshifted);
696
697 }
698
700 const VxVertexOnJetAxis* secondVertex,
701 const VxJetCandidate* myJetCandidate) const {
702
703 //first get a copy of all vertex positions (this you can't avoid I fear...)
704 RecVertexPositions copyOfRecVertexPositions(myJetCandidate->getRecVertexPositions());
705 const FitQuality & copyOfRecVertexQuality=copyOfRecVertexPositions.fitQuality();
706
707 double oldchi2=copyOfRecVertexQuality.chiSquared();
708 double oldndf=copyOfRecVertexQuality.numberDoF();
709
710 //#ifdef JetFitterRoutines_DEBUG2
711 const Amg::VectorX & positionVector=copyOfRecVertexPositions.position();
712 const Amg::MatrixX & positionCov=copyOfRecVertexPositions.covariancePosition();
713 double phiold=positionVector(Trk::jet_phi);
714 double thetaold=positionVector(Trk::jet_theta);
715 double phierr=std::sqrt(positionCov(Trk::jet_phi,Trk::jet_phi));
716 double thetaerr=std::sqrt(positionCov(Trk::jet_theta,Trk::jet_theta));
717
718
719 //now do the merging of the second cluster to the primary vertex...
720 m_helper->performKalmanConstraintToMergeVertices(copyOfRecVertexPositions,
721 *firstVertex,
722 *secondVertex);
723
724 double phinew=positionVector[Trk::jet_phi];
725 double thetanew=positionVector[Trk::jet_theta];
726 bool isshifted=std::pow((phinew-phiold)/phierr,2)+std::pow((thetanew-thetaold)/thetaerr,2)>m_maxDRshift* m_maxDRshift;
727
728 double chi2 = firstVertex->fitQuality().chiSquared() +
729 secondVertex->fitQuality().chiSquared() +
730 copyOfRecVertexPositions.fitQuality().chiSquared()-oldchi2;
731
732
733 double ndf = copyOfRecVertexPositions.fitQuality().numberDoF()-oldndf +
734 firstVertex->fitQuality().numberDoF()+
735 secondVertex->fitQuality().numberDoF();
736
737 if (chi2<0||ndf<0) {
738 ATH_MSG_WARNING ("In the compatibility estimation chi2: " << chi2 << " ndf " << ndf << " giving back 0 prob");
739 return std::pair<double,bool>(0,isshifted);
740 }
741
742 return std::pair<double,bool>(TMath::Prob(chi2,(int)std::floor(ndf+0.5)),isshifted);
743
744
745 }
746
748 const VxVertexOnJetAxis* secondVertex,
749 const VxJetCandidate* myJetCandidate,
750 int num_maxiterations,
751 bool treat_sign_flip,
752 int num_signflip_maxiterations,
753 double deltachi2_convergence) const {
754
755
756 if (firstVertex==nullptr||secondVertex==nullptr||myJetCandidate==nullptr) {
757 ATH_MSG_WARNING ("zero pointer given to the full probability estimation. No estimation performed, zero prob returned ");
758 return 0;
759 }
760
761 //copy the VxJetCandidate into a new object (this is expensive...)
762 VxJetCandidate newJetCandidate(*myJetCandidate);
763
764
765 //first find correspondence between old first and secondVertex and new ones (horrible,but...)
766
767 std::map<const VxVertexOnJetAxis*,VxVertexOnJetAxis*> oldToNewVtxPointers;
768
769
770 const std::vector<VxVertexOnJetAxis*> vectorOfOldJetCand=myJetCandidate->getVerticesOnJetAxis();
771 const std::vector<VxVertexOnJetAxis*> vectorOfNewJetCand=newJetCandidate.getVerticesOnJetAxis();
772
773 const VxVertexOnJetAxis* primaryOfFirst=myJetCandidate->getPrimaryVertex();
774 VxVertexOnJetAxis* primaryOfSecond=newJetCandidate.getPrimaryVertex();
775
776 if (primaryOfFirst==nullptr||primaryOfSecond==nullptr) {
777 ATH_MSG_WARNING ("Empty primary vertex found when estimating fullProbOfMerging. 0 prob returned.");
778 return 0;
779 }
780
781 oldToNewVtxPointers[primaryOfFirst]=primaryOfSecond;
782
783 unsigned int sizeOfVertices=vectorOfOldJetCand.size();
784 if (vectorOfNewJetCand.size()!=sizeOfVertices) {
785 ATH_MSG_WARNING ("Old and new track of vertices do not match during fullProbOfMerging. 0 prob returned.");
786 return 0;
787 }
788
789 for (unsigned int s=0;s<sizeOfVertices;s++) {
790 const VxVertexOnJetAxis* pointer1=vectorOfOldJetCand[s];
791 VxVertexOnJetAxis* pointer2=vectorOfNewJetCand[s];
792 if (pointer1==nullptr||pointer2==nullptr) {
793 ATH_MSG_WARNING ("One of the pointers of the original or copied vector of vertices is empty during fullProbOfMerging. Skipping it...");
794 } else {
795 oldToNewVtxPointers[pointer1]=pointer2;
796 }
797 }
798
799 //now merge firstVertex and secondVertex
800 VxVertexOnJetAxis* newFirstVertex=oldToNewVtxPointers[firstVertex];
801 VxVertexOnJetAxis* newSecondVertex=oldToNewVtxPointers[secondVertex];
802
803 if (newFirstVertex==nullptr||newSecondVertex==nullptr) {
804 ATH_MSG_WARNING ("No correspondence to the given firstVertex or secondVertex in fullProbOfMerging. Returning 0 prob.");
805 return 0.;
806 }
807
808 VxVertexOnJetAxis & commonVertex=m_helper->mergeVerticesInJetCandidate(*newFirstVertex,
809 *newSecondVertex,
810 newJetCandidate);
811
812 //now you need to update the numbering scheme
813 m_initializationHelper->updateTrackNumbering(&newJetCandidate);
814
815 performTheFit(&newJetCandidate,num_maxiterations,
816 treat_sign_flip,
817 num_signflip_maxiterations,
818 deltachi2_convergence);
819
820 // const FitQuality & qualityOfMergedVertex=commonVertex.fitQuality();
821
822#ifdef JetFitterRoutines_DEBUG
823 ATH_MSG_DEBUG( " End estimating full prob of merging... chi2 " << commonVertex.fitQuality().chiSquared() << " ndf " << commonVertex.fitQuality().numberDoF() );
824#endif
825
826 return (double)TMath::Prob(commonVertex.fitQuality().chiSquared(),
827 (int)std::floor(commonVertex.fitQuality().numberDoF()+0.5));
828
829 }
830
832 int num_maxiterations,
833 bool treat_sign_flip,
834 int num_signflip_maxiterations,
835 double deltachi2_convergence,
836 double threshold_probability) const {
837 fillTableWithProbOfMerging(myJetCandidate,
838 true,
839 num_maxiterations,
840 treat_sign_flip,
841 num_signflip_maxiterations,
842 deltachi2_convergence,
843 threshold_probability);
844 }
845
847 fillTableWithProbOfMerging(myJetCandidate,false);
848 }
849
850
852 bool fullcomputation,
853 int num_maxiterations,
854 bool treat_sign_flip,
855 int num_signflip_maxiterations,
856 double deltachi2_convergence,
857 double threshold_probability) const {
858
859 if (myJetCandidate==nullptr) {
860 ATH_MSG_WARNING( "VxJetCandidate provided is a zero pointer. No compatibility table calculated." );
861 return;
862 }
863
864 //first create the compatibility table object...
865 Trk::VxClusteringTable* & clusteringTablePtr(myJetCandidate->getClusteringTable());
866 if (clusteringTablePtr!=nullptr) {
867 delete clusteringTablePtr;
868 }
869 clusteringTablePtr=new Trk::VxClusteringTable();
870
871 double highestprobability(0.);
872
873 VxVertexOnJetAxis* primaryVertex=myJetCandidate->getPrimaryVertex();
874
875 if (primaryVertex==nullptr) {
876 ATH_MSG_WARNING( "VxJetCandidate provided has no primary vertex. No compatibility table calculated." );
877 return;
878 }
879
880 primaryVertex->setCompatibilityToPrimaryVtx(1);//stupid but assign prob 1 to primary vtx for consistency
881
882 const std::vector<VxVertexOnJetAxis*> & tracksOnJetAxis=myJetCandidate->getVerticesOnJetAxis();
883
884 //now evaluate probability of cluster forming with primary vertex
885 const std::vector<VxVertexOnJetAxis*>::const_iterator VtxBegin=tracksOnJetAxis.begin();
886 const std::vector<VxVertexOnJetAxis*>::const_iterator VtxEnd=tracksOnJetAxis.end();
887
888 for (std::vector<VxVertexOnJetAxis*>::const_iterator VtxIter=VtxBegin;
889 VtxIter!=VtxEnd;++VtxIter) {
890
891 std::pair<double,bool> fastProbabilityAndNonLinearity=fastProbabilityOfMerging(primaryVertex,
892 *VtxIter,
893 myJetCandidate);
894
895
896 ATH_MSG_VERBOSE ("Fast probability of merging between primary and " <<
897 (*VtxIter)->getNumVertex() << " is " << fastProbabilityAndNonLinearity.first);
898
899#ifdef JetFitterRoutines_DEBUG2
900 ATH_MSG_DEBUG( "Fast probability of merging between primary and " <<
901 (*VtxIter)->getNumVertex() << " is " << fastProbabilityAndNonLinearity.first << " and is max DR " <<
902 fastProbabilityAndNonLinearity.second );
903#endif
904
905 if (fullcomputation) {
906 if (fastProbabilityAndNonLinearity.first>threshold_probability) {
907 if (fastProbabilityAndNonLinearity.first>highestprobability/100.&&fastProbabilityAndNonLinearity.second) {
908
909 double fullProbability=fullProbabilityOfMerging(primaryVertex,*VtxIter,
910 myJetCandidate,num_maxiterations,
911 treat_sign_flip,
912 num_signflip_maxiterations,
913 deltachi2_convergence);
914
915
916#ifdef JetFitterRoutines_DEBUG2
917 ATH_MSG_DEBUG( "Full probability of merging with primary is " << fullProbability );
918#endif
919
920 ATH_MSG_DEBUG ("Full probability of merging with primary is " << fullProbability);
921
922 //store this fullProbability into the VxClusteringTable of myJetCandidate
923
924 clusteringTablePtr->setCompatibilityOfTo(PairOfVxVertexOnJetAxis(primaryVertex,*VtxIter),fullProbability);
925 if (fullProbability>highestprobability) {
926 highestprobability=fullProbability;
927 }
928 (*VtxIter)->setCompatibilityToPrimaryVtx(fullProbability);
929 } else {
930 clusteringTablePtr->setCompatibilityOfTo(PairOfVxVertexOnJetAxis(primaryVertex,*VtxIter),fastProbabilityAndNonLinearity.first);
931 (*VtxIter)->setCompatibilityToPrimaryVtx(fastProbabilityAndNonLinearity.first);
932 }
933 } else {
934 (*VtxIter)->setCompatibilityToPrimaryVtx(fastProbabilityAndNonLinearity.first);
935 }
936 } else {
937 if (fastProbabilityAndNonLinearity.first>threshold_probability) {
938 clusteringTablePtr->setCompatibilityOfTo(PairOfVxVertexOnJetAxis(primaryVertex,*VtxIter),fastProbabilityAndNonLinearity.first);
939 if (fastProbabilityAndNonLinearity.first>highestprobability) {
940 highestprobability=fastProbabilityAndNonLinearity.first;
941 }
942 }
943 (*VtxIter)->setCompatibilityToPrimaryVtx(fastProbabilityAndNonLinearity.first);
944 }
945 }//end first iteration over tracks for compatibility with primary vertex
946
947 //now all the remaining combination have to be tested...
948
949 for (std::vector<Trk::VxVertexOnJetAxis*>::const_iterator VtxIter2=VtxBegin;
950 VtxIter2!=VtxEnd;++VtxIter2) {
951 for (std::vector<Trk::VxVertexOnJetAxis*>::const_iterator VtxIter1=VtxBegin;
952 VtxIter1!=VtxIter2;++VtxIter1) {
953
954 std::pair<double,bool> fastProbabilityAndNonLinearity=fastProbabilityOfMerging(*VtxIter1,
955 *VtxIter2,
956 myJetCandidate);
957
958
959
960 ATH_MSG_VERBOSE ("Fast probability of merging between vtx n " << (*VtxIter1)->getNumVertex()<<
961 " and " << (*VtxIter2)->getNumVertex() << " is " <<
962 fastProbabilityAndNonLinearity.first << " and is max DR " <<
963 fastProbabilityAndNonLinearity.second);
964
965#ifdef JetFitterRoutines_DEBUG2
966 ATH_MSG_DEBUG( "Fast probability of merging between vtx n " << (*VtxIter1)->getNumVertex() << " and " <<
967 (*VtxIter2)->getNumVertex() << " is " << fastProbabilityAndNonLinearity.first << " and is max DR " <<
968 fastProbabilityAndNonLinearity.second );
969#endif
970 if (fullcomputation) {
971 if (fastProbabilityAndNonLinearity.first>threshold_probability) {
972 if (fastProbabilityAndNonLinearity.first>highestprobability/100.&&fastProbabilityAndNonLinearity.second) {
973 double fullProbability=fullProbabilityOfMerging(*VtxIter1,*VtxIter2,
974 myJetCandidate,num_maxiterations,
975 treat_sign_flip,
976 num_signflip_maxiterations,
977 deltachi2_convergence);
978
979
980#ifdef JetFitterRoutines_DEBUG2
981 ATH_MSG_DEBUG( "Full probability of merging is " << fullProbability );
982#endif
983
984 ATH_MSG_VERBOSE ("Full probability of merging is " << fullProbability);
985
986 //store this fullProbability into the VxClusteringTable of myJetCandidate
987
988 clusteringTablePtr->setCompatibilityOfTo(PairOfVxVertexOnJetAxis(*VtxIter1,*VtxIter2),fullProbability);
989 if (fullProbability>highestprobability) {
990 highestprobability=fullProbability;
991 }
992 } else {
993 clusteringTablePtr->setCompatibilityOfTo(PairOfVxVertexOnJetAxis(*VtxIter1,*VtxIter2),fastProbabilityAndNonLinearity.first);
994 }
995 }
996 } else {
997 if (fastProbabilityAndNonLinearity.first>threshold_probability) {
998 clusteringTablePtr->setCompatibilityOfTo(PairOfVxVertexOnJetAxis(*VtxIter1,*VtxIter2),fastProbabilityAndNonLinearity.first);
999 if (fastProbabilityAndNonLinearity.first>highestprobability) {
1000 highestprobability=fastProbabilityAndNonLinearity.first;
1001 }
1002 }
1003 }
1004 }//end first vtx loop
1005 }//end second vtx loop
1006
1007 }//end fillTableWithFullProbOfMerging() method
1008
1010 VxJetCandidate* myJetCandidate) const {
1011 if (vertexToDelete==myJetCandidate->getPrimaryVertex()) {
1012 ATH_MSG_WARNING ("YOU ARE deleting the primary vertex. This is not possible... ");
1013 return;
1014 }
1015
1016 // now you need to *delete* the second vertex in copyOfRecVertexPositions and
1017 // in copyOfLinearizationPositions
1018 const Amg::VectorX & recPosition=myJetCandidate->getRecVertexPositions().position();
1019 const Amg::VectorX & linPosition=myJetCandidate->getLinearizationVertexPositions().position();
1020 const Amg::VectorX & constraintPosition=myJetCandidate->getConstraintVertexPositions().position();
1021 const Amg::MatrixX & covPosition=myJetCandidate->getRecVertexPositions().covariancePosition();
1022 const Amg::MatrixX & covConstraintPosition=myJetCandidate->getConstraintVertexPositions().covariancePosition();
1023
1024 int numbVertex=numRow(vertexToDelete->getNumVertex());
1025 //call the function which deletes a single row (they're in the anonymous namespace, in Utilities.h)
1026 Amg::VectorX reducedRecPositions=deleteRowFromVector(recPosition,numbVertex);
1027 Amg::VectorX reducedLinPositions=deleteRowFromVector(linPosition,numbVertex);
1028 Amg::VectorX reducedConstraintPositions=deleteRowFromVector(constraintPosition,numbVertex);
1029 Amg::MatrixX reducedCovPositions=deleteRowFromSymMatrix(covPosition,numbVertex);
1030 Amg::MatrixX reducedConstraintCovPositions=deleteRowFromSymMatrix(covConstraintPosition,numbVertex);
1031
1032 myJetCandidate->setRecVertexPositions(RecVertexPositions(reducedRecPositions,
1033 reducedCovPositions,
1034 0.,0.));
1035 myJetCandidate->setConstraintVertexPositions(RecVertexPositions(reducedConstraintPositions,
1036 reducedConstraintCovPositions,
1037 0.,0.));
1038 myJetCandidate->setLinearizationVertexPositions(VertexPositions(reducedLinPositions));
1039
1040
1041
1042 //make a copy of the VxTrackAtVertex vector in myJetCandidate to delete some of the elements
1043
1044 //PAY ATTENTION: here you are modifying the vector of tracks DIRECTLY...
1045 std::vector<VxTrackAtVertex*>* tracksAtJetCandidate(myJetCandidate->vxTrackAtVertex());
1046 // RS 19.04.2011 attempt to fix coverity defect 22750
1047 // const std::vector<VxTrackAtVertex*>::iterator TracksBegin=tracksAtJetCandidate->begin();
1048 // std::vector<VxTrackAtVertex*>::iterator TracksEnd=tracksAtJetCandidate->end();
1049
1050
1051 const std::vector<VxTrackAtVertex*> & tracksAtVtx(vertexToDelete->getTracksAtVertex());
1052
1053 const std::vector<VxTrackAtVertex*>::const_iterator TracksAtVtxBegin=tracksAtVtx.begin();
1054 const std::vector<VxTrackAtVertex*>::const_iterator TracksAtVtxEnd=tracksAtVtx.end();
1055
1056 int numberOfTracksBefore=tracksAtJetCandidate->size();
1057 int numberOfTracksToDelete=tracksAtVtx.size();
1058
1059 for (std::vector<VxTrackAtVertex*>::const_iterator TracksAtVtxIter=TracksAtVtxBegin;
1060 TracksAtVtxIter!=TracksAtVtxEnd;
1061 ++TracksAtVtxIter) {
1062
1063 // RS 19.04.2011 attempt to fix coverity defect 22750
1064 std::vector<VxTrackAtVertex*>::iterator TracksBegin=tracksAtJetCandidate->begin();
1065 std::vector<VxTrackAtVertex*>::iterator TracksEnd=tracksAtJetCandidate->end();
1066 for (std::vector<VxTrackAtVertex*>::iterator TracksIter=TracksBegin;TracksIter!=TracksEnd;) {
1067
1068 if (*TracksIter==*TracksAtVtxIter) {
1069 Trk::VxTrackAtVertex* oldPointer=*TracksIter;
1070 TracksIter=tracksAtJetCandidate->erase(TracksIter);
1071 delete oldPointer;
1072 oldPointer=nullptr;
1073 TracksEnd=tracksAtJetCandidate->end();
1074 break;
1075 }
1076 ++TracksIter;
1077
1078 }
1079 }
1080
1081 if (numberOfTracksBefore-numberOfTracksToDelete!=(int)myJetCandidate->vxTrackAtVertex()->size()) {
1082 ATH_MSG_DEBUG( " MISMATCH in JetFitterRoutines: the jetcandidate had: " << numberOfTracksBefore << " tracks " <<
1083 " and " << numberOfTracksToDelete << " to delete = " << myJetCandidate->vxTrackAtVertex()->size() << " tracks left! " );
1084 }
1085
1086
1087 //now as a last step you need to delete the vertex you're not using anymore...
1088
1089 std::vector<VxVertexOnJetAxis*> copyOfVerticesAtJetCandidate=myJetCandidate->getVerticesOnJetAxis();
1090
1091 const std::vector<VxVertexOnJetAxis*>::iterator VerticesBegin=copyOfVerticesAtJetCandidate.begin();
1092 std::vector<VxVertexOnJetAxis*>::iterator VerticesEnd=copyOfVerticesAtJetCandidate.end();
1093
1094 bool found=false;
1095
1096 //have a variable to store the vector of tracks which then need to be removed (copy)...
1097 // std::vector<VxTrackAtVertex*> tracksToRemove=vertexToDelete->getTracksAtVertex();
1098
1099 for (std::vector<VxVertexOnJetAxis*>::iterator VerticesIter=VerticesBegin;VerticesIter!=VerticesEnd;) {
1100 if ((*VerticesIter)==vertexToDelete) {
1101 delete *VerticesIter;
1102 VerticesIter=copyOfVerticesAtJetCandidate.erase(VerticesIter);
1103 VerticesEnd=copyOfVerticesAtJetCandidate.end();
1104 found=true;
1105 break;
1106 }
1107 ++VerticesIter;
1108
1109 }
1110
1111 if (!found) {
1112 ATH_MSG_WARNING( "Could not find the vertex to delete... Very strange... Check!!! " );
1113 }
1114
1115 //update myJetCandidate with the new vector of tracks
1116 myJetCandidate->setVerticesOnJetAxis(copyOfVerticesAtJetCandidate);
1117
1118 //update the numbering scheme
1119 m_initializationHelper->updateTrackNumbering(myJetCandidate);
1120
1121 }
1122
1124 {
1125
1126 const VertexPositions & newLinVertexPositions=myJetCandidate.getRecVertexPositions();
1127 Amg::VectorX linPositions=newLinVertexPositions.position();
1128
1129 const std::vector<VxVertexOnJetAxis*> & associatedVertices=myJetCandidate.getVerticesOnJetAxis();
1130 const std::vector<VxVertexOnJetAxis*>::const_iterator VtxBegin=associatedVertices.begin();
1131 const std::vector<VxVertexOnJetAxis*>::const_iterator VtxEnd=associatedVertices.end();
1132
1133 for (std::vector<VxVertexOnJetAxis*>::const_iterator VtxIter=VtxBegin;VtxIter!=VtxEnd;++VtxIter) {
1134 VxVertexOnJetAxis* myVertex=(*VtxIter);
1135 if (myVertex!=nullptr) {
1136
1137 double distOnAxis=linPositions[numRow(myVertex->getNumVertex())];
1138
1139 auto const sinLinJetTheta = std::sin(linPositions[Trk::jet_theta]);
1140 auto const cosLinJetTheta = std::cos(linPositions[Trk::jet_theta]);
1141
1142 auto const absLinJetTheta = std::abs(linPositions[Trk::jet_theta]);
1143 auto const abssinLinJetTheta = std::abs(sinLinJetTheta);
1144 auto const abscosLinJetTheta = std::abs(cosLinJetTheta);
1145
1146 double R=distOnAxis*sinLinJetTheta;
1147 double Z=distOnAxis*cosLinJetTheta;
1148 if (std::abs(R)>m_maxR)
1149 {
1150 if (absLinJetTheta>1e-8)
1151 {
1152 ATH_MSG_DEBUG (" Closest distance of track to jet axis is outside ID envelope, R=" << R << ", setting to R= " << m_maxR);
1153 distOnAxis=m_maxR / abssinLinJetTheta;
1154 }
1155 }
1156
1157 Z=distOnAxis*cosLinJetTheta;
1158 if (std::abs(Z)>m_maxZ)
1159 {
1160 if (abscosLinJetTheta>1e-8)
1161 {
1162 ATH_MSG_DEBUG( " Closest distance of track to jet axis is outside ID envelope, Z=" << Z << ", setting to Z= " << m_maxZ );
1163 distOnAxis=m_maxZ / cosLinJetTheta;
1164 }
1165 }
1166
1167 linPositions[numRow(myVertex->getNumVertex())]=distOnAxis;
1168 }
1169 }
1170
1171 VertexPositions & linVertexPositions=myJetCandidate.getLinearizationVertexPositions();
1172 linVertexPositions.setPosition(linPositions);
1173 //now set the linearization position for the next step to the actual fitted vertex
1174 //OLD CODE BEFORE CHECKS
1175 //myJetCandidate->setLinearizationVertexPositions(myJetCandidate->getRecVertexPositions());
1176 }
1177
1178}//end namespace
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
static Double_t a
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
MsgStream & msg() const
void getInitializedCache(MagField::AtlasFieldCache &cache) const
get B field cache for evaluation as a function of 2-d or 3-d position.
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h).
Class to represent and store fit qualities from track reconstruction in terms of and number of degre...
Definition FitQuality.h:97
int numberDoF() const
returns the number of degrees of freedom of the overall track or vertex fit as integer
Definition FitQuality.h:60
double chiSquared() const
returns the of the overall track fit
Definition FitQuality.h:56
ToolHandle< TrkDistanceFinderNeutralNeutral > m_minDistanceFinderNeutral
std::pair< double, bool > fastProbabilityOfMerging(const VxVertexOnJetAxis *, const VxVertexOnJetAxis *, const VxJetCandidate *) const
Calculates in a very fast way the probability two vertices along the jet axis to be compatible with e...
ToolHandle< KalmanVertexOnJetAxisUpdator > m_updator
ToolHandle< TrkDistanceFinderNeutralCharged > m_minDistanceFinder
std::pair< double, bool > fastProbabilityOfMergingWithPrimary(const VxVertexOnJetAxis *otherVertex, const VxJetCandidate *myJetCandidate) const
Internal method to calculate fast probability of merging, for merging with primary vertex.
ToolHandle< KalmanVertexOnJetAxisSmoother > m_smoother
JetFitterRoutines(const std::string &t, const std::string &n, const IInterface *p)
Constructor.
std::pair< double, bool > fastProbabilityOfMergingNoPrimary(const VxVertexOnJetAxis *, const VxVertexOnJetAxis *, const VxJetCandidate *myJetCandidate) const
Internal method to calculate fast probability of merging, for merging with non primary vertex.
void smoothAllVertices(VxJetCandidate *myJetCandidate) const
triggers the smoothing of all vertices (the tracks in the fit are updated using the constraint provid...
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCacheCondObjInputKey
virtual StatusCode initialize() override
void fillTableWithFastProbOfMerging(VxJetCandidate *myJetCandidate) const
The VxClusteringTable of the VxJetCandidate provided in input is created, computing all the needed pr...
void fillTableWithProbOfMerging(VxJetCandidate *myJetCandidate, bool fullcomputation, int num_maxiterations=20, bool treat_sign_flip=true, int num_signflip_maxiterations=10, double deltachi2_convergence=1e-2, double threshold_probability=1e-3) const
Internal method to fill the VxClusteringTable of the VxJetCandidate object, independently on if the f...
void updateAllVertices(VxJetCandidate *myJetCandidate) const
One iteration of the Kalman Updated of all tracks to the actual fit is performed.
~JetFitterRoutines()
Destructor.
bool checkJetCandidate(VxJetCandidate *) const
Internal method to provide a check if the VxJetCandidate has been initialized in a consistent way.
double fullProbabilityOfMerging(const VxVertexOnJetAxis *firstVertex, const VxVertexOnJetAxis *secondVertex, const VxJetCandidate *myJetCandidate, int num_maxiterations=20, bool treat_sign_flip=true, int num_signflip_maxiterations=10, double deltachi2_convergence=1e-2) const
Calculates in a complete way the probability two vertices along the jet axis to be compatible with ea...
void fillTableWithFullProbOfMerging(VxJetCandidate *myJetCandidate, int num_maxiterations=20, bool treat_sign_flip=true, int num_signflip_maxiterations=10, double deltachi2_convergence=1e-3, double threshold_probability=1e-5) const
The VxClusteringTable of the VxJetCandidate provided in input is created, computing all the needed pr...
void initializeToMinDistancesToJetAxis(VxJetCandidate *) const
This method provides the initialization of all the tracks in the fit to the position of minimum dista...
void performTheFit(VxJetCandidate *myJetCandidate, int num_maxiterations=30, bool treat_sign_flip=true, int num_signflip_maxiterations=30, double deltachi2_convergence=0.001) const
This is the method where the fit is actually done.
void deleteVertexFromJetCandidate(VxVertexOnJetAxis *vertexToDelete, VxJetCandidate *myJetCandidate) const
Deltes a vertex from the VxJetCandidate, doing everything is needed to preserve the internal coherenc...
ToolHandle< JetFitterInitializationHelper > m_initializationHelper
void copyRecoPositionsToLinearizationPositions(VxJetCandidate &myJetCandidate) const
Method to copy new reco positions to linearization positions after checking new positions are inside ...
ToolHandle< JetFitterHelper > m_helper
const Amg::Vector3D & momentum() const
Access method for the momentum.
const Amg::Vector3D & position() const
Access method for the position.
Amg::MatrixX const & covariancePosition() const
return the covDeltaV matrix of the vertex fit
const Trk::FitQuality & fitQuality() const
Fit quality access method.
VertexPositions class to represent and store a vertex.
void setPosition(const Amg::VectorX &)
const Amg::VectorX & position() const
return position of vertex
std::vector< Trk::VxTrackAtVertex * > * vxTrackAtVertex(void)
Unconst pointer to the vector of tracks Required by some of the vertex fitters.
void setCompatibilityOfTo(const PairOfVxVertexOnJetAxis &, float)
Set compatibility of a new pair of tracks.
Trk::VxClusteringTable *& getClusteringTable(void)
void setLinearizationVertexPositions(const Trk::VertexPositions &)
const Trk::VertexPositions & getLinearizationVertexPositions() const
void setVerticesOnJetAxis(const std::vector< VxVertexOnJetAxis * > &)
const std::vector< VxVertexOnJetAxis * > & getVerticesOnJetAxis(void) const
const Trk::RecVertexPositions & getConstraintVertexPositions() const
const VxVertexOnJetAxis * getPrimaryVertex(void) const
void setConstraintVertexPositions(const Trk::RecVertexPositions &)
Trk::VxJetFitterDebugInfo *& getDebugInfo(void)
const Trk::RecVertexPositions & getRecVertexPositions() const
void setRecVertexPositions(const Trk::RecVertexPositions &)
The VxTrackAtVertex is a common class for all present TrkVertexFitters The VxTrackAtVertex is designe...
VxVertexOnJetAxis inherits from Vertex.
const Trk::FitQuality & fitQuality() const
Fit quality access method.
int getNumVertex(void) const
Get Method for NumVertex.
const std::vector< VxTrackAtVertex * > & getTracksAtVertex(void) const
get Tracks At Vertex Method
void setCompatibilityToPrimaryVtx(float)
set compatibility to the primary vertex
double chi2(TH1 *h0, TH1 *h1)
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Matrix< double, 3, 1 > Vector3D
Eigen::Matrix< double, Eigen::Dynamic, 1 > VectorX
Dynamic Vector - dynamic allocation.
Ensure that the ATLAS eigen extensions are properly loaded.
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
ParametersT< NeutralParametersDim, Neutral, PerigeeSurface > NeutralPerigee
@ jet_zv
position x,y,z of primary vertex