]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - STEER/AliGeomManager.cxx
Combining standard and sampling TGeo overlap checking in one AliGeomManager method...
[u/mrichter/AliRoot.git] / STEER / AliGeomManager.cxx
index 07373de4ca920557ec649ebf2a098c49a67a4271..31c3e35b4a4599c1a04cf758c6a21d0dd1b04a80 100644 (file)
 #include <TGeoMatrix.h>
 #include <TGeoPhysicalNode.h>
 #include <TSystem.h>
 #include <TGeoMatrix.h>
 #include <TGeoPhysicalNode.h>
 #include <TSystem.h>
+#include <TStopwatch.h>
+#include <TGeoOverlap.h>
+#include <TPluginManager.h>
+#include <TROOT.h>
 
 #include "AliGeomManager.h"
 #include "AliLog.h"
 #include "AliAlignObj.h"
 
 #include "AliGeomManager.h"
 #include "AliLog.h"
 #include "AliAlignObj.h"
-#include "AliAlignObjAngles.h"
+#include "AliAlignObjParams.h"
 #include "AliCDBManager.h"
 #include "AliCDBStorage.h"
 #include "AliCDBEntry.h"
 #include "AliCDBManager.h"
 #include "AliCDBStorage.h"
 #include "AliCDBEntry.h"
@@ -48,7 +52,8 @@ Int_t AliGeomManager::fgLayerSize[kLastLayer - kFirstLayer] = {
   1638,     // TOF
   5, 5,     // PHOS,CPV
   7,        // HMPID ??
   1638,     // TOF
   5, 5,     // PHOS,CPV
   7,        // HMPID ??
-  1         // MUON ??
+  1,         // MUON ??
+  12        // EMCAL
 };
 
 const char* AliGeomManager::fgLayerName[kLastLayer - kFirstLayer] = {
 };
 
 const char* AliGeomManager::fgLayerName[kLastLayer - kFirstLayer] = {
@@ -60,21 +65,9 @@ const char* AliGeomManager::fgLayerName[kLastLayer - kFirstLayer] = {
   "TRD chambers layer 4", "TRD chambers layer 5", "TRD chambers layer 6",
   "TOF layer",
   "PHOS EMC layer","PHOS CPV layer",
   "TRD chambers layer 4", "TRD chambers layer 5", "TRD chambers layer 6",
   "TOF layer",
   "PHOS EMC layer","PHOS CPV layer",
-  "HMPID layer",
-  "?"
-};
-
-TString* AliGeomManager::fgSymName[kLastLayer - kFirstLayer] = {
-  0x0,0x0,
-  0x0,0x0,
-  0x0,0x0,
-  0x0,0x0,
-  0x0,0x0,0x0,
-  0x0,0x0,0x0,
-  0x0,
-  0x0,0x0,
-  0x0,
-  0x0
+  "HMPID layer", 
+  "MUON ?",
+  "EMCAL layer"
 };
 
 TGeoPNEntry** AliGeomManager::fgPNEntry[kLastLayer - kFirstLayer] = {
 };
 
 TGeoPNEntry** AliGeomManager::fgPNEntry[kLastLayer - kFirstLayer] = {
@@ -87,18 +80,6 @@ TGeoPNEntry** AliGeomManager::fgPNEntry[kLastLayer - kFirstLayer] = {
   0x0,
   0x0,0x0,
   0x0,
   0x0,
   0x0,0x0,
   0x0,
-  0x0
-};
-
-TGeoHMatrix** AliGeomManager::fgOrigMatrix[kLastLayer - kFirstLayer] = {
-  0x0,0x0,
-  0x0,0x0,
-  0x0,0x0,
-  0x0,0x0,
-  0x0,0x0,0x0,
-  0x0,0x0,0x0,
-  0x0,
-  0x0,0x0,
   0x0,
   0x0
 };
   0x0,
   0x0
 };
@@ -113,6 +94,7 @@ AliAlignObj** AliGeomManager::fgAlignObjs[kLastLayer - kFirstLayer] = {
   0x0,
   0x0,0x0,
   0x0,
   0x0,
   0x0,0x0,
   0x0,
+  0x0,
   0x0
 };
 
   0x0
 };
 
@@ -126,14 +108,12 @@ void AliGeomManager::LoadGeometry(const char *geomFileName)
   // or from the corresponding CDB entry
 
   fgGeometry = NULL;
   // or from the corresponding CDB entry
 
   fgGeometry = NULL;
-  if (geomFileName && (!gSystem->AccessPathName(geomFileName))) { // gemotry.root exists
+  if (geomFileName && (!gSystem->AccessPathName(geomFileName))) {
     fgGeometry = TGeoManager::Import(geomFileName);
     fgGeometry = TGeoManager::Import(geomFileName);
-    AliInfoClass("Using custom geometry.root file");
+    AliInfoClass(Form("From now on using geometry from custom geometry file %s",geomFileName));
   }
 
   if (!fgGeometry) {
   }
 
   if (!fgGeometry) {
-    AliInfoClass("Using geometry from CDB");
-
     AliCDBPath path("GRP","Geometry","Data");
        
     AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
     AliCDBPath path("GRP","Geometry","Data");
        
     AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
@@ -142,11 +122,12 @@ void AliGeomManager::LoadGeometry(const char *geomFileName)
     entry->SetOwner(0);
     fgGeometry = (TGeoManager*) entry->GetObject();
     if (!fgGeometry) AliFatalClass("Couldn't find TGeoManager in the specified CDB entry!");
     entry->SetOwner(0);
     fgGeometry = (TGeoManager*) entry->GetObject();
     if (!fgGeometry) AliFatalClass("Couldn't find TGeoManager in the specified CDB entry!");
+    
+    AliInfoClass(Form("From now on using geometry from CDB base folder %s",
+                     AliCDBManager::Instance()->GetURI("Geometry/Align/Data")));
   }
 
   }
 
-  InitSymNamesLUT();
   InitPNEntriesLUT();
   InitPNEntriesLUT();
-  InitOrigMatricesLUT();
 }
 
 //_____________________________________________________________________________
 }
 
 //_____________________________________________________________________________
@@ -156,10 +137,7 @@ void AliGeomManager::SetGeometry(TGeoManager *geom)
   if (!geom) AliFatalClass("Pointer to the active geometry is 0x0!");
 
   fgGeometry = geom;
   if (!geom) AliFatalClass("Pointer to the active geometry is 0x0!");
 
   fgGeometry = geom;
-
-  InitSymNamesLUT();
   InitPNEntriesLUT();
   InitPNEntriesLUT();
-  InitOrigMatricesLUT();
 }
 
 //_____________________________________________________________________________
 }
 
 //_____________________________________________________________________________
@@ -187,7 +165,7 @@ Int_t AliGeomManager::LayerSize(Int_t layerId)
   }
   else {
     return fgLayerSize[layerId - kFirstLayer];
   }
   else {
     return fgLayerSize[layerId - kFirstLayer];
- }
 }
 }
 
 //_____________________________________________________________________________
 }
 
 //_____________________________________________________________________________
@@ -202,7 +180,7 @@ const char* AliGeomManager::LayerName(Int_t layerId)
   }
   else {
     return fgLayerName[layerId - kFirstLayer];
   }
   else {
     return fgLayerName[layerId - kFirstLayer];
- }
 }
 }
 
 //_____________________________________________________________________________
 }
 
 //_____________________________________________________________________________
