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