ATLAS Offline Software
Loading...
Searching...
No Matches
Muon::MuonTrackTruthTool Class Reference

Tool to calculate track truth. More...

#include <MuonTrackTruthTool.h>

Inheritance diagram for Muon::MuonTrackTruthTool:
Collaboration diagram for Muon::MuonTrackTruthTool:

Classes

struct  SortResultByMatchedHits

Public Member Functions

 ~MuonTrackTruthTool ()=default
 destructor
StatusCode initialize ()
 AlgTool initilize.
ResultVec match (const TruthTree &truth_tree, const TrackCollection &tracks) const
 perform truth matching for a given set of tracks
SegmentResultVec match (const TruthTree &truth_tree, const std::vector< const MuonSegment * > &segments) const
 perform truth matching for a given set of segments
MuonTrackTruth getTruth (const TruthTree &truth_tree, const Trk::Track &track, bool restrictedTruth=false) const
 get track truth
MuonTrackTruth getTruth (const TruthTree &truth_tree, const std::vector< const MuonSegment * > &segments, bool restrictedTruth=false) const
 get segment truth for a list of segments, the segments will be considered to belong to the same muon
MuonTrackTruth getTruth (const TruthTree &truth_tree, const Muon::MuonSegment &segment) const
 get segment truth
MuonTrackTruth getTruth (const TruthTree &truth_tree, const std::vector< const Trk::MeasurementBase * > &measurements, bool restrictedTruth=false) const
 get truth for a give set of hits.
const TruthTree createTruthTree (const TrackRecordCollection *truthTrackCol, const McEventCollection *mcEventCollection, const std::vector< const MuonSimDataCollection * > &muonSimData, const CscSimDataCollection *cscSimDataMap) const
 create truth tree from sim data
HepMC::ConstGenParticlePtr getMother (const TruthTrajectory &traj, const int barcodeIn) const
 Returns the mother particle of the particle with barcodeIn if it is found in the truth trajectory.
HepMC::ConstGenParticlePtr getAncestor (const TruthTrajectory &traj, const int barcodeIn) const
 Returns the ancestor particle of the particle with barcodeIn if it is found in the truth trajectory.
HepMC::ConstGenParticlePtr getInitial (const TruthTrajectory &traj, const int barcodeIn) const
 Returns the initial particle of the particle with barcodeIn if it is found in the truth trajectory.
unsigned int getNumberOfScatters (const TruthTrajectory &traj, const int barcodeIn) const
 Returns the number of steps a particle took while maintaining its PDG ID.

Private Member Functions

MuonTrackTruth getTruth (const std::vector< const Trk::MeasurementBase * > &measurements, const TruthTreeEntry &truthEntry, bool restrictedTruth) const
void addSimDataToTree (TruthTree &truth_tree, std::map< int, int > &barcode_map, const MuonSimDataCollection *simDataCol) const
void addCscSimDataToTree (TruthTree &truth_tree, std::map< int, int > &barcode_map, const CscSimDataCollection *simDataCol) const
void addMdtTruth (MuonTechnologyTruth &trackTruth, const Identifier &id, const Trk::MeasurementBase &meas, const MuonSimDataCollection &simCol) const
void addClusterTruth (MuonTechnologyTruth &trackTruth, const Identifier &id, const Trk::MeasurementBase &meas, const MuonSimDataCollection &simCol) const
void addClusterTruth (MuonTechnologyTruth &trackTruth, const Identifier &id, const Trk::MeasurementBase &meas, const CscSimDataCollection &simCol) const
void addMissedHits (MuonTechnologyTruth &truth, const std::set< Identifier > &ids, const std::set< Identifier > &chids, const MuonSimDataCollection &simCol, bool restrictedTruth) const
void addMissedHits (MuonTechnologyTruth &truth, const std::set< Identifier > &ids, const std::set< Identifier > &chids, const CscSimDataCollection &simCol, bool restrictedTruth) const
int manipulateBarCode (int barcode) const
bool selectPdg (int pdg) const
const std::pair< HepMC::ConstGenParticlePtr, unsigned int > getInitialPair (const TruthTrajectory &traj, const int barcodeIn) const
 Returns the initial particle of the particle with barcodeIn if it is found in the truth trajectory.

Private Attributes

ServiceHandle< Muon::IMuonIdHelperSvcm_idHelperSvc {this, "MuonIdHelperSvc", "Muon::MuonIdHelperSvc/MuonIdHelperSvc"}
PublicToolHandle< Muon::MuonEDMPrinterToolm_printer {this, "Printer", "Muon::MuonEDMPrinterTool/MuonEDMPrinterTool"}
ToolHandle< Trk::ITruthTrajectoryBuilderm_truthTrajectoryBuilder
Gaudi::Property< bool > m_manipulateBarCode {this, "ManipulateBarCode", false}
Gaudi::Property< bool > m_doSummary {this, "DoSummary", false}
Gaudi::Property< bool > m_matchAllParticles {this, "MatchAllParticles", true}
Gaudi::Property< unsigned int > m_minHits {this, "MinHits", 4}
Gaudi::Property< std::vector< int > > m_pdgsToBeConsidered {this, "ConsideredPDGs", {}}
std::set< int > m_selectedPdgs

Detailed Description

Tool to calculate track truth.

Definition at line 43 of file MuonTrackTruthTool.h.

Constructor & Destructor Documentation

◆ ~MuonTrackTruthTool()

Muon::MuonTrackTruthTool::~MuonTrackTruthTool ( )
default

destructor

Member Function Documentation

◆ addClusterTruth() [1/2]

void Muon::MuonTrackTruthTool::addClusterTruth ( MuonTechnologyTruth & trackTruth,
const Identifier & id,
const Trk::MeasurementBase & meas,
const CscSimDataCollection & simCol ) const
private

Definition at line 612 of file MuonTrackTruthTool.cxx.

613 {
614 Identifier layid = m_idHelperSvc->layerId(id);
615 Identifier chid = m_idHelperSvc->chamberId(id);
616 // find SimData corresponding to identifier
617 CscSimDataCollection::const_iterator it = simCol.find(id);
618 if (it == simCol.end()) {
619 truth.wrongHits.insert(layid);
620 truth.wrongChambers.insert(chid);
621 return;
622 }
623
624 std::vector<CscSimData::Deposit>::const_iterator dit = it->second.getdeposits().begin();
625 std::vector<CscSimData::Deposit>::const_iterator dit_end = it->second.getdeposits().end();
626 for (; dit != dit_end; ++dit) {
627 truth.matchedHits.insert(layid);
628 truth.matchedChambers.insert(chid);
629 }
630 }
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc

