1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 Revision 1.4.4.6 2000/06/04 16:33:32 Nilsen
19 A restructured AliITSgeom class. Now used AliITSgeomMatrix.
21 Revision 1.4.4.5 2000/03/04 23:42:39 Nilsen
22 Updated the comments/documentations and improved the maintainability of the
25 Revision 1.4.4.4 2000/03/02 21:27:07 Nilsen
26 Added two functions, SetByAngles and SetTrans.
28 Revision 1.4.4.3 2000/01/23 03:09:10 Nilsen
29 // fixed compiler warnings for new function LtLErrorMatrix(...)
31 Revision 1.4.4.2 2000/01/19 23:18:20 Nilsen
32 Added transformations of Error matrix to AliITSgeom and fixed some typos
33 in AliITS.h and AliITShitIndex.h
35 Revision 1.4.4.1 2000/01/12 19:03:32 Nilsen
36 This is the version of the files after the merging done in December 1999.
37 See the ReadMe110100.txt file for details
39 Revision 1.4 1999/10/15 07:03:20 fca
40 Fixed bug in GetModuleId(Int_t index,Int_t &lay,Int_t &lad, Int_t &det) and
41 a typo in the creator. aliroot need to be rerun to get a fixed geometry.
43 Revision 1.3 1999/10/04 15:20:12 fca
44 Correct syntax accepted by g++ but not standard for static members, remove minor warnings
46 Revision 1.2 1999/09/29 09:24:20 fca
47 Introduction of the Copyright and cvs Log
51 ///////////////////////////////////////////////////////////////////////
52 // ITS geometry manipulation routines. //
53 // Created April 15 1999. //
55 // By: Bjorn S. Nilsen //
57 // Updated May 27 1999. //
58 // Added Cylindrical random and global based changes. //
59 // Added function PrintComparison. //
60 ///////////////////////////////////////////////////////////////////////
63 ////////////////////////////////////////////////////////////////////////
64 // The local coordinate system by, default, is show in the following
65 // figures. Also shown are the ladder numbering scheme.
68 <img src="picts/ITS/AliITSgeomMatrix_L1.gif">
71 <font size=+2 color=blue>
72 <p>This shows the relative geometry differences between the ALICE Global
73 coordinate system and the local detector coordinate system.
78 <img src="picts/ITS/its1+2_convention_front_5.gif">
81 <font size=+2 color=blue>
82 <p>This shows the front view of the SPDs and the orientation of the local
83 pixel coordinate system. Note that the inner pixel layer has its y coordinate
84 in the opposite direction from all of the other layers.
89 <img src="picts/ITS/its3+4_convention_front_5.gif">
92 <font size=+2 color=blue>
93 <p>This shows the front view of the SDDs and the orientation of the local
94 pixel coordinate system.
99 <img src="picts/ITS/its5+6_convention_front_5.gif">
102 <font size=+2 color=blue>
103 <p>This shows the front view of the SSDs and the orientation of the local
104 pixel coordinate system.
110 ////////////////////////////////////////////////////////////////////////
112 ////////////////////////////////////////////////////////////////////////
115 // Written by Bjorn S. Nilsen
120 // The number of ITS layers for this geometry. By default this
121 // is 6, but can be modified by the creator function if there are
122 // more layers defined.
125 // A pointer to an array fNlayers long containing the number of
126 // ladders for each layer. This array is typically created and filled
127 // by the AliITSgeom creator function.
130 // A pointer to an array fNlayers long containing the number of
131 // active detector volumes for each ladder. This array is typically
132 // created and filled by the AliITSgeom creator function.
134 // AliITSgeomMatrix *fGm
135 // A pointer to an array of AliITSgeomMatrix classes. One element
136 // per module (detector) in the ITS. AliITSgeomMatrix basicly contains
137 // all of the necessary information about the detector and it's coordinate
141 // A pointer to an array of TObjects containing the detailed shape
142 // information for each type of detector used in the ITS. For example
143 // I have created AliITSgeomSPD, AliITSgeomSDD, and AliITSgeomSSD as
144 // example structures, derived from TObjects, to hold the detector
145 // information. I would recommend that one element in each of these
146 // structures, that which describes the shape of the active volume,
147 // be one of the ROOT classes derived from TShape. In this way it would
148 // be easy to have the display program display the correct active
149 // ITS volumes. See the example classes AliITSgeomSPD, AliITSgeomSDD,
150 // and AliITSgeomSSD for a more detailed example.
151 ////////////////////////////////////////////////////////////////////////
152 #include <iostream.h>
161 #include "AliITSgeom.h"
162 #include "AliITSgeomMatrix.h"
163 #include "AliITSgeomSPD.h"
164 #include "AliITSgeomSDD.h"
165 #include "AliITSgeomSSD.h"
169 //_____________________________________________________________________
170 AliITSgeom::AliITSgeom(){
171 ////////////////////////////////////////////////////////////////////////
172 // The default constructor for the AliITSgeom class. It, by default,
173 // sets fNlayers to zero and zeros all pointers.
174 ////////////////////////////////////////////////////////////////////////
175 // Default constructor.
176 // Do not allocate anything zero everything
177 fTrans = 0; // standard GEANT global/local coordinate system.
186 //_____________________________________________________________________
187 AliITSgeom::~AliITSgeom(){
188 ////////////////////////////////////////////////////////////////////////
189 // The destructor for the AliITSgeom class. If the arrays fNlad,
190 // fNdet, or fGm have had memory allocated to them, there pointer values
191 // are non zero, then this memory space is freed and they are set
192 // to zero. In addition, fNlayers is set to zero. The destruction of
193 // TObjArray fShape is, by default, handled by the TObjArray destructor.
194 ////////////////////////////////////////////////////////////////////////
195 // Default destructor.
196 // if arrays exist delete them. Then set everything to zero.
198 for(Int_t i=0;i<fNlayers;i++) delete fGm[i];
201 if(fNlad!=0) delete[] fNlad;
202 if(fNdet!=0) delete[] fNdet;
209 //______________________________________________________________________
210 void AliITSgeom::ReadNewFile(const char *filename){
211 printf("New file format not defined yet\n");
214 //_____________________________________________________________________
215 AliITSgeom::AliITSgeom(const char *filename){
216 ////////////////////////////////////////////////////////////////////////
217 // The constructor for the AliITSgeom class. All of the data to fill
218 // this structure is read in from the file given my the input filename.
219 ////////////////////////////////////////////////////////////////////////
223 Float_t x,y,z,o,p,q,r,s,t;
224 Double_t rot6[6],tran[3];
225 char buf[200],*buff=0; // input character buffer;
227 pf = fopen(filename,"r");
229 fNlayers = 6; // set default number of ladders
231 fNlad = new Int_t[fNlayers];
232 fNdet = new Int_t[fNlayers];
234 // find the number of ladders and detectors in this geometry.
235 for(i=0;i<fNlayers;i++){fNlad[i]=fNdet[i]=0;} // zero out arrays
236 while(fgets(buf,200,pf)!=NULL){ // for ever loop
237 for(i=0;i<200;i++)if(buf[i]!=' '){ // remove blank spaces.
241 // remove blank lines and comments.
242 if(buff[0]=='\n'||buff[0]=='#'||buff[0]=='!'||
243 (buff[0]=='/'&&buff[1]=='/')) continue;
244 if(isalpha(buff[0])) { // must be the new file formated file.
246 delete[] fNlad;delete[] fNdet;
247 ReadNewFile(filename);
249 } // end if isalpha(buff[0])
250 sscanf(buff,"%d %d %d %f %f %f %f %f %f %f %f %f",
251 &l,&a,&d,&x,&y,&z,&o,&p,&q,&r,&s,&t);
253 if(l<1 || l>fNlayers) {
254 printf("error in file %s layer=%d min. is 1 max is %d/n",
255 filename,l,fNlayers);
259 if(l<=fNlayers&&fNlad[l-1]<a) fNlad[l-1] = a;
260 if(l<=fNlayers&&fNdet[l-1]<d) fNdet[l-1] = d;
261 } // end while ever loop
267 } // end if lm>fNlayers
268 // counted the number of ladders and detectors now allocate space.
269 fGm = new AliITSgeomMatrix*[fNmodules];
271 // Set up Shapes for a default configuration of 6 layers.
272 fTrans = 0; // standard GEANT global/local coordinate system.
273 fShape = new TObjArray(3);
274 AddShape((TObject *) new AliITSgeomSPD()); // shape 0
275 AddShape((TObject *) new AliITSgeomSDD()); // shape 1
276 AddShape((TObject *) new AliITSgeomSPD()); // shape 2
278 // prepare to read in transforms
279 lm = 0; // reuse lm as counter of modules.
280 rewind(pf); // start over reading file
281 while(fgets(buf,200,pf)!=NULL){ // for ever loop
282 for(i=0;i<200;i++)if(buf[i]!=' '){ // remove blank spaces.
286 // remove blank lines and comments.
287 if(buff[0]=='\n'||buff[0]=='#'||buff[0]=='!'||
288 (buff[0]=='/'&&buff[1]=='/')) continue;
289 x = y = z = o = p = q = r = s = t = 0.0;
290 sscanf(buff,"%d %d %d %f %f %f %f %f %f %f %f %f",
291 &l,&a,&d,&x,&y,&z,&o,&p,&q,&r,&s,&t);
292 if(l<1 || l>fNlayers) {
293 printf("error in file %s layer=%d min. is 1 max is %d/n",
294 filename,l,fNlayers);
297 id[0] = l;id[1] = a;id[2] = d;
298 tran[0] = tran[1] = tran[2] = 0.0;
299 tran[0] = (Double_t)x;tran[1] = (Double_t)y;tran[2] = (Double_t)z;
300 rot6[0] = rot6[1] = rot6[2] = rot6[3] = rot6[4] = rot6[5] =0.0;
301 rot6[0] = (Double_t)o;rot6[1] = (Double_t)p;rot6[2] = (Double_t)q;
302 rot6[3] = (Double_t)r;rot6[4] = (Double_t)s;rot6[5] = (Double_t)t;
304 case 1: case 2: // layer 1 or2 SPD
305 fGm[lm++] = new AliITSgeomMatrix(rot6,0,id,tran);
307 case 3: case 4: // layer 3 or 4 SDD
308 fGm[lm++] = new AliITSgeomMatrix(rot6,1,id,tran);
310 case 5: case 6: // layer 5 or 6 SSD
311 fGm[lm++] = new AliITSgeomMatrix(rot6,2,id,tran);
314 } // end while ever loop
318 //________________________________________________________________________
319 AliITSgeom::AliITSgeom(AliITSgeom &source){
320 ////////////////////////////////////////////////////////////////////////
321 // The copy constructor for the AliITSgeom class. It calls the
322 // = operator function. See the = operator function for more details.
323 ////////////////////////////////////////////////////////////////////////
325 *this = source; // Just use the = operator for now.
330 //________________________________________________________________________
331 void AliITSgeom::operator=(AliITSgeom &source){
332 ////////////////////////////////////////////////////////////////////////
333 // The = operator function for the AliITSgeom class. It makes an
334 // independent copy of the class in such a way that any changes made
335 // to the copied class will not affect the source class in any way.
336 // This is required for many ITS alignment studies where the copied
337 // class is then modified by introducing some misalignment.
338 ////////////////////////////////////////////////////////////////////////
341 if(this == &source) return; // don't assign to ones self.
343 // if there is an old structure allocated delete it first.
345 for(i=0;i<this->fNmodules;i++) delete this->fGm[i];
348 if(fNlad != 0) delete[] fNlad;
349 if(fNdet != 0) delete[] fNdet;
351 this->fTrans = source.fTrans;
352 this->fNmodules = source.fNmodules;
353 this->fNlayers = source.fNlayers;
354 this->fNlad = new Int_t[fNlayers];
355 for(i=0;i<this->fNlayers;i++) this->fNlad[i] = source.fNlad[i];
356 this->fNdet = new Int_t[fNlayers];
357 for(i=0;i<this->fNlayers;i++) this->fNdet[i] = source.fNdet[i];
358 this->fShape = new TObjArray(*(source.fShape));//This does not make a proper copy.
359 this->fGm = new AliITSgeomMatrix*[this->fNmodules];
360 for(i=0;i<this->fNmodules;i++){
361 this->fGm[i] = new AliITSgeomMatrix(*(source.fGm[i]));
364 }//_____________________________________________________________________
365 Int_t AliITSgeom::GetModuleIndex(const Int_t lay,const Int_t lad,
367 ////////////////////////////////////////////////////////////////////////
368 // This routine computes the module index number from the layer,
369 // ladder, and detector numbers. The number of ladders and detectors
370 // per layer is determined when this geometry package is constructed,
371 // see AliITSgeom(const char *filename) for specifics.
372 ////////////////////////////////////////////////////////////////////////
375 i = fNdet[lay-1] * (lad-1) + det - 1;
377 for(k=0;k<lay-1;k++) j += fNdet[k]*fNlad[k];
379 fGm[i]->GetIndex(id);
380 if(id[0]==lay&&id[1]==lad&&id[2]==det) return i;
381 // Array of modules fGm is not in expected order. Search for this index
382 for(i=0;i<fNmodules;i++){
383 fGm[i]->GetIndex(id);
384 if(id[0]==lay&&id[1]==lad&&id[2]==det) return i;
386 // This layer ladder and detector combination does not exist return -1.
389 //______________________________________________________________________
390 void AliITSgeom::GetModuleId(const Int_t index,
391 Int_t &lay,Int_t &lad,Int_t &det){
392 ////////////////////////////////////////////////////////////////////////
393 // This routine computes the layer, ladder and detector number
394 // given the module index number. The number of ladders and detectors
395 // per layer is determined when this geometry package is constructed,
396 // see AliITSgeom(const char *filename) for specifics.
397 ////////////////////////////////////////////////////////////////////////
400 fGm[index]->GetIndex(id);
401 lay = id[0]; lad = id[1]; det = id[2];
404 // The old way kept for posterity.
408 for(k=0;k<fNlayers;k++){
409 j += fNdet[k]*fNlad[k];
413 i = index -j + fNdet[k]*fNlad[k];
415 for(k=0;k<fNlad[lay-1];k++){
420 det = 1+i-fNdet[lay-1]*k;
424 //___________________________________________________________________________
425 Int_t AliITSgeom::GetStartDet(const Int_t dtype){
426 /////////////////////////////////////////////////////////////////////////
427 // returns the starting module index value for a give type of detector id
428 /////////////////////////////////////////////////////////////////////////
432 return GetModuleIndex(1,1,1);
435 return GetModuleIndex(3,1,1);
438 return GetModuleIndex(5,1,1);
441 printf("<AliITSgeom::GetFirstDet> undefined detector type\n");
445 printf("<AliITSgeom::GetFirstDet> undefined detector type\n");
449 //___________________________________________________________________________
450 Int_t AliITSgeom::GetLastDet(const Int_t dtype){
451 /////////////////////////////////////////////////////////////////////////
452 // returns the last module index value for a give type of detector id
453 /////////////////////////////////////////////////////////////////////////
466 printf("<AliITSgeom::GetLastDet> undefined detector type\n");
470 printf("<AliITSgeom::GetLastDet> undefined detector type\n");
474 //___________________________________________________________________________
475 void AliITSgeom::PrintComparison(FILE *fp,AliITSgeom *other){
476 ////////////////////////////////////////////////////////////////////////
477 // This function was primarily created for diagnostic reasons. It
478 // print to a file pointed to by the file pointer fp the difference
479 // between two AliITSgeom classes. The format of the file is basicly,
480 // define d? to be the difference between the same element of the two
481 // classes. For example dfrx = this->fGm[i][j].frx - other->fGm[i][j].frx.
482 // if(at least one of dfx0, dfy0, dfz0,dfrx,dfry,dfrz are non zero) then print
483 // layer ladder detector dfx0 dfy0 dfz0 dfrx dfry dfrz
484 // if(at least one of the 9 elements of dfr[] are non zero) then print
485 // layer ladder detector dfr[0] dfr[1] dfr[2]
486 // dfr[3] dfr[4] dfr[5]
487 // dfr[6] dfr[7] dfr[8]
488 // Only non zero values are printed to save space. The differences are
489 // typical written to a file because there are usually a lot of numbers
490 // printed out and it is usually easier to read them in some nice editor
491 // rather than zooming quickly past you on a screen. fprintf is used to
492 // do the printing. The fShapeIndex difference is not printed at this time.
493 ////////////////////////////////////////////////////////////////////////
494 Int_t i,j,idt[3],ido[3];
495 Double_t tt[3],to[3]; // translation
496 Double_t rt[3],ro[3]; // phi in radians
497 Double_t mt[3][3],mo[3][3]; // matrixes
498 AliITSgeomMatrix *gt,*go;
501 for(i=0;i<this->fNmodules;i++){
502 gt = this->GetGeomMatrix(i);
503 go = other->GetGeomMatrix(i);
507 for(i=0;i<3;i++) t = t&&idt[i]!=ido[i];
508 if(t) fprintf(fp,"%4.4d %1.1d %2.2d %2.2d %1.1d %2.2d %2.2d\n",i,
509 idt[0],idt[1],idt[2],ido[0],ido[1],ido[2]);
510 gt->GetTranslation(tt);
511 go->GetTranslation(to);
515 for(i=0;i<3;i++) t = t&&tt[i]!=to[i];
516 if(t) fprintf(fp,"%1.1d %2.2d %2.2d dTrans=%f %f %f drot=%f %f %f\n",
517 idt[0],idt[1],idt[2],
518 tt[0]-to[0],tt[1]-to[1],tt[2]-to[2],
519 rt[0]-ro[0],rt[1]-ro[1],rt[2]-ro[2]);
523 for(i=0;i<3;i++)for(j=0;j<3;j++) t = mt[i][j] != mo[i][j];
525 fprintf(fp,"%1.1d %2.2d %2.2d dfr= %e %e %e\n",
526 idt[0],idt[1],idt[2],
527 mt[0][0]-mo[0][0],mt[0][1]-mo[0][1],mt[0][2]-mo[0][2]);
528 fprintf(fp," dfr= %e %e %e\n",
529 mt[1][0]-mo[1][0],mt[1][1]-mo[1][1],mt[1][2]-mo[1][2]);
530 fprintf(fp," dfr= %e %e %e\n",
531 mt[2][0]-mo[2][0],mt[2][1]-mo[2][1],mt[2][2]-mo[2][2]);
537 //___________________________________________________________________________
538 void AliITSgeom::PrintData(FILE *fp,
539 const Int_t lay,const Int_t lad,const Int_t det){
540 ////////////////////////////////////////////////////////////////////////
541 // This function prints out the coordinate transformations for
542 // the particular detector defined by layer, ladder, and detector
543 // to the file pointed to by the File pointer fp. fprintf statements
544 // are used to print out the numbers. The format is
545 // layer ladder detector Trans= fx0 fy0 fz0 rot= frx fry frz Shape=fShapeIndex
546 // dfr= fr[0] fr[1] fr[2]
547 // dfr= fr[3] fr[4] fr[5]
548 // dfr= fr[6] fr[7] fr[8]
549 // By indicating which detector, some control over the information
550 // is given to the user. The output it written to the file pointed
551 // to by the file pointer fp. This can be set to stdout if you want.
552 ////////////////////////////////////////////////////////////////////////
553 AliITSgeomMatrix *gt;
554 Double_t t[3],r[3],m[3][3];
556 gt = this->GetGeomMatrix(GetModuleIndex(lay,lad,det));
557 gt->GetTranslation(t);
559 fprintf(fp,"%1.1d %2.2d %2.2d Trans=%f %f %f rot=%f %f %f Shape=%d\n",
560 lay,lad,det,t[0],t[1],t[2],r[0],r[1],r[2],
561 gt->GetDetectorIndex());
563 fprintf(fp," dfr= %e %e %e\n",m[0][0],m[0][1],m[0][2]);
564 fprintf(fp," dfr= %e %e %e\n",m[1][0],m[1][1],m[1][2]);
565 fprintf(fp," dfr= %e %e %e\n",m[2][0],m[2][1],m[2][2]);
568 //___________________________________________________________________________
569 ofstream & AliITSgeom::PrintGeom(ofstream &R__b){
570 ////////////////////////////////////////////////////////////////////////
571 // The default Streamer function "written by ROOT" doesn't write out
572 // the arrays referenced by pointers. Therefore, a specific Streamer function
573 // has to be written. This function should not be modified but instead added
574 // on to so that older versions can still be read. The proper handling of
575 // the version dependent streamer function hasn't been written do to the lack
576 // of finding an example at the time of writing.
577 ////////////////////////////////////////////////////////////////////////
578 // Stream an object of class AliITSgeom.
581 R__b.setf(ios::scientific);
582 R__b << fTrans << " ";
583 R__b << fNmodules << " ";
584 R__b << fNlayers << " ";
585 for(i=0;i<fNlayers;i++) R__b << fNlad[i] << " ";
586 for(i=0;i<fNlayers;i++) R__b << fNdet[i] << "\n";
587 for(i=0;i<fNmodules;i++) {
588 R__b <<setprecision(16) << *(fGm[i]) << "\n";
592 //___________________________________________________________________________
593 ifstream & AliITSgeom::ReadGeom(ifstream &R__b){
594 ////////////////////////////////////////////////////////////////////////
595 // The default Streamer function "written by ROOT" doesn't write out
596 // the arrays referenced by pointers. Therefore, a specific Streamer function
597 // has to be written. This function should not be modified but instead added
598 // on to so that older versions can still be read. The proper handling of
599 // the version dependent streamer function hasn't been written do to the lack
600 // of finding an example at the time of writing.
601 ////////////////////////////////////////////////////////////////////////
602 // Stream an object of class AliITSgeom.
605 fNlad = new Int_t[fNlayers];
606 fNdet = new Int_t[fNlayers];
608 for(i=0;i<fNmodules;i++) delete fGm[i];
612 R__b >> fTrans >> fNmodules >> fNlayers;
613 fNlad = new Int_t[fNlayers];
614 fNdet = new Int_t[fNlayers];
615 for(i=0;i<fNlayers;i++) R__b >> fNlad[i];
616 for(i=0;i<fNlayers;i++) R__b >> fNdet[i];
617 fGm = new AliITSgeomMatrix*[fNmodules];
618 for(i=0;i<fNmodules;i++){
619 fGm[i] = new AliITSgeomMatrix;
624 //___________________________________________________________________________
625 void AliITSgeom::Streamer(TBuffer &R__b){
626 ////////////////////////////////////////////////////////////////////////
627 // The default Streamer function "written by ROOT" doesn't write out
628 // the arrays referenced by pointers. Therefore, a specific Streamer function
629 // has to be written. This function should not be modified but instead added
630 // on to so that older versions can still be read. The proper handling of
631 // the version dependent streamer function hasn't been written do to the lack
632 // of finding an example at the time of writing.
633 ////////////////////////////////////////////////////////////////////////
634 // Stream an object of class AliITSgeom.
636 UInt_t R__s=0, R__c=0;
638 if (R__b.IsReading()) {
639 Version_t R__v = R__b.ReadVersion();
641 if(fNlad!=0) delete[] fNlad;
642 if(fNdet!=0) delete[] fNdet;
644 for(i=0;i<fNlayers;i++) delete[] fGm[i];
647 Int_t idt,id[3],inmax;
648 Double_t t[3],r[3],m[9],s[3][3];
649 TObject::Streamer(R__b);
652 fNlad = new Int_t[fNlayers];
653 fNdet = new Int_t[fNlayers];
654 for(i=0;i<fNlayers;i++) R__b >> fNlad[i];
655 for(i=0;i<fNlayers;i++) R__b >> fNdet[i];
656 fNmodules = GetModuleIndex(fNlayers,fNlad[fNlayers-1],
658 fGm = new AliITSgeomMatrix*[fNmodules];
660 for(i=0;i<fNlayers;i++){
661 for(j=0;j<fNlad[i]*fNdet[i];j++){
669 for(k=0;k<9;k++) R__b >> m[k];
670 for(k=0;k<3;k++)for(l=0;l<3;l++) s[k][l] = m[3*k+l];
671 GetModuleId(inmax,id[0],id[1],id[2]);
672 fGm[inmax++] = new AliITSgeomMatrix(idt,id,s,t);
677 if(fNlad!=0) delete[] fNlad;
678 if(fNdet!=0) delete[] fNdet;
679 if(fGm!=0){for(i=0;i<fNmodules;i++) delete fGm[i];delete[] fGm;}
680 TObject::Streamer(R__b);
683 R__b.ReadArray(fNlad);
684 R__b.ReadArray(fNdet);
687 fGm = new AliITSgeomMatrix*[fNmodules];
688 for(i=0;i<fNmodules;i++){
689 fGm[i] = new AliITSgeomMatrix;
690 fGm[i]->Streamer(R__b);
692 //R__b.ReadArray(fGm);
693 R__b.CheckByteCount(R__s, R__c, AliITSgeom::IsA());
696 R__c = R__b.WriteVersion(AliITSgeom::IsA(), kTRUE);
697 TObject::Streamer(R__b);
700 R__b.WriteArray(fNlad, fNlayers);
701 R__b.WriteArray(fNdet, fNlayers);
704 //R__b.WriteArray(fGm, __COUNTER__);
705 for(i=0;i<fNmodules;i++){
706 fGm[i]->Streamer(R__b);
708 R__b.SetByteCount(R__c, kTRUE);
709 } // end if reading/writing.
711 //______________________________________________________________________
712 // The following routines modify the transformation of "this"
713 // geometry transformations in a number of different ways.
714 //______________________________________________________________________
715 void AliITSgeom::GlobalChange(const Float_t *tran,const Float_t *rot){
716 ////////////////////////////////////////////////////////////////////////
717 // This function performs a Cartesian translation and rotation of
718 // the full ITS from its default position by an amount determined by
719 // the three element arrays dtranslation and drotation. If every element
720 // of dtranslation and drotation are zero then there is no change made
721 // the geometry. The change is global in that the exact same translation
722 // and rotation is done to every detector element in the exact same way.
723 // The units of the translation are those of the Monte Carlo, usually cm,
724 // and those of the rotation are in radians. The elements of dtranslation
725 // are dtranslation[0] = x, dtranslation[1] = y, and dtranslation[2] = z.
726 // The elements of drotation are drotation[0] = rx, drotation[1] = ry, and
727 // drotation[2] = rz. A change in x will move the hole ITS in the ALICE
728 // global x direction, the same for a change in y. A change in z will
729 // result in a translation of the ITS as a hole up or down the beam line.
730 // A change in the angles will result in the inclination of the ITS with
731 // respect to the beam line, except for an effective rotation about the
732 // beam axis which will just rotate the ITS as a hole about the beam axis.
733 ////////////////////////////////////////////////////////////////////////
738 fTrans = (fTrans && 0xfffd) + 2; // set bit 1 true.
739 for(i=0;i<fNmodules;i++){
740 g = this->GetGeomMatrix(i);
741 g->GetTranslation(t);
747 g->SetTranslation(t);
752 //___________________________________________________________________________
753 void AliITSgeom::GlobalCylindericalChange(const Float_t *tran,const Float_t *rot){
754 ////////////////////////////////////////////////////////////////////////
755 // This function performs a cylindrical translation and rotation of
756 // each ITS element by a fixed about in radius, rphi, and z from its
757 // default position by an amount determined by the three element arrays
758 // dtranslation and drotation. If every element of dtranslation and
759 // drotation are zero then there is no change made the geometry. The
760 // change is global in that the exact same distance change in translation
761 // and rotation is done to every detector element in the exact same way.
762 // The units of the translation are those of the Monte Carlo, usually cm,
763 // and those of the rotation are in radians. The elements of dtranslation
764 // are dtranslation[0] = r, dtranslation[1] = rphi, and dtranslation[2] = z.
765 // The elements of drotation are drotation[0] = rx, drotation[1] = ry, and
766 // drotation[2] = rz. A change in r will results in the increase of the
767 // radius of each layer by the same about. A change in rphi will results in
768 // the rotation of each layer by a different angle but by the same
769 // circumferential distance. A change in z will result in a translation
770 // of the ITS as a hole up or down the beam line. A change in the angles
771 // will result in the inclination of the ITS with respect to the beam
772 // line, except for an effective rotation about the beam axis which will
773 // just rotate the ITS as a hole about the beam axis.
774 ////////////////////////////////////////////////////////////////////////
776 Double_t t[3],ro[3],r,r0,phi,rphi;
779 fTrans = (fTrans && 0xfffd) + 2; // set bit 1 true.
780 for(i=0;i<fNmodules;i++){
781 g = this->GetGeomMatrix(i);
782 g->GetTranslation(t);
784 r = r0= TMath::Hypot(t[1],t[0]);
785 phi = TMath::ATan2(t[1],t[0]);
790 t[0] = r*TMath::Cos(phi);
791 t[1] = r*TMath::Sin(phi);
796 g->SetTranslation(t);
801 //___________________________________________________________________________
802 void AliITSgeom::RandomChange(const Float_t *stran,const Float_t *srot){
803 ////////////////////////////////////////////////////////////////////////
804 // This function performs a Gaussian random displacement and/or
805 // rotation about the present global position of each active
806 // volume/detector of the ITS. The sigma of the random displacement
807 // is determined by the three element array stran, for the
808 // x y and z translations, and the three element array srot,
809 // for the three rotation about the axis x y and z.
810 ////////////////////////////////////////////////////////////////////////
816 fTrans = (fTrans && 0xfffd) + 2; // set bit 1 true.
817 for(i=0;i<fNmodules;i++){
818 g = this->GetGeomMatrix(i);
819 g->GetTranslation(t);
822 t[j] += ran.Gaus(0.0,stran[j]);
823 r[j] += ran.Gaus(0.0, srot[j]);
825 g->SetTranslation(t);
830 //___________________________________________________________________________
831 void AliITSgeom::RandomCylindericalChange(const Float_t *stran,
832 const Float_t *srot){
833 ////////////////////////////////////////////////////////////////////////
834 // This function performs a Gaussian random displacement and/or
835 // rotation about the present global position of each active
836 // volume/detector of the ITS. The sigma of the random displacement
837 // is determined by the three element array stran, for the
838 // r rphi and z translations, and the three element array srot,
839 // for the three rotation about the axis x y and z. This random change
840 // in detector position allow for the simulation of a random uncertainty
841 // in the detector positions of the ITS.
842 ////////////////////////////////////////////////////////////////////////
844 Double_t t[3],ro[3],r,r0,phi,rphi;
848 fTrans = (fTrans && 0xfffd) + 2; // set bit 1 true.
849 for(i=0;i<fNmodules;i++){
850 g = this->GetGeomMatrix(i);
851 g->GetTranslation(t);
853 r = r0= TMath::Hypot(t[1],t[0]);
854 phi = TMath::ATan2(t[1],t[0]);
856 r += ran.Gaus(0.0,stran[0]);
857 rphi += ran.Gaus(0.0,stran[1]);
859 t[0] = r*TMath::Cos(phi);
860 t[1] = r*TMath::Sin(phi);
861 t[2] += ran.Gaus(0.0,stran[2]);
863 ro[j] += ran.Gaus(0.0, srot[j]);
865 g->SetTranslation(t);
870 //______________________________________________________________________
871 void AliITSgeom::GeantToTracking(AliITSgeom &source){
872 /////////////////////////////////////////////////////////////////////////
873 // Copy the geometry data but change it to go between the ALICE
874 // Global coordinate system to that used by the ITS tracking. A slightly
875 // different coordinate system is used when tracking. This coordinate
876 // system is only relevant when the geometry represents the cylindrical
877 // ALICE ITS geometry. For tracking the Z axis is left alone but X-> -Y
878 // and Y-> X such that X always points out of the ITS cylinder for every
879 // layer including layer 1 (where the detectors are mounted upside down).
882 <img src="picts/ITS/AliITSgeomMatrix_T1.gif">
885 ////////////////////////////////////////////////////////////////////////
887 Double_t R0[3][3],R1[3][3];
888 Double_t A0[3][3] = {{0.,+1.,0.},{-1.,0.,0.},{0.,0.,+1.}};
889 Double_t A1[3][3] = {{0.,-1.,0.},{+1.,0.,0.},{0.,0.,+1.}};
891 *this = source; // copy everything
892 for(i=0;i<GetIndexMax();i++){
893 fGm[i]->GetIndex(id);
894 fGm[i]->GetMatrix(R0);
895 if(id[0]==1){ // Layer 1 is treated different from the others.
896 for(j=0;j<3;j++) for(k=0;k<3;k++){
898 for(l=0;l<3;l++) R1[j][k] += A0[j][l]*R0[l][k];
901 for(j=0;j<3;j++) for(k=0;k<3;k++){
903 for(l=0;l<3;l++) R1[j][k] += A1[j][l]*R0[l][k];
906 fGm[i]->SetMatrix(R1);
908 this->fTrans = (this->fTrans && 0xfffe) + 1; // set bit 0 true.
911 //______________________________________________________________________
912 Int_t AliITSgeom::GetNearest(const Double_t g[3],const Int_t lay=0){
913 ////////////////////////////////////////////////////////////////////////
914 // Finds the Detector (Module) that is nearest the point g [cm] in
915 // ALICE Global coordinates. If layer !=0 then the search is restricted
916 // to Detectors (Modules) in that particular layer.
917 ////////////////////////////////////////////////////////////////////////
919 Double_t d,dn=1.0e10;
920 Bool_t t=lay!=0; // skip if lay = 0 default value check all layers.
922 for(i=0;i<fNmodules;i++){
923 if(t){GetModuleId(i,l,a,e);if(l!=lay) continue;}
924 if((d=fGm[i]->Distance2(g))<dn){
931 //______________________________________________________________________
932 void AliITSgeom::GetNearest27(const Double_t g[3],Int_t n[27],const Int_t lay=0){
933 ////////////////////////////////////////////////////////////////////////
934 // Finds 27 Detectors (Modules) that are nearest the point g [cm] in
935 // ALICE Global coordinates. If layer !=0 then the search is restricted
936 // to Detectors (Modules) in that particular layer. The number 27 comes
937 // from including the nearest detector and all those around it (up, down,
938 // left, right, forwards, backwards, and the corners).
939 ////////////////////////////////////////////////////////////////////////
940 Int_t i,l,a,e,in[27]={0,0,0,0,0,0,0,0,0,
943 Double_t d,dn[27]={1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,
944 1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,
945 1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,
946 1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,1.0e10,
947 1.0e10,1.0e10,1.0e10};
948 Bool_t t=(lay!=0); // skip if lay = 0 default value check all layers.
950 for(i=0;i<fNmodules;i++){
951 if(t){GetModuleId(i,l,a,e);if(l!=lay) continue;}
953 d = fGm[i]->Distance2(g);
955 for(e=26;e>a;e--){dn[e] = dn[e-1];in[e] = in[e-1];}
956 dn[a] = d; in[a] = i;
960 for(i=0;i<27;i++) n[i] = in[i];
962 //----------------------------------------------------------------------