]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - ITS/AliITSgeom.cxx
new paths
[u/mrichter/AliRoot.git] / ITS / AliITSgeom.cxx
index cb1ef8171047386c4dda0f5926e948e16c0b7450..5f725cd02c04f1b1e02d32487066232412e02fc9 100644 (file)
 
 /*
 $Log$
 
 /*
 $Log$
-Revision 1.4.4.10  2000/06/12 18:09:49  barbera
-fixed posible compilation errors on HP unix
+Revision 1.16  2001/02/08 23:57:00  nilsen
+Fixed up some informational printouts.
 
 
-Revision 1.4.4.9  2000/06/11 20:29:22  barbera
-Minore modifications.
+Revision 1.15  2001/02/07 20:23:21  nilsen
+Fixed bug with HP and no unget in iostream.h. Now using putback instead.
+Other changes and fixes also included.
 
 
-Revision 1.4.4.5  2000/03/04 23:42:39  nilsen
+Revision 1.14  2001/02/03 00:00:29  nilsen
+New version of AliITSgeom and related files. Now uses automatic streamers,
+set up for new formatted .det file which includes detector information.
+Additional smaller modifications are still to come.
+
+Revision 1.11  2000/10/02 16:32:35  barbera
+Forward declaration added
+
+Revision 1.4.4.15  2000/10/02 15:52:05  barbera
+Forward declaration added
+
+Revision 1.10  2000/09/05 14:25:50  nilsen
+Made fixes for HP compiler. All function parameter default values placed
+in .h file. Fixed the usual problem with HP comilers and the "for(Int_t i..."
+business. Replaced casting (Double_t [3][3]) to (Double_t (*)[3]) for HP.
+Lastly removed all "const" before function parameters which were 2 dim. arrays,
+because on HP root generates some strange code (?). Thanks Peter for the
+changes.
+
+Revision 1.9  2000/08/29 20:19:03  nilsen
+Removed dependancy on structure AliITSeomS and replaced it with class
+AliITSgeomMatrix. Added many new functions with many new arguments. Most
+in the form of in line functions for speed.
+
+Revision 1.4.4.6  2000/06/04 16:33:32  Nilsen
+A restructured AliITSgeom class. Now used AliITSgeomMatrix.
+
+Revision 1.4.4.5  2000/03/04 23:42:39  Nilsen
 Updated the comments/documentations and improved the maintainability of the
 code.
 
 Updated the comments/documentations and improved the maintainability of the
 code.
 
-Revision 1.4.4.4  2000/03/02 21:27:07  nilsen
+Revision 1.4.4.4  2000/03/02 21:27:07  Nilsen
 Added two functions, SetByAngles and SetTrans.
 
 Added two functions, SetByAngles and SetTrans.
 
-Revision 1.4.4.3  2000/01/23 03:09:10  nilsen
+Revision 1.4.4.3  2000/01/23 03:09:10  Nilsen
 // fixed compiler warnings for new function LtLErrorMatrix(...)
 
 // fixed compiler warnings for new function LtLErrorMatrix(...)
 
-Revision 1.4.4.2  2000/01/19 23:18:20  nilsen
+Revision 1.4.4.2  2000/01/19 23:18:20  Nilsen
 Added transformations of Error matrix to AliITSgeom and fixed some typos
 in AliITS.h and AliITShitIndex.h
 
 Added transformations of Error matrix to AliITSgeom and fixed some typos
 in AliITS.h and AliITShitIndex.h
 
-Revision 1.4.4.1  2000/01/12 19:03:32  nilsen
+Revision 1.4.4.1  2000/01/12 19:03:32  Nilsen
 This is the version of the files after the merging done in December 1999.
 See the ReadMe110100.txt file for details
 
 This is the version of the files after the merging done in December 1999.
 See the ReadMe110100.txt file for details
 
@@ -64,59 +92,20 @@ Introduction of the Copyright and cvs Log
 
 
 ////////////////////////////////////////////////////////////////////////
 
 
 ////////////////////////////////////////////////////////////////////////
-// The structure AliITSgeomS:
-//     The structure AliITSgeomS has been defined to hold all of the
-// information necessary to do the coordinate transformations for one
-// detector between the ALICE Cartesian global and the detector local
-// coordinate systems. The rotations are implemented in the following
-// order, Rz*Ry*Rx*(Vglobal-Vtrans)=Vlocal (in matrix notation). 
-// In addition it contains an index to the TObjArray containing all of
-// the information about the shape of the active detector volume, and
-// any other useful detector parameters. See the definition of *fShape
-// below and the classes AliITSgeomSPD, AliITSgeomSDD, and AliITSgeomSSD
-// for a full description. This structure is not available outside of 
-// these routines.
-//
-// Int_t fShapeIndex
-//     The index to the array of detector shape information. In this way
-// only an index is needed to be stored and not all of the shape
-// information. This saves much space since most, if not all, of the
-// detectors of a give type have the same shape information and are only
-// placed in a different spot in the ALICE/ITS detector.
-//
-// Float_t fx0,fy0,fz0
-//     The Cartesian translation vector used to define part of the
-// coordinate transformation. The units of the translation are kept
-// in the Monte Carlo distance units, usually cm.
-//
-// Float_t frx,fry,frz
-//     The three rotation angles that define the rotation matrix. The
-// angles are, frx the rotation about the x axis. fry the rotation about
-// the "new" or "rotated" y axis. frz the rotation about the "new" or
-// "rotated" z axis. These angles, although redundant with the rotation
-// matrix fr, are kept for speed. This allows for their retrieval without
-// having to compute them each and every time. The angles are kept in
-// radians
-//
-// Float_t fr[9]
-//     The 3x3 rotation matrix defined by the angles frx, fry, and frz,
-// for the Global to Local transformation is
-//    |fr[0] fr[1] fr[2]| | cos(frz)  sin(frz) 0| | cos(fry) 0  sin(fry)|
-// fr=|fr[3] fr[4] fr[4]|=|-sin(frz)  cos(frz) 0|*|   0      1    0     |
-//    |fr[6] fr[7] fr[8]| |   0         0      1| |-sin(fry) 0  cos(fry)|
-//
-//    |1    0        0     |
-//   *|0  cos(frx) sin(frx)|
-//    |0 -sin(frx) cos(frx)|
-//
-// Even though this information is redundant with the three rotation
-// angles, because this transformation matrix can be used so much it is
-// kept to speed things up a lot. The coordinate system used is Cartesian.
-//
 //     The local coordinate system by, default, is show in the following
 // figures. Also shown are the ladder numbering scheme.
 //Begin_Html
 /*
 //     The local coordinate system by, default, is show in the following
 // figures. Also shown are the ladder numbering scheme.
 //Begin_Html
 /*
+<img src="picts/ITS/AliITSgeomMatrix_L1.gif">
+</pre>
+<br clear=left>
+<font size=+2 color=blue>
+<p>This shows the relative geometry differences between the ALICE Global
+coordinate system and the local detector coordinate system.
+</font>
+<pre>
+
+<pre>
 <img src="picts/ITS/its1+2_convention_front_5.gif">
 </pre>
 <br clear=left>
 <img src="picts/ITS/its1+2_convention_front_5.gif">
 </pre>
 <br clear=left>
@@ -148,7 +137,7 @@ pixel coordinate system.
 <pre>
 */
 //End_Html
 <pre>
 */
 //End_Html
-
+//
 ////////////////////////////////////////////////////////////////////////
 
 ////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////
 
 ////////////////////////////////////////////////////////////////////////
@@ -173,14 +162,11 @@ pixel coordinate system.
 // active detector volumes for each ladder. This array is typically
 // created and filled by the AliITSgeom creator function.
 //
 // active detector volumes for each ladder. This array is typically
 // created and filled by the AliITSgeom creator function.
 //
-// AliITSgeomS **fGm
-//     A pointer to an array of pointers pointing to the AliITSgeomS
-// structure containing the coordinate transformation information.
-// The AliITSgeomS structure corresponding to layer=lay, ladder=lad,
-// and detector=det is gotten by fGm[lay-1][(fNlad[lay-1]*(lad-1)+det-1)].
-// In this way a lot of space is saved over trying to keep a three
-// dimensional array fNlayersXmax(fNlad)Xmax(fNdet), since the number
-// of detectors typically increases with layer number.
+// AliITSgeomMatrix *fGm
+//     A pointer to an array of AliITSgeomMatrix classes. One element 
+// per module (detector) in the ITS. AliITSgeomMatrix basicly contains
+// all of the necessary information about the detector and it's coordinate
+// transformations.
 //
 // TObjArray *fShape
 //     A pointer to an array of TObjects containing the detailed shape
 //
 // TObjArray *fShape
 //     A pointer to an array of TObjects containing the detailed shape
@@ -193,97 +179,25 @@ pixel coordinate system.
 // be easy to have the display program display the correct active
 // ITS volumes. See the example classes AliITSgeomSPD, AliITSgeomSDD,
 // and AliITSgeomSSD for a more detailed example.
 // be easy to have the display program display the correct active
 // ITS volumes. See the example classes AliITSgeomSPD, AliITSgeomSDD,
 // and AliITSgeomSSD for a more detailed example.
-//
-// Inlined Member Functions:
-//
-// Int_t GetNdetectors(Int_t layer)
-//     This function returns the number of detectors/ladder for a give 
-// layer. In particular it returns fNdet[layer-1].
-//
-// Int_t GetNladders(Int_t layer)
-//     This function returns the number of ladders for a give layer. In
-// particular it returns fNlad[layer-1].
-//
-// Int_t GetNlayers()
-//     This function returns the number of layers defined in the ITS
-// geometry. In particular it returns fNlayers.
-//
-// GetAngles(Int_t layer,Int_t ladder,Int_t detector,
-//           Float_t &rx, Float_t &ry, Float_t &rz)
-//     This function returns the rotation angles for a give detector on
-// a give ladder in a give layer in the three floating point variables
-// provided. rx = frx, fy = fry, rz = frz. The angles are in radians
-//
-// GetTrans(Int_t layer,Int_t ladder,Int_t detector,
-//          Float_t &x, Float_t &y, Float_t &z)
-//     This function returns the Cartesian translation for a give
-// detector on a give ladder in a give layer in the three floating
-// point variables provided. x = fx0, y = fy0, z = fz0. The units are
-// those of the Monte Carlo, generally cm.
-//
-// SetTrans(Int_t layer,Int_t ladder,Int_t detector,
-//          Float_t x, Float_t y, Float_t z)
-//     This function sets a new translation vector, given by the three
-// variables x, y, and z, for the Cartesian coordinate transformation
-// for the detector defined by layer, ladder and detector.
-//
-// Int_t IsVersion()
-//     This function returns the version number of this AliITSgeom
-// class.
-//
-// AddShape(TObject *shape)
-//     This function adds one more shape element to the TObjArray
-// fShape. It is primarily used in the constructor functions of the
-// AliITSgeom class. The pointer *shape can be the pointer to any
-// class that is derived from TObject (this is true for nearly every
-// ROOT class). This does not appear to be working properly at this time.
-//
-// Int_t GetStartSPD()
-//     This functions returns the starting module index number for the
-// silicon pixels detectors (SPD). Typically this is zero. To loop over all
-// of the pixel detectors do: for(i=GetStartSPD();i<=GetLastSPD();i++)
-//
-// Int_t GetLastSPD()
-//     This functions returns the last module index number for the
-// silicon pixels detectors (SPD). To loop over all of the pixel detectors 
-// do: for(i=GetStartSPD();i<=GetLastSPD();i++)
-//
-// Int_t GetStartSDD()
-//     This functions returns the starting module index number for the
-// silicon drift detectors (SDD). To loop over all of the drift detectors 
-// do: for(i=GetStartSDD();i<=GetLastSDD();i++)
-//
-// Int_t GetLastSDD()
-//     This functions returns the last module index number for the
-// silicon drift detectors (SDD). To loop over all of the drift detectors 
-// do: for(i=GetStartSDD();i<=GetLastSDD();i++)
-//
-// Int_t GetStartSSD()
-//     This functions returns the starting module index number for the
-// silicon strip detectors (SSD). To loop over all of the strip detectors 
-// do: for(i=GetStartSSD();i<=GetLastSSD();i++)
-//
-// Int_t GetStartSSD()
-//     This functions returns the last module index number for the
-// silicon strip detectors (SSD). To loop over all of the strip detectors 
-// do: for(i=GetStartSSD();i<=GetLastSSD();i++)
-//
-// TObject *GetShape(Int_t lay,Int_t lad,Int_t det)
-//     This functions returns the shape object AliITSgeomSPD, AliITSgeomSDD,
-// or AliITSgeomSSD for that particular module designated by lay, lad, and
-// detector. In principle there can be additional shape objects. In this
-// way a minimum of shape objects are created since one AliITSgeomS?D shape
-// object is used for all modules of that type.
 ////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////
-
 #include <iostream.h>
 #include <fstream.h>
 #include <iomanip.h>
 #include <iostream.h>
 #include <fstream.h>
 #include <iomanip.h>
+#include <stdlib.h>
 #include <stdio.h>
 #include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <TSystem.h>
+#include <TVector.h>
+#include <TObject.h>
+#include <TRandom.h>
+
 #include "AliITSgeom.h"
 #include "AliITSgeom.h"
-#include "AliITSgeomSPD300.h"
-#include "AliITSgeomSPD425.h"
-#include "TRandom.h"
+//#include "AliITSgeomMatrix.h" // include in AliITSgeom.h
+#include "AliITSgeomSPD.h"
+#include "AliITSgeomSDD.h"
+#include "AliITSgeomSSD.h"
 
 ClassImp(AliITSgeom)
 
 
 ClassImp(AliITSgeom)
 
@@ -293,16 +207,62 @@ AliITSgeom::AliITSgeom(){
 //     The default constructor for the AliITSgeom class. It, by default,
 // sets fNlayers to zero and zeros all pointers.
 ////////////////////////////////////////////////////////////////////////
 //     The default constructor for the AliITSgeom class. It, by default,
 // sets fNlayers to zero and zeros all pointers.
 ////////////////////////////////////////////////////////////////////////
-  // Default constructor.
-  // Do not allocate anything zero everything
-   fNlayers = 0;
-   fNlad    = 0;
-   fNdet    = 0;
-   fGm       = 0;
-   fShape   = 0;
-   return;
+    // Default constructor.
+    // Do not allocate anything zero everything
+    fTrans   = 0; // standard GEANT global/local coordinate system.
+    fNlayers = 0;
+    fNlad    = 0;
+    fNdet    = 0;
+    fGm      = 0;
+    fShape   = 0;
+    strcpy(fVersion,"test");
+    return;
 }
 }