◆ addClusterTruth() [2/2]

void Muon::MuonTrackTruthTool::addClusterTruth ( MuonTechnologyTruth & trackTruth,
const Identifier & id,
const Trk::MeasurementBase & meas,
const MuonSimDataCollection & simCol ) const
private

Definition at line 556 of file MuonTrackTruthTool.cxx.

557 {
558 Identifier layid = m_idHelperSvc->layerId(id);
559 Identifier chid = m_idHelperSvc->chamberId(id);
560
561 MuonSimDataCollection::const_iterator it = simCol.end();
562
563 bool goodCluster = false;
564 const CompetingMuonClustersOnTrack* crot = dynamic_cast<const CompetingMuonClustersOnTrack*>(&meas);
565 if (crot) {
566 for (unsigned int i = 0; i < crot->numberOfContainedROTs(); ++i) {
567 const MuonClusterOnTrack* cluster = &crot->rioOnTrack(i);
568 if (!cluster) continue;
569 // find SimData corresponding to identifier
570 it = simCol.find(cluster->identify());
571 if (it != simCol.end()) {
572 goodCluster = true;
573 break;
574 }
575 }
576 } else {
577 // Find SimData corresponding to identifier
578 const Trk::RIO_OnTrack* rot = nullptr;
579 Trk::RoT_Extractor::extract(rot, &meas);
580 const Trk::PrepRawData* prd = rot->prepRawData();
581 if (prd) {
582 // check if an identifier from the list of RDOs is matched to that in the SDO collection
583 const std::vector<Identifier> &rdoList = prd->rdoList();
584 std::vector<Identifier>::const_iterator rit = rdoList.begin();
585 std::vector<Identifier>::const_iterator rit_end = rdoList.end();
586 for (; rit != rit_end; ++rit) {
587 it = simCol.find(*rit);
588 if (it != simCol.end()) {
589 goodCluster = true;
590 break;
591 }
592 }
593 } else {
594 it = simCol.find(id);
595 if (it != simCol.end()) goodCluster = true;
596 }
597 }
598
599 if (!goodCluster || it == simCol.end()) {
600 truth.wrongHits.insert(id);
601 return;
602 }
603
604 std::vector<MuonSimData::Deposit>::const_iterator dit = it->second.getdeposits().begin();
605 std::vector<MuonSimData::Deposit>::const_iterator dit_end = it->second.getdeposits().end();
606 for (; dit != dit_end; ++dit) {
607 truth.matchedHits.insert(layid);
608 truth.matchedChambers.insert(chid);
609 }
610 }
const std::vector< Identifier > & rdoList() const
return the List of rdo identifiers (pointers)
virtual const Trk::PrepRawData * prepRawData() const =0
returns the PrepRawData (also known as RIO) object to which this RIO_OnTrack is associated.
static void extract(std::vector< const RIO_OnTrack * > &rots, const std::vector< const MeasurementBase * > &measurements)

◆ addCscSimDataToTree()

void Muon::MuonTrackTruthTool::addCscSimDataToTree ( TruthTree & truth_tree,
std::map< int, int > & barcode_map,
const CscSimDataCollection * simDataCol ) const
private

Definition at line 315 of file MuonTrackTruthTool.cxx.

316 {
317 // loop over sim collection and check whether identifiers are on track
318 CscSimDataCollection::const_iterator it = simDataCol->begin();
319 CscSimDataCollection::const_iterator it_end = simDataCol->end();
320 for (; it != it_end; ++it) {
321 Identifier id = it->first;
322
323 // loop over deposits
324 std::vector<CscSimData::Deposit>::const_iterator dit = it->second.getdeposits().begin();
325 std::vector<CscSimData::Deposit>::const_iterator dit_end = it->second.getdeposits().end();
326 for (; dit != dit_end; ++dit) {
327 int barcodeIn = HepMC::uniqueID(dit->first);
328 std::map<int, int>::const_iterator bit = barcode_map.find(barcodeIn);
329 if (bit == barcode_map.end()) {
330 ATH_MSG_VERBOSE(" discarding "
331 << " " << m_idHelperSvc->toString(id) << " barcode " << barcodeIn);
332 continue;
333 }
334 // replace barcode with barcode from map
335 int barcode = bit->second;
336
337 TruthTreeIt eit = truth_tree.find(barcode);
338 if (eit == truth_tree.end()) {
339 ATH_MSG_VERBOSE(" discarding "
340 << " " << m_idHelperSvc->toString(id) << " barcode " << barcode);
341 continue;
342 }
343
344 if (msgLvl(MSG::VERBOSE)) {
345 ATH_MSG_VERBOSE(" adding hit " << m_idHelperSvc->toString(id) << " barcode " << barcode);
346 if (barcode != barcodeIn) ATH_MSG_VERBOSE(" hit barcode " << barcodeIn);
347 }
348 eit->second.cscHits.insert(*it);
349 }
350 }
351 }
#define ATH_MSG_VERBOSE(x)
constexpr unsigned int bit(int n)
int barcode(const T *p)
Definition Barcode.h:15
int uniqueID(const T &p)

◆ addMdtTruth()

void Muon::MuonTrackTruthTool::addMdtTruth ( MuonTechnologyTruth & trackTruth,
const Identifier & id,
const Trk::MeasurementBase & meas,
const MuonSimDataCollection & simCol ) const
private

Definition at line 521 of file MuonTrackTruthTool.cxx.

