162 {
163
164
165 roads.clear();
168
169
170
172 for (
int ireg = 0; ireg < rmap_2nd->
getNRegions(); ireg++) {
173 FPGATrackSimTowerInputHeader tower = FPGATrackSimTowerInputHeader(ireg);
175 }
176 }
177
178
179 HitSpatialIndex hitIndex;
180 {
181 Athena::Chrono chronoBuildIndex(
"NNPathfinder:BuildSpatialIndex",
m_chronoSvc.get());
182 hitIndex.build(hits);
183 }
184
186
187 for (const FPGATrackSimTrack& track : tracks) {
188 Athena::Chrono chronoTrackLoop(
"NNPathfinder:TrackLoop",
m_chronoSvc.get());
190 if (
track.passedOR() == 0) {
191 continue;
192 }
193 const auto& hitsOnTrack =
track.getFPGATrackSimHitPtrs();
194 miniRoad road;
196
197 for (const auto& hit_ptr : hitsOnTrack) {
198 if (!hit_ptr) {
200 return StatusCode::FAILURE;
201 }
203 }
204
207 for (const auto& hit : hits) {
208 ATH_MSG_DEBUG(
"Hit " <<
" X: " << hit->getX() <<
" Y: " << hit->getY() <<
" Z: " << hit->getZ() <<
" R: " << hit->getR() <<
"phi = " << hit->getGPhi() <<
" hitType: " << hit->getHitType() <<
" getDetType: " << hit->getDetType());
209 }
210 }
211
212 std::deque<miniRoad> roadsToExtrapolate;
213 roadsToExtrapolate.push_back(std::move(road));
214
215 std::vector<miniRoad> completedRoads;
216
218
219 const int MAX_ROADS = 10000;
220
221
222 std::vector<std::pair<miniRoad, std::vector<float>>> roadsAwaitingInference;
223
224 while(!roadsToExtrapolate.empty() &&
count < MAX_ROADS ) {
225 miniRoad currentRoad = std::move(roadsToExtrapolate.front());
226
227
228 roadsToExtrapolate.pop_front();
231 ATH_MSG_DEBUG(
"\033[1;31m-------------------------- extraploating road "<<
count <<
"------------------ \033[0m");
233 }
234
236 {
237 completedRoads.push_back(std::move(currentRoad));
238 continue;
239 }
240
241
242 std::vector<float> inputTensorValues;
245 continue;
246 }
247
248
249 roadsAwaitingInference.push_back(std::make_pair(std::move(currentRoad), inputTensorValues));
250
251
252 bool processBatch = (roadsAwaitingInference.size() >= (
size_t)
m_batchSize) || roadsToExtrapolate.empty();
253
254 if (processBatch && !roadsAwaitingInference.empty()) {
255
256 std::vector<std::vector<float>> batchInputTensors;
257 std::vector<std::pair<miniRoad, std::vector<float>>> roadBatch = std::move(roadsAwaitingInference);
258 roadsAwaitingInference.clear();
259
260 for (const auto& [road, tensor] : roadBatch) {
261 batchInputTensors.push_back(tensor);
262 }
263
264
265 std::vector<std::vector<float>> batchOutputTensors;
266 std::vector<long> batchFineIDs;
267 {
268 Athena::Chrono chronoNN(
"NNPathfinder:NNInference",
m_chronoSvc.get());
271 continue;
272 }
273 }
274
275
276 for (size_t batchIdx = 0; batchIdx < roadBatch.size(); ++batchIdx) {
277 miniRoad processRoad = std::move(roadBatch[batchIdx].first);
278 std::vector<float> predhit = batchOutputTensors[batchIdx];
279 long fineID = batchFineIDs[batchIdx];
280
281
283
284
285 if ((
m_useCartesian && (abs(predhit[0]) < 25 && abs(predhit[1]) < 25)) ||
287 {
288 completedRoads.push_back(std::move(processRoad));
289 continue;
290 }
291 }
292 else {
293
294
295 double radius = std::sqrt(predhit[0] * predhit[0] + predhit[1] * predhit[1]);
296 if ((
m_useCartesian && (abs(predhit[0]) > 1024 || abs(predhit[1]) > 1024 || radius > 1024 || abs(predhit[2]) > 3000)) ||
297 (!
m_useCartesian && (abs(predhit[0]) > 1024 || abs(predhit[2]) > 3000))) {
298 completedRoads.push_back(std::move(processRoad));
299 continue;
300 }
301 }
303 ATH_MSG_DEBUG(
"Predicted hit at: " << predhit[0] <<
" " << predhit[1] <<
" " << predhit[2]);
304 }
305
306
307 bool foundhitForRoad = false;
308 if(fineID == 215){
310 completedRoads.push_back(std::move(processRoad));
311 continue;
312 }
313
314
315 unsigned lastLayerInRoad = 0;
316 std::shared_ptr<const FPGATrackSimHit> lastHit;
317 if(!
getLastLayer(processRoad, lastLayerInRoad, lastHit) or !lastHit) {
319 continue;
320 }
321 unsigned layer = lastLayerInRoad+1;
322 bool lastHitWasReal = lastHit->isReal();
323 float lastHitR = lastHit->getR();
325 completedRoads.push_back(std::move(processRoad));
326 continue;
327 }
328 unsigned int hitsInWindow = 0;
329
330
331 const double predr = (
m_useCartesian ? sqrt(predhit[0] * predhit[0] + predhit[1] * predhit[1]) : predhit[0]);
332 const double predphi = predhit[1];
333 const double predz = predhit[2];
334
335
339 int fineID_index = 0;
340
342 auto fineID_it = std::find(m_windowFineID.begin(), m_windowFineID.end(), fineID);
343 if (fineID_it == m_windowFineID.end()) {
344 ATH_MSG_DEBUG("No windows for predicted fineID " << fineID << ", using maximum in provided list instead!");
345 fineID_index = -1;
346 }
347 else {
348 fineID_index = fineID_it - m_windowFineID.begin();
349 }
350 }
352 windowR = (fineID_index == -1) ?
355 }
357 windowZ = (fineID_index == -1) ?
360 }
362 windowPhi = (fineID_index == -1) ?
365 }
366
367
374
375
376 std::vector<std::vector<std::shared_ptr<const FPGATrackSimHit>>> listofHitsFound;
377
378 {
379 Athena::Chrono chronoHitSearch(
"NNPathfinder:HitSearchLoop",
m_chronoSvc.get());
380
381
382 const auto* candidateHits = hitIndex.getHits(fineID);
383 if (candidateHits) {
384 listofHitsFound.reserve(candidateHits->size());
385
386 for (const auto& hit_ptr : *candidateHits) {
387 const auto& hit = *hit_ptr;
388
389 const float hitr = hit.getR();
392
394 ATH_MSG_DEBUG(
"In the hit loop hit at x: " << hit.getX() <<
" y " << hit.getY() <<
" z " << hit.getZ() <<
" phi " << hit.getGPhi());
395 }
396
397
398 const double hitz = hit.getZ();
399 const double hitphi = hit.getGPhi();
400
401 const double dr = abs(hitr - predr);
402 const double dz = abs(hitz - predz);
403 double dphi = abs(hitphi - predphi);
404 while (dphi >
pi) dphi -=
pi;
405
407 (!
m_useCartesian && dphi < windowPhi && dz < windowZ && dr < windowR);
408
409 if (!inWindow) continue;
410
411
412 std::vector<std::shared_ptr<const FPGATrackSimHit>> theseHits{ hit_ptr };
413 hitsInWindow = hitsInWindow + 1;
414
415
416 if(hit.isStrip()) {
418
419 const float EPSILON = 0.00001f;
420 const float searchX = hit.getX();
421 const float searchY = hit.getY();
422 const float searchZ = hit.getZ();
423 const auto searchHash = hit.getIdentifierHash();
425
426 const auto* coordCandidates = hitIndex.getHitsByCoord(searchX, searchY, searchZ);
427 if (coordCandidates) {
428 for (const auto& candidateHitPtr : *coordCandidates) {
429 const auto& candidateHit = *candidateHitPtr;
430 if (candidateHit.getIdentifierHash() != searchHash &&
431 abs(candidateHit.getX() - searchX) <
EPSILON &&
432 abs(candidateHit.getY() - searchY) <
EPSILON &&
433 abs(candidateHit.getZ() - searchZ) <
EPSILON) {
434 theseHits.push_back(candidateHitPtr);
436 break;
437 }
438 }
439 }
440 if (!found) {
441 ATH_MSG_WARNING(
"For a SP in layer " << layer <<
" Couldn't find a matching strip SP");
442 }
443 }
444 else {
445 std::shared_ptr<FPGATrackSimHit> guessedSecondHitPtr = std::make_shared<FPGATrackSimHit>();
446 guessedSecondHitPtr->setX(0);
447 guessedSecondHitPtr->setY(0);
448 guessedSecondHitPtr->setZ(0);
449 guessedSecondHitPtr->setPhysLayer(lastHit->getPhysLayer(true)+1);
453
454 theseHits.push_back(guessedSecondHitPtr);
455 }
456 }
457
458 listofHitsFound.push_back(std::move(theseHits));
459 }
460 }
461 }
462
463 {
464 Athena::Chrono chronoSort(
"NNPathfinder:HitSorting",
m_chronoSvc.get());
465
466
468 std::min(
static_cast<size_t>(
m_maxBranches.value()), listofHitsFound.size()) :
469 listofHitsFound.
size();
470
471
473 auto comparatorFunc = [&](
const auto&
a,
const auto&
b) {
474 return cartesianComparator(
a, b, predr, predz);
475 };
476 if (nToSort < listofHitsFound.size()) {
478 listofHitsFound.begin() + nToSort,
479 listofHitsFound.end(),
480 comparatorFunc);
481 } else {
482 std::sort(listofHitsFound.begin(), listofHitsFound.end(), comparatorFunc);
483 }
484 }
485 else {
489 const double zScale2 = zScale * zScale;
490 const double phiScale2 = phiScale * phiScale;
491 const double rScale2 = rScale * rScale;
492
493 auto comparatorFunc = [&](
const auto&
a,
const auto&
b) {
494 return polarComparator(
a, b, predr, predphi, predz, zScale2, phiScale2, rScale2);
495 };
496 if (nToSort < listofHitsFound.size()) {
498 listofHitsFound.begin() + nToSort,
499 listofHitsFound.end(),
500 comparatorFunc);
501 } else {
502 std::sort(listofHitsFound.begin(), listofHitsFound.end(), comparatorFunc);
503 }
504 }
505 }
506
507
508 std::vector<std::vector<std::shared_ptr<const FPGATrackSimHit>>> cleanHitsToGrow;
509
510
512 int nHitsToChoose = std::min(
int(
m_maxBranches.value()),
int(listofHitsFound.size()));
513 cleanHitsToGrow.reserve(nHitsToChoose);
514 std::copy(listofHitsFound.begin(), listofHitsFound.begin() + nHitsToChoose, std::back_inserter(cleanHitsToGrow));
515 }
516 else {
517 cleanHitsToGrow = std::move(listofHitsFound);
518 }
519
520 {
521 Athena::Chrono chronoRoadBuilding(
"NNPathfinder:RoadBuilding",
m_chronoSvc.get());
522 for (auto& hitsFound: cleanHitsToGrow) {
523
524
525 miniRoad newRoad;
526 if(!
addHitToRoad(newRoad, processRoad, std::move(hitsFound))) {
528 continue;
529 }
530 roadsToExtrapolate.push_back(newRoad);
531 foundhitForRoad = true;
533 ATH_MSG_DEBUG(
"------ road grown with hit from layer "<<layer<<
" to");
535 }
536 }
537
538 if (!foundhitForRoad) {
539
541
542 continue;
543 }
544 else {
545 std::vector<std::shared_ptr<const FPGATrackSimHit>> theseHits;
546
547 if (!
getFakeHit(processRoad, predhit, fineID, theseHits)) {
549 continue;
550 }
551
553 continue;
554 }
555
556 miniRoad newroad;
557 if (!
addHitToRoad(newroad, processRoad, std::move(theseHits))) {
559 continue;
560 }
561 roadsToExtrapolate.push_back(std::move(newroad));
562 }
563 }
564 }
565 }
566 }
567 }
568 {
569 Athena::Chrono chronoRoadConversion(
"NNPathfinder:RoadConversion",
m_chronoSvc.get());
570 for (const auto &miniroad : completedRoads) {
571 FPGATrackSimRoad road;
575
581
582
583 std::vector<std::vector<std::shared_ptr<const FPGATrackSimHit>>> roadhits = miniroad.getVecHits();
585 if (roadhits.size() > nexpected) {
586 roadhits.resize(nexpected);
587 }
588 else if (roadhits.size() < nexpected) {
589 for (unsigned layer = roadhits.size(); layer < nexpected; layer++) {
590 std::shared_ptr<FPGATrackSimHit> emptyHitPtr = std::make_shared<FPGATrackSimHit>();
591 emptyHitPtr->setX(0);
592 emptyHitPtr->setY(0);
593 emptyHitPtr->setZ(0);
594 emptyHitPtr->setLayer(layer);
596
597 roadhits.emplace_back(1,emptyHitPtr);
599 wclayers |= (1 <<
layer);
601 }
602 }
603 road.
setHits(std::move(roadhits));
604
605 m_roads.push_back(std::move(road));
606 }
607 }
608 }
609
611 for (FPGATrackSimRoad &
r :
m_roads)
612 {
614 roads.emplace_back(
r);
615 }
616 ATH_MSG_DEBUG(
"Found " << roads.size() <<
" new roads in second stage.");
617
618 return StatusCode::SUCCESS;
619}
#define ATH_MSG_WARNING(x)
bool isFineIDInStrip(long ID)
bool isFineIDInPixel(long ID)
size_t size() const
Number of registered mappings.
void setHitLayers(layer_bitmask_t hit_layers)
void setHits(std::vector< std::vector< std::shared_ptr< const FPGATrackSimHit > > > &&hits)
void setRoadID(int roadID)
layer_bitmask_t getWCLayers() const
void setWCLayers(layer_bitmask_t wc_layers)
int count(std::string s, const std::string ®x)
count how many occurances of a regx are in a string
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
void partial_sort(DataModel_detail::iterator< DVL > beg, DataModel_detail::iterator< DVL > mid, DataModel_detail::iterator< DVL > end)
Specialization of partial_sort for DataVector/List.
void addHit(const std::shared_ptr< const FPGATrackSimHit > &hit)
unsigned getNHits() const
size_t getNWCLayers() const