EMCAL_FIRSTYEARV1 - geometry for December 2009 to December 2010 run period;
[u/mrichter/AliRoot.git] / EMCAL / AliEMCALGeometry.cxx
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 /* $Id$*/
17
18 //_________________________________________________________________________
19 // Geometry class  for EMCAL : singleton  
20 // EMCAL consists of layers of scintillator and lead
21 // with scintillator fiber arranged as "shish-kebab" skewers 
22 // Places the the Barrel Geometry of The EMCAL at Midrapidity
23 // between 80 and 180(or 190) degrees of Phi and
24 // -0.7 to 0.7 in eta 
25 //
26 //     EMCAL geometry tree:
27 //     EMCAL -> superModule -> module -> tower(cell)
28 //     Indexes
29 //     absId -> nSupMod     -> nModule -> (nIphi,nIeta)
30 //
31 //   Name choices: 
32 //   EMCAL_PDC06 (geometry used for PDC06 simulations, kept for backward compatibility)
33 //      = equivalent to SHISH_77_TRD1_2X2_FINAL_110DEG in old notation
34 //   EMCAL_COMPLETE (geometry for expected complete detector)
35 //      = equivalent to SHISH_77_TRD1_2X2_FINAL_110DEG scTh=0.176 pbTh=0.144
36 //          in old notation
37 //   EMCAL_4SMs - geometry for December 2009 to December 2010 run period; 
38 //                fixed bug for positions of modules inside SM
39 //                (first module has tilt 0.75 degree);
40 //                the sizes updated with last information from production
41 //                drawing (end of October 2010). 
42 //                
43 //
44 //   EMCAL_WSUC (Wayne State test stand)
45 //      = no definite equivalent in old notation, was only used by
46 //          Aleksei, but kept for testing purposes
47 //
48 //   etc.
49 //
50 //
51 //
52 //*-- Author: Sahal Yacoob (LBL / UCT)
53 //     and  : Yves Schutz (SUBATECH)
54 //     and  : Jennifer Klay (LBL)
55 //     and  : Alexei Pavlinov (WSU) 
56 //
57
58 //--- Root header files ---
59 #include <TVector2.h>
60 #include <TVector3.h>
61 //-- ALICE Headers.
62 #include "AliLog.h"
63
64 // // --- EMCAL headers
65 #include "AliEMCALGeometry.h"
66 #include "AliEMCALShishKebabTrd1Module.h"
67 //#include "AliEMCALRecPoint.h"
68 //#include "AliEMCALHistoUtilities.h"
69
70 ClassImp(AliEMCALGeometry)
71
72 // these initialisations are needed for a singleton
73 AliEMCALGeometry  *AliEMCALGeometry::fgGeom      = 0;
74 const Char_t*      AliEMCALGeometry::fgkDefaultGeometryName = "EMCAL_COMPLETE";
75 //
76 // Usage: 
77 //        You can create the AliEMCALGeometry object independently from anything.
78 //        You have to use just the correct name of geometry. If name is empty string the
79 //        default name of geometry will be used.
80 //         
81 //  AliEMCALGeometry* g = AliEMCALGeometry::GetInstance(name,title); // first time
82 //  ..
83 //  g = AliEMCALGeometry::GetInstance();                             // after first time
84 //
85 //  MC:   If you work with MC data you have to get geometry the next way: 
86 //  ==                                      =============================
87 //  AliRunLoader    *rl   = AliRunLoader::Instance();
88 //  AliEMCALGeometry *geom = dynamic_cast<AliEMCAL*>(rl->GetAliRun()->GetDetector("EMCAL"))->GetGeometry();
89 //  TGeoManager::Import("geometry.root");
90
91 AliEMCALGeometry::AliEMCALGeometry() 
92   : AliEMCALGeoUtils()
93
94   // default ctor only for internal usage (singleton)
95   // must be kept public for root persistency purposes, 
96   // but should never be called by the outside world    
97
98   AliDebug(2, "AliEMCALGeometry : default ctor ");
99 }
100 //______________________________________________________________________
101 AliEMCALGeometry::AliEMCALGeometry(const Text_t* name, const Text_t* title) 
102   : AliEMCALGeoUtils(name, title)
103 {
104   // ctor only for internal usage (singleton)
105   AliDebug(2, Form("AliEMCALGeometry(%s,%s) ", name,title));
106
107 }
108 //______________________________________________________________________
109 AliEMCALGeometry::AliEMCALGeometry(const AliEMCALGeometry& geom)
110   : AliEMCALGeoUtils(geom)
111 {
112   //copy ctor
113 }
114
115 //______________________________________________________________________
116 AliEMCALGeometry::~AliEMCALGeometry(void){
117     // dtor
118 }
119
120
121 //______________________________________________________________________
122 AliEMCALGeometry *  AliEMCALGeometry::GetInstance(){ 
123   // Returns the pointer of the unique instance
124   
125   AliEMCALGeometry * rv = static_cast<AliEMCALGeometry *>( fgGeom );
126   return rv; 
127 }
128
129 //______________________________________________________________________
130 AliEMCALGeometry* AliEMCALGeometry::GetInstance(const Text_t* name,
131                                                 const Text_t* title){
132     // Returns the pointer of the unique instance
133
134     AliEMCALGeometry * rv = 0; 
135     if ( fgGeom == 0 ) {
136       if ( strcmp(name,"") == 0 ) { // get default geometry
137          fgGeom = new AliEMCALGeometry(fgkDefaultGeometryName, title);
138       } else {
139          fgGeom = new AliEMCALGeometry(name, title);
140       }  // end if strcmp(name,"")
141       if ( AliEMCALEMCGeometry::fgInit ) rv = (AliEMCALGeometry * ) fgGeom;
142       else {
143          rv = 0; 
144          delete fgGeom; 
145          fgGeom = 0; 
146       } // end if fgInit
147     }else{
148         if ( strcmp(fgGeom->GetName(), name) != 0) {
149           printf("\ncurrent geometry is %s : ", fgGeom->GetName());
150           printf(" you cannot call %s ",name);  
151         }else{
152           rv = (AliEMCALGeometry *) fgGeom; 
153         } // end 
154     }  // end if fgGeom
155     return rv; 
156 }
157
158 //________________________________________________________________________________________________
159 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Double_t distEff, Double_t &xr, Double_t &yr, Double_t &zr) const
160 {
161   // Jul 30, 2007 - taking into account position of shower max
162   // Look to see what the relative
163   // position inside a given cell is
164   // for a recpoint.
165   // In:
166   // absId   - cell is as in Geant,     0<= absId   < fNCells;
167   // e       - cluster energy
168   // OUT:
169   // xr,yr,zr - x,y,z coordinates of cell with absId inside SM 
170
171   // Shift index taking into account the difference between standard SM 
172   // and SM of half size in phi direction
173   const  Int_t kphiIndexShift = fCentersOfCellsPhiDir.GetSize()/4; // Nov 22, 2006; was 6 for cas 2X2
174   static Int_t nSupMod=0, nModule=-1, nIphi=-1, nIeta=-1, iphi=-1, ieta=-1;
175   static Int_t iphim=-1, ietam=-1;
176   static AliEMCALShishKebabTrd1Module *mod = 0;
177   static TVector2 v;
178   if(!CheckAbsCellId(absId)) return kFALSE;
179   
180   GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
181   GetModulePhiEtaIndexInSModule(nSupMod, nModule, iphim, ietam);
182   GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi, ieta); 
183   
184   //Get eta position. Careful with ALICE conventions (increase index decrease eta)      
185   if(nSupMod%2 == 0) {             
186     ietam = (fCentersOfCellsEtaDir.GetSize()/2-1)-ietam;// 47-ietam, revert the ordering on A side in order to keep convention.
187     if(nIeta == 0) nIeta = 1;
188     else           nIeta = 0;
189   }
190   mod = GetShishKebabModule(ietam);
191   mod ->GetPositionAtCenterCellLine(nIeta, distEff, v); 
192   xr = v.Y() - fParSM[0];
193   zr = v.X() - fParSM[2];
194   
195   //Get phi position. Careful with ALICE conventions (increase index increase phi)
196   Int_t iphi2 = iphi;
197   if(nSupMod<10) { 
198     if(nSupMod%2 != 0) 
199       iphi2 = (fCentersOfCellsPhiDir.GetSize()-1)-iphi;// 23-iphi, revert the ordering on C side in order to keep convention.
200     yr = fCentersOfCellsPhiDir.At(iphi2);
201     
202   } else {
203     if(nSupMod%2 != 0) 
204       iphi2 = (fCentersOfCellsPhiDir.GetSize()/2-1)-iphi;// 11-iphi, revert the ordering on C side in order to keep convention.
205     yr = fCentersOfCellsPhiDir.At(iphi2 + kphiIndexShift);
206   }
207   
208   AliDebug(1,Form("absId %i nSupMod %i iphi %i ieta %i xr %f yr %f zr %f ",absId,nSupMod,iphi,ieta,xr,yr,zr));
209   
210   return kTRUE;
211 }
212
213 //Not in use, comment for the moment
214 //________________________________________________________________________________________________
215 //Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Int_t maxAbsId, Double_t distEff, Double_t &xr, Double_t &yr, Double_t &zr) const
216 //{
217 //  // Jul 31, 2007 - taking into account position of shower max and apply coor2.
218 //  // Look to see what the relative
219 //  // position inside a given cell is
220 //  // for a recpoint.
221 //  // In:
222 //  // absId     - cell is as in Geant,     0<= absId   < fNCells;
223 //  // maxAbsId  - abs id of cell with highest energy
224 //  // e         - cluster energy
225 //  // OUT:
226 //  // xr,yr,zr - x,y,z coordinates of cell with absId inside SM 
227 //  
228 //  // Shift index taking into account the difference between standard SM 
229 //  // and SM of half size in phi direction
230 //  const  Int_t kphiIndexShift = fCentersOfCellsPhiDir.GetSize()/4; // Nov 22, 2006; was 6 for cas 2X2
231 //  static Int_t nSupMod, nModule, nIphi, nIeta, iphi, ieta;
232 //  static Int_t iphim, ietam;
233 //  static AliEMCALShishKebabTrd1Module *mod = 0;
234 //  static TVector2 v;
235 //
236 //  static Int_t nSupModM, nModuleM, nIphiM, nIetaM, iphiM, ietaM;
237 //  static Int_t iphimM, ietamM, maxAbsIdCopy=-1;
238 //  static AliEMCALShishKebabTrd1Module *modM = 0;
239 //  static Double_t distCorr;
240 //
241 //  if(!CheckAbsCellId(absId)) return kFALSE;
242 //  
243 //  GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
244 //  GetModulePhiEtaIndexInSModule(nSupMod, nModule, iphim, ietam);
245 //  GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi, ieta); 
246 //  
247 //  //Get eta position. Careful with ALICE conventions (increase index decrease eta)    
248 //  if(nSupMod%2 == 0) {             
249 //    ietam = (fCentersOfCellsEtaDir.GetSize()/2-1)-ietam;// 23-ietam, revert the ordering on A side in order to keep convention.
250 //    if(nIeta == 0) nIeta = 1;
251 //    else                 nIeta = 0;
252 //  }
253 //  
254 //  mod = GetShishKebabModule(ietam);
255 //  
256 //  if(absId != maxAbsId) {
257 //    distCorr = 0.;
258 //    if(maxAbsIdCopy != maxAbsId) {
259 //      GetCellIndex(maxAbsId, nSupModM, nModuleM, nIphiM, nIetaM);
260 //      GetModulePhiEtaIndexInSModule(nSupModM, nModuleM, iphimM, ietamM);
261 //      GetCellPhiEtaIndexInSModule(nSupModM,nModuleM,nIphiM,nIetaM, iphiM, ietaM); 
262 //      //Careful with ALICE conventions (increase index decrease eta)  
263 //      if(nSupModM%2 == 0) {             
264 //      ietamM = (fCentersOfCellsEtaDir.GetSize()/2-1)-ietamM;// 47-ietam, revert the ordering on A side in order to keep convention.
265 //      }
266 //      
267 //      modM = GetShishKebabModule(ietamM); // do I need this ?
268 //      maxAbsIdCopy = maxAbsId;
269 //    }
270 //    
271 //    if(ietamM !=0) {
272 //      distCorr = fEMCGeometry->GetEtaModuleSize()*(ietam-ietamM)/TMath::Tan(modM->GetTheta()); // Stay here
273 //      //printf(" distCorr %f | dist %f | ietam %i -> etamM %i\n", distCorr, dist, ietam, ietamM);  
274 //    }
275 //    // distEff += distCorr;
276 //  }
277 //  // Bad resolution in this case, strong bias vs phi
278 //  // distEff = 0.0; 
279 //  mod->GetPositionAtCenterCellLine(nIeta, distEff, v); // Stay here
280 //  xr = v.Y() - fParSM[0];
281 //  zr = v.X() - fParSM[2];
282 //  
283 //  //Get phi position. Careful with ALICE conventions (increase index increase phi)
284 //  Int_t iphi2 = iphi;
285 //  if(nSupMod<10) { 
286 //    if(nSupMod%2 != 0) 
287 //      iphi2 = (fCentersOfCellsPhiDir.GetSize()-1)-iphi;// 23-iphi, revert the ordering on C side in order to keep convention.
288 //    yr = fCentersOfCellsPhiDir.At(iphi2);
289 //    
290 //  } else {
291 //    if(nSupMod%2 != 0) 
292 //      iphi2 = (fCentersOfCellsPhiDir.GetSize()/2-1)-iphi;// 11-iphi, revert the ordering on C side in order to keep convention.
293 //    yr = fCentersOfCellsPhiDir.At(iphi2 + kphiIndexShift);
294 //  }
295 //  AliDebug(1,Form("absId %i nSupMod %i iphi %i ieta %i xr %f yr %f zr %f ",absId,nSupMod,iphi,ieta,xr,yr,zr));
296 //  
297 //  return kTRUE;
298 //}
299 //
300
301 //
302 // == Shish-kebab cases ==
303 //
304
305 //
306 ////_________________________________________________________________________________
307 //void AliEMCALGeometry::GetGlobalEMCAL(const AliEMCALRecPoint *rp, TVector3 &vglob) const
308 //{
309 //  // Figure out the global numbering
310 //  // of a given supermodule from the
311 //  // local numbering for RecPoints
312 //
313 //  static TVector3 vloc;
314 //  static Int_t nSupMod, nModule, nIphi, nIeta;
315 //
316 //  const AliEMCALRecPoint *rpTmp = rp;
317 //  const AliEMCALRecPoint *rpEmc = rpTmp;
318 //
319 //  GetCellIndex(rpEmc->GetAbsId(0), nSupMod, nModule, nIphi, nIeta);
320 //  rpTmp->GetLocalPosition(vloc);
321 //  GetGlobal(vloc, vglob, nSupMod);
322 //}
323