ATLAS Offline Software
VtxMap.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 #ifndef TRIGTOOLS_TRIG_VSI_VTXMAP
5 #define TRIGTOOLS_TRIG_VSI_VTXMAP
6 
17 
18 #include "TVector3.h"
19 #include "TH3D.h"
20 
21 #include <unordered_set>
22 #include <vector>
23 #include <memory>
24 #include <type_traits>
25 
26 namespace TrigVSI{
27 
28 //========================================================================
37 template<typename WrkVrt, typename Cord>
38 class VtxMap {
39  static_assert(std::is_base_of<TrigVSI::IWrkVrt, WrkVrt>::value, "WrkVrt must be derived from IWrkVrt.");
40  static_assert(Coordinate::is_coord<Cord>::value, "Coord must define static methods for a coordinate system.");
41 
42  public :
43  VtxMap(TH3D* ptr) : m_mapHist( std::unique_ptr<TH3D>(ptr) ){};
44  VtxMap(std::unique_ptr<TH3D>&& uptr) : m_mapHist( std::move(uptr) ){};
45  VtxMap(){};
46  ~VtxMap(){};
47 
49  VtxMap& operator= (VtxMap&&) = default;
50  VtxMap(VtxMap&&) = default;
51 
52 
53  //========================================================================
58  class Cell : public VtxPack<WrkVrt> {
59  public :
68  Cell(size_t id, const KDPoint<double, 3> & p, std::vector<const WrkVrt*>& v) : VtxPack<WrkVrt>(v), m_id(id), m_pos(p) {};
69  Cell(size_t id, const KDPoint<double, 3> & p, std::vector<const WrkVrt*>&& v) : VtxPack<WrkVrt>(v), m_id(id), m_pos(p) {};
70  Cell(size_t id, const KDPoint<double, 3> & p, const WrkVrt* vtx_ptr) : VtxPack<WrkVrt>( std::vector<const WrkVrt*>{vtx_ptr} ), m_id(id), m_pos(p) {};
71  Cell(size_t id, const KDPoint<double, 3> & p) : m_id(id), m_pos(p) {};
72  Cell(){};
73 
74  inline int getId(){ return m_id; };
75 
77  inline KDPoint<double, 3> getPosPoint() { m_pos.setWeight(this->getWeight()); return m_pos; };
78 
80  inline TVector3 getPosVect() const { return Cord::X123toXYZ(m_pos); };
81 
82  private :
83  int m_id = -1;
85  };
86 
87 
88  //========================================================================
95  class CellCluster : public Cluster<Cell*>, public VtxPack<WrkVrt> {
96  public :
103  CellCluster(std::vector<Cell*>&& v) : Cluster<Cell*>(v)
104  {
105  size_t n_vtx = 0;
106  for ( auto& cell_ptr : v ) n_vtx += cell_ptr->nVtx();
107  std::vector<const WrkVrt*> tmp_vtx_cls;
108  tmp_vtx_cls.reserve(n_vtx);
109 
110  double w = 0.;
111  TVector3 tmp_vec(0.,0.,0.);
112  for ( auto& cell_ptr : v ) {
113  std::vector<const WrkVrt*> tmp_vtx_cell = cell_ptr->getVtxList();
114  tmp_vtx_cls.insert( tmp_vtx_cls.end(), tmp_vtx_cell.begin(), tmp_vtx_cell.end() );
115 
116  tmp_vec += cell_ptr->getWeight() * cell_ptr->getPosVect();
117  w += cell_ptr->getWeight();
118  }
119  this->m_vtxLists = std::move(tmp_vtx_cls);
120  this->updateLists();
121 
122  this->m_posAvrVec = (1. / w) * tmp_vec;
123  this->m_posAvr = Cord::XYZtoX123(this->m_posAvrVec);
124  this->m_posAvr.setWeight(w);
125  };
126 
128  inline void emplace_back(const WrkVrt*) = delete;
129 
130  inline size_t nCells() const { return this->nPoints(); };
131 
134  inline double x1() const { return m_posAvr.at(0); };
135  inline double x2() const { return m_posAvr.at(1); };
136  inline double x3() const { return m_posAvr.at(2); };
137  inline const KDPoint<double,3> & PosCoord() const { return m_posAvr; };
139 
142  inline double x() const { return m_posAvrVec.x(); };
143  inline double y() const { return m_posAvrVec.y(); };
144  inline double z() const { return m_posAvrVec.z(); };
145  inline TVector3 PosVect() const { return m_posAvrVec; };
147 
148  private :
150  TVector3 m_posAvrVec;
151  };
152 
153 
154  //
155  // Public member functions
156  //_________________________________________________________________________
157  void Fill(const WrkVrt*);
158 
159  inline bool isInMapVolume(const KDPoint<double, 3>&) const;
160  inline bool isInMapVolume(double, double, double) const;
161  inline bool isInMapVolume(int, int, int) const;
162  inline KDPoint<double, 3> getBinCenter(int) const;
163 
164  inline int getVtxNum(double, double, double) const;
165 
167  inline void lock() { m_locked = true; };
169  inline void unlock() { m_locked = false; };
170 
172  inline void Reset()
173  {
174  m_mapHist->Reset();
175  m_activeCells.clear();
176  m_cellVtxDict.clear();
177  m_locked = false;
178  m_dbscan = DBScan<int>();
179  }
180 
181  void ClusterizeCells(double, size_t);
182 
184  inline std::vector<Cluster<int>> getClustersBin() const { return m_dbscan.getClusters(); };
186  inline size_t nClusters() const { return m_dbscan.nClusters(); };
187 
188  CellCluster getCluster(size_t);
189  std::vector<const WrkVrt*> getVtxInCluster(size_t);
190 
191  private :
192  //
193  // Private member variables
194  //_________________________________________________________________________
195  std::unique_ptr<TH3D> m_mapHist;
196  std::unordered_set<int> m_activeCells;
197  std::unordered_map<int, Cell> m_cellVtxDict;
198  bool m_locked = false;
200 
201  //
202  // Private member functions
203  //_________________________________________________________________________
204  void Fill(double, double, double);
205  std::vector<int> getNeighborCells_(const int&, double);
206 
207 };
208 
209 
210 
216 template<typename WrkVrt, typename Cord>
218 {
219  return VtxMap<WrkVrt,Cord>::isInMapVolume(point[0], point[1], point[2]);
220 }
221 
222 
230 template<typename WrkVrt, typename Cord>
231 bool VtxMap<WrkVrt,Cord>::isInMapVolume(double x1, double x2, double x3) const
232 {
233  if ( m_mapHist->GetXaxis()->FindFixBin(x1) < 1 || m_mapHist->GetXaxis()->FindFixBin(x1) > m_mapHist->GetNbinsX() ) return false;
234  if ( m_mapHist->GetYaxis()->FindFixBin(x2) < 1 || m_mapHist->GetYaxis()->FindFixBin(x2) > m_mapHist->GetNbinsY() ) return false;
235  if ( m_mapHist->GetZaxis()->FindFixBin(x3) < 1 || m_mapHist->GetZaxis()->FindFixBin(x3) > m_mapHist->GetNbinsZ() ) return false;
236  return true;
237 }
238 
239 
246 template<typename WrkVrt, typename Cord>
247 bool VtxMap<WrkVrt,Cord>::isInMapVolume(int ibinx, int ibiny, int ibinz) const
248 {
249  if ( ibinx < 1 || ibinx > m_mapHist->GetNbinsX() ) return false;
250  if ( ibiny < 1 || ibiny > m_mapHist->GetNbinsY() ) return false;
251  if ( ibinz < 1 || ibinz > m_mapHist->GetNbinsZ() ) return false;
252  return true;
253 }
254 
255 
260 template<typename WrkVrt, typename Cord>
261 int VtxMap<WrkVrt,Cord>::getVtxNum(double x, double y, double z) const
262 {
263  if ( !isInMapVolume(x, y, z) ) return -1;
264  int ibin = m_mapHist->FindFixBin(x, y, z);
265  return m_mapHist->GetBinContent(ibin);
266 }
267 
268 
272 template<typename WrkVrt, typename Cord>
274 {
275  int xbin; int ybin; int zbin;
276  m_mapHist->GetBinXYZ(ibin, xbin, ybin, zbin);
277  double x = m_mapHist->GetXaxis()->GetBinCenter(xbin);
278  double y = m_mapHist->GetYaxis()->GetBinCenter(ybin);
279  double z = m_mapHist->GetZaxis()->GetBinCenter(zbin);
280 
281  KDPoint<double, 3> pos_tmp({x,y,z});
282  return pos_tmp;
283 }
284 
285 
291 template<typename WrkVrt, typename Cord>
292 void VtxMap<WrkVrt,Cord>::Fill(double x, double y, double z)
293 {
294  if (m_locked) return;
295  m_mapHist->Fill(x, y, z);
296  m_activeCells.emplace( m_mapHist->FindFixBin(x, y, z) );
297 }
298 
299 
305 template<typename WrkVrt, typename Cord>
306 void VtxMap<WrkVrt,Cord>::Fill( const WrkVrt* vtx_ptr )
307 {
308  if (m_locked) return;
309 
310  // Get position of vertex with projection to map region.
311  TVector3 vec( vtx_ptr->x(), vtx_ptr->y(), vtx_ptr->z() );
312  KDPoint<double,3> pos = Cord::Proj( Cord::XYZtoX123(vec) );
313  double x = pos[0];
314  double y = pos[1];
315  double z = pos[2];
316 
317  if ( !isInMapVolume(x,y,z) ) return;
318 
319  Fill(x,y,z);
320 
321  size_t ibin = m_mapHist->FindFixBin(x, y, z);
322  auto cell_itr = m_cellVtxDict.find( ibin );
323  if ( cell_itr != m_cellVtxDict.end() && cell_itr->second.getId() == static_cast<int>(ibin) ) {
324  cell_itr->second.emplace_back( vtx_ptr );
325  }
326  else {
327  m_cellVtxDict.emplace( ibin, Cell(ibin, getBinCenter(ibin), vtx_ptr) );
328  }
329 }
330 
331 
339 template<typename WrkVrt, typename Cord>
340 void VtxMap<WrkVrt,Cord>::ClusterizeCells(double eps, size_t minN)
341 {
342  m_locked = true;
343  DBScan<int>::RegionFunc region_query = [this](const int& glob_bin, double eps)
344  {
345  return getNeighborCells_(glob_bin, eps);
346  };
347  m_dbscan = DBScan<int>(m_activeCells, region_query);
348  m_dbscan.clusterize(eps, minN);
349 }
350 
351 
355 template<typename WrkVrt, typename Cord>
356 std::vector<int> VtxMap<WrkVrt,Cord>::getNeighborCells_(const int& glob_bin, double eps)
357 {
358  std::vector<int> tmp;
359  int d = static_cast<int>(eps);
360 
361  int binx = 0;
362  int biny = 0;
363  int binz = 0;
364  m_mapHist->GetBinXYZ(glob_bin, binx, biny, binz);
365 
366  KDPoint<int,3> v_ibin;
367 
368  if ( !(isInMapVolume(binx, biny, binz)) ) return tmp;
369 
370  for (int ix = binx - d; ix <= binx + d; ix++) {
371  for (int iy = biny - d; iy <= biny + d; iy++) {
372  for (int iz = binz - d; iz <= binz + d; iz++) {
373  //
374  v_ibin[0] = ix; v_ibin[1] = iy; v_ibin[2] = iz;
375 
376  // Convert coordinate with projection function
377  v_ibin = Cord::ProjBin(v_ibin, m_mapHist);
378 
379  // If current cell is self, skip it.
380  if ( v_ibin[0] == binx && v_ibin[1] == biny && v_ibin[2] == binz ) continue;
381 
382  // If cerrent cell is not in map volme, skip it.
383  if ( !(isInMapVolume(v_ibin[0], v_ibin[1], v_ibin[2])) ) continue;
384 
385  // If there is no entry in current cell, skip it.
386  if ( m_mapHist->GetBinContent(m_mapHist->GetBin(v_ibin[0], v_ibin[1], v_ibin[2])) < 1. ) continue;
387  tmp.emplace_back(m_mapHist->GetBin(v_ibin[0], v_ibin[1], v_ibin[2]));
388  //
389  }
390  }
391  }
392  //
393  return tmp;
394 }
395 
396 
400 template<typename WrkVrt, typename Cord>
401 std::vector<const WrkVrt*> VtxMap<WrkVrt,Cord>::getVtxInCluster(size_t icls)
402 {
403  Cluster<int> cls = m_dbscan.getClusters().at(icls);
404 
405  std::vector<const WrkVrt*> v_tmp;
406  for (const auto& ibin : cls.Points()) {
407  std::vector<const WrkVrt*> v_vtx = m_cellVtxDict[ibin].getVtxList();
408  v_tmp.insert( v_tmp.end(), v_vtx.begin(), v_vtx.end() );
409  }
410  return v_tmp;
411 }
412 
413 
417 template<typename WrkVrt, typename Cord>
419 {
420  const Cluster<int>& cls = m_dbscan.getCluster(icls);
421  std::vector<Cell*> v_tmp;
422 
423  std::vector<int> cell_ids = cls.getPoints();
424  for (const auto ibin : cell_ids) {
425  Cell& cell = m_cellVtxDict[ibin];
426  if ( ibin != cell.getId() ) continue;
427  v_tmp.emplace_back( &cell );
428  }
429  VtxMap<WrkVrt,Cord>::CellCluster cls_tmp( std::move(v_tmp) );
430  return cls_tmp;
431 }
432 
433 
435 
436 } // end of namespace TrigVSI
437 
438 #endif
plotBeamSpotCompare.x1
x1
Definition: plotBeamSpotCompare.py:215
TrigVSI::VtxMap::Cell::m_id
int m_id
Definition: VtxMap.h:83
TrigVSI::VtxMap::Cell::getId
int getId()
Definition: VtxMap.h:74
ReadCellNoiseFromCool.cell
cell
Definition: ReadCellNoiseFromCool.py:53
TrigVSI::VtxMap::CellCluster::x
double x() const
Definition: VtxMap.h:142
TrigVSI::VtxMap::operator=
VtxMap & operator=(VtxMap &&)=default
Move assignment operator.
TrigVSI::VtxPack
Base class of local vertex container in VtxMap.
Definition: IWrkVrt.h:56
TrigVSI::VtxMap::m_locked
bool m_locked
Definition: VtxMap.h:198
TrigVSI::KDPoint::at
T at(size_t i) const
Return i-th element. If given i exceeds the size, return NaN.
Definition: KDPoint.h:128
DBScan.h
Clustering algorithm for vertex merging based on DBSCAN.
TrigVSI::VtxMap::CellCluster::nCells
size_t nCells() const
Definition: VtxMap.h:130
hist_file_dump.d
d
Definition: hist_file_dump.py:142
TrigVSI::DBScan::getClusters
std::vector< Cluster< pointType > > getClusters() const
Retrun the list of clusters along with noise clusters.
Definition: DBScan.h:107
TrigVSI::Cluster< Cell * >::nPoints
size_t nPoints() const
Definition: DBScan.h:31
TrigVSI::VtxMap::Cell::Cell
Cell()
Definition: VtxMap.h:72
plotBeamSpotCompare.x2
x2
Definition: plotBeamSpotCompare.py:217
TrigVSI::DBScan< int >
TrigVSI::VtxMap::m_activeCells
std::unordered_set< int > m_activeCells
Definition: VtxMap.h:196
TrigVSI::VtxMap::CellCluster::CellCluster
CellCluster(std::vector< Cell * > &&v)
Constructor.
Definition: VtxMap.h:103
TrigVSI::Cluster
Base class for clusters.
Definition: DBScan.h:24
TrigVSI::VtxMap::lock
void lock()
Lock the map to prevent adding vertex after clustering.
Definition: VtxMap.h:167
CaloClusterListBadChannel.cls
cls
Definition: CaloClusterListBadChannel.py:8
TrigVSI::VtxMap::getVtxInCluster
std::vector< const WrkVrt * > getVtxInCluster(size_t)
Retrieve list of vertices in i-th cluster.
Definition: VtxMap.h:401
TrigVSI::VtxMap::CellCluster::PosCoord
const KDPoint< double, 3 > & PosCoord() const
Definition: VtxMap.h:137
TrigVSI::VtxMap::Fill
void Fill(const WrkVrt *)
Fill vertex map with vertex from its pointer.
Definition: VtxMap.h:306
TrigVSI::VtxMap::VtxMap
VtxMap(VtxMap &&)=default
athena.value
value
Definition: athena.py:124
TrigVSI::VtxMap::~VtxMap
~VtxMap()
Definition: VtxMap.h:46
vec
std::vector< size_t > vec
Definition: CombinationsGeneratorTest.cxx:9
TrigVSI::VtxMap::getNeighborCells_
std::vector< int > getNeighborCells_(const int &, double)
Region query function to be passed to DBScan.
Definition: VtxMap.h:356
TrigVSI::VtxMap::Cell::Cell
Cell(size_t id, const KDPoint< double, 3 > &p, std::vector< const WrkVrt * > &&v)
Definition: VtxMap.h:69
dbg::ptr
void * ptr(T *p)
Definition: SGImplSvc.cxx:74
const
bool const RAWDATA *ch2 const
Definition: LArRodBlockPhysicsV0.cxx:560
x
#define x
TrigVSI::VtxPack::nVtx
size_t nVtx()
Return the number of vertices.
Definition: IWrkVrt.h:91
TrigVSI::VtxMap::isInMapVolume
bool isInMapVolume(const KDPoint< double, 3 > &) const
Check if the point is inside the map volume.
Definition: VtxMap.h:217
TrigVSI::VtxMap::CellCluster::x2
double x2() const
Definition: VtxMap.h:135
TrigVSI::VtxPack::getWeight
double getWeight()
Return the weight of the container.
Definition: IWrkVrt.h:93
TrigVSI::VtxMap::VtxMap
VtxMap()
Definition: VtxMap.h:45
CxxUtils::vec
typename vecDetail::vec_typedef< T, N >::type vec
Define a nice alias for the vectorized type.
Definition: vec.h:207
TrigVSI::VtxMap::Cell
The class of a cell in 3D histogram.
Definition: VtxMap.h:58
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:209
TrigVSI::VtxMap::CellCluster::x1
double x1() const
Definition: VtxMap.h:134
TrigVSI::Coordinate::is_coord
===========================================================================
Definition: TrigTools/TrigVrtSecInclusive/TrigVrtSecInclusive/Coordinate.h:117
TrigVSI::VtxMap::getClustersBin
std::vector< Cluster< int > > getClustersBin() const
Return a copy of list of clusters consist of bin ID.
Definition: VtxMap.h:184
TrigVSI::VtxMap::CellCluster::PosVect
TVector3 PosVect() const
Definition: VtxMap.h:145
TrigVSI::VtxMap::Cell::Cell
Cell(size_t id, const KDPoint< double, 3 > &p, const WrkVrt *vtx_ptr)
Definition: VtxMap.h:70
z
#define z
TrigVSI::VtxMap::Cell::Cell
Cell(size_t id, const KDPoint< double, 3 > &p)
Definition: VtxMap.h:71
vector
Definition: MultiHisto.h:13
TrigVSI::VtxMap::nClusters
size_t nClusters() const
Return the number of the clusters.
Definition: VtxMap.h:186
TrigVSI::VtxMap::getCluster
CellCluster getCluster(size_t)
Retrieve clustering result as CellCluster object.
Definition: VtxMap.h:418
TrigVSI::VtxMap::getVtxNum
int getVtxNum(double, double, double) const
Count vertex number in the cell at the given position.
Definition: VtxMap.h:261
Coordinate.h
Coordinate policies.
TrigVSI::VtxMap::Cell::getPosVect
TVector3 getPosVect() const
Return center position in TVector3.
Definition: VtxMap.h:80
TrigVSI::VtxMap::VtxMap
VtxMap(std::unique_ptr< TH3D > &&uptr)
Definition: VtxMap.h:44
DeMoUpdate.tmp
string tmp
Definition: DeMoUpdate.py:1167
TrigVSI::VtxMap::ClusterizeCells
void ClusterizeCells(double, size_t)
Generate clusters.
Definition: VtxMap.h:340
TrigVSI::VtxMap::m_dbscan
DBScan< int > m_dbscan
Definition: VtxMap.h:199
TrigVSI::VtxMap::m_mapHist
std::unique_ptr< TH3D > m_mapHist
Definition: VtxMap.h:195
TrigVSI::VtxMap::CellCluster::emplace_back
void emplace_back(const WrkVrt *)=delete
Vertex cannot be added after initialization.
id
SG::auxid_t id
Definition: Control/AthContainers/Root/debug.cxx:239
TrigVSI::VtxMap::m_cellVtxDict
std::unordered_map< int, Cell > m_cellVtxDict
Definition: VtxMap.h:197
TrigVSI::VtxMap
The vertex map class to be used to find multi-track vertices.
Definition: VtxMap.h:38
TrigVSI::KDPoint::setWeight
void setWeight(double w)
Set the weight to given value.
Definition: KDPoint.h:133
TrigVSI::VtxMap::CellCluster::x3
double x3() const
Definition: VtxMap.h:136
TrigVSI::VtxPack::m_vtxLists
std::vector< const WrkVrt * > m_vtxLists
Definition: IWrkVrt.h:100
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:16
TrigVSI::KDPoint< double, 3 >
TrigVSI::VtxMap::CellCluster::y
double y() const
Definition: VtxMap.h:143
KDPoint.h
point classes for clustering
TrigVSI::VtxMap::CellCluster::z
double z() const
Definition: VtxMap.h:144
python.PyAthena.v
v
Definition: PyAthena.py:154
TrigVSI::VtxMap::Reset
void Reset()
Reset vertex map hist, cell list and vertex list.
Definition: VtxMap.h:172
TrigVSI::VtxMap::Cell::Cell
Cell(size_t id, const KDPoint< double, 3 > &p, std::vector< const WrkVrt * > &v)
Constructor.
Definition: VtxMap.h:68
y
#define y
TrigVSI::VtxMap::Cell::getPosPoint
KDPoint< double, 3 > getPosPoint()
Return center position as a KDPoint in specified coordinate.
Definition: VtxMap.h:77
TrigVSI::DBScan::nClusters
size_t nClusters() const
Definition: DBScan.h:54
TrigVSI::VtxMap::CellCluster::m_posAvr
KDPoint< double, 3 > m_posAvr
Definition: VtxMap.h:145
TrigVSI::VtxMap::unlock
void unlock()
Unlock the map. Not recomended.
Definition: VtxMap.h:169
IWrkVrt.h
private
#define private
Definition: xAODTruthCnvAlg.h:20
TrigVSI::VtxMap::VtxMap
VtxMap(TH3D *ptr)
Definition: VtxMap.h:43
TrigVSI::VtxMap::Cell::m_pos
KDPoint< double, 3 > m_pos
Definition: VtxMap.h:84
python.IoTestsLib.w
def w
Definition: IoTestsLib.py:198
TrigVSI::VtxMap::getBinCenter
KDPoint< double, 3 > getBinCenter(int) const
Get bin center position in KDPoint with specified coordinate.
Definition: VtxMap.h:273
TrigVSI::VtxPack::updateLists
void updateLists()
Update set of tracks and incompatible track pair list.
Definition: IWrkVrt.h:117
TrigVSI::VtxMap::CellCluster
Stores the result of vertex clustering performed in VtxMap.
Definition: VtxMap.h:95
TrigVSI
Definition: TrigVrtSecInclusive.cxx:27
TrigVSI::VtxMap::CellCluster::m_posAvrVec
TVector3 m_posAvrVec
Definition: VtxMap.h:150