387 const EventContext& ctx,
388 const std::vector<const xAOD::SpacePointContainer*>& spacePointCollections,
389 const Eigen::Vector3f& beamSpotPos,
float bFieldInZ,
394 gridCfg.bFieldInZ = bFieldInZ;
396 Acts::CylindricalSpacePointGrid2 grid(gridCfg,
397 logger().cloneWithSuffix(
"Grid"));
399 std::size_t totalSpacePoints = 0;
401 totalSpacePoints += spacePoints->size();
404 std::vector<const xAOD::SpacePoint*> selectedXAODSpacePoints;
405 std::vector<float> selectedSpacePointsR;
406 selectedXAODSpacePoints.reserve(totalSpacePoints);
407 selectedSpacePointsR.reserve(totalSpacePoints);
411 float x =
static_cast<float>(
sp->x() - beamSpotPos[0]);
412 float y =
static_cast<float>(
sp->y() - beamSpotPos[1]);
413 float z =
static_cast<float>(
sp->z());
414 float r = std::hypot(
x,
y);
415 float phi = std::atan2(
y,
x);
421 grid.insert(selectedXAODSpacePoints.size(),
phi,
z,
r);
422 selectedXAODSpacePoints.push_back(
sp);
423 selectedSpacePointsR.push_back(
r);
427 for (std::size_t i = 0; i < grid.numberOfBins(); ++i) {
429 grid.at(i), [&](Acts::SpacePointIndex2
a, Acts::SpacePointIndex2 b) {
430 return selectedSpacePointsR[a] < selectedSpacePointsR[b];
434 Acts::SpacePointContainer2 selectedSpacePoints;
435 selectedSpacePoints.createColumns(
436 Acts::SpacePointColumns::CopyFromIndex | Acts::SpacePointColumns::XY |
437 Acts::SpacePointColumns::ZR | Acts::SpacePointColumns::VarianceZ |
438 Acts::SpacePointColumns::VarianceR);
440 selectedSpacePoints.createColumns(Acts::SpacePointColumns::Strip);
442 selectedSpacePoints.reserve(grid.numberOfSpacePoints());
443 std::vector<Acts::SpacePointIndexRange2> gridSpacePointRanges;
444 gridSpacePointRanges.reserve(grid.numberOfBins());
445 for (std::size_t i = 0; i < grid.numberOfBins(); ++i) {
446 std::uint32_t begin = selectedSpacePoints.size();
447 for (
const Acts::SpacePointIndex2 spIndex : grid.at(i)) {
450 auto newSp = selectedSpacePoints.createSpacePoint();
451 newSp.copyFromIndex() = spIndex;
453 std::array<float, 2>{
static_cast<float>(
sp->x() - beamSpotPos[0]),
454 static_cast<float>(
sp->y() - beamSpotPos[1])};
455 newSp.zr() = std::array<float, 2>{
static_cast<float>(
sp->z()),
456 selectedSpacePointsR[spIndex]};
457 newSp.varianceZ() =
static_cast<float>(
sp->varianceZ());
458 newSp.varianceR() =
static_cast<float>(
sp->varianceR());
460 Eigen::Vector3f topStripVector =
461 sp->topHalfStripLength() *
sp->topStripDirection();
462 Eigen::Vector3f bottomStripVector =
463 sp->bottomHalfStripLength() *
sp->bottomStripDirection();
464 Eigen::Vector3f stripCenterDistance =
sp->stripCenterDistance();
465 Eigen::Vector3f topStripCenter =
sp->topStripCenter();
467 newSp.topStripVector() = std::array<float, 3>{
468 topStripVector.x(), topStripVector.y(), topStripVector.z()};
469 newSp.bottomStripVector() =
470 std::array<float, 3>{bottomStripVector.x(), bottomStripVector.y(),
471 bottomStripVector.z()};
472 newSp.stripCenterDistance() = std::array<float, 3>{
473 stripCenterDistance.x(), stripCenterDistance.y(),
474 stripCenterDistance.z()};
475 newSp.topStripCenter() = std::array<float, 3>{
476 topStripCenter.x(), topStripCenter.y(), topStripCenter.z()};
479 std::uint32_t end = selectedSpacePoints.size();
480 gridSpacePointRanges.emplace_back(begin, end);
484 selectedSpacePointsR = {};
486 ACTS_VERBOSE(
"Number of space points after selection "
487 << selectedSpacePoints.size() <<
" out of " << totalSpacePoints);
491 const Acts::Range1D<float> rRange = [&]() -> Acts::Range1D<float> {
492 float minRange = std::numeric_limits<float>::max();
493 float maxRange = std::numeric_limits<float>::lowest();
494 for (
const Acts::SpacePointIndexRange2& range : gridSpacePointRanges) {
495 if (range.first == range.second) {
498 auto first = selectedSpacePoints[range.first];
499 auto last = selectedSpacePoints[range.second - 1];
500 minRange = std::min(first.zr()[1], minRange);
501 maxRange = std::max(last.zr()[1], maxRange);
503 return {minRange, maxRange};
506 auto bottomDoubletFinder =
507 Acts::DoubletSeedFinder::create(Acts::DoubletSeedFinder::DerivedConfig(
509 auto topDoubletFinder = Acts::DoubletSeedFinder::create(
511 auto tripletFinder = Acts::TripletSeedFinder::create(
515 const Acts::Range1D<float> rMiddleSpRange(
519 Acts::BroadTripletSeedFilter::State filterState;
520 Acts::BroadTripletSeedFilter::Cache filterCache;
521 Acts::TripletSeeder::Cache cache;
523 Acts::BroadTripletSeedFilter filter(
m_filterCfg, filterState, filterCache,
526 std::vector<Acts::SpacePointContainer2::ConstRange> bottomSpRanges;
527 std::optional<Acts::SpacePointContainer2::ConstRange> middleSpRange;
528 std::vector<Acts::SpacePointContainer2::ConstRange> topSpRanges;
530 Acts::SeedContainer2 tmpSeedContainer;
532 for (
const auto [bottom, middle,
top] : grid.binnedGroup()) {
533 ACTS_VERBOSE(
"Process middle bin " << middle);
534 if (middle >= gridSpacePointRanges.size()) {
535 ATH_MSG_ERROR(
"Grid Binned Group returned an unreasonable middle bin");
536 return StatusCode::FAILURE;
539 bottomSpRanges.clear();
542 std::ranges::transform(
543 bottom, std::back_inserter(bottomSpRanges),
544 [&](std::size_t b) -> Acts::SpacePointContainer2::ConstRange {
545 return selectedSpacePoints.range(gridSpacePointRanges[b]).asConst();
548 selectedSpacePoints.range(gridSpacePointRanges[middle]).asConst();
549 std::ranges::transform(
550 top, std::back_inserter(topSpRanges),
551 [&](std::size_t t) -> Acts::SpacePointContainer2::ConstRange {
552 return selectedSpacePoints.range(gridSpacePointRanges[t]).asConst();
557 auto firstMiddleSp = middleSpRange->front();
558 auto radiusRangeForMiddle =
561 ACTS_VERBOSE(
"Validity range (radius) for the middle space point is ["
562 << radiusRangeForMiddle.first <<
", "
563 << radiusRangeForMiddle.second <<
"]");
566 cache, *bottomDoubletFinder, *topDoubletFinder, *tripletFinder, filter,
567 selectedSpacePoints, bottomSpRanges, *middleSpRange, topSpRanges,
568 radiusRangeForMiddle, tmpSeedContainer);
574 auto selectionFunction =
575 [&filterState](
const Acts::MutableSeedProxy2& seed) ->
bool {
576 float seedQuality = seed.quality();
577 float bottomQuality =
578 filterState.bestSeedQualityMap.at(seed.spacePointIndices()[0]);
579 float middleQuality =
580 filterState.bestSeedQualityMap.at(seed.spacePointIndices()[1]);
582 filterState.bestSeedQualityMap.at(seed.spacePointIndices()[2]);
584 return bottomQuality <= seedQuality || middleQuality <= seedQuality ||
585 topQuality <= seedQuality;
588 seedContainer.
reserve(seedContainer.
size() + tmpSeedContainer.size());
591 for (Acts::MutableSeedProxy2 seed : tmpSeedContainer) {
596 seedContainer.
push_back(Acts::ConstSeedProxy2(seed),
597 [&](
const Acts::SpacePointIndex2 spIndex) {
598 return selectedXAODSpacePoints[spIndex];
602 return StatusCode::SUCCESS;