@@ -404,27 +382,28 @@ Bool_t AliGeomManager::GetFromGeometry(const char *symname, AliAlignObj &alobj)
 //_____________________________________________________________________________
 void  AliGeomManager::InitAlignObjFromGeometry()
 {
 //_____________________________________________________________________________
 void  AliGeomManager::InitAlignObjFromGeometry()
 {
- // Loop over all alignable volumes and extract
- // the corresponding alignment objects from
- // the TGeo geometry
 // Loop over all alignable volumes and extract
 // the corresponding alignment objects from
 // the TGeo geometry
 
   if(fgAlignObjs[0]) return;
 
   if(fgAlignObjs[0]) return;
-  
+
   for (Int_t iLayer = kFirstLayer; iLayer < AliGeomManager::kLastLayer; iLayer++) {
     fgAlignObjs[iLayer-kFirstLayer] = new AliAlignObj*[LayerSize(iLayer)];
     for (Int_t iModule = 0; iModule < LayerSize(iLayer); iModule++) {
       UShort_t volid = LayerToVolUID(iLayer,iModule);
   for (Int_t iLayer = kFirstLayer; iLayer < AliGeomManager::kLastLayer; iLayer++) {
     fgAlignObjs[iLayer-kFirstLayer] = new AliAlignObj*[LayerSize(iLayer)];
     for (Int_t iModule = 0; iModule < LayerSize(iLayer); iModule++) {
       UShort_t volid = LayerToVolUID(iLayer,iModule);
-      fgAlignObjs[iLayer-kFirstLayer][iModule] = new AliAlignObjAngles("",volid,0,0,0,0,0,0,kTRUE);
+      fgAlignObjs[iLayer-kFirstLayer][iModule] = new AliAlignObjParams("",volid,0,0,0,0,0,0,kTRUE);
       const char *symname = SymName(volid);
       if (!GetFromGeometry(symname, *fgAlignObjs[iLayer-kFirstLayer][iModule]))
        AliErrorClass(Form("Failed to extract the alignment object for the volume (ID=%d and path=%s) !",volid,symname));
     }
   }
       const char *symname = SymName(volid);
       if (!GetFromGeometry(symname, *fgAlignObjs[iLayer-kFirstLayer][iModule]))
        AliErrorClass(Form("Failed to extract the alignment object for the volume (ID=%d and path=%s) !",volid,symname));
     }
   }
-  
+
 }
 
 //_____________________________________________________________________________
 }
 
 //_____________________________________________________________________________
-AliAlignObj* AliGeomManager::GetAlignObj(UShort_t voluid) {
+AliAlignObj* AliGeomManager::GetAlignObj(UShort_t voluid)
+{
   // Returns the alignment object for given volume ID
   //
   Int_t modId;
   // Returns the alignment object for given volume ID
   //
   Int_t modId;
@@ -447,7 +426,8 @@ AliAlignObj* AliGeomManager::GetAlignObj(ELayerID layerId, Int_t modId)
 }
 
 //_____________________________________________________________________________
 }
 
 //_____________________________________________________________________________
-const char* AliGeomManager::SymName(UShort_t voluid) {
+const char* AliGeomManager::SymName(UShort_t voluid)
+{
   // Returns the symbolic volume name for given volume ID
   //
   Int_t modId;
   // Returns the symbolic volume name for given volume ID
   //
   Int_t modId;
@@ -461,300 +441,452 @@ const char* AliGeomManager::SymName(ELayerID layerId, Int_t modId)
   // Returns the symbolic volume name given for a given layer
   // and module ID
   //
   // Returns the symbolic volume name given for a given layer
   // and module ID
   //
+  if(!fgGeometry){
+    AliErrorClass("No geometry instance loaded yet!");
+    return NULL;
+  }
   if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
     AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
     return NULL;
   }
   if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
     AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
     return NULL;
   }
-  InitSymNamesLUT();
 
 
-  return fgSymName[layerId-kFirstLayer][modId].Data();
+  TGeoPNEntry* pne = fgPNEntry[layerId-kFirstLayer][modId];
+  if(!pne)
+  {
+    AliWarningClass(Form("Module %d of layer %s is not activated!",modId,LayerName(layerId)));
+    return NULL;
+  }
+  return pne->GetName();
+
 }
 
 //_____________________________________________________________________________
 }
 
 //_____________________________________________________________________________
