#include <TClass.h>
#include <TFile.h>
#include <TGeoManager.h>
#include <TObjString.h>
#include <TGeoPhysicalNode.h>
#include <TClonesArray.h>
#include <TGeoMatrix.h>
#include <TGeoPhysicalNode.h>
#include <TSystem.h>
#include <TStopwatch.h>
#include <TGeoOverlap.h>
#include <TPluginManager.h>
#include <TROOT.h>
#include "AliGeomManager.h"
#include "AliLog.h"
#include "AliAlignObj.h"
#include "AliAlignObjParams.h"
#include "AliCDBManager.h"
#include "AliCDBStorage.h"
#include "AliCDBEntry.h"
ClassImp(AliGeomManager)
Int_t AliGeomManager::fgLayerSize[kLastLayer - kFirstLayer] = {
80, 160,
84, 176,
748, 950,
36, 36,
90, 90, 90, 90, 90, 90,
1638,
5, 5,
7,
1,
22
};
const char* AliGeomManager::fgLayerName[kLastLayer - kFirstLayer] = {
"ITS inner pixels layer", "ITS outer pixels layer",
"ITS inner drifts layer", "ITS outer drifts layer",
"ITS inner strips layer", "ITS outer strips layer",
"TPC inner chambers layer", "TPC outer chambers layer",
"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",
"PHOS EMC layer","PHOS CPV layer",
"HMPID layer",
"MUON ?",
"EMCAL layer"
};
TGeoPNEntry** AliGeomManager::fgPNEntry[kLastLayer - kFirstLayer] = {
0x0,0x0,
0x0,0x0,
0x0,0x0,
0x0,0x0,
0x0,0x0,0x0,
0x0,0x0,0x0,
0x0,
0x0,0x0,
0x0,
0x0,
0x0
};
AliAlignObj** AliGeomManager::fgAlignObjs[kLastLayer - kFirstLayer] = {
0x0,0x0,
0x0,0x0,
0x0,0x0,
0x0,0x0,
0x0,0x0,0x0,
0x0,0x0,0x0,
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","AD","MFT","FIT"};
Int_t AliGeomManager::fgNalignable[fgkNDetectors] = {0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
TGeoManager* AliGeomManager::fgGeometry = 0x0;
void AliGeomManager::Destroy()
{
TGeoManager::UnlockGeometry();
delete gGeoManager;
fgGeometry = gGeoManager = 0;
ResetPNEntriesLUT();
}
void AliGeomManager::LoadGeometry(const char *geomFileName)
{
if(fgGeometry->IsLocked()){
AliErrorClass("Cannot load a new geometry, the current one being locked. Setting internal geometry to null!!");
fgGeometry = NULL;
return;
}
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("GRP/Geometry/Data")));
}
ResetPNEntriesLUT();
InitPNEntriesLUT();
InitNalignable();
}
void AliGeomManager::SetGeometry(TGeoManager * const geom)
{
if (!geom) AliFatalClass("Pointer to the active geometry is 0x0!");
ResetPNEntriesLUT();
fgGeometry = geom;
InitPNEntriesLUT();
InitNalignable();
}
AliGeomManager::AliGeomManager():
TObject()
{
}
AliGeomManager::~AliGeomManager()
{
}
Int_t AliGeomManager::LayerSize(Int_t layerId)
{
if (layerId < kFirstLayer || layerId >= kLastLayer) {
AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer));
return 0;
}
else {
return fgLayerSize[layerId - kFirstLayer];
}
}
const char* AliGeomManager::LayerName(Int_t layerId)
{
if (layerId < kFirstLayer || layerId >= kLastLayer) {
AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer));
return "Invalid Layer!";
}
else {
return fgLayerName[layerId - kFirstLayer];
}
}
UShort_t AliGeomManager::LayerToVolUID(ELayerID layerId, Int_t modId)
{
return ((UShort_t(layerId) << 11) | UShort_t(modId));
}
UShort_t AliGeomManager::LayerToVolUID(Int_t layerId, Int_t modId)
{
return ((UShort_t(layerId) << 11) | UShort_t(modId));
}
UShort_t AliGeomManager::LayerToVolUIDSafe(ELayerID layerId, Int_t modId)
{
if(modId < 0 || modId >= LayerSize(layerId)){
AliErrorClass(Form("Invalid volume id %d ! Range of valid ids for layer \"%s\" is [0, %d] !",modId,LayerName(layerId),LayerSize(layerId)-1));
return 0;
}
return ((UShort_t(layerId) << 11) | UShort_t(modId));
}
UShort_t AliGeomManager::LayerToVolUIDSafe(Int_t layerId, Int_t modId)
{
if(modId < 0 || modId >= LayerSize(layerId)){
AliErrorClass(Form("Invalid volume id %d ! Range of valid ids for layer \"%s\" is [0, %d] !",modId,LayerName(layerId),LayerSize(layerId)-1));
return 0;
}
return ((UShort_t(layerId) << 11) | UShort_t(modId));
}
AliGeomManager::ELayerID AliGeomManager::VolUIDToLayer(UShort_t voluid, Int_t &modId)
{
modId = voluid & 0x7ff;
return VolUIDToLayer(voluid);
}
AliGeomManager::ELayerID AliGeomManager::VolUIDToLayer(UShort_t voluid)
{
return ELayerID(voluid >> 11);
}
AliGeomManager::ELayerID AliGeomManager::VolUIDToLayerSafe(UShort_t voluid, Int_t &modId)
{
ELayerID layId = VolUIDToLayerSafe(voluid);
if(layId != AliGeomManager::kInvalidLayer){
Int_t mId = Int_t(voluid & 0x7ff);
if( mId>=0 && mId<LayerSize(layId)){
modId = mId;
return layId;
}
}
AliErrorClass(Form("Invalid unique volume id: %d !",voluid));
modId = -1;
return kInvalidLayer;
}
AliGeomManager::ELayerID AliGeomManager::VolUIDToLayerSafe(UShort_t voluid)
{
if( (voluid >> 11) < kLastLayer) return ELayerID(voluid >> 11);
AliErrorClass(Form("Invalid layer id: %d !",(voluid >> 11)));
return kInvalidLayer;
}
Bool_t AliGeomManager::GetFromGeometry(const char *symname, AliAlignObj &alobj)
{
alobj.SetPars(0,0,0,0,0,0);
alobj.SetSymName(symname);
if (!fgGeometry || !fgGeometry->IsClosed()) {
AliErrorClass("Can't get the alignment object! gGeoManager doesn't exist or it is still opened!");
return kFALSE;
}
if (!fgGeometry->GetListOfPhysicalNodes()) {
AliErrorClass("Can't get the alignment object! gGeoManager doesn't contain any aligned nodes!");
return kFALSE;
}
const char *path;
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 = fgGeometry->GetListOfPhysicalNodes();
TGeoPhysicalNode* node = NULL;
for (Int_t iNode = 0; iNode < nodesArr->GetEntriesFast(); iNode++) {
TGeoPhysicalNode* tempNode = (TGeoPhysicalNode*) nodesArr->UncheckedAt(iNode);
const char *nodePath = tempNode->GetName();
if (strcmp(path,nodePath) == 0) {
node = tempNode;
break;
}
}
if (!node) {
if (!fgGeometry->cd(path)) {
AliErrorClass(Form("%s not valid neither as symbolic volume name nor as volume path!",path));
return kFALSE;
}
else {
AliWarningClass(Form("Volume (%s) has not been misaligned!",path));
return kTRUE;
}
}
TGeoHMatrix align,gprime,g,ginv,l;
gprime = *node->GetMatrix();
l = *node->GetOriginalMatrix();
g = *node->GetMatrix(node->GetLevel()-1);
g *= l;
ginv = g.Inverse();
align = gprime * ginv;
return alobj.SetMatrix(align);
}
void AliGeomManager::InitAlignObjFromGeometry()
{
for (Int_t iLayer = kFirstLayer; iLayer < AliGeomManager::kLastLayer; 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 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)
{
Int_t modId;
ELayerID layerId = VolUIDToLayer(voluid,modId);
return GetAlignObj(layerId,modId);
}
AliAlignObj* AliGeomManager::GetAlignObj(ELayerID layerId, Int_t modId)
{
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;
}
InitAlignObjFromGeometry();
return fgAlignObjs[layerId-kFirstLayer][modId];
}
const char* AliGeomManager::SymName(UShort_t voluid)
{
Int_t modId;
ELayerID layerId = VolUIDToLayer(voluid,modId);
return SymName(layerId,modId);
}
const char* AliGeomManager::SymName(ELayerID layerId, Int_t modId)
{
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;
}
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();
}
Bool_t AliGeomManager::CheckSymNamesLUT(const char* )
{
TString detsString = "";
if(fgGeometry->CheckPath("ALIC_1/ITSV_1")) detsString+="ITS ";
if(fgGeometry->CheckPath("ALIC_1/TPC_M_1")) detsString+="TPC ";
TString tofsm;
TString baseTof("ALIC_1/B077_1/BSEGMO");
TString middleTof("_1/BTOF");
TString trailTof("_1/FTOA_0");
Bool_t tofActive=kFALSE;
Bool_t tofSMs[18];
for(Int_t sm=0; sm<18; sm++)
{
tofSMs[sm]=kFALSE;
tofsm=baseTof;
tofsm += sm;
tofsm += middleTof;
tofsm += sm;
tofsm += trailTof;
if(fgGeometry->CheckPath(tofsm.Data()))
{
tofActive=kTRUE;
tofSMs[sm]=kTRUE;
}
}
if(tofActive) detsString+="TOF ";
TString trdsm;
TString baseTrd("ALIC_1/B077_1/BSEGMO");
TString middleTrd("_1/BTRD");
TString trailTrd("_1/UTR1_1");
Bool_t trdActive=kFALSE;
Bool_t trdSMs[18];
for(Int_t sm=0; sm<18; sm++)
{
trdSMs[sm]=kFALSE;
trdsm=baseTrd;
trdsm += sm;
trdsm += middleTrd;
trdsm += sm;
trdsm += trailTrd;
if(fgGeometry->CheckPath(trdsm.Data()))
{
trdActive=kTRUE;
trdSMs[sm]=kTRUE;
}
}
if(trdActive) detsString+="TRD ";
if(fgGeometry->CheckPath("ALIC_1/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 ";
TString emcalSM;
TString baseEmcalSM("ALIC_1/XEN1_1/");
Bool_t emcalActive=kFALSE;
Bool_t emcalSMs[22] = {kFALSE};
for(Int_t sm=0; sm<22; sm++)
{
emcalSM=baseEmcalSM;
if(sm<10){
emcalSM += "SMOD_";
emcalSM += (sm+1);
}else if(sm/2 == 5){
emcalSM += "SM10_";
emcalSM += (sm-9);
}else if(sm > 11){
emcalSM += "DCSM_";
emcalSM += (sm-11);
}
if(fgGeometry->CheckPath(emcalSM.Data()))
{
emcalActive=kTRUE;
emcalSMs[sm]=kTRUE;
}
}
if(emcalActive) detsString+="EMCAL ";
TString symname;
const char* sname;
TGeoPNEntry* pne = 0x0;
Int_t uid;
Int_t modnum;
if(detsString.Contains("ITS")){
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;
{
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;
}
}
}
}
}
}
{
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;
}
}
}
}
}
}
{
modnum=0;
for(Int_t c1 = 1; c1<=14; c1++){
strEntryName1 = strSDD;
strEntryName1 += 2;
strEntryName1 +=strLadder;
strEntryName1 += (c1-1);
for(Int_t c2 =1; c2<=6; c2++){
symname = strEntryName1;
symname += strSensor;
symname += (c2-1);
uid = LayerToVolUID(kSDD1,modnum++);
pne = fgGeometry->GetAlignableEntryByUID(uid);
if(!pne)
{
AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
return kFALSE;
}
sname = pne->GetName();
if(symname.CompareTo(sname))
{
AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
"Expected was %s, found was %s!", uid, symname.Data(), sname));
return kFALSE;
}
}
}
}
{
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);
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;
}
}
}
}
{
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);
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;
}
}
}
}
{
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);
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.");
}
if(detsString.Contains("TPC"))
{
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";
{
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;
}
}
}
{
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.");
}
if(detsString.Contains("TOF"))
{
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";
for (Int_t isect = 0; isect < nSectors; isect++) {
if(tofSMs[isect]) AliDebugClass(3,Form("Consistency check for symnames of TOF supermodule %d.",isect));
for (Int_t istr = 1; istr <= nStrips; istr++) {
symname = snSM;
symname += Form("%02d",isect);
symname += snSTRIP;
symname += Form("%02d",istr);
uid = LayerToVolUID(kTOF,modnum++);
if(!tofSMs[isect]) continue;
if ((isect==13 || isect==14 || isect==15) && (istr >= 39 && istr <= 53)) continue;
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.");
}
if(detsString.Contains("HMPID"))
{
AliDebugClass(2,"Checking consistency of symbolic names for HMPID layers");
TString str = "/HMPID/Chamber";
for (modnum=0; modnum < 7; modnum++) {
symname = str;
symname += modnum;
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.");
}
if(detsString.Contains("TRD"))
{
AliDebugClass(2,"Checking consistency of symbolic names for TRD layers");
Int_t arTRDlayId[6] = {kTRD1, kTRD2, kTRD3, kTRD4, kTRD5, kTRD6};
TString snStr = "TRD/sm";
TString snApp1 = "/st";
TString snApp2 = "/pl";
for(Int_t layer=0; layer<6; layer++){
modnum=0;
AliDebugClass(3,Form("Consistency check for symnames of TRD layer %d.",layer));
for (Int_t isect = 0; isect < 18; isect++) {
for (Int_t icham = 0; icham < 5; icham++) {
symname = snStr;
symname += Form("%02d",isect);
symname += snApp1;
symname += icham;
symname += snApp2;
symname += layer;
uid = LayerToVolUID(arTRDlayId[layer],modnum++);
if(!trdSMs[isect]) continue;
if ((isect==13 || isect==14 || isect==15) && icham==2) continue;
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"))
{
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;
}
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"))
{
AliDebugClass(2,"Checking consistency of symbolic names for EMCAL layers");
TString str = "EMCAL/FullSupermodule";
modnum=0;
for (Int_t iModule=0; iModule < 22; iModule++) {
if(!emcalSMs[iModule]) continue;
symname = str;
symname += iModule+1;
if(iModule/2 == 5) {
symname = "EMCAL/HalfSupermodule";
symname += iModule-9;
}else if(iModule > 11) {
symname = "EMCAL/DCALSupermodule";
symname += iModule-11;
}
modnum = iModule;
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;
}
void AliGeomManager::InitPNEntriesLUT()
{
if(!fgGeometry) {
AliErrorClass("Impossible to initialize PNEntries LUT without an active geometry");
return;
}
for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){
if (!fgPNEntry[iLayer]) fgPNEntry[iLayer] = new TGeoPNEntry*[fgLayerSize[iLayer]];
for(Int_t modnum=0; modnum<fgLayerSize[iLayer]; modnum++){
fgPNEntry[iLayer][modnum] = fgGeometry->GetAlignableEntryByUID(LayerToVolUID(iLayer+1,modnum));
}
}
}
TGeoHMatrix* AliGeomManager::GetMatrix(TGeoPNEntry * const pne)
{
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 (!fgGeometry->cd(path)) {
AliErrorClass(Form("Volume path %s not valid!",path));
return NULL;
}
return fgGeometry->GetCurrentMatrix();
}
TGeoHMatrix* AliGeomManager::GetMatrix(Int_t index)
{
TGeoPNEntry *pne = GetPNEntry(index);
if (!pne) return NULL;
return GetMatrix(pne);
}
TGeoHMatrix* AliGeomManager::GetMatrix(const char* 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);
}
Bool_t AliGeomManager::GetTranslation(Int_t index, Double_t t[3])
{
TGeoHMatrix *m = GetMatrix(index);
if (!m) return kFALSE;
Double_t *trans = m->GetTranslation();
for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
return kTRUE;
}
Bool_t AliGeomManager::GetRotation(Int_t index, Double_t r[9])
{
TGeoHMatrix *m = GetMatrix(index);
if (!m) return kFALSE;
Double_t *rot = m->GetRotationMatrix();
for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
return kTRUE;
}
Bool_t AliGeomManager::GetDeltaForBranch(Int_t index, TGeoHMatrix &inclusiveD)
{
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)
{
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)
{
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 (!fgGeometry->cd(symname)) {
AliErrorClass(Form("Volume path %s not valid!",symname));
return kFALSE;
}
else {
m = *fgGeometry->GetCurrentMatrix();
return kTRUE;
}
}
TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname);
const char* path = NULL;
if(pne){
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;
}
return GetOrigGlobalMatrixFromPath(path,m);
}
Bool_t AliGeomManager::GetOrigGlobalMatrixFromPath(const char *path, TGeoHMatrix &m)
{
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;
}
if (!fgGeometry->CheckPath(path)) {
AliErrorClass(Form("Volume path %s not valid!",path));
return kFALSE;
}
TIter next(fgGeometry->GetListOfPhysicalNodes());
fgGeometry->cd(path);
while(fgGeometry->GetLevel()){
TGeoPhysicalNode *physNode = NULL;
next.Reset();
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();
} else
lm = node->GetMatrix();
m.MultiplyLeft(lm);
fgGeometry->CdUp();
}
return kTRUE;
}
TGeoHMatrix* AliGeomManager::GetOrigGlobalMatrix(TGeoPNEntry * const pne)
{
if (!fgGeometry || !fgGeometry->IsClosed()) {
AliErrorClass("Can't get the global matrix! gGeoManager doesn't exist or it is still opened!");
return NULL;
}
return pne->GetGlobalOrig();
}
TGeoHMatrix* AliGeomManager::GetOrigGlobalMatrix(Int_t index)
{
TGeoPNEntry* pne = GetPNEntry(index);
return pne->GetGlobalOrig();
}
Bool_t AliGeomManager::GetOrigTranslation(Int_t index, Double_t t[3])
{
TGeoHMatrix *m = GetOrigGlobalMatrix(index);
if (!m) return kFALSE;
Double_t *trans = m->GetTranslation();
for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
return kTRUE;
}
Bool_t AliGeomManager::GetOrigRotation(Int_t index, Double_t r[9])
{
TGeoHMatrix *m = GetOrigGlobalMatrix(index);
if (!m) return kFALSE;
Double_t *rot = m->GetRotationMatrix();
for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
return kTRUE;
}
const TGeoHMatrix* AliGeomManager::GetTracking2LocalMatrix(Int_t index)
{
TGeoPNEntry *pne = GetPNEntry(index);
if (!pne) return NULL;
const TGeoHMatrix *m = pne->GetMatrix();
if (!m)
AliErrorClass(Form("TGeoPNEntry (%s) contains no tracking-to-local matrix !",pne->GetName()));
return m;
}
Bool_t AliGeomManager::GetTrackingMatrix(Int_t index, TGeoHMatrix &m)
{
m.Clear();
TGeoHMatrix *m1 = GetMatrix(index);
if (!m1) return kFALSE;
const TGeoHMatrix *m2 = GetTracking2LocalMatrix(index);
if (!m2) return kFALSE;
m = *m1;
m.Multiply(m2);
return kTRUE;
}
TGeoPNEntry* AliGeomManager::GetPNEntry(Int_t voluid) {
Int_t modId;
ELayerID layerId = VolUIDToLayer(voluid,modId);
return GetPNEntry(layerId,modId);
}
TGeoPNEntry* AliGeomManager::GetPNEntry(ELayerID layerId, Int_t modId)
{
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;
}
return fgPNEntry[layerId-kFirstLayer][modId];
}
void AliGeomManager::CheckOverlapsOverPNs(Double_t threshold)
{
TObjArray* ovexlist = 0x0;
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);
Int_t levup=1;
while(((TGeoVolume*)pn->GetVolume(pn->GetLevel()-levup))->IsAssembly()) levup++;
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);
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)
{
Int_t index = -1 ;
for (index = 0; index < fgkNDetectors ; index++) {
if ( strcmp(module, fgkDetectorName[index]) == 0 )
break ;
}
if(index==fgkNDetectors) return -1;
return fgNalignable[index];
}
void AliGeomManager::InitNalignable()
{
Int_t nAlE = gGeoManager->GetNAlignable();
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)
{
TObjArray alignObjArray;
alignObjArray.Clear();
alignObjArray.SetOwner(0);
TString alObjsNotLoaded="";
TString alObjsLoaded="";
TString alignDetsString(alignDetsList);
TObjArray *detsarr = alignDetsString.Tokenize(' ');
TIter iter(detsarr);
TObjString *str = 0;
while((str = (TObjString*) iter.Next())){
TString det(str->String());
AliDebugClass(5,Form("Loading alignment objs for %s",det.Data()));
if(!LoadAlignObjsFromCDBSingleDet(det.Data(),alignObjArray)){
alObjsNotLoaded += det.Data();
alObjsNotLoaded += " ";
} else {
alObjsLoaded += det.Data();
alObjsLoaded += " ";
}
}
detsarr->Delete();
delete detsarr;
if(!alObjsLoaded.IsNull()) AliInfoClass(Form("Alignment objects loaded for: %s",
alObjsLoaded.Data()));
if(!alObjsNotLoaded.IsNull())
AliFatalClass(Form("Could not load alignment objects from OCDB for: %s",
alObjsNotLoaded.Data()));
return ApplyAlignObjsToGeom(alignObjArray);
}
Bool_t AliGeomManager::LoadAlignObjsFromCDBSingleDet(const char* detName, TObjArray& alignObjArray)
{
AliDebugClass(2, Form("Loading alignment objs for detector: %s",detName));
AliCDBEntry *entry;
AliCDBPath path(detName,"Align","Data");
entry=AliCDBManager::Instance()->Get(path.GetPath());
if(!entry){
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);
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);
while( ( alignObj=(AliAlignObj *) iter.Next() ) ){
alignObjArray.Add(alignObj);
}
AliDebugClass(2, Form("fAlignObjArray entries: %d",alignObjArray.GetEntries() ));
return kTRUE;
}
Bool_t AliGeomManager::ApplyAlignObjsToGeom(TObjArray& alignObjArray, Bool_t ovlpcheck)
{
alignObjArray.Sort();
Int_t nvols = alignObjArray.GetEntriesFast();
Bool_t flag = kTRUE;
for(Int_t j=0; j<nvols; j++)
{
AliAlignObj* alobj = (AliAlignObj*) alignObjArray.UncheckedAt(j);
if(!alobj->ApplyToGeometry(ovlpcheck))
{
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() > 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();
}
}
fgGeometry->RefreshPhysicalNodes();
return flag;
}
Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* fileName, const char* clArrayName)
{
TFile* inFile = TFile::Open(fileName,"READ");
if (!inFile || !inFile->IsOpen()) {
AliErrorClass(Form("Could not open file %s !",fileName));
return kFALSE;
}
TClonesArray* alignObjArray = ((TClonesArray*) inFile->Get(clArrayName));
inFile->Close();
if (!alignObjArray) {
AliErrorClass(Form("Could not get array (%s) from file (%s) !",clArrayName,fileName));
return kFALSE;
}
return ApplyAlignObjsToGeom(*alignObjArray);
}
Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* uri, const char* path, Int_t runnum, Int_t version, Int_t sversion)
{
AliCDBStorage* storage = AliCDBManager::Instance()->GetStorage(uri);
AliCDBId id(path, runnum, runnum, version, sversion);
AliCDBEntry* entry = storage->Get(id);
TClonesArray* alignObjArray = dynamic_cast<TClonesArray*>(entry->GetObject());
return ApplyAlignObjsToGeom(*alignObjArray);
}
Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* detName, Int_t runnum, Int_t version, Int_t sversion)
{
AliCDBPath path(detName,"Align","Data");
AliCDBEntry* entry = AliCDBManager::Instance()->Get(path.GetPath(),runnum,version,sversion);
if(!entry) return kFALSE;
TClonesArray* alignObjArray = ((TClonesArray*) entry->GetObject());
return ApplyAlignObjsToGeom(*alignObjArray);
}
void AliGeomManager::ResetPNEntriesLUT()
{
for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){
if (!fgPNEntry[iLayer]) continue;
for (Int_t modnum=0; modnum<fgLayerSize[iLayer]; modnum++) fgPNEntry[iLayer][modnum] = 0;
}
}