ATLAS Offline Software
Loading...
Searching...
No Matches
Trk::DetailedTrackTruthBuilder Class Referencefinal

#include <DetailedTrackTruthBuilder.h>

Inheritance diagram for Trk::DetailedTrackTruthBuilder:
Collaboration diagram for Trk::DetailedTrackTruthBuilder:

Public Member Functions

virtual StatusCode initialize () override
virtual void buildDetailedTrackTruth (DetailedTrackTruthCollection *output, const TrackCollection &tracks, const std::vector< const PRD_MultiTruthCollection * > &prdTruth, const EventContext &ctx) const override
 See description for IDetailedTrackTruthBuilder::buildDetailedTrackTruth()

Private Types

typedef InverseMultiMap< PRD_MultiTruthCollectionPRD_InverseTruth

Private Member Functions

SubDetHitStatistics::SubDetType findSubDetType (const Identifier &id) const
void addTrack (DetailedTrackTruthCollection *output, const ElementLink< DataVector< Trk::Track > > &track, const std::vector< const PRD_MultiTruthCollection * > &orderedPRD_Truth, const PRD_InverseTruth &inverseTruth, const EventContext &ctx) const
void makeTruthToRecMap (PRD_InverseTruth &result, const PRD_MultiTruthCollection &rec2truth) const
SubDetHitStatistics countPRDsOnTruth (const TruthTrajectory &traj, const PRD_InverseTruth &inverseTruth) const

Private Attributes

const AtlasDetectorIDm_idHelper {}
PublicToolHandle< Trk::ITruthTrajectoryBuilderm_truthTrajBuilder {this, "TruthTrajectoryTool", "Trk::ElasticTruthTrajectoryBuilder"}

Detailed Description

Definition at line 25 of file DetailedTrackTruthBuilder.h.

Member Typedef Documentation

◆ PRD_InverseTruth

Member Function Documentation

◆ addTrack()

void Trk::DetailedTrackTruthBuilder::addTrack ( DetailedTrackTruthCollection * output,
const ElementLink< DataVector< Trk::Track > > & track,
const std::vector< const PRD_MultiTruthCollection * > & orderedPRD_Truth,
const PRD_InverseTruth & inverseTruth,
const EventContext & ctx ) const
private

Definition at line 207 of file DetailedTrackTruthBuilder.cxx.

