1 // In case the extension is confusing, this is a -*- C++ -*- file
3 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
6 #include "StoreGate/ReadDecorHandle.h"
10 namespace FlavorTagInference {
11 template <typename C, typename D, typename N>
12 StatusCode DecoratorAlg<C,D,N>::initialize()
14 return initializeInternal();
17 template <typename C, typename D, typename N>
18 StatusCode DecoratorAlg<C,D,N>::initializeInternal(
19 DecoratorAlg::ExtraDependencies extraDeps)
21 ATH_CHECK(m_containerKey.initialize());
22 ATH_CHECK(m_constituentKey.initialize());
23 ATH_CHECK(m_electronKey.initialize(!m_electronKey.empty()));
25 ATH_CHECK(m_decorator.retrieve());
27 std::set<std::string> veto(
28 m_undeclaredReadDecorKeys.begin(),
29 m_undeclaredReadDecorKeys.end());
31 // now we build data dependencies from the internal tools. We have
32 // to reserve the vectors here to prevent a segfault since read /
33 // write handles aren't movable once declaired as a property.
34 auto deps = m_decorator->getDependencies();
36 auto auxKeys = deps.bTagInputs;
37 auxKeys.merge(extraDeps);
38 m_aux.reserve(auxKeys.size());
39 for (const std::string& key: auxKeys) {
40 const std::string full = m_containerKey.key() + "." + key;
41 if (veto.count(full)) {
42 ATH_MSG_DEBUG("Not declaring accessor: " + full);
45 ATH_MSG_DEBUG("Adding accessor: " + full);
46 m_aux.emplace_back(this, key, full, "");
47 ATH_CHECK(m_aux.back().initialize());
50 auto trackInputs = deps.trackInputs;
51 m_constituentAux.reserve(trackInputs.size());
52 for (const std::string& key: trackInputs) {
53 const std::string full = m_constituentKey.key() + "." + key;
54 if (veto.count(full)) {
55 ATH_MSG_DEBUG("Not declaring accessor: " + full);
58 ATH_MSG_DEBUG("Adding constituent accessor: " + full);
59 m_constituentAux.emplace_back(this, key, full, "");
60 ATH_CHECK(m_constituentAux.back().initialize());
63 size_t n_electron_inputs = deps.electronInputs.size();
64 if (n_electron_inputs > 0 && m_electronKey.empty()) {
65 ATH_MSG_ERROR("using electrons without defining the input container");
66 return StatusCode::FAILURE;
68 m_electronAux.reserve(n_electron_inputs);
69 for (const std::string& key: deps.electronInputs) {
70 const std::string full = m_electronKey.key() + "." + key;
71 ATH_MSG_DEBUG("Adding electron accessor: " + full);
72 m_electronAux.emplace_back(this, key, full, "");
73 ATH_CHECK(m_electronAux.back().initialize());
76 std::set<std::string> keys = deps.bTagOutputs;
77 m_decor.reserve(keys.size());
78 for (const std::string& key: keys) {
79 const std::string full = m_containerKey.key() + "." + key;
80 m_decor.emplace_back(this, key, full, "");
81 ATH_CHECK(m_decor.back().initialize());
83 SG::auxid_t auxid = SG::AuxTypeRegistry::instance().findAuxID(key);
84 ATH_MSG_DEBUG("Added decorator: " + full + ","
85 " key " + key + " has auxid " + std::to_string(auxid) );
86 m_auxids.push_back(auxid);
88 ATH_MSG_DEBUG("Finished setting up");
89 return StatusCode::SUCCESS;
93 template <typename C, typename D, typename N>
94 StatusCode DecoratorAlg<C,D,N>::execute(const EventContext& cxt ) const {
95 SG::ReadHandle<C> container(
97 if (!container.isValid()) {
98 ATH_MSG_ERROR("no container " << container.key());
99 return StatusCode::FAILURE;
102 "Decorating " + std::to_string(container->size()) + " elements");
103 for (const auto* element: *container) {
104 m_decorator->decorate(*element);
107 // Lock the decorations
109 for (SG::auxid_t id: m_auxids) {
110 ATH_MSG_DEBUG("locking auxid " << id << " in " << m_containerKey.key());
111 const_cast<C*>(container.cptr())->lockDecoration(id);
114 return StatusCode::SUCCESS;
117 template <typename C, typename D, typename N>
118 StatusCode DecoratorAlg<C,D,N>::finalize() {
119 return StatusCode::SUCCESS;