]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - ITS/AliITStrackerMI.cxx
Reactivate the method Improve() to reduce the fakes in PbPb -see Savannah bug 71798...
[u/mrichter/AliRoot.git] / ITS / AliITStrackerMI.cxx
index fc0d275b1b72354310c29dcd03c91bc449de2b2a..47fc3f1b87a444566c7df594f4f2927fd1b45738 100644 (file)
 #include <TRandom.h>
 #include <TTreeStream.h>
 
-
 #include "AliLog.h"
+#include "AliGeomManager.h"
 #include "AliITSPlaneEff.h"
-#include "AliITSCalibrationSPD.h"
-#include "AliITSCalibrationSDD.h"
-#include "AliITSCalibrationSSD.h"
-#include "AliCDBEntry.h"
-#include "AliCDBManager.h"
-#include "AliAlignObj.h"
 #include "AliTrackPointArray.h"
-#include "AliESDVertex.h"
 #include "AliESDEvent.h"
 #include "AliESDtrack.h"
 #include "AliV0.h"
-#include "AliHelix.h"
 #include "AliITSChannelStatus.h"
 #include "AliITSDetTypeRec.h"
 #include "AliITSRecPoint.h"
+#include "AliITSRecPointContainer.h"
 #include "AliITSgeomTGeo.h"
 #include "AliITSReconstructor.h"
 #include "AliITSClusterParam.h"
@@ -61,6 +54,7 @@
 #include "AliITSPlaneEffSSD.h"
 #include "AliITSV0Finder.h"
 #include "AliITStrackerMI.h"
+#include "AliMathBase.h"
 
 ClassImp(AliITStrackerMI)
 
@@ -99,6 +93,7 @@ fPlaneEff(0) {
   for(i=0;i<4;i++) fSPDdetzcentre[i]=0.;
   for(i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
   for(i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
+  fOriginal.SetOwner();
 }
 //------------------------------------------------------------------------
 AliITStrackerMI::AliITStrackerMI(const Char_t *geom) : AliTracker(),
@@ -136,6 +131,7 @@ fPlaneEff(0) {
     AliWarning("\"geom\" is actually a dummy argument !");
   }
 
+  fOriginal.SetOwner();
   fCoefficients = 0;
   fAfterV0     = kFALSE;
 
@@ -144,9 +140,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 +183,7 @@ fPlaneEff(0) {
        
       } // end loop on detectors
     } // end loop on ladders
+    fForceSkippingOfLayer[i] = 0;
   } // end loop on layers
 
 
