ATLAS Offline Software
Loading...
Searching...
No Matches
EventReco Namespace Reference

Namespaces

namespace  KLFEnums

Classes

class  Edge
class  Global
class  GraphBase
class  HyPERGraph
class  HyPERModel
struct  HyPEROutputNode
 Description of a single output node of the ONNX graph. More...
class  HyPERParser
 This class is in charge of parsing the information from: Graph object -> onnxruntime object. More...
class  HyPERTtbarAllHadronicModel
 This class is in charge of loading the correct HyPER model based on the Ttbar all hadronic topology. More...
class  HyPERTtbarAllHadronicParser
class  HyPERTtbarDiLeptonModel
 This class is in charge of loading the correct HyPER model based on the Ttbar di-lepton topology. More...
class  HyPERTtbarDiLeptonParser
class  HyPERTtbarLJetsModel
 This class is in charge of loading the correct HyPER model based on the Ttbar single lepton topology. More...
class  HyPERTtbarLJetsParser
struct  InputsPack
 This struct stores the input objects needed to build the graph after reading and filtering the xAOD containers. More...
class  KLFitterFinalizeOutputAlg
class  Node
class  RunHyPERAlg
 This class is in charge of building the HyPER graph and running the HyPER algorithm: The user-inputs are: More...
class  RunKLFitterAlg

Typedefs

using Features = std::vector<float>
using EdgeIndex = std::pair<int64_t, int64_t>

Enumerations

enum class  HyPERTopology {
  NotSelected = 0 , TtbarLJets , TtbarAllHadronic , TtbarDiLepton ,
  NumberOfTopologies
}
enum class  HyPEROutputDim { HyperEdges , Edges , Single }
 Which of the graph's dynamic dimensions an output tensor scales with. More...
enum  HyPERParticleID {
  jet = 1 , e = 2 , mu = 3 , met = 4 ,
  tau = 5
}

Functions

void RecoTtbarAllHadronic (const HyPERGraph &hyperGraph, const scores &edge_scores, const scores &hyperedge_scores, indices &reco_indices, std::vector< float > &reco_scores, std::vector< std::string > &reco_labels)
 Reconstruct the ttbar all hadronic topology.
void RecoTtbarLJets (const HyPERGraph &hyperGraph, const scores &edge_scores, const scores &hyperedge_scores, const scores &classification_score, indices &reco_indices, std::vector< float > &reco_scores, std::vector< std::string > &reco_labels, std::vector< std::vector< int64_t > > &reco_ids, float &reco_classification_score)
 Reconstruct the ttbar single lepton topology.
void RecoTtbarDiLepton (const HyPERGraph &hyperGraph, const scores &edge_scores, const scores &hyperedge_scores, const scores &classification_score, indices &reco_indices, std::vector< float > &reco_scores, std::vector< std::string > &reco_labels, std::vector< std::vector< int64_t > > &reco_ids, float &reco_classification_score)
 Reconstruct the ttbar single lepton topology.
bool anyCommonElement (const std::vector< int64_t > &vec1, const std::vector< int64_t > &vec2)
bool isAllowedDecay (std::vector< int64_t > &decay_indices, const std::vector< std::vector< int64_t > > &allowed_decay_modes)
template<typename T>
void combinations (const std::vector< T > &elements, int64_t k, int64_t offset, std::vector< T > &current, std::vector< std::vector< T > > &result)
template<typename T>
std::vector< std::vector< T > > buildCombinations (const std::vector< T > &elements, int64_t hyperEdgeOrder)
template<typename T, typename V>
std::vector< T > vector1DTypeConverter (const std::vector< V > &input)
template<typename T, typename V>
std::vector< std::vector< T > > vector2DTypeConverter (const std::vector< std::vector< V > > &input)
template<typename T>
std::vector< std::vector< T > > convertONNXOutput (T *onnxOutput, const std::vector< int64_t > &shape)
template<typename T>
void flatTensorAndSetShape (const std::vector< std::vector< T > > &input, std::vector< T > &flatTensor, std::vector< int64_t > &shape)
std::vector< std::vector< int64_t > > transpose (const std::vector< std::vector< int64_t > > &vecs)
std::vector< int64_t > range (int64_t n)
HyPERTopology strToHyPERTopology (const std::string &str)
std::size_t getIndexFromLabel (const std::vector< std::string > &vecvec, const std::string &label)
float deltaPhi (float phi1, float phi2)
bool isHadTop (const std::vector< int64_t > &decay_indices)
std::vector< int64_t > findWInTopLep (const std::vector< int64_t > &decay_indices, const std::vector< int64_t > &decay_ids)
int countParticlesSameType (const HyPERGraph &hyperGraph, EventReco::HyPERParticleID particleType)
int countParticlesSameType (const HyPERGraph &hyperGraph, float particleType)
void reescaleIndicesTtbarLJets (const HyPERGraph &hyperGraph, std::vector< int64_t > &top_indices, std::vector< int64_t > &w_indices, const std::vector< int64_t > &ids)
 Re-scale the indices of the reconstructed leptonic top decay to reflect the position in the particle-specific containers.
void reescaleIndicesTtbarDiLepton (const HyPERGraph &hyperGraph, std::vector< int64_t > &top_indices, const std::vector< int64_t > &ids)
void RecoHadronicTop (const HyPERGraph &hyperGraph, const scores &edge_scores, const scores &hyperedge_scores, std::vector< int64_t > &hyperedge_masks, std::vector< int64_t > &top_reco_indices, std::vector< int64_t > &w_reco_indices, float &top_reco_score, float &w_reco_score)
 Reconstruct the hadronic top quark (with the highest score) and W boson from the hypergraph score outputs.
void RecoTop (const HyPERGraph &hyperGraph, const scores &edge_scores, const scores &hyperedge_scores, std::vector< int64_t > &hyperedge_masks, std::vector< int64_t > &top_reco_indices, std::vector< int64_t > &w_reco_indices, float &top_reco_score, float &w_reco_score, std::vector< int64_t > &top_reco_ids, const std::vector< std::vector< int64_t > > &allowed_decay_modes)
 Reconstruct a top quark with a decay compatible with a list of decay modes specified by a list of indices.
void RecoTopForDiLepton (const HyPERGraph &hyperGraph, const scores &edge_scores, std::vector< int64_t > &edge_masks, std::vector< int64_t > &top_reco_indices, float &top_reco_score, std::vector< int64_t > &top_reco_ids, const std::vector< std::vector< int64_t > > &allowed_decay_modes)
 Reconstruct the leptonic top quark (with the highest score) from DiLepton topology.

Variables

MSG::Level g_hyper_msg_level = MSG::INFO

Detailed Description

Author
Diego Baron
Diego Baron
Zihan Zhang
Oliver Majersky
Baptiste Ravina

Typedef Documentation

◆ EdgeIndex

using EventReco::EdgeIndex = std::pair<int64_t, int64_t>

Definition at line 17 of file GraphBase.h.

