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 //_________________________________________________________________________
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
26 // EMCAL geometry tree:
27 // EMCAL -> superModule -> module -> tower(cell)
29 // absId -> nSupMod -> nModule -> (nIphi,nIeta)
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
37 // EMCAL_WSUC (Wayne State test stand)
38 // = no definite equivalent in old notation, was only used by
39 // Aleksei, but kept for testing purposes
45 //*-- Author: Sahal Yacoob (LBL / UCT)
46 // and : Yves Schutz (SUBATECH)
47 // and : Jennifer Klay (LBL)
48 // and : Aleksei Pavlinov (WSU)
51 //--- Root header files ---
57 // // --- EMCAL headers
58 #include "AliEMCALGeometry.h"
59 #include "AliEMCALShishKebabTrd1Module.h"
60 #include "AliEMCALRecPoint.h"
61 //#include "AliEMCALHistoUtilities.h"
63 ClassImp(AliEMCALGeometry)
65 // these initialisations are needed for a singleton
66 AliEMCALGeometry *AliEMCALGeometry::fgGeom = 0;
67 const Char_t* AliEMCALGeometry::fgkDefaultGeometryName = "EMCAL_COMPLETE";
70 // You can create the AliEMCALGeometry object independently from anything.
71 // You have to use just the correct name of geometry. If name is empty string the
72 // default name of geometry will be used.
74 // AliEMCALGeometry* g = AliEMCALGeometry::GetInstance(name,title); // first time
76 // g = AliEMCALGeometry::GetInstance(); // after first time
78 // MC: If you work with MC data you have to get geometry the next way:
79 // == =============================
80 // AliRunLoader *rl = AliRunLoader::Instance();
81 // AliEMCALGeometry *geom = dynamic_cast<AliEMCAL*>(rl->GetAliRun()->GetDetector("EMCAL"))->GetGeometry();
82 // TGeoManager::Import("geometry.root");
84 AliEMCALGeometry::AliEMCALGeometry()
87 // default ctor only for internal usage (singleton)
88 // must be kept public for root persistency purposes,
89 // but should never be called by the outside world
91 AliDebug(2, "AliEMCALGeometry : default ctor ");
93 //______________________________________________________________________
94 AliEMCALGeometry::AliEMCALGeometry(const Text_t* name, const Text_t* title)
95 : AliEMCALGeoUtils(name, title)
97 // ctor only for internal usage (singleton)
98 AliDebug(2, Form("AliEMCALGeometry(%s,%s) ", name,title));
101 //______________________________________________________________________
102 AliEMCALGeometry::AliEMCALGeometry(const AliEMCALGeometry& geom)
103 : AliEMCALGeoUtils(geom)
108 //______________________________________________________________________
109 AliEMCALGeometry::~AliEMCALGeometry(void){
114 //______________________________________________________________________
115 AliEMCALGeometry * AliEMCALGeometry::GetInstance(){
116 // Returns the pointer of the unique instance
118 AliEMCALGeometry * rv = static_cast<AliEMCALGeometry *>( fgGeom );
122 //______________________________________________________________________
123 AliEMCALGeometry* AliEMCALGeometry::GetInstance(const Text_t* name,
124 const Text_t* title){
125 // Returns the pointer of the unique instance
127 AliEMCALGeometry * rv = 0;
129 if ( strcmp(name,"") == 0 ) { // get default geometry
130 fgGeom = new AliEMCALGeometry(fgkDefaultGeometryName, title);
132 fgGeom = new AliEMCALGeometry(name, title);
133 } // end if strcmp(name,"")
134 if ( AliEMCALEMCGeometry::fgInit ) rv = (AliEMCALGeometry * ) fgGeom;
141 if ( strcmp(fgGeom->GetName(), name) != 0) {
142 printf("\ncurrent geometry is %s : ", fgGeom->GetName());
143 printf(" you cannot call %s ",name);
145 rv = (AliEMCALGeometry *) fgGeom;
151 //________________________________________________________________________________________________
152 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Double_t distEff, Double_t &xr, Double_t &yr, Double_t &zr) const
154 // Jul 30, 2007 - taking into account position of shower max
155 // Look to see what the relative
156 // position inside a given cell is
159 // absId - cell is as in Geant, 0<= absId < fNCells;
160 // e - cluster energy
162 // xr,yr,zr - x,y,z coordinates of cell with absId inside SM
164 // Shift index taking into account the difference between standard SM
165 // and SM of half size in phi direction
166 const Int_t kphiIndexShift = fCentersOfCellsPhiDir.GetSize()/4; // Nov 22, 2006; was 6 for cas 2X2
167 static Int_t nSupMod, nModule, nIphi, nIeta, iphi, ieta;
168 static Int_t iphim, ietam;
169 static AliEMCALShishKebabTrd1Module *mod = 0;
171 if(!CheckAbsCellId(absId)) return kFALSE;
173 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
174 GetModulePhiEtaIndexInSModule(nSupMod, nModule, iphim, ietam);
175 GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi, ieta);
177 mod = GetShishKebabModule(ietam);
178 mod->GetPositionAtCenterCellLine(nIeta, distEff, v);
179 xr = v.Y() - fParSM[0];
180 zr = v.X() - fParSM[2];
183 yr = fCentersOfCellsPhiDir.At(iphi);
185 yr = fCentersOfCellsPhiDir.At(iphi + kphiIndexShift);
187 AliDebug(1,Form("absId %i nSupMod %i iphi %i ieta %i xr %f yr %f zr %f ",absId,nSupMod,iphi,ieta,xr,yr,zr));
192 //________________________________________________________________________________________________
193 Bool_t AliEMCALGeometry::RelPosCellInSModule(Int_t absId, Int_t maxAbsId, Double_t distEff, Double_t &xr, Double_t &yr, Double_t &zr) const
195 // Jul 31, 2007 - taking into account position of shower max and apply coor2.
196 // Look to see what the relative
197 // position inside a given cell is
200 // absId - cell is as in Geant, 0<= absId < fNCells;
201 // maxAbsId - abs id of cell with highest energy
202 // e - cluster energy
204 // xr,yr,zr - x,y,z coordinates of cell with absId inside SM
206 // Shift index taking into account the difference between standard SM
207 // and SM of half size in phi direction
208 const Int_t kphiIndexShift = fCentersOfCellsPhiDir.GetSize()/4; // Nov 22, 2006; was 6 for cas 2X2
209 static Int_t nSupMod, nModule, nIphi, nIeta, iphi, ieta;
210 static Int_t iphim, ietam;
211 static AliEMCALShishKebabTrd1Module *mod = 0;
214 static Int_t nSupModM, nModuleM, nIphiM, nIetaM, iphiM, ietaM;
215 static Int_t iphimM, ietamM, maxAbsIdCopy=-1;
216 static AliEMCALShishKebabTrd1Module *modM = 0;
217 static Double_t distCorr;
219 if(!CheckAbsCellId(absId)) return kFALSE;
221 GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
222 GetModulePhiEtaIndexInSModule(nSupMod, nModule, iphim, ietam);
223 GetCellPhiEtaIndexInSModule(nSupMod,nModule,nIphi,nIeta, iphi, ieta);
224 mod = GetShishKebabModule(ietam);
226 if(absId != maxAbsId) {
228 if(maxAbsIdCopy != maxAbsId) {
229 GetCellIndex(maxAbsId, nSupModM, nModuleM, nIphiM, nIetaM);
230 GetModulePhiEtaIndexInSModule(nSupModM, nModuleM, iphimM, ietamM);
231 GetCellPhiEtaIndexInSModule(nSupModM,nModuleM,nIphiM,nIetaM, iphiM, ietaM);
232 modM = GetShishKebabModule(ietamM); // do I need this ?
233 maxAbsIdCopy = maxAbsId;
237 distCorr = fEMCGeometry->GetEtaModuleSize()*(ietam-ietamM)/TMath::Tan(modM->GetTheta()); // Stay here
238 //printf(" distCorr %f | dist %f | ietam %i -> etamM %i\n", distCorr, dist, ietam, ietamM);
240 // distEff += distCorr;
242 // Bad resolution in this case, strong bias vs phi
244 mod->GetPositionAtCenterCellLine(nIeta, distEff, v); // Stay here
245 xr = v.Y() - fParSM[0];
246 zr = v.X() - fParSM[2];
249 yr = fCentersOfCellsPhiDir.At(iphi);
251 yr = fCentersOfCellsPhiDir.At(iphi + kphiIndexShift);
253 AliDebug(1,Form("absId %i nSupMod %i iphi %i ieta %i xr %f yr %f zr %f ",absId,nSupMod,iphi,ieta,xr,yr,zr));
260 // == Shish-kebab cases ==
264 //____________________________________________________________________________
265 void AliEMCALGeometry::GetGlobal(const AliRecPoint* /*rp*/, TVector3& /* vglob */) const
267 AliFatal(Form("Please use GetGlobalEMCAL(recPoint,gpos) instead of GetGlobal!"));
270 //_________________________________________________________________________________
271 void AliEMCALGeometry::GetGlobalEMCAL(const AliEMCALRecPoint *rp, TVector3 &vglob) const
273 // Figure out the global numbering
274 // of a given supermodule from the
275 // local numbering for RecPoints
277 static TVector3 vloc;
278 static Int_t nSupMod, nModule, nIphi, nIeta;
280 const AliEMCALRecPoint *rpTmp = rp;
281 const AliEMCALRecPoint *rpEmc = rpTmp;
283 GetCellIndex(rpEmc->GetAbsId(0), nSupMod, nModule, nIphi, nIeta);
284 rpTmp->GetLocalPosition(vloc);
285 GetGlobal(vloc, vglob, nSupMod);