ATLAS Offline Software
Loading...
Searching...
No Matches
TrackFindingAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7// Athena
12
13// ACTS
14#include "Acts/Geometry/TrackingGeometry.hpp"
15#include "Acts/Geometry/GeometryIdentifier.hpp"
16#include "Acts/Utilities/TrackHelpers.hpp"
17#include "Acts/TrackFitting/MbfSmoother.hpp"
18#include "Acts/Utilities/Logger.hpp"
19#include "ActsInterop/Logger.h"
20
21// ActsTrk
29
30// STL
31#include <Acts/Propagator/StandardAborters.hpp>
32#include <sstream>
33#include <functional>
34#include <stdexcept>
35#include <utility>
36#include <algorithm>
37#include <variant>
38
39namespace {
40 static std::size_t sourceLinkHash(const Acts::SourceLink& slink) {
41 const ActsTrk::ATLASUncalibSourceLink &atlasSourceLink = slink.get<ActsTrk::ATLASUncalibSourceLink>();
42 const xAOD::UncalibratedMeasurement &uncalibMeas = ActsTrk::getUncalibratedMeasurement(atlasSourceLink);
43 return uncalibMeas.identifier();
44 }
45
46 static bool sourceLinkEquality(const Acts::SourceLink& a, const Acts::SourceLink& b) {
49 return uncalibMeas_a.identifier() == uncalibMeas_b.identifier();
50 }
51
52 static std::optional<ActsTrk::detail::RecoTrackStateContainerProxy> getFirstMeasurementFromTrack(typename ActsTrk::detail::RecoTrackContainer::TrackProxy trackProxy) {
53 std::optional<ActsTrk::detail::RecoTrackStateContainerProxy> firstMeasurement {std::nullopt};
54 for (auto st : trackProxy.trackStatesReversed()) {
55 // We are excluding non measurement states and outlier here. Those can
56 // decrease resolution because only the smoothing corrected the very
57 // first prediction as filtering is not possible.
58 if (not st.typeFlags().hasMeasurement()) continue;
59 if (st.typeFlags().isOutlier()) continue;
60 firstMeasurement = st;
61 }
62 return firstMeasurement;
63 }
64
65}
66
67
68
69namespace ActsTrk
70{
72
73 TrackFindingAlg::TrackFindingAlg(const std::string &name, ISvcLocator *pSvcLocator)
74 : TrackFindingBaseAlg(name, pSvcLocator) {}
75
76 // === initialize ==========================================================
77
79 {
80 ATH_MSG_INFO("Initializing " << name() << " ... ");
81
94
96 ATH_CHECK(m_seedContainerKeys.initialize());
97 ATH_CHECK(m_detEleCollKeys.initialize());
100 ATH_CHECK(m_detElStatus.initialize());
101 ATH_CHECK(m_beamSpotKey.initialize());
102
103 m_storeDestinies = not m_seedDestiny.empty();
105
106 if (m_seedContainerKeys.size() != m_detEleCollKeys.size())
107 {
108 ATH_MSG_FATAL("There are " << m_detEleCollKeys.size() << " DetectorElementsKeys, but " << m_seedContainerKeys.size() << " SeedContainerKeys");
109 return StatusCode::FAILURE;
110 }
111
112 if (m_detEleCollKeys.size() != m_seedLabels.size())
113 {
114 ATH_MSG_FATAL("There are " << m_seedLabels.size() << " SeedLabels, but " << m_detEleCollKeys.size() << " DetectorElementsKeys");
115 return StatusCode::FAILURE;
116 }
117
118 if (m_useTopSpRZboundary.size() != 2)
119 {
120 ATH_MSG_FATAL("useTopSpRZboundary must have 2 elements, but has " << m_useTopSpRZboundary.size());
121 return StatusCode::FAILURE;
122 }
123
124 if (m_ambiStrategy != 0u /* OUTSIDE_TF */) m_showResolvedStats = true;
125 if (m_ambiStrategy == 1u /* END_OF_TF */) {
126 Acts::GreedyAmbiguityResolution::Config cfg;
127 cfg.maximumSharedHits = m_maximumSharedHits;
128 cfg.maximumIterations = m_maximumIterations;
129 cfg.nMeasurementsMin = m_nMeasurementsMin;
130
131 m_ambi.emplace(std::move(cfg), makeActsAthenaLogger(this, "Acts"));
132 }
133
134 if (m_storeDestinies) {
135 if (m_seedDestiny.size() != m_seedContainerKeys.size()) {
136 ATH_MSG_ERROR("There are " << m_seedDestiny.size() << " seed destiny collections, but " << m_seedContainerKeys.size() << " seed collections");
137 return StatusCode::FAILURE;
138 }
139 }
140
141 return StatusCode::SUCCESS;
142 }
143
144 // === finalize ============================================================
145
148 return StatusCode::SUCCESS;
149 }
150
151 // === execute =============================================================
152
153 StatusCode TrackFindingAlg::execute(const EventContext &ctx) const
154 {
155 ATH_MSG_DEBUG("Executing " << name() << " ... ");
156
157 auto timer = Monitored::Timer<std::chrono::milliseconds>("TIME_execute");
158 auto mon_nTracks = Monitored::Scalar<int>("nTracks");
159 auto mon = Monitored::Group(m_monTool, timer, mon_nTracks);
160
161 // ================================================== //
162 // ===================== INPUTS ===================== //
163 // ================================================== //
164
165 // SEED TRIPLETS
166 std::vector<const ActsTrk::SeedContainer *> seedContainers;
167 std::size_t total_seeds = 0;
168 ATH_CHECK(getContainersFromKeys(ctx, m_seedContainerKeys, seedContainers, total_seeds));
169
170 // DESTINIES
171 std::vector< std::unique_ptr< std::vector<int> > > destinies {};
172 if (m_storeDestinies) {
173 destinies.reserve( seedContainers.size() );
174 for (std::size_t i(0); i<seedContainers.size(); ++i) {
175 destinies.push_back( std::make_unique< std::vector<int> >( seedContainers.at(i)->size(), DestinyType::UNKNOWN) );
176 }
177 }
178
179 // MEASUREMENTS
180 std::vector<const xAOD::UncalibratedMeasurementContainer *> uncalibratedMeasurementContainers;
181 std::size_t total_measurements = 0;
182 ATH_CHECK(getContainersFromKeys(ctx, m_uncalibratedMeasurementContainerKeys, uncalibratedMeasurementContainers, total_measurements));
183
184 // map detector element status to volume ids
186 volumeIdToDetectorElementCollMap(m_volumeIdToDetectorElementCollMapKey,ctx);
187 ATH_CHECK(volumeIdToDetectorElementCollMap.isValid());
188 std::vector< const InDet::SiDetectorElementStatus *> det_el_status_arr;
189 const std::vector<const InDetDD::SiDetectorElementCollection*> &det_el_collections =volumeIdToDetectorElementCollMap->collections();
190 det_el_status_arr.resize( det_el_collections.size(), nullptr);
192 SG::ReadHandle<InDet::SiDetectorElementStatus> det_el_status(det_el_status_key,ctx);
193 ATH_CHECK( det_el_status.isValid());
194 const std::vector<const InDetDD::SiDetectorElementCollection*>::const_iterator
195 det_el_col_iter = std::find(det_el_collections.begin(),
196 det_el_collections.end(),
197 &det_el_status->getDetectorElements());
198 det_el_status_arr.at(det_el_col_iter - det_el_collections.begin()) = det_el_status.cptr();
199 }
200
201 detail::MeasurementIndex measurementIndex(uncalibratedMeasurementContainers.size());
202 for (std::size_t icontainer = 0; icontainer < uncalibratedMeasurementContainers.size(); ++icontainer) {
203 measurementIndex.addMeasurements(*uncalibratedMeasurementContainers[icontainer]);
204 }
205
206 detail::TrackFindingMeasurements measurements(uncalibratedMeasurementContainers.size());
207 for (std::size_t icontainer = 0; icontainer < uncalibratedMeasurementContainers.size(); ++icontainer) {
208 ATH_MSG_DEBUG("Create " << uncalibratedMeasurementContainers[icontainer]->size() << " source links from measurements in " << m_uncalibratedMeasurementContainerKeys[icontainer].key());
209 measurements.addMeasurements(icontainer,
210 *uncalibratedMeasurementContainers[icontainer],
211 *m_trackingGeometryTool->surfaceIdMap(),
212 m_forceTrackOnSeed ? &measurementIndex : nullptr);
213 }
214
215 ATH_MSG_DEBUG("measurement index size = " << measurementIndex.size());
216
217 ATH_CHECK( propagateDetectorElementStatusToMeasurements(*(volumeIdToDetectorElementCollMap.cptr()), det_el_status_arr, measurements) );
218
219 if (m_trackStatePrinter.isSet()) {
220 m_trackStatePrinter->printMeasurements(ctx, uncalibratedMeasurementContainers, measurements.measurementOffsets());
221 }
222
223 detail::DuplicateSeedDetector duplicateSeedDetector(total_seeds,
224 m_seedMeasOffset.value(),
226 for (std::size_t icontainer = 0; icontainer < seedContainers.size(); ++icontainer)
227 {
228 duplicateSeedDetector.addSeeds(icontainer, *seedContainers[icontainer], measurementIndex,
229 m_paramEstimationTool->spacePointIndicesFun(),
230 [this,icontainer](const ActsTrk::Seed& seed) -> bool {
231 const bool reverseSearch = m_autoReverseSearch && shouldReverseSearch(seed);
232 const bool refitSeeds = icontainer < m_refitSeeds.size() && m_refitSeeds[icontainer];
233 const bool useTopSp = reverseSearch && !refitSeeds;
234 return useTopSp;
235 });
236 }
237
238 // Get Beam pos and make pSurface
240 ATH_CHECK( beamSpotHandle.isValid() );
241 const InDet::BeamSpotData* beamSpotData = beamSpotHandle.cptr();
242
243 // Beam Spot Position
244 Acts::Vector3 beamPos( beamSpotData->beamPos().x() * Acts::UnitConstants::mm,
245 beamSpotData->beamPos().y() * Acts::UnitConstants::mm,
246 0 );
247
248 // Construct a perigee surface as the target surface
249 std::shared_ptr<Acts::PerigeeSurface> pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(beamPos);
250
251 // ================================================== //
252 // ===================== CONDS ====================== //
253 // ================================================== //
254
255 std::vector<const InDetDD::SiDetectorElementCollection*> detElementsCollections;
256 std::size_t total_detElems = 0;
257 ATH_CHECK(getContainersFromKeys(ctx, m_detEleCollKeys, detElementsCollections, total_detElems));
258
259 // ================================================== //
260 // ===================== COMPUTATION ================ //
261 // ================================================== //
262 Acts::VectorTrackContainer actsTrackBackend;
263 Acts::VectorMultiTrajectory actsTrackStateBackend;
264 {
265 std::lock_guard<std::mutex> lock( m_mutex );
266 actsTrackBackend.reserve(m_nTrackReserve);
267 actsTrackStateBackend.reserve(m_nTrackStateReserve);
268 }
269 detail::RecoTrackContainer actsTracksContainer(actsTrackBackend,
270 actsTrackStateBackend);
271
272 if (m_addCounts) {
273 addCounts(actsTracksContainer);
274 }
275
276 detail::ExpectedLayerPatternHelper::add(actsTracksContainer);
277
278 EventStats event_stat;
279 event_stat.resize(m_stat.size());
280
281 DetectorContextHolder detContext {
282 .geometry = m_trackingGeometryTool->getGeometryContext(ctx).context(),
283 .magField = m_extrapolationTool->getMagneticFieldContext(ctx),
284 // CalibrationContext converter not implemented yet.
285 .calib = getCalibrationContext(ctx)
286 };
287
288 detail::SharedHitCounter sharedHits;
289 std::optional<std::vector<unsigned int>> trackCategories;
290 if (m_ambi) trackCategories.emplace(); // only needed if m_ambiStrategy == END_OF_TF
291
292 // Perform the track finding for all initial parameters.
293 for (std::size_t icontainer = 0; icontainer < seedContainers.size(); ++icontainer)
294 {
295 ATH_CHECK(findTracks(detContext,
296 measurements,
297 measurementIndex,
298 sharedHits,
299 duplicateSeedDetector,
300 *seedContainers.at(icontainer),
301 *detElementsCollections.at(icontainer),
302 actsTracksContainer,
303 icontainer,
304 icontainer < m_seedLabels.size() ? m_seedLabels[icontainer].c_str() : m_seedContainerKeys[icontainer].key().c_str(),
305 event_stat,
306 m_storeDestinies ? destinies.at(icontainer).get() : nullptr,
307 *pSurface.get(),
308 trackCategories));
309 }
310
311 ATH_MSG_DEBUG(" \\__ Created " << actsTracksContainer.size() << " tracks");
312
313 mon_nTracks = actsTracksContainer.size();
314
315
316 // ================================================== //
317 // ===================== OUTPUTS ==================== //
318 // ================================================== //
319
320 // Save the seed destinies
321 if (m_storeDestinies) {
322 for (std::size_t i(0); i<destinies.size(); ++i) {
323 const SG::WriteHandleKey< std::vector<int> >& writeKey = m_seedDestiny.at(i);
324 // make the handle and record
325 SG::WriteHandle< std::vector<int> > destinyHandle = SG::makeHandle( writeKey, ctx );
326 ATH_CHECK( destinyHandle.record( std::move( destinies.at(i) ) ) );
327 }
328 }
329
330 {
331 std::lock_guard<std::mutex> lock( m_mutex );
332 // update the reserve space
333 if (actsTrackBackend.size() > m_nTrackReserve) {
334 m_nTrackReserve = static_cast<std::size_t>( std::ceil(m_memorySafetyMargin * actsTrackBackend.size()) );
335 }
336 if (actsTrackStateBackend.size() > m_nTrackStateReserve) {
337 m_nTrackStateReserve = static_cast<std::size_t>( std::ceil(m_memorySafetyMargin * actsTrackStateBackend.size()) );
338 }
339 }
340
341 // handle the ambiguity
342 // we potentially need to short list the track candidates and make some copies
343 if (not m_ambi) {
344 copyStats(event_stat);
345 // no need to shortlist anything. just use the actsTracksContainer
346 ATH_MSG_DEBUG(" \\__ Created " << actsTracksContainer.size() << " resolved tracks");
348 std::move(actsTrackBackend),
349 std::move(actsTrackStateBackend) ) );
350 return StatusCode::SUCCESS;
351 }
352
353 // we have asked for the ambi
354 // we start by shortlisting the container
355 Acts::VectorTrackContainer resolvedTrackBackend;
356 Acts::VectorMultiTrajectory resolvedTrackStateBackend;
357 resolvedTrackBackend.reserve( actsTrackBackend.size() );
358 resolvedTrackStateBackend.reserve( actsTrackStateBackend.size() );
359 detail::RecoTrackContainer resolvedTracksContainer(resolvedTrackBackend, resolvedTrackStateBackend);
360 detail::ExpectedLayerPatternHelper::add(resolvedTracksContainer);
361
362 if (m_addCounts) {
363 addCounts(resolvedTracksContainer);
364 }
365
366 // Start ambiguity resolution
367 Acts::GreedyAmbiguityResolution::State state;
368 m_ambi->computeInitialState(actsTracksContainer, state, &sourceLinkHash,
369 &sourceLinkEquality);
370 m_ambi->resolve(state);
371
372 // Copy the resolved tracks into the output container
373 // We need a different sharedHits counter here because it saves the track index
374 // and since I ran the resolving the track indices changed.
375 detail::SharedHitCounter sharedHits_forFinalAmbi;
376
377 // shotlist
378 for (auto iTrack : state.selectedTracks) {
379 int actsTrackIndex = state.trackTips.at(iTrack);
380 auto destProxy = resolvedTracksContainer.makeTrack();
381 destProxy.copyFrom(actsTracksContainer.getTrack(actsTrackIndex));
382
383 unsigned int category_i = trackCategories->at(actsTrackIndex);
384 ++event_stat[category_i][kNResolvedTracks];
385
386 if (m_countSharedHits) {
387 auto [nShared, nBadTrackMeasurements] = sharedHits_forFinalAmbi.computeSharedHits(destProxy, resolvedTracksContainer, measurementIndex);
388 if (nBadTrackMeasurements > 0)
389 ATH_MSG_ERROR("computeSharedHits: " << nBadTrackMeasurements << " track measurements not found in input track");
390 }
391 } // loop on tracks
392
393 ATH_MSG_DEBUG(" \\__ Created " << resolvedTracksContainer.size() << " resolved tracks");
394 copyStats(event_stat);
395
397 std::move(resolvedTrackBackend),
398 std::move(resolvedTrackStateBackend)) );
399
400 return StatusCode::SUCCESS;
401 }
402
403 StatusCode TrackFindingAlg::storeTrackCollectionToStoreGate(const EventContext& ctx,
404 Acts::VectorTrackContainer&& originalTrackBackend,
405 Acts::VectorMultiTrajectory&& originalTrackStateBackend) const
406 {
407 // convert to const
408 Acts::ConstVectorTrackContainer constTrackBackend( std::move(originalTrackBackend) );
409 Acts::ConstVectorMultiTrajectory constTrackStateBackend( std::move(originalTrackStateBackend) );
410 std::unique_ptr< ActsTrk::TrackContainer> constTracksContainer = std::make_unique< ActsTrk::TrackContainer >( std::move(constTrackBackend),
411 std::move(constTrackStateBackend) );
412
414 ATH_MSG_DEBUG(" \\__ Tracks Container `" << m_trackContainerKey.key() << "` created ...");
415 ATH_CHECK(trackContainerHandle.record(std::move(constTracksContainer)));
416 return StatusCode::SUCCESS;
417 }
418
420 const xAOD::SpacePoint* bottom_sp = seed.sp().front();
421
422 const double r = bottom_sp->radius();
423 const double z = std::abs(bottom_sp->z());
424
425 const double rBoundary = m_useTopSpRZboundary.value()[0];
426 const double zBoundary = m_useTopSpRZboundary.value()[1];
427
428 return r > rBoundary || z > zBoundary;
429 }
430
431 // === findTracks ==========================================================
432
433 StatusCode
435 const detail::TrackFindingMeasurements &measurements,
436 const detail::MeasurementIndex &measurementIndex,
437 detail::SharedHitCounter &sharedHits,
438 detail::DuplicateSeedDetector &duplicateSeedDetector,
439 const ActsTrk::SeedContainer &seeds,
440 const InDetDD::SiDetectorElementCollection& detElements,
441 detail::RecoTrackContainer &actsTracksContainer,
442 std::size_t typeIndex,
443 const char *seedType,
444 EventStats &event_stat,
445 std::vector<int>* destiny,
446 const Acts::PerigeeSurface& pSurface,
447 std::optional<std::vector<unsigned int>>& trackCategories) const
448 {
449 ATH_MSG_DEBUG(name() << "::" << __FUNCTION__);
450
451 auto [options, secondOptions, measurementSelector] = getDefaultOptions(detContext, measurements, &pSurface);
452
453 // ActsTrk::MutableTrackContainer tracksContainerTemp;
454 Acts::VectorTrackContainer trackBackend;
455 Acts::VectorMultiTrajectory trackStateBackend;
456 detail::RecoTrackContainer tracksContainerTemp(trackBackend, trackStateBackend);
457
458 if (m_addCounts) {
459 addCounts(tracksContainerTemp);
460 }
461
462 detail::ExpectedLayerPatternHelper::add(tracksContainerTemp);
463
464 std::size_t category_i = 0;
465 const auto &trackSelectorCfg = trackFinder().trackSelector.config();
466 auto stopBranchProxy = [&](const detail::RecoTrackContainer::TrackProxy &track,
467 const detail::RecoTrackContainer::TrackStateProxy &trackState) -> BranchStopperResult {
468 return stopBranch(track, trackState, trackSelectorCfg, detContext.geometry, measurementIndex, typeIndex, event_stat[category_i]);
469 };
470 options.extensions.branchStopper.connect(stopBranchProxy);
471
472 Acts::PropagatorOptions<detail::Stepper::Options, detail::Navigator::Options,
473 Acts::ActorList<Acts::MaterialInteractor>>
474 extrapolationOptions(detContext.geometry, detContext.magField);
475
476 Acts::TrackExtrapolationStrategy extrapolationStrategy =
477 Acts::TrackExtrapolationStrategy::first;
478
479 // Perform the track finding for all initial parameters
480 ATH_MSG_DEBUG("Invoke track finding with " << seeds.size() << ' ' << seedType << " seeds.");
481
482
483 std::size_t nPrinted = 0;
484
485 // Function for Estimate Track Parameters
486 auto retrieveSurfaceFunction =
487 [this, &detElements] (const ActsTrk::Seed& seed, bool useTopSp) -> const Acts::Surface& {
488 const xAOD::SpacePoint* sp = useTopSp ? seed.sp().back() : seed.sp().front();
489 const InDetDD::SiDetectorElement* element = detElements.getDetectorElement(useTopSp ? sp->elementIdList().back()
490 : sp->elementIdList().front());
491 const Trk::Surface& atlas_surface = element->surface();
492 return m_ATLASConverterTool->trkSurfaceToActsSurface(atlas_surface);
493 };
494
495
496
497 // Loop over the track finding results for all initial parameters
498 for (unsigned int iseed = 0; iseed < seeds.size(); ++iseed)
499 {
500 // Get the seed
501 const ActsTrk::Seed seed = seeds[iseed];
502
503 category_i = typeIndex * (m_statEtaBins.size() + 1);
504 tracksContainerTemp.clear();
505
506 const bool reverseSearch = m_autoReverseSearch && shouldReverseSearch(seed);
507 const bool refitSeeds = typeIndex < m_refitSeeds.size() && m_refitSeeds[typeIndex];
508 const bool useTopSp = reverseSearch && !refitSeeds;
509
510 // Check if the seed is a duplicate seed
511 const bool isDupSeed = duplicateSeedDetector.isDuplicate(typeIndex, iseed);
512
513 if (isDupSeed) {
514 ATH_MSG_DEBUG("skip " << seedType << " seed " << iseed << " - already found");
515 category_i = getSeedCategory(typeIndex, seed, useTopSp);
516 ++event_stat[category_i][kNTotalSeeds];
517 ++event_stat[category_i][kNDuplicateSeeds];
518 if (m_storeDestinies) destiny->at(iseed) = DestinyType::DUPLICATE;
519 if (!m_trackStatePrinter.isSet()) continue; // delay continue to estimate track parms for TrackStatePrinter?
520 }
521
522 // Set the option accordingly - we change the direction and the target surface accordingly
523 options.propagatorPlainOptions.direction = reverseSearch ? Acts::Direction::Backward() : Acts::Direction::Forward();
524 secondOptions.propagatorPlainOptions.direction = options.propagatorPlainOptions.direction.invert();
525 options.targetSurface = reverseSearch ? &pSurface : nullptr;
526 secondOptions.targetSurface = reverseSearch ? nullptr : &pSurface;
527 // TODO since the second pass is strictly an extension we should have a separate branch stopper which never drops and always extrapolates to the target surface
528
529 // Get first estimate of parameters from the seed
530 std::optional<Acts::BoundTrackParameters> optTrackParams =
531 m_paramEstimationTool->estimateTrackParameters(seed,
532 useTopSp,
533 detContext.geometry,
534 detContext.magField,
535 retrieveSurfaceFunction);
536
537 if (!optTrackParams) {
538 ATH_MSG_DEBUG("Failed to estimate track parameters for seed " << iseed);
539 if (!isDupSeed) {
540 category_i = getSeedCategory(typeIndex, seed, useTopSp);
541 ++event_stat[category_i][kNTotalSeeds];
542 ++event_stat[category_i][kNNoEstimatedParams];
543 if (m_storeDestinies) destiny->at(iseed) = DestinyType::FAILURE;
544 }
545 continue;
546 }
547
548 Acts::BoundTrackParameters *initialParameters = &(*optTrackParams);
549 printSeed(iseed, detContext, seeds, *initialParameters, measurementIndex, nPrinted, seedType);
550 if (isDupSeed) continue; // skip now if not done before
551
552 double etaInitial = -std::log(std::tan(0.5 * initialParameters->theta()));
553 category_i = getStatCategory(typeIndex, etaInitial);
554 ++event_stat[category_i][kNTotalSeeds]; // also updated for duplicate seeds
555 ++event_stat[category_i][kNUsedSeeds];
556
557 // Optional refit track parameters to get more refined value
558 std::unique_ptr<Acts::BoundTrackParameters> refitSeedParameters;
559 if (refitSeeds) {
560 refitSeedParameters = doRefit(seed, *initialParameters, detContext, reverseSearch);
561 if (refitSeedParameters.get() == nullptr) {
562 ++event_stat[category_i][kNRejectedRefinedSeeds];
563 if (m_storeDestinies) destiny->at(iseed) = DestinyType::FAILURE;
564 continue;
565 }
566 if (refitSeedParameters.get() != initialParameters) {
567 initialParameters = refitSeedParameters.get();
568 printSeed(iseed, detContext, seeds, *initialParameters, measurementIndex, nPrinted, seedType, true);
569 }
570 }
571
572 auto measurementRangesForced =
573 m_forceTrackOnSeed ? std::make_unique<ActsTrk::detail::MeasurementRangeListFlat>(measurements.setMeasurementRangesForced(seed, measurementIndex))
574 : nullptr;
575 measurementSelector->setMeasurementRangesForced(measurementRangesForced.get());
576 if (measurementRangesForced)
577 event_stat[category_i][kNForcedSeedMeasurements] += measurementRangesForced->size();
578
579 // Get the Acts tracks, given this seed
580 Acts::Result<std::vector<TrkProxy> > result =
581 trackFinder().ckf.findTracks(*initialParameters, options, tracksContainerTemp);
582
583 // The result for this seed
584 if (not result.ok()) {
585 ATH_MSG_WARNING("Track finding failed for " << seedType << " seed " << iseed << " with error" << result.error());
586 if (m_storeDestinies) destiny->at(iseed) = DestinyType::FAILURE;
587 continue;
588 }
589 auto &tracksForSeed = result.value();
590
591
592
593 std::size_t ntracks = 0ul;
594
595 // loop on the tracks we have just found from the seed
596 std::size_t nfirst = 0;
597 for (TrkProxy &firstTrack : tracksForSeed) {
598 // smoothing
599 auto smoothingResult = Acts::smoothTrack(detContext.geometry, firstTrack, logger(), Acts::MbfSmoother());
600 if (!smoothingResult.ok()) {
601 ATH_MSG_DEBUG("Smoothing for seed "
602 << iseed << " and first track " << firstTrack.index()
603 << " failed with error " << smoothingResult.error());
604 continue;
605 }
606
607 // if no two way, just add the track and move on
608 if (not m_doTwoWay) {
609 // add the track to the collection
610 ATH_CHECK( addTrack(detContext,
611 firstTrack,
612 pSurface,
613 extrapolationStrategy,
614 sharedHits,
615 actsTracksContainer,
616 measurementIndex,
617 tracksContainerTemp,
618 duplicateSeedDetector,
619 destiny,
620 event_stat,
621 ntracks,
622 iseed,
623 category_i,
624 seedType,
625 trackCategories) );
626 ++nfirst;
627 continue;
628 }
629
630 // TWO WAY STARTS HERE
631 // We need the first measurement of the track
632 std::optional<detail::RecoTrackStateContainerProxy> firstMeas = getFirstMeasurementFromTrack(firstTrack);
633 // we are supposed to find a measurement
634 if (not firstMeas.has_value()) {
635 ATH_MSG_ERROR("Could not retrieve first measurement from track proxy. Is it ill-formed?");
636 return StatusCode::FAILURE;
637 }
638 detail::RecoTrackStateContainerProxy& firstMeasurement = firstMeas.value();
639
640 // Get the tracks from the second track finding
641 std::vector<typename detail::RecoTrackContainer::TrackProxy> secondTracksForSeed =
642 doTwoWayTrackFinding(firstMeasurement,
643 firstTrack,
644 tracksContainerTemp,
645 secondOptions);
646
647 if ( secondTracksForSeed.empty() ) {
648 ATH_MSG_DEBUG("No viable result from second track finding for " << seedType << " seed " << iseed << " track " << nfirst);
649 ++event_stat[category_i][kNoSecond];
650 ATH_CHECK( addTrack(detContext,
651 firstTrack,
652 pSurface,
653 extrapolationStrategy,
654 sharedHits,
655 actsTracksContainer,
656 measurementIndex,
657 tracksContainerTemp,
658 duplicateSeedDetector,
659 destiny,
660 event_stat,
661 ntracks,
662 iseed,
663 category_i,
664 seedType,
665 trackCategories) );
666 }
667
668 // need to add tracks here
669 // do the stiching
670 // store the original previous state to restore it later
671 auto originalFirstMeasurementPrevious = firstMeasurement.previous();
672 for (auto &secondTrack : secondTracksForSeed) {
673 secondTrack.reverseTrackStates(true);
674
675 firstMeasurement.previous() = secondTrack.outermostTrackState().index();
676 secondTrack.tipIndex() = firstTrack.tipIndex();
677
678 if (reverseSearch) {
679 // smooth the full track
680 auto secondSmoothingResult = Acts::smoothTrack(detContext.geometry,
681 secondTrack,
682 logger());
683 if ( not secondSmoothingResult.ok() ) {
684 continue;
685 }
686 secondTrack.reverseTrackStates(true);
687 }
688
689 // Add track to collection
690 ATH_CHECK( addTrack(detContext,
691 secondTrack,
692 pSurface,
693 extrapolationStrategy,
694 sharedHits,
695 actsTracksContainer,
696 measurementIndex,
697 tracksContainerTemp,
698 duplicateSeedDetector,
699 destiny,
700 event_stat,
701 ntracks,
702 iseed,
703 category_i,
704 seedType,
705 trackCategories) );
706 } // loop on tracks
707
708 // finish the stiching
709 // restore the original previous state for the first track
710 firstMeasurement.previous() = originalFirstMeasurementPrevious;
711
712 nfirst++;
713 } // loop on tracks from seed
714
715 if (m_storeDestinies) {
716 if (ntracks == 0) {
717 destiny->at(iseed) = DestinyType::FAILURE;
718 } else {
719 destiny->at(iseed) = DestinyType::SUCCEED;
720 }
721 }
722
723 if (ntracks == 0) {
724 ATH_MSG_DEBUG("Track finding found no track candidates for " << seedType << " seed " << iseed);
725 ++event_stat[category_i][kNoTrack];
726 } else if (ntracks >= 2) {
727 ++event_stat[category_i][kMultipleBranches];
728 }
729
730 if (m_trackStatePrinter.isSet())
731 std::cout << std::flush;
732 } // loop on seeds
733
734 ATH_MSG_DEBUG("Completed " << seedType << " track finding with " << computeStatSum(typeIndex, kNOutputTracks, event_stat) << " track candidates.");
735
736 return StatusCode::SUCCESS;
737 }
738
739 void
742 detail::DuplicateSeedDetector &duplicateSeedDetector,
743 const detail::MeasurementIndex &measurementIndex) const {
744
745 const auto lastMeasurementIndex = track.tipIndex();
746 duplicateSeedDetector.newTrajectory();
747
748 tracksContainer.trackStateContainer().visitBackwards(
749 lastMeasurementIndex,
750 [&duplicateSeedDetector,&measurementIndex](const detail::RecoTrackStateContainer::ConstTrackStateProxy &state) -> void
751 {
752 // Check there is a source link
753 if (not state.hasUncalibratedSourceLink())
754 return;
755
756 // Fill the duplicate selector
757 auto sl = state.getUncalibratedSourceLink().template get<ATLASUncalibSourceLink>();
758 duplicateSeedDetector.addMeasurement(sl, measurementIndex);
759 }); // end visitBackwards
760 }
761
763 const std::vector< const InDet::SiDetectorElementStatus *> &det_el_status_arr,
764 detail::TrackFindingMeasurements &measurements) const {
765 const Acts::TrackingGeometry *
766 acts_tracking_geometry = m_trackingGeometryTool->trackingGeometry().get();
767 ATH_CHECK(acts_tracking_geometry != nullptr);
768
769 using Counter = struct { unsigned int n_volumes, n_volumes_with_status, n_missing_detector_elements, n_detector_elements, n_disabled_detector_elements;};
770 Counter counter {0u,0u,0u,0u,0u};
771 acts_tracking_geometry->visitVolumes([&counter,
772 &volume_id_to_det_el_coll,
773 &det_el_status_arr,
774 &measurements,
775 this](const Acts::TrackingVolume *volume_ptr) {
776 ++counter.n_volumes;
777 if (!volume_ptr) return;
778
780 det_el_status = det_el_status_arr.at(volume_id_to_det_el_coll.collecionMap().at(volume_ptr->geometryId().volume()));
781 if (det_el_status) {
782 ++counter.n_volumes_with_status;
783 volume_ptr->visitSurfaces([&counter, det_el_status, &measurements,this](const Acts::Surface *surface_ptr) {
784 if (!surface_ptr) return;
785 const Acts::Surface &surface = *surface_ptr;
786 const Acts::SurfacePlacementBase* detector_element = surface.surfacePlacement();
787 if (detector_element) {
788 ++counter.n_detector_elements;
789 const ActsDetectorElement *acts_detector_element = static_cast<const ActsDetectorElement*>(detector_element);
790 if (!det_el_status->isGood( acts_detector_element->identifyHash() )) {
791 ActsTrk::detail::MeasurementRange old_range = measurements.markSurfaceInsensitive(surface_ptr->geometryId());
792 if (!old_range.empty()) {
793 auto geoid_to_string = [](const Acts::GeometryIdentifier &id) -> std::string {
794 std::stringstream amsg;
795 amsg << id;
796 return amsg.str();
797 };
798 std::string a_msg ( geoid_to_string(surface_ptr->geometryId()));
799 ATH_MSG_WARNING("Reject " << (old_range.elementEndIndex() - old_range.elementBeginIndex())
800 << " measurements because surface " << a_msg);
801 }
802 ++counter.n_disabled_detector_elements;
803 }
804 }
805 }, true /*only sensitive surfaces*/);
806 }
807 else {
808 ++counter.n_missing_detector_elements;
809 }
810 });
811 ATH_MSG_DEBUG("Volumes with detector element status " << counter.n_volumes_with_status << " / " << counter.n_volumes
812 << " disabled detector elements " << counter.n_disabled_detector_elements
813 << " / " << counter.n_detector_elements
814 << " missing detector elements "
815 << counter.n_missing_detector_elements);
816 return StatusCode::SUCCESS;
817 }
818
819 std::size_t TrackFindingAlg::getSeedCategory(std::size_t typeIndex,
820 const ActsTrk::Seed& seed,
821 bool useTopSp) const
822 {
823 const xAOD::SpacePoint* sp = useTopSp ? seed.sp().back() : seed.sp().front();
824 const xAOD::SpacePoint::ConstVectorMap pos = sp->globalPosition();
825 double etaSeed = std::atanh(pos[2] / pos.norm());
826 return getStatCategory(typeIndex, etaSeed);
827 }
828
829 void TrackFindingAlg::printSeed(unsigned int iseed,
830 const DetectorContextHolder& detContext,
831 const ActsTrk::SeedContainer& seeds,
832 const Acts::BoundTrackParameters &seedParameters,
833 const detail::MeasurementIndex &measurementIndex,
834 std::size_t& nPrinted,
835 const char *seedType,
836 bool isKF) const
837 {
838 if (not m_trackStatePrinter.isSet()) return;
839
840 if (nPrinted == 0) {
841 ATH_MSG_INFO("CKF results for " << seeds.size() << ' ' << seedType << " seeds:");
842 }
843 ++nPrinted;
844 m_trackStatePrinter->printSeed(detContext.geometry, seeds[iseed], seedParameters, measurementIndex, iseed, isKF);
845 }
846
847namespace {
848struct Collector {
849 using result_type = TrackFindingAlg::ExpectedLayerPattern*;
850
851 template <typename propagator_state_t, typename stepper_t,
852 typename navigator_t>
853 Acts::Result<void> act(propagator_state_t& state, const stepper_t& /*stepper*/,
854 const navigator_t& navigator, result_type& result,
855 const Acts::Logger& /*logger*/) const {
856 const Acts::Surface* currentSurface = navigator.currentSurface(state.navigation);
857 if (currentSurface == nullptr) {
858 return Acts::Result<void>::success();
859 }
860
861 assert(result != nullptr && "Result type is nullptr");
862
863 if (currentSurface->surfacePlacement() != nullptr) {
864 const auto* detElem = dynamic_cast<const ActsDetectorElement*>(currentSurface->surfacePlacement());
865 if(detElem != nullptr) {
866 detail::addToExpectedLayerPattern(*result, *detElem);
867 }
868 }
869
870 return Acts::Result<void>::success();
871 }
872};
873}
874
876 const DetectorContextHolder& detContext,
878 const Acts::Surface &referenceSurface,
879 const detail::Extrapolator &propagator,
880 Acts::TrackExtrapolationStrategy strategy,
881 ExpectedLayerPattern& expectedLayerPattern) const {
882
883 Acts::PropagatorOptions<detail::Stepper::Options, detail::Navigator::Options,
884 Acts::ActorList<Acts::MaterialInteractor, Collector>>
885 options(detContext.geometry, detContext.magField);
886
887 auto findResult = findTrackStateForExtrapolation(
888 options.geoContext, track, referenceSurface, strategy, logger());
889
890 if (!findResult.ok()) {
891 ATH_MSG_WARNING("Failed to find track state for extrapolation");
892 return findResult.error();
893 }
894
895 auto &[trackState, distance] = *findResult;
896
897 options.direction = Acts::Direction::fromScalarZeroAsPositive(distance);
898
899 Acts::BoundTrackParameters parameters = track.createParametersFromState(trackState);
900 ATH_MSG_VERBOSE("Extrapolating track to reference surface at distance "
901 << distance << " with direction " << options.direction
902 << " with starting parameters " << parameters);
903
904 auto state = propagator.makeState<decltype(options), Acts::ForcedSurfaceReached>(referenceSurface, options);
905 ExpectedLayerPattern*& collectorResult = state.get<TrackFindingAlg::ExpectedLayerPattern*>();
906 collectorResult = &expectedLayerPattern;
907
908 auto initRes = propagator.initialize(state, parameters);
909 if(!initRes.ok()) {
910 ATH_MSG_WARNING("Failed to initialize propagation state: " << initRes.error().message());
911 return initRes.error();
912 }
913
914
915 auto propagateOnlyResult =
916 propagator.propagate(state);
917
918 if (!propagateOnlyResult.ok()) {
919 ATH_MSG_WARNING("Failed to extrapolate track: " << propagateOnlyResult.error().message());
920 return propagateOnlyResult.error();
921 }
922
923 auto propagateResult = propagator.makeResult(
924 std::move(state), propagateOnlyResult, options, true, &referenceSurface);
925
926 if (!propagateResult.ok()) {
927 ATH_MSG_WARNING("Failed to extrapolate track: " << propagateResult.error().message());
928 return propagateResult.error();
929 }
930
931 track.setReferenceSurface(referenceSurface.getSharedPtr());
932 track.parameters() = propagateResult->endParameters.value().parameters();
933 track.covariance() =
934 propagateResult->endParameters.value().covariance().value();
935
936 return Acts::Result<void>::success();
937 }
938
941 const Acts::Surface& pSurface,
942 const Acts::TrackExtrapolationStrategy& extrapolationStrategy,
943 detail::SharedHitCounter &sharedHits,
944 detail::RecoTrackContainer &actsTracksContainer,
945 const detail::MeasurementIndex& measurementIndex,
946 const detail::RecoTrackContainer& tracksContainerTemp,
947 detail::DuplicateSeedDetector& duplicateSeedDetector,
948 std::vector<int>* destiny,
949 EventStats& event_stat,
950 std::size_t& ntracks,
951 std::size_t iseed,
952 std::size_t category_i,
953 const char *seedType,
954 std::optional<std::vector<unsigned int>>& trackCategories) const
955 {
956
957 std::array<unsigned int, 4> expectedLayerPattern{};
958
959 // if the the perigeeSurface was not hit (in particular the case for the inside-out pass,
960 // the track has no reference surface and the extrapolation to the perigee has not been done
961 // yet.
962 if (not track.hasReferenceSurface()) {
963 auto extrapolationResult =
964 extrapolateTrackToReferenceSurface(detContext, track,
965 pSurface,
966 trackFinder().extrapolator,
967 extrapolationStrategy,
968 expectedLayerPattern);
969
970 if (not extrapolationResult.ok()) {
971 ATH_MSG_WARNING("Extrapolation for seed "
972 << iseed << " and " << track.index()
973 << " failed with error " << extrapolationResult.error()
974 << " dropping track candidate.");
975 if (m_storeDestinies) destiny->at(iseed) = DestinyType::FAILURE;
976 return StatusCode::SUCCESS;
977 }
978 }
979
980 // Before trimming, inspect encountered surfaces from all track states
981 for(const auto ts : track.trackStatesReversed()) {
982 const auto& surface = ts.referenceSurface();
983 if(surface.surfacePlacement() != nullptr) {
984 const auto* detElem = dynamic_cast<const ActsDetectorElement*>(surface.surfacePlacement());
985 if(detElem != nullptr) {
986 detail::addToExpectedLayerPattern(expectedLayerPattern, *detElem);
987 }
988 }
989 }
990
991 // Trim tracks
992 // - trimHoles
993 // - trimOutliers
994 // - trimMaterial
995 // - trimOtherNoneMeasurement
996 Acts::trimTrack(track, true, true, true, true);
997 Acts::calculateTrackQuantities(track);
998 if (m_addCounts) {
999 initCounts(track);
1000 for (const auto trackState : track.trackStatesReversed()) {
1001 updateCounts(track, trackState.typeFlags(), measurementType(trackState));
1002 }
1003 if (m_checkCounts) {
1004 checkCounts(track);
1005 }
1006 }
1007
1008 ++ntracks;
1009 ++event_stat[category_i][kNOutputTracks];
1010
1011 if ( not trackFinder().trackSelector.isValidTrack(track) or
1012 not selectCountsFinal(track)) {
1013 ATH_MSG_DEBUG("Track " << ntracks << " from " << seedType << " seed " << iseed << " failed track selection");
1014 if ( m_trackStatePrinter.isSet() ) {
1015 m_trackStatePrinter->printTrack(detContext.geometry, tracksContainerTemp, track, measurementIndex, true);
1016 }
1017 return StatusCode::SUCCESS;
1018 }
1019
1020 ++event_stat[category_i][kNSelectedTracks];
1021
1022 // Fill the track infos into the duplicate seed detector
1024 storeSeedInfo(tracksContainerTemp, track, duplicateSeedDetector, measurementIndex);
1025 }
1026
1027 auto actsDestProxy = actsTracksContainer.makeTrack();
1028 actsDestProxy.copyFrom(track); // make sure we copy track states!
1029
1030 detail::ExpectedLayerPatternHelper::set(actsDestProxy, expectedLayerPattern);
1031
1032 auto setTrackCategory = [&]() {
1033 if (!trackCategories) return;
1034 if (!(actsDestProxy.index() < trackCategories->size())) trackCategories->resize(actsDestProxy.index()+1);
1035 trackCategories->at(actsDestProxy.index()) = category_i;
1036 };
1037
1038 if (not m_countSharedHits) {
1039 return StatusCode::SUCCESS;
1040 }
1041
1042 auto [nShared, nBadTrackMeasurements] = sharedHits.computeSharedHits(actsDestProxy, actsTracksContainer, measurementIndex);
1043
1044 if (nBadTrackMeasurements > 0) {
1045 ATH_MSG_ERROR("computeSharedHits: " << nBadTrackMeasurements << " track measurements not found in input for " << seedType << " seed " << iseed << " track");
1046 }
1047
1048 ATH_MSG_DEBUG("found " << actsDestProxy.nSharedHits() << " shared hits in " << seedType << " seed " << iseed << " track");
1049
1050 event_stat[category_i][kNTotalSharedHits] += nShared;
1051
1052 if (m_ambiStrategy == 2u) { // run the ambiguity during track selection
1053
1054 if (actsDestProxy.nSharedHits() <= m_maximumSharedHits) {
1055 setTrackCategory();
1056 ++event_stat[category_i][kNResolvedTracks];
1057 }
1058 else { // track fails the shared hit selection
1059
1060 ATH_MSG_DEBUG("found " << actsDestProxy.nSharedHits() << " shared hits in " << seedType << " seed " << iseed << " track");
1061 // Reset the original track shared hits by running coumputeSharedHits
1062 // with removeSharedHits flag to true
1063 // nSharedRemoved contains the total shared hits that will be removed
1064 auto [nSharedRemoved, nRemoveBadTrackMeasurements] = sharedHits.computeSharedHits(actsDestProxy, actsTracksContainer, measurementIndex, true);
1065
1066 ATH_MSG_DEBUG("Removed " << nSharedRemoved << " shared hits in " << seedType << " seed " << iseed << " track and the matching track");
1067
1068 if (nRemoveBadTrackMeasurements > 0) {
1069 ATH_MSG_ERROR("computeSharedHits with remove flag ON: " << nRemoveBadTrackMeasurements <<
1070 " track measurements not found in input for " << seedType << " seed " << iseed << " track");
1071 }
1072
1073 if (actsDestProxy.nSharedHits() != 0) {
1074 ATH_MSG_ERROR("computeSharedHits with remove flag ON returned " <<
1075 actsDestProxy.nSharedHits()<< " while expecting 0 for" <<
1076 seedType << " seed " << iseed << " track");
1077 }
1078
1079 // Remove the track from the container
1080 actsTracksContainer.removeTrack(actsDestProxy.index());
1081 ATH_MSG_DEBUG("Track " << ntracks << " from " << seedType << " seed " << iseed << " failed shared hit selection");
1082 }
1083 }
1084 else {
1085 // run ambi later
1086 setTrackCategory();
1087 if (m_trackStatePrinter.isSet()) {
1088 m_trackStatePrinter->printTrack(detContext.geometry, actsTracksContainer, actsDestProxy, measurementIndex);
1089 }
1090 }
1091
1092 return StatusCode::SUCCESS;
1093 }
1094
1095} // namespace
#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_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
static Double_t sp
static Double_t a
Header file to be included by clients of the Monitored infrastructure.
std::unique_ptr< const Acts::Logger > makeActsAthenaLogger(IMessageSvc *svc, const std::string &name, int level, std::optional< std::string > parent_name)
#define z
IdentifierHash identifyHash() const
Identifier hash.
SG::WriteHandleKeyArray< std::vector< int > > m_seedDestiny
Gaudi::Property< bool > m_countSharedHits
Gaudi::Property< unsigned int > m_maximumSharedHits
Gaudi::Property< float > m_memorySafetyMargin
SG::ReadHandleKeyArray< xAOD::UncalibratedMeasurementContainer > m_uncalibratedMeasurementContainerKeys
SG::ReadHandleKeyArray< ActsTrk::SeedContainer > m_seedContainerKeys
std::size_t getSeedCategory(std::size_t typeIndex, const ActsTrk::Seed &seed, bool useTopSp) const
SG::ReadCondHandleKey< ActsTrk::ActsVolumeIdToDetectorElementCollectionMap > m_volumeIdToDetectorElementCollMapKey
SG::ReadCondHandleKeyArray< InDetDD::SiDetectorElementCollection > m_detEleCollKeys
StatusCode findTracks(const DetectorContextHolder &detContext, const detail::TrackFindingMeasurements &measurements, const detail::MeasurementIndex &measurementIndex, detail::SharedHitCounter &sharedHits, detail::DuplicateSeedDetector &duplicateSeedDetector, const ActsTrk::SeedContainer &seeds, const InDetDD::SiDetectorElementCollection &detElements, detail::RecoTrackContainer &actsTracksContainer, std::size_t seedCollectionIndex, const char *seedType, EventStats &event_stat, std::vector< int > *destiny, const Acts::PerigeeSurface &pSurface, std::optional< std::vector< unsigned int > > &trackCategories) const
invoke track finding procedure
TrackFindingAlg(const std::string &name, ISvcLocator *pSvcLocator)
void printSeed(unsigned int iseed, const DetectorContextHolder &detContext, const ActsTrk::SeedContainer &seeds, const Acts::BoundTrackParameters &seedParameters, const detail::MeasurementIndex &measurementIndex, std::size_t &nPrinted, const char *seedType, bool isKF=false) const
Gaudi::Property< std::vector< bool > > m_refitSeeds
void storeSeedInfo(const detail::RecoTrackContainer &tracksContainer, const detail::RecoTrackContainerProxy &track, detail::DuplicateSeedDetector &duplicateSeedDetector, const detail::MeasurementIndex &measurementIndex) const
std::optional< Acts::GreedyAmbiguityResolution > m_ambi
StatusCode propagateDetectorElementStatusToMeasurements(const ActsTrk::ActsVolumeIdToDetectorElementCollectionMap &volume_id_to_det_el_coll, const std::vector< const InDet::SiDetectorElementStatus * > &det_el_status_arr, detail::TrackFindingMeasurements &measurements) const
Gaudi::Property< unsigned int > m_nMeasurementsMin
ToolHandle< ActsTrk::ITrackParamsEstimationTool > m_paramEstimationTool
Gaudi::Property< unsigned int > m_seedMeasOffset
virtual StatusCode initialize() override
Gaudi::Property< std::vector< double > > m_useTopSpRZboundary
Acts::Result< void > extrapolateTrackToReferenceSurface(const DetectorContextHolder &detContext, detail::RecoTrackContainerProxy &track, const Acts::Surface &referenceSurface, const detail::Extrapolator &propagator, Acts::TrackExtrapolationStrategy strategy, ExpectedLayerPattern &expectedLayerPattern) const
Gaudi::Property< bool > m_autoReverseSearch
StatusCode storeTrackCollectionToStoreGate(const EventContext &ctx, Acts::VectorTrackContainer &&originalTrackBackend, Acts::VectorMultiTrajectory &&originalTrackStateBackend) const
Gaudi::Property< unsigned int > m_maximumIterations
std::array< unsigned int, 4 > ExpectedLayerPattern
Gaudi::Property< bool > m_forceTrackOnSeed
Gaudi::Property< bool > m_skipDuplicateSeeds
SG::ReadCondHandleKey< InDet::BeamSpotData > m_beamSpotKey
virtual StatusCode execute(const EventContext &ctx) const override
virtual StatusCode finalize() override
StatusCode addTrack(const DetectorContextHolder &detContext, detail::RecoTrackContainerProxy &track, const Acts::Surface &pSurface, const Acts::TrackExtrapolationStrategy &extrapolationStrategy, detail::SharedHitCounter &sharedHits, detail::RecoTrackContainer &actsTracksContainer, const detail::MeasurementIndex &measurementIndex, const detail::RecoTrackContainer &tracksContainerTemp, detail::DuplicateSeedDetector &duplicateSeedDetector, std::vector< int > *destiny, EventStats &event_stat, std::size_t &ntracks, std::size_t iseed, std::size_t category_i, const char *seedType, std::optional< std::vector< unsigned int > > &trackCategories) const
Gaudi::Property< std::size_t > m_ambiStrategy
bool shouldReverseSearch(const ActsTrk::Seed &seed) const
SG::ReadHandleKeyArray< InDet::SiDetectorElementStatus > m_detElStatus
Gaudi::Property< std::vector< float > > m_statEtaBins
Gaudi::Property< bool > m_doTwoWay
Gaudi::Property< bool > m_dumpAllStatEtaBins
static xAOD::UncalibMeasType measurementType(const detail::RecoTrackContainer::TrackStateProxy &trackState)
ToolHandle< ActsTrk::TrackStatePrinterTool > m_trackStatePrinter
SG::WriteHandleKey< ActsTrk::TrackContainer > m_trackContainerKey
detail::RecoTrackContainer::TrackProxy TrkProxy
void copyStats(const EventStats &event_stat) const
std::size_t getStatCategory(std::size_t seed_collection, float eta) const
ToolHandle< GenericMonitoringTool > m_monTool
static void addCounts(detail::RecoTrackContainer &tracksContainer)
std::vector< typename detail::RecoTrackContainer::TrackProxy > doTwoWayTrackFinding(const detail::RecoTrackStateContainerProxy &firstMeasurement, const TrkProxy &trackProxy, detail::RecoTrackContainer &tracksContainerTemp, const TrackFinderOptions &options) const
Perform two-way track finding.
TrackFindingBaseAlg(const std::string &name, ISvcLocator *pSvcLocator)
PublicToolHandle< ActsTrk::ITrackingGeometryTool > m_trackingGeometryTool
ToolHandle< ActsTrk::IActsToTrkConverterTool > m_ATLASConverterTool
ToolHandle< ActsTrk::IExtrapolationTool > m_extrapolationTool
std::size_t computeStatSum(std::size_t seed_collection, EStat counter_i, const EventStats &stat) const
virtual StatusCode initialize() override
StatusCode getContainersFromKeys(const EventContext &ctx, HandleArrayKeyType &handleKeyArray, std::vector< const ContainerType * > &outputContainers, std::size_t &sum) const
Take the array of handle keys and for each key retrieve containers, then append them to the output ve...
void checkCounts(const detail::RecoTrackContainer::TrackProxy &track) const
const Acts::Logger & logger() const
Private access to the logger.
BranchStopperResult stopBranch(const detail::RecoTrackContainer::TrackProxy &track, const detail::RecoTrackContainer::TrackStateProxy &trackState, const Acts::TrackSelector::EtaBinnedConfig &trackSelectorCfg, const Acts::GeometryContext &tgContext, const detail::MeasurementIndex &measurementIndex, const std::size_t typeIndex, EventStats::value_type &event_stat_category_i) const
Branch stopper.
static void initCounts(const detail::RecoTrackContainer::TrackProxy &track)
Gaudi::Property< bool > m_checkCounts
TrackFindingDefaultOptions getDefaultOptions(const DetectorContextHolder &detContext, const detail::TrackFindingMeasurements &measurements, const Acts::PerigeeSurface *pSurface) const
Get CKF options for first and second pass + pointer to MeasurementSelector.
std::unique_ptr< Acts::BoundTrackParameters > doRefit(const MeasurementSource &measurement, const Acts::BoundTrackParameters &initialParameters, const DetectorContextHolder &detContext, const bool paramsAtOutermostSurface) const
Perform Kalman Filter fit and update given initialParameters.
virtual StatusCode finalize() override
std::vector< std::array< unsigned int, kNStat > > EventStats
static void updateCounts(const detail::RecoTrackContainer::TrackProxy &track, Acts::ConstTrackStateTypeMap typeFlags, xAOD::UncalibMeasType detType)
Gaudi::Property< bool > m_addCounts
Acts::CombinatorialKalmanFilterBranchStopperResult BranchStopperResult
bool selectCountsFinal(const detail::RecoTrackContainer::TrackProxy &track) const
Gaudi::Property< std::vector< std::string > > m_seedLabels
void addMeasurement(const ActsTrk::ATLASUncalibSourceLink &sl, const MeasurementIndex &measurementIndex)
bool isDuplicate(std::size_t typeIndex, index_t iseed)
void addSeeds(std::size_t typeIndex, const ActsTrk::SeedContainer &seeds, const MeasurementIndex &measurementIndex)
void addMeasurements(const xAOD::UncalibratedMeasurementContainer &clusterContainer)
auto computeSharedHits(typename track_container_t::TrackProxy &track, track_container_t &tracks, const MeasurementIndex &measurementIndex, bool removeSharedHits=false) -> ReturnSharedAndBad
const std::vector< std::size_t > & measurementOffsets() const
void addMeasurements(std::size_t typeIndex, const xAOD::UncalibratedMeasurementContainer &clusterContainer, const DetectorElementToActsGeometryIdMap &detectorElementToGeoid, const MeasurementIndex *measurementIndex=nullptr)
MeasurementRangeListFlat setMeasurementRangesForced(const ActsTrk::Seed &seed, const MeasurementIndex &measurementIndex) const
MeasurementRange markSurfaceInsensitive(const Acts::GeometryIdentifier &identifier)
Class to hold the SiDetectorElement objects to be put in the detector store.
const SiDetectorElement * getDetectorElement(const IdentifierHash &hash) const
Class to hold geometrical description of a silicon detector element.
Trk::Surface & surface()
Element Surface.
const Amg::Vector3D & beamPos() const noexcept
bool isGood(IdentifierHash hash) const
Group of local monitoring quantities and retain correlation when filling histograms
Declare a monitored scalar variable.
A monitored timer.
const_pointer_type cptr()
Property holding a SG store/key/clid from which a ReadHandle is made.
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.
Abstract Base Class for tracking surfaces.
float z() const
Eigen::Map< const Eigen::Matrix< float, 3, 1 > > ConstVectorMap
float radius() const
DetectorIdentType identifier() const
Returns the full Identifier of the measurement.
int ts
Definition globals.cxx:24
int r
Definition globals.cxx:22
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:130
RecoTrackStateContainer::TrackStateProxy RecoTrackStateContainerProxy
Acts::TrackContainer< Acts::VectorTrackContainer, Acts::VectorMultiTrajectory > RecoTrackContainer
void addToExpectedLayerPattern(std::array< unsigned int, 4 > &pattern, const ActsDetectorElement &detElement)
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
const xAOD::UncalibratedMeasurement & getUncalibratedMeasurement(const ATLASUncalibSourceLink &source_link)
Acts::CalibrationContext getCalibrationContext(const EventContext &ctx)
The Acts::Calibration context is piped through the Acts fitters to (re)calibrate the Acts::SourceLink...
const xAOD::UncalibratedMeasurement * ATLASUncalibSourceLink
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
UncalibratedMeasurement_v1 UncalibratedMeasurement
Define the version of the uncalibrated measurement class.
std::size_t size() const noexcept
static void add(track_container_t &trackContainer)
static void set(track_proxy_t &track, std::array< unsigned int, 4 > values)