1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
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 ////////////////////////////////////////////////////////////////////////
29 #include <Riostream.h>
34 #include <TPolyLine3D.h>
40 #include "AliITSgeomMatrix.h"
42 ClassImp(AliITSgeomMatrix)
43 //----------------------------------------------------------------------
44 AliITSgeomMatrix::AliITSgeomMatrix():
46 fDetectorIndex(0), // Detector type index (like fShapeIndex was)
47 fid(), // layer, ladder, detector numbers.
48 frot(), //! vector of rotations about x,y,z [radians].
49 ftran(), // Translation vector of module x,y,z.
50 fCylR(0.0), //! R Translation in Cylinderical coordinates
51 fCylPhi(0.0),//! Phi Translation vector in Cylindrical coord.
52 fm(), // Rotation matrix based on frot.
53 fPath(){ // Path in geometry to this module
54 // The Default constructor for the AliITSgeomMatrix class. By Default
55 // the angles of rotations are set to zero, meaning that the rotation
56 // matrix is the unit matrix. The translation vector is also set to
57 // zero as are the module id number. The detector type is set to -1
58 // (an undefined value). The full rotation matrix is kept so that
59 // the evaluation of a coordinate transformation can be done
60 // quickly and with a minimum of CPU overhead. The basic coordinate
61 // systems are the ALICE global coordinate system and the detector
62 // local coordinate system. In general this structure is not limited
63 // to just those two coordinate systems.
66 <img src="picts/ITS/AliITSgeomMatrix_L1.gif">
74 // A default constructes AliITSgeomMatrix class.
77 fDetectorIndex = -1; // a value never defined.
80 frot[i] = ftran[i] = 0.0;
81 for(j=0;j<3;j++) fm[i][j] = 0.0;
82 fCylR = fCylPhi = 0.0;
84 fm[0][0] = fm[1][1] = fm[2][2] = 1.0;
87 //----------------------------------------------------------------------
88 AliITSgeomMatrix::AliITSgeomMatrix(const AliITSgeomMatrix &source) :
90 fDetectorIndex(source.fDetectorIndex),
92 fCylPhi(source.fCylPhi),
94 // The standard Copy constructor. This make a full / proper copy of
97 // AliITSgeomMatrix &source The source of this copy
101 // A copy constructes AliITSgeomMatrix class.
104 this->fid[i] = source.fid[i];
105 this->frot[i] = source.frot[i];
106 this->ftran[i] = source.ftran[i];
107 for(j=0;j<3;j++) this->fm[i][j] = source.fm[i][j];
110 //----------------------------------------------------------------------
111 AliITSgeomMatrix& AliITSgeomMatrix::operator=(const AliITSgeomMatrix &source){
112 // The standard = operator. This make a full / proper copy of
114 // The standard Copy constructor. This make a full / proper copy of
117 // AliITSgeomMatrix &source The source of this copy
121 // A copy of the source AliITSgeomMatrix class.
122 if(this == &source)return *this;
125 this->fDetectorIndex = source.fDetectorIndex;
126 this->fCylR = source.fCylR;
127 this->fCylPhi = source.fCylPhi;
129 this->fid[i] = source.fid[i];
130 this->frot[i] = source.frot[i];
131 this->ftran[i] = source.ftran[i];
133 for(j=0;j<3;j++) this->fm[i][j] = source.fm[i][j];
135 this->fPath = source.fPath;
139 //----------------------------------------------------------------------
140 AliITSgeomMatrix::AliITSgeomMatrix(Int_t idt,const Int_t id[3],
141 const Double_t rot[3],const Double_t tran[3]):
143 fDetectorIndex(idt), // Detector type index (like fShapeIndex was)
144 fid(), // layer, ladder, detector numbers.
145 frot(), //! vector of rotations about x,y,z [radians].
146 ftran(), // Translation vector of module x,y,z.
147 fCylR(0.0), //! R Translation in Cylinderical coordinates
148 fCylPhi(0.0),//! Phi Translation vector in Cylindrical coord.
149 fm(), // Rotation matrix based on frot.
150 fPath(){ // Path in geometry to this moduel
151 // This is a constructor for the AliITSgeomMatrix class. The matrix is
152 // defined by 3 standard rotation angles [radians], and the translation
153 // vector tran [cm]. In addition the layer, ladder, and detector number
154 // for this particular module and the type of module must be given.
155 // The full rotation matrix is kept so that the evaluation
156 // of a coordinate transformation can be done quickly and with a minimum
157 // of CPU overhead. The basic coordinate systems are the ALICE global
158 // coordinate system and the detector local coordinate system. In general
159 // this structure is not limited to just those two coordinate systems.
162 <img src="picts/ITS/AliITSgeomMatrix_L1.gif">
166 // Int_t idt The detector index value
167 // Int_t id[3] The layer, ladder, and detector numbers
168 // Double_t rot[3] The 3 Cartician rotaion angles [radians]
169 // Double_t tran[3] The 3 Cartician translation distnaces
173 // A properly inilized AliITSgeomMatrix class.
181 fCylR = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
182 fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
183 if(fCylPhi<0.0) fCylPhi += TMath::Pi();
184 this->MatrixFromAngle();
186 //----------------------------------------------------------------------
187 AliITSgeomMatrix::AliITSgeomMatrix(Int_t idt, const Int_t id[3],
188 Double_t matrix[3][3],
189 const Double_t tran[3]):
191 fDetectorIndex(idt), // Detector type index (like fShapeIndex was)
192 fid(), // layer, ladder, detector numbers.
193 frot(), //! vector of rotations about x,y,z [radians].
194 ftran(), // Translation vector of module x,y,z.
195 fCylR(0.0), //! R Translation in Cylinderical coordinates
196 fCylPhi(0.0),//! Phi Translation vector in Cylindrical coord.
197 fm(), // Rotation matrix based on frot.
198 fPath(){ // Path in geometry to this module
199 // This is a constructor for the AliITSgeomMatrix class. The
200 // rotation matrix is given as one of the inputs, and the
201 // translation vector tran [cm]. In addition the layer, ladder,
202 // and detector number for this particular module and the type of
203 // module must be given. The full rotation matrix is kept so that
204 // the evaluation of a coordinate transformation can be done quickly
205 // and with a minimum of CPU overhead. The basic coordinate systems
206 // are the ALICE global coordinate system and the detector local
207 // coordinate system. In general this structure is not limited to just
208 // those two coordinate systems.
211 <img src="picts/ITS/AliITSgeomMatrix_L1.gif">
215 // Int_t idt The detector index value
216 // Int_t id[3] The layer, ladder, and detector numbers
217 // Double_t rot[3][3] The 3x3 Cartician rotaion matrix
218 // Double_t tran[3] The 3 Cartician translation distnaces
222 // A properly inilized AliITSgeomMatrix class.
228 for(j=0;j<3;j++) fm[i][j] = matrix[i][j];
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();
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.
242 // Double_t ang[6] The 6 Geant3.21 rotation angles. [degrees]
245 Double_t si,c=180./TMath::Pi();
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]);
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]);
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]);
262 for(Int_t i=0;i<6;i++) {ang[i] *= c; if(ang[i]<0.0) ang[i] += 360.;}
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
271 // Double_t ang[6] The 6 Geant3.21 rotation angles. [degrees]
277 Double_t si,lr[9],c=TMath::Pi()/180.;
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;
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;
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.
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];
318 this->AngleFromMatrix();
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]):
329 // This is a constructor for the AliITSgeomMatrix class. The matrix
330 // is defined by the 6 GEANT 3.21 rotation angles [degrees], and
331 // the translation vector tran [cm]. In addition the layer, ladder,
332 // and detector number for this particular module and the type of
333 // module must be given. The full rotation matrix is kept so that
334 // the evaluation of a coordinate transformation can be done
335 // quickly and with a minimum of CPU overhead. The basic coordinate
336 // systems are the ALICE global coordinate system and the detector
337 // local coordinate system. In general this structure is not limited
338 // to just those two coordinate systems.
341 <img src="picts/ITS/AliITSgeomMatrix_L1.gif">
345 // Double_t rotd[6] The 6 Geant 3.21 rotation angles [degrees]
346 // Int_t idt The module Id number
347 // Int_t id[3] The layer, ladder and detector number
348 // Double_t tran[3] The translation vector
355 fCylR = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
356 fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
357 if(fCylPhi<0.0) fCylPhi += TMath::Pi();
358 this->MatrixFromSixAngles(rotd);
361 //----------------------------------------------------------------------
362 void AliITSgeomMatrix::AngleFromMatrix(){
363 // Computes the angles from the rotation matrix up to a phase of
364 // 180 degrees. The matrix used in AliITSgeomMatrix::MatrixFromAngle()
365 // and its inverse AliITSgeomMatrix::AngleFromMatrix() are defined in
366 // the following ways, R = Rz*Ry*Rx (M=R*L+T) where
367 // 1 0 0 Cy 0 +Sy Cz -Sz 0
368 // Rx= 0 Cx -Sx Ry= 0 1 0 Rz=+Sz Cz 0
369 // 0 +Sx Cx -Sy 0 Cy 0 0 1
370 // The choice of the since of S, comes from the choice between
371 // the rotation of the object or the coordinate system (view). I think
372 // that this choice is the first, the rotation of the object.
380 // get angles from matrix up to a phase of 180 degrees.
382 rx = TMath::ATan2(fm[2][1],fm[2][2]);if(rx<0.0) rx += 2.0*TMath::Pi();
383 ry = TMath::ASin(-fm[0][2]); if(ry<0.0) ry += 2.0*TMath::Pi();
384 rz = TMath::ATan2(fm[1][0],fm[0][0]);if(rz<0.0) rz += 2.0*TMath::Pi();
391 //----------------------------------------------------------------------
392 void AliITSgeomMatrix::MatrixFromAngle(){
393 // Computes the Rotation matrix from the angles [radians] kept in this
394 // class. The matrix used in AliITSgeomMatrix::MatrixFromAngle() and
395 // its inverse AliITSgeomMatrix::AngleFromMatrix() are defined in
396 // the following ways, R = Rz*Ry*Rx (M=R*L+T) where
397 // 1 0 0 Cy 0 +Sy Cz -Sz 0
398 // Rx= 0 Cx -Sx Ry= 0 1 0 Rz=+Sz Cz 0
399 // 0 +Sx Cx -Sy 0 Cy 0 0 1
400 // The choice of the since of S, comes from the choice between
401 // the rotation of the object or the coordinate system (view). I think
402 // that this choice is the first, the rotation of the object.
409 Double_t sx,sy,sz,cx,cy,cz;
411 sx = TMath::Sin(frot[0]); cx = TMath::Cos(frot[0]);
412 sy = TMath::Sin(frot[1]); cy = TMath::Cos(frot[1]);
413 sz = TMath::Sin(frot[2]); cz = TMath::Cos(frot[2]);
414 fm[0][0] = +cz*cy; // fr[0]
415 fm[0][1] = +cz*sy*sx - sz*cx; // fr[1]
416 fm[0][2] = +cz*sy*cx + sz*sx; // fr[2]
417 fm[1][0] = +sz*cy; // fr[3]
418 fm[1][1] = +sz*sy*sx + cz*cx; // fr[4]
419 fm[1][2] = +sz*sy*cx - cz*sx; // fr[5]
420 fm[2][0] = -sy; // fr[6]
421 fm[2][1] = +cy*sx; // fr[7]
422 fm[2][2] = +cy*cx; // fr[8]
426 //----------------------------------------------------------------------
427 void AliITSgeomMatrix::GtoLPosition(const Double_t g0[3],Double_t l[3]) const {
428 // Returns the local coordinates given the global coordinates [cm].
430 // Double_t g[3] The position represented in the ALICE
431 // global coordinate system
433 // Double_t l[3] The poistion represented in the local
434 // detector coordiante system
440 for(i=0;i<3;i++) g[i] = g0[i] - ftran[i];
443 for(j=0;j<3;j++) l[i] += fm[i][j]*g[j];
444 // g = R l + translation
448 //----------------------------------------------------------------------
449 void AliITSgeomMatrix::LtoGPosition(const Double_t l[3],Double_t g[3]) const {
450 // Returns the global coordinates given the local coordinates [cm].
452 // Double_t l[3] The poistion represented in the detector
453 // local coordinate system
455 // Double_t g[3] The poistion represented in the ALICE
456 // Global coordinate system
463 for(j=0;j<3;j++) g[i] += fm[j][i]*l[j];
465 // g = R^t l + translation
469 //----------------------------------------------------------------------
470 void AliITSgeomMatrix::GtoLMomentum(const Double_t g[3],Double_t l[3]) const{
471 // Returns the local coordinates of the momentum given the global
472 // coordinates of the momentum. It transforms just like GtoLPosition
473 // except that the translation vector is zero.
475 // Double_t g[3] The momentum represented in the ALICE global
478 // Double_t l[3] the momentum represented in the detector
479 // local coordinate system
486 for(j=0;j<3;j++) l[i] += fm[i][j]*g[j];
491 //----------------------------------------------------------------------
492 void AliITSgeomMatrix::LtoGMomentum(const Double_t l[3],Double_t g[3]) const {
493 // Returns the Global coordinates of the momentum given the local
494 // coordinates of the momentum. It transforms just like LtoGPosition
495 // except that the translation vector is zero.
497 // Double_t l[3] the momentum represented in the detector
498 // local coordinate system
500 // Double_t g[3] The momentum represented in the ALICE global
508 for(j=0;j<3;j++) g[i] += fm[j][i]*l[j];
513 //----------------------------------------------------------------------
514 void AliITSgeomMatrix::GtoLPositionError(const Double_t g[3][3],
515 Double_t l[3][3]) const {
516 // Given an Uncertainty matrix in Global coordinates it is
517 // rotated so that its representation in local coordinates can
518 // be returned. There is no effect due to the translation vector
519 // or its uncertainty.
521 // Double_t g[3][3] The error matrix represented in the ALICE global
524 // Double_t l[3][3] the error matrix represented in the detector
525 // local coordinate system
530 for(i=0;i<3;i++)for(m=0;m<3;m++){
532 for(j=0;j<3;j++)for(k=0;k<3;k++)
533 l[i][m] += fm[j][i]*g[j][k]*fm[k][m];
538 //----------------------------------------------------------------------
539 void AliITSgeomMatrix::LtoGPositionError(const Double_t l[3][3],
540 Double_t g[3][3]) const {
541 // Given an Uncertainty matrix in Local coordinates it is rotated so that
542 // its representation in global coordinates can be returned. There is no
543 // effect due to the translation vector or its uncertainty.
545 // Double_t l[3][3] the error matrix represented in the detector
546 // local coordinate system
548 // Double_t g[3][3] The error matrix represented in the ALICE global
554 for(i=0;i<3;i++)for(m=0;m<3;m++){
556 for(j=0;j<3;j++)for(k=0;k<3;k++)
557 g[i][m] += fm[i][j]*l[j][k]*fm[m][k];
562 //----------------------------------------------------------------------
563 void AliITSgeomMatrix::GtoLPositionTracking(const Double_t g[3],
564 Double_t l[3]) const {
565 // A slightly different coordinate system is used when tracking.
566 // This coordinate system is only relevant when the geometry represents
567 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
568 // alone but X -> -Y and Y -> X such that X always points out of the
569 // ITS Cylinder for every layer including layer 1 (where the detector
570 // are mounted upside down).
573 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
577 // Double_t g[3] The position represented in the ALICE
578 // global coordinate system
580 // Double_t l[3] The poistion represented in the local
581 // detector coordiante system
586 this->GtoLPosition(g,l0);
587 if(fid[0]==1){ // for layer 1 the detector are flipped upside down
588 // with respect to the others.
599 //----------------------------------------------------------------------
600 void AliITSgeomMatrix::LtoGPositionTracking(const Double_t l[3],
601 Double_t g[3]) const {
602 // A slightly different coordinate system is used when tracking.
603 // This coordinate system is only relevant when the geometry represents
604 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
605 // alone but X -> -Y and Y -> X such that X always points out of the
606 // ITS Cylinder for every layer including layer 1 (where the detector
607 // are mounted upside down).
610 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
614 // Double_t l[3] The poistion represented in the detector
615 // local coordinate system
617 // Double_t g[3] The poistion represented in the ALICE
618 // Global coordinate system
623 if(fid[0]==1){ // for layer 1 the detector are flipped upside down
624 // with respect to the others.
633 this->LtoGPosition(l0,g);
636 //----------------------------------------------------------------------
637 void AliITSgeomMatrix::GtoLMomentumTracking(const Double_t g[3],
638 Double_t l[3]) const {
639 // A slightly different coordinate system is used when tracking.
640 // This coordinate system is only relevant when the geometry represents
641 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
642 // alone but X -> -Y and Y -> X such that X always points out of the
643 // ITS Cylinder for every layer including layer 1 (where the detector
644 // are mounted upside down).
647 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
651 // Double_t g[3] The momentum represented in the ALICE global
654 // Double_t l[3] the momentum represented in the detector
655 // local coordinate system
660 this->GtoLMomentum(g,l0);
661 if(fid[0]==1){ // for layer 1 the detector are flipped upside down
662 // with respect to the others.
673 //----------------------------------------------------------------------
674 void AliITSgeomMatrix::LtoGMomentumTracking(const Double_t l[3],
675 Double_t g[3]) const {
676 // A slightly different coordinate system is used when tracking.
677 // This coordinate system is only relevant when the geometry represents
678 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
679 // alone but X -> -Y and Y -> X such that X always points out of the
680 // ITS Cylinder for every layer including layer 1 (where the detector
681 // are mounted upside down).
684 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
688 // Double_t l[3] the momentum represented in the detector
689 // local coordinate system
691 // Double_t g[3] The momentum represented in the ALICE global
697 if(fid[0]==1){ // for layer 1 the detector are flipped upside down
698 // with respect to the others.
707 this->LtoGMomentum(l0,g);
710 //----------------------------------------------------------------------
711 void AliITSgeomMatrix::GtoLPositionErrorTracking(const Double_t g[3][3],
712 Double_t l[3][3]) const {
713 // A slightly different coordinate system is used when tracking.
714 // This coordinate system is only relevant when the geometry represents
715 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
716 // alone but X -> -Y and Y -> X such that X always points out of the
717 // ITS Cylinder for every layer including layer 1 (where the detector
718 // are mounted upside down).
721 <img src="picts/ITS/AliITSgeomMatrix_TE1.gif">
725 // Double_t g[3][3] The error matrix represented in the ALICE global
728 // Double_t l[3][3] the error matrix represented in the detector
729 // local coordinate system
733 Double_t a0[3][3] = {{0.,+1.,0.},{-1.,0.,0.},{0.,0.,+1.}};
734 Double_t a1[3][3] = {{0.,-1.,0.},{+1.,0.,0.},{0.,0.,+1.}};
736 if(fid[0]==1) for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
737 rt[i][k] = a0[i][j]*fm[j][k];
738 else for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
739 rt[i][k] = a1[i][j]*fm[j][k];
740 for(i=0;i<3;i++)for(m=0;m<3;m++){
742 for(j=0;j<3;j++)for(k=0;k<3;k++)
743 l[i][m] += rt[j][i]*g[j][k]*rt[k][m];
748 //----------------------------------------------------------------------
749 void AliITSgeomMatrix::LtoGPositionErrorTracking(const Double_t l[3][3],
750 Double_t g[3][3]) const {
751 // A slightly different coordinate system is used when tracking.
752 // This coordinate system is only relevant when the geometry represents
753 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
754 // alone but X -> -Y and Y -> X such that X always points out of the
755 // ITS Cylinder for every layer including layer 1 (where the detector
756 // are mounted upside down).
759 <img src="picts/ITS/AliITSgeomMatrix_TE1.gif">
763 // Double_t l[3][3] the error matrix represented in the detector
764 // local coordinate system
766 // Double_t g[3][3] The error matrix represented in the ALICE global
772 Double_t a0[3][3] = {{0.,+1.,0.},{-1.,0.,0.},{0.,0.,+1.}};
773 Double_t a1[3][3] = {{0.,-1.,0.},{+1.,0.,0.},{0.,0.,+1.}};
775 if(fid[0]==1) for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
776 rt[i][k] = a0[i][j]*fm[j][k];
777 else for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
778 rt[i][k] = a1[i][j]*fm[j][k];
779 for(i=0;i<3;i++)for(m=0;m<3;m++){
781 for(j=0;j<3;j++)for(k=0;k<3;k++)
782 g[i][m] += rt[i][j]*l[j][k]*rt[m][k];
787 //----------------------------------------------------------------------
788 void AliITSgeomMatrix::PrintTitles(ostream *os) const {
789 // Standard output format for this class but it includes variable
790 // names and formatting that makes it easer to read.
792 // ostream *os The output stream to print the title on
799 *os << "fDetectorIndex=" << fDetectorIndex << " fid[3]={";
800 for(i=0;i<3;i++) *os << fid[i] << " ";
801 *os << "} frot[3]={";
802 for(i=0;i<3;i++) *os << frot[i] << " ";
803 *os << "} ftran[3]={";
804 for(i=0;i<3;i++) *os << ftran[i] << " ";
805 *os << "} fm[3][3]={";
806 for(i=0;i<3;i++){for(j=0;j<3;j++){ *os << fm[i][j] << " ";} *os <<"}{";}
810 //----------------------------------------------------------------------
811 void AliITSgeomMatrix::PrintComment(ostream *os) const {
812 // output format used by Print.
814 // ostream *os The output stream to print the comments on
819 *os << "fDetectorIndex fid[0] fid[1] fid[2] ftran[0] ftran[1] ftran[2] ";
820 *os << "fm[0][0] fm[0][1] fm[0][2] fm[1][0] fm[1][1] fm[1][2] ";
821 *os << "fm[2][0] fm[2][1] fm[2][2] ";
824 //----------------------------------------------------------------------
825 void AliITSgeomMatrix::Print(ostream *os)const{
826 // Standard output format for this class.
828 // ostream *os The output stream to print the class data on
841 #if defined __ICC || defined __ECC || defined __xlC__
848 fmt = os->setf(ios::scientific); // set scientific floating point output
849 *os << fDetectorIndex << " ";
850 for(i=0;i<3;i++) *os << fid[i] << " ";
851 // for(i=0;i<3;i++) *os << frot[i] << " "; // Redundant with fm[][].
852 for(i=0;i<3;i++) *os << setprecision(16) << ftran[i] << " ";
853 for(i=0;i<3;i++)for(j=0;j<3;j++) *os << setprecision(16) <<
855 *os << fPath.Length()<< " ";
856 for(i=0;i<fPath.Length();i++) *os << fPath[i];
858 os->flags(fmt); // reset back to old formating.
861 //----------------------------------------------------------------------
862 void AliITSgeomMatrix::Read(istream *is){
863 // Standard input format for this class.
865 // istream *is The input stream to read on
872 *is >> fDetectorIndex;
873 for(i=0;i<3;i++) *is >> fid[i];
874 // for(i=0;i<3;i++) *is >> frot[i]; // Redundant with fm[][].
875 for(i=0;i<3;i++) *is >> ftran[i];
876 for(i=0;i<3;i++)for(j=0;j<3;j++) *is >> fm[i][j];
877 while(is->peek()==' ')is->get(); // skip white spaces
878 if(isprint(is->peek())){ // old format did not have path.
879 *is >> j; // string length
881 for(i=0;i<j;i++) {*is >> fPath[i];}
883 AngleFromMatrix(); // compute angles frot[].
884 fCylR = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
885 fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
886 if(fCylPhi<0.0) fCylPhi += TMath::Pi();
889 //______________________________________________________________________
890 void AliITSgeomMatrix::Streamer(TBuffer &R__b){
891 // Stream an object of class AliITSgeomMatrix.
893 // TBuffer &R__b The output buffer to stream data on.
899 if (R__b.IsReading()) {
900 AliITSgeomMatrix::Class()->ReadBuffer(R__b, this);
901 fCylR = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
902 fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
903 this->AngleFromMatrix();
904 if(fCylPhi<0.0) fCylPhi += TMath::Pi();
906 AliITSgeomMatrix::Class()->WriteBuffer(R__b, this);
909 //______________________________________________________________________
910 void AliITSgeomMatrix::SetTranslation(const Double_t tran[3]){
911 // Sets the translation vector and computes fCylR and fCylPhi.
913 // Double_t trans[3] The translation vector to be used
918 for(Int_t i=0;i<3;i++) ftran[i] = tran[i];
919 fCylR = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
920 fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
921 if(fCylPhi<0.0) fCylPhi += TMath::Pi();
923 //----------------------------------------------------------------------
924 TPolyLine3D* AliITSgeomMatrix::CreateLocalAxis() const {
925 // This class is used as part of the documentation of this class
931 // A pointer to a new TPolyLine3D object showing the 3 line
932 // segments that make up the this local axis in the global
936 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},
941 LtoGPosition(l[i],g[i]);
942 gf[3*i]=(Float_t)g[i][0];
943 gf[3*i+1]=(Float_t)g[i][1];
944 gf[3*i+2]=(Float_t)g[i][2];
946 return new TPolyLine3D(5,gf);
948 //----------------------------------------------------------------------
949 TPolyLine3D* AliITSgeomMatrix::CreateLocalAxisTracking() const {
950 // This class is used as part of the documentation of this class
956 // A pointer to a new TPolyLine3D object showing the 3 line
957 // segments that make up the this local axis in the global
961 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},
966 LtoGPositionTracking(l[i],g[i]);
967 gf[3*i]=(Float_t)g[i][0];
968 gf[3*i+1]=(Float_t)g[i][1];
969 gf[3*i+2]=(Float_t)g[i][2];
971 return new TPolyLine3D(5,gf);
973 //----------------------------------------------------------------------
974 TNode* AliITSgeomMatrix::CreateNode(const Char_t *nodeName,
975 const Char_t *nodeTitle,TNode *mother,
976 TShape *shape,Bool_t axis) const {
977 // Creates a node inside of the node mother out of the shape shape
978 // in the position, with respect to mother, indecated by "this". If axis
979 // is ture, it will insert an axis within this node/shape.
981 // Char_t *nodeName This name of this node
982 // Char_t *nodeTitle This node title
983 // TNode *mother The node this node will be inside of/with respect to
984 // TShape *shape The shape of this node
985 // Bool_t axis If ture, a set of x,y,z axis will be included
989 // A pointer to "this" node.
990 Double_t trans[3],matrix[3][3],*matr;
991 TRotMatrix *rot = new TRotMatrix();
994 matr = &(matrix[0][0]);
995 this->GetTranslation(trans);
996 this->GetMatrix(matrix);
997 rot->SetMatrix(matr);
1003 TNode *node1 = new TNode(name.Data(),title.Data(),shape,trans[0],trans[1],trans[2],rot);
1006 const Float_t kScale=0.5,kLw=0.2;
1007 Float_t xchar[13][2]={{0.5*kLw,1.},{0.,0.5*kLw},{0.5-0.5*kLw,0.5},
1008 {0.,0.5*kLw},{0.5*kLw,0.},{0.5,0.5-0.5*kLw},
1009 {1-0.5*kLw,0.},{1.,0.5*kLw},{0.5+0.5*kLw,0.5},
1010 {1.,1.-0.5*kLw},{1.-0.5*kLw,1.},{0.5,0.5+0.5*kLw},
1012 Float_t ychar[10][2]={{.5-0.5*kLw,0.},{.5+0.5*kLw,0.},{.5+0.5*kLw,0.5-0.5*kLw},
1013 {1.,1.-0.5*kLw},{1.-0.5*kLw,1.},{0.5+0.5*kLw,0.5},
1014 {0.5*kLw,1.} ,{0.,1-0.5*kLw} ,{0.5-0.5*kLw,0.5},
1016 Float_t zchar[11][2]={{0.,1.},{0,1.-kLw},{1.-kLw,1.-kLw},{0.,kLw} ,{0.,0.},
1017 {1.,0.},{1.,kLw} ,{kLw,kLw} ,{1.,1.-kLw},{1.,1.},
1019 for(i=0;i<13;i++)for(j=0;j<2;j++){
1020 if(i<13) xchar[i][j] = kScale*xchar[i][j];
1021 if(i<10) ychar[i][j] = kScale*ychar[i][j];
1022 if(i<11) zchar[i][j] = kScale*zchar[i][j];
1024 TXTRU *axisxl = new TXTRU("x","x","text",12,2);
1025 for(i=0;i<12;i++) axisxl->DefineVertex(i,xchar[i][0],xchar[i][1]);
1026 axisxl->DefineSection(0,-0.5*kLw);axisxl->DefineSection(1,0.5*kLw);
1027 TXTRU *axisyl = new TXTRU("y","y","text",9,2);
1028 for(i=0;i<9;i++) axisyl->DefineVertex(i,ychar[i][0],ychar[i][1]);
1029 axisyl->DefineSection(0,-0.5*kLw);axisyl->DefineSection(1,0.5*kLw);
1030 TXTRU *axiszl = new TXTRU("z","z","text",10,2);
1031 for(i=0;i<10;i++) axiszl->DefineVertex(i,zchar[i][0],zchar[i][1]);
1032 axiszl->DefineSection(0,-0.5*kLw);axiszl->DefineSection(1,0.5*kLw);
1033 Float_t lxy[13][2]={{-0.5*kLw,-0.5*kLw},{0.8,-0.5*kLw},{0.8,-0.1},{1.0,0.0},
1034 {0.8,0.1},{0.8,0.5*kLw},{0.5*kLw,0.5*kLw},{0.5*kLw,0.8},
1035 {0.1,0.8},{0.0,1.0},{-0.1,0.8},{-0.5*kLw,0.8},
1036 {-0.5*kLw,-0.5*kLw}};
1037 TXTRU *axisxy = new TXTRU("axisxy","axisxy","text",13,2);
1038 for(i=0;i<13;i++) axisxy->DefineVertex(i,lxy[i][0],lxy[i][1]);
1039 axisxy->DefineSection(0,-0.5*kLw);axisxy->DefineSection(1,0.5*kLw);
1040 Float_t lz[8][2]={{0.5*kLw,-0.5*kLw},{0.8,-0.5*kLw},{0.8,-0.1},{1.0,0.0},
1041 {0.8,0.1},{0.8,0.5*kLw},{0.5*kLw,0.5*kLw},
1042 {0.5*kLw,-0.5*kLw}};
1043 TXTRU *axisz = new TXTRU("axisz","axisz","text",8,2);
1044 for(i=0;i<8;i++) axisz->DefineVertex(i,lz[i][0],lz[i][1]);
1045 axisz->DefineSection(0,-0.5*kLw);axisz->DefineSection(1,0.5*kLw);
1046 //TRotMatrix *xaxis90= new TRotMatrix("xaixis90","",90.0, 0.0, 0.0);
1047 TRotMatrix *yaxis90= new TRotMatrix("yaixis90","", 0.0,90.0, 0.0);
1048 TRotMatrix *zaxis90= new TRotMatrix("zaixis90","", 0.0, 0.0,90.0);
1051 title = name.Append("axisxy");
1052 TNode *nodeaxy = new TNode(title.Data(),title.Data(),axisxy);
1053 title = name.Append("axisz");
1054 TNode *nodeaz = new TNode(title.Data(),title.Data(),axisz,0.,0.,0.,yaxis90);
1055 TNode *textboxX0 = new TNode("textboxX0","textboxX0",axisxl,
1056 lxy[3][0],lxy[3][1],0.0);
1057 TNode *textboxX1 = new TNode("textboxX1","textboxX1",axisxl,
1058 lxy[3][0],lxy[3][1],0.0,yaxis90);
1059 TNode *textboxX2 = new TNode("textboxX2","textboxX2",axisxl,
1060 lxy[3][0],lxy[3][1],0.0,zaxis90);
1061 TNode *textboxY0 = new TNode("textboxY0","textboxY0",axisyl,
1062 lxy[9][0],lxy[9][1],0.0);
1063 TNode *textboxY1 = new TNode("textboxY1","textboxY1",axisyl,
1064 lxy[9][0],lxy[9][1],0.0,yaxis90);
1065 TNode *textboxY2 = new TNode("textboxY2","textboxY2",axisyl,
1066 lxy[9][0],lxy[9][1],0.0,zaxis90);
1067 TNode *textboxZ0 = new TNode("textboxZ0","textboxZ0",axiszl,
1069 TNode *textboxZ1 = new TNode("textboxZ1","textboxZ1",axiszl,
1070 0.0,0.0,lz[3][0],yaxis90);
1071 TNode *textboxZ2 = new TNode("textboxZ2","textboxZ2",axiszl,
1072 0.0,0.0,lz[3][0],zaxis90);
1088 //----------------------------------------------------------------------
1089 void AliITSgeomMatrix::MakeFigures() const {
1090 // make figures to help document this class
1097 const Double_t kDx0=550.,kDy0=550.,kDz0=550.; // cm
1098 const Double_t kDx=1.0,kDy=0.300,kDz=3.0,kRmax=0.1; // cm
1099 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},
1101 TCanvas *c = new TCanvas(kFALSE);// create a batch mode canvas.
1102 TView *view = new TView(1); // Create Cartesian coordiante view
1103 TBRIK *mother = new TBRIK("Mother","Mother","void",kDx0,kDy0,kDz0);
1104 TBRIK *det = new TBRIK("Detector","","Si",kDx,kDy,kDz);
1105 TPolyLine3D *axis = new TPolyLine3D(5,&(l[0][0]));
1106 TPCON *arrow = new TPCON("arrow","","air",0.0,360.,2);
1107 TRotMatrix *xarrow= new TRotMatrix("xarrow","",90.,0.0,0.0);
1108 TRotMatrix *yarrow= new TRotMatrix("yarrow","",0.0,90.,0.0);
1110 det->SetLineColor(0); // black
1111 det->SetLineStyle(1); // solid line
1112 det->SetLineWidth(2); // pixel units
1113 det->SetFillColor(1); // black
1114 det->SetFillStyle(4010); // window is 90% transparent
1115 arrow->SetLineColor(det->GetLineColor());
1116 arrow->SetLineWidth(det->GetLineWidth());
1117 arrow->SetLineStyle(det->GetLineStyle());
1118 arrow->SetFillColor(1); // black
1119 arrow->SetFillStyle(4100); // window is 100% opaque
1120 arrow->DefineSection(0,0.0,0.0,kRmax);
1121 arrow->DefineSection(1,2.*kRmax,0.0,0.0);
1122 view->SetRange(-kDx0,-kDy0,-kDz0,kDx0,kDy0,kDz0);
1124 TNode *node0 = new TNode("NODE0","NODE0",mother);
1126 TNode *node1 = new TNode("NODE1","NODE1",det);
1128 TNode *nodex = new TNode("NODEx","NODEx",arrow,l[0][0],l[0][1],l[0][2],xarrow);
1129 TNode *nodey = new TNode("NODEy","NODEy",arrow,l[2][0],l[2][1],l[2][2],yarrow);
1130 TNode *nodez = new TNode("NODEz","NODEz",arrow,l[4][0],l[4][1],l[4][2]);
1141 c->SaveAs("AliITSgeomMatrix_L1.gif");
1143 //----------------------------------------------------------------------
1144 ostream &operator<<(ostream &os,AliITSgeomMatrix &p){
1145 // Standard output streaming function.
1147 // ostream &os The output stream to print the class data on
1148 // AliITSgeomMatrix &p This class
1157 //----------------------------------------------------------------------
1158 istream &operator>>(istream &is,AliITSgeomMatrix &r){
1159 // Standard input streaming function.
1161 // ostream &os The input stream to print the class data on
1162 // AliITSgeomMatrix &p This class
1171 //----------------------------------------------------------------------