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