]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSgeom.cxx
Delete only existent objects.
[u/mrichter/AliRoot.git] / ITS / AliITSgeom.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /*
17 $Log$
18 Revision 1.4.4.5  2000/03/04 23:42:39  nilsen
19 Updated the comments/documentations and improved the maintainability of the
20 code.
21
22 Revision 1.4.4.4  2000/03/02 21:27:07  nilsen
23 Added two functions, SetByAngles and SetTrans.
24
25 Revision 1.4.4.3  2000/01/23 03:09:10  nilsen
26 // fixed compiler warnings for new function LtLErrorMatrix(...)
27
28 Revision 1.4.4.2  2000/01/19 23:18:20  nilsen
29 Added transformations of Error matrix to AliITSgeom and fixed some typos
30 in AliITS.h and AliITShitIndex.h
31
32 Revision 1.4.4.1  2000/01/12 19:03:32  nilsen
33 This is the version of the files after the merging done in December 1999.
34 See the ReadMe110100.txt file for details
35
36 Revision 1.4  1999/10/15 07:03:20  fca
37 Fixed bug in GetModuleId(Int_t index,Int_t &lay,Int_t &lad, Int_t &det) and
38 a typo in the creator. aliroot need to be rerun to get a fixed geometry.
39
40 Revision 1.3  1999/10/04 15:20:12  fca
41 Correct syntax accepted by g++ but not standard for static members, remove minor warnings
42
43 Revision 1.2  1999/09/29 09:24:20  fca
44 Introduction of the Copyright and cvs Log
45
46 */
47
48 ///////////////////////////////////////////////////////////////////////
49 // ITS geometry manipulation routines.                               //
50 // Created April 15 1999.                                            //
51 // version: 0.0.0                                                    //
52 // By: Bjorn S. Nilsen                                               //
53 // version: 0.0.1                                                    //
54 // Updated May 27 1999.                                              //
55 // Added Cylindrical random and global based changes.               //
56 // Added  function PrintComparison.                                  //
57 ///////////////////////////////////////////////////////////////////////
58
59
60 ////////////////////////////////////////////////////////////////////////
61 // The structure ITS_geom:
62 //     The structure ITS_geom has been defined to hold all of the
63 // information necessary to do the coordinate transformations for one
64 // detector between the ALICE Cartesian global and the detector local
65 // coordinate systems. The rotations are implemented in the following
66 // order, Rz*Ry*Rx*(Vglobal-Vtrans)=Vlocal (in matrix notation). 
67 // In addition it contains an index to the TObjArray containing all of
68 // the information about the shape of the active detector volume, and
69 // any other useful detector parameters. See the definition of *fShape
70 // below and the classes AliITSgeomSPD, AliITSgeomSDD, and AliITSgeomSSD
71 // for a full description. This structure is not available outside of 
72 // these routines.
73 //
74 // Int_t fShapeIndex
75 //     The index to the array of detector shape information. In this way
76 // only an index is needed to be stored and not all of the shape
77 // information. This saves much space since most, if not all, of the
78 // detectors of a give type have the same shape information and are only
79 // placed in a different spot in the ALICE/ITS detector.
80 //
81 // Float_t fx0,fy0,fz0
82 //     The Cartesian translation vector used to define part of the
83 // coordinate transformation. The units of the translation are kept
84 // in the Monte Carlo distance units, usually cm.
85 //
86 // Float_t frx,fry,frz
87 //     The three rotation angles that define the rotation matrix. The
88 // angles are, frx the rotation about the x axis. fry the rotation about
89 // the "new" or "rotated" y axis. frz the rotation about the "new" or
90 // "rotated" z axis. These angles, although redundant with the rotation
91 // matrix fr, are kept for speed. This allows for their retrieval without
92 // having to compute them each and every time. The angles are kept in
93 // radians
94 //
95 // Float_t fr[9]
96 //     The 3x3 rotation matrix defined by the angles frx, fry, and frz,
97 // for the Global to Local transformation is
98 //    |fr[0] fr[1] fr[2]| | cos(frz)  sin(frz) 0| | cos(fry) 0  sin(fry)|
99 // fr=|fr[3] fr[4] fr[4]|=|-sin(frz)  cos(frz) 0|*|   0      1    0     |
100 //    |fr[6] fr[7] fr[8]| |   0         0      1| |-sin(fry) 0  cos(fry)|
101 //
102 //    |1    0        0     |
103 //   *|0  cos(frx) sin(frx)|
104 //    |0 -sin(frx) cos(frx)|
105 //
106 // Even though this information is redundant with the three rotation
107 // angles, because this transformation matrix can be used so much it is
108 // kept to speed things up a lot. The coordinate system used is Cartesian.
109 //
110 //     The local coordinate system by, default, is show in the following
111 // figures. Also shown are the ladder numbering scheme.
112 //Begin_Html
113 /*
114 <img src="picts/ITS/its1+2_convention_front_5.gif">
115 </pre>
116 <br clear=left>
117 <font size=+2 color=blue>
118 <p>This shows the front view of the SPDs and the orientation of the local
119 pixel coordinate system. Note that the inner pixel layer has its y coordinate
120 in the opposite direction from all of the other layers.
121 </font>
122 <pre>
123
124 <pre>
125 <img src="picts/ITS/its3+4_convention_front_5.gif">
126 </pre>
127 <br clear=left>
128 <font size=+2 color=blue>
129 <p>This shows the front view of the SDDs and the orientation of the local
130 pixel coordinate system.
131 </font>
132 <pre>
133
134 <pre>
135 <img src="picts/ITS/its5+6_convention_front_5.gif">
136 </pre>
137 <br clear=left>
138 <font size=+2 color=blue>
139 <p>This shows the front view of the SSDs and the orientation of the local
140 pixel coordinate system.
141 </font>
142 <pre>
143 */
144 //End_Html
145
146 ////////////////////////////////////////////////////////////////////////
147
148 ////////////////////////////////////////////////////////////////////////
149 //
150 // version: 0
151 // Written by Bjorn S. Nilsen
152 //
153 // Data Members:
154 //
155 // Int_t fNlayers
156 //     The number of ITS layers for this geometry. By default this
157 //  is 6, but can be modified by the creator function if there are
158 // more layers defined.
159 //
160 // Int_t *fNlad
161 //     A pointer to an array fNlayers long containing the number of 
162 // ladders for each layer. This array is typically created and filled 
163 // by the AliITSgeom creator function.
164 //
165 // Int_t *fNdet
166 //     A pointer to an array fNlayers long containing the number of
167 // active detector volumes for each ladder. This array is typically
168 // created and filled by the AliITSgeom creator function.
169 //
170 // ITS_geom **fg
171 //     A pointer to an array of pointers pointing to the ITS_geom
172 // structure containing the coordinate transformation information.
173 // The ITS_geom structure corresponding to layer=lay, ladder=lad,
174 // and detector=det is gotten by fg[lay-1][(fNlad[lay-1]*(lad-1)+det-1)].
175 // In this way a lot of space is saved over trying to keep a three
176 // dimensional array fNlayersXmax(fNlad)Xmax(fNdet), since the number
177 // of detectors typically increases with layer number.
178 //
179 // TObjArray *fShape
180 //     A pointer to an array of TObjects containing the detailed shape
181 // information for each type of detector used in the ITS. For example
182 // I have created AliITSgeomSPD, AliITSgeomSDD, and AliITSgeomSSD as
183 // example structures, derived from TObjects, to hold the detector
184 // information. I would recommend that one element in each of these
185 // structures, that which describes the shape of the active volume,
186 // be one of the ROOT classes derived from TShape. In this way it would
187 // be easy to have the display program display the correct active
188 // ITS volumes. See the example classes AliITSgeomSPD, AliITSgeomSDD,
189 // and AliITSgeomSSD for a more detailed example.
190 //
191 // Inlined Member Functions:
192 //
193 // Int_t GetNdetectors(Int_t layer)
194 //     This function returns the number of detectors/ladder for a give 
195 // layer. In particular it returns fNdet[layer-1].
196 //
197 // Int_t GetNladders(Int_t layer)
198 //     This function returns the number of ladders for a give layer. In
199 // particular it returns fNlad[layer-1].
200 //
201 // Int_t GetNlayers()
202 //     This function returns the number of layers defined in the ITS
203 // geometry. In particular it returns fNlayers.
204 //
205 // GetAngles(Int_t layer,Int_t ladder,Int_t detector,
206 //           Float_t &rx, Float_t &ry, Float_t &rz)
207 //     This function returns the rotation angles for a give detector on
208 // a give ladder in a give layer in the three floating point variables
209 // provided. rx = frx, fy = fry, rz = frz. The angles are in radians
210 //
211 // GetTrans(Int_t layer,Int_t ladder,Int_t detector,
212 //          Float_t &x, Float_t &y, Float_t &z)
213 //     This function returns the Cartesian translation for a give
214 // detector on a give ladder in a give layer in the three floating
215 // point variables provided. x = fx0, y = fy0, z = fz0. The units are
216 // those of the Monte Carlo, generally cm.
217 //
218 // SetTrans(Int_t layer,Int_t ladder,Int_t detector,
219 //          Float_t x, Float_t y, Float_t z)
220 //     This function sets a new translation vector, given by the three
221 // variables x, y, and z, for the Cartesian coordinate transformation
222 // for the detector defined by layer, ladder and detector.
223 //
224 // Int_t IsVersion()
225 //     This function returns the version number of this AliITSgeom
226 // class.
227 //
228 // AddShape(TObject *shape)
229 //     This function adds one more shape element to the TObjArray
230 // fShape. It is primarily used in the constructor functions of the
231 // AliITSgeom class. The pointer *shape can be the pointer to any
232 // class that is derived from TObject (this is true for nearly every
233 // ROOT class). This does not appear to be working properly at this time.
234 //
235 // Int_t GetStartSPD()
236 //     This functions returns the starting module index number for the
237 // silicon pixels detectors (SPD). Typically this is zero. To loop over all
238 // of the pixel detectors do: for(Int_t i=GetStartSPD();i<=GetLastSPD();i++)
239 //
240 // Int_t GetLastSPD()
241 //     This functions returns the last module index number for the
242 // silicon pixels detectors (SPD). To loop over all of the pixel detectors 
243 // do: for(Int_t i=GetStartSPD();i<=GetLastSPD();i++)
244 //
245 // Int_t GetStartSDD()
246 //     This functions returns the starting module index number for the
247 // silicon drift detectors (SDD). To loop over all of the drift detectors 
248 // do: for(Int_t i=GetStartSDD();i<=GetLastSDD();i++)
249 //
250 // Int_t GetLastSDD()
251 //     This functions returns the last module index number for the
252 // silicon drift detectors (SDD). To loop over all of the drift detectors 
253 // do: for(Int_t i=GetStartSDD();i<=GetLastSDD();i++)
254 //
255 // Int_t GetStartSSD()
256 //     This functions returns the starting module index number for the
257 // silicon strip detectors (SSD). To loop over all of the strip detectors 
258 // do: for(Int_t i=GetStartSSD();i<=GetLastSSD();i++)
259 //
260 // Int_t GetStartSSD()
261 //     This functions returns the last module index number for the
262 // silicon strip detectors (SSD). To loop over all of the strip detectors 
263 // do: for(Int_t i=GetStartSSD();i<=GetLastSSD();i++)
264 //
265 // TObject *GetShape(Int_t lay,Int_t lad,Int_t det)
266 //     This functions returns the shape object AliITSgeomSPD, AliITSgeomSDD,
267 // or AliITSgeomSSD for that particular module designated by lay, lad, and
268 // detector. In principle there can be additional shape objects. In this
269 // way a minimum of shape objects are created since one AliITSgeomS?D shape
270 // object is used for all modules of that type.
271 ////////////////////////////////////////////////////////////////////////
272
273 #include <iostream.h>
274 #include <fstream.h>
275 #include <iomanip.h>
276 #include <stdio.h>
277 #include "AliITSgeom.h"
278 #include "AliITSgeomSPD.h"
279 #include "TRandom.h"
280
281 ClassImp(AliITSgeom)
282
283 //_____________________________________________________________________
284 AliITSgeom::AliITSgeom(){
285 ////////////////////////////////////////////////////////////////////////
286 //     The default constructor for the AliITSgeom class. It, by default,
287 // sets fNlayers to zero and zeros all pointers.
288 ////////////////////////////////////////////////////////////////////////
289   // Default constructor.
290   // Do not allocate anything zero everything
291    fNlayers = 0;
292    fNlad    = 0;
293    fNdet    = 0;
294    fg       = 0;
295    fShape   = 0;
296    return;
297 }
298
299 //_____________________________________________________________________
300 AliITSgeom::~AliITSgeom(){
301 ////////////////////////////////////////////////////////////////////////
302 //     The destructor for the AliITSgeom class. If the arrays fNlad,
303 // fNdet, or fg have had memory allocated to them, there pointer values
304 // are non zero, then this memory space is freed and they are set
305 // to zero. In addition, fNlayers is set to zero. The destruction of
306 // TObjArray fShape is, by default, handled by the TObjArray destructor.
307 ////////////////////////////////////////////////////////////////////////
308   // Default destructor.
309   // if arrays exist delete them. Then set everything to zero.
310    if(fg!=0){
311       for(Int_t i=0;i<fNlayers;i++) delete[] fg[i];
312       delete[] fg;
313    } // end if fg!=0
314    if(fNlad!=0) delete[] fNlad;
315    if(fNdet!=0) delete[] fNdet;
316    fNlayers = 0;
317    fNlad    = 0;
318    fNdet    = 0;
319    fg       = 0;
320    return;
321 }
322
323 //_____________________________________________________________________
324 AliITSgeom::AliITSgeom(const char *filename){
325 ////////////////////////////////////////////////////////////////////////
326 //     The constructor for the AliITSgeom class. All of the data to fill
327 // this structure is read in from the file given my the input filename.
328 ////////////////////////////////////////////////////////////////////////
329    FILE     *pf;
330    Int_t    i;
331    ITS_geom *g;
332    Int_t    l,a,d;
333    Float_t  x,y,z,o,p,q,r,s,t;
334    Double_t oor,pr,qr,rr,sr,tr; // Radians
335    Double_t lr[9];
336    Double_t si; // sin(angle)
337    Double_t PI = TMath::Pi(), byPI = PI/180.;
338
339    pf = fopen(filename,"r");
340
341    fNlayers = 6; // set default number of ladders
342    fNlad    = new Int_t[fNlayers];
343    fNdet    = new Int_t[fNlayers];
344    // find the number of ladders and detectors in this geometry.
345    for(i=0;i<fNlayers;i++){fNlad[i]=fNdet[i]=0;} // zero out arrays
346    for(;;){ // for ever loop
347       i = fscanf(pf,"%d %d %d %f %f %f %f %f %f %f %f %f",
348                      &l,&a,&d,&x,&y,&z,&o,&p,&q,&r,&s,&t);
349       if(i==EOF) break;
350       if(l<1 || l>fNlayers) {
351          printf("error in file %s layer=%d min is 1 max is %d/n",
352                  filename,l,fNlayers);
353          continue;
354       }// end if l
355       if(fNlad[l-1]<a) fNlad[l-1] = a;
356       if(fNdet[l-1]<d) fNdet[l-1] = d;
357    } // end for ever loop
358    // counted the number of ladders and detectors now allocate space.
359    fg = new ITS_geom* [fNlayers];
360    for(i=0;i<fNlayers;i++){
361       fg[i] = 0;
362       l = fNlad[i]*fNdet[i];
363       fg[i] = new ITS_geom[l]; // allocate space for transforms
364    } // end for i
365
366    // Set up Shapes for a default configuration of 6 layers.
367    fShape = new TObjArray;
368    AddShape((TObject *) new AliITSgeomSPD());  // shape 0
369    AddShape((TObject *) new AliITSgeomSDD());  // shape 1
370    AddShape((TObject *) new AliITSgeomSPD());  // shape 2
371
372    // prepare to read in transforms
373    rewind(pf); // start over reading file
374    for(;;){ // for ever loop
375       i = fscanf(pf,"%d %d %d %f %f %f %f %f %f %f %f %f",
376                      &l,&a,&d,&x,&y,&z,&o,&p,&q,&r,&s,&t);
377       if(i==EOF) break;
378       if(l<1 || l>fNlayers) {
379          printf("error in file %s layer=%d min is 1 max is %d/n",
380                  filename,l,fNlayers);
381          continue;
382       }// end if l
383       l--; a--; d--; // shift layer, ladder, and detector counters to zero base
384       i = d + a*fNdet[l]; // position of this detector
385       g = &(fg[l][i]);
386
387       oor = byPI*o;
388       pr = byPI*p;
389       qr = byPI*q;
390       rr = byPI*r;
391       sr = byPI*s;
392       tr = byPI*t;
393
394       g->fx0   = x;
395       g->fy0   = y;
396       g->fz0   = z;
397 //
398       si    = sin(oor);if(o== 90.0) si = +1.0;
399                       if(o==270.0) si = -1.0;
400                       if(o==  0.0||o==180.) si = 0.0;
401       lr[0] = si * cos(pr);
402       lr[1] = si * sin(pr);
403       lr[2] = cos(oor);if(o== 90.0||o==270.) lr[2] = 0.0;
404                       if(o== 0.0)           lr[2] = +1.0;
405                       if(o==180.0)          lr[2] = -1.0;
406 //
407       si    =  sin(qr);if(q== 90.0) si = +1.0; 
408                        if(q==270.0) si = -1.0;
409                        if(q==  0.0||q==180.) si = 0.0;
410       lr[3] = si * cos(rr);
411       lr[4] = si * sin(rr);
412       lr[5] = cos(qr);if(q== 90.0||q==270.) lr[5] = 0.0;
413                       if(q==  0.0)          lr[5] = +1.0;
414                       if(q==180.0)          lr[5] = -1.0;
415 //
416       si    = sin(sr);if(s== 90.0) si = +1.0;
417                       if(s==270.0) si = -1.0;
418                       if(s==  0.0||s==180.) si = 0.0;
419       lr[6] = si * cos(tr);
420       lr[7] = si * sin(tr);
421       lr[8] = cos(sr);if(s== 90.0||s==270.0) lr[8] =  0.0;
422                       if(s==  0.0)           lr[8] = +1.0;
423                       if(s==180.0)           lr[8] = -1.0;
424       // Normalize these elements
425       for(a=0;a<3;a++){// reuse float Si and integers a and d.
426          si = 0.0;
427          for(d=0;d<3;d++) si += lr[3*a+d]*lr[3*a+d];
428          si = TMath::Sqrt(1./si);
429          for(d=0;d<3;d++) g->fr[3*a+d] = lr[3*a+d] = si*lr[3*a+d];
430       } // end for a
431       // get angles from matrix up to a phase of 180 degrees.
432       oor     = atan2(lr[7],lr[8]);if(oor<0.0) oor += 2.0*PI;
433       pr     = asin(lr[2]);       if(pr<0.0) pr += 2.0*PI;
434       qr     = atan2(lr[3],lr[0]);if(qr<0.0) qr += 2.0*PI;
435       g->frx = oor;
436       g->fry = pr;
437       g->frz = qr;
438       // l = layer-1 at this point.
439            if(l==0||l==1) g->fShapeIndex = 0; // SPD's
440       else if(l==2||l==3) g->fShapeIndex = 1; // SDD's
441       else if(l==4||l==5) g->fShapeIndex = 2; // SSD's
442    } // end for ever loop
443    fclose(pf);
444 }
445
446 //________________________________________________________________________
447 AliITSgeom::AliITSgeom(AliITSgeom &source){
448 ////////////////////////////////////////////////////////////////////////
449 //     The copy constructor for the AliITSgeom class. It calls the
450 // = operator function. See the = operator function for more details.
451 ////////////////////////////////////////////////////////////////////////
452
453     *this = source;  // Just use the = operator for now.
454
455     return;
456 }
457
458 //________________________________________________________________________
459 void AliITSgeom::operator=(AliITSgeom &source){
460 ////////////////////////////////////////////////////////////////////////
461 //     The = operator function for the AliITSgeom class. It makes an
462 // independent copy of the class in such a way that any changes made
463 // to the copied class will not affect the source class in any way.
464 // This is required for many ITS alignment studies where the copied
465 // class is then modified by introducing some misalignment.
466 ////////////////////////////////////////////////////////////////////////
467    Int_t i,j,k;
468
469    if(this == &source) return; // don't assign to ones self.
470
471    // if there is an old structure allocated delete it first.
472    if(fg != 0){
473       for(i=0;i<fNlayers;i++) delete[] fg[i];
474       delete[] fg;
475    } // end if fg != 0 
476    if(fNlad != 0) delete[] fNlad;
477    if(fNdet != 0) delete[] fNdet;
478
479    fNlayers = source.fNlayers;
480    fNlad = new Int_t[fNlayers];
481    for(i=0;i<fNlayers;i++) fNlad[i] = source.fNlad[i];
482    fNdet = new Int_t[fNlayers];
483    for(i=0;i<fNlayers;i++) fNdet[i] = source.fNdet[i];
484    fShape = new TObjArray(*(source.fShape));//This does not make a proper copy.
485    fg = new ITS_geom* [fNlayers];
486    for(i=0;i<fNlayers;i++){
487       fg[i] = new ITS_geom[fNlad[i]*fNdet[i]];
488       for(j=0;j<(fNlad[i]*fNdet[i]);j++){
489           fg[i][j].fShapeIndex = source.fg[i][j].fShapeIndex;
490           fg[i][j].fx0 = source.fg[i][j].fx0;
491           fg[i][j].fy0 = source.fg[i][j].fy0;
492           fg[i][j].fz0 = source.fg[i][j].fz0;
493           fg[i][j].frx = source.fg[i][j].frx;
494           fg[i][j].fry = source.fg[i][j].fry;
495           fg[i][j].frz = source.fg[i][j].frz;
496           for(k=0;k<9;k++) fg[i][j].fr[k] = source.fg[i][j].fr[k];
497       } // end for j
498    } // end for i
499    return;
500 }
501 //________________________________________________________________________
502 void AliITSgeom::GtoL(Int_t lay,Int_t lad,Int_t det,
503                        const Double_t *g,Double_t *l){
504 ////////////////////////////////////////////////////////////////////////
505 //     The function that does the global ALICE Cartesian coordinate
506 // to local active volume detector Cartesian coordinate transformation.
507 // The local detector coordinate system is determined by the layer, 
508 // ladder, and detector numbers. The global coordinates are entered by
509 // the three element Double_t array g and the local coordinate values
510 // are returned by the three element Double_t array l. The order of the 
511 // three elements are g[0]=x, g[1]=y, and g[2]=z, similarly for l.
512 ////////////////////////////////////////////////////////////////////////
513    Double_t x,y,z;
514    ITS_geom *gl;
515
516    lay--; lad--; det--;
517    gl = &(fg[lay][fNdet[lay]*lad+det]);
518
519    x    = g[0] - gl->fx0;
520    y    = g[1] - gl->fy0;
521    z    = g[2] - gl->fz0;
522    l[0] = gl->fr[0]*x + gl->fr[1]*y + gl->fr[2]*z;
523    l[1] = gl->fr[3]*x + gl->fr[4]*y + gl->fr[5]*z;
524    l[2] = gl->fr[6]*x + gl->fr[7]*y + gl->fr[8]*z;
525    return;
526 }
527 //________________________________________________________________________
528 void AliITSgeom::GtoL(const Int_t *id,const Double_t *g,Double_t *l){
529 ////////////////////////////////////////////////////////////////////////
530 //     The function that does the local active volume detector Cartesian
531 // coordinate to global ALICE Cartesian coordinate transformation.
532 // The local detector coordinate system is determined by the id[0]=layer, 
533 // id[1]=ladder, and id[2]=detector numbers. The local coordinates are
534 // entered by the three element Double_t array l and the global coordinate
535 // values are returned by the three element Double_t array g. The order of the 
536 // three elements are l[0]=x, l[1]=y, and l[2]=z, similarly for g.
537 ////////////////////////////////////////////////////////////////////////
538     GtoL(id[0],id[1],id[2],g,l);
539     return;
540 }
541 //________________________________________________________________________
542 void AliITSgeom::GtoL(const Int_t index,const Double_t *g,Double_t *l){
543 ////////////////////////////////////////////////////////////////////////
544 //     The function that does the local active volume detector Cartesian
545 // coordinate to global ALICE Cartesian coordinate transformation.
546 // The local detector coordinate system is determined by the detector
547 // index numbers (see GetModuleIndex and GetModuleID). The local 
548 // coordinates are entered by the three element Double_t array l and the 
549 // global coordinate values are returned by the three element Double_t array g.
550 // The order of the three elements are l[0]=x, l[1]=y, and l[2]=z, similarly 
551 // for g.
552 ////////////////////////////////////////////////////////////////////////
553     Int_t    lay,lad,det;
554
555     this->GetModuleId(index,lay,lad,det);
556
557     GtoL(lay,lad,det,g,l);
558     return;
559 }
560 //________________________________________________________________________
561 void AliITSgeom::GtoL(Int_t lay,Int_t lad,Int_t det,
562                        const Float_t *g,Float_t *l){
563 ////////////////////////////////////////////////////////////////////////
564 //     The function that does the global ALICE Cartesian coordinate
565 // to local active volume detector Cartesian coordinate transformation.
566 // The local detector coordinate system is determined by the layer, 
567 // ladder, and detector numbers. The global coordinates are entered by
568 // the three element Float_t array g and the local coordinate values
569 // are returned by the three element Float_t array l. The order of the 
570 // three elements are g[0]=x, g[1]=y, and g[2]=z, similarly for l.
571 ////////////////////////////////////////////////////////////////////////
572     Int_t    i;
573     Double_t gd[3],ld[3];
574
575     for(i=0;i<3;i++) gd[i] = (Double_t) g[i];
576     GtoL(lay,lad,det,(Double_t *)gd,(Double_t *)ld);
577     for(i=0;i<3;i++) l[i] = (Float_t) ld[i];
578     return;
579 }
580 //________________________________________________________________________
581 void AliITSgeom::GtoL(const Int_t *id,const Float_t *g,Float_t *l){
582 ////////////////////////////////////////////////////////////////////////
583 //     The function that does the local active volume detector Cartesian
584 // coordinate to global ALICE Cartesian coordinate transformation.
585 // The local detector coordinate system is determined by the Int_t array id,
586 // id[0]=layer, id[1]=ladder, and id[2]=detector numbers. The local 
587 // coordinates are entered by the three element Float_t array l and the
588 // global coordinate values are returned by the three element Float_t array g.
589 // The order of the three elements are l[0]=x, l[1]=y, and l[2]=z, similarly
590 // for g. The order of the three elements are g[0]=x, g[1]=y, and g[2]=z,
591 // similarly for l.
592 ////////////////////////////////////////////////////////////////////////
593     Int_t    i;
594     Double_t gd[3],ld[3];
595
596     for(i=0;i<3;i++) gd[i] = (Double_t) g[i];
597     GtoL(id[0],id[1],id[2],(Double_t *)gd,(Double_t *)ld);
598     for(i=0;i<3;i++) l[i] = (Float_t) ld[i];
599     return;
600 }
601 //________________________________________________________________________
602 void AliITSgeom::GtoL(const Int_t index,const Float_t *g,Float_t *l){
603 ////////////////////////////////////////////////////////////////////////
604 //     The function that does the local active volume detector Cartesian
605 // coordinate to global ALICE Cartesian coordinate transformation.
606 // The local detector coordinate system is determined by the detector
607 // index numbers (see GetModuleIndex and GetModuleID). The local 
608 // coordinates are entered by the three element Float_t array l and the 
609 // global coordinate values are returned by the three element Float_t array g.
610 // The order of the three elements are l[0]=x, l[1]=y, and l[2]=z, similarly 
611 // for g.
612 ////////////////////////////////////////////////////////////////////////
613     Int_t    lay,lad,det;
614     Int_t    i;
615     Double_t gd[3],ld[3];
616
617     this->GetModuleId(index,lay,lad,det);
618
619     for(i=0;i<3;i++) gd[i] = (Double_t) g[i];
620     GtoL(lay,lad,det,(Double_t *)gd,(Double_t *)ld);
621     for(i=0;i<3;i++) l[i] = (Float_t) ld[i];
622     return;
623 }
624 //________________________________________________________________________
625 void AliITSgeom::LtoG(Int_t lay,Int_t lad,Int_t det,
626                       const Double_t *l,Double_t *g){
627 ////////////////////////////////////////////////////////////////////////
628 //     The function that does the local active volume detector Cartesian
629 // coordinate to global ALICE Cartesian coordinate transformation.
630 // The local detector coordinate system is determined by the layer, 
631 // ladder, and detector numbers. The local coordinates are entered by
632 // the three element Float_t array l and the global coordinate values
633 // are returned by the three element Float_t array g. The order of the 
634 // three elements are l[0]=x, l[1]=y, and l[2]=z, similarly for g.
635 ////////////////////////////////////////////////////////////////////////
636    Double_t x,y,z;
637    ITS_geom *gl;
638
639    lay--; lad--; det--;
640    gl   = &(fg[lay][fNdet[lay]*lad+det]);
641
642    x    = gl->fr[0]*l[0] + gl->fr[3]*l[1] + gl->fr[6]*l[2];
643    y    = gl->fr[1]*l[0] + gl->fr[4]*l[1] + gl->fr[7]*l[2];
644    z    = gl->fr[2]*l[0] + gl->fr[5]*l[1] + gl->fr[8]*l[2];
645    g[0] = x + gl->fx0;
646    g[1] = y + gl->fy0;
647    g[2] = z + gl->fz0;
648    return;
649 }
650 //________________________________________________________________________
651 void AliITSgeom::LtoG(const Int_t *id,const Double_t *l,Double_t *g){
652 ////////////////////////////////////////////////////////////////////////
653 //     The function that does the local active volume detector Cartesian
654 // coordinate to global ALICE Cartesian coordinate transformation.
655 // The local detector coordinate system is determined by the three
656 // element array Id containing as it's three elements Id[0]=layer, 
657 // Id[1]=ladder, and Id[2]=detector numbers. The local coordinates
658 // are entered by the three element Double_t array l and the global
659 // coordinate values are returned by the three element Double_t array g.
660 // The order of the three elements are l[0]=x, l[1]=y, and l[2]=z,
661 // similarly for g.
662 ////////////////////////////////////////////////////////////////////////
663     LtoG(id[0],id[1],id[2],l,g);
664     return;
665 }
666 //________________________________________________________________________
667 void AliITSgeom::LtoG(const Int_t index,const Double_t *l,Double_t *g){
668 ////////////////////////////////////////////////////////////////////////
669 //     The function that does the local active volume detector Cartesian
670 // coordinate to global ALICE Cartesian coordinate transformation.
671 // The local detector coordinate system is determined by the detector  
672 // index number (see GetModuleIndex and GetModuleId). The local coordinates
673 // are entered by the three element Double_t array l and the global
674 // coordinate values are returned by the three element Double_t array g.
675 // The order of the three elements are l[0]=x, l[1]=y, and l[2]=z,
676 // similarly for g.
677 ////////////////////////////////////////////////////////////////////////
678     Int_t    lay,lad,det;
679
680     this->GetModuleId(index,lay,lad,det);
681
682     LtoG(lay,lad,det,l,g);
683     return;
684 }
685 //________________________________________________________________________
686 void AliITSgeom::LtoG(Int_t lay,Int_t lad,Int_t det,
687                       const Float_t *l,Float_t *g){
688 ////////////////////////////////////////////////////////////////////////
689 //     The function that does the local active volume detector Cartesian
690 // coordinate to global ALICE Cartesian coordinate transformation.
691 // The local detector coordinate system is determined by the layer, 
692 // ladder, and detector numbers. The local coordinates are entered by
693 // the three element Float_t array l and the global coordinate values
694 // are returned by the three element Float_t array g. The order of the 
695 // three elements are l[0]=x, l[1]=y, and l[2]=z, similarly for g.
696 ////////////////////////////////////////////////////////////////////////
697     Int_t    i;
698     Double_t gd[3],ld[3];
699
700     for(i=0;i<3;i++) ld[i] = (Double_t) l[i];
701     LtoG(lay,lad,det,(Double_t *)ld,(Double_t *)gd);
702     for(i=0;i<3;i++) g[i] = (Float_t) gd[i];
703     return;
704 }
705 //________________________________________________________________________
706 void AliITSgeom::LtoG(const Int_t *id,const Float_t *l,Float_t *g){
707 ////////////////////////////////////////////////////////////////////////
708 //     The function that does the local active volume detector Cartesian
709 // coordinate to global ALICE Cartesian coordinate transformation.
710 // The local detector coordinate system is determined by the three
711 // element array Id containing as it's three elements Id[0]=layer, 
712 // Id[1]=ladder, and Id[2]=detector numbers. The local coordinates
713 // are entered by the three element Float_t array l and the global
714 // coordinate values are returned by the three element Float_t array g.
715 // The order of the three elements are l[0]=x, l[1]=y, and l[2]=z,
716 // similarly for g.
717 ////////////////////////////////////////////////////////////////////////
718     Int_t    i;
719     Double_t gd[3],ld[3];
720
721     for(i=0;i<3;i++) ld[i] = (Double_t) l[i];
722     LtoG(id[0],id[1],id[2],(Double_t *)ld,(Double_t *)gd);
723     for(i=0;i<3;i++) g[i] = (Float_t) gd[i];
724     return;
725 }
726 //________________________________________________________________________
727 void AliITSgeom::LtoG(const Int_t index,const Float_t *l,Float_t *g){
728 ////////////////////////////////////////////////////////////////////////
729 //     The function that does the local active volume detector Cartesian
730 // coordinate to global ALICE Cartesian coordinate transformation.
731 // The local detector coordinate system is determined by the detector  
732 // index number (see GetModuleIndex and GetModuleId). The local coordinates
733 // are entered by the three element Float_t array l and the global
734 // coordinate values are returned by the three element Float_t array g.
735 // The order of the three elements are l[0]=x, l[1]=y, and l[2]=z,
736 // similarly for g.
737 ////////////////////////////////////////////////////////////////////////
738     Int_t    i,lay,lad,det;
739     Double_t gd[3],ld[3];
740
741     this->GetModuleId(index,lay,lad,det);
742
743     for(i=0;i<3;i++) ld[i] = (Double_t) l[i];
744     LtoG(lay,lad,det,(Double_t *)ld,(Double_t *)gd);
745     for(i=0;i<3;i++) g[i] = (Float_t) gd[i];
746     return;
747 }
748 //______________________________________________________________________
749 void AliITSgeom::LtoL(const Int_t *id1,const Int_t *id2,
750                       Double_t *l1,Double_t *l2){
751 ////////////////////////////////////////////////////////////////////////
752 //     The function that does the local active volume detector Cartesian
753 // coordinate to a different local active volume detector Cartesian coordinate
754 // transformation. The original local detector coordinate system is determined
755 // by the detector array id1, id1[0]=layer, id1[1]=ladder, and id1[2]=detector
756 // and the new coordinate system is determined by the detector array id2,
757 // id2[0]=layer, id2[1]=ladder, and id2[2]=detector. The original local
758 // coordinates are entered by the three element Double_t array l1 and the
759 // other new local coordinate values are returned by the three element
760 // Double_t array l2. The order of the three elements are l1[0]=x, l1[1]=y,
761 // and l1[2]=z, similarly for l2.
762 ////////////////////////////////////////////////////////////////////////
763     Double_t g[3];
764
765     LtoG(id1,l1,g);
766     GtoL(id2,g,l2);
767     return;
768 }
769 //______________________________________________________________________
770 void AliITSgeom::LtoL(const Int_t index1,const Int_t index2,
771                       Double_t *l1,Double_t *l2){
772 ////////////////////////////////////////////////////////////////////////
773 //     The function that does the local active volume detector Cartesian
774 // coordinate to a different local active volume detector Cartesian coordinate
775 // transformation. The original local detector coordinate system is determined
776 // by the detector index number index1, and the new coordinate system is
777 // determined by the detector index number index2, (see GetModuleIndex and
778 // GetModuleId). The original local coordinates are entered by the three
779 // element Double_t array l1 and the other new local coordinate values are
780 // returned by the three element Double_t array l2. The order of the three
781 // elements are l1[0]=x, l1[1]=y, and l1[2]=z, similarly for l2.
782 ////////////////////////////////////////////////////////////////////////
783     Double_t g[3];
784
785     LtoG(index1,l1,g);
786     GtoL(index2,g,l2);
787     return;
788 }
789 //________________________________________________________________________
790 void AliITSgeom::GtoLMomentum(Int_t lay,Int_t lad,Int_t det,
791                               const Double_t *g,Double_t *l){
792 ////////////////////////////////////////////////////////////////////////
793 //     The function that does the global ALICE Cartesian momentum
794 // to local active volume detector Cartesian momentum transformation.
795 // The local detector coordinate system is determined by the layer, 
796 // ladder, and detector numbers. The global momentums are entered by
797 // the three element Double_t array g and the local momentums values
798 // are returned by the three element Double_t array l. The order of the 
799 // three elements are g[0]=x, g[1]=y, and g[2]=z, similarly for l.
800 ////////////////////////////////////////////////////////////////////////
801    Double_t px,py,pz;
802    ITS_geom *gl;
803
804    lay--; lad--; det--;
805    gl = &(fg[lay][fNdet[lay]*lad+det]);
806
807    px   = g[0];
808    py   = g[1];
809    pz   = g[2];
810    l[0] = gl->fr[0]*px + gl->fr[1]*py + gl->fr[2]*pz;
811    l[1] = gl->fr[3]*px + gl->fr[4]*py + gl->fr[5]*pz;
812    l[2] = gl->fr[6]*px + gl->fr[7]*py + gl->fr[8]*pz;
813    return;
814 }
815 //________________________________________________________________________
816 void AliITSgeom::GtoLMomentum(Int_t lay,Int_t lad,Int_t det,
817                               const Float_t *g,Float_t *l){
818 ////////////////////////////////////////////////////////////////////////
819 //     The function that does the global ALICE Cartesian momentum
820 // to local active volume detector Cartesian momentum transformation.
821 // The local detector coordinate system is determined by the layer, 
822 // ladder, and detector numbers. The global momentums are entered by
823 // the three element Float_t array g and the local momentums values
824 // are returned by the three element Float_t array l. The order of the 
825 // three elements are g[0]=x, g[1]=y, and g[2]=z, similarly for l.
826 ////////////////////////////////////////////////////////////////////////
827     Int_t i;
828     Double_t gd[3],ld[3];
829
830     for(i=0;i<3;i++) gd[i] = (Double_t) g[i];
831     GtoLMomentum(lay,lad,det,(Double_t *)gd,(Double_t *)ld);
832     for(i=0;i<3;i++) l[i] = (Float_t) ld[i];
833     return;
834 }
835 //________________________________________________________________________
836 void AliITSgeom::LtoGMomentum(Int_t lay,Int_t lad,Int_t det,
837                               const Double_t *l,Double_t *g){
838 ////////////////////////////////////////////////////////////////////////
839 //     The function that does the local active volume detector Cartesian
840 // momentum to global ALICE Cartesian momentum transformation.
841 // The local detector momentum system is determined by the layer, 
842 // ladder, and detector numbers. The local momentums are entered by
843 // the three element Double_t array l and the global momentum values
844 // are returned by the three element Double_t array g. The order of the 
845 // three elements are l[0]=x, l[1]=y, and l[2]=z, similarly for g.
846 ////////////////////////////////////////////////////////////////////////
847    Double_t px,py,pz;
848    ITS_geom *gl;
849
850    lay--; lad--; det--;
851    gl   = &(fg[lay][fNdet[lay]*lad+det]);
852
853    px   = gl->fr[0]*l[0] + gl->fr[3]*l[1] + gl->fr[6]*l[2];
854    py   = gl->fr[1]*l[0] + gl->fr[4]*l[1] + gl->fr[7]*l[2];
855    pz   = gl->fr[2]*l[0] + gl->fr[5]*l[1] + gl->fr[8]*l[2];
856    g[0] = px;
857    g[1] = py;
858    g[2] = pz;
859    return;
860 }
861 //________________________________________________________________________
862 void AliITSgeom::LtoGMomentum(Int_t lay,Int_t lad,Int_t det,
863                               const Float_t *l,Float_t *g){
864 ////////////////////////////////////////////////////////////////////////
865 //     The function that does the local active volume detector Cartesian
866 // momentum to global ALICE Cartesian momentum transformation.
867 // The local detector momentum system is determined by the layer, 
868 // ladder, and detector numbers. The local momentums are entered by
869 // the three element Float_t array l and the global momentum values
870 // are returned by the three element Float_t array g. The order of the 
871 // three elements are l[0]=x, l[1]=y, and l[2]=z, similarly for g.
872 ////////////////////////////////////////////////////////////////////////
873     Int_t i;
874     Double_t gd[3],ld[3];
875
876     for(i=0;i<3;i++) ld[i] = (Double_t) l[i];
877     LtoGMomentum(lay,lad,det,(Double_t *)ld,(Double_t *)gd);
878     for(i=0;i<3;i++) g[i] = (Float_t) gd[i];
879     return;
880 }
881 //______________________________________________________________________
882 void AliITSgeom::LtoLMomentum(const Int_t *id1,const Int_t *id2,
883                               const Double_t *l1,Double_t *l2){
884 ////////////////////////////////////////////////////////////////////////
885 //     The function that does the local active volume detector Cartesian
886 // momentum to a different local active volume detector Cartesian momentum
887 // transformation. The original local detector momentum system is determined
888 // by the Int_t array id1 (id1[0]=lay, id1[1]=lad, id1[2]=det). The new local
889 // coordinate system id determined by the Int_t array id2. The local
890 // momentums are entered by the three element Double_t array l1 and the other
891 // local momentum values are returned by the three element Double_t array l2.
892 // The order of the three elements are l1[0]=x, l1[1]=y, and l1[2]=z,
893 // similarly for l2.
894 ////////////////////////////////////////////////////////////////////////
895     Double_t g[3];
896
897     LtoGMomentum(id1[0],id1[1],id1[2],l1,g);
898     GtoLMomentum(id2[0],id2[1],id2[2],g,l2);
899     return;
900 }
901 //______________________________________________________________________
902 void AliITSgeom::GtoLErrorMatrix(const Int_t index,Double_t **g,Double_t **l){
903 ////////////////////////////////////////////////////////////////////////
904 //      This converts an error matrix, expressed in global coordinates
905 // into an error matrix expressed in local coordinates. Since the 
906 // translations do not change the error matrix they are not included.
907 // Definition: if GtoL is l[i] = T[i][j]*g[j], then from the definition
908 // of the transformation matrix above T[i][j] = fr[3*i+j]. Then for a 
909 // matrix l[i][l] = T[i][j]*g[j][k]*T[l][k] (sum over repeated indexes). 
910 // Where T[l][k] is the transpose of T[k][l].
911 ////////////////////////////////////////////////////////////////////////
912     Double_t R[3][3],Rt[3][3];
913     Int_t    lay,lad,det,i,j,k,n;
914     ITS_geom *gl;
915
916     GetModuleId(index,lay,lad,det);
917     lay--;lad--;det--;
918     gl = &(fg[lay][fNdet[lay]*lad+det]);
919
920     for(i=0;i<3;i++)for(j=0;j<3;j++){
921         R[i][j] = Rt[j][i] = gl->fr[3*i+j];
922     } // end for i,j
923
924     for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)for(n=0;n<3;n++){
925         l[i][n] = R[i][j]*g[j][k]*Rt[k][n];
926     } // end for i,j,k,l
927     return;
928 }
929 //______________________________________________________________________
930 void AliITSgeom::LtoGErrorMatrix(const Int_t index,Double_t **l,Double_t **g){
931 ////////////////////////////////////////////////////////////////////////
932 //      This converts an error matrix, expressed in local coordinates
933 // into an error matrix expressed in global coordinates. Since the 
934 // translations do not change the error matrix they are not included.
935 // Definition: if GtoL is l[i] = T[i][j]*g[j], then from the definition
936 // of the transformation matrix above T[i][j] = fr[3*i+j]. Then for a 
937 // matrix g[i][l] = T[j][i]*l[j][k]*T[k][l] (sum over repeated indexes). 
938 // Where T[j][i] is the transpose of T[i][j].
939 ////////////////////////////////////////////////////////////////////////
940     Double_t R[3][3],Rt[3][3];
941     Int_t    lay,lad,det,i,j,k,n;
942     ITS_geom *gl;
943
944     GetModuleId(index,lay,lad,det);
945     lay--;lad--;det--;
946     gl = &(fg[lay][fNdet[lay]*lad+det]);
947
948     for(i=0;i<3;i++)for(j=0;j<3;j++){
949         R[i][j] = Rt[j][i] = gl->fr[3*i+j];
950     } // end for i,j
951
952     for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)for(n=0;n<3;n++){
953         g[i][n] = Rt[i][j]*l[j][k]*R[k][n];
954     } // end for i,j,k,l
955     return;
956 }
957 //______________________________________________________________________
958 void AliITSgeom::LtoLErrorMatrix(const Int_t index1,const Int_t index2,
959                                  Double_t **l1,Double_t **l2){
960 ////////////////////////////////////////////////////////////////////////
961 //      This converts an error matrix, expressed in one local coordinates
962 // into an error matrix expressed in different local coordinates. Since  
963 // the translations do not change the error matrix they are not included.
964 // This is done by going through the global coordinate system for 
965 // simplicity and constancy.
966 ////////////////////////////////////////////////////////////////////////
967     Double_t g[3][3];
968
969     this->LtoGErrorMatrix(index1,l1,(Double_t **)g);
970     this->GtoLErrorMatrix(index2,(Double_t **)g,l2);
971     return;
972 }
973 //______________________________________________________________________
974 Int_t AliITSgeom::GetModuleIndex(Int_t lay,Int_t lad,Int_t det){
975 ////////////////////////////////////////////////////////////////////////
976 //      This routine computes the module index number from the layer,
977 // ladder, and detector numbers. The number of ladders and detectors
978 // per layer is determined when this geometry package is constructed,
979 // see AliITSgeom(const char *filename) for specifics.
980 ////////////////////////////////////////////////////////////////////////
981     Int_t i,j,k;
982
983     i = fNdet[lay-1] * (lad-1) + det - 1;
984     j = 0;
985     for(k=0;k<lay-1;k++) j += fNdet[k]*fNlad[k];
986     return (i+j);
987 }
988 //___________________________________________________________________________
989 void AliITSgeom::GetModuleId(Int_t index,Int_t &lay,Int_t &lad,Int_t &det){
990 ////////////////////////////////////////////////////////////////////////
991 //      This routine computes the layer, ladder and detector number 
992 // given the module index number. The number of ladders and detectors
993 // per layer is determined when this geometry package is constructed,
994 // see AliITSgeom(const char *filename) for specifics.
995 ////////////////////////////////////////////////////////////////////////
996     Int_t i,j,k;
997
998     j = 0;
999     for(k=0;k<fNlayers;k++){
1000         j += fNdet[k]*fNlad[k];
1001         if(j>index)break;
1002     } // end for k
1003     lay = k+1;
1004     i = index -j + fNdet[k]*fNlad[k];
1005     j = 0;
1006     for(k=0;k<fNlad[lay-1];k++){
1007         j += fNdet[lay-1];
1008         if(j>i)break;
1009     } // end for k
1010     lad = k+1;
1011     det = 1+i-fNdet[lay-1]*k;
1012     return;
1013 }
1014 //___________________________________________________________________________
1015 void AliITSgeom::GetRotMatrix(Int_t lay,Int_t lad,Int_t det,Double_t *mat){
1016 ////////////////////////////////////////////////////////////////////////
1017 //     Returns, in the Double_t array pointed to by mat, the full rotation
1018 // matrix for the give detector defined by layer, ladder, and detector.
1019 // It returns all nine elements of fr in the ITS_geom structure. See the
1020 // description of the ITS_geom structure for further details of this
1021 // rotation matrix.
1022 ////////////////////////////////////////////////////////////////////////
1023    Int_t    i;
1024    ITS_geom *g;
1025
1026    lay--; lad--; det--; // shift to base 0
1027    g = &(fg[lay][fNdet[lay]*lad+det]);
1028    for(i=0;i<9;i++) mat[i] = g->fr[i];
1029    return;
1030 }
1031 //___________________________________________________________________________
1032 void AliITSgeom::GetRotMatrix(Int_t index,Double_t *mat){
1033 ////////////////////////////////////////////////////////////////////////
1034 //     Returns, in the Double_t array pointed to by mat, the full rotation
1035 // matrix for the give detector defined by the module index number.
1036 // It returns all nine elements of fr in the ITS_geom structure. See the
1037 // description of the ITS_geom structure for further details of this
1038 // rotation matrix.
1039 ////////////////////////////////////////////////////////////////////////
1040    Int_t    lay,lad,det;
1041
1042    this->GetModuleId(index,lay,lad,det);
1043    GetRotMatrix(lay,lad,det,mat);
1044    return;
1045 }
1046 //___________________________________________________________________________
1047 void AliITSgeom::GetRotMatrix(Int_t lay,Int_t lad,Int_t det,Float_t *mat){
1048 ////////////////////////////////////////////////////////////////////////
1049 //     Returns, in the Float_t array pointed to by mat, the full rotation
1050 // matrix for the give detector defined by layer, ladder, and detector.
1051 // It returns all nine elements of fr in the ITS_geom structure. See the
1052 // description of the ITS_geom structure for further details of this
1053 // rotation matrix.
1054 ////////////////////////////////////////////////////////////////////////
1055    Int_t    i;
1056    Double_t matd[9];
1057
1058    GetRotMatrix(lay,lad,det,(Double_t *)matd);
1059    for(i=0;i<9;i++) mat[i] = (Float_t) matd[i];
1060    return;
1061 }
1062
1063 //___________________________________________________________________________
1064 void AliITSgeom::GetRotMatrix(Int_t index,Float_t *mat){
1065 ////////////////////////////////////////////////////////////////////////
1066 //     Returns, in the Float_t array pointed to by mat, the full rotation
1067 // matrix for the give detector defined by module index number.
1068 // It returns all nine elements of fr in the ITS_geom structure. See the
1069 // description of the ITS_geom structure for further details of this
1070 // rotation matrix.
1071 ////////////////////////////////////////////////////////////////////////
1072    Int_t    i,lay,lad,det;
1073    Double_t matd[9];
1074
1075    this->GetModuleId(index,lay,lad,det);
1076    GetRotMatrix(lay,lad,det,(Double_t *)matd);
1077    for(i=0;i<9;i++) mat[i] = (Float_t) matd[i];
1078    return;
1079 }
1080 //___________________________________________________________________________
1081 void AliITSgeom::PrintComparison(FILE *fp,AliITSgeom *other){
1082 ////////////////////////////////////////////////////////////////////////
1083 //     This function was primarily created for diagnostic reasons. It
1084 // print to a file pointed to by the file pointer fp the difference
1085 // between two AliITSgeom classes. The format of the file is basicly,
1086 // define d? to be the difference between the same element of the two
1087 // classes. For example dfrx = this->fg[i][j].frx - other->fg[i][j].frx.
1088 // if(at least one of dfx0, dfy0, dfz0,dfrx,dfry,dfrz are non zero) then print
1089 // layer ladder detector dfx0 dfy0 dfz0 dfrx dfry dfrz
1090 // if(at least one of the 9 elements of dfr[] are non zero) then print
1091 // layer ladder detector dfr[0] dfr[1] dfr[2]
1092 //                       dfr[3] dfr[4] dfr[5]
1093 //                       dfr[6] dfr[7] dfr[8]
1094 // Only non zero values are printed to save space. The differences are
1095 // typical written to a file because there are usually a lot of numbers
1096 // printed out and it is usually easier to read them in some nice editor
1097 // rather than zooming quickly past you on a screen. fprintf is used to
1098 // do the printing. The fShapeIndex difference is not printed at this time.
1099 ////////////////////////////////////////////////////////////////////////
1100    Int_t    i,j,k,l;
1101    Double_t xt,yt,zt,xo,yo,zo;
1102    Double_t rxt,ryt,rzt,rxo,ryo,rzo;  // phi in radians
1103    ITS_geom *gt,*go;
1104    Bool_t   t;
1105
1106    for(i=0;i<this->fNlayers;i++){
1107       for(j=0;j<this->fNlad[i];j++) for(k=0;k<this->fNdet[i];k++){
1108          l   = this->fNdet[i]*j+k; // resolved index
1109          gt  = &(this->fg[i][l]);
1110          go  = &(other->fg[i][l]);
1111          xt  = gt->fx0; yt  = gt->fy0; zt  = gt->fz0;
1112          xo  = go->fx0; yo  = go->fy0; zo  = go->fz0;
1113          rxt = gt->frx; ryt = gt->fry; rzt = gt->frz;
1114          rxo = go->frx; ryo = go->fry; rzo = go->frz;
1115          if(!(xt==xo&&yt==yo&&zt==zo&&rxt==rxo&&ryt==ryo&&rzt==rzo))
1116          fprintf(fp,"%1.1d %2.2d %2.2d dTrans=%f %f %f drot=%f %f %f\n",
1117                  i+1,j+1,k+1,xt-xo,yt-yo,zt-zo,rxt-rxo,ryt-ryo,rzt-rzo);
1118          t = kFALSE;
1119          for(i=0;i<9;i++) t = gt->fr[i] != go->fr[i];
1120          if(t){
1121              fprintf(fp,"%1.1d %2.2d %2.2d dfr= %e %e %e\n",i+1,j+1,k+1,
1122                  gt->fr[0]-go->fr[0],gt->fr[1]-go->fr[1],gt->fr[2]-go->fr[2]);
1123              fprintf(fp,"        dfr= %e %e %e\n",
1124                  gt->fr[3]-go->fr[3],gt->fr[4]-go->fr[4],gt->fr[5]-go->fr[5]);
1125              fprintf(fp,"        dfr= %e %e %e\n",
1126                  gt->fr[6]-go->fr[6],gt->fr[7]-go->fr[7],gt->fr[8]-go->fr[8]);
1127          }
1128       } // end for j,k
1129    } // end for i
1130    return;
1131 }
1132
1133 //___________________________________________________________________________
1134 void AliITSgeom::PrintData(FILE *fp,Int_t lay,Int_t lad,Int_t det){
1135 ////////////////////////////////////////////////////////////////////////
1136 //     This function prints out the coordinate transformations for
1137 // the particular detector defined by layer, ladder, and detector
1138 // to the file pointed to by the File pointer fp. fprintf statements
1139 // are used to print out the numbers. The format is
1140 // layer ladder detector Trans= fx0 fy0 fz0 rot= frx fry frz Shape=fShapeIndex
1141 //                         dfr= fr[0] fr[1] fr[2]
1142 //                         dfr= fr[3] fr[4] fr[5]
1143 //                         dfr= fr[6] fr[7] fr[8]
1144 // By indicating which detector, some control over the information 
1145 // is given to the user. The output it written to the file pointed
1146 // to by the file pointer fp. This can be set to stdout if you want.
1147 ////////////////////////////////////////////////////////////////////////
1148    Int_t    i,j,k,l;
1149    ITS_geom *gt;
1150
1151    i  = lay-1;
1152    j  = lad-1;
1153    k  = det-1;
1154    l  = this->fNdet[i]*j+k; // resolved index
1155    gt = &(this->fg[i][l]);
1156    fprintf(fp,"%1.1d %2.2d %2.2d Trans=%f %f %f rot=%f %f %f Shape=%d\n",
1157            i+1,j+1,k+1,gt->fx0,gt->fy0,gt->fz0,gt->frx,gt->fry,gt->frz,
1158            gt->fShapeIndex);
1159    fprintf(fp,"        dfr= %e %e %e\n",gt->fr[0],gt->fr[1],gt->fr[2]);
1160    fprintf(fp,"        dfr= %e %e %e\n",gt->fr[3],gt->fr[4],gt->fr[5]);
1161    fprintf(fp,"        dfr= %e %e %e\n",gt->fr[6],gt->fr[7],gt->fr[8]);
1162    return;
1163 }
1164 //___________________________________________________________________________
1165 ofstream & AliITSgeom::PrintGeom(ofstream &R__b){
1166 ////////////////////////////////////////////////////////////////////////
1167 //     The default Streamer function "written by ROOT" doesn't write out
1168 // the arrays referenced by pointers. Therefore, a specific Streamer function
1169 // has to be written. This function should not be modified but instead added
1170 // on to so that older versions can still be read. The proper handling of
1171 // the version dependent streamer function hasn't been written do to the lack
1172 // of finding an example at the time of writing.
1173 ////////////////////////////////////////////////////////////////////////
1174    // Stream an object of class AliITSgeom.
1175     Int_t i,j,k;
1176
1177     R__b.setf(ios::scientific);
1178     R__b << fNlayers << " ";
1179     for(i=0;i<fNlayers;i++) R__b << fNlad[i] << " ";
1180     for(i=0;i<fNlayers;i++) R__b << fNdet[i] << "\n";
1181     for(i=0;i<fNlayers;i++) for(j=0;j<fNlad[i]*fNdet[i];j++){
1182         R__b <<setprecision(16) << fg[i][j].fShapeIndex << " ";
1183         R__b <<setprecision(16) << fg[i][j].fx0 << " ";
1184         R__b <<setprecision(16) << fg[i][j].fy0 << " ";
1185         R__b <<setprecision(16) << fg[i][j].fz0 << " ";
1186         R__b <<setprecision(16) << fg[i][j].frx << " ";
1187         R__b <<setprecision(16) << fg[i][j].fry << " ";
1188         R__b <<setprecision(16) << fg[i][j].frz << "\n";
1189         for(k=0;k<9;k++) R__b <<setprecision(16) << fg[i][j].fr[k] << " ";
1190         R__b << "\n";
1191       } // end for i,j
1192 //      R__b << fShape;
1193       return R__b;
1194 }
1195 //___________________________________________________________________________
1196 ifstream & AliITSgeom::ReadGeom(ifstream &R__b){
1197 ////////////////////////////////////////////////////////////////////////
1198 //     The default Streamer function "written by ROOT" doesn't write out
1199 // the arrays referenced by pointers. Therefore, a specific Streamer function
1200 // has to be written. This function should not be modified but instead added
1201 // on to so that older versions can still be read. The proper handling of
1202 // the version dependent streamer function hasn't been written do to the lack
1203 // of finding an example at the time of writing.
1204 ////////////////////////////////////////////////////////////////////////
1205    // Stream an object of class AliITSgeom.
1206     Int_t i,j,k;
1207
1208       R__b >> fNlayers;
1209       if(fNlad!=0) delete[] fNlad;
1210       if(fNdet!=0) delete[] fNdet;
1211       fNlad = new Int_t[fNlayers];
1212       fNdet = new Int_t[fNlayers];
1213       for(i=0;i<fNlayers;i++) R__b >> fNlad[i];
1214       for(i=0;i<fNlayers;i++) R__b >> fNdet[i];
1215       if(fg!=0){
1216           for(i=0;i<fNlayers;i++) delete[] fg[i];
1217           delete[] fg;
1218       } // end if fg!=0
1219       fg = new ITS_geom*[fNlayers];
1220       for(i=0;i<fNlayers;i++){
1221           fg[i] = new ITS_geom[fNlad[i]*fNdet[i]];
1222           for(j=0;j<fNlad[i]*fNdet[i];j++){
1223               R__b >> fg[i][j].fShapeIndex;
1224               R__b >> fg[i][j].fx0;
1225               R__b >> fg[i][j].fy0;
1226               R__b >> fg[i][j].fz0;
1227               R__b >> fg[i][j].frx;
1228               R__b >> fg[i][j].fry;
1229               R__b >> fg[i][j].frz;
1230               for(k=0;k<9;k++) R__b >> fg[i][j].fr[k];
1231           } // end for j
1232       } // end for i
1233 //      R__b >> fShape;
1234       return R__b;
1235 }
1236 //___________________________________________________________________________
1237 void AliITSgeom::Streamer(TBuffer &R__b){
1238 ////////////////////////////////////////////////////////////////////////
1239 //     The default Streamer function "written by ROOT" doesn't write out
1240 // the arrays referenced by pointers. Therefore, a specific Streamer function
1241 // has to be written. This function should not be modified but instead added
1242 // on to so that older versions can still be read. The proper handling of
1243 // the version dependent streamer function hasn't been written do to the lack
1244 // of finding an example at the time of writing.
1245 ////////////////////////////////////////////////////////////////////////
1246    // Stream an object of class AliITSgeom.
1247     Int_t i,j,k;
1248
1249    if (R__b.IsReading()) {
1250       Version_t R__v = R__b.ReadVersion(); if (R__v) { }
1251       TObject::Streamer(R__b);
1252       R__b >> fNlayers;
1253       if(fNlad!=0) delete[] fNlad;
1254       if(fNdet!=0) delete[] fNdet;
1255       fNlad = new Int_t[fNlayers];
1256       fNdet = new Int_t[fNlayers];
1257       for(i=0;i<fNlayers;i++) R__b >> fNlad[i];
1258       for(i=0;i<fNlayers;i++) R__b >> fNdet[i];
1259       if(fg!=0){
1260           for(i=0;i<fNlayers;i++) delete[] fg[i];
1261           delete[] fg;
1262       } // end if fg!=0
1263       fg = new ITS_geom*[fNlayers];
1264       for(i=0;i<fNlayers;i++){
1265           fg[i] = new ITS_geom[fNlad[i]*fNdet[i]];
1266           for(j=0;j<fNlad[i]*fNdet[i];j++){
1267               R__b >> fg[i][j].fShapeIndex;
1268               R__b >> fg[i][j].fx0;
1269               R__b >> fg[i][j].fy0;
1270               R__b >> fg[i][j].fz0;
1271               R__b >> fg[i][j].frx;
1272               R__b >> fg[i][j].fry;
1273               R__b >> fg[i][j].frz;
1274               for(k=0;k<9;k++) R__b >> fg[i][j].fr[k];
1275           } // end for j
1276       } // end for i
1277       R__b >> fShape;
1278    } else {
1279       R__b.WriteVersion(AliITSgeom::IsA());
1280       TObject::Streamer(R__b);
1281       R__b << fNlayers;
1282       for(i=0;i<fNlayers;i++) R__b << fNlad[i];
1283       for(i=0;i<fNlayers;i++) R__b << fNdet[i];
1284       for(i=0;i<fNlayers;i++) for(j=0;j<fNlad[i]*fNdet[i];j++){
1285           R__b << fg[i][j].fShapeIndex;
1286           R__b << fg[i][j].fx0;
1287           R__b << fg[i][j].fy0;
1288           R__b << fg[i][j].fz0;
1289           R__b << fg[i][j].frx;
1290           R__b << fg[i][j].fry;
1291           R__b << fg[i][j].frz;
1292           for(k=0;k<9;k++) R__b << fg[i][j].fr[k];
1293       } // end for i,j
1294       R__b << fShape;
1295    }
1296 }
1297 //______________________________________________________________________
1298 //     The following routines modify the transformation of "this"
1299 // geometry transformations in a number of different ways.
1300 //______________________________________________________________________
1301 void AliITSgeom::SetByAngles(Int_t lay,Int_t lad,Int_t det,
1302                              Float_t rx,Float_t ry,Float_t rz){
1303 ////////////////////////////////////////////////////////////////////////
1304 //     This function computes a new rotation matrix based on the angles
1305 // rx, ry, and rz (in radians) for a give detector on the give ladder
1306 // in the give layer. A new
1307 // fg[layer-1][(fNlad[layer-1]*(ladder-1)+detector-1)].fr[] array is
1308 // computed.
1309 ////////////////////////////////////////////////////////////////////////
1310    ITS_geom *g;
1311    Double_t  sx,cx,sy,cy,sz,cz;
1312
1313    lay--; lad--; det--; // set to zero base now.
1314    g = &(fg[lay][fNdet[lay]*lad+det]);
1315
1316    sx = sin(rx); cx = cos(rx);
1317    sy = sin(ry); cy = cos(ry);
1318    sz = sin(rz); cz = cos(rz);
1319    g->frx   = rx;
1320    g->fry   = ry;
1321    g->frz   = rz;
1322    g->fr[0] =  cz*cy;
1323    g->fr[1] = -cz*sy*sx - sz*cx;
1324    g->fr[2] = -cz*sy*cx + sz*sx;
1325    g->fr[3] =  sz*cy;
1326    g->fr[4] = -sz*sy*sx + cz*cx;
1327    g->fr[5] = -sz*sy*cx - cz*sx;
1328    g->fr[6] =  sy;
1329    g->fr[7] =  cy*sx;
1330    g->fr[8] =  cy*cx;
1331    return;
1332 }
1333 //______________________________________________________________________
1334 void AliITSgeom::SetByAngles(Int_t index,Double_t angl[]){
1335 ////////////////////////////////////////////////////////////////////////
1336 //     Sets the coordinate rotation transformation for a given module
1337 // as determined by the module index number.
1338 ////////////////////////////////////////////////////////////////////////
1339     Int_t lay,lad,det;
1340     Float_t x,y,z;
1341
1342     GetModuleId(index,lay,lad,det);
1343     x = (Float_t) angl[0];
1344     y = (Float_t) angl[1];
1345     z = (Float_t) angl[2];
1346     SetByAngles(lay,lad,det,x,y,z);
1347     return;
1348 }
1349 //______________________________________________________________________
1350 void AliITSgeom::SetTrans(Int_t index,Double_t v[]){
1351 ////////////////////////////////////////////////////////////////////////
1352 //     Sets the coordinate translation for a given module as determined
1353 // by the module index number.
1354 ////////////////////////////////////////////////////////////////////////
1355     Int_t lay,lad,det;
1356     Float_t x,y,z;
1357
1358     GetModuleId(index,lay,lad,det);
1359     x = (Float_t) v[0];
1360     y = (Float_t) v[1];
1361     z = (Float_t) v[2];
1362     SetTrans(lay,lad,det,x,y,z);
1363     return;
1364 }
1365 //___________________________________________________________________________
1366 void AliITSgeom::GlobalChange(Float_t *tran,Float_t *rot){
1367 ////////////////////////////////////////////////////////////////////////
1368 //     This function performs a Cartesian translation and rotation of
1369 // the full ITS from its default position by an amount determined by
1370 // the three element arrays dtranslation and drotation. If every element
1371 // of dtranslation and drotation are zero then there is no change made
1372 // the geometry. The change is global in that the exact same translation
1373 // and rotation is done to every detector element in the exact same way.
1374 // The units of the translation are those of the Monte Carlo, usually cm,
1375 // and those of the rotation are in radians. The elements of dtranslation
1376 // are dtranslation[0] = x, dtranslation[1] = y, and dtranslation[2] = z.
1377 // The elements of drotation are drotation[0] = rx, drotation[1] = ry, and
1378 // drotation[2] = rz. A change in x will move the hole ITS in the ALICE
1379 // global x direction, the same for a change in y. A change in z will
1380 // result in a translation of the ITS as a hole up or down the beam line.
1381 // A change in the angles will result in the inclination of the ITS with
1382 // respect to the beam line, except for an effective rotation about the
1383 // beam axis which will just rotate the ITS as a hole about the beam axis.
1384 ////////////////////////////////////////////////////////////////////////
1385    Int_t    i,j,k,l;
1386    Double_t rx,ry,rz;
1387    Double_t sx,cx,sy,cy,sz,cz;
1388    ITS_geom *gl;
1389
1390    for(i=0;i<fNlayers;i++){
1391       for(j=0;j<fNlad[i];j++) for(k=0;k<fNdet[i];k++){
1392          l = fNdet[i]*j+k; // resolved index
1393          gl = &(fg[i][l]);
1394          gl->fx0 += tran[0];
1395          gl->fy0 += tran[1];
1396          gl->fz0 += tran[2];
1397          gl->frx +=  rot[0];
1398          gl->fry +=  rot[1];
1399          gl->frz +=  rot[2];
1400          rx = gl->frx; ry = gl->fry; rz = gl->frz;
1401          sx = sin(rx); cx = cos(rx);
1402          sy = sin(ry); cy = cos(ry);
1403          sz = sin(rz); cz = cos(rz);
1404          gl->fr[0] =  cz*cy;
1405          gl->fr[1] = -cz*sy*sx - sz*cx;
1406          gl->fr[2] = -cz*sy*cx + sz*sx;
1407          gl->fr[3] =  sz*cy;
1408          gl->fr[4] = -sz*sy*sx + cz*cx;
1409          gl->fr[5] = -sz*sy*cx - cz*sx;
1410          gl->fr[6] =  sy;
1411          gl->fr[7] =  cy*sx;
1412          gl->fr[8] =  cy*cx;
1413       } // end for j,k
1414    } // end for i
1415    return;
1416 }
1417
1418 //___________________________________________________________________________
1419 void AliITSgeom::GlobalCylindericalChange(Float_t *tran,Float_t *rot){
1420 ////////////////////////////////////////////////////////////////////////
1421 //     This function performs a cylindrical translation and rotation of
1422 // each ITS element by a fixed about in radius, rphi, and z from its
1423 // default position by an amount determined by the three element arrays
1424 // dtranslation and drotation. If every element of dtranslation and
1425 // drotation are zero then there is no change made the geometry. The
1426 // change is global in that the exact same distance change in translation
1427 // and rotation is done to every detector element in the exact same way.
1428 // The units of the translation are those of the Monte Carlo, usually cm,
1429 // and those of the rotation are in radians. The elements of dtranslation
1430 // are dtranslation[0] = r, dtranslation[1] = rphi, and dtranslation[2] = z.
1431 // The elements of drotation are drotation[0] = rx, drotation[1] = ry, and
1432 // drotation[2] = rz. A change in r will results in the increase of the
1433 // radius of each layer by the same about. A change in rphi will results in
1434 // the rotation of each layer by a different angle but by the same
1435 // circumferential distance. A change in z will result in a translation
1436 // of the ITS as a hole up or down the beam line. A change in the angles
1437 // will result in the inclination of the ITS with respect to the beam
1438 // line, except for an effective rotation about the beam axis which will
1439 // just rotate the ITS as a hole about the beam axis.
1440 ////////////////////////////////////////////////////////////////////////
1441    Int_t    i,j,k,l;
1442    Double_t rx,ry,rz,r,phi,rphi; // phi in radians
1443    Double_t sx,cx,sy,cy,sz,cz,r0;
1444    ITS_geom *gl;
1445
1446    for(i=0;i<fNlayers;i++){
1447       for(j=0;j<fNlad[i];j++) for(k=0;k<fNdet[i];k++){
1448          l     = fNdet[i]*j+k; // resolved index
1449          gl    = &(fg[i][l]);
1450          r = r0= TMath::Hypot(gl->fy0,gl->fx0);
1451          phi   = atan2(gl->fy0,gl->fx0);
1452          rphi  = r0*phi;
1453          r    += tran[0];
1454          rphi += tran[1];
1455          phi   = rphi/r0;
1456          gl->fx0  = r*TMath::Cos(phi);
1457          gl->fy0  = r*TMath::Sin(phi);
1458          gl->fz0 += tran[2];
1459          gl->frx +=  rot[0];
1460          gl->fry +=  rot[1];
1461          gl->frz +=  rot[2];
1462          rx = gl->frx; ry = gl->fry; rz = gl->frz;
1463          sx = sin(rx); cx = cos(rx);
1464          sy = sin(ry); cy = cos(ry);
1465          sz = sin(rz); cz = cos(rz);
1466          gl->fr[0] =  cz*cy;
1467          gl->fr[1] = -cz*sy*sx - sz*cx;
1468          gl->fr[2] = -cz*sy*cx + sz*sx;
1469          gl->fr[3] =  sz*cy;
1470          gl->fr[4] = -sz*sy*sx + cz*cx;
1471          gl->fr[5] = -sz*sy*cx - cz*sx;
1472          gl->fr[6] =  sy;
1473          gl->fr[7] =  cy*sx;
1474          gl->fr[8] =  cy*cx;
1475       } // end for j,k
1476    } // end for i
1477    return;
1478 }
1479
1480 //___________________________________________________________________________
1481 void AliITSgeom::RandomChange(Float_t *stran,Float_t *srot){
1482 ////////////////////////////////////////////////////////////////////////
1483 //     This function performs a Gaussian random displacement and/or
1484 // rotation about the present global position of each active
1485 // volume/detector of the ITS. The sigma of the random displacement
1486 // is determined by the three element array stran, for the
1487 // x y and z translations, and the three element array srot,
1488 // for the three rotation about the axis x y and z.
1489 ////////////////////////////////////////////////////////////////////////
1490    Int_t    i,j,k,l;
1491    Double_t rx,ry,rz;
1492    Double_t sx,cx,sy,cy,sz,cz;
1493    TRandom  ran;
1494    ITS_geom *gl;
1495
1496    for(i=0;i<fNlayers;i++){
1497       for(j=0;j<fNlad[i];j++) for(k=0;k<fNdet[i];k++){
1498          l = fNdet[i]*j+k; // resolved index
1499          gl = &(fg[i][l]);
1500          gl->fx0 += ran.Gaus(0.0,stran[0]);
1501          gl->fy0 += ran.Gaus(0.0,stran[1]);
1502          gl->fz0 += ran.Gaus(0.0,stran[2]);
1503          gl->frx += ran.Gaus(0.0, srot[0]);
1504          gl->fry += ran.Gaus(0.0, srot[1]);
1505          gl->frz += ran.Gaus(0.0, srot[2]);
1506          rx = gl->frx; ry = gl->fry; rz = gl->frz;
1507          sx = sin(rx); cx = cos(rx);
1508          sy = sin(ry); cy = cos(ry);
1509          sz = sin(rz); cz = cos(rz);
1510          gl->fr[0] =  cz*cy;
1511          gl->fr[1] = -cz*sy*sx - sz*cx;
1512          gl->fr[2] = -cz*sy*cx + sz*sx;
1513          gl->fr[3] =  sz*cy;
1514          gl->fr[4] = -sz*sy*sx + cz*cx;
1515          gl->fr[5] = -sz*sy*cx - cz*sx;
1516          gl->fr[6] =  sy;
1517          gl->fr[7] =  cy*sx;
1518          gl->fr[8] =  cy*cx;
1519       } // end for j,k
1520    } // end for i
1521    return;
1522 }
1523
1524 //___________________________________________________________________________
1525 void AliITSgeom::RandomCylindericalChange(Float_t *stran,Float_t *srot){
1526 ////////////////////////////////////////////////////////////////////////
1527 //     This function performs a Gaussian random displacement and/or
1528 // rotation about the present global position of each active
1529 // volume/detector of the ITS. The sigma of the random displacement
1530 // is determined by the three element array stran, for the
1531 // r rphi and z translations, and the three element array srot,
1532 // for the three rotation about the axis x y and z. This random change
1533 // in detector position allow for the simulation of a random uncertainty
1534 // in the detector positions of the ITS.
1535 ////////////////////////////////////////////////////////////////////////
1536    Int_t     i,j,k,l;
1537    Double_t  rx,ry,rz,r,phi,x,y;  // phi in radians
1538    Double_t  sx,cx,sy,cy,sz,cz,r0;
1539    TRandom   ran;
1540    ITS_geom  *gl;
1541
1542    for(i=0;i<fNlayers;i++){
1543       for(j=0;j<fNlad[i];j++) for(k=0;k<fNdet[i];k++){
1544          l     = fNdet[i]*j+k; // resolved index
1545          gl    = &(fg[i][l]);
1546          x     = gl->fx0;
1547          y     = gl->fy0;
1548          r = r0= TMath::Hypot(y,x);
1549          phi   = TMath::ATan2(y,x);
1550          r    += ran.Gaus(0.0,stran[0]);
1551          phi  += ran.Gaus(0.0,stran[1])/r0;
1552          gl->fx0  = r*TMath::Cos(phi);
1553          gl->fy0  = r*TMath::Sin(phi);
1554          gl->fz0 += ran.Gaus(0.0,stran[2]);
1555          gl->frx += ran.Gaus(0.0, srot[0]);
1556          gl->fry += ran.Gaus(0.0, srot[1]);
1557          gl->frz += ran.Gaus(0.0, srot[2]);
1558          rx = gl->frx; ry = gl->fry; rz = gl->frz;
1559          sx = sin(rx); cx = cos(rx);
1560          sy = sin(ry); cy = cos(ry);
1561          sz = sin(rz); cz = cos(rz);
1562          gl->fr[0] =  cz*cy;
1563          gl->fr[1] = -cz*sy*sx - sz*cx;
1564          gl->fr[2] = -cz*sy*cx + sz*sx;
1565          gl->fr[3] =  sz*cy;
1566          gl->fr[4] = -sz*sy*sx + cz*cx;
1567          gl->fr[5] = -sz*sy*cx - cz*sx;
1568          gl->fr[6] =  sy;
1569          gl->fr[7] =  cy*sx;
1570          gl->fr[8] =  cy*cx;
1571       } // end for j,k
1572    } // end for i
1573    return;
1574 }
1575 //______________________________________________________________________
1576 void AliITSgeom::GeantToTracking(AliITSgeom &source){
1577 /////////////////////////////////////////////////////////////////////////
1578 //     Copy the geometry data but change it to make coordinate systems
1579 // changes between the Global to the Local coordinate system used for 
1580 // ITS tracking. Basicly the difference is that the direction of the
1581 // y coordinate system for layer 1 is rotated about the z axis 180 degrees
1582 // so that it points in the same direction as it does in all of the other
1583 // layers.
1584 ////////////////////////////////////////////////////////////////////////////
1585    Double_t oor,pr,qr;
1586    Int_t    i,j,k;
1587    Double_t PI = TMath::Pi();
1588
1589    if(this == &source) return; // don't assign to ones self.
1590
1591    // if there is an old structure allocated delete it first.
1592    if(fg != 0){
1593       for(i=0;i<fNlayers;i++) delete[] fg[i];
1594       delete[] fg;
1595    } // end if fg != 0 
1596    if(fNlad != 0) delete[] fNlad;
1597    if(fNdet != 0) delete[] fNdet;
1598
1599    fNlayers = source.fNlayers;
1600    fNlad = new Int_t[fNlayers];
1601    for(i=0;i<fNlayers;i++) fNlad[i] = source.fNlad[i];
1602    fNdet = new Int_t[fNlayers];
1603    for(i=0;i<fNlayers;i++) fNdet[i] = source.fNdet[i];
1604    fShape = new TObjArray(*(source.fShape));//This does not make a proper copy.
1605    fg = new ITS_geom* [fNlayers];
1606    for(i=0;i<fNlayers;i++){
1607       fg[i] = new ITS_geom[fNlad[i]*fNdet[i]];
1608       for(j=0;j<(fNlad[i]*fNdet[i]);j++){
1609           fg[i][j].fShapeIndex = source.fg[i][j].fShapeIndex;
1610           fg[i][j].fx0 = source.fg[i][j].fx0;
1611           fg[i][j].fy0 = source.fg[i][j].fy0;
1612           fg[i][j].fz0 = source.fg[i][j].fz0;
1613           fg[i][j].frx = source.fg[i][j].frx;
1614           fg[i][j].fry = source.fg[i][j].fry;
1615           fg[i][j].frz = source.fg[i][j].frz;
1616           for(k=0;k<9;k++) fg[i][j].fr[k] = source.fg[i][j].fr[k];
1617           if(i==0) { // layer=1 is placed up side down
1618               fg[i][j].fr[0] = +source.fg[i][j].fr[1];
1619               fg[i][j].fr[1] = -source.fg[i][j].fr[1];
1620               fg[i][j].fr[4] = +source.fg[i][j].fr[5];
1621               fg[i][j].fr[5] = -source.fg[i][j].fr[4];
1622           }else{
1623               fg[i][j].fr[0] = -source.fg[i][j].fr[1];
1624               fg[i][j].fr[1] = +source.fg[i][j].fr[1];
1625               fg[i][j].fr[4] = -source.fg[i][j].fr[5];
1626               fg[i][j].fr[5] = +source.fg[i][j].fr[4];
1627           } // end if i=1
1628           // get angles from matrix up to a phase of 180 degrees.
1629           oor     = atan2(fg[i][j].fr[7],fg[i][j].fr[8]);
1630           if(oor<0.0) oor += 2.0*PI;
1631           pr     = asin(fg[i][j].fr[2]);
1632           if(pr<0.0) pr += 2.0*PI;
1633           qr     = atan2(fg[i][j].fr[3],fg[i][j].fr[0]);
1634           if(qr<0.0) qr += 2.0*PI;
1635           fg[i][j].frx = oor;
1636           fg[i][j].fry = pr;
1637           fg[i][j].frz = qr;
1638       } // end for j
1639    } // end for i
1640    return;
1641 }