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"
48 ClassImp(AliITSgeomMatrix)
49 //----------------------------------------------------------------------
50 AliITSgeomMatrix::AliITSgeomMatrix():
51 TObject(), // Base Class.
52 fDetectorIndex(0), // Detector type index (like fShapeIndex was)
53 fid(), // layer, ladder, detector numbers.
54 frot(), //! vector of rotations about x,y,z [radians].
55 ftran(), // Translation vector of module x,y,z.
56 fCylR(0.0), //! R Translation in Cylinderical coordinates
57 fCylPhi(0.0),//! Phi Translation vector in Cylindrical coord.
58 fm(), // Rotation matrix based on frot.
59 fPath(){ // Path in geometry to this module
60 // The Default constructor for the AliITSgeomMatrix class. By Default
61 // the angles of rotations are set to zero, meaning that the rotation
62 // matrix is the unit matrix. The translation vector is also set to
63 // zero as are the module id number. The detector type is set to -1
64 // (an undefined value). The full rotation matrix is kept so that
65 // the evaluation of a coordinate transformation can be done
66 // quickly and with a minimum of CPU overhead. The basic coordinate
67 // systems are the ALICE global coordinate system and the detector
68 // local coordinate system. In general this structure is not limited
69 // to just those two coordinate systems.
72 <img src="picts/ITS/AliITSgeomMatrix_L1.gif">
80 // A default constructes AliITSgeomMatrix class.
83 fDetectorIndex = -1; // a value never defined.
86 frot[i] = ftran[i] = 0.0;
87 for(j=0;j<3;j++) fm[i][j] = 0.0;
89 fm[0][0] = fm[1][1] = fm[2][2] = 1.0;
92 //----------------------------------------------------------------------
93 AliITSgeomMatrix::AliITSgeomMatrix(const AliITSgeomMatrix &source) :
94 TObject(source), // Base Class.
95 fDetectorIndex(source.fDetectorIndex),// Detector type index (like
97 fid(), // layer, ladder, detector numbers.
98 frot(), //! vector of rotations about x,y,z [radians].
99 ftran(), // Translation vector of module x,y,z.
100 fCylR(source.fCylR), //! R Translation in Cylinderical coordinates
101 fCylPhi(source.fCylPhi),//! Phi Translation vector in Cylindrical coord.
102 fm(), // Rotation matrix based on frot.
104 // The standard Copy constructor. This make a full / proper copy of
107 // AliITSgeomMatrix &source The source of this copy
111 // A copy constructes AliITSgeomMatrix class.
115 this->fid[i] = source.fid[i];
116 this->frot[i] = source.frot[i];
117 this->ftran[i] = source.ftran[i];
118 for(j=0;j<3;j++) this->fm[i][j] = source.fm[i][j];
121 //----------------------------------------------------------------------
122 AliITSgeomMatrix& AliITSgeomMatrix::operator=(const AliITSgeomMatrix &source){
123 // The standard = operator. This make a full / proper copy of
125 // The standard Copy constructor. This make a full / proper copy of
128 // AliITSgeomMatrix &source The source of this copy
132 // A copy of the source AliITSgeomMatrix class.
134 if(this == &source)return *this;
137 this->fDetectorIndex = source.fDetectorIndex;
138 this->fCylR = source.fCylR;
139 this->fCylPhi = source.fCylPhi;
141 this->fid[i] = source.fid[i];
142 this->frot[i] = source.frot[i];
143 this->ftran[i] = source.ftran[i];
144 for(j=0;j<3;j++) this->fm[i][j] = source.fm[i][j];
146 this->fPath = source.fPath;
149 //----------------------------------------------------------------------
150 AliITSgeomMatrix::AliITSgeomMatrix(Int_t idt,const Int_t id[3],
151 const Double_t rot[3],const Double_t tran[3]):
152 TObject(), // Base class
153 fDetectorIndex(idt), // Detector type index (like fShapeIndex was)
154 fid(), // layer, ladder, detector numbers.
155 frot(), //! vector of rotations about x,y,z [radians].
156 ftran(), // Translation vector of module x,y,z.
157 fCylR(0.0), //! R Translation in Cylinderical coordinates
158 fCylPhi(0.0),//! Phi Translation vector in Cylindrical coord.
159 fm(), // Rotation matrix based on frot.
160 fPath(){ // Path in geometry to this moduel
161 // This is a constructor for the AliITSgeomMatrix class. The matrix is
162 // defined by 3 standard rotation angles [radians], and the translation
163 // vector tran [cm]. In addition the layer, ladder, and detector number
164 // for this particular module and the type of module must be given.
165 // The full rotation matrix is kept so that the evaluation
166 // of a coordinate transformation can be done quickly and with a minimum
167 // of CPU overhead. The basic coordinate systems are the ALICE global
168 // coordinate system and the detector local coordinate system. In general
169 // this structure is not limited to just those two coordinate systems.
172 <img src="picts/ITS/AliITSgeomMatrix_L1.gif">
176 // Int_t idt The detector index value
177 // Int_t id[3] The layer, ladder, and detector numbers
178 // Double_t rot[3] The 3 Cartician rotaion angles [radians]
179 // Double_t tran[3] The 3 Cartician translation distnaces
183 // A properly inilized AliITSgeomMatrix class.
191 fCylR = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
192 fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
193 if(fCylPhi<0.0) fCylPhi += 2.*TMath::Pi();
194 this->MatrixFromAngle();
196 //----------------------------------------------------------------------
197 AliITSgeomMatrix::AliITSgeomMatrix(Int_t idt, const Int_t id[3],
198 Double_t matrix[3][3],
199 const Double_t tran[3]):
200 TObject(), // Base class
201 fDetectorIndex(idt), // Detector type index (like fShapeIndex was)
202 fid(), // layer, ladder, detector numbers.
203 frot(), //! vector of rotations about x,y,z [radians].
204 ftran(), // Translation vector of module x,y,z.
205 fCylR(0.0), //! R Translation in Cylinderical coordinates
206 fCylPhi(0.0),//! Phi Translation vector in Cylindrical coord.
207 fm(), // Rotation matrix based on frot.
208 fPath(){ // Path in geometry to this module
209 // This is a constructor for the AliITSgeomMatrix class. The
210 // rotation matrix is given as one of the inputs, and the
211 // translation vector tran [cm]. In addition the layer, ladder,
212 // and detector number for this particular module and the type of
213 // module must be given. The full rotation matrix is kept so that
214 // the evaluation of a coordinate transformation can be done quickly
215 // and with a minimum of CPU overhead. The basic coordinate systems
216 // are the ALICE global coordinate system and the detector local
217 // coordinate system. In general this structure is not limited to just
218 // those two coordinate systems.
221 <img src="picts/ITS/AliITSgeomMatrix_L1.gif">
225 // Int_t idt The detector index value
226 // Int_t id[3] The layer, ladder, and detector numbers
227 // Double_t rot[3][3] The 3x3 Cartician rotaion matrix
228 // Double_t tran[3] The 3 Cartician translation distnaces
232 // A properly inilized AliITSgeomMatrix class.
238 for(j=0;j<3;j++) fm[i][j] = matrix[i][j];
240 fCylR = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
241 fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
242 if(fCylPhi<0.0) fCylPhi += 2.*TMath::Pi();
243 this->AngleFromMatrix();
245 //----------------------------------------------------------------------
246 void AliITSgeomMatrix::SixAnglesFromMatrix(Double_t *ang)const{
247 // This function returns the 6 GEANT 3.21 rotation angles [degrees] in
248 // the array ang which must be at least [6] long.
252 // Double_t ang[6] The 6 Geant3.21 rotation angles. [degrees]
255 Double_t si,c=180./TMath::Pi();
256 const Double_t epsil=1.e-15;
258 ang[1] = TMath::ATan2(fm[0][1],fm[0][0]);
259 if( !(TMath::AreEqualAbs(TMath::Cos(ang[1]),0.,epsil))) si = fm[0][0]/TMath::Cos(ang[1]);
260 else si = fm[0][1]/TMath::Sin(ang[1]);
261 ang[0] = TMath::ATan2(si,fm[0][2]);
263 ang[3] = TMath::ATan2(fm[1][1],fm[1][0]);
264 if(!(TMath::AreEqualAbs(TMath::Cos(ang[3]),0.,epsil))) si = fm[1][0]/TMath::Cos(ang[3]);
265 else si = fm[1][1]/TMath::Sin(ang[3]);
266 ang[2] = TMath::ATan2(si,fm[1][2]);
268 ang[5] = TMath::ATan2(fm[2][1],fm[2][0]);
269 if(!(TMath::AreEqualAbs(TMath::Cos(ang[5]),0.,epsil))) si = fm[2][0]/TMath::Cos(ang[5]);
270 else si = fm[2][1]/TMath::Sin(ang[5]);
271 ang[4] = TMath::ATan2(si,fm[2][2]);
273 for(Int_t i=0;i<6;i++) {ang[i] *= c; if(ang[i]<0.0) ang[i] += 360.;}
275 //----------------------------------------------------------------------
276 void AliITSgeomMatrix::MatrixFromSixAngles(const Double_t *ang){
277 // Given the 6 GEANT 3.21 rotation angles [degree], this will compute and
278 // set the rotations matrix and 3 standard rotation angles [radians].
279 // These angles and rotation matrix are overwrite the existing values in
282 // Double_t ang[6] The 6 Geant3.21 rotation angles. [degrees]
288 Double_t si,lr[9],c=TMath::Pi()/180.;
289 const Double_t epsil = 1.e-15;
291 si = TMath::Sin(c*ang[0]);
292 if(TMath::AreEqualAbs(ang[0],90.,epsil)) si = +1.0;
293 if(TMath::AreEqualAbs(ang[0],270.,epsil)) si = -1.0;
294 if(TMath::AreEqualAbs(ang[0],0.,epsil) ||TMath::AreEqualAbs(ang[0],180.,epsil)) si = 0.0;
295 lr[0] = si * TMath::Cos(c*ang[1]);
296 lr[1] = si * TMath::Sin(c*ang[1]);
297 lr[2] = TMath::Cos(c*ang[0]);
298 if(TMath::AreEqualAbs(ang[0],90.,epsil)||TMath::AreEqualAbs(ang[0],270.,epsil)) lr[2] = 0.0;
299 if(TMath::AreEqualAbs(ang[0],0.,epsil)) lr[2] = +1.0;
300 if(TMath::AreEqualAbs(ang[0],180.,epsil)) lr[2] = -1.0;
302 si = TMath::Sin(c*ang[2]);
303 if(TMath::AreEqualAbs(ang[2],90.,epsil)) si = +1.0;
304 if(TMath::AreEqualAbs(ang[2],270.,epsil)) si = -1.0;
305 if(TMath::AreEqualAbs(ang[2],0.,epsil) || TMath::AreEqualAbs(ang[2],180.,epsil)) si = 0.0;
306 lr[3] = si * TMath::Cos(c*ang[3]);
307 lr[4] = si * TMath::Sin(c*ang[3]);
308 lr[5] = TMath::Cos(c*ang[2]);
309 if(TMath::AreEqualAbs(ang[2],90.,epsil) || TMath::AreEqualAbs(ang[2],270.,epsil)) lr[5] = 0.0;
310 if(TMath::AreEqualAbs(ang[2],0.,epsil)) lr[5] = +1.0;
311 if(TMath::AreEqualAbs(ang[2],180.,epsil)) lr[5] = -1.0;
313 si = TMath::Sin(c*ang[4]);
314 if(TMath::AreEqualAbs(ang[4],90.,epsil)) si = +1.0;
315 if(TMath::AreEqualAbs(ang[4],270.0,epsil)) si = -1.0;
316 if(TMath::AreEqualAbs(ang[4],0.,epsil)|| TMath::AreEqualAbs(ang[4],180.,epsil)) si = 0.0;
317 lr[6] = si * TMath::Cos(c*ang[5]);
318 lr[7] = si * TMath::Sin(c*ang[5]);
319 lr[8] = TMath::Cos(c*ang[4]);
320 if(TMath::AreEqualAbs(ang[4],90.0,epsil) ||TMath::AreEqualAbs(ang[4],270.,epsil)) lr[8] = 0.0;
321 if(TMath::AreEqualAbs(ang[4],0.,epsil)) lr[8] = +1.0;
322 if(TMath::AreEqualAbs(ang[4],180.0,epsil)) lr[8] = -1.0;
323 // Normalize these elements and fill matrix fm.
324 for(i=0;i<3;i++){// reuse si.
326 for(j=0;j<3;j++) si += lr[3*i+j]*lr[3*i+j];
327 si = TMath::Sqrt(1./si);
328 for(j=0;j<3;j++) fm[i][j] = si*lr[3*i+j];
330 this->AngleFromMatrix();
332 //----------------------------------------------------------------------
333 AliITSgeomMatrix::AliITSgeomMatrix(const Double_t rotd[6]/*degrees*/,
334 Int_t idt,const Int_t id[3],
335 const Double_t tran[3]):
336 TObject(), // Base class
337 fDetectorIndex(idt), // Detector type index (like fShapeIndex was)
338 fid(), // layer, ladder, detector numbers.
339 frot(), //! vector of rotations about x,y,z [radians].
340 ftran(), // Translation vector of module x,y,z.
341 fCylR(0.0), //! R Translation in Cylinderical coordinates
342 fCylPhi(0.0),//! Phi Translation vector in Cylindrical coord.
343 fm(), // Rotation matrix based on frot.
344 fPath(){ // Path in geometry to this module
345 // This is a constructor for the AliITSgeomMatrix class. The matrix
346 // is defined by the 6 GEANT 3.21 rotation angles [degrees], and
347 // the translation vector tran [cm]. In addition the layer, ladder,
348 // and detector number for this particular module and the type of
349 // module must be given. The full rotation matrix is kept so that
350 // the evaluation of a coordinate transformation can be done
351 // quickly and with a minimum of CPU overhead. The basic coordinate
352 // systems are the ALICE global coordinate system and the detector
353 // local coordinate system. In general this structure is not limited
354 // to just those two coordinate systems.
357 <img src="picts/ITS/AliITSgeomMatrix_L1.gif">
361 // Double_t rotd[6] The 6 Geant 3.21 rotation angles [degrees]
362 // Int_t idt The module Id number
363 // Int_t id[3] The layer, ladder and detector number
364 // Double_t tran[3] The translation vector
371 fCylR = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
372 fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
373 if(fCylPhi<0.0) fCylPhi += 2.*TMath::Pi();
374 this->MatrixFromSixAngles(rotd);
376 //----------------------------------------------------------------------
377 void AliITSgeomMatrix::AngleFromMatrix(){
378 // Computes the angles from the rotation matrix up to a phase of
379 // 180 degrees. The matrix used in AliITSgeomMatrix::MatrixFromAngle()
380 // and its inverse AliITSgeomMatrix::AngleFromMatrix() are defined in
381 // the following ways, R = Rz*Ry*Rx (M=R*L+T) where
382 // 1 0 0 Cy 0 +Sy Cz -Sz 0
383 // Rx= 0 Cx -Sx Ry= 0 1 0 Rz=+Sz Cz 0
384 // 0 +Sx Cx -Sy 0 Cy 0 0 1
385 // The choice of the since of S, comes from the choice between
386 // the rotation of the object or the coordinate system (view). I think
387 // that this choice is the first, the rotation of the object.
395 // get angles from matrix up to a phase of 180 degrees.
397 rx = TMath::ATan2(fm[2][1],fm[2][2]);if(rx<0.0) rx += 2.0*TMath::Pi();
398 ry = TMath::ASin(-fm[0][2]); if(ry<0.0) ry += 2.0*TMath::Pi();
399 rz = TMath::ATan2(fm[1][0],fm[0][0]);if(rz<0.0) rz += 2.0*TMath::Pi();
405 //----------------------------------------------------------------------
406 void AliITSgeomMatrix::MatrixFromAngle(){
407 // Computes the Rotation matrix from the angles [radians] kept in this
408 // class. The matrix used in AliITSgeomMatrix::MatrixFromAngle() and
409 // its inverse AliITSgeomMatrix::AngleFromMatrix() are defined in
410 // the following ways, R = Rz*Ry*Rx (M=R*L+T) where
411 // 1 0 0 Cy 0 +Sy Cz -Sz 0
412 // Rx= 0 Cx -Sx Ry= 0 1 0 Rz=+Sz Cz 0
413 // 0 +Sx Cx -Sy 0 Cy 0 0 1
414 // The choice of the since of S, comes from the choice between
415 // the rotation of the object or the coordinate system (view). I think
416 // that this choice is the first, the rotation of the object.
423 Double_t sx,sy,sz,cx,cy,cz;
425 sx = TMath::Sin(frot[0]); cx = TMath::Cos(frot[0]);
426 sy = TMath::Sin(frot[1]); cy = TMath::Cos(frot[1]);
427 sz = TMath::Sin(frot[2]); cz = TMath::Cos(frot[2]);
428 fm[0][0] = +cz*cy; // fr[0]
429 fm[0][1] = +cz*sy*sx - sz*cx; // fr[1]
430 fm[0][2] = +cz*sy*cx + sz*sx; // fr[2]
431 fm[1][0] = +sz*cy; // fr[3]
432 fm[1][1] = +sz*sy*sx + cz*cx; // fr[4]
433 fm[1][2] = +sz*sy*cx - cz*sx; // fr[5]
434 fm[2][0] = -sy; // fr[6]
435 fm[2][1] = +cy*sx; // fr[7]
436 fm[2][2] = +cy*cx; // fr[8]
438 //----------------------------------------------------------------------
439 void AliITSgeomMatrix::SetEulerAnglesChi(const Double_t ang[3]){
440 // Computes the Rotation matrix from the Euler angles [radians],
441 // Chi-convention, kept in this class. The matrix used in
442 // AliITSgeomMatrix::SetEulerAnglesChi and
443 // its inverse AliITSgeomMatrix::GetEulerAnglesChi() are defined in
444 // the following ways, R = Rb*Rc*Rd (M=R*L+T) where
445 // C2 +S2 0 1 0 0 C0 +S0 0
446 // Rb=-S2 C2 0 Rc= 0 C1 +S1 Rd=-S0 C0 0
447 // 0 0 1 0 -S1 C1 0 0 1
448 // This form is taken from Wolfram Research's Geometry>
449 // Transformations>Rotations web page (also should be
450 // found in their book).
452 // Double_t ang[3] The three Euler Angles Phi, Theta, Psi
457 Double_t s0,s1,s2,c0,c1,c2;
459 s0 = TMath::Sin(ang[0]); c0 = TMath::Cos(ang[0]);
460 s1 = TMath::Sin(ang[1]); c1 = TMath::Cos(ang[1]);
461 s2 = TMath::Sin(ang[2]); c2 = TMath::Cos(ang[2]);
462 fm[0][0] = +c2*c0-c1*s0*s2; // fr[0]
463 fm[0][1] = +c2*s0+c1*c0*s2; // fr[1]
464 fm[0][2] = +s2*s1; // fr[2]
465 fm[1][0] = -s2*c0-c1*s0*c2; // fr[3]
466 fm[1][1] = -s2*s0+c1*c0*c2; // fr[4]
467 fm[1][2] = +c2*s1; // fr[5]
468 fm[2][0] = s1*s0; // fr[6]
469 fm[2][1] = -s1*c0; // fr[7]
470 fm[2][2] = +c1; // fr[8]
474 //----------------------------------------------------------------------
475 void AliITSgeomMatrix::GtoLPosition(const Double_t g0[3],Double_t l[3]) const {
476 // Returns the local coordinates given the global coordinates [cm].
478 // Double_t g[3] The position represented in the ALICE
479 // global coordinate system
481 // Double_t l[3] The poistion represented in the local
482 // detector coordiante system
488 for(i=0;i<3;i++) g[i] = g0[i] - ftran[i];
491 for(j=0;j<3;j++) l[i] += fm[i][j]*g[j];
492 // g = R l + translation
496 //----------------------------------------------------------------------
497 void AliITSgeomMatrix::LtoGPosition(const Double_t l[3],Double_t g[3]) const {
498 // Returns the global coordinates given the local coordinates [cm].
500 // Double_t l[3] The poistion represented in the detector
501 // local coordinate system
503 // Double_t g[3] The poistion represented in the ALICE
504 // Global coordinate system
511 for(j=0;j<3;j++) g[i] += fm[j][i]*l[j];
513 // g = R^t l + translation
517 //----------------------------------------------------------------------
518 void AliITSgeomMatrix::GtoLMomentum(const Double_t g[3],Double_t l[3]) const{
519 // Returns the local coordinates of the momentum given the global
520 // coordinates of the momentum. It transforms just like GtoLPosition
521 // except that the translation vector is zero.
523 // Double_t g[3] The momentum represented in the ALICE global
526 // Double_t l[3] the momentum represented in the detector
527 // local coordinate system
534 for(j=0;j<3;j++) l[i] += fm[i][j]*g[j];
539 //----------------------------------------------------------------------
540 void AliITSgeomMatrix::LtoGMomentum(const Double_t l[3],Double_t g[3]) const {
541 // Returns the Global coordinates of the momentum given the local
542 // coordinates of the momentum. It transforms just like LtoGPosition
543 // except that the translation vector is zero.
545 // Double_t l[3] the momentum represented in the detector
546 // local coordinate system
548 // Double_t g[3] The momentum represented in the ALICE global
556 for(j=0;j<3;j++) g[i] += fm[j][i]*l[j];
561 //----------------------------------------------------------------------
562 void AliITSgeomMatrix::GtoLPositionError(const Double_t g[3][3],
563 Double_t l[3][3]) const {
564 // Given an Uncertainty matrix in Global coordinates it is
565 // rotated so that its representation in local coordinates can
566 // be returned. There is no effect due to the translation vector
567 // or its uncertainty.
569 // Double_t g[3][3] The error matrix represented in the ALICE global
572 // Double_t l[3][3] the error matrix represented in the detector
573 // local coordinate system
578 for(i=0;i<3;i++)for(m=0;m<3;m++){
580 for(j=0;j<3;j++)for(k=0;k<3;k++)
581 l[i][m] += fm[j][i]*g[j][k]*fm[k][m];
586 //----------------------------------------------------------------------
587 void AliITSgeomMatrix::LtoGPositionError(const Double_t l[3][3],
588 Double_t g[3][3]) const {
589 // Given an Uncertainty matrix in Local coordinates it is rotated so that
590 // its representation in global coordinates can be returned. There is no
591 // effect due to the translation vector or its uncertainty.
593 // Double_t l[3][3] the error matrix represented in the detector
594 // local coordinate system
596 // Double_t g[3][3] The error matrix represented in the ALICE global
602 for(i=0;i<3;i++)for(m=0;m<3;m++){
604 for(j=0;j<3;j++)for(k=0;k<3;k++)
605 g[i][m] += fm[i][j]*l[j][k]*fm[m][k];
610 //----------------------------------------------------------------------
611 void AliITSgeomMatrix::GtoLPositionTracking(const Double_t g[3],
612 Double_t l[3]) const {
613 // A slightly different coordinate system is used when tracking.
614 // This coordinate system is only relevant when the geometry represents
615 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
616 // alone but X -> -Y and Y -> X such that X always points out of the
617 // ITS Cylinder for every layer including layer 1 (where the detector
618 // are mounted upside down).
621 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
625 // Double_t g[3] The position represented in the ALICE
626 // global coordinate system
628 // Double_t l[3] The poistion represented in the local
629 // detector coordiante system
634 this->GtoLPosition(g,l0);
635 if(fid[0]==1){ // for layer 1 the detector are flipped upside down
636 // with respect to the others.
647 //----------------------------------------------------------------------
648 void AliITSgeomMatrix::LtoGPositionTracking(const Double_t l[3],
649 Double_t g[3]) const {
650 // A slightly different coordinate system is used when tracking.
651 // This coordinate system is only relevant when the geometry represents
652 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
653 // alone but X -> -Y and Y -> X such that X always points out of the
654 // ITS Cylinder for every layer including layer 1 (where the detector
655 // are mounted upside down).
658 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
662 // Double_t l[3] The poistion represented in the detector
663 // local coordinate system
665 // Double_t g[3] The poistion represented in the ALICE
666 // Global coordinate system
671 if(fid[0]==1){ // for layer 1 the detector are flipped upside down
672 // with respect to the others.
681 this->LtoGPosition(l0,g);
684 //----------------------------------------------------------------------
685 void AliITSgeomMatrix::GtoLMomentumTracking(const Double_t g[3],
686 Double_t l[3]) const {
687 // A slightly different coordinate system is used when tracking.
688 // This coordinate system is only relevant when the geometry represents
689 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
690 // alone but X -> -Y and Y -> X such that X always points out of the
691 // ITS Cylinder for every layer including layer 1 (where the detector
692 // are mounted upside down).
695 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
699 // Double_t g[3] The momentum represented in the ALICE global
702 // Double_t l[3] the momentum represented in the detector
703 // local coordinate system
708 this->GtoLMomentum(g,l0);
709 if(fid[0]==1){ // for layer 1 the detector are flipped upside down
710 // with respect to the others.
721 //----------------------------------------------------------------------
722 void AliITSgeomMatrix::LtoGMomentumTracking(const Double_t l[3],
723 Double_t g[3]) const {
724 // A slightly different coordinate system is used when tracking.
725 // This coordinate system is only relevant when the geometry represents
726 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
727 // alone but X -> -Y and Y -> X such that X always points out of the
728 // ITS Cylinder for every layer including layer 1 (where the detector
729 // are mounted upside down).
732 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
736 // Double_t l[3] the momentum represented in the detector
737 // local coordinate system
739 // Double_t g[3] The momentum represented in the ALICE global
745 if(fid[0]==1){ // for layer 1 the detector are flipped upside down
746 // with respect to the others.
755 this->LtoGMomentum(l0,g);
758 //----------------------------------------------------------------------
759 void AliITSgeomMatrix::GtoLPositionErrorTracking(const Double_t g[3][3],
760 Double_t l[3][3]) const {
761 // A slightly different coordinate system is used when tracking.
762 // This coordinate system is only relevant when the geometry represents
763 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
764 // alone but X -> -Y and Y -> X such that X always points out of the
765 // ITS Cylinder for every layer including layer 1 (where the detector
766 // are mounted upside down).
769 <img src="picts/ITS/AliITSgeomMatrix_TE1.gif">
773 // Double_t g[3][3] The error matrix represented in the ALICE global
776 // Double_t l[3][3] the error matrix represented in the detector
777 // local coordinate system
781 Double_t a0[3][3] = {{0.,+1.,0.},{-1.,0.,0.},{0.,0.,+1.}};
782 Double_t a1[3][3] = {{0.,-1.,0.},{+1.,0.,0.},{0.,0.,+1.}};
784 if(fid[0]==1) for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
785 rt[i][k] = a0[i][j]*fm[j][k];
786 else for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
787 rt[i][k] = a1[i][j]*fm[j][k];
788 for(i=0;i<3;i++)for(m=0;m<3;m++){
790 for(j=0;j<3;j++)for(k=0;k<3;k++)
791 l[i][m] += rt[j][i]*g[j][k]*rt[k][m];
796 //----------------------------------------------------------------------
797 void AliITSgeomMatrix::LtoGPositionErrorTracking(const Double_t l[3][3],
798 Double_t g[3][3]) const {
799 // A slightly different coordinate system is used when tracking.
800 // This coordinate system is only relevant when the geometry represents
801 // the cylindrical ALICE ITS geometry. For tracking the Z axis is left
802 // alone but X -> -Y and Y -> X such that X always points out of the
803 // ITS Cylinder for every layer including layer 1 (where the detector
804 // are mounted upside down).
807 <img src="picts/ITS/AliITSgeomMatrix_TE1.gif">
811 // Double_t l[3][3] the error matrix represented in the detector
812 // local coordinate system
814 // Double_t g[3][3] The error matrix represented in the ALICE global
820 Double_t a0[3][3] = {{0.,+1.,0.},{-1.,0.,0.},{0.,0.,+1.}};
821 Double_t a1[3][3] = {{0.,-1.,0.},{+1.,0.,0.},{0.,0.,+1.}};
823 if(fid[0]==1) for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
824 rt[i][k] = a0[i][j]*fm[j][k];
825 else for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
826 rt[i][k] = a1[i][j]*fm[j][k];
827 for(i=0;i<3;i++)for(m=0;m<3;m++){
829 for(j=0;j<3;j++)for(k=0;k<3;k++)
830 g[i][m] += rt[i][j]*l[j][k]*rt[m][k];
835 //----------------------------------------------------------------------
836 void AliITSgeomMatrix::PrintTitles(ostream *os) const {
837 // Standard output format for this class but it includes variable
838 // names and formatting that makes it easer to read.
840 // ostream *os The output stream to print the title on
847 *os << "fDetectorIndex=" << fDetectorIndex << " fid[3]={";
848 for(i=0;i<3;i++) *os << fid[i] << " ";
849 *os << "} frot[3]={";
850 for(i=0;i<3;i++) *os << frot[i] << " ";
851 *os << "} ftran[3]={";
852 for(i=0;i<3;i++) *os << ftran[i] << " ";
853 *os << "} fm[3][3]={";
854 for(i=0;i<3;i++){for(j=0;j<3;j++){ *os << fm[i][j] << " ";} *os <<"}{";}
858 //----------------------------------------------------------------------
859 void AliITSgeomMatrix::PrintComment(ostream *os) const {
860 // output format used by Print.
862 // ostream *os The output stream to print the comments on
867 *os << "fDetectorIndex fid[0] fid[1] fid[2] ftran[0] ftran[1] ftran[2] ";
868 *os << "fm[0][0] fm[0][1] fm[0][2] fm[1][0] fm[1][1] fm[1][2] ";
869 *os << "fm[2][0] fm[2][1] fm[2][2] ";
872 //----------------------------------------------------------------------
873 void AliITSgeomMatrix::Print(ostream *os)const{
874 // Standard output format for this class.
876 // ostream *os The output stream to print the class data on
889 #if defined __ICC || defined __ECC || defined __xlC__
896 fmt = os->setf(ios::scientific); // set scientific floating point output
897 *os << fDetectorIndex << " ";
898 for(i=0;i<3;i++) *os << fid[i] << " ";
899 // for(i=0;i<3;i++) *os << frot[i] << " "; // Redundant with fm[][].
900 for(i=0;i<3;i++) *os << setprecision(16) << ftran[i] << " ";
901 for(i=0;i<3;i++)for(j=0;j<3;j++) *os << setprecision(16) <<
903 *os << fPath.Length()<< " ";
904 for(i=0;i<fPath.Length();i++) *os << fPath[i];
906 os->flags(fmt); // reset back to old formating.
909 //----------------------------------------------------------------------
910 void AliITSgeomMatrix::Read(istream *is){
911 // Standard input format for this class.
913 // istream *is The input stream to read on
919 const Int_t kMxVal=10000;
920 *is >> fDetectorIndex;
921 for(i=0;i<3;i++) *is >> fid[i];
922 // for(i=0;i<3;i++) *is >> frot[i]; // Redundant with fm[][].
923 for(i=0;i<3;i++) *is >> ftran[i];
924 for(i=0;i<3;i++)for(j=0;j<3;j++) *is >> fm[i][j];
925 while(is->peek()==' ')is->get(); // skip white spaces
926 if(isprint(is->peek())){ // old format did not have path.
927 *is >> j; // string length
929 AliError(Form("j> %d",kMxVal));
933 for(i=0;i<j;i++) {*is >> fPath[i];}
935 AngleFromMatrix(); // compute angles frot[].
936 fCylR = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
937 fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
938 if(fCylPhi<0.0) fCylPhi += 2.*TMath::Pi();
941 //______________________________________________________________________
942 void AliITSgeomMatrix::Streamer(TBuffer &R__b){
943 // Stream an object of class AliITSgeomMatrix.
945 // TBuffer &R__b The output buffer to stream data on.
951 if (R__b.IsReading()) {
952 AliITSgeomMatrix::Class()->ReadBuffer(R__b, this);
953 fCylR = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
954 fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
955 this->AngleFromMatrix();
956 if(fCylPhi<0.0) fCylPhi += 2.*TMath::Pi();
958 AliITSgeomMatrix::Class()->WriteBuffer(R__b, this);
961 //______________________________________________________________________
962 void AliITSgeomMatrix::SetTranslation(const Double_t tran[3]){
963 // Sets the translation vector and computes fCylR and fCylPhi.
965 // Double_t trans[3] The translation vector to be used
970 for(Int_t i=0;i<3;i++) ftran[i] = tran[i];
971 fCylR = TMath::Sqrt(ftran[0]*ftran[0]+ftran[1]*ftran[1]);
972 fCylPhi = TMath::ATan2(ftran[1],ftran[0]);
973 if(fCylPhi<0.0) fCylPhi += 2.*TMath::Pi();
975 //----------------------------------------------------------------------
976 TPolyLine3D* AliITSgeomMatrix::CreateLocalAxis() const {
977 // This class is used as part of the documentation of this class
983 // A pointer to a new TPolyLine3D object showing the 3 line
984 // segments that make up the this local axis in the global
988 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},
993 LtoGPosition(l[i],g[i]);
994 gf[3*i]=(Float_t)g[i][0];
995 gf[3*i+1]=(Float_t)g[i][1];
996 gf[3*i+2]=(Float_t)g[i][2];
998 return new TPolyLine3D(5,gf);
1000 //----------------------------------------------------------------------
1001 TPolyLine3D* AliITSgeomMatrix::CreateLocalAxisTracking() const {
1002 // This class is used as part of the documentation of this class
1008 // A pointer to a new TPolyLine3D object showing the 3 line
1009 // segments that make up the this local axis in the global
1010 // reference system.
1013 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},
1018 LtoGPositionTracking(l[i],g[i]);
1019 gf[3*i]=(Float_t)g[i][0];
1020 gf[3*i+1]=(Float_t)g[i][1];
1021 gf[3*i+2]=(Float_t)g[i][2];
1023 return new TPolyLine3D(5,gf);
1025 //----------------------------------------------------------------------
1026 TNode* AliITSgeomMatrix::CreateNode(const Char_t *nodeName,
1027 const Char_t *nodeTitle,TNode *mother,
1028 TShape *shape,Bool_t axis) const {
1029 // Creates a node inside of the node mother out of the shape shape
1030 // in the position, with respect to mother, indecated by "this". If axis
1031 // is ture, it will insert an axis within this node/shape.
1033 // Char_t *nodeName This name of this node
1034 // Char_t *nodeTitle This node title
1035 // TNode *mother The node this node will be inside of/with respect to
1036 // TShape *shape The shape of this node
1037 // Bool_t axis If ture, a set of x,y,z axis will be included
1041 // A pointer to "this" node.
1042 Double_t trans[3],matrix[3][3],*matr;
1043 TRotMatrix *rot = new TRotMatrix();
1046 matr = &(matrix[0][0]);
1047 this->GetTranslation(trans);
1048 this->GetMatrix(matrix);
1049 rot->SetMatrix(matr);
1055 TNode *node1 = new TNode(name.Data(),title.Data(),shape,
1056 trans[0],trans[1],trans[2],rot);
1059 const Float_t kScale=0.5,kLw=0.2;
1060 Float_t xchar[13][2]={
1061 {0.5*kLw,1.},{0.,0.5*kLw},{0.5-0.5*kLw,0.5},
1062 {0.,0.5*kLw},{0.5*kLw,0.},{0.5,0.5-0.5*kLw},
1063 {1-0.5*kLw,0.},{1.,0.5*kLw},{0.5+0.5*kLw,0.5},
1064 {1.,1.-0.5*kLw},{1.-0.5*kLw,1.},{0.5,0.5+0.5*kLw},
1066 Float_t ychar[10][2]={
1067 {.5-0.5*kLw,0.},{.5+0.5*kLw,0.},{.5+0.5*kLw,0.5-0.5*kLw},
1068 {1.,1.-0.5*kLw},{1.-0.5*kLw,1.},{0.5+0.5*kLw,0.5},
1069 {0.5*kLw,1.} ,{0.,1-0.5*kLw} ,{0.5-0.5*kLw,0.5},
1071 Float_t zchar[11][2]={
1072 {0.,1.},{0,1.-kLw},{1.-kLw,1.-kLw},{0.,kLw} ,{0.,0.},
1073 {1.,0.},{1.,kLw} ,{kLw,kLw} ,{1.,1.-kLw},{1.,1.},
1075 for(i=0;i<13;i++)for(j=0;j<2;j++){
1076 if(i<13) xchar[i][j] = kScale*xchar[i][j];
1077 if(i<10) ychar[i][j] = kScale*ychar[i][j];
1078 if(i<11) zchar[i][j] = kScale*zchar[i][j];
1080 TXTRU *axisxl = new TXTRU("x","x","text",12,2);
1081 for(i=0;i<12;i++) axisxl->DefineVertex(i,xchar[i][0],xchar[i][1]);
1082 axisxl->DefineSection(0,-0.5*kLw);axisxl->DefineSection(1,0.5*kLw);
1083 TXTRU *axisyl = new TXTRU("y","y","text",9,2);
1084 for(i=0;i<9;i++) axisyl->DefineVertex(i,ychar[i][0],ychar[i][1]);
1085 axisyl->DefineSection(0,-0.5*kLw);axisyl->DefineSection(1,0.5*kLw);
1086 TXTRU *axiszl = new TXTRU("z","z","text",10,2);
1087 for(i=0;i<10;i++) axiszl->DefineVertex(i,zchar[i][0],zchar[i][1]);
1088 axiszl->DefineSection(0,-0.5*kLw);axiszl->DefineSection(1,0.5*kLw);
1089 Float_t lxy[13][2]={
1090 {-0.5*kLw,-0.5*kLw},{0.8,-0.5*kLw},{0.8,-0.1},{1.0,0.0},
1091 {0.8,0.1},{0.8,0.5*kLw},{0.5*kLw,0.5*kLw},{0.5*kLw,0.8},
1092 {0.1,0.8},{0.0,1.0},{-0.1,0.8},{-0.5*kLw,0.8},
1093 {-0.5*kLw,-0.5*kLw}};
1094 TXTRU *axisxy = new TXTRU("axisxy","axisxy","text",13,2);
1095 for(i=0;i<13;i++) axisxy->DefineVertex(i,lxy[i][0],lxy[i][1]);
1096 axisxy->DefineSection(0,-0.5*kLw);axisxy->DefineSection(1,0.5*kLw);
1098 {0.5*kLw,-0.5*kLw},{0.8,-0.5*kLw},{0.8,-0.1},{1.0,0.0},
1099 {0.8,0.1},{0.8,0.5*kLw},{0.5*kLw,0.5*kLw},
1100 {0.5*kLw,-0.5*kLw}};
1101 TXTRU *axisz = new TXTRU("axisz","axisz","text",8,2);
1102 for(i=0;i<8;i++) axisz->DefineVertex(i,lz[i][0],lz[i][1]);
1103 axisz->DefineSection(0,-0.5*kLw);axisz->DefineSection(1,0.5*kLw);
1104 //TRotMatrix *xaxis90= new TRotMatrix("xaixis90","",90.0, 0.0, 0.0);
1105 TRotMatrix *yaxis90= new TRotMatrix("yaixis90","", 0.0,90.0, 0.0);
1106 TRotMatrix *zaxis90= new TRotMatrix("zaixis90","", 0.0, 0.0,90.0);
1109 title = name.Append("axisxy");
1110 TNode *nodeaxy = new TNode(title.Data(),title.Data(),axisxy);
1111 title = name.Append("axisz");
1112 TNode *nodeaz = new TNode(title.Data(),title.Data(),axisz,
1114 TNode *textboxX0 = new TNode("textboxX0","textboxX0",axisxl,
1115 lxy[3][0],lxy[3][1],0.0);
1116 TNode *textboxX1 = new TNode("textboxX1","textboxX1",axisxl,
1117 lxy[3][0],lxy[3][1],0.0,yaxis90);
1118 TNode *textboxX2 = new TNode("textboxX2","textboxX2",axisxl,
1119 lxy[3][0],lxy[3][1],0.0,zaxis90);
1120 TNode *textboxY0 = new TNode("textboxY0","textboxY0",axisyl,
1121 lxy[9][0],lxy[9][1],0.0);
1122 TNode *textboxY1 = new TNode("textboxY1","textboxY1",axisyl,
1123 lxy[9][0],lxy[9][1],0.0,yaxis90);
1124 TNode *textboxY2 = new TNode("textboxY2","textboxY2",axisyl,
1125 lxy[9][0],lxy[9][1],0.0,zaxis90);
1126 TNode *textboxZ0 = new TNode("textboxZ0","textboxZ0",axiszl,
1128 TNode *textboxZ1 = new TNode("textboxZ1","textboxZ1",axiszl,
1129 0.0,0.0,lz[3][0],yaxis90);
1130 TNode *textboxZ2 = new TNode("textboxZ2","textboxZ2",axiszl,
1131 0.0,0.0,lz[3][0],zaxis90);
1147 //----------------------------------------------------------------------
1148 void AliITSgeomMatrix::MakeFigures() const {
1149 // make figures to help document this class
1156 const Double_t kDx0=550.,kDy0=550.,kDz0=550.; // cm
1157 const Double_t kDx=1.0,kDy=0.300,kDz=3.0,kRmax=0.1; // cm
1158 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},
1160 TCanvas *c = new TCanvas(kFALSE);// create a batch mode canvas.
1161 #if ROOT_VERSION_CODE>= 331523
1162 Double_t rmin[]={-1,-1,-1};
1163 Double_t rmax[]={ 1, 1, 1};
1164 TView *view = new TView3D(1,rmin,rmax);
1166 TView *view = new TView(1); // Create Cartesian coordiante view
1168 TBRIK *mother = new TBRIK("Mother","Mother","void",kDx0,kDy0,kDz0);
1169 TBRIK *det = new TBRIK("Detector","","Si",kDx,kDy,kDz);
1170 TPolyLine3D *axis = new TPolyLine3D(5,&(l[0][0]));
1171 TPCON *arrow = new TPCON("arrow","","air",0.0,360.,2);
1172 TRotMatrix *xarrow= new TRotMatrix("xarrow","",90.,0.0,0.0);
1173 TRotMatrix *yarrow= new TRotMatrix("yarrow","",0.0,90.,0.0);
1175 det->SetLineColor(0); // black
1176 det->SetLineStyle(1); // solid line
1177 det->SetLineWidth(2); // pixel units
1178 det->SetFillColor(1); // black
1179 det->SetFillStyle(4010); // window is 90% transparent
1180 arrow->SetLineColor(det->GetLineColor());
1181 arrow->SetLineWidth(det->GetLineWidth());
1182 arrow->SetLineStyle(det->GetLineStyle());
1183 arrow->SetFillColor(1); // black
1184 arrow->SetFillStyle(4100); // window is 100% opaque
1185 arrow->DefineSection(0,0.0,0.0,kRmax);
1186 arrow->DefineSection(1,2.*kRmax,0.0,0.0);
1187 view->SetRange(-kDx0,-kDy0,-kDz0,kDx0,kDy0,kDz0);
1189 TNode *node0 = new TNode("NODE0","NODE0",mother);
1191 TNode *node1 = new TNode("NODE1","NODE1",det);
1193 TNode *nodex = new TNode("NODEx","NODEx",arrow,
1194 l[0][0],l[0][1],l[0][2],xarrow);
1195 TNode *nodey = new TNode("NODEy","NODEy",arrow,
1196 l[2][0],l[2][1],l[2][2],yarrow);
1197 TNode *nodez = new TNode("NODEz","NODEz",arrow,l[4][0],l[4][1],l[4][2]);
1208 c->SaveAs("AliITSgeomMatrix_L1.gif");
1210 //----------------------------------------------------------------------
1211 ostream &operator<<(ostream &os,AliITSgeomMatrix &p){
1212 // Standard output streaming function.
1214 // ostream &os The output stream to print the class data on
1215 // AliITSgeomMatrix &p This class
1224 //----------------------------------------------------------------------
1225 istream &operator>>(istream &is,AliITSgeomMatrix &r){
1226 // Standard input streaming function.
1228 // ostream &os The input stream to print the class data on
1229 // AliITSgeomMatrix &p This class
1238 //----------------------------------------------------------------------