-void AliGeomManager::InitSymNamesLUT()
+Bool_t AliGeomManager::CheckSymNamesLUT(const char* detsToBeChecked)
 {
 {
-  // Initialize the look-up table which associates the unique
-  // numerical identity of each alignable volume to the 
-  // corresponding symbolic volume name
-  // The LUTs are static; they are created at the creation of the
-  // AliGeomManager instance and recreated if the geometry has changed
-  //
-
-  if(fgSymName[0]) return;
-
-  for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){
-    if(!fgSymName[iLayer]) fgSymName[iLayer]=new TString[fgLayerSize[iLayer]];
+  // Check the look-up table which associates the unique numerical identity of
+  // each alignable volume to the corresponding symbolic volume name.
+  // The LUT is now hold inside the geometry and handled by TGeo.
+  // The method is meant to be launched when loading a geometry to verify that
+  // no changes in the symbolic names have been introduced, which would prevent
+  // backward compatibility with alignment objects.
+  // To accept both complete and partial geometry, this method skips the check
+  // for TRD and TOF volumes which are missing in the partial geometry.
+  // 
+
+//  TString detsString(detsToBeChecked);
+//  if(detsString.Contains("ALL")) detsString="ITS TPC TOF TRD HMPID PHOS EMCAL";
+
+  // Temporary measure to face the case of reconstruction over detectors not present in the geometry
+  TString detsString = "";
+  if(fgGeometry->CheckPath("ALIC_1/ITSV_1")) detsString+="ITS ";
+  if(fgGeometry->CheckPath("ALIC_1/TPC_M_1")) detsString+="TPC ";
+
+  TString tofsm;
+  TString baseTof("ALIC_1/B077_1/BSEGMO");
+  TString middleTof("_1/BTOF");
+  TString trailTof("_1/FTOA_0");
+  Bool_t tofActive=kFALSE;
+  Bool_t tofSMs[18];
+  for(Int_t sm=0; sm<18; sm++)
+  {
+    tofSMs[sm]=kFALSE;
+    tofsm=baseTof;
+    tofsm += sm;
+    tofsm += middleTof;
+    tofsm += sm;
+    tofsm += trailTof;
+    if(fgGeometry->CheckPath(tofsm.Data()))
+    {
+      tofActive=kTRUE;
+      tofSMs[sm]=kTRUE;
+    }
   }
   }
+  if(tofActive) detsString+="TOF ";
+  
+  TString trdsm;
+  TString baseTrd("ALIC_1/B077_1/BSEGMO");
+  TString middleTrd("_1/BTRD");
+  TString trailTrd("_1/UTR1_1");
+  Bool_t trdActive=kFALSE;
+  Bool_t trdSMs[18];
+  for(Int_t sm=0; sm<18; sm++)
+  {
+    trdSMs[sm]=kFALSE;
+    trdsm=baseTrd;
+    trdsm += sm;
+    trdsm += middleTrd;
+    trdsm += sm;
+    trdsm += trailTrd;
+    if(fgGeometry->CheckPath(trdsm.Data()))
+    {
+      trdActive=kTRUE;
+      trdSMs[sm]=kTRUE;
+    }
+  }
+  if(trdActive) detsString+="TRD ";
 
 
+  if(fgGeometry->CheckPath("ALIC_1/B077_1/BSEGMO0_1/BTRD0_1/UTR1_1")) detsString+="TRD ";
+  if(fgGeometry->CheckPath("ALIC_1/Hmp0_0")) detsString+="HMPID ";
+  if(fgGeometry->CheckPath("ALIC_1/PHOS_1")) detsString+="PHOS ";
+  if(fgGeometry->CheckPath("ALIC_1/XEN1_1")) detsString+="EMCAL";
+
+  
   TString symname;
   TString symname;
-  Int_t modnum; // in the following, set it to 0 at the start of each layer
+  const char* sname;
+  TGeoPNEntry* pne = 0x0;
+  Int_t uid; // global unique identity
+  Int_t modnum; // unique id inside layer; in the following, set it to 0 at the start of each layer
 
 
+  if(detsString.Contains("ITS")){
   /*********************       ITS layers  ***********************/
   /*********************       ITS layers  ***********************/
-  TString strSPD = "ITS/SPD";
-  TString strSDD = "ITS/SDD";
-  TString strSSD = "ITS/SSD";
-  TString strStave = "/Stave";
-  TString strHalfStave = "/HalfStave";
-  TString strLadder = "/Ladder";
-  TString strSector = "/Sector";
-  TString strSensor = "/Sensor";
-  TString strEntryName1;
-  TString strEntryName2;
-  TString strEntryName3;
-
-  /*********************       SPD layer1  ***********************/
-  {
-    modnum = 0;
-    
-    for(Int_t cSect = 0; cSect<10; cSect++){
-      strEntryName1 = strSPD;
-      strEntryName1 += 0;
-      strEntryName1 += strSector;
-      strEntryName1 += cSect;
-      
-      for(Int_t cStave =0; cStave<2; cStave++){
-       strEntryName2 = strEntryName1;
-       strEntryName2 += strStave;
-       strEntryName2 += cStave;
-
-       for (Int_t cHS=0; cHS<2; cHS++) {
-         strEntryName3 = strEntryName2;
-         strEntryName3 += strHalfStave;
-         strEntryName3 += cHS;
-         
-         for(Int_t cLad =0; cLad<2; cLad++){
-           symname = strEntryName3;
-           symname += strLadder;
-           symname += cLad+cHS*2;
-           fgSymName[kSPD1-kFirstLayer][modnum] = symname.Data();
-           modnum++;
+    AliDebugClass(2,"Checking consistency of symbolic names for ITS layers");
+    TString strSPD = "ITS/SPD";
+    TString strSDD = "ITS/SDD";
+    TString strSSD = "ITS/SSD";
+    TString strStave = "/Stave";
+    TString strHalfStave = "/HalfStave";
+    TString strLadder = "/Ladder";
+    TString strSector = "/Sector";
+    TString strSensor = "/Sensor";
+    TString strEntryName1;
+    TString strEntryName2;
+    TString strEntryName3;
+
+    /*********************       SPD layer1  ***********************/
+    {
+      modnum = 0;
+
+      for(Int_t cSect = 0; cSect<10; cSect++){
+       strEntryName1 = strSPD;
+       strEntryName1 += 0;
+       strEntryName1 += strSector;
+       strEntryName1 += cSect;
+
+       for(Int_t cStave =0; cStave<2; cStave++){
+         strEntryName2 = strEntryName1;
+         strEntryName2 += strStave;
+         strEntryName2 += cStave;
+
+         for (Int_t cHS=0; cHS<2; cHS++) {
+           strEntryName3 = strEntryName2;
+           strEntryName3 += strHalfStave;
+           strEntryName3 += cHS;
+
+           for(Int_t cLad =0; cLad<2; cLad++){
+             symname = strEntryName3;
+             symname += strLadder;
+             symname += cLad+cHS*2;
+             uid = LayerToVolUID(kSPD1,modnum++);
+             pne = fgGeometry->GetAlignableEntryByUID(uid);
+             if(!pne)
+             {
+               AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
+               return kFALSE;
+             }
+             sname = pne->GetName();
+             if(symname.CompareTo(sname)) 
+             {
+               AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d."
+                     "Expected was %s, found was %s!", uid, symname.Data(), sname));
+               return kFALSE;
+             }
+           }
          }
        }
       }
     }
          }
        }
       }
     }
-  }
-  
-  /*********************       SPD layer2  ***********************/
-  {
-    modnum = 0;
-
-    for(Int_t cSect = 0; cSect<10; cSect++){
-      strEntryName1 = strSPD;
-      strEntryName1 += 1;
-      strEntryName1 += strSector;
-      strEntryName1 += cSect;
-
-      for(Int_t cStave =0; cStave<4; cStave++){
-       strEntryName2 = strEntryName1;
-       strEntryName2 += strStave;
-       strEntryName2 += cStave;
-
-       for (Int_t cHS=0; cHS<2; cHS++) {
-         strEntryName3 = strEntryName2;
-         strEntryName3 += strHalfStave;
-         strEntryName3 += cHS;
-
-         for(Int_t cLad =0; cLad<2; cLad++){
-           symname = strEntryName3;
-           symname += strLadder;
-           symname += cLad+cHS*2;
-           fgSymName[kSPD2-kFirstLayer][modnum] = symname.Data();
-           modnum++;
+
+    /*********************       SPD layer2  ***********************/
+    {
+      modnum = 0;
+
+      for(Int_t cSect = 0; cSect<10; cSect++){
+       strEntryName1 = strSPD;
+       strEntryName1 += 1;
+       strEntryName1 += strSector;
+       strEntryName1 += cSect;
+
+       for(Int_t cStave =0; cStave<4; cStave++){
+         strEntryName2 = strEntryName1;
+         strEntryName2 += strStave;
+         strEntryName2 += cStave;
+
+         for (Int_t cHS=0; cHS<2; cHS++) {
+           strEntryName3 = strEntryName2;
+           strEntryName3 += strHalfStave;
+           strEntryName3 += cHS;
+
+           for(Int_t cLad =0; cLad<2; cLad++){
+             symname = strEntryName3;
+             symname += strLadder;
+             symname += cLad+cHS*2;
+             uid = LayerToVolUID(kSPD2,modnum++);
+             pne = fgGeometry->GetAlignableEntryByUID(uid);
+             if(!pne)
+             {
+               AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
+               return kFALSE;
+             }
+             sname = pne->GetName();
+             if(symname.CompareTo(sname)) 
+             {
+               AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d."
+                     "Expected was %s, found was %s!", uid, symname.Data(), sname));
+               return kFALSE;
+             }
+           }
          }
        }
       }
     }
          }
        }
       }
     }