◆ Features

using EventReco::Features = std::vector<float>

Definition at line 16 of file GraphBase.h.

Enumeration Type Documentation

◆ HyPEROutputDim

enum class EventReco::HyPEROutputDim
strong

Which of the graph's dynamic dimensions an output tensor scales with.

The HyPER models declare every output with exactly one symbolic dimension, tied either to the number of hyperedges or to the number of edges.

Enumerator
HyperEdges 
Edges 
Single 

Definition at line 38 of file HyPERModel.h.

◆ HyPERParticleID

Enumerator
jet 
mu 
met 
tau 

Definition at line 20 of file HyPERUtils.h.

20{ jet = 1, e = 2, mu = 3, met = 4, tau = 5 };

◆ HyPERTopology

enum class EventReco::HyPERTopology
strong
Enumerator
NotSelected 
TtbarLJets 
TtbarAllHadronic 
TtbarDiLepton 
NumberOfTopologies 

Definition at line 25 of file HyPERModel.h.

Function Documentation

◆ anyCommonElement()

bool EventReco::anyCommonElement ( const std::vector< int64_t > & vec1,
const std::vector< int64_t > & vec2 )

Definition at line 14 of file HyPERTopoReco.cxx.

15 {
16 for (const auto& v1 : vec1) {
17 for (const auto& v2 : vec2) {
18 if (v1 == v2)
19 return true;
20 }
21 }
22 return false;
23}

◆ buildCombinations()

template<typename T>
std::vector< std::vector< T > > EventReco::buildCombinations ( const std::vector< T > & elements,
int64_t hyperEdgeOrder )

Definition at line 47 of file HyPERUtils.h.

48 {
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}
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

◆ combinations()

template<typename T>
void EventReco::combinations ( const std::vector< T > & elements,
int64_t k,
int64_t offset,
std::vector< T > & current,
std::vector< std::vector< T > > & result )

Definition at line 24 of file HyPERUtils.h.

26 {
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}

◆ convertONNXOutput()

template<typename T>
std::vector< std::vector< T > > EventReco::convertONNXOutput ( T * onnxOutput,
const std::vector< int64_t > & shape )

Definition at line 85 of file HyPERUtils.h.

86 {
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}
row
Appending html table to final .html summary file.
float j(const xAOD::IParticle &, const xAOD::TrackMeasurementValidation &hit, const Eigen::Matrix3d &jab_inv)

◆ countParticlesSameType() [1/2]

int EventReco::countParticlesSameType ( const HyPERGraph & hyperGraph,
EventReco::HyPERParticleID particleType )

Definition at line 79 of file HyPERTopoReco.cxx.

80 {
81 int count = 0;
82 for (std::size_t i = 0; i < static_cast<std::size_t>(hyperGraph.nNodes());
83 i++) {
84 // Particle ID should be at the position before the last.
85 std::size_t beforeLastPosition = hyperGraph.getNodeFeats(i).size() - 2;
86 if (hyperGraph.getNodeFeats(i).at(beforeLastPosition) ==
87 static_cast<float>(particleType))
88 count++;
89 }
90
91 return count;
92}
int64_t nNodes() const
Definition GraphBase.h:88
Features getNodeFeats(std::size_t index) const
Definition GraphBase.h:74
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:148

◆ countParticlesSameType() [2/2]

int EventReco::countParticlesSameType ( const HyPERGraph & hyperGraph,
float particleType )

Definition at line 96 of file HyPERTopoReco.cxx.

96 {
97 int count = 0;
98 for (std::size_t i = 0; i < static_cast<std::size_t>(hyperGraph.nNodes());
99 i++) {
100 // Particle ID should be at the position before the last.
101 std::size_t beforeLastPosition = hyperGraph.getNodeFeats(i).size() - 2;
102 if (hyperGraph.getNodeFeats(i).at(beforeLastPosition) ==
103 static_cast<float>(particleType))
104 count++;
105 }
106
107 return count;
108}

◆ deltaPhi()

float EventReco::deltaPhi ( float phi1,
float phi2 )

Definition at line 61 of file HyPERUtils.cxx.

61 {
62 float PI = static_cast<float>(TMath::Pi());
63
64 float dphi = phi1 - phi2;
65 while (dphi > PI)
66 dphi -= 2 * PI;
67 while (dphi <= -PI)
68 dphi += 2 * PI;
69
70 return dphi;
71}
const float PI

◆ findWInTopLep()

std::vector< int64_t > EventReco::findWInTopLep ( const std::vector< int64_t > & decay_indices,
const std::vector< int64_t > & decay_ids )

Definition at line 55 of file HyPERTopoReco.cxx.

56 {
57 std::vector<int64_t> w_candidate = {};
58 if (decay_indices.size() != decay_ids.size())
59 throw std::runtime_error(
60 "Number of decay particles and IDs are not consistent!");
61 if (decay_indices.size() != 3)
62 throw std::runtime_error(
63 "Number of decay particles is not consistent with a leptonic top "
64 "decay!");
65
66 for (std::size_t i = 0; i < decay_indices.size(); i++) {
67 if (decay_ids.at(i) == EventReco::HyPERParticleID::jet)
68 continue;
69 w_candidate.push_back(decay_indices.at(i));
70 }
71
72 if (w_candidate.size() != 2)
73 throw std::runtime_error(
74 "Number of W boson decay particles is not consistent with a leptonic "
75 "top decay!");
76 return w_candidate;
77}

◆ flatTensorAndSetShape()

template<typename T>
void EventReco::flatTensorAndSetShape ( const std::vector< std::vector< T > > & input,
std::vector< T > & flatTensor,
std::vector< int64_t > & shape )

Definition at line 101 of file HyPERUtils.h.

103 {
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}

◆ getIndexFromLabel()

std::size_t EventReco::getIndexFromLabel ( const std::vector< std::string > & vec,
const std::string & label )

Definition at line 49 of file HyPERUtils.cxx.

50 {
51 auto it = std::find(vec.begin(), vec.end(), label);
52 if (it == vec.end()) {
53 throw std::runtime_error(
54 "HyPERAlg or VyPERAlg:: Could not find the label: " + label);
55 } else {
56 return std::distance(vec.begin(), it);
57 }
58}
std::vector< size_t > vec
std::string label(const std::string &format, int i)
Definition label.h:19

◆ isAllowedDecay()

bool EventReco::isAllowedDecay ( std::vector< int64_t > & decay_indices,
const std::vector< std::vector< int64_t > > & allowed_decay_modes )

Definition at line 25 of file HyPERTopoReco.cxx.

27 {
28 // Search for the decay mode in the allowed decay modes
29 // Create a sorted copy of the decay indices and the decay mode
30 std::vector<int64_t> decay_indices_sorted = decay_indices;
31 std::sort(decay_indices_sorted.begin(), decay_indices_sorted.end());
32 for (const auto& decay_mode : allowed_decay_modes) {
33 std::vector<int64_t> decay_mode_sorted = decay_mode;
34 std::sort(decay_mode_sorted.begin(), decay_mode_sorted.end());
35 // Check if the decay mode is compatible with the allowed decay mode
36 if (decay_indices_sorted == decay_mode_sorted)
37 return true;
38 }
39 return false;
40}
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.

