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