+//_____________________________________________________________________
+AliITSgeom::AliITSgeom(Int_t itype,Int_t nlayers,Int_t *nlads,Int_t *ndets,
+                      Int_t mods){
+////////////////////////////////////////////////////////////////////////
+//     A simple constructor to set basic geometry class variables
+// Input:
+//      itype  the type of transofmation kept.
+//             0 => Standard Geant
+//         bit 1 => ITS tracking
+//         bit 2 => A change in the coordiante system has been made.
+//         others are still to be defined as needed.
+//      nlayers The number of ITS layers also set the size of the arrays
+//      *nlads  an array of the number of ladders for each layer
+//      *ndets  an array of the number of detectors per ladder for each layer.
+////////////////////////////////////////////////////////////////////////
+    Int_t i;
 
 
+    fTrans    = itype;
+    fNlayers  = nlayers;
+    fNlad     = new Int_t[nlayers];
+    fNdet     = new Int_t[nlayers];
+    for(i=0;i<nlayers;i++){fNlad[i] = nlads[i];fNdet[i] = ndets[i];}
+    fNmodules = mods;
+    fGm       = new TObjArray(mods,0);
+    fShape    = new TObjArray(5); // default value
+    for(i=0;i<5;i++) fShape->AddAt(0,i);
+    strcpy(fVersion,"test");
+    return;
+}
+//______________________________________________________________________
+void AliITSgeom::CreatMatrix(Int_t mod,Int_t lay,Int_t lad,Int_t det,
+                            AliITSDetector idet,Double_t tran[3],
+                            Double_t rot[10]){
+    Int_t id[3];
+    Double_t r[3][3] = {{1.0,0.0,0.0},{0.0,1.0,0.0},{0.0,0.0,1.0}};
+
+    if(fGm->At(mod)!=0) delete fGm->At(mod);
+    id[0] = lay; id[1] = lad; id[2] = det;
+    if(rot[9]!=0.0) { // null rotation
+       r[0][0] = rot[0]; r[0][1] = rot[1]; r[0][2] = rot[2];
+       r[1][0] = rot[3]; r[1][1] = rot[4]; r[1][2] = rot[5];
+       r[2][0] = rot[6]; r[2][1] = rot[7]; r[2][2] = rot[8];
+    } // end if
+    fGm->AddAt(new AliITSgeomMatrix(idet,id,r,tran),mod);
+}
 //_____________________________________________________________________
 AliITSgeom::~AliITSgeom(){
 ////////////////////////////////////////////////////////////////////////
 //_____________________________________________________________________
 AliITSgeom::~AliITSgeom(){
 ////////////////////////////////////////////////////////////////////////
@@ -314,145 +274,305 @@ AliITSgeom::~AliITSgeom(){
 ////////////////////////////////////////////////////////////////////////
   // Default destructor.
   // if arrays exist delete them. Then set everything to zero.
 ////////////////////////////////////////////////////////////////////////
   // Default destructor.
   // if arrays exist delete them. Then set everything to zero.
-   Int_t i;
    if(fGm!=0){
    if(fGm!=0){
-      for(i=0;i<fNlayers;i++) delete[] fGm[i];
-      delete[] fGm;
+      for(Int_t i=0;i<fNlayers;i++) delete fGm->At(i);
+      delete fGm;
    } // end if fGm!=0
    if(fNlad!=0) delete[] fNlad;
    if(fNdet!=0) delete[] fNdet;
    fNlayers = 0;
    fNlad    = 0;
    fNdet    = 0;
    } // end if fGm!=0
    if(fNlad!=0) delete[] fNlad;
    if(fNdet!=0) delete[] fNdet;
    fNlayers = 0;
    fNlad    = 0;
    fNdet    = 0;
-   fGm       = 0;
+   fGm      = 0;
    return;
 }
    return;
 }
+//______________________________________________________________________
+void AliITSgeom::ReadNewFile(const char *filename){
+    Int_t ncmd=9;
+    const char *cmda[]={"Version"        ,"fTrans"  ,"fNmodules",
+                       "fNlayers"       ,"fNladers","fNdetectors",
+                       "fNDetectorTypes","fShape"  ,"Matrix"};
+    Int_t i,j,lNdetTypes,ldet;
+    char cmd[20],c;
+    AliITSgeomSPD *spd;
+    AliITSgeomSDD *sdd;
+    AliITSgeomSSD *ssd;
+    AliITSgeomMatrix *m;
+    ifstream *fp;
+    char *filtmp;
+
+    filtmp = gSystem->ExpandPathName(filename);
+    cout << "AliITSgeom, Reading New .det file " << filtmp << endl;
+    fp = new ifstream(filtmp,ios::in);  // open file to write
+    while(fp->get(c)!=NULL){ // for ever loop
+       if(c==' ') continue; // remove blanks
+       if(c=='\n') continue;
+       if(c=='#' || c=='!'){for(;fp->get(c)!=NULL,c!='\n';); continue;}
+       if(c=='/'){
+           fp->get(c);{
+               if(c=='/'){for(;fp->get(c)!=NULL,c!='\n';);continue;}
+               if(c=='*'){
+               NotYet:
+                   for(;fp->get(c)!=NULL,c!='*';);
+                   fp->get(c);{
+                       if(c=='/') continue;
+                       goto NotYet;
+                   } //
+               } // end if c=='*'
+           } // end if second /
+       } // end if first /
+       fp->putback(c);
+//     fp->unget();
+       *fp >> cmd;
+       for(i=0;i<ncmd;i++) if(strcmp(cmd,cmda[i])==0) break;
+       switch (i){
+       case 0:   // Version
+           *fp >> fVersion;
+           break;
+       case 1:  // fTrans
+           *fp >> fTrans;
+           break;
+       case 2:  // fNModules
+           *fp >> fNmodules;
+           if(fGm!=0){
+               for(j=0;j<fGm->GetEntriesFast();j++) delete fGm->At(j);
+               delete fGm;
+           } // end if
+           fGm = new TObjArray(fNmodules,0);
+           break;
+       case 3:  // fNlayers
+           *fp >> fNlayers;
+           if(fNlad!=0) delete fNlad;
+           if(fNdet!=0) delete fNdet;
+           fNlad = new Int_t[fNlayers];
+           fNdet = new Int_t[fNlayers];
+           break;
+       case 4:  // fNladers
+           for(j=0;j<fNlayers;j++) *fp >> fNlad[j];
+           break;
+       case 5:  // fNdetectors
+           for(j=0;j<fNlayers;j++) *fp >> fNdet[j];
+           break;
+       case 6:  // fNDetectorTypes
+           *fp >> lNdetTypes;
+           if(fShape!=0){
+               for(j=0;j<fShape->GetEntriesFast();j++) delete fShape->At(j);
+               delete fShape;
+           } // end if
+           fShape = new TObjArray(lNdetTypes,0);
+           break;
+       case 7:  // fShape
+           *fp >> ldet;
+           if(fShape==0) fShape = new TObjArray(5,0);
+           switch (ldet){
+           case kSPD :
+               ReSetShape(ldet,(TObject*) new AliITSgeomSPD());
+               spd = (AliITSgeomSPD*) (fShape->At(ldet));
+               *fp >> *spd;
+               spd = 0;
+               break;
+           case kSDD :
+               ReSetShape(ldet,(TObject*) new AliITSgeomSDD());
+               sdd = (AliITSgeomSDD*) (fShape->At(ldet));
+               *fp >> *sdd;
+               sdd = 0;
+               break;
+           case kSSD : case kSSDp :
+               ReSetShape(ldet,(TObject*) new AliITSgeomSSD());
+               ssd = (AliITSgeomSSD*) (fShape->At(ldet));
+               *fp >> *ssd;
+               ssd = 0;
+               break;
+           default:
+               Error("ReadNewFile","Unknown fShape type number=%d c=%c",ldet,c);
+               for(;fp->get(c)==NULL,c!='\n';); // skip to end of line.
+               break;
+           } // end switch
+           break;
+       case 8:  // Matrix
+           *fp >> ldet;
+           if(fGm==0) fGm = new TObjArray(2270,0);
+           if(fGm->At(ldet)!=0) delete (fGm->At(ldet));
+           fGm->AddAt((TObject*)new AliITSgeomMatrix(),ldet);
+           m = (AliITSgeomMatrix*) fGm->At(ldet);
+           *fp >> *m;
+           m = 0;
+           break;
+       default:
+           Error("ReadNewFile","Data line i=%d c=%c",i,c);
+           for(;fp->get(c)==NULL,c!='\n';); // skip this line
+           break;
+       } // end switch i
+    } // end while
+    delete fp;
 
 
+    return;
+}
+//______________________________________________________________________
+void AliITSgeom::WriteNewFile(const char *filename){
+// Writes AliITSgeom, AliITSgeomMatrix, and the defined AliITSgeomS*D classes
+// to a file in a format that is more readable and commentable.
+    ofstream *fp;
+    Int_t i;
+    char *filtmp;
+
+    filtmp = gSystem->ExpandPathName(filename);
+    cout << "AliITSgeom, Writing New .det file " << filtmp << endl;
+    fp = new ofstream(filtmp,ios::out);  // open file to write
+    *fp << "//Comment lines begin with two //, one #, or one !" << endl;
+    *fp << "#Blank lines are skipped including /* and */ sections." << endl;
+    *fp << "!and, in principle the order of the lines is not important" <<endl;
+    *fp << "/* In AliITSgeom.h are defined an enumerated type called" << endl;
+    *fp << " AliITSDetectors These are kSPD=" << (Int_t) kSPD ;
+    *fp << ", kSDD=" << (Int_t) kSDD << ", kSSD=" << (Int_t) kSSD;
+    *fp << ", kSSDp=" << (Int_t) kSSDp << ", and kSDDp=" << (Int_t) kSDDp;
+    *fp << "*/" << endl;
+    *fp << "Version " << fVersion << endl;//This should be consistant with the
+                                           // geometry version.
+    *fp << "fTrans " << fTrans << endl;
+    *fp << "fNmodules " << fNmodules << endl;
+    *fp << "fNlayers " << fNlayers << endl;
+    *fp << "fNladers ";
+    for(i=0;i<fNlayers;i++) *fp << fNlad[i] << " ";
+    *fp << endl;
+    *fp << "fNdetectors ";
+    for(i=0;i<fNlayers;i++) *fp << fNdet[i] << " ";
+    *fp << endl;
+    *fp << "fNDetectorTypes " << fShape->GetEntriesFast() << endl;
+    for(i=0;i<fShape->GetEntriesFast();i++){
+       if(!IsShapeDefined(i)) continue; // only print out used shapes.
+       switch (i){
+       case kSPD :
+           *fp << "fShape " << (Int_t) kSPD << " ";
+           *fp << *((AliITSgeomSPD*)(fShape->At(i)));
+           break;
+       case kSDD :
+           *fp << "fShape " << (Int_t) kSDD << " ";
+           *fp << *((AliITSgeomSDD*)(fShape->At(i)));
+           break;
+       case kSSD : case kSSDp :
+           *fp << "fShape " << i << " ";
+           *fp << *((AliITSgeomSSD*)(fShape->At(i)));
+           break;
+       default:
+           Error("AliITSgeom::WriteNewFile","Unknown Shape value");
+       } // end switch (i)
+    } // end for i
+    for(i=0;i<fNmodules;i++){
+       *fp << "Matrix " << i << " ";
+       *fp << *GetGeomMatrix(i);
+    } // end for i
+    *fp << "//End of File" << endl;;
+
+    delete fp;
+    return;
+}
 //_____________________________________________________________________
 AliITSgeom::AliITSgeom(const char *filename){
 ////////////////////////////////////////////////////////////////////////
 //     The constructor for the AliITSgeom class. All of the data to fill
 // this structure is read in from the file given my the input filename.
 ////////////////////////////////////////////////////////////////////////
 //_____________________________________________________________________
 AliITSgeom::AliITSgeom(const char *filename){
 ////////////////////////////////////////////////////////////////////////
 //     The constructor for the AliITSgeom class. All of the data to fill
 // this structure is read in from the file given my the input filename.
 ////////////////////////////////////////////////////////////////////////
-   FILE     *pf;
-   Int_t    i;
-   AliITSgeomS *g;
+   FILE     *pf=0;
+   Int_t    i,lm=0,id[3];
    Int_t    l,a,d;
    Float_t  x,y,z,o,p,q,r,s,t;
    Int_t    l,a,d;
    Float_t  x,y,z,o,p,q,r,s,t;
-   Double_t oor,pr,qr,rr,sr,tr; // Radians
-   Double_t lr[9];
-   Double_t si; // sin(angle)
-   Double_t pi = TMath::Pi(), byPI = pi/180.;
+   Double_t rot6[6],tran[3];
+   char     buf[200],*buff=0; // input character buffer;
+   char *filtmp;
 
 
-   pf = fopen(filename,"r");
+   filtmp = gSystem->ExpandPathName(filename);
+   cout << "AliITSgeom reading old .det file " << filtmp << endl;
+   fShape = 0;
+   strcpy(fVersion,"DefauleV5");
+   pf = fopen(filtmp,"r");
 
    fNlayers = 6; // set default number of ladders
 
    fNlayers = 6; // set default number of ladders
+TryAgain:
    fNlad    = new Int_t[fNlayers];
    fNdet    = new Int_t[fNlayers];
    fNlad    = new Int_t[fNlayers];
    fNdet    = new Int_t[fNlayers];
+   fNmodules = 0;
    // find the number of ladders and detectors in this geometry.
    for(i=0;i<fNlayers;i++){fNlad[i]=fNdet[i]=0;} // zero out arrays
    // find the number of ladders and detectors in this geometry.
    for(i=0;i<fNlayers;i++){fNlad[i]=fNdet[i]=0;} // zero out arrays
-   for(;;){ // for ever loop
-      i = fscanf(pf,"%d %d %d %f %f %f %f %f %f %f %f %f",
-                     &l,&a,&d,&x,&y,&z,&o,&p,&q,&r,&s,&t);
-      if(i==EOF) break;
+   while(fgets(buf,200,pf)!=NULL){ // for ever loop
+      for(i=0;i<200;i++)if(buf[i]!=' '){ // remove blank spaces.
+           buff = &(buf[i]);
+           break;
+      } // end for i
+      // remove blank lines and comments.
+      if(buff[0]=='\n'||buff[0]=='#'||buff[0]=='!'||
+         (buff[0]=='/'&&buff[1]=='/')) continue;
+      if(isalpha(buff[0])) { // must be the new file formated file.
+            fclose(pf);
+            delete[] fNlad;delete[] fNdet;
+            ReadNewFile(filename);
+            return;
+      } // end if isalpha(buff[0])
+      sscanf(buff,"%d %d %d %f %f %f %f %f %f %f %f %f",
+                  &l,&a,&d,&x,&y,&z,&o,&p,&q,&r,&s,&t);
+      if(l>lm) lm = l;
       if(l<1 || l>fNlayers) {
       if(l<1 || l>fNlayers) {
-         printf("error in file %s layer=%d min is 1 max is %d/n",
+         printf("error in file %s layer=%d min. is 1 max is %d\n",
                  filename,l,fNlayers);
          continue;
       }// end if l
                  filename,l,fNlayers);
          continue;
       }// end if l
-      if(fNlad[l-1]<a) fNlad[l-1] = a;
-      if(fNdet[l-1]<d) fNdet[l-1] = d;
-   } // end for ever loop
+      fNmodules++;
+      if(l<=fNlayers&&fNlad[l-1]<a) fNlad[l-1] = a;
+      if(l<=fNlayers&&fNdet[l-1]<d) fNdet[l-1] = d;
+   } // end while ever loop
+   if(lm>fNlayers){
+       delete[] fNlad;
+       delete[] fNdet;
+       fNlayers = lm;
+       goto TryAgain;
+   } // end if lm>fNlayers
    // counted the number of ladders and detectors now allocate space.
    // counted the number of ladders and detectors now allocate space.
-   fGm = new AliITSgeomS* [fNlayers];
-   for(i=0;i<fNlayers;i++){
-      fGm[i] = 0;
-      l = fNlad[i]*fNdet[i];
-      fGm[i] = new AliITSgeomS[l]; // allocate space for transforms
-   } // end for i
+   fGm = new TObjArray(fNmodules,0);
 
    // Set up Shapes for a default configuration of 6 layers.
 
    // Set up Shapes for a default configuration of 6 layers.
-   fShape = new TObjArray(3);
-   AddShape((TObject *) new AliITSgeomSPD300());  // shape 0
-   AddShape((TObject *) new AliITSgeomSDD());  // shape 1
-   AddShape((TObject *) new AliITSgeomSSD());  // shape 2
-
+   fTrans   = 0; // standard GEANT global/local coordinate system.
    // prepare to read in transforms
    // prepare to read in transforms
+   lm = 0; // reuse lm as counter of modules.
    rewind(pf); // start over reading file
    rewind(pf); // start over reading file
-   for(;;){ // for ever loop
-      i = fscanf(pf,"%d %d %d %f %f %f %f %f %f %f %f %f",
-                     &l,&a,&d,&x,&y,&z,&o,&p,&q,&r,&s,&t);
-      if(i==EOF) break;
+   while(fgets(buf,200,pf)!=NULL){ // for ever loop
+      for(i=0;i<200;i++)if(buf[i]!=' '){ // remove blank spaces.
+           buff = &(buf[i]);
+           break;
+      } // end for i
+      // remove blank lines and comments.
+      if(buff[0]=='\n'||buff[0]=='#'||buff[0]=='!'||
+        (buff[0]=='/'&&buff[1]=='/')) continue;
+      x = y = z = o = p = q = r = s = t = 0.0;
+      sscanf(buff,"%d %d %d %f %f %f %f %f %f %f %f %f",
+                  &l,&a,&d,&x,&y,&z,&o,&p,&q,&r,&s,&t);
       if(l<1 || l>fNlayers) {
       if(l<1 || l>fNlayers) {
-         printf("error in file %s layer=%d min is 1 max is %d/n",
+         printf("error in file %s layer=%d min. is 1 max is %d/n",
                  filename,l,fNlayers);
          continue;
       }// end if l
                  filename,l,fNlayers);
          continue;
       }// end if l
-      l--; a--; d--; // shift layer, ladder, and detector counters to zero base
-      i = d + a*fNdet[l]; // position of this detector
-      g = &(fGm[l][i]);
-
-      oor = byPI*o;
-      pr = byPI*p;
-      qr = byPI*q;
-      rr = byPI*r;
-      sr = byPI*s;
-      tr = byPI*t;
-
-      g->fx0   = x;
-      g->fy0   = y;
-      g->fz0   = z;
-//
-      si    = sin(oor);if(o== 90.0) si = +1.0;
-                      if(o==270.0) si = -1.0;
-                      if(o==  0.0||o==180.) si = 0.0;
-      lr[0] = si * cos(pr);
-      lr[1] = si * sin(pr);
-      lr[2] = cos(oor);if(o== 90.0||o==270.) lr[2] = 0.0;
-                      if(o== 0.0)           lr[2] = +1.0;
-                      if(o==180.0)          lr[2] = -1.0;
-//
-      si    =  sin(qr);if(q== 90.0) si = +1.0; 
-                       if(q==270.0) si = -1.0;
-                       if(q==  0.0||q==180.) si = 0.0;
-      lr[3] = si * cos(rr);
-      lr[4] = si * sin(rr);
-      lr[5] = cos(qr);if(q== 90.0||q==270.) lr[5] = 0.0;
-                      if(q==  0.0)          lr[5] = +1.0;
-                      if(q==180.0)          lr[5] = -1.0;
-//
-      si    = sin(sr);if(s== 90.0) si = +1.0;
-                      if(s==270.0) si = -1.0;
-                      if(s==  0.0||s==180.) si = 0.0;
-      lr[6] = si * cos(tr);
-      lr[7] = si * sin(tr);
-      lr[8] = cos(sr);if(s== 90.0||s==270.0) lr[8] =  0.0;
-                      if(s==  0.0)           lr[8] = +1.0;
-                      if(s==180.0)           lr[8] = -1.0;
-      // Normalize these elements
-      for(a=0;a<3;a++){// reuse float Si and integers a and d.
-         si = 0.0;
-         for(d=0;d<3;d++) si += lr[3*a+d]*lr[3*a+d];
-         si = TMath::Sqrt(1./si);
-         for(d=0;d<3;d++) g->fr[3*a+d] = lr[3*a+d] = si*lr[3*a+d];
-      } // end for a
-      // get angles from matrix up to a phase of 180 degrees.
-      oor     = atan2(lr[7],lr[8]);if(oor<0.0) oor += 2.0*pi;
-      pr     = asin(lr[2]);       if(pr<0.0) pr += 2.0*pi;
-      qr     = atan2(lr[3],lr[0]);if(qr<0.0) qr += 2.0*pi;
-      g->frx = oor;
-      g->fry = pr;
-      g->frz = qr;
-      // l = layer-1 at this point.
-           if(l==0||l==1) g->fShapeIndex = 0; // SPD's
-      else if(l==2||l==3) g->fShapeIndex = 1; // SDD's
-      else if(l==4||l==5) g->fShapeIndex = 2; // SSD's
-   } // end for ever loop
+      id[0] = l;id[1] = a;id[2] = d;
+      tran[0] = tran[1] = tran[2]  = 0.0;
+      tran[0] = (Double_t)x;tran[1] = (Double_t)y;tran[2] = (Double_t)z;
+      rot6[0] = rot6[1] = rot6[2] = rot6[3] = rot6[4] = rot6[5] =0.0;
+      rot6[0] = (Double_t)o;rot6[1] = (Double_t)p;rot6[2] = (Double_t)q;
+      rot6[3] = (Double_t)r;rot6[4] = (Double_t)s;rot6[5] = (Double_t)t;
+      switch (l){
+      case 1: case 2: // layer 1 or2 SPD
+          fGm->AddAt(new AliITSgeomMatrix(rot6,kSPD,id,tran),lm++);
+         break;
+      case 3: case 4: // layer 3 or 4 SDD
+          fGm->AddAt(new AliITSgeomMatrix(rot6,kSDD,id,tran),lm++);
+         break;
+      case 5: case 6: // layer 5 or 6 SSD
+          fGm->AddAt(new AliITSgeomMatrix(rot6,kSSD,id,tran),lm++);
+         break;
+      } // end switch
+   } // end while ever loop
    fclose(pf);
 }
 
 //________________________________________________________________________
    fclose(pf);
 }
 
 //________________________________________________________________________
-AliITSgeom::AliITSgeom(const AliITSgeom &source){
+AliITSgeom::AliITSgeom(AliITSgeom &source){
 ////////////////////////////////////////////////////////////////////////
 //     The copy constructor for the AliITSgeom class. It calls the
 // = operator function. See the = operator function for more details.
 ////////////////////////////////////////////////////////////////////////
 //     The copy constructor for the AliITSgeom class. It calls the
 // = operator function. See the = operator function for more details.
@@ -464,7 +584,7 @@ AliITSgeom::AliITSgeom(const AliITSgeom &source){
 }
 
 //________________________________________________________________________
 }
 
 //________________________________________________________________________
-/*void AliITSgeom::operator=(const AliITSgeom &source){
+void AliITSgeom::operator=(AliITSgeom &source){
 ////////////////////////////////////////////////////////////////////////
 //     The = operator function for the AliITSgeom class. It makes an
 // independent copy of the class in such a way that any changes made
 ////////////////////////////////////////////////////////////////////////
 //     The = operator function for the AliITSgeom class. It makes an
 // independent copy of the class in such a way that any changes made
@@ -472,580 +592,75 @@ AliITSgeom::AliITSgeom(const AliITSgeom &source){
 // This is required for many ITS alignment studies where the copied
 // class is then modified by introducing some misalignment.
 ////////////////////////////////////////////////////////////////////////
 // This is required for many ITS alignment studies where the copied
 // class is then modified by introducing some misalignment.
 ////////////////////////////////////////////////////////////////////////
-   Int_t i,j,k;
+   Int_t i;
 
    if(this == &source) return; // don't assign to ones self.
 
    // if there is an old structure allocated delete it first.
 
    if(this == &source) return; // don't assign to ones self.
 
    // if there is an old structure allocated delete it first.
-   if(fGm != 0){
-      for(i=0;i<fNlayers;i++) delete[] fGm[i];
-      delete[] fGm;
+   if(this->fGm != 0){
+      for(i=0;i<this->fNmodules;i++) delete this->fGm->At(i);
+      delete this->fGm;
    } // end if fGm != 0 
    if(fNlad != 0) delete[] fNlad;
    if(fNdet != 0) delete[] fNdet;
 
    } // end if fGm != 0 
    if(fNlad != 0) delete[] fNlad;
    if(fNdet != 0) delete[] fNdet;
 
-   fNlayers = source.fNlayers;
-   fNlad = new Int_t[fNlayers];
-   for(i=0;i<fNlayers;i++) fNlad[i] = source.fNlad[i];
-   fNdet = new Int_t[fNlayers];
-   for(i=0;i<fNlayers;i++) fNdet[i] = source.fNdet[i];
-   fShape = new TObjArray(*(source.fShape));//This does not make a proper copy.
-   fGm = new AliITSgeomS* [fNlayers];
-   for(i=0;i<fNlayers;i++){
-      fGm[i] = new AliITSgeomS[fNlad[i]*fNdet[i]];
-      for(j=0;j<(fNlad[i]*fNdet[i]);j++){
-         fGm[i][j].fShapeIndex = source.fGm[i][j].fShapeIndex;
-         fGm[i][j].fx0 = source.fGm[i][j].fx0;
-         fGm[i][j].fy0 = source.fGm[i][j].fy0;
-         fGm[i][j].fz0 = source.fGm[i][j].fz0;
-         fGm[i][j].frx = source.fGm[i][j].frx;
-         fGm[i][j].fry = source.fGm[i][j].fry;
-         fGm[i][j].frz = source.fGm[i][j].frz;
-         for(k=0;k<9;k++) fGm[i][j].fr[k] = source.fGm[i][j].fr[k];
-      } // end for j
+   this->fTrans    = source.fTrans;
+   this->fNmodules = source.fNmodules;
+   this->fNlayers = source.fNlayers;
+   this->fNlad = new Int_t[fNlayers];
+   for(i=0;i<this->fNlayers;i++) this->fNlad[i] = source.fNlad[i];
+   this->fNdet = new Int_t[fNlayers];
+   for(i=0;i<this->fNlayers;i++) this->fNdet[i] = source.fNdet[i];
+   this->fShape = new TObjArray(*(source.fShape));//This does not make a proper copy.
+   this->fGm = new TObjArray(this->fNmodules,0);
+   for(i=0;i<this->fNmodules;i++){
+       this->fGm->AddAt(new AliITSgeomMatrix(*(
+          (AliITSgeomMatrix*)(source.fGm->At(i)))),i);
    } // end for i
    return;
    } // end for i
    return;
-   }*/
-//________________________________________________________________________
-AliITSgeom& AliITSgeom::operator=(const AliITSgeom &source){
-////////////////////////////////////////////////////////////////////////
-//     The = operator function for the AliITSgeom class. It makes an
-// independent copy of the class in such a way that any changes made
-// to the copied class will not affect the source class in any way.
-// This is required for many ITS alignment studies where the copied
-// class is then modified by introducing some misalignment.
-////////////////////////////////////////////////////////////////////////
-   Int_t i,j,k;
-
-   if(this == &source) return *this; // don't assign to ones self.
-
-   // if there is an old structure allocated delete it first.
-   if(fGm != 0){
-      for(i=0;i<fNlayers;i++) delete[] fGm[i];
-      delete[] fGm;
-   } // end if fGm != 0 
-   if(fNlad != 0) delete[] fNlad;
-   if(fNdet != 0) delete[] fNdet;
-
-   fNlayers = source.fNlayers;
-   fNlad = new Int_t[fNlayers];
-   for(i=0;i<fNlayers;i++) fNlad[i] = source.fNlad[i];
-   fNdet = new Int_t[fNlayers];
-   for(i=0;i<fNlayers;i++) fNdet[i] = source.fNdet[i];
-   fShape = new TObjArray(*(source.fShape));//This does not make a proper copy.
-   fGm = new AliITSgeomS* [fNlayers];
-   for(i=0;i<fNlayers;i++){
-      fGm[i] = new AliITSgeomS[fNlad[i]*fNdet[i]];
-      for(j=0;j<(fNlad[i]*fNdet[i]);j++){
-         fGm[i][j].fShapeIndex = source.fGm[i][j].fShapeIndex;
-         fGm[i][j].fx0 = source.fGm[i][j].fx0;
-         fGm[i][j].fy0 = source.fGm[i][j].fy0;
-         fGm[i][j].fz0 = source.fGm[i][j].fz0;
-         fGm[i][j].frx = source.fGm[i][j].frx;
-         fGm[i][j].fry = source.fGm[i][j].fry;
-         fGm[i][j].frz = source.fGm[i][j].frz;
-         for(k=0;k<9;k++) fGm[i][j].fr[k] = source.fGm[i][j].fr[k];
-      } // end for j
-   } // end for i
-   return *this;
-}
-//________________________________________________________________________
-void AliITSgeom::GtoL(Int_t lay,Int_t lad,Int_t det,
-                       const Double_t *g,Double_t *l){
-////////////////////////////////////////////////////////////////////////
-//     The function that does the global ALICE Cartesian coordinate
-// to local active volume detector Cartesian coordinate transformation.
-// The local detector coordinate system is determined by the layer, 
-// ladder, and detector numbers. The global coordinates are entered by
-// the three element Double_t array g and the local coordinate values
-// are returned by the three element Double_t array l. The order of the 
-// three elements are g[0]=x, g[1]=y, and g[2]=z, similarly for l.
-////////////////////////////////////////////////////////////////////////
-   Double_t x,y,z;
-   AliITSgeomS *gl;
-
-   lay--; lad--; det--;
-   gl = &(fGm[lay][fNdet[lay]*lad+det]);
-
-   x    = g[0] - gl->fx0;
-   y    = g[1] - gl->fy0;
-   z    = g[2] - gl->fz0;
-   l[0] = gl->fr[0]*x + gl->fr[1]*y + gl->fr[2]*z;
-   l[1] = gl->fr[3]*x + gl->fr[4]*y + gl->fr[5]*z;
-   l[2] = gl->fr[6]*x + gl->fr[7]*y + gl->fr[8]*z;
-   return;
-}
-//________________________________________________________________________
-void AliITSgeom::GtoL(const Int_t *id,const Double_t *g,Double_t *l){
-////////////////////////////////////////////////////////////////////////
-//     The function that does the local active volume detector Cartesian
-// coordinate to global ALICE Cartesian coordinate transformation.
-// The local detector coordinate system is determined by the id[0]=layer, 
-// id[1]=ladder, and id[2]=detector numbers. The local coordinates are
-// entered by the three element Double_t array l and the global coordinate
-// values are returned by the three element Double_t array g. The order of the 
-// three elements are l[0]=x, l[1]=y, and l[2]=z, similarly for g.
-////////////////////////////////////////////////////////////////////////
-    GtoL(id[0],id[1],id[2],g,l);
-    return;
-}
-//________________________________________________________________________
-void AliITSgeom::GtoL(const Int_t index,const Double_t *g,Double_t *l){
-////////////////////////////////////////////////////////////////////////
-//     The function that does the local active volume detector Cartesian
-// coordinate to global ALICE Cartesian coordinate transformation.
-// The local detector coordinate system is determined by the detector
-// index numbers (see GetModuleIndex and GetModuleID). The local 
-// coordinates are entered by the three element Double_t array l and the 
-// global coordinate values are returned by the three element Double_t array g.
-// The order of the three elements are l[0]=x, l[1]=y, and l[2]=z, similarly 
-// for g.
-////////////////////////////////////////////////////////////////////////
-    Int_t    lay,lad,det;
-
-    this->GetModuleId(index,lay,lad,det);
-
-    GtoL(lay,lad,det,g,l);
-    return;
-}
-//________________________________________________________________________
-void AliITSgeom::GtoL(Int_t lay,Int_t lad,Int_t det,
-                       const Float_t *g,Float_t *l){
-////////////////////////////////////////////////////////////////////////
-//     The function that does the global ALICE Cartesian coordinate
-// to local active volume detector Cartesian coordinate transformation.
-// The local detector coordinate system is determined by the layer, 
-// ladder, and detector numbers. The global coordinates are entered by
-// the three element Float_t array g and the local coordinate values
-// are returned by the three element Float_t array l. The order of the 
-// three elements are g[0]=x, g[1]=y, and g[2]=z, similarly for l.
-////////////////////////////////////////////////////////////////////////
-    Int_t    i;
-    Double_t gd[3],ld[3];
-
-    for(i=0;i<3;i++) gd[i] = (Double_t) g[i];
-    GtoL(lay,lad,det,(Double_t *)gd,(Double_t *)ld);
-    for(i=0;i<3;i++) l[i] = (Float_t) ld[i];
-    return;
-}
-//________________________________________________________________________
-void AliITSgeom::GtoL(const Int_t *id,const Float_t *g,Float_t *l){
-////////////////////////////////////////////////////////////////////////
-//     The function that does the local active volume detector Cartesian
-// coordinate to global ALICE Cartesian coordinate transformation.
-// The local detector coordinate system is determined by the Int_t array id,
-// id[0]=layer, id[1]=ladder, and id[2]=detector numbers. The local 
-// coordinates are entered by the three element Float_t array l and the
-// global coordinate values are returned by the three element Float_t array g.
-// The order of the three elements are l[0]=x, l[1]=y, and l[2]=z, similarly
-// for g. The order of the three elements are g[0]=x, g[1]=y, and g[2]=z,
-// similarly for l.
-////////////////////////////////////////////////////////////////////////
-    Int_t    i;
-    Double_t gd[3],ld[3];
-
-    for(i=0;i<3;i++) gd[i] = (Double_t) g[i];
-    GtoL(id[0],id[1],id[2],(Double_t *)gd,(Double_t *)ld);
-    for(i=0;i<3;i++) l[i] = (Float_t) ld[i];
-    return;
-}
-//________________________________________________________________________
-void AliITSgeom::GtoL(const Int_t index,const Float_t *g,Float_t *l){
-////////////////////////////////////////////////////////////////////////
-//     The function that does the local active volume detector Cartesian
-// coordinate to global ALICE Cartesian coordinate transformation.
-// The local detector coordinate system is determined by the detector
-// index numbers (see GetModuleIndex and GetModuleID). The local 
-// coordinates are entered by the three element Float_t array l and the 
-// global coordinate values are returned by the three element Float_t array g.
-// The order of the three elements are l[0]=x, l[1]=y, and l[2]=z, similarly 
-// for g.
-////////////////////////////////////////////////////////////////////////
-    Int_t    lay,lad,det;
-    Int_t    i;
-    Double_t gd[3],ld[3];
-
-    this->GetModuleId(index,lay,lad,det);
-
-    for(i=0;i<3;i++) gd[i] = (Double_t) g[i];
-    GtoL(lay,lad,det,(Double_t *)gd,(Double_t *)ld);
-    for(i=0;i<3;i++) l[i] = (Float_t) ld[i];
-    return;
-}
-//________________________________________________________________________
-void AliITSgeom::LtoG(Int_t lay,Int_t lad,Int_t det,
-                     const Double_t *l,Double_t *g){
-////////////////////////////////////////////////////////////////////////
-//     The function that does the local active volume detector Cartesian
-// coordinate to global ALICE Cartesian coordinate transformation.
-// The local detector coordinate system is determined by the layer, 
-// ladder, and detector numbers. The local coordinates are entered by
-// the three element Float_t array l and the global coordinate values
-// are returned by the three element Float_t array g. The order of the 
-// three elements are l[0]=x, l[1]=y, and l[2]=z, similarly for g.
-////////////////////////////////////////////////////////////////////////
-   Double_t x,y,z;
-   AliITSgeomS *gl;
-
-   lay--; lad--; det--;
-   gl   = &(fGm[lay][fNdet[lay]*lad+det]);
-
-   x    = gl->fr[0]*l[0] + gl->fr[3]*l[1] + gl->fr[6]*l[2];
-   y    = gl->fr[1]*l[0] + gl->fr[4]*l[1] + gl->fr[7]*l[2];
-   z    = gl->fr[2]*l[0] + gl->fr[5]*l[1] + gl->fr[8]*l[2];
-   g[0] = x + gl->fx0;
-   g[1] = y + gl->fy0;
-   g[2] = z + gl->fz0;
-   return;
-}
-//________________________________________________________________________
-void AliITSgeom::LtoG(const Int_t *id,const Double_t *l,Double_t *g){
-////////////////////////////////////////////////////////////////////////
-//     The function that does the local active volume detector Cartesian
-// coordinate to global ALICE Cartesian coordinate transformation.
-// The local detector coordinate system is determined by the three
-// element array Id containing as it's three elements Id[0]=layer, 
-// Id[1]=ladder, and Id[2]=detector numbers. The local coordinates
-// are entered by the three element Double_t array l and the global
-// coordinate values are returned by the three element Double_t array g.
-// The order of the three elements are l[0]=x, l[1]=y, and l[2]=z,
-// similarly for g.
-////////////////////////////////////////////////////////////////////////
-    LtoG(id[0],id[1],id[2],l,g);
-    return;
-}
-//________________________________________________________________________
-void AliITSgeom::LtoG(const Int_t index,const Double_t *l,Double_t *g){
-////////////////////////////////////////////////////////////////////////
-//     The function that does the local active volume detector Cartesian
-// coordinate to global ALICE Cartesian coordinate transformation.
-// The local detector coordinate system is determined by the detector  
-// index number (see GetModuleIndex and GetModuleId). The local coordinates
-// are entered by the three element Double_t array l and the global
-// coordinate values are returned by the three element Double_t array g.
-// The order of the three elements are l[0]=x, l[1]=y, and l[2]=z,
-// similarly for g.
-////////////////////////////////////////////////////////////////////////
-    Int_t    lay,lad,det;
-
-    this->GetModuleId(index,lay,lad,det);
-
-    LtoG(lay,lad,det,l,g);
-    return;
-}
-//________________________________________________________________________
-void AliITSgeom::LtoG(Int_t lay,Int_t lad,Int_t det,
-                     const Float_t *l,Float_t *g){
-////////////////////////////////////////////////////////////////////////
-//     The function that does the local active volume detector Cartesian
-// coordinate to global ALICE Cartesian coordinate transformation.
-// The local detector coordinate system is determined by the layer, 
-// ladder, and detector numbers. The local coordinates are entered by
-// the three element Float_t array l and the global coordinate values
-// are returned by the three element Float_t array g. The order of the 
-// three elements are l[0]=x, l[1]=y, and l[2]=z, similarly for g.
-////////////////////////////////////////////////////////////////////////
-    Int_t    i;
-    Double_t gd[3],ld[3];
-
-    for(i=0;i<3;i++) ld[i] = (Double_t) l[i];
-    LtoG(lay,lad,det,(Double_t *)ld,(Double_t *)gd);
-    for(i=0;i<3;i++) g[i] = (Float_t) gd[i];
-    return;
-}
-//________________________________________________________________________
-void AliITSgeom::LtoG(const Int_t *id,const Float_t *l,Float_t *g){
-////////////////////////////////////////////////////////////////////////
-//     The function that does the local active volume detector Cartesian
-// coordinate to global ALICE Cartesian coordinate transformation.
-// The local detector coordinate system is determined by the three
-// element array Id containing as it's three elements Id[0]=layer, 
-// Id[1]=ladder, and Id[2]=detector numbers. The local coordinates
-// are entered by the three element Float_t array l and the global
-// coordinate values are returned by the three element Float_t array g.
-// The order of the three elements are l[0]=x, l[1]=y, and l[2]=z,
-// similarly for g.
-////////////////////////////////////////////////////////////////////////
-    Int_t    i;
-    Double_t gd[3],ld[3];
-
-    for(i=0;i<3;i++) ld[i] = (Double_t) l[i];
-    LtoG(id[0],id[1],id[2],(Double_t *)ld,(Double_t *)gd);
-    for(i=0;i<3;i++) g[i] = (Float_t) gd[i];
-    return;
-}
-//________________________________________________________________________
-void AliITSgeom::LtoG(const Int_t index,const Float_t *l,Float_t *g){
-////////////////////////////////////////////////////////////////////////
-//     The function that does the local active volume detector Cartesian
-// coordinate to global ALICE Cartesian coordinate transformation.
-// The local detector coordinate system is determined by the detector  
-// index number (see GetModuleIndex and GetModuleId). The local coordinates
-// are entered by the three element Float_t array l and the global
-// coordinate values are returned by the three element Float_t array g.
-// The order of the three elements are l[0]=x, l[1]=y, and l[2]=z,
-// similarly for g.
-////////////////////////////////////////////////////////////////////////
-    Int_t    i,lay,lad,det;
-    Double_t gd[3],ld[3];
-
-    this->GetModuleId(index,lay,lad,det);
-
-    for(i=0;i<3;i++) ld[i] = (Double_t) l[i];
-    LtoG(lay,lad,det,(Double_t *)ld,(Double_t *)gd);
-    for(i=0;i<3;i++) g[i] = (Float_t) gd[i];
-    return;
-}
-//______________________________________________________________________
-void AliITSgeom::LtoL(const Int_t *id1,const Int_t *id2,
-                     Double_t *l1,Double_t *l2){
-////////////////////////////////////////////////////////////////////////
-//     The function that does the local active volume detector Cartesian
-// coordinate to a different local active volume detector Cartesian coordinate
-// transformation. The original local detector coordinate system is determined
-// by the detector array id1, id1[0]=layer, id1[1]=ladder, and id1[2]=detector
-// and the new coordinate system is determined by the detector array id2,
-// id2[0]=layer, id2[1]=ladder, and id2[2]=detector. The original local
-// coordinates are entered by the three element Double_t array l1 and the
-// other new local coordinate values are returned by the three element
-// Double_t array l2. The order of the three elements are l1[0]=x, l1[1]=y,
-// and l1[2]=z, similarly for l2.
-////////////////////////////////////////////////////////////////////////
-    Double_t g[3];
-
-    LtoG(id1,l1,g);
-    GtoL(id2,g,l2);
-    return;
-}
-//______________________________________________________________________
-void AliITSgeom::LtoL(const Int_t index1,const Int_t index2,
-                     Double_t *l1,Double_t *l2){
-////////////////////////////////////////////////////////////////////////
-//     The function that does the local active volume detector Cartesian
-// coordinate to a different local active volume detector Cartesian coordinate
-// transformation. The original local detector coordinate system is determined
-// by the detector index number index1, and the new coordinate system is
-// determined by the detector index number index2, (see GetModuleIndex and
-// GetModuleId). The original local coordinates are entered by the three
-// element Double_t array l1 and the other new local coordinate values are
-// returned by the three element Double_t array l2. The order of the three
-// elements are l1[0]=x, l1[1]=y, and l1[2]=z, similarly for l2.
-////////////////////////////////////////////////////////////////////////
-    Double_t g[3];
-
-    LtoG(index1,l1,g);
-    GtoL(index2,g,l2);
-    return;
-}
-//________________________________________________________________________
-void AliITSgeom::GtoLMomentum(Int_t lay,Int_t lad,Int_t det,
-                             const Double_t *g,Double_t *l){
-////////////////////////////////////////////////////////////////////////
-//     The function that does the global ALICE Cartesian momentum
-// to local active volume detector Cartesian momentum transformation.
-// The local detector coordinate system is determined by the layer, 
-// ladder, and detector numbers. The global momentums are entered by
-// the three element Double_t array g and the local momentums values
-// are returned by the three element Double_t array l. The order of the 
-// three elements are g[0]=x, g[1]=y, and g[2]=z, similarly for l.
-////////////////////////////////////////////////////////////////////////
-   Double_t px,py,pz;
-   AliITSgeomS *gl;
-
-   lay--; lad--; det--;
-   gl = &(fGm[lay][fNdet[lay]*lad+det]);
-
-   px   = g[0];
-   py   = g[1];
-   pz   = g[2];
-   l[0] = gl->fr[0]*px + gl->fr[1]*py + gl->fr[2]*pz;
-   l[1] = gl->fr[3]*px + gl->fr[4]*py + gl->fr[5]*pz;
-   l[2] = gl->fr[6]*px + gl->fr[7]*py + gl->fr[8]*pz;
-   return;
-}
-//________________________________________________________________________
-void AliITSgeom::GtoLMomentum(Int_t lay,Int_t lad,Int_t det,
-                             const Float_t *g,Float_t *l){
-////////////////////////////////////////////////////////////////////////
-//     The function that does the global ALICE Cartesian momentum
-// to local active volume detector Cartesian momentum transformation.
-// The local detector coordinate system is determined by the layer, 
-// ladder, and detector numbers. The global momentums are entered by
-// the three element Float_t array g and the local momentums values
-// are returned by the three element Float_t array l. The order of the 
-// three elements are g[0]=x, g[1]=y, and g[2]=z, similarly for l.
-////////////////////////////////////////////////////////////////////////
-    Int_t i;
-    Double_t gd[3],ld[3];
-
-    for(i=0;i<3;i++) gd[i] = (Double_t) g[i];
-    GtoLMomentum(lay,lad,det,(Double_t *)gd,(Double_t *)ld);
-    for(i=0;i<3;i++) l[i] = (Float_t) ld[i];
-    return;
-}
-//________________________________________________________________________
-void AliITSgeom::LtoGMomentum(Int_t lay,Int_t lad,Int_t det,
-                             const Double_t *l,Double_t *g){
-////////////////////////////////////////////////////////////////////////
-//     The function that does the local active volume detector Cartesian
-// momentum to global ALICE Cartesian momentum transformation.
-// The local detector momentum system is determined by the layer, 
-// ladder, and detector numbers. The local momentums are entered by
-// the three element Double_t array l and the global momentum values
-// are returned by the three element Double_t array g. The order of the 
-// three elements are l[0]=x, l[1]=y, and l[2]=z, similarly for g.
-////////////////////////////////////////////////////////////////////////
-   Double_t px,py,pz;
-   AliITSgeomS *gl;
-
-   lay--; lad--; det--;
-   gl   = &(fGm[lay][fNdet[lay]*lad+det]);
-
-   px   = gl->fr[0]*l[0] + gl->fr[3]*l[1] + gl->fr[6]*l[2];
-   py   = gl->fr[1]*l[0] + gl->fr[4]*l[1] + gl->fr[7]*l[2];
-   pz   = gl->fr[2]*l[0] + gl->fr[5]*l[1] + gl->fr[8]*l[2];
-   g[0] = px;
-   g[1] = py;
-   g[2] = pz;
-   return;
-}
-//________________________________________________________________________
-void AliITSgeom::LtoGMomentum(Int_t lay,Int_t lad,Int_t det,
-                             const Float_t *l,Float_t *g){
-////////////////////////////////////////////////////////////////////////
-//     The function that does the local active volume detector Cartesian
-// momentum to global ALICE Cartesian momentum transformation.
-// The local detector momentum system is determined by the layer, 
-// ladder, and detector numbers. The local momentums are entered by
-// the three element Float_t array l and the global momentum values
-// are returned by the three element Float_t array g. The order of the 
-// three elements are l[0]=x, l[1]=y, and l[2]=z, similarly for g.
-////////////////////////////////////////////////////////////////////////
-    Int_t i;
-    Double_t gd[3],ld[3];
-
-    for(i=0;i<3;i++) ld[i] = (Double_t) l[i];
-    LtoGMomentum(lay,lad,det,(Double_t *)ld,(Double_t *)gd);
-    for(i=0;i<3;i++) g[i] = (Float_t) gd[i];
-    return;
-}
-//______________________________________________________________________
-void AliITSgeom::LtoLMomentum(const Int_t *id1,const Int_t *id2,
-                             const Double_t *l1,Double_t *l2){
-////////////////////////////////////////////////////////////////////////
-//     The function that does the local active volume detector Cartesian
-// momentum to a different local active volume detector Cartesian momentum
-// transformation. The original local detector momentum system is determined
-// by the Int_t array id1 (id1[0]=lay, id1[1]=lad, id1[2]=det). The new local
-// coordinate system id determined by the Int_t array id2. The local
-// momentums are entered by the three element Double_t array l1 and the other
-// local momentum values are returned by the three element Double_t array l2.
-// The order of the three elements are l1[0]=x, l1[1]=y, and l1[2]=z,
-// similarly for l2.
-////////////////////////////////////////////////////////////////////////
-    Double_t g[3];
-
-    LtoGMomentum(id1[0],id1[1],id1[2],l1,g);
-    GtoLMomentum(id2[0],id2[1],id2[2],g,l2);
-    return;
-}
-//______________________________________________________________________
-void AliITSgeom::GtoLErrorMatrix(const Int_t index,Double_t **g,Double_t **l){
-////////////////////////////////////////////////////////////////////////
-//      This converts an error matrix, expressed in global coordinates
-// into an error matrix expressed in local coordinates. Since the 
-// translations do not change the error matrix they are not included.
-// Definition: if GtoL is l[i] = T[i][j]*g[j], then from the definition
-// of the transformation matrix above T[i][j] = fr[3*i+j]. Then for a 
-// matrix l[i][l] = T[i][j]*g[j][k]*T[l][k] (sum over repeated indexes). 
-// Where T[l][k] is the transpose of T[k][l].
-////////////////////////////////////////////////////////////////////////
-    Double_t lR[3][3],lRt[3][3];
-    Int_t    lay,lad,det,i,j,k,n;
-    AliITSgeomS *gl;
-
-    GetModuleId(index,lay,lad,det);
-    lay--;lad--;det--;
-    gl = &(fGm[lay][fNdet[lay]*lad+det]);
-
-    for(i=0;i<3;i++)for(j=0;j<3;j++){
-       lR[i][j] = lRt[j][i] = gl->fr[3*i+j];
-    } // end for i,j
-
-    for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)for(n=0;n<3;n++){
-       l[i][n] = lR[i][j]*g[j][k]*lRt[k][n];
-    } // end for i,j,k,l
-    return;
-}
-//______________________________________________________________________
-void AliITSgeom::LtoGErrorMatrix(const Int_t index,Double_t **l,Double_t **g){
-////////////////////////////////////////////////////////////////////////
-//      This converts an error matrix, expressed in local coordinates
-// into an error matrix expressed in global coordinates. Since the 
-// translations do not change the error matrix they are not included.
-// Definition: if GtoL is l[i] = T[i][j]*g[j], then from the definition
-// of the transformation matrix above T[i][j] = fr[3*i+j]. Then for a 
-// matrix g[i][l] = T[j][i]*l[j][k]*T[k][l] (sum over repeated indexes). 
-// Where T[j][i] is the transpose of T[i][j].
-////////////////////////////////////////////////////////////////////////
-    Double_t lR[3][3],lRt[3][3];
-    Int_t    lay,lad,det,i,j,k,n;
-    AliITSgeomS *gl;
-
-    GetModuleId(index,lay,lad,det);
-    lay--;lad--;det--;
-    gl = &(fGm[lay][fNdet[lay]*lad+det]);
-
-    for(i=0;i<3;i++)for(j=0;j<3;j++){
-       lR[i][j] = lRt[j][i] = gl->fr[3*i+j];
-    } // end for i,j
-
-    for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)for(n=0;n<3;n++){
-       g[i][n] = lRt[i][j]*l[j][k]*lR[k][n];
-    } // end for i,j,k,l
-    return;
-}
-//______________________________________________________________________
-void AliITSgeom::LtoLErrorMatrix(const Int_t index1,const Int_t index2,
-                                Double_t **l1,Double_t **l2){
-////////////////////////////////////////////////////////////////////////
-//      This converts an error matrix, expressed in one local coordinates
-// into an error matrix expressed in different local coordinates. Since  
-// the translations do not change the error matrix they are not included.
-// This is done by going through the global coordinate system for 
-// simplicity and constancy.
-////////////////////////////////////////////////////////////////////////
-    Double_t g[3][3];
-
-    this->LtoGErrorMatrix(index1,l1,(Double_t **)g);
-    this->GtoLErrorMatrix(index2,(Double_t **)g,l2);
-    return;
-}
-//______________________________________________________________________
-Int_t AliITSgeom::GetModuleIndex(Int_t lay,Int_t lad,Int_t det){
+}//_____________________________________________________________________
+Int_t AliITSgeom::GetModuleIndex(const Int_t lay,const Int_t lad,
+                                const Int_t det){
 ////////////////////////////////////////////////////////////////////////
 //      This routine computes the module index number from the layer,
 // ladder, and detector numbers. The number of ladders and detectors
 // per layer is determined when this geometry package is constructed,
 // see AliITSgeom(const char *filename) for specifics.
 ////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////
 //      This routine computes the module index number from the layer,
 // ladder, and detector numbers. The number of ladders and detectors
 // per layer is determined when this geometry package is constructed,
 // see AliITSgeom(const char *filename) for specifics.
 ////////////////////////////////////////////////////////////////////////
-    Int_t i,j,k;
+    Int_t i,j,k,id[3];
 
     i = fNdet[lay-1] * (lad-1) + det - 1;
     j = 0;
     for(k=0;k<lay-1;k++) j += fNdet[k]*fNlad[k];
 
     i = fNdet[lay-1] * (lad-1) + det - 1;
     j = 0;
     for(k=0;k<lay-1;k++) j += fNdet[k]*fNlad[k];
-    return (i+j);
+    i = i+j;
+    GetGeomMatrix(i)->GetIndex(id);
+    if(id[0]==lay&&id[1]==lad&&id[2]==det) return i;
+    // Array of modules fGm is not in expected order. Search for this index
+    for(i=0;i<fNmodules;i++){
+       GetGeomMatrix(i)->GetIndex(id);
+       if(id[0]==lay&&id[1]==lad&&id[2]==det) return i;
+    } // end for i
+    // This layer ladder and detector combination does not exist return -1.
+    return -1;
 }
 }
