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