]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSgeom.cxx
Updated detailed geometry needed by FMD people for some studies
[u/mrichter/AliRoot.git] / ITS / AliITSgeom.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /*
17 $Log$
18 Revision 1.18  2001/08/24 21:06:37  nilsen
19 Added more documentation, fixed up some coding violations, and some
20 forward declorations.
21
22 Revision 1.17  2001/07/27 08:06:48  hristov
23 Use global gRandom generator (M.Ivanov)
24
25 Revision 1.16  2001/02/08 23:57:00  nilsen
26 Fixed up some informational printouts.
27
28 Revision 1.15  2001/02/07 20:23:21  nilsen
29 Fixed bug with HP and no unget in iostream.h. Now using putback instead.
30 Other changes and fixes also included.
31
32 Revision 1.14  2001/02/03 00:00:29  nilsen
33 New version of AliITSgeom and related files. Now uses automatic streamers,
34 set up for new formatted .det file which includes detector information.
35 Additional smaller modifications are still to come.
36
37 Revision 1.11  2000/10/02 16:32:35  barbera
38 Forward declaration added
39
40 Revision 1.4.4.15  2000/10/02 15:52:05  barbera
41 Forward declaration added
42
43 Revision 1.10  2000/09/05 14:25:50  nilsen
44 Made fixes for HP compiler. All function parameter default values placed
45 in .h file. Fixed the usual problem with HP compilers and the "for(Int_t i..."
46 business. Replaced casting (Double_t [3][3]) to (Double_t (*)[3]) for HP.
47 Lastly removed all "const" before function parameters which were 2 dim. arrays,
48 because on HP root generates some strange code (?). Thanks Peter for the
49 changes.
50
51 Revision 1.9  2000/08/29 20:19:03  nilsen
52 Removed dependency on structure AliITSeomS and replaced it with class
53 AliITSgeomMatrix. Added many new functions with many new arguments. Most
54 in the form of in line functions for speed.
55
56 Revision 1.4.4.6  2000/06/04 16:33:32  Nilsen
57 A restructured AliITSgeom class. Now used AliITSgeomMatrix.
58
59 Revision 1.4.4.5  2000/03/04 23:42:39  Nilsen
60 Updated the comments/documentations and improved the maintainability of the
61 code.
62
63 Revision 1.4.4.4  2000/03/02 21:27:07  Nilsen
64 Added two functions, SetByAngles and SetTrans.
65
66 Revision 1.4.4.3  2000/01/23 03:09:10  Nilsen
67 // fixed compiler warnings for new function LtLErrorMatrix(...)
68
69 Revision 1.4.4.2  2000/01/19 23:18:20  Nilsen
70 Added transformations of Error matrix to AliITSgeom and fixed some typos
71 in AliITS.h and AliITShitIndex.h
72
73 Revision 1.4.4.1  2000/01/12 19:03:32  Nilsen
74 This is the version of the files after the merging done in December 1999.
75 See the ReadMe110100.txt file for details
76
77 Revision 1.4  1999/10/15 07:03:20  fca
78 Fixed bug in GetModuleId(Int_t index,Int_t &lay,Int_t &lad, Int_t &det) and
79 a typo in the creator. aliroot need to be rerun to get a fixed geometry.
80
81 Revision 1.3  1999/10/04 15:20:12  fca
82 Correct syntax accepted by g++ but not standard for static members, remove minor warnings
83
84 Revision 1.2  1999/09/29 09:24:20  fca
85 Introduction of the Copyright and cvs Log
86
87 */
88
89 ///////////////////////////////////////////////////////////////////////
90 // ITS geometry manipulation routines.                               //
91 // Created April 15 1999.                                            //
92 // version: 0.0.0                                                    //
93 // By: Bjorn S. Nilsen                                               //
94 // version: 0.0.1                                                    //
95 // Updated May 27 1999.                                              //
96 // Added Cylindrical random and global based changes.               //
97 // Added  function PrintComparison.                                  //
98 ///////////////////////////////////////////////////////////////////////
99
100
101 ////////////////////////////////////////////////////////////////////////
102 //     The local coordinate system by, default, is show in the following
103 // figures. Also shown are the ladder numbering scheme.
104 //Begin_Html
105 /*
106 <img src="picts/ITS/AliITSgeomMatrix_L1.gif">
107 </pre>
108 <br clear=left>
109 <font size=+2 color=blue>
110 <p>This shows the relative geometry differences between the ALICE Global
111 coordinate system and the local detector coordinate system.
112 </font>
113 <pre>
114
115 <pre>
116 <img src="picts/ITS/its1+2_convention_front_5.gif">
117 </pre>
118 <br clear=left>
119 <font size=+2 color=blue>
120 <p>This shows the front view of the SPDs and the orientation of the local
121 pixel coordinate system. Note that the inner pixel layer has its y coordinate
122 in the opposite direction from all of the other layers.
123 </font>
124 <pre>
125
126 <pre>
127 <img src="picts/ITS/its3+4_convention_front_5.gif">
128 </pre>
129 <br clear=left>
130 <font size=+2 color=blue>
131 <p>This shows the front view of the SDDs and the orientation of the local
132 pixel coordinate system.
133 </font>
134 <pre>
135
136 <pre>
137 <img src="picts/ITS/its5+6_convention_front_5.gif">
138 </pre>
139 <br clear=left>
140 <font size=+2 color=blue>
141 <p>This shows the front view of the SSDs and the orientation of the local
142 pixel coordinate system.
143 </font>
144 <pre>
145 */
146 //End_Html
147 //
148 ////////////////////////////////////////////////////////////////////////
149
150 ////////////////////////////////////////////////////////////////////////
151 //
152 // version: 0
153 // Written by Bjorn S. Nilsen
154 //
155 // Data Members:
156 //
157 // Int_t fNlayers
158 //     The number of ITS layers for this geometry. By default this
159 //  is 6, but can be modified by the creator function if there are
160 // more layers defined.
161 //
162 // Int_t *fNlad
163 //     A pointer to an array fNlayers long containing the number of 
164 // ladders for each layer. This array is typically created and filled 
165 // by the AliITSgeom creator function.
166 //
167 // Int_t *fNdet
168 //     A pointer to an array fNlayers long containing the number of
169 // active detector volumes for each ladder. This array is typically
170 // created and filled by the AliITSgeom creator function.
171 //
172 // AliITSgeomMatrix *fGm
173 //     A pointer to an array of AliITSgeomMatrix classes. One element 
174 // per module (detector) in the ITS. AliITSgeomMatrix basicly contains
175 // all of the necessary information about the detector and it's coordinate
176 // transformations.
177 //
178 // TObjArray *fShape
179 //     A pointer to an array of TObjects containing the detailed shape
180 // information for each type of detector used in the ITS. For example
181 // I have created AliITSgeomSPD, AliITSgeomSDD, and AliITSgeomSSD as
182 // example structures, derived from TObjects, to hold the detector
183 // information. I would recommend that one element in each of these
184 // structures, that which describes the shape of the active volume,
185 // be one of the ROOT classes derived from TShape. In this way it would
186 // be easy to have the display program display the correct active
187 // ITS volumes. See the example classes AliITSgeomSPD, AliITSgeomSDD,
188 // and AliITSgeomSSD for a more detailed example.
189 ////////////////////////////////////////////////////////////////////////
190 #include <iostream.h>
191 #include <fstream.h>
192 #include <iomanip.h>
193 #include <stdlib.h>
194 #include <stdio.h>
195 #include <string.h>
196 #include <ctype.h>
197
198 #include <TSystem.h>
199 #include <TRandom.h>
200
201 #include "AliITSgeom.h"
202 #include "AliITSgeomSPD.h"
203 #include "AliITSgeomSDD.h"
204 #include "AliITSgeomSSD.h"
205
206 ClassImp(AliITSgeom)
207
208 //______________________________________________________________________
209 AliITSgeom::AliITSgeom(){
210     //     The default constructor for the AliITSgeom class. It, by default,
211     // sets fNlayers to zero and zeros all pointers.
212     // Do not allocate anything zero everything.
213
214     fTrans   = 0; // standard GEANT global/local coordinate system.
215     fNlayers = 0;
216     fNlad    = 0;
217     fNdet    = 0;
218     fGm      = 0;
219     fShape   = 0;
220     strcpy(fVersion,"test");
221     return;
222 }
223 //______________________________________________________________________
224 AliITSgeom::AliITSgeom(Int_t itype,Int_t nlayers,Int_t *nlads,Int_t *ndets,
225                        Int_t mods){
226     //     A simple constructor to set basic geometry class variables
227     // Inputs:
228     // Int_t itype   the type of transformation kept.
229     //               bit 0 => Standard GEANT
230     //               bit 1 => ITS tracking
231     //               bit 2 => A change in the coordinate system has been made.
232     //               others are still to be defined as needed.
233     // Int_t nlayers The number of ITS layers also set the size of the arrays
234     // Int_t *nlads  an array of the number of ladders for each layer. This
235     //               array must be nlayers long.
236     // Int_t *ndets  an array of the number of detectors per ladder for each
237     //               layer. This array must be nlayers long.
238     // Int_t mods    The number of modules. Typicaly the sum of all the 
239     //               detectors on every layer and ladder.
240     // Outputs:
241     // none
242     Int_t i;
243
244     fTrans    = itype;
245     fNlayers  = nlayers;
246     fNlad     = new Int_t[nlayers];
247     fNdet     = new Int_t[nlayers];
248     for(i=0;i<nlayers;i++){fNlad[i] = nlads[i];fNdet[i] = ndets[i];}
249     fNmodules = mods;
250     fGm       = new TObjArray(mods,0);
251     fShape    = new TObjArray(5); // default value
252     for(i=0;i<5;i++) fShape->AddAt(0,i);
253     strcpy(fVersion,"test");
254     return;
255 }
256 //______________________________________________________________________
257 void AliITSgeom::CreatMatrix(Int_t mod,Int_t lay,Int_t lad,Int_t det,
258                              AliITSDetector idet,const Double_t tran[3],
259                              const Double_t rot[10]){
260     // Given the translation vector tran[3] and the rotation matrix rot[1],
261     // this function creates and adds to the TObject Array fGm the
262     // AliITSgeomMatrix object.
263     // Inputs are:
264     // Int_t           mod     The module number. The location in TObjArray
265     // Int_t           lay     The layer where this module is
266     // Int_t           lad     On which ladder this module is
267     // Int_t           det     Which detector on this ladder this module is
268     // AliITSDetector idet     The type of detector see AliITSgeom.h
269     // Double_t       tran[3]  The translation vector
270     // Double_t       rot[10]  The rotation matrix.
271     // Outputs are:
272     //   none
273     // The rot[10] matrix is set up like:
274     /*   / rot[0]  rot[1]  rot[2] \
275     //  |  rot[3]  rot[4]  rot[5]  |
276     //   \ rot[6]  rot[7]  rot[8] /  if(rot[9]!=0) then the Identity matrix
277     // is used regardless of the values in rot[0]-rot[8].
278     */
279     Int_t id[3];
280     Double_t r[3][3] = {{1.0,0.0,0.0},{0.0,1.0,0.0},{0.0,0.0,1.0}};
281
282     if(fGm->At(mod)!=0) delete fGm->At(mod);
283     id[0] = lay; id[1] = lad; id[2] = det;
284     if(rot[9]!=0.0) { // null rotation
285         r[0][0] = rot[0]; r[0][1] = rot[1]; r[0][2] = rot[2];
286         r[1][0] = rot[3]; r[1][1] = rot[4]; r[1][2] = rot[5];
287         r[2][0] = rot[6]; r[2][1] = rot[7]; r[2][2] = rot[8];
288     } // end if
289     fGm->AddAt(new AliITSgeomMatrix(idet,id,r,tran),mod);
290 }
291 //______________________________________________________________________
292 AliITSgeom::~AliITSgeom(){
293     //     The destructor for the AliITSgeom class. If the arrays fNlad,
294     // fNdet, or fGm have had memory allocated to them, there pointer values
295     // are non zero, then this memory space is freed and they are set
296     // to zero. In addition, fNlayers is set to zero. The destruction of
297     // TObjArray fShape is, by default, handled by the TObjArray destructor.
298
299    if(fGm!=0){
300      //for(Int_t i=0;i<fNlayers;i++) delete fGm->At(i);
301       fGm->Delete();
302       delete fGm;
303    } // end if fGm!=0
304    if(fNlad!=0) delete[] fNlad;
305    if(fNdet!=0) delete[] fNdet;
306    fNlayers = 0;
307    fNlad    = 0;
308    fNdet    = 0;
309    fGm      = 0;
310    return;
311 }
312 //______________________________________________________________________
313 void AliITSgeom::ReadNewFile(const char *filename){
314     // It is generaly preferred to define the geometry in AliITSgeom
315     // directly from the GEANT geometry, see AliITSvPPRasymm.cxx for
316     // and example. Under some circumstances this may not be possible.
317     // This function will read in a formatted file for all of the
318     // information needed to define the geometry in AliITSgeom.
319     // Unlike the older file format, this file may contain comments
320     // and the order of the data does not need to be completely
321     // respected. A file can be created using the function WriteNewFile
322     // defined below.
323     // Inputs are:
324     // const char *filename The file name of the file to be read in.
325     // Outputs are:
326     //  none
327     Int_t ncmd=9;
328     const char *cmda[]={"Version"        ,"fTrans"  ,"fNmodules",
329                         "fNlayers"       ,"fNladers","fNdetectors",
330                         "fNDetectorTypes","fShape"  ,"Matrix"};
331     Int_t i,j,lNdetTypes,ldet;
332     char cmd[20],c;
333     AliITSgeomSPD *spd;
334     AliITSgeomSDD *sdd;
335     AliITSgeomSSD *ssd;
336     AliITSgeomMatrix *m;
337     ifstream *fp;
338     char *filtmp;
339
340     filtmp = gSystem->ExpandPathName(filename);
341     cout << "AliITSgeom, Reading New .det file " << filtmp << endl;
342     fp = new ifstream(filtmp,ios::in);  // open file to write
343     while(fp->get(c)!=NULL){ // for ever loop
344         if(c==' ') continue; // remove blanks
345         if(c=='\n') continue;
346         if(c=='#' || c=='!'){for(;fp->get(c)!=NULL,c!='\n';); continue;}
347         if(c=='/'){
348             fp->get(c);{
349                 if(c=='/'){for(;fp->get(c)!=NULL,c!='\n';);continue;}
350                 if(c=='*'){
351                 NotYet:
352                     for(;fp->get(c)!=NULL,c!='*';);
353                     fp->get(c);{
354                         if(c=='/') continue;
355                         goto NotYet;
356                     } //
357                 } // end if c=='*'
358             } // end if second /
359         } // end if first /
360         fp->putback(c);
361         *fp >> cmd;
362         for(i=0;i<ncmd;i++) if(strcmp(cmd,cmda[i])==0) break;
363         switch (i){
364         case 0:   // Version
365             *fp >> fVersion;
366             break;
367         case 1:  // fTrans
368             *fp >> fTrans;
369             break;
370         case 2:  // fNModules
371             *fp >> fNmodules;
372             if(fGm!=0){
373                 for(j=0;j<fGm->GetEntriesFast();j++) delete fGm->At(j);
374                 delete fGm;
375             } // end if
376             fGm = new TObjArray(fNmodules,0);
377             break;
378         case 3:  // fNlayers
379             *fp >> fNlayers;
380             if(fNlad!=0) delete fNlad;
381             if(fNdet!=0) delete fNdet;
382             fNlad = new Int_t[fNlayers];
383             fNdet = new Int_t[fNlayers];
384             break;
385         case 4:  // fNladers
386             for(j=0;j<fNlayers;j++) *fp >> fNlad[j];
387             break;
388         case 5:  // fNdetectors
389             for(j=0;j<fNlayers;j++) *fp >> fNdet[j];
390             break;
391         case 6:  // fNDetectorTypes
392             *fp >> lNdetTypes;
393             if(fShape!=0){
394                 for(j=0;j<fShape->GetEntriesFast();j++) delete fShape->At(j);
395                 delete fShape;
396             } // end if
397             fShape = new TObjArray(lNdetTypes,0);
398             break;
399         case 7:  // fShape
400             *fp >> ldet;
401             if(fShape==0) fShape = new TObjArray(5,0);
402             switch (ldet){
403             case kSPD :
404                 ReSetShape(ldet,(TObject*) new AliITSgeomSPD());
405                 spd = (AliITSgeomSPD*) (fShape->At(ldet));
406                 *fp >> *spd;
407                 spd = 0;
408                 break;
409             case kSDD :
410                 ReSetShape(ldet,(TObject*) new AliITSgeomSDD());
411                 sdd = (AliITSgeomSDD*) (fShape->At(ldet));
412                 *fp >> *sdd;
413                 sdd = 0;
414                 break;
415             case kSSD : case kSSDp :
416                 ReSetShape(ldet,(TObject*) new AliITSgeomSSD());
417                 ssd = (AliITSgeomSSD*) (fShape->At(ldet));
418                 *fp >> *ssd;
419                 ssd = 0;
420                 break;
421             default:
422                 Error("ReadNewFile","Unknown fShape type number=%d c=%c",ldet,c);
423                 for(;fp->get(c)==NULL,c!='\n';); // skip to end of line.
424                 break;
425             } // end switch
426             break;
427         case 8:  // Matrix
428             *fp >> ldet;
429             if(fGm==0) fGm = new TObjArray(2270,0);
430             if(fGm->At(ldet)!=0) delete (fGm->At(ldet));
431             fGm->AddAt((TObject*)new AliITSgeomMatrix(),ldet);
432             m = (AliITSgeomMatrix*) fGm->At(ldet);
433             *fp >> *m;
434             m = 0;
435             break;
436         default:
437             Error("ReadNewFile","Data line i=%d c=%c",i,c);
438             for(;fp->get(c)==NULL,c!='\n';); // skip this line
439             break;
440         } // end switch i
441     } // end while
442     delete fp;
443
444     return;
445 }
446 //______________________________________________________________________
447 void AliITSgeom::WriteNewFile(const char *filename){
448     // Writes AliITSgeom, AliITSgeomMatrix, and the defined AliITSgeomS*D
449     // classes to a file in a format that is more readable and commendable.
450     // Inputs are:
451     // const char *filename The file name of the file to be write to.
452     // Outputs are:
453     //  none
454     ofstream *fp;
455     Int_t i;
456     char *filtmp;
457
458     filtmp = gSystem->ExpandPathName(filename);
459     cout << "AliITSgeom, Writing New .det file " << filtmp << endl;
460     fp = new ofstream(filtmp,ios::out);  // open file to write
461     *fp << "//Comment lines begin with two //, one #, or one !" << endl;
462     *fp << "#Blank lines are skipped including /* and */ sections." << endl;
463     *fp << "!and, in principle the order of the lines is not important" <<endl;
464     *fp << "/* In AliITSgeom.h are defined an enumerated type called" << endl;
465     *fp << " AliITSDetectors These are kSPD=" << (Int_t) kSPD ;
466     *fp << ", kSDD=" << (Int_t) kSDD << ", kSSD=" << (Int_t) kSSD;
467     *fp << ", kSSDp=" << (Int_t) kSSDp << ", and kSDDp=" << (Int_t) kSDDp;
468     *fp << "*/" << endl;
469     *fp << "Version " << fVersion << endl;//This should be consistent with the
470                                            // geometry version.
471     *fp << "fTrans " << fTrans << endl;
472     *fp << "fNmodules " << fNmodules << endl;
473     *fp << "fNlayers " << fNlayers << endl;
474     *fp << "fNladers ";
475     for(i=0;i<fNlayers;i++) *fp << fNlad[i] << " ";
476     *fp << endl;
477     *fp << "fNdetectors ";
478     for(i=0;i<fNlayers;i++) *fp << fNdet[i] << " ";
479     *fp << endl;
480     *fp << "fNDetectorTypes " << fShape->GetEntriesFast() << endl;
481     for(i=0;i<fShape->GetEntriesFast();i++){
482         if(!IsShapeDefined(i)) continue; // only print out used shapes.
483         switch (i){
484         case kSPD :
485             *fp << "fShape " << (Int_t) kSPD << " ";
486             *fp << *((AliITSgeomSPD*)(fShape->At(i)));
487             break;
488         case kSDD :
489             *fp << "fShape " << (Int_t) kSDD << " ";
490             *fp << *((AliITSgeomSDD*)(fShape->At(i)));
491             break;
492         case kSSD : case kSSDp :
493             *fp << "fShape " << i << " ";
494             *fp << *((AliITSgeomSSD*)(fShape->At(i)));
495             break;
496         default:
497             Error("AliITSgeom::WriteNewFile","Unknown Shape value");
498         } // end switch (i)
499     } // end for i
500     for(i=0;i<fNmodules;i++){
501         *fp << "Matrix " << i << " ";
502         *fp << *GetGeomMatrix(i);
503     } // end for i
504     *fp << "//End of File" << endl;;
505
506     delete fp;
507     return;
508 }
509 //______________________________________________________________________
510 AliITSgeom::AliITSgeom(const char *filename){
511     //     The constructor for the AliITSgeom class. All of the data to fill
512     // this structure is read in from the file given my the input filename.
513     // Inputs are:
514     // const char *filename The file name of the file to be read in.
515     // Outputs are:
516     //  none
517     FILE     *pf=0;
518     Int_t    i,lm=0,id[3];
519     Int_t    l,a,d;
520     Float_t  x,y,z,o,p,q,r,s,t;
521     Double_t rot6[6],tran[3];
522     char     buf[200],*buff=0; // input character buffer;
523     char *filtmp;
524
525     filtmp = gSystem->ExpandPathName(filename);
526     cout << "AliITSgeom reading old .det file " << filtmp << endl;
527     fShape = 0;
528     strcpy(fVersion,"DefauleV5");
529     pf = fopen(filtmp,"r");
530
531     fNlayers = 6; // set default number of ladders
532  TryAgain:
533     fNlad    = new Int_t[fNlayers];
534     fNdet    = new Int_t[fNlayers];
535     fNmodules = 0;
536     // find the number of ladders and detectors in this geometry.
537     for(i=0;i<fNlayers;i++){fNlad[i]=fNdet[i]=0;} // zero out arrays
538     while(fgets(buf,200,pf)!=NULL){ // for ever loop
539         for(i=0;i<200;i++)if(buf[i]!=' '){ // remove blank spaces.
540             buff = &(buf[i]);
541             break;
542         } // end for i
543         // remove blank lines and comments.
544         if(buff[0]=='\n'||buff[0]=='#'||buff[0]=='!'||
545            (buff[0]=='/'&&buff[1]=='/')) continue;
546         if(isalpha(buff[0])) { // must be the new file formated file.
547             fclose(pf);
548             delete[] fNlad;delete[] fNdet;
549             ReadNewFile(filename);
550             return;
551         } // end if isalpha(buff[0])
552         sscanf(buff,"%d %d %d %f %f %f %f %f %f %f %f %f",
553                &l,&a,&d,&x,&y,&z,&o,&p,&q,&r,&s,&t);
554         if(l>lm) lm = l;
555         if(l<1 || l>fNlayers) {
556             printf("error in file %s layer=%d min. is 1 max is %d\n",
557                    filename,l,fNlayers);
558             continue;
559         }// end if l
560         fNmodules++;
561         if(l<=fNlayers&&fNlad[l-1]<a) fNlad[l-1] = a;
562         if(l<=fNlayers&&fNdet[l-1]<d) fNdet[l-1] = d;
563     } // end while ever loop
564     if(lm>fNlayers){
565         delete[] fNlad;
566         delete[] fNdet;
567         fNlayers = lm;
568         goto TryAgain;
569     } // end if lm>fNlayers
570     // counted the number of ladders and detectors now allocate space.
571     fGm = new TObjArray(fNmodules,0);
572
573     // Set up Shapes for a default configuration of 6 layers.
574     fTrans   = 0; // standard GEANT global/local coordinate system.
575     // prepare to read in transforms
576     lm = 0; // reuse lm as counter of modules.
577     rewind(pf); // start over reading file
578     while(fgets(buf,200,pf)!=NULL){ // for ever loop
579         for(i=0;i<200;i++)if(buf[i]!=' '){ // remove blank spaces.
580             buff = &(buf[i]);
581             break;
582         } // end for i
583         // remove blank lines and comments.
584         if(buff[0]=='\n'||buff[0]=='#'||buff[0]=='!'||
585            (buff[0]=='/'&&buff[1]=='/')) continue;
586         x = y = z = o = p = q = r = s = t = 0.0;
587         sscanf(buff,"%d %d %d %f %f %f %f %f %f %f %f %f",
588                &l,&a,&d,&x,&y,&z,&o,&p,&q,&r,&s,&t);
589         if(l<1 || l>fNlayers) {
590             printf("error in file %s layer=%d min. is 1 max is %d/n",
591                    filename,l,fNlayers);
592             continue;
593         }// end if l
594         id[0] = l;id[1] = a;id[2] = d;
595         tran[0] = tran[1] = tran[2]  = 0.0;
596         tran[0] = (Double_t)x;tran[1] = (Double_t)y;tran[2] = (Double_t)z;
597         rot6[0] = rot6[1] = rot6[2] = rot6[3] = rot6[4] = rot6[5] =0.0;
598         rot6[0] = (Double_t)o;rot6[1] = (Double_t)p;rot6[2] = (Double_t)q;
599         rot6[3] = (Double_t)r;rot6[4] = (Double_t)s;rot6[5] = (Double_t)t;
600         switch (l){
601         case 1: case 2: // layer 1 or2 SPD
602             fGm->AddAt(new AliITSgeomMatrix(rot6,kSPD,id,tran),lm++);
603             break;
604         case 3: case 4: // layer 3 or 4 SDD
605             fGm->AddAt(new AliITSgeomMatrix(rot6,kSDD,id,tran),lm++);
606             break;
607         case 5: case 6: // layer 5 or 6 SSD
608             fGm->AddAt(new AliITSgeomMatrix(rot6,kSSD,id,tran),lm++);
609             break;
610         } // end switch
611     } // end while ever loop
612     fclose(pf);
613 }
614 //______________________________________________________________________
615 AliITSgeom::AliITSgeom(AliITSgeom &source){
616     //     The copy constructor for the AliITSgeom class. It calls the
617     // = operator function. See the = operator function for more details.
618     // Inputs are:
619     // AliITSgeom &source  The AliITSgeom class with which to make this
620     //                     a copy of.
621     // Outputs are:
622     // none.
623
624     *this = source;  // Just use the = operator for now.
625     return;
626 }
627 //______________________________________________________________________
628 AliITSgeom& AliITSgeom::operator=(AliITSgeom &source){
629     //     The = operator function for the AliITSgeom class. It makes an
630     // independent copy of the class in such a way that any changes made
631     // to the copied class will not affect the source class in any way.
632     // This is required for many ITS alignment studies where the copied
633     // class is then modified by introducing some misalignment.
634     // Inputs are:
635     // AliITSgeom &source  The AliITSgeom class with which to make this
636     //                     a copy of.
637     // Outputs are:
638     // return  *this       The a new copy of source.
639    Int_t i;
640
641    if(this == &source) return *this; // don't assign to ones self.
642
643    // if there is an old structure allocated delete it first.
644    if(this->fGm != 0){
645       for(i=0;i<this->fNmodules;i++) delete this->fGm->At(i);
646       delete this->fGm;
647    } // end if fGm != 0 
648    if(fNlad != 0) delete[] fNlad;
649    if(fNdet != 0) delete[] fNdet;
650
651    this->fTrans    = source.fTrans;
652    this->fNmodules = source.fNmodules;
653    this->fNlayers = source.fNlayers;
654    this->fNlad = new Int_t[fNlayers];
655    for(i=0;i<this->fNlayers;i++) this->fNlad[i] = source.fNlad[i];
656    this->fNdet = new Int_t[fNlayers];
657    for(i=0;i<this->fNlayers;i++) this->fNdet[i] = source.fNdet[i];
658    this->fShape = new TObjArray(*(source.fShape));//This does not make a proper copy.
659    this->fGm = new TObjArray(this->fNmodules,0);
660    for(i=0;i<this->fNmodules;i++){
661        this->fGm->AddAt(new AliITSgeomMatrix(*(
662            (AliITSgeomMatrix*)(source.fGm->At(i)))),i);
663    } // end for i
664    return *this;
665 }
666 //______________________________________________________________________
667 Int_t AliITSgeom::GetModuleIndex(Int_t lay,Int_t lad,Int_t det){
668     //      This routine computes the module index number from the layer,
669     // ladder, and detector numbers. The number of ladders and detectors
670     // per layer is determined when this geometry package is constructed,
671     // see AliITSgeom(const char *filename) for specifics.
672     // Inputs are:
673     // Int_t lay  The layer number. Starting from 1.
674     // Int_t lad  The ladder number. Starting from 1.
675     // Int_t det  The detector number. Starting from 1.
676     // Outputs are:
677     // return the module index number, starting from zero.
678     Int_t i,j,k,id[3];
679
680     i = fNdet[lay-1] * (lad-1) + det - 1;
681     j = 0;
682     for(k=0;k<lay-1;k++) j += fNdet[k]*fNlad[k];
683     i = i+j;
684     GetGeomMatrix(i)->GetIndex(id);
685     if(id[0]==lay&&id[1]==lad&&id[2]==det) return i;
686     // Array of modules fGm is not in expected order. Search for this index
687     for(i=0;i<fNmodules;i++){
688         GetGeomMatrix(i)->GetIndex(id);
689         if(id[0]==lay&&id[1]==lad&&id[2]==det) return i;
690     } // end for i
691     // This layer ladder and detector combination does not exist return -1.
692     return -1;
693 }
694 //______________________________________________________________________
695 void AliITSgeom::GetModuleId(Int_t index,Int_t &lay,Int_t &lad,Int_t &det){
696     //      This routine computes the layer, ladder and detector number 
697     // given the module index number. The number of ladders and detectors
698     // per layer is determined when this geometry package is constructed,
699     // see AliITSgeom(const char *filename) for specifics.
700     // Inputs are:
701     // Int_t index  The module index number, starting from zero.
702     // Outputs are:
703     // Int_t lay    The layer number. Starting from 1.
704     // Int_t lad    The ladder number. Starting from 1.
705     // Int_t det    The detector number. Starting from 1.
706     Int_t id[3];
707
708     GetGeomMatrix(index)->GetIndex(id);
709     lay = id[0]; lad = id[1]; det = id[2];
710     return;
711
712     // The old way kept for posterity.
713 /*
714     Int_t i,j,k;
715     j = 0;
716     for(k=0;k<fNlayers;k++){
717         j += fNdet[k]*fNlad[k];
718         if(j>index)break;
719     } // end for k
720     lay = k+1;
721     i = index -j + fNdet[k]*fNlad[k];
722     j = 0;
723     for(k=0;k<fNlad[lay-1];k++){
724         j += fNdet[lay-1];
725         if(j>i)break;
726     } // end for k
727     lad = k+1;
728     det = 1+i-fNdet[lay-1]*k;
729     return;
730 */
731 }
732 //______________________________________________________________________
733 Int_t AliITSgeom::GetStartDet(Int_t dtype){
734     // returns the starting module index value for a give type of detector id.
735     // This assumes that the detector types are different on different layers
736     // and that they are not mixed up.
737     // Inputs are:
738     // Int_t dtype A detector type number. 0 for SPD, 1 for SDD, and 2 for SSD.
739     // outputs:
740     // return the module index for the first occurance of that detector type.
741
742     switch(dtype){
743     case 0:
744         return GetModuleIndex(1,1,1);
745         break;
746     case 1:
747         return GetModuleIndex(3,1,1);
748         break;
749     case 2:
750         return GetModuleIndex(5,1,1);
751         break;
752     default:
753         Warning("GetStartDet","undefined detector type %d",dtype);
754         return 0;
755     } // end switch
756
757     Warning("GetStartDet","undefined detector type %d",dtype);
758     return 0;
759 }
760 //______________________________________________________________________
761 Int_t AliITSgeom::GetLastDet(Int_t dtype){
762     // returns the last module index value for a give type of detector id.
763     // This assumes that the detector types are different on different layers
764     // and that they are not mixed up.
765     // Inputs are:
766     // Int_t dtype A detector type number. 0 for SPD, 1 for SDD, and 2 for SSD.
767     // outputs are:
768     // return the module index for the last occurance of that detector type.
769
770     switch(dtype){
771     case 0:
772         return GetLastSPD();
773         break;
774     case 1:
775         return GetLastSDD();
776         break;
777     case 2:
778         return GetLastSSD();
779         break;
780     default:
781         Warning("GetLastDet","undefined detector type %d",dtype);
782         return 0;
783     } // end switch
784
785     Warning("GetLastDet","undefined detector type %d",dtype);
786     return 0;
787 }
788 //______________________________________________________________________
789 void AliITSgeom::PrintComparison(FILE *fp,AliITSgeom *other){
790     //     This function was primarily created for diagnostic reasons. It
791     // print to a file pointed to by the file pointer fp the difference
792     // between two AliITSgeom classes. The format of the file is basicly,
793     // define d? to be the difference between the same element of the two
794     // classes. For example dfrx = this->GetGeomMatrix(i)->frx 
795     // - other->GetGeomMatrix(i)->frx.
796     // if(at least one of dfx0, dfy0, dfz0,dfrx,dfry,dfrz are non zero) then
797     // print layer ladder detector dfx0 dfy0 dfz0 dfrx dfry dfrz
798     // if(at least one of the 9 elements of dfr[] are non zero) then print
799     // layer ladder detector dfr[0] dfr[1] dfr[2]
800     //                       dfr[3] dfr[4] dfr[5]
801     //                       dfr[6] dfr[7] dfr[8]
802     // Only non zero values are printed to save space. The differences are
803     // typical written to a file because there are usually a lot of numbers
804     // printed out and it is usually easier to read them in some nice editor
805     // rather than zooming quickly past you on a screen. fprintf is used to
806     // do the printing. The fShapeIndex difference is not printed at this time.
807     // Inputs are:
808     // FILE *fp           A file pointer to an opened file for writing in which
809     //                    the results of the comparison will be written.
810     // AliITSgeom *other  The other AliITSgeom class to which this one is
811     //                    being compared.
812     // outputs are:
813     // none
814     Int_t    i,j,idt[3],ido[3];
815     Double_t tt[3],to[3];  // translation
816     Double_t rt[3],ro[3];  // phi in radians
817     Double_t mt[3][3],mo[3][3]; // matrixes
818     AliITSgeomMatrix *gt,*go;
819     Bool_t   t;
820
821     for(i=0;i<this->fNmodules;i++){
822         gt  =  this->GetGeomMatrix(i);
823         go  = other->GetGeomMatrix(i);
824         gt->GetIndex(idt);
825         go->GetIndex(ido);
826         t = kFALSE;
827         for(i=0;i<3;i++) t = t&&idt[i]!=ido[i];
828         if(t) fprintf(fp,"%4.4d %1.1d %2.2d %2.2d %1.1d %2.2d %2.2d\n",i,
829                       idt[0],idt[1],idt[2],ido[0],ido[1],ido[2]);
830         gt->GetTranslation(tt);
831         go->GetTranslation(to);
832         gt->GetAngles(rt);
833         go->GetAngles(ro);
834         t = kFALSE;
835         for(i=0;i<3;i++) t = t&&tt[i]!=to[i];
836         if(t) fprintf(fp,"%1.1d %2.2d %2.2d dTrans=%f %f %f drot=%f %f %f\n",
837                       idt[0],idt[1],idt[2],
838                       tt[0]-to[0],tt[1]-to[1],tt[2]-to[2],
839                       rt[0]-ro[0],rt[1]-ro[1],rt[2]-ro[2]);
840         t = kFALSE;
841         gt->GetMatrix(mt);
842         go->GetMatrix(mo);
843         for(i=0;i<3;i++)for(j=0;j<3;j++)  t = mt[i][j] != mo[i][j];
844         if(t){
845             fprintf(fp,"%1.1d %2.2d %2.2d dfr= %e %e %e\n",
846                     idt[0],idt[1],idt[2],
847                     mt[0][0]-mo[0][0],mt[0][1]-mo[0][1],mt[0][2]-mo[0][2]);
848             fprintf(fp,"        dfr= %e %e %e\n",
849                     mt[1][0]-mo[1][0],mt[1][1]-mo[1][1],mt[1][2]-mo[1][2]);
850             fprintf(fp,"        dfr= %e %e %e\n",
851                     mt[2][0]-mo[2][0],mt[2][1]-mo[2][1],mt[2][2]-mo[2][2]);
852         } // end if t
853     } // end for i
854     return;
855 }
856 //______________________________________________________________________
857 void AliITSgeom::PrintData(FILE *fp,Int_t lay,Int_t lad,Int_t det){
858     //     This function prints out the coordinate transformations for
859     // the particular detector defined by layer, ladder, and detector
860     // to the file pointed to by the File pointer fp. fprintf statements
861     // are used to print out the numbers. The format is
862     // layer ladder detector Trans= fx0 fy0 fz0 rot= frx fry frz 
863     // Shape=fShapeIndex
864     //                         dfr= fr[0] fr[1] fr[2]
865     //                         dfr= fr[3] fr[4] fr[5]
866     //                         dfr= fr[6] fr[7] fr[8]
867     // By indicating which detector, some control over the information 
868     // is given to the user. The output it written to the file pointed
869     // to by the file pointer fp. This can be set to stdout if you want.
870     // Inputs are:
871     // FILE *fp           A file pointer to an opened file for writing in which
872     //                    the results of the comparison will be written.
873     // Int_t lay          The layer number. Starting from 1.
874     // Int_t lad          The ladder number. Starting from 1.
875     // Int_t det          The detector number. Starting from 1.
876     // outputs are:
877     // none
878     AliITSgeomMatrix *gt;
879     Double_t t[3],r[3],m[3][3];
880
881     gt = this->GetGeomMatrix(GetModuleIndex(lay,lad,det));
882     gt->GetTranslation(t);
883     gt->GetAngles(r);
884     fprintf(fp,"%1.1d %2.2d %2.2d Trans=%f %f %f rot=%f %f %f Shape=%d\n",
885             lay,lad,det,t[0],t[1],t[2],r[0],r[1],r[2],
886             gt->GetDetectorIndex());
887     gt->GetMatrix(m);
888     fprintf(fp,"        dfr= %e %e %e\n",m[0][0],m[0][1],m[0][2]);
889     fprintf(fp,"        dfr= %e %e %e\n",m[1][0],m[1][1],m[1][2]);
890     fprintf(fp,"        dfr= %e %e %e\n",m[2][0],m[2][1],m[2][2]);
891     return;
892 }
893 //______________________________________________________________________
894 ofstream & AliITSgeom::PrintGeom(ofstream &rb){
895     //     Stream out an object of class AliITSgeom to standard output.
896     // Intputs are:
897     // ofstream &rb    The output streaming buffer.
898     // Outputs are:
899     // ofstream &rb    The output streaming buffer.
900     Int_t i;
901
902     rb.setf(ios::scientific);
903     rb << fTrans << " ";
904     rb << fNmodules << " ";
905     rb << fNlayers << " ";
906     for(i=0;i<fNlayers;i++) rb << fNlad[i] << " ";
907     for(i=0;i<fNlayers;i++) rb << fNdet[i] << "\n";
908     for(i=0;i<fNmodules;i++) {
909         rb <<setprecision(16) << *(GetGeomMatrix(i)) << "\n";
910     } // end for i
911     return rb;
912 }
913 //______________________________________________________________________
914 ifstream & AliITSgeom::ReadGeom(ifstream &rb){
915     //     Stream in an object of class AliITSgeom from standard input.
916     // Intputs are:
917     // ifstream &rb    The input streaming buffer.
918     // Outputs are:
919     // ifstream &rb    The input streaming buffer.
920     Int_t i;
921
922     fNlad = new Int_t[fNlayers];
923     fNdet = new Int_t[fNlayers];
924     if(fGm!=0){
925         for(i=0;i<fNmodules;i++) delete GetGeomMatrix(i);
926         delete fGm;
927     } // end if fGm!=0
928
929     rb >> fTrans >> fNmodules >> fNlayers;
930     fNlad = new Int_t[fNlayers];
931     fNdet = new Int_t[fNlayers];
932     for(i=0;i<fNlayers;i++) rb >> fNlad[i];
933     for(i=0;i<fNlayers;i++) rb >> fNdet[i];
934     fGm = new TObjArray(fNmodules,0);
935     for(i=0;i<fNmodules;i++){
936         fGm->AddAt(new AliITSgeomMatrix,i);
937         rb >> *(GetGeomMatrix(i));
938     } // end for i
939     return rb;
940 }
941 //______________________________________________________________________
942 //     The following routines modify the transformation of "this"
943 // geometry transformations in a number of different ways.
944 //______________________________________________________________________
945 void AliITSgeom::GlobalChange(const Float_t *tran,const Float_t *rot){
946     //     This function performs a Cartesian translation and rotation of
947     // the full ITS from its default position by an amount determined by
948     // the three element arrays tran and rot. If every element
949     // of tran and rot are zero then there is no change made
950     // the geometry. The change is global in that the exact same translation
951     // and rotation is done to every detector element in the exact same way.
952     // The units of the translation are those of the Monte Carlo, usually cm,
953     // and those of the rotation are in radians. The elements of tran
954     // are tran[0] = x, tran[1] = y, and tran[2] = z.
955     // The elements of rot are rot[0] = rx, rot[1] = ry, and
956     // rot[2] = rz. A change in x will move the hole ITS in the ALICE
957     // global x direction, the same for a change in y. A change in z will
958     // result in a translation of the ITS as a hole up or down the beam line.
959     // A change in the angles will result in the inclination of the ITS with
960     // respect to the beam line, except for an effective rotation about the
961     // beam axis which will just rotate the ITS as a hole about the beam axis.
962     // Intputs are:
963     // Float_t *tran   A 3 element array representing the global translations.
964     //                 the elements are x,y,z in cm.
965     // Float_t *rot    A 3 element array representing the global rotation
966     //                 angles about the three axis x,y,z in radians
967     // Outputs are:
968     // none.
969     Int_t    i,j;
970     Double_t t[3],r[3];
971     AliITSgeomMatrix *g;
972
973     fTrans = (fTrans && 0xfffd) + 2;  // set bit 1 true.
974     for(i=0;i<fNmodules;i++){
975         g = this->GetGeomMatrix(i);
976         g->GetTranslation(t);
977         g->GetAngles(r);
978         for(j=0;j<3;j++){
979             t[j] += tran[j];
980             r[j] += rot[j];
981         } // end for j
982         g->SetTranslation(t);
983         g->SetAngles(r);
984     } // end for i
985     return;
986 }
987 //______________________________________________________________________
988 void AliITSgeom::GlobalCylindericalChange(const Float_t *tran,
989                                           const Float_t *rot){
990     //     This function performs a cylindrical translation and rotation of
991     // each ITS element by a fixed about in radius, rphi, and z from its
992     // default position by an amount determined by the three element arrays
993     // tran and rot. If every element of tran and
994     // rot are zero then there is no change made the geometry. The
995     // change is global in that the exact same distance change in translation
996     // and rotation is done to every detector element in the exact same way.
997     // The units of the translation are those of the Monte Carlo, usually cm,
998     // and those of the rotation are in radians. The elements of tran
999     // are tran[0] = r, tran[1] = rphi, and tran[2] = z.
1000     // The elements of rot are rot[0] = rx, rot[1] = ry, and
1001     // rot[2] = rz. A change in r will results in the increase of the
1002     // radius of each layer by the same about. A change in rphi will results in
1003     // the rotation of each layer by a different angle but by the same
1004     // circumferential distance. A change in z will result in a translation
1005     // of the ITS as a hole up or down the beam line. A change in the angles
1006     // will result in the inclination of the ITS with respect to the beam
1007     // line, except for an effective rotation about the beam axis which will
1008     // just rotate the ITS as a hole about the beam axis.
1009     // Intputs are:
1010     // Float_t *tran   A 3 element array representing the global translations.
1011     //                 the elements are r,theta,z in cm/radians.
1012     // Float_t *rot    A 3 element array representing the global rotation
1013     //                 angles about the three axis x,y,z in radians
1014     // Outputs are:
1015     // none.
1016     Int_t    i,j;
1017     Double_t t[3],ro[3],r,r0,phi,rphi;
1018     AliITSgeomMatrix *g;
1019
1020     fTrans = (fTrans && 0xfffd) + 2;  // set bit 1 true.
1021     for(i=0;i<fNmodules;i++){
1022         g = this->GetGeomMatrix(i);
1023         g->GetTranslation(t);
1024         g->GetAngles(ro);
1025         r = r0= TMath::Hypot(t[1],t[0]);
1026         phi   = TMath::ATan2(t[1],t[0]);
1027         rphi  = r0*phi;
1028         r    += tran[0];
1029         rphi += tran[1];
1030         phi   = rphi/r0;
1031         t[0]  = r*TMath::Cos(phi);
1032         t[1]  = r*TMath::Sin(phi);
1033         t[2] += tran[2];
1034         for(j=0;j<3;j++){
1035             ro[j] += rot[j];
1036         } // end for j
1037         g->SetTranslation(t);
1038         g->SetAngles(ro);
1039     } // end for i
1040     return;
1041 }
1042 //______________________________________________________________________
1043 void AliITSgeom::RandomChange(const Float_t *stran,const Float_t *srot){
1044     //     This function performs a Gaussian random displacement and/or
1045     // rotation about the present global position of each active
1046     // volume/detector of the ITS. The sigma of the random displacement
1047     // is determined by the three element array stran, for the
1048     // x y and z translations, and the three element array srot,
1049     // for the three rotation about the axis x y and z.
1050     // Intputs are:
1051     // Float_t *stran  A 3 element array representing the global translations
1052     //                 variances. The elements are x,y,z in cm.
1053     // Float_t *srot   A 3 element array representing the global rotation
1054     //                 angles variances about the three axis x,y,z in radians.
1055     // Outputs are:
1056     // none.
1057     Int_t    i,j;
1058     Double_t t[3],r[3];
1059     AliITSgeomMatrix *g;
1060
1061     fTrans = (fTrans && 0xfffd) + 2;  // set bit 1 true.
1062     for(i=0;i<fNmodules;i++){
1063         g = this->GetGeomMatrix(i);
1064         g->GetTranslation(t);
1065         g->GetAngles(r);
1066         for(j=0;j<3;j++){
1067             t[j] += gRandom->Gaus(0.0,stran[j]);
1068             r[j] += gRandom->Gaus(0.0, srot[j]);
1069         } // end for j
1070         g->SetTranslation(t);
1071         g->SetAngles(r);
1072     } // end for i
1073     return;
1074 }
1075 //______________________________________________________________________
1076 void AliITSgeom::RandomCylindericalChange(const Float_t *stran,
1077                                           const Float_t *srot){
1078     //     This function performs a Gaussian random displacement and/or
1079     // rotation about the present global position of each active
1080     // volume/detector of the ITS. The sigma of the random displacement
1081     // is determined by the three element array stran, for the
1082     // r rphi and z translations, and the three element array srot,
1083     // for the three rotation about the axis x y and z. This random change
1084     // in detector position allow for the simulation of a random uncertainty
1085     // in the detector positions of the ITS.
1086     // Intputs are:
1087     // Float_t *stran  A 3 element array representing the global translations
1088     //                 variances. The elements are r,theta,z in cm/readians.
1089     // Float_t *srot   A 3 element array representing the global rotation
1090     //                 angles variances about the three axis x,y,z in radians.
1091     // Outputs are:
1092     // none.
1093     Int_t    i,j;
1094     Double_t t[3],ro[3],r,r0,phi,rphi;
1095     TRandom ran;
1096     AliITSgeomMatrix *g;
1097
1098     fTrans = (fTrans && 0xfffd) + 2;  // set bit 1 true.
1099     for(i=0;i<fNmodules;i++){
1100         g = this->GetGeomMatrix(i);
1101         g->GetTranslation(t);
1102         g->GetAngles(ro);
1103         r = r0= TMath::Hypot(t[1],t[0]);
1104         phi   = TMath::ATan2(t[1],t[0]);
1105         rphi  = r0*phi;
1106         r    += ran.Gaus(0.0,stran[0]);
1107         rphi += ran.Gaus(0.0,stran[1]);
1108         phi   = rphi/r0;
1109         t[0]  = r*TMath::Cos(phi);
1110         t[1]  = r*TMath::Sin(phi);
1111         t[2] += ran.Gaus(0.0,stran[2]);
1112         for(j=0;j<3;j++){
1113             ro[j] += ran.Gaus(0.0, srot[j]);
1114         } // end for j
1115         g->SetTranslation(t);
1116         g->SetAngles(ro);
1117     } // end for i
1118     return;
1119 }
1120 //______________________________________________________________________
1121 void AliITSgeom::GeantToTracking(AliITSgeom &source){
1122     //     Copy the geometry data but change it to go between the ALICE
1123     // Global coordinate system to that used by the ITS tracking. A slightly
1124     // different coordinate system is used when tracking. This coordinate 
1125     // system is only relevant when the geometry represents the cylindrical
1126     // ALICE ITS geometry. For tracking the Z axis is left alone but X-> -Y
1127     // and Y-> X such that X always points out of the ITS cylinder for every
1128     // layer including layer 1 (where the detectors are mounted upside down).
1129     // Inputs are:
1130     // AliITSgeom &source  The AliITSgeom class with which to make this
1131     //                     a copy of.
1132     // Outputs are:
1133     // return  *this       The a new copy of source.
1134     //Begin_Html
1135     /*
1136       <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
1137     */
1138     //End_Html
1139     Int_t    i,j,k,l,id[3];
1140     Double_t r0[3][3],r1[3][3];
1141     Double_t a0[3][3] = {{0.,+1.,0.},{-1.,0.,0.},{0.,0.,+1.}};
1142     Double_t a1[3][3] = {{0.,-1.,0.},{+1.,0.,0.},{0.,0.,+1.}};
1143
1144     *this = source;  // copy everything
1145     for(i=0;i<GetIndexMax();i++){
1146         GetGeomMatrix(i)->GetIndex(id);
1147         GetGeomMatrix(i)->GetMatrix(r0);
1148         if(id[0]==1){ // Layer 1 is treated different from the others.
1149             for(j=0;j<3;j++) for(k=0;k<3;k++){
1150                 r1[j][k] = 0.;
1151                 for(l=0;l<3;l++) r1[j][k] += a0[j][l]*r0[l][k];
1152             } // end for j,k
1153         }else{
1154             for(j=0;j<3;j++) for(k=0;k<3;k++){
1155                 r1[j][k] = 0.;
1156                 for(l=0;l<3;l++) r1[j][k] += a1[j][l]*r0[l][k];
1157             } // end for j,k
1158         } // end if
1159         GetGeomMatrix(i)->SetMatrix(r1);
1160     } // end for i
1161     this->fTrans = (this->fTrans && 0xfffe) + 1;  // set bit 0 true.
1162     return;
1163 }
1164 //______________________________________________________________________
1165 Int_t AliITSgeom::GetNearest(const Double_t g[3],Int_t lay){
1166     //      Finds the Detector (Module) that is nearest the point g [cm] in
1167     // ALICE Global coordinates. If layer !=0 then the search is restricted
1168     // to Detectors (Modules) in that particular layer.
1169     // Inputs are:
1170     // Double_t g[3]  The ALICE Cartesean global coordinate from which the
1171     //                distance is to be calculated with.
1172     // Int_t lay      The layer to restrict the search to. If layer=0 then
1173     //                all layers are searched. Default is lay=0.
1174     // Outputs are:
1175     // return         The module number representing the nearest module.
1176     Int_t    i,l,a,e,in=0;
1177     Double_t d,dn=1.0e10;
1178     Bool_t   t=lay!=0; // skip if lay = 0 default value check all layers.
1179
1180     for(i=0;i<fNmodules;i++){
1181         if(t){GetModuleId(i,l,a,e);if(l!=lay) continue;}
1182         if((d=GetGeomMatrix(i)->Distance2(g))<dn){
1183             dn = d;
1184             in = i;
1185         } // end if
1186     } // end for i
1187     return in;
1188 }
1189 //______________________________________________________________________
1190 void AliITSgeom::GetNearest27(const Double_t g[3],Int_t n[27],Int_t lay){
1191     //      Finds 27 Detectors (Modules) that are nearest the point g [cm] in
1192     // ALICE Global coordinates. If layer !=0 then the search is restricted
1193     // to Detectors (Modules) in that particular layer. The number 27 comes 
1194     // from including the nearest detector and all those around it (up, down,
1195     // left, right, forwards, backwards, and the corners).
1196     // Inputs are:
1197     // Double_t g[3]  The ALICE Cartesean global coordinate from which the
1198     //                distance is to be calculated with.
1199     // Int_t lay      The layer to restrict the search to. If layer=0 then
1200     //                all layers are searched. Default is lay=0.
1201     // Outputs are:
1202     // Int_t n[27]    The module number representing the nearest 27 modules
1203     //                in order.
1204     Int_t    i,l,a,e,in[27]={0,0,0,0,0,0,0,0,0,
1205                              0,0,0,0,0,0,0,0,0,
1206                              0,0,0,0,0,0,0,0,0,};
1207     Double_t d,dn[27]={1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,
1208                        1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,
1209                        1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,
1210                        1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,
1211                        1.0e10,1.0e10,1.0e10};
1212     Bool_t   t=(lay!=0); // skip if lay = 0 default value check all layers.
1213
1214     for(i=0;i<fNmodules;i++){
1215         if(t){GetModuleId(i,l,a,e);if(l!=lay) continue;}
1216         for(a=0;a<27;a++){
1217             d = GetGeomMatrix(i)->Distance2(g);
1218             if(d<dn[a]){
1219                 for(e=26;e>a;e--){dn[e] = dn[e-1];in[e] = in[e-1];}
1220                 dn[a] = d; in[a] = i;
1221             } // end if d<dn[i]
1222         } // end for a
1223     } // end for i
1224     for(i=0;i<27;i++) n[i] = in[i];
1225 }
1226 //----------------------------------------------------------------------