Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AmbiguityDBScanClustering.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file AmbiguityDBScanClustering.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2023 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 #pragma once
10 
13 
14 #include <map>
15 #include <unordered_map>
16 #include <vector>
17 
18 #include "mlpack/methods/dbscan.hpp"
19 
20 namespace Acts {
21 
29 template <typename track_container_t, typename traj_t,
30  template <typename> class holder_t>
31 std::unordered_map<int, std::vector<int>> dbscanTrackClustering(
32  std::multimap<int, std::pair<int, std::vector<int>>>& trackMap,
34  float epsilon = 0.07, int minPoints = 2) {
35  // Unordered map associating a vector with all the track ID of a cluster to
36  // the ID of the first track of the cluster
37  std::unordered_map<int, std::vector<int>> cluster;
38  // Unordered map associating hits to the ID of the first track of the
39  // different clusters.
40  std::unordered_map<int, int> hitToTrack;
41 
42  // DBSCAN algorithm from MLpack used in the track clustering
43  mlpack::DBSCAN dbscan(epsilon, minPoints);
44 
45  arma::mat data(2, trackMap.size());
46  int trackID = 0;
47  arma::Row<size_t> assignments;
48 
49  // Get the input feature of the network for all the tracks
50  for (const auto& [key, val] : trackMap) {
51  auto traj = tracks.getTrack(val.first);
52  data(0, trackID) = Acts::VectorHelpers::eta(traj.momentum());
53  data(1, trackID) = Acts::VectorHelpers::phi(traj.momentum());
54  trackID++;
55  }
56  size_t clusterNb = dbscan.Cluster(data, assignments);
57  trackID = 0;
58 
59  // Cluster track with DBScan
60  std::vector<std::multimap<int, std::pair<int, std::vector<int>>>>
61  dbscanClusters(clusterNb);
62  for (const auto& [key, val] : trackMap) {
63  int clusterID = assignments(trackID);
64  if (assignments(trackID) == SIZE_MAX) {
65  cluster.emplace(val.first, std::vector<int>(1, val.first));
66  } else {
67  dbscanClusters[clusterID].emplace(key, val);
68  }
69  trackID++;
70  }
71 
72  // Perform a subClustering of the DBScan cluster using the measurement ID
73  // clustering
74  for (const auto& dbscanCluster : dbscanClusters) {
75  auto subCluster = Acts::detail::clusterDuplicateTracks(dbscanCluster);
76  cluster.merge(subCluster);
77  if (!subCluster.empty()) {
78  std::cout << "Overlapping track ID, there must be an error" << std::endl;
79  }
80  }
81  return cluster;
82 }
83 
84 } // namespace Acts