Integrating the Cooked Matrix tracker into the commom reconstruction framework
[u/mrichter/AliRoot.git] / ITS / UPGRADE / AliITSURecoLayer.cxx
index 68f3917..2af9ff1 100644 (file)
@@ -14,20 +14,19 @@ ClassImp(AliITSURecoLayer)
 
 //______________________________________________________
 AliITSURecoLayer::AliITSURecoLayer(const char* name)
-  :fActiveID(-1)
+ :fActiveID(-1)
   ,fNSensors(0)
-  ,fNSensInLadder(0)
-  ,fNLadders(0)
+  ,fNSensorRows(0)
+  ,fNSensorsPerRow(0)
+  ,fSensVIDtoMatrixID(0)
   ,fR(0)
   ,fRMax(0)
   ,fRMin(0)
   ,fZMax(0)
   ,fZMin(0)
-  ,fPhiLadMax(0)
-  ,fPhiLadMin(0)
   ,fPhiOffs(0)
   ,fSensDZInv(0)
-  ,fDPhiLadInv(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)
-  ,fNSensInLadder(0)
-  ,fNLadders(0)
+  ,fNSensorRows(0)
+  ,fNSensorsPerRow(0)
+  ,fSensVIDtoMatrixID(0)
   ,fR(0)
   ,fRMax(0)
   ,fRMin(0)
   ,fZMax(0)
   ,fZMin(0)
-  ,fPhiLadMax(0)
-  ,fPhiLadMin(0)
   ,fPhiOffs(0)
   ,fSensDZInv(0)
