162 std::vector<FPGATrackSimRoad> & roads) {
172 for (
int ireg = 0; ireg < rmap_2nd->
getNRegions(); ireg++) {
179 HitSpatialIndex hitIndex;
182 hitIndex.build(hits);
190 if (track.passedOR() == 0) {
193 const auto& hitsOnTrack = track.getFPGATrackSimHitPtrs();
195 float pt = track.getPt();
197 for (
const auto& hit_ptr : hitsOnTrack) {
200 return StatusCode::FAILURE;
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());
212 std::deque<miniRoad> roadsToExtrapolate;
213 roadsToExtrapolate.push_back(std::move(road));
215 std::vector<miniRoad> completedRoads;
219 const int MAX_ROADS = 10000;
222 std::vector<std::pair<miniRoad, std::vector<float>>> roadsAwaitingInference;
224 while(!roadsToExtrapolate.empty() &&
count < MAX_ROADS ) {
225 miniRoad currentRoad = std::move(roadsToExtrapolate.front());
228 roadsToExtrapolate.pop_front();
231 ATH_MSG_DEBUG(
"\033[1;31m-------------------------- extraploating road "<<
count <<
"------------------ \033[0m");
237 completedRoads.push_back(std::move(currentRoad));
242 std::vector<float> inputTensorValues;
249 roadsAwaitingInference.push_back(std::make_pair(std::move(currentRoad), inputTensorValues));
252 bool processBatch = (roadsAwaitingInference.size() >= (
size_t)
m_batchSize) || roadsToExtrapolate.empty();
254 if (processBatch && !roadsAwaitingInference.empty()) {
256 std::vector<std::vector<float>> batchInputTensors;
257 std::vector<std::pair<miniRoad, std::vector<float>>> roadBatch = std::move(roadsAwaitingInference);
258 roadsAwaitingInference.clear();
260 for (
const auto& [road, tensor] : roadBatch) {
261 batchInputTensors.push_back(tensor);
265 std::vector<std::vector<float>> batchOutputTensors;
266 std::vector<long> batchFineIDs;
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];
285 if ((
m_useCartesian && (abs(predhit[0]) < 25 && abs(predhit[1]) < 25)) ||
288 completedRoads.push_back(std::move(processRoad));
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));
303 ATH_MSG_DEBUG(
"Predicted hit at: " << predhit[0] <<
" " << predhit[1] <<
" " << predhit[2]);
307 bool foundhitForRoad =
false;
310 completedRoads.push_back(std::move(processRoad));
315 unsigned lastLayerInRoad = 0;
316 std::shared_ptr<const FPGATrackSimHit> lastHit;
317 if(!
getLastLayer(processRoad, lastLayerInRoad, lastHit) or !lastHit) {
321 unsigned layer = lastLayerInRoad+1;
322 bool lastHitWasReal = lastHit->isReal();
323 float lastHitR = lastHit->getR();
325 completedRoads.push_back(std::move(processRoad));
328 unsigned int hitsInWindow = 0;
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];
339 int fineID_index = 0;
344 ATH_MSG_DEBUG(
"No windows for predicted fineID " << fineID <<
", using maximum in provided list instead!");
352 windowR = (fineID_index == -1) ?
357 windowZ = (fineID_index == -1) ?
362 windowPhi = (fineID_index == -1) ?
376 std::vector<std::vector<std::shared_ptr<const FPGATrackSimHit>>> listofHitsFound;
382 const auto* candidateHits = hitIndex.getHits(fineID);
384 listofHitsFound.reserve(candidateHits->size());
386 for (
const auto& hit_ptr : *candidateHits) {
387 const auto& hit = *hit_ptr;
389 const float hitr = hit.getR();
394 ATH_MSG_DEBUG(
"In the hit loop hit at x: " << hit.getX() <<
" y " << hit.getY() <<
" z " << hit.getZ() <<
" phi " << hit.getGPhi());
398 const double hitz = hit.getZ();
399 const double hitphi = hit.getGPhi();
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;
406 const bool inWindow = (
m_useCartesian && dr < windowR && dz < windowZ) ||
407 (!
m_useCartesian && dphi < windowPhi && dz < windowZ && dr < windowR);
409 if (!inWindow)
continue;
412 std::vector<std::shared_ptr<const FPGATrackSimHit>> theseHits{ hit_ptr };
413 hitsInWindow = hitsInWindow + 1;
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();
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);
441 ATH_MSG_WARNING(
"For a SP in layer " << layer <<
" Couldn't find a matching strip SP");
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);
454 theseHits.push_back(guessedSecondHitPtr);
458 listofHitsFound.push_back(std::move(theseHits));
468 std::min(
static_cast<size_t>(
m_maxBranches.value()), listofHitsFound.size()) :
469 listofHitsFound.size();
473 auto comparatorFunc = [&](
const auto&
a,
const auto& b) {
474 return cartesianComparator(
a, b, predr, predz);
476 if (nToSort < listofHitsFound.size()) {
478 listofHitsFound.begin() + nToSort,
479 listofHitsFound.end(),
482 std::sort(listofHitsFound.begin(), listofHitsFound.end(), comparatorFunc);
489 const double zScale2 = zScale * zScale;
490 const double phiScale2 = phiScale * phiScale;
491 const double rScale2 = rScale * rScale;
493 auto comparatorFunc = [&](
const auto&
a,
const auto& b) {
494 return polarComparator(
a, b, predr, predphi, predz, zScale2, phiScale2, rScale2);
496 if (nToSort < listofHitsFound.size()) {
498 listofHitsFound.begin() + nToSort,
499 listofHitsFound.end(),
502 std::sort(listofHitsFound.begin(), listofHitsFound.end(), comparatorFunc);
508 std::vector<std::vector<std::shared_ptr<const FPGATrackSimHit>>> cleanHitsToGrow;
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));
517 cleanHitsToGrow = std::move(listofHitsFound);
522 for (
auto& hitsFound: cleanHitsToGrow) {
526 if(!
addHitToRoad(newRoad, processRoad, std::move(hitsFound))) {
530 roadsToExtrapolate.push_back(newRoad);
531 foundhitForRoad =
true;
533 ATH_MSG_DEBUG(
"------ road grown with hit from layer "<<layer<<
" to");
538 if (!foundhitForRoad) {
545 std::vector<std::shared_ptr<const FPGATrackSimHit>> theseHits;
547 if (!
getFakeHit(processRoad, predhit, fineID, theseHits)) {
557 if (!
addHitToRoad(newroad, processRoad, std::move(theseHits))) {
561 roadsToExtrapolate.push_back(std::move(newroad));
570 for (
const auto &miniroad : completedRoads) {
576 road.
setX(track.getPhi());
577 road.
setY(track.getQOverPt());
578 road.
setXBin(track.getHoughXBin());
579 road.
setYBin(track.getHoughYBin());
583 std::vector<std::vector<std::shared_ptr<const FPGATrackSimHit>>> roadhits = miniroad.getVecHits();
585 if (roadhits.size() > nexpected) {
586 roadhits.resize(nexpected);
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);
597 roadhits.emplace_back(1,emptyHitPtr);
599 wclayers |= (1 << layer);
603 road.
setHits(std::move(roadhits));
605 m_roads.push_back(std::move(road));
614 roads.emplace_back(
r);
616 ATH_MSG_DEBUG(
"Found " << roads.size() <<
" new roads in second stage.");
618 return StatusCode::SUCCESS;
623 std::vector<std::shared_ptr<const FPGATrackSimHit>> hitsR;
625 std::vector<std::shared_ptr<const FPGATrackSimHit>> hits = thisroad.
getHits();
628 for (
unsigned ihit = 0; ihit < hits.size(); ihit++) {
630 hitsR.push_back(hits[ihit]);
633 std::sort(hitsR.begin(), hitsR.end(), [](
auto&
a,
auto& b){
634 double dist_a = std::hypot(a->getX(), a->getY(), a->getZ());
635 double dist_b = std::hypot(b->getX(), b->getY(), b->getZ());
636 return dist_a < dist_b;
640 for (
const auto& thit : hitsR)
642 if (
m_debugEvent)
ATH_MSG_DEBUG(thit->getX() <<
" " << thit->getY() <<
" " << thit->getZ() <<
" and phi = " << thit->getGPhi());
646 std::vector<std::shared_ptr<const FPGATrackSimHit>> cleanHits;
647 bool skipHit =
false;
648 for (
auto thit : hitsR)
657 cleanHits.push_back(std::move(thit));
662 cleanHits.push_back(std::move(thit));
668 cleanHits.push_back(std::move(thit));
676 else if (thit->isStrip() && thit->isReal())
679 cleanHits.push_back(std::move(thit));
683 ATH_MSG_WARNING(
"No clue how to deal with this hit in the NN predicition ");
695 std::vector<std::shared_ptr<const FPGATrackSimHit>> hitsToEncode;
699 for (
const auto& thit : cleanHits)
701 if (
m_debugEvent)
ATH_MSG_DEBUG(thit->getX() <<
" " << thit->getY() <<
" " << thit->getZ() <<
" " << thit->isStrip() <<
" and gphi = " << thit->getGPhi());
708 for (
const auto& thit : hitsToEncode)
711 inputTensorValues.push_back(thit->getX() /
getXScale());
712 inputTensorValues.push_back(thit->getY() /
getYScale());
713 inputTensorValues.push_back(thit->getZ() /
getZScale());
716 inputTensorValues.push_back(thit->getR() /
getRScale());
717 inputTensorValues.push_back(thit->getGPhi() /
getPhiScale());
718 inputTensorValues.push_back(thit->getZ() /
getZScale());
721 if (
m_debugEvent)
ATH_MSG_DEBUG(thit->getX() <<
" " << thit->getY() <<
" " << thit->getZ() <<
" and gphi = " << thit->getGPhi());
724 return StatusCode::SUCCESS;
871 std::vector<std::vector<float>>& batchOutputTensors,
872 std::vector<long>& batchFineIDs)
874 if (batchInputTensors.empty()) {
875 return StatusCode::SUCCESS;
878 size_t batchSize = batchInputTensors.size();
879 size_t featureSize = batchInputTensors[0].size();
884 for (
size_t i = 0; i < batchSize; ++i) {
885 for (
size_t j = 0; j < featureSize; ++j) {
886 volInputMatrix(i, j) = batchInputTensors[i][j];
891 auto volNNBatchedOutput =
m_extensionVolNN.runONNXInference(volInputMatrix);
895 batchFineIDs.reserve(batchSize);
897 for (
size_t i = 0; i < volNNBatchedOutput.size(); ++i) {
898 const auto& output = volNNBatchedOutput[i];
899 auto maxIdx = std::distance(output.begin(), std::max_element(output.begin(), output.end()));
900 batchFineIDs.push_back(maxIdx);
905 size_t numClasses = volNNBatchedOutput[0].size();
908 for (
size_t i = 0; i < batchSize; ++i) {
910 for (
size_t j = 0; j < featureSize; ++j) {
911 hitInputMatrix(i, j) = batchInputTensors[i][j];
914 for (
size_t j = 0; j < numClasses; ++j) {
915 hitInputMatrix(i, featureSize + j) = volNNBatchedOutput[i][j];
920 auto hitNNBatchedOutput =
m_extensionHitNN.runONNXInference(hitInputMatrix);
922 batchOutputTensors.reserve(batchSize);
925 for (
size_t i = 0; i < hitNNBatchedOutput.size(); ++i) {
926 std::vector<float> output = hitNNBatchedOutput[i];
939 batchOutputTensors.push_back(std::move(output));
942 return StatusCode::SUCCESS;