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