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