-  ,fDPhiLadInv(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[] fPhiLadMax;
-  delete[] fPhiLadMin;
+  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 %3d 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;
-  fNLadders = fITSGeom->GetNLadders(fActiveID);
-  fNSensInLadder = fITSGeom->GetNDetectors(fActiveID);
-  fNSensors = fNLadders*fNSensInLadder;
-  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;
-  fPhiLadMin = new Double_t[fNLadders];
-  fPhiLadMax = new Double_t[fNLadders];
-  fSensDZInv = 0;
-  fDPhiLadInv = fNLadders/TwoPi();
-  //
-  for (int ild=0;ild<fNLadders;ild++) {
-    fPhiLadMin[ild] = 1e9;
-    fPhiLadMax[ild] = -1e9;
-    //
-    for (int idt=0;idt<fNSensInLadder;idt++) {
-      AliITSURecoSens* sens = new AliITSURecoSens(fNSensors++);
-      fSensors[ild*fNSensInLadder+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,140 +139,149 @@ 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      (fPhiLadMin[ild]>1e8)  fPhiLadMin[ild] = phiMin;
-      else if (!OKforPhiMin(fPhiLadMin[ild],phiMin)) fPhiLadMin[ild] = phiMin;
-      if      (fPhiLadMax[ild]<-1e8) fPhiLadMax[ild] = phiMax;
-      else if (!OKforPhiMax(fPhiLadMax[ild],phiMax)) fPhiLadMax[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 = fNSensInLadder>0 ? fSensDZInv/(fNSensInLadder-1)/fNLadders : 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()/fNLadders;
-  for (int ild=0;ild<fNLadders;ild++) {
-    for (int idt=0;idt<fNSensInLadder;idt++) {
-      AliITSURecoSens* sens = GetSensor(ild,idt);
-      //
-      for (int ils=-1;ils<=1;ils++) {
-       int ildN = ild+ils;  // ladders of neighbouring sensors
-       if (ildN<0) ildN = fNLadders-1; else if (ildN==fNLadders) ildN = 0;
-       for (int ids=-1;ids<=1;ids++) {
-         int idtN = idt+ids;
-         if (idtN<0 || idtN==fNSensInLadder || (ids==0&&ils==0)) continue;
-         AliITSURecoSens* sensN = GetSensor(ildN,idtN); // potential neighbor
-         int neighbID = ildN*fNSensInLadder+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
-  } // ladders
   //
 }
-///*
+
 //______________________________________________________
-Int_t AliITSURecoLayer::FindSensors(const double* impPar, AliITSURecoSens *sensors[AliITSURecoSens::kNNeighbors])
+Int_t AliITSURecoLayer::FindSensors(const double* impPar, AliITSURecoSens *sensors[kMaxSensMatching])
 {
   // find sensors having intersection with track
   // impPar contains: lab phi of track, dphi, labZ, dz
   //
-  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 sensInLad = int(z*fSensDZInv);
-  if      (sensInLad<0) sensInLad = 0;
-  else if (sensInLad>=fNSensInLadder) sensInLad = fNSensInLadder-1;
-  //
-  double phi = impPar[0] - fPhiOffs;
-  BringTo02Pi(phi);
-  int ladID = int(phi*fDPhiLadInv);  // ladder id
-  int nsens = 0;
-  //
-  AliITSURecoSens* sensN,*sens = GetSensor(ladID*fNSensInLadder+sensInLad);
-  sensors[nsens++] = sens;
-  //
-  // check neighbours
-  double zMn=impPar[2]-impPar[3], zMx=impPar[2]+impPar[3], phiMn=impPar[0]-impPar[1], phiMx=impPar[0]+impPar[1];
-  BringTo02Pi(phiMn);
-  BringTo02Pi(phiMx);
-  //
-  sensN = GetSensor(sens->GetNeighborID(AliITSURecoSens::kNghbR)); // neighbor on the right (smaller phi)
-  if (sensN && OKforPhiMin(phiMn,sensN->GetPhiMax())) sensors[nsens++] = sensN;
-  //
-  sensN = GetSensor(sens->GetNeighborID(AliITSURecoSens::kNghbTR)); // neighbor on the top right (smaller phi, larger Z)
-  if (sensN && OKforPhiMin(phiMn,sensN->GetPhiMax()) && sensN->GetZMin()<zMx) sensors[nsens++] = sensN;
+  double zMn=impPar[2]-impPar[3], zMx=impPar[2]+impPar[3]; 
+  if (zMn>fZMax) return 0;
+  if (zMx<fZMin) return 0;
   //
-  sensN = GetSensor(sens->GetNeighborID(AliITSURecoSens::kNghbT)); // neighbor on the top (larger Z)
-  if (sensN && sensN->GetZMin()<zMx) sensors[nsens++] = sensN;
+  int zCenID = int((impPar[2]-fZMin)*fSensDZInv);
+  if      (zCenID<0) zCenID = 0;
+  else if (zCenID>=fNSensorsPerRow) zCenID = fNSensorsPerRow-1;
+  double phiCn = impPar[0] - fPhiOffs;
+  //  BringTo02Pi(phiCn); 
+  int rowCenID = int(phiCn*fSensDPhiInv);
   //
-  sensN = GetSensor(sens->GetNeighborID(AliITSURecoSens::kNghbTL)); // neighbor on the top left (larger Z, larger phi)
-  if (sensN && OKforPhiMax(phiMx,sensN->GetPhiMin()) && sensN->GetZMin()<zMx) sensors[nsens++] = sensN;
+  // due to the misalignments the actual sensorID's might be shifted
+  int res = 0;
+  AliITSURecoSens* sensPrev=0, *sens = GetSensor(rowCenID,zCenID);
   //
-  sensN = GetSensor(sens->GetNeighborID(AliITSURecoSens::kNghbL)); // neighbor on the left (larger phi)
-  if (sensN && OKforPhiMax(phiMx,sensN->GetPhiMin())) sensors[nsens++] = sensN;
+  //  printf("Guess: Primary Sensor: phiID: %d zID: %d ->",rowCenID,zCenID); sens->Print();
   //
-  sensN = GetSensor(sens->GetNeighborID(AliITSURecoSens::kNghbBL)); // neighbor on the bottom left (smaller Z, larger phi)
-  if (sensN && OKforPhiMax(phiMx,sensN->GetPhiMin()) && sensN->GetZMax()>zMn) sensors[nsens++] = sensN;
+  while ( (res=sens->CheckCoverage(impPar[0], impPar[2])) ) {
+    if      (res&AliITSURecoSens::kRight) {if (++rowCenID==fNSensorRows) rowCenID=0;} // neighbor on the right (larger phi)
+    else if (res&AliITSURecoSens::kLeft)  {if (--rowCenID<0) rowCenID = fNSensorRows-1;}      // neighbor on the left (smaller phi)
+    if      (res&AliITSURecoSens::kUp)    {if (++zCenID==fNSensorsPerRow) zCenID = fNSensorsPerRow-1;}    // neighbor at larger Z (if any)
+    else if (res&AliITSURecoSens::kDown)  {if (--zCenID<0) zCenID = 0;}               // neighbor at smaller Z (if any)
+    //
+    AliITSURecoSens* sensAlt = GetSensor(rowCenID,zCenID);
+    if (sensAlt==sens || sensAlt==sensPrev) break;  // there is no better neighbor (z edge) or the point falls in dead area
+    //
+    sensPrev = sens;
+    sens = sensAlt;
+  }
+  //  printf("Found: Primary Sensor: phiID: %d zID: %d ->",rowCenID,zCenID); sens->Print();
   //
-  sensN = GetSensor(sens->GetNeighborID(AliITSURecoSens::kNghbB));  // neighbor on the bottom (smaller Z)
-  if (sensN && sensN->GetZMax()>zMn) sensors[nsens++] = sensN;
+  int nFnd = 0;
+  sensors[nFnd++] = sens;
   //
-  sensN = GetSensor(sens->GetNeighborID(AliITSURecoSens::kNghbBR)); // neighbor on the bottom right (smaller Z, smaller phi)
-  if (sensN && OKforPhiMin(phiMn,sensN->GetPhiMax()) && sensN->GetZMax()>zMn) sensors[nsens++] = sensN;
+  double phiMn = impPar[0]-impPar[1], phiMx = impPar[0]+impPar[1];
+  BringTo02Pi(phiMn);
+  BringTo02Pi(phiMx);
   //
-  return nsens;
+  const int kNNeighb = 8;
+  const int kCheckNeighb[2][kNNeighb] = { // phi and Z neighbours to check
+    { 1, 1, 0,-1,-1,-1, 0, 1},
+    { 0, 1, 1, 1, 0,-1,-1,-1}
+  };
+  //  
+  //  printf("Search: %+.4f %+.4f | %+.4f %+.4f\n",phiMn,phiMx, zMn,zMx);
+  for (int inb=kNNeighb;inb--;) {
+    int idz = kCheckNeighb[1][inb];
+    int iz   = zCenID   + idz;
+    //    printf("#%d  dp:%+d dz:%+d IZ: %d\n",inb, kCheckNeighb[0][inb], kCheckNeighb[1][inb], iz);
+    //
+    if (iz<0 || iz>=fNSensorsPerRow) continue;
+    int idphi = kCheckNeighb[0][inb];
+    int iphi = rowCenID + idphi;
+    if      (iphi<0) iphi += fNSensorRows;
+    else if (iphi>=fNSensorRows) iphi -= fNSensorRows;
+    sens = GetSensor(iphi,iz);
+    //
+    if      (idz>0) {if (zMx<sens->GetZMin()) continue;}
+    else if (idz<0) {if (zMn>sens->GetZMax()) continue;}
+    //
+    // Z range matches
+    if      (idphi>0) {if (!OKforPhiMin(sens->GetPhiMin(),phiMx)) continue;}
+    else if (idphi<0) {if (!OKforPhiMax(sens->GetPhiMax(),phiMn)) continue;}
+    //
+    //    printf("Add %d\n",nFnd);
+    sensors[nFnd++] = sens;
+    if (nFnd==kMaxSensMatching) break;
+  }
+  return nFnd;
 }
+
 //*/
 /*
 Int_t AliITSURecoLayer::FindSensors(const double* impPar, AliITSURecoSens *sensors[AliITSURecoSens::kNNeighbors],int mcLab)
@@ -294,10 +302,10 @@ Int_t AliITSURecoLayer::FindSensors(const double* impPar, AliITSURecoSens *senso
       }
     }
     if (nFnd>0) {
-      Int_t layS,ladS,sensS;
+      Int_t layS,staS,sensS;
       for (int is=0;is<nFnd;is++) {
-       fITSGeom->GetModuleId(fndSens[is],layS,ladS,sensS);
-       printf("SNMC#%d(%d): %d %d %d | ",is,mcLab,layS,ladS,sensS); GetSensorFromID(fndSens[is])->Print();
+       fITSGeom->GetChipId(fndSens[is],layS,staS,sensS);
+       printf("SNMC#%d(%d): %d %d %d | ",is,mcLab,layS,staS,sensS); GetSensorFromID(fndSens[is])->Print();
       }
     }
   }
@@ -314,16 +322,16 @@ Int_t AliITSURecoLayer::FindSensors(const double* impPar, AliITSURecoSens *senso
     if (nFnd>0) printf("MissedSens!!!\n");
     return 0; // outside of Z coverage
   }
-  int sensInLad = int(z*fSensDZInv);
-  if      (sensInLad<0) sensInLad = 0;
-  else if (sensInLad>=fNSensInLadder) sensInLad = fNSensInLadder-1;
+  int sensInSta = int(z*fSensDZInv);
+  if      (sensInSta<0) sensInSta = 0;
+  else if (sensInSta>=fNSensInStave) sensInSta = fNSensInStave-1;
   //
   double phi = impPar[0] - fPhiOffs;
   BringTo02Pi(phi);
-  int ladID = int(phi*fDPhiLadInv);  // ladder id
+  int staID = int(phi*fSensDPhiInv);  // stave id
   int nsens = 0;
   //
-  AliITSURecoSens* sensN,*sens = GetSensor(ladID*fNSensInLadder+sensInLad);
+  AliITSURecoSens* sensN,*sens = GetSensor(staID*fNSensInStave+sensInSta);
   sensors[nsens++] = sens;
   //
   // check neighbours
@@ -356,11 +364,11 @@ Int_t AliITSURecoLayer::FindSensors(const double* impPar, AliITSURecoSens *senso
   if (sensN && OKforPhiMin(phiMn,sensN->GetPhiMax()) && sensN->GetZMax()>zMn) sensors[nsens++] = sensN;
   //
   if (mcLab>=0) {
-    Int_t layS,ladS,sensS;
+    Int_t layS,staS,sensS;
     printf("Found %d sensors for phi %.3f : %.3f | Z %.4f %.4f\n", nsens,phiMn,phiMx,zMn,zMx); 
     for (int is=0;is<nsens;is++) {
-      fITSGeom->GetModuleId(sensors[is]->GetID()+fITSGeom->GetFirstModIndex(fActiveID),layS,ladS,sensS);
-      printf("*SNF#%d: %d %d %d | ",is,layS,ladS,sensS); sensors[is]->Print();
+      fITSGeom->GetChipId(sensors[is]->GetID()+fITSGeom->GetFirstModIndex(fActiveID),layS,staS,sensS);
+      printf("*SNF#%d: %d %d %d | ",is,layS,staS,sensS); sensors[is]->Print();
     }
     for (int ism=0;ism<nFnd;ism++) {
       AliITSURecoSens* snMC = GetSensorFromID(fndSens[ism]);
@@ -390,7 +398,7 @@ void AliITSURecoLayer::ProcessClusters(Int_t mode)
     if (vID<curSensID) {AliFatal("Clusters are not sorted in increasing sensorID");}
     if (vID>curSensID) {
       if (curSens) curSens->ProcessClusters(mode);    // prepare clusters for reconstruction
-      curSens   = GetSensor(vID - fITSGeom->GetFirstModIndex(fActiveID));
+      curSens   = GetSensorFromID(vID); //GetSensor(vID - fITSGeom->GetFirstChipIndex(fActiveID));
       curSensID = vID;
       curSens->SetFirstClusterId(icl);
     }
@@ -423,7 +431,7 @@ Int_t  AliITSURecoLayer::Compare(const TObject* obj) const
 AliITSURecoSens* AliITSURecoLayer::GetSensorFromID(Int_t i) const 
 {
   // get sensor from its global id
-  i -= fITSGeom->GetFirstModIndex(fActiveID);
-  if (i<0||i>=fNSensors) AliFatal(Form("Sensor with id=%d is not in layer %d",i+fITSGeom->GetFirstModIndex(fActiveID),fActiveID));
-  return (AliITSURecoSens*)fSensors[i];
+  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 GetSensor(SensVIDtoMatrixID(i));
 }