]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSgeom.cxx
Fixed compilation warning with HP unix.
[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 AliITSgeomS:
62 //     The structure AliITSgeomS 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 // AliITSgeomS **fGm
171 //     A pointer to an array of pointers pointing to the AliITSgeomS
172 // structure containing the coordinate transformation information.
173 // The AliITSgeomS structure corresponding to layer=lay, ladder=lad,
174 // and detector=det is gotten by fGm[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 "AliITSgeomSPD300.h"
279 #include "AliITSgeomSPD425.h"
280 #include "AliITSgeomSDD.h"
281 #include "AliITSgeomSSD.h"
282 #include "TRandom.h"
283
284 ClassImp(AliITSgeom)
285
286 //_____________________________________________________________________
287 AliITSgeom::AliITSgeom(){
288 ////////////////////////////////////////////////////////////////////////
289 //     The default constructor for the AliITSgeom class. It, by default,
290 // sets fNlayers to zero and zeros all pointers.
291 ////////////////////////////////////////////////////////////////////////
292   // Default constructor.
293   // Do not allocate anything zero everything
294    fNlayers = 0;
295    fNlad    = 0;
296    fNdet    = 0;
297    fGm       = 0;
298    fShape   = 0;
299    return;
300 }
301
302 //_____________________________________________________________________
303 AliITSgeom::~AliITSgeom(){
304 ////////////////////////////////////////////////////////////////////////
305 //     The destructor for the AliITSgeom class. If the arrays fNlad,
306 // fNdet, or fGm have had memory allocated to them, there pointer values
307 // are non zero, then this memory space is freed and they are set
308 // to zero. In addition, fNlayers is set to zero. The destruction of
309 // TObjArray fShape is, by default, handled by the TObjArray destructor.
310 ////////////////////////////////////////////////////////////////////////
311   // Default destructor.
312   // if arrays exist delete them. Then set everything to zero.
313    if(fGm!=0){
314       for(Int_t i=0;i<fNlayers;i++) delete[] fGm[i];
315       delete[] fGm;
316    } // end if fGm!=0
317    if(fNlad!=0) delete[] fNlad;
318    if(fNdet!=0) delete[] fNdet;
319    fNlayers = 0;
320    fNlad    = 0;
321    fNdet    = 0;
322    fGm       = 0;
323    return;
324 }
325
326 //_____________________________________________________________________
327 AliITSgeom::AliITSgeom(const char *filename){
328 ////////////////////////////////////////////////////////////////////////
329 //     The constructor for the AliITSgeom class. All of the data to fill
330 // this structure is read in from the file given my the input filename.
331 ////////////////////////////////////////////////////////////////////////
332    FILE     *pf;
333    Int_t    i;
334    AliITSgeomS *g;
335    Int_t    l,a,d;
336    Float_t  x,y,z,o,p,q,r,s,t;
337    Double_t oor,pr,qr,rr,sr,tr; // Radians
338    Double_t lr[9];
339    Double_t si; // sin(angle)
340    Double_t pi = TMath::Pi(), byPI = pi/180.;
341
342    pf = fopen(filename,"r");
343
344    fNlayers = 6; // set default number of ladders
345    fNlad    = new Int_t[fNlayers];
346    fNdet    = new Int_t[fNlayers];
347    // find the number of ladders and detectors in this geometry.
348    for(i=0;i<fNlayers;i++){fNlad[i]=fNdet[i]=0;} // zero out arrays
349    for(;;){ // for ever loop
350       i = fscanf(pf,"%d %d %d %f %f %f %f %f %f %f %f %f",
351                      &l,&a,&d,&x,&y,&z,&o,&p,&q,&r,&s,&t);
352       if(i==EOF) break;
353       if(l<1 || l>fNlayers) {
354          printf("error in file %s layer=%d min is 1 max is %d/n",
355                  filename,l,fNlayers);
356          continue;
357       }// end if l
358       if(fNlad[l-1]<a) fNlad[l-1] = a;
359       if(fNdet[l-1]<d) fNdet[l-1] = d;
360    } // end for ever loop
361    // counted the number of ladders and detectors now allocate space.
362    fGm = new AliITSgeomS* [fNlayers];
363    for(i=0;i<fNlayers;i++){
364       fGm[i] = 0;
365       l = fNlad[i]*fNdet[i];
366       fGm[i] = new AliITSgeomS[l]; // allocate space for transforms
367    } // end for i
368
369    // Set up Shapes for a default configuration of 6 layers.
370    fShape = new TObjArray(3);
371    AddShape((TObject *) new AliITSgeomSPD300());  // shape 0
372    AddShape((TObject *) new AliITSgeomSDD());  // shape 1
373    AddShape((TObject *) new AliITSgeomSSD());  // shape 2
374
375    // prepare to read in transforms
376    rewind(pf); // start over reading file
377    for(;;){ // for ever loop
378       i = fscanf(pf,"%d %d %d %f %f %f %f %f %f %f %f %f",
379                      &l,&a,&d,&x,&y,&z,&o,&p,&q,&r,&s,&t);
380       if(i==EOF) break;
381       if(l<1 || l>fNlayers) {
382          printf("error in file %s layer=%d min is 1 max is %d/n",
383                  filename,l,fNlayers);
384          continue;
385       }// end if l
386       l--; a--; d--; // shift layer, ladder, and detector counters to zero base
387       i = d + a*fNdet[l]; // position of this detector
388       g = &(fGm[l][i]);
389
390       oor = byPI*o;
391       pr = byPI*p;
392       qr = byPI*q;
393       rr = byPI*r;
394       sr = byPI*s;
395       tr = byPI*t;
396
397       g->fx0   = x;
398       g->fy0   = y;
399       g->fz0   = z;
400 //
401       si    = sin(oor);if(o== 90.0) si = +1.0;
402                       if(o==270.0) si = -1.0;
403                       if(o==  0.0||o==180.) si = 0.0;
404       lr[0] = si * cos(pr);
405       lr[1] = si * sin(pr);
406       lr[2] = cos(oor);if(o== 90.0||o==270.) lr[2] = 0.0;
407                       if(o== 0.0)           lr[2] = +1.0;
408                       if(o==180.0)          lr[2] = -1.0;
409 //
410       si    =  sin(qr);if(q== 90.0) si = +1.0; 
411                        if(q==270.0) si = -1.0;
412                        if(q==  0.0||q==180.) si = 0.0;
413       lr[3] = si * cos(rr);
414       lr[4] = si * sin(rr);
415       lr[5] = cos(qr);if(q== 90.0||q==270.) lr[5] = 0.0;
416                       if(q==  0.0)          lr[5] = +1.0;
417                       if(q==180.0)          lr[5] = -1.0;
418 //
419       si    = sin(sr);if(s== 90.0) si = +1.0;
420                       if(s==270.0) si = -1.0;
421                       if(s==  0.0||s==180.) si = 0.0;
422       lr[6] = si * cos(tr);
423       lr[7] = si * sin(tr);
424       lr[8] = cos(sr);if(s== 90.0||s==270.0) lr[8] =  0.0;
425                       if(s==  0.0)           lr[8] = +1.0;
426                       if(s==180.0)           lr[8] = -1.0;
427       // Normalize these elements
428       for(a=0;a<3;a++){// reuse float Si and integers a and d.
429          si = 0.0;
430          for(d=0;d<3;d++) si += lr[3*a+d]*lr[3*a+d];
431          si = TMath::Sqrt(1./si);
432          for(d=0;d<3;d++) g->fr[3*a+d] = lr[3*a+d] = si*lr[3*a+d];
433       } // end for a
434       // get angles from matrix up to a phase of 180 degrees.
435       oor     = atan2(lr[7],lr[8]);if(oor<0.0) oor += 2.0*pi;
436       pr     = asin(lr[2]);       if(pr<0.0) pr += 2.0*pi;
437       qr     = atan2(lr[3],lr[0]);if(qr<0.0) qr += 2.0*pi;
438       g->frx = oor;
439       g->fry = pr;
440       g->frz = qr;
441       // l = layer-1 at this point.
442            if(l==0||l==1) g->fShapeIndex = 0; // SPD's
443       else if(l==2||l==3) g->fShapeIndex = 1; // SDD's
444       else if(l==4||l==5) g->fShapeIndex = 2; // SSD's
445    } // end for ever loop
446    fclose(pf);
447 }
448
449 //________________________________________________________________________
450 AliITSgeom::AliITSgeom(const AliITSgeom &source){
451 ////////////////////////////////////////////////////////////////////////
452 //     The copy constructor for the AliITSgeom class. It calls the
453 // = operator function. See the = operator function for more details.
454 ////////////////////////////////////////////////////////////////////////
455
456     *this = source;  // Just use the = operator for now.
457
458     return;
459 }
460
461 //________________________________________________________________________
462 /*void AliITSgeom::operator=(const AliITSgeom &source){
463 ////////////////////////////////////////////////////////////////////////
464 //     The = operator function for the AliITSgeom class. It makes an
465 // independent copy of the class in such a way that any changes made
466 // to the copied class will not affect the source class in any way.
467 // This is required for many ITS alignment studies where the copied
468 // class is then modified by introducing some misalignment.
469 ////////////////////////////////////////////////////////////////////////
470    Int_t i,j,k;
471
472    if(this == &source) return; // don't assign to ones self.
473
474    // if there is an old structure allocated delete it first.
475    if(fGm != 0){
476       for(i=0;i<fNlayers;i++) delete[] fGm[i];
477       delete[] fGm;
478    } // end if fGm != 0 
479    if(fNlad != 0) delete[] fNlad;
480    if(fNdet != 0) delete[] fNdet;
481
482    fNlayers = source.fNlayers;
483    fNlad = new Int_t[fNlayers];
484    for(i=0;i<fNlayers;i++) fNlad[i] = source.fNlad[i];
485    fNdet = new Int_t[fNlayers];
486    for(i=0;i<fNlayers;i++) fNdet[i] = source.fNdet[i];
487    fShape = new TObjArray(*(source.fShape));//This does not make a proper copy.
488    fGm = new AliITSgeomS* [fNlayers];
489    for(i=0;i<fNlayers;i++){
490       fGm[i] = new AliITSgeomS[fNlad[i]*fNdet[i]];
491       for(j=0;j<(fNlad[i]*fNdet[i]);j++){
492           fGm[i][j].fShapeIndex = source.fGm[i][j].fShapeIndex;
493           fGm[i][j].fx0 = source.fGm[i][j].fx0;
494           fGm[i][j].fy0 = source.fGm[i][j].fy0;
495           fGm[i][j].fz0 = source.fGm[i][j].fz0;
496           fGm[i][j].frx = source.fGm[i][j].frx;
497           fGm[i][j].fry = source.fGm[i][j].fry;
498           fGm[i][j].frz = source.fGm[i][j].frz;
499           for(k=0;k<9;k++) fGm[i][j].fr[k] = source.fGm[i][j].fr[k];
500       } // end for j
501    } // end for i
502    return;
503    }*/
504 //________________________________________________________________________
505 AliITSgeom& AliITSgeom::operator=(const AliITSgeom &source){
506 ////////////////////////////////////////////////////////////////////////
507 //     The = operator function for the AliITSgeom class. It makes an
508 // independent copy of the class in such a way that any changes made
509 // to the copied class will not affect the source class in any way.
510 // This is required for many ITS alignment studies where the copied
511 // class is then modified by introducing some misalignment.
512 ////////////////////////////////////////////////////////////////////////
513    Int_t i,j,k;
514
515    if(this == &source) return *this; // don't assign to ones self.
516
517    // if there is an old structure allocated delete it first.
518    if(fGm != 0){
519       for(i=0;i<fNlayers;i++) delete[] fGm[i];
520       delete[] fGm;
521    } // end if fGm != 0 
522    if(fNlad != 0) delete[] fNlad;
523    if(fNdet != 0) delete[] fNdet;
524
525    fNlayers = source.fNlayers;
526    fNlad = new Int_t[fNlayers];
527    for(i=0;i<fNlayers;i++) fNlad[i] = source.fNlad[i];
528    fNdet = new Int_t[fNlayers];
529    for(i=0;i<fNlayers;i++) fNdet[i] = source.fNdet[i];
530    fShape = new TObjArray(*(source.fShape));//This does not make a proper copy.
531    fGm = new AliITSgeomS* [fNlayers];
532    for(i=0;i<fNlayers;i++){
533       fGm[i] = new AliITSgeomS[fNlad[i]*fNdet[i]];
534       for(j=0;j<(fNlad[i]*fNdet[i]);j++){
535           fGm[i][j].fShapeIndex = source.fGm[i][j].fShapeIndex;
536           fGm[i][j].fx0 = source.fGm[i][j].fx0;
537           fGm[i][j].fy0 = source.fGm[i][j].fy0;
538           fGm[i][j].fz0 = source.fGm[i][j].fz0;
539           fGm[i][j].frx = source.fGm[i][j].frx;
540           fGm[i][j].fry = source.fGm[i][j].fry;
541           fGm[i][j].frz = source.fGm[i][j].frz;
542           for(k=0;k<9;k++) fGm[i][j].fr[k] = source.fGm[i][j].fr[k];
543       } // end for j
544    } // end for i
545    return *this;
546 }
547 //________________________________________________________________________
548 void AliITSgeom::GtoL(Int_t lay,Int_t lad,Int_t det,
549                        const Double_t *g,Double_t *l){
550 ////////////////////////////////////////////////////////////////////////
551 //     The function that does the global ALICE Cartesian coordinate
552 // to local active volume detector Cartesian coordinate transformation.
553 // The local detector coordinate system is determined by the layer, 
554 // ladder, and detector numbers. The global coordinates are entered by
555 // the three element Double_t array g and the local coordinate values
556 // are returned by the three element Double_t array l. The order of the 
557 // three elements are g[0]=x, g[1]=y, and g[2]=z, similarly for l.
558 ////////////////////////////////////////////////////////////////////////
559    Double_t x,y,z;
560    AliITSgeomS *gl;
561
562    lay--; lad--; det--;
563    gl = &(fGm[lay][fNdet[lay]*lad+det]);
564
565    x    = g[0] - gl->fx0;
566    y    = g[1] - gl->fy0;
567    z    = g[2] - gl->fz0;
568    l[0] = gl->fr[0]*x + gl->fr[1]*y + gl->fr[2]*z;
569    l[1] = gl->fr[3]*x + gl->fr[4]*y + gl->fr[5]*z;
570    l[2] = gl->fr[6]*x + gl->fr[7]*y + gl->fr[8]*z;
571    return;
572 }
573 //________________________________________________________________________
574 void AliITSgeom::GtoL(const Int_t *id,const Double_t *g,Double_t *l){
575 ////////////////////////////////////////////////////////////////////////
576 //     The function that does the local active volume detector Cartesian
577 // coordinate to global ALICE Cartesian coordinate transformation.
578 // The local detector coordinate system is determined by the id[0]=layer, 
579 // id[1]=ladder, and id[2]=detector numbers. The local coordinates are
580 // entered by the three element Double_t array l and the global coordinate
581 // values are returned by the three element Double_t array g. The order of the 
582 // three elements are l[0]=x, l[1]=y, and l[2]=z, similarly for g.
583 ////////////////////////////////////////////////////////////////////////
584     GtoL(id[0],id[1],id[2],g,l);
585     return;
586 }
587 //________________________________________________________________________
588 void AliITSgeom::GtoL(const Int_t index,const Double_t *g,Double_t *l){
589 ////////////////////////////////////////////////////////////////////////
590 //     The function that does the local active volume detector Cartesian
591 // coordinate to global ALICE Cartesian coordinate transformation.
592 // The local detector coordinate system is determined by the detector
593 // index numbers (see GetModuleIndex and GetModuleID). The local 
594 // coordinates are entered by the three element Double_t array l and the 
595 // global coordinate values are returned by the three element Double_t array g.
596 // The order of the three elements are l[0]=x, l[1]=y, and l[2]=z, similarly 
597 // for g.
598 ////////////////////////////////////////////////////////////////////////
599     Int_t    lay,lad,det;
600
601     this->GetModuleId(index,lay,lad,det);
602
603     GtoL(lay,lad,det,g,l);
604     return;
605 }
606 //________________________________________________________________________
607 void AliITSgeom::GtoL(Int_t lay,Int_t lad,Int_t det,
608                        const Float_t *g,Float_t *l){
609 ////////////////////////////////////////////////////////////////////////
610 //     The function that does the global ALICE Cartesian coordinate
611 // to local active volume detector Cartesian coordinate transformation.
612 // The local detector coordinate system is determined by the layer, 
613 // ladder, and detector numbers. The global coordinates are entered by
614 // the three element Float_t array g and the local coordinate values
615 // are returned by the three element Float_t array l. The order of the 
616 // three elements are g[0]=x, g[1]=y, and g[2]=z, similarly for l.
617 ////////////////////////////////////////////////////////////////////////
618     Int_t    i;
619     Double_t gd[3],ld[3];
620
621     for(i=0;i<3;i++) gd[i] = (Double_t) g[i];
622     GtoL(lay,lad,det,(Double_t *)gd,(Double_t *)ld);
623     for(i=0;i<3;i++) l[i] = (Float_t) ld[i];
624     return;
625 }
626 //________________________________________________________________________
627 void AliITSgeom::GtoL(const Int_t *id,const Float_t *g,Float_t *l){
628 ////////////////////////////////////////////////////////////////////////
629 //     The function that does the local active volume detector Cartesian
630 // coordinate to global ALICE Cartesian coordinate transformation.
631 // The local detector coordinate system is determined by the Int_t array id,
632 // id[0]=layer, id[1]=ladder, and id[2]=detector numbers. The local 
633 // coordinates are entered by the three element Float_t array l and the
634 // global coordinate values are returned by the three element Float_t array g.
635 // The order of the three elements are l[0]=x, l[1]=y, and l[2]=z, similarly
636 // for g. The order of the three elements are g[0]=x, g[1]=y, and g[2]=z,
637 // similarly for l.
638 ////////////////////////////////////////////////////////////////////////
639     Int_t    i;
640     Double_t gd[3],ld[3];
641
642     for(i=0;i<3;i++) gd[i] = (Double_t) g[i];
643     GtoL(id[0],id[1],id[2],(Double_t *)gd,(Double_t *)ld);
644     for(i=0;i<3;i++) l[i] = (Float_t) ld[i];
645     return;
646 }
647 //________________________________________________________________________
648 void AliITSgeom::GtoL(const Int_t index,const Float_t *g,Float_t *l){
649 ////////////////////////////////////////////////////////////////////////
650 //     The function that does the local active volume detector Cartesian
651 // coordinate to global ALICE Cartesian coordinate transformation.
652 // The local detector coordinate system is determined by the detector
653 // index numbers (see GetModuleIndex and GetModuleID). The local 
654 // coordinates are entered by the three element Float_t array l and the 
655 // global coordinate values are returned by the three element Float_t array g.
656 // The order of the three elements are l[0]=x, l[1]=y, and l[2]=z, similarly 
657 // for g.
658 ////////////////////////////////////////////////////////////////////////
659     Int_t    lay,lad,det;
660     Int_t    i;
661     Double_t gd[3],ld[3];
662
663     this->GetModuleId(index,lay,lad,det);
664
665     for(i=0;i<3;i++) gd[i] = (Double_t) g[i];
666     GtoL(lay,lad,det,(Double_t *)gd,(Double_t *)ld);
667     for(i=0;i<3;i++) l[i] = (Float_t) ld[i];
668     return;
669 }
670 //________________________________________________________________________
671 void AliITSgeom::LtoG(Int_t lay,Int_t lad,Int_t det,
672                       const Double_t *l,Double_t *g){
673 ////////////////////////////////////////////////////////////////////////
674 //     The function that does the local active volume detector Cartesian
675 // coordinate to global ALICE Cartesian coordinate transformation.
676 // The local detector coordinate system is determined by the layer, 
677 // ladder, and detector numbers. The local coordinates are entered by
678 // the three element Float_t array l and the global coordinate values
679 // are returned by the three element Float_t array g. The order of the 
680 // three elements are l[0]=x, l[1]=y, and l[2]=z, similarly for g.
681 ////////////////////////////////////////////////////////////////////////
682    Double_t x,y,z;
683    AliITSgeomS *gl;
684
685    lay--; lad--; det--;
686    gl   = &(fGm[lay][fNdet[lay]*lad+det]);
687
688    x    = gl->fr[0]*l[0] + gl->fr[3]*l[1] + gl->fr[6]*l[2];
689    y    = gl->fr[1]*l[0] + gl->fr[4]*l[1] + gl->fr[7]*l[2];
690    z    = gl->fr[2]*l[0] + gl->fr[5]*l[1] + gl->fr[8]*l[2];
691    g[0] = x + gl->fx0;
692    g[1] = y + gl->fy0;
693    g[2] = z + gl->fz0;
694    return;
695 }
696 //________________________________________________________________________
697 void AliITSgeom::LtoG(const Int_t *id,const Double_t *l,Double_t *g){
698 ////////////////////////////////////////////////////////////////////////
699 //     The function that does the local active volume detector Cartesian
700 // coordinate to global ALICE Cartesian coordinate transformation.
701 // The local detector coordinate system is determined by the three
702 // element array Id containing as it's three elements Id[0]=layer, 
703 // Id[1]=ladder, and Id[2]=detector numbers. The local coordinates
704 // are entered by the three element Double_t array l and the global
705 // coordinate values are returned by the three element Double_t array g.
706 // The order of the three elements are l[0]=x, l[1]=y, and l[2]=z,
707 // similarly for g.
708 ////////////////////////////////////////////////////////////////////////
709     LtoG(id[0],id[1],id[2],l,g);
710     return;
711 }
712 //________________________________________________________________________
713 void AliITSgeom::LtoG(const Int_t index,const Double_t *l,Double_t *g){
714 ////////////////////////////////////////////////////////////////////////
715 //     The function that does the local active volume detector Cartesian
716 // coordinate to global ALICE Cartesian coordinate transformation.
717 // The local detector coordinate system is determined by the detector  
718 // index number (see GetModuleIndex and GetModuleId). The local coordinates
719 // are entered by the three element Double_t array l and the global
720 // coordinate values are returned by the three element Double_t array g.
721 // The order of the three elements are l[0]=x, l[1]=y, and l[2]=z,
722 // similarly for g.
723 ////////////////////////////////////////////////////////////////////////
724     Int_t    lay,lad,det;
725
726     this->GetModuleId(index,lay,lad,det);
727
728     LtoG(lay,lad,det,l,g);
729     return;
730 }
731 //________________________________________________________________________
732 void AliITSgeom::LtoG(Int_t lay,Int_t lad,Int_t det,
733                       const Float_t *l,Float_t *g){
734 ////////////////////////////////////////////////////////////////////////
735 //     The function that does the local active volume detector Cartesian
736 // coordinate to global ALICE Cartesian coordinate transformation.
737 // The local detector coordinate system is determined by the layer, 
738 // ladder, and detector numbers. The local coordinates are entered by
739 // the three element Float_t array l and the global coordinate values
740 // are returned by the three element Float_t array g. The order of the 
741 // three elements are l[0]=x, l[1]=y, and l[2]=z, similarly for g.
742 ////////////////////////////////////////////////////////////////////////
743     Int_t    i;
744     Double_t gd[3],ld[3];
745
746     for(i=0;i<3;i++) ld[i] = (Double_t) l[i];
747     LtoG(lay,lad,det,(Double_t *)ld,(Double_t *)gd);
748     for(i=0;i<3;i++) g[i] = (Float_t) gd[i];
749     return;
750 }
751 //________________________________________________________________________
752 void AliITSgeom::LtoG(const Int_t *id,const Float_t *l,Float_t *g){
753 ////////////////////////////////////////////////////////////////////////
754 //     The function that does the local active volume detector Cartesian
755 // coordinate to global ALICE Cartesian coordinate transformation.
756 // The local detector coordinate system is determined by the three
757 // element array Id containing as it's three elements Id[0]=layer, 
758 // Id[1]=ladder, and Id[2]=detector numbers. The local coordinates
759 // are entered by the three element Float_t array l and the global
760 // coordinate values are returned by the three element Float_t array g.
761 // The order of the three elements are l[0]=x, l[1]=y, and l[2]=z,
762 // similarly for g.
763 ////////////////////////////////////////////////////////////////////////
764     Int_t    i;
765     Double_t gd[3],ld[3];
766
767     for(i=0;i<3;i++) ld[i] = (Double_t) l[i];
768     LtoG(id[0],id[1],id[2],(Double_t *)ld,(Double_t *)gd);
769     for(i=0;i<3;i++) g[i] = (Float_t) gd[i];
770     return;
771 }
772 //________________________________________________________________________
773 void AliITSgeom::LtoG(const Int_t index,const Float_t *l,Float_t *g){
774 ////////////////////////////////////////////////////////////////////////
775 //     The function that does the local active volume detector Cartesian
776 // coordinate to global ALICE Cartesian coordinate transformation.
777 // The local detector coordinate system is determined by the detector  
778 // index number (see GetModuleIndex and GetModuleId). The local coordinates
779 // are entered by the three element Float_t array l and the global
780 // coordinate values are returned by the three element Float_t array g.
781 // The order of the three elements are l[0]=x, l[1]=y, and l[2]=z,
782 // similarly for g.
783 ////////////////////////////////////////////////////////////////////////
784     Int_t    i,lay,lad,det;
785     Double_t gd[3],ld[3];
786
787     this->GetModuleId(index,lay,lad,det);
788
789     for(i=0;i<3;i++) ld[i] = (Double_t) l[i];
790     LtoG(lay,lad,det,(Double_t *)ld,(Double_t *)gd);
791     for(i=0;i<3;i++) g[i] = (Float_t) gd[i];
792     return;
793 }
794 //______________________________________________________________________
795 void AliITSgeom::LtoL(const Int_t *id1,const Int_t *id2,
796                       Double_t *l1,Double_t *l2){
797 ////////////////////////////////////////////////////////////////////////
798 //     The function that does the local active volume detector Cartesian
799 // coordinate to a different local active volume detector Cartesian coordinate
800 // transformation. The original local detector coordinate system is determined
801 // by the detector array id1, id1[0]=layer, id1[1]=ladder, and id1[2]=detector
802 // and the new coordinate system is determined by the detector array id2,
803 // id2[0]=layer, id2[1]=ladder, and id2[2]=detector. The original local
804 // coordinates are entered by the three element Double_t array l1 and the
805 // other new local coordinate values are returned by the three element
806 // Double_t array l2. The order of the three elements are l1[0]=x, l1[1]=y,
807 // and l1[2]=z, similarly for l2.
808 ////////////////////////////////////////////////////////////////////////
809     Double_t g[3];
810
811     LtoG(id1,l1,g);
812     GtoL(id2,g,l2);
813     return;
814 }
815 //______________________________________________________________________
816 void AliITSgeom::LtoL(const Int_t index1,const Int_t index2,
817                       Double_t *l1,Double_t *l2){
818 ////////////////////////////////////////////////////////////////////////
819 //     The function that does the local active volume detector Cartesian
820 // coordinate to a different local active volume detector Cartesian coordinate
821 // transformation. The original local detector coordinate system is determined
822 // by the detector index number index1, and the new coordinate system is
823 // determined by the detector index number index2, (see GetModuleIndex and
824 // GetModuleId). The original local coordinates are entered by the three
825 // element Double_t array l1 and the other new local coordinate values are
826 // returned by the three element Double_t array l2. The order of the three
827 // elements are l1[0]=x, l1[1]=y, and l1[2]=z, similarly for l2.
828 ////////////////////////////////////////////////////////////////////////
829     Double_t g[3];
830
831     LtoG(index1,l1,g);
832     GtoL(index2,g,l2);
833     return;
834 }
835 //________________________________________________________________________
836 void AliITSgeom::GtoLMomentum(Int_t lay,Int_t lad,Int_t det,
837                               const Double_t *g,Double_t *l){
838 ////////////////////////////////////////////////////////////////////////
839 //     The function that does the global ALICE Cartesian momentum
840 // to local active volume detector Cartesian momentum transformation.
841 // The local detector coordinate system is determined by the layer, 
842 // ladder, and detector numbers. The global momentums are entered by
843 // the three element Double_t array g and the local momentums values
844 // are returned by the three element Double_t array l. The order of the 
845 // three elements are g[0]=x, g[1]=y, and g[2]=z, similarly for l.
846 ////////////////////////////////////////////////////////////////////////
847    Double_t px,py,pz;
848    AliITSgeomS *gl;
849
850    lay--; lad--; det--;
851    gl = &(fGm[lay][fNdet[lay]*lad+det]);
852
853    px   = g[0];
854    py   = g[1];
855    pz   = g[2];
856    l[0] = gl->fr[0]*px + gl->fr[1]*py + gl->fr[2]*pz;
857    l[1] = gl->fr[3]*px + gl->fr[4]*py + gl->fr[5]*pz;
858    l[2] = gl->fr[6]*px + gl->fr[7]*py + gl->fr[8]*pz;
859    return;
860 }
861 //________________________________________________________________________
862 void AliITSgeom::GtoLMomentum(Int_t lay,Int_t lad,Int_t det,
863                               const Float_t *g,Float_t *l){
864 ////////////////////////////////////////////////////////////////////////
865 //     The function that does the global ALICE Cartesian momentum
866 // to local active volume detector Cartesian momentum transformation.
867 // The local detector coordinate system is determined by the layer, 
868 // ladder, and detector numbers. The global momentums are entered by
869 // the three element Float_t array g and the local momentums values
870 // are returned by the three element Float_t array l. The order of the 
871 // three elements are g[0]=x, g[1]=y, and g[2]=z, similarly for l.
872 ////////////////////////////////////////////////////////////////////////
873     Int_t i;
874     Double_t gd[3],ld[3];
875
876     for(i=0;i<3;i++) gd[i] = (Double_t) g[i];
877     GtoLMomentum(lay,lad,det,(Double_t *)gd,(Double_t *)ld);
878     for(i=0;i<3;i++) l[i] = (Float_t) ld[i];
879     return;
880 }
881 //________________________________________________________________________
882 void AliITSgeom::LtoGMomentum(Int_t lay,Int_t lad,Int_t det,
883                               const Double_t *l,Double_t *g){
884 ////////////////////////////////////////////////////////////////////////
885 //     The function that does the local active volume detector Cartesian
886 // momentum to global ALICE Cartesian momentum transformation.
887 // The local detector momentum system is determined by the layer, 
888 // ladder, and detector numbers. The local momentums are entered by
889 // the three element Double_t array l and the global momentum values
890 // are returned by the three element Double_t array g. The order of the 
891 // three elements are l[0]=x, l[1]=y, and l[2]=z, similarly for g.
892 ////////////////////////////////////////////////////////////////////////
893    Double_t px,py,pz;
894    AliITSgeomS *gl;
895
896    lay--; lad--; det--;
897    gl   = &(fGm[lay][fNdet[lay]*lad+det]);
898
899    px   = gl->fr[0]*l[0] + gl->fr[3]*l[1] + gl->fr[6]*l[2];
900    py   = gl->fr[1]*l[0] + gl->fr[4]*l[1] + gl->fr[7]*l[2];
901    pz   = gl->fr[2]*l[0] + gl->fr[5]*l[1] + gl->fr[8]*l[2];
902    g[0] = px;
903    g[1] = py;
904    g[2] = pz;
905    return;
906 }
907 //________________________________________________________________________
908 void AliITSgeom::LtoGMomentum(Int_t lay,Int_t lad,Int_t det,
909                               const Float_t *l,Float_t *g){
910 ////////////////////////////////////////////////////////////////////////
911 //     The function that does the local active volume detector Cartesian
912 // momentum to global ALICE Cartesian momentum transformation.
913 // The local detector momentum system is determined by the layer, 
914 // ladder, and detector numbers. The local momentums are entered by
915 // the three element Float_t array l and the global momentum values
916 // are returned by the three element Float_t array g. The order of the 
917 // three elements are l[0]=x, l[1]=y, and l[2]=z, similarly for g.
918 ////////////////////////////////////////////////////////////////////////
919     Int_t i;
920     Double_t gd[3],ld[3];
921
922     for(i=0;i<3;i++) ld[i] = (Double_t) l[i];
923     LtoGMomentum(lay,lad,det,(Double_t *)ld,(Double_t *)gd);
924     for(i=0;i<3;i++) g[i] = (Float_t) gd[i];
925     return;
926 }
927 //______________________________________________________________________
928 void AliITSgeom::LtoLMomentum(const Int_t *id1,const Int_t *id2,
929                               const Double_t *l1,Double_t *l2){
930 ////////////////////////////////////////////////////////////////////////
931 //     The function that does the local active volume detector Cartesian
932 // momentum to a different local active volume detector Cartesian momentum
933 // transformation. The original local detector momentum system is determined
934 // by the Int_t array id1 (id1[0]=lay, id1[1]=lad, id1[2]=det). The new local
935 // coordinate system id determined by the Int_t array id2. The local
936 // momentums are entered by the three element Double_t array l1 and the other
937 // local momentum values are returned by the three element Double_t array l2.
938 // The order of the three elements are l1[0]=x, l1[1]=y, and l1[2]=z,
939 // similarly for l2.
940 ////////////////////////////////////////////////////////////////////////
941     Double_t g[3];
942
943     LtoGMomentum(id1[0],id1[1],id1[2],l1,g);
944     GtoLMomentum(id2[0],id2[1],id2[2],g,l2);
945     return;
946 }
947 //______________________________________________________________________
948 void AliITSgeom::GtoLErrorMatrix(const Int_t index,Double_t **g,Double_t **l){
949 ////////////////////////////////////////////////////////////////////////
950 //      This converts an error matrix, expressed in global coordinates
951 // into an error matrix expressed in local coordinates. Since the 
952 // translations do not change the error matrix they are not included.
953 // Definition: if GtoL is l[i] = T[i][j]*g[j], then from the definition
954 // of the transformation matrix above T[i][j] = fr[3*i+j]. Then for a 
955 // matrix l[i][l] = T[i][j]*g[j][k]*T[l][k] (sum over repeated indexes). 
956 // Where T[l][k] is the transpose of T[k][l].
957 ////////////////////////////////////////////////////////////////////////
958     Double_t lR[3][3],lRt[3][3];
959     Int_t    lay,lad,det,i,j,k,n;
960     AliITSgeomS *gl;
961
962     GetModuleId(index,lay,lad,det);
963     lay--;lad--;det--;
964     gl = &(fGm[lay][fNdet[lay]*lad+det]);
965
966     for(i=0;i<3;i++)for(j=0;j<3;j++){
967         lR[i][j] = lRt[j][i] = gl->fr[3*i+j];
968     } // end for i,j
969
970     for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)for(n=0;n<3;n++){
971         l[i][n] = lR[i][j]*g[j][k]*lRt[k][n];
972     } // end for i,j,k,l
973     return;
974 }
975 //______________________________________________________________________
976 void AliITSgeom::LtoGErrorMatrix(const Int_t index,Double_t **l,Double_t **g){
977 ////////////////////////////////////////////////////////////////////////
978 //      This converts an error matrix, expressed in local coordinates
979 // into an error matrix expressed in global coordinates. Since the 
980 // translations do not change the error matrix they are not included.
981 // Definition: if GtoL is l[i] = T[i][j]*g[j], then from the definition
982 // of the transformation matrix above T[i][j] = fr[3*i+j]. Then for a 
983 // matrix g[i][l] = T[j][i]*l[j][k]*T[k][l] (sum over repeated indexes). 
984 // Where T[j][i] is the transpose of T[i][j].
985 ////////////////////////////////////////////////////////////////////////
986     Double_t lR[3][3],lRt[3][3];
987     Int_t    lay,lad,det,i,j,k,n;
988     AliITSgeomS *gl;
989
990     GetModuleId(index,lay,lad,det);
991     lay--;lad--;det--;
992     gl = &(fGm[lay][fNdet[lay]*lad+det]);
993
994     for(i=0;i<3;i++)for(j=0;j<3;j++){
995         lR[i][j] = lRt[j][i] = gl->fr[3*i+j];
996     } // end for i,j
997
998     for(i=0;i<3;i++)for(j=0;j<3;j++)for(k=0;k<3;k++)for(n=0;n<3;n++){
999         g[i][n] = lRt[i][j]*l[j][k]*lR[k][n];
1000     } // end for i,j,k,l
1001     return;
1002 }
1003 //______________________________________________________________________
1004 void AliITSgeom::LtoLErrorMatrix(const Int_t index1,const Int_t index2,
1005                                  Double_t **l1,Double_t **l2){
1006 ////////////////////////////////////////////////////////////////////////
1007 //      This converts an error matrix, expressed in one local coordinates
1008 // into an error matrix expressed in different local coordinates. Since  
1009 // the translations do not change the error matrix they are not included.
1010 // This is done by going through the global coordinate system for 
1011 // simplicity and constancy.
1012 ////////////////////////////////////////////////////////////////////////
1013     Double_t g[3][3];
1014
1015     this->LtoGErrorMatrix(index1,l1,(Double_t **)g);
1016     this->GtoLErrorMatrix(index2,(Double_t **)g,l2);
1017     return;
1018 }
1019 //______________________________________________________________________
1020 Int_t AliITSgeom::GetModuleIndex(Int_t lay,Int_t lad,Int_t det){
1021 ////////////////////////////////////////////////////////////////////////
1022 //      This routine computes the module index number from the layer,
1023 // ladder, and detector numbers. The number of ladders and detectors
1024 // per layer is determined when this geometry package is constructed,
1025 // see AliITSgeom(const char *filename) for specifics.
1026 ////////////////////////////////////////////////////////////////////////
1027     Int_t i,j,k;
1028
1029     i = fNdet[lay-1] * (lad-1) + det - 1;
1030     j = 0;
1031     for(k=0;k<lay-1;k++) j += fNdet[k]*fNlad[k];
1032     return (i+j);
1033 }
1034 //___________________________________________________________________________
1035 void AliITSgeom::GetModuleId(Int_t index,Int_t &lay,Int_t &lad,Int_t &det){
1036 ////////////////////////////////////////////////////////////////////////
1037 //      This routine computes the layer, ladder and detector number 
1038 // given the module index number. The number of ladders and detectors
1039 // per layer is determined when this geometry package is constructed,
1040 // see AliITSgeom(const char *filename) for specifics.
1041 ////////////////////////////////////////////////////////////////////////
1042     Int_t i,j,k;
1043
1044     j = 0;
1045     for(k=0;k<fNlayers;k++){
1046         j += fNdet[k]*fNlad[k];
1047         if(j>index)break;
1048     } // end for k
1049     lay = k+1;
1050     i = index -j + fNdet[k]*fNlad[k];
1051     j = 0;
1052     for(k=0;k<fNlad[lay-1];k++){
1053         j += fNdet[lay-1];
1054         if(j>i)break;
1055     } // end for k
1056     lad = k+1;
1057     det = 1+i-fNdet[lay-1]*k;
1058     return;
1059 }
1060 //___________________________________________________________________________
1061 void AliITSgeom::GetRotMatrix(Int_t lay,Int_t lad,Int_t det,Double_t *mat){
1062 ////////////////////////////////////////////////////////////////////////
1063 //     Returns, in the Double_t array pointed to by mat, the full rotation
1064 // matrix for the give detector defined by layer, ladder, and detector.
1065 // It returns all nine elements of fr in the AliITSgeomS structure. See the
1066 // description of the AliITSgeomS structure for further details of this
1067 // rotation matrix.
1068 ////////////////////////////////////////////////////////////////////////
1069    Int_t    i;
1070    AliITSgeomS *g;
1071
1072    lay--; lad--; det--; // shift to base 0
1073    g = &(fGm[lay][fNdet[lay]*lad+det]);
1074    for(i=0;i<9;i++) mat[i] = g->fr[i];
1075    return;
1076 }
1077 //___________________________________________________________________________
1078 void AliITSgeom::GetRotMatrix(Int_t index,Double_t *mat){
1079 ////////////////////////////////////////////////////////////////////////
1080 //     Returns, in the Double_t array pointed to by mat, the full rotation
1081 // matrix for the give detector defined by the module index number.
1082 // It returns all nine elements of fr in the AliITSgeomS structure. See the
1083 // description of the AliITSgeomS structure for further details of this
1084 // rotation matrix.
1085 ////////////////////////////////////////////////////////////////////////
1086    Int_t    lay,lad,det;
1087
1088    this->GetModuleId(index,lay,lad,det);
1089    GetRotMatrix(lay,lad,det,mat);
1090    return;
1091 }
1092 //___________________________________________________________________________
1093 void AliITSgeom::GetRotMatrix(Int_t lay,Int_t lad,Int_t det,Float_t *mat){
1094 ////////////////////////////////////////////////////////////////////////
1095 //     Returns, in the Float_t array pointed to by mat, the full rotation
1096 // matrix for the give detector defined by layer, ladder, and detector.
1097 // It returns all nine elements of fr in the AliITSgeomS structure. See the
1098 // description of the AliITSgeomS structure for further details of this
1099 // rotation matrix.
1100 ////////////////////////////////////////////////////////////////////////
1101    Int_t    i;
1102    Double_t matd[9];
1103
1104    GetRotMatrix(lay,lad,det,(Double_t *)matd);
1105    for(i=0;i<9;i++) mat[i] = (Float_t) matd[i];
1106    return;
1107 }
1108
1109 //___________________________________________________________________________
1110 void AliITSgeom::GetRotMatrix(Int_t index,Float_t *mat){
1111 ////////////////////////////////////////////////////////////////////////
1112 //     Returns, in the Float_t array pointed to by mat, the full rotation
1113 // matrix for the give detector defined by module index number.
1114 // It returns all nine elements of fr in the AliITSgeomS structure. See the
1115 // description of the AliITSgeomS structure for further details of this
1116 // rotation matrix.
1117 ////////////////////////////////////////////////////////////////////////
1118    Int_t    i,lay,lad,det;
1119    Double_t matd[9];
1120
1121    this->GetModuleId(index,lay,lad,det);
1122    GetRotMatrix(lay,lad,det,(Double_t *)matd);
1123    for(i=0;i<9;i++) mat[i] = (Float_t) matd[i];
1124    return;
1125 }
1126
1127 //___________________________________________________________________________
1128 Int_t AliITSgeom::GetStartDet(Int_t id){
1129   /////////////////////////////////////////////////////////////////////////
1130   // returns the starting module index value for a give type of detector id
1131   /////////////////////////////////////////////////////////////////////////
1132   Int_t first;
1133   switch(id)
1134   {
1135   case 0:
1136      first = GetModuleIndex(1,1,1);
1137      break;
1138   case 1:
1139      first = GetModuleIndex(3,1,1);
1140      break;
1141   case 2:
1142      first = GetModuleIndex(5,1,1);
1143      break;
1144   default:
1145      printf("<AliITSgeom::GetFirstDet> undefined detector type\n");
1146      first = 0;
1147
1148   }
1149   return first;
1150 }
1151
1152 //___________________________________________________________________________
1153 Int_t AliITSgeom::GetLastDet(Int_t id){
1154   /////////////////////////////////////////////////////////////////////////
1155   // returns the last module index value for a give type of detector id
1156   /////////////////////////////////////////////////////////////////////////
1157   Int_t last;
1158   switch(id)
1159   {
1160   case 0:
1161      last = GetLastSPD();
1162      break;
1163    case 1:
1164      last = GetLastSDD();
1165      break;
1166    case 2:
1167      last = GetLastSSD();
1168      break;
1169    default:
1170      printf("<AliITSgeom::GetLastDet> undefined detector type\n");
1171      last = 0;
1172   }
1173   return last;
1174 }
1175
1176 //___________________________________________________________________________
1177 void AliITSgeom::PrintComparison(FILE *fp,AliITSgeom *other){
1178 ////////////////////////////////////////////////////////////////////////
1179 //     This function was primarily created for diagnostic reasons. It
1180 // print to a file pointed to by the file pointer fp the difference
1181 // between two AliITSgeom classes. The format of the file is basicly,
1182 // define d? to be the difference between the same element of the two
1183 // classes. For example dfrx = this->fGm[i][j].frx - other->fGm[i][j].frx.
1184 // if(at least one of dfx0, dfy0, dfz0,dfrx,dfry,dfrz are non zero) then print
1185 // layer ladder detector dfx0 dfy0 dfz0 dfrx dfry dfrz
1186 // if(at least one of the 9 elements of dfr[] are non zero) then print
1187 // layer ladder detector dfr[0] dfr[1] dfr[2]
1188 //                       dfr[3] dfr[4] dfr[5]
1189 //                       dfr[6] dfr[7] dfr[8]
1190 // Only non zero values are printed to save space. The differences are
1191 // typical written to a file because there are usually a lot of numbers
1192 // printed out and it is usually easier to read them in some nice editor
1193 // rather than zooming quickly past you on a screen. fprintf is used to
1194 // do the printing. The fShapeIndex difference is not printed at this time.
1195 ////////////////////////////////////////////////////////////////////////
1196    Int_t    i,j,k,l;
1197    Double_t xt,yt,zt,xo,yo,zo;
1198    Double_t rxt,ryt,rzt,rxo,ryo,rzo;  // phi in radians
1199    AliITSgeomS *gt,*go;
1200    Bool_t   t;
1201
1202    for(i=0;i<this->fNlayers;i++){
1203       for(j=0;j<this->fNlad[i];j++) for(k=0;k<this->fNdet[i];k++){
1204          l   = this->fNdet[i]*j+k; // resolved index
1205          gt  = &(this->fGm[i][l]);
1206          go  = &(other->fGm[i][l]);
1207          xt  = gt->fx0; yt  = gt->fy0; zt  = gt->fz0;
1208          xo  = go->fx0; yo  = go->fy0; zo  = go->fz0;
1209          rxt = gt->frx; ryt = gt->fry; rzt = gt->frz;
1210          rxo = go->frx; ryo = go->fry; rzo = go->frz;
1211          if(!(xt==xo&&yt==yo&&zt==zo&&rxt==rxo&&ryt==ryo&&rzt==rzo))
1212          fprintf(fp,"%1.1d %2.2d %2.2d dTrans=%f %f %f drot=%f %f %f\n",
1213                  i+1,j+1,k+1,xt-xo,yt-yo,zt-zo,rxt-rxo,ryt-ryo,rzt-rzo);
1214          t = kFALSE;
1215          for(i=0;i<9;i++) t = gt->fr[i] != go->fr[i];
1216          if(t){
1217              fprintf(fp,"%1.1d %2.2d %2.2d dfr= %e %e %e\n",i+1,j+1,k+1,
1218                  gt->fr[0]-go->fr[0],gt->fr[1]-go->fr[1],gt->fr[2]-go->fr[2]);
1219              fprintf(fp,"        dfr= %e %e %e\n",
1220                  gt->fr[3]-go->fr[3],gt->fr[4]-go->fr[4],gt->fr[5]-go->fr[5]);
1221              fprintf(fp,"        dfr= %e %e %e\n",
1222                  gt->fr[6]-go->fr[6],gt->fr[7]-go->fr[7],gt->fr[8]-go->fr[8]);
1223          }
1224       } // end for j,k
1225    } // end for i
1226    return;
1227 }
1228
1229 //___________________________________________________________________________
1230 void AliITSgeom::PrintData(FILE *fp,Int_t lay,Int_t lad,Int_t det){
1231 ////////////////////////////////////////////////////////////////////////
1232 //     This function prints out the coordinate transformations for
1233 // the particular detector defined by layer, ladder, and detector
1234 // to the file pointed to by the File pointer fp. fprintf statements
1235 // are used to print out the numbers. The format is
1236 // layer ladder detector Trans= fx0 fy0 fz0 rot= frx fry frz Shape=fShapeIndex
1237 //                         dfr= fr[0] fr[1] fr[2]
1238 //                         dfr= fr[3] fr[4] fr[5]
1239 //                         dfr= fr[6] fr[7] fr[8]
1240 // By indicating which detector, some control over the information 
1241 // is given to the user. The output it written to the file pointed
1242 // to by the file pointer fp. This can be set to stdout if you want.
1243 ////////////////////////////////////////////////////////////////////////
1244    Int_t    i,j,k,l;
1245    AliITSgeomS *gt;
1246
1247    i  = lay-1;
1248    j  = lad-1;
1249    k  = det-1;
1250    l  = this->fNdet[i]*j+k; // resolved index
1251    gt = &(this->fGm[i][l]);
1252    fprintf(fp,"%1.1d %2.2d %2.2d Trans=%f %f %f rot=%f %f %f Shape=%d\n",
1253            i+1,j+1,k+1,gt->fx0,gt->fy0,gt->fz0,gt->frx,gt->fry,gt->frz,
1254            gt->fShapeIndex);
1255    fprintf(fp,"        dfr= %e %e %e\n",gt->fr[0],gt->fr[1],gt->fr[2]);
1256    fprintf(fp,"        dfr= %e %e %e\n",gt->fr[3],gt->fr[4],gt->fr[5]);
1257    fprintf(fp,"        dfr= %e %e %e\n",gt->fr[6],gt->fr[7],gt->fr[8]);
1258    return;
1259 }
1260 //___________________________________________________________________________
1261 ofstream & AliITSgeom::PrintGeom(ofstream &lRb){
1262 ////////////////////////////////////////////////////////////////////////
1263 //     The default Streamer function "written by ROOT" doesn't write out
1264 // the arrays referenced by pointers. Therefore, a specific Streamer function
1265 // has to be written. This function should not be modified but instead added
1266 // on to so that older versions can still be read. The proper handling of
1267 // the version dependent streamer function hasn't been written do to the lack
1268 // of finding an example at the time of writing.
1269 ////////////////////////////////////////////////////////////////////////
1270    // Stream an object of class AliITSgeom.
1271     Int_t i,j,k;
1272
1273     lRb.setf(ios::scientific);
1274     lRb << fNlayers << " ";
1275     for(i=0;i<fNlayers;i++) lRb << fNlad[i] << " ";
1276     for(i=0;i<fNlayers;i++) lRb << fNdet[i] << "\n";
1277     for(i=0;i<fNlayers;i++) for(j=0;j<fNlad[i]*fNdet[i];j++){
1278         lRb <<setprecision(16) << fGm[i][j].fShapeIndex << " ";
1279         lRb <<setprecision(16) << fGm[i][j].fx0 << " ";
1280         lRb <<setprecision(16) << fGm[i][j].fy0 << " ";
1281         lRb <<setprecision(16) << fGm[i][j].fz0 << " ";
1282         lRb <<setprecision(16) << fGm[i][j].frx << " ";
1283         lRb <<setprecision(16) << fGm[i][j].fry << " ";
1284         lRb <<setprecision(16) << fGm[i][j].frz << "\n";
1285         for(k=0;k<9;k++) lRb <<setprecision(16) << fGm[i][j].fr[k] << " ";
1286         lRb << "\n";
1287       } // end for i,j
1288 //      lRb << fShape;
1289       return lRb;
1290 }
1291 //___________________________________________________________________________
1292 ifstream & AliITSgeom::ReadGeom(ifstream &lRb){
1293 ////////////////////////////////////////////////////////////////////////
1294 //     The default Streamer function "written by ROOT" doesn't write out
1295 // the arrays referenced by pointers. Therefore, a specific Streamer function
1296 // has to be written. This function should not be modified but instead added
1297 // on to so that older versions can still be read. The proper handling of
1298 // the version dependent streamer function hasn't been written do to the lack
1299 // of finding an example at the time of writing.
1300 ////////////////////////////////////////////////////////////////////////
1301    // Stream an object of class AliITSgeom.
1302     Int_t i,j,k;
1303
1304       lRb >> fNlayers;
1305       if(fNlad!=0) delete[] fNlad;
1306       if(fNdet!=0) delete[] fNdet;
1307       fNlad = new Int_t[fNlayers];
1308       fNdet = new Int_t[fNlayers];
1309       for(i=0;i<fNlayers;i++) lRb >> fNlad[i];
1310       for(i=0;i<fNlayers;i++) lRb >> fNdet[i];
1311       if(fGm!=0){
1312           for(i=0;i<fNlayers;i++) delete[] fGm[i];
1313           delete[] fGm;
1314       } // end if fGm!=0
1315       fGm = new AliITSgeomS*[fNlayers];
1316       for(i=0;i<fNlayers;i++){
1317           fGm[i] = new AliITSgeomS[fNlad[i]*fNdet[i]];
1318           for(j=0;j<fNlad[i]*fNdet[i];j++){
1319               lRb >> fGm[i][j].fShapeIndex;
1320               lRb >> fGm[i][j].fx0;
1321               lRb >> fGm[i][j].fy0;
1322               lRb >> fGm[i][j].fz0;
1323               lRb >> fGm[i][j].frx;
1324               lRb >> fGm[i][j].fry;
1325               lRb >> fGm[i][j].frz;
1326               for(k=0;k<9;k++) lRb >> fGm[i][j].fr[k];
1327           } // end for j
1328       } // end for i
1329 //      lRb >> fShape;
1330       return lRb;
1331 }
1332 //______________________________________________________________________
1333 //     The following routines modify the transformation of "this"
1334 // geometry transformations in a number of different ways.
1335 //______________________________________________________________________
1336 void AliITSgeom::SetByAngles(Int_t lay,Int_t lad,Int_t det,
1337                              Float_t rx,Float_t ry,Float_t rz){
1338 ////////////////////////////////////////////////////////////////////////
1339 //     This function computes a new rotation matrix based on the angles
1340 // rx, ry, and rz (in radians) for a give detector on the give ladder
1341 // in the give layer. A new
1342 // fGm[layer-1][(fNlad[layer-1]*(ladder-1)+detector-1)].fr[] array is
1343 // computed.
1344 ////////////////////////////////////////////////////////////////////////
1345    AliITSgeomS *g;
1346    Double_t  sx,cx,sy,cy,sz,cz;
1347
1348    lay--; lad--; det--; // set to zero base now.
1349    g = &(fGm[lay][fNdet[lay]*lad+det]);
1350
1351    sx = sin(rx); cx = cos(rx);
1352    sy = sin(ry); cy = cos(ry);
1353    sz = sin(rz); cz = cos(rz);
1354    g->frx   = rx;
1355    g->fry   = ry;
1356    g->frz   = rz;
1357    g->fr[0] =  cz*cy;
1358    g->fr[1] = -cz*sy*sx - sz*cx;
1359    g->fr[2] = -cz*sy*cx + sz*sx;
1360    g->fr[3] =  sz*cy;
1361    g->fr[4] = -sz*sy*sx + cz*cx;
1362    g->fr[5] = -sz*sy*cx - cz*sx;
1363    g->fr[6] =  sy;
1364    g->fr[7] =  cy*sx;
1365    g->fr[8] =  cy*cx;
1366    return;
1367 }
1368 //______________________________________________________________________
1369 void AliITSgeom::SetByAngles(Int_t index,Double_t angl[]){
1370 ////////////////////////////////////////////////////////////////////////
1371 //     Sets the coordinate rotation transformation for a given module
1372 // as determined by the module index number.
1373 ////////////////////////////////////////////////////////////////////////
1374     Int_t lay,lad,det;
1375     Float_t x,y,z;
1376
1377     GetModuleId(index,lay,lad,det);
1378     x = (Float_t) angl[0];
1379     y = (Float_t) angl[1];
1380     z = (Float_t) angl[2];
1381     SetByAngles(lay,lad,det,x,y,z);
1382     return;
1383 }
1384 //______________________________________________________________________
1385 void AliITSgeom::SetTrans(Int_t index,Double_t v[]){
1386 ////////////////////////////////////////////////////////////////////////
1387 //     Sets the coordinate translation for a given module as determined
1388 // by the module index number.
1389 ////////////////////////////////////////////////////////////////////////
1390     Int_t lay,lad,det;
1391     Float_t x,y,z;
1392
1393     GetModuleId(index,lay,lad,det);
1394     x = (Float_t) v[0];
1395     y = (Float_t) v[1];
1396     z = (Float_t) v[2];
1397     SetTrans(lay,lad,det,x,y,z);
1398     return;
1399 }
1400 //___________________________________________________________________________
1401 void AliITSgeom::GlobalChange(Float_t *tran,Float_t *rot){
1402 ////////////////////////////////////////////////////////////////////////
1403 //     This function performs a Cartesian translation and rotation of
1404 // the full ITS from its default position by an amount determined by
1405 // the three element arrays dtranslation and drotation. If every element
1406 // of dtranslation and drotation are zero then there is no change made
1407 // the geometry. The change is global in that the exact same translation
1408 // and rotation is done to every detector element in the exact same way.
1409 // The units of the translation are those of the Monte Carlo, usually cm,
1410 // and those of the rotation are in radians. The elements of dtranslation
1411 // are dtranslation[0] = x, dtranslation[1] = y, and dtranslation[2] = z.
1412 // The elements of drotation are drotation[0] = rx, drotation[1] = ry, and
1413 // drotation[2] = rz. A change in x will move the hole ITS in the ALICE
1414 // global x direction, the same for a change in y. A change in z will
1415 // result in a translation of the ITS as a hole up or down the beam line.
1416 // A change in the angles will result in the inclination of the ITS with
1417 // respect to the beam line, except for an effective rotation about the
1418 // beam axis which will just rotate the ITS as a hole about the beam axis.
1419 ////////////////////////////////////////////////////////////////////////
1420    Int_t    i,j,k,l;
1421    Double_t rx,ry,rz;
1422    Double_t sx,cx,sy,cy,sz,cz;
1423    AliITSgeomS *gl;
1424
1425    for(i=0;i<fNlayers;i++){
1426       for(j=0;j<fNlad[i];j++) for(k=0;k<fNdet[i];k++){
1427          l = fNdet[i]*j+k; // resolved index
1428          gl = &(fGm[i][l]);
1429          gl->fx0 += tran[0];
1430          gl->fy0 += tran[1];
1431          gl->fz0 += tran[2];
1432          gl->frx +=  rot[0];
1433          gl->fry +=  rot[1];
1434          gl->frz +=  rot[2];
1435          rx = gl->frx; ry = gl->fry; rz = gl->frz;
1436          sx = sin(rx); cx = cos(rx);
1437          sy = sin(ry); cy = cos(ry);
1438          sz = sin(rz); cz = cos(rz);
1439          gl->fr[0] =  cz*cy;
1440          gl->fr[1] = -cz*sy*sx - sz*cx;
1441          gl->fr[2] = -cz*sy*cx + sz*sx;
1442          gl->fr[3] =  sz*cy;
1443          gl->fr[4] = -sz*sy*sx + cz*cx;
1444          gl->fr[5] = -sz*sy*cx - cz*sx;
1445          gl->fr[6] =  sy;
1446          gl->fr[7] =  cy*sx;
1447          gl->fr[8] =  cy*cx;
1448       } // end for j,k
1449    } // end for i
1450    return;
1451 }
1452
1453 //___________________________________________________________________________
1454 void AliITSgeom::GlobalCylindericalChange(Float_t *tran,Float_t *rot){
1455 ////////////////////////////////////////////////////////////////////////
1456 //     This function performs a cylindrical translation and rotation of
1457 // each ITS element by a fixed about in radius, rphi, and z from its
1458 // default position by an amount determined by the three element arrays
1459 // dtranslation and drotation. If every element of dtranslation and
1460 // drotation are zero then there is no change made the geometry. The
1461 // change is global in that the exact same distance change in translation
1462 // and rotation is done to every detector element in the exact same way.
1463 // The units of the translation are those of the Monte Carlo, usually cm,
1464 // and those of the rotation are in radians. The elements of dtranslation
1465 // are dtranslation[0] = r, dtranslation[1] = rphi, and dtranslation[2] = z.
1466 // The elements of drotation are drotation[0] = rx, drotation[1] = ry, and
1467 // drotation[2] = rz. A change in r will results in the increase of the
1468 // radius of each layer by the same about. A change in rphi will results in
1469 // the rotation of each layer by a different angle but by the same
1470 // circumferential distance. A change in z will result in a translation
1471 // of the ITS as a hole up or down the beam line. A change in the angles
1472 // will result in the inclination of the ITS with respect to the beam
1473 // line, except for an effective rotation about the beam axis which will
1474 // just rotate the ITS as a hole about the beam axis.
1475 ////////////////////////////////////////////////////////////////////////
1476    Int_t    i,j,k,l;
1477    Double_t rx,ry,rz,r,phi,rphi; // phi in radians
1478    Double_t sx,cx,sy,cy,sz,cz,r0;
1479    AliITSgeomS *gl;
1480
1481    for(i=0;i<fNlayers;i++){
1482       for(j=0;j<fNlad[i];j++) for(k=0;k<fNdet[i];k++){
1483          l     = fNdet[i]*j+k; // resolved index
1484          gl    = &(fGm[i][l]);
1485          r = r0= TMath::Hypot(gl->fy0,gl->fx0);
1486          phi   = atan2(gl->fy0,gl->fx0);
1487          rphi  = r0*phi;
1488          r    += tran[0];
1489          rphi += tran[1];
1490          phi   = rphi/r0;
1491          gl->fx0  = r*TMath::Cos(phi);
1492          gl->fy0  = r*TMath::Sin(phi);
1493          gl->fz0 += tran[2];
1494          gl->frx +=  rot[0];
1495          gl->fry +=  rot[1];
1496          gl->frz +=  rot[2];
1497          rx = gl->frx; ry = gl->fry; rz = gl->frz;
1498          sx = sin(rx); cx = cos(rx);
1499          sy = sin(ry); cy = cos(ry);
1500          sz = sin(rz); cz = cos(rz);
1501          gl->fr[0] =  cz*cy;
1502          gl->fr[1] = -cz*sy*sx - sz*cx;
1503          gl->fr[2] = -cz*sy*cx + sz*sx;
1504          gl->fr[3] =  sz*cy;
1505          gl->fr[4] = -sz*sy*sx + cz*cx;
1506          gl->fr[5] = -sz*sy*cx - cz*sx;
1507          gl->fr[6] =  sy;
1508          gl->fr[7] =  cy*sx;
1509          gl->fr[8] =  cy*cx;
1510       } // end for j,k
1511    } // end for i
1512    return;
1513 }
1514
1515 //___________________________________________________________________________
1516 void AliITSgeom::RandomChange(Float_t *stran,Float_t *srot){
1517 ////////////////////////////////////////////////////////////////////////
1518 //     This function performs a Gaussian random displacement and/or
1519 // rotation about the present global position of each active
1520 // volume/detector of the ITS. The sigma of the random displacement
1521 // is determined by the three element array stran, for the
1522 // x y and z translations, and the three element array srot,
1523 // for the three rotation about the axis x y and z.
1524 ////////////////////////////////////////////////////////////////////////
1525    Int_t    i,j,k,l;
1526    Double_t rx,ry,rz;
1527    Double_t sx,cx,sy,cy,sz,cz;
1528    TRandom  ran;
1529    AliITSgeomS *gl;
1530
1531    for(i=0;i<fNlayers;i++){
1532       for(j=0;j<fNlad[i];j++) for(k=0;k<fNdet[i];k++){
1533          l = fNdet[i]*j+k; // resolved index
1534          gl = &(fGm[i][l]);
1535          gl->fx0 += ran.Gaus(0.0,stran[0]);
1536          gl->fy0 += ran.Gaus(0.0,stran[1]);
1537          gl->fz0 += ran.Gaus(0.0,stran[2]);
1538          gl->frx += ran.Gaus(0.0, srot[0]);
1539          gl->fry += ran.Gaus(0.0, srot[1]);
1540          gl->frz += ran.Gaus(0.0, srot[2]);
1541          rx = gl->frx; ry = gl->fry; rz = gl->frz;
1542          sx = sin(rx); cx = cos(rx);
1543          sy = sin(ry); cy = cos(ry);
1544          sz = sin(rz); cz = cos(rz);
1545          gl->fr[0] =  cz*cy;
1546          gl->fr[1] = -cz*sy*sx - sz*cx;
1547          gl->fr[2] = -cz*sy*cx + sz*sx;
1548          gl->fr[3] =  sz*cy;
1549          gl->fr[4] = -sz*sy*sx + cz*cx;
1550          gl->fr[5] = -sz*sy*cx - cz*sx;
1551          gl->fr[6] =  sy;
1552          gl->fr[7] =  cy*sx;
1553          gl->fr[8] =  cy*cx;
1554       } // end for j,k
1555    } // end for i
1556    return;
1557 }
1558
1559 //___________________________________________________________________________
1560 void AliITSgeom::RandomCylindericalChange(Float_t *stran,Float_t *srot){
1561 ////////////////////////////////////////////////////////////////////////
1562 //     This function performs a Gaussian random displacement and/or
1563 // rotation about the present global position of each active
1564 // volume/detector of the ITS. The sigma of the random displacement
1565 // is determined by the three element array stran, for the
1566 // r rphi and z translations, and the three element array srot,
1567 // for the three rotation about the axis x y and z. This random change
1568 // in detector position allow for the simulation of a random uncertainty
1569 // in the detector positions of the ITS.
1570 ////////////////////////////////////////////////////////////////////////
1571    Int_t     i,j,k,l;
1572    Double_t  rx,ry,rz,r,phi,x,y;  // phi in radians
1573    Double_t  sx,cx,sy,cy,sz,cz,r0;
1574    TRandom   ran;
1575    AliITSgeomS  *gl;
1576
1577    for(i=0;i<fNlayers;i++){
1578       for(j=0;j<fNlad[i];j++) for(k=0;k<fNdet[i];k++){
1579          l     = fNdet[i]*j+k; // resolved index
1580          gl    = &(fGm[i][l]);
1581          x     = gl->fx0;
1582          y     = gl->fy0;
1583          r = r0= TMath::Hypot(y,x);
1584          phi   = TMath::ATan2(y,x);
1585          r    += ran.Gaus(0.0,stran[0]);
1586          phi  += ran.Gaus(0.0,stran[1])/r0;
1587          gl->fx0  = r*TMath::Cos(phi);
1588          gl->fy0  = r*TMath::Sin(phi);
1589          gl->fz0 += ran.Gaus(0.0,stran[2]);
1590          gl->frx += ran.Gaus(0.0, srot[0]);
1591          gl->fry += ran.Gaus(0.0, srot[1]);
1592          gl->frz += ran.Gaus(0.0, srot[2]);
1593          rx = gl->frx; ry = gl->fry; rz = gl->frz;
1594          sx = sin(rx); cx = cos(rx);
1595          sy = sin(ry); cy = cos(ry);
1596          sz = sin(rz); cz = cos(rz);
1597          gl->fr[0] =  cz*cy;
1598          gl->fr[1] = -cz*sy*sx - sz*cx;
1599          gl->fr[2] = -cz*sy*cx + sz*sx;
1600          gl->fr[3] =  sz*cy;
1601          gl->fr[4] = -sz*sy*sx + cz*cx;
1602          gl->fr[5] = -sz*sy*cx - cz*sx;
1603          gl->fr[6] =  sy;
1604          gl->fr[7] =  cy*sx;
1605          gl->fr[8] =  cy*cx;
1606       } // end for j,k
1607    } // end for i
1608    return;
1609 }
1610 //______________________________________________________________________
1611 void AliITSgeom::GeantToTracking(AliITSgeom &source){
1612 /////////////////////////////////////////////////////////////////////////
1613 //     Copy the geometry data but change it to make coordinate systems
1614 // changes between the Global to the Local coordinate system used for 
1615 // ITS tracking. Basicly the difference is that the direction of the
1616 // y coordinate system for layer 1 is rotated about the z axis 180 degrees
1617 // so that it points in the same direction as it does in all of the other
1618 // layers.
1619 // Fixed for bug and new calulation of tracking coordiantes. BSN June 8 2000.
1620 ////////////////////////////////////////////////////////////////////////////
1621    Double_t oor,pr,qr;
1622    Int_t    i,j,k;
1623    Double_t pi = TMath::Pi();
1624
1625    if(this == &source) return; // don't assign to ones self.
1626
1627    // if there is an old structure allocated delete it first.
1628    if(fGm != 0){
1629       for(i=0;i<fNlayers;i++) delete[] fGm[i];
1630       delete[] fGm;
1631    } // end if fGm != 0 
1632    if(fNlad != 0) delete[] fNlad;
1633    if(fNdet != 0) delete[] fNdet;
1634
1635    fNlayers = source.fNlayers;
1636    fNlad = new Int_t[fNlayers];
1637    for(i=0;i<fNlayers;i++) fNlad[i] = source.fNlad[i];
1638    fNdet = new Int_t[fNlayers];
1639    for(i=0;i<fNlayers;i++) fNdet[i] = source.fNdet[i];
1640    fShape = new TObjArray(*(source.fShape));//This does not make a proper copy.
1641    fGm = new AliITSgeomS* [fNlayers];
1642    for(i=0;i<fNlayers;i++){
1643       fGm[i] = new AliITSgeomS[fNlad[i]*fNdet[i]];
1644       for(j=0;j<(fNlad[i]*fNdet[i]);j++){
1645           fGm[i][j].fShapeIndex = source.fGm[i][j].fShapeIndex;
1646           fGm[i][j].fx0 = source.fGm[i][j].fx0;
1647           fGm[i][j].fy0 = source.fGm[i][j].fy0;
1648           fGm[i][j].fz0 = source.fGm[i][j].fz0;
1649           fGm[i][j].frx = source.fGm[i][j].frx;
1650           fGm[i][j].fry = source.fGm[i][j].fry;
1651           fGm[i][j].frz = source.fGm[i][j].frz;
1652           for(k=0;k<9;k++) fGm[i][j].fr[k] = source.fGm[i][j].fr[k];
1653           if(i==0) { // layer=1 is placed up side down
1654               // mupliply by -1  0 0
1655               //              0 -1 0
1656               //              0  0 1.
1657               fGm[i][j].fr[0] = -source.fGm[i][j].fr[0];
1658               fGm[i][j].fr[1] = -source.fGm[i][j].fr[1];
1659               fGm[i][j].fr[2] = -source.fGm[i][j].fr[2];
1660               fGm[i][j].fr[3] = -source.fGm[i][j].fr[3];
1661               fGm[i][j].fr[4] = -source.fGm[i][j].fr[4];
1662               fGm[i][j].fr[5] = -source.fGm[i][j].fr[5];
1663           } // end if i=1
1664           // get angles from matrix up to a phase of 180 degrees.
1665           oor     = atan2(fGm[i][j].fr[7],fGm[i][j].fr[8]);
1666           if(oor<0.0) oor += 2.0*pi;
1667           pr     = asin(fGm[i][j].fr[2]);
1668           if(pr<0.0) pr += 2.0*pi;
1669           qr     = atan2(fGm[i][j].fr[3],fGm[i][j].fr[0]);
1670           if(qr<0.0) qr += 2.0*pi;
1671           fGm[i][j].frx = oor;
1672           fGm[i][j].fry = pr;
1673           fGm[i][j].frz = qr;
1674       } // end for j
1675    } // end for i
1676    return;
1677 }
1678 //___________________________________________________________________________
1679 void AliITSgeom::Streamer(TBuffer &lRb){
1680 ////////////////////////////////////////////////////////////////////////
1681 //     The default Streamer function "written by ROOT" doesn't write out
1682 // the arrays referenced by pointers. Therefore, a specific Streamer function
1683 // has to be written. This function should not be modified but instead added
1684 // on to so that older versions can still be read. The proper handling of
1685 // the version dependent streamer function hasn't been written do to the lack
1686 // of finding an example at the time of writing.
1687 ////////////////////////////////////////////////////////////////////////
1688    // Stream an object of class AliITSgeom.
1689     Int_t i,j,k,n;
1690
1691
1692    printf("AliITSgeomStreamer starting\n");
1693    if (lRb.IsReading()) {
1694       Version_t lRv = lRb.ReadVersion(); if (lRv) { }
1695       TObject::Streamer(lRb);
1696       printf("AliITSgeomStreamer reading fNlayers\n");
1697       lRb >> fNlayers;
1698       if(fNlad!=0) delete[] fNlad;
1699       if(fNdet!=0) delete[] fNdet;
1700       fNlad = new Int_t[fNlayers];
1701       fNdet = new Int_t[fNlayers];
1702       printf("AliITSgeomStreamer fNlad\n");
1703       for(i=0;i<fNlayers;i++) lRb >> fNlad[i];
1704       printf("AliITSgeomStreamer fNdet\n");
1705       for(i=0;i<fNlayers;i++) lRb >> fNdet[i];
1706       if(fGm!=0){
1707           for(i=0;i<fNlayers;i++) delete[] fGm[i];
1708           delete[] fGm;
1709       } // end if fGm!=0
1710       fGm = new AliITSgeomS*[fNlayers];
1711       printf("AliITSgeomStreamer AliITSgeomS\n");
1712       for(i=0;i<fNlayers;i++){
1713           n     = fNlad[i]*fNdet[i];
1714           fGm[i] = new AliITSgeomS[n];
1715           for(j=0;j<n;j++){
1716               lRb >> fGm[i][j].fShapeIndex;
1717               lRb >> fGm[i][j].fx0;
1718               lRb >> fGm[i][j].fy0;
1719               lRb >> fGm[i][j].fz0;
1720               lRb >> fGm[i][j].frx;
1721               lRb >> fGm[i][j].fry;
1722               lRb >> fGm[i][j].frz;
1723               for(k=0;k<9;k++) lRb >> fGm[i][j].fr[k];
1724           } // end for j
1725       } // end for i
1726       /*
1727       if(fShape!=0){
1728           delete fShape;
1729       } // end if
1730       printf("AliITSgeomStreamer reading fShape\n");
1731       lRb >> fShape;
1732       */
1733       //if (fShape) fShape->Streamer(lRb);
1734    } else {
1735       lRb.WriteVersion(AliITSgeom::IsA());
1736       TObject::Streamer(lRb);
1737       lRb << fNlayers;
1738       for(i=0;i<fNlayers;i++) lRb << fNlad[i];
1739       for(i=0;i<fNlayers;i++) lRb << fNdet[i];
1740       for(i=0;i<fNlayers;i++) for(j=0;j<fNlad[i]*fNdet[i];j++){
1741           lRb << fGm[i][j].fShapeIndex;
1742           lRb << fGm[i][j].fx0;
1743           lRb << fGm[i][j].fy0;
1744           lRb << fGm[i][j].fz0;
1745           lRb << fGm[i][j].frx;
1746           lRb << fGm[i][j].fry;
1747           lRb << fGm[i][j].frz;
1748           for(k=0;k<9;k++) lRb << fGm[i][j].fr[k];
1749       } // end for i,j
1750       // lRb << fShape;
1751       //if (fShape) fShape->Streamer(lRb);
1752    } // end if reading
1753    printf("AliITSgeomStreamer Finished\n");
1754 }