File indexing completed on 2025-01-18 09:11:00
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011
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;
0025 int m_type;
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) {
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 {
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;
0070
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) {
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 {
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) {
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 {
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) {
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 {
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);
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) {
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) {
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;
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
0280
0281 for (auto &[_, vConn] : m_connector->m_connMap) {
0282 for (auto &c : vConn) {
0283 unsigned int src = c->m_src;
0284 unsigned int dst = c->m_dst;
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++) {
0303 for (int b2 = 0; b2 < nSrcBins; b2++) {
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
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;
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 }