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 HepMC::ConstGenParticlePtr current = link.scptr();
366 do {
368
369 // remove the current particle from the list of particles to consider (if it is still there)
370 seeds.erase(curlink);
371
372 // Have we worked on this particle before?
373 SproutMap::iterator p_old = sprouts.find(curlink);
374 if (p_old != sprouts.end()) {
375 // merge the old sprout with the current one.
376 current_sprout.splice(current_sprout.end(), p_old->second);
377 current_sprout.stat += p_old->second.stat;
378 // and remove the entry for the old
379 sprouts.erase(p_old);
380 break; // the do-while(getMother()) loop
381 } else { // No, this is a new particle. Try to extend the current truth trajectory.
382
383 // Add the particle to the current truth trajectory.
384 // New: with the current stricter cuts on mother-daughter
385 // we don't have to require that ancestors produce hits.
386
387 current_sprout.push_back(current);
388
389 std::map<HepMcParticleLink, SubDetPRDs>::iterator p_newstat = pairStat.find(curlink);
390 if (p_newstat != pairStat.end()) { current_sprout.stat += p_newstat->second; }
391 }
392 } while ((current = m_truthTrackBuilder->getMother(current)));
393
394 // Add the grown sprout to the list
395 sprouts.insert(std::make_pair(link, current_sprout));
396
397 } // while(!seeds.empty())
398
399 //----------------
400 // All seeds have been processed, and the upstream extensions of the
401 // sprouts are done. Extend the sprouts downstream to get the final
402 // truth trajectories and store the result.
403 //
404 // Note: so far the "sprouts" object mapped {last particle ==> sprout}
405 // Extending a sprout downstream will break this relationship,
406 // but at this point we don't care about it and will only use the
407 // value of the map, not the key.
408
409 for (SproutMap::iterator s = sprouts.begin(); s != sprouts.end(); ++s) {
410 // Attempt to extend the TruthTrajectory sprout to the "outside".
411 // This may add only hits that are *not* on the current track.
412 // Thus no need to update stats track and stats common.
413
414 HepMC::ConstGenParticlePtr current = *s->second.begin();
415 while ((current = m_truthTrackBuilder->getDaughter(current))) { s->second.push_front(current); }
416
417 // Now we have info to build the final TruthTrajectory.
418 // FIXME: what is the current average size?
419 TruthTrajectory traj;
420 traj.reserve(2); // The average size is about 1.05. Hardcode that instead of using slow list::size().
421 for (Sprout::const_iterator ppart = s->second.begin(); ppart != s->second.end(); ++ppart) {
422 traj.push_back(HepMcParticleLink(HepMC::uniqueID(*ppart), s->first.eventIndex(), HepMcParticleLink::IS_EVENTNUM, HepMcParticleLink::IS_ID));
423 }
424
425 // Count PRDs on the TruthTrajectory
426 std::set<Muon::MuonStationIndex::ChIndex> tempSet;
427 SubDetHitStatistics truthStat = countPRDsOnTruth(traj, inverseTruth, tempSet);
428
429 ATH_MSG_VERBOSE("addTrack(): sprout length = " << traj.size());
430 output->insert(
431 std::make_pair(MuPatternCombo, DetailedTrackTruth(traj, makeSubDetHitStatistics(s->second.stat), trackStat, truthStat)));
432 }
433
434 ATH_MSG_VERBOSE("addTrack(): #sprouts = " << sprouts.size() << ", output->size() = " << output->size());
435 }
436
437 //================================================================
439 std::set<Muon::MuonStationIndex::ChIndex> chIndices) {
440 // Different particles from the same TruthTrajectory can contribute to the same cluster.
441 // We should be careful to avoid double-counting in such cases.
442
443 SubDetPRDs prds;
444 for (TruthTrajectory::const_iterator p = traj.begin(); p != traj.end(); ++p) {
445 typedef PRD_InverseTruth::const_iterator iter;
446 std::pair<iter, iter> range = inverseTruth.equal_range(*p);
447 for (iter i = range.first; i != range.second; ++i) {
448 if (chIndices.find(m_idHelperSvc->chamberIndex(i->second)) != chIndices.end()) {
450 if (subdet == SubDetHitStatistics::NUM_SUBDETECTORS) continue;
451 prds.subDetHits[subdet].insert(i->second);
452 }
453 }
454 }
455
456 return makeSubDetHitStatistics(prds);
457 }
458
459 //================================================================
461 std::list<HepMC::ConstGenParticlePtr> genPartList, int truthPos,
462 std::set<Muon::MuonStationIndex::ChIndex> chIndices) {
463 double minPos = 2e8, maxPos = 0;
464 Amg::Vector3D first3D(0, 0, 0), last3D(0, 0, 0);
465
466 if (genPartList.empty()) {
467 ATH_MSG_WARNING("No GenParticles associated to this PRD_TruthTrajectory. Exiting segment creation.");
468 return Amg::Vector3D(0, 0, 0);
469 }
470
471 const MuonSimDataCollection* mdtSimDataMap = retrieveTruthCollection("MDT_SDO");
472 if (!mdtSimDataMap) {
473 ATH_MSG_WARNING(" failed to retrieve MuonSimDataCollection: "
474 << "MDT_SDO");
475 return Amg::Vector3D(0, 0, 0);
476 }
477 const MuonSimDataCollection* mmSimDataMap = retrieveTruthCollection("MM_SDO");
478 if (!mmSimDataMap) {
479 ATH_MSG_WARNING(" failed to retrieve MuonSimDataCollection: "
480 << "MM_SDO");
481 return Amg::Vector3D(0, 0, 0);
482 }
483 const MuonSimDataCollection* stgcSimDataMap = retrieveTruthCollection("sTGC_SDO");
484 if (!stgcSimDataMap) {
485 ATH_MSG_WARNING(" failed to retrieve MuonSimDataCollection: "
486 << "sTGC_SDO");
487 return Amg::Vector3D(0, 0, 0);
488 }
489
490 // First sort the hits per detector layer
491 std::map<Muon::MuonStationIndex::StIndex, DetectorLayer> hitsPerLayer;
492 std::map<const Trk::TrkDetElementBase*, std::pair<std::list<const Trk::PrepRawData*>, std::list<const Trk::PrepRawData*> > >
493 clustersPerDetEl;
494
495 // Loop over containedROTs in segment
496 for (unsigned int i_cROTv = 0; i_cROTv < segment.numberOfContainedROTs(); i_cROTv++) {
497 const Trk::RIO_OnTrack* rot = segment.rioOnTrack(i_cROTv);
498
499 // get the PrepRawData from the ROT
500 const Trk::PrepRawData* prd = rot->prepRawData();
501
502 Identifier id = prd->identify();
503
504 Muon::MuonStationIndex::StIndex stIndex = m_idHelperSvc->stationIndex(id);
505 bool isEndcap = m_idHelperSvc->isEndcap(id);
506
507 if (chIndices.find(m_idHelperSvc->chamberIndex(id)) == chIndices.end()) {
508 ATH_MSG_DEBUG("Muon station doesn't match segment. Continuing");
509 continue;
510 }
511
512 // some patches until MuonIdHelper is updated
513 const Muon::MMPrepData* mm = dynamic_cast<const Muon::MMPrepData*>(prd);
514 if (mm) {
515 isEndcap = true;
516 stIndex = Muon::MuonStationIndex::StIndex::EI;
517 }
518 const Muon::sTgcPrepData* stgc = dynamic_cast<const Muon::sTgcPrepData*>(prd);
519 if (stgc) {
520 isEndcap = true;
521 stIndex = Muon::MuonStationIndex::StIndex::EI;
522 }
523 // BEGIN NEW WORK
524
525 DetectorLayer& detLayer = hitsPerLayer[stIndex];
526 detLayer.isEndcap = isEndcap;
527 detLayer.stIndex = stIndex;
528
529 // const Trk::MeasurementBase* meas = 0;
530 if (m_idHelperSvc->isMdt(id)) {
531 const Muon::MdtPrepData* mprd = dynamic_cast<const Muon::MdtPrepData*>(prd);
532 if (!mprd) {
533 ATH_MSG_WARNING(" MDT PRD not of type MdtPrepData " << m_idHelperSvc->toString(id));
534 continue;
535 }
536
537 const MuonSimData::Deposit* deposit = nullptr;
538 for (auto it = genPartList.begin(); it != genPartList.end() && !deposit; ++it) {
539 deposit = getDeposit(*mdtSimDataMap, *it, id);
540 }
541 if (!deposit) {
542 ATH_MSG_WARNING(" Deposit for GenParticle not found " << m_idHelperSvc->toString(id));
543 continue;
544 }
545
546 Amg::Vector2D lp(deposit->second.firstEntry(), deposit->second.secondEntry());
547 const Amg::Vector3D gpos = prd->detectorElement()->surface(id).localToGlobal(lp);
548
549 double val = isEndcap ? fabs(gpos.z()) : gpos.perp();
550
551 // nasty comparisons to figure out which MDT hit comes first
552 if (val < detLayer.minPos) {
553 if (detLayer.maxPos < -1e8 && detLayer.minPos < 1e8) {
554 detLayer.last3D = detLayer.first3D;
555 detLayer.maxPos = detLayer.minPos;
556 }
557 detLayer.first3D = gpos;
558 detLayer.minPos = val;
559 } else if (val > detLayer.maxPos) {
560 detLayer.last3D = gpos;
561 detLayer.maxPos = val;
562 }
563
564 if (val < minPos) {
565 if (maxPos < -1e8 && minPos < 1e8) {
566 last3D = first3D;
567 maxPos = minPos;
568 }
569 minPos = val;
570 first3D = gpos;
571 } else if (val > maxPos) {
572 maxPos = val;
573 last3D = gpos;
574 }
575
576 const Muon::MdtDriftCircleOnTrack* mdt = m_mdtCreator->createRIO_OnTrack(*mprd, gpos);
577 if (!mdt) {
578 ATH_MSG_WARNING(" ROT creation failed " << m_idHelperSvc->toString(id));
579 continue;
580 }
581 Trk::DriftCircleSide side = deposit->second.firstEntry() < 0 ? Trk::LEFT : Trk::RIGHT;
582 m_mdtCreator->updateSign(*const_cast<Muon::MdtDriftCircleOnTrack*>(mdt), side);
583 double pull = (mdt->driftRadius() - deposit->second.firstEntry()) / mdt->localCovariance()(Trk::locR);
584 ATH_MSG_VERBOSE(" new MDT " << m_idHelperSvc->toString(id) << " radius " << mdt->driftRadius() << " true radius "
585 << deposit->second.firstEntry() << " pull " << pull);
586 if (fabs(pull) > 3.) ATH_MSG_VERBOSE(" hit with large pull ");
587 detLayer.meas.push_back(mdt);
588 if (m_idHelperSvc->isSmallChamber(id))
589 ++detLayer.nmdtS;
590 else
591 ++detLayer.nmdtL;
592 // meas = mdt;
593 } else if (mm) {
594 const MuonSimData::Deposit* deposit = nullptr;
595 for (auto it = genPartList.begin(); it != genPartList.end() && !deposit; ++it) {
596 deposit = getDeposit(*mmSimDataMap, *it, id);
597 }
598 if (!deposit) {
599 ATH_MSG_WARNING(" Deposit for GenParticle not found " << m_idHelperSvc->toString(id));
600 continue;
601 }
602
603 Amg::Vector2D lp(deposit->second.firstEntry(), deposit->second.secondEntry());
604 const Amg::Vector3D gpos = prd->detectorElement()->surface(id).localToGlobal(lp);
605
606 // double val = isEndcap ? fabs(gpos->z()) : gpos->perp();
607 // micormegas are always endcap
608 double val = fabs(gpos.z());
609 // nasty comparisons to figure out which MDT hit comes first
610 if (val < detLayer.minPos) {
611 if (detLayer.maxPos < -1e8 && detLayer.minPos < 1e8) {
612 detLayer.last3D = detLayer.first3D;
613 detLayer.maxPos = detLayer.minPos;
614 }
615 detLayer.first3D = gpos;
616 detLayer.minPos = val;
617 } else if (val > detLayer.maxPos) {
618 detLayer.last3D = gpos;
619 detLayer.maxPos = val;
620 }
621
622 if (val < minPos) {
623 if (maxPos < -1e8 && detLayer.minPos < 1e8) {
624 last3D = first3D;
625 maxPos = minPos;
626 }
627 minPos = val;
628 first3D = gpos;
629 } else if (val > maxPos) {
630 maxPos = val;
631 last3D = gpos;
632 }
633
634 const Muon::MuonClusterOnTrack* rot = m_muonClusterCreator->createRIO_OnTrack(*mm, gpos);
635 if (!rot) {
636 ATH_MSG_WARNING(" ROT creation failed " << m_idHelperSvc->toString(id));
637 continue;
638 }
639 double residual = rot->localParameters().get(Trk::locX) - lp.x();
640 double pull = residual / rot->localCovariance()(Trk::locX);
641 ATH_MSG_DEBUG("Adding r " << gpos.perp() << " z " << gpos.z() << " " << m_idHelperSvc->toString(id) << " " << residual
642 << " pull " << pull);
643 detLayer.meas.push_back(rot);
644 // meas = rot;
645 ++detLayer.nnsw;
646
647 } else if (stgc) {
648 // skip pads in outer most two chambers as here the wires are more precise
649 if (m_idHelperSvc->stgcIdHelper().channelType(id) == 0 && abs(m_idHelperSvc->stationEta(id)) > 2) continue;
650
651 // there is already a check for this at the beginning of the method
652 // if( !stgcSimDataMap ) continue;
653
654 const MuonSimData::Deposit* deposit = nullptr;
655 for (auto it = genPartList.begin(); it != genPartList.end() && !deposit; ++it) {
656 deposit = getDeposit(*stgcSimDataMap, *it, id);
657 }
658 if (!deposit) {
659 ATH_MSG_WARNING(" Deposit for GenParticle not found " << m_idHelperSvc->toString(id));
660 continue;
661 }
662
663 Amg::Vector2D lp(deposit->second.firstEntry(), deposit->second.secondEntry());
664 const Amg::Vector3D gpos = prd->detectorElement()->surface(id).localToGlobal(lp);
665
666 // double val = isEndcap ? fabs(gpos->z()) : gpos->perp();
667 // stgcs are always endcap
668 double val = fabs(gpos.z());
669 // // nasty comparisons to figure out which STGC hit comes first
670 if (val < detLayer.minPos) {
671 if (detLayer.maxPos < -1e8 && detLayer.minPos < 1e8) {
672 detLayer.last3D = detLayer.first3D;
673 detLayer.maxPos = detLayer.minPos;
674 }
675 detLayer.first3D = gpos;
676 detLayer.minPos = val;
677 } else if (val > detLayer.maxPos) {
678 detLayer.last3D = gpos;
679 detLayer.maxPos = val;
680 }
681
682 if (val < minPos) {
683 if (maxPos < -1e8 && minPos < 1e8) {
684 last3D = first3D;
685 maxPos = minPos;
686 }
687 minPos = val;
688 first3D = gpos;
689 } else if (val > maxPos) {
690 maxPos = val;
691 last3D = gpos;
692 }
693
694 const Muon::MuonClusterOnTrack* rot = m_muonClusterCreator->createRIO_OnTrack(*stgc, gpos);
695 if (!rot) {
696 ATH_MSG_WARNING(" ROT creation failed " << m_idHelperSvc->toString(id));
697 continue;
698 }
699 double residual = rot->localParameters().get(Trk::locX) - lp.x();
700 double pull = residual / rot->localCovariance()(Trk::locX);
701 ATH_MSG_DEBUG("Adding r " << gpos.perp() << " z " << gpos.z() << " " << m_idHelperSvc->toString(id) << " " << residual
702 << " pull " << pull);
703 detLayer.meas.push_back(rot);
704 // meas = rot;
705 ++detLayer.nnsw;
706 }
707 }
708
709 // END NEW WORK
710 if (minPos == 2e8 || maxPos == 0) {
711 ATH_MSG_WARNING("Min and max positions not found. Filling with meaningless position");
712 return Amg::Vector3D(-15000, -15000, -15000);
713 }
714
715 if (truthPos)
716 return (first3D + last3D) / 2;
717 else {
718 // else truth direction
719 return (last3D - first3D);
720 }
721 }
722
723 //================================================================
724 void DetailedMuonPatternTruthBuilder::addDetailedTrackTruth(std::vector<DetailedTrackTruth>* output,
725 const Muon::MuonPatternCombination& pattern,
726 const std::vector<const PRD_MultiTruthCollection*>& orderedPRD_Truth,
727 const PRD_InverseTruth& inverseTruth) {
728 SubDetHitStatistics trackStat;
729 std::map<HepMcParticleLink, SubDetPRDs> pairStat; // stats for (track,GenParticle) for the current track
730
731 // Loop over MuonPatternChamberIntersect
732 const std::vector<Muon::MuonPatternChamberIntersect>& MPCIV = pattern.chamberData();
733 for (unsigned int i_MPCI = 0; i_MPCI < MPCIV.size(); i_MPCI++) {
734 if (MPCIV.empty()) continue;
735
736 // get the PrepRawData from the MuonPatternChamberIntersect
737 std::vector<const Trk::PrepRawData*> PRDV = MPCIV.at(i_MPCI).prepRawDataVec();
738
739 // Loop over the PRDV
740 for (unsigned int j_PRD = 0; j_PRD < PRDV.size(); j_PRD++) {
741 if (PRDV.empty()) continue;
742
743 Identifier id = PRDV.at(j_PRD)->identify();
745
747 // if PRD truth collection is missing, ignore subdet in track stat calculation as well.
748 if (orderedPRD_Truth[subdet]) {
749 ++trackStat[subdet];
750
751 typedef PRD_MultiTruthCollection::const_iterator iprdt;
752 std::pair<iprdt, iprdt> range = orderedPRD_Truth[subdet]->equal_range(id);
753
754 int n = 0;
755 // Loop over particles contributing to this cluster
756 for (iprdt i = range.first; i != range.second; ++i) {
757 if (!i->second.isValid()) {
758 ATH_MSG_WARNING("Unexpected invalid HepMcParticleLink in PRD_MultiTruthCollection");
759 } else {
760 pairStat[i->second].subDetHits[subdet].insert(id);
761 n += 1;
762 ATH_MSG_VERBOSE("PRD-ID:" << id << " subdet:" << subdet << " number:" << n
763 << " particle link:" << i->second);
764 }
765 }
766 if (n == 0) {
767 ATH_MSG_VERBOSE("--> no link, noise ? PRD-ID:" << id << " subdet:" << subdet);
768 // add uniqueID 0 to pairs, we like to keep track of fake fakes
769 unsigned int ID(0), EV(0);
770 pairStat[HepMcParticleLink(ID, EV, HepMcParticleLink::IS_POSITION, HepMcParticleLink::IS_ID)].subDetHits[subdet].insert(id);
771 }
772 } // orderedPRD_Truth[] available
773 } // subdet type check, warning in findSubDetType()
774 }
775 }
776
777 if (msgLvl(MSG::VERBOSE)) {
778 msg(MSG::VERBOSE) << "PRD truth particles = ";
779 for (std::map<HepMcParticleLink, SubDetPRDs>::const_iterator i = pairStat.begin(); i != pairStat.end(); ++i) {
780 msg(MSG::VERBOSE) << i->first << ",";
781 }
782 msg(MSG::VERBOSE) << endmsg;
783 }
784
785 //----------------------------------------------------------------
786 // The stat structures are ready.
787 // Build truth trajectories for the track
788
789 std::set<HepMcParticleLink> seeds;
790 for (std::map<HepMcParticleLink, SubDetPRDs>::const_iterator i = pairStat.begin(); i != pairStat.end(); ++i) {
791 if (i->first.isValid()) {
792 seeds.insert(i->first);
793 } else {
794 // add uniqueID 0 particles, we like to keep track of fake fakes
795 TruthTrajectory traj;
796 traj.reserve(1);
797 traj.push_back(i->first);
798 ATH_MSG_VERBOSE("addTrack(): add barcode 0 hits - noise ?");
799
800 // noise/no truth hits on this track
801 SubDetHitStatistics noiseStat = makeSubDetHitStatistics(i->second);
802
803 // Only valid HepMcParticleLink make it into seeds and then into sprouts, and
804 // stored in the loop over sprouts below.
805 // Store output for noise/no truth particles here.
806 output->push_back(DetailedTrackTruth(traj, noiseStat, trackStat, noiseStat));
807 }
808 }
809
810 // Grow sprouts from the seeds
811 typedef std::map<HepMcParticleLink, Sprout> SproutMap;
812 SproutMap sprouts;
813
814 while (!seeds.empty()) {
815 HepMcParticleLink link = *seeds.begin();
816
817 Sprout current_sprout;
818 std::queue<HepMC::ConstGenParticlePtr> tmp;
819 unsigned eventIndex = link.eventIndex();
820 HepMC::ConstGenParticlePtr current = link.scptr();
821 do {
823
824 // remove the current particle from the list of particles to consider (if it is still there)
825 seeds.erase(curlink);
826
827 // Have we worked on this particle before?
828 SproutMap::iterator p_old = sprouts.find(curlink);
829 if (p_old != sprouts.end()) {
830 // merge the old sprout with the current one.
831 current_sprout.splice(current_sprout.end(), p_old->second);
832 current_sprout.stat += p_old->second.stat;
833 // and remove the entry for the old
834 sprouts.erase(p_old);
835 break; // the do-while(getMother()) loop
836 } else { // No, this is a new particle. Try to extend the current truth trajectory.
837
838 // Add the particle to the current truth trajectory.
839 // New: with the current stricter cuts on mother-daughter
840 // we don't have to require that ancestors produce hits.
841
842 current_sprout.push_back(current);
843
844 std::map<HepMcParticleLink, SubDetPRDs>::iterator p_newstat = pairStat.find(curlink);
845 if (p_newstat != pairStat.end()) { current_sprout.stat += p_newstat->second; }
846 }
847 } while ((current = m_truthTrackBuilder->getMother(current)));
848
849 // Add the grown sprout to the list
850 sprouts.insert(std::make_pair(link, current_sprout));
851
852 } // while(!seeds.empty())
853
854 //----------------
855 // All seeds have been processed, and the upstream extensions of the
856 // sprouts are done. Extend the sprouts downstream to get the final
857 // truth trajectories and store the result.
858 //
859 // Note: so far the "sprouts" object mapped {last particle ==> sprout}
860 // Extending a sprout downstream will break this relationship,
861 // but at this point we don't care about it and will only use the
862 // value of the map, not the key.
863 for (SproutMap::iterator s = sprouts.begin(); s != sprouts.end(); ++s) {
864 // Attempt to extend the TruthTrajectory sprout to the "outside".
865 // This may add only hits that are *not* on the current track.
866 // Thus no need to update stats track and stats common.
867
868 HepMC::ConstGenParticlePtr current = *s->second.begin();
869 while ((current = m_truthTrackBuilder->getDaughter(current))) { s->second.push_front(current); }
870
871 // Now we have info to build the final TruthTrajectory.
872 // FIXME: what is the current average size?
873 TruthTrajectory traj;
874 traj.reserve(2); // The average size is about 1.05. Hardcode that instead of using slow list::size().
875 for (Sprout::const_iterator ppart = s->second.begin(); ppart != s->second.end(); ++ppart) {
876 traj.push_back(HepMcParticleLink(HepMC::uniqueID(*ppart), s->first.eventIndex(), HepMcParticleLink::IS_EVENTNUM, HepMcParticleLink::IS_ID));
877 }
878
879 // Count PRDs on the TruthTrajectory
880 std::set<Muon::MuonStationIndex::ChIndex> tempSet;
881 SubDetHitStatistics truthStat = countPRDsOnTruth(traj, inverseTruth, tempSet);
882
883 ATH_MSG_VERBOSE("addTrack(): sprout length = " << traj.size());
884 output->push_back(DetailedTrackTruth(traj, makeSubDetHitStatistics(s->second.stat), trackStat, truthStat));
885 }
886
887 ATH_MSG_VERBOSE("addTrack(): #sprouts = " << sprouts.size() << ", output->size() = " << output->size());
888 }
889
891 std::vector<DetailedSegmentTruth>* output, const Muon::MuonSegment& segment,
892 const std::vector<const PRD_MultiTruthCollection*>& prdTruth) {
893 ATH_MSG_VERBOSE("DetailedMuonPatternTruthBuilder::buildDetailedTrackTruthFromSegments() ");
894
895 if (!output) { return; }
896
897 //----------------------------------------------------------------
898 // The caller can pass PRD truth collections in any order. Sort them out.
899
900 std::vector<const PRD_MultiTruthCollection*> orderedPRD_Truth(SubDetHitStatistics::NUM_SUBDETECTORS);
901 PRD_InverseTruth inverseTruth;
902
903 for (std::vector<const PRD_MultiTruthCollection*>::const_iterator i = prdTruth.begin(); i != prdTruth.end(); ++i) {
904 if (*i) {
905 if (!(*i)->empty()) {
906 SubDetHitStatistics::SubDetType subdet = findSubDetType((*i)->begin()->first);
907
909 orderedPRD_Truth[subdet] = *i;
910 addToInverseMultiMap(&inverseTruth, **i);
911 } else {
912 ATH_MSG_WARNING("Got unknown SubDetType in prdTruth ");
913 }
914 } else {
915 ATH_MSG_DEBUG("Empty truth ???");
916 }
917 }
918 }
919
920 //----------------------------------------------------------------
921 // Find associated truth for each track
922 addDetailedTrackTruthFromSegment(output, segment, orderedPRD_Truth, inverseTruth);
923
924 // DEBUG
925 // FIXME: in normal production jobs that does *a lot of* formatting only to discard the result...
927 "Dumping output collection.\n"
928 " Entries with TruthTrajectories of more then one particle shown at the DEBUG level.\n"
929 " Use VERBOSE level for complete dump.");
930 }
931
932 //================================================================
934 std::vector<DetailedSegmentTruth>* output, const Muon::MuonSegment& segment,
935 const std::vector<const PRD_MultiTruthCollection*>& orderedPRD_Truth, const PRD_InverseTruth& inverseTruth) {
936 SubDetHitStatistics trackStat;
937 std::map<HepMcParticleLink, SubDetPRDs> pairStat; // stats for (track,GenParticle) for the current track
938
939 std::set<Muon::MuonStationIndex::ChIndex> chIndices;
940
941 // Loop over containedROTs in segment
942 for (unsigned int i_cROTv = 0; i_cROTv < segment.numberOfContainedROTs(); i_cROTv++) {
943 const Trk::RIO_OnTrack* rot = segment.rioOnTrack(i_cROTv);
944
945 // get the PrepRawData from the ROT
946 const Trk::PrepRawData* prd = rot->prepRawData();
947
948 Identifier id = prd->identify();
949 chIndices.insert(m_idHelperSvc->chamberIndex(id));
950
952
954 // if PRD truth collection is missing, ignore subdet in track stat calculation as well.
955 if (orderedPRD_Truth[subdet]) {
956 ++trackStat[subdet];
957
958 typedef PRD_MultiTruthCollection::const_iterator iprdt;
959 std::pair<iprdt, iprdt> range = orderedPRD_Truth[subdet]->equal_range(id);
960
961 int n = 0;
962 // Loop over particles contributing to this cluster
963 for (iprdt i = range.first; i != range.second; ++i) {
964 if (!i->second.isValid()) {
965 ATH_MSG_WARNING("Unexpected invalid HepMcParticleLink in PRD_MultiTruthCollection");
966 } else {
967 pairStat[i->second].subDetHits[subdet].insert(id);
968 n += 1;
969 ATH_MSG_VERBOSE("PRD-ID:" << id << " subdet:" << subdet << " number:" << n << " particle link:" << i->second);
970 }
971 }
972 if (n == 0) {
973 ATH_MSG_VERBOSE("--> no link, noise ? PRD-ID:" << id << " subdet:" << subdet);
974 // add uniqueID 0 to pairs, we like to keep track of fake fakes
975 unsigned int ID(0), EV(0);
976 pairStat[HepMcParticleLink(ID, EV, HepMcParticleLink::IS_POSITION, HepMcParticleLink::IS_ID)].subDetHits[subdet].insert(id);
977 }
978 } // orderedPRD_Truth[] available
979 } // subdet type check, warning in findSubDetType()
980 }
981
982 if (msgLvl(MSG::VERBOSE)) {
983 msg(MSG::VERBOSE) << "PRD truth particles = ";
984 for (std::map<HepMcParticleLink, SubDetPRDs>::const_iterator i = pairStat.begin(); i != pairStat.end(); ++i) {
985 msg(MSG::VERBOSE) << i->first << ",";
986 }
987 msg(MSG::VERBOSE) << endmsg;
988 }
989
990 //----------------------------------------------------------------
991 // The stat structures are ready.
992 // Build truth trajectories for the track
993
994 std::set<HepMcParticleLink> seeds;
995 for (std::map<HepMcParticleLink, SubDetPRDs>::const_iterator i = pairStat.begin(); i != pairStat.end(); ++i) {
996 if (i->first.isValid()) {
997 seeds.insert(i->first);
998 } else {
999 // add uniqueID 0 particles, we like to keep track of fake fakes
1000 TruthTrajectory traj;
1001 traj.reserve(1);
1002 traj.push_back(i->first);
1003 ATH_MSG_VERBOSE("addTrack(): add barcode 0 hits - noise ?");
1004
1005 // noise/no truth hits on this track
1006 SubDetHitStatistics noiseStat = makeSubDetHitStatistics(i->second);
1007
1008 // Only valid HepMcParticleLink make it into seeds and then into sprouts, and
1009 // stored in the loop over sprouts below.
1010 // Store output for noise/no truth particles here.
1011 output->push_back(
1012 DetailedSegmentTruth(traj, noiseStat, trackStat, noiseStat, Amg::Vector3D(0, 0, 0), Amg::Vector3D(0, 0, 0)));
1013 }
1014 }
1015
1016 // Grow sprouts from the seeds
1017 typedef std::map<HepMcParticleLink, Sprout> SproutMap;
1018 SproutMap sprouts;
1019
1020 while (!seeds.empty()) {
1021 HepMcParticleLink link = *seeds.begin();
1022
1023 Sprout current_sprout;
1024 std::queue<HepMC::ConstGenParticlePtr> tmp;
1025 unsigned eventIndex = link.eventIndex();
1026 HepMC::ConstGenParticlePtr current = link.scptr();
1027
1028 do {
1030
1031 // remove the current particle from the list of particles to consider (if it is still there)
1032 seeds.erase(curlink);
1033
1034 // Have we worked on this particle before?
1035 SproutMap::iterator p_old = sprouts.find(curlink);
1036 if (p_old != sprouts.end()) {
1037 // merge the old sprout with the current one.
1038 current_sprout.splice(current_sprout.end(), p_old->second);
1039 current_sprout.stat += p_old->second.stat;
1040 // and remove the entry for the old
1041 sprouts.erase(p_old);
1042 break; // the do-while(getMother()) loop
1043 } else { // No, this is a new particle. Try to extend the current truth trajectory.
1044
1045 // Add the particle to the current truth trajectory.
1046 // New: with the current stricter cuts on mother-daughter
1047 // we don't have to require that ancestors produce hits.
1048
1049 current_sprout.push_back(current);
1050
1051 std::map<HepMcParticleLink, SubDetPRDs>::iterator p_newstat = pairStat.find(curlink);
1052 if (p_newstat != pairStat.end()) { current_sprout.stat += p_newstat->second; }
1053 }
1054 } while ((current = m_truthTrackBuilder->getMother(current)));
1055
1056 // Add the grown sprout to the list
1057 sprouts.insert(std::make_pair(link, current_sprout));
1058
1059 } // while(!seeds.empty())
1060
1061 //----------------
1062 // All seeds have been processed, and the upstream extensions of the
1063 // sprouts are done. Extend the sprouts downstream to get the final
1064 // truth trajectories and store the result.
1065 //
1066 // Note: so far the "sprouts" object mapped {last particle ==> sprout}
1067 // Extending a sprout downstream will break this relationship,
1068 // but at this point we don't care about it and will only use the
1069 // value of the map, not the key.
1070 for (SproutMap::iterator s = sprouts.begin(); s != sprouts.end(); ++s) {
1071 // Attempt to extend the TruthTrajectory sprout to the "outside".
1072 // This may add only hits that are *not* on the current track.
1073 // Thus no need to update stats track and stats common.
1074
1075 HepMC::ConstGenParticlePtr current = *s->second.begin();
1076 while ((current = m_truthTrackBuilder->getDaughter(current))) { s->second.push_front(current); }
1077
1078 // Now we have info to build the final TruthTrajectory.
1079 // FIXME: what is the current average size?
1080 TruthTrajectory traj;
1081 traj.reserve(2); // The average size is about 1.05. Hardcode that instead of using slow list::size().
1082 for (Sprout::const_iterator ppart = s->second.begin(); ppart != s->second.end(); ++ppart) {
1083 traj.push_back(HepMcParticleLink(HepMC::uniqueID(*ppart), s->first.eventIndex(), HepMcParticleLink::IS_EVENTNUM, HepMcParticleLink::IS_ID));
1084 }
1085
1086 // Count PRDs on the TruthTrajectory
1087 SubDetHitStatistics truthStat = countPRDsOnTruth(traj, inverseTruth, chIndices);
1088 Amg::Vector3D pos = getPRDTruthPosition(segment, s->second, 1, chIndices);
1089 Amg::Vector3D dir = getPRDTruthPosition(segment, s->second, 0, chIndices);
1090
1091 ATH_MSG_VERBOSE("addTrack(): sprout length = " << traj.size());
1092 output->push_back(DetailedSegmentTruth(traj, makeSubDetHitStatistics(s->second.stat), trackStat, truthStat, pos, dir));
1093 }
1094
1095 ATH_MSG_VERBOSE("addTrack(): #sprouts = " << sprouts.size() << ", output->size() = " << output->size());
1096 }
1097
1098 // AV Note: MuonSimData::Deposit typedef std::pair<HepMcParticleLink, MuonMCData> Deposit;
1100 const HepMC::ConstGenParticlePtr& genPart, const Identifier& id) {
1101 MuonSimDataCollection::const_iterator it = simCol.find(id);
1102 if (it == simCol.end()) {
1103 ATH_MSG_WARNING(" Truth PRD not found in simdata collection: " << m_idHelperSvc->toString(id));
1104 return nullptr;
1105 }
1106
1107 const MuonSimData& simData = it->second;
1108 const MuonSimData::Deposit* deposit = nullptr;
1109 std::vector<MuonSimData::Deposit>::const_iterator dit = simData.getdeposits().begin();
1110 std::vector<MuonSimData::Deposit>::const_iterator dit_end = simData.getdeposits().end();
1111 for (; dit != dit_end; ++dit) {
1112 HepMC::ConstGenParticlePtr gp = dit->first.scptr();
1113 if (gp == genPart) {
1114 deposit = &*dit;
1115 break;
1116 }
1117
1118 }
1119 return deposit;
1120 }
1121
1123 // Retrieve SDO map for this event
1124 if (!evtStore()->contains<MuonSimDataCollection>(colName)) return nullptr;
1125
1126 const MuonSimDataCollection* truthCol(nullptr);
1127 if (!evtStore()->retrieve(truthCol, colName).isSuccess()) {
1128 ATH_MSG_VERBOSE("Could NOT find the MuonSimDataMap map key = " << colName);
1129 } else {
1130 ATH_MSG_VERBOSE("Retrieved MuonSimDataCollection for key = " << colName);
1131 }
1132 return truthCol;
1133 }
1134
1135} // 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.
size_t size() const
Number of registered mappings.
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:116
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)
HepMC3::ConstGenParticlePtr ConstGenParticlePtr
Definition GenParticle.h:20
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