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