Project
Loading...
Searching...
No Matches
AlignParam.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
14
15#include <fairlogger/Logger.h>
16#include <TGeoManager.h>
17#include <TGeoMatrix.h>
18#include <TGeoOverlap.h>
19#include <TGeoPhysicalNode.h>
20
22
23using namespace o2::detectors;
24
25//___________________________________________________
26AlignParam::AlignParam(const char* symname, int algID, // volume symbolic name and its alignable ID
27 double x, double y, double z, // delta translation
28 double psi, double theta, double phi, // delta rotation
29 bool global, // global (preferable) or local delta definition
30 bool convertLocalToGlobal) // if local is provided, convert it to global
31 : mSymName(symname), mIsGlobal(global || convertLocalToGlobal), mAlignableID(algID)
32{
38
39 setParams(x, y, z, psi, theta, phi);
40 if (!global && convertLocalToGlobal) {
41 setLocalParams(x, y, z, psi, theta, phi);
42 }
43}
44
45//___________________________________________________
46AlignParam::AlignParam(const char* symname, int algID, TGeoMatrix& m, bool global, bool convertLocalToGlobal)
47 : mSymName(symname), mIsGlobal(global || convertLocalToGlobal), mAlignableID(algID)
48{
50 if (!setRotation(m)) {
51 const double* rot = m.GetRotationMatrix();
52 throw std::runtime_error(fmt::format("Failed to extract roll-pitch-yall angles from [[{},{},{}], [{},{},{}], [{},{},{}] for {}", rot[0], rot[1], rot[2], rot[3], rot[4], rot[5], rot[6], rot[7], rot[8], symname));
53 }
54 if (!global && convertLocalToGlobal && !setLocalParams(mX, mY, mZ, mPsi, mTheta, mPhi)) {
55 throw std::runtime_error(fmt::format("Alignment creation for {} failed: geomManager is absent", symname));
56 }
57}
58
59//___________________________________________________
60TGeoHMatrix AlignParam::createMatrix() const
61{
63 TGeoHMatrix mat;
64 setMatrixTranslation(mX, mY, mZ, mat);
65 setMatrixRotation(mPsi, mTheta, mPhi, mat);
66 return mat;
67}
68
69//___________________________________________________
70void AlignParam::setMatrixRotation(double psi, double theta, double phi, TGeoHMatrix& dest) const
71{
73 double rot[9] = {};
74 anglesToMatrix(psi, theta, phi, rot);
75 dest.SetRotation(rot);
76}
77
78//_____________________________________________________________________________
79void AlignParam::setTranslation(const TGeoMatrix& m)
80{
83
84 if (m.IsTranslation()) {
85 const double* tr = m.GetTranslation();
86 mX = tr[0];
87 mY = tr[1];
88 mZ = tr[2];
89 } else {
90 mX = mY = mZ = 0.;
91 }
92}
93
94//_____________________________________________________________________________
95bool AlignParam::setRotation(const TGeoMatrix& m)
96{
99
100 if (m.IsRotation()) {
101 const double* rot = m.GetRotationMatrix();
102 double psi, theta, phi;
103 if (!matrixToAngles(rot, psi, theta, phi)) {
104 return false;
105 }
106 setRotation(psi, theta, phi);
107 } else {
108 mPsi = mTheta = mPhi = 0.;
109 }
110 return true;
111}
112
113//_____________________________________________________________________________
114bool AlignParam::matrixToAngles(const double* rot, double& psi, double& theta, double& phi) const
115{
120 //
121 if (std::abs(rot[0]) < 1e-7 || std::abs(rot[8]) < 1e-7) {
122 LOG(error) << "Failed to extract roll-pitch-yall angles!";
123 return false;
124 }
125 psi = std::atan2(-rot[5], rot[8]);
126 theta = std::asin(rot[2]);
127 phi = std::atan2(-rot[1], rot[0]);
128 return true;
129}
130
131//_____________________________________________________________________________
132void AlignParam::anglesToMatrix(double psi, double theta, double phi, double* rot) const
133{
134 // Calculates the rotation matrix using the
135 // Euler angles in "x y z" notation
136 //
137 double sinpsi = std::sin(psi);
138 double cospsi = std::cos(psi);
139 double sinthe = std::sin(theta);
140 double costhe = std::cos(theta);
141 double sinphi = std::sin(phi);
142 double cosphi = std::cos(phi);
143
144 rot[0] = costhe * cosphi;
145 rot[1] = -costhe * sinphi;
146 rot[2] = sinthe;
147 rot[3] = sinpsi * sinthe * cosphi + cospsi * sinphi;
148 rot[4] = -sinpsi * sinthe * sinphi + cospsi * cosphi;
149 rot[5] = -costhe * sinpsi;
150 rot[6] = -cospsi * sinthe * cosphi + sinpsi * sinphi;
151 rot[7] = cospsi * sinthe * sinphi + sinpsi * cosphi;
152 rot[8] = costhe * cospsi;
153}
154
155//_____________________________________________________________________________
156bool AlignParam::setLocalParams(double x, double y, double z, double psi, double theta, double phi)
157{
162
163 TGeoHMatrix m;
164 double tr[3] = {x, y, z};
165 m.SetTranslation(tr);
166 setMatrixRotation(psi, theta, phi, m);
167 return setLocalParams(m);
168}
169
170//_____________________________________________________________________________
171bool AlignParam::setLocalParams(const TGeoMatrix& m)
172{
173 // Set the global delta transformation by passing the TGeo matrix
174 // for the local delta transformation.
175 // In case that the TGeo was not initialized or not closed,
176 // returns false and the object parameters are not set.
177 //
178 if (!gGeoManager || !gGeoManager->IsClosed()) {
179 LOG(error) << "Can't set the local alignment object parameters! gGeoManager doesn't exist or it is still open!";
180 return false;
181 }
182
183 const char* symname = getSymName().c_str();
184 TGeoHMatrix gprime, gprimeinv;
185 TGeoPhysicalNode* pn = nullptr;
186 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
187 if (pne) {
188 pn = pne->GetPhysicalNode();
189 if (pn) {
190 if (pn->IsAligned()) {
191 LOG(warning) << "Volume " << symname << " has been misaligned already!";
192 }
193 gprime = *pn->GetMatrix();
194 } else {
195 gprime = pne->GetGlobalOrig();
196 }
197 } else {
198 LOG(warning) << "The symbolic volume name " << symname
199 << " does not correspond to a physical entry. Using it as volume path!";
200 if (!gGeoManager->cd(symname)) {
201 LOG(error) << "Volume name or path " << symname << " is not valid!";
202 return false;
203 }
204 gprime = *gGeoManager->GetCurrentMatrix();
205 }
206
207 TGeoHMatrix m1; // the TGeoHMatrix copy of the local delta "m"
208 m1.SetTranslation(m.GetTranslation());
209 m1.SetRotation(m.GetRotationMatrix());
210
211 gprimeinv = gprime.Inverse();
212 m1.Multiply(&gprimeinv);
213 m1.MultiplyLeft(&gprime);
214
215 setGlobalParams(m1);
216 return true;
217}
218
219//_____________________________________________________________________________
220bool AlignParam::createLocalMatrix(TGeoHMatrix& m) const
221{
222 // Get the matrix for the local delta transformation.
223 // In case that the TGeo was not initialized or not closed,
224 // returns false and the object parameters are not set.
225 //
226 m = createMatrix();
227 if (!mIsGlobal) {
228 return true;
229 }
230 if (!gGeoManager || !gGeoManager->IsClosed()) {
231 LOG(error) << "Can't get the local alignment object parameters! gGeoManager doesn't exist or it is still open!";
232 return false;
233 }
234
235 const char* symname = getSymName().c_str();
236 TGeoPhysicalNode* node;
237 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
238 if (pne) {
239 if (!pne->GetPhysicalNode()) {
240 node = gGeoManager->MakeAlignablePN(pne);
241 } else {
242 node = pne->GetPhysicalNode();
243 }
244 } else {
245 LOG(warning) << "The symbolic volume name " << symname
246 << " does not correspond to a physical entry. Using it as volume path!";
247 node = (TGeoPhysicalNode*)gGeoManager->MakePhysicalNode(symname);
248 }
249
250 if (!node) {
251 LOG(error) << "Volume name or path " << symname << " is not valid!";
252 return false;
253 }
254 TGeoHMatrix gprime, gprimeinv;
255 gprime = *node->GetMatrix();
256 gprimeinv = gprime.Inverse();
257 m.Multiply(&gprime);
258 m.MultiplyLeft(&gprimeinv);
259
260 return true;
261}
262
263//_____________________________________________________________________________
265{
269 //
270 if (!gGeoManager || !gGeoManager->IsClosed()) {
271 LOG(error) << "Can't apply the alignment object! gGeoManager doesn't exist or it is still open!";
272 return false;
273 }
274
275 if (gGeoManager->IsLocked()) {
276 LOG(error) << "Can't apply the alignment object! Geometry is locked!";
277 return false;
278 }
279
280 const char* symname = getSymName().c_str();
281 const char* path;
282 TGeoPhysicalNode* node;
283 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
284 if (pne) {
285 path = pne->GetTitle();
286 node = gGeoManager->MakeAlignablePN(pne);
287 } else {
288 LOG(debug) << "The symbolic volume name " << symname
289 << " does not correspond to a physical entry. Using it as a volume path!";
290 path = symname;
291 if (!gGeoManager->CheckPath(path)) {
292 LOG(error) << "Volume path " << path << " is not valid";
293 return false;
294 }
295 if (gGeoManager->GetListOfPhysicalNodes()->FindObject(path)) {
296 LOG(error) << "Volume path " << path << " has been misaligned already!";
297 return false;
298 }
299 node = (TGeoPhysicalNode*)gGeoManager->MakePhysicalNode(path);
300 }
301
302 if (!node) {
303 LOG(error) << "Volume path " << path << " is not valid";
304 return false;
305 }
306
307 // double threshold = 0.001;
308 TGeoHMatrix* align = new TGeoHMatrix(createMatrix());
309 if (mIsGlobal) {
310 align->Multiply(node->GetMatrix());
311 TGeoHMatrix* g = node->GetMatrix(node->GetLevel() - 1);
312 align->MultiplyLeft(node->GetMatrix(node->GetLevel() - 1)->Inverse());
313 }
314 LOG(debug) << "Aligning volume " << symname;
315
316 node->Align(align);
317
318 return true;
319}
320
321//_____________________________________________________________________________
323{
327 //
328 if (!gGeoManager) {
329 LOG(error) << "gGeoManager doesn't exist or it is still open: unable to return meaningful level value.";
330 return -1;
331 }
332 const char* symname = getSymName().c_str();
333 const char* path;
334 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
335 if (pne) {
336 path = pne->GetTitle();
337 } else {
338 path = symname;
339 }
340
341 TString pathStr = path;
342 int lev = pathStr.CountChar('/');
343 return (pathStr[0] != '/') ? ++lev : lev;
344}
345
346//_____________________________________________________________________________
348{
349 // print parameters
350 printf("%s : %6d | X: %+e Y: %+e Z: %+e | pitch: %+e roll: %+e yaw: %e\n", getSymName().c_str(), getAlignableID(), getX(),
351 getY(), getZ(), getPsi(), getTheta(), getPhi());
352}
353
354//_____________________________________________________________________________
355void AlignParam::setGlobalParams(double x, double y, double z, double psi, double theta, double phi)
356{
358 setTranslation(x, y, z);
359 setRotation(psi, theta, phi);
360}
361
362//_____________________________________________________________________________
363void AlignParam::setParams(double x, double y, double z, double psi, double theta, double phi)
364{
366 setTranslation(x, y, z);
367 setRotation(psi, theta, phi);
368}
369
370//_____________________________________________________________________________
371void AlignParam::setRotation(double psi, double theta, double phi)
372{
374 mPsi = psi;
375 mTheta = theta;
376 mPhi = phi;
377}
378
379//_____________________________________________________________________________
380void AlignParam::setTranslation(double x, double y, double z)
381{
383 mX = x;
384 mY = y;
385 mZ = z;
386}
387
388//_____________________________________________________________________________
389void AlignParam::setGlobalParams(const TGeoMatrix& m)
390{
393 setRotation(m);
394}
395
396//___________________________________________________
397void AlignParam::setMatrixTranslation(double x, double y, double z, TGeoHMatrix& dest) const
398{
400 double tra[3] = {x, y, z};
401 dest.SetTranslation(tra);
402}
403
404//_____________________________________________________________________________
405bool AlignParam::setLocalTranslation(double x, double y, double z)
406{
412
413 TGeoHMatrix m;
414 double tr[3] = {x, y, z};
415 m.SetTranslation(tr);
416
417 return setLocalParams(m);
418}
419
420//_____________________________________________________________________________
421bool AlignParam::setLocalTranslation(const TGeoMatrix& m)
422{
427
428 TGeoHMatrix mtr;
429 mtr.SetTranslation(m.GetTranslation());
430 return setLocalParams(mtr);
431}
432
433//_____________________________________________________________________________
434bool AlignParam::setLocalRotation(double psi, double theta, double phi)
435{
441
442 TGeoHMatrix m;
443 setMatrixRotation(psi, theta, phi, m);
444 return setLocalParams(m);
445}
446
447//_____________________________________________________________________________
448bool AlignParam::setLocalRotation(const TGeoMatrix& m)
449{
454
455 TGeoHMatrix rotm;
456 rotm.SetRotation(m.GetRotationMatrix());
457 return setLocalParams(rotm);
458}
459
460//_____________________________________________________________________________
461int AlignParam::rectify(double zero)
462{
463 int nonZero = 6;
464 if (std::abs(mX) < zero) {
465 mX = 0.;
466 }
467 if (std::abs(mY) < zero) {
468 mY = 0.;
469 nonZero--;
470 }
471 if (std::abs(mZ) < zero) {
472 mZ = 0.;
473 nonZero--;
474 }
475 if (std::abs(mPsi) < zero) {
476 mPsi = 0.;
477 nonZero--;
478 }
479 if (std::abs(mTheta) < zero) {
480 mTheta = 0.;
481 nonZero--;
482 }
483 if (std::abs(mPhi) < zero) {
484 mPhi = 0.;
485 nonZero--;
486 }
487 return nonZero;
488}
Definition of the base alignment parameters class.
std::ostringstream debug
void setParams(double x, double y, double z, double psi, double theta, double phi)
================ methods for direct setting of delta params
bool createLocalMatrix(TGeoHMatrix &m) const
extract local delta matrix
int getAlignableID() const
return alignable entry ID
Definition AlignParam.h:70
void setGlobalParams(double x, double y, double z, double psi, double theta, double phi)
set parameters of global delta
int rectify(double zero=1e-13)
bool setLocalRotation(double psi, double theta, double phi)
set global delta rotation from the local delta rotation
void anglesToMatrix(double psi, double theta, double phi, double *rot) const
TGeoHMatrix createMatrix() const
extract global delta matrix
void setMatrixRotation(double psi, double theta, double phi, TGeoHMatrix &dest) const
void setRotation(double psi, double theta, double phi)
set global delta rotations angles in radian
double getTheta() const
Definition AlignParam.h:52
bool setLocalTranslation(double x, double y, double z)
set global delta translation from the local delta translation
const std::string & getSymName() const
return symbolic name of the volume
Definition AlignParam.h:48
double getPhi() const
iparamater's getters
Definition AlignParam.h:50
void setMatrixTranslation(double x, double y, double z, TGeoHMatrix &dest) const
bool setLocalParams(double x, double y, double z, double psi, double theta, double phi)
================ methods for setting global delta params from local delta
void setTranslation(double x, double y, double z)
set global delta displacements in cm
double getPsi() const
Definition AlignParam.h:51
bool applyToGeometry() const
apply object to geoemetry
bool matrixToAngles(const double *rot, double &psi, double &theta, double &phi) const
GLint GLenum GLint x
Definition glcorearb.h:403
const GLfloat * m
Definition glcorearb.h:4066
GLint y
Definition glcorearb.h:270
GLboolean GLboolean g
Definition glcorearb.h:1233
GLsizei const GLchar *const * path
Definition glcorearb.h:3591
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"