-//___________________________________________________________________________
-void AliITSgeom::GetModuleId(Int_t index,Int_t &lay,Int_t &lad,Int_t &det){
+//______________________________________________________________________
+void AliITSgeom::GetModuleId(const Int_t index,
+                            Int_t &lay,Int_t &lad,Int_t &det){
 ////////////////////////////////////////////////////////////////////////
 //      This routine computes the layer, ladder and detector number 
 // given the module index number. The number of ladders and detectors
 // per layer is determined when this geometry package is constructed,
 // see AliITSgeom(const char *filename) for specifics.
 ////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////
 //      This routine computes the layer, ladder and detector number 
 // given the module index number. The number of ladders and detectors
 // per layer is determined when this geometry package is constructed,
 // see AliITSgeom(const char *filename) for specifics.
 ////////////////////////////////////////////////////////////////////////
-    Int_t i,j,k;
+    Int_t id[3];
 
 
+    GetGeomMatrix(index)->GetIndex(id);
+    lay = id[0]; lad = id[1]; det = id[2];
+    return;
+
+    // The old way kept for posterity.
+/*
+    Int_t i,j,k;
     j = 0;
     for(k=0;k<fNlayers;k++){
        j += fNdet[k]*fNlad[k];
     j = 0;
     for(k=0;k<fNlayers;k++){
        j += fNdet[k]*fNlad[k];
@@ -1061,121 +676,56 @@ void AliITSgeom::GetModuleId(Int_t index,Int_t &lay,Int_t &lad,Int_t &det){
     lad = k+1;
     det = 1+i-fNdet[lay-1]*k;
     return;
     lad = k+1;
     det = 1+i-fNdet[lay-1]*k;
     return;
+*/
 }
 //___________________________________________________________________________
 }
 //___________________________________________________________________________
