ATLAS Offline Software
Loading...
Searching...
No Matches
JetConstituentModSequence.h
Go to the documentation of this file.
1// this file is -*- C++ -*-
2
3/*
4 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
5*/
6
7//JetConstituentModSequence.h
8
9#ifndef JETRECTOOLS_JETCONSTITUENTMODSEQUENCE_H
10#define JETRECTOOLS_JETCONSTITUENTMODSEQUENCE_H
11
12//
13// Michael Nelson, CERN & Univesity of Oxford
14// February, 2016
15
16#include <string>
19
20
21#include "AsgTools/AsgTool.h"
33
34#include "xAODPFlow/PFO.h"
46
47
48#ifndef XAOD_ANALYSIS
50#endif
51
53 // Changed from IJetExecute
55 public:
56 JetConstituentModSequence(const std::string &name); // MEN: constructor
57 StatusCode initialize();
58 int execute() const;
59
60protected:
61 Gaudi::Property<std::string> m_inputContainer {this, "InputContainer", "", "The input container for the sequence"};
62 Gaudi::Property<std::string> m_outputContainer = {this, "OutputContainer", "", "The output container for the sequence"};
63 Gaudi::Property<bool> m_byVertex = {this, "DoByVertex", false, "True if we should match to each primary vertex, not just PV0"};
64 SG::ReadHandleKey<xAOD::VertexContainer> m_vertexContainerKey{this, "VertexContainerKey", "PrimaryVertices", "Reconstructed primary vertex container name"};
65
66 // P-A : the actual type
67 // Define as a basic integer type because Gaudi
68 // doesn't support arbitrary property types
69 unsigned short m_inputType; //
70
71
72 ToolHandleArray<IJetConstituentModifier> m_modifiers{this , "Modifiers" , {} , "List of constit modifier tools."};
73
74#ifndef XAOD_ANALYSIS
75 ToolHandle<GenericMonitoringTool> m_monTool{this,"MonTool","","Monitoring tool"};
76#endif
77
78 bool m_saveAsShallow = true;
79
80 // note: not all keys will be used for a particular instantiation
81 SG::ReadHandleKey<xAOD::CaloClusterContainer> m_inClusterKey{this, "InClusterKey", "", "ReadHandleKey for unmodified CaloClusters"};
82 SG::WriteHandleKey<xAOD::CaloClusterContainer> m_outClusterKey{this, "OutClusterKey", "", "WriteHandleKey for modified CaloClusters"};
83
84 SG::ReadHandleKey<xAOD::TrackCaloClusterContainer> m_inTCCKey{this, "InTCCKey", "", "ReadHandleKey for unmodified TrackCaloClusters"};
85 SG::WriteHandleKey<xAOD::TrackCaloClusterContainer> m_outTCCKey{this, "OutTCCKey", "", "WriteHandleKey for modified TrackCaloClusters"};
86
87 SG::ReadHandleKey<xAOD::PFOContainer> m_inChargedPFOKey{this, "InChargedPFOKey", "", "ReadHandleKey for modified Charged PFlow Objects"};
88 SG::WriteHandleKey<xAOD::PFOContainer> m_outChargedPFOKey{this, "OutChargedPFOKey", "", "WriteHandleKey for modified Charged PFlow Objects"};
89
90 SG::ReadHandleKey<xAOD::PFOContainer> m_inNeutralPFOKey{this, "InNeutralPFOKey", "", "ReadHandleKey for modified Neutral PFlow Objects"};
91 SG::WriteHandleKey<xAOD::PFOContainer> m_outNeutralPFOKey{this, "OutNeutralPFOKey", "", "WriteHandleKey for modified Neutral PFlow Objects"};
92
93 SG::WriteHandleKey<xAOD::PFOContainer> m_outAllPFOKey{this, "OutAllPFOKey", "", "WriteHandleKey for all modified PFlow Objects"};
94
95 SG::ReadHandleKey<xAOD::FlowElementContainer> m_inChargedFEKey{this, "InChargedFEKey", "", "ReadHandleKey for modified Charged FlowElements"};
96 SG::WriteHandleKey<xAOD::FlowElementContainer> m_outChargedFEKey{this, "OutChargedFEKey", "", "WriteHandleKey for modified Charged FlowElements"};
97
98 SG::ReadHandleKey<xAOD::FlowElementContainer> m_inNeutralFEKey{this, "InNeutralFEKey", "", "ReadHandleKey for modified Neutral FlowElements"};
99 SG::WriteHandleKey<xAOD::FlowElementContainer> m_outNeutralFEKey{this, "OutNeutralFEKey", "", "WriteHandleKey for modified Neutral FlowElements"};
100
101 SG::WriteHandleKey<xAOD::FlowElementContainer> m_outAllFEKey{this, "OutAllFEKey", "", "WriteHandleKey for all modified FlowElements"};
102
103 // this ReadDecorHandleKeyArray holds necessary ReadDecorHandleKeys to make sure this algorithm is scheduled after all the relevant decorations are applied
104 // otherwise FEs can be simultaneously decorated in other algorithms and deep-copied here, causing std::bad_array_new_length exceptions
105 SG::ReadDecorHandleKeyArray<xAOD::FlowElementContainer> m_inChargedFEDecorKeys{this, "InChargedFEDecorKeys", {}, "Dummy keys that force all neccessary charged FlowElement decorations to be applied before running this algorithm"};
106 SG::ReadDecorHandleKeyArray<xAOD::FlowElementContainer> m_inNeutralFEDecorKeys{this, "InNeutralFEDecorKeys", {}, "Dummy keys that force all neccessary neutral FlowElement decorations to be applied before running this algorithm"};
107
109
110 template<class T>
111 StatusCode
113 const SG::WriteHandleKey<T>&) const;
114
115 template<class T, class U>
116 StatusCode
118};
119
120template<class T>
121StatusCode
123 const SG::WriteHandleKey<T>& outKey) const {
124
125 const EventContext& ctx = Gaudi::Hive::currentContext();
126
127 /* Read in a container of (type is template parameter),
128 optionally modify the elements of this container, and store.
129 This puts a (modified) copy of the container into storegate.
130 */
131
132 auto inHandle = makeHandle(inKey, ctx);
133 if(!inHandle.isValid()){
134 ATH_MSG_WARNING("Unable to retrieve input container from " << inKey.key());
135 return StatusCode::FAILURE;
136 }
137
138 std::pair< std::unique_ptr<T>, std::unique_ptr<xAOD::ShallowAuxContainer> > newconstit =
139 xAOD::shallowCopyContainer(*inHandle, Gaudi::Hive::currentContext());
140 newconstit.second->setShallowIO(m_saveAsShallow);
141
142 for (auto t : m_modifiers) {ATH_CHECK(t->process(newconstit.first.get()));}
143
144 auto handle = makeHandle(outKey, ctx);
145 ATH_CHECK(handle.record(std::move(newconstit.first), std::move(newconstit.second)));
146
147 xAOD::setOriginalObjectLink(*inHandle, *handle);
148
149 return StatusCode::SUCCESS;
150}
151
152template<class T, class U> StatusCode JetConstituentModSequence::copyModRecordFlowLike(const SG::ReadHandleKey<T>& inNeutralKey, const SG::ReadHandleKey<T>& inChargedKey, const SG::WriteHandleKey<T>& outNeutralKey, const SG::WriteHandleKey<T>& outChargedKey, const SG::WriteHandleKey<T>& outAllKey) const {
153
154 const EventContext& ctx = Gaudi::Hive::currentContext();
155
156 // Cannot be handled the same way as other objects (e.g. clusters),
157 // because the data is split between two containers, but we need
158 // information from both to do the modifications.
159 //
160 // The logic is:
161 // 1. Copy the charged container via a shallow copy
162 // 2. Create N copies of neutral container for by-vertex reconstruction OR
163 // Create a single copy of neutral container for regular jet reconstruction
164 // 3. Merge into a combined view container
165 // 4. Modify the combined container
166
167 // 1. Retrieve the input containers
168 SG::ReadHandle<T> inNeutralHandle = makeHandle(inNeutralKey, ctx);
169 SG::ReadHandle<T> inChargedHandle = makeHandle(inChargedKey, ctx);
170 if(!inNeutralHandle.isValid()){
171 ATH_MSG_WARNING("Unable to retrieve input containers \""
172 << inNeutralKey.key() << "\" and \""
173 << inChargedKey.key() << "\"");
174 return StatusCode::FAILURE;
175 }
176
177 unsigned numNeutralCopies = 1;
178 if (m_byVertex){
179 // Retrieve Primary Vertices
181 if (!handle.isValid()){
182 ATH_MSG_WARNING(" This event has no primary vertex container" );
183 return StatusCode::FAILURE;
184 }
185
186 const xAOD::VertexContainer* vertices = handle.cptr();
187 if(vertices->empty()){
188 ATH_MSG_WARNING(" Failed to retrieve valid primary vertex container" );
189 return StatusCode::FAILURE;
190 }
191 numNeutralCopies = static_cast<unsigned>(vertices->size());
192 }
193
194 // Copy the input containers individually, set I/O option and record
195 // Charged elements
196 SG::WriteHandle<T> outChargedHandle = makeHandle(outChargedKey, ctx);
197
198 std::pair<std::unique_ptr<T>, std::unique_ptr<xAOD::ShallowAuxContainer> > chargedCopy =
199 xAOD::shallowCopyContainer(*inChargedHandle, ctx);
200 chargedCopy.second->setShallowIO(m_saveAsShallow);
201 xAOD::setOriginalObjectLink(*inChargedHandle, *chargedCopy.first);
202
203 ATH_CHECK(outChargedHandle.record(std::move(chargedCopy.first),
204 std::move(chargedCopy.second)));
205
206 // Neutral elements
207 SG::WriteHandle<T> outNeutralHandle = makeHandle(outNeutralKey, ctx);
208
209 // Shallow copy
210 if (m_saveAsShallow){
211
212 std::pair<std::unique_ptr<T>, std::unique_ptr<xAOD::ShallowAuxContainer> > neutralCopy =
213 xAOD::shallowCopyContainer(*inNeutralHandle, ctx);
214 neutralCopy.second->setShallowIO(true);
215 xAOD::setOriginalObjectLink(*inNeutralHandle, *neutralCopy.first);
216
217 ATH_CHECK(outNeutralHandle.record(std::move(neutralCopy.first),
218 std::move(neutralCopy.second)));
219
220 }
221 // Deep copy
222 else{
223 // Define the accessor which will add the index
224 const SG::AuxElement::Accessor<unsigned> copyIndex("ConstituentCopyIndex");
225
226 // Create the new container and its auxiliary store.
227 auto neutralCopies = std::make_unique<T>();
228 auto neutralCopiesAux = std::make_unique<xAOD::AuxContainerBase>();
229 neutralCopies->setStore(neutralCopiesAux.get()); //< Connect the two
230
231 // Create N copies and set copy index
232 // Necessary for by-vertex jet reconstruction
233 for (unsigned i = 0; i < numNeutralCopies; i++){
234 for (const U* fe : *inNeutralHandle) {
235 U* copy = new U();
236 neutralCopies->push_back(copy);
237 *copy = *fe;
238 copyIndex(*copy) = i;
239 xAOD::setOriginalObjectLink(*fe, *copy);
240 }
241 }
242
243 ATH_CHECK(outNeutralHandle.record(std::move(neutralCopies),
244 std::move(neutralCopiesAux))
245 );
246 }
247
248
249 // 2. Set up output handle for merged (view) container and record
250 SG::WriteHandle<T> outAllHandle = makeHandle(outAllKey, ctx);
251 ATH_CHECK(outAllHandle.record(std::make_unique<T>(SG::VIEW_ELEMENTS)));
252 (*outAllHandle).assign((*outNeutralHandle).begin(), (*outNeutralHandle).end());
253 (*outAllHandle).insert((*outAllHandle).end(),
254 (*outChargedHandle).begin(),
255 (*outChargedHandle).end());
256
257 // 3. Now process modifications on all elements
258 for (auto t : m_modifiers) {ATH_CHECK(t->process(&*outAllHandle));}
259 return StatusCode::SUCCESS;
260}
261
262
263#endif
#define ASG_TOOL_CLASS(CLASSNAME, INT1)
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
Handle class for reading a decoration on an object.
Property holding a SG store/key/clid from which a ReadHandle is made.
Handle class for reading from StoreGate.
Property holding a SG store/key/clid from which a WriteHandle is made.
Handle class for recording to StoreGate.
size_type size() const noexcept
Returns the number of elements in the collection.
bool empty() const noexcept
Returns true if the collection is empty.
IJetExecuteTool is a dual-use tool interface for generic tools, i.e. those that behave like algorithm...
SG::ReadHandleKey< xAOD::FlowElementContainer > m_inChargedFEKey
StatusCode copyModRecord(const SG::ReadHandleKey< T > &, const SG::WriteHandleKey< T > &) const
helper function to cast, shallow copy and record a container.
ToolHandle< GenericMonitoringTool > m_monTool
Gaudi::Property< bool > m_byVertex
SG::WriteHandleKey< xAOD::PFOContainer > m_outChargedPFOKey
Gaudi::Property< std::string > m_outputContainer
SG::WriteHandleKey< xAOD::PFOContainer > m_outNeutralPFOKey
SG::ReadHandleKey< xAOD::PFOContainer > m_inChargedPFOKey
SG::ReadHandleKey< xAOD::VertexContainer > m_vertexContainerKey
SG::WriteHandleKey< xAOD::PFOContainer > m_outAllPFOKey
SG::WriteHandleKey< xAOD::TrackCaloClusterContainer > m_outTCCKey
SG::WriteHandleKey< xAOD::FlowElementContainer > m_outAllFEKey
SG::WriteHandleKey< xAOD::FlowElementContainer > m_outNeutralFEKey
SG::ReadDecorHandleKeyArray< xAOD::FlowElementContainer > m_inChargedFEDecorKeys
SG::ReadHandleKey< xAOD::TrackCaloClusterContainer > m_inTCCKey
int execute() const
Method to be called for each event.
JetConstituentModSequence(const std::string &name)
StatusCode initialize()
Dummy implementation of the initialisation function.
ToolHandleArray< IJetConstituentModifier > m_modifiers
Gaudi::Property< std::string > m_inputContainer
SG::WriteHandleKey< xAOD::CaloClusterContainer > m_outClusterKey
SG::ReadHandleKey< xAOD::PFOContainer > m_inNeutralPFOKey
StatusCode copyModRecordFlowLike(const SG::ReadHandleKey< T > &, const SG::ReadHandleKey< T > &, const SG::WriteHandleKey< T > &, const SG::WriteHandleKey< T > &, const SG::WriteHandleKey< T > &) const
SG::ReadHandleKey< xAOD::CaloClusterContainer > m_inClusterKey
SG::ReadDecorHandleKeyArray< xAOD::FlowElementContainer > m_inNeutralFEDecorKeys
SG::WriteHandleKey< xAOD::FlowElementContainer > m_outChargedFEKey
SG::ReadHandleKey< xAOD::FlowElementContainer > m_inNeutralFEKey
SG::Accessor< T, ALLOC > Accessor
Definition AuxElement.h:573
Property holding a SG store/key/clid from which a ReadHandle is made.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const std::string & key() const
Return the StoreGate ID for the referenced object.
Property holding a SG store/key/clid from which a WriteHandle is made.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
Base class for the dual-use tool implementation classes.
Definition AsgTool.h:47
DecorHandleKeyArray< ReadDecorHandle< T, S >, ReadDecorHandleKey< T >, Gaudi::DataHandle::Reader > ReadDecorHandleKeyArray
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
std::pair< std::unique_ptr< T >, std::unique_ptr< ShallowAuxContainer > > shallowCopyContainer(const T &cont, const EventContext &ctx)
Function making a shallow copy of a constant container.
VertexContainer_v1 VertexContainer
Definition of the current "Vertex container version".
bool setOriginalObjectLink(const IParticle &original, IParticle &copy)
This function should be used by CP tools when they make a deep copy of an object in their correctedCo...