ATLAS Offline Software
Loading...
Searching...
No Matches
DerivationFramework::JetConstituentThinning Class Reference

#include <JetConstituentThinning.h>

Inheritance diagram for DerivationFramework::JetConstituentThinning:
Collaboration diagram for DerivationFramework::JetConstituentThinning:

Public Member Functions

 JetConstituentThinning (const std::string &t, const std::string &n, const IInterface *p)
virtual ~JetConstituentThinning ()
virtual StatusCode initialize () override
virtual StatusCode finalize () override
virtual StatusCode doThinning () const override

Private Attributes

StringProperty m_streamName
SG::ReadHandleKey< xAOD::JetContainerm_jetSGKey
StringProperty m_selectionString
StringProperty m_jetConstituentName
StringProperty m_globalConstituentName
StringProperty m_otherObjectsName
SG::ThinningHandleKey< xAOD::FlowElementContainerm_jetChargedKey
SG::ThinningHandleKey< xAOD::FlowElementContainerm_jetNeutralKey
SG::ThinningHandleKey< xAOD::FlowElementContainerm_globalChargedKey
SG::ThinningHandleKey< xAOD::FlowElementContainerm_globalNeutralKey
SG::ThinningHandleKey< xAOD::IParticleContainerm_otherObjectsKey

Detailed Description

Definition at line 28 of file JetConstituentThinning.h.

Constructor & Destructor Documentation

◆ JetConstituentThinning()

DerivationFramework::JetConstituentThinning::JetConstituentThinning ( const std::string & t,
const std::string & n,
const IInterface * p )

Definition at line 16 of file JetConstituentThinning.cxx.

18 : base_class(t, n, p) {}

◆ ~JetConstituentThinning()

DerivationFramework::JetConstituentThinning::~JetConstituentThinning ( )
virtualdefault

Member Function Documentation

◆ doThinning()

StatusCode DerivationFramework::JetConstituentThinning::doThinning ( ) const
overridevirtual

Definition at line 79 of file JetConstituentThinning.cxx.

