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