167 {
168
169
170 roads.clear();
173
174
175
177 for (
int ireg = 0; ireg < rmap_2nd->
getNRegions(); ireg++) {
178 FPGATrackSimTowerInputHeader tower = FPGATrackSimTowerInputHeader(ireg);
180 }
181 }
182
183
184 HitSpatialIndex hitIndex;
185 {
186 Athena::Chrono chronoBuildIndex(
"NNPathfinder:BuildSpatialIndex",
m_chronoSvc.get());
187 hitIndex.build(hits);
188 }
189
191
192 for (const FPGATrackSimTrack& track : tracks) {
193 Athena::Chrono chronoTrackLoop(
"NNPathfinder:TrackLoop",
m_chronoSvc.get());
195 if (
track.passedOR() == 0) {
196 continue;
197 }
198 const std::vector<FPGATrackSimHit> hitsOnTrack =
track.getFPGATrackSimHits();
199 miniRoad road;
201
202 for (const auto &thit : hitsOnTrack) {
203 road.
addHit(std::make_shared<const FPGATrackSimHit>(thit));
204 }
205
208 for (const auto& hit : hits) {
209 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());
210 }
211 }
212
213 std::deque<miniRoad> roadsToExtrapolate;
214 roadsToExtrapolate.push_back(std::move(road));
215
216 std::vector<miniRoad> completedRoads;
217
219
220 const int MAX_ROADS = 10000;
221 while(!roadsToExtrapolate.empty() &&
count < MAX_ROADS ) {
222 miniRoad currentRoad = std::move(roadsToExtrapolate.front());
223
224
225 roadsToExtrapolate.pop_front();
228 ATH_MSG_DEBUG(
"\033[1;31m-------------------------- extraploating road "<<
count <<
"------------------ \033[0m");
230 }
231
233 {
234 completedRoads.push_back(std::move(currentRoad));
235 continue;
236 }
237
238 std::vector<float> inputTensorValues;
239 std::vector<float> predhit;
240 long fineID;
241 {
242 Athena::Chrono chronoNN(
"NNPathfinder:NNInference",
m_chronoSvc.get());
245 continue;
246 }
249 continue;
250 }
251 }
252
254
255
256 if ((
m_useCartesian && (abs(predhit[0]) < 25 && abs(predhit[1]) < 25)) ||
258 {
259 completedRoads.push_back(std::move(currentRoad));
260 continue;
261 }
262 }
263 else {
264
265
266 double radius = std::sqrt(predhit[0] * predhit[0] + predhit[1] * predhit[1]);
267 if ((
m_useCartesian && (abs(predhit[0]) > 1024 || abs(predhit[1]) > 1024 || radius > 1024 || abs(predhit[2]) > 3000)) ||
268 (!
m_useCartesian && (abs(predhit[0]) > 1024 || abs(predhit[2]) > 3000))) {
269 completedRoads.push_back(std::move(currentRoad));
270 continue;
271 }
272 }
274 ATH_MSG_DEBUG(
"Predicted hit at: " << predhit[0] <<
" " << predhit[1] <<
" " << predhit[2]);
275 }
276
277
278 bool foundhitForRoad = false;
279 if(fineID == 215){
281 completedRoads.push_back(std::move(currentRoad));
282 continue;
283 }
284
285 unsigned lastLayerInRoad = 0;
286 std::shared_ptr<const FPGATrackSimHit> lastHit;
287 if(!
getLastLayer(currentRoad, lastLayerInRoad, lastHit) or !lastHit) {
289 continue;
290 }
291 unsigned layer = lastLayerInRoad+1;
292 bool lastHitWasReal = lastHit->isReal();
293 float lastHitR = lastHit->getR();
295 completedRoads.push_back(std::move(currentRoad));
296 continue;
297 }
298 unsigned int hitsInWindow = 0;
299
300
301 const double predr = (
m_useCartesian ? sqrt(predhit[0] * predhit[0] + predhit[1] * predhit[1]) : predhit[0]);
302 const double predphi = predhit[1];
303 const double predz = predhit[2];
304
305
309 int fineID_index = 0;
310
312 auto fineID_it = std::find(m_windowFineID.begin(), m_windowFineID.end(), fineID);
313 if (fineID_it == m_windowFineID.end()){
314 ATH_MSG_DEBUG("No windows for predicted fineID " << fineID << ", using maximum in provided list instead!");
315 fineID_index = -1;
316 }
317 else {
318 fineID_index = fineID_it - m_windowFineID.begin();
319 }
320 }
322 windowR = (fineID_index == -1) ?
325 }
327 windowZ = (fineID_index == -1) ?
330 }
332 windowPhi = (fineID_index == -1) ?
335 }
336
337
344
345
346 std::vector<std::vector<std::shared_ptr<const FPGATrackSimHit>>> listofHitsFound;
347
348 {
349 Athena::Chrono chronoHitSearch(
"NNPathfinder:HitSearchLoop",
m_chronoSvc.get());
350
351
352 const auto* candidateHits = hitIndex.getHits(fineID);
353 if (candidateHits) {
354 listofHitsFound.reserve(candidateHits->size());
355
356 for (const FPGATrackSimHit* hit : *candidateHits) {
357
358 const float hitr = hit->getR();
361
363 ATH_MSG_DEBUG(
"In the hit loop hit at x: " << hit->getX() <<
" y " << hit->getY() <<
" z " << hit->getZ() <<
" phi " << hit->getGPhi());
364 }
365
366
367 const double hitz = hit->getZ();
368 const double hitphi = hit->getGPhi();
369
370 const double dr = abs(hitr - predr);
371 const double dz = abs(hitz - predz);
372 double dphi = abs(hitphi - predphi);
373 while (dphi >
pi) dphi -=
pi;
374
376 (!
m_useCartesian && dphi < windowPhi && dz < windowZ && dr < windowR);
377
378 if (!inWindow) continue;
379
380
381 std::vector<std::shared_ptr<const FPGATrackSimHit>> theseHits{ makeNonOwningHitPtr(hit) };
382 hitsInWindow = hitsInWindow + 1;
383
384
385 if(hit->isStrip()) {
387
388 const float EPSILON = 0.00001f;
389 const float searchX = hit->getX();
390 const float searchY = hit->getY();
391 const float searchZ = hit->getZ();
392 const auto searchHash = hit->getIdentifierHash();
394
395 const auto* coordCandidates = hitIndex.getHitsByCoord(searchX, searchY, searchZ);
396 if (coordCandidates) {
397 for (const FPGATrackSimHit* candidateHit : *coordCandidates) {
398 if (candidateHit->getIdentifierHash() != searchHash &&
399 abs(candidateHit->getX() - searchX) <
EPSILON &&
400 abs(candidateHit->getY() - searchY) <
EPSILON &&
401 abs(candidateHit->getZ() - searchZ) <
EPSILON) {
402 theseHits.push_back(makeNonOwningHitPtr(candidateHit));
404 break;
405 }
406 }
407 }
408 if (!found) {
409 ATH_MSG_WARNING(
"For a SP in layer " << layer <<
" Couldn't find a matching strip SP");
410 }
411 }
412 else {
413 std::shared_ptr<FPGATrackSimHit> guessedSecondHitPtr = std::make_shared<FPGATrackSimHit>();
414 guessedSecondHitPtr->setX(0);
415 guessedSecondHitPtr->setY(0);
416 guessedSecondHitPtr->setZ(0);
417 guessedSecondHitPtr->setPhysLayer(lastHit->getPhysLayer(true)+1);
421
422 theseHits.push_back(guessedSecondHitPtr);
423 }
424 }
425
426 listofHitsFound.push_back(std::move(theseHits));
427 }
428 }
429 }
430
431 {
432 Athena::Chrono chronoSort(
"NNPathfinder:HitSorting",
m_chronoSvc.get());
433
434
436 std::min(
static_cast<size_t>(
m_maxBranches.value()), listofHitsFound.size()) :
437 listofHitsFound.size();
438
439
441 auto comparatorFunc = [&](
const auto&
a,
const auto&
b) {
442 return cartesianComparator(
a, b, predr, predz);
443 };
444 if (nToSort < listofHitsFound.size()) {
446 listofHitsFound.begin() + nToSort,
447 listofHitsFound.end(),
448 comparatorFunc);
449 } else {
450 std::sort(listofHitsFound.begin(), listofHitsFound.end(), comparatorFunc);
451 }
452 }
453 else {
457 const double zScale2 = zScale * zScale;
458 const double phiScale2 = phiScale * phiScale;
459 const double rScale2 = rScale * rScale;
460
461 auto comparatorFunc = [&](
const auto&
a,
const auto&
b) {
462 return polarComparator(
a, b, predr, predphi, predz, zScale2, phiScale2, rScale2);
463 };
464 if (nToSort < listofHitsFound.size()) {
466 listofHitsFound.begin() + nToSort,
467 listofHitsFound.end(),
468 comparatorFunc);
469 } else {
470 std::sort(listofHitsFound.begin(), listofHitsFound.end(), comparatorFunc);
471 }
472 }
473 }
474
475
476 std::vector<std::vector<std::shared_ptr<const FPGATrackSimHit>>> cleanHitsToGrow;
477
478
480 int nHitsToChoose = std::min(
int(
m_maxBranches.value()),
int(listofHitsFound.size()));
481 cleanHitsToGrow.reserve(nHitsToChoose);
482 std::copy(listofHitsFound.begin(), listofHitsFound.begin() + nHitsToChoose, std::back_inserter(cleanHitsToGrow));
483 }
484 else {
485 cleanHitsToGrow = std::move(listofHitsFound);
486 }
487
488 {
489 Athena::Chrono chronoRoadBuilding(
"NNPathfinder:RoadBuilding",
m_chronoSvc.get());
490 for (auto& hitsFound: cleanHitsToGrow) {
491
492
493 miniRoad newRoad;
494 if(!
addHitToRoad(newRoad, currentRoad, std::move(hitsFound))) {
496 continue;
497 }
498 roadsToExtrapolate.push_back(newRoad);
499 foundhitForRoad = true;
501 ATH_MSG_DEBUG(
"------ road grown with hit from layer "<<layer<<
" to");
503 }
504 }
505
506 if (!foundhitForRoad) {
507
509
510 continue;
511 }
512 else {
513 std::vector<std::shared_ptr<const FPGATrackSimHit>> theseHits;
514
515 if (!
getFakeHit(currentRoad, predhit, fineID, theseHits)) {
517 continue;
518 }
519
521 continue;
522 }
523
524 miniRoad newroad;
525 if (!
addHitToRoad(newroad, currentRoad, std::move(theseHits))) {
527 continue;
528 }
529 roadsToExtrapolate.push_back(std::move(newroad));
530 }
531 }
532 }
533 }
534
535 {
536 Athena::Chrono chronoRoadConversion(
"NNPathfinder:RoadConversion",
m_chronoSvc.get());
537 for (const auto &miniroad : completedRoads) {
538 FPGATrackSimRoad road;
542
548
549
550 std::vector<std::vector<std::shared_ptr<const FPGATrackSimHit>>> roadhits = miniroad.getVecHits();
552 if (roadhits.size() > nexpected) {
553 roadhits.resize(nexpected);
554 }
555 else if (roadhits.size() < nexpected) {
556 for (unsigned layer = roadhits.size(); layer < nexpected; layer++) {
557 std::shared_ptr<FPGATrackSimHit> emptyHitPtr = std::make_shared<FPGATrackSimHit>();
558 emptyHitPtr->setX(0);
559 emptyHitPtr->setY(0);
560 emptyHitPtr->setZ(0);
561 emptyHitPtr->setLayer(layer);
563
564 roadhits.emplace_back(1,emptyHitPtr);
566 wclayers |= (1 <<
layer);
568 }
569 }
570 road.
setHits(std::move(roadhits));
571
572 m_roads.push_back(std::move(road));
573 }
574 }
575 }
576
578 for (FPGATrackSimRoad &
r :
m_roads)
579 {
581 roads.emplace_back(
r);
582 }
583 ATH_MSG_DEBUG(
"Found " << roads.size() <<
" new roads in second stage.");
584
585 return StatusCode::SUCCESS;
586}
#define ATH_MSG_WARNING(x)
bool isFineIDInStrip(long ID)
bool isFineIDInPixel(long ID)
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