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