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