10 const std::string&
name,
134 return StatusCode::FAILURE;
140 return StatusCode::FAILURE;
146 return StatusCode::FAILURE;
152 return StatusCode::FAILURE;
161 "Inconsistent config zBinsCustomLooping contains bins that are not "
163 return StatusCode::FAILURE;
172 "Inconsistent config rBinsCustomLooping contains bins that are not "
174 return StatusCode::FAILURE;
194 m_gridCfg.bottomBinFinder = Acts::GridBinFinder<3ul>(
250 m_filterCfg.centralSeedConfirmationRange.nTopForLargeR =
252 m_filterCfg.centralSeedConfirmationRange.nTopForSmallR =
254 m_filterCfg.centralSeedConfirmationRange.seedConfMinBottomRadius =
256 m_filterCfg.centralSeedConfirmationRange.seedConfMaxZOrigin =
258 m_filterCfg.centralSeedConfirmationRange.minImpactSeedConf =
263 m_filterCfg.forwardSeedConfirmationRange.nTopForLargeR =
265 m_filterCfg.forwardSeedConfirmationRange.nTopForSmallR =
267 m_filterCfg.forwardSeedConfirmationRange.seedConfMinBottomRadius =
269 m_filterCfg.forwardSeedConfirmationRange.seedConfMaxZOrigin =
271 m_filterCfg.forwardSeedConfirmationRange.minImpactSeedConf =
277 m_finder = Acts::TripletSeeder(
logger().cloneWithSuffix(
"Finder"));
283 return StatusCode::SUCCESS;
288 float zabs = std::abs(sp->
z());
289 float absCotTheta = zabs /
r;
294 if (zabs > 200 &&
r < 40)
302 static constexpr
float cotThetaEta120 = 1.5095;
303 if (absCotTheta < cotThetaEta120)
307 static constexpr
float cotThetaEta340 = 14.9654;
313 static constexpr
float cotThetaEta220 = 4.4571;
314 if (absCotTheta > cotThetaEta220 &&
r > 260.)
318 static constexpr
float cotThetaEta260 = 6.6947;
319 if (absCotTheta > cotThetaEta260 &&
r > 200.)
323 static constexpr
float cotThetaEta320 = 12.2459;
324 if (absCotTheta > cotThetaEta320 &&
r > 140.)
328 static constexpr
float cotThetaEta400 = 27.2899;
329 if (absCotTheta > cotThetaEta400)
336 const Acts::ConstSpacePointProxy2& middle,
338 bool isBottomCandidate)
const {
344 if (std::abs(middle.zr()[0]) > 1500 and middle.zr()[1] > 100 and
345 middle.zr()[1] < 150) {
354 static constexpr
float cotThetaEta120 = 1.5095;
355 static constexpr
float cotThetaEta360 = 18.2855;
357 float absCotTheta = std::abs(
cotTheta);
359 absCotTheta > cotThetaEta120 && absCotTheta < cotThetaEta360) {
367 const Acts::ConstSpacePointProxy2& spM,
368 const Acts::Range1D<float>& rMiddleSpRange)
const {
370 return {rMiddleSpRange.min(), rMiddleSpRange.max()};
373 throw std::runtime_error(
374 "m_rRangeMiddleSP is empty, please check the configuration.");
382 zBin == 0 ? zBin : --zBin;
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;
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) {
428 std::ranges::sort(grid.at(
i), [&](
const Acts::SpacePointIndex2&
a,
429 const Acts::SpacePointIndex2&
b) {
430 return selectedSpacePointsR[a] < selectedSpacePointsR[b];
434 Acts::SpacePointContainer2 selectedSpacePoints;
435 selectedSpacePoints.createColumns(
436 Acts::SpacePointColumns::SourceLinks | 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::SpacePointIndex2> copyFromIndices;
444 copyFromIndices.reserve(grid.numberOfSpacePoints());
445 std::vector<Acts::SpacePointIndexRange2> gridSpacePointRanges;
446 gridSpacePointRanges.reserve(grid.numberOfBins());
447 for (std::size_t
i = 0;
i < grid.numberOfBins(); ++
i) {
449 for (
const Acts::SpacePointIndex2 spIndex : grid.at(
i)) {
452 auto newSp = selectedSpacePoints.createSpacePoint();
453 newSp.assignSourceLinks(
454 std::array<Acts::SourceLink, 1>{Acts::SourceLink(sp)});
456 std::array<float, 2>{
static_cast<float>(sp->
x() - beamSpotPos[0]),
457 static_cast<float>(sp->
y() - beamSpotPos[1])};
458 newSp.zr() = std::array<float, 2>{
static_cast<float>(sp->
z()),
459 selectedSpacePointsR[spIndex]};
460 newSp.varianceZ() =
static_cast<float>(sp->
varianceZ());
461 newSp.varianceR() =
static_cast<float>(sp->
varianceR());
463 Eigen::Vector3f topStripVector =
465 Eigen::Vector3f bottomStripVector =
470 newSp.topStripVector() = std::array<float, 3>{
471 topStripVector.x(), topStripVector.y(), topStripVector.z()};
472 newSp.bottomStripVector() =
473 std::array<float, 3>{bottomStripVector.x(), bottomStripVector.y(),
474 bottomStripVector.z()};
475 newSp.stripCenterDistance() = std::array<float, 3>{
476 stripCenterDistance.x(), stripCenterDistance.y(),
477 stripCenterDistance.z()};
478 newSp.topStripCenter() = std::array<float, 3>{
479 topStripCenter.x(), topStripCenter.y(), topStripCenter.z()};
482 copyFromIndices.push_back(spIndex);
485 gridSpacePointRanges.emplace_back(
begin,
end);
489 selectedXAODSpacePoints = {};
490 selectedSpacePointsR = {};
492 ACTS_VERBOSE(
"Number of space points after selection "
493 << selectedSpacePoints.size() <<
" out of " << totalSpacePoints);
497 const Acts::Range1D<float> rRange = [&]() -> Acts::Range1D<float> {
499 float maxRange = std::numeric_limits<float>::lowest();
500 for (
const Acts::SpacePointIndexRange2&
range : gridSpacePointRanges) {
504 auto first = selectedSpacePoints[
range.first];
505 auto last = selectedSpacePoints[
range.second - 1];
507 maxRange =
std::max(last.zr()[1], maxRange);
509 return {minRange, maxRange};
512 auto bottomDoubletFinder =
513 Acts::DoubletSeedFinder::create(Acts::DoubletSeedFinder::DerivedConfig(
515 auto topDoubletFinder = Acts::DoubletSeedFinder::create(
517 auto tripletFinder = Acts::TripletSeedFinder::create(
521 const Acts::Range1D<float> rMiddleSpRange(
526 Acts::BroadTripletSeedFilter::Cache filterCache;
527 Acts::TripletSeeder::Cache cache;
532 std::vector<Acts::SpacePointContainer2::ConstRange> bottomSpRanges;
533 std::optional<Acts::SpacePointContainer2::ConstRange> middleSpRange;
534 std::vector<Acts::SpacePointContainer2::ConstRange> topSpRanges;
536 Acts::SeedContainer2 tmpSeedContainer;
537 tmpSeedContainer.reserve(seedContainer.
capacity());
539 for (
const auto [bottom, middle,
top] : grid.binnedGroup()) {
540 ACTS_VERBOSE(
"Process middle bin " << middle);
541 if (middle >= gridSpacePointRanges.size()) {
542 ATH_MSG_ERROR(
"Grid Binned Group returned an unreasonable middle bin");
543 return StatusCode::FAILURE;
546 bottomSpRanges.clear();
550 bottom, std::back_inserter(bottomSpRanges),
551 [&](std::size_t
b) -> Acts::SpacePointContainer2::ConstRange {
552 return selectedSpacePoints.range(gridSpacePointRanges[
b]).asConst();
555 selectedSpacePoints.range(gridSpacePointRanges[middle]).asConst();
557 top, std::back_inserter(topSpRanges),
558 [&](std::size_t
t) -> Acts::SpacePointContainer2::ConstRange {
559 return selectedSpacePoints.range(gridSpacePointRanges[
t]).asConst();
564 auto firstMiddleSp = middleSpRange->front();
565 auto radiusRangeForMiddle =
568 ACTS_VERBOSE(
"Validity range (radius) for the middle space point is ["
569 << radiusRangeForMiddle.first <<
", "
570 << radiusRangeForMiddle.second <<
"]");
573 cache, *bottomDoubletFinder, *topDoubletFinder, *tripletFinder,
filter,
574 selectedSpacePoints, bottomSpRanges, *middleSpRange, topSpRanges,
575 radiusRangeForMiddle, tmpSeedContainer);
581 auto selectionFunction =
582 [&filterState](
const Acts::MutableSeedProxy2& seed) ->
bool {
583 float seedQuality = seed.quality();
584 float bottomQuality =
585 filterState.bestSeedQualityMap.at(seed.spacePointIndices()[0]);
586 float middleQuality =
587 filterState.bestSeedQualityMap.at(seed.spacePointIndices()[1]);
589 filterState.bestSeedQualityMap.at(seed.spacePointIndices()[2]);
591 return bottomQuality <= seedQuality || middleQuality <= seedQuality ||
592 topQuality <= seedQuality;
595 seedContainer.
reserve(tmpSeedContainer.size());
598 for (Acts::MutableSeedProxy2 seed : tmpSeedContainer) {
604 selectedSpacePoints.at(seed.spacePointIndices()[0])
608 selectedSpacePoints.at(seed.spacePointIndices()[1])
612 selectedSpacePoints.at(seed.spacePointIndices()[2])
616 auto outputSeed = std::make_unique<ActsTrk::Seed>(*bottom, *middle, *
top);
617 outputSeed->setVertexZ(seed.vertexZ());
618 outputSeed->setQuality(seed.quality());
619 seedContainer.
push_back(std::move(outputSeed));
622 return StatusCode::SUCCESS;