minor fix
[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 /* $Id$ */
17
18 ///////////////////////////////////////////////////////////////////////
19 // ITS geometry manipulation routines.                               //
20 // Created April 15 1999.                                            //
21 // version: 0.0.0                                                    //
22 // By: Bjorn S. Nilsen                                               //
23 // version: 0.0.1                                                    //
24 // Updated May 27 1999.                                              //
25 // Added Cylindrical random and global based changes.                //
26 //                                                                   //
27 // Modified and added functions Feb. 7 2006                          //
28 ///////////////////////////////////////////////////////////////////////
29
30
31 ////////////////////////////////////////////////////////////////////////
32 //     The local coordinate system by, default, is show in the following
33 // figures. Also shown are the ladder numbering scheme.
34 //Begin_Html
35 /*
36 <img src="picts/ITS/AliITSgeomMatrix_L1.gif">
37 </pre>
38 <br clear=left>
39 <font size=+2 color=blue>
40 <p>This shows the relative geometry differences between the ALICE Global
41 coordinate system and the local detector coordinate system.
42 </font>
43 <pre>
44
45 <pre>
46 <img src="picts/ITS/its1+2_convention_front_5.gif">
47 </pre>
48 <br clear=left>
49 <font size=+2 color=blue>
50 <p>This shows the front view of the SPDs and the orientation of the local
51 pixel coordinate system. Note that the inner pixel layer has its y coordinate
52 in the opposite direction from all of the other layers.
53 </font>
54 <pre>
55
56 <pre>
57 <img src="picts/ITS/its3+4_convention_front_5.gif">
58 </pre>
59 <br clear=left>
60 <font size=+2 color=blue>
61 <p>This shows the front view of the SDDs and the orientation of the local
62 pixel coordinate system.
63 </font>
64 <pre>
65
66 <pre>
67 <img src="picts/ITS/its5+6_convention_front_5.gif">
68 </pre>
69 <br clear=left>
70 <font size=+2 color=blue>
71 <p>This shows the front view of the SSDs and the orientation of the local
72 pixel coordinate system.
73 </font>
74 <pre>
75 */
76 //End_Html
77 //
78 ////////////////////////////////////////////////////////////////////////
79
80 ////////////////////////////////////////////////////////////////////////
81 //
82 // version: 0
83 // Written by Bjorn S. Nilsen
84 //
85 // Data Members:
86 //
87 // TString    fVersion 
88 //     Transformation version.
89 // Int_t      fTrans
90 //     Flag to keep track of which transformation 
91 // Int_t      fNmodules
92 //      The total number of modules
93 // Int_t fNlayers
94 //     The number of ITS layers for this geometry. By default this
95 //  is 6, but can be modified by the creator function if there are
96 // more layers defined.
97 //
98 // TArrayI fNlad
99 //     A pointer to an array fNlayers long containing the number of 
100 // ladders for each layer. This array is typically created and filled 
101 // by the AliITSgeom creator function.
102 //
103 // TArrayI fNdet
104 //     A pointer to an array fNlayers long containing the number of
105 // active detector volumes for each ladder. This array is typically
106 // created and filled by the AliITSgeom creator function.
107 //
108 // TObjArray fGm containing objects of type AliITSgeomMatrix
109 //     A pointer to an array of AliITSgeomMatrix classes. One element 
110 // per module (detector) in the ITS. AliITSgeomMatrix basicly contains
111 // all of the necessary information about the detector and it's coordinate
112 // transformations.
113 //
114 ////////////////////////////////////////////////////////////////////////
115 #include <Riostream.h>
116 #include <ctype.h>
117
118 #include <TRandom.h>
119 #include <TSystem.h>
120 #include <TArrayI.h>
121
122 #include "AliITSgeom.h"
123 #include "AliLog.h"
124
125 ClassImp(AliITSgeom)
126
127 //______________________________________________________________________
128 AliITSgeom::AliITSgeom():
129 TObject(),
130 fVersion("GEANT"),// Transformation version.
131 fTrans(0),       // Flag to keep track of which transformation 
132 fNmodules(0),    // The total number of modules
133 fNlayers(0),     // The number of layers.
134 fNlad(),         //[] Array of the number of ladders/layer(layer)
135 fNdet(),         //[] Array of the number of detector/ladder(layer)
136 fGm(0,0)        // Structure of translation. and rotation.
137 {
138     //     The default constructor for the AliITSgeom class. It, by default,
139     // sets fNlayers to zero and zeros all pointers.
140     // Do not allocate anything zero everything.
141     // Inputs:
142     //    none.
143     // Outputs:
144     //    none.
145     // Return:
146     //    a zeroed AliITSgeom object.
147
148     fGm.SetOwner(kTRUE);
149     return;
150 }
151
152 //______________________________________________________________________
153 AliITSgeom::AliITSgeom(Int_t itype,Int_t nlayers,const Int_t *nlads,
154                        const Int_t *ndets,Int_t mods):
155 TObject(),
156 fVersion("GEANT"),    // Transformation version.
157 fTrans(itype),       // Flag to keep track of which transformation 
158 fNmodules(mods),     // The total number of modules
159 fNlayers(nlayers),   // The number of layers.
160 fNlad(nlayers,nlads),//[] Array of the number of ladders/layer(layer)
161 fNdet(nlayers,ndets),//[] Array of the number of detector/ladder(layer)
162 fGm(mods,0)         // Structure of translation. and rotation.
163 {
164     //     A simple constructor to set basic geometry class variables
165     // Inputs:
166     //      Int_t itype   the type of transformation kept.
167     //                    bit 0 => Standard GEANT
168     //                    bit 1 => ITS tracking
169     //                    bit 2 => A change in the coordinate system 
170     //                    has been made. others are still to be defined 
171     //                    as needed.
172     //      Int_t nlayers The number of ITS layers also set the size of 
173     //                    the arrays
174     //      Int_t *nlads  an array of the number of ladders for each 
175     //                    layer. This array must be nlayers long.
176     //      Int_t *ndets  an array of the number of detectors per ladder
177     //                    for each layer. This array must be nlayers long.
178     //      Int_t mods    The number of modules. Typically the sum of all the 
179     //                    detectors on every layer and ladder.
180     // Outputs:
181     //     none
182     // Return:
183     //     A properly inilized AliITSgeom object.
184
185     fGm.SetOwner(kTRUE);
186     return;
187 }
188 //______________________________________________________________________
189 void AliITSgeom::Init(Int_t itype,Int_t nlayers,const Int_t *nlads,
190                       const Int_t *ndets,Int_t mods){
191     //     A simple Inilizer to set basic geometry class variables
192     // Inputs:
193     //      Int_t itype   the type of transformation kept.
194     //                    bit 0 => Standard GEANT
195     //                    bit 1 => ITS tracking
196     //                    bit 2 => A change in the coordinate system 
197     //                    has been made. others are still to be defined 
198     //                    as needed.
199     //      Int_t nlayers The number of ITS layers also set the size of 
200     //                    the arrays
201     //      Int_t *nlads  an array of the number of ladders for each 
202     //                    layer. This array must be nlayers long.
203     //      Int_t *ndets  an array of the number of detectors per ladder 
204     //                    for each layer. This array must be nlayers long.
205     //      Int_t mods    The number of modules. Typically the sum of all the 
206     //                    detectors on every layer and ladder.
207     // Outputs:
208     //     none
209     // Return:
210     //     A properly inilized AliITSgeom object.
211
212     fVersion  = "GEANT";     // Transformation version.
213     fTrans    = itype;       // Flag to keep track of which transformation 
214     fNmodules = mods;        // The total number of modules
215     fNlayers  = nlayers;     // The number of layers.
216     fNlad.Set(nlayers,nlads);//[] Array of the number of ladders/layer(layer)
217     fNdet.Set(nlayers,ndets);//[] Array of the number of detector/ladder(layer)
218     fGm.Clear();
219     fGm.Expand(mods);        // Structure of translation. and rotation.
220     fGm.SetOwner(kTRUE);
221     return;
222 }
223 //______________________________________________________________________
224 void AliITSgeom::CreateMatrix(Int_t mod,Int_t lay,Int_t lad,Int_t det,
225                               AliITSDetector idet,const Double_t tran[3],
226                               const Double_t rot[10]){
227     // Given the translation vector tran[3] and the rotation matrix rot[1],
228     // this function creates and adds to the TObject Array fGm the
229     // AliITSgeomMatrix object.
230     // The rot[10] matrix is set up like:
231     /*   / rot[0]  rot[1]  rot[2] \
232     //  |  rot[3]  rot[4]  rot[5]  |
233     //   \ rot[6]  rot[7]  rot[8] /  if(rot[9]!=0) then the Identity matrix
234     // is used regardless of the values in rot[0]-rot[8].
235     */
236     // Inputs:
237     //    Int_t           mod     The module number. The location in TObjArray
238     //    Int_t           lay     The layer where this module is
239     //    Int_t           lad     On which ladder this module is
240     //    Int_t           det     Which detector on this ladder this module is
241     //    AliITSDetector idet     The type of detector see AliITSgeom.h
242     //    Double_t       tran[3]  The translation vector
243     //    Double_t       rot[10]  The rotation matrix.
244     // Outputs:
245     //    none
246     // Return:
247     //    none.
248     Int_t id[3];
249     Double_t r[3][3] = {{1.0,0.0,0.0},{0.0,1.0,0.0},{0.0,0.0,1.0}};
250
251     if(mod<0||mod>=fGm.GetSize()){ 
252         Error("CreateMatrix","mod=%d is out of bounds max value=%d",mod,
253               fGm.GetSize());
254         return;
255     } // end if
256     delete fGm.At(mod);
257     id[0] = lay; id[1] = lad; id[2] = det;
258     if(rot[9]!=0.0) { // null rotation
259         r[0][0] = rot[0]; r[0][1] = rot[1]; r[0][2] = rot[2];
260         r[1][0] = rot[3]; r[1][1] = rot[4]; r[1][2] = rot[5];
261         r[2][0] = rot[6]; r[2][1] = rot[7]; r[2][2] = rot[8];
262     } // end if
263     fGm.AddAt(new AliITSgeomMatrix(idet,id,r,tran),mod);
264 }
265 //______________________________________________________________________
266 AliITSgeom::~AliITSgeom(){
267     //     The destructor for the AliITSgeom class. If the arrays fNlad,
268     // fNdet, or fGm have had memory allocated to them, there pointer values
269     // are non zero, then this memory space is freed and they are set
270     // to zero. In addition, fNlayers is set to zero. The destruction of
271     // Inputs:
272     //    none.
273     // Outputs:
274     //    none.
275     // Return:
276     //    none.
277
278     return;
279 }
280 //______________________________________________________________________
281 AliITSgeom::AliITSgeom(const AliITSgeom &source) : 
282 TObject(source),
283 fVersion(source.fVersion), // Transformation version.
284 fTrans(source.fTrans),   // Flag to keep track of which transformation
285 fNmodules(source.fNmodules),// The total number of modules
286 fNlayers(source.fNlayers), // The number of layers.
287 fNlad(source.fNlad),    // Array of the number of ladders/layer(layer)
288 fNdet(source.fNdet),    // Array of the number of detector/ladder(layer)
289 fGm(source.fGm.GetSize(),source.fGm.LowerBound())// Structure of 
290                                                   // translation and rotation.
291 {
292     //     The copy constructor for the AliITSgeom class. It calls the
293     // = operator function. See the = operator function for more details.
294     // Inputs:
295     //     AliITSgeom &source  The AliITSgeom class with which to make this
296     //                         a copy of.
297     // Outputs:
298     //     none.
299     // Return:
300     //     none.
301     Int_t i,n;
302
303     n = source.fGm.GetLast()+1;
304     for(i=source.fGm.LowerBound();i<n;i++){
305         fGm.AddAt(new AliITSgeomMatrix(*((AliITSgeomMatrix*)(
306                                              source.fGm.At(i)))),i);
307     } // end for i
308     fGm.SetOwner(kTRUE);
309     return;
310 }
311 //______________________________________________________________________
312 AliITSgeom& AliITSgeom::operator=(const AliITSgeom &source){
313     //     The = operator function for the AliITSgeom class. It makes an
314     // independent copy of the class in such a way that any changes made
315     // to the copied class will not affect the source class in any way.
316     // This is required for many ITS alignment studies where the copied
317     // class is then modified by introducing some misalignment.
318     // Inputs:
319     //     AliITSgeom &source  The AliITSgeom class with which to make this
320     //                         a copy of.
321     // Outputs:
322     //     none.
323     // Return:
324     //     *this The a new copy of source.
325     Int_t i;
326
327     if(this == &source) return *this; // don't assign to ones self.
328
329     // if there is an old structure allocated delete it first.
330     this->fGm.Clear();
331
332     this->fVersion  = source.fVersion;
333     this->fTrans    = source.fTrans;
334     this->fNmodules = source.fNmodules;
335     this->fNlayers  = source.fNlayers;
336     this->fNlad     = source.fNlad;
337     this->fNdet     = source.fNdet;
338     this->fGm.Expand(this->fNmodules);
339     for(i=source.fGm.LowerBound();i<source.fGm.GetLast();i++){
340         fGm.AddAt(new AliITSgeomMatrix(*((AliITSgeomMatrix*)(
341                                              source.fGm.At(i)))),i);
342     } // end for i
343     fGm.SetOwner(kTRUE);
344     return *this;
345 }
346 //______________________________________________________________________
347 Int_t AliITSgeom::GetModuleIndex(Int_t lay,Int_t lad,Int_t det)const{
348     //      This routine computes the module index number from the layer,
349     // ladder, and detector numbers. The number of ladders and detectors
350     // per layer is determined when this geometry package is constructed,
351     // see AliITSgeom(const char *filename) for specifics.
352     // Inputs:
353     //    Int_t lay  The layer number. Starting from 1.
354     //    Int_t lad  The ladder number. Starting from 1.
355     //    Int_t det  The detector number. Starting from 1.
356     // Outputs:
357     //    none.
358     // Return:
359     //    the module index number, starting from zero.
360     Int_t i,j,k,id[3];
361
362     i = fNdet[lay-1] * (lad-1) + det - 1;
363     j = 0;
364     for(k=0;k<lay-1;k++) j += fNdet[k]*fNlad[k];
365     i = i+j;
366     if(i>=fNmodules) return -1;
367     GetGeomMatrix(i)->GetIndex(id);
368     if(id[0]==lay&&id[1]==lad&&id[2]==det) return i;
369     // Array of modules fGm is not in expected order. Search for this index
370     for(i=0;i<fNmodules;i++){
371         GetGeomMatrix(i)->GetIndex(id);
372         if(id[0]==lay&&id[1]==lad&&id[2]==det) return i;
373     } // end for i
374     // This layer ladder and detector combination does not exist return -1.
375     return -1;
376 }
377 //______________________________________________________________________
378 void AliITSgeom::GetModuleId(Int_t index,Int_t &lay,Int_t &lad,Int_t &det)
379 const{
380     //      This routine computes the layer, ladder and detector number 
381     // given the module index number. The number of ladders and detectors
382     // per layer is determined when this geometry package is constructed,
383     // see AliITSgeom(const char *filename) for specifics.
384     // Inputs:
385     //     Int_t index  The module index number, starting from zero.
386     // Outputs:
387     //     Int_t lay    The layer number. Starting from 1.
388     //     Int_t lad    The ladder number. Starting from 1.
389     //     Int_t det    The detector number. Starting from 1.
390     // Return:
391     //     none.
392     Int_t id[3];
393     AliITSgeomMatrix *g = GetGeomMatrix(index);
394
395     if (g == 0x0){
396         Error("GetModuleId","Can not get GeoMatrix for index = %d",index);
397         lay = -1; lad = -1; det = -1;
398     }else{
399         g->GetIndex(id);
400         lay = id[0]; lad = id[1]; det = id[2];
401     }// End if
402     return;
403     // The old way kept for posterity.
404 /*
405     Int_t i,j,k;
406     j = 0;
407     for(k=0;k<fNlayers;k++){
408         j += fNdet[k]*fNlad[k];
409         if(j>index)break;
410     } // end for k
411     lay = k+1;
412     i = index -j + fNdet[k]*fNlad[k];
413     j = 0;
414     for(k=0;k<fNlad[lay-1];k++){
415         j += fNdet[lay-1];
416         if(j>i)break;
417     } // end for k
418     lad = k+1;
419     det = 1+i-fNdet[lay-1]*k;
420     return;
421 */
422 }
423 //______________________________________________________________________
424 Int_t AliITSgeom::GetNDetTypes(Int_t &max)const{
425     // Finds and returns the number of detector types used and the
426     // maximum detector type value. Only counts id >=0 (no undefined
427     // values. See AliITSgeom.h for list of AliITSDetecor enumerated types.
428     // Inputs:
429     //    none.
430     // Outputs:
431     //    The maximum detector type used
432     // Return:
433     //    The number of detector types used
434     Int_t i,*n,id;
435
436     max = -1;
437     for(i=0;i<GetIndexMax();i++){
438         id = GetModuleType(i);
439         if(id>max) max=id;
440     } // end for i
441     n = new Int_t[max+1];
442     for(i=0;i<max;i++) n[i] = 0;
443     for(i=0;i<GetIndexMax();i++){
444         id = GetModuleType(i);
445         if(id>-1)n[id]++; // note id=-1 => undefined.
446     } // end for i
447     id = 0;
448     for(i=0;i<max;i++) if(n[i]!=0) id++;
449     delete[] n;
450     return id+1;
451 }
452 //______________________________________________________________________
453 Int_t AliITSgeom::GetNDetTypes(TArrayI &maxs,AliITSDetector *types)const{
454     // Finds and returns the number of detector types used and the
455     // number of each detector type. Only counts id >=0 (no undefined
456     // values. See AliITSgeom.h for list of AliITSDetecor enumerated types.
457     // Inputs:
458     //    none.
459     // Outputs:
460     //    The maximum detector type used
461     // Return:
462     //    The number of detector types used
463     Int_t i,j,*n,id,max;
464
465     max = -1;
466     for(i=0;i<GetIndexMax();i++){
467         id = GetModuleType(i);
468         if(id>max) max=id;
469     } // end for i
470     n = new Int_t[max+1];
471     for(i=0;i<max;i++) n[i] = 0;
472     for(i=0;i<GetIndexMax();i++){
473         id = GetModuleType(i);
474         if(id>-1)n[id]++; // note id=-1 => undefined.
475     } // end for i
476     id = 0;
477     for(i=0;i<=max;i++) if(n[i]!=0) id++;
478     maxs.Set(id);
479     j = 0;
480     for(i=0;i<=max;i++) if(n[i]!=0){
481         maxs[j] = n[i];
482         types[j++] = (AliITSDetector) i;
483     } // end for i/end if
484     delete[] n;
485     return id;
486 }
487 //______________________________________________________________________
488 Int_t AliITSgeom::GetStartDet(Int_t dtype)const{
489     // returns the starting module index value for a give type of detector id.
490     // This assumes that the detector types are different on different layers
491     // and that they are not mixed up.
492     // Inputs:
493     //    Int_t dtype A detector type number. 0 for SPD, 1 for SDD, 
494     //                and 2 for SSD.
495     // Outputs:
496     //    none.
497     // Return:
498     //    the module index for the first occurrence of that detector type.
499
500     switch(dtype){
501     case 0:
502         return GetModuleIndex(1,1,1);
503         break;
504     case 1:
505         return GetModuleIndex(3,1,1);
506         break;
507     case 2:
508         return GetModuleIndex(5,1,1);
509         break;
510     default:
511         Warning("GetStartDet","undefined detector type %d",dtype);
512         return 0;
513     } // end switch
514
515     Warning("GetStartDet","undefined detector type %d",dtype);
516     return 0;
517 }
518 //______________________________________________________________________
519 Int_t AliITSgeom::GetLastDet(Int_t dtype)const{
520     // returns the last module index value for a give type of detector id.
521     // This assumes that the detector types are different on different layers
522     // and that they are not mixed up.
523     // Inputs:
524     //     Int_t dtype A detector type number. 0 for SPD, 1 for SDD, 
525     //                 and 2 for SSD.
526     // Outputs:
527     // Return:
528     //     the module index for the last occurrence of that detector type.
529
530     switch((AliITSDetector)dtype){
531     case kSPD:
532         return GetModuleIndex(3,1,1)-1;
533         break;
534     case kSDD:
535         return GetModuleIndex(5,1,1)-1;
536         break;
537     case kSSD:
538         return GetIndexMax()-1;
539         break;
540     case kSSDp: case kSDDp: case kND:
541     default:
542         Warning("GetLastDet","undefined detector type %d",dtype);
543         return 0;
544     } // end switch
545
546     Warning("GetLastDet","undefined detector type %d",dtype);
547     return 0;
548 }
549
550 //______________________________________________________________________
551 void AliITSgeom::PrintData(FILE *fp,Int_t lay,Int_t lad,Int_t det)const{
552     //     This function prints out the coordinate transformations for
553     // the particular detector defined by layer, ladder, and detector
554     // to the file pointed to by the File pointer fp. fprintf statements
555     // are used to print out the numbers. The format is
556     // layer ladder detector Trans= fx0 fy0 fz0 rot= frx fry frz 
557     // Shape=fShapeIndex
558     //                         dfr= fr[0] fr[1] fr[2]
559     //                         dfr= fr[3] fr[4] fr[5]
560     //                         dfr= fr[6] fr[7] fr[8]
561     // By indicating which detector, some control over the information 
562     // is given to the user. The output it written to the file pointed
563     // to by the file pointer fp. This can be set to stdout if you want.
564     // Inputs:
565     //     FILE *fp           A file pointer to an opened file for 
566     //                        writing in which the results of the 
567     //                        comparison will be written.
568     //     Int_t lay          The layer number. Starting from 1.
569     //     Int_t lad          The ladder number. Starting from 1.
570     //     Int_t det          The detector number. Starting from 1.
571     // Outputs:
572     //     none
573     // Return:
574     //     none.
575     AliITSgeomMatrix *gt;
576     Double_t t[3],r[3],m[3][3];
577
578     gt = this->GetGeomMatrix(GetModuleIndex(lay,lad,det));
579     gt->GetTranslation(t);
580     gt->GetAngles(r);
581     fprintf(fp,"%1.1d %2.2d %2.2d Trans=%f %f %f rot=%f %f %f Shape=%d\n",
582             lay,lad,det,t[0],t[1],t[2],r[0],r[1],r[2],
583             gt->GetDetectorIndex());
584     gt->GetMatrix(m);
585     fprintf(fp,"        dfr= %e %e %e\n",m[0][0],m[0][1],m[0][2]);
586     fprintf(fp,"        dfr= %e %e %e\n",m[1][0],m[1][1],m[1][2]);
587     fprintf(fp,"        dfr= %e %e %e\n",m[2][0],m[2][1],m[2][2]);
588     return;
589 }
590
591 //______________________________________________________________________
592 Int_t AliITSgeom::GetNearest(const Double_t g[3],Int_t lay)const{
593     //      Finds the Detector (Module) that is nearest the point g [cm] in
594     // ALICE Global coordinates. If layer !=0 then the search is restricted
595     // to Detectors (Modules) in that particular layer.
596     // Inputs:
597     //     Double_t g[3]  The ALICE Cartesian global coordinate from which the
598     //                    distance is to be calculated with.
599     //     Int_t lay      The layer to restrict the search to. If layer=0 then
600     //                    all layers are searched. Default is lay=0.
601     // Output:
602     //     none.
603     // Return:
604     //     The module number representing the nearest module.
605     Int_t    i,l,a,e,in=0;
606     Double_t d,dn=1.0e10;
607     Bool_t   t=lay!=0; // skip if lay = 0 default value check all layers.
608
609     for(i=0;i<fNmodules;i++){
610         if(t){GetModuleId(i,l,a,e);if(l!=lay) continue;}
611         if((d=GetGeomMatrix(i)->Distance2(g))<dn){
612             dn = d;
613             in = i;
614         } // end if
615     } // end for i
616     return in;
617 }
618 //______________________________________________________________________
619 void AliITSgeom::GetNearest27(const Double_t g[3],Int_t n[27],Int_t lay)const{
620     //      Finds 27 Detectors (Modules) that are nearest the point g [cm] in
621     // ALICE Global coordinates. If layer !=0 then the search is restricted
622     // to Detectors (Modules) in that particular layer. The number 27 comes 
623     // from including the nearest detector and all those around it (up, down,
624     // left, right, forwards, backwards, and the corners).
625     // Input:
626     //     Double_t g[3]  The ALICE Cartesian global coordinate from which the
627     //                    distance is to be calculated with.
628     //     Int_t lay      The layer to restrict the search to. If layer=0 then
629     //                    all layers are searched. Default is lay=0.
630     // Output:
631     //     Int_t n[27]    The module number representing the nearest 27 modules
632     //                    in order.
633     // Return:
634     //     none.
635     Int_t    i,l,a,e,in[27]={0,0,0,0,0,0,0,0,0,
636                              0,0,0,0,0,0,0,0,0,
637                              0,0,0,0,0,0,0,0,0,};
638     Double_t d,dn[27]={1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,
639                        1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,
640                        1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,
641                        1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,
642                        1.0e10,1.0e10,1.0e10};
643     Bool_t   t=(lay!=0); // skip if lay = 0 default value check all layers.
644
645     for(i=0;i<fNmodules;i++){
646         if(t){GetModuleId(i,l,a,e);if(l!=lay) continue;}
647         for(a=0;a<27;a++){
648             d = GetGeomMatrix(i)->Distance2(g);
649             if(d<dn[a]){
650                 for(e=26;e>a;e--){dn[e] = dn[e-1];in[e] = in[e-1];}
651                 dn[a] = d; in[a] = i;
652             } // end if d<dn[i]
653         } // end for a
654     } // end for i
655     for(i=0;i<27;i++) n[i] = in[i];
656 }
657 //_______________________________________________________________________
658 void AliITSgeom::DetLToTrackingV2(Int_t md,Float_t xin,Float_t zin,
659                                   Float_t &yout,Float_t &zout) const {
660
661     //Conversion from local coordinates on detectors to local
662     //coordinates used for tracking ("v2")
663     // Inputs:
664     //   Int_t   md      Module number
665     //   Float_t xin     Standard local coordinate x
666     //   Float_t zin     Standard local coordinate z
667     // Output:
668     //   Float_t yout    Tracking local coordinate y
669     //   Float_t zout    Tracking local coordinate z
670     // Return:
671     //   none.
672     Float_t x,y,z;
673     Double_t rt[9],al;
674
675     GetTrans(md,x,y,z);
676     GetRotMatrix(md,rt);
677     al = TMath::ATan2(rt[1],rt[0])+TMath::Pi();
678     yout = -(-xin+(x*((Float_t)TMath::Cos(al))+y*((Float_t)TMath::Sin(al))));
679     if(md<(GetModuleIndex(2,1,1))) yout *= -1; 
680     zout = -zin+z; 
681 }
682 //_______________________________________________________________________
683 void AliITSgeom::TrackingV2ToDetL(Int_t md,Float_t yin,Float_t zin,
684                                   Float_t &xout,Float_t &zout) const {
685     //Conversion from local coordinates used for tracking ("v2") to
686     //local detector coordinates  
687     // Inputs:
688     //   Int_t   md      Module number
689     //   Float_t yin     Tracking local coordinate y
690     //   Float_t zin     Tracking local coordinate z
691     // Output:
692     //   Float_t xout    Standard local coordinate x
693     //   Float_t zout    Standard local coordinate z
694     // Return:
695     //   none.
696     Float_t x,y,z;
697     Double_t rt[9],al;
698
699     GetTrans(md,x,y,z);
700     GetRotMatrix(md,rt);
701     al = TMath::ATan2(rt[1],rt[0])+TMath::Pi();
702     xout = yin;
703     if(md<(GetModuleIndex(2,1,1))) xout = -xout;
704     xout += (x*((Float_t)TMath::Cos(al))+y*((Float_t)TMath::Sin(al)));
705     zout  = -zin+z; 
706 }
707 //----------------------------------------------------------------------
708