4#ifndef MUONINFERENCE_SEGMENTEDGEINFERENCEALG_H
5#define MUONINFERENCE_SEGMENTEDGEINFERENCEALG_H
10#include "Gaudi/Property.h"
20#include <unordered_map>
21#include <unordered_set>
27 using AthReentrantAlgorithm::AthReentrantAlgorithm;
29 StatusCode
execute(
const EventContext& ctx)
const override;
39 const std::unordered_map<std::uint64_t, float>& pairProbability,
40 const std::vector<unsigned char>& thresholded,
41 const std::vector<std::uint8_t>& keptNode,
42 const std::vector<unsigned char>& nodeDropReason)
const;
48 const std::unordered_map<std::int32_t, std::unordered_set<unsigned>>& muonComponents,
49 const std::unordered_map<std::int32_t, bool>& muonEverMixed,
50 const std::unordered_map<std::int32_t, double>& truthIdToAbsEta)
const;
56 this,
"PairGateDecoration",
"MsSegments.mlTrackComponent"};
61 this,
"ComponentScoreDecoration",
"MsSegments.mlComponentScore"};
63 this,
"FilteredSegmentKey",
"",
64 "Optional VIEW container containing only segments incident to a "
65 "post-classifier selected edge; empty disables the output"};
67 this,
"PairGateThreshold", 0.5f,
68 "Minimum edge probability used to form ML track components"};
70 this,
"MaxEdgesPerNode", 2,
71 "Keep at most this many highest-score neighbours per segment when forming the ML path graph; zero keeps all"};
73 this,
"MaxEdgesPerNodePerLayer", 0,
74 "If > 0, each segment nominates its this-many highest-score edges towards EACH layer (Inner, "
75 "Middle, Outer, Extended, ...) instead of its MaxEdgesPerNode best edges overall; zero keeps "
78 this,
"UseDegreeCappedComponents",
false,
79 "Use a global greedy degree cap instead of the mutual top-K path graph"};
81 this,
"RequireMutualTopKEdges",
true,
82 "Retain an ML association only when both endpoint segments rank it in their top MaxEdgesPerNode scores"};
84 this,
"RecoverOrphanNodes",
true,
85 "For a thresholded node without a mutual top-K edge, retain its best one-sided top-K association"};
87 this,
"SeedAnchorsPerComponent", 0,
88 "Number of highest-score segments that may seed each ML component; zero keeps every retained segment"};
90 this,
"AnchorInnermostLayer",
false,
91 "Restrict seed anchors to inner segment(s); with SeedAnchorsPerComponent > 0 keep only "
92 "the inner segment(s) with the strongest selected edge towards another layer"};
94 this,
"KeepBestSegmentPerChamber",
true,
95 "Keep only the ML-best segment in each chamber within a component"};
97 this,
"MinSegmentsPerComponent", 2,
98 "Discard ML components with fewer retained segments"};
99 ToolHandle<ISegmentEdgeClassifierTool>
m_edgeClassifier{
this,
"EdgeClassifierTool",
"MuonML::SegmentEdgeClassifierTool/SegmentEdgeClassifierTool"};
134 mutable std::array<std::atomic<std::size_t>, 2> m_sumTrueCrossLayerSelected
ATLAS_THREAD_SAFE{};
145 std::array<std::atomic<std::size_t>, 5>
scoreBin{};
DataVector adapter that acts like it holds const pointers.
Property holding a SG store/key/clid from which a ReadHandle is made.
Property holding a SG store/key/clid/attr name from which a WriteDecorHandle is made.
Property holding a SG store/key/clid from which a WriteHandle is made.
Define macros for attributes used to control the static checker.
An algorithm that can be simultaneously executed in multiple threads.
std::atomic< std::size_t > m_sumOnnxBkgSegments
std::atomic< std::size_t > m_sumChamberSuppressedNodes
Gaudi::Property< bool > m_keepBestSegmentPerChamber
void classifyGroupPurity(const std::unordered_map< std::int32_t, std::unordered_set< unsigned > > &muonComponents, const std::unordered_map< std::int32_t, bool > &muonEverMixed, const std::unordered_map< std::int32_t, double > &truthIdToAbsEta) const
MC-only: given the per-muon component memberships and mixed-status gathered while the per-component c...
std::atomic< std::size_t > m_sumRetainedNodes
Gaudi::Property< bool > m_anchorInnermostLayer
SG::WriteDecorHandleKey< xAOD::MuonSegmentContainer > m_pairGateDecorKey
Per-segment payload consumed by MlMsTrackSeeder: [componentId, anchorRank + 1] Empty means that the s...
Gaudi::Property< bool > m_useDegreeCappedComponents
std::atomic< std::size_t > m_sumOrphanRecoveryPairs
ToolHandle< ISegmentEdgeClassifierTool > m_edgeClassifier
StatusCode finalize() override
Log of the post-ONNX rank/mutuality and min-component-size selection.
Gaudi::Property< unsigned int > m_maxEdgesPerNode
std::atomic< std::size_t > m_sumThresholdedNodes
std::atomic< std::size_t > m_sumRetainedBkgSegments
std::array< std::atomic< std::size_t >, 2 > m_sumTrueCrossLayerEdges ATLAS_THREAD_SAFE
True cross-layer edges above PairGateThreshold, total and kept by the selection; barrel / endcap Ever...
Gaudi::Property< bool > m_requireMutualTopKEdges
std::atomic< std::size_t > m_sumOneSidedTopKPairs
std::atomic< std::size_t > m_sumInputBkgSegments
void classifyLostTruthSegments(const xAOD::MuonSegmentContainer &segments, const SegmentEdgeGraph &graph, const std::unordered_map< std::uint64_t, float > &pairProbability, const std::vector< unsigned char > &thresholded, const std::vector< std::uint8_t > &keptNode, const std::vector< unsigned char > &nodeDropReason) const
MC-only: classify every truth-labeled input segment that did not make it into the filtered container ...
std::atomic< std::size_t > m_sumTrueEdgesPassed
bool m_truthDiagEnabled
Whether truth-particle matching is available/enabled this job.
std::atomic< std::size_t > m_sumBkgEdgesPassed
StatusCode execute(const EventContext &ctx) const override
std::atomic< std::size_t > m_sumBkgEdgesTotal
std::atomic< std::size_t > m_sumGraphNodes
Job-summed post-ONNX selection counters (see execute()).
std::atomic< bool > m_warnedMissingToolDiagnostics
StatusCode initialize() override
Gaudi::Property< unsigned int > m_minSegmentsPerComponent
std::atomic< std::size_t > m_sumOnnxTruthSegments
std::atomic< std::size_t > m_sumInputTruthSegments
std::atomic< std::size_t > m_sumNodesRejectedByMinComponent
std::atomic< std::size_t > m_sumTrueEdgesTotal
std::atomic< std::size_t > m_sumRetainedTruthSegments
SG::WriteHandleKey< ConstDataVector< xAOD::MuonSegmentContainer > > m_filteredSegmentKey
Gaudi::Property< bool > m_recoverOrphanNodes
std::atomic< std::size_t > m_sumMutualTopKPairs
Gaudi::Property< unsigned int > m_maxEdgesPerNodePerLayer
SG::WriteDecorHandleKey< xAOD::MuonSegmentContainer > m_componentScoreDecorKey
Per-segment ML scores for MlMsTrackSeeder: [strongest selected cross-layer edge of the segment's comp...
std::atomic< std::size_t > m_sumRejectedComponents
SG::ReadHandleKey< xAOD::MuonSegmentContainer > m_segmentKey
Gaudi::Property< unsigned int > m_seedAnchorsPerComponent
Gaudi::Property< float > m_pairGateThreshold
std::atomic< std::size_t > m_sumTopologyNodes
std::atomic< std::size_t > m_sumComponentsKept
Property holding a SG store/key/clid from which a ReadHandle is made.
Property holding a SG store/key/clid/attr name from which a WriteDecorHandle is made.
Property holding a SG store/key/clid from which a WriteHandle is made.
MuonSegmentContainer_v1 MuonSegmentContainer
Definition of the current "MuonSegment container version".
Job-summed grouping-purity diagnostics: does a formed (kept) component mix segments from more than on...
static constexpr std::size_t kCrossEdgeBins
std::atomic< std::size_t > weakCleanWithOther
std::atomic< std::size_t > weakCleanAlone
static constexpr std::size_t kSizeBins
std::atomic< std::uint64_t > worstMixedPacked
std::array< std::atomic< std::size_t >, 3 *kSizeBins > sizeByOutcome
retained segments
std::array< std::atomic< std::size_t >, 3 > componentsByOutcome
clean / mixed / bkgOnly
std::array< std::atomic< std::size_t >, kColumns *3 > muonOutcome
clean/mixed/fragmented, per column
std::atomic< std::size_t > mixedComponentSegments
std::array< std::atomic< std::size_t >, 3 *kScoreBins > scoreByOutcome
Kept components split by outcome (clean / mixed / bkgOnly), index = outcome * nBins + bin.
static constexpr std::size_t kColumns
static constexpr std::size_t kScoreBins
static constexpr std::size_t kLayerBins
std::array< std::atomic< std::size_t >, 3 *kLayerBins > layersByOutcome
distinct LayerIndex
std::array< std::atomic< std::size_t >, kSizeBins > componentSizeHist
static constexpr std::size_t kCrossScoreBins
Components spanning >= 2 layers (the only ones that can seed), per outcome:
std::array< std::atomic< std::size_t >, 3 *kCrossEdgeBins > crossEdgesByOutcome
number of cross-layer edges
std::array< std::atomic< std::size_t >, 3 *kCrossScoreBins > crossScoreByOutcome
strongest cross-layer edge
Job-summed classification of lost truth segments (classifyLostTruthSegments()).
static constexpr std::size_t kColumns
std::array< std::atomic< std::size_t >, 4 > layerPair
IM / MO / IO / other (C).
std::array< std::atomic< std::size_t >, kCategories *kColumns > category
std::array< std::atomic< std::size_t >, 3 > precisionHits
nPrecisionHits <=4 / 5-6 / >=7 (C)
std::array< std::atomic< std::size_t >, 4 > muonsSeedable
truth muons with >= 2 input chambers (all / regions)
std::array< std::atomic< std::size_t >, 2 > sectorDelta
same / adjacent sector (C)
std::array< std::atomic< std::size_t >, 5 > scoreBin
best true-pair score of category C
std::array< std::atomic< std::size_t >, 4 > muonsSeedLost
... of which < 2 chambers retained
std::array< std::atomic< std::size_t >, 4 > muonSegments
muon has 2 / 3 / 4 / 5+ input segments (C)
static constexpr std::size_t kCategories