]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - EMCAL/AliEMCALGeoUtils.cxx
new non linearity function
[u/mrichter/AliRoot.git] / EMCAL / AliEMCALGeoUtils.cxx
index f15ea1e588f798fbf4b8cb4fd46b2b63916d79ae..d6a9b05f849cf81501d76285d3ebf8d685ba75b8 100644 (file)
@@ -26,7 +26,7 @@
 //        You have to use just the correct name of geometry. If name is empty string the
 //        default name of geometry will be used.
 //         
-//  AliEMCALGeoUtils* geom = new AliEMCALGeoUtils("EMCAL_COMPLETE","EMCAL");
+//  AliEMCALGeoUtils* geom = new AliEMCALGeoUtils("EMCAL_COMPLETEV1","EMCAL");
 //  TGeoManager::Import("geometry.root");
 //
 //  MC:   If you work with MC data you have to get geometry the next way: 
@@ -42,6 +42,7 @@
 #include <TParticle.h>
 #include <TGeoManager.h>
 #include <TGeoMatrix.h>
+#include <TGeoBBox.h>
 #include <TList.h>
 #include <TBrowser.h>
 
@@ -73,7 +74,10 @@ AliEMCALGeoUtils::AliEMCALGeoUtils():
   fEnvelop[0] = 0.;
   fEnvelop[1] = 0.;
   fEnvelop[2] = 0.;
+  for(Int_t i=0;i<12;i++)fkSModuleMatrix[i]=0 ;
 
+  for (Int_t i = 0; i < 48; i++)
+       for (Int_t j = 0; j < 64; j++) fFastOR2DMap[i][j] = -1;
 }  
 
 //____________________________________________________________________________
@@ -94,6 +98,10 @@ AliEMCALGeoUtils::AliEMCALGeoUtils(const AliEMCALGeoUtils & geo)
   fEnvelop[0] = geo.fEnvelop[0];
   fEnvelop[1] = geo.fEnvelop[1];
   fEnvelop[2] = geo.fEnvelop[2];
+  for(Int_t i=0;i<12;i++)fkSModuleMatrix[i]=0 ;
+  
+  for (Int_t i = 0; i < 48; i++)
+       for (Int_t j = 0; j < 64; j++) fFastOR2DMap[i][j] = geo.fFastOR2DMap[i][j];
 }
 
 //____________________________________________________________________________
@@ -122,7 +130,7 @@ AliEMCALGeoUtils::AliEMCALGeoUtils(const Text_t* name, const Text_t* title)
   fNETAdiv = fEMCGeometry->GetNETAdiv();
   fNPHIdiv = fEMCGeometry->GetNPHIdiv();
   fNCellsInModule = fNPHIdiv*fNETAdiv;
-  static int i;
+  static int i=0;
   Int_t nSMod = fEMCGeometry->GetNumberOfSuperModules();
   fPhiBoundariesOfSM.Set(nSMod);
   fPhiCentersOfSM.Set(nSMod/2);
@@ -135,7 +143,7 @@ AliEMCALGeoUtils::AliEMCALGeoUtils(const Text_t* name, const Text_t* title)
   Double_t phiMax =  0.;
   for(Int_t sm=0; sm<nSMod; sm++) {
     fEMCGeometry->GetPhiBoundariesOfSM(sm,phiMin,phiMax);
-       i=sm/2;
+    i=sm/2;
     fPhiCentersOfSM[i] = fEMCGeometry->GetPhiCenterOfSM(sm);
   }
   fNCells = fEMCGeometry->GetNCells();
@@ -166,14 +174,18 @@ AliEMCALGeoUtils::AliEMCALGeoUtils(const Text_t* name, const Text_t* title)
        
   if (AliDebugLevel()>=2) {
     fEMCGeometry->Print();
-    PrintGeometry();
+    PrintGeometryGeoUtils();
   }
 
+  for (Int_t ix = 0; ix < 48; ix++)
+       for (Int_t jx = 0; jx < 64; jx++) fFastOR2DMap[ix][jx] = -1;
+
+  BuildFastOR2DMap();
 }
 
 //____________________________________________________________________________
 AliEMCALGeoUtils & AliEMCALGeoUtils::operator = (const AliEMCALGeoUtils  & /*rvalue*/) { 
-
+  //assing operator
   Fatal("assignment operator", "not implemented") ; 
     return *this ;
 }
