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