added alignables for v1, fixed in v0
authorshahoian <ruben.shahoyan@cern.ch>
Wed, 5 Mar 2014 19:59:52 +0000 (20:59 +0100)
committershahoian <ruben.shahoyan@cern.ch>
Wed, 5 Mar 2014 19:59:52 +0000 (20:59 +0100)
ITS/UPGRADE/AliITSUv0.cxx
ITS/UPGRADE/AliITSUv0.h
ITS/UPGRADE/AliITSUv1.cxx
ITS/UPGRADE/AliITSUv1.h
ITS/UPGRADE/AliITSUv1Layer.cxx
ITS/UPGRADE/AliITSUv1Layer.h
ITS/UPGRADE/readDigits.C

index 5747e1c..d8fa4c1 100644 (file)
@@ -65,6 +65,7 @@ AliITSUv0::AliITSUv0()
   ,fWrapRMin(0)
   ,fWrapRMax(0)
   ,fWrapZSpan(0)
+  ,fLay2WrapV(0)
   ,fLayTurbo(0)
   ,fLayPhi0(0)
   ,fLayRadii(0)
@@ -96,6 +97,7 @@ AliITSUv0::AliITSUv0(const char *title,const Int_t nlay)
   ,fWrapRMin(0)
   ,fWrapRMax(0)
   ,fWrapZSpan(0)
+  ,fLay2WrapV(0)
   ,fLayTurbo(0)
   ,fLayPhi0(0)
   ,fLayRadii(0)
@@ -179,6 +181,8 @@ AliITSUv0::~AliITSUv0() {
   delete [] fWrapRMin;
   delete [] fWrapRMax;
   delete [] fWrapZSpan;
+  delete [] fLay2WrapV;
+  //
 }
 
 //______________________________________________________________________
