361 const Acts::BoundSubspaceIndices& subspaceIndices,
362 boost::container::small_vector< typename TrackStateProxy::IndexType, s_maxBranchesPerSurface> &track_states,
363 const Acts::Logger&
logger,
364 bool outlier_states) {
366 const auto &boundParams = derived_t::boundParams(boundState);
367 const auto &pathLength = derived_t::pathLength(boundState);
369 using PM = Acts::TrackStatePropMask;
371 track_states.reserve( n_new_states );
372 std::optional<TrackStateProxy> firstTrackState{
374 for (
unsigned int state_i=0; state_i<n_new_states; ++state_i) {
375 PM mask = PM::Predicted | PM::Filtered | PM::Jacobian | PM::Calibrated;
377 if (firstTrackState.has_value()) {
380 mask &= ~PM::Predicted & ~PM::Jacobian;
383 if (outlier_states) {
385 mask &= ~PM::Filtered;
389 ACTS_VERBOSE(
"Create SourceLink output track state #"
390 << trackState.index() <<
" with mask: " << mask);
392 if (firstTrackState.has_value()) {
393 trackState.shareFrom(*firstTrackState, PM::Predicted);
394 trackState.shareFrom(*firstTrackState, PM::Jacobian);
398 trackState.predicted() = boundParams.parameters();
399 if (boundParams.covariance()) {
400 trackState.predictedCovariance() = *boundParams.covariance();
402 trackState.jacobian() = derived_t::boundJacobiMatrix(boundState);
403 firstTrackState = trackState;
405 trackState.pathLength() = pathLength;
407 trackState.setReferenceSurface(boundParams.referenceSurface().getSharedPtr());
409 trackState.setProjectorSubspaceIndices(subspaceIndices);
411 Acts::TrackStateType typeFlags = trackState.typeFlags();
412 if (trackState.referenceSurface().surfaceMaterial() !=
nullptr) {
413 typeFlags.set(Acts::TrackStateFlag::MaterialFlag);
415 typeFlags.set(Acts::TrackStateFlag::ParameterFlag);
419 track_states.push_back( trackState.index());
443 const Acts::CalibrationContext& calibrationContext,
444 const Acts::Surface& surface,
446 T_MeasurementRange &&measurement_range,
449 const Acts::Logger&
logger,
450 const std::size_t numMeasurementsCut,
451 const std::pair<float,float>& maxChi2Cut,
453 Acts::Result<boost::container::small_vector< typename TrackStateProxy::IndexType, s_maxBranchesPerSurface> >
454 result = boost::container::small_vector< typename TrackStateProxy::IndexType, s_maxBranchesPerSurface>{};
456 using iterator_t =
decltype(measurement_range.begin());
458 using BaseElementType = std::remove_cv_t<std::remove_pointer_t< container_value_t > >;
460 using TheMatchingMeasurement = MatchingMeasurement<DIM, container_value_t >;
461 using MeasCovPair = TheMatchingMeasurement::MeasCovPair;
469 Acts::SubspaceIndices<DIM> parameter_map =
derived().template parameterMap<DIM>(geometryContext,
474 derived().boundParams(boundState).parameters()),
476 derived().boundParams(boundState).covariance().value()));
479 auto preCalibrator =
derived().template preCalibrator<DIM, BaseElementType>();
480 auto postCalibrator =
derived().template postCalibrator<DIM, BaseElementType>();
482 for (
const auto &measurement : measurement_range ) {
483 TheMatchingMeasurement &matching_measurement=selected_measurements.
slot();
484 if (forced && postCalibrator) {
486 const auto &m =
derived().forwardToCalibrator(measurement);
487 matching_measurement.m_measurement = std::make_pair( m.template localPosition<DIM>(), m.template localCovariance<DIM>() );
488 matching_measurement.m_chi2 = 0.0f;
489 matching_measurement.m_sourceLink=measurement;
492 matching_measurement.m_measurement = preCalibrator(geometryContext,
494 derived().forwardToCalibrator(measurement),
495 derived().boundParams(boundState));
496 matching_measurement.m_chi2 =
computeChi2(matching_measurement.m_measurement.first,
497 matching_measurement.m_measurement.second,
501 if (matching_measurement.m_chi2<maxChi2Cut.second) {
502 matching_measurement.m_sourceLink=measurement;
503 selected_measurements.
acceptAndSort([](
const TheMatchingMeasurement &
a,
504 const TheMatchingMeasurement &b) {
505 return a.m_chi2 < b.m_chi2;
512 using post_calib_meas_cov_pair_t
513 = std::pair<typename MeasurementSelectorTraits<derived_t>::template CalibratedMeasurement<DIM>,
518 static constexpr bool pre_and_post_calib_types_agree
519 = std::is_same< typename MeasurementSelectorTraits<derived_t>::template CalibratedMeasurement<DIM>,
521 && std::is_same< typename MeasurementSelectorTraits<derived_t>::template CalibratedMeasurementCovariance<DIM>,
524 using Empty =
struct {};
525 typename std::conditional< !pre_and_post_calib_types_agree,
526 std::array< post_calib_meas_cov_pair_t, NMeasMax>,
528 if (postCalibrator) {
529 typename std::conditional<!pre_and_post_calib_types_agree, unsigned int, Empty>::type calibrated_meas_cov_i{};
533 idx: selected_measurements) {
534 TheMatchingMeasurement &a_selected_measurement = selected_measurements.
getSlot(idx);
538 post_calib_meas_cov_pair_t &calibrated_measurement
539 = [&calibrated, &a_selected_measurement, calibrated_meas_cov_i]() -> post_calib_meas_cov_pair_t & {
540 if constexpr(pre_and_post_calib_types_agree) {
542 (void) calibrated_meas_cov_i;
543 return a_selected_measurement.m_measurement;
546 (void) a_selected_measurement;
547 assert(calibrated_meas_cov_i < calibrated.size());
548 return calibrated[calibrated_meas_cov_i];
553 calibrated_measurement = postCalibrator(geometryContext,
555 derived().forwardToCalibrator(a_selected_measurement.m_sourceLink.value()),
556 derived().boundParams(boundState));
558 a_selected_measurement.m_chi2 =
computeChi2(calibrated_measurement.first,
559 calibrated_measurement.second,
563 a_selected_measurement.m_isOutLier = (!forced && a_selected_measurement.m_chi2 >= maxChi2Cut.first);
564 if constexpr(!pre_and_post_calib_types_agree) {
565 ++calibrated_meas_cov_i;
572 idx: selected_measurements) {
573 TheMatchingMeasurement &a_selected_measurement = selected_measurements.
getSlot(idx);
574 a_selected_measurement.m_isOutLier = (!forced && a_selected_measurement.m_chi2 >= maxChi2Cut.first);
584 Acts::BoundSubspaceIndices boundSubspaceIndices;
585 std::copy(parameter_map.begin(), parameter_map.end(), boundSubspaceIndices.begin());
590 boundSubspaceIndices,
593 (!selected_measurements.
empty()
594 ? selected_measurements.
getSlot( *(selected_measurements.
begin())).m_isOutLier
596 assert(
result->size() == selected_measurements.
size() );
599 auto use_calibrated_storage = [&postCalibrator]() ->
bool {
600 if constexpr(pre_and_post_calib_types_agree) {
601 (void) postCalibrator;
607 return postCalibrator;
611 if (selected_measurements.
empty()) {
612 auto config_for_surface =
m_config.find(surface.geometryId());
613 if (config_for_surface !=
m_config.end()) {
614 if (config_for_surface->edgeTolerance.has_value()) {
617 auto local_coords =
derived().boundParams(boundState).parameters().template block<2,1>(0,0);
618 if (!surface.insideBounds(local_coords,config_for_surface->edgeTolerance.value())) {
619 result =
result.failure(Acts::CombinatorialKalmanFilterError::NoMeasurementExpected);
626 unsigned int state_i=0;
628 idx: selected_measurements) {
629 assert( state_i < result->size());
631 TheMatchingMeasurement &a_selected_measurement = selected_measurements.
getSlot(idx);
632 trackState.setUncalibratedSourceLink(
derived().makeSourceLink(std::move(a_selected_measurement.m_sourceLink.value())));
634 trackState.typeFlags().set( a_selected_measurement.m_isOutLier
635 ? Acts::TrackStateFlag::OutlierFlag
636 : Acts::TrackStateFlag::MeasurementFlag );
637 trackState.allocateCalibrated(DIM);
638 if (use_calibrated_storage()) {
641 assert( use_calibrated_storage() == !pre_and_post_calib_types_agree);
642 if constexpr(!pre_and_post_calib_types_agree) {
643 assert( state_i < calibrated.size());
644 trackState.template calibrated<DIM>()
646 trackState.template calibratedCovariance<DIM>()
648 trackState.chi2() = a_selected_measurement.m_chi2;
652 trackState.template calibrated<DIM>()
654 trackState.template calibratedCovariance<DIM>()
656 trackState.chi2() = a_selected_measurement.m_chi2;