ATLAS Offline Software
Loading...
Searching...
No Matches
DetailedMuonPatternTruthBuilder.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include <algorithm>
8#include <iostream>
9#include <iterator>
10#include <list>
11#include <map>
12#include <queue>
13
53#include "TrkTrack/Track.h"
57
59 DetectorLayer() = default;
60 Muon::MuonStationIndex::StIndex stIndex{Muon::MuonStationIndex::StIndex::StUnknown};
61 bool isEndcap{false};
62 double minPos{FLT_MAX}; // flag whether first and second globalpos have been filled
63 double maxPos{-FLT_MAX};
64 int nnsw{0};
65 int nmdtS{0};
66 int nmdtL{0};
67 int nphi{0};
68 Amg::Vector3D first3D{Amg::Vector3D::Zero()};
69 Amg::Vector3D last3D{Amg::Vector3D::Zero()};
70 std::vector<const Trk::MeasurementBase*> meas;
71};
72
73namespace {
74
75 template <class Map> void printMap(const Map& m) {
76 std::cout << "printMap(): [";
77 for (typename Map::const_iterator i = m.begin(); i != m.end(); ++i) { std::cout << "(" << i->first << "," << i->second << "), "; }
78 std::cout << "]" << std::endl;
79 }
80
81 struct SubDetPRDs {
82 std::array<std::set<Identifier>, SubDetHitStatistics::NUM_SUBDETECTORS> subDetHits;
83 };
84
85 SubDetPRDs& operator+=(SubDetPRDs& a, const SubDetPRDs& b) {
86 for (unsigned i = 0; i < SubDetHitStatistics::NUM_SUBDETECTORS; i++) {
87 const std::set<Identifier>& bset = b.subDetHits[i];
88 for (std::set<Identifier>::const_iterator pb = bset.begin(); pb != bset.end(); ++pb) { a.subDetHits[i].insert(*pb); }
89 }
90 return a;
91 }
92
93 SubDetHitStatistics makeSubDetHitStatistics(const SubDetPRDs& prds) {
95 for (unsigned i = 0; i < SubDetHitStatistics::NUM_SUBDETECTORS; i++) {
96 res[SubDetHitStatistics::SubDetType(i)] = prds.subDetHits[i].size();
97 }
98 return res;
99 }
100
101 // Truth trajectory sprouts
102 class Sprout : public std::list<HepMC::ConstGenParticlePtr> {
103 public:
104 SubDetPRDs stat;
105 };
106
107} // namespace
108
109namespace Trk {
110
111 //================================================================
113 const IInterface* parent) :
114 AthAlgTool(type, name, parent) {
115 declareInterface<IDetailedMuonPatternTruthBuilder>(this);
116 }
117
118 //================================================================
120 ATH_CHECK(m_truthTrackBuilder.retrieve());
121 ATH_CHECK(m_idHelperSvc.retrieve());
122 ATH_CHECK(m_mdtCreator.retrieve());
124 return StatusCode::SUCCESS;
125 }
126
127 //================================================================
130 const std::vector<const PRD_MultiTruthCollection*>& prdTruth) {
131 ATH_MSG_VERBOSE("DetailedMuonPatternTruthBuilder::buildDetailedMuonPatternTruth() ");
132
133 if (!output) { return; }
134
135 //----------------------------------------------------------------
136 // The caller can pass PRD truth collections in any order. Sort them out.
137
138 std::vector<const PRD_MultiTruthCollection*> orderedPRD_Truth(SubDetHitStatistics::NUM_SUBDETECTORS);
139 PRD_InverseTruth inverseTruth;
140
141 for (std::vector<const PRD_MultiTruthCollection*>::const_iterator i = prdTruth.begin(); i != prdTruth.end(); ++i) {
142 if (*i) {
143 if (!(*i)->empty()) {
144 SubDetHitStatistics::SubDetType subdet = findSubDetType((*i)->begin()->first);
145
147 orderedPRD_Truth[subdet] = *i;
148 addToInverseMultiMap(&inverseTruth, **i);
149 } else {
150 ATH_MSG_WARNING("Got unknown SubDetType in prdTruth ");
151 }
152 } else {
153 ATH_MSG_DEBUG("Empty truth ???");
154 }
155 }
156 }
157
158 //----------------------------------------------------------------
159 // Find associated truth for each track
160
161 for (unsigned itrack = 0; itrack < patterns.size(); itrack++) {
163 addTrack(output, ptrack, orderedPRD_Truth, inverseTruth);
164 }
165
166 // DEBUG
167 // FIXME: in normal production jobs that does *a lot of* formatting only to discard the result...
169 "Dumping output collection.\n"
170 " Entries with TruthTrajectories of more then one particle shown at the DEBUG level.\n"
171 " Use VERBOSE level for complete dump.");
172
173 for (DetailedMuonPatternTruthCollection::const_iterator i = output->begin(); i != output->end(); ++i) {
174 bool interesting = (i->second.trajectory().size() > 1);
175
176 // TODO: Reinsert the following code once I understand the compile-time error
177 // msg(interesting ? MSG::DEBUG : MSG::VERBOSE)
178 // <<"out: trk="<<i->first.index()<<" => "<<i->second<<endmsg;
179
180 if (interesting) {
181 const TruthTrajectory& t = i->second.trajectory();
182 msg(MSG::VERBOSE) << "Particles on the trajectory:\n";
183 for (unsigned k = 0; k < t.size(); ++k) { msg(MSG::VERBOSE) << t[k] << "\n"; }
184 msg(MSG::VERBOSE) << "\n" << endmsg;
185 }
186 }
187 }
188
189 //================================================================
190
191 void DetailedMuonPatternTruthBuilder::buildDetailedTrackTruth(std::vector<DetailedTrackTruth>* output,
192 const Muon::MuonPatternCombination& pattern,
193 const std::vector<const PRD_MultiTruthCollection*>& prdTruth) {
194 ATH_MSG_VERBOSE("DetailedMuonPatternTruthBuilder::buildDetailedTrackTruth() ");
195
196 if (!output) { return; }
197
198 //----------------------------------------------------------------
199 // The caller can pass PRD truth collections in any order. Sort them out.
200
201 std::vector<const PRD_MultiTruthCollection*> orderedPRD_Truth(SubDetHitStatistics::NUM_SUBDETECTORS);
202 PRD_InverseTruth inverseTruth;
203
204 for (std::vector<const PRD_MultiTruthCollection*>::const_iterator i = prdTruth.begin(); i != prdTruth.end(); ++i) {
205 if (*i) {
206 if (!(*i)->empty()) {
207 SubDetHitStatistics::SubDetType subdet = findSubDetType((*i)->begin()->first);
208
210 orderedPRD_Truth[subdet] = *i;
211 addToInverseMultiMap(&inverseTruth, **i);
212 } else {
213 ATH_MSG_WARNING("Got unknown SubDetType in prdTruth ");
214 }
215 } else {
216 ATH_MSG_DEBUG("Empty truth ???");
217 }
218 }
219 }
220
221 //----------------------------------------------------------------
222 // Find associated truth for each track
223 addDetailedTrackTruth(output, pattern, orderedPRD_Truth, inverseTruth);
224
225 // DEBUG
226 // FIXME: in normal production jobs that does *a lot of* formatting only to discard the result...
228 "Dumping output collection.\n"
229 " Entries with TruthTrajectories of more then one particle shown at the DEBUG level.\n"
230 " Use VERBOSE level for complete dump.");
231
232
233 }
234 //================================================================
235
236 //================================================================
237 // Plagiarized from
238 // Tracking/TrkTools/TrkTruthCreatorTools/src/TrackTruthMaker.cxx
239 // (no way to reuse its private function PrepRawDataCollectionType() )
240
242 if (!m_idHelperSvc->isMuon(id)) {
243 if (m_idHelperSvc->mdtIdHelper().is_pixel(id))
245 else if (m_idHelperSvc->mdtIdHelper().is_sct(id))
247 else if (m_idHelperSvc->mdtIdHelper().is_trt(id))
249 } else {
250 if (m_idHelperSvc->isMdt(id))
252 else if (m_idHelperSvc->isRpc(id))
254 else if (m_idHelperSvc->isTgc(id))
256 else if (m_idHelperSvc->isCsc(id))
258 else if (m_idHelperSvc->isMM(id))
260 else if (m_idHelperSvc->issTgc(id))
262 }
263
264 ATH_MSG_WARNING("findSubDetType(): UNKNOWN subdet for id=" << id);
265
267 }
268
269 //================================================================
272 const std::vector<const PRD_MultiTruthCollection*>& orderedPRD_Truth,
273 const PRD_InverseTruth& inverseTruth) {
274 SubDetHitStatistics trackStat;
275 std::map<HepMcParticleLink, SubDetPRDs> pairStat; // stats for (track,GenParticle) for the current track
276
277 // Loop over MuonPatternChamberIntersect
278 const std::vector<Muon::MuonPatternChamberIntersect>& MPCIV = (*MuPatternCombo)->chamberData();
279 for (unsigned int i_MPCI = 0; i_MPCI < MPCIV.size(); i_MPCI++) {
280 if (MPCIV.empty()) continue;
281
282 // get the PrepRawData from the MuonPatternChamberIntersect
283 std::vector<const Trk::PrepRawData*> PRDV = MPCIV.at(i_MPCI).prepRawDataVec();
284
285 // Loop over the PRDV
286 for (unsigned int j_PRD = 0; j_PRD < PRDV.size(); j_PRD++) {
287 if (PRDV.empty()) continue;
288
289 Identifier id = PRDV.at(j_PRD)->identify();
291
293 // if PRD truth collection is missing, ignore subdet in track stat calculation as well.
294 if (orderedPRD_Truth[subdet]) {
295 ++trackStat[subdet];
296
297 typedef PRD_MultiTruthCollection::const_iterator iprdt;
298 std::pair<iprdt, iprdt> range = orderedPRD_Truth[subdet]->equal_range(id);
299
300 int n = 0;
301 // Loop over particles contributing to this cluster
302 for (iprdt i = range.first; i != range.second; ++i) {
303 if (!i->second.isValid()) {
304 ATH_MSG_WARNING("Unexpected invalid HepMcParticleLink in PRD_MultiTruthCollection");
305 } else {
306 pairStat[i->second].subDetHits[subdet].insert(id);
307 n += 1;
308 ATH_MSG_VERBOSE("PRD-ID:" << id << " subdet:" << subdet << " number:" << n
309 << " particle link:" << i->second);
310 }
311 }
312 if (n == 0) {
313 ATH_MSG_VERBOSE("--> no link, noise ? PRD-ID:" << id << " subdet:" << subdet);
314 // add unique ID 0 to pairs, we like to keep track of fake fakes
315 unsigned int ID(0), EV(0);
316 pairStat[HepMcParticleLink(ID, EV, HepMcParticleLink::IS_POSITION, HepMcParticleLink::IS_ID)].subDetHits[subdet].insert(id);
317 }
318 } // orderedPRD_Truth[] available
319 } // subdet type check, warning in findSubDetType()
320 }
321 }
322
323 if (msgLvl(MSG::VERBOSE)) {
324 msg(MSG::VERBOSE) << "PRD truth particles = ";
325 for (std::map<HepMcParticleLink, SubDetPRDs>::const_iterator i = pairStat.begin(); i != pairStat.end(); ++i) {
326 msg(MSG::VERBOSE) << i->first << ",";
327 }
328 msg(MSG::VERBOSE) << endmsg;
329 }
330
331 //----------------------------------------------------------------
332 // The stat structures are ready.
333 // Build truth trajectories for the track
334 std::set<HepMcParticleLink> seeds;
335 for (std::map<HepMcParticleLink, SubDetPRDs>::const_iterator i = pairStat.begin(); i != pairStat.end(); ++i) {
336 if (i->first.isValid()) {
337 seeds.insert(i->first);
338 } else {
339 // add uniqueID 0 particles, we like to keep track of fake fakes
340 TruthTrajectory traj;
341 traj.reserve(1);
342 traj.push_back(i->first);
343 ATH_MSG_VERBOSE("addTrack(): add barcode 0 hits - noise ?");
344
345 // noise/no truth hits on this track
346 SubDetHitStatistics noiseStat = makeSubDetHitStatistics(i->second);
347
348 // Only valid HepMcParticleLink make it into seeds and then into sprouts, and
349 // stored in the loop over sprouts below.
350 // Store output for noise/no truth particles here.
351 output->insert(std::make_pair(MuPatternCombo, DetailedTrackTruth(traj, noiseStat, trackStat, noiseStat)));
352 }
353 }
354
355 // Grow sprouts from the seeds
356 typedef std::map<HepMcParticleLink, Sprout> SproutMap;
357 SproutMap sprouts;
358
359 while (!seeds.empty()) {
360 HepMcParticleLink link = *seeds.begin();
361
362 Sprout current_sprout;
363 std::queue<HepMC::ConstGenParticlePtr> tmp;
364 unsigned eventIndex = link.eventIndex();
365#ifdef HEPMC3
366 HepMC::ConstGenParticlePtr current = link.scptr();
367#else
368 const HepMC::GenParticle* current = link.cptr();
369#endif
370
371 do {
373
374 // remove the current particle from the list of particles to consider (if it is still there)
375 seeds.erase(curlink);
376
377 // Have we worked on this particle before?
378 SproutMap::iterator p_old = sprouts.find(curlink);
379 if (p_old != sprouts.end()) {
380 // merge the old sprout with the current one.
381 current_sprout.splice(current_sprout.end(), p_old->second);
382 current_sprout.stat += p_old->second.stat;
383 // and remove the entry for the old
384 sprouts.erase(p_old);
385 break; // the do-while(getMother()) loop
386 } else { // No, this is a new particle. Try to extend the current truth trajectory.
387
388 // Add the particle to the current truth trajectory.
389 // New: with the current stricter cuts on mother-daughter
390 // we don't have to require that ancestors produce hits.
391
392 current_sprout.push_back(current);
393
394 std::map<HepMcParticleLink, SubDetPRDs>::iterator p_newstat = pairStat.find(curlink);
395 if (p_newstat != pairStat.end()) { current_sprout.stat += p_newstat->second; }
396 }
397 } while ((current = m_truthTrackBuilder->getMother(current)));
398
399 // Add the grown sprout to the list
400 sprouts.insert(std::make_pair(link, current_sprout));
401
402 } // while(!seeds.empty())
403
404 //----------------
405 // All seeds have been processed, and the upstream extensions of the
406 // sprouts are done. Extend the sprouts downstream to get the final
407 // truth trajectories and store the result.
408 //
409 // Note: so far the "sprouts" object mapped {last particle ==> sprout}
410 // Extending a sprout downstream will break this relationship,
411 // but at this point we don't care about it and will only use the
412 // value of the map, not the key.
413
414 for (SproutMap::iterator s = sprouts.begin(); s != sprouts.end(); ++s) {
415 // Attempt to extend the TruthTrajectory sprout to the "outside".
416 // This may add only hits that are *not* on the current track.
417 // Thus no need to update stats track and stats common.
418
419 HepMC::ConstGenParticlePtr current = *s->second.begin();
420 while ((current = m_truthTrackBuilder->getDaughter(current))) { s->second.push_front(current); }
421
422 // Now we have info to build the final TruthTrajectory.
423 // FIXME: what is the current average size?
424 TruthTrajectory traj;
425 traj.reserve(2); // The average size is about 1.05. Hardcode that instead of using slow list::size().
426 for (Sprout::const_iterator ppart = s->second.begin(); ppart != s->second.end(); ++ppart) {
427 traj.push_back(HepMcParticleLink(HepMC::uniqueID(*ppart), s->first.eventIndex(), HepMcParticleLink::IS_EVENTNUM, HepMcParticleLink::IS_ID));
428 }
429
430 // Count PRDs on the TruthTrajectory
431 std::set<Muon::MuonStationIndex::ChIndex> tempSet;
432 SubDetHitStatistics truthStat = countPRDsOnTruth(traj, inverseTruth, tempSet);
433
434 ATH_MSG_VERBOSE("addTrack(): sprout length = " << traj.size());
435 output->insert(
436 std::make_pair(MuPatternCombo, DetailedTrackTruth(traj, makeSubDetHitStatistics(s->second.stat), trackStat, truthStat)));
437 }
438
439 ATH_MSG_VERBOSE("addTrack(): #sprouts = " << sprouts.size() << ", output->size() = " << output->size());
440 }
441
442 //================================================================
444 std::set<Muon::MuonStationIndex::ChIndex> chIndices) {
445 // Different particles from the same TruthTrajectory can contribute to the same cluster.
446 // We should be careful to avoid double-counting in such cases.
447
448 SubDetPRDs prds;
449 for (TruthTrajectory::const_iterator p = traj.begin(); p != traj.end(); ++p) {
450 typedef PRD_InverseTruth::const_iterator iter;
451 std::pair<iter, iter> range = inverseTruth.equal_range(*p);
452 for (iter i = range.first; i != range.second; ++i) {
453 if (chIndices.find(m_idHelperSvc->chamberIndex(i->second)) != chIndices.end()) {
455 if (subdet == SubDetHitStatistics::NUM_SUBDETECTORS) continue;
456 prds.subDetHits[subdet].insert(i->second);
457 }
458 }
459 }
460
461 return makeSubDetHitStatistics(prds);
462 }
463
464 //================================================================
466 std::list<HepMC::ConstGenParticlePtr> genPartList, int truthPos,
467 std::set<Muon::MuonStationIndex::ChIndex> chIndices) {
468 double minPos = 2e8, maxPos = 0;
469 Amg::Vector3D first3D(0, 0, 0), last3D(0, 0, 0);
470
471 if (genPartList.empty()) {
472 ATH_MSG_WARNING("No GenParticles associated to this PRD_TruthTrajectory. Exiting segment creation.");
473 return Amg::Vector3D(0, 0, 0);
474 }
475
476 const MuonSimDataCollection* mdtSimDataMap = retrieveTruthCollection("MDT_SDO");
477 if (!mdtSimDataMap) {
478 ATH_MSG_WARNING(" failed to retrieve MuonSimDataCollection: "
479 << "MDT_SDO");
480 return Amg::Vector3D(0, 0, 0);
481 }
482 const MuonSimDataCollection* mmSimDataMap = retrieveTruthCollection("MM_SDO");
483 if (!mmSimDataMap) {
484 ATH_MSG_WARNING(" failed to retrieve MuonSimDataCollection: "
485 << "MM_SDO");
486 return Amg::Vector3D(0, 0, 0);
487 }
488 const MuonSimDataCollection* stgcSimDataMap = retrieveTruthCollection("sTGC_SDO");
489 if (!stgcSimDataMap) {
490 ATH_MSG_WARNING(" failed to retrieve MuonSimDataCollection: "
491 << "sTGC_SDO");
492 return Amg::Vector3D(0, 0, 0);
493 }
494
495 // First sort the hits per detector layer
496 std::map<Muon::MuonStationIndex::StIndex, DetectorLayer> hitsPerLayer;
497 std::map<const Trk::TrkDetElementBase*, std::pair<std::list<const Trk::PrepRawData*>, std::list<const Trk::PrepRawData*> > >
498 clustersPerDetEl;
499
500 // Loop over containedROTs in segment
501 for (unsigned int i_cROTv = 0; i_cROTv < segment.numberOfContainedROTs(); i_cROTv++) {
502 const Trk::RIO_OnTrack* rot = segment.rioOnTrack(i_cROTv);
503
504 // get the PrepRawData from the ROT
505 const Trk::PrepRawData* prd = rot->prepRawData();
506
507 Identifier id = prd->identify();
508
509 Muon::MuonStationIndex::StIndex stIndex = m_idHelperSvc->stationIndex(id);
510 bool isEndcap = m_idHelperSvc->isEndcap(id);
511
512 if (chIndices.find(m_idHelperSvc->chamberIndex(id)) == chIndices.end()) {
513 ATH_MSG_DEBUG("Muon station doesn't match segment. Continuing");
514 continue;
515 }
516
517 // some patches until MuonIdHelper is updated
518 const Muon::MMPrepData* mm = dynamic_cast<const Muon::MMPrepData*>(prd);
519 if (mm) {
520 isEndcap = true;
521 stIndex = Muon::MuonStationIndex::StIndex::EI;
522 }
523 const Muon::sTgcPrepData* stgc = dynamic_cast<const Muon::sTgcPrepData*>(prd);
524 if (stgc) {
525 isEndcap = true;
526 stIndex = Muon::MuonStationIndex::StIndex::EI;
527 }
528 // BEGIN NEW WORK
529
530 DetectorLayer& detLayer = hitsPerLayer[stIndex];
531 detLayer.isEndcap = isEndcap;
532 detLayer.stIndex = stIndex;
533
534 // const Trk::MeasurementBase* meas = 0;
535 if (m_idHelperSvc->isMdt(id)) {
536 const Muon::MdtPrepData* mprd = dynamic_cast<const Muon::MdtPrepData*>(prd);
537 if (!mprd) {
538 ATH_MSG_WARNING(" MDT PRD not of type MdtPrepData " << m_idHelperSvc->toString(id));
539 continue;
540 }
541
542 const MuonSimData::Deposit* deposit = nullptr;
543 for (auto it = genPartList.begin(); it != genPartList.end() && !deposit; ++it) {
544 deposit = getDeposit(*mdtSimDataMap, *it, id);
545 }
546 if (!deposit) {
547 ATH_MSG_WARNING(" Deposit for GenParticle not found " << m_idHelperSvc->toString(id));
548 continue;
549 }
550
551 Amg::Vector2D lp(deposit->second.firstEntry(), deposit->second.secondEntry());
552 const Amg::Vector3D gpos = prd->detectorElement()->surface(id).localToGlobal(lp);
553
554 double val = isEndcap ? fabs(gpos.z()) : gpos.perp();
555
556 // nasty comparisons to figure out which MDT hit comes first
557 if (val < detLayer.minPos) {
558 if (detLayer.maxPos < -1e8 && detLayer.minPos < 1e8) {
559 detLayer.last3D = detLayer.first3D;
560 detLayer.maxPos = detLayer.minPos;
561 }
562 detLayer.first3D = gpos;
563 detLayer.minPos = val;
564 } else if (val > detLayer.maxPos) {
565 detLayer.last3D = gpos;
566 detLayer.maxPos = val;
567 }
568
569 if (val < minPos) {
570 if (maxPos < -1e8 && minPos < 1e8) {
571 last3D = first3D;
572 maxPos = minPos;
573 }
574 minPos = val;
575 first3D = gpos;
576 } else if (val > maxPos) {
577 maxPos = val;
578 last3D = gpos;
579 }
580
581 const Muon::MdtDriftCircleOnTrack* mdt = m_mdtCreator->createRIO_OnTrack(*mprd, gpos);
582 if (!mdt) {
583 ATH_MSG_WARNING(" ROT creation failed " << m_idHelperSvc->toString(id));
584 continue;
585 }
586 Trk::DriftCircleSide side = deposit->second.firstEntry() < 0 ? Trk::LEFT : Trk::RIGHT;
587 m_mdtCreator->updateSign(*const_cast<Muon::MdtDriftCircleOnTrack*>(mdt), side);
588 double pull = (mdt->driftRadius() - deposit->second.firstEntry()) / mdt->localCovariance()(Trk::locR);
589 ATH_MSG_VERBOSE(" new MDT " << m_idHelperSvc->toString(id) << " radius " << mdt->driftRadius() << " true radius "
590 << deposit->second.firstEntry() << " pull " << pull);
591 if (fabs(pull) > 3.) ATH_MSG_VERBOSE(" hit with large pull ");
592 detLayer.meas.push_back(mdt);
593 if (m_idHelperSvc->isSmallChamber(id))
594 ++detLayer.nmdtS;
595 else
596 ++detLayer.nmdtL;
597 // meas = mdt;
598 } else if (mm) {
599 const MuonSimData::Deposit* deposit = nullptr;
600 for (auto it = genPartList.begin(); it != genPartList.end() && !deposit; ++it) {
601 deposit = getDeposit(*mmSimDataMap, *it, id);
602 }
603 if (!deposit) {
604 ATH_MSG_WARNING(" Deposit for GenParticle not found " << m_idHelperSvc->toString(id));
605 continue;
606 }
607
608 Amg::Vector2D lp(deposit->second.firstEntry(), deposit->second.secondEntry());
609 const Amg::Vector3D gpos = prd->detectorElement()->surface(id).localToGlobal(lp);
610
611 // double val = isEndcap ? fabs(gpos->z()) : gpos->perp();
612 // micormegas are always endcap
613 double val = fabs(gpos.z());
614 // nasty comparisons to figure out which MDT hit comes first
615 if (val < detLayer.minPos) {
616 if (detLayer.maxPos < -1e8 && detLayer.minPos < 1e8) {
617 detLayer.last3D = detLayer.first3D;
618 detLayer.maxPos = detLayer.minPos;
619 }
620 detLayer.first3D = gpos;
621 detLayer.minPos = val;
622 } else if (val > detLayer.maxPos) {
623 detLayer.last3D = gpos;
624 detLayer.maxPos = val;
625 }
626
627 if (val < minPos) {
628 if (maxPos < -1e8 && detLayer.minPos < 1e8) {
629 last3D = first3D;
630 maxPos = minPos;
631 }
632 minPos = val;
633 first3D = gpos;
634 } else if (val > maxPos) {
635 maxPos = val;
636 last3D = gpos;
637 }
638
639 const Muon::MuonClusterOnTrack* rot = m_muonClusterCreator->createRIO_OnTrack(*mm, gpos);
640 if (!rot) {
641 ATH_MSG_WARNING(" ROT creation failed " << m_idHelperSvc->toString(id));
642 continue;
643 }
644 double residual = rot->localParameters().get(Trk::locX) - lp.x();
645 double pull = residual / rot->localCovariance()(Trk::locX);
646 ATH_MSG_DEBUG("Adding r " << gpos.perp() << " z " << gpos.z() << " " << m_idHelperSvc->toString(id) << " " << residual
647 << " pull " << pull);
648 detLayer.meas.push_back(rot);
649 // meas = rot;
650 ++detLayer.nnsw;
651
652 } else if (stgc) {
653 // skip pads in outer most two chambers as here the wires are more precise
654 if (m_idHelperSvc->stgcIdHelper().channelType(id) == 0 && abs(m_idHelperSvc->stationEta(id)) > 2) continue;
655
656 // there is already a check for this at the beginning of the method
657 // if( !stgcSimDataMap ) continue;
658
659 const MuonSimData::Deposit* deposit = nullptr;
660 for (auto it = genPartList.begin(); it != genPartList.end() && !deposit; ++it) {
661 deposit = getDeposit(*stgcSimDataMap, *it, id);
662 }
663 if (!deposit) {
664 ATH_MSG_WARNING(" Deposit for GenParticle not found " << m_idHelperSvc->toString(id));
665 continue;
666 }
667
668 Amg::Vector2D lp(deposit->second.firstEntry(), deposit->second.secondEntry());
669 const Amg::Vector3D gpos = prd->detectorElement()->surface(id).localToGlobal(lp);
670
671 // double val = isEndcap ? fabs(gpos->z()) : gpos->perp();
672 // stgcs are always endcap
673 double val = fabs(gpos.z());
674 // // nasty comparisons to figure out which STGC hit comes first
675 if (val < detLayer.minPos) {
676 if (detLayer.maxPos < -1e8 && detLayer.minPos < 1e8) {
677 detLayer.last3D = detLayer.first3D;
678 detLayer.maxPos = detLayer.minPos;
679 }
680 detLayer.first3D = gpos;
681 detLayer.minPos = val;
682 } else if (val > detLayer.maxPos) {
683 detLayer.last3D = gpos;
684 detLayer.maxPos = val;
685 }
686
687 if (val < minPos) {
688 if (maxPos < -1e8 && minPos < 1e8) {
689 last3D = first3D;
690 maxPos = minPos;
691 }
692 minPos = val;
693 first3D = gpos;
694 } else if (val > maxPos) {
695 maxPos = val;
696 last3D = gpos;
697 }
698
699 const Muon::MuonClusterOnTrack* rot = m_muonClusterCreator->createRIO_OnTrack(*stgc, gpos);
700 if (!rot) {
701 ATH_MSG_WARNING(" ROT creation failed " << m_idHelperSvc->toString(id));
702 continue;
703 }
704 double residual = rot->localParameters().get(Trk::locX) - lp.x();
705 double pull = residual / rot->localCovariance()(Trk::locX);
706 ATH_MSG_DEBUG("Adding r " << gpos.perp() << " z " << gpos.z() << " " << m_idHelperSvc->toString(id) << " " << residual
707 << " pull " << pull);
708 detLayer.meas.push_back(rot);
709 // meas = rot;
710 ++detLayer.nnsw;
711 }
712 }
713
714 // END NEW WORK
715 if (minPos == 2e8 || maxPos == 0) {
716 ATH_MSG_WARNING("Min and max positions not found. Filling with meaningless position");
717 return Amg::Vector3D(-15000, -15000, -15000);
718 }
719
720 if (truthPos)
721 return (first3D + last3D) / 2;
722 else {
723 // else truth direction
724 return (last3D - first3D);
725 }
726 }
727
728 //================================================================
729 void DetailedMuonPatternTruthBuilder::addDetailedTrackTruth(std::vector<DetailedTrackTruth>* output,
730 const Muon::MuonPatternCombination& pattern,
731 const std::vector<const PRD_MultiTruthCollection*>& orderedPRD_Truth,
732 const PRD_InverseTruth& inverseTruth) {
733 SubDetHitStatistics trackStat;
734 std::map<HepMcParticleLink, SubDetPRDs> pairStat; // stats for (track,GenParticle) for the current track
735
736 // Loop over MuonPatternChamberIntersect
737 const std::vector<Muon::MuonPatternChamberIntersect>& MPCIV = pattern.chamberData();
738 for (unsigned int i_MPCI = 0; i_MPCI < MPCIV.size(); i_MPCI++) {
739 if (MPCIV.empty()) continue;
740
741 // get the PrepRawData from the MuonPatternChamberIntersect
742 std::vector<const Trk::PrepRawData*> PRDV = MPCIV.at(i_MPCI).prepRawDataVec();
743
744 // Loop over the PRDV
745 for (unsigned int j_PRD = 0; j_PRD < PRDV.size(); j_PRD++) {
746 if (PRDV.empty()) continue;
747
748 Identifier id = PRDV.at(j_PRD)->identify();
750
752 // if PRD truth collection is missing, ignore subdet in track stat calculation as well.
753 if (orderedPRD_Truth[subdet]) {
754 ++trackStat[subdet];
755
756 typedef PRD_MultiTruthCollection::const_iterator iprdt;
757 std::pair<iprdt, iprdt> range = orderedPRD_Truth[subdet]->equal_range(id);
758
759 int n = 0;
760 // Loop over particles contributing to this cluster
761 for (iprdt i = range.first; i != range.second; ++i) {
762 if (!i->second.isValid()) {
763 ATH_MSG_WARNING("Unexpected invalid HepMcParticleLink in PRD_MultiTruthCollection");
764 } else {
765 pairStat[i->second].subDetHits[subdet].insert(id);
766 n += 1;
767 ATH_MSG_VERBOSE("PRD-ID:" << id << " subdet:" << subdet << " number:" << n
768 << " particle link:" << i->second);
769 }
770 }
771 if (n == 0) {
772 ATH_MSG_VERBOSE("--> no link, noise ? PRD-ID:" << id << " subdet:" << subdet);
773 // add uniqueID 0 to pairs, we like to keep track of fake fakes
774 unsigned int ID(0), EV(0);
775 pairStat[HepMcParticleLink(ID, EV, HepMcParticleLink::IS_POSITION, HepMcParticleLink::IS_ID)].subDetHits[subdet].insert(id);
776 }
777 } // orderedPRD_Truth[] available
778 } // subdet type check, warning in findSubDetType()
779 }
780 }
781
782 if (msgLvl(MSG::VERBOSE)) {
783 msg(MSG::VERBOSE) << "PRD truth particles = ";
784 for (std::map<HepMcParticleLink, SubDetPRDs>::const_iterator i = pairStat.begin(); i != pairStat.end(); ++i) {
785 msg(MSG::VERBOSE) << i->first << ",";
786 }
787 msg(MSG::VERBOSE) << endmsg;
788 }
789
790 //----------------------------------------------------------------
791 // The stat structures are ready.
792 // Build truth trajectories for the track
793
794 std::set<HepMcParticleLink> seeds;
795 for (std::map<HepMcParticleLink, SubDetPRDs>::const_iterator i = pairStat.begin(); i != pairStat.end(); ++i) {
796 if (i->first.isValid()) {
797 seeds.insert(i->first);
798 } else {
799 // add uniqueID 0 particles, we like to keep track of fake fakes
800 TruthTrajectory traj;
801 traj.reserve(1);
802 traj.push_back(i->first);
803 ATH_MSG_VERBOSE("addTrack(): add barcode 0 hits - noise ?");
804
805 // noise/no truth hits on this track
806 SubDetHitStatistics noiseStat = makeSubDetHitStatistics(i->second);
807
808 // Only valid HepMcParticleLink make it into seeds and then into sprouts, and
809 // stored in the loop over sprouts below.
810 // Store output for noise/no truth particles here.
811 output->push_back(DetailedTrackTruth(traj, noiseStat, trackStat, noiseStat));
812 }
813 }
814
815 // Grow sprouts from the seeds
816 typedef std::map<HepMcParticleLink, Sprout> SproutMap;
817 SproutMap sprouts;
818
819 while (!seeds.empty()) {
820 HepMcParticleLink link = *seeds.begin();
821
822 Sprout current_sprout;
823 std::queue<HepMC::ConstGenParticlePtr> tmp;
824 unsigned eventIndex = link.eventIndex();
825#ifdef HEPMC3
826 HepMC::ConstGenParticlePtr current = link.scptr();
827#else
828 const HepMC::GenParticle* current = link.cptr();
829#endif
830
831 do {
833
834 // remove the current particle from the list of particles to consider (if it is still there)
835 seeds.erase(curlink);
836
837 // Have we worked on this particle before?
838 SproutMap::iterator p_old = sprouts.find(curlink);
839 if (p_old != sprouts.end()) {
840 // merge the old sprout with the current one.
841 current_sprout.splice(current_sprout.end(), p_old->second);
842 current_sprout.stat += p_old->second.stat;
843 // and remove the entry for the old
844 sprouts.erase(p_old);
845 break; // the do-while(getMother()) loop
846 } else { // No, this is a new particle. Try to extend the current truth trajectory.
847
848 // Add the particle to the current truth trajectory.
849 // New: with the current stricter cuts on mother-daughter
850 // we don't have to require that ancestors produce hits.
851
852 current_sprout.push_back(current);
853
854 std::map<HepMcParticleLink, SubDetPRDs>::iterator p_newstat = pairStat.find(curlink);
855 if (p_newstat != pairStat.end()) { current_sprout.stat += p_newstat->second; }
856 }
857 } while ((current = m_truthTrackBuilder->getMother(current)));
858
859 // Add the grown sprout to the list
860 sprouts.insert(std::make_pair(link, current_sprout));
861
862 } // while(!seeds.empty())
863
864 //----------------
865 // All seeds have been processed, and the upstream extensions of the
866 // sprouts are done. Extend the sprouts downstream to get the final
867 // truth trajectories and store the result.
868 //
869 // Note: so far the "sprouts" object mapped {last particle ==> sprout}
870 // Extending a sprout downstream will break this relationship,
871 // but at this point we don't care about it and will only use the
872 // value of the map, not the key.
873 for (SproutMap::iterator s = sprouts.begin(); s != sprouts.end(); ++s) {
874 // Attempt to extend the TruthTrajectory sprout to the "outside".
875 // This may add only hits that are *not* on the current track.
876 // Thus no need to update stats track and stats common.
877
878 HepMC::ConstGenParticlePtr current = *s->second.begin();
879 while ((current = m_truthTrackBuilder->getDaughter(current))) { s->second.push_front(current); }
880
881 // Now we have info to build the final TruthTrajectory.
882 // FIXME: what is the current average size?
883 TruthTrajectory traj;
884 traj.reserve(2); // The average size is about 1.05. Hardcode that instead of using slow list::size().
885 for (Sprout::const_iterator ppart = s->second.begin(); ppart != s->second.end(); ++ppart) {
886 traj.push_back(HepMcParticleLink(HepMC::uniqueID(*ppart), s->first.eventIndex(), HepMcParticleLink::IS_EVENTNUM, HepMcParticleLink::IS_ID));
887 }
888
889 // Count PRDs on the TruthTrajectory
890 std::set<Muon::MuonStationIndex::ChIndex> tempSet;
891 SubDetHitStatistics truthStat = countPRDsOnTruth(traj, inverseTruth, tempSet);
892
893 ATH_MSG_VERBOSE("addTrack(): sprout length = " << traj.size());
894 output->push_back(DetailedTrackTruth(traj, makeSubDetHitStatistics(s->second.stat), trackStat, truthStat));
895 }
896
897 ATH_MSG_VERBOSE("addTrack(): #sprouts = " << sprouts.size() << ", output->size() = " << output->size());
898 }
899
901 std::vector<DetailedSegmentTruth>* output, const Muon::MuonSegment& segment,
902 const std::vector<const PRD_MultiTruthCollection*>& prdTruth) {
903 ATH_MSG_VERBOSE("DetailedMuonPatternTruthBuilder::buildDetailedTrackTruthFromSegments() ");
904
905 if (!output) { return; }
906
907 //----------------------------------------------------------------
908 // The caller can pass PRD truth collections in any order. Sort them out.
909
910 std::vector<const PRD_MultiTruthCollection*> orderedPRD_Truth(SubDetHitStatistics::NUM_SUBDETECTORS);
911 PRD_InverseTruth inverseTruth;
912
913 for (std::vector<const PRD_MultiTruthCollection*>::const_iterator i = prdTruth.begin(); i != prdTruth.end(); ++i) {
914 if (*i) {
915 if (!(*i)->empty()) {
916 SubDetHitStatistics::SubDetType subdet = findSubDetType((*i)->begin()->first);
917
919 orderedPRD_Truth[subdet] = *i;
920 addToInverseMultiMap(&inverseTruth, **i);
921 } else {
922 ATH_MSG_WARNING("Got unknown SubDetType in prdTruth ");
923 }
924 } else {
925 ATH_MSG_DEBUG("Empty truth ???");
926 }
927 }
928 }
929
930 //----------------------------------------------------------------
931 // Find associated truth for each track
932 addDetailedTrackTruthFromSegment(output, segment, orderedPRD_Truth, inverseTruth);
933
934 // DEBUG
935 // FIXME: in normal production jobs that does *a lot of* formatting only to discard the result...
937 "Dumping output collection.\n"
938 " Entries with TruthTrajectories of more then one particle shown at the DEBUG level.\n"
939 " Use VERBOSE level for complete dump.");
940 }
941
942 //================================================================
944 std::vector<DetailedSegmentTruth>* output, const Muon::MuonSegment& segment,
945 const std::vector<const PRD_MultiTruthCollection*>& orderedPRD_Truth, const PRD_InverseTruth& inverseTruth) {
946 SubDetHitStatistics trackStat;
947 std::map<HepMcParticleLink, SubDetPRDs> pairStat; // stats for (track,GenParticle) for the current track
948
949 std::set<Muon::MuonStationIndex::ChIndex> chIndices;
950
951 // Loop over containedROTs in segment
952 for (unsigned int i_cROTv = 0; i_cROTv < segment.numberOfContainedROTs(); i_cROTv++) {
953 const Trk::RIO_OnTrack* rot = segment.rioOnTrack(i_cROTv);
954
955 // get the PrepRawData from the ROT
956 const Trk::PrepRawData* prd = rot->prepRawData();
957
958 Identifier id = prd->identify();
959 chIndices.insert(m_idHelperSvc->chamberIndex(id));
960
962
964 // if PRD truth collection is missing, ignore subdet in track stat calculation as well.
965 if (orderedPRD_Truth[subdet]) {
966 ++trackStat[subdet];
967
968 typedef PRD_MultiTruthCollection::const_iterator iprdt;
969 std::pair<iprdt, iprdt> range = orderedPRD_Truth[subdet]->equal_range(id);
970
971 int n = 0;
972 // Loop over particles contributing to this cluster
973 for (iprdt i = range.first; i != range.second; ++i) {
974 if (!i->second.isValid()) {
975 ATH_MSG_WARNING("Unexpected invalid HepMcParticleLink in PRD_MultiTruthCollection");
976 } else {
977 pairStat[i->second].subDetHits[subdet].insert(id);
978 n += 1;
979 ATH_MSG_VERBOSE("PRD-ID:" << id << " subdet:" << subdet << " number:" << n << " particle link:" << i->second);
980 }
981 }
982 if (n == 0) {
983 ATH_MSG_VERBOSE("--> no link, noise ? PRD-ID:" << id << " subdet:" << subdet);
984 // add uniqueID 0 to pairs, we like to keep track of fake fakes
985 unsigned int ID(0), EV(0);
986 pairStat[HepMcParticleLink(ID, EV, HepMcParticleLink::IS_POSITION, HepMcParticleLink::IS_ID)].subDetHits[subdet].insert(id);
987 }
988 } // orderedPRD_Truth[] available
989 } // subdet type check, warning in findSubDetType()
990 }
991
992 if (msgLvl(MSG::VERBOSE)) {
993 msg(MSG::VERBOSE) << "PRD truth particles = ";
994 for (std::map<HepMcParticleLink, SubDetPRDs>::const_iterator i = pairStat.begin(); i != pairStat.end(); ++i) {
995 msg(MSG::VERBOSE) << i->first << ",";
996 }
997 msg(MSG::VERBOSE) << endmsg;
998 }
999
1000 //----------------------------------------------------------------
1001 // The stat structures are ready.
1002 // Build truth trajectories for the track
1003
1004 std::set<HepMcParticleLink> seeds;
1005 for (std::map<HepMcParticleLink, SubDetPRDs>::const_iterator i = pairStat.begin(); i != pairStat.end(); ++i) {
1006 if (i->first.isValid()) {
1007 seeds.insert(i->first);
1008 } else {
1009 // add uniqueID 0 particles, we like to keep track of fake fakes
1010 TruthTrajectory traj;
1011 traj.reserve(1);
1012 traj.push_back(i->first);
1013 ATH_MSG_VERBOSE("addTrack(): add barcode 0 hits - noise ?");
1014
1015 // noise/no truth hits on this track
1016 SubDetHitStatistics noiseStat = makeSubDetHitStatistics(i->second);
1017
1018 // Only valid HepMcParticleLink make it into seeds and then into sprouts, and
1019 // stored in the loop over sprouts below.
1020 // Store output for noise/no truth particles here.
1021 output->push_back(
1022 DetailedSegmentTruth(traj, noiseStat, trackStat, noiseStat, Amg::Vector3D(0, 0, 0), Amg::Vector3D(0, 0, 0)));
1023 }
1024 }
1025
1026 // Grow sprouts from the seeds
1027 typedef std::map<HepMcParticleLink, Sprout> SproutMap;
1028 SproutMap sprouts;
1029
1030 while (!seeds.empty()) {
1031 HepMcParticleLink link = *seeds.begin();
1032
1033 Sprout current_sprout;
1034 std::queue<HepMC::ConstGenParticlePtr> tmp;
1035 unsigned eventIndex = link.eventIndex();
1036#ifdef HEPMC3
1037 HepMC::ConstGenParticlePtr current = link.scptr();
1038#else
1039 const HepMC::GenParticle* current = link.cptr();
1040#endif
1041
1042 do {
1044
1045 // remove the current particle from the list of particles to consider (if it is still there)
1046 seeds.erase(curlink);
1047
1048 // Have we worked on this particle before?
1049 SproutMap::iterator p_old = sprouts.find(curlink);
1050 if (p_old != sprouts.end()) {
1051 // merge the old sprout with the current one.
1052 current_sprout.splice(current_sprout.end(), p_old->second);
1053 current_sprout.stat += p_old->second.stat;
1054 // and remove the entry for the old
1055 sprouts.erase(p_old);
1056 break; // the do-while(getMother()) loop
1057 } else { // No, this is a new particle. Try to extend the current truth trajectory.
1058
1059 // Add the particle to the current truth trajectory.
1060 // New: with the current stricter cuts on mother-daughter
1061 // we don't have to require that ancestors produce hits.
1062
1063 current_sprout.push_back(current);
1064
1065 std::map<HepMcParticleLink, SubDetPRDs>::iterator p_newstat = pairStat.find(curlink);
1066 if (p_newstat != pairStat.end()) { current_sprout.stat += p_newstat->second; }
1067 }
1068 } while ((current = m_truthTrackBuilder->getMother(current)));
1069
1070 // Add the grown sprout to the list
1071 sprouts.insert(std::make_pair(link, current_sprout));
1072
1073 } // while(!seeds.empty())
1074
1075 //----------------
1076 // All seeds have been processed, and the upstream extensions of the
1077 // sprouts are done. Extend the sprouts downstream to get the final
1078 // truth trajectories and store the result.
1079 //
1080 // Note: so far the "sprouts" object mapped {last particle ==> sprout}
1081 // Extending a sprout downstream will break this relationship,
1082 // but at this point we don't care about it and will only use the
1083 // value of the map, not the key.
1084 for (SproutMap::iterator s = sprouts.begin(); s != sprouts.end(); ++s) {
1085 // Attempt to extend the TruthTrajectory sprout to the "outside".
1086 // This may add only hits that are *not* on the current track.
1087 // Thus no need to update stats track and stats common.
1088
1089 HepMC::ConstGenParticlePtr current = *s->second.begin();
1090 while ((current = m_truthTrackBuilder->getDaughter(current))) { s->second.push_front(current); }
1091
1092 // Now we have info to build the final TruthTrajectory.
1093 // FIXME: what is the current average size?
1094 TruthTrajectory traj;
1095 traj.reserve(2); // The average size is about 1.05. Hardcode that instead of using slow list::size().
1096 for (Sprout::const_iterator ppart = s->second.begin(); ppart != s->second.end(); ++ppart) {
1097 traj.push_back(HepMcParticleLink(HepMC::uniqueID(*ppart), s->first.eventIndex(), HepMcParticleLink::IS_EVENTNUM, HepMcParticleLink::IS_ID));
1098 }
1099
1100 // Count PRDs on the TruthTrajectory
1101 SubDetHitStatistics truthStat = countPRDsOnTruth(traj, inverseTruth, chIndices);
1102 Amg::Vector3D pos = getPRDTruthPosition(segment, s->second, 1, chIndices);
1103 Amg::Vector3D dir = getPRDTruthPosition(segment, s->second, 0, chIndices);
1104
1105 ATH_MSG_VERBOSE("addTrack(): sprout length = " << traj.size());
1106 output->push_back(DetailedSegmentTruth(traj, makeSubDetHitStatistics(s->second.stat), trackStat, truthStat, pos, dir));
1107 }
1108
1109 ATH_MSG_VERBOSE("addTrack(): #sprouts = " << sprouts.size() << ", output->size() = " << output->size());
1110 }
1111
1112 // AV Note: MuonSimData::Deposit typedef std::pair<HepMcParticleLink, MuonMCData> Deposit;
1114 const HepMC::ConstGenParticlePtr& genPart, const Identifier& id) {
1115 MuonSimDataCollection::const_iterator it = simCol.find(id);
1116 if (it == simCol.end()) {
1117 ATH_MSG_WARNING(" Truth PRD not found in simdata collection: " << m_idHelperSvc->toString(id));
1118 return nullptr;
1119 }
1120
1121 const MuonSimData& simData = it->second;
1122 const MuonSimData::Deposit* deposit = nullptr;
1123 std::vector<MuonSimData::Deposit>::const_iterator dit = simData.getdeposits().begin();
1124 std::vector<MuonSimData::Deposit>::const_iterator dit_end = simData.getdeposits().end();
1125 for (; dit != dit_end; ++dit) {
1126#ifdef HEPMC3
1127 HepMC::ConstGenParticlePtr gp = dit->first.scptr();
1128#else
1129 const HepMC::GenParticle* gp = dit->first;
1130#endif
1131 if (gp == genPart) {
1132 deposit = &*dit;
1133 break;
1134 }
1135
1136 }
1137 return deposit;
1138 }
1139
1141 // Retrieve SDO map for this event
1142 if (!evtStore()->contains<MuonSimDataCollection>(colName)) return nullptr;
1143
1144 const MuonSimDataCollection* truthCol(nullptr);
1145 if (!evtStore()->retrieve(truthCol, colName).isSuccess()) {
1146 ATH_MSG_VERBOSE("Could NOT find the MuonSimDataMap map key = " << colName);
1147 } else {
1148 ATH_MSG_VERBOSE("Retrieved MuonSimDataCollection for key = " << colName);
1149 }
1150 return truthCol;
1151 }
1152
1153} // namespace Trk
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
An STL vector of pointers that by default owns its pointed-to elements.
std::pair< std::vector< unsigned int >, bool > res
static Double_t a
DataVector< Muon::MuonPatternCombination > MuonPatternCombinationCollection
This typedef represents a collection of MuonPatternCombination objects.
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
ServiceHandle< StoreGateSvc > & evtStore()
bool msgLvl(const MSG::Level lvl) const
MsgStream & msg() const
Derived DataVector<T>.
Definition DataVector.h:795
std::pair< HepMcParticleLink, MuonMCData > Deposit
Definition MuonSimData.h:66
Class to represent MM measurements.
Definition MMPrepData.h:22
This class represents the corrected MDT measurements, where the corrections include the effects of wi...
double driftRadius() const
Returns the value of the drift radius.
Class to represent measurements from the Monitored Drift Tubes.
Definition MdtPrepData.h:33
Base class for Muon cluster RIO_OnTracks.
The MuonPatternCombination class provides the means to store the output of the initial global pattern...
This is the common class for 3D segments used in the muon spectrometer.
const Trk::RIO_OnTrack * rioOnTrack(unsigned int) const
returns the RIO_OnTrack (also known as ROT) objects depending on the integer
Class to represent sTgc measurements.
virtual void buildDetailedMuonPatternTruth(DetailedMuonPatternTruthCollection *output, const MuonPatternCombinationCollection &tracks, const std::vector< const PRD_MultiTruthCollection * > &prdTruth)
See description for IDetailedMuonPatternTruthBuilder::buildDetailedTrackTruth()
InverseMultiMap< PRD_MultiTruthCollection > PRD_InverseTruth
const MuonSimDataCollection * retrieveTruthCollection(const std::string &colName)
SubDetHitStatistics::SubDetType findSubDetType(Identifier id)
void addDetailedTrackTruth(std::vector< DetailedTrackTruth > *output, const Muon::MuonPatternCombination &pattern, const std::vector< const PRD_MultiTruthCollection * > &orderedPRD_Truth, const PRD_InverseTruth &inverseTruth)
Amg::Vector3D getPRDTruthPosition(const Muon::MuonSegment &segment, std::list< HepMC::ConstGenParticlePtr > genPartList, int truthPos, std::set< Muon::MuonStationIndex::ChIndex > chIndices)
void addTrack(DetailedMuonPatternTruthCollection *output, const ElementLink< DataVector< Muon::MuonPatternCombination > > &track, const std::vector< const PRD_MultiTruthCollection * > &orderedPRD_Truth, const PRD_InverseTruth &inverseTruth)
void buildDetailedTrackTruthFromSegments(std::vector< DetailedSegmentTruth > *output, const Muon::MuonSegment &segment, const std::vector< const PRD_MultiTruthCollection * > &prdTruth)
ToolHandle< Muon::IMuonClusterOnTrackCreator > m_muonClusterCreator
SubDetHitStatistics countPRDsOnTruth(const TruthTrajectory &traj, const PRD_InverseTruth &inverseTruth, std::set< Muon::MuonStationIndex::ChIndex > chIndices)
ToolHandle< Trk::ITruthTrajectoryBuilder > m_truthTrackBuilder
void addDetailedTrackTruthFromSegment(std::vector< DetailedSegmentTruth > *output, const Muon::MuonSegment &segment, const std::vector< const PRD_MultiTruthCollection * > &orderedPRD_Truth, const PRD_InverseTruth &inverseTruth)
DetailedMuonPatternTruthBuilder(const std::string &type, const std::string &name, const IInterface *parent)
virtual void buildDetailedTrackTruth(std::vector< DetailedTrackTruth > *output, const Muon::MuonPatternCombination &pattern, const std::vector< const PRD_MultiTruthCollection * > &prdTruth)
ToolHandle< Muon::IMdtDriftCircleOnTrackCreator > m_mdtCreator
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
const MuonSimData::Deposit * getDeposit(const MuonSimDataCollection &simCol, const HepMC::ConstGenParticlePtr &genPart, const Identifier &id)
double get(ParamDefs par) const
Retrieve specified parameter (const version).
const LocalParameters & localParameters() const
Interface method to get the LocalParameters.
const Amg::MatrixX & localCovariance() const
Interface method to get the localError.
virtual const TrkDetElementBase * detectorElement() const =0
return the detector element corresponding to this PRD The pointer will be zero if the det el is not d...
Identifier identify() const
return the identifier
Class to handle RIO On Tracks ROT) for InDet and Muons, it inherits from the common MeasurementBase.
Definition RIO_OnTrack.h:70
virtual const Trk::PrepRawData * prepRawData() const =0
returns the PrepRawData (also known as RIO) object to which this RIO_OnTrack is associated.
virtual void localToGlobal(const Amg::Vector2D &locp, const Amg::Vector3D &mom, Amg::Vector3D &glob) const =0
Specified by each surface type: LocalToGlobal method without dynamic memory allocation.
virtual const Surface & surface() const =0
Return surface associated with this detector element.
A TruthTrajectory is a chain of charged MC particles connected through the mother-daughter relationsh...
constexpr bool simData
Definition constants.h:36
bool contains(const std::string &s, const std::string &regx)
does a string contain the substring
Definition hcg.cxx:114
std::vector< std::string > patterns
Definition listroot.cxx:187
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
int uniqueID(const T &p)
const GenParticle * ConstGenParticlePtr
Definition GenParticle.h:38
StIndex
enum to classify the different station layers in the muon spectrometer
Ensure that the ATLAS eigen extensions are properly loaded.
DriftCircleSide
Enumerates the 'side' of the wire on which the tracks passed (i.e.
@ RIGHT
the drift radius is positive (see Trk::AtaStraightLine)
@ LEFT
the drift radius is negative (see Trk::AtaStraightLine)
void addToInverseMultiMap(InverseMultiMap< OrigMap, CmpT > *result, const OrigMap &rec2truth)
@ locX
Definition ParamDefs.h:37
@ locR
Definition ParamDefs.h:44
DetectorLayer()=default
std::vector< const Trk::MeasurementBase * > meas
Muon::MuonStationIndex::StIndex stIndex