diff --git a/Detectors/ITSMFT/ITS/tracking/CMakeLists.txt b/Detectors/ITSMFT/ITS/tracking/CMakeLists.txt index 7315b166edf54..6e976bfeb5d02 100644 --- a/Detectors/ITSMFT/ITS/tracking/CMakeLists.txt +++ b/Detectors/ITSMFT/ITS/tracking/CMakeLists.txt @@ -13,8 +13,6 @@ o2_add_library(ITStracking SOURCES src/ClusterLines.cxx src/Cluster.cxx src/ROframe.cxx - src/Graph.cxx - src/DBScan.cxx src/IOUtils.cxx src/Label.cxx src/PrimaryVertexContext.cxx @@ -37,7 +35,6 @@ o2_add_library(ITStracking o2_target_root_dictionary(ITStracking HEADERS include/ITStracking/ClusterLines.h include/ITStracking/Tracklet.h - include/ITStracking/DBScan.h include/ITStracking/TrackingConfigParam.h LINKDEF src/TrackingLinkDef.h) diff --git a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/DBScan.h b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/DBScan.h deleted file mode 100644 index 1e8d16b42bdea..0000000000000 --- a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/DBScan.h +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright CERN and copyright holders of ALICE O2. This software is -// distributed under the terms of the GNU General Public License v3 (GPL -// Version 3), copied verbatim in the file "COPYING". -// -// See http://alice-o2.web.cern.ch/license for full licensing information. -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. -/// -/// \file DBScan.h -/// \brief -/// - -#ifndef O2_ITS_TRACKING_DBSCAN_H_ -#define O2_ITS_TRACKING_DBSCAN_H_ - -#include -#include "ITStracking/Graph.h" - -namespace o2 -{ -namespace its -{ - -typedef std::pair State; - -template -class DBScan : Graph -{ - public: - DBScan() = delete; - explicit DBScan(const size_t nThreads); - void init(std::vector&, std::function); - void classifyVertices(const int); - void classifyVertices(std::function&)> classFunction); - void classifyVertices(std::function&)> classFunction, std::function sortFunction); - std::vector getStates() const { return mStates; } - std::vector getCores(); - std::vector> computeClusters(); - - private: - std::vector mStates; - std::function&)> mClassFunction; -}; - -template -DBScan::DBScan(const size_t nThreads) : Graph(nThreads) -{ -} - -template -void DBScan::init(std::vector& vertices, std::function discFunction) -{ - this->Graph::init(vertices); - this->Graph::computeEdges(discFunction); -} - -template -void DBScan::classifyVertices(const int nContributors) -{ - classifyVertices([nContributors](std::vector& edges) { return edges.size() == 0 ? 0 : edges.size() >= static_cast(nContributors - 1) ? 2 : 1; }, - [](State& s1, State& s2) { return static_cast(s1.second) > static_cast(s2.second); }); -} - -template -void DBScan::classifyVertices(std::function& edges)> classFunction) -{ - mClassFunction = classFunction; - const size_t size = {this->mVertices->size()}; - mStates.resize(size); - - if (!this->isMultiThreading()) { - for (size_t iVertex{0}; iVertex < size; ++iVertex) { - mStates[iVertex] = std::make_pair(iVertex, classFunction(this->getEdges()[iVertex])); - } - } else { - const size_t stride{static_cast(std::ceil(this->mVertices->size() / static_cast(this->mExecutors.size())))}; - for (size_t iExecutor{0}; iExecutor < this->mExecutors.size(); ++iExecutor) { - // We cannot pass a template function to std::thread(), using lambda instead - this->mExecutors[iExecutor] = std::thread( - [iExecutor, stride, this](const auto& classFunction) { - for (size_t iVertex{iExecutor * stride}; iVertex < stride * (iExecutor + 1) && iVertex < this->mVertices->size(); ++iVertex) { - mStates[iVertex] = std::make_pair(iVertex, classFunction(this->getEdges()[iVertex])); - } - }, - mClassFunction); - } - } - for (auto&& thread : this->mExecutors) { - thread.join(); - } -} - -template -void DBScan::classifyVertices(std::function&)> classFunction, std::function sortFunction) -{ - classifyVertices(classFunction); - std::sort(mStates.begin(), mStates.end(), sortFunction); -} - -template -std::vector DBScan::getCores() -{ - std::vector cores; - std::vector coreIndices; - std::copy_if(mStates.begin(), mStates.end(), std::back_inserter(cores), [](const State& state) { return state.second == 2; }); - std::transform(cores.begin(), cores.end(), std::back_inserter(coreIndices), [](const State& state) -> int { return state.first; }); - return coreIndices; -} - -template -std::vector> DBScan::computeClusters() -{ - std::vector> clusters; - std::vector cores = getCores(); - std::vector usedVertices(this->mVertices->size(), false); - - for (size_t core{0}; core < cores.size(); ++core) { - if (!usedVertices[cores[core]]) { - std::vector clusterFlags = this->getCluster(cores[core]); - std::transform(usedVertices.begin(), usedVertices.end(), clusterFlags.begin(), usedVertices.begin(), std::logical_or<>()); - clusters.emplace_back(std::move(this->getClusterIndices(clusterFlags))); - } - } - return clusters; -} - -struct Centroid final { - Centroid() = default; - Centroid(int* indices, float* position); - void init(); - static float ComputeDistance(const Centroid& c1, const Centroid& c2); - - int mIndices[2]; - float mPosition[3]; -}; - -} // namespace its -} // namespace o2 -#endif \ No newline at end of file diff --git a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/Graph.h b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/Graph.h deleted file mode 100644 index d1fca077e29c6..0000000000000 --- a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/Graph.h +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright CERN and copyright holders of ALICE O2. This software is -// distributed under the terms of the GNU General Public License v3 (GPL -// Version 3), copied verbatim in the file "COPYING". -// -// See http://alice-o2.web.cern.ch/license for full licensing information. -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. -/// -/// \file Graph.h -/// \brief -/// - -#ifndef TRACKINGITSU_INCLUDE_ALGORITHMS_H_ -#define TRACKINGITSU_INCLUDE_ALGORITHMS_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace o2 -{ -namespace its -{ - -typedef int Edge; - -class Barrier -{ - public: - explicit Barrier(std::size_t count) : count(count) {} - void Wait(); - - private: - std::mutex mutex; - std::condition_variable condition; - std::size_t count; -}; - -template -class Graph -{ - public: - Graph() = delete; - explicit Graph(const size_t nThreads = 1); - void init(std::vector&); - std::vector getCluster(const int); - std::vector getClusterIndices(const int); - std::vector getClusterIndices(const std::vector /* , const int*/); - void computeEdges(std::function); - std::vector> getEdges() const { return mEdges; } - char isMultiThreading() const { return mIsMultiThread; } - - std::vector* mVertices = nullptr; // Observer pointer - std::vector mExecutors; // Difficult to pass - - private: - void findVertexEdges(std::vector& localEdges, const T& vertex, const size_t vId, const size_t size); - - // Multithread block - size_t mNThreads; - char mIsMultiThread; - - // Common data members - std::function mLinkFunction; - std::vector> mEdges; - std::vector mVisited; -}; - -template -Graph::Graph(const size_t nThreads) : mNThreads{nThreads} -{ - mIsMultiThread = nThreads > 1 ? true : false; -} - -template -void Graph::init(std::vector& vertices) -{ - - // Graph initialization - mVertices = &vertices; - if (mIsMultiThread) { - mNThreads = std::min(static_cast(std::thread::hardware_concurrency()), mNThreads); - mExecutors.resize(mNThreads); - } - - mEdges.resize(vertices.size()); - mVisited.resize(vertices.size(), false); -} - -template -void Graph::computeEdges(std::function linkFunction) -{ - mLinkFunction = linkFunction; - int tot_nedges = 0; - const size_t size = {mVertices->size()}; - if (!mIsMultiThread) { - for (size_t iVertex{0}; iVertex < size; ++iVertex) { - findVertexEdges(mEdges[iVertex], (*mVertices)[iVertex], iVertex, size); - tot_nedges += static_cast(mEdges[iVertex].size()); - } - } else { - mNThreads = std::min(static_cast(std::thread::hardware_concurrency()), mNThreads); - mExecutors.resize(mNThreads); - const size_t stride{static_cast(std::ceil(mVertices->size() / static_cast(mExecutors.size())))}; - for (size_t iExecutor{0}; iExecutor < mExecutors.size(); ++iExecutor) { - // We cannot pass a template function to std::thread(), using lambda instead - mExecutors[iExecutor] = std::thread( - [iExecutor, stride, this](const auto& linkFunction) { - for (size_t iVertex1{iExecutor * stride}; iVertex1 < stride * (iExecutor + 1) && iVertex1 < mVertices->size(); ++iVertex1) { - for (size_t iVertex2{0}; iVertex2 < mVertices->size(); ++iVertex2) { - if (iVertex1 != iVertex2 && linkFunction((*mVertices)[iVertex1], (*mVertices)[iVertex2])) { - mEdges[iVertex1].emplace_back(iVertex2); - } - } - } - }, - mLinkFunction); - } - } - for (auto&& thread : mExecutors) { - thread.join(); - } -} -template -void Graph::findVertexEdges(std::vector& localEdges, const T& vertex, const size_t vId, const size_t size) -{ - for (size_t iVertex2{0}; iVertex2 < size; ++iVertex2) { - if (vId != iVertex2 && mLinkFunction(vertex, (*mVertices)[iVertex2])) { - localEdges.emplace_back(iVertex2); - } - } -} - -template -std::vector Graph::getCluster(const int vertexId) -{ - // This method uses a BFS algorithm to return all the graph - // vertex ids belonging to a graph - std::vector indices; - std::vector visited(mVertices->size(), false); - - if (!mIsMultiThread) { - std::queue idQueue; - idQueue.emplace(vertexId); - visited[vertexId] = true; - - // Consume the queue - while (!idQueue.empty()) { - const int id = idQueue.front(); - idQueue.pop(); - for (Edge edge : mEdges[id]) { - if (!visited[edge]) { - idQueue.emplace(edge); - indices.emplace_back(edge); - visited[edge] = true; - } - } - } - } else { - const size_t stride{static_cast(std::ceil(static_cast(this->mVertices->size()) / static_cast(this->mExecutors.size())))}; - std::vector frontier(mVertices->size(), false); - std::vector flags(mVertices->size(), false); - - frontier[vertexId] = true; - int counter{0}; - while (std::any_of(frontier.begin(), frontier.end(), [](const char t) { return t; })) { - flags.resize(mVertices->size(), false); - Barrier barrier(mExecutors.size()); - for (size_t iExecutor{0}; iExecutor < this->mExecutors.size(); ++iExecutor) { - mExecutors[iExecutor] = std::thread( - [&stride, &frontier, &visited, &barrier, &flags, this](const int executorId) { - for (size_t iVertex{executorId * stride}; iVertex < stride * (executorId + 1) && iVertex < this->mVertices->size(); ++iVertex) { - if (frontier[iVertex]) { - flags[iVertex] = true; - frontier[iVertex] = false; - visited[iVertex] = true; - } - } - barrier.Wait(); - for (size_t iVertex{executorId * stride}; iVertex < stride * (executorId + 1) && iVertex < this->mVertices->size(); ++iVertex) { - if (flags[iVertex]) { - for (auto& edge : mEdges[iVertex]) { - if (!visited[edge]) { - frontier[edge] = true; - } - } - } - } - }, - iExecutor); - } - for (auto&& thread : mExecutors) { - thread.join(); - } - } - } - return visited; -} - -template -std::vector Graph::getClusterIndices(const std::vector visited) -{ - // Return a smaller vector only with the int IDs of the vertices belonging to cluster - std::vector indices; - for (size_t iVisited{0}; iVisited < visited.size(); ++iVisited) { - if (visited[iVisited]) { - indices.emplace_back(iVisited); - } - } - return indices; -} - -template -std::vector Graph::getClusterIndices(const int vertexId) -{ - std::vector visited = std::move(getCluster(vertexId)); - return getClusterIndices(visited); -} - -} // namespace its -} // namespace o2 - -#endif \ No newline at end of file diff --git a/Detectors/ITSMFT/ITS/tracking/src/DBScan.cxx b/Detectors/ITSMFT/ITS/tracking/src/DBScan.cxx deleted file mode 100644 index 45eaebb76b54f..0000000000000 --- a/Detectors/ITSMFT/ITS/tracking/src/DBScan.cxx +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright CERN and copyright holders of ALICE O2. This software is -// distributed under the terms of the GNU General Public License v3 (GPL -// Version 3), copied verbatim in the file "COPYING". -// -// See http://alice-o2.web.cern.ch/license for full licensing information. -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. -/// -/// \file DBScan.cxx -/// \brief -/// - -#include "ITStracking/DBScan.h" -#include "ITStracking/Definitions.h" -#include "GPUCommonMath.h" - -namespace o2 -{ -namespace its -{ - -Centroid::Centroid(int* indices, float* position) -{ - for (int i{0}; i < 2; ++i) { - mIndices[i] = indices[i]; - } - for (int i{0}; i < 3; ++i) { - mPosition[i] = position[i]; - } -} - -float Centroid::ComputeDistance(const Centroid& c1, const Centroid& c2) -{ - return o2::gpu::GPUCommonMath::Sqrt((c1.mPosition[0] - c2.mPosition[0]) * (c1.mPosition[0] - c2.mPosition[0]) + - (c1.mPosition[1] - c2.mPosition[1]) * (c1.mPosition[1] - c2.mPosition[1]) + - (c1.mPosition[2] - c2.mPosition[2]) * (c1.mPosition[2] - c2.mPosition[2])); -} -} // namespace its -} // namespace o2 \ No newline at end of file diff --git a/Detectors/ITSMFT/ITS/tracking/src/Graph.cxx b/Detectors/ITSMFT/ITS/tracking/src/Graph.cxx deleted file mode 100644 index a43b8c036056e..0000000000000 --- a/Detectors/ITSMFT/ITS/tracking/src/Graph.cxx +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright CERN and copyright holders of ALICE O2. This software is -// distributed under the terms of the GNU General Public License v3 (GPL -// Version 3), copied verbatim in the file "COPYING". -// -// See http://alice-o2.web.cern.ch/license for full licensing information. -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. -/// -/// \file Graph.cxx -/// \brief -/// - -#include "ITStracking/Graph.h" - -namespace o2 -{ -namespace its -{ - -void Barrier::Wait() -{ - std::unique_lock lock(mutex); - if (--count == 0) { - condition.notify_all(); - } else { - condition.wait(lock, [this] { return count == 0; }); - } -} - -} // namespace its -} // namespace o2 \ No newline at end of file diff --git a/Detectors/ITSMFT/ITS/tracking/src/TrackingLinkDef.h b/Detectors/ITSMFT/ITS/tracking/src/TrackingLinkDef.h index afc832a3a6b24..95a586f24d241 100644 --- a/Detectors/ITSMFT/ITS/tracking/src/TrackingLinkDef.h +++ b/Detectors/ITSMFT/ITS/tracking/src/TrackingLinkDef.h @@ -16,7 +16,6 @@ #pragma link C++ class o2::its::ClusterLines + ; #pragma link C++ class o2::its::Tracklet + ; -#pragma link C++ class o2::its::Centroid + ; #pragma link C++ class o2::its::VertexerParamConfig + ; #pragma link C++ class o2::conf::ConfigurableParamHelper + ;