]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - STEER/AliGeomManager.cxx
datamember added in AliGeomManager with number of alignable volumes per subdetector...
[u/mrichter/AliRoot.git] / STEER / AliGeomManager.cxx
index 6f5165fd52aebf5d09c1b49f6be98c29511166f5..893603c95a425c7ebea3a73cfe4b43eeef0f2f84 100644 (file)
 #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 "AliAlignObjAngles.h"
+#include "AliAlignObjParams.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 ??
-  1         // MUON ??
+  1,         // MUON ??
+  12        // EMCAL
 };
 
 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",
-  "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] = {
@@ -87,18 +80,6 @@ TGeoPNEntry** AliGeomManager::fgPNEntry[kLastLayer - kFirstLayer] = {
   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
 };
@@ -113,9 +94,14 @@ AliAlignObj** AliGeomManager::fgAlignObjs[kLastLayer - kFirstLayer] = {
   0x0,
   0x0,0x0,
   0x0,
+  0x0,
   0x0
 };
 
+const char* AliGeomManager::fgkDetectorName[AliGeomManager::fgkNDetectors] = {"GRP","ITS","TPC","TRD","TOF","PHOS","HMPID","EMCAL","MUON","FMD","ZDC","PMD","T0","VZERO","ACORDE"};
+Int_t AliGeomManager::fgNalignable[fgkNDetectors] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+
 TGeoManager* AliGeomManager::fgGeometry = 0x0;
 
 //_____________________________________________________________________________
@@ -126,14 +112,12 @@ void AliGeomManager::LoadGeometry(const char *geomFileName)
   // 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);
-    AliInfoClass("Using custom geometry.root file");
+    AliInfoClass(Form("From now on using geometry from custom geometry file \"%s\"",geomFileName));
   }
 
   if (!fgGeometry) {
-    AliInfoClass("Using geometry from CDB");
-
     AliCDBPath path("GRP","Geometry","Data");
        
     AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
@@ -142,11 +126,13 @@ 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!");
+    
+    AliInfoClass(Form("From now on using geometry from CDB base folder \"%s\"",
+                     AliCDBManager::Instance()->GetURI("Geometry/Align/Data")));
   }
 
-  InitSymNamesLUT();
   InitPNEntriesLUT();
-  InitOrigMatricesLUT();
+  InitNalignable();
 }
 
 //_____________________________________________________________________________
@@ -156,10 +142,8 @@ void AliGeomManager::SetGeometry(TGeoManager *geom)
   if (!geom) AliFatalClass("Pointer to the active geometry is 0x0!");
 
   fgGeometry = geom;
-
-  InitSymNamesLUT();
   InitPNEntriesLUT();
-  InitOrigMatricesLUT();
+  InitNalignable();
 }
 
 //_____________________________________________________________________________
@@ -187,7 +171,7 @@ Int_t AliGeomManager::LayerSize(Int_t layerId)
   }
   else {
     return fgLayerSize[layerId - kFirstLayer];
- }
 }
 }
 
 //_____________________________________________________________________________
@@ -202,7 +186,7 @@ const char* AliGeomManager::LayerName(Int_t layerId)
   }
   else {
     return fgLayerName[layerId - kFirstLayer];
- }
 }
 }
 
 //_____________________________________________________________________________
@@ -404,27 +388,28 @@ Bool_t AliGeomManager::GetFromGeometry(const char *symname, AliAlignObj &alobj)
 //_____________________________________________________________________________
 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;
-  
+
   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));
     }
   }
-  
+
 }
 
 //_____________________________________________________________________________