◆ isHadTop()

bool EventReco::isHadTop ( const std::vector< int64_t > & decay_indices)

Definition at line 42 of file HyPERTopoReco.cxx.

42 {
43 // Check if the decay mode is compatible with a hadronic top quark
44 if (decay_indices.size() != 3)
45 throw std::runtime_error(
46 "Number of decay particles is not consistent with a hadronic top "
47 "decay!");
48 for (const auto& decay_index : decay_indices) {
49 if (decay_index != EventReco::HyPERParticleID::jet)
50 return false;
51 }
52 return true;
53}

◆ range()

std::vector< int64_t > EventReco::range ( int64_t n)

Definition at line 29 of file HyPERUtils.cxx.

29 {
30 std::vector<int64_t> result;
31 for (int64_t i{0}; i < n; ++i)
32 result.push_back(i);
33 return result;
34}

◆ RecoHadronicTop()

void EventReco::RecoHadronicTop ( const HyPERGraph & hyperGraph,
const scores & edge_scores,
const scores & hyperedge_scores,
std::vector< int64_t > & hyperedge_masks,
std::vector< int64_t > & top_reco_indices,
std::vector< int64_t > & w_reco_indices,
float & top_reco_score,
float & w_reco_score )

Reconstruct the hadronic top quark (with the highest score) and W boson from the hypergraph score outputs.

Tops already reconstructed are masked out.

Definition at line 194 of file HyPERTopoReco.cxx.

208 { // This we want to fill with the score of the W boson.
209
210 if (hyperGraph.nHyperEdges() != static_cast<int>(hyperedge_scores.size()))
211 throw std::runtime_error(
212 "Number of defined hyperedges does not match with the ones from model "
213 "output!");
214 if (hyperGraph.nEdges() != static_cast<int>(edge_scores.size()))
215 throw std::runtime_error(
216 "Number of defined graph edges does not match with the ones from model "
217 "output!");
218
219 for (std::size_t i = 0; i < hyperedge_scores.size(); i++) {
220 if (hyperedge_masks.at(i) == 0)
221 continue; // Skip the hyperedge if it is masked
222
223 if (hyperedge_scores.at(i).at(0) > top_reco_score) {
224 top_reco_score = hyperedge_scores.at(i).at(0);
225 top_reco_indices = {hyperGraph.getHyperEdgeIndices(i).at(0),
226 hyperGraph.getHyperEdgeIndices(i).at(1),
227 hyperGraph.getHyperEdgeIndices(i).at(2)};
228 w_reco_score = 0.0; // Reset the Ws if a new best top is found.
229 w_reco_indices = {-1, -1};
230
231 std::vector<std::vector<int64_t>> w_candidates =
232 buildCombinations<int64_t>(top_reco_indices, 2);
233 for (std::size_t j = 0; j < w_candidates.size(); j++) {
234 // There are two directional edges connecting each pair of nodes
235 float bi_directional_sum = 0;
236 for (std::size_t k = 0; k < edge_scores.size(); k++) {
237 if (w_candidates.at(j).at(0) ==
238 hyperGraph.getEdgeIndicesVector().at(k).first &&
239 w_candidates.at(j).at(1) ==
240 hyperGraph.getEdgeIndicesVector().at(k).second) {
241 bi_directional_sum += edge_scores.at(k).at(0);
242 }
243 if (w_candidates.at(j).at(1) ==
244 hyperGraph.getEdgeIndicesVector().at(k).first &&
245 w_candidates.at(j).at(0) ==
246 hyperGraph.getEdgeIndicesVector().at(k).second) {
247 bi_directional_sum += edge_scores.at(k).at(0);
248 }
249 }
250 if (bi_directional_sum / 2 > w_reco_score) {
251 w_reco_score = bi_directional_sum / 2;
252 w_reco_indices = w_candidates.at(j);
253 }
254 }
255 }
256 }
257}
int64_t nEdges() const
Definition GraphBase.h:89
const std::vector< EdgeIndex > & getEdgeIndicesVector() const
Definition HyPERGraph.h:34
int64_t nHyperEdges() const
Definition HyPERGraph.h:40
HyperEdgeIndex getHyperEdgeIndices(std::size_t index) const
Definition HyPERGraph.h:37
std::vector< std::vector< T > > buildCombinations(const std::vector< T > &elements, int64_t hyperEdgeOrder)
Definition HyPERUtils.h:47

◆ RecoTop()

void EventReco::RecoTop ( const HyPERGraph & hyperGraph,
const scores & edge_scores,
const scores & hyperedge_scores,
std::vector< int64_t > & hyperedge_masks,
std::vector< int64_t > & top_reco_indices,
std::vector< int64_t > & w_reco_indices,
float & top_reco_score,
float & w_reco_score,
std::vector< int64_t > & top_reco_ids,
const std::vector< std::vector< int64_t > > & allowed_decay_modes )

Reconstruct a top quark with a decay compatible with a list of decay modes specified by a list of indices.

Tops already reconstructed are masked out.

Definition at line 264 of file HyPERTopoReco.cxx.

