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