14 #include "Acts/Definitions/Units.hpp"
21 using namespace Acts::UnitLiterals;
32 constexpr
int overlapSector(
const int sec1 ,
const int sec2) {
34 if (sec2 > sec1)
return overlapSector(sec2, sec1);
35 if (sec1 == 1 && sec2 == nSec)
return 0;
44 int secMax{-1}, secMin{100};
46 if (matchedSegs.empty()) {
50 secMax =
std::max(secMax, seg->sector());
51 secMin =
std::min(secMin, seg->sector());
53 const int orSec = overlapSector(secMax, secMin);
58 barrelSeed.addSegment(seg);
59 endcapSeed.addSegment(seg);
61 barrelSeed.setPosition(matchedSegs[0]->position());
62 endcapSeed.setPosition(matchedSegs[0]->position());
63 const auto [barrelLength, barrelTheta] = calcSeedLength(gctx, barrelSeed);
64 const auto [endcapLength, endcapTheta] = calcSeedLength(gctx, endcapSeed);
65 ATH_MSG_VERBOSE(__func__<<
"() "<<__LINE__<<
" - Constructed new seed from truth muon wih pT:"
68 <<
", matchedSeg: "<<matchedSegs.size()<<
" barrel (L/theta): "<<barrelLength
69 <<
"/"<<(barrelTheta / 1._degree)<<
" - endcap (L/theta): "
70 <<endcapLength<<
"/"<<(endcapTheta / 1._degree)<<
"\n"<<barrelSeed);
71 if (barrelLength < 0 && endcapLength < 0) {
75 return barrelLength < 0 || std::abs(endcapLength) < barrelLength
76 ? endcapSeed : barrelSeed;
84 const auto secProj = m_seeder->projectorFromSeed(*seg, seed);
85 const Amg::Vector2D projPos{m_seeder->expressOnCylinder(gctx, *seg, seed.location(), secProj)};
86 if (!m_seeder->withinBounds(projPos, seed.location())) {
90 const double theta = seg->direction().theta();
96 return std::make_pair(maxL - minL, maxTheta - minTheta);
99 ATH_CHECK(m_truthSegmentKey.initialize(m_isMC));
100 ATH_CHECK(m_truthKey.initialize(m_isMC));
102 ATH_CHECK(m_recoSegmentKey.initialize());
106 ATH_CHECK(m_legacyTrackKey.initialize(
false));
110 seederCfg.
detMgr = m_detMgr;
113 m_seeder = std::make_unique<MuonR4::MsTrackSeeder>(
name(), std::move(seederCfg));
117 m_recoSegs = std::make_unique<SegmentVariables>(m_tree, m_recoSegmentKey.key(),
"Segments", msgLevel());
121 return m_segSelector->passSeedingQuality(Gaudi::Hive::currentContext(),
126 return m_segSelector->passTrackQuality(Gaudi::Hive::currentContext(),
135 const unsigned linkIdx = truthS ? m_truthSegs->push_back(*truthS) : -1;
138 m_truthSegToRecoLink.push_back(linkIdx, m_recoSegs->push_back(*seg));
142 m_truthMuRecoSegLinks[m_truthTrks->find(
truthMuon)].push_back(m_recoSegs->push_back(*seg));
148 m_truthSegs = std::make_unique<SegmentVariables>(m_tree, m_truthSegmentKey.key(),
"TruthSegments", msgLevel());
154 m_truthTrks->push_back(truthP);
155 unsigned short linkIdx = m_truthTrks->find(truthP);
162 SG::get(gctx, m_geoCtxKey, Gaudi::Hive::currentContext()).ignore();
164 for (
const auto proj : {leftOverlap, center, rightOverlap}) {
177 SG::get(gctx, m_geoCtxKey, Gaudi::Hive::currentContext()).ignore();
179 for (
const auto proj : {leftOverlap, center, rightOverlap}) {
187 m_tree.addBranch(m_truthSegs);
189 m_truthTrks = std::make_unique<IParticleFourMomBranch>(m_tree,
"TruthMuons");
190 m_tree.addBranch(m_truthTrks);
191 m_trkTruthLinks.emplace_back(m_truthSegmentKey,
"truthParticleLink");
192 m_trkTruthLinks.emplace_back(m_truthKey,
"truthSegmentLinks");
193 m_trkTruthLinks.emplace_back(m_recoSegmentKey,
"truthSegmentLink");
196 m_tree.addBranch(m_recoSegs);
197 m_tree.addBranch(std::make_unique<EventInfoBranch>(m_tree, evOpts));
198 m_tree.addBranch(std::make_unique<TrackContainerModule>(m_tree,
"MsTracks", msgLevel()));
200 if(!m_legacyTrackKey.empty()) {
201 m_legacyTrks = std::make_unique<IParticleFourMomBranch>(m_tree,
"LegacyMSTrks");
202 m_legacyTrks->addVariable(std::make_unique<TrackChi2Branch>(*m_legacyTrks));
207 m_tree.addBranch(m_legacyTrks);
212 return StatusCode::SUCCESS;
215 const EventContext& ctx{Gaudi::Hive::currentContext()};
221 m_legacyTrks->push_back(
track);
227 if (recoSegments->empty()){
228 return StatusCode::SUCCESS;
237 std::map<const xAOD::TruthParticle*, std::vector<unsigned>> truthToSeedMatchCounter{};
239 unsigned int seedIdx = m_seedPos.size();
240 m_seedPos += seed.position();
241 m_seedType+= Acts::toUnderlying(seed.location());
245 m_seedRecoSegMatch[seedIdx].push_back(m_recoSegs->push_back(*seg));
247 truthSeg !=
nullptr) {
249 if (seedIdx >= matchCounter.size()) {
250 matchCounter.resize(seedIdx +1);
252 ++matchCounter[seedIdx];
255 const auto[seedLength,
theta] = calcSeedLength(*gctx, seed);
256 m_seedLength+= seedLength;
257 m_seedThetaCone+=
theta;
258 m_seedQP += m_seeder->estimateQtimesP(*gctx, *magCache, seed) /
Gaudi::Units::GeV;
261 m_recoSegs->push_back(*seg);
269 chName(seg->chamberIndex()), std::abs(seg->etaIndex()),
270 seg->etaIndex() > 0 ?
'A' :
'C', seg->sector(),
272 seg->direction().eta(), seg->direction().phi() / 1._degree));
274 m_truthSegs->push_back(*seg);
276 if (truthSegs->size()) {
277 m_truthSegToRecoLink[truthSegs->size()-1];
283 if (truthMuons && truthMuons->size()) {
285 m_truthMuToSeedIdx[truthMuons->size() -1];
286 m_truthMuToSeedCounter[truthMuons->size() -1];
287 m_truthMuTruthSegLinks[truthMuons->size() -1];
288 m_truthMuRecoSegLinks[truthMuons->size() -1];
292 <<
", phi: "<<(truth->phi() / 1._degree)<<
", q: "<<truth->charge());
294 m_truthTrks->push_back(*truth);
295 unsigned truthIdx = m_truthTrks->find(truth);
296 std::vector<unsigned>& matchCounter = truthToSeedMatchCounter[truth];
299 while ( (maxSeed = std::ranges::max_element(matchCounter))!=matchCounter.end() && (*maxSeed) > 0) {
300 m_truthMuToSeedIdx[truthIdx].push_back(
std::distance(matchCounter.begin(), maxSeed));
301 m_truthMuToSeedCounter[truthIdx].push_back(*maxSeed);
305 std::vector<unsigned short>& truthSegLinks = m_truthMuTruthSegLinks[truthIdx];
306 const std::vector<const xAOD::MuonSegment*> truthSegs =
getTruthSegments(*truth);
307 m_truthMuTruthNSegs += truthSegs.size();
309 truthSegLinks.push_back(m_truthSegs->push_back(*truthSeg));
312 auto truthSeed = makeSeedFromTruth(*gctx, *truth);
314 m_truthMuonsSeedLength[truthIdx] = -1;
315 m_truthMuonsSeedCone[truthIdx] = -1;
316 m_truthMuonQP[truthIdx] =0;
318 const auto [
length, cone] = calcSeedLength(*gctx, *truthSeed);
319 m_truthMuonsSeedLength[truthIdx] =
length;
320 m_truthMuonsSeedCone [truthIdx] = cone;
321 m_truthMuonQP[truthIdx] = m_seeder->estimateQtimesP(*gctx, *magCache, *truthSeed) /
Gaudi::Units::GeV;
327 return StatusCode::SUCCESS;
331 return StatusCode::SUCCESS;