283 { // This is the list of decay modes we want to
284 // consider.
285 if (hyperGraph.nHyperEdges() != static_cast<int>(hyperedge_scores.size()))
286 throw std::runtime_error(
287 "Number of defined hyperedges does not match with the ones from model "
288 "output!");
289 if (hyperGraph.nEdges() != static_cast<int>(edge_scores.size()))
290 throw std::runtime_error(
291 "Number of defined graph edges does not match with the ones from model "
292 "output!");
293 if (allowed_decay_modes.empty())
294 throw std::runtime_error("No allowed decay modes available!");
295
296 for (std::size_t i = 0; i < hyperedge_scores.size(); i++) {
297 if (hyperedge_masks.at(i) == 0)
298 continue; // Skip the hyperedge if it is masked
299 if (hyperedge_scores.at(i).at(0) > top_reco_score) {
300
301 std::vector<int64_t> top_candidate_indices = {
302 hyperGraph.getHyperEdgeIndices(i).at(0),
303 hyperGraph.getHyperEdgeIndices(i).at(1),
304 hyperGraph.getHyperEdgeIndices(i).at(2)};
305 // Get particle IDs. The conversions here are float -> HyPERParticleID
306 // (int) -> int64_t
307 // The ID should be the element before the last in the node features. See
308 // RunHyPERAlg::buildTtbarLJetsGraph
309 std::size_t beforeLastPosition = hyperGraph.getNodeFeats(0).size() - 2;
311 hyperGraph.getNodeFeats(top_candidate_indices.at(0))
312 .at(beforeLastPosition));
314 hyperGraph.getNodeFeats(top_candidate_indices.at(1))
315 .at(beforeLastPosition));
317 hyperGraph.getNodeFeats(top_candidate_indices.at(2))
318 .at(beforeLastPosition));
319 std::vector<int64_t> top_candidate_ids = {static_cast<int64_t>(id_1),
320 static_cast<int64_t>(id_2),
321 static_cast<int64_t>(id_3)};
322 if (!isAllowedDecay(top_candidate_ids, allowed_decay_modes))
323 continue;
324
325 top_reco_score = hyperedge_scores.at(i).at(0);
326 top_reco_ids = top_candidate_ids;
327 top_reco_indices = top_candidate_indices;
328 w_reco_score = 0.0; // Reset the Ws if a new best top is found.
329 w_reco_indices = {-1, -1};
330
331 if (isHadTop(top_reco_ids)) { // Do the same as the had top reco
332 std::vector<std::vector<int64_t>> w_candidates =
333 buildCombinations<int64_t>(top_reco_indices, 2);
334 for (std::size_t j = 0; j < w_candidates.size(); j++) {
335 // There are two directional edges connecting each pair of nodes
336 float bi_directional_sum = 0;
337 for (std::size_t k = 0; k < edge_scores.size(); k++) {
338 if (w_candidates.at(j).at(0) ==
339 hyperGraph.getEdgeIndicesVector().at(k).first &&
340 w_candidates.at(j).at(1) ==
341 hyperGraph.getEdgeIndicesVector().at(k).second) {
342 bi_directional_sum += edge_scores.at(k).at(0);
343 }
344 if (w_candidates.at(j).at(1) ==
345 hyperGraph.getEdgeIndicesVector().at(k).first &&
346 w_candidates.at(j).at(0) ==
347 hyperGraph.getEdgeIndicesVector().at(k).second) {
348 bi_directional_sum += edge_scores.at(k).at(0);
349 }
350 }
351 if (bi_directional_sum / 2 > w_reco_score) {
352 w_reco_score = bi_directional_sum / 2;
353 w_reco_indices = w_candidates.at(j);
354 }
355 }
356 } else { // Just look for the hadronic index and the rest is the W boson
357 w_reco_indices = findWInTopLep(top_reco_indices, top_reco_ids);
358 float bi_directional_sum = 0;
359 for (std::size_t k = 0; k < edge_scores.size(); k++) {
360 if (w_reco_indices.at(0) ==
361 hyperGraph.getEdgeIndicesVector().at(k).first &&
362 w_reco_indices.at(1) ==
363 hyperGraph.getEdgeIndicesVector().at(k).second) {
364 bi_directional_sum += edge_scores.at(k).at(0);
365 }
366 if (w_reco_indices.at(0) ==
367 hyperGraph.getEdgeIndicesVector().at(k).second &&
368 w_reco_indices.at(1) ==
369 hyperGraph.getEdgeIndicesVector().at(k).first) {
370 bi_directional_sum += edge_scores.at(k).at(0);
371 }
372 }
373 w_reco_score = bi_directional_sum / 2;
374 }
375 }
376 }
377}
bool isHadTop(const std::vector< int64_t > &decay_indices)
std::vector< int64_t > findWInTopLep(const std::vector< int64_t > &decay_indices, const std::vector< int64_t > &decay_ids)
bool isAllowedDecay(std::vector< int64_t > &decay_indices, const std::vector< std::vector< int64_t > > &allowed_decay_modes)

◆ RecoTopForDiLepton()

void EventReco::RecoTopForDiLepton ( const HyPERGraph & hyperGraph,
const scores & edge_scores,
std::vector< int64_t > & edge_masks,
std::vector< int64_t > & top_reco_indices,
float & top_reco_score,
std::vector< int64_t > & top_reco_ids,
const std::vector< std::vector< int64_t > > & allowed_decay_modes )

Reconstruct the leptonic top quark (with the highest score) from DiLepton topology.

Tops already reconstructed are masked out. Only edges are considered in this case.

Definition at line 660 of file HyPERTopoReco.cxx.

673 { // This is the list of decay modes we want to
674 // consider.
675
676 using namespace asg::msgUserCode;
677 // Sanity checks
678 if (hyperGraph.nEdges() != static_cast<int>(edge_scores.size()))
679 throw std::runtime_error(
680 "Number of defined graph edges does not match with the ones from model "
681 "output!");
682 if (allowed_decay_modes.empty())
683 throw std::runtime_error("No allowed decay modes available!");
684
685 for (std::size_t i = 0; i < edge_scores.size(); i++) {
686 if (edge_masks.at(i) == 0) {
687 if (EventReco::g_hyper_msg_level == MSG::VERBOSE)
688 ANA_MSG_INFO("Skipping due to masking.");
689 continue; // Skip the edge if it is masked
690 }
691
692 // Get particle IDs.
693 std::vector<int64_t> top_candidate_indices = {
694 hyperGraph.getEdgeIndicesVector().at(i).first,
695 hyperGraph.getEdgeIndicesVector().at(i).second};
696 // Get particle IDs. The conversions here are float -> HyPERParticleID
697 // (int) -> int64_t
698 // The ID should be the element before the last in the node features. We
699 // have to MULTIPLY by 2 because of the feature scaling. See
700 // RunHyPERAlg::buildTtbarDiLeptonGraph
701 std::size_t beforeLastPosition = hyperGraph.getNodeFeats(0).size() - 2;
703 2 * hyperGraph.getNodeFeats(top_candidate_indices.at(0))
704 .at(beforeLastPosition));
706 2 * hyperGraph.getNodeFeats(top_candidate_indices.at(1))
707 .at(beforeLastPosition));
708 std::vector<int64_t> top_candidate_ids = {static_cast<int64_t>(id_1),
709 static_cast<int64_t>(id_2)};
710
711 // Only allow allowed decay modes
712 if (!isAllowedDecay(top_candidate_ids, allowed_decay_modes)) {
713 if (EventReco::g_hyper_msg_level == MSG::VERBOSE)
714 ANA_MSG_INFO("Skipping due to not allowed decay.");
715 continue;
716 }
717
718 if (edge_scores.at(i).at(0) > top_reco_score) {
719 top_reco_score = edge_scores.at(i).at(0);
720 top_reco_indices = top_candidate_indices;
721 top_reco_ids = top_candidate_ids;
722 }
723 }
724}
#define ANA_MSG_INFO(xmsg,...)
Macro printing info messages.
MSG::Level g_hyper_msg_level

◆ RecoTtbarAllHadronic()

void EventReco::RecoTtbarAllHadronic ( const HyPERGraph & hyperGraph,
const scores & edge_scores,
const scores & hyperedge_scores,
indices & reco_indices,
std::vector< float > & reco_scores,
std::vector< std::string > & reco_labels )

Reconstruct the ttbar all hadronic topology.

Definition at line 382 of file HyPERTopoReco.cxx.

