79 {
80
81
83 if (!
jets.isValid()) {
85 return StatusCode::FAILURE;
86 }
87
88
89 std::vector<const xAOD::Jet*> selectedJets;
90
92
93 std::vector<int>
entries = m_parser->evaluateAsVector();
96 return StatusCode::FAILURE;
97 }
98
99 for (
size_t i = 0;
i <
jets->size(); ++
i) {
101 selectedJets.push_back((*jets)[i]);
102 }
103 }
104 } else {
105
106 for (const auto* jet : *jets) {
107 selectedJets.push_back(jet);
108 }
109 }
110
111 ATH_MSG_DEBUG(
"Number of selected jets: " << selectedJets.size()
112 <<
" out of " <<
jets->size());
113
114
115 SG::ThinningHandle<xAOD::FlowElementContainer> jetChargedContainer(
m_jetChargedKey, ctx);
116 SG::ThinningHandle<xAOD::FlowElementContainer> jetNeutralContainer(
m_jetNeutralKey, ctx);
117 SG::ThinningHandle<xAOD::FlowElementContainer> globalChargedContainer(
m_globalChargedKey, ctx);
118 SG::ThinningHandle<xAOD::FlowElementContainer> globalNeutralContainer(
m_globalNeutralKey, ctx);
119
120
121 std::vector<bool> jetChargedMask(jetChargedContainer.isValid() ? jetChargedContainer->size() : 0, false);
122 std::vector<bool> jetNeutralMask(jetNeutralContainer.isValid() ? jetNeutralContainer->size() : 0, false);
123 std::vector<bool> globalChargedMask(globalChargedContainer.isValid() ? globalChargedContainer->size() : 0, false);
124 std::vector<bool> globalNeutralMask(globalNeutralContainer.isValid() ? globalNeutralContainer->size() : 0, false);
125
126
127 const int jetChargedMaskSize = static_cast<int>(jetChargedMask.size());
128 const int jetNeutralMaskSize = static_cast<int>(jetNeutralMask.size());
129 const int globalChargedMaskSize = static_cast<int>(globalChargedMask.size());
130 const int globalNeutralMaskSize = static_cast<int>(globalNeutralMask.size());
131
132
133 static const SG::AuxElement::ConstAccessor<ElementLink<xAOD::IParticleContainer>> originalAcc("originalObjectLink");
134
135
136 std::vector<const xAOD::IParticle*> otherObjects;
137
138
139 for (const auto* jet : selectedJets) {
140 if (!jet) continue;
141
142 ATH_MSG_VERBOSE(
"Processing jet with " << jet->numConstituents() <<
" constituents");
143
144 for (
size_t i = 0;
i < jet->numConstituents(); ++
i) {
145 const auto&
link = jet->constituentLinks().at(i);
146 if (!
link.isValid()) {
148 continue;
149 }
150
152 if (index < 0) {
154 continue;
155 }
156
157
159 if (!flowElement) {
160 ATH_MSG_VERBOSE(
" Constituent at index " << i <<
" is not a FlowElement, skipping");
161 continue;
162 }
163
164
166
167
169 if (index < jetChargedMaskSize) {
170 jetChargedMask[
index] =
true;
171 ATH_MSG_VERBOSE(
" Charged constituent at index " << index <<
": pt=" << flowElement->
pt()
172 <<
", eta=" << flowElement->
eta());
173 }
174 } else {
175 if (index < jetNeutralMaskSize) {
176 jetNeutralMask[
index] =
true;
177 ATH_MSG_VERBOSE(
" Neutral constituent at index " << index <<
": pt=" << flowElement->
pt()
178 <<
", eta=" << flowElement->
eta());
179 }
180 }
181
182
183 if (originalAcc.isAvailable(*flowElement)) {
184 const ElementLink<xAOD::IParticleContainer>& origLink = originalAcc(*flowElement);
186 int origIndex = origLink.
index();
187 if (origIndex >= 0) {
188 if (
isCharged && origIndex < globalChargedMaskSize) {
189 globalChargedMask[origIndex] = true;
191 }
else if (!
isCharged && origIndex < globalNeutralMaskSize) {
192 globalNeutralMask[origIndex] = true;
194 }
195 }
196 }
197 }
198
199
201 std::vector<const xAOD::IParticle*> others = flowElement->
otherObjects();
202 otherObjects.insert(otherObjects.end(), others.begin(), others.end());
203 }
204 }
205 }
206
207 size_t nChargedKept = std::count(jetChargedMask.begin(), jetChargedMask.end(), true);
208 size_t nNeutralKept = std::count(jetNeutralMask.begin(), jetNeutralMask.end(), true);
209 ATH_MSG_DEBUG(
"Keeping " << nChargedKept <<
" charged constituents and "
210 << nNeutralKept << " neutral constituents from selected jets");
211
213 ATH_MSG_DEBUG(
"Found " << otherObjects.size() <<
" otherObjects from constituents");
214 }
215
216
217 if (jetChargedContainer.isValid()) {
218 jetChargedContainer.keep(jetChargedMask);
220 << nChargedKept << " out of " << jetChargedContainer->size() << " objects");
221 } else {
223 }
224
225 if (jetNeutralContainer.isValid()) {
226 jetNeutralContainer.keep(jetNeutralMask);
227 size_t nNeutralGlobalKept = std::count(jetNeutralMask.begin(), jetNeutralMask.end(), true);
229 << nNeutralGlobalKept << " out of " << jetNeutralContainer->size() << " objects");
230 } else {
232 }
233
234 if (globalChargedContainer.isValid()) {
235 globalChargedContainer.keep(globalChargedMask);
236 size_t nGlobalChargedKept = std::count(globalChargedMask.begin(), globalChargedMask.end(), true);
238 << nGlobalChargedKept << " out of " << globalChargedContainer->size() << " objects");
239 } else {
241 }
242
243 if (globalNeutralContainer.isValid()) {
244 globalNeutralContainer.keep(globalNeutralMask);
245 size_t nGlobalNeutralKept = std::count(globalNeutralMask.begin(), globalNeutralMask.end(), true);
247 << nGlobalNeutralKept << " out of " << globalNeutralContainer->size() << " objects");
248 } else {
250 }
251
252
254 SG::ThinningHandle<xAOD::IParticleContainer> otherObjectsContainer(
m_otherObjectsKey, ctx);
255
256 if (!otherObjectsContainer.isValid()) {
258 } else {
259 size_t nObjects = otherObjectsContainer->size();
260 std::vector<bool>
mask(nObjects,
false);
262
263
264 for (const auto* other : otherObjects) {
265 if (!other) continue;
267 if (index >= 0 && index < maskSize) {
269 }
270 }
271
272 size_t nKept = std::count(
mask.begin(),
mask.end(),
true);
274 << nKept << " out of " << nObjects << " objects");
275
276 otherObjectsContainer.keep(mask);
277 }
278 }
279
280 return StatusCode::SUCCESS;
281}
#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
Check if the element can be found.
std::vector< const xAOD::IParticle * > otherObjects() const
virtual double pt() const override
virtual double eta() const override
The pseudorapidity ( ) of the particle.
pointer & link(pointer p) const
Return a reference to the link for an element.
FlowElement_v1 FlowElement
Definition of the current "pfo version".