Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:23:22

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 // TODO: update to C++17 style
0010 #include "Acts/TrackFinding/GbtsConnector.hpp"
0011 
0012 #include <cstring>
0013 #include <fstream>
0014 #include <iostream>
0015 #include <list>
0016 #include <set>
0017 #include <unordered_map>
0018 
0019 namespace Acts::Experimental {
0020 
0021 GbtsConnection::GbtsConnection(unsigned int s, unsigned int d)
0022     : m_src(s), m_dst(d) {}
0023 
0024 GbtsConnector::GbtsConnector(std::ifstream& inFile, bool LRTmode) {
0025   m_connMap.clear();
0026   m_layerGroups.clear();
0027 
0028   int nLinks{};
0029 
0030   inFile >> nLinks >> m_etaBin;
0031 
0032   for (int l = 0; l < nLinks; l++) {
0033     unsigned int stage{}, lIdx{}, src{}, dst{}, nEntries{};
0034     int height{}, width{};
0035 
0036     inFile >> lIdx >> stage >> src >> dst >> height >> width >> nEntries;
0037 
0038     GbtsConnection* pC = new GbtsConnection(src, dst);
0039 
0040     int dummy{};
0041 
0042     for (int i = 0; i < height; i++) {
0043       for (int j = 0; j < width; j++) {
0044         inFile >> dummy;  // pC->m_binTable[j+i*width];
0045       }
0046     }
0047 
0048     int srcvol_id = src / 1000;
0049     int dstvol_id = dst / 1000;
0050 
0051     bool srcIsStrip = (srcvol_id == 13 || srcvol_id == 12 || srcvol_id == 14);
0052     bool dstIsStrip = (dstvol_id == 13 || dstvol_id == 12 || dstvol_id == 14);
0053     if (LRTmode) {
0054       if (!srcIsStrip || !dstIsStrip) {
0055         delete pC;
0056         continue;
0057       }
0058     } else {
0059       if (srcIsStrip || dstIsStrip) {
0060         delete pC;
0061         continue;
0062       }
0063     }
0064 
0065     std::map<int, std::vector<GbtsConnection*> >::iterator it =
0066         m_connMap.find(stage);
0067 
0068     if (it == m_connMap.end()) {
0069       std::vector<GbtsConnection*> v = {pC};
0070       m_connMap.insert(std::make_pair(stage, v));
0071     } else {
0072       (*it).second.push_back(pC);
0073     }
0074   }
0075 
0076   // re-arrange the connection stages
0077 
0078   std::list<const GbtsConnection*> lConns;
0079 
0080   std::map<int, std::vector<const GbtsConnection*> > newConnMap;
0081 
0082   for (const auto& conn : m_connMap) {
0083     std::copy(conn.second.begin(), conn.second.end(),
0084               std::back_inserter(lConns));
0085   }
0086 
0087   int stageCounter = 0;
0088 
0089   while (!lConns.empty()) {
0090     std::unordered_map<unsigned int, std::pair<int, int> >
0091         mCounter;  // layerKey, nDst, nSrc
0092 
0093     for (const auto& conn : lConns) {
0094       auto entryIt = mCounter.find(conn->m_dst);
0095       if (entryIt != mCounter.end()) {
0096         (*entryIt).second.first++;
0097       } else {
0098         int nDst = 1;
0099         int nSrc = 0;
0100         mCounter.insert(
0101             std::make_pair(conn->m_dst, std::make_pair(nDst, nSrc)));
0102       }
0103 
0104       entryIt = mCounter.find(conn->m_src);
0105       if (entryIt != mCounter.end()) {
0106         (*entryIt).second.second++;
0107       } else {
0108         int nDst = 0;
0109         int nSrc = 1;
0110         mCounter.insert(
0111             std::make_pair(conn->m_src, std::make_pair(nDst, nSrc)));
0112       }
0113     }
0114 
0115     // find layers with nSrc = 0
0116 
0117     std::set<unsigned int> zeroLayers;
0118 
0119     for (const auto& layerCounts : mCounter) {
0120       if (layerCounts.second.second != 0) {
0121         continue;
0122       }
0123 
0124       zeroLayers.insert(layerCounts.first);
0125     }
0126 
0127     // remove connections which use zeroLayer as destination
0128 
0129     std::vector<const GbtsConnection*> theStage;
0130 
0131     std::list<const GbtsConnection*>::iterator cIt = lConns.begin();
0132 
0133     while (cIt != lConns.end()) {
0134       if (zeroLayers.find((*cIt)->m_dst) !=
0135           zeroLayers.end()) {  // check if contains
0136         theStage.push_back(*cIt);
0137         cIt = lConns.erase(cIt);
0138         continue;
0139       }
0140       ++cIt;
0141     }
0142     newConnMap.insert(std::make_pair(stageCounter, theStage));
0143     stageCounter++;
0144   }
0145 
0146   // create layer groups
0147 
0148   int currentStage = 0;
0149 
0150   // the doublet making is done using "outside-in" approach hence the reverse
0151   // iterations
0152 
0153   for (std::map<int, std::vector<const GbtsConnection*> >::reverse_iterator it =
0154            newConnMap.rbegin();
0155        it != newConnMap.rend(); ++it, currentStage++) {
0156     const std::vector<const GbtsConnection*>& vConn = (*it).second;
0157 
0158     // loop over links, extract all connections for the stage, group sources by
0159     // L1 (dst) index
0160 
0161     std::map<unsigned int, std::vector<const GbtsConnection*> > l1ConnMap;
0162 
0163     for (const auto* conn : vConn) {
0164       unsigned int dst = conn->m_dst;
0165 
0166       std::map<unsigned int, std::vector<const GbtsConnection*> >::iterator
0167           l1MapIt = l1ConnMap.find(dst);
0168       if (l1MapIt != l1ConnMap.end()) {
0169         (*l1MapIt).second.push_back(conn);
0170       } else {
0171         std::vector<const GbtsConnection*> v = {conn};
0172         l1ConnMap.insert(std::make_pair(dst, v));
0173       }
0174     }
0175 
0176     std::vector<LayerGroup> lgv;
0177 
0178     lgv.reserve(l1ConnMap.size());
0179 
0180     for (const auto& l1Group : l1ConnMap) {
0181       lgv.push_back(LayerGroup(l1Group.first, l1Group.second));
0182     }
0183 
0184     m_layerGroups.insert(std::make_pair(currentStage, lgv));
0185   }
0186 
0187   newConnMap.clear();
0188 }
0189 
0190 GbtsConnector::~GbtsConnector() {
0191   m_layerGroups.clear();
0192 
0193   for (auto& conn : m_connMap) {
0194     for (auto& link : conn.second) {
0195       delete link;
0196     }
0197     conn.second.clear();
0198   }
0199 
0200   m_connMap.clear();
0201 }
0202 
0203 }  // namespace Acts::Experimental