-  }
-
-//   /*********************       SPD layer1  ***********************/
-//   {
-//     modnum = 0;
-
-//     for(Int_t c1 = 1; c1<=10; c1++){
-//       strEntryName1 = strSPD;
-//       strEntryName1 += 0;
-//       strEntryName1 += strSector;
-//       strEntryName1 += (c1-1);
-//       for(Int_t c2 =1; c2<=2; c2++){
-//     strEntryName2 = strEntryName1;
-//     strEntryName2 += strStave;
-//     strEntryName2 += (c2-1);
-//     for(Int_t c3 =1; c3<=4; c3++){
-//       symname = strEntryName2;
-//       symname += strLadder;
-//       symname += (c3-1);
-//       fgSymName[kSPD1-kFirstLayer][modnum] = symname.Data();
-//       modnum++;
-//     }
-//       }
-//     }
-//   }
-  
-//   /*********************       SPD layer2  ***********************/
-//   {
-//     modnum = 0;
-
-//     for(Int_t c1 = 1; c1<=10; c1++){
-//       strEntryName1 = strSPD;
-//       strEntryName1 += 1;
-//       strEntryName1 += strSector;
-//       strEntryName1 += (c1-1);
-//       for(Int_t c2 =1; c2<=4; c2++){
-//     strEntryName2 = strEntryName1;
-//     strEntryName2 += strStave;
-//     strEntryName2 += (c2-1);
-//     for(Int_t c3 =1; c3<=4; c3++){
-//       symname = strEntryName2;
-//       symname += strLadder;
-//       symname += (c3-1);
-//       fgSymName[kSPD2-kFirstLayer][modnum] = symname.Data();
-//       modnum++;
-//     }
-//       }
-//     }
-//   }
-
-
-
-
-
-
 
 
+    /*********************       SDD layer1  ***********************/
+    {
+      modnum=0;
 
 
+      for(Int_t c1 = 1; c1<=14; c1++){
+       strEntryName1 = strSDD;
+       strEntryName1 += 2;
+       strEntryName1 +=strLadder;
+       strEntryName1 += (c1-1);
+       for(Int_t c2 =1; c2<=6; c2++){
+         symname = strEntryName1;
+         symname += strSensor;
+         symname += (c2-1);
+         uid = LayerToVolUID(kSDD1,modnum++);
+         pne = fgGeometry->GetAlignableEntryByUID(uid);
+         if(!pne)
+         {
+           AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
+           return kFALSE;
+         }
+         sname = pne->GetName();
+         if(symname.CompareTo(sname)) 
+         {
+           AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
+                 "Expected was %s, found was %s!", uid, symname.Data(), sname));
+           return kFALSE;
+         }
+       }
+      }
+    }
 
 
-  /*********************       SDD layer1  ***********************/
-  {
-    modnum=0;
+    /*********************       SDD layer2  ***********************/
+    {
+      modnum=0;
 
 
-    for(Int_t c1 = 1; c1<=14; c1++){
-      strEntryName1 = strSDD;
-      strEntryName1 += 2;
-      strEntryName1 +=strLadder;
-      strEntryName1 += (c1-1);
-      for(Int_t c2 =1; c2<=6; c2++){
-       symname = strEntryName1;
-       symname += strSensor;
-       symname += (c2-1);
-       fgSymName[kSDD1-kFirstLayer][modnum] = symname.Data();
-       modnum++;
+      for(Int_t c1 = 1; c1<=22; c1++){
+       strEntryName1 = strSDD;
+       strEntryName1 += 3;
+       strEntryName1 +=strLadder;
+       strEntryName1 += (c1-1);
+       for(Int_t c2 = 1; c2<=8; c2++){
+         symname = strEntryName1;
+         symname += strSensor;
+         symname += (c2-1);
+         uid = LayerToVolUID(kSDD2,modnum++);
+         pne = fgGeometry->GetAlignableEntryByUID(uid);
+         if(!pne)
+         {
+           AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
+           return kFALSE;
+         }
+         sname = pne->GetName();
+         if(symname.CompareTo(sname)) 
+         {
+           AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
+                 "Expected was %s, found was %s!", uid, symname.Data(), sname));
+           return kFALSE;
+         }
+       }
       }
     }
       }
     }
-  }
 
 
-  /*********************       SDD layer2  ***********************/
-  {
-    modnum=0;
+    /*********************       SSD layer1  ***********************/
+    {
+      modnum=0;
 
 
-    for(Int_t c1 = 1; c1<=22; c1++){
-      strEntryName1 = strSDD;
-      strEntryName1 += 3;
-      strEntryName1 +=strLadder;
-      strEntryName1 += (c1-1);
-      for(Int_t c2 = 1; c2<=8; c2++){
-       symname = strEntryName1;
-       symname += strSensor;
-       symname += (c2-1);
-       fgSymName[kSDD2-kFirstLayer][modnum] = symname.Data();
-       modnum++;
+      for(Int_t c1 = 1; c1<=34; c1++){
+       strEntryName1 = strSSD;
+       strEntryName1 += 4;
+       strEntryName1 +=strLadder;
+       strEntryName1 += (c1-1);
+       for(Int_t c2 = 1; c2<=22; c2++){
+         symname = strEntryName1;
+         symname += strSensor;
+         symname += (c2-1);
+         uid = LayerToVolUID(kSSD1,modnum++);
+         pne = fgGeometry->GetAlignableEntryByUID(uid);
+         if(!pne)
+         {
+           AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
+           return kFALSE;
+         }
+         sname = pne->GetName();
+         if(symname.CompareTo(sname)) 
+         {
+           AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
+                 "Expected was %s, found was %s!", uid, symname.Data(), sname));
+           return kFALSE;
+         }
+       }
       }
     }
       }
     }
-  }
 
 
-  /*********************       SSD layer1  ***********************/
-  {
-    modnum=0;
+    /*********************       SSD layer2  ***********************/
+    {
+      modnum=0;
 
 
-    for(Int_t c1 = 1; c1<=34; c1++){
-      strEntryName1 = strSSD;
-      strEntryName1 += 4;
-      strEntryName1 +=strLadder;
-      strEntryName1 += (c1-1);
-      for(Int_t c2 = 1; c2<=22; c2++){
-       symname = strEntryName1;
-       symname += strSensor;
-       symname += (c2-1);
-       fgSymName[kSSD1-kFirstLayer][modnum] = symname.Data();
-       modnum++;
+      for(Int_t c1 = 1; c1<=38; c1++){
+       strEntryName1 = strSSD;
+       strEntryName1 += 5;
+       strEntryName1 +=strLadder;
+       strEntryName1 += (c1-1);
+       for(Int_t c2 = 1; c2<=25; c2++){
+         symname = strEntryName1;
+         symname += strSensor;
+         symname += (c2-1);
+         uid = LayerToVolUID(kSSD2,modnum++);
+         pne = fgGeometry->GetAlignableEntryByUID(uid);
+         if(!pne)
+         {
+           AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
+           return kFALSE;
+         }
+         sname = pne->GetName();
+         if(symname.CompareTo(sname)) 
+         {
+           AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
+                 "Expected was %s, found was %s!", uid, symname.Data(), sname));
+           return kFALSE;
+         }
+       }
       }
     }
       }
     }
+
+    AliDebugClass(2,"Consistency check for ITS symbolic names finished successfully.");
   }
 
   }
 
-  /*********************       SSD layer2  ***********************/
+  if(detsString.Contains("TPC"))
   {
   {
-    modnum=0;
+    /***************    TPC inner and outer layers    ****************/
+    
+    AliDebugClass(2,"Checking consistency of symbolic names for TPC layers");
+    TString sAsector="TPC/EndcapA/Sector";
+    TString sCsector="TPC/EndcapC/Sector";
+    TString sInner="/InnerChamber";
+    TString sOuter="/OuterChamber";
 
 
-    for(Int_t c1 = 1; c1<=38; c1++){
-      strEntryName1 = strSSD;
-      strEntryName1 += 5;
-      strEntryName1 +=strLadder;
-      strEntryName1 += (c1-1);
-      for(Int_t c2 = 1; c2<=25; c2++){
-       symname = strEntryName1;
-       symname += strSensor;
-       symname += (c2-1);
-       fgSymName[kSSD2-kFirstLayer][modnum] = symname.Data();
-       modnum++;
+    /***************    TPC inner chambers' layer    ****************/
+    {
+      modnum = 0;
+
+      for(Int_t cnt=1; cnt<=18; cnt++)
+      {
+       symname = sAsector;
+       symname += cnt;
+       symname += sInner;
+       uid = LayerToVolUID(kTPC1,modnum++);
+       pne = fgGeometry->GetAlignableEntryByUID(uid);
+       if(!pne)
+       {
+         AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
+         return kFALSE;
+       }
+       sname = pne->GetName();
+       if(symname.CompareTo(sname)) 
+       {
+         AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
+               "Expected was %s, found was %s!", uid, symname.Data(), sname));
+         return kFALSE;
+       }
+      }
+
+      for(Int_t cnt=1; cnt<=18; cnt++)
+      {
+       symname = sCsector;
+       symname += cnt;
+       symname += sInner;
+       uid = LayerToVolUID(kTPC1,modnum++);
+       pne = fgGeometry->GetAlignableEntryByUID(uid);
+       if(!pne)
+       {
+         AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
+         return kFALSE;
+       }
+       sname = pne->GetName();
+       if(symname.CompareTo(sname)) 
+       {
+         AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
+               "Expected was %s, found was %s!", uid, symname.Data(), sname));
+         return kFALSE;
+       }
       }
     }
       }
     }
