Improved version of alignmnet object classes (R.Grosso)
[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 //-----------------------------------------------------------------
17 //   Implementation of the alignment object class through the abstract
18 //  class AliAlignObj. From it two derived concrete representation of
19 //  alignment object class (AliAlignObjAngles, AliAlignObjMatrix) are
20 //  derived in separate files.
21 //-----------------------------------------------------------------
22 /*****************************************************************************
23  * AliAlignObjAngles: derived alignment class storing alignment information  *
24  *   for a single volume in form of three doubles for the translation        *
25  *   and three doubles for the rotation expressed with the euler angles      *
26  *   in the xyz-convention (http://mathworld.wolfram.com/EulerAngles.html),  *
27  *   also known as roll, pitch, yaw. PLEASE NOTE THE ANGLES SIGNS ARE        *
28  *   INVERSE WITH RESPECT TO THIS REFERENCE!!! In this way the representation*
29  *   is fully consistent with the TGeo Rotation methods.                     *
30  *****************************************************************************/
31
32 #include "AliAlignObj.h"
33 //#include "AliLog.h"
34
35 ClassImp(AliAlignObj)
36
37 //_____________________________________________________________________________
38 AliAlignObj::AliAlignObj():
39   fVolUID(0)
40 {
41   // dummy constructor
42 }
43
44 //_____________________________________________________________________________
45 AliAlignObj::AliAlignObj(const AliAlignObj& theAlignObj) :
46   TObject(theAlignObj)
47 {
48   //copy constructor
49   fVolPath = theAlignObj.GetVolPath();
50   fVolUID = theAlignObj.GetVolUID();
51 }
52
53 //_____________________________________________________________________________
54 AliAlignObj &AliAlignObj::operator =(const AliAlignObj& theAlignObj)
55 {
56   // assignment operator
57   if(this==&theAlignObj) return *this;
58   fVolPath = theAlignObj.GetVolPath();
59   fVolUID = theAlignObj.GetVolUID();
60   return *this;
61 }
62
63 //_____________________________________________________________________________
64 AliAlignObj::~AliAlignObj()
65 {
66   // dummy destructor
67 }
68
69 //_____________________________________________________________________________
70 void AliAlignObj::SetVolUID(ELayerID detId, Int_t modId)
71 {
72   // From detector name and module number (according to detector numbering)
73   // build fVolUID, unique numerical identity of that volume inside ALICE
74   // fVolUID is 16 bits, first 5 reserved for detID (32 possible values),
75   // remaining 11 for module ID inside det (2048 possible values).
76   //
77   fVolUID = LayerToVolUID(detId,modId);
78 }
79
80 //_____________________________________________________________________________
81 void AliAlignObj::GetVolUID(ELayerID &layerId, Int_t &modId) const
82 {
83   // From detector name and module number (according to detector numbering)
84   // build fVolUID, unique numerical identity of that volume inside ALICE
85   // fVolUID is 16 bits, first 5 reserved for detID (32 possible values),
86   // remaining 11 for module ID inside det (2048 possible values).
87   //
88   layerId = VolUIDToLayer(fVolUID,modId);
89 }
90
91 //_____________________________________________________________________________
92 void AliAlignObj::AnglesToMatrix(const Double_t *angles, Double_t *rot) const
93 {
94   // Calculates the rotation matrix using the 
95   // Euler angles in "x y z" notation
96   Double_t degrad = TMath::DegToRad();
97   Double_t sinpsi = TMath::Sin(degrad*angles[0]);
98   Double_t cospsi = TMath::Cos(degrad*angles[0]);
99   Double_t sinthe = TMath::Sin(degrad*angles[1]);
100   Double_t costhe = TMath::Cos(degrad*angles[1]);
101   Double_t sinphi = TMath::Sin(degrad*angles[2]);
102   Double_t cosphi = TMath::Cos(degrad*angles[2]);
103
104   rot[0] =  costhe*cosphi;
105   rot[1] = -costhe*sinphi;
106   rot[2] =  sinthe;
107   rot[3] =  sinpsi*sinthe*cosphi + cospsi*sinphi;
108   rot[4] = -sinpsi*sinthe*sinphi + cospsi*cosphi;
109   rot[5] = -costhe*sinpsi;
110   rot[6] = -cospsi*sinthe*cosphi + sinpsi*sinphi;
111   rot[7] =  cospsi*sinthe*sinphi + sinpsi*cosphi;
112   rot[8] =  costhe*cospsi;
113 }
114
115 //_____________________________________________________________________________
116 Bool_t AliAlignObj::MatrixToAngles(const Double_t *rot, Double_t *angles) const
117 {
118   // Calculates the Euler angles in "x y z" notation
119   // using the rotation matrix
120   if(rot[0]<1e-7 || rot[8]<1e-7) return kFALSE;
121   Double_t raddeg = TMath::RadToDeg();
122   angles[0]=raddeg*TMath::ATan2(-rot[5],rot[8]);
123   angles[1]=raddeg*TMath::ASin(rot[2]);
124   angles[2]=raddeg*TMath::ATan2(-rot[1],rot[0]);
125   return kTRUE;
126 }
127
128 //_____________________________________________________________________________
129 void AliAlignObj::Print(Option_t *) const
130 {
131   // Print the contents of the
132   // alignment object in angles and
133   // matrix representations
134   Double_t tr[3];
135   GetTranslation(tr);
136   Double_t angles[3];
137   GetAngles(angles);
138   TGeoHMatrix m;
139   GetMatrix(m);
140   const Double_t *rot = m.GetRotationMatrix();
141 //   printf("Volume=%s ID=%u\n", GetVolPath(),GetVolUID());
142   Int_t IDs[2];
143   //  GetVolUID(IDs);
144   printf("Volume=%s LayerID=%d ModuleID=%d\n", GetVolPath(),IDs[0],IDs[1]);
145   printf("%12.6f%12.6f%12.6f    Tx = %12.6f    Psi   = %12.6f\n", rot[0], rot[1], rot[2], tr[0], angles[0]);
146   printf("%12.6f%12.6f%12.6f    Ty = %12.6f    Theta = %12.6f\n", rot[3], rot[4], rot[5], tr[1], angles[1]);
147   printf("%12.6f%12.6f%12.6f    Tz = %12.6f    Phi   = %12.6f\n", rot[6], rot[7], rot[8], tr[2], angles[2]);
148
149 }
150
151 //_____________________________________________________________________________
152 UShort_t AliAlignObj::LayerToVolUID(ELayerID layerId, Int_t modId)
153 {
154   // From detector (layer) name and module number (according to detector numbering)
155   // build fVolUID, unique numerical identity of that volume inside ALICE
156   // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
157   // remaining 11 for module ID inside det (2048 possible values).
158   //
159   return ((UShort_t(layerId) << 11) | UShort_t(modId));
160 }
161
162 //_____________________________________________________________________________
163 AliAlignObj::ELayerID AliAlignObj::VolUIDToLayer(UShort_t voluid, Int_t &modId)
164 {
165   // From detector (layer) name and module number (according to detector numbering)
166   // build fVolUID, unique numerical identity of that volume inside ALICE
167   // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
168   // remaining 11 for module ID inside det (2048 possible values).
169   //
170   modId = voluid & 0x7ff;
171
172   return VolUIDToLayer(voluid);
173 }
174
175 //_____________________________________________________________________________
176 AliAlignObj::ELayerID AliAlignObj::VolUIDToLayer(UShort_t voluid)
177 {
178   // From detector (layer) name and module number (according to detector numbering)
179   // build fVolUID, unique numerical identity of that volume inside ALICE
180   // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
181   // remaining 11 for module ID inside det (2048 possible values).
182   //
183   return ELayerID((voluid >> 11) & 0x1f);
184 }