ATLAS Offline Software
Loading...
Searching...
No Matches
InDetJetFitterVxFinder.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
5/***************************************************************************
6 InDetJetFitterVxFinder.cxx - Description
7 -------------------
8
9 begin : March 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
31#include <TMath.h>
34#include "TrkTrack/Track.h"
38
39
40namespace InDet
41{
42
44 {
45 double first;
46 const Trk::TrackParticleBase* second;
48 : first (p1), second (p2) {}
49 bool operator< (const TrackParticle_pair& other) const
50 { return first > other.first; }
51 };
52
53 struct Track_pair
54 {
55 double first;
56 const Trk::Track* second;
57 Track_pair(double p1, const Trk::Track* p2)
58 : first (p1), second (p2) {}
59 bool operator< (const Track_pair& other) const
60 { return first > other.first; }
61 };
62
63 InDetJetFitterVxFinder::InDetJetFitterVxFinder(const std::string& t, const std::string& n, const IInterface* p) :
64 AthAlgTool(t,n,p)
65 {
66 declareInterface< ISecVertexInJetFinder >(this) ;
67 }
68
69
71
72
74
75 //retrieving the udator itself
76 ATH_CHECK( m_helper.retrieve() );
78 ATH_CHECK( m_routines.retrieve() );
79 ATH_CHECK( m_trkFilter.retrieve() );
80
81 return StatusCode::SUCCESS;
82 }
83
84
86 const TLorentzVector & jetMomentum,
87 const std::vector<const Trk::TrackParticleBase*> & myTracks) const {
88 Amg::Vector3D myDirection(jetMomentum.Vect().X(),jetMomentum.Vect().Y(),jetMomentum.Vect().Z());
89
90 std::vector<TrackParticle_pair> tracks;
91
92 std::vector<const Trk::TrackParticleBase*>::const_iterator tracksBegin=myTracks.begin();
93 std::vector<const Trk::TrackParticleBase*>::const_iterator tracksEnd=myTracks.end();
94 for (std::vector<const Trk::TrackParticleBase*>::const_iterator tracksIter=tracksBegin;
95 tracksIter!=tracksEnd;++tracksIter) {
96 if (m_trkFilter->decision(**tracksIter,&primaryVertex)) {
97 tracks.emplace_back((*tracksIter)->perigee()->momentum().perp(),*tracksIter);
98 }
99 }
100
101 std::vector<std::vector<const Trk::TrackParticleBase*> > bunchesOfTracks;
102
103 std::sort(tracks.begin(),tracks.end());
104
105 std::vector<const Trk::TrackParticleBase*> tracksToAdd;
106
107 std::vector<TrackParticle_pair>::const_iterator tracks2Begin=tracks.begin();
108 std::vector<TrackParticle_pair>::const_iterator tracks2End=tracks.end();
109 for (std::vector<TrackParticle_pair>::const_iterator tracks2Iter=tracks2Begin;
110 tracks2Iter!=tracks2End;++tracks2Iter) {
111 if (msgLvl(MSG::VERBOSE)) msg() << " track: " << (*tracks2Iter).first << " and : " << (*tracks2Iter).second << endmsg;
112
113 tracksToAdd.push_back((*tracks2Iter).second);
114 if (tracksToAdd.size() % m_maxTracksToFitAtOnce == 0) {
115 if (msgLvl(MSG::VERBOSE)) msg() << " new bunch " << endmsg;
116 bunchesOfTracks.push_back(tracksToAdd);
117 tracksToAdd.clear();
118 }
119 }
120
121 bunchesOfTracks.push_back(tracksToAdd);
122
123 std::vector<std::vector<const Trk::TrackParticleBase*> >::const_iterator BunchesBegin=bunchesOfTracks.begin();
124 std::vector<std::vector<const Trk::TrackParticleBase*> >::const_iterator BunchesEnd=bunchesOfTracks.end();
125
126 std::vector<const Trk::TrackParticleBase*>::const_iterator tracksToAddBegin;
127 std::vector<const Trk::TrackParticleBase*>::const_iterator tracksToAddEnd;
128 std::vector<const Trk::TrackParticleBase*>::const_iterator tracksToAddIter;
129
130
131 Trk::VxJetCandidate* myJetCandidate=nullptr;
132
133 for (std::vector<std::vector<const Trk::TrackParticleBase*> >::const_iterator BunchesIter=BunchesBegin;
134 BunchesIter!=BunchesEnd;++BunchesIter) {
135
136 if (BunchesIter==BunchesBegin) {
137 if (msgLvl(MSG::VERBOSE)) msg() << " initial fit with " << (*BunchesIter).size() << " tracks " << endmsg;
138 myJetCandidate=m_initializationHelper->initializeJetCandidate(*BunchesIter,&primaryVertex,&myDirection);
139 m_routines->initializeToMinDistancesToJetAxis(myJetCandidate);
140 doTheFit(myJetCandidate);
141 } else {
142 if (msgLvl(MSG::VERBOSE)) msg() << " other fit with " << (*BunchesIter).size() << " tracks " << endmsg;
143 std::vector<Trk::VxVertexOnJetAxis*> setOfVertices=myJetCandidate->getVerticesOnJetAxis();
144 std::vector<Trk::VxTrackAtVertex*>* setOfTracks=myJetCandidate->vxTrackAtVertex();
145 tracksToAddBegin=(*BunchesIter).begin();
146 tracksToAddEnd=(*BunchesIter).end();
147 for (tracksToAddIter=tracksToAddBegin;tracksToAddIter!=tracksToAddEnd;++tracksToAddIter) {
148 std::vector<Trk::VxTrackAtVertex*> temp_vector_tracksAtVertex;
150 link.setElement(*tracksToAddIter);
152 Trk::VxTrackAtVertex* newVxTrack=new Trk::VxTrackAtVertex(linkTT);
153 temp_vector_tracksAtVertex.push_back(newVxTrack);
154 setOfTracks->push_back(newVxTrack);
155 setOfVertices.push_back(new Trk::VxVertexOnJetAxis(temp_vector_tracksAtVertex));
156 }
157 if (msgLvl(MSG::VERBOSE)) msg() << " new overall number of tracks to fit : " << setOfVertices.size() << endmsg;
158 myJetCandidate->setVerticesOnJetAxis(setOfVertices);
160 doTheFit(myJetCandidate);
161 }
162 }
163
164 std::vector<Trk::VxCandidate*> myCandidates;
165 myCandidates.push_back(myJetCandidate);
166
167// return new Trk::VxSecVertexInfo(myCandidates);//ownership of the single objects is taken over!
168 return nullptr;
169
170 }
171
173 const TLorentzVector & jetMomentum,
174 const std::vector<const Trk::TrackParticleBase*> & firstInputTracks,
175 const std::vector<const Trk::TrackParticleBase*> & secondInputTracks,
176 const Amg::Vector3D & vtxSeedDirection) const
177 {
178
179 Amg::Vector3D myDirection(jetMomentum.Vect().X(),jetMomentum.Vect().Y(),jetMomentum.Vect().Z());
180
181 std::vector<std::vector<const Trk::TrackParticleBase*> > bunchesOfTracks;
182
183 std::vector<const Trk::TrackParticleBase*> tracksToAdd;
184
185 std::vector<const Trk::TrackParticleBase*>::const_iterator tracks2Begin=firstInputTracks.begin();
186 std::vector<const Trk::TrackParticleBase*>::const_iterator tracks2End=firstInputTracks.end();
187 for (std::vector<const Trk::TrackParticleBase*>::const_iterator tracks2Iter=tracks2Begin;
188 tracks2Iter!=tracks2End;++tracks2Iter) {
189 if (msgLvl(MSG::VERBOSE)) msg() << " adding track to fit " << endmsg;
190 tracksToAdd.push_back(*tracks2Iter);
191 }
192
193 bunchesOfTracks.push_back(tracksToAdd);
194 tracksToAdd.clear();
195
196 std::vector<const Trk::TrackParticleBase*>::const_iterator tracks3Begin=secondInputTracks.begin();
197 std::vector<const Trk::TrackParticleBase*>::const_iterator tracks3End=secondInputTracks.end();
198 for (std::vector<const Trk::TrackParticleBase*>::const_iterator tracks3Iter=tracks3Begin;
199 tracks3Iter!=tracks3End;++tracks3Iter) {
200 if (msgLvl(MSG::VERBOSE)) msg() << " adding track to fit " << endmsg;
201 tracksToAdd.push_back(*tracks3Iter);
202 }
203
204 if (!tracksToAdd.empty())
205 {
206 bunchesOfTracks.push_back(tracksToAdd);
207 }
208 tracksToAdd.clear();
209
210
211 //now it just uses these bunches...
212 //now I have just to make sure that no clustering is done at first iteration
213 //while it needs to be done at second iteration (there will be only two iterations)
214
215
216 std::vector<std::vector<const Trk::TrackParticleBase*> >::const_iterator BunchesBegin=bunchesOfTracks.begin();
217 std::vector<std::vector<const Trk::TrackParticleBase*> >::const_iterator BunchesEnd=bunchesOfTracks.end();
218
219 std::vector<const Trk::TrackParticleBase*>::const_iterator tracksToAddBegin;
220 std::vector<const Trk::TrackParticleBase*>::const_iterator tracksToAddEnd;
221 std::vector<const Trk::TrackParticleBase*>::const_iterator tracksToAddIter;
222
223
224 Trk::VxJetCandidate* myJetCandidate=nullptr;
225
226 for (std::vector<std::vector<const Trk::TrackParticleBase*> >::const_iterator BunchesIter=BunchesBegin;
227 BunchesIter!=BunchesEnd;++BunchesIter) {
228
229 if (BunchesIter==BunchesBegin) {
230 if (msgLvl(MSG::VERBOSE)) msg() << " initial fit with " << (*BunchesIter).size() << " tracks " << endmsg;
231 myJetCandidate=m_initializationHelper->initializeJetCandidate(*BunchesIter,&primaryVertex,&myDirection,&vtxSeedDirection);
232 m_routines->initializeToMinDistancesToJetAxis(myJetCandidate);
233 if (!(*BunchesIter).empty())
234 {
235 doTheFit(myJetCandidate,true);
236 }
237 } else {
238 if (msgLvl(MSG::VERBOSE)) msg() << " other fit with " << (*BunchesIter).size() << " tracks " << endmsg;
239 std::vector<Trk::VxVertexOnJetAxis*> setOfVertices=myJetCandidate->getVerticesOnJetAxis();
240 std::vector<Trk::VxTrackAtVertex*>* setOfTracks=myJetCandidate->vxTrackAtVertex();
241 tracksToAddBegin=(*BunchesIter).begin();
242 tracksToAddEnd=(*BunchesIter).end();
243 for (tracksToAddIter=tracksToAddBegin;tracksToAddIter!=tracksToAddEnd;++tracksToAddIter) {
244 std::vector<Trk::VxTrackAtVertex*> temp_vector_tracksAtVertex;
246 link.setElement(*tracksToAddIter);
248 Trk::VxTrackAtVertex* newVxTrack=new Trk::VxTrackAtVertex(linkTT);
249 temp_vector_tracksAtVertex.push_back(newVxTrack);
250 setOfTracks->push_back(newVxTrack);
251 setOfVertices.push_back(new Trk::VxVertexOnJetAxis(temp_vector_tracksAtVertex));
252 }
253 if (msgLvl(MSG::VERBOSE)) msg() << " new overall number of tracks to fit : " << setOfVertices.size() << endmsg;
254 myJetCandidate->setVerticesOnJetAxis(setOfVertices);
256 m_routines->initializeToMinDistancesToJetAxis(myJetCandidate);
257 doTheFit(myJetCandidate);
258 }
259 }
260
261 std::vector<Trk::VxCandidate*> myCandidates;
262 myCandidates.push_back(myJetCandidate);
263
264// return new Trk::VxSecVertexInfo(myCandidates);//ownership of the single objects is taken over!
265 return nullptr;
266
267 }
268
270 bool performClustering) const {
271
272
273 int numClusteringLoops=0;
274 bool noMoreVerticesToCluster(false);
275
276 do {//reguards clustering
277
278 if (msgLvl(MSG::VERBOSE)) msg() << "InDetJetFitterVxFinder: ------>>>> new cycle of fit" << endmsg;
279
280 int numLoops=0;
281 bool noMoreTracksToDelete(false);
282 do {//reguards eliminating incompatible tracks...
283
284 m_routines->performTheFit(myJetCandidate,10,false,30,0.001);
285
286 const std::vector<Trk::VxVertexOnJetAxis*> & vertices=myJetCandidate->getVerticesOnJetAxis();
287
288 std::vector<Trk::VxVertexOnJetAxis*>::const_iterator verticesBegin=vertices.begin();
289 std::vector<Trk::VxVertexOnJetAxis*>::const_iterator verticesEnd=vertices.end();
290
291
292 //delete incompatible tracks...
293 float max_prob(1.);
294 Trk::VxVertexOnJetAxis* worseVertex(nullptr);
295 for (std::vector<Trk::VxVertexOnJetAxis*>::const_iterator verticesIter=verticesBegin;
296 verticesIter!=verticesEnd;++verticesIter) {
297 if (*verticesIter==nullptr) {
298 if (msgLvl(MSG::WARNING)) msg() << "One vertex is empy. Problem when trying to delete incompatible vertices. No further vertices deleted." << endmsg;
299 } else {
300 const Trk::FitQuality & fitQuality=(*verticesIter)->fitQuality();
301 if (TMath::Prob(fitQuality.chiSquared(),(int)std::floor(fitQuality.numberDoF()+0.5))<max_prob) {
302 max_prob=TMath::Prob(fitQuality.chiSquared(),(int)std::floor(fitQuality.numberDoF()+0.5));
303 worseVertex=*verticesIter;
304 }
305 }
306 }
307 if (max_prob<m_vertexProbCut) {
308 if (msgLvl(MSG::DEBUG)) msg() << "Deleted vertex " << worseVertex->getNumVertex() << " with probability " << max_prob << endmsg;
309 // std::cout << "Deleted vertex " << worseVertex->getNumVertex() << " with probability " << max_prob << std::endl;
310 if (worseVertex==myJetCandidate->getPrimaryVertex()) {
311 if (msgLvl(MSG::INFO)) msg() << " The most incompatible vertex is the primary vertex. Please check..." << endmsg;
312 }
313
314 m_routines->deleteVertexFromJetCandidate(worseVertex,myJetCandidate);
315
316 } else {
317 noMoreTracksToDelete=true;
318 if (msgLvl(MSG::VERBOSE)) msg() << "No tracks to delete: maximum probability is " << max_prob << endmsg;
319 }
320
321 numLoops+=1;
322 } while (numLoops<m_maxNumDeleteIterations&&!(noMoreTracksToDelete));
323
324 if (!performClustering) break;
325
326 if (!m_useFastClustering) {
327 m_routines->fillTableWithFullProbOfMerging(myJetCandidate,5,false,10,0.01);
328 } else {
329 m_routines->fillTableWithFastProbOfMerging(myJetCandidate);
330 }
331 const Trk::VxClusteringTable* clusteringTablePtr(myJetCandidate->getClusteringTable());
332
333
334
335
336 if (clusteringTablePtr==nullptr) {
337 if (msgLvl(MSG::WARNING)) msg() << " No Clustering Table while it should have been calculated... no more clustering performed during vertexing " << endmsg;
338 noMoreVerticesToCluster=true;
339 } else {
340
341 if (msgLvl(MSG::VERBOSE)) msg() << " clustering table is " << *clusteringTablePtr << endmsg;
342
343 //now iterate over the full map and decide wether you want to do the clustering OR not...
344 float probVertex(0.);
345 Trk::PairOfVxVertexOnJetAxis pairOfVxVertexOnJetAxis=clusteringTablePtr->getMostCompatibleVertices(probVertex);
346 //a PairOfVxVertexOnJetAxis is a std::pair<VxVertexOnJetAxis*,VxVertexOnJetAxis*>
347
348 if (probVertex>0.&&probVertex>m_vertexClusteringProbabilityCut) {
349 if (msgLvl(MSG::VERBOSE)) msg() << " merging vtx number " << (*pairOfVxVertexOnJetAxis.first).getNumVertex() <<
350 " and " << (*pairOfVxVertexOnJetAxis.second).getNumVertex() << endmsg;
351 // const Trk::VxVertexOnJetAxis & mergedVertex=
352 m_helper->mergeVerticesInJetCandidate(*pairOfVxVertexOnJetAxis.first,
353 *pairOfVxVertexOnJetAxis.second,
354 *myJetCandidate);
355 //now you need to update the numbering scheme
356 Trk::JetFitterInitializationHelper::updateTrackNumbering(myJetCandidate);//maybe this should be moved to a lower level...
357
358 } else {
359 noMoreVerticesToCluster=true;
360 }
361 }
362 numClusteringLoops+=1;
363 } while (numClusteringLoops<m_maxClusteringIterations&&!(noMoreVerticesToCluster));
364
365 //now a section should follow where the "complicate" VxJetCandidate is transformed in a conventional "VxCandidate"
366 //so that it can be used also by the normal B-Tagging algorithms...
367 //TO BE COMPLETED
368
369 //return myJetCandidate;
370
371 }
372
373
374}//end namespace Rec
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
bool msgLvl(const MSG::Level lvl) const
MsgStream & msg() const
void doTheFit(Trk::VxJetCandidate *myJetCandidate, bool performClustering=true) const
Gaudi::Property< float > m_vertexClusteringProbabilityCut
virtual Trk::VxSecVertexInfo * findSecVertex(const xAOD::Vertex &, const TLorentzVector &, const std::vector< const xAOD::IParticle * > &) const override
Gaudi::Property< int > m_maxClusteringIterations
ToolHandle< Trk::JetFitterInitializationHelper > m_initializationHelper
ToolHandle< Trk::ITrackSelectorTool > m_trkFilter
Gaudi::Property< float > m_vertexProbCut
ToolHandle< Trk::JetFitterRoutines > m_routines
InDetJetFitterVxFinder(const std::string &t, const std::string &n, const IInterface *p)
ToolHandle< Trk::JetFitterHelper > m_helper
Gaudi::Property< int > m_maxNumDeleteIterations
Gaudi::Property< bool > m_useFastClustering
Gaudi::Property< int > m_maxTracksToFitAtOnce
virtual StatusCode initialize() override
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
Class to represent and store fit qualities from track reconstruction in terms of and number of degre...
Definition FitQuality.h:97
static void updateTrackNumbering(VxJetCandidate *)
Does the update of the ordering of the vertices along the jetaxis.
Trk::RecVertex inherits from Trk::Vertex.
Definition RecVertex.h:44
std::vector< Trk::VxTrackAtVertex * > * vxTrackAtVertex(void)
Unconst pointer to the vector of tracks Required by some of the vertex fitters.
PairOfVxVertexOnJetAxis getMostCompatibleVertices(float &probability) const
Get pair of tracks with highest compatibility.
Trk::VxClusteringTable *& getClusteringTable(void)
void setVerticesOnJetAxis(const std::vector< VxVertexOnJetAxis * > &)
const std::vector< VxVertexOnJetAxis * > & getVerticesOnJetAxis(void) const
const VxVertexOnJetAxis * getPrimaryVertex(void) const
The VxTrackAtVertex is a common class for all present TrkVertexFitters The VxTrackAtVertex is designe...
VxVertexOnJetAxis inherits from Vertex.
int getNumVertex(void) const
Get Method for NumVertex.
Eigen::Matrix< double, 3, 1 > Vector3D
Primary Vertex Finder.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
bool operator<(const TrackParticle_pair &other) const
const Trk::TrackParticleBase * second
TrackParticle_pair(double p1, const Trk::TrackParticleBase *p2)
bool operator<(const Track_pair &other) const
Track_pair(double p1, const Trk::Track *p2)