Back to home page

EIC code displayed by LXR

 
 

    


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

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