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-2023 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"
32
33#include "xAODPFlow/PFO.h"
45
46
47#ifndef XAOD_ANALYSIS
49#endif
50
52 // Changed from IJetExecute
54 public:
55 JetConstituentModSequence(const std::string &name); // MEN: constructor
56 StatusCode initialize();
57 int execute() const;
58
59protected:
60 Gaudi::Property<std::string> m_inputContainer {this, "InputContainer", "", "The input container for the sequence"};
61 Gaudi::Property<std::string> m_outputContainer = {this, "OutputContainer", "", "The output container for the sequence"};
62 Gaudi::Property<bool> m_byVertex = {this, "DoByVertex", false, "True if we should match to each primary vertex, not just PV0"};
63 SG::ReadHandleKey<xAOD::VertexContainer> m_vertexContainerKey{this, "VertexContainerKey", "PrimaryVertices", "Reconstructed primary vertex container name"};
64
65 // P-A : the actual type
66 // Define as a basic integer type because Gaudi
67 // doesn't support arbitrary property types
68 unsigned short m_inputType; //
69
70
71 ToolHandleArray<IJetConstituentModifier> m_modifiers{this , "Modifiers" , {} , "List of constit modifier tools."};
72
73#ifndef XAOD_ANALYSIS
74 ToolHandle<GenericMonitoringTool> m_monTool{this,"MonTool","","Monitoring tool"};
75#endif
76
77 bool m_saveAsShallow = true;
78
79 // note: not all keys will be used for a particular instantiation
80 SG::ReadHandleKey<xAOD::CaloClusterContainer> m_inClusterKey{this, "InClusterKey", "", "ReadHandleKey for unmodified CaloClusters"};
81 SG::WriteHandleKey<xAOD::CaloClusterContainer> m_outClusterKey{this, "OutClusterKey", "", "WriteHandleKey for modified CaloClusters"};
82
83 SG::ReadHandleKey<xAOD::TrackCaloClusterContainer> m_inTCCKey{this, "InTCCKey", "", "ReadHandleKey for unmodified TrackCaloClusters"};
84 SG::WriteHandleKey<xAOD::TrackCaloClusterContainer> m_outTCCKey{this, "OutTCCKey", "", "WriteHandleKey for modified TrackCaloClusters"};
85
86 SG::ReadHandleKey<xAOD::PFOContainer> m_inChargedPFOKey{this, "InChargedPFOKey", "", "ReadHandleKey for modified Charged PFlow Objects"};
87 SG::WriteHandleKey<xAOD::PFOContainer> m_outChargedPFOKey{this, "OutChargedPFOKey", "", "WriteHandleKey for modified Charged PFlow Objects"};
88
89 SG::ReadHandleKey<xAOD::PFOContainer> m_inNeutralPFOKey{this, "InNeutralPFOKey", "", "ReadHandleKey for modified Neutral PFlow Objects"};
90 SG::WriteHandleKey<xAOD::PFOContainer> m_outNeutralPFOKey{this, "OutNeutralPFOKey", "", "WriteHandleKey for modified Neutral PFlow Objects"};
91
92 SG::WriteHandleKey<xAOD::PFOContainer> m_outAllPFOKey{this, "OutAllPFOKey", "", "WriteHandleKey for all modified PFlow Objects"};
93
94 SG::ReadHandleKey<xAOD::FlowElementContainer> m_inChargedFEKey{this, "InChargedFEKey", "", "ReadHandleKey for modified Charged FlowElements"};
95 SG::WriteHandleKey<xAOD::FlowElementContainer> m_outChargedFEKey{this, "OutChargedFEKey", "", "WriteHandleKey for modified Charged FlowElements"};
96
97 SG::ReadHandleKey<xAOD::FlowElementContainer> m_inNeutralFEKey{this, "InNeutralFEKey", "", "ReadHandleKey for modified Neutral FlowElements"};
98 SG::WriteHandleKey<xAOD::FlowElementContainer> m_outNeutralFEKey{this, "OutNeutralFEKey", "", "WriteHandleKey for modified Neutral FlowElements"};
99
100 SG::WriteHandleKey<xAOD::FlowElementContainer> m_outAllFEKey{this, "OutAllFEKey", "", "WriteHandleKey for all modified FlowElements"};
101
102 // this ReadDecorHandleKeyArray holds necessary ReadDecorHandleKeys to make sure this algorithm is scheduled after all the relevant decorations are applied
103 // otherwise FEs can be simultaneously decorated in other algorithms and deep-copied here, causing std::bad_array_new_length exceptions
104 SG::ReadDecorHandleKeyArray<xAOD::FlowElementContainer> m_inChargedFEDecorKeys{this, "InChargedFEDecorKeys", {}, "Dummy keys that force all neccessary charged FlowElement decorations to be applied before running this algorithm"};
105 SG::ReadDecorHandleKeyArray<xAOD::FlowElementContainer> m_inNeutralFEDecorKeys{this, "InNeutralFEDecorKeys", {}, "Dummy keys that force all neccessary neutral FlowElement decorations to be applied before running this algorithm"};
106
108
109 template<class T>
110 StatusCode
112 const SG::WriteHandleKey<T>&) const;
113
114 template<class T, class U>
115 StatusCode
117};
118
119template<class T>
120StatusCode
122 const SG::WriteHandleKey<T>& outKey) const {
123
124 /* Read in a container of (type is template parameter),
125 optionally modify the elements of this container, and store.
126 This puts a (modified) copy of the container into storegate.
127 */
128
129 auto inHandle = makeHandle(inKey);
130 if(!inHandle.isValid()){
131 ATH_MSG_WARNING("Unable to retrieve input container from " << inKey.key());
132 return StatusCode::FAILURE;
133 }
134
135 std::pair< T*, xAOD::ShallowAuxContainer* > newconstit =
136 xAOD::shallowCopyContainer(*inHandle);
137 newconstit.second->setShallowIO(m_saveAsShallow);
138
139 for (auto t : m_modifiers) {ATH_CHECK(t->process(newconstit.first));}
140
141 auto handle = makeHandle(outKey);
142 ATH_CHECK(handle.record(std::unique_ptr<T>(newconstit.first),
143 std::unique_ptr<xAOD::ShallowAuxContainer>(newconstit.second)));
144
145 xAOD::setOriginalObjectLink(*inHandle, *handle);
146
147 return StatusCode::SUCCESS;
148}
149
150template<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 {
151
152 // Cannot be handled the same way as other objects (e.g. clusters),
153 // because the data is split between two containers, but we need
154 // information from both to do the modifications.
155 //
156 // The logic is:
157 // 1. Copy the charged container via a shallow copy
158 // 2. Create N copies of neutral container for by-vertex reconstruction OR
159 // Create a single copy of neutral container for regular jet reconstruction
160 // 3. Merge into a combined view container
161 // 4. Modify the combined container
162
163 // 1. Retrieve the input containers
164 SG::ReadHandle<T> inNeutralHandle = makeHandle(inNeutralKey);
165 SG::ReadHandle<T> inChargedHandle = makeHandle(inChargedKey);
166 if(!inNeutralHandle.isValid()){
167 ATH_MSG_WARNING("Unable to retrieve input containers \""
168 << inNeutralKey.key() << "\" and \""
169 << inChargedKey.key() << "\"");
170 return StatusCode::FAILURE;
171 }
172
173 unsigned numNeutralCopies = 1;
174 if (m_byVertex){
175 // Retrieve Primary Vertices
177 if (!handle.isValid()){
178 ATH_MSG_WARNING(" This event has no primary vertex container" );
179 return StatusCode::FAILURE;
180 }
181
182 const xAOD::VertexContainer* vertices = handle.cptr();
183 if(vertices->empty()){
184 ATH_MSG_WARNING(" Failed to retrieve valid primary vertex container" );
185 return StatusCode::FAILURE;
186 }
187 numNeutralCopies = static_cast<unsigned>(vertices->size());
188 }
189
190 // Copy the input containers individually, set I/O option and record
191 // Charged elements
192 SG::WriteHandle<T> outChargedHandle = makeHandle(outChargedKey);
193
194 std::pair<T*, xAOD::ShallowAuxContainer* > chargedCopy = xAOD::shallowCopyContainer(*inChargedHandle);
195 chargedCopy.second->setShallowIO(m_saveAsShallow);
196 xAOD::setOriginalObjectLink(*inChargedHandle, *chargedCopy.first);
197
198 ATH_CHECK(outChargedHandle.record(std::unique_ptr<T>(chargedCopy.first),
199 std::unique_ptr<xAOD::ShallowAuxContainer>(chargedCopy.second)));
200
201 // Neutral elements
202 SG::WriteHandle<T> outNeutralHandle = makeHandle(outNeutralKey);
203
204 // Shallow copy
205 if (m_saveAsShallow){
206
207 std::pair<T*, xAOD::ShallowAuxContainer* > neutralCopy = xAOD::shallowCopyContainer(*inNeutralHandle);
208 chargedCopy.second->setShallowIO(true);
209 xAOD::setOriginalObjectLink(*inNeutralHandle, *neutralCopy.first);
210
211 ATH_CHECK(outNeutralHandle.record(std::unique_ptr<T>(neutralCopy.first),
212 std::unique_ptr<xAOD::ShallowAuxContainer>(neutralCopy.second)));
213
214 }
215 // Deep copy
216 else{
217 // Define the accessor which will add the index
218 const SG::AuxElement::Accessor<unsigned> copyIndex("ConstituentCopyIndex");
219
220 // Create the new container and its auxiliary store.
221 auto neutralCopies = std::make_unique<T>();
222 auto neutralCopiesAux = std::make_unique<xAOD::AuxContainerBase>();
223 neutralCopies->setStore(neutralCopiesAux.get()); //< Connect the two
224
225 // Create N copies and set copy index
226 // Necessary for by-vertex jet reconstruction
227 for (unsigned i = 0; i < numNeutralCopies; i++){
228 for (const U* fe : *inNeutralHandle) {
229 U* copy = new U();
230 neutralCopies->push_back(copy);
231 *copy = *fe;
232 copyIndex(*copy) = i;
233 xAOD::setOriginalObjectLink(*fe, *copy);
234 }
235 }
236
237 ATH_CHECK(outNeutralHandle.record(std::move(neutralCopies),
238 std::move(neutralCopiesAux))
239 );
240 }
241
242
243 // 2. Set up output handle for merged (view) container and record
244 SG::WriteHandle<T> outAllHandle = makeHandle(outAllKey);
245 ATH_CHECK(outAllHandle.record(std::make_unique<T>(SG::VIEW_ELEMENTS)));
246 (*outAllHandle).assign((*outNeutralHandle).begin(), (*outNeutralHandle).end());
247 (*outAllHandle).insert((*outAllHandle).end(),
248 (*outChargedHandle).begin(),
249 (*outChargedHandle).end());
250
251 // 3. Now process modifications on all elements
252 for (auto t : m_modifiers) {ATH_CHECK(t->process(&*outAllHandle));}
253 return StatusCode::SUCCESS;
254}
255
256
257#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:572
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...