diff --git a/AtlasTest/CITest/Athena.cmake b/AtlasTest/CITest/Athena.cmake index 219c9fdbfb81ca636afc4298e518d1e9ab2213c8..498fbc94e2f31e2f2a33ee5a00f424fa1b2f311b 100644 --- a/AtlasTest/CITest/Athena.cmake +++ b/AtlasTest/CITest/Athena.cmake @@ -291,6 +291,9 @@ atlas_add_citest( ACTS_ActsBenchmarkWithSpot PROPERTIES PROCESSOR 8 LOG_IGNORE_PATTERN "ActsTrackFindingAlg.*ERROR Propagation reached the step count limit|ActsTrackFindingAlg.*ERROR Propagation failed: PropagatorError:3 Propagation reached the configured maximum number of steps with the initial parameters|ActsTrackFindingAlg.*ERROR CombinatorialKalmanFilter failed: CombinatorialKalmanFilterError:5 Propagation reaches max steps before track finding is finished with the initial parameters|ActsTrackFindingAlg.Acts.*ERROR.*SurfaceError:1" ) +atlas_add_citest( ACTS_ActsAnalogueClustering + SCRIPT ActsAnalogueClustering.sh ) + ################################################################################# # Trigger ################################################################################# diff --git a/Tracking/Acts/ActsConfig/python/ActsConfigFlags.py b/Tracking/Acts/ActsConfig/python/ActsConfigFlags.py index f721ab7c215c7c864f6e69a8ae6f2a50372b11c7..bef91085727e89552b9d3d5ef03c4a06eb8fd8fd 100644 --- a/Tracking/Acts/ActsConfig/python/ActsConfigFlags.py +++ b/Tracking/Acts/ActsConfig/python/ActsConfigFlags.py @@ -16,6 +16,10 @@ class TrackFitterType(FlagEnum): KalmanFitter = 'KalmanFitter' # default ACTS fitter to choose GaussianSumFitter = 'GaussianSumFitter' # new experimental implementation +class PixelCalibrationStrategy(FlagEnum): + Uncalibrated = "Uncalibrated" + AnalogueClustering = "AnalogueClustering" + def createActsConfigFlags(): actscf = AthConfigFlags() @@ -48,6 +52,7 @@ def createActsConfigFlags(): actscf.addFlag("Acts.SeedingStrategy", SeedingStrategy.Default, type=SeedingStrategy) # Define Seeding Strategy # Track finding + actscf.addFlag('Acts.PixelCalibrationStrategy', PixelCalibrationStrategy.Uncalibrated, type=PixelCalibrationStrategy) actscf.addFlag('Acts.doRotCorrection', True) actscf.addFlag('Acts.doPrintTrackStates', False) actscf.addFlag('Acts.skipDuplicateSeeds', True) diff --git a/Tracking/Acts/ActsConfig/python/ActsMeasurementCalibrationConfig.py b/Tracking/Acts/ActsConfig/python/ActsMeasurementCalibrationConfig.py new file mode 100644 index 0000000000000000000000000000000000000000..76737bb337f4d89afc5943456ee26deb0f735ae8 --- /dev/null +++ b/Tracking/Acts/ActsConfig/python/ActsMeasurementCalibrationConfig.py @@ -0,0 +1,34 @@ +# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration + +from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator +from AthenaConfiguration.ComponentFactory import CompFactory + +def ActsAnalogueClusteringToolCfg(flags, + name: str='ActsAnalogueClusteringTool', + **kwargs) -> ComponentAccumulator: + + if not flags.Detector.GeometryITk: + raise Exception("Acts Analogue Clustering calibration only supports ITk!") + + from PixelConditionsAlgorithms.ITkPixelConditionsConfig import ITkPixelOfflineCalibCondAlgCfg + from SiLorentzAngleTool.ITkPixelLorentzAngleConfig import ITkPixelLorentzAngleToolCfg + + acc = ComponentAccumulator() + + acc.merge(ITkPixelOfflineCalibCondAlgCfg(flags)) + + if 'DetEleCollKey' not in kwargs: + kwargs.setdefault("DetEleCollKey", "ITkPixelDetectorElementCollection") + + if 'PixelOfflineCalibData' not in kwargs: + kwargs.setdefault("PixelOfflineCalibData", "ITkPixelOfflineCalibData") + + if 'PixelLorentzAngleTool' not in kwargs: + kwargs.setdefault("PixelLorentzAngleTool", acc.popToolsAndMerge(ITkPixelLorentzAngleToolCfg(flags))) + + if 'CalibrateErrors' not in kwargs: + kwargs.setdefault("CalibrateErrors", not flags.Tracking.useBroadPixClusterErrors) + + acc.setPrivateTools(CompFactory.ActsTrk.ITkAnalogueClusteringTool(name, **kwargs)) + + return acc diff --git a/Tracking/Acts/ActsConfig/python/ActsTrackFindingConfig.py b/Tracking/Acts/ActsConfig/python/ActsTrackFindingConfig.py index 766421ca02ddda5385b2bba40474e85701aa7371..ee9ac463c5e03c388d497a40ca5e6ea85549b7d0 100644 --- a/Tracking/Acts/ActsConfig/python/ActsTrackFindingConfig.py +++ b/Tracking/Acts/ActsConfig/python/ActsTrackFindingConfig.py @@ -117,6 +117,18 @@ def ActsMainTrackFindingAlgCfg(flags, ReverseFilteringPt=0, OutlierChi2Cut=30)) ) + + if 'PixelCalibrator' not in kwargs: + from AthenaConfiguration.Enums import BeamType + from ActsConfig.ActsConfigFlags import PixelCalibrationStrategy + from ActsConfig.ActsMeasurementCalibrationConfig import ActsAnalogueClusteringToolCfg + + if flags.Beam.Type is not BeamType.Cosmics: + if flags.Acts.PixelCalibrationStrategy is PixelCalibrationStrategy.AnalogueClustering: + kwargs.setdefault( + 'PixelCalibrator', + acc.popToolsAndMerge(ActsAnalogueClusteringToolCfg(flags)) + ) if flags.Acts.doMonitoring and 'MonTool' not in kwargs: from ActsConfig.ActsMonitoringConfig import ActsTrackFindingMonitoringToolCfg diff --git a/Tracking/Acts/ActsConfig/test/ActsAnalogueClustering.sh b/Tracking/Acts/ActsConfig/test/ActsAnalogueClustering.sh new file mode 100755 index 0000000000000000000000000000000000000000..720b529c5131a5ad1f560e4cb09a1834cc2e73a4 --- /dev/null +++ b/Tracking/Acts/ActsConfig/test/ActsAnalogueClustering.sh @@ -0,0 +1,13 @@ +#!/usr/bin/bash +# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration + +# ttbar mu=200 input +input_rdo=/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/PhaseIIUpgrade/RDO/ATLAS-P2-RUN4-03-00-00/mc21_14TeV.601229.PhPy8EG_A14_ttbar_hdamp258p75_SingleLep.recon.RDO.e8481_s4149_r14700/RDO.33629020._000047.pool.root.1 +n_events=2 + +Reco_tf.py --CA \ + --preInclude "InDetConfig.ConfigurationHelpers.OnlyTrackingPreInclude,ActsConfig.ActsCIFlags.actsValidateTracksFlags" \ + --preExec 'from ActsConfig.ActsConfigFlags import PixelCalibrationStrategy; flags.Acts.PixelCalibrationStrategy=PixelCalibrationStrategy.AnalogueClustering' \ + --inputRDOFile ${input_rdo} \ + --outputAODFile test.AOD.pool.root \ + --maxEvents ${n_events} diff --git a/Tracking/Acts/ActsTrackReconstruction/CMakeLists.txt b/Tracking/Acts/ActsTrackReconstruction/CMakeLists.txt index 77e23639fbc1ce241788be5a4cd8ccbf54ffe331..0048eabd60227098866fa873d5e63edaf4372723 100644 --- a/Tracking/Acts/ActsTrackReconstruction/CMakeLists.txt +++ b/Tracking/Acts/ActsTrackReconstruction/CMakeLists.txt @@ -33,6 +33,7 @@ atlas_add_component( ActsTrackReconstruction InDetReadoutGeometry MagFieldConditions MagFieldElements + PixelConditionsData StoreGateLib TRT_ReadoutGeometry TrkEventPrimitives diff --git a/Tracking/Acts/ActsTrackReconstruction/src/AnalogueClusteringToolImpl.h b/Tracking/Acts/ActsTrackReconstruction/src/AnalogueClusteringToolImpl.h new file mode 100644 index 0000000000000000000000000000000000000000..68ff2e9a40a6c5cbee037516cb69299b66073673 --- /dev/null +++ b/Tracking/Acts/ActsTrackReconstruction/src/AnalogueClusteringToolImpl.h @@ -0,0 +1,96 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef ACTS_ANALOGUECLUSTERING_H +#define ACTS_ANALOGUECLUSTERING_H + +#include "AthenaBaseComps/AthAlgTool.h" +#include "InDetReadoutGeometry/SiDetectorElementCollection.h" +#include "PixelConditionsData/ITkPixelOfflineCalibData.h" +#include "StoreGate/ReadCondHandleKey.h" + +#include "ActsToolInterfaces/IOnTrackCalibratorTool.h" +#include "OnTrackCalibrator.h" + +namespace ActsTrk { + +template <typename calib_data_t, typename traj_t> +class AnalogueClusteringToolImpl : public extends<AthAlgTool, IOnTrackCalibratorTool<traj_t>> { +public: + using base_class = typename extends<AthAlgTool, IOnTrackCalibratorTool<traj_t>>::base_class; + using Pos = typename OnTrackCalibrator<traj_t>::PixelPos; + using Cov = typename OnTrackCalibrator<traj_t>::PixelCov; + using TrackStateProxy = typename OnTrackCalibrator<traj_t>::TrackStateProxy; + + AnalogueClusteringToolImpl(const std::string& type, + const std::string& name, + const IInterface* parent); + + virtual StatusCode initialize() override; + + std::pair<Pos, Cov> calibrate(const Acts::GeometryContext&, + const Acts::CalibrationContext&, + const xAOD::PixelCluster&, + const TrackStateProxy&) const; + + virtual void connect(OnTrackCalibrator<traj_t>& calibrator) const override; + +private: + + using error_data_t = typename std::remove_pointer_t<decltype(std::declval<calib_data_t>().getClusterErrorData())>; + + const InDetDD::SiDetectorElement* getDetectorElement(xAOD::DetectorIDHashType id) const; + + std::pair<float, float> anglesOfIncidence(const InDetDD::SiDetectorElement& element, + const TrackStateProxy& state) const; + + const error_data_t* getErrorData() const; + + std::pair<float, float> + getPositionCorrection(const error_data_t& errorData, + const InDetDD::SiDetectorElement& element, + const std::pair<float, float>& angles, + const xAOD::PixelCluster& cluster) const; + + std::pair<float, float> + getCorrectedError(const error_data_t& errorData, + const InDetDD::SiDetectorElement& element, + const std::pair<float, float>& angles, + const xAOD::PixelCluster& cluster) const; + + SG::ReadCondHandleKey<InDetDD::SiDetectorElementCollection> m_pixelDetEleCollKey { + this, + "DetEleCollKey", + "", + "Key of SiDetectorElementCollection for Pixel" + }; + + SG::ReadCondHandleKey<calib_data_t> m_clusterErrorKey { + this, + "PixelOfflineCalibData", + "ITkPixelOfflineCalibData", + "Calibration data for pixel clusters" + }; + + + ToolHandle<ISiLorentzAngleTool> m_lorentzAngleTool { + this, + "PixelLorentzAngleTool", + "", + "Tool to retreive Lorentz angle" + }; + + Gaudi::Property<bool> m_doErrCalib {this, "CalibrateErrors", true}; + + // in micrometers + Gaudi::Property<int> m_thickness {this, "PixelThickness", 250}; + + +}; + +} // namespace ActsTrk + +#include "AnalogueClusteringToolImpl.icc" + +#endif diff --git a/Tracking/Acts/ActsTrackReconstruction/src/AnalogueClusteringToolImpl.icc b/Tracking/Acts/ActsTrackReconstruction/src/AnalogueClusteringToolImpl.icc new file mode 100644 index 0000000000000000000000000000000000000000..c5ec19201d82362cca3956c770a3ec54616060f4 --- /dev/null +++ b/Tracking/Acts/ActsTrackReconstruction/src/AnalogueClusteringToolImpl.icc @@ -0,0 +1,242 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef ANALOGUECLUSTERINGTOOLIMPL_ICC +#define ANALOGUECLUSTERINGTOOLIMPL_ICC + +namespace ActsTrk { + +template <typename calib_data_t, typename traj_t> +AnalogueClusteringToolImpl<calib_data_t, traj_t>::AnalogueClusteringToolImpl( + const std::string& type, + const std::string& name, + const IInterface* parent) + : base_class(type, name, parent) +{} + +template <typename calib_data_t, typename traj_t> +StatusCode AnalogueClusteringToolImpl<calib_data_t, traj_t>::initialize() +{ + ATH_MSG_DEBUG("Initializing " << AthAlgTool::name() << " ..."); + ATH_CHECK(m_pixelDetEleCollKey.initialize()); + ATH_CHECK(m_clusterErrorKey.initialize()); + ATH_CHECK(m_lorentzAngleTool.retrieve()); + ATH_MSG_DEBUG(AthAlgTool::name() << " successfully initialized"); + return StatusCode::SUCCESS; +} + +template <typename calib_data_t, typename traj_t> +const InDetDD::SiDetectorElement* +AnalogueClusteringToolImpl<calib_data_t, traj_t>::getDetectorElement(xAOD::DetectorIDHashType id) const +{ + SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> pixelDetEleHandle( + m_pixelDetEleCollKey, + Gaudi::Hive::currentContext()); + + const InDetDD::SiDetectorElementCollection* detElements(*pixelDetEleHandle); + + if (!pixelDetEleHandle.isValid() or detElements == nullptr) { + ATH_MSG_ERROR(m_pixelDetEleCollKey.fullKey() << " is not available."); + return nullptr; + } + + const InDetDD::SiDetectorElement* element = detElements->getDetectorElement(id); + if (element == nullptr) { + ATH_MSG_ERROR("No element corresponding to hash " << id << " for " << m_pixelDetEleCollKey.fullKey()); + return nullptr; + } + + return element; +} + +template <typename calib_data_t, typename traj_t> +std::pair<float, float> +AnalogueClusteringToolImpl<calib_data_t, traj_t>::anglesOfIncidence(const InDetDD::SiDetectorElement& element, + const TrackStateProxy& state) const +{ + + Acts::Vector3 direction = Acts::makeDirectionFromPhiTheta( + state.parameters()[Acts::eBoundPhi], + state.parameters()[Acts::eBoundTheta]); + + float projPhi = direction.dot(element.phiAxis()); + float projEta = direction.dot(element.etaAxis()); + float projNorm = direction.dot(element.normal()); + + float anglePhi = std::atan2(projPhi, projNorm); + float angleEta = std::atan2(projEta, projNorm); + + // Map the angles of inward-going tracks onto [-PI/2, PI/2] + if (anglePhi > M_PI *0.5) { + anglePhi -= M_PI; + } + if (anglePhi < -M_PI *0.5) { + anglePhi += M_PI; + } + + // settle the sign/pi periodicity issues + float thetaloc; + if (angleEta > -0.5 * M_PI && angleEta < M_PI / 2.) { + thetaloc = M_PI_2 - angleEta; + } else if (angleEta > M_PI_2 && angleEta < M_PI) { + thetaloc = 1.5 * M_PI - angleEta; + } else { // 3rd quadrant + thetaloc = -M_PI_2 - angleEta; + } + angleEta = -1 * log(tan(thetaloc * 0.5)); + + + // Subtract the Lorentz angle effect + float angleShift = m_lorentzAngleTool->getTanLorentzAngle(element.identifyHash()); + anglePhi = std::atan(std::tan(anglePhi) - element.design().readoutSide() * angleShift); + + return std::make_pair(anglePhi, angleEta); +} + +template <typename calib_data_t, typename traj_t> +const typename AnalogueClusteringToolImpl<calib_data_t, traj_t>::error_data_t* +AnalogueClusteringToolImpl<calib_data_t, traj_t>::getErrorData() const +{ + SG::ReadCondHandle<calib_data_t> handle( + m_clusterErrorKey, + Gaudi::Hive::currentContext()); + + if (!handle.isValid()) { + ATH_MSG_ERROR(m_clusterErrorKey << " is not available."); + return nullptr; + } + + const error_data_t* data = handle->getClusterErrorData(); + if (data == nullptr) { + ATH_MSG_ERROR("No cluster error data corresponding to " << m_clusterErrorKey); + return nullptr; + } + + return data; +} + +template <typename calib_data_t, typename traj_t> +std::pair<float, float> +AnalogueClusteringToolImpl<calib_data_t, traj_t>::getPositionCorrection( + const error_data_t& errorData, + const InDetDD::SiDetectorElement& element, + const std::pair<float, float>& angles, + const xAOD::PixelCluster& cluster) const +{ + // TODO validate these angles + auto& [anglePhi, angleEta] = angles; + + float deltaX = 0; + float deltaY = 0; + + float omX = cluster.omegaX(); + float omY = cluster.omegaY(); + int nrows = cluster.channelsInPhi(); + int ncols = cluster.channelsInEta(); + + if (omX > -0.5 && omY > -0.5 && (nrows > 1 || ncols > 1)) { + Identifier id = element.identify(); + std::pair<double, double> delta = + errorData.getDelta( + &id, + nrows, + anglePhi, + ncols, + angleEta); + + if (nrows > 1) + deltaX = delta.first * (omX - 0.5); + + if (ncols > 1) + deltaY = delta.second * (omY - 0.5); + } + + return std::make_pair(deltaX, deltaY); +} + +template <typename calib_data_t, typename traj_t> +std::pair<float, float> +AnalogueClusteringToolImpl<calib_data_t, traj_t>::getCorrectedError( + const error_data_t& errorData, + const InDetDD::SiDetectorElement& element, + const std::pair<float, float>& angles, + const xAOD::PixelCluster& cluster) const +{ + float errX = 0; + float errY = 0; + + int nrows = cluster.channelsInPhi(); + int ncols = cluster.channelsInEta(); + + auto& [anglePhi, angleEta] = angles; + + // Special case for very shallow tracks + // Error estimated from geometrical projection of + // the track path in silicon onto the module surface + if (std::abs(anglePhi) > 1) { + errX = m_thickness * Acts::UnitConstants::um * std::tan(std::abs(anglePhi)) / std::sqrt(12); + errY = m_thickness * Acts::UnitConstants::um * std::tan(std::abs(angleEta)); + if (cluster.widthInEta() > errY) { + errY = cluster.widthInEta() / std::sqrt(12); + } else { + errY /= std::sqrt(12); + } + } else if (nrows > 1 && ncols > 1) { + Identifier id = element.identify(); + std::tie(errX, errY) = errorData.getDeltaError(&id); + } + + return std::make_pair(errX, errY); +} + +template <typename calib_data_t, typename traj_t> +std::pair<typename AnalogueClusteringToolImpl<calib_data_t, traj_t>::Pos, + typename AnalogueClusteringToolImpl<calib_data_t, traj_t>::Cov> +AnalogueClusteringToolImpl<calib_data_t, traj_t>::calibrate( + const Acts::GeometryContext& /*gctx*/, + const Acts::CalibrationContext& /*cctx*/, + const xAOD::PixelCluster& cluster, + const TrackStateProxy& state) const +{ + Pos pos = cluster.template localPosition<2>(); + Cov cov = cluster.template localCovariance<2>(); + + assert(!cluster.rdoList().empty()); + const InDetDD::SiDetectorElement *detElement = getDetectorElement(cluster.identifierHash()); + if (detElement == nullptr) { + throw std::runtime_error("SiDetectorElement is NULL"); + } + + const error_data_t *errorData = getErrorData(); + if (errorData == nullptr) { + throw std::runtime_error("PixelClusterErrorData is NULL"); + } + + std::pair<float, float> angles = anglesOfIncidence(*detElement, state); + + auto [deltaX, deltaY] = getPositionCorrection(*errorData, *detElement, angles, cluster); + pos[Acts::eBoundLoc0] += deltaX; + pos[Acts::eBoundLoc1] += deltaY; + + if (m_doErrCalib) { + auto [errX, errY] = getCorrectedError(*errorData, *detElement, angles, cluster); + if (errX > 0) + cov(0, 0) = errX * errX; + if (errY > 0) + cov(1, 1) = errY * errY; + } + + return std::make_pair(pos, cov); +} + +template <typename calib_data_t, typename traj_t> +void AnalogueClusteringToolImpl<calib_data_t, traj_t>::connect(OnTrackCalibrator<traj_t>& calibrator) const +{ + calibrator.pixel_calibrator. template connect<&AnalogueClusteringToolImpl<calib_data_t, traj_t>::calibrate>(this); +} + + +} // namespace ActsTrk + +#endif diff --git a/Tracking/Acts/ActsTrackReconstruction/src/ITkAnalogueClusteringTool.h b/Tracking/Acts/ActsTrackReconstruction/src/ITkAnalogueClusteringTool.h new file mode 100644 index 0000000000000000000000000000000000000000..8062eaad2bd178732d5dd30337bf96c4ee9f3707 --- /dev/null +++ b/Tracking/Acts/ActsTrackReconstruction/src/ITkAnalogueClusteringTool.h @@ -0,0 +1,23 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef ACTS_ITKANALOGUECLUSTERINGTOOL_H +#define ACTS_ITKANALOGUECLUSTERINGTOOL_H + +#include "AnalogueClusteringToolImpl.h" + +namespace ActsTrk { + +class ITkAnalogueClusteringTool : + public AnalogueClusteringToolImpl<ITk::PixelOfflineCalibData, ActsTrk::MutableTrackStateBackend> { +public: + using calib_data_t = ITk::PixelOfflineCalibData; + using traj_t = ActsTrk::MutableTrackStateBackend; + using AnalogueClusteringToolImpl<calib_data_t, traj_t>::AnalogueClusteringToolImpl; +}; + +} // namespace ActsTrk + + +#endif diff --git a/Tracking/Acts/ActsTrackReconstruction/src/OnTrackCalibrator.h b/Tracking/Acts/ActsTrackReconstruction/src/OnTrackCalibrator.h index 00248036c2ab534d9fabc87db613085e0be054bc..fe95ca9964478ad7f4dfb391cf0d8d2bad1ae20b 100644 --- a/Tracking/Acts/ActsTrackReconstruction/src/OnTrackCalibrator.h +++ b/Tracking/Acts/ActsTrackReconstruction/src/OnTrackCalibrator.h @@ -1,10 +1,13 @@ /* - Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration */ #ifndef ONTRACKCALIBRATOR_H #define ONTRACKCALIBRATOR_H + +#include <GaudiKernel/ToolHandle.h> + #include "MeasurementCalibrator.h" namespace ActsTrk { @@ -39,8 +42,8 @@ public: OnTrackCalibrator(const ActsTrk::IActsToTrkConverterTool &converter_tool, const TrackingSurfaceHelper &surface_helper, - IOnTrackCalibratorTool<traj_t> *pixelTool, - IOnTrackCalibratorTool<traj_t> *stripTool); + const ToolHandle<IOnTrackCalibratorTool<traj_t>> &pixelTool, + const ToolHandle<IOnTrackCalibratorTool<traj_t>> &stripTool); void calibrate(const Acts::GeometryContext& geoctx, const Acts::CalibrationContext& cctx, diff --git a/Tracking/Acts/ActsTrackReconstruction/src/OnTrackCalibrator.icc b/Tracking/Acts/ActsTrackReconstruction/src/OnTrackCalibrator.icc index 8357bbcb791d1634e6306ac6e2c59d3cd8312f78..91be5e703b3e315a12e468d3aaa4e147ced4faaf 100644 --- a/Tracking/Acts/ActsTrackReconstruction/src/OnTrackCalibrator.icc +++ b/Tracking/Acts/ActsTrackReconstruction/src/OnTrackCalibrator.icc @@ -12,25 +12,26 @@ OnTrackCalibrator<traj_t> OnTrackCalibrator<traj_t>::NoCalibration( const ActsTrk::IActsToTrkConverterTool &converter_tool, const TrackingSurfaceHelper &surface_helper) { - return OnTrackCalibrator(converter_tool, surface_helper, nullptr, nullptr); + ToolHandle<IOnTrackCalibratorTool<traj_t>> null(nullptr); + return OnTrackCalibrator(converter_tool, surface_helper, null, null); } template <typename traj_t> OnTrackCalibrator<traj_t>::OnTrackCalibrator( const ActsTrk::IActsToTrkConverterTool &converter_tool, const TrackingSurfaceHelper &surface_helper, - IOnTrackCalibratorTool<traj_t> *pixelTool, - IOnTrackCalibratorTool<traj_t> *stripTool) + const ToolHandle<IOnTrackCalibratorTool<traj_t>>& pixelTool, + const ToolHandle<IOnTrackCalibratorTool<traj_t>>& stripTool) : MeasurementCalibratorBase(converter_tool), m_surfaceHelper(&surface_helper) { - if (pixelTool != nullptr) { + if (pixelTool.isEnabled()) { pixelTool->connect(*this); } else { pixel_calibrator.template connect<&OnTrackCalibrator<traj_t>::passthrough<2, xAOD::PixelCluster>>(this); } - if (stripTool != nullptr) { + if (stripTool.isEnabled()) { stripTool->connect(*this); } else { strip_calibrator.template connect<&OnTrackCalibrator<traj_t>::passthrough<1, xAOD::StripCluster>>(this); diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx index b666278ce4a64a2a9129003a270e0f08c294b92b..d910b43a9dc53ae57aedc23a57e508deb06e9bf1 100644 --- a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx +++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx @@ -5,6 +5,7 @@ #include "src/TrackFindingData.h" // Athena +#include "AsgTools/ToolStore.h" #include "TrkParameters/TrackParameters.h" #include "TrkTrackSummary/TrackSummary.h" #include "InDetPrepRawData/PixelClusterCollection.h" @@ -37,7 +38,7 @@ #include "ActsInterop/Logger.h" #include "ActsInterop/TableUtils.h" -#include "MeasurementCalibrator.h" +#include "OnTrackCalibrator.h" // Other #include <sstream> #include <functional> @@ -124,6 +125,8 @@ namespace ActsTrk ATH_CHECK(m_ATLASConverterTool.retrieve()); ATH_CHECK(m_trackStatePrinter.retrieve(EnableTool{not m_trackStatePrinter.empty()})); ATH_CHECK(m_fitterTool.retrieve()); + ATH_CHECK(m_pixelCalibTool.retrieve(EnableTool{not m_pixelCalibTool.empty()})); + ATH_CHECK(m_stripCalibTool.retrieve(EnableTool{not m_stripCalibTool.empty()})); m_logger = makeActsAthenaLogger(this, "Acts"); @@ -488,8 +491,14 @@ namespace ActsTrk ActsTrk::MutableTrackContainer tracksContainerTemp; - OnTrackCalibrator calibrator = OnTrackCalibrator<ActsTrk::MutableTrackStateBackend> - ::NoCalibration(*m_ATLASConverterTool, tracking_surface_helper); + // Measurement calibration + // N.B. OnTrackCalibrator expects disabled tool handles when no calibration is requested. + // Therefore, passing them without checking if they are enabled is safe. + OnTrackCalibrator calibrator = OnTrackCalibrator<ActsTrk::MutableTrackStateBackend>( + *m_ATLASConverterTool, + tracking_surface_helper, + m_pixelCalibTool, + m_stripCalibTool); options.extensions.calibrator.connect<&OnTrackCalibrator<ActsTrk::MutableTrackStateBackend>::calibrate>(&calibrator); diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h index 111f2c648b3a647a8d99aba4426a84fd5b324e17..de7fba0ee620ece10ff774f311203cdcd260f4af 100644 --- a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h +++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h @@ -23,6 +23,7 @@ #include "ActsEventCnv/IActsToTrkConverterTool.h" #include "ActsGeometry/ATLASSourceLink.h" #include "ActsToolInterfaces/IFitterTool.h" +#include "ActsToolInterfaces/IOnTrackCalibratorTool.h" // Athena #include "AthenaMonitoringKernel/GenericMonitoringTool.h" @@ -46,8 +47,6 @@ #include "StoreGate/WriteHandleKey.h" #include "ActsEvent/TrackContainerHandlesHelper.h" -#include "OnTrackCalibrator.h" - class TrackingSurfaceHelper; namespace { @@ -63,6 +62,7 @@ namespace ActsTrk class TrackFindingAlg : public AthReentrantAlgorithm { public: + TrackFindingAlg(const std::string &name, ISvcLocator *pSvcLocator); virtual ~TrackFindingAlg(); @@ -79,6 +79,10 @@ namespace ActsTrk ToolHandle<ActsTrk::IActsToTrkConverterTool> m_ATLASConverterTool{this, "ATLASConverterTool", ""}; ToolHandle<ActsTrk::ITrackStatePrinter> m_trackStatePrinter{this, "TrackStatePrinter", "", "optional track state printer"}; ToolHandle<ActsTrk::IFitterTool> m_fitterTool{this, "FitterTool", "", "Fitter Tool for Seeds"}; + ToolHandle<ActsTrk::IOnTrackCalibratorTool<ActsTrk::MutableTrackStateBackend>> m_pixelCalibTool{ + this, "PixelCalibrator", "", "Opt. pixel measurement calibrator"}; + ToolHandle<ActsTrk::IOnTrackCalibratorTool<ActsTrk::MutableTrackStateBackend>> m_stripCalibTool{ + this, "StripCalibrator", "", "Opt. strip measurement calibrator"}; // Handle Keys // Seed collections. These 2 vectors must match element for element. diff --git a/Tracking/Acts/ActsTrackReconstruction/src/components/ActsTrackReconstruction_entries.cxx b/Tracking/Acts/ActsTrackReconstruction/src/components/ActsTrackReconstruction_entries.cxx index 30627d39e988f0f165da26b03a4b002966e3f5a6..a1312a782bc43d7e3e04ac3ab026010d9d78b258 100644 --- a/Tracking/Acts/ActsTrackReconstruction/src/components/ActsTrackReconstruction_entries.cxx +++ b/Tracking/Acts/ActsTrackReconstruction/src/components/ActsTrackReconstruction_entries.cxx @@ -7,6 +7,7 @@ #include "src/ReFitterAlg.h" #include "src/TrackToTrackParticleCnvAlg.h" // Tools +#include "src/ITkAnalogueClusteringTool.h" #include "src/TrackStatePrinter.h" #include "src/KalmanFitter.h" #include "src/GaussianSumFitter.h" @@ -23,6 +24,7 @@ DECLARE_COMPONENT( ActsTrk::ProtoTrackReportingAlg ) DECLARE_COMPONENT( ActsTrk::TrackToTrackParticleCnvAlg ) // Tools +DECLARE_COMPONENT( ActsTrk::ITkAnalogueClusteringTool ) DECLARE_COMPONENT( ActsTrk::TrackStatePrinter ) DECLARE_COMPONENT( ActsTrk::KalmanFitter ) DECLARE_COMPONENT( ActsTrk::GaussianSumFitter )