(first track monitor, after getting tracks) create a vector of references from a vector of instances
(second track monitor, after set track parameters to truth) create a vector of references from a vector of instances
149{
150 const EventContext& ctx = getContext();
151
152
153 SG::ReadHandle<FPGATrackSimHitCollection> FPGAHits(
m_FPGAHitKey, ctx);
154 if (!FPGAHits.isValid()) {
156 ATH_MSG_WARNING(
"Didn't receive " << FPGAHits.key() <<
" on first event; assuming no input events.");
157 }
158 SmartIF<IEventProcessor> appMgr{service("ApplicationMgr")};
159 if (!appMgr) {
160 ATH_MSG_ERROR(
"Failed to retrieve ApplicationMgr as IEventProcessor");
161 return StatusCode::FAILURE;
162 }
163 return appMgr->stopRun();
164 }
165
166
167 SG::WriteHandle<ConstDataVector<FPGATrackSimHitCollection>> FPGAHits_1st (
m_FPGAHitKey_1st,ctx);
168 SG::WriteHandle<ConstDataVector<FPGATrackSimHitCollection>> FPGAHits_2nd (
m_FPGAHitKey_2nd,ctx);
169 SG::WriteHandle<FPGATrackSimRoadCollection> FPGARoads_1st (
m_FPGARoadKey, ctx);
170
171
174 auto* FPGAHits_1st_cdv = FPGAHits_1st.ptr();
175 auto* FPGAHits_2nd_cdv = FPGAHits_2nd.ptr();
176
177 ATH_CHECK( FPGARoads_1st.record (std::make_unique<FPGATrackSimRoadCollection>()));
178
179 SG::WriteHandle<FPGATrackSimTrackCollection> FPGATracks_1stHandle (
m_FPGATrackKey, ctx);
180 ATH_CHECK(FPGATracks_1stHandle.record (std::make_unique<FPGATrackSimTrackCollection>()));
181
183 ATH_CHECK( FPGAHitsFiltered_1st.record (std::make_unique<FPGATrackSimHitCollection>()));
184
186 ATH_CHECK( FPGASpacePoints.record (std::make_unique<FPGATrackSimClusterCollection>()));
187
188
189 if (!
m_evtSel->getSelectedEvent()) {
190
191
193 std::vector<FPGATrackSimRoad> roads_1st;
194 std::vector<FPGATrackSimTrack> tracks_1st;
195 auto dataFlowInfo = std::make_unique<FPGATrackSimDataFlowInfo>();
197 }
198
199 return StatusCode::SUCCESS;
200 }
204 }
205
206
208
210 if (!FPGAEventInfo.isValid()) {
211 ATH_MSG_ERROR(
"Could not find FPGA Event Info with key " << FPGAEventInfo.key());
212 return StatusCode::FAILURE;
213 }
214 FPGATrackSimEventInfo eventInfo = *FPGAEventInfo.cptr();
219
220 std::vector<std::shared_ptr<const FPGATrackSimHit>> phits_output, phits_all, phits_1st, phits_2nd;
221 std::vector<const FPGATrackSimHit*> phits_strips;
222
223 {
224 std::optional<Athena::Chrono> chronoSplitHits;
225 if constexpr (
enableBenchmark) chronoSplitHits.emplace(
"1st Stage: Split hits to 1st and 2nd stage",
m_chrono.get());
226
227 phits_1st.reserve(FPGAHits->size());
228 phits_2nd.reserve(FPGAHits->size());
230 auto noDelete = [](const FPGATrackSimHit*) {};
231 for (const FPGATrackSimHit* hit : *(FPGAHits.cptr())) {
232
233
234 auto sharedHit = std::shared_ptr<const FPGATrackSimHit>{hit, noDelete};
235 phits_all.push_back(sharedHit);
237 phits_1st.push_back(sharedHit);
238 phits_2nd.push_back(std::move(sharedHit));
239 if(hit->isStrip()) phits_strips.push_back(hit);
240 }
241 }
242
243
245 }
246
247
248 for (auto& hit : phits_1st) {
249 FPGAHits_1st_cdv->push_back(hit.get());
250 }
251
253
254
256 std::vector<FPGATrackSimCluster> spacepoints;
257 std::optional<Athena::Chrono> chronoSPFormation;
260
261 for (FPGATrackSimCluster& cluster : spacepoints) {
262 FPGASpacePoints->push_back(std::move(cluster));
263 }
264
265
266 for (const auto& cluster : *FPGASpacePoints) {
267
268 for (const auto& hit : cluster.getHitList()) {
269 (
m_secondStageStrips ? phits_2nd : phits_1st).emplace_back(&hit, [](
const FPGATrackSimHit*){});
270 }
271 }
272 } else {
273
274
275 for (const FPGATrackSimHit* hit : phits_strips) {
276 (
m_secondStageStrips ? phits_2nd : phits_1st).emplace_back(hit, [](
const FPGATrackSimHit*){});
277 }
278 }
279
280
281 for (auto& hit : phits_2nd) {
282 FPGAHits_2nd_cdv->push_back(hit.get());
283 }
284
285
286 for (const FPGATrackSimHit* hit : *(FPGAHits_2nd.cptr())) {
287 phits_output.emplace_back(hit, [](const FPGATrackSimHit*){});
288 }
289 ATH_MSG_DEBUG(
"1st stage hits: " << phits_1st.size() <<
" 2nd stage hits: " << phits_2nd.size() );
290 if (phits_1st.empty()) {
291
293 std::vector<FPGATrackSimRoad> roads_1st;
294 std::vector<FPGATrackSimTrack> tracks_1st;
295 auto dataFlowInfo = std::make_unique<FPGATrackSimDataFlowInfo>();
297 }
298 return StatusCode::SUCCESS;
299 }
300
301
302 SG::ReadHandle<FPGATrackSimTruthTrackCollection> FPGATruthTracks(
m_FPGATruthTrackKey, ctx);
303 if (!FPGATruthTracks.isValid()) {
304 ATH_MSG_ERROR(
"Could not find FPGA Truth Track Collection with key " << FPGATruthTracks.key());
305 return StatusCode::FAILURE;
306 }
307
309 if (!FPGAOfflineTracks.isValid()) {
310 ATH_MSG_ERROR(
"Could not find FPGA Offline Track Collection with key " << FPGAOfflineTracks.key());
311 return StatusCode::FAILURE;
312 }
313
314
316
318
320 const std::vector<FPGATrackSimTruthTrack>& truthtracks = *FPGATruthTracks;
325 auto monitorRoads = [&](auto& monitor, const auto& roads) {
326 if (!monitor.empty()) {
327 monitor->fillRoad(roads, truthtracks, nLogicalLayers);
328 }
329 };
330
331 std::vector<FPGATrackSimRoad> roads_1st;
332 {
333 std::optional<Athena::Chrono> chronoGetRoads;
335
338 }
339
340
341 {
342
343 std::optional<Athena::Chrono> chronoRoadFiltering;
345 std::vector<FPGATrackSimRoad> postfilter_roads;
348 roads_1st = std::move(postfilter_roads);
349 }
352 }
353
354
355 {
356
357 std::optional<Athena::Chrono> chronoOverlapRemoval;
362 }
363
364
365 {
366
367 std::optional<Athena::Chrono> chronoRoadFiltering2;
369 std::vector<FPGATrackSimRoad> postfilter2_roads;
372 roads_1st = std::move(postfilter2_roads);
373 }
376 }
377
379
381
383 auto monitorTracks = [&](auto& monitor, const auto& tracks) {
384 if (monitor.empty()) return;
385
386 std::vector<const FPGATrackSimTrack*> track_ptrs;
387 track_ptrs.reserve(tracks.size());
388
389 if constexpr (std::is_pointer_v<typename std::decay_t<decltype(tracks)>::value_type>) {
390
391 track_ptrs.insert(track_ptrs.end(), tracks.begin(), tracks.end());
392 } else {
393
394 std::transform(tracks.begin(), tracks.end(), std::back_inserter(track_ptrs), [](const auto& t) { return &t; });
395 }
396
397 monitor->fillTrack(track_ptrs, truthtracks, 1.e15);
398 };
399
400 std::vector<FPGATrackSimTrack> tracks_1st;
401 {
402
403 std::optional<Athena::Chrono> chronoGettingTracks;
412 }
413 } else {
416
417 for (const auto& road : roads_1st) {
418 std::vector<FPGATrackSimTrack> tracksForCurrentRoad;
419
420
421 std::vector<FPGATrackSimRoad> roadVec = {road};
423
424
425 if (!tracksForCurrentRoad.empty()) {
426 auto bestTrackIter = std::min_element(
427 tracksForCurrentRoad.begin(), tracksForCurrentRoad.end(),
428 [](
const FPGATrackSimTrack&
a,
const FPGATrackSimTrack& b) {
429 return a.getChi2ndof() < b.getChi2ndof();
430 });
431
432 if (bestTrackIter != tracksForCurrentRoad.end() && bestTrackIter->getChi2ndof() < 1.e15) {
433 tracks_1st.push_back(*bestTrackIter);
434 }
435 }
436 }
437 } else {
439 }
440 }
441 } else {
442 ATH_MSG_DEBUG(
"No tracking. Just running dummy road2track algorith");
444 for (const auto& road : roads_1st) {
445 std::vector<std::shared_ptr<const FPGATrackSimHit>> track_hits;
446 for (
unsigned layer = 0;
layer < road.getNLayers(); ++
layer) {
447 track_hits.insert(track_hits.end(), road.getHitPtrs(layer).begin(), road.getHitPtrs(layer).end());
448 }
449
450 FPGATrackSimTrack track_cand;
452 for (size_t ihit = 0; ihit < track_hits.size(); ++ihit) {
454 }
455 tracks_1st.push_back(std::move(track_cand));
456 }
457 }
459 }
460
461
462
465 for (auto &track : tracks_1st)
466 track.calculateTruth();
467
471 }
472
473
474 {
475
476 std::optional<Athena::Chrono> chronoSetTruthParams;
477 if constexpr (
enableBenchmark) chronoSetTruthParams.emplace(
"1st Stage: Set Track Parameters to Truth",
m_chrono.get());
478
479 for (FPGATrackSimTrack& track : tracks_1st) {
483 track.setQOverPt(truthtracks.front().getQOverPt());
485 track.setD0(truthtracks.front().getD0());
487 track.setPhi(truthtracks.front().getPhi());
489 track.setZ0(truthtracks.front().getZ0());
491 track.setEta(truthtracks.front().getEta());
492 }
493 }
497 }
498
499
500 for (auto const& road : roads_1st) {
501 FPGARoads_1st->push_back(road);
502 }
503
504
505 if (truthtracks.size() > 0) {
509 if (tracks_1st.size() > 0) {
512 }
513 }
514
515
516
517 for (auto itrack = tracks_1st.begin(); itrack != tracks_1st.end();) {
518 if (!
passesChi2Cut(*itrack)) itrack = tracks_1st.erase(itrack);
519 else ++itrack;
520 }
521
525
526 {
527
528 std::optional<Athena::Chrono> chronoOverlapRemoval2;
531
532 std::vector<const FPGATrackSimTrack*> tracks_1st_after_chi2;
533 std::vector<const FPGATrackSimTrack*> tracks_1st_after_overlap;
534 for (const FPGATrackSimTrack& track : tracks_1st) {
535 if (
track.passedOR()) {
536 tracks_1st_after_overlap.push_back(&track);
538 }
539 }
542 }
543
546
547 if (truthtracks.size() > 0) {
548
549 unsigned npasschi2(0);
550 unsigned npasschi2OLR(0);
551 if (tracks_1st.size() > 0) {
552 for (const auto& track : tracks_1st) {
553 npasschi2++;
554 if (
track.passedOR()) {
555 npasschi2OLR++;
556 }
557 }
558 }
563 }
564
565
567
568 for (const FPGATrackSimTrack& track : tracks_1st) {
569 FPGATracks_1stHandle->push_back(track);
570 }
571
572
573
574 std::vector<FPGATrackSimRoad> roadsLRT;
575 std::vector<FPGATrackSimTrack> tracksLRT;
577
578 std::vector<std::shared_ptr<const FPGATrackSimHit>> remainingHits;
579
581 ATH_MSG_DEBUG(
"Doing hit filtering based on prompt tracks.");
583
584 for (const auto &Hit : remainingHits) FPGAHitsFiltered_1st->push_back(new FPGATrackSimHit(*Hit));
585
586 } else {
587 ATH_MSG_DEBUG(
"No hit filtering requested; using all hits for LRT.");
588 remainingHits = std::move(phits_1st);
589 }
590
591
594 }
595
596 auto dataFlowInfo = std::make_unique<FPGATrackSimDataFlowInfo>();
597
598
601 }
602
603
606
607 SmartIF<IEventProcessor> appMgr{service("ApplicationMgr")};
608 if (!appMgr) {
609 ATH_MSG_ERROR(
"Failed to retrieve ApplicationMgr as IEventProcessor");
610 return StatusCode::FAILURE;
611 }
612
613
615 }
616
617
620
621 return StatusCode::SUCCESS;
622}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
void roadsToTrack(std::vector< FPGATrackSimRoad > &roads, std::vector< FPGATrackSimTrack > &track_cands, const FPGATrackSimPlaneMap *pmap)
ToolHandle< FPGATrackSimTrackMonitor > m_1st_stage_road_monitor
Gaudi::Property< int > m_region
Gaudi::Property< bool > m_filterRoads2
Gaudi::Property< bool > m_doTracking
FPGATrackSimLogicalEventInputHeader * m_slicedHitHeader
Gaudi::Property< bool > m_doLRT
ToolHandle< FPGATrackSimSpacePointsToolI > m_spacepointsTool
ToolHandle< FPGATrackSimOverlapRemovalTool > m_overlapRemovalTool_1st
Gaudi::Property< int > m_SetTruthParametersForTracks
ToolHandle< FPGATrackSimTrackMonitor > m_1st_stage_road_post_OLR_monitor
ToolHandle< FPGATrackSimSlicingEngineTool > m_slicingEngineTool
Gaudi::Property< bool > m_writeOutputData
ServiceHandle< IChronoStatSvc > m_chrono
Gaudi::Property< bool > m_doGNNPixelSeeding
FPGATrackSimLogicalEventInputHeader * m_slicedStripHeaderPreSP
SG::WriteHandleKey< ConstDataVector< FPGATrackSimHitCollection > > m_FPGAHitKey_1st
Gaudi::Property< bool > m_doGNNTrack
ToolHandle< FPGATrackSimHoughRootOutputTool > m_houghRootOutputTool
ToolHandle< FPGATrackSimTrackMonitor > m_1st_stage_road_post_filter_2_monitor
unsigned long m_maxNTracksTot
void MakeSeedTracks(std::vector< FPGATrackSimTrack > &tracks)
FPGATrackSimLogicalEventInputHeader * m_slicedFirstPixelHeader
Gaudi::Property< bool > m_doOverlapRemoval
Gaudi::Property< bool > m_doNNTrack
Gaudi::Property< bool > m_writeOutNonSPStripHits
Gaudi::Property< bool > m_noHitFilter
Gaudi::Property< bool > m_doSpacepoints
ToolHandle< IFPGATrackSimRoadFilterTool > m_roadFilterTool
Gaudi::Property< bool > m_outputRoadUnionTool
FPGATrackSimLogicalEventInputHeader * m_slicedSecondPixelHeader
SG::WriteHandleKey< FPGATrackSimRoadCollection > m_FPGARoadKey
ToolHandle< FPGATrackSimNNTrackTool > m_NNTrackTool
ToolHandle< FPGATrackSimLLPRoadFilterTool > m_LRTRoadFilterTool
Gaudi::Property< bool > m_filterRoads
bool passesChi2Cut(const FPGATrackSimTrack &track)
ToolHandle< IFPGATrackSimRoadFinderTool > m_LRTRoadFinderTool
ToolHandle< FPGATrackSimTrackMonitor > m_1st_stage_track_post_OLR_monitor
ToolHandle< FPGATrackSimOutputHeaderTool > m_writeOutputTool
ToolHandle< FPGATrackSimTrackMonitor > m_1st_stage_track_post_setTruth_monitor
SG::ReadHandleKey< FPGATrackSimHitCollection > m_FPGAHitKey
Gaudi::Property< bool > m_secondStageStrips
ToolHandle< FPGATrackSimTrackFitterTool > m_trackFitterTool_1st
Gaudi::Property< bool > m_doLRTHitFiltering
ToolHandle< IFPGATrackSimRoadFilterTool > m_roadFilterTool2
Gaudi::Property< bool > m_passLowestChi2TrackOnly
Gaudi::Property< bool > m_doHoughRootOutput1st
ToolHandle< FPGATrackSimTrackMonitor > m_1st_stage_track_post_chi2_monitor
ToolHandle< FPGATrackSimTrackMonitor > m_1st_stage_track_monitor
StatusCode writeOutputData(const std::vector< FPGATrackSimRoad > &roads_1st, std::vector< FPGATrackSimTrack > const &tracks_1st, FPGATrackSimDataFlowInfo const *dataFlowInfo)
FPGATrackSimLogicalEventOutputHeader * m_logicEventOutputHeader
SG::WriteHandleKey< FPGATrackSimClusterCollection > m_FPGASpacePointsKey
SG::WriteHandleKey< ConstDataVector< FPGATrackSimHitCollection > > m_FPGAHitKey_2nd
ToolHandle< FPGATrackSimTrackMonitor > m_1st_stage_road_post_filter_1_monitor
unsigned long m_maxNTracksChi2OLRTot
unsigned long m_maxNTracksChi2Tot
SG::ReadHandleKey< FPGATrackSimOfflineTrackCollection > m_FPGAOfflineTrackKey
long m_nTracksChi2OLRFound
ServiceHandle< IFPGATrackSimMappingSvc > m_FPGATrackSimMapping
ToolHandle< FPGATrackSimRoadUnionTool > m_roadFinderTool
SG::WriteHandleKey< FPGATrackSimTrackCollection > m_FPGATrackKey
Gaudi::Property< int > m_keepHitsStrategy
Gaudi::Property< int > m_writeRegion
ServiceHandle< IFPGATrackSimEventSelectionSvc > m_evtSel
Gaudi::Property< bool > m_doMultiTruth
SG::WriteHandleKey< FPGATrackSimHitCollection > m_FPGAHitFilteredKey
SG::ReadHandleKey< FPGATrackSimTruthTrackCollection > m_FPGATruthTrackKey
unsigned long m_maxNRoadsFound
SG::ReadHandleKey< FPGATrackSimEventInfo > m_FPGAEventInfoKey
FPGATrackSimLogicalEventInputHeader * m_slicedStripHeader
void setFPGATrackSimHit(unsigned i, std::shared_ptr< const FPGATrackSimHit > hit)
void setNLayers(int)
set the number of layers in the track.
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
constexpr bool enableBenchmark