ATLAS Offline Software
Loading...
Searching...
No Matches
FPGATrackSimLogicalHitsProcessAlg.cxx
Go to the documentation of this file.
1
2
3// Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
4
6
15
19
21
24
26
27#include "GaudiKernel/IEventProcessor.h"
28
29#include <algorithm>
30#include <vector>
31
32constexpr bool enableBenchmark =
33#ifdef BENCHMARK_FPGATRACKSIM
34 true;
35#else
36 false;
37#endif
38
40// Initialize
41
42FPGATrackSimLogicalHitsProcessAlg::FPGATrackSimLogicalHitsProcessAlg (const std::string& name, ISvcLocator* pSvcLocator) :
43 AthAlgorithm(name, pSvcLocator)
44{
45}
46
47
49{
50 // Dump the configuration to make sure it propagated through right
51 const std::vector<Gaudi::Details::PropertyBase*> props = this->getProperties();
52 for( Gaudi::Details::PropertyBase* prop : props ) {
53 if (prop->ownerTypeName()==this->type()) {
54 ATH_MSG_DEBUG("Property:\t" << prop->name() << "\t : \t" << prop->toString());
55 }
56 }
57
58 std::stringstream ss(m_description);
59 std::string line;
60 ATH_MSG_INFO("Tag config:");
61 if (!m_description.empty()) {
62 while (std::getline(ss, line, '\n')) {
63 ATH_MSG_INFO('\t' << line);
64 }
65 }
66 ATH_CHECK(m_roadFinderTool.retrieve());
67 ATH_CHECK(m_LRTRoadFilterTool.retrieve(EnableTool{m_doLRT}));
68 ATH_CHECK(m_LRTRoadFinderTool.retrieve(EnableTool{m_doLRT}));
69 ATH_CHECK(m_houghRootOutputTool.retrieve(EnableTool{m_doHoughRootOutput1st}));
70 ATH_CHECK(m_NNTrackTool.retrieve(EnableTool{m_doNNTrack}));
71 ATH_CHECK(m_roadFilterTool.retrieve(EnableTool{m_filterRoads}));
72 ATH_CHECK(m_roadFilterTool2.retrieve(EnableTool{m_filterRoads2}));
73
74 ATH_CHECK(m_spacepointsTool.retrieve(EnableTool{m_doSpacepoints}));
75
76 ATH_CHECK(m_trackFitterTool_1st.retrieve(EnableTool{m_doTracking}));
78 ATH_CHECK(m_writeOutputTool.retrieve());
81
82
96
97
98
99 ATH_MSG_DEBUG("initialize() Instantiating root objects");
100
101 // ROOT branches created for test vectors.
102 m_logicEventOutputHeader = m_writeOutputTool->addOutputBranch(m_outputBranch.value(), true);
103
105
106 // Updated slicing engine test vectors will have three streams.
110
111 // We also need a pre- and post- SP copy of the SPs.
113
114 // Connect the slicing tools accordingly. We probably no longer need to hook up the roadfinder here.
117
118 ATH_MSG_DEBUG("initialize() Setting branch");
119
120 if (!m_monTool.empty())
121 ATH_CHECK(m_monTool.retrieve());
122
123 ATH_CHECK( m_FPGASpacePointsKey.initialize() );
124 ATH_CHECK( m_FPGAHitInRoadsKey.initialize() );
125 ATH_CHECK( m_FPGAHitFilteredKey.initialize() );
126 ATH_CHECK( m_FPGARoadKey.initialize() );
127 ATH_CHECK( m_FPGATrackKey.initialize() );
128 ATH_CHECK( m_FPGAHitKey.initialize() );
129 ATH_CHECK( m_FPGAHitKey_1st.initialize() );
130 ATH_CHECK( m_FPGAHitKey_2nd.initialize() );
131 ATH_CHECK( m_FPGATruthTrackKey.initialize() );
132 ATH_CHECK( m_FPGAOfflineTrackKey.initialize() );
133 ATH_CHECK( m_FPGAEventInfoKey.initialize() );
134
135 ATH_CHECK( m_chrono.retrieve() );
136 ATH_MSG_DEBUG("initialize() Finished");
137
138 return StatusCode::SUCCESS;
139}
140
141
143// MAIN EXECUTE ROUTINE //
145
147{
148 const EventContext& ctx = getContext();
149
150 // Get reference to hits from StoreGate.
152 if (!FPGAHits.isValid()) {
153 if (m_evt == 0) {
154 ATH_MSG_WARNING("Didn't receive " << FPGAHits.key() << " on first event; assuming no input events.");
155 }
156 SmartIF<IEventProcessor> appMgr{service("ApplicationMgr")};
157 if (!appMgr) {
158 ATH_MSG_ERROR("Failed to retrieve ApplicationMgr as IEventProcessor");
159 return StatusCode::FAILURE;
160 }
161 return appMgr->stopRun();
162 }
163
164 // Set up write handles.
169
170 ATH_CHECK( FPGAHits_1st.record (std::make_unique<FPGATrackSimHitCollection>()));
171 ATH_CHECK( FPGAHits_2nd.record (std::make_unique<FPGATrackSimHitCollection>()));
172 ATH_CHECK( FPGARoads_1st.record (std::make_unique<FPGATrackSimRoadCollection>()));
173 ATH_CHECK( FPGAHitsInRoads_1st.record (std::make_unique<FPGATrackSimHitContainer>()));
174
176 ATH_CHECK(FPGATracks_1stHandle.record (std::make_unique<FPGATrackSimTrackCollection>()));
177
179 ATH_CHECK( FPGAHitsFiltered_1st.record (std::make_unique<FPGATrackSimHitCollection>()));
180
182 ATH_CHECK( FPGASpacePoints.record (std::make_unique<FPGATrackSimClusterCollection>()));
183
184 // Query the event selection service to make sure this event passed cuts.
185 if (!m_evtSel->getSelectedEvent()) {
186
187 // Potentially write the output data, now it's empty and reset, but this keeps things synchronized over trees
188 if (m_writeOutputData) {
189 std::vector<std::shared_ptr<const FPGATrackSimRoad>> roads_1st;
190 std::vector<FPGATrackSimTrack> tracks_1st;
191 auto dataFlowInfo = std::make_unique<FPGATrackSimDataFlowInfo>();
192 ATH_CHECK(writeOutputData(roads_1st, tracks_1st, dataFlowInfo.get()));
193 }
194
195 return StatusCode::SUCCESS;
196 }
197 ATH_MSG_INFO("Event accepted by: " << m_evtSel->name());
198 if ((m_writeRegion>=0)&&(m_writeRegion==m_evtSel->getRegionID())) {
199 m_writeOutputTool->activateEventOutput();
200 }
201
202 // Event passes cuts, count it. technically, DataPrep does this now.
203 m_evt++;
204
205 // Read event info structure. all we need this for is to propagate to our event info structures.
207 if (!FPGAEventInfo.isValid()) {
208 ATH_MSG_ERROR("Could not find FPGA Event Info with key " << FPGAEventInfo.key());
209 return StatusCode::FAILURE;
210 }
211 FPGATrackSimEventInfo eventInfo = *FPGAEventInfo.cptr();
212 m_slicedFirstPixelHeader->newEvent(eventInfo);
213 m_slicedSecondPixelHeader->newEvent(eventInfo);
214 m_slicedStripHeader->newEvent(eventInfo);
215 m_slicedStripHeaderPreSP->newEvent(eventInfo);
216
217 if constexpr (enableBenchmark) m_chrono->chronoStart("1st Stage: Split hits to 1st and 2nd stage");
218
219 std::vector<std::shared_ptr<const FPGATrackSimHit>> phits_output, phits_all, phits_1st, phits_2nd;
220 phits_1st.reserve(FPGAHits->size());
221 phits_2nd.reserve(FPGAHits->size());
222 ATH_MSG_DEBUG("Incoming Hits: " << FPGAHits->size());
223 for (const FPGATrackSimHit& hit : *(FPGAHits.cptr())) {
224 phits_all.emplace_back(&hit, [](const FPGATrackSimHit*){});
225 }
226
227 // Use the slicing engine tool to do the stage-based separation. Does not use the pmap.
228 m_slicingEngineTool->sliceHits(phits_all, phits_1st, phits_2nd);
229 // record 1st stage hits in SG
230 for (auto& hit : phits_1st) {
231 FPGAHits_1st->push_back(*hit);
232 }
233
235
236 // The slicing engine puts strip hits into a logical event input header. That header now needs to go
237 // to the spacepoint tool if it's turned on. Those hits then get added to phits_1st or phits_2nd as appropriate.
238 if (m_doSpacepoints) {
239 m_spacepoints.clear();
240 if constexpr (enableBenchmark) m_chrono->chronoStart("1st Stage: SP fornmation");
242 if constexpr (enableBenchmark) m_chrono->chronoStop("1st Stage: SP fornmation");
243 for (const FPGATrackSimCluster& cluster : m_spacepoints) FPGASpacePoints->push_back(cluster);
244 }
245
246 // Use a property to control whether the strips/SPs go to 1st or second stage.
247 for (const FPGATrackSimHit& hit : m_slicedStripHeader->towers().at(0).hits()) {
248 (m_secondStageStrips ? phits_2nd : phits_1st).emplace_back(&hit, [](const FPGATrackSimHit*){});
249 }
250 for (auto& hit : phits_2nd) {
251 FPGAHits_2nd->push_back(*hit);
252 }
253
254 // Add all hits including SPs to this for the HoughRootOutputTool
255 for (const FPGATrackSimHit& hit : *(FPGAHits_2nd.cptr())) {
256 phits_output.emplace_back(&hit, [](const FPGATrackSimHit*){});
257 }
258
259 if constexpr (enableBenchmark) m_chrono->chronoStop("1st Stage: Split hits to 1st and 2nd stage");
260 ATH_MSG_DEBUG("1st stage hits: " << phits_1st.size() << " 2nd stage hits: " << phits_2nd.size() );
261 if (phits_1st.empty()) return StatusCode::SUCCESS;
262 // Get truth tracks from DataPrep as well.
264 if (!FPGATruthTracks.isValid()) {
265 ATH_MSG_ERROR("Could not find FPGA Truth Track Collection with key " << FPGATruthTracks.key());
266 return StatusCode::FAILURE;
267 }
268
269 // Same for offline tracks.
271 if (!FPGAOfflineTracks.isValid()) {
272 ATH_MSG_ERROR("Could not find FPGA Offline Track Collection with key " << FPGAOfflineTracks.key());
273 return StatusCode::FAILURE;
274 }
275
276
278 // roads //
280
282 const std::vector<FPGATrackSimTruthTrack>& truthtracks = *FPGATruthTracks;
284 auto nLogicalLayers = m_FPGATrackSimMapping->PlaneMap_1st(0)->getNLogiLayers();
287 auto monitorRoads = [&](auto& monitor, const auto& roads) {
288 if (!monitor.empty()) {
289 monitor->fillRoad(roads, truthtracks, nLogicalLayers);
290 }
291 };
292
293
294 if constexpr (enableBenchmark) m_chrono->chronoStart("1st Stage: GetRoads");
295 // get roads
296 std::vector<std::shared_ptr<const FPGATrackSimRoad>> roads_1st;
297 ATH_CHECK(m_roadFinderTool->getRoads(phits_1st, roads_1st, *(FPGATruthTracks.cptr())));
298 monitorRoads(m_1st_stage_road_monitor, roads_1st);
299 if constexpr (enableBenchmark) m_chrono->chronoStop("1st Stage: GetRoads");
300
301
302
303 // Standard road Filter
304 if constexpr (enableBenchmark) m_chrono->chronoStart("1st Stage: RoadFiltering");
305 std::vector<std::shared_ptr<const FPGATrackSimRoad>> postfilter_roads;
306 if (m_filterRoads) {
307 ATH_CHECK(m_roadFilterTool->filterRoads(roads_1st, postfilter_roads));
308 roads_1st = std::move(postfilter_roads);
309 }
311 monitorRoads(m_1st_stage_road_post_filter_1_monitor, roads_1st);
312 if constexpr (enableBenchmark) m_chrono->chronoStop("1st Stage: RoadFiltering");
313
314
315 // overlap removal
316 if constexpr (enableBenchmark) m_chrono->chronoStart("1st Stage: OverlapRemoval");
317 if (m_doOverlapRemoval) ATH_CHECK(m_overlapRemovalTool_1st->runOverlapRemoval(roads_1st));
319 monitorRoads(m_1st_stage_road_post_OLR_monitor, roads_1st);
320 if constexpr (enableBenchmark) m_chrono->chronoStop("1st Stage: OverlapRemoval");
321
322
323 // Road Filter2
324 if constexpr (enableBenchmark) m_chrono->chronoStart("1st Stage: RoadFiltering2");
325 std::vector<std::shared_ptr<const FPGATrackSimRoad>> postfilter2_roads;
326 if (m_filterRoads2) {
327 ATH_CHECK(m_roadFilterTool2->filterRoads(roads_1st, postfilter2_roads));
328 roads_1st = std::move(postfilter2_roads);
329 }
331 monitorRoads(m_1st_stage_road_post_filter_2_monitor, roads_1st);
332 if constexpr (enableBenchmark) m_chrono->chronoStop("1st Stage: RoadFiltering2");
333
334
336 // tracks //
338
340 auto monitorTracks = [&](auto& monitor, const auto& tracks) {
341 if (monitor.empty()) return;
342 // prepare vector<const FPGATrackSimTrack*> regardless of input type
343 std::vector<const FPGATrackSimTrack*> track_ptrs;
344 track_ptrs.reserve(tracks.size());
345 // transform tracks into a vector of pointers
346 if constexpr (std::is_pointer_v<typename std::decay_t<decltype(tracks)>::value_type>) {
347 // tracks is std::vector<const FPGATrackSimTrack*>
348 track_ptrs.insert(track_ptrs.end(), tracks.begin(), tracks.end());
349 } else {
350 // tracks is std::vector<FPGATrackSimTrack>
351 std::transform(tracks.begin(), tracks.end(), std::back_inserter(track_ptrs), [](const auto& t) { return &t; });
352 }
353 // monitor using track pointers
354 monitor->fillTrack(track_ptrs, truthtracks, 1.e15);
355 };
356
357 // Get tracks
358 if constexpr (enableBenchmark) m_chrono->chronoStart("1st Stage: Getting Tracks");
359 std::vector<FPGATrackSimTrack> tracks_1st;
360 if (m_doTracking) {
361 if (m_doNNTrack) {
362 ATH_MSG_DEBUG("Performing NN tracking");
363 ATH_CHECK(m_NNTrackTool->getTracks_1st(roads_1st, tracks_1st));
364 if (m_doGNNTrack) {
365 ATH_MSG_DEBUG("Performing track parameter estimation");
366 ATH_CHECK(m_NNTrackTool->setTrackParameters(tracks_1st,true,m_evtSel->getMin(), m_evtSel->getMax()));
367 }
368 } else {
369 ATH_MSG_DEBUG("Performing Linear tracking");
370 if (m_passLowestChi2TrackOnly) { // Pass only the lowest chi2 track per road
371 // Loop over roads and keep only the best track for each road
372 for (const auto& road : roads_1st) {
373 std::vector<FPGATrackSimTrack> tracksForCurrentRoad;
374
375 // Collect tracks for this road
376 std::vector<std::shared_ptr<const FPGATrackSimRoad>> roadVec = {road};
377 ATH_CHECK(m_trackFitterTool_1st->getTracks(roadVec, tracksForCurrentRoad, m_evtSel->getMin(), m_evtSel->getMax()));
378
379 // Find the best track for this road
380 if (!tracksForCurrentRoad.empty()) {
381 auto bestTrackIter = std::min_element(
382 tracksForCurrentRoad.begin(), tracksForCurrentRoad.end(),
383 [](const FPGATrackSimTrack& a, const FPGATrackSimTrack& b) {
384 return a.getChi2ndof() < b.getChi2ndof();
385 });
386
387 if (bestTrackIter != tracksForCurrentRoad.end() && bestTrackIter->getChi2ndof() < 1.e15) {
388 tracks_1st.push_back(*bestTrackIter);
389 }
390 }
391 }
392 } else { // Pass all tracks with chi2 < 1e15
393 ATH_CHECK(m_trackFitterTool_1st->getTracks(roads_1st, tracks_1st, m_evtSel->getMin(), m_evtSel->getMax()));
394 }
395 }
396 } else { // No tracking;
397 ATH_MSG_DEBUG("No tracking. Just running dummy road2track algorith");
398 if(m_doGNNPixelSeeding) { //For GNNPixelSeeding, convert the roads to a track in the simplest form
399 for (const std::shared_ptr<const FPGATrackSimRoad>& road : roads_1st) {
400 std::vector<std::shared_ptr<const FPGATrackSimHit>> track_hits;
401 for (unsigned layer = 0; layer < road->getNLayers(); ++layer) {
402 track_hits.insert(track_hits.end(), road->getHits(layer).begin(), road->getHits(layer).end());
403 }
404
405 FPGATrackSimTrack track_cand;
406 track_cand.setNLayers(track_hits.size());
407 for (size_t ihit = 0; ihit < track_hits.size(); ++ihit) {
408 track_cand.setFPGATrackSimHit(ihit, *(track_hits[ihit]));
409 }
410 tracks_1st.push_back(track_cand);
411 }
412 }
413 else { roadsToTrack(roads_1st, tracks_1st, m_FPGATrackSimMapping->PlaneMap_1st(0)); }
414 }
415
416 // calculateTruth() before any monitors
417 // this explicitly calculates barcode, barcodeFrac and eventIndex
418 ATH_MSG_DEBUG("doMultiTruth = " << m_doMultiTruth);
419 if (m_doMultiTruth)
420 for (auto &track : tracks_1st)
421 track.calculateTruth();
422
425 monitorTracks(m_1st_stage_track_monitor, tracks_1st);
426 if constexpr (enableBenchmark) m_chrono->chronoStop("1st Stage: Getting Tracks");
427
428
429 // set track parameters to truth
430 if constexpr (enableBenchmark) m_chrono->chronoStart("1st Stage: Set Track Parameters to Truth");
431 //Loop over tracks and set the region for all of them, also optionally set track parameters to truth
432 for (FPGATrackSimTrack& track : tracks_1st) {
433 track.setRegion(m_region);
434 if (m_SetTruthParametersForTracks >= 0 && truthtracks.size() > 0) {
436 track.setQOverPt(truthtracks.front().getQOverPt());
437 else if (m_SetTruthParametersForTracks != 1)
438 track.setD0(truthtracks.front().getD0());
439 else if (m_SetTruthParametersForTracks != 2)
440 track.setPhi(truthtracks.front().getPhi());
441 else if (m_SetTruthParametersForTracks != 3)
442 track.setZ0(truthtracks.front().getZ0());
443 else if (m_SetTruthParametersForTracks != 4)
444 track.setEta(truthtracks.front().getEta());
445 }
446 }
449 monitorTracks(m_1st_stage_track_post_setTruth_monitor, tracks_1st);
450 if constexpr (enableBenchmark) m_chrono->chronoStop("1st Stage: Set Track Parameters to Truth");
451
452 // Loop over roads and store them in SG (after track finding to also copy the sector information)
453 for (auto const& road : roads_1st) {
454 std::vector<FPGATrackSimHit> road_hits;
455 ATH_MSG_DEBUG("Hough Road X Y: " << road->getX() << " " << road->getY());
456 for (size_t l = 0; l < road->getNLayers(); ++l) {
457 for (const auto& layerH : road->getHits(l)) {
458 road_hits.push_back(*layerH);
459 }
460 }
461 FPGAHitsInRoads_1st->push_back(std::move(road_hits));
462 FPGARoads_1st->push_back(*road);
463 }
464
465 // overlap removal
466 if constexpr (enableBenchmark) m_chrono->chronoStart("1st Stage: OverlapRemoval");
467 if (m_doOverlapRemoval) ATH_CHECK(m_overlapRemovalTool_1st->runOverlapRemoval(tracks_1st));
468 // monitor variables (vectors of pointers)
469 std::vector<const FPGATrackSimTrack*> tracks_1st_after_chi2;
470 std::vector<const FPGATrackSimTrack*> tracks_1st_after_overlap;
471 for (const FPGATrackSimTrack& track : tracks_1st) {
472 if (track.getChi2ndof() < m_trackScoreCut.value()) {
474 tracks_1st_after_chi2.push_back(&track);
475 if (track.passedOR()) {
476 tracks_1st_after_overlap.push_back(&track);
478 }
479 }
480 }
482 monitorTracks(m_1st_stage_track_post_chi2_monitor, tracks_1st_after_chi2);
484 monitorTracks(m_1st_stage_track_post_OLR_monitor, tracks_1st_after_overlap);
485 if constexpr (enableBenchmark) m_chrono->chronoStop("1st Stage: OverlapRemoval");
486
487 m_nRoadsTot += roads_1st.size();
488 m_nTracksTot += tracks_1st.size();
489
490 // Do some simple monitoring of efficiencies. okay, we need truth tracks here.
491 if (truthtracks.size() > 0) {
492 m_evt_truth++;
493 if (roads_1st.size() > 0) m_nRoadsFound++;
494 if (roads_1st.size() > m_maxNRoadsFound) m_maxNRoadsFound = roads_1st.size();
495
496 unsigned npasschi2(0);
497 unsigned npasschi2OLR(0);
498 if (tracks_1st.size() > 0) {
500 if (tracks_1st.size() > m_maxNTracksTot) m_maxNTracksTot = tracks_1st.size();
501 for (const auto& track : tracks_1st) {
502 if (track.getChi2ndof() < m_trackScoreCut.value()) {
503 npasschi2++;
504 if (track.passedOR()) {
505 npasschi2OLR++;
506 }
507 }
508 }
509 }
510 if (npasschi2 > m_maxNTracksChi2Tot) m_maxNTracksChi2Tot = npasschi2;
511 if (npasschi2OLR > m_maxNTracksChi2OLRTot) m_maxNTracksChi2OLRTot = npasschi2OLR;
512 if (npasschi2 > 0) m_nTracksChi2Found++;
513 if (npasschi2OLR > 0) m_nTracksChi2OLRFound++;
514 }
515
516 for (const FPGATrackSimTrack& track : tracks_1st) FPGATracks_1stHandle->push_back(track);
517
518 // Now, we may want to do large-radius tracking on the hits not used by the first stage tracking.
519 // This follows overlap removal.
520 std::vector<std::shared_ptr<const FPGATrackSimRoad>> roadsLRT;
521 std::vector<FPGATrackSimTrack> tracksLRT; // currently empty
522 if (m_doLRT) {
523 // Filter out hits that are on successful first-stage tracks
524 std::vector<std::shared_ptr<const FPGATrackSimHit>> remainingHits;
525
527 ATH_MSG_DEBUG("Doing hit filtering based on prompt tracks.");
528 ATH_CHECK(m_LRTRoadFilterTool->filterUsedHits(tracks_1st, phits_1st, remainingHits));
529
530 for (const auto &Hit : remainingHits) FPGAHitsFiltered_1st->push_back(*Hit);
531
532 } else {
533 ATH_MSG_DEBUG("No hit filtering requested; using all hits for LRT.");
534 remainingHits = std::move(phits_1st);
535 }
536
537 // Get LRT roads with remaining hits
538 ATH_MSG_DEBUG("Finding LRT roads");
539 ATH_CHECK(m_LRTRoadFinderTool->getRoads( remainingHits, roadsLRT ));
540 }
541
542 auto dataFlowInfo = std::make_unique<FPGATrackSimDataFlowInfo>();
543
544 // Write the output and reset
545 if (m_writeOutputData) {
546 ATH_CHECK(writeOutputData(roads_1st, tracks_1st, dataFlowInfo.get()));
547 }
548
549 // This one we can do-- by passing in truth and offline tracks via storegate above (*FPGAOfflineTracks).
551 ATH_MSG_DEBUG("Running HoughRootOutputTool in 1st stage.");
552
553 SmartIF<IEventProcessor> appMgr{service("ApplicationMgr")};
554 if (!appMgr) {
555 ATH_MSG_ERROR("Failed to retrieve ApplicationMgr as IEventProcessor");
556 return StatusCode::FAILURE;
557 }
558
559 // Create output ROOT file
560 ATH_CHECK(m_houghRootOutputTool->fillTree(tracks_1st, truthtracks, *FPGAOfflineTracks, phits_output, m_writeOutNonSPStripHits, false));
561 }
562
563 // Reset data pointers
566
567 return StatusCode::SUCCESS;
568}
569
570
572// INPUT PASSING, READING AND PROCESSING //
574
575StatusCode FPGATrackSimLogicalHitsProcessAlg::writeOutputData( const std::vector<std::shared_ptr<const FPGATrackSimRoad>>& roads_1st,
576 std::vector<FPGATrackSimTrack> const& tracks_1st,
577 FPGATrackSimDataFlowInfo const* dataFlowInfo)
578{
580
581 ATH_MSG_DEBUG("NFPGATrackSimRoads_1st = " << roads_1st.size() << ", NFPGATrackSimTracks_1st = " << tracks_1st.size());
582
583 if (!m_writeOutputData) return StatusCode::SUCCESS;
584 m_logicEventOutputHeader->reserveFPGATrackSimRoads_1st(roads_1st.size());
585 m_logicEventOutputHeader->addFPGATrackSimRoads_1st(roads_1st);
586
587 m_logicEventOutputHeader->reserveFPGATrackSimTracks_1st(tracks_1st.size());
588 m_logicEventOutputHeader->addFPGATrackSimTracks_1st(tracks_1st);
589
590 m_logicEventOutputHeader->setDataFlowInfo(*dataFlowInfo);
591 ATH_MSG_DEBUG(m_logicEventOutputHeader->getDataFlowInfo());
592
593 // It would be nice to rearrange this so both algorithms use one instance of this tool, I think.
594 // Which means that dataprep can't call writeData because that does Fill().
595 ATH_CHECK(m_writeOutputTool->writeData());
596
597
598
599 return StatusCode::SUCCESS;
600}
601
602
604// Finalize
605
607{
608 ATH_MSG_INFO("PRINTING FPGATRACKSIM SIMPLE STATS");
609 ATH_MSG_INFO("========================================================================================");
610 ATH_MSG_INFO("Ran on events = " << m_evt);
611 ATH_MSG_INFO("Inclusive efficiency to find a road = " << (m_evt_truth == 0 ? "NAN" : std::to_string(m_nRoadsFound/(float)m_evt_truth)));
612 ATH_MSG_INFO("Inclusive efficiency to find a track = " << (m_evt_truth == 0 ? "NAN" : std::to_string(m_nTracksFound/(float)m_evt_truth)));
613 ATH_MSG_INFO("Inclusive efficiency to find a track passing chi2 = " << (m_evt_truth == 0 ? "NAN" : std::to_string(m_nTracksChi2Found/(float)m_evt_truth)));
614 ATH_MSG_INFO("Inclusive efficiency to find a track passing chi2 and OLR = " << (m_evt_truth == 0 ? "NAN" : std::to_string(m_nTracksChi2OLRFound/(float)m_evt_truth)));
615
616
617 ATH_MSG_INFO("Number of 1st stage roads/event = " << (m_evt == 0 ? "NAN" : std::to_string(m_nRoadsTot/(float)m_evt)));
618 ATH_MSG_INFO("Number of 1st stage track combinations/event = " << (m_evt == 0 ? "NAN" : std::to_string(m_nTracksTot/(float)m_evt)));
619 ATH_MSG_INFO("Number of 1st stage tracks passing chi2/event = " << (m_evt == 0 ? "NAN" : std::to_string(m_nTracksChi2Tot/(float)m_evt)));
620 ATH_MSG_INFO("Number of 1st stage tracks passing chi2 and OLR/event = " << (m_evt == 0 ? "NAN" : std::to_string(m_nTracksChi2OLRTot/(float)m_evt)));
621 ATH_MSG_INFO("========================================================================================");
622
623 ATH_MSG_INFO("Max number of 1st stage roads in an event = " << m_maxNRoadsFound);
624 ATH_MSG_INFO("Max number of 1st stage track combinations in an event = " << m_maxNTracksTot);
625 ATH_MSG_INFO("Max number of 1st stage tracks passing chi2 in an event = " << m_maxNTracksChi2Tot);
626 ATH_MSG_INFO("Max number of 1st stage tracks passing chi2 and OLR in an event = " << m_maxNTracksChi2OLRTot);
627 ATH_MSG_INFO("========================================================================================");
628
629 return StatusCode::SUCCESS;
630}
631
632
634// Helpers
635
636void FPGATrackSimLogicalHitsProcessAlg::printHitSubregions(std::vector<FPGATrackSimHit> const & hits)
637{
638 ATH_MSG_WARNING("Hit regions:");
639 for (const auto& hit : hits)
640 {
641 std::vector<uint32_t> regions = m_FPGATrackSimMapping->SubRegionMap()->getRegions(hit);
642 std::stringstream ss;
643 for (auto r : regions)
644 ss << r << ",";
645 ATH_MSG_WARNING("\t[" << ss.str() << "]");
646 }
647}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Structs that store the data flow information per event.
: FPGATrackSim-specific class to represent an hit in the detector.
void roadsToTrack(std::vector< std::shared_ptr< const FPGATrackSimRoad > > &roads, std::vector< FPGATrackSimTrack > &track_cands, const FPGATrackSimPlaneMap *pmap)
Utilize NN score to build track candidates.
Overlap removal tool for FPGATrackSimTrack.
Maps ITK module indices to FPGATrackSim regions.
Stores slice definitions for FPGATrackSim regions.
Defines a class for roads.
Structs that store the 5 track parameters.
static Double_t a
static Double_t ss
static const std::vector< std::string > regions
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
ToolHandle< FPGATrackSimTrackMonitor > m_1st_stage_road_monitor
Gaudi::Property< std::string > m_sliceSecondPixelBranch
FPGATrackSimLogicalEventInputHeader * m_slicedHitHeader
ToolHandle< FPGATrackSimSpacePointsToolI > m_spacepointsTool
ToolHandle< FPGATrackSimOverlapRemovalTool > m_overlapRemovalTool_1st
SG::WriteHandleKey< FPGATrackSimHitCollection > m_FPGAHitKey_2nd
ToolHandle< GenericMonitoringTool > m_monTool
ToolHandle< FPGATrackSimTrackMonitor > m_1st_stage_road_post_OLR_monitor
ToolHandle< FPGATrackSimSlicingEngineTool > m_slicingEngineTool
Gaudi::Property< std::string > m_sliceStripBranchPreSP
FPGATrackSimLogicalEventInputHeader * m_slicedStripHeaderPreSP
ToolHandle< FPGATrackSimHoughRootOutputTool > m_houghRootOutputTool
ToolHandle< FPGATrackSimTrackMonitor > m_1st_stage_road_post_filter_2_monitor
FPGATrackSimLogicalEventInputHeader * m_slicedFirstPixelHeader
ToolHandle< IFPGATrackSimRoadFilterTool > m_roadFilterTool
StatusCode writeOutputData(const std::vector< std::shared_ptr< const FPGATrackSimRoad > > &roads_1st, std::vector< FPGATrackSimTrack > const &tracks_1st, FPGATrackSimDataFlowInfo const *dataFlowInfo)
FPGATrackSimLogicalEventInputHeader * m_slicedSecondPixelHeader
SG::WriteHandleKey< FPGATrackSimRoadCollection > m_FPGARoadKey
ToolHandle< FPGATrackSimNNTrackTool > m_NNTrackTool
ToolHandle< FPGATrackSimLLPRoadFilterTool > m_LRTRoadFilterTool
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< std::string > m_sliceFirstPixelBranch
ToolHandle< FPGATrackSimTrackFitterTool > m_trackFitterTool_1st
ToolHandle< IFPGATrackSimRoadFilterTool > m_roadFilterTool2
ToolHandle< FPGATrackSimTrackMonitor > m_1st_stage_track_post_chi2_monitor
ToolHandle< FPGATrackSimTrackMonitor > m_1st_stage_track_monitor
FPGATrackSimLogicalEventOutputHeader * m_logicEventOutputHeader
SG::WriteHandleKey< FPGATrackSimClusterCollection > m_FPGASpacePointsKey
ToolHandle< FPGATrackSimTrackMonitor > m_1st_stage_road_post_filter_1_monitor
SG::WriteHandleKey< FPGATrackSimHitContainer > m_FPGAHitInRoadsKey
SG::ReadHandleKey< FPGATrackSimOfflineTrackCollection > m_FPGAOfflineTrackKey
ServiceHandle< IFPGATrackSimMappingSvc > m_FPGATrackSimMapping
ToolHandle< FPGATrackSimRoadUnionTool > m_roadFinderTool
void printHitSubregions(std::vector< FPGATrackSimHit > const &hits)
SG::WriteHandleKey< FPGATrackSimHitCollection > m_FPGAHitKey_1st
SG::WriteHandleKey< FPGATrackSimTrackCollection > m_FPGATrackKey
ServiceHandle< IFPGATrackSimEventSelectionSvc > m_evtSel
std::vector< FPGATrackSimCluster > m_spacepoints
FPGATrackSimLogicalHitsProcessAlg(const std::string &name, ISvcLocator *pSvcLocator)
SG::WriteHandleKey< FPGATrackSimHitCollection > m_FPGAHitFilteredKey
SG::ReadHandleKey< FPGATrackSimTruthTrackCollection > m_FPGATruthTrackKey
SG::ReadHandleKey< FPGATrackSimEventInfo > m_FPGAEventInfoKey
FPGATrackSimLogicalEventInputHeader * m_slicedStripHeader
void setNLayers(int)
set the number of layers in the track.
void setFPGATrackSimHit(unsigned i, const FPGATrackSimHit &hit)
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
virtual const std::string & key() const override final
Return the StoreGate ID for the referenced object.
const_pointer_type cptr() const
Dereference the pointer.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
int r
Definition globals.cxx:22
constexpr bool enableBenchmark