ATLAS Offline Software
Loading...
Searching...
No Matches
FPGATrackSimLayerStudyAlg.cxx
Go to the documentation of this file.
1// Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2
4
15
19
21
24
26
27#include "GaudiKernel/IEventProcessor.h"
28
29constexpr bool enableBenchmark =
30#ifdef BENCHMARK_LAYERSTUDYALG
31 true;
32#else
33 false;
34#endif
35
37// Initialize
38
39FPGATrackSimLayerStudyAlg::FPGATrackSimLayerStudyAlg (const std::string& name, ISvcLocator* pSvcLocator) :
40 AthAlgorithm(name, pSvcLocator)
41{
42}
43
44
45StatusCode FPGATrackSimLayerStudyAlg::initialize ATLAS_NOT_THREAD_SAFE()
46{
47 std::stringstream ss(m_description);
48 std::string line;
49 ATH_MSG_INFO("Tag config:");
50 if (!m_description.empty()) {
51 while (std::getline(ss, line, '\n')) {
52 ATH_MSG_INFO('\t' << line);
53 }
54 }
55
56 ATH_CHECK(m_hitBinningTool.retrieve());
57 ATH_CHECK(m_binMonitoring.retrieve());
58 ATH_CHECK(m_FPGATrackSimMapping.retrieve());
59 ATH_CHECK(m_evtSel.retrieve());
60
61 // TODO add this here
62 ATH_MSG_DEBUG("initialize() Instantiating output layer study tree");
63
64 // Setup layer configuration if not already set from layerMap
65 if (m_hitBinningTool->getNLayers()==0) {
66 m_hitBinningTool->setNLayers(m_FPGATrackSimMapping->PlaneMap_1st(0)->getNLogiLayers());
67 }
68
69 // Set up the histograms. Use the event selection service to test whether or not this is single particle.
70 // It may be better to not use a separate tool for this, and just fold it into this algorithm.
71 // The reason to keep a separate tool would be is if we eventually want to migrate *all* of GenScanMonitoring -> BinMonitoring,
72 // but that can't happen until GenScan is fully converted to use the new binning.
73 ATH_CHECK(m_binMonitoring->registerHistograms(m_hitBinningTool.get(), (m_evtSel->getSampleType() == SampleType::skipTruth)));
74
75 // Retrieve truth tracks.
76 ATH_CHECK(m_FPGAHitKey.initialize());
77 ATH_CHECK(m_FPGATruthTrackKey.initialize());
78
79 ATH_CHECK(m_chrono.retrieve());
80 ATH_MSG_DEBUG("initialize() Finished");
81
82 return StatusCode::SUCCESS;
83}
84
85
87// MAIN EXECUTE ROUTINE //
89
90StatusCode FPGATrackSimLayerStudyAlg::execute ATLAS_NOT_THREAD_SAFE()
91{
92 const EventContext& ctx = getContext();
93
94 // Get reference to hits from StoreGate.
95 SG::ReadHandle<FPGATrackSimHitCollection> FPGAHits(m_FPGAHitKey, ctx);
96 if (!FPGAHits.isValid()) {
97 if (m_evt == 0) {
98 ATH_MSG_WARNING("Didn't receive " << FPGAHits.key() << " on first event; assuming no input events.");
99 }
100 SmartIF<IEventProcessor> appMgr{service("ApplicationMgr")};
101 if (!appMgr) {
102 ATH_MSG_ERROR("Failed to retrieve ApplicationMgr as IEventProcessor");
103 return StatusCode::FAILURE;
104 }
105 return appMgr->stopRun();
106 }
107
108 // Query the event selection service to make sure this event passed cuts.
109 if (!m_evtSel->getSelectedEvent()) {
110 ATH_MSG_DEBUG("Event skipped by: " << m_evtSel->name());
111 return StatusCode::SUCCESS;
112 }
113
114 // Event passes cuts, count it. technically, DataPrep does this now.
115 m_evt++;
116
117 if constexpr (enableBenchmark) m_chrono->chronoStart("Layer Study: Split hits to 1st and 2nd stage");
118
119 // It shouldn't matter which slice we use; there should really only be one here
120 const FPGATrackSimPlaneMap* pmap_2nd = m_FPGATrackSimMapping->PlaneMap_2nd(0);
121
122 std::vector<FPGATrackSimHit> hits;
123 std::vector<std::shared_ptr<const FPGATrackSimHit>> phits;
124 const FPGATrackSimRegionMap* rmap_1st = m_FPGATrackSimMapping->SubRegionMap();
125 phits.reserve(FPGAHits->size());
126 hits.reserve(FPGAHits->size());
127
128 // For stage = 0, we'll run over all of them. Otherwise only look at first or second stage.
129 for (const FPGATrackSimHit& hit : *FPGAHits) {
130 // Acquire a non-constant copy of the hit, this is messy, but we have to map them.
131 FPGATrackSimHit hitCopy = hit;
132 pmap_2nd->map(hitCopy);
133 hits.push_back(hitCopy);
134
135 switch (m_stage) {
136 case 0:
137 phits.push_back(std::make_shared<FPGATrackSimHit>(hitCopy));
138 break;
139 case 1:
140 // For first stage hits, require that they are also pixel hits. This is a safe assumption because
141 // the inside out algorithm will only ever run on pixels.
142 if (rmap_1st->getRegions(hit).size() > 0 && hit.isPixel()) phits.push_back(std::make_shared<FPGATrackSimHit>(hitCopy));
143 break;
144 case 2:
145 if (rmap_1st->getRegions(hit).size() == 0) phits.push_back(std::make_shared<FPGATrackSimHit>(hitCopy));
146 break;
147 default:
148 ATH_MSG_FATAL("Unrecognized stage: " << m_stage << ", will exit layer study");
149 break;
150 }
151 }
152
153 if constexpr (enableBenchmark) m_chrono->chronoStop("Layer Study: Split hits to 1st and 2nd stage");
154
155 // Get truth tracks from DataPrep as well.
156 SG::ReadHandle<FPGATrackSimTruthTrackCollection> FPGATruthTracks(m_FPGATruthTrackKey, ctx);
157 if (!FPGATruthTracks.isValid()) {
158 ATH_MSG_ERROR("Could not find FPGA Truth Track Collection with key " << FPGATruthTracks.key());
159 return StatusCode::FAILURE;
160 }
161
162 // Update truth information in output layer study tree.
163 m_binMonitoring->parseTruthInfo(*FPGATruthTracks);
164 m_hitBinningTool->getBinTool().binDesc()->setTruthBin(m_binMonitoring->truthBin());
165
166 // Make hit level plots
167 for (auto &hit : phits) {
168 m_binMonitoring->fillHitLevelInput(hit.get());
169 }
170
171 // Bin the hits, depending on m_stage we either use phits_1st, phits_2nd, or all the hits.
172 ATH_CHECK(m_hitBinningTool->fill(phits));
173
174 // scan over image building pairs for bins over threshold
175 for (FPGATrackSimBinArray<FPGATrackSimBinnedHits::BinEntry>::ConstIterator &bin : m_hitBinningTool->lastStepBinnedHits()) {
176 bool isTruthBin = (FPGATrackSimBinUtil::IdxSet(bin.idx())==m_binMonitoring->truthBin(m_hitBinningTool->getBinTool().lastStep()->stepNum()));
177
178 // Apply threshold, of course if threshold is 0 then use all bins
179 if (bin.data().hitCnt < m_threshold) {
180 if (isTruthBin) {
181 ATH_MSG_DEBUG("Truth bin failed threshold " << bin.data().hitCnt << " thr=" << m_threshold << " " << bin.idx());}
182 continue;
183 }
184 ATH_MSG_DEBUG("Bin passes threshold " << bin.data().hitCnt << " " << bin.idx());
185
186 // Monitor contents of bins passing threshold
187 if (m_requireTruth and not isTruthBin) continue;
188
189 m_binMonitoring->fillBinLevelOutput(bin.idx(), bin.data());
190 }
191 m_binMonitoring->fillBinningSummary(phits);
192
193
194 // Reset the hit binning tool.
195 m_hitBinningTool->resetBins();
196
197 return StatusCode::SUCCESS;
198}
199
201// Finalize
202
204{
205 ATH_MSG_INFO("PRINTING FPGATRACKSIM SIMPLE STATS");
206 ATH_MSG_INFO("========================================================================================");
207 ATH_MSG_INFO("Ran on events = " << m_evt);
208
209 return StatusCode::SUCCESS;
210}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Binning Utilities for GenScanTool.
Structs that store the data flow information per event.
: FPGATrackSim-specific class to represent an hit in the detector.
StatusCode FPGATrackSimLayerStudyAlg::initialize ATLAS_NOT_THREAD_SAFE()
Install fatal handler with default options.
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 ss
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
virtual StatusCode finalize() override
FPGATrackSimLayerStudyAlg(const std::string &name, ISvcLocator *pSvcLocator)
void map(FPGATrackSimHit &hit) const
std::vector< uint32_t > getRegions(const FPGATrackSimHit &hit) const
constexpr bool enableBenchmark