ATLAS Offline Software
Loading...
Searching...
No Matches
TrackParticleCnvAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5
6// Gaudi/Athena include(s):
8
9// EDM include(s):
10
13
17
18// Local include(s):
19#include "TrackParticleCnvAlg.h"
20
21namespace xAODMaker {
23 ISvcLocator* svcLoc)
24 : AthReentrantAlgorithm(name, svcLoc) {}
25
26StatusCode
28{
29
30 ATH_MSG_DEBUG("Initializing TrackParticleCnvAlg");
31 ATH_MSG_DEBUG("AODContainerName = " << m_aod.key());
32 ATH_MSG_DEBUG("xAODContainerName = " << m_xaodTrackParticlesout.key());
33 ATH_CHECK(m_particleCreator.retrieve());
35 ATH_CHECK(m_truthClassifier.retrieve());
36 else
37 m_truthClassifier.disable();
38 ATH_CHECK(m_TrackCollectionCnvTool.retrieve(DisableTool{ !m_convertTracks }));
40 DisableTool{ !m_convertAODTrackParticles }));
41 // to preserve the inisialised parameters of the ParticleCreatorTool:
42 ATH_MSG_DEBUG("Overriding particle creator tool settings.");
45 m_TrackCollectionCnvTool->setParticleCreatorTool(&m_particleCreator));
47 ATH_CHECK(m_RecTrackParticleContainerCnvTool->setParticleCreatorTool(
49
59
60 // Retrieve monitoring tools if provided
61 ATH_CHECK(m_trackMonitoringTool.retrieve(DisableTool{ !m_doMonitoring }));
62 ATH_CHECK(m_monTool.retrieve(DisableTool{ !m_doMonitoring }));
63
65
66 // Return gracefully:
67 return StatusCode::SUCCESS;
68}
69
70StatusCode
71TrackParticleCnvAlg::execute(const EventContext& ctx) const
72{
73
74 const Rec::TrackParticleContainer* aod{};
75 const TrackCollection* tracks{};
76 const xAODTruthParticleLinkVector* truthLinks{};
77 const TrackParticleTruthCollection* aodTruth{};
78 const TrackTruthCollection* trackTruth{};
79 const ObservedTrackMap* tracksMap{};
80 const xAOD::Vertex* primaryVertex{};
81
82 //timer object for total execution time
83 auto mnt_timer_Total = Monitored::Timer<std::chrono::milliseconds>("TIME_Total");
84
85 // Retrieve the AOD particles:
88 if (!rh_aod.isValid()) {
89 ATH_MSG_ERROR(m_aod.key() << " not found");
90 return StatusCode::FAILURE;
91 } else {
92 aod = rh_aod.cptr();
93 ATH_MSG_VERBOSE("Got TrackParticleContainer with key " << m_aod.key()
94 << " found.");
95 }
96 }
97 // Retrieve the Tracks:
98 if (m_convertTracks) {
100 if (!rh_tracks.isValid()) {
101 ATH_MSG_ERROR(m_tracks.key() << " not found");
102 return StatusCode::SUCCESS;
103 } else {
104 tracks = rh_tracks.cptr();
105 ATH_MSG_VERBOSE("Got TrackCollection with key " << m_tracks.key()
106 << " found.");
107
108 }
109 }
110 if (m_addTruthLink) {
113 if (!rh_aodTruth.isValid()) {
114 ATH_MSG_WARNING("No TrackParticleTruthCollection with key "
115 << m_aodTruth.key() << " found. Do nothing.");
116 return StatusCode::SUCCESS;
117 } else
118 aodTruth = rh_aodTruth.cptr();
119 }
120 if (m_convertTracks) {
122 if (!rh_trackTruth.isValid()) {
123 ATH_MSG_WARNING("No DetailedTrackTruthCollection with key "
124 << m_trackTruth.key() << " found. Do nothing.");
125 return StatusCode::SUCCESS;
126 } else
127 trackTruth = rh_trackTruth.cptr();
128 }
129
130 SG::ReadHandle<xAODTruthParticleLinkVector> rh_truthParticleLinkVec(
132 if (!rh_truthParticleLinkVec.isValid()) {
133 ATH_MSG_WARNING("No xAODTruthParticleLinkVector with key "
134 << m_truthParticleLinkVec.key() << " found. Do nothing.");
135 return StatusCode::SUCCESS;
136 } else
137 truthLinks = rh_truthParticleLinkVec.cptr();
138 }
139
140 if(!m_primaryVertexContainer.key().empty())
141 {
143 if (!vtx_container.isValid()) {
144 ATH_MSG_WARNING("No xAOD::VertexContainer with key "<< m_primaryVertexContainer.key() << " found. Do nothing.");
145 return StatusCode::SUCCESS;
146 }
147 const xAOD::Vertex* dummyVertex{};
148 for(auto vtx : *vtx_container) {
149 if(vtx->vertexType()==xAOD::VxType::PriVtx) {
150 primaryVertex = vtx;
151 break;
152 }
153 if(vtx->vertexType()==xAOD::VxType::NoVtx) {
154 // in case of no primary vertex
155 dummyVertex = vtx;
156 }
157 }
158 if(!primaryVertex)
159 {
160 if(dummyVertex)
161 {
162 ATH_MSG_INFO("No primary vertex found, will use dummy vertex at "
163 << dummyVertex->x() << "," << dummyVertex->y() << ","
164 << dummyVertex->z());
165 primaryVertex = dummyVertex;
166 }
167 else
168 {
169 ATH_MSG_WARNING("Neither primary nor dummy vertex found. Do Nothing.");
170 return StatusCode::SUCCESS;
171 }
172 }
173 }
174
175 if (m_convertTracks) {
177 ATH_CHECK(
178 wh_xaodout.record(std::make_unique<xAOD::TrackParticleContainer>(),
179 std::make_unique<xAOD::TrackParticleAuxContainer>()));
180
181 // Augment track particles with information from observer tool
184 if (!rh_tracksMap.isValid()) {
185 ATH_MSG_ERROR(m_tracksMap.key() << " not found");
186 return StatusCode::FAILURE;
187 }
188 else {
189 tracksMap = rh_tracksMap.cptr();
190 ATH_MSG_VERBOSE("Got ObservedTrackMap with key " << m_tracksMap.key()
191 << " found.");
192 }
193 convert(ctx, (*tracks), trackTruth, m_TrackCollectionCnvTool, wh_xaodout,
194 truthLinks, primaryVertex, tracksMap);
195 } else {
196 convert(ctx, (*tracks), trackTruth, m_TrackCollectionCnvTool, wh_xaodout,
197 truthLinks, primaryVertex);
198 }
199 // Monitor track parameters
200 if (m_doMonitoring)
201 m_trackMonitoringTool->monitor_tracks("Track", "Pass", *wh_xaodout);
202 }
204 SG::WriteHandle<xAOD::TrackParticleContainer> wh_xaodTrackParticlesout(
206 ATH_CHECK(wh_xaodTrackParticlesout.record(
207 std::make_unique<xAOD::TrackParticleContainer>(),
208 std::make_unique<xAOD::TrackParticleAuxContainer>()));
209 convert(ctx, (*aod), aodTruth, m_RecTrackParticleContainerCnvTool,
210 wh_xaodTrackParticlesout, truthLinks);
211 }
212
213 //extra scope needed to trigger the monitoring
214 {auto monTime = Monitored::Group(m_monTool, mnt_timer_Total);}
215
216 return StatusCode::SUCCESS;
217}
218
219template<typename CONT>
221
222template<>
224{
225public:
228 unsigned int) const
229 {
230 return track_particle->track();
231 }
232};
233
234template<>
235class AssociationHelper<Rec::TrackParticleContainer>
236{
237public:
240 : m_contSrc(&cont_src)
241 {
242 if (cont_src.size() != cont_dest->size()) {
243 std::stringstream message;
244 message << __FILE__ << ":" << __LINE__
245 << " Expected one-to-one conversion from AOD to xAOD "
246 "TrackParticles but sizes differ: "
247 << cont_src.size() << " != " << cont_dest->size();
248 throw std::runtime_error(message.str());
249 }
250 }
251
253 unsigned int idx) const
254 {
255 return m_contSrc->at(idx);
256 }
257
258private:
260};
261
262template<typename CONT, typename TRUTHCONT, typename CONVTOOL>
263int
265 const EventContext& ctx,
266 const CONT& container,
267 const TRUTHCONT& truth,
268 CONVTOOL& conv_tool,
270 const xAODTruthParticleLinkVector* truthLinkVec,
271 const xAOD::Vertex* primaryVertex,
272 const ObservedTrackMap* obs_track_map /*=0*/) const
273{
274 // Create the xAOD container and its auxiliary store:
275
276 // convert the track containers separately with the converting tools that are
277 // also used by TrigHLTtoxAODTool
278 ATH_MSG_DEBUG("calling the converting tool for " << xaod.name());
279 // Augment track particles using track map if available
280 if (obs_track_map){
281 if (conv_tool->convertAndAugment(ctx, &container, xaod.ptr(), obs_track_map, primaryVertex).isFailure()) {
282 ATH_MSG_ERROR("Couldn't convert and augment aod to xaod ("
283 << xaod.name() << ") with the converting tool");
284 return -1;
285 }
286 }
287 else{
288 if (conv_tool->convert(ctx, &container, xaod.ptr(), primaryVertex).isFailure()) {
289 ATH_MSG_ERROR("Couldn't convert aod to xaod ("
290 << xaod.name() << ") with the converting tool");
291 return -1;
292 }
293 }
294 // Create the xAOD objects:
295 xAOD::TrackParticleContainer::iterator itr_xaod = xaod->begin();
296 xAOD::TrackParticleContainer::iterator end_xaod = xaod->end();
297
298 AssociationHelper<CONT> association_to_src(container, xaod.ptr());
299 unsigned int trackCounter(0);
300 // loop over AOD and converted xAOD for summary info and truth links
301 for (; itr_xaod != end_xaod; ++itr_xaod) {
302 // protect if something went wrong and there is no converted xaod equivalent
303
304 if (!(*itr_xaod)) {
305 ATH_MSG_WARNING("Empty element in xAOD container!");
306 continue;
307 }
308
309 xAOD::TrackParticle* particle = *itr_xaod;
310
311 if (!particle) {
312 ATH_MSG_WARNING("Failed to get an xAOD::TrackParticle");
313 continue;
314 }
315
316 trackCounter++;
317 if(msgLvl(MSG::DEBUG)){
318 int npix, nsct, ntrt, npixh, nscth, npixshim, npixsplit;
319 npix = nsct = ntrt = npixh = nscth = npixshim = npixsplit = -1;
320 const Trk::Track *tr = particle->track();
321 if (tr){
322 const Trk::TrackSummary* ts = tr->trackSummary();
323 if (ts) {
324 npix = ts->get(Trk::numberOfPixelHits);
325 nsct = ts->get(Trk::numberOfSCTHits);
326 ntrt = ts->get(Trk::numberOfTRTHits);
327 nscth = ts->get(Trk::numberOfSCTHoles);
328 npixh = ts->get(Trk::numberOfPixelHoles);
329 }
330 }
331 msg() << MSG::DEBUG << "REGTEST: " << std::setw(5) << trackCounter
332 << " pT: " << std::setw(10) << particle->pt()
333 << " eta: " << particle->eta()
334 << " phi: " << particle->phi()
335 << " d0: " << particle->d0()
336 << " z0: " << particle->z0()
337 << "\t" << npix << "/" << nsct << "/" << ntrt << "/holes/" << npixh << "/" << nscth
338 << endmsg;
339 }
340 //
341 // --------- statistics
342 //
343 if (m_addTruthLink) {
347 unsigned int classification = 0; // Better default value here?
348 float probability = -1.0;
350
351 ElementLink<CONT> tpLink(
352 association_to_src(*itr_xaod, itr_xaod - xaod->begin()), container);
353 if (!tpLink.isValid()) {
354 ATH_MSG_WARNING("Failed to create ElementLink to Track/TrackParticle");
355 } else if(truth->empty()){
356 // This can happen if there is no HS track
357 ATH_MSG_DEBUG("No truth available");
358 } else {
359 auto result = truth->find(tpLink);
360 if (result == truth->end()) {
362 "Failed find truth associated with Track/TrackParticle");
363 } else {
364 // setTruthLink(link,result->second, type, origin);
365 ATH_MSG_VERBOSE("Found track Truth: uniqueID "
366 << HepMC::uniqueID(result->second.particleLink()) << " evt "
367 << result->second.particleLink().eventIndex());
368 probability = result->second.probability();
369 link = truthLinkVec->find(result->second.particleLink());
370 if (link.isValid()) {
371 ATH_MSG_DEBUG("Found matching xAOD Truth: uniqueID "
372 << HepMC::uniqueID(*link) << " pt " << (*link)->pt()
373 << " eta " << (*link)->eta() << " phi "
374 << (*link)->phi());
375 // if configured also get truth classification
376 if (result->second.particleLink().cptr() &&
377 !m_truthClassifier.empty()) {
378 auto truthClass = m_truthClassifier->particleHepMCTruthClassifier(
379 result->second.particleLink());
380 type = truthClass.first;
381 origin = truthClass.second;
382 classification = std::get<0>(MCTruthPartClassifier::defOrigOfParticle(result->second.particleLink().cptr())); // See AGENE-2351
383 ATH_MSG_VERBOSE("Got truth type " << static_cast<int>(type)
384 << " origin "
385 << static_cast<int>(origin)
386 << " classification "
387 << static_cast<unsigned int>(classification));
388 }
389 } else {
390 if (HepMC::uniqueID(result->second.particleLink()) > 0) {
391 ATH_MSG_WARNING("No associated xAOD truth for valid truth link "
392 << result->second.particleLink());
393 }
394 }
395 }
396 }
397 //This is the Algorithm creating TrackParticles
398 //
399 static const SG::AuxElement::Accessor<
401 theLink("truthParticleLink");
402 static const SG::AuxElement::Accessor<float> theProbability(
403 "truthMatchProbability");
404 theLink(*particle) = link;
405 theProbability(*particle) = probability;
406 if (!m_truthClassifier.empty()) {
407 static const SG::AuxElement::Accessor<int> theType("truthType");
408 static const SG::AuxElement::Accessor<int> theOrigin("truthOrigin");
409 static const SG::AuxElement::Accessor<unsigned int> theClassification("truthClassification");
410 theType(*particle) = static_cast<int>(type);
411 theOrigin(*particle) = static_cast<int>(origin);
412 theClassification(*particle) = static_cast<unsigned int>(classification);
413 }
414 }
415 } // loop over aod tracks
416
417 ATH_MSG_DEBUG("Converted [" << container.size() << " -> " << xaod->size()
418 << "] TrackParticles and stored in "
419 << xaod.name());
420 if (container.size() != xaod->size()) {
421 ATH_MSG_WARNING("number of items in the AOD container: "
422 << container.size()
423 << " is not equal to the number of items in its converted "
424 "xAOD equivalent: "
425 << xaod->size());
426 }
427
428 return 1;
429}
430
435 const Rec::TrackParticle& tp,
436 const EventContext& ctx)
437{
438 // create the xAOD::TrackParticle, the pointer is added to the container in
439 // the function
440 xAOD::TrackParticle* xp = m_particleCreator->createParticle(ctx, tp, &xaod);
441 return xp;
442}
443
446 const TrackCollection& container,
447 const Trk::Track& tp,
448 const EventContext& ctx)
449{
450 // create the xAOD::TrackParticle, the pointer is added to the container in
451 // the function
452 ElementLink<TrackCollection> trackLink(&tp, container,ctx);
453 return m_particleCreator->createParticle(ctx, trackLink, &xaod);
454}
455
456} // namespace xAODMaker
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Helpers for checking error return status codes and reporting errors.
Header file to be included by clients of the Monitored infrastructure.
std::map< int, std::tuple< Trk::Track *, double, xAOD::RejectionStep, xAOD::RejectionReason, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, float, float, int, std::vector< xAOD::RejectionStep >, std::vector< xAOD::RejectionReason > > > ObservedTrackMap
DataVector< Trk::Track > TrackCollection
This typedef represents a collection of Trk::Track objects.
bool msgLvl(const MSG::Level lvl) const
An algorithm that can be simultaneously executed in multiple threads.
DataModel_detail::iterator< DataVector > iterator
Definition DataVector.h:842
size_type size() const noexcept
Returns the number of elements in the collection.
Group of local monitoring quantities and retain correlation when filling histograms
A monitored timer.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
const std::string & name() const
Return the StoreGate ID for the referenced object.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
pointer_type ptr()
Dereference the pointer.
A summary of the information contained by a track.
const Trk::TrackSummary * trackSummary() const
Returns a pointer to the const Trk::TrackSummary owned by this const track (could be nullptr).
AssociationHelper(const Rec::TrackParticleContainer &cont_src, xAOD::TrackParticleContainer *cont_dest)
const Rec::TrackParticle * operator()(xAOD::TrackParticle *, unsigned int idx) const
AssociationHelper(const TrackCollection &, xAOD::TrackParticleContainer *)
const Trk::Track * operator()(xAOD::TrackParticle *track_particle, unsigned int) const
ToolHandle< xAODMaker::IRecTrackParticleContainerCnvTool > m_RecTrackParticleContainerCnvTool
Gaudi::Property< bool > m_convertAODTrackParticles
toggle on converting AOD track particles to xAOD
SG::ReadHandleKey< xAODTruthParticleLinkVector > m_truthParticleLinkVec
ToolHandle< GenericMonitoringTool > m_monTool
ToolHandle< ITrackParticleMonitoring > m_trackMonitoringTool
ToolHandle< xAODMaker::ITrackCollectionCnvTool > m_TrackCollectionCnvTool
virtual StatusCode initialize()
Function initialising the algorithm.
Gaudi::Property< bool > m_addTruthLink
toggle on adding truth links
SG::ReadHandleKey< Rec::TrackParticleContainer > m_aod
virtual StatusCode execute(const EventContext &ctx) const
Function executing the algorithm.
SG::ReadHandleKey< TrackParticleTruthCollection > m_aodTruth
SG::ReadHandleKey< TrackTruthCollection > m_trackTruth
SG::WriteHandleKey< xAOD::TrackParticleContainer > m_xaodTrackParticlesout
int convert(const EventContext &ctx, const CONT &, const TRUTHCONT &, CONVTOOL &tool, SG::WriteHandle< xAOD::TrackParticleContainer > &, const xAODTruthParticleLinkVector *, const xAOD::Vertex *primaryVertex=nullptr, const ObservedTrackMap *obs_track_map=0) const
SG::ReadHandleKey< ObservedTrackMap > m_tracksMap
TrackParticleCnvAlg(const std::string &name, ISvcLocator *svcLoc)
Regular algorithm constructor.
SG::WriteHandleKey< xAOD::TrackParticleContainer > m_xaodout
Gaudi::Property< bool > m_augmentObservedTracks
SG::ReadHandleKey< TrackCollection > m_tracks
SG::ReadHandleKey< xAOD::VertexContainer > m_primaryVertexContainer
xAOD::TrackParticle * createParticle(xAOD::TrackParticleContainer &xaod, const Rec::TrackParticleContainer &container, const Rec::TrackParticle &tp, const EventContext &ctx)
Gaudi::Property< bool > m_convertTracks
toggle on converting tracks to xAOD
ToolHandle< IMCTruthClassifier > m_truthClassifier
ToolHandle to truth classifier.
Gaudi::Property< bool > m_doMonitoring
ToolHandle< Trk::ITrackParticleCreatorTool > m_particleCreator
The key for the input TrackParticleTruthCollection.
ElementLink< xAOD::TruthParticleContainer > find(const HepMcParticleLink &hepMCLink) const
const Trk::Track * track() const
Returns a pointer (which can be NULL) to the Trk::Track which was used to make this TrackParticle.
float z() const
Returns the z position.
float y() const
Returns the y position.
float x() const
Returns the x position.
int ts
Definition globals.cxx:24
int uniqueID(const T &p)
std::tuple< unsigned int, T > defOrigOfParticle(T thePart)
Gaudi Tools.
@ numberOfPixelHits
number of pixel layers on track with absence of hits
@ numberOfSCTHoles
number of Holes in both sides of a SCT module
@ numberOfPixelHoles
number of pixels which have a ganged ambiguity.
@ PriVtx
Primary vertex.
@ NoVtx
Dummy vertex. TrackParticle was not used in vertex fit.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Vertex_v1 Vertex
Define the latest version of the vertex class.
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".