22 #include <unordered_set>
23 #include <nlohmann/json.hpp>
41 ATH_MSG_ERROR(
"MM or STGC not part of initialized detector layout");
42 return StatusCode::FAILURE;
45 return StatusCode::SUCCESS;
48 template <
class ContainerType>
51 const ContainerType* &contToPush)
const {
55 return StatusCode::SUCCESS;
59 contToPush = readHandle.cptr();
60 return StatusCode::SUCCESS;
71 Amg::intersect<3>(startPos, dirEstUp, testHit->
planeNormal(), planeOffSet).value_or(0) * dirEstUp;
73 Amg::intersect<3>(startPos, dirEstDn, testHit->
planeNormal(), planeOffSet).value_or(0) * dirEstDn;
75 switch (testHit->
type()) {
79 const double halfLength = prd->
readoutElement()->
stripLayer(prd->measurementHash()).design().stripLength(prd->channelNumber()) * 0.5;
84 const bool below = estPlaneArrivalDn.y() >
std::max(leftEdge.y(), rightEdge.y());
85 const bool above = estPlaneArrivalUp.y() <
std::min(leftEdge.y(), rightEdge.y());
87 << (below || above ?
" is outside the window" :
" is inside the window"));
104 const HitLayVec &combinatoricLayers)
const {
109 unsigned int iterLay0{0}, iterLay1{0}, iterLay2{0}, iterLay3{0};
110 unsigned int startLay1{0}, startLay2{0}, startLay3{0};
112 for( ; iterLay0 < combinatoricLayers[0].size() ; ++iterLay0){
114 const SpacePoint* hit0 = combinatoricLayers[0][iterLay0];
125 for( iterLay1 = startLay1; iterLay1 < combinatoricLayers[1].size() ; ++iterLay1){
126 const SpacePoint* hit1 = combinatoricLayers[1][iterLay1];
135 for( iterLay2 = startLay2; iterLay2 < combinatoricLayers[2].size() ; ++iterLay2){
136 const SpacePoint* hit2 = combinatoricLayers[2][iterLay2];
139 iterLay1 = combinatoricLayers[1].size();
145 for( iterLay3 = startLay3; iterLay3 < combinatoricLayers[3].size(); ++iterLay3){
146 const SpacePoint* hit3 = combinatoricLayers[3][iterLay3];
149 iterLay1 = combinatoricLayers[1].size();
150 iterLay2 = combinatoricLayers[2].size();
156 seedHitsFromLayers.emplace_back(
HitVec{hit0, hit1, hit2, hit3});
161 return seedHitsFromLayers;
167 const HitLayVec& stripHitsLayers)
const {
173 for (
unsigned int i = 0;
i < stripHitsLayers.size();
i++) {
175 double offset = stripHitsLayers[
i].front()->positionInChamber().dot(stripHitsLayers[
i].front()->planeNormal());
176 const Amg::Vector3D extrapPos = startPos + Amg::intersect<3>(startPos, direction, stripHitsLayers[
i].front()->planeNormal(),
offset).value_or(0) * direction;
178 unsigned int indexOfHit = stripHitsLayers[
i].size()+1;
179 unsigned int triedHit{0};
183 for (
unsigned int j = 0; j < stripHitsLayers[
i].size(); j++) {
184 auto hit = stripHitsLayers[
i].at(j);
189 if (
pull > minPull) {
206 <<
Amg::toString(stripHitsLayers[
i].at(indexOfHit)->positionInChamber())<<
", dir: "<<
Amg::toString(stripHitsLayers[
i].at(indexOfHit)->directionInChamber())<<
" found with pull "<<minPull);
207 combinatoricHits.push_back(stripHitsLayers[
i].at(indexOfHit));
210 return combinatoricHits;
213 std::unique_ptr<SegmentSeed>
217 const HitLayVec& extensionLayers)
const {
220 ATH_MSG_VERBOSE(
"Seed Rejection: Wrong number of initial layers for seeding --they should be four");
231 double interceptX = segPos.x();
232 double interceptY = segPos.y();
235 for (std::size_t
i = 0;
i < 4;
i++) {
241 double halfLength = 0.5 * clust->
readoutElement()->
stripLayer(clust->measurementHash()).design().stripLength(clust->channelNumber());
243 if (std::abs(
params[
i]) > halfLength) {
244 ATH_MSG_VERBOSE(
"Seed Rejection: Invalid seed - outside of the strip's length");
251 auto extendedHits =
extendHits(segPos, direction, extensionLayers);
252 hits.insert(
hits.end(), extendedHits.begin(), extendedHits.end());
253 return std::make_unique<SegmentSeed>(tanTheta, interceptY, tanPhi,
254 interceptX,
hits.size(),
255 std::move(
hits),
max.parentBucket());
258 std::vector<std::unique_ptr<SegmentSeed>>
263 HitLayVec stripHitsLayers{hitLayers.stripHits()};
265 std::vector<std::unique_ptr<SegmentSeed>> seeds;
267 unsigned int layerSize = stripHitsLayers.size();
277 constexpr
double legX{0.2};
280 const auto* mmClust =
static_cast<const xAOD::MMCluster*
>(sp->primaryMeasurement());
291 const double pull2 = (mmClust->localPosition<1>().
x() - simHit->
localPosition().x()) / std::sqrt(mmClust->localCovariance<1>().x());
296 m_visionTool->visualizeBucket(Gaudi::Hive::currentContext(), *
max.parentBucket(),
297 "truth", std::move(primitives));
301 std::array<const SpacePoint*, 4> seedHits{};
302 for (std::size_t
i = 0;
i < layerSize - 3; ++
i) {
303 seedHits[0] = stripHitsLayers[
i].front();
304 for (std::size_t j =
i + 1; j < layerSize - 2; ++j) {
305 seedHits[1] = stripHitsLayers[j].front();
306 for (std::size_t
k = j + 1;
k < layerSize - 1; ++
k) {
307 seedHits[2] = stripHitsLayers[
k].front();
308 for (std::size_t
l =
k + 1;
l < layerSize; ++
l) {
309 seedHits[3] = stripHitsLayers[
l].front();
310 AmgSymMatrix(2) bMatrix = CombinatorialSeedSolver::betaMatrix(seedHits);
311 if (std::abs(bMatrix.determinant()) < 1.e-6) {
316 const HitLayVec layers{stripHitsLayers[
i], stripHitsLayers[j], stripHitsLayers[
k], stripHitsLayers[
l]};
324 std::copy_if(stripHitsLayers.begin(), stripHitsLayers.end(), std::back_inserter(extensionLayers),
326 const Identifier gasGapId = m_idHelperSvc->gasGapId(stripLayer.front()->identify());
327 return std::ranges::find_if(layers,[&gasGapId, this](const HitVec& spacePoints){
328 return gasGapId == m_idHelperSvc->gasGapId(spacePoints.front()->identify());
334 for (
auto &combinatoricHits :
result) {
337 seeds.push_back(std::move(seed));
353 ATH_CHECK(retrieveContainer(ctx, m_etaKey, maxima));
356 ATH_CHECK(retrieveContainer(ctx, m_geoCtxKey, gctx));
360 ATH_CHECK(writeMaxima.record(std::make_unique<SegmentSeedContainer>()));
365 std::vector<std::unique_ptr<SegmentSeed>> seeds = findSeedsFromMaximum(*
max, *gctx);
367 for(
const auto& hitMax :
max->getHitsInMax()){
368 ATH_MSG_VERBOSE(
"Hit "<<m_idHelperSvc->toString(hitMax->identify())<<
", "
372 for (
auto &seed : seeds) {
373 ATH_MSG_VERBOSE(
"Seed tanTheta = "<<seed->tanTheta()<<
", y0 = "<<seed->interceptY()
374 <<
", tanPhi = "<<seed->tanPhi()<<
", x0 = "<<seed->interceptX()<<
", hits in the seed "<<seed->getHitsInMax().size());
376 for(
const auto& hit : seed->getHitsInMax()){
380 if (m_visionTool.isEnabled()) {
381 m_visionTool->visualizeSeed(ctx, *seed,
"#phi-combinatorialSeed");
383 writeMaxima->push_back(std::move(seed));
388 return StatusCode::SUCCESS;