47 namespace Experimental {
50 template <
typename traj_t>
83 calibrator.template connect<&detail::voidFitterCalibrator<traj_t>>();
84 updater.template connect<&detail::voidFitterUpdater<traj_t>>();
85 outlierFinder.template connect<&detail::voidOutlierFinder<traj_t>>();
92 template <
typename traj_t>
108 std::reference_wrapper<const CalibrationContext> cctx,
111 const Surface* rSurface =
nullptr,
bool mScattering =
false,
115 const size_t nUpdateMax_ = 5)
159 template <
typename traj_t>
230 template <
size_t measDim,
typename traj_t>
231 void collector(
typename traj_t::TrackStateProxy& trackStateProxy,
233 auto predicted = trackStateProxy.predicted();
234 auto measurement = trackStateProxy.template calibrated<measDim>();
235 auto covarianceMeasurement =
236 trackStateProxy.template calibratedCovariance<measDim>();
238 auto projJacobian = (trackStateProxy.projector()
239 .template topLeftCorner<measDim, eBoundSize>() *
242 auto projPredicted = (trackStateProxy.projector()
243 .template topLeftCorner<measDim, eBoundSize>() *
247 ACTS_VERBOSE(
"Processing and collecting measurements in Actor:\n"
248 <<
"\tMeasurement:\t" << measurement.transpose()
249 <<
"\n\tPredicted:\t" << predicted.transpose()
250 <<
"\n\tProjector:\t" << trackStateProxy.effectiveProjector()
251 <<
"\n\tProjected Jacobian:\t" << projJacobian
252 <<
"\n\tCovariance Measurements:\t" << covarianceMeasurement);
255 for (
size_t i = 0;
i < measDim;
i++) {
256 if (covarianceMeasurement(
i,
i) < 1
e-10) {
257 ACTS_WARNING(
"Invalid covariance of measurement: cov(" <<
i <<
"," <<
i
267 <<
"\t\tResidual:\t" << measurement[i] - projPredicted[i]
268 <<
"\n\t\tCovariance:\t" << covarianceMeasurement(i, i)
269 <<
"\n\t\tProjected Jacobian:\t" << projJacobian.row(i));
278 template <
typename propagator_t,
typename traj_t>
289 std::unique_ptr<const Logger> _logger =
291 : m_propagator(std::
move(pPropagator)),
313 template <
typename parameters_t>
369 template <
typename propagator_state_t,
typename stepper_t,
370 typename navigator_t>
386 navigator.insertExternalSurface(state.navigation,
387 measurementIt->first);
394 auto surface = navigator.currentSurface(state.navigation);
409 stepper.transportCovarianceToBound(state.stepping, *
surface,
413 "Actor - indices before processing:"
418 <<
"result.fittedStates->size(): " << result.
fittedStates->size())
425 ~(TrackStatePropMask::Smoothed | TrackStatePropMask::Filtered);
443 currentTrackIndex = 0;
444 ACTS_VERBOSE(
" processSurface: currentTrackIndex (kInv->0) = "
445 << currentTrackIndex);
448 ACTS_VERBOSE(
" processSurface: currentTrackIndex (n+1) = "
449 << currentTrackIndex);
455 ACTS_VERBOSE(
" processSurface: currentTrackIndex (ADD NEW)= "
456 << currentTrackIndex);
461 typename traj_t::TrackStateProxy trackStateProxy =
462 fittedStates.getTrackState(currentTrackIndex);
467 trackStateProxy.setReferenceSurface(
surface->getSharedPtr());
469 auto res = stepper.boundState(state.stepping, *
surface,
false,
472 result.
result = res.error();
475 auto& [boundParams, jacobian,
pathLength] = *res;
478 trackStateProxy.predicted() =
std::move(boundParams.parameters());
479 if (boundParams.covariance().has_value()) {
480 trackStateProxy.predictedCovariance() =
484 trackStateProxy.jacobian() =
std::move(jacobian);
491 sourcelink_it->second, trackStateProxy);
494 auto typeFlags = trackStateProxy.typeFlags();
496 if (
surface->surfaceMaterial() !=
nullptr) {
507 if (trackStateProxy.calibratedSize() == 1) {
508 collector<1>(trackStateProxy, result, *
actorLogger);
509 }
else if (trackStateProxy.calibratedSize() == 2) {
510 collector<2>(trackStateProxy, result, *
actorLogger);
513 "Only measurements of 1 and 2 dimensions are implemented yet.");
520 ACTS_VERBOSE(
"Actor - indices after processing, before over writing:"
522 <<
"result.lastMeasurementIndex: "
524 <<
"trackStateProxy.index(): " << trackStateProxy.index()
528 <<
"currentTrackIndex: " << currentTrackIndex)
532 ACTS_INFO(
"Actor: This case is not implemented yet")
537 ACTS_INFO(
"Actor: finish due to limit. Result might be garbage.");
544 template <
typename parameters_t>
550 template <
typename propagator_state_t,
typename stepper_t,
551 typename navigator_t,
typename result_t>
553 const navigator_t& ,
const result_t& result,
555 if (!result.result.ok() or result.finished) {
581 template <
typename source_link_iterator_t,
typename start_parameters_t,
583 typename track_container_t,
template <
typename>
class holder_t,
585 auto fit(source_link_iterator_t
it, source_link_iterator_t
end,
586 const start_parameters_t& sParameters,
589 const -> std::enable_if_t<
596 <<
" input measurements");
597 std::map<GeometryIdentifier, SourceLink> inputMeasurements;
601 auto geoId = gx2fOptions.extensions.surfaceAccessor(sl)->geometryId();
602 inputMeasurements.emplace(geoId,
std::move(sl));
604 ACTS_VERBOSE(
"inputMeasurements.size() = " << inputMeasurements.size());
611 using GX2FResult =
typename GX2FActor::result_type;
612 using Actors = Acts::ActionList<GX2FActor>;
613 using Aborters = Acts::AbortList<GX2FAborter>;
617 const size_t reducedMatrixSize = 4;
618 start_parameters_t params = sParameters;
636 for (
size_t nUpdate = 0; nUpdate < gx2fOptions.nUpdateMax; nUpdate++) {
638 << gx2fOptions.nUpdateMax);
641 params.parameters() += deltaParams;
649 auto& gx2fActor = propagatorOptions.
actionList.template get<GX2FActor>();
650 gx2fActor.inputMeasurements = &inputMeasurements;
651 gx2fActor.extensions = gx2fOptions.extensions;
652 gx2fActor.calibrationContext = &gx2fOptions.calibrationContext.get();
654 gx2fActor.nUpdate = nUpdate;
656 typename propagator_t::template action_list_t_result_t<
660 auto&
r = inputResult.template get<Gx2FitterResult<traj_t>>();
662 r.fittedStates = &trackContainer.trackStateContainer();
664 auto result = m_propagator.template propagate(
665 params, propagatorOptions,
true,
std::move(inputResult));
669 auto& propRes = *result;
670 GX2FResult gx2fResult =
std::move(propRes.template get<GX2FResult>());
673 << gx2fResult.collectorResiduals.size());
674 ACTS_VERBOSE(
"gx2fResult.collectorCovariances.size() = "
675 << gx2fResult.collectorCovariances.size());
676 ACTS_VERBOSE(
"gx2fResult.collectorProjectedJacobians.size() = "
677 << gx2fResult.collectorProjectedJacobians.size());
680 aMatrix = BoundMatrix::Zero();
681 bVector = BoundVector::Zero();
684 for (
size_t iMeas = 0; iMeas < gx2fResult.collectorResiduals.size();
686 const auto ri = gx2fResult.collectorResiduals[iMeas];
687 const auto covi = gx2fResult.collectorCovariances[iMeas];
688 const auto projectedJacobian =
689 gx2fResult.collectorProjectedJacobians[iMeas];
691 const double chi2meas = ri / covi * ri;
693 projectedJacobian * projectedJacobian.transpose() / covi;
694 const BoundVector bVectorMeas = projectedJacobian / covi * ri;
697 aMatrix += aMatrixMeas;
698 bVector += bVectorMeas;
702 deltaParams = BoundVector::Zero();
704 aMatrix.topLeftCorner<reducedMatrixSize, reducedMatrixSize>()
705 .colPivHouseholderQr()
706 .solve(bVector.topLeftCorner<reducedMatrixSize, 1>());
708 for (
size_t idp = 0; idp < reducedMatrixSize; idp++) {
709 deltaParams(idp, 0) = deltaParamsReduced(idp, 0);
717 tipIndex = gx2fResult.lastMeasurementIndex;
730 BoundMatrix fullCovariancePredicted = BoundMatrix::Identity();
731 if (aMatrix.topLeftCorner<reducedMatrixSize, reducedMatrixSize>()
732 .determinant() != 0) {
733 fullCovariancePredicted
734 .template topLeftCorner<reducedMatrixSize, reducedMatrixSize>() =
735 aMatrix.topLeftCorner<reducedMatrixSize, reducedMatrixSize>()
737 }
else if (gx2fOptions.nUpdateMax > 0) {
738 ACTS_ERROR(
"det(a) == 0. This should not happen ever.");
739 return Experimental::GlobalChiSquareFitterError::DetAIsZero;
743 auto track = trackContainer.getTrack(trackContainer.addTrack());
744 track.tipIndex() = tipIndex;
745 track.parameters() = params.parameters();
746 track.covariance() = fullCovariancePredicted;
747 track.setReferenceSurface(params.referenceSurface().getSharedPtr());