16#include "Acts/Definitions/Units.hpp"
23using namespace Acts::UnitLiterals;
27 constexpr double toDeg(
const double rad) {
28 return rad / 1._degree;
38 if (matchedSegs.empty() ||
toLayerIndex(matchedSegs.front()->chamberIndex()) ==
toLayerIndex(matchedSegs.back()->chamberIndex())) {
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) {
63 return barrelLength < 0 || std::abs(endcapLength) < barrelLength
64 ? endcapSeed : barrelSeed;
69 double maxL{-1.*Gaudi::Units::km}, minL{1.*Gaudi::Units::km},
70 maxTheta{-181.}, minTheta{181};
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));
83 return std::make_pair(maxL - minL, maxTheta - minTheta);
110 return m_segSelector->passSeedingQuality(Gaudi::Hive::currentContext(),
115 return m_segSelector->passTrackQuality(Gaudi::Hive::currentContext(),
126 const unsigned linkIdx = truthS ?
m_truthSegs->push_back(*truthS) : -1;
146 unsigned short linkIdx =
m_truthTrks->find(truthP);
149 for (
auto loc : {Location::Barrel, Location::Endcap}) {
151 std::format(
"TruthSegments_has{}Proj", loc), [loc,
this](
const SG::AuxElement* aux) ->
unsigned short {
170 std::vector<unsigned short>>>(
m_tree,
172 std::vector<unsigned short> idx{};
182 return getTruthSegments(p).size();
185 auto cone = std::make_shared<VectorBranch<float>>(
m_tree,
186 std::format(
"{}_seedThetaCone",
m_truthTrks->name()));
187 auto qTimesP = std::make_shared<VectorBranch<float>>(
m_tree,
191 m_tree.addBranch(qTimesP);
195 const ActsTrk::GeometryContext* gctx{};
197 const EventContext& ctx{Gaudi::Hive::currentContext()};
201 magCache->getInitializedCache(magField);
205 qTimesP->push_back(0);
209 cone->push_back(
theta);
210 qTimesP->push_back(
m_seedingTool->estimateQtimesP(gctx->context(), *truthSeed, magField) / Gaudi::Units::GeV);
215 m_tree.addBranch(m_truthTrks);
216 m_trkTruthLinks.emplace_back(m_truthSegmentKey,
"truthParticleLink");
217 m_trkTruthLinks.emplace_back(m_truthKey,
"truthSegmentLinks");
218 m_trkTruthLinks.emplace_back(m_recoSegmentKey,
"truthSegmentLink");
219 m_trkTruthLinks.emplace_back(m_muonKey,
"truthParticleLink");
222 m_tree.addBranch(m_recoSegs);
223 m_tree.addBranch(std::make_unique<EventInfoBranch>(m_tree, evOpts));
225 static const std::vector<std::string> trackSummaries{
227 "innerSmallHits",
"innerLargeHits",
"innerSmallHoles",
"innerLargeHoles",
228 "innerClosePrecisionHits",
230 "middleSmallHits",
"middleLargeHits",
"middleSmallHoles",
231 "middleLargeHoles",
"middleClosePrecisionHits",
233 "outerSmallHits",
"outerLargeHits",
"outerSmallHoles",
"outerLargeHoles",
234 "outerClosePrecisionHits",
236 "extendedSmallHits",
"extendedLargeHits",
"extendedSmallHoles",
237 "extendedLargeHoles",
"extendedClosePrecisionHits",
238 "innerTriggerEtaHits",
"innerTriggerPhiHits",
239 "middleTriggerEtaHits",
"middleTriggerPhiHits",
240 "outerTriggerEtaHits",
"outerTriggerPhiHits",
242 "innerTriggerEtaHoles",
"innerTriggerPhiHoles",
243 "middleTriggerEtaHoles",
"middleTriggerPhiHoles",
244 "outerTriggerEtaHoles",
"outerTriggerPhiHoles",
246 if(!m_legacyTrackKey.empty()) {
247 m_legacyTrks = std::make_unique<IParticleFourMomBranch>(m_tree,
"LegacyMSTrks");
248 m_legacyTrks->addVariable(std::make_unique<TrackChi2Branch>(*m_legacyTrks));
253 for (
const auto& summary : trackSummaries) {
256 m_tree.addBranch(m_legacyTrks);
257 m_legacyRecoSegs = std::make_unique<SegmentVariables>(m_tree, m_legacySegmentKey.key(),
"LegacyRecoSegments", msgLevel());
258 m_tree.addBranch(m_legacyRecoSegs);
261 m_seedSummary = std::make_shared<TrackSummaryModule>(m_tree,
"MsTrkSeed", m_summaryTool.get());
262 m_muonTrks = std::make_shared<IParticleFourMomBranch>(m_tree,
"ActsMuons");
263 m_muonTrks->addVariable(std::make_unique<TrackChi2Branch>(*m_muonTrks));
264 m_muonTrks->addVariable(std::make_unique<TrackFitIterBranch>(*m_muonTrks));
266 using TrkType = xAOD::Muon::TrackParticleType;
267 auto dumpTrack = [&](
const std::string& trkName,
269 auto trkColl = std::make_shared<IParticleFourMomBranch>(m_tree, std::format(
"Acts{:}", trkName));
270 trkColl->addVariable(std::make_unique<TrackChi2Branch>(*trkColl));
271 trkColl->addVariable(std::make_unique<TrackFitIterBranch>(*trkColl));
272 trkColl->addVariable(std::make_unique<MaterialRecorderBranch>(*trkColl));
273 trkColl->addVariable(std::make_unique<EnergyLossBranch>(*trkColl));
275 trkColl->addVariable<
float>(
"d0");
276 trkColl->addVariable<
float>(
"z0");
277 for (
const auto& summary : trackSummaries) {
280 m_muonTrks->addVariable(std::make_unique<MuonVal::LinkerBranch>(*m_muonTrks, trkColl,
290 dumpTrack(
"MsTrk", TrkType::MuonSpectrometerTrackParticle);
291 dumpTrack(
"MeTrk", TrkType::ExtrapolatedMuonSpectrometerTrackParticle);
293 m_muonTrks->addVariable<
uint16_t>(
"allAuthors");
294 m_muonTrks->addVariable<
uint16_t>(
"author");
297 std::vector<unsigned short>>>(m_tree,
298 std::format(
"{:}_segmentLinks", m_muonTrks->name()), [&] (
const xAOD::Muon& p){
299 std::vector<unsigned short> idx{};
300 for (
unsigned seg = 0 ; seg <
p.nMuonSegments(); ++seg) {
301 idx.push_back(m_recoSegs->push_back(*
p.muonSegment(seg)));
307 std::format(
"{:}_seedLink", m_muonTrks->name()), [&] (
const xAOD::Muon& p) ->
unsigned short {
308 using enum xAOD::Muon::TrackParticleType;
309 const xAOD::TrackParticle* msTrack = p.trackParticle(MuonSpectrometerTrackParticle);
315 THROW_EXCEPTION(
"Cannot find the associated ms track from the primary track");
317 return actsTrk->component<std::size_t>(
"parentSeed");
324 },
"truth",
"ActsMuon");
327 for (
const auto& summary : trackSummaries) {
330 m_tree.addBranch(m_muonTrks);
332 m_tree.addBranch(m_seedSummary);
336 return StatusCode::SUCCESS;
345 return StatusCode::SUCCESS;
349 ATH_MSG_VERBOSE(
"iMuon " << muon->index() <<
" pT: "<<(muon->pt() *MeVtoGeV)<<
" [GeV], eta: "
350 <<muon->eta() <<
", phi: "<<toDeg(muon->phi())<<
", q: "<<muon->charge()
351 <<
", nSegments: "<<muon->nMuonSegments());
352 const xAOD::TrackParticle* track = muon->trackParticle(xAOD::Muon::TrackParticleType::MuonSpectrometerTrackParticle);
359 for (
size_t s = 0; s < muon->nMuonSegments(); ++s) {
362 ATH_MSG_VERBOSE(std::format(
"Legacy muon-segment link: segment {:} @{:}, eta: {:.2f}, phi {:.2f}",
373 if (legacyRecoSegs->
size()) {
389 return StatusCode::SUCCESS;
393 return StatusCode::SUCCESS;
401 Amg::toString(seg->position())<<
", eta: "<<seg->direction().eta()
402 <<
", phi: "<<toDeg(seg->direction().phi()));
405 if (truthSegs->
size()) {
412 const std::size_t nT = truthMuons->
size() - 1;
413 if (!truthMuons->
empty()) {
422 <<
", eta: "<<truth->eta()<<
", phi: "<<toDeg(truth->phi())<<
", q: "<<truth->charge());
426 return StatusCode::SUCCESS;
448 std::vector<unsigned>> truthToSeedMatchCounter{};
450 if (!trkSeeds->empty()) {
457 m_seedType+= Acts::toUnderlying(seed.location());
461 auto startPars =
m_seedingTool->estimateStartParameters(ctx, seed);
462 if (startPars.ok()) {
472 truthSeg !=
nullptr) {
474 if (seedIdx >= matchCounter.size()) {
475 matchCounter.resize(seedIdx +1);
477 ++matchCounter[seedIdx];
487 for (
auto& [truthMuon, matches] : truthToSeedMatchCounter) {
488 const unsigned tIndex =
m_truthTrks->find(truthMuon);
493 while (std::count_if(matches.begin(), matches.end(),
494 [](
const unsigned nMatched){
497 auto bestMatch = std::ranges::max_element(matches);
498 const std::size_t seedIdx = std::distance(matches.begin(), bestMatch);
515 return StatusCode::SUCCESS;
523 return StatusCode::SUCCESS;
527 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.
Acts::GeometryContext context() const
const ServiceHandle< StoreGateSvc > & detStore() const
void getInitializedCache(MagField::AtlasFieldCache &cache) const
get B field cache for evaluation as a function of 2-d or 3-d position.
size_type size() const noexcept
Returns the number of elements in the collection.
bool empty() const noexcept
Returns true if the collection is empty.
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h).
void addSegment(const xAOD::MuonSegment *seg)
Append a segment to the seed.
Location
Enum defining whether the seed is made in the endcap / barrel.
void setPosition(Amg::Vector3D &&pos)
set the seed's position
ToolHandle< MuonR4::ITrackSeedingDiagnosticsTool > m_seedingTool
The track seeding tool to construct the seed candidates and to estimate the initial parameters.
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
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.
MuonVal::UnitThreeVectorBranch m_seedDir
Seed direction vector.
ToolHandle< MuonR4::ISegmentSelectionTool > m_segSelector
Selection tool to quantify the segment candidate quality.
SegmentKey_t m_recoSegmentKey
Primary segment container.
MuonVal::MuonTesterTree m_tree
SegmentKey_t m_truthSegmentKey
Segment from the truth hits.
MuonVal::VectorBranch< char > & m_seedGood
Does the seeding tool construct valid parameters from the seed.
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.
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Eigen::Matrix< double, 2, 1 > Vector2D
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
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.
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.
LayerIndex toLayerIndex(ChIndex index)
convert ChIndex into LayerIndex
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.
#define THROW_EXCEPTION(MESSAGE)