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();
256 ang[1] = TMath::ATan2(fm[0][1],fm[0][0]);
257 if(TMath::Cos(ang[1])!=0.0) si = fm[0][0]/TMath::Cos(ang[1]);
258 else si = fm[0][1]/TMath::Sin(ang[1]);
259 ang[0] = TMath::ATan2(si,fm[0][2]);
261 ang[3] = TMath::ATan2(fm[1][1],fm[1][0]);
262 if(TMath::Cos(ang[3])!=0.0) si = fm[1][0]/TMath::Cos(ang[3]);
263 else si = fm[1][1]/TMath::Sin(ang[3]);
264 ang[2] = TMath::ATan2(si,fm[1][2]);
266 ang[5] = TMath::ATan2(fm[2][1],fm[2][0]);
267 if(TMath::Cos(ang[5])!=0.0) si = fm[2][0]/TMath::Cos(ang[5]);
268 else si = fm[2][1]/TMath::Sin(ang[5]);
269 ang[4] = TMath::ATan2(si,fm[2][2]);
271 for(Int_t i=0;i<6;i++) {ang[i] *= c; if(ang[i]<0.0) ang[i] += 360.;}
273 //----------------------------------------------------------------------
274 void AliITSgeomMatrix::MatrixFromSixAngles(const Double_t *ang){
275 // Given the 6 GEANT 3.21 rotation angles [degree], this will compute and
276 // set the rotations matrix and 3 standard rotation angles [radians].
277 // These angles and rotation matrix are overwrite the existing values in
280 // Double_t ang[6] The 6 Geant3.21 rotation angles. [degrees]
286 Double_t si,lr[9],c=TMath::Pi()/180.;
288 si = TMath::Sin(c*ang[0]);
289 if(ang[0]== 90.0) si = +1.0;
290 if(ang[0]==270.0) si = -1.0;
291 if(ang[0]== 0.0||ang[0]==180.) si = 0.0;
292 lr[0] = si * TMath::Cos(c*ang[1]);
293 lr[1] = si * TMath::Sin(c*ang[1]);
294 lr[2] = TMath::Cos(c*ang[0]);
295 if(ang[0]== 90.0||ang[0]==270.) lr[2] = 0.0;
296 if(ang[0]== 0.0) lr[2] = +1.0;
297 if(ang[0]==180.0) lr[2] = -1.0;
299 si = TMath::Sin(c*ang[2]);
300 if(ang[2]== 90.0) si = +1.0;
301 if(ang[2]==270.0) si = -1.0;
302 if(ang[2]== 0.0||ang[2]==180.) si = 0.0;
303 lr[3] = si * TMath::Cos(c*ang[3]);
304 lr[4] = si * TMath::Sin(c*ang[3]);
305 lr[5] = TMath::Cos(c*ang[2]);
306 if(ang[2]== 90.0||ang[2]==270.) lr[5] = 0.0;
307 if(ang[2]== 0.0) lr[5] = +1.0;
308 if(ang[2]==180.0) lr[5] = -1.0;
310 si = TMath::Sin(c*ang[4]);
311 if(ang[4]== 90.0) si = +1.0;
312 if(ang[4]==270.0) si = -1.0;
313 if(ang[4]== 0.0||ang[4]==180.) si = 0.0;
314 lr[6] = si * TMath::Cos(c*ang[5]);
315 lr[7] = si * TMath::Sin(c*ang[5]);
316 lr[8] = TMath::Cos(c*ang[4]);
317 if(ang[4]== 90.0||ang[4]==270.0) lr[8] = 0.0;
318 if(ang[4]== 0.0) lr[8] = +1.0;
319 if(ang[4]==180.0) lr[8] = -1.0;
320 // Normalize these elements and fill matrix fm.
321 for(i=0;i<3;i++){// reuse si.
323 for(j=0;j<3;j++) si += lr[3*i+j]*lr[3*i+j];
324 si = TMath::Sqrt(1./si);
325 for(j=0;j<3;j++) fm[i][j] = si*lr[3*i+j];
327 this->AngleFromMatrix();
329 //----------------------------------------------------------------------
330 AliITSgeomMatrix::AliITSgeomMatrix(const Double_t rotd[6]/*degrees*/,
331 Int_t idt,const Int_t id[3],
332 const Double_t tran[3]):
333 TObject(), // Base class
334 fDetectorIndex(idt), // Detector type index (like fShapeIndex was)
335 fid(), // layer, ladder, detector numbers.
336 frot(), //! vector of rotations about x,y,z [radians].
337 ftran(), // Translation vector of module x,y,z.
338 fCylR(0.0), //! R Translation in Cylinderical coordinates
339 fCylPhi(0.0),//! Phi Translation vector in Cylindrical coord.
340 fm(), // Rotation matrix based on frot.
341 fPath(){ // Path in geometry to this module
342 // This is a constructor for the AliITSgeomMatrix class. The matrix
343 // is defined by the 6 GEANT 3.21 rotation angles [degrees], and
344 // the translation vector tran [cm]. In addition the layer, ladder,
345 // and detector number for this particular module and the type of
346 // module must be given. The full rotation matrix is kept so that
347 // the evaluation of a coordinate transformation can be done
348 // quickly and with a minimum of CPU overhead. The basic coordinate
349 // systems are the ALICE global coordinate system and the detector
350 // local coordinate system. In general this structure is not limited
351 // to just those two coordinate systems.
354 <img src="picts/ITS/AliITSgeomMatrix_L1.gif">
358 // Double_t rotd[6] The 6 Geant 3.21 rotation angles [degrees]
359 // Int_t idt The module Id number
360 // Int_t id[3] The layer, ladder and detector number
361 // Double_t tran[3] The translation vector
368 fCylR = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
369 fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
370 if(fCylPhi<0.0) fCylPhi += 2.*TMath::Pi();
371 this->MatrixFromSixAngles(rotd);
373 //----------------------------------------------------------------------
374 void AliITSgeomMatrix::AngleFromMatrix(){
375 // Computes the angles from the rotation matrix up to a phase of
376 // 180 degrees. The matrix used in AliITSgeomMatrix::MatrixFromAngle()
377 // and its inverse AliITSgeomMatrix::AngleFromMatrix() are defined in
378 // the following ways, R = Rz*Ry*Rx (M=R*L+T) where
379 // 1 0 0 Cy 0 +Sy Cz -Sz 0
380 // Rx= 0 Cx -Sx Ry= 0 1 0 Rz=+Sz Cz 0
381 // 0 +Sx Cx -Sy 0 Cy 0 0 1
382 // The choice of the since of S, comes from the choice between
383 // the rotation of the object or the coordinate system (view). I think
384 // that this choice is the first, the rotation of the object.
392 // get angles from matrix up to a phase of 180 degrees.
394 rx = TMath::ATan2(fm[2][1],fm[2][2]);if(rx<0.0) rx += 2.0*TMath::Pi();
395 ry = TMath::ASin(-fm[0][2]); if(ry<0.0) ry += 2.0*TMath::Pi();
396 rz = TMath::ATan2(fm[1][0],fm[0][0]);if(rz<0.0) rz += 2.0*TMath::Pi();
402 //----------------------------------------------------------------------
403 void AliITSgeomMatrix::MatrixFromAngle(){
404 // Computes the Rotation matrix from the angles [radians] kept in this
405 // class. The matrix used in AliITSgeomMatrix::MatrixFromAngle() and
406 // its inverse AliITSgeomMatrix::AngleFromMatrix() are defined in
407 // the following ways, R = Rz*Ry*Rx (M=R*L+T) where
408 // 1 0 0 Cy 0 +Sy Cz -Sz 0
409 // Rx= 0 Cx -Sx Ry= 0 1 0 Rz=+Sz Cz 0
410 // 0 +Sx Cx -Sy 0 Cy 0 0 1
411 // The choice of the since of S, comes from the choice between
412 // the rotation of the object or the coordinate system (view). I think
413 // that this choice is the first, the rotation of the object.
420 Double_t sx,sy,sz,cx,cy,cz;
422 sx = TMath::Sin(frot[0]); cx = TMath::Cos(frot[0]);
423 sy = TMath::Sin(frot[1]); cy = TMath::Cos(frot[1]);
424 sz = TMath::Sin(frot[2]); cz = TMath::Cos(frot[2]);
425 fm[0][0] = +cz*cy; // fr[0]
426 fm[0][1] = +cz*sy*sx - sz*cx; // fr[1]
427 fm[0][2] = +cz*sy*cx + sz*sx; // fr[2]
428 fm[1][0] = +sz*cy; // fr[3]
429 fm[1][1] = +sz*sy*sx + cz*cx; // fr[4]
430 fm[1][2] = +sz*sy*cx - cz*sx; // fr[5]
431 fm[2][0] = -sy; // fr[6]
432 fm[2][1] = +cy*sx; // fr[7]
433 fm[2][2] = +cy*cx; // fr[8]
435 //----------------------------------------------------------------------
436 void AliITSgeomMatrix::SetEulerAnglesChi(const Double_t ang[3]){
437 // Computes the Rotation matrix from the Euler angles [radians],
438 // Chi-convention, kept in this class. The matrix used in
439 // AliITSgeomMatrix::SetEulerAnglesChi and
440 // its inverse AliITSgeomMatrix::GetEulerAnglesChi() are defined in
441 // the following ways, R = Rb*Rc*Rd (M=R*L+T) where
442 // C2 +S2 0 1 0 0 C0 +S0 0
443 // Rb=-S2 C2 0 Rc= 0 C1 +S1 Rd=-S0 C0 0
444 // 0 0 1 0 -S1 C1 0 0 1
445 // This form is taken from Wolfram Research's Geometry>
446 // Transformations>Rotations web page (also should be
447 // found in their book).
449 // Double_t ang[3] The three Euler Angles Phi, Theta, Psi
454 Double_t s0,s1,s2,c0,c1,c2;
456 s0 = TMath::Sin(ang[0]); c0 = TMath::Cos(ang[0]);
457 s1 = TMath::Sin(ang[1]); c1 = TMath::Cos(ang[1]);
458 s2 = TMath::Sin(ang[2]); c2 = TMath::Cos(ang[2]);
459 fm[0][0] = +c2*c0-c1*s0*s2; // fr[0]
460 fm[0][1] = +c2*s0+c1*c0*s2; // fr[1]
461 fm[0][2] = +s2*s1; // fr[2]
462 fm[1][0] = -s2*c0-c1*s0*c2; // fr[3]
463 fm[1][1] = -s2*s0+c1*c0*c2; // fr[4]
464 fm[1][2] = +c2*s1; // fr[5]
465 fm[2][0] = s1*s0; // fr[6]
466 fm[2][1] = -s1*c0; // fr[7]
467 fm[2][2] = +c1; // fr[8]
471 //----------------------------------------------------------------------
472 void AliITSgeomMatrix::GtoLPosition(const Double_t g0[3],Double_t l[3]) const {
473 // Returns the local coordinates given the global coordinates [cm].
475 // Double_t g[3] The position represented in the ALICE
476 // global coordinate system
478 // Double_t l[3] The poistion represented in the local
479 // detector coordiante system
485 for(i=0;i<3;i++) g[i] = g0[i] - ftran[i];
488 for(j=0;j<3;j++) l[i] += fm[i][j]*g[j];
489 // g = R l + translation
493 //----------------------------------------------------------------------
494 void AliITSgeomMatrix::LtoGPosition(const Double_t l[3],Double_t g[3]) const {
495 // Returns the global coordinates given the local coordinates [cm].
497 // Double_t l[3] The poistion represented in the detector
498 // local coordinate system
500 // Double_t g[3] The poistion represented in the ALICE
501 // Global coordinate system
508 for(j=0;j<3;j++) g[i] += fm[j][i]*l[j];
510 // g = R^t l + translation
514 //----------------------------------------------------------------------
515 void AliITSgeomMatrix::GtoLMomentum(const Double_t g[3],Double_t l[3]) const{
516 // Returns the local coordinates of the momentum given the global
517 // coordinates of the momentum. It transforms just like GtoLPosition
518 // except that the translation vector is zero.
520 // Double_t g[3] The momentum represented in the ALICE global
523 // Double_t l[3] the momentum represented in the detector
524 // local coordinate system
531 for(j=0;j<3;j++) l[i] += fm[i][j]*g[j];
536 //----------------------------------------------------------------------
537 void AliITSgeomMatrix::LtoGMomentum(const Double_t l[3],Double_t g[3]) const {
538 // Returns the Global coordinates of the momentum given the local
539 // coordinates of the momentum. It transforms just like LtoGPosition
540 // except that the translation vector is zero.
542 // Double_t l[3] the momentum represented in the detector
543 // local coordinate system
545 // Double_t g[3] The momentum represented in the ALICE global
553 for(j=0;j<3;j++) g[i] += fm[j][i]*l[j];
558 //----------------------------------------------------------------------
559 void AliITSgeomMatrix::GtoLPositionError(const Double_t g[3][3],
560 Double_t l[3][3]) const {
561 // Given an Uncertainty matrix in Global coordinates it is
562 // rotated so that its representation in local coordinates can
563 // be returned. There is no effect due to the translation vector
564 // or its uncertainty.
566 // Double_t g[3][3] The error matrix represented in the ALICE global
569 // Double_t l[3][3] the error matrix represented in the detector
570 // local coordinate system
575 for(i=0;i<3;i++)for(m=0;m<3;m++){
577 for(j=0;j<3;j++)for(k=0;k<3;k++)
578 l[i][m] += fm[j][i]*g[j][k]*fm[k][m];
583 //----------------------------------------------------------------------
584 void AliITSgeomMatrix::LtoGPositionError(const Double_t l[3][3],
585 Double_t g[3][3]) const {
586 // Given an Uncertainty matrix in Local coordinates it is rotated so that
587 // its representation in global coordinates can be returned. There is no
588 // effect due to the translation vector or its uncertainty.
590 // Double_t l[3][3] the error matrix represented in the detector
591 // local coordinate system
593 // Double_t g[3][3] The error matrix represented in the ALICE global
599 for(i=0;i<3;i++)for(m=0;m<3;m++){
601 for(j=0;j<3;j++)for(k=0;k<3;k++)
602 g[i][m] += fm[i][j]*l[j][k]*fm[m][k];
607 //----------------------------------------------------------------------
608 void AliITSgeomMatrix::GtoLPositionTracking(const Double_t g[3],
609 Double_t l[3]) const {
610 // A slightly different coordinate system is used when tracking.
611 // This coordinate system is only relevant when the geometry represents
612 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
613 // alone but X -> -Y and Y -> X such that X always points out of the
614 // ITS Cylinder for every layer including layer 1 (where the detector
615 // are mounted upside down).
618 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
622 // Double_t g[3] The position represented in the ALICE
623 // global coordinate system
625 // Double_t l[3] The poistion represented in the local
626 // detector coordiante system
631 this->GtoLPosition(g,l0);
632 if(fid[0]==1){ // for layer 1 the detector are flipped upside down
633 // with respect to the others.
644 //----------------------------------------------------------------------
645 void AliITSgeomMatrix::LtoGPositionTracking(const Double_t l[3],
646 Double_t g[3]) const {
647 // A slightly different coordinate system is used when tracking.
648 // This coordinate system is only relevant when the geometry represents
649 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
650 // alone but X -> -Y and Y -> X such that X always points out of the
651 // ITS Cylinder for every layer including layer 1 (where the detector
652 // are mounted upside down).
655 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
659 // Double_t l[3] The poistion represented in the detector
660 // local coordinate system
662 // Double_t g[3] The poistion represented in the ALICE
663 // Global coordinate system
668 if(fid[0]==1){ // for layer 1 the detector are flipped upside down
669 // with respect to the others.
678 this->LtoGPosition(l0,g);
681 //----------------------------------------------------------------------
682 void AliITSgeomMatrix::GtoLMomentumTracking(const Double_t g[3],
683 Double_t l[3]) const {
684 // A slightly different coordinate system is used when tracking.
685 // This coordinate system is only relevant when the geometry represents
686 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
687 // alone but X -> -Y and Y -> X such that X always points out of the
688 // ITS Cylinder for every layer including layer 1 (where the detector
689 // are mounted upside down).
692 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
696 // Double_t g[3] The momentum represented in the ALICE global
699 // Double_t l[3] the momentum represented in the detector
700 // local coordinate system
705 this->GtoLMomentum(g,l0);
706 if(fid[0]==1){ // for layer 1 the detector are flipped upside down
707 // with respect to the others.
718 //----------------------------------------------------------------------
719 void AliITSgeomMatrix::LtoGMomentumTracking(const Double_t l[3],
720 Double_t g[3]) const {
721 // A slightly different coordinate system is used when tracking.
722 // This coordinate system is only relevant when the geometry represents
723 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
724 // alone but X -> -Y and Y -> X such that X always points out of the
725 // ITS Cylinder for every layer including layer 1 (where the detector
726 // are mounted upside down).
729 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
733 // Double_t l[3] the momentum represented in the detector
734 // local coordinate system
736 // Double_t g[3] The momentum represented in the ALICE global
742 if(fid[0]==1){ // for layer 1 the detector are flipped upside down
743 // with respect to the others.
752 this->LtoGMomentum(l0,g);
755 //----------------------------------------------------------------------
756 void AliITSgeomMatrix::GtoLPositionErrorTracking(const Double_t g[3][3],
757 Double_t l[3][3]) const {
758 // A slightly different coordinate system is used when tracking.
759 // This coordinate system is only relevant when the geometry represents
760 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
761 // alone but X -> -Y and Y -> X such that X always points out of the
762 // ITS Cylinder for every layer including layer 1 (where the detector
763 // are mounted upside down).
766 <img src="picts/ITS/AliITSgeomMatrix_TE1.gif">
770 // Double_t g[3][3] The error matrix represented in the ALICE global
773 // Double_t l[3][3] the error matrix represented in the detector
774 // local coordinate system
778 Double_t a0[3][3] = {{0.,+1.,0.},{-1.,0.,0.},{0.,0.,+1.}};
779 Double_t a1[3][3] = {{0.,-1.,0.},{+1.,0.,0.},{0.,0.,+1.}};
781 if(fid[0]==1) for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
782 rt[i][k] = a0[i][j]*fm[j][k];
783 else for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
784 rt[i][k] = a1[i][j]*fm[j][k];
785 for(i=0;i<3;i++)for(m=0;m<3;m++){
787 for(j=0;j<3;j++)for(k=0;k<3;k++)
788 l[i][m] += rt[j][i]*g[j][k]*rt[k][m];
793 //----------------------------------------------------------------------
794 void AliITSgeomMatrix::LtoGPositionErrorTracking(const Double_t l[3][3],
795 Double_t g[3][3]) const {
796 // A slightly different coordinate system is used when tracking.
797 // This coordinate system is only relevant when the geometry represents
798 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
799 // alone but X -> -Y and Y -> X such that X always points out of the
800 // ITS Cylinder for every layer including layer 1 (where the detector
801 // are mounted upside down).
804 <img src="picts/ITS/AliITSgeomMatrix_TE1.gif">
808 // Double_t l[3][3] the error matrix represented in the detector
809 // local coordinate system
811 // Double_t g[3][3] The error matrix represented in the ALICE global
817 Double_t a0[3][3] = {{0.,+1.,0.},{-1.,0.,0.},{0.,0.,+1.}};
818 Double_t a1[3][3] = {{0.,-1.,0.},{+1.,0.,0.},{0.,0.,+1.}};
820 if(fid[0]==1) for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
821 rt[i][k] = a0[i][j]*fm[j][k];
822 else for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
823 rt[i][k] = a1[i][j]*fm[j][k];
824 for(i=0;i<3;i++)for(m=0;m<3;m++){
826 for(j=0;j<3;j++)for(k=0;k<3;k++)
827 g[i][m] += rt[i][j]*l[j][k]*rt[m][k];
832 //----------------------------------------------------------------------
833 void AliITSgeomMatrix::PrintTitles(ostream *os) const {
834 // Standard output format for this class but it includes variable
835 // names and formatting that makes it easer to read.
837 // ostream *os The output stream to print the title on
844 *os << "fDetectorIndex=" << fDetectorIndex << " fid[3]={";
845 for(i=0;i<3;i++) *os << fid[i] << " ";
846 *os << "} frot[3]={";
847 for(i=0;i<3;i++) *os << frot[i] << " ";
848 *os << "} ftran[3]={";
849 for(i=0;i<3;i++) *os << ftran[i] << " ";
850 *os << "} fm[3][3]={";
851 for(i=0;i<3;i++){for(j=0;j<3;j++){ *os << fm[i][j] << " ";} *os <<"}{";}
855 //----------------------------------------------------------------------
856 void AliITSgeomMatrix::PrintComment(ostream *os) const {
857 // output format used by Print.
859 // ostream *os The output stream to print the comments on
864 *os << "fDetectorIndex fid[0] fid[1] fid[2] ftran[0] ftran[1] ftran[2] ";
865 *os << "fm[0][0] fm[0][1] fm[0][2] fm[1][0] fm[1][1] fm[1][2] ";
866 *os << "fm[2][0] fm[2][1] fm[2][2] ";
869 //----------------------------------------------------------------------
870 void AliITSgeomMatrix::Print(ostream *os)const{
871 // Standard output format for this class.
873 // ostream *os The output stream to print the class data on
886 #if defined __ICC || defined __ECC || defined __xlC__
893 fmt = os->setf(ios::scientific); // set scientific floating point output
894 *os << fDetectorIndex << " ";
895 for(i=0;i<3;i++) *os << fid[i] << " ";
896 // for(i=0;i<3;i++) *os << frot[i] << " "; // Redundant with fm[][].
897 for(i=0;i<3;i++) *os << setprecision(16) << ftran[i] << " ";
898 for(i=0;i<3;i++)for(j=0;j<3;j++) *os << setprecision(16) <<
900 *os << fPath.Length()<< " ";
901 for(i=0;i<fPath.Length();i++) *os << fPath[i];
903 os->flags(fmt); // reset back to old formating.
906 //----------------------------------------------------------------------
907 void AliITSgeomMatrix::Read(istream *is){
908 // Standard input format for this class.
910 // istream *is The input stream to read on
917 *is >> fDetectorIndex;
918 for(i=0;i<3;i++) *is >> fid[i];
919 // for(i=0;i<3;i++) *is >> frot[i]; // Redundant with fm[][].
920 for(i=0;i<3;i++) *is >> ftran[i];
921 for(i=0;i<3;i++)for(j=0;j<3;j++) *is >> fm[i][j];
922 while(is->peek()==' ')is->get(); // skip white spaces
923 if(isprint(is->peek())){ // old format did not have path.
924 *is >> j; // string length
926 for(i=0;i<j;i++) {*is >> fPath[i];}
928 AngleFromMatrix(); // compute angles frot[].
929 fCylR = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
930 fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
931 if(fCylPhi<0.0) fCylPhi += 2.*TMath::Pi();
934 //______________________________________________________________________
935 void AliITSgeomMatrix::Streamer(TBuffer &R__b){
936 // Stream an object of class AliITSgeomMatrix.
938 // TBuffer &R__b The output buffer to stream data on.
944 if (R__b.IsReading()) {
945 AliITSgeomMatrix::Class()->ReadBuffer(R__b, this);
946 fCylR = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
947 fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
948 this->AngleFromMatrix();
949 if(fCylPhi<0.0) fCylPhi += 2.*TMath::Pi();
951 AliITSgeomMatrix::Class()->WriteBuffer(R__b, this);
954 //______________________________________________________________________
955 void AliITSgeomMatrix::SetTranslation(const Double_t tran[3]){
956 // Sets the translation vector and computes fCylR and fCylPhi.
958 // Double_t trans[3] The translation vector to be used
963 for(Int_t i=0;i<3;i++) ftran[i] = tran[i];
964 fCylR = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
965 fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
966 if(fCylPhi<0.0) fCylPhi += 2.*TMath::Pi();
968 //----------------------------------------------------------------------
969 TPolyLine3D* AliITSgeomMatrix::CreateLocalAxis() const {
970 // This class is used as part of the documentation of this class
976 // A pointer to a new TPolyLine3D object showing the 3 line
977 // segments that make up the this local axis in the global
981 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},
986 LtoGPosition(l[i],g[i]);
987 gf[3*i]=(Float_t)g[i][0];
988 gf[3*i+1]=(Float_t)g[i][1];
989 gf[3*i+2]=(Float_t)g[i][2];
991 return new TPolyLine3D(5,gf);
993 //----------------------------------------------------------------------
994 TPolyLine3D* AliITSgeomMatrix::CreateLocalAxisTracking() const {
995 // This class is used as part of the documentation of this class
1001 // A pointer to a new TPolyLine3D object showing the 3 line
1002 // segments that make up the this local axis in the global
1003 // reference system.
1006 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},
1011 LtoGPositionTracking(l[i],g[i]);
1012 gf[3*i]=(Float_t)g[i][0];
1013 gf[3*i+1]=(Float_t)g[i][1];
1014 gf[3*i+2]=(Float_t)g[i][2];
1016 return new TPolyLine3D(5,gf);
1018 //----------------------------------------------------------------------
1019 TNode* AliITSgeomMatrix::CreateNode(const Char_t *nodeName,
1020 const Char_t *nodeTitle,TNode *mother,
1021 TShape *shape,Bool_t axis) const {
1022 // Creates a node inside of the node mother out of the shape shape
1023 // in the position, with respect to mother, indecated by "this". If axis
1024 // is ture, it will insert an axis within this node/shape.
1026 // Char_t *nodeName This name of this node
1027 // Char_t *nodeTitle This node title
1028 // TNode *mother The node this node will be inside of/with respect to
1029 // TShape *shape The shape of this node
1030 // Bool_t axis If ture, a set of x,y,z axis will be included
1034 // A pointer to "this" node.
1035 Double_t trans[3],matrix[3][3],*matr;
1036 TRotMatrix *rot = new TRotMatrix();
1039 matr = &(matrix[0][0]);
1040 this->GetTranslation(trans);
1041 this->GetMatrix(matrix);
1042 rot->SetMatrix(matr);
1048 TNode *node1 = new TNode(name.Data(),title.Data(),shape,
1049 trans[0],trans[1],trans[2],rot);
1052 const Float_t kScale=0.5,kLw=0.2;
1053 Float_t xchar[13][2]={
1054 {0.5*kLw,1.},{0.,0.5*kLw},{0.5-0.5*kLw,0.5},
1055 {0.,0.5*kLw},{0.5*kLw,0.},{0.5,0.5-0.5*kLw},
1056 {1-0.5*kLw,0.},{1.,0.5*kLw},{0.5+0.5*kLw,0.5},
1057 {1.,1.-0.5*kLw},{1.-0.5*kLw,1.},{0.5,0.5+0.5*kLw},
1059 Float_t ychar[10][2]={
1060 {.5-0.5*kLw,0.},{.5+0.5*kLw,0.},{.5+0.5*kLw,0.5-0.5*kLw},
1061 {1.,1.-0.5*kLw},{1.-0.5*kLw,1.},{0.5+0.5*kLw,0.5},
1062 {0.5*kLw,1.} ,{0.,1-0.5*kLw} ,{0.5-0.5*kLw,0.5},
1064 Float_t zchar[11][2]={
1065 {0.,1.},{0,1.-kLw},{1.-kLw,1.-kLw},{0.,kLw} ,{0.,0.},
1066 {1.,0.},{1.,kLw} ,{kLw,kLw} ,{1.,1.-kLw},{1.,1.},
1068 for(i=0;i<13;i++)for(j=0;j<2;j++){
1069 if(i<13) xchar[i][j] = kScale*xchar[i][j];
1070 if(i<10) ychar[i][j] = kScale*ychar[i][j];
1071 if(i<11) zchar[i][j] = kScale*zchar[i][j];
1073 TXTRU *axisxl = new TXTRU("x","x","text",12,2);
1074 for(i=0;i<12;i++) axisxl->DefineVertex(i,xchar[i][0],xchar[i][1]);
1075 axisxl->DefineSection(0,-0.5*kLw);axisxl->DefineSection(1,0.5*kLw);
1076 TXTRU *axisyl = new TXTRU("y","y","text",9,2);
1077 for(i=0;i<9;i++) axisyl->DefineVertex(i,ychar[i][0],ychar[i][1]);
1078 axisyl->DefineSection(0,-0.5*kLw);axisyl->DefineSection(1,0.5*kLw);
1079 TXTRU *axiszl = new TXTRU("z","z","text",10,2);
1080 for(i=0;i<10;i++) axiszl->DefineVertex(i,zchar[i][0],zchar[i][1]);
1081 axiszl->DefineSection(0,-0.5*kLw);axiszl->DefineSection(1,0.5*kLw);
1082 Float_t lxy[13][2]={
1083 {-0.5*kLw,-0.5*kLw},{0.8,-0.5*kLw},{0.8,-0.1},{1.0,0.0},
1084 {0.8,0.1},{0.8,0.5*kLw},{0.5*kLw,0.5*kLw},{0.5*kLw,0.8},
1085 {0.1,0.8},{0.0,1.0},{-0.1,0.8},{-0.5*kLw,0.8},
1086 {-0.5*kLw,-0.5*kLw}};
1087 TXTRU *axisxy = new TXTRU("axisxy","axisxy","text",13,2);
1088 for(i=0;i<13;i++) axisxy->DefineVertex(i,lxy[i][0],lxy[i][1]);
1089 axisxy->DefineSection(0,-0.5*kLw);axisxy->DefineSection(1,0.5*kLw);
1091 {0.5*kLw,-0.5*kLw},{0.8,-0.5*kLw},{0.8,-0.1},{1.0,0.0},
1092 {0.8,0.1},{0.8,0.5*kLw},{0.5*kLw,0.5*kLw},
1093 {0.5*kLw,-0.5*kLw}};
1094 TXTRU *axisz = new TXTRU("axisz","axisz","text",8,2);
1095 for(i=0;i<8;i++) axisz->DefineVertex(i,lz[i][0],lz[i][1]);
1096 axisz->DefineSection(0,-0.5*kLw);axisz->DefineSection(1,0.5*kLw);
1097 //TRotMatrix *xaxis90= new TRotMatrix("xaixis90","",90.0, 0.0, 0.0);
1098 TRotMatrix *yaxis90= new TRotMatrix("yaixis90","", 0.0,90.0, 0.0);
1099 TRotMatrix *zaxis90= new TRotMatrix("zaixis90","", 0.0, 0.0,90.0);
1102 title = name.Append("axisxy");
1103 TNode *nodeaxy = new TNode(title.Data(),title.Data(),axisxy);
1104 title = name.Append("axisz");
1105 TNode *nodeaz = new TNode(title.Data(),title.Data(),axisz,
1107 TNode *textboxX0 = new TNode("textboxX0","textboxX0",axisxl,
1108 lxy[3][0],lxy[3][1],0.0);
1109 TNode *textboxX1 = new TNode("textboxX1","textboxX1",axisxl,
1110 lxy[3][0],lxy[3][1],0.0,yaxis90);
1111 TNode *textboxX2 = new TNode("textboxX2","textboxX2",axisxl,
1112 lxy[3][0],lxy[3][1],0.0,zaxis90);
1113 TNode *textboxY0 = new TNode("textboxY0","textboxY0",axisyl,
1114 lxy[9][0],lxy[9][1],0.0);
1115 TNode *textboxY1 = new TNode("textboxY1","textboxY1",axisyl,
1116 lxy[9][0],lxy[9][1],0.0,yaxis90);
1117 TNode *textboxY2 = new TNode("textboxY2","textboxY2",axisyl,
1118 lxy[9][0],lxy[9][1],0.0,zaxis90);
1119 TNode *textboxZ0 = new TNode("textboxZ0","textboxZ0",axiszl,
1121 TNode *textboxZ1 = new TNode("textboxZ1","textboxZ1",axiszl,
1122 0.0,0.0,lz[3][0],yaxis90);
1123 TNode *textboxZ2 = new TNode("textboxZ2","textboxZ2",axiszl,
1124 0.0,0.0,lz[3][0],zaxis90);
1140 //----------------------------------------------------------------------
1141 void AliITSgeomMatrix::MakeFigures() const {
1142 // make figures to help document this class
1149 const Double_t kDx0=550.,kDy0=550.,kDz0=550.; // cm
1150 const Double_t kDx=1.0,kDy=0.300,kDz=3.0,kRmax=0.1; // cm
1151 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},
1153 TCanvas *c = new TCanvas(kFALSE);// create a batch mode canvas.
1154 #if ROOT_VERSION_CODE>= 331523
1155 Double_t rmin[]={-1,-1,-1};
1156 Double_t rmax[]={ 1, 1, 1};
1157 TView *view = new TView3D(1,rmin,rmax);
1159 TView *view = new TView(1); // Create Cartesian coordiante view
1161 TBRIK *mother = new TBRIK("Mother","Mother","void",kDx0,kDy0,kDz0);
1162 TBRIK *det = new TBRIK("Detector","","Si",kDx,kDy,kDz);
1163 TPolyLine3D *axis = new TPolyLine3D(5,&(l[0][0]));
1164 TPCON *arrow = new TPCON("arrow","","air",0.0,360.,2);
1165 TRotMatrix *xarrow= new TRotMatrix("xarrow","",90.,0.0,0.0);
1166 TRotMatrix *yarrow= new TRotMatrix("yarrow","",0.0,90.,0.0);
1168 det->SetLineColor(0); // black
1169 det->SetLineStyle(1); // solid line
1170 det->SetLineWidth(2); // pixel units
1171 det->SetFillColor(1); // black
1172 det->SetFillStyle(4010); // window is 90% transparent
1173 arrow->SetLineColor(det->GetLineColor());
1174 arrow->SetLineWidth(det->GetLineWidth());
1175 arrow->SetLineStyle(det->GetLineStyle());
1176 arrow->SetFillColor(1); // black
1177 arrow->SetFillStyle(4100); // window is 100% opaque
1178 arrow->DefineSection(0,0.0,0.0,kRmax);
1179 arrow->DefineSection(1,2.*kRmax,0.0,0.0);
1180 view->SetRange(-kDx0,-kDy0,-kDz0,kDx0,kDy0,kDz0);
1182 TNode *node0 = new TNode("NODE0","NODE0",mother);
1184 TNode *node1 = new TNode("NODE1","NODE1",det);
1186 TNode *nodex = new TNode("NODEx","NODEx",arrow,
1187 l[0][0],l[0][1],l[0][2],xarrow);
1188 TNode *nodey = new TNode("NODEy","NODEy",arrow,
1189 l[2][0],l[2][1],l[2][2],yarrow);
1190 TNode *nodez = new TNode("NODEz","NODEz",arrow,l[4][0],l[4][1],l[4][2]);
1201 c->SaveAs("AliITSgeomMatrix_L1.gif");
1203 //----------------------------------------------------------------------
1204 ostream &operator<<(ostream &os,AliITSgeomMatrix &p){
1205 // Standard output streaming function.
1207 // ostream &os The output stream to print the class data on
1208 // AliITSgeomMatrix &p This class
1217 //----------------------------------------------------------------------
1218 istream &operator>>(istream &is,AliITSgeomMatrix &r){
1219 // Standard input streaming function.
1221 // ostream &os The input stream to print the class data on
1222 // AliITSgeomMatrix &p This class
1231 //----------------------------------------------------------------------