New class for ITS coordiante transformations used by AliITSgeom nearly
authornilsen <nilsen@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 29 Aug 2000 20:16:50 +0000 (20:16 +0000)
committernilsen <nilsen@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 29 Aug 2000 20:16:50 +0000 (20:16 +0000)
exclusively.

ITS/AliITSgeomMatrix.cxx [new file with mode: 0644]
ITS/AliITSgeomMatrix.h [new file with mode: 0644]

diff --git a/ITS/AliITSgeomMatrix.cxx b/ITS/AliITSgeomMatrix.cxx
new file mode 100644 (file)
index 0000000..bf6fe3a
--- /dev/null
@@ -0,0 +1,663 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/*
+$Log$
+Revision 1.1.2.1  2000/06/04 16:32:31  Nilsen
+A new class to hold the matrix information needed by AliITSgeom.
+
+*/
+#include <iostream.h>
+#include <TMath.h>
+#include <TBuffer.h>
+
+#include "AliITSgeomMatrix.h"
+
+ClassImp(AliITSgeomMatrix)
+//----------------------------------------------------------------------
+AliITSgeomMatrix::AliITSgeomMatrix(){
+////////////////////////////////////////////////////////////////////////
+// The Default constructor for the AliITSgeomMatrix class. By Default
+// the angles of rotations are set to zero, meaning that the rotation
+// matrix is the unit matrix. The translation vector is also set to zero
+// as are the module id number. The detector type is set to -1 (an undefined
+// value). The full rotation matrix is kept so that the evaluation 
+// of a coordinate transformation can be done quickly and with a minimum
+// of CPU overhead. The basic coordinate systems are the ALICE global
+// coordinate system and the detector local coordinate system. In general
+// this structure is not limited to just those two coordinate systems.
+//Begin_Html
+/*
+<img src="picts/ITS/AliISgeomMatrix_L1.gif">
+*/
+//End_Html
+////////////////////////////////////////////////////////////////////////
+    Int_t i,j;
+
+    fDetectorIndex = -1; // a value never defined.
+    for(i=0;i<3;i++){
+       fid[i] = 0;
+       frot[i] = ftran[i] = 0.0;
+       for(j=0;j<3;j++) fm[i][j] = 0.0;
+    }// end for i
+    fm[0][0] = fm[1][1] = fm[2][2] = 1.0;
+}
+//----------------------------------------------------------------------
+AliITSgeomMatrix::AliITSgeomMatrix(const AliITSgeomMatrix &sourse){
+////////////////////////////////////////////////////////////////////////
+// The standard copy constructor. This make a full / proper copy of
+// this class.
+////////////////////////////////////////////////////////////////////////
+       Int_t i,j;
+
+       this->fDetectorIndex = sourse.fDetectorIndex;
+       for(i=0;i<3;i++){
+               this->fid[i]     = sourse.fid[i];
+               this->frot[i]    = sourse.frot[i];
+               this->ftran[i]   = sourse.ftran[i];
+               for(j=0;j<3;j++) this->fm[i][j] = sourse.fm[i][j];
+       }// end for i
+}
+//----------------------------------------------------------------------
+void AliITSgeomMatrix::operator=(const AliITSgeomMatrix &sourse){
+////////////////////////////////////////////////////////////////////////
+// The standard = operator. This make a full / proper copy of
+// this class.
+////////////////////////////////////////////////////////////////////////
+       Int_t i,j;
+
+       this->fDetectorIndex = sourse.fDetectorIndex;
+       for(i=0;i<3;i++){
+               this->fid[i]     = sourse.fid[i];
+               this->frot[i]    = sourse.frot[i];
+               this->ftran[i]   = sourse.ftran[i];
+               for(j=0;j<3;j++) this->fm[i][j] = sourse.fm[i][j];
+       }// end for i
+}
+//----------------------------------------------------------------------
+AliITSgeomMatrix::AliITSgeomMatrix(const Int_t idt,const Int_t id[3],
+                  const Double_t rot[3],const Double_t tran[3]){
+////////////////////////////////////////////////////////////////////////
+// This is a constructor for the AliITSgeomMatrix class. The matrix is
+// defined by 3 standard rotation angles [radians], and the translation
+// vector tran [cm]. In addition the layer, ladder, and detector number
+// for this particular module and the type of module must be given.
+// The full rotation matrix is kept so that the evaluation 
+// of a coordinate transformation can be done quickly and with a minimum
+// of CPU overhead. The basic coordinate systems are the ALICE global
+// coordinate system and the detector local coordinate system. In general
+// this structure is not limited to just those two coordinate systems.
+//Begin_Html
+/*
+<img src="picts/ITS/AliISgeomMatrix_L1.gif">
+*/
+//End_Html
+////////////////////////////////////////////////////////////////////////
+       Int_t i;
+
+       fDetectorIndex = idt; // a value never defined.
+       for(i=0;i<3;i++){
+               fid[i]   = id[i];
+               frot[i]  = rot[i];
+               ftran[i] = tran[i];
+       }// end for i
+       this->MatrixFromAngle();
+}
+//----------------------------------------------------------------------
+AliITSgeomMatrix::AliITSgeomMatrix(const Int_t idt, const Int_t id[3],
+                                   const Double_t matrix[3][3],
+                                   const Double_t tran[3]){
+////////////////////////////////////////////////////////////////////////
+// This is a constructor for the AliITSgeomMatrix class. The rotation matrix
+// is given as one of the inputs, and the translation vector tran [cm]. In 
+// addition the layer, ladder, and detector number for this particular
+// module and the type of module must be given. The full rotation matrix
+// is kept so that the evaluation of a coordinate transformation can be
+// done quickly and with a minimum of CPU overhead. The basic coordinate
+// systems are the ALICE global coordinate system and the detector local
+// coordinate system. In general this structure is not limited to just
+// those two coordinate systems.
+//Begin_Html
+/*
+<img src="picts/ITS/AliISgeomMatrix_L1.gif">
+*/
+//End_Html
+////////////////////////////////////////////////////////////////////////
+       Int_t i,j;
+
+       fDetectorIndex = idt; // a value never defined.
+       for(i=0;i<3;i++){
+               fid[i]   = id[i];
+               ftran[i] = tran[i];
+               for(j=0;j<3;j++) fm[i][j] = matrix[i][j];
+       }// end for i
+       this->AngleFromMatrix();
+}
+//----------------------------------------------------------------------
+void AliITSgeomMatrix::SixAnglesFromMatrix(Double_t *ang){
+////////////////////////////////////////////////////////////////////////
+// This function returns the 6 GEANT 3.21 rotation angles [degrees] in
+// the array ang which must be at least [6] long.
+////////////////////////////////////////////////////////////////////////
+    Double_t si,c=180./TMath::Pi();
+
+    ang[1] = TMath::ATan2(fm[0][1],fm[0][0]);
+    if(TMath::Cos(ang[1])!=0.0) si = fm[0][0]/TMath::Cos(ang[1]);
+    else si = fm[0][1]/TMath::Sin(ang[1]);
+    ang[0] = TMath::ATan2(si,fm[0][2]);
+
+    ang[3] = TMath::ATan2(fm[1][1],fm[1][0]);
+    if(TMath::Cos(ang[3])!=0.0) si = fm[1][0]/TMath::Cos(ang[3]);
+    else si = fm[1][1]/TMath::Sin(ang[3]);
+    ang[4] = TMath::ATan2(si,fm[1][2]);
+
+    ang[6] = TMath::ATan2(fm[2][1],fm[2][0]);
+    if(TMath::Cos(ang[6])!=0.0) si = fm[2][0]/TMath::Cos(ang[6]);
+    else si = fm[2][1]/TMath::Sin(ang[6]);
+    ang[5] = TMath::ATan2(si,fm[2][2]);
+
+    for(Int_t i=0;i<6;i++) {ang[i] *= c; if(ang[i]<0.0) ang[i] += 360.;}
+}
+//----------------------------------------------------------------------
+void AliITSgeomMatrix::MatrixFromSixAngles(const Double_t *ang){
+////////////////////////////////////////////////////////////////////////
+// Given the 6 GEANT 3.21 rotation angles [degree], this will compute and
+// set the rotations matrix and 3 standard rotation angles [radians].
+// These angles and rotation matrix are overwrite the existing values in
+// this class.
+////////////////////////////////////////////////////////////////////////
+    Int_t    i,j;
+    Double_t si,lr[9],c=TMath::Pi()/180.;
+
+    si    = TMath::Sin(c*ang[0]);
+    if(ang[0]== 90.0)                 si = +1.0;
+    if(ang[0]==270.0)                 si = -1.0;
+    if(ang[0]==  0.0||ang[0]==180.) si =  0.0;
+    lr[0] = si * TMath::Cos(c*ang[1]);
+    lr[1] = si * TMath::Sin(c*ang[1]);
+    lr[2] = TMath::Cos(c*ang[0]);
+    if(ang[0]== 90.0||ang[0]==270.) lr[2] =  0.0;
+    if(ang[0]== 0.0)                  lr[2] = +1.0;
+    if(ang[0]==180.0)                 lr[2] = -1.0;
+//
+    si    =  TMath::Sin(c*ang[2]);
+    if(ang[2]== 90.0)                 si = +1.0; 
+    if(ang[2]==270.0)                 si = -1.0;
+    if(ang[2]==  0.0||ang[2]==180.) si =  0.0;
+    lr[3] = si * TMath::Cos(c*ang[3]);
+    lr[4] = si * TMath::Sin(c*ang[3]);
+    lr[5] = TMath::Cos(c*ang[2]);
+    if(ang[2]== 90.0||ang[2]==270.) lr[5] =  0.0;
+    if(ang[2]==  0.0)                 lr[5] = +1.0;
+    if(ang[2]==180.0)                 lr[5] = -1.0;
+//
+    si    = TMath::Sin(c*ang[4]);
+    if(ang[4]== 90.0)                 si = +1.0;
+    if(ang[4]==270.0)                 si = -1.0;
+    if(ang[4]==  0.0||ang[4]==180.) si =  0.0;
+    lr[6] = si * TMath::Cos(c*ang[5]);
+    lr[7] = si * TMath::Sin(c*ang[5]);
+    lr[8] = TMath::Cos(c*ang[4]);
+    if(ang[4]== 90.0||ang[4]==270.0) lr[8] =  0.0;
+    if(ang[4]==  0.0)                  lr[8] = +1.0;
+    if(ang[4]==180.0)                  lr[8] = -1.0;
+    // Normalize these elements and fill matrix fm.
+    for(i=0;i<3;i++){// reuse si.
+       si = 0.0;
+       for(j=0;j<3;j++) si += lr[3*i+j]*lr[3*i+j];
+       si = TMath::Sqrt(1./si);
+       for(j=0;j<3;j++) fm[i][j] = si*lr[3*i+j];
+    } // end for i
+    this->AngleFromMatrix();
+}
+//----------------------------------------------------------------------
+AliITSgeomMatrix::AliITSgeomMatrix(const Double_t rotd[6]/*degrees*/,
+                                   const Int_t idt,const Int_t id[3],
+                                  const Double_t tran[3]){
+////////////////////////////////////////////////////////////////////////
+// This is a constructor for the AliITSgeomMatrix class. The matrix is
+// defined by the 6 GEANT 3.21 rotation angles [degrees], and the translation
+// vector tran [cm]. In addition the layer, ladder, and detector number
+// for this particular module and the type of module must be given.
+// The full rotation matrix is kept so that the evaluation 
+// of a coordinate transformation can be done quickly and with a minimum
+// of CPU overhead. The basic coordinate systems are the ALICE global
+// coordinate system and the detector local coordinate system. In general
+// this structure is not limited to just those two coordinate systems.
+//Begin_Html
+/*
+<img src="picts/ITS/AliISgeomMatrix_L1.gif">
+*/
+//End_Html
+////////////////////////////////////////////////////////////////////////
+    Int_t i;
+
+    fDetectorIndex = idt; // a value never defined.
+    for(i=0;i<3;i++){
+       fid[i]   = id[i];
+       ftran[i] = tran[i];
+    }// end for i
+    this->MatrixFromSixAngles(rotd);
+}
+//----------------------------------------------------------------------
+void AliITSgeomMatrix::AngleFromMatrix(){
+////////////////////////////////////////////////////////////////////////
+// Computes the angles from the rotation matrix up to a phase of 180 degrees.
+////////////////////////////////////////////////////////////////////////
+    Double_t rx,ry,rz;
+    // get angles from matrix up to a phase of 180 degrees.
+
+    rx = TMath::ATan2(fm[2][1],fm[2][2]);if(rx<0.0) rx += 2.0*TMath::Pi();
+    ry = TMath::ASin(fm[0][2]);          if(ry<0.0) ry += 2.0*TMath::Pi();
+    rz = TMath::ATan2(fm[1][1],fm[0][0]);if(rz<0.0) rz += 2.0*TMath::Pi();
+    frot[0] = rx;
+    frot[1] = ry;
+    frot[2] = rz;
+    return;
+}
+//----------------------------------------------------------------------
+void AliITSgeomMatrix::MatrixFromAngle(){
+////////////////////////////////////////////////////////////////////////
+// Computes the Rotation matrix from the angles [radians] kept in this
+// class.
+////////////////////////////////////////////////////////////////////////
+   Double_t sx,sy,sz,cx,cy,cz;
+
+   sx = TMath::Sin(frot[0]); cx = TMath::Cos(frot[0]);
+   sy = TMath::Sin(frot[1]); cy = TMath::Cos(frot[1]);
+   sz = TMath::Sin(frot[2]); cz = TMath::Cos(frot[2]);
+   fm[0][0] =  cz*cy;             // fr[0]
+   fm[0][1] = -cz*sy*sx - sz*cx;  // fr[1]
+   fm[0][2] = -cz*sy*cx + sz*sx;  // fr[2]
+   fm[1][0] =  sz*cy;             // fr[3]
+   fm[1][1] = -sz*sy*sx + cz*cx;  // fr[4]
+   fm[1][2] = -sz*sy*cx - cz*sx;  // fr[5]
+   fm[2][0] =  sy;                // fr[6]
+   fm[2][1] =  cy*sx;             // fr[7]
+   fm[2][2] =  cy*cx;             // fr[8]
+
+}
+//----------------------------------------------------------------------
+void AliITSgeomMatrix::GtoLPosition(const Double_t g0[3],Double_t l[3]){
+////////////////////////////////////////////////////////////////////////
+// Returns the local coordinates given the global coordinates [cm].
+////////////////////////////////////////////////////////////////////////
+       Int_t    i,j;
+       Double_t g[3];
+
+       for(i=0;i<3;i++) g[i] = g0[i] - ftran[i];
+       for(i=0;i<3;i++){
+               l[i] = 0.0;
+               for(j=0;j<3;j++) l[i] += fm[i][j]*g[j];
+               // g = R l + translation
+       } // end for i
+       return;
+}
+//----------------------------------------------------------------------
+void AliITSgeomMatrix::LtoGPosition(const Double_t l[3],Double_t g[3]){
+////////////////////////////////////////////////////////////////////////
+// Returns the global coordinates given the local coordinates [cm].
+////////////////////////////////////////////////////////////////////////
+       Int_t    i,j;
+
+       for(i=0;i<3;i++){
+               g[i] = 0.0;
+               for(j=0;j<3;j++) g[i] += fm[j][i]*l[j];
+               g[i] += ftran[i];
+               // g = R^t l + translation
+       } // end for i
+       return;
+}
+//----------------------------------------------------------------------
+void AliITSgeomMatrix::GtoLMomentum(const Double_t g[3],Double_t l[3]){
+////////////////////////////////////////////////////////////////////////
+// Returns the local coordinates of the momentum given the global
+// coordinates of the momentum. It transforms just like GtoLPosition
+// except that the translation vector is zero.
+////////////////////////////////////////////////////////////////////////
+       Int_t    i,j;
+
+       for(i=0;i<3;i++){
+               l[i] = 0.0;
+               for(j=0;j<3;j++) l[i] += fm[i][j]*g[j];
+               // g = R l
+       } // end for i
+       return;
+}
+//----------------------------------------------------------------------
+void AliITSgeomMatrix::LtoGMomentum(const Double_t l[3],Double_t g[3]){
+////////////////////////////////////////////////////////////////////////
+// Returns the Global coordinates of the momentum given the local
+// coordinates of the momentum. It transforms just like LtoGPosition
+// except that the translation vector is zero.
+////////////////////////////////////////////////////////////////////////
+       Int_t    i,j;
+
+       for(i=0;i<3;i++){
+               g[i] = 0.0;
+               for(j=0;j<3;j++) g[i] += fm[j][i]*l[j];
+               // g = R^t l
+       } // end for i
+       return;
+}
+//----------------------------------------------------------------------
+void AliITSgeomMatrix::GtoLPositionError(const Double_t g[3][3],
+                                               Double_t l[3][3]){
+////////////////////////////////////////////////////////////////////////
+// Given an Uncertainty matrix in Global coordinates it is rotated so that 
+// its representation in local coordinates can be returned. There is no
+// effect due to the translation vector or its uncertainty.
+////////////////////////////////////////////////////////////////////////
+       Int_t    i,j,k,m;
+
+       for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)for(m=0;m<3;m++)
+               l[i][m] = fm[j][i]*g[j][k]*fm[k][m];
+               // g = R^t l R
+       return;
+}
+//----------------------------------------------------------------------
+void AliITSgeomMatrix::LtoGPositionError(const Double_t l[3][3],
+                                               Double_t g[3][3]){
+////////////////////////////////////////////////////////////////////////
+// Given an Uncertainty matrix in Local coordinates it is rotated so that 
+// its representation in global coordinates can be returned. There is no
+// effect due to the translation vector or its uncertainty.
+////////////////////////////////////////////////////////////////////////
+       Int_t    i,j,k,m;
+
+       for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)for(m=0;m<3;m++)
+               g[i][m] = fm[i][j]*l[j][k]*fm[m][k];
+               // g = R l R^t
+       return;
+}
+//----------------------------------------------------------------------
+void AliITSgeomMatrix::GtoLPositionTracking(const Double_t g0[3],
+                                           Double_t l[3]){
+////////////////////////////////////////////////////////////////////////
+// A slightly different coordinate system is used when tracking.
+// This coordinate system is only relevant when the geometry represents
+// the cylindrical ALICE ITS geometry. For tracking the Z axis is left
+// alone but X -> -Y and Y -> X such that X always points out of the
+// ITS Cylinder for every layer including layer 1 (where the detector 
+// are mounted upside down).
+//Begin_Html
+/*
+<img src="picts/ITS/AliITSgeomMatrix_T1.gif">
+ */
+//End_Html
+////////////////////////////////////////////////////////////////////////
+    Double_t l0[3];
+
+    this->GtoLPosition(g0,l0);
+    if(fid[0]==1){ // for layer 1 the detector are flipped upside down
+                  // with respect to the others.
+       l[0] = +l0[1];
+       l[1] = -l0[0];
+       l[2] = +l0[2];
+    }else{
+       l[0] = -l0[1];
+       l[1] = +l0[0];
+       l[2] = +l0[2];
+    } // end if
+    return;
+}
+//----------------------------------------------------------------------
+void AliITSgeomMatrix::LtoGPositionTracking(const Double_t l[3],
+                                           Double_t g[3]){
+////////////////////////////////////////////////////////////////////////
+// A slightly different coordinate system is used when tracking.
+// This coordinate system is only relevant when the geometry represents
+// the cylindrical ALICE ITS geometry. For tracking the Z axis is left
+// alone but X -> -Y and Y -> X such that X always points out of the
+// ITS Cylinder for every layer including layer 1 (where the detector 
+// are mounted upside down).
+//Begin_Html
+/*
+<img src="picts/ITS/AliITSgeomMatrix_T1.gif">
+ */
+//End_Html
+////////////////////////////////////////////////////////////////////////
+    Double_t l0[3];
+
+    if(fid[0]==1){ // for layer 1 the detector are flipped upside down
+                  // with respect to the others.
+       l0[0] = -l[1];
+       l0[1] = +l[0];
+       l0[2] = +l[2];
+    }else{
+       l0[0] = +l[1];
+       l0[1] = -l[0];
+       l0[2] = +l[2];
+    } // end if
+    this->LtoGPosition(l0,g);
+    return;
+}
+//----------------------------------------------------------------------
+void AliITSgeomMatrix::GtoLMomentumTracking(const Double_t g[3],
+                                           Double_t l[3]){
+////////////////////////////////////////////////////////////////////////
+// A slightly different coordinate system is used when tracking.
+// This coordinate system is only relevant when the geometry represents
+// the cylindrical ALICE ITS geometry. For tracking the Z axis is left
+// alone but X -> -Y and Y -> X such that X always points out of the
+// ITS Cylinder for every layer including layer 1 (where the detector 
+// are mounted upside down).
+//Begin_Html
+/*
+<img src="picts/ITS/AliITSgeomMatrix_T1.gif">
+ */
+//End_Html
+////////////////////////////////////////////////////////////////////////
+    Double_t l0[3];
+
+    this->GtoLMomentum(g,l0);
+    if(fid[0]==1){ // for layer 1 the detector are flipped upside down
+                  // with respect to the others.
+       l[0] = +l0[1];
+       l[1] = -l0[0];
+       l[2] = +l0[2];
+    }else{
+       l[0] = -l0[1];
+       l[1] = +l0[0];
+       l[2] = +l0[2];
+    } // end if
+    return;
+       return;
+}
+//----------------------------------------------------------------------
+void AliITSgeomMatrix::LtoGMomentumTracking(const Double_t l[3],
+                                           Double_t g[3]){
+////////////////////////////////////////////////////////////////////////
+// A slightly different coordinate system is used when tracking.
+// This coordinate system is only relevant when the geometry represents
+// the cylindrical ALICE ITS geometry. For tracking the Z axis is left
+// alone but X -> -Y and Y -> X such that X always points out of the
+// ITS Cylinder for every layer including layer 1 (where the detector 
+// are mounted upside down).
+//Begin_Html
+/*
+<img src="picts/ITS/AliITSgeomMatrix_T1.gif">
+ */
+//End_Html
+////////////////////////////////////////////////////////////////////////
+    Double_t l0[3];
+
+    if(fid[0]==1){ // for layer 1 the detector are flipped upside down
+                  // with respect to the others.
+       l0[0] = -l[1];
+       l0[1] = +l[0];
+       l0[2] = +l[2];
+    }else{
+       l0[0] = +l[1];
+       l0[1] = -l[0];
+       l0[2] = +l[2];
+    } // end if
+    this->LtoGMomentum(l0,g);
+       return;
+}
+//----------------------------------------------------------------------
+void AliITSgeomMatrix::GtoLPositionErrorTracking(const Double_t g[3][3],
+                                                Double_t l[3][3]){
+////////////////////////////////////////////////////////////////////////
+// A slightly different coordinate system is used when tracking.
+// This coordinate system is only relevant when the geometry represents
+// the cylindrical ALICE ITS geometry. For tracking the Z axis is left
+// alone but X -> -Y and Y -> X such that X always points out of the
+// ITS Cylinder for every layer including layer 1 (where the detector 
+// are mounted upside down).
+//Begin_Html
+/*
+<img src="picts/ITS/AliITSgeomMatrix_T1.gif">
+ */
+//End_Html
+////////////////////////////////////////////////////////////////////////
+       Int_t    i,j,k,m;
+       Double_t Rt[3][3];
+       Double_t A0[3][3] = {{0.,+1.,0.},{-1.,0.,0.},{0.,0.,+1.}};
+       Double_t A1[3][3] = {{0.,-1.,0.},{+1.,0.,0.},{0.,0.,+1.}};
+
+       if(fid[0]==1) for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
+           Rt[i][k] = A0[i][j]*fm[j][k];
+       else for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
+           Rt[i][k] = A1[i][j]*fm[j][k];
+       for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)for(m=0;m<3;m++)
+               l[i][m] = Rt[j][i]*g[j][k]*Rt[k][m];
+               // g = R^t l R
+       return;
+}
+//----------------------------------------------------------------------
+void AliITSgeomMatrix::LtoGPositionErrorTracking(const Double_t l[3][3],
+                                                Double_t g[3][3]){
+////////////////////////////////////////////////////////////////////////
+// A slightly different coordinate system is used when tracking.
+// This coordinate system is only relevant when the geometry represents
+// the cylindrical ALICE ITS geometry. For tracking the Z axis is left
+// alone but X -> -Y and Y -> X such that X always points out of the
+// ITS Cylinder for every layer including layer 1 (where the detector 
+// are mounted upside down).
+//Begin_Html
+/*
+<img src="picts/ITS/AliITSgeomMatrix_T1.gif">
+ */
+//End_Html
+////////////////////////////////////////////////////////////////////////
+       Int_t    i,j,k,m;
+       Double_t Rt[3][3];
+       Double_t A0[3][3] = {{0.,+1.,0.},{-1.,0.,0.},{0.,0.,+1.}};
+       Double_t A1[3][3] = {{0.,-1.,0.},{+1.,0.,0.},{0.,0.,+1.}};
+
+       if(fid[0]==1) for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
+           Rt[i][k] = A0[i][j]*fm[j][k];
+       else for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)
+           Rt[i][k] = A1[i][j]*fm[j][k];
+       for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)for(m=0;m<3;m++)
+               g[i][m] = Rt[i][j]*l[j][k]*Rt[m][k];
+               // g = R l R^t
+       return;
+}
+//----------------------------------------------------------------------
+void AliITSgeomMatrix::PrintTitles(ostream *os){
+////////////////////////////////////////////////////////////////////////
+// Standard output format for this class but it includes variable
+// names and formatting that makes it easer to read.
+////////////////////////////////////////////////////////////////////////
+    Int_t i,j;
+
+    *os << "fDetectorIndex=" << fDetectorIndex << " fid[3]={";
+    for(i=0;i<3;i++) *os << fid[i]   << " ";
+    *os << "} frot[3]={";
+    for(i=0;i<3;i++) *os << frot[i]  << " ";
+    *os << "} ftran[3]={";
+    for(i=0;i<3;i++) *os << ftran[i] << " ";
+    *os << "} fm[3][3]={";
+    for(i=0;i<3;i++){for(j=0;j<3;j++){  *os << fm[i][j] << " ";} *os <<"}{";}
+    *os << "}" << endl;
+    return;
+}
+//----------------------------------------------------------------------
+void AliITSgeomMatrix::print(ostream *os){
+////////////////////////////////////////////////////////////////////////
+// Standard output format for this class.
+////////////////////////////////////////////////////////////////////////
+    Int_t i,j;
+
+    *os << fDetectorIndex << " ";
+    for(i=0;i<3;i++) *os << fid[i]   << " ";
+    for(i=0;i<3;i++) *os << frot[i]  << " ";
+    for(i=0;i<3;i++) *os << ftran[i] << " ";
+    for(i=0;i<3;i++)for(j=0;j<3;j++)  *os << fm[i][j] << " ";
+    *os << endl;
+    return;
+}
+//----------------------------------------------------------------------
+void AliITSgeomMatrix::read(istream *is){
+////////////////////////////////////////////////////////////////////////
+// Standard input format for this class.
+////////////////////////////////////////////////////////////////////////
+    Int_t i,j;
+
+    *is >> fDetectorIndex;
+    for(i=0;i<3;i++) *is >> fid[i];
+    for(i=0;i<3;i++) *is >> frot[i];
+    for(i=0;i<3;i++) *is >> ftran[i];
+    for(i=0;i<3;i++)for(j=0;j<3;j++)  *is >> fm[i][j];
+    return;
+}
+//----------------------------------------------------------------------
+ostream &operator<<(ostream &os,AliITSgeomMatrix &p){
+////////////////////////////////////////////////////////////////////////
+// Standard output streaming function.
+////////////////////////////////////////////////////////////////////////
+
+    p.print(&os);
+    return os;
+}
+//----------------------------------------------------------------------
+istream &operator>>(istream &is,AliITSgeomMatrix &r){
+////////////////////////////////////////////////////////////////////////
+// Standard input streaming function.
+////////////////////////////////////////////////////////////////////////
+
+    r.read(&is);
+    return is;
+}
+//----------------------------------------------------------------------
+void AliITSgeomMatrix::Streamer(TBuffer &R__b){
+////////////////////////////////////////////////////////////////////////
+// Stream an object of class AliITSgeomMatrix.
+////////////////////////////////////////////////////////////////////////
+
+   UInt_t R__s, R__c;
+   if (R__b.IsReading()) {
+      Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
+      if (R__v==1) {
+         R__b >> fDetectorIndex;
+         R__b.ReadStaticArray(fid);
+         R__b.ReadStaticArray(frot);
+         R__b.ReadStaticArray(ftran);
+         R__b.ReadStaticArray((double*)fm);
+         R__b.CheckByteCount(R__s, R__c, AliITSgeomMatrix::IsA());
+      } // end if R__v
+   } else { // R__b.IsWriting()
+      R__c = R__b.WriteVersion(AliITSgeomMatrix::IsA(), kTRUE);
+      R__b << fDetectorIndex;
+      R__b.WriteArray(fid, 3);
+      R__b.WriteArray(frot, 3);
+      R__b.WriteArray(ftran, 3);
+      R__b.WriteArray((double*)fm, 9);
+      R__b.SetByteCount(R__c, kTRUE);
+   } // end if R__b.IsReading()||IsWriting()
+}
+//______________________________________________________________________
diff --git a/ITS/AliITSgeomMatrix.h b/ITS/AliITSgeomMatrix.h
new file mode 100644 (file)
index 0000000..7043684
--- /dev/null
@@ -0,0 +1,85 @@
+#ifndef ALIITSGEOMMATRIX_H
+#define ALIITSGEOMMATRIX_H
+/* Copyright(c) 2000, ALICE Experiment at CERN, All rights reserved. *
+ * see cxx source for full Copyright notice.                         */
+/* $Id: */
+////////////////////////////////////////////////////////////////////////
+// ITS geometry manipulation routines on the module level. This class is
+// to replace the structure ITS_geom in the class AliITSgeom.
+// Created May 30 2000.
+// version 0.0.0
+// By Bjorn S. Nilsen
+////////////////////////////////////////////////////////////////////////
+
+class AliITSgeomMatrix{
+ public:
+       AliITSgeomMatrix(); // Default constructor
+       AliITSgeomMatrix(const Int_t idt,const Int_t id[3],
+                        const Double_t rot[3],const Double_t tran[3]);
+        AliITSgeomMatrix(const Int_t idt,const Int_t id[3],
+                        const Double_t matrix[3][3],const Double_t tran[3]);
+        AliITSgeomMatrix(const Double_t rotd[6]/*degrees Geant angles*/,
+                         const Int_t idt,const Int_t id[3],
+                         const Double_t tran[3]);
+       AliITSgeomMatrix(const AliITSgeomMatrix &source);
+       void operator=(const AliITSgeomMatrix &sourse); // copy
+       virtual ~AliITSgeomMatrix(){};
+       void print(ostream *os);
+       void PrintTitles(ostream *os);
+       void read(istream *is);
+
+       void SetAngles(const Double_t rot[3]){// [radians]
+              for(Int_t i=0;i<3;i++)frot[i] = rot[i];this->MatrixFromAngle();}
+       void SetTranslation(const Double_t tran[3]){
+                           for(Int_t i=0;i<3;i++) ftran[i] = tran[i];}
+       void SetMatrix(const Double_t matrix[3][3]){ for(Int_t i=0;i<3;i++)
+        for(Int_t j=0;j<3;j++) fm[i][j]=matrix[i][j];this->AngleFromMatrix();}
+       void SetDetectorIndex(const Int_t idt) {fDetectorIndex = idt;}
+       void SetIndex(const Int_t id[3]){
+                          for(Int_t i=0;i<3;i++) fid[i] = id[i];}
+       void GetAngles(Double_t rot[3]){// [radians]
+                          for(Int_t i=0;i<3;i++)  rot[i] = frot[i];}
+       void GetTranslation(Double_t tran[3]){
+                           for(Int_t i=0;i<3;i++) tran[i] = ftran[i];}
+       void GetMatrix(Double_t matrix[3][3]){for(Int_t i=0;i<3;i++)
+                        for(Int_t j=0;j<3;j++) matrix[i][j] = fm[i][j];}
+       Int_t GetDetectorIndex() {return fDetectorIndex;}
+       void  GetIndex(Int_t id[3]){for(Int_t i=0;i<3;i++) id[i] = fid[i];}
+       void  MatrixFromSixAngles(const Double_t *ang);
+       void  SixAnglesFromMatrix(Double_t *ang);
+
+       void GtoLPosition(const Double_t g[3],Double_t l[3]);
+       void LtoGPosition(const Double_t l[3],Double_t g[3]);
+       void GtoLMomentum(const Double_t g[3],Double_t l[3]);
+       void LtoGMomentum(const Double_t l[3],Double_t g[3]);
+       void GtoLPositionError(const Double_t g[3][3],Double_t l[3][3]);
+       void LtoGPositionError(const Double_t l[3][3],Double_t g[3][3]);
+       // Tracking Related Routines
+       void GtoLPositionTracking(const Double_t g[3],Double_t l[3]);
+       void LtoGPositionTracking(const Double_t l[3],Double_t g[3]);
+       void GtoLMomentumTracking(const Double_t g[3],Double_t l[3]);
+       void LtoGMomentumTracking(const Double_t l[3],Double_t g[3]);
+       void GtoLPositionErrorTracking(const Double_t g[3][3],
+                                      Double_t l[3][3]);
+       void LtoGPositionErrorTracking(const Double_t l[3][3],
+                                      Double_t g[3][3]);
+       Double_t Distance2(const Double_t t[3]){Double_t d=0.0,q;
+                 for(Int_t i=0;i<3;i++){q = t[i]-ftran[i]; d += q*q;}
+                 return d;}
+ private: // private functions
+       void MatrixFromAngle();
+       void AngleFromMatrix();
+ private: // Data members.
+       Int_t    fDetectorIndex; // Detector type index (like fShapeIndex was)
+       Int_t    fid[3];         // layer, ladder, detector numbers.
+       Double_t frot[3];        // vector of rotations about x,y,z [radians].
+       Double_t ftran[3];       // Translation vector of module x,y,z.
+       Double_t fm[3][3];       // Rotation matrix based on frot.
+
+       ClassDef(AliITSgeomMatrix,1) // Matrix class used by AliITSgeom.
+};
+// Input and output function for standard C++ input/output.
+ostream &operator<<(ostream &os,AliITSgeomMatrix &source);
+istream &operator>>(istream &os,AliITSgeomMatrix &source);
+
+#endif