-void AliITSgeom::GetRotMatrix(Int_t lay,Int_t lad,Int_t det,Double_t *mat){
-////////////////////////////////////////////////////////////////////////
-//     Returns, in the Double_t array pointed to by mat, the full rotation
-// matrix for the give detector defined by layer, ladder, and detector.
-// It returns all nine elements of fr in the AliITSgeomS structure. See the
-// description of the AliITSgeomS structure for further details of this
-// rotation matrix.
-////////////////////////////////////////////////////////////////////////
-   Int_t    i;
-   AliITSgeomS *g;
-
-   lay--; lad--; det--; // shift to base 0
-   g = &(fGm[lay][fNdet[lay]*lad+det]);
-   for(i=0;i<9;i++) mat[i] = g->fr[i];
-   return;
-}
-//___________________________________________________________________________
-void AliITSgeom::GetRotMatrix(Int_t index,Double_t *mat){
-////////////////////////////////////////////////////////////////////////
-//     Returns, in the Double_t array pointed to by mat, the full rotation
-// matrix for the give detector defined by the module index number.
-// It returns all nine elements of fr in the AliITSgeomS structure. See the
-// description of the AliITSgeomS structure for further details of this
-// rotation matrix.
-////////////////////////////////////////////////////////////////////////
-   Int_t    lay,lad,det;
-
-   this->GetModuleId(index,lay,lad,det);
-   GetRotMatrix(lay,lad,det,mat);
-   return;
-}
-//___________________________________________________________________________
-void AliITSgeom::GetRotMatrix(Int_t lay,Int_t lad,Int_t det,Float_t *mat){
-////////////////////////////////////////////////////////////////////////
-//     Returns, in the Float_t array pointed to by mat, the full rotation
-// matrix for the give detector defined by layer, ladder, and detector.
-// It returns all nine elements of fr in the AliITSgeomS structure. See the
-// description of the AliITSgeomS structure for further details of this
-// rotation matrix.
-////////////////////////////////////////////////////////////////////////
-   Int_t    i;
-   Double_t matd[9];
-
-   GetRotMatrix(lay,lad,det,(Double_t *)matd);
-   for(i=0;i<9;i++) mat[i] = (Float_t) matd[i];
-   return;
-}
-
-//___________________________________________________________________________
-void AliITSgeom::GetRotMatrix(Int_t index,Float_t *mat){
-////////////////////////////////////////////////////////////////////////
-//     Returns, in the Float_t array pointed to by mat, the full rotation
-// matrix for the give detector defined by module index number.
-// It returns all nine elements of fr in the AliITSgeomS structure. See the
-// description of the AliITSgeomS structure for further details of this
-// rotation matrix.
-////////////////////////////////////////////////////////////////////////
-   Int_t    i,lay,lad,det;
-   Double_t matd[9];
-
-   this->GetModuleId(index,lay,lad,det);
-   GetRotMatrix(lay,lad,det,(Double_t *)matd);
-   for(i=0;i<9;i++) mat[i] = (Float_t) matd[i];
-   return;
-}
-
-//___________________________________________________________________________
-Int_t AliITSgeom::GetStartDet(Int_t id){
+Int_t AliITSgeom::GetStartDet(const Int_t dtype){
   /////////////////////////////////////////////////////////////////////////
   // returns the starting module index value for a give type of detector id
   /////////////////////////////////////////////////////////////////////////
   /////////////////////////////////////////////////////////////////////////
   // returns the starting module index value for a give type of detector id
   /////////////////////////////////////////////////////////////////////////
-  Int_t first;
-  switch(id)
-  {
+
+  switch(dtype){
   case 0:
   case 0:
-     first = GetModuleIndex(1,1,1);
+     return GetModuleIndex(1,1,1);
      break;
   case 1:
      break;
   case 1:
-     first = GetModuleIndex(3,1,1);
+     return GetModuleIndex(3,1,1);
      break;
   case 2:
      break;
   case 2:
-     first = GetModuleIndex(5,1,1);
+     return GetModuleIndex(5,1,1);
      break;
   default:
      printf("<AliITSgeom::GetFirstDet> undefined detector type\n");
      break;
   default:
      printf("<AliITSgeom::GetFirstDet> undefined detector type\n");
-     first = 0;
+     return 0;
+  } // end switch
 
 
-  }
-  return first;
+  printf("<AliITSgeom::GetFirstDet> undefined detector type\n");
+  return 0;
 }
 
 //___________________________________________________________________________
 }
 
 //___________________________________________________________________________
