]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
Merge branch 'master' into dev
authorshahoian <ruben.shahoyan@cern.ch>
Wed, 12 Mar 2014 16:22:10 +0000 (17:22 +0100)
committershahoian <ruben.shahoyan@cern.ch>
Wed, 12 Mar 2014 16:22:10 +0000 (17:22 +0100)
31 files changed:
ITS/UPGRADE/AliITSUAux.h
ITS/UPGRADE/AliITSUGeomTGeo.cxx
ITS/UPGRADE/AliITSUGeomTGeo.h
ITS/UPGRADE/AliITSUHit.cxx
ITS/UPGRADE/AliITSUHit.h
ITS/UPGRADE/AliITSURecoLayer.cxx
ITS/UPGRADE/AliITSURecoLayer.h
ITS/UPGRADE/AliITSURecoSens.cxx
ITS/UPGRADE/AliITSURecoSens.h
ITS/UPGRADE/AliITSUTrackerGlo.cxx
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/Detector.cxx
ITS/UPGRADE/DetectorK.cxx
ITS/UPGRADE/KMCDetector.cxx
ITS/UPGRADE/MakeITSUResMisAlignment.C
ITS/UPGRADE/readDigits.C
ITS/UPGRADE/v0/AliITSUpgradeReconstructor.cxx
TPC/Rec/AliTPCtrack.cxx
TPC/Rec/AliTPCtracker.cxx
TRD/AliTRDseedV1.cxx
TRD/AliTRDtrackV1.cxx
TRD/AliTRDtrackerV1.cxx
test/ppbench/aod.C [deleted file]
test/ppbench/recraw/aod.C [deleted file]
test/ppbench/recraw/rec.C [deleted file]
test/ppbench/sim.C

