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