1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 Revision 1.4.4.5 2000/03/04 23:42:39 nilsen
19 Updated the comments/documentations and improved the maintainability of the
22 Revision 1.4.4.4 2000/03/02 21:27:07 nilsen
23 Added two functions, SetByAngles and SetTrans.
25 Revision 1.4.4.3 2000/01/23 03:09:10 nilsen
26 // fixed compiler warnings for new function LtLErrorMatrix(...)
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
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
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.
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
43 Revision 1.2 1999/09/29 09:24:20 fca
44 Introduction of the Copyright and cvs Log
48 ///////////////////////////////////////////////////////////////////////
49 // ITS geometry manipulation routines. //
50 // Created April 15 1999. //
52 // By: Bjorn S. Nilsen //
54 // Updated May 27 1999. //
55 // Added Cylindrical random and global based changes. //
56 // Added function PrintComparison. //
57 ///////////////////////////////////////////////////////////////////////
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
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.
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.
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
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)|
103 // *|0 cos(frx) sin(frx)|
104 // |0 -sin(frx) cos(frx)|
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.
110 // The local coordinate system by, default, is show in the following
111 // figures. Also shown are the ladder numbering scheme.
114 <img src="picts/ITS/its1+2_convention_front_5.gif">
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.
125 <img src="picts/ITS/its3+4_convention_front_5.gif">
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.
135 <img src="picts/ITS/its5+6_convention_front_5.gif">
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.
146 ////////////////////////////////////////////////////////////////////////
148 ////////////////////////////////////////////////////////////////////////
151 // Written by Bjorn S. Nilsen
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.
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.
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.
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.
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.
191 // Inlined Member Functions:
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].
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].
201 // Int_t GetNlayers()
202 // This function returns the number of layers defined in the ITS
203 // geometry. In particular it returns fNlayers.
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
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.
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.
225 // This function returns the version number of this AliITSgeom
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.
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++)
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++)
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++)
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++)
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++)
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++)
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 ////////////////////////////////////////////////////////////////////////
273 #include <iostream.h>
278 #include "AliITSgeom.h"
279 #include "AliITSgeomSPD300.h"
280 #include "AliITSgeomSPD425.h"
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
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.
313 for(Int_t i=0;i<fNlayers;i++) delete[] fGm[i];
316 if(fNlad!=0) delete[] fNlad;
317 if(fNdet!=0) delete[] fNdet;
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 ////////////////////////////////////////////////////////////////////////
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;
339 Double_t si; // sin(angle)
340 Double_t pi = TMath::Pi(), byPI = pi/180.;
342 pf = fopen(filename,"r");
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);
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);
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++){
365 l = fNlad[i]*fNdet[i];
366 fGm[i] = new AliITSgeomS[l]; // allocate space for transforms
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
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);
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);
386 l--; a--; d--; // shift layer, ladder, and detector counters to zero base
387 i = d + a*fNdet[l]; // position of this detector
390 //part coming from the tracking
391 g->angles[0] = o; // Added 25-05-00 S. Vanadia
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
408 // Tracking rotation matrix 25-5-2000
410 ppr = (Double_t)(p+90.0)*byPI;
411 rrr = (Double_t)(r+90.0)*byPI;
414 ppr = (Double_t)(p-90.0)*byPI;
415 rrr = (Double_t)(r-90.0)*byPI;
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
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;
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;
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.
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];
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;
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
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 ////////////////////////////////////////////////////////////////////////
490 *this = source; // Just use the = operator for now.
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 ////////////////////////////////////////////////////////////////////////
506 if(this == &source) return; // don't assign to ones self.
508 // if there is an old structure allocated delete it first.
510 for(i=0;i<fNlayers;i++) delete[] fGm[i];
513 if(fNlad != 0) delete[] fNlad;
514 if(fNdet != 0) delete[] fNdet;
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];
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 ////////////////////////////////////////////////////////////////////////
550 if(this == &source) return *this; // don't assign to ones self.
552 // if there is an old structure allocated delete it first.
554 for(i=0;i<fNlayers;i++) delete[] fGm[i];
557 if(fNlad != 0) delete[] fNlad;
558 if(fNdet != 0) delete[] fNdet;
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;
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];
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
588 fGm[i][j].rottrack[ii][jj] = source.fGm[i][j].rottrack[ii][jj];
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 ////////////////////////////////////////////////////////////////////////
604 gl = &(fGm[lay][fNdet[lay]*lad+det]);
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;
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 ////////////////////////////////////////////////////////////////////////
628 gl = &(fGm[lay][fNdet[lay]*lad+det]);
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];
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 ////////////////////////////////////////////////////////////////////////
658 gl = &(fGm[lay][fNdet[lay]*lad+det]);
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;
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);
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
693 ////////////////////////////////////////////////////////////////////////
696 this->GetModuleId(index,lay,lad,det);
698 GtoL(lay,lad,det,g,l);
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 ////////////////////////////////////////////////////////////////////////
714 Double_t gd[3],ld[3];
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];
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,
733 ////////////////////////////////////////////////////////////////////////
735 Double_t gd[3],ld[3];
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];
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
753 ////////////////////////////////////////////////////////////////////////
756 Double_t gd[3],ld[3];
758 this->GetModuleId(index,lay,lad,det);
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];
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 ////////////////////////////////////////////////////////////////////////
781 gl = &(fGm[lay][fNdet[lay]*lad+det]);
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];
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,
803 ////////////////////////////////////////////////////////////////////////
804 LtoG(id[0],id[1],id[2],l,g);
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,
818 ////////////////////////////////////////////////////////////////////////
821 this->GetModuleId(index,lay,lad,det);
823 LtoG(lay,lad,det,l,g);
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 ////////////////////////////////////////////////////////////////////////
839 Double_t gd[3],ld[3];
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];
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,
858 ////////////////////////////////////////////////////////////////////////
860 Double_t gd[3],ld[3];
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];
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,
878 ////////////////////////////////////////////////////////////////////////
880 Double_t gd[3],ld[3];
882 this->GetModuleId(index,lay,lad,det);
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];
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 ////////////////////////////////////////////////////////////////////////
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 ////////////////////////////////////////////////////////////////////////
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 ////////////////////////////////////////////////////////////////////////
946 gl = &(fGm[lay][fNdet[lay]*lad+det]);
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;
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 ////////////////////////////////////////////////////////////////////////
969 Double_t gd[3],ld[3];
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];
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 ////////////////////////////////////////////////////////////////////////
992 gl = &(fGm[lay][fNdet[lay]*lad+det]);
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];
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 ////////////////////////////////////////////////////////////////////////
1015 Double_t gd[3],ld[3];
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];
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 ////////////////////////////////////////////////////////////////////////
1038 LtoGMomentum(id1[0],id1[1],id1[2],l1,g);
1039 GtoLMomentum(id2[0],id2[1],id2[2],g,l2);
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;
1057 GetModuleId(index,lay,lad,det);
1059 gl = &(fGm[lay][fNdet[lay]*lad+det]);
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];
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
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;
1085 GetModuleId(index,lay,lad,det);
1087 gl = &(fGm[lay][fNdet[lay]*lad+det]);
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];
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
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 ////////////////////////////////////////////////////////////////////////
1110 this->LtoGErrorMatrix(index1,l1,(Double_t **)g);
1111 this->GtoLErrorMatrix(index2,(Double_t **)g,l2);
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 ////////////////////////////////////////////////////////////////////////
1124 i = fNdet[lay-1] * (lad-1) + det - 1;
1126 for(k=0;k<lay-1;k++) j += fNdet[k]*fNlad[k];
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 ////////////////////////////////////////////////////////////////////////
1140 for(k=0;k<fNlayers;k++){
1141 j += fNdet[k]*fNlad[k];
1145 i = index -j + fNdet[k]*fNlad[k];
1147 for(k=0;k<fNlad[lay-1];k++){
1152 det = 1+i-fNdet[lay-1]*k;
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
1163 ////////////////////////////////////////////////////////////////////////
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];
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
1180 ////////////////////////////////////////////////////////////////////////
1183 this->GetModuleId(index,lay,lad,det);
1184 GetRotMatrix(lay,lad,det,mat);
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
1195 ////////////////////////////////////////////////////////////////////////
1199 GetRotMatrix(lay,lad,det,(Double_t *)matd);
1200 for(i=0;i<9;i++) mat[i] = (Float_t) matd[i];
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
1212 ////////////////////////////////////////////////////////////////////////
1213 Int_t i,lay,lad,det;
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];
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 /////////////////////////////////////////////////////////////////////////
1231 first = GetModuleIndex(1,1,1);
1234 first = GetModuleIndex(3,1,1);
1237 first = GetModuleIndex(5,1,1);
1240 printf("<AliITSgeom::GetFirstDet> undefined detector type\n");
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 /////////////////////////////////////////////////////////////////////////
1256 last = GetLastSPD();
1259 last = GetLastSDD();
1262 last = GetLastSSD();
1265 printf("<AliITSgeom::GetLastDet> undefined detector type\n");
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 ////////////////////////////////////////////////////////////////////////
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;
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);
1310 for(i=0;i<9;i++) t = gt->fr[i] != go->fr[i];
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]);
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 ////////////////////////////////////////////////////////////////////////
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,
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]);
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.
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] << " ";
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] << " ";
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.
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];
1418 for(i=0;i<fNlayers;i++) delete[] fGm[i];
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];
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
1459 ////////////////////////////////////////////////////////////////////////
1461 Double_t sx,cx,sy,cy,sz,cz;
1463 lay--; lad--; det--; // set to zero base now.
1464 g = &(fGm[lay][fNdet[lay]*lad+det]);
1466 sx = sin(rx); cx = cos(rx);
1467 sy = sin(ry); cy = cos(ry);
1468 sz = sin(rz); cz = cos(rz);
1473 g->fr[1] = -cz*sy*sx - sz*cx;
1474 g->fr[2] = -cz*sy*cx + sz*sx;
1476 g->fr[4] = -sz*sy*sx + cz*cx;
1477 g->fr[5] = -sz*sy*cx - cz*sx;
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 ////////////////////////////////////////////////////////////////////////
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);
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 ////////////////////////////////////////////////////////////////////////
1508 GetModuleId(index,lay,lad,det);
1512 SetTrans(lay,lad,det,x,y,z);
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 ////////////////////////////////////////////////////////////////////////
1537 Double_t sx,cx,sy,cy,sz,cz;
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
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);
1555 gl->fr[1] = -cz*sy*sx - sz*cx;
1556 gl->fr[2] = -cz*sy*cx + sz*sx;
1558 gl->fr[4] = -sz*sy*sx + cz*cx;
1559 gl->fr[5] = -sz*sy*cx - cz*sx;
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 ////////////////////////////////////////////////////////////////////////
1592 Double_t rx,ry,rz,r,phi,rphi; // phi in radians
1593 Double_t sx,cx,sy,cy,sz,cz,r0;
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
1600 r = r0= TMath::Hypot(gl->fy0,gl->fx0);
1601 phi = atan2(gl->fy0,gl->fx0);
1606 gl->fx0 = r*TMath::Cos(phi);
1607 gl->fy0 = r*TMath::Sin(phi);
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);
1617 gl->fr[1] = -cz*sy*sx - sz*cx;
1618 gl->fr[2] = -cz*sy*cx + sz*sx;
1620 gl->fr[4] = -sz*sy*sx + cz*cx;
1621 gl->fr[5] = -sz*sy*cx - cz*sx;
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 ////////////////////////////////////////////////////////////////////////
1642 Double_t sx,cx,sy,cy,sz,cz;
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
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);
1661 gl->fr[1] = -cz*sy*sx - sz*cx;
1662 gl->fr[2] = -cz*sy*cx + sz*sx;
1664 gl->fr[4] = -sz*sy*sx + cz*cx;
1665 gl->fr[5] = -sz*sy*cx - cz*sx;
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 ////////////////////////////////////////////////////////////////////////
1687 Double_t rx,ry,rz,r,phi,x,y; // phi in radians
1688 Double_t sx,cx,sy,cy,sz,cz,r0;
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
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);
1713 gl->fr[1] = -cz*sy*sx - sz*cx;
1714 gl->fr[2] = -cz*sy*cx + sz*sx;
1716 gl->fr[4] = -sz*sy*sx + cz*cx;
1717 gl->fr[5] = -sz*sy*cx - cz*sx;
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
1734 // Fixed for bug and new calulation of tracking coordiantes. BSN June 8 2000.
1735 ////////////////////////////////////////////////////////////////////////////
1738 Double_t pi = TMath::Pi();
1740 if(this == &source) return; // don't assign to ones self.
1742 // if there is an old structure allocated delete it first.
1744 for(i=0;i<fNlayers;i++) delete[] fGm[i];
1746 } // end if fGm != 0
1747 if(fNlad != 0) delete[] fNlad;
1748 if(fNdet != 0) delete[] fNdet;
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
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];
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;
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.
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");
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];
1823 for(i=0;i<fNlayers;i++) delete[] fGm[i];
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];
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];
1855 printf("AliITSgeomStreamer reading fShape\n");
1858 //if (fShape) fShape->Streamer(lRb);
1860 lRb.WriteVersion(AliITSgeom::IsA());
1861 TObject::Streamer(lRb);
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];
1885 //if (fShape) fShape->Streamer(lRb);
1887 //printf("AliITSgeomStreamer Finished\n");