14 #include "Acts/Surfaces/PerigeeSurface.hpp"
17 struct TrackFindingBaseAlg::CKF_pimpl :
public detail::CKF_config {};
83 auto magneticField = std::make_unique<ATLASMagneticFieldWrapper>();
87 detail::Navigator::Config
config{trackingGeometry};
88 config.resolvePassive =
false;
89 config.resolveMaterial =
true;
90 config.resolveSensitive =
true;
98 std::vector<double> absEtaEdges;
101 absEtaEdges.reserve(2
ul);
102 absEtaEdges.push_back(0.0);
103 absEtaEdges.push_back(std::numeric_limits<double>::infinity());
113 auto setCut = [](
auto &cfgVal,
const auto &
cuts,
size_t ind) ->
void
120 Acts::TrackSelector::EtaBinnedConfig trackSelectorCfg{std::move(absEtaEdges)};
123 assert(trackSelectorCfg.cutSets.size() == 1);
124 trackSelectorCfg.cutSets[0].absEtaMin =
m_absEtaMin;
125 trackSelectorCfg.cutSets[0].absEtaMax =
m_absEtaMax;
128 for (
auto &
cfg : trackSelectorCfg.cutSets)
154 std::move(extrapolator),
157 Acts::TrackSelector{trackSelectorCfg}};
159 m_trackFinder = std::make_unique<CKF_pimpl>(std::move(ckfConfig));
161 trackFinder().
ckfExtensions.updater.connect<&ActsTrk::detail::FitterHelperFunctions::gainMatrixUpdate<detail::RecoTrackStateContainer>>();
167 return StatusCode::SUCCESS;
171 ATH_MSG_FATAL(
"execute() method from the base class was called! Implement proper execute() method in the derived class!");
173 return StatusCode::FAILURE;
179 return StatusCode::SUCCESS;
194 measurementSelector->
connect(&
options.extensions.createTrackStates);
196 return measurementSelector;
202 const Acts::PerigeeSurface* pSurface)
const {
203 Acts::PropagatorPlainOptions plainOptions{detContext.
geometry, detContext.
magField};
205 plainOptions.direction = Acts::Direction::Forward();
210 trackFinder().ckfExtensions, plainOptions, pSurface);
214 Acts::PropagatorPlainOptions plainSecondOptions{detContext.
geometry, detContext.
magField};
216 plainSecondOptions.direction = plainOptions.direction.invert();
219 options.extensions, plainSecondOptions, pSurface);
220 secondOptions.targetSurface = pSurface;
221 secondOptions.skipPrePropagationUpdate =
true;
223 return {std::move(
options), std::move(secondOptions), std::move(measurementSelector)};
229 return (!(std::abs(
eta) < trackSelectorCfg.absEtaEdges.back())) ? trackSelectorCfg.cutSets.back()
230 : (std::abs(
eta) < trackSelectorCfg.absEtaEdges.front()) ? trackSelectorCfg.cutSets.front()
231 : trackSelectorCfg.getCuts(
eta);
234 std::vector<typename detail::RecoTrackContainer::TrackProxy>
243 if (!secondInitialParameters.referenceSurface().insideBounds(secondInitialParameters.localPosition())) {
247 auto rootBranch = tracksContainerTemp.makeTrack();
248 rootBranch.copyFromWithoutStates(trackProxy);
256 if (not secondResult.ok()) {
259 return secondResult.value();
263 if (trackState.hasReferenceSurface()) {
264 if (
const auto *actsDetElem =
dynamic_cast<const IDetectorElementBase *
>(trackState.referenceSurface().associatedDetectorElement())) {
265 switch (actsDetElem->detectorType()) {
282 const detail::RecoTrackContainer::TrackProxy &
track,
283 const detail::RecoTrackContainer::TrackStateProxy &trackState,
284 const Acts::TrackSelector::EtaBinnedConfig &trackSelectorCfg,
285 const Acts::GeometryContext &tgContext,
287 const std::size_t typeIndex,
288 EventStats::value_type &event_stat_category_i)
const {
297 measurementIndex,
true);
301 return BranchStopperResult::Continue;
304 const auto &
parameters = trackState.hasFiltered() ? trackState.filtered()
305 : trackState.predicted();
316 <<
pT <<
" after " <<
track.nMeasurements()
318 return BranchStopperResult::StopAndDrop;
324 !(std::abs(
eta) < trackSelectorCfg.absEtaEdges.back() +
328 <<
eta <<
" after " <<
track.nMeasurements()
330 return BranchStopperResult::StopAndDrop;
336 bool enoughMeasurements = (
track.nMeasurements() >= minMeasurementsBranchStop);
337 bool tooManyHoles = (
track.nHoles() > cutSet.maxHoles);
338 bool tooManyOutliers = (
track.nOutliers() > cutSet.maxOutliers);
341 auto [enoughMeasurementsPS, tooManyHolesPS, tooManyOutliersPS] =
343 enoughMeasurements = enoughMeasurements && enoughMeasurementsPS;
344 tooManyHoles = tooManyHoles || tooManyHolesPS;
345 tooManyOutliers = tooManyOutliers || tooManyOutliersPS;
348 if (!(tooManyHoles || tooManyOutliers)) {
349 return BranchStopperResult::Continue;
352 if (!enoughMeasurements) {
358 << (enoughMeasurements ?
"keep" :
"drop")
359 <<
" branch with nHoles=" <<
track.nHoles() <<
" ("
363 <<
" hgtd), nOutliers=" <<
track.nOutliers() <<
" ("
367 <<
"), nMeasurements=" <<
track.nMeasurements() <<
" ("
373 << (enoughMeasurements ?
"keep" :
"drop")
374 <<
" branch with nHoles=" <<
track.nHoles()
375 <<
", nOutliers=" <<
track.nOutliers()
376 <<
", nMeasurements=" <<
track.nMeasurements());
379 return enoughMeasurements ? BranchStopperResult::StopAndKeep
380 : BranchStopperResult::StopAndDrop;
386 tracksContainer.addColumn<
unsigned int>(
"nPixelHits");
387 tracksContainer.addColumn<
unsigned int>(
"nStripHits");
388 tracksContainer.addColumn<
unsigned int>(
"nHgtdHits");
389 tracksContainer.addColumn<
unsigned int>(
"nPixelHoles");
390 tracksContainer.addColumn<
unsigned int>(
"nStripHoles");
391 tracksContainer.addColumn<
unsigned int>(
"nHgtdHoles");
392 tracksContainer.addColumn<
unsigned int>(
"nPixelOutliers");
393 tracksContainer.addColumn<
unsigned int>(
"nStripOutliers");
394 tracksContainer.addColumn<
unsigned int>(
"nHgtdOutliers");
411 const detail::RecoTrackContainer::TrackProxy &
track,
414 if (typeFlags.test(Acts::TrackStateFlag::HoleFlag)) {
416 }
else if (typeFlags.test(Acts::TrackStateFlag::OutlierFlag)) {
418 }
else if (typeFlags.test(Acts::TrackStateFlag::MeasurementFlag)) {
422 if (typeFlags.test(Acts::TrackStateFlag::HoleFlag)) {
424 }
else if (typeFlags.test(Acts::TrackStateFlag::OutlierFlag)) {
426 }
else if (typeFlags.test(Acts::TrackStateFlag::MeasurementFlag)) {
430 if (typeFlags.test(Acts::TrackStateFlag::HoleFlag)) {
432 }
else if (typeFlags.test(Acts::TrackStateFlag::OutlierFlag)) {
434 }
else if (typeFlags.test(Acts::TrackStateFlag::MeasurementFlag)) {
441 const detail::RecoTrackContainer::TrackProxy &
track,
442 const detail::RecoTrackContainer::TrackProxy &
other) {
478 bool enoughMeasurements =
true, tooManyHoles =
false, tooManyOutliers =
false;
480 std::size_t
etaBin = (std::abs(
eta) < trackSelectorCfg.absEtaEdges.front()) ? 0
481 : (std::abs(
eta) >= trackSelectorCfg.absEtaEdges.back()) ? trackSelectorCfg.absEtaEdges.size() - 1
482 : trackSelectorCfg.binIndex(
eta);
483 auto cutMin = [
etaBin](std::size_t
val,
const std::vector<std::size_t> &cutSet) {
484 return !cutSet.empty() && (
val < (
etaBin < cutSet.size() ? cutSet[
etaBin] : cutSet.back()));
486 auto cutMax = [
etaBin](std::size_t
val,
const std::vector<std::size_t> &cutSet) {
487 return !cutSet.empty() && (
val > (
etaBin < cutSet.size() ? cutSet[
etaBin] : cutSet.back()));
500 return {enoughMeasurements, tooManyHoles, tooManyOutliers};
508 ATH_MSG_ERROR(
"Outlier chi2 cut off provided but number of elements does not agree with"
509 " chi2 cut off for measurements which however is required: "
511 return StatusCode::FAILURE;
516 chi2CutOffOutlier.push_back( std::make_pair(
static_cast<float>(elm),
527 return StatusCode::SUCCESS ;
541 ATH_MSG_FATAL(
"Eta bins for statistics counter not in ascending order.");
551 std::lock_guard<std::mutex>
lock(m_mutex);
552 std::size_t category_i = 0;
553 for (
const std::array<unsigned int, kNStat> &src_stat : event_stat)
555 std::array<std::size_t, kNStat> &dest_stat = m_stat[category_i++];
556 for (std::size_t
i = 0;
i < src_stat.size(); ++
i)
558 assert(
i < dest_stat.size());
559 dest_stat[
i] += src_stat[
i];
568 std::vector<std::string> stat_labels =
574 std::make_pair(
kNoTrack,
"Cannot find track"),
582 std::make_pair(
kNoSecond,
"Tracks failing second CKF"),
588 assert(stat_labels.size() ==
kNStat);
594 std::vector<std::string> eta_labels;
596 for (std::size_t eta_bin_i = 0; eta_bin_i <
m_statEtaBins.size() + 2; ++eta_bin_i)
605 std::vector<std::size_t>
stat =
606 TableUtils::createCounterArrayWithProjections<std::size_t>(
nSeedCollections(),
611 std::size_t stat_stride =
615 std::size_t eta_stride =
619 std::stringstream table_out;
625 for (std::size_t stat_i = 0; stat_i <
kNStat; ++stat_i)
627 std::size_t dest_idx_offset = stat_i * stat_stride;
633 .dumpHeader(stat_i == 0)
634 .dumpFooter(stat_i + 1 ==
kNStat)
635 .separateLastRow(
true)
636 .minLabelWidth(max_label_width)
637 .labelPrefix(stat_labels.at(stat_i));
647 std::size_t dest_idx_offset = eta_bin_i * eta_stride;
651 eta_labels.at(eta_bin_i))
664 auto [ratio_labels, ratio_def] =
666 std::vector<TableUtils::SummandDefinition>{
700 for (std::size_t ratio_i = 0; ratio_i < ratio_labels.size(); ++ratio_i)
703 ratio_i * ratio_stride,
709 .dumpHeader(ratio_i == 0)
710 .dumpFooter(ratio_i + 1 == ratio_labels.size())
711 .separateLastRow(
true)
712 .minLabelWidth(max_label_width)
713 .labelPrefix(ratio_labels.at(ratio_i));
720 (
m_statEtaBins.size() + 1) * ratio_eta_stride + 0 * ratio_stride,
726 .minLabelWidth(max_label_width)
730 eta_labels.erase(eta_labels.end() - 1);
731 constexpr std::size_t ratio_i = 3;
733 ratio_i * ratio_stride,
741 .separateLastRow(
false)
742 .minLabelWidth(max_label_width)
743 .labelPrefix(ratio_labels.at(ratio_i));
752 std::vector<float>::const_iterator bin_iter = std::upper_bound(
m_statEtaBins.begin(),
756 assert(category_i < m_stat.size());
761 std::size_t
out = 0
u;
766 assert(category_i <
stat.size());
767 out +=
stat[category_i][counter_i];
776 return enoughMeasurementsPS && !tooManyHolesPS && !tooManyOutliersPS;