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 #if ROOT_VERSION_CODE>= 331523
39 #include <TPolyLine3D.h>
45 #include "AliITSgeomMatrix.h"
47 ClassImp(AliITSgeomMatrix)
48 //----------------------------------------------------------------------
49 AliITSgeomMatrix::AliITSgeomMatrix():
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.
71 <img src="picts/ITS/AliITSgeomMatrix_L1.gif">
79 // A default constructes AliITSgeomMatrix class.
82 fDetectorIndex = -1; // a value never defined.
85 frot[i] = ftran[i] = 0.0;
86 for(j=0;j<3;j++) fm[i][j] = 0.0;
87 fCylR = fCylPhi = 0.0;
89 fm[0][0] = fm[1][1] = fm[2][2] = 1.0;
92 //----------------------------------------------------------------------
93 AliITSgeomMatrix::AliITSgeomMatrix(const AliITSgeomMatrix &source) :
95 fDetectorIndex(source.fDetectorIndex),
97 fCylPhi(source.fCylPhi),
99 // The standard Copy constructor. This make a full / proper copy of
102 // AliITSgeomMatrix &source The source of this copy
106 // A copy constructes AliITSgeomMatrix class.
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];
115 //----------------------------------------------------------------------
116 AliITSgeomMatrix& AliITSgeomMatrix::operator=(const AliITSgeomMatrix &source){
117 // The standard = operator. This make a full / proper copy of
119 // The standard Copy constructor. This make a full / proper copy of
122 // AliITSgeomMatrix &source The source of this copy
126 // A copy of the source AliITSgeomMatrix class.
127 if(this == &source)return *this;
130 this->fDetectorIndex = source.fDetectorIndex;
131 this->fCylR = source.fCylR;
132 this->fCylPhi = source.fCylPhi;
134 this->fid[i] = source.fid[i];
135 this->frot[i] = source.frot[i];
136 this->ftran[i] = source.ftran[i];
138 for(j=0;j<3;j++) this->fm[i][j] = source.fm[i][j];
140 this->fPath = source.fPath;
144 //----------------------------------------------------------------------
145 AliITSgeomMatrix::AliITSgeomMatrix(Int_t idt,const Int_t id[3],
146 const Double_t rot[3],const Double_t tran[3]):
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.
167 <img src="picts/ITS/AliITSgeomMatrix_L1.gif">
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
178 // A properly inilized AliITSgeomMatrix class.
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();
191 //----------------------------------------------------------------------
192 AliITSgeomMatrix::AliITSgeomMatrix(Int_t idt, const Int_t id[3],
193 Double_t matrix[3][3],
194 const Double_t tran[3]):
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.
216 <img src="picts/ITS/AliITSgeomMatrix_L1.gif">
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
227 // A properly inilized AliITSgeomMatrix class.
233 for(j=0;j<3;j++) fm[i][j] = matrix[i][j];
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();
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.
247 // Double_t ang[6] The 6 Geant3.21 rotation angles. [degrees]
250 Double_t si,c=180./TMath::Pi();
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]);
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]);
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]);
267 for(Int_t i=0;i<6;i++) {ang[i] *= c; if(ang[i]<0.0) ang[i] += 360.;}
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
276 // Double_t ang[6] The 6 Geant3.21 rotation angles. [degrees]
282 Double_t si,lr[9],c=TMath::Pi()/180.;
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;
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;
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.
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];
323 this->AngleFromMatrix();
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]):
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.
346 <img src="picts/ITS/AliITSgeomMatrix_L1.gif">
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
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);
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.
385 // get angles from matrix up to a phase of 180 degrees.
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();
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.
414 Double_t sx,sy,sz,cx,cy,cz;
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]
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].
435 // Double_t g[3] The position represented in the ALICE
436 // global coordinate system
438 // Double_t l[3] The poistion represented in the local
439 // detector coordiante system
445 for(i=0;i<3;i++) g[i] = g0[i] - ftran[i];
448 for(j=0;j<3;j++) l[i] += fm[i][j]*g[j];
449 // g = R l + translation
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].
457 // Double_t l[3] The poistion represented in the detector
458 // local coordinate system
460 // Double_t g[3] The poistion represented in the ALICE
461 // Global coordinate system
468 for(j=0;j<3;j++) g[i] += fm[j][i]*l[j];
470 // g = R^t l + translation
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.
480 // Double_t g[3] The momentum represented in the ALICE global
483 // Double_t l[3] the momentum represented in the detector
484 // local coordinate system
491 for(j=0;j<3;j++) l[i] += fm[i][j]*g[j];
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.
502 // Double_t l[3] the momentum represented in the detector
503 // local coordinate system
505 // Double_t g[3] The momentum represented in the ALICE global
513 for(j=0;j<3;j++) g[i] += fm[j][i]*l[j];
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.
526 // Double_t g[3][3] The error matrix represented in the ALICE global
529 // Double_t l[3][3] the error matrix represented in the detector
530 // local coordinate system
535 for(i=0;i<3;i++)for(m=0;m<3;m++){
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];
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.
550 // Double_t l[3][3] the error matrix represented in the detector
551 // local coordinate system
553 // Double_t g[3][3] The error matrix represented in the ALICE global
559 for(i=0;i<3;i++)for(m=0;m<3;m++){
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];
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).
578 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
582 // Double_t g[3] The position represented in the ALICE
583 // global coordinate system
585 // Double_t l[3] The poistion represented in the local
586 // detector coordiante system
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.
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).
615 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
619 // Double_t l[3] The poistion represented in the detector
620 // local coordinate system
622 // Double_t g[3] The poistion represented in the ALICE
623 // Global coordinate system
628 if(fid[0]==1){ // for layer 1 the detector are flipped upside down
629 // with respect to the others.
638 this->LtoGPosition(l0,g);
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).
652 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
656 // Double_t g[3] The momentum represented in the ALICE global
659 // Double_t l[3] the momentum represented in the detector
660 // local coordinate system
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.
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).
689 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
693 // Double_t l[3] the momentum represented in the detector
694 // local coordinate system
696 // Double_t g[3] The momentum represented in the ALICE global
702 if(fid[0]==1){ // for layer 1 the detector are flipped upside down
703 // with respect to the others.
712 this->LtoGMomentum(l0,g);
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).
726 <img src="picts/ITS/AliITSgeomMatrix_TE1.gif">
730 // Double_t g[3][3] The error matrix represented in the ALICE global
733 // Double_t l[3][3] the error matrix represented in the detector
734 // local coordinate system
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.}};
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++){
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];
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).
764 <img src="picts/ITS/AliITSgeomMatrix_TE1.gif">
768 // Double_t l[3][3] the error matrix represented in the detector
769 // local coordinate system
771 // Double_t g[3][3] The error matrix represented in the ALICE global
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.}};
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++){
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];
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.
797 // ostream *os The output stream to print the title on
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 <<"}{";}
815 //----------------------------------------------------------------------
816 void AliITSgeomMatrix::PrintComment(ostream *os) const {
817 // output format used by Print.
819 // ostream *os The output stream to print the comments on
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] ";
829 //----------------------------------------------------------------------
830 void AliITSgeomMatrix::Print(ostream *os)const{
831 // Standard output format for this class.
833 // ostream *os The output stream to print the class data on
846 #if defined __ICC || defined __ECC || defined __xlC__
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) <<
860 *os << fPath.Length()<< " ";
861 for(i=0;i<fPath.Length();i++) *os << fPath[i];
863 os->flags(fmt); // reset back to old formating.
866 //----------------------------------------------------------------------
867 void AliITSgeomMatrix::Read(istream *is){
868 // Standard input format for this class.
870 // istream *is The input stream to read on
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
886 for(i=0;i<j;i++) {*is >> fPath[i];}
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();
894 //______________________________________________________________________
895 void AliITSgeomMatrix::Streamer(TBuffer &R__b){
896 // Stream an object of class AliITSgeomMatrix.
898 // TBuffer &R__b The output buffer to stream data on.
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();
911 AliITSgeomMatrix::Class()->WriteBuffer(R__b, this);
914 //______________________________________________________________________
915 void AliITSgeomMatrix::SetTranslation(const Double_t tran[3]){
916 // Sets the translation vector and computes fCylR and fCylPhi.
918 // Double_t trans[3] The translation vector to be used
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();
928 //----------------------------------------------------------------------
929 TPolyLine3D* AliITSgeomMatrix::CreateLocalAxis() const {
930 // This class is used as part of the documentation of this class
936 // A pointer to a new TPolyLine3D object showing the 3 line
937 // segments that make up the this local axis in the global
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},
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];
951 return new TPolyLine3D(5,gf);
953 //----------------------------------------------------------------------
954 TPolyLine3D* AliITSgeomMatrix::CreateLocalAxisTracking() const {
955 // This class is used as part of the documentation of this class
961 // A pointer to a new TPolyLine3D object showing the 3 line
962 // segments that make up the this local axis in the global
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},
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];
976 return new TPolyLine3D(5,gf);
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.
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
994 // A pointer to "this" node.
995 Double_t trans[3],matrix[3][3],*matr;
996 TRotMatrix *rot = new TRotMatrix();
999 matr = &(matrix[0][0]);
1000 this->GetTranslation(trans);
1001 this->GetMatrix(matrix);
1002 rot->SetMatrix(matr);
1008 TNode *node1 = new TNode(name.Data(),title.Data(),shape,trans[0],trans[1],trans[2],rot);
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},
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},
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.},
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];
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);
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,
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);
1093 //----------------------------------------------------------------------
1094 void AliITSgeomMatrix::MakeFigures() const {
1095 // make figures to help document this class
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},
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);
1112 TView *view = new TView(1); // Create Cartesian coordiante view
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);
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);
1135 TNode *node0 = new TNode("NODE0","NODE0",mother);
1137 TNode *node1 = new TNode("NODE1","NODE1",det);
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]);
1152 c->SaveAs("AliITSgeomMatrix_L1.gif");
1154 //----------------------------------------------------------------------
1155 ostream &operator<<(ostream &os,AliITSgeomMatrix &p){
1156 // Standard output streaming function.
1158 // ostream &os The output stream to print the class data on
1159 // AliITSgeomMatrix &p This class
1168 //----------------------------------------------------------------------
1169 istream &operator>>(istream &is,AliITSgeomMatrix &r){
1170 // Standard input streaming function.
1172 // ostream &os The input stream to print the class data on
1173 // AliITSgeomMatrix &p This class
1182 //----------------------------------------------------------------------