remove props
[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 void AliITSgeom::PrintGeom(ostream *wb)const{
593     //     Stream out an object of class AliITSgeom to standard output.
594     // Intputs:
595     //     ofstream *wb    The output streaming buffer.
596     // Outputs:
597     //     none.
598     // Return:
599     //     none.
600   Int_t i;
601
602     wb->setf(ios::scientific);
603     streamsize stsiz = wb->precision();
604     *wb << fTrans << " ";
605     *wb << fNmodules << " ";
606     *wb << fNlayers << " ";
607     for(i=0;i<fNlayers;i++) *wb << fNlad[i] << " ";
608     for(i=0;i<fNlayers;i++) *wb << fNdet[i] << "\n";
609     for(i=0;i<fNmodules;i++) {
610         *wb <<setprecision(16) << *(GetGeomMatrix(i)) << "\n";
611     } // end for i
612     *wb << setprecision (stsiz);
613     return;
614 }
615 */
616 //______________________________________________________________________
617 //     The following routines modify the transformation of "this"
618 // geometry transformations in a number of different ways.
619 //______________________________________________________________________
620 void AliITSgeom::GlobalChange(const Float_t *tran,const Float_t *rot){
621     //     This function performs a Cartesian translation and rotation of
622     // the full ITS from its default position by an amount determined by
623     // the three element arrays tran and rot. If every element
624     // of tran and rot are zero then there is no change made
625     // the geometry. The change is global in that the exact same translation
626     // and rotation is done to every detector element in the exact same way.
627     // The units of the translation are those of the Monte Carlo, usually cm,
628     // and those of the rotation are in radians. The elements of tran
629     // are tran[0] = x, tran[1] = y, and tran[2] = z.
630     // The elements of rot are rot[0] = rx, rot[1] = ry, and
631     // rot[2] = rz. A change in x will move the hole ITS in the ALICE
632     // global x direction, the same for a change in y. A change in z will
633     // result in a translation of the ITS as a hole up or down the beam line.
634     // A change in the angles will result in the inclination of the ITS with
635     // respect to the beam line, except for an effective rotation about the
636     // beam axis which will just rotate the ITS as a hole about the beam axis.
637     // Intputs:
638     //     Float_t *tran   A 3 element array representing the global 
639     //                     translations. the elements are x,y,z in cm.
640     //     Float_t *rot    A 3 element array representing the global rotation
641     //                     angles about the three axis x,y,z in radians
642     // Outputs:
643     //     none.
644     // Return:
645     //     none.
646     Int_t    i,j;
647     Double_t t[3],r[3];
648     AliITSgeomMatrix *g;
649
650     fTrans = (fTrans && 0xfffd) + 2;  // set bit 1 true.
651     for(i=0;i<fNmodules;i++){
652         g = this->GetGeomMatrix(i);
653         g->GetTranslation(t);
654         g->GetAngles(r);
655         for(j=0;j<3;j++){
656             t[j] += tran[j];
657             r[j] += rot[j];
658         } // end for j
659         g->SetTranslation(t);
660         g->SetAngles(r);
661     } // end for i
662     return;
663 }
664 //______________________________________________________________________
665 void AliITSgeom::GlobalCylindericalChange(const Float_t *tran,
666                                           const Float_t *rot){
667     //     This function performs a cylindrical translation and rotation of
668     // each ITS element by a fixed about in radius, rphi, and z from its
669     // default position by an amount determined by the three element arrays
670     // tran and rot. If every element of tran and
671     // rot are zero then there is no change made the geometry. The
672     // change is global in that the exact same distance change in translation
673     // and rotation is done to every detector element in the exact same way.
674     // The units of the translation are those of the Monte Carlo, usually cm,
675     // and those of the rotation are in radians. The elements of tran
676     // are tran[0] = r, tran[1] = rphi, and tran[2] = z.
677     // The elements of rot are rot[0] = rx, rot[1] = ry, and
678     // rot[2] = rz. A change in r will results in the increase of the
679     // radius of each layer by the same about. A change in rphi will results in
680     // the rotation of each layer by a different angle but by the same
681     // circumferential distance. A change in z will result in a translation
682     // of the ITS as a hole up or down the beam line. A change in the angles
683     // will result in the inclination of the ITS with respect to the beam
684     // line, except for an effective rotation about the beam axis which will
685     // just rotate the ITS as a hole about the beam axis.
686     // Intputs:
687     //     Float_t *tran   A 3 element array representing the global 
688     //                     translations. the elements are r,theta,z in 
689     //                     cm/radians.
690     //     Float_t *rot    A 3 element array representing the global rotation
691     //                     angles about the three axis x,y,z in radians
692     // Outputs:
693     //     none.
694     // Return:
695     //     none.
696     Int_t    i,j;
697     Double_t t[3],ro[3],r,r0,phi,rphi;
698     AliITSgeomMatrix *g;
699
700     fTrans = (fTrans && 0xfffd) + 2;  // set bit 1 true.
701     for(i=0;i<fNmodules;i++){
702         g = this->GetGeomMatrix(i);
703         g->GetTranslation(t);
704         g->GetAngles(ro);
705         r = r0= TMath::Hypot(t[1],t[0]);
706         phi   = TMath::ATan2(t[1],t[0]);
707         rphi  = r0*phi;
708         r    += tran[0];
709         rphi += tran[1];
710         phi   = rphi/r0;
711         t[0]  = r*TMath::Cos(phi);
712         t[1]  = r*TMath::Sin(phi);
713         t[2] += tran[2];
714         for(j=0;j<3;j++){
715             ro[j] += rot[j];
716         } // end for j
717         g->SetTranslation(t);
718         g->SetAngles(ro);
719     } // end for i
720     return;
721 }
722 //______________________________________________________________________
723 void AliITSgeom::RandomChange(const Float_t *stran,const Float_t *srot){
724     //     This function performs a Gaussian random displacement and/or
725     // rotation about the present global position of each active
726     // volume/detector of the ITS. The sigma of the random displacement
727     // is determined by the three element array stran, for the
728     // x y and z translations, and the three element array srot,
729     // for the three rotation about the axis x y and z.
730     // Intputs:
731     //     Float_t *stran  A 3 element array representing the global 
732     //                     translations variances. The elements are x,
733     //                     y,z in cm.
734     //     Float_t *srot   A 3 element array representing the global rotation
735     //                     angles variances about the three axis x,y,z in 
736     //                     radians.
737     // Outputs:
738     //     none.
739     // Return:
740     //     none.
741     Int_t    i,j;
742     Double_t t[3],r[3];
743     AliITSgeomMatrix *g;
744
745     fTrans = (fTrans && 0xfffd) + 2;  // set bit 1 true.
746     for(i=0;i<fNmodules;i++){
747         g = this->GetGeomMatrix(i);
748         g->GetTranslation(t);
749         g->GetAngles(r);
750         for(j=0;j<3;j++){
751             t[j] += gRandom->Gaus(0.0,stran[j]);
752             r[j] += gRandom->Gaus(0.0, srot[j]);
753         } // end for j
754         g->SetTranslation(t);
755         g->SetAngles(r);
756     } // end for i
757     return;
758 }
759 //______________________________________________________________________
760 void AliITSgeom::RandomCylindericalChange(const Float_t *stran,
761                                           const Float_t *srot){
762     //     This function performs a Gaussian random displacement and/or
763     // rotation about the present global position of each active
764     // volume/detector of the ITS. The sigma of the random displacement
765     // is determined by the three element array stran, for the
766     // r rphi and z translations, and the three element array srot,
767     // for the three rotation about the axis x y and z. This random change
768     // in detector position allow for the simulation of a random uncertainty
769     // in the detector positions of the ITS.
770     // Intputs:
771     //     Float_t *stran  A 3 element array representing the global 
772     //                     translations variances. The elements are r,
773     //                     theta,z in cm/radians.
774     //     Float_t *srot   A 3 element array representing the global rotation
775     //                     angles variances about the three axis x,y,z in 
776     //                     radians.
777     // Outputs:
778     //     none.
779     // Return:
780     //     none.
781     Int_t    i,j;
782     Double_t t[3],ro[3],r,r0,phi,rphi;
783     TRandom ran;
784     AliITSgeomMatrix *g;
785
786     fTrans = (fTrans && 0xfffd) + 2;  // set bit 1 true.
787     for(i=0;i<fNmodules;i++){
788         g = this->GetGeomMatrix(i);
789         g->GetTranslation(t);
790         g->GetAngles(ro);
791         r = r0= TMath::Hypot(t[1],t[0]);
792         phi   = TMath::ATan2(t[1],t[0]);
793         rphi  = r0*phi;
794         r    += ran.Gaus(0.0,stran[0]);
795         rphi += ran.Gaus(0.0,stran[1]);
796         phi   = rphi/r0;
797         t[0]  = r*TMath::Cos(phi);
798         t[1]  = r*TMath::Sin(phi);
799         t[2] += ran.Gaus(0.0,stran[2]);
800         for(j=0;j<3;j++){
801             ro[j] += ran.Gaus(0.0, srot[j]);
802         } // end for j
803         g->SetTranslation(t);
804         g->SetAngles(ro);
805     } // end for i
806     return;
807 }
808 //______________________________________________________________________
809 void AliITSgeom::GeantToTracking(const AliITSgeom &source){
810     //     Copy the geometry data but change it to go between the ALICE
811     // Global coordinate system to that used by the ITS tracking. A slightly
812     // different coordinate system is used when tracking. This coordinate 
813     // system is only relevant when the geometry represents the cylindrical
814     // ALICE ITS geometry. For tracking the Z axis is left alone but X-> -Y
815     // and Y-> X such that X always points out of the ITS cylinder for every
816     // layer including layer 1 (where the detectors are mounted upside down).
817     //Begin_Html
818     /*
819       <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
820     */
821     //End_Html
822     // Input:
823     //     AliITSgeom &source  The AliITSgeom class with which to make this
824     //                         a copy of.
825     // Output:
826     //     none.
827     // Return:
828     //     none.
829     Int_t    i,j,k,l,id[3];
830     Double_t r0[3][3],r1[3][3];
831     Double_t a0[3][3] = {{0.,+1.,0.},{-1.,0.,0.},{0.,0.,+1.}};
832     Double_t a1[3][3] = {{0.,-1.,0.},{+1.,0.,0.},{0.,0.,+1.}};
833
834     *this = source;  // copy everything
835     for(i=0;i<GetIndexMax();i++){
836         GetGeomMatrix(i)->GetIndex(id);
837         GetGeomMatrix(i)->GetMatrix(r0);
838         if(id[0]==1){ // Layer 1 is treated different from the others.
839             for(j=0;j<3;j++) for(k=0;k<3;k++){
840                 r1[j][k] = 0.;
841                 for(l=0;l<3;l++) r1[j][k] += a0[j][l]*r0[l][k];
842             } // end for j,k
843         }else{
844             for(j=0;j<3;j++) for(k=0;k<3;k++){
845                 r1[j][k] = 0.;
846                 for(l=0;l<3;l++) r1[j][k] += a1[j][l]*r0[l][k];
847             } // end for j,k
848         } // end if
849         GetGeomMatrix(i)->SetMatrix(r1);
850     } // end for i
851     this->fTrans = (this->fTrans && 0xfffe) + 1;  // set bit 0 true.
852     return;
853 }
854 //______________________________________________________________________
855 Int_t AliITSgeom::GetNearest(const Double_t g[3],Int_t lay)const{
856     //      Finds the Detector (Module) that is nearest the point g [cm] in
857     // ALICE Global coordinates. If layer !=0 then the search is restricted
858     // to Detectors (Modules) in that particular layer.
859     // Inputs:
860     //     Double_t g[3]  The ALICE Cartesian global coordinate from which the
861     //                    distance is to be calculated with.
862     //     Int_t lay      The layer to restrict the search to. If layer=0 then
863     //                    all layers are searched. Default is lay=0.
864     // Output:
865     //     none.
866     // Return:
867     //     The module number representing the nearest module.
868     Int_t    i,l,a,e,in=0;
869     Double_t d,dn=1.0e10;
870     Bool_t   t=lay!=0; // skip if lay = 0 default value check all layers.
871
872     for(i=0;i<fNmodules;i++){
873         if(t){GetModuleId(i,l,a,e);if(l!=lay) continue;}
874         if((d=GetGeomMatrix(i)->Distance2(g))<dn){
875             dn = d;
876             in = i;
877         } // end if
878     } // end for i
879     return in;
880 }
881 //______________________________________________________________________
882 void AliITSgeom::GetNearest27(const Double_t g[3],Int_t n[27],Int_t lay)const{
883     //      Finds 27 Detectors (Modules) that are nearest the point g [cm] in
884     // ALICE Global coordinates. If layer !=0 then the search is restricted
885     // to Detectors (Modules) in that particular layer. The number 27 comes 
886     // from including the nearest detector and all those around it (up, down,
887     // left, right, forwards, backwards, and the corners).
888     // Input:
889     //     Double_t g[3]  The ALICE Cartesian global coordinate from which the
890     //                    distance is to be calculated with.
891     //     Int_t lay      The layer to restrict the search to. If layer=0 then
892     //                    all layers are searched. Default is lay=0.
893     // Output:
894     //     Int_t n[27]    The module number representing the nearest 27 modules
895     //                    in order.
896     // Return:
897     //     none.
898     Int_t    i,l,a,e,in[27]={0,0,0,0,0,0,0,0,0,
899                              0,0,0,0,0,0,0,0,0,
900                              0,0,0,0,0,0,0,0,0,};
901     Double_t d,dn[27]={1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,
902                        1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,
903                        1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,
904                        1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,
905                        1.0e10,1.0e10,1.0e10};
906     Bool_t   t=(lay!=0); // skip if lay = 0 default value check all layers.
907
908     for(i=0;i<fNmodules;i++){
909         if(t){GetModuleId(i,l,a,e);if(l!=lay) continue;}
910         for(a=0;a<27;a++){
911             d = GetGeomMatrix(i)->Distance2(g);
912             if(d<dn[a]){
913                 for(e=26;e>a;e--){dn[e] = dn[e-1];in[e] = in[e-1];}
914                 dn[a] = d; in[a] = i;
915             } // end if d<dn[i]
916         } // end for a
917     } // end for i
918     for(i=0;i<27;i++) n[i] = in[i];
919 }
920 //_______________________________________________________________________
921 void AliITSgeom::DetLToTrackingV2(Int_t md,Float_t xin,Float_t zin,
922                                   Float_t &yout,Float_t &zout) {
923
924     //Conversion from local coordinates on detectors to local
925     //coordinates used for tracking ("v2")
926     // Inputs:
927     //   Int_t   md      Module number
928     //   Float_t xin     Standard local coordinate x
929     //   Float_t zin     Standard local coordinate z
930     // Output:
931     //   Float_t yout    Tracking local coordinate y
932     //   Float_t zout    Tracking local coordinate z
933     // Return:
934     //   none.
935     Float_t x,y,z;
936     Double_t rt[9],al;
937
938     GetTrans(md,x,y,z);
939     GetRotMatrix(md,rt);
940     al = TMath::ATan2(rt[1],rt[0])+TMath::Pi();
941     yout = -(-xin+(x*((Float_t)TMath::Cos(al))+y*((Float_t)TMath::Sin(al))));
942     if(md<(GetModuleIndex(2,1,1))) yout *= -1; 
943     zout = -zin+z; 
944 }
945 //_______________________________________________________________________
946 void AliITSgeom::TrackingV2ToDetL(Int_t md,Float_t yin,Float_t zin,
947                                   Float_t &xout,Float_t &zout) {
948     //Conversion from local coordinates used for tracking ("v2") to
949     //local detector coordinates  
950     // Inputs:
951     //   Int_t   md      Module number
952     //   Float_t yin     Tracking local coordinate y
953     //   Float_t zin     Tracking local coordinate z
954     // Output:
955     //   Float_t xout    Standard local coordinate x
956     //   Float_t zout    Standard local coordinate z
957     // Return:
958     //   none.
959     Float_t x,y,z;
960     Double_t rt[9],al;
961
962     GetTrans(md,x,y,z);
963     GetRotMatrix(md,rt);
964     al = TMath::ATan2(rt[1],rt[0])+TMath::Pi();
965     xout = yin;
966     if(md<(GetModuleIndex(2,1,1))) xout = -xout;
967     xout += (x*((Float_t)TMath::Cos(al))+y*((Float_t)TMath::Sin(al)));
968     zout  = -zin+z; 
969 }
970 //----------------------------------------------------------------------
971