-AliAlignObj* AliGeomManager::GetAlignObj(UShort_t voluid) {
+AliAlignObj* AliGeomManager::GetAlignObj(UShort_t voluid)
+{
   // Returns the alignment object for given volume ID
   //
   Int_t modId;
@@ -447,7 +432,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;
@@ -461,227 +447,471 @@ const char* AliGeomManager::SymName(ELayerID layerId, Int_t modId)
   // 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;
   }
-  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;
+  // 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 ";
 
-  for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){
-    if(!fgSymName[iLayer]) fgSymName[iLayer]=new TString[fgLayerSize[iLayer]];
+  if(fgGeometry->CheckPath("ALIC_1/Hmp0_0")) detsString+="HMPID ";
+  
+  TString phosMod, cpvMod;
+  TString basePhos("ALIC_1/PHOS_");
+  Bool_t phosActive=kFALSE;
+  Bool_t cpvActive=kFALSE;
+  Bool_t phosMods[5];
+  for(Int_t pmod=0; pmod<5; pmod++)
+  {
+    phosMods[pmod]=kFALSE;
+    phosMod = basePhos;
+    phosMod += (pmod+1);
+    cpvMod = phosMod;
+    cpvMod += "/PCPV_1";
+    if(fgGeometry->CheckPath(phosMod.Data()))
+    {
+      phosActive=kTRUE;
+      phosMods[pmod]=kTRUE;
+      if(fgGeometry->CheckPath(cpvMod.Data())) cpvActive=kTRUE;
+    }
   }
+  if(phosActive) detsString+="PHOS ";
+
+  if(fgGeometry->CheckPath("ALIC_1/XEN1_1")) detsString+="EMCAL";
 
   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  ***********************/
-  TString strSPD = "ITS/SPD";
-  TString strSDD = "ITS/SDD";
-  TString strSSD = "ITS/SSD";
-  TString strStave = "/Stave";
-  TString strLadder = "/Ladder";
-  TString strSector = "/Sector";
-  TString strSensor = "/Sensor";
-  TString strEntryName1;
-  TString strEntryName2;
-
-
-  /*********************       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++;
+    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 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++;
+
+    /*********************       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;
+             }
+           }
+         }
        }
       }
     }
-  }
 
-  /*********************       SDD layer1  ***********************/
-  {
-    modnum=0;
+    /*********************       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);
-       fgSymName[kSDD1-kFirstLayer][modnum] = symname.Data();
-       modnum++;
+      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 layer2  ***********************/
-  {
-    modnum=0;
+    /*********************       SDD layer2  ***********************/
+    {
+      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<=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;
+         }
+       }
       }
     }
-  }
 
