ATLAS Offline Software
Loading...
Searching...
No Matches
SystObjectLinkerAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include <unordered_map>
8#include <iomanip>
9
13
15static const SG::Decorator< iplink_t > dec_nominalObject("nominalObjectLink");
16
17namespace CP
18{
19 SystObjectLinkerAlg ::SystObjectLinkerAlg(const std::string &name,
20 ISvcLocator *pSvcLocator)
21 : EL::AnaReentrantAlgorithm(name, pSvcLocator)
22 {
23
24 }
25
26 StatusCode SystObjectLinkerAlg ::initialize()
27 {
28
29 // Read syst-aware input handles
31
32 // Intialise syst-aware output decorators
34
35 // Intialise syst list (must come after all syst-aware inputs and outputs)
36 ATH_CHECK (m_systematicsList.initialize());
37
38 ATH_MSG_DEBUG("Adding nominal/systematic object links for " << m_inputHandle.getNamePattern());
39
40 return StatusCode::SUCCESS;
41 }
42
43 StatusCode SystObjectLinkerAlg ::execute(const EventContext&) const
44 {
45
46 // Populate a map of systematics hash to container, so we
47 // can iterate safely regardless of the ordering of systs
48 // from the SystematicsSvc
49 // (mainly avoid assumption that nominal comes first)
50 std::unordered_map<std::size_t, const xAOD::IParticleContainer*> systhash_to_container;
51 systhash_to_container.reserve(m_systematicsList.systematicsVector().size());
52 // Record the hash for the nominal for easier access
53 size_t nominal_hash{SIZE_MAX};
54 // Loop is over CP::SystematicsSet, but recommended to use auto
55 // in case this ever changes...
56 for (const auto& sys : m_systematicsList.systematicsVector())
57 {
58 const xAOD::IParticleContainer* sys_container = nullptr;
59 ATH_CHECK( m_inputHandle.retrieve(sys_container, sys) );
60
61 // Record the hash for the nominal
62 if(sys.name().empty()) {nominal_hash = sys.hash();}
63
64 // We can't find the original container if the systematics
65 // copies are empty. This is a slight vulnerability.
66 if (sys_container->empty()) {
67 ATH_MSG_DEBUG("Container for systematic variation '" << sys.name() << "' was empty.");
68 systhash_to_container.insert({sys.hash(), nullptr});
69 continue;
70 }
71
72 // Navigate to the full container, as this may be a view container
73 // holding a subset of the objects
74 // Cast from SG::AuxVectorData
75 const xAOD::IParticleContainer* full_container =
76 static_cast<const xAOD::IParticleContainer*>(sys_container->front()->container());
77 systhash_to_container.insert({sys.hash(), full_container});
78 if(full_container == sys_container) {
79 ATH_MSG_VERBOSE("The unfiltered container and the input container are the same.");
80 } else {
81 ATH_MSG_DEBUG("Read in container with " << sys_container->size() << " elements.");
82 ATH_MSG_DEBUG("Traced back to unfiltered container with " << full_container->size() << " elements.");
83 }
84 }
85
86 if(nominal_hash==SIZE_MAX) {
87 ATH_MSG_ERROR("The nominal variation was not detected!");
88 return StatusCode::FAILURE;
89 }
90
91 // Iterate over the nominal container, extract the index-parallel syst
92 // Then apply the bidirectional links as decorations
93 const xAOD::IParticleContainer* nom_cont = systhash_to_container[nominal_hash];
94 if(nom_cont==nullptr) {
95 ATH_MSG_DEBUG("Unable to retrieve the nominal container, will have to assume there are no relevant objects");
96 return StatusCode::SUCCESS;
97 }
98
99 for (const xAOD::IParticle* nom_obj : *nom_cont) {
100 for (const auto& sys : m_systematicsList.systematicsVector()) {
101 if(sys.hash()==nominal_hash) {continue;}
102 const xAOD::IParticleContainer *var_cont = systhash_to_container[sys.hash()];
103 if(var_cont==nullptr) {
104 ATH_MSG_ERROR("Cannot decorate syst '" << sys.name() << "' for obj " << nom_obj->index());
105 ATH_MSG_ERROR("Likely the systematics input container was empty after filtering.");
106 //must return here, the var_cont pointer is dereferenced in the next line
107 return StatusCode::FAILURE;
108 }
109 const xAOD::IParticle* var_obj = (*var_cont)[nom_obj->index()];
110 dec_nominalObject(*var_obj) = iplink_t(*nom_cont, nom_obj->index());
111 ATH_MSG_VERBOSE("Writing decoration " << m_syst_link_decor.getName(sys) << " from object " << nom_obj->index());
112 m_syst_link_decor.set(*nom_obj, iplink_t(*var_cont, var_obj->index()), sys);
113 ATH_MSG_VERBOSE("Nominal object with pt " << std::setprecision(3) << nom_obj->pt()/1e3 << " GeV linked to");
114 ATH_MSG_VERBOSE(" '" << sys.name() << "' varied object with pt " << std::setprecision(3) << var_obj->pt()/1e3 << " GeV.");
115 }
116 }
117
118 return StatusCode::SUCCESS;
119 }
120}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
DataVector adapter that acts like it holds const pointers.
ElementLink< xAOD::IParticleContainer > iplink_t
static const SG::Decorator< iplink_t > dec_nominalObject("nominalObjectLink")
CP::SysReadHandle< xAOD::IParticleContainer > m_inputHandle
Setup syst-aware input container handles.
CP::SysListHandle m_systematicsList
We use default finalize() – this is for cleanup, and we don't do any.
CP::SysWriteDecorHandle< ElementLink< xAOD::IParticleContainer > > m_syst_link_decor
Setup sys-aware output decorations.
const T * front() const
Access the first element in the collection as an rvalue.
size_type size() const noexcept
Returns the number of elements in the collection.
bool empty() const noexcept
Returns true if the collection is empty.
AnaReentrantAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
constructor with parameters
size_t index() const
Return the index of this element within its container.
Helper class to provide type-safe access to aux data.
Definition Decorator.h:59
Class providing the definition of the 4-vector interface.
virtual double pt() const =0
The transverse momentum ( ) of the particle.
Select isolated Photons, Electrons and Muons.
ElementLink< xAOD::IParticleContainer > iplink_t
This module defines the arguments passed from the BATCH driver to the BATCH worker.
DataVector< IParticle > IParticleContainer
Simple convenience declaration of IParticleContainer.