File indexing completed on 2026-03-28 07:45:42
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Seeding2/GbtsGeometry.hpp"
0010
0011 #include "Acts/Utilities/MathHelpers.hpp"
0012
0013 #include <algorithm>
0014 #include <cmath>
0015 #include <cstring>
0016 #include <iostream>
0017
0018 namespace Acts::Experimental {
0019
0020 GbtsLayer::GbtsLayer(const GbtsLayerDescription& layerDescription,
0021 const float etaBinWidth, const std::int32_t bin0)
0022 : m_layerDescription(layerDescription) {
0023 if (m_layerDescription.type == GbtsLayerType::Barrel) {
0024 m_r1 = m_layerDescription.refCoord;
0025 m_r2 = m_layerDescription.refCoord;
0026 m_z1 = m_layerDescription.minBound;
0027 m_z2 = m_layerDescription.maxBound;
0028 } else if (m_layerDescription.type == GbtsLayerType::Endcap) {
0029 m_r1 = m_layerDescription.minBound;
0030 m_r2 = m_layerDescription.maxBound;
0031 m_z1 = m_layerDescription.refCoord;
0032 m_z2 = m_layerDescription.refCoord;
0033 } else {
0034 throw std::runtime_error("invalid layer type");
0035 }
0036
0037 const float t1 = m_z1 / m_r1;
0038 const float eta1 = -std::log(fastHypot(1, t1) - t1);
0039
0040 const float t2 = m_z2 / m_r2;
0041 const float eta2 = -std::log(fastHypot(1, t2) - t2);
0042
0043 m_minEta = eta1;
0044 m_maxEta = eta2;
0045
0046 if (m_maxEta < m_minEta) {
0047 m_minEta = eta2;
0048 m_maxEta = eta1;
0049 }
0050
0051
0052 m_maxEta += 1e-6;
0053 m_minEta -= 1e-6;
0054
0055 const float deltaEta = m_maxEta - m_minEta;
0056
0057 std::uint32_t binCounter = bin0;
0058
0059 if (deltaEta < etaBinWidth) {
0060 m_nBins = 1;
0061 m_bins.push_back(binCounter++);
0062 m_etaBin = deltaEta;
0063 if (m_layerDescription.type == GbtsLayerType::Barrel) {
0064 m_minRadius.push_back(m_layerDescription.refCoord - 2.0f);
0065 m_maxRadius.push_back(m_layerDescription.refCoord + 2.0f);
0066 m_minBinCoord.push_back(m_layerDescription.minBound);
0067 m_maxBinCoord.push_back(m_layerDescription.maxBound);
0068 } else if (m_layerDescription.type == GbtsLayerType::Endcap) {
0069 m_minRadius.push_back(m_layerDescription.minBound - 2.0f);
0070 m_maxRadius.push_back(m_layerDescription.maxBound + 2.0f);
0071 m_minBinCoord.push_back(m_layerDescription.minBound);
0072 m_maxBinCoord.push_back(m_layerDescription.maxBound);
0073 } else {
0074 throw std::runtime_error("invalid layer type");
0075 }
0076 } else {
0077 const auto nB = static_cast<std::uint32_t>(deltaEta / etaBinWidth);
0078 m_nBins = nB;
0079 if (deltaEta - etaBinWidth * nB > 0.5f * etaBinWidth) {
0080 m_nBins++;
0081 }
0082
0083 m_etaBin = deltaEta / m_nBins;
0084
0085 if (m_nBins == 1) {
0086 m_bins.push_back(binCounter++);
0087 if (m_layerDescription.type == GbtsLayerType::Barrel) {
0088 m_minRadius.push_back(m_layerDescription.refCoord - 2.0f);
0089 m_maxRadius.push_back(m_layerDescription.refCoord + 2.0f);
0090 m_minBinCoord.push_back(m_layerDescription.minBound);
0091 m_maxBinCoord.push_back(m_layerDescription.maxBound);
0092 } else if (m_layerDescription.type == GbtsLayerType::Endcap) {
0093 m_minRadius.push_back(m_layerDescription.minBound - 2.0f);
0094 m_maxRadius.push_back(m_layerDescription.maxBound + 2.0f);
0095 m_minBinCoord.push_back(m_layerDescription.minBound);
0096 m_maxBinCoord.push_back(m_layerDescription.maxBound);
0097 } else {
0098 throw std::runtime_error("invalid layer type");
0099 }
0100 } else {
0101 float eta = m_minEta + 0.5f * m_etaBin;
0102
0103 for (std::uint32_t i = 1; i <= m_nBins; ++i) {
0104 m_bins.push_back(binCounter++);
0105
0106 float e1 = eta - 0.5f * m_etaBin;
0107 float e2 = eta + 0.5f * m_etaBin;
0108
0109 if (m_layerDescription.type == GbtsLayerType::Barrel) {
0110 m_minRadius.push_back(m_layerDescription.refCoord - 2.0f);
0111 m_maxRadius.push_back(m_layerDescription.refCoord + 2.0f);
0112 const float z1 = m_layerDescription.refCoord * std::sinh(e1);
0113 m_minBinCoord.push_back(z1);
0114 const float z2 = m_layerDescription.refCoord * std::sinh(e2);
0115 m_maxBinCoord.push_back(z2);
0116 } else if (m_layerDescription.type == GbtsLayerType::Endcap) {
0117
0118 if (m_layerDescription.refCoord > 0) {
0119 std::swap(e1, e2);
0120 }
0121 float r = m_layerDescription.refCoord / std::sinh(e1);
0122 m_minBinCoord.push_back(r);
0123 m_minRadius.push_back(r - 2.0f);
0124 r = m_layerDescription.refCoord / std::sinh(e2);
0125 m_maxBinCoord.push_back(r);
0126 m_maxRadius.push_back(r + 2.0f);
0127 } else {
0128 throw std::runtime_error("invalid layer type");
0129 }
0130
0131 eta += m_etaBin;
0132 }
0133 }
0134 }
0135 }
0136
0137 bool GbtsLayer::checkCompatibility(const GbtsLayer& otherLayer,
0138 const std::uint32_t b1,
0139 const std::uint32_t b2, const float minZ0,
0140 const float maxZ0) const {
0141 const float z1min = m_minBinCoord.at(b1);
0142 const float z1max = m_maxBinCoord.at(b1);
0143 const float r1 = m_layerDescription.refCoord;
0144
0145 const float tol = 5.0f;
0146
0147 if (m_layerDescription.type == GbtsLayerType::Barrel &&
0148 otherLayer.m_layerDescription.type == GbtsLayerType::Barrel) {
0149 const float minB2 = otherLayer.m_minBinCoord.at(b2);
0150 const float maxB2 = otherLayer.m_maxBinCoord.at(b2);
0151
0152 const float r2 = otherLayer.m_layerDescription.refCoord;
0153
0154 const float A = r2 / (r2 - r1);
0155 const float B = r1 / (r2 - r1);
0156
0157 const float z0Min = z1min * A - maxB2 * B;
0158 const float z0Max = z1max * A - minB2 * B;
0159
0160 if (z0Max < minZ0 - tol || z0Min > maxZ0 + tol) {
0161 return false;
0162 }
0163
0164 return true;
0165 }
0166
0167 if (m_layerDescription.type == GbtsLayerType::Barrel &&
0168 otherLayer.m_layerDescription.type == GbtsLayerType::Endcap) {
0169 const float z2 = otherLayer.m_layerDescription.refCoord;
0170 const float r2max = otherLayer.m_maxBinCoord.at(b2);
0171 float r2min = otherLayer.m_minBinCoord.at(b2);
0172
0173 if (r2max <= r1) {
0174 return false;
0175 }
0176
0177 if (r2min <= r1) {
0178 r2min = r1 + 1e-3f;
0179 }
0180
0181 float z0Max = 0;
0182 float z0Min = 0;
0183
0184 if (z2 > 0) {
0185 z0Max = (z1max * r2max - z2 * r1) / (r2max - r1);
0186 z0Min = (z1min * r2min - z2 * r1) / (r2min - r1);
0187 } else {
0188 z0Max = (z1max * r2min - z2 * r1) / (r2min - r1);
0189 z0Min = (z1min * r2max - z2 * r1) / (r2max - r1);
0190 }
0191
0192 if (z0Max < minZ0 - tol || z0Min > maxZ0 + tol) {
0193 return false;
0194 }
0195 return true;
0196 }
0197
0198 if (m_layerDescription.type == GbtsLayerType::Endcap &&
0199 otherLayer.m_layerDescription.type == GbtsLayerType::Endcap) {
0200 const float z2 = otherLayer.m_layerDescription.refCoord;
0201 const float z1 = m_layerDescription.refCoord;
0202 const float r2max = otherLayer.m_maxBinCoord.at(b2);
0203 const float r2min = otherLayer.m_minBinCoord.at(b2);
0204 const float r1max = m_maxBinCoord.at(b1);
0205 const float r1min = m_minBinCoord.at(b1);
0206
0207 if (r1min >= r2max) {
0208 return false;
0209 }
0210
0211 if (z2 > 0) {
0212
0213 const float z0Max = z1 - r1min * (z2 - z1) / (r2max - r1min);
0214
0215 if (z0Max < minZ0 - tol) {
0216 return false;
0217 }
0218
0219 if (r2min > r1max) {
0220 const float z0Min = z1 - r1max * (z2 - z1) / (r2min - r1max);
0221
0222 if (z0Min > maxZ0 + tol) {
0223 return false;
0224 }
0225 }
0226 } else {
0227 const float z0Min = z1 - r1min * (z2 - z1) / (r2max - r1min);
0228
0229 if (z0Min > maxZ0 + tol) {
0230 return false;
0231 }
0232
0233 if (r2min > r1max) {
0234 const float z0Max = z1 - r1max * (z2 - z1) / (r2min - r1max);
0235
0236 if (z0Max < minZ0 - tol) {
0237 return false;
0238 }
0239 }
0240 }
0241 return true;
0242 }
0243
0244 if (m_layerDescription.type == GbtsLayerType::Endcap &&
0245 otherLayer.m_layerDescription.type == GbtsLayerType::Barrel) {
0246 const float z1 = m_layerDescription.refCoord;
0247 const float r1max = m_maxBinCoord.at(b1);
0248 const float r1min = m_minBinCoord.at(b1);
0249
0250 const float z2min = otherLayer.m_minBinCoord.at(b2);
0251 const float z2max = otherLayer.m_maxBinCoord.at(b2);
0252 const float r2 = otherLayer.m_layerDescription.refCoord;
0253
0254 if (r2 < r1min) {
0255 return false;
0256 }
0257
0258
0259
0260 float z0Min = z1 - (z2max - z1) / (r2 / r1max - 1);
0261 float z0Max = z1 - (z2max - z1) / (r2 / r1min - 1);
0262
0263 if (z0Min > z0Max) {
0264 std::swap(z0Min, z0Max);
0265 }
0266
0267 bool beyondRange = (z0Max < minZ0 - tol || z0Min > maxZ0 + tol);
0268
0269 if (!beyondRange) {
0270 return true;
0271 }
0272
0273
0274
0275 z0Min = z1 - (z2min - z1) / (r2 / r1max - 1);
0276 z0Max = z1 - (z2min - z1) / (r2 / r1min - 1);
0277
0278 if (z0Min > z0Max) {
0279 std::swap(z0Min, z0Max);
0280 }
0281
0282 beyondRange = (z0Max < minZ0 - tol || z0Min > maxZ0 + tol);
0283
0284 if (!beyondRange) {
0285 return true;
0286 }
0287
0288 return false;
0289 }
0290
0291 return true;
0292 }
0293
0294 std::int32_t GbtsLayer::getEtaBin(const float zh, const float rh) const {
0295 if (m_bins.size() == 1) {
0296 return m_bins.at(0);
0297 }
0298
0299 const float t1 = zh / rh;
0300 const float eta = -std::log(fastHypot(1, t1) - t1);
0301
0302 std::int32_t idx = static_cast<std::int32_t>((eta - m_minEta) / m_etaBin);
0303 if (idx < 0) {
0304 idx = 0;
0305 } else if (idx >= static_cast<std::int32_t>(m_bins.size())) {
0306 idx = static_cast<std::int32_t>(m_bins.size()) - 1;
0307 }
0308
0309
0310 return m_bins.at(idx);
0311 }
0312
0313 GbtsGeometry::GbtsGeometry(
0314 const std::vector<GbtsLayerDescription>& layerDescriptions,
0315 const GbtsLayerConnectionMap& layerConnections)
0316 : m_etaBinWidth(layerConnections.etaBinWidth) {
0317
0318 const float minZ0 = -168.0f;
0319 const float maxZ0 = 168.0f;
0320
0321 for (const GbtsLayerDescription& layer : layerDescriptions) {
0322 const GbtsLayer& pL = createLayer(layer, m_nEtaBins);
0323 m_nEtaBins += pL.numOfBins();
0324 }
0325
0326
0327
0328
0329 std::int32_t lastBin1 = -1;
0330
0331 for (const auto& [layer, vConn] : layerConnections.connectionMap) {
0332 for (const auto& connection : vConn) {
0333 const std::uint32_t src = connection->src;
0334 const std::uint32_t dst = connection->dst;
0335
0336 const GbtsLayer* pL1 = layerById(dst);
0337 const GbtsLayer* pL2 = layerById(src);
0338 if (pL1 == nullptr) {
0339 std::cout << " skipping invalid dst layer " << dst << std::endl;
0340 continue;
0341 }
0342 if (pL2 == nullptr) {
0343 std::cout << " skipping invalid src layer " << src << std::endl;
0344 continue;
0345 }
0346
0347 const std::uint32_t nSrcBins = pL2->numOfBins();
0348 const std::uint32_t nDstBins = pL1->numOfBins();
0349
0350 connection->binTable.resize(nSrcBins * nDstBins, 0);
0351
0352 for (std::uint32_t b1 = 0; b1 < nDstBins; ++b1) {
0353
0354 for (std::uint32_t b2 = 0; b2 < nSrcBins; ++b2) {
0355 if (!pL1->checkCompatibility(*pL2, b1, b2, minZ0, maxZ0)) {
0356 continue;
0357 }
0358 const std::uint32_t address = b1 + b2 * nDstBins;
0359 connection->binTable.at(address) = 1;
0360
0361 const std::int32_t bin1Idx = pL1->bins().at(b1);
0362 const std::int32_t bin2Idx = pL2->bins().at(b2);
0363
0364 if (bin1Idx != lastBin1) {
0365
0366 m_binGroups.emplace_back(bin1Idx,
0367 std::vector<std::uint32_t>(1, bin2Idx));
0368 lastBin1 = bin1Idx;
0369 } else {
0370
0371 m_binGroups.back().second.push_back(bin2Idx);
0372 }
0373 }
0374 }
0375 }
0376 }
0377
0378
0379 BinConnections binMap;
0380
0381
0382
0383
0384
0385 for (const auto& [bin1, bin2s] : m_binGroups) {
0386
0387
0388 auto& bin1Links = binMap[bin1];
0389
0390 for (const auto& bin2 : bin2s) {
0391 auto& bin2Links = binMap[bin2];
0392
0393 bin1Links.second.push_back(bin2);
0394 bin2Links.first.push_back(bin1);
0395 }
0396 }
0397
0398
0399 const BinConnections originalBinMap = binMap;
0400
0401
0402
0403
0404
0405 std::vector<std::uint32_t> stageData;
0406
0407 std::vector<std::size_t> stageOffsets;
0408
0409 stageOffsets.reserve(51);
0410 stageOffsets.push_back(0);
0411
0412 std::vector<std::uint32_t> exitBins;
0413 while (!binMap.empty()) {
0414 exitBins.clear();
0415
0416
0417
0418 for (const auto& bl : binMap) {
0419 auto& binLinks = bl.second;
0420 auto& outLinks = binLinks.first;
0421
0422 if (!outLinks.empty()) {
0423 continue;
0424 }
0425
0426 exitBins.push_back(bl.first);
0427 }
0428
0429
0430 std::sort(exitBins.begin(), exitBins.end());
0431
0432
0433
0434 stageData.insert(stageData.end(), exitBins.begin(), exitBins.end());
0435 stageOffsets.push_back(stageData.size());
0436
0437
0438
0439 for (const std::uint32_t& bin1Key : exitBins) {
0440 auto p1 = binMap.find(bin1Key);
0441 if (p1 == binMap.end()) {
0442 continue;
0443 }
0444 auto& bin1Links = p1->second;
0445
0446 for (const std::uint32_t bin2Key : bin1Links.second) {
0447 const auto p2 = binMap.find(bin2Key);
0448 if (p2 == binMap.end()) {
0449 continue;
0450 }
0451
0452 auto& binLinks = p2->second;
0453 std::vector<std::uint32_t>& links = binLinks.first;
0454
0455 std::erase(links, bin1Key);
0456 }
0457 }
0458
0459
0460
0461 for (auto bin1Key : exitBins) {
0462 binMap.erase(bin1Key);
0463 }
0464 }
0465
0466
0467
0468 m_binGroups.clear();
0469
0470
0471 const std::size_t nStages = stageOffsets.size() - 1;
0472
0473
0474 for (std::size_t stageIndex = nStages; stageIndex-- > 0;) {
0475 const std::size_t begin = stageOffsets[stageIndex];
0476 const std::size_t end = stageOffsets[stageIndex + 1];
0477
0478 for (std::size_t k = begin; k < end; ++k) {
0479 const std::uint32_t bin1Idx = stageData[k];
0480
0481 const auto p = originalBinMap.find(bin1Idx);
0482 if (p == originalBinMap.end()) {
0483 continue;
0484 }
0485
0486 const auto& binLists = p->second;
0487 const std::vector<std::uint32_t>& bin2List = binLists.second;
0488
0489
0490 m_binGroups.emplace_back(bin1Idx, std::vector<std::uint32_t>(bin2List));
0491 }
0492 }
0493 }
0494
0495 const GbtsLayer* GbtsGeometry::layerById(std::uint32_t id) const {
0496 if (const auto it = m_layerFromUserIdMap.find(id);
0497 it != m_layerFromUserIdMap.end()) {
0498 return &m_layers.at(it->second);
0499 }
0500 return nullptr;
0501 }
0502
0503 const GbtsLayer& GbtsGeometry::layerByIndex(std::int32_t idx) const {
0504 return m_layers.at(idx);
0505 }
0506
0507 const GbtsLayer& GbtsGeometry::createLayer(
0508 const GbtsLayerDescription& layerDescription, std::uint32_t bin0) {
0509 const std::uint32_t layerIndex = m_layers.size();
0510 GbtsLayer& ref = m_layers.emplace_back(layerDescription, m_etaBinWidth, bin0);
0511 m_layerFromUserIdMap.try_emplace(layerDescription.id, layerIndex);
0512 return ref;
0513 }
0514
0515 }