ATLAS Offline Software
Loading...
Searching...
No Matches
EgammaTrackParticleThinning.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
6// EgammaTrackParticleThinning.cxx, (c) ATLAS Detector software
8// Author: James Catmore (James.Catmore@cern.ch)
9
15
16namespace {
18 "originalTrackParticle");
19}
20
21// Constructor
23 const std::string& t,
24 const std::string& n,
25 const IInterface* p)
26 : base_class(t, n, p)
27{}
28
29// Destructor
31= default;
32
33// Athena initialize and finalize
34StatusCode
36{
37 // Decide which collections need to be checked for ID TrackParticles
38 ATH_CHECK(m_egammaKey.initialize());
39
41 ATH_MSG_INFO("Using " << m_gsfSGKey.key()
42 << " as the source collection for GSF track particles");
43 ATH_MSG_INFO((m_bestMatchOnly ? "Best match " : "ALL ")
44 << "GSF track particles associated with objects in "
45 << m_egammaKey.key() << '\n'
46 << " will be marked as kept true in the ThinningHandle "
47 << "otherwise as kept false");
48
49 ATH_CHECK(m_inDetSGKey.initialize(m_streamName, !m_inDetSGKey.empty()));
50 if (!m_inDetSGKey.empty()) {
52 "Using "
53 << m_inDetSGKey.key()
54 << " as the source collection for inner detector track particles");
55
56 ATH_MSG_INFO("Inner detector track particles refitted to produce"
57 << m_gsfSGKey.key() << '\n'
58 << " will be retained when the corresponding "
59 << m_gsfSGKey.key() << " track particle will be retained");
60 if (m_coneSize > 0) {
62 "Inner detector track particles in a cone dr "
63 << m_coneSize << " around the " << m_egammaKey.key() << '\n'
64 << " obects will be marked as kept true in the ThinningHandle "
65 << "otherwise as kept false");
66 }
67 }
68
70 if (!m_gsfVtxSGKey.empty()) {
71 ATH_MSG_INFO("Using " << m_gsfVtxSGKey.key()
72 << " as the source collection for GSF conversion vertices");
73 ATH_MSG_INFO((m_bestVtxMatchOnly ? "Best match " : "ALL ")
74 << " GSF conversion vertices will be kept");
75 }
76
77 // Set up the text-parsing machinery for selectiong the objects directly
78 // according to user cuts
79 if (!m_selectionString.empty()) {
80 ATH_CHECK(initializeParser(m_selectionString));
81 }
82
83 return StatusCode::SUCCESS;
84}
85
86StatusCode
88{
89 ATH_MSG_INFO("Selected " << m_nSelEgammas <<" out of " << m_nEgammas
90 << " objects from " << m_egammaKey.key());
91 ATH_MSG_INFO("Kept " << m_nGSFPass << " out of " << m_ntotGSF
92 << " objects from " << m_gsfSGKey.key());
93 if (!m_gsfVtxSGKey.empty()) {
94 ATH_MSG_INFO("Kept " << m_nGSFVtxPass << " out of " << m_ntotGSFVtx
95 << " vertices from " << m_gsfVtxSGKey.key());
96 }
97 if (!m_inDetSGKey.empty()) {
98 ATH_MSG_INFO("Kept " << m_npass << "out of " << m_ntot << " objects from "
99 << m_inDetSGKey.key());
100 }
101
102 ATH_CHECK(finalizeParser());
103 return StatusCode::SUCCESS;
104}
105
106// The thinning itself
107StatusCode
109{
110 const EventContext& ctx = Gaudi::Hive::currentContext();
111 SG::ThinningHandle<xAOD::TrackParticleContainer> importedGSFTrackParticles(
112 m_gsfSGKey, ctx);
113
114 // Allow for not input Indet Track Particle collection
115 std::unique_ptr<SG::ThinningHandle<xAOD::TrackParticleContainer>>
116 importedTrackParticles = nullptr;
117 if (!m_inDetSGKey.empty()) {
118 importedTrackParticles =
119 std::make_unique<SG::ThinningHandle<xAOD::TrackParticleContainer>>(
120 m_inDetSGKey, ctx);
121 }
122
123 // Check the event contains tracks
124 const xAOD::TrackParticleContainer* tps = (importedTrackParticles != nullptr)
125 ? importedTrackParticles->cptr()
126 : nullptr;
127 const xAOD::TrackParticleContainer* gsfs = importedGSFTrackParticles.cptr();
128 unsigned int nTracks = tps ? tps->size() : 0;
129 unsigned int nGSF = gsfs->size();
130
131 ATH_MSG_DEBUG("nTracks : " << nTracks << " , nGSF : " << nGSF);
132 if (nTracks == 0 && nGSF == 0) {
133 ATH_MSG_DEBUG("Nothing to thin");
134 return StatusCode::SUCCESS;
135 }
136
137 // Set up a mask with the same entries as the full TrackParticle collection(s)
138 std::vector<bool> mask, gsfMask;
139 mask.assign(nTracks, false); // default: don't keep any tracks
140 gsfMask.assign(nGSF, false);
141 m_ntot += nTracks;
142 m_ntotGSF += nGSF;
143
144 // Retrieve e-gamma container
146 if (!importedEgamma.isValid()) {
147 ATH_MSG_ERROR("No e-gamma collection with name " << m_egammaKey.key()
148 << " found in StoreGate!");
149 return StatusCode::FAILURE;
150 }
151
152 size_t nEgammas(importedEgamma->size());
153 ATH_MSG_DEBUG("nEgammas : " << nEgammas);
154 m_nEgammas += nEgammas;
155 bool doSelect = !m_selectionString.empty();
156 if (nEgammas != 0) {
158 // Execute the text parsers if requested
159 if (doSelect) {
160 std::vector<int> entries = m_parser->evaluateAsVector();
161 unsigned int nEntries = entries.size();
162 // check the sizes are compatible
163 if (nEgammas != nEntries) {
164 ATH_MSG_ERROR("Sizes incompatible! Are you sure your selection string "
165 "used e-gamma objects??");
166 return StatusCode::FAILURE;
167 } else {
168 // identify which e-gammas to keep for the thinning check
169 for (unsigned int i = 0; i < nEgammas; ++i)
170 if (entries[i] == 1)
171 tofill.push_back(importedEgamma->at(i));
172 }
173 } // end of selection
174 const xAOD::EgammaContainer* egToCheck = doSelect
175 ? tofill.asDataVector() : importedEgamma.cptr();
176 ATH_MSG_DEBUG("Setting the masks");
177 m_nSelEgammas += egToCheck->size();
178 // Are we dealing with electrons or photons?
179 if (dynamic_cast<const xAOD::ElectronContainer*>(importedEgamma.cptr()) != nullptr)
180 setElectronMasks(mask, gsfMask, egToCheck, tps, gsfs);
181 else if (dynamic_cast<const xAOD::PhotonContainer*>(importedEgamma.cptr()) != nullptr)
182 setPhotonMasks(mask, gsfMask, egToCheck, tps, gsfs);
183 else
184 ATH_MSG_WARNING("Input container is neither for Electrons, "
185 "nor for Photons ??");
186 }//end of if nEgammas != 0
187 else if (!m_gsfVtxSGKey.empty()) {
188 clearGSFVtx(ctx);
189 }
190
191 // Count up the mask contents
192 unsigned int n_pass = 0;
193 for (unsigned int i = 0; i < nTracks; ++i) {
194 if (mask[i]) {
195 ++n_pass;
196 }
197 }
198 m_npass += n_pass;
199 unsigned int n_gsf_pass = 0;
200 for (unsigned int i = 0; i < nGSF; ++i) {
201 if (gsfMask[i]) {
202 ++n_gsf_pass;
203 }
204 }
205 m_nGSFPass += n_gsf_pass;
206
207 // Execute the thinning service based on the mask. Finish.
208 importedGSFTrackParticles.keep(gsfMask);
209 if (tps) {
210 importedTrackParticles->keep(mask);
211 }
212
213 return StatusCode::SUCCESS;
214}
215
217 const EventContext& ctx) const
218{
219 SG::ThinningHandle<xAOD::VertexContainer> importedGSFConversionVtx(
220 m_gsfVtxSGKey, ctx);
221 const xAOD::VertexContainer* gsfVtxs = importedGSFConversionVtx.cptr();
222 unsigned int nGSFVtx = gsfVtxs->size();
223 if (nGSFVtx == 0) {
224 ATH_MSG_DEBUG("No conversion vertex to thin");
225 return;
226 }
227 std::vector<bool> gsfVtxMask(nGSFVtx,false);
228 m_ntotGSFVtx += nGSFVtx;
229 ATH_MSG_DEBUG("nGSFVtx : " << nGSFVtx);
230 importedGSFConversionVtx.keep(gsfVtxMask);
231}
232
233void
235 std::vector<bool>& mask,
236 std::vector<bool>& gsfMask,
237 const xAOD::EgammaContainer* egammas,
239 const xAOD::TrackParticleContainer* gsfs) const
240{
241 if (m_gsfVtxSGKey.empty()) {
242 ATH_MSG_ERROR("Thinning track particles/vertices associated to photons"
243 "but no conversion vertex key provided");
244 return;
245 }
246
247 SG::ThinningHandle<xAOD::VertexContainer> importedGSFConversionVtx(
248 m_gsfVtxSGKey, Gaudi::Hive::currentContext());
249 const xAOD::VertexContainer* gsfVtxs = importedGSFConversionVtx.cptr();
250 unsigned int nGSFVtx = gsfVtxs->size(), n_gsfVtx_pass = 0;
251 std::vector<bool> gsfVtxMask(nGSFVtx,false);
252 m_ntotGSFVtx += nGSFVtx;
253 ATH_MSG_DEBUG("nGSFVtx : " << nGSFVtx);
254
256 for (const auto* egamma : *egammas) {
257 const xAOD::Photon* photon = egamma->type() == xAOD::Type::Photon
258 ? static_cast<const xAOD::Photon*>(egamma)
259 : nullptr;
260 if (!photon) {
261 ATH_MSG_ERROR("Did not get a photon object in "
262 "EgammaTrackParticleThinning::setPhotonMasks");
263 return;
264 }
265 if (tps && m_coneSize > 0.0) {
266 trIC.select(photon, m_coneSize, tps, mask);
267 } // check InDet tracks in a cone around the e-gammas
268
269 std::vector<ElementLink<xAOD::VertexContainer>> vertexLinks =
270 photon->vertexLinks();
271 unsigned int nLinks = vertexLinks.size();
272 if (nLinks == 0) {
273 continue;
274 }
275 if (!m_bestVtxMatchOnly) {
276 for (unsigned int i = 0; i < nLinks; ++i) {
277 if (!(vertexLinks[i])) {
278 continue;
279 }
280 if (!(vertexLinks[i]).isValid()) {
281 continue;
282 }
283 gsfVtxMask[vertexLinks[i].index()] = true;
284 }
285 }
286 if (m_bestMatchOnly) {
287 nLinks = 1;
288 }
289 for (unsigned int i = 0; i < nLinks; ++i) {
290 if (!(vertexLinks[i]).isValid()) {
291 continue;
292 }
293 gsfVtxMask[vertexLinks[i].index()] = true;
294 const xAOD::Vertex* vx = *(vertexLinks[i]);
295 if (!vx) {
296 continue;
297 }
298 auto trackParticleLinks = vx->trackParticleLinks();
299 for (const auto& link : trackParticleLinks) {
300 if (!link.isValid()) {
301 continue;
302 }
303 gsfMask[link.index()] = true;
304 if (tps) {
305 const ElementLink<xAOD::TrackParticleContainer>& origTrackLink =
306 orig(*((*gsfs)[link.index()]));
307 if (origTrackLink.isValid()) {
308 int inDetIndex = origTrackLink.index();
309 mask[inDetIndex] = true;
310 }
311 }
312 }
313 }
314 }
315 importedGSFConversionVtx.keep(gsfVtxMask);
316 for (bool b : gsfVtxMask) {
317 if (b)
318 ++n_gsfVtx_pass;
319 }
320 m_nGSFVtxPass += n_gsfVtx_pass;
321}
322
323void
325 std::vector<bool>& mask,
326 std::vector<bool>& gsfMask,
327 const xAOD::EgammaContainer* egammas,
329 const xAOD::TrackParticleContainer* gsfs) const
330{
332 for (const auto *egamma : *egammas) {
333 const xAOD::Electron* electron =
335 ? static_cast<const xAOD::Electron*>(egamma)
336 : nullptr;
337
338 if (!electron) {
339 ATH_MSG_ERROR("Did not get an electron object in "
340 "EgammaTrackParticleThinning::setElectronMasks");
341 return;
342 }
343 if (tps && m_coneSize > 0.0)
344 trIC.select(electron,
346 tps,
347 mask); // check InDet tracks in a cone around the e-gammas
348
349 unsigned int nGSFLinks = m_bestMatchOnly ? 1 : electron->nTrackParticles();
350 for (unsigned int i = 0; i < nGSFLinks; ++i) {
351 if (!(electron->trackParticleLink(i).isValid())) {
352 continue;
353 }
354 int gsfIndex = electron->trackParticleLink(i).index();
355 gsfMask[gsfIndex] = true;
356 if (tps) {
357 const ElementLink<xAOD::TrackParticleContainer>& origTrackLink =
358 orig(*((*gsfs)[gsfIndex]));
359 if (origTrackLink.isValid()) {
360 int inDetIndex = origTrackLink.index();
361 mask[inDetIndex] = true;
362 }
363 }
364 }
365 }
366}
367
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
bool isValid(const T &p)
Av: we implement here an ATLAS-sepcific convention: all particles which are 99xxxxx are fine.
Definition AtlasPID.h:878
DataVector adapter that acts like it holds const pointers.
Handle for requesting thinning for a data object.
DataVector adapter that acts like it holds const pointers.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
const DV * asDataVector() const
Return a pointer to this object, as a const DataVector.
size_type size() const noexcept
Returns the number of elements in the collection.
SG::ThinningHandleKey< xAOD::TrackParticleContainer > m_inDetSGKey
SG::ThinningHandleKey< xAOD::TrackParticleContainer > m_gsfSGKey
EgammaTrackParticleThinning(const std::string &t, const std::string &n, const IInterface *p)
SG::ThinningHandleKey< xAOD::VertexContainer > m_gsfVtxSGKey
void setPhotonMasks(std::vector< bool > &, std::vector< bool > &, const xAOD::EgammaContainer *, const xAOD::TrackParticleContainer *, const xAOD::TrackParticleContainer *) const
void setElectronMasks(std::vector< bool > &, std::vector< bool > &, const xAOD::EgammaContainer *, const xAOD::TrackParticleContainer *, const xAOD::TrackParticleContainer *) const
SG::ReadHandleKey< xAOD::EgammaContainer > m_egammaKey
SG::Accessor< T, ALLOC > Accessor
Definition AuxElement.h:572
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
void keep(size_t ndx)
Mark that index ndx in the container should be kept (not thinned away).
Handle for requesting thinning for a data object.
elec/gamma data class.
Definition egamma.h:58
const TrackParticleLinks_t & trackParticleLinks() const
Get all the particles associated with the vertex.
double entries
Definition listroot.cxx:49
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
@ Photon
The object is a photon.
Definition ObjectType.h:47
@ Electron
The object is an electron.
Definition ObjectType.h:46
PhotonContainer_v1 PhotonContainer
Definition of the current "photon container version".
ElectronContainer_v1 ElectronContainer
Definition of the current "electron container version".
VertexContainer_v1 VertexContainer
Definition of the current "Vertex container version".
Vertex_v1 Vertex
Define the latest version of the vertex class.
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
Photon_v1 Photon
Definition of the current "egamma version".
EgammaContainer_v1 EgammaContainer
Definition of the current "egamma container version".
Electron_v1 Electron
Definition of the current "egamma version".
void select(const xAOD::IParticle *particle, float coneSize, const xAOD::TrackParticleContainer *tracks, std::vector< bool > &mask)