ATLAS Offline Software
Loading...
Searching...
No Matches
JetVertexFractionTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
5// JetVertexFractionTool.cxx
6
10
11//**********************************************************************
12
14 : asg::AsgTool(name) {
15}
16
17//**********************************************************************
18
20 ATH_MSG_INFO("Initializing JetVertexFractionTool " << name());
21 ATH_MSG_INFO("Using origin vertex: " << m_useOriginVertex);
22
23 if(m_jetContainerName.empty()){
24 ATH_MSG_ERROR("JetVertexFractionTool needs to have its input jet container name configured!");
25 return StatusCode::FAILURE;
26 }
27
28 if ( m_htsel.empty() ) {
29 ATH_MSG_INFO(" No track selector.");
30 } else {
31 ATH_MSG_INFO(" Track selector: " << m_htsel->name());
32 }
33 ATH_MSG_INFO(" Attribute name: " << m_jvfKey.key());
34
36 m_jvfKey = m_jetContainerName + "." + m_jvfKey.key();
39 m_jvfCorrVtxHandleKey = m_jvfCorrKey.key() + "Vec";
40
41#ifndef XAOD_STANDALONE
43 // The user has promised that this will be produced by the same alg running JVF.
44 // Tell the scheduler to ignore it to avoid circular dependencies.
46 }
47#endif
48
49 ATH_CHECK(m_vertexContainer_key.initialize());
50 ATH_CHECK(m_tva_key.initialize());
51 ATH_CHECK(m_tracksCont_key.initialize());
52 ATH_CHECK(m_sumPtTrkKey.initialize());
53 ATH_CHECK(m_jvfKey.initialize());
54 ATH_CHECK(m_jvfCorrKey.initialize());
57
58 return StatusCode::SUCCESS;
59}
60
61StatusCode JetVertexFractionTool::decorate(const xAOD::JetContainer& jetCont) const {
62
63 // Get the vertices container
64 auto vertexContainer = SG::makeHandle (m_vertexContainer_key);
65 if (!vertexContainer.isValid()){
66 ATH_MSG_WARNING("Invalid xAOD::VertexContainer datahandle"
67 << m_vertexContainer_key.key());
68 return StatusCode::FAILURE;
69 }
70 const auto *vertices = vertexContainer.cptr();
71
72 ATH_MSG_DEBUG("Successfully retrieved VertexContainer: "
73 << m_vertexContainer_key.key());
74
75 // Get the Tracks container
76 auto tracksContainer = SG::makeHandle (m_tracksCont_key);
77 if (!tracksContainer.isValid()){
78 ATH_MSG_ERROR("Could not retrieve the TrackParticleContainer: "
79 << m_tracksCont_key.key());
80 return StatusCode::FAILURE;
81 }
82 const auto *tracksCont = tracksContainer.cptr();
83
84 ATH_MSG_DEBUG("Successfully retrieved TrackParticleContainer: "
85 << m_tracksCont_key.key());
86
87 // Get the TVA object
88 auto tvaContainer = SG::makeHandle (m_tva_key);
89 if (!tvaContainer.isValid()){
90 ATH_MSG_ERROR("Could not retrieve the TrackVertexAssociation: "
91 << m_tva_key.key());
92 return StatusCode::FAILURE;
93 }
94 const auto *tva = tvaContainer.cptr();
95
96 ATH_MSG_DEBUG("Successfully retrieved TrackVertexAssociation: "
97 << m_tva_key.key());
98
99 if (vertices->empty() ) {
100 ATH_MSG_WARNING("There are no vertices in the container. Exiting");
101 return StatusCode::SUCCESS;
102 }
103
104 // Get the vertex to calculate with respect to
105 // Only appropriate if we are using a single vertex interpretation, not if using OriginVertex
106 const xAOD::Vertex* HSvertex = nullptr;
108 HSvertex = findHSVertex(vertices);
109
110 // Count pileup tracks - currently done for each collection
111 // Only appropriate if we are using a single vertex interpretation, not if using OriginVertex
112 const int n_putracks = !m_useOriginVertex ? getPileupTrackCount(HSvertex, tracksCont, tva) : -1;
113
117
118 // We don't want to initialize this handle if this is trigger
119 std::unique_ptr<SG::WriteDecorHandle<xAOD::JetContainer, ElementLink<xAOD::VertexContainer> > > maxJvfVtxHandle;
120 if(!m_isTrigger)
121 maxJvfVtxHandle = std::make_unique<SG::WriteDecorHandle<xAOD::JetContainer, ElementLink<xAOD::VertexContainer> > >(m_maxJvfVtxKey);
122
123 for(const xAOD::Jet * jet : jetCont) {
124 // Get origin-vertex-specific information if relevant
126 {
127 HSvertex = jet->getAssociatedObject<xAOD::Vertex>("OriginVertex");
128 if (!HSvertex) // nullptr if the attribute doesn't exist
129 {
130 ATH_MSG_ERROR("OriginVertex was requested, but the jet does not contain an OriginVertex");
131 return StatusCode::FAILURE;
132 }
133 else
134 ATH_MSG_VERBOSE("JetVertexFractionTool " << name() << " is using OriginVertex at index: " << HSvertex->index());
135 }
136 const int n_putracks_local = !m_useOriginVertex ? n_putracks : getPileupTrackCount(HSvertex,tracksCont,tva);
137
138 // Get the tracks associated to the jet
139 // Note that there may be no tracks - this is both normal and an error case
140 std::vector<const xAOD::TrackParticle*> tracks;
141 if ( ! jet->getAssociatedObjects(m_assocTracksName, tracks) ) {
142 ATH_MSG_DEBUG("Associated tracks not found.");
143 }
144
145 // Get the track pT sums for all tracks in the jet (first key) and those associated to PU (second key) vertices.
146 const std::pair<float,float> tracksums = getJetVertexTrackSums(HSvertex, tracks, tva);
147 // Get the track pT sums for each individual vertex
148 std::vector<float> vsumpttrk = sumPtTrkHandle(*jet);
149 float sumpttrk_all = tracksums.first;
150 float sumpttrk_nonPV = tracksums.second;
151 float sumpttrk_PV = vsumpttrk[HSvertex->index() - (*vertices)[0]->index()];
152
153 // Get and set the JVF vector
154 std::vector<float> jvf(vertices->size());
155 for(size_t vtxi=0; vtxi<vertices->size(); ++vtxi) {
156 jvf[vtxi] = sumpttrk_all > 1e-9 ? vsumpttrk[vtxi] / sumpttrk_all : -1;
157 }
158 jvfHandle(*jet) = jvf;
159
160 // Get and set the highest JVF vertex
161 if(!m_isTrigger) {
162 (*maxJvfVtxHandle)(*jet) = getMaxJetVertexFraction(vertices,jvf);
163 }
164 // Calculate JVFCorr
165 // Default JVFcorr to -1 when no tracks are associated.
166 float jvfcorr = -999.;
167 if(sumpttrk_PV + sumpttrk_nonPV > 0) {
168 jvfcorr = sumpttrk_PV / (sumpttrk_PV + ( sumpttrk_nonPV / (m_kcorrJVF * std::max(n_putracks_local, 1) ) ) );
169 } else {
170 jvfcorr = -1;
171 }
172 jvfCorrHandle(*jet) = jvfcorr;
173 }
174
175 if (m_useOriginVertex) { // Add extra info to compute JVT for jets assuming other vertices as origin
176 std::vector<float> jvfCorrVtx;
177
178 auto jvfCorrVtxHandle = std::make_unique<SG::WriteDecorHandle<xAOD::JetContainer, std::vector<float> > >(m_jvfCorrVtxHandleKey);
179
180 for(const xAOD::Jet * jet : jetCont) {
181 jvfCorrVtx.clear();
182 std::vector<float> vsumpttrk = sumPtTrkHandle(*jet);
183
184 // Loop over vertices
185 for(const xAOD::Vertex* pv : *vertices){
186
187 // Calculate JVFCorr for a given vertex
188 // Default JVFcorr to -1 when no tracks are associated. - copied from JetVertexFractionTool.cxx
189 // Get the tracks associated to the jet
190 // Note that there may be no tracks - this is both normal and an error case
191 std::vector<const xAOD::TrackParticle*> tracks;
192 if ( ! jet->getAssociatedObjects(m_assocTracksName, tracks) ) {
193 ATH_MSG_DEBUG("Associated tracks not found.");
194 }
195
196 const int n_putracks = getPileupTrackCount(pv, tracksCont, tva);
197
198 // Get the track pT sums for all tracks in the jet (first key) and those associated to PU(?) (second key) vertices.
199 const std::pair<float,float> tracksums = getJetVertexTrackSums(pv, tracks, tva);
200 // Get the track pT sums for each individual vertex
201
202 float sumpttrk_PV = vsumpttrk[pv->index()];
203 float sumpttrk_nonPV = tracksums.second; // Consider as "PU" all vertices not matching the one I'm looping over
204 float jvfcorr = -999.;
205 float kcorrJVF = 0.01;
206 if(sumpttrk_PV + sumpttrk_nonPV > 0) {
207 jvfcorr = sumpttrk_PV / (sumpttrk_PV + ( sumpttrk_nonPV / (kcorrJVF * std::max(n_putracks, 1) ) ) );
208 } else {
209 jvfcorr = -1;
210 }
211 jvfCorrVtx.push_back(jvfcorr);
212 }
213
214 (*jvfCorrVtxHandle)(*jet) = jvfCorrVtx;
215 // Done
216
217 }
218 }
219 return StatusCode::SUCCESS;
220}
221
222//**********************************************************************
223
226 const std::vector<float>& jvf) const {
227 size_t maxIndex = 0;
228 float maxVal = -100;
229 for ( size_t iVertex = 0; iVertex < jvf.size(); ++iVertex ) {
230 if ( jvf.at(iVertex) > maxVal ) {
231 maxIndex = iVertex;
232 maxVal = jvf.at(iVertex);
233 }
234 }
236 ElementLink<xAOD::VertexContainer>(*vertices,vertices->at(maxIndex)->index());
237 return link;
238}
239
240//**********************************************************************
241
243 const std::vector<const xAOD::TrackParticle*>& tracks,
244 const jet::TrackVertexAssociation* tva) const {
245 float sumTrackAll = 0;
246 float sumTracknotPV = 0;
247 bool notsel = m_htsel.empty();
248 unsigned int nkeep = 0;
249 unsigned int nskip = 0;
250 for (size_t iTrack = 0; iTrack < tracks.size(); ++iTrack) {
251 const xAOD::TrackParticle* track = tracks.at(iTrack);
252 if ( notsel || m_htsel->accept(*track) ) {
253 sumTrackAll += track->pt();
254
255 const xAOD::Vertex* ptvtx = tva->associatedVertex(track);
256 if( ptvtx != nullptr ) {
257 // Track has vertex, assign to appropriate pT sum
258 if ( ptvtx->index() != vertex->index() ) {sumTracknotPV += track->pt(); }
259 }
260 ++nkeep;
261 }
262 else { ++nskip; }
263 }
264 ATH_MSG_VERBOSE("JetVertexTaggerTool " << name()
265 << ": nsel=" << nkeep
266 << ", nrej=" << nskip );
267
268 return std::make_pair(sumTrackAll,sumTracknotPV);
269
270}
271
272
273//**********************************************************************
274
276 const xAOD::TrackParticleContainer*& tracksCont,
277 const jet::TrackVertexAssociation* tva) const
278{
279 int n_pileuptrackcount = 0;
280 bool notsel = m_htsel.empty();
281 unsigned int nkeep = 0;
282 unsigned int nskip = 0;
283 int tot_count = 0;
284 for(size_t iTrack = 0; iTrack < tracksCont->size(); ++iTrack)
285 {
286 const xAOD::TrackParticle * track = tracksCont->at(iTrack);
287 if ( notsel || m_htsel->accept(*track) ) {
288 const xAOD::Vertex* ptvtx = tva->associatedVertex(track);
289 // Count track as PU if associated with non-primary vertex and within pT cut.
290 // N.B. tracks with no vertex associated may be added to PV track sums, but not PU sums, nor the PU vertex counting.
291 if ( ptvtx != nullptr ) {
292 if ( (ptvtx->index() != vertex->index() ) && (track->pt() < m_PUtrkptcut) ) ++n_pileuptrackcount;
293 }
294 tot_count++;
295 ++nkeep;
296 }
297 else { ++nskip; }
298 }
299 const int n_pileuptracks = n_pileuptrackcount;
300
301 ATH_MSG_VERBOSE("JetVertexFractionTool " << name()
302 << ": nsel=" << nkeep
303 << ", nrej=" << nskip
304 << ", total " << tracksCont->size() );
305 ATH_MSG_VERBOSE("JetVertexFractionTool " << name()
306 << ": n_PUtracks=" << n_pileuptracks
307 << ", total=" << tot_count );
308
309 return n_pileuptracks;
310}
311
312//**********************************************************************
313
315{
316 const xAOD::Vertex* primvert = nullptr;
317 for (const xAOD::Vertex* pv : *vertices) {
318 if (pv->vertexType() == xAOD::VxType::PriVtx ) {
319 primvert = pv;
320 ATH_MSG_VERBOSE("JetVertexFractionTool " << name() << " Found HS vertex.");
321 break;
322 }
323 }
324 if (primvert == nullptr ) {
325 ATH_MSG_VERBOSE("There is no vertex of type PriVx. Taking default vertex.");
326 primvert = *(vertices->begin());
327 }
328 return primvert;
329}
#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)
Handle class for reading a decoration on an object.
Handle class for adding a decoration to an object.
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce(T &h)
const T * at(size_type n) const
Access an element, as an rvalue.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
Gaudi::Property< bool > m_isTrigger
ElementLink< xAOD::VertexContainer > getMaxJetVertexFraction(const xAOD::VertexContainer *, const std::vector< float > &) const
int getPileupTrackCount(const xAOD::Vertex *, const xAOD::TrackParticleContainer *&, const jet::TrackVertexAssociation *) const
SG::WriteDecorHandleKey< xAOD::JetContainer > m_maxJvfVtxKey
SG::ReadDecorHandleKey< xAOD::JetContainer > m_sumPtTrkKey
Gaudi::Property< std::string > m_jetContainerName
SG::WriteDecorHandleKey< xAOD::JetContainer > m_jvfKey
virtual StatusCode initialize() override
Dummy implementation of the initialisation function.
virtual StatusCode decorate(const xAOD::JetContainer &jetCont) const override
Decorate a jet collection without otherwise modifying it.
std::pair< float, float > getJetVertexTrackSums(const xAOD::Vertex *, const std::vector< const xAOD::TrackParticle * > &, const jet::TrackVertexAssociation *) const
ToolHandle< InDet::IInDetTrackSelectionTool > m_htsel
const xAOD::Vertex * findHSVertex(const xAOD::VertexContainer *&) const
JetVertexFractionTool(const std::string &name)
Gaudi::Property< float > m_kcorrJVF
SG::ReadHandleKey< jet::TrackVertexAssociation > m_tva_key
SG::ReadHandleKey< xAOD::VertexContainer > m_vertexContainer_key
Gaudi::Property< float > m_PUtrkptcut
Gaudi::Property< bool > m_useOriginVertex
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_tracksCont_key
SG::WriteDecorHandleKey< xAOD::JetContainer > m_jvfCorrVtxHandleKey
Gaudi::Property< bool > m_suppressInputDeps
Gaudi::Property< std::string > m_assocTracksName
SG::WriteDecorHandleKey< xAOD::JetContainer > m_jvfCorrKey
size_t index() const
Return the index of this element within its container.
Handle class for reading a decoration on an object.
Handle class for adding a decoration to an object.
AsgTool(const std::string &name)
Constructor specifying the tool instance's name.
Definition AsgTool.cxx:58
Class to hold N-to-one aassociations between tracks and vertices.
const xAOD::Vertex * associatedVertex(const xAOD::TrackParticle *trk) const
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
@ PriVtx
Primary vertex.
Jet_v1 Jet
Definition of the current "jet version".
TrackParticle_v1 TrackParticle
Reference the current persistent version:
VertexContainer_v1 VertexContainer
Definition of the current "Vertex container version".
Vertex_v1 Vertex
Define the latest version of the vertex class.
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
JetContainer_v1 JetContainer
Definition of the current "jet container version".