1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 Revision 1.3 1999/10/04 15:20:12 fca
19 Correct syntax accepted by g++ but not standard for static members, remove minor warnings
21 Revision 1.2 1999/09/29 09:24:20 fca
22 Introduction of the Copyright and cvs Log
26 ///////////////////////////////////////////////////////////////////////
27 // ITS geometry manimulaiton routines. //
28 // Created April 15 1999. //
30 // By: Bjorn S. Nilsen //
32 // Updated May 27 1999. //
33 // Added Cylinderical random and global based changes. //
34 // Added function PrintComparison. //
35 ///////////////////////////////////////////////////////////////////////
40 #include "AliITSgeom.h"
45 //_____________________________________________________________________
46 AliITSgeom::AliITSgeom(){
47 ////////////////////////////////////////////////////////////////////////
48 // The default constructor for the AliITSgeom class. It, by default,
49 // sets fNlayers to zero and zeros all pointers.
50 ////////////////////////////////////////////////////////////////////////
51 // Default constructor.
52 // Do not allocate anything zero everything
61 //_____________________________________________________________________
62 AliITSgeom::~AliITSgeom(){
63 ////////////////////////////////////////////////////////////////////////
64 // The destructor for the AliITSgeom class. If the arrays fNlad,
65 // fNdet, or fg have had memory allocated to them, there pointer values
66 // are non zero, then this memory space is freed and they are set
67 // to zero. In addition, fNlayers is set to zero. The destruction of
68 // TObjArray fShape is, by default, handled by the TObjArray destructor.
69 ////////////////////////////////////////////////////////////////////////
70 // Default destructor.
71 // if arrays exist delet them. Then set everything to zero.
73 for(Int_t i=0;i<fNlayers;i++) delete[] fg[i];
76 if(fNlad!=0) delete[] fNlad;
77 if(fNdet!=0) delete[] fNdet;
85 //_____________________________________________________________________
86 AliITSgeom::AliITSgeom(const char *filename){
87 ////////////////////////////////////////////////////////////////////////
88 // The constructor for the AliITSgeom class. All of the data to fill
89 // this structure is read in from the file given my the input filename.
90 ////////////////////////////////////////////////////////////////////////
95 Float_t x,y,z,o,p,q,r,s,t;
96 Double_t oor,pr,qr,rr,sr,tr; // Radians
98 Double_t si; // sin(angle)
99 Double_t PI = TMath::Pi(), byPI = PI/180.;
101 pf = fopen(filename,"r");
103 fNlayers = 6; // set default number of ladders
104 fNlad = new Int_t[fNlayers];
105 fNdet = new Int_t[fNlayers];
106 // find the number of laders and detectors in this geometry.
107 for(i=0;i<fNlayers;i++){fNlad[i]=fNdet[i]=0;} // zero out arrays
108 for(;;){ // for ever loop
109 i = fscanf(pf,"%d %d %d %f %f %f %f %f %f %f %f %f",
110 &l,&a,&d,&x,&y,&z,&o,&p,&q,&r,&s,&t);
112 if(l<1 || l>fNlayers) {
113 printf("error in file %s layer=%d min is 1 max is %d/n",
114 filename,l,fNlayers);
117 if(fNlad[l-1]<a) fNlad[l-1] = a;
118 if(fNdet[l-1]<d) fNdet[l-1] = d;
119 } // end for ever loop
120 // counted the number of laders and detectors now allocate space.
121 fg = new ITS_geom* [fNlayers];
122 for(i=0;i<fNlayers;i++){
124 l = fNlad[i]*fNdet[i];
125 fg[i] = new ITS_geom[l]; // allocate space for transforms
128 // Set up Shapes for a default configuration of 6 layers.
129 fShape = new TObjArray;
130 AddShape((TObject *) new AliITSgeomSPD()); // shape 0
131 AddShape((TObject *) new AliITSgeomSDD()); // shape 1
132 AddShape((TObject *) new AliITSgeomSPD()); // shape 2
134 // prepair to read in transforms
135 rewind(pf); // start over reading file
136 for(;;){ // for ever loop
137 i = fscanf(pf,"%d %d %d %f %f %f %f %f %f %f %f %f",
138 &l,&a,&d,&x,&y,&z,&o,&p,&q,&r,&s,&t);
140 if(l<1 || l>fNlayers) {
141 printf("error in file %s layer=%d min is 1 max is %d/n",
142 filename,l,fNlayers);
145 l--; a--; d--; // shift layer, lader, and detector counters to zero base
146 i = d + a*fNdet[l]; // position of this detector
160 si = sin(oor);if(o== 90.0) si = +1.0;
161 if(o==270.0) si = -1.0;
162 if(o== 0.0||o==180.) si = 0.0;
163 lr[0] = si * cos(pr);
164 lr[1] = si * sin(pr);
165 lr[2] = cos(oor);if(o== 90.0||o==270.) lr[2] = 0.0;
166 if(o== 0.0) lr[2] = +1.0;
167 if(o==180.0) lr[2] = -1.0;
169 si = sin(qr);if(q== 90.0) si = +1.0;
170 if(q==270.0) si = -1.0;
171 if(q== 0.0||q==180.) si = 0.0;
172 lr[3] = si * cos(rr);
173 lr[4] = si * sin(rr);
174 lr[5] = cos(qr);if(q== 90.0||q==270.) lr[5] = 0.0;
175 if(q== 0.0) lr[5] = +1.0;
176 if(q==180.0) lr[5] = -1.0;
178 si = sin(sr);if(s== 90.0) si = +1.0;
179 if(s==270.0) si = -1.0;
180 if(s== 0.0||s==180.) si = 0.0;
181 lr[6] = si * cos(tr);
182 lr[7] = si * sin(tr);
183 lr[8] = cos(sr);if(s== 90.0||s==270.0) lr[8] = 0.0;
184 if(s== 0.0) lr[8] = +1.0;
185 if(s==180.0) lr[8] = -1.0;
186 // Normalize these elements
187 for(a=0;a<3;a++){// reuse float si and integers a and d.
189 for(d=0;d<3;d++) si += lr[3*a+d]*lr[3*a+d];
190 si = TMath::Sqrt(1./si);
191 for(d=0;d<3;d++) g->fr[3*a+d] = lr[3*a+d] = si*lr[3*a+d];
193 // get angles from matrix up to a phase of 180 degrees.
194 oor = atan2(lr[7],lr[8]);if(oor<0.0) oor += 2.0*PI;
195 pr = asin(lr[2]); if(pr<0.0) pr += 2.0*PI;
196 qr = atan2(lr[3],lr[0]);if(qr<0.0) qr += 2.0*PI;
200 // l = layer-1 at this point.
201 if(l==0||l==1) g->fShapeIndex = 0; // SPD's
202 else if(l==2||l==3) g->fShapeIndex = 1; // SDD's
203 else if(l==4||l==5) g->fShapeIndex = 2; // SSD's
204 } // end for ever loop
208 //________________________________________________________________________
209 AliITSgeom::AliITSgeom(AliITSgeom &source){
210 ////////////////////////////////////////////////////////////////////////
211 // The copy constructor for the AliITSgeom class. It calls the
212 // = operator function. See the = operator function for more details.
213 ////////////////////////////////////////////////////////////////////////
214 source = *this; // Just use the = operator for now.
218 //________________________________________________________________________
219 void AliITSgeom::operator=(AliITSgeom &source){
220 ////////////////////////////////////////////////////////////////////////
221 // The = operator function for the AliITSgeom class. It makes an
222 // independent copy of the class in such a way that any changes made
223 // to the copied class will not affect the source class in any way.
224 // This is required for many ITS alignment studies where the copied
225 // class is then modified by introducing some misalignment.
226 ////////////////////////////////////////////////////////////////////////
229 if(this == &source) return; // don't assign to ones self.
231 // if there is an old structure allocated delete it first.
233 for(i=0;i<fNlayers;i++) delete[] fg[i];
236 if(fNlad != 0) delete[] fNlad;
237 if(fNdet != 0) delete[] fNdet;
239 fNlayers = source.fNlayers;
240 fNlad = new Int_t[fNlayers];
241 for(i=0;i<fNlayers;i++) fNlad[i] = source.fNlad[i];
242 fNdet = new Int_t[fNlayers];
243 for(i=0;i<fNlayers;i++) fNdet[i] = source.fNdet[i];
244 fShape = new TObjArray(*(source.fShape));//This does not make a proper copy.
245 fg = new ITS_geom* [fNlayers];
246 for(i=0;i<fNlayers;i++){
247 fg[i] = new ITS_geom[fNlad[i]*fNdet[i]];
248 for(j=0;j<(fNlad[i]*fNdet[i]);j++){
249 fg[i][j].fShapeIndex = source.fg[i][j].fShapeIndex;
250 fg[i][j].fx0 = source.fg[i][j].fx0;
251 fg[i][j].fy0 = source.fg[i][j].fy0;
252 fg[i][j].fz0 = source.fg[i][j].fz0;
253 fg[i][j].frx = source.fg[i][j].frx;
254 fg[i][j].fry = source.fg[i][j].fry;
255 fg[i][j].frz = source.fg[i][j].frz;
256 for(k=0;k<9;k++) fg[i][j].fr[k] = source.fg[i][j].fr[k];
263 //________________________________________________________________________
264 void AliITSgeom::GtoL(Int_t lay,Int_t lad,Int_t det,
265 const Float_t *g,Float_t *l){
266 ////////////////////////////////////////////////////////////////////////
267 // The function that does the global ALICE Cartesian coordinate
268 // to local active volume detector Cartesian coordinate transformation.
269 // The local detector coordinate system is determined by the layer,
270 // ladder, and detector numbers. The global coordinates are entered by
271 // the three element Float_t array g and the local coordinate values
272 // are returned by the three element Float_t array l. The order of the
273 // three elements are g[0]=x, g[1]=y, and g[2]=z, similarly for l.
274 ////////////////////////////////////////////////////////////////////////
279 gl = &(fg[lay][fNdet[lay]*lad+det]);
284 l[0] = gl->fr[0]*x + gl->fr[1]*y + gl->fr[2]*z;
285 l[1] = gl->fr[3]*x + gl->fr[4]*y + gl->fr[5]*z;
286 l[2] = gl->fr[6]*x + gl->fr[7]*y + gl->fr[8]*z;
290 //________________________________________________________________________
291 void AliITSgeom::GtoL(const Int_t *id,const Float_t *g,Float_t *l){
292 ////////////////////////////////////////////////////////////////////////
293 // The function that does the local active volume detector Cartesian
294 // coordinate to global ALICE Cartesian coordinate transformation.
295 // The local detector coordinate system is determined by the layer,
296 // ladder, and detector numbers. The local coordinates are entered by
297 // the three element Float_t array l and the global coordinate values
298 // are returned by the three element Float_t array g. The order of the
299 // three elements are l[0]=x, l[1]=y, and l[2]=z, similarly for g.
300 ////////////////////////////////////////////////////////////////////////
305 lay = id[0]; lad = id[1]; det = id[2];
307 gl = &(fg[lay][fNdet[lay]*lad+det]);
312 l[0] = gl->fr[0]*x + gl->fr[1]*y + gl->fr[2]*z;
313 l[1] = gl->fr[3]*x + gl->fr[4]*y + gl->fr[5]*z;
314 l[2] = gl->fr[6]*x + gl->fr[7]*y + gl->fr[8]*z;
317 //________________________________________________________________________
318 void AliITSgeom::GtoL(const Int_t index,const Float_t *g,Float_t *l){
319 ////////////////////////////////////////////////////////////////////////
320 // The function that does the local active volume detector Cartesian
321 // coordinate to global ALICE Cartesian coordinate transformation.
322 // The local detector coordinate system is determined by the detector
323 // index numbers (see GetModuleIndex and GetModuleID). The local
324 // coordinates are entered by the three element Float_t array l and the
325 // global coordinate values are returned by the three element Float_t array g.
326 // The order of the three elements are l[0]=x, l[1]=y, and l[2]=z, similarly
328 ////////////////////////////////////////////////////////////////////////
333 this->GetModuleId(index,lay,lad,det);
335 gl = &(fg[lay][fNdet[lay]*lad+det]);
340 l[0] = gl->fr[0]*x + gl->fr[1]*y + gl->fr[2]*z;
341 l[1] = gl->fr[3]*x + gl->fr[4]*y + gl->fr[5]*z;
342 l[2] = gl->fr[6]*x + gl->fr[7]*y + gl->fr[8]*z;
346 //________________________________________________________________________
347 void AliITSgeom::LtoG(Int_t lay,Int_t lad,Int_t det,
348 const Float_t *l,Float_t *g){
349 ////////////////////////////////////////////////////////////////////////
350 // The function that does the local active volume detector Cartesian
351 // coordinate to global ALICE Cartesian coordinate transformation.
352 // The local detector coordinate system is determined by the layer,
353 // ladder, and detector numbers. The local coordinates are entered by
354 // the three element Float_t array l and the global coordinate values
355 // are returned by the three element Float_t array g. The order of the
356 // three elements are l[0]=x, l[1]=y, and l[2]=z, similarly for g.
357 ////////////////////////////////////////////////////////////////////////
362 gl = &(fg[lay][fNdet[lay]*lad+det]);
364 x = gl->fr[0]*l[0] + gl->fr[3]*l[1] + gl->fr[6]*l[2];
365 y = gl->fr[1]*l[0] + gl->fr[4]*l[1] + gl->fr[7]*l[2];
366 z = gl->fr[2]*l[0] + gl->fr[5]*l[1] + gl->fr[8]*l[2];
373 //________________________________________________________________________
374 void AliITSgeom::LtoG(const Int_t *id,const Float_t *l,Float_t *g){
375 ////////////////////////////////////////////////////////////////////////
376 // The function that does the local active volume detector Cartesian
377 // coordinate to global ALICE Cartesian coordinate transformation.
378 // The local detector coordinate system is determined by the three
379 // element array Id containing as it's three elements Id[0]=layer,
380 // Id[1]=ladder, and Id[2]=detector numbers. The local coordinates
381 // are entered by the three element Float_t array l and the global
382 // coordinate values are returned by the three element Float_t array g.
383 // The order of the three elements are l[0]=x, l[1]=y, and l[2]=z,
385 ////////////////////////////////////////////////////////////////////////
390 lay = id[0]; lad = id[1]; det = id[2];
392 gl = &(fg[lay][fNdet[lay]*lad+det]);
394 x = gl->fr[0]*l[0] + gl->fr[3]*l[1] + gl->fr[6]*l[2];
395 y = gl->fr[1]*l[0] + gl->fr[4]*l[1] + gl->fr[7]*l[2];
396 z = gl->fr[2]*l[0] + gl->fr[5]*l[1] + gl->fr[8]*l[2];
402 //________________________________________________________________________
403 void AliITSgeom::LtoG(const Int_t index,const Float_t *l,Float_t *g){
404 ////////////////////////////////////////////////////////////////////////
405 // The function that does the local active volume detector Cartesian
406 // coordinate to global ALICE Cartesian coordinate transformation.
407 // The local detector coordinate system is determined by the detector
408 // index number (see GetModuleIndex and GetModuleId). The local coordinates
409 // are entered by the three element Float_t array l and the global
410 // coordinate values are returned by the three element Float_t array g.
411 // The order of the three elements are l[0]=x, l[1]=y, and l[2]=z,
413 ////////////////////////////////////////////////////////////////////////
418 this->GetModuleId(index,lay,lad,det);
420 gl = &(fg[lay][fNdet[lay]*lad+det]);
422 x = gl->fr[0]*l[0] + gl->fr[3]*l[1] + gl->fr[6]*l[2];
423 y = gl->fr[1]*l[0] + gl->fr[4]*l[1] + gl->fr[7]*l[2];
424 z = gl->fr[2]*l[0] + gl->fr[5]*l[1] + gl->fr[8]*l[2];
430 //________________________________________________________________________
431 void AliITSgeom::GtoLMomentum(Int_t lay,Int_t lad,Int_t det,
432 const Float_t *g,Float_t *l){
433 ////////////////////////////////////////////////////////////////////////
434 // The function that does the global ALICE Cartesian momentum
435 // to local active volume detector Cartesian momentum transformation.
436 // The local detector coordinate system is determined by the layer,
437 // ladder, and detector numbers. The global momentums are entered by
438 // the three element Float_t array g and the local momentums values
439 // are returned by the three element Float_t array l. The order of the
440 // three elements are g[0]=x, g[1]=y, and g[2]=z, similarly for l.
441 ////////////////////////////////////////////////////////////////////////
446 gl = &(fg[lay][fNdet[lay]*lad+det]);
451 l[0] = gl->fr[0]*px + gl->fr[1]*py + gl->fr[2]*pz;
452 l[1] = gl->fr[3]*px + gl->fr[4]*py + gl->fr[5]*pz;
453 l[2] = gl->fr[6]*px + gl->fr[7]*py + gl->fr[8]*pz;
456 //________________________________________________________________________
457 void AliITSgeom::LtoGMomentum(Int_t lay,Int_t lad,Int_t det,
458 const Float_t *l,Float_t *g){
459 ////////////////////////////////////////////////////////////////////////
460 // The function that does the local active volume detector Cartesian
461 // momentum to global ALICE Cartesian momentum transformation.
462 // The local detector momentum system is determined by the layer,
463 // ladder, and detector numbers. The locall momentums are entered by
464 // the three element Float_t array l and the global momentum values
465 // are returned by the three element Float_t array g. The order of the
466 // three elements are l[0]=x, l[1]=y, and l[2]=z, similarly for g.
467 ////////////////////////////////////////////////////////////////////////
472 gl = &(fg[lay][fNdet[lay]*lad+det]);
474 px = gl->fr[0]*l[0] + gl->fr[3]*l[1] + gl->fr[6]*l[2];
475 py = gl->fr[1]*l[0] + gl->fr[4]*l[1] + gl->fr[7]*l[2];
476 pz = gl->fr[2]*l[0] + gl->fr[5]*l[1] + gl->fr[8]*l[2];
482 //___________________________________________________________________________
483 Int_t AliITSgeom::GetModuleIndex(Int_t lay,Int_t lad,Int_t det){
486 i = fNdet[lay-1] * (lad-1) + det - 1;
488 for(k=0;k<lay-1;k++) j += fNdet[k]*fNlad[k];
491 //___________________________________________________________________________
492 void AliITSgeom::GetModuleId(Int_t index,Int_t &lay,Int_t &lad,Int_t &det){
496 for(k=0;k<fNlayers;k++){
497 j += fNdet[k]*fNlad[k];
501 i = index -j + fNdet[k]*fNlad[k];
503 for(k=0;k<fNlad[lay-1];k++){
508 det = 1+i-fNdet[lay-1]*k;
511 //___________________________________________________________________________
512 void AliITSgeom::GlobalChange(Float_t *tran,Float_t *rot){
513 ////////////////////////////////////////////////////////////////////////
514 // This function performs a Cartesian translation and rotation of
515 // the full ITS from its default position by an amount determined by
516 // the three element arrays dtranslation and drotation. If every element
517 // of dtranslation and drotation are zero then there is no change made
518 // the geometry. The change is global in that the exact same translation
519 // and rotation is done to every detector element in the exact same way.
520 // The units of the translation are those of the Monte Carlo, usually cm,
521 // and those of the rotation are in radians. The elements of dtranslation
522 // are dtranslation[0] = x, dtranslation[1] = y, and dtranslation[2] = z.
523 // The elements of drotation are drotation[0] = rx, drotation[1] = ry, and
524 // drotation[2] = rz. A change in x will move the hole ITS in the ALICE
525 // global x direction, the same for a change in y. A change in z will
526 // result in a translation of the ITS as a hole up or down the beam line.
527 // A change in the angles will result in the inclination of the ITS with
528 // respect to the beam line, except for an effective rotation about the
529 // beam axis which will just rotate the ITS as a hole about the beam axis.
530 ////////////////////////////////////////////////////////////////////////
533 Double_t sx,cx,sy,cy,sz,cz;
536 for(i=0;i<fNlayers;i++){
537 for(j=0;j<fNlad[i];j++) for(k=0;k<fNdet[i];k++){
538 l = fNdet[i]*j+k; // resolved index
546 rx = gl->frx; ry = gl->fry; rz = gl->frz;
547 sx = sin(rx); cx = cos(rx);
548 sy = sin(ry); cy = cos(ry);
549 sz = sin(rz); cz = cos(rz);
551 gl->fr[1] = -cz*sy*sx - sz*cx;
552 gl->fr[2] = -cz*sy*cx + sz*sx;
554 gl->fr[4] = -sz*sy*sx + cz*cx;
555 gl->fr[5] = -sz*sy*cx - cz*sx;
564 //___________________________________________________________________________
565 void AliITSgeom::GlobalCylindericalChange(Float_t *tran,Float_t *rot){
566 ////////////////////////////////////////////////////////////////////////
567 // This function performs a cylindrical translation and rotation of
568 // each ITS element by a fixed about in radius, rphi, and z from its
569 // default position by an amount determined by the three element arrays
570 // dtranslation and drotation. If every element of dtranslation and
571 // drotation are zero then there is no change made the geometry. The
572 // change is global in that the exact same distance change in translation
573 // and rotation is done to every detector element in the exact same way.
574 // The units of the translation are those of the Monte Carlo, usually cm,
575 // and those of the rotation are in radians. The elements of dtranslation
576 // are dtranslation[0] = r, dtranslation[1] = rphi, and dtranslation[2] = z.
577 // The elements of drotation are drotation[0] = rx, drotation[1] = ry, and
578 // drotation[2] = rz. A change in r will results in the increase of the
579 // radius of each layer by the same about. A change in rphi will results in
580 // the rotation of each layer by a different angle but by the same
581 // circumferential distance. A change in z will result in a translation
582 // of the ITS as a hole up or down the beam line. A change in the angles
583 // will result in the inclination of the ITS with respect to the beam
584 // line, except for an effective rotation about the beam axis which will
585 // just rotate the ITS as a hole about the beam axis.
586 ////////////////////////////////////////////////////////////////////////
588 Double_t rx,ry,rz,r,phi,rphi; // phi in radians
589 Double_t sx,cx,sy,cy,sz,cz,r0;
592 // printf("trans=%f %f %f rot=%f %f %f\n",tran[0],tran[1],tran[2],
593 // rot[0],rot[1],rot[2]);
594 for(i=0;i<fNlayers;i++){
595 for(j=0;j<fNlad[i];j++) for(k=0;k<fNdet[i];k++){
596 l = fNdet[i]*j+k; // resolved index
598 r = r0= TMath::Hypot(gl->fy0,gl->fx0);
599 phi = atan2(gl->fy0,gl->fx0);
604 gl->fx0 = r*TMath::Cos(phi);
605 gl->fy0 = r*TMath::Sin(phi);
610 rx = gl->frx; ry = gl->fry; rz = gl->frz;
611 sx = sin(rx); cx = cos(rx);
612 sy = sin(ry); cy = cos(ry);
613 sz = sin(rz); cz = cos(rz);
615 gl->fr[1] = -cz*sy*sx - sz*cx;
616 gl->fr[2] = -cz*sy*cx + sz*sx;
618 gl->fr[4] = -sz*sy*sx + cz*cx;
619 gl->fr[5] = -sz*sy*cx - cz*sx;
628 //___________________________________________________________________________
629 void AliITSgeom::RandomChange(Float_t *stran,Float_t *srot){
630 ////////////////////////////////////////////////////////////////////////
631 // This function performs a Gaussian random displacement and/or
632 // rotation about the present global position of each active
633 // volume/detector of the ITS. The sigma of the random displacement
634 // is determined by the three element array stranslation, for the
635 // x y and z translations, and the three element array srotation,
636 // for the three rotation about the axis x y and z.
637 ////////////////////////////////////////////////////////////////////////
640 Double_t sx,cx,sy,cy,sz,cz;
644 for(i=0;i<fNlayers;i++){
645 for(j=0;j<fNlad[i];j++) for(k=0;k<fNdet[i];k++){
646 l = fNdet[i]*j+k; // resolved index
648 gl->fx0 += ran.Gaus(0.0,stran[0]);
649 gl->fy0 += ran.Gaus(0.0,stran[1]);
650 gl->fz0 += ran.Gaus(0.0,stran[2]);
651 gl->frx += ran.Gaus(0.0, srot[0]);
652 gl->fry += ran.Gaus(0.0, srot[1]);
653 gl->frz += ran.Gaus(0.0, srot[2]);
654 rx = gl->frx; ry = gl->fry; rz = gl->frz;
655 sx = sin(rx); cx = cos(rx);
656 sy = sin(ry); cy = cos(ry);
657 sz = sin(rz); cz = cos(rz);
659 gl->fr[1] = -cz*sy*sx - sz*cx;
660 gl->fr[2] = -cz*sy*cx + sz*sx;
662 gl->fr[4] = -sz*sy*sx + cz*cx;
663 gl->fr[5] = -sz*sy*cx - cz*sx;
672 //___________________________________________________________________________
673 void AliITSgeom::RandomCylindericalChange(Float_t *stran,Float_t *srot){
674 ////////////////////////////////////////////////////////////////////////
675 // This function performs a Gaussian random displacement and/or
676 // rotation about the present global position of each active
677 // volume/detector of the ITS. The sigma of the random displacement
678 // is determined by the three element array stranslation, for the
679 // r rphi and z translations, and the three element array srotation,
680 // for the three rotation about the axis x y and z. This random change
681 // in detector position allow for the simulation of a random uncertainty
682 // in the detector positions of the ITS.
683 ////////////////////////////////////////////////////////////////////////
685 Double_t rx,ry,rz,r,phi,x,y; // phi in radians
686 Double_t sx,cx,sy,cy,sz,cz,r0;
690 // printf("trans=%f %f %f rot=%f %f %f\n",stran[0],stran[1],stran[2],
691 // srot[0],srot[1],srot[2]);
692 for(i=0;i<fNlayers;i++){
693 for(j=0;j<fNlad[i];j++) for(k=0;k<fNdet[i];k++){
694 l = fNdet[i]*j+k; // resolved index
698 r = r0= TMath::Hypot(y,x);
699 phi = TMath::ATan2(y,x);
700 // if(phi<0.0) phi += 2.0*TMath::Pi();
701 r += ran.Gaus(0.0,stran[0]);
702 phi += ran.Gaus(0.0,stran[1])/r0;
703 // printf("fx0=%f fy0=%f rcos(phi)=%f rsin(phi)=%f\n",gl->fx0,gl->fy0,
704 // r*TMath::Cos(phi),r*TMath::Sin(phi));
705 gl->fx0 = r*TMath::Cos(phi);
706 gl->fy0 = r*TMath::Sin(phi);
707 // printf("r0=%f r=%f hypot=%f phi0=%f phi=%f ATan2=%f\n",
708 // r0,r,TMath::Hypot(gl->fy0,gl->fx0),
709 // phi0,phi,TMath::ATan2(gl->fy0,gl->fx0));
710 gl->fz0 += ran.Gaus(0.0,stran[2]);
711 gl->frx += ran.Gaus(0.0, srot[0]);
712 gl->fry += ran.Gaus(0.0, srot[1]);
713 gl->frz += ran.Gaus(0.0, srot[2]);
714 rx = gl->frx; ry = gl->fry; rz = gl->frz;
715 sx = sin(rx); cx = cos(rx);
716 sy = sin(ry); cy = cos(ry);
717 sz = sin(rz); cz = cos(rz);
719 gl->fr[1] = -cz*sy*sx - sz*cx;
720 gl->fr[2] = -cz*sy*cx + sz*sx;
722 gl->fr[4] = -sz*sy*sx + cz*cx;
723 gl->fr[5] = -sz*sy*cx - cz*sx;
732 //___________________________________________________________________________
733 void AliITSgeom::SetByAngles(Int_t lay,Int_t lad,Int_t det,
734 Float_t rx,Float_t ry,Float_t rz){
735 ////////////////////////////////////////////////////////////////////////
736 // This function computes a new rotation matrix based on the angles
737 // rx, ry, and rz (in radians) for a give detector on the give ladder
738 // in the give layer. A new
739 // fg[layer-1][(fNlad[layer-1]*(ladder-1)+detector-1)].fr[] array is
741 ////////////////////////////////////////////////////////////////////////
743 Double_t sx,cx,sy,cy,sz,cz;
745 lay--; lad--; det--; // set to zero base now.
746 g = &(fg[lay][fNdet[lay]*lad+det]);
748 sx = sin(rx); cx = cos(rx);
749 sy = sin(ry); cy = cos(ry);
750 sz = sin(rz); cz = cos(rz);
755 g->fr[1] = -cz*sy*sx - sz*cx;
756 g->fr[2] = -cz*sy*cx + sz*sx;
758 g->fr[4] = -sz*sy*sx + cz*cx;
759 g->fr[5] = -sz*sy*cx - cz*sx;
766 //___________________________________________________________________________
767 void AliITSgeom::GetRotMatrix(Int_t lay,Int_t lad,Int_t det,Float_t *mat){
768 ////////////////////////////////////////////////////////////////////////
769 // Returns, in the Float_t array pointed to by mat, the full rotation
770 // matrix for the give detector defined by layer, ladder, and detector.
771 // It returns all nine elements of fr in the ITS_geom structure. See the
772 // description of the ITS_geom structure for further details of this
774 ////////////////////////////////////////////////////////////////////////
778 lay--; lad--; det--; // shift to base 0
779 g = &(fg[lay][fNdet[lay]*lad+det]);
780 for(i=0;i<9;i++) mat[i] = g->fr[i];
784 //___________________________________________________________________________
785 void AliITSgeom::PrintComparison(FILE *fp,AliITSgeom *other){
786 ////////////////////////////////////////////////////////////////////////
787 // This function was primarily created for diagnostic reasons. It
788 // print to a file pointed to by the file pointer fp the difference
789 // between two AliITSgeom classes. The format of the file is basicly,
790 // define d? to be the difference between the same element of the two
791 // classes. For example dfrx = this->fg[i][j].frx - other->fg[i][j].frx.
792 // if(at least one of dfx0, dfy0, dfz0,dfrx,dfry,dfrz are non zero) then print
793 // layer ladder detector dfx0 dfy0 dfz0 dfrx dfry dfrz
794 // if(at least one of the 9 elements of dfr[] are non zero) then print
795 // layer ladder detector dfr[0] dfr[1] dfr[2]
796 // dfr[3] dfr[4] dfr[5]
797 // dfr[6] dfr[7] dfr[8]
798 // Only non zero values are printed to save space. The differences are
799 // typical written to a file because there are usually a lot of numbers
800 // printed out and it is usually easier to read them in some nice editor
801 // rather than zooming quickly past you on a screen. fprintf is used to
802 // do the printing. The fShapeIndex difference is not printed at this time.
803 ////////////////////////////////////////////////////////////////////////
805 Double_t xt,yt,zt,xo,yo,zo;
806 Double_t rxt,ryt,rzt,rxo,ryo,rzo; // phi in radians
810 for(i=0;i<this->fNlayers;i++){
811 for(j=0;j<this->fNlad[i];j++) for(k=0;k<this->fNdet[i];k++){
812 l = this->fNdet[i]*j+k; // resolved index
813 gt = &(this->fg[i][l]);
814 go = &(other->fg[i][l]);
815 xt = gt->fx0; yt = gt->fy0; zt = gt->fz0;
816 xo = go->fx0; yo = go->fy0; zo = go->fz0;
817 rxt = gt->frx; ryt = gt->fry; rzt = gt->frz;
818 rxo = go->frx; ryo = go->fry; rzo = go->frz;
819 if(!(xt==xo&&yt==yo&&zt==zo&&rxt==rxo&&ryt==ryo&&rzt==rzo))
820 fprintf(fp,"%1.1d %2.2d %2.2d dTrans=%f %f %f drot=%f %f %f\n",
821 i+1,j+1,k+1,xt-xo,yt-yo,zt-zo,rxt-rxo,ryt-ryo,rzt-rzo);
823 for(i=0;i<9;i++) t = gt->fr[i] != go->fr[i];
825 fprintf(fp,"%1.1d %2.2d %2.2d dfr= %e %e %e\n",i+1,j+1,k+1,
826 gt->fr[0]-go->fr[0],gt->fr[1]-go->fr[1],gt->fr[2]-go->fr[2]);
827 fprintf(fp," dfr= %e %e %e\n",
828 gt->fr[3]-go->fr[3],gt->fr[4]-go->fr[4],gt->fr[5]-go->fr[5]);
829 fprintf(fp," dfr= %e %e %e\n",
830 gt->fr[6]-go->fr[6],gt->fr[7]-go->fr[7],gt->fr[8]-go->fr[8]);
837 //___________________________________________________________________________
838 void AliITSgeom::PrintData(FILE *fp,Int_t lay,Int_t lad,Int_t det){
839 ////////////////////////////////////////////////////////////////////////
840 // This function prints out the coordinate transformations for
841 // the particular detector defined by layer, ladder, and detector
842 // to the file pointed to by the File pointer fp. fprinf statements
843 // are used to print out the numbers. The format is
844 // layer ladder detector Trans= fx0 fy0 fz0 rot= frx fry frz Shape=fShapeIndex
845 // dfr= fr[0] fr[1] fr[2]
846 // dfr= fr[3] fr[4] fr[5]
847 // dfr= fr[6] fr[7] fr[8]
848 // By indicating which detector, some control over the information
849 // is given to the user. The output it written to the file pointed
850 // to by the file pointer fp. This can be set to stdout if you want.
851 ////////////////////////////////////////////////////////////////////////
858 l = this->fNdet[i]*j+k; // resolved index
859 gt = &(this->fg[i][l]);
860 fprintf(fp,"%1.1d %2.2d %2.2d Trans=%f %f %f rot=%f %f %f Shape=%d\n",
861 i+1,j+1,k+1,gt->fx0,gt->fy0,gt->fz0,gt->frx,gt->fry,gt->frz,
863 fprintf(fp," dfr= %e %e %e\n",gt->fr[0],gt->fr[1],gt->fr[2]);
864 fprintf(fp," dfr= %e %e %e\n",gt->fr[3],gt->fr[4],gt->fr[5]);
865 fprintf(fp," dfr= %e %e %e\n",gt->fr[6],gt->fr[7],gt->fr[8]);
868 //___________________________________________________________________________
869 void AliITSgeom::Streamer(TBuffer &R__b){
870 ////////////////////////////////////////////////////////////////////////
871 // The default Streamer function "written by ROOT" doesn't write out
872 // the arrays referenced by pointers. Therefore, a specific Streamer function
873 // has to be written. This function should not be modified but instead added
874 // on to so that older versions can still be read. The proper handling of
875 // the version dependent streamer function hasn't been written do to the lack
876 // of finding an example at the time of writting.
877 ////////////////////////////////////////////////////////////////////////
878 // Stream an object of class AliITSgeom.
881 if (R__b.IsReading()) {
882 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
883 TObject::Streamer(R__b);
885 if(fNlad!=0) delete[] fNlad;
886 if(fNdet!=0) delete[] fNdet;
887 fNlad = new Int_t[fNlayers];
888 fNdet = new Int_t[fNlayers];
889 for(i=0;i<fNlayers;i++) R__b >> fNlad[i];
890 for(i=0;i<fNlayers;i++) R__b >> fNdet[i];
892 for(i=0;i<fNlayers;i++) delete[] fg[i];
895 fg = new ITS_geom*[fNlayers];
896 for(i=0;i<fNlayers;i++){
897 fg[i] = new ITS_geom[fNlad[i]*fNdet[i]];
898 for(j=0;j<fNlad[i]*fNdet[i];j++){
899 R__b >> fg[i][j].fShapeIndex;
900 R__b >> fg[i][j].fx0;
901 R__b >> fg[i][j].fy0;
902 R__b >> fg[i][j].fz0;
903 R__b >> fg[i][j].frx;
904 R__b >> fg[i][j].fry;
905 R__b >> fg[i][j].frz;
906 for(k=0;k<9;k++) R__b >> fg[i][j].fr[k];
911 R__b.WriteVersion(AliITSgeom::IsA());
912 TObject::Streamer(R__b);
914 for(i=0;i<fNlayers;i++) R__b << fNlad[i];
915 for(i=0;i<fNlayers;i++) R__b << fNdet[i];
916 for(i=0;i<fNlayers;i++) for(j=0;j<fNlad[i]*fNdet[i];j++){
917 R__b << fg[i][j].fShapeIndex;
918 R__b << fg[i][j].fx0;
919 R__b << fg[i][j].fy0;
920 R__b << fg[i][j].fz0;
921 R__b << fg[i][j].frx;
922 R__b << fg[i][j].fry;
923 R__b << fg[i][j].frz;
924 for(k=0;k<9;k++) R__b << fg[i][j].fr[k];
930 //___________________________________________________________________________
931 ofstream & AliITSgeom::PrintGeom(ofstream &R__b){
932 ////////////////////////////////////////////////////////////////////////
933 // The default Streamer function "written by ROOT" doesn't write out
934 // the arrays referenced by pointers. Therefore, a specific Streamer function
935 // has to be written. This function should not be modified but instead added
936 // on to so that older versions can still be read. The proper handling of
937 // the version dependent streamer function hasn't been written do to the lack
938 // of finding an example at the time of writting.
939 ////////////////////////////////////////////////////////////////////////
940 // Stream an object of class AliITSgeom.
943 R__b.setf(ios::scientific);
944 R__b << fNlayers << " ";
945 for(i=0;i<fNlayers;i++) R__b << fNlad[i] << " ";
946 for(i=0;i<fNlayers;i++) R__b << fNdet[i] << "\n";
947 for(i=0;i<fNlayers;i++) for(j=0;j<fNlad[i]*fNdet[i];j++){
948 R__b <<setprecision(16) << fg[i][j].fShapeIndex << " ";
949 R__b <<setprecision(16) << fg[i][j].fx0 << " ";
950 R__b <<setprecision(16) << fg[i][j].fy0 << " ";
951 R__b <<setprecision(16) << fg[i][j].fz0 << " ";
952 R__b <<setprecision(16) << fg[i][j].frx << " ";
953 R__b <<setprecision(16) << fg[i][j].fry << " ";
954 R__b <<setprecision(16) << fg[i][j].frz << "\n";
955 for(k=0;k<9;k++) R__b <<setprecision(16) << fg[i][j].fr[k] << " ";
962 //___________________________________________________________________________
963 ifstream & AliITSgeom::ReadGeom(ifstream &R__b){
964 ////////////////////////////////////////////////////////////////////////
965 // The default Streamer function "written by ROOT" doesn't write out
966 // the arrays referenced by pointers. Therefore, a specific Streamer function
967 // has to be written. This function should not be modified but instead added
968 // on to so that older versions can still be read. The proper handling of
969 // the version dependent streamer function hasn't been written do to the lack
970 // of finding an example at the time of writting.
971 ////////////////////////////////////////////////////////////////////////
972 // Stream an object of class AliITSgeom.
976 if(fNlad!=0) delete[] fNlad;
977 if(fNdet!=0) delete[] fNdet;
978 fNlad = new Int_t[fNlayers];
979 fNdet = new Int_t[fNlayers];
980 for(i=0;i<fNlayers;i++) R__b >> fNlad[i];
981 for(i=0;i<fNlayers;i++) R__b >> fNdet[i];
983 for(i=0;i<fNlayers;i++) delete[] fg[i];
986 fg = new ITS_geom*[fNlayers];
987 for(i=0;i<fNlayers;i++){
988 fg[i] = new ITS_geom[fNlad[i]*fNdet[i]];
989 for(j=0;j<fNlad[i]*fNdet[i];j++){
990 R__b >> fg[i][j].fShapeIndex;
991 R__b >> fg[i][j].fx0;
992 R__b >> fg[i][j].fy0;
993 R__b >> fg[i][j].fz0;
994 R__b >> fg[i][j].frx;
995 R__b >> fg[i][j].fry;
996 R__b >> fg[i][j].frz;
997 for(k=0;k<9;k++) R__b >> fg[i][j].fr[k];