212 {
213 const Trk::Track& track{**trackLink};
214 SubDetHitStatistics trackStat;
215 std::map<HepMcParticleLink,SubDetPRDs> pairStat; // stats for (track,GenParticle) for the current track
216 IProxyDict *proxy=ctx.getExtension<Atlas::ExtendedEventContext>().proxy();
217 //----------------------------------------------------------------
218 // loop over the RIO_OnTrack
219 for (const Trk::MeasurementBase* measurement : *track.measurementsOnTrack()) {
220 // not all MB are necessarily ROTs.
221 const Trk::RIO_OnTrack * riontrack = dynamic_cast<const Trk::RIO_OnTrack*>(measurement);
222
223 if (!riontrack) { // handle CompetingRIOsOnTrack case
224 const Trk::CompetingRIOsOnTrack* competing = dynamic_cast<const Trk::CompetingRIOsOnTrack*>(measurement);
225 if (competing) {
226 riontrack = & competing->rioOnTrack( competing->indexOfMaxAssignProb() );
227 }
228 }
229 if (!riontrack){
230 continue;
231 }
232 ATH_MSG_VERBOSE("Process ROT "<<(*riontrack));
233
234 // get the PrepRawData from the RIO_OnTrack
235 const Trk::PrepRawData* prd = riontrack->prepRawData();
236 if (!prd) {
237 ATH_MSG_WARNING("ROT without prd found...");
238 continue;
239 }
240 const Identifier& id = prd->identify();
242
244 ATH_MSG_WARNING("Invalid detector id "<<id);
245 continue;
246 }
247 if (!orderedPRD_Truth[subdet]) {
248 ATH_MSG_VERBOSE("No truth collection registered for "<<subdet);
249 continue;
250 }
251
252 ++trackStat[subdet];
253
254 using iprdt = PRD_MultiTruthCollection::const_iterator;
255 std::pair<iprdt, iprdt> range = orderedPRD_Truth[subdet]->equal_range(id);
256
257 int n=0;
258 // Loop over particles contributing to this cluster
259 for (iprdt i = range.first; i!= range.second; ++i) {
260 HepMC::ConstGenParticlePtr pa = (*i).second.cptr();
261 if (!pa) {
262 continue;
263 }
264
265 if (!i->second.isValid()) {
266 ATH_MSG_WARNING("Unexpected invalid HepMcParticleLink in PRD_MultiTruthCollection");
267 continue;
268 }
269 pairStat[i->second].subDetHits[subdet].insert(id);
270 ++n;
271 ATH_MSG_VERBOSE("PRD-ID:"<<id<<" subdet:"<<subdet<<" number:"<<n<<" particle link:"<<i->second);
272 }
273 if (n == 0) {
274 ATH_MSG_VERBOSE("--> no link, noise ? PRD-ID:"<<id<<" subdet:"<<subdet);
275 // add id 0 to pairs, we like to keep track of fake fakes
276 unsigned int UID(HepMC::UNDEFINED_ID);
277 unsigned int EV(0);
278 pairStat[HepMcParticleLink(UID,EV,HepMcParticleLink::IS_EVENTNUM,HepMcParticleLink::IS_ID)].subDetHits[subdet].insert(id);
279 }
280
281 } // Loop over measurements
282
283 if (msgLvl(MSG::VERBOSE)) {
284 msg(MSG::VERBOSE)<<"PRD truth particles = ";
285 for (std::map<HepMcParticleLink,SubDetPRDs>::const_iterator i=pairStat.begin(); i!=pairStat.end(); ++i) {
286 msg(MSG::VERBOSE)<<i->first<<",";
287 }
288 msg(MSG::VERBOSE)<<endmsg;
289 }
290
291 ATH_MSG_VERBOSE("Construct the stat structures....");
292 //----------------------------------------------------------------
293 // The stat structures are ready.
294 // Build truth trajectories for the track
295
296 std::set<HepMcParticleLink> seeds;
297 for (std::map<HepMcParticleLink,SubDetPRDs>::const_iterator i=pairStat.begin(); i!=pairStat.end(); ++i) {
298 if (i->first.isValid()) {
299 seeds.insert(i->first);
300 }
301 else {
302 // add id 0 particles, we like to keep track of fake fakes
303 TruthTrajectory traj;
304 traj.reserve(1);
305 traj.push_back(i->first);
306 ATH_MSG_VERBOSE("addTrack(): add id 0 hits (noise ?) to DetailedTrackTruthCollection.");
307
308 // noise/no truth hits on this track
309 SubDetHitStatistics noiseStat = makeSubDetHitStatistics(i->second);
310
311 // Only valid HepMcParticleLink make it into seeds and then into sprouts, and
312 // stored in the loop over sprouts below.
313 // Store output for noise/no truth particles here.
314 output->insert(std::make_pair(trackLink,
315 DetailedTrackTruth(traj,
316 noiseStat,
317 trackStat,
318 noiseStat) ));
319 }
320 }
321
322 // Grow sprouts from the seeds
323 using SproutMap = std::map<HepMcParticleLink, Sprout>;
324 SproutMap sprouts;
325 while (!seeds.empty() ) {
326 ATH_MSG_VERBOSE("Remaining seeds in set: "<<seeds.size());
327 HepMcParticleLink link = *seeds.begin();
328 Sprout current_sprout;
329 std::queue<HepMC::ConstGenParticlePtr> tmp;
330 ExtendedEventIndex eventIndex(link, proxy);
332 ATH_MSG_VERBOSE("Check link: "<<link);
333 const auto truthSuppressionStatus = link.getTruthSuppressionType();
334
335 unsigned nAncestor{0};
336 do {
337 HepMcParticleLink curlink( eventIndex.makeLink(HepMC::uniqueID(current), proxy));
338 curlink.setTruthSuppressionType(truthSuppressionStatus);
340 if (!nAncestor && !seeds.count(curlink)) {
341 ATH_MSG_WARNING("The first link should always point to the object itself.\nHowever "<<
342 link<<"=="<<curlink<<"\n evaluates to " <<(curlink==link)<<", getTruthSuppressionType: "
343 <<(curlink.getTruthSuppressionType() == link.getTruthSuppressionType())
344 <<", id:"<<(curlink.id() == link.id())
345 <<", eventIndex: "<<(curlink.eventIndex() == link.eventIndex()));
346 ATH_MSG_WARNING("Remove the link itself from the set");
347 seeds.erase(link);
348
349 }
350 // remove the current particle from the list of particles to consider (if it is still there)
351 seeds.erase(curlink);
352
353 // Have we worked on this particle before?
354 SproutMap::iterator p_old = sprouts.find(curlink);
355 if (p_old != sprouts.end()) {
356 //merge the old sprout with the current one.
357 current_sprout.splice(current_sprout.end(), p_old->second);
358 current_sprout.stat += p_old->second.stat;
359 // and remove the entry for the old
360 sprouts.erase(p_old);
361 break; // the do-while(getMother()) loop
362 }
363 // No, this is a new particle. Try to extend the current truth trajectory.
364
365 // Add the particle to the current truth trajectory.
366 // New: with the current stricter cuts on mother-daughter
367 // we don't have to require that ancestors produce hits.
368
369 current_sprout.push_back(current);
370
371 std::map<HepMcParticleLink,SubDetPRDs>::iterator p_newstat = pairStat.find(curlink);
372 if (p_newstat != pairStat.end()) {
373 current_sprout.stat += p_newstat->second;
374 }
375
376
377 } while ( (current = m_truthTrajBuilder->getMother(current)) && ++nAncestor);
378
379 // Add the grown sprout to the list
380 sprouts.insert(std::make_pair(link, current_sprout));
381
382 } // while(!seeds.empty())
383
384 //----------------
385 // All seeds have been processed, and the upstream extensions of the
386 // sprouts are done. Extend the sprouts downstream to get the final
387 // truth trajectories and store the result.
388 //
389 // Note: so far the "sprouts" object mapped {last particle ==> sprout}
390 // Extending a sprout downstream will break this relationship,
391 // but at this point we don't care about it and will only use the
392 // value of the map, not the key.
393
394 for (SproutMap::iterator s=sprouts.begin(); s!=sprouts.end(); ++s) {
395
396 // Attempt to extend the TruthTrajectory sprout to the "outside".
397 // This may add only hits that are *not* on the current track.
398 // Thus no need to update stats track and stats common.
399
400 auto current = *s->second.begin();
401 while( (current = m_truthTrajBuilder->getDaughter(current)) ) {
402 s->second.push_front(current);
403 }
404
405 // Now we have info to build the final TruthTrajectory.
406 // FIXME: what is the current average size?
407 TruthTrajectory traj;
408 traj.reserve(2); // The average size is about 1.05. Hardcode that instead of using slow list::size().
409 for (Sprout::const_iterator ppart=s->second.begin(); ppart!=s->second.end(); ++ppart) {
410 traj.push_back(HepMcParticleLink(ExtendedEventIndex(s->first, proxy).makeLink(HepMC::uniqueID(*ppart), proxy)));
411 }
412
413 // Count PRDs on the TruthTrajectory
414 SubDetHitStatistics truthStat = countPRDsOnTruth(traj, inverseTruth);
415
416 ATH_MSG_VERBOSE("addTrack(): sprout length = "<<traj.size());
417 output->insert(std::make_pair(trackLink,
418 DetailedTrackTruth(traj,
419 makeSubDetHitStatistics(s->second.stat),
420 trackStat,
421 truthStat) ));
422 }
423
424
425 ATH_MSG_VERBOSE("addTrack(): #sprouts = "<<sprouts.size()<<", output->size() = "<<output->size());
426 }
#define endmsg
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
unsigned int indexOfMaxAssignProb() const
Index of the ROT with the highest assignment probability.
virtual const RIO_OnTrack & rioOnTrack(unsigned int) const =0
returns the RIO_OnTrack (also known as ROT) objects depending on the integer.
PublicToolHandle< Trk::ITruthTrajectoryBuilder > m_truthTrajBuilder
SubDetHitStatistics::SubDetType findSubDetType(const Identifier &id) const
SubDetHitStatistics countPRDsOnTruth(const TruthTrajectory &traj, const PRD_InverseTruth &inverseTruth) const
Identifier identify() const
return the identifier
virtual const Trk::PrepRawData * prepRawData() const =0
returns the PrepRawData (also known as RIO) object to which this RIO_OnTrack is associated.
thread_local event_number_t eventIndex
int uniqueID(const T &p)
constexpr int UNDEFINED_ID
const GenParticle * ConstGenParticlePtr
Definition GenParticle.h:38
output
Definition merge.py:16
MsgStream & msg
Definition testRead.cxx:32