522 {
523 const MdtDriftCircleOnTrack* mdt = dynamic_cast<const MdtDriftCircleOnTrack*>(&meas);
524 if (!mdt) {
525 ATH_MSG_WARNING(" dynamic_cast to MdtDriftCircleOnTrack failed for measurement with id " << m_idHelperSvc->toString(id));
526 return;
527 }
528
529 Identifier chid = m_idHelperSvc->chamberId(id);
530
531 // find SimData corresponding to identifier
532 MuonSimDataCollection::const_iterator it = simCol.find(id);
533 if (it == simCol.end()) {
534 truth.wrongHits.insert(id);
535 truth.wrongChambers.insert(chid);
536 return;
537 }
538
539 std::vector<MuonSimData::Deposit>::const_iterator dit = it->second.getdeposits().begin();
540 std::vector<MuonSimData::Deposit>::const_iterator dit_end = it->second.getdeposits().end();
541 for (; dit != dit_end; ++dit) {
542 double radius = dit->second.firstEntry();
543
544 // check whether SDO and hit have same sign, don't check sign if drift radius < 0.3 mm as it will be badly determined
545 double checkSign = fabs(mdt->driftRadius()) > 0.3 ? radius * mdt->driftRadius() : 1;
546 if (checkSign >= 0) {
547 truth.matchedHits.insert(id);
548 truth.matchedChambers.insert(chid);
549 } else {
550 truth.wrongHits.insert(id);
551 truth.wrongChambers.insert(chid);
552 }
553 }
554 }
#define ATH_MSG_WARNING(x)
double driftRadius() const
Returns the value of the drift radius.

◆ addMissedHits() [1/2]

void Muon::MuonTrackTruthTool::addMissedHits ( MuonTechnologyTruth & truth,
const std::set< Identifier > & ids,
const std::set< Identifier > & chids,
const CscSimDataCollection & simCol,
bool restrictedTruth ) const
private

Definition at line 494 of file MuonTrackTruthTool.cxx.

495 {
496 // loop over sim collection and check whether identifiers are on track
497 CscSimDataCollection::const_iterator it = simCol.begin();
498 CscSimDataCollection::const_iterator it_end = simCol.end();
499 for (; it != it_end; ++it) {
500 Identifier id = m_idHelperSvc->layerId(it->first);
501
502 int isOnTrack = ids.count(id);
503 if (isOnTrack) continue;
504
505 // if restricted truth mode, skip if chamber has not hits
506 Identifier chid = m_idHelperSvc->chamberId(id);
507 bool chamberHasHits = chids.count(chid);
508 if (restrictedTruth && !chamberHasHits) continue;
509
510 // loop over deposits
511 std::vector<CscSimData::Deposit>::const_iterator dit = it->second.getdeposits().begin();
512 std::vector<CscSimData::Deposit>::const_iterator dit_end = it->second.getdeposits().end();
513 for (; dit != dit_end; ++dit) {
514 truth.missedHits.insert(id);
515 // only fill a missed chamber if the chamber had no hits
516 if (!chamberHasHits) truth.missedChambers.insert(chid);
517 }
518 }
519 }

◆ addMissedHits() [2/2]

void Muon::MuonTrackTruthTool::addMissedHits ( MuonTechnologyTruth & truth,
const std::set< Identifier > & ids,
const std::set< Identifier > & chids,
const MuonSimDataCollection & simCol,
bool restrictedTruth ) const
private

Definition at line 465 of file MuonTrackTruthTool.cxx.

466 {
467 // loop over sim collection and check whether identifiers are on track
468 MuonSimDataCollection::const_iterator it = simCol.begin();
469 MuonSimDataCollection::const_iterator it_end = simCol.end();
470 for (; it != it_end; ++it) {
471 Identifier id = it->first;
472 // for trigger chambers use layer id
473 if (m_idHelperSvc->isTrigger(id) || m_idHelperSvc->isCsc(id)) id = m_idHelperSvc->layerId(id);
474
475 int isOnTrack = ids.count(id);
476 if (isOnTrack) continue;
477
478 // if restricted truth mode, skip if chamber has not hits
479 Identifier chid = m_idHelperSvc->chamberId(id);
480 bool chamberHasHits = chids.count(chid);
481 if (restrictedTruth && !chamberHasHits) continue;
482
483 // loop over deposits
484 std::vector<MuonSimData::Deposit>::const_iterator dit = it->second.getdeposits().begin();
485 std::vector<MuonSimData::Deposit>::const_iterator dit_end = it->second.getdeposits().end();
486 for (; dit != dit_end; ++dit) {
487 truth.missedHits.insert(id);
488 // only fill a missed chamber if the chamber had no hits
489 if (!chamberHasHits) truth.missedChambers.insert(chid);
490 }
491 }
492 }

◆ addSimDataToTree()

void Muon::MuonTrackTruthTool::addSimDataToTree ( TruthTree & truth_tree,
std::map< int, int > & barcode_map,
const MuonSimDataCollection * simDataCol ) const
private

Definition at line 262 of file MuonTrackTruthTool.cxx.

263 {
264 // loop over sim collection and check whether identifiers are on track
265 MuonSimDataCollection::const_iterator it = simDataCol->begin();
266 MuonSimDataCollection::const_iterator it_end = simDataCol->end();
267 for (; it != it_end; ++it) {
268 Identifier id = it->first;
269
270 // loop over deposits
271 std::vector<MuonSimData::Deposit>::const_iterator dit = it->second.getdeposits().begin();
272 std::vector<MuonSimData::Deposit>::const_iterator dit_end = it->second.getdeposits().end();
273 for (; dit != dit_end; ++dit) {
274 int barcodeIn = HepMC::uniqueID(dit->first);
275 std::map<int, int>::const_iterator bit = barcode_map.find(barcodeIn);
276 if (bit == barcode_map.end()) {
277 ATH_MSG_VERBOSE(" discarding "
278 << " " << m_idHelperSvc->toString(id) << " barcode " << barcodeIn);
279 continue;
280 }
281 // replace barcode with barcode from map
282 int barcode = bit->second;
283
284 TruthTreeIt eit = truth_tree.find(barcode);
285 if (eit == truth_tree.end()) {
286 ATH_MSG_VERBOSE(" discarding "
287 << " " << m_idHelperSvc->toString(id) << " barcode " << barcode);
288 continue;
289 }
290
291 if (m_idHelperSvc->isMdt(id)) {
292 eit->second.mdtHits.insert(*it);
293 } else if (m_idHelperSvc->isRpc(id)) {
294 if (m_idHelperSvc->stationIndex(id) == StIndex::BO && m_idHelperSvc->rpcIdHelper().doubletR(id) == 2) {
295 ATH_MSG_VERBOSE(" Discarding non existing RPC hit " << m_idHelperSvc->toString(id));
296 continue;
297 }
298
299 eit->second.rpcHits.insert(*it);
300 } else if (m_idHelperSvc->isTgc(id)) {
301 eit->second.tgcHits.insert(*it);
302 } else if (m_idHelperSvc->issTgc(id)) {
303 eit->second.stgcHits.insert(*it);
304 } else if (m_idHelperSvc->isMM(id)) {
305 eit->second.mmHits.insert(*it);
306 }
307 if (msgLvl(MSG::VERBOSE)) {
308 ATH_MSG_VERBOSE(" adding hit " << m_idHelperSvc->toString(id) << " barcode " << barcode);
309 if (barcode != barcodeIn) ATH_MSG_VERBOSE(" hit barcode " << barcodeIn);
310 }
311 }
312 }
313 }

