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 bool convertLocalToGlobal)
31 : mSymName(symname), mIsGlobal(global || convertLocalToGlobal), mAlignableID(algID)
40 if (!global && convertLocalToGlobal) {
47 : mSymName(symname), mIsGlobal(global || convertLocalToGlobal), 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));
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));
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);
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!";
236 TGeoPhysicalNode* node;
237 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
239 if (!pne->GetPhysicalNode()) {
240 node = gGeoManager->MakeAlignablePN(pne);
242 node = pne->GetPhysicalNode();
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);
251 LOG(error) <<
"Volume name or path " << symname <<
" is not valid!";
254 TGeoHMatrix gprime, gprimeinv;
255 gprime = *node->GetMatrix();
256 gprimeinv = gprime.Inverse();
258 m.MultiplyLeft(&gprimeinv);
270 if (!gGeoManager || !gGeoManager->IsClosed()) {
271 LOG(error) <<
"Can't apply the alignment object! gGeoManager doesn't exist or it is still open!";
275 if (gGeoManager->IsLocked()) {
276 LOG(error) <<
"Can't apply the alignment object! Geometry is locked!";
282 TGeoPhysicalNode* node;
283 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
285 path = pne->GetTitle();
286 node = gGeoManager->MakeAlignablePN(pne);
288 LOG(
debug) <<
"The symbolic volume name " << symname
289 <<
" does not correspond to a physical entry. Using it as a volume path!";
291 if (!gGeoManager->CheckPath(
path)) {
292 LOG(error) <<
"Volume path " <<
path <<
" is not valid";
295 if (gGeoManager->GetListOfPhysicalNodes()->FindObject(
path)) {
296 LOG(error) <<
"Volume path " <<
path <<
" has been misaligned already!";
299 node = (TGeoPhysicalNode*)gGeoManager->MakePhysicalNode(
path);
303 LOG(error) <<
"Volume path " <<
path <<
" is not valid";
310 align->Multiply(node->GetMatrix());
311 TGeoHMatrix*
g = node->GetMatrix(node->GetLevel() - 1);
312 align->MultiplyLeft(node->GetMatrix(node->GetLevel() - 1)->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;
400 double tra[3] = {
x,
y,
z};
401 dest.SetTranslation(tra);
414 double tr[3] = {
x,
y,
z};
415 m.SetTranslation(tr);
429 mtr.SetTranslation(
m.GetTranslation());
456 rotm.SetRotation(
m.GetRotationMatrix());
464 if (std::abs(mX) < zero) {
467 if (std::abs(mY) < zero) {
471 if (std::abs(mZ) < zero) {
475 if (std::abs(mPsi) < zero) {
479 if (std::abs(mTheta) < zero) {
483 if (std::abs(mPhi) < zero) {
Definition of the base alignment parameters class.
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
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
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"