◆ buildDetailedTrackTruth()

void Trk::DetailedTrackTruthBuilder::buildDetailedTrackTruth ( DetailedTrackTruthCollection * output,
const TrackCollection & tracks,
const std::vector< const PRD_MultiTruthCollection * > & prdTruth,
const EventContext & ctx ) const
overridevirtual

See description for IDetailedTrackTruthBuilder::buildDetailedTrackTruth()

Definition at line 86 of file DetailedTrackTruthBuilder.cxx.

91 {
92 ATH_MSG_VERBOSE("DetailedTrackTruthBuilder::buildDetailedTrackTruth() ");
93
94 if (!output) { return; }
95
96 //----------------------------------------------------------------
97 // The caller can pass PRD truth collections in any order. Sort them out.
98
99 std::vector<const PRD_MultiTruthCollection*> orderedPRD_Truth(SubDetHitStatistics::NUM_SUBDETECTORS);
100 PRD_InverseTruth inverseTruth;
101
102 for ( const PRD_MultiTruthCollection* prdTruthColl : prdTruth ) {
103 if (prdTruthColl->empty()) {
104 continue;
105 }
106
107 SubDetHitStatistics::SubDetType subdet = findSubDetType(prdTruthColl->begin()->first);
108 ATH_MSG_DEBUG("Assign: "<<prdTruthColl<<" to "<<subdet);
110 orderedPRD_Truth[subdet] = prdTruthColl;
111 makeTruthToRecMap(inverseTruth,*prdTruthColl);
112 } else {
113 ATH_MSG_WARNING("Got unknown SubDetType in prdTruth ");
114 }
115 }
116 ATH_MSG_DEBUG("makeTruthToRecMap filling done");
117
118 //----------------------------------------------------------------
119 // Find associated truth for each track
120
121 for (unsigned itrack=0; itrack<tracks.size(); ++itrack) {
122 ElementLink<DataVector<Trk::Track> > ptrack(tracks, itrack);
123 addTrack(output, ptrack, orderedPRD_Truth, inverseTruth, ctx);
124 }
125
126 // DEBUG
127 // FIXME: in normal production jobs that does *a lot of* formatting only to discard the result...
128 ATH_MSG_DEBUG("Dumping output collection.\n"
129 " Entries with TruthTrajectories of more then one particle shown at the DEBUG level.\n"
130 " Use VERBOSE level for complete dump.");
131
132 for (DetailedTrackTruthCollection::const_iterator i=output->begin(); i!=output->end(); ++i) {
133 bool interesting = (i->second.trajectory().size() > 1);
134
135 msg(interesting ? MSG::DEBUG : MSG::VERBOSE)
136 <<"out: trk="<<i->first.index()<<" => "<<i->second<<endmsg;
137
138 if (interesting) {
139 const TruthTrajectory& t = i->second.trajectory();
140 msg(MSG::VERBOSE)<<"Particles on the trajectory:\n";
141 for (unsigned k=0; k<t.size(); ++k) {
142 msg(MSG::VERBOSE)<<t[k]<<"\n";
143 }
144 msg(MSG::VERBOSE)<<"\n"<<endmsg;
145 }
146
147 }
148
149 }
#define ATH_MSG_DEBUG(x)
size_type size() const noexcept
Returns the number of elements in the collection.
InverseMultiMap< PRD_MultiTruthCollection > PRD_InverseTruth
void makeTruthToRecMap(PRD_InverseTruth &result, const PRD_MultiTruthCollection &rec2truth) const
void addTrack(DetailedTrackTruthCollection *output, const ElementLink< DataVector< Trk::Track > > &track, const std::vector< const PRD_MultiTruthCollection * > &orderedPRD_Truth, const PRD_InverseTruth &inverseTruth, const EventContext &ctx) const

