ATLAS Offline Software
Loading...
Searching...
No Matches
MuonPrecisionLayerDecorAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
8
9#include <unordered_map>
10namespace{
11 static const SG::AuxElement::ConstAccessor<std::vector<std::vector<unsigned int>>> acc_alignEffectChId("alignEffectChId");
12 static const SG::AuxElement::ConstAccessor<std::vector<float>> acc_alligSigmaDeltaTrans("alignEffectSigmaDeltaTrans");
13 constexpr unsigned badQualityFlag = 2;
14 constexpr unsigned goodQualityFlag = 1;
15
16}
17
19 ATH_CHECK(m_MuonContainer.initialize());
20 ATH_CHECK(m_TrackContainer.initialize());
21 m_trkAlignReadKey.clear();
23 m_trkAlignReadKey.emplace_back(trk, "alignEffectChId");
24 m_trkAlignReadKey.emplace_back(trk, "alignEffectSigmaDeltaTrans");
25 }
26 ATH_CHECK(m_trkAlignReadKey.initialize());
27 ATH_CHECK(m_goodPrecLayerKey.initialize());
28 ATH_CHECK(m_isGoodSmallKey.initialize());
30 return StatusCode::SUCCESS;
31 }
32
33 StatusCode MuonPrecisionLayerDecorAlg::execute(const EventContext& ctx) const {
35 if (!muons.isValid()) {
36 ATH_MSG_FATAL("Failed to load track collection "<<m_MuonContainer.fullKey());
37 return StatusCode::FAILURE;
38 }
42
43 for (const xAOD::Muon* mu : *muons) {
44 // no CT or ST muons
45 if (mu->primaryTrackParticle() == mu->trackParticle(xAOD::Muon::InnerDetectorTrackParticle)) continue;
46 // no SA muons w/o ME tracks
47 if (mu->primaryTrackParticle() == mu->trackParticle(xAOD::Muon::MuonSpectrometerTrackParticle)) continue;
48 const xAOD::TrackParticle* ptp = mu->primaryTrackParticle();
49 const std::vector<std::vector<unsigned int>>& chIds = acc_alignEffectChId(*ptp);
50 const std::vector<float>& alignEffSDT = acc_alligSigmaDeltaTrans(*ptp);
51
52 uint8_t prec{0}; // all precision layers
53 mu->summaryValue(prec, xAOD::numberOfPrecisionLayers);
54 const uint8_t nTotPrec = prec;
55 uint8_t nBadPrec{0}, nBadBar{0}, nBadSmall{0}, nBadLarge{0}, nGoodBar{0}, nGoodLarge{0}, nGoodSmall{0};
56
57 using namespace Muon::MuonStationIndex;
58 std::unordered_map<ChIndex, int> chamberQual{}; // 1=good, 2=bad; for choosing large/small
60 for (unsigned int i = 0; i < chIds.size(); ++i) {
62 for (unsigned int j = 0; j < chIds[i].size(); ++j) {
63 const auto currInd = static_cast<ChIndex>(chIds[i][j]);
64 const int quality = alignEffSDT[i] >= 0.5 ? badQualityFlag : goodQualityFlag;
65 if ((chamberQual.count(currInd) && chIds[i].size() > 1) || !chamberQual.count(currInd)) {
66 // either we haven't seen this chamber before, or we have but now
67 // we're in a sub-vector that's not just this chamber
68 chamberQual[currInd] = quality;
69 }
70 }
71 }
72 for (const auto& [chamber, quality] : chamberQual) {
73 const bool is_barrel = isBarrel(chamber);
74 const bool is_small = isSmall(chamber);
75 if (quality == badQualityFlag) {
76 ++nBadPrec;
77 nBadBar+= is_barrel;
78 nBadSmall+= is_small;
79 nBadLarge+= !is_small;
80 } else {
81 nGoodBar+= is_barrel;
82 nGoodLarge+= !is_small;
83 nGoodSmall+= is_small;
84 }
85 }
86 const uint8_t nGoodPrec = nTotPrec - nBadPrec;
87 const uint8_t nBadEnd = nBadPrec - nBadBar;
88 const uint8_t nGoodEnd = nGoodPrec - nGoodBar;
89 const bool countHits = (nGoodSmall == nGoodLarge) || (nBadSmall == nBadLarge);
90
91 uint8_t isSmall = (nGoodPrec >= nBadPrec&& nGoodSmall > nGoodLarge) || (nGoodPrec < nBadPrec&& nBadSmall > nBadLarge);
92 const uint8_t isEnd = (nGoodPrec >= nBadPrec&& nGoodEnd > nGoodBar) || (nGoodPrec < nBadPrec && nBadEnd >nBadBar );
93
94 static constexpr std::array<xAOD::MuonSummaryType, 4> small_sectors{xAOD::innerSmallHits, xAOD::middleSmallHits, xAOD::outerSmallHits, xAOD::extendedSmallHits};
95 static constexpr std::array<xAOD::MuonSummaryType, 4> large_sectors{xAOD::innerLargeHits, xAOD::middleLargeHits, xAOD::outerLargeHits, xAOD::extendedLargeHits};
96
97 if (countHits) { // decide large-small by counting hits
98 auto accumulator = [mu](int val, const xAOD::MuonSummaryType& sum) -> int{
99 uint8_t sumval = 0;
100 mu->summaryValue(sumval,sum);
101 return val +sumval;
102 };
103 const int nSmallHits = std::accumulate(small_sectors.begin(), small_sectors.end(),0 ,accumulator);
104 const int nLargeHits = std::accumulate(large_sectors.begin(), large_sectors.end(),0 ,accumulator);
105 isSmall = (nSmallHits > nLargeHits);
106 }
107 acc_precLayers(*mu) = nGoodPrec;
108 acc_isSmallGood(*mu) = isSmall;
109 acc_isEndcapGood(*mu) = isEnd;
110 }
111 return StatusCode::SUCCESS;
112 }
113
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
Handle class for reading from StoreGate.
Handle class for adding a decoration to an object.
SG::ReadHandleKey< xAOD::MuonContainer > m_MuonContainer
SG::ReadDecorHandleKeyArray< xAOD::TrackParticleContainer > m_trkAlignReadKey
SG::ReadHandleKeyArray< xAOD::TrackParticleContainer > m_TrackContainer
SG::WriteDecorHandleKey< xAOD::MuonContainer > m_goodPrecLayerKey
SG::WriteDecorHandleKey< xAOD::MuonContainer > m_isEndcapGoodLayersKey
SG::WriteDecorHandleKey< xAOD::MuonContainer > m_isGoodSmallKey
virtual StatusCode initialize() override
virtual StatusCode execute(const EventContext &ctx) const override
SG::ConstAccessor< T, ALLOC > ConstAccessor
Definition AuxElement.h:569
Property holding a SG store/key/clid from which a ReadHandle is made.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
Handle class for adding a decoration to an object.
bool isSmall(const ChIndex index)
Returns true if the chamber index is in a small sector.
bool isBarrel(const ChIndex index)
Returns true if the chamber index points to a barrel chamber.
ChIndex
enum to classify the different chamber layers in the muon spectrometer
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Muon_v1 Muon
Reference the current persistent version:
@ numberOfPrecisionLayers
layers with at least 3 hits [unit8_t].
MuonSummaryType
Enumerates the different types of information stored in Summary.
@ outerSmallHits
number of precision hits in the outer small layer
@ middleSmallHits
number of precision hits in the middle small layer
@ outerLargeHits
number of precision hits in the outer large layer
@ middleLargeHits
number of precision hits in the middle large layer
@ extendedSmallHits
number of precision hits in the extended small layer
@ extendedLargeHits
number of precision hits in the extended large layer
@ innerLargeHits
number of precision hits in the inner large layer
@ innerSmallHits
number of precision hits in the inner small layer