ATLAS Offline Software
SystObjectUnioniserAlg.icc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 /// @author Teng Jian Khoo
6 
7 #include <iomanip>
8 #include <set>
9 
10 #include <AthLinks/ElementLink.h>
11 #include "AsgAnalysisAlgorithms/SystObjectUnioniserAlg.h"
12 
13 namespace CP
14 {
15  template<class T, class C>
16  StatusCode SystObjectUnioniserAlg<T,C> ::initialize()
17  {
18 
19  ATH_CHECK (m_inputHandle.initialize(m_systematicsList));
20  // ATH_CHECK (m_syst_link_acc.initialize(m_systematicsList, m_outputHandle));
21  ATH_CHECK (m_outputHandle.initialize(m_systematicsList));
22 
23  // Intialise syst list (must come after all syst-aware inputs and outputs)
24  ATH_CHECK (m_systematicsList.initialize());
25 
26  for(const auto& sys : m_systematicsList.systematicsVector()) {
27  std::string decor_name{};
28  ATH_CHECK (m_systematicsList.service().makeSystematicsName(decor_name, m_syst_decor_pattern, sys));
29  m_syst_link_acc.insert({sys.hash(),SG::AuxElement::ConstAccessor<iplink_t>(decor_name)});
30  }
31 
32  return StatusCode::SUCCESS;
33  }
34 
35  template<class T, class C>
36  StatusCode SystObjectUnioniserAlg<T,C> ::execute(const EventContext&) const
37  {
38  static const SG::AuxElement::ConstAccessor< iplink_t > acc_nominalObject("nominalObjectLink");
39 
40  // Populate a map of systematics hash to container, so we
41  // can iterate safely regardless of the ordering of systs
42  // from the SystematicsSvc
43  // (mainly avoid assumption that nominal comes first)
44  std::unordered_map<std::size_t, const C*> systhash_to_container;
45  systhash_to_container.reserve(m_systematicsList.systematicsVector().size());
46  // Loop is over CP::SystematicsSet, but recommended to use auto
47  // in case this ever changes...
48  for (const auto& sys : m_systematicsList.systematicsVector()) {
49  const C* sys_container = nullptr;
50  ATH_CHECK( m_inputHandle.retrieve(sys_container, sys) );
51  systhash_to_container.insert({sys.hash(), sys_container});
52  }
53 
54  // Collect the nominal objects that are in any of the
55  // filtered collections
56  std::set<const T*> passed_nominal_objects;
57  for (const auto& sys : m_systematicsList.systematicsVector()) {
58  if(sys.name().empty()) {
59  // In this case, we don't have to touch any ElementLinks
60  const C& nom_cont = *systhash_to_container[sys.hash()];
61  passed_nominal_objects.insert(nom_cont.begin(),nom_cont.end());
62  ATH_MSG_DEBUG("Gathered " << passed_nominal_objects.size() << " nominal objects");
63  } else {
64  // In this case we have to extract the nominal objects via links
65  const C& var_cont = *systhash_to_container[sys.hash()];
66  for(const T* var_obj : var_cont) {
67  ATH_MSG_VERBOSE("Locating nominal object from selection with variation " << sys.name());
68  const T* nom_obj = static_cast<const T*>(*acc_nominalObject(*var_obj));
69  auto result = passed_nominal_objects.insert(nom_obj);
70  if(result.second) {
71  ATH_MSG_VERBOSE("Added variation object with index " << var_obj->index());
72  } else {
73  ATH_MSG_VERBOSE("Object for " << sys.name() << " with index " << var_obj->index() << " is already selected");
74  }}
75  }
76  }
77 
78  // Build the output containers
79  for (const auto& sys : m_systematicsList.systematicsVector()) {
80  if(sys.name().empty()) {
81  // Simply write out the set
82  auto cdv_nom = std::make_unique<ConstDataVector<C> >(
83  passed_nominal_objects.begin(),
84  passed_nominal_objects.end(),
85  SG::VIEW_ELEMENTS
86  );
87  ATH_MSG_DEBUG("Recording " << cdv_nom->size() << " objects in nominal container");
88  ATH_CHECK(m_outputHandle.record(std::move(cdv_nom),sys));
89  } else {
90  // Create a new CDV, and fill it with the variation objects
91  // corresponding to each nominal object
92  auto cdv_var = std::make_unique<ConstDataVector<C> >(
93  SG::VIEW_ELEMENTS);
94  for(const T* nom_obj : passed_nominal_objects) {
95  ATH_MSG_VERBOSE("Locating systematic object from nominal object " << nom_obj->index());
96  const T* var_obj = static_cast<const T*>(*m_syst_link_acc.at(sys.hash())(*nom_obj));
97  cdv_var->push_back(var_obj);
98  }
99  ATH_MSG_DEBUG("Recording " << cdv_var->size() << " objects in '" << sys.name() << "' container");
100  ATH_CHECK(m_outputHandle.record(std::move(cdv_var), sys));
101  }
102  }
103 
104  return StatusCode::SUCCESS;
105  }
106 
107 }