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