Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:11:02

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 // SeedFinderGbts.ipp
0010 // TODO: update to C++17 style
0011 
0012 #include "Acts/Geometry/Extent.hpp"
0013 #include "Acts/Seeding/SeedFilter.hpp"
0014 #include "Acts/Seeding/SeedFinder.hpp"
0015 #include "Acts/Seeding/SeedFinderGbtsConfig.hpp"
0016 #include "Acts/Seeding/SeedFinderUtils.hpp"
0017 #include "Acts/Utilities/BinningType.hpp"
0018 
0019 #include <algorithm>
0020 #include <cmath>
0021 #include <fstream>
0022 #include <functional>
0023 #include <iostream>
0024 #include <list>
0025 #include <numbers>
0026 #include <numeric>
0027 #include <type_traits>
0028 #include <vector>
0029 
0030 // core so in ACTS namespace
0031 
0032 namespace Acts {
0033 
0034 template <typename external_spacepoint_t>
0035 SeedFinderGbts<external_spacepoint_t>::SeedFinderGbts(
0036     const SeedFinderGbtsConfig<external_spacepoint_t>& config,
0037     const GbtsGeometry<external_spacepoint_t>& gbtsGeo,
0038     std::unique_ptr<const Acts::Logger> logger)
0039     : m_config(config),
0040       m_storage(
0041           std::make_unique<GbtsDataStorage<external_spacepoint_t>>(gbtsGeo)),
0042       m_logger(std::move(logger)) {}
0043 
0044 // define loadspace points function
0045 template <typename external_spacepoint_t>
0046 void SeedFinderGbts<external_spacepoint_t>::loadSpacePoints(
0047     const std::vector<GbtsSP<external_spacepoint_t>>& gbtsSPvect) {
0048   ACTS_VERBOSE("Loading space points");
0049   for (const auto& gbtssp : gbtsSPvect) {
0050     bool is_Pixel = gbtssp.isPixel();
0051     if (!is_Pixel) {
0052       continue;
0053     }
0054     m_storage->addSpacePoint(gbtssp, (m_config.m_useClusterWidth > 0));
0055   }
0056 
0057   m_config.m_phiSliceWidth = 2 * std::numbers::pi / m_config.m_nMaxPhiSlice;
0058 
0059   m_storage->sortByPhi();
0060 
0061   m_storage->generatePhiIndexing(1.5 * m_config.m_phiSliceWidth);
0062 }
0063 
0064 template <typename external_spacepoint_t>
0065 void SeedFinderGbts<external_spacepoint_t>::runGbts_TrackFinder(
0066     std::vector<GbtsTrigTracklet<external_spacepoint_t>>& vTracks,
0067     const Acts::RoiDescriptor& roi,
0068     const Acts::GbtsGeometry<external_spacepoint_t>& gbtsGeo) {
0069   ACTS_VERBOSE("Running GBTS Track Finder");
0070   const float min_z0 = roi.zedMinus();
0071   const float max_z0 = roi.zedPlus();
0072   const float cut_zMinU = min_z0 + m_config.maxOuterRadius * roi.dzdrMinus();
0073   const float cut_zMaxU = max_z0 + m_config.maxOuterRadius * roi.dzdrPlus();
0074   float m_minR_squ = m_config.m_tripletPtMin * m_config.m_tripletPtMin /
0075                      std::pow(m_config.ptCoeff, 2);  // from athena
0076   float m_maxCurv = m_config.ptCoeff / m_config.m_tripletPtMin;
0077   const float maxKappa_high_eta = 0.8 / m_minR_squ;
0078   const float maxKappa_low_eta = 0.6 / m_minR_squ;
0079 
0080   // 1. loop over stages
0081 
0082   int currentStage = 0;
0083 
0084   const Acts::GbtsConnector& connector = *(gbtsGeo.connector());
0085 
0086   std::vector<Acts::GbtsEdge<external_spacepoint_t>> edgeStorage;
0087 
0088   edgeStorage.reserve(m_config.MaxEdges);
0089 
0090   int nEdges = 0;
0091 
0092   for (std::map<int, std::vector<GbtsConnector::LayerGroup>>::const_iterator
0093            it = connector.m_layerGroups.begin();
0094        it != connector.m_layerGroups.end(); ++it, currentStage++) {
0095     // loop over L1 layers for the current stage
0096 
0097     for (const auto& layerGroup : (*it).second) {
0098       unsigned int dst = layerGroup.m_dst;  // n1 : inner nodes
0099 
0100       const GbtsLayer<external_spacepoint_t>* pL1 =
0101           gbtsGeo.getGbtsLayerByKey(dst);
0102 
0103       if (pL1 == nullptr) {
0104         continue;
0105       }
0106 
0107       for (const auto& conn :
0108            layerGroup.m_sources) {  // loop over L2(L1) for the current stage
0109 
0110         unsigned int src = conn->m_src;  // n2 : the new connectors
0111 
0112         const GbtsLayer<external_spacepoint_t>* pL2 =
0113             gbtsGeo.getGbtsLayerByKey(src);
0114 
0115         if (pL2 == nullptr) {
0116           continue;
0117         }
0118         int nDstBins = pL1->m_bins.size();
0119         int nSrcBins = pL2->m_bins.size();
0120 
0121         for (int b1 = 0; b1 < nDstBins; b1++) {  // loop over bins in Layer 1
0122 
0123           const GbtsEtaBin<external_spacepoint_t>& B1 =
0124               m_storage->getEtaBin(pL1->m_bins.at(b1));
0125 
0126           if (B1.empty()) {
0127             continue;
0128           }
0129 
0130           float rb1 = pL1->getMinBinRadius(b1);
0131 
0132           // 3. loops over source eta-bins
0133 
0134           for (int b2 = 0; b2 < nSrcBins; b2++) {  // loop over bins in Layer 2
0135 
0136             if (m_config.m_useEtaBinning && (nSrcBins + nDstBins > 2)) {
0137               if (conn->m_binTable[b1 + b2 * nDstBins] != 1) {
0138                 continue;  // using precomputed LUT
0139               }
0140             }
0141 
0142             const GbtsEtaBin<external_spacepoint_t>& B2 =
0143                 m_storage->getEtaBin(pL2->m_bins.at(b2));
0144 
0145             if (B2.empty()) {
0146               continue;
0147             }
0148 
0149             float rb2 = pL2->getMaxBinRadius(b2);
0150 
0151             // calculated delta Phi for rb1 ---> rb2 extrapolation
0152 
0153             float deltaPhi =
0154                 0.5f *
0155                 m_config
0156                     .m_phiSliceWidth;  // the default sliding window along phi
0157 
0158             if (m_config.m_useEtaBinning) {
0159               deltaPhi = 0.001f + m_maxCurv * std::abs(rb2 - rb1);
0160             }
0161 
0162             unsigned int first_it = 0;
0163             for (const auto& n1 : B1.m_vn) {  // loop over nodes in Layer 1
0164 
0165               if (n1->m_in.size() >= MAX_SEG_PER_NODE) {
0166                 continue;
0167               }
0168 
0169               float r1 = n1->m_spGbts.SP->r();
0170               float x1 = n1->m_spGbts.SP->x();
0171               float y1 = n1->m_spGbts.SP->y();
0172               float z1 = n1->m_spGbts.SP->z();
0173               float phi1 = std::atan(x1 / y1);
0174 
0175               float minPhi = phi1 - deltaPhi;
0176               float maxPhi = phi1 + deltaPhi;
0177 
0178               for (unsigned int n2PhiIdx = first_it;
0179                    n2PhiIdx < B2.m_vPhiNodes.size();
0180                    n2PhiIdx++) {  // sliding window over nodes in Layer 2
0181 
0182                 float phi2 = B2.m_vPhiNodes.at(n2PhiIdx).first;
0183 
0184                 if (phi2 < minPhi) {
0185                   first_it = n2PhiIdx;
0186                   continue;
0187                 }
0188                 if (phi2 > maxPhi) {
0189                   break;
0190                 }
0191 
0192                 GbtsNode<external_spacepoint_t>* n2 =
0193                     B2.m_vn.at(B2.m_vPhiNodes.at(n2PhiIdx).second).get();
0194 
0195                 if (n2->m_out.size() >= MAX_SEG_PER_NODE) {
0196                   continue;
0197                 }
0198                 if (n2->isFull()) {
0199                   continue;
0200                 }
0201 
0202                 float r2 = n2->m_spGbts.SP->r();
0203 
0204                 float dr = r2 - r1;
0205 
0206                 if (dr < m_config.m_minDeltaRadius) {
0207                   continue;
0208                 }
0209 
0210                 float z2 = n2->m_spGbts.SP->z();
0211 
0212                 float dz = z2 - z1;
0213                 float tau = dz / dr;
0214                 float ftau = std::abs(tau);
0215                 if (ftau > 36.0) {
0216                   continue;
0217                 }
0218 
0219                 if (ftau < n1->m_minCutOnTau) {
0220                   continue;
0221                 }
0222                 if (ftau < n2->m_minCutOnTau) {
0223                   continue;
0224                 }
0225                 if (ftau > n1->m_maxCutOnTau) {
0226                   continue;
0227                 }
0228                 if (ftau > n2->m_maxCutOnTau) {
0229                   continue;
0230                 }
0231 
0232                 if (m_config.m_doubletFilterRZ) {
0233                   float z0 = z1 - r1 * tau;
0234 
0235                   if (z0 < min_z0 || z0 > max_z0) {
0236                     continue;
0237                   }
0238 
0239                   float zouter = z0 + m_config.maxOuterRadius * tau;
0240 
0241                   if (zouter < cut_zMinU || zouter > cut_zMaxU) {
0242                     continue;
0243                   }
0244                 }
0245 
0246                 float dx = n2->m_spGbts.SP->x() - x1;
0247                 float dy = n2->m_spGbts.SP->y() - y1;
0248 
0249                 float L2 = 1 / (dx * dx + dy * dy);
0250 
0251                 float D =
0252                     (n2->m_spGbts.SP->y() * x1 - y1 * n2->m_spGbts.SP->x()) /
0253                     (r1 * r2);
0254 
0255                 float kappa = D * D * L2;
0256 
0257                 if (ftau < 4.0) {  // eta = 2.1
0258                   if (kappa > maxKappa_low_eta) {
0259                     continue;
0260                   }
0261 
0262                 } else {
0263                   if (kappa > maxKappa_high_eta) {
0264                     continue;
0265                   }
0266                 }
0267 
0268                 // match edge candidate against edges incoming to n2
0269 
0270                 float exp_eta = std::sqrt(1 + tau * tau) - tau;
0271 
0272                 bool isGood =
0273                     n2->m_in.size() <=
0274                     2;  // we must have enough incoming edges to decide
0275 
0276                 if (!isGood) {
0277                   float uat_1 = 1.0f / exp_eta;
0278 
0279                   for (const auto& n2_in_idx : n2->m_in) {
0280                     float tau2 = edgeStorage.at(n2_in_idx).m_p[0];
0281                     float tau_ratio = tau2 * uat_1 - 1.0f;
0282 
0283                     // bad match
0284                     if (std::abs(tau_ratio) > m_config.cut_tau_ratio_max) {
0285                       continue;
0286                     }
0287 
0288                     // good match found
0289                     isGood = true;
0290                     break;
0291                   }
0292                 }
0293                 if (!isGood) {
0294                   continue;  // no match found, skip creating [n1 <- n2] edge
0295                 }
0296 
0297                 float curv = D * std::sqrt(L2);  // signed curvature
0298                 float dPhi2 = std::asin(curv * r2);
0299                 float dPhi1 = std::asin(curv * r1);
0300 
0301                 if (nEdges < m_config.MaxEdges) {
0302                   edgeStorage.emplace_back(n1.get(), n2, exp_eta, curv,
0303                                            phi1 + dPhi1, phi2 + dPhi2);
0304 
0305                   n1->addIn(nEdges);
0306                   n2->addOut(nEdges);
0307 
0308                   nEdges++;
0309                 }
0310               }  // loop over n2 (outer) nodes
0311             }  // loop over n1 (inner) nodes
0312           }  // loop over source eta bins
0313         }  // loop over dst eta bins
0314       }  // loop over L2(L1) layers
0315     }  // loop over dst layers
0316   }  // loop over the stages of doublet making
0317 
0318   std::vector<const GbtsNode<external_spacepoint_t>*> vNodes;
0319 
0320   m_storage->getConnectingNodes(vNodes);
0321 
0322   if (vNodes.empty()) {
0323     ACTS_VERBOSE("No nodes");
0324     return;
0325   }
0326 
0327   int nNodes = vNodes.size();
0328 
0329   for (int nodeIdx = 0; nodeIdx < nNodes; nodeIdx++) {
0330     const GbtsNode<external_spacepoint_t>& pN = *vNodes.at(nodeIdx);
0331 
0332     std::vector<std::pair<float, int>> in_sort, out_sort;
0333     in_sort.resize(pN.m_in.size());
0334     out_sort.resize(pN.m_out.size());
0335 
0336     for (int inIdx = 0; inIdx < static_cast<int>(pN.m_in.size()); inIdx++) {
0337       int inEdgeIdx = pN.m_in.at(inIdx);
0338       Acts::GbtsEdge<external_spacepoint_t>* pS = &(edgeStorage.at(inEdgeIdx));
0339       in_sort[inIdx].second = inEdgeIdx;
0340       in_sort[inIdx].first = pS->m_p[0];
0341     }
0342     for (int outIdx = 0; outIdx < static_cast<int>(pN.m_out.size()); outIdx++) {
0343       int outEdgeIdx = pN.m_out.at(outIdx);
0344       Acts::GbtsEdge<external_spacepoint_t>* pS = &(edgeStorage.at(outEdgeIdx));
0345       out_sort[outIdx].second = outEdgeIdx;
0346       out_sort[outIdx].first = pS->m_p[0];
0347     }
0348 
0349     std::ranges::sort(in_sort);
0350     std::ranges::sort(out_sort);
0351 
0352     unsigned int last_out = 0;
0353 
0354     for (unsigned int in_idx = 0; in_idx < in_sort.size();
0355          in_idx++) {  // loop over incoming edges
0356 
0357       int inEdgeIdx = in_sort[in_idx].second;
0358 
0359       Acts::GbtsEdge<external_spacepoint_t>* pS = &(edgeStorage.at(inEdgeIdx));
0360 
0361       pS->m_nNei = 0;
0362       float tau1 = pS->m_p[0];
0363       float uat_1 = 1.0f / tau1;
0364       float curv1 = pS->m_p[1];
0365       float Phi1 = pS->m_p[2];
0366 
0367       for (unsigned int out_idx = last_out; out_idx < out_sort.size();
0368            out_idx++) {
0369         int outEdgeIdx = out_sort[out_idx].second;
0370 
0371         Acts::GbtsEdge<external_spacepoint_t>* pNS =
0372             &(edgeStorage.at(outEdgeIdx));
0373 
0374         float tau2 = pNS->m_p[0];
0375         float tau_ratio = tau2 * uat_1 - 1.0f;
0376 
0377         if (tau_ratio < -m_config.cut_tau_ratio_max) {
0378           last_out = out_idx;
0379           continue;
0380         }
0381         if (tau_ratio > m_config.cut_tau_ratio_max) {
0382           break;
0383         }
0384 
0385         float dPhi = pNS->m_p[3] - Phi1;
0386 
0387         if (dPhi < -std::numbers::pi_v<float>) {
0388           dPhi += static_cast<float>(2 * std::numbers::pi);
0389         } else if (dPhi > std::numbers::pi_v<float>) {
0390           dPhi -= static_cast<float>(2 * std::numbers::pi);
0391         }
0392 
0393         if (dPhi < -m_config.cut_dphi_max || dPhi > m_config.cut_dphi_max) {
0394           continue;
0395         }
0396 
0397         float curv2 = pNS->m_p[1];
0398         float dcurv = curv2 - curv1;
0399 
0400         if (dcurv < -m_config.cut_dcurv_max || dcurv > m_config.cut_dcurv_max) {
0401           continue;
0402         }
0403 
0404         pS->m_vNei[pS->m_nNei++] = outEdgeIdx;
0405         if (pS->m_nNei >= N_SEG_CONNS) {
0406           break;
0407         }
0408       }
0409     }
0410   }
0411 
0412   const int maxIter = 15;
0413 
0414   int maxLevel = 0;
0415 
0416   int iter = 0;
0417 
0418   std::vector<Acts::GbtsEdge<external_spacepoint_t>*> v_old;
0419 
0420   for (int edgeIndex = 0; edgeIndex < nEdges; edgeIndex++) {
0421     Acts::GbtsEdge<external_spacepoint_t>* pS = &(edgeStorage.at(edgeIndex));
0422     if (pS->m_nNei == 0) {
0423       continue;
0424     }
0425     v_old.push_back(pS);  // TO-DO: increment level for segments as they already
0426                           // have at least one neighbour
0427   }
0428 
0429   for (; iter < maxIter; iter++) {
0430     // generate proposals
0431     std::vector<Acts::GbtsEdge<external_spacepoint_t>*> v_new;
0432     v_new.clear();
0433 
0434     for (auto pS : v_old) {
0435       int next_level = pS->m_level;
0436 
0437       for (int nIdx = 0; nIdx < pS->m_nNei; nIdx++) {
0438         unsigned int nextEdgeIdx = pS->m_vNei[nIdx];
0439 
0440         Acts::GbtsEdge<external_spacepoint_t>* pN =
0441             &(edgeStorage.at(nextEdgeIdx));
0442 
0443         if (pS->m_level == pN->m_level) {
0444           next_level = pS->m_level + 1;
0445           v_new.push_back(pS);
0446           break;
0447         }
0448       }
0449 
0450       pS->m_next = next_level;  // proposal
0451     }
0452     // update
0453 
0454     int nChanges = 0;
0455 
0456     for (auto pS : v_new) {
0457       if (pS->m_next != pS->m_level) {
0458         nChanges++;
0459         pS->m_level = pS->m_next;
0460         if (maxLevel < pS->m_level) {
0461           maxLevel = pS->m_level;
0462         }
0463       }
0464     }
0465 
0466     if (nChanges == 0) {
0467       break;
0468     }
0469 
0470     v_old = std::move(v_new);
0471     v_new.clear();
0472   }
0473 
0474   int minLevel = 3;  // a triplet + 2 confirmation
0475 
0476   std::vector<Acts::GbtsEdge<external_spacepoint_t>*> vSeeds;
0477 
0478   vSeeds.reserve(m_config.MaxEdges / 2);
0479 
0480   for (int edgeIndex = 0; edgeIndex < nEdges; edgeIndex++) {
0481     Acts::GbtsEdge<external_spacepoint_t>* pS = &(edgeStorage.at(edgeIndex));
0482 
0483     if (pS->m_level < minLevel) {
0484       continue;
0485     }
0486 
0487     vSeeds.push_back(pS);
0488   }
0489 
0490   m_triplets.clear();
0491 
0492   std::ranges::sort(
0493       vSeeds, typename Acts::GbtsEdge<external_spacepoint_t>::CompareLevel());
0494 
0495   if (vSeeds.empty()) {
0496     return;
0497   }
0498 
0499   // backtracking
0500 
0501   GbtsTrackingFilter<external_spacepoint_t> tFilter(
0502       m_config.m_layerGeometry, edgeStorage,
0503       logger().cloneWithSuffix("GbtsFilter"));
0504 
0505   for (auto pS : vSeeds) {
0506     if (pS->m_level == -1) {
0507       continue;
0508     }
0509 
0510     GbtsEdgeState<external_spacepoint_t> rs(false);
0511 
0512     tFilter.followTrack(pS, rs);
0513 
0514     if (!rs.m_initialized) {
0515       continue;
0516     }
0517 
0518     if (static_cast<int>(rs.m_vs.size()) < minLevel) {
0519       continue;
0520     }
0521 
0522     std::vector<const GbtsSP<external_spacepoint_t>*> vSP;
0523 
0524     for (typename std::vector<
0525              Acts::GbtsEdge<external_spacepoint_t>*>::reverse_iterator sIt =
0526              rs.m_vs.rbegin();
0527          sIt != rs.m_vs.rend(); ++sIt) {
0528       (*sIt)->m_level = -1;  // mark as collected
0529 
0530       if (sIt == rs.m_vs.rbegin()) {
0531         vSP.push_back(&(*sIt)->m_n1->m_spGbts);
0532       }
0533       vSP.push_back(&(*sIt)->m_n2->m_spGbts);
0534     }
0535 
0536     if (vSP.size() < 3) {
0537       continue;
0538     }
0539 
0540     // making triplets
0541 
0542     unsigned int nTriplets = 0;
0543 
0544     std::vector<TrigInDetTriplet<external_spacepoint_t>> output;
0545 
0546     for (unsigned int idx_m = 1; idx_m < vSP.size() - 1; idx_m++) {
0547       const GbtsSP<external_spacepoint_t>& spM = *vSP.at(idx_m);
0548       const double pS_r = spM.SP->r();
0549       const double pS_x = spM.SP->x();
0550       const double pS_y = spM.SP->y();
0551       const double cosA = pS_x / pS_r;
0552       const double sinA = pS_y / pS_r;
0553 
0554       for (unsigned int idx_o = idx_m + 1; idx_o < vSP.size(); idx_o++) {
0555         const GbtsSP<external_spacepoint_t>& spO = *vSP.at(idx_o);
0556 
0557         double dx = spO.SP->x() - pS_x;
0558         double dy = spO.SP->y() - pS_y;
0559         double R2inv = 1.0 / (dx * dx + dy * dy);
0560         double xn = dx * cosA + dy * sinA;
0561         double yn = -dx * sinA + dy * cosA;
0562 
0563         const double uo = xn * R2inv;
0564         const double vo = yn * R2inv;
0565 
0566         for (unsigned int idx_i = 0; idx_i < idx_m; idx_i++) {
0567           const GbtsSP<external_spacepoint_t>& spI = *vSP.at(idx_i);
0568 
0569           dx = spI.SP->x() - pS_x;
0570           dy = spI.SP->y() - pS_y;
0571           R2inv = 1.0 / (dx * dx + dy * dy);
0572 
0573           xn = dx * cosA + dy * sinA;
0574           yn = -dx * sinA + dy * cosA;
0575 
0576           const double ui = xn * R2inv;
0577           const double vi = yn * R2inv;
0578 
0579           // 1. pT estimate
0580 
0581           const double du = uo - ui;
0582           if (du == 0.0) {
0583             continue;
0584           }
0585           const double A = (vo - vi) / du;
0586           const double B = vi - A * ui;
0587 
0588           if ((1 + A * A) < (B * B) * m_minR_squ) {
0589             continue;
0590           }
0591 
0592           // 2. d0 cut
0593 
0594           const double fabs_d0 = std::abs(pS_r * (B * pS_r - A));
0595 
0596           if (fabs_d0 > m_config.m_tripletD0Max) {
0597             continue;
0598           }
0599 
0600           // 3. phi0 cut
0601 
0602           // if (!roi.isFullscan()) {
0603           //   const double uc = 2 * B * pS_r - A;
0604           //   // const double phi0 = std::atan2(sinA - uc * cosA, cosA + uc *
0605           //   sinA);
0606           //   //           if ( !RoiUtil::containsPhi( *roiDescriptor, phi0 ) )
0607           //   {
0608           //   //             continue;
0609           //   //           }
0610           // }
0611 
0612           // 4. add new triplet
0613 
0614           const double Q = fabs_d0 * fabs_d0;
0615 
0616           output.emplace_back(spI, spM, spO, Q);
0617 
0618           nTriplets++;
0619 
0620           if (nTriplets >= m_config.m_maxTripletBufferLength) {
0621             break;
0622           }
0623         }
0624         if (nTriplets >= m_config.m_maxTripletBufferLength) {
0625           break;
0626         }
0627       }
0628       if (nTriplets >= m_config.m_maxTripletBufferLength) {
0629         break;
0630       }
0631     }
0632 
0633     if (output.empty()) {
0634       continue;
0635     }
0636 
0637     vTracks.emplace_back(vSP, output);
0638   }
0639 }
0640 
0641 template <typename external_spacepoint_t>
0642 template <typename output_container_t>
0643 void SeedFinderGbts<external_spacepoint_t>::createSeeds(
0644     const Acts::RoiDescriptor& roi,
0645     const Acts::GbtsGeometry<external_spacepoint_t>& gbtsGeo,
0646     output_container_t& out_cont) {
0647   ACTS_VERBOSE("Creating seeds");
0648   std::vector<GbtsTrigTracklet<external_spacepoint_t>>
0649       vTracks;  // make empty vector
0650 
0651   vTracks.reserve(5000);
0652 
0653   runGbts_TrackFinder(vTracks, roi, gbtsGeo);  // returns filled vector
0654 
0655   if (vTracks.empty()) {
0656     return;
0657   }
0658 
0659   m_triplets.clear();  // member of class , saying not declared, maybe public?
0660 
0661   for (auto& track : vTracks) {
0662     for (auto& seed : track.m_seeds) {  // access member of GbtsTrigTracklet
0663 
0664       float newQ = seed.Q();  // function of TrigInDetTriplet
0665       if (m_config.m_LRTmode) {
0666         // In LRT mode penalize pixels in Triplets
0667         if (seed.s1().isPixel()) {
0668           newQ += 1000;  // functions of TrigSiSpacePointBase
0669         }
0670         if (seed.s2().isPixel()) {
0671           newQ += 1000;
0672         }
0673         if (seed.s3().isPixel()) {
0674           newQ += 1000;
0675         }
0676       } else {
0677         // In normal (non LRT) mode penalise SSS by 1000, PSS (if enabled) and
0678         // PPS by 10000
0679         if (seed.s3().isSCT()) {
0680           newQ += seed.s1().isSCT() ? 1000.0 : 10000.0;
0681         }
0682       }
0683       seed.Q(newQ);
0684       m_triplets.emplace_back(seed);
0685     }
0686   }
0687   vTracks.clear();
0688 
0689   for (auto& triplet : m_triplets) {
0690     const external_spacepoint_t* S1 =
0691         triplet.s1().SP;  // triplet-> GbtsSP-> simspacepoint
0692     const external_spacepoint_t* S2 = triplet.s2().SP;
0693     const external_spacepoint_t* S3 = triplet.s3().SP;
0694 
0695     // input to seed
0696     float Vertex = 0;
0697     float Quality = triplet.Q();
0698     // make a new seed, add to vector of seeds
0699     out_cont.emplace_back(*S1, *S2, *S3);
0700     out_cont.back().setVertexZ(Vertex);
0701     out_cont.back().setQuality(Quality);
0702   }
0703 }
0704 
0705 // outer called in alg
0706 template <typename external_spacepoint_t>
0707 std::vector<Seed<external_spacepoint_t>>
0708 SeedFinderGbts<external_spacepoint_t>::createSeeds(
0709     const Acts::RoiDescriptor& roi,
0710     const Acts::GbtsGeometry<external_spacepoint_t>& gbtsGeo) {
0711   std::vector<seed_t> r;
0712   createSeeds(roi, gbtsGeo, r);
0713   return r;
0714 }
0715 
0716 }  // namespace Acts