-  }
 
 
+    /***************    TPC outer chambers' layer    ****************/
+    {
+      modnum = 0;
+
+      for(Int_t cnt=1; cnt<=18; cnt++)
+      {
+       symname = sAsector;
+       symname += cnt;
+       symname += sOuter;
+       uid = LayerToVolUID(kTPC2,modnum++);
+       pne = fgGeometry->GetAlignableEntryByUID(uid);
+       if(!pne)
+       {
+         AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
+         return kFALSE;
+       }
+       sname = pne->GetName();
+       if(symname.CompareTo(sname)) 
+       {
+         AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
+               "Expected was %s, found was %s!", uid, symname.Data(), sname));
+         return kFALSE;
+       }
+      }
 
 
-  /***************    TPC inner and outer layers    ****************/
-  TString sAsector="TPC/EndcapA/Sector";
-  TString sCsector="TPC/EndcapC/Sector";
-  TString sInner="/InnerChamber";
-  TString sOuter="/OuterChamber";
-  
-  /***************    TPC inner chambers' layer    ****************/
-  {
-    modnum = 0;
-    
-    for(Int_t cnt=1; cnt<=18; cnt++){
-      symname = sAsector;
-      symname += cnt;
-      symname += sInner;
-      fgSymName[kTPC1-kFirstLayer][modnum] = symname.Data();
-      modnum++;
-    }
-    for(Int_t cnt=1; cnt<=18; cnt++){
-      symname = sCsector;
-      symname += cnt;
-      symname += sInner;
-      fgSymName[kTPC1-kFirstLayer][modnum] = symname.Data();
-      modnum++;
+      for(Int_t cnt=1; cnt<=18; cnt++)
+      {
+       symname = sCsector;
+       symname += cnt;
+       symname += sOuter;
+       uid = LayerToVolUID(kTPC2,modnum++);
+       pne = fgGeometry->GetAlignableEntryByUID(uid);
+       if(!pne)
+       {
+         AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
+         return kFALSE;
+       }
+       sname = pne->GetName();
+       if(symname.CompareTo(sname)) 
+       {
+         AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
+               "Expected was %s, found was %s!", uid, symname.Data(), sname));
+         return kFALSE;
+       }
+      }
     }
     }
+
+    AliDebugClass(2,"Consistency check for TPC symbolic names finished successfully.");
   }
 
   }
 
-  /***************    TPC outer chambers' layer    ****************/
+  if(detsString.Contains("TOF"))
   {
   {
-    modnum = 0;
-    
-    for(Int_t cnt=1; cnt<=18; cnt++){
-      symname = sAsector;
-      symname += cnt;
-      symname += sOuter;
-      fgSymName[kTPC2-kFirstLayer][modnum] = symname.Data();
-      modnum++;
-    }
-    for(Int_t cnt=1; cnt<=18; cnt++){
-      symname = sCsector;
-      symname += cnt;
-      symname += sOuter;
-      fgSymName[kTPC2-kFirstLayer][modnum] = symname.Data();
-      modnum++;
-    }
-  }    
+    /*********************       TOF layer   ***********************/
 
 
-  /*********************       TOF layer   ***********************/
-  {
+    AliDebugClass(2,"Checking consistency of symbolic names for TOF layers");
     modnum=0;
     modnum=0;
-    
+
     Int_t nstrA=15;
     Int_t nstrB=19;
     Int_t nstrC=19;
     Int_t nSectors=18;
     Int_t nStrips=nstrA+2*nstrB+2*nstrC;
     Int_t nstrA=15;
     Int_t nstrB=19;
     Int_t nstrC=19;
     Int_t nSectors=18;
     Int_t nStrips=nstrA+2*nstrB+2*nstrC;
-    
+
     TString snSM  = "TOF/sm";
     TString snSTRIP = "/strip";
     
     TString snSM  = "TOF/sm";
     TString snSTRIP = "/strip";
     
@@ -764,26 +896,64 @@ void AliGeomManager::InitSymNamesLUT()
        symname += Form("%02d",isect);
        symname += snSTRIP;
        symname += Form("%02d",istr);
        symname += Form("%02d",isect);
        symname += snSTRIP;
        symname += Form("%02d",istr);
-       fgSymName[kTOF-kFirstLayer][modnum] = symname.Data();   
-       modnum++;
+       uid = LayerToVolUID(kTOF,modnum++);
+       if(!tofSMs[isect]) continue; // taking possible missing TOF sectors (partial geometry) into account
+       AliDebugClass(2,Form("Consistency check for symnames of TOF supermodule %d.",isect));
+       if ((isect==13 || isect==14 || isect==15) && (istr >= 39 && istr <= 53)) continue; //taking holes into account
+       pne = fgGeometry->GetAlignableEntryByUID(uid);
+       if(!pne)
+       {
+         AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
+         return kFALSE;
+       }
+       sname = pne->GetName();
+       if(symname.CompareTo(sname)) 
+       {
+         AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
+               "Expected was %s, found was %s!", uid, symname.Data(), sname));
+         return kFALSE;
+       }
       }
     }
       }
     }
+    
+    AliDebugClass(2,"Consistency check for TOF symbolic names finished successfully.");
   } 
 
   } 
 
-  /*********************      HMPID layer   ***********************/
+  if(detsString.Contains("HMPID"))
   {
   {
+    /*********************      HMPID layer   ***********************/
+
+    AliDebugClass(2,"Checking consistency of symbolic names for HMPID layers");
     TString str = "/HMPID/Chamber";
 
     for (modnum=0; modnum < 7; modnum++) {
       symname = str;
       symname += modnum;
     TString str = "/HMPID/Chamber";
 
     for (modnum=0; modnum < 7; modnum++) {
       symname = str;
       symname += modnum;
-      fgSymName[kHMPID-kFirstLayer][modnum] = symname.Data();
+      uid = LayerToVolUID(kHMPID,modnum);
+      pne = fgGeometry->GetAlignableEntryByUID(uid);
+      if(!pne)
+      {
+       AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
+       return kFALSE;
+      }
+      sname = pne->GetName();
+      if(symname.CompareTo(sname)) 
+      {
+       AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
+             "Expected was %s, found was %s!", uid, symname.Data(), sname));
+       return kFALSE;
+      }
     }
     }
+
+    AliDebugClass(2,"Consistency check for HMPID symbolic names finished successfully.");
   }
 
   }
 
