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