ATLAS Offline Software
Loading...
Searching...
No Matches
FoldDecoratorAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "FoldDecoratorAlg.h"
6
9
10#include <nlohmann/json.hpp>
11
12#include <random>
13
14namespace FlavorTagInference {
15
17 const std::string& name, ISvcLocator* svcloc):
18 AthReentrantAlgorithm(name, svcloc)
19 {
20 }
21
23 {
24 ATH_CHECK(m_mcEventNumberKey.initialize());
25 // event info is usually not decorated, renounce the dependency
27 if (m_jetCollection.empty()) {
28 ATH_MSG_ERROR("jet collection not specified");
29 return StatusCode::FAILURE;
30 }
31 m_hashKey = m_jetCollection + "." + m_hashKey.key();
32 ATH_CHECK(m_hashKey.initialize());
33
34 // other entropy sources, mostly counts
35 for (auto& key: m_jetAssociations) {
36 key = m_jetCollection + "." + key.key();
37 }
38 ATH_CHECK(m_jetAssociations.initialize());
39 // most the associations also aren't decorated, renounce these
40 // dependencies too
42 for (auto& key: m_jetInts) {
43 key = m_jetCollection + "." + key.key();
44 }
45 ATH_CHECK(m_jetInts.initialize());
46 // same with jetInts: usually not decorated
48
49 // set up some salts for other sources of entropy
50 std::map<std::string, uint32_t> fullSeeds;
51 for (const auto& [k, v]: m_jetVarSeeds) {
52 fullSeeds[m_jetCollection + "." + k] = v;
53 }
54 auto addHashKeys = [this, &fullSeeds](auto keys) {
55 for (auto& key: keys) {
56 uint32_t salt = m_salt;
57 if (auto h = fullSeeds.extract(key.key())) {
58 salt = std::mt19937(h.mapped())();
59 }
60 this->m_hashedKeys[key.key()] = salt;
61 }
62 };
63 addHashKeys(m_jetAssociations);
64 addHashKeys(m_jetInts);
65 if (!fullSeeds.empty()) {
66 for (const auto& [k, v]: fullSeeds) {
67 ATH_MSG_ERROR("unused salt for jet variable " << k);
68 }
69 return StatusCode::FAILURE;
70 }
71
72 // more sources from constituents
73 std::set<std::string> associations;
74 for (const auto& key: m_jetAssociations) associations.insert(key.key());
75 using charmap_t = std::map<std::string,std::vector<std::string>>;
76 auto chars = nlohmann::json::parse(m_constituentChars);
77 for (const auto& [k, vlist]: chars.get<charmap_t>()) {
78 uint32_t salt = m_salt;
79 std::string key = m_jetCollection + "." + k;
80 if (!associations.count(key)) {
81 ATH_MSG_ERROR("Constituent " << key << " is not read from the jet");
82 return StatusCode::FAILURE;
83 }
84 for (const auto& v: vlist) {
85 if (auto h = m_constituentSeeds.value().extract(v)) {
86 salt = std::mt19937(h.mapped())();
87 }
88 m_chars[key].emplace_back(salt,v);
89 }
90 }
91 if (!m_constituentSeeds.empty()) {
92 for (const auto& [k, v]: m_constituentSeeds) {
93 ATH_MSG_ERROR("unused salt for constituent variable " << k);
94 }
95 return StatusCode::FAILURE;
96 }
97
98 return StatusCode::SUCCESS;
99 }
100
101 StatusCode FoldDecoratorAlg::execute(const EventContext& cxt) const {
103 m_mcEventNumberKey, cxt);
105 m_hashKey, cxt);
106 auto hjetassoc = m_jetAssociations.makeHandles(cxt);
107 auto hjetint = m_jetInts.makeHandles(cxt);
108 uint32_t number = hnumber(*hnumber);
109 auto event_hash = std::mt19937(number ^ m_salt)();
110
111 // get more entropy from jet variables
112 auto getSalt = [this, event_hash](const auto& handle) {
113 return this->m_hashedKeys.at(handle.decorKey()) ^ event_hash;
114 };
115 for (const auto* jet: *hhash) {
116 uint32_t jet_hash = 0;
117 for (const auto& assoc: hjetassoc) {
118 const auto& iplc = assoc(*jet);
119 jet_hash ^= std::mt19937( iplc.size() ^ getSalt(assoc))();
120 if (m_chars.count(assoc.decorKey())) {
121 for (const auto& [salt, acc]: m_chars.at(assoc.decorKey())) {
122 unsigned int count = 0;
123 for (const auto& lnk: iplc) count += acc(**lnk);
124 jet_hash ^= std::mt19937(count ^ salt ^ event_hash)();
125 }
126 }
127 }
128 for (const auto& hint: hjetint) {
129 jet_hash ^= std::mt19937( hint(*jet) ^ getSalt(hint))();
130 }
131 hhash(*jet) = event_hash ^ jet_hash;
132 }
133 return StatusCode::SUCCESS;
134 }
135
136} // end namespace FlavorTagInference
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
Handle class for reading a decoration on an object.
Handle class for adding a decoration to an object.
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce(T &h)
void renounceArray(SG::VarHandleKeyArray &handlesArray)
Header file for AthHistogramAlgorithm.
An algorithm that can be simultaneously executed in multiple threads.
Gaudi::Property< std::map< std::string, uint32_t > > m_jetVarSeeds
FoldDecoratorAlg(const std::string &name, ISvcLocator *svcloc)
Gaudi::Property< std::string > m_jetCollection
SG::ReadDecorHandleKey< xAOD::EventInfo > m_mcEventNumberKey
SG::ReadDecorHandleKeyArray< JC, int > m_jetInts
Gaudi::Property< uint32_t > m_salt
std::unordered_map< std::string, std::vector< SaltedCReader > > m_chars
SG::ReadDecorHandleKeyArray< JC, IPLV > m_jetAssociations
Gaudi::Property< std::map< std::string, uint32_t > > m_constituentSeeds
Gaudi::Property< std::string > m_constituentChars
std::unordered_map< std::string, uint32_t > m_hashedKeys
SG::WriteDecorHandleKey< JC > m_hashKey
virtual StatusCode initialize() override
virtual StatusCode execute(const EventContext &cxt) const override
Handle class for reading a decoration on an object.
Handle class for adding a decoration to an object.
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:146
This file contains "getter" functions used for accessing tagger inputs from the EDM.
std::string number(const double &d, const std::string &s)
Definition utils.cxx:186