15#include <fairlogger/Logger.h>
16#include <TGeoManager.h>
17#include <TGeoMatrix.h>
18#include <TGeoOverlap.h>
19#include <TGeoPhysicalNode.h>
27 double x,
double y,
double z,
28 double psi,
double theta,
double phi,
30 : mSymName(symname), mAlignableID(algID)
47 : mSymName(symname), mAlignableID(algID)
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));
55 throw std::runtime_error(fmt::format(
"Alignment creation for {} failed: geomManager is absent", symname));
75 dest.SetRotation(rot);
84 if (
m.IsTranslation()) {
85 const double* tr =
m.GetTranslation();
100 if (
m.IsRotation()) {
101 const double* rot =
m.GetRotationMatrix();
102 double psi, theta, phi;
108 mPsi = mTheta = mPhi = 0.;
121 if (std::abs(rot[0]) < 1e-7 || std::abs(rot[8]) < 1e-7) {
122 LOG(error) <<
"Failed to extract roll-pitch-yall angles!";
125 psi = std::atan2(-rot[5], rot[8]);
126 theta = std::asin(rot[2]);
127 phi = std::atan2(-rot[1], rot[0]);
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);
144 rot[0] = costhe * cosphi;
145 rot[1] = -costhe * sinphi;
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;
164 double tr[3] = {
x,
y,
z};
165 m.SetTranslation(tr);
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!";
184 TGeoHMatrix gprime, gprimeinv;
185 TGeoPhysicalNode* pn =
nullptr;
186 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
188 pn = pne->GetPhysicalNode();
190 if (pn->IsAligned()) {
191 LOG(warning) <<
"Volume " << symname <<
" has been misaligned already!";
193 gprime = *pn->GetMatrix();
195 gprime = pne->GetGlobalOrig();
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!";
204 gprime = *gGeoManager->GetCurrentMatrix();
208 m1.SetTranslation(
m.GetTranslation());
209 m1.SetRotation(
m.GetRotationMatrix());
211 gprimeinv = gprime.Inverse();
212 m1.Multiply(&gprimeinv);
213 m1.MultiplyLeft(&gprime);
226 if (!gGeoManager || !gGeoManager->IsClosed()) {
227 LOG(error) <<
"Can't get the local alignment object parameters! gGeoManager doesn't exist or it is still open!";
232 TGeoPhysicalNode* node;
233 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
235 if (!pne->GetPhysicalNode()) {
236 node = gGeoManager->MakeAlignablePN(pne);
238 node = pne->GetPhysicalNode();
241 LOG(warning) <<
"The symbolic volume name " << symname
242 <<
" does not correspond to a physical entry. Using it as volume path!";
243 node = (TGeoPhysicalNode*)gGeoManager->MakePhysicalNode(symname);
247 LOG(error) <<
"Volume name or path " << symname <<
" is not valid!";
251 TGeoHMatrix gprime, gprimeinv;
252 gprime = *node->GetMatrix();
253 gprimeinv = gprime.Inverse();
255 m.MultiplyLeft(&gprimeinv);
267 if (!gGeoManager || !gGeoManager->IsClosed()) {
268 LOG(error) <<
"Can't apply the alignment object! gGeoManager doesn't exist or it is still open!";
272 if (gGeoManager->IsLocked()) {
273 LOG(error) <<
"Can't apply the alignment object! Geometry is locked!";
279 TGeoPhysicalNode* node;
280 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
282 path = pne->GetTitle();
283 node = gGeoManager->MakeAlignablePN(pne);
285 LOG(
debug) <<
"The symbolic volume name " << symname
286 <<
" does not correspond to a physical entry. Using it as a volume path!";
288 if (!gGeoManager->CheckPath(
path)) {
289 LOG(error) <<
"Volume path " <<
path <<
" is not valid";
292 if (gGeoManager->GetListOfPhysicalNodes()->FindObject(
path)) {
293 LOG(error) <<
"Volume path " <<
path <<
" has been misaligned already!";
296 node = (TGeoPhysicalNode*)gGeoManager->MakePhysicalNode(
path);
300 LOG(error) <<
"Volume path " <<
path <<
" is not valid";
306 TGeoHMatrix gprime = *node->GetMatrix();
308 gprime.MultiplyLeft(&align);
309 TGeoHMatrix* ginv =
new TGeoHMatrix;
310 TGeoHMatrix*
g = node->GetMatrix(node->GetLevel() - 1);
311 *ginv =
g->Inverse();
314 LOG(
debug) <<
"Aligning volume " << symname;
329 LOG(error) <<
"gGeoManager doesn't exist or it is still open: unable to return meaningful level value.";
334 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
336 path = pne->GetTitle();
341 TString pathStr =
path;
342 int lev = pathStr.CountChar(
'/');
343 return (pathStr[0] !=
'/') ? ++lev : lev;
392 double tra[3] = {
x,
y,
z};
393 dest.SetTranslation(tra);
406 double tr[3] = {
x,
y,
z};
407 m.SetTranslation(tr);
421 mtr.SetTranslation(
m.GetTranslation());
448 rotm.SetRotation(
m.GetRotationMatrix());
456 if (std::abs(mX) < zero) {
459 if (std::abs(mY) < zero) {
463 if (std::abs(mZ) < zero) {
467 if (std::abs(mPsi) < zero) {
471 if (std::abs(mTheta) < zero) {
475 if (std::abs(mPhi) < zero) {
Definition of the base alignment parameters class.
bool createLocalMatrix(TGeoHMatrix &m) const
extract local delta matrix
int getAlignableID() const
return alignable entry ID
void setGlobalParams(double x, double y, double z, double psi, double theta, double phi)
================ methods for direct setting of delta params
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
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
double getPhi() const
iparamater's getters
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
bool applyToGeometry() const
apply object to geoemetry
bool matrixToAngles(const double *rot, double &psi, double &theta, double &phi) const
GLsizei const GLchar *const * path
GLdouble GLdouble GLdouble z
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"