469{
470 if (not fitResult.ok())
471 return nullptr;
472
473 std::unique_ptr<Trk::Track> newtrack = nullptr;
474
475 const auto& acts_track = fitResult.value();
476 auto finalTrajectory = std::make_unique<Trk::TrackStates>();
477
478 int numberOfDeadPixel = 0;
479 int numberOfDeadSCT = 0;
480
481 std::vector<std::unique_ptr<const Acts::BoundTrackParameters>> actsSmoothedParam;
482
483 tracks.trackStateContainer().visitBackwards(acts_track.tipIndex(),
484 [&] (const auto &state) -> void
485 {
486
487 auto flag = state.typeFlags();
488 const auto* associatedDetEl = state.referenceSurface().associatedDetectorElement();
489 if (not associatedDetEl)
490 return;
491
492 const auto* actsElement = dynamic_cast<const ActsDetectorElement*>(associatedDetEl);
493 if (not actsElement)
494 return;
495
496 const auto* upstreamDetEl = actsElement->upstreamDetectorElement();
497 if (not upstreamDetEl)
498 return;
499
500 ATH_MSG_VERBOSE("Try casting to TRT for if");
501 if (dynamic_cast<const InDetDD::TRT_BaseElement*>(upstreamDetEl))
502 return;
503
504 const auto* trkDetElem = dynamic_cast<const Trk::TrkDetElementBase*>(upstreamDetEl);
505 if (not trkDetElem)
506 return;
507
508 ATH_MSG_VERBOSE("trkDetElem type: " << static_cast<std::underlying_type_t<Trk::DetectorElemType>>(trkDetElem->detectorType()));
509
510 ATH_MSG_VERBOSE("Try casting to SiDetectorElement");
511 const auto* detElem = dynamic_cast<const InDetDD::SiDetectorElement*>(upstreamDetEl);
512 if (not detElem)
513 return;
514 ATH_MSG_VERBOSE("detElem = " << detElem);
515
516
517 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern;
518 std::unique_ptr<Trk::TrackParameters> parm;
519
520
521 if (flag.test(Acts::TrackStateFlag::HoleFlag)){
522 ATH_MSG_VERBOSE("State is a hole (no associated measurement), use predicted parameters");
523 const Acts::BoundTrackParameters actsParam(state.referenceSurface().getSharedPtr(),
524 state.predicted(),
525 state.predictedCovariance(),
526 acts_track.particleHypothesis());
527 parm = m_ATLASConverterTool->actsTrackParametersToTrkParameters(actsParam, tgContext);
528 auto boundaryCheck = m_boundaryCheckTool->boundaryCheck(*parm);
529
530 ATH_MSG_VERBOSE("Check if this is a hole, a dead sensors or a state outside the sensor boundary");
531 if(boundaryCheck == Trk::BoundaryCheckResult::DeadElement){
532 if (detElem->isPixel()) {
533 ++numberOfDeadPixel;
534 }
535 else if (detElem->isSCT()) {
536 ++numberOfDeadSCT;
537 }
538
539 return;
540 } else if (boundaryCheck != Trk::BoundaryCheckResult::Candidate){
541
542 return;
543 }
544 typePattern.set(Trk::TrackStateOnSurface::Hole);
545 }
546
547 else if (
flag.test(Acts::TrackStateFlag::OutlierFlag) or not state.hasSmoothed()) {
548 ATH_MSG_VERBOSE("The state was tagged as an outlier or was missed in the reverse filtering, use filtered parameters");
549 const Acts::BoundTrackParameters actsParam(state.referenceSurface().getSharedPtr(),
550 state.filtered(),
551 state.filteredCovariance(),
552 acts_track.particleHypothesis());
553 parm = m_ATLASConverterTool->actsTrackParametersToTrkParameters(actsParam, tgContext);
554 typePattern.set(Trk::TrackStateOnSurface::Outlier);
555 }
556
557 else{
558 ATH_MSG_VERBOSE("The state is a measurement state, use smoothed parameters");
559
560 const Acts::BoundTrackParameters actsParam(state.referenceSurface().getSharedPtr(),
561 state.smoothed(),
562 state.smoothedCovariance(),
563 acts_track.particleHypothesis());
564
565 actsSmoothedParam.push_back(std::make_unique<const Acts::BoundTrackParameters>(Acts::BoundTrackParameters(actsParam)));
566 parm = m_ATLASConverterTool->actsTrackParametersToTrkParameters(actsParam, tgContext);
567 typePattern.set(Trk::TrackStateOnSurface::Measurement);
568 }
569
570 std::unique_ptr<Trk::MeasurementBase> measState;
571 if (state.hasUncalibratedSourceLink()){
572 auto sl = state.getUncalibratedSourceLink().template get<ATLASSourceLink>();
573 assert(sl);
574 measState = sl->uniqueClone();
575 }
576 double nDoF = state.calibratedSize();
577 auto quality =Trk::FitQualityOnSurface(state.chi2(), nDoF);
578 const Trk::TrackStateOnSurface *perState = new Trk::TrackStateOnSurface(quality, std::move(measState), std::move(parm), nullptr, typePattern);
579
581 ATH_MSG_VERBOSE(
"State succesfully creates, adding it to the trajectory");
582 finalTrajectory->insert(finalTrajectory->begin(), perState);
583 }
584 });
585
586
587 const Acts::BoundTrackParameters actsPer(acts_track.referenceSurface().getSharedPtr(),
588 acts_track.parameters(),
589 acts_track.covariance(),
590 acts_track.particleHypothesis());
591 std::unique_ptr<Trk::TrackParameters> per =
m_ATLASConverterTool->actsTrackParametersToTrkParameters(actsPer, tgContext);
592 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern;
594 const Trk::TrackStateOnSurface *perState = new Trk::TrackStateOnSurface(nullptr, std::move(per), nullptr, typePattern);
595 if (perState) finalTrajectory->insert(finalTrajectory->begin(), perState);
596
597
600 newtrack = std::make_unique<Trk::Track>(newInfo, std::move(finalTrajectory), nullptr);
602
603 if (!newtrack->trackSummary()) {
604 newtrack->setTrackSummary(std::make_unique<Trk::TrackSummary>());
610 }
612 }
613
614 return newtrack;
615}
@ GaussianSumFilter
Tracks from Gaussian Sum Filter.
@ Perigee
This represents a perigee, and so will contain a Perigee object only.
@ numberOfTRTHoles
number of TRT hits which pass the high threshold (only xenon counted) total number of TRT hits which ...
@ numberOfSCTHoles
number of Holes in both sides of a SCT module
@ numberOfSCTDeadSensors
number of TRT hits
@ numberOfPixelHoles
number of pixels which have a ganged ambiguity.
@ numberOfPixelDeadSensors
number of pixel hits with broad errors (width/sqrt(12))