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>
46 #include "AliITSgeomMatrix.h"
51 using std::setprecision;
52 ClassImp(AliITSgeomMatrix)
53 //----------------------------------------------------------------------
54 AliITSgeomMatrix::AliITSgeomMatrix():
55 TObject(), // Base Class.
56 fDetectorIndex(0), // Detector type index (like fShapeIndex was)
57 fid(), // layer, ladder, detector numbers.
58 frot(), //! vector of rotations about x,y,z [radians].
59 ftran(), // Translation vector of module x,y,z.
60 fCylR(0.0), //! R Translation in Cylinderical coordinates
61 fCylPhi(0.0),//! Phi Translation vector in Cylindrical coord.
62 fm(), // Rotation matrix based on frot.
63 fPath(){ // Path in geometry to this module
64 // The Default constructor for the AliITSgeomMatrix class. By Default
65 // the angles of rotations are set to zero, meaning that the rotation
66 // matrix is the unit matrix. The translation vector is also set to
67 // zero as are the module id number. The detector type is set to -1
68 // (an undefined value). The full rotation matrix is kept so that
69 // the evaluation of a coordinate transformation can be done
70 // quickly and with a minimum of CPU overhead. The basic coordinate
71 // systems are the ALICE global coordinate system and the detector
72 // local coordinate system. In general this structure is not limited
73 // to just those two coordinate systems.
76 <img src="picts/ITS/AliITSgeomMatrix_L1.gif">
84 // A default constructes AliITSgeomMatrix class.
87 fDetectorIndex = -1; // a value never defined.
90 frot[i] = ftran[i] = 0.0;
91 for(j=0;j<3;j++) fm[i][j] = 0.0;
93 fm[0][0] = fm[1][1] = fm[2][2] = 1.0;
96 //----------------------------------------------------------------------
97 AliITSgeomMatrix::AliITSgeomMatrix(const AliITSgeomMatrix &source) :
98 TObject(source), // Base Class.
99 fDetectorIndex(source.fDetectorIndex),// Detector type index (like
101 fid(), // layer, ladder, detector numbers.
102 frot(), //! vector of rotations about x,y,z [radians].
103 ftran(), // Translation vector of module x,y,z.
104 fCylR(source.fCylR), //! R Translation in Cylinderical coordinates
105 fCylPhi(source.fCylPhi),//! Phi Translation vector in Cylindrical coord.
106 fm(), // Rotation matrix based on frot.
108 // The standard Copy constructor. This make a full / proper copy of
111 // AliITSgeomMatrix &source The source of this copy
115 // A copy constructes AliITSgeomMatrix class.
119 this->fid[i] = source.fid[i];
120 this->frot[i] = source.frot[i];
121 this->ftran[i] = source.ftran[i];
122 for(j=0;j<3;j++) this->fm[i][j] = source.fm[i][j];
125 //----------------------------------------------------------------------
126 AliITSgeomMatrix& AliITSgeomMatrix::operator=(const AliITSgeomMatrix &source){
127 // The standard = operator. This make a full / proper copy of
129 // The standard Copy constructor. This make a full / proper copy of
132 // AliITSgeomMatrix &source The source of this copy
136 // A copy of the source AliITSgeomMatrix class.
138 if(this == &source)return *this;
141 this->fDetectorIndex = source.fDetectorIndex;
142 this->fCylR = source.fCylR;
143 this->fCylPhi = source.fCylPhi;
145 this->fid[i] = source.fid[i];
146 this->frot[i] = source.frot[i];
147 this->ftran[i] = source.ftran[i];
148 for(j=0;j<3;j++) this->fm[i][j] = source.fm[i][j];
150 this->fPath = source.fPath;
153 //----------------------------------------------------------------------
154 AliITSgeomMatrix::AliITSgeomMatrix(Int_t idt,const Int_t id[3],
155 const Double_t rot[3],const Double_t tran[3]):
156 TObject(), // Base class
157 fDetectorIndex(idt), // Detector type index (like fShapeIndex was)
158 fid(), // layer, ladder, detector numbers.
159 frot(), //! vector of rotations about x,y,z [radians].
160 ftran(), // Translation vector of module x,y,z.
161 fCylR(0.0), //! R Translation in Cylinderical coordinates
162 fCylPhi(0.0),//! Phi Translation vector in Cylindrical coord.
163 fm(), // Rotation matrix based on frot.
164 fPath(){ // Path in geometry to this moduel
165 // This is a constructor for the AliITSgeomMatrix class. The matrix is
166 // defined by 3 standard rotation angles [radians], and the translation
167 // vector tran [cm]. In addition the layer, ladder, and detector number
168 // for this particular module and the type of module must be given.
169 // The full rotation matrix is kept so that the evaluation
170 // of a coordinate transformation can be done quickly and with a minimum
171 // of CPU overhead. The basic coordinate systems are the ALICE global
172 // coordinate system and the detector local coordinate system. In general
173 // this structure is not limited to just those two coordinate systems.
176 <img src="picts/ITS/AliITSgeomMatrix_L1.gif">
180 // Int_t idt The detector index value
181 // Int_t id[3] The layer, ladder, and detector numbers
182 // Double_t rot[3] The 3 Cartician rotaion angles [radians]
183 // Double_t tran[3] The 3 Cartician translation distnaces
187 // A properly inilized AliITSgeomMatrix class.
195 fCylR = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
196 fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
197 if(fCylPhi<0.0) fCylPhi += 2.*TMath::Pi();
198 this->MatrixFromAngle();
200 //----------------------------------------------------------------------
201 AliITSgeomMatrix::AliITSgeomMatrix(Int_t idt, const Int_t id[3],
202 Double_t matrix[3][3],
203 const Double_t tran[3]):
204 TObject(), // Base class
205 fDetectorIndex(idt), // Detector type index (like fShapeIndex was)
206 fid(), // layer, ladder, detector numbers.
207 frot(), //! vector of rotations about x,y,z [radians].
208 ftran(), // Translation vector of module x,y,z.
209 fCylR(0.0), //! R Translation in Cylinderical coordinates
210 fCylPhi(0.0),//! Phi Translation vector in Cylindrical coord.
211 fm(), // Rotation matrix based on frot.
212 fPath(){ // Path in geometry to this module
213 // This is a constructor for the AliITSgeomMatrix class. The
214 // rotation matrix is given as one of the inputs, and the
215 // translation vector tran [cm]. In addition the layer, ladder,
216 // and detector number for this particular module and the type of
217 // module must be given. The full rotation matrix is kept so that
218 // the evaluation of a coordinate transformation can be done quickly
219 // and with a minimum of CPU overhead. The basic coordinate systems
220 // are the ALICE global coordinate system and the detector local
221 // coordinate system. In general this structure is not limited to just
222 // those two coordinate systems.
225 <img src="picts/ITS/AliITSgeomMatrix_L1.gif">
229 // Int_t idt The detector index value
230 // Int_t id[3] The layer, ladder, and detector numbers
231 // Double_t rot[3][3] The 3x3 Cartician rotaion matrix
232 // Double_t tran[3] The 3 Cartician translation distnaces
236 // A properly inilized AliITSgeomMatrix class.
242 for(j=0;j<3;j++) fm[i][j] = matrix[i][j];
244 fCylR = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
245 fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
246 if(fCylPhi<0.0) fCylPhi += 2.*TMath::Pi();
247 this->AngleFromMatrix();
249 //----------------------------------------------------------------------
250 void AliITSgeomMatrix::SixAnglesFromMatrix(Double_t *ang)const{
251 // This function returns the 6 GEANT 3.21 rotation angles [degrees] in
252 // the array ang which must be at least [6] long.
256 // Double_t ang[6] The 6 Geant3.21 rotation angles. [degrees]
259 Double_t si,c=180./TMath::Pi();
260 const Double_t epsil=1.e-15;
262 ang[1] = TMath::ATan2(fm[0][1],fm[0][0]);
263 if( !(TMath::AreEqualAbs(TMath::Cos(ang[1]),0.,epsil))) si = fm[0][0]/TMath::Cos(ang[1]);
264 else si = fm[0][1]/TMath::Sin(ang[1]);
265 ang[0] = TMath::ATan2(si,fm[0][2]);
267 ang[3] = TMath::ATan2(fm[1][1],fm[1][0]);
268 if(!(TMath::AreEqualAbs(TMath::Cos(ang[3]),0.,epsil))) si = fm[1][0]/TMath::Cos(ang[3]);
269 else si = fm[1][1]/TMath::Sin(ang[3]);
270 ang[2] = TMath::ATan2(si,fm[1][2]);
272 ang[5] = TMath::ATan2(fm[2][1],fm[2][0]);
273 if(!(TMath::AreEqualAbs(TMath::Cos(ang[5]),0.,epsil))) si = fm[2][0]/TMath::Cos(ang[5]);
274 else si = fm[2][1]/TMath::Sin(ang[5]);
275 ang[4] = TMath::ATan2(si,fm[2][2]);
277 for(Int_t i=0;i<6;i++) {ang[i] *= c; if(ang[i]<0.0) ang[i] += 360.;}
279 //----------------------------------------------------------------------
280 void AliITSgeomMatrix::MatrixFromSixAngles(const Double_t *ang){
281 // Given the 6 GEANT 3.21 rotation angles [degree], this will compute and
282 // set the rotations matrix and 3 standard rotation angles [radians].
283 // These angles and rotation matrix are overwrite the existing values in
286 // Double_t ang[6] The 6 Geant3.21 rotation angles. [degrees]
292 Double_t si,lr[9],c=TMath::Pi()/180.;
293 const Double_t epsil = 1.e-15;
295 si = TMath::Sin(c*ang[0]);
296 if(TMath::AreEqualAbs(ang[0],90.,epsil)) si = +1.0;
297 if(TMath::AreEqualAbs(ang[0],270.,epsil)) si = -1.0;
298 if(TMath::AreEqualAbs(ang[0],0.,epsil) ||TMath::AreEqualAbs(ang[0],180.,epsil)) si = 0.0;
299 lr[0] = si * TMath::Cos(c*ang[1]);
300 lr[1] = si * TMath::Sin(c*ang[1]);
301 lr[2] = TMath::Cos(c*ang[0]);
302 if(TMath::AreEqualAbs(ang[0],90.,epsil)||TMath::AreEqualAbs(ang[0],270.,epsil)) lr[2] = 0.0;
303 if(TMath::AreEqualAbs(ang[0],0.,epsil)) lr[2] = +1.0;
304 if(TMath::AreEqualAbs(ang[0],180.,epsil)) lr[2] = -1.0;
306 si = TMath::Sin(c*ang[2]);
307 if(TMath::AreEqualAbs(ang[2],90.,epsil)) si = +1.0;
308 if(TMath::AreEqualAbs(ang[2],270.,epsil)) si = -1.0;
309 if(TMath::AreEqualAbs(ang[2],0.,epsil) || TMath::AreEqualAbs(ang[2],180.,epsil)) si = 0.0;
310 lr[3] = si * TMath::Cos(c*ang[3]);
311 lr[4] = si * TMath::Sin(c*ang[3]);
312 lr[5] = TMath::Cos(c*ang[2]);
313 if(TMath::AreEqualAbs(ang[2],90.,epsil) || TMath::AreEqualAbs(ang[2],270.,epsil)) lr[5] = 0.0;
314 if(TMath::AreEqualAbs(ang[2],0.,epsil)) lr[5] = +1.0;
315 if(TMath::AreEqualAbs(ang[2],180.,epsil)) lr[5] = -1.0;
317 si = TMath::Sin(c*ang[4]);
318 if(TMath::AreEqualAbs(ang[4],90.,epsil)) si = +1.0;
319 if(TMath::AreEqualAbs(ang[4],270.0,epsil)) si = -1.0;
320 if(TMath::AreEqualAbs(ang[4],0.,epsil)|| TMath::AreEqualAbs(ang[4],180.,epsil)) si = 0.0;
321 lr[6] = si * TMath::Cos(c*ang[5]);
322 lr[7] = si * TMath::Sin(c*ang[5]);
323 lr[8] = TMath::Cos(c*ang[4]);
324 if(TMath::AreEqualAbs(ang[4],90.0,epsil) ||TMath::AreEqualAbs(ang[4],270.,epsil)) lr[8] = 0.0;
325 if(TMath::AreEqualAbs(ang[4],0.,epsil)) lr[8] = +1.0;
326 if(TMath::AreEqualAbs(ang[4],180.0,epsil)) lr[8] = -1.0;
327 // Normalize these elements and fill matrix fm.
328 for(i=0;i<3;i++){// reuse si.
330 for(j=0;j<3;j++) si += lr[3*i+j]*lr[3*i+j];
331 si = TMath::Sqrt(1./si);
332 for(j=0;j<3;j++) fm[i][j] = si*lr[3*i+j];
334 this->AngleFromMatrix();
336 //----------------------------------------------------------------------
337 AliITSgeomMatrix::AliITSgeomMatrix(const Double_t rotd[6]/*degrees*/,
338 Int_t idt,const Int_t id[3],
339 const Double_t tran[3]):
340 TObject(), // Base class
341 fDetectorIndex(idt), // Detector type index (like fShapeIndex was)
342 fid(), // layer, ladder, detector numbers.
343 frot(), //! vector of rotations about x,y,z [radians].
344 ftran(), // Translation vector of module x,y,z.
345 fCylR(0.0), //! R Translation in Cylinderical coordinates
346 fCylPhi(0.0),//! Phi Translation vector in Cylindrical coord.
347 fm(), // Rotation matrix based on frot.
348 fPath(){ // Path in geometry to this module
349 // This is a constructor for the AliITSgeomMatrix class. The matrix
350 // is defined by the 6 GEANT 3.21 rotation angles [degrees], and
351 // the translation vector tran [cm]. In addition the layer, ladder,
352 // and detector number for this particular module and the type of
353 // module must be given. The full rotation matrix is kept so that
354 // the evaluation of a coordinate transformation can be done
355 // quickly and with a minimum of CPU overhead. The basic coordinate
356 // systems are the ALICE global coordinate system and the detector
357 // local coordinate system. In general this structure is not limited
358 // to just those two coordinate systems.
361 <img src="picts/ITS/AliITSgeomMatrix_L1.gif">
365 // Double_t rotd[6] The 6 Geant 3.21 rotation angles [degrees]
366 // Int_t idt The module Id number
367 // Int_t id[3] The layer, ladder and detector number
368 // Double_t tran[3] The translation vector
375 fCylR = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
376 fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
377 if(fCylPhi<0.0) fCylPhi += 2.*TMath::Pi();
378 this->MatrixFromSixAngles(rotd);
380 //----------------------------------------------------------------------
381 void AliITSgeomMatrix::AngleFromMatrix(){
382 // Computes the angles from the rotation matrix up to a phase of
383 // 180 degrees. The matrix used in AliITSgeomMatrix::MatrixFromAngle()
384 // and its inverse AliITSgeomMatrix::AngleFromMatrix() are defined in
385 // the following ways, R = Rz*Ry*Rx (M=R*L+T) where
386 // 1 0 0 Cy 0 +Sy Cz -Sz 0
387 // Rx= 0 Cx -Sx Ry= 0 1 0 Rz=+Sz Cz 0
388 // 0 +Sx Cx -Sy 0 Cy 0 0 1
389 // The choice of the since of S, comes from the choice between
390 // the rotation of the object or the coordinate system (view). I think
391 // that this choice is the first, the rotation of the object.
399 // get angles from matrix up to a phase of 180 degrees.
401 rx = TMath::ATan2(fm[2][1],fm[2][2]);if(rx<0.0) rx += 2.0*TMath::Pi();
402 ry = TMath::ASin(-fm[0][2]); if(ry<0.0) ry += 2.0*TMath::Pi();
403 rz = TMath::ATan2(fm[1][0],fm[0][0]);if(rz<0.0) rz += 2.0*TMath::Pi();
409 //----------------------------------------------------------------------
410 void AliITSgeomMatrix::MatrixFromAngle(){
411 // Computes the Rotation matrix from the angles [radians] kept in this
412 // class. The matrix used in AliITSgeomMatrix::MatrixFromAngle() and
413 // its inverse AliITSgeomMatrix::AngleFromMatrix() are defined in
414 // the following ways, R = Rz*Ry*Rx (M=R*L+T) where
415 // 1 0 0 Cy 0 +Sy Cz -Sz 0
416 // Rx= 0 Cx -Sx Ry= 0 1 0 Rz=+Sz Cz 0
417 // 0 +Sx Cx -Sy 0 Cy 0 0 1
418 // The choice of the since of S, comes from the choice between
419 // the rotation of the object or the coordinate system (view). I think
420 // that this choice is the first, the rotation of the object.
427 Double_t sx,sy,sz,cx,cy,cz;
429 sx = TMath::Sin(frot[0]); cx = TMath::Cos(frot[0]);
430 sy = TMath::Sin(frot[1]); cy = TMath::Cos(frot[1]);
431 sz = TMath::Sin(frot[2]); cz = TMath::Cos(frot[2]);
432 fm[0][0] = +cz*cy; // fr[0]
433 fm[0][1] = +cz*sy*sx - sz*cx; // fr[1]
434 fm[0][2] = +cz*sy*cx + sz*sx; // fr[2]
435 fm[1][0] = +sz*cy; // fr[3]
436 fm[1][1] = +sz*sy*sx + cz*cx; // fr[4]
437 fm[1][2] = +sz*sy*cx - cz*sx; // fr[5]
438 fm[2][0] = -sy; // fr[6]
439 fm[2][1] = +cy*sx; // fr[7]
440 fm[2][2] = +cy*cx; // fr[8]
442 //----------------------------------------------------------------------
443 void AliITSgeomMatrix::SetEulerAnglesChi(const Double_t ang[3]){
444 // Computes the Rotation matrix from the Euler angles [radians],
445 // Chi-convention, kept in this class. The matrix used in
446 // AliITSgeomMatrix::SetEulerAnglesChi and
447 // its inverse AliITSgeomMatrix::GetEulerAnglesChi() are defined in
448 // the following ways, R = Rb*Rc*Rd (M=R*L+T) where
449 // C2 +S2 0 1 0 0 C0 +S0 0
450 // Rb=-S2 C2 0 Rc= 0 C1 +S1 Rd=-S0 C0 0
451 // 0 0 1 0 -S1 C1 0 0 1
452 // This form is taken from Wolfram Research's Geometry>
453 // Transformations>Rotations web page (also should be
454 // found in their book).
456 // Double_t ang[3] The three Euler Angles Phi, Theta, Psi
461 Double_t s0,s1,s2,c0,c1,c2;
463 s0 = TMath::Sin(ang[0]); c0 = TMath::Cos(ang[0]);
464 s1 = TMath::Sin(ang[1]); c1 = TMath::Cos(ang[1]);
465 s2 = TMath::Sin(ang[2]); c2 = TMath::Cos(ang[2]);
466 fm[0][0] = +c2*c0-c1*s0*s2; // fr[0]
467 fm[0][1] = +c2*s0+c1*c0*s2; // fr[1]
468 fm[0][2] = +s2*s1; // fr[2]
469 fm[1][0] = -s2*c0-c1*s0*c2; // fr[3]
470 fm[1][1] = -s2*s0+c1*c0*c2; // fr[4]
471 fm[1][2] = +c2*s1; // fr[5]
472 fm[2][0] = s1*s0; // fr[6]
473 fm[2][1] = -s1*c0; // fr[7]
474 fm[2][2] = +c1; // fr[8]
478 //----------------------------------------------------------------------
479 void AliITSgeomMatrix::GtoLPosition(const Double_t g0[3],Double_t l[3]) const {
480 // Returns the local coordinates given the global coordinates [cm].
482 // Double_t g[3] The position represented in the ALICE
483 // global coordinate system
485 // Double_t l[3] The poistion represented in the local
486 // detector coordiante system
492 for(i=0;i<3;i++) g[i] = g0[i] - ftran[i];
495 for(j=0;j<3;j++) l[i] += fm[i][j]*g[j];
496 // g = R l + translation
500 //----------------------------------------------------------------------
501 void AliITSgeomMatrix::LtoGPosition(const Double_t l[3],Double_t g[3]) const {
502 // Returns the global coordinates given the local coordinates [cm].
504 // Double_t l[3] The poistion represented in the detector
505 // local coordinate system
507 // Double_t g[3] The poistion represented in the ALICE
508 // Global coordinate system
515 for(j=0;j<3;j++) g[i] += fm[j][i]*l[j];
517 // g = R^t l + translation
521 //----------------------------------------------------------------------
522 void AliITSgeomMatrix::GtoLMomentum(const Double_t g[3],Double_t l[3]) const{
523 // Returns the local coordinates of the momentum given the global
524 // coordinates of the momentum. It transforms just like GtoLPosition
525 // except that the translation vector is zero.
527 // Double_t g[3] The momentum represented in the ALICE global
530 // Double_t l[3] the momentum represented in the detector
531 // local coordinate system
538 for(j=0;j<3;j++) l[i] += fm[i][j]*g[j];
543 //----------------------------------------------------------------------
544 void AliITSgeomMatrix::LtoGMomentum(const Double_t l[3],Double_t g[3]) const {
545 // Returns the Global coordinates of the momentum given the local
546 // coordinates of the momentum. It transforms just like LtoGPosition
547 // except that the translation vector is zero.
549 // Double_t l[3] the momentum represented in the detector
550 // local coordinate system
552 // Double_t g[3] The momentum represented in the ALICE global
560 for(j=0;j<3;j++) g[i] += fm[j][i]*l[j];
565 //----------------------------------------------------------------------
566 void AliITSgeomMatrix::GtoLPositionError(const Double_t g[3][3],
567 Double_t l[3][3]) const {
568 // Given an Uncertainty matrix in Global coordinates it is
569 // rotated so that its representation in local coordinates can
570 // be returned. There is no effect due to the translation vector
571 // or its uncertainty.
573 // Double_t g[3][3] The error matrix represented in the ALICE global
576 // Double_t l[3][3] the error matrix represented in the detector
577 // local coordinate system
582 for(i=0;i<3;i++)for(m=0;m<3;m++){
584 for(j=0;j<3;j++)for(k=0;k<3;k++)
585 l[i][m] += fm[j][i]*g[j][k]*fm[k][m];
590 //----------------------------------------------------------------------
591 void AliITSgeomMatrix::LtoGPositionError(const Double_t l[3][3],
592 Double_t g[3][3]) const {
593 // Given an Uncertainty matrix in Local coordinates it is rotated so that
594 // its representation in global coordinates can be returned. There is no
595 // effect due to the translation vector or its uncertainty.
597 // Double_t l[3][3] the error matrix represented in the detector
598 // local coordinate system
600 // Double_t g[3][3] The error matrix represented in the ALICE global
606 for(i=0;i<3;i++)for(m=0;m<3;m++){
608 for(j=0;j<3;j++)for(k=0;k<3;k++)
609 g[i][m] += fm[i][j]*l[j][k]*fm[m][k];
614 //----------------------------------------------------------------------
615 void AliITSgeomMatrix::GtoLPositionTracking(const Double_t g[3],
616 Double_t l[3]) const {
617 // A slightly different coordinate system is used when tracking.
618 // This coordinate system is only relevant when the geometry represents
619 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
620 // alone but X -> -Y and Y -> X such that X always points out of the
621 // ITS Cylinder for every layer including layer 1 (where the detector
622 // are mounted upside down).
625 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
629 // Double_t g[3] The position represented in the ALICE
630 // global coordinate system
632 // Double_t l[3] The poistion represented in the local
633 // detector coordiante system
638 this->GtoLPosition(g,l0);
639 if(fid[0]==1){ // for layer 1 the detector are flipped upside down
640 // with respect to the others.
651 //----------------------------------------------------------------------
652 void AliITSgeomMatrix::LtoGPositionTracking(const Double_t l[3],
653 Double_t g[3]) const {
654 // A slightly different coordinate system is used when tracking.
655 // This coordinate system is only relevant when the geometry represents
656 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
657 // alone but X -> -Y and Y -> X such that X always points out of the
658 // ITS Cylinder for every layer including layer 1 (where the detector
659 // are mounted upside down).
662 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
666 // Double_t l[3] The poistion represented in the detector
667 // local coordinate system
669 // Double_t g[3] The poistion represented in the ALICE
670 // Global coordinate system
675 if(fid[0]==1){ // for layer 1 the detector are flipped upside down
676 // with respect to the others.
685 this->LtoGPosition(l0,g);
688 //----------------------------------------------------------------------
689 void AliITSgeomMatrix::GtoLMomentumTracking(const Double_t g[3],
690 Double_t l[3]) const {
691 // A slightly different coordinate system is used when tracking.
692 // This coordinate system is only relevant when the geometry represents
693 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
694 // alone but X -> -Y and Y -> X such that X always points out of the
695 // ITS Cylinder for every layer including layer 1 (where the detector
696 // are mounted upside down).
699 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
703 // Double_t g[3] The momentum represented in the ALICE global
706 // Double_t l[3] the momentum represented in the detector
707 // local coordinate system
712 this->GtoLMomentum(g,l0);
713 if(fid[0]==1){ // for layer 1 the detector are flipped upside down
714 // with respect to the others.
725 //----------------------------------------------------------------------
726 void AliITSgeomMatrix::LtoGMomentumTracking(const Double_t l[3],
727 Double_t g[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).
736 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
740 // Double_t l[3] the momentum represented in the detector
741 // local coordinate system
743 // Double_t g[3] The momentum represented in the ALICE global
749 if(fid[0]==1){ // for layer 1 the detector are flipped upside down
750 // with respect to the others.
759 this->LtoGMomentum(l0,g);
762 //----------------------------------------------------------------------
763 void AliITSgeomMatrix::GtoLPositionErrorTracking(const Double_t g[3][3],
764 Double_t l[3][3]) const {
765 // A slightly different coordinate system is used when tracking.
766 // This coordinate system is only relevant when the geometry represents
767 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
768 // alone but X -> -Y and Y -> X such that X always points out of the
769 // ITS Cylinder for every layer including layer 1 (where the detector
770 // are mounted upside down).
773 <img src="picts/ITS/AliITSgeomMatrix_TE1.gif">
777 // Double_t g[3][3] The error matrix represented in the ALICE global
780 // Double_t l[3][3] the error matrix represented in the detector
781 // local coordinate system
785 Double_t a0[3][3] = {{0.,+1.,0.},{-1.,0.,0.},{0.,0.,+1.}};
786 Double_t a1[3][3] = {{0.,-1.,0.},{+1.,0.,0.},{0.,0.,+1.}};
788 if(fid[0]==1) for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
789 rt[i][k] = a0[i][j]*fm[j][k];
790 else for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
791 rt[i][k] = a1[i][j]*fm[j][k];
792 for(i=0;i<3;i++)for(m=0;m<3;m++){
794 for(j=0;j<3;j++)for(k=0;k<3;k++)
795 l[i][m] += rt[j][i]*g[j][k]*rt[k][m];
800 //----------------------------------------------------------------------
801 void AliITSgeomMatrix::LtoGPositionErrorTracking(const Double_t l[3][3],
802 Double_t g[3][3]) const {
803 // A slightly different coordinate system is used when tracking.
804 // This coordinate system is only relevant when the geometry represents
805 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
806 // alone but X -> -Y and Y -> X such that X always points out of the
807 // ITS Cylinder for every layer including layer 1 (where the detector
808 // are mounted upside down).
811 <img src="picts/ITS/AliITSgeomMatrix_TE1.gif">
815 // Double_t l[3][3] the error matrix represented in the detector
816 // local coordinate system
818 // Double_t g[3][3] The error matrix represented in the ALICE global
824 Double_t a0[3][3] = {{0.,+1.,0.},{-1.,0.,0.},{0.,0.,+1.}};
825 Double_t a1[3][3] = {{0.,-1.,0.},{+1.,0.,0.},{0.,0.,+1.}};
827 if(fid[0]==1) for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
828 rt[i][k] = a0[i][j]*fm[j][k];
829 else for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
830 rt[i][k] = a1[i][j]*fm[j][k];
831 for(i=0;i<3;i++)for(m=0;m<3;m++){
833 for(j=0;j<3;j++)for(k=0;k<3;k++)
834 g[i][m] += rt[i][j]*l[j][k]*rt[m][k];
839 //----------------------------------------------------------------------
840 void AliITSgeomMatrix::PrintTitles(ostream *os) const {
841 // Standard output format for this class but it includes variable
842 // names and formatting that makes it easer to read.
844 // ostream *os The output stream to print the title on
851 *os << "fDetectorIndex=" << fDetectorIndex << " fid[3]={";
852 for(i=0;i<3;i++) *os << fid[i] << " ";
853 *os << "} frot[3]={";
854 for(i=0;i<3;i++) *os << frot[i] << " ";
855 *os << "} ftran[3]={";
856 for(i=0;i<3;i++) *os << ftran[i] << " ";
857 *os << "} fm[3][3]={";
858 for(i=0;i<3;i++){for(j=0;j<3;j++){ *os << fm[i][j] << " ";} *os <<"}{";}
862 //----------------------------------------------------------------------
863 void AliITSgeomMatrix::PrintComment(ostream *os) const {
864 // output format used by Print.
866 // ostream *os The output stream to print the comments on
871 *os << "fDetectorIndex fid[0] fid[1] fid[2] ftran[0] ftran[1] ftran[2] ";
872 *os << "fm[0][0] fm[0][1] fm[0][2] fm[1][0] fm[1][1] fm[1][2] ";
873 *os << "fm[2][0] fm[2][1] fm[2][2] ";
876 //----------------------------------------------------------------------
877 void AliITSgeomMatrix::Print(ostream *os)const{
878 // Standard output format for this class.
880 // ostream *os The output stream to print the class data on
893 #if defined __ICC || defined __ECC || defined __xlC__
900 fmt = os->setf(ios::scientific); // set scientific floating point output
901 *os << fDetectorIndex << " ";
902 for(i=0;i<3;i++) *os << fid[i] << " ";
903 // for(i=0;i<3;i++) *os << frot[i] << " "; // Redundant with fm[][].
904 for(i=0;i<3;i++) *os << setprecision(16) << ftran[i] << " ";
905 for(i=0;i<3;i++)for(j=0;j<3;j++) *os << setprecision(16) <<
907 *os << fPath.Length()<< " ";
908 for(i=0;i<fPath.Length();i++) *os << fPath[i];
910 os->flags(fmt); // reset back to old formating.
913 //----------------------------------------------------------------------
914 void AliITSgeomMatrix::Read(istream *is){
915 // Standard input format for this class.
917 // istream *is The input stream to read on
923 const Int_t kMxVal=10000;
924 *is >> fDetectorIndex;
925 for(i=0;i<3;i++) *is >> fid[i];
926 // for(i=0;i<3;i++) *is >> frot[i]; // Redundant with fm[][].
927 for(i=0;i<3;i++) *is >> ftran[i];
928 for(i=0;i<3;i++)for(j=0;j<3;j++) *is >> fm[i][j];
929 while(is->peek()==' ')is->get(); // skip white spaces
930 if(isprint(is->peek())){ // old format did not have path.
931 *is >> j; // string length
933 AliError(Form("j> %d",kMxVal));
937 for(i=0;i<j;i++) {*is >> fPath[i];}
939 AngleFromMatrix(); // compute angles frot[].
940 fCylR = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
941 fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
942 if(fCylPhi<0.0) fCylPhi += 2.*TMath::Pi();
945 //______________________________________________________________________
946 void AliITSgeomMatrix::Streamer(TBuffer &R__b){
947 // Stream an object of class AliITSgeomMatrix.
949 // TBuffer &R__b The output buffer to stream data on.
955 if (R__b.IsReading()) {
956 AliITSgeomMatrix::Class()->ReadBuffer(R__b, this);
957 fCylR = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
958 fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
959 this->AngleFromMatrix();
960 if(fCylPhi<0.0) fCylPhi += 2.*TMath::Pi();
962 AliITSgeomMatrix::Class()->WriteBuffer(R__b, this);
965 //______________________________________________________________________
966 void AliITSgeomMatrix::SetTranslation(const Double_t tran[3]){
967 // Sets the translation vector and computes fCylR and fCylPhi.
969 // Double_t trans[3] The translation vector to be used
974 for(Int_t i=0;i<3;i++) ftran[i] = tran[i];
975 fCylR = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
976 fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
977 if(fCylPhi<0.0) fCylPhi += 2.*TMath::Pi();
979 //----------------------------------------------------------------------
980 TPolyLine3D* AliITSgeomMatrix::CreateLocalAxis() const {
981 // This class is used as part of the documentation of this class
987 // A pointer to a new TPolyLine3D object showing the 3 line
988 // segments that make up the this local axis in the global
992 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},
997 LtoGPosition(l[i],g[i]);
998 gf[3*i]=(Float_t)g[i][0];
999 gf[3*i+1]=(Float_t)g[i][1];
1000 gf[3*i+2]=(Float_t)g[i][2];
1002 return new TPolyLine3D(5,gf);
1004 //----------------------------------------------------------------------
1005 TPolyLine3D* AliITSgeomMatrix::CreateLocalAxisTracking() const {
1006 // This class is used as part of the documentation of this class
1012 // A pointer to a new TPolyLine3D object showing the 3 line
1013 // segments that make up the this local axis in the global
1014 // reference system.
1017 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},
1022 LtoGPositionTracking(l[i],g[i]);
1023 gf[3*i]=(Float_t)g[i][0];
1024 gf[3*i+1]=(Float_t)g[i][1];
1025 gf[3*i+2]=(Float_t)g[i][2];
1027 return new TPolyLine3D(5,gf);
1029 //----------------------------------------------------------------------
1030 TNode* AliITSgeomMatrix::CreateNode(const Char_t *nodeName,
1031 const Char_t *nodeTitle,TNode *mother,
1032 TShape *shape,Bool_t axis) const {
1033 // Creates a node inside of the node mother out of the shape shape
1034 // in the position, with respect to mother, indecated by "this". If axis
1035 // is ture, it will insert an axis within this node/shape.
1037 // Char_t *nodeName This name of this node
1038 // Char_t *nodeTitle This node title
1039 // TNode *mother The node this node will be inside of/with respect to
1040 // TShape *shape The shape of this node
1041 // Bool_t axis If ture, a set of x,y,z axis will be included
1045 // A pointer to "this" node.
1046 Double_t trans[3],matrix[3][3],*matr;
1047 TRotMatrix *rot = new TRotMatrix();
1050 matr = &(matrix[0][0]);
1051 this->GetTranslation(trans);
1052 this->GetMatrix(matrix);
1053 rot->SetMatrix(matr);
1059 TNode *node1 = new TNode(name.Data(),title.Data(),shape,
1060 trans[0],trans[1],trans[2],rot);
1063 const Float_t kScale=0.5,kLw=0.2;
1064 Float_t xchar[13][2]={
1065 {static_cast<Float_t>(0.5*kLw),1.},{0.,static_cast<Float_t>(0.5*kLw)},{static_cast<Float_t>(0.5-0.5*kLw),0.5},
1066 {0.,static_cast<Float_t>(0.5*kLw)},{static_cast<Float_t>(0.5*kLw),0.},{0.5,static_cast<Float_t>(0.5-0.5*kLw)},
1067 {static_cast<Float_t>(1-0.5*kLw),0.},{1.,static_cast<Float_t>(0.5*kLw)},{static_cast<Float_t>(0.5+0.5*kLw),0.5},
1068 {1.,static_cast<Float_t>(1.-0.5*kLw)},{static_cast<Float_t>(1.-0.5*kLw),1.},{0.5,static_cast<Float_t>(0.5+0.5*kLw)},
1069 {static_cast<Float_t>(0.5*kLw),1.}};
1070 Float_t ychar[10][2]={
1071 {static_cast<Float_t>(.5-0.5*kLw),0.},{static_cast<Float_t>(.5+0.5*kLw),0.},{static_cast<Float_t>(.5+0.5*kLw),static_cast<Float_t>(0.5-0.5*kLw)},
1072 {1.,static_cast<Float_t>(1.-0.5*kLw)},{static_cast<Float_t>(1.-0.5*kLw),1.},{static_cast<Float_t>(0.5+0.5*kLw),0.5},
1073 {static_cast<Float_t>(0.5*kLw),1.} ,{0.,static_cast<Float_t>(1-0.5*kLw)} ,{static_cast<Float_t>(0.5-0.5*kLw),0.5},
1074 {static_cast<Float_t>(.5-0.5*kLw),0.}};
1075 Float_t zchar[11][2]={
1076 {0.,1.},{0,static_cast<Float_t>(1.-kLw)},{static_cast<Float_t>(1.-kLw),static_cast<Float_t>(1.-kLw)},{0.,kLw} ,{0.,0.},
1077 {1.,0.},{1.,kLw} ,{kLw,kLw} ,{1.,static_cast<Float_t>(1.-kLw)},{1.,1.},
1079 for(i=0;i<13;i++)for(j=0;j<2;j++){
1080 if(i<13) xchar[i][j] = kScale*xchar[i][j];
1081 if(i<10) ychar[i][j] = kScale*ychar[i][j];
1082 if(i<11) zchar[i][j] = kScale*zchar[i][j];
1084 TXTRU *axisxl = new TXTRU("x","x","text",12,2);
1085 for(i=0;i<12;i++) axisxl->DefineVertex(i,xchar[i][0],xchar[i][1]);
1086 axisxl->DefineSection(0,-0.5*kLw);axisxl->DefineSection(1,0.5*kLw);
1087 TXTRU *axisyl = new TXTRU("y","y","text",9,2);
1088 for(i=0;i<9;i++) axisyl->DefineVertex(i,ychar[i][0],ychar[i][1]);
1089 axisyl->DefineSection(0,-0.5*kLw);axisyl->DefineSection(1,0.5*kLw);
1090 TXTRU *axiszl = new TXTRU("z","z","text",10,2);
1091 for(i=0;i<10;i++) axiszl->DefineVertex(i,zchar[i][0],zchar[i][1]);
1092 axiszl->DefineSection(0,-0.5*kLw);axiszl->DefineSection(1,0.5*kLw);
1093 Float_t lxy[13][2]={
1094 {static_cast<Float_t>(-0.5*kLw),static_cast<Float_t>(-0.5*kLw)},{0.8,static_cast<Float_t>(-0.5*kLw)},{0.8,-0.1},{1.0,0.0},
1095 {0.8,0.1},{0.8,static_cast<Float_t>(0.5*kLw)},{static_cast<Float_t>(0.5*kLw),static_cast<Float_t>(0.5*kLw)},{static_cast<Float_t>(0.5*kLw),0.8},
1096 {0.1,0.8},{0.0,1.0},{-0.1,0.8},{static_cast<Float_t>(-0.5*kLw),0.8},
1097 {static_cast<Float_t>(-0.5*kLw),static_cast<Float_t>(-0.5*kLw)}};
1098 TXTRU *axisxy = new TXTRU("axisxy","axisxy","text",13,2);
1099 for(i=0;i<13;i++) axisxy->DefineVertex(i,lxy[i][0],lxy[i][1]);
1100 axisxy->DefineSection(0,-0.5*kLw);axisxy->DefineSection(1,0.5*kLw);
1102 {static_cast<Float_t>(0.5*kLw),static_cast<Float_t>(-0.5*kLw)},{0.8,static_cast<Float_t>(-0.5*kLw)},{0.8,-0.1},{1.0,0.0},
1103 {0.8,0.1},{0.8,static_cast<Float_t>(0.5*kLw)},{static_cast<Float_t>(0.5*kLw),static_cast<Float_t>(0.5*kLw)},
1104 {static_cast<Float_t>(0.5*kLw),static_cast<Float_t>(-0.5*kLw)}};
1105 TXTRU *axisz = new TXTRU("axisz","axisz","text",8,2);
1106 for(i=0;i<8;i++) axisz->DefineVertex(i,lz[i][0],lz[i][1]);
1107 axisz->DefineSection(0,-0.5*kLw);axisz->DefineSection(1,0.5*kLw);
1108 //TRotMatrix *xaxis90= new TRotMatrix("xaixis90","",90.0, 0.0, 0.0);
1109 TRotMatrix *yaxis90= new TRotMatrix("yaixis90","", 0.0,90.0, 0.0);
1110 TRotMatrix *zaxis90= new TRotMatrix("zaixis90","", 0.0, 0.0,90.0);
1113 title = name.Append("axisxy");
1114 TNode *nodeaxy = new TNode(title.Data(),title.Data(),axisxy);
1115 title = name.Append("axisz");
1116 TNode *nodeaz = new TNode(title.Data(),title.Data(),axisz,
1118 TNode *textboxX0 = new TNode("textboxX0","textboxX0",axisxl,
1119 lxy[3][0],lxy[3][1],0.0);
1120 TNode *textboxX1 = new TNode("textboxX1","textboxX1",axisxl,
1121 lxy[3][0],lxy[3][1],0.0,yaxis90);
1122 TNode *textboxX2 = new TNode("textboxX2","textboxX2",axisxl,
1123 lxy[3][0],lxy[3][1],0.0,zaxis90);
1124 TNode *textboxY0 = new TNode("textboxY0","textboxY0",axisyl,
1125 lxy[9][0],lxy[9][1],0.0);
1126 TNode *textboxY1 = new TNode("textboxY1","textboxY1",axisyl,
1127 lxy[9][0],lxy[9][1],0.0,yaxis90);
1128 TNode *textboxY2 = new TNode("textboxY2","textboxY2",axisyl,
1129 lxy[9][0],lxy[9][1],0.0,zaxis90);
1130 TNode *textboxZ0 = new TNode("textboxZ0","textboxZ0",axiszl,
1132 TNode *textboxZ1 = new TNode("textboxZ1","textboxZ1",axiszl,
1133 0.0,0.0,lz[3][0],yaxis90);
1134 TNode *textboxZ2 = new TNode("textboxZ2","textboxZ2",axiszl,
1135 0.0,0.0,lz[3][0],zaxis90);
1151 //----------------------------------------------------------------------
1152 void AliITSgeomMatrix::MakeFigures() const {
1153 // make figures to help document this class
1160 const Double_t kDx0=550.,kDy0=550.,kDz0=550.; // cm
1161 const Double_t kDx=1.0,kDy=0.300,kDz=3.0,kRmax=0.1; // cm
1162 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},
1164 TCanvas *c = new TCanvas(kFALSE);// create a batch mode canvas.
1165 #if ROOT_VERSION_CODE>= 331523
1166 Double_t rmin[]={-1,-1,-1};
1167 Double_t rmax[]={ 1, 1, 1};
1168 TView *view = new TView3D(1,rmin,rmax);
1170 TView *view = new TView(1); // Create Cartesian coordiante view
1172 TBRIK *mother = new TBRIK("Mother","Mother","void",kDx0,kDy0,kDz0);
1173 TBRIK *det = new TBRIK("Detector","","Si",kDx,kDy,kDz);
1174 TPolyLine3D *axis = new TPolyLine3D(5,&(l[0][0]));
1175 TPCON *arrow = new TPCON("arrow","","air",0.0,360.,2);
1176 TRotMatrix *xarrow= new TRotMatrix("xarrow","",90.,0.0,0.0);
1177 TRotMatrix *yarrow= new TRotMatrix("yarrow","",0.0,90.,0.0);
1179 det->SetLineColor(0); // black
1180 det->SetLineStyle(1); // solid line
1181 det->SetLineWidth(2); // pixel units
1182 det->SetFillColor(1); // black
1183 det->SetFillStyle(4010); // window is 90% transparent
1184 arrow->SetLineColor(det->GetLineColor());
1185 arrow->SetLineWidth(det->GetLineWidth());
1186 arrow->SetLineStyle(det->GetLineStyle());
1187 arrow->SetFillColor(1); // black
1188 arrow->SetFillStyle(4100); // window is 100% opaque
1189 arrow->DefineSection(0,0.0,0.0,kRmax);
1190 arrow->DefineSection(1,2.*kRmax,0.0,0.0);
1191 view->SetRange(-kDx0,-kDy0,-kDz0,kDx0,kDy0,kDz0);
1193 TNode *node0 = new TNode("NODE0","NODE0",mother);
1195 TNode *node1 = new TNode("NODE1","NODE1",det);
1197 TNode *nodex = new TNode("NODEx","NODEx",arrow,
1198 l[0][0],l[0][1],l[0][2],xarrow);
1199 TNode *nodey = new TNode("NODEy","NODEy",arrow,
1200 l[2][0],l[2][1],l[2][2],yarrow);
1201 TNode *nodez = new TNode("NODEz","NODEz",arrow,l[4][0],l[4][1],l[4][2]);
1212 c->SaveAs("AliITSgeomMatrix_L1.gif");
1214 //----------------------------------------------------------------------
1215 ostream &operator<<(ostream &os,AliITSgeomMatrix &p){
1216 // Standard output streaming function.
1218 // ostream &os The output stream to print the class data on
1219 // AliITSgeomMatrix &p This class
1228 //----------------------------------------------------------------------
1229 istream &operator>>(istream &is,AliITSgeomMatrix &r){
1230 // Standard input streaming function.
1232 // ostream &os The input stream to print the class data on
1233 // AliITSgeomMatrix &p This class
1242 //----------------------------------------------------------------------