ATLAS Offline Software
Loading...
Searching...
No Matches
FPGATrackSimLayerStudyAlg.cxx
Go to the documentation of this file.
1// Copyright (C) 2002-2026 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
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());
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(const EventContext& ctx)
91{
92
93 // Get reference to hits from StoreGate.
95 if (!FPGAHits.isValid()) {
96 if (m_evt == 0) {
97 ATH_MSG_WARNING("Didn't receive " << FPGAHits.key() << " on first event; assuming no input events.");
98 }
99 SmartIF<IEventProcessor> appMgr{service("ApplicationMgr")};
100 if (!appMgr) {
101 ATH_MSG_ERROR("Failed to retrieve ApplicationMgr as IEventProcessor");
102 return StatusCode::FAILURE;
103 }
104 return appMgr->stopRun();
105 }
106
107 // Query the event selection service to make sure this event passed cuts.
108 if (!m_evtSel->getSelectedEvent()) {
109 ATH_MSG_DEBUG("Event skipped by: " << m_evtSel->name());
110 return StatusCode::SUCCESS;
111 }
112
113 // Event passes cuts, count it. technically, DataPrep does this now.
114 m_evt++;
115
116 if constexpr (enableBenchmark) m_chrono->chronoStart("Layer Study: Split hits to 1st and 2nd stage");
117
118 // It shouldn't matter which slice we use; there should really only be one here
119 const FPGATrackSimPlaneMap* pmap_2nd = m_FPGATrackSimMapping->PlaneMap_2nd(0);
120
121 std::vector<FPGATrackSimHit> hits;
122 std::vector<std::shared_ptr<const FPGATrackSimHit>> phits;
123 const FPGATrackSimRegionMap* rmap_1st = m_FPGATrackSimMapping->SubRegionMap();
124 phits.reserve(FPGAHits->size());
125 hits.reserve(FPGAHits->size());
126
127 // For stage = 0, we'll run over all of them. Otherwise only look at first or second stage.
128 for (const FPGATrackSimHit* hit : *FPGAHits) {
129 // Acquire a non-constant copy of the hit, this is messy, but we have to map them.
130 FPGATrackSimHit hitCopy = *hit;
131 pmap_2nd->map(hitCopy);
132 hits.push_back(hitCopy);
133
134 switch (m_stage) {
135 case 0:
136 phits.push_back(std::make_shared<FPGATrackSimHit>(hitCopy));
137 break;
138 case 1:
139 // For first stage hits, require that they are also pixel hits. This is a safe assumption because
140 // the inside out algorithm will only ever run on pixels.
141 if (rmap_1st->getRegions(*hit).size() > 0 && hit->isPixel()) phits.push_back(std::make_shared<FPGATrackSimHit>(hitCopy));
142 break;
143 case 2:
144 if (rmap_1st->getRegions(*hit).size() == 0) phits.push_back(std::make_shared<FPGATrackSimHit>(hitCopy));
145 break;
146 default:
147 ATH_MSG_FATAL("Unrecognized stage: " << m_stage << ", will exit layer study");
148 break;
149 }
150 }
151
152 if constexpr (enableBenchmark) m_chrono->chronoStop("Layer Study: Split hits to 1st and 2nd stage");
153
154 // Get truth tracks from DataPrep as well.
156 if (!FPGATruthTracks.isValid()) {
157 ATH_MSG_ERROR("Could not find FPGA Truth Track Collection with key " << FPGATruthTracks.key());
158 return StatusCode::FAILURE;
159 }
160
161 // Update truth information in output layer study tree.
162 m_binMonitoring->parseTruthInfo(*FPGATruthTracks);
163 m_hitBinningTool->getBinTool().binDesc()->setTruthBin(m_binMonitoring->truthBin());
164
165 // Make hit level plots
166 for (auto &hit : phits) {
167 m_binMonitoring->fillHitLevelInput(hit.get());
168 }
169
170 // Bin the hits, depending on m_stage we either use phits_1st, phits_2nd, or all the hits.
171 ATH_CHECK(m_hitBinningTool->fill(phits));
172
173 // scan over image building pairs for bins over threshold
175 bool isTruthBin = (FPGATrackSimBinUtil::IdxSet(bin.idx())==m_binMonitoring->truthBin(m_hitBinningTool->getBinTool().lastStep()->stepNum()));
176
177 // Apply threshold, of course if threshold is 0 then use all bins
178 if (bin.data().hitCnt < m_threshold) {
179 if (isTruthBin) {
180 ATH_MSG_DEBUG("Truth bin failed threshold " << bin.data().hitCnt << " thr=" << m_threshold << " " << bin.idx());}
181 continue;
182 }
183 ATH_MSG_DEBUG("Bin passes threshold " << bin.data().hitCnt << " " << bin.idx());
184
185 // Monitor contents of bins passing threshold
186 if (m_requireTruth and not isTruthBin) continue;
187
188 m_binMonitoring->fillBinLevelOutput(bin.idx(), bin.data());
189 }
190 m_binMonitoring->fillBinningSummary(phits);
191
192
193 // Reset the hit binning tool.
194 m_hitBinningTool->resetBins();
195
196 return StatusCode::SUCCESS;
197}
198
200// Finalize
201
203{
204 ATH_MSG_INFO("PRINTING FPGATRACKSIM SIMPLE STATS");
205 ATH_MSG_INFO("========================================================================================");
206 ATH_MSG_INFO("Ran on events = " << m_evt);
207
208 return StatusCode::SUCCESS;
209}
#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.
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 initialize() override
virtual StatusCode finalize() override
ServiceHandle< IFPGATrackSimEventSelectionSvc > m_evtSel
FPGATrackSimLayerStudyAlg(const std::string &name, ISvcLocator *pSvcLocator)
Gaudi::Property< bool > m_requireTruth
SG::ReadHandleKey< FPGATrackSimHitCollection > m_FPGAHitKey
ToolHandle< FPGATrackSimBinnedHits > m_hitBinningTool
ServiceHandle< IFPGATrackSimMappingSvc > m_FPGATrackSimMapping
ToolHandle< FPGATrackSimLayerStudyTool > m_binMonitoring
virtual StatusCode execute(const EventContext &ctx) override
Execute method.
SG::ReadHandleKey< FPGATrackSimTruthTrackCollection > m_FPGATruthTrackKey
Gaudi::Property< unsigned > m_threshold
ServiceHandle< IChronoStatSvc > m_chrono
void map(FPGATrackSimHit &hit) const
std::vector< uint32_t > getRegions(const FPGATrackSimHit &hit) const
virtual bool isValid() override final
Can the handle be successfully dereferenced?
virtual const std::string & key() const override final
Return the StoreGate ID for the referenced object.
constexpr bool enableBenchmark