155 ATH_MSG_WARNING(
"Didn't receive " << FPGAHits.
key() <<
" on first event; assuming no input events.");
157 SmartIF<IEventProcessor> appMgr{service(
"ApplicationMgr")};
159 ATH_MSG_ERROR(
"Failed to retrieve ApplicationMgr as IEventProcessor");
160 return StatusCode::FAILURE;
162 return appMgr->stopRun();
173 auto* FPGAHits_1st_cdv = FPGAHits_1st.
ptr();
174 auto* FPGAHits_2nd_cdv = FPGAHits_2nd.
ptr();
176 ATH_CHECK( FPGARoads_1st.
record (std::make_unique<FPGATrackSimRoadCollection>()));
179 ATH_CHECK(FPGATracks_1stHandle.
record (std::make_unique<FPGATrackSimTrackCollection>()));
182 ATH_CHECK( FPGAHitsFiltered_1st.
record (std::make_unique<FPGATrackSimHitCollection>()));
185 ATH_CHECK( FPGASpacePoints.
record (std::make_unique<FPGATrackSimClusterCollection>()));
188 if (!
m_evtSel->getSelectedEvent()) {
192 std::vector<FPGATrackSimRoad> roads_1st;
193 std::vector<FPGATrackSimTrack> tracks_1st;
194 auto dataFlowInfo = std::make_unique<FPGATrackSimDataFlowInfo>();
198 return StatusCode::SUCCESS;
209 if (!FPGAEventInfo.
isValid()) {
210 ATH_MSG_ERROR(
"Could not find FPGA Event Info with key " << FPGAEventInfo.
key());
211 return StatusCode::FAILURE;
219 std::vector<std::shared_ptr<const FPGATrackSimHit>> phits_output, phits_all, phits_1st, phits_2nd;
220 std::vector<const FPGATrackSimHit*> phits_strips;
223 std::optional<Athena::Chrono> chronoSplitHits;
224 if constexpr (
enableBenchmark) chronoSplitHits.emplace(
"1st Stage: Split hits to 1st and 2nd stage",
m_chrono.get());
226 phits_1st.reserve(FPGAHits->size());
227 phits_2nd.reserve(FPGAHits->size());
233 auto sharedHit = std::shared_ptr<const FPGATrackSimHit>{hit, noDelete};
234 phits_all.push_back(sharedHit);
236 phits_1st.push_back(sharedHit);
237 phits_2nd.push_back(std::move(sharedHit));
238 if(hit->isStrip()) phits_strips.push_back(hit);
247 for (
auto& hit : phits_1st) {
248 FPGAHits_1st_cdv->push_back(hit.get());
255 std::vector<FPGATrackSimCluster> spacepoints;
256 std::optional<Athena::Chrono> chronoSPFormation;
261 FPGASpacePoints->push_back(std::move(cluster));
265 for (
const auto& cluster : *FPGASpacePoints) {
267 for (
const auto& hit : cluster.getHitList()) {
280 for (
auto& hit : phits_2nd) {
281 FPGAHits_2nd_cdv->push_back(hit.get());
288 ATH_MSG_DEBUG(
"1st stage hits: " << phits_1st.size() <<
" 2nd stage hits: " << phits_2nd.size() );
289 if (phits_1st.empty()) {
292 std::vector<FPGATrackSimRoad> roads_1st;
293 std::vector<FPGATrackSimTrack> tracks_1st;
294 auto dataFlowInfo = std::make_unique<FPGATrackSimDataFlowInfo>();
297 return StatusCode::SUCCESS;
302 if (!FPGATruthTracks.
isValid()) {
303 ATH_MSG_ERROR(
"Could not find FPGA Truth Track Collection with key " << FPGATruthTracks.
key());
304 return StatusCode::FAILURE;
308 if (!FPGAOfflineTracks.
isValid()) {
309 ATH_MSG_ERROR(
"Could not find FPGA Offline Track Collection with key " << FPGAOfflineTracks.
key());
310 return StatusCode::FAILURE;
319 const std::vector<FPGATrackSimTruthTrack>& truthtracks = *FPGATruthTracks;
324 auto monitorRoads = [&](
auto& monitor,
const auto& roads) {
325 if (!monitor.empty()) {
326 monitor->fillRoad(roads, truthtracks, nLogicalLayers);
330 std::vector<FPGATrackSimRoad> roads_1st;
332 std::optional<Athena::Chrono> chronoGetRoads;
342 std::optional<Athena::Chrono> chronoRoadFiltering;
344 std::vector<FPGATrackSimRoad> postfilter_roads;
347 roads_1st = std::move(postfilter_roads);
356 std::optional<Athena::Chrono> chronoOverlapRemoval;
366 std::optional<Athena::Chrono> chronoRoadFiltering2;
368 std::vector<FPGATrackSimRoad> postfilter2_roads;
371 roads_1st = std::move(postfilter2_roads);
382 auto monitorTracks = [&](
auto& monitor,
const auto& tracks) {
383 if (monitor.empty())
return;
385 std::vector<const FPGATrackSimTrack*> track_ptrs;
386 track_ptrs.reserve(tracks.size());
388 if constexpr (std::is_pointer_v<
typename std::decay_t<
decltype(tracks)>::value_type>) {
390 track_ptrs.insert(track_ptrs.end(), tracks.begin(), tracks.end());
393 std::transform(tracks.begin(), tracks.end(), std::back_inserter(track_ptrs), [](
const auto& t) { return &t; });
396 monitor->fillTrack(track_ptrs, truthtracks, 1.e15);
399 std::vector<FPGATrackSimTrack> tracks_1st;
402 std::optional<Athena::Chrono> chronoGettingTracks;
416 for (
const auto& road : roads_1st) {
417 std::vector<FPGATrackSimTrack> tracksForCurrentRoad;
420 std::vector<FPGATrackSimRoad> roadVec = {road};
424 if (!tracksForCurrentRoad.empty()) {
425 auto bestTrackIter = std::min_element(
426 tracksForCurrentRoad.begin(), tracksForCurrentRoad.end(),
428 return a.getChi2ndof() < b.getChi2ndof();
431 if (bestTrackIter != tracksForCurrentRoad.end() && bestTrackIter->getChi2ndof() < 1.e15) {
432 tracks_1st.push_back(*bestTrackIter);
441 ATH_MSG_DEBUG(
"No tracking. Just running dummy road2track algorith");
443 for (
const auto& road : roads_1st) {
444 std::vector<std::shared_ptr<const FPGATrackSimHit>> track_hits;
445 for (
unsigned layer = 0; layer < road.getNLayers(); ++layer) {
446 track_hits.insert(track_hits.end(), road.getHitPtrs(layer).begin(), road.getHitPtrs(layer).end());
451 for (
size_t ihit = 0; ihit < track_hits.size(); ++ihit) {
454 tracks_1st.push_back(std::move(track_cand));
464 for (
auto &track : tracks_1st)
465 track.calculateTruth();
475 std::optional<Athena::Chrono> chronoSetTruthParams;
476 if constexpr (
enableBenchmark) chronoSetTruthParams.emplace(
"1st Stage: Set Track Parameters to Truth",
m_chrono.get());
482 track.setQOverPt(truthtracks.front().getQOverPt());
484 track.setD0(truthtracks.front().getD0());
486 track.setPhi(truthtracks.front().getPhi());
488 track.setZ0(truthtracks.front().getZ0());
490 track.setEta(truthtracks.front().getEta());
499 for (
auto const& road : roads_1st) {
500 FPGARoads_1st->push_back(road);
504 if (truthtracks.size() > 0) {
508 if (tracks_1st.size() > 0) {
516 for (
auto itrack = tracks_1st.begin(); itrack != tracks_1st.end();) {
517 if (!
passesChi2Cut(*itrack)) itrack = tracks_1st.erase(itrack);
527 std::optional<Athena::Chrono> chronoOverlapRemoval2;
531 std::vector<const FPGATrackSimTrack*> tracks_1st_after_chi2;
532 std::vector<const FPGATrackSimTrack*> tracks_1st_after_overlap;
534 if (track.passedOR()) {
535 tracks_1st_after_overlap.push_back(&track);
546 if (truthtracks.size() > 0) {
548 unsigned npasschi2(0);
549 unsigned npasschi2OLR(0);
550 if (tracks_1st.size() > 0) {
551 for (
const auto& track : tracks_1st) {
553 if (track.passedOR()) {
568 FPGATracks_1stHandle->push_back(track);
573 std::vector<FPGATrackSimRoad> roadsLRT;
574 std::vector<FPGATrackSimTrack> tracksLRT;
577 std::vector<std::shared_ptr<const FPGATrackSimHit>> remainingHits;
580 ATH_MSG_DEBUG(
"Doing hit filtering based on prompt tracks.");
586 ATH_MSG_DEBUG(
"No hit filtering requested; using all hits for LRT.");
587 remainingHits = std::move(phits_1st);
595 auto dataFlowInfo = std::make_unique<FPGATrackSimDataFlowInfo>();
606 SmartIF<IEventProcessor> appMgr{service(
"ApplicationMgr")};
608 ATH_MSG_ERROR(
"Failed to retrieve ApplicationMgr as IEventProcessor");
609 return StatusCode::FAILURE;
620 return StatusCode::SUCCESS;