ATLAS Offline Software
Loading...
Searching...
No Matches
InDetTrtTrackScoringTool.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 "CLHEP/GenericFunctions/CumulativeChiSquare.hh"
13#include "TrkTrack/Track.h"
15
16//---------------------------------------------------------------------------------------------------------------------
17
19 const std::string& n,
20 const IInterface* p)
21 : AthAlgTool(t, n, p)
22 , m_trtId(nullptr)
23 , m_summaryTypeScore(Trk::numberOfTrackSummaryTypes)
24{
25 declareInterface<Trk::ITrackScoringTool>(this);
26
27 // declare properties
28 m_summaryTypeScore[Trk::numberOfTRTHits] = 1; // 10 straws ~ 1 SCT
29 m_summaryTypeScore[Trk::numberOfTRTHighThresholdHits] = 0; // addition for being TR
30}
31
32//---------------------------------------------------------------------------------------------------------------------
33
34StatusCode
36{
37 ATH_CHECK(m_selectortool.retrieve( DisableTool{m_selectortool.empty() } ));
38 ATH_CHECK(m_lumiBlockMuTool.retrieve());
39
40 if (detStore()->retrieve(m_trtId, "TRT_ID").isFailure()) {
41 ATH_MSG_FATAL("Could not get TRT_ID helper !");
42 return StatusCode::FAILURE;
43 }
44 if (m_useAmbigFcn) {
46 }
47
48 // Read handle for AtlasFieldCacheCondObj
50
51 return StatusCode::SUCCESS;
52}
53
54//---------------------------------------------------------------------------------------------------------------------
56{
57 // get parameters without error - this is faster
58 const Trk::TrackParameters* input = track.trackParameters()->front();
59
61
62 const EventContext& ctx = Gaudi::Hive::currentContext();
64 const AtlasFieldCacheCondObj* fieldCondObj{ *readHandle };
65 if (fieldCondObj == nullptr) {
66 ATH_MSG_ERROR("simpleScore: Failed to retrieve AtlasFieldCacheCondObj with key "
68 return false;
69 }
71 fieldCondObj->getInitializedCache(fieldCache);
72
73 if (fieldCache.solenoidOn()) { // B field
74 if (input->pT() < m_ptmin) {
75 ATH_MSG_DEBUG("Reject track below Pt cut !");
76 return false;
77 }
78 }
79
80 if (std::abs(input->eta()) > m_maxEta) {
81 return false;
82 }
83
84 return true;
85}
86
87//---------------------------------------------------------------------------------------------------------------------
88
90InDet::InDetTrtTrackScoringTool::score(const Trk::Track& track, bool checkBasicSel) const
91{
92 if(checkBasicSel && !passBasicSelections(track)){
93 ATH_MSG_VERBOSE ("Track fail basic selections");
94 return Trk::TrackScore(0);
95 }
96 if (!track.trackSummary()) {
97 ATH_MSG_FATAL("Track without a summary");
98 }
99 Trk::TrackScore score = Trk::TrackScore(simpleScore(track, *track.trackSummary()));
100 return score;
101}
102
103//---------------------------------------------------------------------------------------------------------------------
104
107{
108 int numTRT = trackSummary.get(Trk::numberOfTRTHits);
109 int numTRTTube = trackSummary.get(Trk::numberOfTRTTubeHits);
110
111 // TRT precision hits cut
112 if (numTRT >= 15 && ((double)(numTRT - numTRTTube)) / numTRT < m_minTRTprecision) {
113 return Trk::TrackScore(0);
114 }
115
116 const Trk::Perigee* perigee = track.perigeeParameters();
117 int numTRT_plusOutliers = numTRT + trackSummary.get(Trk::numberOfTRTOutliers);
118 unsigned int eta_bin = getEtaBin(*perigee);
119 double minTRT = getMuDependentNtrtMinCut(eta_bin);
120
121 // nTRT cut from egamma optimization
122 if (numTRT_plusOutliers < minTRT) {
123 return Trk::TrackScore(0);
124 }
125
126 // Cut on the minimum number of hits
127 bool isGood = m_selectortool.isEnabled() ? isGoodTRT(track) : true;
128 if (!isGood) {
129 return Trk::TrackScore(0);
130 }
131
132 //
133 // --- Now Start Scoring
134 //
135
136 if (m_useAmbigFcn) {
137
138 //
139 // -- modern score
140 //
141 return TRT_ambigScore(track, trackSummary);
142
143 } else {
144
145 //
146 // --classical scoring !
147 //
148 // score of 100 per track
150 // --- summary score analysis
151 for (int i = 0; i < Trk::numberOfTrackSummaryTypes; ++i) {
152 int value = trackSummary.get(static_cast<Trk::SummaryType>(i));
153 // value is -1 if undefined.
154 if (value > 0) {
155 score += m_summaryTypeScore[i] * value;
156 }
157 }
158 // --- prob(chi2,NDF), protect for chi2 <= 0
159 if (track.fitQuality() != nullptr && track.fitQuality()->chiSquared() > 0 && track.fitQuality()->numberDoF() > 0) {
160 double p = 1.0 - Genfun::CumulativeChiSquare(track.fitQuality()->numberDoF())(track.fitQuality()->chiSquared());
161 if (p > 0)
162 score += log10(p);
163 else
164 score -= 50;
165 }
166 return score;
167 }
168}
169
170//---------------------------------------------------------------------------------------------------------------
171
174{
175 //
176 // --- start with bonus for high pt tracks
177 //
178 // double prob = 1.;
179 double pt = std::abs(track.trackParameters()->front()->pT());
180 double prob = log10(pt) - 1.; // 100 MeV is min and gets score 1
181
182 //
183 // --- special treatment for TRT hits
184 //
185 int iTRT_Hits = trackSummary.get(Trk::numberOfTRTHits);
186 int iTRT_Outliers = trackSummary.get(Trk::numberOfTRTOutliers);
187 //
188
189 if (iTRT_Hits > 0 && m_maxTrtRatio > 0) {
190 // get expected number of TRT hits
191 double nTrtExpected = 30.;
192 assert( m_selectortool.isEnabled());
193 nTrtExpected = m_selectortool->minNumberDCs(track.trackParameters()->front());
194 double ratio = iTRT_Hits / nTrtExpected;
195 if (ratio > m_boundsTrtRatio[m_maxTrtRatio])
197 for (int i = 0; i < m_maxTrtRatio; ++i) {
198 if (m_boundsTrtRatio[i] < ratio && ratio <= m_boundsTrtRatio[i + 1]) {
199 prob *= m_factorTrtRatio[i];
200 break;
201 }
202 }
203 }
204
205 if (iTRT_Hits > 0 && iTRT_Outliers >= 0 && m_maxTrtFittedRatio > 0) {
206 double fitted = double(iTRT_Hits) / double(iTRT_Hits + iTRT_Outliers);
209 for (int i = 0; i < m_maxTrtFittedRatio; ++i) {
210 if (fitted <= m_boundsTrtFittedRatio[i + 1]) {
211 prob *= m_factorTrtFittedRatio[i];
212 break;
213 }
214 }
215 }
216
217 //
218 // --- non binned Chi2
219
220 if (track.fitQuality() != nullptr && track.fitQuality()->chiSquared() > 0 && track.fitQuality()->numberDoF() > 0) {
221 int indf = track.fitQuality()->numberDoF();
222 double chi2 = track.fitQuality()->chiSquared();
223 double fac = 1. / log10(10. + 10. * chi2 / indf); // very soft chi2
224 prob *= fac;
225 }
226
227 //
228 // --- do we use the binned prob for chi2/NDF or sigma chi2 ?
229 //
230 if ((m_useSigmaChi2) && track.fitQuality()) {
231 int indf = track.fitQuality()->numberDoF();
232 double ichi2 = track.fitQuality()->chiSquared();
233 if (indf > 0) {
234 //
235 // --- binned sigma chi2 score
236 //
237 if (m_useSigmaChi2) {
238 int sigmaChi2times100 = trackSummary.get(Trk::standardDeviationOfChi2OS);
239 if (sigmaChi2times100 > 0) {
240 double testvar = double(sigmaChi2times100) / 100. - sqrt(2. * ichi2 / indf);
241 if (testvar < m_boundsSigmaChi2[0]) {
242 prob *= m_factorSigmaChi2[0];
243 } else if (m_boundsSigmaChi2[m_maxSigmaChi2] <= testvar) {
245 } else {
246 for (int i = 0; i < m_maxSigmaChi2; ++i) {
247 if (m_boundsSigmaChi2[i] <= testvar && testvar < m_boundsSigmaChi2[i + 1]) {
248 prob *= m_factorSigmaChi2[i];
249 }
250 }
251 }
252 }
253 }
254 }
255 }
256
258 return score;
259}
260
261//-----------------------------------------------------------------------------------------------------------
262void
264{
265
266 //
267 // --- ratio of TRT hits over expected
268 //
269 constexpr int maxTrtRatio = 7;
270 constexpr double TrtRatioBounds[maxTrtRatio + 1] = { 0, 0.2, 0.4, 0.6,
271 0.8, 1.0, 1.2, 2.4 };
272 // this needs tuning !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
273 constexpr double goodTrtRatio[maxTrtRatio] = { 0.05, 0.11, 0.12, 0.15,
274 0.20, 0.16, 0.17 };
275 constexpr double fakeTrtRatio[maxTrtRatio] = { 0.6, 0.08, 0.06, 0.05,
276 0.04, 0.03, 0.03 };
277 // put it into the private members
278 m_maxTrtRatio = m_selectortool.isEnabled() ? maxTrtRatio : 0;
279 for (int i = 0; i < m_maxTrtRatio; ++i)
280 m_factorTrtRatio.push_back(goodTrtRatio[i] / fakeTrtRatio[i]);
281 for (int i = 0; i <= m_maxTrtRatio; ++i)
282 m_boundsTrtRatio.push_back(TrtRatioBounds[i]);
283
284 //
285 // --- ratio of TRT fitted to (fitted+outliers)
286 //
287 const int maxTrtFittedRatio = 4;
288 const double TrtFittedRatioBounds[maxTrtFittedRatio + 1] = { 0, 0.3, 0.6, 0.9, 1.0 };
289 // this needs tuning !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
290 const double goodTrtFittedRatio[maxTrtFittedRatio] = { 0.1, 0.2, 0.3, 0.5 };
291 const double fakeTrtFittedRatio[maxTrtFittedRatio] = { 0.6, 0.1, 0.1, 0.1 };
292 // put it into the private members
293 m_maxTrtFittedRatio = maxTrtFittedRatio;
294 for (int i = 0; i < m_maxTrtFittedRatio; ++i)
295 m_factorTrtFittedRatio.push_back(goodTrtFittedRatio[i] / fakeTrtFittedRatio[i]);
296 for (int i = 0; i <= m_maxTrtFittedRatio; ++i)
297 m_boundsTrtFittedRatio.push_back(TrtFittedRatioBounds[i]);
298
299 //
300 // --- sigma chi2
301 //
302 if (!m_useSigmaChi2) {
303 // do not use it !
304 m_maxSigmaChi2 = -1;
305 } else {
306 constexpr int maxSigmaChi2 = 26;
307 constexpr double SigmaChi2Bounds[maxSigmaChi2 + 1] = {
308 -5.0, -4.5, -4.0, -3.5, -3.0, -2.5, -2.0, -1.5, -1.0,
309 -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5,
310 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0
311 };
312 constexpr double modiSigmaChi2[maxSigmaChi2] = {
313 0.0001, 0.0001, 0.0001, 0.0001, 0.001, 0.005, 0.024, 0.255, 0.644,
314 0.045, 0.008, 0.005, 0.004, 0.003, 0.002, 0.001, 0.001, 0.001,
315 0.001, 0.001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001
316 };
317 constexpr double vetoSigmaChi2[maxSigmaChi2] = {
318 0.001, 0.001, 0.001, 0.003, 0.014, 0.030, 0.079, 0.244, 0.295,
319 0.064, 0.029, 0.028, 0.030, 0.026, 0.023, 0.023, 0.021, 0.019,
320 0.016, 0.018, 0.012, 0.009, 0.007, 0.005, 0.001, 0.001
321 };
322 // put it into the private members
323 m_maxSigmaChi2 = maxSigmaChi2;
324 for (int i = 0; i < maxSigmaChi2; ++i) {
325 if (vetoSigmaChi2[i] == 0.0)
326 m_factorSigmaChi2.push_back(1.0);
327 else
328 m_factorSigmaChi2.push_back(modiSigmaChi2[i] / vetoSigmaChi2[i]);
329 }
330 for (int i = 0; i < maxSigmaChi2; ++i)
331 m_boundsSigmaChi2.push_back(SigmaChi2Bounds[i]);
332 }
333}
334
335bool
337{
338
339 int nTRT = 0;
340
341 // some cointer for the custom cuts
342 int nEC = 0;
343 int nBRL = 0;
344 int firstWheel = -999;
345 int lastLayer = -999;
346
347 // get list of measurements
348 const DataVector<const Trk::MeasurementBase>* trkV = track.measurementsOnTrack();
349
350 // loop over the measurements
352 for (im = trkV->begin(); im != ime; ++im) {
353
354 const InDet::TRT_DriftCircleOnTrack* trtcircle = nullptr;
355 // Make sure is not a pseudomeasurement
356 if ((*im)->type(Trk::MeasurementBaseType::RIO_OnTrack)) {
357 const Trk::RIO_OnTrack* rot = static_cast<const Trk::RIO_OnTrack*>((*im));
358 // is it really a TRT ?
360 trtcircle = static_cast<const InDet::TRT_DriftCircleOnTrack*>(*im);
361 }
362 }
363 if (!trtcircle) {
364 continue;
365 }
366
367 // increment measurment
368 ++nTRT;
369
370 // compute some transition area variables...
372 Identifier id = trtcircle->detectorElement()->identify();
373 int isB = m_trtId->barrel_ec(id);
374 if (isB == 2 || isB == -2)
375 nEC++;
376 else if (isB == 1 || isB == -1)
377 nBRL++;
378 if (nBRL > 0)
379 lastLayer = m_trtId->layer_or_wheel(id);
380 if (nEC == 1)
381 firstWheel = m_trtId->layer_or_wheel(id);
382 }
383 }
384
385 if (!m_parameterization) {
386
387 bool toLower = false;
388
389 // Cases where the min number of required TRT drift circles drops to 10
390 if (m_oldLogic && int(trkV->size()) <= m_minTRTonTrk) {
391 if ((nEC > 0 && nBRL > 0) || (nEC == 0 && nBRL > 0 && lastLayer < 2) ||
392 (nEC > 0 && nBRL == 0 && (firstWheel > 10 || firstWheel < 2))) {
393 toLower = true;
394 }
395 }
396
397 if ((int(trkV->size()) > m_minTRTonTrk) || toLower) {
398 return true; // Ask for a minimum number of TRT hits to process
399 } else {
400 return false;
401 }
402 } else {
403
404 // new pass, this is using the parameterization
405 const DataVector<const Trk::TrackParameters>* vpar = track.trackParameters();
406 const Trk::TrackParameters* par = (*vpar)[0];
407 int nCutTRT = m_minTRTonTrk;
408 assert( m_selectortool.isEnabled() );
409 int expected = m_selectortool->minNumberDCs(par);
410 if (expected > m_minTRTonTrk)
411 nCutTRT = expected;
412 return nTRT > nCutTRT;
413 }
414}
415
416unsigned int
418{
419 // Find the correct bin for applying eta-dependent cuts
420
421 double tanThetaOver2 = std::tan(perigee.parameters()[Trk::theta] / 2.);
422 double abs_eta = (tanThetaOver2 == 0) ? 999.0 : std::abs(std::log(tanThetaOver2));
423
424 for (unsigned int i = 0; i < m_TRTTrksEtaBins.size(); ++i) {
425 if (abs_eta < m_TRTTrksEtaBins[i]) {
426 return i;
427 }
428 }
429 return m_TRTTrksEtaBins.size() - 1;
430}
431
432double
434{
435
436 double minTRT = m_TRTTrksMinTRTHitsThresholds[eta_bin];
437
438 if (m_TRTTrksMinTRTHitsMuDependencies[eta_bin] > 0) {
439
440 float avg_mu = m_lumiBlockMuTool->averageInteractionsPerCrossing(Gaudi::Hive::currentContext());
441
442 // The mu-dependent cuts have only been validted up to mu = 80.
443 // Also there is some physical limit to nTRT, so at some point
444 // there needs to be a ceiling for this threshold.
445 // To be revisited when a higher mu value is reached.
446 avg_mu = std::min(80.f,avg_mu);
447
448 // minTRT = a + avg_mu * b
449 minTRT += avg_mu * m_TRTTrksMinTRTHitsMuDependencies[eta_bin];
450 }
451
452 return minTRT;
453}
454
#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_DEBUG(x)
This is an Identifier helper class for the TRT subdetector.
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
const ServiceHandle< StoreGateSvc > & detStore() const
void getInitializedCache(MagField::AtlasFieldCache &cache) const
get B field cache for evaluation as a function of 2-d or 3-d position.
Derived DataVector<T>.
Definition DataVector.h:795
DataModel_detail::const_iterator< DataVector > const_iterator
Standard const_iterator.
Definition DataVector.h:838
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
virtual Identifier identify() const override final
identifier of this detector element:
std::vector< Trk::TrackScore > m_summaryTypeScore
holds the scores assigned to each Trk::SummaryType from the track's Trk::TrackSummary
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
DoubleArrayProperty m_TRTTrksMinTRTHitsMuDependencies
IntegerProperty m_minTRTonTrk
cuts for selecting good tracks
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCacheCondObjInputKey
unsigned int getEtaBin(const Trk::Perigee &perigee) const
bool isGoodTRT(const Trk::Track &) const
Decide whether standalone TRT tracks pass the minimum hit requirement.
InDetTrtTrackScoringTool(const std::string &, const std::string &, const IInterface *)
const TRT_ID * m_trtId
ID TRT helper.
BooleanProperty m_useAmbigFcn
use the scoring tuned to Ambiguity processing or not
Trk::TrackScore TRT_ambigScore(const Trk::Track &track, const Trk::TrackSummary &trackSum) const
virtual Trk::TrackScore score(const Trk::Track &track, bool checkBasicSel) const override
create a score based on how good the passed track is
ToolHandle< ILumiBlockMuTool > m_lumiBlockMuTool
virtual StatusCode initialize() override
virtual bool passBasicSelections(const Trk::Track &track) const override
check track selections independent from TrackSummary
ToolHandle< ITrtDriftCircleCutTool > m_selectortool
Returns minimum number of expected TRT drift circles depending on eta.
double getMuDependentNtrtMinCut(unsigned int eta_bin) const
Represents 'corrected' measurements from the TRT (for example, corrected for wire sag).
virtual const InDetDD::TRT_BaseElement * detectorElement() const override final
returns the detector element, assoicated with the PRD of this class
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h)
bool solenoidOn() const
status of the magnets
Class to handle RIO On Tracks ROT) for InDet and Muons, it inherits from the common MeasurementBase.
Definition RIO_OnTrack.h:70
virtual bool rioType(RIO_OnTrackType::Type type) const =0
Method checking the Rio On Track type.
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)
Ensure that the ATLAS eigen extensions are properly loaded.
float TrackScore
Definition TrackScore.h:10
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
@ theta
Definition ParamDefs.h:66
ParametersBase< TrackParametersDim, Charged > TrackParameters
SummaryType
enumerates the different types of information stored in Summary.
@ numberOfTRTHighThresholdHits
total number of TRT hits which pass the high threshold
@ numberOfTRTTubeHits
number of TRT hits on track in straws with xenon