ATLAS Offline Software
HistogrammingMultiSeedFinder.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"
11 #include "xAODTracking/Vertex.h"
13 #include <optional>
14 
15 namespace InDet
16 {
18  {
19 
20  if(m_trkFilter.retrieve().isFailure())
21  {
22  ATH_MSG_ERROR(" Unable to retrieve "<<m_trkFilter);
23  return StatusCode::FAILURE;
24  }
25 
26  if(m_cleaningTool.retrieve().isFailure())
27  {
28  ATH_MSG_ERROR(" Unable to retrieve "<<m_cleaningTool);
29  return StatusCode::FAILURE;
30  }
31 
33  if(m_vtxSeedFinder.retrieve().isFailure())
34  {
35  ATH_MSG_ERROR("Unable to retrieve " << m_vtxSeedFinder);
36  return StatusCode::FAILURE;
37  }
38 
39  if ( m_extrapolator.retrieve().isFailure() )
40  {
41  ATH_MSG_ERROR("Failed to retrieve tool " << m_extrapolator);
42  return StatusCode::FAILURE;
43  }
44 
45  return StatusCode::SUCCESS;
46  }//end of initialize mtehod
47 
48 
49  HistogrammingMultiSeedFinder::HistogrammingMultiSeedFinder(const std::string& t, const std::string& n, const IInterface*p):
50  AthAlgTool(t,n,p),
51  m_sepNBins(2),
52  m_nBins(500),
53  m_nRemaining(1),
54  m_histoRange(200.),
55  m_ignoreBeamSpot(false),
56  m_vtxSeedFinder("Trk::CrossDistancesSeedFinder"),
57  m_extrapolator("Trk::Extrapolator")
58  {
59  declareInterface<IMultiPVSeedFinder>(this);
60  declareProperty("maxSeparNumBins", m_sepNBins);
61  declareProperty("nBins", m_nBins);
62  declareProperty("nRemainTracks", m_nRemaining);
63  declareProperty("HistoRange", m_histoRange);
64  declareProperty("IgnoreBeamSpot", m_ignoreBeamSpot);
65 
66 
67  //track filter
68  declareProperty("TrackSelector", m_trkFilter );
69 
70  //cleaning tool
71  declareProperty("CleaningTool", m_cleaningTool);
72 
73  //vertex finder tool (needed when no beam spot is available)
74  declareProperty("VertexSeedFinder",m_vtxSeedFinder);
75 
76  //extrapolator
77  declareProperty("Extrapolator",m_extrapolator);
78  }//end of constructor
79 
81  = default;
82 
83  std::vector< std::vector<const Trk::Track *> > HistogrammingMultiSeedFinder::seeds(const std::vector<const Trk::Track*>& tracks )const
84  {
85  const EventContext& ctx = Gaudi::Hive::currentContext();
86 
87  //step 1: preselection
88  std::vector<const Trk::Track*> preselectedTracks(0);
89  std::vector<const Trk::Track*>::const_iterator tr = tracks.begin();
90  std::vector<const Trk::Track*>::const_iterator tre = tracks.end();
91 
92  //beamposition
94 
95  Trk::RecVertex beamrecposition(beamSpotHandle->beamVtx());
96  ATH_MSG_DEBUG("Beam spot position is: "<< beamrecposition.position());
97  for(;tr!=tre;++tr) if(m_trkFilter->decision(**tr,&beamrecposition)) preselectedTracks.push_back(*tr);
98  Trk::Vertex* beamposition=&beamrecposition;
99 
100  Trk::Vertex myVertex;
101  if (m_ignoreBeamSpot)
102  {
103  myVertex = Trk::Vertex(m_vtxSeedFinder->findSeed(tracks));
104  ATH_MSG_DEBUG(" vtx seed x: " << myVertex.position().x() <<
105  " vtx seed y: " << myVertex.position().y() <<
106  " vtx seed z: " << myVertex.position().z());
107  beamposition = &myVertex;
108  }
109 
110  //step 2: histogramming tracks
111  //output container
112  std::vector< std::vector<const Trk::Track *> > result(0);
113  if(!preselectedTracks.empty())
114  {
115  std::map<unsigned int, std::vector<const Trk::Track *> > histo;
116 
117  //getting the bin size
118  double bin_size = 2. * m_histoRange/ m_nBins;
119 
120  std::vector<const Trk::Track*>::const_iterator p_tr = preselectedTracks.begin();
121  std::vector<const Trk::Track*>::const_iterator p_tre = preselectedTracks.end();
122 
123 
124  //creating a perigee surfce to extrapolate tracks
125  Trk::PerigeeSurface perigeeSurface(beamposition->position());
126 
127  for(;p_tr != p_tre; ++p_tr)
128  {
129  const Trk::TrackParameters* lexPerigee =
130  m_extrapolator->extrapolateTrack(ctx, **p_tr, perigeeSurface, Trk::anyDirection, true, Trk::pion).release();
131 
132  double currentTrackZ0 = lexPerigee->parameters()[Trk::z0];
133  delete lexPerigee;
134 
135  unsigned int bin_number =
136  int(floor((currentTrackZ0 + m_histoRange) / bin_size)) + 1;
137 
138  // now checking whether this bin entry already exists and adding track, if
139  // not, creating one.
140  std::map<unsigned int, std::vector<const Trk::Track*>>::iterator map_pos =
141  histo.find(bin_number);
142  if (map_pos != histo.end()) {
143  // this bin already exists, adding entry
144  map_pos->second.push_back(*p_tr);
145  }else{
146  //this bin is not their yet, adding bin
147  std::vector<const Trk::Track *> tmp_vec(0);
148  tmp_vec.push_back(*p_tr);
149  histo.insert( std::map<unsigned int, std::vector<const Trk::Track *> >::value_type(bin_number, tmp_vec));
150  }//end of checking bin existence
151  }//end of loop over all sorted tracks
152 
153  //------------------------- Debug output -------------------------------------------------------------------
154  //debug output: checking the bin contents of the histogram
155  /* std::cout<<"**********Checking the histogram ************"<<std::endl;
156  for(std::map<unsigned int, std::vector<const Trk::Track *> >::iterator i = histo.begin(); i != histo.end(); ++i)
157  {
158  std::cout<<"Currennt bin N "<< i->first<<std::endl;
159  std::cout<<"Containes entries: "<< i->second.size()<<std::endl;
160  }//end of debug histogram check
161  */
162  //------------------------- End of debug output -------------------------------------------------------------------
163 
164  //step 3: merging clusters
165  //bins closer to each other than several empty bins become
166  //parts of the same cluster
167 
168  std::vector<std::vector<const Trk::Track *> > preClusters(0);
169  std::vector<const Trk::Track *> tmp_cluster(0);
170  unsigned int previous_bin = histo.begin()->first;
171  for(auto & i : histo){
172  unsigned int current_bin = i.first;
173  if((current_bin - previous_bin)>m_sepNBins ){
174  //forming a new cluster
175  preClusters.push_back(tmp_cluster);
176  tmp_cluster.clear();
177  }
178 
179  // in any case filling tracks into this bin.
180  for(const auto *j : i.second) tmp_cluster.push_back(j);
181  previous_bin = current_bin;
182  }//end of loop over the map entries
183  preClusters.push_back(tmp_cluster);
184 
185  //step 4 iterative cleaning of formed clusters
186  for(const auto & preCluster : preClusters){
187  if(preCluster.size()>m_nRemaining){
188  std::vector<const Trk::Track *> tracks_to_clean = preCluster;
189  bool clean_again = false;
190  do{
191  std::pair<std::vector<const Trk::Track *>, std::vector<const Trk::Track *> > clusterAndOutl =
192  m_cleaningTool->clusterAndOutliers(tracks_to_clean, beamposition);
193 
194  //if core size is miningfull, storing it
195  std::vector<const Trk::Track *> core_cluster = clusterAndOutl.first;
196  std::vector<const Trk::Track *> core_outl = clusterAndOutl.second;
197 
198  //--------------Debug output-----------------------------------------------------
199  // std::cout<<"Cleaning iteration "<<clean_count<<std::endl;
200  // std::cout<<"Reduced cluster size: "<<core_cluster.size()<<std::endl;
201  // std::cout<<"Outliers size: "<<core_outl.size()<<std::endl;
202  // ++clean_count;
203  //-------------------End of debug output -----------------------------------------
204 
205  if(core_cluster.empty()){
206  ATH_MSG_DEBUG("Core cluster has 0 size, remaining tracks are discarded.");
207  clean_again = false;
208  }else{
209  //storing clusters with >1 track (optional)
210  if(core_cluster.size()>1) result.push_back(core_cluster);
211  //checking the outliers, whether more cleaning is to be done
212  if(core_outl.size()>m_nRemaining){
213  clean_again = true;
214  tracks_to_clean.clear();
215  tracks_to_clean = core_outl;
216  }else if(core_outl.size()>1){
217  clean_again = false;
218  ATH_MSG_DEBUG("There were remaining outliers of size: "<< core_outl.size());
219  ATH_MSG_DEBUG("Not evident, whether these tracks form a cluster. Rejected...");
220  }else clean_again = false;//end of outlier size check
221  }//end of core cluster 0 check
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 preclusters
229  }//end of preselection not zero check
230 
231  return result;
232  }//end of seed finding method
233 
234  std::vector< std::vector<const Trk::TrackParameters *> > HistogrammingMultiSeedFinder::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::map<unsigned int, std::vector<const xAOD::TrackParticle *> > histo;
273 
274  //getting the bin size
275  double bin_size = 2.* m_histoRange/ m_nBins;
276 
277  ATH_MSG_DEBUG("Beam spot position is: "<< beamposition.position());
278 
279  //getting a perigee surface to be used
280  Trk::PerigeeSurface perigeeSurface(beamposition.position());
281 
282  std::vector<const xAOD::TrackParticle*>::const_iterator p_tr = preselectedTracks.begin();
283  std::vector<const xAOD::TrackParticle*>::const_iterator p_tre = preselectedTracks.end();
284  for(;p_tr != p_tre; ++p_tr){
285  const Trk::TrackParameters* lexPerigee =
286  m_extrapolator->extrapolate(ctx, (*p_tr)->perigeeParameters(),
287  perigeeSurface, Trk::anyDirection, true, Trk::pion)
288  .release();
289  double currentTrackZ0 = lexPerigee->parameters()[Trk::z0];
290  delete lexPerigee;
291 
292  unsigned int bin_number =
293  int(floor((currentTrackZ0 + m_histoRange) / bin_size)) + 1;
294 
295  // now checking whether this bin entry already exists and adding
296  // track, if not, creating one.
297  std::map<unsigned int,
298  std::vector<const xAOD::TrackParticle*>>::iterator map_pos =
299  histo.find(bin_number);
300  if (map_pos != histo.end()) {
301  // this bin already exists, adding entry
302  map_pos->second.push_back(*p_tr);
303  }else{
304  //this bin is not their yet, adding bin
305  std::vector<const xAOD::TrackParticle *> tmp_vec(0);
306  tmp_vec.push_back(*p_tr);
307  histo.insert( std::map<unsigned int, std::vector<const xAOD::TrackParticle *> >::value_type(bin_number, tmp_vec));
308  }//end of checking bin existence
309  }//end of loop over all sorted track particles
310 
311  //step 3: merging clusters
312  //bins closer to each other than several empty bins become
313  //parts of the same cluster
314 
315  std::vector<std::vector<const xAOD::TrackParticle *> > preClusters(0);
316  std::vector<const xAOD::TrackParticle *> tmp_cluster(0);
317  unsigned int previous_bin = histo.begin()->first;
318  for(auto & i : histo){
319  unsigned int current_bin = i.first;
320  if((current_bin - previous_bin)>m_sepNBins){
321  //forming a new cluster
322  preClusters.push_back(tmp_cluster);
323  tmp_cluster.clear();
324  }
325  // in any case filling tracks into this bin.
326  for(const auto *j : i.second) tmp_cluster.push_back(j);
327  previous_bin = current_bin;
328  }//end of loop over the map entries
329  preClusters.push_back(tmp_cluster);
330 
331  for(const auto & preCluster : preClusters){
332 
333  //------------------------------Debug code -------------------------------------------------------
334  /* std::vector<const Trk::Track *>::const_iterator cb = i->begin();
335  std::vector<const Trk::Track *>::const_iterator ce = i->end();
336  std::cout<<"*********Starting next cluster of size "<<i->size()<<std::endl;
337  for(;cb!=ce;++cb)
338  {
339  std::cout<<"Track Z0 in cluster: "<<(*cb)->perigeeParameters()->parameters()[Trk::z0]<<std::endl;
340  }//end of loop over the cluster entries
341  */
342  //-------------------------------end of debug code-------------------------------------------------
343 
344  if(preCluster.size()>m_nRemaining){
345  //iterative cleaning until outlying tracks remain
346  std::vector<const xAOD::TrackParticle *> tracks_to_clean = preCluster;
347  bool clean_again = false;
348  do{
349  std::pair<std::vector<const Trk::TrackParameters *>,
350  std::vector<const xAOD::TrackParticle *> > clusterAndOutl = m_cleaningTool->clusterAndOutliers(tracks_to_clean, &beamposition);
351 
352  //if core size is miningfull, storing it
353  std::vector<const Trk::TrackParameters *> core_cluster = clusterAndOutl.first;
354  std::vector<const xAOD::TrackParticle *> core_outl = clusterAndOutl.second;
355 
356  //--------------Debug output-----------------------------------------------------
357  // std::cout<<"Cleaning iteration "<<clean_count<<std::endl;
358  // std::cout<<"Reduced cluster size: "<<core_cluster.size()<<std::endl;
359  // std::cout<<"Outliers size: "<<core_outl.size()<<std::endl;
360  // ++clean_count;
361  //-------------------End of debug output -----------------------------------------
362 
363  if(core_cluster.empty()){
364  ATH_MSG_DEBUG("Core cluster has 0 size, remaining tracks are discarded.");
365  clean_again = false;
366  }else{
367  //storing clusters with >1 track (optional)
368  if(core_cluster.size()>1) result.push_back(core_cluster);
369 
370  //checking the outliers, whether more cleaning is to be done
371  if(core_outl.size()>m_nRemaining){
372  clean_again = true;
373  tracks_to_clean.clear();
374  tracks_to_clean = core_outl;
375  }else if(core_outl.size()>1){
376  clean_again = false;
377  ATH_MSG_DEBUG("There were remaining outliers of size: "<< core_outl.size());
378  ATH_MSG_DEBUG("Not evident, whether these tracks form a cluster. Rejected...");
379  }else clean_again = false;//end of outlier size check
380  }//end of core cluster 0 check
381 
382  }while(clean_again);//end of loop
383 
384  }else if(preCluster.size()==2){
385  //case of two track cluster. accepting without cleaning
386  std::vector<const Trk::TrackParameters *> twotrack;
387  twotrack.push_back(&(preCluster[0]->perigeeParameters()));
388  twotrack.push_back(&(preCluster[1]->perigeeParameters()));
389  result.push_back(twotrack);
390  }//end of cluster size check
391  }//end of loop over all the clusters
392  }//end of preselection size check
393  return result;
394  }
395 
396 }//end of namespace definitions
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
InDet::HistogrammingMultiSeedFinder::m_ignoreBeamSpot
bool m_ignoreBeamSpot
Definition: HistogrammingMultiSeedFinder.h:74
InDet::HistogrammingMultiSeedFinder::~HistogrammingMultiSeedFinder
~HistogrammingMultiSeedFinder()
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
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
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
IExtrapolator.h
xAOD::Vertex_v1::position
const Amg::Vector3D & position() const
Returns the 3-pos.
InDet::HistogrammingMultiSeedFinder::m_sepNBins
unsigned int m_sepNBins
Definition: HistogrammingMultiSeedFinder.h:66
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
Trk::RecVertex
Trk::RecVertex inherits from Trk::Vertex.
Definition: RecVertex.h:44
InDet::HistogrammingMultiSeedFinder::HistogrammingMultiSeedFinder
HistogrammingMultiSeedFinder(const std::string &t, const std::string &n, const IInterface *p)
Constructor and destructor.
Definition: HistogrammingMultiSeedFinder.cxx:49
Track.h
InDet::HistogrammingMultiSeedFinder::m_nBins
unsigned int m_nBins
Definition: HistogrammingMultiSeedFinder.h:68
InDetTrackClusterCleaningTool.h
InDet::HistogrammingMultiSeedFinder::seeds
virtual std::vector< std::vector< const Trk::Track * > > seeds(const std::vector< const Trk::Track * > &tracks) const override
Clustering method itself.
Definition: HistogrammingMultiSeedFinder.cxx:83
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
HistogrammingMultiSeedFinder.h
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
InDet::HistogrammingMultiSeedFinder::m_nRemaining
unsigned int m_nRemaining
Definition: HistogrammingMultiSeedFinder.h:70
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Trk::ParametersBase
Definition: ParametersBase.h:55
Trk::Vertex::position
const Amg::Vector3D & position() const
return position of vertex
Definition: Vertex.cxx:72
InDet::HistogrammingMultiSeedFinder::m_cleaningTool
ToolHandle< InDetTrackClusterCleaningTool > m_cleaningTool
Definition: HistogrammingMultiSeedFinder.h:78
Vertex.h
InDet::HistogrammingMultiSeedFinder::m_vtxSeedFinder
ToolHandle< Trk::IVertexSeedFinder > m_vtxSeedFinder
Definition: HistogrammingMultiSeedFinder.h:79
Trk::perigeeParameters
@ perigeeParameters
Definition: MeasurementType.h:19
InDet::HistogrammingMultiSeedFinder::m_histoRange
float m_histoRange
Definition: HistogrammingMultiSeedFinder.h:72
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
InDet::HistogrammingMultiSeedFinder::m_extrapolator
ToolHandle< Trk::IExtrapolator > m_extrapolator
Definition: HistogrammingMultiSeedFinder.h:83
xAOD::Vertex_v1
Class describing a Vertex.
Definition: Vertex_v1.h:42
InDet::HistogrammingMultiSeedFinder::m_beamSpotKey
SG::ReadCondHandleKey< InDet::BeamSpotData > m_beamSpotKey
Definition: HistogrammingMultiSeedFinder.h:82
InDet::HistogrammingMultiSeedFinder::initialize
virtual StatusCode initialize() override
Definition: HistogrammingMultiSeedFinder.cxx:17
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
AthAlgTool
Definition: AthAlgTool.h:26
InDet::HistogrammingMultiSeedFinder::m_trkFilter
ToolHandle< Trk::ITrackSelectorTool > m_trkFilter
Definition: HistogrammingMultiSeedFinder.h:77
ITrackSelectorTool.h
plotBeamSpotCompare.histo
histo
Definition: plotBeamSpotCompare.py:415
value_type
Definition: EDM_MasterSearch.h:11
xAOD::Vertex_v1::setCovariancePosition
void setCovariancePosition(const AmgSymMatrix(3)&covariancePosition)
Sets the vertex covariance matrix.