79 {
80 const EventContext &ctx = Gaudi::Hive::currentContext();
81
82
84 if (!
jets.isValid()) {
86 return StatusCode::FAILURE;
87 }
88
89
90 std::vector<const xAOD::Jet*> selectedJets;
91
93
94 std::vector<int>
entries = m_parser->evaluateAsVector();
97 return StatusCode::FAILURE;
98 }
99
100 for (
size_t i = 0;
i <
jets->size(); ++
i) {
102 selectedJets.push_back((*jets)[i]);
103 }
104 }
105 } else {
106
107 for (const auto* jet : *jets) {
108 selectedJets.push_back(jet);
109 }
110 }
111
112 ATH_MSG_DEBUG(
"Number of selected jets: " << selectedJets.size()
113 <<
" out of " <<
jets->size());
114
115
116 SG::ThinningHandle<xAOD::FlowElementContainer> jetChargedContainer(
m_jetChargedKey, ctx);
117 SG::ThinningHandle<xAOD::FlowElementContainer> jetNeutralContainer(
m_jetNeutralKey, ctx);
118 SG::ThinningHandle<xAOD::FlowElementContainer> globalChargedContainer(
m_globalChargedKey, ctx);
119 SG::ThinningHandle<xAOD::FlowElementContainer> globalNeutralContainer(
m_globalNeutralKey, ctx);
120
121
122 std::vector<bool> jetChargedMask(jetChargedContainer.isValid() ? jetChargedContainer->size() : 0, false);
123 std::vector<bool> jetNeutralMask(jetNeutralContainer.isValid() ? jetNeutralContainer->size() : 0, false);
124 std::vector<bool> globalChargedMask(globalChargedContainer.isValid() ? globalChargedContainer->size() : 0, false);
125 std::vector<bool> globalNeutralMask(globalNeutralContainer.isValid() ? globalNeutralContainer->size() : 0, false);
126
127
128 const int jetChargedMaskSize = static_cast<int>(jetChargedMask.size());
129 const int jetNeutralMaskSize = static_cast<int>(jetNeutralMask.size());
130 const int globalChargedMaskSize = static_cast<int>(globalChargedMask.size());
131 const int globalNeutralMaskSize = static_cast<int>(globalNeutralMask.size());
132
133
135
136
137 std::vector<const xAOD::IParticle*> otherObjects;
138
139
140 for (const auto* jet : selectedJets) {
141 if (!jet) continue;
142
143 ATH_MSG_VERBOSE(
"Processing jet with " << jet->numConstituents() <<
" constituents");
144
145 for (
size_t i = 0;
i < jet->numConstituents(); ++
i) {
146 const auto& link = jet->constituentLinks().at(i);
147 if (!link.isValid()) {
149 continue;
150 }
151
152 int index = link.index();
153 if (index < 0) {
155 continue;
156 }
157
158
160 if (!flowElement) {
161 ATH_MSG_VERBOSE(
" Constituent at index " << i <<
" is not a FlowElement, skipping");
162 continue;
163 }
164
165
167
168
170 if (index < jetChargedMaskSize) {
171 jetChargedMask[
index] =
true;
172 ATH_MSG_VERBOSE(
" Charged constituent at index " << index <<
": pt=" << flowElement->
pt()
173 <<
", eta=" << flowElement->
eta());
174 }
175 } else {
176 if (index < jetNeutralMaskSize) {
177 jetNeutralMask[
index] =
true;
178 ATH_MSG_VERBOSE(
" Neutral constituent at index " << index <<
": pt=" << flowElement->
pt()
179 <<
", eta=" << flowElement->
eta());
180 }
181 }
182
183
184 if (originalAcc.isAvailable(*flowElement)) {
185 const ElementLink<xAOD::IParticleContainer>& origLink = originalAcc(*flowElement);
187 int origIndex = origLink.
index();
188 if (origIndex >= 0) {
189 if (
isCharged && origIndex < globalChargedMaskSize) {
190 globalChargedMask[origIndex] = true;
192 }
else if (!
isCharged && origIndex < globalNeutralMaskSize) {
193 globalNeutralMask[origIndex] = true;
195 }
196 }
197 }
198 }
199
200
202 std::vector<const xAOD::IParticle*> others = flowElement->
otherObjects();
203 otherObjects.insert(otherObjects.end(), others.begin(), others.end());
204 }
205 }
206 }
207
208 size_t nChargedKept = std::count(jetChargedMask.begin(), jetChargedMask.end(), true);
209 size_t nNeutralKept = std::count(jetNeutralMask.begin(), jetNeutralMask.end(), true);
210 ATH_MSG_DEBUG(
"Keeping " << nChargedKept <<
" charged constituents and "
211 << nNeutralKept << " neutral constituents from selected jets");
212
214 ATH_MSG_DEBUG(
"Found " << otherObjects.size() <<
" otherObjects from constituents");
215 }
216
217
218 if (jetChargedContainer.isValid()) {
219 jetChargedContainer.keep(jetChargedMask);
221 << nChargedKept << " out of " << jetChargedContainer->size() << " objects");
222 } else {
224 }
225
226 if (jetNeutralContainer.isValid()) {
227 jetNeutralContainer.keep(jetNeutralMask);
228 size_t nNeutralGlobalKept = std::count(jetNeutralMask.begin(), jetNeutralMask.end(), true);
230 << nNeutralGlobalKept << " out of " << jetNeutralContainer->size() << " objects");
231 } else {
233 }
234
235 if (globalChargedContainer.isValid()) {
236 globalChargedContainer.keep(globalChargedMask);
237 size_t nGlobalChargedKept = std::count(globalChargedMask.begin(), globalChargedMask.end(), true);
239 << nGlobalChargedKept << " out of " << globalChargedContainer->size() << " objects");
240 } else {
242 }
243
244 if (globalNeutralContainer.isValid()) {
245 globalNeutralContainer.keep(globalNeutralMask);
246 size_t nGlobalNeutralKept = std::count(globalNeutralMask.begin(), globalNeutralMask.end(), true);
248 << nGlobalNeutralKept << " out of " << globalNeutralContainer->size() << " objects");
249 } else {
251 }
252
253
255 SG::ThinningHandle<xAOD::IParticleContainer> otherObjectsContainer(
m_otherObjectsKey, ctx);
256
257 if (!otherObjectsContainer.isValid()) {
259 } else {
260 size_t nObjects = otherObjectsContainer->size();
261 std::vector<bool>
mask(nObjects,
false);
263
264
265 for (const auto* other : otherObjects) {
266 if (!other) continue;
268 if (index >= 0 && index < maskSize) {
270 }
271 }
272
273 size_t nKept = std::count(
mask.begin(),
mask.end(),
true);
275 << nKept << " out of " << nObjects << " objects");
276
277 otherObjectsContainer.keep(mask);
278 }
279 }
280
281 return StatusCode::SUCCESS;
282}
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
bool isCharged(const T &p)
SG::ReadHandleKey< xAOD::JetContainer > m_jetSGKey
SG::ThinningHandleKey< xAOD::IParticleContainer > m_otherObjectsKey
SG::ThinningHandleKey< xAOD::FlowElementContainer > m_globalNeutralKey
SG::ThinningHandleKey< xAOD::FlowElementContainer > m_jetChargedKey
StringProperty m_selectionString
StringProperty m_otherObjectsName
SG::ThinningHandleKey< xAOD::FlowElementContainer > m_jetNeutralKey
SG::ThinningHandleKey< xAOD::FlowElementContainer > m_globalChargedKey
index_type index() const
Get the index of the element inside of its container.
bool isValid() const
Test to see if the link can be dereferenced.
SG::ConstAccessor< T, ALLOC > ConstAccessor
std::vector< const xAOD::IParticle * > otherObjects() const
virtual double pt() const override
virtual double eta() const override
The pseudorapidity ( ) of the particle.
FlowElement_v1 FlowElement
Definition of the current "pfo version".