@@ -182,7 +194,12 @@ AliEMCALGeoUtils & AliEMCALGeoUtils::operator = (const AliEMCALGeoUtils  & /*rva
 AliEMCALGeoUtils::~AliEMCALGeoUtils(void)
 {
   // dtor
-  if(fEMCGeometry){
+  if (fEMCGeometry){ 
+    for(Int_t smod = 0 ; smod < fEMCGeometry->GetNumberOfSuperModules(); smod++){
+      if(fkSModuleMatrix[smod])
+        delete fkSModuleMatrix[smod] ;
+        fkSModuleMatrix[smod]=0 ;
+    }
     delete fEMCGeometry; fEMCGeometry = 0 ;
   }
 }
@@ -211,20 +228,6 @@ void AliEMCALGeoUtils::GetGlobal(const Double_t *loc, Double_t *glob, int ind) c
   // local numbering and the transformation
   // matrix stored by the geometry manager (allows for misaligned
   // geometry)
-
-//  if(ind>=0 && ind < fEMCGeometry->GetNumberOfSuperModules()) {
-//    TString volpath = "ALIC_1/XEN1_1/SMOD_";
-//    volpath += ind+1;
-//
-//    if(fKey110DEG && ind>=10) {
-//      volpath = "ALIC_1/XEN1_1/SM10_";
-//      volpath += ind-10+1;
-//    }
-//
-//    if(!gGeoManager->cd(volpath.Data()))
-//      AliFatal(Form("AliEMCALGeometry::GeoManager cannot find path %s!",volpath.Data()));
-//
-//    TGeoHMatrix* m = gGeoManager->GetCurrentMatrix();
        
        const TGeoHMatrix* m = GetMatrixForSuperModule(ind);
     if(m) {
@@ -232,7 +235,6 @@ void AliEMCALGeoUtils::GetGlobal(const Double_t *loc, Double_t *glob, int ind) c
     } else {
       AliFatal("Geo matrixes are not loaded \n") ;
     }
-//  }
 }
 
 //________________________________________________________________________________________________
@@ -252,29 +254,13 @@ void AliEMCALGeoUtils::GetGlobal(const TVector3 &vloc, TVector3 &vglob, int ind)
 void AliEMCALGeoUtils::GetGlobal(Int_t absId , double glob[3]) const
 {
   // Alice numbering scheme - Jun 03, 2006
-  static Int_t nSupMod, nModule, nIphi, nIeta;
+  static Int_t nSupMod=-1, nModule=-1, nIphi=-1, nIeta=-1;
   static double loc[3];
 
-  if (!gGeoManager || !gGeoManager->IsClosed()) {
-    AliError("Can't get the global coordinates! gGeoManager doesn't exist or it is still open!");
-    return;
-  }
-
   glob[0]=glob[1]=glob[2]=0.0; // bad case
   if(RelPosCellInSModule(absId, loc)) {
     GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
 
-//    TString volpath = "ALIC_1/XEN1_1/SMOD_";
-//    volpath += (nSupMod+1);
-//
-//    if(fKey110DEG && nSupMod>=10) {
-//      volpath = "ALIC_1/XEN1_1/SM10_";
-//      volpath += (nSupMod-10+1);
-//    }
-//    if(!gGeoManager->cd(volpath.Data()))
-//      AliFatal(Form("GeoManager cannot find path %s!",volpath.Data()));
-//
-//    TGeoHMatrix* m = gGeoManager->GetCurrentMatrix();
          const TGeoHMatrix* m = GetMatrixForSuperModule(nSupMod);
          if(m) {
       m->LocalToMaster(loc, glob);
@@ -315,6 +301,16 @@ void AliEMCALGeoUtils::PrintCellIndexes(Int_t absId, int pri, const char *tit) c
   }
 }
 
+void AliEMCALGeoUtils::PrintLocalTrd1(Int_t pri) const
+{
+  // For comparing with numbers from drawing
+  for(Int_t i=0; i<GetShishKebabTrd1Modules()->GetSize(); i++){
+    printf(" %s | ", GetShishKebabModule(i)->GetName());
+    if(i==0 && pri<1) GetShishKebabModule(i)->PrintShish(1);
+    else     GetShishKebabModule(i)->PrintShish(pri);
+  }
+}
+
 //________________________________________________________________________________________________
 void AliEMCALGeoUtils::EtaPhiFromIndex(Int_t absId,Double_t &eta,Double_t &phi) const
 {
@@ -378,7 +374,7 @@ void  AliEMCALGeoUtils::GetModuleIndexesFromCellIndexesInSModule(Int_t nSupMod,
                        Int_t &iphim, Int_t &ietam, Int_t &nModule) const
 {
   // Transition from cell indexes (ieta,iphi) to module indexes (ietam,iphim, nModule)
-  static Int_t nphi;
+  static Int_t nphi=-1;
   nphi  = GetNumberOfModuleInPhiDirection(nSupMod);  
 
   ietam  = ieta/fNETAdiv;
@@ -390,8 +386,8 @@ void  AliEMCALGeoUtils::GetModuleIndexesFromCellIndexesInSModule(Int_t nSupMod,
 Int_t  AliEMCALGeoUtils::GetAbsCellIdFromCellIndexes(Int_t nSupMod, Int_t iphi, Int_t ieta) const
 {
   // Transition from super module number(nSupMod) and cell indexes (ieta,iphi) to absId
-  static Int_t ietam, iphim, nModule;
-  static Int_t nIeta, nIphi; // cell indexes in module
+  static Int_t ietam=-1, iphim=-1, nModule=-1;
+  static Int_t nIeta=-1, nIphi=-1; // cell indexes in module
 
   GetModuleIndexesFromCellIndexesInSModule(nSupMod, iphi, ieta, ietam, iphim, nModule);
 
@@ -407,12 +403,16 @@ Bool_t AliEMCALGeoUtils::SuperModuleNumberFromEtaPhi(Double_t eta, Double_t phi,
 { 
   // Return false if phi belongs a phi cracks between SM
  
-  static Int_t i;
+  static Int_t i=0;
 
   if(TMath::Abs(eta) > fEtaMaxOfTRD1) return kFALSE;
 
   phi = TVector2::Phi_0_2pi(phi); // move phi to (0,2pi) boundaries
   for(i=0; i<6; i++) {
+       
+       //Check if it is not the complete geometry
+       if (i >= fEMCGeometry->GetNumberOfSuperModules()/2) return kFALSE;
+
     if(phi>=fPhiBoundariesOfSM[2*i] && phi<=fPhiBoundariesOfSM[2*i+1]) {
       nSupMod = 2*i;
       if(eta < 0.0) nSupMod++;
@@ -429,8 +429,8 @@ Bool_t AliEMCALGeoUtils::GetAbsCellIdFromEtaPhi(Double_t eta, Double_t phi, Int_
 {
   // Nov 17,2006
   // stay here - phi problem as usual 
-  static Int_t nSupMod, i, ieta, iphi, etaShift, nphi;
-  static Double_t absEta=0.0, d=0.0, dmin=0.0, phiLoc;
+  static Int_t nSupMod=-1, i=0, ieta=-1, iphi=-1, etaShift=0, nphi=-1;
+  static Double_t absEta=0.0, d=0.0, dmin=0.0, phiLoc=0;
   absId = nSupMod = - 1;
   if(SuperModuleNumberFromEtaPhi(eta, phi, nSupMod)) {
     // phi index first
@@ -469,6 +469,17 @@ Bool_t AliEMCALGeoUtils::GetAbsCellIdFromEtaPhi(Double_t eta, Double_t phi, Int_
     AliDebug(2,Form(" ieta %i : dmin %f (eta=%f) : nSupMod %i ", ieta, dmin, eta, nSupMod));
 
     if(eta<0) iphi = (nphi-1) - iphi;
+         
+       //patch for mapping following alice convention  
+       if(nSupMod%2 == 0)                
+                 ieta = (fCentersOfCellsEtaDir.GetSize()-1)-ieta;// 47-ieta, revert the ordering on A side in order to keep convention.
+       else {
+               if(nSupMod<10) 
+                               iphi = (fCentersOfCellsPhiDir.GetSize()-1)  -iphi;// 23-iphi, revert the ordering on C side in order to keep convention.
+               else 
+                               iphi = (fCentersOfCellsPhiDir.GetSize()/2-1)-iphi;// 11-iphi, revert the ordering on C side in order to keep convention.
+       }
+  
     absId = GetAbsCellIdFromCellIndexes(nSupMod, iphi, ieta);
 
     return kTRUE;
@@ -524,7 +535,7 @@ Int_t  AliEMCALGeoUtils::GetSuperModuleNumber(Int_t absId)  const
   // Return the number of the  supermodule given the absolute
   // ALICE numbering id
 
-  static Int_t nSupMod, nModule, nIphi, nIeta;
+  static Int_t nSupMod=-1, nModule=-1, nIphi=-1, nIeta=-1;
   GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
   return nSupMod;
 } 
@@ -537,7 +548,7 @@ void AliEMCALGeoUtils::GetModulePhiEtaIndexInSModule(Int_t nSupMod, Int_t nModul
   // ietam, iphi - indexes of module in two dimensional grid of SM
   // ietam - have to change from 0 to fNZ-1
   // iphim - have to change from 0 to nphi-1 (fNPhi-1 or fNPhi/2-1)
-  static Int_t nphi;
+  static Int_t nphi=-1;
 
   if(fKey110DEG == 1 && nSupMod>=10) nphi = fNPhi/2;
   else                               nphi = fNPhi;
@@ -564,7 +575,7 @@ int &iphi, int &ieta) const
   // ieta - have to change from 0 to (fNZ*fNETAdiv-1)
   // iphi - have to change from 0 to (fNPhi*fNPHIdiv-1 or fNPhi*fNPHIdiv/2-1)
   //
-  static Int_t iphim, ietam;
+  static Int_t iphim=-1, ietam=-1;
 
   GetModulePhiEtaIndexInSModule(nSupMod,nModule, iphim, ietam); 
   //  ieta  = ietam*fNETAdiv + (1-nIeta); // x(module) = -z(SM) 
@@ -593,7 +604,7 @@ Bool_t AliEMCALGeoUtils::RelPosCellInSModule(Int_t absId, Double_t &xr, Double_t
   // Shift index taking into account the difference between standard SM 
   // and SM of half size in phi direction
   const Int_t kphiIndexShift = fCentersOfCellsPhiDir.GetSize()/4; // Nov 22, 2006; was 6 for cas 2X2
-  static Int_t nSupMod, nModule, nIphi, nIeta, iphi, ieta;
+  static Int_t nSupMod=-1, nModule=-1, nIphi=-1, nIeta=-1, iphi=-1, ieta=-1;
   if(!CheckAbsCellId(absId)) return kFALSE;
 
   GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
@@ -659,6 +670,7 @@ void AliEMCALGeoUtils::CreateListOfTrd1Modules()
   // Generate the list of Trd1 modules
   // which will make up the EMCAL
   // geometry
+  // key: look to the AliEMCALShishKebabTrd1Module::
 
   AliDebug(2,Form(" AliEMCALGeometry::CreateListOfTrd1Modules() started "));
 
@@ -785,7 +797,7 @@ AliEMCALShishKebabTrd1Module* AliEMCALGeoUtils::GetShishKebabModule(Int_t neta)
 }
 
 //___________________________________________________________________
-void AliEMCALGeoUtils::PrintGeometry()
+void AliEMCALGeoUtils::PrintGeometryGeoUtils()
 {
   //Print information from geometry
   fEMCGeometry->PrintGeometry();
@@ -825,7 +837,7 @@ Bool_t  AliEMCALGeoUtils::Impact(const TParticle * particle) const
   TVector3 vtx(particle->Vx(),particle->Vy(),particle->Vz());
   TVector3 vimpact(0,0,0);
   ImpactOnEmcal(vtx,particle->Theta(),particle->Phi(),absID,vimpact);
-  if(absID!=0) 
+  if(absID>=0) 
     in=kTRUE;
   return in;
 }
@@ -843,18 +855,15 @@ void AliEMCALGeoUtils::ImpactOnEmcal(TVector3 vtx, Double_t theta, Double_t phi,
   absId=-1;
   if(phi==0 || theta==0) return;
 
-   TVector3 direction;
-   Double_t factor = (fIPDistance-vtx[1])/p[1];
+  TVector3 direction;
+  Double_t factor = (fIPDistance-vtx[1])/p[1];
   direction = vtx + factor*p;
 
-  if (!gGeoManager){
-    AliFatal("Geo manager not initialized\n");
-  }
   //from particle direction -> tower hitted
   GetAbsCellIdFromEtaPhi(direction.Eta(),direction.Phi(),absId);
   
   //tower absID hitted -> tower/module plane (evaluated at the center of the tower)
-  Int_t nSupMod, nModule, nIphi, nIeta;
+  Int_t nSupMod=-1, nModule=-1, nIphi=-1, nIeta=-1;
   Double_t loc[3],loc2[3],loc3[3];
   Double_t glob[3]={},glob2[3]={},glob3[3]={};
   
@@ -864,7 +873,7 @@ void AliEMCALGeoUtils::ImpactOnEmcal(TVector3 vtx, Double_t theta, Double_t phi,
   GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
 
   //look at 2 neighbours-s cell using nIphi={0,1} and nIeta={0,1}
-  Int_t nIphi2,nIeta2,absId2,absId3;
+  Int_t nIphi2=-1,nIeta2=-1,absId2=-1,absId3=-1;
   if(nIeta==0) nIeta2=1;
   else nIeta2=0;
   absId2=GetAbsCellId(nSupMod,nModule,nIphi,nIeta2);  
@@ -878,18 +887,7 @@ void AliEMCALGeoUtils::ImpactOnEmcal(TVector3 vtx, Double_t theta, Double_t phi,
   //3rd point on emcal cell plane
   if(!RelPosCellInSModule(absId3,loc3)) return;
     
-//  TString volpath = "ALIC_1/XEN1_1/SMOD_";
-//  volpath += (nSupMod+1);
-//  
-//  if(fKey110DEG && nSupMod>=10) {
-//    volpath = "ALIC_1/XEN1_1/SM10_";
-//    volpath += (nSupMod-10+1);
-//  }
-//  if(!gGeoManager->cd(volpath.Data())){
-//    AliFatal(Form("GeoManager cannot find path %s!",volpath.Data()))
-//    return;
-//  }
-//  TGeoHMatrix* m = gGeoManager->GetCurrentMatrix();
+  // Get Matrix
   const TGeoHMatrix* m = GetMatrixForSuperModule(nSupMod);
   if(m) {
     m->LocalToMaster(loc, glob);
@@ -980,13 +978,17 @@ Int_t AliEMCALGeoUtils::GetAbsTRUNumberFromNumberInSm(const Int_t row, const Int
 //________________________________________________________________________________________________
 Bool_t AliEMCALGeoUtils::GetAbsFastORIndexFromTRU(const Int_t iTRU, const Int_t iADC, Int_t& id) const
 {
-    if (iTRU > 31 || iTRU < 0 || iADC > 95 || iADC < 0) 
+       //Trigger mapping method, get  FastOr Index from TRU
+
+  if (iTRU > 31 || iTRU < 0 || iADC > 95 || iADC < 0) 
        {
                AliError("TRU out of range!");
                return kFALSE;
        }
-                                
-       id = iADC + iTRU * 96;
+       
+       id  = ( iTRU % 2 ) ? iADC%4 + 4 * (23 - int(iADC/4)) : (3 - iADC%4) + 4 * int(iADC/4);
+
+       id += iTRU * 96;
        
        return kTRUE;
 }
@@ -994,6 +996,9 @@ Bool_t AliEMCALGeoUtils::GetAbsFastORIndexFromTRU(const Int_t iTRU, const Int_t
 //________________________________________________________________________________________________
 Bool_t AliEMCALGeoUtils::GetTRUFromAbsFastORIndex(const Int_t id, Int_t& iTRU, Int_t& iADC) const
 {
+
+       //Trigger mapping method, get TRU number from FastOr Index
+
        if (id > 3071 || id < 0)
        {
                AliError("Id out of range!");
@@ -1001,29 +1006,31 @@ Bool_t AliEMCALGeoUtils::GetTRUFromAbsFastORIndex(const Int_t id, Int_t& iTRU, I
        }
        
        iTRU = id / 96;
+       
        iADC = id % 96;
        
+       iADC = ( iTRU % 2 ) ? iADC%4 + 4 * (23 - int(iADC/4)) : (3 - iADC%4) + 4 * int(iADC/4);
+       
        return kTRUE;
 }
 
 //________________________________________________________________________________________________
 Bool_t AliEMCALGeoUtils::GetPositionInTRUFromAbsFastORIndex(const Int_t id, Int_t& iTRU, Int_t& iEta, Int_t& iPhi) const
 {
-       Int_t iADC;
-       
-       Bool_t isOK = GetTRUFromAbsFastORIndex(id, iTRU, iADC);
+       //Trigger mapping method, get position in TRU from FasOr Index
        
-       if (!isOK) return kFALSE;
+       Int_t iADC=-1;  
+       if (!GetTRUFromAbsFastORIndex(id, iTRU, iADC)) return kFALSE;
        
        Int_t x = iADC / 4;
        Int_t y = iADC % 4;
        
-       if ( int( iTRU / 3 ) % 2 ) // C side 
+       if ( iTRU % 2 ) // C side 
        {
                iEta = 23 - x;
                iPhi =      y;
        }
-       else                       // A side
+       else            // A side
        {
                iEta =      x;
                iPhi =  3 - y;
@@ -1035,37 +1042,234 @@ Bool_t AliEMCALGeoUtils::GetPositionInTRUFromAbsFastORIndex(const Int_t id, Int_
 //________________________________________________________________________________________________
 Bool_t AliEMCALGeoUtils::GetPositionInSMFromAbsFastORIndex(const Int_t id, Int_t& iSM, Int_t& iEta, Int_t& iPhi) const
 {
-       Int_t iTRU;
-       Bool_t isOK = GetPositionInTRUFromAbsFastORIndex(id, iTRU, iEta, iPhi);
+       //Trigger mapping method, get position in Super Module from FasOr Index
+
+       Int_t iTRU=-1;
+               
+       if (!GetPositionInTRUFromAbsFastORIndex(id, iTRU, iEta, iPhi)) return kFALSE;
        
-       if (!isOK) return kFALSE;
+       if (iTRU % 2) // C side
+       {
+               iSM  = 2 * ( int( int(iTRU / 2) / 3 ) ) + 1;
+       }
+       else            // A side
+       {
+               iSM  = 2 * ( int( int(iTRU / 2) / 3 ) );
+       }
+
+       iPhi += 4 * int((iTRU % 6) / 2);
        
-       iSM  = iTRU / 3;
+       return kTRUE;
+}
+
+//________________________________________________________________________________________________
+Bool_t AliEMCALGeoUtils::GetPositionInEMCALFromAbsFastORIndex(const Int_t id, Int_t& iEta, Int_t& iPhi) const
+{
+  //Trigger mapping method, get position in EMCAL from FastOR index
+
+       Int_t iSM=-1;
        
-       if ( int( iTRU / 3 ) % 2 ) // C side
+       if (GetPositionInSMFromAbsFastORIndex(id, iSM, iEta, iPhi))
        {
-               iPhi = iPhi + 4 * ( 2 - ( iTRU % 3 ) );
+               if (iSM % 2) iEta += 24; 
+               
+               iPhi += 12 * int(iSM / 2);
+               
+               return kTRUE;
        }
-       else                       // A side
+       
+       return kFALSE;
+}
+
+//________________________________________________________________________________________________
+Bool_t AliEMCALGeoUtils::GetAbsFastORIndexFromPositionInTRU(const Int_t iTRU, const Int_t iEta, const Int_t iPhi, Int_t& id) const
+{
+       //Trigger mapping method, get Index if FastOr from Position in TRU
+
+       if (iTRU < 0 || iTRU > 31 || iEta < 0 || iEta > 23 || iPhi < 0 || iPhi > 3) 
        {
-               iPhi = iPhi + 4 * (       iTRU % 3   );
+               AliError("Out of range!");      
+               return kFALSE;
        }
        
+       id =  iPhi  + 4 * iEta + iTRU * 96;
+       
        return kTRUE;
 }
 
 //________________________________________________________________________________________________
-Bool_t AliEMCALGeoUtils::GetAbsFastORIndexFromPositionInTRU(const Int_t iTRU, const Int_t iEta, const Int_t iPhi, Int_t& id) const
+Bool_t AliEMCALGeoUtils::GetAbsFastORIndexFromPositionInSM(const Int_t  iSM, const Int_t iEta, const Int_t iPhi, Int_t& id) const
 {
-       if (iTRU < 0 || iTRU > 31 || iEta < 0 || iEta > 23 || iPhi < 0 || iPhi > 3) return kFALSE;
+  //Trigger mapping method, from position in SM Index get FastOR index 
+
+       if (iSM < 0 || iSM > 11 || iEta < 0 || iEta > 23 || iPhi < 0 || iPhi > 11) 
+       {
+               AliError("Out of range!");
+               return kFALSE;
+       }
+       
+       Int_t x = iEta;
+       Int_t y = iPhi % 4;     
        
-       if ( int( iTRU / 3 ) % 2 ) // C side
+       Int_t iOff = (iSM % 2) ? 1 : 0;
+       Int_t iTRU = 2 * int(iPhi / 4) + 6 * int(iSM / 2) + iOff;
+
+       if (GetAbsFastORIndexFromPositionInTRU(iTRU, x, y, id))
+       {
+               return kTRUE;
+       }
+       
+       return kFALSE;
+}
+
+//________________________________________________________________________________________________
+Bool_t AliEMCALGeoUtils::GetAbsFastORIndexFromPositionInEMCAL(const Int_t iEta, const Int_t iPhi, Int_t& id) const
+{
+  //Trigger mapping method, from position in EMCAL Index get FastOR index 
+
+       if (iEta < 0 || iEta > 47 || iPhi < 0 || iPhi > 63 ) 
        {
-               id =      iPhi  + 4 * ( 23 - iEta ) + iTRU * 96;
+               AliError("Out of range!");
+               return kFALSE;
        }
-       else 
+       
+       if (fFastOR2DMap[iEta][iPhi] == -1) 
        {
-               id = (3 - iPhi) + 4 *        iEta + iTRU * 96;
+               AliError("Invalid index!");
+               return kFALSE;
+       }
+       
+       id = fFastOR2DMap[iEta][iPhi];
+       
+       return kTRUE;
+}
+
+//________________________________________________________________________________________________
+Bool_t AliEMCALGeoUtils::GetFastORIndexFromCellIndex(const Int_t id, Int_t& idx) const
+{
+  //Trigger mapping method, from cell index get FastOR index 
+
+       Int_t iSupMod, nModule, nIphi, nIeta, iphim, ietam;
+       
+       Bool_t isOK = GetCellIndex( id, iSupMod, nModule, nIphi, nIeta );
+       
+       GetModulePhiEtaIndexInSModule( iSupMod, nModule, iphim, ietam );
+       
+       if (isOK && GetAbsFastORIndexFromPositionInSM(iSupMod, ietam, iphim, idx))
+       {
+               return kTRUE;
+       }
+       
+       return kFALSE;
+}
+
+//________________________________________________________________________________________________
+Bool_t AliEMCALGeoUtils::GetCellIndexFromFastORIndex(const Int_t id, Int_t idx[4]) const
+{
+  //Trigger mapping method, from FASTOR index get cell index 
+
+  Int_t iSM=-1, iEta=-1, iPhi=-1;
+       if (GetPositionInSMFromAbsFastORIndex(id, iSM, iEta, iPhi))
+       {
+               Int_t ix = 2 * iEta;
+               Int_t iy = 2 * iPhi;
+               
+               for (Int_t i=0; i<2; i++)
+               {
+                       for (Int_t j=0; j<2; j++)
+                       {
+                               idx[2*i+j] = GetAbsCellIdFromCellIndexes(iSM, iy + i, ix + j);
+                       }
+               }
+               
+               return kTRUE;
+       }
+       
+       return kFALSE;
+}
+
+//________________________________________________________________________________________________
+Bool_t AliEMCALGeoUtils::GetTRUIndexFromSTUIndex(const Int_t id, Int_t& idx) const
+{
+  //Trigger mapping method, from STU index get TRU index 
+
+       if (id > 31 || id < 0) 
+       {
+               AliError(Form("TRU index out of range: %d",id));
+               return kFALSE;
+       }
+       
+       idx = (id > 15) ? 2 * (31 - id) : 2 * (15 - id) + 1;
+       
+       return kTRUE;
+}
+
+//________________________________________________________________________________________________
+Int_t AliEMCALGeoUtils::GetTRUIndexFromSTUIndex(const Int_t id) const
+{
+  //Trigger mapping method, from STU index get TRU index 
+
+       if (id > 31 || id < 0) 
+       {
+               AliError(Form("TRU index out of range: %d",id));
+       }
+       
+       Int_t idx = (id > 15) ? 2 * (31 - id) : 2 * (15 - id) + 1;
+       
+       return idx;
+}
+
+//________________________________________________________________________________________________
+void AliEMCALGeoUtils::BuildFastOR2DMap()
+{
+       // Needed by STU
+       for (Int_t i = 0; i < 32; i++)
+       {
+               for (Int_t j = 0; j < 24; j++)
+               {
+                       for (Int_t k = 0; k < 4; k++)
+                       {
+                               Int_t id;
+                               if (GetAbsFastORIndexFromPositionInTRU(i, j, k, id))
+                               {
+                                       Int_t x = j, y = k + 4 * int(i / 2);
+                               
+                                       if (i % 2) x += 24;
+                               
+                                       fFastOR2DMap[x][y] = id;
+                               }
+                       }                       
+               }
+       }
+}
+
+//________________________________________________________________________________________________
+Bool_t AliEMCALGeoUtils::GetFastORIndexFromL0Index(const Int_t iTRU, const Int_t id, Int_t idx[], const Int_t size) const
+{
+  //Trigger mapping method, from L0 index get FastOR index 
+       if (size <= 0 ||size > 4)
+       {
+               AliError("Size not supported!");
+               return kFALSE;
+       }
+               
+       Int_t motif[4] = {0, 1, 4, 5};
+       
+       switch (size)
+       {
+               case 1: // Cosmic trigger
+                       if (!GetAbsFastORIndexFromTRU(iTRU, id, idx[1])) return kFALSE;
+                       break;
+               case 4: // 4 x 4
+                       for (Int_t k = 0; k < 4; k++)
+                       {
+                               Int_t iADC = motif[k] + 4 * int(id / 3) + (id % 3);
+                               
+                               if (!GetAbsFastORIndexFromTRU(iTRU, iADC, idx[k])) return kFALSE;
+                       }
+                       break;
+               default:
+                       break;
        }
        
        return kTRUE;
@@ -1073,6 +1277,7 @@ Bool_t AliEMCALGeoUtils::GetAbsFastORIndexFromPositionInTRU(const Int_t iTRU, co
 
 //____________________________________________________________________________
 const TGeoHMatrix * AliEMCALGeoUtils::GetMatrixForSuperModule(Int_t smod) const {
+
        //Provides shift-rotation matrix for EMCAL
        
        if(smod < 0 || smod > fEMCGeometry->GetNumberOfSuperModules()) 
@@ -1090,13 +1295,14 @@ const TGeoHMatrix * AliEMCALGeoUtils::GetMatrixForSuperModule(Int_t smod) const
        //    TGeoHMatrix* m = gGeoManager->GetCurrentMatrix();
        
        if(gGeoManager){
-               char path[255] ;
-               sprintf(path,"/ALIC_1/XEN1_1/SMOD_%d",smod+1) ;
+    const Int_t buffersize = 255;
+               char path[buffersize] ;
+               snprintf(path,buffersize,"/ALIC_1/XEN1_1/SMOD_%d",smod+1) ;
                //TString volpath = "ALIC_1/XEN1_1/SMOD_";
            //volpath += smod+1;
 
                if(fKey110DEG && smod >= 10){
-                         sprintf(path,"/ALIC_1/XEN1_1/SM10_%d",smod-10+1) ;
+                         snprintf(path,buffersize,"/ALIC_1/XEN1_1/SM10_%d",smod-10+1) ;
                        //volpath = "ALIC_1/XEN1_1/SM10_";
                        //volpath += smod-10+1;
                }
@@ -1105,15 +1311,16 @@ const TGeoHMatrix * AliEMCALGeoUtils::GetMatrixForSuperModule(Int_t smod) const
                }
                return gGeoManager->GetCurrentMatrix();
        }
-       
+
        if(fkSModuleMatrix[smod]){
                return fkSModuleMatrix[smod] ;
        }
        else{
-               printf("Can not find EMCAL misalignment matrixes\n") ;
-               printf("Either import TGeoManager from geometry.root or \n");
-               printf("read stored matrixes from AliESD Header:  \n") ;   
-               printf("AliEMCALGeoUtils::SetMisalMatrixes(header->GetEMCALMisalMatrix()) \n") ;
+               AliInfo("Stop:");
+               printf("\t Can not find EMCAL misalignment matrixes\n") ;
+               printf("\t Either import TGeoManager from geometry.root or \n");
+               printf("\t read stored matrixes from AliESD Header:  \n") ;   
+               printf("\t AliEMCALGeoUtils::SetMisalMatrixes(header->GetEMCALMisalMatrix()) \n") ;
                abort() ;
        }
        return 0 ;
@@ -1137,3 +1344,141 @@ void AliEMCALGeoUtils::GetModulePhiEtaIndexInSModuleFromTRUIndex(Int_t itru, Int
   //printf(" GetModulePhiEtaIndexInSModuleFromTRUIndex : itru %2i iphitru %2i ietatru %2i iphiSM %2i ietaSM %2i \n", 
   // itru, iphitru, ietatru, iphiSM, ietaSM);
 }
+
+//__________________________________________________________________________________________________________________
+void AliEMCALGeoUtils::RecalculateTowerPosition(Float_t drow, Float_t dcol, const Int_t sm, const Float_t depth,
+                                                const Float_t misaligTransShifts[15], const Float_t misaligRotShifts[15], Float_t global[3]) const
+{ //Transform clusters cell position into global with alternative method, taking into account the depth calculation.
+  //Input are: the tower indeces, 
+  //           supermodule, 
+  //           particle type (photon 0, electron 1, hadron 2 )
+  //           misalignment shifts to global position in case of need.
+  // Federico.Ronchetti@cern.ch
+  
+    
+  // To use in a print later
+  Int_t droworg = drow;
+  Int_t dcolorg = dcol;
+  
+  if(gGeoManager){
+    //Recover some stuff
+    
+    gGeoManager->cd("ALIC_1/XEN1_1");
+    TGeoNode        *geoXEn1 = gGeoManager->GetCurrentNode();
+    TGeoNodeMatrix  *geoSM[4];        
+    TGeoVolume      *geoSMVol[4];     
+    TGeoShape       *geoSMShape[4];    
+    TGeoBBox        *geoBox[4];        
+    TGeoMatrix      *geoSMMatrix[4];       
+    
+    for(int iSM = 0; iSM < 4; iSM++) {  
+      geoSM[iSM]       = dynamic_cast<TGeoNodeMatrix *>(geoXEn1->GetDaughter(iSM));
+      geoSMVol[iSM]    = geoSM[iSM]->GetVolume(); 
+      geoSMShape[iSM]  = geoSMVol[iSM]->GetShape();
+      geoBox[iSM]      = dynamic_cast<TGeoBBox *>(geoSMShape[iSM]);
+      geoSMMatrix[iSM] = geoSM[iSM]->GetMatrix();
+    }
+    
+    if(sm % 2 == 0) {
+      dcol = 47. - dcol;
+      drow = 23. - drow;
+    }
+    
+    Int_t istrip = 0;
+    Float_t z0   = 0;
+    Float_t zb   = 0;
+    Float_t z_is = 0;
+    
+    Float_t x,y,z; // return variables in terry's RF
+    
+    //***********************************************************
+    //Do not like this: too many hardcoded values, is it not already stored somewhere else?
+    //                : need more comments in the code 
+    //***********************************************************
+    
+    Float_t dz = 6.0;   // base cell width in eta
+    Float_t dx = 6.004; // base cell width in phi
+    
+    
+    //Float_t L = 26.04; // active tower length for hadron (lead+scint+paper)
+    // we use the geant numbers 13.87*2=27.74
+    Float_t teta1 = 0.;
+      
+    //Do some basic checks
+    if (dcol >= 47.5 || dcol<-0.5) {
+      AliError(Form("Bad tower coordinate dcol=%d, where dcol >= 47.5 || dcol<-0.5; org: %d", dcol, dcolorg));
+      return;
+    }
+    if (drow >= 23.5 || drow<-0.5) {
+      AliError(Form("Bad tower coordinate drow=%d, where drow >= 23.5 || drow<-0.5; org: %d", drow, droworg));
+      return;
+    }
+    if (sm > 11 || sm <0) {
+      AliError(Form("Bad SM number sm=%d, where sm > 11 || sm<0", sm));
+      return;
+    }    
+    
+    istrip = int ((dcol+0.5)/2);
+    
+    // tapering angle
+    teta1 = TMath::DegToRad() * istrip * 1.5;
+    
+    // calculation of module corner along z 
+    // as a function of strip
+    
+    for (int is=0; is<= istrip; is++) {
+      
+      teta1 = TMath::DegToRad() * (is*1.5 + 0.75);
+      if(is==0)
+        z_is = z_is + 2*dz*TMath::Cos(teta1);
+      else
+        z_is = z_is + 2*dz*TMath::Cos(teta1) + 2*dz*TMath::Sin(teta1)*TMath::Tan(teta1-0.75*TMath::DegToRad());
+      
+    }
+    
+    z0 = dz*(dcol-2*istrip+0.5);
+    zb = (2*dz-z0-depth*TMath::Tan(teta1));
+    
+    z = z_is - zb*TMath::Cos(teta1);
+    y = depth/TMath::Cos(teta1) + zb*TMath::Sin(teta1);
+    
+    x = (drow + 0.5)*dx;
+    
+    // moving the origin from terry's RF
+    // to the GEANT one
+    
+    double xx =  y - geoBox[sm]->GetDX();
+    double yy = -x + geoBox[sm]->GetDY(); 
+    double zz =  z - geoBox[sm]->GetDZ(); 
+    const double localIn[3] = {xx, yy, zz};
+    double dglobal[3];
+    //geoSMMatrix[sm]->Print();
+    //printf("TFF Local    (row = %d, col = %d, x = %3.2f,  y = %3.2f, z = %3.2f)\n", iroworg, icolorg, localIn[0], localIn[1], localIn[2]);
+    geoSMMatrix[sm]->LocalToMaster(localIn, dglobal);
+    //printf("TFF Global   (row = %2.0f, col = %2.0f, x = %3.2f,  y = %3.2f, z = %3.2f)\n", drow, dcol, dglobal[0], dglobal[1], dglobal[2]);
+    
+    //apply global shifts
+    if(sm == 2 || sm == 3) {//sector 1
+      global[0] = dglobal[0] + misaligTransShifts[3] + misaligRotShifts[3]*TMath::Sin(TMath::DegToRad()*20) ; 
+      global[1] = dglobal[1] + misaligTransShifts[4] + misaligRotShifts[4]*TMath::Cos(TMath::DegToRad()*20) ; 
+      global[2] = dglobal[2] + misaligTransShifts[5];
+    }
+    else if(sm == 0 || sm == 1){//sector 0
+      global[0] = dglobal[0] + misaligTransShifts[0]; 
+      global[1] = dglobal[1] + misaligTransShifts[1]; 
+      global[2] = dglobal[2] + misaligTransShifts[2];
+    }
+    else {
+      AliInfo("Careful, correction not implemented yet!");
+      global[0] = dglobal[0] ;
+      global[1] = dglobal[1] ;
+      global[2] = dglobal[2] ;
+    }
+    
+    
+  }
+  else{
+    AliFatal("Geometry boxes information, check that geometry.root is loaded\n");
+  }
+  
+}