]>
Commit | Line | Data |
---|---|---|
c18195b9 | 1 | /************************************************************************** |
2 | * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * | |
3 | * * | |
4 | * Author: The ALICE Off-line Project. * | |
5 | * Contributors are mentioned in the code where appropriate. * | |
6 | * * | |
7 | * Permission to use, copy, modify and distribute this software and its * | |
8 | * documentation strictly for non-commercial purposes is hereby granted * | |
9 | * without fee, provided that the above copyright notice appears in all * | |
10 | * copies and that both the copyright notice and this permission notice * | |
11 | * appear in the supporting documentation. The authors make no claims * | |
12 | * about the suitability of this software for any purpose. It is * | |
13 | * provided "as is" without express or implied warranty. * | |
14 | **************************************************************************/ | |
15 | ||
090026bf | 16 | /* $Id$ */ |
17 | ||
c18195b9 | 18 | //----------------------------------------------------------------- |
7e154d52 | 19 | // Implementation of the alignment object class, holding the alignment |
20 | // constants for a single volume, through the abstract class AliAlignObj. | |
21 | // From it two derived concrete representation of alignment object class | |
22 | // (AliAlignObjAngles, AliAlignObjMatrix) are derived in separate files. | |
c18195b9 | 23 | //----------------------------------------------------------------- |
a1e17193 | 24 | |
25 | #include <TClass.h> | |
995ad051 | 26 | #include <TGeoManager.h> |
27 | #include <TGeoPhysicalNode.h> | |
090026bf | 28 | #include <TMath.h> |
276cb1b1 | 29 | #include "TObjString.h" |
995ad051 | 30 | |
c18195b9 | 31 | #include "AliAlignObj.h" |
03b18860 | 32 | #include "AliTrackPointArray.h" |
33 | #include "AliLog.h" | |
c5304981 | 34 | #include "AliAlignObjAngles.h" |
98937d93 | 35 | |
c18195b9 | 36 | ClassImp(AliAlignObj) |
37 | ||
38 | //_____________________________________________________________________________ | |
39 | AliAlignObj::AliAlignObj(): | |
fe12e09c | 40 | fVolPath(), |
c18195b9 | 41 | fVolUID(0) |
42 | { | |
03b18860 | 43 | // default constructor |
25be1e5c | 44 | // InitSymNames(); |
c18195b9 | 45 | } |
46 | ||
47 | //_____________________________________________________________________________ | |
b760c02e | 48 | AliAlignObj::AliAlignObj(const char* symname, UShort_t voluid) : |
fe12e09c | 49 | TObject(), |
b760c02e | 50 | fVolPath(symname), |
fe12e09c | 51 | fVolUID(voluid) |
d9cc42ed | 52 | { |
53 | // standard constructor | |
54 | // | |
d9cc42ed | 55 | } |
56 | ||
d9cc42ed | 57 | //_____________________________________________________________________________ |
c18195b9 | 58 | AliAlignObj::AliAlignObj(const AliAlignObj& theAlignObj) : |
fe12e09c | 59 | TObject(theAlignObj), |
b760c02e | 60 | fVolPath(theAlignObj.GetSymName()), |
fe12e09c | 61 | fVolUID(theAlignObj.GetVolUID()) |
c18195b9 | 62 | { |
63 | //copy constructor | |
c18195b9 | 64 | } |
65 | ||
66 | //_____________________________________________________________________________ | |
67 | AliAlignObj &AliAlignObj::operator =(const AliAlignObj& theAlignObj) | |
68 | { | |
69 | // assignment operator | |
70 | if(this==&theAlignObj) return *this; | |
b760c02e | 71 | fVolPath = theAlignObj.GetSymName(); |
c18195b9 | 72 | fVolUID = theAlignObj.GetVolUID(); |
73 | return *this; | |
74 | } | |
75 | ||
38b3a170 | 76 | //_____________________________________________________________________________ |
77 | AliAlignObj &AliAlignObj::operator*=(const AliAlignObj& theAlignObj) | |
78 | { | |
79 | // multiplication operator | |
80 | // The operator can be used to 'combine' | |
81 | // two alignment objects | |
82 | TGeoHMatrix m1; | |
83 | GetMatrix(m1); | |
84 | TGeoHMatrix m2; | |
85 | theAlignObj.GetMatrix(m2); | |
86 | m1.MultiplyLeft(&m2); | |
87 | SetMatrix(m1); | |
88 | return *this; | |
89 | } | |
90 | ||
c18195b9 | 91 | //_____________________________________________________________________________ |
92 | AliAlignObj::~AliAlignObj() | |
93 | { | |
94 | // dummy destructor | |
95 | } | |
96 | ||
befe2c08 | 97 | //_____________________________________________________________________________ |
25be1e5c | 98 | void AliAlignObj::SetVolUID(AliGeomManager::ELayerID detId, Int_t modId) |
befe2c08 | 99 | { |
100 | // From detector name and module number (according to detector numbering) | |
101 | // build fVolUID, unique numerical identity of that volume inside ALICE | |
102 | // fVolUID is 16 bits, first 5 reserved for detID (32 possible values), | |
103 | // remaining 11 for module ID inside det (2048 possible values). | |
104 | // | |
25be1e5c | 105 | fVolUID = AliGeomManager::LayerToVolUID(detId,modId); |
befe2c08 | 106 | } |
107 | ||
108 | //_____________________________________________________________________________ | |
25be1e5c | 109 | void AliAlignObj::GetVolUID(AliGeomManager::ELayerID &layerId, Int_t &modId) const |
befe2c08 | 110 | { |
7e154d52 | 111 | // From the fVolUID, unique numerical identity of that volume inside ALICE, |
112 | // (voluid is 16 bits, first 5 reserved for layerID (32 possible values), | |
113 | // remaining 11 for module ID inside det (2048 possible values)), sets | |
114 | // the argument layerId to the identity of the layer to which that volume | |
115 | // belongs and sets the argument modId to the identity of that volume | |
116 | // internally to the layer. | |
befe2c08 | 117 | // |
25be1e5c | 118 | layerId = AliGeomManager::VolUIDToLayer(fVolUID,modId); |
befe2c08 | 119 | } |
120 | ||
b760c02e | 121 | //_____________________________________________________________________________ |
122 | Bool_t AliAlignObj::GetPars(Double_t tr[], Double_t angles[]) const | |
123 | { | |
124 | GetTranslation(tr); | |
125 | return GetAngles(angles); | |
126 | } | |
127 | ||
4b94e753 | 128 | //_____________________________________________________________________________ |
129 | Int_t AliAlignObj::GetLevel() const | |
130 | { | |
85fbf070 | 131 | // Return the geometry level of the alignable volume to which |
132 | // the alignment object is associated; this is the number of | |
133 | // slashes in the corresponding volume path | |
134 | // | |
135 | if(!gGeoManager){ | |
136 | AliWarning("gGeoManager doesn't exist or it is still opened: unable to return meaningful level value."); | |
137 | return (-1); | |
138 | } | |
139 | const char* symname = GetSymName(); | |
140 | const char* path; | |
141 | TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname); | |
142 | if(pne){ | |
143 | path = pne->GetTitle(); | |
144 | }else{ | |
145 | path = symname; | |
146 | } | |
147 | ||
148 | TString path_str = path; | |
149 | if(path_str[0]!='/') path_str.Prepend('/'); | |
150 | return path_str.CountChar('/'); | |
4b94e753 | 151 | } |
152 | ||
153 | //_____________________________________________________________________________ | |
154 | Int_t AliAlignObj::Compare(const TObject *obj) const | |
155 | { | |
156 | // Compare the levels of two | |
157 | // alignment objects | |
158 | // Used in the sorting during | |
159 | // the application of alignment | |
160 | // objects to the geometry | |
7e154d52 | 161 | // |
4b94e753 | 162 | Int_t level = GetLevel(); |
163 | Int_t level2 = ((AliAlignObj *)obj)->GetLevel(); | |
164 | if (level == level2) | |
165 | return 0; | |
166 | else | |
167 | return ((level > level2) ? 1 : -1); | |
168 | } | |
169 | ||
c18195b9 | 170 | //_____________________________________________________________________________ |
171 | void AliAlignObj::AnglesToMatrix(const Double_t *angles, Double_t *rot) const | |
172 | { | |
fdf65bb5 | 173 | // Calculates the rotation matrix using the |
174 | // Euler angles in "x y z" notation | |
7e154d52 | 175 | // |
c18195b9 | 176 | Double_t degrad = TMath::DegToRad(); |
177 | Double_t sinpsi = TMath::Sin(degrad*angles[0]); | |
178 | Double_t cospsi = TMath::Cos(degrad*angles[0]); | |
179 | Double_t sinthe = TMath::Sin(degrad*angles[1]); | |
180 | Double_t costhe = TMath::Cos(degrad*angles[1]); | |
181 | Double_t sinphi = TMath::Sin(degrad*angles[2]); | |
182 | Double_t cosphi = TMath::Cos(degrad*angles[2]); | |
183 | ||
184 | rot[0] = costhe*cosphi; | |
185 | rot[1] = -costhe*sinphi; | |
186 | rot[2] = sinthe; | |
187 | rot[3] = sinpsi*sinthe*cosphi + cospsi*sinphi; | |
188 | rot[4] = -sinpsi*sinthe*sinphi + cospsi*cosphi; | |
189 | rot[5] = -costhe*sinpsi; | |
190 | rot[6] = -cospsi*sinthe*cosphi + sinpsi*sinphi; | |
191 | rot[7] = cospsi*sinthe*sinphi + sinpsi*cosphi; | |
192 | rot[8] = costhe*cospsi; | |
193 | } | |
194 | ||
195 | //_____________________________________________________________________________ | |
196 | Bool_t AliAlignObj::MatrixToAngles(const Double_t *rot, Double_t *angles) const | |
197 | { | |
fdf65bb5 | 198 | // Calculates the Euler angles in "x y z" notation |
199 | // using the rotation matrix | |
b760c02e | 200 | // Returns false in case the rotation angles can not be |
201 | // extracted from the matrix | |
7e154d52 | 202 | // |
b760c02e | 203 | if(TMath::Abs(rot[0])<1e-7 || TMath::Abs(rot[8])<1e-7) { |
204 | AliError("Failed to extract roll-pitch-yall angles!"); | |
205 | return kFALSE; | |
206 | } | |
c18195b9 | 207 | Double_t raddeg = TMath::RadToDeg(); |
208 | angles[0]=raddeg*TMath::ATan2(-rot[5],rot[8]); | |
209 | angles[1]=raddeg*TMath::ASin(rot[2]); | |
210 | angles[2]=raddeg*TMath::ATan2(-rot[1],rot[0]); | |
211 | return kTRUE; | |
212 | } | |
213 | ||
03b18860 | 214 | //______________________________________________________________________________ |
215 | void AliAlignObj::Transform(AliTrackPoint &p) const | |
216 | { | |
217 | // The method transforms the space-point coordinates using the | |
218 | // transformation matrix provided by the AliAlignObj | |
219 | // The covariance matrix is not affected since we assume | |
220 | // that the transformations are sufficiently small | |
7e154d52 | 221 | // |
03b18860 | 222 | if (fVolUID != p.GetVolumeID()) |
223 | AliWarning(Form("Alignment object ID is not equal to the space-point ID (%d != %d)",fVolUID,p.GetVolumeID())); | |
224 | ||
225 | TGeoHMatrix m; | |
226 | GetMatrix(m); | |
227 | Double_t *rot = m.GetRotationMatrix(); | |
228 | Double_t *tr = m.GetTranslation(); | |
229 | ||
230 | Float_t xyzin[3],xyzout[3]; | |
231 | p.GetXYZ(xyzin); | |
232 | for (Int_t i = 0; i < 3; i++) | |
233 | xyzout[i] = tr[i]+ | |
234 | xyzin[0]*rot[3*i]+ | |
235 | xyzin[1]*rot[3*i+1]+ | |
236 | xyzin[2]*rot[3*i+2]; | |
237 | p.SetXYZ(xyzout); | |
238 | ||
239 | } | |
240 | ||
79e21da6 | 241 | //_____________________________________________________________________________ |
03b18860 | 242 | void AliAlignObj::Transform(AliTrackPointArray &array) const |
243 | { | |
e1e6896f | 244 | // This method is used to transform all the track points |
245 | // from the input AliTrackPointArray | |
7e154d52 | 246 | // |
03b18860 | 247 | AliTrackPoint p; |
248 | for (Int_t i = 0; i < array.GetNPoints(); i++) { | |
249 | array.GetPoint(p,i); | |
250 | Transform(p); | |
251 | array.AddPoint(i,&p); | |
252 | } | |
253 | } | |
254 | ||
c18195b9 | 255 | //_____________________________________________________________________________ |
256 | void AliAlignObj::Print(Option_t *) const | |
257 | { | |
258 | // Print the contents of the | |
259 | // alignment object in angles and | |
260 | // matrix representations | |
7e154d52 | 261 | // |
c18195b9 | 262 | Double_t tr[3]; |
263 | GetTranslation(tr); | |
264 | Double_t angles[3]; | |
265 | GetAngles(angles); | |
266 | TGeoHMatrix m; | |
267 | GetMatrix(m); | |
268 | const Double_t *rot = m.GetRotationMatrix(); | |
c18195b9 | 269 | |
b760c02e | 270 | printf("Volume=%s\n",GetSymName()); |
c041444f | 271 | if (GetVolUID() != 0) { |
25be1e5c | 272 | AliGeomManager::ELayerID layerId; |
c041444f | 273 | Int_t modId; |
274 | GetVolUID(layerId,modId); | |
25be1e5c | 275 | printf("VolumeID=%d LayerID=%d ( %s ) ModuleID=%d\n", GetVolUID(),layerId,AliGeomManager::LayerName(layerId),modId); |
c041444f | 276 | } |
277 | printf("%12.8f%12.8f%12.8f Tx = %12.8f Psi = %12.8f\n", rot[0], rot[1], rot[2], tr[0], angles[0]); | |
278 | printf("%12.8f%12.8f%12.8f Ty = %12.8f Theta = %12.8f\n", rot[3], rot[4], rot[5], tr[1], angles[1]); | |
279 | printf("%12.8f%12.8f%12.8f Tz = %12.8f Phi = %12.8f\n", rot[6], rot[7], rot[8], tr[2], angles[2]); | |
280 | ||
281 | } | |
282 | ||
b760c02e | 283 | //_____________________________________________________________________________ |
284 | void AliAlignObj::SetPars(Double_t x, Double_t y, Double_t z, | |
285 | Double_t psi, Double_t theta, Double_t phi) | |
286 | { | |
32898fe7 | 287 | // Set the global delta transformation by passing 3 angles (expressed in |
288 | // degrees) and 3 shifts (in centimeters) | |
7e154d52 | 289 | // |
b760c02e | 290 | SetTranslation(x,y,z); |
291 | SetRotation(psi,theta,phi); | |
292 | } | |
293 | ||
1bfe7ffc | 294 | //_____________________________________________________________________________ |
295 | Bool_t AliAlignObj::SetLocalPars(Double_t x, Double_t y, Double_t z, | |
296 | Double_t psi, Double_t theta, Double_t phi) | |
297 | { | |
32898fe7 | 298 | // Set the global delta transformation by passing the parameters |
299 | // for the local delta transformation (3 shifts and 3 angles). | |
7e154d52 | 300 | // In case that the TGeo was not initialized or not closed, |
301 | // returns false and the object parameters are not set. | |
302 | // | |
b760c02e | 303 | TGeoHMatrix m; |
304 | Double_t tr[3] = {x, y, z}; | |
305 | m.SetTranslation(tr); | |
306 | Double_t angles[3] = {psi, theta, phi}; | |
307 | Double_t rot[9]; | |
308 | AnglesToMatrix(angles,rot); | |
309 | m.SetRotation(rot); | |
310 | ||
311 | return SetLocalMatrix(m); | |
312 | ||
313 | } | |
314 | ||
32898fe7 | 315 | //_____________________________________________________________________________ |
316 | Bool_t AliAlignObj::SetLocalTranslation(Double_t x, Double_t y, Double_t z) | |
317 | { | |
318 | // Set the global delta transformation by passing the three shifts giving | |
319 | // the translation in the local reference system of the alignable | |
320 | // volume (known by TGeo geometry). | |
321 | // In case that the TGeo was not initialized or not closed, | |
322 | // returns false and the object parameters are not set. | |
323 | // | |
324 | TGeoHMatrix m; | |
325 | Double_t tr[3] = {x, y, z}; | |
326 | m.SetTranslation(tr); | |
327 | ||
328 | return SetLocalMatrix(m); | |
329 | ||
330 | } | |
331 | ||
332 | //_____________________________________________________________________________ | |
333 | Bool_t AliAlignObj::SetLocalTranslation(const TGeoMatrix& m) | |
334 | { | |
335 | // Set the global delta transformation by passing the matrix of | |
336 | // the local delta transformation and taking its translational part | |
337 | // In case that the TGeo was not initialized or not closed, | |
338 | // returns false and the object parameters are not set. | |
339 | // | |
340 | const Double_t* tr = m.GetTranslation(); | |
341 | TGeoHMatrix mtr; | |
342 | mtr.SetTranslation(tr); | |
343 | ||
344 | return SetLocalMatrix(mtr); | |
345 | ||
346 | } | |
347 | ||
348 | //_____________________________________________________________________________ | |
349 | Bool_t AliAlignObj::SetLocalRotation(Double_t psi, Double_t theta, Double_t phi) | |
350 | { | |
351 | // Set the global delta transformation by passing the three angles giving | |
352 | // the rotation in the local reference system of the alignable | |
353 | // volume (known by TGeo geometry). | |
354 | // In case that the TGeo was not initialized or not closed, | |
355 | // returns false and the object parameters are not set. | |
356 | // | |
357 | TGeoHMatrix m; | |
358 | Double_t angles[3] = {psi, theta, phi}; | |
359 | Double_t rot[9]; | |
360 | AnglesToMatrix(angles,rot); | |
361 | m.SetRotation(rot); | |
362 | ||
363 | return SetLocalMatrix(m); | |
364 | ||
365 | } | |
366 | ||
367 | //_____________________________________________________________________________ | |
368 | Bool_t AliAlignObj::SetLocalRotation(const TGeoMatrix& m) | |
369 | { | |
370 | // Set the global delta transformation by passing the matrix of | |
371 | // the local delta transformation and taking its rotational part | |
372 | // In case that the TGeo was not initialized or not closed, | |
373 | // returns false and the object parameters are not set. | |
374 | // | |
375 | TGeoHMatrix rotm; | |
376 | const Double_t* rot = m.GetRotationMatrix(); | |
377 | rotm.SetRotation(rot); | |
378 | ||
379 | return SetLocalMatrix(rotm); | |
380 | ||
381 | } | |
382 | ||
b760c02e | 383 | //_____________________________________________________________________________ |
384 | Bool_t AliAlignObj::SetLocalMatrix(const TGeoMatrix& m) | |
385 | { | |
32898fe7 | 386 | // Set the global delta transformation by passing the TGeo matrix |
387 | // for the local delta transformation. | |
7e154d52 | 388 | // In case that the TGeo was not initialized or not closed, |
389 | // returns false and the object parameters are not set. | |
390 | // | |
1bfe7ffc | 391 | if (!gGeoManager || !gGeoManager->IsClosed()) { |
392 | AliError("Can't set the alignment object parameters! gGeoManager doesn't exist or it is still opened!"); | |
393 | return kFALSE; | |
394 | } | |
395 | ||
b760c02e | 396 | const char* symname = GetSymName(); |
397 | TGeoPhysicalNode* node; | |
398 | TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname); | |
399 | if(pne){ | |
400 | node = gGeoManager->MakeAlignablePN(pne); | |
401 | }else{ | |
402 | AliWarning(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as volume path!",symname)); | |
403 | node = (TGeoPhysicalNode*) gGeoManager->MakePhysicalNode(symname); | |
404 | } | |
405 | ||
1bfe7ffc | 406 | if (!node) { |
b760c02e | 407 | AliError(Form("Volume name or path %s not valid!",symname)); |
1bfe7ffc | 408 | return kFALSE; |
409 | } | |
410 | if (node->IsAligned()) | |
b760c02e | 411 | AliWarning(Form("Volume %s has been already misaligned!",symname)); |
1bfe7ffc | 412 | |
b760c02e | 413 | TGeoHMatrix m1; |
414 | const Double_t *tr = m.GetTranslation(); | |
415 | m1.SetTranslation(tr); | |
416 | const Double_t* rot = m.GetRotationMatrix(); | |
417 | m1.SetRotation(rot); | |
1bfe7ffc | 418 | |
419 | TGeoHMatrix align,gprime,gprimeinv; | |
420 | gprime = *node->GetMatrix(); | |
421 | gprimeinv = gprime.Inverse(); | |
b760c02e | 422 | m1.Multiply(&gprimeinv); |
423 | m1.MultiplyLeft(&gprime); | |
1bfe7ffc | 424 | |
b760c02e | 425 | return SetMatrix(m1); |
426 | } | |
1bfe7ffc | 427 | |
b760c02e | 428 | //_____________________________________________________________________________ |
429 | Bool_t AliAlignObj::SetMatrix(const TGeoMatrix& m) | |
430 | { | |
32898fe7 | 431 | // Set the global delta transformation by passing the TGeoMatrix |
432 | // for it | |
7e154d52 | 433 | // |
b760c02e | 434 | SetTranslation(m); |
435 | return SetRotation(m); | |
1bfe7ffc | 436 | } |
437 | ||
32898fe7 | 438 | //_____________________________________________________________________________ |
439 | Bool_t AliAlignObj::GetLocalPars(Double_t transl[], Double_t angles[]) const | |
440 | { | |
441 | // Get the translations and angles (in degrees) expressing the | |
442 | // local delta transformation. | |
443 | // In case that the TGeo was not initialized or not closed, | |
444 | // returns false and the object parameters are not set. | |
445 | // | |
446 | if(!GetLocalTranslation(transl)) return kFALSE; | |
447 | return GetLocalAngles(angles); | |
448 | } | |
449 | ||
450 | //_____________________________________________________________________________ | |
451 | Bool_t AliAlignObj::GetLocalTranslation(Double_t* tr) const | |
452 | { | |
453 | // Get the 3 shifts giving the translational part of the local | |
454 | // delta transformation. | |
455 | // In case that the TGeo was not initialized or not closed, | |
456 | // returns false and the object parameters are not set. | |
457 | // | |
458 | TGeoHMatrix ml; | |
459 | if(!GetLocalMatrix(ml)) return kFALSE; | |
460 | const Double_t* transl; | |
461 | transl = ml.GetTranslation(); | |
462 | tr[0]=transl[0]; | |
463 | tr[1]=transl[1]; | |
464 | tr[2]=transl[2]; | |
465 | return kTRUE; | |
466 | } | |
467 | ||
468 | //_____________________________________________________________________________ | |
469 | Bool_t AliAlignObj::GetLocalAngles(Double_t* angles) const | |
470 | { | |
471 | // Get the 3 angles giving the rotational part of the local | |
472 | // delta transformation. | |
473 | // In case that the TGeo was not initialized or not closed, | |
474 | // returns false and the object parameters are not set. | |
475 | // | |
476 | TGeoHMatrix ml; | |
477 | if(!GetLocalMatrix(ml)) return kFALSE; | |
478 | const Double_t *rot = ml.GetRotationMatrix(); | |
479 | return MatrixToAngles(rot,angles); | |
480 | } | |
481 | ||
482 | //_____________________________________________________________________________ | |
483 | Bool_t AliAlignObj::GetLocalMatrix(TGeoHMatrix& m) const | |
484 | { | |
485 | // Get the matrix for the local delta transformation. | |
486 | // In case that the TGeo was not initialized or not closed, | |
487 | // returns false and the object parameters are not set. | |
488 | // | |
489 | if (!gGeoManager || !gGeoManager->IsClosed()) { | |
490 | AliError("Can't set the alignment object parameters! gGeoManager doesn't exist or it is still opened!"); | |
491 | return kFALSE; | |
492 | } | |
493 | ||
494 | const char* symname = GetSymName(); | |
495 | TGeoPhysicalNode* node; | |
496 | TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname); | |
497 | if(pne){ | |
498 | node = gGeoManager->MakeAlignablePN(pne); | |
499 | }else{ | |
500 | AliWarning(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as volume path!",symname)); | |
501 | node = (TGeoPhysicalNode*) gGeoManager->MakePhysicalNode(symname); | |
502 | } | |
503 | ||
504 | if (!node) { | |
505 | AliError(Form("Volume name or path %s not valid!",symname)); | |
506 | return kFALSE; | |
507 | } | |
508 | if (node->IsAligned()) | |
509 | AliWarning(Form("Volume %s has been already misaligned!",symname)); | |
510 | ||
511 | GetMatrix(m); | |
512 | TGeoHMatrix gprime,gprimeinv; | |
513 | gprime = *node->GetMatrix(); | |
514 | gprimeinv = gprime.Inverse(); | |
515 | m.Multiply(&gprime); | |
516 | m.MultiplyLeft(&gprimeinv); | |
517 | ||
518 | return kTRUE; | |
519 | } | |
520 | ||
995ad051 | 521 | //_____________________________________________________________________________ |
522 | Bool_t AliAlignObj::ApplyToGeometry() | |
523 | { | |
7e154d52 | 524 | // Apply the current alignment object to the TGeo geometry |
525 | // This method returns FALSE if the symname of the object was not | |
526 | // valid neither to get a TGeoPEntry nor as a volume path | |
527 | // | |
995ad051 | 528 | if (!gGeoManager || !gGeoManager->IsClosed()) { |
529 | AliError("Can't apply the alignment object! gGeoManager doesn't exist or it is still opened!"); | |
530 | return kFALSE; | |
531 | } | |
532 | ||
b760c02e | 533 | const char* symname = GetSymName(); |
534 | const char* path; | |
535 | TGeoPhysicalNode* node; | |
536 | TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname); | |
537 | if(pne){ | |
b760c02e | 538 | path = pne->GetTitle(); |
7e154d52 | 539 | node = gGeoManager->MakeAlignablePN(pne); |
b760c02e | 540 | }else{ |
5bd470e1 | 541 | AliDebug(1,Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname)); |
b760c02e | 542 | path=symname; |
7e154d52 | 543 | if (!gGeoManager->CheckPath(path)) { |
5bd470e1 | 544 | AliDebug(1,Form("Volume path %s not valid!",path)); |
b760c02e | 545 | return kFALSE; |
546 | } | |
7e154d52 | 547 | if (gGeoManager->GetListOfPhysicalNodes()->FindObject(path)) { |
548 | AliError(Form("Volume %s has already been misaligned!",path)); | |
b760c02e | 549 | return kFALSE; |
550 | } | |
551 | node = (TGeoPhysicalNode*) gGeoManager->MakePhysicalNode(path); | |
995ad051 | 552 | } |
48cac49d | 553 | |
48cac49d | 554 | if (!node) { |
b760c02e | 555 | AliError(Form("Volume path %s not valid!",path)); |
995ad051 | 556 | return kFALSE; |
557 | } | |
558 | ||
559 | TGeoHMatrix align,gprime; | |
560 | gprime = *node->GetMatrix(); | |
561 | GetMatrix(align); | |
562 | gprime.MultiplyLeft(&align); | |
563 | TGeoHMatrix *ginv = new TGeoHMatrix; | |
564 | TGeoHMatrix *g = node->GetMatrix(node->GetLevel()-1); | |
565 | *ginv = g->Inverse(); | |
566 | *ginv *= gprime; | |
25be1e5c | 567 | AliGeomManager::ELayerID layerId; // unique identity for layer in the alobj |
b760c02e | 568 | Int_t modId; // unique identity for volume inside layer in the alobj |
995ad051 | 569 | GetVolUID(layerId, modId); |
b760c02e | 570 | AliDebug(2,Form("Aligning volume %s of detector layer %d with local ID %d",symname,layerId,modId)); |
995ad051 | 571 | node->Align(ginv); |
572 | ||
573 | return kTRUE; | |
574 | } | |
575 |