ATLAS Offline Software
Loading...
Searching...
No Matches
Tracking/TrkTools/TrkTrackSummaryTool/src/TrackSummaryTool.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//
8//
11//
13#include "Identifier/Identifier.h"
22//
23#include "GaudiKernel/EventContext.h"
24#include <algorithm>
25#include <cmath>
26#include <initializer_list>
27
28namespace {
29template<class Indexable, class IntegerArray>
30void
31setTheseElements(Indexable& container,
32 const IntegerArray& indices,
33 const typename Indexable::value_type& toValue)
34{
35 for (const auto idx : indices) {
36 container[idx] = toValue;
37 }
38}
39//
40template<class Indexable>
41void
42setTheseElements(Indexable& container,
43 const std::initializer_list<size_t>& indices,
44 const typename Indexable::value_type& toValue)
45{
46 for (const auto idx : indices) {
47 container[idx] = toValue;
48 }
49}
50}
51
53 const std::string& n,
54 const IInterface* p)
55 : base_class(t, n, p)
56 , m_detID{}
57{
58 declareInterface<ITrackSummaryTool>(this);
59}
60
62
63StatusCode
65{
66 ATH_CHECK(detStore()->retrieve(m_detID, "AtlasID"));
67 if (m_idTool.empty() && m_muonTool.empty()) {
68 ATH_MSG_WARNING("Could get neither InDetHelperTool nor MuonHelperTool.");
69 }
70 if (not m_idTool.empty()) {
71 ATH_CHECK(m_idTool.retrieve());
72 }
73 if (not m_muonTool.empty()) {
74 ATH_CHECK(m_muonTool.retrieve());
75 }
77 ATH_MSG_INFO("Search for InDet holes ON");
78 }
79 if(m_doHolesMuon){
80 ATH_MSG_INFO("Search for Muon holes ON");
81 }
82 return StatusCode::SUCCESS;
83}
84
85/*
86 * method that creates creates/updates the summary for
87 * a non-const track.
88 *
89 * if a summary is present it uses it as starting point
90 * by cloning it and adds additional info.
91 *
92 * it sets the track summary for the non-const
93 * track.
94 */
95void
97 const EventContext& ctx,
98 Trk::Track& track,
99 bool suppress_hole_search) const
100{
101 track.setTrackSummary(createSummary(ctx,
102 track,
103 m_doHolesInDet & !suppress_hole_search,
104 m_doHolesMuon & !suppress_hole_search));
105}
106
107/*
108 * method that creates a new summary from const track.
109 * It does not modify the const Track
110 */
111std::unique_ptr<Trk::TrackSummary>
112Trk::TrackSummaryTool::summary(const EventContext& ctx,
113 const Track& track) const
114{
115 return createSummary(
116 ctx, track, m_doHolesInDet, m_doHolesMuon);
117}
118
119/*
120 * method that creates a new summary from const track.
121 * It does not modify the const Track
122 * It never does a search for holes
123 */
124std::unique_ptr<Trk::TrackSummary>
126 const Track& track) const
127{
128 return createSummary(ctx, track, false, false);
129}
130
131/*
132 * Method that creates a new summary from const track.
133 * It does not modify the const Track
134 */
135std::unique_ptr<Trk::TrackSummary>
137 const Track& track,
138 bool doHolesInDet,
139 bool doHolesMuon) const
140{
141 std::unique_ptr<Trk::TrackSummary> ts;
142 // first check if track has summary already and then clone it.
143 if (track.trackSummary() != nullptr) {
144 ts = std::make_unique<Trk::TrackSummary>(*(track.trackSummary()));
145 } else {
146 ts = std::make_unique<Trk::TrackSummary>();
147 }
148 // fill the summary
149 fillSummary(ctx, *ts, track, doHolesInDet, doHolesMuon);
150 return ts;
151}
152
153/*
154 * Method that actually fills the summary
155 * Work is delegated mainly the tools.
156 * Here we set the summary info to initial values
157 * and call other methods/tools to fill it
158 */
159void
162 const Trk::Track& track,
163 bool doHolesInDet,
164 bool doHolesMuon) const
165{
166 // Resize the vector where we will keep the information needed for the summary
167 std::vector<int>& information = ts.m_information;
168 information.resize(std::min(information.size(),
169 static_cast<size_t>(numberOfTrackSummaryTypes)));
170
171 constexpr int toZero{ 0 };
172 if (!m_idTool.empty()) {
173 if (m_pixelExists) {
174 // Pixel counters set to 0
175 constexpr size_t numberOfPixelCounters{ 8 };
176 constexpr std::array<size_t, numberOfPixelCounters> atPixelIndices{
185 };
186 setTheseElements(information, atPixelIndices, toZero);
187 information[Trk::numberOfDBMHits] = 0;
188
189 }
190 // SCT and TRT counters set to 0
191 constexpr size_t numberOfSctOrTrtCounters{ 9 };
192 constexpr std::array<size_t, numberOfSctOrTrtCounters> atSctOrTrtIndices{
202 };
203 setTheseElements(information, atSctOrTrtIndices, toZero);
204 }
205
206 if (!m_muonTool.empty()) {
207 // Muon counters set to 0
208 constexpr size_t numberOfMuonRelatedCounters{ 15 };
209 constexpr std::array<size_t, numberOfMuonRelatedCounters> atMuonIndices{
218 };
219 // New Small Wheel counters set to 0
220 constexpr size_t numberOfNswRelatedCounters{ 6 };
221 constexpr std::array<size_t, numberOfNswRelatedCounters> atNswIndices{
224 };
225 setTheseElements(information, atMuonIndices, toZero);
226 setTheseElements(information, atNswIndices, toZero);
227 }
228
229 // update the summart counters processing the track states
230 std::bitset<numberOfDetectorTypes> hitPattern;
231 if (track.trackStateOnSurfaces()) {
232 information[Trk::numberOfOutliersOnTrack] = 0;
234 track,
235 track.trackStateOnSurfaces(),
236 information,
237 hitPattern,
238 doHolesInDet,
239 doHolesMuon);
240 } else {
241 ATH_MSG_WARNING("Null pointer to TSoS found on Track (author = "
242 << track.info().dumpInfo()
243 << "). This should never happen! ");
244 }
245 ts.m_idHitPattern = hitPattern.to_ulong();
246
247 //Now the possible additional summary steps
248 // Is the hole search done , could be there in the input already
249 bool holeSearchDone = (information[Trk::numberOfPixelHoles] != -1 &&
250 information[Trk::numberOfSCTHoles] != -1 &&
251 information[Trk::numberOfSCTDoubleHoles] != -1 &&
252 information[Trk::numberOfPixelDeadSensors] != -1 &&
253 information[Trk::numberOfSCTDeadSensors] != -1);
254
255 // Do the holes search if we have to or insist to
256 if ((doHolesInDet || doHolesMuon) &&
257 (!holeSearchDone || m_alwaysRecomputeHoles.value())) {
258 if (m_pixelExists) {
259 information[numberOfPixelHoles] = 0;
260 }
261 information[numberOfSCTHoles] = 0;
262 information[numberOfSCTDoubleHoles] = 0;
263 searchHolesStepWise(track, information, doHolesInDet, doHolesMuon);
264 }
265
266 // add detailed summary for muons
267 if (m_addMuonDetailedSummary && !m_muonTool.empty()) {
268 m_muonTool->addDetailedTrackSummary(ctx, track, ts);
269 }
270}
271
272/*
273 * Internal helper processing the Track State on Surfaces
274 */
275void
277 const EventContext& ctx,
278 const Track& track,
279 const Trk::TrackStates* tsos,
280 std::vector<int>& information,
281 std::bitset<numberOfDetectorTypes>& hitPattern,
282 bool doHolesInDet,
283 bool doHolesMuon) const
284{
285 int cntAddChi2 = 0;
286 float chi2Sum = 0;
287 float chi2Sum2 = 0;
290 for (; it != itEnd; ++it) {
291 const auto& trackState = **it;
292 const auto isMeasurement =
294 const auto isOutlier = trackState.type(Trk::TrackStateOnSurface::Outlier);
295 if (isMeasurement or isOutlier) {
296 const Trk::MeasurementBase* measurement = trackState.measurementOnTrack();
297 if (!measurement) {
298 ATH_MSG_WARNING("measurementOnTrack == null for a TrackStateOnSurface "
299 "of type Measurement or Outlier");
300 } else {
301 if (isOutlier)
302 ++information[Trk::numberOfOutliersOnTrack]; // increment outlier
303 // counter
305 ctx, track, measurement, *it, information, hitPattern);
306 } // if have measurement pointer
307 } // if type measurement, scatterer or outlier
308
309 if (isMeasurement) {
310 if (const auto& pFitQuality{ trackState.fitQualityOnSurface() };
311 pFitQuality and pFitQuality.numberDoF() > 0) {
312 ++cntAddChi2;
313 if (const auto& chiSq{ pFitQuality.chiSquared() };
314 chiSq > 1.e5) { // limit unphysical values and protect against FPE
315 chi2Sum += 1.e5;
316 chi2Sum2 += 1.e10;
317 } else {
318 const float chi2add = chiSq / pFitQuality.numberDoF();
319 chi2Sum += chi2add;
320 chi2Sum2 += chi2add * chi2add;
321 }
322 }
323 }
324
325 if (trackState.type(Trk::TrackStateOnSurface::Hole) &&
326 trackState.trackParameters()) {
327 if (!doHolesInDet ||
328 !doHolesMuon) { // no dedicated hole search via extrapolation, but
329 // take what might be on the track already.
330 if (trackState.trackParameters()
331 ->associatedSurface()
332 .associatedDetectorElement() != nullptr) {
333 const Identifier& id = trackState.trackParameters()
334 ->associatedSurface()
335 .associatedDetectorElementIdentifier();
336 if (!doHolesInDet && m_detID->is_pixel(id))
337 ++information[Trk::numberOfPixelHoles];
338 if (!doHolesInDet && m_detID->is_sct(id))
339 ++information[Trk::numberOfSCTHoles];
340 if (!doHolesMuon && m_detID->is_mdt(id))
341 ++information[Trk::numberOfMdtHoles];
342 }
343 }
344 }
345 }
346
347 float varChi2 = 0;
348 if (cntAddChi2 > 0) {
349 const auto inverseCount{ 1. / cntAddChi2 };
350 varChi2 = (chi2Sum2 - (chi2Sum * chi2Sum * inverseCount)) * inverseCount;
351 }
352 if (varChi2 > 0 && varChi2 < 1.e13)
353 information[Trk::standardDeviationOfChi2OS] = int(std::sqrt(varChi2) * 100);
354}
355
356/*
357 * Internal helper going through the measurements
358 * and delegating filling the summary to the
359 * relevant Helper tool
360 */
361void
363 const EventContext& ctx,
364 const Track& track,
365 const Trk::MeasurementBase* meas,
366 const Trk::TrackStateOnSurface* tsos,
367 std::vector<int>& information,
368 std::bitset<numberOfDetectorTypes>& hitPattern) const
369{
370 // Check if the measurement type is RIO on Track (ROT)
371 const RIO_OnTrack* rot = nullptr;
373 rot = static_cast<const RIO_OnTrack*>(meas);
374 }
375 if (rot) {
376 // have RIO_OnTrack
378 if (tool == nullptr) {
379 ATH_MSG_WARNING("Cannot find tool to match ROT. Skipping.");
380 } else {
381 tool->analyse(
382 ctx, track, rot, tsos, information, hitPattern);
383 }
384 } else {
385 // check if the measurement type is CompetingRIOsOnTrack
386 const Trk::CompetingRIOsOnTrack* compROT = nullptr;
388 compROT = static_cast<const CompetingRIOsOnTrack*>(meas);
389 }
390 if (compROT) {
391 // if this works we have a CompetingRIOsOnTrack.
392 rot = &compROT->rioOnTrack(0); // get 1st rot
394 getTool(rot->identify()); // Use 'main' ROT to get detector type
395 if (tool == nullptr) {
396 ATH_MSG_WARNING("Cannot find tool to match cROT. Skipping.");
397 } else {
398 tool->analyse(
399 ctx, track, compROT, tsos, information, hitPattern);
400 }
401 }
402 }
403}
404
407{
408 if (m_detID->is_indet(id)) {
409 if (!m_idTool.empty()) {
410 return &*m_idTool;
411 }
412 ATH_MSG_WARNING("getTool: Identifier is from ID but have no ID tool");
413 } else if (m_detID->is_muon(id)) {
414 if (!m_muonTool.empty()) {
415 return &*m_muonTool;
416 }
417 ATH_MSG_WARNING("getTool: Identifier is from Muon but have no Muon tool");
418 } else {
420 "getTool: Identifier is of unknown type! id: " << id.getString());
421 }
422 return nullptr;
423}
424
425void
427 std::vector<int>& information,
428 bool doHolesInDet,
429 bool doHolesMuon) const
430{
431 ATH_MSG_VERBOSE("Entering Trk::TrackSummaryTool::searchHolesStepWise");
432 // -------- obtain hits in Pixel and SCT only
433 if (track.trackStateOnSurfaces() == nullptr) {
434 constexpr int toMinusOne{ -1 };
435 constexpr std::array<size_t, 16> atIndices{ numberOfPixelHoles,
448 // new small wheels
452 setTheseElements(information, atIndices, toMinusOne);
453 return;
454 }
455
456 constexpr int toZero{ 0 };
457 if (doHolesInDet) {
458 // -------- perform the InDet hole search
459 if (m_pixelExists) {
460 setTheseElements(
461 information, { numberOfPixelHoles, numberOfPixelDeadSensors }, toZero);
462 }
463 setTheseElements(
464 information,
466 toZero);
467 m_idTool->searchForHoles(track, information, Trk::pion);
468 }
469 if (!m_muonTool.empty() && doHolesMuon) {
470 // now do Muon hole search. It works completely differently to the above,
471 // so we need to make this all a bit more general
472 // and probably more efficient. But this hopefully works for now! EJWM
473 constexpr size_t numberOfRelatedMuonCounters{ 10 };
474 constexpr std::array<size_t, numberOfRelatedMuonCounters> atMuonIndices{
482 // new small wheels
486 };
487 setTheseElements(information, atMuonIndices, toZero);
488 m_muonTool->searchForHoles(track, information, Trk::muon);
489 }
490}
491
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
This class provides an interface to generate or decode an identifier for the upper levels of the dete...
DataModel_detail::const_iterator< DataVector > 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.
Base class for all CompetingRIOsOnTack implementations, extends the common MeasurementBase.
virtual const RIO_OnTrack & rioOnTrack(unsigned int) const =0
returns the RIO_OnTrack (also known as ROT) objects depending on the integer.
This class is the pure abstract base class for all fittable tracking measurements.
virtual bool type(MeasurementBaseType::Type type) const =0
Interface method checking the type.
Class to handle RIO On Tracks ROT) for InDet and Muons, it inherits from the common MeasurementBase.
Definition RIO_OnTrack.h:70
Identifier identify() const
return the identifier -extends MeasurementBase
represents the track state (measurement, material, fit parameters and quality) at a surface.
@ Measurement
This is a measurement, and will at least contain a Trk::MeasurementBase.
@ Outlier
This TSoS contains an outlier, that is, it contains a MeasurementBase/RIO_OnTrack which was not used ...
@ Hole
A hole on the track - this is defined in the following way.
Gaudi::Property< bool > m_addMuonDetailedSummary
controls whether the detailed summary is added for the muons
Gaudi::Property< bool > m_doHolesMuon
controls whether holes on track in MS are produced Turning this on will (slightly) increase processin...
Gaudi::Property< bool > m_doHolesInDet
controls whether holes on track in ID are produced
void searchHolesStepWise(const Trk::Track &track, std::vector< int > &information, bool doHolesInDet, bool doHolesMuon) const
Extrapolation is performed from one hit to the next, it is checked if surfaces in between the extrapo...
void fillSummary(const EventContext &ctx, Trk::TrackSummary &ts, const Trk::Track &track, bool doHolesInDet, bool doHolesMuon) const
virtual ~TrackSummaryTool()
std::unique_ptr< Trk::TrackSummary > createSummary(const EventContext &ctx, const Track &track, bool doHolesInDet, bool doHolesMuon) const
Gaudi::Property< bool > m_pixelExists
switch to deactivate Pixel info init
ToolHandle< IExtendedTrackSummaryHelperTool > m_muonTool
tool to decipher muon RoTs
virtual void computeAndReplaceTrackSummary(const EventContext &ctx, Track &track, bool suppress_hole_search=false) const override final
virtual std::unique_ptr< Trk::TrackSummary > summary(const EventContext &ctx, const Track &track) const override final
const Trk::IExtendedTrackSummaryHelperTool * getTool(const Identifier &id) const
Return the correct tool, matching the passed Identifier.
void processTrackStates(const EventContext &ctx, const Track &track, const Trk::TrackStates *tsos, std::vector< int > &information, std::bitset< numberOfDetectorTypes > &hitPattern, bool doHolesInDet, bool doHolesMuon) const
loops over TrackStatesOnSurface and uses this to produce the summary information Fills 'information',...
void processMeasurement(const EventContext &ctx, const Track &track, const Trk::MeasurementBase *meas, const Trk::TrackStateOnSurface *tsos, std::vector< int > &information, std::bitset< numberOfDetectorTypes > &hitPattern) const
TrackSummaryTool(const std::string &, const std::string &, const IInterface *)
virtual std::unique_ptr< Trk::TrackSummary > summaryNoHoleSearch(const EventContext &ctx, const Track &track) const override final
ToolHandle< IExtendedTrackSummaryHelperTool > m_idTool
tool to decipher ID RoTs
A summary of the information contained by a track.
int ts
Definition globals.cxx:24
DataVector< const Trk::TrackStateOnSurface > TrackStates
@ numberOfTgcPhiHoles
number of TGC Phi measurements missing from the track
@ numberOfTRTHoles
number of TRT hits which pass the high threshold (only xenon counted) total number of TRT hits which ...
@ numberOfRpcEtaHoles
number of RPC Eta measurements missing from the track
@ 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
@ numberOfTRTHighThresholdOutliers
number of dead TRT straws crossed
@ numberOfMdtHoles
number of MDT measurements missing from the track
@ numberOfMmHits
number of TGC Eta measurements missing from the track
@ numberOfStgcEtaHits
number of TGC Eta measurements missing from the track
@ numberOfStgcPhiHoles
number of TGC Phi measurements missing from the track
@ numberOfStgcEtaHoles
number of TGC Eta measurements missing from the track
@ numberOfNextToInnermostPixelLayerHits
these are the pixel hits, including the b-layer
@ numberOfMmHoles
number of TGC Eta measurements missing from the track
@ 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
@ numberOfStgcPhiHits
number of TGC Phi measurements missing from the track
@ 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
@ numberOfTgcEtaHoles
number of TGC Eta measurements missing from the track
@ numberOfTRTHighThresholdHitsTotal
number of TRT hits used for dE/dx computation
@ numberOfCscUnspoiltEtaHits
number of unspoilt CSC eta measurements (all CSC phi measurements are by definition spoilt).
@ numberOfPixelDeadSensors
number of pixel hits with broad errors (width/sqrt(12))
@ numberOfCscPhiHoles
number of CSC Phi measurements missing from the track
@ numberOfRpcPhiHoles
number of RPC Phi measurements missing from the track
@ numberOfCscEtaHoles
number of CSC Eta measurements missing from the track