386 {
387
388 std::vector<int64_t> top1_reco_indices(3, -1);
389 std::vector<int64_t> top2_reco_indices(3, -1);
390 std::vector<int64_t> w1_reco_indices(2, -1);
391 std::vector<int64_t> w2_reco_indices(2, -1);
392
393 float top1_reco_score = 0;
394 float top2_reco_score = 0;
395 float w1_reco_score = 0;
396 float w2_reco_score = 0;
397
398 // Reconstructing top1
399 std::vector<int64_t> top1_masks(hyperedge_scores.size(), 1);
400 RecoHadronicTop(hyperGraph, edge_scores, hyperedge_scores, top1_masks,
401 top1_reco_indices, w1_reco_indices, top1_reco_score,
402 w1_reco_score);
403
404 // Check if reco top1 is successful
405 if (top1_reco_indices == std::vector<int64_t>(3, -1)) {
406 reco_labels.push_back("HyPER_Reco_Top1");
407 reco_indices.push_back(top1_reco_indices);
408 reco_scores.push_back(top1_reco_score);
409 reco_labels.push_back("HyPER_Reco_Top2");
410 reco_indices.push_back(top2_reco_indices);
411 reco_scores.push_back(top2_reco_score);
412 reco_labels.push_back("HyPER_Reco_W1");
413 reco_indices.push_back(w1_reco_indices);
414 reco_scores.push_back(w1_reco_score);
415 reco_labels.push_back("HyPER_Reco_W2");
416 reco_indices.push_back(w2_reco_indices);
417 reco_scores.push_back(w2_reco_score);
418 return; // No point in continuing if top1 is not reconstructed.
419 }
420
421 // Masking out the hyperedges containing nodes in top1
422 std::vector<int64_t> top2_masks;
423 for (std::size_t i = 0;
424 i < static_cast<std::size_t>(hyperGraph.nHyperEdges()); i++) {
425 if (anyCommonElement(top1_reco_indices, hyperGraph.getHyperEdgeIndices(i)))
426 top2_masks.push_back(0);
427 else
428 top2_masks.push_back(1);
429 }
430
431 // Reconstructing top2
432 RecoHadronicTop(hyperGraph, edge_scores, hyperedge_scores, top2_masks,
433 top2_reco_indices, w2_reco_indices, top2_reco_score,
434 w2_reco_score);
435
436 // Save results
437 reco_labels.push_back("HyPER_Reco_Top1");
438 reco_indices.push_back(top1_reco_indices);
439 reco_scores.push_back(top1_reco_score);
440 reco_labels.push_back("HyPER_Reco_Top2");
441 reco_indices.push_back(top2_reco_indices);
442 reco_scores.push_back(top2_reco_score);
443 reco_labels.push_back("HyPER_Reco_W1");
444 reco_indices.push_back(w1_reco_indices);
445 reco_scores.push_back(w1_reco_score);
446 reco_labels.push_back("HyPER_Reco_W2");
447 reco_indices.push_back(w2_reco_indices);
448 reco_scores.push_back(w2_reco_score);
449}
void RecoHadronicTop(const HyPERGraph &hyperGraph, const scores &edge_scores, const scores &hyperedge_scores, std::vector< int64_t > &hyperedge_masks, std::vector< int64_t > &top_reco_indices, std::vector< int64_t > &w_reco_indices, float &top_reco_score, float &w_reco_score)
Reconstruct the hadronic top quark (with the highest score) and W boson from the hypergraph score out...
bool anyCommonElement(const std::vector< int64_t > &vec1, const std::vector< int64_t > &vec2)

◆ RecoTtbarDiLepton()

void EventReco::RecoTtbarDiLepton ( const HyPERGraph & hyperGraph,
const scores & edge_scores,
const scores & hyperedge_scores,
const scores & classification_score,
indices & reco_indices,
std::vector< float > & reco_scores,
std::vector< std::string > & reco_labels,
std::vector< std::vector< int64_t > > & reco_ids,
float & reco_classification_score )

Reconstruct the ttbar single lepton topology.

Definition at line 729 of file HyPERTopoReco.cxx.

