ATLAS Offline Software
Loading...
Searching...
No Matches
JetHitAssociationAlg.cxx
Go to the documentation of this file.
1/*
2Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5//Include header file
7
8#include "JetHitPhiRanges.h"
9
13
14// RoIDescriptor for wedge selections
16
17//Include some helpful ROOT objects here.
18
19#include "CxxUtils/phihelper.h"
20#include <cmath>
21#include <optional>
22#include <algorithm> //sort, min, max
23
24
25namespace FlavorTagDiscriminants {
26
27 JetHitAssociationAlg::JetHitAssociationAlg(const std::string& name, ISvcLocator* loc)
28 : AthReentrantAlgorithm(name, loc) {}
29
30
32 ATH_MSG_INFO("Initializing " << name());
33
34 // Initialize jet keys
35 ATH_CHECK(m_jetCollectionKey.initialize());
36 CHECK(m_hitAssociationKey.initialize());
37
38 ATH_CHECK(m_wedgeZKey.initialize(!m_wedgeZKey.empty()));
39
40 // Initialize hits position decoration keys
42 ATH_CHECK(m_hitsXRelToVertexKey.initialize());
43 ATH_CHECK(m_hitsYRelToVertexKey.initialize());
44 ATH_CHECK(m_hitsZRelToVertexKey.initialize());
45
46 if(m_useDRCone) {
47 if(m_dRHitToJet <= 0) {
48 ATH_MSG_FATAL("Invalid dR cone size!");
49 return StatusCode::FAILURE;
50 }
51 }
52 else if(m_dPhiHitToJet <= 0 || m_dEtaHitToVertex <= 0 || m_dZHitToVertex <= 0) {
53 ATH_MSG_FATAL("Invalid RoiDescriptor size!");
54 return StatusCode::FAILURE;
55 }
56
57 return StatusCode::SUCCESS;
58 }
59
60
61 StatusCode JetHitAssociationAlg::execute(const EventContext& ctx) const {
62 ATH_MSG_DEBUG("Executing " << name());
63
64 // Read out jets
66 if(!jetReadHandle.isValid()) {
67 ATH_MSG_ERROR("Failed to retrieve jet container with key " << m_jetCollectionKey.key());
68 return StatusCode::FAILURE;
69 }
70 // Avoid reading out hits if there are no jets to attach them to
71 if(jetReadHandle->empty()) return StatusCode::SUCCESS;
72
73 // Set up jet decorators
75
76 std::optional<SG::ReadDecorHandle<xAOD::IParticleContainer, float>> wedgeZ;
77 if(!m_wedgeZKey.empty()) wedgeZ.emplace(m_wedgeZKey, ctx);
78
79
80 // Read out hits (we need to keep the handles open to later build the ElementLinks)
82 if(!hitsHandle.isValid()) {
83 ATH_MSG_ERROR("Failed to retrieve hits container with key " << hitsHandle.key());
84 return StatusCode::FAILURE;
85 }
86
90
91 // The bec aux-variable is not declaared through keys to the SG, so it creates dependency errors in the
92 // schedules if we try to use a ReadDecorHandle(Key) for it.
93 static const SG::AuxElement::ConstAccessor<int> bec("bec");
94
95 // Filter input hits
96 std::vector<Hit> hits;
97 hits.reserve(hitsHandle->size());
98 for(const xAOD::TrackMeasurementValidation* hit : *hitsHandle) {
99 const int hit_bec = bec(*hit);
100 if(hit_bec == 0 && !m_includeBarrel) continue;
101 if(hit_bec != 0 && !m_includeEndcap) continue;
102
103 const float hx = x(*hit);
104 const float hy = y(*hit);
105 hits.push_back({hit, std::atan2(hy, hx), z(*hit), std::sqrt(hx*hx + hy*hy)});
106 }
107
108 // Sorting once per event lets each jet binary-search its phi window in
109 // getPhiRanges rather than scan every hit in the event
110 std::sort(hits.begin(), hits.end(),
111 [](const Hit& a, const Hit& b) { return a.phi < b.phi; });
112
113 // Loop over jets
114 for(const xAOD::IParticle* jet : *jetReadHandle) {
115
116 double zed = 0.0;
117 if(wedgeZ) {
118 zed = (*wedgeZ)(*jet);
119 if(!std::isfinite(zed)) {
120 ATH_MSG_WARNING("Wedge z-centre is not finite, dropping hits for this jet.");
121 hitAssociation(*jet) = {};
122 continue;
123 }
124 }
125
126 // Create links and decorate the jet
127 std::vector<ElementLink<xAOD::TrackMeasurementValidationContainer>> links;
128 for(const auto& [dist, hit] : getJetHits(jet, hits, zed)) {
131 hit->index(),
132 ctx
133 ));
134 }
135
136 hitAssociation(*jet) = std::move(links);
137 }
138
139 return StatusCode::SUCCESS;
140 }
141
142
143 const std::vector<std::pair<float, const xAOD::TrackMeasurementValidation*>>
145 const std::vector<Hit>& hits,
146 double zed) const {
147 const double eta = jet->eta();
148 const double phi = jet->phi();
149
150 std::vector<std::pair<float, const xAOD::TrackMeasurementValidation*>> ret;
151
152 // Both selections below imply |dphi| <= halfWidth, so only the hits in
153 // that phi window need testing. The epsilon keeps float rounding from
154 // dropping a hit on the boundary.
155 const float halfWidth =
156 (m_useDRCone ? m_dRHitToJet.value() : m_dPhiHitToJet.value()) + 1e-5f;
157
158 using HitItr = std::vector<Hit>::const_iterator;
159 const std::vector<std::pair<HitItr, HitItr>> ranges =
160 getPhiRanges(hits, phi, halfWidth);
161
162 if(m_useDRCone) {
163 for(const auto& [first, last] : ranges) {
164 for(HitItr it = first; it != last; ++it) {
165 const Hit& hit = *it;
166 const float dEta = eta - std::asinh((hit.z - zed) / hit.r);
167 const float dPhi = CxxUtils::wrapToPi(phi - hit.phi);
168
169 const float dR = std::sqrt(dEta * dEta + dPhi * dPhi);
170 if(dR > m_dRHitToJet) continue;
171
172 ret.emplace_back(dR, hit.original_hit);
173 }
174 }
175 }
176 else {
177 const RoiDescriptor roi(
180 zed, zed - m_dZHitToVertex, zed + m_dZHitToVertex
181 );
182
183 for(const auto& [first, last] : ranges) {
184 for(HitItr it = first; it != last; ++it) {
185 const Hit& hit = *it;
186 if(!RoiUtil::contains(roi, hit.z, hit.r, hit.phi)) continue;
187
188 ret.emplace_back(std::abs(CxxUtils::wrapToPi(phi - hit.phi)), hit.original_hit);
189 }
190 }
191 }
192
193 // If a maximum number of hits has been provided, sort them by distance and truncate the vector
194 if(m_maxHits > 0) {
195 std::sort(ret.begin(), ret.end(), [](const auto& h1, const auto& h2) -> bool { return h1.first < h2.first; });
196 ret.resize(std::min(static_cast<unsigned int>(m_maxHits), static_cast<unsigned int>(ret.size())));
197 }
198
199 return ret;
200 }
201
202}
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_INFO(x,...)
#define ATH_MSG_FATAL(x,...)
#define CHECK(...)
Evaluate an expression and check for errors.
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.
#define y
#define x
#define z
An algorithm that can be simultaneously executed in multiple threads.
virtual StatusCode execute(const EventContext &) const override
SG::ReadDecorHandleKey< xAOD::IParticleContainer > m_wedgeZKey
SG::ReadDecorHandleKey< xAOD::TrackMeasurementValidationContainer > m_hitsYRelToVertexKey
SG::ReadHandleKey< xAOD::TrackMeasurementValidationContainer > m_inputHitCollectionKey
SG::ReadHandleKey< xAOD::IParticleContainer > m_jetCollectionKey
JetHitAssociationAlg(const std::string &name, ISvcLocator *pSvcLocator)
SG::ReadDecorHandleKey< xAOD::TrackMeasurementValidationContainer > m_hitsXRelToVertexKey
const std::vector< std::pair< float, const xAOD::TrackMeasurementValidation * > > getJetHits(const xAOD::IParticle *jet, const std::vector< Hit > &hits, double zed) const
SG::WriteDecorHandleKey< xAOD::IParticleContainer > m_hitAssociationKey
SG::ReadDecorHandleKey< xAOD::TrackMeasurementValidationContainer > m_hitsZRelToVertexKey
Describes the Region of Ineterest geometry It has basically 9 parameters.
Handle class for reading a decoration on an object.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
virtual const std::string & key() const override final
Return the StoreGate ID for the referenced object.
Handle class for adding a decoration to an object.
Class providing the definition of the 4-vector interface.
constexpr T wrapToPi(T phi)
Wrap angle in radians to [-pi, pi].
Definition phihelper.h:31
std::vector< std::pair< typename std::vector< Hit >::const_iterator, typename std::vector< Hit >::const_iterator > > getPhiRanges(const std::vector< Hit > &hits, float phi, float halfWidth)
bool contains(const IRoiDescriptor &roi, double z0, double dzdr)
see whether a segment is contained within the roi in r-z
Definition RoiUtil.cxx:42
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
TrackMeasurementValidation_v1 TrackMeasurementValidation
Reference the current persistent version:
Helper for azimuthal angle calculations.