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 // Use ConstDataVector with VIEW_ELEMENTS for non-owning const pointer storage
175 auto* FPGAHits_1st_cdv = FPGAHits_1st.ptr();
176 auto* FPGAHits_2nd_cdv = FPGAHits_2nd.ptr();
177
178 ATH_CHECK( FPGARoads_1st.record (std::make_unique<FPGATrackSimRoadCollection>()));
179 ATH_CHECK( FPGAHitsInRoads_1st.record (std::make_unique<FPGATrackSimHitContainer>()));
180
182 ATH_CHECK(FPGATracks_1stHandle.record (std::make_unique<FPGATrackSimTrackCollection>()));
183
185 ATH_CHECK( FPGAHitsFiltered_1st.record (std::make_unique<FPGATrackSimHitCollection>()));
186
188 ATH_CHECK( FPGASpacePoints.record (std::make_unique<FPGATrackSimClusterCollection>()));
189
190 // Query the event selection service to make sure this event passed cuts.
191 if (!m_evtSel->getSelectedEvent()) {
192
193 // Potentially write the output data, now it's empty and reset, but this keeps things synchronized over trees
194 if (m_writeOutputData) {
195 std::vector<FPGATrackSimRoad> roads_1st;
196 std::vector<FPGATrackSimTrack> tracks_1st;
197 auto dataFlowInfo = std::make_unique<FPGATrackSimDataFlowInfo>();
198 ATH_CHECK(writeOutputData(roads_1st, tracks_1st, dataFlowInfo.get()));
199 }
200
201 return StatusCode::SUCCESS;
202 }
203 ATH_MSG_INFO("Event accepted by: " << m_evtSel->name());
204 if ((m_writeRegion>=0)&&(m_writeRegion==m_evtSel->getRegionID())) {
205 m_writeOutputTool->activateEventOutput();
206 }
207
208 // Event passes cuts, count it. technically, DataPrep does this now.
209 m_evt++;
210
211 // Read event info structure. all we need this for is to propagate to our event info structures.
213 if (!FPGAEventInfo.isValid()) {
214 ATH_MSG_ERROR("Could not find FPGA Event Info with key " << FPGAEventInfo.key());
215 return StatusCode::FAILURE;
216 }
217 FPGATrackSimEventInfo eventInfo = *FPGAEventInfo.cptr();
218 m_slicedFirstPixelHeader->newEvent(eventInfo);
219 m_slicedSecondPixelHeader->newEvent(eventInfo);
220 m_slicedStripHeader->newEvent(eventInfo);
221 m_slicedStripHeaderPreSP->newEvent(eventInfo);
222
223 std::vector<std::shared_ptr<const FPGATrackSimHit>> phits_output, phits_all, phits_1st, phits_2nd;
224 std::vector<const FPGATrackSimHit*> phits_strips; // this should store pointers to strip hits for this region
225
226 {
227 std::optional<Athena::Chrono> chronoSplitHits;
228 if constexpr (enableBenchmark) chronoSplitHits.emplace("1st Stage: Split hits to 1st and 2nd stage", m_chrono.get());
229
230 phits_1st.reserve(FPGAHits->size());
231 phits_2nd.reserve(FPGAHits->size());
232 ATH_MSG_DEBUG("Incoming Hits: " << FPGAHits->size());
233 for (const FPGATrackSimHit* hit : *(FPGAHits.cptr())) {
234 phits_all.emplace_back(hit, [](const FPGATrackSimHit*) {});
235 }
236
237 // Use the slicing engine tool to do the stage-based separation. Does not use the pmap.
238 m_slicingEngineTool->sliceHits(phits_all, phits_1st, phits_2nd, phits_strips);
239 }
240
241 // record 1st stage hits in SG (VIEW_ELEMENTS - no copy, just store pointers)
242 for (auto& hit : phits_1st) {
243 FPGAHits_1st_cdv->push_back(hit.get());
244 }
245
247
248 // The slicing engine puts strip hits into a logical event input header. That header now needs to go
249 // to the spacepoint tool if it's turned on. Those hits then get added to phits_1st or phits_2nd as appropriate.
250 if (m_doSpacepoints) {
251 std::vector<FPGATrackSimCluster> spacepoints;
252 std::optional<Athena::Chrono> chronoSPFormation;
253 if constexpr (enableBenchmark) chronoSPFormation.emplace("1st Stage: SP formation", m_chrono.get());
254 ATH_CHECK(m_spacepointsTool->DoSpacePoints(*m_slicedStripHeader, spacepoints));
255 // Move spacepoints into the output container to avoid unnecessary copies
256 for (FPGATrackSimCluster& cluster : spacepoints) {
257 FPGASpacePoints->push_back(std::move(cluster));
258 }
259
260 // Add spacepoint hits to appropriate stage (using FPGASpacePoints directly from StoreGate)
261 for (const auto& cluster : *FPGASpacePoints) {
262 // Keep the exact constituent hits of the spacepoint (not just the cluster-equivalent summary)
263 for (const auto& hit : cluster.getHitList()) {
264 (m_secondStageStrips ? phits_2nd : phits_1st).emplace_back(&hit, [](const FPGATrackSimHit*){});
265 }
266 }
267 } else {
268 // If spacepoints are disabled, add strip hits from phits_strips (filled by slicing engine)
269 // These pointers point to hits in FPGAHits, which has stable lifetime in StoreGate
270 for (const FPGATrackSimHit* hit : phits_strips) {
271 (m_secondStageStrips ? phits_2nd : phits_1st).emplace_back(hit, [](const FPGATrackSimHit*){});
272 }
273 }
274
275 // VIEW_ELEMENTS - no copy, just store pointers
276 for (auto& hit : phits_2nd) {
277 FPGAHits_2nd_cdv->push_back(hit.get());
278 }
279
280 // Add all hits including SPs to this for the HoughRootOutputTool
281 for (const FPGATrackSimHit* hit : *(FPGAHits_2nd.cptr())) {
282 phits_output.emplace_back(hit, [](const FPGATrackSimHit*){});
283 }
284 ATH_MSG_DEBUG("1st stage hits: " << phits_1st.size() << " 2nd stage hits: " << phits_2nd.size() );
285 if (phits_1st.empty()) return StatusCode::SUCCESS;
286 // Get truth tracks from DataPrep as well.
288 if (!FPGATruthTracks.isValid()) {
289 ATH_MSG_ERROR("Could not find FPGA Truth Track Collection with key " << FPGATruthTracks.key());
290 return StatusCode::FAILURE;
291 }
292
293 // Same for offline tracks.
295 if (!FPGAOfflineTracks.isValid()) {
296 ATH_MSG_ERROR("Could not find FPGA Offline Track Collection with key " << FPGAOfflineTracks.key());
297 return StatusCode::FAILURE;
298 }
299
300
302 // roads //
304
306 const std::vector<FPGATrackSimTruthTrack>& truthtracks = *FPGATruthTracks;
308 auto nLogicalLayers = m_FPGATrackSimMapping->PlaneMap_1st(0)->getNLogiLayers();
311 auto monitorRoads = [&](auto& monitor, const auto& roads) {
312 if (!monitor.empty()) {
313 monitor->fillRoad(roads, truthtracks, nLogicalLayers);
314 }
315 };
316
317 std::vector<FPGATrackSimRoad> roads_1st;
318 {
319 std::optional<Athena::Chrono> chronoGetRoads;
320 if constexpr (enableBenchmark) chronoGetRoads.emplace("1st Stage: GetRoads", m_chrono.get());
321 // get roads
322 ATH_CHECK(m_roadFinderTool->getRoads(phits_1st, roads_1st, *(FPGATruthTracks.cptr())));
323 monitorRoads(m_1st_stage_road_monitor, roads_1st);
324 }
325
326
327 {
328 // Standard road Filter
329 std::optional<Athena::Chrono> chronoRoadFiltering;
330 if constexpr (enableBenchmark) chronoRoadFiltering.emplace("1st Stage: RoadFiltering", m_chrono.get());
331 std::vector<FPGATrackSimRoad> postfilter_roads;
332 if (m_filterRoads) {
333 ATH_CHECK(m_roadFilterTool->filterRoads(roads_1st, postfilter_roads));
334 roads_1st = std::move(postfilter_roads);
335 }
337 monitorRoads(m_1st_stage_road_post_filter_1_monitor, roads_1st);
338 }
339
340
341 {
342 // overlap removal
343 std::optional<Athena::Chrono> chronoOverlapRemoval;
344 if constexpr (enableBenchmark) chronoOverlapRemoval.emplace("1st Stage: OverlapRemoval", m_chrono.get());
345 if (m_doOverlapRemoval) ATH_CHECK(m_overlapRemovalTool_1st->runOverlapRemoval(roads_1st));
347 monitorRoads(m_1st_stage_road_post_OLR_monitor, roads_1st);
348 }
349
350
351 {
352 // Road Filter2
353 std::optional<Athena::Chrono> chronoRoadFiltering2;
354 if constexpr (enableBenchmark) chronoRoadFiltering2.emplace("1st Stage: RoadFiltering2", m_chrono.get());
355 std::vector<FPGATrackSimRoad> postfilter2_roads;
356 if (m_filterRoads2) {
357 ATH_CHECK(m_roadFilterTool2->filterRoads(roads_1st, postfilter2_roads));
358 roads_1st = std::move(postfilter2_roads);
359 }
361 monitorRoads(m_1st_stage_road_post_filter_2_monitor, roads_1st);
362 }
363
364
366 // tracks //
368
370 auto monitorTracks = [&](auto& monitor, const auto& tracks) {
371 if (monitor.empty()) return;
372 // prepare vector<const FPGATrackSimTrack*> regardless of input type
373 std::vector<const FPGATrackSimTrack*> track_ptrs;
374 track_ptrs.reserve(tracks.size());
375 // transform tracks into a vector of pointers
376 if constexpr (std::is_pointer_v<typename std::decay_t<decltype(tracks)>::value_type>) {
377 // tracks is std::vector<const FPGATrackSimTrack*>
378 track_ptrs.insert(track_ptrs.end(), tracks.begin(), tracks.end());
379 } else {
380 // tracks is std::vector<FPGATrackSimTrack>
381 std::transform(tracks.begin(), tracks.end(), std::back_inserter(track_ptrs), [](const auto& t) { return &t; });
382 }
383 // monitor using track pointers
384 monitor->fillTrack(track_ptrs, truthtracks, 1.e15);
385 };
386
387 std::vector<FPGATrackSimTrack> tracks_1st;
388 {
389 // Get tracks
390 std::optional<Athena::Chrono> chronoGettingTracks;
391 if constexpr (enableBenchmark) chronoGettingTracks.emplace("1st Stage: Getting Tracks", m_chrono.get());
392 if (m_doTracking) {
393 if (m_doNNTrack) {
394 ATH_MSG_DEBUG("Performing NN tracking");
395 ATH_CHECK(m_NNTrackTool->getTracks_1st(roads_1st, tracks_1st));
396 if (m_doGNNTrack) {
397 ATH_MSG_DEBUG("Performing track parameter estimation");
398 ATH_CHECK(m_NNTrackTool->setTrackParameters(tracks_1st,true,m_evtSel->getMin(), m_evtSel->getMax()));
399 }
400 } else {
401 ATH_MSG_DEBUG("Performing Linear tracking");
402 if (m_passLowestChi2TrackOnly) { // Pass only the lowest chi2 track per road
403 // Loop over roads and keep only the best track for each road
404 for (const auto& road : roads_1st) {
405 std::vector<FPGATrackSimTrack> tracksForCurrentRoad;
406
407 // Collect tracks for this road
408 std::vector<FPGATrackSimRoad> roadVec = {road};
409 ATH_CHECK(m_trackFitterTool_1st->getTracks(roadVec, tracksForCurrentRoad, m_evtSel->getMin(), m_evtSel->getMax()));
410
411 // Find the best track for this road
412 if (!tracksForCurrentRoad.empty()) {
413 auto bestTrackIter = std::min_element(
414 tracksForCurrentRoad.begin(), tracksForCurrentRoad.end(),
415 [](const FPGATrackSimTrack& a, const FPGATrackSimTrack& b) {
416 return a.getChi2ndof() < b.getChi2ndof();
417 });
418
419 if (bestTrackIter != tracksForCurrentRoad.end() && bestTrackIter->getChi2ndof() < 1.e15) {
420 tracks_1st.push_back(*bestTrackIter);
421 }
422 }
423 }
424 } else { // Pass all tracks with chi2 < 1e15
425 ATH_CHECK(m_trackFitterTool_1st->getTracks(roads_1st, tracks_1st, m_evtSel->getMin(), m_evtSel->getMax()));
426 }
427 }
428 } else { // No tracking;
429 ATH_MSG_DEBUG("No tracking. Just running dummy road2track algorith");
430 if(m_doGNNPixelSeeding) { //For GNNPixelSeeding, convert the roads to a track in the simplest form
431 for (const auto& road : roads_1st) {
432 std::vector<std::shared_ptr<const FPGATrackSimHit>> track_hits;
433 for (unsigned layer = 0; layer < road.getNLayers(); ++layer) {
434 track_hits.insert(track_hits.end(), road.getHitPtrs(layer).begin(), road.getHitPtrs(layer).end());
435 }
436
437 FPGATrackSimTrack track_cand;
438 track_cand.setNLayers(track_hits.size());
439 for (size_t ihit = 0; ihit < track_hits.size(); ++ihit) {
440 track_cand.setFPGATrackSimHit(ihit, track_hits[ihit]);
441 }
442 tracks_1st.push_back(track_cand);
443 }
444 }
445 else { roadsToTrack(roads_1st, tracks_1st, m_FPGATrackSimMapping->PlaneMap_1st(0)); }
446 }
447
448 // calculateTruth() before any monitors
449 // this explicitly calculates barcode, barcodeFrac and eventIndex
450 ATH_MSG_DEBUG("doMultiTruth = " << m_doMultiTruth);
451 if (m_doMultiTruth)
452 for (auto &track : tracks_1st)
453 track.calculateTruth();
454
457 monitorTracks(m_1st_stage_track_monitor, tracks_1st);
458 }
459
460
461 {
462 // set track parameters to truth
463 std::optional<Athena::Chrono> chronoSetTruthParams;
464 if constexpr (enableBenchmark) chronoSetTruthParams.emplace("1st Stage: Set Track Parameters to Truth", m_chrono.get());
465 //Loop over tracks and set the region for all of them, also optionally set track parameters to truth
466 for (FPGATrackSimTrack& track : tracks_1st) {
467 track.setRegion(m_region);
468 if (m_SetTruthParametersForTracks >= 0 && truthtracks.size() > 0) {
470 track.setQOverPt(truthtracks.front().getQOverPt());
471 else if (m_SetTruthParametersForTracks != 1)
472 track.setD0(truthtracks.front().getD0());
473 else if (m_SetTruthParametersForTracks != 2)
474 track.setPhi(truthtracks.front().getPhi());
475 else if (m_SetTruthParametersForTracks != 3)
476 track.setZ0(truthtracks.front().getZ0());
477 else if (m_SetTruthParametersForTracks != 4)
478 track.setEta(truthtracks.front().getEta());
479 }
480 }
483 monitorTracks(m_1st_stage_track_post_setTruth_monitor, tracks_1st);
484 }
485
486 // Loop over roads and store them in SG (after track finding to also copy the sector information)
487 for (auto const& road : roads_1st) {
488 auto road_hits = std::make_unique<FPGATrackSimHitCollection>();
489 ATH_MSG_DEBUG("Hough Road X Y: " << road.getX() << " " << road.getY());
490 for (size_t l = 0; l < road.getNLayers(); ++l) {
491 for (const auto& layerH : road.getHitPtrs(l)) {
492 road_hits->push_back(new FPGATrackSimHit(*layerH));
493 }
494 }
495 FPGAHitsInRoads_1st->push_back(std::move(*road_hits));
496 FPGARoads_1st->push_back(road);
497 }
498
499 {
500 // overlap removal
501 std::optional<Athena::Chrono> chronoOverlapRemoval2;
502 if constexpr (enableBenchmark) chronoOverlapRemoval2.emplace("1st Stage: OverlapRemoval", m_chrono.get());
503 if (m_doOverlapRemoval) ATH_CHECK(m_overlapRemovalTool_1st->runOverlapRemoval(tracks_1st));
504 // monitor variables (vectors of pointers)
505 std::vector<const FPGATrackSimTrack*> tracks_1st_after_chi2;
506 std::vector<const FPGATrackSimTrack*> tracks_1st_after_overlap;
507 for (const FPGATrackSimTrack& track : tracks_1st) {
508 if (track.getChi2ndof() < m_trackScoreCut.value()) {
510 tracks_1st_after_chi2.push_back(&track);
511 if (track.passedOR()) {
512 tracks_1st_after_overlap.push_back(&track);
514 }
515 }
516 }
518 monitorTracks(m_1st_stage_track_post_chi2_monitor, tracks_1st_after_chi2);
520 monitorTracks(m_1st_stage_track_post_OLR_monitor, tracks_1st_after_overlap);
521 }
522
523 m_nRoadsTot += roads_1st.size();
524 m_nTracksTot += tracks_1st.size();
525
526 // Do some simple monitoring of efficiencies. okay, we need truth tracks here.
527 if (truthtracks.size() > 0) {
528 m_evt_truth++;
529 if (roads_1st.size() > 0) m_nRoadsFound++;
530 if (roads_1st.size() > m_maxNRoadsFound) m_maxNRoadsFound = roads_1st.size();
531
532 unsigned npasschi2(0);
533 unsigned npasschi2OLR(0);
534 if (tracks_1st.size() > 0) {
536 if (tracks_1st.size() > m_maxNTracksTot) m_maxNTracksTot = tracks_1st.size();
537 for (const auto& track : tracks_1st) {
538 if (track.getChi2ndof() < m_trackScoreCut.value()) {
539 npasschi2++;
540 if (track.passedOR()) {
541 npasschi2OLR++;
542 }
543 }
544 }
545 }
546 if (npasschi2 > m_maxNTracksChi2Tot) m_maxNTracksChi2Tot = npasschi2;
547 if (npasschi2OLR > m_maxNTracksChi2OLRTot) m_maxNTracksChi2OLRTot = npasschi2OLR;
548 if (npasschi2 > 0) m_nTracksChi2Found++;
549 if (npasschi2OLR > 0) m_nTracksChi2OLRFound++;
550 }
551
552 for (const FPGATrackSimTrack& track : tracks_1st) FPGATracks_1stHandle->push_back(track);
553
554 // Now, we may want to do large-radius tracking on the hits not used by the first stage tracking.
555 // This follows overlap removal.
556 std::vector<FPGATrackSimRoad> roadsLRT;
557 std::vector<FPGATrackSimTrack> tracksLRT; // currently empty
558 if (m_doLRT) {
559 // Filter out hits that are on successful first-stage tracks
560 std::vector<std::shared_ptr<const FPGATrackSimHit>> remainingHits;
561
563 ATH_MSG_DEBUG("Doing hit filtering based on prompt tracks.");
564 ATH_CHECK(m_LRTRoadFilterTool->filterUsedHits(tracks_1st, phits_1st, remainingHits));
565
566 for (const auto &Hit : remainingHits) FPGAHitsFiltered_1st->push_back(new FPGATrackSimHit(*Hit));
567
568 } else {
569 ATH_MSG_DEBUG("No hit filtering requested; using all hits for LRT.");
570 remainingHits = std::move(phits_1st);
571 }
572
573 // Get LRT roads with remaining hits
574 ATH_MSG_DEBUG("Finding LRT roads");
575 ATH_CHECK(m_LRTRoadFinderTool->getRoads( remainingHits, roadsLRT ));
576 }
577
578 auto dataFlowInfo = std::make_unique<FPGATrackSimDataFlowInfo>();
579
580 // Write the output and reset
581 if (m_writeOutputData) {
582 ATH_CHECK(writeOutputData(roads_1st, tracks_1st, dataFlowInfo.get()));
583 }
584
585 // This one we can do-- by passing in truth and offline tracks via storegate above (*FPGAOfflineTracks).
587 ATH_MSG_DEBUG("Running HoughRootOutputTool in 1st stage.");
588
589 SmartIF<IEventProcessor> appMgr{service("ApplicationMgr")};
590 if (!appMgr) {
591 ATH_MSG_ERROR("Failed to retrieve ApplicationMgr as IEventProcessor");
592 return StatusCode::FAILURE;
593 }
594
595 // Create output ROOT file
596 ATH_CHECK(m_houghRootOutputTool->fillTree(tracks_1st, truthtracks, *FPGAOfflineTracks, phits_output, m_writeOutNonSPStripHits, false));
597 }
598
599 // Reset data pointers
602
603 return StatusCode::SUCCESS;
604}
605
606
608// INPUT PASSING, READING AND PROCESSING //
610
611StatusCode FPGATrackSimLogicalHitsProcessAlg::writeOutputData( const std::vector<FPGATrackSimRoad>& roads_1st,
612 std::vector<FPGATrackSimTrack> const& tracks_1st,
613 FPGATrackSimDataFlowInfo const* dataFlowInfo)
614{
616
617 ATH_MSG_DEBUG("NFPGATrackSimRoads_1st = " << roads_1st.size() << ", NFPGATrackSimTracks_1st = " << tracks_1st.size());
618
619 if (!m_writeOutputData) return StatusCode::SUCCESS;
620 m_logicEventOutputHeader->reserveFPGATrackSimRoads_1st(roads_1st.size());
621 m_logicEventOutputHeader->addFPGATrackSimRoads_1st(roads_1st);
622
623 m_logicEventOutputHeader->reserveFPGATrackSimTracks_1st(tracks_1st.size());
624 m_logicEventOutputHeader->addFPGATrackSimTracks_1st(tracks_1st);
625
626 m_logicEventOutputHeader->setDataFlowInfo(*dataFlowInfo);
627 ATH_MSG_DEBUG(m_logicEventOutputHeader->getDataFlowInfo());
628
629 // It would be nice to rearrange this so both algorithms use one instance of this tool, I think.
630 // Which means that dataprep can't call writeData because that does Fill().
631 ATH_CHECK(m_writeOutputTool->writeData());
632
633
634
635 return StatusCode::SUCCESS;
636}
637
638
640// Finalize
641
643{
644 ATH_MSG_INFO("PRINTING FPGATRACKSIM SIMPLE STATS");
645 ATH_MSG_INFO("========================================================================================");
646 ATH_MSG_INFO("Ran on events = " << m_evt);
647 ATH_MSG_INFO("Inclusive efficiency to find a road = " << (m_evt_truth == 0 ? "NAN" : std::to_string(m_nRoadsFound/(float)m_evt_truth)));
648 ATH_MSG_INFO("Inclusive efficiency to find a track = " << (m_evt_truth == 0 ? "NAN" : std::to_string(m_nTracksFound/(float)m_evt_truth)));
649 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)));
650 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)));
651
652
653 ATH_MSG_INFO("Number of 1st stage roads/event = " << (m_evt == 0 ? "NAN" : std::to_string(m_nRoadsTot/(float)m_evt)));
654 ATH_MSG_INFO("Number of 1st stage track combinations/event = " << (m_evt == 0 ? "NAN" : std::to_string(m_nTracksTot/(float)m_evt)));
655 ATH_MSG_INFO("Number of 1st stage tracks passing chi2/event = " << (m_evt == 0 ? "NAN" : std::to_string(m_nTracksChi2Tot/(float)m_evt)));
656 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)));
657 ATH_MSG_INFO("========================================================================================");
658
659 ATH_MSG_INFO("Max number of 1st stage roads in an event = " << m_maxNRoadsFound);
660 ATH_MSG_INFO("Max number of 1st stage track combinations in an event = " << m_maxNTracksTot);
661 ATH_MSG_INFO("Max number of 1st stage tracks passing chi2 in an event = " << m_maxNTracksChi2Tot);
662 ATH_MSG_INFO("Max number of 1st stage tracks passing chi2 and OLR in an event = " << m_maxNTracksChi2OLRTot);
663 ATH_MSG_INFO("========================================================================================");
664
665 return StatusCode::SUCCESS;
666}
667
668
670// Helpers
671
672void FPGATrackSimLogicalHitsProcessAlg::printHitSubregions(std::vector<FPGATrackSimHit> const & hits)
673{
674 ATH_MSG_WARNING("Hit regions:");
675 for (const auto& hit : hits)
676 {
677 std::vector<uint32_t> regions = m_FPGATrackSimMapping->SubRegionMap()->getRegions(hit);
678 std::stringstream ss;
679 for (auto r : regions)
680 ss << r << ",";
681 ATH_MSG_WARNING("\t[" << ss.str() << "]");
682 }
683}
#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:
DataVector adapter that acts like it holds const pointers.
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
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
SG::WriteHandleKey< ConstDataVector< FPGATrackSimHitCollection > > m_FPGAHitKey_1st
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
SG::WriteHandleKey< ConstDataVector< FPGATrackSimHitCollection > > m_FPGAHitKey_2nd
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< FPGATrackSimTrackCollection > m_FPGATrackKey
ServiceHandle< IFPGATrackSimEventSelectionSvc > m_evtSel
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 setFPGATrackSimHit(unsigned i, std::shared_ptr< const FPGATrackSimHit > hit)
void setNLayers(int)
set the number of layers in the track.
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.
pointer_type ptr()
Dereference the pointer.
int r
Definition globals.cxx:22
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
constexpr bool enableBenchmark