81 float shift_x = vertex.x() - beamSpotHandle->beamTilt(0)*vertex.z();
82 float shift_y = vertex.y() - beamSpotHandle->beamTilt(1)*vertex.z();
91 std::map<short, std::vector<IdentifierHash> > detIdMap;
103 sctSpacePointsContainer = sctHandle.
ptr();
105 std::vector<IdentifierHash> listOfSctIds;
106 m_regsel_sct->lookup(ctx)->HashIDList( internalRoI, listOfSctIds );
110 for(
const auto& hashId : listOfSctIds) {
112 short layerIndex = h2l->at(
static_cast<int>(hashId));
114 auto it = detIdMap.find(layerIndex);
115 if(it != detIdMap.end()) (*it).second.push_back(hashId);
117 std::vector<IdentifierHash> v = {hashId};
118 detIdMap.insert(std::make_pair(layerIndex,v));
132 pixelSpacePointsContainer = pixHandle.
ptr();
134 std::vector<IdentifierHash> listOfPixIds;
136 m_regsel_pix->lookup(ctx)->HashIDList( internalRoI, listOfPixIds );
140 for(
const auto& hashId : listOfPixIds) {
142 short layerIndex = h2l->at(
static_cast<int>(hashId));
144 auto it = detIdMap.find(layerIndex);
145 if(it != detIdMap.end()) (*it).second.push_back(hashId);
147 std::vector<IdentifierHash> v = {hashId};
148 detIdMap.insert(std::make_pair(layerIndex,v));
155 std::unique_ptr<GNN_DataStorage> storage = std::make_unique<GNN_DataStorage>(*
m_geo,
m_mlLUT);
157 std::vector<const Trk::SpacePoint*> vSP;
161 std::vector<std::vector<GNN_Node> > trigSpStorage[2];
167 for(
const auto& lColl : detIdMap) {
169 short layerIndex = lColl.first;
171 int layerKey =
m_geo->getTrigFTF_GNN_LayerByIndex(layerIndex)->m_layer.m_subdet;
173 bool isPixel = layerKey > 20000;
175 auto pCont = isPixel ? pixelSpacePointsContainer : sctSpacePointsContainer;
177 int contIdx= isPixel ? 0 : 1;
181 for(
const auto& idx : lColl.second) {
183 std::vector<GNN_Node>& tmpColl = trigSpStorage[contIdx].at(
static_cast<int>(idx));
185 auto input_coll = pCont->indexFindPtr(idx);
187 if(input_coll ==
nullptr)
continue;
191 nNewNodes += (isPixel) ? storage->loadPixelGraphNodes(layerIndex, tmpColl,
m_useML) : storage->loadStripGraphNodes(layerIndex, tmpColl);
194 if(isPixel) nPixels += nNewNodes;
195 else nStrips += nNewNodes;
201 storage->sortByPhi();
202 storage->initializeNodes(
m_useML);
205 std::vector<GNN_Edge> edgeStorage;
207 std::pair<int, int> graphStats =
buildTheGraph(internalRoI, storage, edgeStorage);
209 ATH_MSG_DEBUG(
"Created graph with "<<graphStats.first<<
" edges and "<<graphStats.second<<
" edge links");
214 if (graphStats.second == 0)
return seedStats;
216 int maxLevel =
runCCA(graphStats.first, edgeStorage);
218 ATH_MSG_DEBUG(
"Reached Level "<<maxLevel<<
" after GNN iterations");
220 std::vector<std::pair<float, std::vector<unsigned int> > > vSeedCandidates;
224 if (vSeedCandidates.empty())
return seedStats;
226 for(
const auto& seed : vSeedCandidates) {
228 unsigned int lastIdx = output.size();
229 output.emplace_back(seed.first);
231 for(
const auto& sp_idx : seed.second) {
232 output[lastIdx].addSpacePoint(vSP[sp_idx]);
241 std::vector<const Trk::SpacePoint*> vSP;
242 std::vector<short> vL;
247 std::unique_ptr<TrigAccel::DATA_EXPORT_BUFFER> dataBuffer = std::unique_ptr<TrigAccel::DATA_EXPORT_BUFFER>(
new TrigAccel::DATA_EXPORT_BUFFER(5000));
250 const size_t bufferOffset = 256;
251 size_t totalSize = bufferOffset+dataTypeSize;
256 unsigned int spIdx = 0;
262 for(
const auto& lColl : detIdMap) {
264 short layerIndex = lColl.first;
270 bool isPixel = layerKey > 20000;
273 auto pCont = isPixel ? pixelSpacePointsContainer : sctSpacePointsContainer;
284 nEtaBins += pL->
m_bins.size();
286 for(
auto b : pL->
m_bins) {
287 if(b > MaxEtaBin) MaxEtaBin = b;
290 for(
const auto& idx : lColl.second) {
292 auto input_coll = pCont->indexFindPtr(idx);
294 if(input_coll ==
nullptr)
continue;
296 for(
const auto sp : *input_coll) {
304 if(cw > 0.2)
continue;
309 vSP.emplace_back(
sp);
310 vL.emplace_back(layerIndex);
312 const auto& p =
sp->globalPosition();
314 float params[4] = {(float)(p.x() - shift_x), float(p.y() - shift_y), (float)(p.z()), cw};
316 memcpy(&pJobData->
m_params[sp_offset], ¶ms[0],
sizeof(params));
327 if (isPixel) nPixels += spIdx - pJobData->
m_layerInfo[4*nLayers];
328 else nStrips += spIdx - pJobData->
m_layerInfo[4*nLayers];
333 if(spIdx == 0)
return seedStats;
339 pJobData->
m_nMaxEdges =
static_cast<unsigned int>(7*spIdx);
345 for(
const auto& bg :
m_geo->bin_groups()) {
347 int bin1_idx = bg.first;
349 for(
const auto& bin2_idx : bg.second) {
360 const float ptCoeff = 0.29997*1.9972/2.0;
362 float tripletPtMin = 0.8*
m_minPt;
364 float maxCurv = ptCoeff/tripletPtMin;
366 const float pt_scale = 900/
m_minPt;
368 const float min_deltaPhi_low_dr = 0.002*pt_scale;
369 const float dphi_coeff_low_dr = 4.33e-4*pt_scale;
370 const float min_deltaPhi = 0.015*pt_scale;
371 const float dphi_coeff = 2.2e-4*pt_scale;
373 const float cut_dphi_max =
m_LRTmode ? 0.07 : 0.012;
374 const float cut_dcurv_max =
m_LRTmode ? 0.015 : 0.001;
375 const float cut_tau_ratio_max =
m_LRTmode ? 0.015f : 0.01;
379 const float maxOuterRadius =
m_LRTmode ? 1050.0 : 550.0;
380 const float minDeltaRadius = 2.0;
382 const float cut_zMinU = min_z0 + maxOuterRadius*internalRoI.
dzdrMinus();
383 const float cut_zMaxU = max_z0 + maxOuterRadius*internalRoI.
dzdrPlus();
385 const float maxKappa =
m_LRTmode ? 1.0*maxCurv : 0.9*maxCurv;
415 ATH_MSG_DEBUG(
"Loaded "<<nPixels<<
" Pixel Spacepoints and "<<nStrips<<
" Strip SpacePoints");
417 std::shared_ptr<TrigAccel::OffloadBuffer> pBuff = std::make_shared<TrigAccel::OffloadBuffer>(dataBuffer.get());
426 bool workSuccess = pWork->run();
432 std::shared_ptr<TrigAccel::OffloadBuffer> pOutput = pWork->getOutput();
439 if(pSeeds->
m_nSeeds == 0)
return seedStats;
441 for(
unsigned int seed=0; seed<pSeeds->
m_nSeeds; seed++) {
443 unsigned int lastIdx = output.size();
446 output[lastIdx].addSpacePoint(vSP[pSeeds->
m_seedsArray[seed].m_nodes[
node]]);
452 unsigned int nEdges = pGraph->
m_nEdges;
457 std::vector<GNN_Node> nodes;
458 nodes.reserve(vSP.size());
460 for(
unsigned int idx = 0;idx < vSP.size(); idx++) {
461 nodes.emplace_back(
static_cast<unsigned short>(vL[idx]));
462 auto &
node = nodes.back();
464 const auto& pos = vSP[idx]->globalPosition();
465 float xs = pos.x() - shift_x;
466 float ys = pos.y() - shift_y;
471 node.m_r = std::sqrt(xs*xs + ys*ys);
476 std::vector<GNN_Edge> edgeStorage;
478 std::pair<int, int> graphStats(0,0);
480 edgeStorage.resize(nEdges);
482 unsigned int edgeSize = nMaxNei + 1 + 2;
484 for(
unsigned int idx=0;idx<nEdges;idx++) {
485 unsigned int pos = idx*edgeSize;
493 edgeStorage[idx].m_n1 = &nodes[node1Idx];
495 edgeStorage[idx].m_n2 = &nodes[node2Idx];
496 edgeStorage[idx].m_level = 1;
497 edgeStorage[idx].m_nNei = nNei;
498 for(
int k=0;k<nNei;k++) {
503 graphStats.first = nEdges;
504 graphStats.second = pGraph->
m_nLinks;
508 int maxLevel =
runCCA(graphStats.first, edgeStorage);
510 ATH_MSG_DEBUG(
"Reached Level "<<maxLevel<<
" after GNN iterations");
512 if(maxLevel < minLevel)
return seedStats;
514 std::vector<GNN_Edge*> vSeeds;
516 vSeeds.reserve(graphStats.first/2);
518 for(
int edgeIndex=0;edgeIndex<graphStats.first;edgeIndex++) {
519 GNN_Edge* pS = &(edgeStorage.at(edgeIndex));
521 if(pS->
m_level < minLevel)
continue;
523 vSeeds.push_back(pS);
526 if(vSeeds.empty())
return seedStats;
536 output.reserve(vSeeds.size());
538 for(
auto pS : vSeeds) {
540 if(pS->m_level == -1)
continue;
546 if(!
rs.m_initialized) {
550 if(
static_cast<int>(
rs.m_vs.size()) < minLevel)
continue;
552 std::vector<const GNN_Node*> vN;
554 for(std::vector<GNN_Edge*>::reverse_iterator sIt=
rs.m_vs.rbegin();sIt!=
rs.m_vs.rend();++sIt) {
556 (*sIt)->m_level = -1;
558 if(sIt ==
rs.m_vs.rbegin()) {
559 vN.push_back((*sIt)->m_n1);
561 vN.push_back((*sIt)->m_n2);
564 if(vN.size()<3)
continue;
566 unsigned int lastIdx = output.size();
567 output.emplace_back(
rs.m_J);
569 for(
const auto& n : vN) {
570 output[lastIdx].addSpacePoint(vSP[n->m_idx]);