◆ createTruthTree()

const MuonTrackTruthTool::TruthTree Muon::MuonTrackTruthTool::createTruthTree ( const TrackRecordCollection * truthTrackCol,
const McEventCollection * mcEventCollection,
const std::vector< const MuonSimDataCollection * > & muonSimData,
const CscSimDataCollection * cscSimDataMap ) const

create truth tree from sim data

Definition at line 108 of file MuonTrackTruthTool.cxx.

111 {
112 std::map<int, int> barcode_map;
113 MuonTrackTruthTool::TruthTree truth_tree;
114 if (truthTrackCol->empty()) {
115 ATH_MSG_WARNING(" TrackRecordCollection is empty ");
116 return truth_tree;
117 }
118
119 const HepMC::GenEvent* genEvent = nullptr;
120 if (!mcEventCollection->empty()) {
121 ATH_MSG_VERBOSE("McEventCollection size " << mcEventCollection->size());
122 if (mcEventCollection->size() == 1) genEvent = mcEventCollection->front();
123 }
124
125 ATH_MSG_VERBOSE(" creating truth tree from track record " << truthTrackCol->size());
126
127 TrackRecordConstIterator tr_it = truthTrackCol->begin();
128 TrackRecordConstIterator tr_it_end = truthTrackCol->end();
129 for (; tr_it != tr_it_end; ++tr_it) {
130 int PDGCode((*tr_it).GetPDGCode());
131 int barcode = HepMC::uniqueID(*tr_it);
132 if (!m_matchAllParticles && !selectPdg(PDGCode)) {
133 ATH_MSG_VERBOSE(" discarding truth track: pdg " << PDGCode << " barcode " << barcode);
134 continue;
135 }
136
137 // check whether barcode is already in, skip if that is the case
138 if (barcode_map.count(barcode)) {
139 ATH_MSG_VERBOSE(" barcode " << barcode << " already in map, final state barcode " << barcode_map[barcode]);
140 continue;
141 }
142 ATH_MSG_VERBOSE(" found new particle with pdgid " << PDGCode << " in truth record, barcode " << barcode);
143
144 std::unique_ptr<TruthTrajectory> truthTrajectory;
145 // associate the muon truth with the gen event info
146 if (genEvent) {
147 HepMC::ConstGenParticlePtr genParticle =
148 (barcode>HepMC::UNDEFINED_ID) ? genEvent->particles().at(barcode-1) : nullptr; // FIXME implement HepMC::id_to_particle/vertex explicitly
149 if (genParticle) {
150 truthTrajectory = std::make_unique<TruthTrajectory>();
151 m_truthTrajectoryBuilder->buildTruthTrajectory(truthTrajectory.get(), genParticle);
152 if (!truthTrajectory->empty()) {
153 // always use barcode of the 'final' particle in chain in map
154 barcode = HepMC::uniqueID(truthTrajectory->front());
155
156 if (msgLvl(MSG::VERBOSE)) {
157 auto particle = truthTrajectory->front().cptr();
158 ATH_MSG_VERBOSE(" found GenParticle: size " << truthTrajectory->size() << " fs barcode " << barcode << "particle "<< particle);
159 if (particle->production_vertex()) {
160 ATH_MSG_VERBOSE(" vertex: r " << particle->production_vertex()->position().perp() << " z "
161 << particle->production_vertex()->position().z());
162 }
163 }
164
165 // now collect all barcodes beloning to this TruthTrajectory
166 std::vector<HepMcParticleLink>::const_iterator pit = truthTrajectory->begin();
167 std::vector<HepMcParticleLink>::const_iterator pit_end = truthTrajectory->end();
168 for (; pit != pit_end; ++pit) {
169 int code = HepMC::uniqueID(*pit);
170
171 if (msgLvl(MSG::VERBOSE) && code != barcode) {
172 auto particle = (*pit).cptr();
173 ATH_MSG_VERBOSE(" secondary barcode: " << code << "particle "<< particle);
174 if (particle->production_vertex())
175 ATH_MSG_VERBOSE(" vertex: r " <<particle->production_vertex()->position().perp() << " z "
176 << particle->production_vertex()->position().z());
177 // sanity check
178 if (barcode_map.count(code)) ATH_MSG_VERBOSE(" pre-existing barcode " << code);
179 }
180
181 // enter barcode
182 barcode_map[code] = barcode;
183 }
184 } else {
185 ATH_MSG_WARNING(" empty truth trajectory " << barcode);
186 }
187 }
188 } else {
189 // add one to one relation
190 barcode_map[barcode] = barcode;
191 }
192
193 if (truth_tree.count(barcode)) {
194 ATH_MSG_WARNING(" found muon barcode twice in truth record: " << barcode);
195 continue;
196 }
197
198 TruthTreeEntry& entry = truth_tree[barcode];
199 entry.truthTrack = &(*tr_it);
200 // entry.truthTrajectory = truthTrajectory.get();
201 entry.truthTrajectory = std::move(truthTrajectory);
202 // m_truthTrajectoriesToBeDeleted.push_back(std::move(truthTrajectory));
203 }
204
205 // add sim data collections
206 for (const MuonSimDataCollection* simDataMap : muonSimData) { addSimDataToTree(truth_tree, barcode_map, simDataMap); }
207 if (cscSimDataMap) { addCscSimDataToTree(truth_tree, barcode_map, cscSimDataMap); }
208
209 unsigned int ngood(0);
210 std::vector<int> badBarcodes;
211 // erase entries with too few hits or no track record
212 TruthTreeIt it = truth_tree.begin();
213 for (; it != truth_tree.end(); ++it) {
214 bool erase = false;
215 unsigned int nhits = it->second.mdtHits.size() + it->second.rpcHits.size() + it->second.tgcHits.size() +
216 it->second.cscHits.size() + it->second.stgcHits.size() + it->second.mmHits.size();
217 if (!it->second.truthTrack) erase = true;
218 if (nhits < m_minHits) erase = true;
219
220 if (erase) {
221 ATH_MSG_VERBOSE(" Erasing entry: barcode " << HepMC::uniqueID(it->second.truthTrack) << " hits " << nhits);
222 badBarcodes.push_back(it->first);
223 } else {
224 ++ngood;
225 ATH_MSG_VERBOSE(" Keeping entry: barcode " << HepMC::uniqueID(it->second.truthTrack) << " hits " << nhits);
226 }
227 }
228
229 std::vector<int>::iterator badIt = badBarcodes.begin();
230 std::vector<int>::iterator badIt_end = badBarcodes.end();
231 for (; badIt != badIt_end; ++badIt) truth_tree.erase(*badIt);
232
233 if (ngood != truth_tree.size()) {
234 ATH_MSG_WARNING(" Problem cleaning map: size " << truth_tree.size() << " accepted entries " << ngood);
235 }
236
237 if (m_doSummary || msgLvl(MSG::DEBUG)) {
238 ATH_MSG_INFO(" summarizing truth tree: number of particles " << truth_tree.size());
239 TruthTreeIt it = truth_tree.begin();
240 TruthTreeIt it_end = truth_tree.end();
241 for (; it != it_end; ++it) {
242 if (!it->second.truthTrack)
243 ATH_MSG_INFO(" no TrackRecord ");
244 else {
245 ATH_MSG_INFO(" PDG " << it->second.truthTrack->GetPDGCode() << " barcode " << HepMC::uniqueID(it->second.truthTrack));
246 }
247 if (!it->second.mdtHits.empty()) ATH_MSG_INFO(" mdt " << it->second.mdtHits.size());
248 if (!it->second.rpcHits.empty()) ATH_MSG_INFO(" rpc " << it->second.rpcHits.size());
249 if (!it->second.tgcHits.empty()) ATH_MSG_INFO(" tgc " << it->second.tgcHits.size());
250 if (!it->second.cscHits.empty()) ATH_MSG_INFO(" csc " << it->second.cscHits.size());
251 if (!it->second.stgcHits.empty()) ATH_MSG_INFO(" stgc " << it->second.stgcHits.size());
252 if (!it->second.mmHits.empty()) ATH_MSG_INFO(" mm " << it->second.mmHits.size());
253 if (it->second.mdtHits.empty() && it->second.rpcHits.empty() && it->second.tgcHits.empty() && it->second.cscHits.empty() &&
254 it->second.stgcHits.empty() && it->second.mmHits.empty())
255 ATH_MSG_INFO(" no hits ");
256 }
257 }
258
259 return truth_tree;
260 }
#define ATH_MSG_INFO(x)
AtlasHitsVector< TrackRecord >::const_iterator TrackRecordConstIterator
bool empty() const
const_iterator begin() const
size_type size() const
const_iterator end() const
const T * front() const
Access the first element in the collection as an rvalue.
size_type size() const noexcept
Returns the number of elements in the collection.
bool empty() const noexcept
Returns true if the collection is empty.
ToolHandle< Trk::ITruthTrajectoryBuilder > m_truthTrajectoryBuilder
bool selectPdg(int pdg) const
Gaudi::Property< unsigned int > m_minHits
void addCscSimDataToTree(TruthTree &truth_tree, std::map< int, int > &barcode_map, const CscSimDataCollection *simDataCol) const
Gaudi::Property< bool > m_matchAllParticles
Gaudi::Property< bool > m_doSummary
void addSimDataToTree(TruthTree &truth_tree, std::map< int, int > &barcode_map, const MuonSimDataCollection *simDataCol) const
constexpr int UNDEFINED_ID
HepMC3::ConstGenParticlePtr ConstGenParticlePtr
Definition GenParticle.h:20
HepMC3::GenEvent GenEvent
Definition GenEvent.h:39
virtual void erase() override final
Free all allocated elements and release memory back to the system.
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses

◆ getAncestor()

HepMC::ConstGenParticlePtr Muon::MuonTrackTruthTool::getAncestor ( const TruthTrajectory & traj,
const int barcodeIn ) const

Returns the ancestor particle of the particle with barcodeIn if it is found in the truth trajectory.

Ancestor here means the last particle at generator level that has a status code different from final state, e.g. Z

Definition at line 650 of file MuonTrackTruthTool.cxx.

650 {
651 bool foundBC = false;
652 for (const auto& pit : traj) {
653 if (!pit) continue;
654 if (HepMC::uniqueID(pit) == barcodeIn || foundBC) {
655 foundBC = true;
656 auto particle = pit.scptr();
657 if (!MC::isStable(particle)) { // first non final state particle
658 return particle;
659 }
660 }
661 }
662 return nullptr;
663 }
bool isStable(const T &p)
Identify if the particle is stable, i.e. has not decayed.

◆ getInitial()

HepMC::ConstGenParticlePtr Muon::MuonTrackTruthTool::getInitial ( const TruthTrajectory & traj,
const int barcodeIn ) const

Returns the initial particle of the particle with barcodeIn if it is found in the truth trajectory.

For example a mu undergoing a mubrem would create a second mu, in which case this method returns the mu prior to bremsstrahlung. This interface calls the method getInitialPair.

Definition at line 706 of file MuonTrackTruthTool.cxx.

706 {
707 return getInitialPair(traj, barcodeIn).first;
708 }
const std::pair< HepMC::ConstGenParticlePtr, unsigned int > getInitialPair(const TruthTrajectory &traj, const int barcodeIn) const
Returns the initial particle of the particle with barcodeIn if it is found in the truth trajectory.

◆ getInitialPair()

const std::pair< HepMC::ConstGenParticlePtr, unsigned int > Muon::MuonTrackTruthTool::getInitialPair ( const TruthTrajectory & traj,
const int barcodeIn ) const
private

Returns the initial particle of the particle with barcodeIn if it is found in the truth trajectory.

For example a mu undergoing a mubrem would create a second mu, in which case this method returns the mu prior to bremsstrahlung. The number of such scatters is returned in the .second.

