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