ATLAS Offline Software
VtxMap.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 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 "TMath.h"
19 #include "TVector3.h"
20 #include "TH3D.h"
21 
22 #include <iostream>
23 #include <deque>
24 #include <unordered_set>
25 #include <vector>
26 #include <functional>
27 
28 namespace TrigVSI{
29 
30 //========================================================================
39 template<typename WrkVrt, typename Cord>
40 class VtxMap {
41  static_assert(std::is_base_of<TrigVSI::IWrkVrt, WrkVrt>::value, "WrkVrt must be derived from IWrkVrt.");
42  static_assert(Coordinate::is_coord<Cord>::value, "Coord must define static methods for a coordinate system.");
43 
44  public :
45  VtxMap(TH3D* ptr) : m_mapHist( std::unique_ptr<TH3D>(ptr) ){};
46  VtxMap(std::unique_ptr<TH3D>&& uptr) : m_mapHist( std::move(uptr) ){};
47  VtxMap(){};
48  ~VtxMap(){};
49 
51  VtxMap& operator= (VtxMap&&) = default;
52  VtxMap(VtxMap&&) = default;
53 
54 
55  //========================================================================
60  class Cell : public VtxPack<WrkVrt> {
61  public :
70  Cell(size_t id, KDPoint<double, 3> p, std::vector<const WrkVrt*>& v) : VtxPack<WrkVrt>(v), m_id(id), m_pos(p) {};
71  Cell(size_t id, KDPoint<double, 3> p, std::vector<const WrkVrt*>&& v) : VtxPack<WrkVrt>(v), m_id(id), m_pos(p) {};
72  Cell(size_t id, KDPoint<double, 3> p, const WrkVrt* vtx_ptr) : VtxPack<WrkVrt>( std::vector<const WrkVrt*>{vtx_ptr} ), m_id(id), m_pos(p) {};
73  Cell(size_t id, KDPoint<double, 3> p) : m_id(id), m_pos(p) {};
74  Cell(){};
75 
76  inline int getId(){ return m_id; };
77 
79  inline KDPoint<double, 3> getPosPoint() { m_pos.setWeight(this->getWeight()); return m_pos; };
80 
82  inline TVector3 getPosVect() const { return Cord::X123toXYZ(m_pos); };
83 
84  private :
85  int m_id = -1;
87  };
88 
89 
90  //========================================================================
97  class CellCluster : public Cluster<Cell*>, public VtxPack<WrkVrt> {
98  public :
105  CellCluster(std::vector<Cell*>&& v) : Cluster<Cell*>(v)
106  {
107  size_t n_vtx = 0;
108  for ( auto& cell_ptr : v ) n_vtx += cell_ptr->nVtx();
109  std::vector<const WrkVrt*> tmp_vtx_cls;
110  tmp_vtx_cls.reserve(n_vtx);
111 
112  double w = 0.;
113  TVector3 tmp_vec(0.,0.,0.);
114  for ( auto& cell_ptr : v ) {
115  std::vector<const WrkVrt*> tmp_vtx_cell = cell_ptr->getVtxList();
116  tmp_vtx_cls.insert( tmp_vtx_cls.end(), tmp_vtx_cell.begin(), tmp_vtx_cell.end() );
117 
118  tmp_vec += cell_ptr->getWeight() * cell_ptr->getPosVect();
119  w += cell_ptr->getWeight();
120  }
121  this->m_vtxLists = std::move(tmp_vtx_cls);
122  this->updateLists();
123 
124  this->m_posAvrVec = (1. / w) * tmp_vec;
125  this->m_posAvr = Cord::XYZtoX123(this->m_posAvrVec);
126  this->m_posAvr.setWeight(w);
127  };
128 
130  inline void emplace_back(const WrkVrt*) = delete;
131 
132  inline size_t nCells() const { return this->nPoints(); };
133 
136  inline double x1() const { return m_posAvr.at(0); };
137  inline double x2() const { return m_posAvr.at(1); };
138  inline double x3() const { return m_posAvr.at(2); };
139  inline KDPoint<double,3> PosCoord() const { return m_posAvr; };
141 
144  inline double x() const { return m_posAvrVec.x(); };
145  inline double y() const { return m_posAvrVec.y(); };
146  inline double z() const { return m_posAvrVec.z(); };
147  inline TVector3 PosVect() const { return m_posAvrVec; };
149 
150  private :
152  TVector3 m_posAvrVec;
153  };
154 
155 
156  //
157  // Public member functions
158  //_________________________________________________________________________
159  void Fill(const WrkVrt*);
160 
161  inline bool isInMapVolume(const KDPoint<double, 3>&) const;
162  inline bool isInMapVolume(double, double, double) const;
163  inline bool isInMapVolume(int, int, int) const;
164  inline KDPoint<double, 3> getBinCenter(int) const;
165 
166  inline int getVtxNum(double, double, double) const;
167 
169  inline void lock() { m_locked = true; };
171  inline void unlock() { m_locked = false; };
172 
174  inline void Reset()
175  {
176  m_mapHist->Reset();
177  m_activeCells.clear();
178  m_cellVtxDict.clear();
179  m_locked = false;
180  m_dbscan = DBScan<int>();
181  }
182 
183  void ClusterizeCells(double, size_t);
184 
186  inline std::vector<Cluster<int>> getClustersBin() const { return m_dbscan.getClusters(); };
188  inline size_t nClusters() const { return m_dbscan.nClusters(); };
189 
190  CellCluster getCluster(size_t);
191  std::vector<const WrkVrt*> getVtxInCluster(size_t);
192 
193  private :
194  //
195  // Private member variables
196  //_________________________________________________________________________
197  std::unique_ptr<TH3D> m_mapHist;
198  std::unordered_set<int> m_activeCells;
199  std::unordered_map<int, Cell> m_cellVtxDict;
200  bool m_locked = false;
202 
203  //
204  // Private member functions
205  //_________________________________________________________________________
206  void Fill(double, double, double);
207  std::vector<int> getNeighborCells_(const int&, double);
208 
209 };
210 
211 
212 
218 template<typename WrkVrt, typename Cord>
220 {
221  return VtxMap<WrkVrt,Cord>::isInMapVolume(point[0], point[1], point[2]);
222 }
223 
224 
232 template<typename WrkVrt, typename Cord>
233 bool VtxMap<WrkVrt,Cord>::isInMapVolume(double x1, double x2, double x3) const
234 {
235  if ( m_mapHist->GetXaxis()->FindFixBin(x1) < 1 || m_mapHist->GetXaxis()->FindFixBin(x1) > m_mapHist->GetNbinsX() ) return false;
236  if ( m_mapHist->GetYaxis()->FindFixBin(x2) < 1 || m_mapHist->GetYaxis()->FindFixBin(x2) > m_mapHist->GetNbinsY() ) return false;
237  if ( m_mapHist->GetZaxis()->FindFixBin(x3) < 1 || m_mapHist->GetZaxis()->FindFixBin(x3) > m_mapHist->GetNbinsZ() ) return false;
238  return true;
239 }
240 
241 
248 template<typename WrkVrt, typename Cord>
249 bool VtxMap<WrkVrt,Cord>::isInMapVolume(int ibinx, int ibiny, int ibinz) const
250 {
251  if ( ibinx < 1 || ibinx > m_mapHist->GetNbinsX() ) return false;
252  if ( ibiny < 1 || ibiny > m_mapHist->GetNbinsY() ) return false;
253  if ( ibinz < 1 || ibinz > m_mapHist->GetNbinsZ() ) return false;
254  return true;
255 }
256 
257 
262 template<typename WrkVrt, typename Cord>
263 int VtxMap<WrkVrt,Cord>::getVtxNum(double x, double y, double z) const
264 {
265  if ( !isInMapVolume(x, y, z) ) return -1;
266  int ibin = m_mapHist->FindFixBin(x, y, z);
267  return m_mapHist->GetBinContent(ibin);
268 }
269 
270 
274 template<typename WrkVrt, typename Cord>
276 {
277  int xbin; int ybin; int zbin;
278  m_mapHist->GetBinXYZ(ibin, xbin, ybin, zbin);
279  double x = m_mapHist->GetXaxis()->GetBinCenter(xbin);
280  double y = m_mapHist->GetYaxis()->GetBinCenter(ybin);
281  double z = m_mapHist->GetZaxis()->GetBinCenter(zbin);
282 
283  KDPoint<double, 3> pos_tmp({x,y,z});
284  return pos_tmp;
285 }
286 
287 
293 template<typename WrkVrt, typename Cord>
294 void VtxMap<WrkVrt,Cord>::Fill(double x, double y, double z)
295 {
296  if (m_locked) return;
297  m_mapHist->Fill(x, y, z);
298  m_activeCells.emplace( m_mapHist->FindFixBin(x, y, z) );
299 }
300 
301 
307 template<typename WrkVrt, typename Cord>
308 void VtxMap<WrkVrt,Cord>::Fill( const WrkVrt* vtx_ptr )
309 {
310  if (m_locked) return;
311 
312  // Get position of vertex with projection to map region.
313  TVector3 vec( vtx_ptr->x(), vtx_ptr->y(), vtx_ptr->z() );
314  KDPoint<double,3> pos = Cord::Proj( Cord::XYZtoX123(vec) );
315  double x = pos[0];
316  double y = pos[1];
317  double z = pos[2];
318 
319  if ( !isInMapVolume(x,y,z) ) return;
320 
321  Fill(x,y,z);
322 
323  size_t ibin = m_mapHist->FindFixBin(x, y, z);
324  auto cell_itr = m_cellVtxDict.find( ibin );
325  if ( cell_itr != m_cellVtxDict.end() && cell_itr->second.getId() == static_cast<int>(ibin) ) {
326  cell_itr->second.emplace_back( vtx_ptr );
327  }
328  else {
329  m_cellVtxDict.emplace( ibin, Cell(ibin, getBinCenter(ibin), vtx_ptr) );
330  }
331 }
332 
333 
341 template<typename WrkVrt, typename Cord>
342 void VtxMap<WrkVrt,Cord>::ClusterizeCells(double eps, size_t minN)
343 {
344  m_locked = true;
345  DBScan<int>::RegionFunc region_query = [this](const int& glob_bin, double eps)
346  {
347  return getNeighborCells_(glob_bin, eps);
348  };
349  m_dbscan = DBScan<int>(m_activeCells, region_query);
350  m_dbscan.clusterize(eps, minN);
351 }
352 
353 
357 template<typename WrkVrt, typename Cord>
358 std::vector<int> VtxMap<WrkVrt,Cord>::getNeighborCells_(const int& glob_bin, double eps)
359 {
360  std::vector<int> tmp;
361  int d = static_cast<int>(eps);
362 
363  int binx = 0;
364  int biny = 0;
365  int binz = 0;
366  m_mapHist->GetBinXYZ(glob_bin, binx, biny, binz);
367 
368  KDPoint<int,3> v_ibin;
369 
370  if ( !(isInMapVolume(binx, biny, binz)) ) return tmp;
371 
372  for (int ix = binx - d; ix <= binx + d; ix++) {
373  for (int iy = biny - d; iy <= biny + d; iy++) {
374  for (int iz = binz - d; iz <= binz + d; iz++) {
375  //
376  v_ibin[0] = ix; v_ibin[1] = iy; v_ibin[2] = iz;
377 
378  // Convert coordinate with projection function
379  v_ibin = Cord::ProjBin(v_ibin, m_mapHist);
380 
381  // If current cell is self, skip it.
382  if ( v_ibin[0] == binx && v_ibin[1] == biny && v_ibin[2] == binz ) continue;
383 
384  // If cerrent cell is not in map volme, skip it.
385  if ( !(isInMapVolume(v_ibin[0], v_ibin[1], v_ibin[2])) ) continue;
386 
387  // If there is no entry in current cell, skip it.
388  if ( m_mapHist->GetBinContent(m_mapHist->GetBin(v_ibin[0], v_ibin[1], v_ibin[2])) < 1. ) continue;
389  tmp.emplace_back(m_mapHist->GetBin(v_ibin[0], v_ibin[1], v_ibin[2]));
390  //
391  }
392  }
393  }
394  //
395  return tmp;
396 }
397 
398 
402 template<typename WrkVrt, typename Cord>
403 std::vector<const WrkVrt*> VtxMap<WrkVrt,Cord>::getVtxInCluster(size_t icls)
404 {
405  Cluster<int> cls = m_dbscan.getClusters().at(icls);
406 
407  std::vector<const WrkVrt*> v_tmp;
408  for (const auto& ibin : cls.Points()) {
409  std::vector<const WrkVrt*> v_vtx = m_cellVtxDict[ibin].getVtxList();
410  v_tmp.insert( v_tmp.end(), v_vtx.begin(), v_vtx.end() );
411  }
412  return v_tmp;
413 }
414 
415 
419 template<typename WrkVrt, typename Cord>
421 {
422  const Cluster<int>& cls = m_dbscan.getCluster(icls);
423  std::vector<Cell*> v_tmp;
424 
425  std::vector<int> cell_ids = cls.getPoints();
426  for (const auto ibin : cell_ids) {
427  Cell& cell = m_cellVtxDict[ibin];
428  if ( ibin != cell.getId() ) continue;
429  v_tmp.emplace_back( &cell );
430  }
431  VtxMap<WrkVrt,Cord>::CellCluster cls_tmp( std::move(v_tmp) );
432  return cls_tmp;
433 }
434 
435 
437 
438 } // end of namespace TrigVSI
439 
440 #endif
plotBeamSpotCompare.x1
x1
Definition: plotBeamSpotCompare.py:216
TrigVSI::VtxMap::Cell::m_id
int m_id
Definition: VtxMap.h:85
TrigVSI::VtxMap::Cell::getId
int getId()
Definition: VtxMap.h:76
ReadCellNoiseFromCool.cell
cell
Definition: ReadCellNoiseFromCool.py:53
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
TrigVSI::VtxMap::CellCluster::x
double x() const
Definition: VtxMap.h:144
TrigVSI::VtxMap::CellCluster::PosCoord
KDPoint< double, 3 > PosCoord() const
Definition: VtxMap.h:139
TrigVSI::VtxMap::operator=
VtxMap & operator=(VtxMap &&)=default
Move assignment operator.
TH3D
Definition: rootspy.cxx:505
TrigVSI::VtxPack
Base class of local vertex container in VtxMap.
Definition: IWrkVrt.h:56
TrigVSI::VtxMap::m_locked
bool m_locked
Definition: VtxMap.h:200
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:132
hist_file_dump.d
d
Definition: hist_file_dump.py:137
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:74
plotBeamSpotCompare.x2
x2
Definition: plotBeamSpotCompare.py:218
TrigVSI::DBScan< int >
TrigVSI::VtxMap::m_activeCells
std::unordered_set< int > m_activeCells
Definition: VtxMap.h:198
TrigVSI::VtxMap::CellCluster::CellCluster
CellCluster(std::vector< Cell * > &&v)
Constructor.
Definition: VtxMap.h:105
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:169
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:403
TrigVSI::VtxMap::Fill
void Fill(const WrkVrt *)
Fill vertex map with vertex from its pointer.
Definition: VtxMap.h:308
TrigVSI::VtxMap::VtxMap
VtxMap(VtxMap &&)=default
athena.value
value
Definition: athena.py:122
TrigVSI::VtxMap::~VtxMap
~VtxMap()
Definition: VtxMap.h:48
vec
std::vector< size_t > vec
Definition: CombinationsGeneratorTest.cxx:12
TrigVSI::VtxMap::getNeighborCells_
std::vector< int > getNeighborCells_(const int &, double)
Region query function to be passed to DBScan.
Definition: VtxMap.h:358
const
bool const RAWDATA *ch2 const
Definition: LArRodBlockPhysicsV0.cxx:562
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:219
TrigVSI::VtxMap::CellCluster::x2
double x2() const
Definition: VtxMap.h:137
TrigVSI::VtxPack::getWeight
double getWeight()
Return the weight of the container.
Definition: IWrkVrt.h:93
TrigVSI::VtxMap::VtxMap
VtxMap()
Definition: VtxMap.h:47
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:60
TrigVSI::VtxMap::CellCluster::x1
double x1() const
Definition: VtxMap.h:136
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:186
TrigVSI::VtxMap::CellCluster::PosVect
TVector3 PosVect() const
Definition: VtxMap.h:147
z
#define z
vector
Definition: MultiHisto.h:13
TrigVSI::VtxMap::nClusters
size_t nClusters() const
Return the number of the clusters.
Definition: VtxMap.h:188
TrigVSI::VtxMap::getCluster
CellCluster getCluster(size_t)
Retrieve clustering result as CellCluster object.
Definition: VtxMap.h:420
TrigVSI::VtxMap::getVtxNum
int getVtxNum(double, double, double) const
Count vertex number in the cell at the given position.
Definition: VtxMap.h:263
Coordinate.h
Coordinate policies.
TrigVSI::VtxMap::Cell::getPosVect
TVector3 getPosVect() const
Return center position in TVector3.
Definition: VtxMap.h:82
TrigVSI::VtxMap::Cell::Cell
Cell(size_t id, KDPoint< double, 3 > p)
Definition: VtxMap.h:73
TrigVSI::VtxMap::VtxMap
VtxMap(std::unique_ptr< TH3D > &&uptr)
Definition: VtxMap.h:46
DeMoUpdate.tmp
string tmp
Definition: DeMoUpdate.py:1167
TrigVSI::VtxMap::ClusterizeCells
void ClusterizeCells(double, size_t)
Generate clusters.
Definition: VtxMap.h:342
TrigVSI::VtxMap::m_dbscan
DBScan< int > m_dbscan
Definition: VtxMap.h:201
TrigVSI::VtxMap::m_mapHist
std::unique_ptr< TH3D > m_mapHist
Definition: VtxMap.h:197
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:194
private
#define private
Definition: DetDescrConditionsDict_dict_fixes.cxx:13
TrigVSI::VtxMap::m_cellVtxDict
std::unordered_map< int, Cell > m_cellVtxDict
Definition: VtxMap.h:199
TrigVSI::VtxMap
The vertex map class to be used to find multi-track vertices.
Definition: VtxMap.h:40
TrigVSI::KDPoint::setWeight
void setWeight(double w)
Set the weight to given value.
Definition: KDPoint.h:133
TrigVSI::VtxMap::Cell::Cell
Cell(size_t id, KDPoint< double, 3 > p, std::vector< const WrkVrt * > &&v)
Definition: VtxMap.h:71
TrigVSI::VtxMap::CellCluster::x3
double x3() const
Definition: VtxMap.h:138
TrigVSI::VtxPack::m_vtxLists
std::vector< const WrkVrt * > m_vtxLists
Definition: IWrkVrt.h:100
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
TrigVSI::KDPoint< double, 3 >
TrigVSI::VtxMap::CellCluster::y
double y() const
Definition: VtxMap.h:145
KDPoint.h
point classes for clustering
TrigVSI::VtxMap::CellCluster::z
double z() const
Definition: VtxMap.h:146
python.PyAthena.v
v
Definition: PyAthena.py:157
TrigVSI::VtxMap::Reset
void Reset()
Reset vertex map hist, cell list and vertex list.
Definition: VtxMap.h:174
y
#define y
TrigVSI::VtxMap::Cell::getPosPoint
KDPoint< double, 3 > getPosPoint()
Return center position as a KDPoint in specified coordinate.
Definition: VtxMap.h:79
TrigVSI::DBScan::nClusters
size_t nClusters() const
Definition: DBScan.h:54
TrigVSI::VtxMap::CellCluster::m_posAvr
KDPoint< double, 3 > m_posAvr
Definition: VtxMap.h:147
TrigVSI::VtxMap::unlock
void unlock()
Unlock the map. Not recomended.
Definition: VtxMap.h:171
IWrkVrt.h
TrigVSI::VtxMap::VtxMap
VtxMap(TH3D *ptr)
Definition: VtxMap.h:45
TrigVSI::VtxMap::Cell::m_pos
KDPoint< double, 3 > m_pos
Definition: VtxMap.h:86
python.IoTestsLib.w
def w
Definition: IoTestsLib.py:200
TrigVSI::VtxMap::getBinCenter
KDPoint< double, 3 > getBinCenter(int) const
Get bin center position in KDPoint with specified coordinate.
Definition: VtxMap.h:275
TrigVSI::VtxMap::Cell::Cell
Cell(size_t id, KDPoint< double, 3 > p, std::vector< const WrkVrt * > &v)
Constructor.
Definition: VtxMap.h:70
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:97
TrigVSI::VtxMap::Cell::Cell
Cell(size_t id, KDPoint< double, 3 > p, const WrkVrt *vtx_ptr)
Definition: VtxMap.h:72
TrigVSI
Definition: TrigVrtSecInclusive.cxx:27
TrigVSI::VtxMap::CellCluster::m_posAvrVec
TVector3 m_posAvrVec
Definition: VtxMap.h:152