37b63ef83a74cbeb2a9eec6a49bcf029c4448abc
[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 // Added  function PrintComparison.                                  //
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 void AliITSgeom::PrintComparison(FILE *fp,AliITSgeom *other)const{
551     //     This function was primarily created for diagnostic reasons. It
552     // print to a file pointed to by the file pointer fp the difference
553     // between two AliITSgeom classes. The format of the file is basically,
554     // define d? to be the difference between the same element of the two
555     // classes. For example dfrx = this->GetGeomMatrix(i)->frx 
556     // - other->GetGeomMatrix(i)->frx.
557     // if(at least one of dfx0, dfy0, dfz0,dfrx,dfry,dfrz are non zero) then
558     // print layer ladder detector dfx0 dfy0 dfz0 dfrx dfry dfrz
559     // if(at least one of the 9 elements of dfr[] are non zero) then print
560     // layer ladder detector dfr[0] dfr[1] dfr[2]
561     //                       dfr[3] dfr[4] dfr[5]
562     //                       dfr[6] dfr[7] dfr[8]
563     // Only non zero values are printed to save space. The differences are
564     // typical written to a file because there are usually a lot of numbers
565     // printed out and it is usually easier to read them in some nice editor
566     // rather than zooming quickly past you on a screen. fprintf is used to
567     // do the printing. The fShapeIndex difference is not printed at this time.
568     // Inputs:
569     //    FILE *fp           A file pointer to an opened file for writing 
570     //                       in which the results of the comparison will 
571     //                       be written.
572     //    AliITSgeom *other  The other AliITSgeom class to which this one is
573     //                       being compared.
574     // Outputs:
575     //    none.
576     // Return:
577     //    none.
578     Int_t    i,j,idt[3],ido[3];
579     Double_t tt[3],to[3];  // translation
580     Double_t rt[3],ro[3];  // phi in radians
581     Double_t mt[3][3],mo[3][3]; // matrices
582     AliITSgeomMatrix *gt,*go;
583     Bool_t   t;
584
585     for(i=0;i<this->fNmodules;i++){
586         gt  =  this->GetGeomMatrix(i);
587         go  = other->GetGeomMatrix(i);
588         gt->GetIndex(idt);
589         go->GetIndex(ido);
590         t = kFALSE;
591         for(i=0;i<3;i++) t = t&&idt[i]!=ido[i];
592         if(t) fprintf(fp,"%4.4d %1.1d %2.2d %2.2d %1.1d %2.2d %2.2d\n",i,
593                       idt[0],idt[1],idt[2],ido[0],ido[1],ido[2]);
594         gt->GetTranslation(tt);
595         go->GetTranslation(to);
596         gt->GetAngles(rt);
597         go->GetAngles(ro);
598         t = kFALSE;
599         for(i=0;i<3;i++) t = t&&tt[i]!=to[i];
600         if(t) fprintf(fp,"%1.1d %2.2d %2.2d dTrans=%f %f %f drot=%f %f %f\n",
601                       idt[0],idt[1],idt[2],
602                       tt[0]-to[0],tt[1]-to[1],tt[2]-to[2],
603                       rt[0]-ro[0],rt[1]-ro[1],rt[2]-ro[2]);
604         t = kFALSE;
605         gt->GetMatrix(mt);
606         go->GetMatrix(mo);
607         for(i=0;i<3;i++)for(j=0;j<3;j++)  t = mt[i][j] != mo[i][j];
608         if(t){
609             fprintf(fp,"%1.1d %2.2d %2.2d dfr= %e %e %e\n",
610                     idt[0],idt[1],idt[2],
611                     mt[0][0]-mo[0][0],mt[0][1]-mo[0][1],mt[0][2]-mo[0][2]);
612             fprintf(fp,"        dfr= %e %e %e\n",
613                     mt[1][0]-mo[1][0],mt[1][1]-mo[1][1],mt[1][2]-mo[1][2]);
614             fprintf(fp,"        dfr= %e %e %e\n",
615                     mt[2][0]-mo[2][0],mt[2][1]-mo[2][1],mt[2][2]-mo[2][2]);
616         } // end if t
617     } // end for i
618     return;
619 }
620 //______________________________________________________________________
621 void AliITSgeom::PrintData(FILE *fp,Int_t lay,Int_t lad,Int_t det)const{
622     //     This function prints out the coordinate transformations for
623     // the particular detector defined by layer, ladder, and detector
624     // to the file pointed to by the File pointer fp. fprintf statements
625     // are used to print out the numbers. The format is
626     // layer ladder detector Trans= fx0 fy0 fz0 rot= frx fry frz 
627     // Shape=fShapeIndex
628     //                         dfr= fr[0] fr[1] fr[2]
629     //                         dfr= fr[3] fr[4] fr[5]
630     //                         dfr= fr[6] fr[7] fr[8]
631     // By indicating which detector, some control over the information 
632     // is given to the user. The output it written to the file pointed
633     // to by the file pointer fp. This can be set to stdout if you want.
634     // Inputs:
635     //     FILE *fp           A file pointer to an opened file for 
636     //                        writing in which the results of the 
637     //                        comparison will be written.
638     //     Int_t lay          The layer number. Starting from 1.
639     //     Int_t lad          The ladder number. Starting from 1.
640     //     Int_t det          The detector number. Starting from 1.
641     // Outputs:
642     //     none
643     // Return:
644     //     none.
645     AliITSgeomMatrix *gt;
646     Double_t t[3],r[3],m[3][3];
647
648     gt = this->GetGeomMatrix(GetModuleIndex(lay,lad,det));
649     gt->GetTranslation(t);
650     gt->GetAngles(r);
651     fprintf(fp,"%1.1d %2.2d %2.2d Trans=%f %f %f rot=%f %f %f Shape=%d\n",
652             lay,lad,det,t[0],t[1],t[2],r[0],r[1],r[2],
653             gt->GetDetectorIndex());
654     gt->GetMatrix(m);
655     fprintf(fp,"        dfr= %e %e %e\n",m[0][0],m[0][1],m[0][2]);
656     fprintf(fp,"        dfr= %e %e %e\n",m[1][0],m[1][1],m[1][2]);
657     fprintf(fp,"        dfr= %e %e %e\n",m[2][0],m[2][1],m[2][2]);
658     return;
659 }
660 //______________________________________________________________________
661 void AliITSgeom::PrintGeom(ostream *wb)const{
662     //     Stream out an object of class AliITSgeom to standard output.
663     // Intputs:
664     //     ofstream *wb    The output streaming buffer.
665     // Outputs:
666     //     none.
667     // Return:
668     //     none.
669   Int_t i;
670
671     wb->setf(ios::scientific);
672     *wb << fTrans << " ";
673     *wb << fNmodules << " ";
674     *wb << fNlayers << " ";
675     for(i=0;i<fNlayers;i++) *wb << fNlad[i] << " ";
676     for(i=0;i<fNlayers;i++) *wb << fNdet[i] << "\n";
677     for(i=0;i<fNmodules;i++) {
678         *wb <<setprecision(16) << *(GetGeomMatrix(i)) << "\n";
679     } // end for i
680     return;
681 }
682 //______________________________________________________________________
683 //     The following routines modify the transformation of "this"
684 // geometry transformations in a number of different ways.
685 //______________________________________________________________________
686 void AliITSgeom::GlobalChange(const Float_t *tran,const Float_t *rot){
687     //     This function performs a Cartesian translation and rotation of
688     // the full ITS from its default position by an amount determined by
689     // the three element arrays tran and rot. If every element
690     // of tran and rot are zero then there is no change made
691     // the geometry. The change is global in that the exact same translation
692     // and rotation is done to every detector element in the exact same way.
693     // The units of the translation are those of the Monte Carlo, usually cm,
694     // and those of the rotation are in radians. The elements of tran
695     // are tran[0] = x, tran[1] = y, and tran[2] = z.
696     // The elements of rot are rot[0] = rx, rot[1] = ry, and
697     // rot[2] = rz. A change in x will move the hole ITS in the ALICE
698     // global x direction, the same for a change in y. A change in z will
699     // result in a translation of the ITS as a hole up or down the beam line.
700     // A change in the angles will result in the inclination of the ITS with
701     // respect to the beam line, except for an effective rotation about the
702     // beam axis which will just rotate the ITS as a hole about the beam axis.
703     // Intputs:
704     //     Float_t *tran   A 3 element array representing the global 
705     //                     translations. the elements are x,y,z in cm.
706     //     Float_t *rot    A 3 element array representing the global rotation
707     //                     angles about the three axis x,y,z in radians
708     // Outputs:
709     //     none.
710     // Return:
711     //     none.
712     Int_t    i,j;
713     Double_t t[3],r[3];
714     AliITSgeomMatrix *g;
715
716     fTrans = (fTrans && 0xfffd) + 2;  // set bit 1 true.
717     for(i=0;i<fNmodules;i++){
718         g = this->GetGeomMatrix(i);
719         g->GetTranslation(t);
720         g->GetAngles(r);
721         for(j=0;j<3;j++){
722             t[j] += tran[j];
723             r[j] += rot[j];
724         } // end for j
725         g->SetTranslation(t);
726         g->SetAngles(r);
727     } // end for i
728     return;
729 }
730 //______________________________________________________________________
731 void AliITSgeom::GlobalCylindericalChange(const Float_t *tran,
732                                           const Float_t *rot){
733     //     This function performs a cylindrical translation and rotation of
734     // each ITS element by a fixed about in radius, rphi, and z from its
735     // default position by an amount determined by the three element arrays
736     // tran and rot. If every element of tran and
737     // rot are zero then there is no change made the geometry. The
738     // change is global in that the exact same distance change in translation
739     // and rotation is done to every detector element in the exact same way.
740     // The units of the translation are those of the Monte Carlo, usually cm,
741     // and those of the rotation are in radians. The elements of tran
742     // are tran[0] = r, tran[1] = rphi, and tran[2] = z.
743     // The elements of rot are rot[0] = rx, rot[1] = ry, and
744     // rot[2] = rz. A change in r will results in the increase of the
745     // radius of each layer by the same about. A change in rphi will results in
746     // the rotation of each layer by a different angle but by the same
747     // circumferential distance. A change in z will result in a translation
748     // of the ITS as a hole up or down the beam line. A change in the angles
749     // will result in the inclination of the ITS with respect to the beam
750     // line, except for an effective rotation about the beam axis which will
751     // just rotate the ITS as a hole about the beam axis.
752     // Intputs:
753     //     Float_t *tran   A 3 element array representing the global 
754     //                     translations. the elements are r,theta,z in 
755     //                     cm/radians.
756     //     Float_t *rot    A 3 element array representing the global rotation
757     //                     angles about the three axis x,y,z in radians
758     // Outputs:
759     //     none.
760     // Return:
761     //     none.
762     Int_t    i,j;
763     Double_t t[3],ro[3],r,r0,phi,rphi;
764     AliITSgeomMatrix *g;
765
766     fTrans = (fTrans && 0xfffd) + 2;  // set bit 1 true.
767     for(i=0;i<fNmodules;i++){
768         g = this->GetGeomMatrix(i);
769         g->GetTranslation(t);
770         g->GetAngles(ro);
771         r = r0= TMath::Hypot(t[1],t[0]);
772         phi   = TMath::ATan2(t[1],t[0]);
773         rphi  = r0*phi;
774         r    += tran[0];
775         rphi += tran[1];
776         phi   = rphi/r0;
777         t[0]  = r*TMath::Cos(phi);
778         t[1]  = r*TMath::Sin(phi);
779         t[2] += tran[2];
780         for(j=0;j<3;j++){
781             ro[j] += rot[j];
782         } // end for j
783         g->SetTranslation(t);
784         g->SetAngles(ro);
785     } // end for i
786     return;
787 }
788 //______________________________________________________________________
789 void AliITSgeom::RandomChange(const Float_t *stran,const Float_t *srot){
790     //     This function performs a Gaussian random displacement and/or
791     // rotation about the present global position of each active
792     // volume/detector of the ITS. The sigma of the random displacement
793     // is determined by the three element array stran, for the
794     // x y and z translations, and the three element array srot,
795     // for the three rotation about the axis x y and z.
796     // Intputs:
797     //     Float_t *stran  A 3 element array representing the global 
798     //                     translations variances. The elements are x,
799     //                     y,z in cm.
800     //     Float_t *srot   A 3 element array representing the global rotation
801     //                     angles variances about the three axis x,y,z in 
802     //                     radians.
803     // Outputs:
804     //     none.
805     // Return:
806     //     none.
807     Int_t    i,j;
808     Double_t t[3],r[3];
809     AliITSgeomMatrix *g;
810
811     fTrans = (fTrans && 0xfffd) + 2;  // set bit 1 true.
812     for(i=0;i<fNmodules;i++){
813         g = this->GetGeomMatrix(i);
814         g->GetTranslation(t);
815         g->GetAngles(r);
816         for(j=0;j<3;j++){
817             t[j] += gRandom->Gaus(0.0,stran[j]);
818             r[j] += gRandom->Gaus(0.0, srot[j]);
819         } // end for j
820         g->SetTranslation(t);
821         g->SetAngles(r);
822     } // end for i
823     return;
824 }
825 //______________________________________________________________________
826 void AliITSgeom::RandomCylindericalChange(const Float_t *stran,
827                                           const Float_t *srot){
828     //     This function performs a Gaussian random displacement and/or
829     // rotation about the present global position of each active
830     // volume/detector of the ITS. The sigma of the random displacement
831     // is determined by the three element array stran, for the
832     // r rphi and z translations, and the three element array srot,
833     // for the three rotation about the axis x y and z. This random change
834     // in detector position allow for the simulation of a random uncertainty
835     // in the detector positions of the ITS.
836     // Intputs:
837     //     Float_t *stran  A 3 element array representing the global 
838     //                     translations variances. The elements are r,
839     //                     theta,z in cm/radians.
840     //     Float_t *srot   A 3 element array representing the global rotation
841     //                     angles variances about the three axis x,y,z in 
842     //                     radians.
843     // Outputs:
844     //     none.
845     // Return:
846     //     none.
847     Int_t    i,j;
848     Double_t t[3],ro[3],r,r0,phi,rphi;
849     TRandom ran;
850     AliITSgeomMatrix *g;
851
852     fTrans = (fTrans && 0xfffd) + 2;  // set bit 1 true.
853     for(i=0;i<fNmodules;i++){
854         g = this->GetGeomMatrix(i);
855         g->GetTranslation(t);
856         g->GetAngles(ro);
857         r = r0= TMath::Hypot(t[1],t[0]);
858         phi   = TMath::ATan2(t[1],t[0]);
859         rphi  = r0*phi;
860         r    += ran.Gaus(0.0,stran[0]);
861         rphi += ran.Gaus(0.0,stran[1]);
862         phi   = rphi/r0;
863         t[0]  = r*TMath::Cos(phi);
864         t[1]  = r*TMath::Sin(phi);
865         t[2] += ran.Gaus(0.0,stran[2]);
866         for(j=0;j<3;j++){
867             ro[j] += ran.Gaus(0.0, srot[j]);
868         } // end for j
869         g->SetTranslation(t);
870         g->SetAngles(ro);
871     } // end for i
872     return;
873 }
874 //______________________________________________________________________
875 void AliITSgeom::GeantToTracking(const AliITSgeom &source){
876     //     Copy the geometry data but change it to go between the ALICE
877     // Global coordinate system to that used by the ITS tracking. A slightly
878     // different coordinate system is used when tracking. This coordinate 
879     // system is only relevant when the geometry represents the cylindrical
880     // ALICE ITS geometry. For tracking the Z axis is left alone but X-> -Y
881     // and Y-> X such that X always points out of the ITS cylinder for every
882     // layer including layer 1 (where the detectors are mounted upside down).
883     //Begin_Html
884     /*
885       <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
886     */
887     //End_Html
888     // Input:
889     //     AliITSgeom &source  The AliITSgeom class with which to make this
890     //                         a copy of.
891     // Output:
892     //     none.
893     // Return:
894     //     none.
895     Int_t    i,j,k,l,id[3];
896     Double_t r0[3][3],r1[3][3];
897     Double_t a0[3][3] = {{0.,+1.,0.},{-1.,0.,0.},{0.,0.,+1.}};
898     Double_t a1[3][3] = {{0.,-1.,0.},{+1.,0.,0.},{0.,0.,+1.}};
899
900     *this = source;  // copy everything
901     for(i=0;i<GetIndexMax();i++){
902         GetGeomMatrix(i)->GetIndex(id);
903         GetGeomMatrix(i)->GetMatrix(r0);
904         if(id[0]==1){ // Layer 1 is treated different from the others.
905             for(j=0;j<3;j++) for(k=0;k<3;k++){
906                 r1[j][k] = 0.;
907                 for(l=0;l<3;l++) r1[j][k] += a0[j][l]*r0[l][k];
908             } // end for j,k
909         }else{
910             for(j=0;j<3;j++) for(k=0;k<3;k++){
911                 r1[j][k] = 0.;
912                 for(l=0;l<3;l++) r1[j][k] += a1[j][l]*r0[l][k];
913             } // end for j,k
914         } // end if
915         GetGeomMatrix(i)->SetMatrix(r1);
916     } // end for i
917     this->fTrans = (this->fTrans && 0xfffe) + 1;  // set bit 0 true.
918     return;
919 }
920 //______________________________________________________________________
921 Int_t AliITSgeom::GetNearest(const Double_t g[3],Int_t lay)const{
922     //      Finds the Detector (Module) that is nearest the point g [cm] in
923     // ALICE Global coordinates. If layer !=0 then the search is restricted
924     // to Detectors (Modules) in that particular layer.
925     // Inputs:
926     //     Double_t g[3]  The ALICE Cartesian global coordinate from which the
927     //                    distance is to be calculated with.
928     //     Int_t lay      The layer to restrict the search to. If layer=0 then
929     //                    all layers are searched. Default is lay=0.
930     // Output:
931     //     none.
932     // Return:
933     //     The module number representing the nearest module.
934     Int_t    i,l,a,e,in=0;
935     Double_t d,dn=1.0e10;
936     Bool_t   t=lay!=0; // skip if lay = 0 default value check all layers.
937
938     for(i=0;i<fNmodules;i++){
939         if(t){GetModuleId(i,l,a,e);if(l!=lay) continue;}
940         if((d=GetGeomMatrix(i)->Distance2(g))<dn){
941             dn = d;
942             in = i;
943         } // end if
944     } // end for i
945     return in;
946 }
947 //______________________________________________________________________
948 void AliITSgeom::GetNearest27(const Double_t g[3],Int_t n[27],Int_t lay)const{
949     //      Finds 27 Detectors (Modules) that are nearest the point g [cm] in
950     // ALICE Global coordinates. If layer !=0 then the search is restricted
951     // to Detectors (Modules) in that particular layer. The number 27 comes 
952     // from including the nearest detector and all those around it (up, down,
953     // left, right, forwards, backwards, and the corners).
954     // Input:
955     //     Double_t g[3]  The ALICE Cartesian global coordinate from which the
956     //                    distance is to be calculated with.
957     //     Int_t lay      The layer to restrict the search to. If layer=0 then
958     //                    all layers are searched. Default is lay=0.
959     // Output:
960     //     Int_t n[27]    The module number representing the nearest 27 modules
961     //                    in order.
962     // Return:
963     //     none.
964     Int_t    i,l,a,e,in[27]={0,0,0,0,0,0,0,0,0,
965                              0,0,0,0,0,0,0,0,0,
966                              0,0,0,0,0,0,0,0,0,};
967     Double_t d,dn[27]={1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,
968                        1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,
969                        1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,
970                        1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,
971                        1.0e10,1.0e10,1.0e10};
972     Bool_t   t=(lay!=0); // skip if lay = 0 default value check all layers.
973
974     for(i=0;i<fNmodules;i++){
975         if(t){GetModuleId(i,l,a,e);if(l!=lay) continue;}
976         for(a=0;a<27;a++){
977             d = GetGeomMatrix(i)->Distance2(g);
978             if(d<dn[a]){
979                 for(e=26;e>a;e--){dn[e] = dn[e-1];in[e] = in[e-1];}
980                 dn[a] = d; in[a] = i;
981             } // end if d<dn[i]
982         } // end for a
983     } // end for i
984     for(i=0;i<27;i++) n[i] = in[i];
985 }
986 //_______________________________________________________________________
987 void AliITSgeom::DetLToTrackingV2(Int_t md,Float_t xin,Float_t zin,
988                                   Float_t &yout,Float_t &zout) {
989
990     //Conversion from local coordinates on detectors to local
991     //coordinates used for tracking ("v2")
992     // Inputs:
993     //   Int_t   md      Module number
994     //   Float_t xin     Standard local coordinate x
995     //   Float_t zin     Standard local coordinate z
996     // Output:
997     //   Float_t yout    Tracking local coordinate y
998     //   Float_t zout    Tracking local coordinate z
999     // Return:
1000     //   none.
1001     Float_t x,y,z;
1002     Double_t rt[9],al;
1003
1004     GetTrans(md,x,y,z);
1005     GetRotMatrix(md,rt);
1006     al = TMath::ATan2(rt[1],rt[0])+TMath::Pi();
1007     yout = -(-xin+(x*((Float_t)TMath::Cos(al))+y*((Float_t)TMath::Sin(al))));
1008     if(md<(GetModuleIndex(2,1,1))) yout *= -1; 
1009     zout = -zin+z; 
1010 }
1011 //_______________________________________________________________________
1012 void AliITSgeom::TrackingV2ToDetL(Int_t md,Float_t yin,Float_t zin,
1013                                   Float_t &xout,Float_t &zout) {
1014     //Conversion from local coordinates used for tracking ("v2") to
1015     //local detector coordinates  
1016     // Inputs:
1017     //   Int_t   md      Module number
1018     //   Float_t yin     Tracking local coordinate y
1019     //   Float_t zin     Tracking local coordinate z
1020     // Output:
1021     //   Float_t xout    Standard local coordinate x
1022     //   Float_t zout    Standard local coordinate z
1023     // Return:
1024     //   none.
1025     Float_t x,y,z;
1026     Double_t rt[9],al;
1027
1028     GetTrans(md,x,y,z);
1029     GetRotMatrix(md,rt);
1030     al = TMath::ATan2(rt[1],rt[0])+TMath::Pi();
1031     xout = yin;
1032     if(md<(GetModuleIndex(2,1,1))) xout = -xout;
1033     xout += (x*((Float_t)TMath::Cos(al))+y*((Float_t)TMath::Sin(al)));
1034     zout  = -zin+z; 
1035 }
1036 //----------------------------------------------------------------------
1037