◆ countPRDsOnTruth()

SubDetHitStatistics Trk::DetailedTrackTruthBuilder::countPRDsOnTruth ( const TruthTrajectory & traj,
const PRD_InverseTruth & inverseTruth ) const
private

Definition at line 451 of file DetailedTrackTruthBuilder.cxx.

453 {
454 // Different particles from the same TruthTrajectory can contribute to the same cluster.
455 // We should be careful to avoid double-counting in such cases.
456
457
458 SubDetPRDs prds;
459 for (TruthTrajectory::const_iterator p = traj.begin(); p != traj.end(); ++p) {
460 // if this is a geantino (pile-up truth reduction), then we
461 // would sum over hits from all particles that arise from this
462 // pile-up collision. the result is useless. don't do it. in
463 // release 20, geantinos have pdg_id==999
464 if (!(*p).cptr()) {
465 ATH_MSG_WARNING( "HepMcParticleLink " << *p << " in truth trajectory does not point to a valid GenParticle.");
466 continue;
467 }
468 if ( MC::isGeantino(*p) ) { continue; }
469 using iter = PRD_InverseTruth::const_iterator;
470 std::pair<iter,iter> range = inverseTruth.equal_range(*p);
471 for (iter i = range.first; i != range.second; ++i) {
473
474 if (subdet<SubDetHitStatistics::NUM_SUBDETECTORS) prds.subDetHits[subdet].insert(i->second);
475 }
476 }
477
478 return makeSubDetHitStatistics(prds);
479 }
bool isGeantino(const T &p)

