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 MagField::AtlasFieldCache fieldCache;
792 fieldCondObj->getInitializedCache(fieldCache);
793
794 for (const auto* param : parameters) {
795 std::vector<float>& values = parametersVec[numParam];
796 values.resize(6);
797 const Amg::Vector3D& pos = param->position();
798 const Amg::Vector3D& mom = param->momentum();
799 values[0] = pos[0];
800 values[1] = pos[1];
801 values[2] = pos[2];
802 values[3] = mom[0];
803 values[4] = mom[1];
804 values[5] = mom[2];
805
806 const bool straightPars = (!fieldCache.solenoidOn() && m_trackingVolumesSvc->volume(Trk::ITrackingVolumesSvc::CalorimeterEntryLayer).inside(pos)) ||
809 AmgSymMatrix(5) covarianceMatrix;
810 covarianceMatrix.setIdentity();
811
812 if (param->covariance()) {
813 // has covariance matrix
814 // now convert from to Curvilinear -- to be double checked for correctness
815 CurvilinearUVT curvilinearUVT(mom.unit());
816 if (!straightPars){
817 Amg::Vector3D magnFieldVect;
818 magnFieldVect.setZero();
819 fieldCache.getField(pos.data(), magnFieldVect.data());
820 const Amg::Transform3D& localToGlobalTransform = param->associatedSurface().transform();
821
822 JacobianLocalToCurvilinear jacobian(magnFieldVect,
823 param->parameters()[Trk::qOverP],
824 std::sin(param->parameters()[Trk::theta]),
825 curvilinearUVT,
826 localToGlobalTransform.rotation().col(0),
827 localToGlobalTransform.rotation().col(1));
828
829 covarianceMatrix = param->covariance()->similarity(jacobian);
830 } else {
831 const Amg::Vector3D loc_x {param->parameters()[Trk::locX],0,0};
832 const Amg::Vector3D loc_y {0,param->parameters()[Trk::locY],0};
833 JacobianLocalToCurvilinear jacobian(curvilinearUVT, loc_x, loc_y);
834 covarianceMatrix = param->covariance()->similarity(jacobian);
835 }
836 }
837 std::vector<float> covMatrixVec;
838 Amg::compress(covarianceMatrix, covMatrixVec);
839 tp.setTrackParameterCovarianceMatrix(numParam, covMatrixVec);
840
841 ++numParam;
842 }
843
844 tp.setTrackParameters(parametersVec);
845 unsigned int i = 0;
846 for (; i < positions.size(); ++i) {
847 tp.setParameterPosition(i, positions[i]);
848 if (positions[i] == xAOD::FirstMeasurement) {
849 float x_position = tp.parameterX(i);
850 float y_position = tp.parameterY(i);
851 tp.setRadiusOfFirstHit(std::sqrt(x_position * x_position + y_position * y_position));
853 parameters[i]->associatedSurface().associatedDetectorElementIdentifier().get_compact());
854 }
855 }
856}
857
858void
860{
861 tp.setBeamlineTiltX(tiltx);
862 tp.setBeamlineTiltY(tilty);
863}
864
865void
867{
868 tp.setHitPattern(hitpattern);
869}
870
871void
876
877void
882
883void
885{
886 // ensure that xAOD TrackSummary and TrackSummary enums are in sync.
887 constexpr unsigned int xAodReferenceEnum1 = static_cast<unsigned int>(xAOD::numberOfTRTXenonHits);
888 constexpr unsigned int TrkReferenceEnum1 = static_cast<unsigned int>(Trk::numberOfTRTXenonHits);
889 static_assert(xAodReferenceEnum1 == TrkReferenceEnum1, "Trk and xAOD enums differ in their indices");
890 constexpr unsigned int xAodReferenceEnum2 = static_cast<unsigned int>(xAOD::numberOfTRTTubeHits);
891 constexpr unsigned int TrkReferenceEnum2 = static_cast<unsigned int>(Trk::numberOfTRTTubeHits);
892 static_assert(xAodReferenceEnum2 == TrkReferenceEnum2, "Trk and xAOD enums differ in their indices");
893
894 for (unsigned int i = 0; i < Trk::numberOfTrackSummaryTypes; i++) {
895 // Only add values which are +ve (i.e., which were created)
897 continue;
898 }
900 continue;
901 }
903 continue;
904 }
905 // skip values which are floats
906 if (std::find(unusedSummaryTypes.begin(), unusedSummaryTypes.end(), i) != unusedSummaryTypes.end()) {
907 continue;
908 }
910 continue;
911 }
912 if (m_doITk && i == Trk::numberOfContribPixelLayers){ // Filled in addDetailedHitInformation for ITk
913 continue;
914 }
915
916 int value = summary.get(static_cast<Trk::SummaryType>(i));
917 uint8_t uvalue = static_cast<uint8_t>(std::min(value,255));
918 // coverity[first_enum_type]
919 if (value > 0) {
920 tp.setSummaryValue(uvalue, static_cast<xAOD::SummaryType>(i));
921 }
922 }
923
924 // muon hit info
925 if (!m_hitSummaryTool.empty()) {
926 ATH_MSG_DEBUG("now do muon hit info");
928 uint8_t numberOfPrecisionLayers = msSummary.nprecisionLayers;
929 ATH_MSG_DEBUG("# of prec layers: " << static_cast<unsigned int>(numberOfPrecisionLayers));
930 uint8_t numberOfPrecisionHoleLayers = msSummary.nprecisionHoleLayers;
931 uint8_t numberOfPhiLayers = msSummary.nphiLayers;
932 uint8_t numberOfPhiHoleLayers = msSummary.nphiHoleLayers;
933 uint8_t numberOfTriggerEtaLayers = msSummary.ntrigEtaLayers;
934 uint8_t numberOfTriggerEtaHoleLayers = msSummary.ntrigEtaHoleLayers;
935 tp.setSummaryValue(numberOfPrecisionLayers, xAOD::numberOfPrecisionLayers);
936 tp.setSummaryValue(numberOfPrecisionHoleLayers, xAOD::numberOfPrecisionHoleLayers);
937 tp.setSummaryValue(numberOfPhiLayers, xAOD::numberOfPhiLayers);
938 tp.setSummaryValue(numberOfPhiHoleLayers, xAOD::numberOfPhiHoleLayers);
939 tp.setSummaryValue(numberOfTriggerEtaLayers, xAOD::numberOfTriggerEtaLayers);
940 tp.setSummaryValue(numberOfTriggerEtaHoleLayers, xAOD::numberOfTriggerEtaHoleLayers);
941 }
942
943}
944
945void
946TrackParticleCreatorTool::addPIDInformation(const EventContext& ctx, const Trk::Track *track, xAOD::TrackParticle& tp) const
947{
948 // TRT PID information
949 {
950 static const std::vector<float> eProbabilityDefault(numberOfeProbabilityTypes,0.5);
951 constexpr int initialValue{-1};
952 std::vector<float> eProbability_tmp;
953 const std::vector<float>& eProbability(
954 track && !m_eProbabilityTool.empty()
955 ? eProbability_tmp =
956 m_eProbabilityTool->electronProbability(ctx, *track)
958 int nHits = track && !m_eProbabilityTool.empty()
960 : initialValue;
961 for (const Trk::eProbabilityType& copy : m_copyEProbabilities) {
962 float eProbability_value = eProbability.at(copy);
963 tp.setSummaryValue(eProbability_value, static_cast<xAOD::SummaryType>(copy + xAOD::eProbabilityComb));
964 }
965 for (const std::pair<SG::AuxElement::Accessor<float>, Trk::eProbabilityType>& decoration :
967 float fvalue = eProbability.at(decoration.second);
968 decoration.first(tp) = fvalue;
969 }
970 // now the extra summary types
971 for (const std::pair<SG::AuxElement::Accessor<uint8_t>, Trk::SummaryType>& decoration :
973 uint8_t summary_value = nHits;
974 decoration.first(tp) = summary_value;
975 }
976
977 }
978
979 // PixelPID
980 {
981 const int initialValue{-1};
982 float dedx = initialValue;
983 int nHitsUsed_dEdx = initialValue;
984 int nOverflowHits_dEdx = initialValue;
985 if (track && !m_dedxtool.empty() && track->info().trackFitter() != TrackInfo::Unknown) {
986 dedx = m_dedxtool->dEdx(ctx, *track, nHitsUsed_dEdx, nOverflowHits_dEdx);
987 }
988 tp.setNumberOfUsedHitsdEdx(nHitsUsed_dEdx);
989 tp.setNumberOfIBLOverflowsdEdx(nOverflowHits_dEdx);
990 tp.setSummaryValue(dedx, static_cast<xAOD::SummaryType>(51));
991 }
992}
993
994void
996{
997
998 Trk::DetailedHitInfo detailedInfo;
999
1000 for (const TrackStateOnSurface* tsos : *trackStates) {
1001
1002 const Trk::MeasurementBase* mesb = tsos->measurementOnTrack();
1003 if(mesb==nullptr) continue;
1004 // Check if the measurement type is RIO on Track (ROT)
1005 const RIO_OnTrack* rot = nullptr;
1007 rot = static_cast<const RIO_OnTrack*>(mesb);
1008 }
1009 if(rot==nullptr) continue;
1010
1011 const Identifier& id = rot->identify();
1012 if(!m_pixelID->is_pixel(id)) continue;
1013
1014 Trk::DetectorRegion region;
1015 const InDetDD::SiDetectorElement* detEl = dynamic_cast<const InDetDD::SiDetectorElement*>(rot->detectorElement());
1019 else region = Trk::pixelEndcap;
1020
1021 detailedInfo.addHit(region, m_pixelID->layer_disk(id), m_pixelID->eta_module(id));
1022
1023 }
1024
1025 uint8_t nContribPixelLayers = static_cast<uint8_t>(detailedInfo.getPixelContributions());
1026
1027 uint8_t nContribPixelBarrelFlatLayers = static_cast<uint8_t>(detailedInfo.getContributionFromRegion(Trk::pixelBarrelFlat ));
1028 uint8_t nContribPixelBarrelInclinedLayers = static_cast<uint8_t>(detailedInfo.getContributionFromRegion(Trk::pixelBarrelInclined));
1029 uint8_t nContribPixelBarrelLayers = static_cast<uint8_t>(nContribPixelBarrelFlatLayers+nContribPixelBarrelInclinedLayers);
1030 uint8_t nContribPixelEndcap = static_cast<uint8_t>(detailedInfo.getContributionFromRegion(Trk::pixelEndcap ));
1031
1032 uint8_t nPixelBarrelFlatHits = static_cast<uint8_t>(detailedInfo.getHitsFromRegion(Trk::pixelBarrelFlat ));
1033 uint8_t nPixelBarrelInclinedHits = static_cast<uint8_t>(detailedInfo.getHitsFromRegion(Trk::pixelBarrelInclined));
1034 uint8_t nPixelBarrelHits = static_cast<uint8_t>(nPixelBarrelFlatHits+nPixelBarrelInclinedHits);
1035 uint8_t nPixelEndcapHits = static_cast<uint8_t>(detailedInfo.getHitsFromRegion(Trk::pixelEndcap ));
1036
1037 uint8_t nInnermostPixelLayerEndcapHits = static_cast<uint8_t>(detailedInfo.getHits(Trk::pixelEndcap, 0));
1038 uint8_t nNextToInnermostPixelLayerEndcapHits = static_cast<uint8_t>(detailedInfo.getHits(Trk::pixelEndcap, 1)
1039 + detailedInfo.getHits(Trk::pixelEndcap, 2)); // L0.5 shorties + L1
1040
1041 tp.setSummaryValue(nContribPixelLayers, xAOD::numberOfContribPixelLayers);
1042 tp.setSummaryValue(nContribPixelBarrelLayers, xAOD::numberOfContribPixelBarrelLayers);
1043 tp.setSummaryValue(nContribPixelEndcap, xAOD::numberOfContribPixelEndcap);
1045 tp.setSummaryValue(nPixelBarrelHits, xAOD::numberOfPixelBarrelHits);
1046 tp.setSummaryValue(nContribPixelBarrelFlatLayers, xAOD::numberOfContribPixelBarrelFlatLayers);
1047 tp.setSummaryValue(nContribPixelBarrelInclinedLayers, xAOD::numberOfContribPixelBarrelInclinedLayers);
1048 tp.setSummaryValue(nPixelBarrelFlatHits, xAOD::numberOfPixelBarrelFlatHits);
1049 tp.setSummaryValue(nPixelBarrelInclinedHits, xAOD::numberOfPixelBarrelInclinedHits);
1050 tp.setSummaryValue(nPixelEndcapHits, xAOD::numberOfPixelEndcapHits);
1051 }
1052 tp.setSummaryValue(nInnermostPixelLayerEndcapHits, xAOD::numberOfInnermostPixelLayerEndcapHits);
1053 tp.setSummaryValue(nNextToInnermostPixelLayerEndcapHits, xAOD::numberOfNextToInnermostPixelLayerEndcapHits);
1054
1055}
1056
1057void
1059{
1060
1061 if(m_testPixelLayerTool.empty() || perigee==nullptr) return;
1062
1063 uint8_t zero = static_cast<uint8_t>(0);
1064 uint8_t nContribPixLayers, nInPixHits, nNextInPixHits;
1065 if(!tp.summaryValue(nContribPixLayers, xAOD::numberOfContribPixelLayers)){
1066 nContribPixLayers = zero;
1067 }
1068 if(nContribPixLayers==0){
1069 ATH_MSG_DEBUG("No pixels on track, so wo do not expect hit in inner layers");
1072 }
1073
1074 else {
1075
1076 // Innermost pixel layer
1078 nInPixHits = zero;
1079 }
1080 if(nInPixHits>0){
1081 ATH_MSG_DEBUG("Innermost pixel Layer hit on track, so we expect an innermost pixel layer hit");
1082 uint8_t one = static_cast<uint8_t>(1);
1084 } else {
1085 uint8_t expectHit = static_cast<uint8_t>(m_testPixelLayerTool->expectHitInInnermostPixelLayer(perigee));
1087 }
1088
1089 // Next-to-innermost pixel layer
1091 nNextInPixHits = zero;
1092 }
1093 if(nNextInPixHits>0){
1094 ATH_MSG_DEBUG("Next-to-innermost pixel Layer hit on track, so we expect an next-to-innermost pixel layer hit");
1095 uint8_t one = static_cast<uint8_t>(1);
1097 } else {
1098 uint8_t expectHit = static_cast<uint8_t>(m_testPixelLayerTool->expectHitInNextToInnermostPixelLayer(perigee));
1100 }
1101
1102 } // end else if nContribPixLayers>0
1103
1104}
1105
1106void
1108{
1109
1110 uint8_t nPixOutliers = 0, nInPixOutliers = 0, nNInPixOutliers = 0, nSCTOutliers = 0;
1111 uint8_t nInEndcapPixOutliers = 0, nNInEndcapPixOutliers = 0;
1112
1113 for (const TrackStateOnSurface* tsos : *trackStates) {
1114
1115 bool isOutlier = tsos->type(Trk::TrackStateOnSurface::Outlier);
1116 if(!isOutlier) continue;
1117
1118 const Trk::MeasurementBase* mesb = tsos->measurementOnTrack();
1119 if(mesb==nullptr) continue;
1120 // Check if the measurement type is RIO on Track (ROT)
1121 const RIO_OnTrack* rot = nullptr;
1123 rot = static_cast<const RIO_OnTrack*>(mesb);
1124 }
1125 if (rot == nullptr)
1126 continue;
1127
1128 const Identifier& id = rot->identify();
1129
1130 if (m_pixelID->is_pixel(id)) {
1131 nPixOutliers++;
1132 int layer = m_pixelID->layer_disk(id);
1133 if (m_pixelID->is_barrel(id)) {
1134 if (layer == 0){
1135 nInPixOutliers++;
1136 }
1137 else if (layer == 1){
1138 nNInPixOutliers++;
1139 }
1140 } else if (m_doITk) { // isITk && isEndCap -> ITk specific counters
1141 if (layer == 0){
1142 nInEndcapPixOutliers++;
1143 }
1144 else if (layer == 1 || layer == 2){
1145 nNInEndcapPixOutliers++; // L0.5 + L1 disks
1146 }
1147 }
1148 }
1149 else if (m_sctID->is_sct(id)) {
1150 nSCTOutliers++;
1151 }
1152
1153 // TRT outliers are already filled in the InDetTrackSummaryHelperTool as
1154 // used in the ambi solver
1155 }
1156
1161
1162 if(m_doITk){
1165 }
1166
1167}
1168
1169void
1171{
1172
1173 uint8_t nPixSharedHits = 0, nInPixSharedHits = 0, nNInPixSharedHits = 0, nSCTSharedHits = 0, nTRTSharedHits = 0;
1174 uint8_t nInPixSharedEndcapHits = 0, nNInPixSharedEndcapHits = 0;
1175 uint8_t nPixSplitHits = 0, nInPixSplitHits = 0, nNInPixSplitHits = 0;
1176 uint8_t nInPixSplitEndcapHits = 0, nNInPixSplitEndcapHits = 0;
1177
1178 const DataVector<const Trk::MeasurementBase>* measurements = track->measurementsOnTrack();
1179 if(!measurements){
1180 ATH_MSG_DEBUG("No measurement on track");
1181 return;
1182 }
1183
1184 const EventContext& ctx = Gaudi::Hive::currentContext();
1186
1187 for (const auto* const ms : *measurements) {
1188 // check if it's a rot
1189 const Trk::RIO_OnTrack* rot = nullptr;
1191 rot = static_cast<const Trk::RIO_OnTrack*>(ms);
1192 }
1193 if (!rot) {
1194 ATH_MSG_DEBUG("Cannot cast measurement to RIO_OnTrack");
1195 continue;
1196 }
1197
1198 const Identifier& id = rot->identify();
1199
1200 if (m_doSharedSiHits && m_pixelID->is_pixel(id)) {
1201 // check if split, when running TIDE
1202 bool hitIsSplit(false);
1203 if (m_runningTIDE_Ambi) {
1204 const InDet::PixelClusterOnTrack* pix = nullptr;
1206 pix = static_cast<const InDet::PixelClusterOnTrack*>(rot);
1207 }
1208 if (pix) {
1209 const InDet::PixelCluster* pixPrd = pix->prepRawData();
1211 splitProb = getClusterSplittingProbability(pixPrd);
1212 int layer = m_pixelID->layer_disk(id);
1213 if (pixPrd and splitProb.isSplit()) {
1214 ATH_MSG_DEBUG("split Pixel hit found");
1215 hitIsSplit = true;
1216 nPixSplitHits++;
1217 if (m_pixelID->is_barrel(id)) {
1218 if (layer == 0)
1219 nInPixSplitHits++;
1220 else if (layer == 1)
1221 nNInPixSplitHits++;
1222 } else if (m_doITk) { // isITk && isEndCap -> ITk specific counters
1223 if (layer == 0)
1224 nInPixSplitEndcapHits++;
1225 else if (layer == 1 || layer == 2)
1226 nNInPixSplitEndcapHits++; // L0.5 + L1 disks
1227 }
1228 }
1229 }
1230 }
1231
1232 // check if shared
1233 // if we are running the TIDE ambi don't count split hits as shared
1234 if (!hitIsSplit) {
1235 if (prd_to_track_map->isShared(*(rot->prepRawData()))) {
1236 ATH_MSG_DEBUG("shared Pixel hit found");
1237 nPixSharedHits++;
1238 int layer = m_pixelID->layer_disk(id);
1239 if (m_pixelID->is_barrel(id)) {
1240 if (layer == 0)
1241 nInPixSharedHits++;
1242 else if (layer == 1)
1243 nNInPixSharedHits++;
1244 } else if (m_doITk) { // isITk && isEndCap -> ITk specific counters
1245 if (layer == 0)
1246 nInPixSharedEndcapHits++;
1247 else if (layer == 1 || layer == 2)
1248 nNInPixSharedEndcapHits++; // L0.5 + L1 disks
1249 }
1250 }
1251 }
1252
1253 } // end pixel
1254
1255 else if (m_doSharedSiHits && m_sctID->is_sct(id)) {
1256 if (prd_to_track_map->isShared(*(rot->prepRawData()))) {
1257 ATH_MSG_DEBUG("shared SCT hit found");
1258 nSCTSharedHits++;
1259 }
1260 }
1261
1262 else if (m_doSharedTRTHits && m_trtID->is_trt(id)) {
1263 if (prd_to_track_map->isShared(*(rot->prepRawData()))) {
1264 ATH_MSG_DEBUG("shared TRT hit found");
1265 nTRTSharedHits++;
1266 }
1267 }
1268 }
1269
1273
1277 tp.setSummaryValue(nSCTSharedHits, xAOD::numberOfSCTSharedHits);
1278 tp.setSummaryValue(nTRTSharedHits, xAOD::numberOfTRTSharedHits);
1279
1280 if(m_doITk){
1285 }
1286
1287}
1288
1289
1290void
1292{
1293
1294 uint8_t nInPixSharedEndcapHits = 0, nNInPixSharedEndcapHits = 0;
1295 uint8_t nInPixSplitEndcapHits = 0, nNInPixSplitEndcapHits = 0;
1296
1301
1302}
1303
1304
1307{
1308 const EventContext& ctx = Gaudi::Hive::currentContext();
1309 if (!pix || m_clusterSplitProbContainer.key().empty()) {
1311 }
1313 if (!splitProbContainer.isValid()) {
1314 ATH_MSG_FATAL("Failed to get cluster splitting probability container "
1316 }
1317 return splitProbContainer->splitProbability(pix);
1318}
1319
1320
1323{
1325 return beamSpotHandle.cptr();
1326}
1327
1328} // 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:997
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
c *Fortran *integer maxpup parameter(maxpup=100) integer idbmup
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.
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