Back to home page

sPhenix code displayed by LXR

 
 

    


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

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/GbtsGeometry.hpp"
0010 
0011 #include <cmath>
0012 #include <cstring>
0013 #include <iostream>
0014 
0015 namespace Acts::Experimental {
0016 
0017 GbtsLayer::GbtsLayer(const TrigInDetSiLayer& ls, float ew, std::int32_t bin0)
0018     : m_layer(&ls), m_etaBinWidth(ew) {
0019   if (m_layer->m_type == 0) {  // barrel
0020     m_r1 = m_layer->m_refCoord;
0021     m_r2 = m_layer->m_refCoord;
0022     m_z1 = m_layer->m_minBound;
0023     m_z2 = m_layer->m_maxBound;
0024   } else {  // endcap
0025     m_r1 = m_layer->m_minBound;
0026     m_r2 = m_layer->m_maxBound;
0027     m_z1 = m_layer->m_refCoord;
0028     m_z2 = m_layer->m_refCoord;
0029   }
0030 
0031   float t1 = m_z1 / m_r1;
0032   float eta1 = -std::log(std::sqrt(1 + t1 * t1) - t1);
0033 
0034   float t2 = m_z2 / m_r2;
0035   float eta2 = -std::log(std::sqrt(1 + t2 * t2) - t2);
0036 
0037   m_minEta = eta1;
0038   m_maxEta = eta2;
0039 
0040   if (m_maxEta < m_minEta) {
0041     m_minEta = eta2;
0042     m_maxEta = eta1;
0043   }
0044 
0045   m_maxEta += 1e-6;  // increasing them slightly to avoid range_check exceptions
0046   m_minEta -= 1e-6;
0047 
0048   float deltaEta = m_maxEta - m_minEta;
0049 
0050   int binCounter = bin0;
0051 
0052   if (deltaEta < m_etaBinWidth) {
0053     m_nBins = 1;
0054     m_bins.push_back(binCounter++);
0055     m_etaBin = deltaEta;
0056     if (m_layer->m_type == 0) {  // barrel
0057       m_minRadius.push_back(m_layer->m_refCoord - 2.0);
0058       m_maxRadius.push_back(m_layer->m_refCoord + 2.0);
0059       m_minBinCoord.push_back(m_layer->m_minBound);
0060       m_maxBinCoord.push_back(m_layer->m_maxBound);
0061     } else {  // endcap
0062       m_minRadius.push_back(m_layer->m_minBound - 2.0);
0063       m_maxRadius.push_back(m_layer->m_maxBound + 2.0);
0064       m_minBinCoord.push_back(m_layer->m_minBound);
0065       m_maxBinCoord.push_back(m_layer->m_maxBound);
0066     }
0067   } else {
0068     int nB = static_cast<int>(deltaEta / m_etaBinWidth);
0069     m_nBins = nB;
0070     if (deltaEta - m_etaBinWidth * nB > 0.5 * m_etaBinWidth) {
0071       m_nBins++;
0072     }
0073 
0074     m_etaBin = deltaEta / m_nBins;
0075 
0076     if (m_nBins == 1) {
0077       m_bins.push_back(binCounter++);
0078       if (m_layer->m_type == 0) {  // barrel
0079         m_minRadius.push_back(m_layer->m_refCoord - 2.0);
0080         m_maxRadius.push_back(m_layer->m_refCoord + 2.0);
0081         m_minBinCoord.push_back(m_layer->m_minBound);
0082         m_maxBinCoord.push_back(m_layer->m_maxBound);
0083       } else {  // endcap
0084         m_minRadius.push_back(m_layer->m_minBound - 2.0);
0085         m_maxRadius.push_back(m_layer->m_maxBound + 2.0);
0086         m_minBinCoord.push_back(m_layer->m_minBound);
0087         m_maxBinCoord.push_back(m_layer->m_maxBound);
0088       }
0089     } else {
0090       float eta = m_minEta + 0.5 * m_etaBin;
0091 
0092       for (int i = 1; i <= m_nBins; i++) {
0093         m_bins.push_back(binCounter++);
0094 
0095         float e1 = eta - 0.5 * m_etaBin;
0096         float e2 = eta + 0.5 * m_etaBin;
0097 
0098         if (m_layer->m_type == 0) {  // barrel
0099           m_minRadius.push_back(m_layer->m_refCoord - 2.0);
0100           m_maxRadius.push_back(m_layer->m_refCoord + 2.0);
0101           float z1 = m_layer->m_refCoord * std::sinh(e1);
0102           m_minBinCoord.push_back(z1);
0103           float z2 = m_layer->m_refCoord * std::sinh(e2);
0104           m_maxBinCoord.push_back(z2);
0105         } else {  // endcap
0106 
0107           // for the positive endcap larger eta corresponds to smaller radius
0108           if (m_layer->m_refCoord > 0) {
0109             std::swap(e1, e2);
0110           }
0111           float r = m_layer->m_refCoord / std::sinh(e1);
0112           m_minBinCoord.push_back(r);
0113           m_minRadius.push_back(r - 2.0);
0114           r = m_layer->m_refCoord / std::sinh(e2);
0115           m_maxBinCoord.push_back(r);
0116           m_maxRadius.push_back(r + 2.0);
0117         }
0118 
0119         eta += m_etaBin;
0120       }
0121     }
0122   }
0123 }
0124 
0125 bool GbtsLayer::verifyBin(const GbtsLayer* pL, int b1, int b2, float min_z0,
0126                           float max_z0) const {
0127   float z1min = m_minBinCoord.at(b1);
0128   float z1max = m_maxBinCoord.at(b1);
0129   float r1 = m_layer->m_refCoord;
0130 
0131   if (m_layer->m_type == 0 && pL->m_layer->m_type == 0) {  // barrel <- barrel
0132 
0133     const float tol = 5.0;
0134 
0135     float min_b2 = pL->m_minBinCoord.at(b2);
0136     float max_b2 = pL->m_maxBinCoord.at(b2);
0137 
0138     float r2 = pL->m_layer->m_refCoord;
0139 
0140     float A = r2 / (r2 - r1);
0141     float B = r1 / (r2 - r1);
0142 
0143     float z0_min = z1min * A - max_b2 * B;
0144     float z0_max = z1max * A - min_b2 * B;
0145 
0146     if (z0_max < min_z0 - tol || z0_min > max_z0 + tol) {
0147       return false;
0148     }
0149 
0150     return true;
0151   }
0152 
0153   if (m_layer->m_type == 0 && pL->m_layer->m_type != 0) {  // barrel <- endcap
0154 
0155     float z2 = pL->m_layer->m_refCoord;
0156     float r2max = pL->m_maxBinCoord.at(b2);
0157     float r2min = pL->m_minBinCoord.at(b2);
0158 
0159     if (r2max <= r1) {
0160       return false;
0161     }
0162 
0163     if (r2min <= r1) {
0164       r2min = r1 + 1e-3;
0165     }
0166 
0167     float z0_max = 0.0;
0168     float z0_min = 0.0;
0169 
0170     if (z2 > 0) {
0171       z0_max = (z1max * r2max - z2 * r1) / (r2max - r1);
0172       z0_min = (z1min * r2min - z2 * r1) / (r2min - r1);
0173     } else {
0174       z0_max = (z1max * r2min - z2 * r1) / (r2min - r1);
0175       z0_min = (z1min * r2max - z2 * r1) / (r2max - r1);
0176     }
0177 
0178     if (z0_max < min_z0 || z0_min > max_z0) {
0179       return false;
0180     }
0181     return true;
0182   }
0183 
0184   return true;
0185 }
0186 
0187 int GbtsLayer::getEtaBin(float zh, float rh) const {
0188   if (m_bins.size() == 1) {
0189     return m_bins.at(0);
0190   }
0191 
0192   float t1 = zh / rh;
0193   float eta = -std::log(std::sqrt(1 + t1 * t1) - t1);
0194 
0195   int idx = static_cast<int>((eta - m_minEta) / m_etaBin);
0196 
0197   if (idx < 0) {
0198     idx = 0;
0199   }
0200   if (idx >= static_cast<int>(m_bins.size())) {
0201     idx = static_cast<int>(m_bins.size()) - 1;
0202   }
0203 
0204   return m_bins.at(idx);  // index in the global storage
0205 }
0206 
0207 float GbtsLayer::getMinBinRadius(int idx) const {
0208   if (idx >= static_cast<int>(m_minRadius.size())) {
0209     idx = idx - 1;
0210   }
0211   if (idx < 0) {
0212     idx = 0;
0213   }
0214 
0215   return m_minRadius.at(idx);
0216 }
0217 
0218 float GbtsLayer::getMaxBinRadius(int idx) const {
0219   if (idx >= static_cast<int>(m_maxRadius.size())) {
0220     idx = idx - 1;
0221   }
0222   if (idx < 0) {
0223     idx = 0;
0224   }
0225 
0226   return m_maxRadius.at(idx);
0227 }
0228 
0229 GbtsGeometry::GbtsGeometry(const std::vector<TrigInDetSiLayer>& layers,
0230                            const std::unique_ptr<GbtsConnector>& conn) {
0231   const float min_z0 = -168.0;
0232   const float max_z0 = 168.0;
0233 
0234   m_etaBinWidth = conn->m_etaBin;
0235 
0236   for (const auto& layer : layers) {
0237     const GbtsLayer* pL = addNewLayer(layer, m_nEtaBins);
0238     m_nEtaBins += pL->numOfBins();
0239   }
0240 
0241   // calculating bin tables in the connector...
0242   // calculate bin pairs for graph edge building
0243 
0244   int lastBin1 = -1;
0245 
0246   for (std::map<int, std::vector<GbtsConnection*> >::const_iterator it =
0247            conn->m_connMap.begin();
0248        it != conn->m_connMap.end(); ++it) {
0249     const std::vector<GbtsConnection*>& vConn = (*it).second;
0250 
0251     for (std::vector<GbtsConnection*>::const_iterator cIt = vConn.begin();
0252          cIt != vConn.end(); ++cIt) {
0253       unsigned int src = (*cIt)->m_src;  // n2 : the new connectors
0254       unsigned int dst = (*cIt)->m_dst;  // n1
0255 
0256       const GbtsLayer* pL1 = getGbtsLayerByKey(dst);
0257       const GbtsLayer* pL2 = getGbtsLayerByKey(src);
0258 
0259       if (pL1 == nullptr) {
0260         std::cout << " skipping invalid dst layer " << dst << std::endl;
0261         continue;
0262       }
0263       if (pL2 == nullptr) {
0264         std::cout << " skipping invalid src layer " << src << std::endl;
0265         continue;
0266       }
0267       int nSrcBins = pL2->numOfBins();
0268       int nDstBins = pL1->numOfBins();
0269 
0270       (*cIt)->m_binTable.resize(nSrcBins * nDstBins, 0);
0271 
0272       for (int b1 = 0; b1 < nDstBins; b1++) {    // loop over bins in Layer 1
0273         for (int b2 = 0; b2 < nSrcBins; b2++) {  // loop over bins in Layer 2
0274           if (!pL1->verifyBin(pL2, b1, b2, min_z0, max_z0)) {
0275             continue;
0276           }
0277           int address = b1 + b2 * nDstBins;
0278           (*cIt)->m_binTable.at(address) = 1;
0279 
0280           int bin1_idx = pL1->getBins().at(b1);
0281           int bin2_idx = pL2->getBins().at(b2);
0282 
0283           if (bin1_idx != lastBin1) {  // adding a new group
0284 
0285             std::vector<int> v2(1, bin2_idx);
0286             m_binGroups.push_back(std::make_pair(bin1_idx, v2));
0287             lastBin1 = bin1_idx;
0288 
0289           } else {  // extend the last group
0290             (*m_binGroups.rbegin()).second.push_back(bin2_idx);
0291           }
0292         }
0293       }
0294     }
0295   }
0296 }
0297 
0298 const GbtsLayer* GbtsGeometry::getGbtsLayerByKey(unsigned int key) const {
0299   std::map<unsigned int, GbtsLayer*>::const_iterator it = m_layMap.find(key);
0300   if (it == m_layMap.end()) {
0301     return nullptr;
0302   }
0303   return (*it).second;
0304 }
0305 
0306 const GbtsLayer* GbtsGeometry::getGbtsLayerByIndex(int idx) const {
0307   return m_layArray.at(idx).get();
0308 }
0309 
0310 const GbtsLayer* GbtsGeometry::addNewLayer(const TrigInDetSiLayer& l,
0311                                            int bin0) {
0312   unsigned int layerKey = l.m_subdet;
0313 
0314   float ew = m_etaBinWidth;
0315 
0316   std::unique_ptr<GbtsLayer> pHL = std::make_unique<GbtsLayer>(l, ew, bin0);
0317   GbtsLayer* ref = pHL.get();
0318 
0319   m_layMap.insert(std::pair<unsigned int, GbtsLayer*>(layerKey, ref));
0320   m_layArray.push_back(std::move(pHL));
0321   m_layerKeys.push_back(layerKey);
0322   return ref;
0323 }
0324 
0325 }  // namespace Acts::Experimental