ATLAS Offline Software
Loading...
Searching...
No Matches
TrackFindingBaseAlg.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// ActsTrk
14#include "Acts/Surfaces/PerigeeSurface.hpp"
15#include "Acts/TrackFitting/GsfMixtureReduction.hpp"
16
18
19#include <boost/math/distributions/chi_squared.hpp>
20#include <cmath>
21#include <numbers>
22
23namespace ActsTrk {
25
28
30
33
34 TrackFindingBaseAlg::TrackFindingBaseAlg(const std::string &name, ISvcLocator *pSvcLocator) : AthReentrantAlgorithm(name, pSvcLocator) {}
35
37
39 ATH_MSG_DEBUG("Properties Summary:");
51 ATH_MSG_DEBUG(" " << m_phiMin);
52 ATH_MSG_DEBUG(" " << m_phiMax);
53 ATH_MSG_DEBUG(" " << m_etaMin);
54 ATH_MSG_DEBUG(" " << m_etaMax);
57 ATH_MSG_DEBUG(" " << m_ptMin);
58 ATH_MSG_DEBUG(" " << m_ptMax);
59 ATH_MSG_DEBUG(" " << m_d0Min);
60 ATH_MSG_DEBUG(" " << m_d0Max);
61 ATH_MSG_DEBUG(" " << m_z0Min);
62 ATH_MSG_DEBUG(" " << m_z0Max);
87
88 m_logger = makeActsAthenaLogger(this, "Acts");
89 m_bremLogger = makeActsAthenaLogger(this, "BremActs");
90
91 // Read and Write handles
92 ATH_CHECK(m_trackContainerKey.initialize());
94
95 ATH_CHECK(m_monTool.retrieve(EnableTool{not m_monTool.empty()}));
97 ATH_CHECK(m_ctxProvider.initialize());
98 ATH_CHECK(m_trackStatePrinter.retrieve(EnableTool{not m_trackStatePrinter.empty()}));
99 ATH_CHECK(m_pixelCalibTool.retrieve(EnableTool{not m_pixelCalibTool.empty()}));
100 ATH_CHECK(m_stripCalibTool.retrieve(EnableTool{not m_stripCalibTool.empty()}));
101 ATH_CHECK(m_hgtdCalibTool.retrieve(EnableTool{not m_hgtdCalibTool.empty()}));
102
103 // auto magneticField = std::make_shared<ATLASMagneticFieldWrapper>();
104 // duplicated so that multi stepper owns different instance of magnetic field than single stepper
105 // auto magField = std::make_shared<ATLASMagneticFieldWrapper>();
106 auto trackingGeometry = m_trackingGeometrySvc->trackingGeometry();
107
108 if(trackingGeometry->geometryVersion() == Acts::TrackingGeometry::GeometryVersion::Gen3) {
109 m_endOfWorldVolumeIds.value().clear();
110 switch (m_envelopeConstraint.value()) {
111 using enum ActsTrk::SystemEnvelope;
112 case Acts::toUnderlying(ITkExit):
113 case Acts::toUnderlying(CaloExit): {
114 const Acts::TrackingVolume* volume = m_trackingGeometrySvc
115 ->getEnvelope(static_cast<SystemEnvelope>(m_envelopeConstraint.value()));
116 ATH_CHECK(volume != nullptr);
117 m_endOfWorldVolumeIds.value().push_back(volume->motherVolume()->geometryId().volume());
118 break;
119 } default: {
120 ATH_MSG_ERROR("Invalid configuration "<<m_envelopeConstraint);
121 return StatusCode::FAILURE;
122 }
123 }
124 }
125
126 // m_etaBins (from flags.Tracking.ActiveConfig.etaBins) includes a dummy first and last bin, which we ignore
127 std::vector<double> absEtaEdges;
128 if (m_etaBins.size() <= 2)
129 {
130 absEtaEdges.reserve(2ul);
131 absEtaEdges.push_back(0.0);
132 absEtaEdges.push_back(std::numeric_limits<double>::infinity());
133 }
134 else
135 {
136 absEtaEdges.reserve(m_etaBins.size());
137 absEtaEdges.push_back(m_absEtaMin);
138 absEtaEdges.insert(absEtaEdges.end(), m_etaBins.begin() + 1, m_etaBins.end() - 1);
139 absEtaEdges.push_back(m_absEtaMax);
140 }
141
142 auto setCut = [](auto &cfgVal, const auto &cuts, size_t ind) -> void
143 {
144 if (cuts.empty())
145 return;
146 cfgVal = (ind < cuts.size()) ? cuts[ind] : cuts[cuts.size() - 1];
147 };
148
149 Acts::TrackSelector::EtaBinnedConfig trackSelectorCfg{std::move(absEtaEdges)};
150 if (m_etaBins.size() <= 2)
151 {
152 assert(trackSelectorCfg.cutSets.size() == 1);
153 trackSelectorCfg.cutSets[0].absEtaMin = m_absEtaMin;
154 trackSelectorCfg.cutSets[0].absEtaMax = m_absEtaMax;
155 }
156 size_t cutIndex = 0;
157 for (auto &cfg : trackSelectorCfg.cutSets)
158 {
159 setCut(cfg.phiMin, m_phiMin, cutIndex);
160 setCut(cfg.phiMax, m_phiMax, cutIndex);
161 setCut(cfg.etaMin, m_etaMin, cutIndex);
162 setCut(cfg.etaMax, m_etaMax, cutIndex);
163 setCut(cfg.ptMin, m_ptMin, cutIndex);
164 setCut(cfg.ptMax, m_ptMax, cutIndex);
165 setCut(cfg.loc0Min, m_d0Min, cutIndex);
166 setCut(cfg.loc0Max, m_d0Max, cutIndex);
167 setCut(cfg.loc1Min, m_z0Min, cutIndex);
168 setCut(cfg.loc1Max, m_z0Max, cutIndex);
169 setCut(cfg.minMeasurements, m_minMeasurements, cutIndex);
170 setCut(cfg.maxHoles, m_maxHoles, cutIndex);
171 setCut(cfg.maxOutliers, m_maxOutliers, cutIndex);
172 setCut(cfg.maxHolesAndOutliers, m_maxHolesAndOutliers, cutIndex);
173 setCut(cfg.maxSharedHits, m_maxSharedHits, cutIndex);
174 setCut(cfg.maxChi2, m_maxChi2, cutIndex);
175 ++cutIndex;
176 }
177
178 ATH_MSG_DEBUG(trackSelectorCfg);
179
180 // initializer measurement selector and connect it to the delegates of the track finder optins
181 ATH_CHECK(initializeMeasurementSelector());
182
183 m_trackFinder = getTrackFindingFunction(trackingGeometry, trackSelectorCfg);
185
186 m_bremTrackFinder = getBremTrackFindingFunction(trackingGeometry, trackSelectorCfg);
188
189 initStatTables();
190
191 return StatusCode::SUCCESS;
192 }
193
194 StatusCode TrackFindingBaseAlg::execute(const EventContext &) const {
195 ATH_MSG_FATAL("execute() method from the base class was called! Implement proper execute() method in the derived class!");
196
197 return StatusCode::FAILURE;
198 }
199
202
203 return StatusCode::SUCCESS;
204 }
205
206 std::unique_ptr<ActsTrk::IMeasurementSelector> TrackFindingBaseAlg::setMeasurementSelector(
207 const EventContext &ctx,
208 const detail::TrackFindingMeasurements &measurements,
209 TrackFinderOptions &options) const {
210
211 std::unique_ptr<ActsTrk::IMeasurementSelector> measurementSelector = ActsTrk::detail::getMeasurementSelector(
212 ctx,
213 m_pixelCalibTool.isEnabled() ? &(*m_pixelCalibTool) : nullptr,
214 m_stripCalibTool.isEnabled() ? &(*m_stripCalibTool) : nullptr,
215 m_hgtdCalibTool.isEnabled() ? &(*m_hgtdCalibTool) : nullptr,
216 measurements.measurementRanges(),
218 m_measurementSelectorConfig.m_chi2CutOffOutlier,
220 m_edgeHoleBorderWidth.value());
221
222 measurementSelector->connect(&options.extensions.createTrackStates);
223
224 return measurementSelector;
225 }
226
227 std::unique_ptr<TrackFindingBaseAlg::CKF_pimpl> TrackFindingBaseAlg::getTrackFindingFunction(std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry,
228 Acts::TrackSelector::EtaBinnedConfig trackSelectorCfg)
229 {
230 auto magneticField = std::make_unique<ATLASMagneticFieldWrapper>();
231
232 detail::Stepper stepper(std::move(magneticField));
233 detail::Navigator::Config config(trackingGeometry);
234 config.resolvePassive = false;
235 config.resolveMaterial = true;
236 config.resolveSensitive = true;
237 detail::Navigator navigator(config, logger().cloneWithSuffix("Navigator"));
238 detail::Propagator propagator(std::move(stepper), std::move(navigator), logger().cloneWithSuffix("Prop"));
239
240 detail::Extrapolator extrapolator = propagator;
241
242 detail::CKF_config ckfConfig{
243 {
244 std::move(extrapolator),
245 Acts::TrackSelector{trackSelectorCfg}
246 },
247 detail::CKF{std::move(propagator), logger().cloneWithSuffix("CKF")},
248 {}
249 };
250
251 return std::make_unique<CKF_pimpl>(std::move(ckfConfig));
252 };
253
254 std::unique_ptr<TrackFindingBaseAlg::bremCKF_pimpl> TrackFindingBaseAlg::getBremTrackFindingFunction(std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry,
255 Acts::TrackSelector::EtaBinnedConfig trackSelectorCfg)
256 {
257 auto magneticField = std::make_unique<ATLASMagneticFieldWrapper>();
258 auto bremMagneticField = std::make_unique<ATLASMagneticFieldWrapper>();
259
260 detail::BremStepper bremStepper(std::move(magneticField));
261 detail::Navigator::Config bremConfig{trackingGeometry};
262 bremConfig.resolvePassive = false;
263 bremConfig.resolveMaterial = true;
264 bremConfig.resolveSensitive = true;
265 detail::Navigator bremNavigator(bremConfig, bremLogger().cloneWithSuffix("BremNavigator"));
266 detail::BremPropagator bremPropagator(std::move(bremStepper), std::move(bremNavigator), bremLogger().cloneWithSuffix("BremProp"));
267
268 detail::Stepper stepper(std::move(bremMagneticField));
269 detail::Navigator::Config config(trackingGeometry);
270 config.resolvePassive = false;
271 config.resolveMaterial = true;
272 config.resolveSensitive = true;
273 detail::Navigator navigator(config, logger().cloneWithSuffix("Navigator"));
274 detail::Propagator propagator(std::move(stepper), std::move(navigator), logger().cloneWithSuffix("Prop"));
275
276 detail::Extrapolator extrapolator = propagator;
277
278 detail::bremCKF_config bremCkfConfig{
279 {
280 std::move(extrapolator),
281 Acts::TrackSelector{trackSelectorCfg}
282 },
283 detail::BremCKF{std::move(bremPropagator), bremLogger().cloneWithSuffix("BremCKF")},
284 {}
285 };
286
287 return std::make_unique<bremCKF_pimpl>(std::move(bremCkfConfig));
288 };
289
290
292 const EventContext &ctx,
293 const DetectorContextHolder &detContext,
294 const detail::TrackFindingMeasurements &measurements,
295 const Acts::PerigeeSurface* pSurface) const {
296 Acts::PropagatorPlainOptions plainOptions{detContext.geometry, detContext.magField};
297 plainOptions.maxSteps = m_maxPropagationStep;
298 plainOptions.direction = Acts::Direction::Forward();
299 plainOptions.endOfWorldVolumeIds = m_endOfWorldVolumeIds;
300
301 // Set the CombinatorialKalmanFilter options
302 TrackFinderOptions options(detContext.geometry, detContext.magField, detContext.calib,
303 trackFinder().ckfExtensions, plainOptions);
304 options.recordMaterialStates = m_recordMaterialStates;
305
306 std::unique_ptr<ActsTrk::IMeasurementSelector> measurementSelector = setMeasurementSelector(ctx, measurements, options);
307
308 Acts::PropagatorPlainOptions plainSecondOptions{detContext.geometry, detContext.magField};
309 plainSecondOptions.maxSteps = m_maxPropagationStep;
310 plainSecondOptions.direction = plainOptions.direction.invert();
311 plainSecondOptions.endOfWorldVolumeIds = m_endOfWorldVolumeIds;
312
313 TrackFinderOptions secondOptions(detContext.geometry, detContext.magField, detContext.calib,
314 options.extensions, plainSecondOptions);
315 secondOptions.targetSurface = pSurface;
316 secondOptions.skipPrePropagationUpdate = true;
317 secondOptions.recordMaterialStates = m_recordMaterialStates;
318
319 return {std::move(options), std::move(secondOptions), std::move(measurementSelector)};
320 };
321
323 const EventContext &ctx,
324 const DetectorContextHolder &detContext,
325 const detail::TrackFindingMeasurements &measurements,
326 const Acts::PerigeeSurface* pSurface) const {
327 Acts::PropagatorPlainOptions plainOptions{detContext.geometry, detContext.magField};
328 plainOptions.maxSteps = m_maxPropagationStep;
329 plainOptions.direction = Acts::Direction::Forward();
330 plainOptions.endOfWorldVolumeIds = m_endOfWorldVolumeIds;
331
332 // Set the CombinatorialKalmanFilter options
333 BremTrackFinderOptions options(detContext.geometry, detContext.magField, detContext.calib,
334 bremTrackFinder().ckfExtensions, plainOptions, pSurface);
335 options.recordMaterialStates = m_recordMaterialStates;
336
337 options.maxComponents = m_bremMaxComponents;
338 options.weightCutoff = m_bremWeightCutoff;
339
340 options.extensions.mixtureReducer.connect<&Acts::reduceMixtureWithKLDistance>();
341 options.betheHeitlerApprox = std::make_shared<Acts::PolynomialBetheHeitlerApprox>(Acts::makeDefaultBetheHeitlerApprox());
342
343 std::unique_ptr<ActsTrk::IMeasurementSelector> measurementSelector = setMeasurementSelector(ctx, measurements, options);
344
345 Acts::PropagatorPlainOptions plainSecondOptions{detContext.geometry, detContext.magField};
346 plainSecondOptions.maxSteps = m_maxPropagationStep;
347 plainSecondOptions.direction = plainOptions.direction.invert();
348 plainSecondOptions.endOfWorldVolumeIds = m_endOfWorldVolumeIds;
349
350 BremTrackFinderOptions secondOptions(detContext.geometry, detContext.magField, detContext.calib,
351 options.extensions, plainSecondOptions, pSurface);
352 secondOptions.targetSurface = pSurface;
353 secondOptions.skipPrePropagationUpdate = true;
354 secondOptions.recordMaterialStates = m_recordMaterialStates;
355
356 secondOptions.maxComponents = m_bremMaxComponents;
357 secondOptions.weightCutoff = m_bremWeightCutoff;
358
359 secondOptions.betheHeitlerApprox = std::make_shared<Acts::PolynomialBetheHeitlerApprox>(Acts::makeDefaultBetheHeitlerApprox());
360
361 if (m_bremMergeMethod == "MaxWeight"){
362 options.mergeMethod = Acts::ComponentMergeMethod::eMaxWeight;
363 secondOptions.mergeMethod = Acts::ComponentMergeMethod::eMaxWeight;
364 }
365 else if (m_bremMergeMethod == "Mean"){
366 options.mergeMethod = Acts::ComponentMergeMethod::eMean;
367 secondOptions.mergeMethod = Acts::ComponentMergeMethod::eMean;
368 }
369 else {
370 throw std::runtime_error("Unknown option for GSF component merge method: " + m_bremMergeMethod.value());
371 }
372
373 return {std::move(options), std::move(secondOptions), std::move(measurementSelector)};
374 };
375
376 const Acts::TrackSelector::Config& TrackFindingBaseAlg::getCuts (double eta) const {
377 const auto &trackSelectorCfg = trackFinder().trackSelector.config();
378 // return the last bin for |eta|>=4 or nan
379 return (!(std::abs(eta) < trackSelectorCfg.absEtaEdges.back())) ? trackSelectorCfg.cutSets.back()
380 : (std::abs(eta) < trackSelectorCfg.absEtaEdges.front()) ? trackSelectorCfg.cutSets.front()
381 : trackSelectorCfg.getCuts(eta);
382 };
383
384 Acts::Result<std::vector<detail::RecoTrackContainer::TrackProxy> > TrackFindingBaseAlg::findTracksCKF(const Acts::BoundTrackParameters &seedParameters,
385 const TrackFinderOptions& options,
386 detail::RecoTrackContainer& tracksContainerTemp,
387 detail::RecoTrackContainer::TrackProxy &rootBranch) const
388 {
389 return trackFinder().ckf.findTracks(seedParameters, options, tracksContainerTemp, rootBranch);
390 }
391
392 Acts::Result<std::vector<detail::RecoTrackContainer::TrackProxy> > TrackFindingBaseAlg::findTracksCKF(const Acts::BoundTrackParameters &seedParameters,
393 const BremTrackFinderOptions& options,
394 detail::RecoTrackContainer& tracksContainerTemp,
395 detail::RecoTrackContainer::TrackProxy &rootBranch) const
396 {
397 const Acts::BoundTrackParameters elTrackParameters = seedParameters.withParticleHypothesis(Acts::ParticleHypothesis::electron());
398 return bremTrackFinder().ckf.findTracks(elTrackParameters, options, tracksContainerTemp, rootBranch);
399 }
400
401 void TrackFindingBaseAlg::inflateCovarianceTwoWay(Acts::BoundTrackParameters &secondInitialParameters) const {
402 ATH_MSG_DEBUG("Inflating covariance matrix for second track finding with factor = " << m_twoWayinflateCovarianceFactor.value());
403 ATH_MSG_VERBOSE("Original parameters before inflation: \n" << secondInitialParameters);
404
405 auto inflatedCovariance = secondInitialParameters.covariance().value();
406 inflatedCovariance *= m_twoWayinflateCovarianceFactor;
407
408 const auto& origSurface = secondInitialParameters.referenceSurface();
409 auto surfacePtr = const_cast<Acts::Surface&>(origSurface).shared_from_this();
410
411 Acts::BoundTrackParameters newParams(
412 std::static_pointer_cast<const Acts::Surface>(std::move(surfacePtr)),
413 secondInitialParameters.parameters(),
414 std::make_optional(inflatedCovariance),
415 secondInitialParameters.particleHypothesis());
416 secondInitialParameters = std::move(newParams);
417
418 ATH_MSG_VERBOSE("Inflated covariance matrix : \n" << secondInitialParameters.covariance().value());
419 }
420 xAOD::UncalibMeasType TrackFindingBaseAlg::measurementType (const detail::RecoTrackContainer::TrackStateProxy &trackState) {
421 if (trackState.hasReferenceSurface()) {
422 if (const auto *actsDetElem = dynamic_cast<const ISurfacePlacement*>(trackState.referenceSurface().surfacePlacement())) {
423 switch (actsDetElem->detectorType()) {
430 default:
431 break;
432 }
433 }
434 }
436 }
437
439 const detail::RecoTrackContainer::TrackProxy &track,
440 const detail::RecoTrackContainer::TrackStateProxy &trackState,
441 const Acts::TrackSelector::EtaBinnedConfig &trackSelectorCfg,
442 const Acts::GeometryContext &tgContext,
443 const detail::MeasurementIndex &measurementIndex,
444 const std::size_t typeIndex,
445 EventStats::value_type &event_stat_category_i) const {
446 if (m_addCounts) {
447 updateCounts(track, trackState.typeFlags(),
448 measurementType(trackState));
449 if (m_checkCounts) {
450 checkCounts(track);
451 }
452 }
453
454 if (m_trackStatePrinter.isSet()) {
455 m_trackStatePrinter->printTrackState(tgContext, trackState,
456 measurementIndex, true);
457 }
458
459 if (!m_doBranchStopper) {
460 return BranchStopperResult::Continue;
461 }
462
463 const auto &parameters = trackState.hasFiltered() ? trackState.filtered()
464 : trackState.predicted();
465 double eta = -std::log(std::tan(0.5 * parameters[Acts::eBoundTheta]));
466 const auto &cutSet = getCuts(eta);
467
468 if (typeIndex < m_ptMinMeasurements.size() &&
469 !(track.nMeasurements() < m_ptMinMeasurements[typeIndex])) {
470 double pT = std::sin(parameters[Acts::eBoundTheta]) /
471 parameters[Acts::eBoundQOverP];
472 if (std::abs(pT) < cutSet.ptMin * m_branchStopperPtMinFactor) {
473 ++event_stat_category_i[kNStoppedTracksMinPt];
474 ATH_MSG_DEBUG("CkfBranchStopper: drop branch with q*pT="
475 << pT << " after " << track.nMeasurements()
476 << " measurements");
477 return BranchStopperResult::StopAndDrop;
478 }
479 }
480
481 if (typeIndex < m_absEtaMaxMeasurements.size() &&
482 !(track.nMeasurements() < m_absEtaMaxMeasurements[typeIndex]) &&
483 !(std::abs(eta) < trackSelectorCfg.absEtaEdges.back() +
485 ++event_stat_category_i[kNStoppedTracksMaxEta];
486 ATH_MSG_DEBUG("CkfBranchStopper: drop branch with eta="
487 << eta << " after " << track.nMeasurements()
488 << " measurements");
489 return BranchStopperResult::StopAndDrop;
490 }
491
492
493 // In the pixel endcap regions relax the requirement for minMeasurements before cutting the branch off
494 auto minMeasurementsBranchStop = std::abs(eta) > m_branchStopperAbsEtaMeasCut ? cutSet.minMeasurements - m_branchStopperMeasCutReduce : cutSet.minMeasurements;
495 bool enoughMeasurements = (track.nMeasurements() >= minMeasurementsBranchStop);
496 bool tooManyHoles = (track.nHoles() > cutSet.maxHoles);
497 bool tooManyOutliers = (track.nOutliers() > cutSet.maxOutliers);
498 bool tooManyHolesAndOutliers = (track.nHoles() + track.nOutliers() > cutSet.maxHolesAndOutliers);
499
500 if (m_addCounts) {
501 auto [enoughMeasurementsPS, tooManyHolesPS, tooManyOutliersPS] =
502 selectCounts(track, eta);
503 enoughMeasurements = enoughMeasurements && enoughMeasurementsPS;
504 tooManyHoles = tooManyHoles || tooManyHolesPS;
505 tooManyOutliers = tooManyOutliers || tooManyOutliersPS;
506 }
507
508 if (!(tooManyHoles || tooManyOutliers || tooManyHolesAndOutliers)) {
509 return BranchStopperResult::Continue;
510 }
511
512 if (!enoughMeasurements) {
513 ++event_stat_category_i[kNStoppedTracksMaxHoles];
514 }
515
516 if (m_addCounts) {
517 ATH_MSG_DEBUG("CkfBranchStopper: stop and "
518 << (enoughMeasurements ? "keep" : "drop")
519 << " branch with nHoles=" << track.nHoles() << " ("
520 << s_branchState.nPixelHoles(track) << " pixel+"
521 << s_branchState.nStripHoles(track) << " strip+"
522 << s_branchState.nHgtdHoles(track)
523 << " hgtd), nOutliers=" << track.nOutliers() << " ("
524 << s_branchState.nPixelOutliers(track) << "+"
525 << s_branchState.nStripOutliers(track) << "+"
526 << s_branchState.nHgtdOutliers(track)
527 << "), nMeasurements=" << track.nMeasurements() << " ("
528 << s_branchState.nPixelHits(track) << "+"
529 << s_branchState.nStripHits(track) << "+"
530 << s_branchState.nHgtdHits(track) << ")");
531 } else {
532 ATH_MSG_DEBUG("CkfBranchStopper: stop and "
533 << (enoughMeasurements ? "keep" : "drop")
534 << " branch with nHoles=" << track.nHoles()
535 << ", nOutliers=" << track.nOutliers()
536 << ", nMeasurements=" << track.nMeasurements());
537 }
538
539 return enoughMeasurements ? BranchStopperResult::StopAndKeep
540 : BranchStopperResult::StopAndDrop;
541 }
542
543
545 {
546 if (addCounts) {
547 tracksContainer.addColumn<unsigned int>("nPixelHits");
548 tracksContainer.addColumn<unsigned int>("nStripHits");
549 tracksContainer.addColumn<unsigned int>("nHgtdHits");
550 tracksContainer.addColumn<unsigned int>("nPixelHoles");
551 tracksContainer.addColumn<unsigned int>("nStripHoles");
552 tracksContainer.addColumn<unsigned int>("nHgtdHoles");
553 tracksContainer.addColumn<unsigned int>("nPixelOutliers");
554 tracksContainer.addColumn<unsigned int>("nStripOutliers");
555 tracksContainer.addColumn<unsigned int>("nHgtdOutliers");
556 }
558 }
559
560 void TrackFindingBaseAlg::initCounts(const detail::RecoTrackContainer::TrackProxy &track)
561 {
562 s_branchState.nPixelHits(track) = 0;
563 s_branchState.nStripHits(track) = 0;
564 s_branchState.nHgtdHits(track) = 0;
565 s_branchState.nPixelHoles(track) = 0;
566 s_branchState.nStripHoles(track) = 0;
567 s_branchState.nHgtdHoles(track) = 0;
568 s_branchState.nPixelOutliers(track) = 0;
569 s_branchState.nStripOutliers(track) = 0;
570 s_branchState.nHgtdOutliers(track) = 0;
571 }
572
574 const detail::RecoTrackContainer::TrackProxy &track,
575 Acts::ConstTrackStateTypeMap typeFlags, xAOD::UncalibMeasType detType) {
577 if (typeFlags.isHole()) {
578 s_branchState.nPixelHoles(track)++;
579 } else if (typeFlags.isOutlier()) {
580 s_branchState.nPixelOutliers(track)++;
581 } else if (typeFlags.isMeasurement()) {
582 s_branchState.nPixelHits(track)++;
583 }
584 } else if (detType == xAOD::UncalibMeasType::StripClusterType) {
585 if (typeFlags.isHole()) {
586 s_branchState.nStripHoles(track)++;
587 } else if (typeFlags.isOutlier()) {
588 s_branchState.nStripOutliers(track)++;
589 } else if (typeFlags.isMeasurement()) {
590 s_branchState.nStripHits(track)++;
591 }
592 } else if (detType == xAOD::UncalibMeasType::HGTDClusterType) {
593 if (typeFlags.isHole()) {
594 s_branchState.nHgtdHoles(track)++;
595 } else if (typeFlags.isOutlier()) {
596 s_branchState.nHgtdOutliers(track)++;
597 } else if (typeFlags.isMeasurement()) {
598 s_branchState.nHgtdHits(track)++;
599 }
600 }
601 }
602
603 void TrackFindingBaseAlg::checkCounts(const detail::RecoTrackContainer::TrackProxy &track) const {
604 // This check will fail if there are other types (HGTD, MS?) of hits, holes, or outliers.
605 // The check can be removed when it is no longer appropriate.
606 if (track.nMeasurements() != s_branchState.nPixelHits(track) + s_branchState.nStripHits(track) + s_branchState.nHgtdHits(track))
607 ATH_MSG_WARNING("mismatched hit count: total (" << track.nMeasurements()
608 << ") != pixel (" << s_branchState.nPixelHits(track)
609 << ") + strip (" << s_branchState.nStripHits(track)
610 << ") + hgtd (" << s_branchState.nHgtdHits(track)
611 << ")");
612 if (track.nHoles() != s_branchState.nPixelHoles(track) + s_branchState.nStripHoles(track) + s_branchState.nHgtdHoles(track))
613 ATH_MSG_WARNING("mismatched hole count: total (" << track.nHoles()
614 << ") < pixel (" << s_branchState.nPixelHoles(track)
615 << ") + strip (" << s_branchState.nStripHoles(track)
616 << ") + hgtd (" << s_branchState.nHgtdHoles(track)
617 << ")");
618 if (track.nOutliers() != s_branchState.nPixelOutliers(track) + s_branchState.nStripOutliers(track) + s_branchState.nHgtdOutliers(track))
619 ATH_MSG_WARNING("mismatched outlier count: total (" << track.nOutliers()
620 << ") != pixel (" << s_branchState.nPixelOutliers(track)
621 << ") + strip (" << s_branchState.nStripOutliers(track)
622 << ") + hgtd (" << s_branchState.nHgtdOutliers(track)
623 << ")");
624 };
625
626 std::array<bool, 3> TrackFindingBaseAlg::selectCounts(const detail::RecoTrackContainer::TrackProxy &track, double eta) const {
627 bool enoughMeasurements = true, tooManyHoles = false, tooManyOutliers = false;
628 const auto &trackSelectorCfg = (ActsTrk::TrackContainerUtils::fitterType(track) == xAOD::GaussianSumFilter) ? bremTrackFinder().trackSelector.config() : trackFinder().trackSelector.config();
629 std::size_t etaBin = (std::abs(eta) < trackSelectorCfg.absEtaEdges.front()) ? 0
630 : (std::abs(eta) >= trackSelectorCfg.absEtaEdges.back()) ? trackSelectorCfg.absEtaEdges.size() - 1
631 : trackSelectorCfg.binIndex(eta);
632 auto cutMin = [etaBin](std::size_t val, const std::vector<std::size_t> &cutSet) {
633 return !cutSet.empty() && (val < (etaBin < cutSet.size() ? cutSet[etaBin] : cutSet.back()));
634 };
635 auto cutMax = [etaBin](std::size_t val, const std::vector<std::size_t> &cutSet) {
636 return !cutSet.empty() && (val > (etaBin < cutSet.size() ? cutSet[etaBin] : cutSet.back()));
637 };
638
639 enoughMeasurements = enoughMeasurements && !cutMin(s_branchState.nPixelHits(track), m_minPixelHits);
640 enoughMeasurements = enoughMeasurements && !cutMin(s_branchState.nStripHits(track), m_minStripHits);
641 enoughMeasurements = enoughMeasurements && !cutMin(s_branchState.nHgtdHits(track), m_minHgtdHits);
642 tooManyHoles = tooManyHoles || cutMax(s_branchState.nPixelHoles(track), m_maxPixelHoles);
643 tooManyHoles = tooManyHoles || cutMax(s_branchState.nStripHoles(track), m_maxStripHoles);
644 tooManyHoles = tooManyHoles || cutMax(s_branchState.nHgtdHoles(track), m_maxHgtdHoles);
645 tooManyOutliers = tooManyOutliers || cutMax(s_branchState.nPixelOutliers(track), m_maxPixelOutliers);
646 tooManyOutliers = tooManyOutliers || cutMax(s_branchState.nStripOutliers(track), m_maxStripOutliers);
647 tooManyOutliers = tooManyOutliers || cutMax(s_branchState.nHgtdOutliers(track), m_maxHgtdOutliers);
648
649 return {enoughMeasurements, tooManyHoles, tooManyOutliers};
650 }
651
653 // the cuts for each eta bin are (measurement, outlier) pairs for each measurement dimension
654 auto &chi2CutOffOutlier = m_measurementSelectorConfig.m_chi2CutOffOutlier;
655 const std::vector<double> &cutOff = m_chi2CutOffSigma.value();
656 const std::vector<double> &outlierCutOff = m_chi2OutlierCutOffSigma.value();
657 chi2CutOffOutlier.reserve( cutOff.size() );
658 if (!outlierCutOff.empty()) {
659 if (cutOff.size() != outlierCutOff.size()) {
660 ATH_MSG_ERROR("Outlier chi2 cut off provided but number of elements does not agree with"
661 " chi2 cut off for measurements which however is required: "
662 << cutOff.size() << " != " << outlierCutOff.size());
663 return StatusCode::FAILURE;
664 }
665 }
666 // A cut at n sigma of a 1D Gaussian (two-sided) has the p-value erfc(n/sqrt(2)). The chi2 cut for
667 // a measurement of dimension DIM is the chi2 value with this p-value for DIM degrees of freedom.
668 // For DIM=1 this is n^2.
669 auto chi2Cut = [](double cut, std::size_t dim) -> float {
670 const double pValue = std::erfc(cut / std::numbers::sqrt2);
671 return static_cast<float>(boost::math::quantile(
672 boost::math::complement(boost::math::chi_squared_distribution<double>(dim), pValue)));
673 };
674 for (std::size_t idx = 0; idx < cutOff.size(); ++idx) {
675 std::array<std::pair<float, float>, 4> cuts{};
676 for (std::size_t dim = 1; dim < cuts.size(); ++dim) {
677 cuts[dim] = std::make_pair(chi2Cut(cutOff[idx], dim),
678 idx < outlierCutOff.size()
679 ? chi2Cut(outlierCutOff[idx], dim)
680 : std::numeric_limits<float>::max());
681 }
682 cuts[0] = cuts[1];
683 chi2CutOffOutlier.push_back(cuts);
684 ATH_MSG_DEBUG("Measurement selector eta bin " << idx << ": chi2 cuts for "
685 << cutOff[idx] << " / "
686 << (idx < outlierCutOff.size() ? outlierCutOff[idx] : std::numeric_limits<double>::infinity())
687 << " sigma: 1D " << cuts[1].first << " / " << cuts[1].second
688 << ", 2D " << cuts[2].first << " / " << cuts[2].second
689 << ", 3D " << cuts[3].first << " / " << cuts[3].second);
690 }
691 if (m_etaBins.size() > 2) {
692 std::vector<float> &etaBinsf = m_measurementSelectorConfig.m_etaBins;
693 etaBinsf.assign(m_etaBins.begin() + 1, m_etaBins.end() - 1);
694 }
695
696 return /*m_measurementSelector ?*/ StatusCode::SUCCESS /*: StatusCode::FAILURE*/;
697 }
698
699 // === Statistics printout =================================================
700
702 if (!m_statEtaBins.empty())
703 {
705 float last_eta = m_statEtaBins[0];
706 for (float eta : m_statEtaBins)
707 {
708 if (eta < last_eta)
709 {
710 ATH_MSG_FATAL("Eta bins for statistics counter not in ascending order.");
711 }
712 last_eta = eta;
713 }
714 }
715 m_stat.resize(nSeedCollections() * seedCollectionStride());
716 }
717
718 // copy statistics
719 void TrackFindingBaseAlg::copyStats(const EventStats &event_stat) const {
720 std::lock_guard<std::mutex> lock(m_mutex);
721 std::size_t category_i = 0;
722 for (const std::array<unsigned int, kNStat> &src_stat : event_stat)
723 {
724 std::array<std::size_t, kNStat> &dest_stat = m_stat[category_i++];
725 for (std::size_t i = 0; i < src_stat.size(); ++i)
726 {
727 assert(i < dest_stat.size());
728 dest_stat[i] += src_stat[i];
729 }
730 }
731 }
732
733 // print statistics
735 if (msgLvl(MSG::INFO))
736 {
737 std::vector<std::string> stat_labels =
739 {
740 std::make_pair(kNTotalSeeds, "Input seeds"),
741 std::make_pair(kNoTrackParam, "No track parameters"),
742 std::make_pair(kNUsedSeeds, "Used seeds"),
743 std::make_pair(kNoTrack, "Cannot find track"),
744 std::make_pair(kNDuplicateSeeds, "Duplicate seeds"),
745 std::make_pair(kNNoEstimatedParams, "Initial param estimation failed"),
746 std::make_pair(kNRejectedSeedParams, "Rejected seed parameters"),
747 std::make_pair(kNSeedRefitFailure, "Seed refit Kalman fit failure"),
748 std::make_pair(kNOutputTracks, "CKF tracks"),
749 std::make_pair(kNSelectedTracks, "selected tracks"),
750 std::make_pair(kNResolvedTracks, "resolved tracks"),
751 std::make_pair(kNStoppedTracksMaxHoles, "Stopped tracks reaching max holes"),
752 std::make_pair(kMultipleBranches, "Seeds with more than one branch"),
753 std::make_pair(kNoSecond, "Tracks failing second CKF"),
754 std::make_pair(kNStoppedTracksMinPt, "Stopped tracks below pT cut"),
755 std::make_pair(kNStoppedTracksMaxEta, "Stopped tracks above max eta"),
756 std::make_pair(kNTotalSharedHits, "Total shared hits"),
757 std::make_pair(kNForcedSeedMeasurements, "Total forced measurements")
758 });
759 assert(stat_labels.size() == kNStat);
760 std::vector<std::string> categories;
761 categories.reserve(m_seedLabels.size() + 1);
762 categories.insert(categories.end(), m_seedLabels.begin(), m_seedLabels.end());
763 categories.push_back("ALL");
764
765 std::vector<std::string> eta_labels;
766 eta_labels.reserve(m_statEtaBins.size() + 2);
767 for (std::size_t eta_bin_i = 0; eta_bin_i < m_statEtaBins.size() + 2; ++eta_bin_i)
768 {
769 eta_labels.push_back(TableUtils::makeEtaBinLabel(m_statEtaBins, eta_bin_i, m_useAbsEtaForStat));
770 }
771
772 // vector used as 3D array stat[ eta_bin ][ stat_i ][ seed_type]
773 // stat_i = [0, kNStat)
774 // eta_bin = [0, m_statEtaBins.size()+2 ); eta_bin == m_statEtaBinsSize()+1 means sum of all etaBins
775 // seed_type = [0, nSeedCollections()+1) seed_type == nSeedCollections() means sum of all seed collections
776 std::vector<std::size_t> stat =
778 m_statEtaBins.size() + 1,
779 m_stat);
780
781 // the extra columns and rows for the projections are addeded internally:
782 std::size_t stat_stride =
784 m_statEtaBins.size() + 1,
785 kNStat);
786 std::size_t eta_stride =
788 m_statEtaBins.size() + 1,
789 kNStat);
790 std::stringstream table_out;
791
792 if (m_dumpAllStatEtaBins.value())
793 {
794 // dump for each counter a table with one row per eta bin
795 std::size_t max_label_width = TableUtils::maxLabelWidth(stat_labels) + TableUtils::maxLabelWidth(eta_labels);
796 for (std::size_t stat_i = 0; stat_i < kNStat; ++stat_i)
797 {
798 std::size_t dest_idx_offset = stat_i * stat_stride;
799 table_out << makeTable(stat, dest_idx_offset, eta_stride,
800 eta_labels,
801 categories)
802 .columnWidth(10)
803 // only dump the footer for the last eta bin i.e. total
804 .dumpHeader(stat_i == 0)
805 .dumpFooter(stat_i + 1 == kNStat)
806 .separateLastRow(true) // separate the sum of all eta bins
807 .minLabelWidth(max_label_width)
808 .labelPrefix(stat_labels.at(stat_i));
809 }
810 }
811 else
812 {
813 // dump one table with one row per counter showing the total eta range
814 for (std::size_t eta_bin_i = (m_dumpAllStatEtaBins.value() ? 0 : m_statEtaBins.size() + 1);
815 eta_bin_i < m_statEtaBins.size() + 2;
816 ++eta_bin_i)
817 {
818 std::size_t dest_idx_offset = eta_bin_i * eta_stride;
819 table_out << makeTable(stat, dest_idx_offset, stat_stride,
820 stat_labels,
821 categories,
822 eta_labels.at(eta_bin_i))
823 .columnWidth(10)
824 // only dump the footer for the last eta bin i.e. total
825 .dumpFooter(!m_dumpAllStatEtaBins.value() || eta_bin_i == m_statEtaBins.size() + 1);
826 }
827 }
828 ATH_MSG_INFO("statistics:\n"
829 << table_out.str());
830 table_out.str("");
831
832 // define retios first element numerator, second element denominator
833 // each element contains a vector of counter and a multiplier e.g. +- 1
834 // ratios are computed as (sum_i stat[stat_i] * multiplier_i ) / (sum_j stat[stat_j] * multiplier_j )
835 auto [ratio_labels, ratio_def] =
837 std::vector<TableUtils::SummandDefinition>{
841 // no track counted as used but want to include it as failed
843 }, // failed seeds i.e. seeds which are not duplicates but did not produce a track
844 std::vector<TableUtils::SummandDefinition>{TableUtils::defineSummand(kNTotalSeeds, 1)}),
846 TableUtils::defineSimpleRatio("Rejected seed params / seeds", kNRejectedSeedParams, kNTotalSeeds),
848 TableUtils::defineSimpleRatio("selected tracks / used seeds", kNSelectedTracks, kNUsedSeeds),
850 TableUtils::defineSimpleRatio("resolved tracks / used seeds", kNResolvedTracks, kNUsedSeeds),
851 TableUtils::defineSimpleRatio("branched tracks / used seeds", kMultipleBranches, kNUsedSeeds),
852 TableUtils::defineSimpleRatio("no 2nd CKF / CKF tracks", kNoSecond, kNOutputTracks),
854 TableUtils::defineSimpleRatio("forced measurements / used seeds", kNForcedSeedMeasurements, kNUsedSeeds)});
855
856 std::vector<float> ratio = TableUtils::computeRatios(ratio_def,
857 nSeedCollections() + 1,
858 m_statEtaBins.size() + 2,
859 stat);
860
861 // the extra columns and rows for the projections are _not_ added internally
862 std::size_t ratio_stride = TableUtils::ratioStride(nSeedCollections() + 1,
863 m_statEtaBins.size() + 2,
864 ratio_def);
865 std::size_t ratio_eta_stride = TableUtils::subCategoryStride(nSeedCollections() + 1,
866 m_statEtaBins.size() + 2,
867 ratio_def);
868
869 std::size_t max_label_width = TableUtils::maxLabelWidth(ratio_labels) + TableUtils::maxLabelWidth(eta_labels);
870 if (m_dumpAllStatEtaBins.value())
871 {
872 // show for each ratio a table with one row per eta bin
873 for (std::size_t ratio_i = 0; ratio_i < ratio_labels.size(); ++ratio_i)
874 {
875 table_out << makeTable(ratio,
876 ratio_i * ratio_stride,
877 ratio_eta_stride,
878 eta_labels,
879 categories)
880 .columnWidth(10)
881 // only dump the footer for the last eta bin i.e. total
882 .dumpHeader(ratio_i == 0)
883 .dumpFooter(ratio_i + 1 == ratio_labels.size())
884 .separateLastRow(true) // separate the sum of las
885 .minLabelWidth(max_label_width)
886 .labelPrefix(ratio_labels.at(ratio_i));
887 }
888 }
889 else
890 {
891 // dump one table with one row per ratio showing the total eta range
892 table_out << makeTable(ratio,
893 (m_statEtaBins.size() + 1) * ratio_eta_stride + 0 * ratio_stride,
894 ratio_stride,
895 ratio_labels,
896 categories)
897 .columnWidth(10)
898 // only dump the footer for the last eta bin i.e. total
899 .minLabelWidth(max_label_width)
900 .dumpFooter(false);
901
902 // also dump a table for final tracks over used seeds (ratio_i==6 or 4) showing one row per eta bin
903 eta_labels.erase(eta_labels.end() - 1); // drop last line of table which shows again all eta bins summed.
904 std::size_t ratio_i = m_showResolvedStats ? 6 : 4;
905 table_out << makeTable(ratio,
906 ratio_i * ratio_stride,
907 ratio_eta_stride,
908 eta_labels,
909 categories)
910 .columnWidth(10)
911 .dumpHeader(false)
912 // only dump the footer for the last eta bin i.e. total
913 .dumpFooter(!m_dumpAllStatEtaBins.value() || ratio_i + 1 == ratio_labels.size())
914 .separateLastRow(false)
915 .minLabelWidth(max_label_width)
916 .labelPrefix(ratio_labels.at(ratio_i));
917 }
918
919 ATH_MSG_INFO("Ratios:\n"
920 << table_out.str());
921 }
922 }
923
924 std::size_t TrackFindingBaseAlg::getStatCategory(std::size_t seed_collection, float eta) const {
925 std::vector<float>::const_iterator bin_iter = std::upper_bound(m_statEtaBins.begin(),
926 m_statEtaBins.end(),
927 m_useAbsEtaForStat ? std::abs(eta) : eta);
928 std::size_t category_i = seed_collection * seedCollectionStride() + static_cast<std::size_t>(bin_iter - m_statEtaBins.begin());
929 assert(category_i < m_stat.size());
930 return category_i;
931 }
932
933 std::size_t TrackFindingBaseAlg::computeStatSum(std::size_t seed_collection, EStat counter_i, const EventStats &stat) const {
934 std::size_t out = 0u;
935 for (std::size_t category_i = seed_collection * seedCollectionStride();
936 category_i < (seed_collection + 1) * seedCollectionStride();
937 ++category_i)
938 {
939 assert(category_i < stat.size());
940 out += stat[category_i][counter_i];
941 }
942 return out;
943 }
944
945 bool TrackFindingBaseAlg::selectCountsFinal(const detail::RecoTrackContainer::TrackProxy &track) const {
946 if (not m_addCounts) return true;
947 double eta = -std::log(std::tan(0.5 * track.theta()));
948 auto [enoughMeasurementsPS, tooManyHolesPS, tooManyOutliersPS] = selectCounts(track, eta);
949 return enoughMeasurementsPS && !tooManyHolesPS && !tooManyOutliersPS;
950 }
951
952 bool TrackFindingBaseAlg::hasMatchingCaloROI(const Acts::GeometryContext &geoCtx,
953 const std::optional<Acts::BoundTrackParameters> &boundParams, const ROIPhiRZContainer &caloClusterROIs
954 ) const
955 {
956 assert(m_doBremRecovery && "brem recovery must be turned on");
957 double phi = boundParams->phi();
958 double eta = Acts::AngleHelpers::etaFromTheta(boundParams->theta());
959 const Acts::Vector3 pos = boundParams->position(geoCtx);
960 double radius = pos.perp();
961 double z = boundParams->position(geoCtx).z();
962 return caloClusterROIs.hasMatchingROI(phi, eta, radius, z, m_phiWidthROI, m_etaWidthROI);
963 }
964
965} // namespace ActsTrk
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#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.
TableUtils::StatTable< T > makeTable(const std::array< T, N > &counter, const std::array< std::string, N > &label)
Definition TableUtils.h:544
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
#define z
Extension of the interface of the Acts::SurfacePlacementBase for ATLAS.
Gaudi::Property< std::vector< std::size_t > > m_maxStripHoles
const Acts::Logger & bremLogger() const
Gaudi::Property< double > m_branchStopperAbsEtaMeasCut
Gaudi::Property< std::vector< float > > m_statEtaBins
Gaudi::Property< double > m_seedPtMinFactor
Gaudi::Property< double > m_branchStopperPtMinFactor
Gaudi::Property< std::vector< std::size_t > > m_maxOutliers
Gaudi::Property< std::vector< std::size_t > > m_maxHgtdHoles
std::unique_ptr< const Acts::Logger > m_logger
logging instance
Gaudi::Property< std::vector< double > > m_etaBins
Gaudi::Property< bool > m_doTwoWay
Gaudi::Property< bool > m_dumpAllStatEtaBins
Gaudi::Property< std::vector< size_t > > m_numMeasurementsCutOff
Gaudi::Property< std::vector< std::size_t > > m_maxSharedHits
Gaudi::Property< unsigned int > m_maxPropagationStep
static xAOD::UncalibMeasType measurementType(const detail::RecoTrackContainer::TrackStateProxy &trackState)
ToolHandle< ActsTrk::TrackStatePrinterTool > m_trackStatePrinter
Gaudi::Property< double > m_edgeHoleBorderWidth
Gaudi::Property< std::vector< double > > m_etaMax
Gaudi::Property< std::vector< double > > m_ptMin
std::unique_ptr< bremCKF_pimpl > m_bremTrackFinder
Gaudi::Property< std::vector< std::size_t > > m_minPixelHits
Gaudi::Property< std::vector< std::size_t > > m_maxStripOutliers
SG::WriteHandleKey< ActsTrk::TrackContainer > m_trackContainerKey
Gaudi::Property< std::vector< double > > m_chi2CutOffSigma
Gaudi::Property< std::vector< double > > m_ptMax
void inflateCovarianceTwoWay(Acts::BoundTrackParameters &secondInitialParameters) const
Gaudi::Property< std::vector< std::size_t > > m_maxPixelHoles
static constexpr BranchState s_branchState
void copyStats(const EventStats &event_stat) const
Gaudi::Property< std::vector< double > > m_phiMin
std::unique_ptr< CKF_pimpl > getTrackFindingFunction(std::shared_ptr< const Acts::TrackingGeometry >, Acts::TrackSelector::EtaBinnedConfig)
Gaudi::Property< double > m_branchStopperMeasCutReduce
ToolHandle< ActsTrk::IPixelOnTrackCalibratorTool< detail::RecoTrackStateContainer > > m_pixelCalibTool
Gaudi::Property< std::vector< std::uint32_t > > m_endOfWorldVolumeIds
Gaudi::Property< std::vector< std::size_t > > m_minStripHits
ActsTrk::MutableTrackContainerHandlesHelper m_tracksBackendHandlesHelper
std::size_t getStatCategory(std::size_t seed_collection, float eta) const
std::size_t seedCollectionStride() const
Gaudi::Property< double > m_branchStopperAbsEtaMaxExtra
std::unique_ptr< const Acts::Logger > m_bremLogger
ToolHandle< GenericMonitoringTool > m_monTool
Gaudi::Property< std::vector< std::size_t > > m_absEtaMaxMeasurements
Gaudi::Property< double > m_phiWidthROI
TrackFindingBaseAlg(const std::string &name, ISvcLocator *pSvcLocator)
Gaudi::Property< std::vector< double > > m_etaMin
Gaudi::Property< bool > m_recordMaterialStates
Gaudi::Property< std::vector< double > > m_d0Min
virtual StatusCode execute(const EventContext &ctx) const override
Gaudi::Property< std::string > m_bremMergeMethod
Gaudi::Property< double > m_bremWeightCutoff
Gaudi::Property< std::vector< std::size_t > > m_maxHgtdOutliers
Gaudi::Property< std::vector< double > > m_z0Max
Gaudi::Property< double > m_absEtaMax
std::size_t computeStatSum(std::size_t seed_collection, EStat counter_i, const EventStats &stat) const
virtual StatusCode initialize() override
Gaudi::Property< std::vector< double > > m_z0Min
void checkCounts(const detail::RecoTrackContainer::TrackProxy &track) const
Gaudi::Property< bool > m_doBranchStopper
static void addCountsAndProperties(detail::RecoTrackContainer &tracksContainer, bool add_counts)
Gaudi::Property< std::vector< std::size_t > > m_minMeasurements
Gaudi::Property< std::vector< double > > m_maxChi2
Gaudi::Property< double > m_absEtaMin
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.
Gaudi::Property< std::size_t > m_bremMaxComponents
static void initCounts(const detail::RecoTrackContainer::TrackProxy &track)
Gaudi::Property< std::vector< std::size_t > > m_maxPixelOutliers
const Acts::TrackSelector::Config & getCuts(double eta) const
Retrieves track selector configuration for given eta value.
Gaudi::Property< bool > m_checkCounts
Gaudi::Property< std::vector< std::size_t > > m_maxHoles
ToolHandle< ActsTrk::IStripOnTrackCalibratorTool< detail::RecoTrackStateContainer > > m_stripCalibTool
std::array< bool, 3 > selectCounts(const detail::RecoTrackContainer::TrackProxy &track, double eta) const
std::unique_ptr< bremCKF_pimpl > getBremTrackFindingFunction(std::shared_ptr< const Acts::TrackingGeometry >, Acts::TrackSelector::EtaBinnedConfig)
Gaudi::Property< std::vector< std::size_t > > m_maxHolesAndOutliers
std::unique_ptr< CKF_pimpl > m_trackFinder
Gaudi::Property< std::vector< double > > m_chi2OutlierCutOffSigma
bool hasMatchingCaloROI(const Acts::GeometryContext &geoCtx, const std::optional< Acts::BoundTrackParameters > &boundParams, const ROIPhiRZContainer &caloClusterROIs) const
Acts::BremCombinatorialKalmanFilterOptions< detail::RecoTrackContainer > BremTrackFinderOptions
TrackFindingBremOptions getBremOptions(const EventContext &ctx, const DetectorContextHolder &detContext, const detail::TrackFindingMeasurements &measurements, const Acts::PerigeeSurface *pSurface) const
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.
Acts::CombinatorialKalmanFilterOptions< detail::RecoTrackContainer > TrackFinderOptions
virtual StatusCode finalize() override
ContextUtility m_ctxProvider
Utility to fetch the geometry, magnetic field and calibration context in the event.
std::vector< std::array< unsigned int, kNStat > > EventStats
ToolHandle< ActsTrk::IHGTDOnTrackCalibratorTool< detail::RecoTrackStateContainer > > m_hgtdCalibTool
Gaudi::Property< bool > m_doBremRecovery
Gaudi::Property< double > m_twoWayinflateCovarianceFactor
static void updateCounts(const detail::RecoTrackContainer::TrackProxy &track, Acts::ConstTrackStateTypeMap typeFlags, xAOD::UncalibMeasType detType)
Gaudi::Property< bool > m_addCounts
Gaudi::Property< std::vector< std::size_t > > m_minHgtdHits
struct ActsTrk::TrackFindingBaseAlg::MeasurementSelectorConfig m_measurementSelectorConfig
Gaudi::Property< double > m_etaWidthROI
Acts::Result< std::vector< TrkProxy > > findTracksCKF(const Acts::BoundTrackParameters &seedParameters, const TrackFinderOptions &options, detail::RecoTrackContainer &tracksContainerTemp, detail::RecoTrackContainer::TrackProxy &rootBranch) const
Gaudi::Property< std::vector< double > > m_phiMax
Gaudi::Property< std::vector< std::size_t > > m_ptMinMeasurements
Gaudi::Property< std::vector< double > > m_d0Max
Acts::CombinatorialKalmanFilterBranchStopperResult BranchStopperResult
std::unique_ptr< ActsTrk::IMeasurementSelector > setMeasurementSelector(const EventContext &ctx, const detail::TrackFindingMeasurements &measurements, TrackFinderOptions &options) const
Setup and attach measurement selector to KF options.
Gaudi::Property< std::uint32_t > m_envelopeConstraint
Stop the propagation as soon as the envelope is left (Gen3 only).
bool selectCountsFinal(const detail::RecoTrackContainer::TrackProxy &track) const
Gaudi::Property< std::vector< std::string > > m_seedLabels
const MeasurementRangeList & measurementRanges() const
bool msgLvl(const MSG::Level lvl) const
An algorithm that can be simultaneously executed in multiple threads.
container for phi sorted ROIs defined by phi, r and z.
bool hasMatchingROI(float phi, double eta, double r, double z, float roi_phi_width, double roi_eta_width) const
Test whether there is a matching ROI for the given phi and r,z corrected eta.
static Root::TMsgLogger logger("iLumiCalc")
Acts::Result< void > gainMatrixUpdate(const Acts::GeometryContext &gctx, typename trajectory_t::TrackStateProxy trackState, const Acts::Logger &logger)
Acts::Propagator< BremStepper, Navigator > BremPropagator
Acts::SympyStepper Stepper
Adapted from Acts Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithmFunction....
Acts::CombinatorialKalmanFilter< BremPropagator, RecoTrackContainer > BremCKF
std::unique_ptr< ActsTrk::IMeasurementSelector > getMeasurementSelector(const EventContext &ctx, const ActsTrk::IPixelOnTrackCalibratorTool< detail::RecoTrackStateContainer > *pixelOnTrackCalibratorTool, const ActsTrk::IStripOnTrackCalibratorTool< detail::RecoTrackStateContainer > *stripOnTrackCalibratorTool, const ActsTrk::IHGTDOnTrackCalibratorTool< detail::RecoTrackStateContainer > *hgtdOnTrackCalibratorTool, const ActsTrk::detail::MeasurementRangeList &measurementRanges, const std::vector< float > &etaBinsf, const std::vector< std::array< std::pair< float, float >, 4 > > &chi2CutOffOutlier, const std::vector< size_t > &numMeasurementsCutOff, double edge_hole_border_width)
Acts::TrackContainer< Acts::VectorTrackContainer, Acts::VectorMultiTrajectory > RecoTrackContainer
Acts::CombinatorialKalmanFilter< Propagator, RecoTrackContainer > CKF
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
std::string prefixFromTrackContainerName(const std::string &tracks)
Parse TrackContainer name to get the prefix for backends The name has to contain XYZTracks,...
@ Pixel
Inner detector legacy.
SystemEnvelope
Define an enumeration to retrieve the envelope tracking volume from.
std::tuple< std::vector< std::string >, std::vector< RatioDefinition > > splitRatioDefinitionsAndLabels(std::initializer_list< std::tuple< std::string, RatioDefinition > > a_ratio_list)
Definition TableUtils.h:469
SummandDefinition defineSummand(T counter_idx, int multiplier)
Definition TableUtils.h:423
std::size_t maxLabelWidth(const T_Collection &col)
Definition TableUtils.h:311
RatioDefinition defineSimpleRatio(T numerator, T denominator)
Definition TableUtils.h:405
std::vector< std::string > makeLabelVector(T_index n_entries, std::initializer_list< std::pair< T_index, T_string > > a_list)
Definition TableUtils.h:296
constexpr std::size_t subCategoryStride(const std::size_t categories, const std::size_t sub_categories, const std::size_t n_counter)
Definition TableUtils.h:325
constexpr std::size_t counterStride(const std::size_t categories, const std::size_t sub_categories, const std::size_t n_counter)
Definition TableUtils.h:330
std::string makeEtaBinLabel(const std::vector< float > &eta_bins, std::size_t eta_bin_i, bool abs_eta=false)
Definition TableUtils.h:535
std::tuple< std::string, RatioDefinition > makeRatioDefinition(std::string &&name, std::vector< SummandDefinition > &&numerator, std::vector< SummandDefinition > &&denominator)
Definition TableUtils.h:459
std::vector< float > computeRatios(const std::vector< RatioDefinition > &ratio_def, const std::size_t categories, const std::size_t sub_categories, const std::vector< std::size_t > &counter)
constexpr std::size_t ratioStride(const std::size_t categories, const std::size_t sub_categories, const std::vector< RatioDefinition > &ratio_def)
Definition TableUtils.h:494
std::vector< T_Output > createCounterArrayWithProjections(const std::size_t categories, const std::size_t sub_categories, const std::vector< std::array< T_Input, N > > &input_counts)
Definition TableUtils.h:343
@ GaussianSumFilter
Tracks from Gaussian Sum Filter.
UncalibMeasType
Define the type of the uncalibrated measurement.
static void addFitterTypeProperty(track_container_t &tracksContainer)
add fitter column to the track container
static xAOD::TrackFitter fitterType(const consttrackproxy_t &trackProxy)
get fitter type of a track