ATLAS Offline Software
Loading...
Searching...
No Matches
InDetConversionTrackSelectorTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
6#include "VxVertex/Vertex.h"
7#include "TrkTrack/Track.h"
9// normal includes
12#include "VxVertex/RecVertex.h"
14#include "xAODTracking/Vertex.h"
15#include <cmath>
16
17
18namespace InDet
19{
20
21 InDetConversionTrackSelectorTool::InDetConversionTrackSelectorTool(const std::string& t, const std::string& n, const IInterface* p)
22 :AthAlgTool(t,n,p)
23 {
24 declareInterface<ITrackSelectorTool>(this);
25 }
26
27
29 {
30 ATH_CHECK( m_extrapolator.retrieve() );
33
34 return StatusCode::SUCCESS;
35 }
36
38 {
41 if (evt.isValid()) {
42 InDet::BeamSpotData temp(evt->beamStatus(), evt->beamPosX(), evt->beamPosY(), evt->beamPosZ(),
43 evt->beamPosSigmaX(), evt->beamPosSigmaY(), evt->beamPosSigmaZ(),
44 evt->beamTiltXZ(), evt->beamTiltYZ(), evt->beamPosSigmaXY());
45 return new Trk::RecVertex(temp.beamVtx());
46 } else {
47 ATH_MSG_WARNING( " Cannot get beamSpot center from xAOD::EventInfo. Using (0,0,0)... " );
48 return new Trk::Vertex(Amg::Vector3D(0,0,0));
49 }
50 }else{
52 if (beamSpotHandle.isValid()) {
53 return new Trk::RecVertex(beamSpotHandle->beamVtx());
54 } else {
55 ATH_MSG_WARNING( " Cannot get beamSpot center from BeamSpotData. Using (0,0,0)... " );
56 return new Trk::Vertex(Amg::Vector3D(0,0,0));
57 }
58 }
59 }
60
61
63 {
64 // Find the correct bin for applying eta-dependent cuts
65
66 double tanThetaOver2 = std::tan( perigee.parameters()[Trk::theta] / 2.);
67 double abs_eta = (tanThetaOver2 == 0) ? 999.0 : std::fabs( std::log(tanThetaOver2) );
68
69 for (unsigned int i=0;i<m_TRTTrksEtaBins.size();++i) {
70 if (abs_eta < m_TRTTrksEtaBins[i]) {
71 return i;
72 }
73 }
74 return m_TRTTrksEtaBins.size()-1;
75 }
76
77
79 {
80 const EventContext& ctx = Gaudi::Hive::currentContext();
81 bool pass = false;
82 const Trk::Perigee* perigee=dynamic_cast<const Trk::Perigee*>(track.perigeeParameters());
83 const bool vertexSuppliedByUser{vx!=nullptr};
84 const Trk::Vertex* myVertex=vx;
85 //in case no Vertex is provided by the user, beam position will be used if available
86 if (not vertexSuppliedByUser) {
87 myVertex = getBeamSpot(ctx);
88 }
89 Trk::PerigeeSurface perigeeSurface(myVertex->position());
90 const Trk::TrackParameters *firstmeaspar=nullptr;
91 for (const auto *i : *track.trackParameters()){
92 if ( i->covariance() && !dynamic_cast<const Trk::Perigee*>(i)) {
93 firstmeaspar=i;
94 break;
95 }
96 }
97 if (!firstmeaspar) {
98 //assumes perigeeParameters exist...
99 //no track selection if firstmeas + perigee does not exist !
100 firstmeaspar=track.perigeeParameters();
101 if (!firstmeaspar){
102 ATH_MSG_WARNING( " First measurment on track is missing. Using perigee Parameters, but they are missing: 0 pointer! Track selection failed " );
103 //clean up vertex
104 if (not vertexSuppliedByUser) delete myVertex;
105 return false;
106 }
107 }
108
109 const Trk::TrackParameters* extrapolatedParameters =
110 m_extrapolator->extrapolate(ctx,
111 *firstmeaspar,
112 perigeeSurface,
114 true,
115 track.info().particleHypothesis()).release();
116 perigee = extrapolatedParameters
117 ? dynamic_cast<const Trk::Perigee*>(extrapolatedParameters)
118 : nullptr;
119 if (perigee==nullptr || !perigee->covariance() ) {
120 ATH_MSG_WARNING( "Track Selector failed to extrapolate track to the vertex: " << myVertex->position() );
121 if (extrapolatedParameters!=nullptr) {
122 ATH_MSG_WARNING( "The return object of the extrapolator was not a perigee even if a perigeeSurface was used!");
123 delete extrapolatedParameters;
124 if (not vertexSuppliedByUser) delete myVertex;
125 return false;
126 }
127 if (not vertexSuppliedByUser) delete myVertex;
128 return false;
129 }
130
131 double qOverP = perigee->parameters()[Trk::qOverP];
132 double pt = std::fabs(1./qOverP)*std::sin(perigee->parameters()[Trk::theta]);
133 double d0 = perigee->parameters()[Trk::d0];
134 double z0 = perigee->parameters()[Trk::z0];
135 const Trk::TrackSummary* tSum = track.trackSummary();
136 if(tSum){
137 double ratioTrk = 1.0;
138 int nclus = tSum->get(Trk::numberOfPixelHits) + tSum->get(Trk::numberOfSCTHits);
139 bool isSilicon = (nclus > 0);
140 int nTrtHits = tSum->get(Trk::numberOfTRTHits);
141 int nTrtOutliers = tSum->get(Trk::numberOfTRTOutliers);
142 int ntrt = nTrtHits + nTrtOutliers;
143 int nTrtXenonHits = tSum->get(Trk::numberOfTRTXenonHits);
144 if(m_isConv) {
145 if(ntrt > 0 && (!m_PIDonlyForXe || nTrtXenonHits==ntrt) ){
146 // only check TRT PID if m_PIDonlyForXe is false or all TRT hits are Xenon hits
147 ATH_MSG_FATAL( "eProbabilityHT not available for Trk::Tracks only xAOD::TrackParticle objects" );
148 }
149
150 // Start of track cuts
151 if ( pt >= m_minPt ) {
152
153 // Silicon track cuts
154 if ( isSilicon && (std::fabs(d0)<=m_maxSiD0) && (fabs(z0)<=m_maxSiZ0) ) {
155 if((ntrt<=15 && ratioTrk>=m_trRatio1) ||
156 (ntrt>15 && ntrt<=25 && ratioTrk>=m_trRatio2) ||
157 (ntrt>25 && ratioTrk>=m_trRatio3)) pass = true;
158 }
159
160 // TRT-only track cuts
161 if ( (not isSilicon) && (std::fabs(d0)<=m_maxTrtD0) && (std::fabs(z0)<=m_maxTrtZ0) ) {
162
163 unsigned int eta_bin = getEtaBin(*perigee);
164 // TRT-only Tracks: eProbabilityHT cut below
165 // See InDet Trt Track Scoring Tool for nTRT cut on TRT-only tracks
166 double trRatioTRT = std::max( m_trRatioTRT.value(), m_TRTTrksBinnedRatioTRT[eta_bin] );
167
168 if ( ratioTrk >= trRatioTRT ) pass = true; // TRT Track cuts
169 }
170 } // end of track cuts for isConv
171
172 } else {
173 //The cuts below are necessary for the V0 track selection
174 const AmgSymMatrix(5)& err = *perigee->covariance();
175 double sd0sq = err(0,0);
176 double sd0 = (sd0sq>0.)?std::sqrt(sd0sq):0.;
177 double sz0sq = err(1,1);
178 double sz0 = (sz0sq>0.)?std::sqrt(sz0sq):0.;
179 if(nclus == 0){
180 if(std::fabs(d0)>=m_sD0_Trt*sd0 && std::fabs(d0)<=m_maxTrtD0 && std::fabs(z0)<=m_sZ0_Trt*sz0 && pt>=m_minPt) pass = true;
181 }else{
182 if(std::fabs(d0)>=m_sD0_Si*sd0 && std::fabs(z0)<=m_maxSiZ0 && pt>=m_minPt) pass = true;
183 }
184 ratioTrk = 1.0;
185 if(ntrt > 0 && (!m_PIDonlyForXe || nTrtXenonHits==ntrt) ) { // only check TRT PID if m_PIDonlyForXe is false or all TRT hits are Xenon hits
186 ATH_MSG_FATAL( "eProbabilityHT not available for Trk::Tracks only xAOD::TrackParticle objects" );
187 }
188 if(ratioTrk>m_trRatioV0) pass = false;
189 }
190
191 } else pass = false;
192 if (not vertexSuppliedByUser) delete myVertex;
193 if (perigee!=track.perigeeParameters()) delete perigee;
194 return pass;
195 }
196
198 {
199 const EventContext& ctx = Gaudi::Hive::currentContext();
200 bool pass = false;
201 const Trk::TrackParameters* definintParameters=&(track.definingParameters());
202 const Trk::Perigee* perigee=dynamic_cast<const Trk::Perigee*>(definintParameters);
203 const Trk::Vertex* myVertex=vx;
204 const bool vertexSuppliedByUser{vx!=nullptr};
205 //in case no Vertex is provided by the user, beam position will be used if available
206 if (not vertexSuppliedByUser) {
207 myVertex = getBeamSpot(ctx);
208 }
209
210 Trk::PerigeeSurface perigeeSurface(myVertex->position());
211 const Trk::TrackParameters *firstmeaspar=nullptr;
212 for (const auto *i : track.trackParameters()){
213 if ( i->covariance() && !dynamic_cast<const Trk::Perigee*>(i)) {
214 firstmeaspar=i;
215 break;
216 }
217 }
218 if (!firstmeaspar) {
219 //using perigee instead of firstmeasurement, since first measurement was not found...
220 firstmeaspar=&(track.definingParameters());
221 if (!firstmeaspar){
222 ATH_MSG_WARNING( " Track Paraemters at first measurement not found. Perigee not found. Cannot do TrackSelection..." );
223 if (not vertexSuppliedByUser) delete myVertex;
224 return false;
225 }
226 }
227 const Trk::TrackParameters* extrapolatedParameters =
228 m_extrapolator->extrapolate(
229 ctx, *firstmeaspar, perigeeSurface, Trk::anyDirection, true, Trk::pion).release();
230 perigee = extrapolatedParameters
231 ? dynamic_cast<const Trk::Perigee*>(extrapolatedParameters)
232 : nullptr;
233 if (perigee == nullptr || !perigee->covariance()) {
234 ATH_MSG_WARNING( "Track Selector failed to extrapolate track to the vertex: " << myVertex->position() );
235 if (extrapolatedParameters!=nullptr) {
236 ATH_MSG_WARNING( "The return object of the extrapolator was not a perigee even if a perigeeSurface was used!" );
237 delete extrapolatedParameters;
238 if (not vertexSuppliedByUser) delete myVertex;
239 return false;
240 }
241 if (not vertexSuppliedByUser) delete myVertex;
242 return false;
243 }
244
245 double qOverP = perigee->parameters()[Trk::qOverP];
246 double pt = std::fabs(1./qOverP)*std::sin(perigee->parameters()[Trk::theta]);
247 double d0 = perigee->parameters()[Trk::d0];
248 double z0 = perigee->parameters()[Trk::z0];
249 const Trk::TrackSummary* tSum = track.trackSummary();
250 if(tSum){
251 double ratioTrk = 1.0;
252 int nclus = tSum->get(Trk::numberOfPixelHits) + tSum->get(Trk::numberOfSCTHits);
253 bool isSilicon = (nclus > 0);
254 int nTrtHits = tSum->get(Trk::numberOfTRTHits);
255 int nTrtOutliers = tSum->get(Trk::numberOfTRTOutliers);
256 int ntrt = nTrtHits + nTrtOutliers;
257 int nTrtXenonHits = tSum->get(Trk::numberOfTRTXenonHits);
258
259 if(m_isConv){
260 if(ntrt > 0 && (!m_PIDonlyForXe || nTrtXenonHits==ntrt) ){
261 // only check TRT PID if m_PIDonlyForXe is false or all TRT hits are Xenon hits
262 ATH_MSG_FATAL( "eProbabilityHT not available for Trk::TrackParticleBase only xAOD::TrackParticle objects" );
263 }
264
265 // Start of track cuts
266 if ( pt >= m_minPt ) {
267
268 // Silicon track cuts
269 if ( isSilicon && (std::fabs(d0)<=m_maxSiD0) && (fabs(z0)<=m_maxSiZ0) ) {
270 if((ntrt<=15 && ratioTrk>=m_trRatio1) ||
271 (ntrt>15 && ntrt<=25 && ratioTrk>=m_trRatio2) ||
272 (ntrt>25 && ratioTrk>=m_trRatio3)) pass = true;
273 }
274
275 // TRT-only track cuts
276 if ( (not isSilicon) && (std::fabs(d0)<=m_maxTrtD0) && (std::fabs(z0)<=m_maxTrtZ0) ) {
277
278 unsigned int eta_bin = getEtaBin(*perigee);
279 // TRT-only Tracks: eProbabilityHT cuts below
280 // See InDet Trt Track Scoring Tool for nTRT cut on TRT-only tracks
281 double trRatioTRT = std::max( m_trRatioTRT.value(), m_TRTTrksBinnedRatioTRT[eta_bin] );
282
283 if ( ratioTrk >= trRatioTRT ) pass = true; // TRT Track cuts
284 }
285 } // end of track cuts for isConv
286
287 } else {
288 //The cuts below are necessary for the V0 track selection
289 const AmgSymMatrix(5)& err = *perigee->covariance();
290 double sd0sq = err(0,0);
291 double sd0 = (sd0sq>0.)?std::sqrt(sd0sq):0.;
292 double sz0sq = err(1,1);
293 double sz0 = (sz0sq>0.)?std::sqrt(sz0sq):0.;
294 if(nclus == 0){
295 if(std::fabs(d0)>=m_sD0_Trt*sd0 && std::fabs(d0)<= m_maxTrtD0 && std::fabs(z0)<=m_sZ0_Trt*sz0 && pt>=m_minPt) pass = true;
296 }else{
297 if(std::fabs(d0)>=m_sD0_Si*sd0 && std::fabs(z0)<=m_maxSiZ0 && pt>=m_minPt) pass = true;
298 }
299
300 ratioTrk = 1.0;
301 if(ntrt > 0 && (!m_PIDonlyForXe || nTrtXenonHits==ntrt) ) {// only check TRT PID if m_PIDonlyForXe is false or all TRT hits are Xenon hits
302 ATH_MSG_FATAL( "eProbabilityHT not available for Trk::TrackParticleBase only xAOD::TrackParticle objects" );
303 }
304 if(ratioTrk>m_trRatioV0) pass = false;
305 }
306 } else pass = false;
307 if (not vertexSuppliedByUser) delete myVertex;
308 if (perigee!=&(track.definingParameters())) delete perigee;
309
310 return pass;
311 }
312
315 const EventContext& ctx,
316 const xAOD::Vertex* vertex) const
317 {
318 if (vertex) {
319 return vertex->position();
320 }
323 if (evt.isValid()) {
324 return Amg::Vector3D(evt->beamPosX(), evt->beamPosY(), evt->beamPosZ());
325 }else{
326 return Amg::Vector3D(0, 0, 0);
327 }
328 }
330 if (beamSpotHandle.isValid()) {
331 return beamSpotHandle->beamVtx().position();
332 } else {
333 return Amg::Vector3D(0, 0, 0);
334 }
335 }
336
337 // ---------------------------------------------------------------------
339 {
340 const EventContext& ctx = Gaudi::Hive::currentContext();
341 bool pass = false;
342 const Trk::Perigee& perigee=tp.perigeeParameters();
343 // in case no Vertex is provided by the user, beam position will be used if
344 // available
345 Trk::PerigeeSurface perigeeSurface(getPosOrBeamSpot(ctx, vertex));
346 const Trk::TrackParameters* extrapolatedParameters =
347 m_extrapolator->extrapolate(
348 ctx, perigee, perigeeSurface, Trk::anyDirection, false, Trk::pion).release();
349 if (extrapolatedParameters == nullptr) {
350 ATH_MSG_WARNING("Extrapolation to the vertex failed: " << perigeeSurface
351 << "\n"
352 << perigee);
353 return false;
354 }
355 double qOverP = perigee.parameters()[Trk::qOverP];
356 double pt = std::fabs(1./qOverP)*std::sin(perigee.parameters()[Trk::theta]);
357 double d0 = extrapolatedParameters->parameters()[Trk::d0];
358 double z0 = extrapolatedParameters->parameters()[Trk::z0];
359
360 double ratioTrk = 1.0;
362 bool isSilicon = (nclus > 0);
363 int nTrtHits = getCount(tp,xAOD::numberOfTRTHits);
364 int nTrtOutliers = getCount(tp,xAOD::numberOfTRTOutliers);
365 int ntrt = nTrtHits + nTrtOutliers;
366 int nTrtXenonHits = getCount(tp,xAOD::numberOfTRTXenonHits);
367
368 if(m_isConv){
369 float temp(0);
370 if(ntrt > 0 && (!m_PIDonlyForXe || nTrtXenonHits==ntrt) ){
371 // only check TRT PID if m_PIDonlyForXe is false or all TRT hits are Xenon hits
372 ratioTrk = tp.summaryValue(temp,xAOD::eProbabilityHT) ? temp: 0 ;
373 }
374
375 // Start of track cuts
376 if ( pt >= m_minPt ) {
377
378 // Silicon track cuts
379 if ( isSilicon && (std::fabs(d0)<=m_maxSiD0) && (fabs(z0)<=m_maxSiZ0) ) {
380 if((ntrt<=15 && ratioTrk>=m_trRatio1) ||
381 (ntrt>15 && ntrt<=25 && ratioTrk>=m_trRatio2) ||
382 (ntrt>25 && ratioTrk>=m_trRatio3)) pass = true;
383 }
384
385 // TRT-only track cuts
386 if ( (not isSilicon) && (std::fabs(d0)<=m_maxTrtD0) && (std::fabs(z0)<=m_maxTrtZ0) ) {
387
388 unsigned int eta_bin = getEtaBin(perigee);
389 // TRT-only Tracks: eProbabilityHT cuts below
390 // See InDet Trt Track Scoring Tool for nTRT cut on TRT-only tracks
391 double trRatioTRT = std::max( m_trRatioTRT.value(), m_TRTTrksBinnedRatioTRT[eta_bin] );
392
393 if ( ratioTrk >= trRatioTRT ) pass = true; // TRT Track cuts
394 }
395 } // end of track cuts for isConv
396
397 } else {
398 //The cuts below are necessary for the V0 track selection
399 const AmgSymMatrix(5)& err = *perigee.covariance();
400 double sd0sq = err(0,0);
401 double sd0 = (sd0sq>0.)?std::sqrt(sd0sq):0.;
402 double sz0sq = err(1,1);
403 double sz0 = (sz0sq>0.)?std::sqrt(sz0sq):0.;
404 if(nclus == 0){
405 if(std::fabs(d0)>=m_sD0_Trt*sd0 && std::fabs(d0)<= m_maxTrtD0 && std::fabs(z0)<=m_sZ0_Trt*sz0 && pt>=m_minPt) pass = true;
406 }else{
407 if(std::fabs(d0)>=m_sD0_Si*sd0 && std::fabs(z0)<=m_maxSiZ0 && pt>=m_minPt) pass = true;
408 }
409 ratioTrk = 1.0;
410 float temp(0);
411 if(ntrt > 0 && (!m_PIDonlyForXe || nTrtXenonHits==ntrt) ) // only check TRT PID if m_PIDonlyForXe is false or all TRT hits are Xenon hits
412 ratioTrk = tp.summaryValue(temp,xAOD::eProbabilityHT) ? temp: 0 ;
413 if(ratioTrk>m_trRatioV0) pass = false;
414 }
415
416
417 delete extrapolatedParameters;
418 return pass;
419 }
420}//end of namespace definitions
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_WARNING(x)
#define AmgSymMatrix(dim)
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
int getCount(const xAOD::TrackParticle &tp, xAOD::SummaryType type) const
unsigned int getEtaBin(const Trk::Perigee &perigee) const
Amg::Vector3D getPosOrBeamSpot(const EventContext &ctx, const xAOD::Vertex *) const
DoubleProperty m_maxSiD0
Properties for track selection:all cuts are ANDed.
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfo_key
SG::ReadCondHandleKey< InDet::BeamSpotData > m_beamSpotKey
InDetConversionTrackSelectorTool(const std::string &t, const std::string &n, const IInterface *p)
Trk::Vertex * getBeamSpot(const EventContext &ctx) const
virtual bool decision(const Trk::Track &track, const Trk::Vertex *vertex) const override final
Select a Trk::Track.
Class describing the Line to which the Perigee refers to.
Trk::RecVertex inherits from Trk::Vertex.
Definition RecVertex.h:44
A summary of the information contained by a track.
int get(const SummaryType &type) const
returns the summary information for the passed SummaryType.
This class is a simplest representation of a vertex candidate.
const Amg::Vector3D & position() const
return position of vertex
Definition Vertex.cxx:63
Eigen::Matrix< double, 3, 1 > Vector3D
Primary Vertex Finder.
@ anyDirection
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
@ theta
Definition ParamDefs.h:66
@ qOverP
perigee
Definition ParamDefs.h:67
@ d0
Definition ParamDefs.h:63
@ z0
Definition ParamDefs.h:64
ParametersBase< TrackParametersDim, Charged > TrackParameters
@ numberOfPixelHits
number of pixel layers on track with absence of hits
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Vertex_v1 Vertex
Define the latest version of the vertex class.
@ numberOfTRTXenonHits
number of TRT hits on track in straws with xenon [unit8_t].
@ numberOfTRTHits
number of TRT hits [unit8_t].
@ eProbabilityHT
Electron probability from High Threshold (HT) information [float].
@ numberOfSCTHits
number of hits in SCT [unit8_t].
@ numberOfPixelHits
these are the pixel hits, including the b-layer [unit8_t].
@ numberOfTRTOutliers
number of TRT outliers [unit8_t].