X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=STEER%2FAliGeomManager.cxx;h=c97a571dee17aa5879a0f09e15d366a3aa4d126b;hb=439b5096a34b91270cdb9eacc2f4c58a6dda29c5;hp=65a4e491c21c20bf3f056fce3b1dad974f2ec81a;hpb=67dd553539b62fad2cda86ae0457ee02af8115b7;p=u%2Fmrichter%2FAliRoot.git diff --git a/STEER/AliGeomManager.cxx b/STEER/AliGeomManager.cxx index 65a4e491c21..c97a571dee1 100644 --- a/STEER/AliGeomManager.cxx +++ b/STEER/AliGeomManager.cxx @@ -27,11 +27,16 @@ #include #include #include +#include +#include +#include +#include +#include #include "AliGeomManager.h" #include "AliLog.h" #include "AliAlignObj.h" -#include "AliAlignObjAngles.h" +#include "AliAlignObjParams.h" #include "AliCDBManager.h" #include "AliCDBStorage.h" #include "AliCDBEntry.h" @@ -45,9 +50,10 @@ Int_t AliGeomManager::fgLayerSize[kLastLayer - kFirstLayer] = { 36, 36, // TPC inner and outer chambers 90, 90, 90, 90, 90, 90, // 6 TRD chambers' layers 1638, // TOF - 1, 1, // PHOS ?? + 5, 5, // PHOS,CPV 7, // HMPID ?? - 1 // MUON ?? + 1, // MUON ?? + 12 // EMCAL }; const char* AliGeomManager::fgLayerName[kLastLayer - kFirstLayer] = { @@ -58,22 +64,10 @@ const char* AliGeomManager::fgLayerName[kLastLayer - kFirstLayer] = { "TRD chambers layer 1", "TRD chambers layer 2", "TRD chambers layer 3", "TRD chambers layer 4", "TRD chambers layer 5", "TRD chambers layer 6", "TOF 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 + "PHOS EMC layer","PHOS CPV layer", + "HMPID layer", + "MUON ?", + "EMCAL layer" }; TGeoPNEntry** AliGeomManager::fgPNEntry[kLastLayer - kFirstLayer] = { @@ -86,6 +80,7 @@ TGeoPNEntry** AliGeomManager::fgPNEntry[kLastLayer - kFirstLayer] = { 0x0, 0x0,0x0, 0x0, + 0x0, 0x0 }; @@ -99,41 +94,67 @@ AliAlignObj** AliGeomManager::fgAlignObjs[kLastLayer - kFirstLayer] = { 0x0, 0x0,0x0, 0x0, + 0x0, 0x0 }; -AliGeomManager* AliGeomManager::fgInstance = 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; //_____________________________________________________________________________ -AliGeomManager* AliGeomManager::Instance() +void AliGeomManager::LoadGeometry(const char *geomFileName) { -// returns AliGeomManager instance (singleton) + // initialization + // Load geometry either from a file + // or from the corresponding CDB entry + + if(fgGeometry->IsLocked()){ + AliErrorClass("Cannot load a new geometry, the current one being locked. Setting internal geometry to null!!"); + fgGeometry = NULL; + return; + } - if (!fgInstance) { - fgInstance = new AliGeomManager(); - fgInstance->Init(); - } - return fgInstance; + fgGeometry = NULL; + if (geomFileName && (!gSystem->AccessPathName(geomFileName))) { + fgGeometry = TGeoManager::Import(geomFileName); + AliInfoClass(Form("From now on using geometry from custom geometry file \"%s\"",geomFileName)); + } + + if (!fgGeometry) { + AliCDBPath path("GRP","Geometry","Data"); + + AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath()); + if(!entry) AliFatalClass("Couldn't load geometry data from CDB!"); + + 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"))); + } + ResetPNEntriesLUT(); + InitPNEntriesLUT(); + InitNalignable(); } //_____________________________________________________________________________ -void AliGeomManager::Init() +void AliGeomManager::SetGeometry(TGeoManager * const geom) { -// initialization - if(!gGeoManager) AliFatal("Impossible to initialize AliGeomManager without an active geometry"); - fgGeometry = gGeoManager; - InitSymNamesLUT(); + // Load already active geometry + if (!geom) AliFatalClass("Pointer to the active geometry is 0x0!"); + ResetPNEntriesLUT(); + fgGeometry = geom; InitPNEntriesLUT(); + InitNalignable(); } //_____________________________________________________________________________ AliGeomManager::AliGeomManager(): - TObject(), - - // fgGeometry(NULL), - fAlignObjArray(NULL) + TObject() { // default constructor } @@ -142,8 +163,6 @@ AliGeomManager::AliGeomManager(): AliGeomManager::~AliGeomManager() { // dummy destructor - if(fAlignObjArray) fAlignObjArray->Delete(); - delete fAlignObjArray; } //_____________________________________________________________________________ @@ -158,7 +177,7 @@ Int_t AliGeomManager::LayerSize(Int_t layerId) } else { return fgLayerSize[layerId - kFirstLayer]; - } + } } //_____________________________________________________________________________ @@ -173,7 +192,7 @@ const char* AliGeomManager::LayerName(Int_t layerId) } else { return fgLayerName[layerId - kFirstLayer]; - } + } } //_____________________________________________________________________________ @@ -320,27 +339,25 @@ Bool_t AliGeomManager::GetFromGeometry(const char *symname, AliAlignObj &alobj) alobj.SetPars(0,0,0,0,0,0); alobj.SetSymName(symname); - if (!gGeoManager || !gGeoManager->IsClosed()) { + if (!fgGeometry || !fgGeometry->IsClosed()) { AliErrorClass("Can't get the alignment object! gGeoManager doesn't exist or it is still opened!"); return kFALSE; } - if (!gGeoManager->GetListOfPhysicalNodes()) { + if (!fgGeometry->GetListOfPhysicalNodes()) { AliErrorClass("Can't get the alignment object! gGeoManager doesn't contain any aligned nodes!"); return kFALSE; } - ReactIfChangedGeom(); - const char *path; - TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname); + TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname); if(pne){ path = pne->GetTitle(); }else{ AliWarningClass(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname)); path = symname; } - TObjArray* nodesArr = gGeoManager->GetListOfPhysicalNodes(); + TObjArray* nodesArr = fgGeometry->GetListOfPhysicalNodes(); TGeoPhysicalNode* node = NULL; for (Int_t iNode = 0; iNode < nodesArr->GetEntriesFast(); iNode++) { TGeoPhysicalNode* tempNode = (TGeoPhysicalNode*) nodesArr->UncheckedAt(iNode); @@ -352,7 +369,7 @@ Bool_t AliGeomManager::GetFromGeometry(const char *symname, AliAlignObj &alobj) } if (!node) { - if (!gGeoManager->cd(path)) { + if (!fgGeometry->cd(path)) { AliErrorClass(Form("%s not valid neither as symbolic volume name nor as volume path!",path)); return kFALSE; } @@ -377,29 +394,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 - - if(fgAlignObjs[0]) return; - - ReactIfChangedGeom(); - + // Loop over all alignable volumes and extract + // the corresponding alignment objects from + // the TGeo geometry + // for (Int_t iLayer = kFirstLayer; iLayer < AliGeomManager::kLastLayer; iLayer++) { - fgAlignObjs[iLayer-kFirstLayer] = new AliAlignObj*[LayerSize(iLayer)]; + if (!fgAlignObjs[iLayer-kFirstLayer]) { + 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; @@ -422,7 +438,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; @@ -436,225 +453,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; } - ReactIfChangedGeom(); - 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 - // + // 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"; @@ -664,26 +927,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"; @@ -700,12 +1001,115 @@ 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."); + } + + if(detsString.Contains("PHOS")) + { + /********************* PHOS EMC layer ***********************/ + + 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."); + } + + if(detsString.Contains("EMCAL")) + { + /********************* EMCAL layer ***********************/ + + AliDebugClass(2,"Checking consistency of symbolic names for EMCAL layers"); + TString str = "EMCAL/FullSupermodule"; + modnum=0; + + for (Int_t iModule=1; iModule <= 12; iModule++) { + symname = str; + symname += iModule; + if(iModule >10) { + symname = "EMCAL/HalfSupermodule"; + symname += iModule-10; + } + modnum = iModule-1; + 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; + } //_____________________________________________________________________________ @@ -717,33 +1121,39 @@ void AliGeomManager::InitPNEntriesLUT() // The LUTs are static; they are created at the creation of the // AliGeomManager instance and recreated if the geometry has changed // - - for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){ - if(!fgPNEntry[iLayer]) fgPNEntry[iLayer] = new TGeoPNEntry*[fgLayerSize[iLayer]]; + if(!fgGeometry) { + AliErrorClass("Impossible to initialize PNEntries LUT without an active geometry"); + return; } - for (Int_t iLayer = 0; iLayer < (kLastLayer-kFirstLayer); iLayer++){ - for(Int_t modnum=0; modnumGetAlignableEntry(fgSymName[iLayer-kFirstLayer][modnum].Data()); + for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){ + if (!fgPNEntry[iLayer]) fgPNEntry[iLayer] = new TGeoPNEntry*[fgLayerSize[iLayer]]; + for(Int_t modnum=0; modnumGetAlignableEntryByUID(LayerToVolUID(iLayer+1,modnum)); } } } //______________________________________________________________________ -TGeoHMatrix* AliGeomManager::GetMatrix(TGeoPNEntry* pne) +TGeoHMatrix* AliGeomManager::GetMatrix(TGeoPNEntry * const 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(); const char* path = pne->GetTitle(); - if (!gGeoManager->cd(path)) { + if (!fgGeometry->cd(path)) { AliErrorClass(Form("Volume path %s not valid!",path)); return NULL; } - return gGeoManager->GetCurrentMatrix(); + return fgGeometry->GetCurrentMatrix(); } //______________________________________________________________________ @@ -752,8 +1162,6 @@ TGeoHMatrix* AliGeomManager::GetMatrix(Int_t index) // Get the global transformation matrix for a given alignable volume // identified by its unique ID 'index' by quering the TGeoManager - ReactIfChangedGeom(); - TGeoPNEntry *pne = GetPNEntry(index); if (!pne) return NULL; @@ -766,8 +1174,12 @@ TGeoHMatrix* AliGeomManager::GetMatrix(const char* symname) // Get the global transformation matrix for a given alignable volume // identified by its symbolic name 'symname' by quering the TGeoManager - ReactIfChangedGeom(); - TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname); + if (!fgGeometry || !fgGeometry->IsClosed()) { + AliErrorClass("No active geometry or geometry not yet closed!"); + return NULL; + } + + TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname); if (!pne) return NULL; return GetMatrix(pne); @@ -804,89 +1216,154 @@ Bool_t AliGeomManager::GetRotation(Int_t index, Double_t r[9]) } //_____________________________________________________________________________ -Bool_t AliGeomManager::GetOrigGlobalMatrix(const char *symname, TGeoHMatrix &m) +Bool_t AliGeomManager::GetDeltaForBranch(Int_t index, TGeoHMatrix &inclusiveD) { - // 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 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. // - if (!gGeoManager || !gGeoManager->IsClosed()) { - AliErrorClass("Can't get the original global matrix! gGeoManager doesn't exist or it is still opened!"); + 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; } - - if (!gGeoManager->GetListOfPhysicalNodes()) { + 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 + // 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()) { + AliErrorClass("No active geometry or geometry not yet closed!"); + return kFALSE; + } + if (!fgGeometry->GetListOfPhysicalNodes()) { AliWarningClass("gGeoManager doesn't contain any aligned nodes!"); - if (!gGeoManager->cd(symname)) { + if (!fgGeometry->cd(symname)) { AliErrorClass(Form("Volume path %s not valid!",symname)); return kFALSE; } else { - m = *gGeoManager->GetCurrentMatrix(); + m = *fgGeometry->GetCurrentMatrix(); return kTRUE; } } + TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname); const char* path = NULL; - TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname); 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; } - if (!gGeoManager->CheckPath(path)) { - AliErrorClass(Form("Volume path %s not valid!",path)); + return GetOrigGlobalMatrixFromPath(path,m); +} + +//_____________________________________________________________________________ +Bool_t AliGeomManager::GetOrigGlobalMatrixFromPath(const char *path, TGeoHMatrix &m) +{ + // 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(); + + if (!fgGeometry || !fgGeometry->IsClosed()) { + AliErrorClass("Can't get the original global matrix! gGeoManager doesn't exist or it is still opened!"); return kFALSE; } - m.Clear(); + if (!fgGeometry->CheckPath(path)) { + AliErrorClass(Form("Volume path %s not valid!",path)); + return kFALSE; + } - TIter next(gGeoManager->GetListOfPhysicalNodes()); - gGeoManager->cd(path); + TIter next(fgGeometry->GetListOfPhysicalNodes()); + fgGeometry->cd(path); - while(gGeoManager->GetLevel()){ + while(fgGeometry->GetLevel()){ TGeoPhysicalNode *physNode = NULL; next.Reset(); - TGeoNode *node = gGeoManager->GetCurrentNode(); + TGeoNode *node = fgGeometry->GetCurrentNode(); while ((physNode=(TGeoPhysicalNode*)next())) if (physNode->GetNode() == node) break; 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(); m.MultiplyLeft(lm); - gGeoManager->CdUp(); + fgGeometry->CdUp(); } return kTRUE; } -//______________________________________________________________________ -Bool_t AliGeomManager::GetOrigGlobalMatrix(Int_t index, TGeoHMatrix &m) +//_____________________________________________________________________________ +TGeoHMatrix* AliGeomManager::GetOrigGlobalMatrix(TGeoPNEntry * const pne) { - // Get the original (ideal geometry) TGeo matrix for - // a given module identified by 'index'. - // The method is slow, so it should be used - // with great care. - - m.Clear(); + // The method returns global matrix for the ideal detector geometry + // using the corresponding TGeoPNEntry as an input. + // 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; + } - ReactIfChangedGeom(); - const char *symname = SymName(index); - if (!symname) return kFALSE; + return pne->GetGlobalOrig(); +} - return GetOrigGlobalMatrix(symname,m); +//______________________________________________________________________ +TGeoHMatrix* AliGeomManager::GetOrigGlobalMatrix(Int_t index) +{ + // 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. + // + TGeoPNEntry* pne = GetPNEntry(index); + return pne->GetGlobalOrig(); } //______________________________________________________________________ @@ -895,10 +1372,10 @@ Bool_t AliGeomManager::GetOrigTranslation(Int_t index, Double_t t[3]) // Get the original translation vector (ideal geometry) // for a given module 'index' by quering the TGeoManager - TGeoHMatrix m; - if (!GetOrigGlobalMatrix(index,m)) return kFALSE; + TGeoHMatrix *m = GetOrigGlobalMatrix(index); + if (!m) return kFALSE; - Double_t *trans = m.GetTranslation(); + Double_t *trans = m->GetTranslation(); for (Int_t i = 0; i < 3; i++) t[i] = trans[i]; return kTRUE; @@ -910,10 +1387,10 @@ Bool_t AliGeomManager::GetOrigRotation(Int_t index, Double_t r[9]) // Get the original rotation matrix (ideal geometry) // for a given module 'index' by quering the TGeoManager - TGeoHMatrix m; - if (!GetOrigGlobalMatrix(index,m)) return kFALSE; + TGeoHMatrix *m = GetOrigGlobalMatrix(index); + if (!m) return kFALSE; - Double_t *rot = m.GetRotationMatrix(); + Double_t *rot = m->GetRotationMatrix(); for (Int_t i = 0; i < 9; i++) r[i] = rot[i]; return kTRUE; @@ -922,16 +1399,15 @@ Bool_t AliGeomManager::GetOrigRotation(Int_t index, Double_t r[9]) //______________________________________________________________________ const TGeoHMatrix* AliGeomManager::GetTracking2LocalMatrix(Int_t index) { - // Get the matrix which transforms from the tracking to local r.s. + // Get the matrix which transforms from the tracking to the local RS // The method queries directly the TGeoPNEntry - ReactIfChangedGeom(); TGeoPNEntry *pne = GetPNEntry(index); if (!pne) return NULL; 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; } @@ -966,22 +1442,13 @@ TGeoPNEntry* AliGeomManager::GetPNEntry(Int_t voluid) { return GetPNEntry(layerId,modId); } -//_____________________________________________________________________________ -TGeoPNEntry* AliGeomManager::GetPNEntry(UShort_t voluid) { - // Returns the TGeoPNEntry for the given global volume ID "voluid" - // - Int_t modId; - ELayerID layerId = VolUIDToLayer(voluid,modId); - return GetPNEntry(layerId,modId); -} - //_____________________________________________________________________________ TGeoPNEntry* AliGeomManager::GetPNEntry(ELayerID layerId, Int_t modId) { // Returns the TGeoPNEntry for a given layer // and module ID // - ReactIfChangedGeom(); + 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; @@ -990,6 +1457,100 @@ 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; pniGetEntriesFast(); 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; + 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); + TString pneName = 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) { @@ -1005,9 +1566,9 @@ Bool_t AliGeomManager::ApplyAlignObjsFromCDB(const char* AlignDetsList) // Finally an overlaps check is performed. // - if(!fAlignObjArray) fAlignObjArray = new TObjArray(); - fAlignObjArray->Clear(); - fAlignObjArray->SetOwner(0); + TObjArray alignObjArray; + alignObjArray.Clear(); + alignObjArray.SetOwner(0); TString alObjsNotLoaded=""; TString alObjsLoaded=""; @@ -1019,8 +1580,8 @@ Bool_t AliGeomManager::ApplyAlignObjsFromCDB(const char* AlignDetsList) while((str = (TObjString*) iter.Next())){ TString det(str->String()); - AliInfo(Form("Loading alignment objs for %s",det.Data())); - if(!LoadAlignObjsFromCDBSingleDet(det.Data())){ + AliDebugClass(5,Form("Loading alignment objs for %s",det.Data())); + if(!LoadAlignObjsFromCDBSingleDet(det.Data(),alignObjArray)){ alObjsNotLoaded += det.Data(); alObjsNotLoaded += " "; } else { @@ -1028,17 +1589,19 @@ Bool_t AliGeomManager::ApplyAlignObjsFromCDB(const char* AlignDetsList) alObjsLoaded += " "; } } + detsarr->Delete(); + delete detsarr; - if(!alObjsLoaded.IsNull()) AliInfo(Form("Alignment objects loaded for: %s", - alObjsLoaded.Data())); - if(!alObjsNotLoaded.IsNull()) AliInfo(Form("Didn't/couldn't load alignment objects for: %s", - alObjsNotLoaded.Data())); + if(!alObjsLoaded.IsNull()) AliInfoClass(Form("Alignment objects loaded for: %s", + alObjsLoaded.Data())); + if(!alObjsNotLoaded.IsNull()) AliInfoClass(Form("Didn't/couldn't load alignment objects for: %s", + alObjsNotLoaded.Data())); - return(ApplyAlignObjsToGeom(fAlignObjArray)); + return ApplyAlignObjsToGeom(alignObjArray); } //_____________________________________________________________________________ -Bool_t AliGeomManager::LoadAlignObjsFromCDBSingleDet(const char* detName) +Bool_t AliGeomManager::LoadAlignObjsFromCDBSingleDet(const char* detName, TObjArray& alignObjArray) { // Adds the alignable objects found in the CDBEntry for the detector // passed as argument to the array of all alignment objects to be applyed @@ -1046,7 +1609,7 @@ Bool_t AliGeomManager::LoadAlignObjsFromCDBSingleDet(const char* detName) // // Fills array of single detector's alignable objects from CDB - AliDebug(2, Form("Loading alignment objs for detector: %s",detName)); + AliDebugClass(2, Form("Loading alignment objs for detector: %s",detName)); AliCDBEntry *entry; @@ -1054,56 +1617,67 @@ Bool_t AliGeomManager::LoadAlignObjsFromCDBSingleDet(const char* detName) entry=AliCDBManager::Instance()->Get(path.GetPath()); if(!entry){ - AliDebug(2,Form("Couldn't load alignment data for detector %s",detName)); + AliDebugClass(2,Form("Couldn't load alignment data for detector %s",detName)); return kFALSE; } entry->SetOwner(1); TClonesArray *alignArray = (TClonesArray*) entry->GetObject(); alignArray->SetOwner(0); - AliDebug(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); // loop over align objects in detector while( ( alignObj=(AliAlignObj *) iter.Next() ) ){ - fAlignObjArray->Add(alignObj); + alignObjArray.Add(alignObj); } // delete entry --- Don't delete, it is cached! - AliDebug(2, Form("fAlignObjArray entries: %d",fAlignObjArray->GetEntries() )); + AliDebugClass(2, Form("fAlignObjArray entries: %d",alignObjArray.GetEntries() )); return kTRUE; } //_____________________________________________________________________________ -Bool_t AliGeomManager::ApplyAlignObjsToGeom(TObjArray* alObjArray) +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 // - ReactIfChangedGeom(); - - alObjArray->Sort(); - Int_t nvols = alObjArray->GetEntriesFast(); + alignObjArray.Sort(); + Int_t nvols = alignObjArray.GetEntriesFast(); Bool_t flag = kTRUE; for(Int_t j=0; jApplyToGeometry(ovlpcheck); + if(!flag) { - AliAlignObj* alobj = (AliAlignObj*) alObjArray->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) { - gGeoManager->GetTopNode()->CheckOverlaps(1); - TObjArray* ovexlist = gGeoManager->GetListOfOverlaps(); + } + + if (AliDebugLevelClass() > 5) { + fgGeometry->CheckOverlaps(0.001); + TObjArray* ovexlist = fgGeometry->GetListOfOverlaps(); if(ovexlist->GetEntriesFast()){ - AliError("The application of alignment objects to the geometry caused huge overlaps/extrusions!"); + AliErrorClass("The application of alignment objects to the geometry caused huge overlaps/extrusions!"); + fgGeometry->PrintOverlaps(); } } + // Update the TGeoPhysicalNodes + fgGeometry->RefreshPhysicalNodes(); + return flag; } @@ -1122,14 +1696,14 @@ Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* fileName, const char* cl return kFALSE; } - TClonesArray* alObjArray = ((TClonesArray*) inFile->Get(clArrayName)); + TClonesArray* alignObjArray = ((TClonesArray*) inFile->Get(clArrayName)); inFile->Close(); - if (!alObjArray) { + if (!alignObjArray) { AliErrorClass(Form("Could not get array (%s) from file (%s) !",clArrayName,fileName)); return kFALSE; } - return ApplyAlignObjsToGeom(alObjArray); + return ApplyAlignObjsToGeom(*alignObjArray); } @@ -1144,9 +1718,9 @@ Bool_t AliGeomManager::ApplyAlignObjsToGeom(AliCDBParam* param, AliCDBId& Id) AliCDBStorage* storage = AliCDBManager::Instance()->GetStorage(param); AliCDBEntry* entry = storage->Get(Id); - TClonesArray* AlObjArray = ((TClonesArray*) entry->GetObject()); + TClonesArray* alignObjArray = ((TClonesArray*) entry->GetObject()); - return ApplyAlignObjsToGeom(AlObjArray); + return ApplyAlignObjsToGeom(*alignObjArray); } @@ -1179,21 +1753,20 @@ Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* detName, Int_t runnum, I AliCDBEntry* entry = AliCDBManager::Instance()->Get(path.GetPath(),runnum,version,sversion); if(!entry) return kFALSE; - TClonesArray* AlObjArray = ((TClonesArray*) entry->GetObject()); + TClonesArray* alignObjArray = ((TClonesArray*) entry->GetObject()); - return ApplyAlignObjsToGeom(AlObjArray); + return ApplyAlignObjsToGeom(*alignObjArray); } //_____________________________________________________________________________ -void AliGeomManager::ReactIfChangedGeom() +void AliGeomManager::ResetPNEntriesLUT() { - // Check if the TGeo geometry has changed. In that case reinitialize the - // look-up tables + // cleans static arrays containing the information on currently loaded geometry + // + for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){ + if (!fgPNEntry[iLayer]) continue; + for (Int_t modnum=0; modnum