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>
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 xAOD::ShallowCopyResult_t<T> newconstit = xAOD::shallowCopy(*inHandle);
139 newconstit.second->setShallowIO(m_saveAsShallow);
140
141 for (auto t : m_modifiers) {ATH_CHECK(t->process(newconstit.first.get()));}
142
143 auto handle = makeHandle(outKey, ctx);
144 ATH_CHECK(handle.record(std::move(newconstit.first), std::move(newconstit.second)));
145
146 xAOD::setOriginalObjectLink(*inHandle, *handle);
147
148 return StatusCode::SUCCESS;
149}
150
151template<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 {
152
153 const EventContext& ctx = Gaudi::Hive::currentContext();
154
155 // Cannot be handled the same way as other objects (e.g. clusters),
156 // because the data is split between two containers, but we need
157 // information from both to do the modifications.
158 //
159 // The logic is:
160 // 1. Copy the charged container via a shallow copy
161 // 2. Create N copies of neutral container for by-vertex reconstruction OR
162 // Create a single copy of neutral container for regular jet reconstruction
163 // 3. Merge into a combined view container
164 // 4. Modify the combined container
165
166 // 1. Retrieve the input containers
167 SG::ReadHandle<T> inNeutralHandle = makeHandle(inNeutralKey, ctx);
168 SG::ReadHandle<T> inChargedHandle = makeHandle(inChargedKey, ctx);
169 if(!inNeutralHandle.isValid()){
170 ATH_MSG_WARNING("Unable to retrieve input containers \""
171 << inNeutralKey.key() << "\" and \""
172 << inChargedKey.key() << "\"");
173 return StatusCode::FAILURE;
174 }
175
176 unsigned numNeutralCopies = 1;
177 if (m_byVertex){
178 // Retrieve Primary Vertices
180 if (!handle.isValid()){
181 ATH_MSG_WARNING(" This event has no primary vertex container" );
182 return StatusCode::FAILURE;
183 }
184
185 const xAOD::VertexContainer* vertices = handle.cptr();
186 if(vertices->empty()){
187 ATH_MSG_WARNING(" Failed to retrieve valid primary vertex container" );
188 return StatusCode::FAILURE;
189 }
190 numNeutralCopies = static_cast<unsigned>(vertices->size());
191 }
192
193 // Copy the input containers individually, set I/O option and record
194 // Charged elements
195 SG::WriteHandle<T> outChargedHandle = makeHandle(outChargedKey, ctx);
196
197 xAOD::ShallowCopyResult_t<T> chargedCopy =
198 xAOD::shallowCopy(*inChargedHandle, ctx);
199 chargedCopy.second->setShallowIO(m_saveAsShallow);
200 xAOD::setOriginalObjectLink(*inChargedHandle, *chargedCopy.first);
201
202 ATH_CHECK(outChargedHandle.record(std::move(chargedCopy.first),
203 std::move(chargedCopy.second)));
204
205 // Neutral elements
206 SG::WriteHandle<T> outNeutralHandle = makeHandle(outNeutralKey, ctx);
207
208 // Shallow copy
209 if (m_saveAsShallow){
210
211 xAOD::ShallowCopyResult_t<T> neutralCopy =
212 xAOD::shallowCopy(*inNeutralHandle, ctx);
213 neutralCopy.second->setShallowIO(true);
214 xAOD::setOriginalObjectLink(*inNeutralHandle, *neutralCopy.first);
215
216 ATH_CHECK(outNeutralHandle.record(std::move(neutralCopy.first),
217 std::move(neutralCopy.second)));
218
219 }
220 // Deep copy
221 else{
222 // Define the accessor which will add the index
223 const SG::AuxElement::Accessor<unsigned> copyIndex("ConstituentCopyIndex");
224
225 // Create the new container and its auxiliary store.
226 auto neutralCopies = std::make_unique<T>();
227 auto neutralCopiesAux = std::make_unique<xAOD::AuxContainerBase>();
228 neutralCopies->setStore(neutralCopiesAux.get()); //< Connect the two
229
230 // Create N copies and set copy index
231 // Necessary for by-vertex jet reconstruction
232 for (unsigned i = 0; i < numNeutralCopies; i++){
233 for (const U* fe : *inNeutralHandle) {
234 U* copy = new U();
235 neutralCopies->push_back(copy);
236 *copy = *fe;
237 copyIndex(*copy) = i;
238 xAOD::setOriginalObjectLink(*fe, *copy);
239 }
240 }
241
242 ATH_CHECK(outNeutralHandle.record(std::move(neutralCopies),
243 std::move(neutralCopiesAux))
244 );
245 }
246
247
248 // 2. Set up output handle for merged (view) container and record
249 SG::WriteHandle<T> outAllHandle = makeHandle(outAllKey, ctx);
250 ATH_CHECK(outAllHandle.record(std::make_unique<T>(SG::VIEW_ELEMENTS)));
251 (*outAllHandle).assign((*outNeutralHandle).begin(), (*outNeutralHandle).end());
252 (*outAllHandle).insert((*outAllHandle).end(),
253 (*outChargedHandle).begin(),
254 (*outChargedHandle).end());
255
256 // 3. Now process modifications on all elements
257 for (auto t : m_modifiers) {ATH_CHECK(t->process(&*outAllHandle));}
258 return StatusCode::SUCCESS;
259}
260
261
262#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
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
::StatusCode StatusCode
StatusCode definition for legacy code.
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())
typename ShallowCopyResult< T >::type ShallowCopyResult_t
Return type of xAOD::shallowCopy.
Definition ShallowCopy.h:68
VertexContainer_v1 VertexContainer
Definition of the current "Vertex container version".
ShallowCopyResult_t< T > shallowCopy(const T &cont, const EventContext &ctx)
Create a shallow copy of an existing container.
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...