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