ATLAS Offline Software
Loading...
Searching...
No Matches
TrackSelector.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
3*/
4
6
10#include "TrkTrack/Track.h"
12#include "CLHEP/GenericFunctions/CumulativeChiSquare.hh"
14#include "GaudiKernel/IToolSvc.h"
15#include <string>
16#include <bitset>
17#include <algorithm>
18
19namespace Analysis {
20
21 static const InterfaceID IID_ITrackSelector("Analysis::TrackSelector", 1, 0);
22
24 const std::string& name, const IInterface* parent) :
25 AthAlgTool(type, name, parent),
26 m_ntri(0),
27 m_ntrf(0)
28 {
29
30 declareInterface<TrackSelector>(this);
31 declareProperty("useBLayerHitPrediction", m_useBLayerHitPrediction = false);
32 declareProperty("usePerigeeParameters", m_usePerigeeParameters = false);
33 declareProperty("pTMin", m_pTMin = 1.*Gaudi::Units::GeV);
34 declareProperty("usepTDepTrackSel", m_usepTDepTrackSel = false);
35 declareProperty("pTMinOffset", m_pTMinOffset = 0.);
36 declareProperty("pTMinSlope", m_pTMinSlope = 0.);
37 declareProperty("d0Max", m_d0Max = 1.*Gaudi::Units::mm);
38 declareProperty("z0Max", m_z0Max = 1.5*Gaudi::Units::mm);
39 declareProperty("sigd0Max",m_sigd0Max = 999.*Gaudi::Units::mm);
40 declareProperty("sigz0Max",m_sigz0Max = 999.*Gaudi::Units::mm);
41 declareProperty("etaMax", m_etaMax = 9999.);
42 declareProperty("useTrackSummaryInfo", m_useTrackSummaryInfo = true);
43 declareProperty("nHitBLayer", m_nHitBLayer = 1);
44 declareProperty("nHitPix", m_nHitPix = 1);
45 declareProperty("nHitSct", m_nHitSct = 0);
46 declareProperty("nHitSi", m_nHitSi = 7);
47 declareProperty("nHitTrt", m_nHitTrt = 0);
48 declareProperty("nHitTrtHighE", m_nHitTrtHighE = 0);
49 declareProperty("useDeadPixInfo", m_useDeadPixInfo = true);
50 declareProperty("useDeadSctInfo", m_useDeadSctInfo = true);
51 declareProperty("useTrackQualityInfo", m_useTrackQualityInfo = true);
52 declareProperty("fitChi2", m_fitChi2 = 99999.);
53 declareProperty("fitProb", m_fitProb = -1.);
54 declareProperty("fitChi2OnNdfMax",m_fitChi2OnNdfMax=999.);
55 declareProperty("inputTrackCollection", m_inputTrackCollection);
56 declareProperty("outputTrackCollection", m_outputTrackCollection);
57 declareProperty("useAntiPileUpCuts", m_useAntiPileUpCuts = false);
58 declareProperty("antiPileUpSigD0Cut", m_antiPileUpSigD0Cut = 3.0);
59 declareProperty("antiPileUpSigZ0Cut", m_antiPileUpSigZ0Cut = 3.8);
60 declareProperty("antiPileUpNHitSiCut", m_antiPileUpNHitSiCut = 9);
61 declareProperty("antiPileUpNHolePixCut", m_antiPileUpNHolePixCut = 9);
62 declareProperty("useTrackingTightDefinition", m_useTrackingTightDefinition = false);
63 }
64
67
68 const InterfaceID& TrackSelector::interfaceID() {
69 return IID_ITrackSelector;
70 }
71
73 for(int i=0;i<numCuts;i++) m_ntrc[i]=0;
75 if ( m_trackToVertexTool.retrieve().isFailure() ) {
76 ATH_MSG_FATAL("#BTAG# Failed to retrieve tool " << m_trackToVertexTool);
77 return StatusCode::FAILURE;
78 } else {
79 ATH_MSG_DEBUG("#BTAG# Retrieved tool " << m_trackToVertexTool);
80 }
81
85 ATH_MSG_INFO("Using InDetEtaDependentCutsSvc. Track selections from config not used");
86 }
87 else{
88 ATH_MSG_INFO("Using track selections from config");
89 }
90
92 m_d0Max = 2*Gaudi::Units::mm;
93 m_z0Max = 3*Gaudi::Units::mm;
94 m_pTMin = 0.4*Gaudi::Units::GeV;
95 }
96
98 if (msgLvl(MSG::DEBUG)) {
99 msg(MSG::DEBUG) << "#BTAG# TrackSelector " << name() << " cuts: " << endmsg;
101 msg(MSG::DEBUG) << "#BTAG# - pT >= " << m_pTMin << endmsg;
102 msg(MSG::DEBUG) << "#BTAG# - |eta| <= " << m_etaMax << endmsg;
103 msg(MSG::DEBUG) << "#BTAG# - |d0| <= " << m_d0Max << endmsg;
104 msg(MSG::DEBUG) << "#BTAG# - |z0| <= " << m_z0Max << endmsg;
105 }
106
107 msg(MSG::DEBUG) << "#BTAG# - |sigd0| <= " << m_sigd0Max << endmsg;
108 msg(MSG::DEBUG) << "#BTAG# - |sigz0| <= " << m_sigz0Max << endmsg;
110 msg(MSG::DEBUG) << "#BTAG# - antiPUcut: reject tracks with |sigz0| > " << m_antiPileUpSigZ0Cut
111 << " when |sigd0| < " << m_antiPileUpSigD0Cut << endmsg;
112 }
113
115
117 msg(MSG::DEBUG) << "#BTAG# - nbHitsBLayer >= " << m_nHitBLayer << endmsg;
118 if(m_useDeadPixInfo) {
119 msg(MSG::DEBUG) << "#BTAG# - nbHitsPix+nbDeadPix >= " << m_nHitPix << endmsg;
120 } else {
121 msg(MSG::DEBUG) << "#BTAG# - nbHitsPix >= " << m_nHitPix << endmsg;
122 }
124 msg(MSG::DEBUG) << "#BTAG# using conddb for b-layer hit requirements " << endmsg;
125
126 if(m_useDeadSctInfo) {
127 msg(MSG::DEBUG) << "#BTAG# - nbHitsSct+nbDeadSct >= " << m_nHitSct << endmsg;
128 } else {
129 msg(MSG::DEBUG) << "#BTAG# - nbHitsSct >= " << m_nHitSct << endmsg;
130 }
131 int nhsi = m_nHitSi;
133 if(m_useDeadPixInfo) {
134 if(m_useDeadSctInfo) {
135 msg(MSG::DEBUG) << "#BTAG# - nbHitsSi+nbDeadPix+nbDeadSct >= " << nhsi << endmsg;
136 } else {
137 msg(MSG::DEBUG) << "#BTAG# - nbHitsSi+nbDeadPix >= " << nhsi << endmsg;
138 }
139 } else {
140 if(m_useDeadSctInfo) {
141 msg(MSG::DEBUG) << "#BTAG# - nbHitsSi+nbDeadSct >= " << nhsi << endmsg;
142 } else {
143 msg(MSG::DEBUG) << "#BTAG# - nbHitsSi >= " << nhsi << endmsg;
144 }
145 }
146 }
147
148 msg(MSG::DEBUG) << "#BTAG# - nbHitsTrt >= " << m_nHitTrt << endmsg;
149 msg(MSG::DEBUG) << "#BTAG# - nbHitsTrtHighE >= " << m_nHitTrtHighE << endmsg;
150 }
151
152 msg(MSG::DEBUG) << "#BTAG# - fit chi2 <= " << m_fitChi2 << endmsg;
153 msg(MSG::DEBUG) << "#BTAG# - fit proba >= " << m_fitProb << endmsg;
154 msg(MSG::DEBUG) << "#BTAG# - fit chi2 / ndf <= " << m_fitChi2OnNdfMax << endmsg;
155 }
156
157 return StatusCode::SUCCESS;
158 }
159
160
162 ATH_MSG_VERBOSE("#BTAG# tracks selected: In= " << m_ntri);
163 for(int i=0;i<numCuts;i++) ATH_MSG_VERBOSE("#BTAG# cut" << i << "= " << m_ntrc[i]);
164 ATH_MSG_VERBOSE("#BTAG# Out= " << m_ntrf);
165 return StatusCode::SUCCESS;
166 }
167
168
170 const xAOD::TrackParticle* track,
171 double refPt) const
172{
173 std::bitset<17> failedCuts;
174 return selectTrack (pv, track, failedCuts, refPt);
175}
176
178 const xAOD::TrackParticle* track,
179 std::bitset<17>& failedCuts,
180 double refPt) const
181{
182 double trackD0;
183 double trackZ0;
184 double tracksigD0;
185 double tracksigZ0;
187 trackD0 = track->d0();
188 trackZ0 = track->z0() - pv.z();
189 tracksigD0 = std::sqrt(track->definingParametersCovMatrix()(0,0));
190 tracksigZ0 = std::sqrt(track->definingParametersCovMatrix()(1,1));
191 } else {
192 // extrapolate with the TrackToVertex tool:
193 auto ctx = Gaudi::Hive::currentContext();
194 auto perigee = m_trackToVertexTool->perigeeAtVertex(ctx, *track, pv);
195 if (perigee==nullptr) {
196 ATH_MSG_WARNING("#BTAG# Extrapolation failed. Rejecting track... ");
197 return false;
198 }
199 trackD0 = perigee->parameters()[Trk::d0];
200 trackZ0 = perigee->parameters()[Trk::z0];
201 tracksigD0 = std::sqrt((*perigee->covariance())(Trk::d0,Trk::d0));
202 tracksigZ0 = std::sqrt((*perigee->covariance())(Trk::z0,Trk::z0));
203 }
204
205 ATH_MSG_VERBOSE( "#BTAG# Track "
206 << " Eta= " << track->eta() << " Phi= " << track->phi() << " pT= " <<track->pt()
207 << " d0= " << trackD0
208 << " z0= " << trackZ0 << " sigd0= " << tracksigD0 << " sigz0: " << tracksigZ0 );
209
211 double eta = track->eta();
212 bool pass = true;
213 double pTMin_cut = m_useEtaDependentCuts ? m_etaDependentCutsSvc->getMinPtAtEta(eta) : m_pTMin;
214 if(track->pt() < pTMin_cut) {
215 pass = false;
216 failedCuts.set(pTMin);
217 } else if (refPt > 0 && m_usepTDepTrackSel && track->pt() < m_pTMinOffset + m_pTMinSlope*refPt) {
218 pass = false;
219 failedCuts.set(pTMin);
220 }
221
222 double d0_cut = m_useEtaDependentCuts ? m_etaDependentCutsSvc->getMaxPrimaryImpactAtEta(eta) : m_d0Max;
223 if(std::abs(trackD0)>d0_cut) {
224 pass = false;
225 failedCuts.set(d0Max);
226 }
227
228 double z0_cut = m_useEtaDependentCuts ? m_etaDependentCutsSvc->getMaxZImpactAtEta(eta) : m_z0Max;
229 if(std::abs(trackZ0*sin(track->theta()))>z0_cut) {
230 pass = false;
231 failedCuts.set(z0Max);
232 }
233 if (tracksigD0>m_sigd0Max) {
234 pass = false;
235 failedCuts.set(sigd0Max);
236 }
237 if (tracksigZ0>m_sigz0Max) {
238 pass = false;
239 failedCuts.set(sigz0Max);
240 }
242 if(fabs(trackZ0/tracksigZ0)>m_antiPileUpSigZ0Cut && fabs(trackD0/tracksigD0)<m_antiPileUpSigD0Cut) {
243 pass = false;
244 failedCuts.set(sigz0Max);
245 failedCuts.set(sigd0Max);
246 }
247 }
248
249 double eta_cut = m_useEtaDependentCuts ? m_etaDependentCutsSvc->getMaxEta() : m_etaMax;
250 if(std::abs(track->eta())>eta_cut) {
251 pass = false;
252 failedCuts.set(etaMax);
253 }
255 uint8_t nb=0;
256 track->summaryValue(nb, xAOD::numberOfInnermostPixelLayerHits);
257 int InPix_cut = m_useEtaDependentCuts ? m_etaDependentCutsSvc->getMinInnermostPixelHitsAtEta(eta) : m_nHitBLayer;
258 if(nb < InPix_cut) {
259 failedCuts.set(nHitBLayer);
261 pass = false;
262 failedCuts.set(deadBLayer);
263 } else {
264 uint8_t ehib=1;
265 if (!track->summaryValue(ehib,xAOD::expectInnermostPixelLayerHit)) {
266 ATH_MSG_WARNING("#BTAG# expectInnermostPixelLayerHit not computed in TrackSummary: assuming true");
267 ehib=1;
268 }
269 if(ehib) { // check if module was alive
270 pass = false;
271 failedCuts.set(deadBLayer);
272 }
273 }
274 }
275 uint8_t nhp=0;
276 track->summaryValue(nhp, xAOD::numberOfPixelHoles);
278 int PixHole_cut = m_useEtaDependentCuts ? m_etaDependentCutsSvc->getMaxPixelHolesAtEta(eta) : m_antiPileUpNHolePixCut;
279 if(nhp>=PixHole_cut) {
280 pass = false;
281 }
282 }
283 uint8_t np=0;
284 track->summaryValue(np, xAOD::numberOfPixelHits);
286 {
287 uint8_t ndead;
288 track->summaryValue(ndead, xAOD::numberOfPixelDeadSensors);
289 np += std::max((int)ndead, 0);
290 }
291 int Pix_cut = m_useEtaDependentCuts ? m_etaDependentCutsSvc->getMinPixelHitsAtEta(eta) : m_nHitPix;
292 if(np < Pix_cut) {
293 pass = false;
294 failedCuts.set(nHitPix);
295 }
296
297 uint8_t ns=0;
298 track->summaryValue(ns, xAOD::numberOfSCTHits);
300 {
301 uint8_t ndead;
302 track->summaryValue(ndead, xAOD::numberOfSCTDeadSensors);
303 ns += std::max((int)ndead,0);
304 }
305 int SCTStrip_cut = m_useEtaDependentCuts ? m_etaDependentCutsSvc->getMinStripHitsAtEta(eta) : m_nHitSct;
306 if(ns < SCTStrip_cut) {
307 pass = false;
308 failedCuts.set(nHitSct);
309 }
310
311 int Si_cut = m_useEtaDependentCuts ? m_etaDependentCutsSvc->getMinSiHitsAtEta(eta) : m_nHitSi;
312 if((np+ns) < Si_cut) {
313 pass = false;
314 failedCuts.set(nHitSi);
315 }
317 if((np+ns) < m_antiPileUpNHitSiCut) {
318 pass = false;
319 failedCuts.set(nHitSi);
320 }
321 }
322 uint8_t nh=0;
323 track->summaryValue(nh, xAOD::numberOfTRTHits);//ms
324 if(nh < m_nHitTrt) {
325 pass = false;
326 failedCuts.set(nHitTrt);
327 }
328 uint8_t nhe=0;
329 track->summaryValue(nhe, xAOD::numberOfTRTHighThresholdHits);//ms
330 if(nhe < m_nHitTrtHighE) {
331 pass = false;
332 failedCuts.set(nHitTrtHighE);
333 }
334 // Tracking CP group Tight definition
336 uint8_t nibl, nnibl;
337 track->summaryValue(nibl , xAOD::numberOfPixelHits);
338 track->summaryValue(nnibl, xAOD::numberOfPixelHits);
339 bool innerHitsCrit = ((nibl+nnibl)>0);
340 bool lowetaCrit = fabs(track->eta())> 1.65 && (ns+np)>=11;
341 bool highetaCrit = fabs(track->eta())<=1.65 && (ns+np)>=9 ;
342 bool pixholeCrit = (nhp==0) ;
343 bool isTight = innerHitsCrit && pixholeCrit && (lowetaCrit || highetaCrit);
344 if (!isTight){
345 pass=false;
346 failedCuts.set(trackingTightDef);
347 }
348
349 }
350 }
351
352 // Now the fit quality
353 double chi2 = track->chiSquared();
354 int ndf = track->numberDoF();
355 double proba = 1.;
356 if(ndf>0 && chi2>=0.) {
357 Genfun::CumulativeChiSquare myCumulativeChiSquare(ndf);
358 proba = 1.-myCumulativeChiSquare(chi2);
359 }
360 if(chi2>m_fitChi2) {
361 pass = false;
362 failedCuts.set(fitChi2);
363 }
364 if(proba<m_fitProb) {
365 pass = false;
366 failedCuts.set(fitProb);
367 }
368 if(ndf>0) {
369 if(chi2/double(ndf)>m_fitChi2OnNdfMax) {
370 pass = false;
371 failedCuts.set(fitChi2OnNdfMax);
372 }
373 } else {
374 pass = false;
375 failedCuts.set(fitChi2OnNdfMax);
376 }
377
379 if( msgLvl(MSG::VERBOSE) ){
380 ATH_MSG_VERBOSE("#BTAG# passedCuts for track ");
381 for(int i=0;i<numCuts;i++) {
382 int passl = ~failedCuts[(m_Cuts)i];
383 if(passl) m_ntrc[i]++;
384 msg(MSG::VERBOSE) << passl;
385 }
386 msg(MSG::VERBOSE) << endmsg;
387 }
388
389 return pass;
390 }
391
392}
Scalar eta() const
pseudorapidity method
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
static const Attributes_t empty
virtual StatusCode initialize() override
double m_pTMin
if true use perigee parameters instead of parameters w.r.t. primary vertex
virtual StatusCode finalize() override
ServiceHandle< InDet::IInDetEtaDependentCutsSvc > m_etaDependentCutsSvc
service to get cut values depending on different variable
static const InterfaceID & interfaceID()
bool m_usePerigeeParameters
Properties for V0 finding: not yet implemented.
TrackSelector(const std::string &type, const std::string &name, const IInterface *parent)
bool m_useTrackQualityInfo
if true uses dead SCT sensors to compute nSct
bool selectTrack(const Amg::Vector3D &pv, const xAOD::TrackParticle *track, double refPt=0) const
Returns true if the argument track fulfills the selection.
bool m_useDeadSctInfo
if true uses dead pixel sensors from conddb (except b-layer) to compute nPix
std::string m_outputTrackCollection
location of inputTracks in StoreGate
bool m_useBLayerHitPrediction
if false the following cuts are ignored
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
bool msgLvl(const MSG::Level lvl) const
MsgStream & msg() const
double chi2(TH1 *h0, TH1 *h1)
Eigen::Matrix< double, 3, 1 > Vector3D
The namespace of all packages in PhysicsAnalysis/JetTagging.
static const InterfaceID IID_ITrackSelector("Analysis::TrackSelector", 1, 0)
@ d0
Definition ParamDefs.h:63
@ z0
Definition ParamDefs.h:64
TrackParticle_v1 TrackParticle
Reference the current persistent version:
@ expectInnermostPixelLayerHit
Do we expect a 0th-layer barrel hit for this track?
@ numberOfPixelHoles
number of pixel layers on track with absence of hits [unit8_t].
@ numberOfTRTHits
number of TRT hits [unit8_t].
@ numberOfSCTDeadSensors
number of dead SCT sensors crossed [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].
@ numberOfTRTHighThresholdHits
number of TRT hits which pass the high threshold (only xenon counted) [unit8_t].
@ numberOfPixelDeadSensors
number of dead pixel sensors crossed [unit8_t].