ATLAS Offline Software
Loading...
Searching...
No Matches
CVFAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3 */
4
5#include "CVFAlg.h"
10
11// NB: We should try and get something like the faster binned phi approach used
12// in the PFlow construction. Of course, we might *really* want to just find a
13// way of sharing that information? (for the track <-> cluster association)
14namespace
15{
16 bool fastDR(
17 double eta,
18 double phi,
20 double dr,
21 double dr2)
22 {
23 double dEta = std::abs(eta - track.eta);
24 if (dEta > dr)
25 return false;
26 double dPhi = std::abs(phi - track.phi);
27 if (dPhi > dr)
28 return false;
29 return (dEta * dEta + dPhi * dPhi) < dr2;
30 }
31} // namespace
32
33namespace HLT
34{
35 namespace MET
36 {
37 CVFAlg::CVFAlg(const std::string &name, ISvcLocator *pSvcLocator)
38 : AthReentrantAlgorithm(name, pSvcLocator)
39 {
40 }
41
42 StatusCode CVFAlg::initialize()
43 {
44 ATH_MSG_DEBUG("Initializing " << name());
45 CHECK(m_extensionTool.retrieve());
46 if (!m_trackSelTool.empty())
47 {
48 CHECK(m_trackSelTool.retrieve());
49 m_useTrackSelTool = true;
50 }
51 CHECK(m_tvaTool.retrieve());
52 CHECK(m_inputClusterKey.initialize());
53 CHECK(m_inputTrackKey.initialize());
54 CHECK(m_inputVertexKey.initialize());
55 if (m_outputCVFKey.key().find(".") == std::string::npos)
58 {
59 ATH_MSG_ERROR("CVF key does not match input cluster key!");
60 return StatusCode::FAILURE;
61 }
62 CHECK(m_outputCVFKey.initialize());
63 return StatusCode::SUCCESS;
64 }
65
66 StatusCode CVFAlg::execute(const EventContext &ctx) const
67 {
68 using TrackExtension = IExtendTrackToLayerTool::TrackExtension;
69
70 auto clusters = SG::makeHandle(m_inputClusterKey, ctx);
71 if (!clusters.isValid())
72 {
73 ATH_MSG_ERROR("Failed to retrieve " << m_inputClusterKey);
74 return StatusCode::FAILURE;
75 }
76 auto tracks = SG::makeHandle(m_inputTrackKey, ctx);
77 if (!tracks.isValid())
78 {
79 ATH_MSG_ERROR("Failed to retrieve " << m_inputTrackKey);
80 return StatusCode::FAILURE;
81 }
82 auto vertexHandle = SG::makeHandle(m_inputVertexKey, ctx);
83 if (!vertexHandle.isValid())
84 {
85 ATH_MSG_ERROR("Failed to retrieve " << m_inputVertexKey);
86 return StatusCode::FAILURE;
87 }
88 auto decCVF = SG::makeHandle<float>(m_outputCVFKey, ctx);
89
90 // Find the primary vertex
91 const xAOD::Vertex *priVtx = nullptr;
92 std::vector<const xAOD::Vertex *> vertices;
93 vertices.reserve(vertexHandle->size());
94 for (const xAOD::Vertex *vtx : *vertexHandle)
95 {
96 if (!priVtx && vtx->vertexType() == xAOD::VxType::PriVtx)
97 priVtx = vtx;
98 vertices.push_back(vtx);
99 }
100 if (!priVtx)
101 {
102 // If we fail to find a primary vertex then we give every cluster a
103 // CVF value of -1
104 for (const xAOD::CaloCluster *iclus : *clusters)
105 decCVF(*iclus) = -1;
106 return StatusCode::SUCCESS;
107 }
108
109 const xAOD::TrackParticleContainer *filteredTracks = nullptr;
112 {
113 for (const xAOD::TrackParticle *track : *tracks)
114 if (m_trackSelTool->accept(*track))
115 viewTracks.push_back(track);
116 filteredTracks = viewTracks.asDataVector();
117 }
118 else
119 filteredTracks = tracks.ptr();
120
121 // To speed things up later, check the maximum positive and negative range of
122 // the track etas. This means we can avoid too many loops and dR comparisons
123 // later on.
124 double minTrkEta = std::numeric_limits<double>::infinity();
125 double maxTrkEta = -std::numeric_limits<double>::infinity();
126 ATH_MSG_DEBUG("Building extrapolation");
127 std::vector<std::tuple<bool, const xAOD::TrackParticle *, TrackExtension>> extensions;
128 extensions.reserve(filteredTracks->size());
129 for (const xAOD::TrackParticle *track : *filteredTracks)
130 {
131 TrackExtension ext = m_extensionTool->extendTrack(ctx, *track);
132 if (!ext.isValid())
133 continue;
134 minTrkEta = std::min(minTrkEta, ext.eta);
135 maxTrkEta = std::max(maxTrkEta, ext.eta);
136 bool isPV;
137 if (m_useCompatible)
138 isPV = m_tvaTool->isCompatible(*track, *priVtx);
139 else
140 isPV = m_tvaTool->getUniqueMatchVertex(*track, vertices) == priVtx;
141 extensions.push_back(std::make_tuple(isPV, track, ext));
142 }
143
144 double DR2 = m_clusterMatchDR.value() * m_clusterMatchDR.value();
145 for (const xAOD::CaloCluster *iclus : *clusters)
146 {
147 double eta = iclus->eta();
148 if (iclus->e() < 0.0 ||
149 eta - m_clusterMatchDR > maxTrkEta ||
150 eta + m_clusterMatchDR < minTrkEta)
151 {
152 decCVF(*iclus) = -1;
153 continue;
154 }
155
156 double phi = iclus->phi();
157 double totalSum = 0;
158 double PVSum = 0;
159 for (const std::tuple<bool, const xAOD::TrackParticle *, TrackExtension> &ext : extensions)
160 {
161 // match the cluster to the track
162 if (!fastDR(eta, phi, std::get<2>(ext), m_clusterMatchDR, DR2))
163 continue;
164 totalSum += std::get<1>(ext)->pt();
165 if (std::get<0>(ext))
166 PVSum += std::get<1>(ext)->pt();
167 }
168 decCVF(*iclus) = totalSum == 0 ? -1 : PVSum / totalSum;
169 }
170 return StatusCode::SUCCESS;
171 }
172 } // namespace MET
173} // namespace HLT
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_MSG_ERROR(x)
#define ATH_MSG_DEBUG(x)
DataVector adapter that acts like it holds const pointers.
#define CHECK(...)
Evaluate an expression and check for errors.
Some common helper functions used by decoration handles.
Handle class for reading from StoreGate.
Handle class for adding a decoration to an object.
An algorithm that can be simultaneously executed in multiple threads.
DataVector adapter that acts like it holds const pointers.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
const DV * asDataVector() const
Return a pointer to this object, as a const DataVector.
size_type size() const noexcept
Returns the number of elements in the collection.
ToolHandle< InDet::IInDetTrackSelectionTool > m_trackSelTool
Definition CVFAlg.h:46
SG::ReadHandleKey< xAOD::CaloClusterContainer > m_inputClusterKey
Definition CVFAlg.h:50
Gaudi::Property< bool > m_useCompatible
Definition CVFAlg.h:60
ToolHandle< IExtendTrackToLayerTool > m_extensionTool
Definition CVFAlg.h:44
SG::WriteDecorHandleKey< xAOD::CaloClusterContainer > m_outputCVFKey
Definition CVFAlg.h:56
ToolHandle< CP::ITrackVertexAssociationTool > m_tvaTool
Definition CVFAlg.h:48
CVFAlg(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
Definition CVFAlg.cxx:37
Gaudi::Property< double > m_clusterMatchDR
Definition CVFAlg.h:58
bool m_useTrackSelTool
Is a track selection tool being used?
Definition CVFAlg.h:66
virtual StatusCode execute(const EventContext &ctx) const override
Run the algorithm.
Definition CVFAlg.cxx:66
SG::ReadHandleKey< xAOD::VertexContainer > m_inputVertexKey
Definition CVFAlg.h:54
virtual StatusCode initialize() override
Initialise the algorithm.
Definition CVFAlg.cxx:42
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_inputTrackKey
Definition CVFAlg.h:52
VxType::VertexType vertexType() const
The type of the vertex.
It used to be useful piece of code for replacing actual SG with other store of similar functionality ...
std::string contKeyFromKey(const std::string &key)
Extract the container part of key.
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
bool dPhi(const xAOD::TauJet &tau, const xAOD::CaloVertexedTopoCluster &cluster, float &out)
bool dEta(const xAOD::TauJet &tau, const xAOD::CaloVertexedTopoCluster &cluster, float &out)
@ PriVtx
Primary vertex.
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Vertex_v1 Vertex
Define the latest version of the vertex class.
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
Helper struct to hold track extrapolation information.