ATLAS Offline Software
Loading...
Searching...
No Matches
TauTrackFinder.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5#ifndef XAOD_ANALYSIS
6
8
9#include "TauTrackFinder.h"
11
12
13TauTrackFinder::TauTrackFinder(const std::string& name) :
14 TauRecToolBase(name),
16 m_HadSamplings {CaloSampling::TileBar1, CaloSampling::HEC1, CaloSampling::TileExt1}
17{}
18
20
21// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
23
24 // retrieve tools
26 ATH_CHECK( m_trackToVertexTool.retrieve() );
27 ATH_CHECK( m_caloExtensionTool.retrieve() );
29
30 // initialize ReadHandleKey
32 // use CaloExtensionTool when key is empty
34 // allow empty for LRT
36
38 if(inTrigger()) {
39 ATH_MSG_ERROR ("Ghost matching is not a valid tau-track association scheme for trigger, use cone association. Aborting.");
40 return StatusCode::FAILURE;
41 }
42 ATH_MSG_INFO ("Using ghost matching for tau-track association" << m_ghostTrackDR );
43 // allow empty for trigger
45 }
46
47 ATH_CHECK( m_beamSpotKey.initialize(inTrigger()) );
48
49 return StatusCode::SUCCESS;
50}
51
52// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
54 const EventContext &ctx = Gaudi::Hive::currentContext();
55 std::vector<const xAOD::TrackParticle*> tauTracks;
56 std::vector<const xAOD::TrackParticle*> wideTracks;
57 std::vector<const xAOD::TrackParticle*> otherTracks;
58
59 //Retrieve standard track container
60 const xAOD::TrackParticleContainer* trackParticleCont = nullptr;
61
63 if (!trackPartInHandle.isValid()) {
64 ATH_MSG_ERROR ("Could not retrieve HiveDataObj with key " << trackPartInHandle.key());
65 return StatusCode::FAILURE;
66 }
67 trackParticleCont = trackPartInHandle.cptr();
68
69 //Retrieve LRT container
70 const xAOD::TrackParticleContainer* largeD0TracksParticleCont = nullptr;
71 std::vector<const xAOD::TrackParticle*> vecTrksLargeD0;
72 if (! m_largeD0TracksInputContainer.empty()) {
74 if (!trackPartInHandle.isValid()) {
75 ATH_MSG_VERBOSE ("Could not retrieve HiveDataObj with key " << trackPartInHandle.key());
76 ATH_MSG_VERBOSE ("LRT container " << trackPartInHandle.key()<<" is not being used for tau tracks");
77 }
78 else {
79 largeD0TracksParticleCont = trackPartInHandle.cptr();
80 vecTrksLargeD0 = std::vector<const xAOD::TrackParticle*>(largeD0TracksParticleCont->begin(), largeD0TracksParticleCont->end());
81 }
82 }
83
84
85
86 // retrieve the seed jet container when using ghost-matching
87 const xAOD::JetContainer* jetContainer = nullptr;
88 if (! m_jetContainer.empty()) {
90 if (!jetContHandle.isValid()) {
91 ATH_MSG_ERROR ("Could not retrieve HiveDataObj with key " << jetContHandle.key());
92 return StatusCode::FAILURE;
93 }
94 jetContainer = jetContHandle.cptr();
95 }
96 // in EleRM reco, we need the original track particles
97 std::vector<const xAOD::TrackParticle*> vecTrks;
98 vecTrks.reserve( trackParticleCont->size() );
99 for (auto trk : *trackParticleCont){
100 if (!inEleRM()) { vecTrks.push_back(trk); }
101 else{
102 static const SG::ConstAccessor<ElementLink<xAOD::TrackParticleContainer>> acc_originalObject("ERMOriginalTrack");
103 auto original_id_track_link = acc_originalObject(*trk);
104 if (!original_id_track_link.isValid()) {
105 ATH_MSG_ERROR("Original track link is not valid");
106 continue;
107 }
108 vecTrks.push_back(*original_id_track_link);
109 }
110 }
111
112 // get the primary vertex
113 const xAOD::Vertex* pVertex = pTau.vertex();
114
115 // retrieve tracks wrt a vertex
116 // as a vertex is used: tau origin / PV / beamspot / 0,0,0 (in this order, depending on availability)
117
118 getTauTracksFromPV(pTau, vecTrks, pVertex, m_useGhostTracks, jetContainer, tauTracks, wideTracks, otherTracks);
119
120 bool foundLRTCont = bool (largeD0TracksParticleCont != nullptr);
121 // additional LRT with vertex association added to tracks
122 if (foundLRTCont){
123 // for now, use cone association for LRTs, not ghost association
124 getTauTracksFromPV(pTau, vecTrksLargeD0, pVertex, false, nullptr, tauTracks, wideTracks, otherTracks);
125 }
126
127 // remove core and wide tracks outside a maximal delta z0 wrt lead core track
128 if (m_applyZ0cut) {
129 this->removeOffsideTracksWrtLeadTrk(ctx, tauTracks, wideTracks, otherTracks, pVertex, m_z0maxDelta);
130 }
131
133 bool alreadyUsed = false;
134 for (std::vector<const xAOD::TrackParticle*>::iterator track_it = tauTracks.begin(); track_it != tauTracks.end() ;)
135 {
136 alreadyUsed = false;
137 //loop over all up-to-now core tracks
138 for( const xAOD::TauTrack* tau_trk : tauTrackCon ) {
139 //originally it was coreTrack&passTrkSelector
141 if( (*track_it) == tau_trk->track()) alreadyUsed = true;
142 }
143 //if this track has already been used by another tau, don't associate it to this new one
144 if(alreadyUsed) {
145 ATH_MSG_INFO( "Found Already Used track new, now removing: " << *track_it );
146 track_it = tauTracks.erase(track_it);
147 } else ++track_it;
148 }
149 }
150
151 // associate track to tau candidate and calculate charge
152 float charge = 0.;
153 for (unsigned int i = 0; i < tauTracks.size(); ++i) {
154 const xAOD::TrackParticle* trackParticle = tauTracks.at(i);
155
156 ATH_MSG_VERBOSE(name() << " adding core track nr: " << i
157 << " eta " << trackParticle->eta()
158 << " phi " << trackParticle->phi());
159
160 charge += trackParticle->charge();
161
162 xAOD::TauTrack* track = new xAOD::TauTrack();
163 tauTrackCon.push_back(track);
164
166 linkToTrackParticle.toContainedElement(*static_cast<const xAOD::TrackParticleContainer*>(trackParticle->container()), trackParticle);
167 if (foundLRTCont && isLargeD0Track(trackParticle)){//Check LRT track and link to container
169 }
170 else {
172 }
173 track->addTrackLink(linkToTrackParticle);
174
175 track->setP4(trackParticle->pt(), trackParticle->eta(), trackParticle->phi(), trackParticle->m());
178 // in case TrackClassifier is not run, still get sensible results
181
183 linkToTauTrack.toContainedElement(tauTrackCon, track);
184 pTau.addTauTrackLink(linkToTauTrack);
185
186 ATH_MSG_VERBOSE(name() << " added core track nr: " << i
187 << " eta " << pTau.track(i)->eta()
188 << " phi " << pTau.track(i)->phi());
189 }
190 // set the charge, which is defined by the core tau tracks only
191 pTau.setCharge(charge);
192
193 for (unsigned int i = 0; i < wideTracks.size(); ++i) {
194 const xAOD::TrackParticle* trackParticle = wideTracks.at(i);
195
196 ATH_MSG_VERBOSE(name() << " adding wide track nr: " << i
197 << " eta " << trackParticle->eta()
198 << " phi " << trackParticle->phi());
199
200 xAOD::TauTrack* track = new xAOD::TauTrack();
201 tauTrackCon.push_back(track);
202
204 linkToTrackParticle.toContainedElement(*static_cast<const xAOD::TrackParticleContainer*>(trackParticle->container()), trackParticle);
205 if (foundLRTCont && isLargeD0Track(trackParticle)){//Check LRT track and link to container
207 }
208 else {
210 }
211 track->addTrackLink(linkToTrackParticle);
212
213 track->setP4(trackParticle->pt(), trackParticle->eta(), trackParticle->phi(), trackParticle->m());
216 // in case TrackClassifier is not run, still get sensible results
217 track->setFlag(xAOD::TauJetParameters::TauTrackFlag::classifiedIsolation, true); // for sake of trigger, reset in TauTrackClassifier
218 track->setFlag(xAOD::TauJetParameters::TauTrackFlag::modifiedIsolationTrack, true); // for sake of trigger, reset in TauTrackClassifier
220
222 linkToTauTrack.toContainedElement(tauTrackCon, track);
223 pTau.addTauTrackLink(linkToTauTrack);
224 }
225
226 //These are set again in TauTrackClassifier
227 pTau.setDetail(xAOD::TauJetParameters::nChargedTracks, static_cast<int>(pTau.nTracks()));
229
230 for (unsigned int i = 0; i < otherTracks.size(); ++i) {
231 const xAOD::TrackParticle* trackParticle = otherTracks.at(i);
232
233 ATH_MSG_VERBOSE(name() << " adding other track nr: " << i
234 << " eta " << trackParticle->eta()
235 << " phi " << trackParticle->phi());
236
237 xAOD::TauTrack* track = new xAOD::TauTrack();
238 tauTrackCon.push_back(track);
239
241 if (foundLRTCont && isLargeD0Track(trackParticle)){//Check LRT track and link to container
242 linkToTrackParticle.toContainedElement(*static_cast<const xAOD::TrackParticleContainer*>(trackParticle->container()), trackParticle);
244 }
245 else {
246 linkToTrackParticle.toContainedElement(*static_cast<const xAOD::TrackParticleContainer*>(trackParticle->container()), trackParticle);
248 }
249 track->addTrackLink(linkToTrackParticle);
250
251 track->setP4(trackParticle->pt(), trackParticle->eta(), trackParticle->phi(), trackParticle->m());
252 float dR = track->p4().DeltaR(pTau.p4());
254 else track->setFlag(xAOD::TauJetParameters::TauTrackFlag::wideTrack, true);
256
258 linkToTauTrack.toContainedElement(tauTrackCon, track);
259 pTau.addTauTrackLink(linkToTauTrack);
260 }
261
263 // keep track of total number of associated tracks, in case of tau track thinning
264 pTau.setDetail(xAOD::TauJetParameters::nAllTracks, static_cast<int>(pTau.nAllTracks()));
265
266 ATH_MSG_DEBUG("numTrack: " << "/" << pTau.nTracks());
267 ATH_MSG_DEBUG("charge: " << "/" << pTau.charge());
268
269 // impact parameter variables w.r.t. tau vertex
270 const xAOD::Vertex* vxcand = nullptr;
271
272 xAOD::Vertex vxbkp;
273 vxbkp.makePrivateStore();
274
275 // FIXME: don't we want to use the beamspot in the offline reconstruction too, when there is no reconstructed primary vertex?
276 if (pTau.vertex()!=nullptr && pTau.vertex()->vertexType() != xAOD::VxType::NoVtx) {
277 vxcand = pTau.vertex();
278 }
279 else if (inTrigger()) { // online: use vertex with x-y coordinates from the beamspot and the z from the leading track
280 vxbkp.setX(0); vxbkp.setY(0); vxbkp.setZ(0);
281
283 if(beamSpotHandle.isValid()) {
284 vxbkp.setPosition(beamSpotHandle->beamPos());
285 const auto& cov = beamSpotHandle->beamVtx().covariancePosition();
286 vxbkp.setCovariancePosition(cov);
287
288 if(!tauTracks.empty()) {
289 vxbkp.setZ(tauTracks.at(0)->z0());
290 }
291 }
292 else {
293 ATH_MSG_DEBUG("No Beamspot object in tau candidate");
294 }
295 vxcand = & vxbkp;
296 }
297
298
299 // this could be replaced with TauTrack::setDetail
300 static const SG::Accessor<float> dec_d0TJVA("d0TJVA");
301 static const SG::Accessor<float> dec_z0sinthetaTJVA("z0sinthetaTJVA");
302 static const SG::Accessor<float> dec_d0SigTJVA("d0SigTJVA");
303 static const SG::Accessor<float> dec_z0sinthetaSigTJVA("z0sinthetaSigTJVA");
304
305 for(const ElementLink<xAOD::TauTrackContainer>& trackLink : pTau.allTauTrackLinks())
306 {
307 assert (trackLink.getStorableObjectPointer() == &tauTrackCon);
308 xAOD::TauTrack* track = tauTrackCon[trackLink.index()];
309 dec_d0TJVA(*track) = track->track()->d0();
310 dec_z0sinthetaTJVA(*track) = track->z0sinThetaTJVA(pTau);
311 dec_d0SigTJVA(*track) = -999.;
312 dec_z0sinthetaSigTJVA(*track) = -999.;
313
314 // in the trigger, z0sintheta and corresponding significance are meaningless if we use the beamspot
315 if(vxcand) {
316 std::unique_ptr<const Trk::ImpactParametersAndSigma> myIPandSigma
317 = std::unique_ptr<const Trk::ImpactParametersAndSigma>(m_trackToVertexIPEstimator->estimate(ctx, track->track(), vxcand));
318
319 if(myIPandSigma) {
320 dec_d0TJVA(*track) = myIPandSigma->IPd0;
321 dec_z0sinthetaTJVA(*track) = myIPandSigma->IPz0SinTheta;
322 dec_d0SigTJVA(*track) = (myIPandSigma->sigmad0 != 0.) ? static_cast<float>( myIPandSigma->IPd0 / myIPandSigma->sigmad0 ) : -999.f;
323 dec_z0sinthetaSigTJVA(*track) = (myIPandSigma->sigmaz0SinTheta != 0.) ? static_cast<float>( myIPandSigma->IPz0SinTheta / myIPandSigma->sigmaz0SinTheta ) : -999.f;
324 }
325 }
326 }
327
328 // extrapolate core tracks to calorimeter surface
329 // store information only in ExtraDetailsContainer
331 {
332 StatusCode sc = extrapolateToCaloSurface(ctx, pTau, tauTrackCon);
333 if (sc.isFailure() && !sc.isRecoverable()) {
334 ATH_MSG_ERROR("couldn't extrapolate tracks to calo surface");
335 return StatusCode::FAILURE;
336 }
337 }
338
339 return StatusCode::SUCCESS;
340}
341
342
343// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
345 const xAOD::TrackParticle& trackParticle,
346 const xAOD::Vertex* primaryVertex) const
347{
348 double dR = pTau.p4().DeltaR(trackParticle.p4());
349
350 if (dR > m_maxJetDr_wide) return NotTauTrack;
351
352 bool goodTrack = m_trackSelectorTool_tau->decision(trackParticle, primaryVertex);
353
354 if (goodTrack) {
355 if (dR > m_maxJetDr_tau)
356 return TauTrackWide;
357 else
358 return TauTrackCore;
359 } else
360 return TauTrackOther;
361}
362
363// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
365 const std::vector<const xAOD::TrackParticle*>& vecTrackParticles,
366 const xAOD::Vertex* primaryVertex,
367 const bool& useGhostTracks,
368 const xAOD::JetContainer* jetContainer,
369 std::vector<const xAOD::TrackParticle*> &tauTracks,
370 std::vector<const xAOD::TrackParticle*> &wideTracks,
371 std::vector<const xAOD::TrackParticle*> &otherTracks) const
372{
373 std::vector<const xAOD::TrackParticle*> ghostTracks;
374 if(useGhostTracks) {
375 const xAOD::Jet* seedJet = pTau.jet();
376 if(seedJet) {
377 if(!seedJet->getAssociatedObjects("GhostTrack", ghostTracks)) {
378 ATH_MSG_WARNING("Could not retrieve GhostTrack from seed jet.");
379 }
380 }
381 }
382 // in EleRM reco, we need the original track particles
383 if (inEleRM()){
384 for (uint i = 0; i < ghostTracks.size(); i++){
385 static const SG::ConstAccessor<ElementLink<xAOD::TrackParticleContainer>> acc_originalTrack("ERMOriginalTrack");
386 auto original_id_track_link = acc_originalTrack(*(ghostTracks[i]));
387 if (!original_id_track_link.isValid()) {
388 ATH_MSG_ERROR("Original track link is not valid");
389 continue;
390 }
391 ghostTracks[i] = *original_id_track_link;
392 }
393 }
394
395 for (const xAOD::TrackParticle *trackParticle : vecTrackParticles) {
396 TauTrackType type = tauTrackType(pTau, *trackParticle, primaryVertex);
397 if(type == NotTauTrack) continue;
398
399 if(useGhostTracks) {
400 // require that tracks are ghost-matched with the seed jet at large dR(tau,track), to avoid using tracks from another tau
401 double dR = pTau.p4().DeltaR(trackParticle->p4());
402 if (dR > m_ghostTrackDR) {
403 if (std::find(ghostTracks.begin(), ghostTracks.end(), trackParticle) == ghostTracks.end()) {
404 // check whether the jet closest to the track is the current seed jet
405 // if so, recover the track even if not ghost-matched, to improve tau-track association efficiency at low pt (esp. for 3p)
406 double dRmin = 999.;
407 bool isSeedClosest = false;
408 for (const xAOD::Jet* jet : *jetContainer) {
410 TLorentzVector jetLV;
411 jetLV.SetPtEtaPhiM(jetP4.Pt(), jetP4.Eta(), jetP4.Phi(), jetP4.M());
412 double dRjet = trackParticle->p4().DeltaR(jetLV);
413 if(dRjet < dRmin) {
414 dRmin = dRjet;
415 isSeedClosest = (jet == pTau.jet());
416 }
417 }
418 if(!isSeedClosest) continue;
419 }
420 }
421 }
422
423 if (type == TauTrackCore)
424 tauTracks.push_back(trackParticle);
425 else if (type == TauTrackWide)
426 wideTracks.push_back(trackParticle);
427 else if (type == TauTrackOther)
428 otherTracks.push_back(trackParticle);
429 }
430 std::sort(tauTracks.begin(), tauTracks.end(), TrackSort());
431 std::sort(wideTracks.begin(), wideTracks.end(), TrackSort());
432 std::sort(otherTracks.begin(), otherTracks.end(), TrackSort());
433}
434
435
436// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
437StatusCode TauTrackFinder::extrapolateToCaloSurface(const EventContext& ctx,
438 xAOD::TauJet& pTau,
439 xAOD::TauTrackContainer& tauTrackCon) const
440{
441 Trk::TrackParametersIdHelper parsIdHelper;
442
443 int trackIndex = -1;
444 const Trk::CaloExtension * caloExtension = nullptr;
445 std::unique_ptr<Trk::CaloExtension> uniqueExtension;
446 for(const ElementLink<xAOD::TauTrackContainer>& trackLink : pTau.allTauTrackLinks())
447 {
448 assert (trackLink.getStorableObjectPointer() == &tauTrackCon);
449 xAOD::TauTrack* tauTrack = tauTrackCon[trackLink.index()];
450 const xAOD::TrackParticle *orgTrack = tauTrack->track();
451 if( !orgTrack ) continue;
452 trackIndex = orgTrack->index();
453
454 // set default values
455 float etaEM = -10.0;
456 float phiEM = -10.0;
457 float etaHad = -10.0;
458 float phiHad = -10.0;
459
460 // get the extrapolation into the calo
461 ATH_MSG_DEBUG( "Try extrapolation of track with pt = " << orgTrack->pt()
462 << ", eta " << orgTrack->eta()
463 << ", phi" << orgTrack->phi() );
464
465 if(!m_ParticleCacheKey.key().empty()){
466 /*get the CaloExtension object*/
467 ATH_MSG_VERBOSE("Using the CaloExtensionBuilder Cache");
469 caloExtension = (*particleCache)[trackIndex];
470 ATH_MSG_VERBOSE("Getting element " << trackIndex << " from the particleCache");
471 if( not caloExtension ){
472 ATH_MSG_VERBOSE("Cache does not contain a calo extension -> "
473 "Calculating with the a CaloExtensionTool");
474 uniqueExtension = m_caloExtensionTool->caloExtension(ctx, *orgTrack);
475 caloExtension = uniqueExtension.get();
476 }
477 }
478 else {
479 /* If CaloExtensionBuilder is unavailable, use the calo extension tool */
480 ATH_MSG_VERBOSE("Using the CaloExtensionTool");
481 uniqueExtension = m_caloExtensionTool->caloExtension(ctx, *orgTrack);
482 caloExtension = uniqueExtension.get();
483 }
484
485 if (!caloExtension)
486 {
487 ATH_MSG_DEBUG("Track extrapolation failed");
488 }
489 else {
490 const std::vector<Trk::CurvilinearParameters>& clParametersVector = caloExtension->caloLayerIntersections();
491 if (clParametersVector.empty()) {
492 ATH_MSG_DEBUG("Track extrapolation failed");
493 }
494
495 ATH_MSG_DEBUG("Scanning samplings");
496 bool validECal = false;
497 bool validHCal = false;
498 for( const Trk::CurvilinearParameters& cur : clParametersVector ){
499 ATH_MSG_DEBUG("Sampling " << parsIdHelper.caloSample(cur.cIdentifier()) );
500
501 // only use entry layer
502 if( not parsIdHelper.isEntryToVolume(cur.cIdentifier()) ) continue;
503
504 CaloSampling::CaloSample sample = parsIdHelper.caloSample(cur.cIdentifier());
505
506 // ECal
507 if( not validECal and m_EMSamplings.count(sample))
508 {
509 validECal = true;
510 etaEM = cur.position().eta();
511 phiEM = cur.position().phi();
512 ATH_MSG_DEBUG("Extrapolated to ECal layer " << sample);
513 }
514
515 // HCal
516 if( not validHCal and m_HadSamplings.count(sample))
517 {
518 validHCal = true;
519 etaHad = cur.position().eta();
520 phiHad = cur.position().phi();
521 ATH_MSG_DEBUG("Extrapolated to HCal layer " << sample);
522 }
523 if( validECal and validHCal ) break;
524 }
525 // EM failure warn if within acceptance
526 if( not validECal and std::abs(orgTrack->pt()) < 2.48 ){
527 ATH_MSG_DEBUG("Failed extrapolation to ECal");
528 }
529 // Had failure warn if enough pt to reach HCal
530 if( not validHCal and orgTrack->pt() > 2000. ){
531 ATH_MSG_DEBUG("Failed extrapolation to HCal");
532 }
533
534 ATH_MSG_DEBUG( "Extrapolated track with eta=" << orgTrack->eta()
535 << " phi="<<orgTrack->phi()
536 << " to ECal eta=" << etaEM
537 << " phi="<< phiEM
538 << " HCal eta=" << etaHad
539 << " phi="<< phiHad
540 );
541 }
546 }
547
548 return StatusCode::SUCCESS;
549
550}
551
552// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
554 std::vector<const xAOD::TrackParticle*> &tauTracks,
555 std::vector<const xAOD::TrackParticle*> &wideTracks,
556 std::vector<const xAOD::TrackParticle*> &otherTracks,
557 const xAOD::Vertex* tauOrigin,
558 double maxDeltaZ0) const
559{
560 float MAX=1e5;
561
562 // need at least one core track to have a leading trk to compare with
563 if (tauTracks.empty()) return;
564
565 // get lead trk parameters
566 const xAOD::TrackParticle *leadTrack = tauTracks.at(0);
567 float z0_leadTrk = getZ0(ctx, leadTrack, tauOrigin);
568
569 if (z0_leadTrk > MAX-1) return; // bad lead trk -> do nothing
570
571 ATH_MSG_VERBOSE("before z0 cut: #coreTracks=" << tauTracks.size() << ", #wideTracks=" << wideTracks.size() << ", #otherTracks=" << otherTracks.size());
572
573 std::vector<const xAOD::TrackParticle*>::iterator itr;
574
575 // skip leading track, because it is the reference
576 itr = tauTracks.begin()+1;
577 while (itr!=tauTracks.end()) {
578 float z0 = getZ0(ctx, *itr, tauOrigin);
579 float deltaZ0=z0 - z0_leadTrk;
580 ATH_MSG_VERBOSE("core Trks: deltaZ0= " << deltaZ0);
581
582 if ( std::abs(deltaZ0) < maxDeltaZ0 ) {++itr;}
583 else {
584 otherTracks.push_back(*itr);
585 itr = tauTracks.erase(itr); //remove from core track collection
586 }
587 }
588
589 // check wide tracks
590 itr = wideTracks.begin();
591 while (itr!=wideTracks.end()) {
592 float z0 = getZ0(ctx, *itr, tauOrigin);
593 float deltaZ0=z0 - z0_leadTrk;
594 ATH_MSG_VERBOSE("wide Trks: deltaZ0= " << deltaZ0);
595
596 if ( std::abs(deltaZ0) < maxDeltaZ0 ) { ++itr; }
597 else {
598 otherTracks.push_back(*itr);
599 itr = wideTracks.erase(itr); //remove from wide track collection
600 }
601 }
602
603 ATH_MSG_VERBOSE("after z0 cut: #coreTracks=" << tauTracks.size() << ", #wideTracks=" << wideTracks.size() << ", #otherTracks=" << otherTracks.size());
604
605 // sort again
606 std::sort(tauTracks.begin(), tauTracks.end(), TrackSort());
607 std::sort(wideTracks.begin(), wideTracks.end(), TrackSort());
608 std::sort(otherTracks.begin(), otherTracks.end(), TrackSort());
609}
610
611// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
612float TauTrackFinder::getZ0(const EventContext& ctx, const xAOD::TrackParticle* track, const xAOD::Vertex* vertex) const
613{
614 float MAX=1e5;
615
616 if (!track) return MAX;
617
618 std::unique_ptr<Trk::Perigee> perigee;
619 if (vertex) perigee = m_trackToVertexTool->perigeeAtVertex(ctx, *track, vertex->position());
620 else perigee = m_trackToVertexTool->perigeeAtVertex(ctx, *track); //will use beamspot or 0,0,0 instead
621
622 if (!perigee) {
623 ATH_MSG_WARNING("Bad track; can't find perigee at vertex.");
624 return MAX;
625 }
626
627 return static_cast<float>(perigee->parameters()[Trk::z0]);
628}
629
631{
632 const std::bitset<xAOD::NumberOfTrackRecoInfo> patternReco = track->patternRecoInfo();
634 ATH_MSG_DEBUG("LargeD0Track found");
635 return true;
636 }
637
638 return false;
639}
640#endif
#define MAX(x, y)
#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)
double charge(const T &p)
Definition AtlasPID.h:997
unsigned int uint
static Double_t sc
value_type push_back(value_type pElem)
Add an element to the end of the collection.
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
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.
Helper class to provide type-safe access to aux data.
Helper class to provide constant type-safe access to aux data.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
virtual const std::string & key() const override final
Return the StoreGate ID for the referenced object.
TauRecToolBase(const std::string &name)
bool inEleRM() const
bool inTrigger() const
SG::ReadHandleKey< CaloExtensionCollection > m_ParticleCacheKey
SG::ReadCondHandleKey< InDet::BeamSpotData > m_beamSpotKey
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_trackPartInputContainer
TauTrackType tauTrackType(const xAOD::TauJet &tauJet, const xAOD::TrackParticle &trackParticle, const xAOD::Vertex *primaryVertex) const
Gaudi::Property< double > m_ghostTrackDR
virtual StatusCode initialize() override
Algorithm functions.
StatusCode extrapolateToCaloSurface(const EventContext &ctx, xAOD::TauJet &pTau, xAOD::TauTrackContainer &tauTrackCon) const
Extrapolate track eta and phi to the calorimeter middle surface.
void getTauTracksFromPV(const xAOD::TauJet &tauJet, const std::vector< const xAOD::TrackParticle * > &vecTrackParticles, const xAOD::Vertex *primaryVertex, const bool &useGhostTracks, const xAOD::JetContainer *jetContainer, std::vector< const xAOD::TrackParticle * > &tauTracks, std::vector< const xAOD::TrackParticle * > &wideTracks, std::vector< const xAOD::TrackParticle * > &otherTracks) const
std::set< CaloSampling::CaloSample > m_HadSamplings
ToolHandle< Trk::ITrackToVertexIPEstimator > m_trackToVertexIPEstimator
SG::ReadHandleKey< xAOD::JetContainer > m_jetContainer
std::set< CaloSampling::CaloSample > m_EMSamplings
TauTrackType
Enumerator defining type of tau track.
ToolHandle< Trk::ITrackSelectorTool > m_trackSelectorTool_tau
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_largeD0TracksInputContainer
Gaudi::Property< double > m_maxJetDr_wide
Gaudi::Property< float > m_z0maxDelta
virtual StatusCode executeTrackFinder(xAOD::TauJet &pTau, xAOD::TauTrackContainer &tauTrackCon) const override
Gaudi::Property< bool > m_applyZ0cut
Gaudi::Property< double > m_maxJetDr_tau
Gaudi::Property< bool > m_bypassExtrapolator
Gaudi::Property< bool > m_useGhostTracks
void removeOffsideTracksWrtLeadTrk(const EventContext &ctx, std::vector< const xAOD::TrackParticle * > &tauTracks, std::vector< const xAOD::TrackParticle * > &wideTracks, std::vector< const xAOD::TrackParticle * > &otherTracks, const xAOD::Vertex *tauOrigin, double maxDeltaZ0) const
TauTrackFinder(const std::string &name)
Constructor and Destructor.
ToolHandle< Trk::IParticleCaloExtensionTool > m_caloExtensionTool
tools
float getZ0(const EventContext &ctx, const xAOD::TrackParticle *track, const xAOD::Vertex *vertex) const
Some internally used functions.
Gaudi::Property< bool > m_removeDuplicateCoreTracks
bool isLargeD0Track(const xAOD::TrackParticle *track) const
ToolHandle< Reco::ITrackToVertex > m_trackToVertexTool
Helper method to sort tracks.
Definition TrackSort.h:24
Tracking class to hold the extrapolation through calorimeter Layers Both the caloEntryLayerIntersecti...
const std::vector< CurvilinearParameters > & caloLayerIntersections() const
access to the intersections with the calorimeter layers.
helper class to encode and decode a TrackParametersIdentifier
bool isEntryToVolume(TrackParametersIdentifier id) const
returns true if the id belongs to the volume entrance
CaloSampling::CaloSample caloSample(TrackParametersIdentifier id) const
CaloSample encoded in id, returns CaloSampling::Unknown if id is not valid.
std::vector< const T * > getAssociatedObjects(const std::string &name) const
get associated objects as a vector<object> this compact form throws an exception if the object is not...
float charge() const
virtual FourMom_t p4() const
The full 4-momentum of the particle.
Definition TauJet_v3.cxx:96
void setCharge(float)
const TauTrack * track(size_t i, TauJetParameters::TauTrackFlag flag=TauJetParameters::TauTrackFlag::classifiedCharged, int *container_index=0) const
Get the pointer to a given tauTrack associated with this tau /*container index needed by trackNonCons...
void setDetail(TauJetParameters::Detail detail, int value)
const Vertex * vertex() const
size_t nAllTracks() const
const Jet * jet() const
const TauTrackLinks_t & allTauTrackLinks() const
void addTauTrackLink(const ElementLink< TauTrackContainer > &tr)
add a TauTrack to the tau
size_t nTracks(TauJetParameters::TauTrackFlag flag=TauJetParameters::TauTrackFlag::classifiedCharged) const
virtual double eta() const
The pseudorapidity ( ) of the particle.
virtual double phi() const
The azimuthal angle ( ) of the particle.
void setDetail(TauJetParameters::TrackDetail detail, float value)
const TrackParticle * track() const
virtual double m() const override final
The invariant mass of the particle..
virtual FourMom_t p4() const override final
The full 4-momentum of the particle.
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.
float charge() const
Returns the charge.
void setCovariancePosition(const AmgSymMatrix(3)&covariancePosition)
Sets the vertex covariance matrix.
void setZ(float value)
Sets the z position.
void setX(float value)
Sets the x position.
void setY(float value)
Sets the y position.
void setPosition(const Amg::Vector3D &position)
Sets the 3-position.
VxType::VertexType vertexType() const
The type of the vertex.
CurvilinearParametersT< TrackParametersDim, Charged, PlaneSurface > CurvilinearParameters
@ z0
Definition ParamDefs.h:64
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
@ NoVtx
Dummy vertex. TrackParticle was not used in vertex fit.
Jet_v1 Jet
Definition of the current "jet version".
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Vertex_v1 Vertex
Define the latest version of the vertex class.
TauTrack_v1 TauTrack
Definition of the current version.
Definition TauTrack.h:16
TauJet_v3 TauJet
Definition of the current "tau version".
@ JetConstitScaleMomentum
Definition JetTypes.h:29
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
TauTrackContainer_v1 TauTrackContainer
Definition of the current TauTrack container version.
JetContainer_v1 JetContainer
Definition of the current "jet container version".
@ SiSpacePointsSeedMaker_LargeD0
ROOT::Math::LorentzVector< ROOT::Math::PtEtaPhiM4D< double > > JetFourMom_t
Base 4 Momentum type for Jet.
Definition JetTypes.h:17