-  /*********************      TRD layers 1-6   *******************/
-  //!! 6 layers with index increasing in outwards direction
+  if(detsString.Contains("TRD"))
   {
   {
+    /*********************      TRD layers 1-6   *******************/
+    //!! 6 layers with index increasing in outwards direction
+    
+    AliDebugClass(2,"Checking consistency of symbolic names for TRD layers");
     Int_t arTRDlayId[6] = {kTRD1, kTRD2, kTRD3, kTRD4, kTRD5, kTRD6};
 
     TString snStr  = "TRD/sm";
     Int_t arTRDlayId[6] = {kTRD1, kTRD2, kTRD3, kTRD4, kTRD5, kTRD6};
 
     TString snStr  = "TRD/sm";
@@ -800,40 +970,127 @@ void AliGeomManager::InitSymNamesLUT()
          symname += icham;
          symname += snApp2;
          symname += layer;
          symname += icham;
          symname += snApp2;
          symname += layer;
-         fgSymName[arTRDlayId[layer]-kFirstLayer][modnum] = symname.Data();
-         modnum++;
+         uid = LayerToVolUID(arTRDlayId[layer],modnum++);
+         if(!trdSMs[isect]) continue;
+         AliDebugClass(2,Form("Consistency check for symnames of TRD supermodule %d.",isect));
+         if ((isect==13 || isect==14 || isect==15) && icham==2) continue; //keeping holes into account
+         pne = fgGeometry->GetAlignableEntryByUID(uid);
+         if(!pne)
+         {
+           AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
+           return kFALSE;
+         }
+         sname = pne->GetName();
+         if(symname.CompareTo(sname)) 
+         {
+           AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
+                 "Expected was %s, found was %s!", uid, symname.Data(), sname));
+           return kFALSE;
+         }
        }
       }
     }
        }
       }
     }
+
+    AliDebugClass(2,"Consistency check for TRD symbolic names finished successfully.");
   }
 
   }
 
-  /*********************      PHOS EMC layer   ***********************/
+  if(detsString.Contains("PHOS"))
   {
   {
-    TString str = "PHOS/Module";
-    modnum=0;
+    /*********************      PHOS EMC layer   ***********************/
 
 
-    for (Int_t iModule=1; iModule <= 5; iModule++) {
-      symname = str;
-      symname += iModule;
-      modnum = iModule-1;
-      fgSymName[kPHOS1-kFirstLayer][modnum] = symname.Data();
+    AliDebugClass(2,"Checking consistency of symbolic names for PHOS layers");
+    
+    {
+      TString str = "PHOS/Module";
+      modnum=0;
+
+      for (Int_t iModule=1; iModule <= 5; iModule++) {
+       symname = str;
+       symname += iModule;
+       modnum = iModule-1;
+       uid = LayerToVolUID(kPHOS1,modnum);
+       pne = fgGeometry->GetAlignableEntryByUID(uid);
+       if(!pne)
+       {
+         AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
+         return kFALSE;
+       }
+       sname = pne->GetName();
+       if(symname.CompareTo(sname)) 
+       {
+         AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
+               "Expected was %s, found was %s!", uid, symname.Data(), sname));
+         return kFALSE;
+       }
+      }
+    }
+
+    /*********************      PHOS CPV layer   ***********************/
+    {
+      TString str = "PHOS/Module";
+      modnum=0;
+
+      for (Int_t iModule=1; iModule <= 5; iModule++) {
+       symname = str;
+       symname += iModule;
+       symname += "/CPV";
+       modnum = iModule-1;
+       uid = LayerToVolUID(kPHOS2,modnum);
+       pne = fgGeometry->GetAlignableEntryByUID(uid);
+       if(!pne)
+       {
+         AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
+         return kFALSE;
+       }
+       sname = pne->GetName();
+       if(symname.CompareTo(sname)) 
+       {
+         AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
+               "Expected was %s, found was %s!", uid, symname.Data(), sname));
+         return kFALSE;
+       }
+      }
     }
     }
+
+    AliDebugClass(2,"Consistency check for PHOS symbolic names finished successfully.");
   }
 
   }
 
-  /*********************      PHOS CPV layer   ***********************/
+  if(detsString.Contains("EMCAL"))
   {
   {
-    TString str = "PHOS/Module";
+    /*********************      EMCAL layer   ***********************/
+
+    AliDebugClass(2,"Checking consistency of symbolic names for EMCAL layers");
+    TString str = "EMCAL/FullSupermodule";
     modnum=0;
 
     modnum=0;
 
-    for (Int_t iModule=1; iModule <= 5; iModule++) {
+    for (Int_t iModule=1; iModule <= 12; iModule++) {
       symname = str;
       symname += iModule;
       symname = str;
       symname += iModule;
-      symname += "/CPV";
+      if(iModule >10) {
+       symname = "EMCAL/HalfSupermodule";
+       symname += iModule-10;
+      }
       modnum = iModule-1;
       modnum = iModule-1;
-      fgSymName[kPHOS2-kFirstLayer][modnum] = symname.Data();
+      uid = LayerToVolUID(kEMCAL,modnum);
+      pne = fgGeometry->GetAlignableEntryByUID(uid);
+      if(!pne)
+      {
+       AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
+       return kFALSE;
+      }
+      sname = pne->GetName();
+      if(symname.CompareTo(sname)) 
+      {
+       AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
+             "Expected was %s, found was %s!", uid, symname.Data(), sname));
+       return kFALSE;
+      }
     }
     }
+  
+    AliDebugClass(2,"Consistency check for EMCAL symbolic names finished successfully.");
   }
   }
-
+  
+  return kTRUE;
 
 }
 
 
 }
 
@@ -856,48 +1113,22 @@ void AliGeomManager::InitPNEntriesLUT()
   for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){
     fgPNEntry[iLayer] = new TGeoPNEntry*[fgLayerSize[iLayer]];
     for(Int_t modnum=0; modnum<fgLayerSize[iLayer]; modnum++){
   for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){
     fgPNEntry[iLayer] = new TGeoPNEntry*[fgLayerSize[iLayer]];
     for(Int_t modnum=0; modnum<fgLayerSize[iLayer]; modnum++){
-      fgPNEntry[iLayer][modnum] = fgGeometry->GetAlignableEntry(fgSymName[iLayer][modnum]);
-    }
-  }
-}
-
-//_____________________________________________________________________________
-void AliGeomManager::InitOrigMatricesLUT()
-{
-  // Initialize the storage for the look-up table with the original global
-  // matrices for each alignable volume.
-  // The LUTs are static; the matrices are created on demand and recreated
-  // if the geometry has changed.
-  if (fgOrigMatrix[0]) return;
-
-  if (!fgGeometry || !fgGeometry->IsClosed()) {
-    AliErrorClass("Impossible to initialize orignal matrices LUT without an active geometry");
-    return;
-  }
-
-  for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){
-    fgOrigMatrix[iLayer] = new TGeoHMatrix*[fgLayerSize[iLayer]];
-    for(Int_t modnum=0; modnum<fgLayerSize[iLayer]; modnum++){
-      if (!fgPNEntry[iLayer][modnum]) continue;
-      TGeoHMatrix *m = GetOrigGlobalMatrix(fgPNEntry[iLayer][modnum]);
-      if (!m) continue;
-      fgOrigMatrix[iLayer][modnum] = new TGeoHMatrix(*m);
+      fgPNEntry[iLayer][modnum] = fgGeometry->GetAlignableEntryByUID(LayerToVolUID(iLayer+1,modnum));
     }
   }
     }
   }
