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 assert( !trackState.hasCalibrated());
80 trackState.allocateCalibrated(2);
81 trackState.template calibrated<2>() = pos.template cast<double>();
82 trackState.template calibratedCovariance<2>() = cov.template cast<double>();
83 if (testTrackStateFlag(Acts::TrackStateFlag::IsSplitHit, flags)) {
84 trackState.typeFlags().setIsSplitHit();
85 }
86}
87
88template <typename derived_t, typename traj_t>
89std::tuple<typename PixelClusterCalibratorCommon<traj_t>::Pos,
90 typename PixelClusterCalibratorCommon<traj_t>::Cov,
91 unsigned int>
92PixelClusterCalibratorBase<derived_t, traj_t>::calibrate(const Acts::GeometryContext& gctx,
93 const Acts::CalibrationContext& cctx,
94 const Acts::Surface& surface,
95 const xAOD::PixelCluster& cluster,
96 const Acts::BoundTrackParameters& bound_parameters) const
97{
98 const EventContext& ctx = *cctx.get<const EventContext*>();
99 const InDetDD::SiDetectorElement &detElement = this->getDetectorElement(surface);
100 Acts::Vector3 direction = Acts::makeDirectionFromPhiTheta(bound_parameters.parameters()[Acts::eBoundPhi],
101 bound_parameters.parameters()[Acts::eBoundTheta]);
102 return this->derived().calibrate(ctx, gctx, cctx, cluster, detElement, this->tanAnglesOfIncidence(ctx,
103 gctx,
104 surface,
105 detElement,
106 direction));
107}
108
109template <typename derived_t, typename traj_t>
110void
111PixelClusterCalibratorBase<derived_t, traj_t>
112 ::connectOnTrackCalibrator(PixelClusterCalibratorBase<derived_t, traj_t>::OnTrackCalibrator& calibrator) const
113{
114 using CalibFuncPtr_t =
115 void(PixelClusterCalibratorBase<derived_t, traj_t>:: *)(const Acts::GeometryContext&,
116 const Acts::CalibrationContext&,
117 const xAOD::PixelCluster&,
118 TrackStateProxy&) const;
119
120 calibrator. template connect<static_cast<CalibFuncPtr_t>(&PixelClusterCalibratorBase<derived_t, traj_t>::calibrate)>(this);
121}
122
123
124template <typename derived_t, typename traj_t>
125void
126PixelClusterCalibratorBase<derived_t,traj_t>
127 ::connectCalibrator(typename PixelClusterCalibratorBase<derived_t,traj_t>::Calibrator &calibrator) const {
128 using CalibFuncPtr_t =
129 std::tuple<typename PixelClusterCalibratorCommon<traj_t>::Pos,
130 typename PixelClusterCalibratorCommon<traj_t>::Cov,
131 unsigned int>
132 (PixelClusterCalibratorBase<derived_t, traj_t>:: *)(const Acts::GeometryContext&,
133 const Acts::CalibrationContext&,
134 const Acts::Surface&,
135 const xAOD::PixelCluster&,
136 const Acts::BoundTrackParameters&) const;
137
138 calibrator.template connect<static_cast<CalibFuncPtr_t>(&PixelClusterCalibratorBase<derived_t, traj_t>::calibrate)>(this);
139}
140
141template <typename traj_t>
142StatusCode PixelClusterCalibrationToolBase<traj_t>::initialize()
143{
144 ATH_CHECK(m_lorentzAngleTool.retrieve());
145 ATH_CHECK(AthAlgTool::detStore()->retrieve(m_pixelID, "PixelID"));
146
147 return StatusCode::SUCCESS;
148}
149
150template <typename traj_t>
151bool PixelClusterCalibrationToolBase<traj_t>::calibrateAfterMeasurementSelection() const
152{ return m_postCalibration.value(); }
153
154} // namespace ActsTrk