-Int_t AliITSgeom::GetLastDet(Int_t id){
+Int_t AliITSgeom::GetLastDet(const Int_t dtype){
   /////////////////////////////////////////////////////////////////////////
   // returns the last module index value for a give type of detector id
   /////////////////////////////////////////////////////////////////////////
   /////////////////////////////////////////////////////////////////////////
   // returns the last module index value for a give type of detector id
   /////////////////////////////////////////////////////////////////////////
-  Int_t last;
-  switch(id)
-  {
+
+  switch(dtype){
   case 0:
   case 0:
-     last = GetLastSPD();
+     return GetLastSPD();
      break;
    case 1:
      break;
    case 1:
-     last = GetLastSDD();
+     return GetLastSDD();
      break;
    case 2:
      break;
    case 2:
-     last = GetLastSSD();
+     return GetLastSSD();
      break;
    default:
      printf("<AliITSgeom::GetLastDet> undefined detector type\n");
      break;
    default:
      printf("<AliITSgeom::GetLastDet> undefined detector type\n");
-     last = 0;
-  }
-  return last;
+     return 0;
+  } // end switch
+
+  printf("<AliITSgeom::GetLastDet> undefined detector type\n");
+  return 0;
 }
 
 //___________________________________________________________________________
 }
 
 //___________________________________________________________________________
