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