New version of AliAlignObj. The new things are the ITS mapping and some added functio...
[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 "AliTrackPointArray.h"
34 #include "AliLog.h"
35  
36 ClassImp(AliAlignObj)
37
38 Int_t AliAlignObj::fgLayerSize[kLastLayer - kFirstLayer] = {
39   80, 160,  // ITS SPD
40   84, 176,  // ITS SDD
41   748, 950, // ITS SSD
42   36, 36,   // TPC
43   90, 90, 90, 90, 90, 90,  // TRD
44   1,        // TOF ??
45   1, 1,     // PHOS ??
46   7,        // RICH ??
47   1         // MUON ??
48 };
49
50 const char* AliAlignObj::fgLayerName[kLastLayer - kFirstLayer] = {
51   "ITS inner pixels layer", "ITS outer pixels layer",
52   "ITS inner drifts layer", "ITS outer drifts layer",
53   "ITS inner strips layer", "ITS outer strips layer",
54   "TPC inner chambers layer", "TPC outer chambers layer",
55   "TRD chambers layer 1", "TRD chambers layer 2", "TRD chambers layer 3",
56   "TRD chambers layer 4", "TRD chambers layer 5", "TRD chambers layer 6",
57   "TOF layer",
58   "?","?",
59   "RICH layer",
60   "?"
61 };
62
63 const char** AliAlignObj::fgVolPath[kLastLayer - kFirstLayer] = {
64   0x0,0x0,
65   0x0,0x0,
66   0x0,0x0,
67   0x0,0x0,
68   0x0,0x0,0x0,
69   0x0,0x0,0x0,
70   0x0,
71   0x0,0x0,
72   0x0,
73   0x0
74 };
75
76 //_____________________________________________________________________________
77 AliAlignObj::AliAlignObj():
78   fVolUID(0)
79 {
80   // default constructor
81   InitVolPaths();
82 }
83
84 //_____________________________________________________________________________
85 AliAlignObj::AliAlignObj(const AliAlignObj& theAlignObj) :
86   TObject(theAlignObj)
87 {
88   //copy constructor
89   fVolPath = theAlignObj.GetVolPath();
90   fVolUID = theAlignObj.GetVolUID();
91 }
92
93 //_____________________________________________________________________________
94 AliAlignObj &AliAlignObj::operator =(const AliAlignObj& theAlignObj)
95 {
96   // assignment operator
97   if(this==&theAlignObj) return *this;
98   fVolPath = theAlignObj.GetVolPath();
99   fVolUID = theAlignObj.GetVolUID();
100   return *this;
101 }
102
103 //_____________________________________________________________________________
104 AliAlignObj::~AliAlignObj()
105 {
106   // dummy destructor
107 }
108
109 //_____________________________________________________________________________
110 void AliAlignObj::SetVolUID(ELayerID detId, Int_t modId)
111 {
112   // From detector name and module number (according to detector numbering)
113   // build fVolUID, unique numerical identity of that volume inside ALICE
114   // fVolUID is 16 bits, first 5 reserved for detID (32 possible values),
115   // remaining 11 for module ID inside det (2048 possible values).
116   //
117   fVolUID = LayerToVolUID(detId,modId);
118 }
119
120 //_____________________________________________________________________________
121 void AliAlignObj::GetVolUID(ELayerID &layerId, Int_t &modId) const
122 {
123   // From detector name and module number (according to detector numbering)
124   // build fVolUID, unique numerical identity of that volume inside ALICE
125   // fVolUID is 16 bits, first 5 reserved for detID (32 possible values),
126   // remaining 11 for module ID inside det (2048 possible values).
127   //
128   layerId = VolUIDToLayer(fVolUID,modId);
129 }
130
131 //_____________________________________________________________________________
132 void AliAlignObj::AnglesToMatrix(const Double_t *angles, Double_t *rot) const
133 {
134   // Calculates the rotation matrix using the 
135   // Euler angles in "x y z" notation
136   Double_t degrad = TMath::DegToRad();
137   Double_t sinpsi = TMath::Sin(degrad*angles[0]);
138   Double_t cospsi = TMath::Cos(degrad*angles[0]);
139   Double_t sinthe = TMath::Sin(degrad*angles[1]);
140   Double_t costhe = TMath::Cos(degrad*angles[1]);
141   Double_t sinphi = TMath::Sin(degrad*angles[2]);
142   Double_t cosphi = TMath::Cos(degrad*angles[2]);
143
144   rot[0] =  costhe*cosphi;
145   rot[1] = -costhe*sinphi;
146   rot[2] =  sinthe;
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;
153 }
154
155 //_____________________________________________________________________________
156 Bool_t AliAlignObj::MatrixToAngles(const Double_t *rot, Double_t *angles) const
157 {
158   // Calculates the Euler angles in "x y z" notation
159   // using the rotation matrix
160   if(rot[0]<1e-7 || rot[8]<1e-7) return kFALSE;
161   Double_t raddeg = TMath::RadToDeg();
162   angles[0]=raddeg*TMath::ATan2(-rot[5],rot[8]);
163   angles[1]=raddeg*TMath::ASin(rot[2]);
164   angles[2]=raddeg*TMath::ATan2(-rot[1],rot[0]);
165   return kTRUE;
166 }
167
168 //______________________________________________________________________________
169 void AliAlignObj::Transform(AliTrackPoint &p) const
170 {
171   // The method transforms the space-point coordinates using the
172   // transformation matrix provided by the AliAlignObj
173   // The covariance matrix is not affected since we assume
174   // that the transformations are sufficiently small
175
176   if (fVolUID != p.GetVolumeID())
177     AliWarning(Form("Alignment object ID is not equal to the space-point ID (%d != %d)",fVolUID,p.GetVolumeID())); 
178
179   TGeoHMatrix m;
180   GetMatrix(m);
181   Double_t *rot = m.GetRotationMatrix();
182   Double_t *tr  = m.GetTranslation();
183
184   Float_t xyzin[3],xyzout[3];
185   p.GetXYZ(xyzin);
186   for (Int_t i = 0; i < 3; i++)
187     xyzout[i] = tr[i]+
188                 xyzin[0]*rot[3*i]+
189                 xyzin[1]*rot[3*i+1]+
190                 xyzin[2]*rot[3*i+2];
191   p.SetXYZ(xyzout);
192   
193 }
194
195 //______________________________________________________________________________
196 void AliAlignObj::Transform(AliTrackPointArray &array) const
197 {
198   AliTrackPoint p;
199   for (Int_t i = 0; i < array.GetNPoints(); i++) {
200     array.GetPoint(p,i);
201     Transform(p);
202     array.AddPoint(i,&p);
203   }
204 }
205
206 //_____________________________________________________________________________
207 void AliAlignObj::Print(Option_t *) const
208 {
209   // Print the contents of the
210   // alignment object in angles and
211   // matrix representations
212   Double_t tr[3];
213   GetTranslation(tr);
214   Double_t angles[3];
215   GetAngles(angles);
216   TGeoHMatrix m;
217   GetMatrix(m);
218   const Double_t *rot = m.GetRotationMatrix();
219 //   printf("Volume=%s ID=%u\n", GetVolPath(),GetVolUID());
220   ELayerID layerId;
221   Int_t modId;
222   GetVolUID(layerId,modId);
223   printf("Volume=%s LayerID=%d ModuleID=%d\n", GetVolPath(),layerId,modId);
224   printf("%12.6f%12.6f%12.6f    Tx = %12.6f    Psi   = %12.6f\n", rot[0], rot[1], rot[2], tr[0], angles[0]);
225   printf("%12.6f%12.6f%12.6f    Ty = %12.6f    Theta = %12.6f\n", rot[3], rot[4], rot[5], tr[1], angles[1]);
226   printf("%12.6f%12.6f%12.6f    Tz = %12.6f    Phi   = %12.6f\n", rot[6], rot[7], rot[8], tr[2], angles[2]);
227
228 }
229
230 //_____________________________________________________________________________
231 UShort_t AliAlignObj::LayerToVolUID(ELayerID layerId, Int_t modId)
232 {
233   // From detector (layer) name and module number (according to detector numbering)
234   // build fVolUID, unique numerical identity of that volume inside ALICE
235   // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
236   // remaining 11 for module ID inside det (2048 possible values).
237   //
238   return ((UShort_t(layerId) << 11) | UShort_t(modId));
239 }
240
241 //_____________________________________________________________________________
242 AliAlignObj::ELayerID AliAlignObj::VolUIDToLayer(UShort_t voluid, Int_t &modId)
243 {
244   // From detector (layer) name and module number (according to detector numbering)
245   // build fVolUID, unique numerical identity of that volume inside ALICE
246   // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
247   // remaining 11 for module ID inside det (2048 possible values).
248   //
249   modId = voluid & 0x7ff;
250
251   return VolUIDToLayer(voluid);
252 }
253
254 //_____________________________________________________________________________
255 AliAlignObj::ELayerID AliAlignObj::VolUIDToLayer(UShort_t voluid)
256 {
257   // From detector (layer) name and module number (according to detector numbering)
258   // build fVolUID, unique numerical identity of that volume inside ALICE
259   // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
260   // remaining 11 for module ID inside det (2048 possible values).
261   //
262   return ELayerID((voluid >> 11) & 0x1f);
263 }
264
265 //_____________________________________________________________________________
266 void AliAlignObj::InitVolPaths()
267 {
268   // Initialize the LUTs which contain
269   // the TGeo volume paths for each
270   // alignable volume. The LUTs are
271   // static, so they are created during
272   // the creation of the first intance
273   // of AliAlignObj
274
275   if (fgVolPath[0]) return;
276
277   for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++)
278     fgVolPath[iLayer] = new const char *[fgLayerSize[iLayer]];
279
280   /*********************       SPD layer1  ***********************/
281   {
282     Int_t modnum = 0;
283     TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT12_1/I12B_"; //".../I12A_"
284     TString str1 = "/I10B_";    //"/I10A_";
285     TString str2 = "/I107_";    //"/I103_"
286     TString str3 = "/I101_1/ITS1_1";
287     TString volpath, volpath1, volpath2;
288
289     for(Int_t c1 = 1; c1<=10; c1++){
290       volpath = str0;
291       volpath += c1;
292       volpath += str1;
293       for(Int_t c2 =1; c2<=2; c2++){
294         volpath1 = volpath;
295         volpath1 += c2;
296         volpath1 += str2;
297         for(Int_t c3 =1; c3<=4; c3++){
298           volpath2 = volpath1;
299           volpath2 += c3;
300           volpath2 += str3;
301           fgVolPath[kSPD1-kFirstLayer][modnum] = volpath2.Data();
302           modnum++;
303         }
304       }
305     }
306   }
307   
308   /*********************       SPD layer2  ***********************/
309   {
310     Int_t modnum = 0;
311     TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT12_1/I12B_";  //".../I12A_"
312     TString str1 = "/I20B_";  //"/I20A"
313     TString str2 = "/I1D7_";  //"/I1D3"
314     TString str3 = "/I1D1_1/ITS2_1";
315     TString volpath, volpath1, volpath2;
316
317     for(Int_t c1 = 1; c1<=10; c1++){
318       volpath = str0;
319       volpath += c1;
320       volpath += str1;
321       for(Int_t c2 =1; c2<=4; c2++){
322         volpath1 = volpath;
323         volpath1 += c2;
324         volpath1 += str2;
325         for(Int_t c3 =1; c3<=4; c3++){
326           volpath2 = volpath1;
327           volpath2 += c3;
328           volpath2 += str3;
329           fgVolPath[kSPD2-kFirstLayer][modnum] = volpath2.Data();
330           modnum++;
331         }
332       }
333     }
334   }
335
336   /*********************       SDD layer1  ***********************/
337   {
338     Int_t modnum=0;
339     TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT34_1/I004_";
340     TString str1 = "/I302_";
341     TString str2 = "/ITS3_1";
342     TString volpath, volpath1;
343
344     for(Int_t c1 = 1; c1<=14; c1++){
345       volpath = str0;
346       volpath += c1;
347       volpath += str1;
348       for(Int_t c2 =1; c2<=6; c2++){
349         volpath1 = volpath;
350         volpath1 += c2;
351         volpath1 += str2;
352         fgVolPath[kSDD1-kFirstLayer][modnum] = volpath1.Data();
353         modnum++;
354       }
355     }
356   }
357
358   /*********************       SDD layer2  ***********************/
359   {
360     Int_t modnum=0;
361     TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT34_1/I005_";
362     TString str1 = "/I402_";
363     TString str2 = "/ITS4_1";
364     TString volpath, volpath1;
365
366     for(Int_t c1 = 1; c1<=22; c1++){
367       volpath = str0;
368       volpath += c1;
369       volpath += str1;
370       for(Int_t c2 = 1; c2<=8; c2++){
371         volpath1 = volpath;
372         volpath1 += c2;
373         volpath1 += str2;
374         fgVolPath[kSDD2-kFirstLayer][modnum] = volpath1.Data();
375         modnum++;
376       }
377     }
378   }
379
380   /*********************       SSD layer1  ***********************/
381   {
382     Int_t modnum=0;
383     TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT56_1/I565_";
384     TString str1 = "/I562_";
385     TString str2 = "/ITS5_1";
386     TString volpath, volpath1;
387
388     for(Int_t c1 = 1; c1<=34; c1++){
389       volpath = str0;
390       volpath += c1;
391       volpath += str1;
392       for(Int_t c2 = 1; c2<=22; c2++){
393         volpath1 = volpath;
394         volpath1 += c2;
395         volpath1 += str2;
396         fgVolPath[kSSD1-kFirstLayer][modnum] = volpath1.Data();
397         modnum++;
398       }
399     }
400   }
401
402   /*********************       SSD layer1  ***********************/
403   {
404     Int_t modnum=0;
405     TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT56_1/I569_";
406     TString str1 = "/I566_";
407     TString str2 = "/ITS6_1";
408     TString volpath, volpath1;
409
410     for(Int_t c1 = 1; c1<=38; c1++){
411       volpath = str0;
412       volpath += c1;
413       volpath += str1;
414       for(Int_t c2 = 1; c2<=25; c2++){
415         volpath1 = volpath;
416         volpath1 += c2;
417         volpath1 += str2;
418         fgVolPath[kSSD2-kFirstLayer][modnum] = volpath1.Data();
419         modnum++;
420       }
421     }
422   }
423
424  
425 }