15#include "Acts/Definitions/Units.hpp"
22using namespace Acts::UnitLiterals;
33 constexpr int overlapSector(
const int sec1 ,
const int sec2) {
35 if (sec2 > sec1)
return overlapSector(sec2, sec1);
36 if (sec1 == 1 && sec2 == nSec)
return 0;
45 int secMax{-1}, secMin{100};
47 if (matchedSegs.empty()) {
51 secMax = std::max(secMax, seg->sector());
52 secMin = std::min(secMin, seg->sector());
54 const int orSec = overlapSector(secMax, secMin);
64 const auto [barrelLength, barrelTheta] =
calcSeedLength(gctx, barrelSeed);
65 const auto [endcapLength, endcapTheta] =
calcSeedLength(gctx, endcapSeed);
66 ATH_MSG_VERBOSE(__func__<<
"() "<<__LINE__<<
" - Constructed new seed from truth muon wih pT:"
67 <<(truthMuon.pt()/ Gaudi::Units::GeV)<<
" [GeV], eta: "<<truthMuon.eta()
68 <<
", phi: "<<(truthMuon.phi() / 1._degree)<<
", q: "<<truthMuon.charge()
69 <<
", matchedSeg: "<<matchedSegs.size()<<
" barrel (L/theta): "<<barrelLength
70 <<
"/"<<(barrelTheta / 1._degree)<<
" - endcap (L/theta): "
71 <<endcapLength<<
"/"<<(endcapTheta / 1._degree)<<
"\n"<<barrelSeed);
72 if (barrelLength < 0 && endcapLength < 0) {
76 return barrelLength < 0 || std::abs(endcapLength) < barrelLength
77 ? endcapSeed : barrelSeed;
82 double maxL{-1.*Gaudi::Units::km}, minL{1.*Gaudi::Units::km},
85 const auto secProj =
m_seeder->projectorFromSeed(*seg, seed);
87 if (!
m_seeder->withinBounds(projPos, seed.location())) {
90 const double projected = projPos[seed.location()==Location::Barrel];
91 const double theta = seg->direction().theta();
92 minL = std::min(minL, projected);
93 maxL = std::max(maxL, projected);
94 minTheta = std::min(minTheta,
theta);
95 maxTheta = std::max(maxTheta,
theta);
97 return std::make_pair(maxL - minL, maxTheta - minTheta);
120 m_seeder = std::make_unique<MuonR4::MsTrackSeeder>(name(), std::move(seederCfg));
128 return m_segSelector->passSeedingQuality(Gaudi::Hive::currentContext(),
133 return m_segSelector->passTrackQuality(Gaudi::Hive::currentContext(),
144 const unsigned linkIdx = truthS ?
m_truthSegs->push_back(*truthS) : -1;
164 unsigned short linkIdx =
m_truthTrks->find(truthP);
173 for (
const auto proj : {leftOverlap, center, rightOverlap}) {
175 if (
m_seeder->withinBounds(projPos, Location::Barrel)) {
188 for (
const auto proj : {leftOverlap, center, rightOverlap}) {
190 if (
m_seeder->withinBounds(projPos, Location::Endcap)) {
208 m_tree.addBranch(std::make_unique<EventInfoBranch>(
m_tree, evOpts));
218 for (
const auto& summary :{
220 "innerSmallHits",
"innerLargeHits",
"innerSmallHoles",
"innerLargeHoles",
222 "middleSmallHits",
"middleLargeHits",
"middleSmallHoles",
225 "outerSmallHits",
"outerLargeHits",
"outerSmallHoles",
"outerLargeHoles",
227 "extendedSmallHits",
"extendedLargeHits",
"extendedSmallHoles",
228 "extendedLargeHoles",
229 "etaLayer1Hits",
"phiLayer1Hits",
"etaLayer2Hits",
"phiLayer2Hits",
230 "etaLayer3Hits",
"phiLayer3Hits",
"etaLayer4Hits",
"phiLayer4Hits",
231 "etaLayer1Holes",
"phiLayer1Holes",
"etaLayer2Holes",
"phiLayer2Holes",
232 "etaLayer3Holes",
"phiLayer3Holes",
"etaLayer4Holes",
"phiLayer4Holes" }) {
251 return StatusCode::SUCCESS;
254 const EventContext& ctx{Gaudi::Hive::currentContext()};
268 std::unordered_map<const xAOD::MuonSegment*, unsigned short> segIndex;
271 unsigned short iTrk = 0;
273 ATH_MSG_VERBOSE(
"Legacy track "<< iTrk <<
": pT: "<<(track->pt() *MeVtoGeV)<<
" [GeV], eta: "<<track->eta()
274 <<
", phi: "<<(track->phi() / 1._degree)<<
", q: "<<track->charge());
282 ATH_MSG_VERBOSE(
"iMuon " << iMuon <<
" pT: "<<(muon->pt() *MeVtoGeV)<<
" [GeV], eta: "<<muon->eta()
283 <<
", phi: "<<(muon->phi() / 1._degree)<<
", q: "<<muon->charge() <<
", nSegments: "<<muon->nMuonSegments());
288 const xAOD::TrackParticle* msTrack = muon->trackParticle( xAOD::Muon::MuonSpectrometerTrackParticle);
289 if ( !msTrack || (msTrack != track) ) {
continue; }
292 for (
size_t s = 0; s < muon->nMuonSegments(); ++s) {
295 ATH_MSG_VERBOSE(std::format(
"Legacy muon-segment link: segment {:} @{:}, eta: {:.2f}, phi {:.2f}",
299 segIndex[segment] = iTrk;
307 if (legacyRecoSegs) {
308 unsigned short iSeg = 0;
317 ATH_MSG_VERBOSE(std::format(
"Dump legacy reco segment index {:} {:} @{:}, eta: {:.2f}, phi {:.2f} associated muon: {:}",
335 std::map<const xAOD::TruthParticle*, std::vector<unsigned>> truthToSeedMatchCounter{};
339 m_seedType+= Acts::toUnderlying(seed.location());
346 truthSeg !=
nullptr) {
348 if (seedIdx >= matchCounter.size()) {
349 matchCounter.resize(seedIdx +1);
351 ++matchCounter[seedIdx];
357 m_seedQP +=
m_seeder->estimateQtimesP(*gctx, *magCache, seed) / Gaudi::Units::GeV;
367 ATH_MSG_VERBOSE(std::format(
"Dump truth segment {:} @{:}, eta: {:.2f}, phi {:.2f}",
369 seg->direction().eta(), seg->direction().phi() / 1._degree));
372 if (truthSegs->size()) {
379 if (truthMuons && truthMuons->
size()) {
387 ATH_MSG_DEBUG(
"Truth muon: pT: "<<(truth->pt() *MeVtoGeV)<<
", eta: "<<truth->eta()
388 <<
", phi: "<<(truth->phi() / 1._degree)<<
", q: "<<truth->charge());
392 std::vector<unsigned>& matchCounter = truthToSeedMatchCounter[truth];
393 std::vector<unsigned>::iterator maxSeed = matchCounter.begin();
395 while ( (maxSeed = std::ranges::max_element(matchCounter))!=matchCounter.end() && (*maxSeed) > 0) {
402 const std::vector<const xAOD::MuonSegment*> truthSegs =
getTruthSegments(*truth);
405 truthSegLinks.push_back(
m_truthSegs->push_back(*truthSeg));
417 m_truthMuonQP[truthIdx] =
m_seeder->estimateQtimesP(*gctx, *magCache, *truthSeed) / Gaudi::Units::GeV;
424 for (
const auto trk : *msTracks) {
429 return StatusCode::SUCCESS;
433 return StatusCode::SUCCESS;
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)
Handle class for reading from StoreGate.
const ServiceHandle< StoreGateSvc > & detStore() const
size_type size() const noexcept
Returns the number of elements in the collection.
ElementLink implementation for ROOT usage.
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.
SectorProjector
Enumeration to select the sector projection.
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.
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.
StatusCode execute() override final
MuonVal::VectorBranch< float > & m_truthMuonQP
Estimated Q x P from the seeder algorithm class.
MuonVal::VectorBranch< float > & m_truthMuonsSeedLength
MuonVal::VectorBranch< char > & m_seedType
Is the seed in the encap or in the barrel chambers.
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_legacyTrackKey
Legacy track reconstruction chain.
SG::ReadHandleKey< xAOD::TruthParticleContainer > m_truthKey
Key to the truth particle collection.
Gaudi::Property< bool > m_isMC
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
SG::ReadHandleKey< MuonR4::MsTrackSeedContainer > m_msTrkSeedKey
Temporary container write handle to push the seeds to store gate for later efficiency analysis.
SG::ReadDecorHandleKeyArray< SG::AuxVectorBase > m_trkTruthLinks
Decoration dependency to the MS truth track links.
MuonVal::MatrixBranch< unsigned short > & m_truthMuTruthSegLinks
Links from the truth muon to the segments.
MuonVal::VectorBranch< float > & m_truthMuonsSeedCone
Angular deviation of the true segment seed.
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
Corresponding matching counter of reconstructed segments.
MuonVal::VectorBranch< unsigned short > & m_truthMuTruthNSegs
Number of associated truth muon segments.
MuonVal::ThreeVectorBranch m_seedPos
Simple seed information.
SG::ReadHandleKey< xAOD::MuonContainer > m_legacyMuonKey
Legacy muons.
MuonVal::VectorBranch< float > & m_seedLength
Maximum separation between the segments on the reference plane.
SG::ReadHandleKey< ActsTrk::TrackContainer > m_trackKey
Dependency on the R4 MS track container.
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
SG::ReadHandleKey< ActsTrk::GeometryContext > m_geoCtxKey
Dependency on the geometry alignment.
SegmentKey_t m_truthSegmentKey
Segment from the truth hits.
std::shared_ptr< TrackSummaryModule > m_trackSummary
Hit summary on the reconstructed track.
StatusCode finalize() override final
std::shared_ptr< TrackSummaryModule > m_seedSummary
Hit summary on the track seed.
std::pair< double, double > calcSeedLength(const ActsTrk::GeometryContext &gctx, const MuonR4::MsTrackSeed &seed) const
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...
Helper class to provide constant type-safe access to aux data.
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::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Eigen::Matrix< double, 2, 1 > Vector2D
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
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.
ElementLink< MuonR4::SegmentContainer > SegLink_t
Abrivation of the link to the reco segment container.
std::vector< SegLink_t > SegLinkVec_t
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.
constexpr unsigned numberOfSectors()
return total number of sectors
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:
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.
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.