#include <TClass.h>
#include <TString.h>
#include <TGeoManager.h>
#include <TGeoPhysicalNode.h>
#include <TGeoShape.h>
#include <TGeoBBox.h>
#include <TDatime.h>
#include <TMath.h>
#include <TSystem.h>
#include "AliITSUGeomTGeo.h"
#include "AliLog.h"
#include "AliAlignObj.h"
#include "AliITSsegmentation.h"
#include "AliITSUSegmentationPix.h"
using namespace TMath;
ClassImp(AliITSUGeomTGeo)
UInt_t AliITSUGeomTGeo::fgUIDShift = 16;
TString AliITSUGeomTGeo::fgITSVolName = "ITSV";
TString AliITSUGeomTGeo::fgITSLrName = "ITSULayer";
TString AliITSUGeomTGeo::fgITSStaveName = "ITSUStave";
TString AliITSUGeomTGeo::fgITSHalfStaveName = "ITSUHalfStave";
TString AliITSUGeomTGeo::fgITSModuleName = "ITSUModule";
TString AliITSUGeomTGeo::fgITSChipName = "ITSUChip";
TString AliITSUGeomTGeo::fgITSSensName = "ITSUSensor";
TString AliITSUGeomTGeo::fgITSWrapVolName = "ITSUWrapVol";
TString AliITSUGeomTGeo::fgITSChipTypeName[AliITSUGeomTGeo::kNChipTypes] = {"Pix"};
TString AliITSUGeomTGeo::fgITSsegmFileName = "itsSegmentations.root";
AliITSUGeomTGeo::AliITSUGeomTGeo(Bool_t build, Bool_t loadSegm)
:fVersion(kITSVNA)
,fNLayers(0)
,fNChips(0)
,fNStaves(0)
,fNHalfStaves(0)
,fNModules(0)
,fNChipsPerModule(0)
,fNChipRowsPerModule(0)
,fNChipsPerHalfStave(0)
,fNChipsPerStave(0)
,fNChipsPerLayer(0)
,fLrChipType(0)
,fLastChipIndex(0)
,fMatSens(0)
,fMatT2L(0)
,fSegm(0)
{
for (int i=AliITSUAux::kMaxLayers;i--;) fLr2Wrapper[i] = -1;
if (build) BuildITS(loadSegm);
}
AliITSUGeomTGeo::AliITSUGeomTGeo(const AliITSUGeomTGeo &src)
:TObject(src)
,fVersion(src.fVersion)
,fNLayers(src.fNLayers)
,fNChips(src.fNChips)
,fNStaves(0)
,fNHalfStaves(0)
,fNModules(0)
,fNChipsPerModule(0)
,fNChipRowsPerModule(0)
,fNChipsPerHalfStave(0)
,fNChipsPerStave(0)
,fNChipsPerLayer(0)
,fLrChipType(0)
,fLastChipIndex(0)
,fMatSens(0)
,fMatT2L(0)
,fSegm(0)
{
if (fNLayers) {
fNStaves = new Int_t[fNLayers];
fNChipsPerModule = new Int_t[fNLayers];
fNChipRowsPerModule = new Int_t[fNLayers];
fLrChipType = new Int_t[fNLayers];
fLastChipIndex = new Int_t[fNLayers];
fNChipsPerHalfStave = new Int_t[fNLayers];
fNChipsPerStave = new Int_t[fNLayers];
fNChipsPerLayer = new Int_t[fNLayers];
for (int i=fNLayers;i--;) {
fNStaves[i] = src.fNStaves[i];
fNHalfStaves[i] = src.fNHalfStaves[i];
fNModules[i] = src.fNModules[i];
fNChipsPerModule[i] = src.fNChipsPerModule[i];
fNChipRowsPerModule[i] = src.fNChipRowsPerModule[i];
fNChipsPerHalfStave[i] = src.fNChipsPerHalfStave[i];
fNChipsPerStave[i] = src.fNChipsPerStave[i];
fNChipsPerLayer[i] = src.fNChipsPerLayer[i];
fLrChipType[i] = src.fLrChipType[i];
fLastChipIndex[i] = src.fLastChipIndex[i];
}
if (src.fMatSens) {
fMatSens = new TObjArray(fNChips);
fMatSens->SetOwner(kTRUE);
for (int i=0;i<fNChips;i++) {
const TGeoHMatrix* mat = (TGeoHMatrix*)src.fMatSens->At(i);
fMatSens->AddAt(new TGeoHMatrix(*mat),i);
}
}
if (src.fMatT2L) {
fMatT2L = new TObjArray(fNChips);
fMatT2L->SetOwner(kTRUE);
for (int i=0;i<fNChips;i++) {
const TGeoHMatrix* mat =(TGeoHMatrix*) src.fMatT2L->At(i);
fMatT2L->AddAt(new TGeoHMatrix(*mat),i);
}
}
if (src.fSegm) {
int sz = src.fSegm->GetEntriesFast();
fSegm = new TObjArray(sz);
fSegm->SetOwner(kTRUE);
for (int i=0;i<sz;i++) {
AliITSsegmentation* sg = (AliITSsegmentation*)src.fSegm->UncheckedAt(i);
if (!sg) continue;
fSegm->AddAt(sg->Clone(),i);
}
}
}
for (int i=AliITSUAux::kMaxLayers;i--;) fLr2Wrapper[i] = src.fLr2Wrapper[i];
}
AliITSUGeomTGeo::~AliITSUGeomTGeo()
{
delete[] fNStaves;
delete[] fNHalfStaves;
delete[] fNModules;
delete[] fLrChipType;
delete[] fNChipsPerModule;
delete[] fNChipRowsPerModule;
delete[] fNChipsPerHalfStave;
delete[] fNChipsPerStave;
delete[] fNChipsPerLayer;
delete[] fLastChipIndex;
delete fMatT2L;
delete fMatSens;
delete fSegm;
}
AliITSUGeomTGeo& AliITSUGeomTGeo::operator=(const AliITSUGeomTGeo &src)
{
if (this!=&src) {
delete[] fNStaves;
delete[] fNHalfStaves;
delete[] fNModules;
delete[] fLrChipType;
delete[] fNChipsPerModule;
delete[] fNChipRowsPerModule;
delete[] fNChipsPerHalfStave;
delete[] fNChipsPerStave;
delete[] fNChipsPerLayer;
delete[] fLastChipIndex;
fNStaves = fNHalfStaves = fNModules = fLrChipType = fNChipsPerModule = fLastChipIndex = 0;
fVersion = src.fVersion;
fNLayers = src.fNLayers;
fNChips = src.fNChips;
if (src.fMatSens) {
delete fMatSens;
fMatSens = new TObjArray(fNChips);
fMatSens->SetOwner(kTRUE);
for (int i=0;i<fNChips;i++) {
const TGeoHMatrix* mat = (TGeoHMatrix*) src.fMatSens->At(i);
fMatSens->AddAt(new TGeoHMatrix(*mat),i);
}
}
if (src.fMatT2L) {
delete fMatT2L;
fMatT2L = new TObjArray(fNChips);
fMatT2L->SetOwner(kTRUE);
for (int i=0;i<fNChips;i++) {
const TGeoHMatrix* mat = (TGeoHMatrix*) src.fMatT2L->At(i);
fMatT2L->AddAt(new TGeoHMatrix(*mat),i);
}
}
if (src.fSegm) {
int sz = src.fSegm->GetEntriesFast();
fSegm = new TObjArray(sz);
fSegm->SetOwner(kTRUE);
for (int i=0;i<sz;i++) {
AliITSsegmentation* sg = (AliITSsegmentation*)src.fSegm->UncheckedAt(i);
if (!sg) continue;
fSegm->AddAt(sg->Clone(),i);
}
}
if (fNLayers) {
fNStaves = new Int_t[fNLayers];
fNHalfStaves = new Int_t[fNLayers];
fNModules = new Int_t[fNLayers];
fNChipsPerModule = new Int_t[fNLayers];
fNChipRowsPerModule = new Int_t[fNLayers];
fNChipsPerHalfStave = new Int_t[fNLayers];
fNChipsPerStave = new Int_t[fNLayers];
fNChipsPerLayer = new Int_t[fNLayers];
fLrChipType = new Int_t[fNLayers];
fLastChipIndex = new Int_t[fNLayers];
for (int i=fNLayers;i--;) {
fNStaves[i] = src.fNStaves[i];
fNHalfStaves[i] = src.fNHalfStaves[i];
fNModules[i] = src.fNModules[i];
fNChipsPerModule[i] = src.fNChipsPerModule[i];
fNChipRowsPerModule[i] = src.fNChipRowsPerModule[i];
fNChipsPerHalfStave[i] = src.fNChipsPerHalfStave[i];
fNChipsPerStave[i] = src.fNChipsPerStave[i];
fNChipsPerLayer[i] = src.fNChipsPerLayer[i];
fLrChipType[i] = src.fLrChipType[i];
fLastChipIndex[i] = src.fLastChipIndex[i];
}
}
}
return *this;
}
Int_t AliITSUGeomTGeo::GetChipIndex(Int_t lay,Int_t sta,Int_t chipInStave) const
{
return GetFirstChipIndex(lay) + fNChipsPerStave[lay]*sta + chipInStave;
}
Int_t AliITSUGeomTGeo::GetChipIndex(Int_t lay,Int_t sta, Int_t substa, Int_t chipInSStave) const
{
int n = GetFirstChipIndex(lay) + fNChipsPerStave[lay]*sta + chipInSStave;
if (fNHalfStaves[lay] && substa>0) n += fNChipsPerHalfStave[lay]*substa;
return n;
}
Int_t AliITSUGeomTGeo::GetChipIndex(Int_t lay,Int_t sta, Int_t substa, Int_t md, Int_t chipInMod) const
{
int n = GetFirstChipIndex(lay) + fNChipsPerStave[lay]*sta + chipInMod;
if (fNHalfStaves[lay] && substa>0) n += fNChipsPerHalfStave[lay]*substa;
if (fNModules[lay] && md>0) n += fNChipsPerModule[lay]*md;
return n;
}
Bool_t AliITSUGeomTGeo::GetLayer(Int_t index,Int_t &lay,Int_t &indexInLr) const
{
lay = GetLayer(index);
indexInLr = index - GetFirstChipIndex(lay);
return kTRUE;
}
Int_t AliITSUGeomTGeo::GetLayer(Int_t index) const
{
int lay = 0;
while(index>fLastChipIndex[lay]) lay++;
return lay;
}
Int_t AliITSUGeomTGeo::GetStave(Int_t index) const
{
int lay = 0;
while(index>fLastChipIndex[lay]) lay++;
index -= GetFirstChipIndex(lay);
return index/fNChipsPerStave[lay];
}
Int_t AliITSUGeomTGeo::GetHalfStave(Int_t index) const
{
int lay = 0;
while(index>fLastChipIndex[lay]) lay++;
if (fNHalfStaves[lay]<0) return -1;
index -= GetFirstChipIndex(lay);
index %= fNChipsPerStave[lay];
return index/fNChipsPerHalfStave[lay];
}
Int_t AliITSUGeomTGeo::GetModule(Int_t index) const
{
int lay = 0;
while(index>fLastChipIndex[lay]) lay++;
if (fNModules[lay]<0) return 0;
index -= GetFirstChipIndex(lay);
index %= fNChipsPerStave[lay];
if (fNHalfStaves[lay]) index %= fNChipsPerHalfStave[lay];
return index/fNChipsPerModule[lay];
}
Int_t AliITSUGeomTGeo::GetChipIdInLayer(Int_t index) const
{
int lay = 0;
while(index>fLastChipIndex[lay]) lay++;
index -= GetFirstChipIndex(lay);
return index;
}
Int_t AliITSUGeomTGeo::GetChipIdInStave(Int_t index) const
{
int lay = 0;
while(index>fLastChipIndex[lay]) lay++;
index -= GetFirstChipIndex(lay);
return index%fNChipsPerStave[lay];
}
Int_t AliITSUGeomTGeo::GetChipIdInHalfStave(Int_t index) const
{
int lay = 0;
while(index>fLastChipIndex[lay]) lay++;
index -= GetFirstChipIndex(lay);
return index%fNChipsPerHalfStave[lay];
}
Int_t AliITSUGeomTGeo::GetChipIdInModule(Int_t index) const
{
int lay = 0;
while(index>fLastChipIndex[lay]) lay++;
index -= GetFirstChipIndex(lay);
return index%fNChipsPerModule[lay];
}
Bool_t AliITSUGeomTGeo::GetChipId(Int_t index,Int_t &lay,Int_t &sta,Int_t &hsta, Int_t &mod, Int_t &chip) const
{
lay = GetLayer(index);
index -= GetFirstChipIndex(lay);
sta = index/fNChipsPerStave[lay];
index %= fNChipsPerStave[lay];
hsta = fNHalfStaves[lay]>0 ? index/fNChipsPerHalfStave[lay] : -1;
index %= fNChipsPerHalfStave[lay];
mod = fNModules[lay]>0 ? index/fNChipsPerModule[lay] : -1;
chip = index%fNChipsPerModule[lay];
return kTRUE;
}
const char* AliITSUGeomTGeo::GetSymName(Int_t index) const
{
Int_t lay, index2;
if (!GetLayer(index,lay,index2)) return NULL;
TGeoPNEntry* pne = gGeoManager->GetAlignableEntryByUID( ChipVolUID(index) );
if (!pne) {
AliError(Form("Failed to find alignable entry with index %d: (Lr%d Chip:%d) !",index,lay,index2));
return NULL;
}
return pne->GetName();
}
const char* AliITSUGeomTGeo::ComposeSymNameITS()
{
return "ITS";
}
const char* AliITSUGeomTGeo::ComposeSymNameLayer(Int_t lr)
{
return Form("%s/%s%d",ComposeSymNameITS(),GetITSLayerPattern(),lr);
}
const char* AliITSUGeomTGeo::ComposeSymNameStave(Int_t lr, Int_t stave)
{
return Form("%s/%s%d",ComposeSymNameLayer(lr),GetITSStavePattern(),stave);
}
const char* AliITSUGeomTGeo::ComposeSymNameHalfStave(Int_t lr, Int_t stave, Int_t substave)
{
return substave>=0 ?
Form("%s/%s%d",ComposeSymNameStave(lr,stave),GetITSHalfStavePattern(),substave) :
ComposeSymNameStave(lr,stave);
}
const char* AliITSUGeomTGeo::ComposeSymNameModule(Int_t lr, Int_t stave, Int_t substave, Int_t mod)
{
return mod>=0 ?
Form("%s/%s%d",ComposeSymNameHalfStave(lr,stave,substave),GetITSModulePattern(),mod) :
ComposeSymNameHalfStave(lr,stave,substave);
}
const char* AliITSUGeomTGeo::ComposeSymNameChip(Int_t lr, Int_t sta, Int_t substave, Int_t mod, Int_t chip)
{
return Form("%s/%s%d",ComposeSymNameModule(lr,sta,substave,mod),GetITSChipPattern(),chip);
}
TGeoHMatrix* AliITSUGeomTGeo::GetMatrix(Int_t index) const
{
static TGeoHMatrix matTmp;
TGeoPNEntry *pne = GetPNEntry(index);
if (!pne) return NULL;
TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
if (pnode) return pnode->GetMatrix();
const char* path = pne->GetTitle();
gGeoManager->PushPath();
if (!gGeoManager->cd(path)) {
gGeoManager->PopPath();
AliError(Form("Volume path %s not valid!",path));
return NULL;
}
matTmp = *gGeoManager->GetCurrentMatrix();
gGeoManager->PopPath();
return &matTmp;
}
Bool_t AliITSUGeomTGeo::GetTranslation(Int_t index, Double_t t[3]) const
{
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 AliITSUGeomTGeo::GetRotation(Int_t index, Double_t r[9]) const
{
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 AliITSUGeomTGeo::GetOrigMatrix(Int_t index, TGeoHMatrix &m) const
{
m.Clear();
const char *symname = GetSymName(index);
if (!symname) return kFALSE;
return AliGeomManager::GetOrigGlobalMatrix(symname,m);
}
Bool_t AliITSUGeomTGeo::GetOrigTranslation(Int_t index, Double_t t[3]) const
{
TGeoHMatrix m;
if (!GetOrigMatrix(index,m)) return kFALSE;
Double_t *trans = m.GetTranslation();
for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
return kTRUE;
}
Bool_t AliITSUGeomTGeo::GetOrigRotation(Int_t index, Double_t r[9]) const
{
TGeoHMatrix m;
if (!GetOrigMatrix(index,m)) return kFALSE;
Double_t *rot = m.GetRotationMatrix();
for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
return kTRUE;
}
TGeoHMatrix* AliITSUGeomTGeo::ExtractMatrixT2L(Int_t index) const
{
TGeoPNEntry *pne = GetPNEntry(index);
if (!pne) return NULL;
TGeoHMatrix *m = (TGeoHMatrix*) pne->GetMatrix();
if (!m) AliError(Form("TGeoPNEntry (%s) contains no matrix !",pne->GetName()));
return m;
}
Bool_t AliITSUGeomTGeo::GetTrackingMatrix(Int_t index, TGeoHMatrix &m)
{
m.Clear();
TGeoHMatrix *m1 = GetMatrix(index);
if (!m1) return kFALSE;
const TGeoHMatrix *m2 = GetMatrixT2L(index);
if (!m2) return kFALSE;
m = *m1;
m.Multiply(m2);
return kTRUE;
}
TGeoHMatrix* AliITSUGeomTGeo::ExtractMatrixSens(Int_t index) const
{
Int_t lay,stav,sstav,mod,chipInMod;
GetChipId(index,lay,stav,sstav,mod,chipInMod);
int wrID = fLr2Wrapper[lay];
TString path = Form("/ALIC_1/%s_2/",AliITSUGeomTGeo::GetITSVolPattern());
if (wrID>=0) path += Form("%s%d_1/",GetITSWrapVolPattern(),wrID);
path += Form("%s%d_1/%s%d_%d/",AliITSUGeomTGeo::GetITSLayerPattern(),lay,AliITSUGeomTGeo::GetITSStavePattern(),lay,stav);
if (fNHalfStaves[lay]>0) path += Form("%s%d_%d/",AliITSUGeomTGeo::GetITSHalfStavePattern(),lay,sstav);
if (fNModules[lay]>0) path += Form("%s%d_%d/",AliITSUGeomTGeo::GetITSModulePattern(),lay,mod);
path += Form("%s%d_%d/%s%d_1",AliITSUGeomTGeo::GetITSChipPattern(),lay,chipInMod,AliITSUGeomTGeo::GetITSSensorPattern(),lay);
static TGeoHMatrix matTmp;
gGeoManager->PushPath();
if (!gGeoManager->cd(path.Data())) {
gGeoManager->PopPath();
AliError(Form("Error in cd-ing to %s",path.Data()));
return 0;
}
matTmp = *gGeoManager->GetCurrentMatrix();
gGeoManager->PopPath();
return &matTmp;
}
TGeoPNEntry* AliITSUGeomTGeo::GetPNEntry(Int_t index) const
{
if (index >= fNChips) {
AliError(Form("Invalid ITS chip index: %d (0 -> %d) !",index,fNChips));
return NULL;
}
if (!gGeoManager || !gGeoManager->IsClosed()) {
AliError("Can't get the matrix! gGeoManager doesn't exist or it is still opened!");
return NULL;
}
TGeoPNEntry* pne = gGeoManager->GetAlignableEntryByUID( ChipVolUID(index) );
if (!pne) AliError(Form("The index %d does not correspond to a physical entry!",index));
return pne;
}
void AliITSUGeomTGeo::BuildITS(Bool_t loadSegm)
{
if (fVersion!=kITSVNA) {AliWarning("Already built"); return;}
if (!gGeoManager) AliFatal("Geometry is not loaded");
fNLayers = ExtractNumberOfLayers();
if (!fNLayers) return;
fNStaves = new Int_t[fNLayers];
fNHalfStaves = new Int_t[fNLayers];
fNModules = new Int_t[fNLayers];
fNChipsPerModule = new Int_t[fNLayers];
fNChipRowsPerModule = new Int_t[fNLayers];
fNChipsPerHalfStave = new Int_t[fNLayers];
fNChipsPerStave = new Int_t[fNLayers];
fNChipsPerLayer = new Int_t[fNLayers];
fLrChipType = new Int_t[fNLayers];
fLastChipIndex = new Int_t[fNLayers];
fNChips = 0;
for (int i=0;i<fNLayers;i++) {
fLrChipType[i] = ExtractLayerChipType(i);
fNStaves[i] = ExtractNumberOfStaves(i);
fNHalfStaves[i] = ExtractNumberOfHalfStaves(i);
fNModules[i] = ExtractNumberOfModules(i);
fNChipsPerModule[i] = ExtractNChipsPerModule(i,fNChipRowsPerModule[i]);
fNChipsPerHalfStave[i]= fNChipsPerModule[i]*Max(1,fNModules[i]);
fNChipsPerStave[i] = fNChipsPerHalfStave[i]*Max(1,fNHalfStaves[i]);
fNChipsPerLayer[i] = fNChipsPerStave[i]*fNStaves[i];
fNChips += fNChipsPerLayer[i];
fLastChipIndex[i] = fNChips-1;
}
FetchMatrices();
fVersion = kITSVUpg;
if (loadSegm) {
fSegm = new TObjArray();
AliITSUSegmentationPix::LoadSegmentations(fSegm,GetITSsegmentationFileName());
}
}
Int_t AliITSUGeomTGeo::ExtractNumberOfLayers()
{
Int_t numberOfLayers = 0;
TGeoVolume *itsV = gGeoManager->GetVolume(GetITSVolPattern());
if (!itsV) AliFatal(Form("ITS volume %s is not in the geometry",GetITSVolPattern()));
SetUIDShift(itsV->GetUniqueID());
TObjArray* nodes = itsV->GetNodes();
Int_t nNodes = nodes->GetEntriesFast();
for (Int_t j=0; j<nNodes; j++) {
int lrID = -1;
TGeoNode* nd = (TGeoNode*)nodes->At(j);
const char* name = nd->GetName();
if (strstr(name,GetITSLayerPattern())) {
numberOfLayers++;
if ( (lrID=ExtractVolumeCopy(name,AliITSUGeomTGeo::GetITSLayerPattern()))<0 ) {
AliFatal(Form("Failed to extract layer ID from the %s",name));
exit(1);
}
fLr2Wrapper[lrID] = -1;
}
else if (strstr(name,GetITSWrapVolPattern())) {
int wrID = -1;
if ( (wrID=ExtractVolumeCopy(name,AliITSUGeomTGeo::GetITSWrapVolPattern()))<0 ) {
AliFatal(Form("Failed to extract wrapper ID from the %s",name));
exit(1);
}
TObjArray* nodesW = nd->GetNodes();
int nNodesW = nodesW->GetEntriesFast();
for (Int_t jw=0; jw<nNodesW; jw++) {
TGeoNode* ndW = (TGeoNode*)nodesW->At(jw);
if (strstr(ndW->GetName(),GetITSLayerPattern())) {
if ( (lrID=ExtractVolumeCopy(ndW->GetName(),AliITSUGeomTGeo::GetITSLayerPattern()))<0 ) {
AliFatal(Form("Failed to extract layer ID from the %s",name));
exit(1);
}
numberOfLayers++;
fLr2Wrapper[lrID] = wrID;
}
}
}
}
return numberOfLayers;
}
Int_t AliITSUGeomTGeo::ExtractNumberOfStaves(Int_t lay) const
{
Int_t numberOfStaves = 0;
char laynam[30];
snprintf(laynam, 30, "%s%d",GetITSLayerPattern(),lay);
TGeoVolume* volLr = gGeoManager->GetVolume(laynam);
if (!volLr) { AliFatal(Form("can't find %s volume",laynam)); return -1; }
Int_t nNodes = volLr->GetNodes()->GetEntries();
for (Int_t j=0; j<nNodes; j++) {
if (strstr(volLr->GetNodes()->At(j)->GetName(),GetITSStavePattern())) numberOfStaves++;
}
return numberOfStaves;
}
Int_t AliITSUGeomTGeo::ExtractNumberOfHalfStaves(Int_t lay) const
{
if (fgITSHalfStaveName.IsNull()) return 0;
Int_t nSS = 0;
char stavnam[30];
snprintf(stavnam, 30, "%s%d", GetITSStavePattern(),lay);
TGeoVolume* volLd = gGeoManager->GetVolume(stavnam);
if (!volLd) AliFatal(Form("can't find %s volume",stavnam));
Int_t nNodes = volLd->GetNodes()->GetEntries();
for (Int_t j=0; j<nNodes; j++) if (strstr(volLd->GetNodes()->At(j)->GetName(),GetITSHalfStavePattern())) nSS++;
return nSS;
}
Int_t AliITSUGeomTGeo::ExtractNumberOfModules(Int_t lay) const
{
if (fgITSModuleName.IsNull()) return 0;
char stavnam[30];
TGeoVolume* volLd = 0;
if (!fgITSHalfStaveName.IsNull()) {
snprintf(stavnam, 30, "%s%d", GetITSHalfStavePattern(),lay);
volLd = gGeoManager->GetVolume(stavnam);
}
if (!volLd) {
snprintf(stavnam, 30, "%s%d", GetITSStavePattern(),lay);
volLd = gGeoManager->GetVolume(stavnam);
}
if (!volLd) return 0;
Int_t nMod = 0;
Int_t nNodes = volLd->GetNodes()->GetEntries();
for (Int_t j=0; j<nNodes; j++) if (strstr(volLd->GetNodes()->At(j)->GetName(),GetITSModulePattern())) nMod++;
return nMod;
}
Int_t AliITSUGeomTGeo::ExtractNChipsPerModule(Int_t lay, int &nrow) const
{
Int_t numberOfChips = 0;
char stavnam[30];
TGeoVolume* volLd = 0;
if (!fgITSModuleName.IsNull()) {
snprintf(stavnam, 30, "%s%d", GetITSModulePattern(),lay);
volLd = gGeoManager->GetVolume(stavnam);
}
if (!volLd) {
if (!fgITSHalfStaveName.IsNull()) {
snprintf(stavnam, 30, "%s%d", GetITSHalfStavePattern(),lay);
volLd = gGeoManager->GetVolume(stavnam);
}
}
if (!volLd) {
snprintf(stavnam, 30, "%s%d", GetITSStavePattern(),lay);
volLd = gGeoManager->GetVolume(stavnam);
}
if (!volLd) AliFatal(Form("can't find volume containing chips on layer %d",lay));
Int_t nNodes = volLd->GetNodes()->GetEntries();
double xmin=1e9,xmax=-1e9, zmin=1e9,zmax=-1e9;
double lab[3],loc[3]={0,0,0};
double dx=-1,dz=-1;
for (Int_t j=0; j<nNodes; j++) {
TGeoNodeMatrix* node = (TGeoNodeMatrix*)volLd->GetNodes()->At(j);
if (!strstr(node->GetName(),GetITSChipPattern())) continue;
node->LocalToMaster(loc,lab);
if (lab[0]>xmax) xmax=lab[0];
if (lab[0]<xmin) xmin=lab[0];
if (lab[2]>zmax) zmax=lab[2];
if (lab[2]<zmin) zmin=lab[2];
numberOfChips++;
if (dx<0) {
TGeoShape* chShape = node->GetVolume()->GetShape();
TGeoBBox* bbox = dynamic_cast<TGeoBBox*>(chShape);
if (!bbox) {
AliFatal(Form("Chip %s volume is of unprocessed shape %s",node->GetName(),chShape->IsA()->GetName()));
}
else {
dx = 2*bbox->GetDX();
dz = 2*bbox->GetDZ();
}
}
}
double spanX = xmax-xmin;
double spanZ = zmax-zmin;
nrow = TMath::Nint(spanX/dx + 1);
int ncol = TMath::Nint(spanZ/dz + 1);
if (nrow*ncol != numberOfChips)
AliError(Form("Inconsistency between Nchips=%d and Nrow*Ncol=%d*%d->%d\n"
"Extracted chip dimensions (x,z): %.4f %.4f, Module Span: %.4f %.4f",
numberOfChips,nrow,ncol,nrow*ncol,
dx,dz,spanX,spanZ));
return numberOfChips;
}
Int_t AliITSUGeomTGeo::ExtractLayerChipType(Int_t lay) const
{
char stavnam[30];
snprintf(stavnam, 30, "%s%d", GetITSLayerPattern(),lay);
TGeoVolume* volLd = gGeoManager->GetVolume(stavnam);
if (!volLd) {AliFatal(Form("can't find %s volume",stavnam)); return -1;}
return volLd->GetUniqueID();
}
UInt_t AliITSUGeomTGeo::ComposeChipTypeID(UInt_t segmId)
{
if (segmId>=kMaxSegmPerChipType) AliFatalClass(Form("Id=%d is >= max.allowed %d",segmId,kMaxSegmPerChipType));
return segmId + kChipTypePix*kMaxSegmPerChipType;
}
void AliITSUGeomTGeo::Print(Option_t *) const
{
printf("Geometry version %d, NLayers:%d NChips:%d\n",fVersion,fNLayers,fNChips);
if (fVersion==kITSVNA) return;
for (int i=0;i<fNLayers;i++) {
printf("Lr%2d\tNStav:%2d\tNChips:%2d (%dx%-2d)\tNMod:%d\tNSubSt:%d\tNSt:%3d\tChipType:%3d\tChip#:%5d:%-5d\tWrapVol:%d\n",
i,fNStaves[i],fNChipsPerModule[i],fNChipRowsPerModule[i],
fNChipRowsPerModule[i] ? fNChipsPerModule[i]/fNChipRowsPerModule[i] : 0,
fNModules[i],fNHalfStaves[i],fNStaves[i],
fLrChipType[i],GetFirstChipIndex(i),GetLastChipIndex(i),fLr2Wrapper[i]);
}
}
void AliITSUGeomTGeo::FetchMatrices()
{
if (!gGeoManager) AliFatal("Geometry is not loaded");
fMatSens = new TObjArray(fNChips);
fMatSens->SetOwner(kTRUE);
for (int i=0;i<fNChips;i++) fMatSens->AddAt(new TGeoHMatrix(*ExtractMatrixSens(i)),i);
CreateT2LMatrices();
}
void AliITSUGeomTGeo::CreateT2LMatrices()
{
fMatT2L = new TObjArray(fNChips);
fMatT2L->SetOwner(kTRUE);
TGeoHMatrix matLtoT;
double locA[3]={-100,0,0},locB[3]={100,0,0},gloA[3],gloB[3];
for (int isn=0;isn<fNChips;isn++) {
const TGeoHMatrix* matSens = GetMatrixSens(isn);
if (!matSens) {AliFatal(Form("Failed to get matrix for sensor %d",isn)); return;}
matSens->LocalToMaster(locA,gloA);
matSens->LocalToMaster(locB,gloB);
double dx = gloB[0]-gloA[0];
double dy = gloB[1]-gloA[1];
double t = (gloB[0]*dx+gloB[1]*dy)/(dx*dx+dy*dy),x=gloB[0]-dx*t,y=gloB[1]-dy*t;
TGeoHMatrix* t2l = new TGeoHMatrix();
t2l->RotateZ(ATan2(y,x)*RadToDeg());
t2l->SetDx(x);
t2l->SetDy(y);
t2l->MultiplyLeft(&matSens->Inverse());
fMatT2L->AddAt(t2l,isn);
}
}
Int_t AliITSUGeomTGeo::ExtractVolumeCopy(const char* name, const char* prefix) const
{
TString nms = name;
if (!nms.BeginsWith(prefix)) return -1;
nms.Remove(0,strlen(prefix));
if (!isdigit(nms.Data()[0])) return -1;
return nms.Atoi();
}