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