Project
Loading...
Searching...
No Matches
AlignmentDOF.cxx
Go to the documentation of this file.
1// Copyright 2019-2026 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
13
14#include <cmath>
15#include <stdexcept>
16
18#include "ITS3Base/SpecsV2.h"
19
20namespace
21{
22
23void validateDerivativeOutput(const DOFSet& dofSet, Eigen::Ref<Eigen::MatrixXd> out)
24{
25 if (out.rows() != 3 || out.cols() != dofSet.nDOFs()) {
26 throw std::invalid_argument(std::format("Derivative buffer shape {}x{} does not match expected 3x{}",
27 out.rows(), out.cols(), dofSet.nDOFs()));
28 }
29 out.setZero();
30}
31
32} // namespace
33
34void RigidBodyDOFSet::fillDerivatives(const DerivativeContext& ctx, Eigen::Ref<Eigen::MatrixXd> out) const
35{
36 validateDerivativeOutput(*this, out);
37
38 const double csp = 1. / std::sqrt(1. + (ctx.tgl * ctx.tgl));
39 const double uP = ctx.snp * csp;
40 const double vP = ctx.tgl * csp;
41
42 out(0, TX) = uP;
43 out(0, TY) = -1.;
44 out(0, RX) = ctx.trkZ;
45 out(0, RY) = ctx.trkZ * uP;
46 out(0, RZ) = -ctx.trkY * uP;
47
48 out(1, TX) = vP;
49 out(1, TZ) = -1.;
50 out(1, RX) = -ctx.trkY;
51 out(1, RY) = ctx.trkZ * vP;
52 out(1, RZ) = -ctx.trkY * vP;
53}
54
55void LegendreDOFSet::fillDerivatives(const DerivativeContext& ctx, Eigen::Ref<Eigen::MatrixXd> out) const
56{
57 validateDerivativeOutput(*this, out);
58 if (ctx.sensorID < 0 || ctx.layerID < 0) {
59 throw std::invalid_argument("LegendreDOFSet requires an ITS3 measurement context");
60 }
61
62 const double gloX = ctx.measX * std::cos(ctx.measAlpha);
63 const double gloY = ctx.measX * std::sin(ctx.measAlpha);
64 const auto [u, v] = o2::its3::align::computeUV(gloX, gloY, ctx.measZ, ctx.sensorID, o2::its3::constants::radii[ctx.layerID]);
65 const auto pu = o2::its3::align::legendrePols(mOrder, u);
66 const auto pv = o2::its3::align::legendrePols(mOrder, v);
67
68 int idx = 0;
69 for (int i = 0; i <= mOrder; ++i) {
70 for (int j = 0; j <= i; ++j) {
71 const double basis = pu[j] * pv[i - j];
72 out(0, idx) = ctx.dydx * basis;
73 out(1, idx) = ctx.dzdx * basis;
74 ++idx;
75 }
76 }
77}
78
79void InextensionalDOFSet::fillDerivatives(const DerivativeContext& ctx, Eigen::Ref<Eigen::MatrixXd> out) const
80{
81 validateDerivativeOutput(*this, out);
82 if (ctx.layerID < 0) {
83 throw std::invalid_argument("InextensionalDOFSet requires an ITS3 measurement context");
84 }
85
86 const double r = o2::its3::constants::radii[ctx.layerID];
87 const double phi = std::atan2(r * std::sin(ctx.measAlpha), r * std::cos(ctx.measAlpha));
88 const double z = ctx.measZ;
89
90 for (int n = 2; n <= mMaxOrder; ++n) {
91 const double sn = std::sin(n * phi);
92 const double cn = std::cos(n * phi);
93 const double n2 = static_cast<double>(n * n);
94 const int off = modeOffset(n);
95
96 out(0, off + 0) = -(z / r) * (n * sn + ctx.dydx * n2 * cn);
97 out(1, off + 0) = -cn - ctx.dzdx * (z / r) * n2 * cn;
98
99 out(0, off + 1) = (z / r) * (n * cn - ctx.dydx * n2 * sn);
100 out(1, off + 1) = -sn * (1. + ctx.dzdx * (z / r) * n2);
101
102 out(0, off + 2) = -cn + ctx.dydx * n * sn;
103 out(1, off + 2) = ctx.dzdx * n * sn;
104
105 out(0, off + 3) = -sn - ctx.dydx * n * cn;
106 out(1, off + 3) = -ctx.dzdx * n * cn;
107 }
108
109 out(0, alphaIdx()) = z / r;
110 out(1, alphaIdx()) = -phi;
111
112 out(0, betaIdx()) = -phi - ctx.dydx;
113 out(1, betaIdx()) = -ctx.dzdx;
114}
int32_t i
uint32_t j
Definition RawData.h:0
int nDOFs() const
static int modeOffset(int n)
void fillDerivatives(const DerivativeContext &ctx, Eigen::Ref< Eigen::MatrixXd > out) const override
void fillDerivatives(const DerivativeContext &ctx, Eigen::Ref< Eigen::MatrixXd > out) const override
void fillDerivatives(const DerivativeContext &ctx, Eigen::Ref< Eigen::MatrixXd > out) const override
GLdouble n
Definition glcorearb.h:1982
const GLdouble * v
Definition glcorearb.h:832
GLboolean r
Definition glcorearb.h:1233
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
std::vector< double > legendrePols(int order, double x)
std::pair< double, double > computeUV(double gloX, double gloY, double gloZ, int sensorID, double radius)
constexpr std::array< double, nLayers > radii
Definition SpecsV2.h:134