ATLAS Offline Software
Loading...
Searching...
No Matches
TrackParticleCreatorTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5/***************************************************************************
6 TrackParticleCreatorTool.cxx - Description
7 -------------------
8 begin : Autumn 2003
9 authors : Andreas Wildauer (CERN PH-ATC), Fredrik Akesson (CERN PH-ATC)
10 email : andreas.wildauer@cern.ch, fredrik.akesson@cern.ch
11 changes :
12
13***************************************************************************/
16
17// forward declares
19#include "TrkTrack/Track.h"
21
22// normal includes
24
29
36
44
45#include "xAODTracking/Vertex.h"
46
47#include <algorithm>
48#include <cassert>
49#include <cmath>
50#include <map>
51#include <memory>
52#include <vector>
53
54// helper methods to print messages
55template<class T>
56inline MsgStream&
57operator<<(MsgStream& msg_stream, const std::map<std::string, T>& elm_map)
58{
59 for (const std::pair<const std::string, T>& elm : elm_map) {
60 msg_stream << " " << elm.first;
61 }
62 return msg_stream;
63}
64
65template<class T>
66inline MsgStream&
67operator<<(MsgStream& msg_stream, const std::vector<std::string>& elm_vector)
68{
69 for (const std::string& elm : elm_vector) {
70 msg_stream << " " << elm;
71 }
72 return msg_stream;
73}
74
75namespace Trk {
76const std::string TrackParticleCreatorTool::s_trtdEdxUsedHitsDecorationName{ "TRTdEdxUsedHits" };
77
78namespace {
79void
80createEProbabilityMap(std::map<std::string, std::pair<Trk::eProbabilityType, bool>>& eprob_map)
81{
82 // key: name to be used to activate copying of the electron probability values to the xAOD
83 // TrackParticle
84 // abd for those which are added as decoration the name to be used for the decoration
85 // value.first: enum of the electron probability value
86 // value.second: false is a non dynamic element of the xAOD TrackParticle and added via
87 // setTrackSummary
88 // true will be added as a decoration.
89 eprob_map.insert(std::make_pair("eProbabilityComb", std::make_pair(Trk::eProbabilityComb, false)));
90 eprob_map.insert(std::make_pair("eProbabilityHT", std::make_pair(Trk::eProbabilityHT, false)));
91
92 // added as decorations
93 eprob_map.insert(std::make_pair("eProbabilityToT", std::make_pair(Trk::eProbabilityToT, true)));
94 eprob_map.insert(std::make_pair("eProbabilityBrem", std::make_pair(Trk::eProbabilityBrem, true)));
95 eprob_map.insert(std::make_pair("eProbabilityNN", std::make_pair(Trk::eProbabilityNN, true)));
96 eprob_map.insert(std::make_pair("TRTdEdx", std::make_pair(Trk::TRTdEdx, true)));
97 eprob_map.insert(std::make_pair("TRTTrackOccupancy", std::make_pair(Trk::TRTTrackOccupancy, true)));
98}
99
100void
101createExtraSummaryTypeMap(std::map<std::string, Trk::SummaryType>& extra_summary_type_map)
102{
103 extra_summary_type_map.insert(std::make_pair("TRTdEdxUsedHits", Trk::numberOfTRTHitsUsedFordEdx));
104}
105}
106
107const SG::AuxElement::Accessor<uint8_t> TrackParticleCreatorTool::s_trtdEdxUsedHitsDecoration(
109
111 const std::string& n,
112 const IInterface* p)
113 : base_class(t, n, p)
114 , m_detID(nullptr)
115 , m_pixelID(nullptr)
116 , m_sctID(nullptr)
117 , m_trtID(nullptr)
121 , m_doIBL(false)
122{
123}
124
125StatusCode
127{
128
129 ATH_MSG_DEBUG("initialize TrackParticleCreatorTool");
130 ATH_CHECK(m_beamSpotKey.initialize());
131 if (std::find(std::begin(m_perigeeOptions), std::end(m_perigeeOptions), m_perigeeExpression) ==
132 std::end(m_perigeeOptions)) {
133 ATH_MSG_ERROR("Unknown Configuration for Perigee Expression - please use one of "
135 return StatusCode::FAILURE;
136 }
137
138 /* Retrieve track summary tool */
139 if (!m_trackSummaryTool.empty()) {
140 if (m_trackSummaryTool.retrieve().isFailure()) {
141 ATH_MSG_FATAL("Failed to retrieve tool " << m_trackSummaryTool);
142 return StatusCode::FAILURE;
143 }
144 ATH_MSG_DEBUG("Retrieved tool " << m_trackSummaryTool);
145 } else {
146 m_trackSummaryTool.disable();
147 }
148
149 if (detStore()->retrieve(m_detID, "AtlasID").isFailure()) {
150 ATH_MSG_FATAL("Could not get AtlasDetectorID ");
151 return StatusCode::FAILURE;
152 }
153
154 if (detStore()->retrieve(m_pixelID, "PixelID").isFailure()) {
155 ATH_MSG_FATAL("Could not get PixelID ");
156 return StatusCode::FAILURE;
157 }
158
159 if (detStore()->retrieve(m_sctID, "SCT_ID").isFailure()) {
160 ATH_MSG_FATAL("Could not get SCT_ID ");
161 return StatusCode::FAILURE;
162 }
163
164 if (m_doSharedTRTHits) {
165 if (detStore()->retrieve(m_trtID, "TRT_ID").isFailure()) {
166 ATH_MSG_FATAL("Could not get TRT_ID ");
167 return StatusCode::FAILURE;
168 }
169 }
170
171 if (!m_IBLParameterSvc.empty()) {
172 if (m_IBLParameterSvc.retrieve().isFailure()) {
173 ATH_MSG_FATAL("Could not retrieve IBLParameterSvc");
174 return StatusCode::FAILURE;
175 }
176 }
177
178 m_doIBL = !m_IBLParameterSvc.empty() && m_IBLParameterSvc->containsIBL();
179
180 if (m_doIBL && !m_IBLParameterSvc->contains3D()) {
181 ATH_MSG_WARNING("Assuming hybrid 2D/3D IBL module composition, but geometry is all-planar");
182 }
183
184 /* Retrieve track to vertex from ToolService */
185 if (m_trackToVertex.retrieve().isFailure()) {
186 ATH_MSG_FATAL("Failed to retrieve tool " << m_trackToVertex);
187 return StatusCode::FAILURE;
188 }
189 ATH_MSG_DEBUG("Retrieved tool " << m_trackToVertex);
190
191 if (!m_hitSummaryTool.empty()) {
192 /* Retrieve hit summary tool from ToolService */
193 if (m_hitSummaryTool.retrieve().isFailure()) {
194 ATH_MSG_FATAL("Failed to retrieve tool " << m_hitSummaryTool);
195 return StatusCode::FAILURE;
196 }
197 ATH_MSG_DEBUG("Retrieved tool " << m_hitSummaryTool);
198
199 } else {
200 m_hitSummaryTool.disable();
201 }
203
205
206 StatusCode sc(StatusCode::SUCCESS);
207 m_copyEProbabilities.clear();
210
211 if (!m_copyExtraSummaryName.empty()) {
212 std::map<std::string, std::pair<Trk::eProbabilityType, bool>> eprob_map;
213 std::map<std::string, Trk::SummaryType> extra_summary_type_map;
214 createEProbabilityMap(eprob_map);
215 createExtraSummaryTypeMap(extra_summary_type_map);
216
217 std::vector<std::string> errors;
218 for (const std::string& eprob_to_copy : m_copyExtraSummaryName) {
219 std::map<std::string, std::pair<Trk::eProbabilityType, bool>>::const_iterator eprob_iter =
220 eprob_map.find(eprob_to_copy);
221 if (eprob_iter == eprob_map.end()) {
222 std::map<std::string, Trk::SummaryType>::const_iterator extra_summary_type_iter =
223 extra_summary_type_map.find(eprob_to_copy);
224 if (extra_summary_type_iter == extra_summary_type_map.end()) {
225 errors.push_back(eprob_to_copy);
226 } else {
227 m_decorateSummaryTypes.emplace_back(
228 SG::AuxElement::Accessor<uint8_t>(extra_summary_type_iter->first),
229 extra_summary_type_iter->second);
230 }
231 } else {
232 if (!eprob_iter->second.second) {
233 m_copyEProbabilities.push_back(eprob_iter->second.first);
234 } else {
235 m_decorateEProbabilities.emplace_back(SG::AuxElement::Accessor<float>(eprob_iter->first),
236 eprob_iter->second.first);
237 }
238 }
239 }
240
241 if (!errors.empty()) {
242 ATH_MSG_ERROR("Error in configuration. Unknown electron probability name: "
243 << errors << ". known are " << eprob_map << " " << extra_summary_type_map);
244 sc = StatusCode::FAILURE;
245 }
246 }
247
248 ATH_CHECK( m_eProbabilityTool.retrieve( DisableTool{m_eProbabilityTool.empty()} ) );
249 ATH_CHECK( m_dedxtool.retrieve( DisableTool{m_dedxtool.empty()} ) );
250 ATH_CHECK( m_testPixelLayerTool.retrieve( DisableTool{m_testPixelLayerTool.empty()} ) );
251
252 ATH_CHECK(m_assoMapContainer.initialize(!m_assoMapContainer.key().empty()));
254 !m_clusterSplitProbContainer.key().empty()));
255
256 ATH_MSG_VERBOSE(" initialize successful.");
257 return sc;
258}
259
262 const Trk::Track& track,
264 const xAOD::Vertex* vxCandidate,
265 xAOD::ParticleHypothesis prtOrigin) const
266{
267 const Trk::Perigee* aPer = nullptr;
268 const Trk::TrackParameters* parsToBeDeleted = nullptr;
269 // Origin
270 if (m_perigeeExpression == "Origin") {
271 aPer = track.perigeeParameters();
272 if (aPer) {
273 // aMeasPer clone will be created later if all perigee option selected
274 if (m_keepAllPerigee) {
275 aPer = nullptr;
276 }
277 } else {
278 const Amg::Vector3D persf(0, 0, 0);
279 const Trk::Perigee* result = m_trackToVertex->perigeeAtVertex(ctx, track, persf).release();
280 if (result != nullptr) {
281 aPer = result;
282 parsToBeDeleted = result;
283 } else {
284 ATH_MSG_WARNING("Could not extrapolate to 0,0,0. No TrackParticle created.");
285 return nullptr;
286 }
287 }
288 // Beamspot
289 } else if (m_perigeeExpression == "BeamSpot") {
290 const Trk::Perigee* result = m_trackToVertex->perigeeAtVertex(ctx, track, CacheBeamSpotData(ctx)->beamVtx().position()).release();
291 if (!result) {
292 ATH_MSG_WARNING("Failed to extrapolate to first Beamspot - No TrackParticle created.");
293 return nullptr;
294 }
295 parsToBeDeleted = result;
296 aPer = result;
297 }
298 // the non default way, express the perigee wrt. the vertex position
299 else if (m_perigeeExpression == "Vertex") {
300 if (vxCandidate != nullptr) {
301 const Trk::Perigee* result = m_trackToVertex->perigeeAtVertex(ctx, track, vxCandidate->position()).release();
302 if (result != nullptr) {
303 parsToBeDeleted = result;
304 aPer = result;
305 } else {
306 ATH_MSG_WARNING("Could not extrapolate track to vertex region! No TrackParticle created.");
307 return nullptr;
308 }
309 } else {
310 ATH_MSG_WARNING("Perigee expression at Vertex, but no vertex found! No TrackParticle created.");
311 }
312 //BeamLine
313 } else if (m_perigeeExpression == "BeamLine") {
314 const Trk::Perigee* result = m_trackToVertex->perigeeAtBeamline(ctx, track, CacheBeamSpotData(ctx)).release();
315 if (!result) {
316 ATH_MSG_WARNING("Failed to extrapolate to Beamline - No TrackParticle created.");
317 return nullptr;
318 }
319 parsToBeDeleted = result;
320 aPer = result;
321 }
322 /*
323 * We start from the existing summary
324 * and see what we want to add
325 */
326 std::unique_ptr<Trk::TrackSummary> updated_summary;
327 const Trk::TrackSummary* summary = track.trackSummary();
328 if (m_trackSummaryTool.get() != nullptr) {
329 if (!track.trackSummary() || m_updateTrackSummary) {
330 updated_summary = m_trackSummaryTool->summary(ctx, track);
331 summary = updated_summary.get();
332 }
333 } else {
335 "No proper TrackSummaryTool found. Creating TrackParticle with a TrackSummary on track");
336 }
337 if (!summary) {
338 ATH_MSG_WARNING("Track particle created for a track without a track summary");
339 }
340
341 // find the first and the last hit in track
342 // we do that the same way as in the track slimming tool!
343 // that way it is also ok on not slimmed tracks!
344 std::vector<const Trk::TrackParameters*> parameters;
345 std::vector<xAOD::ParameterPosition> parameterPositions;
346
347 int nbc_meas_A1 = 0;
348 int nbc_meas_B3 = 0;
349 int nbc_meas_A1_or_B3 = 0;
350 int nbc_meas_A1_or_B3_or_C = 0;
351
352 int isBC_A1 = 0;
353 int isBC_B3 = 0;
354 int isBC_C = 0;
355
356 const Trk::TrackStates* trackStates = track.trackStateOnSurfaces();
357 const Trk::TrackParameters* first(nullptr);
358 const Trk::TrackParameters* tp(nullptr);
359
360 if (m_badclusterID != 0) {
361 for (const TrackStateOnSurface* tsos : *trackStates) {
362 if (tsos->type(TrackStateOnSurface::Measurement) && tsos->trackParameters() != nullptr &&
363 tsos->measurementOnTrack() != nullptr &&
364 !(tsos->measurementOnTrack()->type(Trk::MeasurementBaseType::PseudoMeasurementOnTrack))) {
365 tp = tsos->trackParameters();
366
367 const InDet::SiClusterOnTrack* clus =
368 dynamic_cast<const InDet::SiClusterOnTrack*>(tsos->measurementOnTrack());
369 if (!clus) {
370 ATH_MSG_DEBUG("Failed dynamic_cast to InDet::SiClusterOnTrack ");
371 continue;
372 }
373 const Trk::PrepRawData* prdc = nullptr;
374 prdc = clus->prepRawData();
375 if (!prdc) {
376 ATH_MSG_DEBUG("No PRD for Si cluster");
377 }
378 const InDet::SiCluster* RawDataClus = dynamic_cast<const InDet::SiCluster*>(clus->prepRawData());
379 if (!RawDataClus) {
380 ATH_MSG_DEBUG("No RDC for Si cluster");
381 continue;
382 }
383 const Trk::MeasurementBase* mesb = tsos->measurementOnTrack();
384
385 if (RawDataClus->detectorElement()->isPixel()) {
386 const InDetDD::SiDetectorElement* element = nullptr;
388 dynamic_cast<const InDet::PixelCluster*>(RawDataClus);
389 if (!pixelCluster) {
390 ATH_MSG_DEBUG("Pixel cluster null though detector element matches pixel");
391 }
392
393 else {
394 float size = pixelCluster->rdoList().size();
395 float tot = pixelCluster->totalToT();
396 float charge = pixelCluster->totalCharge();
397 float cotthetaz = -1;
398 int zWidth = -1;
399
400 element = pixelCluster->detectorElement();
401 if (!element)
402 ATH_MSG_DEBUG("No element for track incidence angles!");
403 float PixTrkAngle = -1000;
404 float PixTrkThetaI = -1000;
405 float theta = -1000;
406 if (element) {
407 const Amg::Vector3D& my_track = tp->momentum();
408 const Amg::Vector3D& my_normal = element->normal();
409 const Amg::Vector3D& my_phiax = element->phiAxis();
410 const Amg::Vector3D& my_etaax = element->etaAxis();
411 // track component on etaAxis:
412 float trketacomp = my_track.dot(my_etaax);
413 // track component on phiAxis:
414 float trkphicomp = my_track.dot(my_phiax);
415 // track component on the normal to the module
416 float trknormcomp = my_track.dot(my_normal);
417 // Track angle
418 PixTrkAngle = std::atan2(trkphicomp, trknormcomp);
419 PixTrkThetaI = std::atan2(trketacomp, trknormcomp);
420 float length = std::sqrt(trketacomp * trketacomp + trkphicomp * trkphicomp + trknormcomp * trknormcomp);
421 theta = std::acos(trknormcomp / length);
422 cotthetaz = 1. / std::tan(PixTrkThetaI);
423
424 // reducing the angle in the right quadrant
425 // M_PI (pi) and M_PI_2 (pi/2.) are defined in cmath.
426 if (PixTrkThetaI > M_PI_2)
427 PixTrkThetaI -= M_PI;
428 else if (PixTrkThetaI < -M_PI_2)
429 PixTrkThetaI += M_PI;
430 PixTrkThetaI = M_PI_2 - PixTrkThetaI;
431 if (PixTrkAngle > M_PI_2)
432 PixTrkAngle -= M_PI;
433 else if (PixTrkAngle < -M_PI_2)
434 PixTrkAngle += M_PI;
435 PixTrkAngle = M_PI_2 - PixTrkAngle;
436 if (theta > M_PI_2)
437 theta = M_PI - theta;
438 }
439
440 Identifier surfaceID;
442 if (m_detID->is_pixel(surfaceID)) {
443 const InDet::SiWidth& width = pixelCluster->width();
444 zWidth = static_cast<int>(width.colRow().y());
445 }
446
447 int isIBLclus = false;
448 if (m_doIBL && m_pixelID->barrel_ec(surfaceID) == 0 &&
449 m_pixelID->layer_disk(surfaceID) == 0) {
450 isIBLclus = true;
451 }
452
453 // count bad clusters
454 if (!isIBLclus) {
455 if ((size == 1 && tot < 8) || (size == 2 && tot < 15)) {
456 isBC_A1 = true;
457 nbc_meas_A1++;
458 }
459 // Need to replace these magic numbers with constexpr with meaning full names
460 if (charge < 13750. / std::cos(theta) - 22500.) {
461 isBC_B3 = true;
462 nbc_meas_B3++;
463 }
464 if (isBC_A1 || isBC_B3) {
465 nbc_meas_A1_or_B3++;
466 }
467 if ((zWidth == 1 && cotthetaz > 5.8) || (zWidth == 2 && cotthetaz > 5.8) ||
468 (zWidth == 3 && cotthetaz > 6.2) || (zWidth > 3 && cotthetaz < 2.5)) {
469 isBC_C = true;
470 }
471 if (isBC_A1 || isBC_B3 || isBC_C) {
472 nbc_meas_A1_or_B3_or_C++;
473 }
474 }
475 }
476 }
477 }
478 }
479 }
481 // search first valid TSOS first
482 for (const TrackStateOnSurface* tsos : *trackStates) {
483 if (tsos->type(TrackStateOnSurface::Measurement) && tsos->trackParameters() != nullptr &&
484 tsos->measurementOnTrack() != nullptr &&
485 !(tsos->measurementOnTrack()->type(Trk::MeasurementBaseType::PseudoMeasurementOnTrack))) {
486 first = tsos->trackParameters();
487 parameters.push_back(tsos->trackParameters());
488 parameterPositions.push_back(xAOD::FirstMeasurement);
489 break;
490 }
491 }
492
494 // search last valid TSOS first
495 for (Trk::TrackStates::const_reverse_iterator rItTSoS = trackStates->rbegin();
496 rItTSoS != trackStates->rend();
497 ++rItTSoS) {
498 if ((*rItTSoS)->type(TrackStateOnSurface::Measurement) &&
499 (*rItTSoS)->trackParameters() != nullptr && (*rItTSoS)->measurementOnTrack() != nullptr &&
500 !((*rItTSoS)->measurementOnTrack()->type(
502 if (!(first == (*rItTSoS)->trackParameters())) {
503 parameters.push_back((*rItTSoS)->trackParameters());
504 parameterPositions.push_back(xAOD::LastMeasurement);
505 }
506 break;
507 }
508 }
509 }
510
511 // security check:
512 if (parameters.size() > 2)
513 ATH_MSG_WARNING("More than two additional track parameters to be stored in TrackParticle!");
514 }
515
516 // KeepAllPerigee will keep all perigee's on the track plus the parameters at the first
517 // measurement, provided this measurement precedes any second perigee. The track (initial) perigee
518 // is the 'defining parameter' for the TrackParticle, by convention this is pushed to the back of
519 // the parameter vector by the TP constructor.
520 else if (m_keepAllPerigee) {
521 bool haveFirstMeasurementParameters = false;
522 for (const TrackStateOnSurface* tsos : *(track.trackStateOnSurfaces())) {
523 if (!tsos->trackParameters())
524 continue;
525
526 if (!haveFirstMeasurementParameters && tsos->type(TrackStateOnSurface::Measurement) &&
527 !tsos->type(TrackStateOnSurface::Outlier) && tsos->measurementOnTrack() &&
528 !(tsos->measurementOnTrack()->type(Trk::MeasurementBaseType::PseudoMeasurementOnTrack))) {
529 haveFirstMeasurementParameters = true;
530 parameters.push_back(tsos->trackParameters());
531 ATH_MSG_VERBOSE(" including first measurement parameters at R "
532 << tsos->trackParameters()->position().perp() << ", Z "
533 << tsos->trackParameters()->position().z());
534 parameterPositions.push_back(xAOD::FirstMeasurement);
535 continue;
536 }
537 if (!tsos->type(TrackStateOnSurface::Perigee) ||
538 !(tsos->trackParameters()->surfaceType() == Trk::SurfaceType::Perigee) ||
539 !(tsos->trackParameters()->type() == Trk::AtaSurface)) {
540 continue;
541 }
542 if (!aPer) {
543 aPer = static_cast<const Perigee*>(tsos->trackParameters());
544 } else {
545 parameters.push_back(tsos->trackParameters());
546 }
547
548 ATH_MSG_VERBOSE(" including perigee at R " << tsos->trackParameters()->position().perp() << ", Z "
549 << tsos->trackParameters()->position().z());
550
551 // we are not interested in keeping measurement parameters after any second perigee
552 if (!parameters.empty())
553 haveFirstMeasurementParameters = true;
554 }
555 }
556
557 xAOD::TrackParticle* trackparticle = createParticle(ctx,
558 aPer,
559 track.fitQuality(),
560 &track.info(),
561 summary,
562 parameters,
563 parameterPositions,
564 prtOrigin,
565 container,
566 &track);
567
568 static const SG::AuxElement::Accessor<int> nbCmeas("nBC_meas");
569 switch (m_badclusterID) {
570 case 1: {
571 nbCmeas(*trackparticle) = nbc_meas_A1;
572 break;
573 }
574 case 2: {
575 nbCmeas(*trackparticle) = nbc_meas_B3;
576 break;
577 }
578 case 3: {
579 nbCmeas(*trackparticle) = nbc_meas_A1_or_B3;
580 break;
581 }
582 case 4: {
583 nbCmeas(*trackparticle) = nbc_meas_A1_or_B3_or_C;
584 break;
585 }
586 default: {
587 }
588 }
589
590 delete parsToBeDeleted;
591 return trackparticle;
592}
593
596 const Rec::TrackParticle& trackParticle,
597 xAOD::TrackParticleContainer* container) const
598{
599
600 // Attempt to fill the position enums - will necessarily be a bit of a hack, since we don't have
601 // all the information.
602 std::vector<xAOD::ParameterPosition> positions;
603 bool firstMeasurement = false;
604 for (const auto* parameter : trackParticle.trackParameters()) {
605 if (!firstMeasurement && parameter && !parameter->associatedSurface().isFree()) {
606 // if the surface isn't free, it must belong to a detector element => measurement
607 firstMeasurement = true;
608 positions.push_back(xAOD::FirstMeasurement);
609 } else if (firstMeasurement && parameter && !parameter->associatedSurface().isFree()) {
610 // Making the (possibly unfounded assumption that if we have the first measurement, the next
611 // will be the last)
612 positions.push_back(xAOD::LastMeasurement);
613 } else {
614 positions.push_back(xAOD::BeamLine); // Don't have a default yet!
615 }
616 }
617
618 xAOD::TrackParticle* trackparticle =
619 createParticle(ctx,
620 trackParticle.measuredPerigee(),
621 trackParticle.fitQuality(),
622 &trackParticle.info(),
623 trackParticle.trackSummary(),
624 trackParticle.trackParameters(),
625 positions,
626 static_cast<xAOD::ParticleHypothesis>(trackParticle.info().particleHypothesis()),
627 container,
628 nullptr);
629
630 if (!trackparticle) {
631 ATH_MSG_WARNING("WARNING: Problem creating TrackParticle - Returning 0");
632 return nullptr;
633 }
634
635 trackparticle->setTrackLink(*(trackParticle.trackElementLink()));
636
638 compare(trackParticle, *trackparticle);
639
640 return trackparticle;
641}
642
645 const ElementLink<TrackCollection>& trackLink,
647 const xAOD::Vertex* vxCandidate,
648 xAOD::ParticleHypothesis prtOrigin) const
649{
650
651 xAOD::TrackParticle* trackparticle =
652 createParticle(ctx, **trackLink, container, vxCandidate, prtOrigin);
653
654 if (!trackparticle) {
655 ATH_MSG_WARNING("WARNING: Problem creating TrackParticle - Returning 0");
656 return nullptr;
657 }
658
659 trackparticle->setTrackLink(trackLink);
660
661 return trackparticle;
662}
663
665 const EventContext& ctx,
666 const Perigee* perigee,
667 const FitQuality* fq,
668 const TrackInfo* trackInfo,
669 const TrackSummary* summary,
670 const std::vector<const Trk::TrackParameters*>& parameters,
671 const std::vector<xAOD::ParameterPosition>& positions,
672 xAOD::ParticleHypothesis prtOrigin,
673 xAOD::TrackParticleContainer* container) const {
674 return createParticle(ctx,perigee, fq, trackInfo, summary, parameters, positions, prtOrigin, container, nullptr);
675}
676
679 const Perigee* perigee,
680 const FitQuality* fq,
681 const TrackInfo* trackInfo,
682 const TrackSummary* summary,
683 const std::vector<const Trk::TrackParameters*>& parameters,
684 const std::vector<xAOD::ParameterPosition>& positions,
685 xAOD::ParticleHypothesis prtOrigin,
687 const Trk::Track *track) const
688{
689
690 xAOD::TrackParticle* trackparticle = new xAOD::TrackParticle;
691 if (!trackparticle) {
692 ATH_MSG_WARNING("WARNING: Problem creating TrackParticle - Returning 0");
693 return nullptr;
694 }
695 /*
696 * The following needs care as in one case the ownership
697 * can be passed to StoreGate i.e to the relevant container
698 * DataVector.
699 * In the other the caller has the ownership
700 */
701
702 if (container) {
703 container->push_back(trackparticle);
704 } else {
705 trackparticle->makePrivateStore();
706 }
707
708 // Fit quality
709 if (fq) {
710 setFitQuality(*trackparticle, *fq);
711 }
712 // Track Info
713 if (trackInfo) {
714 setTrackInfo(*trackparticle, *trackInfo, prtOrigin);
715 }
716 // track summary
717 if (summary) {
718 setTrackSummary(*trackparticle, *summary);
719 setHitPattern(*trackparticle, summary->getHitPattern());
720 addPIDInformation(ctx, track, *trackparticle);
721 if(m_doITk) addDetailedHitInformation(track->trackStateOnSurfaces(), *trackparticle);
722 }
723
724 if (m_computeAdditionalInfo && track!=nullptr) {
725 addExpectedHitInformation(track->perigeeParameters(), *trackparticle);
726 addOutlierHitInformation(track->trackStateOnSurfaces(), *trackparticle);
727 if(m_doSharedSiHits || m_doSharedTRTHits) addSharedHitInformation(track, *trackparticle);
728 else if(m_doITk) addDummyEndcapSharedHitInformation(*trackparticle);
729 }
730
731 const auto* beamspot = CacheBeamSpotData(ctx);
732 if (beamspot) {
733 setTilt(*trackparticle, beamspot->beamTilt(0), beamspot->beamTilt(1));
734 }
735 // Parameters
736 if (perigee) {
737 setDefiningParameters(*trackparticle, *perigee);
738 } else {
739 ATH_MSG_WARNING("Track without perigee parameters? Not setting any defining parameters!");
740 }
741 setParameters(ctx, *trackparticle, parameters, positions);
742
743 return trackparticle;
744}
745
746void
748{
749 int index = Amg::compare(tp1.parameters(), tp2.parameters(), 1e-6, true);
750 if (index != -1) {
751 ATH_MSG_WARNING("Bad parameters conversion " << Amg::toString(tp1.parameters(), 7) << " --- "
752 << Amg::toString(tp2.parameters(), 7));
753 }
754 if ((tp1.covariance() && !tp2.covariance()) || (!tp1.covariance() && tp2.covariance())) {
755 ATH_MSG_WARNING("Bad Covariance conversion " << tp1.covariance() << " --- " << tp2.covariance());
756 } else if (tp1.covariance() && tp2.covariance()) {
757 std::pair<int, int> indices = Amg::compare(*tp1.covariance(), *tp2.covariance(), 1e-6, true);
758 if (indices.first != -1)
759 ATH_MSG_WARNING("Bad Covariance conversion " << std::endl
760 << Amg::toString(*tp1.covariance(), 10) << std::endl
761 << Amg::toString(*tp2.covariance(), 10));
762 }
763}
764
765void
767{
768 if (tp.measuredPerigee()) {
770 }
771
772 // trackParticle.info(),trackParticle.trackSummary(),
773 if (tp.trackParameters().size() != tpx.numberOfParameters()) {
774 ATH_MSG_WARNING("Number of parameters not the same " << tp.trackParameters().size() << " --- "
775 << tpx.numberOfParameters());
776 }
777}
778
779void
782 const std::vector<const Trk::TrackParameters*>& parameters,
783 const std::vector<xAOD::ParameterPosition>& positions) const
784{
785 std::vector<std::vector<float>> parametersVec;
786 parametersVec.resize(parameters.size());
787 unsigned int numParam = 0;
788
790 const AtlasFieldCacheCondObj* fieldCondObj{ *readHandle };
791 if (!fieldCondObj)[[unlikely]]{
792 ATH_MSG_ERROR("fieldCondObj is nullptr in TrackParticleCreatorTool::setParameters");
793 return;
794 }
795 MagField::AtlasFieldCache fieldCache;
796 //cppcheck-suppress nullPointerRedundantCheck
797 fieldCondObj->getInitializedCache(fieldCache);
798
799 for (const auto* param : parameters) {
800 std::vector<float>& values = parametersVec[numParam];
801 values.resize(6);
802 const Amg::Vector3D& pos = param->position();
803 const Amg::Vector3D& mom = param->momentum();
804 values[0] = pos[0];
805 values[1] = pos[1];
806 values[2] = pos[2];
807 values[3] = mom[0];
808 values[4] = mom[1];
809 values[5] = mom[2];
810
811 const bool straightPars = (!fieldCache.solenoidOn() && m_trackingVolumesSvc->volume(Trk::ITrackingVolumesSvc::CalorimeterEntryLayer).inside(pos)) ||
814 AmgSymMatrix(5) covarianceMatrix;
815 covarianceMatrix.setIdentity();
816
817 if (param->covariance()) {
818 // has covariance matrix
819 // now convert from to Curvilinear -- to be double checked for correctness
820 CurvilinearUVT curvilinearUVT(mom.unit());
821 if (!straightPars){
822 Amg::Vector3D magnFieldVect;
823 magnFieldVect.setZero();
824 fieldCache.getField(pos.data(), magnFieldVect.data());
825 const Amg::Transform3D& localToGlobalTransform = param->associatedSurface().transform();
826
827 JacobianLocalToCurvilinear jacobian(magnFieldVect,
828 param->parameters()[Trk::qOverP],
829 std::sin(param->parameters()[Trk::theta]),
830 curvilinearUVT,
831 localToGlobalTransform.rotation().col(0),
832 localToGlobalTransform.rotation().col(1));
833
834 covarianceMatrix = param->covariance()->similarity(jacobian);
835 } else {
836 const Amg::Vector3D loc_x {param->parameters()[Trk::locX],0,0};
837 const Amg::Vector3D loc_y {0,param->parameters()[Trk::locY],0};
838 JacobianLocalToCurvilinear jacobian(curvilinearUVT, loc_x, loc_y);
839 covarianceMatrix = param->covariance()->similarity(jacobian);
840 }
841 }
842 std::vector<float> covMatrixVec;
843 Amg::compress(covarianceMatrix, covMatrixVec);
844 tp.setTrackParameterCovarianceMatrix(numParam, covMatrixVec);
845
846 ++numParam;
847 }
848
849 tp.setTrackParameters(parametersVec);
850 unsigned int i = 0;
851 for (; i < positions.size(); ++i) {
852 tp.setParameterPosition(i, positions[i]);
853 if (positions[i] == xAOD::FirstMeasurement) {
854 float x_position = tp.parameterX(i);
855 float y_position = tp.parameterY(i);
856 tp.setRadiusOfFirstHit(std::sqrt(x_position * x_position + y_position * y_position));
858 parameters[i]->associatedSurface().associatedDetectorElementIdentifier().get_compact());
859 }
860 }
861}
862
863void
865{
866 tp.setBeamlineTiltX(tiltx);
867 tp.setBeamlineTiltY(tilty);
868}
869
870void
872{
873 tp.setHitPattern(hitpattern);
874}
875
876void
881
882void
887
888void
890{
891 // ensure that xAOD TrackSummary and TrackSummary enums are in sync.
892 constexpr unsigned int xAodReferenceEnum1 = static_cast<unsigned int>(xAOD::numberOfTRTXenonHits);
893 constexpr unsigned int TrkReferenceEnum1 = static_cast<unsigned int>(Trk::numberOfTRTXenonHits);
894 static_assert(xAodReferenceEnum1 == TrkReferenceEnum1, "Trk and xAOD enums differ in their indices");
895 constexpr unsigned int xAodReferenceEnum2 = static_cast<unsigned int>(xAOD::numberOfTRTTubeHits);
896 constexpr unsigned int TrkReferenceEnum2 = static_cast<unsigned int>(Trk::numberOfTRTTubeHits);
897 static_assert(xAodReferenceEnum2 == TrkReferenceEnum2, "Trk and xAOD enums differ in their indices");
898
899 for (unsigned int i = 0; i < Trk::numberOfTrackSummaryTypes; i++) {
900 // Only add values which are +ve (i.e., which were created)
902 continue;
903 }
905 continue;
906 }
908 continue;
909 }
910 // skip values which are floats
911 if (std::find(unusedSummaryTypes.begin(), unusedSummaryTypes.end(), i) != unusedSummaryTypes.end()) {
912 continue;
913 }
915 continue;
916 }
917 if (m_doITk && i == Trk::numberOfContribPixelLayers){ // Filled in addDetailedHitInformation for ITk
918 continue;
919 }
920
921 int value = summary.get(static_cast<Trk::SummaryType>(i));
922 uint8_t uvalue = static_cast<uint8_t>(std::min(value,255));
923 // coverity[first_enum_type]
924 if (value > 0) {
925 tp.setSummaryValue(uvalue, static_cast<xAOD::SummaryType>(i));
926 }
927 }
928
929 // muon hit info
930 if (!m_hitSummaryTool.empty()) {
931 ATH_MSG_DEBUG("now do muon hit info");
933 uint8_t numberOfPrecisionLayers = msSummary.nprecisionLayers;
934 ATH_MSG_DEBUG("# of prec layers: " << static_cast<unsigned int>(numberOfPrecisionLayers));
935 uint8_t numberOfPrecisionHoleLayers = msSummary.nprecisionHoleLayers;
936 uint8_t numberOfPhiLayers = msSummary.nphiLayers;
937 uint8_t numberOfPhiHoleLayers = msSummary.nphiHoleLayers;
938 uint8_t numberOfTriggerEtaLayers = msSummary.ntrigEtaLayers;
939 uint8_t numberOfTriggerEtaHoleLayers = msSummary.ntrigEtaHoleLayers;
940 tp.setSummaryValue(numberOfPrecisionLayers, xAOD::numberOfPrecisionLayers);
941 tp.setSummaryValue(numberOfPrecisionHoleLayers, xAOD::numberOfPrecisionHoleLayers);
942 tp.setSummaryValue(numberOfPhiLayers, xAOD::numberOfPhiLayers);
943 tp.setSummaryValue(numberOfPhiHoleLayers, xAOD::numberOfPhiHoleLayers);
944 tp.setSummaryValue(numberOfTriggerEtaLayers, xAOD::numberOfTriggerEtaLayers);
945 tp.setSummaryValue(numberOfTriggerEtaHoleLayers, xAOD::numberOfTriggerEtaHoleLayers);
946 }
947
948}
949
950void
951TrackParticleCreatorTool::addPIDInformation(const EventContext& ctx, const Trk::Track *track, xAOD::TrackParticle& tp) const
952{
953 // TRT PID information
954 {
955 static const std::vector<float> eProbabilityDefault(numberOfeProbabilityTypes,0.5);
956 constexpr int initialValue{-1};
957 std::vector<float> eProbability_tmp;
958 const std::vector<float>& eProbability(
959 track && !m_eProbabilityTool.empty()
960 ? eProbability_tmp =
961 m_eProbabilityTool->electronProbability(ctx, *track)
963 int nHits = track && !m_eProbabilityTool.empty()
965 : initialValue;
966 for (const Trk::eProbabilityType& copy : m_copyEProbabilities) {
967 float eProbability_value = eProbability.at(copy);
968 tp.setSummaryValue(eProbability_value, static_cast<xAOD::SummaryType>(copy + xAOD::eProbabilityComb));
969 }
970 for (const std::pair<SG::AuxElement::Accessor<float>, Trk::eProbabilityType>& decoration :
972 float fvalue = eProbability.at(decoration.second);
973 decoration.first(tp) = fvalue;
974 }
975 // now the extra summary types
976 for (const std::pair<SG::AuxElement::Accessor<uint8_t>, Trk::SummaryType>& decoration :
978 uint8_t summary_value = nHits;
979 decoration.first(tp) = summary_value;
980 }
981
982 }
983
984 // PixelPID
985 {
986 const int initialValue{-1};
987 float dedx = initialValue;
988 int nHitsUsed_dEdx = initialValue;
989 int nOverflowHits_dEdx = initialValue;
990 if (track && !m_dedxtool.empty() && track->info().trackFitter() != TrackInfo::Unknown) {
991 dedx = m_dedxtool->dEdx(ctx, *track, nHitsUsed_dEdx, nOverflowHits_dEdx);
992 }
993 tp.setNumberOfUsedHitsdEdx(nHitsUsed_dEdx);
994 tp.setNumberOfIBLOverflowsdEdx(nOverflowHits_dEdx);
995 tp.setSummaryValue(dedx, static_cast<xAOD::SummaryType>(51));
996 }
997}
998
999void
1001{
1002
1003 Trk::DetailedHitInfo detailedInfo;
1004
1005 for (const TrackStateOnSurface* tsos : *trackStates) {
1006
1007 const Trk::MeasurementBase* mesb = tsos->measurementOnTrack();
1008 if(mesb==nullptr) continue;
1009 // Check if the measurement type is RIO on Track (ROT)
1010 const RIO_OnTrack* rot = nullptr;
1012 rot = static_cast<const RIO_OnTrack*>(mesb);
1013 }
1014 if(rot==nullptr) continue;
1015
1016 const Identifier& id = rot->identify();
1017 if(!m_pixelID->is_pixel(id)) continue;
1018
1019 Trk::DetectorRegion region;
1020 const InDetDD::SiDetectorElement* detEl = static_cast<const InDetDD::SiDetectorElement*>(rot->detectorElement());
1024 else region = Trk::pixelEndcap;
1025
1026 detailedInfo.addHit(region, m_pixelID->layer_disk(id), m_pixelID->eta_module(id));
1027
1028 }
1029
1030 uint8_t nContribPixelLayers = static_cast<uint8_t>(detailedInfo.getPixelContributions());
1031
1032 uint8_t nContribPixelBarrelFlatLayers = static_cast<uint8_t>(detailedInfo.getContributionFromRegion(Trk::pixelBarrelFlat ));
1033 uint8_t nContribPixelBarrelInclinedLayers = static_cast<uint8_t>(detailedInfo.getContributionFromRegion(Trk::pixelBarrelInclined));
1034 uint8_t nContribPixelBarrelLayers = static_cast<uint8_t>(nContribPixelBarrelFlatLayers+nContribPixelBarrelInclinedLayers);
1035 uint8_t nContribPixelEndcap = static_cast<uint8_t>(detailedInfo.getContributionFromRegion(Trk::pixelEndcap ));
1036
1037 uint8_t nPixelBarrelFlatHits = static_cast<uint8_t>(detailedInfo.getHitsFromRegion(Trk::pixelBarrelFlat ));
1038 uint8_t nPixelBarrelInclinedHits = static_cast<uint8_t>(detailedInfo.getHitsFromRegion(Trk::pixelBarrelInclined));
1039 uint8_t nPixelBarrelHits = static_cast<uint8_t>(nPixelBarrelFlatHits+nPixelBarrelInclinedHits);
1040 uint8_t nPixelEndcapHits = static_cast<uint8_t>(detailedInfo.getHitsFromRegion(Trk::pixelEndcap ));
1041
1042 uint8_t nInnermostPixelLayerEndcapHits = static_cast<uint8_t>(detailedInfo.getHits(Trk::pixelEndcap, 0));
1043 uint8_t nNextToInnermostPixelLayerEndcapHits = static_cast<uint8_t>(detailedInfo.getHits(Trk::pixelEndcap, 1)
1044 + detailedInfo.getHits(Trk::pixelEndcap, 2)); // L0.5 shorties + L1
1045
1046 tp.setSummaryValue(nContribPixelLayers, xAOD::numberOfContribPixelLayers);
1047 tp.setSummaryValue(nContribPixelBarrelLayers, xAOD::numberOfContribPixelBarrelLayers);
1048 tp.setSummaryValue(nContribPixelEndcap, xAOD::numberOfContribPixelEndcap);
1050 tp.setSummaryValue(nPixelBarrelHits, xAOD::numberOfPixelBarrelHits);
1051 tp.setSummaryValue(nContribPixelBarrelFlatLayers, xAOD::numberOfContribPixelBarrelFlatLayers);
1052 tp.setSummaryValue(nContribPixelBarrelInclinedLayers, xAOD::numberOfContribPixelBarrelInclinedLayers);
1053 tp.setSummaryValue(nPixelBarrelFlatHits, xAOD::numberOfPixelBarrelFlatHits);
1054 tp.setSummaryValue(nPixelBarrelInclinedHits, xAOD::numberOfPixelBarrelInclinedHits);
1055 tp.setSummaryValue(nPixelEndcapHits, xAOD::numberOfPixelEndcapHits);
1056 }
1057 tp.setSummaryValue(nInnermostPixelLayerEndcapHits, xAOD::numberOfInnermostPixelLayerEndcapHits);
1058 tp.setSummaryValue(nNextToInnermostPixelLayerEndcapHits, xAOD::numberOfNextToInnermostPixelLayerEndcapHits);
1059
1060}
1061
1062void
1064{
1065
1066 if(m_testPixelLayerTool.empty() || perigee==nullptr) return;
1067
1068 uint8_t zero = static_cast<uint8_t>(0);
1069 uint8_t nContribPixLayers, nInPixHits, nNextInPixHits;
1070 if(!tp.summaryValue(nContribPixLayers, xAOD::numberOfContribPixelLayers)){
1071 nContribPixLayers = zero;
1072 }
1073 if(nContribPixLayers==0){
1074 ATH_MSG_DEBUG("No pixels on track, so wo do not expect hit in inner layers");
1077 }
1078
1079 else {
1080
1081 // Innermost pixel layer
1083 nInPixHits = zero;
1084 }
1085 if(nInPixHits>0){
1086 ATH_MSG_DEBUG("Innermost pixel Layer hit on track, so we expect an innermost pixel layer hit");
1087 uint8_t one = static_cast<uint8_t>(1);
1089 } else {
1090 uint8_t expectHit = static_cast<uint8_t>(m_testPixelLayerTool->expectHitInInnermostPixelLayer(perigee));
1092 }
1093
1094 // Next-to-innermost pixel layer
1096 nNextInPixHits = zero;
1097 }
1098 if(nNextInPixHits>0){
1099 ATH_MSG_DEBUG("Next-to-innermost pixel Layer hit on track, so we expect an next-to-innermost pixel layer hit");
1100 uint8_t one = static_cast<uint8_t>(1);
1102 } else {
1103 uint8_t expectHit = static_cast<uint8_t>(m_testPixelLayerTool->expectHitInNextToInnermostPixelLayer(perigee));
1105 }
1106
1107 } // end else if nContribPixLayers>0
1108
1109}
1110
1111void
1113{
1114
1115 uint8_t nPixOutliers = 0, nInPixOutliers = 0, nNInPixOutliers = 0, nSCTOutliers = 0;
1116 uint8_t nInEndcapPixOutliers = 0, nNInEndcapPixOutliers = 0;
1117
1118 for (const TrackStateOnSurface* tsos : *trackStates) {
1119
1120 bool isOutlier = tsos->type(Trk::TrackStateOnSurface::Outlier);
1121 if(!isOutlier) continue;
1122
1123 const Trk::MeasurementBase* mesb = tsos->measurementOnTrack();
1124 if(mesb==nullptr) continue;
1125 // Check if the measurement type is RIO on Track (ROT)
1126 const RIO_OnTrack* rot = nullptr;
1128 rot = static_cast<const RIO_OnTrack*>(mesb);
1129 }
1130 if (rot == nullptr)
1131 continue;
1132
1133 const Identifier& id = rot->identify();
1134
1135 if (m_pixelID->is_pixel(id)) {
1136 nPixOutliers++;
1137 int layer = m_pixelID->layer_disk(id);
1138 if (m_pixelID->is_barrel(id)) {
1139 if (layer == 0){
1140 nInPixOutliers++;
1141 }
1142 else if (layer == 1){
1143 nNInPixOutliers++;
1144 }
1145 } else if (m_doITk) { // isITk && isEndCap -> ITk specific counters
1146 if (layer == 0){
1147 nInEndcapPixOutliers++;
1148 }
1149 else if (layer == 1 || layer == 2){
1150 nNInEndcapPixOutliers++; // L0.5 + L1 disks
1151 }
1152 }
1153 }
1154 else if (m_sctID->is_sct(id)) {
1155 nSCTOutliers++;
1156 }
1157
1158 // TRT outliers are already filled in the InDetTrackSummaryHelperTool as
1159 // used in the ambi solver
1160 }
1161
1166
1167 if(m_doITk){
1170 }
1171
1172}
1173
1174void
1176{
1177
1178 uint8_t nPixSharedHits = 0, nInPixSharedHits = 0, nNInPixSharedHits = 0, nSCTSharedHits = 0, nTRTSharedHits = 0;
1179 uint8_t nInPixSharedEndcapHits = 0, nNInPixSharedEndcapHits = 0;
1180 uint8_t nPixSplitHits = 0, nInPixSplitHits = 0, nNInPixSplitHits = 0;
1181 uint8_t nInPixSplitEndcapHits = 0, nNInPixSplitEndcapHits = 0;
1182
1183 const DataVector<const Trk::MeasurementBase>* measurements = track->measurementsOnTrack();
1184 if(!measurements){
1185 ATH_MSG_DEBUG("No measurement on track");
1186 return;
1187 }
1188
1189 const EventContext& ctx = Gaudi::Hive::currentContext();
1191
1192 for (const auto* const ms : *measurements) {
1193 // check if it's a rot
1194 const Trk::RIO_OnTrack* rot = nullptr;
1196 rot = static_cast<const Trk::RIO_OnTrack*>(ms);
1197 }
1198 if (!rot) {
1199 ATH_MSG_DEBUG("Cannot cast measurement to RIO_OnTrack");
1200 continue;
1201 }
1202
1203 const Identifier& id = rot->identify();
1204
1205 if (m_doSharedSiHits && m_pixelID->is_pixel(id)) {
1206 // check if split, when running TIDE
1207 bool hitIsSplit(false);
1208 if (m_runningTIDE_Ambi) {
1209 const InDet::PixelClusterOnTrack* pix = nullptr;
1211 pix = static_cast<const InDet::PixelClusterOnTrack*>(rot);
1212 }
1213 if (pix) {
1214 const InDet::PixelCluster* pixPrd = pix->prepRawData();
1216 splitProb = getClusterSplittingProbability(pixPrd);
1217 int layer = m_pixelID->layer_disk(id);
1218 if (pixPrd and splitProb.isSplit()) {
1219 ATH_MSG_DEBUG("split Pixel hit found");
1220 hitIsSplit = true;
1221 nPixSplitHits++;
1222 if (m_pixelID->is_barrel(id)) {
1223 if (layer == 0)
1224 nInPixSplitHits++;
1225 else if (layer == 1)
1226 nNInPixSplitHits++;
1227 } else if (m_doITk) { // isITk && isEndCap -> ITk specific counters
1228 if (layer == 0)
1229 nInPixSplitEndcapHits++;
1230 else if (layer == 1 || layer == 2)
1231 nNInPixSplitEndcapHits++; // L0.5 + L1 disks
1232 }
1233 }
1234 }
1235 }
1236
1237 // check if shared
1238 // if we are running the TIDE ambi don't count split hits as shared
1239 if (!hitIsSplit) {
1240 if (prd_to_track_map->isShared(*(rot->prepRawData()))) {
1241 ATH_MSG_DEBUG("shared Pixel hit found");
1242 nPixSharedHits++;
1243 int layer = m_pixelID->layer_disk(id);
1244 if (m_pixelID->is_barrel(id)) {
1245 if (layer == 0)
1246 nInPixSharedHits++;
1247 else if (layer == 1)
1248 nNInPixSharedHits++;
1249 } else if (m_doITk) { // isITk && isEndCap -> ITk specific counters
1250 if (layer == 0)
1251 nInPixSharedEndcapHits++;
1252 else if (layer == 1 || layer == 2)
1253 nNInPixSharedEndcapHits++; // L0.5 + L1 disks
1254 }
1255 }
1256 }
1257
1258 } // end pixel
1259
1260 else if (m_doSharedSiHits && m_sctID->is_sct(id)) {
1261 if (prd_to_track_map->isShared(*(rot->prepRawData()))) {
1262 ATH_MSG_DEBUG("shared SCT hit found");
1263 nSCTSharedHits++;
1264 }
1265 }
1266
1267 else if (m_doSharedTRTHits && m_trtID->is_trt(id)) {
1268 if (prd_to_track_map->isShared(*(rot->prepRawData()))) {
1269 ATH_MSG_DEBUG("shared TRT hit found");
1270 nTRTSharedHits++;
1271 }
1272 }
1273 }
1274
1278
1282 tp.setSummaryValue(nSCTSharedHits, xAOD::numberOfSCTSharedHits);
1283 tp.setSummaryValue(nTRTSharedHits, xAOD::numberOfTRTSharedHits);
1284
1285 if(m_doITk){
1290 }
1291
1292}
1293
1294
1295void
1297{
1298
1299 uint8_t nInPixSharedEndcapHits = 0, nNInPixSharedEndcapHits = 0;
1300 uint8_t nInPixSplitEndcapHits = 0, nNInPixSplitEndcapHits = 0;
1301
1306
1307}
1308
1309
1312{
1313 const EventContext& ctx = Gaudi::Hive::currentContext();
1314 if (!pix || m_clusterSplitProbContainer.key().empty()) {
1316 }
1318 if (!splitProbContainer.isValid()) {
1319 ATH_MSG_FATAL("Failed to get cluster splitting probability container "
1321 }
1322 return splitProbContainer->splitProbability(pix);
1323}
1324
1325
1328{
1330 return beamSpotHandle.cptr();
1331}
1332
1333} // end of namespace Trk
#define M_PI
#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)
This class provides an interface to generate or decode an identifier for the upper levels of the dete...
double charge(const T &p)
Definition AtlasPID.h:1003
An STL vector of pointers that by default owns its pointed-to elements.
#define AmgSymMatrix(dim)
double length(const pvec &v)
static Double_t sc
static const uint32_t nHits
size_t size() const
Number of registered mappings.
const double width
MsgStream & operator<<(MsgStream &msg_stream, const std::map< std::string, T > &elm_map)
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
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition DataVector.h:847
virtual DetectorType type() const
Type of element.
Class to hold geometrical description of a silicon detector element.
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
virtual const Amg::Vector3D & normal() const override final
Get reconstruction local normal axes in global frame.
Specific class to represent the pixel measurements.
RIO_OnTrack base class for Silicon detector in the InnerDetector.
virtual const InDetDD::SiDetectorElement * detectorElement() const override final
return the detector element corresponding to this PRD The pointer will be zero if the det el is not d...
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h).
bool solenoidOn() const
status of the magnets
void getField(const double *ATH_RESTRICT xyz, double *ATH_RESTRICT bxyz, double *ATH_RESTRICT deriv=nullptr)
get B field value at given position xyz[3] is in mm, bxyz[3] is in kT if deriv[9] is given,...
const Trk::Perigee * measuredPerigee() const
Accessor method for Perigee.
const_pointer_type cptr()
virtual bool isValid() override final
Can the handle be successfully dereferenced?
static const ProbabilityInfo & getNoSplitProbability()
simple class that constructs the curvilinear vectors curvU and curvV from a given momentum direction ...
int getContributionFromRegion(Trk::DetectorRegion region)
int getHits(Trk::DetectorRegion region, int layer)
void addHit(Trk::DetectorRegion region, int layer, int etaModule, int hit=1)
This class containes the detailed information on the contributing layers and regions to the hit count...
int getHitsFromRegion(Trk::DetectorRegion region)
Class to represent and store fit qualities from track reconstruction in terms of and number of degre...
Definition FitQuality.h:97
@ MuonSpectrometerExitLayer
Tracking Volume which defines the outer surfaces of the MS.
@ CalorimeterEntryLayer
Tracking Volume which defines the entrance srufaces of the calorimeter.
@ MuonSpectrometerEntryLayer
Tracking Volume which defines the entrance surfaces of the MS.
This class is the pure abstract base class for all fittable tracking measurements.
virtual const Surface & associatedSurface() const =0
Interface method to get the associated Surface.
virtual bool type(MeasurementBaseType::Type type) const =0
Interface method checking the type.
const Amg::Vector3D & momentum() const
Access method for the momentum.
Class to handle RIO On Tracks ROT) for InDet and Muons, it inherits from the common MeasurementBase.
Definition RIO_OnTrack.h:70
virtual const TrkDetElementBase * detectorElement() const =0
returns the detector element, assoicated with the PRD of this class
virtual const Trk::PrepRawData * prepRawData() const =0
returns the PrepRawData (also known as RIO) object to which this RIO_OnTrack is associated.
Identifier identify() const
return the identifier -extends MeasurementBase
virtual bool rioType(RIO_OnTrackType::Type type) const =0
Method checking the Rio On Track type.
const TrkDetElementBase * associatedDetectorElement() const
return associated Detector Element
Contains information about the 'fitter' of this track.
ParticleHypothesis particleHypothesis() const
Returns the particle hypothesis used for Track fitting.
const ElementLink< TrackCollection > * trackElementLink() const
Return the ElementLink to the Track.
const FitQuality * fitQuality() const
accessor function for FitQuality.
const TrackSummary * trackSummary() const
accessor function for TrackSummary.
const std::vector< const TrackParameters * > & trackParameters() const
Returns the track parameters.
const TrackInfo & info() const
returns the info of the track.
ServiceHandle< ITrackingVolumesSvc > m_trackingVolumesSvc
static const SG::AuxElement::Accessor< uint8_t > s_trtdEdxUsedHitsDecoration
virtual const InDet::BeamSpotData * CacheBeamSpotData(const EventContext &ctx) const override final
void addOutlierHitInformation(const Trk::TrackStates *trackStates, xAOD::TrackParticle &tp) const
Add outlier hit info not computed in Trk::TrkSummary anymore.
TrackParticleCreatorTool(const std::string &, const std::string &, const IInterface *)
StringArrayProperty m_copyExtraSummaryName
Configurable to set the eProbabilities and extra track summary types which are to be copied from the ...
void setTrackSummary(xAOD::TrackParticle &tp, const TrackSummary &summary) const
Method to set TrackSummary of a xAOD::TrackParticle.
std::vector< std::string > m_perigeeOptions
void addPIDInformation(const EventContext &ctx, const Track *track, xAOD::TrackParticle &tp) const
Add Pixel and TRT PID information to the track particle.
ToolHandle< Muon::IMuonHitSummaryTool > m_hitSummaryTool
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCacheCondObjInputKey
BooleanProperty m_keepParameters
the following keep options are mutually exclusive
void setTrackInfo(xAOD::TrackParticle &tp, const TrackInfo &trackInfo, xAOD::ParticleHypothesis prtOrigin) const
Method to set TrackInfo of a xAOD::TrackParticle.
virtual xAOD::TrackParticle * createParticle(const EventContext &ctx, const Rec::TrackParticle &trackParticle, xAOD::TrackParticleContainer *container) const override final
Method to construct a xAOD::TrackParticle from a Rec::TrackParticle.
static const std::string s_trtdEdxUsedHitsDecorationName
Name used for the decoration of the track particle with TRT dE/dx .
static void addDummyEndcapSharedHitInformation(xAOD::TrackParticle &tp)
Add dummy endcap shared hit info as AuxDyn variable in case nominal shared hit info not computed (for...
void addDetailedHitInformation(const Trk::TrackStates *trackStates, xAOD::TrackParticle &tp) const
Add extra detailed hit summary info not computed in Trk::TrkSummary.
BooleanProperty m_doITk
if the track contains a summary, the shared, expected hit, and PID information will be recomputed.
static void setHitPattern(xAOD::TrackParticle &tp, unsigned long hitpattern)
ServiceHandle< IIBLParameterSvc > m_IBLParameterSvc
SG::ReadCondHandleKey< InDet::BeamSpotData > m_beamSpotKey
static void setNumberOfOverflowHits(xAOD::TrackParticle &tp, int overflows)
void addSharedHitInformation(const Track *track, xAOD::TrackParticle &tp) const
Add shared hit info not computed in Trk::TrkSummary anymore.
SG::ReadHandleKey< Trk::ClusterSplitProbabilityContainer > m_clusterSplitProbContainer
std::vector< Trk::eProbabilityType > m_copyEProbabilities
Enums of an eProbability which are set in the xAOD::TrackSummary.
void addExpectedHitInformation(const Perigee *perigee, xAOD::TrackParticle &tp) const
Add expected hit info for innermost pixel layers not computed in Trk::TrkSummary.
PublicToolHandle< IExtendedTrackSummaryTool > m_trackSummaryTool
SG::ReadHandleKey< Trk::PRDtoTrackMap > m_assoMapContainer
static void setTilt(xAOD::TrackParticle &tp, float tiltx, float tilty)
const Trk::ClusterSplitProbabilityContainer::ProbabilityInfo & getClusterSplittingProbability(const InDet::PixelCluster *pix) const
static const std::string & trtdEdxUsedHitsAuxName()
Get the name used for the decoration of the track particle with the number of used hits for TRT dE/dx...
ToolHandle< InDet::IInDetTestPixelLayerTool > m_testPixelLayerTool
tool to calculate expected hit information in innermost layers
Gaudi::Property< int > m_itkDecorationLevel
void setParameters(const EventContext &ctx, xAOD::TrackParticle &tp, const std::vector< const Trk::TrackParameters * > &parameters, const std::vector< xAOD::ParameterPosition > &positions) const
Method to set parameters of a xAOD::TrackParticle.
void setDefiningParameters(xAOD::TrackParticle &tp, const Perigee &perigee) const
Method to set Defining parameters of a xAOD::TrackParticle.
const AtlasDetectorID * m_detID
atlas id helper
virtual StatusCode initialize() override
BooleanProperty m_keepAllPerigee
keep all MeasuredPerigee parameters (e.g.
void compare(const Rec::TrackParticle &tp, const xAOD::TrackParticle &tpx) const
ToolHandle< ITRT_ElectronPidTool > m_eProbabilityTool
tool to calculate electron probabilities
static void setNumberOfUsedHits(xAOD::TrackParticle &tp, int hits)
ToolHandle< Reco::ITrackToVertex > m_trackToVertex
std::vector< std::pair< SG::AuxElement::Accessor< float >, Trk::eProbabilityType > > m_decorateEProbabilities
The pairs if enums of an eProbability which is added as a decoration to the track particle and the na...
void setFitQuality(xAOD::TrackParticle &tp, const FitQuality &fq) const
Method to set FitQuality of a xAOD::TrackParticle.
std::vector< std::pair< SG::AuxElement::Accessor< uint8_t >, Trk::SummaryType > > m_decorateSummaryTypes
ToolHandle< IPixelToTPIDTool > m_dedxtool
tool to calculate dE/dx using pixel clusters
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.
@ Perigee
This represents a perigee, and so will contain a Perigee object only.
@ Outlier
This TSoS contains an outlier, that is, it contains a MeasurementBase/RIO_OnTrack which was not used ...
A summary of the information contained by a track.
virtual Identifier identify() const =0
Identifier.
void setTrackParameterCovarianceMatrix(unsigned int index, std::vector< float > &cov)
Set the cov matrix of the parameter at 'index', using a vector of floats.
void setTrackParameters(std::vector< std::vector< float > > &parameters)
Set the parameters via the passed vector of vectors.
void setBeamlineTiltX(float tiltX)
void setNumberOfIBLOverflowsdEdx(uint8_t numoverflows)
void setTrackLink(const ElementLink< TrackCollection > &track)
Set the link to the original track.
void setIdentifierOfFirstHit(uint64_t id)
Set the offline identifier of the first hit.
const Trk::Perigee & perigeeParameters() const
Returns the Trk::MeasuredPerigee track parameters.
void setRadiusOfFirstHit(float radius)
Set the radius of the first hit.
void setParameterPosition(unsigned int index, ParameterPosition pos)
Set the 'position' (i.e. where it is in ATLAS) of the parameter at 'index', using the ParameterPositi...
float parameterX(unsigned int index) const
Returns the parameter x position, for 'index'.
void setBeamlineTiltY(float tiltY)
bool summaryValue(uint8_t &value, const SummaryType &information) const
Accessor for TrackSummary values.
void setNumberOfUsedHitsdEdx(uint8_t numhits)
size_t numberOfParameters() const
Returns the number of additional parameters stored in the TrackParticle.
float parameterY(unsigned int index) const
Returns the parameter y position, for 'index'.
void setSummaryValue(uint8_t &value, const SummaryType &information)
Set method for TrackSummary values.
void setHitPattern(uint32_t hitpattern)
const Amg::Vector3D & position() const
Returns the 3-pos.
void zero(TH2 *h)
zero the contents of a 2d histogram
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
void compress(const AmgSymMatrix(N) &covMatrix, std::vector< float > &vec)
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
std::pair< int, int > compare(const AmgSymMatrix(N) &m1, const AmgSymMatrix(N) &m2, double precision=1e-9, bool relative=false)
compare two matrices, returns the indices of the first element that fails the condition,...
Ensure that the ATLAS eigen extensions are properly loaded.
static const std::vector< unsigned int > unusedSummaryTypes
DataVector< const Trk::TrackStateOnSurface > TrackStates
@ pixelBarrelInclined
@ pixelEndcap
@ pixelBarrelFlat
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
@ pixelCluster
@ eProbabilityBrem
Electron probability from Brem fitting (DNA).
@ eProbabilityComb
Electron probability from combining the below probabilities.
@ eProbabilityNumberOfTRTHitsUsedFordEdx
Number of TRT hits used for dEdx measurement.
@ eProbabilityToT
Electron probability from Time-Over-Threshold (ToT) information.
@ eProbabilityHT
Electron probability from High Threshold (HT) information.
static const std::vector< float > eProbabilityDefault(numberOfeProbabilityTypes, 0.5)
@ locY
local cartesian
Definition ParamDefs.h:38
@ locX
Definition ParamDefs.h:37
@ theta
Definition ParamDefs.h:66
@ qOverP
perigee
Definition ParamDefs.h:67
@ y
Definition ParamDefs.h:56
std::pair< long int, long int > indices
const Amg::Vector3D & position() const
Method to retrieve the position of the Intersection.
ParametersBase< TrackParametersDim, Charged > TrackParameters
SummaryType
enumerates the different types of information stored in Summary.
@ numberOfTgcPhiHoles
number of TGC Phi measurements missing from the track
@ numberOfContribPixelLayers
number of contributing layers of the pixel detector
@ numberOfStgcEtaHits
number of TGC Eta measurements missing from the track
@ numberOfMmHoles
number of TGC Eta measurements missing from the track
@ numberOfTRTHitsUsedFordEdx
number of TRT high threshold outliers (only xenon counted)
@ numberOfTRTTubeHits
number of TRT hits on track in straws with xenon
@ numberOfCscUnspoiltEtaHits
number of unspoilt CSC eta measurements (all CSC phi measurements are by definition spoilt).
@ numberOfCscEtaHoles
number of CSC Eta measurements missing from the track
Definition index.py:1
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Vertex_v1 Vertex
Define the latest version of the vertex class.
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
SummaryType
Enumerates the different types of information stored in Summary.
@ numberOfInnermostPixelLayerSharedEndcapHits
number of Pixel 0th layer endcap hits shared by several tracks.
@ expectInnermostPixelLayerHit
Do we expect a 0th-layer barrel hit for this track?
@ numberOfInnermostPixelLayerEndcapHits
these are the hits in the 0th pixel layer endcap [unit8_t].
@ numberOfPrecisionLayers
layers with at least 3 hits [unit8_t].
@ numberOfNextToInnermostPixelLayerSharedHits
number of Pixel 1st layer barrel hits shared by several tracks.
@ numberOfNextToInnermostPixelLayerSharedEndcapHits
number of Pixel 1st layer endcap hits shared by several tracks.
@ numberOfContribPixelLayers
number of contributing layers of the pixel detector [unit8_t].
@ numberOfNextToInnermostPixelLayerSplitHits
number of Pixel 1st layer barrel hits split by cluster splitting
@ numberOfPixelSplitHits
number of Pixel all-layer hits split by cluster splitting [unit8_t].
@ numberOfInnermostPixelLayerEndcapOutliers
number of 0th layer endcap outliers
@ numberOfPixelBarrelHits
these are the pixel hits, in the barrel flat layers [unit8_t].
@ numberOfInnermostPixelLayerSharedHits
number of Pixel 0th layer barrel hits shared by several tracks.
@ numberOfTriggerEtaHoleLayers
layers with trigger eta holes but no hits [unit8_t].
@ numberOfPixelOutliers
these are the pixel outliers, including the b-layer [unit8_t].
@ numberOfContribPixelBarrelFlatLayers
number of contributing barrel flat layers of the pixel detector [unit8_t].
@ numberOfPhiHoleLayers
layers with trigger phi holes but no hits [unit8_t].
@ numberOfTRTXenonHits
number of TRT hits on track in straws with xenon [unit8_t].
@ numberOfNextToInnermostPixelLayerHits
these are the hits in the 1st pixel barrel layer
@ numberOfContribPixelBarrelInclinedLayers
number of contributing barrel inclined layers of the pixel detector [unit8_t].
@ numberOfInnermostPixelLayerSplitHits
number of Pixel 0th layer barrel hits split by cluster splitting
@ numberOfTRTTubeHits
number of TRT tube hits [unit8_t].
@ numberOfPixelEndcapHits
these are the pixel hits, in the endcap layers [unit8_t].
@ numberOfInnermostPixelLayerOutliers
number of 0th layer barrel outliers
@ numberOfTriggerEtaLayers
layers with trigger eta hits [unit8_t].
@ numberOfNextToInnermostPixelLayerSplitEndcapHits
number of Pixel 1st layer endcap hits split by cluster splitting
@ numberOfNextToInnermostPixelLayerEndcapHits
these are the hits in the 0.5th and 1st pixel layer endcap rings [unit8_t].
@ numberOfPhiLayers
layers with a trigger phi hit [unit8_t].
@ expectNextToInnermostPixelLayerHit
Do we expect a 1st-layer barrel hit for this track?
@ numberOfContribPixelEndcap
number of contributing endcap layers of the pixel detector [unit8_t].
@ numberOfNextToInnermostPixelLayerEndcapOutliers
number of 1st layer endcap disk outliers
@ numberOfPrecisionHoleLayers
layers with holes AND no hits [unit8_t].
@ numberOfPixelBarrelInclinedHits
these are the pixel hits, in the barrel inclined layers [unit8_t].
@ numberOfSCTOutliers
number of SCT outliers [unit8_t].
@ numberOfPixelBarrelFlatHits
these are the pixel hits, in the barrel flat layers [unit8_t].
@ numberOfInnermostPixelLayerHits
these are the hits in the 0th pixel barrel layer
@ numberOfPixelSharedHits
number of Pixel all-layer hits shared by several tracks [unit8_t].
@ eProbabilityComb
Electron probability from combining the below probabilities [float].
@ numberOfSCTSharedHits
number of SCT hits shared by several tracks [unit8_t].
@ numberOfInnermostPixelLayerSplitEndcapHits
number of Pixel 0th layer endcap hits shared by several tracks.
@ numberOfContribPixelBarrelLayers
number of contributing barrel flat layers of the pixel detector [unit8_t].
@ numberOfTRTSharedHits
number of TRT hits used by more than one track
@ numberOfNextToInnermostPixelLayerOutliers
number of 1st pixel layer barrel outliers
@ BeamLine
Parameter defined at the Vertex/Beamline.
@ FirstMeasurement
Parameter defined at the position of the 1st measurement.
@ LastMeasurement
Parameter defined at the position of the last measurement.
#define unlikely(x)
unsigned int nphiHoleLayers
number of eta trigger layer holes
unsigned int ntrigEtaLayers
number of phi layers
unsigned int ntrigEtaHoleLayers
number of precision holes
unsigned int nphiLayers
number of precision layers
unsigned int nprecisionHoleLayers
number of eta trigger layers