ATLAS Offline Software
Loading...
Searching...
No Matches
TrackIsolationTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
6// TrackIsolationTool
7//
8// (c) ATLAS software
10
11//<<<<<< INCLUDES >>>>>>
14// #include "InDetTrackSelectionTool/IInDetTrackSelectionTool.h"
20#include "xAODMuon/Muon.h"
21#include <iomanip>
22
23namespace xAOD {
24
25 //<<<<<< CLASS STRUCTURE INITIALIZATION >>>>>>
26
29 {
30#ifndef XAOD_ANALYSIS
31 declareInterface<ITrackIsolationTool>(this);
32#endif // XAOD_ANALYSIS
33 }
34
36 = default;
37
38 //<<<<<< PUBLIC MEMBER FUNCTION DEFINITIONS >>>>>>
39
41 {
42#ifndef XAOD_ANALYSIS
43 ATH_CHECK(m_tracksInConeTool.retrieve( DisableTool{m_simpleIsolation} ));
44#endif // XAOD_ANALYSIS
45
46 if(m_trkselTool.retrieve().isFailure()){
47 ATH_MSG_FATAL("Could not retrieve InDetTrackSelectionTool");
48 return StatusCode::FAILURE;
49 }
50 if (!m_ttvaTool.empty()) {
51 ATH_MSG_DEBUG("Use TTVA tool " << m_ttvaTool);
52 m_useTTVATool = true;
53 ATH_CHECK( m_ttvaTool.retrieve() );
54 }
55 else
56 ATH_MSG_DEBUG("Will not use TTVA tool");
57
60
61 // the read handles
63 if (!m_vertexLocation.key().empty())
64 ATH_CHECK(m_vertexLocation.initialize());
65
66 if (m_coreTrackEtaRange.value() > 0)
68
69 return StatusCode::SUCCESS;
70 }
71
73 {
74 if (vtxC) {
75 if (vtxC->empty()) {
76 ATH_MSG_INFO("No vertex in container.");
77 return nullptr;
78 }
79 // In fact, should rather do like that, in case front is not PriVtx
80 for (const auto* const vtx : *vtxC ) {
81 if (vtx->vertexType() == xAOD::VxType::PriVtx)
82 return vtx;
83 }
84 }
85 return nullptr;
86 }
87
89 if( particle.type() == xAOD::Type::ObjectType::Muon) {
90 const Muon* muon = static_cast<const Muon*>(&particle);
91 const xAOD::TrackParticle* tp = muon->trackParticle(xAOD::Muon::InnerDetectorTrackParticle);
92 if( !tp ) tp = muon->primaryTrackParticle();
93 if( !tp ) {
96 ATH_MSG_WARNING(" No TrackParticle found for muon with pT: " <<muon->pt() * 1.e-3 <<"[GeV], eta: "<<muon->eta()<<" phi: "<<
97 muon->phi()<<" q: "<<muon->charge()<<" primaryAuthor: "<<muon->author()<< " allAuthors: "<<muon->allAuthors());
98 } else return tp;
99 }
100 return &particle;
101 }
102
103
105 const std::vector<Iso::IsolationType>& isoTypes,
106 TrackCorrection corrbitset,
107 const Vertex* vertex,
108 const std::set<const TrackParticle*>* exclusionSet,
109 const TrackParticleContainer* indetTrackParticles ) const
110 {
112 // If not vertex is given, use the ID best one. If one does not want to cut on z0sinT, use the TrackSelectionTool config
114 if (vertex == nullptr && !m_vertexLocation.key().empty()) {
116 if (!vtxH.isValid()) {
117 ATH_MSG_ERROR("Did not find a vertex container with key " << m_vertexLocation.key());
118 return false;
119 }
120 vertex = retrieveIDBestPrimaryVertex(vtxH.ptr());
121 if (vertex)
122 ATH_MSG_DEBUG("No vertex provided, is required. Use the ID-chosen pvx, z = " << vertex->z());
123 }
124
126 const IParticle* tp = getReferenceParticle(particle);
127 if( !tp ){
128 ATH_MSG_WARNING("Failed to obtain reference particle");
129 return false;
130 }
131 if (tp->pt() <= 0.)
132 ATH_MSG_WARNING("A particle of type " << particle.type() << " with strange pT : " << tp->pt()*1e-3 << " GeV");
133 TrackIsolationInput input( tp, corrbitset, vertex, exclusionSet );
134
135 for( auto isoType : isoTypes ){
137 if( flavour != Iso::ptcone ) {
138 ATH_MSG_WARNING("Unsupported isolation type passed, cannot calculate isolation " << Iso::toCString(isoType));
139 return false;
140 }
141 float conesize = Iso::coneSize(isoType);
142 input.coneSizesSquared.push_back(conesize*conesize);
143 }
144
145 for(size_t i=1; i<input.coneSizesSquared.size(); i++){
146 if(input.coneSizesSquared[i]>input.coneSizesSquared[i-1]) ATH_MSG_ERROR("Isolation Cone should be in decreasing order. "<< i << "th variable is " << Iso::toCString(isoTypes[i]) << " is larger than the one before it: " << Iso::toCString(isoTypes[i-1]));
147 }
148
149 std::sort(input.coneSizesSquared.begin(),input.coneSizesSquared.end(),[](float i, float j) { return i>j; });
150
151 initresult(result, corrbitset, input.coneSizesSquared.size());
152
153 input.maxRadius = sqrt(input.coneSizesSquared[0]);
154
155 bool success = false;
156 // run isolation code
157 if( indetTrackParticles ) success = simpleIsolation(input,result,indetTrackParticles);
158 else if( m_simpleIsolation ) success = simpleIsolation(input,result);
159 else success = binnedIsolation(input,result);
160
161 if( msgLvl(MSG::DEBUG) ){
162 if( !success ){
163 ATH_MSG_DEBUG(" Track isolation calculation failed");
164 }else{
165 msg(MSG::DEBUG) << "Calculated track isolation: ";
166 for( unsigned int i = 0; i< result.ptcones.size();++i ){
167 msg(MSG::DEBUG) << " coneSizeSquared " << std::setw(3) << input.coneSizesSquared[i] << " value " << result.ptcones[i];
168 }
169 msg(MSG::DEBUG) << endmsg;
170 }
171 }
172 return success;
173 }
174
175
177 {
179 std::vector<const TrackParticle*> tps;
180#ifndef XAOD_ANALYSIS
181 if( !m_tracksInConeTool->particlesInCone(input.particle->eta(),input.particle->phi(),input.maxRadius,tps) ) return false;
182#else
183 if( !getparticlesInCone(input.particle->eta(),input.particle->phi(),input.maxRadius,tps) ) return false;
184#endif
185
186 for( const auto& tp : tps ) {
187 if( (!m_trkselTool->accept( *tp , input.vertex)) ||
188 (m_useTTVATool && (!input.vertex || !m_ttvaTool->isCompatible(*tp, *input.vertex)))){
189 if (m_useTTVATool && !input.vertex){
190 ATH_MSG_DEBUG("Encountered a track isolation input with invalid vertex while requiring TTVA. Rejecting, please check your inputs!");
191 }
192 ATH_MSG_DEBUG("reject track pt = " << tp->pt());
193 continue;
194 } else{
195 ATH_MSG_DEBUG("Accept track " << tp << " pt = " << tp->pt() << " z+vz = " << tp->z0()+tp->vz() << " eta = " << tp->eta() << " phi = " << tp->phi());
196 }
197 add( input,*tp, result );
198
199 }
200 return true;
201 }
202
204 {
205
208 if( !indetTrackParticles ) {
210 if (!tpH.isValid()) {
211 ATH_MSG_ERROR("Could not open a TrackParticle container with key "
213 return false;
214 }
215 indetTrackParticles = tpH.ptr();
216 }
217
218 // exit if not track particles found
219 if( !indetTrackParticles ) return false;
220
221 // loop over all track particles
222 for( const auto *const tp : *indetTrackParticles ) {
223 if( (!m_trkselTool->accept(*tp, input.vertex)) ||
224 (m_useTTVATool && !m_ttvaTool->isCompatible(*tp, *input.vertex))){
225 ATH_MSG_DEBUG("[2] reject track pt = " << tp->pt());
226 continue;
227 }
228
229 add( input, *tp, result );
230 }
231
232 return true;
233 }
234
236 {
237 // check if track pointer matches the one of input or one of the exclusion set
238 // Jon Burr: I'm not completely convinced by the use of CoreTrackEtaRange.
239 // With this setup, if you're running in simple isolation mode any track
240 // within the same eta slice (even on the other side of the detector) will
241 // be included in the eta code. If you manually provide a track particle
242 // container then the tool automatically runs in this simple mode...
243 // This is fine in IsolationBuilder (the main client) but could produce
244 // unexpected results with other users
245 if(input.corrections.trackbitset.test(static_cast<unsigned int>(Iso::coreTrackPtr))){
246 if(input.particle == &tp2 ||
247 (input.exclusionSet && input.exclusionSet->count(&tp2)) ||
248 (m_useLooseTrackCore && std::abs(input.particle->eta() - tp2.eta()) < m_coreTrackEtaRange)){
249 ATH_MSG_DEBUG("track pointer " << &tp2 << ", track pt = " << tp2.pt() << ", input pt = " << input.particle->pt()) ;
250 result.coreCorrections[Iso::coreTrackPtr] += tp2.pt();
251 return;
252 }
253 }
254
255 // check eta
256 float deta = input.particle->eta()-tp2.eta();
257 if( fabs(deta) > input.maxRadius ) return;
258
259 // check phi
260 float dphi = phiInRange(input.particle->phi()-tp2.phi());
261 if( fabs(dphi) > input.maxRadius ) return;
262
263 // check dr2
264 float dr2 = deta*deta + dphi*dphi;
265
266 // check cone if using cone based overlap removal
267 if(input.corrections.trackbitset.test(static_cast<unsigned int>(Iso::coreTrackCone))
268 && dr2 < m_overlapCone2 ) {
269 result.coreCorrections[Iso::coreTrackCone] += tp2.pt();
270 return;
271 }
272
274 for( unsigned int k=0;k<input.coneSizesSquared.size();++k ){
275 if( dr2 >= input.coneSizesSquared[k] ) return;
276 result.ptcones[k] += tp2.pt();
277 if( dr2 <= input.ptvarconeRadiusSquared ){
278 result.ptvarcones_10GeVDivPt[k] += tp2.pt();
279 }
280 }
281 }
282
284 TrackCorrection corrlist,
285 unsigned int typesize) {
286
287 result.corrlist = corrlist;
288 result.coreCorrections.clear();
289 result.ptcones.resize(typesize,0.);
290 result.ptvarcones_10GeVDivPt.resize(typesize,0.);
291
292 std::vector<float> vec;
293 vec.resize(typesize,0.);
294
295 for(unsigned int i=0;i<static_cast<unsigned int>(Iso::numIsolationTrackCorrections);i++){
296 result.coreCorrections[static_cast<Iso::IsolationTrackCorrection>(i)] = 0.;
297 }
298 }
299
300#ifdef XAOD_ANALYSIS
301 bool TrackIsolationTool::getparticlesInCone( float eta, float phi, float dr, std::vector< const TrackParticle*>& output ) const {
302
305 if(!trks.isValid()) {
306 ATH_MSG_ERROR("Could not find TrackParticle container with key "
308 return false;
309 }
310
311 ATH_MSG_DEBUG("checing track eta=" << eta << ", phi=" << phi);
313 float dr2 = dr*dr;
314 for(auto trk: *trks){
315 float dEta = fabs(eta-trk->eta());
316 if(dEta>dr) continue;
317 float dPhi = fabs(phi-trk->phi());
318 while(dPhi>M_PI){dPhi = 2.*M_PI -dPhi;}
319 if(dPhi>dr) continue;
320 ATH_MSG_DEBUG("ID trk pt=" << trk->pt()*0.001 << " eta=" << trk->eta() << ", phi=" << trk->phi() << " dEta=" << dEta << ", dPhi=" << dPhi << ", dR2 = " << dEta*dEta+dPhi*dPhi);
321 if(dr2>(dEta*dEta+dPhi*dPhi)) output.push_back(trk);
322 }
323
324 return true;
325 }
326#endif // XAOD_ANALYSIS
327
328} // end of namespace
#define M_PI
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Handle class for reading from StoreGate.
std::vector< size_t > vec
bool msgLvl(const MSG::Level lvl) const
bool empty() const noexcept
Returns true if the collection is empty.
const_pointer_type ptr()
Dereference the pointer.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
AsgTool(const std::string &name)
Constructor specifying the tool instance's name.
Definition AsgTool.cxx:58
Class providing the definition of the 4-vector interface.
SG::ReadHandleKey< VertexContainer > m_vertexLocation
bool binnedIsolation(TrackIsolationInput &input, TrackIsolation &result) const
using TracksInConeTool
void add(TrackIsolationInput &input, const TrackParticle &tp2, TrackIsolation &result) const
add track particle to isolation calculation
virtual ~TrackIsolationTool(void)
destructor
Gaudi::Property< float > m_coreTrackEtaRange
overlap cone size squared
virtual StatusCode initialize() override
initialize
ToolHandle< ITrackParticlesInConeTool > m_tracksInConeTool
tracks in cone tool
virtual bool trackIsolation(TrackIsolation &result, const IParticle &tp, const std::vector< Iso::IsolationType > &cones, TrackCorrection corrections, const Vertex *vertex=0, const std::set< const TrackParticle * > *exclusionSet=0, const TrackParticleContainer *indetTrackParticles=0) const override
ITrackIsolationTool interface:
SG::ReadHandleKey< TrackParticleContainer > m_indetTrackParticleLocation
track particle location
const Vertex * retrieveIDBestPrimaryVertex(const VertexContainer *vtxC) const
retrieve pvx if not given
bool simpleIsolation(TrackIsolationInput &input, TrackIsolation &result, const TrackParticleContainer *indetTrackParticles=0) const
simple isolation (loop)
bool m_useLooseTrackCore
Whether the loose core track eta range is used.
ToolHandle< CP::ITrackVertexAssociationTool > m_ttvaTool
Select tracks associated to the vertex.
float phiInRange(float phi) const
hepler function to ensure phi is within +-Pi
const IParticle * getReferenceParticle(const IParticle &particle) const
get reference particle
TrackIsolationTool(const std::string &name)
constructor
Gaudi::Property< float > m_overlapCone
static void initresult(TrackIsolation &result, TrackCorrection corrlist, unsigned int typesize)
init result struct
Gaudi::Property< bool > m_simpleIsolation
flag to select calculation type
bool m_useTTVATool
Use the ttva tool. Set to true if one was provided.
ToolHandle< InDet::IInDetTrackSelectionTool > m_trkselTool
selection of tracks
virtual double phi() const override final
The azimuthal angle ( ) of the particle (has range to .)
virtual double pt() const override final
The transverse momentum ( ) of the particle.
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
NRpcCablingAlg reads raw condition data and writes derived condition data to the condition store.
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
output
Definition merge.py:16
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
@ Muon
The object is a muon.
Definition ObjectType.h:48
IsolationFlavour isolationFlavour(IsolationType type)
convert Isolation Type into Isolation Flavour
IsolationFlavour
Enumeration for different ways of calculating isolation in xAOD files.
@ ptcone
Track isolation.
static const char * toCString(IsolationConeSize conesize)
float coneSize(IsolationConeSize type)
convert Isolation Size into cone size
@ PriVtx
Primary vertex.
ICaloAffectedTool is abstract interface for tools checking if 4 mom is in calo affected region.
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".
MsgStream & msg
Definition testRead.cxx:32