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