735 {
736 using namespace asg::msgUserCode;
737
738 std::vector<int64_t> top1_reco_indices(2, -1);
739 std::vector<int64_t> top2_reco_indices(2, -1);
740
741 float top1_reco_score = 0;
742 float top2_reco_score = 0;
743
744 std::vector<int64_t> top1_reco_ids(2, -1);
745 std::vector<int64_t> top2_reco_ids(2, -1);
746
747 if (EventReco::g_hyper_msg_level == MSG::VERBOSE) {
748 setMsgLevel(MSG::INFO);
749 ANA_MSG_INFO("Reconstructing TtbarDiLepton top quarks...");
750 ANA_MSG_INFO("Working with these HE scores:");
751 for (const auto& he_score : hyperedge_scores) {
752 ANA_MSG_INFO("Element " << he_score.at(0));
753 }
754 ANA_MSG_INFO("Working with these edge scores:");
755 for (const auto& e_score : edge_scores) {
756 ANA_MSG_INFO("Element " << e_score.at(0));
757 }
758 ANA_MSG_INFO("Working with this classification score:");
759 ANA_MSG_INFO(classification_score.at(0).at(0));
760 }
761
762 // Save the classification score
763 reco_classification_score = classification_score.at(0).at(0);
764
765 // Allowed decays
766 std::vector<std::vector<int64_t>> allowed_decays = {
769
770 // Reconstructing top1
771 std::vector<int64_t> top1_masks(edge_scores.size(), 1);
772 RecoTopForDiLepton(hyperGraph, edge_scores, top1_masks, top1_reco_indices,
773 top1_reco_score, top1_reco_ids, allowed_decays);
774 if (EventReco::g_hyper_msg_level == MSG::VERBOSE) {
775 ANA_MSG_INFO("Top1 reco score: " << top1_reco_score);
776 ANA_MSG_INFO("Top1 reco indices before scaling: "
777 << top1_reco_indices.at(0) << " " << top1_reco_indices.at(1));
778 ANA_MSG_INFO("Top1 reco IDs: " << top1_reco_ids.at(0) << " "
779 << top1_reco_ids.at(1));
780 }
781
782 // If top1 reco failed, return default values for both tops
783 if (top1_reco_indices == std::vector<int64_t>(2, -1)) {
784 ANA_MSG_INFO("Top1 reco failed.");
785 reco_labels.push_back("HyPER_Reco_Top1");
786 reco_indices.push_back(top1_reco_indices);
787 reco_scores.push_back(top1_reco_score);
788 reco_ids.push_back(top1_reco_ids);
789 reco_labels.push_back("HyPER_Reco_Top2");
790 reco_indices.push_back(top2_reco_indices);
791 reco_scores.push_back(top2_reco_score);
792 reco_ids.push_back(top2_reco_ids);
793 reco_labels.push_back("HyPER_Reco_HE");
794 reco_scores.push_back(-1.0);
795 return;
796 }
797
798 // Now, reconstruct top2
799 // Calculate top2 masks
800 std::vector<int64_t> top2_masks(edge_scores.size(), 1);
801 for (std::size_t i = 0; i < static_cast<std::size_t>(edge_scores.size());
802 i++) {
803 if (anyCommonElement(top1_reco_indices,
804 {hyperGraph.getEdgeIndicesVector().at(i).first,
805 hyperGraph.getEdgeIndicesVector().at(i).second}))
806 top2_masks.at(i) = 0;
807 }
808 // Now, reconstruct top2
809 RecoTopForDiLepton(hyperGraph, edge_scores, top2_masks, top2_reco_indices,
810 top2_reco_score, top2_reco_ids, allowed_decays);
811 if (EventReco::g_hyper_msg_level == MSG::VERBOSE) {
812 ANA_MSG_INFO("Top2 reco score: " << top2_reco_score);
813 ANA_MSG_INFO("Top2 reco indices before scaling: "
814 << top2_reco_indices.at(0) << " " << top2_reco_indices.at(1));
815 ANA_MSG_INFO("Top2 reco IDs: " << top2_reco_ids.at(0) << " "
816 << top2_reco_ids.at(1));
817 }
818
819 // Check if reco top2 is successful
820 bool both_tops_reco = true; // At this point, top1 is already reconstructed
821 if (top2_reco_indices == std::vector<int64_t>(2, -1))
822 both_tops_reco = false;
823
824 // Let's find the hyperedge score corresponding to the two tops if both tops
825 // are reconstructed.
826 float HE_reco_score = -1.0;
827 if (both_tops_reco) {
828 for (std::size_t i = 0;
829 i < static_cast<std::size_t>(hyperGraph.nHyperEdges()); i++) {
830 std::vector<int64_t> he_indices = hyperGraph.getHyperEdgeIndices(i);
831 // Check all top indices are in the HE indices.
832 bool top1_in_he =
833 std::find(he_indices.begin(), he_indices.end(),
834 top1_reco_indices.at(0)) != he_indices.end() &&
835 std::find(he_indices.begin(), he_indices.end(),
836 top1_reco_indices.at(1)) != he_indices.end();
837 bool top2_in_he =
838 std::find(he_indices.begin(), he_indices.end(),
839 top2_reco_indices.at(0)) != he_indices.end() &&
840 std::find(he_indices.begin(), he_indices.end(),
841 top2_reco_indices.at(1)) != he_indices.end();
842 if (top1_in_he && top2_in_he) {
843 HE_reco_score = hyperedge_scores.at(i).at(0);
844 break;
845 }
846 }
847 }
848
849 // Finally, we need to shift the indices in the tops to reflect
850 // the position in the particle-specific containers.
851 if (both_tops_reco) {
852 reescaleIndicesTtbarDiLepton(hyperGraph, top1_reco_indices, top1_reco_ids);
853 reescaleIndicesTtbarDiLepton(hyperGraph, top2_reco_indices, top2_reco_ids);
854 } else { // Only shift top1
855 reescaleIndicesTtbarDiLepton(hyperGraph, top1_reco_indices, top1_reco_ids);
856 }
857
858 if (EventReco::g_hyper_msg_level == MSG::VERBOSE) {
859 ANA_MSG_INFO("Top1 reco indices after scaling: "
860 << top1_reco_indices.at(0) << " " << top1_reco_indices.at(1));
861 ANA_MSG_INFO("Top2 reco indices after scaling: "
862 << top2_reco_indices.at(0) << " " << top2_reco_indices.at(1));
863 }
864
865 // Save results
866 reco_labels.push_back("HyPER_Reco_Top1");
867 reco_indices.push_back(top1_reco_indices);
868 reco_scores.push_back(top1_reco_score);
869 reco_ids.push_back(top1_reco_ids);
870 reco_labels.push_back("HyPER_Reco_Top2");
871 reco_indices.push_back(top2_reco_indices);
872 reco_scores.push_back(top2_reco_score);
873 reco_ids.push_back(top2_reco_ids);
874 reco_labels.push_back("HyPER_Reco_HE");
875 reco_scores.push_back(HE_reco_score);
876}
void RecoTopForDiLepton(const HyPERGraph &hyperGraph, const scores &edge_scores, std::vector< int64_t > &edge_masks, std::vector< int64_t > &top_reco_indices, float &top_reco_score, std::vector< int64_t > &top_reco_ids, const std::vector< std::vector< int64_t > > &allowed_decay_modes)
Reconstruct the leptonic top quark (with the highest score) from DiLepton topology.
void reescaleIndicesTtbarDiLepton(const HyPERGraph &hyperGraph, std::vector< int64_t > &top_indices, const std::vector< int64_t > &ids)

◆ RecoTtbarLJets()

void EventReco::RecoTtbarLJets ( const HyPERGraph & hyperGraph,
const scores & edge_scores,
const scores & hyperedge_scores,
const scores & classification_score,
indices & reco_indices,
std::vector< float > & reco_scores,
std::vector< std::string > & reco_labels,
std::vector< std::vector< int64_t > > & reco_ids,
float & reco_classification_score )

Reconstruct the ttbar single lepton topology.

Definition at line 454 of file HyPERTopoReco.cxx.

460 {
461 using namespace asg::msgUserCode;
462
463 std::vector<int64_t> top1_reco_indices(3, -1);
464 std::vector<int64_t> top2_reco_indices(3, -1);
465 std::vector<int64_t> w1_reco_indices(2, -1);
466 std::vector<int64_t> w2_reco_indices(2, -1);
467
468 float top1_reco_score = 0;
469 float top2_reco_score = 0;
470 float w1_reco_score = 0;
471 float w2_reco_score = 0;
472
473 std::vector<int64_t> top1_reco_ids(3, -1);
474 std::vector<int64_t> top2_reco_ids(3, -1);
475
476 if (EventReco::g_hyper_msg_level == MSG::VERBOSE) {
477 setMsgLevel(MSG::INFO);
478 ANA_MSG_INFO("Reconstructing TtbarSingleLepton top quarks...");
479 ANA_MSG_INFO("Working with these HE scores:");
480 for (const auto& he_score : hyperedge_scores) {
481 ANA_MSG_INFO("Element " << he_score.at(0));
482 }
483 ANA_MSG_INFO("Working with these edge scores:");
484 for (const auto& e_score : edge_scores) {
485 ANA_MSG_INFO("Element " << e_score.at(0));
486 }
487 ANA_MSG_INFO("Working with this classification score:");
488 ANA_MSG_INFO(classification_score.at(0).at(0));
489 }
490
491 // Save the classification score
492 reco_classification_score = classification_score.at(0).at(0);
493
494 // Allowed decays
495 std::vector<std::vector<int64_t>> allowed_decays = {
502
503 // Reconstructing top1
504 std::vector<int64_t> top1_masks(hyperedge_scores.size(), 1);
505 RecoTop(hyperGraph, edge_scores, hyperedge_scores, top1_masks,
506 top1_reco_indices, w1_reco_indices, top1_reco_score, w1_reco_score,
507 top1_reco_ids, allowed_decays);
508 if (EventReco::g_hyper_msg_level == MSG::VERBOSE) {
509 ANA_MSG_INFO("Top1 reco indices: " << top1_reco_indices.at(0) << " "
510 << top1_reco_indices.at(1) << " "
511 << top1_reco_indices.at(2));
512 ANA_MSG_INFO("Top1 reco score: " << top1_reco_score);
513 ANA_MSG_INFO("W1 reco indices: " << w1_reco_indices.at(0) << " "
514 << w1_reco_indices.at(1));
515 ANA_MSG_INFO("W1 reco score: " << w1_reco_score);
516 }
517
518 // Check if reco top1 is successful
519 if (top1_reco_indices == std::vector<int64_t>(3, -1)) {
520 // If not, return the default values for both tops.
521 reco_labels.push_back("HyPER_Reco_TopHad");
522 reco_indices.push_back(top1_reco_indices);
523 reco_scores.push_back(top1_reco_score);
524 reco_ids.push_back(top1_reco_ids);
525 reco_labels.push_back("HyPER_Reco_TopLep");
526 reco_indices.push_back(top2_reco_indices);
527 reco_scores.push_back(top2_reco_score);
528 reco_ids.push_back(top2_reco_ids);
529 reco_labels.push_back("HyPER_Reco_WHad");
530 reco_indices.push_back(w1_reco_indices);
531 reco_scores.push_back(w1_reco_score);
532 reco_labels.push_back("HyPER_Reco_WLep");
533 reco_indices.push_back(w2_reco_indices);
534 reco_scores.push_back(w2_reco_score);
535 return;
536 }
537
538 // Masking out the hyperedges containing nodes in top1
539 std::vector<int64_t> top2_masks;
540 for (std::size_t i = 0;
541 i < static_cast<std::size_t>(hyperGraph.nHyperEdges()); i++) {
542 if (anyCommonElement(top1_reco_indices, hyperGraph.getHyperEdgeIndices(i)))
543 top2_masks.push_back(0);
544 else
545 top2_masks.push_back(1);
546 }
547
548 // If the top1 is hadronic, redefine the allowed decays and conversely
549 bool top1_is_hadronic = false;
550 if (isHadTop(top1_reco_ids)) {
551 if (EventReco::g_hyper_msg_level == MSG::VERBOSE)
552 ANA_MSG_INFO("Top1 is hadronic!");
553 top1_is_hadronic = true;
558 } else {
559 if (EventReco::g_hyper_msg_level == MSG::VERBOSE)
560 ANA_MSG_INFO("Top1 is Leptonic!");
563 }
564
565 // Reconstructing top2
566 RecoTop(hyperGraph, edge_scores, hyperedge_scores, top2_masks,
567 top2_reco_indices, w2_reco_indices, top2_reco_score, w2_reco_score,
568 top2_reco_ids, allowed_decays);
569 if (EventReco::g_hyper_msg_level == MSG::VERBOSE) {
570 ANA_MSG_INFO("Top2 reco indices: " << top2_reco_indices.at(0) << " "
571 << top2_reco_indices.at(1) << " "
572 << top2_reco_indices.at(2));
573 ANA_MSG_INFO("Top2 reco score: " << top2_reco_score);
574 ANA_MSG_INFO("W2 reco indices: " << w2_reco_indices.at(0) << " "
575 << w2_reco_indices.at(1));
576 ANA_MSG_INFO("W2 reco score: " << w2_reco_score);
577 }
578
579 // Check if reco top2 is successful
580 bool both_tops_reco = true;
581 if (top2_reco_indices == std::vector<int64_t>(3, -1))
582 both_tops_reco = false;
583
584 // Finally, we need to shift the indices in the leptonic top decay to reflect
585 // the position in the particle-specific containers.
586 if (top1_is_hadronic && both_tops_reco) {
587 reescaleIndicesTtbarLJets(hyperGraph, top2_reco_indices, w2_reco_indices,
588 top2_reco_ids);
589 }
590 if (!top1_is_hadronic) {
591 reescaleIndicesTtbarLJets(hyperGraph, top1_reco_indices, w1_reco_indices,
592 top1_reco_ids);
593 }
594
595 if (EventReco::g_hyper_msg_level == MSG::VERBOSE) {
596 ANA_MSG_INFO("Final reco indices:");
597 ANA_MSG_INFO("Top1 reco indices: " << top1_reco_indices.at(0) << " "
598 << top1_reco_indices.at(1) << " "
599 << top1_reco_indices.at(2));
600 ANA_MSG_INFO("Top2 reco indices: " << top2_reco_indices.at(0) << " "
601 << top2_reco_indices.at(1) << " "
602 << top2_reco_indices.at(2));
603 ANA_MSG_INFO("W1 reco indices: " << w1_reco_indices.at(0) << " "
604 << w1_reco_indices.at(1));
605 ANA_MSG_INFO("W2 reco indices: " << w2_reco_indices.at(0) << " "
606 << w2_reco_indices.at(1));
607 ANA_MSG_INFO("Final reco scores:");
608 ANA_MSG_INFO("Top1 reco score: " << top1_reco_score);
609 ANA_MSG_INFO("Top2 reco score: " << top2_reco_score);
610 ANA_MSG_INFO("W1 reco score: " << w1_reco_score);
611 ANA_MSG_INFO("W2 reco score: " << w2_reco_score);
612 ANA_MSG_INFO("Final reco IDs:");
613 ANA_MSG_INFO("Top1 reco IDs: " << top1_reco_ids.at(0) << " "
614 << top1_reco_ids.at(1) << " "
615 << top1_reco_ids.at(2));
616 ANA_MSG_INFO("Top2 reco IDs: " << top2_reco_ids.at(0) << " "
617 << top2_reco_ids.at(1) << " "
618 << top2_reco_ids.at(2));
619 }
620
621 // Save results
622 if (top1_is_hadronic) {
623 reco_labels.push_back("HyPER_Reco_TopHad");
624 reco_indices.push_back(top1_reco_indices);
625 reco_scores.push_back(top1_reco_score);
626 reco_ids.push_back(top1_reco_ids);
627 reco_labels.push_back("HyPER_Reco_TopLep");
628 reco_indices.push_back(top2_reco_indices);
629 reco_scores.push_back(top2_reco_score);
630 reco_ids.push_back(top2_reco_ids);
631 reco_labels.push_back("HyPER_Reco_WHad");
632 reco_indices.push_back(w1_reco_indices);
633 reco_scores.push_back(w1_reco_score);
634 reco_labels.push_back("HyPER_Reco_WLep");
635 reco_indices.push_back(w2_reco_indices);
636 reco_scores.push_back(w2_reco_score);
637 } else {
638 reco_labels.push_back("HyPER_Reco_TopHad");
639 reco_indices.push_back(top2_reco_indices);
640 reco_scores.push_back(top2_reco_score);
641 reco_ids.push_back(top2_reco_ids);
642 reco_labels.push_back("HyPER_Reco_TopLep");
643 reco_indices.push_back(top1_reco_indices);
644 reco_scores.push_back(top1_reco_score);
645 reco_ids.push_back(top1_reco_ids);
646 reco_labels.push_back("HyPER_Reco_WHad");
647 reco_indices.push_back(w2_reco_indices);
648 reco_scores.push_back(w2_reco_score);
649 reco_labels.push_back("HyPER_Reco_WLep");
650 reco_indices.push_back(w1_reco_indices);
651 reco_scores.push_back(w1_reco_score);
652 }
653}
void RecoTop(const HyPERGraph &hyperGraph, const scores &edge_scores, const scores &hyperedge_scores, std::vector< int64_t > &hyperedge_masks, std::vector< int64_t > &top_reco_indices, std::vector< int64_t > &w_reco_indices, float &top_reco_score, float &w_reco_score, std::vector< int64_t > &top_reco_ids, const std::vector< std::vector< int64_t > > &allowed_decay_modes)
Reconstruct a top quark with a decay compatible with a list of decay modes specified by a list of ind...
void reescaleIndicesTtbarLJets(const HyPERGraph &hyperGraph, std::vector< int64_t > &top_indices, std::vector< int64_t > &w_indices, const std::vector< int64_t > &ids)
Re-scale the indices of the reconstructed leptonic top decay to reflect the position in the particle-...

◆ reescaleIndicesTtbarDiLepton()

void EventReco::reescaleIndicesTtbarDiLepton ( const HyPERGraph & hyperGraph,
std::vector< int64_t > & top_indices,
const std::vector< int64_t > & ids )

Definition at line 153 of file HyPERTopoReco.cxx.

155 {
156 // Divide by 2 because of the feature scaling applied to the IDs in
157 // RunHyPERAlg::buildTtbarDiLeptonGraph. See the comments there for more
158 // details.
159 int nJets =
161 int nElectrons =
163 // int nMuons = countParticlesSameType(hyperGraph,
164 // EventReco::HyPERParticleID::mu/2.0f);
165 // // When tau is supported...
166
167 // Sanity check. In di-lepton there should be no METs counted as particles.
168 int nMETs =
170 if (nMETs != 1)
171 throw std::runtime_error("Number of METs is not consistent!");
172
173 // Reescale the indices
174 for (std::size_t i = 0; i < top_indices.size(); i++) {
175 if (ids.at(i) ==
176 EventReco::HyPERParticleID::jet) { // For jets do nothing since they are
177 // filled first and then their positions
178 // are the same as in the original
179 // container.
180 continue;
181 } else if (ids.at(i) == EventReco::HyPERParticleID::e) {
182 top_indices.at(i) -= nJets;
183 } else if (ids.at(i) == EventReco::HyPERParticleID::mu) {
184 top_indices.at(i) -= (nJets + nElectrons);
185 } // When tau is supported...
186 }
187}
int countParticlesSameType(const HyPERGraph &hyperGraph, EventReco::HyPERParticleID particleType)

◆ reescaleIndicesTtbarLJets()

void EventReco::reescaleIndicesTtbarLJets ( const HyPERGraph & hyperGraph,
std::vector< int64_t > & top_indices,
std::vector< int64_t > & w_indices,
const std::vector< int64_t > & ids )

Re-scale the indices of the reconstructed leptonic top decay to reflect the position in the particle-specific containers.

Definition at line 114 of file HyPERTopoReco.cxx.

117 {
119 int nElectrons = countParticlesSameType(hyperGraph, EventReco::HyPERParticleID::e);
120 // int nMuons = countParticlesSameType(hyperGraph, EventReco::HyPERParticleID::mu);
121 // // When tau is supported...
123
124 // Sanity check
125 if (nMETs != 1)
126 throw std::runtime_error("Number of METs is not consistent!");
127
128 // Reescale the indices
129 for (std::size_t i = 0; i < top_indices.size(); i++) {
130 if (ids.at(i) ==
131 EventReco::HyPERParticleID::jet) { // For jets do nothing since they are
132 // filled first and then their positions
133 // are the same as in the original
134 // container.
135 continue;
136 } else if (ids.at(i) == EventReco::HyPERParticleID::e) {
137 top_indices.at(i) -= nJets;
138 w_indices.at(0) = top_indices.at(
139 i); // Always put the lepton as the first in the w_indices.
140 } else if (ids.at(i) == EventReco::HyPERParticleID::mu) {
141 top_indices.at(i) -= (nJets + nElectrons);
142 w_indices.at(0) = top_indices.at(
143 i); // Always put the lepton as the first in the w_indices.
144 } else if (ids.at(i) == EventReco::HyPERParticleID::met) {
145 top_indices.at(i) =
146 0; // Just assign 0 here since MET is always the first particle.
147 w_indices.at(1) =
148 0; // always put the MET as the second in the w_indices.
149 }
150 }
151}

◆ strToHyPERTopology()

HyPERTopology EventReco::strToHyPERTopology ( const std::string & str)

Definition at line 37 of file HyPERUtils.cxx.

37 {
38 if (str == "TtbarLJets")
40 if (str == "TtbarLJetsNoBTag")
42 if (str == "TtbarAllHadronic")
44 if (str == "TtbarDiLepton")
47}

◆ transpose()

std::vector< std::vector< int64_t > > EventReco::transpose ( const std::vector< std::vector< int64_t > > & vecs)

Definition at line 12 of file HyPERUtils.cxx.

13 {
14 if (vecs.empty() || vecs[0].empty())
15 return {};
16
17 std::size_t rows = vecs.size();
18 std::size_t cols = vecs[0].size();
19 std::vector<std::vector<int64_t>> transposed(cols,
20 std::vector<int64_t>(rows));
21 for (std::size_t i = 0; i < rows; ++i) {
22 for (std::size_t j = 0; j < cols; ++j) {
23 transposed[j][i] = vecs[i][j];
24 }
25 }
26 return transposed;
27}

◆ vector1DTypeConverter()

template<typename T, typename V>
std::vector< T > EventReco::vector1DTypeConverter ( const std::vector< V > & input)

Definition at line 60 of file HyPERUtils.h.

60 {
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}

◆ vector2DTypeConverter()

template<typename T, typename V>
std::vector< std::vector< T > > EventReco::vector2DTypeConverter ( const std::vector< std::vector< V > > & input)

Definition at line 70 of file HyPERUtils.h.

71 {
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}
std::vector< T > vector1DTypeConverter(const std::vector< V > &input)
Definition HyPERUtils.h:60

Variable Documentation

◆ g_hyper_msg_level

MSG::Level EventReco::g_hyper_msg_level = MSG::INFO
thread_local

Definition at line 10 of file HyPERUtils.cxx.