ATLAS Offline Software
Loading...
Searching...
No Matches
TrackSelectionAlgs.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// Header include
9
12
13#include <iostream>
14
15#include "TH1D.h"
16#include "TNtuple.h"
17#include "TTree.h"
18#include "TROOT.h"
19
20//-------------------------------------------------
21
22using namespace std;
23
24namespace VKalVrtAthena {
25
26
27 //____________________________________________________________________________________________________
28 bool VrtSecInclusive::selectTrack_d0Cut ( const xAOD::TrackParticle* trk ) const { return ( fabs( trk->d0() ) > m_jp.d0TrkPVDstMinCut && fabs( trk->d0() ) < m_jp.d0TrkPVDstMaxCut ); }
29 bool VrtSecInclusive::selectTrack_z0Cut ( const xAOD::TrackParticle* trk ) const { return ( fabs( trk->z0() ) > m_jp.z0TrkPVDstMinCut && fabs( trk->z0() ) < m_jp.z0TrkPVDstMaxCut ); }
30 bool VrtSecInclusive::selectTrack_d0errCut ( const xAOD::TrackParticle* trk ) const { const double cov11 = trk->definingParametersCovMatrix()(0,0); return cov11 < m_jp.d0TrkErrorCut*m_jp.d0TrkErrorCut; }
31 bool VrtSecInclusive::selectTrack_z0errCut ( const xAOD::TrackParticle* trk ) const { const double cov22 = trk->definingParametersCovMatrix()(1,1); return cov22 < m_jp.z0TrkErrorCut*m_jp.z0TrkErrorCut; }
34 bool VrtSecInclusive::selectTrack_pTCut ( const xAOD::TrackParticle* trk ) const { return trk->pt() > m_jp.TrkPtCut; }
35 bool VrtSecInclusive::selectTrack_chi2Cut ( const xAOD::TrackParticle* trk ) const { return trk->chiSquared() / (trk->numberDoF()+AlgConsts::infinitesimal) < m_jp.TrkChi2Cut; }
36
37 //____________________________________________________________________________________________________
39
40 uint8_t PixelHits = 0;
41 uint8_t SCTHits = 0;
42 uint8_t BLayHits = 0;
43 uint8_t PixShare = 0;
44 uint8_t SCTShare = 0;
45 uint8_t TRTHits = 0;
46
47 if( !(trk->summaryValue( PixelHits, xAOD::numberOfPixelHits ) ) ) PixelHits =0;
48 if( !(trk->summaryValue( SCTHits, xAOD::numberOfSCTHits ) ) ) SCTHits =0;
49 if( !(trk->summaryValue( BLayHits, xAOD::numberOfInnermostPixelLayerHits ) ) ) BLayHits =0;
50 if( !(trk->summaryValue( PixShare, xAOD::numberOfPixelSharedHits ) ) ) PixShare =0;
51 if( !(trk->summaryValue( SCTShare, xAOD::numberOfSCTSharedHits ) ) ) SCTShare =0;
52 if( !(trk->summaryValue( TRTHits, xAOD::numberOfTRTHits ) ) ) TRTHits =0;
53
54 uint8_t SharedHits = PixShare + SCTShare;
55
56 // do Pixel/SCT/SiHits only if we exclude StandAlone TRT hits
57 if( !m_jp.SAloneTRT ) {
58 if(PixelHits < m_jp.CutPixelHits) return false;
59 if(SCTHits < m_jp.CutSctHits) return false;
60 if((PixelHits+SCTHits) < m_jp.CutSiHits) return false;
61 if(BLayHits < m_jp.CutBLayHits) return false;
62 if(SharedHits > m_jp.CutSharedHits) return false;
63 }
64
65 // The folloing part reproduces the track selection in RPVDixpVrt
66 if( m_jp.doTRTPixCut ) {
67 if(TRTHits == 0 && PixelHits < 2) return false;
68 }
69
70 if( PixelHits == 0 && SCTHits < 6 ) return false;
71
72 return true;
73 }
74
75 //____________________________________________________________________________________________________
77 uint8_t PixelHits = 0;
78 uint8_t SCTHits = 0;
79 uint8_t TRTHits = 0;
80
81 if( !(trk->summaryValue( PixelHits, xAOD::numberOfPixelHits ) ) ) PixelHits =0;
82 if( !(trk->summaryValue( SCTHits, xAOD::numberOfSCTHits ) ) ) SCTHits =0;
83 if( !(trk->summaryValue( TRTHits, xAOD::numberOfTRTHits ) ) ) TRTHits =0;
84
85 if( trk->pt() > 20.e3 ) return true;
86
87 if( SCTHits < m_jp.CutTightSCTHits ) return false;
88
89 if( fabs( trk->eta() ) < 1.7 ) {
90 if( TRTHits < m_jp.CutTightTRTHits ) return false;
91 }
92
93 return true;
94 }
95
96 //____________________________________________________________________________________________________
100
101 //____________________________________________________________________________________________________
103 uint8_t npix = 0;
105 uint8_t nsct = 0;
107 uint8_t nSiHits = npix + nsct ;
108 uint8_t nSCTHoles=0;
109 trk->summaryValue(nSCTHoles, xAOD::numberOfSCTHoles);
110
111 double dTheta = std::fabs(TMath::ATan2(std::fabs(trk->d0()),trk->z0())-2*std::atan(std::exp(-1*trk->eta())));
112 bool geometric_cut = dTheta < 1. || std::fabs(trk->z0()) < 200. ;
113
114 bool z0_cut = trk->z0() <= 500. ;
115 bool chi2_cut = (trk->chiSquared()/ (trk->numberDoF()+AlgConsts::infinitesimal)) <= 9. ;
116 bool NSiHits_cut = nSiHits >=8 ;
117 bool NSCTHits_cut = nsct >= 7 ;
118 bool NSCTHoles_cut = nSCTHoles <= 1;
119
120 ATH_MSG_DEBUG( " > " << __FUNCTION__ << ": z0_cut, chi2_cut, NSiHits_cut, NSCTHits_cut, NSCTHoles_cut = " <<z0_cut<<", "<<chi2_cut<<", "<<NSiHits_cut<<", "<<NSCTHits_cut<<", "<< NSCTHoles_cut );
121 ATH_MSG_DEBUG( " > " << __FUNCTION__ << ": npix, nsct, nSiHits, nSCTHoles, dTheta, z0, d0, chi2 = " <<unsigned(npix)<<", "<<unsigned(nsct)<<", "<<unsigned(nSiHits)<<", "<<unsigned(nSCTHoles)<<", "<< dTheta<<", "<< trk->z0()<<", "<< trk->d0()<<", " <<trk->chiSquared() ) ;
122
123 const std::bitset<xAOD::NumberOfTrackRecoInfo> patternReco = trk->patternRecoInfo();
124 bool isLRT = patternReco.test(49) ;
125 ATH_MSG_DEBUG( " > " << __FUNCTION__ << ": Track is LRT = " << isLRT ) ;
126 if (isLRT) { // apply all cuts to LRT tracks
127 return (z0_cut && chi2_cut && NSiHits_cut && NSCTHits_cut && NSCTHoles_cut && geometric_cut);
128 }
129 else{ // not LRT track; only apply SiHit cut
130 return NSiHits_cut ;
131 }
132 }
133
134
135 //____________________________________________________________________________________________________
137
138 if( !m_decor_isSelected ) {
139 m_decor_isSelected.emplace( "is_selected" + m_jp.augVerString );
140 }
141
142 // Setup cut functions
143 if( m_trackSelectionFuncs.empty() && !m_jp.passThroughTrackSelection ) {
144
145 // These cuts are optional. Specified by JobProperty
147 if( m_jp.do_d0Cut ) m_trackSelectionFuncs.emplace_back( &VrtSecInclusive::selectTrack_d0Cut );
148 if( m_jp.do_z0Cut ) m_trackSelectionFuncs.emplace_back( &VrtSecInclusive::selectTrack_z0Cut );
149 if( m_jp.do_d0errCut ) m_trackSelectionFuncs.emplace_back( &VrtSecInclusive::selectTrack_d0errCut );
150 if( m_jp.do_z0errCut ) m_trackSelectionFuncs.emplace_back( &VrtSecInclusive::selectTrack_z0errCut );
151 if (m_jp.doSelectTracksWithLRTCuts) m_trackSelectionFuncs.emplace_back( &VrtSecInclusive::selectTrack_LRTR3Cut );
152 //if( m_jp.do_d0signifCut ) m_trackSelectionFuncs.emplace_back( &VrtSecInclusive::selectTrack_d0signifCut ); // not implemented yet
153 //if( m_jp.do_z0signifCut ) m_trackSelectionFuncs.emplace_back( &VrtSecInclusive::selectTrack_z0signifCut ); // not implemented yet
154
155 // These cuts are used by default
160
161 }
162
163 if( std::find( m_selectedTracks.begin(), m_selectedTracks.end(), trk ) != m_selectedTracks.end() ) return;
164
165 std::vector<bool> cutBits;
166
167 cutBits.reserve(m_trackSelectionFuncs.size());
168 for( auto func : m_trackSelectionFuncs ) cutBits.emplace_back( (this->*func)( trk ) );
169
170 if( m_jp.FillHist ) {
171 m_hists["trkSelCuts"]->Fill( 0 );
172 for( size_t ibit = 0; ibit < cutBits.size(); ibit++) {
173 if( cutBits.at(ibit) ) {
174 m_hists["trkSelCuts"]->Fill( ibit+1 );
175 } else {
176 break;
177 }
178 }
179 }
180
181 // Good track should not find any false bit
182 bool isGood_standard = ( std::find( cutBits.begin(), cutBits.end(), false ) == cutBits.end() );
183
184 if( isGood_standard ) {
185
186 // Store the selected track to the new m_selectedTracks
187 // Here we firstly need to register the empty pointer to the m_selectedTracks,
188 // then need to do deep copy after then. This is the feature of xAOD.
189
190 int uniqueID = HepMC::UNDEFINED_ID;
191
192 if( m_jp.doTruth ) {
193
194 const xAOD::TruthParticle *truth = getTrkGenParticle(trk);
195
196 if ( truth ) {
197 uniqueID = HepMC::uniqueID(truth);
198 }
199
200 }
201
202 (*m_decor_isSelected)( *trk ) = true;
203 if (m_jp.doSelectTracksFromElectrons || m_jp.doSelectIDAndGSFTracks) {
204 const xAOD::TrackParticle *id_tr;
206 if (id_tr != nullptr){
207 (*m_decor_isSelected)( *id_tr ) = true; }
208 }
209
210 m_selectedTracks.emplace_back( trk );
211
212 if( m_jp.FillNtuple ) m_ntupleVars->get< vector<int> >( "SelTrk_uniqueID" ).emplace_back(uniqueID);
213
214 ATH_MSG_VERBOSE( " > " << __FUNCTION__ << ": Track index " << trk->index() << " has been selected." );
215 ATH_MSG_VERBOSE( " > " << __FUNCTION__ << ": Track index " << trk->index()
216 << " parameter:"
217 << " pt = " << trk->pt()
218 << " eta = " << trk->eta()
219 << " d0 = " << trk->d0()
220 << " z0 = " << trk->z0() << "." );
221
222 }
223
224 }
225
226 //____________________________________________________________________________________________________
228
229 ATH_MSG_DEBUG( " > " << __FUNCTION__ << ": begin" );
230
231 //--------------------------------------------------------
232 // Extract tracks from xAOD::TrackParticle container
233 //
234
235 const xAOD::TrackParticleContainer* trackParticleContainer ( nullptr );
236 ATH_CHECK( evtStore()->retrieve( trackParticleContainer, m_jp.TrackLocation) );
237
238 ATH_MSG_DEBUG( " > " << __FUNCTION__ << ": Extracted xAOD::TrackParticle number=" << trackParticleContainer->size() );
239
240 if( m_jp.FillNtuple )
241 m_ntupleVars->get<unsigned int>( "NumAllTrks" ) = static_cast<int>( trackParticleContainer->size() );
242
243
244 // Loop over tracks
245 for( const auto *trk : *trackParticleContainer ) { selectTrack( trk ); }
246
247 ATH_MSG_DEBUG( " > " << __FUNCTION__ << ": Number of total ID tracks = " << trackParticleContainer->size() );
248 ATH_MSG_DEBUG( " > " << __FUNCTION__ << ": Number of selected tracks = " << m_selectedTracks.size() );
249
250 return StatusCode::SUCCESS;
251 }
252
253
254 //____________________________________________________________________________________________________
256
257 const xAOD::MuonContainer* muons ( nullptr );
258 ATH_CHECK( evtStore()->retrieve( muons, m_jp.MuonLocation) );
259
260
261 for( const auto *const muon : *muons ) {
262 const auto* trk = muon->trackParticle( xAOD::Muon::InnerDetectorTrackParticle );
263
264 if( !trk ) continue;
265 // remove calo-tagged muons when selecting muons
266 if (m_jp.doRemoveCaloTaggedMuons) {
267 if (muon->muonType() == xAOD::Muon::CaloTagged) continue;
268 }
269 selectTrack( trk );
270
271 }
272
273 ATH_MSG_DEBUG( " > " << __FUNCTION__ << ": Number of total muons = " << muons->size() );
274 ATH_MSG_DEBUG( " > " << __FUNCTION__ << ": Number of selected tracks = " << m_selectedTracks.size() );
275
276 return StatusCode::SUCCESS;
277 }
278
279
280 //____________________________________________________________________________________________________
282
283 const xAOD::ElectronContainer *electrons( nullptr );
284 ATH_CHECK( evtStore()->retrieve( electrons, m_jp.ElectronLocation ) );
285
286 for( const auto *const electron : *electrons ) {
287 if( 0 == electron->nTrackParticles() ) continue;
288
289 // The first track is the best-matched track
290 const auto* trk = electron->trackParticle(0);
291
292 if( !trk ) continue;
293 selectTrack( trk );
294 }
295
296 ATH_MSG_DEBUG( " > " << __FUNCTION__ << ": Number of total electrons = " << electrons->size() );
297 ATH_MSG_DEBUG( " > " << __FUNCTION__ << ": Number of selected tracks = " << m_selectedTracks.size() );
298
299 return StatusCode::SUCCESS;
300 }
301
302
303 //____________________________________________________________________________________________________
305
306 ATH_MSG_DEBUG( " > " << __FUNCTION__ << ": begin" );
307
308 //--------------------------------------------------------
309 // Extract tracks from xAOD::TrackParticle container
310 //
311
312 const xAOD::TrackParticleContainer* IDtracks ( nullptr );
313 ATH_CHECK( evtStore()->retrieve( IDtracks, m_jp.TrackLocation) );
314
315 const xAOD::ElectronContainer *electrons( nullptr );
316 ATH_CHECK( evtStore()->retrieve( electrons, m_jp.ElectronLocation ) );
317
318 const xAOD::MuonContainer* muons ( nullptr );
319 ATH_CHECK( evtStore()->retrieve( muons, m_jp.MuonLocation) );
320
321 std::vector<const xAOD::TrackParticle*> IDTrksFromEls;
322
323 // Loop over electrons to select all GSF tracks
324 for( const auto *electron : *electrons ) {
325 if( 0 == electron->nTrackParticles() ) { continue; }
326 // The first track is the best-matched GSF track
327 const auto* el_trk = electron->trackParticle(0);
328 selectTrack( el_trk );
329 m_leptonicTracks.emplace_back(el_trk);
330 IDTrksFromEls.emplace_back(xAOD::EgammaHelpers::getOriginalTrackParticle(electron));
331 }
332
333 // Loop over ID tracks to select all non-el tracks
334 for( const auto *trk : *IDtracks ) {
335 // do not select ID track if matched to an electron
336 if ( std::find(IDTrksFromEls.begin(), IDTrksFromEls.end(), trk) != IDTrksFromEls.end() ) { continue; }
337 selectTrack( trk );
338 }
339
340 // Loop over muons to book-keep all ID tracks matched to muons
341 for (const auto *muon : *muons) {
342 if (m_jp.doRemoveCaloTaggedMuons && muon->muonType() == xAOD::Muon::CaloTagged) { continue; }
343 const auto* mu_trk = muon->trackParticle( xAOD::Muon::InnerDetectorTrackParticle );
344 if(!mu_trk) { continue; }
345 m_leptonicTracks.emplace_back(mu_trk);
346 }
347
348 ATH_MSG_DEBUG( " > " << __FUNCTION__ << ": Number of total ID tracks = " << IDtracks->size() );
349 ATH_MSG_DEBUG( " > " << __FUNCTION__ << ": Number of total electrons = " << electrons->size() );
350 ATH_MSG_DEBUG( " > " << __FUNCTION__ << ": Number of selected tracks = " << m_selectedTracks.size() );
351
352 return StatusCode::SUCCESS;
353 }
354
355
356} // end of namespace VKalVrtAthena
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
size_type size() const noexcept
Returns the number of elements in the collection.
bool selectTrack_pTCut(const xAOD::TrackParticle *) const
static const xAOD::TruthParticle * getTrkGenParticle(const xAOD::TrackParticle *)
Definition TruthAlgs.cxx:26
bool selectTrack_chi2Cut(const xAOD::TrackParticle *) const
bool selectTrack_notPVassociated(const xAOD::TrackParticle *) const
track-by-track selection strategies
void selectTrack(const xAOD::TrackParticle *)
Vertexing Algorithm Member Functions.
bool selectTrack_hitPatternTight(const xAOD::TrackParticle *) const
static bool selectTrack_d0signifCut(const xAOD::TrackParticle *)
bool selectTrack_d0errCut(const xAOD::TrackParticle *) const
std::unique_ptr< NtupleVars > m_ntupleVars
bool selectTrack_hitPattern(const xAOD::TrackParticle *) const
std::vector< CutFunc > m_trackSelectionFuncs
std::optional< SG::Decorator< char > > m_decor_isSelected
std::map< std::string, TH1 * > m_hists
bool selectTrack_LRTR3Cut(const xAOD::TrackParticle *) const
bool selectTrack_d0Cut(const xAOD::TrackParticle *) const
bool selectTrack_z0Cut(const xAOD::TrackParticle *) const
const xAOD::VertexContainer * m_primaryVertices
bool selectTrack_z0errCut(const xAOD::TrackParticle *) const
std::vector< const xAOD::TrackParticle * > m_selectedTracks
static bool selectTrack_z0signifCut(const xAOD::TrackParticle *)
std::vector< const xAOD::TrackParticle * > m_leptonicTracks
float z0() const
Returns the parameter.
float numberDoF() const
Returns the number of degrees of freedom of the overall track or vertex fit as float.
const ParametersCovMatrix_t definingParametersCovMatrix() const
Returns the 5x5 symmetric matrix containing the defining parameters covariance matrix.
std::bitset< NumberOfTrackRecoInfo > patternRecoInfo() const
Access method for pattern recognition algorithm.
float d0() const
Returns the parameter.
bool summaryValue(uint8_t &value, const SummaryType &information) const
Accessor for TrackSummary values.
virtual double pt() const override final
The transverse momentum ( ) of the particle.
float chiSquared() const
Returns the of the overall track fit.
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
int uniqueID(const T &p)
constexpr int UNDEFINED_ID
bool isAssociatedToVertices(const xAOD::TrackParticle *trk, const xAOD::VertexContainer *vertices)
STL namespace.
const xAOD::TrackParticle * getOriginalTrackParticleFromGSF(const xAOD::TrackParticle *trkPar)
Helper function for getting the "Original" Track Particle (i.e before GSF) via the GSF Track Particle...
const xAOD::TrackParticle * getOriginalTrackParticle(const xAOD::Electron *el)
Helper function for getting the "Original" Track Particle (i.e before GSF) via the electron.
ElectronContainer_v1 ElectronContainer
Definition of the current "electron container version".
TrackParticle_v1 TrackParticle
Reference the current persistent version:
TruthParticle_v1 TruthParticle
Typedef to implementation.
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
MuonContainer_v1 MuonContainer
Definition of the current "Muon container version".
@ numberOfTRTHits
number of TRT hits [unit8_t].
@ numberOfSCTHits
number of hits in SCT [unit8_t].
@ numberOfInnermostPixelLayerHits
these are the hits in the 0th pixel barrel layer
@ numberOfPixelHits
these are the pixel hits, including the b-layer [unit8_t].
@ numberOfPixelSharedHits
number of Pixel all-layer hits shared by several tracks [unit8_t].
@ numberOfSCTSharedHits
number of SCT hits shared by several tracks [unit8_t].
@ numberOfSCTHoles
number of SCT holes [unit8_t].