]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSgeomMatrix.cxx
Bug fix in AngleFromMatrix() fixed, Thanks Robert for find this.
[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 $Id$ 
18 */
19 ////////////////////////////////////////////////////////////////////////
20 // This is the implementation file for AliITSgeomMatrix class. It 
21 // contains the routines to manipulate, setup, and queary the geometry 
22 // of a given ITS module. An ITS module may be one of at least three
23 // ITS detector technologies, Silicon Pixel, Drift, or Strip Detectors,
24 // and variations of these in size and/or layout. These routines let
25 // one go between ALICE global coordiantes (cm) to a given modules 
26 // specific local coordinates (cm).
27 ////////////////////////////////////////////////////////////////////////
28
29 #include <Riostream.h>
30 #include <TMath.h>
31 #include <TBuffer.h>
32 #include <TCanvas.h>
33 #include <TView.h>
34 #include <TPolyLine3D.h>
35 #include <TNode.h>
36 #include <TPCON.h>
37 #include <TBRIK.h>
38 #include <TXTRU.h>
39
40 #include "AliITSgeomMatrix.h"
41
42 ClassImp(AliITSgeomMatrix)
43 //----------------------------------------------------------------------
44 AliITSgeomMatrix::AliITSgeomMatrix():
45 TObject(),
46 fDetectorIndex(0), // Detector type index (like fShapeIndex was)
47 fid(),       // layer, ladder, detector numbers.
48 frot(),      //! vector of rotations about x,y,z [radians].
49 ftran(),     // Translation vector of module x,y,z.
50 fCylR(0.0),  //! R Translation in Cylinderical coordinates
51 fCylPhi(0.0),//! Phi Translation vector in Cylindrical coord.
52 fm(),        // Rotation matrix based on frot.
53 fPath(){     // Path in geometry to this module
54     // The Default constructor for the AliITSgeomMatrix class. By Default
55     // the angles of rotations are set to zero, meaning that the rotation
56     // matrix is the unit matrix. The translation vector is also set to 
57     // zero as are the module id number. The detector type is set to -1 
58     // (an undefined value). The full rotation matrix is kept so that 
59     // the evaluation  of a coordinate transformation can be done 
60     // quickly and with a minimum of CPU overhead. The basic coordinate 
61     // systems are the ALICE global coordinate system and the detector 
62     // local coordinate system. In general this structure is not limited 
63     // to just those two coordinate systems.
64     //Begin_Html
65     /*
66       <img src="picts/ITS/AliITSgeomMatrix_L1.gif">
67     */
68     //End_Html
69     // Inputs:
70     //    none.
71     // Outputs:
72     //    none.
73     // Return:
74     //    A default constructes AliITSgeomMatrix class.
75     Int_t i,j;
76
77     fDetectorIndex = -1; // a value never defined.
78     for(i=0;i<3;i++){
79         fid[i] = 0;
80         frot[i] = ftran[i] = 0.0;
81         for(j=0;j<3;j++) fm[i][j] = 0.0;
82         fCylR = fCylPhi = 0.0;
83     }// end for i
84     fm[0][0] = fm[1][1] = fm[2][2] = 1.0;
85 }
86 /*
87 //----------------------------------------------------------------------
88 AliITSgeomMatrix::AliITSgeomMatrix(const AliITSgeomMatrix &sourse) : 
89     TObject(sourse){
90     // The standard Copy constructor. This make a full / proper copy of
91     // this class.
92     // Inputs:
93     //    AliITSgeomMatrix &source   The source of this copy
94     // Outputs:
95     //    none.
96     // Return:
97     //    A copy constructes AliITSgeomMatrix class.
98         Int_t i,j;
99
100         this->fDetectorIndex = sourse.fDetectorIndex;
101         for(i=0;i<3;i++){
102                 this->fid[i]     = sourse.fid[i];
103                 this->frot[i]    = sourse.frot[i];
104                 this->ftran[i]   = sourse.ftran[i];
105                 this->fCylR      = sourse.fCylR;
106                 this->fCylPhi    = sourse.fCylPhi;
107                 for(j=0;j<3;j++) this->fm[i][j] = sourse.fm[i][j];
108         }// end for i
109      this->fPath   = sourse.fPath;
110 }
111 //----------------------------------------------------------------------
112 void AliITSgeomMatrix::operator=(const AliITSgeomMatrix &sourse){
113     // The standard = operator. This make a full / proper copy of
114     // this class.
115     // The standard Copy constructor. This make a full / proper copy of
116     // this class.
117     // Inputs:
118     //    AliITSgeomMatrix &source   The source of this copy
119     // Outputs:
120     //    none.
121     // Return:
122     //    A copy of the source AliITSgeomMatrix class.
123         Int_t i,j;
124
125         this->fDetectorIndex = sourse.fDetectorIndex;
126         for(i=0;i<3;i++){
127                 this->fid[i]     = sourse.fid[i];
128                 this->frot[i]    = sourse.frot[i];
129                 this->ftran[i]   = sourse.ftran[i];
130                 this->fCylR      = sourse.fCylR;
131                 this->fCylPhi    = sourse.fCylPhi;
132                 for(j=0;j<3;j++) this->fm[i][j] = sourse.fm[i][j];
133         }// end for i
134      this->fPath   = sourse.fPath;
135 }
136 */
137 //----------------------------------------------------------------------
138 AliITSgeomMatrix::AliITSgeomMatrix(Int_t idt,const Int_t id[3],
139                         const Double_t rot[3],const Double_t tran[3]):
140 TObject(),
141 fDetectorIndex(idt), // Detector type index (like fShapeIndex was)
142 fid(),       // layer, ladder, detector numbers.
143 frot(),      //! vector of rotations about x,y,z [radians].
144 ftran(),     // Translation vector of module x,y,z.
145 fCylR(0.0),  //! R Translation in Cylinderical coordinates
146 fCylPhi(0.0),//! Phi Translation vector in Cylindrical coord.
147 fm(),        // Rotation matrix based on frot.
148 fPath(){     // Path in geometry to this moduel
149     // This is a constructor for the AliITSgeomMatrix class. The matrix is
150     // defined by 3 standard rotation angles [radians], and the translation
151     // vector tran [cm]. In addition the layer, ladder, and detector number
152     // for this particular module and the type of module must be given.
153     // The full rotation matrix is kept so that the evaluation 
154     // of a coordinate transformation can be done quickly and with a minimum
155     // of CPU overhead. The basic coordinate systems are the ALICE global
156     // coordinate system and the detector local coordinate system. In general
157     // this structure is not limited to just those two coordinate systems.
158     //Begin_Html
159     /*
160       <img src="picts/ITS/AliITSgeomMatrix_L1.gif">
161     */
162     //End_Html
163     // Inputs:
164     //    Int_t idt        The detector index value
165     //    Int_t id[3]      The layer, ladder, and detector numbers
166     //    Double_t rot[3]  The 3 Cartician rotaion angles [radians]
167     //    Double_t tran[3] The 3 Cartician translation distnaces
168     // Outputs:
169     //    none.
170     // Return:
171     //    A properly inilized AliITSgeomMatrix class.
172     Int_t i;
173
174     for(i=0;i<3;i++){
175         fid[i]   = id[i];
176         frot[i]  = rot[i];
177         ftran[i] = tran[i];
178     }// end for i
179     fCylR   = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
180     fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
181     if(fCylPhi<0.0) fCylPhi += TMath::Pi();
182     this->MatrixFromAngle();
183 }
184 //----------------------------------------------------------------------
185 AliITSgeomMatrix::AliITSgeomMatrix(Int_t idt, const Int_t id[3],
186                                    Double_t matrix[3][3],
187                                    const Double_t tran[3]):
188 TObject(),
189 fDetectorIndex(idt), // Detector type index (like fShapeIndex was)
190 fid(),       // layer, ladder, detector numbers.
191 frot(),      //! vector of rotations about x,y,z [radians].
192 ftran(),     // Translation vector of module x,y,z.
193 fCylR(0.0),  //! R Translation in Cylinderical coordinates
194 fCylPhi(0.0),//! Phi Translation vector in Cylindrical coord.
195 fm(),        // Rotation matrix based on frot.
196 fPath(){     // Path in geometry to this module
197     // This is a constructor for the AliITSgeomMatrix class. The 
198     // rotation matrix is given as one of the inputs, and the 
199     // translation vector tran [cm]. In  addition the layer, ladder, 
200     // and detector number for this particular module and the type of 
201     // module must be given. The full rotation matrix is kept so that 
202     // the evaluation of a coordinate transformation can be done quickly 
203     // and with a minimum of CPU overhead. The basic coordinate systems 
204     // are the ALICE global coordinate system and the detector local
205     // coordinate system. In general this structure is not limited to just
206     // those two coordinate systems.
207     //Begin_Html
208     /*
209       <img src="picts/ITS/AliITSgeomMatrix_L1.gif">
210     */
211     //End_Html
212     // Inputs:
213     //    Int_t idt          The detector index value
214     //    Int_t id[3]        The layer, ladder, and detector numbers
215     //    Double_t rot[3][3] The 3x3 Cartician rotaion matrix
216     //    Double_t tran[3]   The 3 Cartician translation distnaces
217     // Outputs:
218     //    none.
219     // Return:
220     //    A properly inilized AliITSgeomMatrix class.
221     Int_t i,j;
222
223     for(i=0;i<3;i++){
224         fid[i]   = id[i];
225         ftran[i] = tran[i];
226         for(j=0;j<3;j++) fm[i][j] = matrix[i][j];
227     }// end for i
228     fCylR   = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
229     fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
230     if(fCylPhi<0.0) fCylPhi += TMath::Pi();
231     this->AngleFromMatrix();
232 }
233 //----------------------------------------------------------------------
234 void AliITSgeomMatrix::SixAnglesFromMatrix(Double_t *ang)const{
235     // This function returns the 6 GEANT 3.21 rotation angles [degrees] in
236     // the array ang which must be at least [6] long.
237     // Inputs:
238     //   none.
239     // Outputs:
240     //   Double_t ang[6]  The 6 Geant3.21 rotation angles. [degrees]
241     // Return:
242     //   noting
243     Double_t si,c=180./TMath::Pi();
244
245     ang[1] = TMath::ATan2(fm[0][1],fm[0][0]);
246     if(TMath::Cos(ang[1])!=0.0) si = fm[0][0]/TMath::Cos(ang[1]);
247     else si = fm[0][1]/TMath::Sin(ang[1]);
248     ang[0] = TMath::ATan2(si,fm[0][2]);
249
250     ang[3] = TMath::ATan2(fm[1][1],fm[1][0]);
251     if(TMath::Cos(ang[3])!=0.0) si = fm[1][0]/TMath::Cos(ang[3]);
252     else si = fm[1][1]/TMath::Sin(ang[3]);
253     ang[2] = TMath::ATan2(si,fm[1][2]);
254
255     ang[5] = TMath::ATan2(fm[2][1],fm[2][0]);
256     if(TMath::Cos(ang[5])!=0.0) si = fm[2][0]/TMath::Cos(ang[5]);
257     else si = fm[2][1]/TMath::Sin(ang[5]);
258     ang[4] = TMath::ATan2(si,fm[2][2]);
259
260     for(Int_t i=0;i<6;i++) {ang[i] *= c; if(ang[i]<0.0) ang[i] += 360.;}
261 }
262 //----------------------------------------------------------------------
263 void AliITSgeomMatrix::MatrixFromSixAngles(const Double_t *ang){
264     // Given the 6 GEANT 3.21 rotation angles [degree], this will compute and
265     // set the rotations matrix and 3 standard rotation angles [radians].
266     // These angles and rotation matrix are overwrite the existing values in
267     // this class.
268     // Inputs:
269     //   Double_t ang[6]  The 6 Geant3.21 rotation angles. [degrees]
270     // Outputs:
271     //   none.
272     // Return:
273     //   noting
274     Int_t    i,j;
275     Double_t si,lr[9],c=TMath::Pi()/180.;
276
277     si    = TMath::Sin(c*ang[0]);
278     if(ang[0]== 90.0)                 si = +1.0;
279     if(ang[0]==270.0)                 si = -1.0;
280     if(ang[0]==  0.0||ang[0]==180.) si =  0.0;
281     lr[0] = si * TMath::Cos(c*ang[1]);
282     lr[1] = si * TMath::Sin(c*ang[1]);
283     lr[2] = TMath::Cos(c*ang[0]);
284     if(ang[0]== 90.0||ang[0]==270.) lr[2] =  0.0;
285     if(ang[0]== 0.0)                  lr[2] = +1.0;
286     if(ang[0]==180.0)                 lr[2] = -1.0;
287 //
288     si    =  TMath::Sin(c*ang[2]);
289     if(ang[2]== 90.0)                 si = +1.0; 
290     if(ang[2]==270.0)                 si = -1.0;
291     if(ang[2]==  0.0||ang[2]==180.) si =  0.0;
292     lr[3] = si * TMath::Cos(c*ang[3]);
293     lr[4] = si * TMath::Sin(c*ang[3]);
294     lr[5] = TMath::Cos(c*ang[2]);
295     if(ang[2]== 90.0||ang[2]==270.) lr[5] =  0.0;
296     if(ang[2]==  0.0)                 lr[5] = +1.0;
297     if(ang[2]==180.0)                 lr[5] = -1.0;
298 //
299     si    = TMath::Sin(c*ang[4]);
300     if(ang[4]== 90.0)                 si = +1.0;
301     if(ang[4]==270.0)                 si = -1.0;
302     if(ang[4]==  0.0||ang[4]==180.) si =  0.0;
303     lr[6] = si * TMath::Cos(c*ang[5]);
304     lr[7] = si * TMath::Sin(c*ang[5]);
305     lr[8] = TMath::Cos(c*ang[4]);
306     if(ang[4]== 90.0||ang[4]==270.0) lr[8] =  0.0;
307     if(ang[4]==  0.0)                  lr[8] = +1.0;
308     if(ang[4]==180.0)                  lr[8] = -1.0;
309     // Normalize these elements and fill matrix fm.
310     for(i=0;i<3;i++){// reuse si.
311         si = 0.0;
312         for(j=0;j<3;j++) si += lr[3*i+j]*lr[3*i+j];
313         si = TMath::Sqrt(1./si);
314         for(j=0;j<3;j++) fm[i][j] = si*lr[3*i+j];
315     } // end for i
316     this->AngleFromMatrix();
317 }
318 //----------------------------------------------------------------------
319 AliITSgeomMatrix::AliITSgeomMatrix(const Double_t rotd[6]/*degrees*/,
320                                    Int_t idt,const Int_t id[3],
321                                    const Double_t tran[3]):
322 TObject(),
323 fDetectorIndex(idt),
324 fCylR(0.),
325 fCylPhi(0.),
326 fPath(){
327     // This is a constructor for the AliITSgeomMatrix class. The matrix 
328     // is defined by the 6 GEANT 3.21 rotation angles [degrees], and 
329     // the translation vector tran [cm]. In addition the layer, ladder, 
330     // and detector number for this particular module and the type of 
331     // module must be given. The full rotation matrix is kept so that 
332     // the evaluation  of a coordinate transformation can be done 
333     // quickly and with a minimum of CPU overhead. The basic coordinate 
334     // systems are the ALICE global coordinate system and the detector 
335     // local coordinate system. In general this structure is not limited 
336     // to just those two coordinate systems.
337     //Begin_Html
338     /*
339       <img src="picts/ITS/AliITSgeomMatrix_L1.gif">
340     */
341     //End_Html
342     // Inputs:
343     //    Double_t rotd[6]  The 6 Geant 3.21 rotation angles [degrees]
344     //    Int_t idt         The module Id number
345     //    Int_t id[3]       The layer, ladder and detector number
346     //    Double_t tran[3]  The translation vector
347     Int_t i;
348
349     for(i=0;i<3;i++){
350         fid[i]   = id[i];
351         ftran[i] = tran[i];
352     }// end for i
353     fCylR   = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
354     fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
355     if(fCylPhi<0.0) fCylPhi += TMath::Pi();
356     this->MatrixFromSixAngles(rotd);
357 }
358 //----------------------------------------------------------------------
359 void AliITSgeomMatrix::AngleFromMatrix(){
360     // Computes the angles from the rotation matrix up to a phase of 
361     // 180 degrees. The matrix used in AliITSgeomMatrix::MatrixFromAngle()
362     // and  its inverse AliITSgeomMatrix::AngleFromMatrix() are defined in 
363     // the following ways, R = Rz*Ry*Rx (M=R*L+T) where
364     //     1   0   0       Cy  0 -Sy       Cz -Sz  0
365     // Rx= 0   Cx -Sx  Ry=  0  1   0   Rz= Sz  Cz  0
366     //     0   Sx  Cx      Sy  0  Cy        0   0  1
367     // The choice of the since of S, comes from the choice between 
368     // the rotation of the object or the coordinate system (view). I think
369     // that this choice is the first, the rotation of the object.
370     // Inputs:
371     //   none
372     // Outputs:
373     //   none
374     // Return:
375     //   none
376     Double_t rx,ry,rz;
377     // get angles from matrix up to a phase of 180 degrees.
378
379     rx = TMath::ATan2(fm[2][1],fm[2][2]);if(rx<0.0) rx += 2.0*TMath::Pi();
380     ry = TMath::ASin(fm[0][2]);          if(ry<0.0) ry += 2.0*TMath::Pi();
381     rz = TMath::ATan2(fm[1][0],fm[0][0]);if(rz<0.0) rz += 2.0*TMath::Pi();
382     frot[0] = rx;
383     frot[1] = ry;
384     frot[2] = rz;
385     return;
386 }
387 //----------------------------------------------------------------------
388 void AliITSgeomMatrix::MatrixFromAngle(){
389     // Computes the Rotation matrix from the angles [radians] kept in this
390     // class. The matrix used in AliITSgeomMatrix::MatrixFromAngle() and 
391     // its inverse AliITSgeomMatrix::AngleFromMatrix() are defined in 
392     // the following ways, R = Rz*Ry*Rx (M=R*L+T) where
393     //     1   0   0       Cy  0 -Sy       Cz -Sz  0
394     // Rx= 0   Cx -Sx  Ry=  0  1   0   Rz= Sz  Cz  0
395     //     0   Sx  Cx      Sy  0  Cy        0   0  1
396     // The choice of the since of S, comes from the choice between 
397     // the rotation of the object or the coordinate system (view). I think
398     // that this choice is the first, the rotation of the object.
399     // Inputs:
400     //   none
401     // Outputs:
402     //   none
403     // Return:
404     //   none
405    Double_t sx,sy,sz,cx,cy,cz;
406
407    sx = TMath::Sin(frot[0]); cx = TMath::Cos(frot[0]);
408    sy = TMath::Sin(frot[1]); cy = TMath::Cos(frot[1]);
409    sz = TMath::Sin(frot[2]); cz = TMath::Cos(frot[2]);
410    fm[0][0] =  cz*cy;             // fr[0]
411    fm[0][1] = -cz*sy*sx - sz*cx;  // fr[1]
412    fm[0][2] = -cz*sy*cx + sz*sx;  // fr[2]
413    fm[1][0] =  sz*cy;             // fr[3]
414    fm[1][1] = -sz*sy*sx + cz*cx;  // fr[4]
415    fm[1][2] = -sz*sy*cx - cz*sx;  // fr[5]
416    fm[2][0] =  sy;                // fr[6]
417    fm[2][1] =  cy*sx;             // fr[7]
418    fm[2][2] =  cy*cx;             // fr[8]
419
420 }
421 //----------------------------------------------------------------------
422 void AliITSgeomMatrix::GtoLPosition(const Double_t g0[3],Double_t l[3]) const {
423     // Returns the local coordinates given the global coordinates [cm].
424     // Inputs:
425     //   Double_t g[3]   The position represented in the ALICE 
426     //                   global coordinate system
427     // Outputs:
428     //   Double_t l[3]  The poistion represented in the local
429     //                  detector coordiante system
430     // Return:
431     //   none
432         Int_t    i,j;
433         Double_t g[3];
434
435         for(i=0;i<3;i++) g[i] = g0[i] - ftran[i];
436         for(i=0;i<3;i++){
437                 l[i] = 0.0;
438                 for(j=0;j<3;j++) l[i] += fm[i][j]*g[j];
439                 // g = R l + translation
440         } // end for i
441         return;
442 }
443 //----------------------------------------------------------------------
444 void AliITSgeomMatrix::LtoGPosition(const Double_t l[3],Double_t g[3]) const {
445     // Returns the global coordinates given the local coordinates [cm].
446     // Inputs:
447     //   Double_t l[3]   The poistion represented in the detector 
448     //                   local coordinate system
449     // Outputs:
450     //   Double_t g[3]   The poistion represented in the ALICE
451     //                   Global coordinate system
452     // Return:
453     //   none.
454         Int_t    i,j;
455
456         for(i=0;i<3;i++){
457                 g[i] = 0.0;
458                 for(j=0;j<3;j++) g[i] += fm[j][i]*l[j];
459                 g[i] += ftran[i];
460                 // g = R^t l + translation
461         } // end for i
462         return;
463 }
464 //----------------------------------------------------------------------
465 void AliITSgeomMatrix::GtoLMomentum(const Double_t g[3],Double_t l[3]) const{
466     // Returns the local coordinates of the momentum given the global
467     // coordinates of the momentum. It transforms just like GtoLPosition
468     // except that the translation vector is zero.
469     // Inputs:
470     //   Double_t g[3] The momentum represented in the ALICE global 
471     //                 coordinate system
472     // Outputs:
473     //   Double_t l[3] the momentum represented in the detector 
474     //                 local coordinate system
475     // Return:
476     //   none.
477         Int_t    i,j;
478
479         for(i=0;i<3;i++){
480                 l[i] = 0.0;
481                 for(j=0;j<3;j++) l[i] += fm[i][j]*g[j];
482                 // g = R l
483         } // end for i
484         return;
485 }
486 //----------------------------------------------------------------------
487 void AliITSgeomMatrix::LtoGMomentum(const Double_t l[3],Double_t g[3]) const {
488     // Returns the Global coordinates of the momentum given the local
489     // coordinates of the momentum. It transforms just like LtoGPosition
490     // except that the translation vector is zero.
491     // Inputs:
492     //   Double_t l[3] the momentum represented in the detector 
493     //                 local coordinate system
494     // Outputs:
495     //   Double_t g[3] The momentum represented in the ALICE global 
496     //                 coordinate system
497     // Return:
498     //   none.
499         Int_t    i,j;
500
501         for(i=0;i<3;i++){
502                 g[i] = 0.0;
503                 for(j=0;j<3;j++) g[i] += fm[j][i]*l[j];
504                 // g = R^t l
505         } // end for i
506         return;
507 }
508 //----------------------------------------------------------------------
509 void AliITSgeomMatrix::GtoLPositionError(const Double_t g[3][3],
510                                          Double_t l[3][3]) const {
511     // Given an Uncertainty matrix in Global coordinates it is 
512     // rotated so that  its representation in local coordinates can 
513     // be returned. There is no effect due to the translation vector 
514     // or its uncertainty.
515     // Inputs:
516     //   Double_t g[3][3] The error matrix represented in the ALICE global 
517     //                    coordinate system
518     // Outputs:
519     //   Double_t l[3][3] the error matrix represented in the detector 
520     //                    local coordinate system
521     // Return:
522     //   none.
523         Int_t    i,j,k,m;
524
525         for(i=0;i<3;i++)for(m=0;m<3;m++){
526             l[i][m] = 0.0;
527             for(j=0;j<3;j++)for(k=0;k<3;k++)
528                 l[i][m] += fm[j][i]*g[j][k]*fm[k][m];
529         } // end for i,m
530             // g = R^t l R
531         return;
532 }
533 //----------------------------------------------------------------------
534 void AliITSgeomMatrix::LtoGPositionError(const Double_t l[3][3],
535                                                Double_t g[3][3]) const {
536     // Given an Uncertainty matrix in Local coordinates it is rotated so that 
537     // its representation in global coordinates can be returned. There is no
538     // effect due to the translation vector or its uncertainty.
539     // Inputs:
540     //   Double_t l[3][3] the error matrix represented in the detector 
541     //                    local coordinate system
542     // Outputs:
543     //   Double_t g[3][3] The error matrix represented in the ALICE global 
544     //                    coordinate system
545     // Return:
546     //   none.
547         Int_t    i,j,k,m;
548
549         for(i=0;i<3;i++)for(m=0;m<3;m++){
550             g[i][m] = 0.0;
551             for(j=0;j<3;j++)for(k=0;k<3;k++)
552                 g[i][m] += fm[i][j]*l[j][k]*fm[m][k];
553         } // end for i,m
554             // g = R l R^t
555         return;
556 }
557 //----------------------------------------------------------------------
558 void AliITSgeomMatrix::GtoLPositionTracking(const Double_t g[3],
559                                             Double_t l[3]) const {
560     // A slightly different coordinate system is used when tracking.
561     // This coordinate system is only relevant when the geometry represents
562     // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
563     // alone but X -> -Y and Y -> X such that X always points out of the
564     // ITS Cylinder for every layer including layer 1 (where the detector 
565     // are mounted upside down).
566     //Begin_Html
567     /*
568       <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
569     */
570     //End_Html
571     // Inputs:
572     //   Double_t g[3]   The position represented in the ALICE 
573     //                   global coordinate system
574     // Outputs:
575     //   Double_t l[3]  The poistion represented in the local
576     //                  detector coordiante system
577     // Return:
578     //   none
579     Double_t l0[3];
580
581     this->GtoLPosition(g,l0);
582     if(fid[0]==1){ // for layer 1 the detector are flipped upside down
583                    // with respect to the others.
584         l[0] = +l0[1];
585         l[1] = -l0[0];
586         l[2] = +l0[2];
587     }else{
588         l[0] = -l0[1];
589         l[1] = +l0[0];
590         l[2] = +l0[2];
591     } // end if
592     return;
593 }
594 //----------------------------------------------------------------------
595 void AliITSgeomMatrix::LtoGPositionTracking(const Double_t l[3],
596                                             Double_t g[3]) const {
597     // A slightly different coordinate system is used when tracking.
598     // This coordinate system is only relevant when the geometry represents
599     // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
600     // alone but X -> -Y and Y -> X such that X always points out of the
601     // ITS Cylinder for every layer including layer 1 (where the detector 
602     // are mounted upside down).
603     //Begin_Html
604     /*
605       <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
606     */
607     //End_Html
608     // Inputs:
609     //   Double_t l[3]   The poistion represented in the detector 
610     //                   local coordinate system
611     // Outputs:
612     //   Double_t g[3]   The poistion represented in the ALICE
613     //                   Global coordinate system
614     // Return:
615     //   none.
616     Double_t l0[3];
617
618     if(fid[0]==1){ // for layer 1 the detector are flipped upside down
619                    // with respect to the others.
620         l0[0] = -l[1];
621         l0[1] = +l[0];
622         l0[2] = +l[2];
623     }else{
624         l0[0] = +l[1];
625         l0[1] = -l[0];
626         l0[2] = +l[2];
627     } // end if
628     this->LtoGPosition(l0,g);
629     return;
630 }
631 //----------------------------------------------------------------------
632 void AliITSgeomMatrix::GtoLMomentumTracking(const Double_t g[3],
633                                             Double_t l[3]) const {
634     // A slightly different coordinate system is used when tracking.
635     // This coordinate system is only relevant when the geometry represents
636     // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
637     // alone but X -> -Y and Y -> X such that X always points out of the
638     // ITS Cylinder for every layer including layer 1 (where the detector 
639     // are mounted upside down).
640     //Begin_Html
641     /*
642       <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
643     */
644     //End_Html
645     // Inputs:
646     //   Double_t g[3] The momentum represented in the ALICE global 
647     //                 coordinate system
648     // Outputs:
649     //   Double_t l[3] the momentum represented in the detector 
650     //                 local coordinate system
651     // Return:
652     //   none.
653     Double_t l0[3];
654
655     this->GtoLMomentum(g,l0);
656     if(fid[0]==1){ // for layer 1 the detector are flipped upside down
657                    // with respect to the others.
658         l[0] = +l0[1];
659         l[1] = -l0[0];
660         l[2] = +l0[2];
661     }else{
662         l[0] = -l0[1];
663         l[1] = +l0[0];
664         l[2] = +l0[2];
665     } // end if
666     return;
667 }
668 //----------------------------------------------------------------------
669 void AliITSgeomMatrix::LtoGMomentumTracking(const Double_t l[3],
670                                             Double_t g[3]) const {
671     // A slightly different coordinate system is used when tracking.
672     // This coordinate system is only relevant when the geometry represents
673     // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
674     // alone but X -> -Y and Y -> X such that X always points out of the
675     // ITS Cylinder for every layer including layer 1 (where the detector 
676     // are mounted upside down).
677     //Begin_Html
678     /*
679       <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
680     */
681     //End_Html
682     // Inputs:
683     //   Double_t l[3] the momentum represented in the detector 
684     //                 local coordinate system
685     // Outputs:
686     //   Double_t g[3] The momentum represented in the ALICE global 
687     //                 coordinate system
688     // Return:
689     //   none.
690     Double_t l0[3];
691
692     if(fid[0]==1){ // for layer 1 the detector are flipped upside down
693                    // with respect to the others.
694         l0[0] = -l[1];
695         l0[1] = +l[0];
696         l0[2] = +l[2];
697     }else{
698         l0[0] = +l[1];
699         l0[1] = -l[0];
700         l0[2] = +l[2];
701     } // end if
702     this->LtoGMomentum(l0,g);
703         return;
704 }
705 //----------------------------------------------------------------------
706 void AliITSgeomMatrix::GtoLPositionErrorTracking(const Double_t g[3][3],
707                                                  Double_t l[3][3]) const {
708     // A slightly different coordinate system is used when tracking.
709     // This coordinate system is only relevant when the geometry represents
710     // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
711     // alone but X -> -Y and Y -> X such that X always points out of the
712     // ITS Cylinder for every layer including layer 1 (where the detector 
713     // are mounted upside down).
714     //Begin_Html
715     /*
716       <img src="picts/ITS/AliITSgeomMatrix_TE1.gif">
717     */
718     //End_Html
719     // Inputs:
720     //   Double_t g[3][3] The error matrix represented in the ALICE global 
721     //                    coordinate system
722     // Outputs:
723     //   Double_t l[3][3] the error matrix represented in the detector 
724     //                    local coordinate system
725     // Return:
726         Int_t    i,j,k,m;
727         Double_t rt[3][3];
728         Double_t a0[3][3] = {{0.,+1.,0.},{-1.,0.,0.},{0.,0.,+1.}};
729         Double_t a1[3][3] = {{0.,-1.,0.},{+1.,0.,0.},{0.,0.,+1.}};
730
731         if(fid[0]==1) for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
732             rt[i][k] = a0[i][j]*fm[j][k];
733         else for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
734             rt[i][k] = a1[i][j]*fm[j][k];
735         for(i=0;i<3;i++)for(m=0;m<3;m++){
736             l[i][m] = 0.0;
737             for(j=0;j<3;j++)for(k=0;k<3;k++)
738                 l[i][m] += rt[j][i]*g[j][k]*rt[k][m];
739         } // end for i,m
740             // g = R^t l R
741         return;
742 }
743 //----------------------------------------------------------------------
744 void AliITSgeomMatrix::LtoGPositionErrorTracking(const Double_t l[3][3],
745                                                  Double_t g[3][3]) const {
746     // A slightly different coordinate system is used when tracking.
747     // This coordinate system is only relevant when the geometry represents
748     // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
749     // alone but X -> -Y and Y -> X such that X always points out of the
750     // ITS Cylinder for every layer including layer 1 (where the detector 
751     // are mounted upside down).
752     //Begin_Html
753     /*
754       <img src="picts/ITS/AliITSgeomMatrix_TE1.gif">
755     */
756     //End_Html
757     // Inputs:
758     //   Double_t l[3][3] the error matrix represented in the detector 
759     //                    local coordinate system
760     // Outputs:
761     //   Double_t g[3][3] The error matrix represented in the ALICE global 
762     //                    coordinate system
763     // Return:
764     //   none.
765         Int_t    i,j,k,m;
766         Double_t rt[3][3];
767         Double_t a0[3][3] = {{0.,+1.,0.},{-1.,0.,0.},{0.,0.,+1.}};
768         Double_t a1[3][3] = {{0.,-1.,0.},{+1.,0.,0.},{0.,0.,+1.}};
769
770         if(fid[0]==1) for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
771             rt[i][k] = a0[i][j]*fm[j][k];
772         else for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
773             rt[i][k] = a1[i][j]*fm[j][k];
774         for(i=0;i<3;i++)for(m=0;m<3;m++){
775             g[i][m] = 0.0;
776             for(j=0;j<3;j++)for(k=0;k<3;k++)
777                 g[i][m] += rt[i][j]*l[j][k]*rt[m][k];
778         } // end for i,m
779             // g = R l R^t
780         return;
781 }
782 //----------------------------------------------------------------------
783 void AliITSgeomMatrix::PrintTitles(ostream *os) const {
784     // Standard output format for this class but it includes variable
785     // names and formatting that makes it easer to read.
786     // Inputs:
787     //    ostream *os   The output stream to print the title on
788     // Outputs:
789     //    none.
790     // Return:
791     //    none.
792     Int_t i,j;
793
794     *os << "fDetectorIndex=" << fDetectorIndex << " fid[3]={";
795     for(i=0;i<3;i++) *os << fid[i]   << " ";
796     *os << "} frot[3]={";
797     for(i=0;i<3;i++) *os << frot[i]  << " ";
798     *os << "} ftran[3]={";
799     for(i=0;i<3;i++) *os << ftran[i] << " ";
800     *os << "} fm[3][3]={";
801     for(i=0;i<3;i++){for(j=0;j<3;j++){  *os << fm[i][j] << " ";} *os <<"}{";}
802     *os << "}" << endl;
803     return;
804 }
805 //----------------------------------------------------------------------
806 void AliITSgeomMatrix::PrintComment(ostream *os) const {
807     //  output format used by Print.
808     // Inputs:
809     //    ostream *os   The output stream to print the comments on
810     // Outputs:
811     //    none.
812     // Return:
813     //    none.
814     *os << "fDetectorIndex fid[0] fid[1] fid[2] ftran[0] ftran[1] ftran[2] ";
815     *os << "fm[0][0]  fm[0][1]  fm[0][2]  fm[1][0]  fm[1][1]  fm[1][2]  ";
816     *os << "fm[2][0]  fm[2][1]  fm[2][2] ";
817     return;
818 }
819 //----------------------------------------------------------------------
820 void AliITSgeomMatrix::Print(ostream *os)const{
821     // Standard output format for this class.
822     // Inputs:
823     //    ostream *os   The output stream to print the class data on
824     // Outputs:
825     //    none.
826     // Return:
827     //    none.
828     Int_t i,j;
829 #if defined __GNUC__
830 #if __GNUC__ > 2
831     ios::fmtflags fmt;
832 #else
833     Int_t fmt;
834 #endif
835 #else
836 #if defined __ICC || defined __ECC || defined __xlC__
837     ios::fmtflags fmt;
838 #else
839     Int_t fmt;
840 #endif
841 #endif
842
843     fmt = os->setf(ios::scientific);  // set scientific floating point output
844     *os << fDetectorIndex << " ";
845     for(i=0;i<3;i++) *os << fid[i]   << " ";
846 //    for(i=0;i<3;i++) *os << frot[i]  << " ";  // Redundant with fm[][].
847     for(i=0;i<3;i++) *os << setprecision(16) << ftran[i] << " ";
848     for(i=0;i<3;i++)for(j=0;j<3;j++)  *os << setprecision(16) << 
849                                           fm[i][j] << " ";
850     *os << fPath.Length()<< " ";
851     for(i=0;i<fPath.Length();i++) *os << fPath[i];
852     *os << endl;
853     os->flags(fmt); // reset back to old formating.
854     return;
855 }
856 //----------------------------------------------------------------------
857 void AliITSgeomMatrix::Read(istream *is){
858     // Standard input format for this class.
859     // Inputs:
860     //    istream *is   The input stream to read on
861     // Outputs:
862     //    none.
863     // Return:
864     //    none.
865     Int_t i,j;
866
867     *is >> fDetectorIndex;
868     for(i=0;i<3;i++) *is >> fid[i];
869 //    for(i=0;i<3;i++) *is >> frot[i]; // Redundant with fm[][].
870     for(i=0;i<3;i++) *is >> ftran[i];
871     for(i=0;i<3;i++)for(j=0;j<3;j++)  *is >> fm[i][j];
872     while(is->peek()==' ')is->get(); // skip white spaces
873     if(isprint(is->peek())){ // old format did not have path.
874         *is >> j; // string length
875         fPath.Resize(j);
876         for(i=0;i<j;i++) {*is >> fPath[i];}
877     } // end if
878     AngleFromMatrix(); // compute angles frot[].
879     fCylR   = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
880     fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
881     if(fCylPhi<0.0) fCylPhi += TMath::Pi();
882     return;
883 }
884 //______________________________________________________________________
885 void AliITSgeomMatrix::Streamer(TBuffer &R__b){
886    // Stream an object of class AliITSgeomMatrix.
887     // Inputs:
888     //     TBuffer &R__b   The output buffer to stream data on.
889     // Outputs:
890     //    none.
891     // Return:
892     //    none.
893
894     if (R__b.IsReading()) {
895         AliITSgeomMatrix::Class()->ReadBuffer(R__b, this);
896         fCylR   = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
897         fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
898         this->AngleFromMatrix();
899         if(fCylPhi<0.0) fCylPhi += TMath::Pi();
900     } else {
901         AliITSgeomMatrix::Class()->WriteBuffer(R__b, this);
902     } // end if
903 }
904 //______________________________________________________________________
905 void AliITSgeomMatrix::SetTranslation(const Double_t tran[3]){
906     // Sets the translation vector and computes fCylR and fCylPhi.
907     // Inputs:
908     //   Double_t trans[3]   The translation vector to be used
909     // Outputs:
910     //   none.
911     // Return:
912     //   none.
913     for(Int_t i=0;i<3;i++) ftran[i] = tran[i];
914     fCylR   = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
915     fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
916     if(fCylPhi<0.0) fCylPhi += TMath::Pi();
917 }
918 //----------------------------------------------------------------------
919 TPolyLine3D* AliITSgeomMatrix::CreateLocalAxis() const {
920     // This class is used as part of the documentation of this class
921     // Inputs:
922     //   none.
923     // Outputs:
924     //   none.
925     // Return:
926     //   A pointer to a new TPolyLine3D object showing the 3 line
927     //   segments that make up the this local axis in the global
928     //   reference system.
929     Float_t  gf[15];
930     Double_t g[5][3];
931     Double_t l[5][3]={{1.0,0.0,0.0},{0.0,0.0,0.0},{0.0,1.0,0.0},{0.0,0.0,0.0},
932                       {0.0,0.0,1.0}};
933     Int_t i;
934
935     for(i=0;i<5;i++) {
936         LtoGPosition(l[i],g[i]);
937         gf[3*i]=(Float_t)g[i][0];
938         gf[3*i+1]=(Float_t)g[i][1];
939         gf[3*i+2]=(Float_t)g[i][2];
940     } // end for i
941     return new TPolyLine3D(5,gf);
942 }
943 //----------------------------------------------------------------------
944 TPolyLine3D* AliITSgeomMatrix::CreateLocalAxisTracking() const {
945     // This class is used as part of the documentation of this class
946     // Inputs:
947     //   none.
948     // Outputs:
949     //   none.
950     // Return:
951     //   A pointer to a new TPolyLine3D object showing the 3 line
952     //   segments that make up the this local axis in the global
953     //   reference system.
954     Float_t gf[15];
955     Double_t g[5][3];
956     Double_t l[5][3]={{1.0,0.0,0.0},{0.0,0.0,0.0},{0.0,1.0,0.0},{0.0,0.0,0.0},
957                       {0.0,0.0,1.0}};
958     Int_t i;
959
960     for(i=0;i<5;i++) {
961         LtoGPositionTracking(l[i],g[i]);
962         gf[3*i]=(Float_t)g[i][0];
963         gf[3*i+1]=(Float_t)g[i][1];
964         gf[3*i+2]=(Float_t)g[i][2];
965     } // end for i
966     return new TPolyLine3D(5,gf);
967 }
968 //----------------------------------------------------------------------
969 TNode* AliITSgeomMatrix::CreateNode(const Char_t *nodeName,
970                                     const Char_t *nodeTitle,TNode *mother,
971                                     TShape *shape,Bool_t axis) const {
972     // Creates a node inside of the node mother out of the shape shape
973     // in the position, with respect to mother, indecated by "this". If axis
974     // is ture, it will insert an axis within this node/shape.
975     // Inputs:
976     //   Char_t *nodeName  This name of this node
977     //   Char_t *nodeTitle This node title
978     //   TNode  *mother    The node this node will be inside of/with respect to
979     //   TShape *shape     The shape of this node
980     //   Bool_t axis       If ture, a set of x,y,z axis will be included
981     // Outputs:
982     //   none.
983     // Return:
984     //   A pointer to "this" node.
985     Double_t trans[3],matrix[3][3],*matr;
986     TRotMatrix *rot = new TRotMatrix();
987     TString name,title;
988
989     matr = &(matrix[0][0]);
990     this->GetTranslation(trans);
991     this->GetMatrix(matrix);
992     rot->SetMatrix(matr);
993     //
994     name = nodeName;
995     title = nodeTitle;
996     //
997     mother->cd();
998     TNode *node1 = new TNode(name.Data(),title.Data(),shape,trans[0],trans[1],trans[2],rot);
999     if(axis){
1000         Int_t i,j;
1001         const Float_t kScale=0.5,kLw=0.2;
1002         Float_t xchar[13][2]={{0.5*kLw,1.},{0.,0.5*kLw},{0.5-0.5*kLw,0.5},
1003                               {0.,0.5*kLw},{0.5*kLw,0.},{0.5,0.5-0.5*kLw},
1004                               {1-0.5*kLw,0.},{1.,0.5*kLw},{0.5+0.5*kLw,0.5},
1005                               {1.,1.-0.5*kLw},{1.-0.5*kLw,1.},{0.5,0.5+0.5*kLw},
1006                               {0.5*kLw,1.}};
1007         Float_t ychar[10][2]={{.5-0.5*kLw,0.},{.5+0.5*kLw,0.},{.5+0.5*kLw,0.5-0.5*kLw},
1008                               {1.,1.-0.5*kLw},{1.-0.5*kLw,1.},{0.5+0.5*kLw,0.5},
1009                               {0.5*kLw,1.}   ,{0.,1-0.5*kLw} ,{0.5-0.5*kLw,0.5},
1010                               {.5-0.5*kLw,0.}};
1011         Float_t zchar[11][2]={{0.,1.},{0,1.-kLw},{1.-kLw,1.-kLw},{0.,kLw}   ,{0.,0.},
1012                               {1.,0.},{1.,kLw}  ,{kLw,kLw}      ,{1.,1.-kLw},{1.,1.},
1013                               {0.,1.}};
1014         for(i=0;i<13;i++)for(j=0;j<2;j++){
1015             if(i<13) xchar[i][j] = kScale*xchar[i][j];
1016             if(i<10) ychar[i][j] = kScale*ychar[i][j];
1017             if(i<11) zchar[i][j] = kScale*zchar[i][j];
1018         } // end for i,j
1019         TXTRU *axisxl = new TXTRU("x","x","text",12,2);
1020         for(i=0;i<12;i++) axisxl->DefineVertex(i,xchar[i][0],xchar[i][1]);
1021         axisxl->DefineSection(0,-0.5*kLw);axisxl->DefineSection(1,0.5*kLw);
1022         TXTRU *axisyl = new TXTRU("y","y","text",9,2);
1023         for(i=0;i<9;i++) axisyl->DefineVertex(i,ychar[i][0],ychar[i][1]);
1024         axisyl->DefineSection(0,-0.5*kLw);axisyl->DefineSection(1,0.5*kLw);
1025         TXTRU *axiszl = new TXTRU("z","z","text",10,2);
1026         for(i=0;i<10;i++) axiszl->DefineVertex(i,zchar[i][0],zchar[i][1]);
1027         axiszl->DefineSection(0,-0.5*kLw);axiszl->DefineSection(1,0.5*kLw);
1028         Float_t lxy[13][2]={{-0.5*kLw,-0.5*kLw},{0.8,-0.5*kLw},{0.8,-0.1},{1.0,0.0},
1029                             {0.8,0.1},{0.8,0.5*kLw},{0.5*kLw,0.5*kLw},{0.5*kLw,0.8},
1030                             {0.1,0.8},{0.0,1.0},{-0.1,0.8},{-0.5*kLw,0.8},
1031                             {-0.5*kLw,-0.5*kLw}};
1032         TXTRU *axisxy = new TXTRU("axisxy","axisxy","text",13,2);
1033         for(i=0;i<13;i++) axisxy->DefineVertex(i,lxy[i][0],lxy[i][1]);
1034         axisxy->DefineSection(0,-0.5*kLw);axisxy->DefineSection(1,0.5*kLw);
1035         Float_t lz[8][2]={{0.5*kLw,-0.5*kLw},{0.8,-0.5*kLw},{0.8,-0.1},{1.0,0.0},
1036                            {0.8,0.1},{0.8,0.5*kLw},{0.5*kLw,0.5*kLw},
1037                            {0.5*kLw,-0.5*kLw}};
1038         TXTRU *axisz = new TXTRU("axisz","axisz","text",8,2);
1039         for(i=0;i<8;i++) axisz->DefineVertex(i,lz[i][0],lz[i][1]);
1040         axisz->DefineSection(0,-0.5*kLw);axisz->DefineSection(1,0.5*kLw);
1041         //TRotMatrix *xaxis90= new TRotMatrix("xaixis90","",90.0, 0.0, 0.0);
1042         TRotMatrix *yaxis90= new TRotMatrix("yaixis90","", 0.0,90.0, 0.0);
1043         TRotMatrix *zaxis90= new TRotMatrix("zaixis90","", 0.0, 0.0,90.0);
1044         //
1045         node1->cd();
1046         title = name.Append("axisxy");
1047         TNode *nodeaxy = new TNode(title.Data(),title.Data(),axisxy);
1048         title = name.Append("axisz");
1049         TNode *nodeaz = new TNode(title.Data(),title.Data(),axisz,0.,0.,0.,yaxis90);
1050         TNode *textboxX0 = new TNode("textboxX0","textboxX0",axisxl,
1051                                     lxy[3][0],lxy[3][1],0.0);
1052         TNode *textboxX1 = new TNode("textboxX1","textboxX1",axisxl,
1053                                     lxy[3][0],lxy[3][1],0.0,yaxis90);
1054         TNode *textboxX2 = new TNode("textboxX2","textboxX2",axisxl,
1055                                     lxy[3][0],lxy[3][1],0.0,zaxis90);
1056         TNode *textboxY0 = new TNode("textboxY0","textboxY0",axisyl,
1057                                     lxy[9][0],lxy[9][1],0.0);
1058         TNode *textboxY1 = new TNode("textboxY1","textboxY1",axisyl,
1059                                     lxy[9][0],lxy[9][1],0.0,yaxis90);
1060         TNode *textboxY2 = new TNode("textboxY2","textboxY2",axisyl,
1061                                     lxy[9][0],lxy[9][1],0.0,zaxis90);
1062         TNode *textboxZ0 = new TNode("textboxZ0","textboxZ0",axiszl,
1063                                     0.0,0.0,lz[3][0]);
1064         TNode *textboxZ1 = new TNode("textboxZ1","textboxZ1",axiszl,
1065                                     0.0,0.0,lz[3][0],yaxis90);
1066         TNode *textboxZ2 = new TNode("textboxZ2","textboxZ2",axiszl,
1067                                     0.0,0.0,lz[3][0],zaxis90);
1068         nodeaxy->Draw();
1069         nodeaz->Draw();
1070         textboxX0->Draw();
1071         textboxX1->Draw();
1072         textboxX2->Draw();
1073         textboxY0->Draw();
1074         textboxY1->Draw();
1075         textboxY2->Draw();
1076         textboxZ0->Draw();
1077         textboxZ1->Draw();
1078         textboxZ2->Draw();
1079     } // end if
1080     mother->cd();
1081     return node1;
1082 }
1083 //----------------------------------------------------------------------
1084 void AliITSgeomMatrix::MakeFigures() const {
1085     // make figures to help document this class
1086     // Inputs:
1087     //   none.
1088     // Outputs:
1089     //   none.
1090     // Return:
1091     //   none.
1092     const Double_t kDx0=550.,kDy0=550.,kDz0=550.; // cm
1093     const Double_t kDx=1.0,kDy=0.300,kDz=3.0,kRmax=0.1; // cm
1094     Float_t l[5][3]={{1.0,0.0,0.0},{0.0,0.0,0.0},{0.0,1.0,0.0},{0.0,0.0,0.0},
1095                       {0.0,0.0,1.0}};
1096     TCanvas *c = new TCanvas(kFALSE);// create a batch mode canvas.
1097     TView   *view = new TView(1); // Create Cartesian coordiante view
1098     TBRIK   *mother  = new TBRIK("Mother","Mother","void",kDx0,kDy0,kDz0);
1099     TBRIK   *det  = new TBRIK("Detector","","Si",kDx,kDy,kDz);
1100     TPolyLine3D *axis = new TPolyLine3D(5,&(l[0][0]));
1101     TPCON *arrow      = new TPCON("arrow","","air",0.0,360.,2);
1102     TRotMatrix *xarrow= new TRotMatrix("xarrow","",90.,0.0,0.0);
1103     TRotMatrix *yarrow= new TRotMatrix("yarrow","",0.0,90.,0.0);
1104
1105     det->SetLineColor(0); // black
1106     det->SetLineStyle(1); // solid line
1107     det->SetLineWidth(2); // pixel units
1108     det->SetFillColor(1); // black
1109     det->SetFillStyle(4010); // window is 90% transparent
1110     arrow->SetLineColor(det->GetLineColor());
1111     arrow->SetLineWidth(det->GetLineWidth());
1112     arrow->SetLineStyle(det->GetLineStyle());
1113     arrow->SetFillColor(1); // black
1114     arrow->SetFillStyle(4100); // window is 100% opaque
1115     arrow->DefineSection(0,0.0,0.0,kRmax);
1116     arrow->DefineSection(1,2.*kRmax,0.0,0.0);
1117     view->SetRange(-kDx0,-kDy0,-kDz0,kDx0,kDy0,kDz0);
1118     //
1119     TNode *node0 = new TNode("NODE0","NODE0",mother);
1120     node0->cd();
1121     TNode *node1 = new TNode("NODE1","NODE1",det);
1122     node1->cd();
1123     TNode *nodex = new TNode("NODEx","NODEx",arrow,l[0][0],l[0][1],l[0][2],xarrow);
1124     TNode *nodey = new TNode("NODEy","NODEy",arrow,l[2][0],l[2][1],l[2][2],yarrow);
1125     TNode *nodez = new TNode("NODEz","NODEz",arrow,l[4][0],l[4][1],l[4][2]);
1126     //
1127     axis->Draw();
1128     nodex->Draw();
1129     nodey->Draw();
1130     nodez->Draw();
1131     
1132     //
1133     node0->cd();
1134     node0->Draw();
1135     c->Update();
1136     c->SaveAs("AliITSgeomMatrix_L1.gif");
1137 }
1138 //----------------------------------------------------------------------
1139 ostream &operator<<(ostream &os,AliITSgeomMatrix &p){
1140     // Standard output streaming function.
1141     // Inputs:
1142     //    ostream &os          The output stream to print the class data on
1143     //    AliITSgeomMatrix &p  This class
1144     // Outputs:
1145     //    none.
1146     // Return:
1147     //    none.
1148
1149     p.Print(&os);
1150     return os;
1151 }
1152 //----------------------------------------------------------------------
1153 istream &operator>>(istream &is,AliITSgeomMatrix &r){
1154     // Standard input streaming function.
1155     // Inputs:
1156     //    ostream &os          The input stream to print the class data on
1157     //    AliITSgeomMatrix &p  This class
1158     // Outputs:
1159     //    none.
1160     // Return:
1161     //    none.
1162
1163     r.Read(&is);
1164     return is;
1165 }
1166 //----------------------------------------------------------------------