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