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