ATLAS Offline Software
DivisiveMultiSeedFinder.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 #include "TrkTrack/Track.h"
13 #include "xAODTracking/Vertex.h"
15 
16 namespace InDet
17 {
18 
20  {
21 
22  if(m_trkFilter.retrieve().isFailure())
23  {
24  ATH_MSG_ERROR("Unable to retrieve "<<m_trkFilter);
25  return StatusCode::FAILURE;
26  }
27 
28  if(m_sortingTool.retrieve().isFailure())
29  {
30  ATH_MSG_ERROR("Unable to retrieve "<<m_sortingTool);
31  return StatusCode::FAILURE;
32  }
33 
34  if(m_vtxSeedFinder.retrieve().isFailure())
35  {
36  ATH_MSG_ERROR("Unable to retrieve " << m_vtxSeedFinder);
37  return StatusCode::FAILURE;
38  }
39 
40  if(m_cleaningTool.retrieve().isFailure())
41  {
42  ATH_MSG_ERROR("Unable to retrieve "<<m_cleaningTool);
43  return StatusCode::FAILURE;
44  }
45 
47 
48  if ( m_extrapolator.retrieve().isFailure() )
49  {
50  ATH_MSG_ERROR("Failed to retrieve tool " << m_extrapolator);
51  return StatusCode::FAILURE;
52  }
53 
54  return StatusCode::SUCCESS;
55  }//end of initialize method
56 
57 
58  DivisiveMultiSeedFinder::DivisiveMultiSeedFinder(const std::string& t, const std::string& n, const
59  IInterface*p):AthAlgTool(t,n,p),
60  m_sepDistance(0.5),
61  m_nRemaining(1),
62  m_ignoreBeamSpot(false),
63  m_extrapolator("Trk::Extrapolator"),
64  m_vtxSeedFinder("Trk::CrossDistancesSeedFinder")
65  {
66  declareInterface<IMultiPVSeedFinder>(this);
67  declareProperty("separationDistance", m_sepDistance);
68  declareProperty("nRemainTracks", m_nRemaining);
69  declareProperty("IgnoreBeamSpot", m_ignoreBeamSpot);
70 
71  //track filter
72  declareProperty("TrackSelector",m_trkFilter);
73 
74  //sorting tool
75  declareProperty("SortingTool", m_sortingTool);
76 
77  //cleaning tool
78  declareProperty("CleaningTool", m_cleaningTool);
79 
80  //vertex finder tool (needed when no beam spot is available)
81  declareProperty("VertexSeedFinder",m_vtxSeedFinder);
82 
83  //extrapolator
84  declareProperty("Extrapolator",m_extrapolator);
85 
86  }//end of constructor
87 
89  = default;
90 
91  std::vector< std::vector<const Trk::Track *> > DivisiveMultiSeedFinder::seeds(const std::vector<const Trk::Track*>& tracks )const
92  {
93  const EventContext& ctx = Gaudi::Hive::currentContext();
94 
95  //step 1: preselection
96  std::vector<const Trk::Track*> preselectedTracks(0);
97  std::vector<const Trk::Track*>::const_iterator tr = tracks.begin();
98  std::vector<const Trk::Track*>::const_iterator tre = tracks.end();
99 
101  Trk::RecVertex beamrecposition(beamSpotHandle->beamVtx());
102  for(;tr!=tre;++tr) if(m_trkFilter->decision(**tr,&beamrecposition)) preselectedTracks.push_back(*tr);
103  ATH_MSG_DEBUG("Beam spot position is: "<< beamrecposition.position());
104  Trk::Vertex* beamposition=&beamrecposition;
105 
106  Trk::Vertex myVertex;
107  if (m_ignoreBeamSpot)
108  {
109  myVertex = Trk::Vertex(m_vtxSeedFinder->findSeed(tracks));
110  ATH_MSG_DEBUG(" vtx seed x: " << myVertex.position().x() <<
111  " vtx seed y: " << myVertex.position().y() <<
112  " vtx seed z: " << myVertex.position().z());
113  beamposition = &myVertex;
114  }
115 
116  //step 2: sorting in z0
117  //output container
118  std::vector< std::vector<const Trk::Track *> > result(0);
119  if(!preselectedTracks.empty())
120  {
121  std::vector<int> indexOfSorted = m_sortingTool->sortedIndex(preselectedTracks, beamposition);
122 
123  //step 3 preclustering
124  std::vector< std::vector<const Trk::Track *> > preClusters(0);
125 
126  //left-handed track position
127  std::vector<const Trk::Track *> tmp_cluster(0);
128 
129  Trk::PerigeeSurface perigeeSurface(beamposition->position());
130 
131  const Trk::TrackParameters* exPerigee =
133  ->extrapolateTrack(ctx, *preselectedTracks[indexOfSorted[0]], perigeeSurface, Trk::anyDirection, true, Trk::pion)
134  .release();
135 
136  double lastTrackZ0 = -999.;
137  if(exPerigee) { lastTrackZ0 = exPerigee->parameters()[Trk::z0]; delete exPerigee; }
138  else
139  {
140  ATH_MSG_WARNING("Impossible to extrapolate the first track; returning 0 container for this event");
141  return result;
142  }
143 
144  //looping over container
145  for(int i : indexOfSorted)
146  {
147  const Trk::TrackParameters* lexPerigee =
149  ->extrapolateTrack(ctx, *preselectedTracks[i], perigeeSurface, Trk::anyDirection, true, Trk::pion)
150  .release();
151 
152  double currentTrackZ0 = lexPerigee->parameters()[Trk::z0];
153  delete lexPerigee;
154 
155  if (std::fabs(currentTrackZ0 - lastTrackZ0) < m_sepDistance) {
156  // the distance is below separation, adding to the same cluster
157  tmp_cluster.push_back(preselectedTracks[i]);
158  }else{
159  //the distance is above separation, starting new cluster
160  preClusters.push_back(tmp_cluster);
161  tmp_cluster.clear();
162  tmp_cluster.push_back(preselectedTracks[i]);
163  }//end of gap size check
164  lastTrackZ0 = currentTrackZ0;
165  }//end of loop over the sorted container
166 
167  //storing the last (or the only cluster)
168  preClusters.push_back(tmp_cluster);
169 
170  //step 4 iterative cleaning of clusters
171  for(const auto & preCluster : preClusters)
172  {
173  //------------------------------Debug code -------------------------------------------------------
174  /* std::vector<const Trk::Track *>::const_iterator cb = i->begin();
175  std::vector<const Trk::Track *>::const_iterator ce = i->end();
176  std::cout<<"*********Starting next cluster of size "<<i->size()<<std::endl;
177  for(;cb!=ce;++cb)
178  {
179  std::cout<<"Track Z0 in cluster: "<<(*cb)->perigeeParameters()->parameters()[Trk::z0]<<std::endl;
180  }//end of loop over the cluster entries
181  */
182  //-------------------------------end of debug code-------------------------------------------------
183 
184  if(preCluster.size()>m_nRemaining){
185  //iterative cleaning until outlying tracks remain
186  std::vector<const Trk::Track *> tracks_to_clean = preCluster;
187  bool clean_again = false;
188  do {
189  std::pair<std::vector<const Trk::Track *>, std::vector<const Trk::Track *> > clusterAndOutl =
190  m_cleaningTool->clusterAndOutliers(tracks_to_clean, beamposition);
191 
192  //if core size is miningfull, storing it
193  std::vector<const Trk::Track *> core_cluster = clusterAndOutl.first;
194  std::vector<const Trk::Track *> core_outl = clusterAndOutl.second;
195 
196  //--------------Debug output-----------------------------------------------------
197  // std::cout<<"Cleaning iteration "<<clean_count<<std::endl;
198  // std::cout<<"Reduced cluster size: "<<core_cluster.size()<<std::endl;
199  // std::cout<<"Outliers size: "<<core_outl.size()<<std::endl;
200  // ++clean_count;
201  //-------------------End of debug output -----------------------------------------
202 
203  if(core_cluster.empty()){
204  ATH_MSG_DEBUG("Core cluster has 0 size, remaining tracks are discarded.");
205  clean_again = false;
206  }else{
207  //storing clusters with >1 track (optional)
208  if(core_cluster.size()>1) result.push_back(core_cluster);
209 
210  //checking the outliers, whether more cleaning is to be done
211  if(core_outl.size()>m_nRemaining){
212  clean_again = true;
213  tracks_to_clean.clear();
214  tracks_to_clean = core_outl;
215  }else if(core_outl.size()>1){
216  clean_again = false;
217  ATH_MSG_DEBUG("There were remaining outliers of size: "<< core_outl.size());
218  ATH_MSG_DEBUG("Not evident, whether these tracks form a cluster. Rejected...");
219  }else clean_again = false;//end of outlier size check
220  }//end of core cluster 0 check
221 
222  }while(clean_again);//end of loop
223 
224  }else if(preCluster.size()==2){
225  //case of two track cluster. accepting without cleaning
226  result.push_back(preCluster);
227  }//end of cluster size check
228  }//end of loop over all the clusters
229  }//end of preselection size check
230 
231  return result;
232  }//end of clustering method
233 
234  std::vector< std::vector<const Trk::TrackParameters *> > DivisiveMultiSeedFinder::seeds(const std::vector<const xAOD::TrackParticle*>& tracks )const
235  {
236  const EventContext& ctx = Gaudi::Hive::currentContext();
237 
238  //step 1: preselection
239  std::vector<const xAOD::TrackParticle*> preselectedTracks(0);
240 
241  //selecting with respect to the beam spot
242  xAOD::Vertex beamposition;
244  beamposition.setPosition(beamSpotHandle->beamVtx().position());
245  beamposition.setCovariancePosition(beamSpotHandle->beamVtx().covariancePosition());
246 
247  for (const auto *track : tracks) {
248  if (m_trkFilter->decision(*track,&beamposition)) preselectedTracks.push_back(track);
249  }
250 
251  std::vector<const Trk::TrackParameters*> perigeeList;
252  std::vector<const xAOD::TrackParticle*>::const_iterator trackBegin=tracks.begin();
253  std::vector<const xAOD::TrackParticle*>::const_iterator trackEnd=tracks.end();
254  for (std::vector<const xAOD::TrackParticle*>::const_iterator trackIter=trackBegin;trackIter!=trackEnd;++trackIter){
255  perigeeList.push_back(&((*trackIter)->perigeeParameters()));
256  }
257 
258  Trk::RecVertex myVertex (m_vtxSeedFinder->findSeed(perigeeList));
259 
260  if (m_ignoreBeamSpot) {
261  ATH_MSG_DEBUG(" vtx seed x: " << myVertex.position().x() <<
262  " vtx seed y: " << myVertex.position().y() <<
263  " vtx seed z: " << myVertex.position().z());
264  beamposition.setPosition(myVertex.position());
265  beamposition.setCovariancePosition(myVertex.covariancePosition());
266  }
267 
268  //step 2: sorting in z0
269  //output container
270  std::vector< std::vector<const Trk::TrackParameters *> > result(0);
271  if(!preselectedTracks.empty()){
272  std::vector<int> indexOfSorted = m_sortingTool->sortedIndex(preselectedTracks, &beamposition);
273 
274  //need new sort method, either for xAODTrackParticles, or TrackParameters. Neither currently supported...
275 
276  //step 3 preclustering
277  std::vector< std::vector<const xAOD::TrackParticle *> > preClusters(0);
278 
279  //left-handed track position
280  std::vector<const xAOD::TrackParticle *> tmp_cluster(0);
281 
282  Trk::PerigeeSurface perigeeSurface(beamposition.position());
283  const Trk::TrackParameters* exPerigee =
285  ->extrapolate(ctx, preselectedTracks[indexOfSorted[0]]->perigeeParameters(),
286  perigeeSurface, Trk::anyDirection, true, Trk::pion)
287  .release();
288 
289  double lastTrackZ0 = -999.;
290  if(exPerigee){
291  lastTrackZ0 = exPerigee->parameters()[Trk::z0];delete exPerigee;
292  }
293  else{
294  ATH_MSG_WARNING("Impossible to extrapolate the first track; returning 0 container for this event");
295  return result;
296  }
297 
298  //looping over container
299  for(int i : indexOfSorted){
300  const Trk::TrackParameters* lexPerigee =
301  m_extrapolator->extrapolate(ctx, preselectedTracks[i]->perigeeParameters(),
302  perigeeSurface, Trk::anyDirection, true, Trk::pion).release();
303 
304  double currentTrackZ0 = lexPerigee->parameters()[Trk::z0];
305  delete lexPerigee;
306 
307  if (std::fabs(currentTrackZ0 - lastTrackZ0) < m_sepDistance) {
308  // the distance is below separation, adding to the same cluster
309  tmp_cluster.push_back(preselectedTracks[i]);
310  }else{
311  //the distance is above separation, starting new cluster
312  preClusters.push_back(tmp_cluster);
313  tmp_cluster.clear();
314  tmp_cluster.push_back(preselectedTracks[i]);
315  }//end of gap size check
316 
317  lastTrackZ0 = currentTrackZ0;
318  }//end of loop over the sorted container
319 
320  //storing the last (or the only) cluster
321  preClusters.push_back(tmp_cluster);
322  ATH_MSG_DEBUG("The preselection returns clusters: "<<preClusters.size());
323 
324  //step 4 iterative cleaning of clusters
325  for(const auto & preCluster : preClusters){
326 
327  //------------------------------Debug code -------------------------------------------------------
328  /* std::vector<const Trk::Track *>::const_iterator cb = i->begin();
329  std::vector<const Trk::Track *>::const_iterator ce = i->end();
330  std::cout<<"*********Starting next cluster of size "<<i->size()<<std::endl;
331  for(;cb!=ce;++cb)
332  {
333  std::cout<<"Track Z0 in cluster: "<<(*cb)->perigeeParameters()->parameters()[Trk::z0]<<std::endl;
334  }//end of loop over the cluster entries
335  */
336  //-------------------------------end of debug code-------------------------------------------------
337 
338  if(preCluster.size()>m_nRemaining){
339  //iterative cleaning until outlying tracks remain
340  std::vector<const xAOD::TrackParticle *> tracks_to_clean = preCluster;
341  bool clean_again = false;
342  do{
343  std::pair<std::vector<const Trk::TrackParameters *>,
344  std::vector<const xAOD::TrackParticle *> > clusterAndOutl = m_cleaningTool->clusterAndOutliers(tracks_to_clean, &beamposition);
345 
346  //if core size is miningfull, storing it
347  std::vector<const Trk::TrackParameters *> core_cluster = clusterAndOutl.first;
348  std::vector<const xAOD::TrackParticle *> core_outl = clusterAndOutl.second;
349 
350  //--------------Debug output-----------------------------------------------------
351  // std::cout<<"Cleaning iteration "<<clean_count<<std::endl;
352  // std::cout<<"Reduced cluster size: "<<core_cluster.size()<<std::endl;
353  // std::cout<<"Outliers size: "<<core_outl.size()<<std::endl;
354  // ++clean_count;
355  //-------------------End of debug output -----------------------------------------
356 
357  if(core_cluster.empty()){
358  ATH_MSG_DEBUG("Core cluster has 0 size, remaining tracks are discarded.");
359  clean_again = false;
360  }else{
361  //storing clusters with >1 track (optional)
362  if(core_cluster.size()>1) result.push_back(core_cluster);
363 
364  //checking the outliers, whether more cleaning is to be done
365  if(core_outl.size()>m_nRemaining){
366  clean_again = true;
367  tracks_to_clean.clear();
368  tracks_to_clean = core_outl;
369  }else if(core_outl.size()>1){
370  clean_again = false;
371  ATH_MSG_DEBUG("There were remaining outliers of size: "<< core_outl.size());
372  ATH_MSG_DEBUG("Not evident, whether these tracks form a cluster. Rejected...");
373  }else clean_again = false;//end of outlier size check
374  }//end of core cluster 0 check
375 
376  }while(clean_again);//end of loop
377 
378  }else if(preCluster.size()==2){
379  //case of two track cluster. accepting without cleaning
380  std::vector<const Trk::TrackParameters *> twotrack;
381  twotrack.push_back(&(preCluster[0]->perigeeParameters()));
382  twotrack.push_back(&(preCluster[1]->perigeeParameters()));
383  result.push_back(twotrack);
384  }//end of cluster size check
385  }//end of loop over all the clusters
386  }//end of preselection size check
387  return result;
388 
389  }
390 
391 }//end of namespace definitions
Trk::anyDirection
@ anyDirection
Definition: PropDirection.h:22
Trk::Vertex
Definition: Tracking/TrkEvent/VxVertex/VxVertex/Vertex.h:26
IVertexSeedFinder.h
xAOD::Vertex_v1::setPosition
void setPosition(const Amg::Vector3D &position)
Sets the 3-position.
get_generator_info.result
result
Definition: get_generator_info.py:21
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
xAOD::Vertex
Vertex_v1 Vertex
Define the latest version of the vertex class.
Definition: Event/xAOD/xAODTracking/xAODTracking/Vertex.h:16
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
DivisiveMultiSeedFinder.h
Trk::PerigeeSurface
Definition: PerigeeSurface.h:43
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
InDet
DUMMY Primary Vertex Finder.
Definition: VP1ErrorUtils.h:36
EventPrimitivesHelpers.h
Trk::z0
@ z0
Definition: ParamDefs.h:70
InDet::DivisiveMultiSeedFinder::m_beamSpotKey
SG::ReadCondHandleKey< InDet::BeamSpotData > m_beamSpotKey
Definition: DivisiveMultiSeedFinder.h:73
IExtrapolator.h
xAOD::Vertex_v1::position
const Amg::Vector3D & position() const
Returns the 3-pos.
InDetTrackZ0SortingTool.h
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
IMultiPVSeedFinder.h
Trk::RecVertex
Trk::RecVertex inherits from Trk::Vertex.
Definition: RecVertex.h:44
InDet::DivisiveMultiSeedFinder::~DivisiveMultiSeedFinder
~DivisiveMultiSeedFinder()
Track.h
InDet::DivisiveMultiSeedFinder::m_sepDistance
double m_sepDistance
Definition: DivisiveMultiSeedFinder.h:52
InDetTrackClusterCleaningTool.h
InDet::DivisiveMultiSeedFinder::m_trkFilter
ToolHandle< Trk::ITrackSelectorTool > m_trkFilter
Definition: DivisiveMultiSeedFinder.h:64
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
lumiFormat.i
int i
Definition: lumiFormat.py:92
beamspotman.n
n
Definition: beamspotman.py:731
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
Trk::pion
@ pion
Definition: ParticleHypothesis.h:29
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
InDet::DivisiveMultiSeedFinder::initialize
virtual StatusCode initialize() override
Definition: DivisiveMultiSeedFinder.cxx:19
Trk::ParametersBase
Definition: ParametersBase.h:55
Trk::Vertex::position
const Amg::Vector3D & position() const
return position of vertex
Definition: Vertex.cxx:72
Vertex.h
InDet::DivisiveMultiSeedFinder::m_extrapolator
ToolHandle< Trk::IExtrapolator > m_extrapolator
Definition: DivisiveMultiSeedFinder.h:75
InDet::DivisiveMultiSeedFinder::m_vtxSeedFinder
ToolHandle< Trk::IVertexSeedFinder > m_vtxSeedFinder
Definition: DivisiveMultiSeedFinder.h:78
InDet::DivisiveMultiSeedFinder::m_cleaningTool
ToolHandle< InDetTrackClusterCleaningTool > m_cleaningTool
Definition: DivisiveMultiSeedFinder.h:70
Trk::perigeeParameters
@ perigeeParameters
Definition: MeasurementType.h:19
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
InDet::DivisiveMultiSeedFinder::seeds
virtual std::vector< std::vector< const Trk::Track * > > seeds(const std::vector< const Trk::Track * > &tracks) const override
Clustering method itself.
Definition: DivisiveMultiSeedFinder.cxx:91
xAOD::Vertex_v1
Class describing a Vertex.
Definition: Vertex_v1.h:42
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
InDet::DivisiveMultiSeedFinder::DivisiveMultiSeedFinder
DivisiveMultiSeedFinder(const std::string &t, const std::string &n, const IInterface *p)
Constructor and destructor.
Definition: DivisiveMultiSeedFinder.cxx:58
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
AthAlgTool
Definition: AthAlgTool.h:26
ITrackSelectorTool.h
InDet::DivisiveMultiSeedFinder::m_nRemaining
unsigned int m_nRemaining
Definition: DivisiveMultiSeedFinder.h:54
xAOD::Vertex_v1::setCovariancePosition
void setCovariancePosition(const AmgSymMatrix(3)&covariancePosition)
Sets the vertex covariance matrix.
InDet::DivisiveMultiSeedFinder::m_ignoreBeamSpot
bool m_ignoreBeamSpot
Definition: DivisiveMultiSeedFinder.h:56
InDet::DivisiveMultiSeedFinder::m_sortingTool
ToolHandle< InDetTrackZ0SortingTool > m_sortingTool
Definition: DivisiveMultiSeedFinder.h:67