ATLAS Offline Software
Loading...
Searching...
No Matches
BucketDumperAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "BucketDumperAlg.h"
6
16#include <fstream>
17#include <unordered_map>
19#include "CLHEP/Random/RandFlat.h"
20
21namespace {
22 struct LocalSegSorter{
23 bool operator()(const xAOD::MuonSegment* a, const xAOD::MuonSegment* b) const {
24 if(a == b) {
25 return false;
26 }
27 if (a->chamberIndex() != b->chamberIndex()) {
28 return a->chamberIndex() < b->chamberIndex();
29 }
30 if (a->sector() != b->sector()) {
31 return a->sector() < b->sector();
32 }
33 if (a->etaIndex() != b->etaIndex()) {
34 return a->etaIndex() < b->etaIndex();
35 }
36 using namespace MuonR4::SegmentFit;
37 auto locParsA = localSegmentPars(*a);
38 auto locParsB = localSegmentPars(*b);
39 return locParsA < locParsB;
40 }
41 };
42}
43
44namespace MuonR4{
46 ATH_CHECK(m_spacePointKeys.initialize());
47 ATH_CHECK(m_inSegmentKeys.initialize());
48 if (m_isMC) {
49 for (const auto& key : m_inSegmentKeys) {
50 m_truthDecorKeys.emplace_back(key, "truthParticleLink");
51 }
52 }
53 ATH_CHECK(m_truthDecorKeys.initialize());
54 ATH_CHECK(m_geoCtxKey.initialize());
55 m_tree.addBranch(std::make_shared<MuonVal::EventHashBranch>(m_tree.tree()));
56 ATH_CHECK(m_visionTool.retrieve(EnableTool{!m_visionTool.empty()}));
57 if (m_visionTool.empty()) {
58 m_tree.disableBranch(m_spoint_trueLabel.name());
59 }
60
61 // Setup ML bucket score branches
63 ATH_CHECK(m_inferenceTool.retrieve());
64 ATH_MSG_INFO("ML bucket scoring enabled with tool: " << m_inferenceTool.name());
65 }
66
67 // Disable ML score branches if not enabled
68 if (!m_doMLBucketScore) {
69 m_tree.disableBranch(m_bucket_ml_score_class0.name());
70 m_tree.disableBranch(m_bucket_ml_score_class1.name());
71 m_tree.disableBranch(m_bucket_ml_score_class2.name());
72 }
73
74 ATH_CHECK(m_tree.init(this));
75 ATH_MSG_DEBUG("Successfully initialized");
76
77 return StatusCode::SUCCESS;
78 }
79
81 ATH_CHECK(m_tree.write());
82 return StatusCode::SUCCESS;
83 }
84
86 const EventContext& ctx{Gaudi::Hive::currentContext()};
89
90 for (unsigned keyNum = 0 ; keyNum < m_spacePointKeys.size(); ++keyNum) {
92 keyNum < m_inSegmentKeys.size() ? m_inSegmentKeys[keyNum] : emptyKey));
93 }
94 return StatusCode::SUCCESS;
95 }
96 StatusCode BucketDumperAlg::dumpContainer(const EventContext& ctx,
97 const SG::ReadHandleKey<SpacePointContainer>& spacePointKey,
99
100 // Define the segment mapping type
101 using SegmentsPerBucket_t = std::unordered_map<const SpacePointBucket*,
102 std::set<const xAOD::MuonSegment*, LocalSegSorter>>;
103 SegmentsPerBucket_t segmentMap{};
104
105 const xAOD::MuonSegmentContainer* readSegment{nullptr};
106 ATH_CHECK(SG::get(readSegment, segmentKey, ctx));
107 if (readSegment) {
108 for (const xAOD::MuonSegment* segment : *readSegment) {
109 segmentMap[detailedSegment(*segment)->parent()->parentBucket()].insert(segment);
110 }
111 }
112
113 const ActsTrk::GeometryContext* gctx{nullptr};
114 ATH_CHECK(SG::get(gctx, m_geoCtxKey, ctx));
115
116 const SpacePointContainer* spContainer{nullptr};
117 ATH_CHECK(SG::get(spContainer, spacePointKey, ctx));
118
119 // Compute ML bucket scores if enabled - only for MuonSpacePoints container
120 // The tool is configured to read "MuonSpacePoints" from StoreGate, so we only run it for that container
121 std::unordered_map<const SpacePointBucket*, std::vector<float>> bucketScores;
122 const std::string& containerName = spacePointKey.key();
123 if (m_doMLBucketScore && containerName == "MuonSpacePoints") {
124 ATH_MSG_DEBUG("Computing ML bucket scores for container: " << containerName);
125 ATH_CHECK(computeAllBucketScores(ctx, spContainer, bucketScores));
126 ATH_MSG_DEBUG("ML scoring completed, got scores for " << bucketScores.size() << " buckets");
127 } else if (m_doMLBucketScore && containerName != "MuonSpacePoints") {
128 ATH_MSG_DEBUG("Skipping ML scoring for container: " << containerName
129 << " (only MuonSpacePoints is supported)");
130 }
131
132 CLHEP::HepRandomEngine* rndEngine = getRandomEngine(ctx);
133
134 const SpacePointPerLayerSorter layerSorter{};
135
136 for(const SpacePointBucket* bucket : *spContainer) {
138 if (!m_isMC && segmentMap[bucket].empty() && m_fracToKeep < 1. &&
139 CLHEP::RandFlat::shoot(rndEngine,0.,1.) > m_fracToKeep) {
140 ATH_MSG_VERBOSE("Skipping bucket without segment");
141 continue;
142 }
143
144 if (m_doMLBucketFilter && !bucketScores.empty()) {
145 auto scoreIt = bucketScores.find(bucket);
146 if (scoreIt != bucketScores.end() && scoreIt->second.size() >= 3) {
147 const auto& logits = scoreIt->second;
148 int predictedClass = 0;
149 float maxLogit = logits[0];
150 if (logits[1] > maxLogit) { maxLogit = logits[1]; predictedClass = 1; }
151 if (logits[2] > maxLogit) { maxLogit = logits[2]; predictedClass = 2; }
152 if (predictedClass == 0) continue;
153 }
154 }
155
157 m_bucket_sector = bucket->msSector()->sector();
158 m_bucket_chamberIdx = static_cast<uint8_t>(bucket->msSector()->chamberIndex());
159 m_bucket_side = bucket->msSector()->side();
161 m_bucket_min = bucket->coveredMin();
162 m_bucket_max = bucket->coveredMax();
163
165 const Amg::Vector3D bucketPos = bucket->msSector()->localToGlobalTransform(*gctx) *
166 (0.5*(bucket->coveredMin() + bucket->coveredMax()) * Amg::Vector3D::UnitY());
167 m_bucket_posX = bucketPos.x();
168 m_bucket_posY = bucketPos.y();
169 m_bucket_posZ = bucketPos.z();
170
172 m_bucket_truthHit = std::ranges::any_of(*bucket,[this](const SpacePointBucket::value_type & sp){
173 return m_visionTool->isLabeled(*sp);
174 });
175
177 m_bucket_segments = segmentMap[bucket].size();
178
179
180
181 std::unordered_map<const SpacePoint*, std::vector<int16_t>> spacePointToSegment{};
182 std::set<const xAOD::MuonSegment*, LocalSegSorter> truthSegments{};
184 auto match_itr = segmentMap.find(bucket);
185 if (match_itr != segmentMap.end()) {
186 for (const xAOD::MuonSegment* segment : match_itr->second) {
187 for (const auto& meas : detailedSegment(*segment)->measurements()) {
188 if (meas->fitState() == CalibratedSpacePoint::State::Valid) {
189 spacePointToSegment[meas->spacePoint()].push_back(segment->index());
190 }
191 }
192 using namespace SegmentFit;
193 const auto pars = localSegmentPars(*segment);
194 m_segmentLocX += pars[Acts::toUnderlying(ParamDefs::x0)];
195 m_segmentLocY += pars[Acts::toUnderlying(ParamDefs::y0)];
196 m_segmentLocTheta += pars[Acts::toUnderlying(ParamDefs::theta)];
197 m_segmentLocPhi += pars[Acts::toUnderlying(ParamDefs::phi)];
198
200 unsigned truthLink = -1;
201 if (const xAOD::TruthParticle* truthPart = getTruthMatchedParticle(*segment)) {
202 truthLink = truthPart->index();
203 }
205 if (const xAOD::MuonSegment* truthSeg = getMatchedTruthSegment(*segment)) {
206 truthSegments.insert(truthSeg);
207 }
208 m_segmentTruthIdx+=truthLink;
209 m_segmentPos.push_back(segment->position());
210 m_segmentDir.push_back(segment->direction());
211 m_segment_chiSquared.push_back(segment->chiSquared());
212 m_segment_numberDoF.push_back(segment->numberDoF());
213 }
214 }
215
216 std::vector<unsigned int> layNumbers{};
217 std::unordered_map<const SpacePoint*, std::vector<const xAOD::MuonSegment*>> spToTrueSeg{};
218 if (m_isMC) {
219 using SegLinkVec_t = std::vector<ElementLink<xAOD::MuonSegmentContainer>>;
220 static const SG::ConstAccessor<SegLinkVec_t> segAcc{"truthSegmentLinks"};
221 for (const auto& sp : *bucket){
222 for (const auto& link : segAcc(*sp->primaryMeasurement())) {
223 spToTrueSeg[sp.get()].push_back(*link);
224 truthSegments.insert(*link);
225 }
226 }
227 }
228
229 for(const SpacePointBucket::value_type& sp : *bucket) {
231 const unsigned int layNum = layerSorter.sectorLayerNum(*sp);
232 if (std::find(layNumbers.begin(), layNumbers.end(), layNum) == layNumbers.end()) {
233 layNumbers.push_back(layNum);
234 }
235 const unsigned layer = layNumbers.size()-1;
236
237 const Identifier& id = sp->identify();
238
240 const auto* dc = static_cast<const xAOD::MdtDriftCircle*>(sp->primaryMeasurement());
241 if (dc->status() != Muon::MdtDriftCircleStatus::MdtStatusDriftTime){
242 continue;
243 }
244 m_spoint_isMdt.push_back(true);
245 m_spoint_isStrip.push_back(false);
246 m_spoint_adc.push_back(dc->adc());
247 m_spoint_tdc.push_back(dc->tdc());
248 } else {
249 // check the technology to fill channel, adc and tdc... pushing back 0 for now
250 m_spoint_adc.push_back(0);
251 m_spoint_tdc.push_back(0);
252 m_spoint_isMdt.push_back(false);
253 m_spoint_isStrip.push_back(true);
254 }
255
256 m_spoint_id.push_back(id);
257
258
259 const std::vector<int16_t>& segIdxs = spacePointToSegment[sp.get()];
260 m_spoint_mat[m_spoint_mat.size()] = segIdxs;
261 auto& trueSegLinks = m_spoint_trueSeg[m_spoint_trueSeg.size()];
262 for (const xAOD::MuonSegment* matchedSeg : spToTrueSeg[sp.get()]) {
263 trueSegLinks.push_back(std::distance(truthSegments.begin(), truthSegments.find(matchedSeg)));
264 }
265 m_spoint_nSegments.push_back(segIdxs.size());
266
267 m_bucket_spacePoints = bucket->size();
268 m_spoint_localPosition.push_back(sp->localPosition());
269 using CovIdx = SpacePoint::CovIdx;
270 m_spoint_covX.push_back(sp->covariance()[Acts::toUnderlying(CovIdx::phiCov)]);
271 m_spoint_covY.push_back(sp->covariance()[Acts::toUnderlying(CovIdx::etaCov)]);
272 m_spoint_driftR.push_back(sp->driftRadius());
273 m_spoint_measuresEta.push_back(sp->measuresEta());
274 m_spoint_measuresPhi.push_back(sp->measuresPhi());
275 m_spoint_nEtaInstances.push_back(sp->nEtaInstanceCounts());
276 m_spoint_nPhiInstances.push_back(sp->nPhiInstanceCounts());
277 m_spoint_dimension.push_back(sp->dimension());
278 m_spoint_layer.push_back(layer);
279 if (m_visionTool.isEnabled()) {
280 m_spoint_trueLabel.push_back(m_visionTool->isLabeled(*sp));
281 }
282
283 Amg::Vector3D globalPos = sp->msSector()->localToGlobalTransform(*gctx) * sp->localPosition();
284 m_spoint_globalPosition.push_back( globalPos );
285 }
286
287 for (const xAOD::MuonSegment* truthSeg: truthSegments) {
288 using namespace SegmentFit;
289 const auto truthPars = localSegmentPars(*truthSeg);
290 m_truthSegLocX += truthPars[Acts::toUnderlying(ParamDefs::x0)];
291 m_truthSegLocY += truthPars[Acts::toUnderlying(ParamDefs::y0)];
292 m_truthSegLocTheta += truthPars[Acts::toUnderlying(ParamDefs::theta)];
293 m_truthSegLocPhi += truthPars[Acts::toUnderlying(ParamDefs::phi)];
294 }
295
296 m_bucket_layers = layNumbers.size();
297
298 // Add ML bucket filter scores if available
299 // Only add scores if we actually computed them for this container
300 if (m_doMLBucketScore && !bucketScores.empty()) {
301 auto scoreIt = bucketScores.find(bucket);
302 if (scoreIt != bucketScores.end() && scoreIt->second.size() >= 3) {
303 m_bucket_ml_score_class0.push_back(scoreIt->second[0]);
304 m_bucket_ml_score_class1.push_back(scoreIt->second[1]);
305 m_bucket_ml_score_class2.push_back(scoreIt->second[2]);
306 } else {
307 // Empty buckets are skipped during inference, so missing scores is expected
308 // Only warn if a non-empty bucket is missing scores (indicates a real problem)
309 if (bucket && !bucket->empty()) {
310 ATH_MSG_WARNING("Non-empty bucket from scored container not found in ML scores map");
311 }
312 m_bucket_ml_score_class0.push_back(0.f);
313 m_bucket_ml_score_class1.push_back(0.f);
314 m_bucket_ml_score_class2.push_back(0.f);
315 }
316 } else if (m_doMLBucketScore) {
317 // No scores computed for this container (e.g., NswSpacePoints) - fill with zeros
318 m_bucket_ml_score_class0.push_back(0.f);
319 m_bucket_ml_score_class1.push_back(0.f);
320 m_bucket_ml_score_class2.push_back(0.f);
321 }
322
323 if (!m_tree.fill(ctx)) {
324 return StatusCode::FAILURE;
325 }
326 }
327
328 return StatusCode::SUCCESS;
329
330 }
331
332 CLHEP::HepRandomEngine* BucketDumperAlg::getRandomEngine(const EventContext&ctx) const {
333 ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this, m_streamName);
334 std::string rngName = m_streamName;
335 rngWrapper->setSeed(rngName, ctx);
336 return rngWrapper->getEngine(ctx);
337 }
338
339 StatusCode BucketDumperAlg::computeAllBucketScores(const EventContext& ctx,
340 const SpacePointContainer* spContainer,
341 std::unordered_map<const SpacePointBucket*, std::vector<float>>& bucketScoreMap) const {
342 bucketScoreMap.clear();
343
344 ATH_MSG_DEBUG("computeAllBucketScores: doMLBucketScore=" << m_doMLBucketScore
345 << ", tool empty=" << m_inferenceTool.empty()
346 << ", spContainer=" << (spContainer ? "valid" : "null"));
347
348 if (!m_doMLBucketScore || m_inferenceTool.empty() || !spContainer) {
349 return StatusCode::SUCCESS;
350 }
351
352 // Count non-empty buckets
353 size_t nonEmptyBuckets = 0;
354 for (const MuonR4::SpacePointBucket* bucket : *spContainer) {
355 if (bucket && !bucket->empty()) {
356 ++nonEmptyBuckets;
357 }
358 }
359
360 // If no non-empty buckets, skip inference
361 if (nonEmptyBuckets == 0) {
362 ATH_MSG_DEBUG("Container has no non-empty buckets, skipping ML scoring");
363 return StatusCode::SUCCESS;
364 }
365
366 // Run the inference tool
367 ATH_MSG_DEBUG("Calling runGraphInference on tool: " << m_inferenceTool.name());
368 MuonML::GraphRawData graphData{};
369 ATH_CHECK(m_inferenceTool->runGraphInference(ctx, graphData));
370 ATH_MSG_DEBUG("runGraphInference completed successfully");
371
372 // Extract logits from the inference output
373 if (!graphData.graph || graphData.graph->dataTensor.size() <= 2) {
374 ATH_MSG_ERROR("Missing output logits tensor at index 2");
375 return StatusCode::FAILURE;
376 }
377
378 const Ort::Value& outTensor = graphData.graph->dataTensor[2];
379 const auto& info = outTensor.GetTensorTypeAndShapeInfo();
380 std::vector<int64_t> outShape = info.GetShape();
381
382 if (outShape.size() != 2 || outShape[1] != 3) {
383 ATH_MSG_ERROR("Unexpected ONNX output tensor shape");
384 return StatusCode::FAILURE;
385 }
386
387 const float* logitsPtr = outTensor.GetTensorData<float>();
388 if (!logitsPtr) {
389 ATH_MSG_ERROR("Failed to get logits data pointer");
390 return StatusCode::FAILURE;
391 }
392
393 // Map logits to buckets - only considering non-empty buckets
394 size_t totalNumPredictions = static_cast<size_t>(outShape[0]);
395 size_t predIdx = 0;
396
397 for (const MuonR4::SpacePointBucket* bucket : *spContainer) {
398 if (!bucket || bucket->empty()) {
399 continue; // Skip empty buckets
400 }
401
402 if (predIdx >= totalNumPredictions) {
403 ATH_MSG_ERROR("More non-empty buckets than predictions from model");
404 return StatusCode::FAILURE;
405 }
406
407 std::vector<float> scores(3);
408 scores[0] = logitsPtr[3 * predIdx + 0];
409 scores[1] = logitsPtr[3 * predIdx + 1];
410 scores[2] = logitsPtr[3 * predIdx + 2];
411
412 bucketScoreMap[bucket] = scores;
413 ++predIdx;
414 }
415
416 if (predIdx != totalNumPredictions) {
417 ATH_MSG_ERROR("Number of non-empty buckets (" << predIdx << ") does not match predictions ("
418 << totalNumPredictions << ")");
419 return StatusCode::FAILURE;
420 }
421
422 ATH_MSG_INFO("Successfully computed ML bucket scores for " << bucketScoreMap.size() << " buckets");
423 return StatusCode::SUCCESS;
424 }
425
426}
427
428
429
430
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
static Double_t sp
static Double_t a
Handle class for reading from StoreGate.
static const Attributes_t empty
A wrapper class for event-slot-local random engines.
Definition RNGWrapper.h:56
void setSeed(const std::string &algName, const EventContext &ctx)
Set the random seed using a string (e.g.
Definition RNGWrapper.h:169
CLHEP::HepRandomEngine * getEngine(const EventContext &ctx) const
Retrieve the random engine corresponding to the provided EventContext.
Definition RNGWrapper.h:134
ToolHandle< MuonValR4::IPatternVisualizationTool > m_visionTool
Pattern visualization tool.
MuonVal::ScalarBranch< Char_t > & m_bucket_side
MuonVal::ThreeVectorBranch m_spoint_localPosition
MuonVal::VectorBranch< unsigned short > & m_spoint_measuresEta
MuonVal::ScalarBranch< uint8_t > & m_bucket_sector
MuonVal::VectorBranch< float > & m_truthSegLocTheta
MuonVal::VectorBranch< float > & m_segment_numberDoF
SG::ReadHandleKeyArray< SpacePointContainer > m_spacePointKeys
Gaudi::Property< bool > m_doMLBucketFilter
StatusCode dumpContainer(const EventContext &ctx, const SG::ReadHandleKey< SpacePointContainer > &spacePointKey, const SG::ReadHandleKey< xAOD::MuonSegmentContainer > &segmentKey)
Dumps the space point container with the associated muon segment container.
ToolHandle< MuonML::IGraphInferenceTool > m_inferenceTool
Inference tool for ML bucket scoring (optional)
MuonVal::ScalarBranch< float > & m_bucket_min
MuonVal::VectorBranch< uint16_t > & m_spoint_layer
MuonVal::ThreeVectorBranch m_segmentPos
MuonVal::VectorBranch< float > & m_spoint_covX
MuonVal::VectorBranch< float > & m_segmentLocTheta
MuonVal::VectorBranch< float > & m_truthSegLocY
MuonVal::VectorBranch< float > & m_segment_chiSquared
CLHEP::HepRandomEngine * getRandomEngine(const EventContext &ctx) const
MuonVal::MatrixBranch< int16_t > & m_spoint_mat
MuonVal::ScalarBranch< float > & m_bucket_posZ
MuonVal::ScalarBranch< uint16_t > & m_bucket_layers
MuonVal::VectorBranch< float > & m_truthSegLocPhi
MuonVal::VectorBranch< float > & m_segmentLocY
MuonVal::VectorBranch< uint16_t > & m_segmentTruthIdx
virtual StatusCode initialize() override final
MuonVal::VectorBranch< float > & m_bucket_ml_score_class1
MuonVal::MuonTesterTree m_tree
MuonVal::VectorBranch< float > & m_segmentLocX
Gaudi::Property< double > m_fracToKeep
MuonVal::ScalarBranch< float > & m_bucket_max
virtual StatusCode execute() override final
MuonVal::VectorBranch< uint16_t > & m_spoint_nSegments
Gaudi::Property< bool > m_doMLBucketScore
SG::ReadDecorHandleKeyArray< xAOD::MuonSegmentContainer > m_truthDecorKeys
Gaudi::Property< bool > m_isMC
MuonVal::VectorBranch< float > & m_bucket_ml_score_class0
ML bucket filter scores (3 classes for the filter model)
MuonVal::VectorBranch< unsigned int > & m_spoint_nPhiInstances
StatusCode computeAllBucketScores(const EventContext &ctx, const SpacePointContainer *spContainer, std::unordered_map< const SpacePointBucket *, std::vector< float > > &bucketScoreMap) const
Computes ML bucket scores using the inference tool for a specific container.
MuonVal::ScalarBranch< uint8_t > & m_bucket_truthHit
Gaudi::Property< std::string > m_streamName
MuonVal::ThreeVectorBranch m_segmentDir
MuonVal::VectorBranch< uint16_t > & m_spoint_tdc
MuonVal::VectorBranch< float > & m_spoint_driftR
MuonVal::ScalarBranch< float > & m_bucket_posY
MuonVal::VectorBranch< float > & m_segmentLocPhi
MuonVal::ScalarBranch< float > & m_bucket_posX
MuonVal::VectorBranch< uint16_t > & m_spoint_adc
MuonVal::MuonIdentifierBranch m_spoint_id
SG::ReadHandleKey< ActsTrk::GeometryContext > m_geoCtxKey
MuonVal::ScalarBranch< uint16_t > & m_bucket_segments
MuonVal::VectorBranch< unsigned int > & m_spoint_dimension
SG::ReadHandleKeyArray< xAOD::MuonSegmentContainer > m_inSegmentKeys
MuonVal::ScalarBranch< uint8_t > & m_bucket_chamberIdx
MuonVal::VectorBranch< float > & m_spoint_covY
MuonVal::MatrixBranch< int16_t > & m_spoint_trueSeg
MuonVal::VectorBranch< unsigned short > & m_spoint_isStrip
MuonVal::VectorBranch< unsigned int > & m_spoint_nEtaInstances
MuonVal::VectorBranch< float > & m_truthSegLocX
MuonVal::VectorBranch< unsigned short > & m_spoint_trueLabel
ServiceHandle< IAthRNGSvc > m_rndmSvc
MuonVal::ScalarBranch< uint16_t > & m_bucket_spacePoints
MuonVal::VectorBranch< float > & m_bucket_ml_score_class2
MuonVal::VectorBranch< unsigned short > & m_spoint_isMdt
virtual StatusCode finalize() override final
MuonVal::ThreeVectorBranch m_spoint_globalPosition
MuonVal::VectorBranch< unsigned short > & m_spoint_measuresPhi
const SpacePointBucket * parentBucket() const
Returns the bucket out of which the seed was formed.
const SegmentSeed * parent() const
Returns the seed out of which the segment was built.
const MeasVec & measurements() const
Returns the associated measurements.
: 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.
unsigned int sectorLayerNum(const SpacePoint &sp) const
method returning the logic layer number
size_t index() const
Return the index of this element within its container.
Helper class to provide constant type-safe access to aux data.
Property holding a SG store/key/clid from which a ReadHandle is made.
const std::string & key() const
Return the StoreGate ID for the referenced object.
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
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.
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.
const xAOD::MuonSegment * getMatchedTruthSegment(const xAOD::MuonSegment &segment)
Returns the truth-matched segment.
std::vector< SegLink_t > SegLinkVec_t
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.
MdtDriftCircle_v1 MdtDriftCircle
MuonSegmentContainer_v1 MuonSegmentContainer
Definition of the current "MuonSegment container version".
TruthParticle_v1 TruthParticle
Typedef to implementation.
MuonSegment_v1 MuonSegment
Reference the current persistent version:
Helper struct to ship the Graph from the space point buckets to ONNX.
Definition GraphData.h:25
std::unique_ptr< InferenceGraph > graph
Pointer to the graph to be parsed to ONNX.
Definition GraphData.h:46