ATLAS Offline Software
Loading...
Searching...
No Matches
MsTrackTester.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4#include "MsTrackTester.h"
5
15
16#include "Acts/Definitions/Units.hpp"
17
18#include <format>
19
20using namespace MuonVal;
21using namespace MuonPRDTest;
22using namespace MuonR4;
23using namespace Acts::UnitLiterals;
24
25namespace {
26 constexpr double MeVtoGeV = 1.e-3;
27 constexpr double toDeg(const double rad) {
28 return rad / 1._degree;
29 }
30 using Location = MsTrackSeeder::Location;
31
32}
33
34namespace MuonValR4 {
35 std::optional<MsTrackSeed> MsTrackTester::makeSeedFromTruth(const ActsTrk::GeometryContext& gctx,
36 const xAOD::TruthParticle& truthMuon) const {
37 std::vector<const xAOD::MuonSegment*> matchedSegs = MuonR4::getTruthSegments(truthMuon);
38 if (matchedSegs.empty()) {
39 return std::nullopt;
40 }
41 ExpandedSector sector{matchedSegs[0]->position().phi()};
43 MsTrackSeed barrelSeed{Location::Barrel, sector};
44 MsTrackSeed endcapSeed{Location::Endcap, sector};
45 for (const xAOD::MuonSegment* seg : matchedSegs) {
46 barrelSeed.addSegment(seg);
47 endcapSeed.addSegment(seg);
48 }
49 barrelSeed.setPosition(matchedSegs[0]->position());
50 endcapSeed.setPosition(matchedSegs[0]->position());
51 const auto [barrelLength, barrelTheta] = calcSeedLength(gctx, barrelSeed);
52 const auto [endcapLength, endcapTheta] = calcSeedLength(gctx, endcapSeed);
53 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - Constructed new seed from truth muon wih pT:"
54 <<(truthMuon.pt()/ Gaudi::Units::GeV)<<" [GeV], eta: "<<truthMuon.eta()
55 <<", phi: "<<toDeg(truthMuon.phi())<<", q: "<<truthMuon.charge()
56 <<", matchedSeg: "<<matchedSegs.size()<< " barrel (L/theta): "<<barrelLength
57 <<"/"<<barrelTheta<<" - endcap (L/theta): "
58 <<endcapLength<<"/"<<endcapTheta<<"\n"<<barrelSeed);
59 if (barrelLength < 0 && endcapLength < 0) {
60 ATH_MSG_WARNING(__func__<<"() "<<__LINE__<<" - Invalid seed");
61 return std::nullopt;
62 }
63 return barrelLength < 0 || std::abs(endcapLength) < barrelLength
64 ? endcapSeed : barrelSeed;
65 }
66
67 std::pair<double, double> MsTrackTester::calcSeedLength(const ActsTrk::GeometryContext& gctx,
68 const MuonR4::MsTrackSeed& seed) const {
69 double maxL{-1.*Gaudi::Units::km}, minL{1.*Gaudi::Units::km},
70 maxTheta{-181.}, minTheta{181};
71 for (const xAOD::MuonSegment* seg : seed.segments()) {
72 const Amg::Vector2D projPos{m_seeder->expressOnCylinder(gctx, *seg, seed.location(), seed.sector())};
73 if (!m_seeder->withinBounds(projPos, seed.location())) {
74 continue;
75 }
76 const double projected = projPos[seed.location()==Location::Barrel];
77 const double theta = seg->direction().theta();
78 minL = std::min(minL, projected);
79 maxL = std::max(maxL, projected);
80 minTheta = std::min(minTheta, toDeg(theta));
81 maxTheta = std::max(maxTheta, toDeg(theta));
82 }
83 return std::make_pair(maxL - minL, maxTheta - minTheta);
84 }
87 ATH_CHECK(m_truthKey.initialize(m_isMC));
88
89 ATH_CHECK(m_muonKey.initialize());
90 ATH_CHECK(m_msTrkSeedKey.initialize());
91 ATH_CHECK(m_recoSegmentKey.initialize());
92
93 ATH_CHECK(m_segSelector.retrieve());
94 ATH_CHECK(m_summaryTool.retrieve());
95
96 ATH_CHECK(m_geoCtxKey.initialize());
97 ATH_CHECK(m_fieldCacheKey.initialize());
98
99 ATH_CHECK(m_legacyMuonKey.initialize(!m_legacyMuonKey.empty()));
100 ATH_CHECK(m_legacyTrackKey.initialize(!m_legacyMuonKey.empty()));
101 ATH_CHECK(m_legacySegmentKey.initialize(!m_legacyMuonKey.empty()));
102
103 ATH_CHECK(detStore()->retrieve(m_detMgr));
104
105 MsTrackSeeder::Config seederCfg{};
106 seederCfg.detMgr = m_detMgr;
107 seederCfg.seedHalfLength = 2.*Gaudi::Units::m;
108 seederCfg.endcapDiscRadius = 40.*Gaudi::Units::m;
109 m_seeder = std::make_unique<MuonR4::MsTrackSeeder>(name(), std::move(seederCfg));
110
111 int evOpts{0};
112
113 m_recoSegs = std::make_unique<SegmentVariables>(m_tree, m_recoSegmentKey.key(), "Segments", msgLevel());
115 "Segments_passSeedQual",[this](const SG::AuxElement* aux){
116 const auto* seg = static_cast<const xAOD::MuonSegment*>(aux);
117 return m_segSelector->passSeedingQuality(Gaudi::Hive::currentContext(),
118 *MuonR4::detailedSegment(*seg)); }));
120 "Segments_passTrackQual",[this](const SG::AuxElement* aux){
121 const auto* seg = static_cast<const xAOD::MuonSegment*>(aux);
122 return m_segSelector->passTrackQuality(Gaudi::Hive::currentContext(),
124 }));
125
126
127 if (m_isMC) {
128 evOpts |= EventInfoBranch::isMC;
130 "Segments_truthSegLink",[this](const SG::AuxElement* aux){
131 const auto* seg = static_cast<const xAOD::MuonSegment*>(aux);
133 const unsigned linkIdx = truthS ? m_truthSegs->push_back(*truthS) : -1;
135 if (truthS) {
136 m_truthSegToRecoLink.push_back(linkIdx, m_recoSegs->push_back(*seg));
137 const xAOD::TruthParticle* truthMuon = MuonR4::getTruthMatchedParticle(*truthS);
138 if (truthMuon){
139 m_truthTrks->push_back(truthMuon);
140 m_truthMuRecoSegLinks[m_truthTrks->find(truthMuon)].push_back(m_recoSegs->push_back(*seg));
141 }
142 }
143 return linkIdx;
144 }));
145
146 m_truthSegs = std::make_unique<SegmentVariables>(m_tree, m_truthSegmentKey.key(), "TruthSegments", msgLevel());
147
149 "TruthSegments_truthLink",[this](const SG::AuxElement* aux){
150 const auto* seg = static_cast<const xAOD::MuonSegment*>(aux);
152 m_truthTrks->push_back(truthP);
153 unsigned short linkIdx = m_truthTrks->find(truthP);
154 return linkIdx;
155 }));
156 for (auto loc : {Location::Barrel, Location::Endcap}) {
158 std::format("TruthSegments_has{}Proj", loc), [loc, this](const SG::AuxElement* aux){
159 const auto* seg = static_cast<const xAOD::MuonSegment*>(aux);
160 const ActsTrk::GeometryContext* gctx{nullptr};
161 SG::get(gctx, m_geoCtxKey, Gaudi::Hive::currentContext()).ignore();
162 ExpandedSector sector{seg->position().phi()};
163 const Amg::Vector2D projPos{m_seeder->expressOnCylinder(*gctx, *seg, loc, sector)};
164 if (m_seeder->withinBounds(projPos, loc)) {
165 return 1;
166 }
167 return 0;
168 }));
169 }
170
171 m_tree.addBranch(m_truthSegs);
172
173 m_truthTrks = std::make_unique<IParticleFourMomBranch>(m_tree, "TruthMuons");
174 m_truthTrks->addVariable<int>(-1, "truthOrigin");
175 m_truthTrks->addVariable<int>(-1, "truthType");
177 m_truthTrks->addVariable(
179 std::vector<unsigned short>>>(m_tree,
180 std::format("{:}_truthSegLinks", m_truthTrks->name()), [&] (const xAOD::TruthParticle& p){
181 std::vector<unsigned short> idx{};
182 for (const xAOD::MuonSegment* truthSeg: getTruthSegments(p)){
183 idx.push_back(m_truthSegs->push_back(*truthSeg));
184 }
185 return idx;
186 }));
188 m_truthTrks->addVariable(
190 std::format("{:}_nTruthSegments", m_truthTrks->name()), [&] (const xAOD::TruthParticle& p) -> unsigned short {
191 return getTruthSegments(p).size();
192 }));
194 m_truthTrks->addVariable(
196 std::format("{:}_qTimesPalpha", m_truthTrks->name()), [&] (const xAOD::TruthParticle& p) -> float {
197 const auto truthSegs = getTruthSegments(p);
198 if (truthSegs.size() < 2) {
199 return 0.f;
200 }
201 const AtlasFieldCacheCondObj* magCache{nullptr};
202 (void) SG::get(magCache, m_fieldCacheKey, Gaudi::Hive::currentContext()).isSuccess();
203
204 return toDeg(m_seeder->estimateTwoStationP(*truthSegs.front(), *truthSegs.back(),
205 *magCache)) ;
206 }));
208 auto cone = std::make_shared<VectorBranch<float>>(m_tree,
209 std::format("{}_seedThetaCone", m_truthTrks->name()));
210 auto qTimesP = std::make_shared<VectorBranch<float>>(m_tree,
211 std::format("{}_qTimesP", m_truthTrks->name()));
212
213 m_tree.addBranch(cone);
214 m_tree.addBranch(qTimesP);
215 m_truthTrks->addVariable(
217 std::format("{:}_seedLength", m_truthTrks->name()), [cone, qTimesP, this] (const xAOD::TruthParticle& p) -> float {
218 const ActsTrk::GeometryContext* gctx{nullptr};
219 const AtlasFieldCacheCondObj* magCache{nullptr};
220 const EventContext& ctx{Gaudi::Hive::currentContext()};
221 (void) SG::get(magCache, m_fieldCacheKey, ctx).isSuccess();
222 (void) SG::get(gctx, m_geoCtxKey, ctx).isSuccess();
223
224 auto truthSeed = makeSeedFromTruth(*gctx, p);
225 if (!truthSeed) {
226 cone->push_back(-1);
227 qTimesP->push_back(0);
228 return -1.;
229 }
230 auto [length, theta] = calcSeedLength(*gctx, *truthSeed);
231 cone->push_back(theta);
232 qTimesP->push_back(m_seeder->estimateQtimesP(*gctx, *magCache, *truthSeed) / Gaudi::Units::GeV);
233
234 return length;
235 }));
236
237 m_tree.addBranch(m_truthTrks);
238 m_trkTruthLinks.emplace_back(m_truthSegmentKey, "truthParticleLink");
239 m_trkTruthLinks.emplace_back(m_truthKey, "truthSegmentLinks");
240 m_trkTruthLinks.emplace_back(m_recoSegmentKey, "truthSegmentLink");
241 m_trkTruthLinks.emplace_back(m_muonKey, "truthParticleLink");
242 }
243
244 m_tree.addBranch(m_recoSegs);
245 m_tree.addBranch(std::make_unique<EventInfoBranch>(m_tree, evOpts));
246
247 static const std::vector<std::string> trackSummaries{
248 // Inner
249 "innerSmallHits", "innerLargeHits", "innerSmallHoles", "innerLargeHoles",
250 // Middle
251 "middleSmallHits", "middleLargeHits", "middleSmallHoles",
252 "middleLargeHoles",
253 // Outer
254 "outerSmallHits", "outerLargeHits", "outerSmallHoles", "outerLargeHoles",
255 // Extended
256 "extendedSmallHits", "extendedLargeHits", "extendedSmallHoles",
257 "extendedLargeHoles",
258 "innerTriggerEtaHits", "innerTriggerPhiHits",
259 "middleTriggerEtaHits", "middleTriggerPhiHits",
260 "outerTriggerEtaHits", "outerTriggerPhiHits",
261
262 "innerTriggerEtaHoles", "innerTriggerPhiHoles",
263 "middleTriggerEtaHoles", "middleTriggerPhiHoles",
264 "outerTriggerEtaHoles", "outerTriggerPhiHoles",
265 };
266 if(!m_legacyTrackKey.empty()) {
267 m_legacyTrks = std::make_unique<IParticleFourMomBranch>(m_tree, "LegacyMSTrks");
268 m_legacyTrks->addVariable(std::make_unique<TrackChi2Branch>(*m_legacyTrks));
269 if (m_isMC) {
270 BilateralLinkerBranch::connectCollections(m_legacyTrks, m_truthTrks, [](const xAOD::IParticle* trk){
271 return xAOD::TruthHelpers::getTruthParticle(*trk); }, "truth", "LegacyMS");
272 }
273 for (const auto& summary : trackSummaries) {
274 m_legacyTrks->addVariable<uint8_t>(-1, summary);
275 }
276 m_tree.addBranch(m_legacyTrks);
277 m_legacyRecoSegs = std::make_unique<SegmentVariables>(m_tree, m_legacySegmentKey.key(), "LegacyRecoSegments", msgLevel());
278 m_tree.addBranch(m_legacyRecoSegs);
279 }
280
281 m_seedSummary = std::make_shared<TrackSummaryModule>(m_tree, "MsTrkSeed", m_summaryTool.get());
282 m_muonTrks = std::make_shared<IParticleFourMomBranch>(m_tree, "ActsMuons");
283 m_muonTrks->addVariable(std::make_unique<TrackChi2Branch>(*m_muonTrks));
284 m_muonTrks->addVariable<uint16_t>("allAuthors");
285 m_muonTrks->addVariable<uint16_t>("author");
287 m_muonTrks->addVariable(std::make_unique<GenericPartDecorBranch<xAOD::Muon,
288 std::vector<unsigned short>>>(m_tree,
289 std::format("{:}_segmentLinks", m_muonTrks->name()), [&] (const xAOD::Muon& p){
290 std::vector<unsigned short> idx{};
291 for (unsigned seg = 0 ; seg < p.nMuonSegments(); ++seg) {
292 idx.push_back(m_recoSegs->push_back(*p.muonSegment(seg)));
293 }
294 return idx;
295 }));
297 m_muonTrks->addVariable(std::make_unique<GenericPartDecorBranch<xAOD::Muon, unsigned short>>(m_tree,
298 std::format("{:}_seedLink", m_muonTrks->name()), [&] (const xAOD::Muon& p) -> unsigned short {
299 using enum xAOD::Muon::TrackParticleType;
300 const xAOD::TrackParticle* msTrack = p.trackParticle(MuonSpectrometerTrackParticle);
301 if (!msTrack) {
302 return -1;
303 }
304 auto actsTrk = ActsTrk::getActsTrack(*msTrack);
305 if (!actsTrk) {
306 THROW_EXCEPTION("Cannot find the associated ms track from the primary track");
307 }
308 return actsTrk->component<std::size_t>("parentSeed");
309 }));
310
311 if (m_isMC) {
312 BilateralLinkerBranch::connectCollections(m_muonTrks, m_truthTrks,
313 [](const xAOD::IParticle* trk) -> const xAOD::TruthParticle* {
315 }, "truth", "ActsMuon");
316 }
317
318 for (const auto& summary : trackSummaries) {
319 m_muonTrks->addVariable<uint8_t>(summary);
320 }
321 m_tree.addBranch(m_muonTrks);
322
323 m_tree.addBranch(m_seedSummary);
324
325 ATH_CHECK(m_trkTruthLinks.initialize());
326 ATH_CHECK(m_tree.init(this));
327 return StatusCode::SUCCESS;
328 }
329 StatusCode MsTrackTester::dumpLegacyTracks(const EventContext& ctx) {
330
331 //This for now is to be able to retrieve the matching between the legacy segments and tracks ...
332 const xAOD::MuonContainer* legacyMuons{nullptr};
333 ATH_CHECK(SG::get(legacyMuons, m_legacyMuonKey, ctx));
334
335 if (!legacyMuons) {
336 return StatusCode::SUCCESS;
337 }
338
339 for (const xAOD::Muon* muon : *legacyMuons) {
340 ATH_MSG_VERBOSE("iMuon " << muon->index() << " pT: "<<(muon->pt() *MeVtoGeV)<<" [GeV], eta: "
341 <<muon->eta() <<", phi: "<<toDeg(muon->phi())<<", q: "<<muon->charge()
342 <<", nSegments: "<<muon->nMuonSegments());
343 const xAOD::TrackParticle* track = muon->trackParticle(xAOD::Muon::TrackParticleType::MuonSpectrometerTrackParticle);
344 if (!track) {
345 continue;
346 }
347 m_summaryTool->copySummary(m_summaryTool->makeSummary(ctx, *track->track()), *track);
348 m_legacyTrks->push_back(track);
349 auto trkIdx = m_legacyTrks->find(track);
350 for (size_t s = 0; s < muon->nMuonSegments(); ++s) {
351 const xAOD::MuonSegment* segment = muon->muonSegment(s);
352 auto segIdx = m_legacyRecoSegs->push_back(*segment);
353 ATH_MSG_VERBOSE(std::format( "Legacy muon-segment link: segment {:} @{:}, eta: {:.2f}, phi {:.2f}",
354 printID(*segment), Amg::toString(segment->position()),
355 segment->direction().eta(), toDeg(segment->direction().phi())));
356 m_legacySegToTrkLinks[segIdx] = trkIdx;
357 }
358 }
359
360 //Dump also legacy segments
361 const xAOD::MuonSegmentContainer* legacyRecoSegs{nullptr};
362 ATH_CHECK(SG::get(legacyRecoSegs, m_legacySegmentKey, ctx));
363
364 if (legacyRecoSegs->size()) {
365 m_legacySegToTrkLinks[legacyRecoSegs->size()-1];
366 for (const xAOD::MuonSegment* seg : *legacyRecoSegs) {
367 //Store all segments
368 m_legacyRecoSegs->push_back(*seg);
369 }
370 }
371
372 const xAOD::TrackParticleContainer* legacyTrks{nullptr};
373 ATH_CHECK(SG::get(legacyTrks, m_legacyTrackKey, ctx));
374
375 for (const xAOD::TrackParticle* track : *legacyTrks) {
376 m_summaryTool->copySummary(m_summaryTool->makeSummary(ctx, *track->track()), *track);
377 m_legacyTrks->push_back(track);
378 }
379
380 return StatusCode::SUCCESS;
381 }
382 StatusCode MsTrackTester::dumpTruthContent(const EventContext& ctx) {
383 if (!m_isMC) {
384 return StatusCode::SUCCESS;
385 }
386 const xAOD::MuonSegmentContainer* truthSegs{nullptr};
387 ATH_CHECK(SG::get(truthSegs, m_truthSegmentKey, ctx));
388
389 const ActsTrk::GeometryContext* gctx{nullptr};
390 ATH_CHECK(SG::get(gctx, m_geoCtxKey, ctx));
391
392 const AtlasFieldCacheCondObj* magCache{nullptr};
393 ATH_CHECK(SG::get(magCache, m_fieldCacheKey, ctx));
394
395 for (const xAOD::MuonSegment* seg : *truthSegs) {
396 ATH_MSG_VERBOSE("Dump truth segment "<<printID(*seg)<<" @"<<
397 Amg::toString(seg->position())<<", eta: "<<seg->direction().eta()
398 <<", phi: "<<toDeg(seg->direction().phi()));
399 m_truthSegs->push_back(*seg);
400 }
401 if (truthSegs->size()) {
402 m_truthSegToRecoLink[truthSegs->size()-1];
403 }
404
405
406 const xAOD::TruthParticleContainer* truthMuons{nullptr};
407 ATH_CHECK(SG::get(truthMuons, m_truthKey, ctx));
408 const std::size_t nT = truthMuons->size() - 1;
409 if (!truthMuons->empty()) {
414 }
415
416 for (const xAOD::TruthParticle* truth : *truthMuons) {
417 ATH_MSG_DEBUG("Truth muon: pT: "<<(truth->pt() *MeVtoGeV)
418 <<", eta: "<<truth->eta()<<", phi: "<<toDeg(truth->phi())<<", q: "<<truth->charge());
419 m_truthTrks->push_back(*truth);
420 }
421
422 return StatusCode::SUCCESS;
423 }
424 StatusCode MsTrackTester::dumpRecoContent(const EventContext& ctx) {
425 const xAOD::MuonContainer* muons{nullptr};
426 ATH_CHECK(SG::get(muons, m_muonKey, ctx));
428 const xAOD::MuonSegmentContainer* recoSegments{nullptr};
429 ATH_CHECK(SG::get(recoSegments, m_recoSegmentKey, ctx));
430
431 const MuonR4::MsTrackSeedContainer* trkSeeds{nullptr};
432 ATH_CHECK(SG::get(trkSeeds, m_msTrkSeedKey, ctx));
433
434 const ActsTrk::GeometryContext* gctx{nullptr};
435 ATH_CHECK(SG::get(gctx, m_geoCtxKey, ctx));
436
437 const AtlasFieldCacheCondObj* magCache{nullptr};
438 ATH_CHECK(SG::get(magCache, m_fieldCacheKey, ctx));
439
440 std::unordered_map<const xAOD::TruthParticle*,
441 std::vector<unsigned>> truthToSeedMatchCounter{};
442
443 if (!trkSeeds->empty()) {
444 m_seedTruthLink[trkSeeds->size() -1];
445 }
446
447 for (const MuonR4::MsTrackSeed& seed : *trkSeeds) {
448 unsigned int seedIdx = m_seedPos.size();
449 m_seedPos += seed.position();
450 m_seedType+= Acts::toUnderlying(seed.location());
451 m_seedSector += seed.sector().sector();
452 m_seedSummary->push_back(ctx, seed);
453 ATH_MSG_VERBOSE(" Dump new seed: "<<seed);
454 for (const xAOD::MuonSegment* seg : seed.segments()){
455 m_seedRecoSegMatch[seedIdx].push_back(m_recoSegs->push_back(*seg));
456 if (const xAOD::MuonSegment* truthSeg = MuonR4::getMatchedTruthSegment(*seg);
457 truthSeg != nullptr) {
458 std::vector<unsigned>& matchCounter = truthToSeedMatchCounter[MuonR4::getTruthMatchedParticle(*truthSeg)];
459 if (seedIdx >= matchCounter.size()) {
460 matchCounter.resize(seedIdx +1);
461 }
462 ++matchCounter[seedIdx];
463 }
464 }
465 const auto[seedLength, theta] = calcSeedLength(*gctx, seed);
466 m_seedLength+= seedLength;
468 m_seedQP += m_seeder->estimateQtimesP(*gctx, *magCache, seed) / Gaudi::Units::GeV;
469 }
471 for (auto& [truthMuon, matches] : truthToSeedMatchCounter) {
472 const unsigned tIndex = m_truthTrks->find(truthMuon);
473 if (tIndex >= m_truthTrks->size()) {
474 continue;
475 }
477 while (std::count_if(matches.begin(), matches.end(),
478 [](const unsigned nMatched){
479 return nMatched > 0;
480 })) {
481 auto bestMatch = std::ranges::max_element(matches);
482 const std::size_t seedIdx = std::distance(matches.begin(), bestMatch);
483 m_truthMuToSeedIdx[tIndex].push_back(seedIdx);
484
485 m_seedTruthLink[seedIdx] = tIndex;
486 m_truthMuToSeedCounter[tIndex].push_back(*bestMatch);
487 (*bestMatch) = 0;
488 }
489 }
490
491 for (const xAOD::Muon* muon : *muons) {
492 m_muonTrks->push_back(muon);
493 }
494
495 for (const xAOD::MuonSegment* seg : *recoSegments) {
496 m_recoSegs->push_back(*seg);
497 }
498
499 return StatusCode::SUCCESS;
500 }
501 StatusCode MsTrackTester::execute(const EventContext& ctx) {
505
506 ATH_CHECK(m_tree.fill(ctx));
507 return StatusCode::SUCCESS;
508 }
510 ATH_CHECK(m_tree.write());
511 return StatusCode::SUCCESS;
512 }
513}
Scalar theta() const
theta method
#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)
double length(const pvec &v)
if(pathvar)
Handle class for reading from StoreGate.
const ServiceHandle< StoreGateSvc > & detStore() const
StatusCode addVariable(const std::string &name, T *&ptr, const std::string &docstring="")
Add a variable to the tuple.
size_type size() const noexcept
Returns the number of elements in the collection.
bool empty() const noexcept
Returns true if the collection is empty.
void addSegment(const xAOD::MuonSegment *seg)
Append a segment to the seed.
void setPosition(Amg::Vector3D &&pos)
set the seed's position
MsTrackSeed::Location Location
Enum toggling whether the segment is in the endcap or barrel.
const MuonGMR4::MuonDetectorManager * m_detMgr
std::optional< MuonR4::MsTrackSeed > makeSeedFromTruth(const ActsTrk::GeometryContext &gctx, const xAOD::TruthParticle &truthMuon) const
Construct MS track seed from the truth associated segments.
ToolHandle< MuonR4::ITrackSummaryTool > m_summaryTool
Hit summary tool.
StatusCode dumpLegacyTracks(const EventContext &ctx)
Dumps the legacy containers to the TTree.
SegmentKey_t m_legacySegmentKey
Legacy segment container.
MuonVal::VectorBranch< unsigned short > & m_legacySegToTrkLinks
Link of the legacy track to the legacy segment.
ParticleBranchPtr_t m_truthTrks
std::unique_ptr< MuonR4::MsTrackSeeder > m_seeder
MuonVal::VectorBranch< int > & m_seedSector
Sector of the seed, even center, odd overlap regions, for details see:
MuonVal::VectorBranch< float > & m_seedThetaCone
Maximum angular difference between the segments part of the seed.
ParticleBranchPtr_t m_legacyTrks
Output branches of the legacy MS tracks.
SegmentBranchPtr_t m_truthSegs
SegmentBranchPtr_t m_legacyRecoSegs
MuonVal::MatrixBranch< unsigned short > & m_truthMuRecoSegLinks
Links from the truth muon to the segments.
MuonVal::MatrixBranch< unsigned short > & m_truthMuToSeedIdx
Links to all MsTrkSeeds that could be matched to the truthMuon, i.e.
TrackKey_t m_legacyTrackKey
Legacy track reconstruction chain.
ActsTrk::GeoContextReadKey_t m_geoCtxKey
Dependency on the geometry alignment.
StatusCode execute(const EventContext &ctx) override final
Execute method.
MuonVal::VectorBranch< char > & m_seedType
Is the seed in the encap or in the barrel chambers.
StatusCode dumpRecoContent(const EventContext &ctx)
Dump the reconstructed information.
SG::ReadHandleKey< xAOD::TruthParticleContainer > m_truthKey
Key to the truth particle collection.
Gaudi::Property< bool > m_isMC
ParticleBranchPtr_t m_muonTrks
Stored muon information from the Acts muon reco chain.
MuonVal::MatrixBranch< unsigned short > & m_truthSegToRecoLink
Link of the truth segments to the matchin reco segments.
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCacheKey
Dependency on the magnetic field.
SegmentBranchPtr_t m_recoSegs
StatusCode dumpTruthContent(const EventContext &ctx)
Dump truth information.
SG::ReadHandleKey< MuonR4::MsTrackSeedContainer > m_msTrkSeedKey
Temporary container write handle to push the seeds to store gate for later efficiency analysis.
StatusCode initialize() override final
MuonVal::MatrixBranch< unsigned short > & m_seedRecoSegMatch
Link of the track seed to the building segment.
MuonVal::VectorBranch< float > & m_seedQP
Estimated momentum times charge from the track seed.
MuonVal::MatrixBranch< unsigned short > & m_truthMuToSeedCounter
Number of matched segments in the seed.
MuonVal::ThreeVectorBranch m_seedPos
Simple seed information.
MuonKey_t m_legacyMuonKey
Legacy muons.
MuonVal::VectorBranch< float > & m_seedLength
Maximum separation between the segments on the reference plane.
ToolHandle< MuonR4::ISegmentSelectionTool > m_segSelector
Segment selection tool to pick the good quality segments.
SegmentKey_t m_recoSegmentKey
Primary segment container.
MuonVal::MuonTesterTree m_tree
SegmentKey_t m_truthSegmentKey
Segment from the truth hits.
StatusCode finalize() override final
std::shared_ptr< TrackSummaryModule > m_seedSummary
Hit summary on the track seed.
MuonVal::VectorBranch< unsigned short > & m_seedTruthLink
Link to the truth muon.
std::pair< double, double > calcSeedLength(const ActsTrk::GeometryContext &gctx, const MuonR4::MsTrackSeed &seed) const
Calculate the length of the seed and the theta deflection angle The length is defined as the spread o...
MuonKey_t m_muonKey
Dependency on the R4 muon container.
static bool connectCollections(ParticleBranch_ptr primColl, ParticleBranch_ptr secondColl, Linker_t fromPrimToSec, const std::string &altPrimName="", const std::string &altSecName="")
@ isMC
Flag determining whether the branch is simulation.
Generic branch object where the information is evaluated by a std::function instead reading it from t...
Class providing the definition of the 4-vector interface.
Amg::Vector3D direction() const
Returns the direction as Amg::Vector.
Amg::Vector3D position() const
Returns the position as Amg::Vector.
std::optional< ActsTrk::TrackContainer::ConstTrackProxy > getActsTrack(const xAOD::TrackParticle &trkPart)
Return the proxy to the Acts track from which the track particle was made frome.
Definition Decoration.cxx:9
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Eigen::Matrix< double, 2, 1 > Vector2D
constexpr float MeVtoGeV
ID3PD * m_tree
Pointer to the ID3PD object used.
for(size_t i=0;i< m_blockFillers.size();i++)
Fill one block.
This header ties the generic definitions in this package.
const xAOD::TruthParticle * getTruthMatchedParticle(const xAOD::MuonSegment &segment)
Returns the particle truth-matched to the segment.
std::vector< MsTrackSeed > MsTrackSeedContainer
Definition MsTrackSeed.h:71
std::string printID(const xAOD::MuonSegment &seg)
Print the chamber ID of a segment, e.g.
std::vector< const xAOD::MuonSegment * > getTruthSegments(const xAOD::TruthParticle &truthMuon)
Returns the segments associated to the truth muon.
const xAOD::MuonSegment * getMatchedTruthSegment(const xAOD::MuonSegment &segment)
Returns the truth-matched segment.
const Segment * detailedSegment(const xAOD::MuonSegment &seg)
Helper function to navigate from the xAOD::MuonSegment to the MuonR4::Segment.
Lightweight algorithm to read xAOD MDT sim hits and (fast-digitised) drift circles from SG and fill a...
Class to store array like branches into the n-tuples.
Definition HitValAlg.cxx:19
AuxElement(SG::AuxVectorData *container, size_t index)
Base class for elements of a container that can have aux data.
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
const xAOD::TruthParticle * getTruthParticle(const xAOD::IParticle &p)
Return the truthParticle associated to the given IParticle (if any).
MuonSegmentContainer_v1 MuonSegmentContainer
Definition of the current "MuonSegment container version".
TrackParticle_v1 TrackParticle
Reference the current persistent version:
TruthParticle_v1 TruthParticle
Typedef to implementation.
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
Muon_v1 Muon
Reference the current persistent version:
setWord1 uint16_t
MuonContainer_v1 MuonContainer
Definition of the current "Muon container version".
MuonSegment_v1 MuonSegment
Reference the current persistent version:
TruthParticleContainer_v1 TruthParticleContainer
Declare the latest version of the truth particle container.
Configuration object.
double endcapDiscRadius
Radius of the endcap discs.
const MuonGMR4::MuonDetectorManager * detMgr
Detector manager to fetch the sector enevelope transforms.
double seedHalfLength
Maximum separation of point on the cylinder to be picked up onto a seed.
#define THROW_EXCEPTION(MESSAGE)
Definition throwExcept.h:10