@@ -1185,7 +735,8 @@ void AliITSgeom::PrintComparison(FILE *fp,AliITSgeom *other){
 // print to a file pointed to by the file pointer fp the difference
 // between two AliITSgeom classes. The format of the file is basicly,
 // define d? to be the difference between the same element of the two
 // print to a file pointed to by the file pointer fp the difference
 // between two AliITSgeom classes. The format of the file is basicly,
 // define d? to be the difference between the same element of the two
-// classes. For example dfrx = this->fGm[i][j].frx - other->fGm[i][j].frx.
+// classes. For example dfrx = this->GetGeomMatrix(i)->frx 
+// - other->GetGeomMatrix(i)->frx.
 // if(at least one of dfx0, dfy0, dfz0,dfrx,dfry,dfrz are non zero) then print
 // layer ladder detector dfx0 dfy0 dfz0 dfrx dfry dfrz
 // if(at least one of the 9 elements of dfr[] are non zero) then print
 // if(at least one of dfx0, dfy0, dfz0,dfrx,dfry,dfrz are non zero) then print
 // layer ladder detector dfx0 dfy0 dfz0 dfrx dfry dfrz
 // if(at least one of the 9 elements of dfr[] are non zero) then print
@@ -1198,41 +749,52 @@ void AliITSgeom::PrintComparison(FILE *fp,AliITSgeom *other){
 // rather than zooming quickly past you on a screen. fprintf is used to
 // do the printing. The fShapeIndex difference is not printed at this time.
 ////////////////////////////////////////////////////////////////////////
 // rather than zooming quickly past you on a screen. fprintf is used to
 // do the printing. The fShapeIndex difference is not printed at this time.
 ////////////////////////////////////////////////////////////////////////
-   Int_t    i,j,k,l;
-   Double_t xt,yt,zt,xo,yo,zo;
-   Double_t rxt,ryt,rzt,rxo,ryo,rzo;  // phi in radians
-   AliITSgeomS *gt,*go;
+   Int_t    i,j,idt[3],ido[3];
+   Double_t tt[3],to[3];  // translation
+   Double_t rt[3],ro[3];  // phi in radians
+   Double_t mt[3][3],mo[3][3]; // matrixes
+   AliITSgeomMatrix *gt,*go;
    Bool_t   t;
 
    Bool_t   t;
 
-   for(i=0;i<this->fNlayers;i++){
-      for(j=0;j<this->fNlad[i];j++) for(k=0;k<this->fNdet[i];k++){
-        l   = this->fNdet[i]*j+k; // resolved index
-         gt  = &(this->fGm[i][l]);
-        go  = &(other->fGm[i][l]);
-         xt  = gt->fx0; yt  = gt->fy0; zt  = gt->fz0;
-         xo  = go->fx0; yo  = go->fy0; zo  = go->fz0;
-         rxt = gt->frx; ryt = gt->fry; rzt = gt->frz;
-         rxo = go->frx; ryo = go->fry; rzo = go->frz;
-        if(!(xt==xo&&yt==yo&&zt==zo&&rxt==rxo&&ryt==ryo&&rzt==rzo))
-        fprintf(fp,"%1.1d %2.2d %2.2d dTrans=%f %f %f drot=%f %f %f\n",
-                i+1,j+1,k+1,xt-xo,yt-yo,zt-zo,rxt-rxo,ryt-ryo,rzt-rzo);
+   for(i=0;i<this->fNmodules;i++){
+         gt  =  this->GetGeomMatrix(i);
+        go  = other->GetGeomMatrix(i);
+         gt->GetIndex(idt);
+         go->GetIndex(ido);
+         t = kFALSE;
+         for(i=0;i<3;i++) t = t&&idt[i]!=ido[i];
+         if(t) fprintf(fp,"%4.4d %1.1d %2.2d %2.2d %1.1d %2.2d %2.2d\n",i,
+                       idt[0],idt[1],idt[2],ido[0],ido[1],ido[2]);
+         gt->GetTranslation(tt);
+         go->GetTranslation(to);
+         gt->GetAngles(rt);
+         go->GetAngles(ro);
+         t = kFALSE;
+         for(i=0;i<3;i++) t = t&&tt[i]!=to[i];
+        if(t) fprintf(fp,"%1.1d %2.2d %2.2d dTrans=%f %f %f drot=%f %f %f\n",
+                      idt[0],idt[1],idt[2],
+                       tt[0]-to[0],tt[1]-to[1],tt[2]-to[2],
+                       rt[0]-ro[0],rt[1]-ro[1],rt[2]-ro[2]);
         t = kFALSE;
         t = kFALSE;
-        for(i=0;i<9;i++) t = gt->fr[i] != go->fr[i];
+         gt->GetMatrix(mt);
+         go->GetMatrix(mo);
+        for(i=0;i<3;i++)for(j=0;j<3;j++)  t = mt[i][j] != mo[i][j];
         if(t){
         if(t){
-            fprintf(fp,"%1.1d %2.2d %2.2d dfr= %e %e %e\n",i+1,j+1,k+1,
-                 gt->fr[0]-go->fr[0],gt->fr[1]-go->fr[1],gt->fr[2]-go->fr[2]);
+            fprintf(fp,"%1.1d %2.2d %2.2d dfr= %e %e %e\n",
+                     idt[0],idt[1],idt[2],
+                 mt[0][0]-mo[0][0],mt[0][1]-mo[0][1],mt[0][2]-mo[0][2]);
             fprintf(fp,"        dfr= %e %e %e\n",
             fprintf(fp,"        dfr= %e %e %e\n",
-                 gt->fr[3]-go->fr[3],gt->fr[4]-go->fr[4],gt->fr[5]-go->fr[5]);
+                 mt[1][0]-mo[1][0],mt[1][1]-mo[1][1],mt[1][2]-mo[1][2]);
             fprintf(fp,"        dfr= %e %e %e\n",
             fprintf(fp,"        dfr= %e %e %e\n",
-                 gt->fr[6]-go->fr[6],gt->fr[7]-go->fr[7],gt->fr[8]-go->fr[8]);
-        }
-      } // end for j,k
+                 mt[2][0]-mo[2][0],mt[2][1]-mo[2][1],mt[2][2]-mo[2][2]);
+        } // end if t
    } // end for i
    return;
 }
 
 //___________________________________________________________________________
    } // end for i
    return;
 }
 
 //___________________________________________________________________________