79 {
80 const EventContext &ctx = Gaudi::Hive::currentContext();
81
82 // Retrieve jet collection
83 SG::ReadHandle<xAOD::JetContainer> jets(m_jetSGKey, ctx);
84 if (!jets.isValid()) {
85 ATH_MSG_ERROR("Failed to retrieve jet collection " << m_jetSGKey.key());
86 return StatusCode::FAILURE;
87 }
88
89 // Get the jets that pass the selection
90 std::vector<const xAOD::Jet*> selectedJets;
91
92 if (!m_selectionString.empty()) {
93 // Use the expression parser
94 std::vector<int> entries = m_parser->evaluateAsVector();
95 if (entries.size() != jets->size()) {
96 ATH_MSG_ERROR("Selection string evaluation size mismatch!");
97 return StatusCode::FAILURE;
98 }
99
100 for (size_t i = 0; i < jets->size(); ++i) {
101 if (entries[i] == 1) {
102 selectedJets.push_back((*jets)[i]);
103 }
104 }
105 } else {
106 // Keep all jets
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 // Get thinning handles for all containers
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 // Initialize masks for all containers
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 // Cache mask sizes as int for comparison (avoid repeated static_cast)
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 // Accessor for originalObjectLink
134 static const SG::AuxElement::ConstAccessor<ElementLink<xAOD::IParticleContainer>> originalAcc("originalObjectLink");
135
136 // Collect otherObjects indices if needed
137 std::vector<const xAOD::IParticle*> otherObjects;
138
139 // Loop over selected jets and mark constituents to keep
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()) {
148 ATH_MSG_VERBOSE(" Invalid constituent link at index " << i);
149 continue;
150 }
151
152 int index = link.index();
153 if (index < 0) {
154 ATH_MSG_VERBOSE(" Constituent link has negative index, skipping");
155 continue;
156 }
157
158 // Cast to FlowElement (all PFlow constituents are FlowElements)
159 const xAOD::FlowElement* flowElement = dynamic_cast<const xAOD::FlowElement*>(*link);
160 if (!flowElement) {
161 ATH_MSG_VERBOSE(" Constituent at index " << i << " is not a FlowElement, skipping");
162 continue;
163 }
164
165 // Check if it's charged or neutral
166 bool isCharged = flowElement->isCharged();
167
168 // Mark in the jet constituent container mask
169 if (isCharged) {
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 // Mark in the global container mask using originalObjectLink
184 if (originalAcc.isAvailable(*flowElement)) {
185 const ElementLink<xAOD::IParticleContainer>& origLink = originalAcc(*flowElement);
186 if (origLink.isValid()) {
187 int origIndex = origLink.index();
188 if (origIndex >= 0) {
189 if (isCharged && origIndex < globalChargedMaskSize) {
190 globalChargedMask[origIndex] = true;
191 ATH_MSG_VERBOSE(" Global charged constituent at index " << origIndex);
192 } else if (!isCharged && origIndex < globalNeutralMaskSize) {
193 globalNeutralMask[origIndex] = true;
194 ATH_MSG_VERBOSE(" Global neutral constituent at index " << origIndex);
195 }
196 }
197 }
198 }
199
200 // Collect otherObjects for thinning if requested
201 if (!m_otherObjectsName.empty()) {
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
213 if (!m_otherObjectsName.empty()) {
214 ATH_MSG_DEBUG("Found " << otherObjects.size() << " otherObjects from constituents");
215 }
216
217
218 if (jetChargedContainer.isValid()) {
219 jetChargedContainer.keep(jetChargedMask);
220 ATH_MSG_DEBUG("Container " << m_jetChargedKey.key() << ": keeping "
221 << nChargedKept << " out of " << jetChargedContainer->size() << " objects");
222 } else {
223 ATH_MSG_WARNING("Container " << m_jetChargedKey.key() << " not valid, skipping");
224 }
225
226 if (jetNeutralContainer.isValid()) {
227 jetNeutralContainer.keep(jetNeutralMask);
228 size_t nNeutralGlobalKept = std::count(jetNeutralMask.begin(), jetNeutralMask.end(), true);
229 ATH_MSG_DEBUG("Container " << m_jetNeutralKey.key() << ": keeping "
230 << nNeutralGlobalKept << " out of " << jetNeutralContainer->size() << " objects");
231 } else {
232 ATH_MSG_WARNING("Container " << m_jetNeutralKey.key() << " not valid, skipping");
233 }
234
235 if (globalChargedContainer.isValid()) {
236 globalChargedContainer.keep(globalChargedMask);
237 size_t nGlobalChargedKept = std::count(globalChargedMask.begin(), globalChargedMask.end(), true);
238 ATH_MSG_DEBUG("Container " << m_globalChargedKey.key() << ": keeping "
239 << nGlobalChargedKept << " out of " << globalChargedContainer->size() << " objects");
240 } else {
241 ATH_MSG_WARNING("Container " << m_globalChargedKey.key() << " not valid, skipping");
242 }
243
244 if (globalNeutralContainer.isValid()) {
245 globalNeutralContainer.keep(globalNeutralMask);
246 size_t nGlobalNeutralKept = std::count(globalNeutralMask.begin(), globalNeutralMask.end(), true);
247 ATH_MSG_DEBUG("Container " << m_globalNeutralKey.key() << ": keeping "
248 << nGlobalNeutralKept << " out of " << globalNeutralContainer->size() << " objects");
249 } else {
250 ATH_MSG_WARNING("Container " << m_globalNeutralKey.key() << " not valid, skipping");
251 }
252
253 // Thin otherObjects container if requested
254 if (!m_otherObjectsName.empty()) {
255 SG::ThinningHandle<xAOD::IParticleContainer> otherObjectsContainer(m_otherObjectsKey, ctx);
256
257 if (!otherObjectsContainer.isValid()) {
258 ATH_MSG_WARNING("OtherObjects container " << m_otherObjectsKey.key() << " not valid, skipping");
259 } else {
260 size_t nObjects = otherObjectsContainer->size();
261 std::vector<bool> mask(nObjects, false);
262 const int maskSize = static_cast<int>(mask.size());
263
264 // Mark objects using their indices
265 for (const auto* other : otherObjects) {
266 if (!other) continue;
267 int index = other->index();
268 if (index >= 0 && index < maskSize) {
269 mask[index] = true;
270 }
271 }
272
273 size_t nKept = std::count(mask.begin(), mask.end(), true);
274 ATH_MSG_DEBUG("OtherObjects container " << m_otherObjectsKey.key() << ": keeping "
275 << nKept << " out of " << nObjects << " objects");
276
277 otherObjectsContainer.keep(mask);
278 }
279 }
280
281 return StatusCode::SUCCESS;
282}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
bool isCharged(const T &p)
Definition AtlasPID.h:1004
SG::ReadHandleKey< xAOD::JetContainer > m_jetSGKey
SG::ThinningHandleKey< xAOD::IParticleContainer > m_otherObjectsKey
SG::ThinningHandleKey< xAOD::FlowElementContainer > m_globalNeutralKey
SG::ThinningHandleKey< xAOD::FlowElementContainer > m_jetChargedKey
SG::ThinningHandleKey< xAOD::FlowElementContainer > m_jetNeutralKey
SG::ThinningHandleKey< xAOD::FlowElementContainer > m_globalChargedKey
SG::ConstAccessor< T, ALLOC > ConstAccessor
Definition AuxElement.h:569
std::vector< const xAOD::IParticle * > otherObjects() const
virtual double pt() const override
virtual double eta() const override
The pseudorapidity ( ) of the particle.
double entries
Definition listroot.cxx:49
str index
Definition DeMoScan.py:362
const uint32_t maskSize
FlowElement_v1 FlowElement
Definition of the current "pfo version".
Definition FlowElement.h:16

◆ finalize()

StatusCode DerivationFramework::JetConstituentThinning::finalize ( )
overridevirtual

Definition at line 73 of file JetConstituentThinning.cxx.

73 {
74 ATH_MSG_VERBOSE("finalize() ...");
75 return StatusCode::SUCCESS;
76}

◆ initialize()

StatusCode DerivationFramework::JetConstituentThinning::initialize ( )
overridevirtual

Definition at line 22 of file JetConstituentThinning.cxx.

22 {
23 ATH_MSG_VERBOSE("initialize() ...");
24
25 // Check that we have a jet container
26 if (m_jetSGKey.empty()) {
27 ATH_MSG_FATAL("No jet collection provided!");
28 return StatusCode::FAILURE;
29 }
30
31 ATH_CHECK(m_jetSGKey.initialize());
32 ATH_MSG_INFO("Using " << m_jetSGKey.key() << " as the jet collection");
33
34 // Initialize the selection string parser if provided
35 if (!m_selectionString.empty()) {
36 ATH_CHECK(initializeParser(m_selectionString));
37 ATH_MSG_INFO("Jet selection string: " << m_selectionString);
38 }
39
40 // Build container names from prefixes
41 std::string jetChargedName = m_jetConstituentName + "ChargedParticleFlowObjects";
42 std::string jetNeutralName = m_jetConstituentName + "NeutralParticleFlowObjects";
43 std::string globalChargedName = m_globalConstituentName + "ChargedParticleFlowObjects";
44 std::string globalNeutralName = m_globalConstituentName + "NeutralParticleFlowObjects";
45
46 // Initialize thinning handle keys
47 m_jetChargedKey = SG::ThinningHandleKey<xAOD::FlowElementContainer>(jetChargedName);
48 m_jetNeutralKey = SG::ThinningHandleKey<xAOD::FlowElementContainer>(jetNeutralName);
49 m_globalChargedKey = SG::ThinningHandleKey<xAOD::FlowElementContainer>(globalChargedName);
50 m_globalNeutralKey = SG::ThinningHandleKey<xAOD::FlowElementContainer>(globalNeutralName);
51
56
57 ATH_MSG_INFO("Thinning containers:");
58 ATH_MSG_INFO(" Jet constituents: " << jetChargedName << ", " << jetNeutralName);
59 ATH_MSG_INFO(" Global constituents: " << globalChargedName << ", " << globalNeutralName);
60
61 // Initialize otherObjects thinning if requested
62 if (!m_otherObjectsName.empty()) {
63 m_otherObjectsKey = SG::ThinningHandleKey<xAOD::IParticleContainer>(m_otherObjectsName);
65 ATH_MSG_INFO(" OtherObjects: " << m_otherObjectsName);
66 } else {
67 ATH_MSG_INFO(" OtherObjects thinning: disabled");
68 }
69
70 return StatusCode::SUCCESS;
71}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)

Member Data Documentation

◆ m_globalChargedKey

SG::ThinningHandleKey<xAOD::FlowElementContainer> DerivationFramework::JetConstituentThinning::m_globalChargedKey
private

Definition at line 59 of file JetConstituentThinning.h.

◆ m_globalConstituentName

StringProperty DerivationFramework::JetConstituentThinning::m_globalConstituentName
private
Initial value:
{
this, "GlobalConstituentName", "Global", "Prefix for global constituent containers (e.g., Global for GlobalChargedParticleFlowObjects)"}

Definition at line 51 of file JetConstituentThinning.h.

51 {
52 this, "GlobalConstituentName", "Global", "Prefix for global constituent containers (e.g., Global for GlobalChargedParticleFlowObjects)"};

◆ m_globalNeutralKey

SG::ThinningHandleKey<xAOD::FlowElementContainer> DerivationFramework::JetConstituentThinning::m_globalNeutralKey
private

Definition at line 60 of file JetConstituentThinning.h.

◆ m_jetChargedKey

SG::ThinningHandleKey<xAOD::FlowElementContainer> DerivationFramework::JetConstituentThinning::m_jetChargedKey
private

Definition at line 57 of file JetConstituentThinning.h.

◆ m_jetConstituentName

StringProperty DerivationFramework::JetConstituentThinning::m_jetConstituentName
private
Initial value:
{
this, "JetConstituentName", "CHSG", "Prefix for jet constituent containers (e.g., CHSG for CHSGChargedParticleFlowObjects)"}

Definition at line 48 of file JetConstituentThinning.h.

48 {
49 this, "JetConstituentName", "CHSG", "Prefix for jet constituent containers (e.g., CHSG for CHSGChargedParticleFlowObjects)"};

◆ m_jetNeutralKey

SG::ThinningHandleKey<xAOD::FlowElementContainer> DerivationFramework::JetConstituentThinning::m_jetNeutralKey
private

Definition at line 58 of file JetConstituentThinning.h.

◆ m_jetSGKey

SG::ReadHandleKey<xAOD::JetContainer> DerivationFramework::JetConstituentThinning::m_jetSGKey
private
Initial value:
{
this, "JetKey", "", "SG key for jet container"}

Definition at line 42 of file JetConstituentThinning.h.

42 {
43 this, "JetKey", "", "SG key for jet container"};

◆ m_otherObjectsKey

SG::ThinningHandleKey<xAOD::IParticleContainer> DerivationFramework::JetConstituentThinning::m_otherObjectsKey
private

Definition at line 61 of file JetConstituentThinning.h.

◆ m_otherObjectsName

StringProperty DerivationFramework::JetConstituentThinning::m_otherObjectsName
private
Initial value:
{
this, "OtherObjectsName", "", "Optional container name for otherObjects (e.g., CaloCalTopoClusters). If empty, otherObjects thinning is disabled."}

Definition at line 54 of file JetConstituentThinning.h.

54 {
55 this, "OtherObjectsName", "", "Optional container name for otherObjects (e.g., CaloCalTopoClusters). If empty, otherObjects thinning is disabled."};

◆ m_selectionString

StringProperty DerivationFramework::JetConstituentThinning::m_selectionString
private
Initial value:
{
this, "SelectionString", "", "Selection string for jets"}

Definition at line 45 of file JetConstituentThinning.h.

45 {
46 this, "SelectionString", "", "Selection string for jets"};

◆ m_streamName

StringProperty DerivationFramework::JetConstituentThinning::m_streamName
private
Initial value:
{this, "StreamName", "",
"Name of the stream being thinned"}

Definition at line 39 of file JetConstituentThinning.h.

39 {this, "StreamName", "",
40 "Name of the stream being thinned"};

The documentation for this class was generated from the following files: