ATLAS Offline Software
Loading...
Searching...
No Matches
MuonFastSABuilderAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6
9#include "Acts/Utilities/VectorHelpers.hpp"
10
11namespace {
13 double inDeg(double angle) {
14 return angle / Gaudi::Units::deg;
15 }
17 std::string print(const xAOD::Muon& muon) {
18 std::ostringstream oss;
19 using namespace MuonR4::FastReco;
20 const double P {muon.pt() * std::cosh(muon.eta())};
21 const double momUncertainty {std::sqrt(getQOverPCov(muon)*std::pow(P,4))};
22 oss<<"Eta: "<<muon.eta()<<", Phi: "<<inDeg(muon.phi())
23 <<", Pt: "<<muon.pt()/Gaudi::Units::GeV<<" GeV, Charge: "<<muon.charge()
24 <<", P: "<<P/ Gaudi::Units::GeV<<" += "<<momUncertainty/Gaudi::Units::GeV
25 <<" Gev"<<std::endl<<"Associated "<< *getParentPattern(muon);
26 return oss.str();
27 }
28}
29
30namespace MuonR4 {
31using namespace Acts::UnitLiterals;
32using namespace Muon::MuonStationIndex;
33
35 ATH_CHECK(m_outMuons.initialize());
36 ATH_CHECK(m_qOverPCovKey.initialize());
37 ATH_CHECK(m_inSegments.initialize());
38 ATH_CHECK(m_seedingTool.retrieve());
39 return StatusCode::SUCCESS;
40}
41
42StatusCode MuonFastSABuilderAlg::execute(const EventContext& ctx) const {
43 ATH_MSG_VERBOSE(__func__<<"() Start building muon candidates");
44
45 const xAOD::MuonSegmentContainer* inSegments{nullptr};
46 ATH_CHECK(SG::get(inSegments, m_inSegments, ctx));
47
48 MuonDataShip dataShip{};
50 dataShip.dec_qOverPCov.initialize(m_qOverPCovKey, ctx);
51
53 auto firstSeg = inSegments->stdcont().begin();
54 const auto lastSeg = inSegments->stdcont().end();
55 while(firstSeg != lastSeg) {
56 const GlobalPattern* pattern {FastReco::getParentPattern(**firstSeg)};
57 assert(pattern);
58
59 const auto nextToLastSeg {std::find_if(firstSeg, lastSeg,
60 [pattern](const xAOD::MuonSegment* seg) {
61 return FastReco::getParentPattern(*seg) != pattern;
62 })};
63 const std::span<const xAOD::MuonSegment* const> muonSegments {firstSeg, nextToLastSeg};
64
65 xAOD::Muon* newMuon {buildMuonCandidate(ctx, *pattern, muonSegments, dataShip)};
66
67 firstSeg = nextToLastSeg;
68 if (!newMuon) {
69 ATH_MSG_DEBUG(__func__<<"() No muon candidate could be built from pattern " << *pattern);
70 continue;
71 }
73 std::vector<ElementLink<xAOD::MuonSegmentContainer>> segLinks{};
74 for (const xAOD::MuonSegment* seg : muonSegments) {
75 segLinks.emplace_back(*inSegments, seg->index());
76 }
77 newMuon->setMuonSegmentLinks(segLinks);
78 ATH_MSG_DEBUG(__func__<<"() Built new muon candidate: " << print(*newMuon));
79 }
80 ATH_MSG_DEBUG("Written "<<dataShip.muonContainer->size()<<" FastMuonSA into StoreGate.");
81 return StatusCode::SUCCESS;
82}
83
85 const GlobalPattern& pattern,
86 std::span<const xAOD::MuonSegment* const> segments,
87 MuonDataShip& outMuonData) const {
88
89 ATH_MSG_VERBOSE(__func__<<"() Starting muon building from "
90 << segments.size()<<" segments for pattern " << std::endl << pattern);
91
92 if (segments.size() < 2) {
93 ATH_MSG_DEBUG(__func__<<"() Not enough muon segments to construct a candidate - abort.");
94 return nullptr;
95 }
96
98 const std::vector<StIndex> stations {pattern.getStations()};
99 const unsigned nBarrelStations = std::ranges::count_if(stations,
100 [](const StIndex station) { return isBarrel(station); });
101
103 using enum MsTrackSeed::Location;
104 MsTrackSeed trackSeed {nBarrelStations * 2u >= stations.size() ? Barrel : Endcap,
105 pattern.expSector()};
106 for (const xAOD::MuonSegment* seg : segments) {
107 trackSeed.addSegment(seg);
108 }
109 ATH_MSG_VERBOSE(__func__<<"() Constructed track seed: " << trackSeed);
110
111 Acts::Result<Acts::BoundTrackParameters> seedPars {
112 m_seedingTool->estimateStartParameters(ctx, trackSeed)};
113
114 if (!seedPars.ok()) {
115 ATH_MSG_DEBUG(__func__<<"() Failed to estimate seed parameters for track seed: " << trackSeed);
116 return nullptr;
117 }
118
119 xAOD::Muon* newMuon = outMuonData.muonContainer->push_back(std::make_unique<xAOD::Muon>());
120 newMuon->setAuthor(xAOD::Muon::Author::MuidSA);
121 newMuon->setMuonType(xAOD::Muon::MuonType::MuonStandAlone);
122 newMuon->setCharge(seedPars->charge());
123
124 newMuon->setP4(ActsTrk::energyToAthena(seedPars->transverseMomentum()),
125 Acts::VectorHelpers::eta(*seedPars),seedPars->phi());
126
128 std::optional<Acts::BoundMatrix> cov {seedPars->covariance()};
129 float& qOverPCov {outMuonData.dec_qOverPCov(*newMuon)};
130 if (!cov || (*cov)(Acts::eBoundQOverP, Acts::eBoundQOverP) < Acts::s_epsilon) {
131 ATH_MSG_WARNING(__func__<<"() No covariance matrix available for seed parameters of track seed: " << trackSeed);
132 qOverPCov = 0.;
133 return newMuon;
134 }
136 static constexpr double conversionFactor {1 / Acts::square(ActsTrk::energyToAthena(1.))};
137 qOverPCov = (*cov)(Acts::eBoundQOverP, Acts::eBoundQOverP) * conversionFactor;
138 return newMuon;
139}
140}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
static Double_t P(Double_t *tt, Double_t *par)
void print(char *figname, TCanvas *c1)
double angle(const GeoTrf::Vector2D &a, const GeoTrf::Vector2D &b)
constexpr float inDeg(const float rad)
const PtrVector & stdcont() const
Return the underlying std::vector of the container.
Data class to represent an eta maximum in hough space.
void addSegment(const xAOD::MuonSegment *seg)
Append a segment to the seed.
Location
Enum defining whether the seed is made in the endcap / barrel.
Definition MsTrackSeed.h:25
SG::WriteDecorHandleKey< xAOD::MuonContainer > m_qOverPCovKey
Muon decoration of the Q/P covariance.
xAOD::Muon * buildMuonCandidate(const EventContext &ctx, const GlobalPattern &pattern, std::span< const xAOD::MuonSegment *const > segments, MuonDataShip &outMuonData) const
Given the muon segments, it builds the standalone muon candidate, estimating the momentum and filling...
ToolHandle< ITrackSeedingTool > m_seedingTool
The track seeding tool to construct the seed candidates and to estimate the initial parameters.
SG::ReadHandleKey< xAOD::MuonSegmentContainer > m_inSegments
Read handle key for the input segments.
virtual StatusCode initialize() override
SG::WriteHandleKey< xAOD::MuonContainer > m_outMuons
Write handle key for the output muon candidates.
virtual StatusCode execute(const EventContext &ctx) const override
StatusCode record(const SG::WriteHandleKey< Cont_t > &key, const EventContext &ctx)
Record the container to store gate using the passed write handle key.
void setAuthor(const Author auth)
set author
void setMuonType(MuonType type)
void setMuonSegmentLinks(const std::vector< ElementLink< MuonSegmentContainer > > &segments)
Set the vector of ElementLinks to the MuonSegments used to create this Muon.
void setP4(double pt, double eta, double phi)
Set method for IParticle values.
Definition Muon_v1.cxx:71
void setCharge(float charge)
Set the charge (must be the same as primaryTrackParticle() ).
constexpr double energyToAthena(const double actsE)
Converts an energy scalar from Acts to Athena units.
const GlobalPattern * getParentPattern(const xAOD::MuonSegment &segment)
Retrieve the parent global pattern of the segment.
double getQOverPCov(const xAOD::Muon &muon)
Retrieve the Q/P covariance of the muon.
This header ties the generic definitions in this package.
std::string print(const cont_t &container)
Print a space point container to string.
StIndex
enum to classify the different station layers in the muon spectrometer
bool isBarrel(const ChIndex index)
Returns true if the chamber index points to a barrel chamber.
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
MuonSegmentContainer_v1 MuonSegmentContainer
Definition of the current "MuonSegment container version".
Muon_v1 Muon
Reference the current persistent version:
MuonSegment_v1 MuonSegment
Reference the current persistent version:
Data ship containing the muon container and the covariance decorator.
xAOD::ContainerDecorator< xAOD::MuonContainer, float > dec_qOverPCov
The Q/P covariance decorator.