ATLAS Offline Software
Loading...
Searching...
No Matches
TrackParticleCnvAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5// $Id: TrackParticleCnvAlg.cxx 298303 2013-12-05 08:41:30Z emoyse $
6
7// Gaudi/Athena include(s):
9
10// EDM include(s):
11
14
18
19// Local include(s):
20#include "TrackParticleCnvAlg.h"
21
22namespace xAODMaker {
24 ISvcLocator* svcLoc)
25 : AthReentrantAlgorithm(name, svcLoc) {}
26
27StatusCode
29{
30
31 ATH_MSG_DEBUG("Initializing TrackParticleCnvAlg");
32 ATH_MSG_DEBUG("AODContainerName = " << m_aod.key());
33 ATH_MSG_DEBUG("xAODContainerName = " << m_xaodTrackParticlesout.key());
34 ATH_CHECK(m_particleCreator.retrieve());
36 ATH_CHECK(m_truthClassifier.retrieve());
37 else
38 m_truthClassifier.disable();
39 ATH_CHECK(m_TrackCollectionCnvTool.retrieve(DisableTool{ !m_convertTracks }));
41 DisableTool{ !m_convertAODTrackParticles }));
42 // to preserve the inisialised parameters of the ParticleCreatorTool:
43 ATH_MSG_DEBUG("Overriding particle creator tool settings.");
46 m_TrackCollectionCnvTool->setParticleCreatorTool(&m_particleCreator));
48 ATH_CHECK(m_RecTrackParticleContainerCnvTool->setParticleCreatorTool(
50
60
61 // Retrieve monitoring tools if provided
62 ATH_CHECK(m_trackMonitoringTool.retrieve(DisableTool{ !m_doMonitoring }));
63 ATH_CHECK(m_monTool.retrieve(DisableTool{ !m_doMonitoring }));
64
66
67 // Return gracefully:
68 return StatusCode::SUCCESS;
69}
70
71StatusCode
72TrackParticleCnvAlg::execute(const EventContext& ctx) const
73{
74
75 const Rec::TrackParticleContainer* aod = nullptr;
76 const TrackCollection* tracks = nullptr;
77 const xAODTruthParticleLinkVector* truthLinks = nullptr;
78 const TrackParticleTruthCollection* aodTruth = nullptr;
79 const TrackTruthCollection* trackTruth = nullptr;
80 const ObservedTrackMap* tracksMap = nullptr;
81 const xAOD::Vertex* primaryVertex = nullptr;
82
83 //timer object for total execution time
84 auto mnt_timer_Total = Monitored::Timer<std::chrono::milliseconds>("TIME_Total");
85
86 // Retrieve the AOD particles:
89 if (!rh_aod.isValid()) {
90 ATH_MSG_ERROR(m_aod.key() << " not found");
91 return StatusCode::FAILURE;
92 } else {
93 aod = rh_aod.cptr();
94 ATH_MSG_VERBOSE("Got TrackParticleContainer with key " << m_aod.key()
95 << " found.");
96 }
97 }
98 // Retrieve the Tracks:
99 if (m_convertTracks) {
101 if (!rh_tracks.isValid()) {
102 ATH_MSG_ERROR(m_tracks.key() << " not found");
103 return StatusCode::SUCCESS;
104 } else {
105 tracks = rh_tracks.cptr();
106 ATH_MSG_VERBOSE("Got TrackCollection with key " << m_tracks.key()
107 << " found.");
108
109 }
110 }
111 if (m_addTruthLink) {
114 if (!rh_aodTruth.isValid()) {
115 ATH_MSG_WARNING("No TrackParticleTruthCollection with key "
116 << m_aodTruth.key() << " found. Do nothing.");
117 return StatusCode::SUCCESS;
118 } else
119 aodTruth = rh_aodTruth.cptr();
120 }
121 if (m_convertTracks) {
123 if (!rh_trackTruth.isValid()) {
124 ATH_MSG_WARNING("No DetailedTrackTruthCollection with key "
125 << m_trackTruth.key() << " found. Do nothing.");
126 return StatusCode::SUCCESS;
127 } else
128 trackTruth = rh_trackTruth.cptr();
129 }
130
131 SG::ReadHandle<xAODTruthParticleLinkVector> rh_truthParticleLinkVec(
133 if (!rh_truthParticleLinkVec.isValid()) {
134 ATH_MSG_WARNING("No xAODTruthParticleLinkVector with key "
135 << m_truthParticleLinkVec.key() << " found. Do nothing.");
136 return StatusCode::SUCCESS;
137 } else
138 truthLinks = rh_truthParticleLinkVec.cptr();
139 }
140
141 if(!m_primaryVertexContainer.key().empty())
142 {
144 if (!vtx_container.isValid()) {
145 ATH_MSG_WARNING("No xAOD::VertexContainer with key "<< m_primaryVertexContainer.key() << " found. Do nothing.");
146 return StatusCode::SUCCESS;
147 }
148 const xAOD::Vertex* dummyVertex = nullptr;
149 for(auto vtx : *vtx_container) {
150 if(vtx->vertexType()==xAOD::VxType::PriVtx) {
151 primaryVertex = vtx;
152 break;
153 }
154 if(vtx->vertexType()==xAOD::VxType::NoVtx) {
155 // in case of no primary vertex
156 dummyVertex = vtx;
157 }
158 }
159 if(!primaryVertex)
160 {
161 if(dummyVertex)
162 {
163 ATH_MSG_INFO("No primary vertex found, will use dummy vertex at "
164 << dummyVertex->x() << "," << dummyVertex->y() << ","
165 << dummyVertex->z());
166 primaryVertex = dummyVertex;
167 }
168 else
169 {
170 ATH_MSG_WARNING("Neither primary nor dummy vertex found. Do Nothing.");
171 return StatusCode::SUCCESS;
172 }
173 }
174 }
175
176 if (m_convertTracks) {
178 ATH_CHECK(
179 wh_xaodout.record(std::make_unique<xAOD::TrackParticleContainer>(),
180 std::make_unique<xAOD::TrackParticleAuxContainer>()));
181
182 // Augment track particles with information from observer tool
185 if (!rh_tracksMap.isValid()) {
186 ATH_MSG_ERROR(m_tracksMap.key() << " not found");
187 return StatusCode::FAILURE;
188 }
189 else {
190 tracksMap = rh_tracksMap.cptr();
191 ATH_MSG_VERBOSE("Got ObservedTrackMap with key " << m_tracksMap.key()
192 << " found.");
193 }
194 convert((*tracks), trackTruth, m_TrackCollectionCnvTool, wh_xaodout,
195 truthLinks, primaryVertex, tracksMap);
196 } else {
197 convert((*tracks), trackTruth, m_TrackCollectionCnvTool, wh_xaodout,
198 truthLinks, primaryVertex);
199 }
200 // Monitor track parameters
201 if (m_doMonitoring)
202 m_trackMonitoringTool->monitor_tracks("Track", "Pass", *wh_xaodout);
203 }
205 SG::WriteHandle<xAOD::TrackParticleContainer> wh_xaodTrackParticlesout(
207 ATH_CHECK(wh_xaodTrackParticlesout.record(
208 std::make_unique<xAOD::TrackParticleContainer>(),
209 std::make_unique<xAOD::TrackParticleAuxContainer>()));
211 wh_xaodTrackParticlesout, truthLinks);
212 }
213
214 //extra scope needed to trigger the monitoring
215 {auto monTime = Monitored::Group(m_monTool, mnt_timer_Total);}
216
217 return StatusCode::SUCCESS;
218}
219
220template<typename CONT>
222
223template<>
225{
226public:
229 unsigned int) const
230 {
231 return track_particle->track();
232 }
233};
234
235template<>
236class AssociationHelper<Rec::TrackParticleContainer>
237{
238public:
241 : m_contSrc(&cont_src)
242 {
243 if (cont_src.size() != cont_dest->size()) {
244 std::stringstream message;
245 message << __FILE__ << ":" << __LINE__
246 << " Expected one-to-one conversion from AOD to xAOD "
247 "TrackParticles but sizes differ: "
248 << cont_src.size() << " != " << cont_dest->size();
249 throw std::runtime_error(message.str());
250 }
251 }
252
254 unsigned int idx) const
255 {
256 return m_contSrc->at(idx);
257 }
258
259private:
261};
262
263template<typename CONT, typename TRUTHCONT, typename CONVTOOL>
264int
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(&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(&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 float probability = -1.0;
349
350 ElementLink<CONT> tpLink(
351 association_to_src(*itr_xaod, itr_xaod - xaod->begin()), container);
352 if (!tpLink.isValid()) {
353 ATH_MSG_WARNING("Failed to create ElementLink to Track/TrackParticle");
354 } else if(truth->empty()){
355 // This can happen if there is no HS track
356 ATH_MSG_DEBUG("No truth available");
357 } else {
358 auto result = truth->find(tpLink);
359 if (result == truth->end()) {
361 "Failed find truth associated with Track/TrackParticle");
362 } else {
363 // setTruthLink(link,result->second, type, origin);
364 ATH_MSG_VERBOSE("Found track Truth: uniqueID "
365 << HepMC::uniqueID(result->second.particleLink()) << " evt "
366 << result->second.particleLink().eventIndex());
367 probability = result->second.probability();
368 link = truthLinkVec->find(result->second.particleLink());
369 if (link.isValid()) {
370 ATH_MSG_DEBUG("Found matching xAOD Truth: uniqueID "
371 << HepMC::uniqueID(*link) << " pt " << (*link)->pt()
372 << " eta " << (*link)->eta() << " phi "
373 << (*link)->phi());
374 // if configured also get truth classification
375 if (result->second.particleLink().cptr() &&
376 !m_truthClassifier.empty()) {
377 auto truthClass = m_truthClassifier->particleHepMCTruthClassifier(
378 result->second.particleLink());
379 type = truthClass.first;
380 origin = truthClass.second;
381 ATH_MSG_VERBOSE("Got truth type " << static_cast<int>(type)
382 << " origin "
383 << static_cast<int>(origin));
384 }
385 } else {
386 if (HepMC::uniqueID(result->second.particleLink()) > 0) {
387 ATH_MSG_WARNING("No associated xAOD truth for valid truth link "
388 << result->second.particleLink());
389 }
390 }
391 }
392 }
393 //This is the Algorithm creating TrackParticles
394 //
395 static const SG::AuxElement::Accessor<
397 theLink("truthParticleLink");
398 static const SG::AuxElement::Accessor<float> theProbability(
399 "truthMatchProbability");
400 theLink(*particle) = link;
401 theProbability(*particle) = probability;
402 if (!m_truthClassifier.empty()) {
403 static const SG::AuxElement::Accessor<int> theType("truthType");
404 static const SG::AuxElement::Accessor<int> theOrigin("truthOrigin");
405 theType(*particle) = static_cast<int>(type);
406 theOrigin(*particle) = static_cast<int>(origin);
407 }
408 }
409 } // loop over aod tracks
410
411 ATH_MSG_DEBUG("Converted [" << container.size() << " -> " << xaod->size()
412 << "] TrackParticles and stored in "
413 << xaod.name());
414 if (container.size() != xaod->size()) {
415 ATH_MSG_WARNING("number of items in the AOD container: "
416 << container.size()
417 << " is not equal to the number of items in its converted "
418 "xAOD equivalent: "
419 << xaod->size());
420 }
421
422 return 1;
423}
424
429 const Rec::TrackParticle& tp)
430{
431 // create the xAOD::TrackParticle, the pointer is added to the container in
432 // the function
433 xAOD::TrackParticle* xp = m_particleCreator->createParticle(tp, &xaod);
434 return xp;
435} // createParticleAndTruth
436
440 const Trk::Track& tp,
441 const EventContext& ctx)
442{
443 // create the xAOD::TrackParticle, the pointer is added to the container in
444 // the function
445 ElementLink<TrackCollection> trackLink(&tp, container,ctx);
446 return m_particleCreator->createParticle(trackLink, &xaod);
447}
448
449} // 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.
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.
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.
int convert(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< TrackParticleTruthCollection > m_aodTruth
SG::ReadHandleKey< TrackTruthCollection > m_trackTruth
SG::WriteHandleKey< xAOD::TrackParticleContainer > m_xaodTrackParticlesout
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
Gaudi::Property< bool > m_convertTracks
toggle on converting tracks to xAOD
ToolHandle< IMCTruthClassifier > m_truthClassifier
ToolHandle to truth classifier.
xAOD::TrackParticle * createParticle(xAOD::TrackParticleContainer &xaod, const Rec::TrackParticleContainer &container, const Rec::TrackParticle &tp)
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)
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".