ATLAS Offline Software
Loading...
Searching...
No Matches
HyPERUtils.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5#ifndef HYPERANALYSISALGORITHMS_HYPERUTILS_H
6#define HYPERANALYSISALGORITHMS_HYPERUTILS_H
7
10#include <cstdint>
11#include <algorithm>
12#include <vector>
13
14
15
16namespace EventReco {
17
18// Standalone message level for HyPER library code (replaces RunHyPERAlg::s_msgLevelHyPER)
19extern thread_local MSG::Level g_hyper_msg_level;
20// HyPER particle IDs
21enum HyPERParticleID { jet = 1, e = 2, mu = 3, met = 4, tau = 5 };
22
23// This function is equivlant to `itertools.combination` in python.
24template <typename T>
25void combinations(const std::vector<T>& elements, int64_t k, int64_t offset,
26 std::vector<T>& current,
27 std::vector<std::vector<T>>& result) {
28 // k is how many elements we are left to find, at the beginning is equal to
29 // hyperEdgeOrder
30 if (k == 0) { // When we found all elements, store in the result.
31 result.push_back(current);
32 return;
33 }
34 // First time, we start with the first element of the array up until the last
35 // possible combination.
36 for (std::size_t i = offset; i <= elements.size() - k; ++i) {
37 current.push_back(elements[i]); // Push the current element.
38 combinations(elements, k - 1, i + 1, current,
39 result); // we now need just k-1 elements , and we move one
40 // position forward.
41 current.pop_back(); // We remove the last one and go again.
42 }
43}
44
45// This function find all possible combiantions of `order=hyperEdgeOrder`, from
46// a given number of elements (nodes).
47template <typename T>
48std::vector<std::vector<T>> buildCombinations(const std::vector<T>& elements,
49 int64_t hyperEdgeOrder) {
50 std::vector<std::vector<T>>
51 result; // This stores all the possible combinations
52 std::vector<T> current; // This is a single combination, at the beginning
53 // they are empty.
54 combinations<T>(elements, hyperEdgeOrder, 0, current,
55 result); // Find the correct combinations.
56 return result;
57}
58
59// Convert a 1D vector from type T to type V
60template <typename T, typename V>
61std::vector<T> vector1DTypeConverter(const std::vector<V>& input) {
62 std::vector<T> out = {};
63 for (std::size_t i = 0; i < static_cast<std::size_t>(input.size()); i++) {
64 out.push_back(static_cast<T>(input[i]));
65 }
66 return out;
67}
68
69// Convert a 2D vector from type T to type V
70template <typename T, typename V>
71std::vector<std::vector<T>> vector2DTypeConverter(
72 const std::vector<std::vector<V>>& input) {
73 std::vector<std::vector<T>> out = {};
74
75 for (const auto& row : input) { // Each of the rows is a vector<V>
76 std::vector<T> newRow; // Use the previous function to convert each row.
77 newRow = vector1DTypeConverter<T, V>(row);
78 out.push_back(std::move(newRow));
79 }
80
81 return out;
82}
83
84// Convert an ONNX output (1D) to a 2D vector
85template <typename T>
86std::vector<std::vector<T>> convertONNXOutput(
87 T* onnxOutput, const std::vector<int64_t>& shape) {
88 std::vector<std::vector<T>> toSave = {};
89
90 for (std::size_t i = 0; i < static_cast<std::size_t>(shape[0]); i++) {
91 std::vector<T> row = {};
92 for (std::size_t j = 0; j < static_cast<std::size_t>(shape[1]); j++) {
93 row.push_back(onnxOutput[i * shape[1] + j]);
94 }
95 toSave.push_back(std::move(row));
96 }
97 return toSave;
98}
99
100// Flatten tensors
101template <typename T>
102void flatTensorAndSetShape(const std::vector<std::vector<T>>& input,
103 std::vector<T>& flatTensor,
104 std::vector<int64_t>& shape) {
105 if (input.empty())
106 throw std::runtime_error("Tensor is empty, it cannot be flatten.");
107 shape = {static_cast<int64_t>(input.size()),
108 static_cast<int64_t>(input[0].size())};
109 for (std::size_t row = 0; row < static_cast<std::size_t>(input.size());
110 row++) {
111 flatTensor.insert(std::end(flatTensor), std::begin(input[row]),
112 std::end(input[row]));
113 }
114}
115
116// This transposes a matrix
117std::vector<std::vector<int64_t>> transpose(
118 const std::vector<std::vector<int64_t>>& vecs);
119
120// This generates a vector from 0 to nNodes - 1
121std::vector<int64_t> range(int64_t n);
122
123// @enum HyPERTopology
124HyPERTopology strToHyPERTopology(const std::string& str);
125
126// getIndexFromLabel
127std::size_t getIndexFromLabel(const std::vector<std::string>& vec,
128 const std::string& label);
129
130// Calculate delta phi between two angles in radians from -pi to pi
131float deltaPhi(float phi1, float phi2);
132
133} // namespace EventReco
134
135#endif // HYPERANALYSISALGORITHMS_HYPERUTILS_H
std::vector< size_t > vec
Definition of message levels and a helper function.
std::string label(const std::string &format, int i)
Definition label.h:19
std::vector< std::vector< T > > vector2DTypeConverter(const std::vector< std::vector< V > > &input)
Definition HyPERUtils.h:71
std::vector< std::vector< T > > buildCombinations(const std::vector< T > &elements, int64_t hyperEdgeOrder)
Definition HyPERUtils.h:48
HyPERTopology strToHyPERTopology(const std::string &str)
std::size_t getIndexFromLabel(const std::vector< std::string > &vec, const std::string &label)
void combinations(const std::vector< T > &elements, int64_t k, int64_t offset, std::vector< T > &current, std::vector< std::vector< T > > &result)
Definition HyPERUtils.h:25
MSG::Level g_hyper_msg_level
void flatTensorAndSetShape(const std::vector< std::vector< T > > &input, std::vector< T > &flatTensor, std::vector< int64_t > &shape)
Definition HyPERUtils.h:102
std::vector< int64_t > range(int64_t n)
std::vector< T > vector1DTypeConverter(const std::vector< V > &input)
Definition HyPERUtils.h:61
float deltaPhi(float phi1, float phi2)
std::vector< std::vector< int64_t > > transpose(const std::vector< std::vector< int64_t > > &vecs)
std::vector< std::vector< T > > convertONNXOutput(T *onnxOutput, const std::vector< int64_t > &shape)
Definition HyPERUtils.h:86