-
 }
 
 //______________________________________________________________________
 TGeoHMatrix* AliGeomManager::GetMatrix(TGeoPNEntry* pne) 
 {
 }
 
 //______________________________________________________________________
 TGeoHMatrix* AliGeomManager::GetMatrix(TGeoPNEntry* pne) 
 {
-  // Get the transformation matrix for a given PNEntry
+  // Get the global transformation matrix for a given PNEntry
   // by quering the TGeoManager
 
   if (!fgGeometry || !fgGeometry->IsClosed()) {
     AliErrorClass("Can't get the global matrix! gGeoManager doesn't exist or it is still opened!");
     return NULL;
   }
   // by quering the TGeoManager
 
   if (!fgGeometry || !fgGeometry->IsClosed()) {
     AliErrorClass("Can't get the global matrix! gGeoManager doesn't exist or it is still opened!");
     return NULL;
   }
-  
+
   TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
   if (pnode) return pnode->GetMatrix();
 
   TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
   if (pnode) return pnode->GetMatrix();
 
@@ -968,11 +1199,46 @@ Bool_t AliGeomManager::GetRotation(Int_t index, Double_t r[9])
   return kTRUE;
 }
 
   return kTRUE;
 }
 
+//_____________________________________________________________________________
+Bool_t AliGeomManager::GetDeltaForBranch(Int_t index, TGeoHMatrix &inclusiveD)
+{
+  // The method sets the matrix passed as argument as the global delta
+  // (for the volume referred by the unique index) including the displacements
+  // of all parent volumes in the branch.
+  //
+
+  TGeoHMatrix go,invgo;
+  go = *GetOrigGlobalMatrix(index);
+  invgo = go.Inverse();
+  inclusiveD = *GetMatrix(index);
+  inclusiveD.Multiply(&invgo);
+
+  return kTRUE;
+}
+
+//_____________________________________________________________________________
+Bool_t AliGeomManager::GetDeltaForBranch(AliAlignObj& aao, TGeoHMatrix &inclusiveD)
+{
+  // The method sets the matrix passed as argument as the global delta
+  // (for the volume referred by the alignment object) including the displacements
+  // of all parent volumes in the brach.
+  //
+  Int_t index = aao.GetVolUID();
+  if(!index){
+    AliErrorClass("Either the alignment object or its index are not valid");
+    return kFALSE;
+  }
+  return GetDeltaForBranch(index, inclusiveD);
+}
+
 //______________________________________________________________________
 Bool_t AliGeomManager::GetOrigGlobalMatrix(const char* symname, TGeoHMatrix &m) 
 {
   // Get the global transformation matrix (ideal geometry) for a given alignable volume
 //______________________________________________________________________
 Bool_t AliGeomManager::GetOrigGlobalMatrix(const char* symname, TGeoHMatrix &m) 
 {
   // Get the global transformation matrix (ideal geometry) for a given alignable volume
-  //  identified by its symbolic name 'symname' by quering the TGeoManager
+  // The alignable volume is identified by 'symname' which has to be either a valid symbolic
+  // name, the query being performed after alignment, or a valid volume path if the query is
+  // performed before alignment.
+  //
   m.Clear();
 
   if (!fgGeometry || !fgGeometry->IsClosed()) {
   m.Clear();
 
   if (!fgGeometry || !fgGeometry->IsClosed()) {
@@ -994,7 +1260,8 @@ Bool_t AliGeomManager::GetOrigGlobalMatrix(const char* symname, TGeoHMatrix &m)
   TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname);
   const char* path = NULL;
   if(pne){
   TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname);
   const char* path = NULL;
   if(pne){
-    path = pne->GetTitle();
+    m = *pne->GetGlobalOrig();
+    return kTRUE;
   }else{
     AliWarningClass(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname));
     path=symname;
   }else{
     AliWarningClass(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname));
     path=symname;
@@ -1006,11 +1273,11 @@ Bool_t AliGeomManager::GetOrigGlobalMatrix(const char* symname, TGeoHMatrix &m)
 //_____________________________________________________________________________
 Bool_t AliGeomManager::GetOrigGlobalMatrixFromPath(const char *path, TGeoHMatrix &m)
 {
 //_____________________________________________________________________________
 Bool_t AliGeomManager::GetOrigGlobalMatrixFromPath(const char *path, TGeoHMatrix &m)
 {
-  // The method returns global matrix for the ideal detector geometry
-  // Symname identifies either the corresponding TGeoPNEntry or directly
-  // the volume path. The output global matrix is stored in 'm'.
-  // Returns kFALSE in case TGeo has not been initialized or the symname
-  // is invalid.
+  // The method returns the global matrix for the volume identified by 
+  // 'path' in the ideal detector geometry.
+  // The output global matrix is stored in 'm'.
+  // Returns kFALSE in case TGeo has not been initialized or the volume
+  // path is not valid.
   //
   m.Clear();
 
   //
   m.Clear();
 
@@ -1037,8 +1304,8 @@ Bool_t AliGeomManager::GetOrigGlobalMatrixFromPath(const char *path, TGeoHMatrix
 
     TGeoMatrix *lm = NULL;
     if (physNode) {
 
     TGeoMatrix *lm = NULL;
     if (physNode) {
-        lm = physNode->GetOriginalMatrix();
-       if (!lm) lm = node->GetMatrix();
+      lm = physNode->GetOriginalMatrix();
+      if (!lm) lm = node->GetMatrix();
     } else
       lm = node->GetMatrix();
 
     } else
       lm = node->GetMatrix();
 
@@ -1055,41 +1322,32 @@ TGeoHMatrix* AliGeomManager::GetOrigGlobalMatrix(TGeoPNEntry* pne)
 {
   // The method returns global matrix for the ideal detector geometry
   // using the corresponding TGeoPNEntry as an input.
 {
   // The method returns global matrix for the ideal detector geometry
   // using the corresponding TGeoPNEntry as an input.
-  // The method creates a new matrix, so it has to be used carefully in order
-  // to avoid memory leaks.
-  // In case of missing TGeoManager the method return NULL.
-
+  // The returned pointer should be copied by the user, since its content could
+  // be overwritten by a following call to the method.
+  // In case of missing TGeoManager the method returns NULL.
+  //
   if (!fgGeometry || !fgGeometry->IsClosed()) {
     AliErrorClass("Can't get the global matrix! gGeoManager doesn't exist or it is still opened!");
     return NULL;
   }
 
   if (!fgGeometry || !fgGeometry->IsClosed()) {
     AliErrorClass("Can't get the global matrix! gGeoManager doesn't exist or it is still opened!");
     return NULL;
   }
 
-  const char* path = pne->GetTitle();
-  static TGeoHMatrix m;
-  if (!GetOrigGlobalMatrixFromPath(path,m))
-    return NULL;
-
-  return &m;
+  return pne->GetGlobalOrig();
 }
 
 //______________________________________________________________________
 TGeoHMatrix* AliGeomManager::GetOrigGlobalMatrix(Int_t index)
 {
 }
 
 //______________________________________________________________________
 TGeoHMatrix* AliGeomManager::GetOrigGlobalMatrix(Int_t index)
 {
-  // Get the original (ideal geometry) TGeo matrix for
-  // a given module identified by 'index'.
-  // In general the method is slow, so we use
-  // LUT for fast access. The LUT is reset in case of
+  // The method returns global matrix from the ideal detector geometry
+  // for the volume identified by its index.
+  // The returned pointer should be copied by the user, since its content could
+  // be overwritten by a following call to the method.
+  // In case of missing TGeoManager the method returns NULL.
+  // If possible, the method uses the LUT of original ideal matrices
+  // for fast access. The LUT is reset in case a
   // new geometry is loaded.
   // new geometry is loaded.
-  Int_t modId;
-  ELayerID layerId = VolUIDToLayer(index,modId);
-
-  if (fgOrigMatrix[layerId-kFirstLayer][modId])
-    return fgOrigMatrix[layerId-kFirstLayer][modId];
-  else {
-    TGeoPNEntry *pne = GetPNEntry(index);
-    if (!pne) return NULL;
-    return GetOrigGlobalMatrix(pne);
-  }
+  //
+  TGeoPNEntry* pne = GetPNEntry(index);
+  return pne->GetGlobalOrig();
 }
 
 //______________________________________________________________________
 }
 
 //______________________________________________________________________
@@ -1133,7 +1391,7 @@ const TGeoHMatrix* AliGeomManager::GetTracking2LocalMatrix(Int_t index)
 
   const TGeoHMatrix *m = pne->GetMatrix();
   if (!m)
 
   const TGeoHMatrix *m = pne->GetMatrix();
   if (!m)
-    AliErrorClass(Form("TGeoPNEntry (%s) contains no matrix !",pne->GetName()));
+    AliErrorClass(Form("TGeoPNEntry (%s) contains no tracking-to-local matrix !",pne->GetName()));
 
   return m;
 }
 
   return m;
 }
@@ -1183,6 +1441,56 @@ TGeoPNEntry* AliGeomManager::GetPNEntry(ELayerID layerId, Int_t modId)
   return fgPNEntry[layerId-kFirstLayer][modId];
 }
 
   return fgPNEntry[layerId-kFirstLayer][modId];
 }
 
+//_____________________________________________________________________________
+void AliGeomManager::CheckOverlapsOverPNs(Double_t threshold)
+{
+  // Check for overlaps/extrusions on physical nodes only;
+  // this overlap-checker is meant to be used to check overlaps/extrusions
+  // originated by the application of alignment objects.
+  //
+
+  TObjArray* ovexlist = new TObjArray(64);
+
+  AliInfoClass("********* Checking overlaps/extrusions over physical nodes only *********");
+  TObjArray* pnList = gGeoManager->GetListOfPhysicalNodes();
+  TGeoVolume* mvol = 0;
+  TGeoPhysicalNode* pn;
+  TObjArray* overlaps = new TObjArray(64);
+  overlaps->SetOwner();
+
+  TStopwatch timer2;
+  timer2.Start();
+  for(Int_t pni=0; pni<pnList->GetEntriesFast(); pni++){
+    pn = (TGeoPhysicalNode*) pnList->UncheckedAt(pni);
+    // checking the volume of the mother (go upper in the tree in case it is an assembly)
+    Int_t levup=1;
+    while(((TGeoVolume*)pn->GetVolume(pn->GetLevel()-levup))->IsAssembly()) levup++;
+      //Printf("Going to upper level");
+    mvol = pn->GetVolume(pn->GetLevel()-levup);
+    if(!mvol->IsSelected()){
+      AliInfoClass(Form("Checking overlaps for volume %s",mvol->GetName()));
+      mvol->CheckOverlaps(threshold);
+      ovexlist = gGeoManager->GetListOfOverlaps();
+      TIter next(ovexlist);
+      TGeoOverlap *ov;
+      while ((ov=(TGeoOverlap*)next())) overlaps->Add(ov->Clone());
+      mvol->SelectVolume();
+    }
+  }
+  mvol->SelectVolume(kTRUE); // clears the list of selected volumes
+
+  AliInfoClass(Form("Number of overlapping/extruding PNs: %d",overlaps->GetEntriesFast()));
+  timer2.Stop();
+  timer2.Print();
+
+  TIter nextN(overlaps);
+  TGeoOverlap *ovlp;
+  while ((ovlp=(TGeoOverlap*)nextN())) ovlp->PrintInfo();
+
+  overlaps->Delete();
+  delete overlaps;
+}
+
 //_____________________________________________________________________________
 Bool_t AliGeomManager::ApplyAlignObjsFromCDB(const char* AlignDetsList)
 {
 //_____________________________________________________________________________
 Bool_t AliGeomManager::ApplyAlignObjsFromCDB(const char* AlignDetsList)
 {
@@ -1221,6 +1529,8 @@ Bool_t AliGeomManager::ApplyAlignObjsFromCDB(const char* AlignDetsList)
       alObjsLoaded += " ";
     }
   }
       alObjsLoaded += " ";
     }
   }
