]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliAlignObj.cxx
corrected bug in GetValue(UInt_t timeSec) (Haavard)
[u/mrichter/AliRoot.git] / STEER / AliAlignObj.cxx
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
16 /* $Id$ */
17
18 //-----------------------------------------------------------------
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.
23 //-----------------------------------------------------------------
24
25 #include <TClass.h>
26 #include <TGeoManager.h>
27 #include <TGeoPhysicalNode.h>
28 #include <TMath.h>
29 #include "TObjString.h"
30
31 #include "AliAlignObj.h"
32 #include "AliTrackPointArray.h"
33 #include "AliLog.h"
34 #include "AliAlignObjAngles.h"
35  
36 ClassImp(AliAlignObj)
37
38 //_____________________________________________________________________________
39 AliAlignObj::AliAlignObj():
40   fVolPath(),
41   fVolUID(0)
42 {
43   // default constructor
44   // InitSymNames();
45 }
46
47 //_____________________________________________________________________________
48 AliAlignObj::AliAlignObj(const char* symname, UShort_t voluid) :
49   TObject(),
50   fVolPath(symname),
51   fVolUID(voluid)
52 {
53   // standard constructor
54   //
55 }
56
57 //_____________________________________________________________________________
58 AliAlignObj::AliAlignObj(const AliAlignObj& theAlignObj) :
59   TObject(theAlignObj),
60   fVolPath(theAlignObj.GetSymName()),
61   fVolUID(theAlignObj.GetVolUID())
62 {
63   //copy constructor
64 }
65
66 //_____________________________________________________________________________
67 AliAlignObj &AliAlignObj::operator =(const AliAlignObj& theAlignObj)
68 {
69   // assignment operator
70   if(this==&theAlignObj) return *this;
71   fVolPath = theAlignObj.GetSymName();
72   fVolUID = theAlignObj.GetVolUID();
73   return *this;
74 }
75
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
91 //_____________________________________________________________________________
92 AliAlignObj::~AliAlignObj()
93 {
94   // dummy destructor
95 }
96
97 //_____________________________________________________________________________
98 void AliAlignObj::SetVolUID(AliGeomManager::ELayerID detId, Int_t modId)
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   //
105   fVolUID = AliGeomManager::LayerToVolUID(detId,modId);
106 }
107
108 //_____________________________________________________________________________
109 void AliAlignObj::GetVolUID(AliGeomManager::ELayerID &layerId, Int_t &modId) const
110 {
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.
117   //
118   layerId = AliGeomManager::VolUIDToLayer(fVolUID,modId);
119 }
120
121 //_____________________________________________________________________________
122 Bool_t AliAlignObj::GetPars(Double_t tr[], Double_t angles[]) const
123 {
124   GetTranslation(tr);
125   return GetAngles(angles);
126 }
127
128 //_____________________________________________________________________________
129 Int_t AliAlignObj::GetLevel() const
130 {
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('/');
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
161   //
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
170 //_____________________________________________________________________________
171 void AliAlignObj::AnglesToMatrix(const Double_t *angles, Double_t *rot) const
172 {
173   // Calculates the rotation matrix using the 
174   // Euler angles in "x y z" notation
175   //
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 {
198   // Calculates the Euler angles in "x y z" notation
199   // using the rotation matrix
200   // Returns false in case the rotation angles can not be
201   // extracted from the matrix
202   //
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   }
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
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
221   //
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
241 //_____________________________________________________________________________
242 void AliAlignObj::Transform(AliTrackPointArray &array) const
243 {
244   // This method is used to transform all the track points
245   // from the input AliTrackPointArray
246   // 
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
255 //_____________________________________________________________________________
256 void AliAlignObj::Print(Option_t *) const
257 {
258   // Print the contents of the
259   // alignment object in angles and
260   // matrix representations
261   //
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();
269
270   printf("Volume=%s\n",GetSymName());
271   if (GetVolUID() != 0) {
272     AliGeomManager::ELayerID layerId;
273     Int_t modId;
274     GetVolUID(layerId,modId);
275     printf("VolumeID=%d LayerID=%d ( %s ) ModuleID=%d\n", GetVolUID(),layerId,AliGeomManager::LayerName(layerId),modId);
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
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 {
287   // Set the global delta transformation by passing 3 angles (expressed in
288   // degrees) and 3 shifts (in centimeters)
289   // 
290   SetTranslation(x,y,z);
291   SetRotation(psi,theta,phi);
292 }
293
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 {
298   // Set the global delta transformation by passing the parameters
299   // for the local delta transformation (3 shifts and 3 angles).
300   // In case that the TGeo was not initialized or not closed,
301   // returns false and the object parameters are not set.
302   //
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
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
383 //_____________________________________________________________________________
384 Bool_t AliAlignObj::SetLocalMatrix(const TGeoMatrix& m)
385 {
386   // Set the global delta transformation by passing the TGeo matrix
387   // for the local delta transformation.
388   // In case that the TGeo was not initialized or not closed,
389   // returns false and the object parameters are not set.
390   //
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
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
406   if (!node) {
407     AliError(Form("Volume name or path %s not valid!",symname));
408     return kFALSE;
409   }
410   if (node->IsAligned())
411     AliWarning(Form("Volume %s has been already misaligned!",symname));
412
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);
418
419   TGeoHMatrix align,gprime,gprimeinv;
420   gprime = *node->GetMatrix();
421   gprimeinv = gprime.Inverse();
422   m1.Multiply(&gprimeinv);
423   m1.MultiplyLeft(&gprime);
424
425   return SetMatrix(m1);
426 }
427
428 //_____________________________________________________________________________
429 Bool_t AliAlignObj::SetMatrix(const TGeoMatrix& m)
430 {
431   // Set the global delta transformation by passing the TGeoMatrix
432   // for it
433   //
434   SetTranslation(m);
435   return SetRotation(m);
436 }
437
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
521 //_____________________________________________________________________________
522 Bool_t AliAlignObj::ApplyToGeometry()
523 {
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   //
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   
533   const char* symname = GetSymName();
534   const char* path;
535   TGeoPhysicalNode* node;
536   TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
537   if(pne){
538     path = pne->GetTitle();
539     node = gGeoManager->MakeAlignablePN(pne);
540   }else{
541     AliDebug(1,Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname));
542     path=symname;
543     if (!gGeoManager->CheckPath(path)) {
544       AliDebug(1,Form("Volume path %s not valid!",path));
545       return kFALSE;
546     }
547     if (gGeoManager->GetListOfPhysicalNodes()->FindObject(path)) {
548       AliError(Form("Volume %s has already been misaligned!",path));
549       return kFALSE;
550     }
551     node = (TGeoPhysicalNode*) gGeoManager->MakePhysicalNode(path);
552   }
553
554   if (!node) {
555     AliError(Form("Volume path %s not valid!",path));
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;
567   AliGeomManager::ELayerID layerId; // unique identity for layer in the alobj
568   Int_t modId; // unique identity for volume inside layer in the alobj
569   GetVolUID(layerId, modId);
570   AliDebug(2,Form("Aligning volume %s of detector layer %d with local ID %d",symname,layerId,modId));
571   node->Align(ginv);
572
573   return kTRUE;
574 }
575