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"
42 #include <type_traits>
43 #include <system_error>
49 const IInterface*
p) :
67 auto field = std::make_shared<ATLASMagneticFieldWrapper>();
68 Acts::MultiEigenStepperLoop<> stepper(
field);
70 logger().cloneWithSuffix(
"Navigator") );
71 Acts::Propagator<Acts::MultiEigenStepperLoop<>,
Acts::Navigator> propagator(std::move(stepper),
73 logger().cloneWithSuffix(
"Prop"));
75 Acts::AtlasBetheHeitlerApprox<6, 5> bha = Acts::makeDefaultBetheHeitlerApprox();
76 m_fitter = std::make_unique<Fitter>(std::move(propagator), std::move(bha),
77 logger().cloneWithSuffix(
"GaussianSumFitter"));
81 Acts::DirectNavigator directNavigator(
logger().cloneWithSuffix(
"DirectNavigator") );
82 Acts::MultiEigenStepperLoop<> stepperDirect(
field);
83 Acts::Propagator<Acts::MultiEigenStepperLoop<>, Acts::DirectNavigator> directPropagator(std::move(stepperDirect),
84 std::move(directNavigator),
85 logger().cloneWithSuffix(
"DirectPropagator"));
86 Acts::AtlasBetheHeitlerApprox<6, 5> bhaDirect = Acts::makeDefaultBetheHeitlerApprox();
87 m_directFitter = std::make_unique<DirectFitter>(std::move(directPropagator),std::move(bhaDirect),
88 logger().cloneWithSuffix(
"DirectGaussianSumFitter"));
92 m_gsfExtensions.updater.connect<&ActsTrk::detail::FitterHelperFunctions::gainMatrixUpdate<ActsTrk::MutableTrackStateBackend>>();
94 m_gsfExtensions.calibrator.connect<&ActsTrk::detail::TrkMeasurementCalibrator::calibrate<ActsTrk::MutableTrackStateBackend>>(
m_calibrator.get());
98 m_gsfExtensions.mixtureReducer.connect<&Acts::reduceMixtureWithKLDistance>();
116 return StatusCode::SUCCESS;
121 std::unique_ptr<Trk::Track>
129 std::unique_ptr<Trk::Track>
track =
nullptr;
130 ATH_MSG_VERBOSE (
"--> enter GaussianSumFitter::fit(Track,,) with Track from author = "
135 ATH_MSG_DEBUG(
"called to refit empty track or track with too little information, reject fit");
141 ATH_MSG_DEBUG(
"input fails to provide track parameters for seeding the GSF, reject fit");
146 std::shared_ptr<Acts::PerigeeSurface> pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(
147 Acts::Vector3{0., 0., 0.});
152 Acts::CalibrationContext calContext{};
155 Acts::GsfOptions<ActsTrk::MutableTrackStateBackend>
165 std::vector<Acts::SourceLink> trackSourceLinks =
m_ATLASConverterTool->trkTrackToSourceLinks(tgContext,inputTrack);
177 std::unique_ptr<Trk::Track>
184 std::unique_ptr<Trk::Track>
track =
nullptr;
186 if (inputMeasSet.size() < 2) {
187 ATH_MSG_DEBUG(
"called to refit empty measurement set or a measurement set with too little information, reject fit");
192 std::shared_ptr<Acts::PerigeeSurface> pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(
193 Acts::Vector3{0., 0., 0.});
198 Acts::CalibrationContext calContext{};
201 Acts::GsfOptions<ActsTrk::MutableTrackStateBackend>
208 gsfOptions.abortOnError =
false;
210 std::vector< Acts::SourceLink > trackSourceLinks;
211 trackSourceLinks.reserve(inputMeasSet.size());
213 for (
auto* measSet : inputMeasSet) {
214 trackSourceLinks.push_back(
m_ATLASConverterTool->trkMeasurementToSourceLink(tgContext, *measSet));
217 const auto& initialParams =
m_ATLASConverterTool->trkTrackParametersToActsParameters(estimatedStartParameters, tgContext);
221 std::vector<const Acts::Surface*> surfaces;
222 surfaces.reserve(inputMeasSet.size());
223 for (
auto* measSet : inputMeasSet) {
228 surfaces.push_back(&actsSrf);
248 std::unique_ptr<Trk::Track>
263 std::unique_ptr<Trk::Track>
270 ATH_MSG_VERBOSE (
"--> enter GaussianSumFitter::fit(Track,Meas'BaseSet,,)");
274 if (addMeasColl.empty()) {
275 ATH_MSG_DEBUG(
"client tries to add an empty MeasurementSet to the track fit." );
276 return fit(ctx,inputTrack);
281 ATH_MSG_DEBUG(
"called to refit empty track or track with too little information, reject fit");
287 ATH_MSG_DEBUG(
"input fails to provide track parameters for seeding the GSF, reject fit");
291 std::unique_ptr<Trk::Track>
track =
nullptr;
294 std::shared_ptr<Acts::PerigeeSurface> pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(Acts::Vector3{0., 0., 0.});
299 Acts::CalibrationContext calContext{};
302 Acts::GsfOptions<ActsTrk::MutableTrackStateBackend>
308 std::vector<Acts::SourceLink> trackSourceLinks =
m_ATLASConverterTool->trkTrackToSourceLinks(tgContext, inputTrack);
311 for (
auto* meas : addMeasColl) {
324 std::unique_ptr<Trk::Track>
332 ATH_MSG_DEBUG(
"Fit of Track with additional PrepRawDataSet not yet implemented");
338 std::unique_ptr<Trk::Track>
351 ATH_MSG_DEBUG(
"input #2 is empty try to fit track 1 alone" );
352 return fit(ctx,intrk1);
357 ATH_MSG_DEBUG(
"input #1 is empty try to fit track 2 alone" );
358 return fit(ctx,intrk2);
363 ATH_MSG_DEBUG(
"input #1 fails to provide track parameters for seeding the GSF, reject fit");
367 std::unique_ptr<Trk::Track>
track =
nullptr;
370 std::shared_ptr<Acts::PerigeeSurface> pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(
371 Acts::Vector3{0., 0., 0.});
376 Acts::CalibrationContext calContext{};
379 Acts::GsfOptions<ActsTrk::MutableTrackStateBackend>
385 std::vector<Acts::SourceLink> trackSourceLinks =
m_ATLASConverterTool->trkTrackToSourceLinks(tgContext, intrk1);
386 std::vector<Acts::SourceLink> trackSourceLinks2 =
m_ATLASConverterTool->trkTrackToSourceLinks(tgContext, intrk2);
387 trackSourceLinks.insert(trackSourceLinks.end(), trackSourceLinks2.begin(), trackSourceLinks2.end());
397 std::unique_ptr<Trk::Track>
399 const Acts::GeometryContext& tgContext,
401 Acts::Result<typename ActsTrk::MutableTrackContainer::TrackProxy, std::error_code>& fitResult)
const
403 if (not fitResult.ok())
406 std::unique_ptr<Trk::Track> newtrack =
nullptr;
408 const auto& acts_track = fitResult.value();
409 auto finalTrajectory = std::make_unique<Trk::TrackStates>();
411 int numberOfDeadPixel = 0;
412 int numberOfDeadSCT = 0;
414 std::vector<std::unique_ptr<const Acts::BoundTrackParameters>> actsSmoothedParam;
416 tracks.trackStateContainer().visitBackwards(acts_track.tipIndex(),
417 [&] (
const auto &state) ->
void
420 auto flag = state.typeFlags();
421 const auto* associatedDetEl = state.referenceSurface().associatedDetectorElement();
422 if (not associatedDetEl)
425 const auto* actsElement = dynamic_cast<const ActsDetectorElement*>(associatedDetEl);
429 const auto* upstreamDetEl = actsElement->upstreamDetectorElement();
430 if (not upstreamDetEl)
433 ATH_MSG_VERBOSE(
"Try casting to TRT for if");
434 if (dynamic_cast<const InDetDD::TRT_BaseElement*>(upstreamDetEl))
437 const auto* trkDetElem = dynamic_cast<const Trk::TrkDetElementBase*>(upstreamDetEl);
441 ATH_MSG_VERBOSE(
"trkDetElem type: " << static_cast<std::underlying_type_t<Trk::DetectorElemType>>(trkDetElem->detectorType()));
443 ATH_MSG_VERBOSE(
"Try casting to SiDetectorElement");
444 const auto* detElem = dynamic_cast<const InDetDD::SiDetectorElement*>(upstreamDetEl);
447 ATH_MSG_VERBOSE(
"detElem = " << detElem);
450 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern;
451 std::unique_ptr<Trk::TrackParameters> parm;
454 if (flag.test(Acts::TrackStateFlag::HoleFlag)){
455 ATH_MSG_VERBOSE(
"State is a hole (no associated measurement), use predicted parameters");
456 const Acts::BoundTrackParameters actsParam(state.referenceSurface().getSharedPtr(),
458 state.predictedCovariance(),
459 acts_track.particleHypothesis());
460 parm = m_ATLASConverterTool->actsTrackParametersToTrkParameters(actsParam, tgContext);
461 auto boundaryCheck = m_boundaryCheckTool->boundaryCheck(*parm);
463 ATH_MSG_VERBOSE(
"Check if this is a hole, a dead sensors or a state outside the sensor boundary");
464 if(boundaryCheck == Trk::BoundaryCheckResult::DeadElement){
465 if (detElem->isPixel()) {
468 else if (detElem->isSCT()) {
473 } else if (boundaryCheck != Trk::BoundaryCheckResult::Candidate){
477 typePattern.set(Trk::TrackStateOnSurface::Hole);
480 else if (
flag.test(Acts::TrackStateFlag::OutlierFlag) or not state.hasSmoothed()) {
481 ATH_MSG_VERBOSE(
"The state was tagged as an outlier or was missed in the reverse filtering, use filtered parameters");
482 const Acts::BoundTrackParameters actsParam(state.referenceSurface().getSharedPtr(),
484 state.filteredCovariance(),
485 acts_track.particleHypothesis());
486 parm = m_ATLASConverterTool->actsTrackParametersToTrkParameters(actsParam, tgContext);
487 typePattern.set(Trk::TrackStateOnSurface::Outlier);
491 ATH_MSG_VERBOSE(
"The state is a measurement state, use smoothed parameters");
493 const Acts::BoundTrackParameters actsParam(state.referenceSurface().getSharedPtr(),
495 state.smoothedCovariance(),
496 acts_track.particleHypothesis());
498 actsSmoothedParam.push_back(std::make_unique<const Acts::BoundTrackParameters>(Acts::BoundTrackParameters(actsParam)));
499 parm = m_ATLASConverterTool->actsTrackParametersToTrkParameters(actsParam, tgContext);
500 typePattern.set(Trk::TrackStateOnSurface::Measurement);
503 std::unique_ptr<Trk::MeasurementBase> measState;
504 if (state.hasUncalibratedSourceLink()){
505 auto sl = state.getUncalibratedSourceLink().template get<ATLASSourceLink>();
507 measState = sl->uniqueClone();
509 double nDoF = state.calibratedSize();
514 ATH_MSG_VERBOSE(
"State succesfully creates, adding it to the trajectory");
515 finalTrajectory->insert(finalTrajectory->begin(), perState);
520 const Acts::BoundTrackParameters actsPer(acts_track.referenceSurface().getSharedPtr(),
521 acts_track.parameters(),
522 acts_track.covariance(),
523 acts_track.particleHypothesis());
524 std::unique_ptr<Trk::TrackParameters> per = m_ATLASConverterTool->actsTrackParametersToTrkParameters(actsPer, tgContext);
525 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern;
528 if (perState) finalTrajectory->insert(finalTrajectory->begin(), perState);
533 newtrack = std::make_unique<Trk::Track>(newInfo, std::move(finalTrajectory),
nullptr);
534 if (newtrack && !m_refitOnly) {
536 if (!newtrack->trackSummary()) {
537 newtrack->setTrackSummary(std::make_unique<Trk::TrackSummary>());
544 m_trkSummaryTool->updateTrackSummary(ctx, *newtrack,
true);
550 const Acts::GsfExtensions<typename ActsTrk::MutableTrackStateBackend>&
551 GaussianSumFitterTool::getExtensions()
const
553 return m_gsfExtensions;
563 Acts::GsfOptions<typename ActsTrk::MutableTrackStateBackend>
564 GaussianSumFitterTool::prepareOptions(
const Acts::GeometryContext& tgContext,
565 const Acts::MagneticFieldContext& mfContext,
566 const Acts::CalibrationContext& calContext,
567 const Acts::PerigeeSurface& surface)
const
569 Acts::PropagatorPlainOptions propagationOption(tgContext, mfContext);
570 propagationOption.maxSteps = m_option_maxPropagationStep;
572 Acts::GsfOptions<typename ActsTrk::MutableTrackStateBackend> gsfOptions(tgContext, mfContext, calContext);
573 gsfOptions.extensions=m_gsfExtensions;
574 gsfOptions.propagatorPlainOptions=propagationOption;
575 gsfOptions.referenceSurface = &surface;
578 gsfOptions.abortOnError =
false;
579 gsfOptions.maxComponents = m_maxComponents;
580 gsfOptions.weightCutoff = m_weightCutOff;
581 gsfOptions.componentMergeMethod = m_componentMergeMethod;