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