◆ findSubDetType()

SubDetHitStatistics::SubDetType Trk::DetailedTrackTruthBuilder::findSubDetType ( const Identifier & id) const
private

Definition at line 158 of file DetailedTrackTruthBuilder.cxx.

158 {
159 if (m_idHelper->is_pixel(id))
161 if (m_idHelper->is_sct(id))
163 if (m_idHelper->is_trt(id))
165 if (m_idHelper->is_mdt(id))
167 if (m_idHelper->is_rpc(id))
169 if (m_idHelper->is_tgc(id))
171 if (m_idHelper->is_stgc(id))
173 if (m_idHelper->is_mm(id))
175 if (m_idHelper->is_csc(id))
177
178
179 ATH_MSG_WARNING("findSubDetType(): UNKNOWN subdet for id="<<id);
180
182 }

◆ initialize()

StatusCode Trk::DetailedTrackTruthBuilder::initialize ( )
overridevirtual

Definition at line 77 of file DetailedTrackTruthBuilder.cxx.

78 {
79 ATH_CHECK( m_truthTrajBuilder.retrieve() );
80 ATH_CHECK( detStore()->retrieve(m_idHelper, "AtlasID") );
81
82 return StatusCode::SUCCESS;
83 }
#define ATH_CHECK
Evaluate an expression and check for errors.
retrieve(aClass, aKey=None)
Definition PyKernel.py:110

◆ makeTruthToRecMap()

void Trk::DetailedTrackTruthBuilder::makeTruthToRecMap ( PRD_InverseTruth & result,
const PRD_MultiTruthCollection & rec2truth ) const
private

Definition at line 428 of file DetailedTrackTruthBuilder.cxx.

428 {
429 // invert the map from Identifier (reco hit) to HepMcParticleLink,
430 // to allow lookup of all Identifiers produced by a given HepMcParticleLink.
431 // the result is only used in countPRDsOnTruth. since that code ignores
432 // geantinos, don't bother to sort the geantinos here.
433 for ( const auto& i : rec2truth ) {
434 // i.first = Identifier
435 // i.second = HepMcParticleLink
436 auto pa = i.second.cptr();
437 if ( !pa ) { // skip noise
438 continue;
439 }
440 ATH_MSG_VERBOSE("Check geantino "<<MC::isGeantino(pa)<<", is_truth_suppressed_pileup:"
442
443 if ( MC::isGeantino(pa) && HepMC::is_truth_suppressed_pileup(i.second) ) {
444 continue;
445 } // skip geantinos
446 result.insert(std::make_pair(i.second, i.first));
447 }
448 }
bool is_truth_suppressed_pileup(const T &p)
Method to establish if a particle (or barcode) corresponds to truth-suppressed pile-up (TODO update t...

Member Data Documentation

◆ m_idHelper

const AtlasDetectorID* Trk::DetailedTrackTruthBuilder::m_idHelper {}
private

Definition at line 41 of file DetailedTrackTruthBuilder.h.

41{};

◆ m_truthTrajBuilder

PublicToolHandle<Trk::ITruthTrajectoryBuilder> Trk::DetailedTrackTruthBuilder::m_truthTrajBuilder {this, "TruthTrajectoryTool", "Trk::ElasticTruthTrajectoryBuilder"}
private

Definition at line 43 of file DetailedTrackTruthBuilder.h.

43{this, "TruthTrajectoryTool", "Trk::ElasticTruthTrajectoryBuilder"};

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