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 "xAODEgamma/Electron.h"
22#include <iomanip>
23
24namespace xAOD {
25
26 //<<<<<< CLASS STRUCTURE INITIALIZATION >>>>>>
27
30 {
31#ifndef XAOD_ANALYSIS
32 declareInterface<ITrackIsolationTool>(this);
33#endif // XAOD_ANALYSIS
34 }
35
37 = default;
38
39 //<<<<<< PUBLIC MEMBER FUNCTION DEFINITIONS >>>>>>
40
42 {
43#ifndef XAOD_ANALYSIS
44 ATH_CHECK(m_tracksInConeTool.retrieve( DisableTool{m_simpleIsolation} ));
45#endif // XAOD_ANALYSIS
46
47 if(m_trkselTool.retrieve().isFailure()){
48 ATH_MSG_FATAL("Could not retrieve InDetTrackSelectionTool");
49 return StatusCode::FAILURE;
50 }
51 if (!m_ttvaTool.empty()) {
52 ATH_MSG_DEBUG("Use TTVA tool " << m_ttvaTool);
53 m_useTTVATool = true;
54 ATH_CHECK( m_ttvaTool.retrieve() );
55 }
56 else
57 ATH_MSG_DEBUG("Will not use TTVA tool");
58
61
62 // the read handles
64 if (!m_vertexLocation.key().empty())
65 ATH_CHECK(m_vertexLocation.initialize());
66
67 if (m_coreTrackEtaRange.value() > 0)
69
70 return StatusCode::SUCCESS;
71 }
72
74 {
75 if (vtxC) {
76 if (vtxC->empty()) {
77 ATH_MSG_INFO("No vertex in container.");
78 return nullptr;
79 }
80 // In fact, should rather do like that, in case front is not PriVtx
81 for (const auto* const vtx : *vtxC ) {
82 if (vtx->vertexType() == xAOD::VxType::PriVtx)
83 return vtx;
84 }
85 }
86 return nullptr;
87 }
88
90 if( particle.type() == xAOD::Type::ObjectType::Muon) {
91 const Muon* muon = static_cast<const Muon*>(&particle);
92 const xAOD::TrackParticle* tp = muon->trackParticle(xAOD::Muon::InnerDetectorTrackParticle);
93 if( !tp ) tp = muon->trackParticle(xAOD::Muon::TrackParticleType::Primary);
94 if( !tp ) {
97 ATH_MSG_WARNING(" No TrackParticle found for muon with pT: " <<muon->pt() * 1.e-3 <<"[GeV], eta: "<<muon->eta()<<" phi: "<<
98 muon->phi()<<" q: "<<muon->charge()<<" primaryAuthor: "<<muon->author()<< " allAuthors: "<<muon->allAuthors());
99 } else return tp;
100 }
101 else if( particle.type() == xAOD::Type::ObjectType::Electron )
102 {
103 const Electron* electron = static_cast<const xAOD::Electron*>(&particle);
105 {
106 const xAOD::TrackParticle* tp = electron->trackParticle();
107 return tp;
108 }
109 }
110 return &particle;
111 }
112
113
115 const std::vector<Iso::IsolationType>& isoTypes,
116 TrackCorrection corrbitset,
117 const Vertex* vertex,
118 const std::set<const TrackParticle*>* exclusionSet,
119 const TrackParticleContainer* indetTrackParticles ) const
120 {
122 // If not vertex is given, use the ID best one. If one does not want to cut on z0sinT, use the TrackSelectionTool config
124 if (vertex == nullptr && !m_vertexLocation.key().empty()) {
126 if (!vtxH.isValid()) {
127 ATH_MSG_ERROR("Did not find a vertex container with key " << m_vertexLocation.key());
128 return false;
129 }
130 vertex = retrieveIDBestPrimaryVertex(vtxH.ptr());
131 if (vertex)
132 ATH_MSG_DEBUG("No vertex provided, is required. Use the ID-chosen pvx, z = " << vertex->z());
133 }
134
136 const IParticle* tp = getReferenceParticle(particle);
137 if( !tp ){
138 ATH_MSG_WARNING("Failed to obtain reference particle");
139 return false;
140 }
141 if (tp->pt() <= 0.)
142 ATH_MSG_WARNING("A particle of type " << particle.type() << " with strange pT : " << tp->pt()*1e-3 << " GeV");
143 TrackIsolationInput input( tp, corrbitset, vertex, exclusionSet );
144
145 for( auto isoType : isoTypes ){
147 if( flavour != Iso::ptcone ) {
148 ATH_MSG_WARNING("Unsupported isolation type passed, cannot calculate isolation " << Iso::toCString(isoType));
149 return false;
150 }
151 float conesize = Iso::coneSize(isoType);
152 input.coneSizesSquared.push_back(conesize*conesize);
153 }
154
155 for(size_t i=1; i<input.coneSizesSquared.size(); i++){
156 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]));
157 }
158
159 std::sort(input.coneSizesSquared.begin(),input.coneSizesSquared.end(),[](float i, float j) { return i>j; });
160
161 initresult(result, corrbitset, input.coneSizesSquared.size());
162
163 input.maxRadius = sqrt(input.coneSizesSquared[0]);
164
165 bool success = false;
166 // run isolation code
167 if( indetTrackParticles ) success = simpleIsolation(input,result,indetTrackParticles);
168 else if( m_simpleIsolation ) success = simpleIsolation(input,result);
169 else success = binnedIsolation(input,result);
170
171 if( msgLvl(MSG::DEBUG) ){
172 if( !success ){
173 ATH_MSG_DEBUG(" Track isolation calculation failed");
174 }else{
175 msg(MSG::DEBUG) << "Calculated track isolation: ";
176 for( unsigned int i = 0; i< result.ptcones.size();++i ){
177 msg(MSG::DEBUG) << " coneSizeSquared " << std::setw(3) << input.coneSizesSquared[i] << " value " << result.ptcones[i];
178 }
179 msg(MSG::DEBUG) << endmsg;
180 }
181 }
182 return success;
183 }
184
185
187 {
189 std::vector<const TrackParticle*> tps;
190#ifndef XAOD_ANALYSIS
191 if( !m_tracksInConeTool->particlesInCone(input.particle->eta(),input.particle->phi(),input.maxRadius,tps) ) return false;
192#else
193 if( !getparticlesInCone(input.particle->eta(),input.particle->phi(),input.maxRadius,tps) ) return false;
194#endif
195
196 for( const auto& tp : tps ) {
197 if( (!m_trkselTool->accept( *tp , input.vertex)) ||
198 (m_useTTVATool && (!input.vertex || !m_ttvaTool->isCompatible(*tp, *input.vertex)))){
199 if (m_useTTVATool && !input.vertex){
200 ATH_MSG_DEBUG("Encountered a track isolation input with invalid vertex while requiring TTVA. Rejecting, please check your inputs!");
201 }
202 ATH_MSG_DEBUG("reject track pt = " << tp->pt());
203 continue;
204 } else{
205 ATH_MSG_DEBUG("Accept track " << tp << " pt = " << tp->pt() << " z+vz = " << tp->z0()+tp->vz() << " eta = " << tp->eta() << " phi = " << tp->phi());
206 }
207 add( input,*tp, result );
208
209 }
210 return true;
211 }
212
214 {
215
218 if( !indetTrackParticles ) {
220 if (!tpH.isValid()) {
221 ATH_MSG_ERROR("Could not open a TrackParticle container with key "
223 return false;
224 }
225 indetTrackParticles = tpH.ptr();
226 }
227
228 // exit if not track particles found
229 if( !indetTrackParticles ) return false;
230
231 // loop over all track particles
232 for( const auto *const tp : *indetTrackParticles ) {
233 if( (!m_trkselTool->accept(*tp, input.vertex)) ||
234 (m_useTTVATool && !m_ttvaTool->isCompatible(*tp, *input.vertex))){
235 ATH_MSG_DEBUG("[2] reject track pt = " << tp->pt());
236 continue;
237 }
238
239 add( input, *tp, result );
240 }
241
242 return true;
243 }
244
246 {
247 // check if track pointer matches the one of input or one of the exclusion set
248 // Jon Burr: I'm not completely convinced by the use of CoreTrackEtaRange.
249 // With this setup, if you're running in simple isolation mode any track
250 // within the same eta slice (even on the other side of the detector) will
251 // be included in the eta code. If you manually provide a track particle
252 // container then the tool automatically runs in this simple mode...
253 // This is fine in IsolationBuilder (the main client) but could produce
254 // unexpected results with other users
255 if(input.corrections.trackbitset.test(static_cast<unsigned int>(Iso::coreTrackPtr))){
256 if(input.particle == &tp2 ||
257 (input.exclusionSet && input.exclusionSet->count(&tp2)) ||
258 (m_useLooseTrackCore && std::abs(input.particle->eta() - tp2.eta()) < m_coreTrackEtaRange)){
259 ATH_MSG_DEBUG("track pointer " << &tp2 << ", track pt = " << tp2.pt() << ", input pt = " << input.particle->pt()) ;
260 result.coreCorrections[Iso::coreTrackPtr] += tp2.pt();
261 return;
262 }
263 }
264
265 // check eta
266 float deta = input.particle->eta()-tp2.eta();
267 if( fabs(deta) > input.maxRadius ) return;
268
269 // check phi
270 float dphi = phiInRange(input.particle->phi()-tp2.phi());
271 if( fabs(dphi) > input.maxRadius ) return;
272
273 // check dr2
274 float dr2 = deta*deta + dphi*dphi;
275
276 float dT_Sig=0;
277 //CheckTiming for ForwardElectron case
278 if(m_DoTimingSel && input.particle->type() == xAOD::Type::ObjectType::TrackParticle)
279 {
280 const xAOD::TrackParticle* tp = static_cast<const xAOD::TrackParticle*>(input.particle);
281 if(tp->hasValidTime() && tp2.hasValidTime()) {
282 dT_Sig = abs(tp->time() - tp2.time()) / sqrt( pow(tp2.timeResolution(),2)+pow(tp->timeResolution(),2));
283 } else {
284 ATH_MSG_DEBUG("No valid time for the track while doing track->time()" );
285 dT_Sig=0;
286 }
287 }
288 if( dT_Sig > m_maxTime) return;
289
290 // check cone if using cone based overlap removal
291 if(input.corrections.trackbitset.test(static_cast<unsigned int>(Iso::coreTrackCone))
292 && dr2 < m_overlapCone2 ) {
293 result.coreCorrections[Iso::coreTrackCone] += tp2.pt();
294 return;
295 }
296
298 for( unsigned int k=0;k<input.coneSizesSquared.size();++k ){
299 if( dr2 >= input.coneSizesSquared[k] ) return;
300 result.ptcones[k] += tp2.pt();
301 if( dr2 <= input.ptvarconeRadiusSquared ){
302 result.ptvarcones_10GeVDivPt[k] += tp2.pt();
303 }
304 }
305 }
306
308 TrackCorrection corrlist,
309 unsigned int typesize) {
310
311 result.corrlist = corrlist;
312 result.coreCorrections.clear();
313 result.ptcones.resize(typesize,0.);
314 result.ptvarcones_10GeVDivPt.resize(typesize,0.);
315
316 std::vector<float> vec;
317 vec.resize(typesize,0.);
318
319 for(unsigned int i=0;i<static_cast<unsigned int>(Iso::numIsolationTrackCorrections);i++){
320 result.coreCorrections[static_cast<Iso::IsolationTrackCorrection>(i)] = 0.;
321 }
322 }
323
324#ifdef XAOD_ANALYSIS
325 bool TrackIsolationTool::getparticlesInCone( float eta, float phi, float dr, std::vector< const TrackParticle*>& output ) const {
326
329 if(!trks.isValid()) {
330 ATH_MSG_ERROR("Could not find TrackParticle container with key "
332 return false;
333 }
334
335 ATH_MSG_DEBUG("checing track eta=" << eta << ", phi=" << phi);
337 float dr2 = dr*dr;
338 for(auto trk: *trks){
339 float dEta = fabs(eta-trk->eta());
340 if(dEta>dr) continue;
341 float dPhi = fabs(phi-trk->phi());
342 while(dPhi>M_PI){dPhi = 2.*M_PI -dPhi;}
343 if(dPhi>dr) continue;
344 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);
345 if(dr2>(dEta*dEta+dPhi*dPhi)) output.push_back(trk);
346 }
347
348 return true;
349 }
350#endif // XAOD_ANALYSIS
351
352} // 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_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_INFO(x,...)
#define ATH_MSG_FATAL(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.
virtual double pt() const =0
The transverse momentum ( ) of the particle.
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.
Gaudi::Property< bool > m_DoTimingSel
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
Gaudi::Property< float > m_maxTime
bool m_useTTVATool
Use the ttva tool. Set to true if one was provided.
ToolHandle< InDet::IInDetTrackSelectionTool > m_trkselTool
selection of tracks
float timeResolution() const
Returns the time resolution.
float time() const
Returns the time.
virtual double phi() const override final
The azimuthal angle ( ) of the particle (has range to .).
uint8_t hasValidTime() const
Returns whether or not the track has a valid time.
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.
@ TrackParticle
The object is a charged track particle.
Definition ObjectType.h:43
@ Muon
The object is a muon.
Definition ObjectType.h:48
@ Electron
The object is an electron.
Definition ObjectType.h:46
const uint16_t AuthorFwdElectron
Electron reconstructed by the Forward cluster-based algorithm.
Definition EgammaDefs.h:30
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".
Electron_v1 Electron
Definition of the current "egamma version".
MsgStream & msg
Definition testRead.cxx:32