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