Definition at line 665 of file MuonTrackTruthTool.cxx.

666 {
667 std::pair<HepMC::ConstGenParticlePtr, unsigned int> thePair(nullptr, 0);
668 unsigned int scat = 0;
669 ATH_MSG_DEBUG("getFirst() : size = " << traj.size());
670 bool foundBC = false;
671 int pdgFinal = 0;
672 double ePrev = 0.;
673 HepMC::ConstGenParticlePtr theFirst{nullptr};
674 for (auto pit = traj.begin(); pit != traj.end(); ++pit) {
675 if (HepMC::uniqueID(*pit) == barcodeIn || foundBC) {
676 auto particle = (*pit).scptr();
677 if (!foundBC) {
678 foundBC = true;
679 theFirst = particle;
680 pdgFinal = particle->pdg_id();
681 } else {
682 if (particle->pdg_id() == pdgFinal) {
683 const auto& pit_p = *pit;
684 if ((theFirst != pit_p.scptr()) && (particle->momentum().t() != ePrev))
685 ++scat; // if the particle has not changed pdgid after the first step count as scatter. also avoid counting
686 // pure interface changes as scatter
687 } else { // the first time this particle appears
688 --pit; // AV This is confusing
689 theFirst = (*pit).scptr();
690 break;
691 }
692 }
693 ATH_MSG_DEBUG("getFirst() : pt = " << particle->momentum().perp() << " scat = " << scat);
694 ePrev = particle->momentum().t(); // prepare for comparing this entry with the next one
695 }
696 }
697 // sanity check
698 if (theFirst && theFirst->pdg_id() != pdgFinal) ATH_MSG_ERROR("Wrong pdgId association in getFirst()");
699 ATH_MSG_DEBUG("Number of scatters = " << scat << " pdgId = " << pdgFinal);
700
701 thePair.first = theFirst;
702 thePair.second = scat;
703 return thePair;
704 }
#define ATH_MSG_ERROR(x)
#define ATH_MSG_DEBUG(x)

◆ getMother()

HepMC::ConstGenParticlePtr Muon::MuonTrackTruthTool::getMother ( const TruthTrajectory & traj,
const int barcodeIn ) const

Returns the mother particle of the particle with barcodeIn if it is found in the truth trajectory.

It traces the decay chain until if finds the first particle that is different flavor from the starting one.

Definition at line 632 of file MuonTrackTruthTool.cxx.

632 {
633 ATH_MSG_DEBUG("getMother() : size = " << traj.size());
634 int pdgFinal = ((traj.empty()) ? -999 : traj.front().cptr()->pdg_id());
635 bool foundBC = false;
636 for (const auto& pit : traj) {
637 if (!pit) continue;
638 if (HepMC::uniqueID(pit) == barcodeIn || foundBC) {
639 foundBC = true;
640 ATH_MSG_DEBUG("getMother() : " << pit );
641 auto particle = pit.scptr();
642 if (particle->pdg_id() != pdgFinal) { // the first case a track had a different flavour
643 break;
644 }
645 }
646 }
647 return nullptr;
648 }

◆ getNumberOfScatters()

unsigned int Muon::MuonTrackTruthTool::getNumberOfScatters ( const TruthTrajectory & traj,
const int barcodeIn ) const

Returns the number of steps a particle took while maintaining its PDG ID.

This method calls getInitialPair for calculating this number.

Definition at line 710 of file MuonTrackTruthTool.cxx.

710 {
711 return (getInitialPair(traj, barcodeIn)).second;
712 }

◆ getTruth() [1/5]

MuonTrackTruth Muon::MuonTrackTruthTool::getTruth ( const std::vector< const Trk::MeasurementBase * > & measurements,
const TruthTreeEntry & truthEntry,
bool restrictedTruth ) const
private

Definition at line 417 of file MuonTrackTruthTool.cxx.

418 {
419 MuonTrackTruth trackTruth;
420 trackTruth.truthTrack = truthEntry.truthTrack;
421 trackTruth.truthTrajectory = truthEntry.truthTrajectory;
422
423 std::vector<const Trk::MeasurementBase*>::const_iterator mit = measurements.begin();
424 std::vector<const Trk::MeasurementBase*>::const_iterator mit_end = measurements.end();
425 for (; mit != mit_end; ++mit) {
426 // check whether state is a measurement
427 const Trk::MeasurementBase* meas = *mit;
428 if (!meas) { continue; }
429
430 const Trk::RIO_OnTrack* rot = nullptr;
432 if (!rot) {
433 if (!dynamic_cast<const Trk::PseudoMeasurementOnTrack*>(meas)) ATH_MSG_WARNING(" Could not get rot from measurement ");
434 continue;
435 }
436 Identifier id = rot->identify();
437 if (!id.is_valid() || !m_idHelperSvc->mdtIdHelper().is_muon(id)) continue;
438
439 if (m_idHelperSvc->isMdt(id)) {
440 addMdtTruth(trackTruth.mdts, id, *meas, truthEntry.mdtHits);
441 } else if (m_idHelperSvc->isCsc(id)) {
442 addClusterTruth(trackTruth.cscs, id, *meas, truthEntry.cscHits);
443 } else if (m_idHelperSvc->isRpc(id)) {
444 addClusterTruth(trackTruth.rpcs, id, *meas, truthEntry.rpcHits);
445 } else if (m_idHelperSvc->isTgc(id)) {
446 addClusterTruth(trackTruth.tgcs, id, *meas, truthEntry.tgcHits);
447 } else if (m_idHelperSvc->issTgc(id)) {
448 addClusterTruth(trackTruth.stgcs, id, *meas, truthEntry.stgcHits);
449 } else if (m_idHelperSvc->isMM(id)) {
450 addClusterTruth(trackTruth.mms, id, *meas, truthEntry.mmHits);
451 }
452 }
453
454 addMissedHits(trackTruth.mdts, trackTruth.mdts.matchedHits, trackTruth.mdts.matchedChambers, truthEntry.mdtHits, restrictedTruth);
455 addMissedHits(trackTruth.cscs, trackTruth.cscs.matchedHits, trackTruth.cscs.matchedChambers, truthEntry.cscHits, restrictedTruth);
456 addMissedHits(trackTruth.rpcs, trackTruth.rpcs.matchedHits, trackTruth.rpcs.matchedChambers, truthEntry.rpcHits, restrictedTruth);
457 addMissedHits(trackTruth.tgcs, trackTruth.tgcs.matchedHits, trackTruth.tgcs.matchedChambers, truthEntry.tgcHits, restrictedTruth);
458 addMissedHits(trackTruth.stgcs, trackTruth.stgcs.matchedHits, trackTruth.stgcs.matchedChambers, truthEntry.stgcHits,
459 restrictedTruth);
460 addMissedHits(trackTruth.mms, trackTruth.mms.matchedHits, trackTruth.mms.matchedChambers, truthEntry.mmHits, restrictedTruth);
461
462 return trackTruth;
463 }
void addClusterTruth(MuonTechnologyTruth &trackTruth, const Identifier &id, const Trk::MeasurementBase &meas, const MuonSimDataCollection &simCol) const
void addMissedHits(MuonTechnologyTruth &truth, const std::set< Identifier > &ids, const std::set< Identifier > &chids, const MuonSimDataCollection &simCol, bool restrictedTruth) const
void addMdtTruth(MuonTechnologyTruth &trackTruth, const Identifier &id, const Trk::MeasurementBase &meas, const MuonSimDataCollection &simCol) const
Identifier identify() const
return the identifier -extends MeasurementBase

