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