396 const EventContext& ctx,
397 const std::vector<const xAOD::SpacePointContainer*>& spacePointCollections,
398 const Eigen::Vector3f& beamSpotPos,
float bFieldInZ,
403 gridCfg.bFieldInZ = bFieldInZ;
405 Acts::CylindricalSpacePointGrid2 grid(gridCfg,
406 logger().cloneWithSuffix(
"Grid"));
408 std::size_t totalSpacePoints = 0;
410 totalSpacePoints += spacePoints->size();
413 std::vector<const xAOD::SpacePoint*> selectedXAODSpacePoints;
414 std::vector<float> selectedSpacePointsR;
415 selectedXAODSpacePoints.reserve(totalSpacePoints);
416 selectedSpacePointsR.reserve(totalSpacePoints);
420 float x =
static_cast<float>(
sp->x() - beamSpotPos[0]);
421 float y =
static_cast<float>(
sp->y() - beamSpotPos[1]);
422 float z =
static_cast<float>(
sp->z());
423 float r = std::hypot(
x,
y);
424 float phi = std::atan2(
y,
x);
430 grid.insert(selectedXAODSpacePoints.size(),
phi,
z,
r);
431 selectedXAODSpacePoints.push_back(
sp);
432 selectedSpacePointsR.push_back(
r);
436 for (std::size_t i = 0; i < grid.numberOfBins(); ++i) {
438 grid.at(i), [&](Acts::SpacePointIndex2
a, Acts::SpacePointIndex2 b) {
439 return selectedSpacePointsR[a] < selectedSpacePointsR[b];
443 Acts::SpacePointContainer2 selectedSpacePoints;
444 selectedSpacePoints.createColumns(
445 Acts::SpacePointColumns::CopyFromIndex |
446 Acts::SpacePointColumns::PackedXY | Acts::SpacePointColumns::PackedZR |
447 Acts::SpacePointColumns::VarianceZ | Acts::SpacePointColumns::VarianceR);
449 selectedSpacePoints.createColumns(Acts::SpacePointColumns::Strip);
451 selectedSpacePoints.reserve(grid.numberOfSpacePoints());
452 std::vector<Acts::SpacePointIndexRange2> gridSpacePointRanges;
453 gridSpacePointRanges.reserve(grid.numberOfBins());
454 for (std::size_t i = 0; i < grid.numberOfBins(); ++i) {
455 std::uint32_t begin = selectedSpacePoints.size();
456 for (
const Acts::SpacePointIndex2 spIndex : grid.at(i)) {
459 auto newSp = selectedSpacePoints.createSpacePoint();
460 newSp.copyFromIndex() = spIndex;
462 std::array<float, 2>{
static_cast<float>(
sp->x() - beamSpotPos[0]),
463 static_cast<float>(
sp->y() - beamSpotPos[1])};
464 newSp.zr() = std::array<float, 2>{
static_cast<float>(
sp->z()),
465 selectedSpacePointsR[spIndex]};
466 newSp.varianceZ() =
static_cast<float>(
sp->varianceZ());
467 newSp.varianceR() =
static_cast<float>(
sp->varianceR());
469 Eigen::Vector3f topStripVector =
470 sp->topHalfStripLength() *
sp->topStripDirection();
471 Eigen::Vector3f bottomStripVector =
472 sp->bottomHalfStripLength() *
sp->bottomStripDirection();
473 Eigen::Vector3f stripCenterDistance =
sp->stripCenterDistance();
474 Eigen::Vector3f topStripCenter =
sp->topStripCenter();
476 newSp.topStripVector() = std::array<float, 3>{
477 topStripVector.x(), topStripVector.y(), topStripVector.z()};
478 newSp.bottomStripVector() =
479 std::array<float, 3>{bottomStripVector.x(), bottomStripVector.y(),
480 bottomStripVector.z()};
481 newSp.stripCenterDistance() = std::array<float, 3>{
482 stripCenterDistance.x(), stripCenterDistance.y(),
483 stripCenterDistance.z()};
484 newSp.topStripCenter() = std::array<float, 3>{
485 topStripCenter.x(), topStripCenter.y(), topStripCenter.z()};
488 std::uint32_t end = selectedSpacePoints.size();
489 gridSpacePointRanges.emplace_back(begin, end);
493 selectedSpacePointsR = {};
495 ACTS_VERBOSE(
"Number of space points after selection "
496 << selectedSpacePoints.size() <<
" out of " << totalSpacePoints);
500 const Acts::Range1D<float> rRange = [&]() -> Acts::Range1D<float> {
501 float minRange = std::numeric_limits<float>::max();
502 float maxRange = std::numeric_limits<float>::lowest();
503 for (
const Acts::SpacePointIndexRange2& range : gridSpacePointRanges) {
504 if (range.first == range.second) {
507 auto first = selectedSpacePoints[range.first];
508 auto last = selectedSpacePoints[range.second - 1];
509 minRange = std::min(first.zr()[1], minRange);
510 maxRange = std::max(last.zr()[1], maxRange);
512 return {minRange, maxRange};
521 if(inputHoughVtx->size() == 1) {
528 auto bottomDoubletFinder =
529 Acts::DoubletSeedFinder::create(Acts::DoubletSeedFinder::DerivedConfig(
530 bottomDoubletFinderCfg, bFieldInZ));
531 auto topDoubletFinder = Acts::DoubletSeedFinder::create(
533 auto tripletFinder = Acts::TripletSeedFinder::create(
537 const Acts::Range1D<float> rMiddleSpRange(
541 Acts::BroadTripletSeedFilter::State filterState;
542 Acts::BroadTripletSeedFilter::Cache filterCache;
543 Acts::TripletSeeder::Cache cache;
545 Acts::BroadTripletSeedFilter filter(
m_filterCfg, filterState, filterCache,
548 std::vector<Acts::SpacePointContainer2::ConstRange> bottomSpRanges;
549 std::optional<Acts::SpacePointContainer2::ConstRange> middleSpRange;
550 std::vector<Acts::SpacePointContainer2::ConstRange> topSpRanges;
552 Acts::SeedContainer2 tmpSeedContainer;
554 for (
const auto [bottom, middle,
top] : grid.binnedGroup()) {
555 ACTS_VERBOSE(
"Process middle bin " << middle);
556 if (middle >= gridSpacePointRanges.size()) {
557 ATH_MSG_ERROR(
"Grid Binned Group returned an unreasonable middle bin");
558 return StatusCode::FAILURE;
561 bottomSpRanges.clear();
564 std::ranges::transform(
565 bottom, std::back_inserter(bottomSpRanges),
566 [&](std::size_t b) -> Acts::SpacePointContainer2::ConstRange {
567 return selectedSpacePoints.range(gridSpacePointRanges[b]).asConst();
570 selectedSpacePoints.range(gridSpacePointRanges[middle]).asConst();
571 std::ranges::transform(
572 top, std::back_inserter(topSpRanges),
573 [&](std::size_t t) -> Acts::SpacePointContainer2::ConstRange {
574 return selectedSpacePoints.range(gridSpacePointRanges[t]).asConst();
579 auto firstMiddleSp = middleSpRange->front();
580 auto radiusRangeForMiddle =
583 ACTS_VERBOSE(
"Validity range (radius) for the middle space point is ["
584 << radiusRangeForMiddle.first <<
", "
585 << radiusRangeForMiddle.second <<
"]");
588 cache, *bottomDoubletFinder, *topDoubletFinder, *tripletFinder, filter,
589 selectedSpacePoints, bottomSpRanges, *middleSpRange, topSpRanges,
590 radiusRangeForMiddle, tmpSeedContainer);
596 auto selectionFunction =
597 [&filterState](
const Acts::MutableSeedProxy2& seed) ->
bool {
598 float seedQuality = seed.quality();
599 float bottomQuality =
600 filterState.bestSeedQualityMap.at(seed.spacePointIndices()[0]);
601 float middleQuality =
602 filterState.bestSeedQualityMap.at(seed.spacePointIndices()[1]);
604 filterState.bestSeedQualityMap.at(seed.spacePointIndices()[2]);
606 return bottomQuality <= seedQuality || middleQuality <= seedQuality ||
607 topQuality <= seedQuality;
610 seedContainer.
reserve(seedContainer.
size() + tmpSeedContainer.size());
613 for (Acts::MutableSeedProxy2 seed : tmpSeedContainer) {
619 Acts::ConstSeedProxy2(seed), [&](
const Acts::SpacePointIndex2 spIndex) {
620 const Acts::SpacePointIndex2 originalIndex =
621 selectedSpacePoints.at(spIndex).copyFromIndex();
622 return selectedXAODSpacePoints[originalIndex];
626 return StatusCode::SUCCESS;