@@ -201,22 +200,34 @@ 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) {
@@ -227,7 +238,8 @@ fPlaneEff(0) {
   for(Int_t i=0;i<2;i++) {fxOverX0Shield[i]=-1.;fxTimesRhoShield[i]=-1.;}
   for(Int_t i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
   
-  fDebugStreamer = new TTreeSRedirector("ITSdebug.root");
+  if (AliITSReconstructor::GetRecoParam()->GetESDV0Params()->StreamLevel()>0)
+    fDebugStreamer = new TTreeSRedirector("ITSdebug.root");
 
   // only for plane efficiency evaluation
   if (AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
@@ -273,6 +285,7 @@ fITSChannelStatus(tracker.fITSChannelStatus),
 fkDetTypeRec(tracker.fkDetTypeRec),
 fPlaneEff(tracker.fPlaneEff) {
   //Copy constructor
+  fOriginal.SetOwner();
   Int_t i;
   for(i=0;i<4;i++) {
     fSPDdetzcentre[i]=tracker.fSPDdetzcentre[i];
@@ -309,13 +322,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 +360,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 +385,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 +435,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 +492,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 +510,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:
@@ -608,7 +623,7 @@ Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
   if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::FindV02(event,this);
   fAfterV0 = kTRUE;
   //
-  itsTracks.Delete();
+  itsTracks.Clear();
   //
   Int_t entries = fTrackHypothesys.GetEntriesFast();
   for (Int_t ientry=0; ientry<entries; ientry++) {
@@ -618,13 +633,19 @@ Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
   }
 
   fTrackHypothesys.Delete();
+  entries = fBestHypothesys.GetEntriesFast();
+  for (Int_t ientry=0; ientry<entries; ientry++) {
+    TObjArray * array =(TObjArray*)fBestHypothesys.UncheckedAt(ientry);
+    if (array) array->Delete();
+    delete fBestHypothesys.RemoveAt(ientry);
+  }
   fBestHypothesys.Delete();
   fOriginal.Clear();
   delete [] fCoefficients;
   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 +659,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++) {
@@ -658,6 +679,7 @@ Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
      t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
 
      ResetTrackToFollow(*t);
+
      /*
      // propagate to vertex [SR, GSI 17.02.2003]
      // Start Time measurement [SR, GSI 17.02.2003], corrected by I.Belikov
@@ -694,7 +716,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";
 
@@ -712,7 +734,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++) {
@@ -771,7 +793,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";
 
@@ -805,6 +827,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:
@@ -877,6 +900,7 @@ Bool_t AliITStrackerMI::GetTrackPointTrackingError(Int_t index,
   p.SetCharge(cl->GetQ());
   p.SetDriftTime(cl->GetDriftTime());
   p.SetChargeRatio(cl->GetChargeRatio());
+  p.SetClusterType(cl->GetClusterType());
 
   AliGeomManager::ELayerID iLayer = AliGeomManager::kInvalidLayer; 
   switch (l) {
@@ -940,6 +964,7 @@ void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdin
   TObjArray *bestarray = (TObjArray*)fBestHypothesys.At(esdindex);
   if (!bestarray){
     bestarray = new TObjArray(5);
+    bestarray->SetOwner();
     fBestHypothesys.AddAt(bestarray,esdindex);
   }
 
@@ -1020,7 +1045,7 @@ void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdin
        if(LocalModuleCoord(ilayer,idet,vtrack,xloc,zloc)) { // local module coords
          vtrack->SetModuleIndexInfo(ilayer,idet,modstatus,xloc,zloc);
        }
-       if(constrain) vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
+       if(constrain && AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
        ntracks[ilayer]++;
        continue;
       }
@@ -1111,7 +1136,7 @@ void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdin
                TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
                AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
          }
-         if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
+         if (isPrim && AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
        }
        updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
        if (dead) {
@@ -1132,7 +1157,7 @@ void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdin
       while ((cl=layer.GetNextCluster(clidx))!=0) { 
        if (ntracks[ilayer]>95) break; //space for skipped clusters  
        Bool_t changedet =kFALSE;  
-       if (cl->GetQ()==0 && deadzoneSPD==kTRUE) continue;
+       if (TMath::Abs(cl->GetQ())<1.e-13 && deadzoneSPD==kTRUE) continue;
        Int_t idetc=cl->GetDetectorIndex();
 
        if (currenttrack->GetDetectorIndex()==idetc) { // track already on the cluster's detector
@@ -1144,6 +1169,9 @@ void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdin
               (currenttrack->GetY()-cl->GetY())*(currenttrack->GetY()-cl->GetY())*msy > 1. ) 
            {  // cluster not associated to track
              AliDebug(2,"not associated");
+             // MvL: added here as well
+             // bring track back to ideal detector plane
+             currenttrack->Propagate(xTrOrig);
              continue;
            }
          // bring track back to ideal detector plane
@@ -1176,13 +1204,13 @@ void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdin
        // chi2 cut
        AliDebug(2,Form("chi2 %f max %f",chi2trkcl,AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)));
        if (chi2trkcl < AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) {
-         if (cl->GetQ()==0) deadzoneSPD=kTRUE; // only 1 prolongation with virtual cluster       
+         if (TMath::Abs(cl->GetQ())<1.e-13) deadzoneSPD=kTRUE; // only 1 prolongation with virtual cluster       
          if (ntracks[ilayer]>=100) continue;
          AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
          updatetrack->SetClIndex(ilayer,-1);
          if (changedet) new (&currenttrack2) AliITStrackMI(backuptrack);
 
-         if (cl->GetQ()!=0) { // real cluster
+         if (TMath::Abs(cl->GetQ())>1.e-13) { // real cluster
            if (!UpdateMI(updatetrack,cl,chi2trkcl,(ilayer<<28)+clidx)) {
              AliDebug(2,"update failed");
              continue;
@@ -1218,7 +1246,7 @@ void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdin
                  TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
                  AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
            }
-           if (isPrim) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
+           if (isPrim && AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
          } //apply vertex constrain              
          ntracks[ilayer]++;
        }  // create new hypothesis
@@ -1229,32 +1257,19 @@ void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdin
       } // loop over possible prolongations 
      
       // allow one prolongation without clusters
-      if (constrain && itrack<=1 && currenttrack1.GetNSkipped()==0 && deadzoneSPD==kFALSE && ntracks[ilayer]<100) {
+      if (constrain && itrack<=1 && TMath::Abs(currenttrack1.GetNSkipped())<1.e-13 && deadzoneSPD==kFALSE && ntracks[ilayer]<100) {
        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);
+       if(AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
        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
@@ -1589,7 +1604,6 @@ 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;
@@ -1913,16 +1927,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);
 
@@ -1951,7 +1974,7 @@ const AliITSRecPoint *AliITStrackerMI::AliITSlayer::GetNextCluster(Int_t &ci,Boo
       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;
+      if (TMath::Abs(fClusters[i]->GetQ())<1.e-13 && fSkip==2) continue;
       ci=i;
       if (!test) fI=i+1;
       return fClusters[i];
@@ -1960,7 +1983,7 @@ const AliITSRecPoint *AliITStrackerMI::AliITSlayer::GetNextCluster(Int_t &ci,Boo
     for (Int_t i=fI; i<fImax; i++) {
       if (fYcs[i]<fYmin) continue;
       if (fYcs[i]>fYmax) continue;
-      if (fClustersCs[i]->GetQ()==0&&fSkip==2) continue;
+      if (TMath::Abs(fClustersCs[i]->GetQ())<1.e-13 && fSkip==2) continue;
       ci=fClusterIndexCs[i];
       if (!test) fI=i+1;
       return fClustersCs[i];
@@ -2240,14 +2263,32 @@ Bool_t AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *track,
     index[k]=clusters[k]; 
   }
 
-  // special for cosmics: check which the innermost layer crossed
-  // by the track
-  Int_t innermostlayer=5;
-  Double_t drphi = TMath::Abs(track->GetD(0.,0.));
-  for(innermostlayer=0; innermostlayer<AliITSgeomTGeo::GetNLayers(); innermostlayer++) {
-    if(drphi < fgLayers[innermostlayer].GetR()) break;
+  // special for cosmics and TPC prolonged tracks: 
+  // propagate to the innermost of:
+  // - innermost layer crossed by the track
+  // - innermost layer where a cluster was associated to the track
+  static AliITSRecoParam *repa = NULL;
+  if(!repa){
+    repa = (AliITSRecoParam*) AliITSReconstructor::GetRecoParam();
+    if(!repa){
+      repa = AliITSRecoParam::GetHighFluxParam();
+      AliWarning("Using default AliITSRecoParam class");
+    }
+  }
+  Int_t evsp=repa->GetEventSpecie();
+  ULong_t trStatus=0;
+  if(track->GetESDtrack()) trStatus=track->GetStatus();
+  Int_t innermostlayer=0;
+  if((evsp&AliRecoParam::kCosmic) || (trStatus&AliESDtrack::kTPCin))  {
+    innermostlayer=5;
+    Double_t drphi = TMath::Abs(track->GetD(0.,0.));
+    for(innermostlayer=0; innermostlayer<AliITSgeomTGeo::GetNLayers(); innermostlayer++) {
+      if( (drphi < (fgLayers[innermostlayer].GetR()+1.)) ||
+         index[innermostlayer] >= 0 ) break;
+    }
+
+    AliDebug(2,Form(" drphi  %f  innermost %d",drphi,innermostlayer));
   }
-  //printf(" drphi  %f  innermost %d\n",drphi,innermostlayer);
 
   Int_t modstatus=1; // found
   Float_t xloc,zloc;
@@ -2264,6 +2305,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
@@ -2303,7 +2345,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);
@@ -2397,7 +2443,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;
@@ -2505,12 +2551,17 @@ Double_t AliITStrackerMI::GetNormalizedChi2(AliITStrackMI * track, Int_t mode)
   // or there is a dead from OCDB)
   Float_t deadzonefactor = 0.; 
   if (track->GetNDeadZone()>0.) {    
-    Float_t sumDeadZoneProbability=0; 
-    for(Int_t ilay=0;ilay<6;ilay++) sumDeadZoneProbability+=track->GetDeadZoneProbability(ilay);
-    Float_t nDeadZoneWithProbNot1=(Float_t)(track->GetNDeadZone())-sumDeadZoneProbability;
-    if(nDeadZoneWithProbNot1>0.) {
-      Float_t deadZoneProbability = sumDeadZoneProbability - (Float_t)((Int_t)sumDeadZoneProbability);
-      deadZoneProbability /= nDeadZoneWithProbNot1;
+    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 %d nDZWithProbNot1 %d 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);  
     }
   }  
@@ -2518,8 +2569,9 @@ Double_t AliITStrackerMI::GetNormalizedChi2(AliITStrackMI * track, Int_t mode)
   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 %f\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)
@@ -2569,30 +2621,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;
 }
 //------------------------------------------------------------------------
@@ -2720,9 +2788,9 @@ Float_t AliITStrackerMI::GetNumberOfSharedClusters(AliITStrackMI* track,Int_t id
     Int_t l=(index & 0xf0000000) >> 28;
     Int_t c=(index & 0x0fffffff) >> 00;
     if (c>fgLayers[l].GetNumberOfClusters()) continue;
-    if (ny[l]==0){
-      printf("problem\n");
-    }
+    // if (ny[l]<1.e-13){
+    //   printf("problem\n");
+    // }
     AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
     Float_t weight=1;
     //
@@ -2770,9 +2838,9 @@ Int_t AliITStrackerMI::GetOverlapTrack(const AliITStrackMI *track, Int_t trackID
     Int_t index = clusterlist[icluster];
     Int_t l=(index & 0xf0000000) >> 28;
     Int_t c=(index & 0x0fffffff) >> 00;
-    if (ny[l]==0){
-      printf("problem\n");
-    }
+    // if (ny[l]<1.e-13){
+    //   printf("problem\n");
+    // }
     if (c>fgLayers[l].GetNumberOfClusters()) continue;
     //if (l>3) continue;
     AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(index);
@@ -3204,6 +3272,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);
@@ -3217,6 +3286,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){
@@ -3233,7 +3303,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
@@ -3252,6 +3323,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){
@@ -3342,7 +3414,9 @@ AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI
     backtrack = new(backtrack) AliITStrackMI(*track); 
     if (track->GetConstrain()) {
       if (!CorrectForPipeMaterial(backtrack,"inward")) continue;
-      if (!backtrack->Improve(0,xyzVtx,ersVtx))         continue;     
+      if (AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) {
+       if (!backtrack->Improve(0,xyzVtx,ersVtx)) continue;     
+      }
       backtrack->ResetCovariance(10.);      
     }else{
       backtrack->ResetCovariance(10.);
@@ -3604,8 +3678,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++){
@@ -3614,9 +3691,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;
@@ -3624,17 +3700,18 @@ 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));
    
 }
 //------------------------------------------------------------------------
-void AliITStrackerMI::CookdEdx(AliITStrackMI* track)
-{
+void AliITStrackerMI::CookdEdx(AliITStrackMI* track){
+  //
+  // Fill the dE/dx in this track
   //
   track->SetChi2MIP(9,0);
   for (Int_t i=0;i<track->GetNumberOfClusters();i++){
@@ -3714,7 +3791,7 @@ Int_t AliITStrackerMI::UpdateMI(AliITStrackMI* track, const AliITSRecPoint* cl,D
     }
   }
 
-  if (cl->GetQ()<=0) return 0;  // ingore the "virtual" clusters
+  if (TMath::Abs(cl->GetQ())<1.e-13) return 0;  // ingore the "virtual" clusters
 
 
   // Take into account the mis-alignment (bring track to cluster plane)
@@ -3831,9 +3908,9 @@ void AliITStrackerMI::UpdateESDtrack(AliITStrackMI* track, ULong_t flags) const
   AliITStrackMI * oldtrack = (AliITStrackMI*)(track->GetESDtrack()->GetITStrack());
   if (oldtrack) delete oldtrack; 
   track->GetESDtrack()->SetITStrack(new AliITStrackMI(*track));
-  if (TMath::Abs(track->GetDnorm(1))<0.000000001){
-    printf("Problem\n");
-  }
+  // if (TMath::Abs(track->GetDnorm(1))<0.000000001){
+  //   printf("Problem\n");
+  // }
 }
 //------------------------------------------------------------------------
 Int_t AliITStrackerMI::GetNearestLayer(const Double_t *xr) const{
@@ -4273,6 +4350,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 {
   //-----------------------------------------------------------------
@@ -4280,17 +4387,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;
 
-  if (idet<0 && ilayer>1 && AliITSReconstructor::GetRecoParam()->GetExtendedEtaAcceptance()) {
+  Int_t innerLayCanSkip=0; // was 2, changed on 05.11.2009
+
+  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;
@@ -4305,6 +4417,7 @@ 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: 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
@@ -4320,8 +4433,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; 
       } 
   }
 
@@ -4358,10 +4471,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
@@ -4432,7 +4545,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 
 
@@ -4490,19 +4603,29 @@ Bool_t AliITStrackerMI::IsOKForPlaneEff(const AliITStrackMI* track, const Int_t
   AliITStrackMI tmp(*track);
 
 // require a minimal number of cluster in other layers and eventually clusters in closest layers 
-  Int_t ncl=0; 
-  for(Int_t lay=AliITSgeomTGeo::kNLayers-1;lay>ilayer;lay--) {
+  Int_t ncl_out=0; Int_t ncl_in=0;
+  for(Int_t lay=AliITSgeomTGeo::kNLayers-1;lay>ilayer;lay--) { // count n. of cluster in outermost layers
     AliDebug(2,Form("trak=%d  lay=%d  ; index=%d ESD label= %d",tmp.GetLabel(),lay,
                     tmp.GetClIndex(lay),((AliESDtrack*)tmp.GetESDtrack())->GetLabel())) ;
-    if (tmp.GetClIndex(lay)>=0) ncl++;
+    if (tmp.GetClIndex(lay)>=0) ncl_out++;
   }
+  for(Int_t lay=ilayer-1; lay>=0;lay--) { // count n. of cluster in innermost layers
+    AliDebug(2,Form("trak=%d  lay=%d  ; index=%d ESD label= %d",tmp.GetLabel(),lay,
+                    tmp.GetClIndex(lay),((AliESDtrack*)tmp.GetESDtrack())->GetLabel())) ;
+    if (tmp.GetClIndex(lay)>=0) ncl_in++;
+  }
+  Int_t ncl=ncl_out+ncl_out;
   Bool_t nextout = kFALSE;
   if(ilayer==AliITSgeomTGeo::kNLayers-1) nextout=kTRUE; // you are already on the outermost layer
   else nextout = ((tmp.GetClIndex(ilayer+1)>=0)? kTRUE : kFALSE );
   Bool_t nextin = kFALSE;
   if(ilayer==0) nextin=kTRUE; // you are already on the innermost layer
   else nextin = ((index[ilayer-1]>=0)? kTRUE : kFALSE );
-  if(ncl<AliITSgeomTGeo::kNLayers-(ilayer+1)-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersPlaneEff()) 
+  // maximum number of missing clusters allowed in outermost layers
+  if(ncl_out<AliITSgeomTGeo::kNLayers-(ilayer+1)-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersOutPlaneEff()) 
+     return kFALSE; 
+  // maximum number of missing clusters allowed (both in innermost and in outermost layers)
+  if(ncl<AliITSgeomTGeo::kNLayers-1-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersPlaneEff()) 
      return kFALSE; 
   if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInOuterLayerPlaneEff() && !nextout)  return kFALSE;
   if(AliITSReconstructor::GetRecoParam()->GetRequireClusterInInnerLayerPlaneEff() && !nextin)   return kFALSE;
@@ -4533,10 +4656,10 @@ Bool_t AliITStrackerMI::IsOKForPlaneEff(const AliITStrackMI* track, const Int_t
   // DEFINITION OF SEARCH ROAD FOR accepting a track
   //
   //For the time being they are hard-wired, later on from AliITSRecoParam
-  // Double_t nsigx=AliITSRecoParam::GetNSigXFarFromBoundary();
-  // Double_t nsigz=AliITSRecoParam::GetNSigZFarFromBoundary();
-  Double_t nsigz=4; 
-  Double_t nsigx=4; 
+  Double_t nsigx=AliITSReconstructor::GetRecoParam()->GetNSigXFromBoundaryPlaneEff();
+  Double_t nsigz=AliITSReconstructor::GetRecoParam()->GetNSigZFromBoundaryPlaneEff();
+  // Double_t nsigz=4; 
+  // Double_t nsigx=4; 
   Double_t dx=nsigx*TMath::Sqrt(tmp.GetSigmaY2());  // those are precisions in the tracking reference system
   Double_t dz=nsigz*TMath::Sqrt(tmp.GetSigmaZ2());  // Use it also for the module reference system, as it is
                                                 // done for RecPoints
@@ -4716,3 +4839,4 @@ void AliITStrackerMI::UseTrackForPlaneEff(const AliITStrackMI* track, Int_t ilay
   }
 return;
 }
+