ATLAS Offline Software
Loading...
Searching...
No Matches
InDetJetFitterVxFinder.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 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(std::move(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 std::unique_ptr<Trk::VxJetCandidate> myJetCandidate;
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.reset(m_initializationHelper->initializeJetCandidate(*BunchesIter,&primaryVertex,&myDirection));
139 m_routines->initializeToMinDistancesToJetAxis(myJetCandidate.get());
140 doTheFit(myJetCandidate.get());
141 } else if (myJetCandidate){
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(std::move(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.get());
161 }
162 }
163
164 std::vector<Trk::VxCandidate*> myCandidates;
165 myCandidates.push_back(myJetCandidate.get());
166 //this function has no useful output?
167 return nullptr;
168
169 }
170
172 const TLorentzVector & jetMomentum,
173 const std::vector<const Trk::TrackParticleBase*> & firstInputTracks,
174 const std::vector<const Trk::TrackParticleBase*> & secondInputTracks,
175 const Amg::Vector3D & vtxSeedDirection) const
176 {
177
178 Amg::Vector3D myDirection(jetMomentum.Vect().X(),jetMomentum.Vect().Y(),jetMomentum.Vect().Z());
179
180 std::vector<std::vector<const Trk::TrackParticleBase*> > bunchesOfTracks;
181
182 std::vector<const Trk::TrackParticleBase*> tracksToAdd;
183
184 std::vector<const Trk::TrackParticleBase*>::const_iterator tracks2Begin=firstInputTracks.begin();
185 std::vector<const Trk::TrackParticleBase*>::const_iterator tracks2End=firstInputTracks.end();
186 for (std::vector<const Trk::TrackParticleBase*>::const_iterator tracks2Iter=tracks2Begin;
187 tracks2Iter!=tracks2End;++tracks2Iter) {
188 if (msgLvl(MSG::VERBOSE)) msg() << " adding track to fit " << endmsg;
189 tracksToAdd.push_back(*tracks2Iter);
190 }
191
192 bunchesOfTracks.push_back(tracksToAdd);
193 tracksToAdd.clear();
194
195 std::vector<const Trk::TrackParticleBase*>::const_iterator tracks3Begin=secondInputTracks.begin();
196 std::vector<const Trk::TrackParticleBase*>::const_iterator tracks3End=secondInputTracks.end();
197 for (std::vector<const Trk::TrackParticleBase*>::const_iterator tracks3Iter=tracks3Begin;
198 tracks3Iter!=tracks3End;++tracks3Iter) {
199 if (msgLvl(MSG::VERBOSE)) msg() << " adding track to fit " << endmsg;
200 tracksToAdd.push_back(*tracks3Iter);
201 }
202
203 if (!tracksToAdd.empty())
204 {
205 bunchesOfTracks.push_back(tracksToAdd);
206 }
207 tracksToAdd.clear();
208
209
210 //now it just uses these bunches...
211 //now I have just to make sure that no clustering is done at first iteration
212 //while it needs to be done at second iteration (there will be only two iterations)
213
214
215 std::vector<std::vector<const Trk::TrackParticleBase*> >::const_iterator BunchesBegin=bunchesOfTracks.begin();
216 std::vector<std::vector<const Trk::TrackParticleBase*> >::const_iterator BunchesEnd=bunchesOfTracks.end();
217
218 std::vector<const Trk::TrackParticleBase*>::const_iterator tracksToAddBegin;
219 std::vector<const Trk::TrackParticleBase*>::const_iterator tracksToAddEnd;
220 std::vector<const Trk::TrackParticleBase*>::const_iterator tracksToAddIter;
221
222
223 std::unique_ptr<Trk::VxJetCandidate> myJetCandidate;
224
225 for (std::vector<std::vector<const Trk::TrackParticleBase*> >::const_iterator BunchesIter=BunchesBegin;
226 BunchesIter!=BunchesEnd;++BunchesIter) {
227
228 if (BunchesIter==BunchesBegin) {
229 if (msgLvl(MSG::VERBOSE)) msg() << " initial fit with " << (*BunchesIter).size() << " tracks " << endmsg;
230 myJetCandidate.reset(m_initializationHelper->initializeJetCandidate(*BunchesIter,&primaryVertex,&myDirection,&vtxSeedDirection));
231 m_routines->initializeToMinDistancesToJetAxis(myJetCandidate.get());
232 if (!(*BunchesIter).empty())
233 {
234 doTheFit(myJetCandidate.get(),true); //will not delete myJetCandidate
235 }
236 } else if (myJetCandidate){
237 if (msgLvl(MSG::VERBOSE)) msg() << " other fit with " << (*BunchesIter).size() << " tracks " << endmsg;
238 std::vector<Trk::VxVertexOnJetAxis*> setOfVertices=myJetCandidate->getVerticesOnJetAxis();
239 std::vector<Trk::VxTrackAtVertex*>* setOfTracks=myJetCandidate->vxTrackAtVertex();
240 tracksToAddBegin=(*BunchesIter).begin();
241 tracksToAddEnd=(*BunchesIter).end();
242 for (tracksToAddIter=tracksToAddBegin;tracksToAddIter!=tracksToAddEnd;++tracksToAddIter) {
243 std::vector<Trk::VxTrackAtVertex*> temp_vector_tracksAtVertex;
245 link.setElement(*tracksToAddIter);
247 Trk::VxTrackAtVertex* newVxTrack=new Trk::VxTrackAtVertex(linkTT);
248 temp_vector_tracksAtVertex.push_back(newVxTrack);
249 setOfTracks->push_back(newVxTrack);
250 setOfVertices.push_back(new Trk::VxVertexOnJetAxis(std::move(temp_vector_tracksAtVertex)));
251 }
252 if (msgLvl(MSG::VERBOSE)) msg() << " new overall number of tracks to fit : " << setOfVertices.size() << endmsg;
253 myJetCandidate->setVerticesOnJetAxis(setOfVertices);
255 m_routines->initializeToMinDistancesToJetAxis(myJetCandidate.get());
256 doTheFit(myJetCandidate.get());
257 }
258 }
259
260 std::vector<Trk::VxCandidate*> myCandidates;
261 myCandidates.push_back(myJetCandidate.release());//pass ownership to myCandidates
262 //this function, finally, has no useful output?
263 return nullptr;
264
265 }
266
268 bool performClustering) const {
269
270
271 int numClusteringLoops=0;
272 bool noMoreVerticesToCluster(false);
273
274 do {//reguards clustering
275
276 if (msgLvl(MSG::VERBOSE)) msg() << "InDetJetFitterVxFinder: ------>>>> new cycle of fit" << endmsg;
277
278 int numLoops=0;
279 bool noMoreTracksToDelete(false);
280 do {//reguards eliminating incompatible tracks...
281
282 m_routines->performTheFit(myJetCandidate,10,false,30,0.001);
283
284 const std::vector<Trk::VxVertexOnJetAxis*> & vertices=myJetCandidate->getVerticesOnJetAxis();
285
286 std::vector<Trk::VxVertexOnJetAxis*>::const_iterator verticesBegin=vertices.begin();
287 std::vector<Trk::VxVertexOnJetAxis*>::const_iterator verticesEnd=vertices.end();
288
289
290 //delete incompatible tracks...
291 float max_prob(1.);
292 Trk::VxVertexOnJetAxis* worseVertex(nullptr);
293 for (std::vector<Trk::VxVertexOnJetAxis*>::const_iterator verticesIter=verticesBegin;
294 verticesIter!=verticesEnd;++verticesIter) {
295 if (*verticesIter==nullptr) {
296 if (msgLvl(MSG::WARNING)) msg() << "One vertex is empy. Problem when trying to delete incompatible vertices. No further vertices deleted." << endmsg;
297 } else {
298 const Trk::FitQuality & fitQuality=(*verticesIter)->fitQuality();
299 if (TMath::Prob(fitQuality.chiSquared(),(int)std::floor(fitQuality.numberDoF()+0.5))<max_prob) {
300 max_prob=TMath::Prob(fitQuality.chiSquared(),(int)std::floor(fitQuality.numberDoF()+0.5));
301 worseVertex=*verticesIter;
302 }
303 }
304 }
305 if ((max_prob<m_vertexProbCut) && worseVertex) {
306 if (msgLvl(MSG::DEBUG)) msg() << "Deleted vertex " << worseVertex->getNumVertex() << " with probability " << max_prob << endmsg;
307 if (worseVertex==myJetCandidate->getPrimaryVertex()) {
308 if (msgLvl(MSG::INFO)) msg() << " The most incompatible vertex is the primary vertex. Please check..." << endmsg;
309 }
310
311 m_routines->deleteVertexFromJetCandidate(worseVertex,myJetCandidate);
312
313 } else {
314 noMoreTracksToDelete=true;
315 if (msgLvl(MSG::VERBOSE)) msg() << "No tracks to delete: maximum probability is " << max_prob << endmsg;
316 }
317
318 numLoops+=1;
319 } while (numLoops<m_maxNumDeleteIterations&&!(noMoreTracksToDelete));
320
321 if (!performClustering) break;
322
323 if (!m_useFastClustering) {
324 m_routines->fillTableWithFullProbOfMerging(myJetCandidate,5,false,10,0.01);
325 } else {
326 m_routines->fillTableWithFastProbOfMerging(myJetCandidate);
327 }
328 const Trk::VxClusteringTable* clusteringTablePtr(myJetCandidate->getClusteringTable());
329
330
331
332
333 if (clusteringTablePtr==nullptr) {
334 if (msgLvl(MSG::WARNING)) msg() << " No Clustering Table while it should have been calculated... no more clustering performed during vertexing " << endmsg;
335 noMoreVerticesToCluster=true;
336 } else {
337
338 if (msgLvl(MSG::VERBOSE)) msg() << " clustering table is " << *clusteringTablePtr << endmsg;
339
340 //now iterate over the full map and decide wether you want to do the clustering OR not...
341 float probVertex(0.);
342 Trk::PairOfVxVertexOnJetAxis pairOfVxVertexOnJetAxis=clusteringTablePtr->getMostCompatibleVertices(probVertex);
343 //a PairOfVxVertexOnJetAxis is a std::pair<VxVertexOnJetAxis*,VxVertexOnJetAxis*>
344
345 if (probVertex>0.&&probVertex>m_vertexClusteringProbabilityCut) {
346 if (msgLvl(MSG::VERBOSE)) msg() << " merging vtx number " << (*pairOfVxVertexOnJetAxis.first).getNumVertex() <<
347 " and " << (*pairOfVxVertexOnJetAxis.second).getNumVertex() << endmsg;
348 // const Trk::VxVertexOnJetAxis & mergedVertex=
349 m_helper->mergeVerticesInJetCandidate(*pairOfVxVertexOnJetAxis.first,
350 *pairOfVxVertexOnJetAxis.second,
351 *myJetCandidate);
352 //now you need to update the numbering scheme
353 Trk::JetFitterInitializationHelper::updateTrackNumbering(myJetCandidate);//maybe this should be moved to a lower level...
354
355 } else {
356 noMoreVerticesToCluster=true;
357 }
358 }
359 numClusteringLoops+=1;
360 } while (numClusteringLoops<m_maxClusteringIterations&&!(noMoreVerticesToCluster));
361
362 //now a section should follow where the "complicate" VxJetCandidate is transformed in a conventional "VxCandidate"
363 //so that it can be used also by the normal B-Tagging algorithms...
364 //TO BE COMPLETED
365
366 //return myJetCandidate;
367
368 }
369
370
371}//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
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
virtual Trk::VxSecVertexInfo * findSecVertex(const EventContext &, const xAOD::Vertex &, const TLorentzVector &, const std::vector< const xAOD::IParticle * > &) const override
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
PairOfVxVertexOnJetAxis getMostCompatibleVertices(float &probability) const
Get pair of tracks with highest compatibility.
Trk::VxClusteringTable *& getClusteringTable(void)
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)