ATLAS Offline Software
Loading...
Searching...
No Matches
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
26namespace TrigVSI{
27
28//========================================================================
37template<typename WrkVrt, typename Cord>
38class 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(){};
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;
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
216template<typename WrkVrt, typename Cord>
218{
219 return VtxMap<WrkVrt,Cord>::isInMapVolume(point[0], point[1], point[2]);
220}
221
222
230template<typename WrkVrt, typename Cord>
231bool 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
246template<typename WrkVrt, typename Cord>
247bool 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
260template<typename WrkVrt, typename Cord>
261int 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
272template<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
291template<typename WrkVrt, typename Cord>
292void 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
305template<typename WrkVrt, typename Cord>
306void 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
339template<typename WrkVrt, typename Cord>
340void 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
355template<typename WrkVrt, typename Cord>
356std::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
400template<typename WrkVrt, typename Cord>
401std::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
417template<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
std::vector< size_t > vec
Clustering algorithm for vertex merging based on DBSCAN.
point classes for clustering
Coordinate policies.
#define y
#define x
#define z
Base class for clusters.
Definition DBScan.h:24
size_t nPoints() const
Definition DBScan.h:31
Class for operating DBSCAN clustering.
Definition DBScan.h:43
std::function< std::vector< pointType >(const pointType &, double)> RegionFunc
Function type for region query function.
Definition DBScan.h:45
Class for k-dimensional point.
Definition KDPoint.h:29
Stores the result of vertex clustering performed in VtxMap.
Definition VtxMap.h:95
KDPoint< double, 3 > m_posAvr
Definition VtxMap.h:149
const KDPoint< double, 3 > & PosCoord() const
Definition VtxMap.h:137
CellCluster(std::vector< Cell * > &&v)
Constructor.
Definition VtxMap.h:103
size_t nCells() const
Definition VtxMap.h:130
TVector3 PosVect() const
Definition VtxMap.h:145
void emplace_back(const WrkVrt *)=delete
Vertex cannot be added after initialization.
The class of a cell in 3D histogram.
Definition VtxMap.h:58
Cell(size_t id, const KDPoint< double, 3 > &p)
Definition VtxMap.h:71
Cell(size_t id, const KDPoint< double, 3 > &p, std::vector< const WrkVrt * > &&v)
Definition VtxMap.h:69
TVector3 getPosVect() const
Return center position in TVector3.
Definition VtxMap.h:80
KDPoint< double, 3 > m_pos
Definition VtxMap.h:84
Cell(size_t id, const KDPoint< double, 3 > &p, std::vector< const WrkVrt * > &v)
Constructor.
Definition VtxMap.h:68
KDPoint< double, 3 > getPosPoint()
Return center position as a KDPoint in specified coordinate.
Definition VtxMap.h:77
Cell(size_t id, const KDPoint< double, 3 > &p, const WrkVrt *vtx_ptr)
Definition VtxMap.h:70
The vertex map class to be used to find multi-track vertices.
Definition VtxMap.h:38
size_t nClusters() const
Return the number of the clusters.
Definition VtxMap.h:186
std::unique_ptr< TH3D > m_mapHist
Definition VtxMap.h:195
void ClusterizeCells(double, size_t)
Generate clusters.
Definition VtxMap.h:340
std::vector< const WrkVrt * > getVtxInCluster(size_t)
Retrieve list of vertices in i-th cluster.
Definition VtxMap.h:401
std::unordered_map< int, Cell > m_cellVtxDict
Definition VtxMap.h:197
VtxMap(std::unique_ptr< TH3D > &&uptr)
Definition VtxMap.h:44
void Reset()
Reset vertex map hist, cell list and vertex list.
Definition VtxMap.h:172
int getVtxNum(double, double, double) const
Count vertex number in the cell at the given position.
Definition VtxMap.h:261
DBScan< int > m_dbscan
Definition VtxMap.h:199
KDPoint< double, 3 > getBinCenter(int) const
Get bin center position in KDPoint with specified coordinate.
Definition VtxMap.h:273
VtxMap & operator=(VtxMap &&)=default
Move assignment operator.
CellCluster getCluster(size_t)
Retrieve clustering result as CellCluster object.
Definition VtxMap.h:418
std::vector< Cluster< int > > getClustersBin() const
Return a copy of list of clusters consist of bin ID.
Definition VtxMap.h:184
VtxMap(TH3D *ptr)
Definition VtxMap.h:43
std::vector< int > getNeighborCells_(const int &, double)
Region query function to be passed to DBScan.
Definition VtxMap.h:356
void unlock()
Unlock the map. Not recomended.
Definition VtxMap.h:169
void lock()
Lock the map to prevent adding vertex after clustering.
Definition VtxMap.h:167
bool isInMapVolume(const KDPoint< double, 3 > &) const
Check if the point is inside the map volume.
Definition VtxMap.h:217
VtxMap(VtxMap &&)=default
void Fill(const WrkVrt *)
Fill vertex map with vertex from its pointer.
Definition VtxMap.h:306
std::unordered_set< int > m_activeCells
Definition VtxMap.h:196
std::vector< const WrkVrt * > m_vtxLists
Definition IWrkVrt.h:100
VtxPack(std::vector< const WrkVrt * > &v)
Constructor.
Definition IWrkVrt.h:62
size_t nVtx()
Return the number of vertices.
Definition IWrkVrt.h:91
void updateLists()
Update set of tracks and incompatible track pair list.
Definition IWrkVrt.h:117
double getWeight()
Return the weight of the container.
Definition IWrkVrt.h:93
STL class.
STL namespace.
#define private