diff --git a/Core/include/Acts/Seeding/InternalSeed.hpp b/Core/include/Acts/Seeding/InternalSeed.hpp index 28dd297400a..a5552f9f71b 100644 --- a/Core/include/Acts/Seeding/InternalSeed.hpp +++ b/Core/include/Acts/Seeding/InternalSeed.hpp @@ -23,14 +23,17 @@ class InternalSeed { public: InternalSeed(InternalSpacePoint& s0, InternalSpacePoint& s1, - InternalSpacePoint& s2, float z); + InternalSpacePoint& s2, float z, + bool qualitySeed = false); InternalSeed& operator=(const InternalSeed& seed); const std::array*, 3> sp; float z() const { return m_z; } + bool qualitySeed() const { return m_qualitySeed; } protected: float m_z; + bool m_qualitySeed; }; /// @cond @@ -44,15 +47,17 @@ inline InternalSeed& InternalSeed::operator=( const InternalSeed& seed) { m_z = seed.m_z; sp = seed.sp; + m_qualitySeed = seed.m_qualitySeed; return (*this); } template inline InternalSeed::InternalSeed( InternalSpacePoint& s0, InternalSpacePoint& s1, - InternalSpacePoint& s2, float z) + InternalSpacePoint& s2, float z, bool qualitySeed) : sp({&s0, &s1, &s2}) { m_z = z; + m_qualitySeed = qualitySeed; } /// @endcond diff --git a/Core/include/Acts/Seeding/InternalSpacePoint.hpp b/Core/include/Acts/Seeding/InternalSpacePoint.hpp index c7d980ee945..8e7eb3b8e9f 100644 --- a/Core/include/Acts/Seeding/InternalSpacePoint.hpp +++ b/Core/include/Acts/Seeding/InternalSpacePoint.hpp @@ -40,8 +40,10 @@ class InternalSpacePoint { float phi() const { return atan2f(m_y, m_x); } const float& varianceR() const { return m_varianceR; } const float& varianceZ() const { return m_varianceZ; } + const float& deltaR() const { return m_deltaR; } const float& quality() const { return m_quality; } const float& cotTheta() const { return m_cotTheta; } + void setDeltaR(float deltaR) { m_deltaR = deltaR; } void setCotTheta(float cotTheta) { m_cotTheta = cotTheta; } void setQuality(float quality) { if (quality >= m_quality) { @@ -57,6 +59,7 @@ class InternalSpacePoint { float m_r; // radius in beam system coordinates float m_varianceR; // float m_varianceZ; // + float m_deltaR; // float m_cotTheta = std::numeric_limits< double>::quiet_NaN(); // 1/tanTheta estimated from central+this space // point. Its evaluation requires that the space diff --git a/Core/include/Acts/Seeding/SeedConfirmationRangeConfig.hpp b/Core/include/Acts/Seeding/SeedConfirmationRangeConfig.hpp new file mode 100644 index 00000000000..f443d3662ef --- /dev/null +++ b/Core/include/Acts/Seeding/SeedConfirmationRangeConfig.hpp @@ -0,0 +1,33 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2022 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +#include + +namespace Acts { +/// @brief contains parameters for seed confirmation +struct SeedConfirmationRangeConfig { + // z minimum and maximum of middle component of the seed used to define the + // region of the detector for seed confirmation + float zMinSeedConf = + std::numeric_limits::min(); // Acts::UnitConstants::mm + float zMaxSeedConf = + std::numeric_limits::max(); // Acts::UnitConstants::mm + // radius of bottom component of seed that is used to define the number of + // compatible top required + float rMaxSeedConf = + std::numeric_limits::max(); // Acts::UnitConstants::mm + // number of compatible top SPs of seed if bottom radius is larger than + // rMaxSeedConf + size_t nTopForLargeR = 0; + // number of compatible top SPs of seed if bottom radius is smaller than + // rMaxSeedConf + size_t nTopForSmallR = 0; +}; +} // namespace Acts diff --git a/Core/include/Acts/Seeding/SeedFilter.hpp b/Core/include/Acts/Seeding/SeedFilter.hpp index 0b5761be138..15218457edd 100644 --- a/Core/include/Acts/Seeding/SeedFilter.hpp +++ b/Core/include/Acts/Seeding/SeedFilter.hpp @@ -19,7 +19,6 @@ #include namespace Acts { - /// Filter seeds at various stages with the currently /// available information. template @@ -40,27 +39,50 @@ class SeedFilter { /// @param invHelixDiameterVec vector containing 1/(2*r) values where r is the helix radius /// @param impactParametersVec vector containing the impact parameters /// @param zOrigin on the z axis as defined by bottom and middle space point - /// @param outIt Output iterator for the seeds + /// @param numQualitySeeds number of high quality seeds in seed confirmation + /// @param numSeeds number of seeds that did not pass the quality confirmation but were still accepted, if quality confirmation is not used this is the total number of seeds + /// @param outCont Output container for the seeds virtual void filterSeeds_2SpFixed( InternalSpacePoint& bottomSP, InternalSpacePoint& middleSP, std::vector*>& topSpVec, std::vector& invHelixDiameterVec, std::vector& impactParametersVec, float zOrigin, - std::back_insert_iterator>>>> - outIt) const; + int& numQualitySeeds, int& numSeeds, + std::vector>>>& + outCont) const; /// Filter seeds once all seeds for one middle space point have been created /// @param seedsPerSpM vector of pairs containing weight and seed for all + /// @param numQualitySeeds number of high quality seeds in seed confirmation /// @param outIt Output iterator for the seeds /// for all seeds with the same middle space point virtual void filterSeeds_1SpFixed( std::vector>>>& seedsPerSpM, + int& numQualitySeeds, std::back_insert_iterator>> outIt) const; + + /// Check if there is a lower quality seed that can be replaced + /// @param bottomSP fixed bottom space point + /// @param middleSP fixed middle space point + /// @param topSp fixed top space point + /// @param zOrigin on the z axis as defined by bottom and middle space point + /// @param isQualitySeed information whether the seed is quality confirmed or not + /// @param weight weight of the seed + /// @param outCont container for the seeds + virtual void checkReplaceSeeds( + InternalSpacePoint& bottomSP, + InternalSpacePoint& middleSP, + InternalSpacePoint& topSp, float zOrigin, + bool isQualitySeed, float weight, + std::vector>>>& + outCont) const; + const SeedFilterConfig getSeedFilterConfig() const { return m_cfg; } const IExperimentCuts* getExperimentCuts() const { return m_experimentCuts; diff --git a/Core/include/Acts/Seeding/SeedFilter.ipp b/Core/include/Acts/Seeding/SeedFilter.ipp index ea274a8cef1..797d20eb60c 100644 --- a/Core/include/Acts/Seeding/SeedFilter.ipp +++ b/Core/include/Acts/Seeding/SeedFilter.ipp @@ -28,14 +28,35 @@ void SeedFilter::filterSeeds_2SpFixed( std::vector*>& topSpVec, std::vector& invHelixDiameterVec, std::vector& impactParametersVec, float zOrigin, - std::back_insert_iterator>>>> - outIt) const { + int& numQualitySeeds, int& numSeeds, + std::vector>>>& + outCont) const { + // seed confirmation + int nTopSeedConf = 0; + if (m_cfg.seedConfirmation) { + // check if bottom SP is in the central or forward region + SeedConfirmationRangeConfig seedConfRange = + (bottomSP.z() > m_cfg.centralSeedConfirmationRange.zMaxSeedConf || + bottomSP.z() < m_cfg.centralSeedConfirmationRange.zMinSeedConf) + ? m_cfg.forwardSeedConfirmationRange + : m_cfg.centralSeedConfirmationRange; + // set the minimum number of top SP depending on whether the bottom SP is + // in the central or forward region + nTopSeedConf = bottomSP.radius() > seedConfRange.rMaxSeedConf + ? seedConfRange.nTopForLargeR + : seedConfRange.nTopForSmallR; + } + + size_t maxWeightSeedIndex = 0; + bool maxWeightSeed = false; + float weightMax = -std::numeric_limits::max(); + // initialize original index locations std::vector idx(topSpVec.size()); std::iota(idx.begin(), idx.end(), 0); - if (m_cfg.curvatureSortingInFilter) { + if (m_cfg.curvatureSortingInFilter and topSpVec.size() > 2) { // sort indexes based on comparing values in invHelixDiameterVec std::sort(idx.begin(), idx.end(), [&invHelixDiameterVec](size_t i1, size_t i2) { @@ -46,13 +67,15 @@ void SeedFilter::filterSeeds_2SpFixed( for (auto& i : idx) { // if two compatible seeds with high distance in r are found, compatible // seeds span 5 layers - // -> very good seed + // -> weaker requirement for a good seed std::vector compatibleSeedR; float invHelixDiameter = invHelixDiameterVec[i]; float lowerLimitCurv = invHelixDiameter - m_cfg.deltaInvHelixDiameter; float upperLimitCurv = invHelixDiameter + m_cfg.deltaInvHelixDiameter; - float currentTop_r = topSpVec[i]->radius(); + // use deltaR instead of top radius + float currentTop_r = m_cfg.useDeltaRorTopRadius ? topSpVec[i]->deltaR() + : topSpVec[i]->radius(); float impact = impactParametersVec[i]; float weight = -(impact * m_cfg.impactWeightFactor); @@ -60,12 +83,10 @@ void SeedFilter::filterSeeds_2SpFixed( if (i == j) { continue; } - // compared top SP should have at least deltaRMin distance - float otherTop_r = topSpVec[j]->radius(); - float deltaR = currentTop_r - otherTop_r; - if (std::abs(deltaR) < m_cfg.deltaRMin) { - continue; - } + + float otherTop_r = m_cfg.useDeltaRorTopRadius ? topSpVec[j]->deltaR() + : topSpVec[j]->radius(); + // curvature difference within limits? if (invHelixDiameterVec[j] < lowerLimitCurv) { continue; @@ -76,6 +97,11 @@ void SeedFilter::filterSeeds_2SpFixed( } continue; } + // compared top SP should have at least deltaRMin distance + float deltaR = currentTop_r - otherTop_r; + if (std::abs(deltaR) < m_cfg.deltaRMin) { + continue; + } bool newCompSeed = true; for (float previousDiameter : compatibleSeedR) { // original ATLAS code uses higher min distance for 2nd found compatible @@ -105,9 +131,97 @@ void SeedFilter::filterSeeds_2SpFixed( continue; } } - outIt = std::make_pair( - weight, std::make_unique>( - bottomSP, middleSP, *topSpVec[i], zOrigin)); + + // increment in seed weight if number of compatible seeds is larger than + // numSeedIncrement + if (compatibleSeedR.size() > m_cfg.numSeedIncrement) { + weight += m_cfg.seedWeightIncrement; + } + + int deltaSeedConf; + if (m_cfg.seedConfirmation) { + // seed confirmation cuts - keep seeds if they have specific values of + // impact parameter, z-origin and number of compatible seeds inside a + // pre-defined range that also depends on the region of the detector (i.e. + // forward or central region) defined by SeedConfirmationRange + deltaSeedConf = compatibleSeedR.size() + 1 - nTopSeedConf; + if (deltaSeedConf < 0 || (numQualitySeeds and deltaSeedConf == 0)) { + continue; + } + bool seedRangeCuts = bottomSP.radius() < m_cfg.seedConfMinBottomRadius || + std::abs(zOrigin) > m_cfg.seedConfMaxZOrigin; + if (seedRangeCuts and deltaSeedConf == 0 and + impact > m_cfg.minImpactSeedConf) { + continue; + } + + // term on the weight that depends on the value of zOrigin + weight += -std::abs(zOrigin) + m_cfg.compatSeedWeight; + + // skip a bad quality seed if any of its constituents has a weight larger + // than the seed weight + if (weight < bottomSP.quality() and weight < middleSP.quality() and + weight < topSpVec[i]->quality()) { + continue; + } + + if (deltaSeedConf > 0) { + // if we have not yet reached our max number of quality seeds we add the + // new seed to outCont + if (numQualitySeeds < m_cfg.maxQualitySeedsPerSpMConf) { + // fill high quality seed + ++numQualitySeeds; + outCont.push_back(std::make_pair( + weight, + std::make_unique>( + bottomSP, middleSP, *topSpVec[i], zOrigin, true))); + } else { + // otherwise we check if there is a lower quality seed to remove + checkReplaceSeeds(bottomSP, middleSP, *topSpVec[i], zOrigin, true, + weight, outCont); + } + + } else if (weight > weightMax) { + // store weight and index of the best "lower quality" seed + weightMax = weight; + maxWeightSeedIndex = i; + maxWeightSeed = true; + } + } else { + // keep the normal behavior without seed quality confirmation + // if we have not yet reached our max number of seeds we add the new seed + // to outCont + if (numSeeds < m_cfg.maxSeedsPerSpMConf) { + // fill seed + ++numSeeds; + outCont.push_back(std::make_pair( + weight, std::make_unique>( + bottomSP, middleSP, *topSpVec[i], zOrigin, false))); + } else { + // otherwise we check if there is a lower quality seed to remove + checkReplaceSeeds(bottomSP, middleSP, *topSpVec[i], zOrigin, false, + weight, outCont); + } + } + } + // if no high quality seed was found for a certain middle+bottom SP pair, + // lower quality seeds can be accepted + if (m_cfg.seedConfirmation and maxWeightSeed and !numQualitySeeds) { + // if we have not yet reached our max number of seeds we add the new seed to + // outCont + if (numSeeds < m_cfg.maxSeedsPerSpMConf) { + // fill seed + ++numSeeds; + outCont.push_back(std::make_pair( + weightMax, + std::make_unique>( + bottomSP, middleSP, *topSpVec[maxWeightSeedIndex], zOrigin, + false))); + } else { + // otherwise we check if there is a lower quality seed to remove + checkReplaceSeeds(bottomSP, middleSP, *topSpVec[maxWeightSeedIndex], + zOrigin, false, weightMax, outCont); + } } } @@ -117,6 +231,7 @@ void SeedFilter::filterSeeds_1SpFixed( std::vector>>>& seedsPerSpM, + int& numQualitySeeds, std::back_insert_iterator>> outIt) const { // sort by weight and iterate only up to configured max number of seeds per @@ -155,9 +270,28 @@ void SeedFilter::filterSeeds_1SpFixed( // default filter removes the last seeds if maximum amount exceeded // ordering by weight by filterSeeds_2SpFixed means these are the lowest // weight seeds - for (; it < itBegin + maxSeeds; ++it) { + unsigned int numTotalSeeds = 0; + for (; it < itBegin + seedsPerSpM.size(); ++it) { + // stop if we reach the maximum number of seeds + if (numTotalSeeds >= maxSeeds) { + break; + } + float bestSeedQuality = (*it).first; + if (m_cfg.seedConfirmation) { + // continue if higher-quality seeds were found + if (numQualitySeeds > 0 and (*it).second->qualitySeed() == false) { + continue; + } + if (bestSeedQuality < (*it).second->sp[0]->quality() and + bestSeedQuality < (*it).second->sp[1]->quality() and + bestSeedQuality < (*it).second->sp[2]->quality()) { + continue; + } + } + + // set quality of seed components (*it).second->sp[0]->setQuality(bestSeedQuality); (*it).second->sp[1]->setQuality(bestSeedQuality); (*it).second->sp[2]->setQuality(bestSeedQuality); @@ -165,6 +299,52 @@ void SeedFilter::filterSeeds_1SpFixed( outIt = Seed{ (*it).second->sp[0]->sp(), (*it).second->sp[1]->sp(), (*it).second->sp[2]->sp(), (*it).second->z()}; + numTotalSeeds += 1; + } +} + +template +void SeedFilter::checkReplaceSeeds( + InternalSpacePoint& bottomSP, + InternalSpacePoint& middleSP, + InternalSpacePoint& topSp, float zOrigin, + bool isQualitySeed, float weight, + std::vector>>>& + outCont) const { + // find the index of the seeds with qualitySeed() == isQualitySeed in outCont + // and store in seed_indices + std::vector seed_indices; + seed_indices.reserve(outCont.size()); + auto it = std::find_if( + outCont.begin(), outCont.end(), + [&](std::pair>>& + weight_seed) { + return weight_seed.second->qualitySeed() == isQualitySeed; + }); + while (it != outCont.end()) { + seed_indices.emplace_back(std::distance(std::begin(outCont), it)); + it = std::find_if( + std::next(it), outCont.end(), + [&](std::pair< + float, std::unique_ptr>>& + outContCheck) { + return outContCheck.second->qualitySeed() == isQualitySeed; + }); + } + + // find index of the seed with the minimum weight + size_t index = + *std::min_element(std::begin(seed_indices), std::end(seed_indices), + [&outCont](const size_t& a, const size_t& b) { + return outCont.at(a).first < outCont.at(b).first; + }); + // replace that seed with the new one if new one is better + if (outCont.at(index).first < weight) { + outCont.at(index) = std::make_pair( + weight, std::make_unique>( + bottomSP, middleSP, topSp, zOrigin, isQualitySeed)); } } diff --git a/Core/include/Acts/Seeding/SeedFilterConfig.hpp b/Core/include/Acts/Seeding/SeedFilterConfig.hpp index 3298699f367..ee772c2b3dc 100644 --- a/Core/include/Acts/Seeding/SeedFilterConfig.hpp +++ b/Core/include/Acts/Seeding/SeedFilterConfig.hpp @@ -9,12 +9,12 @@ #pragma once #include "Acts/Definitions/Units.hpp" +#include "Acts/Seeding/SeedConfirmationRangeConfig.hpp" // System include(s). #include namespace Acts { - struct SeedFilterConfig { // the allowed delta between two inverted seed radii for them to be considered // compatible. @@ -37,11 +37,48 @@ struct SeedFilterConfig { // sort vectors vectors by curvature bool curvatureSortingInFilter = false; + // increment in seed weight if the number of compatible seeds is larger than + // numSeedIncrement, this is used in case of high occupancy scenarios if we + // want to increase the weight of the seed by seedWeightIncrement when the + // number of compatible seeds is higher than a certain value + float seedWeightIncrement = 0; + float numSeedIncrement = std::numeric_limits::infinity(); + + // seedConfirmation enables seed confirmation cuts - keep seeds if they have + // specific values of impact parameter, z-origin and number of compatible + // seeds inside a pre-defined range that also depends on the region of the + // detector (i.e. forward or central region) defined by SeedConfirmationRange + bool seedConfirmation = false; + // contains parameters for central seed confirmation + SeedConfirmationRangeConfig centralSeedConfirmationRange; + // contains parameters for forward seed confirmation + SeedConfirmationRangeConfig forwardSeedConfirmationRange; + // minimum radius for bottom SP in seed confirmation + float seedConfMinBottomRadius = 60. * Acts::UnitConstants::mm; + // maximum zOrigin in seed confirmation + float seedConfMaxZOrigin = 150. * Acts::UnitConstants::mm; + // minimum impact parameter for seed confirmation + float minImpactSeedConf = 1. * Acts::UnitConstants::mm; + + // maximum number of lower quality seeds in seed confirmation + int maxSeedsPerSpMConf = std::numeric_limits::max(); + // maximum number of quality seeds for each middle-bottom SP-duplet in seed + // confirmation if the limit is reached we check if there is a lower quality + // seed to be replaced + int maxQualitySeedsPerSpMConf = std::numeric_limits::max(); + + // use deltaR between top and middle SP instead of top radius to search for + // compatible SPs + bool useDeltaRorTopRadius = false; + SeedFilterConfig toInternalUnits() const { using namespace Acts::UnitLiterals; SeedFilterConfig config = *this; config.deltaRMin /= 1_mm; config.deltaInvHelixDiameter /= 1. / 1_mm; + config.seedConfMinBottomRadius /= 1_mm; + config.seedConfMaxZOrigin /= 1_mm; + config.minImpactSeedConf /= 1_mm; return config; } diff --git a/Core/include/Acts/Seeding/SeedFinderOrthogonal.hpp b/Core/include/Acts/Seeding/SeedFinderOrthogonal.hpp index f927bde8e3e..a51690c97d6 100644 --- a/Core/include/Acts/Seeding/SeedFinderOrthogonal.hpp +++ b/Core/include/Acts/Seeding/SeedFinderOrthogonal.hpp @@ -96,11 +96,11 @@ class SeedFinderOrthogonal { * @tparam output_container_t The type of the output seed container. * * @param spacePoints The input spacepoints from which to create seeds. - * @param out_it The output iterator to write seeds to. + * @param out_cont The output container to write seeds to. */ template void createSeeds(const input_container_t &spacePoints, - std::back_insert_iterator out_it) const; + output_container_t &out_cont) const; /** * @brief Perform seed finding, returning a new container of seeds. @@ -190,31 +190,32 @@ class SeedFinderOrthogonal { * @brief Filter potential candidate pairs, and output seeds into an * iterator. * - * @tparam output_it_t The type of the output iterator. + * @tparam output_container_t The type of the output container. * * @param middle The (singular) middle spacepoint. * @param bottom The (vector of) candidate bottom spacepoints. * @param top The (vector of) candidate top spacepoints. - * @param it The iterator to write the resulting seeds to. + * @param numQualitySeeds number of high quality seeds in seed confirmation. + * @param cont The container to write the resulting seeds to. */ - template + template void filterCandidates(internal_sp_t &middle, std::vector &bottom, - std::vector &top, - output_it_t it) const; + std::vector &top, int numQualitySeeds, + output_container_t &cont) const; /** * @brief Search for seeds starting from a given middle space point. * * @tparam NDims Number of dimensions for our spatial embedding (probably 3). - * @tparam output_it_t Type of the output iterator. + * @tparam output_container_t Type of the output container. * * @param tree The k-d tree to use for searching. - * @param out_it The iteratorto write output seeds to. + * @param out_cont The container write output seeds to. * @param middle_p The middle spacepoint to find seeds for. */ - template - void processFromMiddleSP(const tree_t &tree, output_it_t out_it, + template + void processFromMiddleSP(const tree_t &tree, output_container_t &out_cont, const typename tree_t::pair_t &middle_p) const; /** diff --git a/Core/include/Acts/Seeding/SeedFinderOrthogonal.ipp b/Core/include/Acts/Seeding/SeedFinderOrthogonal.ipp index 2a639f5e30c..e3a966054fb 100644 --- a/Core/include/Acts/Seeding/SeedFinderOrthogonal.ipp +++ b/Core/include/Acts/Seeding/SeedFinderOrthogonal.ipp @@ -199,10 +199,11 @@ SeedFinderOrthogonal::SeedFinderOrthogonal( } template -template +template void SeedFinderOrthogonal::filterCandidates( internal_sp_t &middle, std::vector &bottom, - std::vector &top, output_it_t it) const { + std::vector &top, int numQualitySeeds, + output_container_t &cont) const { float rM = middle.radius(); float varianceRM = middle.varianceR(); float varianceZM = middle.varianceZ(); @@ -241,6 +242,8 @@ void SeedFinderOrthogonal::filterCandidates( top[t]->z() - middle.z())); } + int numSeeds = 0; + for (size_t b = 0; b < numBotSP; b++) { auto lb = linCircleBottom[b]; float Zob = lb.Zo; @@ -347,15 +350,16 @@ void SeedFinderOrthogonal::filterCandidates( } if (!top_valid.empty()) { m_config.seedFilter->filterSeeds_2SpFixed( - *bottom[b], middle, top_valid, curvatures, impactParameters, Zob, it); + *bottom[b], middle, top_valid, curvatures, impactParameters, Zob, + numQualitySeeds, numSeeds, cont); } } } template -template +template void SeedFinderOrthogonal::processFromMiddleSP( - const tree_t &tree, output_it_t out_it, + const tree_t &tree, output_container_t &out_cont, const typename tree_t::pair_t &middle_p) const { using range_t = typename tree_t::range_t; internal_sp_t &middle = *middle_p.second; @@ -505,26 +509,29 @@ void SeedFinderOrthogonal::processFromMiddleSP( float, std::unique_ptr>>> protoseeds; + int numQualitySeeds = 0; + /* * If we have candidates for increasing z tracks, we try to combine them. */ if (!bottom_lh_v.empty() && !top_lh_v.empty()) { - filterCandidates(middle, bottom_lh_v, top_lh_v, - std::back_inserter(protoseeds)); + filterCandidates(middle, bottom_lh_v, top_lh_v, numQualitySeeds, + protoseeds); } /* * Try to combine candidates for decreasing z tracks. */ if (!bottom_hl_v.empty() && !top_hl_v.empty()) { - filterCandidates(middle, bottom_hl_v, top_hl_v, - std::back_inserter(protoseeds)); + filterCandidates(middle, bottom_hl_v, top_hl_v, numQualitySeeds, + protoseeds); } /* * Run a seed filter, just like in other seeding algorithms. */ - m_config.seedFilter->filterSeeds_1SpFixed(protoseeds, out_it); + m_config.seedFilter->filterSeeds_1SpFixed(protoseeds, numQualitySeeds, + std::back_inserter(out_cont)); } template @@ -553,8 +560,7 @@ auto SeedFinderOrthogonal::createTree( template template void SeedFinderOrthogonal::createSeeds( - const input_container_t &spacePoints, - std::back_insert_iterator out_it) const { + const input_container_t &spacePoints, output_container_t &out_cont) const { /* * The template parameters we accept are a little too generic, so we want to * run some basic checks to make sure the containers have the correct value @@ -591,7 +597,7 @@ void SeedFinderOrthogonal::createSeeds( * seeing what happens if we take them to be our middle spacepoint. */ for (const typename tree_t::pair_t &middle_p : tree) { - processFromMiddleSP(tree, out_it, middle_p); + processFromMiddleSP(tree, out_cont, middle_p); } /* @@ -609,7 +615,7 @@ SeedFinderOrthogonal::createSeeds( const input_container_t &spacePoints) const { std::vector r; - createSeeds(spacePoints, std::back_inserter(r)); + createSeeds(spacePoints, r); return r; } diff --git a/Core/include/Acts/Seeding/SeedFinderUtils.ipp b/Core/include/Acts/Seeding/SeedFinderUtils.ipp index 09795dbf57f..8e85801cad9 100644 --- a/Core/include/Acts/Seeding/SeedFinderUtils.ipp +++ b/Core/include/Acts/Seeding/SeedFinderUtils.ipp @@ -129,6 +129,8 @@ void transformCoordinates(std::vector& vec, linCircleVec.push_back(l); sp->setCotTheta(cot_theta); + + sp->setDeltaR(std::sqrt((x * x) + (y * y) + (deltaZ * deltaZ))); } // sort the SP in order of cotTheta std::sort(vec.begin(), vec.end(), diff --git a/Core/include/Acts/Seeding/Seedfinder.ipp b/Core/include/Acts/Seeding/Seedfinder.ipp index 234666cb989..4215ed729bc 100644 --- a/Core/include/Acts/Seeding/Seedfinder.ipp +++ b/Core/include/Acts/Seeding/Seedfinder.ipp @@ -74,7 +74,7 @@ void Seedfinder::createSeedsForGroup( size_t nTopSeedConf = 0; if (m_config.seedConfirmation == true) { // check if middle SP is in the central or forward region - SeedConfirmationRange seedConfRange = + SeedConfirmationRangeConfig seedConfRange = (zM > m_config.centralSeedConfirmationRange.zMaxSeedConf || zM < m_config.centralSeedConfirmationRange.zMinSeedConf) ? m_config.forwardSeedConfirmationRange @@ -250,6 +250,9 @@ void Seedfinder::createSeedsForGroup( size_t numBotSP = state.compatBottomSP.size(); size_t numTopSP = state.compatTopSP.size(); + int numQualitySeeds = 0; + int numSeeds = 0; + size_t t0 = 0; for (size_t b = 0; b < numBotSP; b++) { @@ -507,10 +510,12 @@ void Seedfinder::createSeedsForGroup( if (!state.topSpVec.empty()) { m_config.seedFilter->filterSeeds_2SpFixed( *state.compatBottomSP[b], *spM, state.topSpVec, state.curvatures, - state.impactParameters, Zob, std::back_inserter(state.seedsPerSpM)); + state.impactParameters, Zob, numQualitySeeds, numSeeds, + state.seedsPerSpM); } } - m_config.seedFilter->filterSeeds_1SpFixed(state.seedsPerSpM, outIt); + m_config.seedFilter->filterSeeds_1SpFixed(state.seedsPerSpM, + numQualitySeeds, outIt); } } diff --git a/Core/include/Acts/Seeding/SeedfinderConfig.hpp b/Core/include/Acts/Seeding/SeedfinderConfig.hpp index f0b6970fd39..55c0e297bee 100644 --- a/Core/include/Acts/Seeding/SeedfinderConfig.hpp +++ b/Core/include/Acts/Seeding/SeedfinderConfig.hpp @@ -10,23 +10,13 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/Units.hpp" +#include "Acts/Seeding/SeedConfirmationRangeConfig.hpp" #include "Acts/Utilities/Delegate.hpp" #include namespace Acts { -struct SeedConfirmationRange { - float zMinSeedConf = - std::numeric_limits::min() * Acts::UnitConstants::mm; - float zMaxSeedConf = - std::numeric_limits::max() * Acts::UnitConstants::mm; - float rMaxSeedConf = - std::numeric_limits::max() * Acts::UnitConstants::mm; - size_t nTopForLargeR = 0; - size_t nTopForSmallR = 0; -}; - // forward declaration to avoid cyclic dependence template class SeedFilter; @@ -63,9 +53,9 @@ struct SeedfinderConfig { // seed confirmation bool seedConfirmation = false; // parameters for central seed confirmation - SeedConfirmationRange centralSeedConfirmationRange; + SeedConfirmationRangeConfig centralSeedConfirmationRange; // parameters for forward seed confirmation - SeedConfirmationRange forwardSeedConfirmationRange; + SeedConfirmationRangeConfig forwardSeedConfirmationRange; // cut to the maximum value of delta z between SPs float deltaZMax = diff --git a/Examples/Python/src/TrackFinding.cpp b/Examples/Python/src/TrackFinding.cpp index 101c852a391..0e14b528044 100644 --- a/Examples/Python/src/TrackFinding.cpp +++ b/Examples/Python/src/TrackFinding.cpp @@ -63,6 +63,14 @@ void addTrackFinding(Context& ctx) { ACTS_PYTHON_MEMBER(maxSeedsPerSpM); ACTS_PYTHON_MEMBER(compatSeedLimit); ACTS_PYTHON_MEMBER(curvatureSortingInFilter); + ACTS_PYTHON_MEMBER(seedConfirmation); + ACTS_PYTHON_MEMBER(centralSeedConfirmationRange); + ACTS_PYTHON_MEMBER(forwardSeedConfirmationRange); + ACTS_PYTHON_MEMBER(useDeltaRorTopRadius); + ACTS_PYTHON_MEMBER(seedWeightIncrement); + ACTS_PYTHON_MEMBER(numSeedIncrement); + ACTS_PYTHON_MEMBER(maxSeedsPerSpMConf); + ACTS_PYTHON_MEMBER(maxQualitySeedsPerSpMConf); ACTS_PYTHON_STRUCT_END(); patchKwargsConstructor(c); } @@ -124,8 +132,9 @@ void addTrackFinding(Context& ctx) { } { - using seedConf = Acts::SeedConfirmationRange; - auto c = py::class_(m, "SeedConfirmationRange").def(py::init<>()); + using seedConf = Acts::SeedConfirmationRangeConfig; + auto c = py::class_(m, "SeedConfirmationRangeConfig") + .def(py::init<>()); ACTS_PYTHON_STRUCT_BEGIN(c, seedConf); ACTS_PYTHON_MEMBER(zMinSeedConf); ACTS_PYTHON_MEMBER(zMaxSeedConf); diff --git a/Examples/Scripts/Python/itk_seeding.py b/Examples/Scripts/Python/itk_seeding.py index 678c3840b36..9c9baa6a7f3 100755 --- a/Examples/Scripts/Python/itk_seeding.py +++ b/Examples/Scripts/Python/itk_seeding.py @@ -91,14 +91,14 @@ def runITkSeeding(field, csvInputDir, outputDir, s=None): deltaRMiddleMinSPRange=10, deltaRMiddleMaxSPRange=10, seedConfirmation=True, - centralSeedConfirmationRange=acts.SeedConfirmationRange( + centralSeedConfirmationRange=acts.SeedConfirmationRangeConfig( zMinSeedConf=250 * u.mm, zMaxSeedConf=250 * u.mm, rMaxSeedConf=140 * u.mm, nTopForLargeR=1, nTopForSmallR=2, ), # contains parameters for seed confirmation - forwardSeedConfirmationRange=acts.SeedConfirmationRange( + forwardSeedConfirmationRange=acts.SeedConfirmationRangeConfig( zMinSeedConf=3000 * u.mm, zMaxSeedConf=-3000 * u.mm, rMaxSeedConf=140 * u.mm, @@ -115,6 +115,10 @@ def runITkSeeding(field, csvInputDir, outputDir, s=None): compatSeedWeight=100, compatSeedLimit=3, curvatureSortingInFilter=True, + seedConfirmation=True, + centralSeedConfirmationRange=seedFinderConfig.centralSeedConfirmationRange, + forwardSeedConfirmationRange=seedFinderConfig.forwardSeedConfirmationRange, + useDeltaRorTopRadius=True, ) seedingAlg = acts.examples.SeedingAlgorithm( diff --git a/Plugins/Cuda/include/Acts/Plugins/Cuda/Seeding/Seedfinder.ipp b/Plugins/Cuda/include/Acts/Plugins/Cuda/Seeding/Seedfinder.ipp index 3390fb17f84..45e8fd9f85b 100644 --- a/Plugins/Cuda/include/Acts/Plugins/Cuda/Seeding/Seedfinder.ipp +++ b/Plugins/Cuda/include/Acts/Plugins/Cuda/Seeding/Seedfinder.ipp @@ -286,12 +286,12 @@ Seedfinder::createSeedsForGroup( std::make_unique>( bottomSP, middleSP, topSP, Zob))); } - - m_config.seedFilter->filterSeeds_1SpFixed(seedsPerSpM, + int numQualitySeeds = 0; // not used but needs to be fixed + m_config.seedFilter->filterSeeds_1SpFixed(seedsPerSpM, numQualitySeeds, std::back_inserter(outputVec)); } } ACTS_CUDA_ERROR_CHECK(cudaStreamDestroy(cuStream)); return outputVec; } -} // namespace Acts \ No newline at end of file +} // namespace Acts diff --git a/Plugins/Cuda/include/Acts/Plugins/Cuda/Seeding2/SeedFinder.ipp b/Plugins/Cuda/include/Acts/Plugins/Cuda/Seeding2/SeedFinder.ipp index 2e17aa11d14..d15e92f3108 100644 --- a/Plugins/Cuda/include/Acts/Plugins/Cuda/Seeding2/SeedFinder.ipp +++ b/Plugins/Cuda/include/Acts/Plugins/Cuda/Seeding2/SeedFinder.ipp @@ -204,8 +204,9 @@ SeedFinder::createSeedsForGroup( std::make_unique>( bottomSP, middleSP, topSP, 0))); } + int numQualitySeeds = 0; // not used but needs to be fixed m_commonConfig.seedFilter->filterSeeds_1SpFixed( - seedsPerSPM, std::back_inserter(outputVec)); + seedsPerSPM, numQualitySeeds, std::back_inserter(outputVec)); } // Free up all allocated device memory. @@ -222,4 +223,4 @@ void SeedFinder::setLogger( } } // namespace Cuda -} // namespace Acts \ No newline at end of file +} // namespace Acts diff --git a/Plugins/Sycl/include/Acts/Plugins/Sycl/Seeding/Seedfinder.ipp b/Plugins/Sycl/include/Acts/Plugins/Sycl/Seeding/Seedfinder.ipp index 31d345ff3d4..fa554984f28 100644 --- a/Plugins/Sycl/include/Acts/Plugins/Sycl/Seeding/Seedfinder.ipp +++ b/Plugins/Sycl/include/Acts/Plugins/Sycl/Seeding/Seedfinder.ipp @@ -140,9 +140,10 @@ Seedfinder::createSeedsForGroup( weight, std::make_unique>( bottomSP, middleSP, topSP, 0))); } - m_config.seedFilter->filterSeeds_1SpFixed(seedsPerSPM, + int numQualitySeeds = 0; // not used but needs to be fixed + m_config.seedFilter->filterSeeds_1SpFixed(seedsPerSPM, numQualitySeeds, std::back_inserter(outputVec)); } return outputVec; } -} // namespace Acts::Sycl \ No newline at end of file +} // namespace Acts::Sycl