ATLAS Offline Software
Loading...
Searching...
No Matches
TauTrackFinder.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 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
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(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) ATH_MSG_INFO( "Found Already Used track new, now removing: " << *track_it );
145 if (alreadyUsed) track_it = tauTracks.erase(track_it);
146 else ++track_it;
147 }
148 }
149
150 // associate track to tau candidate and calculate charge
151 float charge = 0.;
152 for (unsigned int i = 0; i < tauTracks.size(); ++i) {
153 const xAOD::TrackParticle* trackParticle = tauTracks.at(i);
154
155 ATH_MSG_VERBOSE(name() << " adding core track nr: " << i
156 << " eta " << trackParticle->eta()
157 << " phi " << trackParticle->phi());
158
159 charge += trackParticle->charge();
160
161 xAOD::TauTrack* track = new xAOD::TauTrack();
162 tauTrackCon.push_back(track);
163
165 linkToTrackParticle.toContainedElement(*static_cast<const xAOD::TrackParticleContainer*>(trackParticle->container()), trackParticle);
166 if (foundLRTCont && isLargeD0Track(trackParticle)){//Check LRT track and link to container
168 }
169 else {
171 }
172 track->addTrackLink(linkToTrackParticle);
173
174 track->setP4(trackParticle->pt(), trackParticle->eta(), trackParticle->phi(), trackParticle->m());
177 // in case TrackClassifier is not run, still get sensible results
180
182 linkToTauTrack.toContainedElement(tauTrackCon, track);
183 pTau.addTauTrackLink(linkToTauTrack);
184
185 ATH_MSG_VERBOSE(name() << " added core track nr: " << i
186 << " eta " << pTau.track(i)->eta()
187 << " phi " << pTau.track(i)->phi());
188 }
189 // set the charge, which is defined by the core tau tracks only
190 pTau.setCharge(charge);
191
192 for (unsigned int i = 0; i < wideTracks.size(); ++i) {
193 const xAOD::TrackParticle* trackParticle = wideTracks.at(i);
194
195 ATH_MSG_VERBOSE(name() << " adding wide track nr: " << i
196 << " eta " << trackParticle->eta()
197 << " phi " << trackParticle->phi());
198
199 xAOD::TauTrack* track = new xAOD::TauTrack();
200 tauTrackCon.push_back(track);
201
203 linkToTrackParticle.toContainedElement(*static_cast<const xAOD::TrackParticleContainer*>(trackParticle->container()), trackParticle);
204 if (foundLRTCont && isLargeD0Track(trackParticle)){//Check LRT track and link to container
206 }
207 else {
209 }
210 track->addTrackLink(linkToTrackParticle);
211
212 track->setP4(trackParticle->pt(), trackParticle->eta(), trackParticle->phi(), trackParticle->m());
215 // in case TrackClassifier is not run, still get sensible results
216 track->setFlag(xAOD::TauJetParameters::TauTrackFlag::classifiedIsolation, true); // for sake of trigger, reset in TauTrackClassifier
217 track->setFlag(xAOD::TauJetParameters::TauTrackFlag::modifiedIsolationTrack, true); // for sake of trigger, reset in TauTrackClassifier
219
221 linkToTauTrack.toContainedElement(tauTrackCon, track);
222 pTau.addTauTrackLink(linkToTauTrack);
223 }
224
225 //These are set again in TauTrackClassifier
226 pTau.setDetail(xAOD::TauJetParameters::nChargedTracks, static_cast<int>(pTau.nTracks()));
228
229 for (unsigned int i = 0; i < otherTracks.size(); ++i) {
230 const xAOD::TrackParticle* trackParticle = otherTracks.at(i);
231
232 ATH_MSG_VERBOSE(name() << " adding other track nr: " << i
233 << " eta " << trackParticle->eta()
234 << " phi " << trackParticle->phi());
235
236 xAOD::TauTrack* track = new xAOD::TauTrack();
237 tauTrackCon.push_back(track);
238
240 if (foundLRTCont && isLargeD0Track(trackParticle)){//Check LRT track and link to container
241 linkToTrackParticle.toContainedElement(*static_cast<const xAOD::TrackParticleContainer*>(trackParticle->container()), trackParticle);
243 }
244 else {
245 linkToTrackParticle.toContainedElement(*static_cast<const xAOD::TrackParticleContainer*>(trackParticle->container()), trackParticle);
247 }
248 track->addTrackLink(linkToTrackParticle);
249
250 track->setP4(trackParticle->pt(), trackParticle->eta(), trackParticle->phi(), trackParticle->m());
251 float dR = track->p4().DeltaR(pTau.p4());
253 else track->setFlag(xAOD::TauJetParameters::TauTrackFlag::wideTrack, true);
255
257 linkToTauTrack.toContainedElement(tauTrackCon, track);
258 pTau.addTauTrackLink(linkToTauTrack);
259 }
260
262 // keep track of total number of associated tracks, in case of tau track thinning
263 pTau.setDetail(xAOD::TauJetParameters::nAllTracks, static_cast<int>(pTau.nAllTracks()));
264
265 ATH_MSG_DEBUG("numTrack: " << "/" << pTau.nTracks());
266 ATH_MSG_DEBUG("charge: " << "/" << pTau.charge());
267
268 // impact parameter variables w.r.t. tau vertex
269 const xAOD::Vertex* vxcand = nullptr;
270
271 xAOD::Vertex vxbkp;
272 vxbkp.makePrivateStore();
273
274 // FIXME: don't we want to use the beamspot in the offline reconstruction too, when there is no reconstructed primary vertex?
275 if (pTau.vertex()!=nullptr && pTau.vertex()->vertexType() != xAOD::VxType::NoVtx) {
276 vxcand = pTau.vertex();
277 }
278 else if (inTrigger()) { // online: use vertex with x-y coordinates from the beamspot and the z from the leading track
279 vxbkp.setX(0); vxbkp.setY(0); vxbkp.setZ(0);
280
282 if(beamSpotHandle.isValid()) {
283 vxbkp.setPosition(beamSpotHandle->beamPos());
284 const auto& cov = beamSpotHandle->beamVtx().covariancePosition();
285 vxbkp.setCovariancePosition(cov);
286
287 if(!tauTracks.empty()) {
288 vxbkp.setZ(tauTracks.at(0)->z0());
289 }
290 }
291 else {
292 ATH_MSG_DEBUG("No Beamspot object in tau candidate");
293 }
294 vxcand = & vxbkp;
295 }
296
297
298 // this could be replaced with TauTrack::setDetail
299 static const SG::Accessor<float> dec_d0TJVA("d0TJVA");
300 static const SG::Accessor<float> dec_z0sinthetaTJVA("z0sinthetaTJVA");
301 static const SG::Accessor<float> dec_d0SigTJVA("d0SigTJVA");
302 static const SG::Accessor<float> dec_z0sinthetaSigTJVA("z0sinthetaSigTJVA");
303
304 for(const ElementLink<xAOD::TauTrackContainer>& trackLink : pTau.allTauTrackLinks())
305 {
306 assert (trackLink.getStorableObjectPointer() == &tauTrackCon);
307 xAOD::TauTrack* track = tauTrackCon[trackLink.index()];
308 dec_d0TJVA(*track) = track->track()->d0();
309 dec_z0sinthetaTJVA(*track) = track->z0sinThetaTJVA(pTau);
310 dec_d0SigTJVA(*track) = -999.;
311 dec_z0sinthetaSigTJVA(*track) = -999.;
312
313 // in the trigger, z0sintheta and corresponding significance are meaningless if we use the beamspot
314 if(vxcand) {
315 std::unique_ptr<const Trk::ImpactParametersAndSigma> myIPandSigma
316 = std::unique_ptr<const Trk::ImpactParametersAndSigma>(m_trackToVertexIPEstimator->estimate(track->track(), vxcand));
317
318 if(myIPandSigma) {
319 dec_d0TJVA(*track) = myIPandSigma->IPd0;
320 dec_z0sinthetaTJVA(*track) = myIPandSigma->IPz0SinTheta;
321 dec_d0SigTJVA(*track) = (myIPandSigma->sigmad0 != 0.) ? static_cast<float>( myIPandSigma->IPd0 / myIPandSigma->sigmad0 ) : -999.f;
322 dec_z0sinthetaSigTJVA(*track) = (myIPandSigma->sigmaz0SinTheta != 0.) ? static_cast<float>( myIPandSigma->IPz0SinTheta / myIPandSigma->sigmaz0SinTheta ) : -999.f;
323 }
324 }
325 }
326
327 // extrapolate core tracks to calorimeter surface
328 // store information only in ExtraDetailsContainer
330 {
331 StatusCode sc = extrapolateToCaloSurface(pTau, tauTrackCon);
332 if (sc.isFailure() && !sc.isRecoverable()) {
333 ATH_MSG_ERROR("couldn't extrapolate tracks to calo surface");
334 return StatusCode::FAILURE;
335 }
336 }
337
338 return StatusCode::SUCCESS;
339}
340
341
342// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
344 const xAOD::TrackParticle& trackParticle,
345 const xAOD::Vertex* primaryVertex) const
346{
347 double dR = pTau.p4().DeltaR(trackParticle.p4());
348
349 if (dR > m_maxJetDr_wide) return NotTauTrack;
350
351 bool goodTrack = m_trackSelectorTool_tau->decision(trackParticle, primaryVertex);
352
353 if (goodTrack) {
354 if (dR > m_maxJetDr_tau)
355 return TauTrackWide;
356 else
357 return TauTrackCore;
358 } else
359 return TauTrackOther;
360}
361
362// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
364 const std::vector<const xAOD::TrackParticle*>& vecTrackParticles,
365 const xAOD::Vertex* primaryVertex,
366 const bool& useGhostTracks,
367 const xAOD::JetContainer* jetContainer,
368 std::vector<const xAOD::TrackParticle*> &tauTracks,
369 std::vector<const xAOD::TrackParticle*> &wideTracks,
370 std::vector<const xAOD::TrackParticle*> &otherTracks) const
371{
372 std::vector<const xAOD::TrackParticle*> ghostTracks;
373 if(useGhostTracks) {
374 const xAOD::Jet* seedJet = pTau.jet();
375 if(seedJet) {
376 if(!seedJet->getAssociatedObjects("GhostTrack", ghostTracks)) {
377 ATH_MSG_WARNING("Could not retrieve GhostTrack from seed jet.");
378 }
379 }
380 }
381 // in EleRM reco, we need the original track particles
382 if (inEleRM()){
383 for (uint i = 0; i < ghostTracks.size(); i++){
384 static const SG::ConstAccessor<ElementLink<xAOD::TrackParticleContainer>> acc_originalTrack("ERMOriginalTrack");
385 auto original_id_track_link = acc_originalTrack(*(ghostTracks[i]));
386 if (!original_id_track_link.isValid()) {
387 ATH_MSG_ERROR("Original track link is not valid");
388 continue;
389 }
390 ghostTracks[i] = *original_id_track_link;
391 }
392 }
393
394 for (const xAOD::TrackParticle *trackParticle : vecTrackParticles) {
395 TauTrackType type = tauTrackType(pTau, *trackParticle, primaryVertex);
396 if(type == NotTauTrack) continue;
397
398 if(useGhostTracks) {
399 // require that tracks are ghost-matched with the seed jet at large dR(tau,track), to avoid using tracks from another tau
400 double dR = pTau.p4().DeltaR(trackParticle->p4());
401 if (dR > m_ghostTrackDR) {
402 if (std::find(ghostTracks.begin(), ghostTracks.end(), trackParticle) == ghostTracks.end()) {
403 // check whether the jet closest to the track is the current seed jet
404 // if so, recover the track even if not ghost-matched, to improve tau-track association efficiency at low pt (esp. for 3p)
405 double dRmin = 999.;
406 bool isSeedClosest = false;
407 for (const xAOD::Jet* jet : *jetContainer) {
409 TLorentzVector jetLV;
410 jetLV.SetPtEtaPhiM(jetP4.Pt(), jetP4.Eta(), jetP4.Phi(), jetP4.M());
411 double dRjet = trackParticle->p4().DeltaR(jetLV);
412 if(dRjet < dRmin) {
413 dRmin = dRjet;
414 isSeedClosest = (jet == pTau.jet());
415 }
416 }
417 if(!isSeedClosest) continue;
418 }
419 }
420 }
421
422 if (type == TauTrackCore)
423 tauTracks.push_back(trackParticle);
424 else if (type == TauTrackWide)
425 wideTracks.push_back(trackParticle);
426 else if (type == TauTrackOther)
427 otherTracks.push_back(trackParticle);
428 }
429 std::sort(tauTracks.begin(), tauTracks.end(), TrackSort());
430 std::sort(wideTracks.begin(), wideTracks.end(), TrackSort());
431 std::sort(otherTracks.begin(), otherTracks.end(), TrackSort());
432}
433
434
435// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
437 xAOD::TauTrackContainer& tauTrackCon) const
438{
439 Trk::TrackParametersIdHelper parsIdHelper;
440
441 int trackIndex = -1;
442 const Trk::CaloExtension * caloExtension = nullptr;
443 std::unique_ptr<Trk::CaloExtension> uniqueExtension;
444 for(const ElementLink<xAOD::TauTrackContainer>& trackLink : pTau.allTauTrackLinks())
445 {
446 assert (trackLink.getStorableObjectPointer() == &tauTrackCon);
447 xAOD::TauTrack* tauTrack = tauTrackCon[trackLink.index()];
448 const xAOD::TrackParticle *orgTrack = tauTrack->track();
449 if( !orgTrack ) continue;
450 trackIndex = orgTrack->index();
451
452 // set default values
453 float etaEM = -10.0;
454 float phiEM = -10.0;
455 float etaHad = -10.0;
456 float phiHad = -10.0;
457
458 // get the extrapolation into the calo
459 ATH_MSG_DEBUG( "Try extrapolation of track with pt = " << orgTrack->pt()
460 << ", eta " << orgTrack->eta()
461 << ", phi" << orgTrack->phi() );
462
463 if(!m_ParticleCacheKey.key().empty()){
464 /*get the CaloExtension object*/
465 ATH_MSG_VERBOSE("Using the CaloExtensionBuilder Cache");
467 caloExtension = (*particleCache)[trackIndex];
468 ATH_MSG_VERBOSE("Getting element " << trackIndex << " from the particleCache");
469 if( not caloExtension ){
470 ATH_MSG_VERBOSE("Cache does not contain a calo extension -> "
471 "Calculating with the a CaloExtensionTool");
472 uniqueExtension = m_caloExtensionTool->caloExtension(
473 Gaudi::Hive::currentContext(), *orgTrack);
474 caloExtension = uniqueExtension.get();
475 }
476 }
477 else {
478 /* If CaloExtensionBuilder is unavailable, use the calo extension tool */
479 ATH_MSG_VERBOSE("Using the CaloExtensionTool");
480 uniqueExtension = m_caloExtensionTool->caloExtension(
481 Gaudi::Hive::currentContext(), *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// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
553void TauTrackFinder::removeOffsideTracksWrtLeadTrk(std::vector<const xAOD::TrackParticle*> &tauTracks,
554 std::vector<const xAOD::TrackParticle*> &wideTracks,
555 std::vector<const xAOD::TrackParticle*> &otherTracks,
556 const xAOD::Vertex* tauOrigin,
557 double maxDeltaZ0) const
558{
559 float MAX=1e5;
560
561 // need at least one core track to have a leading trk to compare with
562 if (tauTracks.empty()) return;
563
564 // get lead trk parameters
565 const xAOD::TrackParticle *leadTrack = tauTracks.at(0);
566 float z0_leadTrk = getZ0(leadTrack, tauOrigin);
567
568 if (z0_leadTrk > MAX-1) return; // bad lead trk -> do nothing
569
570 ATH_MSG_VERBOSE("before z0 cut: #coreTracks=" << tauTracks.size() << ", #wideTracks=" << wideTracks.size() << ", #otherTracks=" << otherTracks.size());
571
572 std::vector<const xAOD::TrackParticle*>::iterator itr;
573
574 // skip leading track, because it is the reference
575 itr = tauTracks.begin()+1;
576 while (itr!=tauTracks.end()) {
577 float z0 = getZ0(*itr, tauOrigin);
578 float deltaZ0=z0 - z0_leadTrk;
579 ATH_MSG_VERBOSE("core Trks: deltaZ0= " << deltaZ0);
580
581 if ( std::abs(deltaZ0) < maxDeltaZ0 ) {++itr;}
582 else {
583 otherTracks.push_back(*itr);
584 itr = tauTracks.erase(itr); //remove from core track collection
585 }
586 }
587
588 // check wide tracks
589 itr = wideTracks.begin();
590 while (itr!=wideTracks.end()) {
591 float z0 = getZ0(*itr, tauOrigin);
592 float deltaZ0=z0 - z0_leadTrk;
593 ATH_MSG_VERBOSE("wide Trks: deltaZ0= " << deltaZ0);
594
595 if ( std::abs(deltaZ0) < maxDeltaZ0 ) { ++itr; }
596 else {
597 otherTracks.push_back(*itr);
598 itr = wideTracks.erase(itr); //remove from wide track collection
599 }
600 }
601
602 ATH_MSG_VERBOSE("after z0 cut: #coreTracks=" << tauTracks.size() << ", #wideTracks=" << wideTracks.size() << ", #otherTracks=" << otherTracks.size());
603
604 // sort again
605 std::sort(tauTracks.begin(), tauTracks.end(), TrackSort());
606 std::sort(wideTracks.begin(), wideTracks.end(), TrackSort());
607 std::sort(otherTracks.begin(), otherTracks.end(), TrackSort());
608}
609
610// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
611float TauTrackFinder::getZ0(const xAOD::TrackParticle* track, const xAOD::Vertex* vertex) const
612{
613 float MAX=1e5;
614
615 if (!track) return MAX;
616
617 std::unique_ptr<Trk::Perigee> perigee;
618 if (vertex) perigee = m_trackToVertexTool->perigeeAtVertex(Gaudi::Hive::currentContext(), *track, vertex->position());
619 else perigee = m_trackToVertexTool->perigeeAtVertex(Gaudi::Hive::currentContext(), *track); //will use beamspot or 0,0,0 instead
620
621 if (!perigee) {
622 ATH_MSG_WARNING("Bad track; can't find perigee at vertex.");
623 return MAX;
624 }
625
626 return static_cast<float>(perigee->parameters()[Trk::z0]);
627}
628
630{
631 const std::bitset<xAOD::NumberOfTrackRecoInfo> patternReco = track->patternRecoInfo();
633 ATH_MSG_DEBUG("LargeD0Track found");
634 return true;
635 }
636
637 return false;
638}
639#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.
void makePrivateStore()
Create a new (empty) private store for this object.
const SG::AuxVectorData * container() const
Return the container holding this element.
size_t index() const
Return the index of this element within its container.
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
float getZ0(const xAOD::TrackParticle *track, const xAOD::Vertex *vertex) const
Some internally used functions.
virtual StatusCode initialize() override
Algorithm functions.
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
StatusCode extrapolateToCaloSurface(xAOD::TauJet &pTau, xAOD::TauTrackContainer &tauTrackCon) const
Extrapolate track eta and phi to the calorimeter middle surface.
ToolHandle< Trk::ITrackToVertexIPEstimator > m_trackToVertexIPEstimator
void removeOffsideTracksWrtLeadTrk(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
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
TauTrackFinder(const std::string &name)
Constructor and Destructor.
ToolHandle< Trk::IParticleCaloExtensionTool > m_caloExtensionTool
tools
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