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