ATLAS Offline Software
Loading...
Searching...
No Matches
InDetAmbiScoringTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6// Markus Elsing
8
10#include "TrkTrack/Track.h"
14#include "CLHEP/GenericFunctions/CumulativeChiSquare.hh"
18
19
20//---------------------------------------------------------------------------------------------------------------------
21
23 const std::string& n,
24 const IInterface* p ) :
25 AthAlgTool(t,n,p),
26 m_summaryTypeScore(Trk::numberOfTrackSummaryTypes)
27{
28 declareInterface<Trk::ITrackScoringTool>(this);
29
30 //set values for scores
32 m_summaryTypeScore[Trk::numberOfPixelHoles] = -10; // a hole is bad
33 m_summaryTypeScore[Trk::numberOfInnermostPixelLayerHits] = 10; // addition for being b-layer
34 m_summaryTypeScore[Trk::numberOfGangedPixels] = -5; // decrease for being ganged
35 m_summaryTypeScore[Trk::numberOfGangedFlaggedFakes] = -10; // decrease for being ganged fake
36 m_summaryTypeScore[Trk::numberOfSCTHits] = 10; // half of a pixel, since only 1dim
37 m_summaryTypeScore[Trk::numberOfSCTHoles] = -5; // a hole is bad !
38 m_summaryTypeScore[Trk::numberOfSCTDoubleHoles] = -15; // a double hole is even worse !
39 m_summaryTypeScore[Trk::numberOfTRTHits] = 1; // 10 straws ~ 1 SCT
40 m_summaryTypeScore[Trk::numberOfTRTHighThresholdHits] = 0; // addition for being TR
41 m_summaryTypeScore[Trk::numberOfOutliersOnTrack] = -1; // -ME- TRT oulier should not kill 5 TRT on track (was -5)
42
43 // scoring for Muons not needed
51
52}
53
54//---------------------------------------------------------------------------------------------------------------------
55
57{
58 StatusCode sc = AlgTool::initialize();
59 if (sc.isFailure()) return sc;
60
61 sc = m_extrapolator.retrieve();
62 if (sc.isFailure()) {
63 msg(MSG::FATAL) << "Failed to retrieve tool " << m_extrapolator << endmsg;
64 return StatusCode::FAILURE;
65 } else
66 msg(MSG::DEBUG) << "Retrieved tool " << m_extrapolator << endmsg;
67
68 // Get segment selector tool
69 //
70 ATH_CHECK(m_selectortool.retrieve( DisableTool{m_selectortool.empty()} ) );
71
72 ATH_CHECK(m_beamSpotKey.initialize());
73
75 msg(MSG::FATAL) << "Both on, normal ambi funciton and the one for back tracking, configuration problem, not recoverable" << endmsg;
76 return StatusCode::FAILURE;
77 }
78
79 // Read handle for AtlasFieldCacheCondObj
81
82 if (not m_etaDependentCutsSvc.name().empty()) ATH_CHECK(m_etaDependentCutsSvc.retrieve());
83
85
87
88 return StatusCode::SUCCESS;
89}
90
91//---------------------------------------------------------------------------------------------------------------------
93{
94 //
95 // --- kinematic selection (done as well on input ?)
96 //
97 // --- beam spot position
98 Amg::Vector3D beamSpotPosition(0,0,0);
100 if (beamSpotHandle.isValid()) beamSpotPosition = beamSpotHandle->beamVtx().position();
101 // --- create surface
102 Trk::PerigeeSurface perigeeSurface(beamSpotPosition);
103
104 const Trk::TrackParameters* input = track.trackParameters()->front();
105 double trackEta = input->eta();
106
107 // cuts on parameters
108 const EventContext& ctx = Gaudi::Hive::currentContext();
110 const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
111 if (fieldCondObj == nullptr) {
112 ATH_MSG_ERROR("simpleScore: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCacheCondObjInputKey.key());
113 return false;
114 }
115 MagField::AtlasFieldCache fieldCache;
116 fieldCondObj->getInitializedCache (fieldCache);
117
118 if (fieldCache.solenoidOn()){
119 double minPt = m_etaDependentCutsSvc.name().empty() ?
120 m_minPt.value() : m_etaDependentCutsSvc->getMinPtAtEta(trackEta);
121 if (std::abs(input->pT()) < minPt) {
122 ATH_MSG_DEBUG ("Track pt < "<<m_minPt<<", reject it");
123 return false;
124 }
125 }
126 double maxEta = m_etaDependentCutsSvc.name().empty() ?
127 m_maxEta.value() : m_etaDependentCutsSvc->getMaxEta();
128 if (std::abs(input->eta()) > maxEta) {
129 ATH_MSG_DEBUG ("Track eta > "<<maxEta<<", reject it");
130 return false;
131 }
132
133 // uses perigee on track or extrapolates, no material in any case, we cut on impacts
134 // add back extrapolation without errors
135 std::unique_ptr<const Trk::TrackParameters> parm( m_extrapolator->extrapolateDirectly(ctx,*input, perigeeSurface) );
136
137 if (!parm || parm->surfaceType()!=Trk::SurfaceType::Perigee) {
138 ATH_MSG_WARNING( "Extrapolation of perigee failed, this should never happen" );
139 return false;
140 }
141
142 ATH_MSG_VERBOSE ("extrapolated perigee: "<<*parm);
143 double maxZ0 = m_etaDependentCutsSvc.name().empty() ?
144 m_maxZImp.value() : m_etaDependentCutsSvc->getMaxZImpactAtEta(trackEta);
145 if (std::abs(parm->parameters()[Trk::z0]) > maxZ0) {
146 ATH_MSG_DEBUG ("Track Z impact > "<<maxZ0<<", reject it");
147 return false;
148 }
149
150 double maxD0 = m_etaDependentCutsSvc.name().empty() ?
151 m_maxRPhiImp.value() : m_etaDependentCutsSvc->getMaxPrimaryImpactAtEta(trackEta);
152 if(m_useEmClusSeed) {
153 if (isEmCaloCompatible( track, ctx ) ) {
154 maxD0 = m_maxRPhiImpEM;
155 }
156 }
157 if (std::abs(parm->parameters()[Trk::d0]) > maxD0) {
158 ATH_MSG_DEBUG ("Track Rphi impact > "<<maxD0<<", reject it");
159 return false;
160 }
161
162 return true;
163}
164
165
166//---------------------------------------------------------------------------------------------------------------------
167
168Trk::TrackScore InDet::InDetAmbiScoringTool::score( const Trk::Track& track, bool checkBasicSel ) const
169{
170 if(checkBasicSel && !passBasicSelections(track)){
171 ATH_MSG_VERBOSE ("Track fail basic selections");
172 return Trk::TrackScore(0);
173 }
174 if (!track.trackSummary()) {
175 ATH_MSG_FATAL("Track without a summary");
176 }
177 ATH_MSG_VERBOSE ("Track has TrackSummary "<<*track.trackSummary());
178 Trk::TrackScore score = Trk::TrackScore( simpleScore(track, *track.trackSummary()) );
179
180 ATH_MSG_DEBUG ("Track has Score: "<<score);
181
182 return score;
183}
184
185//---------------------------------------------------------------------------------------------------------------------
186
188{
189 int numPixel = trackSummary.get(Trk::numberOfPixelHits);
190 int numSCT = trackSummary.get(Trk::numberOfSCTHits);
191 int numTRT = trackSummary.get(Trk::numberOfTRTHits);
192 int numTRTTube = trackSummary.get(Trk::numberOfTRTTubeHits);
193 int numPixelHoles = trackSummary.get(Trk::numberOfPixelHoles);
194 int numSCTHoles = trackSummary.get(Trk::numberOfSCTHoles);
195 int numSCTDoubleHoles = trackSummary.get(Trk::numberOfSCTDoubleHoles);
196 int numPixelDead = trackSummary.get(Trk::numberOfPixelDeadSensors);
197 int numSCTDead = trackSummary.get(Trk::numberOfSCTDeadSensors);
198
199 if (numPixelDead<0) numPixelDead = 0;
200 if (numSCTDead<0) numSCTDead = 0;
201
202 // is this a track from the pattern or a fitted track ?
203 bool ispatterntrack = (track.info().trackFitter()==Trk::TrackInfo::Unknown);
204 //
205 // --- reject bad tracks
206 //
207 //
208 // --- the following cuts we only apply to fitted tracks
209 //
210 if (ispatterntrack) {
211 ATH_MSG_DEBUG ("==> this is a pattern track, no hit cuts !");
212 } else {
213 ATH_MSG_DEBUG ("==> this is a refitted track, so we can use the chi2 and other stuff ! ");
214
215 double trackEta = track.trackParameters()->front()->eta();
216
217 // NdF cut :
218 if (track.fitQuality()) {
219 ATH_MSG_DEBUG ("numberDoF = "<<track.fitQuality()->numberDoF());
220 }
221 // Number of double Holes
222 if (numSCTDoubleHoles>=0) {
223 int maxDoubleHoles = m_etaDependentCutsSvc.name().empty() ?
224 m_maxDoubleHoles.value() : m_etaDependentCutsSvc->getMaxDoubleHolesAtEta(trackEta);
225 if (numSCTDoubleHoles > maxDoubleHoles ) {
226 ATH_MSG_DEBUG ("Track has "<< numSCTDoubleHoles <<" double holes, reject it!");
227 return Trk::TrackScore(0);
228 }
229 }
230 // Number of Si (Pixel+SCT) Holes
231 if (numSCTHoles>=0 && numPixelHoles>=0) {
232 int maxSiHoles = m_etaDependentCutsSvc.name().empty() ?
233 m_maxSiHoles.value() : m_etaDependentCutsSvc->getMaxSiHolesAtEta(trackEta);
234 if (numPixelHoles+numSCTHoles > maxSiHoles ) {
235 ATH_MSG_DEBUG ("Track has "<< numPixelHoles <<" Pixel and " << numSCTHoles << " SCT holes, reject it!");
236 return Trk::TrackScore(0);
237 }
238 }
239 // Number of Pixel Holes
240 if ( numPixelHoles>=0 ) {
241 int maxPixelHoles = m_etaDependentCutsSvc.name().empty() ?
242 m_maxPixelHoles.value() : m_etaDependentCutsSvc->getMaxPixelHolesAtEta(trackEta);
243 if (numPixelHoles > maxPixelHoles ) {
244 ATH_MSG_DEBUG ("Track has "<< numPixelHoles <<" Pixel holes, reject it!");
245 return Trk::TrackScore(0);
246 }
247 }
248 // Number of SCT Holes
249 if ( numSCTHoles>=0 ) {
250 int maxSctHoles = m_etaDependentCutsSvc.name().empty() ?
251 m_maxSctHoles.value() : m_etaDependentCutsSvc->getMaxSctHolesAtEta(trackEta);
252 if ( numSCTHoles > maxSctHoles ) {
253 ATH_MSG_DEBUG ("Track has "<< numSCTHoles << " SCT holes, reject it!");
254 return Trk::TrackScore(0);
255 }
256 }
257 // TRT cut
258 if (!m_useITkAmbigFcn && numTRT > 0 && numTRT < m_minTRTonTrk) {
259 ATH_MSG_DEBUG ("Track has " << numTRT << " TRT hits, reject it");
260 return Trk::TrackScore(0);
261 }
262 // TRT precision hits cut
263 if (!m_useITkAmbigFcn && numTRT >= 15 && ((double)(numTRT-numTRTTube))/numTRT < m_minTRTprecision) {
264 ATH_MSG_DEBUG ("Track has " << ((double)numTRTTube)/numTRT << " TRT tube hit fraction, reject it");
265 return Trk::TrackScore(0);
266 }
267 // Number of Si Clusters
268 if ( numSCT>=0 && numPixel>=0) {
269 int minSiClusters = m_etaDependentCutsSvc.name().empty() ?
270 m_minSiClusters.value() : m_etaDependentCutsSvc->getMinSiHitsAtEta(trackEta);
271 if (numPixel+numSCT+numPixelDead+numSCTDead < minSiClusters) {
272 ATH_MSG_DEBUG ("Track has " << numPixel+numSCT << " Si clusters and " << numPixelDead+numSCTDead << " dead sensors, reject it");
273 return Trk::TrackScore(0);
274 }
275 }
276 // Number of pixel clusters
277 if (numPixel>=0) {
278 int minPixel = m_etaDependentCutsSvc.name().empty() ?
279 m_minPixel.value() : m_etaDependentCutsSvc->getMinPixelHitsAtEta(trackEta);
280 if(numPixel < minPixel) {
281 ATH_MSG_DEBUG ("Track has " << numPixel << " pixel hits, reject it");
282 return Trk::TrackScore(0);
283 }
284 }
285 }
286
287 //
288 // --- now start scoring
289 //
290
292
293 //
294 // --- use scoring function
295 //
296
297 return ambigScore(track,trackSummary);
298
299 } else {
300
301 //
302 // use classical score
303 //
304 // score of 100 per track
306 // --- summary score analysis
307 for (int i=0; i<Trk::numberOfTrackSummaryTypes; ++i) {
308 int value = trackSummary.get(static_cast<Trk::SummaryType>(i));
309 //value is -1 if undefined.
310 if (value>0) {
311 score+=m_summaryTypeScore[i]*value;
312 ATH_MSG_DEBUG ("\tType ["<<i<<"], value \t= "<<value<<"], score \t="<<score);
313 }
314 }
315 // --- prob(chi2,NDF), protect for chi2 <= 0
316 if (track.fitQuality()!=nullptr && track.fitQuality()->chiSquared()>0 && track.fitQuality()->numberDoF()>0 ) {
317 double p = 1.0-Genfun::CumulativeChiSquare(track.fitQuality()->numberDoF())(track.fitQuality()->chiSquared());
318 if ( p > 0 )
319 score += log10( p );
320 else
321 score -= 50;
322 }
323
324 return score;
325 }
326
327}
328
329//---------------------------------------------------------------------------------------------------------------------
330
332{
333 //
334 // --- start with bonus for high pt tracks
335 //
336 // double prob = 1.;
337 double pt = std::abs(track.trackParameters()->front()->pT());
338 double prob = log10( pt ) - 1.; // 100 MeV is min and gets score 1
339 ATH_MSG_DEBUG ("Modifier for pt = " << pt / 1000. << " GeV is: "<< prob);
340
341 //
342 // --- prob and cuts on holes
343 //
344 if (m_usePixel) {
345 // --- Pixel holes
346 int iPixHoles = trackSummary.get(Trk::numberOfPixelHoles);
347 if ( iPixHoles > -1 && m_maxPixHoles > 0) {
348 if (iPixHoles > m_maxPixHoles) {
349 prob /= (iPixHoles - m_maxPixHoles + 1); // holes are bad !
350 iPixHoles = m_maxPixHoles;
351 }
352 prob *= m_factorPixHoles[iPixHoles];
353 ATH_MSG_DEBUG ("Modifier for " << iPixHoles << " Pixel holes: "<<m_factorPixHoles[iPixHoles]
354 << " New score now: " << prob);
355 }
356 }
357
358 if (m_useSCT) {
359 // --- SCT holes
360 int iSCT_Holes = trackSummary.get(Trk::numberOfSCTHoles);
361 if (iSCT_Holes > -1 && m_maxSCT_Holes > 0) {
362 if (iSCT_Holes > m_maxSCT_Holes) {
363 prob /= (iSCT_Holes - m_maxSCT_Holes + 1); // holes are bad !
364 iSCT_Holes = m_maxSCT_Holes;
365 }
366 prob *= m_factorSCT_Holes[iSCT_Holes];
367 ATH_MSG_DEBUG ("Modifier for " << iSCT_Holes << " SCT holes: "<<m_factorSCT_Holes[iSCT_Holes]
368 << " New score now: " << prob);
369 }
370 // --- SCT double holes
371 int iDblHoles = trackSummary.get(Trk::numberOfSCTDoubleHoles);
372 if (iDblHoles > -1 && m_maxDblHoles > 0) {
373 if (iDblHoles > m_maxDblHoles) {
374 prob /= (iDblHoles - m_maxDblHoles + 1); // holes are bad !
375 iDblHoles = m_maxDblHoles;
376 }
377 prob *= m_factorDblHoles[iDblHoles];
378 ATH_MSG_DEBUG ("Modifier for " << iDblHoles << " double holes: "<<m_factorDblHoles[iDblHoles]
379 << " New score now: " << prob);
380 }
381 }
382 //
383 // --- prob for other counters
384 //
385 if (m_usePixel) {
386
387 // ME: this if statement needs to be removed...
388 // --- count layers only if holes are not searched for
389 // if (trackSummary.get(Trk::numberOfPixelHoles) == -1) {
390
391 // --- Pixel layers
392 int iPixLay = trackSummary.get(Trk::numberOfContribPixelLayers);
393 if (iPixLay > -1 && m_maxPixLay > 0) {
394 if (iPixLay > m_maxPixLay) {
395 prob *= (iPixLay - m_maxPixLay + 1); // layers are good !
396 iPixLay = m_maxPixLay;
397 }
398 prob *= m_factorPixLay[iPixLay];
399 ATH_MSG_DEBUG ("Modifier for " << iPixLay << " Pixel layers: "<<m_factorPixLay[iPixLay]
400 << " New score now: " << prob);
401 }
402
403 // --- Pixel hits
404 int pixelHits = trackSummary.get(Trk::numberOfPixelHits);
405 if (pixelHits > -1 && m_maxPixelHits > 0) {
406 if (pixelHits > m_maxPixelHits) {
407 prob *= (pixelHits - m_maxPixelHits + 1); // hits are good !
408 pixelHits = m_maxPixelHits;
409 }
410 prob *= m_factorPixelHits[pixelHits];
411 ATH_MSG_DEBUG ("Modifier for " << pixelHits << " Pixel hits: "<<m_factorPixelHits[pixelHits]
412 << " New score now: " << prob);
413 }
414 // --- Pixel blayer hits
415 int bLayerHits = trackSummary.get(Trk::numberOfInnermostPixelLayerHits);
416 if (bLayerHits > -1 && m_maxB_LayerHits > 0) {
417 if (bLayerHits > m_maxB_LayerHits) {
418 prob *= (bLayerHits - m_maxB_LayerHits + 1); // hits are good !
419 bLayerHits = m_maxB_LayerHits;
420 }
421 prob *= m_factorB_LayerHits[bLayerHits];
422 ATH_MSG_DEBUG ("Modifier for " << bLayerHits << " b-layer hits: "<<m_factorB_LayerHits[bLayerHits]
423 << " New score now: " << prob);
424 }
425 // --- Pixel Ganged fakes
426 int pixelGangedFakes = trackSummary.get(Trk::numberOfGangedFlaggedFakes);
427 if (pixelGangedFakes > -1 && m_maxGangedFakes > 0) {
428 if (pixelGangedFakes > m_maxGangedFakes) {
429 prob /= (pixelGangedFakes - m_maxGangedFakes + 1); // ganged are bad !
430 pixelGangedFakes = m_maxGangedFakes;
431 }
432 prob *= m_factorGangedFakes[pixelGangedFakes];
433 ATH_MSG_DEBUG ("Modifier for " << pixelGangedFakes << " ganged fakes hits: "<<m_factorGangedFakes[pixelGangedFakes]
434 << " New score now: " << prob);
435 }
436 }
437
438 int iHits = 0;
439 iHits += m_usePixel ? trackSummary.get(Trk::numberOfPixelHits) : 3; // if Pixel off, do not count as inefficient
440 iHits += m_useSCT ? trackSummary.get(Trk::numberOfSCTHits) : 8; // if SCT off, do not count as inefficient
441 if (iHits > -1 && m_maxHits > 0) {
442 if (iHits > m_maxHits) {
443 prob *= (iHits - m_maxHits + 1); // hits are good !
444 iHits = m_maxHits;
445 }
446 prob *= m_factorHits[iHits];
447 ATH_MSG_DEBUG ("Modifier for " << iHits << " Sihits: "<<m_factorHits[iHits]
448 << " New score now: " << prob);
449 }
450
451 //
452 // --- special treatment for TRT hits
453 //
454 if (!m_useITkAmbigFcn) {
455 int iTRT_Hits = trackSummary.get(Trk::numberOfTRTHits);
456 int iTRT_Outliers = trackSummary.get(Trk::numberOfTRTOutliers);
457 //
458 if ( iTRT_Hits > 0 && m_maxTrtRatio > 0) {
459 // get expected number of TRT hits
460 double nTrtExpected = 30.;
461 assert( m_selectortool.isEnabled() );
462 nTrtExpected = m_selectortool->minNumberDCs(track.trackParameters()->front());
463 ATH_MSG_DEBUG ("Expected number of TRT hits: " << nTrtExpected << " for eta: "
464 << std::abs(track.trackParameters()->front()->eta()));
465 double ratio = (nTrtExpected != 0) ? iTRT_Hits / nTrtExpected : 0;
467 for (int i=0; i<m_maxTrtRatio; ++i) {
468 if ( m_boundsTrtRatio[i] < ratio && ratio <= m_boundsTrtRatio[i+1]) {
469 prob*= m_factorTrtRatio[i];
470 ATH_MSG_DEBUG ("Modifier for " << iTRT_Hits << " TRT hits (ratio " << ratio
471 << ") is : "<< m_factorTrtRatio[i] << " New score now: " << prob);
472 break;
473 }
474 }
475 }
476 //
477 if ( iTRT_Hits > 0 && iTRT_Outliers >= 0 && m_maxTrtFittedRatio > 0) {
478 double fitted = double(iTRT_Hits) / double(iTRT_Hits + iTRT_Outliers);
480 for (int i=0; i<m_maxTrtFittedRatio; ++i) {
481 if (fitted <= m_boundsTrtFittedRatio[i+1]) {
482 prob*= m_factorTrtFittedRatio[i];
483 ATH_MSG_DEBUG ("Modifier for TRT fitted ratio of " << fitted
484 << " is : "<< m_factorTrtFittedRatio[i] << " New score now: " << prob);
485 break;
486 }
487 }
488 }
489 } // end if(!m_useITkAmbigFcn)
490
491 // is this a track from the pattern or a fitted track ?
492 bool ispatterntrack = (track.info().trackFitter()==Trk::TrackInfo::Unknown);
493
494 //
495 // --- non binned Chi2
496 //
497 if (!ispatterntrack) {
498 if (track.fitQuality()!=nullptr && track.fitQuality()->chiSquared()>0 && track.fitQuality()->numberDoF()>0 ) {
499 int indf = track.fitQuality()->numberDoF();
500 double chi2 = track.fitQuality()->chiSquared();
501 double fac = 1. / log10 (10. + 10. * chi2 / indf); // very soft chi2
502 prob *= fac;
503 ATH_MSG_DEBUG ("Modifier for chi2 = " << chi2 << " and NDF = " << indf
504 << " is : "<< fac << " New score now: " << prob);
505
506 }
507 }
508 //
509 // --- fit quality prob
510 //
511 if ( !ispatterntrack && (m_useSigmaChi2) && track.fitQuality() ) {
512
513 int ndf = track.fitQuality()->numberDoF();
514 double chi2 = track.fitQuality()->chiSquared();
515 if (ndf > 0) {
516 //
517 // --- special variable for bad chi2 distribution
518 //
519 if (m_useSigmaChi2) {
520 int sigmaChi2times100 = trackSummary.get(Trk::standardDeviationOfChi2OS);
521 if (sigmaChi2times100 > 0) {
522 double testvar = double(sigmaChi2times100)/100. - sqrt(2.*chi2/ndf);
523 if (msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << "sigma chi2 = " << testvar << endmsg;
524 if ( testvar< m_boundsSigmaChi2[0] ) {
525 prob *= m_factorSigmaChi2[0];
526 ATH_MSG_DEBUG ("Modifier for " << testvar << " sigma chi2: "<< m_factorSigmaChi2[0]
527 << " New score now: " << prob);
528 } else if (m_boundsSigmaChi2[m_maxSigmaChi2] <= testvar) {
530 ATH_MSG_DEBUG ("Modifier for " << testvar << " sigma chi2: "<< m_factorSigmaChi2[m_maxSigmaChi2-1]
531 << " New score now: " << prob);
532 } else {
533 for (int i = 0 ; i<m_maxSigmaChi2 ; ++i ) {
534 if ( m_boundsSigmaChi2[i]<=testvar && testvar<m_boundsSigmaChi2[i+1] ) {
535 prob *= m_factorSigmaChi2[i];
536 ATH_MSG_DEBUG ("Modifier for " << testvar << " sigma chi2: "<< m_factorSigmaChi2[i]
537 << " New score now: " << prob);
538 break;
539 }
540 }
541 }
542 }
543 }
544 }
545 }
546
547 return Trk::TrackScore(prob);
548}
549
550//---------------------------------------------------------------------------------------------------------------------
551
553{
554 //
555 // --- number of Pixel holes
556 //
557 // --- NewTracking and BackTracking
558 const int maxPixHoles = 2; // there is an explicit cut
559 const double goodPixHoles[maxPixHoles+1] = {1.0 , 0.04 , 0.004 };
560 const double fakePixHoles[maxPixHoles+1] = {1.0 , 0.30 , 0.200 };
561 // put it into the private members
562 m_maxPixHoles = maxPixHoles;
563 for (int i=0; i<=m_maxPixHoles; ++i) m_factorPixHoles.push_back(goodPixHoles[i]/fakePixHoles[i]);
564
565 //
566 // --- number of SCT holes
567 //
568 if (!m_useTRT_AmbigFcn) {
569 // --- NewTracking
570 const int maxSCT_Holes = 5; // moved from 3 -> 5 , there is an explicit cut anyway
571 const double goodSCT_Holes[maxSCT_Holes+1] = { 1.0 , 0.06 , 0.010 , 0.0007, 0.0005, 0.0003 };
572 const double fakeSCT_Holes[maxSCT_Holes+1] = { 1.0 , 0.15 , 0.100 , 0.0100, 0.0100, 0.0100 };
573 // put it into the private members
574 m_maxSCT_Holes = maxSCT_Holes;
575 for (int i=0; i<=m_maxSCT_Holes; ++i) m_factorSCT_Holes.push_back(goodSCT_Holes[i]/fakeSCT_Holes[i]);
576 } else {
577 // --- BackTracking
578 const int maxSCT_Holes = 6;
579 const double goodSCT_Holes[maxSCT_Holes+1] = {0.910, 0.074, 0.014, 0.001, 0.001, 0.00001, 0.00001};
580 const double fakeSCT_Holes[maxSCT_Holes+1] = {0.910, 0.192, 0.229, 0.061, 0.065, 0.016 , 0.025};
581 // put it into the private members
582 m_maxSCT_Holes = maxSCT_Holes;
583 for (int i=0; i<=m_maxSCT_Holes; ++i) m_factorSCT_Holes.push_back(goodSCT_Holes[i]/fakeSCT_Holes[i]);
584 }
585
586 //
587 // --- number of SCT double holes
588 //
589 // --- NewTracking and BackTracking
590 const int maxDblHoles = 3; // there is a cut on this anyway !
591 const double goodDblHoles[maxDblHoles+1] = { 1. , 0.03 , 0.007 , 0.0003 };
592 const double fakeDblHoles[maxDblHoles+1] = { 1. , 0.09 , 0.09 , 0.008 };
593 // put it into the private members
594 m_maxDblHoles = maxDblHoles;
595 for (int i=0; i<=m_maxDblHoles; ++i) m_factorDblHoles.push_back(goodDblHoles[i]/fakeDblHoles[i]);
596
597 //
598 // --- number of Blayer hits
599 //
600 if (!m_useTRT_AmbigFcn) {
601 // --- NewTracking
602 if (m_useITkAmbigFcn) {
603 const int maxB_LayerHitsITk = 8;
604 m_maxB_LayerHits = maxB_LayerHitsITk;
605 const double blayModi[maxB_LayerHitsITk + 1] = {0.25, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5};
606 for (int i = 0; i <= m_maxB_LayerHits; ++i) m_factorB_LayerHits.push_back(blayModi[i]);
607 } else {
608 const int maxB_LayerHits = 3;
609 const double goodB_LayerHits[maxB_LayerHits+1] = {0.203, 0.732, 0.081, 0.010};
610 const double fakeB_LayerHits[maxB_LayerHits+1] = {0.808, 0.174, 0.018, 0.002};
611 // put it into the private members
612 m_maxB_LayerHits = maxB_LayerHits;
613 for (int i=0; i<=m_maxB_LayerHits; ++i) m_factorB_LayerHits.push_back(goodB_LayerHits[i]/fakeB_LayerHits[i]);
614 }
615 } else {
616 // --- BackTracking
617 const int maxB_LayerHits = 3;
618 const double goodB_LayerHits[maxB_LayerHits+1] = {0.605, 0.349, 0.044, 0.010};
619 const double fakeB_LayerHits[maxB_LayerHits+1] = {0.865, 0.124, 0.011, 0.002};
620 // put it into the private members
621 m_maxB_LayerHits = maxB_LayerHits;
622 for (int i=0; i<=m_maxB_LayerHits; ++i) m_factorB_LayerHits.push_back(goodB_LayerHits[i]/fakeB_LayerHits[i]);
623 }
624
625 //
626 // --- number of Pixel hits without Blayer
627 //
628 if (!m_useTRT_AmbigFcn) {
629 // --- NewTracking
630 if (m_useITkAmbigFcn) {
631 const int maxPixelHitsITk = 26;
632 m_maxPixelHits = maxPixelHitsITk;
633 double maxScore = 30.0;
634 double minScore = 5.00;
635 int maxBarrel = 10;
636 int minBarrel = 3;
637 int minEnd = 5;
638
639 double step[2] = {
640 (maxScore - minScore) / (maxBarrel - minBarrel), (maxScore - minScore) / (maxPixelHitsITk - minEnd)
641 };
642
643 for (int i = 0; i <= maxPixelHitsITk; i++) {
644 if (i < minEnd) m_factorPixelHits.push_back(0.01 + (i * 0.33));
645 else m_factorPixelHits.push_back(minScore + ((i - minEnd) * step[1]));
646 }
647 } else {
648 const int maxPixelHits = 8; // we see up to 8 with IBL (was 6)
649 const double goodPixelHits[maxPixelHits+1] = {0.095, 0.031, 0.118, 0.615, 0.137, 0.011, 0.01 , 0.011, 0.012};
650 const double fakePixelHits[maxPixelHits+1] = {0.658, 0.100, 0.091, 0.124, 0.026, 0.002, 0.001 , 0.001, 0.001};
651 m_maxPixelHits = maxPixelHits;
652 for (int i=0; i<=m_maxPixelHits; ++i) m_factorPixelHits.push_back(goodPixelHits[i]/fakePixelHits[i]);
653 }
654 } else {
655 // --- BackTracking
656 const int maxPixelHits = 8; // we see up to 8 with IBL (was 6)
657 const double goodPixelHits[maxPixelHits+1] = {0.401, 0.079, 0.140, 0.291, 0.011, 0.078, 0.01 , 0.011, 0.012};
658 const double fakePixelHits[maxPixelHits+1] = {0.673, 0.138, 0.113, 0.057, 0.002, 0.011, 0.001 , 0.001, 0.001};
659 m_maxPixelHits = maxPixelHits;
660 for (int i=0; i<=m_maxPixelHits; ++i) m_factorPixelHits.push_back(goodPixelHits[i]/fakePixelHits[i]);
661 }
662
663 //
664 // --- number of Pixel layers
665 //
666 if (!m_useTRT_AmbigFcn) {
667 // --- NewTracking
668 if (m_useITkAmbigFcn) {
669 const int maxPixelLayITk = 16;
670 m_maxPixLay = maxPixelLayITk;
671 double maxScore = 30.0;
672 double minScore = 5.00;
673 int maxBarrel = 10;
674 int minBarrel = 3;
675 int minEnd = 5;
676
677 double step[2] = {
678 (maxScore - minScore) / (maxBarrel - minBarrel), (maxScore - minScore) / (maxPixelLayITk - minEnd)
679 };
680
681 for (int i = 0; i <= maxPixelLayITk; i++) {
682 if (i < minEnd) m_factorPixLay.push_back(0.01 + (i * 0.33));
683 else m_factorPixLay.push_back(minScore + ((i - minEnd) * step[1]));
684 }
685 } else {
686 const int maxPixLay = 7; // 3 barrel, 3 endcap, IBL, in practice one should see maybe 5 (was 3)
687 const double goodPixLay[maxPixLay+1] = {0.095, 0.033, 0.131, 0.740, 0.840, 0.940, 1.040,1.140};
688 const double fakePixLay[maxPixLay+1] = {0.658, 0.106, 0.092, 0.144, 0.144, 0.144, 0.144,0.144};
689 // put it into the private members
690 m_maxPixLay = maxPixLay;
691 for (int i=0; i<=m_maxPixLay; ++i) m_factorPixLay.push_back(goodPixLay[i]/fakePixLay[i]);
692 }
693 } else {
694 // --- BackTracking
695 const int maxPixLay = 7; // 3 barrel, 3 endcap, IBL, in practice one should see maybe 5 (was 5)
696 const double goodPixLay[maxPixLay+1] = {0.401, 0.088, 0.152, 0.355, 0.405, 0.455, 0.505, 0.555};
697 const double fakePixLay[maxPixLay+1] = {0.673, 0.146, 0.115, 0.065, 0.065, 0.065, 0.065, 0.065};
698 // put it into the private members
699 m_maxPixLay = maxPixLay;
700 for (int i=0; i<=m_maxPixLay; ++i) m_factorPixLay.push_back(goodPixLay[i]/fakePixLay[i]);
701 }
702
703 //
704 // --- number of Pixel Ganged Fakes
705 //
706 // --- NewTracking and BackTracking
707 const int maxGangedFakes = 2; // there is an explicit cut
708 const double goodGangedFakes[maxGangedFakes+1] = {0.62 , 0.23 , 0.15 };
709 const double fakeGangedFakes[maxGangedFakes+1] = {0.12 , 0.41 , 0.47 };
710 // put it into the private members
711 m_maxGangedFakes = maxGangedFakes;
712 for (int i=0; i<=m_maxGangedFakes; ++i) m_factorGangedFakes.push_back(goodGangedFakes[i]/fakeGangedFakes[i]);
713
714 //
715 // --- total number of SCT+Pixel hits
716 //
717 // --- NewTracking and BackTracking
718 if (m_useITkAmbigFcn) {
719 const int maxHitsITk = 26;
720 m_maxHits = maxHitsITk;
721 double maxScore = 40.0;
722 double minScore = 5.00;
723 int maxBarrel = 25;
724 int minBarrel = 9;
725 int minEnd = 12;
726
727 double step[2] = {
728 (maxScore - minScore) / (maxBarrel - minBarrel), (maxScore - minScore) / (maxHitsITk - minEnd)
729 };
730
731 for (int i = 0; i <= maxHitsITk; i++) {
732 if (i < minEnd) m_factorHits.push_back(0.01 + (i * 1.0 / minEnd));
733 else m_factorHits.push_back(minScore + ((i - minEnd) * step[1]));
734 }
735 } else {
736 const int maxHits = 19; // there is a min cut on this anyway !
737 const double goodSiHits[maxHits+1] = { 0.001 , 0.002 , 0.003 , 0.004 , 0.01 , 0.01 , 0.01 ,
738 0.015 , 0.02 , 0.06 , 0.1 , 0.3 , 0.2 , 0.50 , 0.055,
739 0.03 , 0.015 , 0.010 , 0.002 , 0.0005 };
740 const double fakeSiHits[maxHits+1] = { 1.0 , 1.0 , 1.0 , 1.0 , 0.5 , 0.25 , 0.15 ,
741 0.20 , 0.1 , 0.2 , 0.08 , 0.07 , 0.035 , 0.08 , 0.008,
742 0.004 , 0.0015 , 0.0008 , 0.0001 , 0.00001 };
743 // put it into the private members
744 m_maxHits = maxHits;
745 for (int i=0; i<=m_maxHits; ++i) m_factorHits.push_back(goodSiHits[i]/fakeSiHits[i]);
746 }
747
748 //
749 // --- ratio of TRT hits over expected
750 //
751 // --- NewTracking and BackTracking
752 const int maxTrtRatio = 7 ;
753 const double TrtRatioBounds[maxTrtRatio+1] = { 0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 2.4};
754 // this needs tuning !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
755 const double goodTrtRatio[maxTrtRatio] = { 0.05, 0.11, 0.12, 0.15, 0.20, 0.16, 0.17};
756 const double fakeTrtRatio[maxTrtRatio] = { 0.6 , 0.08, 0.06, 0.05, 0.04, 0.03, 0.03};
757 // put it into the private members
758 m_maxTrtRatio = m_selectortool.isEnabled() ? maxTrtRatio : 0;
759 for (int i=0; i<m_maxTrtRatio; ++i) m_factorTrtRatio.push_back(goodTrtRatio[i]/fakeTrtRatio[i]);
760 for (int i=0; i<=m_maxTrtRatio; ++i) m_boundsTrtRatio.push_back(TrtRatioBounds[i]);
761
762 //
763 // --- ratio of TRT fitted to (fitted+outliers)
764 //
765 // --- NewTracking and BackTracking
766 const int maxTrtFittedRatio = 4;
767 const double TrtFittedRatioBounds[maxTrtFittedRatio+1] = { 0, 0.3, 0.6, 0.9, 1.0};
768 // this needs tuning !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
769 const double goodTrtFittedRatio[maxTrtFittedRatio] = { 0.1, 0.2, 0.3, 0.5};
770 const double fakeTrtFittedRatio[maxTrtFittedRatio] = { 0.6, 0.1, 0.1, 0.1};
771 // put it into the private members
772 m_maxTrtFittedRatio = maxTrtFittedRatio;
773 for (int i=0; i<m_maxTrtFittedRatio; ++i) m_factorTrtFittedRatio.push_back(goodTrtFittedRatio[i]/fakeTrtFittedRatio[i]);
774 for (int i=0; i<=m_maxTrtFittedRatio; ++i) m_boundsTrtFittedRatio.push_back(TrtFittedRatioBounds[i]);
775
776
777 //
778 // --- sigma chi2
779 //
780 if (!m_useSigmaChi2) {
781 m_maxSigmaChi2 = -1 ;
782 } else {
783 // --- NewTracking and BackTracking
784 const int maxSigmaChi2 = 13 ;
785 const double SigmaChi2Bounds[maxSigmaChi2+1] = { -5.,-4.,-3.,-2.,-1.,0.,1.,2.,3.,4.,5.,6.,7.,8.};
786 const double goodSigmaChi2[maxSigmaChi2] = {0.00004, 0.0004, 0.002, 0.15, 0.8, 0.015, 0.01 , 0.009, 0.008, 0.0007 , 0.0006 , 0.0005, 0.00004};
787 const double fakeSigmaChi2[maxSigmaChi2] = {0.0008 , 0.005 , 0.02 , 0.2 , 0.3, 0.1 , 0.1 , 0.1 , 0.1 , 0.01 , 0.01 , 0.01 , 0.001};
788 // put it into the private members
789 m_maxSigmaChi2 = maxSigmaChi2;
790 for (int i=0; i<m_maxSigmaChi2; ++i) m_factorSigmaChi2.push_back(goodSigmaChi2[i]/fakeSigmaChi2[i]);
791 for (int i=0; i<=m_maxSigmaChi2; ++i) m_boundsSigmaChi2.push_back(SigmaChi2Bounds[i]);
792 }
793
794 //
795 // --- debug output
796 //
797 if (msgLvl(MSG::VERBOSE)) {
798
799 for (int i=0; i<=m_maxPixHoles; ++i)
800 msg(MSG::VERBOSE) << "Modifier for " << i << " Pixel holes: " << m_factorPixHoles[i] <<endmsg;
801
802 for (int i=0; i<=m_maxSCT_Holes; ++i)
803 msg(MSG::VERBOSE) << "Modifier for " << i << " SCT holes: " << m_factorSCT_Holes[i] <<endmsg;
804
805 for (int i=0; i<=m_maxDblHoles; ++i)
806 msg(MSG::VERBOSE) << "Modifier for " << i << " double SCT holes: " << m_factorDblHoles[i] <<endmsg;
807
808 for (int i=0; i<=m_maxPixLay; ++i)
809 msg(MSG::VERBOSE) << "Modifier for " << i << " Pixel layers: " << m_factorPixLay[i] <<endmsg;
810
811 for (int i=0; i<=m_maxB_LayerHits; ++i)
812 msg(MSG::VERBOSE) << "Modifier for " << i << " b-layer hits: " << m_factorB_LayerHits[i] <<endmsg;
813
814 for (int i=0; i<=m_maxPixelHits; ++i)
815 msg(MSG::VERBOSE) << "Modifier for " << i << " Pixel hits: " << m_factorPixelHits[i] <<endmsg;
816
817 for (int i=0; i<=m_maxGangedFakes; ++i)
818 msg(MSG::VERBOSE) << "Modifier for " << i << " ganged fakes: " << m_factorGangedFakes[i] <<endmsg;
819
820 for (int i=0; i<=m_maxHits; ++i)
821 msg(MSG::VERBOSE) << "Modifier for " << i << " Si hits: " << m_factorHits[i] <<endmsg;
822
823 if (m_selectortool.isEnabled()) {
824 for (int i=0; i<m_maxTrtRatio; ++i)
825 msg(MSG::VERBOSE) << "Modifier for " << m_boundsTrtRatio[i] << " < TRT ratio < "
826 << m_boundsTrtRatio[i+1] <<" : " <<m_factorTrtRatio[i] <<endmsg;
827 }
828
829 for (int i=0; i<m_maxTrtFittedRatio; ++i)
830 msg(MSG::VERBOSE) << "Modifier for " << m_boundsTrtFittedRatio[i] << " < TRT fitted ratio < "
832
833
834 // only if used
835 for (int i=0; i<m_maxSigmaChi2; ++i)
836 msg(MSG::VERBOSE) << "Modifier for " << m_boundsSigmaChi2[i] << " < sigma(chi2) - sqrt(2chi2) < " << m_boundsSigmaChi2[i+1]
837 <<" : " <<m_factorSigmaChi2[i] <<endmsg;
838 }
839
840}
841
842bool InDet::InDetAmbiScoringTool::isEmCaloCompatible(const Trk::Track& track, const EventContext& ctx) const
843{
844 const Trk::TrackParameters * Tp = track.trackParameters()->front();
845
846 //Switch to the track parameters of the first measurment instead of the perigee parameters
847 ATH_MSG_VERBOSE ("--> Looping over TSOS's");
848 for (const auto *tsos : *track.trackStateOnSurfaces() ) {
849 // get measurment from TSOS
850 const auto *meas = tsos->measurementOnTrack();
851 const auto *tp = tsos->trackParameters();
852 // if we do not have a measurement, we should just mark it
853 if (!meas || !tp) {
854 continue;
855 } else {
856 Tp = tp;
857 break;
858 }
859 }
860
861 double F = Tp->momentum().phi();
862 double E = Tp->momentum().eta();
863 double R = Tp->position().perp();
864 double Z = Tp->position().z();
866 return calo->hasMatchingROI(F, E, R, Z, m_phiWidthEm, m_etaWidthEm);
867}
868
869
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
static Double_t Tp(Double_t *t, Double_t *par)
static Double_t sc
#define F(x, y, z)
Definition MD5.cxx:112
Handle class for reading from StoreGate.
Handle class for recording to StoreGate.
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
bool msgLvl(const MSG::Level lvl) const
MsgStream & msg() const
void getInitializedCache(MagField::AtlasFieldCache &cache) const
get B field cache for evaluation as a function of 2-d or 3-d position.
SG::ReadHandleKey< ROIPhiRZContainer > m_caloClusterROIKey
virtual StatusCode initialize() override
DoubleProperty m_minPt
cuts for selecting good tracks
Trk::TrackScore ambigScore(const Trk::Track &track, const Trk::TrackSummary &trackSum) const
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCacheCondObjInputKey
ToolHandle< Trk::IExtrapolator > m_extrapolator
std::vector< double > m_boundsSigmaChi2
InDetAmbiScoringTool(const std::string &, const std::string &, const IInterface *)
std::vector< double > m_boundsTrtRatio
BooleanProperty m_useAmbigFcn
use the scoring tuned to Ambiguity processing or not
virtual Trk::TrackScore score(const Trk::Track &track, bool checkBasicSel) const override
create a score based on how good the passed track is
virtual bool passBasicSelections(const Trk::Track &track) const override
check track selections independent from TrackSummary
BooleanProperty m_useITkAmbigFcn
use the ITk scoring tuned to Ambiguity processing or not
std::vector< double > m_factorHits
std::vector< double > m_factorPixHoles
ToolHandle< ITrtDriftCircleCutTool > m_selectortool
Returns minimum number of expected TRT drift circles depending on eta.
std::vector< double > m_boundsTrtFittedRatio
ServiceHandle< IInDetEtaDependentCutsSvc > m_etaDependentCutsSvc
ITk eta-dependent cuts.
std::vector< double > m_factorSigmaChi2
std::vector< double > m_factorB_LayerHits
std::vector< Trk::TrackScore > m_summaryTypeScore
holds the scores assigned to each Trk::SummaryType from the track's Trk::TrackSummary
bool isEmCaloCompatible(const Trk::Track &track, const EventContext &ctx) const
Check if the cluster is compatible with a EM cluster.
std::vector< double > m_factorPixelHits
std::vector< double > m_factorTrtFittedRatio
SG::ReadCondHandleKey< InDet::BeamSpotData > m_beamSpotKey
virtual Trk::TrackScore simpleScore(const Trk::Track &track, const Trk::TrackSummary &trackSum) const override
create a score based on how good the passed TrackSummary is
std::vector< double > m_factorTrtRatio
std::vector< double > m_factorSCT_Holes
std::vector< double > m_factorDblHoles
std::vector< double > m_factorPixLay
std::vector< double > m_factorGangedFakes
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h)
bool solenoidOn() const
status of the magnets
Class describing the Line to which the Perigee refers to.
A summary of the information contained by a track.
int get(const SummaryType &type) const
returns the summary information for the passed SummaryType.
double chi2(TH1 *h0, TH1 *h1)
Eigen::Matrix< double, 3, 1 > Vector3D
Ensure that the ATLAS eigen extensions are properly loaded.
float TrackScore
Definition TrackScore.h:10
@ d0
Definition ParamDefs.h:63
@ z0
Definition ParamDefs.h:64
ParametersBase< TrackParametersDim, Charged > TrackParameters
SummaryType
enumerates the different types of information stored in Summary.
@ numberOfContribPixelLayers
number of contributing layers of the pixel detector
@ numberOfGangedPixels
number of Ganged Pixels flagged as fakes
@ numberOfPixelHits
number of pixel layers on track with absence of hits
@ numberOfInnermostPixelLayerHits
these are the hits in the 1st pixel layer
@ numberOfTRTHighThresholdHits
total number of TRT hits which pass the high threshold
@ numberOfSCTHoles
number of Holes in both sides of a SCT module
@ numberOfGangedFlaggedFakes
number of dead pixel sensors crossed
@ numberOfPixelHoles
number of pixels which have a ganged ambiguity.
@ numberOfTRTTubeHits
number of TRT hits on track in straws with xenon
@ numberOfOutliersOnTrack
100 times the standard deviation of the chi2 from the surfaces
@ numberOfPixelDeadSensors
number of pixel hits with broad errors (width/sqrt(12))