Project
Loading...
Searching...
No Matches
Transformations.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 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
15#include <TGeoManager.h>
16#include <TGeoMatrix.h>
17#include <array>
18#include <fmt/format.h>
19#include <rapidjson/document.h>
20#include <rapidjson/istreamwrapper.h>
21#include <string>
22#include <vector>
23
24namespace o2::mch::geo
25{
26
28
30{
31 return [&geo](int detElemId) -> o2::math_utils::Transform3D {
32 if (std::find(begin(allDeIds), end(allDeIds), detElemId) == end(allDeIds)) {
33 throw std::runtime_error("Wrong detection element Id");
34 }
35
36 std::string volPathName = geo.GetTopVolume()->GetName();
37
38 int nCh = detElemId / 100;
39
40 if (nCh <= 4 && geo.GetVolume("YOUT1")) {
41 volPathName += "/YOUT1_1/";
42 } else if ((nCh == 5 || nCh == 6) && geo.GetVolume("DDIP")) {
43 volPathName += "/DDIP_1/";
44 } else if (nCh >= 7 && geo.GetVolume("YOUT2")) {
45 volPathName += "/YOUT2_1/";
46 } else {
47 volPathName += "/";
48 }
49
50 volPathName += volumePathName(detElemId);
51
52 TGeoNavigator* navig = gGeoManager->GetCurrentNavigator();
53
54 if (!navig->cd(volPathName.c_str())) {
55 throw std::runtime_error("could not get to volPathName=" + volPathName);
56 }
57
58 return o2::math_utils::Transform3D{*(navig->GetCurrentMatrix())};
59 };
60}
61
63{
64 rapidjson::IStreamWrapper isw(in);
65
66 rapidjson::Document d;
67 d.ParseStream(isw);
68
69 rapidjson::Value& alignables = d["alignables"];
70 assert(alignables.IsArray());
71
72 std::map<int, std::tuple<double, double, double>> angles;
73 std::map<int, std::tuple<double, double, double>> translations;
74
75 // loop over json document and extract Tait-Bryan angles (yaw,pitch,roll)
76 // as well as translation vector (tx,ty,tz)
77 // for each detection element
78
79 constexpr double deg2rad = 3.14159265358979323846 / 180.0;
80
81 for (auto& al : alignables.GetArray()) {
82 auto itr = al.FindMember("deid");
83 if (itr != al.MemberEnd()) {
84 int deid = itr->value.GetInt();
85 auto t = al["transform"].GetObject();
86 angles[deid] = {
87 deg2rad * t["yaw"].GetDouble(),
88 deg2rad * t["pitch"].GetDouble(),
89 deg2rad * t["roll"].GetDouble()};
90 translations[deid] = {
91 t["tx"].GetDouble(),
92 t["ty"].GetDouble(),
93 t["tz"].GetDouble()};
94 }
95 }
96
97 return [angles, translations](int detElemId) -> o2::math_utils::Transform3D {
98 if (std::find(begin(allDeIds), end(allDeIds), detElemId) == end(allDeIds)) {
99 throw std::runtime_error("Wrong detection element Id");
100 }
101 auto [yaw, pitch, roll] = angles.at(detElemId);
102 auto [tx, ty, tz] = translations.at(detElemId);
103 double tr[3] = {tx, ty, tz};
104 // get the angles, convert them to a matrix and build a Transform3D
105 // from it
106 auto rot = o2::mch::geo::angles2matrix(yaw, pitch, roll);
107 TGeoHMatrix m;
108 m.SetRotation(&rot[0]);
109 m.SetTranslation(tr);
111 };
112} // namespace o2::mch::geo
113
114std::array<double, 9> angles2matrix(double yaw, double pitch, double roll)
115{
116 std::array<double, 9> rot;
117
118 double sinpsi = std::sin(roll);
119 double cospsi = std::cos(roll);
120 double sinthe = std::sin(pitch);
121 double costhe = std::cos(pitch);
122 double sinphi = std::sin(yaw);
123 double cosphi = std::cos(yaw);
124 rot[0] = costhe * cosphi;
125 rot[1] = -costhe * sinphi;
126 rot[2] = sinthe;
127 rot[3] = sinpsi * sinthe * cosphi + cospsi * sinphi;
128 rot[4] = -sinpsi * sinthe * sinphi + cospsi * cosphi;
129 rot[5] = -costhe * sinpsi;
130 rot[6] = -cospsi * sinthe * cosphi + sinpsi * sinphi;
131 rot[7] = cospsi * sinthe * sinphi + sinpsi * cosphi;
132 rot[8] = costhe * cospsi;
133 return rot;
134}
135
136std::tuple<double, double, double> matrix2angles(gsl::span<double> rot)
137{
138 double roll = std::atan2(-rot[5], rot[8]);
139 double pitch = std::asin(rot[2]);
140 double yaw = std::atan2(-rot[1], rot[0]);
141 return std::make_tuple(yaw,
142 pitch,
143 roll);
144}
145
146} // namespace o2::mch::geo
const GLfloat * m
Definition glcorearb.h:4066
GLuint GLuint end
Definition glcorearb.h:469
std::array< int, 156 > deIdsForAllMCH
get the local-to-global transformation for a given detection element
Definition Geometry.h:25
TransformationCreator transformationFromJSON(std::istream &in)
std::tuple< double, double, double > matrix2angles(gsl::span< double > rot)
std::array< int, 156 > allDeIds
std::array< double, 9 > angles2matrix(double yaw, double pitch, double roll)
std::string volumePathName(int deId)
TransformationCreator transformationFromTGeoManager(const TGeoManager &geo)
std::function< o2::math_utils::Transform3D(int detElemId)> TransformationCreator
constexpr double deg2rad