@@ -212,15 +216,20 @@ void AliITSUv0::AddAlignableVolumes() const{
   //
   for (int lr=0; lr<fNLayers; lr++) {
     //
-    pth = Form("ALIC_1/%s_2/%s%d_1",AliITSUGeomTGeo::GetITSVolPattern(),AliITSUGeomTGeo::GetITSLayerPattern(),lr);
+    TString wrpV = fLay2WrapV[lr]!=-1 ? Form("%s%d_1/",AliITSUGeomTGeo::GetITSWrapVolPattern(),fLay2WrapV[lr]) : "";
+    pth = Form("ALIC_1/%s_2/%s%s%d_1",AliITSUGeomTGeo::GetITSVolPattern(),wrpV.Data(),AliITSUGeomTGeo::GetITSLayerPattern(),lr);
     //printf("SetAlignable: %s %s\n",snm.Data(),pth.Data());
-    gGeoManager->SetAlignableEntry(AliITSUGeomTGeo::ComposeSymNameLayer(lr),pth.Data());
+    if( !gGeoManager->SetAlignableEntry(AliITSUGeomTGeo::ComposeSymNameLayer(lr),pth.Data()) ) {
+      AliFatal(Form("Unable to set alignable entry ! %s :: %s",AliITSUGeomTGeo::ComposeSymNameLayer(lr),pth.Data()));
+    }
     //
     for (int ld=0; ld<fStavPerLay[lr]; ld++) {
       //
       TString pthL = Form("%s/%s%d_%d",pth.Data(),AliITSUGeomTGeo::GetITSStavePattern(),lr,ld);
       //printf("SetAlignable: %s %s\n",snmL.Data(),pthL.Data());
-      gGeoManager->SetAlignableEntry(AliITSUGeomTGeo::ComposeSymNameStave(lr,ld),pthL.Data());
+      if ( !gGeoManager->SetAlignableEntry(AliITSUGeomTGeo::ComposeSymNameStave(lr,ld),pthL.Data()) ) {
+       AliFatal(Form("Unable to set alignable entry ! %s :: %s",AliITSUGeomTGeo::ComposeSymNameStave(lr,ld),pthL.Data()));
+      }
       //
       for (int md=0; md<fModPerStav[lr]; md++) {
        //
@@ -231,7 +240,9 @@ void AliITSUv0::AddAlignableVolumes() const{
        //      int modUID = AliGeomManager::LayerToVolUID(lr+1,chipNum++); // here chipNum would be chip within the layer
        int modUID = AliITSUGeomTGeo::ChipVolUID( chipNum++ );
        // 
-       gGeoManager->SetAlignableEntry(AliITSUGeomTGeo::ComposeSymNameChip(lr,ld,-1,-1,md),pthM.Data(),modUID);
+       if ( !gGeoManager->SetAlignableEntry(AliITSUGeomTGeo::ComposeSymNameChip(lr,ld,-1,-1,md),pthM.Data(),modUID) ) {
+         AliFatal(Form("Unable to set alignable entry ! %s :: %s",AliITSUGeomTGeo::ComposeSymNameChip(lr,ld,-1,-1,md),pthM.Data()));
+       }
        //
       }
     }
@@ -312,6 +323,8 @@ void AliITSUv0::CreateGeometry() {
     }
   }
   //
+  fLay2WrapV = new Int_t[fNLayers];
+
   // Now create the actual geometry
   for (Int_t j=0; j<fNLayers; j++) {
     TGeoVolume* dest = vITSV;
@@ -342,6 +355,7 @@ void AliITSUv0::CreateGeometry() {
        if (fLayZLength[j]>=fWrapZSpan[iw]) AliFatal(Form("ZSpan %.3f of wrapper volume %d is less than ZSpan %.3f of layer %d",
                                                          fWrapZSpan[iw],iw,fLayZLength[j],j));
        dest = wrapVols[iw];
+       fLay2WrapV[j] = iw;
        break;
       }
     }
index 0f201e4..877c690 100644 (file)
@@ -76,6 +76,7 @@ class AliITSUv0 : public AliITSU {
   Double_t* fWrapRMin;       // min radius of wrapper volume
   Double_t* fWrapRMax;       // max radius of wrapper volume
   Double_t* fWrapZSpan;      // Z span of wrapper volume
+  Int_t*    fLay2WrapV;      // id of wrapper layer to which layer belongs (-1 if not wrapped)
   Bool_t   *fLayTurbo;       // True for "turbo" layers
   Double_t *fLayPhi0;        // Vector of layer's 1st stave phi in lab
   Double_t *fLayRadii;       // Vector of layer radii
index 6172df3..e2af53c 100644 (file)
@@ -65,6 +65,7 @@ AliITSUv1::AliITSUv1()
   ,fWrapRMin(0)
   ,fWrapRMax(0)
   ,fWrapZSpan(0)
+  ,fLay2WrapV(0)
   ,fLayTurbo(0)
   ,fLayPhi0(0)
   ,fLayRadii(0)
@@ -97,6 +98,7 @@ AliITSUv1::AliITSUv1(const char *title,const Int_t nlay)
   ,fWrapRMin(0)
   ,fWrapRMax(0)
   ,fWrapZSpan(0)
+  ,fLay2WrapV(0)
   ,fLayTurbo(0)
   ,fLayPhi0(0)
   ,fLayRadii(0)
@@ -181,10 +183,12 @@ AliITSUv1::~AliITSUv1() {
   delete [] fWrapRMin;
   delete [] fWrapRMax;
   delete [] fWrapZSpan;
+  delete [] fLay2WrapV;
 }
 
 //______________________________________________________________________
-void AliITSUv1::AddAlignableVolumes() const{
+void AliITSUv1::AddAlignableVolumes() const
+{
   // Creates entries for alignable volumes associating the symbolic volume
   // name with the corresponding volume path.
   // 
@@ -193,53 +197,113 @@ void AliITSUv1::AddAlignableVolumes() const{
   // system
   // For this, this function has to run before the misalignment because we
   // are using the ideal positions in the AliITSgeom object.
-  // Inputs:
-  //   none.
-  // Outputs:
-  //   none.
-  // Return:
-  //   none.
-  /*
   AliInfo("Add ITS alignable volumes");
 
   if (!gGeoManager) { AliFatal("TGeoManager doesn't exist !"); return;  }
-  TString pth;
   //
-  pth = Form("ALIC_1/%s_2",AliITSUGeomTGeo::GetITSVolPattern());
-  // RS: to be checked with MS
-  if( !gGeoManager->SetAlignableEntry(AliITSUGeomTGeo::ComposeSymNameITS(),pth.Data()) )
-    AliFatal(Form("Unable to set alignable entry ! %s :: %s","ITS",pth.Data()));    
+  TString path = Form("ALIC_1/%s_2",AliITSUGeomTGeo::GetITSVolPattern());
+  TString sname = AliITSUGeomTGeo::ComposeSymNameITS();
+  //
+  AliDebug(1,Form("%s <-> %s",sname.Data(),path.Data()));
+  if( !gGeoManager->SetAlignableEntry(sname.Data(),path.Data()) )
+    AliFatal(Form("Unable to set alignable entry ! %s %s",sname.Data(),path.Data()));    
+  //
+  int lastUID = 0;
+  for (int lr=0; lr<fNLayers; lr++) AddAlignableVolumesLayer(lr,path,lastUID);
+  //
+}
+
+//______________________________________________________________________
+void AliITSUv1::AddAlignableVolumesLayer(int lr, TString& parent,Int_t &lastUID) const
+{
+  // add alignable volumes for layer and its daughters
+  //
+  TString wrpV = fLay2WrapV[lr]!=-1 ? Form("%s%d_1/",AliITSUGeomTGeo::GetITSWrapVolPattern(),fLay2WrapV[lr]) : "";
+  TString path = Form("%s/%s%s%d_1",parent.Data(),wrpV.Data(),AliITSUGeomTGeo::GetITSLayerPattern(),lr);
+  TString sname = AliITSUGeomTGeo::ComposeSymNameLayer(lr);
+  AliDebug(1,Form("Add %s <-> %s", sname.Data(),path.Data()));
+  if ( !gGeoManager->SetAlignableEntry(sname.Data(),path.Data()) ) 
+    AliFatal(Form("Unable to set alignable entry ! %s : %s",sname.Data(),path.Data()));
+  //
+  const AliITSUv1Layer* lrobj = fUpGeom[lr];
+  int nstaves = lrobj->GetNStavesPerParent();
+  for (int st=0; st<nstaves; st++) AddAlignableVolumesStave(lr,st,path,lastUID);
+  //
+}
+    
+//______________________________________________________________________
+void AliITSUv1::AddAlignableVolumesStave(int lr, int st, TString& parent, Int_t &lastUID) const
+{
+  // add alignable volumes for stave and its daughters
+  //
+  TString path = Form("%s/%s%d_%d",parent.Data(),AliITSUGeomTGeo::GetITSStavePattern(),lr,st);
+  TString sname = AliITSUGeomTGeo::ComposeSymNameStave(lr,st);
+  AliDebug(1,Form("Add %s <-> %s", sname.Data(),path.Data()));
+  if ( !gGeoManager->SetAlignableEntry(sname.Data(),path.Data()) ) 
+    AliFatal(Form("Unable to set alignable entry ! %s : %s",sname.Data(),path.Data()));
   //
-  int modNum = 0;
+  const AliITSUv1Layer* lrobj = fUpGeom[lr];
+  int nsstave = lrobj->GetNHalfStavesPerParent();
+  int start = nsstave>0 ? 0:-1;
   //
-  for (int lr=0; lr<fNLayers; lr++) {
+  for (int sst=start; sst<nsstave; sst++) AddAlignableVolumesHalfStave(lr,st,sst,path,lastUID);
+}
+
+//______________________________________________________________________
+void AliITSUv1::AddAlignableVolumesHalfStave(int lr, int st, int sst, TString& parent, Int_t &lastUID) const
+{
+  // add alignable volumes for halfstave (if any) and its daughters
+  //
+  TString path = parent;
+  if (sst>=0) {
+    path = Form("%s/%s%d_%d",parent.Data(),AliITSUGeomTGeo::GetITSHalfStavePattern(),lr,sst);
+    TString sname = AliITSUGeomTGeo::ComposeSymNameHalfStave(lr,st,sst);
+    AliDebug(1,Form("Add %s <-> %s", sname.Data(),path.Data()));
+    if ( !gGeoManager->SetAlignableEntry(sname.Data(),path.Data()) ) 
+      AliFatal(Form("Unable to set alignable entry ! %s : %s",sname.Data(),path.Data()));
     //
-    pth = Form("ALIC_1/%s_2/%s%d_1",AliITSUGeomTGeo::GetITSVolPattern(),AliITSUGeomTGeo::GetITSLayerPattern(),lr);
-    //printf("SetAlignable: %s %s\n",snm.Data(),pth.Data());
-    gGeoManager->SetAlignableEntry(AliITSUGeomTGeo::ComposeSymNameLayer(lr),pth.Data());
+  }
+  const AliITSUv1Layer* lrobj = fUpGeom[lr];
+  int nmodules = lrobj->GetNModulesPerParent();
+  int start = nmodules>0 ? 0:-1;
+  //
+  for (int md=start; md<nmodules; md++) AddAlignableVolumesModule(lr,st,sst,md,path,lastUID);
+}
+
+//______________________________________________________________________
+void AliITSUv1::AddAlignableVolumesModule(int lr, int st, int sst, int md, TString& parent, Int_t &lastUID) const
+{
+  // add alignable volumes for module (if any) and its daughters
+  //
+  TString path = parent;
+  if (md>=0) {
+    path = Form("%s/%s%d_%d",parent.Data(),AliITSUGeomTGeo::GetITSModulePattern(),lr,md);
+    TString sname = AliITSUGeomTGeo::ComposeSymNameModule(lr,st,sst,md);
+    AliDebug(1,Form("Add %s <-> %s", sname.Data(),path.Data()));
+    if ( !gGeoManager->SetAlignableEntry(sname.Data(),path.Data()) ) 
+      AliFatal(Form("Unable to set alignable entry ! %s : %s",sname.Data(),path.Data()));
     //
-    for (int ld=0; ld<fStavPerLay[lr]; ld++) {
-      //
-      TString pthL = Form("%s/%s%d_%d",pth.Data(),AliITSUGeomTGeo::GetITSStavePattern(),lr,ld);
-      //printf("SetAlignable: %s %s\n",snmL.Data(),pthL.Data());
-      gGeoManager->SetAlignableEntry(AliITSUGeomTGeo::ComposeSymNameStave(lr,ld),pthL.Data());
-      //
-      for (int md=0; md<fUnitPerStave[lr]; md++) {
-       //
-       TString pthM = Form("%s/%s%d_%d",pthL.Data(),AliITSUGeomTGeo::GetITSChipPattern(),lr,md);
-       //
-       // RS: Attention, this is a hack: AliGeomManager cannot accomodate all ITSU chips w/o
-       // conflicts with TPC. For this reason we define the UID of the chip to be simply its ID
-       //      int modUID = AliGeomManager::LayerToVolUID(lr+1,modNum++); // here modNum would be chip within the layer
-       int modUID = AliITSUGeomTGeo::ChipVolUID( modNum++ );
-       // 
-       gGeoManager->SetAlignableEntry(AliITSUGeomTGeo::ComposeSymNameChip(lr,ld,md),pthM.Data(),modUID);
-       //
-      }
-    }
   }
   //
-  */
+  const AliITSUv1Layer* lrobj = fUpGeom[lr];
+  int nchips = lrobj->GetNChipsPerParent();
+  //
+  for (int ic=0; ic<nchips; ic++) AddAlignableVolumesChip(lr,st,sst,md,ic,path,lastUID);
+}  
+
+//______________________________________________________________________
+void AliITSUv1::AddAlignableVolumesChip(int lr, int st, int sst, int md, int ch, TString& parent, Int_t &lastUID) const
+{
+  // add alignable volumes for chip
+  //
+  TString path = Form("%s/%s%d_%d",parent.Data(),AliITSUGeomTGeo::GetITSChipPattern(),lr,ch);
+  TString sname = AliITSUGeomTGeo::ComposeSymNameChip(lr,st,sst,md,ch);
+  int modUID = AliITSUGeomTGeo::ChipVolUID( lastUID++ );
+  //
+  AliDebug(1,Form("Add %s <-> %s : ID=%d", sname.Data(),path.Data(),modUID));
+  if ( !gGeoManager->SetAlignableEntry(sname,path.Data(),modUID) )
+    AliFatal(Form("Unable to set alignable entry ! %s : %s | %d",sname.Data(),path.Data(),modUID));
+  //
 }
 
 //______________________________________________________________________
@@ -315,9 +379,12 @@ void AliITSUv1::CreateGeometry() {
     }
   }
   //
+  fLay2WrapV = new Int_t[fNLayers];
+
   // Now create the actual geometry
   for (Int_t j=0; j<fNLayers; j++) {
     TGeoVolume* dest = vITSV;
+    fLay2WrapV[j] = -1;
     //
     if (fLayTurbo[j]) {
       fUpGeom[j] = new AliITSUv1Layer(j,kTRUE,kFALSE);
@@ -348,6 +415,7 @@ void AliITSUv1::CreateGeometry() {
        if (fLayZLength[j]>=fWrapZSpan[iw]) AliFatal(Form("ZSpan %.3f of wrapper volume %d is less than ZSpan %.3f of layer %d",
                                                          fWrapZSpan[iw],iw,fLayZLength[j],j));
        dest = wrapVols[iw];
+       fLay2WrapV[j] = iw;
        break;
       }
     }
index 95a65f3..34331d1 100644 (file)
@@ -44,6 +44,12 @@ class AliITSUv1 : public AliITSU {
   virtual       ~AliITSUv1() ;
   virtual void   SetNWrapVolumes(Int_t n);
   virtual void   AddAlignableVolumes() const;
+  void           AddAlignableVolumesLayer(int lr, TString& parent,Int_t &lastUID) const;
+  void           AddAlignableVolumesStave(int lr, int st, TString& parent,Int_t &lastUID) const;
+  void           AddAlignableVolumesHalfStave(int lr, int st, int sst, TString& parent,Int_t &lastUID) const;
+  void           AddAlignableVolumesModule(int lr, int st, int sst, int md, TString& parent,Int_t &lastUID) const;
+  void           AddAlignableVolumesChip(int lr, int st, int sst, int md, int ch, TString& parent,Int_t &lastUID) const;
+
   virtual void   CreateGeometry();
   virtual void   CreateMaterials();
   virtual void   DefineLayer(Int_t nlay,Double_t phi0,Double_t r,Double_t zlen,Int_t nstav,
@@ -80,6 +86,7 @@ class AliITSUv1 : public AliITSU {
   Double_t* fWrapRMin;       // min radius of wrapper volume
   Double_t* fWrapRMax;       // max radius of wrapper volume
   Double_t* fWrapZSpan;      // Z span of wrapper volume
+  Int_t*    fLay2WrapV;      // id of wrapper layer to which layer belongs (-1 if not wrapped)
   Bool_t   *fLayTurbo;       // True for "turbo" layers
   Double_t *fLayPhi0;        // Vector of layer's 1st stave phi in lab
   Double_t *fLayRadii;       // Vector of layer radii
index 193e1b7..ec0e0db 100644 (file)
@@ -109,6 +109,7 @@ AliITSUv1Layer::AliITSUv1Layer():
 {
   //
   // Standard constructor
+  for (int i=kNHLevels;i--;) fHierarchy[i] = 0;
   //
 }
 
@@ -133,6 +134,7 @@ AliITSUv1Layer::AliITSUv1Layer(Int_t debug):
 {
   //
   // Constructor setting debugging level
+  for (int i=kNHLevels;i--;) fHierarchy[i] = 0;
   //
 }
 
@@ -157,6 +159,7 @@ AliITSUv1Layer::AliITSUv1Layer(Int_t lay, Int_t debug):
 {
   //
   // Constructor setting layer number and debugging level
+  for (int i=kNHLevels;i--;) fHierarchy[i] = 0;
   //
 }
 
@@ -182,6 +185,7 @@ AliITSUv1Layer::AliITSUv1Layer(Int_t lay, Bool_t turbo, Int_t debug):
   //
   // Constructor setting layer number and debugging level
   // for a "turbo" layer (i.e. where staves overlap in phi)
+  for (int i=kNHLevels;i--;) fHierarchy[i] = 0;
   //
 }
 
@@ -206,6 +210,7 @@ AliITSUv1Layer::AliITSUv1Layer(const AliITSUv1Layer &s):
 {
   //
   // Copy constructor
+  for (int i=kNHLevels;i--;) fHierarchy[i] = s.fHierarchy[i];
   //
 }
 
@@ -232,7 +237,8 @@ AliITSUv1Layer& AliITSUv1Layer::operator=(const AliITSUv1Layer &s)
   fChipTypeID  = s.fChipTypeID;
   fBuildLevel  = s.fBuildLevel;
   fStaveModel  = s.fStaveModel;
-
+  for (int i=kNHLevels;i--;) fHierarchy[i] = s.fHierarchy[i];
+  //
   return *this;
 }
 
@@ -462,6 +468,7 @@ TGeoVolume* AliITSUv1Layer::CreateStave(const TGeoManager * /*mgr*/){
       ypos = 0.021;  // Remove small overlap - M.S: 21may13
       zpos = -stave->GetDZ() + j*2*zmod + zmod;
       staveVol->AddNode(chipVol, j, new TGeoTranslation(xpos, ypos, zpos));
+      fHierarchy[kChip]++;
     }
  
   // put mechanical stave structure, only inner barrel up to now
@@ -479,6 +486,7 @@ TGeoVolume* AliITSUv1Layer::CreateStave(const TGeoManager * /*mgr*/){
        ypos = 0.021;  // Remove small overlap - M.S: 21may13
        zpos = -stave->GetDZ() + j*2*zmod + zmod;
        staveVol->AddNode(chipVol, j, new TGeoTranslation(xpos, ypos, zpos));
+       fHierarchy[kModule]++;
       }
     } else { // (if fStaveModel) Create new stave struct as in TDR
       chipVol = CreateStaveOuterB(xLenO);
@@ -487,7 +495,7 @@ TGeoVolume* AliITSUv1Layer::CreateStave(const TGeoManager * /*mgr*/){
           - fgkOBHalfStaveXOverlap/2;
       staveVol->AddNode(chipVol, 0, new TGeoTranslation(-xpos, 2.5, 0));
       staveVol->AddNode(chipVol, 1, new TGeoTranslation( xpos, 2.5+fgkOBHalfStaveYTrans, 0));
-
+      fHierarchy[kHalfStave] = 2; // RS 
       mechStaveVol = CreateSpaceFrameOuterB(xLenO); 
       if (mechStaveVol)
        staveVol->AddNode(mechStaveVol, 1,
@@ -2093,6 +2101,7 @@ TGeoVolume* AliITSUv1Layer::CreateStaveModelOuterB1(const TGeoManager *mgr){
   for (Int_t j=0; j<fNChips; j++) {
     zpos = -zlen + j*(2*zmod + fgkOBModuleGap) + zmod;
     halfStaveVol->AddNode(moduleVol, j, new TGeoTranslation(0, ypos, zpos));
+    fHierarchy[kModule]++;
   }
 
   ypos -= (ymod + coldPlate->GetDY());
@@ -2611,6 +2620,7 @@ TGeoVolume* AliITSUv1Layer::CreateModuleOuterB(const TGeoManager *mgr){
       zpos = -module->GetDZ() + chip->GetDZ() + k*(2*chip->GetDZ() + zGap);
       modVol->AddNode(chipVol, 2*k  , new TGeoTranslation( xpos, ypos, zpos));
       modVol->AddNode(chipVol, 2*k+1, new TGeoTranslation(-xpos, ypos, zpos));
+      fHierarchy[kChip]+=2;
     }
 
   ypos += (chip->GetDY() + flexAl->GetDY());
index fe42d5a..fa49390 100644 (file)
@@ -27,6 +27,9 @@ class TGeoVolume;
 
 class AliITSUv1Layer : public AliITSv11Geometry {
   public:
+  enum {kStave,kHalfStave,kModule,kChip,kNHLevels};
+
+  public:
     AliITSUv1Layer();
     AliITSUv1Layer(Int_t debug);
     AliITSUv1Layer(Int_t lay, Int_t debug);
@@ -42,18 +45,24 @@ class AliITSUv1Layer : public AliITSv11Geometry {
     Double_t  GetStaveWidth() const {return fStaveWidth;};
     Double_t  GetSensorThick() const {return fSensorThick;};
     Double_t  GetNStaves()    const {return fNStaves;};
-    Double_t  GetNChips()    const {return fNChips;};
+    Double_t  GetNChips()      const {return fNChips;};
     Double_t  GetRadius()      const {return fLayRadius;};
     Double_t  GetPhi0()        const {return fPhi0;};
     Double_t  GetZLength()     const {return fZLength;};
-    Int_t     GetChipType()     const {return fChipTypeID;}
+    Int_t     GetChipType()    const {return fChipTypeID;}
+    //
+    Int_t     GetNStavesPerParent()     const {return fHierarchy[kStave];}
+    Int_t     GetNHalfStavesPerParent() const {return fHierarchy[kHalfStave];}
+    Int_t     GetNModulesPerParent()    const {return fHierarchy[kModule];}
+    Int_t     GetNChipsPerParent()      const {return fHierarchy[kChip];}
+    //
     AliITSUv1::AliITSUModel_t GetStaveModel() const {return fStaveModel;}
     //
     void      SetStaveThick(Double_t t)      {fStaveThick = t;};
     void      SetStaveTilt(Double_t t);
     void      SetStaveWidth(Double_t w);
     void      SetSensorThick(Double_t t)     {fSensorThick = t;};
-    void      SetNStaves(Int_t n)            {fNStaves = n;};
+    void      SetNStaves(Int_t n)            {fHierarchy[kStave] = fNStaves = n;};
     void      SetNUnits(Int_t u);
     void      SetRadius(Double_t r)          {fLayRadius = r;};
     void      SetPhi0(Double_t phi)          {fPhi0 = phi;}
@@ -110,8 +119,10 @@ class AliITSUv1Layer : public AliITSv11Geometry {
     Double_t  fStaveWidth;  // Stave width (for turbo layers only)
     Double_t  fStaveTilt;   // Stave tilt angle (for turbo layers only) in degrees
     Int_t     fNStaves;     // Number of staves in this layer
-    Int_t     fNModules;    // Number of modules per half stave (OB only)
-    Int_t     fNChips;      // IB: N. chips per stave - OB: N. chips per module
+    Int_t     fNModules;    // Number of modules per container if defined (HalfStave, Stave, whatever is container)
+    Int_t     fNChips;      // N. chips per container (module, HalfStave, Stave, whatever is container)
+    Int_t     fHierarchy[kNHLevels]; // array to query number of staves, hstaves, modules, chips per its parent volume
+    //    
     UInt_t    fChipTypeID;  // detector type id
     Bool_t    fIsTurbo;     // True if this layer is a "turbo" layer
     Int_t     fBuildLevel;  // Used for material studies
index 2ca2f09..84af4dd 100644 (file)
@@ -71,12 +71,12 @@ void readDigits(int nev=-1,int evStart=0)
       digTree->GetEntry(imod);      
       int detType = gm->GetChipChipTypeID(imod);
       AliITSUSegmentationPix* segm = (AliITSUSegmentationPix*)gm->GetSegmentationByID(detType);
-      int lay,sta,det;
+      int lay,sta,ssta,mod,chip;
       int nsdig = sDigArr->GetEntries();
       int ndig  = digArr->GetEntries();
       if (ndig<1) continue;
-      gm->GetChipId(imod, lay,sta,det);
-      printf("\nChip %3d: (det %2d in stave %2d of Layer %d) |NSDigits: %4d NDigits: %4d\n",imod,det,sta,lay,nsdig,ndig);
+      gm->GetChipId(imod, lay,sta,ssta,mod,chip);
+      printf("\nChip %3d: (chip %2d in module:%d/substave:%1d/stave:%2d/Layer:%d) |NSDigits: %4d NDigits: %4d\n",imod,chip,mod,ssta,sta,lay,nsdig,ndig);
       //
       for (int isdig=0;isdig<nsdig;isdig++) {
        AliITSUSDigit *pSdig = (AliITSUSDigit*)sDigArr->At(isdig);