◆ getTruth() [2/5]

MuonTrackTruth Muon::MuonTrackTruthTool::getTruth ( const TruthTree & truth_tree,
const Muon::MuonSegment & segment ) const

get segment truth

Definition at line 353 of file MuonTrackTruthTool.cxx.

353 {
354 return getTruth(truth_tree, segment.containedMeasurements(), true);
355 }
MuonTrackTruth getTruth(const TruthTree &truth_tree, const Trk::Track &track, bool restrictedTruth=false) const
get track truth
const std::vector< const Trk::MeasurementBase * > & containedMeasurements() const
returns the vector of Trk::MeasurementBase objects

◆ getTruth() [3/5]

MuonTrackTruth Muon::MuonTrackTruthTool::getTruth ( const TruthTree & truth_tree,
const std::vector< const MuonSegment * > & segments,
bool restrictedTruth = false ) const

get segment truth for a list of segments, the segments will be considered to belong to the same muon

Definition at line 362 of file MuonTrackTruthTool.cxx.

363 {
364 std::set<Identifier> ids;
365 std::vector<const Trk::MeasurementBase*> measurements;
366 std::vector<const MuonSegment*>::const_iterator sit = segments.begin();
367 std::vector<const MuonSegment*>::const_iterator sit_end = segments.end();
368 for (; sit != sit_end; ++sit) {
369 std::vector<const Trk::MeasurementBase*>::const_iterator mit = (*sit)->containedMeasurements().begin();
370 std::vector<const Trk::MeasurementBase*>::const_iterator mit_end = (*sit)->containedMeasurements().end();
371 for (; mit != mit_end; ++mit) {
372 const Trk::MeasurementBase* meas = *mit;
373 const Trk::RIO_OnTrack* rot = nullptr;
375 if (!rot) {
376 if (!dynamic_cast<const Trk::PseudoMeasurementOnTrack*>(meas)) ATH_MSG_WARNING(" Could not get rot from measurement ");
377 continue;
378 }
379 Identifier id = rot->identify();
380 if (!id.is_valid() || !m_idHelperSvc->mdtIdHelper().is_muon(id)) continue;
381 if (ids.count(id)) continue;
382 measurements.push_back(meas);
383 ids.insert(id);
384 }
385 }
386 return getTruth(truth_tree, measurements, restrictedTruth);
387 }

◆ getTruth() [4/5]

MuonTrackTruth Muon::MuonTrackTruthTool::getTruth ( const TruthTree & truth_tree,
const std::vector< const Trk::MeasurementBase * > & measurements,
bool restrictedTruth = false ) const

get truth for a give set of hits.

If restrictedTruth is set to true only missed hits in chambers with hits will be counted.

Definition at line 389 of file MuonTrackTruthTool.cxx.

390 {
391 MuonTrackTruth bestMatch;
392 bestMatch.truthTrack = nullptr;
393 bestMatch.truthTrajectory = nullptr;
394
395 unsigned int nmatchedHitsBest = 0;
396 // loop over muons and match hits
397 TruthTreeConstIt tit = truth_tree.begin();
398 TruthTreeConstIt tit_end = truth_tree.end();
399 for (; tit != tit_end; ++tit) {
400 unsigned int nhits = tit->second.mdtHits.size() + tit->second.cscHits.size() + tit->second.rpcHits.size() +
401 tit->second.tgcHits.size() + tit->second.stgcHits.size() + tit->second.mmHits.size();
402 if (nhits == 0) continue;
403
404 MuonTrackTruth trackTruth = getTruth(measurements, tit->second, restrictedTruth);
405 unsigned int nmatchedHits = trackTruth.numberOfMatchedHits();
406 ATH_MSG_DEBUG(" performed truth match for particle with barcode: " << tit->first << " overlap " << nmatchedHits << " fraction "
407 << (double)nmatchedHits / (double)nhits);
408 if (nmatchedHits > 0 && nmatchedHits > nmatchedHitsBest) {
409 bestMatch = trackTruth;
410 nmatchedHitsBest = nmatchedHits;
411 }
412 }
413
414 return bestMatch;
415 }

◆ getTruth() [5/5]

MuonTrackTruth Muon::MuonTrackTruthTool::getTruth ( const TruthTree & truth_tree,
const Trk::Track & track,
bool restrictedTruth = false ) const

get track truth

Definition at line 357 of file MuonTrackTruthTool.cxx.

357 {
358 if (track.measurementsOnTrack()) return getTruth(truth_tree, track.measurementsOnTrack()->stdcont(), restrictedTruth);
359 return {};
360 }

◆ initialize()

StatusCode Muon::MuonTrackTruthTool::initialize ( )

AlgTool initilize.

Definition at line 25 of file MuonTrackTruthTool.cxx.

