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():
50 TObject(), // Base Class.
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;
88 fm[0][0] = fm[1][1] = fm[2][2] = 1.0;
91 //----------------------------------------------------------------------
92 AliITSgeomMatrix::AliITSgeomMatrix(const AliITSgeomMatrix &source) :
93 TObject(source), // Base Class.
94 fDetectorIndex(source.fDetectorIndex),// Detector type index (like
96 fid(), // layer, ladder, detector numbers.
97 frot(), //! vector of rotations about x,y,z [radians].
98 ftran(), // Translation vector of module x,y,z.
99 fCylR(source.fCylR), //! R Translation in Cylinderical coordinates
100 fCylPhi(source.fCylPhi),//! Phi Translation vector in Cylindrical coord.
101 fm(), // Rotation matrix based on frot.
103 // The standard Copy constructor. This make a full / proper copy of
106 // AliITSgeomMatrix &source The source of this copy
110 // A copy constructes AliITSgeomMatrix class.
114 this->fid[i] = source.fid[i];
115 this->frot[i] = source.frot[i];
116 this->ftran[i] = source.ftran[i];
117 for(j=0;j<3;j++) this->fm[i][j] = source.fm[i][j];
120 //----------------------------------------------------------------------
121 AliITSgeomMatrix& AliITSgeomMatrix::operator=(const AliITSgeomMatrix &source){
122 // The standard = operator. This make a full / proper copy of
124 // The standard Copy constructor. This make a full / proper copy of
127 // AliITSgeomMatrix &source The source of this copy
131 // A copy of the source AliITSgeomMatrix class.
133 if(this == &source)return *this;
136 this->fDetectorIndex = source.fDetectorIndex;
137 this->fCylR = source.fCylR;
138 this->fCylPhi = source.fCylPhi;
140 this->fid[i] = source.fid[i];
141 this->frot[i] = source.frot[i];
142 this->ftran[i] = source.ftran[i];
143 for(j=0;j<3;j++) this->fm[i][j] = source.fm[i][j];
145 this->fPath = source.fPath;
148 //----------------------------------------------------------------------
149 AliITSgeomMatrix::AliITSgeomMatrix(Int_t idt,const Int_t id[3],
150 const Double_t rot[3],const Double_t tran[3]):
151 TObject(), // Base class
152 fDetectorIndex(idt), // Detector type index (like fShapeIndex was)
153 fid(), // layer, ladder, detector numbers.
154 frot(), //! vector of rotations about x,y,z [radians].
155 ftran(), // Translation vector of module x,y,z.
156 fCylR(0.0), //! R Translation in Cylinderical coordinates
157 fCylPhi(0.0),//! Phi Translation vector in Cylindrical coord.
158 fm(), // Rotation matrix based on frot.
159 fPath(){ // Path in geometry to this moduel
160 // This is a constructor for the AliITSgeomMatrix class. The matrix is
161 // defined by 3 standard rotation angles [radians], and the translation
162 // vector tran [cm]. In addition the layer, ladder, and detector number
163 // for this particular module and the type of module must be given.
164 // The full rotation matrix is kept so that the evaluation
165 // of a coordinate transformation can be done quickly and with a minimum
166 // of CPU overhead. The basic coordinate systems are the ALICE global
167 // coordinate system and the detector local coordinate system. In general
168 // this structure is not limited to just those two coordinate systems.
171 <img src="picts/ITS/AliITSgeomMatrix_L1.gif">
175 // Int_t idt The detector index value
176 // Int_t id[3] The layer, ladder, and detector numbers
177 // Double_t rot[3] The 3 Cartician rotaion angles [radians]
178 // Double_t tran[3] The 3 Cartician translation distnaces
182 // A properly inilized AliITSgeomMatrix class.
190 fCylR = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
191 fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
192 if(fCylPhi<0.0) fCylPhi += 2.*TMath::Pi();
193 this->MatrixFromAngle();
195 //----------------------------------------------------------------------
196 AliITSgeomMatrix::AliITSgeomMatrix(Int_t idt, const Int_t id[3],
197 Double_t matrix[3][3],
198 const Double_t tran[3]):
199 TObject(), // Base class
200 fDetectorIndex(idt), // Detector type index (like fShapeIndex was)
201 fid(), // layer, ladder, detector numbers.
202 frot(), //! vector of rotations about x,y,z [radians].
203 ftran(), // Translation vector of module x,y,z.
204 fCylR(0.0), //! R Translation in Cylinderical coordinates
205 fCylPhi(0.0),//! Phi Translation vector in Cylindrical coord.
206 fm(), // Rotation matrix based on frot.
207 fPath(){ // Path in geometry to this module
208 // This is a constructor for the AliITSgeomMatrix class. The
209 // rotation matrix is given as one of the inputs, and the
210 // translation vector tran [cm]. In addition the layer, ladder,
211 // and detector number for this particular module and the type of
212 // module must be given. The full rotation matrix is kept so that
213 // the evaluation of a coordinate transformation can be done quickly
214 // and with a minimum of CPU overhead. The basic coordinate systems
215 // are the ALICE global coordinate system and the detector local
216 // coordinate system. In general this structure is not limited to just
217 // those two coordinate systems.
220 <img src="picts/ITS/AliITSgeomMatrix_L1.gif">
224 // Int_t idt The detector index value
225 // Int_t id[3] The layer, ladder, and detector numbers
226 // Double_t rot[3][3] The 3x3 Cartician rotaion matrix
227 // Double_t tran[3] The 3 Cartician translation distnaces
231 // A properly inilized AliITSgeomMatrix class.
237 for(j=0;j<3;j++) fm[i][j] = matrix[i][j];
239 fCylR = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
240 fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
241 if(fCylPhi<0.0) fCylPhi += 2.*TMath::Pi();
242 this->AngleFromMatrix();
244 //----------------------------------------------------------------------
245 void AliITSgeomMatrix::SixAnglesFromMatrix(Double_t *ang)const{
246 // This function returns the 6 GEANT 3.21 rotation angles [degrees] in
247 // the array ang which must be at least [6] long.
251 // Double_t ang[6] The 6 Geant3.21 rotation angles. [degrees]
254 Double_t si,c=180./TMath::Pi();
255 const Double_t epsil=1.e-15;
257 ang[1] = TMath::ATan2(fm[0][1],fm[0][0]);
258 if( !(TMath::AreEqualAbs(TMath::Cos(ang[1]),0.,epsil))) si = fm[0][0]/TMath::Cos(ang[1]);
259 else si = fm[0][1]/TMath::Sin(ang[1]);
260 ang[0] = TMath::ATan2(si,fm[0][2]);
262 ang[3] = TMath::ATan2(fm[1][1],fm[1][0]);
263 if(!(TMath::AreEqualAbs(TMath::Cos(ang[3]),0.,epsil))) si = fm[1][0]/TMath::Cos(ang[3]);
264 else si = fm[1][1]/TMath::Sin(ang[3]);
265 ang[2] = TMath::ATan2(si,fm[1][2]);
267 ang[5] = TMath::ATan2(fm[2][1],fm[2][0]);
268 if(!(TMath::AreEqualAbs(TMath::Cos(ang[5]),0.,epsil))) si = fm[2][0]/TMath::Cos(ang[5]);
269 else si = fm[2][1]/TMath::Sin(ang[5]);
270 ang[4] = TMath::ATan2(si,fm[2][2]);
272 for(Int_t i=0;i<6;i++) {ang[i] *= c; if(ang[i]<0.0) ang[i] += 360.;}
274 //----------------------------------------------------------------------
275 void AliITSgeomMatrix::MatrixFromSixAngles(const Double_t *ang){
276 // Given the 6 GEANT 3.21 rotation angles [degree], this will compute and
277 // set the rotations matrix and 3 standard rotation angles [radians].
278 // These angles and rotation matrix are overwrite the existing values in
281 // Double_t ang[6] The 6 Geant3.21 rotation angles. [degrees]
287 Double_t si,lr[9],c=TMath::Pi()/180.;
288 const Double_t epsil = 1.e-15;
290 si = TMath::Sin(c*ang[0]);
291 if(TMath::AreEqualAbs(ang[0],90.,epsil)) si = +1.0;
292 if(TMath::AreEqualAbs(ang[0],270.,epsil)) si = -1.0;
293 if(TMath::AreEqualAbs(ang[0],0.,epsil) ||TMath::AreEqualAbs(ang[0],180.,epsil)) si = 0.0;
294 lr[0] = si * TMath::Cos(c*ang[1]);
295 lr[1] = si * TMath::Sin(c*ang[1]);
296 lr[2] = TMath::Cos(c*ang[0]);
297 if(TMath::AreEqualAbs(ang[0],90.,epsil)||TMath::AreEqualAbs(ang[0],270.,epsil)) lr[2] = 0.0;
298 if(TMath::AreEqualAbs(ang[0],0.,epsil)) lr[2] = +1.0;
299 if(TMath::AreEqualAbs(ang[0],180.,epsil)) lr[2] = -1.0;
301 si = TMath::Sin(c*ang[2]);
302 if(TMath::AreEqualAbs(ang[2],90.,epsil)) si = +1.0;
303 if(TMath::AreEqualAbs(ang[2],270.,epsil)) si = -1.0;
304 if(TMath::AreEqualAbs(ang[2],0.,epsil) || TMath::AreEqualAbs(ang[2],180.,epsil)) si = 0.0;
305 lr[3] = si * TMath::Cos(c*ang[3]);
306 lr[4] = si * TMath::Sin(c*ang[3]);
307 lr[5] = TMath::Cos(c*ang[2]);
308 if(TMath::AreEqualAbs(ang[2],90.,epsil) || TMath::AreEqualAbs(ang[2],270.,epsil)) lr[5] = 0.0;
309 if(TMath::AreEqualAbs(ang[2],0.,epsil)) lr[5] = +1.0;
310 if(TMath::AreEqualAbs(ang[2],180.,epsil)) lr[5] = -1.0;
312 si = TMath::Sin(c*ang[4]);
313 if(TMath::AreEqualAbs(ang[4],90.,epsil)) si = +1.0;
314 if(TMath::AreEqualAbs(ang[4],270.0,epsil)) si = -1.0;
315 if(TMath::AreEqualAbs(ang[4],0.,epsil)|| TMath::AreEqualAbs(ang[4],180.,epsil)) si = 0.0;
316 lr[6] = si * TMath::Cos(c*ang[5]);
317 lr[7] = si * TMath::Sin(c*ang[5]);
318 lr[8] = TMath::Cos(c*ang[4]);
319 if(TMath::AreEqualAbs(ang[4],90.0,epsil) ||TMath::AreEqualAbs(ang[4],270.,epsil)) lr[8] = 0.0;
320 if(TMath::AreEqualAbs(ang[4],0.,epsil)) lr[8] = +1.0;
321 if(TMath::AreEqualAbs(ang[4],180.0,epsil)) lr[8] = -1.0;
322 // Normalize these elements and fill matrix fm.
323 for(i=0;i<3;i++){// reuse si.
325 for(j=0;j<3;j++) si += lr[3*i+j]*lr[3*i+j];
326 si = TMath::Sqrt(1./si);
327 for(j=0;j<3;j++) fm[i][j] = si*lr[3*i+j];
329 this->AngleFromMatrix();
331 //----------------------------------------------------------------------
332 AliITSgeomMatrix::AliITSgeomMatrix(const Double_t rotd[6]/*degrees*/,
333 Int_t idt,const Int_t id[3],
334 const Double_t tran[3]):
335 TObject(), // Base class
336 fDetectorIndex(idt), // Detector type index (like fShapeIndex was)
337 fid(), // layer, ladder, detector numbers.
338 frot(), //! vector of rotations about x,y,z [radians].
339 ftran(), // Translation vector of module x,y,z.
340 fCylR(0.0), //! R Translation in Cylinderical coordinates
341 fCylPhi(0.0),//! Phi Translation vector in Cylindrical coord.
342 fm(), // Rotation matrix based on frot.
343 fPath(){ // Path in geometry to this module
344 // This is a constructor for the AliITSgeomMatrix class. The matrix
345 // is defined by the 6 GEANT 3.21 rotation angles [degrees], and
346 // the translation vector tran [cm]. In addition the layer, ladder,
347 // and detector number for this particular module and the type of
348 // module must be given. The full rotation matrix is kept so that
349 // the evaluation of a coordinate transformation can be done
350 // quickly and with a minimum of CPU overhead. The basic coordinate
351 // systems are the ALICE global coordinate system and the detector
352 // local coordinate system. In general this structure is not limited
353 // to just those two coordinate systems.
356 <img src="picts/ITS/AliITSgeomMatrix_L1.gif">
360 // Double_t rotd[6] The 6 Geant 3.21 rotation angles [degrees]
361 // Int_t idt The module Id number
362 // Int_t id[3] The layer, ladder and detector number
363 // Double_t tran[3] The translation vector
370 fCylR = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
371 fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
372 if(fCylPhi<0.0) fCylPhi += 2.*TMath::Pi();
373 this->MatrixFromSixAngles(rotd);
375 //----------------------------------------------------------------------
376 void AliITSgeomMatrix::AngleFromMatrix(){
377 // Computes the angles from the rotation matrix up to a phase of
378 // 180 degrees. The matrix used in AliITSgeomMatrix::MatrixFromAngle()
379 // and its inverse AliITSgeomMatrix::AngleFromMatrix() are defined in
380 // the following ways, R = Rz*Ry*Rx (M=R*L+T) where
381 // 1 0 0 Cy 0 +Sy Cz -Sz 0
382 // Rx= 0 Cx -Sx Ry= 0 1 0 Rz=+Sz Cz 0
383 // 0 +Sx Cx -Sy 0 Cy 0 0 1
384 // The choice of the since of S, comes from the choice between
385 // the rotation of the object or the coordinate system (view). I think
386 // that this choice is the first, the rotation of the object.
394 // get angles from matrix up to a phase of 180 degrees.
396 rx = TMath::ATan2(fm[2][1],fm[2][2]);if(rx<0.0) rx += 2.0*TMath::Pi();
397 ry = TMath::ASin(-fm[0][2]); if(ry<0.0) ry += 2.0*TMath::Pi();
398 rz = TMath::ATan2(fm[1][0],fm[0][0]);if(rz<0.0) rz += 2.0*TMath::Pi();
404 //----------------------------------------------------------------------
405 void AliITSgeomMatrix::MatrixFromAngle(){
406 // Computes the Rotation matrix from the angles [radians] kept in this
407 // class. The matrix used in AliITSgeomMatrix::MatrixFromAngle() and
408 // its inverse AliITSgeomMatrix::AngleFromMatrix() are defined in
409 // the following ways, R = Rz*Ry*Rx (M=R*L+T) where
410 // 1 0 0 Cy 0 +Sy Cz -Sz 0
411 // Rx= 0 Cx -Sx Ry= 0 1 0 Rz=+Sz Cz 0
412 // 0 +Sx Cx -Sy 0 Cy 0 0 1
413 // The choice of the since of S, comes from the choice between
414 // the rotation of the object or the coordinate system (view). I think
415 // that this choice is the first, the rotation of the object.
422 Double_t sx,sy,sz,cx,cy,cz;
424 sx = TMath::Sin(frot[0]); cx = TMath::Cos(frot[0]);
425 sy = TMath::Sin(frot[1]); cy = TMath::Cos(frot[1]);
426 sz = TMath::Sin(frot[2]); cz = TMath::Cos(frot[2]);
427 fm[0][0] = +cz*cy; // fr[0]
428 fm[0][1] = +cz*sy*sx - sz*cx; // fr[1]
429 fm[0][2] = +cz*sy*cx + sz*sx; // fr[2]
430 fm[1][0] = +sz*cy; // fr[3]
431 fm[1][1] = +sz*sy*sx + cz*cx; // fr[4]
432 fm[1][2] = +sz*sy*cx - cz*sx; // fr[5]
433 fm[2][0] = -sy; // fr[6]
434 fm[2][1] = +cy*sx; // fr[7]
435 fm[2][2] = +cy*cx; // fr[8]
437 //----------------------------------------------------------------------
438 void AliITSgeomMatrix::SetEulerAnglesChi(const Double_t ang[3]){
439 // Computes the Rotation matrix from the Euler angles [radians],
440 // Chi-convention, kept in this class. The matrix used in
441 // AliITSgeomMatrix::SetEulerAnglesChi and
442 // its inverse AliITSgeomMatrix::GetEulerAnglesChi() are defined in
443 // the following ways, R = Rb*Rc*Rd (M=R*L+T) where
444 // C2 +S2 0 1 0 0 C0 +S0 0
445 // Rb=-S2 C2 0 Rc= 0 C1 +S1 Rd=-S0 C0 0
446 // 0 0 1 0 -S1 C1 0 0 1
447 // This form is taken from Wolfram Research's Geometry>
448 // Transformations>Rotations web page (also should be
449 // found in their book).
451 // Double_t ang[3] The three Euler Angles Phi, Theta, Psi
456 Double_t s0,s1,s2,c0,c1,c2;
458 s0 = TMath::Sin(ang[0]); c0 = TMath::Cos(ang[0]);
459 s1 = TMath::Sin(ang[1]); c1 = TMath::Cos(ang[1]);
460 s2 = TMath::Sin(ang[2]); c2 = TMath::Cos(ang[2]);
461 fm[0][0] = +c2*c0-c1*s0*s2; // fr[0]
462 fm[0][1] = +c2*s0+c1*c0*s2; // fr[1]
463 fm[0][2] = +s2*s1; // fr[2]
464 fm[1][0] = -s2*c0-c1*s0*c2; // fr[3]
465 fm[1][1] = -s2*s0+c1*c0*c2; // fr[4]
466 fm[1][2] = +c2*s1; // fr[5]
467 fm[2][0] = s1*s0; // fr[6]
468 fm[2][1] = -s1*c0; // fr[7]
469 fm[2][2] = +c1; // fr[8]
473 //----------------------------------------------------------------------
474 void AliITSgeomMatrix::GtoLPosition(const Double_t g0[3],Double_t l[3]) const {
475 // Returns the local coordinates given the global coordinates [cm].
477 // Double_t g[3] The position represented in the ALICE
478 // global coordinate system
480 // Double_t l[3] The poistion represented in the local
481 // detector coordiante system
487 for(i=0;i<3;i++) g[i] = g0[i] - ftran[i];
490 for(j=0;j<3;j++) l[i] += fm[i][j]*g[j];
491 // g = R l + translation
495 //----------------------------------------------------------------------
496 void AliITSgeomMatrix::LtoGPosition(const Double_t l[3],Double_t g[3]) const {
497 // Returns the global coordinates given the local coordinates [cm].
499 // Double_t l[3] The poistion represented in the detector
500 // local coordinate system
502 // Double_t g[3] The poistion represented in the ALICE
503 // Global coordinate system
510 for(j=0;j<3;j++) g[i] += fm[j][i]*l[j];
512 // g = R^t l + translation
516 //----------------------------------------------------------------------
517 void AliITSgeomMatrix::GtoLMomentum(const Double_t g[3],Double_t l[3]) const{
518 // Returns the local coordinates of the momentum given the global
519 // coordinates of the momentum. It transforms just like GtoLPosition
520 // except that the translation vector is zero.
522 // Double_t g[3] The momentum represented in the ALICE global
525 // Double_t l[3] the momentum represented in the detector
526 // local coordinate system
533 for(j=0;j<3;j++) l[i] += fm[i][j]*g[j];
538 //----------------------------------------------------------------------
539 void AliITSgeomMatrix::LtoGMomentum(const Double_t l[3],Double_t g[3]) const {
540 // Returns the Global coordinates of the momentum given the local
541 // coordinates of the momentum. It transforms just like LtoGPosition
542 // except that the translation vector is zero.
544 // Double_t l[3] the momentum represented in the detector
545 // local coordinate system
547 // Double_t g[3] The momentum represented in the ALICE global
555 for(j=0;j<3;j++) g[i] += fm[j][i]*l[j];
560 //----------------------------------------------------------------------
561 void AliITSgeomMatrix::GtoLPositionError(const Double_t g[3][3],
562 Double_t l[3][3]) const {
563 // Given an Uncertainty matrix in Global coordinates it is
564 // rotated so that its representation in local coordinates can
565 // be returned. There is no effect due to the translation vector
566 // or its uncertainty.
568 // Double_t g[3][3] The error matrix represented in the ALICE global
571 // Double_t l[3][3] the error matrix represented in the detector
572 // local coordinate system
577 for(i=0;i<3;i++)for(m=0;m<3;m++){
579 for(j=0;j<3;j++)for(k=0;k<3;k++)
580 l[i][m] += fm[j][i]*g[j][k]*fm[k][m];
585 //----------------------------------------------------------------------
586 void AliITSgeomMatrix::LtoGPositionError(const Double_t l[3][3],
587 Double_t g[3][3]) const {
588 // Given an Uncertainty matrix in Local coordinates it is rotated so that
589 // its representation in global coordinates can be returned. There is no
590 // effect due to the translation vector or its uncertainty.
592 // Double_t l[3][3] the error matrix represented in the detector
593 // local coordinate system
595 // Double_t g[3][3] The error matrix represented in the ALICE global
601 for(i=0;i<3;i++)for(m=0;m<3;m++){
603 for(j=0;j<3;j++)for(k=0;k<3;k++)
604 g[i][m] += fm[i][j]*l[j][k]*fm[m][k];
609 //----------------------------------------------------------------------
610 void AliITSgeomMatrix::GtoLPositionTracking(const Double_t g[3],
611 Double_t l[3]) const {
612 // A slightly different coordinate system is used when tracking.
613 // This coordinate system is only relevant when the geometry represents
614 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
615 // alone but X -> -Y and Y -> X such that X always points out of the
616 // ITS Cylinder for every layer including layer 1 (where the detector
617 // are mounted upside down).
620 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
624 // Double_t g[3] The position represented in the ALICE
625 // global coordinate system
627 // Double_t l[3] The poistion represented in the local
628 // detector coordiante system
633 this->GtoLPosition(g,l0);
634 if(fid[0]==1){ // for layer 1 the detector are flipped upside down
635 // with respect to the others.
646 //----------------------------------------------------------------------
647 void AliITSgeomMatrix::LtoGPositionTracking(const Double_t l[3],
648 Double_t g[3]) const {
649 // A slightly different coordinate system is used when tracking.
650 // This coordinate system is only relevant when the geometry represents
651 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
652 // alone but X -> -Y and Y -> X such that X always points out of the
653 // ITS Cylinder for every layer including layer 1 (where the detector
654 // are mounted upside down).
657 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
661 // Double_t l[3] The poistion represented in the detector
662 // local coordinate system
664 // Double_t g[3] The poistion represented in the ALICE
665 // Global coordinate system
670 if(fid[0]==1){ // for layer 1 the detector are flipped upside down
671 // with respect to the others.
680 this->LtoGPosition(l0,g);
683 //----------------------------------------------------------------------
684 void AliITSgeomMatrix::GtoLMomentumTracking(const Double_t g[3],
685 Double_t l[3]) const {
686 // A slightly different coordinate system is used when tracking.
687 // This coordinate system is only relevant when the geometry represents
688 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
689 // alone but X -> -Y and Y -> X such that X always points out of the
690 // ITS Cylinder for every layer including layer 1 (where the detector
691 // are mounted upside down).
694 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
698 // Double_t g[3] The momentum represented in the ALICE global
701 // Double_t l[3] the momentum represented in the detector
702 // local coordinate system
707 this->GtoLMomentum(g,l0);
708 if(fid[0]==1){ // for layer 1 the detector are flipped upside down
709 // with respect to the others.
720 //----------------------------------------------------------------------
721 void AliITSgeomMatrix::LtoGMomentumTracking(const Double_t l[3],
722 Double_t g[3]) const {
723 // A slightly different coordinate system is used when tracking.
724 // This coordinate system is only relevant when the geometry represents
725 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
726 // alone but X -> -Y and Y -> X such that X always points out of the
727 // ITS Cylinder for every layer including layer 1 (where the detector
728 // are mounted upside down).
731 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
735 // Double_t l[3] the momentum represented in the detector
736 // local coordinate system
738 // Double_t g[3] The momentum represented in the ALICE global
744 if(fid[0]==1){ // for layer 1 the detector are flipped upside down
745 // with respect to the others.
754 this->LtoGMomentum(l0,g);
757 //----------------------------------------------------------------------
758 void AliITSgeomMatrix::GtoLPositionErrorTracking(const Double_t g[3][3],
759 Double_t l[3][3]) const {
760 // A slightly different coordinate system is used when tracking.
761 // This coordinate system is only relevant when the geometry represents
762 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
763 // alone but X -> -Y and Y -> X such that X always points out of the
764 // ITS Cylinder for every layer including layer 1 (where the detector
765 // are mounted upside down).
768 <img src="picts/ITS/AliITSgeomMatrix_TE1.gif">
772 // Double_t g[3][3] The error matrix represented in the ALICE global
775 // Double_t l[3][3] the error matrix represented in the detector
776 // local coordinate system
780 Double_t a0[3][3] = {{0.,+1.,0.},{-1.,0.,0.},{0.,0.,+1.}};
781 Double_t a1[3][3] = {{0.,-1.,0.},{+1.,0.,0.},{0.,0.,+1.}};
783 if(fid[0]==1) for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
784 rt[i][k] = a0[i][j]*fm[j][k];
785 else for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
786 rt[i][k] = a1[i][j]*fm[j][k];
787 for(i=0;i<3;i++)for(m=0;m<3;m++){
789 for(j=0;j<3;j++)for(k=0;k<3;k++)
790 l[i][m] += rt[j][i]*g[j][k]*rt[k][m];
795 //----------------------------------------------------------------------
796 void AliITSgeomMatrix::LtoGPositionErrorTracking(const Double_t l[3][3],
797 Double_t g[3][3]) const {
798 // A slightly different coordinate system is used when tracking.
799 // This coordinate system is only relevant when the geometry represents
800 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
801 // alone but X -> -Y and Y -> X such that X always points out of the
802 // ITS Cylinder for every layer including layer 1 (where the detector
803 // are mounted upside down).
806 <img src="picts/ITS/AliITSgeomMatrix_TE1.gif">
810 // Double_t l[3][3] the error matrix represented in the detector
811 // local coordinate system
813 // Double_t g[3][3] The error matrix represented in the ALICE global
819 Double_t a0[3][3] = {{0.,+1.,0.},{-1.,0.,0.},{0.,0.,+1.}};
820 Double_t a1[3][3] = {{0.,-1.,0.},{+1.,0.,0.},{0.,0.,+1.}};
822 if(fid[0]==1) for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
823 rt[i][k] = a0[i][j]*fm[j][k];
824 else for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
825 rt[i][k] = a1[i][j]*fm[j][k];
826 for(i=0;i<3;i++)for(m=0;m<3;m++){
828 for(j=0;j<3;j++)for(k=0;k<3;k++)
829 g[i][m] += rt[i][j]*l[j][k]*rt[m][k];
834 //----------------------------------------------------------------------
835 void AliITSgeomMatrix::PrintTitles(ostream *os) const {
836 // Standard output format for this class but it includes variable
837 // names and formatting that makes it easer to read.
839 // ostream *os The output stream to print the title on
846 *os << "fDetectorIndex=" << fDetectorIndex << " fid[3]={";
847 for(i=0;i<3;i++) *os << fid[i] << " ";
848 *os << "} frot[3]={";
849 for(i=0;i<3;i++) *os << frot[i] << " ";
850 *os << "} ftran[3]={";
851 for(i=0;i<3;i++) *os << ftran[i] << " ";
852 *os << "} fm[3][3]={";
853 for(i=0;i<3;i++){for(j=0;j<3;j++){ *os << fm[i][j] << " ";} *os <<"}{";}
857 //----------------------------------------------------------------------
858 void AliITSgeomMatrix::PrintComment(ostream *os) const {
859 // output format used by Print.
861 // ostream *os The output stream to print the comments on
866 *os << "fDetectorIndex fid[0] fid[1] fid[2] ftran[0] ftran[1] ftran[2] ";
867 *os << "fm[0][0] fm[0][1] fm[0][2] fm[1][0] fm[1][1] fm[1][2] ";
868 *os << "fm[2][0] fm[2][1] fm[2][2] ";
871 //----------------------------------------------------------------------
872 void AliITSgeomMatrix::Print(ostream *os)const{
873 // Standard output format for this class.
875 // ostream *os The output stream to print the class data on
888 #if defined __ICC || defined __ECC || defined __xlC__
895 fmt = os->setf(ios::scientific); // set scientific floating point output
896 *os << fDetectorIndex << " ";
897 for(i=0;i<3;i++) *os << fid[i] << " ";
898 // for(i=0;i<3;i++) *os << frot[i] << " "; // Redundant with fm[][].
899 for(i=0;i<3;i++) *os << setprecision(16) << ftran[i] << " ";
900 for(i=0;i<3;i++)for(j=0;j<3;j++) *os << setprecision(16) <<
902 *os << fPath.Length()<< " ";
903 for(i=0;i<fPath.Length();i++) *os << fPath[i];
905 os->flags(fmt); // reset back to old formating.
908 //----------------------------------------------------------------------
909 void AliITSgeomMatrix::Read(istream *is){
910 // Standard input format for this class.
912 // istream *is The input stream to read on
919 *is >> fDetectorIndex;
920 for(i=0;i<3;i++) *is >> fid[i];
921 // for(i=0;i<3;i++) *is >> frot[i]; // Redundant with fm[][].
922 for(i=0;i<3;i++) *is >> ftran[i];
923 for(i=0;i<3;i++)for(j=0;j<3;j++) *is >> fm[i][j];
924 while(is->peek()==' ')is->get(); // skip white spaces
925 if(isprint(is->peek())){ // old format did not have path.
926 *is >> j; // string length
928 for(i=0;i<j;i++) {*is >> fPath[i];}
930 AngleFromMatrix(); // compute angles frot[].
931 fCylR = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
932 fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
933 if(fCylPhi<0.0) fCylPhi += 2.*TMath::Pi();
936 //______________________________________________________________________
937 void AliITSgeomMatrix::Streamer(TBuffer &R__b){
938 // Stream an object of class AliITSgeomMatrix.
940 // TBuffer &R__b The output buffer to stream data on.
946 if (R__b.IsReading()) {
947 AliITSgeomMatrix::Class()->ReadBuffer(R__b, this);
948 fCylR = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
949 fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
950 this->AngleFromMatrix();
951 if(fCylPhi<0.0) fCylPhi += 2.*TMath::Pi();
953 AliITSgeomMatrix::Class()->WriteBuffer(R__b, this);
956 //______________________________________________________________________
957 void AliITSgeomMatrix::SetTranslation(const Double_t tran[3]){
958 // Sets the translation vector and computes fCylR and fCylPhi.
960 // Double_t trans[3] The translation vector to be used
965 for(Int_t i=0;i<3;i++) ftran[i] = tran[i];
966 fCylR = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
967 fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
968 if(fCylPhi<0.0) fCylPhi += 2.*TMath::Pi();
970 //----------------------------------------------------------------------
971 TPolyLine3D* AliITSgeomMatrix::CreateLocalAxis() const {
972 // This class is used as part of the documentation of this class
978 // A pointer to a new TPolyLine3D object showing the 3 line
979 // segments that make up the this local axis in the global
983 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},
988 LtoGPosition(l[i],g[i]);
989 gf[3*i]=(Float_t)g[i][0];
990 gf[3*i+1]=(Float_t)g[i][1];
991 gf[3*i+2]=(Float_t)g[i][2];
993 return new TPolyLine3D(5,gf);
995 //----------------------------------------------------------------------
996 TPolyLine3D* AliITSgeomMatrix::CreateLocalAxisTracking() const {
997 // This class is used as part of the documentation of this class
1003 // A pointer to a new TPolyLine3D object showing the 3 line
1004 // segments that make up the this local axis in the global
1005 // reference system.
1008 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},
1013 LtoGPositionTracking(l[i],g[i]);
1014 gf[3*i]=(Float_t)g[i][0];
1015 gf[3*i+1]=(Float_t)g[i][1];
1016 gf[3*i+2]=(Float_t)g[i][2];
1018 return new TPolyLine3D(5,gf);
1020 //----------------------------------------------------------------------
1021 TNode* AliITSgeomMatrix::CreateNode(const Char_t *nodeName,
1022 const Char_t *nodeTitle,TNode *mother,
1023 TShape *shape,Bool_t axis) const {
1024 // Creates a node inside of the node mother out of the shape shape
1025 // in the position, with respect to mother, indecated by "this". If axis
1026 // is ture, it will insert an axis within this node/shape.
1028 // Char_t *nodeName This name of this node
1029 // Char_t *nodeTitle This node title
1030 // TNode *mother The node this node will be inside of/with respect to
1031 // TShape *shape The shape of this node
1032 // Bool_t axis If ture, a set of x,y,z axis will be included
1036 // A pointer to "this" node.
1037 Double_t trans[3],matrix[3][3],*matr;
1038 TRotMatrix *rot = new TRotMatrix();
1041 matr = &(matrix[0][0]);
1042 this->GetTranslation(trans);
1043 this->GetMatrix(matrix);
1044 rot->SetMatrix(matr);
1050 TNode *node1 = new TNode(name.Data(),title.Data(),shape,
1051 trans[0],trans[1],trans[2],rot);
1054 const Float_t kScale=0.5,kLw=0.2;
1055 Float_t xchar[13][2]={
1056 {0.5*kLw,1.},{0.,0.5*kLw},{0.5-0.5*kLw,0.5},
1057 {0.,0.5*kLw},{0.5*kLw,0.},{0.5,0.5-0.5*kLw},
1058 {1-0.5*kLw,0.},{1.,0.5*kLw},{0.5+0.5*kLw,0.5},
1059 {1.,1.-0.5*kLw},{1.-0.5*kLw,1.},{0.5,0.5+0.5*kLw},
1061 Float_t ychar[10][2]={
1062 {.5-0.5*kLw,0.},{.5+0.5*kLw,0.},{.5+0.5*kLw,0.5-0.5*kLw},
1063 {1.,1.-0.5*kLw},{1.-0.5*kLw,1.},{0.5+0.5*kLw,0.5},
1064 {0.5*kLw,1.} ,{0.,1-0.5*kLw} ,{0.5-0.5*kLw,0.5},
1066 Float_t zchar[11][2]={
1067 {0.,1.},{0,1.-kLw},{1.-kLw,1.-kLw},{0.,kLw} ,{0.,0.},
1068 {1.,0.},{1.,kLw} ,{kLw,kLw} ,{1.,1.-kLw},{1.,1.},
1070 for(i=0;i<13;i++)for(j=0;j<2;j++){
1071 if(i<13) xchar[i][j] = kScale*xchar[i][j];
1072 if(i<10) ychar[i][j] = kScale*ychar[i][j];
1073 if(i<11) zchar[i][j] = kScale*zchar[i][j];
1075 TXTRU *axisxl = new TXTRU("x","x","text",12,2);
1076 for(i=0;i<12;i++) axisxl->DefineVertex(i,xchar[i][0],xchar[i][1]);
1077 axisxl->DefineSection(0,-0.5*kLw);axisxl->DefineSection(1,0.5*kLw);
1078 TXTRU *axisyl = new TXTRU("y","y","text",9,2);
1079 for(i=0;i<9;i++) axisyl->DefineVertex(i,ychar[i][0],ychar[i][1]);
1080 axisyl->DefineSection(0,-0.5*kLw);axisyl->DefineSection(1,0.5*kLw);
1081 TXTRU *axiszl = new TXTRU("z","z","text",10,2);
1082 for(i=0;i<10;i++) axiszl->DefineVertex(i,zchar[i][0],zchar[i][1]);
1083 axiszl->DefineSection(0,-0.5*kLw);axiszl->DefineSection(1,0.5*kLw);
1084 Float_t lxy[13][2]={
1085 {-0.5*kLw,-0.5*kLw},{0.8,-0.5*kLw},{0.8,-0.1},{1.0,0.0},
1086 {0.8,0.1},{0.8,0.5*kLw},{0.5*kLw,0.5*kLw},{0.5*kLw,0.8},
1087 {0.1,0.8},{0.0,1.0},{-0.1,0.8},{-0.5*kLw,0.8},
1088 {-0.5*kLw,-0.5*kLw}};
1089 TXTRU *axisxy = new TXTRU("axisxy","axisxy","text",13,2);
1090 for(i=0;i<13;i++) axisxy->DefineVertex(i,lxy[i][0],lxy[i][1]);
1091 axisxy->DefineSection(0,-0.5*kLw);axisxy->DefineSection(1,0.5*kLw);
1093 {0.5*kLw,-0.5*kLw},{0.8,-0.5*kLw},{0.8,-0.1},{1.0,0.0},
1094 {0.8,0.1},{0.8,0.5*kLw},{0.5*kLw,0.5*kLw},
1095 {0.5*kLw,-0.5*kLw}};
1096 TXTRU *axisz = new TXTRU("axisz","axisz","text",8,2);
1097 for(i=0;i<8;i++) axisz->DefineVertex(i,lz[i][0],lz[i][1]);
1098 axisz->DefineSection(0,-0.5*kLw);axisz->DefineSection(1,0.5*kLw);
1099 //TRotMatrix *xaxis90= new TRotMatrix("xaixis90","",90.0, 0.0, 0.0);
1100 TRotMatrix *yaxis90= new TRotMatrix("yaixis90","", 0.0,90.0, 0.0);
1101 TRotMatrix *zaxis90= new TRotMatrix("zaixis90","", 0.0, 0.0,90.0);
1104 title = name.Append("axisxy");
1105 TNode *nodeaxy = new TNode(title.Data(),title.Data(),axisxy);
1106 title = name.Append("axisz");
1107 TNode *nodeaz = new TNode(title.Data(),title.Data(),axisz,
1109 TNode *textboxX0 = new TNode("textboxX0","textboxX0",axisxl,
1110 lxy[3][0],lxy[3][1],0.0);
1111 TNode *textboxX1 = new TNode("textboxX1","textboxX1",axisxl,
1112 lxy[3][0],lxy[3][1],0.0,yaxis90);
1113 TNode *textboxX2 = new TNode("textboxX2","textboxX2",axisxl,
1114 lxy[3][0],lxy[3][1],0.0,zaxis90);
1115 TNode *textboxY0 = new TNode("textboxY0","textboxY0",axisyl,
1116 lxy[9][0],lxy[9][1],0.0);
1117 TNode *textboxY1 = new TNode("textboxY1","textboxY1",axisyl,
1118 lxy[9][0],lxy[9][1],0.0,yaxis90);
1119 TNode *textboxY2 = new TNode("textboxY2","textboxY2",axisyl,
1120 lxy[9][0],lxy[9][1],0.0,zaxis90);
1121 TNode *textboxZ0 = new TNode("textboxZ0","textboxZ0",axiszl,
1123 TNode *textboxZ1 = new TNode("textboxZ1","textboxZ1",axiszl,
1124 0.0,0.0,lz[3][0],yaxis90);
1125 TNode *textboxZ2 = new TNode("textboxZ2","textboxZ2",axiszl,
1126 0.0,0.0,lz[3][0],zaxis90);
1142 //----------------------------------------------------------------------
1143 void AliITSgeomMatrix::MakeFigures() const {
1144 // make figures to help document this class
1151 const Double_t kDx0=550.,kDy0=550.,kDz0=550.; // cm
1152 const Double_t kDx=1.0,kDy=0.300,kDz=3.0,kRmax=0.1; // cm
1153 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},
1155 TCanvas *c = new TCanvas(kFALSE);// create a batch mode canvas.
1156 #if ROOT_VERSION_CODE>= 331523
1157 Double_t rmin[]={-1,-1,-1};
1158 Double_t rmax[]={ 1, 1, 1};
1159 TView *view = new TView3D(1,rmin,rmax);
1161 TView *view = new TView(1); // Create Cartesian coordiante view
1163 TBRIK *mother = new TBRIK("Mother","Mother","void",kDx0,kDy0,kDz0);
1164 TBRIK *det = new TBRIK("Detector","","Si",kDx,kDy,kDz);
1165 TPolyLine3D *axis = new TPolyLine3D(5,&(l[0][0]));
1166 TPCON *arrow = new TPCON("arrow","","air",0.0,360.,2);
1167 TRotMatrix *xarrow= new TRotMatrix("xarrow","",90.,0.0,0.0);
1168 TRotMatrix *yarrow= new TRotMatrix("yarrow","",0.0,90.,0.0);
1170 det->SetLineColor(0); // black
1171 det->SetLineStyle(1); // solid line
1172 det->SetLineWidth(2); // pixel units
1173 det->SetFillColor(1); // black
1174 det->SetFillStyle(4010); // window is 90% transparent
1175 arrow->SetLineColor(det->GetLineColor());
1176 arrow->SetLineWidth(det->GetLineWidth());
1177 arrow->SetLineStyle(det->GetLineStyle());
1178 arrow->SetFillColor(1); // black
1179 arrow->SetFillStyle(4100); // window is 100% opaque
1180 arrow->DefineSection(0,0.0,0.0,kRmax);
1181 arrow->DefineSection(1,2.*kRmax,0.0,0.0);
1182 view->SetRange(-kDx0,-kDy0,-kDz0,kDx0,kDy0,kDz0);
1184 TNode *node0 = new TNode("NODE0","NODE0",mother);
1186 TNode *node1 = new TNode("NODE1","NODE1",det);
1188 TNode *nodex = new TNode("NODEx","NODEx",arrow,
1189 l[0][0],l[0][1],l[0][2],xarrow);
1190 TNode *nodey = new TNode("NODEy","NODEy",arrow,
1191 l[2][0],l[2][1],l[2][2],yarrow);
1192 TNode *nodez = new TNode("NODEz","NODEz",arrow,l[4][0],l[4][1],l[4][2]);
1203 c->SaveAs("AliITSgeomMatrix_L1.gif");
1205 //----------------------------------------------------------------------
1206 ostream &operator<<(ostream &os,AliITSgeomMatrix &p){
1207 // Standard output streaming function.
1209 // ostream &os The output stream to print the class data on
1210 // AliITSgeomMatrix &p This class
1219 //----------------------------------------------------------------------
1220 istream &operator>>(istream &is,AliITSgeomMatrix &r){
1221 // Standard input streaming function.
1223 // ostream &os The input stream to print the class data on
1224 // AliITSgeomMatrix &p This class
1233 //----------------------------------------------------------------------