]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSgeomMatrix.cxx
56f1bfb7f4a27397ac63c2fe379be9de06bcfe51
[u/mrichter/AliRoot.git] / ITS / AliITSgeomMatrix.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 $Log$
18 Revision 1.3  2000/09/05 14:25:50  nilsen
19 Made fixes for HP compiler. All function parameter default values placed
20 in .h file. Fixed the usual problem with HP comilers and the "for(Int_t i..."
21 business. Replaced casting (Double_t [3][3]) to (Double_t (*)[3]) for HP.
22 Lastly removed all "const" before function parameters which were 2 dim. arrays,
23 because on HP root generates some strange code (?). Thanks Peter for the
24 changes.
25
26 Revision 1.2  2000/08/29 20:16:50  nilsen
27 New class for ITS coordiante transformations used by AliITSgeom nearly
28 exclusively.
29
30 Revision 1.1.2.1  2000/06/04 16:32:31  Nilsen
31 A new class to hold the matrix information needed by AliITSgeom.
32
33 */
34 #include <iostream.h>
35 #include <TMath.h>
36 #include <TBuffer.h>
37
38 #include "AliITSgeomMatrix.h"
39
40 ClassImp(AliITSgeomMatrix)
41 //----------------------------------------------------------------------
42 AliITSgeomMatrix::AliITSgeomMatrix(){
43 ////////////////////////////////////////////////////////////////////////
44 // The Default constructor for the AliITSgeomMatrix class. By Default
45 // the angles of rotations are set to zero, meaning that the rotation
46 // matrix is the unit matrix. The translation vector is also set to zero
47 // as are the module id number. The detector type is set to -1 (an undefined
48 // value). The full rotation matrix is kept so that the evaluation 
49 // of a coordinate transformation can be done quickly and with a minimum
50 // of CPU overhead. The basic coordinate systems are the ALICE global
51 // coordinate system and the detector local coordinate system. In general
52 // this structure is not limited to just those two coordinate systems.
53 //Begin_Html
54 /*
55 <img src="picts/ITS/AliISgeomMatrix_L1.gif">
56 */
57 //End_Html
58 ////////////////////////////////////////////////////////////////////////
59     Int_t i,j;
60
61     fDetectorIndex = -1; // a value never defined.
62     for(i=0;i<3;i++){
63         fid[i] = 0;
64         frot[i] = ftran[i] = 0.0;
65         for(j=0;j<3;j++) fm[i][j] = 0.0;
66     }// end for i
67     fm[0][0] = fm[1][1] = fm[2][2] = 1.0;
68 }
69 //----------------------------------------------------------------------
70 AliITSgeomMatrix::AliITSgeomMatrix(const AliITSgeomMatrix &sourse){
71 ////////////////////////////////////////////////////////////////////////
72 // The standard copy constructor. This make a full / proper copy of
73 // this class.
74 ////////////////////////////////////////////////////////////////////////
75         Int_t i,j;
76
77         this->fDetectorIndex = sourse.fDetectorIndex;
78         for(i=0;i<3;i++){
79                 this->fid[i]     = sourse.fid[i];
80                 this->frot[i]    = sourse.frot[i];
81                 this->ftran[i]   = sourse.ftran[i];
82                 for(j=0;j<3;j++) this->fm[i][j] = sourse.fm[i][j];
83         }// end for i
84 }
85 //----------------------------------------------------------------------
86 void AliITSgeomMatrix::operator=(const AliITSgeomMatrix &sourse){
87 ////////////////////////////////////////////////////////////////////////
88 // The standard = operator. This make a full / proper copy of
89 // this class.
90 ////////////////////////////////////////////////////////////////////////
91         Int_t i,j;
92
93         this->fDetectorIndex = sourse.fDetectorIndex;
94         for(i=0;i<3;i++){
95                 this->fid[i]     = sourse.fid[i];
96                 this->frot[i]    = sourse.frot[i];
97                 this->ftran[i]   = sourse.ftran[i];
98                 for(j=0;j<3;j++) this->fm[i][j] = sourse.fm[i][j];
99         }// end for i
100 }
101 //----------------------------------------------------------------------
102 AliITSgeomMatrix::AliITSgeomMatrix(const Int_t idt,const Int_t id[3],
103                    const Double_t rot[3],const Double_t tran[3]){
104 ////////////////////////////////////////////////////////////////////////
105 // This is a constructor for the AliITSgeomMatrix class. The matrix is
106 // defined by 3 standard rotation angles [radians], and the translation
107 // vector tran [cm]. In addition the layer, ladder, and detector number
108 // for this particular module and the type of module must be given.
109 // The full rotation matrix is kept so that the evaluation 
110 // of a coordinate transformation can be done quickly and with a minimum
111 // of CPU overhead. The basic coordinate systems are the ALICE global
112 // coordinate system and the detector local coordinate system. In general
113 // this structure is not limited to just those two coordinate systems.
114 //Begin_Html
115 /*
116 <img src="picts/ITS/AliISgeomMatrix_L1.gif">
117 */
118 //End_Html
119 ////////////////////////////////////////////////////////////////////////
120         Int_t i;
121
122         fDetectorIndex = idt; // a value never defined.
123         for(i=0;i<3;i++){
124                 fid[i]   = id[i];
125                 frot[i]  = rot[i];
126                 ftran[i] = tran[i];
127         }// end for i
128         this->MatrixFromAngle();
129 }
130 //----------------------------------------------------------------------
131 AliITSgeomMatrix::AliITSgeomMatrix(const Int_t idt, const Int_t id[3],
132                                    Double_t matrix[3][3],
133                                    const Double_t tran[3]){
134 ////////////////////////////////////////////////////////////////////////
135 // This is a constructor for the AliITSgeomMatrix class. The rotation matrix
136 // is given as one of the inputs, and the translation vector tran [cm]. In 
137 // addition the layer, ladder, and detector number for this particular
138 // module and the type of module must be given. The full rotation matrix
139 // is kept so that the evaluation of a coordinate transformation can be
140 // done quickly and with a minimum of CPU overhead. The basic coordinate
141 // systems are the ALICE global coordinate system and the detector local
142 // coordinate system. In general this structure is not limited to just
143 // those two coordinate systems.
144 //Begin_Html
145 /*
146 <img src="picts/ITS/AliISgeomMatrix_L1.gif">
147 */
148 //End_Html
149 ////////////////////////////////////////////////////////////////////////
150         Int_t i,j;
151
152         fDetectorIndex = idt; // a value never defined.
153         for(i=0;i<3;i++){
154                 fid[i]   = id[i];
155                 ftran[i] = tran[i];
156                 for(j=0;j<3;j++) fm[i][j] = matrix[i][j];
157         }// end for i
158         this->AngleFromMatrix();
159 }
160 //----------------------------------------------------------------------
161 void AliITSgeomMatrix::SixAnglesFromMatrix(Double_t *ang){
162 ////////////////////////////////////////////////////////////////////////
163 // This function returns the 6 GEANT 3.21 rotation angles [degrees] in
164 // the array ang which must be at least [6] long.
165 ////////////////////////////////////////////////////////////////////////
166     Double_t si,c=180./TMath::Pi();
167
168     ang[1] = TMath::ATan2(fm[0][1],fm[0][0]);
169     if(TMath::Cos(ang[1])!=0.0) si = fm[0][0]/TMath::Cos(ang[1]);
170     else si = fm[0][1]/TMath::Sin(ang[1]);
171     ang[0] = TMath::ATan2(si,fm[0][2]);
172
173     ang[3] = TMath::ATan2(fm[1][1],fm[1][0]);
174     if(TMath::Cos(ang[3])!=0.0) si = fm[1][0]/TMath::Cos(ang[3]);
175     else si = fm[1][1]/TMath::Sin(ang[3]);
176     ang[2] = TMath::ATan2(si,fm[1][2]);
177
178     ang[5] = TMath::ATan2(fm[2][1],fm[2][0]);
179     if(TMath::Cos(ang[5])!=0.0) si = fm[2][0]/TMath::Cos(ang[5]);
180     else si = fm[2][1]/TMath::Sin(ang[5]);
181     ang[4] = TMath::ATan2(si,fm[2][2]);
182
183     for(Int_t i=0;i<6;i++) {ang[i] *= c; if(ang[i]<0.0) ang[i] += 360.;}
184 }
185 //----------------------------------------------------------------------
186 void AliITSgeomMatrix::MatrixFromSixAngles(const Double_t *ang){
187 ////////////////////////////////////////////////////////////////////////
188 // Given the 6 GEANT 3.21 rotation angles [degree], this will compute and
189 // set the rotations matrix and 3 standard rotation angles [radians].
190 // These angles and rotation matrix are overwrite the existing values in
191 // this class.
192 ////////////////////////////////////////////////////////////////////////
193     Int_t    i,j;
194     Double_t si,lr[9],c=TMath::Pi()/180.;
195
196     si    = TMath::Sin(c*ang[0]);
197     if(ang[0]== 90.0)                 si = +1.0;
198     if(ang[0]==270.0)                 si = -1.0;
199     if(ang[0]==  0.0||ang[0]==180.) si =  0.0;
200     lr[0] = si * TMath::Cos(c*ang[1]);
201     lr[1] = si * TMath::Sin(c*ang[1]);
202     lr[2] = TMath::Cos(c*ang[0]);
203     if(ang[0]== 90.0||ang[0]==270.) lr[2] =  0.0;
204     if(ang[0]== 0.0)                  lr[2] = +1.0;
205     if(ang[0]==180.0)                 lr[2] = -1.0;
206 //
207     si    =  TMath::Sin(c*ang[2]);
208     if(ang[2]== 90.0)                 si = +1.0; 
209     if(ang[2]==270.0)                 si = -1.0;
210     if(ang[2]==  0.0||ang[2]==180.) si =  0.0;
211     lr[3] = si * TMath::Cos(c*ang[3]);
212     lr[4] = si * TMath::Sin(c*ang[3]);
213     lr[5] = TMath::Cos(c*ang[2]);
214     if(ang[2]== 90.0||ang[2]==270.) lr[5] =  0.0;
215     if(ang[2]==  0.0)                 lr[5] = +1.0;
216     if(ang[2]==180.0)                 lr[5] = -1.0;
217 //
218     si    = TMath::Sin(c*ang[4]);
219     if(ang[4]== 90.0)                 si = +1.0;
220     if(ang[4]==270.0)                 si = -1.0;
221     if(ang[4]==  0.0||ang[4]==180.) si =  0.0;
222     lr[6] = si * TMath::Cos(c*ang[5]);
223     lr[7] = si * TMath::Sin(c*ang[5]);
224     lr[8] = TMath::Cos(c*ang[4]);
225     if(ang[4]== 90.0||ang[4]==270.0) lr[8] =  0.0;
226     if(ang[4]==  0.0)                  lr[8] = +1.0;
227     if(ang[4]==180.0)                  lr[8] = -1.0;
228     // Normalize these elements and fill matrix fm.
229     for(i=0;i<3;i++){// reuse si.
230         si = 0.0;
231         for(j=0;j<3;j++) si += lr[3*i+j]*lr[3*i+j];
232         si = TMath::Sqrt(1./si);
233         for(j=0;j<3;j++) fm[i][j] = si*lr[3*i+j];
234     } // end for i
235     this->AngleFromMatrix();
236 }
237 //----------------------------------------------------------------------
238 AliITSgeomMatrix::AliITSgeomMatrix(const Double_t rotd[6]/*degrees*/,
239                                    const Int_t idt,const Int_t id[3],
240                                    const Double_t tran[3]){
241 ////////////////////////////////////////////////////////////////////////
242 // This is a constructor for the AliITSgeomMatrix class. The matrix is
243 // defined by the 6 GEANT 3.21 rotation angles [degrees], and the translation
244 // vector tran [cm]. In addition the layer, ladder, and detector number
245 // for this particular module and the type of module must be given.
246 // The full rotation matrix is kept so that the evaluation 
247 // of a coordinate transformation can be done quickly and with a minimum
248 // of CPU overhead. The basic coordinate systems are the ALICE global
249 // coordinate system and the detector local coordinate system. In general
250 // this structure is not limited to just those two coordinate systems.
251 //Begin_Html
252 /*
253 <img src="picts/ITS/AliISgeomMatrix_L1.gif">
254 */
255 //End_Html
256 ////////////////////////////////////////////////////////////////////////
257     Int_t i;
258
259     fDetectorIndex = idt; // a value never defined.
260     for(i=0;i<3;i++){
261         fid[i]   = id[i];
262         ftran[i] = tran[i];
263     }// end for i
264     this->MatrixFromSixAngles(rotd);
265 }
266 //----------------------------------------------------------------------
267 void AliITSgeomMatrix::AngleFromMatrix(){
268 ////////////////////////////////////////////////////////////////////////
269 // Computes the angles from the rotation matrix up to a phase of 180 degrees.
270 ////////////////////////////////////////////////////////////////////////
271     Double_t rx,ry,rz;
272     // get angles from matrix up to a phase of 180 degrees.
273
274     rx = TMath::ATan2(fm[2][1],fm[2][2]);if(rx<0.0) rx += 2.0*TMath::Pi();
275     ry = TMath::ASin(fm[0][2]);          if(ry<0.0) ry += 2.0*TMath::Pi();
276     rz = TMath::ATan2(fm[1][1],fm[0][0]);if(rz<0.0) rz += 2.0*TMath::Pi();
277     frot[0] = rx;
278     frot[1] = ry;
279     frot[2] = rz;
280     return;
281 }
282 //----------------------------------------------------------------------
283 void AliITSgeomMatrix::MatrixFromAngle(){
284 ////////////////////////////////////////////////////////////////////////
285 // Computes the Rotation matrix from the angles [radians] kept in this
286 // class.
287 ////////////////////////////////////////////////////////////////////////
288    Double_t sx,sy,sz,cx,cy,cz;
289
290    sx = TMath::Sin(frot[0]); cx = TMath::Cos(frot[0]);
291    sy = TMath::Sin(frot[1]); cy = TMath::Cos(frot[1]);
292    sz = TMath::Sin(frot[2]); cz = TMath::Cos(frot[2]);
293    fm[0][0] =  cz*cy;             // fr[0]
294    fm[0][1] = -cz*sy*sx - sz*cx;  // fr[1]
295    fm[0][2] = -cz*sy*cx + sz*sx;  // fr[2]
296    fm[1][0] =  sz*cy;             // fr[3]
297    fm[1][1] = -sz*sy*sx + cz*cx;  // fr[4]
298    fm[1][2] = -sz*sy*cx - cz*sx;  // fr[5]
299    fm[2][0] =  sy;                // fr[6]
300    fm[2][1] =  cy*sx;             // fr[7]
301    fm[2][2] =  cy*cx;             // fr[8]
302
303 }
304 //----------------------------------------------------------------------
305 void AliITSgeomMatrix::GtoLPosition(const Double_t g0[3],Double_t l[3]){
306 ////////////////////////////////////////////////////////////////////////
307 // Returns the local coordinates given the global coordinates [cm].
308 ////////////////////////////////////////////////////////////////////////
309         Int_t    i,j;
310         Double_t g[3];
311
312         for(i=0;i<3;i++) g[i] = g0[i] - ftran[i];
313         for(i=0;i<3;i++){
314                 l[i] = 0.0;
315                 for(j=0;j<3;j++) l[i] += fm[i][j]*g[j];
316                 // g = R l + translation
317         } // end for i
318         return;
319 }
320 //----------------------------------------------------------------------
321 void AliITSgeomMatrix::LtoGPosition(const Double_t l[3],Double_t g[3]){
322 ////////////////////////////////////////////////////////////////////////
323 // Returns the global coordinates given the local coordinates [cm].
324 ////////////////////////////////////////////////////////////////////////
325         Int_t    i,j;
326
327         for(i=0;i<3;i++){
328                 g[i] = 0.0;
329                 for(j=0;j<3;j++) g[i] += fm[j][i]*l[j];
330                 g[i] += ftran[i];
331                 // g = R^t l + translation
332         } // end for i
333         return;
334 }
335 //----------------------------------------------------------------------
336 void AliITSgeomMatrix::GtoLMomentum(const Double_t g[3],Double_t l[3]){
337 ////////////////////////////////////////////////////////////////////////
338 // Returns the local coordinates of the momentum given the global
339 // coordinates of the momentum. It transforms just like GtoLPosition
340 // except that the translation vector is zero.
341 ////////////////////////////////////////////////////////////////////////
342         Int_t    i,j;
343
344         for(i=0;i<3;i++){
345                 l[i] = 0.0;
346                 for(j=0;j<3;j++) l[i] += fm[i][j]*g[j];
347                 // g = R l
348         } // end for i
349         return;
350 }
351 //----------------------------------------------------------------------
352 void AliITSgeomMatrix::LtoGMomentum(const Double_t l[3],Double_t g[3]){
353 ////////////////////////////////////////////////////////////////////////
354 // Returns the Global coordinates of the momentum given the local
355 // coordinates of the momentum. It transforms just like LtoGPosition
356 // except that the translation vector is zero.
357 ////////////////////////////////////////////////////////////////////////
358         Int_t    i,j;
359
360         for(i=0;i<3;i++){
361                 g[i] = 0.0;
362                 for(j=0;j<3;j++) g[i] += fm[j][i]*l[j];
363                 // g = R^t l
364         } // end for i
365         return;
366 }
367 //----------------------------------------------------------------------
368 void AliITSgeomMatrix::GtoLPositionError(Double_t g[3][3],
369                                                Double_t l[3][3]){
370 ////////////////////////////////////////////////////////////////////////
371 // Given an Uncertainty matrix in Global coordinates it is rotated so that 
372 // its representation in local coordinates can be returned. There is no
373 // effect due to the translation vector or its uncertainty.
374 ////////////////////////////////////////////////////////////////////////
375         Int_t    i,j,k,m;
376
377         for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)for(m=0;m<3;m++)
378                 l[i][m] = fm[j][i]*g[j][k]*fm[k][m];
379                 // g = R^t l R
380         return;
381 }
382 //----------------------------------------------------------------------
383 void AliITSgeomMatrix::LtoGPositionError(Double_t l[3][3],
384                                                Double_t g[3][3]){
385 ////////////////////////////////////////////////////////////////////////
386 // Given an Uncertainty matrix in Local coordinates it is rotated so that 
387 // its representation in global coordinates can be returned. There is no
388 // effect due to the translation vector or its uncertainty.
389 ////////////////////////////////////////////////////////////////////////
390         Int_t    i,j,k,m;
391
392         for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)for(m=0;m<3;m++)
393                 g[i][m] = fm[i][j]*l[j][k]*fm[m][k];
394                 // g = R l R^t
395         return;
396 }
397 //----------------------------------------------------------------------
398 void AliITSgeomMatrix::GtoLPositionTracking(const Double_t g0[3],
399                                             Double_t l[3]){
400 ////////////////////////////////////////////////////////////////////////
401 // A slightly different coordinate system is used when tracking.
402 // This coordinate system is only relevant when the geometry represents
403 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
404 // alone but X -> -Y and Y -> X such that X always points out of the
405 // ITS Cylinder for every layer including layer 1 (where the detector 
406 // are mounted upside down).
407 //Begin_Html
408 /*
409 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
410  */
411 //End_Html
412 ////////////////////////////////////////////////////////////////////////
413     Double_t l0[3];
414
415     this->GtoLPosition(g0,l0);
416     if(fid[0]==1){ // for layer 1 the detector are flipped upside down
417                    // with respect to the others.
418         l[0] = +l0[1];
419         l[1] = -l0[0];
420         l[2] = +l0[2];
421     }else{
422         l[0] = -l0[1];
423         l[1] = +l0[0];
424         l[2] = +l0[2];
425     } // end if
426     return;
427 }
428 //----------------------------------------------------------------------
429 void AliITSgeomMatrix::LtoGPositionTracking(const Double_t l[3],
430                                             Double_t g[3]){
431 ////////////////////////////////////////////////////////////////////////
432 // A slightly different coordinate system is used when tracking.
433 // This coordinate system is only relevant when the geometry represents
434 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
435 // alone but X -> -Y and Y -> X such that X always points out of the
436 // ITS Cylinder for every layer including layer 1 (where the detector 
437 // are mounted upside down).
438 //Begin_Html
439 /*
440 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
441  */
442 //End_Html
443 ////////////////////////////////////////////////////////////////////////
444     Double_t l0[3];
445
446     if(fid[0]==1){ // for layer 1 the detector are flipped upside down
447                    // with respect to the others.
448         l0[0] = -l[1];
449         l0[1] = +l[0];
450         l0[2] = +l[2];
451     }else{
452         l0[0] = +l[1];
453         l0[1] = -l[0];
454         l0[2] = +l[2];
455     } // end if
456     this->LtoGPosition(l0,g);
457     return;
458 }
459 //----------------------------------------------------------------------
460 void AliITSgeomMatrix::GtoLMomentumTracking(const Double_t g[3],
461                                             Double_t l[3]){
462 ////////////////////////////////////////////////////////////////////////
463 // A slightly different coordinate system is used when tracking.
464 // This coordinate system is only relevant when the geometry represents
465 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
466 // alone but X -> -Y and Y -> X such that X always points out of the
467 // ITS Cylinder for every layer including layer 1 (where the detector 
468 // are mounted upside down).
469 //Begin_Html
470 /*
471 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
472  */
473 //End_Html
474 ////////////////////////////////////////////////////////////////////////
475     Double_t l0[3];
476
477     this->GtoLMomentum(g,l0);
478     if(fid[0]==1){ // for layer 1 the detector are flipped upside down
479                    // with respect to the others.
480         l[0] = +l0[1];
481         l[1] = -l0[0];
482         l[2] = +l0[2];
483     }else{
484         l[0] = -l0[1];
485         l[1] = +l0[0];
486         l[2] = +l0[2];
487     } // end if
488     return;
489         return;
490 }
491 //----------------------------------------------------------------------
492 void AliITSgeomMatrix::LtoGMomentumTracking(const Double_t l[3],
493                                             Double_t g[3]){
494 ////////////////////////////////////////////////////////////////////////
495 // A slightly different coordinate system is used when tracking.
496 // This coordinate system is only relevant when the geometry represents
497 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
498 // alone but X -> -Y and Y -> X such that X always points out of the
499 // ITS Cylinder for every layer including layer 1 (where the detector 
500 // are mounted upside down).
501 //Begin_Html
502 /*
503 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
504  */
505 //End_Html
506 ////////////////////////////////////////////////////////////////////////
507     Double_t l0[3];
508
509     if(fid[0]==1){ // for layer 1 the detector are flipped upside down
510                    // with respect to the others.
511         l0[0] = -l[1];
512         l0[1] = +l[0];
513         l0[2] = +l[2];
514     }else{
515         l0[0] = +l[1];
516         l0[1] = -l[0];
517         l0[2] = +l[2];
518     } // end if
519     this->LtoGMomentum(l0,g);
520         return;
521 }
522 //----------------------------------------------------------------------
523 void AliITSgeomMatrix::GtoLPositionErrorTracking(Double_t g[3][3],
524                                                  Double_t l[3][3]){
525 ////////////////////////////////////////////////////////////////////////
526 // A slightly different coordinate system is used when tracking.
527 // This coordinate system is only relevant when the geometry represents
528 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
529 // alone but X -> -Y and Y -> X such that X always points out of the
530 // ITS Cylinder for every layer including layer 1 (where the detector 
531 // are mounted upside down).
532 //Begin_Html
533 /*
534 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
535  */
536 //End_Html
537 ////////////////////////////////////////////////////////////////////////
538         Int_t    i,j,k,m;
539         Double_t Rt[3][3];
540         Double_t A0[3][3] = {{0.,+1.,0.},{-1.,0.,0.},{0.,0.,+1.}};
541         Double_t A1[3][3] = {{0.,-1.,0.},{+1.,0.,0.},{0.,0.,+1.}};
542
543         if(fid[0]==1) for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
544             Rt[i][k] = A0[i][j]*fm[j][k];
545         else for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
546             Rt[i][k] = A1[i][j]*fm[j][k];
547         for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)for(m=0;m<3;m++)
548                 l[i][m] = Rt[j][i]*g[j][k]*Rt[k][m];
549                 // g = R^t l R
550         return;
551 }
552 //----------------------------------------------------------------------
553 void AliITSgeomMatrix::LtoGPositionErrorTracking(Double_t l[3][3],
554                                                  Double_t g[3][3]){
555 ////////////////////////////////////////////////////////////////////////
556 // A slightly different coordinate system is used when tracking.
557 // This coordinate system is only relevant when the geometry represents
558 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
559 // alone but X -> -Y and Y -> X such that X always points out of the
560 // ITS Cylinder for every layer including layer 1 (where the detector 
561 // are mounted upside down).
562 //Begin_Html
563 /*
564 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
565  */
566 //End_Html
567 ////////////////////////////////////////////////////////////////////////
568         Int_t    i,j,k,m;
569         Double_t Rt[3][3];
570         Double_t A0[3][3] = {{0.,+1.,0.},{-1.,0.,0.},{0.,0.,+1.}};
571         Double_t A1[3][3] = {{0.,-1.,0.},{+1.,0.,0.},{0.,0.,+1.}};
572
573         if(fid[0]==1) for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
574             Rt[i][k] = A0[i][j]*fm[j][k];
575         else for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
576             Rt[i][k] = A1[i][j]*fm[j][k];
577         for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)for(m=0;m<3;m++)
578                 g[i][m] = Rt[i][j]*l[j][k]*Rt[m][k];
579                 // g = R l R^t
580         return;
581 }
582 //----------------------------------------------------------------------
583 void AliITSgeomMatrix::PrintTitles(ostream *os){
584 ////////////////////////////////////////////////////////////////////////
585 // Standard output format for this class but it includes variable
586 // names and formatting that makes it easer to read.
587 ////////////////////////////////////////////////////////////////////////
588     Int_t i,j;
589
590     *os << "fDetectorIndex=" << fDetectorIndex << " fid[3]={";
591     for(i=0;i<3;i++) *os << fid[i]   << " ";
592     *os << "} frot[3]={";
593     for(i=0;i<3;i++) *os << frot[i]  << " ";
594     *os << "} ftran[3]={";
595     for(i=0;i<3;i++) *os << ftran[i] << " ";
596     *os << "} fm[3][3]={";
597     for(i=0;i<3;i++){for(j=0;j<3;j++){  *os << fm[i][j] << " ";} *os <<"}{";}
598     *os << "}" << endl;
599     return;
600 }
601 //----------------------------------------------------------------------
602 void AliITSgeomMatrix::print(ostream *os){
603 ////////////////////////////////////////////////////////////////////////
604 // Standard output format for this class.
605 ////////////////////////////////////////////////////////////////////////
606     Int_t i,j;
607
608     *os << fDetectorIndex << " ";
609     for(i=0;i<3;i++) *os << fid[i]   << " ";
610     for(i=0;i<3;i++) *os << frot[i]  << " ";
611     for(i=0;i<3;i++) *os << ftran[i] << " ";
612     for(i=0;i<3;i++)for(j=0;j<3;j++)  *os << fm[i][j] << " ";
613     *os << endl;
614     return;
615 }
616 //----------------------------------------------------------------------
617 void AliITSgeomMatrix::read(istream *is){
618 ////////////////////////////////////////////////////////////////////////
619 // Standard input format for this class.
620 ////////////////////////////////////////////////////////////////////////
621     Int_t i,j;
622
623     *is >> fDetectorIndex;
624     for(i=0;i<3;i++) *is >> fid[i];
625     for(i=0;i<3;i++) *is >> frot[i];
626     for(i=0;i<3;i++) *is >> ftran[i];
627     for(i=0;i<3;i++)for(j=0;j<3;j++)  *is >> fm[i][j];
628     return;
629 }
630 //----------------------------------------------------------------------
631 ostream &operator<<(ostream &os,AliITSgeomMatrix &p){
632 ////////////////////////////////////////////////////////////////////////
633 // Standard output streaming function.
634 ////////////////////////////////////////////////////////////////////////
635
636     p.print(&os);
637     return os;
638 }
639 //----------------------------------------------------------------------
640 istream &operator>>(istream &is,AliITSgeomMatrix &r){
641 ////////////////////////////////////////////////////////////////////////
642 // Standard input streaming function.
643 ////////////////////////////////////////////////////////////////////////
644
645     r.read(&is);
646     return is;
647 }
648 //----------------------------------------------------------------------
649 void AliITSgeomMatrix::Streamer(TBuffer &R__b){
650 ////////////////////////////////////////////////////////////////////////
651 // Stream an object of class AliITSgeomMatrix.
652 ////////////////////////////////////////////////////////////////////////
653
654    UInt_t R__s, R__c;
655    if (R__b.IsReading()) {
656       Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
657       if (R__v==1) {
658          R__b >> fDetectorIndex;
659          R__b.ReadStaticArray(fid);
660          R__b.ReadStaticArray(frot);
661          R__b.ReadStaticArray(ftran);
662          R__b.ReadStaticArray((double*)fm);
663          R__b.CheckByteCount(R__s, R__c, AliITSgeomMatrix::IsA());
664       } // end if R__v
665    } else { // R__b.IsWriting()
666       R__c = R__b.WriteVersion(AliITSgeomMatrix::IsA(), kTRUE);
667       R__b << fDetectorIndex;
668       R__b.WriteArray(fid, 3);
669       R__b.WriteArray(frot, 3);
670       R__b.WriteArray(ftran, 3);
671       R__b.WriteArray((double*)fm, 9);
672       R__b.SetByteCount(R__c, kTRUE);
673    } // end if R__b.IsReading()||IsWriting()
674 }
675 //______________________________________________________________________