ATLAS Offline Software
Loading...
Searching...
No Matches
SegmentDumperAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN
3 for the benefit of the ATLAS collaboration
4*/
5
6#include "SegmentDumperAlg.h"
7
13#include "xAODMuonPrepData/UtilFunctions.h" // getTruthMatchedParticle
14
18
19#include <set>
20#include <unordered_map>
21#include <limits>
22
23namespace {
24struct LocalSegSorter {
25 bool operator()(const xAOD::MuonSegment* a,
26 const xAOD::MuonSegment* b) const {
27 if (a == b) return false;
28 if (a->chamberIndex() != b->chamberIndex())
29 return a->chamberIndex() < b->chamberIndex();
30 if (a->sector() != b->sector())
31 return a->sector() < b->sector();
32 if (a->etaIndex() != b->etaIndex())
33 return a->etaIndex() < b->etaIndex();
34 using namespace MuonR4::SegmentFit;
35 auto la = localSegmentPars(*a);
36 auto lb = localSegmentPars(*b);
37 return la < lb;
38 }
39};
40} // namespace
41
42namespace MuonR4 {
43
45 ATH_MSG_INFO("Initializing SegmentDumperAlg (MC)");
46
47 ATH_CHECK(m_spacePointKeys.initialize());
48 ATH_CHECK(m_segmentKeys.initialize());
49
50 // Truth decoration on MC
51 m_truthDecorKeys.emplace_back(m_segmentKeys, "truthParticleLink");
52 ATH_CHECK(m_truthDecorKeys.initialize());
53
54 ATH_CHECK(m_geoCtxKey.initialize());
55 m_tree.addBranch(std::make_shared<MuonVal::EventHashBranch>(m_tree.tree()));
56 ATH_CHECK(m_tree.init(this));
57 return StatusCode::SUCCESS;
58}
59
61 ATH_CHECK(m_tree.write());
62 return StatusCode::SUCCESS;
63}
64
66 const EventContext& ctx{Gaudi::Hive::currentContext()};
67
68 using SegmentsPerBucket_t =
69 std::unordered_map<const SpacePointBucket*,
70 std::set<const xAOD::MuonSegment*, LocalSegSorter>>;
71
72 const ActsTrk::GeometryContext* gctx{nullptr};
73 ATH_CHECK(SG::get(gctx, m_geoCtxKey, ctx));
74
75 const xAOD::MuonSegmentContainer* segContainer{nullptr};
76 ATH_CHECK(SG::get(segContainer, m_segmentKeys, ctx));
77
78 for (unsigned iKey = 0; iKey < m_spacePointKeys.size(); ++iKey) {
79 const auto& spKey = m_spacePointKeys[iKey];
80
81 const SpacePointContainer* spContainer{nullptr};
82 ATH_CHECK(SG::get(spContainer, spKey, ctx));
83
84 SegmentsPerBucket_t segPerBucket{};
85 if (segContainer) {
86 for (const xAOD::MuonSegment* seg : *segContainer) {
87 const auto* detSeg = MuonR4::detailedSegment(*seg);
88 segPerBucket[detSeg->parent()->parentBucket()].insert(seg);
89 }
90 }
91
92 for (const SpacePointBucket* bucket : *spContainer) {
93 m_bucket_spacePoints = static_cast<uint16_t>(bucket->size());
94 m_bucket_chamberIdx = static_cast<uint8_t>(bucket->msSector()->chamberIndex());
95 m_bucket_sector = static_cast<uint8_t>(bucket->msSector()->sector());
97
98 const auto it = segPerBucket.find(bucket);
99 m_bucket_segments = (it != segPerBucket.end()) ? static_cast<uint16_t>(it->second.size()) : 0;
100 if (it != segPerBucket.end()) {
101 for (const xAOD::MuonSegment* seg : it->second) {
102 // Reco-level outputs (always aligned to segments)
103 m_segmentPos.push_back(seg->position());
104 m_segmentDir.push_back(seg->direction());
105 m_segment_chiSquared.push_back(seg->chiSquared());
106 m_segment_numberDoF.push_back(seg->numberDoF());
107
108 // --- Reco η/φ (GLOBAL): direction is already in global coordinates
109 const Amg::Vector3D& globDir = seg->direction();
110 float segEta = static_cast<float>(globDir.eta());
111 float segPhi = static_cast<float>(globDir.phi());
112 m_segmentRecoEta.push_back(segEta);
113 m_segmentRecoPhi.push_back(segPhi);
114
115 // Truth association
116 int32_t truthIdx = -1;
117 int32_t truthPdg = -1;
119 if (tp) {
120 truthIdx = static_cast<int32_t>(tp->index());
121 truthPdg = static_cast<int32_t>(tp->pdgId());
122 }
123
124 // Per-segment truth flags/ids remain aligned to segments
125 m_segmentHasTruth.push_back(truthIdx >= 0 ? 1 : 0);
126
127 // Fill truth kinematics ONLY when a truth match exists (sparse truth arrays)
128 if (truthIdx >= 0) {
129 m_segmentTruthIdx.push_back(truthIdx);
130 m_segmentTruthPDGId.push_back(truthPdg);
131 m_segmentTruthPt.push_back(static_cast<float>(tp->pt())); // MeV
132 m_segmentTruthEta.push_back(static_cast<float>(tp->eta()));
133 m_segmentTruthPhi.push_back(static_cast<float>(tp->phi()));
134 }
135 }
136 }
137
138 if (!m_tree.fill(ctx)) {
139 ATH_MSG_ERROR("Failed to fill output tree");
140 return StatusCode::FAILURE;
141 }
142 }
143 }
144
145 return StatusCode::SUCCESS;
146}
147
150 std::vector<unsigned int> uniqueLayers;
151 uniqueLayers.reserve(bucket.size());
152
153 for (const SpacePointBucket::value_type& sp : bucket) {
154 const unsigned layNum = sorter.sectorLayerNum(*sp);
155 if (std::find(uniqueLayers.begin(), uniqueLayers.end(), layNum) == uniqueLayers.end()) {
156 uniqueLayers.push_back(layNum);
157 }
158 }
159 return static_cast<uint16_t>(uniqueLayers.size());
160}
161
162} // namespace MuonR4
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
static Double_t sp
static Double_t a
Handle class for reading from StoreGate.
MuonVal::ThreeVectorBranch m_segmentPos
MuonVal::VectorBranch< float > & m_segment_numberDoF
SG::ReadDecorHandleKeyArray< xAOD::MuonSegmentContainer > m_truthDecorKeys
Truth decoration (MC)
MuonVal::VectorBranch< float > & m_segmentTruthPhi
MuonVal::VectorBranch< float > & m_segmentTruthEta
SG::ReadHandleKeyArray< SpacePointContainer > m_spacePointKeys
Inputs.
SG::ReadHandleKey< xAOD::MuonSegmentContainer > m_segmentKeys
MuonVal::VectorBranch< float > & m_segmentTruthPt
MuonVal::ScalarBranch< uint16_t > & m_bucket_spacePoints
MuonVal::MuonTesterTree m_tree
Output tree.
MuonVal::VectorBranch< float > & m_segmentRecoEta
MuonVal::ScalarBranch< uint16_t > & m_bucket_segments
MuonVal::ScalarBranch< uint8_t > & m_bucket_chamberIdx
MuonVal::VectorBranch< int32_t > & m_segmentTruthPDGId
SG::ReadHandleKey< ActsTrk::GeometryContext > m_geoCtxKey
uint16_t countLayersInBucket(const SpacePointBucket &bucket) const
MuonVal::ScalarBranch< uint8_t > & m_bucket_sector
MuonVal::VectorBranch< float > & m_segmentRecoPhi
StatusCode finalize() override final
MuonVal::VectorBranch< uint8_t > & m_segmentHasTruth
StatusCode initialize() override final
StatusCode execute() override final
MuonVal::VectorBranch< float > & m_segment_chiSquared
MuonVal::VectorBranch< int32_t > & m_segmentTruthIdx
MuonVal::ThreeVectorBranch m_segmentDir
MuonVal::ScalarBranch< uint16_t > & m_bucket_layers
: The muon space point bucket represents a collection of points that will bre processed together in t...
The SpacePointPerLayerSorter sort two given space points by their layer Identifier.
float numberDoF() const
Returns the numberDoF.
Amg::Vector3D direction() const
Returns the direction as Amg::Vector.
float chiSquared() const
Amg::Vector3D position() const
Returns the position as Amg::Vector.
int lb
Definition globals.cxx:23
Eigen::Matrix< double, 3, 1 > Vector3D
Parameters localSegmentPars(const xAOD::MuonSegment &seg)
Returns the localSegPars decoration from a xAODMuon::Segment.
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.
DataVector< SpacePointBucket > SpacePointContainer
Abrivation of the space point container type.
const Segment * detailedSegment(const xAOD::MuonSegment &seg)
Helper function to navigate from the xAOD::MuonSegment to the MuonR4::Segment.
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".
TruthParticle_v1 TruthParticle
Typedef to implementation.
MuonSegment_v1 MuonSegment
Reference the current persistent version: