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