ATLAS Offline Software
Loading...
Searching...
No Matches
TrackParticleCreatorTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 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
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 (detStore()->retrieve(m_trtID, "TRT_ID").isFailure()) {
165 ATH_MSG_FATAL("Could not get TRT_ID ");
166 return StatusCode::FAILURE;
167 }
168
169 if (!m_IBLParameterSvc.empty()) {
170 if (m_IBLParameterSvc.retrieve().isFailure()) {
171 ATH_MSG_FATAL("Could not retrieve IBLParameterSvc");
172 return StatusCode::FAILURE;
173 }
174 }
175
176 m_doIBL = !m_IBLParameterSvc.empty() && m_IBLParameterSvc->containsIBL();
177
178 if (m_doIBL && !m_IBLParameterSvc->contains3D()) {
179 ATH_MSG_WARNING("Assuming hybrid 2D/3D IBL module composition, but geometry is all-planar");
180 }
181
182 /* Retrieve track to vertex from ToolService */
183 if (m_trackToVertex.retrieve().isFailure()) {
184 ATH_MSG_FATAL("Failed to retrieve tool " << m_trackToVertex);
185 return StatusCode::FAILURE;
186 }
187 ATH_MSG_DEBUG("Retrieved tool " << m_trackToVertex);
188
189 if (!m_hitSummaryTool.empty()) {
190 /* Retrieve hit summary tool from ToolService */
191 if (m_hitSummaryTool.retrieve().isFailure()) {
192 ATH_MSG_FATAL("Failed to retrieve tool " << m_hitSummaryTool);
193 return StatusCode::FAILURE;
194 }
195 ATH_MSG_DEBUG("Retrieved tool " << m_hitSummaryTool);
196
197 } else {
198 m_hitSummaryTool.disable();
199 }
201
203
204 StatusCode sc(StatusCode::SUCCESS);
205 m_copyEProbabilities.clear();
208
209 if (!m_copyExtraSummaryName.empty()) {
210 std::map<std::string, std::pair<Trk::eProbabilityType, bool>> eprob_map;
211 std::map<std::string, Trk::SummaryType> extra_summary_type_map;
212 createEProbabilityMap(eprob_map);
213 createExtraSummaryTypeMap(extra_summary_type_map);
214
215 std::vector<std::string> errors;
216 for (const std::string& eprob_to_copy : m_copyExtraSummaryName) {
217 std::map<std::string, std::pair<Trk::eProbabilityType, bool>>::const_iterator eprob_iter =
218 eprob_map.find(eprob_to_copy);
219 if (eprob_iter == eprob_map.end()) {
220 std::map<std::string, Trk::SummaryType>::const_iterator extra_summary_type_iter =
221 extra_summary_type_map.find(eprob_to_copy);
222 if (extra_summary_type_iter == extra_summary_type_map.end()) {
223 errors.push_back(eprob_to_copy);
224 } else {
225 m_decorateSummaryTypes.emplace_back(
226 SG::AuxElement::Accessor<uint8_t>(extra_summary_type_iter->first),
227 extra_summary_type_iter->second);
228 }
229 } else {
230 if (!eprob_iter->second.second) {
231 m_copyEProbabilities.push_back(eprob_iter->second.first);
232 } else {
233 m_decorateEProbabilities.emplace_back(SG::AuxElement::Accessor<float>(eprob_iter->first),
234 eprob_iter->second.first);
235 }
236 }
237 }
238
239 if (!errors.empty()) {
240 ATH_MSG_ERROR("Error in configuration. Unknown electron probability name: "
241 << errors << ". known are " << eprob_map << " " << extra_summary_type_map);
242 sc = StatusCode::FAILURE;
243 }
244 }
245
246 ATH_CHECK( m_eProbabilityTool.retrieve( DisableTool{m_eProbabilityTool.empty()} ) );
247 ATH_CHECK( m_dedxtool.retrieve( DisableTool{m_dedxtool.empty()} ) );
248 ATH_CHECK( m_testPixelLayerTool.retrieve( DisableTool{m_testPixelLayerTool.empty()} ) );
249
250 ATH_CHECK(m_assoMapContainer.initialize(!m_assoMapContainer.key().empty()));
252 !m_clusterSplitProbContainer.key().empty()));
253
254 ATH_MSG_VERBOSE(" initialize successful.");
255 return sc;
256}
257
260 const Trk::Track& track,
262 const xAOD::Vertex* vxCandidate,
263 xAOD::ParticleHypothesis prtOrigin) const
264{
265 const Trk::Perigee* aPer = nullptr;
266 const Trk::TrackParameters* parsToBeDeleted = nullptr;
267 // Origin
268 if (m_perigeeExpression == "Origin") {
269 aPer = track.perigeeParameters();
270 if (aPer) {
271 // aMeasPer clone will be created later if all perigee option selected
272 if (m_keepAllPerigee) {
273 aPer = nullptr;
274 }
275 } else {
276 const Amg::Vector3D persf(0, 0, 0);
277 const Trk::Perigee* result = m_trackToVertex->perigeeAtVertex(ctx, track, persf).release();
278 if (result != nullptr) {
279 aPer = result;
280 parsToBeDeleted = result;
281 } else {
282 ATH_MSG_WARNING("Could not extrapolate to 0,0,0. No TrackParticle created.");
283 return nullptr;
284 }
285 }
286 // Beamspot
287 } else if (m_perigeeExpression == "BeamSpot") {
288 const Trk::Perigee* result = m_trackToVertex->perigeeAtVertex(ctx, track, CacheBeamSpotData(ctx)->beamVtx().position()).release();
289 if (!result) {
290 ATH_MSG_WARNING("Failed to extrapolate to first Beamspot - No TrackParticle created.");
291 return nullptr;
292 }
293 parsToBeDeleted = result;
294 aPer = result;
295 }
296 // the non default way, express the perigee wrt. the vertex position
297 else if (m_perigeeExpression == "Vertex") {
298 if (vxCandidate != nullptr) {
299 const Trk::Perigee* result = m_trackToVertex->perigeeAtVertex(ctx, track, vxCandidate->position()).release();
300 if (result != nullptr) {
301 parsToBeDeleted = result;
302 aPer = result;
303 } else {
304 ATH_MSG_WARNING("Could not extrapolate track to vertex region! No TrackParticle created.");
305 return nullptr;
306 }
307 } else {
308 ATH_MSG_WARNING("Perigee expression at Vertex, but no vertex found! No TrackParticle created.");
309 }
310 //BeamLine
311 } else if (m_perigeeExpression == "BeamLine") {
312 const Trk::Perigee* result = m_trackToVertex->perigeeAtBeamline(ctx, track, CacheBeamSpotData(ctx)).release();
313 if (!result) {
314 ATH_MSG_WARNING("Failed to extrapolate to Beamline - No TrackParticle created.");
315 return nullptr;
316 }
317 parsToBeDeleted = result;
318 aPer = result;
319 }
320 /*
321 * We start from the existing summary
322 * and see what we want to add
323 */
324 std::unique_ptr<Trk::TrackSummary> updated_summary;
325 const Trk::TrackSummary* summary = track.trackSummary();
326 if (m_trackSummaryTool.get() != nullptr) {
327 if (!track.trackSummary() || m_updateTrackSummary) {
328 updated_summary = m_trackSummaryTool->summary(ctx, track);
329 summary = updated_summary.get();
330 }
331 } else {
333 "No proper TrackSummaryTool found. Creating TrackParticle with a TrackSummary on track");
334 }
335 if (!summary) {
336 ATH_MSG_WARNING("Track particle created for a track without a track summary");
337 }
338
339 // find the first and the last hit in track
340 // we do that the same way as in the track slimming tool!
341 // that way it is also ok on not slimmed tracks!
342 std::vector<const Trk::TrackParameters*> parameters;
343 std::vector<xAOD::ParameterPosition> parameterPositions;
344
345 int nbc_meas_A1 = 0;
346 int nbc_meas_B3 = 0;
347 int nbc_meas_A1_or_B3 = 0;
348 int nbc_meas_A1_or_B3_or_C = 0;
349
350 int isBC_A1 = 0;
351 int isBC_B3 = 0;
352 int isBC_C = 0;
353
354 const Trk::TrackStates* trackStates = track.trackStateOnSurfaces();
355 const Trk::TrackParameters* first(nullptr);
356 const Trk::TrackParameters* tp(nullptr);
357
358 if (m_badclusterID != 0) {
359 for (const TrackStateOnSurface* tsos : *trackStates) {
360 if (tsos->type(TrackStateOnSurface::Measurement) && tsos->trackParameters() != nullptr &&
361 tsos->measurementOnTrack() != nullptr &&
362 !(tsos->measurementOnTrack()->type(Trk::MeasurementBaseType::PseudoMeasurementOnTrack))) {
363 tp = tsos->trackParameters();
364
365 const InDet::SiClusterOnTrack* clus =
366 dynamic_cast<const InDet::SiClusterOnTrack*>(tsos->measurementOnTrack());
367 if (!clus) {
368 ATH_MSG_DEBUG("Failed dynamic_cast to InDet::SiClusterOnTrack ");
369 continue;
370 }
371 const Trk::PrepRawData* prdc = nullptr;
372 prdc = clus->prepRawData();
373 if (!prdc) {
374 ATH_MSG_DEBUG("No PRD for Si cluster");
375 }
376 const InDet::SiCluster* RawDataClus = dynamic_cast<const InDet::SiCluster*>(clus->prepRawData());
377 if (!RawDataClus) {
378 ATH_MSG_DEBUG("No RDC for Si cluster");
379 continue;
380 }
381 const Trk::MeasurementBase* mesb = tsos->measurementOnTrack();
382
383 if (RawDataClus->detectorElement()->isPixel()) {
384 const InDetDD::SiDetectorElement* element = nullptr;
386 dynamic_cast<const InDet::PixelCluster*>(RawDataClus);
387 if (!pixelCluster) {
388 ATH_MSG_DEBUG("Pixel cluster null though detector element matches pixel");
389 }
390
391 else {
392 float size = pixelCluster->rdoList().size();
393 float tot = pixelCluster->totalToT();
394 float charge = pixelCluster->totalCharge();
395 float cotthetaz = -1;
396 int zWidth = -1;
397
398 element = pixelCluster->detectorElement();
399 if (!element)
400 ATH_MSG_DEBUG("No element for track incidence angles!");
401 float PixTrkAngle = -1000;
402 float PixTrkThetaI = -1000;
403 float theta = -1000;
404 if (element) {
405 const Amg::Vector3D& my_track = tp->momentum();
406 const Amg::Vector3D& my_normal = element->normal();
407 const Amg::Vector3D& my_phiax = element->phiAxis();
408 const Amg::Vector3D& my_etaax = element->etaAxis();
409 // track component on etaAxis:
410 float trketacomp = my_track.dot(my_etaax);
411 // track component on phiAxis:
412 float trkphicomp = my_track.dot(my_phiax);
413 // track component on the normal to the module
414 float trknormcomp = my_track.dot(my_normal);
415 // Track angle
416 PixTrkAngle = std::atan2(trkphicomp, trknormcomp);
417 PixTrkThetaI = std::atan2(trketacomp, trknormcomp);
418 float length = std::sqrt(trketacomp * trketacomp + trkphicomp * trkphicomp + trknormcomp * trknormcomp);
419 theta = std::acos(trknormcomp / length);
420 cotthetaz = 1. / std::tan(PixTrkThetaI);
421
422 // reducing the angle in the right quadrant
423 // M_PI (pi) and M_PI_2 (pi/2.) are defined in cmath.
424 if (PixTrkThetaI > M_PI_2)
425 PixTrkThetaI -= M_PI;
426 else if (PixTrkThetaI < -M_PI_2)
427 PixTrkThetaI += M_PI;
428 PixTrkThetaI = M_PI_2 - PixTrkThetaI;
429 if (PixTrkAngle > M_PI_2)
430 PixTrkAngle -= M_PI;
431 else if (PixTrkAngle < -M_PI_2)
432 PixTrkAngle += M_PI;
433 PixTrkAngle = M_PI_2 - PixTrkAngle;
434 if (theta > M_PI_2)
435 theta = M_PI - theta;
436 }
437
438 Identifier surfaceID;
440 if (m_detID->is_pixel(surfaceID)) {
441 const InDet::SiWidth& width = pixelCluster->width();
442 zWidth = static_cast<int>(width.colRow().y());
443 }
444
445 int isIBLclus = false;
446 if (m_doIBL && m_pixelID->barrel_ec(surfaceID) == 0 &&
447 m_pixelID->layer_disk(surfaceID) == 0) {
448 isIBLclus = true;
449 }
450
451 // count bad clusters
452 if (!isIBLclus) {
453 if ((size == 1 && tot < 8) || (size == 2 && tot < 15)) {
454 isBC_A1 = true;
455 nbc_meas_A1++;
456 }
457 // Need to replace these magic numbers with constexpr with meaning full names
458 if (charge < 13750. / std::cos(theta) - 22500.) {
459 isBC_B3 = true;
460 nbc_meas_B3++;
461 }
462 if (isBC_A1 || isBC_B3) {
463 nbc_meas_A1_or_B3++;
464 }
465 if ((zWidth == 1 && cotthetaz > 5.8) || (zWidth == 2 && cotthetaz > 5.8) ||
466 (zWidth == 3 && cotthetaz > 6.2) || (zWidth > 3 && cotthetaz < 2.5)) {
467 isBC_C = true;
468 }
469 if (isBC_A1 || isBC_B3 || isBC_C) {
470 nbc_meas_A1_or_B3_or_C++;
471 }
472 }
473 }
474 }
475 }
476 }
477 }
479 // search first valid TSOS first
480 for (const TrackStateOnSurface* tsos : *trackStates) {
481 if (tsos->type(TrackStateOnSurface::Measurement) && tsos->trackParameters() != nullptr &&
482 tsos->measurementOnTrack() != nullptr &&
483 !(tsos->measurementOnTrack()->type(Trk::MeasurementBaseType::PseudoMeasurementOnTrack))) {
484 first = tsos->trackParameters();
485 parameters.push_back(tsos->trackParameters());
486 parameterPositions.push_back(xAOD::FirstMeasurement);
487 break;
488 }
489 }
490
492 // search last valid TSOS first
493 for (Trk::TrackStates::const_reverse_iterator rItTSoS = trackStates->rbegin();
494 rItTSoS != trackStates->rend();
495 ++rItTSoS) {
496 if ((*rItTSoS)->type(TrackStateOnSurface::Measurement) &&
497 (*rItTSoS)->trackParameters() != nullptr && (*rItTSoS)->measurementOnTrack() != nullptr &&
498 !((*rItTSoS)->measurementOnTrack()->type(
500 if (!(first == (*rItTSoS)->trackParameters())) {
501 parameters.push_back((*rItTSoS)->trackParameters());
502 parameterPositions.push_back(xAOD::LastMeasurement);
503 }
504 break;
505 }
506 }
507 }
508
509 // security check:
510 if (parameters.size() > 2)
511 ATH_MSG_WARNING("More than two additional track parameters to be stored in TrackParticle!");
512 }
513
514 // KeepAllPerigee will keep all perigee's on the track plus the parameters at the first
515 // measurement, provided this measurement precedes any second perigee. The track (initial) perigee
516 // is the 'defining parameter' for the TrackParticle, by convention this is pushed to the back of
517 // the parameter vector by the TP constructor.
518 else if (m_keepAllPerigee) {
519 bool haveFirstMeasurementParameters = false;
520 for (const TrackStateOnSurface* tsos : *(track.trackStateOnSurfaces())) {
521 if (!tsos->trackParameters())
522 continue;
523
524 if (!haveFirstMeasurementParameters && tsos->type(TrackStateOnSurface::Measurement) &&
525 !tsos->type(TrackStateOnSurface::Outlier) && tsos->measurementOnTrack() &&
526 !(tsos->measurementOnTrack()->type(Trk::MeasurementBaseType::PseudoMeasurementOnTrack))) {
527 haveFirstMeasurementParameters = true;
528 parameters.push_back(tsos->trackParameters());
529 ATH_MSG_VERBOSE(" including first measurement parameters at R "
530 << tsos->trackParameters()->position().perp() << ", Z "
531 << tsos->trackParameters()->position().z());
532 parameterPositions.push_back(xAOD::FirstMeasurement);
533 continue;
534 }
535 if (!tsos->type(TrackStateOnSurface::Perigee) ||
536 !(tsos->trackParameters()->surfaceType() == Trk::SurfaceType::Perigee) ||
537 !(tsos->trackParameters()->type() == Trk::AtaSurface)) {
538 continue;
539 }
540 if (!aPer) {
541 aPer = static_cast<const Perigee*>(tsos->trackParameters());
542 } else {
543 parameters.push_back(tsos->trackParameters());
544 }
545
546 ATH_MSG_VERBOSE(" including perigee at R " << tsos->trackParameters()->position().perp() << ", Z "
547 << tsos->trackParameters()->position().z());
548
549 // we are not interested in keeping measurement parameters after any second perigee
550 if (!parameters.empty())
551 haveFirstMeasurementParameters = true;
552 }
553 }
554
555 xAOD::TrackParticle* trackparticle = createParticle(ctx,
556 aPer,
557 track.fitQuality(),
558 &track.info(),
559 summary,
560 parameters,
561 parameterPositions,
562 prtOrigin,
563 container,
564 &track);
565
566 static const SG::AuxElement::Accessor<int> nbCmeas("nBC_meas");
567 switch (m_badclusterID) {
568 case 1: {
569 nbCmeas(*trackparticle) = nbc_meas_A1;
570 break;
571 }
572 case 2: {
573 nbCmeas(*trackparticle) = nbc_meas_B3;
574 break;
575 }
576 case 3: {
577 nbCmeas(*trackparticle) = nbc_meas_A1_or_B3;
578 break;
579 }
580 case 4: {
581 nbCmeas(*trackparticle) = nbc_meas_A1_or_B3_or_C;
582 break;
583 }
584 default: {
585 }
586 }
587
588 delete parsToBeDeleted;
589 return trackparticle;
590}
591
594 const Rec::TrackParticle& trackParticle,
596{
597
598 // Attempt to fill the position enums - will necessarily be a bit of a hack, since we don't have
599 // all the information.
600 std::vector<xAOD::ParameterPosition> positions;
601 bool firstMeasurement = false;
602 for (const auto* parameter : trackParticle.trackParameters()) {
603 if (!firstMeasurement && parameter && !parameter->associatedSurface().isFree()) {
604 // if the surface isn't free, it must belong to a detector element => measurement
605 firstMeasurement = true;
606 positions.push_back(xAOD::FirstMeasurement);
607 } else if (firstMeasurement && parameter && !parameter->associatedSurface().isFree()) {
608 // Making the (possibly unfounded assumption that if we have the first measurement, the next
609 // will be the last)
610 positions.push_back(xAOD::LastMeasurement);
611 } else {
612 positions.push_back(xAOD::BeamLine); // Don't have a default yet!
613 }
614 }
615
616 xAOD::TrackParticle* trackparticle =
617 createParticle(ctx,
618 trackParticle.measuredPerigee(),
619 trackParticle.fitQuality(),
620 &trackParticle.info(),
621 trackParticle.trackSummary(),
622 trackParticle.trackParameters(),
623 positions,
624 static_cast<xAOD::ParticleHypothesis>(trackParticle.info().particleHypothesis()),
625 container,
626 nullptr);
627
628 if (!trackparticle) {
629 ATH_MSG_WARNING("WARNING: Problem creating TrackParticle - Returning 0");
630 return nullptr;
631 }
632
633 trackparticle->setTrackLink(*(trackParticle.trackElementLink()));
634
636 compare(trackParticle, *trackparticle);
637
638 return trackparticle;
639}
640
643 const ElementLink<TrackCollection>& trackLink,
645 const xAOD::Vertex* vxCandidate,
646 xAOD::ParticleHypothesis prtOrigin) const
647{
648
649 xAOD::TrackParticle* trackparticle =
650 createParticle(ctx, **trackLink, container, vxCandidate, prtOrigin);
651
652 if (!trackparticle) {
653 ATH_MSG_WARNING("WARNING: Problem creating TrackParticle - Returning 0");
654 return nullptr;
655 }
656
657 trackparticle->setTrackLink(trackLink);
658
659 return trackparticle;
660}
661
663 const EventContext& ctx,
664 const Perigee* perigee,
665 const FitQuality* fq,
666 const TrackInfo* trackInfo,
667 const TrackSummary* summary,
668 const std::vector<const Trk::TrackParameters*>& parameters,
669 const std::vector<xAOD::ParameterPosition>& positions,
670 xAOD::ParticleHypothesis prtOrigin,
672 return createParticle(ctx,perigee, fq, trackInfo, summary, parameters, positions, prtOrigin, container, nullptr);
673}
674
677 const Perigee* perigee,
678 const FitQuality* fq,
679 const TrackInfo* trackInfo,
680 const TrackSummary* summary,
681 const std::vector<const Trk::TrackParameters*>& parameters,
682 const std::vector<xAOD::ParameterPosition>& positions,
683 xAOD::ParticleHypothesis prtOrigin,
685 const Trk::Track *track) const
686{
687
688 xAOD::TrackParticle* trackparticle = new xAOD::TrackParticle;
689 if (!trackparticle) {
690 ATH_MSG_WARNING("WARNING: Problem creating TrackParticle - Returning 0");
691 return nullptr;
692 }
693 /*
694 * The following needs care as in one case the ownership
695 * can be passed to StoreGate i.e to the relevant container
696 * DataVector.
697 * In the other the caller has the ownership
698 */
699
700 if (container) {
701 container->push_back(trackparticle);
702 } else {
703 trackparticle->makePrivateStore();
704 }
705
706 // Fit quality
707 if (fq) {
708 setFitQuality(*trackparticle, *fq);
709 }
710 // Track Info
711 if (trackInfo) {
712 setTrackInfo(*trackparticle, *trackInfo, prtOrigin);
713 }
714 // track summary
715 if (summary) {
716 setTrackSummary(*trackparticle, *summary);
717 setHitPattern(*trackparticle, summary->getHitPattern());
718 addPIDInformation(ctx, track, *trackparticle);
719 if(m_doITk) addDetailedHitInformation(track->trackStateOnSurfaces(), *trackparticle);
720 }
721
722 if (m_computeAdditionalInfo && track!=nullptr) {
723 addExpectedHitInformation(track->perigeeParameters(), *trackparticle);
724 addOutlierHitInformation(track->trackStateOnSurfaces(), *trackparticle);
725 if(m_doSharedSiHits || m_doSharedTRTHits) addSharedHitInformation(track, *trackparticle);
726 else if(m_doITk) addDummyEndcapSharedHitInformation(*trackparticle);
727 }
728
729 const auto* beamspot = CacheBeamSpotData(ctx);
730 if (beamspot) {
731 setTilt(*trackparticle, beamspot->beamTilt(0), beamspot->beamTilt(1));
732 }
733 // Parameters
734 if (perigee) {
735 setDefiningParameters(*trackparticle, *perigee);
736 } else {
737 ATH_MSG_WARNING("Track without perigee parameters? Not setting any defining parameters!");
738 }
739 setParameters(ctx, *trackparticle, parameters, positions);
740
741 return trackparticle;
742}
743
744void
746{
747 int index = Amg::compare(tp1.parameters(), tp2.parameters(), 1e-6, true);
748 if (index != -1) {
749 ATH_MSG_WARNING("Bad parameters conversion " << Amg::toString(tp1.parameters(), 7) << " --- "
750 << Amg::toString(tp2.parameters(), 7));
751 }
752 if ((tp1.covariance() && !tp2.covariance()) || (!tp1.covariance() && tp2.covariance())) {
753 ATH_MSG_WARNING("Bad Covariance conversion " << tp1.covariance() << " --- " << tp2.covariance());
754 } else if (tp1.covariance() && tp2.covariance()) {
755 std::pair<int, int> indices = Amg::compare(*tp1.covariance(), *tp2.covariance(), 1e-6, true);
756 if (indices.first != -1)
757 ATH_MSG_WARNING("Bad Covariance conversion " << std::endl
758 << Amg::toString(*tp1.covariance(), 10) << std::endl
759 << Amg::toString(*tp2.covariance(), 10));
760 }
761}
762
763void
765{
766 if (tp.measuredPerigee()) {
767 compare(*tp.measuredPerigee(), tpx.perigeeParameters());
768 }
769
770 // trackParticle.info(),trackParticle.trackSummary(),
771 if (tp.trackParameters().size() != tpx.numberOfParameters()) {
772 ATH_MSG_WARNING("Number of parameters not the same " << tp.trackParameters().size() << " --- "
773 << tpx.numberOfParameters());
774 }
775}
776
777void
780 const std::vector<const Trk::TrackParameters*>& parameters,
781 const std::vector<xAOD::ParameterPosition>& positions) const
782{
783 std::vector<std::vector<float>> parametersVec;
784 parametersVec.resize(parameters.size());
785 unsigned int numParam = 0;
786
788 const AtlasFieldCacheCondObj* fieldCondObj{ *readHandle };
789 MagField::AtlasFieldCache fieldCache;
790 fieldCondObj->getInitializedCache(fieldCache);
791
792 for (const auto* param : parameters) {
793 std::vector<float>& values = parametersVec[numParam];
794 values.resize(6);
795 const Amg::Vector3D& pos = param->position();
796 const Amg::Vector3D& mom = param->momentum();
797 values[0] = pos[0];
798 values[1] = pos[1];
799 values[2] = pos[2];
800 values[3] = mom[0];
801 values[4] = mom[1];
802 values[5] = mom[2];
803
804 const bool straightPars = (!fieldCache.solenoidOn() && m_trackingVolumesSvc->volume(Trk::ITrackingVolumesSvc::CalorimeterEntryLayer).inside(pos)) ||
807 AmgSymMatrix(5) covarianceMatrix;
808 covarianceMatrix.setIdentity();
809
810 if (param->covariance()) {
811 // has covariance matrix
812 // now convert from to Curvilinear -- to be double checked for correctness
813 CurvilinearUVT curvilinearUVT(mom.unit());
814 if (!straightPars){
815 Amg::Vector3D magnFieldVect;
816 magnFieldVect.setZero();
817 fieldCache.getField(pos.data(), magnFieldVect.data());
818 const Amg::Transform3D& localToGlobalTransform = param->associatedSurface().transform();
819
820 JacobianLocalToCurvilinear jacobian(magnFieldVect,
821 param->parameters()[Trk::qOverP],
822 std::sin(param->parameters()[Trk::theta]),
823 curvilinearUVT,
824 localToGlobalTransform.rotation().col(0),
825 localToGlobalTransform.rotation().col(1));
826
827 covarianceMatrix = param->covariance()->similarity(jacobian);
828 } else {
829 const Amg::Vector3D loc_x {param->parameters()[Trk::locX],0,0};
830 const Amg::Vector3D loc_y {0,param->parameters()[Trk::locY],0};
831 JacobianLocalToCurvilinear jacobian(curvilinearUVT, loc_x, loc_y);
832 covarianceMatrix = param->covariance()->similarity(jacobian);
833 }
834 }
835 std::vector<float> covMatrixVec;
836 Amg::compress(covarianceMatrix, covMatrixVec);
837 tp.setTrackParameterCovarianceMatrix(numParam, covMatrixVec);
838
839 ++numParam;
840 }
841
842 tp.setTrackParameters(parametersVec);
843 unsigned int i = 0;
844 for (; i < positions.size(); ++i) {
845 tp.setParameterPosition(i, positions[i]);
846 if (positions[i] == xAOD::FirstMeasurement) {
847 float x_position = tp.parameterX(i);
848 float y_position = tp.parameterY(i);
849 tp.setRadiusOfFirstHit(std::sqrt(x_position * x_position + y_position * y_position));
850 tp.setIdentifierOfFirstHit(
851 parameters[i]->associatedSurface().associatedDetectorElementIdentifier().get_compact());
852 }
853 }
854}
855
856void
858{
859 tp.setBeamlineTiltX(tiltx);
860 tp.setBeamlineTiltY(tilty);
861}
862
863void
865{
866 tp.setHitPattern(hitpattern);
867}
868
869void
871{
872 tp.setNumberOfUsedHitsdEdx(hits);
873}
874
875void
877{
878 tp.setNumberOfIBLOverflowsdEdx(overflows);
879}
880
881void
883{
884 // ensure that xAOD TrackSummary and TrackSummary enums are in sync.
885 constexpr unsigned int xAodReferenceEnum1 = static_cast<unsigned int>(xAOD::numberOfTRTXenonHits);
886 constexpr unsigned int TrkReferenceEnum1 = static_cast<unsigned int>(Trk::numberOfTRTXenonHits);
887 static_assert(xAodReferenceEnum1 == TrkReferenceEnum1, "Trk and xAOD enums differ in their indices");
888 constexpr unsigned int xAodReferenceEnum2 = static_cast<unsigned int>(xAOD::numberOfTRTTubeHits);
889 constexpr unsigned int TrkReferenceEnum2 = static_cast<unsigned int>(Trk::numberOfTRTTubeHits);
890 static_assert(xAodReferenceEnum2 == TrkReferenceEnum2, "Trk and xAOD enums differ in their indices");
891
892 for (unsigned int i = 0; i < Trk::numberOfTrackSummaryTypes; i++) {
893 // Only add values which are +ve (i.e., which were created)
895 continue;
896 }
898 continue;
899 }
901 continue;
902 }
903 // skip values which are floats
904 if (std::find(unusedSummaryTypes.begin(), unusedSummaryTypes.end(), i) != unusedSummaryTypes.end()) {
905 continue;
906 }
908 continue;
909 }
910 if (m_doITk && i == Trk::numberOfContribPixelLayers){ // Filled in addDetailedHitInformation for ITk
911 continue;
912 }
913
914 int value = summary.get(static_cast<Trk::SummaryType>(i));
915 uint8_t uvalue = static_cast<uint8_t>(std::min(value,255));
916 // coverity[first_enum_type]
917 if (value > 0) {
918 tp.setSummaryValue(uvalue, static_cast<xAOD::SummaryType>(i));
919 }
920 }
921
922 // muon hit info
923 if (!m_hitSummaryTool.empty()) {
924 ATH_MSG_DEBUG("now do muon hit info");
926 uint8_t numberOfPrecisionLayers = msSummary.nprecisionLayers;
927 ATH_MSG_DEBUG("# of prec layers: " << static_cast<unsigned int>(numberOfPrecisionLayers));
928 uint8_t numberOfPrecisionHoleLayers = msSummary.nprecisionHoleLayers;
929 uint8_t numberOfPhiLayers = msSummary.nphiLayers;
930 uint8_t numberOfPhiHoleLayers = msSummary.nphiHoleLayers;
931 uint8_t numberOfTriggerEtaLayers = msSummary.ntrigEtaLayers;
932 uint8_t numberOfTriggerEtaHoleLayers = msSummary.ntrigEtaHoleLayers;
933 tp.setSummaryValue(numberOfPrecisionLayers, xAOD::numberOfPrecisionLayers);
934 tp.setSummaryValue(numberOfPrecisionHoleLayers, xAOD::numberOfPrecisionHoleLayers);
935 tp.setSummaryValue(numberOfPhiLayers, xAOD::numberOfPhiLayers);
936 tp.setSummaryValue(numberOfPhiHoleLayers, xAOD::numberOfPhiHoleLayers);
937 tp.setSummaryValue(numberOfTriggerEtaLayers, xAOD::numberOfTriggerEtaLayers);
938 tp.setSummaryValue(numberOfTriggerEtaHoleLayers, xAOD::numberOfTriggerEtaHoleLayers);
939 }
940
941}
942
943void
944TrackParticleCreatorTool::addPIDInformation(const EventContext& ctx, const Trk::Track *track, xAOD::TrackParticle& tp) const
945{
946 // TRT PID information
947 {
948 static const std::vector<float> eProbabilityDefault(numberOfeProbabilityTypes,0.5);
949 constexpr int initialValue{-1};
950 std::vector<float> eProbability_tmp;
951 const std::vector<float>& eProbability(
952 track && !m_eProbabilityTool.empty()
953 ? eProbability_tmp =
954 m_eProbabilityTool->electronProbability(ctx, *track)
956 int nHits = track && !m_eProbabilityTool.empty()
958 : initialValue;
959 for (const Trk::eProbabilityType& copy : m_copyEProbabilities) {
960 float eProbability_value = eProbability.at(copy);
961 tp.setSummaryValue(eProbability_value, static_cast<xAOD::SummaryType>(copy + xAOD::eProbabilityComb));
962 }
963 for (const std::pair<SG::AuxElement::Accessor<float>, Trk::eProbabilityType>& decoration :
965 float fvalue = eProbability.at(decoration.second);
966 decoration.first(tp) = fvalue;
967 }
968 // now the extra summary types
969 for (const std::pair<SG::AuxElement::Accessor<uint8_t>, Trk::SummaryType>& decoration :
971 uint8_t summary_value = nHits;
972 decoration.first(tp) = summary_value;
973 }
974
975 }
976
977 // PixelPID
978 {
979 const int initialValue{-1};
980 float dedx = initialValue;
981 int nHitsUsed_dEdx = initialValue;
982 int nOverflowHits_dEdx = initialValue;
983 if (track && !m_dedxtool.empty() && track->info().trackFitter() != TrackInfo::Unknown) {
984 dedx = m_dedxtool->dEdx(ctx, *track, nHitsUsed_dEdx, nOverflowHits_dEdx);
985 }
986 tp.setNumberOfUsedHitsdEdx(nHitsUsed_dEdx);
987 tp.setNumberOfIBLOverflowsdEdx(nOverflowHits_dEdx);
988 tp.setSummaryValue(dedx, static_cast<xAOD::SummaryType>(51));
989 }
990}
991
992void
994{
995
996 Trk::DetailedHitInfo detailedInfo;
997
998 for (const TrackStateOnSurface* tsos : *trackStates) {
999
1000 const Trk::MeasurementBase* mesb = tsos->measurementOnTrack();
1001 if(mesb==nullptr) continue;
1002 // Check if the measurement type is RIO on Track (ROT)
1003 const RIO_OnTrack* rot = nullptr;
1005 rot = static_cast<const RIO_OnTrack*>(mesb);
1006 }
1007 if(rot==nullptr) continue;
1008
1009 const Identifier& id = rot->identify();
1010 if(!m_pixelID->is_pixel(id)) continue;
1011
1012 Trk::DetectorRegion region;
1013 const InDetDD::SiDetectorElement* detEl = dynamic_cast<const InDetDD::SiDetectorElement*>(rot->detectorElement());
1017 else region = Trk::pixelEndcap;
1018
1019 detailedInfo.addHit(region, m_pixelID->layer_disk(id), m_pixelID->eta_module(id));
1020
1021 }
1022
1023 uint8_t nContribPixelLayers = static_cast<uint8_t>(detailedInfo.getPixelContributions());
1024
1025 uint8_t nContribPixelBarrelFlatLayers = static_cast<uint8_t>(detailedInfo.getContributionFromRegion(Trk::pixelBarrelFlat ));
1026 uint8_t nContribPixelBarrelInclinedLayers = static_cast<uint8_t>(detailedInfo.getContributionFromRegion(Trk::pixelBarrelInclined));
1027 uint8_t nContribPixelEndcap = static_cast<uint8_t>(detailedInfo.getContributionFromRegion(Trk::pixelEndcap ));
1028
1029 uint8_t nPixelBarrelFlatHits = static_cast<uint8_t>(detailedInfo.getHitsFromRegion(Trk::pixelBarrelFlat ));
1030 uint8_t nPixelBarrelInclinedHits = static_cast<uint8_t>(detailedInfo.getHitsFromRegion(Trk::pixelBarrelInclined));
1031 uint8_t nPixelEndcapHits = static_cast<uint8_t>(detailedInfo.getHitsFromRegion(Trk::pixelEndcap ));
1032
1033 uint8_t nInnermostPixelLayerEndcapHits = static_cast<uint8_t>(detailedInfo.getHits(Trk::pixelEndcap, 0));
1034 uint8_t nNextToInnermostPixelLayerEndcapHits = static_cast<uint8_t>(detailedInfo.getHits(Trk::pixelEndcap, 1)
1035 + detailedInfo.getHits(Trk::pixelEndcap, 2)); // L0.5 shorties + L1
1036
1037 tp.setSummaryValue(nContribPixelLayers, xAOD::numberOfContribPixelLayers);
1038 tp.setSummaryValue(nContribPixelBarrelFlatLayers, xAOD::numberOfContribPixelBarrelFlatLayers);
1039 tp.setSummaryValue(nContribPixelBarrelInclinedLayers, xAOD::numberOfContribPixelBarrelInclinedLayers);
1040 tp.setSummaryValue(nContribPixelEndcap, xAOD::numberOfContribPixelEndcap);
1041 tp.setSummaryValue(nPixelBarrelFlatHits, xAOD::numberOfPixelBarrelFlatHits);
1042 tp.setSummaryValue(nPixelBarrelInclinedHits, xAOD::numberOfPixelBarrelInclinedHits);
1043 tp.setSummaryValue(nPixelEndcapHits, xAOD::numberOfPixelEndcapHits);
1044 tp.setSummaryValue(nInnermostPixelLayerEndcapHits, xAOD::numberOfInnermostPixelLayerEndcapHits);
1045 tp.setSummaryValue(nNextToInnermostPixelLayerEndcapHits, xAOD::numberOfNextToInnermostPixelLayerEndcapHits);
1046
1047}
1048
1049void
1051{
1052
1053 if(m_testPixelLayerTool.empty() || perigee==nullptr) return;
1054
1055 uint8_t zero = static_cast<uint8_t>(0);
1056 uint8_t nContribPixLayers, nInPixHits, nNextInPixHits;
1057 if(!tp.summaryValue(nContribPixLayers, xAOD::numberOfContribPixelLayers)){
1058 nContribPixLayers = zero;
1059 }
1060 if(nContribPixLayers==0){
1061 ATH_MSG_DEBUG("No pixels on track, so wo do not expect hit in inner layers");
1062 tp.setSummaryValue(zero, xAOD::expectInnermostPixelLayerHit);
1064 }
1065
1066 else {
1067
1068 // Innermost pixel layer
1069 if(!tp.summaryValue(nInPixHits, xAOD::numberOfInnermostPixelLayerHits)){
1070 nInPixHits = zero;
1071 }
1072 if(nInPixHits>0){
1073 ATH_MSG_DEBUG("Innermost pixel Layer hit on track, so we expect an innermost pixel layer hit");
1074 uint8_t one = static_cast<uint8_t>(1);
1075 tp.setSummaryValue(one, xAOD::expectInnermostPixelLayerHit);
1076 } else {
1077 uint8_t expectHit = static_cast<uint8_t>(m_testPixelLayerTool->expectHitInInnermostPixelLayer(perigee));
1078 tp.setSummaryValue(expectHit, xAOD::expectInnermostPixelLayerHit);
1079 }
1080
1081 // Next-to-innermost pixel layer
1082 if(!tp.summaryValue(nNextInPixHits, xAOD::numberOfNextToInnermostPixelLayerHits)){
1083 nNextInPixHits = zero;
1084 }
1085 if(nNextInPixHits>0){
1086 ATH_MSG_DEBUG("Next-to-innermost pixel Layer hit on track, so we expect an next-to-innermost pixel layer hit");
1087 uint8_t one = static_cast<uint8_t>(1);
1088 tp.setSummaryValue(one, xAOD::expectNextToInnermostPixelLayerHit);
1089 } else {
1090 uint8_t expectHit = static_cast<uint8_t>(m_testPixelLayerTool->expectHitInNextToInnermostPixelLayer(perigee));
1091 tp.setSummaryValue(expectHit, xAOD::expectNextToInnermostPixelLayerHit);
1092 }
1093
1094 } // end else if nContribPixLayers>0
1095
1096}
1097
1098void
1100{
1101
1102 uint8_t nPixOutliers = 0, nInPixOutliers = 0, nNInPixOutliers = 0, nSCTOutliers = 0;
1103 uint8_t nInEndcapPixOutliers = 0, nNInEndcapPixOutliers = 0;
1104
1105 for (const TrackStateOnSurface* tsos : *trackStates) {
1106
1107 bool isOutlier = tsos->type(Trk::TrackStateOnSurface::Outlier);
1108 if(!isOutlier) continue;
1109
1110 const Trk::MeasurementBase* mesb = tsos->measurementOnTrack();
1111 if(mesb==nullptr) continue;
1112 // Check if the measurement type is RIO on Track (ROT)
1113 const RIO_OnTrack* rot = nullptr;
1115 rot = static_cast<const RIO_OnTrack*>(mesb);
1116 }
1117 if (rot == nullptr)
1118 continue;
1119
1120 const Identifier& id = rot->identify();
1121
1122 if (m_pixelID->is_pixel(id)) {
1123 nPixOutliers++;
1124 int layer = m_pixelID->layer_disk(id);
1125 if (m_pixelID->is_barrel(id)) {
1126 if (layer == 0){
1127 nInPixOutliers++;
1128 }
1129 else if (layer == 1){
1130 nNInPixOutliers++;
1131 }
1132 } else if (m_doITk) { // isITk && isEndCap -> ITk specific counters
1133 if (layer == 0){
1134 nInEndcapPixOutliers++;
1135 }
1136 else if (layer == 1 || layer == 2){
1137 nNInEndcapPixOutliers++; // L0.5 + L1 disks
1138 }
1139 }
1140 }
1141 else if (m_sctID->is_sct(id)) {
1142 nSCTOutliers++;
1143 }
1144
1145 // TRT outliers are already filled in the InDetTrackSummaryHelperTool as
1146 // used in the ambi solver
1147 }
1148
1149 tp.setSummaryValue(nPixOutliers, xAOD::numberOfPixelOutliers);
1150 tp.setSummaryValue(nInPixOutliers, xAOD::numberOfInnermostPixelLayerOutliers);
1151 tp.setSummaryValue(nNInPixOutliers, xAOD::numberOfNextToInnermostPixelLayerOutliers);
1152 tp.setSummaryValue(nSCTOutliers, xAOD::numberOfSCTOutliers);
1153
1154 if(m_doITk){
1155 tp.setSummaryValue(nInEndcapPixOutliers, xAOD::numberOfInnermostPixelLayerEndcapOutliers);
1156 tp.setSummaryValue(nNInEndcapPixOutliers, xAOD::numberOfNextToInnermostPixelLayerEndcapOutliers);
1157 }
1158
1159}
1160
1161void
1163{
1164
1165 uint8_t nPixSharedHits = 0, nInPixSharedHits = 0, nNInPixSharedHits = 0, nSCTSharedHits = 0, nTRTSharedHits = 0;
1166 uint8_t nInPixSharedEndcapHits = 0, nNInPixSharedEndcapHits = 0;
1167 uint8_t nPixSplitHits = 0, nInPixSplitHits = 0, nNInPixSplitHits = 0;
1168 uint8_t nInPixSplitEndcapHits = 0, nNInPixSplitEndcapHits = 0;
1169
1170 const DataVector<const Trk::MeasurementBase>* measurements = track->measurementsOnTrack();
1171 if(!measurements){
1172 ATH_MSG_DEBUG("No measurement on track");
1173 return;
1174 }
1175
1176 const EventContext& ctx = Gaudi::Hive::currentContext();
1178
1179 for (const auto* const ms : *measurements) {
1180 // check if it's a rot
1181 const Trk::RIO_OnTrack* rot = nullptr;
1183 rot = static_cast<const Trk::RIO_OnTrack*>(ms);
1184 }
1185 if (!rot) {
1186 ATH_MSG_DEBUG("Cannot cast measurement to RIO_OnTrack");
1187 continue;
1188 }
1189
1190 const Identifier& id = rot->identify();
1191
1192 if (m_doSharedSiHits && m_pixelID->is_pixel(id)) {
1193 // check if split, when running TIDE
1194 bool hitIsSplit(false);
1195 if (m_runningTIDE_Ambi) {
1196 const InDet::PixelClusterOnTrack* pix = nullptr;
1198 pix = static_cast<const InDet::PixelClusterOnTrack*>(rot);
1199 }
1200 if (pix) {
1201 const InDet::PixelCluster* pixPrd = pix->prepRawData();
1203 splitProb = getClusterSplittingProbability(pixPrd);
1204 int layer = m_pixelID->layer_disk(id);
1205 if (pixPrd and splitProb.isSplit()) {
1206 ATH_MSG_DEBUG("split Pixel hit found");
1207 hitIsSplit = true;
1208 nPixSplitHits++;
1209 if (m_pixelID->is_barrel(id)) {
1210 if (layer == 0)
1211 nInPixSplitHits++;
1212 else if (layer == 1)
1213 nNInPixSplitHits++;
1214 } else if (m_doITk) { // isITk && isEndCap -> ITk specific counters
1215 if (layer == 0)
1216 nInPixSplitEndcapHits++;
1217 else if (layer == 1 || layer == 2)
1218 nNInPixSplitEndcapHits++; // L0.5 + L1 disks
1219 }
1220 }
1221 }
1222 }
1223
1224 // check if shared
1225 // if we are running the TIDE ambi don't count split hits as shared
1226 if (!hitIsSplit) {
1227 if (prd_to_track_map->isShared(*(rot->prepRawData()))) {
1228 ATH_MSG_DEBUG("shared Pixel hit found");
1229 nPixSharedHits++;
1230 int layer = m_pixelID->layer_disk(id);
1231 if (m_pixelID->is_barrel(id)) {
1232 if (layer == 0)
1233 nInPixSharedHits++;
1234 else if (layer == 1)
1235 nNInPixSharedHits++;
1236 } else if (m_doITk) { // isITk && isEndCap -> ITk specific counters
1237 if (layer == 0)
1238 nInPixSharedEndcapHits++;
1239 else if (layer == 1 || layer == 2)
1240 nNInPixSharedEndcapHits++; // L0.5 + L1 disks
1241 }
1242 }
1243 }
1244
1245 } // end pixel
1246
1247 else if (m_doSharedSiHits && m_sctID->is_sct(id)) {
1248 if (prd_to_track_map->isShared(*(rot->prepRawData()))) {
1249 ATH_MSG_DEBUG("shared SCT hit found");
1250 nSCTSharedHits++;
1251 }
1252 }
1253
1254 else if (m_doSharedTRTHits && m_trtID->is_trt(id)) {
1255 if (prd_to_track_map->isShared(*(rot->prepRawData()))) {
1256 ATH_MSG_DEBUG("shared TRT hit found");
1257 nTRTSharedHits++;
1258 }
1259 }
1260 }
1261
1262 tp.setSummaryValue(nPixSplitHits, xAOD::numberOfPixelSplitHits);
1263 tp.setSummaryValue(nInPixSplitHits, xAOD::numberOfInnermostPixelLayerSplitHits);
1264 tp.setSummaryValue(nNInPixSplitHits, xAOD::numberOfNextToInnermostPixelLayerSplitHits);
1265
1266 tp.setSummaryValue(nPixSharedHits, xAOD::numberOfPixelSharedHits);
1267 tp.setSummaryValue(nInPixSharedHits, xAOD::numberOfInnermostPixelLayerSharedHits);
1268 tp.setSummaryValue(nNInPixSharedHits, xAOD::numberOfNextToInnermostPixelLayerSharedHits);
1269 tp.setSummaryValue(nSCTSharedHits, xAOD::numberOfSCTSharedHits);
1270 tp.setSummaryValue(nTRTSharedHits, xAOD::numberOfTRTSharedHits);
1271
1272 if(m_doITk){
1273 tp.setSummaryValue(nInPixSplitEndcapHits, xAOD::numberOfInnermostPixelLayerSplitEndcapHits);
1274 tp.setSummaryValue(nNInPixSplitEndcapHits, xAOD::numberOfNextToInnermostPixelLayerSplitEndcapHits);
1275 tp.setSummaryValue(nInPixSharedEndcapHits, xAOD::numberOfInnermostPixelLayerSharedEndcapHits);
1276 tp.setSummaryValue(nNInPixSharedEndcapHits, xAOD::numberOfNextToInnermostPixelLayerSharedEndcapHits);
1277 }
1278
1279}
1280
1281
1282void
1284{
1285
1286 uint8_t nInPixSharedEndcapHits = 0, nNInPixSharedEndcapHits = 0;
1287 uint8_t nInPixSplitEndcapHits = 0, nNInPixSplitEndcapHits = 0;
1288
1289 tp.setSummaryValue(nInPixSplitEndcapHits, xAOD::numberOfInnermostPixelLayerSplitEndcapHits);
1290 tp.setSummaryValue(nNInPixSplitEndcapHits, xAOD::numberOfNextToInnermostPixelLayerSplitEndcapHits);
1291 tp.setSummaryValue(nInPixSharedEndcapHits, xAOD::numberOfInnermostPixelLayerSharedEndcapHits);
1292 tp.setSummaryValue(nNInPixSharedEndcapHits, xAOD::numberOfNextToInnermostPixelLayerSharedEndcapHits);
1293
1294}
1295
1296
1299{
1300 const EventContext& ctx = Gaudi::Hive::currentContext();
1301 if (!pix || m_clusterSplitProbContainer.key().empty()) {
1303 }
1305 if (!splitProbContainer.isValid()) {
1306 ATH_MSG_FATAL("Failed to get cluster splitting probability container "
1308 }
1309 return splitProbContainer->splitProbability(pix);
1310}
1311
1312
1315{
1317 return beamSpotHandle.cptr();
1318}
1319
1320} // 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
static const uint32_t nHits
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.
void makePrivateStore()
Create a new (empty) private store for this object.
SG::Accessor< T, ALLOC > Accessor
Definition AuxElement.h:572
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.
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
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 setTrackLink(const ElementLink< TrackCollection > &track)
Set the link to the original track.
const Trk::Perigee & perigeeParameters() const
Returns the Trk::MeasuredPerigee track parameters.
size_t numberOfParameters() const
Returns the number of additional parameters stored in the TrackParticle.
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
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
@ 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.
@ 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