index 39b548071e3891bf929808f6cc8cbba8c93d93c9..abad138c368c6db8d1b46c7493ecf8614a9cb637 100644 (file)
@@ -24,6 +24,8 @@ namespace AliITSUAux {
   void   BringTo02Pi(double &phi);
   Bool_t OKforPhiMin(double phiMin,double phi);
   Bool_t OKforPhiMax(double phiMax,double phi);
+  Double_t MeanPhiSmall(double phi0, double phi1);
+  Double_t DeltaPhiSmall(double phi0, double phi1);
   UInt_t PackCluster(Int_t lr, Int_t clID);
   Int_t  UnpackCluster(UInt_t p, Int_t &lr);
   Int_t  UnpackLayer(UInt_t p);
@@ -102,5 +104,26 @@ inline Int_t AliITSUAux::NumberOfBitsSet(UInt_t x) {
   return (((x + (x >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
 }
 
+//_________________________________________________________________________________
+inline Double_t AliITSUAux::MeanPhiSmall(double phi0, double phi1) {
+  // return mean phi, assume phis in 0:2pi
+  double phi;
+  if (!OKforPhiMin(phi0,phi1)) {phi=phi0; phi0=phi1; phi1=phi;}
+  if (phi0>phi1) phi = (phi1 - (TwoPi()-phi0))/2; // wrap
+  else           phi = (phi0+phi1)/2;
+  BringTo02Pi(phi);
+  return phi;
+}
+
+//_________________________________________________________________________________
+inline Double_t AliITSUAux::DeltaPhiSmall(double phi0, double phi1) {
+  // return delta phi, assume phis in 0:2pi
+  double del;
+  if (!OKforPhiMin(phi0,phi1)) {del=phi0; phi0=phi1; phi1=del;}
+  del = phi1 - phi0;
+  if (del<0) del += TwoPi();
+  return del;
+}
+
 
 #endif
index 4553171e4db51a5f7fbc35f124b3adc40f774c83..0fbd5386f9953df215a564a694096c819291aa7e 100644 (file)
@@ -31,6 +31,8 @@
 #include <TString.h>
 #include <TGeoManager.h>
 #include <TGeoPhysicalNode.h>
+#include <TGeoShape.h>
+#include <TGeoBBox.h>
 #include <TDatime.h>
 #include <TMath.h>
 #include <TSystem.h>
@@ -48,8 +50,8 @@ UInt_t AliITSUGeomTGeo::fgUIDShift = 16;                // bit shift to go from
 TString AliITSUGeomTGeo::fgITSVolName = "ITSV";
 TString AliITSUGeomTGeo::fgITSLrName  = "ITSULayer";
 TString AliITSUGeomTGeo::fgITSStaveName = "ITSUStave";
-TString AliITSUGeomTGeo::fgITSSubStaveName = "ITSUSubStave";
-TString AliITSUGeomTGeo::fgITSModuleName = "ITSUModuleName"; 
+TString AliITSUGeomTGeo::fgITSHalfStaveName = "ITSUHalfStave";
+TString AliITSUGeomTGeo::fgITSModuleName = "ITSUModule";
 TString AliITSUGeomTGeo::fgITSChipName = "ITSUChip";
 TString AliITSUGeomTGeo::fgITSSensName = "ITSUSensor";
 TString AliITSUGeomTGeo::fgITSWrapVolName = "ITSUWrapVol";
@@ -63,10 +65,11 @@ AliITSUGeomTGeo::AliITSUGeomTGeo(Bool_t build, Bool_t loadSegm)
   ,fNLayers(0)
   ,fNChips(0)
   ,fNStaves(0)
-  ,fNSubStaves(0)
+  ,fNHalfStaves(0)
   ,fNModules(0)
   ,fNChipsPerModule(0)
-  ,fNChipsPerSubStave(0)
+  ,fNChipRowsPerModule(0)
+  ,fNChipsPerHalfStave(0)
   ,fNChipsPerStave(0)
   ,fNChipsPerLayer(0)
   ,fLrChipType(0)
@@ -87,10 +90,11 @@ AliITSUGeomTGeo::AliITSUGeomTGeo(const AliITSUGeomTGeo &src)
   ,fNLayers(src.fNLayers)
   ,fNChips(src.fNChips)
   ,fNStaves(0)
-  ,fNSubStaves(0)
+  ,fNHalfStaves(0)
   ,fNModules(0)
   ,fNChipsPerModule(0)
-  ,fNChipsPerSubStave(0)
+  ,fNChipRowsPerModule(0)
+  ,fNChipsPerHalfStave(0)
   ,fNChipsPerStave(0)
   ,fNChipsPerLayer(0)
   ,fLrChipType(0)
@@ -102,21 +106,21 @@ AliITSUGeomTGeo::AliITSUGeomTGeo(const AliITSUGeomTGeo &src)
   // copy c-tor
   if (fNLayers) {
     fNStaves   = new Int_t[fNLayers];
-    fNSubStaves= new Int_t[fNLayers];
-    fNModules  = new Int_t[fNLayers];
     fNChipsPerModule = new Int_t[fNLayers];
+    fNChipRowsPerModule = new Int_t[fNLayers];
     fLrChipType  = new Int_t[fNLayers];
     fLastChipIndex   = new Int_t[fNLayers];
-    fNChipsPerSubStave = 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];
-      fNSubStaves[i] = src.fNSubStaves[i];
+      fNHalfStaves[i] = src.fNHalfStaves[i];
       fNModules[i] = src.fNModules[i];
       fNChipsPerModule[i] = src.fNChipsPerModule[i];
-      fNChipsPerSubStave[i] = src.fNChipsPerSubStave[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];
@@ -157,11 +161,12 @@ AliITSUGeomTGeo::~AliITSUGeomTGeo()
 {
   //d-tor
   delete[] fNStaves;
-  delete[] fNSubStaves;
+  delete[] fNHalfStaves;
   delete[] fNModules;
   delete[] fLrChipType;
   delete[] fNChipsPerModule;
-  delete[] fNChipsPerSubStave;
+  delete[] fNChipRowsPerModule;
+  delete[] fNChipsPerHalfStave;
   delete[] fNChipsPerStave;
   delete[] fNChipsPerLayer;
   delete[] fLastChipIndex;
@@ -177,15 +182,16 @@ AliITSUGeomTGeo& AliITSUGeomTGeo::operator=(const AliITSUGeomTGeo &src)
   // cp op.
   if (this!=&src) {
     delete[] fNStaves;
-    delete[] fNSubStaves;
+    delete[] fNHalfStaves;
     delete[] fNModules;
     delete[] fLrChipType;
     delete[] fNChipsPerModule;
-    delete[] fNChipsPerSubStave;
+    delete[] fNChipRowsPerModule;
+    delete[] fNChipsPerHalfStave;
     delete[] fNChipsPerStave;
     delete[] fNChipsPerLayer;
     delete[] fLastChipIndex;
-    fNStaves = fNSubStaves = fNModules = fLrChipType = fNChipsPerModule = fLastChipIndex = 0;
+    fNStaves = fNHalfStaves = fNModules = fLrChipType = fNChipsPerModule = fLastChipIndex = 0;
     fVersion = src.fVersion;
     fNLayers = src.fNLayers;
     fNChips = src.fNChips;
@@ -220,20 +226,22 @@ AliITSUGeomTGeo& AliITSUGeomTGeo::operator=(const AliITSUGeomTGeo &src)
     //
     if (fNLayers) {
       fNStaves   = new Int_t[fNLayers];
-      fNSubStaves   = new Int_t[fNLayers];
+      fNHalfStaves   = new Int_t[fNLayers];
       fNModules     = new Int_t[fNLayers];
       fNChipsPerModule = new Int_t[fNLayers];
-      fNChipsPerSubStave = 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];
-       fNSubStaves[i] = src.fNSubStaves[i];
+       fNHalfStaves[i] = src.fNHalfStaves[i];
        fNModules[i]   = src.fNModules[i];
        fNChipsPerModule[i] = src.fNChipsPerModule[i];
-       fNChipsPerSubStave[i] = src.fNChipsPerSubStave[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];
@@ -269,7 +277,7 @@ Int_t AliITSUGeomTGeo::GetChipIndex(Int_t lay,Int_t sta, Int_t substa, Int_t chi
   //    Int_t chipInSStave  The chip number in the sub stave. Starting from 0
   //
   int n = GetFirstChipIndex(lay) + fNChipsPerStave[lay]*sta + chipInSStave;
-  if (fNSubStaves[lay] && substa>0) n += fNChipsPerSubStave[lay]*substa;
+  if (fNHalfStaves[lay] && substa>0) n += fNChipsPerHalfStave[lay]*substa;
   return n;
 }
 
@@ -286,7 +294,7 @@ Int_t AliITSUGeomTGeo::GetChipIndex(Int_t lay,Int_t sta, Int_t substa, Int_t md,
   //    Int_t chipInSStave  The chip number in the module. Starting from 0
   //
   int n = GetFirstChipIndex(lay) + fNChipsPerStave[lay]*sta + chipInMod;
-  if (fNSubStaves[lay] && substa>0) n += fNChipsPerSubStave[lay]*substa;
+  if (fNHalfStaves[lay] && substa>0) n += fNChipsPerHalfStave[lay]*substa;
   if (fNModules[lay] && md>0)       n += fNChipsPerModule[lay]*md;
   return n;
 }
@@ -330,16 +338,16 @@ Int_t AliITSUGeomTGeo::GetStave(Int_t index) const
 }
 
 //______________________________________________________________________
-Int_t AliITSUGeomTGeo::GetSubStave(Int_t index) const
+Int_t AliITSUGeomTGeo::GetHalfStave(Int_t index) const
 {
   // Get chip substave id in stave, from 0
   //
   int lay = 0;
   while(index>fLastChipIndex[lay]) lay++;
-  if (fNSubStaves[lay]<0) return -1;
+  if (fNHalfStaves[lay]<0) return -1;
   index -= GetFirstChipIndex(lay);
   index %= fNChipsPerStave[lay];
-  return index/fNChipsPerSubStave[lay];
+  return index/fNChipsPerHalfStave[lay];
 }
 
 //______________________________________________________________________
@@ -352,7 +360,7 @@ Int_t AliITSUGeomTGeo::GetModule(Int_t index) const
   if (fNModules[lay]<0) return 0;
   index -= GetFirstChipIndex(lay);
   index %= fNChipsPerStave[lay];
-  if (fNSubStaves[lay]) index %= fNChipsPerSubStave[lay];
+  if (fNHalfStaves[lay]) index %= fNChipsPerHalfStave[lay];
   return index/fNChipsPerModule[lay];
 }
 
@@ -379,14 +387,14 @@ Int_t AliITSUGeomTGeo::GetChipIdInStave(Int_t index) const
 }
 
 //______________________________________________________________________
-Int_t AliITSUGeomTGeo::GetChipIdInSubStave(Int_t index) const
+Int_t AliITSUGeomTGeo::GetChipIdInHalfStave(Int_t index) const
 {
   // Get chip number within stave, from 0
   //
   int lay = 0;
   while(index>fLastChipIndex[lay]) lay++;
   index -= GetFirstChipIndex(lay);
-  return index%fNChipsPerSubStave[lay];
+  return index%fNChipsPerHalfStave[lay];
 }
 
 //______________________________________________________________________
@@ -401,7 +409,7 @@ Int_t AliITSUGeomTGeo::GetChipIdInModule(Int_t index) const
 }
 
 //______________________________________________________________________
-Bool_t AliITSUGeomTGeo::GetChipId(Int_t index,Int_t &lay,Int_t &sta,Int_t &ssta, Int_t &mod, Int_t &chip)  const
+Bool_t AliITSUGeomTGeo::GetChipId(Int_t index,Int_t &lay,Int_t &sta,Int_t &hsta, Int_t &mod, Int_t &chip)  const
 {
   //
   // This routine computes the layer, stave, substave, module and chip number 
@@ -411,7 +419,7 @@ Bool_t AliITSUGeomTGeo::GetChipId(Int_t index,Int_t &lay,Int_t &sta,Int_t &ssta,
   // Outputs:
   //     Int_t lay    The layer number. Starting from 0
   //     Int_t sta    The stave number. Starting from 0
-  //     Int_t ssta   The substave number. Starting from 0
+  //     Int_t ssta   The halfstave number. Starting from 0
   //     Int_t mod    The module number. Starting from 0
   //     Int_t chip   The detector number. Starting from 0
   //
@@ -419,8 +427,8 @@ Bool_t AliITSUGeomTGeo::GetChipId(Int_t index,Int_t &lay,Int_t &sta,Int_t &ssta,
   index -= GetFirstChipIndex(lay);
   sta  = index/fNChipsPerStave[lay];
   index %= fNChipsPerStave[lay];
-  ssta = fNSubStaves[lay]>0 ? index/fNChipsPerSubStave[lay] : -1;
-  index %= fNChipsPerSubStave[lay];
+  hsta = fNHalfStaves[lay]>0 ? index/fNChipsPerHalfStave[lay] : -1;
+  index %= fNChipsPerHalfStave[lay];
   mod  = fNModules[lay]>0 ? index/fNChipsPerModule[lay] : -1;
   chip = index%fNChipsPerModule[lay];
   //
@@ -468,11 +476,11 @@ const char* AliITSUGeomTGeo::ComposeSymNameStave(Int_t lr, Int_t stave)
 }
 
 //______________________________________________________________________
-const char* AliITSUGeomTGeo::ComposeSymNameSubStave(Int_t lr, Int_t stave, Int_t substave)
+const char* AliITSUGeomTGeo::ComposeSymNameHalfStave(Int_t lr, Int_t stave, Int_t substave)
 {
   // sym name of the stave at given layer
   return substave>=0 ? 
-    Form("%s/%s%d",ComposeSymNameStave(lr,stave),GetITSSubStavePattern(),substave) :
+    Form("%s/%s%d",ComposeSymNameStave(lr,stave),GetITSHalfStavePattern(),substave) :
     ComposeSymNameStave(lr,stave);
 }
 
@@ -481,8 +489,8 @@ const char* AliITSUGeomTGeo::ComposeSymNameModule(Int_t lr, Int_t stave, Int_t s
 {
   // sym name of the substave at given layer/stave
   return mod>=0 ? 
-    Form("%s/%s%d",ComposeSymNameSubStave(lr,stave,substave),GetITSModulePattern(),mod) :
-    ComposeSymNameSubStave(lr,stave,substave);    
+    Form("%s/%s%d",ComposeSymNameHalfStave(lr,stave,substave),GetITSModulePattern(),mod) :
+    ComposeSymNameHalfStave(lr,stave,substave);    
 }
 
 //______________________________________________________________________
@@ -632,7 +640,7 @@ TGeoHMatrix* AliITSUGeomTGeo::ExtractMatrixSens(Int_t index) const
   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 (fNSubStaves[lay]>0) path += Form("%s%d_%d/",AliITSUGeomTGeo::GetITSSubStavePattern(),lay,sstav);
+  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;
@@ -687,23 +695,25 @@ void AliITSUGeomTGeo::BuildITS(Bool_t loadSegm)
   if (!fNLayers) return;
   //
   fNStaves         = new Int_t[fNLayers];
-  fNSubStaves      = new Int_t[fNLayers];
+  fNHalfStaves     = new Int_t[fNLayers];
   fNModules        = new Int_t[fNLayers];
   fNChipsPerModule = new Int_t[fNLayers];
-  fNChipsPerSubStave = 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);
-    fNSubStaves[i]      = ExtractNumberOfSubStaves(i);
+    fNHalfStaves[i]     = ExtractNumberOfHalfStaves(i);
     fNModules[i]        = ExtractNumberOfModules(i);
-    fNChipsPerModule[i] = ExtractNChipsPerModule(i);
-    fNChipsPerSubStave[i] = fNChipsPerModule[i]*Max(1,fNModules[i]);
-    fNChipsPerStave[i]    = fNChipsPerSubStave[i]*Max(1,fNSubStaves[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;
@@ -781,7 +791,7 @@ Int_t AliITSUGeomTGeo::ExtractNumberOfStaves(Int_t lay) const
 }
 
 //______________________________________________________________________
-Int_t AliITSUGeomTGeo::ExtractNumberOfSubStaves(Int_t lay) const
+Int_t AliITSUGeomTGeo::ExtractNumberOfHalfStaves(Int_t lay) const
 {
   // Determines the number of substaves in the stave of the layer
   //
@@ -789,7 +799,7 @@ Int_t AliITSUGeomTGeo::ExtractNumberOfSubStaves(Int_t lay) const
   //   lay: layer number, starting from 0
   //
   // MS
-  if (fgITSSubStaveName.IsNull()) return 0; // for the setup w/o substave defined the stave and the substave is the same thing
+  if (fgITSHalfStaveName.IsNull()) return 0; // for the setup w/o substave defined the stave and the substave is the same thing
   Int_t nSS = 0;
   char stavnam[30];
   snprintf(stavnam, 30, "%s%d", GetITSStavePattern(),lay);
@@ -798,7 +808,7 @@ Int_t AliITSUGeomTGeo::ExtractNumberOfSubStaves(Int_t lay) const
   //
   // Loop on all stave nodes, count Chip volumes by checking names
   Int_t nNodes = volLd->GetNodes()->GetEntries();
-  for (Int_t j=0; j<nNodes; j++) if (strstr(volLd->GetNodes()->At(j)->GetName(),GetITSSubStavePattern())) nSS++;
+  for (Int_t j=0; j<nNodes; j++) if (strstr(volLd->GetNodes()->At(j)->GetName(),GetITSHalfStavePattern())) nSS++;
   //
   return nSS;
   //
@@ -816,8 +826,8 @@ Int_t AliITSUGeomTGeo::ExtractNumberOfModules(Int_t lay) const
   if (fgITSModuleName.IsNull()) return 0;
   char stavnam[30];
   TGeoVolume* volLd = 0;
-  if (!fgITSSubStaveName.IsNull()) {
-    snprintf(stavnam, 30, "%s%d", GetITSSubStavePattern(),lay); 
+  if (!fgITSHalfStaveName.IsNull()) {
+    snprintf(stavnam, 30, "%s%d", GetITSHalfStavePattern(),lay); 
     volLd = gGeoManager->GetVolume(stavnam);
   }
   if (!volLd) { // no substaves, check staves
@@ -836,10 +846,10 @@ Int_t AliITSUGeomTGeo::ExtractNumberOfModules(Int_t lay) const
 }
 
 //______________________________________________________________________
-Int_t AliITSUGeomTGeo::ExtractNChipsPerModule(Int_t lay)  const
+Int_t AliITSUGeomTGeo::ExtractNChipsPerModule(Int_t lay, int &nrow)  const
 {
   // Determines the number of chips per module on the (sub)stave in the Upgrade Geometry
-  //
+  // Also extract the layout: span of module centers in Z and X
   // Inputs:
   //   lay: layer number from 0
   // MS
@@ -851,8 +861,8 @@ Int_t AliITSUGeomTGeo::ExtractNChipsPerModule(Int_t lay)  const
     volLd = gGeoManager->GetVolume(stavnam);
   }
   if (!volLd) { // no modules on this layer, check substaves
-    if (!fgITSSubStaveName.IsNull()) {
-      snprintf(stavnam, 30, "%s%d", GetITSSubStavePattern(),lay); 
+    if (!fgITSHalfStaveName.IsNull()) {
+      snprintf(stavnam, 30, "%s%d", GetITSHalfStavePattern(),lay); 
       volLd = gGeoManager->GetVolume(stavnam);
     }
   }
@@ -864,11 +874,44 @@ Int_t AliITSUGeomTGeo::ExtractNChipsPerModule(Int_t lay)  const
   //
   // Loop on all stave nodes, count Chip volumes by checking names
   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++) {
     //    AliInfo(Form("L%d %d of %d %s %s -> %d",lay,j,nNodes,volLd->GetNodes()->At(j)->GetName(),GetITSChipPattern(),numberOfChips));
-    if (strstr(volLd->GetNodes()->At(j)->GetName(),GetITSChipPattern())) numberOfChips++;
+    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;
   //
 }
@@ -908,8 +951,10 @@ 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\tNMod:%d\tNSubSt:%d\tNSt:%3d\tChipType:%3d\tChip#:%4d:%4d\tWrapVol:%d\n",
-          i,fNStaves[i],fNChipsPerModule[i],fNModules[i],fNSubStaves[i],fNStaves[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]);
   }
 }
index 3f98c5d1a4b1f5aabdf1dd370da7cb493a57d85f..8083a4d94cc612315650ea990d4b892d69fbb31e 100644 (file)
@@ -55,12 +55,14 @@ class AliITSUGeomTGeo : public TObject {
   AliITSUGeomTGeo& operator=(const AliITSUGeomTGeo &geom);
   //
   Int_t  GetNChips()                                                    const {return fNChips;}
+  Int_t  GetNChipRowsPerModule(Int_t lay)                               const {return fNChipRowsPerModule[lay];}
+  Int_t  GetNChipColsPerModule(Int_t lay)                               const {return fNChipRowsPerModule[lay] ? fNChipsPerModule[lay]/fNChipRowsPerModule[lay] : -1;}
   Int_t  GetNChipsPerModule(Int_t lay)                                  const {return fNChipsPerModule[lay];}
-  Int_t  GetNChipsPerSubStave(Int_t lay)                                const {return fNChipsPerSubStave[lay];}
+  Int_t  GetNChipsPerHalfStave(Int_t lay)                               const {return fNChipsPerHalfStave[lay];}
   Int_t  GetNChipsPerStave(Int_t lay)                                   const {return fNChipsPerStave[lay];}
   Int_t  GetNChipsPerLayer(Int_t lay)                                   const {return fNChipsPerLayer[lay];}
   Int_t  GetNModules(Int_t lay)                                         const {return fNModules[lay];}
-  Int_t  GetNSubStaves(Int_t lay)                                       const {return fNSubStaves[lay];}
+  Int_t  GetNHalfStaves(Int_t lay)                                      const {return fNHalfStaves[lay];}
   Int_t  GetNStaves(Int_t lay)                                          const {return fNStaves[lay];}
   Int_t  GetNLayers()                                                   const {return fNLayers;}
   
@@ -71,11 +73,11 @@ class AliITSUGeomTGeo : public TObject {
   Bool_t GetChipId(Int_t index,Int_t &lay,Int_t &sta,Int_t &ssta,Int_t &mod,Int_t &chip)        const;
   Int_t  GetLayer(Int_t index)                                          const;
   Int_t  GetStave(Int_t index)                                          const;
-  Int_t  GetSubStave(Int_t index)                                       const;
+  Int_t  GetHalfStave(Int_t index)                                      const;
   Int_t  GetModule(Int_t index)                                         const;
   Int_t  GetChipIdInLayer(Int_t index)                                  const;
   Int_t  GetChipIdInStave(Int_t index)                                  const;
-  Int_t  GetChipIdInSubStave(Int_t index)                               const;
+  Int_t  GetChipIdInHalfStave(Int_t index)                              const;
   Int_t  GetChipIdInModule(Int_t index)                                 const;
   //
   Int_t  GetLastChipIndex(Int_t lay)                                       const {return fLastChipIndex[lay];}
@@ -130,7 +132,7 @@ class AliITSUGeomTGeo : public TObject {
   static const char* GetITSLayerPattern()                               {return fgITSLrName.Data();}
   static const char* GetITSWrapVolPattern()                             {return fgITSWrapVolName.Data();}
   static const char* GetITSStavePattern()                               {return fgITSStaveName.Data();}
-  static const char* GetITSSubStavePattern()                            {return fgITSSubStaveName.Data();}
+  static const char* GetITSHalfStavePattern()                           {return fgITSHalfStaveName.Data();}
   static const char* GetITSModulePattern()                              {return fgITSModuleName.Data();}
   static const char* GetITSChipPattern()                                {return fgITSChipName.Data();}
   static const char* GetITSSensorPattern()                              {return fgITSSensName.Data();}
@@ -141,7 +143,7 @@ class AliITSUGeomTGeo : public TObject {
   static void        SetITSLayerPattern(const char* nm)                 {fgITSLrName = nm;}
   static void        SetITSWrapVolPattern(const char* nm)               {fgITSWrapVolName = nm;}
   static void        SetITSStavePattern(const char* nm)                 {fgITSStaveName = nm;}
-  static void        SetITSSubStavePattern(const char* nm)              {fgITSSubStaveName = nm;}
+  static void        SetITSHalfStavePattern(const char* nm)             {fgITSHalfStaveName = nm;}
   static void        SetITSModulePattern(const char* nm)                {fgITSModuleName = nm;}
   static void        SetITSChipPattern(const char* nm)                  {fgITSChipName = nm;}
   static void        SetITSSensorPattern(const char* nm)                {fgITSSensName = nm;}
@@ -152,7 +154,7 @@ class AliITSUGeomTGeo : public TObject {
   static const char *ComposeSymNameITS();
   static const char *ComposeSymNameLayer(Int_t lr);
   static const char *ComposeSymNameStave(Int_t lr, Int_t sta);
-  static const char *ComposeSymNameSubStave(Int_t lr, Int_t sta, Int_t ssta);
+  static const char *ComposeSymNameHalfStave(Int_t lr, Int_t sta, Int_t ssta);
   static const char *ComposeSymNameModule(Int_t lr, Int_t sta, Int_t ssta, Int_t mod);
   static const char *ComposeSymNameChip(Int_t lr, Int_t sta, Int_t ssta, Int_t mod, Int_t chip);
   //
@@ -167,9 +169,9 @@ class AliITSUGeomTGeo : public TObject {
   TGeoHMatrix* ExtractMatrixSens(Int_t index)                     const;
   Bool_t       GetLayer(Int_t index,Int_t &lay,Int_t &index2)     const;
   TGeoPNEntry* GetPNEntry(Int_t index)                            const;
-  Int_t        ExtractNChipsPerModule(Int_t lay)                  const;
+  Int_t        ExtractNChipsPerModule(Int_t lay, Int_t &nrow)     const;
   Int_t        ExtractNumberOfStaves(Int_t lay)                   const;
-  Int_t        ExtractNumberOfSubStaves(Int_t lay)                const;
+  Int_t        ExtractNumberOfHalfStaves(Int_t lay)               const;
   Int_t        ExtractNumberOfModules(Int_t lay)                  const;
   Int_t        ExtractLayerChipType(Int_t lay)                    const;
   Int_t        ExtractNumberOfLayers();
@@ -182,10 +184,11 @@ class AliITSUGeomTGeo : public TObject {
   Int_t  fNLayers;             // number of layers
   Int_t  fNChips;              // The total number of chips
   Int_t *fNStaves;             //[fNLayers] Array of the number of staves/layer(layer)
-  Int_t *fNSubStaves;          //[fNLayers] Array of the number of substaves/stave(layer)
+  Int_t *fNHalfStaves;         //[fNLayers] Array of the number of substaves/stave(layer)
   Int_t *fNModules;            //[fNLayers] Array of the number of modules/substave(layer)
   Int_t *fNChipsPerModule;     //[fNLayers] Array of the number of chips per module (group of chips on the substaves)
-  Int_t *fNChipsPerSubStave;   //[fNLayers] Array of the number of chips per substave
+  Int_t *fNChipRowsPerModule;  //[fNLayers] Array of the number of chips rows per module (relevant for OB modules)
+  Int_t *fNChipsPerHalfStave;  //[fNLayers] Array of the number of chips per substave
   Int_t *fNChipsPerStave;      //[fNLayers] Array of the number of chips per stave
   Int_t *fNChipsPerLayer;      //[fNLayers] Array of the number of chips per stave
 
@@ -202,7 +205,7 @@ class AliITSUGeomTGeo : public TObject {
   static TString  fgITSVolName;             // ITS mother volume name
   static TString  fgITSLrName;              // ITS Layer name
   static TString  fgITSStaveName;           // ITS Stave name 
-  static TString  fgITSSubStaveName;        // ITS SubStave name 
+  static TString  fgITSHalfStaveName;       // ITS HalfStave name 
   static TString  fgITSModuleName;          // ITS Module name 
   static TString  fgITSChipName;            // ITS Chip name 
   static TString  fgITSSensName;            // ITS Sensor name 
index 21f07d0a0bdb086cdbf64ff338339349ba84046b..116f4c2a77a50d972806a1d362facbf7136c3e66 100644 (file)
@@ -118,12 +118,12 @@ Int_t AliITSUHit::GetStave() const
 }  
 
 //______________________________________________________________________
-Int_t AliITSUHit::GetSubStave() const
+Int_t AliITSUHit::GetHalfStave() const
 {
   // Returns the substave of the chip. Note: indices start from 0!
   AliITSUGeomTGeo *gm = ((AliITSU*)gAlice->GetDetector("ITS"))->GetITSGeomTGeo();
   if (!gm) AliFatal("NULL pointer to the geometry!");
-  return gm->GetSubStave(fModule);
+  return gm->GetHalfStave(fModule);
 }  
 
 //______________________________________________________________________
index e1b118b14ee1ae8be478c8ed9e3d7936dcb526a7..ff279d164ba5895f44ceea42ba9b918ab16050e2 100644 (file)
@@ -30,7 +30,7 @@ class AliITSUHit : public AliITShit {
 
   virtual Int_t GetLayer() const;
   virtual Int_t GetStave() const;
-  virtual Int_t GetSubStave() const;
+  virtual Int_t GetHalfStave() const;
   virtual Int_t GetModule() const;  
   virtual Int_t GetChipInModule() const;
   virtual void  GetChipID(Int_t &layer,Int_t &stave,Int_t &sstave, Int_t &mod, Int_t &det) const;
index c2f6f3a33e8cbcf1d49b5f71e1ed693ada6c00c7..e3bea39dc8a0921d78cd0cbfb491ecddf4a33457 100644 (file)
@@ -16,18 +16,17 @@ ClassImp(AliITSURecoLayer)
 AliITSURecoLayer::AliITSURecoLayer(const char* name)
   :fActiveID(-1)
   ,fNSensors(0)
-  ,fNSensInStave(0)
-  ,fNStaves(0)
+  ,fNSensorRows(0)
+  ,fNSensorsPerRow(0)
+  ,fSensVIDtoMatrixID(0)
   ,fR(0)
   ,fRMax(0)
   ,fRMin(0)
   ,fZMax(0)
   ,fZMin(0)
-  ,fPhiStaMax(0)
-  ,fPhiStaMin(0)
   ,fPhiOffs(0)
   ,fSensDZInv(0)
-  ,fDPhiStaInv(0)
+  ,fSensDPhiInv(0)
   ,fMaxStep(0.5)
   ,fSensors(0)
   ,fITSGeom(0)
@@ -41,18 +40,17 @@ AliITSURecoLayer::AliITSURecoLayer(const char* name)
 AliITSURecoLayer::AliITSURecoLayer(const char* name, Int_t activeID, AliITSUGeomTGeo* gm)
   :fActiveID(activeID)
   ,fNSensors(0)
-  ,fNSensInStave(0)
-  ,fNStaves(0)
+  ,fNSensorRows(0)
+  ,fNSensorsPerRow(0)
+  ,fSensVIDtoMatrixID(0)
   ,fR(0)
   ,fRMax(0)
   ,fRMin(0)
   ,fZMax(0)
   ,fZMin(0)
-  ,fPhiStaMax(0)
-  ,fPhiStaMin(0)
   ,fPhiOffs(0)
   ,fSensDZInv(0)
-  ,fDPhiStaInv(0)
+  ,fSensDPhiInv(0)
   ,fMaxStep(0.5)
   ,fSensors(0)
   ,fITSGeom(gm)
@@ -67,9 +65,8 @@ AliITSURecoLayer::AliITSURecoLayer(const char* name, Int_t activeID, AliITSUGeom
 AliITSURecoLayer::~AliITSURecoLayer()
 {
   // def. d-tor
-  delete[] fSensors;
-  delete[] fPhiStaMax;
-  delete[] fPhiStaMin;
+  delete fSensors;
+  delete[] fSensVIDtoMatrixID;
   if (GetOwnsClusterArray()) delete fClusters;
 }
 
@@ -77,8 +74,10 @@ AliITSURecoLayer::~AliITSURecoLayer()
 void AliITSURecoLayer::Print(Option_t* opt) const                            
 {
   //print 
-  printf("Lr %-15s %d (act:%+d), NSens: %4d | MaxStep:%.2f ",GetName(),GetID(),GetActiveID(),GetNSensors(),fMaxStep);
-  printf("%6.3f<R<%6.3f | %+8.3f<Z<%+8.3f dZ:%6.3f\n",fRMin,fRMax,fZMin,fZMax,fSensDZInv>0 ? 1/fSensDZInv : 0);
+  printf("Lr %-15s %d (act:%+d), NSens: %4d in %d rows| MaxStep:%.2f ",
+        GetName(),GetID(),GetActiveID(),GetNSensors(),GetNSensorRows(),fMaxStep);
+  printf("%6.3f<R<%6.3f | %+8.3f<Z<%+8.3f dZ:%6.3f dPhi:%6.3f\n",fRMin,fRMax,fZMin,fZMax,
+        fSensDZInv>0 ? 1/fSensDZInv : 0, fSensDPhiInv>0 ? 1/fSensDPhiInv : 0);
   TString opts = opt; opts.ToLower();
   if (opts.Contains("sn")) for (int i=0;i<GetNSensors();i++) GetSensor(i)->Print(opt);
 }
@@ -89,50 +88,50 @@ void AliITSURecoLayer::Build()
   // build internal structures
   const double kSafeR = 0.05; // safety margin for Rmin,Rmax of the layer
   if (fActiveID<0) return;
-  fNStaves = fITSGeom->GetNStaves(fActiveID);
-  fNSensInStave = fITSGeom->GetNChipsPerModule(fActiveID);
-  fNSensors = fNStaves*fNSensInStave;
-  fSensors = new AliITSURecoSens*[fNSensors];
+  //
+  int nStaves=fITSGeom->GetNStaves(fActiveID);
+  // determine number of sensor rows (sensors aligned at same phi and spanning the Z range of the layer)
+  fNSensorRows = nStaves;
+  //
+  // if the stave has susbtaves, each substave can have multiple rows of sensors (but just 1 row of modules)
+  if (fITSGeom->GetNHalfStaves(fActiveID)>0) fNSensorRows *= fITSGeom->GetNHalfStaves(fActiveID);
+  //
+  // if there are modules defined, the module may have multiple rows of sensors (though not spanning full Z)
+  if (fITSGeom->GetNModules(fActiveID)>0) fNSensorRows *= fITSGeom->GetNChipRowsPerModule(fActiveID);
+  //
+  fNSensors = fITSGeom->GetNChipsPerLayer(fActiveID);
+  fNSensorsPerRow = fNSensors/fNSensorRows;
+  //
+  fSensors = new TObjArray(fNSensors);
+  fSensVIDtoMatrixID = new Int_t[fNSensors];
   const AliITSsegmentation* kSegm = fITSGeom->GetSegmentation(fActiveID);
   //
-  // name layer according its active id, detector type and segmentation tyoe
   TGeoHMatrix mmod;
   const TGeoHMatrix* mt2l;
-  fRMin=fZMin=1e9;
-  fRMax=fZMax=-1e9;
   double phiTF,rTF, loc[3]={0,0,0},glo[3];
-  fNSensors = 0;
-  fPhiStaMin = new Double_t[fNStaves];
-  fPhiStaMax = new Double_t[fNStaves];
-  fSensDZInv = 0;
-  fDPhiStaInv = fNStaves/TwoPi();
-  //
-  for (int ild=0;ild<fNStaves;ild++) {
-    fPhiStaMin[ild] = 1e9;
-    fPhiStaMax[ild] = -1e9;
-    //
-    for (int idt=0;idt<fNSensInStave;idt++) {
-      AliITSURecoSens* sens = new AliITSURecoSens(fNSensors++);
-      fSensors[ild*fNSensInStave+idt] = sens;
-      //
+  //
+  int nSensPerStave = fITSGeom->GetNChipsPerStave(fActiveID);
+  for (int staveI=0;staveI<nStaves;staveI++) {
+    for (int sensI=0;sensI<nSensPerStave;sensI++) {
+      int sID = fITSGeom->GetChipIndex(fActiveID,staveI,sensI);
+      AliITSURecoSens* sens = new AliITSURecoSens( sID );
+      fSensors->AddLast(sens);
       double phiMin=1e9,phiMax=-1e9,zMin=1e9,zMax=-1e9;
-      mmod = *fITSGeom->GetMatrixSens(fActiveID,ild,idt);
-      for (int ix=0;ix<2;ix++) {
+      // this is NOT the sensor matrix, just the ideal chip matrix to get neighbors correct
+      fITSGeom->GetOrigMatrix(sID,mmod); 
+      //
+      for (int ix=0;ix<2;ix++) {       // determine sensor boundaries (ideal)
        loc[0] = (ix-0.5)*kSegm->Dx(); // +-DX/2
        for (int iy=0;iy<2;iy++) {
          loc[1] = (iy-0.5)*kSegm->Dy(); // +-DY/2
          for (int iz=0;iz<2;iz++) {
            loc[2] = (iz-0.5)*kSegm->Dz(); // +-DZ/2
-           //
            mmod.LocalToMaster(loc,glo);
            double phi = ATan2(glo[1],glo[0]);
-           double r   = glo[0]*glo[0] + glo[1]*glo[1];
-           if (fRMin>r) fRMin = r;
-           if (fRMax<r) fRMax = r;
            BringTo02Pi(phi);
-           if      (phiMin>1e8) phiMin=phi; 
+           if      (phiMin>1e8)  phiMin=phi;
            else if (!OKforPhiMin(phiMin,phi)) phiMin=phi;
-           if      (phiMax<-1e8) phiMax=phi;
+           if      (phiMax<-1e8) phiMax=phi; 
            else if (!OKforPhiMax(phiMax,phi)) phiMax=phi;            
            if (glo[2]>zMax) zMax=glo[2];
            if (glo[2]<zMin) zMin=glo[2];
@@ -140,107 +139,103 @@ void AliITSURecoLayer::Build()
        }
       }
       sens->SetBoundaries(phiMin,phiMax,zMin,zMax);
-      mt2l = fITSGeom->GetMatrixT2L(fActiveID,ild,idt);
-      mmod.Multiply(mt2l);     
-      loc[0]=loc[1]=loc[2]=0;
-      mmod.LocalToMaster(loc,glo);
-      rTF   = Sqrt(glo[0]*glo[0] + glo[1]*glo[1]);  //  tracking params (misaligned)
-      phiTF = ATan2(glo[1],glo[0]);
-      BringTo02Pi(phiTF);
-      //
-      sens->SetXTF(rTF);
-      sens->SetPhiTF(phiTF);
-      //
-      if      (fPhiStaMin[ild]>1e8)  fPhiStaMin[ild] = phiMin;
-      else if (!OKforPhiMin(fPhiStaMin[ild],phiMin)) fPhiStaMin[ild] = phiMin;
-      if      (fPhiStaMax[ild]<-1e8) fPhiStaMax[ild] = phiMax;
-      else if (!OKforPhiMax(fPhiStaMax[ild],phiMax)) fPhiStaMax[ild] = phiMax;
-      if (fZMin>zMin) fZMin = zMin;
-      if (fZMax<zMax) fZMax = zMax;
-      //
-      if (idt>0) fSensDZInv += zMax - GetSensor(ild,idt-1)->GetZMax(); // z interval to previous
     }
   }
+  fSensors->Sort(); // sort sensors to get the neighborhood correct
+  //
+  // now fill real sensor angles, Z's, accounting for misalignment
+  fRMin=fZMin=1e9;
+  fRMax=fZMax=-1e9;
+  //
+  fPhiOffs = 0;
+  int firstSensID = fITSGeom->GetFirstChipIndex(fActiveID);
+  for (int sensI=0;sensI<fNSensors;sensI++) {
+    AliITSURecoSens* sens = GetSensor(sensI);
+    mmod = *fITSGeom->GetMatrixSens(sens->GetID());
+    fSensVIDtoMatrixID[sens->GetID() - firstSensID] = sensI;
+    double phiMin=1e9,phiMax=-1e9,zMin=1e9,zMax=-1e9;
+    for (int ix=0;ix<2;ix++) {
+      loc[0] = (ix-0.5)*kSegm->Dx(); // +-DX/2
+      for (int iy=0;iy<2;iy++) {
+       loc[1] = (iy-0.5)*kSegm->Dy(); // +-DY/2
+       for (int iz=0;iz<2;iz++) {
+         loc[2] = (iz-0.5)*kSegm->Dz(); // +-DZ/2
+         //
+         mmod.LocalToMaster(loc,glo);
+         double phi = ATan2(glo[1],glo[0]);
+         double r   = glo[0]*glo[0] + glo[1]*glo[1];
+         if (fRMin>r) fRMin = r;
+         if (fRMax<r) fRMax = r;
+         BringTo02Pi(phi);
+         if      (phiMin>1e8) phiMin=phi; 
+         else if (!OKforPhiMin(phiMin,phi)) phiMin=phi;
+         if      (phiMax<-1e8) phiMax=phi;
+         else if (!OKforPhiMax(phiMax,phi)) phiMax=phi;              
+         if (glo[2]>zMax) zMax=glo[2];
+         if (glo[2]<zMin) zMin=glo[2];
+       }
+      }
+    }
+    mt2l = fITSGeom->GetMatrixT2L( sens->GetID() );
+    mmod.Multiply(mt2l);       
+    loc[0]=loc[1]=loc[2]=0;
+    mmod.LocalToMaster(loc,glo);
+    rTF   = Sqrt(glo[0]*glo[0] + glo[1]*glo[1]);  //  tracking params (misaligned)
+    phiTF = ATan2(glo[1],glo[0]);
+    BringTo02Pi(phiTF);
+    //
+    sens->SetXTF(rTF);
+    sens->SetPhiTF(phiTF);
+    sens->SetBoundaries(phiMin,phiMax,zMin,zMax);
+    if (fZMin>zMin) fZMin = zMin;
+    if (fZMax<zMax) fZMax = zMax;
+    //
+    if (sensI<fNSensorsPerRow) fPhiOffs += MeanPhiSmall(phiMax,phiMin);
+  }
+  //
+  fPhiOffs /= fNSensorsPerRow; // average phi of the 1st row
+  fSensDZInv = fNSensorsPerRow/(fZMax-fZMin);
+  fSensDPhiInv = fNSensorRows/(2*Pi());
   //
   fRMin = Sqrt(fRMin);
   fRMax = Sqrt(fRMax);
   fR = 0.5*(fRMin+fRMax);
   fRMin -= kSafeR;
   fRMax += kSafeR;
-  double dz = fNSensInStave>0 ? fSensDZInv/(fNSensInStave-1)/fNStaves : fZMax-fZMin;
-  fSensDZInv = 1./dz;
-
-  const int kNBId[3][3] = { 
-    {AliITSURecoSens::kNghbBL,AliITSURecoSens::kNghbB,AliITSURecoSens::kNghbBR},
-    {AliITSURecoSens::kNghbL,          -1            ,AliITSURecoSens::kNghbR },
-    {AliITSURecoSens::kNghbTL,AliITSURecoSens::kNghbT,AliITSURecoSens::kNghbTR}
-  };
-
-  // add neighbours info
-  double zTol = 0.45*dz, phiTol = 0.45*TwoPi()/fNStaves;
-  for (int ild=0;ild<fNStaves;ild++) {
-    for (int idt=0;idt<fNSensInStave;idt++) {
-      AliITSURecoSens* sens = GetSensor(ild,idt);
-      //
-      for (int ils=-1;ils<=1;ils++) {
-       int ildN = ild+ils;  // staves of neighbouring sensors
-       if (ildN<0) ildN = fNStaves-1; else if (ildN==fNStaves) ildN = 0;
-       for (int ids=-1;ids<=1;ids++) {
-         int idtN = idt+ids;
-         if (idtN<0 || idtN==fNSensInStave || (ids==0&&ils==0)) continue;
-         AliITSURecoSens* sensN = GetSensor(ildN,idtN); // potential neighbor
-         int neighbID = ildN*fNSensInStave+idtN;
-         //      
-         int zType = 1;  // side
-         if (sens->GetZMin()-zTol  > sensN->GetZMax()) continue; // too large distance
-         if (sensN->GetZMin()-zTol > sens->GetZMax() ) continue; // too large distance
-         if      (sens->GetZMin()-zTol>sensN->GetZMin()) zType =  0;     // bottom
-         else if (sensN->GetZMin()-zTol>sens->GetZMin()) zType =  2;     // top
-         //
-         int phiType = 1;
-
-         double phiTstMn = sensN->GetPhiMin()-phiTol;
-         BringTo02Pi(phiTstMn);
-         if (!OKforPhiMax(sens->GetPhiMax(),phiTstMn)) continue; // too large angle      
-         double phiTstMx = sensN->GetPhiMax()+phiTol;    
-         BringTo02Pi(phiTstMx);
-         if (!OKforPhiMin(sens->GetPhiMin(),phiTstMx)) continue; // too large angle
-         //
-         phiTstMn = sensN->GetPhiMin()+phiTol;
-         BringTo02Pi(phiTstMn);
-         phiTstMx = sensN->GetPhiMax()-phiTol;   
-         BringTo02Pi(phiTstMx);
-         if      (!OKforPhiMax(sens->GetPhiMax(),phiTstMx)) phiType = 0; // left
-         else if (!OKforPhiMin(sens->GetPhiMin(),phiTstMn)) phiType = 2; // right
-         //
-         sens->SetNeighborID(kNBId[zType][phiType], neighbID);
-       } // phi scan
-      } // z scan
-    } // sensors
-  } // staves
   //
 }
 
 //______________________________________________________
-Int_t AliITSURecoLayer::FindSensors(const double* impPar, AliITSURecoSens *sensors[AliITSURecoSens::kNNeighbors])
+Int_t AliITSURecoLayer::FindSensors(const double* impPar, AliITSURecoSens *sensors[kNNeighbors])
 {
   // find sensors having intersection with track
   // impPar contains: lab phi of track, dphi, labZ, dz
   //
+  return 0;
+  /*
   double z = impPar[2];
   if (z>fZMax+impPar[3]) return 0; // outside of Z coverage
   z -= fZMin;
   if (z<-impPar[3]) return 0; // outside of Z coverage
-  int sensInSta = int(z*fSensDZInv);
-  if      (sensInSta<0) sensInSta = 0;
-  else if (sensInSta>=fNSensInStave) sensInSta = fNSensInStave-1;
+  int sensInRow = int(z*fSensDZInv);
+  if      (sensInRow<0) sensInRow = 0;
+  else if (sensInRow>=fNSensorsPerRow) sensInRow = fNSensorsPerRow-1;
   //
   double phi = impPar[0] - fPhiOffs;
   BringTo02Pi(phi);
-  int staID = int(phi*fDPhiStaInv);  // stave id
+  int rowID = int(phi*fSensDPhiInv);  // stave id
+  //
+  int sensID = rowID*fNSensorsPerRow + sensInRow; // most probable candidate
   int nsens = 0;
   //
-  AliITSURecoSens* sensN,*sens = GetSensor(staID*fNSensInStave+sensInSta);
+  AliITSURecoSens* sensN,*sens = GetSensor(sesnID);
+  //
+  int res = sens->CheckCoverage(impPar);
+
+  // make sure this is best matching sensor
+  if (sens->GetZMin()<impPar[2] && sens->GetZMax()>impPar[2] && 
+      OKforPhiMin(sens->GetPhiMin(),impPar[0]) && OKforPhiMax(sens->GetPhiMax(),impPar[0]) ) 
+
   sensors[nsens++] = sens;
   //
   // check neighbours
@@ -273,7 +268,9 @@ Int_t AliITSURecoLayer::FindSensors(const double* impPar, AliITSURecoSens *senso
   if (sensN && OKforPhiMin(phiMn,sensN->GetPhiMax()) && sensN->GetZMax()>zMn) sensors[nsens++] = sensN;
   //
   return nsens;
+  */
 }
+
 //*/
 /*
 Int_t AliITSURecoLayer::FindSensors(const double* impPar, AliITSURecoSens *sensors[AliITSURecoSens::kNNeighbors],int mcLab)
@@ -320,7 +317,7 @@ Int_t AliITSURecoLayer::FindSensors(const double* impPar, AliITSURecoSens *senso
   //
   double phi = impPar[0] - fPhiOffs;
   BringTo02Pi(phi);
-  int staID = int(phi*fDPhiStaInv);  // stave id
+  int staID = int(phi*fSensDPhiInv);  // stave id
   int nsens = 0;
   //
   AliITSURecoSens* sensN,*sens = GetSensor(staID*fNSensInStave+sensInSta);
@@ -425,5 +422,5 @@ AliITSURecoSens* AliITSURecoLayer::GetSensorFromID(Int_t i) const
   // get sensor from its global id
   i -= fITSGeom->GetFirstChipIndex(fActiveID);
   if (i<0||i>=fNSensors) AliFatal(Form("Sensor with id=%d is not in layer %d",i+fITSGeom->GetFirstChipIndex(fActiveID),fActiveID));
-  return (AliITSURecoSens*)fSensors[i];
+  return GetSensor(SensVIDtoMatrixID(i));
 }
index 23e933765fc48790001e145018bda512042b2b9e..7ac5c87d03d94d1ab178a4c93018ccd04ec2b053 100644 (file)
@@ -22,6 +22,8 @@ class AliCluster;
 class AliITSURecoLayer : public TNamed
 {
  public:
+  //
+  enum {kNghbR,kNghbTR,kNghbT,kNghbTL,kNghbL,kNghbBL,kNghbB,kNghbBR,kNNeighbors}; // neighbors: Top,Left etc
   //
   enum {kPassive=BIT(14)                 // layer is passive
        ,kOwnsClusterArray=BIT(15)       // owner of cluster array, delete in destructor
@@ -35,8 +37,8 @@ class AliITSURecoLayer : public TNamed
   Int_t              GetID()                       const {return (int)GetUniqueID();}
   Int_t              GetActiveID()                 const {return fActiveID;}
   Int_t              GetNSensors()                 const {return fNSensors;}
-  Int_t              GetNStaves()                 const {return fNStaves;}
-  Int_t              GetNSensInStave()            const {return fNSensInStave;}
+  Int_t              GetNSensorRows()              const {return fNSensorRows;}
+  Int_t              GetNSensorsPerRow()           const {return fNSensorsPerRow;}
   Double_t           GetRMin()                     const {return fRMin;}
   Double_t           GetRMax()                     const {return fRMax;}
   Double_t           GetDR()                       const {return fRMax-fRMin;}
@@ -60,8 +62,9 @@ class AliITSURecoLayer : public TNamed
   void               SetOwnsClusterArray(Bool_t v=kTRUE) {SetBit(kOwnsClusterArray,v);}
   void               SetMaxStep(Double_t st)             {fMaxStep = st>0 ? st : 0.1;}
   //
-  AliITSURecoSens*   GetSensor(Int_t i)            const {return i<0 ? 0:(AliITSURecoSens*)fSensors[i];}
-  AliITSURecoSens*   GetSensor(Int_t ld,Int_t is)  const {return GetSensor(ld*fNSensInStave+is);}
+  AliITSURecoSens*   GetSensor(Int_t i)            const {return (AliITSURecoSens*)fSensors->UncheckedAt(i);}
+  AliITSURecoSens*   GetSensor(Int_t row,Int_t sinrow)  const {return GetSensor(sinrow+row*fNSensorsPerRow);}
+  //
   AliITSURecoSens*   GetSensorFromID(Int_t i)      const;
   TClonesArray*      GetClusters()                 const {return (TClonesArray*)fClusters;}
   TClonesArray**     GetClustersAddress()                {return (TClonesArray**)&fClusters;}  
@@ -70,7 +73,7 @@ class AliITSURecoLayer : public TNamed
   void               SetClusters(TClonesArray* cl)       {fClusters = cl;}
   //
   //  Int_t              FindSensors(const double* impPar, AliITSURecoSens *sensors[AliITSURecoSens::kNNeighbors], int mcLab=-1);
-  Int_t              FindSensors(const double* impPar, AliITSURecoSens *sensors[AliITSURecoSens::kNNeighbors]);
+  Int_t              FindSensors(const double* impPar, AliITSURecoSens *sensors[kNNeighbors]);
   //
   virtual void       Print(Option_t* option = "")  const;
   virtual Bool_t     IsSortable()                  const {return kTRUE;}
@@ -79,24 +82,24 @@ class AliITSURecoLayer : public TNamed
   //
  protected:
   void               Build();
+  Int_t              SensVIDtoMatrixID(Int_t i)    const {return fSensVIDtoMatrixID[i];}
   //
  protected:
   Int_t              fActiveID;  // ID within active layers
   Int_t              fNSensors;  // N of chips
-  Int_t              fNSensInStave; // N sensors in the stave
-  Int_t              fNStaves;  // N stave
+  Int_t              fNSensorRows; // N of sensor rows (sensors aligned at same phi and spanning the Z range of the layer)
+  Int_t              fNSensorsPerRow; // number of sensors in a row
+  Int_t*             fSensVIDtoMatrixID; //[fNSensors]
   Double_t           fR;         // mean R
   Double_t           fRMax;      // max  R
   Double_t           fRMin;      // min  R
   Double_t           fZMax;      // max  Z
   Double_t           fZMin;      // min  Z
-  Double_t*          fPhiStaMax; // max lab phi of the stave
-  Double_t*          fPhiStaMin; // min lab phi of the stave
   Double_t           fPhiOffs;   // offset in phi for 1st stave
   Double_t           fSensDZInv; // inverse mean sensor Z span
-  Double_t           fDPhiStaInv;// inverse mean stave dphi
+  Double_t           fSensDPhiInv;// inverse mean sensor dphi
   Double_t           fMaxStep;   // max step in tracking X allowed within layer
-  AliITSURecoSens**  fSensors;   // sensors
+  TObjArray*         fSensors;   // sensors
   AliITSUGeomTGeo*   fITSGeom;   // geometry interface
   TClonesArray*      fClusters;  // clusters of the layer
   //
index a8770bb986a8be38f2f984be3a04e4b7bc525df1..aa132bbedb29f0ebd5dbbc1228c2914d37f1032c 100644 (file)
@@ -2,6 +2,11 @@
 #include "AliITSUGeomTGeo.h"
 #include "AliITSsegmentation.h"
 #include "AliExternalTrackParam.h"
+#include "AliITSUAux.h"
+#include "AliLog.h"
+
+using namespace AliITSUAux;
+using namespace TMath;
 
 ClassImp(AliITSURecoSens)
 
@@ -18,7 +23,6 @@ AliITSURecoSens::AliITSURecoSens(Int_t id)
 {
   // def. c-tor
   SetID(id);
-  for (int i=kNNeighbors;i--;) fNeighbors[i] = -1;
 }
 
 //______________________________________________________
@@ -34,7 +38,6 @@ AliITSURecoSens::AliITSURecoSens(const AliITSURecoSens &source)
   ,fZMax(source.fZMax)
 {
   // copy c-tor
-  for (int i=kNNeighbors;i--;) fNeighbors[i] = source.fNeighbors[i];
 }
 
 //______________________________________________________
@@ -52,7 +55,6 @@ AliITSURecoSens& AliITSURecoSens::operator=(const AliITSURecoSens &source)
   fZMin   = source.fZMin;
   fZMax   = source.fZMax;
   //
-  for (int i=kNNeighbors;i--;) fNeighbors[i] = source.fNeighbors[i];
   return *this;
 }
 
@@ -70,9 +72,8 @@ void AliITSURecoSens::SetBoundaries(double phiMn,double phiMx, double zMn, doubl
 void AliITSURecoSens::Print(Option_t*) const                         
 {
   //print 
-  printf("Sensor%4d xTF=%+.3e phiTF=%+.3e | Phi:[%5.3f:%5.3f] Z:[%+7.3f:%+7.3f]| Neighb.:",
+  printf("Sensor%4d xTF=%+.3e phiTF=%+.3e | Phi:[%5.3f:%5.3f] Z:[%+7.3f:%+7.3f]\n",
         GetID(),GetXTF(),GetPhiTF(), fPhiMin,fPhiMax, fZMin,fZMax);
-  for (int i=0;i<kNNeighbors;i++) printf(" %4d",fNeighbors[i]); printf("\n");
 }
 
 //______________________________________________________
@@ -90,3 +91,52 @@ void AliITSURecoSens::ProcessClusters(Int_t)
   //
   // to do
 }
+
+//______________________________________________________________________________
+Int_t AliITSURecoSens::Compare(const TObject* obj)  const
+{
+  // compare sensor positions
+  AliITSURecoSens* copy = (AliITSURecoSens*)obj;
+  double phi  = MeanPhiSmall(fPhiMin,fPhiMax);
+  double phiC = MeanPhiSmall(copy->fPhiMin,copy->fPhiMax);
+  double span = DeltaPhiSmall(fPhiMin,fPhiMax)/2;
+  double dPhi = DeltaPhiSmall(phi,phiC);
+  //
+  // special case to well define 1st raw (closest to 0 from above): wrap around 0/2pi
+  if (dPhi>span) return phi<phiC ? -1 : 1;
+  //
+  double phiT = phi+span;
+  BringTo02Pi(phiT);
+  //  if (phiT<phiC && OKforPhiMin(phiT,phiC)) return -1;
+  if (OKforPhiMin(phiT,phiC)) return -1;
+  phiT = phi-span;
+  BringTo02Pi(phiT);
+  //if (phiT>phiC && OKforPhiMax( phiT,phiC)) return 1;
+  if (OKforPhiMax( phiT,phiC)) return 1;
+  //
+  // sane phi range, check Z
+  double dz = (fZMax-fZMin)/2;
+  if (fZMax+dz < copy->fZMax) return -1;
+  if (fZMin-dz > copy->fZMin) return 1;
+  AliError(Form("Same chip compared? %d %d",GetID(),copy->GetID()));
+  Print();
+  copy->Print();
+  return 0;
+  //
+}
+
+//______________________________________________________________________________
+Int_t AliITSURecoSens::CheckCoverage(const double* impPar) const
+{
+  // check if the sensor contains the impact point (phi,dphi,z,dz)
+  // if not, tell in which direction to move. 
+  // kLeft, kRight are for smaller/larger angles, kUp,kDown for larger/smaller Z
+  //
+  int res = 0;
+  if      (impPar[2]<fZMin) res |= kDown;
+  else if (impPar[2]>fZMax) res |= kUp;
+  //
+  if      (!OKforPhiMin(fPhiMin,impPar[0])) res |= kLeft;
+  else if (!OKforPhiMax(fPhiMax,impPar[0])) res |= kRight;
+  return res;
+}
index 56ed68232fc05d31b26fa7988ce5ed0762c91a70..a54caf44bb4aab0e84c38a3a0363b35ad4db68b7 100644 (file)
@@ -14,7 +14,8 @@
 class AliITSURecoSens : public TObject
 {
  public:
-  enum {kNghbR,kNghbTR,kNghbT,kNghbTL,kNghbL,kNghbBL,kNghbB,kNghbBR,kNNeighbors}; // neighbors: Top,Left etc
+  //
+  enum {kLeft=BIT(1),kRight=BIT(2),kUp=BIT(3),kDown=BIT(4)};
   //
   AliITSURecoSens(Int_t id);
   AliITSURecoSens(const AliITSURecoSens &source); 
@@ -22,6 +23,7 @@ class AliITSURecoSens : public TObject
   AliITSURecoSens& operator=(const AliITSURecoSens &source); 
   //
   Int_t              GetID()                       const {return (int)GetUniqueID();}
+  Int_t              CheckCoverage(const double* impPar) const;
   Double_t           GetXTF()                      const {return fXTF;}
   Double_t           GetPhiTF()                    const {return fPhiTF;}
   Double_t           GetPhiMin()                   const {return fPhiMin;}
@@ -29,15 +31,12 @@ class AliITSURecoSens : public TObject
   Double_t           GetZMin()                     const {return fZMin;}
   Double_t           GetZMax()                     const {return fZMax;}
   //
-  Int_t              GetNeighborID(int i)          const {return fNeighbors[i];}
-  //
   Int_t              GetNClusters()                const {return fNClusters;}
   Int_t              GetFirstClusterId()           const {return fFirstClusterId;}
   //
   void               SetID(Int_t i)                      {SetUniqueID(i);}
   void               SetXTF(double v)                    {fXTF = v;}
   void               SetPhiTF(double v)                  {fPhiTF = v;}
-  void               SetNeighborID(int i, int id)        {fNeighbors[i] = id;}
   void               SetBoundaries(double phiMn,double phiMx, double zMn, double zMx);
   //
   void               SetNClusters(Int_t ncl)             {fNClusters = ncl;}
@@ -47,9 +46,12 @@ class AliITSURecoSens : public TObject
   void               ProcessClusters(Int_t mode=0);
   //
   virtual void       Print(Option_t* option = "")  const;
-
+  //
+  virtual Bool_t     IsSortable()                 const {return kTRUE;}
+  virtual Int_t             Compare(const TObject* obj)  const;
+  virtual Bool_t     IsEqual(const TObject* obj)  const {return Compare(obj)==0;}
+  //
  protected:
-  Int_t              fNeighbors[kNNeighbors];      // id of neighbors  
   Int_t              fNClusters;                   // number of clusters
   Int_t              fFirstClusterId;              // index of the 1st cluster in the layer's clusters array
   Double_t           fXTF;                         // X in tracking frame
index 51bfc81c8fcc19bf79b7ac93f7fecad36528b9ba..ac51a7cc9d88c7ea5fee30e144d44ad01796298e 100644 (file)
@@ -507,7 +507,7 @@ void AliITSUTrackerGlo::FindTrack(AliESDtrack* esdTr, Int_t esdID)
   fCurrHyp = fWorkHyp;
   fCurrHyp->InitFrom(hypTr);
   //
-  AliITSURecoSens *hitSens[AliITSURecoSens::kNNeighbors+1];
+  AliITSURecoSens *hitSens[AliITSURecoLayer::kNNeighbors+1];
   //
   int ilaUp = fNLrActive;     // previous active layer really checked (some may be excluded!)
   //
index 5747e1cd01dd438015c5671d830d1d6936daedff..d8fa4c13ea891a7469ee06ed86205aa4d05def76 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 0f201e4705e7917806e42e1bca8faa3f82de3f23..877c690feaaa691e3f015906ee9a1a3cc45cfc67 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 77fa195b92cb338f7a58324c2006ab3cce0290bd..e2af53cbbef9ba8c4f7cdcccccfb6c70468c1cce 100644 (file)
@@ -65,15 +65,16 @@ AliITSUv1::AliITSUv1()
   ,fWrapRMin(0)
   ,fWrapRMax(0)
   ,fWrapZSpan(0)
+  ,fLay2WrapV(0)
   ,fLayTurbo(0)
   ,fLayPhi0(0)
   ,fLayRadii(0)
   ,fLayZLength(0)
   ,fStavPerLay(0)
-  ,fModPerStav(0)
-  ,fStaThick(0)
-  ,fStaWidth(0)
-  ,fStaTilt(0)
+  ,fUnitPerStave(0)
+  ,fStaveThick(0)
+  ,fStaveWidth(0)
+  ,fStaveTilt(0)
   ,fDetThick(0)
   ,fChipTypeID(0)
   ,fBuildLevel(0)
@@ -97,15 +98,16 @@ AliITSUv1::AliITSUv1(const char *title,const Int_t nlay)
   ,fWrapRMin(0)
   ,fWrapRMax(0)
   ,fWrapZSpan(0)
+  ,fLay2WrapV(0)
   ,fLayTurbo(0)
   ,fLayPhi0(0)
   ,fLayRadii(0)
   ,fLayZLength(0)
   ,fStavPerLay(0)
-  ,fModPerStav(0)
-  ,fStaThick(0)
-  ,fStaWidth(0)
-  ,fStaTilt(0)
+  ,fUnitPerStave(0)
+  ,fStaveThick(0)
+  ,fStaveWidth(0)
+  ,fStaveTilt(0)
   ,fDetThick(0)
   ,fChipTypeID(0)
   ,fBuildLevel(0)
@@ -124,34 +126,34 @@ AliITSUv1::AliITSUv1(const char *title,const Int_t nlay)
   for (Int_t j=0; j<fNLayers; j++)
     fLayerName[j].Form("%s%d",AliITSUGeomTGeo::GetITSSensorPattern(),j); // See AliITSUv1Layer
   //
-  fLayTurbo   = new Bool_t[fNLayers];
-  fLayPhi0    = new Double_t[fNLayers];
-  fLayRadii   = new Double_t[fNLayers];
-  fLayZLength = new Double_t[fNLayers];
-  fStavPerLay = new Int_t[fNLayers];
-  fModPerStav = new Int_t[fNLayers];
-  fStaThick   = new Double_t[fNLayers];
-  fStaWidth   = new Double_t[fNLayers];
-  fStaTilt    = new Double_t[fNLayers];
-  fDetThick   = new Double_t[fNLayers];
-  fChipTypeID  = new UInt_t[fNLayers];
-  fBuildLevel = new Int_t[fNLayers];
+  fLayTurbo     = new Bool_t[fNLayers];
+  fLayPhi0      = new Double_t[fNLayers];
+  fLayRadii     = new Double_t[fNLayers];
+  fLayZLength   = new Double_t[fNLayers];
+  fStavPerLay   = new Int_t[fNLayers];
+  fUnitPerStave = new Int_t[fNLayers];
+  fStaveThick   = new Double_t[fNLayers];
+  fStaveWidth   = new Double_t[fNLayers];
+  fStaveTilt    = new Double_t[fNLayers];
+  fDetThick     = new Double_t[fNLayers];
+  fChipTypeID   = new UInt_t[fNLayers];
+  fBuildLevel   = new Int_t[fNLayers];
 
 
   fUpGeom = new AliITSUv1Layer*[fNLayers];
   
   if (fNLayers > 0) { // if not, we'll Fatal-ize in CreateGeometry
     for (Int_t j=0; j<fNLayers; j++) {
-      fLayPhi0[j] = 0;
-      fLayRadii[j] = 0.;
-      fLayZLength[j] = 0.;
-      fStavPerLay[j] = 0;
-      fModPerStav[j] = 0;
-      fStaWidth[j] = 0.;
-      fDetThick[j] = 0.;
-      fChipTypeID[j] = 0;
-      fBuildLevel[j] = 0;
-      fUpGeom[j] = 0;     
+      fLayPhi0[j]      = 0;
+      fLayRadii[j]     = 0.;
+      fLayZLength[j]   = 0.;
+      fStavPerLay[j]   = 0;
+      fUnitPerStave[j] = 0;
+      fStaveWidth[j]   = 0.;
+      fDetThick[j]     = 0.;
+      fChipTypeID[j]   = 0;
+      fBuildLevel[j]   = 0;
+      fUpGeom[j]       = 0;
     }
   }
 }
@@ -170,10 +172,10 @@ AliITSUv1::~AliITSUv1() {
   delete [] fLayRadii;
   delete [] fLayZLength;
   delete [] fStavPerLay;
-  delete [] fModPerStav;
-  delete [] fStaThick;
-  delete [] fStaWidth;
-  delete [] fStaTilt;
+  delete [] fUnitPerStave;
+  delete [] fStaveThick;
+  delete [] fStaveWidth;
+  delete [] fStaveTilt;
   delete [] fDetThick;
   delete [] fChipTypeID;
   delete [] fBuildLevel;
@@ -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<fModPerStav[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));
+  //
 }
 
 //______________________________________________________________________
@@ -287,21 +351,21 @@ void AliITSUv1::CreateGeometry() {
   if (fNLayers <= 0) AliFatal(Form("Wrong number of layers (%d)",fNLayers));
   //
   for (Int_t j=0; j<fNLayers; j++) {
-    if (fLayRadii[j] <= 0)                 AliFatal(Form("Wrong layer radius for layer %d (%f)",j,fLayRadii[j]));
-    if (fLayZLength[j] <= 0)               AliFatal(Form("Wrong layer length for layer %d (%f)",j,fLayZLength[j]));
-    if (fStavPerLay[j] <= 0)               AliFatal(Form("Wrong number of staves for layer %d (%d)",j,fStavPerLay[j]));
-    if (fModPerStav[j] <= 0)               AliFatal(Form("Wrong number of chips for layer %d (%d)",j,fModPerStav[j]));
-    if (fStaThick[j] < 0)                  AliFatal(Form("Wrong stave thickness for layer %d (%f)",j,fStaThick[j]));
-    if (fLayTurbo[j] && fStaWidth[j] <= 0) AliFatal(Form("Wrong stave width for layer %d (%f)",j,fStaWidth[j]));
-    if (fDetThick[j] < 0)                  AliFatal(Form("Wrong chip thickness for layer %d (%f)",j,fDetThick[j]));
+    if (fLayRadii[j] <= 0)                   AliFatal(Form("Wrong layer radius for layer %d (%f)",j,fLayRadii[j]));
+    if (fLayZLength[j] <= 0)                 AliFatal(Form("Wrong layer length for layer %d (%f)",j,fLayZLength[j]));
+    if (fStavPerLay[j] <= 0)                 AliFatal(Form("Wrong number of staves for layer %d (%d)",j,fStavPerLay[j]));
+    if (fUnitPerStave[j] <= 0)               AliFatal(Form("Wrong number of chips for layer %d (%d)",j,fUnitPerStave[j]));
+    if (fStaveThick[j] < 0)                  AliFatal(Form("Wrong stave thickness for layer %d (%f)",j,fStaveThick[j]));
+    if (fLayTurbo[j] && fStaveWidth[j] <= 0) AliFatal(Form("Wrong stave width for layer %d (%f)",j,fStaveWidth[j]));
+    if (fDetThick[j] < 0)                    AliFatal(Form("Wrong chip thickness for layer %d (%f)",j,fDetThick[j]));
     //
     if (j > 0) {
-      if (fLayRadii[j]<=fLayRadii[j-1])    AliFatal(Form("Layer %d radius (%f) is smaller than layer %d radius (%f)",
-                                                        j,fLayRadii[j],j-1,fLayRadii[j-1]));
+      if (fLayRadii[j]<=fLayRadii[j-1])      AliFatal(Form("Layer %d radius (%f) is smaller than layer %d radius (%f)",
+                          j,fLayRadii[j],j-1,fLayRadii[j-1]));
     } // if (j > 0)
 
-    if (fStaThick[j] == 0) AliInfo(Form("Stave thickness for layer %d not set, using default",j));
-    if (fDetThick[j] == 0) AliInfo(Form("Chip thickness for layer %d not set, using default",j));
+    if (fStaveThick[j] == 0) AliInfo(Form("Stave thickness for layer %d not set, using default",j));
+    if (fDetThick[j]   == 0) AliInfo(Form("Chip thickness for layer %d not set, using default",j));
 
   } // for (Int_t j=0; j<fNLayers; j++)
 
@@ -315,14 +379,17 @@ 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);
-      fUpGeom[j]->SetStaveWidth(fStaWidth[j]);
-      fUpGeom[j]->SetStaveTilt(fStaTilt[j]);
+      fUpGeom[j]->SetStaveWidth(fStaveWidth[j]);
+      fUpGeom[j]->SetStaveTilt(fStaveTilt[j]);
     }
     else fUpGeom[j] = new AliITSUv1Layer(j,kFALSE);
     //
@@ -330,7 +397,7 @@ void AliITSUv1::CreateGeometry() {
     fUpGeom[j]->SetRadius(fLayRadii[j]);
     fUpGeom[j]->SetZLength(fLayZLength[j]);
     fUpGeom[j]->SetNStaves(fStavPerLay[j]);
-    fUpGeom[j]->SetNChips(fModPerStav[j]);
+    fUpGeom[j]->SetNUnits(fUnitPerStave[j]);
     fUpGeom[j]->SetChipType(fChipTypeID[j]);
     fUpGeom[j]->SetBuildLevel(fBuildLevel[j]);
     if (j < 3)
@@ -339,8 +406,8 @@ void AliITSUv1::CreateGeometry() {
       fUpGeom[j]->SetStaveModel(fStaveModelOB);
     AliDebug(1,Form("fBuildLevel: %d\n",fBuildLevel[j]));
     //
-    if (fStaThick[j] != 0) fUpGeom[j]->SetStaveThick(fStaThick[j]);
-    if (fDetThick[j] != 0) fUpGeom[j]->SetSensorThick(fDetThick[j]);
+    if (fStaveThick[j] != 0) fUpGeom[j]->SetStaveThick(fStaveThick[j]);
+    if (fDetThick[j]   != 0) fUpGeom[j]->SetSensorThick(fDetThick[j]);
     //
     for (int iw=0;iw<fNWrapVol;iw++) {
       if (fLayRadii[j]>fWrapRMin[iw] && fLayRadii[j]<fWrapRMax[iw]) {
@@ -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;
       }
     }
@@ -487,7 +555,7 @@ void AliITSUv1::CreateMaterials() {
 //______________________________________________________________________
 void AliITSUv1::DefineLayer(const Int_t nlay, const double phi0, const Double_t r,
                            const Double_t zlen, const Int_t nstav,
-                           const Int_t nmod, const Double_t lthick,
+                           const Int_t nunit, const Double_t lthick,
                            const Double_t dthick, const UInt_t dettypeID,
                            const Int_t buildLevel)
 {
@@ -498,9 +566,11 @@ void AliITSUv1::DefineLayer(const Int_t nlay, const double phi0, const Double_t
   //          r       layer radius
   //          zlen    layer length
   //          nstav   number of staves
-  //          nmod    number of chips per stave
+  //          nunit   IB: number of chips per stave
+  //                  OB: number of modules per half stave
   //          lthick  stave thickness (if omitted, defaults to 0)
   //          dthick  detector thickness (if omitted, defaults to 0)
+  //          dettypeID  ??
   //          buildLevel (if 0, all geometry is build, used for material budget studies)
   // Outputs:
   //   none.
@@ -517,8 +587,8 @@ void AliITSUv1::DefineLayer(const Int_t nlay, const double phi0, const Double_t
   fLayRadii[nlay] = r;
   fLayZLength[nlay] = zlen;
   fStavPerLay[nlay] = nstav;
-  fModPerStav[nlay] = nmod;
-  fStaThick[nlay] = lthick;
+  fUnitPerStave[nlay] = nunit;
+  fStaveThick[nlay] = lthick;
   fDetThick[nlay] = dthick;
   fChipTypeID[nlay] = dettypeID;
   fBuildLevel[nlay] = buildLevel;
@@ -527,7 +597,7 @@ void AliITSUv1::DefineLayer(const Int_t nlay, const double phi0, const Double_t
 
 //______________________________________________________________________
 void AliITSUv1::DefineLayerTurbo(Int_t nlay, Double_t phi0, Double_t r, Double_t zlen, Int_t nstav,
-                                Int_t nmod, Double_t width, Double_t tilt,
+                                Int_t nunit, Double_t width, Double_t tilt,
                                 Double_t lthick,Double_t dthick,
                                 UInt_t dettypeID, Int_t buildLevel)
 {
@@ -539,7 +609,8 @@ void AliITSUv1::DefineLayerTurbo(Int_t nlay, Double_t phi0, Double_t r, Double_t
   //          r       layer radius
   //          zlen    layer length
   //          nstav   number of staves
-  //          nmod    number of chips per stave
+  //          nunit   IB: number of chips per stave
+  //                  OB: number of modules per half stave
   //          width   stave width
   //          tilt    layer tilt angle (degrees)
   //          lthick  stave thickness (if omitted, defaults to 0)
@@ -561,10 +632,10 @@ void AliITSUv1::DefineLayerTurbo(Int_t nlay, Double_t phi0, Double_t r, Double_t
   fLayRadii[nlay] = r;
   fLayZLength[nlay] = zlen;
   fStavPerLay[nlay] = nstav;
-  fModPerStav[nlay] = nmod;
-  fStaThick[nlay] = lthick;
-  fStaWidth[nlay] = width;
-  fStaTilt[nlay] = tilt;
+  fUnitPerStave[nlay] = nunit;
+  fStaveThick[nlay] = lthick;
+  fStaveWidth[nlay] = width;
+  fStaveTilt[nlay] = tilt;
   fDetThick[nlay] = dthick;
   fChipTypeID[nlay] = dettypeID;
   fBuildLevel[nlay] = buildLevel;
@@ -587,7 +658,8 @@ void AliITSUv1::GetLayerParameters(Int_t nlay, Double_t &phi0,
   //          r       layer radius
   //          zlen    layer length
   //          nstav   number of staves
-  //          nmod    number of chips per stave
+  //          nmod    IB: number of chips per stave
+  //                  OB: number of modules per half stave
   //          width   stave width
   //          tilt    stave tilt angle
   //          lthick  stave thickness
@@ -605,10 +677,10 @@ void AliITSUv1::GetLayerParameters(Int_t nlay, Double_t &phi0,
   r      = fLayRadii[nlay];
   zlen   = fLayZLength[nlay];
   nstav  = fStavPerLay[nlay];
-  nmod   = fModPerStav[nlay];
-  width  = fStaWidth[nlay];
-  tilt   = fStaTilt[nlay];
-  lthick = fStaThick[nlay];
+  nmod   = fUnitPerStave[nlay];
+  width  = fStaveWidth[nlay];
+  tilt   = fStaveTilt[nlay];
+  lthick = fStaveThick[nlay];
   dthick = fDetThick[nlay];
   dettype= fChipTypeID[nlay];
 }
@@ -679,6 +751,7 @@ void AliITSUv1::StepManager()
   //   none.
   // Return:
   //   none.
+  //
   if(!(this->IsActive())) return;
   if(!(gMC->TrackCharge())) return;
   //
@@ -690,44 +763,43 @@ void AliITSUv1::StepManager()
   //printf("R: %.1f | Lay: %d  NotSens: %d\n",positionRS.Pt(), lay, notSens);
           
   if (notSens) return;
-
-  if(gMC->IsTrackExiting()) {
-    AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber(), AliTrackReference::kITS);
-  } // if Outer ITS mother Volume
-
+  //
+  if (lay < 0 || lay >= fNLayers) {
+    AliError(Form("Invalid value: lay=%d. Not an ITS sensitive volume",lay));
+    return; // not an ITS sensitive volume.
+  } 
+  //
   static TLorentzVector position, momentum; // Saves on calls to construtors
   static AliITSUHit hit;// Saves on calls to constructors
-
+  //
   TClonesArray &lhits = *(Hits());
-  Int_t   cpn0, cpn1, mod, status = 0;
+  Int_t chipID, status = 0;
   //
   // Track status
   if(gMC->IsTrackInside())      status +=  1;
   if(gMC->IsTrackEntering())    status +=  2;
-  if(gMC->IsTrackExiting())     status +=  4;
+  if(gMC->IsTrackExiting()) {
+    AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber(), AliTrackReference::kITS);
+    status +=  4;
+  } // if Outer ITS mother Volume
   if(gMC->IsTrackOut())         status +=  8;
   if(gMC->IsTrackDisappeared()) status += 16;
   if(gMC->IsTrackStop())        status += 32;
   if(gMC->IsTrackAlive())       status += 64;
-
   //
   // retrieve the indices with the volume path
   //
-  if (lay < 0 || lay >= fNLayers) {
-    AliError(Form("Invalid value: lay=%d. Not an ITS sensitive volume",lay));
-    return; // not an ITS sensitive volume.
-  } else {
-    copy = 1;
-    gMC->CurrentVolOffID(1,cpn1);
-    gMC->CurrentVolOffID(2,cpn0);
-  } //
-
-  mod = fGeomTGeo->GetChipIndex(lay,cpn0,cpn1);
-  //RS2DEL  fInitGeom.DecodeDetector(mod,lay+1,cpn0,cpn1,copy);
+  gMC->TrackPosition(position);
+  int chip=-1,module=-1,sstave=-1,stave=-1,level=0; // volume copies on different levels
+  gMC->CurrentVolOffID(++level,chip);
+  if (fGeomTGeo->GetNModules(lay)>0)    gMC->CurrentVolOffID(++level,module);
+  if (fGeomTGeo->GetNHalfStaves(lay)>0) gMC->CurrentVolOffID(++level,sstave);
+  gMC->CurrentVolOffID(++level,stave);
   //
+  chipID = fGeomTGeo->GetChipIndex(lay,stave,sstave,module,chip);
   // Fill hit structure.
   //
-  hit.SetChip(mod);
+  hit.SetChip(chipID);
   hit.SetTrack(gAlice->GetMCApp()->GetCurrentTrackNumber());
   gMC->TrackPosition(position);
   gMC->TrackMomentum(momentum);
index cad621988071185fb9bb7271578ff258eeb2fb00..34331d1367bb7bd64a3c5503500d1c7bffb69ead 100644 (file)
@@ -44,12 +44,18 @@ 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,
-                            Int_t nmod, Double_t lthick=0.,Double_t dthick=0.,UInt_t detType=0, Int_t buildFlag=0);
+                            Int_t nunit, Double_t lthick=0.,Double_t dthick=0.,UInt_t detType=0, Int_t buildFlag=0);
   virtual void   DefineLayerTurbo(Int_t nlay,Double_t phi0,Double_t r,Double_t zlen,Int_t nstav,
-                                 Int_t nmod,Double_t width,Double_t tilt,
+                                 Int_t nunit,Double_t width,Double_t tilt,
                                  Double_t lthick = 0.,Double_t dthick = 0.,UInt_t detType=0, Int_t buildFlag=0);
   virtual void   GetLayerParameters(Int_t nlay, Double_t &phi0,Double_t &r, Double_t &zlen,
                                    Int_t &nstav, Int_t &nmod,
@@ -80,17 +86,18 @@ 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
   Double_t *fLayZLength;     // Vector of layer length along Z
   Int_t    *fStavPerLay;     // Vector of number of staves per layer
-  Int_t    *fModPerStav;     // Vector of number of chips per stave
-  Double_t *fStaThick;       // Vector of stave thicknesses
-  Double_t *fStaWidth;       // Vector of stave width (only used for turbo)
-  Double_t *fStaTilt;        // Vector of stave tilt (only used for turbo)
+  Int_t    *fUnitPerStave;   // Vector of number of "units" per stave
+  Double_t *fStaveThick;     // Vector of stave thicknesses
+  Double_t *fStaveWidth;     // Vector of stave width (only used for turbo)
+  Double_t *fStaveTilt;      // Vector of stave tilt (only used for turbo)
   Double_t *fDetThick;       // Vector of detector thicknesses
-  UInt_t   *fChipTypeID;      // Vector of detector type id
+  UInt_t   *fChipTypeID;     // Vector of detector type id
   Int_t    *fBuildLevel;     // Vector of Material Budget Studies
   //  
   AliITSUv1Layer **fUpGeom; //! Geometry
index 966b854580335ce2eb4dc6fa1e9013ff18c2c3e7..ec0e0db16f6c5fcc357de318fc54695078ec5b3e 100644 (file)
 #include <TGeoTrd1.h>
 using namespace TMath;
 
-const Double_t AliITSUv1Layer::fgkDefaultSensorThick = 300*fgkmicron;
-const Double_t AliITSUv1Layer::fgkDefaultStaveThick =   1*fgkcm;
-
-const Double_t AliITSUv1Layer::fgkOBHalfStaveWidth   =   3.01 *fgkcm;
-const Double_t AliITSUv1Layer::fgkOBChipGap        =   0.01 *fgkcm;
-const Double_t AliITSUv1Layer::fgkOBFlexCable1Thick  =   0.005*fgkcm;
-const Double_t AliITSUv1Layer::fgkOBFlexCable2Thick  =   0.01 *fgkcm;
-const Double_t AliITSUv1Layer::fgkOBBusCable1Thick   =   0.02 *fgkcm;
-const Double_t AliITSUv1Layer::fgkOBBusCable2Thick   =   0.02 *fgkcm;
-const Double_t AliITSUv1Layer::fgkOBColdPlateThick   =   0.012*fgkcm;
-const Double_t AliITSUv1Layer::fgkOBCarbonPlateThick =   0.012*fgkcm;
-const Double_t AliITSUv1Layer::fgkOBGlueThick        =   0.03 *fgkcm;
-const Double_t AliITSUv1Layer::fgkOBChipZLength    =  21.06 *fgkcm;
+const Int_t    AliITSUv1Layer::fgkNumberOfInnerLayers =   3;
+
+const Double_t AliITSUv1Layer::fgkDefaultSensorThick  = 300*fgkmicron;
+const Double_t AliITSUv1Layer::fgkDefaultStaveThick   =   1*fgkcm;
+
+const Int_t    AliITSUv1Layer::fgkOBChipsPerRow       =   7;
+const Int_t    AliITSUv1Layer::fgkOBNChipRows         =   2;
+
+const Double_t AliITSUv1Layer::fgkOBHalfStaveWidth    =   3.01 *fgkcm;
+const Double_t AliITSUv1Layer::fgkOBModuleWidth       = fgkOBHalfStaveWidth;
+const Double_t AliITSUv1Layer::fgkOBModuleGap         =   0.01 *fgkcm;
+const Double_t AliITSUv1Layer::fgkOBChipXGap          =   0.01 *fgkcm;
+const Double_t AliITSUv1Layer::fgkOBChipZGap          =   0.01 *fgkcm;
+const Double_t AliITSUv1Layer::fgkOBFlexCableAlThick  =   0.005*fgkcm;
+const Double_t AliITSUv1Layer::fgkOBFlexCableKapThick =   0.01 *fgkcm;
+const Double_t AliITSUv1Layer::fgkOBBusCableAlThick   =   0.02 *fgkcm;
+const Double_t AliITSUv1Layer::fgkOBBusCableKapThick  =   0.02 *fgkcm;
+const Double_t AliITSUv1Layer::fgkOBColdPlateThick    =   0.012*fgkcm;
+const Double_t AliITSUv1Layer::fgkOBCarbonPlateThick  =   0.012*fgkcm;
+const Double_t AliITSUv1Layer::fgkOBGlueThick         =   0.03 *fgkcm;
+const Double_t AliITSUv1Layer::fgkOBModuleZLength     =  21.06 *fgkcm;
+const Double_t AliITSUv1Layer::fgkOBHalfStaveYTrans   =   1.76 *fgkmm;
+const Double_t AliITSUv1Layer::fgkOBHalfStaveXOverlap =   2.3  *fgkmm;
+const Double_t AliITSUv1Layer::fgkOBGraphiteFoilThick =  30.0  *fgkmicron;
+const Double_t AliITSUv1Layer::fgkOBCoolTubeInnerD    =   2.67 *fgkmm;
+const Double_t AliITSUv1Layer::fgkOBCoolTubeThick     =  64.0  *fgkmicron;
+const Double_t AliITSUv1Layer::fgkOBCoolTubeXDist     =  11.1  *fgkmm;
+
+const Double_t AliITSUv1Layer::fgkOBSpaceFrameWidth   =  42.0  *fgkmm;
+const Double_t AliITSUv1Layer::fgkOBSpaceFrameTotHigh =  43.1  *fgkmm;
+const Double_t AliITSUv1Layer::fgkOBSFrameBeamRadius  =   0.6  *fgkmm;
+const Double_t AliITSUv1Layer::fgkOBSpaceFrameLa      =   3.0  *fgkmm;
+const Double_t AliITSUv1Layer::fgkOBSpaceFrameHa      =   0.721979*fgkmm;
+const Double_t AliITSUv1Layer::fgkOBSpaceFrameLb      =   3.7  *fgkmm;
+const Double_t AliITSUv1Layer::fgkOBSpaceFrameHb      =   0.890428*fgkmm;
+const Double_t AliITSUv1Layer::fgkOBSpaceFrameL       =   0.25 *fgkmm;
+const Double_t AliITSUv1Layer::fgkOBSFBotBeamAngle    =  56.5;
+const Double_t AliITSUv1Layer::fgkOBSFrameBeamSidePhi =  65.0;
 
 
 ClassImp(AliITSUv1Layer)
@@ -75,6 +100,7 @@ AliITSUv1Layer::AliITSUv1Layer():
   fStaveWidth(0),
   fStaveTilt(0),
   fNStaves(0),
+  fNModules(0),
   fNChips(0),
   fChipTypeID(0),
   fIsTurbo(0),
@@ -83,6 +109,7 @@ AliITSUv1Layer::AliITSUv1Layer():
 {
   //
   // Standard constructor
+  for (int i=kNHLevels;i--;) fHierarchy[i] = 0;
   //
 }
 
@@ -98,6 +125,7 @@ AliITSUv1Layer::AliITSUv1Layer(Int_t debug):
   fStaveWidth(0),
   fStaveTilt(0),
   fNStaves(0),
+  fNModules(0),
   fNChips(0),
   fChipTypeID(0),
   fIsTurbo(0),
@@ -106,6 +134,7 @@ AliITSUv1Layer::AliITSUv1Layer(Int_t debug):
 {
   //
   // Constructor setting debugging level
+  for (int i=kNHLevels;i--;) fHierarchy[i] = 0;
   //
 }
 
@@ -121,6 +150,7 @@ AliITSUv1Layer::AliITSUv1Layer(Int_t lay, Int_t debug):
   fStaveWidth(0),
   fStaveTilt(0),
   fNStaves(0),
+  fNModules(0),
   fNChips(0),
   fChipTypeID(0),
   fIsTurbo(0),
@@ -129,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;
   //
 }
 
@@ -144,6 +175,7 @@ AliITSUv1Layer::AliITSUv1Layer(Int_t lay, Bool_t turbo, Int_t debug):
   fStaveWidth(0),
   fStaveTilt(0),
   fNStaves(0),
+  fNModules(0),
   fNChips(0),
   fChipTypeID(0),
   fIsTurbo(turbo),
@@ -153,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;
   //
 }
 
@@ -168,6 +201,7 @@ AliITSUv1Layer::AliITSUv1Layer(const AliITSUv1Layer &s):
   fStaveWidth(s.fStaveWidth),
   fStaveTilt(s.fStaveTilt),
   fNStaves(s.fNStaves),
+  fNModules(s.fNModules),
   fNChips(s.fNChips),
   fChipTypeID(s.fChipTypeID),
   fIsTurbo(s.fIsTurbo),
@@ -176,6 +210,7 @@ AliITSUv1Layer::AliITSUv1Layer(const AliITSUv1Layer &s):
 {
   //
   // Copy constructor
+  for (int i=kNHLevels;i--;) fHierarchy[i] = s.fHierarchy[i];
   //
 }
 
@@ -192,16 +227,18 @@ AliITSUv1Layer& AliITSUv1Layer::operator=(const AliITSUv1Layer &s)
   fLayRadius   = s.fLayRadius;
   fZLength     = s.fZLength;
   fSensorThick = s.fSensorThick;
-  fStaveThick = s.fStaveThick;
-  fStaveWidth = s.fStaveWidth;
-  fStaveTilt  = s.fStaveTilt;
-  fNStaves    = s.fNStaves;
-  fNChips    = s.fNChips;
+  fStaveThick  = s.fStaveThick;
+  fStaveWidth  = s.fStaveWidth;
+  fStaveTilt   = s.fStaveTilt;
+  fNStaves     = s.fNStaves;
+  fNModules    = s.fNModules;
+  fNChips      = s.fNChips;
   fIsTurbo     = s.fIsTurbo;
-  fChipTypeID   = s.fChipTypeID;
+  fChipTypeID  = s.fChipTypeID;
   fBuildLevel  = s.fBuildLevel;
   fStaveModel  = s.fStaveModel;
-
+  for (int i=kNHLevels;i--;) fHierarchy[i] = s.fHierarchy[i];
+  //
   return *this;
 }
 
@@ -235,10 +272,13 @@ void AliITSUv1Layer::CreateLayer(TGeoVolume *moth){
 
 
   // Check if the user set the proper parameters
-  if (fLayRadius <= 0) AliFatal(Form("Wrong layer radius (%f)",fLayRadius));
-  if (fZLength   <= 0) AliFatal(Form("Wrong layer length (%f)",fZLength));
+  if (fLayRadius<= 0) AliFatal(Form("Wrong layer radius (%f)",fLayRadius));
+  if (fZLength  <= 0) AliFatal(Form("Wrong layer length (%f)",fZLength));
   if (fNStaves  <= 0) AliFatal(Form("Wrong number of staves (%d)",fNStaves));
-  if (fNChips  <= 0) AliFatal(Form("Wrong number of chips (%d)",fNChips));
+  if (fNChips   <= 0) AliFatal(Form("Wrong number of chips (%d)",fNChips));
+
+  if (fLayerNumber >= fgkNumberOfInnerLayers && fNModules <= 0)
+    AliFatal(Form("Wrong number of modules (%d)",fNModules));
 
   if (fStaveThick <= 0) {
     AliInfo(Form("Stave thickness wrong or not set (%f), using default (%f)",
@@ -410,58 +450,63 @@ TGeoVolume* AliITSUv1Layer::CreateStave(const TGeoManager * /*mgr*/){
   // We have all shapes: now create the real volumes
 
   snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSStavePattern(), fLayerNumber);
-//  TGeoVolume *stavVol = new TGeoVolume(volname, stave, medAir);
-  TGeoVolume *stavVol = new TGeoVolumeAssembly(volname);
+//  TGeoVolume *staveVol = new TGeoVolume(volname, stave, medAir);
+  TGeoVolume *staveVol = new TGeoVolumeAssembly(volname);
 
-  //  stavVol->SetVisibility(kFALSE);
-  stavVol->SetVisibility(kTRUE);
-  stavVol->SetLineColor(2);
-  TGeoVolume *modVol = 0;
-  TGeoVolume *mechStavVol = 0;
+  //  staveVol->SetVisibility(kFALSE);
+  staveVol->SetVisibility(kTRUE);
+  staveVol->SetLineColor(2);
+  TGeoVolume *chipVol = 0;
+  TGeoVolume *mechStaveVol = 0;
 
   // Now build up the stave
-  if (fLayerNumber<3) {
-    modVol = CreateChipInnerB(xlenI,ylen,zlen);
-    zmod = ((TGeoBBox*)modVol->GetShape())->GetDZ();
+  if (fLayerNumber < fgkNumberOfInnerLayers) {
+    chipVol = CreateChipInnerB(xlenI,ylen,zlen);
+    zmod = ((TGeoBBox*)chipVol->GetShape())->GetDZ();
     for (Int_t j=0; j<fNChips; j++) {
       xpos = 0.;
       ypos = 0.021;  // Remove small overlap - M.S: 21may13
       zpos = -stave->GetDZ() + j*2*zmod + zmod;
-      stavVol->AddNode(modVol, j, new TGeoTranslation(xpos, ypos, zpos));
+      staveVol->AddNode(chipVol, j, new TGeoTranslation(xpos, ypos, zpos));
+      fHierarchy[kChip]++;
     }
  
   // put mechanical stave structure, only inner barrel up to now
-    mechStavVol = CreateStaveStructInnerB(xlenI,zlen); 
-    if (mechStavVol)
-      stavVol->AddNode(mechStavVol, fNChips, new TGeoCombiTrans(0, -0.15-ylen, 0, new TGeoRotation("",0, 0, 180)));
+    mechStaveVol = CreateStaveStructInnerB(xlenI,zlen); 
+    if (mechStaveVol)
+      staveVol->AddNode(mechStaveVol, fNChips, new TGeoCombiTrans(0, -0.15-ylen, 0, new TGeoRotation("",0, 0, 180)));
   }
 
   else{
     if (fStaveModel == AliITSUv1::kOBModel0) { // Create simplified stave struct as in v0
-      modVol = CreateChipInnerB(xlenI,ylen,zlen);
-  printf("?????? %f %f %f\n",xlenI,ylen,zlen);
-      zmod = ((TGeoBBox*)modVol->GetShape())->GetDZ();
+      chipVol = CreateChipInnerB(xlenI,ylen,zlen);
+      zmod = ((TGeoBBox*)chipVol->GetShape())->GetDZ();
       for (Int_t j=0; j<fNChips; j++) {
        xpos = 0.;
        ypos = 0.021;  // Remove small overlap - M.S: 21may13
        zpos = -stave->GetDZ() + j*2*zmod + zmod;
-       stavVol->AddNode(modVol, j, new TGeoTranslation(xpos, ypos, zpos));
+       staveVol->AddNode(chipVol, j, new TGeoTranslation(xpos, ypos, zpos));
+       fHierarchy[kModule]++;
       }
     } else { // (if fStaveModel) Create new stave struct as in TDR
-      modVol = CreateStaveOuterB(xLenO);
-      stavVol->AddNode(modVol, 1, new TGeoTranslation(0, 2.5, 0));
-
-      mechStavVol = CreateSpaceFrameOuterB(xLenO); 
-      if (mechStavVol)
-       stavVol->AddNode(mechStavVol, 1,
-                        new TGeoCombiTrans(0, 0, 0,
-                                           new TGeoRotation("", 180, 0, 0)));
+      chipVol = CreateStaveOuterB(xLenO);
+
+      xpos = ((TGeoBBox*)(chipVol->GetShape()))->GetDX()
+          - 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,
+                         new TGeoCombiTrans(0, 0, 0,
+                                            new TGeoRotation("", 180, 0, 0)));
     } // if (fStaveModel)
   }
   
 
   // Done, return the stave
-  return stavVol;
+  return staveVol;
 }
 
 //________________________________________________________________________
@@ -1795,7 +1840,7 @@ TGeoVolume* AliITSUv1Layer::CreateStaveOuterB(const Double_t xsta,
       mechStavVol = CreateStaveModelOuterB0(xsta,mgr);
       break;
     case AliITSUv1::kOBModel1:
-      mechStavVol = CreateStaveModelOuterB1(xsta,mgr);
+      mechStavVol = CreateStaveModelOuterB1(mgr);
       break;
     default:
       AliFatal(Form("Unknown stave model %d",fStaveModel));
@@ -1851,13 +1896,12 @@ TGeoVolume* AliITSUv1Layer::CreateStaveModelOuterB0(const Double_t ,
 }
 
 //________________________________________________________________________
-TGeoVolume* AliITSUv1Layer::CreateStaveModelOuterB1(const Double_t xsta,
-                                                   const TGeoManager *mgr){
+TGeoVolume* AliITSUv1Layer::CreateStaveModelOuterB1(const TGeoManager *mgr){
 //
-// Create the mechanical stave structure for the Outer Barrel as in TDR
+// Create the mechanical half stave structure
+// for the Outer Barrel as in TDR
 //
 // Input:
-//         xsta : X length
 //         mgr  : the GeoManager (used only to get the proper material)
 //
 // Output:
@@ -1866,241 +1910,277 @@ TGeoVolume* AliITSUv1Layer::CreateStaveModelOuterB1(const Double_t xsta,
 //
 // Created:      20 Nov 2013  Anastasia Barbano
 // Updated:      16 Jan 2014  Mario Sitta
+// Updated:      24 Feb 2014  Mario Sitta
 //
 
-  // Materials defined in AliITSUv0
+
+  // Local parameters
+  Double_t yFlex1      = fgkOBFlexCableAlThick;
+  Double_t yFlex2      = fgkOBFlexCableKapThick;
+  Double_t flexOverlap = 5; // to be checked
+  Double_t xHalfSt     = fgkOBHalfStaveWidth/2;
+  Double_t rCoolMin    = fgkOBCoolTubeInnerD/2;
+  Double_t rCoolMax    = rCoolMin + fgkOBCoolTubeThick;
+  Double_t kLay1       = 0.004; // to be checked
+  Double_t kLay2       = fgkOBGraphiteFoilThick;
+
+  Double_t xlen, ylen;
+  Double_t ymod, zmod;
+  Double_t xpos, ypos, ypos1, zpos/*, zpos5cm*/;
+  Double_t zlen;
+  char volname[30];
+
+
+  zlen = (fNChips*fgkOBModuleZLength + (fNChips-1)*fgkOBModuleGap)/2; //uhm... I need to check this
+
+
+  // First create all needed shapes
+
+  TGeoVolume *moduleVol = CreateModuleOuterB();
+  moduleVol->SetVisibility(kTRUE);
+  ymod = ((TGeoBBox*)(moduleVol->GetShape()))->GetDY();
+  zmod = ((TGeoBBox*)(moduleVol->GetShape()))->GetDZ();
+
+  TGeoBBox *busAl  = new TGeoBBox("BusAl",  xHalfSt, fgkOBBusCableAlThick/2,
+                                           zlen);
+  TGeoBBox *busKap = new TGeoBBox("BusKap", xHalfSt, fgkOBBusCableKapThick/2,
+                                           zlen);
+
+  TGeoBBox *coldPlate  = new TGeoBBox("ColdPlate", fgkOBHalfStaveWidth/2,
+                                     fgkOBColdPlateThick/2, zlen);
+
+  TGeoTube *coolTube   = new TGeoTube("CoolingTube", rCoolMin, rCoolMax, zlen);
+  TGeoTube *coolWater  = new TGeoTube("CoolingWater", 0.,  rCoolMin, zlen);
+
+  xlen = xHalfSt - fgkOBCoolTubeXDist/2 - coolTube->GetRmax();
+  TGeoBBox *graphlat    = new TGeoBBox("GraphLateral", xlen/2, kLay2/2, zlen);
+
+  xlen = fgkOBCoolTubeXDist/2 - coolTube->GetRmax();
+  TGeoBBox *graphmid    = new TGeoBBox("GraphMiddle", xlen, kLay2/2, zlen);
+
+  ylen = coolTube->GetRmax() - kLay2;
+  TGeoBBox *graphvert   = new TGeoBBox("GraphVertical", kLay2/2, ylen/2, zlen);
+
+  TGeoTubeSeg *graphtub = new TGeoTubeSeg("GraphTube", rCoolMax,
+                                         rCoolMax+kLay2, zlen,
+                                         180., 360.);
+
+  xlen = xHalfSt - fgkOBCoolTubeXDist/2 - coolTube->GetRmax() - kLay2;
+  TGeoBBox *fleeclat    = new TGeoBBox("FleecLateral", xlen/2, kLay1/2, zlen);
+
+  xlen = fgkOBCoolTubeXDist/2 - coolTube->GetRmax() - kLay2;
+  TGeoBBox *fleecmid    = new TGeoBBox("FleecMiddle", xlen, kLay1/2, zlen);
+
+  ylen = coolTube->GetRmax() - kLay2 - kLay1;
+  TGeoBBox *fleecvert   = new TGeoBBox("FleecVertical", kLay1/2, ylen/2, zlen);
+
+  TGeoTubeSeg *fleectub = new TGeoTubeSeg("FleecTube", rCoolMax+kLay2,
+                                         rCoolMax+kLay1+kLay2,
+                                         zlen, 180., 360.);
+
+  TGeoBBox *flex1_5cm  = new TGeoBBox("Flex1MV_5cm",xHalfSt,yFlex1/2,flexOverlap/2);
+  TGeoBBox *flex2_5cm  = new TGeoBBox("Flex2MV_5cm",xHalfSt,yFlex2/2,flexOverlap/2);
+
+  // The half stave container
+  ylen = ymod + busAl->GetDY() + busKap->GetDY() +
+         coldPlate->GetDY() + 2*coolTube->GetRmax() +
+         graphtub->GetRmax() + fleectub->GetRmax();
+  TGeoBBox *halfStave = new TGeoBBox(xHalfSt, ylen, fZLength/2);
+
+
+  // We have all shapes: now create the real volumes
+
   TGeoMedium *medAluminum     = mgr->GetMedium("ITS_ALUMINUM$");
   TGeoMedium *medCarbon       = mgr->GetMedium("ITS_CARBON$");
   TGeoMedium *medKapton       = mgr->GetMedium("ITS_KAPTON(POLYCH2)$");
-  TGeoMedium *medGlue         = mgr->GetMedium("ITS_GLUE$");
   TGeoMedium *medWater        = mgr->GetMedium("ITS_WATER$");
   TGeoMedium *medCarbonFleece = mgr->GetMedium("ITS_CarbonFleece$"); 
   TGeoMedium *medFGS003       = mgr->GetMedium("ITS_FGS003$"); //amec thermasol
   TGeoMedium *medAir          = mgr->GetMedium("ITS_AIR$");
 
 
-  // Local parameters
-  Double_t modGap             = fgkOBChipGap;
-  Double_t yFlex1             = fgkOBFlexCable1Thick;
-  Double_t yFlex2             = fgkOBFlexCable2Thick;
-  Double_t yBus1              = fgkOBBusCable1Thick;
-  Double_t yBus2              = fgkOBBusCable2Thick;
-  Double_t xModPlate          = fgkOBHalfStaveWidth;
-  Double_t yModPlate          = fgkOBCarbonPlateThick;
-  Double_t xCPlate            = fgkOBHalfStaveWidth;
-  Double_t yCPlate            = fgkOBColdPlateThick;
-  Double_t yGlue              = fgkOBGlueThick;
-  Double_t flexOverlap        = 5;
-  Double_t deltaY             = 0.176;
-  Double_t xOverlap           = 0.23;       //overlapping of the halfStaves to cover the dead zone of sensors
-  Double_t zMod               = fgkOBChipZLength;
-  Double_t xHalfSt            = fgkOBHalfStaveWidth/2;
-  Double_t xPos               = xOverlap/2 - xHalfSt;
-  Double_t xlen               = xsta;
-  Double_t rMin               = 0.267/2;
-  Double_t rMax               = rMin + 0.0065;
-  Double_t kLay1              = 0.004;      //carbon fleece
-  Double_t kLay2              = 0.003;      //carbon paper
-  Double_t yPos               = kLay1+kLay2;
-  Double_t ylen,zact;
-  Double_t zpos, zpos5cm;
-  Double_t ymod;
-  Double_t zbus;
-  Double_t zlen;
+  TGeoVolume *busAlVol = new TGeoVolume("BusAlVol", busAl , medAluminum);
+  busAlVol->SetLineColor(kCyan);
+  busAlVol->SetFillColor(busAlVol->GetLineColor());
+  busAlVol->SetFillStyle(4000); // 0% transparent
 
+  TGeoVolume *busKapVol = new TGeoVolume("BusKapVol", busKap, medKapton);
+  busKapVol->SetLineColor(kBlue);
+  busKapVol->SetFillColor(busKapVol->GetLineColor());
+  busKapVol->SetFillStyle(4000); // 0% transparent
 
-  if (fIsTurbo) xlen = 0.5*fStaveWidth;
-  //ylen    = 0.5*fStaveThick;
-  ymod    = 0.005/2;//0.5*fSensorThick;
-  ylen    = 0.5*(2*kLay1+2*kLay2+2*rMax+yCPlate+yGlue+ yModPlate + ymod + 2*yFlex1 + 2*yFlex2 + yBus1 + yBus2 + deltaY);
-  zact    = fNChips*zMod; //active area 
-  zbus    = zact + (fNChips-1)*modGap; 
-  zlen    = zbus/2;
+  TGeoVolume *coldPlateVol = new TGeoVolume("ColdPlateVol",
+                                           coldPlate, medCarbon);
+  coldPlateVol->SetLineColor(kYellow-3);
+  coldPlateVol->SetFillColor(coldPlateVol->GetLineColor());
+  coldPlateVol->SetFillStyle(4000); // 0% transparent
 
+  TGeoVolume *coolTubeVol  = new TGeoVolume("CoolingTubeVol",
+                                           coolTube, medKapton);
+  coolTubeVol->SetLineColor(kGray);
+  coolTubeVol->SetFillColor(coolTubeVol->GetLineColor());
+  coolTubeVol->SetFillStyle(4000); // 0% transparent
+
+  TGeoVolume *coolWaterVol = new TGeoVolume("CoolingWaterVol",
+                                           coolWater,medWater);
+  coolWaterVol->SetLineColor(kBlue);
+  coolWaterVol->SetFillColor(coolWaterVol->GetLineColor());
+  coolWaterVol->SetFillStyle(4000); // 0% transparent
+
+  TGeoVolume *graphlatVol = new TGeoVolume("GraphiteFoilLateral",
+                                          graphlat, medFGS003);
+  graphlatVol->SetLineColor(kGreen);
+  graphlatVol->SetFillColor(graphlatVol->GetLineColor());
+  graphlatVol->SetFillStyle(4000); // 0% transparent
+
+  TGeoVolume *graphmidVol = new TGeoVolume("GraphiteFoilMiddle",
+                                          graphmid, medFGS003);
+  graphmidVol->SetLineColor(kGreen);
+  graphmidVol->SetFillColor(graphmidVol->GetLineColor());
+  graphmidVol->SetFillStyle(4000); // 0% transparent
+
+  TGeoVolume *graphvertVol = new TGeoVolume("GraphiteFoilVertical",
+                                           graphvert, medFGS003);
+  graphvertVol->SetLineColor(kGreen);
+  graphvertVol->SetFillColor(graphvertVol->GetLineColor());
+  graphvertVol->SetFillStyle(4000); // 0% transparent
+
+  TGeoVolume *graphtubVol = new TGeoVolume("GraphiteFoilPipeCover",
+                                          graphtub, medFGS003);
+  graphtubVol->SetLineColor(kGreen);
+  graphtubVol->SetFillColor(graphtubVol->GetLineColor());
+  graphtubVol->SetFillStyle(4000); // 0% transparent
+
+  TGeoVolume *fleeclatVol = new TGeoVolume("CarbonFleeceLateral",
+                                          fleeclat, medCarbonFleece);
+  fleeclatVol->SetLineColor(kViolet);
+  fleeclatVol->SetFillColor(fleeclatVol->GetLineColor());
+  fleeclatVol->SetFillStyle(4000); // 0% transparent
+
+  TGeoVolume *fleecmidVol = new TGeoVolume("CarbonFleeceMiddle",
+                                          fleecmid, medCarbonFleece);
+  fleecmidVol->SetLineColor(kViolet);
+  fleecmidVol->SetFillColor(fleecmidVol->GetLineColor());
+  fleecmidVol->SetFillStyle(4000); // 0% transparent
+
+  TGeoVolume *fleecvertVol = new TGeoVolume("CarbonFleeceVertical",
+                                           fleecvert, medCarbonFleece);
+  fleecvertVol->SetLineColor(kViolet);
+  fleecvertVol->SetFillColor(fleecvertVol->GetLineColor());
+  fleecvertVol->SetFillStyle(4000); // 0% transparent
+
+  TGeoVolume *fleectubVol = new TGeoVolume("CarbonFleecePipeCover",
+                                          fleectub, medCarbonFleece);
+  fleectubVol->SetLineColor(kViolet);
+  fleectubVol->SetFillColor(fleectubVol->GetLineColor());
+  fleectubVol->SetFillStyle(4000); // 0% transparent
+
+  snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSHalfStavePattern(), fLayerNumber);
+  TGeoVolume *halfStaveVol  = new TGeoVolume(volname, halfStave, medAir);
+//   halfStaveVol->SetLineColor(12);
+//   halfStaveVol->SetFillColor(12); 
+//   halfStaveVol->SetVisibility(kTRUE);
 
-  // First create all needed shapes
 
-  TGeoTube *coolTube   = new TGeoTube("CoolingTube",rMin,rMax,zbus/2);
-  TGeoTube *coolTubeW  = new TGeoTube("CoolingTubeWater",0,rMin,zbus/2);
-  TGeoBBox *coldPlate  = new TGeoBBox("ColdPlate",xCPlate/2,yCPlate/2,zbus/2);
-  TGeoBBox *glue       = new TGeoBBox("Glue",xCPlate/2,yGlue/2,zbus/2);
-  TGeoBBox *modPlate   = new TGeoBBox("CarbonPlate",xModPlate/2,yModPlate/2,zbus/2);
-  TGeoBBox *flex1      = new TGeoBBox("Flex1MV",xHalfSt,yFlex1/2,zMod/2);
-  TGeoBBox *flex2      = new TGeoBBox("Flex2MV",xHalfSt,yFlex2/2,zMod/2);
-  TGeoBBox *flex1_5cm  = new TGeoBBox("Flex1MV_5cm",xHalfSt,yFlex1/2,flexOverlap/2);
-  TGeoBBox *flex2_5cm  = new TGeoBBox("Flex2MV_5cm",xHalfSt,yFlex2/2,flexOverlap/2);
-  TGeoBBox *bus1       = new TGeoBBox("Bus1HV",xHalfSt,yBus1/2,zbus/2);
-  TGeoBBox *bus2       = new TGeoBBox("Bus2HV",xHalfSt,yBus2/2,zbus/2); 
-  TGeoTubeSeg *cone1   = new TGeoTubeSeg(rMax +kLay2,rMax+kLay1+kLay2,zlen,180.,360.);  //Carbon Fleece 
-  TGeoTubeSeg *cone2   = new TGeoTubeSeg(rMax ,rMax+kLay2,zlen,180.,360.);  //Graphite paper 
-  TGeoBBox *box11      = new TGeoBBox((0.95-kLay2-rMax)/2,kLay1/2,zlen);
-  TGeoBBox *box12      = new TGeoBBox((1.11-2*kLay2-2*rMax)/2,kLay1/2,zlen);
-  TGeoBBox *box13      = new TGeoBBox(kLay1/2,(rMax-(kLay1+kLay2))/2,zlen);
-  TGeoBBox *box21      = new TGeoBBox((0.95-rMax)/2,kLay2/2,zlen);
-  TGeoBBox *box22      = new TGeoBBox((1.11-2*rMax)/2,kLay2/2,zlen);
-  TGeoBBox *box23      = new TGeoBBox(kLay2/2,(rMax-kLay2)/2,zlen);
-  TGeoBBox *mechStruct = new TGeoBBox("mechanicalStructure",xlen, ylen, 0.5*fZLength); 
-
-
-  TGeoVolume *modVol       = CreateChipOuterB(xHalfSt, ymod, zMod);
-  TGeoVolume *coolTubeVol  = new TGeoVolume("CoolingTubeVol",coolTube,medKapton);
-  TGeoVolume *coolTubeWVol = new TGeoVolume("CoolingTubeWaterVol",coolTubeW,medWater);
-  TGeoVolume *coldPlateVol = new TGeoVolume("ColdPlateVol",coldPlate,medCarbon);
-  TGeoVolume *glueVol      = new TGeoVolume("GlueVol",glue,medGlue);
-  TGeoVolume *modPlateVol  = new TGeoVolume("CarbonPlateVol",modPlate,medCarbon);
-  TGeoVolume *flex1Vol     = new TGeoVolume("Flex1Vol",flex1,medAluminum);
-  TGeoVolume *flex2Vol     = new TGeoVolume("Flex2Vol",flex2,medKapton);
   TGeoVolume *flex1_5cmVol = new TGeoVolume("Flex1Vol5cm",flex1_5cm,medAluminum);
   TGeoVolume *flex2_5cmVol = new TGeoVolume("Flex2Vol5cm",flex2_5cm,medKapton);
-  TGeoVolume *bus1Vol      = new TGeoVolume("Bus1Vol",bus1,medAluminum);
-  TGeoVolume *bus2Vol      = new TGeoVolume("Bus2Vol",bus2,medKapton);
-  TGeoVolume *cone1Vol     = new TGeoVolume("CarbonFleecePipeCover",cone1,medCarbonFleece);
-  TGeoVolume *cone2Vol     = new TGeoVolume("GraphitePaperPipeCover",cone2,medFGS003);
-  TGeoVolume *plate11Vol   = new TGeoVolume("CarbonFleeceLR1",box11,medCarbonFleece);
-  TGeoVolume *plate12Vol   = new TGeoVolume("CarbonFleeceMiddle1",box12,medCarbonFleece); 
-  TGeoVolume *plate13Vol   = new TGeoVolume("CarbonFleeceVertical1",box13,medCarbonFleece); 
-  TGeoVolume *plate21Vol   = new TGeoVolume("CarbonFleeceLR2",box21,medFGS003);
-  TGeoVolume *plate22Vol   = new TGeoVolume("CarbonFleeceMiddle2",box22,medFGS003);
-  TGeoVolume *plate23Vol   = new TGeoVolume("CarbonFleeceVertical2",box23,medFGS003);
-  TGeoVolume *mechStavVol  = new TGeoVolume("mechStaveVolume",mechStruct,medAir);
-
-  mechStavVol->SetLineColor(12);
-  mechStavVol->SetFillColor(12); 
-  mechStavVol->SetVisibility(kTRUE);
 
-  modVol->SetVisibility(kTRUE);
+
   flex1_5cmVol->SetLineColor(kRed);
   flex2_5cmVol->SetLineColor(kGreen);
-  modPlateVol->SetLineColor(kMagenta-8);
-  coolTubeVol->SetLineColor(kGray);
-  coolTubeWVol->SetLineColor(kBlue);
-  coldPlateVol->SetLineColor(kYellow-3);
-  glueVol->SetLineColor(kBlack);
-  flex1Vol->SetLineColor(kRed);
-  flex2Vol->SetLineColor(kGreen);
-  bus1Vol->SetLineColor(kCyan);
-  bus2Vol->SetLineColor(kBlue);
-  cone1Vol->SetFillColor(kViolet);
-  plate11Vol->SetFillColor(kViolet);
-  plate12Vol->SetLineColor(kViolet);
-  plate13Vol->SetLineColor(kViolet);
-  cone2Vol->SetLineColor(kGreen);
-  plate22Vol->SetFillColor(kGreen);
-  plate21Vol->SetLineColor(kGreen);
-  plate23Vol->SetLineColor(kGreen);
-
-
-  //Carbon Fleece
-
-  mechStavVol->AddNode(plate11Vol,1,new TGeoTranslation(xPos -(1.11/2+rMax+box11->GetDX()+kLay2),-ylen + yPos +2*rMax-kLay2-kLay1/2,0));
-  mechStavVol->AddNode(plate11Vol,2,new TGeoTranslation(xPos +(1.11/2+rMax+box11->GetDX()+kLay2),-ylen + yPos +2*rMax-kLay2-kLay1/2,0));
-  mechStavVol->AddNode(plate11Vol,3,new TGeoTranslation(-xPos -(1.11/2+rMax+box11->GetDX()+kLay2),-ylen + yPos +2*rMax-kLay2-kLay1/2 +deltaY,0));
-  mechStavVol->AddNode(plate11Vol,4,new TGeoTranslation(-xPos +(1.11/2+rMax+box11->GetDX()+kLay2),-ylen + yPos +2*rMax-kLay2-kLay1/2 +deltaY,0));
-  mechStavVol->AddNode(plate12Vol,1,new TGeoTranslation(xPos ,-ylen + yPos +2*rMax-kLay2-kLay1/2,0));
-  mechStavVol->AddNode(plate12Vol,2,new TGeoTranslation(-xPos ,-ylen + yPos +2*rMax-kLay2-kLay1/2 + deltaY,0));
-  mechStavVol->AddNode(plate13Vol,1,new TGeoTranslation(xPos -(1.11/2+rMax+kLay2+box13->GetDX()),-ylen + yPos +2*rMax-kLay1-kLay2-box13->GetDY(),0));
-  mechStavVol->AddNode(plate13Vol,2,new TGeoTranslation(xPos -1.11/2+rMax+kLay2+box13->GetDX(),-ylen + yPos +2*rMax-kLay1-kLay2-box13->GetDY(),0));
-  mechStavVol->AddNode(plate13Vol,3,new TGeoTranslation(xPos +(1.11/2+rMax+kLay2+box13->GetDX()),-ylen + yPos +2*rMax-kLay1-kLay2-box13->GetDY(),0));
-  mechStavVol->AddNode(plate13Vol,4,new TGeoTranslation(xPos +1.11/2-rMax-kLay2-box13->GetDX(),-ylen + yPos +2*rMax-kLay1-kLay2-box13->GetDY(),0));
-  mechStavVol->AddNode(plate13Vol,5,new TGeoTranslation(-xPos -(1.11/2+rMax+kLay2+box13->GetDX()),-ylen + yPos +2*rMax-kLay1-kLay2-box13->GetDY() +deltaY,0));
-  mechStavVol->AddNode(plate13Vol,6,new TGeoTranslation(-xPos -1.11/2+rMax+kLay2+box13->GetDX(),-ylen + yPos +2*rMax-kLay1-kLay2-box13->GetDY() +deltaY,0));
-  mechStavVol->AddNode(plate13Vol,7,new TGeoTranslation(-xPos +(1.11/2+rMax+kLay2+box13->GetDX()),-ylen + yPos +2*rMax-kLay1-kLay2-box13->GetDY() +deltaY,0));
-  mechStavVol->AddNode(plate13Vol,8,new TGeoTranslation(-xPos +1.11/2-rMax-kLay2-box13->GetDX(),-ylen + yPos +2*rMax-kLay1-kLay2-box13->GetDY() +deltaY,0));
-
-  mechStavVol->AddNode(cone1Vol,1,new TGeoTranslation(xPos - 0.555,-ylen + yPos + rMax,0));
-  mechStavVol->AddNode(cone1Vol,2,new TGeoTranslation(xPos + 0.555,-ylen + yPos + rMax,0));
-  mechStavVol->AddNode(cone1Vol,3,new TGeoTranslation(-xPos - 0.555,-ylen + yPos + rMax + deltaY,0));
-  mechStavVol->AddNode(cone1Vol,4,new TGeoTranslation(-xPos + 0.555,-ylen + yPos + rMax + deltaY,0));
-
-
-  //Carbon Paper
-
-  mechStavVol->AddNode(plate21Vol,1,new TGeoTranslation(xPos -(1.11/2+rMax+box21->GetDX()),-ylen + yPos +2*rMax-kLay2/2,0));
-  mechStavVol->AddNode(plate21Vol,2,new TGeoTranslation(xPos +(1.11/2+rMax+box21->GetDX()) ,-ylen + yPos +2*rMax-kLay2/2,0));
-  mechStavVol->AddNode(plate21Vol,3,new TGeoTranslation(-xPos -(1.11/2+rMax+box21->GetDX()) ,-ylen + yPos +2*rMax-kLay2/2 +deltaY,0));
-  mechStavVol->AddNode(plate21Vol,4,new TGeoTranslation(-xPos +(1.11/2+rMax+box21->GetDX()) ,-ylen + yPos +2*rMax-kLay2/2 +deltaY,0));
-  mechStavVol->AddNode(plate22Vol,1,new TGeoTranslation(xPos ,-ylen + yPos +2*rMax-kLay2/2,0));
-  mechStavVol->AddNode(plate22Vol,2,new TGeoTranslation(-xPos ,-ylen + yPos +2*rMax-kLay2/2 + deltaY,0));
-  mechStavVol->AddNode(plate23Vol,1,new TGeoTranslation(xPos -(1.11/2+rMax+box23->GetDX()),-ylen + yPos +2*rMax-kLay2-(rMax-kLay2)/2,0));
-  mechStavVol->AddNode(plate23Vol,2,new TGeoTranslation(xPos -1.11/2+rMax+box23->GetDX(),-ylen + yPos +2*rMax-kLay2-(rMax-kLay2)/2,0));
-  mechStavVol->AddNode(plate23Vol,3,new TGeoTranslation(xPos +(1.11/2+rMax+box23->GetDX()),-ylen + yPos +2*rMax-kLay2-(rMax-kLay2)/2,0));
-  mechStavVol->AddNode(plate23Vol,4,new TGeoTranslation(xPos +1.11/2-rMax-box23->GetDX(),-ylen + yPos +2*rMax-kLay2-(rMax-kLay2)/2,0));
-  mechStavVol->AddNode(plate23Vol,5,new TGeoTranslation(-xPos -(1.11/2+rMax+box23->GetDX()),-ylen + yPos +2*rMax-kLay2-(rMax-kLay2)/2+deltaY,0));
-  mechStavVol->AddNode(plate23Vol,6,new TGeoTranslation(-xPos -1.11/2+rMax+box23->GetDX(),-ylen + yPos +2*rMax-kLay2-(rMax-kLay2)/2+deltaY,0));
-  mechStavVol->AddNode(plate23Vol,7,new TGeoTranslation(-xPos +(1.11/2+rMax+box23->GetDX()),-ylen + yPos +2*rMax-kLay2-(rMax-kLay2)/2+deltaY,0));
-  mechStavVol->AddNode(plate23Vol,8,new TGeoTranslation(-xPos +1.11/2-rMax-box23->GetDX(),-ylen + yPos +2*rMax-kLay2-(rMax-kLay2)/2+deltaY,0));
-
-  mechStavVol->AddNode(cone2Vol,1,new TGeoTranslation(xPos - 0.555,-ylen + yPos + rMax,0));
-  mechStavVol->AddNode(cone2Vol,2,new TGeoTranslation(xPos + 0.555,-ylen + yPos + rMax,0));
-  mechStavVol->AddNode(cone2Vol,3,new TGeoTranslation(-xPos - 0.555,-ylen + yPos + rMax + deltaY,0));
-  mechStavVol->AddNode(cone2Vol,4,new TGeoTranslation(-xPos + 0.555,-ylen + yPos + rMax + deltaY,0));
-
-  //Cooling Tubes + water
-
-  mechStavVol->AddNode(coolTubeVol,1,new TGeoTranslation(xPos - 0.555,-ylen + yPos + rMax,0));
-  mechStavVol->AddNode(coolTubeWVol,1,new TGeoTranslation(xPos - 0.555,-ylen + yPos + rMax,0));
-  mechStavVol->AddNode(coolTubeVol,2,new TGeoTranslation(xPos + 0.555,-ylen + yPos + rMax,0));
-  mechStavVol->AddNode(coolTubeWVol,2,new TGeoTranslation(xPos + 0.555,-ylen + yPos + rMax,0));
-  mechStavVol->AddNode(coolTubeVol,3,new TGeoTranslation(-xPos - 0.555,-ylen + yPos + rMax + deltaY,0));
-  mechStavVol->AddNode(coolTubeWVol,3,new TGeoTranslation(-xPos - 0.555,-ylen + yPos + rMax + deltaY,0));
-  mechStavVol->AddNode(coolTubeVol,4,new TGeoTranslation(-xPos + 0.555,-ylen + yPos + rMax + deltaY,0));
-  mechStavVol->AddNode(coolTubeWVol,4,new TGeoTranslation(-xPos + 0.555,-ylen + yPos + rMax + deltaY,0));
-
-  //Cold Plate
-
-  mechStavVol->AddNode(coldPlateVol,1,new TGeoTranslation(xPos,-ylen + yPos + 2*rMax + yCPlate/2,0));
-  mechStavVol->AddNode(coldPlateVol,2,new TGeoTranslation(-xPos,-ylen + yPos + 2*rMax + yCPlate/2 + deltaY,0));
-
-  //Glue
-
-  mechStavVol->AddNode(glueVol,1,new TGeoTranslation(xPos,-ylen + yPos + 2*rMax + yCPlate + yGlue/2,0));
-  mechStavVol->AddNode(glueVol,2,new TGeoTranslation(-xPos,-ylen + yPos + 2*rMax + yCPlate + yGlue/2 + deltaY,0));
-
-  //Chip Carbon Plate
-
-  mechStavVol->AddNode(modPlateVol,1,new TGeoTranslation(xPos, -ylen + yPos + 2*rMax + yCPlate + yGlue + yModPlate/2,0));
-  mechStavVol->AddNode(modPlateVol,2,new TGeoTranslation(-xPos, -ylen + yPos + 2*rMax + yCPlate + yGlue + yModPlate/2 + deltaY,0));
-
-  //Bus
-
-  mechStavVol->AddNode(bus1Vol,1,new TGeoTranslation(xPos, -ylen + yPos + 2*rMax + yCPlate + yGlue + yModPlate + 2*ymod + 2*yFlex1 + 2*yFlex2 + yBus1/2,0));
-  mechStavVol->AddNode(bus1Vol,2,new TGeoTranslation(-xPos, -ylen + yPos + 2*rMax + yCPlate + yGlue + yModPlate + 2*ymod + 2*yFlex1 + 2*yFlex2 + yBus1/2 + deltaY,0));
-  mechStavVol->AddNode(bus2Vol,1,new TGeoTranslation(xPos, -ylen + yPos + 2*rMax + yCPlate + yGlue + yModPlate + 2*ymod + 2*yFlex1 + 2*yFlex2 + yBus1 + yBus2/2,0));
-  mechStavVol->AddNode(bus2Vol,2,new TGeoTranslation(-xPos, -ylen + yPos + 2*rMax + yCPlate + yGlue + yModPlate + 2*ymod + 2*yFlex1 + 2*yFlex2 + yBus1 + yBus2/2 + deltaY,0));
   
-  //FPC + chips
 
-  for (Int_t j=0; j<fNChips; j++) {
+  // Now build up the half stave
+  ypos = halfStave->GetDY() - busKap->GetDY();
+  halfStaveVol->AddNode(busKapVol, 1, new TGeoTranslation(0, ypos, 0));
 
-    zpos = -(zact + (fNChips-1)*modGap)/2 + j*(zMod + modGap) + zMod/2;
-    zpos5cm = -(zact + (fNChips-1)*modGap)/2 + (j+1)*(zMod + modGap) + flexOverlap/2 ;
-
-    mechStavVol->AddNode(modVol, j, new TGeoTranslation(xPos, -ylen + yPos + 2*rMax + yCPlate + yGlue + yModPlate + ymod, zpos));
-    mechStavVol->AddNode(modVol, fNChips+j, new TGeoTranslation(-xPos, -ylen + yPos + 2*rMax + yCPlate + yGlue + yModPlate + ymod +deltaY, zpos));
-    mechStavVol->AddNode(flex1Vol,j,new TGeoTranslation(xPos, -ylen + yPos + 2*rMax + yCPlate + yGlue + yModPlate + 2*ymod + yFlex1/2,zpos));
-    mechStavVol->AddNode(flex1Vol,fNChips+j,new TGeoTranslation(-xPos, -ylen + yPos + 2*rMax + yCPlate + yGlue + yModPlate + 2*ymod + yFlex1/2 + deltaY,zpos));
-    mechStavVol->AddNode(flex2Vol,j,new TGeoTranslation(xPos, -ylen + yPos + yModPlate + 2*rMax + yCPlate + yGlue + 2*ymod + yFlex1 + yFlex2/2,zpos));
-    mechStavVol->AddNode(flex2Vol,fNChips+j,new TGeoTranslation(-xPos, -ylen + yPos + 2*rMax + yCPlate + yGlue + yModPlate + 2*ymod + yFlex1 + yFlex2/2 + deltaY,zpos));
-
-    if((j+1)!=fNChips){
-      mechStavVol->AddNode(flex1_5cmVol,j,new TGeoTranslation(xPos,-ylen + yPos + 2*rMax + yCPlate + yGlue + yModPlate + 2*ymod + yFlex1 + yFlex2 + yFlex1/2,zpos5cm));
-      mechStavVol->AddNode(flex1_5cmVol,fNChips+j,new TGeoTranslation(-xPos,-ylen + yPos + 2*rMax + yCPlate + yGlue + yModPlate + 2*ymod + yFlex1 + yFlex2 + yFlex1/2 +deltaY,zpos5cm));
-      mechStavVol->AddNode(flex2_5cmVol,j,new TGeoTranslation(xPos,-ylen + yPos + 2*rMax + yCPlate + yGlue + yModPlate + 2*ymod + 2*yFlex1 + 3*yFlex2/2,zpos5cm));
-      mechStavVol->AddNode(flex2_5cmVol,fNChips+j,new TGeoTranslation(-xPos,-ylen + yPos + 2*rMax + yCPlate + yGlue + yModPlate + 2*ymod + 2*yFlex1 + 3*yFlex2/2 +deltaY,zpos5cm));
-    }
-    else {
-      mechStavVol->AddNode(flex1_5cmVol,j,new TGeoTranslation(xPos,-ylen + yPos + 2*rMax + yCPlate + yGlue + yModPlate + 2*ymod + yFlex1/2,zpos5cm-modGap));
-      mechStavVol->AddNode(flex1_5cmVol,fNChips+j,new TGeoTranslation(-xPos,-ylen + yPos + 2*rMax + yCPlate + yGlue + yModPlate + 2*ymod + yFlex1/2 +deltaY,zpos5cm-modGap));
-      mechStavVol->AddNode(flex2_5cmVol,j,new TGeoTranslation(xPos,-ylen + yPos + 2*rMax + yCPlate + yGlue + yModPlate +2*ymod + yFlex1 + yFlex2/2,zpos5cm-modGap));
-      mechStavVol->AddNode(flex2_5cmVol,fNChips+j,new TGeoTranslation(-xPos,-ylen + yPos + 2*rMax + yCPlate + yGlue + yModPlate + 2*ymod + yFlex1 + yFlex2/2 +deltaY,zpos5cm-modGap));
+  ypos -= (busKap->GetDY() + busAl->GetDY());
+  halfStaveVol->AddNode(busAlVol, 1, new TGeoTranslation(0, ypos, 0));
 
-      }
+  ypos -= (busAl->GetDY() + ymod);
+  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());
+  halfStaveVol->AddNode(coldPlateVol, 1, new TGeoTranslation(0, ypos, 0));
+
+  coolTubeVol->AddNode(coolWaterVol, 1, 0);
+
+  xpos = fgkOBCoolTubeXDist/2;
+  ypos1 = ypos - (coldPlate->GetDY() + coolTube->GetRmax());
+  halfStaveVol->AddNode(coolTubeVol, 1, new TGeoTranslation(-xpos, ypos1, 0));
+  halfStaveVol->AddNode(coolTubeVol, 2, new TGeoTranslation( xpos, ypos1, 0));
+
+  halfStaveVol->AddNode(graphtubVol, 1, new TGeoTranslation(-xpos, ypos1, 0));
+  halfStaveVol->AddNode(graphtubVol, 2, new TGeoTranslation( xpos, ypos1, 0));
+
+  halfStaveVol->AddNode(fleectubVol, 1, new TGeoTranslation(-xpos, ypos1, 0));
+  halfStaveVol->AddNode(fleectubVol, 2, new TGeoTranslation( xpos, ypos1, 0));
+
+  xpos = xHalfSt - graphlat->GetDX();
+  ypos1 = ypos - (coldPlate->GetDY() + graphlat->GetDY());
+  halfStaveVol->AddNode(graphlatVol, 1, new TGeoTranslation(-xpos, ypos1, 0));
+  halfStaveVol->AddNode(graphlatVol, 2, new TGeoTranslation( xpos, ypos1, 0));
+
+  halfStaveVol->AddNode(graphmidVol, 1, new TGeoTranslation(0, ypos1, 0));
+
+  xpos = xHalfSt - 2*graphlat->GetDX() + graphvert->GetDX();
+  ypos1 = ypos - (coldPlate->GetDY() +2*graphlat->GetDY() +graphvert->GetDY());
+  halfStaveVol->AddNode(graphvertVol, 1, new TGeoTranslation(-xpos, ypos1, 0));
+  halfStaveVol->AddNode(graphvertVol, 2, new TGeoTranslation( xpos, ypos1, 0));
+  xpos = graphmid->GetDX() - graphvert->GetDX();
+  halfStaveVol->AddNode(graphvertVol, 3, new TGeoTranslation(-xpos, ypos1, 0));
+  halfStaveVol->AddNode(graphvertVol, 4, new TGeoTranslation( xpos, ypos1, 0));
+
+  xpos = xHalfSt - fleeclat->GetDX();
+  ypos1 = ypos - (coldPlate->GetDY() +2*graphlat->GetDY() +fleeclat->GetDY());
+  halfStaveVol->AddNode(fleeclatVol, 1, new TGeoTranslation(-xpos, ypos1, 0));
+  halfStaveVol->AddNode(fleeclatVol, 2, new TGeoTranslation( xpos, ypos1, 0));
+
+  halfStaveVol->AddNode(fleecmidVol, 1, new TGeoTranslation(0, ypos1, 0));
+
+  xpos = xHalfSt - 2*fleeclat->GetDX() + fleecvert->GetDX();
+  ypos1 = ypos - (coldPlate->GetDY() +2*graphlat->GetDY()
+               + 2*fleeclat->GetDY() + fleecvert->GetDY());
+  halfStaveVol->AddNode(fleecvertVol, 1, new TGeoTranslation(-xpos, ypos1, 0));
+  halfStaveVol->AddNode(fleecvertVol, 2, new TGeoTranslation( xpos, ypos1, 0));
+  xpos = fleecmid->GetDX() - fleecvert->GetDX();
+  halfStaveVol->AddNode(fleecvertVol, 3, new TGeoTranslation(-xpos, ypos1, 0));
+  halfStaveVol->AddNode(fleecvertVol, 4, new TGeoTranslation( xpos, ypos1, 0));
+
+
+
+  //THE FOLLOWING IS ONLY A REMINDER FOR WHAT IS STILL MISSING
+
+//   for (Int_t j=0; j<fNChips; j++) {
+
+//     zpos = -(zact + (fNChips-1)*modGap)/2 + j*(zMod + modGap) + zMod/2;
+//     zpos5cm = -(zact + (fNChips-1)*modGap)/2 + (j+1)*(zMod + modGap) + flexOverlap/2 ;
+
+//     halfStaveVol->AddNode(moduleVol, j, new TGeoTranslation(xPos, -ylen + yPos + 2*rCoolMax + yCPlate + yGlue + yModPlate + ymod, zpos));
+//     halfStaveVol->AddNode(moduleVol, fNChips+j, new TGeoTranslation(-xPos, -ylen + yPos + 2*rCoolMax + yCPlate + yGlue + yModPlate + ymod +deltaY, zpos));
+
+//     if((j+1)!=fNChips){
+//       halfStaveVol->AddNode(flex1_5cmVol,j,new TGeoTranslation(xPos,-ylen + yPos + 2*rCoolMax + yCPlate + yGlue + yModPlate + 2*ymod + yFlex1 + yFlex2 + yFlex1/2,zpos5cm));
+//       halfStaveVol->AddNode(flex1_5cmVol,fNChips+j,new TGeoTranslation(-xPos,-ylen + yPos + 2*rCoolMax + yCPlate + yGlue + yModPlate + 2*ymod + yFlex1 + yFlex2 + yFlex1/2 +deltaY,zpos5cm));
+//       halfStaveVol->AddNode(flex2_5cmVol,j,new TGeoTranslation(xPos,-ylen + yPos + 2*rCoolMax + yCPlate + yGlue + yModPlate + 2*ymod + 2*yFlex1 + 3*yFlex2/2,zpos5cm));
+//       halfStaveVol->AddNode(flex2_5cmVol,fNChips+j,new TGeoTranslation(-xPos,-ylen + yPos + 2*rCoolMax + yCPlate + yGlue + yModPlate + 2*ymod + 2*yFlex1 + 3*yFlex2/2 +deltaY,zpos5cm));
+//     }
+//     else {
+//       halfStaveVol->AddNode(flex1_5cmVol,j,new TGeoTranslation(xPos,-ylen + yPos + 2*rCoolMax + yCPlate + yGlue + yModPlate + 2*ymod + yFlex1/2,zpos5cm-modGap));
+//       halfStaveVol->AddNode(flex1_5cmVol,fNChips+j,new TGeoTranslation(-xPos,-ylen + yPos + 2*rCoolMax + yCPlate + yGlue + yModPlate + 2*ymod + yFlex1/2 +deltaY,zpos5cm-modGap));
+//       halfStaveVol->AddNode(flex2_5cmVol,j,new TGeoTranslation(xPos,-ylen + yPos + 2*rCoolMax + yCPlate + yGlue + yModPlate +2*ymod + yFlex1 + yFlex2/2,zpos5cm-modGap));
+//       halfStaveVol->AddNode(flex2_5cmVol,fNChips+j,new TGeoTranslation(-xPos,-ylen + yPos + 2*rCoolMax + yCPlate + yGlue + yModPlate + 2*ymod + yFlex1 + yFlex2/2 +deltaY,zpos5cm-modGap));
+
+//       }
+//   }
   
 
-  // Done, return the stave structur
-  return mechStavVol;
+  // Done, return the half stave structure
+  return halfStaveVol;
 }
 
 //________________________________________________________________________
@@ -2123,10 +2203,11 @@ TGeoVolume* AliITSUv1Layer::CreateSpaceFrameOuterB(const Double_t xsta,
 
   switch (fStaveModel) {
     case AliITSUv1::kOBModelDummy:
+    case AliITSUv1::kOBModel0:
       mechStavVol = CreateSpaceFrameOuterBDummy(xsta,mgr);
       break;
     case AliITSUv1::kOBModel1:
-      mechStavVol = CreateSpaceFrameOuterB0(xsta,mgr);
+      mechStavVol = CreateSpaceFrameOuterB1(xsta,mgr);
       break;
     default:
       AliFatal(Form("Unknown stave model %d",fStaveModel));
@@ -2157,10 +2238,10 @@ TGeoVolume* AliITSUv1Layer::CreateSpaceFrameOuterBDummy(const Double_t ,
 }
 
 //________________________________________________________________________
-TGeoVolume* AliITSUv1Layer::CreateSpaceFrameOuterB0(const Double_t xlen,
+TGeoVolume* AliITSUv1Layer::CreateSpaceFrameOuterB1(const Double_t xlen,
                                                    const TGeoManager *mgr){
 //
-// Create the space frame for the Outer Barrel (Model 0)
+// Create the space frame for the Outer Barrel (Model 1)
 //
 // Input:
 //         xlen : X length
@@ -2173,6 +2254,7 @@ TGeoVolume* AliITSUv1Layer::CreateSpaceFrameOuterB0(const Double_t xlen,
 //
 // Created:      20 Dec 2013  Anastasia Barbano
 // Updated:      15 Jan 2014  Mario Sitta
+// Updated:      18 Feb 2014  Mario Sitta
 //
 
 
@@ -2182,40 +2264,41 @@ TGeoVolume* AliITSUv1Layer::CreateSpaceFrameOuterB0(const Double_t xlen,
 
 
   // Local parameters
-  Double_t staveWidth        = 4.2;
-  Double_t staveHeight       = 4.2;
+  Double_t sframeWidth        = fgkOBSpaceFrameWidth;
+  Double_t sframeHeight       = fgkOBSpaceFrameTotHigh - fgkOBHalfStaveYTrans;
 //  Double_t staveSegBoxDW     = 7.5;
 //  Double_t staveSegBoxDH     = 7.1;
-  Double_t staveBeamRadius   = 0.06;
-  Double_t staveLa           = 0.3;
-  Double_t staveHa           = 0.0721979;
-  Double_t staveLb           = 0.37;
-  Double_t staveHb           = 0.0890428;
-  Double_t stavel            = 0.025;
-  Double_t beamSidePhi        = 65;
-  Double_t bottomBeamAngle    = 56.5;
+  Double_t staveBeamRadius   = fgkOBSFrameBeamRadius;
+  Double_t staveLa           = fgkOBSpaceFrameLa;
+  Double_t staveHa           = fgkOBSpaceFrameHa;
+  Double_t staveLb           = fgkOBSpaceFrameLb;
+  Double_t staveHb           = fgkOBSpaceFrameHb;
+  Double_t stavel            = fgkOBSpaceFrameL;
+  Double_t bottomBeamAngle   = fgkOBSFBotBeamAngle;
 //  Double_t dy                 = staveSegBoxDH/2;
-  Double_t triangleHeight     = staveHeight - staveBeamRadius;
-  Double_t halfTheta          = TMath::ATan( 0.5*staveWidth/triangleHeight );
+  Double_t triangleHeight     = sframeHeight - staveBeamRadius;
+  Double_t halfTheta          = TMath::ATan( 0.5*sframeWidth/triangleHeight );
   Double_t alpha              = TMath::Pi()*3./4. - halfTheta/2.;
   Double_t beta               = (TMath::Pi() - 2.*halfTheta)/4.;
-//  Double_t dYTranslation      = (staveHeight/2. -0.5*staveWidth*TMath::Tan(beta)-staveBeamRadius);
-  Double_t distCenterSideDown =  0.5*staveWidth/TMath::Cos(beta);
-  Double_t zact;
-  Double_t zbus;
+//  Double_t dYTranslation      = (sframeHeight/2. -0.5*sframeWidth*TMath::Tan(beta)-staveBeamRadius);
+  Double_t distCenterSideDown =  0.5*sframeWidth/TMath::Cos(beta);
+
   Double_t zlen;
   Double_t seglen;    
 
 
-  zact    = fNChips*fgkOBChipZLength; //active area 
-  zbus    = zact + (fNChips-1)*fgkOBChipGap; 
-  zlen    = zbus/2;
+  zlen = fNModules*fgkOBModuleZLength + (fNModules-1)*fgkOBModuleGap;
+
   seglen  = zlen/10;
 
+  if (gGeoManager->GetVolume("mechStaveVolume")) // Should always be so
+    sframeHeight -= ((TGeoBBox*)gGeoManager->GetVolume("mechStaveVolume")->GetShape())->GetDY()*2.;
+
+
   // First create all needed shapes and volumes
 
-  TGeoBBox *spaceFrame = new TGeoBBox("CarbonFrame",xlen, 2.2, zlen);
-  TGeoBBox *segment    = new TGeoBBox(staveWidth/2,staveHeight/2,seglen/2);
+  TGeoBBox *spaceFrame = new TGeoBBox("CarbonFrame",xlen, 2.2, zlen/2);
+  TGeoBBox *segment    = new TGeoBBox(sframeWidth/2,sframeHeight/2,seglen/2);
 
   TGeoVolume *spaceFrameVol = new TGeoVolume("CarbonFrameVolume",
                                             spaceFrame, medAir);
@@ -2232,7 +2315,7 @@ TGeoVolume* AliITSUv1Layer::CreateSpaceFrameOuterB0(const Double_t xlen,
   TGeoVolume *cfStavTopVol2 = new TGeoVolume("ITSsddCFstavTopCornerVol2",cfStavTop2,medCarbon );
 
   //TGeoTranslation *trTop1 = new TGeoTranslation(0, fgkStaveHeight/2-dy, 0);
-  TGeoTranslation *trTop1 = new TGeoTranslation(0, staveHeight/2, 0);
+  TGeoTranslation *trTop1 = new TGeoTranslation(0, sframeHeight/2, 0);
   
   //--- the 2 side V
   TGeoArb8 *cfStavSide1 = CreateStaveSide( "CFstavSideCornerVol1shape", seglen/2., beta, -1,staveLb, staveHb, stavel);
@@ -2243,10 +2326,10 @@ TGeoVolume* AliITSUv1Layer::CreateSpaceFrameOuterB0(const Double_t xlen,
   
   TGeoCombiTrans *ctSideR = CreateCombiTrans("", distCenterSideDown, 0,alpha*TMath::RadToDeg());
   //AddTranslationToCombiTrans(ctSideR, 0, -dYTranslation-dy, 0);
-  AddTranslationToCombiTrans(ctSideR, 0, staveHeight/2-2.85/*2.765250*//*triangleHeight*/, 0);
+  AddTranslationToCombiTrans(ctSideR, 0, sframeHeight/2-2.85/*2.765250*//*triangleHeight*/, 0);
   TGeoCombiTrans *ctSideL = CreateCombiTrans("", distCenterSideDown,0,-alpha*TMath::RadToDeg());
   //AddTranslationToCombiTrans(ctSideL, 0, -dYTranslation-dy, 0);
-  AddTranslationToCombiTrans(ctSideL, 0, staveHeight/2-2.85/*triangleHeight*/, 0);
+  AddTranslationToCombiTrans(ctSideL, 0, sframeHeight/2-2.85/*triangleHeight*/, 0);
 
   segmentVol->AddNode(cfStavTopVol1,1,trTop1);
   segmentVol->AddNode(cfStavTopVol2,1,trTop1);
@@ -2258,8 +2341,8 @@ TGeoVolume* AliITSUv1Layer::CreateSpaceFrameOuterB0(const Double_t xlen,
 
   //--- The beams
   // Beams on the sides
-  Double_t beamPhiPrime = TMath::ASin(1./TMath::Sqrt( (1+TMath::Sin(2*beta)*TMath::Sin(2*beta)/(TanD(beamSidePhi)*TanD(beamSidePhi))) ));
-  Double_t beamLength = TMath::Sqrt( staveHeight*staveHeight/( TMath::Sin(beamPhiPrime)*TMath::Sin(beamPhiPrime))+ staveWidth*staveWidth/4.)-staveLa/2-staveLb/2;
+  Double_t beamPhiPrime = TMath::ASin(1./TMath::Sqrt( (1+TMath::Sin(2*beta)*TMath::Sin(2*beta)/(TanD(fgkOBSFrameBeamSidePhi)*TanD(fgkOBSFrameBeamSidePhi))) ));
+  Double_t beamLength = TMath::Sqrt( sframeHeight*sframeHeight/( TMath::Sin(beamPhiPrime)*TMath::Sin(beamPhiPrime))+ sframeWidth*sframeWidth/4.)-staveLa/2-staveLb/2;
   TGeoTubeSeg *sideBeamS = new TGeoTubeSeg(0, staveBeamRadius,beamLength/2.,0, 180);
   TGeoVolume *sideBeam = new TGeoVolume("ITSsddCFSideBeamVol", sideBeamS,medCarbon);
 
@@ -2289,24 +2372,24 @@ TGeoVolume* AliITSUv1Layer::CreateSpaceFrameOuterB0(const Double_t xlen,
   beamTransf[7] = new TGeoCombiTrans(-0.5*triangleHeight* TMath::Tan(halfTheta),staveBeamRadius/2.,3*seglen/8,beamRot4);
 
   //--- Beams of the bottom
-  TGeoTubeSeg *bottomBeam1 = new TGeoTubeSeg(0, staveBeamRadius,staveWidth/2.-staveLb/3, 0, 180);
+  TGeoTubeSeg *bottomBeam1 = new TGeoTubeSeg(0, staveBeamRadius,sframeWidth/2.-staveLb/3, 0, 180);
   TGeoVolume *bottomBeam1Vol = new TGeoVolume("ITSsddBottomBeam1Vol", bottomBeam1, medCarbon);
-  TGeoTubeSeg *bottomBeam2 = new TGeoTubeSeg(0, staveBeamRadius,staveWidth/2.-staveLb/3, 0, 90);
+  TGeoTubeSeg *bottomBeam2 = new TGeoTubeSeg(0, staveBeamRadius,sframeWidth/2.-staveLb/3, 0, 90);
   TGeoVolume *bottomBeam2Vol = new TGeoVolume("ITSsddBottomBeam2Vol",bottomBeam2, medCarbon);
-  TGeoTubeSeg *bottomBeam3 = new TGeoTubeSeg(0, staveBeamRadius,0.5*staveWidth/SinD(bottomBeamAngle) - staveLb/3, 0, 180);
+  TGeoTubeSeg *bottomBeam3 = new TGeoTubeSeg(0, staveBeamRadius,0.5*sframeWidth/SinD(bottomBeamAngle) - staveLb/3, 0, 180);
   TGeoVolume *bottomBeam3Vol = new TGeoVolume("ITSsddBottomBeam3Vol", bottomBeam3, medCarbon);
   TGeoRotation *bottomBeamRot1 = new TGeoRotation("", 90, 90,  90);
   TGeoRotation *bottomBeamRot2 = new TGeoRotation("",-90, 90, -90);
 
-  TGeoCombiTrans *bottomBeamTransf1 = new TGeoCombiTrans("",0,-(staveHeight/2-staveBeamRadius),0, bottomBeamRot1);
-  TGeoCombiTrans *bottomBeamTransf2 = new TGeoCombiTrans(0,-(staveHeight/2-staveBeamRadius),-seglen/2, bottomBeamRot1);
-  TGeoCombiTrans *bottomBeamTransf3 = new TGeoCombiTrans(0,-(staveHeight/2-staveBeamRadius), seglen/2, bottomBeamRot2);
+  TGeoCombiTrans *bottomBeamTransf1 = new TGeoCombiTrans("",0,-(sframeHeight/2-staveBeamRadius),0, bottomBeamRot1);
+  TGeoCombiTrans *bottomBeamTransf2 = new TGeoCombiTrans(0,-(sframeHeight/2-staveBeamRadius),-seglen/2, bottomBeamRot1);
+  TGeoCombiTrans *bottomBeamTransf3 = new TGeoCombiTrans(0,-(sframeHeight/2-staveBeamRadius), seglen/2, bottomBeamRot2);
   // be careful for beams #3: when "reading" from -z to +z and 
   // from the bottom of the stave, it should draw a Lambda, and not a V
   TGeoRotation *bottomBeamRot4 = new TGeoRotation("", -90, bottomBeamAngle, -90);
   TGeoRotation *bottomBeamRot5 = new TGeoRotation("" ,-90,-bottomBeamAngle, -90);
-  TGeoCombiTrans *bottomBeamTransf4 = new TGeoCombiTrans(0,-(staveHeight/2-staveBeamRadius),-seglen/4,bottomBeamRot4);
-  TGeoCombiTrans *bottomBeamTransf5 = new TGeoCombiTrans(0,-(staveHeight/2-staveBeamRadius),seglen/4, bottomBeamRot5);
+  TGeoCombiTrans *bottomBeamTransf4 = new TGeoCombiTrans(0,-(sframeHeight/2-staveBeamRadius),-seglen/4,bottomBeamRot4);
+  TGeoCombiTrans *bottomBeamTransf5 = new TGeoCombiTrans(0,-(sframeHeight/2-staveBeamRadius),seglen/4, bottomBeamRot5);
 
   cfStavTopVol1->SetLineColor(35);
   cfStavTopVol2->SetLineColor(35);
@@ -2344,9 +2427,9 @@ TGeoVolume* AliITSUv1Layer::CreateSpaceFrameOuterB0(const Double_t xlen,
 
 //________________________________________________________________________
 TGeoVolume* AliITSUv1Layer::CreateChipInnerB(const Double_t xsta,
-                                              const Double_t ysta,   
-                                              const Double_t zsta,
-                                              const TGeoManager *mgr){
+                                            const Double_t ysta,   
+                                            const Double_t zsta,
+                                            const TGeoManager *mgr){
 //
 // Creates the actual Chip
 //
@@ -2409,29 +2492,27 @@ TGeoVolume* AliITSUv1Layer::CreateChipInnerB(const Double_t xsta,
 }
 
 //________________________________________________________________________
-TGeoVolume* AliITSUv1Layer::CreateChipOuterB(const Double_t xsta,
-                                              const Double_t ysta,   
-                                              const Double_t zmod,
-                                              const TGeoManager *mgr){
+TGeoVolume* AliITSUv1Layer::CreateModuleOuterB(const TGeoManager *mgr){
 //
-// Creates the actual Chip
+// Creates the OB Module: HIC + FPC + Carbon plate
 //
 // Input:
-//         xsta,ysta,zsta : the half stave dimensions
 //         mgr  : the GeoManager (used only to get the proper material)
 //
 // Output:
 //
 // Return:
+//         the module as a TGeoVolume
 //
 // Created:      18 Dec 2013  M. Sitta, A. Barbano
+// Updated:      26 Feb 2014  M. Sitta
 //
 
 
   char volname[30];
 
-  Double_t xGap  = 0.01; 
-  Double_t zGap  = 0.01;
+  Double_t xGap  = fgkOBChipXGap;
+  Double_t zGap  = fgkOBChipZGap;
 
   Double_t xlen, ylen, zlen;
   Double_t xpos, ypos, zpos;
@@ -2439,46 +2520,117 @@ TGeoVolume* AliITSUv1Layer::CreateChipOuterB(const Double_t xsta,
   // First create all needed shapes
 
   // The chip
-  TGeoBBox *chip = new TGeoBBox(xsta,  ysta, zmod/2);
+  xlen = (fgkOBHalfStaveWidth/2-xGap/2)/fgkOBNChipRows;
+  ylen = fSensorThick; // TO BE CHECKED
+  zlen = (fgkOBModuleZLength - (fgkOBChipsPerRow-1)*zGap)/(2*fgkOBChipsPerRow);
+  TGeoBBox *chip = new TGeoBBox("OBChip", xlen, ylen, zlen);
 
-  // The sensor
-  xlen = 0.5*(chip->GetDX()-xGap/2);
-  //xlen = 0.5*1.5;
-  ylen = ysta;
-  zlen = (2*chip->GetDZ()-6*zGap)/14;
-  TGeoBBox *sensor = new TGeoBBox(xlen, ylen, zlen);
+  // The module carbon plate
+  xlen = fgkOBHalfStaveWidth/2;
+  ylen = fgkOBCarbonPlateThick/2;
+  zlen = fgkOBModuleZLength/2;
+  TGeoBBox *modPlate = new TGeoBBox("CarbonPlate", xlen, ylen, zlen);
+
+  // The glue
+  ylen = fgkOBGlueThick/2;
+  TGeoBBox *glue = new TGeoBBox("Glue", xlen, ylen, zlen);
+
+  // The flex cables
+  ylen = fgkOBFlexCableAlThick/2;
+  TGeoBBox *flexAl = new TGeoBBox("FlexAl", xlen, ylen, zlen);
+
+  ylen = fgkOBFlexCableKapThick/2;
+  TGeoBBox *flexKap = new TGeoBBox("FlexKap", xlen, ylen, zlen);
+
+  // The module
+  xlen = fgkOBHalfStaveWidth/2;
+  ylen = chip->GetDY() + modPlate->GetDY() + glue->GetDY() +
+         flexAl->GetDY() + flexKap->GetDY();
+  zlen = fgkOBModuleZLength/2;
+  TGeoBBox *module = new TGeoBBox(xlen,  ylen, zlen);
 
 
   // We have all shapes: now create the real volumes
  
-  TGeoMedium *medSi  = mgr->GetMedium("ITS_SI$");
+  TGeoMedium *medSi       = mgr->GetMedium("ITS_SI$");
+  TGeoMedium *medAir      = mgr->GetMedium("ITS_AIR$");
+  TGeoMedium *medCarbon   = mgr->GetMedium("ITS_CARBON$");
+  TGeoMedium *medGlue     = mgr->GetMedium("ITS_GLUE$");
+  TGeoMedium *medAluminum = mgr->GetMedium("ITS_ALUMINUM$");
+  TGeoMedium *medKapton   = mgr->GetMedium("ITS_KAPTON(POLYCH2)$");
+
   snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSChipPattern(), fLayerNumber);
-  TGeoVolume *modVol = new TGeoVolume(volname, chip, medSi);
-  modVol->SetVisibility(kTRUE);
+  TGeoVolume *chipVol = new TGeoVolume(volname, chip, medSi);
+  //chipVol->SetVisibility(kTRUE);
+  chipVol->SetLineColor(kYellow);
+  //chipVol->SetLineWidth(1);
+  //chipVol->SetTransparency(30);
+  chipVol->SetFillColor(chipVol->GetLineColor());
+  chipVol->SetFillStyle(4000); // 0% transparent
 
   snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSSensorPattern(), fLayerNumber);
-  TGeoVolume *sensVol = new TGeoVolume(volname, sensor, medSi);
-  
-
-
-  // Now build up the chip
-  xpos = -chip->GetDX() + sensor->GetDX();
-  //xpos = -xGap/2 -sensor->GetDX();
-  ypos = -chip->GetDY() + sensor->GetDY();
-  for(Int_t k=0;k<7;k++)   //put 7x2 chip into one chip
-    {
-      zpos = -chip->GetDZ() + sensor->GetDZ() + k*(2*sensor->GetDZ() + zGap);
-      modVol->AddNode(sensVol, k+1, new TGeoTranslation(xpos, ypos, zpos));
-      modVol->AddNode(sensVol, k+2, new TGeoTranslation(-xpos, ypos, zpos));
-    }
-  
+  TGeoVolume *sensVol = new TGeoVolume(volname, chip, medSi);
   //sensVol->SetVisibility(kTRUE);
   sensVol->SetLineColor(kYellow);
   //sensVol->SetLineWidth(1);
   //sensVol->SetTransparency(30);
   sensVol->SetFillColor(sensVol->GetLineColor());
   sensVol->SetFillStyle(4000); // 0% transparent
-  // Done, return the chip
+
+  TGeoVolume *modPlateVol = new TGeoVolume("CarbonPlateVol",
+                                           modPlate, medCarbon);
+  modPlateVol->SetLineColor(kMagenta-8);
+  modPlateVol->SetFillColor(modPlateVol->GetLineColor());
+  modPlateVol->SetFillStyle(4000); // 0% transparent
+
+  TGeoVolume *glueVol = new TGeoVolume("GlueVol", glue, medGlue);
+  glueVol->SetLineColor(kBlack);
+  glueVol->SetFillColor(glueVol->GetLineColor());
+  glueVol->SetFillStyle(4000); // 0% transparent
+
+  TGeoVolume *flexAlVol = new TGeoVolume("FlexAlVol", flexAl, medAluminum);
+  flexAlVol->SetLineColor(kRed);
+  flexAlVol->SetFillColor(flexAlVol->GetLineColor());
+  flexAlVol->SetFillStyle(4000); // 0% transparent
+
+  TGeoVolume *flexKapVol = new TGeoVolume("FlexKapVol", flexKap, medKapton);
+  flexKapVol->SetLineColor(kGreen);
+  flexKapVol->SetFillColor(flexKapVol->GetLineColor());
+  flexKapVol->SetFillStyle(4000); // 0% transparent
+
+  snprintf(volname, 30, "%s%d", AliITSUGeomTGeo::GetITSModulePattern(), fLayerNumber);
+  TGeoVolume *modVol = new TGeoVolume(volname, module, medAir);
+  modVol->SetVisibility(kTRUE);
+  
+
+  // Now build up the module
+  chipVol->AddNode(sensVol,1);
+
+  ypos = -module->GetDY() + modPlate->GetDY();
+  modVol->AddNode(modPlateVol, 1, new TGeoTranslation(0, ypos, 0));
+
+  ypos += (modPlate->GetDY() + glue->GetDY());
+  modVol->AddNode(glueVol, 1, new TGeoTranslation(0, ypos, 0));
+
+  xpos = -module->GetDX() + chip->GetDX();
+  //xpos = -xGap/2 -chip->GetDX();
+  ypos += (glue->GetDY() + chip->GetDY());
+  for(Int_t k=0; k<fgkOBChipsPerRow; k++)   //put 7x2 chip into one module
+    {
+      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());
+  modVol->AddNode(flexAlVol, 1, new TGeoTranslation(0, ypos, 0));
+
+  ypos += (flexAl->GetDY() + flexKap->GetDY());
+  modVol->AddNode(flexKapVol, 1, new TGeoTranslation(0, ypos, 0));
+  
+
+  // Done, return the module
   return modVol;
 }
 
@@ -2518,6 +2670,34 @@ Double_t AliITSUv1Layer::RadiusOfTurboContainer(){
     return -1;
 }
 
+//________________________________________________________________________
+void AliITSUv1Layer::SetNUnits(Int_t u)
+{
+//
+// Sets the number of units in a stave:
+//      for the Inner Barrel: the number of chips per stave
+//      for the Outer Barrel: the number of modules per half stave
+//
+//
+// Input:
+//         u :  the number of units
+//
+// Output:
+//
+// Return:
+//
+// Created:      18 Feb 2013  Mario Sitta (was already SetNChips)
+//
+
+  if (fLayerNumber < fgkNumberOfInnerLayers)
+    fNChips = u;
+  else {
+    fNModules = u;
+    fNChips = fgkOBChipsPerRow;
+  }
+
+}
+
 //________________________________________________________________________
 void AliITSUv1Layer::SetStaveTilt(const Double_t t)
 {
index a363b5e57dae137b414c306d7fb20c497264da1b..fa4939091a78ee7b8532d1f63f81af316d3e3f61 100644 (file)
@@ -26,6 +26,9 @@
 class TGeoVolume;
 
 class AliITSUv1Layer : public AliITSv11Geometry {
+  public:
+  enum {kStave,kHalfStave,kModule,kChip,kNHLevels};
+
   public:
     AliITSUv1Layer();
     AliITSUv1Layer(Int_t debug);
@@ -42,22 +45,28 @@ 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      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      SetNChips(Int_t m)          {fNChips = m;};
-    void      SetRadius(Double_t r)         {fLayRadius = r;};
-    void      SetPhi0(Double_t phi)         {fPhi0 = phi;}
-    void      SetZLength(Double_t z)        {fZLength   = z;};
+    void      SetSensorThick(Double_t t)     {fSensorThick = t;};
+    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;}
+    void      SetZLength(Double_t z)         {fZLength   = z;};
     void      SetChipType(Int_t tp)          {fChipTypeID = tp;}
     void      SetBuildLevel(Int_t buildLevel){fBuildLevel=buildLevel;}
     void      SetStaveModel(AliITSUv1::AliITSUModel_t model) {fStaveModel=model;}
@@ -71,7 +80,7 @@ class AliITSUv1Layer : public AliITSv11Geometry {
     TGeoVolume* CreateStave(const TGeoManager *mgr=gGeoManager);
     //TGeoVolume* CreateChip(Double_t x, Double_t z, const TGeoManager *mgr=gGeoManager);
     TGeoVolume* CreateChipInnerB(Double_t x,Double_t y, Double_t z, const TGeoManager *mgr=gGeoManager);
-    TGeoVolume* CreateChipOuterB(Double_t x,Double_t y, Double_t z, const TGeoManager *mgr=gGeoManager);
+    TGeoVolume* CreateModuleOuterB(const TGeoManager *mgr=gGeoManager);
 
 
     TGeoVolume* CreateStaveStructInnerB(Double_t x,Double_t z, const TGeoManager *mgr=gGeoManager);
@@ -85,10 +94,10 @@ class AliITSUv1Layer : public AliITSv11Geometry {
     TGeoVolume* CreateStaveOuterB(Double_t x, const TGeoManager *mgr=gGeoManager);
     TGeoVolume* CreateStaveModelOuterBDummy(Double_t x, const TGeoManager *mgr=gGeoManager) const;
     TGeoVolume* CreateStaveModelOuterB0(Double_t x, const TGeoManager *mgr=gGeoManager) const;
-    TGeoVolume* CreateStaveModelOuterB1(Double_t x, const TGeoManager *mgr=gGeoManager);
+    TGeoVolume* CreateStaveModelOuterB1(const TGeoManager *mgr=gGeoManager);
     TGeoVolume* CreateSpaceFrameOuterB(Double_t x, const TGeoManager *mgr=gGeoManager);
     TGeoVolume* CreateSpaceFrameOuterBDummy(Double_t x, const TGeoManager *mgr=gGeoManager) const;
-    TGeoVolume* CreateSpaceFrameOuterB0(Double_t x, const TGeoManager *mgr=gGeoManager);
+    TGeoVolume* CreateSpaceFrameOuterB1(Double_t x, const TGeoManager *mgr=gGeoManager);
 
     TGeoArb8* CreateStaveSide(const char *name,
                               Double_t dz, Double_t angle, Double_t xSign,
@@ -106,12 +115,15 @@ class AliITSUv1Layer : public AliITSv11Geometry {
     Double_t  fLayRadius;   // Inner radius of this layer
     Double_t  fZLength;     // Z length of this layer
     Double_t  fSensorThick; // Sensor thickness
-    Double_t  fStaveThick; // Stave thickness
-    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     fNChips;    // Number of chips per stave in this layer
-    UInt_t    fChipTypeID;   // detector type id
+    Double_t  fStaveThick;  // Stave thickness
+    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 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
 
@@ -119,19 +131,49 @@ class AliITSUv1Layer : public AliITSv11Geometry {
 
     // Parameters for the Upgrade geometry
 
+    // General Parameters
+    static const Int_t    fgkNumberOfInnerLayers;// Number of IB Layers
+
     static const Double_t fgkDefaultSensorThick; // Default sensor thickness
-    static const Double_t fgkDefaultStaveThick; // Default stave thickness
+    static const Double_t fgkDefaultStaveThick;  // Default stave thickness
+
+    // Inner Barrel Parameters
+
+    // Outer Barrel Parameters
+    static const Int_t    fgkOBChipsPerRow;      // OB chips per row in module
+    static const Int_t    fgkOBNChipRows;        // OB chip rows in module
 
     static const Double_t fgkOBHalfStaveWidth;   // OB Half Stave Width
-    static const Double_t fgkOBChipGap;        // Gap between OB chips
-    static const Double_t fgkOBFlexCable1Thick;  // Thickness of
-    static const Double_t fgkOBFlexCable2Thick;  // OB flex cables
-    static const Double_t fgkOBBusCable1Thick;   // Thickness of
-    static const Double_t fgkOBBusCable2Thick;   // OB bus cables
+    static const Double_t fgkOBModuleWidth;      // OB Module Width
+    static const Double_t fgkOBModuleGap;        // Gap between OB modules
+    static const Double_t fgkOBChipXGap;         // Gap between OB chips on X
+    static const Double_t fgkOBChipZGap;         // Gap between OB chips on Z
+    static const Double_t fgkOBFlexCableAlThick; // Thickness of FPC Aluminum
+    static const Double_t fgkOBFlexCableKapThick;// Thickness of FPC Kapton
+    static const Double_t fgkOBBusCableAlThick;  // Thickness of Bus Aluminum
+    static const Double_t fgkOBBusCableKapThick; // Thickness of Bus Kapton
     static const Double_t fgkOBCarbonPlateThick; // OB Carbon Plate Thickness
     static const Double_t fgkOBColdPlateThick;   // OB Cold Plate Thickness
     static const Double_t fgkOBGlueThick;        // OB Glue total Thickness
-    static const Double_t fgkOBChipZLength;    // OB Chip Length along Z
+    static const Double_t fgkOBModuleZLength;    // OB Chip Length along Z
+    static const Double_t fgkOBHalfStaveYTrans;  // OB half staves Y transl.
+    static const Double_t fgkOBHalfStaveXOverlap;// OB half staves X overlap
+    static const Double_t fgkOBGraphiteFoilThick;// OB graphite foil thickness
+    static const Double_t fgkOBCoolTubeInnerD;   // OB cooling inner diameter
+    static const Double_t fgkOBCoolTubeThick;    // OB cooling tube thickness
+    static const Double_t fgkOBCoolTubeXDist;    // OB cooling tube separation
+
+    static const Double_t fgkOBSpaceFrameWidth;  // OB Space Frame Width
+    static const Double_t fgkOBSpaceFrameTotHigh;// OB Total Y Height
+    static const Double_t fgkOBSFrameBeamRadius; // OB Space Frame Beam Radius
+    static const Double_t fgkOBSpaceFrameLa;     // Parameters defining...
+    static const Double_t fgkOBSpaceFrameHa;     // ...the V side shape...
+    static const Double_t fgkOBSpaceFrameLb;     // ...of the carbon...
+    static const Double_t fgkOBSpaceFrameHb;     // ...OB Space Frame
+    static const Double_t fgkOBSpaceFrameL;      // OB SF
+    static const Double_t fgkOBSFBotBeamAngle;   // OB SF bottom beam angle
+    static const Double_t fgkOBSFrameBeamSidePhi;// OB SF side beam angle
+
 
   ClassDef(AliITSUv1Layer,0) // ITS Upgrade v1 geometry
 };
index e2828b0f3b58d6d57d48c6b288b15f08184ad3cd..4e9e85689119253fe3bd0068f10c9361cc82553b 100644 (file)
@@ -1542,12 +1542,12 @@ void Detector::MakeAliceCurrent(Int_t AlignResiduals, Bool_t flagTPC) {
     
   } else if (AlignResiduals==2) {
     
-    // tracking errors ... PLUS ... module misalignment
+    // tracking errors ... PLUS ... chip misalignment
     
     // itsRecoParam->SetClusterMisalErrorYBOn(0.0010,0.0030,0.0500,0.0500,0.0020,0.0020);  // [cm]
     // itsRecoParam->SetClusterMisalErrorZBOn(0.0050,0.0050,0.0050,0.0050,0.1000,0.1000);
     
-    //  the ITS modules are misalignment with small gaussian smearings with
+    //  the ITS chips are misalignment with small gaussian smearings with
     //  sigmarphi ~ 8, 10, 10 micron in SPD, SDD, SSD
     
     AddLayer((char*)"spd1", 3.9, 0.0114, TMath::Sqrt(0.0012*0.0012+0.0010*0.0010+0.0008*0.0008), 
@@ -1565,7 +1565,7 @@ void Detector::MakeAliceCurrent(Int_t AlignResiduals, Bool_t flagTPC) {
 
   } else {
       
-      //  the ITS modules are misalignment with small gaussian smearings with
+      //  the ITS chips are misalignment with small gaussian smearings with
       //  sigmarphi ~ 8, 10, 10 micron in SPD, SDD, SSD
       //  unknown in Z ????
 
index a52c2b11fe2bf833acc9080c16c0c2d2ae49ce95..b0868c0e5321870824943d27775e133a4b9cb600 100644 (file)
@@ -1844,12 +1844,12 @@ void DetectorK::MakeAliceCurrent(Int_t AlignResiduals, Bool_t flagTPC) {
     
   } else if (AlignResiduals==2) {
     
-    // tracking errors ... PLUS ... module misalignment
+    // tracking errors ... PLUS ... chip misalignment
     
     // itsRecoParam->SetClusterMisalErrorYBOn(0.0010,0.0030,0.0500,0.0500,0.0020,0.0020);  // [cm]
     // itsRecoParam->SetClusterMisalErrorZBOn(0.0050,0.0050,0.0050,0.0050,0.1000,0.1000);
     
-    //  the ITS modules are misalignment with small gaussian smearings with
+    //  the ITS chips are misalignment with small gaussian smearings with
     //  sigmarphi ~ 8, 10, 10 micron in SPD, SDD, SSD
     
     AddLayer((char*)"spd1", 3.9, 0.0114, TMath::Sqrt(0.0012*0.0012+0.0010*0.0010+0.0008*0.0008), 
@@ -1867,7 +1867,7 @@ void DetectorK::MakeAliceCurrent(Int_t AlignResiduals, Bool_t flagTPC) {
 
   } else {
       
-      //  the ITS modules are misalignment with small gaussian smearings with
+      //  the ITS chips are misalignment with small gaussian smearings with
       //  sigmarphi ~ 8, 10, 10 micron in SPD, SDD, SSD
       //  unknown in Z ????
 
index 1c9ce095d67e7f6dc5ca4981810162de84fb408e..22786adadaa8a9d7be292ec4be0717fb2addc27c 100755 (executable)
@@ -1724,12 +1724,12 @@ void KMCDetector::MakeAliceCurrent(Bool_t flagTPC, Int_t AlignResiduals) {
   } else if (AlignResiduals==2) {
 
     
-    // tracking errors ... PLUS ... module misalignment
+    // tracking errors ... PLUS ... chip misalignment
     
     // itsRecoParam->SetClusterMisalErrorYBOn(0.0010,0.0030,0.0500,0.0500,0.0020,0.0020);  // [cm]
     // itsRecoParam->SetClusterMisalErrorZBOn(0.0050,0.0050,0.0050,0.0050,0.1000,0.1000);
     
-    //  the ITS modules are misalignment with small gaussian smearings with
+    //  the ITS chips are misalignment with small gaussian smearings with
     //  sigmarphi ~ 8, 10, 10 micron in SPD, SDD, SSD
     
     AddLayer((char*)"spd1_its", 3.9, 0.0114, 2.48e-01, TMath::Sqrt(0.0012*0.0012+0.0010*0.0010+0.0008*0.0008), 
@@ -1747,7 +1747,7 @@ void KMCDetector::MakeAliceCurrent(Bool_t flagTPC, Int_t AlignResiduals) {
 
   } else {
       
-      //  the ITS modules are misalignment with small gaussian smearings with
+      //  the ITS chips are misalignment with small gaussian smearings with
       //  sigmarphi ~ 8, 10, 10 micron in SPD, SDD, SSD
       //  unknown in Z ????
 
index 8e5bb729d35388a72e808cd65097f5a574f2dfee..c9d9d292644907e8c323f6e16083118c6d11f249 100644 (file)
@@ -92,7 +92,7 @@ void MakeITSUResMisAlignment()
       new( (*deltas)[idel++] ) AliAlignObjParams(sname.Data(),dummyVID,
                                                 dx,dy,dz,dtht,dpsi,dphi,kTRUE);
       //
-      for (int isn=0;isn<gm0->GetNChipsPerModule(ilr);isn++) {
+      for (int isn=0;isn<gm0->GetNChipsPerStave(ilr);isn++) {
        dx   = sgXMod*gRandom->Gaus();
        dy   = sgYMod*gRandom->Gaus();  
        dz   = sgZMod*gRandom->Gaus();
@@ -100,7 +100,7 @@ void MakeITSUResMisAlignment()
        dpsi = sgPsiMod*gRandom->Gaus(); 
        dphi = sgPhiMod*gRandom->Gaus();        
        int mid = gm0->GetChipIndex(ilr,ild,isn);
-       sname = gm0->GetSymName(mid);
+       sname = gm0->ComposeSymNameChip(ilr,ild,-1,-1,isn);
        new( (*deltas)[idel++] ) AliAlignObjParams(sname.Data(),gm0->ChipVolUID(mid),
                                                   dx,dy,dz,dtht,dpsi,dphi,kTRUE);
       }
index 2ca2f09fa3deaac64fe8cdc4569e3abeb3055f33..84af4dd02c2f809ae87f214a6c488ce8b31e9b5f 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);
index 859d85785b4717ea6c45453d2876e7f3e048519c..ecee86859701bd92367bc631c62e66cb25c505f3 100644 (file)
@@ -26,7 +26,7 @@
 #include "AliITSReconstructor.h"
 #include "AliITSupgrade.h"
 #include "AliITSUpgradeReconstructor.h" //class header
-#include "AliITSDetTypeRec.h"
+#include "AliITSChipTypeRec.h"
 #include "AliITS.h"              //Reconstruct() 
 #include "AliESDEvent.h"           //FillEsd()
 #include "AliRawReader.h"          //Reconstruct() for raw digits
index 1401ccaa285de79105abbab2bc1b0b48d2782502..9ed3e1fe966a380a5b3398b1374034b725a3be7b 100644 (file)
@@ -158,7 +158,7 @@ AliTPCtrack::AliTPCtrack(const AliESDtrack& t, TTreeSRedirector *pcstream) :
   const AliExternalTrackParam  *tpcin = t.GetInnerParam();
   const AliExternalTrackParam  *tpc=(tpcout)?tpcout:tpcin;
   if (!tpc) tpc=&param;
-  Bool_t isOK=recoParam->GetUseOuterDetectors();
+  Bool_t isOK=kTRUE;// RS recoParam->GetUseOuterDetectors();
   if (param.GetCovariance()[0]>kmaxC[0]*kmaxC[0]) isOK=kFALSE;
   if (param.GetCovariance()[2]>kmaxC[1]*kmaxC[1]) isOK=kFALSE;
   if (param.GetCovariance()[5]>kmaxC[2]*kmaxC[2]) isOK=kFALSE;
index 47179c9d836dcd648cf39e51c52ce64024831a4b..93858ade886acf374605859f492d74714e0f5e4d 100644 (file)
@@ -3240,6 +3240,7 @@ void AliTPCtracker::ReadSeeds(const AliESDEvent *const event, Int_t direction)
 
     }
     if (((status&AliESDtrack::kITSout)==0)&&(direction==1)) seed->ResetCovariance(10.); 
+    //RS    if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) == 0 ) seed->ResetCovariance(10.);
     if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) == 0 ) seed->ResetCovariance(10.);
     //if ( direction ==2 && ((status & AliESDtrack::kTPCout) == 0) ) {
     //  fSeeds->AddAt(0,i);
@@ -7914,6 +7915,7 @@ Bool_t AliTPCtracker::IsFindable(AliTPCseed & track){
 
 void AliTPCtracker::AddCovariance(AliTPCseed * seed){
   //
+  return;
   // Adding systematic error estimate to the covariance matrix
   //                !!!! the systematic error for element 4 is in 1/GeV 
   // 03.03.2012     MI changed in respect to the previous versions
index e06f1c2cf610d0cbb733cda16df8ecc4d2b92b1a..0925cbf116b6bc39de8007830c26e2e6a86b1846 100644 (file)
@@ -850,13 +850,14 @@ void AliTRDseedV1::GetCovAt(Double_t x, Double_t *cov) const
   //GetPadLength()*GetPadLength()/12.;
 
   // insert systematic uncertainties
+  /* //RS
   if(fkReconstructor){
     Double_t sys[15]; memset(sys, 0, 15*sizeof(Double_t));
     fkReconstructor->GetRecoParam()->GetSysCovMatrix(sys);
     sy2 += sys[0];
     sz2 += sys[1];
   }
-
+  */
   // rotate covariance matrix if no RC
   if(!IsRowCross()){
     Double_t t2 = GetTilt()*GetTilt();
@@ -2072,7 +2073,7 @@ Bool_t AliTRDseedV1::FitRobust(Bool_t chg)
     if(!attach){ 
       AliWarning("No usable AttachClusters calib object.");
     } else { 
-      kScalePulls = attach->GetScaleCov();//*lyScaler;
+      // kScalePulls = attach->GetScaleCov();//*lyScaler;
     }
     // Retrieve chamber status
     SetChmbGood(calibration->IsChamberGood(fDet));
index 52090dc61af4728ad4ee6d2f7333def4024b916a..4921d25bf9caf2268b70c5848f4fbfad72e80733 100644 (file)
@@ -145,6 +145,7 @@ AliTRDtrackV1::AliTRDtrackV1(const AliESDtrack &t) : AliKalmanTrack()
   for(int is =0; is<AliPID::kSPECIES; is++) fPID[is] = pid;
 
   const AliExternalTrackParam *par = &t;
+  /* RS
   if (t.GetStatus() & AliESDtrack::kTRDbackup) {
     par = t.GetOuterParam();
     if (!par) {
@@ -152,6 +153,7 @@ AliTRDtrackV1::AliTRDtrackV1(const AliESDtrack &t) : AliKalmanTrack()
       par = &t;
     }
   }
+  */
   Set(par->GetX() 
      ,par->GetAlpha()
      ,par->GetParameter()
index 4ab9e5d8829e64d33abbeac45b3a6f05cc7cb35b..e14f7882395af4c8a0230689dbb798be0f26f7c7 100644 (file)
@@ -582,6 +582,7 @@ Int_t AliTRDtrackerV1::FollowProlongation(AliTRDtrackV1 &t)
       AliDebug(1, Form("Tracklet Det[%d] !OK", tracklet->GetDetector()));
       continue;
     }
+    tracklet->FitRobust();
     Double_t x  = tracklet->GetX();//GetX0();
     // reject tracklets which are not considered for inward refit
     if(x > t.GetX()+AliTRDReconstructor::GetMaxStep()) continue;
@@ -624,6 +625,10 @@ Int_t AliTRDtrackerV1::FollowProlongation(AliTRDtrackV1 &t)
     Double_t cov[3]; tracklet->GetCovAt(x, cov);
     Double_t p[2] = { tracklet->GetY(), tracklet->GetZ()};
     Double_t chi2 = ((AliExternalTrackParam)t).GetPredictedChi2(p, cov);
+    AliInfo(Form("Pl:%d X:%+e : %+e P: %+e %+e Cov:%+e %+e %+e -> dXY: %+e %+e | chi2:%.2f pT:%.2f alp:%.3f",
+                iplane,x,t.GetX(),p[0],p[1],cov[0],cov[1],cov[2],
+                p[0]-t.GetY(),p[1]-t.GetZ(),
+                chi2,t.Pt(),t.GetAlpha()));
     if (chi2 < 1e+10 && ((AliExternalTrackParam&)t).Update(p, cov)){ 
       // Register info to track
       t.SetNumberOfClusters();
diff --git a/test/ppbench/aod.C b/test/ppbench/aod.C
deleted file mode 100644 (file)
index 911379c..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-void aod(){
-
-    gSystem->Load("libANALYSIS");
-    gSystem->Load("libANALYSISalice");
-    gSystem->Load("libCORRFW");
-    gSystem->Load("libPWGHFbase");
-    gSystem->Load("libPWGmuon");
-    gSystem->Load("libESDfilter");
-    gSystem->Load("libTENDER");
-    gSystem->Load("libPWGPP");
-
-    gROOT->Macro("${ALICE_ROOT}/STEER/CreateAODfromESD.C(\"AliESDs.root\",\"AliAOD.root\",\"local://$ALICE_ROOT/OCDB\",\"local://.\")");
-}
diff --git a/test/ppbench/recraw/aod.C b/test/ppbench/recraw/aod.C
deleted file mode 100644 (file)
index 55bfd5f..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-void aod(){
-
-    gSystem->Load("libANALYSIS");
-    gSystem->Load("libANALYSISalice");
-    gSystem->Load("libCORRFW");
-    gSystem->Load("libPWGHFbase");
-    gSystem->Load("libPWGmuon");
-    gSystem->Load("libESDfilter");
-    gSystem->Load("libTENDER");
-    gSystem->Load("libPWGPP");
-
-    gROOT->Macro("${ALICE_ROOT}/STEER/CreateAODfromESD.C(\"AliESDs.root\",\"AliAODs.root\",\"local://$ALICE_ROOT/OCDB\",\"local://..\",kFALSE)");
-}
diff --git a/test/ppbench/recraw/rec.C b/test/ppbench/recraw/rec.C
deleted file mode 100644 (file)
index 285ef55..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-void rec() {
-
-  AliReconstruction reco;
-
-  reco.SetWriteESDfriend();
-  reco.SetWriteAlignmentData();
-
-  reco.SetInput("raw.root");
-
-  reco.SetNumberOfEventsPerFile(-1); // all events in one single file
-
-  reco.SetDefaultStorage("local://$ALICE_ROOT/OCDB");
-  reco.SetSpecificStorage("GRP/GRP/Data",
-                         Form("local://%s/..",gSystem->pwd()));
-  reco.SetRunPlaneEff(kTRUE);
-
-  reco.SetRunReconstruction("ALL") ;
-  reco.SetRunQA("ALL:ALL") ;
-  
-  reco.SetQARefDefaultStorage("local://$ALICE_ROOT/QAref") ;
-  
-  for (Int_t det = 0 ; det < AliQA::kNDET ; det++) {
-    reco.SetQACycles((AliQAv1::DETECTORINDEX_t)det, 999) ;
-    reco.SetQAWriteExpert((AliQAv1::DETECTORINDEX_t)det) ; 
-  }
-
-  TStopwatch timer;
-  timer.Start();
-  reco.Run();
-  timer.Stop();
-  timer.Print();
-}
index baf8eeb74536a03175eef56823b75ef48e6f5945..ac835873dd06f9f74832bd9ee4047571d7c351ee 100644 (file)
@@ -20,6 +20,10 @@ void sim(Int_t nev=20) {
   simulator.SetSpecificStorage("GRP/GRP/Data",
                               Form("local://%s",gSystem->pwd()));
   
+  simulator.SetSpecificStorage("ITS/Align/Data",
+                              Form("local://%s",gSystem->pwd()));
+
+
   simulator.SetRunQA("ALL:ALL") ; 
   
   simulator.SetQARefDefaultStorage("local://$ALICE_ROOT/QAref") ;