ATLAS Offline Software
Loading...
Searching...
No Matches
CleanHitDecoratorAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6
10
12
13#include <algorithm>
14#include <cmath>
15#include <limits>
16#include <optional>
17
18namespace {
19
20 struct HitPos {
21 float z;
22 float phi;
23 unsigned long deid;
24 int layer;
25 };
26
27 inline float deltaPhi(const HitPos& a, const HitPos& b) {
28 float d = b.phi - a.phi;
29 if (d > M_PI) d -= 2*M_PI;
30 else if (d <= -M_PI) d += 2*M_PI;
31 return d;
32 }
33
34 inline bool isGoodHit(
39 if (isFakeHandle(*h)) return false;
40 if (hasBSErrHandle(*h)) return false;
41 if (DCSStateHandle(*h)) return false;
42 return true;
43 }
44
45}
46
47namespace FlavorTagDiscriminants {
48
49 CleanHitDecoratorAlg::CleanHitDecoratorAlg(const std::string& name, ISvcLocator* svcLoc)
50 : AthReentrantAlgorithm(name, svcLoc) {}
51
53 ATH_MSG_DEBUG("Initializing " << name());
54
55 ATH_CHECK(m_hitContainer.initialize());
56
57 ATH_CHECK(m_cleanHitKey.initialize());
58
59 // The goodness decorations exist only on pixel hits
60 ATH_CHECK(m_isFakeKey.initialize(!m_isSCT));
61 ATH_CHECK(m_hasBSErrKey.initialize(!m_isSCT));
62 ATH_CHECK(m_DCSStateKey.initialize(!m_isSCT));
63
64 // The geometry decorations are read only by the overlap removal
68
69 return StatusCode::SUCCESS;
70 }
71
72 StatusCode CleanHitDecoratorAlg::execute(const EventContext& ctx) const {
73 // Read hits
75 if (!hits.isValid()) {
76 ATH_MSG_ERROR("Failed to retrieve " << m_hitContainer.key());
77 return StatusCode::FAILURE;
78 }
79
80 // Decoration handle
82 cleanDeco(m_cleanHitKey, ctx);
83
84 std::optional<SG::ReadDecorHandle<xAOD::TrackMeasurementValidationContainer, char>>
85 isFakeHandle;
86 std::optional<SG::ReadDecorHandle<xAOD::TrackMeasurementValidationContainer, int>>
87 hasBSErrHandle;
88 std::optional<SG::ReadDecorHandle<xAOD::TrackMeasurementValidationContainer, int>>
89 DCSStateHandle;
90 if (!m_isSCT) {
91 isFakeHandle.emplace(m_isFakeKey, ctx);
92 hasBSErrHandle.emplace(m_hasBSErrKey, ctx);
93 DCSStateHandle.emplace(m_DCSStateKey, ctx);
94 }
95
96 // Without overlap removal the flag depends only on the hit itself, so neither
97 // the geometry nor the ordering is needed
98 if (!m_doOverlapRemoval) {
99 for (const xAOD::TrackMeasurementValidation* hit : *hits) {
100 cleanDeco(*hit) =
101 (m_isSCT || isGoodHit(hit, *isFakeHandle, *hasBSErrHandle, *DCSStateHandle)) ? 1 : 0;
102 }
103 return StatusCode::SUCCESS;
104 }
105
107 becHandle(m_becKey, ctx);
109 deidHandle(m_deidKey, ctx);
111 layerHandle(m_layerKey, ctx);
112
113 std::vector<std::pair<float, const xAOD::TrackMeasurementValidation*>> hits_sorted;
114 hits_sorted.reserve(hits->size());
115
116 for (const xAOD::TrackMeasurementValidation* hit : *hits) {
117 hits_sorted.emplace_back(hit->localX(), hit);
118 }
119
120 std::ranges::sort(hits_sorted);
121
122 std::vector<std::vector<HitPos>> savedHits;
123
124 for (const auto& [localX, hit] : hits_sorted) {
125
126 int cleanFlag = 1;
127
128 // Extract geometry
129 HitPos hp;
130 hp.z = hit->globalZ();
131 hp.phi = std::atan2(hit->globalY(), hit->globalX());
132 hp.deid = deidHandle(*hit);
133 hp.layer = layerHandle(*hit);
134
135 const bool isBarrel = (becHandle(*hit) == 0);
136
137 // Overlap evaluation
138 const float dZcut = 20.f;
139 const float dPhicut = isBarrel ? 0.004f : std::numeric_limits<float>::max();
140
141 if (static_cast<size_t>(hp.layer) >= savedHits.size()) {
142 savedHits.resize(hp.layer + 1);
143 }
144
145 auto& layerHits = savedHits[hp.layer];
146
147 for (const HitPos& prev : layerHits) {
148
149 // Skip hits from the same module
150 if (prev.deid == hp.deid)
151 continue;
152
153 const float dphi = std::abs(deltaPhi(prev, hp));
154 const float dz = std::abs(prev.z - hp.z);
155
156 if (dphi < dPhicut && dz < dZcut) {
157 cleanFlag = 0;
158 break;
159 }
160 }
161
162 // Mark bad hits
163 if (!m_isSCT && !isGoodHit(hit, *isFakeHandle, *hasBSErrHandle, *DCSStateHandle)) {
164 cleanFlag = 0;
165 }
166
167 // Write decoration
168 cleanDeco(*hit) = cleanFlag;
169
170 // Save for next comparisons
171 layerHits.push_back(hp);
172 }
173
174 return StatusCode::SUCCESS;
175 }
176
177}
#define M_PI
Scalar deltaPhi(const MatrixBase< Derived > &vec) const
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_DEBUG(x)
Base class for elements of a container that can have aux data.
bool hit(const Container &ids, int pdgId)
static Double_t a
Handle class for reading a decoration on an object.
Handle class for reading from StoreGate.
Handle class for adding a decoration to an object.
Header file for AthHistogramAlgorithm.
An algorithm that can be simultaneously executed in multiple threads.
CleanHitDecoratorAlg(const std::string &name, ISvcLocator *svcLoc)
SG::ReadDecorHandleKey< xAOD::TrackMeasurementValidationContainer > m_deidKey
SG::ReadDecorHandleKey< xAOD::TrackMeasurementValidationContainer > m_hasBSErrKey
SG::ReadDecorHandleKey< xAOD::TrackMeasurementValidationContainer > m_DCSStateKey
virtual StatusCode execute(const EventContext &ctx) const override
SG::ReadHandleKey< xAOD::TrackMeasurementValidationContainer > m_hitContainer
SG::ReadDecorHandleKey< xAOD::TrackMeasurementValidationContainer > m_becKey
SG::ReadDecorHandleKey< xAOD::TrackMeasurementValidationContainer > m_layerKey
SG::ReadDecorHandleKey< xAOD::TrackMeasurementValidationContainer > m_isFakeKey
SG::WriteDecorHandleKey< xAOD::TrackMeasurementValidationContainer > m_cleanHitKey
Handle class for reading a decoration on an object.
Handle class for adding a decoration to an object.
bool isGoodHit(const CalibratedSpacePoint &hit)
Returns whether the calibrated spacepoint is valid and therefore suitable to be used in the segment f...
TrackMeasurementValidation_v1 TrackMeasurementValidation
Reference the current persistent version: