]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - ITS/AliITStrackerMI.cxx
For Pythia with tune don't switch off MI in ConfigHeavyFlavor
[u/mrichter/AliRoot.git] / ITS / AliITStrackerMI.cxx
index 14584171006849b22b76af3842a2450fcb7f3255..38a162b7957f104220004b3a745e890ad5a34078 100644 (file)
@@ -33,7 +33,6 @@
 #include <TRandom.h>
 #include <TTreeStream.h>
 
-
 #include "AliLog.h"
 #include "AliITSPlaneEff.h"
 #include "AliITSCalibrationSPD.h"
@@ -51,6 +50,7 @@
 #include "AliITSChannelStatus.h"
 #include "AliITSDetTypeRec.h"
 #include "AliITSRecPoint.h"
+#include "AliITSRecPointContainer.h"
 #include "AliITSgeomTGeo.h"
 #include "AliITSReconstructor.h"
 #include "AliITSClusterParam.h"
@@ -61,6 +61,7 @@
 #include "AliITSPlaneEffSSD.h"
 #include "AliITSV0Finder.h"
 #include "AliITStrackerMI.h"
+#include "AliMathBase.h"
 
 ClassImp(AliITStrackerMI)
 
@@ -144,9 +145,11 @@ fPlaneEff(0) {
     Int_t ndet=AliITSgeomTGeo::GetNDetectors(i);
 
     Double_t xyz[3], &x=xyz[0], &y=xyz[1], &z=xyz[2];
-    AliITSgeomTGeo::GetOrigTranslation(i,1,1,xyz); 
+    AliITSgeomTGeo::GetTranslation(i,1,1,xyz); 
     Double_t poff=TMath::ATan2(y,x);
     Double_t zoff=z;
+
+    AliITSgeomTGeo::GetOrigTranslation(i,1,1,xyz);
     Double_t r=TMath::Sqrt(x*x + y*y);
 
     AliITSgeomTGeo::GetOrigTranslation(i,1,2,xyz);
@@ -185,6 +188,7 @@ fPlaneEff(0) {
        
       } // end loop on detectors
     } // end loop on ladders
+    fForceSkippingOfLayer[i] = 0;
   } // end loop on layers
 
 
@@ -201,22 +205,33 @@ fPlaneEff(0) {
                     AliITSReconstructor::GetRecoParam()->GetSigmaZVdef()}; 
   SetVertex(xyzVtx,ersVtx);
 
-  for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fLayersNotToSkip[i]=AliITSRecoParam::GetLayersNotToSkip(i);
   fLastLayerToTrackTo=AliITSRecoParam::GetLastLayerToTrackTo();
   for (Int_t i=0;i<100000;i++){
     fBestTrackIndex[i]=0;
   }
 
   // store positions of centre of SPD modules (in z)
+  //  The convetion is that fSPDdetzcentre is ordered from -z to +z
   Double_t tr[3];
-  AliITSgeomTGeo::GetTranslation(1,1,1,tr);
-  fSPDdetzcentre[0] = tr[2];
-  AliITSgeomTGeo::GetTranslation(1,1,2,tr);
-  fSPDdetzcentre[1] = tr[2];
-  AliITSgeomTGeo::GetTranslation(1,1,3,tr);
-  fSPDdetzcentre[2] = tr[2];
-  AliITSgeomTGeo::GetTranslation(1,1,4,tr);
-  fSPDdetzcentre[3] = tr[2];
+  if (tr[2]<0) { // old geom (up to v5asymmPPR)
+    AliITSgeomTGeo::GetTranslation(1,1,1,tr);
+    fSPDdetzcentre[0] = tr[2];
+    AliITSgeomTGeo::GetTranslation(1,1,2,tr);
+    fSPDdetzcentre[1] = tr[2];
+    AliITSgeomTGeo::GetTranslation(1,1,3,tr);
+    fSPDdetzcentre[2] = tr[2];
+    AliITSgeomTGeo::GetTranslation(1,1,4,tr);
+    fSPDdetzcentre[3] = tr[2];
+  } else { // new geom (from v11Hybrid)
+    AliITSgeomTGeo::GetTranslation(1,1,4,tr);
+    fSPDdetzcentre[0] = tr[2];
+    AliITSgeomTGeo::GetTranslation(1,1,3,tr);
+    fSPDdetzcentre[1] = tr[2];
+    AliITSgeomTGeo::GetTranslation(1,1,2,tr);
+    fSPDdetzcentre[2] = tr[2];
+    AliITSgeomTGeo::GetTranslation(1,1,1,tr);
+    fSPDdetzcentre[3] = tr[2];
+  }
 
   fUseTGeo = AliITSReconstructor::GetRecoParam()->GetUseTGeoInTracker();
   if(AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance() && fUseTGeo!=1 && fUseTGeo!=3) {
@@ -309,13 +324,6 @@ AliITStrackerMI::~AliITStrackerMI()
   if(fPlaneEff) delete fPlaneEff;
 }
 //------------------------------------------------------------------------
-void AliITStrackerMI::SetLayersNotToSkip(const Int_t *l) {
-  //--------------------------------------------------------------------
-  //This function set masks of the layers which must be not skipped
-  //--------------------------------------------------------------------
-  for (Int_t i=0; i<AliITSgeomTGeo::GetNLayers(); i++) fLayersNotToSkip[i]=l[i];
-}
-//------------------------------------------------------------------------
 void AliITStrackerMI::ReadBadFromDetTypeRec() {
   //--------------------------------------------------------------------
   //This function read ITS bad detectors, chips, channels from AliITSDetTypeRec
@@ -354,22 +362,23 @@ Int_t AliITStrackerMI::LoadClusters(TTree *cTree) {
   //--------------------------------------------------------------------
   //This function loads ITS clusters
   //--------------------------------------------------------------------
-  TBranch *branch=cTree->GetBranch("ITSRecPoints");
-  if (!branch) { 
-    Error("LoadClusters"," can't get the branch !\n");
-    return 1;
+  TClonesArray *clusters = NULL;
+  AliITSRecPointContainer* rpcont=AliITSRecPointContainer::Instance();
+  clusters=rpcont->FetchClusters(0,cTree);
+  if(!(rpcont->IsSPDActive() || rpcont->IsSDDActive() || rpcont->IsSSDActive())){
+      AliError("ITS is not in a known running configuration: SPD, SDD and SSD are not active");
+      return 1;
   }
-
-  static TClonesArray dummy("AliITSRecPoint",10000), *clusters=&dummy;
-  branch->SetAddress(&clusters);
-
   Int_t i=0,j=0,ndet=0;
   Int_t detector=0;
   for (i=0; i<AliITSgeomTGeo::GetNLayers(); i++) {
     ndet=fgLayers[i].GetNdetectors();
     Int_t jmax = j + fgLayers[i].GetNladders()*ndet;
     for (; j<jmax; j++) {           
-      if (!cTree->GetEvent(j)) continue;
+      //      if (!cTree->GetEvent(j)) continue;
+      clusters = rpcont->UncheckedGetClusters(j);
+      if(!clusters)continue;
       Int_t ncl=clusters->GetEntriesFast();
       SignDeltas(clusters,GetZ());
  
@@ -378,12 +387,17 @@ Int_t AliITStrackerMI::LoadClusters(TTree *cTree) {
         detector=c->GetDetectorIndex();
 
        if (!c->Misalign()) AliWarning("Can't misalign this cluster !");
-
-        fgLayers[i].InsertCluster(new AliITSRecPoint(*c));
+       
+       Int_t retval = fgLayers[i].InsertCluster(new AliITSRecPoint(*c));
+       if(retval) {
+         AliWarning(Form("Too many clusters on layer %d!",i));
+         break;  
+       } 
       }
-      clusters->Delete();
+
       // add dead zone "virtual" cluster in SPD, if there is a cluster within 
       // zwindow cm from the dead zone      
+      //  This method assumes that fSPDdetzcentre is ordered from -z to +z
       if (i<2 && AliITSReconstructor::GetRecoParam()->GetAddVirtualClustersInDeadZone()) {
        for (Float_t xdead = 0; xdead < AliITSRecoParam::GetSPDdetxlength(); xdead += (i+1.)*AliITSReconstructor::GetRecoParam()->GetXPassDeadZoneHits()) {
          Int_t lab[4]   = {0,0,0,detector};
@@ -423,7 +437,8 @@ Int_t AliITStrackerMI::LoadClusters(TTree *cTree) {
     fgLayers[i].SortClusters();
   }
 
-  dummy.Clear();
+  // check whether we have to skip some layers
+  SetForceSkippingOfLayer();
 
   return 0;
 }
@@ -479,6 +494,7 @@ Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
   // The clusters must be already loaded !
   //--------------------------------------------------------------------
 
+  AliDebug(2,Form("SKIPPING %d %d %d %d %d %d",ForceSkippingOfLayer(0),ForceSkippingOfLayer(1),ForceSkippingOfLayer(2),ForceSkippingOfLayer(3),ForceSkippingOfLayer(4),ForceSkippingOfLayer(5)));
 
   fTrackingPhase="Clusters2Tracks";
 
@@ -496,11 +512,12 @@ Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
     }
   }
   // temporary
-
+  Int_t noesd = 0;
   {/* Read ESD tracks */
     Double_t pimass = TDatabasePDG::Instance()->GetParticle(211)->Mass();
     Int_t nentr=event->GetNumberOfTracks();
-    Info("Clusters2Tracks", "Number of ESD tracks: %d\n", nentr);
+    noesd=nentr;
+    //    Info("Clusters2Tracks", "Number of ESD tracks: %d\n", nentr);
     while (nentr--) {
       AliESDtrack *esd=event->GetTrack(nentr);
       //  ---- for debugging:
@@ -624,7 +641,7 @@ Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
   fCoefficients=0;
   DeleteTrksMaterialLUT();
 
-  Info("Clusters2Tracks","Number of prolonged tracks: %d\n",ntrk);
+  AliInfo(Form("Number of prolonged tracks: %d out of %d ESD tracks",ntrk,noesd));
 
   fTrackingPhase="Default";
   
@@ -638,7 +655,7 @@ Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
   //--------------------------------------------------------------------
   fTrackingPhase="PropagateBack";
   Int_t nentr=event->GetNumberOfTracks();
-  Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
+  //  Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
 
   Int_t ntrk=0;
   for (Int_t i=0; i<nentr; i++) {
@@ -659,6 +676,7 @@ Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
 
      ResetTrackToFollow(*t);
 
+     /*
      // propagate to vertex [SR, GSI 17.02.2003]
      // Start Time measurement [SR, GSI 17.02.2003], corrected by I.Belikov
      if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
@@ -666,7 +684,17 @@ Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
         fTrackToFollow.StartTimeIntegral();
        // from vertex to outside pipe
        CorrectForPipeMaterial(&fTrackToFollow,"outward");
+       }*/
+     // Start time integral and add distance from current position to vertex 
+     Double_t xyzTrk[3],xyzVtx[3]={GetX(),GetY(),GetZ()};
+     fTrackToFollow.GetXYZ(xyzTrk);
+     Double_t dst2 = 0.;
+     for (Int_t icoord=0; icoord<3; icoord++) {  
+       Double_t di = xyzTrk[icoord] - xyzVtx[icoord];
+       dst2 += di*di; 
      }
+     fTrackToFollow.StartTimeIntegral();
+     fTrackToFollow.AddTimeStep(TMath::Sqrt(dst2));
 
      fTrackToFollow.ResetCovariance(10.); fTrackToFollow.ResetClusters();
      if (RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&fTrackToFollow,t)) {
@@ -684,7 +712,7 @@ Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
      delete t;
   }
 
-  Info("PropagateBack","Number of back propagated ITS tracks: %d\n",ntrk);
+  AliInfo(Form("Number of back propagated ITS tracks: %d out of %d ESD tracks",ntrk,nentr));
 
   fTrackingPhase="Default";
 
@@ -702,7 +730,7 @@ Int_t AliITStrackerMI::RefitInward(AliESDEvent *event) {
   if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::RefitV02(event,this);
 
   Int_t nentr=event->GetNumberOfTracks();
-  Info("RefitInward", "Number of ESD tracks: %d\n", nentr);
+  //  Info("RefitInward", "Number of ESD tracks: %d\n", nentr);
 
   Int_t ntrk=0;
   for (Int_t i=0; i<nentr; i++) {
@@ -761,7 +789,7 @@ Int_t AliITStrackerMI::RefitInward(AliESDEvent *event) {
     delete t;
   }
 
-  Info("RefitInward","Number of refitted tracks: %d\n",ntrk);
+  AliInfo(Form("Number of refitted tracks: %d out of %d ESD tracks",ntrk,nentr));
 
   fTrackingPhase="Default";
 
@@ -795,6 +823,7 @@ Bool_t AliITStrackerMI::GetTrackPoint(Int_t index, AliTrackPoint& p) const {
   p.SetCharge(cl->GetQ());
   p.SetDriftTime(cl->GetDriftTime());
   p.SetChargeRatio(cl->GetChargeRatio());
+  p.SetClusterType(cl->GetClusterType());
   AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer; 
   switch (l) {
   case 0:
@@ -851,22 +880,23 @@ Bool_t AliITStrackerMI::GetTrackPointTrackingError(Int_t index,
   Float_t tgl = t->GetTgl(); // tgl about const along track
   Float_t expQ = TMath::Max(0.8*t->GetTPCsignal(),30.);
 
-  Float_t errlocalx,errlocalz;
+  Float_t errtrky,errtrkz,covyz;
   Bool_t addMisalErr=kFALSE;
-  AliITSClusterParam::GetError(l,cl,tgl,tgphi,expQ,errlocalx,errlocalz,addMisalErr);
+  AliITSClusterParam::GetError(l,cl,tgl,tgphi,expQ,errtrky,errtrkz,covyz,addMisalErr);
 
   Float_t xyz[3];
   Float_t cov[6];
   cl->GetGlobalXYZ(xyz);
   //  cl->GetGlobalCov(cov);
   Float_t pos[3] = {0.,0.,0.};
-  AliCluster tmpcl((UShort_t)cl->GetVolumeId(),pos[0],pos[1],pos[2],errlocalx*errlocalx,errlocalz*errlocalz,0);
+  AliCluster tmpcl((UShort_t)cl->GetVolumeId(),pos[0],pos[1],pos[2],errtrky*errtrky,errtrkz*errtrkz,covyz);
   tmpcl.GetGlobalCov(cov);
 
   p.SetXYZ(xyz, cov);
   p.SetCharge(cl->GetQ());
   p.SetDriftTime(cl->GetDriftTime());
   p.SetChargeRatio(cl->GetChargeRatio());
+  p.SetClusterType(cl->GetClusterType());
 
   AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer; 
   switch (l) {
@@ -1004,6 +1034,7 @@ void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdin
        // apply correction for material of the current layer
        CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
        vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
+       vtrack->SetDeadZoneProbability(ilayer,1.); // no penalty for missing cluster
        vtrack->SetClIndex(ilayer,-1);
        modstatus = (skip==1 ? 3 : 4); // skipped : out in z
        if(LocalModuleCoord(ilayer,idet,vtrack,xloc,zloc)) { // local module coords
@@ -1084,7 +1115,7 @@ void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdin
          modstatus = 5; // no cls in road
        } else if (dead==1) {
          modstatus = 7; // holes in z in SPD
-       } else if (dead==2 || dead==3) {
+       } else if (dead==2 || dead==3 || dead==4) {
          modstatus = 2; // dead from OCDB
        }
        updatetrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
@@ -1102,12 +1133,16 @@ void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdin
          }
          if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
        }
+       updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
        if (dead) {
-         updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
          if (dead==1) { // dead zone at z=0,+-7cm in SPD
-           updatetrack->SetDeadZoneProbability(GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
+           updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
            deadzoneSPD=kTRUE;
-         }
+         } else if (dead==2 || dead==3) { // dead module or chip from OCDB  
+           updatetrack->SetDeadZoneProbability(ilayer,1.); 
+         } else if (dead==4) { // at least a single dead channel from OCDB  
+           updatetrack->SetDeadZoneProbability(ilayer,0.); 
+         } 
        }
        ntracks[ilayer]++;
       }
@@ -1176,7 +1211,7 @@ void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdin
            modstatus = 1; // found
          } else {             // virtual cluster in dead zone
            updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
-           updatetrack->SetDeadZoneProbability(GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
+           updatetrack->SetDeadZoneProbability(ilayer,GetSPDDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2())));
            modstatus = 7; // holes in z in SPD
          }
 
@@ -1225,21 +1260,8 @@ void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdin
        vtrack->IncrementNSkipped();
        ntracks[ilayer]++;
       }
-
-      // allow one prolongation without clusters for tracks with |tgl|>1.1
-      if (constrain && itrack==0 && TMath::Abs(currenttrack1.GetTgl())>1.1) {  //big theta - for low flux
-       AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
-       // apply correction for material of the current layer
-       CorrectForLayerMaterial(vtrack,ilayer,trackGlobXYZ1,"inward");
-       vtrack->SetClIndex(ilayer,-1);
-       modstatus = 3; // skipped
-       vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
-       vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
-       vtrack->SetNDeadZone(vtrack->GetNDeadZone()+1);
-       ntracks[ilayer]++;
-      }
-     
       
+
     } // loop over tracks in layer ilayer+1
 
     //loop over track candidates for the current layer
@@ -1413,6 +1435,7 @@ fYcs(0),
 fZcs(0),
 fNcs(0),
 fCurrentSlice(-1),
+fZmin(0),
 fZmax(0),
 fYmin(0),
 fYmax(0),
@@ -1420,7 +1443,11 @@ fI(0),
 fImax(0),
 fSkip(0),
 fAccepted(0),
-fRoad(0){
+fRoad(0),
+fMaxSigmaClY(0),
+fMaxSigmaClZ(0),
+fNMaxSigmaCl(3)
+{
   //--------------------------------------------------------------------
   //default AliITSlayer constructor
   //--------------------------------------------------------------------
@@ -1451,6 +1478,7 @@ fYcs(0),
 fZcs(0),
 fNcs(0),
 fCurrentSlice(-1),
+fZmin(0),
 fZmax(0),
 fYmin(0),
 fYmax(0),
@@ -1458,7 +1486,10 @@ fI(0),
 fImax(0),
 fSkip(0),
 fAccepted(0),
-fRoad(0) {
+fRoad(0),
+fMaxSigmaClY(0),
+fMaxSigmaClZ(0),
+fNMaxSigmaCl(3) {
   //--------------------------------------------------------------------
   //main AliITSlayer constructor
   //--------------------------------------------------------------------
@@ -1483,6 +1514,7 @@ fYcs(layer.fYcs),
 fZcs(layer.fZcs),
 fNcs(layer.fNcs),
 fCurrentSlice(layer.fCurrentSlice),
+fZmin(layer.fZmin),
 fZmax(layer.fZmax),
 fYmin(layer.fYmin),
 fYmax(layer.fYmax),
@@ -1490,7 +1522,11 @@ fI(layer.fI),
 fImax(layer.fImax),
 fSkip(layer.fSkip),
 fAccepted(layer.fAccepted),
-fRoad(layer.fRoad){
+fRoad(layer.fRoad),
+fMaxSigmaClY(layer.fMaxSigmaClY),
+fMaxSigmaClZ(layer.fMaxSigmaClZ),
+fNMaxSigmaCl(layer.fNMaxSigmaCl)
+{
   //Copy constructor
 }
 //------------------------------------------------------------------------
@@ -1560,18 +1596,26 @@ Int_t AliITStrackerMI::AliITSlayer::InsertCluster(AliITSRecPoint *cl) {
   //This function adds a cluster to this layer
   //--------------------------------------------------------------------
   if (fN==AliITSRecoParam::GetMaxClusterPerLayer()) {
-    ::Error("InsertCluster","Too many clusters !\n");
     return 1;
   }
   fCurrentSlice=-1;
   fClusters[fN]=cl;
   fN++;
   AliITSdetector &det=GetDetector(cl->GetDetectorIndex());    
+  //AD
+  Double_t nSigmaY=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaY2());
+  Double_t nSigmaZ=fNMaxSigmaCl*TMath::Sqrt(cl->GetSigmaZ2()); 
+  if (cl->GetY()-nSigmaY<det.GetYmin()) det.SetYmin(cl->GetY()-nSigmaY);
+  if (cl->GetY()+nSigmaY>det.GetYmax()) det.SetYmax(cl->GetY()+nSigmaY);
+  if (cl->GetZ()-nSigmaZ<det.GetZmin()) det.SetZmin(cl->GetZ()-nSigmaZ);
+  if (cl->GetZ()+nSigmaZ>det.GetZmax()) det.SetZmax(cl->GetZ()+nSigmaZ);
+  //AD              
+  /*
   if (cl->GetY()<det.GetYmin()) det.SetYmin(cl->GetY());
   if (cl->GetY()>det.GetYmax()) det.SetYmax(cl->GetY());
   if (cl->GetZ()<det.GetZmin()) det.SetZmin(cl->GetZ());
   if (cl->GetZ()>det.GetZmax()) det.SetZmax(cl->GetZ());
-                            
+  */                
   return 0;
 }
 //------------------------------------------------------------------------
@@ -1584,8 +1628,14 @@ void  AliITStrackerMI::AliITSlayer::SortClusters()
   Float_t *z                = new Float_t[fN];
   Int_t   * index           = new Int_t[fN];
   //
+  fMaxSigmaClY=0.; //AD
+  fMaxSigmaClZ=0.; //AD
+
   for (Int_t i=0;i<fN;i++){
     z[i] = fClusters[i]->GetZ();
+    // save largest errors in y and z for this layer
+    fMaxSigmaClY=TMath::Max(fMaxSigmaClY,TMath::Sqrt(fClusters[i]->GetSigmaY2()));
+    fMaxSigmaClZ=TMath::Max(fMaxSigmaClZ,TMath::Sqrt(fClusters[i]->GetSigmaZ2()));
   }
   TMath::Sort(fN,z,index,kFALSE);
   for (Int_t i=0;i<fN;i++){
@@ -1764,7 +1814,17 @@ SelectClusters(Double_t zmin,Double_t zmax,Double_t ymin, Double_t ymax) {
   //--------------------------------------------------------------------
  
   Double_t circle=2*TMath::Pi()*fR;
-  fYmin = ymin; fYmax =ymax;
+  fYmin = ymin; 
+  fYmax = ymax;
+  fZmin = zmin;
+  fZmax = zmax;
+  // AD
+  // enlarge road in y by maximum cluster error on this layer (3 sigma)
+  fYmin -= fNMaxSigmaCl*fMaxSigmaClY;
+  fYmax += fNMaxSigmaCl*fMaxSigmaClY;
+  fZmin -= fNMaxSigmaCl*fMaxSigmaClZ;
+  fZmax += fNMaxSigmaCl*fMaxSigmaClZ;
+
   Float_t ymiddle = (fYmin+fYmax)*0.5;
   if (ymiddle<fYB[0]) {
     fYmin+=circle; fYmax+=circle; ymiddle+=circle;
@@ -1829,10 +1889,10 @@ SelectClusters(Double_t zmin,Double_t zmax,Double_t ymin, Double_t ymax) {
     }
   }  
   //  
-  fI=FindClusterIndex(zmin); fZmax=zmax;
-  fImax = TMath::Min(FindClusterIndex(zmax)+1,fNcs);
-  fSkip = 0;
-  fAccepted =0;
+  fI        = FindClusterIndex(fZmin); 
+  fImax     = TMath::Min(FindClusterIndex(fZmax)+1,fNcs);
+  fSkip     = 0;
+  fAccepted = 0;
 
   return;
 }
@@ -1859,16 +1919,25 @@ FindDetectorIndex(Double_t phi, Double_t z) const {
   Double_t dz=fZOffset-z;
   Double_t nnz = dz*(fNdetectors-1)*0.5/fZOffset+0.5;
   Int_t nz = (nnz<0 ? -1 : (Int_t)nnz);
-  if (nz>=fNdetectors) return -1;
-  if (nz<0)            return -1;
+  if (nz>=fNdetectors || nz<0) {
+    //printf("ndet %d phi %f z %f  np %d nz %d\n",fNdetectors,phi,z,np,nz);
+    return -1;
+  }
 
   // ad hoc correction for 3rd ladder of SDD inner layer,
   // which is reversed (rotated by pi around local y)
   // this correction is OK only from AliITSv11Hybrid onwards
   if (GetR()>12. && GetR()<20.) { // SDD inner
     if(np==2) { // 3rd ladder
-      nz = (fNdetectors-1) - nz;
-    } 
+      Double_t posMod252[3];
+      AliITSgeomTGeo::GetTranslation(252,posMod252);
+      // check the Z coordinate of Mod 252: if negative 
+      // (old SDD geometry in AliITSv11Hybrid)
+      // the swap of numeration whould be applied
+      if(posMod252[2]<0.){
+       nz = (fNdetectors-1) - nz;
+      } 
+    }
   }
   //printf("ndet %d phi %f z %f  np %d nz %d\n",fNdetectors,phi,z,np,nz);
 
@@ -1886,10 +1955,17 @@ const AliITSRecPoint *AliITStrackerMI::AliITSlayer::GetNextCluster(Int_t &ci,Boo
     Double_t rpi2 = 2.*fR*TMath::Pi();
     for (Int_t i=fI; i<fImax; i++) {
       Double_t y = fY[i];
+      Double_t z = fZ[i];
       if (fYmax<y) y -= rpi2;
       if (fYmin>y) y += rpi2;
       if (y<fYmin) continue;
       if (y>fYmax) continue;
+      // AD
+      // skip clusters that are in "extended" road but they 
+      // 3sigma error does not touch the original road
+      if (z+fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())<fZmin+fNMaxSigmaCl*fMaxSigmaClZ) continue;
+      if (z-fNMaxSigmaCl*TMath::Sqrt(fClusters[i]->GetSigmaZ2())>fZmax-fNMaxSigmaCl*fMaxSigmaClZ) continue;
+      //
       if (fClusters[i]->GetQ()==0&&fSkip==2) continue;
       ci=i;
       if (!test) fI=i+1;
@@ -2186,7 +2262,7 @@ Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
   for(innermostlayer=0; innermostlayer<AliITSgeomTGeo::GetNLayers(); innermostlayer++) {
     if(drphi < fgLayers[innermostlayer].GetR()) break;
   }
-  //printf(" drphi  %f  innermost %d\n",drphi,innermostlayer);
+  AliDebug(2,Form(" drphi  %f  innermost %d",drphi,innermostlayer));
 
   Int_t modstatus=1; // found
   Float_t xloc,zloc;
@@ -2203,6 +2279,7 @@ Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
   for (Int_t ilayer = from; ilayer != to; ilayer += step) {
      AliITSlayer &layer=fgLayers[ilayer];
      Double_t r=layer.GetR();
+
      if (step<0 && xx>r) break;
 
      // material between SSD and SDD, SDD and SPD
@@ -2216,6 +2293,11 @@ Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
      Double_t oldGlobXYZ[3];
      if (!track->GetXYZ(oldGlobXYZ)) return kFALSE;
 
+     // continue if we are already beyond this layer
+     Double_t oldGlobR = TMath::Sqrt(oldGlobXYZ[0]*oldGlobXYZ[0]+oldGlobXYZ[1]*oldGlobXYZ[1]);
+     if(step>0 && oldGlobR > r) continue; // going outward
+     if(step<0 && oldGlobR < r) continue; // going inward
+
      Double_t phi,z;
      if (!track->GetPhiZat(r,phi,z)) return kFALSE;
 
@@ -2237,7 +2319,11 @@ Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
 
      if (idet<0) return kFALSE;
 
+
      const AliITSdetector &det=layer.GetDetector(idet);
+     // only for ITS-SA tracks refit
+     if (ilayer>1 && fTrackingPhase.Contains("RefitInward") && !(track->GetStatus()&AliESDtrack::kTPCin)) track->SetCheckInvariant(kFALSE);
+     // 
      if (!track->Propagate(det.GetPhi(),det.GetR())) return kFALSE;
 
      track->SetDetectorIndex(idet);
@@ -2286,7 +2372,7 @@ Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
         dy = 0.5*(ymax-ymin);
         Int_t dead = CheckDeadZone(track,ilayer,idet,dz,dy,kTRUE);
         if (dead==1) modstatus = 7; // holes in z in SPD
-        if (dead==2 || dead==3) modstatus = 2; // dead from OCDB
+        if (dead==2 || dead==3 || dead==4) modstatus = 2; // dead from OCDB
        }
      }
      
@@ -2331,7 +2417,7 @@ Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
      // cross material
      // add time if going outward
      if(!CorrectForLayerMaterial(track,ilayer,oldGlobXYZ,dir)) return kFALSE;
-                 
+     track->SetCheckInvariant(kTRUE);
   } // end loop on layers
 
   if (!track->PropagateTo(xx,0.,0.)) return kFALSE;
@@ -2433,12 +2519,33 @@ Double_t AliITStrackerMI::GetNormalizedChi2(AliITStrackMI * track, Int_t mode)
     }
   }
   if (match<0) match=0;
-  Float_t deadzonefactor = (track->GetNDeadZone()>0) ? 3*(1.1-track->GetDeadZoneProbability()):0.;
+
+  // penalty factor for missing points (NDeadZone>0), but no penalty
+  // for layer with deadZoneProb close to 1 (either we wanted to skip layer
+  // or there is a dead from OCDB)
+  Float_t deadzonefactor = 0.; 
+  if (track->GetNDeadZone()>0.) {    
+    Int_t sumDeadZoneProbability=0; 
+    for(Int_t ilay=0;ilay<6;ilay++) {
+      if(track->GetDeadZoneProbability(ilay)>0.) sumDeadZoneProbability++;
+    }
+    Int_t nDeadZoneWithProbNot1=(Int_t)(track->GetNDeadZone())-sumDeadZoneProbability;
+    if(nDeadZoneWithProbNot1>0) {
+      Float_t deadZoneProbability = track->GetNDeadZone()-(Float_t)sumDeadZoneProbability;
+      AliDebug(2,Form("nDeadZone %f sumDZProbability %f nDZWithProbNot1 %f deadZoneProb %f\n",track->GetNDeadZone(),sumDeadZoneProbability,nDeadZoneWithProbNot1,deadZoneProbability));
+      deadZoneProbability /= (Float_t)nDeadZoneWithProbNot1;
+      Float_t one = 1.;
+      deadZoneProbability = TMath::Min(deadZoneProbability,one);
+      deadzonefactor = 3.*(1.1-deadZoneProbability);  
+    }
+  }  
+
   Double_t normchi2 = 2*track->GetNSkipped()+match+deadzonefactor+(1+(2*track->GetNSkipped()+deadzonefactor)/track->GetNumberOfClusters())*
     (chi2)/TMath::Max(double(sum-track->GetNSkipped()),
                                1./(1.+track->GetNSkipped()));     
- return normchi2;
+  AliDebug(2,Form("match %f deadzonefactor %f chi2 %f sum %f skipped\n",match,deadzonefactor,chi2,sum,track->GetNSkipped()));
+  AliDebug(2,Form("NormChi2 %f  cls %d\n",normchi2,track->GetNumberOfClusters()));
+  return normchi2;
 }
 //------------------------------------------------------------------------
 Double_t AliITStrackerMI::GetMatchingChi2(const AliITStrackMI * track1,const AliITStrackMI * track2)
@@ -2488,30 +2595,46 @@ Double_t  AliITStrackerMI::GetSPDDeadZoneProbability(Double_t zpos, Double_t zer
   //
   //  return probability that given point (characterized by z position and error) 
   //  is in SPD dead zone
+  //     This method assumes that fSPDdetzcentre is ordered from -z to +z
   //
   Double_t probability = 0.;
-  Double_t absz = TMath::Abs(zpos);
-  Double_t nearestz = (absz<2.) ? 0.5*(fSPDdetzcentre[1]+fSPDdetzcentre[2]) : 
-                                  0.5*(fSPDdetzcentre[2]+fSPDdetzcentre[3]);
-  if (TMath::Abs(absz-nearestz)>0.25+3.*zerr) return probability;
+  Double_t nearestz = 0.,distz=0.;
+  Int_t    nearestzone = -1;
+  Double_t mindistz = 1000.;
+
+  // find closest dead zone
+  for (Int_t i=0; i<3; i++) {
+    distz=TMath::Abs(zpos-0.5*(fSPDdetzcentre[i]+fSPDdetzcentre[i+1]));
+    if (distz<mindistz) {
+      nearestzone=i;
+      nearestz=0.5*(fSPDdetzcentre[i]+fSPDdetzcentre[i+1]);
+      mindistz=distz;
+    }
+  }
+
+  // too far from dead zone
+  if (TMath::Abs(zpos-nearestz)>0.25+3.*zerr) return probability;
+
+
   Double_t zmin, zmax;   
-  if (zpos<-6.) { // dead zone at z = -7
+  if (nearestzone==0) { // dead zone at z = -7
     zmin = fSPDdetzcentre[0] + 0.5*AliITSRecoParam::GetSPDdetzlength();
     zmax = fSPDdetzcentre[1] - 0.5*AliITSRecoParam::GetSPDdetzlength();
-  } else if (zpos>6.) { // dead zone at z = +7
-    zmin = fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength();
-    zmax = fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength();
-  } else if (absz<2.) { // dead zone at z = 0
+  } else if (nearestzone==1) { // dead zone at z = 0
     zmin = fSPDdetzcentre[1] + 0.5*AliITSRecoParam::GetSPDdetzlength();
     zmax = fSPDdetzcentre[2] - 0.5*AliITSRecoParam::GetSPDdetzlength();
+  } else if (nearestzone==2) { // dead zone at z = +7
+    zmin = fSPDdetzcentre[2] + 0.5*AliITSRecoParam::GetSPDdetzlength();
+    zmax = fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength();
   } else {
     zmin = 0.;
     zmax = 0.;
   }
   // probability that the true z is in the range [zmin,zmax] (i.e. inside 
   // dead zone)
-  probability = 0.5*( TMath::Erf((zpos-zmin)/zerr/TMath::Sqrt(2.)) - 
-                     TMath::Erf((zpos-zmax)/zerr/TMath::Sqrt(2.)) );
+  probability = 0.5*( AliMathBase::ErfFast((zpos-zmin)/zerr/TMath::Sqrt(2.)) - 
+                     AliMathBase::ErfFast((zpos-zmax)/zerr/TMath::Sqrt(2.)) );
+  AliDebug(2,Form("zpos %f +- %f nearestzone %d  zmin zmax %f %f prob %f\n",zpos,zerr,nearestzone,zmin,zmax,probability));
   return probability;
 }
 //------------------------------------------------------------------------
@@ -3123,6 +3246,7 @@ void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mo
   for (Int_t itrack=0;itrack<entries;itrack++){
     AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
     if (track){
+      AliDebug(2,Form("track %d  ncls %d\n",itrack,track->GetNumberOfClusters()));
       track->SetChi2MIP(0,GetNormalizedChi2(track, mode));            
       if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)) 
        chi2[itrack] = track->GetChi2MIP(0);
@@ -3136,6 +3260,7 @@ void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mo
   //
   TMath::Sort(entries,chi2,index,kFALSE);
   besttrack = (AliITStrackMI*)array->At(index[0]);
+  if(besttrack) AliDebug(2,Form("ncls best track %d\n",besttrack->GetNumberOfClusters()));
   if (besttrack&&besttrack->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
     for (Int_t j=0;j<6;j++){
       if (besttrack->GetClIndex(j)>=0){
@@ -3152,7 +3277,8 @@ void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mo
   for (Int_t itrack=0;itrack<entries;itrack++){
     AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
     if (track){      
-      track->SetChi2MIP(0,GetNormalizedChi2(track,mode));            
+      track->SetChi2MIP(0,GetNormalizedChi2(track,mode));
+      AliDebug(2,Form("track %d  ncls %d\n",itrack,track->GetNumberOfClusters()));            
       if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)) 
        chi2[itrack] = track->GetChi2MIP(0)-0*(track->GetNumberOfClusters()+track->GetNDeadZone()); 
       else
@@ -3171,6 +3297,7 @@ void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mo
     TMath::Sort(entries,chi2,index,kFALSE);
     besttrack = (AliITStrackMI*)array->At(index[0]);
     if (besttrack){
+      AliDebug(2,Form("ncls best track %d     %f   %f\n",besttrack->GetNumberOfClusters(),besttrack->GetChi2MIP(0),chi2[index[0]]));
       //
       for (Int_t j=0;j<6;j++){
        if (besttrack->GetNz(j)>0&&besttrack->GetNy(j)>0){
@@ -3523,8 +3650,11 @@ void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
   //--------------------------------------------------------------------
   Int_t tpcLabel=-1; 
      
-  if ( track->GetESDtrack())   tpcLabel =  TMath::Abs(track->GetESDtrack()->GetTPCLabel());
-
+  if (track->GetESDtrack()){
+    tpcLabel = track->GetESDtrack()->GetTPCLabel();
+    ULong_t trStatus=track->GetESDtrack()->GetStatus();
+    if(!(trStatus&AliESDtrack::kTPCin)) tpcLabel=track->GetLabel(); // for ITSsa tracks
+  }
    track->SetChi2MIP(9,0);
    Int_t nwrong=0;
    for (Int_t i=0;i<track->GetNumberOfClusters();i++){
@@ -3533,9 +3663,8 @@ void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
      AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
      Int_t isWrong=1;
      for (Int_t ind=0;ind<3;ind++){
-       if (tpcLabel>0)
-        if (cl->GetLabel(ind)==tpcLabel) isWrong=0;
-       AliDebug(2,Form("icl %d  ilab %d lab %d",i,ind,cl->GetLabel(ind)));
+       if (cl->GetLabel(ind)==TMath::Abs(tpcLabel)) isWrong=0;
+       //AliDebug(2,Form("icl %d  ilab %d lab %d",i,ind,cl->GetLabel(ind)));
      }
      track->SetChi2MIP(9,track->GetChi2MIP(9)+isWrong*(2<<l));
      nwrong+=isWrong;
@@ -3543,10 +3672,10 @@ void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
    Int_t nclusters = track->GetNumberOfClusters();
    if (nclusters > 0) //PH Some tracks don't have any cluster
      track->SetFakeRatio(double(nwrong)/double(nclusters));
-   if (tpcLabel>0){
-     if (track->GetFakeRatio()>wrong) track->SetLabel(-tpcLabel);
-     else
-       track->SetLabel(tpcLabel);
+   if (tpcLabel>0 && track->GetFakeRatio()>wrong) {
+     track->SetLabel(-tpcLabel);
+   } else {
+     track->SetLabel(tpcLabel);
    }
    AliDebug(2,Form(" nls %d wrong %d  label %d  tpcLabel %d\n",nclusters,nwrong,track->GetLabel(),tpcLabel));
    
@@ -3586,17 +3715,17 @@ Double_t AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSR
   //
   // Compute predicted chi2
   //
-  Float_t erry,errz;
+  Float_t erry,errz,covyz;
   Float_t theta = track->GetTgl();
   Float_t phi   = track->GetSnp();
   phi = TMath::Abs(phi)*TMath::Sqrt(1./((1.-phi)*(1.+phi)));
-  AliITSClusterParam::GetError(layer,cluster,theta,phi,track->GetExpQ(),erry,errz);
+  AliITSClusterParam::GetError(layer,cluster,theta,phi,track->GetExpQ(),erry,errz,covyz);
   AliDebug(2,Form(" chi2: tr-cl   %f  %f   tr X %f cl X %f",track->GetY()-cluster->GetY(),track->GetZ()-cluster->GetZ(),track->GetX(),cluster->GetX()));
   // Take into account the mis-alignment (bring track to cluster plane)
   Double_t xTrOrig=track->GetX();
   if (!track->Propagate(xTrOrig+cluster->GetX())) return 1000.;
   AliDebug(2,Form(" chi2: tr-cl   %f  %f   tr X %f cl X %f",track->GetY()-cluster->GetY(),track->GetZ()-cluster->GetZ(),track->GetX(),cluster->GetX()));
-  Double_t chi2 = track->GetPredictedChi2MI(cluster->GetY(),cluster->GetZ(),erry,errz);
+  Double_t chi2 = track->GetPredictedChi2MI(cluster->GetY(),cluster->GetZ(),erry,errz,covyz);
   // Bring the track back to detector plane in ideal geometry
   // [mis-alignment will be accounted for in UpdateMI()]
   if (!track->Propagate(xTrOrig)) return 1000.;
@@ -3612,6 +3741,7 @@ Double_t AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSR
   track->SetNz(layer,nz);
   track->SetSigmaY(layer,erry);
   track->SetSigmaZ(layer, errz);
+  track->SetSigmaYZ(layer,covyz);
   //track->fNormQ[layer] = cluster->GetQ()/TMath::Sqrt(1+theta*theta+phi*phi);
   track->SetNormQ(layer,cluster->GetQ()/TMath::Sqrt((1.+ track->GetTgl()*track->GetTgl())/((1.-track->GetSnp())*(1.+track->GetSnp()))));
   return chi2;
@@ -3643,18 +3773,17 @@ Int_t AliITStrackerMI::UpdateMI(AliITStrackMI* track, const AliITSRecPoint* cl,D
   AliDebug(2,Form(" xtr %f  xcl %f",track->GetX(),cl->GetX()));
 
   if (!track->Propagate(xTrOrig+cl->GetX())) return 0;
-
   
   AliCluster c(*cl);
   c.SetSigmaY2(track->GetSigmaY(layer)*track->GetSigmaY(layer));
   c.SetSigmaZ2(track->GetSigmaZ(layer)*track->GetSigmaZ(layer));
+  c.SetSigmaYZ(track->GetSigmaYZ(layer));
 
 
   Int_t updated = track->UpdateMI(&c,chi2,index);
-
   // Bring the track back to detector plane in ideal geometry
   if (!track->Propagate(xTrOrig)) return 0;
-
   if(!updated) AliDebug(2,"update failed");
   return updated;
 }
@@ -3979,6 +4108,13 @@ Int_t AliITStrackerMI::CorrectForShieldMaterial(AliITStrackMI *t,
     Error("CorrectForShieldMaterial"," Wrong shield name\n");
     return 0;
   }
+
+  // do nothing if we are already beyond the shield
+  Double_t rTrack = TMath::Sqrt(t->GetX()*t->GetX()+t->GetY()*t->GetY());
+  if(dir<0 && rTrack > rToGo) return 1; // going outward
+  if(dir>0 && rTrack < rToGo) return 1; // going inward
+
+
   Double_t xToGo;
   if (!t->GetLocalXat(rToGo,xToGo)) return 0;
 
@@ -4185,6 +4321,36 @@ void AliITStrackerMI::DeleteTrksMaterialLUT() {
   return;
 }
 //------------------------------------------------------------------------
+void AliITStrackerMI::SetForceSkippingOfLayer() {
+  //-----------------------------------------------------------------
+  // Check if we are forced to skip layers
+  // either we set to skip them in RecoParam
+  // or they were off during data-taking
+  //-----------------------------------------------------------------
+
+  const AliEventInfo *eventInfo = GetEventInfo();
+  
+  for(Int_t l=0; l<AliITSgeomTGeo::kNLayers; l++) {
+    fForceSkippingOfLayer[l] = 0;
+    // check reco param
+    if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(l)) fForceSkippingOfLayer[l] = 1;
+    // check run info
+
+    if(eventInfo && 
+       AliITSReconstructor::GetRecoParam()->GetSkipSubdetsNotInTriggerCluster()) {
+      AliDebug(2,Form("GetEventInfo->GetTriggerCluster: %s",eventInfo->GetTriggerCluster()));
+      if(l==0 || l==1)  {
+       if(!strstr(eventInfo->GetTriggerCluster(),"ITSSPD")) fForceSkippingOfLayer[l] = 1;
+      } else if(l==2 || l==3) {
+       if(!strstr(eventInfo->GetTriggerCluster(),"ITSSDD")) fForceSkippingOfLayer[l] = 1; 
+      } else {
+       if(!strstr(eventInfo->GetTriggerCluster(),"ITSSSD")) fForceSkippingOfLayer[l] = 1;
+      } 
+    }
+  }
+  return;
+}
+//------------------------------------------------------------------------
 Int_t AliITStrackerMI::CheckSkipLayer(const AliITStrackMI *track,
                                      Int_t ilayer,Int_t idet) const {
   //-----------------------------------------------------------------
@@ -4192,17 +4358,22 @@ Int_t AliITStrackerMI::CheckSkipLayer(const AliITStrackMI *track,
   // without clusters, because we want to skip the layer.
   // In this case the return value is > 0:
   // return 1: the user requested to skip a layer
-  // return 2: track outside z acceptance of SSD/SDD and will cross both SPD
+  // return 2: track outside z acceptance
   //-----------------------------------------------------------------
 
-  if (AliITSReconstructor::GetRecoParam()->GetLayersToSkip(ilayer)) return 1;
+  if (ForceSkippingOfLayer(ilayer)) return 1;
+
+  Int_t innerLayCanSkip=0; // was 2, changed on 05.11.2009
 
-  if (idet<0 && ilayer>1 && AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance()) {
+  if (idet<0 &&  // out in z
+      ilayer>innerLayCanSkip && 
+      AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance()) {
     // check if track will cross SPD outer layer
     Double_t phiAtSPD2,zAtSPD2;
     if (track->GetPhiZat(fgLayers[1].GetR(),phiAtSPD2,zAtSPD2)) {
       if (TMath::Abs(zAtSPD2)<2.*AliITSRecoParam::GetSPDdetzlength()) return 2;
     }
+    return 2; // always allow skipping, changed on 05.11.2009
   }
 
   return 0;
@@ -4217,8 +4388,10 @@ Int_t AliITStrackerMI::CheckDeadZone(AliITStrackMI *track,
   // without clusters, because there is a dead zone in the road.
   // In this case the return value is > 0:
   // return 1: dead zone at z=0,+-7cm in SPD
+  //     This method assumes that fSPDdetzcentre is ordered from -z to +z
   // return 2: all road is "bad" (dead or noisy) from the OCDB
-  // return 3: something "bad" (dead or noisy) from the OCDB
+  // return 3: at least a chip is "bad" (dead or noisy) from the OCDB
+  // return 4: at least a single channel is "bad" (dead or noisy) from the OCDB
   //-----------------------------------------------------------------
 
   // check dead zones at z=0,+-7cm in the SPD
@@ -4231,8 +4404,8 @@ Int_t AliITStrackerMI::CheckDeadZone(AliITStrackMI *track,
                          fSPDdetzcentre[3] - 0.5*AliITSRecoParam::GetSPDdetzlength()};
     for (Int_t i=0; i<3; i++)
       if (track->GetZ()-dz<zmaxdead[i] && track->GetZ()+dz>zmindead[i]) {
-       AliDebug(2,Form("crack SPD %d",ilayer));
-       return 1; 
+       AliDebug(2,Form("crack SPD %d track z %f   %f   %f  %f\n",ilayer,track->GetZ(),dz,zmaxdead[i],zmindead[i]));
+       if (GetSPDDeadZoneProbability(track->GetZ(),TMath::Sqrt(track->GetSigmaZ2()))>0.1) return 1; 
       } 
   }
 
@@ -4269,10 +4442,10 @@ Int_t AliITStrackerMI::CheckDeadZone(AliITStrackMI *track,
 
   // check if road goes out of detector
   Bool_t touchNeighbourDet=kFALSE; 
-  if (TMath::Abs(xlocmin)>0.5*detSizeX) {xlocmin=-0.5*detSizeX; touchNeighbourDet=kTRUE;} 
-  if (TMath::Abs(xlocmax)>0.5*detSizeX) {xlocmax=+0.5*detSizeX; touchNeighbourDet=kTRUE;} 
-  if (TMath::Abs(zlocmin)>0.5*detSizeZ) {zlocmin=-0.5*detSizeZ; touchNeighbourDet=kTRUE;} 
-  if (TMath::Abs(zlocmax)>0.5*detSizeZ) {zlocmax=+0.5*detSizeZ; touchNeighbourDet=kTRUE;} 
+  if (TMath::Abs(xlocmin)>0.5*detSizeX) {xlocmin=-0.4999*detSizeX; touchNeighbourDet=kTRUE;} 
+  if (TMath::Abs(xlocmax)>0.5*detSizeX) {xlocmax=+0.4999*detSizeX; touchNeighbourDet=kTRUE;} 
+  if (TMath::Abs(zlocmin)>0.5*detSizeZ) {zlocmin=-0.4999*detSizeZ; touchNeighbourDet=kTRUE;} 
+  if (TMath::Abs(zlocmax)>0.5*detSizeZ) {zlocmax=+0.4999*detSizeZ; touchNeighbourDet=kTRUE;} 
   AliDebug(2,Form("layer %d det %d zmim zmax %f %f xmin xmax %f %f   %f %f",ilayer,idet,zlocmin,zlocmax,xlocmin,xlocmax,detSizeZ,detSizeX));
 
   // check if this detector is bad
@@ -4326,7 +4499,7 @@ Int_t AliITStrackerMI::CheckDeadZone(AliITStrackMI *track,
 
   if (fITSChannelStatus->AnyBadInRoad(idetInITS,zlocmin,zlocmax,xlocmin,xlocmax)) {
     AliDebug(2,Form("Bad channel in det %d of layer %d\n",idet,ilayer));
-    return 3;
+    return 4;
   }
   //if (fITSChannelStatus->FractionOfBadInRoad(idet,zlocmin,zlocmax,xlocmin,xlocmax) > AliITSReconstructor::GetRecoParam()->GetMinFractionOfBadInRoad()) return 3;
 
@@ -4343,7 +4516,7 @@ Bool_t AliITStrackerMI::LocalModuleCoord(Int_t ilayer,Int_t idet,
   xloc=0.; 
   zloc=0.;
 
-  if(idet<0) return kFALSE;
+  if(idet<0) return kTRUE; // track out of z acceptance of layer
 
   Int_t ndet=AliITSgeomTGeo::GetNDetectors(ilayer+1); // layers from 1 to 6