25 {
26 ATH_CHECK(m_idHelperSvc.retrieve());
27 ATH_CHECK(m_printer.retrieve());
29
30 // add muons
31 if (m_pdgsToBeConsidered.value().empty()) {
32 m_selectedPdgs.insert(13);
33 m_selectedPdgs.insert(-13);
34 } else {
35 // add pdgs
36 for (auto pdg : m_pdgsToBeConsidered.value()) { m_selectedPdgs.insert(pdg); }
37 ATH_MSG_DEBUG(" PDG codes used for matching "<<m_selectedPdgs);
38 }
39 return StatusCode::SUCCESS;
40 }
#define ATH_CHECK
Evaluate an expression and check for errors.
Gaudi::Property< std::vector< int > > m_pdgsToBeConsidered
PublicToolHandle< Muon::MuonEDMPrinterTool > m_printer

◆ manipulateBarCode()

int Muon::MuonTrackTruthTool::manipulateBarCode ( int barcode) const
private

Definition at line 42 of file MuonTrackTruthTool.cxx.

42 { // FIXME This is obsolete now
43 if (m_manipulateBarCode) return barcode % 10000;
44 return barcode;
45 }
Gaudi::Property< bool > m_manipulateBarCode

◆ match() [1/2]

MuonTrackTruthTool::SegmentResultVec Muon::MuonTrackTruthTool::match ( const TruthTree & truth_tree,
const std::vector< const MuonSegment * > & segments ) const

perform truth matching for a given set of segments

Definition at line 89 of file MuonTrackTruthTool.cxx.

90 {
91 SegmentResultVec result;
92 result.reserve(segments.size());
93
94 // loop over tracks and match each of them with truth
95 std::vector<const MuonSegment*>::const_iterator sit = segments.begin();
96 std::vector<const MuonSegment*>::const_iterator sit_end = segments.end();
97 for (; sit != sit_end; ++sit) {
98 // create truth association
99 result.emplace_back(*sit, getTruth(truth_tree, **sit));
100 }
101
102 // sort result per muon and per number of matched hits
104
105 return result;
106 }
void stable_sort(DataModel_detail::iterator< DVL > beg, DataModel_detail::iterator< DVL > end)
Specialization of stable_sort for DataVector/List.

◆ match() [2/2]

MuonTrackTruthTool::ResultVec Muon::MuonTrackTruthTool::match ( const TruthTree & truth_tree,
const TrackCollection & tracks ) const

perform truth matching for a given set of tracks

Definition at line 66 of file MuonTrackTruthTool.cxx.

66 {
67 ResultVec result;
68 result.reserve(tracks.size());
69
70 // loop over tracks and match each of them with truth
72 TrackCollection::const_iterator tit_end = tracks.end();
73 for (; tit != tit_end; ++tit) {
74 MuonTrackTruth match = getTruth(truth_tree, **tit);
75 if (!match.truthTrack) continue;
76
77 if (match.numberOfMatchedHits() == 0) continue;
78
79 // create truth association
80 result.emplace_back(*tit, match);
81 }
82
83 // sort result per muon and per number of matched hits
85
86 return result;
87 }
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
ResultVec match(const TruthTree &truth_tree, const TrackCollection &tracks) const
perform truth matching for a given set of tracks

◆ selectPdg()

bool Muon::MuonTrackTruthTool::selectPdg ( int pdg) const
inlineprivate

Definition at line 127 of file MuonTrackTruthTool.h.

127{ return m_selectedPdgs.count(pdg); }

Member Data Documentation

◆ m_doSummary

Gaudi::Property<bool> Muon::MuonTrackTruthTool::m_doSummary {this, "DoSummary", false}
private

Definition at line 141 of file MuonTrackTruthTool.h.

141{this, "DoSummary", false};

◆ m_idHelperSvc

ServiceHandle<Muon::IMuonIdHelperSvc> Muon::MuonTrackTruthTool::m_idHelperSvc {this, "MuonIdHelperSvc", "Muon::MuonIdHelperSvc/MuonIdHelperSvc"}
private

Definition at line 134 of file MuonTrackTruthTool.h.

134{this, "MuonIdHelperSvc", "Muon::MuonIdHelperSvc/MuonIdHelperSvc"};

◆ m_manipulateBarCode

Gaudi::Property<bool> Muon::MuonTrackTruthTool::m_manipulateBarCode {this, "ManipulateBarCode", false}
private

Definition at line 140 of file MuonTrackTruthTool.h.

140{this, "ManipulateBarCode", false};

◆ m_matchAllParticles

Gaudi::Property<bool> Muon::MuonTrackTruthTool::m_matchAllParticles {this, "MatchAllParticles", true}
private

Definition at line 142 of file MuonTrackTruthTool.h.

142{this, "MatchAllParticles", true};

◆ m_minHits

Gaudi::Property<unsigned int> Muon::MuonTrackTruthTool::m_minHits {this, "MinHits", 4}
private

Definition at line 143 of file MuonTrackTruthTool.h.

143{this, "MinHits", 4};

◆ m_pdgsToBeConsidered

Gaudi::Property<std::vector<int> > Muon::MuonTrackTruthTool::m_pdgsToBeConsidered {this, "ConsideredPDGs", {}}
private

Definition at line 144 of file MuonTrackTruthTool.h.

144{this, "ConsideredPDGs", {}};

◆ m_printer

PublicToolHandle<Muon::MuonEDMPrinterTool> Muon::MuonTrackTruthTool::m_printer {this, "Printer", "Muon::MuonEDMPrinterTool/MuonEDMPrinterTool"}
private

Definition at line 136 of file MuonTrackTruthTool.h.

136{this, "Printer", "Muon::MuonEDMPrinterTool/MuonEDMPrinterTool"};

◆ m_selectedPdgs

std::set<int> Muon::MuonTrackTruthTool::m_selectedPdgs
private

Definition at line 146 of file MuonTrackTruthTool.h.

◆ m_truthTrajectoryBuilder

ToolHandle<Trk::ITruthTrajectoryBuilder> Muon::MuonTrackTruthTool::m_truthTrajectoryBuilder
private
Initial value:
{
this, "TruthTrajectoryBuilder", "Muon::MuonDecayTruthTrajectoryBuilder/MuonDecayTruthTrajectoryBuilder"}

Definition at line 137 of file MuonTrackTruthTool.h.

137 {
138 this, "TruthTrajectoryBuilder", "Muon::MuonDecayTruthTrajectoryBuilder/MuonDecayTruthTrajectoryBuilder"};

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