ATLAS Offline Software
Loading...
Searching...
No Matches
FPGAConversionAlgorithm.cxx
Go to the documentation of this file.
1// Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2
5#include <type_traits>
6#include <format>
7
8constexpr bool enableBenchmark =
9#ifdef BENCHMARK_FPGATRACKSIM
10 true;
11#else
12 false;
13#endif
14
15FPGAConversionAlgorithm::FPGAConversionAlgorithm(const std::string& name, ISvcLocator* pSvcLocator ):
16 AthReentrantAlgorithm( name, pSvcLocator ){}
17
41
42 StatusCode FPGAConversionAlgorithm::execute(const EventContext& ctx) const {
43 std::unique_ptr<InDet::PixelClusterCollection> PixelCollFromHits = std::make_unique<InDet::PixelClusterCollection>();
44 std::unique_ptr<InDet::SCT_ClusterCollection> SCTCollFromHits = std::make_unique<InDet::SCT_ClusterCollection>();
45
46 std::unique_ptr<InDet::PixelClusterCollection> PixelCollFromClusters = std::make_unique<InDet::PixelClusterCollection>();
47 std::unique_ptr<InDet::SCT_ClusterCollection> SCTCollFromClusters = std::make_unique<InDet::SCT_ClusterCollection>();
48
49 std::unique_ptr<InDet::SCT_ClusterCollection> SCTCollFromSP = std::make_unique<InDet::SCT_ClusterCollection>();
50 std::unique_ptr<xAOD::PixelClusterContainer> PixelContFromHits = std::make_unique<xAOD::PixelClusterContainer>();
51 std::unique_ptr<xAOD::PixelClusterAuxContainer> PixelAuxContFromHits = std::make_unique<xAOD::PixelClusterAuxContainer>();
52 PixelContFromHits->setStore (PixelAuxContFromHits.get());
53
54 std::unique_ptr<xAOD::StripClusterContainer> SCTContFromHits = std::make_unique<xAOD::StripClusterContainer>();
55 std::unique_ptr<xAOD::StripClusterAuxContainer> SCTAuxContFromHits = std::make_unique<xAOD::StripClusterAuxContainer>();
56 SCTContFromHits->setStore(SCTAuxContFromHits.get() );
57
58 std::unique_ptr<xAOD::PixelClusterContainer> PixelContFromClusters = std::make_unique<xAOD::PixelClusterContainer>();
59 std::unique_ptr<xAOD::PixelClusterAuxContainer> PixelAuxContFromClusters = std::make_unique<xAOD::PixelClusterAuxContainer>();
60 PixelContFromClusters->setStore (PixelAuxContFromClusters.get());
61
62 std::unique_ptr<xAOD::StripClusterContainer> SCTContFromClusters = std::make_unique<xAOD::StripClusterContainer>();
63 std::unique_ptr<xAOD::StripClusterAuxContainer> SCTAuxContFromClusters = std::make_unique<xAOD::StripClusterAuxContainer>();
64 SCTContFromClusters->setStore(SCTAuxContFromClusters.get() );
65
66 std::unique_ptr<xAOD::SpacePointContainer> StripSPCont = std::make_unique<xAOD::SpacePointContainer>();
67 std::unique_ptr<xAOD::SpacePointAuxContainer> StripSPAuxCont = std::make_unique<xAOD::SpacePointAuxContainer>();
68 StripSPCont->setStore(StripSPAuxCont.get() );
69
70 std::unique_ptr<xAOD::SpacePointContainer> PixelSPCont = std::make_unique<xAOD::SpacePointContainer>();
71 std::unique_ptr<xAOD::SpacePointAuxContainer> PixelSPAuxCont = std::make_unique<xAOD::SpacePointAuxContainer>();
72 PixelSPCont->setStore(PixelSPAuxCont.get() );
73
74 std::unique_ptr<ActsTrk::ProtoTrackCollection> ProtoTracksFromRoads = std::make_unique<ActsTrk::ProtoTrackCollection>();
75 std::unique_ptr<ActsTrk::ProtoTrackCollection> ProtoTracksFromTracks = std::make_unique<ActsTrk::ProtoTrackCollection>();
76
77 if (m_doClusters) {
78
80 if (FPGAClustersHandle.isValid()) { // To avoid running over events that didn't pass truth tracks selections
81 const FPGATrackSimClusterCollection *FPGAClusterColl = FPGAClustersHandle.cptr();
82
83 // Convert to InDet clusters
84 if (m_doIndet) {
85 ATH_MSG_DEBUG("InDet Clusters CONVERSION");
86 ATH_CHECK(m_ClusterConverter->convertClusters(*FPGAClusterColl, *PixelCollFromClusters, *SCTCollFromClusters));
87 }
88
89 // Convert to xAOD clusters
90 ATH_MSG_INFO("xAOD Clusters CONVERSION");
91 if constexpr (enableBenchmark) m_chrono->chronoStart("FPGAConversion: cluster conversion");
92 ATH_CHECK( m_ClusterConverter->convertClusters(*FPGAClusterColl, *PixelContFromClusters, *SCTContFromClusters) );
93 if constexpr (enableBenchmark) m_chrono->chronoStop("FPGAConversion: cluster conversion");
94
95 if (m_doActsTrk) {
96 if (m_useRoads) {
98 if (!FPGARoadsHandle.isValid()) {
99 ATH_MSG_FATAL("Failed to retrieve 1st stage FPGATrackSimRoadCollection");
100 return StatusCode::FAILURE;
101 }
103 if (!FPGAHitsInRoadsHandle.isValid()) {
104 ATH_MSG_FATAL("Failed to retrieve 1st stage FPGATrackSimItInRoadCollection");
105 return StatusCode::FAILURE;
106 }
107 const FPGATrackSimHitContainer* FPGAHitsInRoadsCont = FPGAHitsInRoadsHandle.cptr();
108 const FPGATrackSimRoadCollection* FPGARoadColl = FPGARoadsHandle.cptr();
109 if constexpr (enableBenchmark) m_chrono->chronoStart("FPGAConversion: Prototrack formation (from roads)");
110 ATH_CHECK(m_ActsTrkConverter->findProtoTracks(ctx, *PixelContFromClusters, *SCTContFromClusters, *ProtoTracksFromRoads, *FPGAHitsInRoadsCont, *FPGARoadColl));
111 if constexpr (enableBenchmark) m_chrono->chronoStop("FPGAConversion: Prototrack formation (from roads)");
112 }
113 else{
115 if (!FPGATracksHandle.isValid()) {
116 ATH_MSG_FATAL("Failed to retrieve 1st stage FPGATrackSimTrackCollection");
117 return StatusCode::FAILURE;
118 }
119 const FPGATrackSimTrackCollection* FPGATrackColl = FPGATracksHandle.cptr();
120
121 if constexpr (enableBenchmark) m_chrono->chronoStart("FPGAConversion: Prototrack formation (from tracks)");
122 ATH_CHECK(m_ActsTrkConverter->findProtoTracks(ctx, *PixelContFromClusters, *SCTContFromClusters, *ProtoTracksFromTracks, *FPGATrackColl));
123 if constexpr (enableBenchmark) m_chrono->chronoStop("FPGAConversion: Prototrack formation (from tracks)");
124 }
125 }
126
127 if (m_doSP) {
128 ATH_MSG_INFO("Starting xAOD SpacePoint Conversion");
130
131 if (FPGASPHandle.isValid()) { // To avoid running over events that didn't pass truth tracks selections
132 const FPGATrackSimClusterCollection *FPGASPColl = FPGASPHandle.cptr();
133 ATH_CHECK( m_ClusterConverter->convertSpacePoints(*FPGASPColl, *StripSPCont, *PixelSPCont, *SCTContFromClusters, *PixelContFromClusters) );
134 }
135 else {{ATH_MSG_WARNING("Failed to retrieve 1st stage FPGATrackSimSpacePointCollection. Will skip SP conversion ");}}
136 }
137 }
138
139 else {ATH_MSG_WARNING("Failed to retrieve 1st stage FPGATrackSimClusterCollection. Will skip clusters and track conversion ");}
142
143 ATH_CHECK( xAODPixelClusterFromFPGAClusterHandle.record (std::move(PixelContFromClusters), std::move(PixelAuxContFromClusters)));
144 ATH_CHECK( xAODStripClusterFromFPGAClusterHandle.record (std::move(SCTContFromClusters), std::move(SCTAuxContFromClusters)));
145 if(m_doActsTrk)
146 {
148 ATH_CHECK( ActsProtoTrackFromFPGATrackHandle.record (std::move(ProtoTracksFromTracks)));
149 if(m_useRoads) {
151 ATH_CHECK( ActsProtoTrackFromFPGARoadHandle.record (std::move(ProtoTracksFromRoads)));
152 }
153 }
154 if (m_doSP)
155 {
158 ATH_CHECK( xAODStripSpacePointFromFPGAHandle.record (std::move(StripSPCont), std::move(StripSPAuxCont)));
159 ATH_CHECK( xAODPixelSpacePointFromFPGAHandle.record (std::move(PixelSPCont), std::move(PixelSPAuxCont)));
160 }
161 }
162
163 if (m_doHits) {
165
166 if (FPGAHitsHandle.isValid()) {
167 const FPGATrackSimHitCollection *FPGAHitColl = FPGAHitsHandle.cptr();
168
169 // Convert to InDet clusters
170 if (m_doIndet) {
171 ATH_MSG_DEBUG("InDet Hits CONVERSION");
172 ATH_CHECK(m_ClusterConverter->convertHits(*FPGAHitColl, *PixelCollFromHits, *SCTCollFromHits));
173 }
174 ATH_MSG_DEBUG("xAOD Hits CONVERSION");
175 ATH_CHECK( m_ClusterConverter->convertHits(*FPGAHitColl, *PixelContFromHits, *SCTContFromHits) );
176 }
177
178 else {ATH_MSG_WARNING("Failed to retrieve 1st stage FPGATrackSimHitCollection. Will skip hit conversion ");}
179
180
183 ATH_CHECK( xAODPixelClusterFromFPGAHitHandle.record (std::move(PixelContFromHits),std::move(PixelAuxContFromHits)));
184 ATH_CHECK( xAODStripClusterFromFPGAHitHandle.record (std::move(SCTContFromHits),std::move(SCTAuxContFromHits)));
185
186 // Also do the tracks
187 if (m_doActsTrk && !m_useRoads) {
189 if (!FPGATracksHandle.isValid()) {
190 ATH_MSG_FATAL("Failed to retrieve 1st stage FPGATrackSimTrackCollection");
191 return StatusCode::FAILURE;
192 }
193 const FPGATrackSimTrackCollection* FPGATrackColl = FPGATracksHandle.cptr();
194
195 if constexpr (enableBenchmark) m_chrono->chronoStart("FPGAConversion: Prototrack formation (from tracks)");
196 ATH_CHECK(m_ActsTrkConverter->findProtoTracks(ctx, *PixelContFromClusters, *SCTContFromClusters, *ProtoTracksFromTracks, *FPGATrackColl));
197 if constexpr (enableBenchmark) m_chrono->chronoStop("FPGAConversion: Prototrack formation (from tracks)");
198 }
199 }
200
201 return StatusCode::SUCCESS;
202 }
203
204
205template <typename T> // should be InDet::PixelCluster or InDet::SCT_Cluster
206StatusCode FPGAConversionAlgorithm::convertCollectionToContainer(Trk::PrepRawDataCollection<T>* inputCollection, // i.e. InDet::PixelClusterCollection or InDet::SCT_ClusterCollection
208 )
209{
210 if constexpr (!std::is_same<T, InDet::PixelCluster>::value && !std::is_same<T, InDet::SCT_Cluster>::value) {
211 static_assert(false, "Bad type <T>. Should be InDet::PixelCluster or InDet::SCT_Cluster");
212 return StatusCode::FAILURE;
213 }
214
215 std::unique_ptr<Trk::PrepRawDataContainer<Trk::PrepRawDataCollection<T>>> outputContainer = std::make_unique<Trk::PrepRawDataContainer<Trk::PrepRawDataCollection<T>>>(SG::VIEW_ELEMENTS);
216 SG::WriteHandle<Trk::PrepRawDataContainer<Trk::PrepRawDataCollection<T>>> outputContainerHandle(outputContainerKey);
217
218 if (!inputCollection || inputCollection->empty()){
219 outputContainerHandle.record(std::move(outputContainer));
220 return StatusCode::SUCCESS;
221 }
222
224 newCol->setIdentifier(inputCollection->identify());
225 for (const T* clus : *inputCollection) {
226 newCol->push_back(std::make_unique<T>(*clus));
227 ATH_MSG_DEBUG("NewCol cluster identifier " << clus->identify());
228 }
229
230 ATH_MSG_DEBUG("newCol->identifyHash() " << newCol->identifyHash());
231 ATH_CHECK(outputContainer->addCollection(newCol,newCol->identifyHash()));
232
233 if(outputContainerHandle.record(std::move(outputContainer)).isFailure()){
234 ATH_MSG_ERROR("Could not record InDetSCTClusterContainer object with "
235 << outputContainerHandle.key()
236 << " into Event Store");
237 return StatusCode::FAILURE;
238 }
239
240 return StatusCode::SUCCESS;
241}
#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)
std::vector< FPGATrackSimCluster > FPGATrackSimClusterCollection
std::vector< FPGATrackSimHit > FPGATrackSimHitCollection
std::vector< std::vector< FPGATrackSimHit > > FPGATrackSimHitContainer
std::vector< FPGATrackSimRoad > FPGATrackSimRoadCollection
std::vector< FPGATrackSimTrack > FPGATrackSimTrackCollection
Handle class for reading from StoreGate.
An algorithm that can be simultaneously executed in multiple threads.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
bool empty() const noexcept
Returns true if the collection is empty.
SG::WriteHandleKey< ActsTrk::ProtoTrackCollection > m_ActsProtoTrackFromFPGARoadKey
FPGAConversionAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
SG::WriteHandleKey< xAOD::PixelClusterContainer > m_xAODPixelClusterFromFPGAHitKey
SG::WriteHandleKey< xAOD::SpacePointContainer > m_xAODStripSpacePointFromFPGAKey
ServiceHandle< IChronoStatSvc > m_chrono
SG::WriteHandleKey< xAOD::PixelClusterContainer > m_xAODPixelClusterFromFPGAClusterKey
ToolHandle< IFPGAActsTrkConverter > m_ActsTrkConverter
ToolHandle< IFPGAClusterConverter > m_ClusterConverter
SG::ReadHandleKey< FPGATrackSimTrackCollection > m_FPGATrackKey
SG::ReadHandleKey< FPGATrackSimHitCollection > m_FPGAHitKey
Gaudi::Property< bool > m_doSP
Gaudi::Property< bool > m_doActsTrk
SG::ReadHandleKey< FPGATrackSimHitContainer > m_FPGAHitInRoadsKey
virtual StatusCode execute(const EventContext &ctx) const override
SG::ReadHandleKey< FPGATrackSimClusterCollection > m_FPGASPKey
SG::WriteHandleKey< xAOD::StripClusterContainer > m_xAODStripClusterFromFPGAHitKey
SG::WriteHandleKey< InDet::PixelClusterContainer > m_outputPixelClusterContainerKey
SG::WriteHandleKey< InDet::SCT_ClusterContainer > m_outputStripClusterContainerKey
SG::WriteHandleKey< ActsTrk::ProtoTrackCollection > m_ActsProtoTrackFromFPGATrackKey
Gaudi::Property< bool > m_doIndet
SG::WriteHandleKey< xAOD::StripClusterContainer > m_xAODStripClusterFromFPGAClusterKey
StatusCode convertCollectionToContainer(Trk::PrepRawDataCollection< T > *inputCollection, SG::WriteHandleKey< Trk::PrepRawDataContainer< Trk::PrepRawDataCollection< T > > > &outputContainerKey)
Gaudi::Property< bool > m_doClusters
SG::WriteHandleKey< xAOD::SpacePointContainer > m_xAODPixelSpacePointFromFPGAKey
virtual StatusCode initialize() override
Athena algorithm's Hooks.
SG::ReadHandleKey< FPGATrackSimClusterCollection > m_FPGAClusterKey
Gaudi::Property< bool > m_doHits
Gaudi::Property< bool > m_useRoads
SG::ReadHandleKey< FPGATrackSimRoadCollection > m_FPGARoadKey
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
Property holding a SG store/key/clid from which a WriteHandle is made.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
virtual Identifier identify() const override final
virtual IdentifierHash identifyHash() const override final
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
constexpr bool enableBenchmark