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