ATLAS Offline Software
Loading...
Searching...
No Matches
PixelClusterCalibrationToolBase.icc
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4#include <limits>
5#include "ActsGeometry/ActsDetectorElement.h"
6#include <PixelReadoutGeometry/PixelModuleDesign.h>
7#include "InDetReadoutGeometry/SiDetectorElement.h"
8#include "InDetMeasurementUtilities/Helpers.h"
9#include "Acts/Surfaces/PlaneSurface.hpp"
10
11#include "TrackStateFlagHelper.h"
12
13#include <stdexcept>
14
15namespace ActsTrk::detail {
16
17template <typename traj_t>
18const InDetDD::SiDetectorElement&
19PixelClusterCalibratorCommon<traj_t>::getDetectorElement(const Acts::Surface &surface) const {
20 const auto* detElem = getActsDetectorElement(surface);
21 const InDetDD::SiDetectorElement *
22 siDetElement = detElem ? dynamic_cast<const InDetDD::SiDetectorElement *>(detElem->upstreamDetectorElement())
23 : nullptr;
24 if (!siDetElement) {
25 throw std::runtime_error("SiDetectorElement is NULL");
26 }
27 return *siDetElement;
28}
29
30template <typename traj_t>
31std::pair<float, float>
32PixelClusterCalibratorCommon<traj_t>::tanAnglesOfIncidence(const EventContext &ctx,
33 const Acts::GeometryContext& gctx,
34 const Acts::Surface &surface,
35 const InDetDD::SiDetectorElement& element,
36 const Acts::Vector3& direction) const
37{
38 // to ensure that referenceFrame can be called with dummy direction and position
39 assert(dynamic_cast<const Acts::PlaneSurface *>(&surface) != nullptr);
40 static const Acts::Vector3 dummy=Acts::Vector3::Zero();
41 Acts::Vector3 projection = surface.referenceFrame(gctx, dummy,dummy).transpose() * direction;
42#ifndef NDEBUG
43 float projPhi = direction.dot(element.phiAxis());
44 float projEta = direction.dot(element.etaAxis());
45 float projNorm = direction.dot(element.normal());
46 assert( std::abs(projection[0] - projPhi) < std::abs(projPhi) * std::numeric_limits<float>::epsilon() *2.);
47 assert( std::abs(projection[1] - projEta) < std::abs(projEta) * std::numeric_limits<float>::epsilon() *2.);
48 assert( std::abs(projection[2] - projNorm) < std::abs(projNorm) * std::numeric_limits<float>::epsilon() *2.);
49#endif
50
51 double inv_proj_norm = 1./projection[2];
52 double tan_phi = projection[0]*inv_proj_norm;
53 double tan_theta = projection[1]*inv_proj_norm;
54
55 // Subtract the Lorentz angle effect
56 double angleShift = m_baseOptions.m_lorentzAngleTool->getTanLorentzAngle(element.identifyHash(), ctx);
57 tan_phi -= element.design().readoutSide() * angleShift;
58
59 return std::make_pair(static_cast<float>(tan_phi), static_cast<float>(tan_theta));
60}
61
62template <typename derived_t, typename traj_t>
63void
64PixelClusterCalibratorBase<derived_t, traj_t>::calibrate(
65 const Acts::GeometryContext& gctx,
66 const Acts::CalibrationContext& cctx,
67 const xAOD::PixelCluster& cluster,
68 typename PixelClusterCalibratorBase<derived_t, traj_t>::TrackStateProxy& trackState) const
69{
70 const EventContext& ctx = *cctx.get<const EventContext*>();
71 const InDetDD::SiDetectorElement &detElement = this->getDetectorElement(trackState.referenceSurface());
72 Acts::Vector3 direction = Acts::makeDirectionFromPhiTheta(trackState.parameters()[Acts::eBoundPhi],
73 trackState.parameters()[Acts::eBoundTheta]);
74 auto [pos,cov,flags] = derived().calibrate(ctx, gctx, cctx, cluster, detElement, this->tanAnglesOfIncidence(ctx,
75 gctx,
76 trackState.referenceSurface(),
77 detElement,
78 direction),
79 Acts::Vector2(trackState.parameters()[Acts::eBoundLoc0],
80 trackState.parameters()[Acts::eBoundLoc1]));
81 assert( !trackState.hasCalibrated());
82 trackState.allocateCalibrated(2);
83 trackState.template calibrated<2>() = pos.template cast<double>();
84 trackState.template calibratedCovariance<2>() = cov.template cast<double>();
85 if (testTrackStateFlag(Acts::TrackStateFlag::IsSplitHit, flags)) {
86 trackState.typeFlags().setIsSplitHit();
87 }
88}
89
90template <typename derived_t, typename traj_t>
91std::tuple<typename PixelClusterCalibratorCommon<traj_t>::Pos,
92 typename PixelClusterCalibratorCommon<traj_t>::Cov,
93 unsigned int>
94PixelClusterCalibratorBase<derived_t, traj_t>::calibrate(const Acts::GeometryContext& gctx,
95 const Acts::CalibrationContext& cctx,
96 const Acts::Surface& surface,
97 const xAOD::PixelCluster& cluster,
98 const Acts::BoundTrackParameters& bound_parameters) const
99{
100 const EventContext& ctx = *cctx.get<const EventContext*>();
101 const InDetDD::SiDetectorElement &detElement = this->getDetectorElement(surface);
102 Acts::Vector3 direction = Acts::makeDirectionFromPhiTheta(bound_parameters.parameters()[Acts::eBoundPhi],
103 bound_parameters.parameters()[Acts::eBoundTheta]);
104 return this->derived().calibrate(ctx, gctx, cctx, cluster, detElement, this->tanAnglesOfIncidence(ctx,
105 gctx,
106 surface,
107 detElement,
108 direction),
109 Acts::Vector2(bound_parameters.parameters()[Acts::eBoundLoc0],
110 bound_parameters.parameters()[Acts::eBoundLoc1]));
111}
112
113template <typename derived_t, typename traj_t>
114void
115PixelClusterCalibratorBase<derived_t, traj_t>
116 ::connectOnTrackCalibrator(PixelClusterCalibratorBase<derived_t, traj_t>::OnTrackCalibrator& calibrator) const
117{
118 using CalibFuncPtr_t =
119 void(PixelClusterCalibratorBase<derived_t, traj_t>:: *)(const Acts::GeometryContext&,
120 const Acts::CalibrationContext&,
121 const xAOD::PixelCluster&,
122 TrackStateProxy&) const;
123
124 calibrator. template connect<static_cast<CalibFuncPtr_t>(&PixelClusterCalibratorBase<derived_t, traj_t>::calibrate)>(this);
125}
126
127
128template <typename derived_t, typename traj_t>
129void
130PixelClusterCalibratorBase<derived_t,traj_t>
131 ::connectCalibrator(typename PixelClusterCalibratorBase<derived_t,traj_t>::Calibrator &calibrator) const {
132 using CalibFuncPtr_t =
133 std::tuple<typename PixelClusterCalibratorCommon<traj_t>::Pos,
134 typename PixelClusterCalibratorCommon<traj_t>::Cov,
135 unsigned int>
136 (PixelClusterCalibratorBase<derived_t, traj_t>:: *)(const Acts::GeometryContext&,
137 const Acts::CalibrationContext&,
138 const Acts::Surface&,
139 const xAOD::PixelCluster&,
140 const Acts::BoundTrackParameters&) const;
141
142 calibrator.template connect<static_cast<CalibFuncPtr_t>(&PixelClusterCalibratorBase<derived_t, traj_t>::calibrate)>(this);
143}
144
145template <typename traj_t>
146StatusCode PixelClusterCalibrationToolBase<traj_t>::initialize()
147{
148 ATH_CHECK(m_lorentzAngleTool.retrieve());
149 ATH_CHECK(AthAlgTool::detStore()->retrieve(m_pixelID, "PixelID"));
150
151 return StatusCode::SUCCESS;
152}
153
154template <typename traj_t>
155bool PixelClusterCalibrationToolBase<traj_t>::calibrateAfterMeasurementSelection() const
156{ return m_postCalibration.value(); }
157
158} // namespace ActsTrk