-  /*********************       SSD layer1  ***********************/
-  {
-    modnum=0;
+    /*********************       SSD layer1  ***********************/
+    {
+      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<=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 layer2  ***********************/
-  {
-    modnum=0;
+    /*********************       SSD layer2  ***********************/
+    {
+      modnum=0;
 
-    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++;
+      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.");
+  }
 
-  /***************    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    ****************/
+  if(detsString.Contains("TPC"))
   {
-    modnum = 0;
+    /***************    TPC inner and outer layers    ****************/
     
-    for(Int_t cnt=1; cnt<=18; cnt++){
-      symname = sAsector;
-      symname += cnt;
-      symname += sInner;
-      fgSymName[kTPC1-kFirstLayer][modnum] = symname.Data();
-      modnum++;
+    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";
+
+    /***************    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;
+       }
+      }
     }
-    for(Int_t cnt=1; cnt<=18; cnt++){
-      symname = sCsector;
-      symname += cnt;
-      symname += sInner;
-      fgSymName[kTPC1-kFirstLayer][modnum] = symname.Data();
-      modnum++;
+
+    /***************    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;
+       }
+      }
+
+      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;
-    
+
     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";
     
@@ -691,26 +921,64 @@ void AliGeomManager::InitSymNamesLUT()
        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;
-      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";
@@ -727,40 +995,114 @@ void AliGeomManager::InitSymNamesLUT()
          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=0; iModule < 5; iModule++) {
+       if(!phosMods[iModule]) continue;
+       symname = str;
+       symname += (iModule+1);
+       uid = LayerToVolUID(kPHOS1,iModule);
+       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   ***********************/
+       if(!cpvActive) continue;
+       symname += "/CPV";
+       uid = LayerToVolUID(kPHOS2,iModule);
+       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;
 
-    for (Int_t iModule=1; iModule <= 5; iModule++) {
+    for (Int_t iModule=1; iModule <= 12; iModule++) {
       symname = str;
       symname += iModule;
-      symname += "/CPV";
+      if(iModule >10) {
+       symname = "EMCAL/HalfSupermodule";
+       symname += iModule-10;
+      }
       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;
 
 }
 
@@ -783,48 +1125,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++){
-      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) 
 {
-  // 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;
   }
-  
+
   TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
   if (pnode) return pnode->GetMatrix();
 
@@ -895,11 +1211,46 @@ Bool_t AliGeomManager::GetRotation(Int_t index, Double_t r[9])
   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
-  //  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()) {
@@ -921,7 +1272,8 @@ Bool_t AliGeomManager::GetOrigGlobalMatrix(const char* symname, TGeoHMatrix &m)
   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;
@@ -933,11 +1285,11 @@ Bool_t AliGeomManager::GetOrigGlobalMatrix(const char* symname, 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();
 
@@ -964,8 +1316,8 @@ Bool_t AliGeomManager::GetOrigGlobalMatrixFromPath(const char *path, TGeoHMatrix
 
     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();
 
@@ -982,41 +1334,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 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;
   }
 
-  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)
 {
-  // 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.
-  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();
 }
 
 //______________________________________________________________________
@@ -1060,7 +1403,7 @@ const TGeoHMatrix* AliGeomManager::GetTracking2LocalMatrix(Int_t index)
 
   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;
 }
@@ -1110,6 +1453,99 @@ TGeoPNEntry* AliGeomManager::GetPNEntry(ELayerID layerId, Int_t 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;
+}
+
+//_____________________________________________________________________________
+Int_t AliGeomManager::GetNalignable(const char* module)
+{
+  // Get number of declared alignable volumes for given detector in current geometry
+  //
+  
+  // return the detector index corresponding to detector
+  Int_t index = -1 ;
+  for (index = 0; index < fgkNDetectors ; index++) {
+    if ( strcmp(module, fgkDetectorName[index]) == 0 )
+      break ;
+  }
+  return fgNalignable[index];
+}
+  
+//_____________________________________________________________________________
+void AliGeomManager::InitNalignable()
+{
+  // Set number of declared alignable volumes for given detector in current geometry
+  // by looping on the list of PNEntries
+  //
+  
+  Int_t nAlE = gGeoManager->GetNAlignable(); // total number of alignable entries
+  TGeoPNEntry *pne = 0;
+  TString *pneName = 0;
+  const char* detName;
+  
+  for (Int_t iDet = 0; iDet < fgkNDetectors ; iDet++) {
+    detName = fgkDetectorName[iDet];
+    Int_t nAlDet = 0;
+    
+    for(Int_t iE = 0; iE < nAlE; iE++)
+    {
+      pne = gGeoManager->GetAlignableEntry(iE);
+      pneName = new TString(pne->GetName());
+      if(pneName->Contains(detName)) nAlDet++;
+      if(!strcmp(detName,"GRP")) if(pneName->Contains("ABSO") || pneName->Contains("DIPO") || pneName->Contains("FRAME") || pneName->Contains("PIPE") || pneName->Contains("SHIL")) nAlDet++;
+    }
+    fgNalignable[iDet] = nAlDet;
+  }
+
+}
+  
 //_____________________________________________________________________________
 Bool_t AliGeomManager::ApplyAlignObjsFromCDB(const char* AlignDetsList)
 {
@@ -1148,6 +1584,8 @@ Bool_t AliGeomManager::ApplyAlignObjsFromCDB(const char* AlignDetsList)
       alObjsLoaded += " ";
     }
   }
+  detsarr->Delete();
+  delete detsarr;
 
   if(!alObjsLoaded.IsNull()) AliInfoClass(Form("Alignment objects loaded for: %s",
                                               alObjsLoaded.Data()));
@@ -1180,8 +1618,10 @@ Bool_t AliGeomManager::LoadAlignObjsFromCDBSingleDet(const char* detName, TObjAr
   entry->SetOwner(1);
   TClonesArray *alignArray = (TClonesArray*) entry->GetObject();       
   alignArray->SetOwner(0);
-  AliDebugClass(2,Form("Found %d alignment objects for %s",
-                      alignArray->GetEntries(),detName));
+  Int_t nAlObjs = alignArray->GetEntries();
+  AliDebugClass(2,Form("Found %d alignment objects for %s",nAlObjs,detName));
+  Int_t nAlVols = GetNalignable(detName);
+  if(nAlObjs!=nAlVols) AliWarningClass(Form("%d alignment objects loaded for %s, which has %d alignable volumes",nAlObjs,detName,GetNalignable(detName)));
 
   AliAlignObj *alignObj=0;
   TIter iter(alignArray);
@@ -1198,7 +1638,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
@@ -1209,16 +1649,24 @@ Bool_t AliGeomManager::ApplyAlignObjsToGeom(TObjArray& alignObjArray)
   Bool_t flag = kTRUE;
 
   for(Int_t j=0; j<nvols; j++)
+  {
+    AliAlignObj* alobj = (AliAlignObj*) alignObjArray.UncheckedAt(j);
+    flag = alobj->ApplyToGeometry(ovlpcheck);
+    if(!flag)
     {
-      AliAlignObj* alobj = (AliAlignObj*) alignObjArray.UncheckedAt(j);
-      if (alobj->ApplyToGeometry() == kFALSE) flag = kFALSE;
+      AliDebugClass(5,Form("Error applying alignment object for volume %s !",alobj->GetSymName()));
+    }else{
+      AliDebugClass(5,Form("Alignment object for volume %s applied successfully",alobj->GetSymName()));
     }
 
-  if (AliDebugLevelClass() >= 1) {
-    fgGeometry->GetTopNode()->CheckOverlaps(1);
+  }
+
+  if (AliDebugLevelClass() > 5) {
+    fgGeometry->CheckOverlaps(0.001);
     TObjArray* ovexlist = fgGeometry->GetListOfOverlaps();
     if(ovexlist->GetEntriesFast()){  
       AliErrorClass("The application of alignment objects to the geometry caused huge overlaps/extrusions!");
+      fgGeometry->PrintOverlaps();
    }
   }
 
@@ -1304,3 +1752,5 @@ Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* detName, Int_t runnum, I
 
   return ApplyAlignObjsToGeom(*alignObjArray);
 }
+
+