+  detsarr->Delete();
+  delete detsarr;
 
   if(!alObjsLoaded.IsNull()) AliInfoClass(Form("Alignment objects loaded for: %s",
                                               alObjsLoaded.Data()));
 
   if(!alObjsLoaded.IsNull()) AliInfoClass(Form("Alignment objects loaded for: %s",
                                               alObjsLoaded.Data()));
@@ -1271,7 +1581,7 @@ Bool_t AliGeomManager::LoadAlignObjsFromCDBSingleDet(const char* detName, TObjAr
 }
 
 //_____________________________________________________________________________
 }
 
 //_____________________________________________________________________________
-Bool_t AliGeomManager::ApplyAlignObjsToGeom(TObjArray& alignObjArray)
+Bool_t AliGeomManager::ApplyAlignObjsToGeom(TObjArray& alignObjArray, Bool_t ovlpcheck)
 {
   // Read collection of alignment objects (AliAlignObj derived) saved
   // in the TClonesArray alObjArray and apply them to gGeoManager
 {
   // Read collection of alignment objects (AliAlignObj derived) saved
   // in the TClonesArray alObjArray and apply them to gGeoManager
@@ -1284,7 +1594,7 @@ Bool_t AliGeomManager::ApplyAlignObjsToGeom(TObjArray& alignObjArray)
   for(Int_t j=0; j<nvols; j++)
     {
       AliAlignObj* alobj = (AliAlignObj*) alignObjArray.UncheckedAt(j);
   for(Int_t j=0; j<nvols; j++)
     {
       AliAlignObj* alobj = (AliAlignObj*) alignObjArray.UncheckedAt(j);
-      if (alobj->ApplyToGeometry() == kFALSE) flag = kFALSE;
+      if (alobj->ApplyToGeometry(ovlpcheck) == kFALSE) flag = kFALSE;
     }
 
   if (AliDebugLevelClass() >= 1) {
     }
 
   if (AliDebugLevelClass() >= 1) {
@@ -1377,3 +1687,27 @@ Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* detName, Int_t runnum, I
 
   return ApplyAlignObjsToGeom(*alignObjArray);
 }
 
   return ApplyAlignObjsToGeom(*alignObjArray);
 }
+
+//_____________________________________________________________________________
+Int_t AliGeomManager::CheckOverlapsExtrusions(TGeoNode* start, Double_t threshold)
+{
+  // For the given node check for overlaps and extrusions within threshold by means
+  // both of the standard checker and of the checker by sampling.
+  // Returns the total number of overlaps for the given node.
+  //
+  TGeoVolume* vol = start->GetVolume();
+  gGeoManager->ClearOverlaps();
+  gGeoManager->SetCheckingOverlaps();
+  AliDebugClass(2,Form("Checking overlaps for volume %s",vol->GetName()));
+  vol->CheckOverlaps(threshold); 
+  AliDebugClass(2,Form("Checking overlaps by sampling for node %s",start->GetName()));
+  start->CheckOverlaps(threshold,"s");  
+
+  TObjArray* ovexArray = (TObjArray*)gGeoManager->GetListOfOverlaps();
+  AliDebugClass(2,Form("Number of overlaps/extrusions: %d", ovexArray->GetEntriesFast()));
+  
+  gGeoManager->SetCheckingOverlaps(kFALSE);
+
+ return ovexArray->GetEntriesFast();
+}
+