]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EMCAL/AliEMCALGeometry.cxx
Removing ^M at the end of lines
[u/mrichter/AliRoot.git] / EMCAL / AliEMCALGeometry.cxx
1 /**************************************************************************
2
3  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4
5  *                                                                        *
6
7  * Author: The ALICE Off-line Project.                                    *
8
9  * Contributors are mentioned in the code where appropriate.              *
10
11  *                                                                        *
12
13  * Permission to use, copy, modify and distribute this software and its   *
14
15  * documentation strictly for non-commercial purposes is hereby granted   *
16
17  * without fee, provided that the above copyright notice appears in all   *
18
19  * copies and that both the copyright notice and this permission notice   *
20
21  * appear in the supporting documentation. The authors make no claims     *
22
23  * about the suitability of this software for any purpose. It is          *
24
25  * provided "as is" without express or implied warranty.                  *
26
27  **************************************************************************/
28
29
30
31 /* $Id$*/
32
33
34
35 //_________________________________________________________________________
36
37 // Geometry class  for EMCAL : singleton  
38
39 // EMCAL consists of layers of scintillator and lead
40
41 // Places the the Barrel Geometry of The EMCAL at Midrapidity
42
43 // between 0 and 120 degrees of Phi and
44
45 // -0.7 to 0.7 in eta 
46
47 // Number of Modules and Layers may be controlled by 
48
49 // the name of the instance defined               
50
51 // EMCALArch2x has more modules along both phi and eta
52
53 // EMCALArchxa has less Layers in the Radial Direction
54
55 //*-- Author: Sahal Yacoob (LBL / UCT)
56
57 //     and  : Yves Schutz (SUBATECH)
58
59 //     and  : Jennifer Klay (LBL)
60
61
62
63 // --- ROOT system ---
64
65
66
67 // --- Standard library ---
68
69
70
71 #include <iostream.h>
72
73
74
75 // --- AliRoot header files ---
76
77 #include <TMath.h>
78
79 // -- ALICE Headers.
80
81 #include "AliConst.h"
82
83 // --- EMCAL headers
84
85 #include "AliEMCALGeometry.h"
86
87
88
89 ClassImp(AliEMCALGeometry);
90
91
92
93 AliEMCALGeometry *AliEMCALGeometry::fgGeom = 0;
94
95 Bool_t            AliEMCALGeometry::fgInit = kFALSE;
96
97
98
99 //______________________________________________________________________
100
101 AliEMCALGeometry::~AliEMCALGeometry(void){
102
103     // dtor
104
105 }
106
107 //______________________________________________________________________
108
109 void AliEMCALGeometry::Init(void){
110
111     // Initializes the EMCAL parameters
112
113
114
115     fgInit = kFALSE; // Assume failer untill proven otherwise.
116
117
118
119     TString name(GetName()) ; 
120
121                  
122
123     if( name != "EMCALArch1a" &&
124
125         name != "EMCALArch1b" && 
126
127         name != "EMCALArch2a" && 
128
129         name != "EMCALArch2b"  ){
130
131       cerr << "ERROR: " << ClassName() << "::Init -> " << name.Data() 
132
133            << " is not a known geometry (choose among EMCALArch1a, EMCALArch1b, EMCALArch2a and EMCALArch2b)" 
134
135            << endl ; 
136
137       abort() ;
138
139     } // end if
140
141     //
142
143     if ( name == "EMCALArch1a"  ||
144
145          name == "EMCALArch1b" ) {
146
147         fNZ         = 96;
148
149         fNPhi       = 144;
150
151     } // end if
152
153     if ( name == "EMCALArch2a"  ||
154
155          name, "EMCALArch2b" ) {
156
157         fNZ         = 112;
158
159         fNPhi       = 168;
160
161     } // end if
162
163     if ( name == "EMCALArch1a"  ||
164
165          name == "EMCALArch2a" ) {
166
167         fNLayers    = 21;
168
169     } // end if
170
171     if ( name == "EMCALArch1b"  ||
172
173          name == "EMCALArch2b" ) {
174
175         fNLayers    = 25;
176
177     } // end if
178
179
180
181     // geometry
182
183     fAirGap         = 5.0; // cm, air gap between EMCAL mother volume and 
184
185                            // active material.
186
187     fAlFrontThick   = 3.18; // cm, Thickness of front Al layer
188
189     fPbRadThickness = 0.5; // cm, Thickness of theh Pb radiators.
190
191     fPreShowerSintThick = 0.6; // cm, Thickness of the sintilator for the
192
193                                // preshower part of the calorimeter
194
195     fFullShowerSintThick = 0.5; // cm, Thickness of the sintilator for the
196
197                                 // full shower part of the calorimeter
198
199     fArm1PhiMin     =  60.0; // degrees, Starting EMCAL Phi position
200
201     fArm1PhiMax     = 180.0; // degrees, Ending EMCAL Phi position
202
203     fArm1EtaMin     = -0.7; // pseudorapidity, Starting EMCAL Eta position
204
205     fArm1EtaMax     = +0.7; // pseudorapidity, Ending EMCAL Eta position
206
207     fIPDistance     = 454.0; // cm, Radial distance to inner surface of EMCAL
208
209     fShellThickness = GetAlFrontThickness() + 2.*GetPreSintThick() +
210
211         (fNLayers-2)*GetFullSintThick()+(fNLayers-1)*GetPbRadThick();
212
213     //below; cm, Z lenght of the EMCAL.
214
215     fZLength        = 2.*ZFromEtaR(fIPDistance+fShellThickness,fArm1EtaMax);
216
217     fEnvelop[0]     = fIPDistance; // mother volume inner radius
218
219     fEnvelop[1]     = fIPDistance + fShellThickness; // mother volume outer r.
220
221     fEnvelop[2]     = 1.00001*fZLength; // add some padding for mother volume. 
222
223     fGap2Active     = 1.0;  // cm, Gap between 
224
225     fgInit = kTRUE; 
226
227 }
228
229 //______________________________________________________________________
230
231 AliEMCALGeometry *  AliEMCALGeometry::GetInstance(){ 
232
233   // Returns the pointer of the unique instance
234
235   
236
237   return static_cast<AliEMCALGeometry *>( fgGeom ) ; 
238
239 }
240
241 //______________________________________________________________________
242
243 AliEMCALGeometry* AliEMCALGeometry::GetInstance(const Text_t* name,
244
245                                                 const Text_t* title){
246
247     // Returns the pointer of the unique instance
248
249
250
251     AliEMCALGeometry * rv = 0; 
252
253     if ( fgGeom == 0 ) {
254
255         if ( strcmp(name,"") == 0 ) rv = 0;
256
257         else {    
258
259             fgGeom = new AliEMCALGeometry(name, title);
260
261             if ( fgInit ) rv = (AliEMCALGeometry * ) fgGeom;
262
263             else {
264
265                 rv = 0; 
266
267                 delete fgGeom; 
268
269                 fgGeom = 0; 
270
271             } // end if fgInit
272
273         } // end if strcmp(name,"")
274
275     }else{
276
277         if ( strcmp(fgGeom->GetName(), name) != 0 ) {
278
279             cout << "AliEMCALGeometry <E> : current geometry is " 
280
281                  << fgGeom->GetName() << endl
282
283                  << "                      you cannot call     " << name 
284
285                  << endl; 
286
287         }else{
288
289             rv = (AliEMCALGeometry *) fgGeom; 
290
291         } // end if
292
293     }  // end if fgGeom
294
295     return rv; 
296
297 }
298
299 //______________________________________________________________________
300
301 Int_t AliEMCALGeometry::TowerIndex(Int_t ieta,Int_t iphi,Int_t ipre) const {
302
303     // Returns the tower index number from the based on the Z and Phi
304
305     // index numbers. There are 2 times the number of towers to separate
306
307     // out the full towsers from the pre-towsers.
308
309     // Inputs:
310
311     //   Int_t ieta    // index allong z axis [1-fNZ]
312
313     //   Int_t iphi  // index allong phi axis [1-fNPhi]
314
315     //   Int_t ipre  // 0 = Full tower, 1 = Pre-shower tower only. [0,1]
316
317     // Outputs:
318
319     //   none.
320
321     // Returned
322
323     // Int_t the absoulute tower index. [1-2*fNZ*fNPhi]
324
325     Int_t index;
326
327
328
329     if((ieta<=0 || ieta>GetNEta()) || (iphi<=0 || iphi>GetNPhi()) ||
330
331        (ipre<0 || ipre>1) ){
332
333         cout << "inputs out of range ieta=" << ieta << " [1-" << GetNEta();
334
335         cout << "] iphi=" << iphi << " [1-" << GetNPhi() << "] ipre=";
336
337         cout << ipre << "[0,1]. returning -1" << endl;
338
339         return -1;
340
341     } // end if
342
343     index = iphi + GetNPhi()*(ieta-1) + ipre*(GetNPhi()*GetNEta());
344
345     return index;
346
347 }
348
349 //______________________________________________________________________
350
351 void AliEMCALGeometry::TowerIndexes(Int_t index,Int_t &ieta,Int_t &iphi,
352
353                                     Int_t &ipre) const {
354
355     // given the tower index number it returns the based on the Z and Phi
356
357     // index numbers and if it is for the full tower or the pre-tower number.
358
359     // There are 2 times the number of towers to separate
360
361     // out the full towsers from the pre-towsers.
362
363     // Inputs:
364
365     //   Int_t index // Tower index number [1-2*fNZ*fNPhi]
366
367     // Outputs:
368
369     //   Int_t ieta    // index allong z axis [1-fNZ]
370
371     //   Int_t iphi  // index allong phi axis [1-fNPhi]
372
373     //   Int_t ipre  // 0 = Full tower, 1 = Pre-shower tower only. [0,1]
374
375     // Returned
376
377     //   none.
378
379     Int_t itowers;
380
381
382
383     itowers = GetNEta()*GetNPhi();
384
385     if(index<1 || index>2*itowers){
386
387         cout << "index=" << index <<" is out of range [1-";
388
389         cout << 2*itowers << "], returning -1 for all." << endl;
390
391         ieta = -1; iphi = -1; ipre = -1;
392
393         return ;
394
395     } // end if
396
397     ipre = 0;
398
399     if(index>itowers){ // pre shower indexs
400
401         ipre = 1;
402
403         index = index - itowers;
404
405     } // end if
406
407     ieta = 1+ (Int_t)((index-1)/GetNPhi());
408
409     iphi = index - GetNPhi()*(ieta-1);
410
411     return;
412
413 }
414
415 //______________________________________________________________________
416
417 void AliEMCALGeometry::EtaPhiFromIndex(Int_t index,Float_t &eta,Float_t &phi) const {
418
419     // given the tower index number it returns the based on the eta and phi
420
421     // of the tower.
422
423     // Inputs:
424
425     //   Int_t index // Tower index number [1-2*fNZ*fNPhi]
426
427     // Outputs:
428
429     //   Float_t eta  // eta of center of tower in pseudorapidity
430
431     //   Float_t phi  // phi of center of tower in degrees
432
433     // Returned
434
435     //   none.
436
437     Int_t ieta,iphi,ipre;
438
439     Double_t deta,dphi,phid;
440
441
442
443     TowerIndexes(index,ieta,iphi,ipre);
444
445     deta = (GetArm1EtaMax()-GetArm1EtaMin())/((Float_t)GetNEta());
446
447     eta  = GetArm1EtaMin() + (((Float_t)ieta)-0.5)*deta;
448
449     dphi = (GetArm1PhiMax() - GetArm1PhiMin())/((Float_t)GetNPhi());  // in degrees.
450
451     phid = GetArm1PhiMin() + dphi*((Float_t)iphi -0.5);//iphi range [1-fNphi].
452
453     phi  = phid;
454
455 }
456
457 //______________________________________________________________________
458
459 Int_t AliEMCALGeometry::TowerIndexFromEtaPhi(Float_t eta,Float_t phi) const {
460
461     // returns the tower index number based on the eta and phi of the tower.
462
463     // Inputs:
464
465     //   Float_t eta  // eta of center of tower in pseudorapidity
466
467     //   Float_t phi  // phi of center of tower in degrees
468
469     // Outputs:
470
471     //   none.
472
473     // Returned
474
475     //   Int_t index // Tower index number [1-fNZ*fNPhi]
476
477     Int_t ieta,iphi;
478
479
480
481     ieta = 1 + (Int_t)(((Float_t)GetNEta())*(eta-GetArm1EtaMin())/
482
483                   (GetArm1EtaMax() - GetArm1EtaMin()));
484
485     if(ieta<=0 || ieta>GetNEta()){
486
487         cout << "TowerIndexFromEtaPhi:";
488
489         cout << "ieta = "<< ieta << " eta=" << eta << " is outside of EMCAL. etamin=";
490
491         cout << GetArm1EtaMin() << " to etamax=" << GetArm1EtaMax();
492
493         cout << " returning -1" << endl;
494
495         return -1;
496
497     } // end if
498
499     iphi = 1 + (Int_t)(((Float_t)GetNPhi())*(phi-GetArm1PhiMin())/
500
501                   ((Float_t)(GetArm1PhiMax() - GetArm1PhiMin())));
502
503     if(iphi<=0 || iphi>GetNPhi()){
504
505         cout << "TowerIndexFromEtaPhi:";
506
507         cout << "iphi=" << iphi << " phi=" << phi << " is outside of EMCAL.";
508
509         cout << " Phimin=" << GetArm1PhiMin() << " PhiMax=" << GetArm1PhiMax();
510
511         cout << " returning -1" << endl;
512
513         return -1;
514
515     } // end if
516
517     return TowerIndex(ieta,iphi,0);
518
519 }
520
521 //______________________________________________________________________
522
523 Int_t AliEMCALGeometry::PreTowerIndexFromEtaPhi(Float_t eta,Float_t phi) const {
524
525     // returns the pretower index number based on the eta and phi of the tower.
526
527     // Inputs:
528
529     //   Float_t eta  // eta of center of tower in pseudorapidity
530
531     //   Float_t phi  // phi of center of tower in degrees
532
533     // Outputs:
534
535     //   none.
536
537     // Returned
538
539     //   Int_t index // PreTower index number [fNZ*fNPhi-2*fNZ*fNPhi]
540
541
542
543     return GetNEta()*GetNPhi()+TowerIndexFromEtaPhi(eta,phi);
544
545 }
546
547 //______________________________________________________________________
548
549 Bool_t AliEMCALGeometry::AbsToRelNumbering(Int_t AbsId, Int_t *relid) const {
550
551     // Converts the absolute numbering into the following array/
552
553     //  relid[0] = EMCAL Arm number 1:1 
554
555     //  relid[1] = 0  Not in Pre Shower layers
556
557     //           = -1 In Pre Shower
558
559     //  relid[2] = Row number inside EMCAL
560
561     //  relid[3] = Column number inside EMCAL
562
563     // Input:
564
565     //   Int_t AbsId // Tower index number [1-2*fNZ*fNPhi]
566
567     // Outputs:
568
569     //   Int_t *relid // array of 5. Discribed above.
570
571     Bool_t rv  = kTRUE ;
572
573     Int_t ieta=0,iphi=0,ipre=0,index=AbsId;
574
575
576
577     TowerIndexes(index,ieta,iphi,ipre);
578
579     relid[0] = 1;
580
581     relid[1] = 0;
582
583     if(ipre==1) 
584
585       relid[1] = -1;
586
587     relid[2] = ieta;
588
589     relid[3] = iphi;
590
591
592
593     return rv;
594
595 }
596
597 //______________________________________________________________________
598
599 void AliEMCALGeometry::PosInAlice(const Int_t *relid,Float_t &theta,
600
601                                      Float_t &phi) const {
602
603     // Converts the relative numbering into the local EMCAL-module (x, z)
604
605     // coordinates
606
607     Int_t ieta   = relid[2]; // offset along x axis
608
609     Int_t iphi = relid[3]; // offset along z axis
610
611     Int_t ipre = relid[1]; // indicates -1 preshower, or 0 full tower.
612
613     Int_t index;
614
615     Float_t eta;
616
617
618
619     if(ipre==-1) ipre = 1;
620
621     index = TowerIndex(ieta,iphi,ipre);
622
623     EtaPhiFromIndex(index,eta,phi);
624
625     theta = 180.*(2.0*TMath::ATan(TMath::Exp(-eta)))/TMath::Pi();
626
627
628
629     return;
630
631 }
632
633
634
635 //______________________________________________________________________
636
637 void AliEMCALGeometry::XYZFromIndex(const Int_t *relid,Float_t &x,Float_t &y, Float_t &z) const {
638
639     // given the tower relative number it returns the X, Y and Z
640
641     // of the tower.
642
643     
644
645     // Outputs:
646
647     //   Float_t x  // x of center of tower in cm
648
649     //   Float_t y  // y of center of tower in cm
650
651     //   Float_t z  // z of centre of tower in cm
652
653     // Returned
654
655     //   none.
656
657     
658
659     Float_t eta,theta, phi,cyl_radius,kDeg2Rad;
660
661     
662
663     Int_t ieta   = relid[2]; // offset along x axis
664
665     Int_t iphi = relid[3]; // offset along z axis
666
667     Int_t ipre = relid[1]; // indicates -1 preshower, or 0 full tower.
668
669     Int_t index;
670
671     
672
673
674
675     if(ipre==-1) ipre = 1;
676
677     index = TowerIndex(ieta,iphi,ipre);
678
679     EtaPhiFromIndex(index,eta,phi);
680
681     theta = 180.*(2.0*TMath::ATan(TMath::Exp(-eta)))/TMath::Pi();
682
683
684
685  
686
687     
688
689     kDeg2Rad = TMath::Pi() / static_cast<Double_t>(180) ; 
690
691     cyl_radius = GetIPDistance()+ GetAirGap() ;
692
693     x =  cyl_radius * TMath::Cos(phi * kDeg2Rad ) ;
694
695     y =  cyl_radius * TMath::Cos(phi * kDeg2Rad ) ; 
696
697     z =  cyl_radius / TMath::Tan(theta * kDeg2Rad ) ; 
698
699  
700
701  return;
702
703
704
705
706
707 //______________________________________________________________________
708
709 /*
710
711 Boot_t AliEMCALGeometry::AreNeighbours(Int_t index1,Int_t index2) const {
712
713     // Returns kTRUE if the two towers are neighbours or not, including
714
715     // diagonals. Both indexes are required to be either towers or preshower.
716
717     // Inputs:
718
719     //   Int_t index1  // index of tower 1
720
721     //   Int_t index2  // index of tower 2
722
723     // Outputs:
724
725     //   none.
726
727     // Returned
728
729     //   Boot_t kTRUE if the towers are neighbours otherwise false.
730
731     Boot_t anb = kFALSE;
732
733     Int_t ieta1 = 0, ieta2 = 0, iphi1 = 0, iphi2 = 0, ipre1 = 0, ipre2 = 0;
734
735
736
737     TowerIndexes(index1,ieta1,iphi1,ipre1);
738
739     TowerIndexes(index2,ieta2,iphi2,ipre2);
740
741     if(ipre1!=ipre2) return anb;
742
743     if((ieta1>=ieta2-1 && ieta1<=ieta2+1) && (iphi1>=iphi2-1 &&iphi1<=iphi2+1))
744
745                                                                  anb = kTRUE;
746
747     return anb;
748
749 }
750
751  */
752