ATLAS Offline Software
Loading...
Searching...
No Matches
TrackFindingGNNAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
7#include <numbers>
8
9// Athena
12
13// ACTS
14#include "Acts/Geometry/GeometryIdentifier.hpp"
15#include "Acts/Geometry/TrackingGeometry.hpp"
16#include "Acts/Surfaces/PerigeeSurface.hpp"
17#include "Acts/Surfaces/Surface.hpp"
18#include "Acts/Utilities/MathHelpers.hpp"
19
20// ActsTrk
27#include "ActsInterop/Logger.h"
30
31// STL
32#include <algorithm>
33#include <optional>
34#include <sstream>
35#include <utility>
36#include <boost/container/small_vector.hpp>
37
38#include "ActsPlugins/Gnn/CudaTrackBuilding.hpp"
39#include "ActsPlugins/Gnn/GnnPipeline.hpp"
40#include "ActsPlugins/Gnn/ModuleMapCuda.hpp"
41#include "ActsPlugins/Gnn/OnnxEdgeClassifier.hpp"
42#include "ActsPlugins/Gnn/TensorRTEdgeClassifier.hpp"
43#include "ActsPlugins/Gnn/TorchEdgeClassifier.hpp"
44
45
46using namespace Acts::UnitLiterals;
47
48// TODO: Use the function from the InDetGNN package, but it is not cmake module
49// we can link to
50namespace {
51int compute_overlap_SP_flag(const int &eta_module_cl1,
52 const int &phi_module_cl1,
53 const int &eta_module_cl2,
54 const int &phi_module_cl2) {
55 int flag = -999;
56
57 if ((eta_module_cl1 == eta_module_cl2) &&
58 (phi_module_cl1 == phi_module_cl2)) {
59 flag = 0; // not an overlap Space Point
60 } else if ((eta_module_cl1 != eta_module_cl2) &&
61 (phi_module_cl1 == phi_module_cl2)) {
62 flag = 1; // overlap Space Point in eta only
63 } else if ((eta_module_cl1 == eta_module_cl2) &&
64 (phi_module_cl1 != phi_module_cl2)) {
65 flag = 2; // overlap Space Point in phi only
66 } else {
67 flag = 3; // "overlap" Space Point in eta and phi (not sure we can call it
68 // overlap)
69 }
70 return flag;
71}
72} // namespace
73
74namespace ActsTrk {
75
76
78 ISvcLocator *pSvcLocator)
79 : AthReentrantAlgorithm(name, pSvcLocator) {}
80
82
83// === initialize ==========================================================
84
86 // Athena tools
87 m_logger = makeActsAthenaLogger(this, "Acts GNN Algorithm");
88 ACTS_DEBUG("TrackFindingGNNAlg::initialize() - begin");
91 ATH_CHECK(m_trackContainerKey.initialize());
95 ATH_CHECK(m_trackContainerKey.initialize());
96 ATH_CHECK(m_chronoSvc.retrieve());
98 ATH_CHECK(m_fitterTool.retrieve());
99
105
106 // ACTS tools
107 ActsPlugins::ModuleMapCuda::Config gcCfg;
108 gcCfg.rScale = 1000.f;
109 gcCfg.zScale = 1000.f;
110 gcCfg.phiScale = std::numbers::pi_v<float>;
111 gcCfg.moduleMapPath = m_moduleMapPath.value();
112 gcCfg.gpuBlocks = 512;
113 std::shared_ptr<ActsPlugins::GraphConstructionBase> gc =
114 std::make_shared<ActsPlugins::ModuleMapCuda>(
115 gcCfg, m_logger->cloneWithSuffix("ModuleMap"));
116
117 std::shared_ptr<ActsPlugins::EdgeClassificationBase> gnn;
118 if (m_gnnPath.value().find(".onnx") != std::string::npos) {
119#ifdef ACTS_GNN_ONNX_BACKEND
120 ActsPlugins::OnnxEdgeClassifier::Config gnnCfg;
121 gnnCfg.modelPath = m_gnnPath.value();
122 gnnCfg.cut = m_edgeCut.value();
123 gnn = std::make_shared<ActsPlugins::OnnxEdgeClassifier>(
124 gnnCfg, m_logger->cloneWithSuffix("GNN"));
125#else
126 ATH_MSG_ERROR("GNN .onnx selected but build lacks ONNX backend");
127 return StatusCode::FAILURE;
128#endif
129 } else if (m_gnnPath.value().find(".pt") != std::string::npos) {
130#ifdef ACTS_GNN_TORCH_BACKEND
131 ActsPlugins::TorchEdgeClassifier::Config gnnCfg;
132 gnnCfg.modelPath = m_gnnPath.value();
133 gnnCfg.cut = m_edgeCut.value();
134 gnnCfg.useEdgeFeatures = true;
135 gnn = std::make_shared<ActsPlugins::TorchEdgeClassifier>(
136 gnnCfg, m_logger->cloneWithSuffix("GNN"));
137#else
138 ATH_MSG_ERROR("GNN .pt selected but build lacks libtorch backend");
139 return StatusCode::FAILURE;
140#endif
141 } else if (m_gnnPath.value().find(".engine") != std::string::npos) {
142#ifdef ACTS_GNN_WITH_TENSORRT
143 ActsPlugins::TensorRTEdgeClassifier::Config gnnCfg;
144 gnnCfg.cut = m_edgeCut.value();
145 gnnCfg.modelPath = m_gnnPath.value();
146 gnnCfg.numExecutionContexts = m_numTrtContexts.value();
147 gnn = std::make_shared<ActsPlugins::TensorRTEdgeClassifier>(
148 gnnCfg, m_logger->cloneWithSuffix("GNN"));
149#else
150 ATH_MSG_ERROR("GNN .engine selected but build lacks TensorRT backend");
151 return StatusCode::FAILURE;
152#endif
153 } else {
154 ATH_MSG_ERROR("Unknown GNN model extension: " << m_gnnPath.value());
155 return StatusCode::FAILURE;
156 }
157
158 ActsPlugins::CudaTrackBuilding::Config tbCfg;
159 tbCfg.doJunctionRemoval = true;
160 std::shared_ptr<ActsPlugins::TrackBuildingBase> tb =
161 std::make_shared<ActsPlugins::CudaTrackBuilding>(
162 tbCfg, m_logger->cloneWithSuffix("GraphSeg"));
163
164 m_gnnPipeline = std::make_unique<ActsPlugins::GnnPipeline>(
165 gc, std::vector{gnn}, tb, m_logger->cloneWithSuffix("Pipeline"));
166
167 // Limit the total number of instances on the GPU to avoid out of memory
168 m_gpuInstanceCount.emplace(m_maxGpuInstances.value());
169
170 // Parameter estimation and fitter come from Athena tools now
171
172 ATH_CHECK(detStore()->retrieve(m_stripIdHelper, "SCT_ID"));
173 ACTS_INFO("Use phi overlap spacepoints: " << std::boolalpha
174 << m_usePhiOverlapSps.value());
175
176 using TSC = Acts::TrackSelector::Config;
177 m_trackSelectorConfig = Acts::TrackSelector::EtaBinnedConfig(0.0);
178
179 auto commonConfig = [&](TSC &config) {
180 config.requireReferenceSurface = true;
181 config.loc1Min = m_offlineZ0Sel.value() ? -200_mm : -150_mm; // z0 min
182 config.loc1Max = m_offlineZ0Sel.value() ? 200_mm : 150_mm; // z0 max
183 };
184
186 .addCuts(2.0,
187 [&](TSC &config) {
188 commonConfig(config);
189 config.maxHoles = m_relaxCentralHoleSel.value() ? 4 : 2;
190 config.minMeasurements = m_relaxMeasurementSel.value() ? 7 : 9;
191 config.ptMin = 900_MeV;
192 config.loc0Max = 2_mm; // d0 max
193 config.loc0Min = -2_mm; // d0 min
194 })
195 .addCuts(2.6,
196 [&](TSC &config) {
197 commonConfig(config);
198 config.maxHoles = m_relaxCentralHoleSel.value() ? 4 : 2;
199 config.minMeasurements = m_relaxMeasurementSel.value() ? 7 : 8;
200 config.ptMin = 400_MeV;
201 config.loc0Max = 2_mm; // d0 max
202 config.loc0Min = -2_mm; // d0 min
203 })
204 .addCuts([&](TSC &config) {
205 commonConfig(config);
206 config.maxHoles = 2;
207 config.minMeasurements = 7;
208 config.ptMin = 400_MeV;
209 config.loc0Max = 10_mm; // d0 max
210 config.loc0Min = -10_mm; // d0 min
211 });
212
213 ACTS_INFO("Track selector config:\n" << m_trackSelectorConfig);
214
215 ACTS_DEBUG("TrackFindingGNNAlg::initialize() - end");
216 return StatusCode::SUCCESS;
217}
218
219// === execute =============================================================
220
221StatusCode TrackFindingGNNAlg::execute(const EventContext &ctx) const {
222 ACTS_DEBUG("TrackFindingGNNAlg::execute() - begin");
223
224 std::optional<Athena::Chrono> timer;
225 timer.emplace("GNN get spacepoint handles", m_chronoSvc.get());
226
227 Acts::GeometryContext gctx =
228 m_trackingGeometryTool->getGeometryContext(ctx).context();
229 Acts::MagneticFieldContext mctx =
230 m_extrapolationTool->getMagneticFieldContext(ctx);
231 Acts::CalibrationContext cctx = ActsTrk::getCalibrationContext(ctx);
232
233 auto detElToGeoIdMap = m_trackingGeometryTool->surfaceIdMap();
234
235 // Build features
236 auto pixelSPHandle = SG::makeHandle(m_xaodPixelSpacePointContainerKey, ctx);
237 ATH_CHECK(pixelSPHandle.isValid());
238 const auto &pixelSPContainer = *pixelSPHandle.cptr();
239
240 auto stripSPHandle = SG::makeHandle(m_xaodStripSpacePointContainerKey, ctx);
241 ATH_CHECK(stripSPHandle.isValid());
242 const auto &stripSPContainer = *stripSPHandle.cptr();
243
244 auto stripSPOVHandle =
246 ATH_CHECK(stripSPOVHandle.isValid());
247 const auto &stripSPOVContainer = *stripSPOVHandle.cptr();
248
249 constexpr std::size_t nFeatures = 12;
250 std::size_t nSP = pixelSPContainer.size() + stripSPContainer.size() +
251 stripSPOVContainer.size();
252
253 ACTS_DEBUG("Number spacepoints: "
254 << nSP << " (" << "pixel: " << pixelSPContainer.size() << ", "
255 << "strip: " << stripSPContainer.size() << ", "
256 << "strip overlap: " << stripSPOVContainer.size() << ")");
257
258
259 timer.emplace("GNN extract data", m_chronoSvc.get());
260
261 std::vector<std::uint64_t> moduleIds;
262 moduleIds.reserve(nSP);
263 std::vector<const xAOD::SpacePoint *> allSPPtrs;
264 allSPPtrs.reserve(nSP);
265 std::vector<Acts::GeometryIdentifier> geoIds, sortedGeoIds(nSP);
266 geoIds.reserve(nSP);
267
268 std::size_t skipped = 0;
269 for (const auto &spc :
270 {pixelSPContainer, stripSPContainer, stripSPOVContainer}) {
271 for (auto sp : spc) {
272 auto cl1 = sp->measurements().front();
273 auto geoIdCl1 =
274 ActsTrk::getSurfaceGeometryIdOfMeasurement(*detElToGeoIdMap, *cl1);
275 Identifier atlasIdCl1(static_cast<Identifier::value_type>(cl1->identifier()));
276
277 if ( sp->measurements().size() == 2) {
278 auto cl2 = sp->measurements().at(1);
279 Identifier atlasIdCl2(static_cast<Identifier::value_type>(cl2->identifier()));
280
281 auto overlapFlag =
282 compute_overlap_SP_flag(m_stripIdHelper->eta_module(atlasIdCl1),
283 m_stripIdHelper->phi_module(atlasIdCl1),
284 m_stripIdHelper->eta_module(atlasIdCl2),
285 m_stripIdHelper->phi_module(atlasIdCl2));
286
287 if (overlapFlag == 2 || overlapFlag == 3) {
288 skipped++;
289 ACTS_VERBOSE("Skip phi overlap spacepoint (flag=" << overlapFlag
290 << ")");
291 continue;
292 }
293 }
294
295 geoIds.push_back(geoIdCl1);
296 moduleIds.push_back(atlasIdCl1.get_compact());
297 allSPPtrs.push_back(sp);
298 }
299 }
300
301 ACTS_DEBUG("Skipped " << skipped << " SPs because of phi overlap");
302 nSP = allSPPtrs.size();
303 ACTS_DEBUG("Keep " << nSP << " SPs for feature creation");
304
305 timer.emplace("GNN build input tensor", m_chronoSvc.get());
306
307 std::vector<std::size_t> idxs(nSP);
308 std::iota(idxs.begin(), idxs.end(), 0);
309
310 std::ranges::sort(
311 idxs, [&](auto a, auto b) { return moduleIds.at(a) < moduleIds.at(b); });
312 std::ranges::sort(moduleIds);
313
314 std::vector<float> features(nFeatures * nSP);
315 std::vector<boost::container::static_vector<Acts::SourceLink, 2>> sourceLinks(
316 nSP);
317 std::vector<int> id(nSP);
318
319 for (auto k = 0ul; k < nSP; k++) {
320 id.at(k) = k;
321 auto i = idxs.at(k);
322
323 std::span<float> f(features.data() + k * nFeatures, nFeatures);
324 const auto &sp = *allSPPtrs.at(i);
325
326 using namespace Acts::VectorHelpers;
327 using namespace Acts::AngleHelpers;
328
329 Acts::Vector3 spp{sp.x(), sp.y(), sp.z()};
330
331 if (sp.measurements().size() == 1) {
332 for (auto j = 0ul; j < nFeatures; j += 4) {
333 f[j + 0] = perp(spp) / 1000.f;
334 f[j + 1] = phi(spp) / std::numbers::pi_v<float>;
335 f[j + 2] = sp.z() / 1000.f;
336 f[j + 3] = eta(spp);
337 }
338 } else {
339 std::size_t j = 0;
340 f[j + 0] = perp(spp) / 1000.f;
341 f[j + 1] = phi(spp) / std::numbers::pi_v<float>;
342 f[j + 2] = sp.z() / 1000.f;
343 f[j + 3] = eta(spp);
344
345 for (auto m : sp.measurements()) {
346 auto cl = static_cast<const xAOD::StripCluster *>(m);
347 auto gp = cl->globalPosition();
348 j += 4;
349 f[j + 0] = perp(gp) / 1000.f;
350 f[j + 1] = phi(gp) / std::numbers::pi_v<float>;
351 f[j + 2] = gp.z() / 1000.f;
352 f[j + 3] = eta(gp);
353 }
354 }
355
356 for (const xAOD::UncalibratedMeasurement* m : sp.measurements()) {
357 sourceLinks.at(k).push_back(detail::MeasurementCalibratorBase::pack(m));
358 }
359
360 sortedGeoIds.at(k) = geoIds.at(i);
361 }
362
363 timer.reset();
364 timer.emplace("GNN inference", m_chronoSvc.get());
365
366 m_gpuInstanceCount->acquire();
367 auto candidates =
368 m_gnnPipeline->run(features, moduleIds, id, ActsPlugins::Device::Cuda(m_cudaDeviceIndex.value()));
369 m_gpuInstanceCount->release();
370
371 ACTS_DEBUG("Have " << candidates.size() << " candidates after GNN");
372
373 // Remove candidates if they either have less then the configured amount of measurements, or no pixel hit
374 auto candidateSelector = [&](const std::vector<int> &c) {
375 bool tooFewMeasurements = std::accumulate(c.begin(), c.end(), 0ul, [&](auto sum, auto spi) {
376 return sum + allSPPtrs.at(spi)->measurements().size();
377 }) < m_minCandidateMeasurements.value();
378 bool noPixelHits = !std::ranges::any_of(c, [&](auto spi) { return allSPPtrs.at(spi)->measurements().size() == 1; });
379 return tooFewMeasurements || noPixelHits;
380 };
381
382 candidates.erase(std::remove_if(candidates.begin(), candidates.end(), candidateSelector),
383 candidates.end());
384 ACTS_DEBUG("Candidates left with >= " << m_minCandidateMeasurements.value()
385 << " measurements: " << candidates.size());
386
387 timer.reset();
388 timer.emplace("GNN parameter estimation + fit", m_chronoSvc.get());
389
390 Acts::VectorTrackContainer trackBackend;
391 Acts::VectorMultiTrajectory trackStateBackend;
392 constexpr std::size_t nTracksExpected = 3000;
393 trackBackend.reserve(nTracksExpected);
394 trackStateBackend.reserve(nTracksExpected * 30);
395 detail::RecoTrackContainer tracks(trackBackend, trackStateBackend);
396
397 // v45: Create SeedContainer to hold seeds (Seeds are now proxy objects)
398 ActsTrk::SeedContainer seedContainer;
399
400 auto makeSeedFromCandidate = [&](const std::vector<int> &cand) -> std::optional<boost::container::small_vector<const xAOD::SpacePoint*, 3>> {
401 // Select at least 3 SPs with deltaR spacing in cylindrical coordinates
402 boost::container::small_vector<const xAOD::SpacePoint*, 3> picked;
403 if (cand.empty()) return std::nullopt;
404 auto r_of = [&](const xAOD::SpacePoint* sp) {
405 Acts::Vector3 v{sp->x(), sp->y(), sp->z()};
406 return v.perp();
407 };
408 const xAOD::SpacePoint* last = allSPPtrs.at(cand.front());
409 picked.push_back(last);
410 for (std::size_t i = 1; i < cand.size() && picked.size() < 3; ++i) {
411 const xAOD::SpacePoint* sp = allSPPtrs.at(cand.at(i));
412 if (std::abs(r_of(sp) - r_of(last)) > m_minDeltaR.value()) {
413 picked.push_back(sp);
414 last = sp;
415 }
416 }
417 if (picked.size() < 3) return std::nullopt;
418 return picked;
419 };
420
421 auto retrieveSurface = [&](const ActsTrk::Seed& seed, bool useTopSp) -> const Acts::Surface& {
422 const xAOD::SpacePoint* sp = useTopSp ? seed.sp().front() : seed.sp().back();
423 auto geoId = ActsTrk::getSurfaceGeometryIdOfMeasurement(*detElToGeoIdMap, *sp->measurements().front());
424 const auto* surface = m_trackingGeometryTool->trackingGeometry()->findSurface(geoId);
425 if (!surface) {
426 throw std::runtime_error("retrieveSurface: no Acts surface for GeometryIdentifier " + std::to_string(geoId.value()));
427 }
428 return *surface;
429 };
430
431 auto R_of = [](const xAOD::SpacePoint* sp) {
432 return Acts::fastHypot(sp->x(), sp->y(), sp->z());
433 };
434
435 for (const auto &cand : candidates) {
436 auto pickedOpt = makeSeedFromCandidate(cand);
437 if (!pickedOpt.has_value()) continue;
438
439 auto picked = *pickedOpt;
440 std::sort(picked.begin(), picked.end(),
441 [&](const xAOD::SpacePoint* a, const xAOD::SpacePoint* b) {
442 return R_of(a) < R_of(b);
443 });
444 ActsTrk::Seed seed = seedContainer.push_back(
445 ActsTrk::SpacePointRange(picked.data(), picked.size()), 0.f, 0.f);
446
447 auto initialParamsOpt = m_paramEstimationTool->estimateTrackParameters(
448 seed, /*useTopSp=*/true, gctx, mctx, retrieveSurface);
449 if (!initialParamsOpt.has_value()) continue;
450
451 boost::container::small_vector<const xAOD::SpacePoint*, 16> sortedSP;
452 sortedSP.reserve(cand.size());
453 for (int spi : cand) sortedSP.push_back(allSPPtrs.at(spi));
454 std::sort(sortedSP.begin(), sortedSP.end(),
455 [&](const xAOD::SpacePoint* a, const xAOD::SpacePoint* b) {
456 return R_of(a) < R_of(b);
457 });
458
459 std::vector<const xAOD::UncalibratedMeasurement*> measList;
460 measList.reserve(sortedSP.size() * 2);
461 for (const xAOD::SpacePoint* sp : sortedSP) {
462 for (const xAOD::UncalibratedMeasurement* m : sp->measurements()) {
463 measList.push_back(m);
464 }
465 }
466
467 auto fitted = m_fitterTool->fit(measList, *initialParamsOpt, gctx, mctx, cctx);
468 if (fitted) {
469 for (auto track : *fitted) {
470 auto newTrack = tracks.makeTrack();
471 newTrack.copyFrom(track);
472 }
473 }
474 }
475
476 ACTS_DEBUG("After track fit: " << tracks.size() << " / " << candidates.size()
477 << " successfull");
478
479 // For single muon/electron case
480 if (candidates.size() == 1 && tracks.size() == 1) {
481 const auto &t = *tracks.begin();
482 ACTS_DEBUG("Single particle case: " << candidates.front().size() << " -> "
483 << t.nMeasurements()
484 << " measurements");
485 }
486
487 timer.reset();
488 timer.emplace("Track selection & conversion", m_chronoSvc.get());
489
490 Acts::VectorTrackContainer selTrackBackend;
491 selTrackBackend.reserve(trackBackend.size());
492 detail::RecoTrackContainer selectedTracks(selTrackBackend, trackStateBackend);
493
494 Acts::TrackSelector selector(m_trackSelectorConfig);
495 for (auto track : tracks) {
496 if (selector.isValidTrack(track)) {
497 auto newTrack = selectedTracks.makeTrack();
498
499 // v45: copyFrom now copies everything including tip/stem indices
500 newTrack.copyFrom(track);
501 }
502 }
503
504 ACTS_DEBUG("GNN cand: " << candidates.size() << ", fitted: " << tracks.size()
505 << ", selected: " << selectedTracks.size());
506
507 // Write tracks to storage again
508 Acts::ConstVectorTrackContainer constTrackBackend(std::move(selTrackBackend));
509 Acts::ConstVectorMultiTrajectory constTrackStateBackend(std::move(trackStateBackend));
510 std::unique_ptr<ActsTrk::TrackContainer> constTracksContainer
511 = std::make_unique<ActsTrk::TrackContainer>(std::move(constTrackBackend), std::move(constTrackStateBackend) );
512
513 ACTS_DEBUG("Storing track collection with key '" << m_trackContainerKey.key() << "'");
515 ATH_CHECK(trackContainerHandle.record(std::move(constTracksContainer)));
516
517 return StatusCode::SUCCESS;
518}
519} // namespace ActsTrk
Scalar eta() const
pseudorapidity method
Scalar perp() const
perp method - perpendicular length
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
static Double_t sp
static Double_t a
std::unique_ptr< const Acts::Logger > makeActsAthenaLogger(IMessageSvc *svc, const std::string &name, int level, std::optional< std::string > parent_name)
Gaudi::Property< std::string > m_moduleMapPath
Gaudi::Property< std::string > m_gnnPath
Gaudi::Property< bool > m_relaxCentralHoleSel
std::unique_ptr< const Acts::Logger > m_logger
logging instance
ToolHandle< ActsTrk::IFitterTool > m_fitterTool
Acts::TrackSelector::EtaBinnedConfig m_trackSelectorConfig
Gaudi::Property< unsigned int > m_numTrtContexts
ToolHandle< ActsTrk::ITrackParamsEstimationTool > m_paramEstimationTool
Gaudi::Property< double > m_edgeCut
virtual StatusCode initialize() override
Gaudi::Property< bool > m_relaxMeasurementSel
std::unique_ptr< ActsPlugins::GnnPipeline > m_gnnPipeline
SG::ReadHandleKey< xAOD::SpacePointContainer > m_xaodStripSpacePointOverlapContainerKey
SG::WriteHandleKey< ActsTrk::TrackContainer > m_trackContainerKey
Gaudi::Property< bool > m_offlineZ0Sel
virtual StatusCode execute(const EventContext &ctx) const override
detail::OnTrackCalibrator< ActsTrk::MutableTrackStateBackend > m_uncalibMeasCalibrator
PublicToolHandle< ITrackingGeometryTool > m_trackingGeometryTool
SG::ReadHandleKey< xAOD::SpacePointContainer > m_xaodPixelSpacePointContainerKey
Gaudi::Property< unsigned int > m_minCandidateMeasurements
TrackFindingGNNAlg(const std::string &name, ISvcLocator *pSvcLocator)
ToolHandle< ActsTrk::IExtrapolationTool > m_extrapolationTool
Gaudi::Property< unsigned int > m_maxGpuInstances
Gaudi::Property< double > m_minDeltaR
ServiceHandle< IChronoStatSvc > m_chronoSvc
Gaudi::Property< bool > m_usePhiOverlapSps
SG::ReadHandleKey< xAOD::SpacePointContainer > m_xaodStripSpacePointContainerKey
detail::xAODUncalibMeasSurfAcc m_uncalibMeasSurfAccessor
Gaudi::Property< int > m_cudaDeviceIndex
static Acts::SourceLink pack(const Ptr_t &measurement)
Pack the measurement type pointer to an Acts::SourceLink including the intermediate conversion into a...
static OnTrackCalibrator NoCalibration(const ActsTrk::ITrackingGeometryTool *trackGeoTool)
Constructs a calibrator which copies the local position & covariance of the ITk measurements onto the...
Helper class to access the Acts::surface associated with an Uncalibrated xAOD measurement.
const ServiceHandle< StoreGateSvc > & detStore() const
An algorithm that can be simultaneously executed in multiple threads.
value_type get_compact() const
Get the compact id.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
Acts::TrackContainer< Acts::VectorTrackContainer, Acts::VectorMultiTrajectory > RecoTrackContainer
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
Acts::GeometryIdentifier getSurfaceGeometryIdOfMeasurement(const DetectorElementToActsGeometryIdMap &detector_element_to_geoid, const xAOD::UncalibratedMeasurement &measurement)
Acts::CalibrationContext getCalibrationContext(const EventContext &ctx)
The Acts::Calibration context is piped through the Acts fitters to (re)calibrate the Acts::SourceLink...
int compute_overlap_SP_flag(const int &eta_module_cl1, const int &phi_module_cl1, const int &eta_module_cl2, const int &phi_module_cl2)
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
bool flag
Definition master.py:29
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
DataModel_detail::iterator< DVL > remove_if(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end, Predicate pred)
Specialization of remove_if for DataVector/List.
StripCluster_v1 StripCluster
Define the version of the strip cluster class.
UncalibratedMeasurement_v1 UncalibratedMeasurement
Define the version of the uncalibrated measurement class.
Seed push_back(SpacePointRange spacePoints, float quality, float vertexZ)