Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2026-07-16 08:07:53

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 #include "Acts/Seeding/GbtsDataStorage.hpp"
0010 
0011 #include <algorithm>
0012 #include <cmath>
0013 #include <cstring>
0014 #include <numbers>
0015 #include <utility>
0016 
0017 namespace Acts::Experimental {
0018 
0019 GbtsEtaBin::GbtsEtaBin() {
0020   m_vn.reserve(1000);
0021 }
0022 
0023 void GbtsEtaBin::sortByPhi() {
0024   std::vector<std::pair<float, const GbtsNode*>> phiBuckets[32];
0025 
0026   int nBuckets = 31;
0027 
0028   for (const auto& n : m_vn) {
0029     int bIdx = static_cast<int>(
0030         0.5 * nBuckets *
0031         (n->phi() / static_cast<float>(std::numbers::pi) + 1.0f));
0032     phiBuckets[bIdx].push_back(std::make_pair(n->phi(), n));
0033   }
0034 
0035   for (auto& b : phiBuckets) {
0036     std::sort(b.begin(), b.end());
0037   }
0038 
0039   int idx = 0;
0040   for (const auto& b : phiBuckets) {
0041     for (const auto& p : b) {
0042       m_vn[idx++] = p.second;
0043     }
0044   }
0045 }
0046 
0047 void GbtsEtaBin::initializeNodes() {
0048   if (m_vn.empty()) {
0049     return;
0050   }
0051 
0052   m_params.resize(m_vn.size());
0053 
0054   m_in.resize(m_vn.size());
0055   for (auto& v : m_in) {
0056     v.reserve(50);  // reasonably high number of incoming edges per node
0057   }
0058 
0059   std::transform(
0060       m_vn.begin(), m_vn.end(), m_params.begin(), [](const GbtsNode* pN) {
0061         std::array<float, 5> a = {-100.0, 100.0, pN->phi(), pN->r(), pN->z()};
0062         return a;
0063       });
0064 
0065   auto [min_iter, max_iter] = std::minmax_element(
0066       m_vn.begin(), m_vn.end(),
0067       [](const GbtsNode* s, const GbtsNode* s1) { return (s->r() < s1->r()); });
0068   m_maxRadius = (*max_iter)->r();
0069   m_minRadius = (*min_iter)->r();
0070 }
0071 
0072 void GbtsEtaBin::generatePhiIndexing(float dphi) {
0073   for (unsigned int nIdx = 0; nIdx < m_vn.size(); nIdx++) {
0074     float phi = m_params[nIdx][2];
0075     if (phi <= std::numbers::pi - dphi) {
0076       continue;
0077     }
0078     m_vPhiNodes.push_back(
0079         std::pair<float, unsigned int>(phi - 2 * std::numbers::pi, nIdx));
0080   }
0081 
0082   for (unsigned int nIdx = 0; nIdx < m_vn.size(); nIdx++) {
0083     float phi = m_params[nIdx][2];
0084     m_vPhiNodes.push_back(std::pair<float, unsigned int>(phi, nIdx));
0085   }
0086 
0087   for (unsigned int nIdx = 0; nIdx < m_vn.size(); nIdx++) {
0088     float phi = m_params[nIdx][2];
0089     if (phi >= -std::numbers::pi + dphi) {
0090       break;
0091     }
0092     m_vPhiNodes.push_back(
0093         std::pair<float, unsigned int>(phi + 2 * std::numbers::pi, nIdx));
0094   }
0095 }
0096 GbtsDataStorage::GbtsDataStorage(std::shared_ptr<const GbtsGeometry> geometry,
0097                                  const SeedFinderGbtsConfig& config,
0098                                  GbtsMLLookupTable mlLUT)
0099     : m_geo(std::move(geometry)), m_config(config), m_mlLUT(std::move(mlLUT)) {
0100   // parse the look up table if useML is true
0101 
0102   m_etaBins.resize(m_geo->num_bins());
0103 }
0104 
0105 int GbtsDataStorage::loadPixelGraphNodes(short layerIndex,
0106                                          std::span<const GbtsNode> coll,
0107                                          bool useML) {
0108   int nLoaded = 0;
0109 
0110   const GbtsLayer* pL = m_geo->getGbtsLayerByIndex(layerIndex);
0111 
0112   if (pL == nullptr) {
0113     return -1;
0114   }
0115 
0116   bool isBarrel = (pL->getLayer()->m_type == 0);
0117 
0118   for (const auto& node : coll) {
0119     int binIndex = pL->getEtaBin(node.z(), node.r());
0120 
0121     if (binIndex == -1) {
0122       continue;
0123     }
0124 
0125     if (isBarrel) {
0126       m_etaBins.at(binIndex).m_vn.push_back(&node);
0127     } else {
0128       if (useML) {
0129         float cluster_width = node.pixelClusterWidth();
0130         if (cluster_width > m_config.max_endcap_clusterwidth) {
0131           continue;
0132         }
0133       }
0134       m_etaBins.at(binIndex).m_vn.push_back(&node);
0135     }
0136 
0137     nLoaded++;
0138   }
0139 
0140   return nLoaded;
0141 }
0142 
0143 int GbtsDataStorage::loadStripGraphNodes(short layerIndex,
0144                                          std::span<const GbtsNode> coll) {
0145   int nLoaded = 0;
0146 
0147   const GbtsLayer* pL = m_geo->getGbtsLayerByIndex(layerIndex);
0148 
0149   if (pL == nullptr) {
0150     return -1;
0151   }
0152 
0153   for (const auto& node : coll) {
0154     int binIndex = pL->getEtaBin(node.z(), node.r());
0155 
0156     if (binIndex == -1) {
0157       continue;
0158     }
0159 
0160     m_etaBins.at(binIndex).m_vn.push_back(&node);
0161     nLoaded++;
0162   }
0163 
0164   return nLoaded;
0165 }
0166 
0167 unsigned int GbtsDataStorage::numberOfNodes() const {
0168   unsigned int n = 0;
0169 
0170   for (const auto& b : m_etaBins) {
0171     n += b.m_vn.size();
0172   }
0173   return n;
0174 }
0175 
0176 void GbtsDataStorage::sortByPhi() {
0177   for (auto& b : m_etaBins) {
0178     b.sortByPhi();
0179   }
0180 }
0181 
0182 void GbtsDataStorage::initializeNodes(bool useML) {
0183   for (auto& b : m_etaBins) {
0184     b.initializeNodes();
0185     if (!b.m_vn.empty()) {
0186       b.m_layerKey = m_geo->getGbtsLayerKeyByIndex((*b.m_vn.begin())->layer());
0187     }
0188   }
0189 
0190   if (!useML) {
0191     return;
0192   }
0193 
0194   unsigned int nL = m_geo->num_layers();
0195 
0196   for (unsigned int layerIdx = 0; layerIdx < nL; layerIdx++) {
0197     const GbtsLayer* pL = m_geo->getGbtsLayerByIndex(layerIdx);
0198 
0199     if (pL->getLayer()->m_subdet <
0200         20000) {  // skip strips volumes: layers in range [1200X-1400X]
0201       continue;
0202     }
0203 
0204     bool isBarrel = (pL->getLayer()->m_type == 0);
0205 
0206     if (!isBarrel) {
0207       continue;
0208     }
0209 
0210     // adjusting cuts on |cot(theta)| using pre-trained LUT loaded from file
0211 
0212     int lutSize = m_mlLUT.size();
0213 
0214     int nBins = pL->numOfBins();
0215 
0216     for (int b = 0; b < nBins; b++) {  // loop over eta-bins in Layer
0217 
0218       GbtsEtaBin& B = m_etaBins.at(pL->getBins().at(b));
0219 
0220       if (B.empty()) {
0221         continue;
0222       }
0223 
0224       for (unsigned int nIdx = 0; nIdx < B.m_vn.size(); nIdx++) {
0225         float cluster_width = B.m_vn[nIdx]->pixelClusterWidth();
0226         float locPosY = B.m_vn[nIdx]->localPositionY();
0227 
0228         int lutBinIdx = static_cast<int>(std::floor(20 * cluster_width)) -
0229                         1;  // lut bin width is 0.05 mm, check if this is
0230                             // actually what we want with float conversion
0231 
0232         if (lutBinIdx >= lutSize) {
0233           continue;
0234         }
0235         if (lutBinIdx < 0) {
0236           continue;  // protect against negative index
0237         }
0238 
0239         const std::array<float, 5> lutBin = m_mlLUT[lutBinIdx];
0240 
0241         float dist2border = 10.0 - std::abs(locPosY);
0242 
0243         float min_tau = -100.0;
0244         float max_tau = 100.0;
0245 
0246         if (dist2border > 0.3f) {  // far enough from the edge
0247           min_tau = lutBin[1];
0248           max_tau = lutBin[2];
0249         } else {  // possible cluster shortening at a module edge
0250           min_tau = lutBin[3];
0251           max_tau = lutBin[4];
0252         }
0253 
0254         if (max_tau < 0) {  // insufficient training data
0255           max_tau = 100.0;  // use "no-cut" default
0256         }
0257 
0258         B.m_params[nIdx][0] = min_tau;
0259         B.m_params[nIdx][1] = max_tau;
0260       }
0261     }
0262   }
0263 }
0264 
0265 void GbtsDataStorage::generatePhiIndexing(float dphi) {
0266   for (auto& b : m_etaBins) {
0267     b.generatePhiIndexing(dphi);
0268   }
0269 }
0270 
0271 }  // namespace Acts::Experimental