-void AliITSgeom::PrintData(FILE *fp,Int_t lay,Int_t lad,Int_t det){
+void AliITSgeom::PrintData(FILE *fp,
+                          const Int_t lay,const Int_t lad,const Int_t det){
 ////////////////////////////////////////////////////////////////////////
 //     This function prints out the coordinate transformations for
 // the particular detector defined by layer, ladder, and detector
 ////////////////////////////////////////////////////////////////////////
 //     This function prints out the coordinate transformations for
 // the particular detector defined by layer, ladder, and detector
@@ -1246,164 +808,72 @@ void AliITSgeom::PrintData(FILE *fp,Int_t lay,Int_t lad,Int_t det){
 // is given to the user. The output it written to the file pointed
 // to by the file pointer fp. This can be set to stdout if you want.
 ////////////////////////////////////////////////////////////////////////
 // is given to the user. The output it written to the file pointed
 // to by the file pointer fp. This can be set to stdout if you want.
 ////////////////////////////////////////////////////////////////////////
-   Int_t    i,j,k,l;
-   AliITSgeomS *gt;
-
-   i  = lay-1;
-   j  = lad-1;
-   k  = det-1;
-   l  = this->fNdet[i]*j+k; // resolved index
-   gt = &(this->fGm[i][l]);
+   AliITSgeomMatrix *gt;
+   Double_t t[3],r[3],m[3][3];
+
+   gt = this->GetGeomMatrix(GetModuleIndex(lay,lad,det));
+   gt->GetTranslation(t);
+   gt->GetAngles(r);
    fprintf(fp,"%1.1d %2.2d %2.2d Trans=%f %f %f rot=%f %f %f Shape=%d\n",
    fprintf(fp,"%1.1d %2.2d %2.2d Trans=%f %f %f rot=%f %f %f Shape=%d\n",
-          i+1,j+1,k+1,gt->fx0,gt->fy0,gt->fz0,gt->frx,gt->fry,gt->frz,
-           gt->fShapeIndex);
-   fprintf(fp,"        dfr= %e %e %e\n",gt->fr[0],gt->fr[1],gt->fr[2]);
-   fprintf(fp,"        dfr= %e %e %e\n",gt->fr[3],gt->fr[4],gt->fr[5]);
-   fprintf(fp,"        dfr= %e %e %e\n",gt->fr[6],gt->fr[7],gt->fr[8]);
+          lay,lad,det,t[0],t[1],t[2],r[0],r[1],r[2],
+           gt->GetDetectorIndex());
+   gt->GetMatrix(m);
+   fprintf(fp,"        dfr= %e %e %e\n",m[0][0],m[0][1],m[0][2]);
+   fprintf(fp,"        dfr= %e %e %e\n",m[1][0],m[1][1],m[1][2]);
+   fprintf(fp,"        dfr= %e %e %e\n",m[2][0],m[2][1],m[2][2]);
    return;
 }
 //___________________________________________________________________________
    return;
 }
 //___________________________________________________________________________
-ofstream & AliITSgeom::PrintGeom(ofstream &lRb){
+ofstream & AliITSgeom::PrintGeom(ofstream &R__b){
 ////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////
-//     The default Streamer function "written by ROOT" doesn't write out
-// the arrays referenced by pointers. Therefore, a specific Streamer function
-// has to be written. This function should not be modified but instead added
-// on to so that older versions can still be read. The proper handling of
-// the version dependent streamer function hasn't been written do to the lack
-// of finding an example at the time of writing.
+//     Stream out an object of class AliITSgeom to standard output.
 ////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////
-   // Stream an object of class AliITSgeom.
-    Int_t i,j,k;
+    Int_t i;
 
 
-    lRb.setf(ios::scientific);
-    lRb << fNlayers << " ";
-    for(i=0;i<fNlayers;i++) lRb << fNlad[i] << " ";
-    for(i=0;i<fNlayers;i++) lRb << fNdet[i] << "\n";
-    for(i=0;i<fNlayers;i++) for(j=0;j<fNlad[i]*fNdet[i];j++){
-       lRb <<setprecision(16) << fGm[i][j].fShapeIndex << " ";
-       lRb <<setprecision(16) << fGm[i][j].fx0 << " ";
-       lRb <<setprecision(16) << fGm[i][j].fy0 << " ";
-       lRb <<setprecision(16) << fGm[i][j].fz0 << " ";
-       lRb <<setprecision(16) << fGm[i][j].frx << " ";
-       lRb <<setprecision(16) << fGm[i][j].fry << " ";
-       lRb <<setprecision(16) << fGm[i][j].frz << "\n";
-       for(k=0;k<9;k++) lRb <<setprecision(16) << fGm[i][j].fr[k] << " ";
-       lRb << "\n";
-      } // end for i,j
-//      lRb << fShape;
-      return lRb;
+    R__b.setf(ios::scientific);
+    R__b << fTrans << " ";
+    R__b << fNmodules << " ";
+    R__b << fNlayers << " ";
+    for(i=0;i<fNlayers;i++) R__b << fNlad[i] << " ";
+    for(i=0;i<fNlayers;i++) R__b << fNdet[i] << "\n";
+    for(i=0;i<fNmodules;i++) {
+       R__b <<setprecision(16) << *(GetGeomMatrix(i)) << "\n";
+    } // end for i
+    return R__b;
 }
 //___________________________________________________________________________
 }
 //___________________________________________________________________________
-ifstream & AliITSgeom::ReadGeom(ifstream &lRb){
+ifstream & AliITSgeom::ReadGeom(ifstream &R__b){
 ////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////
-//     The default Streamer function "written by ROOT" doesn't write out
-// the arrays referenced by pointers. Therefore, a specific Streamer function
-// has to be written. This function should not be modified but instead added
-// on to so that older versions can still be read. The proper handling of
-// the version dependent streamer function hasn't been written do to the lack
-// of finding an example at the time of writing.
+//     Stream in an object of class AliITSgeom from standard input.
 ////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////
-   // Stream an object of class AliITSgeom.
-    Int_t i,j,k;
+      Int_t i;
 
 
-      lRb >> fNlayers;
-      if(fNlad!=0) delete[] fNlad;
-      if(fNdet!=0) delete[] fNdet;
       fNlad = new Int_t[fNlayers];
       fNdet = new Int_t[fNlayers];
       fNlad = new Int_t[fNlayers];
       fNdet = new Int_t[fNlayers];
-      for(i=0;i<fNlayers;i++) lRb >> fNlad[i];
-      for(i=0;i<fNlayers;i++) lRb >> fNdet[i];
       if(fGm!=0){
       if(fGm!=0){
-         for(i=0;i<fNlayers;i++) delete[] fGm[i];
-         delete[] fGm;
+         for(i=0;i<fNmodules;i++) delete GetGeomMatrix(i);
+         delete fGm;
       } // end if fGm!=0
       } // end if fGm!=0
-      fGm = new AliITSgeomS*[fNlayers];
-      for(i=0;i<fNlayers;i++){
-         fGm[i] = new AliITSgeomS[fNlad[i]*fNdet[i]];
-         for(j=0;j<fNlad[i]*fNdet[i];j++){
-             lRb >> fGm[i][j].fShapeIndex;
-             lRb >> fGm[i][j].fx0;
-             lRb >> fGm[i][j].fy0;
-             lRb >> fGm[i][j].fz0;
-             lRb >> fGm[i][j].frx;
-             lRb >> fGm[i][j].fry;
-             lRb >> fGm[i][j].frz;
-             for(k=0;k<9;k++) lRb >> fGm[i][j].fr[k];
-         } // end for j
+
+      R__b >> fTrans >> fNmodules >> fNlayers;
+      fNlad = new Int_t[fNlayers];
+      fNdet = new Int_t[fNlayers];
+      for(i=0;i<fNlayers;i++) R__b >> fNlad[i];
+      for(i=0;i<fNlayers;i++) R__b >> fNdet[i];
+      fGm = new TObjArray(fNmodules,0);
+      for(i=0;i<fNmodules;i++){
+         fGm->AddAt(new AliITSgeomMatrix,i);
+         R__b >> *(GetGeomMatrix(i));
       } // end for i
       } // end for i
-//      lRb >> fShape;
-      return lRb;
+      return R__b;
 }
 }
+//___________________________________________________________________________
+
 //______________________________________________________________________
 //     The following routines modify the transformation of "this"
 // geometry transformations in a number of different ways.
 //______________________________________________________________________
 //______________________________________________________________________
 //     The following routines modify the transformation of "this"
 // geometry transformations in a number of different ways.
 //______________________________________________________________________
-void AliITSgeom::SetByAngles(Int_t lay,Int_t lad,Int_t det,
-                            Float_t rx,Float_t ry,Float_t rz){
-////////////////////////////////////////////////////////////////////////
-//     This function computes a new rotation matrix based on the angles
-// rx, ry, and rz (in radians) for a give detector on the give ladder
-// in the give layer. A new
-// fGm[layer-1][(fNlad[layer-1]*(ladder-1)+detector-1)].fr[] array is
-// computed.
-////////////////////////////////////////////////////////////////////////
-   AliITSgeomS *g;
-   Double_t  sx,cx,sy,cy,sz,cz;
-
-   lay--; lad--; det--; // set to zero base now.
-   g = &(fGm[lay][fNdet[lay]*lad+det]);
-
-   sx = sin(rx); cx = cos(rx);
-   sy = sin(ry); cy = cos(ry);
-   sz = sin(rz); cz = cos(rz);
-   g->frx   = rx;
-   g->fry   = ry;
-   g->frz   = rz;
-   g->fr[0] =  cz*cy;
-   g->fr[1] = -cz*sy*sx - sz*cx;
-   g->fr[2] = -cz*sy*cx + sz*sx;
-   g->fr[3] =  sz*cy;
-   g->fr[4] = -sz*sy*sx + cz*cx;
-   g->fr[5] = -sz*sy*cx - cz*sx;
-   g->fr[6] =  sy;
-   g->fr[7] =  cy*sx;
-   g->fr[8] =  cy*cx;
-   return;
-}
-//______________________________________________________________________
-void AliITSgeom::SetByAngles(Int_t index,Double_t angl[]){
-////////////////////////////////////////////////////////////////////////
-//     Sets the coordinate rotation transformation for a given module
-// as determined by the module index number.
-////////////////////////////////////////////////////////////////////////
-    Int_t lay,lad,det;
-    Float_t x,y,z;
-
-    GetModuleId(index,lay,lad,det);
-    x = (Float_t) angl[0];
-    y = (Float_t) angl[1];
-    z = (Float_t) angl[2];
-    SetByAngles(lay,lad,det,x,y,z);
-    return;
-}
-//______________________________________________________________________
-void AliITSgeom::SetTrans(Int_t index,Double_t v[]){
-////////////////////////////////////////////////////////////////////////
-//     Sets the coordinate translation for a given module as determined
-// by the module index number.
-////////////////////////////////////////////////////////////////////////
-    Int_t lay,lad,det;
-    Float_t x,y,z;
-
-    GetModuleId(index,lay,lad,det);
-    x = (Float_t) v[0];
-    y = (Float_t) v[1];
-    z = (Float_t) v[2];
-    SetTrans(lay,lad,det,x,y,z);
-    return;
-}
-//___________________________________________________________________________
-void AliITSgeom::GlobalChange(Float_t *tran,Float_t *rot){
+void AliITSgeom::GlobalChange(const Float_t *tran,const Float_t *rot){
 ////////////////////////////////////////////////////////////////////////
 //     This function performs a Cartesian translation and rotation of
 // the full ITS from its default position by an amount determined by
 ////////////////////////////////////////////////////////////////////////
 //     This function performs a Cartesian translation and rotation of
 // the full ITS from its default position by an amount determined by
@@ -1422,41 +892,26 @@ void AliITSgeom::GlobalChange(Float_t *tran,Float_t *rot){
 // respect to the beam line, except for an effective rotation about the
 // beam axis which will just rotate the ITS as a hole about the beam axis.
 ////////////////////////////////////////////////////////////////////////
 // respect to the beam line, except for an effective rotation about the
 // beam axis which will just rotate the ITS as a hole about the beam axis.
 ////////////////////////////////////////////////////////////////////////
-   Int_t    i,j,k,l;
-   Double_t rx,ry,rz;
-   Double_t sx,cx,sy,cy,sz,cz;
-   AliITSgeomS *gl;
-
-   for(i=0;i<fNlayers;i++){
-      for(j=0;j<fNlad[i];j++) for(k=0;k<fNdet[i];k++){
-        l = fNdet[i]*j+k; // resolved index
-         gl = &(fGm[i][l]);
-         gl->fx0 += tran[0];
-         gl->fy0 += tran[1];
-         gl->fz0 += tran[2];
-         gl->frx +=  rot[0];
-         gl->fry +=  rot[1];
-         gl->frz +=  rot[2];
-         rx = gl->frx; ry = gl->fry; rz = gl->frz;
-         sx = sin(rx); cx = cos(rx);
-         sy = sin(ry); cy = cos(ry);
-         sz = sin(rz); cz = cos(rz);
-         gl->fr[0] =  cz*cy;
-         gl->fr[1] = -cz*sy*sx - sz*cx;
-         gl->fr[2] = -cz*sy*cx + sz*sx;
-         gl->fr[3] =  sz*cy;
-         gl->fr[4] = -sz*sy*sx + cz*cx;
-         gl->fr[5] = -sz*sy*cx - cz*sx;
-         gl->fr[6] =  sy;
-         gl->fr[7] =  cy*sx;
-         gl->fr[8] =  cy*cx;
-      } // end for j,k
+   Int_t    i,j;
+   Double_t t[3],r[3];
+   AliITSgeomMatrix *g;
+
+   fTrans = (fTrans && 0xfffd) + 2;  // set bit 1 true.
+   for(i=0;i<fNmodules;i++){
+         g = this->GetGeomMatrix(i);
+         g->GetTranslation(t);
+         g->GetAngles(r);
+         for(j=0;j<3;j++){
+              t[j] += tran[j];
+              r[j] += rot[j];
+         } // end for j
+         g->SetTranslation(t);
+         g->SetAngles(r);
    } // end for i
    return;
 }
    } // end for i
    return;
 }
-
 //___________________________________________________________________________
 //___________________________________________________________________________
-void AliITSgeom::GlobalCylindericalChange(Float_t *tran,Float_t *rot){
+void AliITSgeom::GlobalCylindericalChange(const Float_t *tran,const Float_t *rot){
 ////////////////////////////////////////////////////////////////////////
 //     This function performs a cylindrical translation and rotation of
 // each ITS element by a fixed about in radius, rphi, and z from its
 ////////////////////////////////////////////////////////////////////////
 //     This function performs a cylindrical translation and rotation of
 // each ITS element by a fixed about in radius, rphi, and z from its
@@ -1478,47 +933,34 @@ void AliITSgeom::GlobalCylindericalChange(Float_t *tran,Float_t *rot){
 // line, except for an effective rotation about the beam axis which will
 // just rotate the ITS as a hole about the beam axis.
 ////////////////////////////////////////////////////////////////////////
 // line, except for an effective rotation about the beam axis which will
 // just rotate the ITS as a hole about the beam axis.
 ////////////////////////////////////////////////////////////////////////
-   Int_t    i,j,k,l;
-   Double_t rx,ry,rz,r,phi,rphi; // phi in radians
-   Double_t sx,cx,sy,cy,sz,cz,r0;
-   AliITSgeomS *gl;
-
-   for(i=0;i<fNlayers;i++){
-      for(j=0;j<fNlad[i];j++) for(k=0;k<fNdet[i];k++){
-        l     = fNdet[i]*j+k; // resolved index
-         gl    = &(fGm[i][l]);
-        r = r0= TMath::Hypot(gl->fy0,gl->fx0);
-        phi   = atan2(gl->fy0,gl->fx0);
+   Int_t    i,j;
+   Double_t t[3],ro[3],r,r0,phi,rphi;
+   AliITSgeomMatrix *g;
+
+   fTrans = (fTrans && 0xfffd) + 2;  // set bit 1 true.
+   for(i=0;i<fNmodules;i++){
+         g = this->GetGeomMatrix(i);
+         g->GetTranslation(t);
+         g->GetAngles(ro);
+        r = r0= TMath::Hypot(t[1],t[0]);
+        phi   = TMath::ATan2(t[1],t[0]);
         rphi  = r0*phi;
         r    += tran[0];
         rphi += tran[1];
         phi   = rphi/r0;
         rphi  = r0*phi;
         r    += tran[0];
         rphi += tran[1];
         phi   = rphi/r0;
-         gl->fx0  = r*TMath::Cos(phi);
-         gl->fy0  = r*TMath::Sin(phi);
-         gl->fz0 += tran[2];
-         gl->frx +=  rot[0];
-         gl->fry +=  rot[1];
-         gl->frz +=  rot[2];
-         rx = gl->frx; ry = gl->fry; rz = gl->frz;
-         sx = sin(rx); cx = cos(rx);
-         sy = sin(ry); cy = cos(ry);
-         sz = sin(rz); cz = cos(rz);
-         gl->fr[0] =  cz*cy;
-         gl->fr[1] = -cz*sy*sx - sz*cx;
-         gl->fr[2] = -cz*sy*cx + sz*sx;
-         gl->fr[3] =  sz*cy;
-         gl->fr[4] = -sz*sy*sx + cz*cx;
-         gl->fr[5] = -sz*sy*cx - cz*sx;
-         gl->fr[6] =  sy;
-         gl->fr[7] =  cy*sx;
-         gl->fr[8] =  cy*cx;
-      } // end for j,k
+         t[0]  = r*TMath::Cos(phi);
+         t[1]  = r*TMath::Sin(phi);
+         t[2] += tran[2];
+         for(j=0;j<3;j++){
+              ro[j] += rot[j];
+         } // end for j
+         g->SetTranslation(t);
+         g->SetAngles(ro);
    } // end for i
    return;
 }
    } // end for i
    return;
 }
-
 //___________________________________________________________________________
 //___________________________________________________________________________
-void AliITSgeom::RandomChange(Float_t *stran,Float_t *srot){
+void AliITSgeom::RandomChange(const Float_t *stran,const Float_t *srot){
 ////////////////////////////////////////////////////////////////////////
 //     This function performs a Gaussian random displacement and/or
 // rotation about the present global position of each active
 ////////////////////////////////////////////////////////////////////////
 //     This function performs a Gaussian random displacement and/or
 // rotation about the present global position of each active
@@ -1527,42 +969,28 @@ void AliITSgeom::RandomChange(Float_t *stran,Float_t *srot){
 // x y and z translations, and the three element array srot,
 // for the three rotation about the axis x y and z.
 ////////////////////////////////////////////////////////////////////////
 // x y and z translations, and the three element array srot,
 // for the three rotation about the axis x y and z.
 ////////////////////////////////////////////////////////////////////////
-   Int_t    i,j,k,l;
-   Double_t rx,ry,rz;
-   Double_t sx,cx,sy,cy,sz,cz;
-   TRandom  ran;
-   AliITSgeomS *gl;
-
-   for(i=0;i<fNlayers;i++){
-      for(j=0;j<fNlad[i];j++) for(k=0;k<fNdet[i];k++){
-        l = fNdet[i]*j+k; // resolved index
-         gl = &(fGm[i][l]);
-         gl->fx0 += ran.Gaus(0.0,stran[0]);
-         gl->fy0 += ran.Gaus(0.0,stran[1]);
-         gl->fz0 += ran.Gaus(0.0,stran[2]);
-         gl->frx += ran.Gaus(0.0, srot[0]);
-         gl->fry += ran.Gaus(0.0, srot[1]);
-         gl->frz += ran.Gaus(0.0, srot[2]);
-         rx = gl->frx; ry = gl->fry; rz = gl->frz;
-         sx = sin(rx); cx = cos(rx);
-         sy = sin(ry); cy = cos(ry);
-         sz = sin(rz); cz = cos(rz);
-         gl->fr[0] =  cz*cy;
-         gl->fr[1] = -cz*sy*sx - sz*cx;
-         gl->fr[2] = -cz*sy*cx + sz*sx;
-         gl->fr[3] =  sz*cy;
-         gl->fr[4] = -sz*sy*sx + cz*cx;
-         gl->fr[5] = -sz*sy*cx - cz*sx;
-         gl->fr[6] =  sy;
-         gl->fr[7] =  cy*sx;
-         gl->fr[8] =  cy*cx;
-      } // end for j,k
+   Int_t    i,j;
+   Double_t t[3],r[3];
+   //MI   TRandom ran;
+   AliITSgeomMatrix *g;
+
+   fTrans = (fTrans && 0xfffd) + 2;  // set bit 1 true.
+   for(i=0;i<fNmodules;i++){
+         g = this->GetGeomMatrix(i);
+         g->GetTranslation(t);
+         g->GetAngles(r);
+         for(j=0;j<3;j++){
+              t[j] += gRandom->Gaus(0.0,stran[j]);
+              r[j] += gRandom->Gaus(0.0, srot[j]);
+         } // end for j
+         g->SetTranslation(t);
+         g->SetAngles(r);
    } // end for i
    return;
 }
    } // end for i
    return;
 }
-
 //___________________________________________________________________________
 //___________________________________________________________________________
-void AliITSgeom::RandomCylindericalChange(Float_t *stran,Float_t *srot){
+void AliITSgeom::RandomCylindericalChange(const Float_t *stran,
+                                         const Float_t *srot){
 ////////////////////////////////////////////////////////////////////////
 //     This function performs a Gaussian random displacement and/or
 // rotation about the present global position of each active
 ////////////////////////////////////////////////////////////////////////
 //     This function performs a Gaussian random displacement and/or
 // rotation about the present global position of each active
@@ -1573,187 +1001,123 @@ void AliITSgeom::RandomCylindericalChange(Float_t *stran,Float_t *srot){
 // in detector position allow for the simulation of a random uncertainty
 // in the detector positions of the ITS.
 ////////////////////////////////////////////////////////////////////////
 // in detector position allow for the simulation of a random uncertainty
 // in the detector positions of the ITS.
 ////////////////////////////////////////////////////////////////////////
-   Int_t     i,j,k,l;
-   Double_t  rx,ry,rz,r,phi,x,y;  // phi in radians
-   Double_t  sx,cx,sy,cy,sz,cz,r0;
-   TRandom   ran;
-   AliITSgeomS  *gl;
-
-   for(i=0;i<fNlayers;i++){
-      for(j=0;j<fNlad[i];j++) for(k=0;k<fNdet[i];k++){
-        l     = fNdet[i]*j+k; // resolved index
-         gl    = &(fGm[i][l]);
-        x     = gl->fx0;
-        y     = gl->fy0;
-        r = r0= TMath::Hypot(y,x);
-        phi   = TMath::ATan2(y,x);
+   Int_t    i,j;
+   Double_t t[3],ro[3],r,r0,phi,rphi;
+   TRandom ran;
+   AliITSgeomMatrix *g;
+
+   fTrans = (fTrans && 0xfffd) + 2;  // set bit 1 true.
+   for(i=0;i<fNmodules;i++){
+         g = this->GetGeomMatrix(i);
+         g->GetTranslation(t);
+         g->GetAngles(ro);
+        r = r0= TMath::Hypot(t[1],t[0]);
+        phi   = TMath::ATan2(t[1],t[0]);
+        rphi  = r0*phi;
         r    += ran.Gaus(0.0,stran[0]);
         r    += ran.Gaus(0.0,stran[0]);
-        phi  += ran.Gaus(0.0,stran[1])/r0;
-         gl->fx0  = r*TMath::Cos(phi);
-         gl->fy0  = r*TMath::Sin(phi);
-         gl->fz0 += ran.Gaus(0.0,stran[2]);
-         gl->frx += ran.Gaus(0.0, srot[0]);
-         gl->fry += ran.Gaus(0.0, srot[1]);
-         gl->frz += ran.Gaus(0.0, srot[2]);
-         rx = gl->frx; ry = gl->fry; rz = gl->frz;
-         sx = sin(rx); cx = cos(rx);
-         sy = sin(ry); cy = cos(ry);
-         sz = sin(rz); cz = cos(rz);
-         gl->fr[0] =  cz*cy;
-         gl->fr[1] = -cz*sy*sx - sz*cx;
-         gl->fr[2] = -cz*sy*cx + sz*sx;
-         gl->fr[3] =  sz*cy;
-         gl->fr[4] = -sz*sy*sx + cz*cx;
-         gl->fr[5] = -sz*sy*cx - cz*sx;
-         gl->fr[6] =  sy;
-         gl->fr[7] =  cy*sx;
-         gl->fr[8] =  cy*cx;
-      } // end for j,k
+        rphi += ran.Gaus(0.0,stran[1]);
+        phi   = rphi/r0;
+         t[0]  = r*TMath::Cos(phi);
+         t[1]  = r*TMath::Sin(phi);
+         t[2] += ran.Gaus(0.0,stran[2]);
+         for(j=0;j<3;j++){
+              ro[j] += ran.Gaus(0.0, srot[j]);
+         } // end for j
+         g->SetTranslation(t);
+         g->SetAngles(ro);
    } // end for i
    return;
 }
 //______________________________________________________________________
 void AliITSgeom::GeantToTracking(AliITSgeom &source){
 /////////////////////////////////////////////////////////////////////////
    } // end for i
    return;
 }
 //______________________________________________________________________
 void AliITSgeom::GeantToTracking(AliITSgeom &source){
 /////////////////////////////////////////////////////////////////////////
-//     Copy the geometry data but change it to make coordinate systems
-// changes between the Global to the Local coordinate system used for 
-// ITS tracking. Basicly the difference is that the direction of the
-// y coordinate system for layer 1 is rotated about the z axis 180 degrees
-// so that it points in the same direction as it does in all of the other
-// layers.
-// Fixed for bug and new calulation of tracking coordiantes. BSN June 8 2000.
-////////////////////////////////////////////////////////////////////////////
-   Double_t oor,pr,qr;
-   Int_t    i,j,k;
-   Double_t pi = TMath::Pi();
-
-   if(this == &source) return; // don't assign to ones self.
-
-   // if there is an old structure allocated delete it first.
-   if(fGm != 0){
-      for(i=0;i<fNlayers;i++) delete[] fGm[i];
-      delete[] fGm;
-   } // end if fGm != 0 
-   if(fNlad != 0) delete[] fNlad;
-   if(fNdet != 0) delete[] fNdet;
-
-   fNlayers = source.fNlayers;
-   fNlad = new Int_t[fNlayers];
-   for(i=0;i<fNlayers;i++) fNlad[i] = source.fNlad[i];
-   fNdet = new Int_t[fNlayers];
-   for(i=0;i<fNlayers;i++) fNdet[i] = source.fNdet[i];
-   fShape = new TObjArray(*(source.fShape));//This does not make a proper copy.
-   fGm = new AliITSgeomS* [fNlayers];
-   for(i=0;i<fNlayers;i++){
-      fGm[i] = new AliITSgeomS[fNlad[i]*fNdet[i]];
-      for(j=0;j<(fNlad[i]*fNdet[i]);j++){
-         fGm[i][j].fShapeIndex = source.fGm[i][j].fShapeIndex;
-         fGm[i][j].fx0 = source.fGm[i][j].fx0;
-         fGm[i][j].fy0 = source.fGm[i][j].fy0;
-         fGm[i][j].fz0 = source.fGm[i][j].fz0;
-         fGm[i][j].frx = source.fGm[i][j].frx;
-         fGm[i][j].fry = source.fGm[i][j].fry;
-         fGm[i][j].frz = source.fGm[i][j].frz;
-         for(k=0;k<9;k++) fGm[i][j].fr[k] = source.fGm[i][j].fr[k];
-         if(i==0) { // layer=1 is placed up side down
-             // mupliply by -1  0 0
-             //              0 -1 0
-             //              0  0 1.
-             fGm[i][j].fr[0] = -source.fGm[i][j].fr[0];
-             fGm[i][j].fr[1] = -source.fGm[i][j].fr[1];
-             fGm[i][j].fr[2] = -source.fGm[i][j].fr[2];
-             fGm[i][j].fr[3] = -source.fGm[i][j].fr[3];
-              fGm[i][j].fr[4] = -source.fGm[i][j].fr[4];
-              fGm[i][j].fr[5] = -source.fGm[i][j].fr[5];
-         } // end if i=1
-         // get angles from matrix up to a phase of 180 degrees.
-         oor     = atan2(fGm[i][j].fr[7],fGm[i][j].fr[8]);
-         if(oor<0.0) oor += 2.0*pi;
-         pr     = asin(fGm[i][j].fr[2]);
-         if(pr<0.0) pr += 2.0*pi;
-         qr     = atan2(fGm[i][j].fr[3],fGm[i][j].fr[0]);
-         if(qr<0.0) qr += 2.0*pi;
-         fGm[i][j].frx = oor;
-         fGm[i][j].fry = pr;
-         fGm[i][j].frz = qr;
-      } // end for j
+//     Copy the geometry data but change it to go between the ALICE
+// Global coordinate system to that used by the ITS tracking. 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 detectors are mounted upside down).
+//Begin_Html
+/*
+<img src="picts/ITS/AliITSgeomMatrix_T1.gif">
+*/
+//End_Html
+////////////////////////////////////////////////////////////////////////
+   Int_t    i,j,k,l,id[3];
+   Double_t R0[3][3],R1[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.}};
+
+   *this = source;  // copy everything
+   for(i=0;i<GetIndexMax();i++){
+       GetGeomMatrix(i)->GetIndex(id);
+       GetGeomMatrix(i)->GetMatrix(R0);
+       if(id[0]==1){ // Layer 1 is treated different from the others.
+          for(j=0;j<3;j++) for(k=0;k<3;k++){
+              R1[j][k] = 0.;
+              for(l=0;l<3;l++) R1[j][k] += A0[j][l]*R0[l][k];
+          } // end for j,k
+       }else{
+          for(j=0;j<3;j++) for(k=0;k<3;k++){
+              R1[j][k] = 0.;
+              for(l=0;l<3;l++) R1[j][k] += A1[j][l]*R0[l][k];
+          } // end for j,k
+       } // end if
+       GetGeomMatrix(i)->SetMatrix(R1);
    } // end for i
    } // end for i
+   this->fTrans = (this->fTrans && 0xfffe) + 1;  // set bit 0 true.
    return;
 }
    return;
 }
-//___________________________________________________________________________
-void AliITSgeom::Streamer(TBuffer &lRb){
-////////////////////////////////////////////////////////////////////////
-//     The default Streamer function "written by ROOT" doesn't write out
-// the arrays referenced by pointers. Therefore, a specific Streamer function
-// has to be written. This function should not be modified but instead added
-// on to so that older versions can still be read. The proper handling of
-// the version dependent streamer function hasn't been written do to the lack
-// of finding an example at the time of writing.
-////////////////////////////////////////////////////////////////////////
-   // Stream an object of class AliITSgeom.
-    Int_t i,j,k,n;
-
-
-    //   printf("AliITSgeomStreamer starting\n");
-   if (lRb.IsReading()) {
-      Version_t lRv = lRb.ReadVersion(); if (lRv) { }
-      TObject::Streamer(lRb);
-//      printf("AliITSgeomStreamer reading fNlayers\n");
-      lRb >> fNlayers;
-      if(fNlad!=0) delete[] fNlad;
-      if(fNdet!=0) delete[] fNdet;
-      fNlad = new Int_t[fNlayers];
-      fNdet = new Int_t[fNlayers];
-//      printf("AliITSgeomStreamer fNlad\n");
-      for(i=0;i<fNlayers;i++) lRb >> fNlad[i];
-//      printf("AliITSgeomStreamer fNdet\n");
-      for(i=0;i<fNlayers;i++) lRb >> fNdet[i];
-      if(fGm!=0){
-         for(i=0;i<fNlayers;i++) delete[] fGm[i];
-         delete[] fGm;
-      } // end if fGm!=0
-      fGm = new AliITSgeomS*[fNlayers];
-//      printf("AliITSgeomStreamer AliITSgeomS\n");
-      for(i=0;i<fNlayers;i++){
-         n     = fNlad[i]*fNdet[i];
-         fGm[i] = new AliITSgeomS[n];
-         for(j=0;j<n;j++){
-             lRb >> fGm[i][j].fShapeIndex;
-             lRb >> fGm[i][j].fx0;
-             lRb >> fGm[i][j].fy0;
-             lRb >> fGm[i][j].fz0;
-             lRb >> fGm[i][j].frx;
-             lRb >> fGm[i][j].fry;
-             lRb >> fGm[i][j].frz;
-             for(k=0;k<9;k++) lRb >> fGm[i][j].fr[k];
-         } // end for j
-      } // end for i
-      /*
-      if(fShape!=0){
-         delete fShape;
-      } // end if
-      printf("AliITSgeomStreamer reading fShape\n");
-      lRb >> fShape;
-      */
-      //if (fShape) fShape->Streamer(lRb);
-   } else {
-      lRb.WriteVersion(AliITSgeom::IsA());
-      TObject::Streamer(lRb);
-      lRb << fNlayers;
-      for(i=0;i<fNlayers;i++) lRb << fNlad[i];
-      for(i=0;i<fNlayers;i++) lRb << fNdet[i];
-      for(i=0;i<fNlayers;i++) for(j=0;j<fNlad[i]*fNdet[i];j++){
-         lRb << fGm[i][j].fShapeIndex;
-         lRb << fGm[i][j].fx0;
-         lRb << fGm[i][j].fy0;
-         lRb << fGm[i][j].fz0;
-         lRb << fGm[i][j].frx;
-         lRb << fGm[i][j].fry;
-         lRb << fGm[i][j].frz;
-         for(k=0;k<9;k++) lRb << fGm[i][j].fr[k];
-      } // end for i,j
-      // lRb << fShape;
-      //if (fShape) fShape->Streamer(lRb);
-   } // end if reading
-   //   printf("AliITSgeomStreamer Finished\n");
+//______________________________________________________________________
+Int_t AliITSgeom::GetNearest(const Double_t g[3],const Int_t lay){
+////////////////////////////////////////////////////////////////////////
+//      Finds the Detector (Module) that is nearest the point g [cm] in
+// ALICE Global coordinates. If layer !=0 then the search is restricted
+// to Detectors (Modules) in that particular layer.
+////////////////////////////////////////////////////////////////////////
+     Int_t    i,l,a,e,in=0;
+     Double_t d,dn=1.0e10;
+     Bool_t   t=lay!=0; // skip if lay = 0 default value check all layers.
+
+     for(i=0;i<fNmodules;i++){
+          if(t){GetModuleId(i,l,a,e);if(l!=lay) continue;}
+          if((d=GetGeomMatrix(i)->Distance2(g))<dn){
+               dn = d;
+               in = i;
+          } // end if
+     } // end for i
+     return in;
+}
+//______________________________________________________________________
+void AliITSgeom::GetNearest27(const Double_t g[3],Int_t n[27],const Int_t lay){
+////////////////////////////////////////////////////////////////////////
+//      Finds 27 Detectors (Modules) that are nearest the point g [cm] in
+// ALICE Global coordinates. If layer !=0 then the search is restricted
+// to Detectors (Modules) in that particular layer. The number 27 comes 
+// from including the nearest detector and all those around it (up, down,
+// left, right, forwards, backwards, and the corners).
+////////////////////////////////////////////////////////////////////////
+     Int_t    i,l,a,e,in[27]={0,0,0,0,0,0,0,0,0,
+                              0,0,0,0,0,0,0,0,0,
+                              0,0,0,0,0,0,0,0,0,};
+     Double_t d,dn[27]={1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,
+                        1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,
+                        1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,
+                        1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,
+                        1.0e10,1.0e10,1.0e10};
+     Bool_t   t=(lay!=0); // skip if lay = 0 default value check all layers.
+
+     for(i=0;i<fNmodules;i++){
+          if(t){GetModuleId(i,l,a,e);if(l!=lay) continue;}
+          for(a=0;a<27;a++){
+               d = GetGeomMatrix(i)->Distance2(g);
+               if(d<dn[a]){
+                   for(e=26;e>a;e--){dn[e] = dn[e-1];in[e] = in[e-1];}
+                   dn[a] = d; in[a] = i;
+               } // end if d<dn[i]
+          } // end for a
+     } // end for i
+     for(i=0;i<27;i++) n[i] = in[i];
 }
 }
+//----------------------------------------------------------------------