696 if (not fitResult.ok())
699 std::unique_ptr<Trk::Track> newtrack =
nullptr;
701 const auto& acts_track = fitResult.value();
702 auto finalTrajectory = std::make_unique<Trk::TrackStates>();
704 int numberOfDeadPixel = 0;
705 int numberOfDeadSCT = 0;
707 std::vector<std::unique_ptr<const Acts::BoundTrackParameters>> actsSmoothedParam;
709 tracks.trackStateContainer().visitBackwards(acts_track.tipIndex(),
710 [&] (
const auto &state) ->
void
713 auto flag = state.typeFlags();
714 const auto* associatedDetEl = state.referenceSurface().associatedDetectorElement();
715 if (not associatedDetEl)
718 const auto* actsElement = dynamic_cast<const ActsDetectorElement*>(associatedDetEl);
722 const auto* upstreamDetEl = actsElement->upstreamDetectorElement();
723 if (not upstreamDetEl)
726 ATH_MSG_VERBOSE(
"Try casting to TRT for if");
727 if (dynamic_cast<const InDetDD::TRT_BaseElement*>(upstreamDetEl))
730 const auto* trkDetElem = dynamic_cast<const Trk::TrkDetElementBase*>(upstreamDetEl);
734 ATH_MSG_VERBOSE(
"trkDetElem type: " << static_cast<std::underlying_type_t<Trk::DetectorElemType>>(trkDetElem->detectorType()));
736 ATH_MSG_VERBOSE(
"Try casting to SiDetectorElement");
737 const auto* detElem = dynamic_cast<const InDetDD::SiDetectorElement*>(upstreamDetEl);
740 ATH_MSG_VERBOSE(
"detElem = " << detElem);
743 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern;
744 std::unique_ptr<Trk::TrackParameters> parm;
747 if (flag.test(Acts::TrackStateFlag::HoleFlag)){
748 ATH_MSG_VERBOSE(
"State is a hole (no associated measurement), use predicted parameters");
749 const Acts::BoundTrackParameters actsParam(state.referenceSurface().getSharedPtr(),
751 state.predictedCovariance(),
752 acts_track.particleHypothesis());
753 parm = m_ATLASConverterTool->actsTrackParametersToTrkParameters(actsParam, tgContext);
754 auto boundaryCheck = m_boundaryCheckTool->boundaryCheck(*parm);
757 ATH_MSG_VERBOSE(
"Check if this is a hole, a dead sensors or a state outside the sensor boundary");
758 if(boundaryCheck == Trk::BoundaryCheckResult::DeadElement){
759 if (detElem->isPixel()) {
762 else if (detElem->isSCT()) {
767 } else if (boundaryCheck != Trk::BoundaryCheckResult::Candidate){
771 typePattern.set(Trk::TrackStateOnSurface::Hole);
774 else if (
flag.test(Acts::TrackStateFlag::OutlierFlag) or !state.hasSmoothed()) {
775 ATH_MSG_VERBOSE(
"The state was tagged as an outlier or was missed in the reverse filtering, use filtered parameters");
776 const Acts::BoundTrackParameters actsParam(state.referenceSurface().getSharedPtr(),
778 state.filteredCovariance(),
779 acts_track.particleHypothesis());
780 parm = m_ATLASConverterTool->actsTrackParametersToTrkParameters(actsParam, tgContext);
781 typePattern.set(Trk::TrackStateOnSurface::Outlier);
785 ATH_MSG_VERBOSE(
"The state is a measurement state, use smoothed parameters");
787 const Acts::BoundTrackParameters actsParam(state.referenceSurface().getSharedPtr(),
789 state.smoothedCovariance(),
790 acts_track.particleHypothesis());
792 actsSmoothedParam.push_back(std::make_unique<const Acts::BoundTrackParameters>(Acts::BoundTrackParameters(actsParam)));
793 parm = m_ATLASConverterTool->actsTrackParametersToTrkParameters(actsParam, tgContext);
794 typePattern.set(Trk::TrackStateOnSurface::Measurement);
796 std::unique_ptr<Trk::MeasurementBase> measState;
797 if (state.hasUncalibratedSourceLink() && !SourceLinkType){
798 auto sl = state.getUncalibratedSourceLink().template get<ATLASSourceLink>();
800 measState = sl->uniqueClone();
802 else if (state.hasUncalibratedSourceLink() && SourceLinkType){
803 auto sl = state.getUncalibratedSourceLink().template get<PRDSourceLink>().prd;
806 const IdentifierHash idHash = sl->detectorElement()->identifyHash();
807 int dim = state.calibratedSize();
808 std::unique_ptr<Trk::RIO_OnTrack> rot;
810 const InDet::SCT_Cluster* sct_Cluster = dynamic_cast<const InDet::SCT_Cluster*>(sl);
812 ATH_MSG_ERROR(
"ERROR could not cast PRD to SCT_Cluster");
815 rot = std::make_unique<InDet::SCT_ClusterOnTrack>(sct_Cluster,Trk::LocalParameters(Trk::DefinedParameter(state.template calibrated<1>()[0], Trk::loc1)), state.template calibratedCovariance<1>(),idHash);
821 ATH_MSG_VERBOSE(
"Dimension is 2 but we need SCT_Cluster for this measurment");
826 rot = std::make_unique<InDet::PixelClusterOnTrack>(
pixelCluster,
Trk::LocalParameters(state.template calibrated<2>()),state.template calibratedCovariance<2>(),idHash);
830 throw std::domain_error(
"Cannot handle measurement dim>2");
832 measState = rot->uniqueClone();
834 double nDoF = state.calibratedSize();
839 ATH_MSG_VERBOSE(
"State succesfully creates, adding it to the trajectory");
840 finalTrajectory->insert(finalTrajectory->begin(), perState);
844 const Acts::BoundTrackParameters actsPer(acts_track.referenceSurface().getSharedPtr(),
845 acts_track.parameters(),
846 acts_track.covariance(),
847 acts_track.particleHypothesis());
848 std::unique_ptr<Trk::TrackParameters> per =
m_ATLASConverterTool->actsTrackParametersToTrkParameters(actsPer, tgContext);
849 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern;
852 if (perState) finalTrajectory->insert(finalTrajectory->begin(), perState);
857 newtrack = std::make_unique<Trk::Track>(newInfo, std::move(finalTrajectory),
nullptr);