14 #include "Acts/Propagator/MultiEigenStepperLoop.hpp"
15 #include "Acts/MagneticField/MagneticFieldContext.hpp"
16 #include "Acts/Surfaces/PerigeeSurface.hpp"
17 #include "Acts/Utilities/CalibrationContext.hpp"
18 #include "Acts/Definitions/TrackParametrization.hpp"
19 #include "Acts/Definitions/Units.hpp"
20 #include "Acts/Propagator/EigenStepper.hpp"
21 #include "Acts/Surfaces/Surface.hpp"
22 #include "Acts/TrackFitting/GsfMixtureReduction.hpp"
23 #include "Acts/Utilities/Helpers.hpp"
24 #include "Acts/EventData/VectorMultiTrajectory.hpp"
25 #include "Acts/EventData/VectorTrackContainer.hpp"
26 #include "Acts/EventData/TrackParameters.hpp"
27 #include "Acts/Utilities/Logger.hpp"
28 #include "Acts/Utilities/CalibrationContext.hpp"
37 #include "Acts/Propagator/DirectNavigator.hpp"
43 #include <type_traits>
44 #include <system_error>
50 const IInterface*
p) :
68 auto field = std::make_shared<ATLASMagneticFieldWrapper>();
69 Acts::MultiEigenStepperLoop<> stepper(
field);
71 logger().cloneWithSuffix(
"Navigator") );
72 Acts::Propagator<Acts::MultiEigenStepperLoop<>,
Acts::Navigator> propagator(std::move(stepper),
74 logger().cloneWithSuffix(
"Prop"));
76 Acts::AtlasBetheHeitlerApprox<6, 5> bha = Acts::makeDefaultBetheHeitlerApprox();
77 m_fitter = std::make_unique<Fitter>(std::move(propagator), std::move(bha),
78 logger().cloneWithSuffix(
"GaussianSumFitter"));
82 Acts::DirectNavigator directNavigator(
logger().cloneWithSuffix(
"DirectNavigator") );
83 Acts::MultiEigenStepperLoop<> stepperDirect(
field);
84 Acts::Propagator<Acts::MultiEigenStepperLoop<>, Acts::DirectNavigator> directPropagator(std::move(stepperDirect),
85 std::move(directNavigator),
86 logger().cloneWithSuffix(
"DirectPropagator"));
87 Acts::AtlasBetheHeitlerApprox<6, 5> bhaDirect = Acts::makeDefaultBetheHeitlerApprox();
88 m_directFitter = std::make_unique<DirectFitter>(std::move(directPropagator),std::move(bhaDirect),
89 logger().cloneWithSuffix(
"DirectGaussianSumFitter"));
93 m_gsfExtensions.updater.connect<&ActsTrk::detail::FitterHelperFunctions::gainMatrixUpdate<ActsTrk::MutableTrackStateBackend>>();
95 m_gsfExtensions.calibrator.connect<&ActsTrk::detail::TrkMeasurementCalibrator::calibrate<ActsTrk::MutableTrackStateBackend>>(
m_calibrator.get());
99 m_gsfExtensions.mixtureReducer.connect<&Acts::reduceMixtureWithKLDistance>();
117 return StatusCode::SUCCESS;
122 std::unique_ptr<Trk::Track>
130 std::unique_ptr<Trk::Track> track =
nullptr;
131 ATH_MSG_VERBOSE (
"--> enter GaussianSumFitter::fit(Track,,) with Track from author = "
136 ATH_MSG_DEBUG(
"called to refit empty track or track with too little information, reject fit");
142 ATH_MSG_DEBUG(
"input fails to provide track parameters for seeding the GSF, reject fit");
147 std::shared_ptr<Acts::PerigeeSurface> pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(
153 Acts::CalibrationContext calContext{};
156 Acts::GsfOptions<ActsTrk::MutableTrackStateBackend>
166 std::vector<Acts::SourceLink> trackSourceLinks =
m_ATLASConverterTool->trkTrackToSourceLinks(tgContext,inputTrack);
178 std::unique_ptr<Trk::Track>
185 std::unique_ptr<Trk::Track> track =
nullptr;
187 if (inputMeasSet.size() < 2) {
188 ATH_MSG_DEBUG(
"called to refit empty measurement set or a measurement set with too little information, reject fit");
193 std::shared_ptr<Acts::PerigeeSurface> pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(
199 Acts::CalibrationContext calContext{};
202 Acts::GsfOptions<ActsTrk::MutableTrackStateBackend>
209 gsfOptions.abortOnError =
false;
211 std::vector< Acts::SourceLink > trackSourceLinks;
212 trackSourceLinks.reserve(inputMeasSet.size());
214 for (
auto* measSet : inputMeasSet) {
215 trackSourceLinks.push_back(
m_ATLASConverterTool->trkMeasurementToSourceLink(tgContext, *measSet));
218 const auto& initialParams =
m_ATLASConverterTool->trkTrackParametersToActsParameters(estimatedStartParameters, tgContext);
222 std::vector<const Acts::Surface*> surfaces;
223 surfaces.reserve(inputMeasSet.size());
224 for (
auto* measSet : inputMeasSet) {
229 surfaces.push_back(&actsSrf);
249 std::unique_ptr<Trk::Track>
264 std::unique_ptr<Trk::Track>
271 ATH_MSG_VERBOSE (
"--> enter GaussianSumFitter::fit(Track,Meas'BaseSet,,)");
275 if (addMeasColl.empty()) {
276 ATH_MSG_DEBUG(
"client tries to add an empty MeasurementSet to the track fit." );
277 return fit(ctx,inputTrack);
282 ATH_MSG_DEBUG(
"called to refit empty track or track with too little information, reject fit");
288 ATH_MSG_DEBUG(
"input fails to provide track parameters for seeding the GSF, reject fit");
292 std::unique_ptr<Trk::Track> track =
nullptr;
295 std::shared_ptr<Acts::PerigeeSurface> pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(
Acts::Vector3::Zero());
300 Acts::CalibrationContext calContext{};
303 Acts::GsfOptions<ActsTrk::MutableTrackStateBackend>
309 std::vector<Acts::SourceLink> trackSourceLinks =
m_ATLASConverterTool->trkTrackToSourceLinks(tgContext, inputTrack);
312 for (
auto* meas : addMeasColl) {
325 std::unique_ptr<Trk::Track>
333 ATH_MSG_DEBUG(
"Fit of Track with additional PrepRawDataSet not yet implemented");
339 std::unique_ptr<Trk::Track>
352 ATH_MSG_DEBUG(
"input #2 is empty try to fit track 1 alone" );
353 return fit(ctx,intrk1);
358 ATH_MSG_DEBUG(
"input #1 is empty try to fit track 2 alone" );
359 return fit(ctx,intrk2);
364 ATH_MSG_DEBUG(
"input #1 fails to provide track parameters for seeding the GSF, reject fit");
368 std::unique_ptr<Trk::Track> track =
nullptr;
371 std::shared_ptr<Acts::PerigeeSurface> pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(
377 Acts::CalibrationContext calContext{};
380 Acts::GsfOptions<ActsTrk::MutableTrackStateBackend>
386 std::vector<Acts::SourceLink> trackSourceLinks =
m_ATLASConverterTool->trkTrackToSourceLinks(tgContext, intrk1);
387 std::vector<Acts::SourceLink> trackSourceLinks2 =
m_ATLASConverterTool->trkTrackToSourceLinks(tgContext, intrk2);
388 trackSourceLinks.insert(trackSourceLinks.end(), trackSourceLinks2.begin(), trackSourceLinks2.end());
399 std::unique_ptr< ActsTrk::MutableTrackContainer >
402 const Acts::BoundTrackParameters& ,
403 const Acts::GeometryContext& ,
404 const Acts::MagneticFieldContext& ,
405 const Acts::CalibrationContext& ,
408 ATH_MSG_VERBOSE(
"ACTS seed refit is not implemented in GaussianSumFitterTool");
412 std::unique_ptr< ActsTrk::MutableTrackContainer >
414 const std::vector< ActsTrk::ATLASUncalibSourceLink> & ,
415 const Acts::BoundTrackParameters& ,
416 const Acts::GeometryContext& ,
417 const Acts::MagneticFieldContext& ,
418 const Acts::CalibrationContext& ,
420 const Acts::Surface* )
const
422 ATH_MSG_VERBOSE(
"ACTS uncalib slink refit is not implemented in GaussianSumFitterTool");
428 const EventContext& ctx,
429 const ActsTrk::TrackContainer::ConstTrackProxy& track,
433 const Acts::BoundTrackParameters initialParams = track.createParametersAtReference();
434 std::vector<Acts::SourceLink> sourceLinks;
435 std::vector<const Acts::Surface*> surfSequence;
437 for (
auto ts : track.trackStatesReversed()) {
438 surfSequence.push_back(&
ts.referenceSurface());
439 if (!
ts.hasCalibrated()) {
443 if (
ts.typeFlags().test(Acts::TrackStateFlag::MeasurementFlag)) {
448 if (sourceLinks.size() < 2) {
449 ATH_MSG_DEBUG(
"called to refit 0 or 1 sourceLink with too little information, reject fit");
450 return StatusCode::SUCCESS;
454 std::shared_ptr<Acts::PerigeeSurface> pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(
Acts::Vector3::Zero());
458 Acts::CalibrationContext calContext{};
460 Acts::GsfOptions<ActsTrk::MutableTrackStateBackend> gsfOptions =
prepareOptions(tgContext, mfContext, calContext, *pSurface);
463 if (!actsTrackingGeometry) {
465 return StatusCode::FAILURE;
473 gsfOptions.extensions = gsfExtensions;
474 gsfOptions.abortOnError =
false;
482 return StatusCode::SUCCESS;
485 std::unique_ptr<Trk::Track>
487 const Acts::GeometryContext& tgContext,
489 Acts::Result<typename ActsTrk::MutableTrackContainer::TrackProxy, std::error_code>& fitResult)
const
491 if (not fitResult.ok())
494 std::unique_ptr<Trk::Track> newtrack =
nullptr;
496 const auto& acts_track = fitResult.value();
497 auto finalTrajectory = std::make_unique<Trk::TrackStates>();
499 int numberOfDeadPixel = 0;
500 int numberOfDeadSCT = 0;
502 std::vector<std::unique_ptr<const Acts::BoundTrackParameters>> actsSmoothedParam;
504 tracks.trackStateContainer().visitBackwards(acts_track.tipIndex(),
505 [&] (
const auto &state) ->
void
508 auto flag = state.typeFlags();
509 const auto* associatedDetEl = state.referenceSurface().associatedDetectorElement();
510 if (not associatedDetEl)
513 const auto* actsElement = dynamic_cast<const ActsDetectorElement*>(associatedDetEl);
517 const auto* upstreamDetEl = actsElement->upstreamDetectorElement();
518 if (not upstreamDetEl)
521 ATH_MSG_VERBOSE(
"Try casting to TRT for if");
522 if (dynamic_cast<const InDetDD::TRT_BaseElement*>(upstreamDetEl))
525 const auto* trkDetElem = dynamic_cast<const Trk::TrkDetElementBase*>(upstreamDetEl);
529 ATH_MSG_VERBOSE(
"trkDetElem type: " << static_cast<std::underlying_type_t<Trk::DetectorElemType>>(trkDetElem->detectorType()));
531 ATH_MSG_VERBOSE(
"Try casting to SiDetectorElement");
532 const auto* detElem = dynamic_cast<const InDetDD::SiDetectorElement*>(upstreamDetEl);
535 ATH_MSG_VERBOSE(
"detElem = " << detElem);
538 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern;
539 std::unique_ptr<Trk::TrackParameters> parm;
542 if (flag.test(Acts::TrackStateFlag::HoleFlag)){
543 ATH_MSG_VERBOSE(
"State is a hole (no associated measurement), use predicted parameters");
544 const Acts::BoundTrackParameters actsParam(state.referenceSurface().getSharedPtr(),
546 state.predictedCovariance(),
547 acts_track.particleHypothesis());
548 parm = m_ATLASConverterTool->actsTrackParametersToTrkParameters(actsParam, tgContext);
549 auto boundaryCheck = m_boundaryCheckTool->boundaryCheck(*parm);
551 ATH_MSG_VERBOSE(
"Check if this is a hole, a dead sensors or a state outside the sensor boundary");
552 if(boundaryCheck == Trk::BoundaryCheckResult::DeadElement){
553 if (detElem->isPixel()) {
556 else if (detElem->isSCT()) {
561 } else if (boundaryCheck != Trk::BoundaryCheckResult::Candidate){
565 typePattern.set(Trk::TrackStateOnSurface::Hole);
568 else if (
flag.test(Acts::TrackStateFlag::OutlierFlag) or not state.hasSmoothed()) {
569 ATH_MSG_VERBOSE(
"The state was tagged as an outlier or was missed in the reverse filtering, use filtered parameters");
570 const Acts::BoundTrackParameters actsParam(state.referenceSurface().getSharedPtr(),
572 state.filteredCovariance(),
573 acts_track.particleHypothesis());
574 parm = m_ATLASConverterTool->actsTrackParametersToTrkParameters(actsParam, tgContext);
575 typePattern.set(Trk::TrackStateOnSurface::Outlier);
579 ATH_MSG_VERBOSE(
"The state is a measurement state, use smoothed parameters");
581 const Acts::BoundTrackParameters actsParam(state.referenceSurface().getSharedPtr(),
583 state.smoothedCovariance(),
584 acts_track.particleHypothesis());
586 actsSmoothedParam.push_back(std::make_unique<const Acts::BoundTrackParameters>(Acts::BoundTrackParameters(actsParam)));
587 parm = m_ATLASConverterTool->actsTrackParametersToTrkParameters(actsParam, tgContext);
588 typePattern.set(Trk::TrackStateOnSurface::Measurement);
591 std::unique_ptr<Trk::MeasurementBase> measState;
592 if (state.hasUncalibratedSourceLink()){
593 auto sl = state.getUncalibratedSourceLink().template get<ATLASSourceLink>();
595 measState = sl->uniqueClone();
597 double nDoF = state.calibratedSize();
602 ATH_MSG_VERBOSE(
"State succesfully creates, adding it to the trajectory");
603 finalTrajectory->insert(finalTrajectory->begin(), perState);
608 const Acts::BoundTrackParameters actsPer(acts_track.referenceSurface().getSharedPtr(),
609 acts_track.parameters(),
610 acts_track.covariance(),
611 acts_track.particleHypothesis());
612 std::unique_ptr<Trk::TrackParameters> per = m_ATLASConverterTool->actsTrackParametersToTrkParameters(actsPer, tgContext);
613 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern;
616 if (perState) finalTrajectory->insert(finalTrajectory->begin(), perState);
621 newtrack = std::make_unique<Trk::Track>(newInfo, std::move(finalTrajectory),
nullptr);
622 if (newtrack && !m_refitOnly) {
624 if (!newtrack->trackSummary()) {
625 newtrack->setTrackSummary(std::make_unique<Trk::TrackSummary>());
632 m_trkSummaryTool->updateTrackSummary(ctx, *newtrack,
true);
638 const Acts::GsfExtensions<typename ActsTrk::MutableTrackStateBackend>&
639 GaussianSumFitterTool::getExtensions()
const
641 return m_gsfExtensions;
651 Acts::GsfOptions<typename ActsTrk::MutableTrackStateBackend>
652 GaussianSumFitterTool::prepareOptions(
const Acts::GeometryContext& tgContext,
653 const Acts::MagneticFieldContext& mfContext,
654 const Acts::CalibrationContext& calContext,
655 const Acts::PerigeeSurface& surface)
const
657 Acts::PropagatorPlainOptions propagationOption(tgContext, mfContext);
658 propagationOption.maxSteps = m_option_maxPropagationStep;
660 Acts::GsfOptions<typename ActsTrk::MutableTrackStateBackend> gsfOptions(tgContext, mfContext, calContext);
661 gsfOptions.extensions=m_gsfExtensions;
662 gsfOptions.propagatorPlainOptions=propagationOption;
663 gsfOptions.referenceSurface = &surface;
666 gsfOptions.abortOnError =
false;
667 gsfOptions.maxComponents = m_maxComponents;
668 gsfOptions.weightCutoff = m_weightCutOff;
669 gsfOptions.componentMergeMethod = m_componentMergeMethod;