20#include <nlohmann/json.hpp>
30 return std::all_of(
sensors.begin(),
sensors.end(), [](
const auto& sensor) { return sensor.empty(); });
36 if (jsonPath.empty()) {
40 std::ifstream
f(jsonPath);
42 LOGP(fatal,
"Cannot open misalignment JSON file: {}", jsonPath);
45 using json = nlohmann::json;
46 const auto data = json::parse(
f);
47 for (
const auto& item :
data) {
48 const int id = item[
"id"].get<
int>();
53 auto& sensor = model[
id];
54 if (item.contains(
"matrix")) {
55 auto v = item[
"matrix"].get<std::vector<std::vector<double>>>();
57 LOGP(fatal,
"Legendre matrix for sensor {} is empty in {}",
id, jsonPath);
59 TMatrixD
m(
v.size(),
v.back().size());
60 for (std::size_t
r{0};
r <
v.size(); ++
r) {
61 for (std::size_t
c{0};
c <
v[
r].size(); ++
c) {
66 sensor.hasLegendre =
true;
68 if (item.contains(
"inextensional")) {
69 const auto& inex = item[
"inextensional"];
70 sensor.hasInextensional =
true;
71 if (inex.contains(
"modes")) {
72 for (
const auto& [
key,
val] : inex[
"modes"].items()) {
73 sensor.inextensional.modes[std::stoi(
key)] =
val.get<std::array<double, 4>>();
76 if (inex.contains(
"alpha")) {
77 sensor.inextensional.alpha = inex[
"alpha"].get<
double>();
79 if (inex.contains(
"beta")) {
80 sensor.inextensional.beta = inex[
"beta"].get<
double>();
95 const double gloX = frame.
x * std::cos(frame.
alpha);
96 const double gloY = frame.
x * std::sin(frame.
alpha);
97 const double gloZ = frame.
z;
104 const double newGloY = gloY + (shift.
dy * std::cos(frame.
alpha));
105 const double newGloX = gloX - (shift.
dy * std::sin(frame.
alpha));
106 const double newGloZ = gloZ + shift.
dz;
108 shift.
accepted = std::abs(uNew) <= 1. && std::abs(vNew) <= 1.;
120 const double phi = std::atan2(
r * std::sin(frame.
alpha),
r * std::cos(frame.
alpha));
121 const double z = frame.
z;
124 double uz = 0., uphi = 0., ur = 0.;
125 for (
const auto& [
n,
coeffs] : inex.modes) {
127 const double sn = std::sin(
n * phi);
128 const double cn = std::cos(
n * phi);
129 const int n2 =
n *
n;
131 const double fn = (a_n * cn) + (b_n * sn);
132 const double fpn = (-
n * a_n * sn) + (
n * b_n * cn);
133 const double fppn = (-n2 * a_n * cn) - (n2 * b_n * sn);
134 const double gn = (c_n * cn) + (d_n * sn);
135 const double gpn = (-
n * c_n * sn) + (
n * d_n * cn);
138 uphi += -(
z /
r) * fpn + gn;
139 ur += (
z /
r) * fppn - gpn;
142 uz += inex.alpha * phi;
143 uphi += -(
z /
r) * inex.alpha + inex.beta * phi;
146 shift.
dy = -uphi + (slopes.
dydx * ur);
147 shift.
dz = -uz + (slopes.
dzdx * ur);
Class for time synchronization of RawReader instances.
GLint GLenum GLint const GLfloat * coeffs
GLdouble GLdouble GLdouble z
MisalignmentShift evaluateInextensionalShift(const SensorMisalignment &sensor, const MisalignmentFrame &frame, const TrackSlopes &slopes)
MisalignmentModel loadMisalignmentModel(const std::string &jsonPath)
MisalignmentShift evaluateLegendreShift(const SensorMisalignment &sensor, const MisalignmentFrame &frame, const TrackSlopes &slopes)
std::pair< double, double > computeUV(double gloX, double gloY, double gloZ, int sensorID, double radius)
constexpr std::array< double, nLayers > radii
bool empty() const noexcept
static constexpr std::size_t NSensors
std::array< SensorMisalignment, NSensors > sensors
o2::math_utils::Legendre2DPolynominal legendre
InextensionalMisalignment inextensional