]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - ITS/AliITStrackerMI.cxx
Filling histograms separately for the SPD and Tracks vertices
[u/mrichter/AliRoot.git] / ITS / AliITStrackerMI.cxx
index 75e423dad176811b6d6fc1c9d0ef13bc7f8a2d08..d7df282aa40886f7144165587f3707f1f827661b 100644 (file)
 #include <TRandom.h>
 #include <TTreeStream.h>
 #include <TVector3.h>
+#include <TBits.h>
 
 #include "AliLog.h"
 #include "AliGeomManager.h"
 #include "AliITSPlaneEff.h"
 #include "AliTrackPointArray.h"
 #include "AliESDEvent.h"
+#include "AliESDV0Params.h"
 #include "AliESDtrack.h"
 #include "AliV0.h"
 #include "AliITSChannelStatus.h"
@@ -56,6 +58,8 @@
 #include "AliITSV0Finder.h"
 #include "AliITStrackerMI.h"
 #include "AliMathBase.h"
+#include "AliPID.h"
+
 
 ClassImp(AliITStrackerMI)
 
@@ -77,6 +81,9 @@ fEsd(0),
 fTrackingPhase("Default"),
 fUseTGeo(3),
 fNtracks(0),
+fFlagFakes(kFALSE),
+fSelectBestMIP03(kFALSE),
+fUseImproveKalman(kFALSE),
 fxOverX0Pipe(-1.),
 fxTimesRhoPipe(-1.),
 fxOverX0PipeTrks(0),
@@ -88,13 +95,25 @@ fxTimesRhoLayerTrks(0),
 fDebugStreamer(0),
 fITSChannelStatus(0),
 fkDetTypeRec(0),
-fPlaneEff(0) {
+fPlaneEff(0),
+fSPDChipIntPlaneEff(0),
+fITSPid(0)
+
+ {
   //Default constructor
   Int_t i;
   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<2;i++) {
+    fxOverX0Shield[i]=-1.;
+    fxTimesRhoShield[i]=-1.;
+    fConstraint[i]=0;
+  }
   for(i=0;i<6;i++) {fxOverX0Layer[i]=-1.;fxTimesRhoLayer[i]=-1.;}
   fOriginal.SetOwner();
+  for(i=0;i<AliITSgeomTGeo::kNLayers;i++)fForceSkippingOfLayer[i]=0;
+  for(i=0;i<100000;i++)fBestTrackIndex[i]=0;
+  fITSPid=new AliITSPIDResponse();
+
 }
 //------------------------------------------------------------------------
 AliITStrackerMI::AliITStrackerMI(const Char_t *geom) : AliTracker(),
@@ -113,6 +132,9 @@ fEsd(0),
 fTrackingPhase("Default"),
 fUseTGeo(3),
 fNtracks(0),
+fFlagFakes(kFALSE),
+fSelectBestMIP03(kFALSE),
+fUseImproveKalman(kFALSE),
 fxOverX0Pipe(-1.),
 fxTimesRhoPipe(-1.),
 fxOverX0PipeTrks(0),
@@ -124,7 +146,9 @@ fxTimesRhoLayerTrks(0),
 fDebugStreamer(0),
 fITSChannelStatus(0),
 fkDetTypeRec(0),
-fPlaneEff(0) {
+fPlaneEff(0),
+fSPDChipIntPlaneEff(0),
+fITSPid(0) {
   //--------------------------------------------------------------------
   //This is the AliITStrackerMI constructor
   //--------------------------------------------------------------------
@@ -246,16 +270,28 @@ fPlaneEff(0) {
   if (AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
       AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0) {
     Int_t iplane=AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff();
-    if(!AliITSReconstructor::GetRecoParam()->GetLayersToSkip(iplane)==1)
+    if(AliITSReconstructor::GetRecoParam()->GetLayersToSkip(iplane)!=1)
       AliWarning(Form("Evaluation of Plane Eff for layer %d will be attempted without removing it from tracker",iplane));
-    if (iplane<2) fPlaneEff = new AliITSPlaneEffSPD();
+    if (iplane<2) {
+      fPlaneEff = new AliITSPlaneEffSPD();
+      fSPDChipIntPlaneEff = new Bool_t[AliITSPlaneEffSPD::kNModule*AliITSPlaneEffSPD::kNChip];
+      for (UInt_t i=0; i<AliITSPlaneEffSPD::kNModule*AliITSPlaneEffSPD::kNChip; i++) fSPDChipIntPlaneEff[i]=kFALSE;
+    }
     else if (iplane<4) fPlaneEff = new AliITSPlaneEffSDD();
     else fPlaneEff = new AliITSPlaneEffSSD();
     if(AliITSReconstructor::GetRecoParam()->GetReadPlaneEffFromOCDB())
        if(!fPlaneEff->ReadFromCDB()) {AliWarning("AliITStrackerMI reading of AliITSPlaneEff from OCDB failed") ;}
     if(AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) fPlaneEff->SetCreateHistos(kTRUE);
   }
+  //
+  // RS
+  fSelectBestMIP03  = kFALSE;//AliITSReconstructor::GetRecoParam()->GetSelectBestMIP03();
+  fFlagFakes        = AliITSReconstructor::GetRecoParam()->GetFlagFakes();
+  fUseImproveKalman = AliITSReconstructor::GetRecoParam()->GetUseImproveKalman();
+  //
+  fITSPid=new AliITSPIDResponse();
 }
+/*
 //------------------------------------------------------------------------
 AliITStrackerMI::AliITStrackerMI(const AliITStrackerMI &tracker):AliTracker(tracker),
 fI(tracker.fI),
@@ -273,6 +309,8 @@ fEsd(tracker.fEsd),
 fTrackingPhase(tracker.fTrackingPhase),
 fUseTGeo(tracker.fUseTGeo),
 fNtracks(tracker.fNtracks),
+fFlagFakes(tracker.fFlagFakes),
+fSelectBestMIP03(tracker.fSelectBestMIP03),
 fxOverX0Pipe(tracker.fxOverX0Pipe),
 fxTimesRhoPipe(tracker.fxTimesRhoPipe),
 fxOverX0PipeTrks(0),
@@ -300,6 +338,7 @@ fPlaneEff(tracker.fPlaneEff) {
     fxTimesRhoShield[i]=tracker.fxTimesRhoShield[i];
   }
 }
+
 //------------------------------------------------------------------------
 AliITStrackerMI & AliITStrackerMI::operator=(const AliITStrackerMI &tracker){
   //Assignment operator
@@ -307,6 +346,7 @@ AliITStrackerMI & AliITStrackerMI::operator=(const AliITStrackerMI &tracker){
   new(this) AliITStrackerMI(tracker);
   return *this;
 }
+*/
 //------------------------------------------------------------------------
 AliITStrackerMI::~AliITStrackerMI()
 {
@@ -321,6 +361,9 @@ AliITStrackerMI::~AliITStrackerMI()
   }
   if(fITSChannelStatus) delete fITSChannelStatus;
   if(fPlaneEff) delete fPlaneEff;
+  if(fITSPid) delete fITSPid;
+  if (fSPDChipIntPlaneEff) delete [] fSPDChipIntPlaneEff;
+
 }
 //------------------------------------------------------------------------
 void AliITStrackerMI::ReadBadFromDetTypeRec() {
@@ -406,8 +449,8 @@ Int_t AliITStrackerMI::LoadClusters(TTree *cTree) {
          Float_t q      = 0.; // this identifies virtual clusters
          Float_t hit[6] = {xdead,
                            0.,
-                           AliITSReconstructor::GetRecoParam()->GetSigmaXDeadZoneHit2(),
-                           AliITSReconstructor::GetRecoParam()->GetSigmaZDeadZoneHit2(),
+                           static_cast<Float_t>(AliITSReconstructor::GetRecoParam()->GetSigmaXDeadZoneHit2()),
+                           static_cast<Float_t>(AliITSReconstructor::GetRecoParam()->GetSigmaZDeadZoneHit2()),
                            q,
                            0.};
          Bool_t local   = kTRUE;
@@ -499,7 +542,12 @@ Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
   AliDebug(2,Form("SKIPPING %d %d %d %d %d %d",ForceSkippingOfLayer(0),ForceSkippingOfLayer(1),ForceSkippingOfLayer(2),ForceSkippingOfLayer(3),ForceSkippingOfLayer(4),ForceSkippingOfLayer(5)));
 
   fTrackingPhase="Clusters2Tracks";
-
+  //
+  // RS
+  fSelectBestMIP03  = kFALSE;//AliITSReconstructor::GetRecoParam()->GetSelectBestMIP03();
+  fFlagFakes        = AliITSReconstructor::GetRecoParam()->GetFlagFakes();
+  fUseImproveKalman = AliITSReconstructor::GetRecoParam()->GetUseImproveKalman();
+  //
   TObjArray itsTracks(15000);
   fOriginal.Clear();
   fEsd = event;         // store pointer to the esd 
@@ -516,7 +564,6 @@ 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();
     noesd=nentr;
     //    Info("Clusters2Tracks", "Number of ESD tracks: %d\n", nentr);
@@ -533,9 +580,6 @@ Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
       t->GetDZ(GetX(),GetY(),GetZ(),t->GetDP());              //I.B.
       Double_t vdist = TMath::Sqrt(t->GetD(0)*t->GetD(0)+t->GetD(1)*t->GetD(1));
 
-
-      // look at the ESD mass hypothesys !
-      if (t->GetMass()<0.9*pimass) t->SetMass(pimass); 
       // write expected q
       t->SetExpQ(TMath::Max(0.8*t->GetESDtrack()->GetTPCsignal(),30.));
 
@@ -606,6 +650,7 @@ Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
        besttrack->SetFakeRatio(1.);
        CookLabel(besttrack,0.); //For comparison only
        UpdateESDtrack(besttrack,AliESDtrack::kITSin);
+       t->SetWinner(besttrack);
 
        if (fConstraint[fPass]&&(!besttrack->IsGoldPrimary())) continue;  //to be tracked also without vertex constrain 
 
@@ -615,7 +660,9 @@ Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
      }
      GetBestHypothesysMIP(itsTracks); 
   } // end loop on the two tracking passes
-
+  //
+  if (fFlagFakes) FlagFakes(itsTracks);
+  //
   if(event->GetNumberOfV0s()>0) AliITSV0Finder::UpdateTPCV0(event,this);
   if(AliITSReconstructor::GetRecoParam()->GetFindV0s()) AliITSV0Finder::FindV02(event,this);
   fAfterV0 = kTRUE;
@@ -624,7 +671,7 @@ Int_t AliITStrackerMI::Clusters2Tracks(AliESDEvent *event) {
   //
   Int_t entries = fTrackHypothesys.GetEntriesFast();
   for (Int_t ientry=0; ientry<entries; ientry++) {
-    TObjArray * array =(TObjArray*)fTrackHypothesys.UncheckedAt(ientry);
+    TObjArray * array =(TObjArray*)fTrackHypothesys.At(ientry);
     if (array) array->Delete();
     delete fTrackHypothesys.RemoveAt(ientry); 
   }
@@ -632,7 +679,7 @@ 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);
+    TObjArray * array =(TObjArray*)fBestHypothesys.At(ientry);
     if (array) array->Delete();
     delete fBestHypothesys.RemoveAt(ientry);
   }
@@ -657,54 +704,60 @@ Int_t AliITStrackerMI::PropagateBack(AliESDEvent *event) {
   fTrackingPhase="PropagateBack";
   Int_t nentr=event->GetNumberOfTracks();
   //  Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
-
+  double bz0 = GetBz();
+  const double kWatchStep=10.; // for larger steps watch arc vs segment difference
+  //
   Int_t ntrk=0;
   for (Int_t i=0; i<nentr; i++) {
      AliESDtrack *esd=event->GetTrack(i);
 
-     if ((esd->GetStatus()&AliESDtrack::kITSin)==0) continue;
-     if (esd->GetStatus()&AliESDtrack::kITSout) continue;
-
-     AliITStrackMI *t = new AliITStrackMI(*esd);
-
-     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
-     if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
-       if (fTrackToFollow.PropagateToVertex(event->GetVertex()))
-        fTrackToFollow.StartTimeIntegral();
-       // from vertex to outside pipe
-       CorrectForPipeMaterial(&fTrackToFollow,"outward");
-       }*/
      // Start time integral and add distance from current position to vertex 
+     if (esd->GetStatus()&AliESDtrack::kITSout) continue;
+     AliITStrackMI t(*esd);
      Double_t xyzTrk[3],xyzVtx[3]={GetX(),GetY(),GetZ()};
-     fTrackToFollow.GetXYZ(xyzTrk);
+     t.GetXYZ(xyzTrk); 
      Double_t dst2 = 0.;
-     for (Int_t icoord=0; icoord<3; icoord++) {  
-       Double_t di = xyzTrk[icoord] - xyzVtx[icoord];
-       dst2 += di*di; 
+     {
+       double dxs = xyzTrk[0] - xyzVtx[0];
+       double dys = xyzTrk[1] - xyzVtx[1];
+       double dzs = xyzTrk[2] - xyzVtx[2];
+       // RS: for large segment steps d use approximation of cicrular arc s by
+       // s = 2R*asin(d/2R) = d/p asin(p) \approx d/p (p + 1/6 p^3) = d (1+1/6 p^2)
+       // where R is the track radius, p = d/2R = 2C*d (C is the abs curvature)
+       // Hence s^2/d^2 = (1+1/6 p^2)^2
+       dst2 = dxs*dxs + dys*dys;
+       if (dst2 > kWatchStep*kWatchStep) { // correct circular part for arc/segment factor
+        double crv = TMath::Abs(esd->GetC(bz0));
+        double fcarc = 1.+crv*crv*dst2/6.;
+        dst2 *= fcarc*fcarc;
+       }
+       dst2 += dzs*dzs;
      }
-     fTrackToFollow.StartTimeIntegral();
-     fTrackToFollow.AddTimeStep(TMath::Sqrt(dst2));
+     t.StartTimeIntegral();
+     t.AddTimeStep(TMath::Sqrt(dst2));
+     //
+     // transfer the time integral to ESD track
+     esd->SetStatus(AliESDtrack::kTIME);
+     Double_t times[AliPID::kSPECIESC];
+     t.GetIntegratedTimes(times,AliPID::kSPECIESC); 
+     esd->SetIntegratedTimes(times);
+     esd->SetIntegratedLength(t.GetIntegratedLength());
+     //
+     if ((esd->GetStatus()&AliESDtrack::kITSin)==0) continue;
 
+     t.SetExpQ(TMath::Max(0.8*t.GetESDtrack()->GetTPCsignal(),30.));
+     ResetTrackToFollow(t);
+     //
      fTrackToFollow.ResetCovariance(10.); fTrackToFollow.ResetClusters();
-     if (RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&fTrackToFollow,t)) {
-        if (!CorrectForTPCtoITSDeadZoneMaterial(&fTrackToFollow)) {
-          delete t;
-          continue;
-        }
-        fTrackToFollow.SetLabel(t->GetLabel());
-        //fTrackToFollow.CookdEdx();
-        CookLabel(&fTrackToFollow,0.); //For comparison only
-        fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSout);
-        //UseClusters(&fTrackToFollow);
-        ntrk++;
+     if (RefitAt(AliITSRecoParam::GetrInsideITSscreen(),&fTrackToFollow,&t)) {
+       if (!CorrectForTPCtoITSDeadZoneMaterial(&fTrackToFollow)) continue;
+       //       fTrackToFollow.SetLabel(t.GetLabel());              // why do we neet this
+       //fTrackToFollow.CookdEdx();
+       CookLabel(&fTrackToFollow,0.); //For comparison only // why do we need this?
+       fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSout);
+       //UseClusters(&fTrackToFollow);
+       ntrk++;
      }
-     delete t;
   }
 
   AliInfo(Form("Number of back propagated ITS tracks: %d out of %d ESD tracks",ntrk,nentr));
@@ -730,6 +783,13 @@ Int_t AliITStrackerMI::RefitInward(AliESDEvent *event) {
   Int_t nentr=event->GetNumberOfTracks();
   //  Info("RefitInward", "Number of ESD tracks: %d\n", nentr);
 
+  // only for PlaneEff and in case of SPD (for FO studies)
+  if( AliITSReconstructor::GetRecoParam()->GetComputePlaneEff() &&
+      AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()>=0 && 
+      AliITSReconstructor::GetRecoParam()->GetIPlanePlaneEff()<2) {
+      for (UInt_t i=0; i<AliITSPlaneEffSPD::kNModule*AliITSPlaneEffSPD::kNChip; i++) fSPDChipIntPlaneEff[i]=kFALSE;     
+  }
+
   Int_t ntrk=0;
   for (Int_t i=0; i<nentr; i++) {
     AliESDtrack *esd=event->GetTrack(i);
@@ -772,7 +832,7 @@ Int_t AliITStrackerMI::RefitInward(AliESDEvent *event) {
        //       fTrackToFollow.CookdEdx();
        CookdEdx(&fTrackToFollow);
 
-       CookLabel(&fTrackToFollow,0.0); //For comparison only
+       CookLabel(&fTrackToFollow,0.0); //For comparison only // RS why do we need this?
 
        //The beam pipe
        if (CorrectForPipeMaterial(&fTrackToFollow,"inward")) {
@@ -967,14 +1027,15 @@ void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdin
   //
   //setup tree of the prolongations
   //
-  static AliITStrackMI tracks[7][100];
+  const int kMaxTr = 100; //RS
+  static AliITStrackMI tracks[7][kMaxTr];
   AliITStrackMI *currenttrack;
   static AliITStrackMI currenttrack1;
   static AliITStrackMI currenttrack2;  
   static AliITStrackMI backuptrack;
   Int_t ntracks[7];
-  Int_t nindexes[7][100];
-  Float_t normalizedchi2[100];
+  Int_t nindexes[7][kMaxTr];
+  Float_t normalizedchi2[kMaxTr];
   for (Int_t ilayer=0;ilayer<6;ilayer++) ntracks[ilayer]=0;
   otrack->SetNSkipped(0);
   new (&(tracks[6][0])) AliITStrackMI(*otrack);
@@ -997,8 +1058,9 @@ void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdin
     Int_t nskipped=0;
     Float_t nused =0;
     for (Int_t itrack =0; itrack<ntracks[ilayer+1]; itrack++) {
+      //      printf("LR %d Tr:%d NSeeds: %d\n",ilayer,itrack,ntracks[ilayer+1]);
       //set current track
-      if (ntracks[ilayer]>=100) break;  
+      if (ntracks[ilayer]>=kMaxTr) break;  
       if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNSkipped()>0) nskipped++;
       if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].GetNUsed()>2.) nused++;
       if (ntracks[ilayer]>15+ilayer){
@@ -1023,8 +1085,13 @@ void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdin
       if (!currenttrack1.GetXYZ(trackGlobXYZ1)) continue;
 
       // Get the budget to the primary vertex for the current track being prolonged
-      Double_t budgetToPrimVertex = GetEffectiveThickness();
-
+      Double_t budgetToPrimVertex = 0;
+      double xMSLrs[9],x2X0MSLrs[9]; // needed for ImproveKalman
+      int nMSLrs = 0;
+      //
+      if (fUseImproveKalman) nMSLrs = GetEffectiveThicknessLbyL(xMSLrs,x2X0MSLrs);
+      else budgetToPrimVertex = GetEffectiveThickness();
+      //
       // check if we allow a prolongation without point
       Int_t skip = CheckSkipLayer(&currenttrack1,ilayer,idet);
       if (skip) {
@@ -1041,7 +1108,11 @@ 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 && AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
+       if(constrain && AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) {
+         fUseImproveKalman ? 
+           vtrack->ImproveKalman(xyzVtx,ersVtx,xMSLrs,x2X0MSLrs,nMSLrs) : 
+           vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
+       }
        ntracks[ilayer]++;
        continue;
       }
@@ -1132,7 +1203,11 @@ void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdin
                TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
                AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
          }
-         if (isPrim && AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
+         if (isPrim && AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) {
+           fUseImproveKalman ? 
+             updatetrack->ImproveKalman(xyzVtx,ersVtx,xMSLrs,x2X0MSLrs,nMSLrs) : 
+             updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
+         }
        }
        updatetrack->SetNDeadZone(updatetrack->GetNDeadZone()+1);
        if (dead) {
@@ -1151,7 +1226,7 @@ void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdin
       clidx=-1;
       // loop over clusters in the road
       while ((cl=layer.GetNextCluster(clidx))!=0) { 
-       if (ntracks[ilayer]>95) break; //space for skipped clusters  
+       if (ntracks[ilayer]>int(0.95*kMaxTr)) break; //space for skipped clusters  
        Bool_t changedet =kFALSE;  
        if (TMath::Abs(cl->GetQ())<1.e-13 && deadzoneSPD==kTRUE) continue;
        Int_t idetc=cl->GetDetectorIndex();
@@ -1201,7 +1276,7 @@ void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdin
        AliDebug(2,Form("chi2 %f max %f",chi2trkcl,AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)));
        if (chi2trkcl < AliITSReconstructor::GetRecoParam()->GetMaxChi2s(ilayer)) {
          if (TMath::Abs(cl->GetQ())<1.e-13) deadzoneSPD=kTRUE; // only 1 prolongation with virtual cluster       
-         if (ntracks[ilayer]>=100) continue;
+         if (ntracks[ilayer]>=kMaxTr) continue;
          AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
          updatetrack->SetClIndex(ilayer,-1);
          if (changedet) new (&currenttrack2) AliITStrackMI(backuptrack);
@@ -1242,7 +1317,11 @@ void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdin
                  TMath::Abs(updatetrack->GetD(1)/(1.+ilayer)) > // z
                  AliITSReconstructor::GetRecoParam()->GetMaxDZforPrimTrk()) isPrim=kFALSE;
            }
-           if (isPrim && AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
+           if (isPrim && AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) {
+             fUseImproveKalman ? 
+               updatetrack->ImproveKalman(xyzVtx,ersVtx,xMSLrs,x2X0MSLrs,nMSLrs) : 
+               updatetrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
+           }
          } //apply vertex constrain              
          ntracks[ilayer]++;
        }  // create new hypothesis
@@ -1253,14 +1332,18 @@ void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdin
       } // loop over possible prolongations 
      
       // allow one prolongation without clusters
-      if (constrain && itrack<=1 && TMath::Abs(currenttrack1.GetNSkipped())<1.e-13 && deadzoneSPD==kFALSE && ntracks[ilayer]<100) {
+      if (constrain && itrack<=1 && TMath::Abs(currenttrack1.GetNSkipped())<1.e-13 && deadzoneSPD==kFALSE && ntracks[ilayer]<kMaxTr) {
        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);
-       if(AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
+       if(AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) {
+         fUseImproveKalman ? 
+           vtrack->ImproveKalman(xyzVtx,ersVtx,xMSLrs,x2X0MSLrs,nMSLrs) : 
+           vtrack->Improve(budgetToPrimVertex,xyzVtx,ersVtx);
+       }
        vtrack->IncrementNSkipped();
        ntracks[ilayer]++;
       }
@@ -1294,7 +1377,8 @@ void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdin
     TMath::Sort(ntracks[ilayer],normalizedchi2,nindexes[ilayer],kFALSE); 
     ntracks[ilayer] = TMath::Min(accepted,7+2*ilayer);
     if (ntracks[ilayer]<golden+2+ilayer) ntracks[ilayer]=TMath::Min(golden+2+ilayer,accepted);
-    if (ntracks[ilayer]>90) ntracks[ilayer]=90; 
+    //    if (ntracks[ilayer]>90) ntracks[ilayer]=90; 
+    if (ntracks[ilayer]>int(kMaxTr*0.9)) ntracks[ilayer]=int(kMaxTr*0.9); 
   } // end loop over layers
 
 
@@ -1363,7 +1447,7 @@ void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdin
   // update TPC V0 information
   //
   if (otrack->GetESDtrack()->GetV0Index(0)>0){    
-    Float_t fprimvertex[3]={GetX(),GetY(),GetZ()};
+    Float_t fprimvertex[3]={static_cast<Float_t>(GetX()),static_cast<Float_t>(GetY()),static_cast<Float_t>(GetZ())};
     for (Int_t i=0;i<3;i++){
       Int_t  index = otrack->GetESDtrack()->GetV0Index(i); 
       if (index==0) break;
@@ -1464,7 +1548,7 @@ fNMaxSigmaCl(3)
   fYB[0]=0;
   fYB[1]=0;
 
-  for (Int_t j=0; j<AliITSRecoParam::fgkMaxClusterPerLayer5; j++) {
+  for (Int_t j=0; j<AliITSRecoParam::kMaxClusterPerLayer5; j++) {
     for (Int_t j1=0; j1<6; j1++) {
       fClusters5[j1][j]=0;
       fClusterIndex5[j1][j]=-1;
@@ -1476,7 +1560,7 @@ fNMaxSigmaCl(3)
     }
   }
 
-  for (Int_t j=0; j<AliITSRecoParam::fgkMaxClusterPerLayer10; j++) {
+  for (Int_t j=0; j<AliITSRecoParam::kMaxClusterPerLayer10; j++) {
     for (Int_t j1=0; j1<11; j1++) {
       fClusters10[j1][j]=0;
       fClusterIndex10[j1][j]=-1;
@@ -1488,7 +1572,7 @@ fNMaxSigmaCl(3)
     }
   }
 
-  for (Int_t j=0; j<AliITSRecoParam::fgkMaxClusterPerLayer20; j++) {
+  for (Int_t j=0; j<AliITSRecoParam::kMaxClusterPerLayer20; j++) {
     for (Int_t j1=0; j1<21; j1++) {
       fClusters20[j1][j]=0;
       fClusterIndex20[j1][j]=-1;
@@ -1499,8 +1583,10 @@ fNMaxSigmaCl(3)
       fBy20[j1][1]=0;
     }
   }
-
-
+  for(Int_t i=0;i<AliITSRecoParam::kMaxClusterPerLayer;i++){
+    fClusters[i]=NULL;
+    fClusterIndex[i]=0;
+  }
 }
 //------------------------------------------------------------------------
 AliITStrackerMI::AliITSlayer::
@@ -1552,7 +1638,7 @@ fNMaxSigmaCl(3) {
   fYB[0]=0;
   fYB[1]=0;
 
 for (Int_t j=0; j<AliITSRecoParam::fgkMaxClusterPerLayer5; j++) {
for (Int_t j=0; j<AliITSRecoParam::kMaxClusterPerLayer5; j++) {
     for (Int_t j1=0; j1<6; j1++) {
       fClusters5[j1][j]=0;
       fClusterIndex5[j1][j]=-1;
@@ -1564,7 +1650,7 @@ fNMaxSigmaCl(3) {
     }
   }
 
-  for (Int_t j=0; j<AliITSRecoParam::fgkMaxClusterPerLayer10; j++) {
+  for (Int_t j=0; j<AliITSRecoParam::kMaxClusterPerLayer10; j++) {
     for (Int_t j1=0; j1<11; j1++) {
       fClusters10[j1][j]=0;
       fClusterIndex10[j1][j]=-1;
@@ -1576,7 +1662,7 @@ fNMaxSigmaCl(3) {
     }
   }
 
-  for (Int_t j=0; j<AliITSRecoParam::fgkMaxClusterPerLayer20; j++) {
+  for (Int_t j=0; j<AliITSRecoParam::kMaxClusterPerLayer20; j++) {
     for (Int_t j1=0; j1<21; j1++) {
       fClusters20[j1][j]=0;
       fClusterIndex20[j1][j]=-1;
@@ -1587,8 +1673,12 @@ fNMaxSigmaCl(3) {
       fBy20[j1][1]=0;
     }
   }
-
+  for(Int_t i=0;i<AliITSRecoParam::kMaxClusterPerLayer;i++){
+    fClusters[i]=NULL;
+    fClusterIndex[i]=0;
+  }
 }
+/*
 //------------------------------------------------------------------------
 AliITStrackerMI::AliITSlayer::AliITSlayer(const AliITSlayer& layer):
 fR(layer.fR),
@@ -1622,6 +1712,7 @@ fNMaxSigmaCl(layer.fNMaxSigmaCl)
 {
   //Copy constructor
 }
+*/
 //------------------------------------------------------------------------
 AliITStrackerMI::AliITSlayer::~AliITSlayer() {
   //--------------------------------------------------------------------
@@ -2281,6 +2372,46 @@ Double_t AliITStrackerMI::GetEffectiveThickness()
   }
   return d/(xn*xn);
 }
+
+//------------------------------------------------------------------------
+Int_t AliITStrackerMI::GetEffectiveThicknessLbyL(Double_t* xMS, Double_t* x2x0MS)
+{
+  //--------------------------------------------------------------------
+  // Returns the array of layers between the current layer and the vertex
+  //--------------------------------------------------------------------
+  //
+  if(fUseTGeo!=0) {
+    if(fxOverX0Layer[0]<0) BuildMaterialLUT("Layers");
+    if(fxOverX0Shield[0]<0) BuildMaterialLUT("Shields");
+    if(fxOverX0Pipe<0) BuildMaterialLUT("Pipe");
+  }
+
+  int nl = 0;
+  double x0 = 0;
+  for (int il=fI;il--;) {
+    //
+    if (il==3) {
+      x2x0MS[nl] = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(1) : fxOverX0Shield[1]);
+      xMS[nl++]  = AliITSRecoParam::GetrInsideShield(1);
+    }
+    else if (il==1) {
+      x2x0MS[nl] = (fUseTGeo==0 ? AliITSRecoParam::Getdshield(0) : fxOverX0Shield[0]);
+      xMS[nl++]  = AliITSRecoParam::GetrInsideShield(0);
+    }
+    //
+    x2x0MS[nl] = (fUseTGeo==0 ? fgLayers[il].GetThickness(0,0,x0) : fxOverX0Layer[il]);
+    xMS[nl++]  = fgLayers[il].GetR();
+    //
+  }
+  //
+  // beam pipe
+  x2x0MS[nl]  = (fUseTGeo==0 ? AliITSRecoParam::GetdPipe() : fxOverX0Pipe);
+  xMS[nl++]  = AliITSRecoParam::GetrPipe();
+  //
+  return nl;
+}
+
+
 //------------------------------------------------------------------------
 Int_t AliITStrackerMI::AliITSlayer::InRoad() const {
   //-------------------------------------------------------------------
@@ -2959,7 +3090,7 @@ Int_t AliITStrackerMI::GetOverlapTrack(const AliITStrackMI *track, Int_t trackID
     else{
       //
       Int_t tracks2[24], cluster[24];
-      for (Int_t i=0;i<trackindex;i++){ tracks2[i]=-1; cluster[i]=0;}
+      for (Int_t i=0;i<24;i++){ tracks2[i]=-1; cluster[i]=0;}
       Int_t index =0;
       //
       for (Int_t i=0;i<trackindex;i++){
@@ -3016,7 +3147,7 @@ Int_t AliITStrackerMI::GetOverlapTrack(const AliITStrackMI *track, Int_t trackID
   return sharedtrack;
 }
 //------------------------------------------------------------------------
-AliITStrackMI *  AliITStrackerMI::GetBest2Tracks(Int_t trackID1, Int_t trackID2, Float_t th0, Float_t th1){
+AliITStrackMI *  AliITStrackerMI::GetBest2Tracks(Int_t trackID1, Int_t trackID2, Float_t th0, Float_t th1,AliITStrackMI* original){
   //
   // try to find track hypothesys without conflicts
   // with minimal chi2;
@@ -3030,7 +3161,7 @@ AliITStrackMI *  AliITStrackerMI::GetBest2Tracks(Int_t trackID1, Int_t trackID2,
   AliITStrackMI * track10=(AliITStrackMI*) arr1->UncheckedAt(0);
   AliITStrackMI * track20=(AliITStrackMI*) arr2->UncheckedAt(0);
   if (track10->Pt()>0.5+track20->Pt()) return track10;
-
+  //
   for (Int_t itrack=0;itrack<entries1;itrack++){
     AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
     UnRegisterClusterTracks(track,trackID1);
@@ -3228,12 +3359,14 @@ AliITStrackMI *  AliITStrackerMI::GetBest2Tracks(Int_t trackID1, Int_t trackID2,
     track1->SetChi2MIP(8,index1);
     fBestTrackIndex[trackID1] =index1;
     UpdateESDtrack(track1, AliESDtrack::kITSin);
+    original->SetWinner(track1);
   }  
   else if (track10->GetChi2MIP(0)<th1){
     track10->SetChi2MIP(5,maxconflicts);
     track10->SetChi2MIP(6,maxchi2);    
     //    track10->UpdateESDtrack(AliESDtrack::kITSin);
     UpdateESDtrack(track10,AliESDtrack::kITSin);
+    original->SetWinner(track10);
   }   
   
   for (Int_t itrack=0;itrack<entries1;itrack++){
@@ -3283,13 +3416,11 @@ void AliITStrackerMI::AddTrackHypothesys(AliITStrackMI * track, Int_t esdindex)
   // add track to the list of hypothesys
   //------------------------------------------------------------------
 
-  if (esdindex>=fTrackHypothesys.GetEntriesFast()) 
-    fTrackHypothesys.Expand(TMath::Max(fTrackHypothesys.GetSize(),esdindex*2+10));
   //
   TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
   if (!array) {
     array = new TObjArray(10);
-    fTrackHypothesys.AddAt(array,esdindex);
+    fTrackHypothesys.AddAtAndExpand(array,esdindex);
   }
   array->AddLast(track);
 }
@@ -3309,6 +3440,7 @@ void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mo
   Float_t minchi2=10000;
   Int_t maxn=0;
   AliITStrackMI * besttrack=0;
+  //
   for (Int_t itrack=0;itrack<array->GetEntriesFast();itrack++){
     AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
     if (!track) continue;
@@ -3324,6 +3456,7 @@ void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mo
     if (chi2<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)){
       if (track->GetNumberOfClusters()<maxn) continue;
       maxn = track->GetNumberOfClusters();
+      //      if (fSelectBestMIP03 && track->GetChi2MIP(3)>0) chi2 *= track->GetChi2MIP(3); // RS    
       if (chi2<minchi2){
        minchi2=chi2;
        besttrack=track;
@@ -3358,10 +3491,13 @@ 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);
+      AliDebug(2,Form("track %d  ncls %d\n",itrack,track->GetNumberOfClusters()));      
+      double chi2t = GetNormalizedChi2(track, mode);
+      track->SetChi2MIP(0,chi2t);
+      if (chi2t<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)) {
+       if (fSelectBestMIP03 && track->GetChi2MIP(3)>0) chi2t *= track->GetChi2MIP(3); // RS
+       chi2[itrack] = chi2t;
+      }
       else{
        if (track->GetConstrain() || track->GetNumberOfClusters()>5){  //keep best short tracks - without vertex constrain
          delete array->RemoveAt(itrack);            
@@ -3389,16 +3525,18 @@ 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));
+      double chi2t = GetNormalizedChi2(track, mode);
+      track->SetChi2MIP(0,chi2t);
       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
-       {
-         if (track->GetConstrain() || track->GetNumberOfClusters()>5){  //keep best short tracks - without vertex constrain
-           delete array->RemoveAt(itrack);     
-         }
+      if (track->GetChi2MIP(0)<AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(0)) {
+       if (fSelectBestMIP03 && track->GetChi2MIP(3)>0) chi2t *= track->GetChi2MIP(3); // RS
+       chi2[itrack] = chi2t;  //-0*(track->GetNumberOfClusters()+track->GetNDeadZone()); 
+      }
+      else {
+       if (track->GetConstrain() || track->GetNumberOfClusters()>5){  //keep best short tracks - without vertex constrain
+         delete array->RemoveAt(itrack);       
        }
+      }
     }   
   }
   entries = array->GetEntriesFast();  
@@ -3470,6 +3608,7 @@ AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI
   //-------------------------------------------------------------
   // try to find best hypothesy
   // currently - minimal chi2 of track+backpropagated track+matching to the tpc track
+  // RS: optionally changing this to product of Chi2MIP(0)*Chi2MIP(3) == (chi2*chi2_interpolated)
   //-------------------------------------------------------------
   if (fTrackHypothesys.GetEntriesFast()<=esdindex) return 0;
   TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
@@ -3501,7 +3640,8 @@ AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI
     if (track->GetConstrain()) {
       if (!CorrectForPipeMaterial(backtrack,"inward")) continue;
       if (AliITSReconstructor::GetRecoParam()->GetImproveWithVertex()) {
-       if (!backtrack->Improve(0,xyzVtx,ersVtx)) continue;     
+       if (fUseImproveKalman) {if (!backtrack->ImproveKalman(xyzVtx,ersVtx,0,0,0)) continue;}
+       else                   {if (!backtrack->Improve(0,xyzVtx,ersVtx)) continue;}
       }
       backtrack->ResetCovariance(10.);      
     }else{
@@ -3528,7 +3668,7 @@ AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI
     forwardtrack = new(forwardtrack) AliITStrackMI(*original);
     forwardtrack->ResetClusters();
     x = track->GetX();
-    RefitAt(x,forwardtrack,track);
+    if (!RefitAt(x,forwardtrack,track) && fSelectBestMIP03) continue;  // w/o fwd track MIP03 is meaningless
     track->SetChi2MIP(2,NormalizedChi2(forwardtrack,0));    
     if  (track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2)*6.0)  continue;
     if  (!(track->GetConstrain())&&track->GetChi2MIP(2)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(2))  continue;
@@ -3551,7 +3691,9 @@ AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI
       track->SetChi2MIP(3,1000);
       continue; 
     }
-    Double_t chi2 = track->GetChi2MIP(0)+track->GetNUsed();    
+    Double_t chi2 = track->GetChi2MIP(0); // +track->GetNUsed();    //RS
+    if (fSelectBestMIP03) chi2 *= track->GetChi2MIP(3);
+    else chi2 += track->GetNUsed();
     //
     for (Int_t ichi=0;ichi<5;ichi++){
       forwardtrack->SetChi2MIP(ichi, track->GetChi2MIP(ichi));
@@ -3579,8 +3721,10 @@ AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI
     if (!track) continue;
     
     if (accepted>checkmax || track->GetChi2MIP(3)>AliITSReconstructor::GetRecoParam()->GetMaxChi2PerCluster(3)*6. || 
-       (track->GetNumberOfClusters()<besttrack->GetNumberOfClusters()-1.)||
-       track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*besttrack->GetNUsed()+3.){
+       (track->GetNumberOfClusters()<besttrack->GetNumberOfClusters()-1.)
+       // RS: don't apply this cut when fSelectBestMIP03 is on
+       || (!fSelectBestMIP03 && (track->GetChi2MIP(0)>besttrack->GetChi2MIP(0)+2.*besttrack->GetNUsed()+3.))
+       ){
       if (track->GetConstrain() || track->GetNumberOfClusters()>5){  //keep best short tracks - without vertex constrain
        delete array->RemoveAt(i);    
        continue;
@@ -3614,6 +3758,9 @@ AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI
     longtrack =track;
   }
   //if (longtrack) besttrack=longtrack;
+  //
+  // RS do shared cluster analysis here only if the new sharing analysis is not requested
+  //RRR if (fFlagFakes) return besttrack;
 
   Int_t list[6];
   AliITSRecPoint * clist[6];
@@ -3630,7 +3777,7 @@ AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI
     Int_t sharedtrack = GetOverlapTrack(besttrack, esdindex, nshared, list, overlist);
     if (sharedtrack>=0){
       //
-      besttrack = GetBest2Tracks(esdindex,sharedtrack,10,5.5);     
+      besttrack = GetBest2Tracks(esdindex,sharedtrack,10,5.5,original);     
       if (besttrack){
        shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
       }
@@ -3711,13 +3858,15 @@ void  AliITStrackerMI::GetBestHypothesysMIP(TObjArray &itsTracks)
       }
       if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()<minn) continue;
       Float_t chi2 = trackHyp->GetChi2MIP(0);
-      if (fAfterV0){
+      if (fSelectBestMIP03) chi2 *= trackHyp->GetChi2MIP(3);
+      if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()>minn) maxchi2 = chi2; //trackHyp->GetChi2MIP(0);
+      //
+      if (fAfterV0){ // ??? RS
        if (!trackHyp->GetGoldV0()&&trackHyp->GetConstrain()==kFALSE) chi2+=5;
       }
-      if (trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone()>minn) maxchi2 = trackHyp->GetChi2MIP(0);       
-      //
       if (chi2 > maxchi2) continue;
-      minn= trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone();
+      minn = trackHyp->GetNumberOfClusters()+trackHyp->GetNDeadZone();
+      if (fSelectBestMIP03) minn++; // allow next to longest to win
       maxchi2 = chi2;
       longtrack=trackHyp;
     }    
@@ -3744,22 +3893,156 @@ void  AliITStrackerMI::GetBestHypothesysMIP(TObjArray &itsTracks)
        Int_t sharedtrack = GetOverlapTrack(longtrack, i, nshared, list, overlist);
        //if (sharedtrack==-1) sharedtrack=0;
        if (sharedtrack>=0) {       
-         besttrack = GetBest2Tracks(i,sharedtrack,10,5.5);                       
+         besttrack = GetBest2Tracks(i,sharedtrack,10,5.5,track);                         
        }
       }   
       if (besttrack&&fAfterV0) {
        UpdateESDtrack(besttrack,AliESDtrack::kITSin);
+       track->SetWinner(besttrack);
       }
       if (besttrack) {
-       if (fConstraint[fPass]) UpdateESDtrack(besttrack,AliESDtrack::kITSin);
+       if (fConstraint[fPass]) {
+         UpdateESDtrack(besttrack,AliESDtrack::kITSin);
+         track->SetWinner(besttrack);
+       }
        if (besttrack->GetChi2MIP(0)+besttrack->GetNUsed()>1.5 && fConstraint[fPass]) {
          if ( TMath::Abs(besttrack->GetD(0))>0.1 || 
               TMath::Abs(besttrack->GetD(1))>0.1 ) track->SetReconstructed(kFALSE);    
        }       
       }
-    }    
+    }
   }
 } 
+
+//------------------------------------------------------------------------
+void AliITStrackerMI::FlagFakes(const TObjArray &itsTracks)
+{
+  //
+  // RS: flag those tracks which are suxpected to have fake clusters
+  //
+  const double kThreshPt = 0.5;
+  AliRefArray *refArr[6];
+  //
+  for (int i=0;i<6;i++) {
+    int ncl = fgLayers[i].GetNumberOfClusters();
+    refArr[i] = new AliRefArray(ncl,TMath::Min(ncl,1000));
+  }
+  Int_t nentries = itsTracks.GetEntriesFast();
+  //
+  // fill cluster->track associations
+  for (Int_t itr=0;itr<nentries;itr++){
+    AliITStrackMI* track = (AliITStrackMI*)itsTracks.UncheckedAt(itr);   
+    if (!track) continue;
+    AliITStrackMI* trackITS = track->GetWinner();
+    if (!trackITS) continue;
+    for (int il=trackITS->GetNumberOfClusters();il--;) {
+      int idx = trackITS->GetClusterIndex(il);
+      Int_t l=(idx & 0xf0000000) >> 28, c=(idx & 0x0fffffff) >> 00;
+      //      if (c>fgLayers[l].GetNumberOfClusters()) continue;
+      refArr[l]->AddReference(c, itr);
+    }
+  }
+  //
+  const UInt_t kMaxRef = 100;
+  UInt_t crefs[kMaxRef];
+  Int_t ncrefs=0;
+  // process tracks with shared clusters
+  for (int itr=0;itr<nentries;itr++){
+    AliITStrackMI* track0 = (AliITStrackMI*)itsTracks.UncheckedAt(itr);  
+    AliITStrackMI* trackH0 = track0->GetWinner(); 
+    if (!trackH0) continue;
+    AliESDtrack* esd0 = track0->GetESDtrack();
+    //
+    for (int il=0;il<trackH0->GetNumberOfClusters();il++) {
+      int idx = trackH0->GetClusterIndex(il);
+      Int_t l=(idx & 0xf0000000) >> 28, c=(idx & 0x0fffffff) >> 00;
+      ncrefs = refArr[l]->GetReferences(c,crefs,kMaxRef);                
+      if (ncrefs<2) continue; // there will be always self-reference, for sharing needs at least 2
+      esd0->SetITSSharedFlag(l); 
+      for (int ir=ncrefs;ir--;) {
+       if (int(crefs[ir]) <= itr) continue; // ==:selfreference, <: the same pair will be checked with >
+       AliITStrackMI* track1 = (AliITStrackMI*)itsTracks.UncheckedAt(crefs[ir]);
+       AliITStrackMI* trackH1 = track1->GetWinner(); 
+       AliESDtrack* esd1 = track1->GetESDtrack();
+       esd1->SetITSSharedFlag(l);
+       //
+       double pt0 = trackH0->Pt(), pt1 = trackH1->Pt(), res = 0.;      
+       if      (pt0>kThreshPt && pt0-pt1>0.2+0.2*(pt0-kThreshPt) ) res = -100;
+       else if (pt1>kThreshPt && pt1-pt0>0.2+0.2*(pt1-kThreshPt) ) res = 100;
+
+       // select the one with smallest chi2's product
+       res += trackH0->GetChi2MIP(0)*trackH0->GetChi2MIP(3); 
+       res -= trackH1->GetChi2MIP(0)*trackH1->GetChi2MIP(3);
+       //
+       if (res<0) esd1->SetITSFakeFlag();  // esd0 is winner
+       else       esd0->SetITSFakeFlag();  // esd1 is winner
+      }
+      //
+    }
+    //
+  }
+  //
+  for (int i=6;i--;) delete refArr[i];
+}
+
+
+
+//------------------------------------------------------------------------
+void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
+  //--------------------------------------------------------------------
+  //This function "cooks" a track label. If label<0, this track is fake.
+  //--------------------------------------------------------------------
+  const int kMaxLbPerCl = 3;
+  int lbID[36],lbStat[36];
+  Int_t nLab=0, nCl = track->GetNumberOfClusters();
+  //
+  //  track->SetLabel(-1);
+  //  track->SetFakeRatio(0);
+  //
+  for (Int_t i=0;i<nCl;i++) { // fill all labels
+    Int_t cindex = track->GetClusterIndex(i);
+    //    Int_t l=(cindex & 0xf0000000) >> 28;
+    AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
+    //
+    for (int imc=0;imc<kMaxLbPerCl;imc++) { // labels within single cluster
+      int trLb = cl->GetLabel(imc);
+      if (trLb<0) break;
+      // search this mc track in already accounted ones
+      int iLab;
+      for (iLab=0;iLab<nLab;iLab++) if (lbID[iLab]==trLb) break;
+      if (iLab<nLab) lbStat[iLab]++;
+      else {
+       lbID[nLab] = trLb;
+       lbStat[nLab++] = 1;
+      }
+    } // loop over given cluster's labels   
+  } // loop over clusters
+  //
+  if (nLab<1) return; // no labels at all
+  //
+  Int_t tpcLabel=-1; 
+  if (track->GetESDtrack() && track->GetESDtrack()->IsOn(AliESDtrack::kTPCin)){
+    tpcLabel = TMath::Abs(track->GetESDtrack()->GetTPCLabel());
+  }
+  //
+  // find majority label
+  if (nCl && nLab) {
+    int maxLab=0,tpcLabID=-1;
+    for (int ilb=nLab;ilb--;) {
+      int st = lbStat[ilb];
+      if (lbStat[maxLab]<st) maxLab = ilb;
+      if (lbID[ilb] == tpcLabel) tpcLabID = ilb;
+    }
+    // if there is an equal choice, prefer ITS label consistent with TPC label
+    if (tpcLabel>0 && (tpcLabID!=maxLab) && lbStat[maxLab]==lbStat[tpcLabID]) maxLab=tpcLabID;
+                                                                              
+    track->SetFakeRatio(1.-float(lbStat[maxLab])/nCl);
+    track->SetLabel( lbStat[maxLab]>=nCl-wrong ? lbID[maxLab] : -lbID[maxLab]);
+  }
+  //
+}
+
+/*
 //------------------------------------------------------------------------
 void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
   //--------------------------------------------------------------------
@@ -3794,9 +4077,10 @@ void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
    } else {
      track->SetLabel(tpcLabel);
    }
-   AliDebug(2,Form(" nls %d wrong %d  label %d  tpcLabel %d\n",nclusters,nwrong,track->GetLabel(),tpcLabel));
-   
+   AliDebug(2,Form(" nls %d wrong %d  label %d  tpcLabel %d\n",nclusters,nwrong,track->GetLabel(),tpcLabel)); 
 }
+*/
+
 //------------------------------------------------------------------------
 void AliITStrackerMI::CookdEdx(AliITStrackMI* track){
   //
@@ -4043,7 +4327,7 @@ void AliITStrackerMI::BuildMaterialLUT(TString material) {
   } else {
     Error("BuildMaterialLUT","Wrong layer name\n");
   }
-
+  const double kAngEps = 1e-4; // tiny slope to avoid tracks strictly normal to Z axis
   for(Int_t imat=ifirst; imat<=ilast; imat++) {
     Double_t param[5]={0.,0.,0.,0.,0.};
     for (Int_t i=0; i<n; i++) {
@@ -4055,8 +4339,9 @@ void AliITStrackerMI::BuildMaterialLUT(TString material) {
       point1[2] = z;
       point2[0] = rmax[imat]*cosphi;
       point2[1] = rmax[imat]*sinphi;
-      point2[2] = z;
+      point2[2] = z+(rmax[imat]-rmin[imat])*kAngEps;
       AliTracker::MeanMaterialBudget(point1,point2,mparam);
+      if (mparam[1]>999) {n--; continue;}  // skip anomalous values in failed propagation
       for(Int_t j=0;j<5;j++) param[j]+=mparam[j];
     }
     for(Int_t j=0;j<5;j++) param[j]/=(Float_t)n;
@@ -4577,6 +4862,7 @@ Int_t AliITStrackerMI::CheckDeadZone(AliITStrackMI *track,
     }
   }
 
+  if(zlocmin>zlocmax)return 0;
   Int_t nChipsInRoad = segm->GetChipsInLocalWindow(chipsInRoad,zlocmin,zlocmax,xlocmin,xlocmax);
   AliDebug(2,Form("lay %d nChipsInRoad %d",ilayer,nChipsInRoad));
   if (!nChipsInRoad) return 0;
@@ -4658,7 +4944,7 @@ Bool_t AliITStrackerMI::LocalModuleCoord(Int_t ilayer,Int_t idet,
 }
 //------------------------------------------------------------------------
 //------------------------------------------------------------------------
-Bool_t AliITStrackerMI::IsOKForPlaneEff(const AliITStrackMI* track, const Int_t *clusters, Int_t ilayer) const {
+Bool_t AliITStrackerMI::IsOKForPlaneEff(const AliITStrackMI* track, const Int_t *clusters, Int_t ilayer){
 //
 // Method to be optimized further: 
 // Aim: decide whether a track can be used for PlaneEff evaluation
@@ -4694,19 +4980,19 @@ 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_out=0; Int_t ncl_in=0;
+  Int_t nclout=0; Int_t nclin=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_out++;
-if(index[lay]>=0)ncl_out++;
+   // if (tmp.GetClIndex(lay)>=0) nclout++;
+if(index[lay]>=0)nclout++;
   }
   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 (index[lay]>=0) ncl_in++; 
+   if (index[lay]>=0) nclin++; 
   }
-  Int_t ncl=ncl_out+ncl_in;
+  Int_t ncl=nclout+nclin;
   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 );
@@ -4714,7 +5000,7 @@ if(index[lay]>=0)ncl_out++;
   if(ilayer==0) nextin=kTRUE; // you are already on the innermost layer
   else nextin = ((index[ilayer-1]>=0)? kTRUE : kFALSE );
   // maximum number of missing clusters allowed in outermost layers
-  if(ncl_out<AliITSgeomTGeo::kNLayers-(ilayer+1)-AliITSReconstructor::GetRecoParam()->GetMaxMissingClustersOutPlaneEff()) 
+  if(nclout<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()) 
@@ -4749,9 +5035,20 @@ if(index[lay]>=0)ncl_out++;
   //
   Double_t nsigx=AliITSReconstructor::GetRecoParam()->GetNSigXFromBoundaryPlaneEff();
   Double_t nsigz=AliITSReconstructor::GetRecoParam()->GetNSigZFromBoundaryPlaneEff();
-  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
+  Double_t distx=AliITSReconstructor::GetRecoParam()->GetDistXFromBoundaryPlaneEff();
+  Double_t distz=AliITSReconstructor::GetRecoParam()->GetDistZFromBoundaryPlaneEff();
+  Double_t dx=nsigx*TMath::Sqrt(tmp.GetSigmaY2()) + distx;
+  // those are precisions in the tracking reference system
+  Double_t dz=nsigz*TMath::Sqrt(tmp.GetSigmaZ2()) + distz;
+  // Use it also for the module reference system, as it is done for RecPoints
+
+  if(AliITSReconstructor::GetRecoParam()->GetSwitchOnMaxDistNSigFrmBndPlaneEff()){
+   if(nsigx*TMath::Sqrt(tmp.GetSigmaY2())<=distx) dx -= nsigx*TMath::Sqrt(tmp.GetSigmaY2());
+   else dx -= distx;
+
+   if(nsigz*TMath::Sqrt(tmp.GetSigmaZ2())<=distz) dz -= nsigz*TMath::Sqrt(tmp.GetSigmaZ2());
+   else dz -= distz;
+  }
 
   // exclude tracks at boundary between detectors
   //Double_t boundaryWidth=AliITSRecoParam::GetBoundaryWidthPlaneEff();
@@ -4763,6 +5060,28 @@ if(index[lay]>=0)ncl_out++;
        (locx+dx > blockXmx-boundaryWidth) ||
        (locz-dz < blockZmn+boundaryWidth) ||
        (locz+dz > blockZmx-boundaryWidth) ) return kFALSE;
+
+  if(ilayer==0){
+       const AliESDEvent *myesd = ((AliESDtrack*)tmp.GetESDtrack())->GetESDEvent();
+       //The beam pipe
+       if (CorrectForPipeMaterial(&tmp,"inward")) {
+          const AliESDVertex* vtx = myesd->GetVertex();
+          if(!vtx) return kFALSE;
+          Double_t ddz[2],cov[3];
+          Double_t maxD=3.;
+          if(!tmp.PropagateToDCA(vtx,AliTracker::GetBz(),maxD,ddz,cov)) return kFALSE;
+          if(TMath::Abs(ddz[0])>=AliITSReconstructor::GetRecoParam()->GetDCACutPlaneEff()) return kFALSE;
+
+          Double_t covar[6]; vtx->GetCovMatrix(covar);
+          Double_t p[2]={tmp.GetParameter()[0]-ddz[0],tmp.GetParameter()[1]-ddz[1]};
+          Double_t c[3]={covar[2],0.,covar[5]};
+          Double_t chi2= ((AliESDtrack*)tmp.GetESDtrack())->GetPredictedChi2(p,c);
+          if (chi2>AliITSReconstructor::GetRecoParam()->GetVertexChi2CutPlaneEff()) return kFALSE;  // Use this to cut on chi^2
+
+       } else return kFALSE;
+    }
+
+
   return kTRUE;
 }
 //------------------------------------------------------------------------
@@ -4841,9 +5160,32 @@ void AliITStrackerMI::UseTrackForPlaneEff(const AliITStrackMI* track, Int_t ilay
     msz *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadZNonC();
     msy *= AliITSReconstructor::GetRecoParam()->GetNSigma2RoadYNonC();
   }
+
+  if(AliITSReconstructor::GetRecoParam()->GetSwitchOffStdSearchClusPlaneEff()){
+     Double_t nsigx=AliITSReconstructor::GetRecoParam()->GetNSigXSearchClusterPlaneEff();
+     Double_t nsigz=AliITSReconstructor::GetRecoParam()->GetNSigZSearchClusterPlaneEff();
+     Double_t distx=AliITSReconstructor::GetRecoParam()->GetDistXSearchClusterPlaneEff();
+     Double_t distz=AliITSReconstructor::GetRecoParam()->GetDistZSearchClusterPlaneEff();
+     msy = nsigx*TMath::Sqrt(tmp.GetSigmaY2()) + distx;
+     msz = nsigz*TMath::Sqrt(tmp.GetSigmaZ2()) + distz;
+
+  if(AliITSReconstructor::GetRecoParam()->GetSwitchOnMaxDistNSigSrhClusPlaneEff()){
+     if(nsigx*TMath::Sqrt(tmp.GetSigmaY2())<=distx) msy -= nsigx*TMath::Sqrt(tmp.GetSigmaY2());
+     else msy -= distx;
+
+     if(nsigz*TMath::Sqrt(tmp.GetSigmaZ2())<=distz) msz -= nsigz*TMath::Sqrt(tmp.GetSigmaZ2());
+     else msz -= distz;
+  }
+
+  msy *= msy;
+  msz *= msz;
+
+  }
+
+  if(msz==0 || msy==0){AliWarning("UseTrackForPlaneEff: null search frame"); return;}
+    
   msz = 1./msz; // 1/RoadZ^2
   msy = 1./msy; // 1/RoadY^2
-//
 
   const AliITSRecPoint *cl=0; Int_t clidx=-1, ci=-1;
   Int_t idetc=-1;
@@ -4890,13 +5232,36 @@ void AliITStrackerMI::UseTrackForPlaneEff(const AliITStrackMI* track, Int_t ilay
   }
   if(!fPlaneEff->UpDatePlaneEff(found,key))
        AliWarning(Form("UseTrackForPlaneEff: cannot UpDate PlaneEff for key=%d",key));
+
+// this for FO efficiency studies (only for SPD) // 
+   UInt_t keyFO=999999;
+   Bool_t foundFO=kFALSE;
+   if(ilayer<2){ //ONLY SPD layers for FastOr studies
+    TBits mapFO = fkDetTypeRec->GetFastOrFiredMap();
+    Int_t phase = (fEsd->GetBunchCrossNumber())%4;
+    if(!fSPDChipIntPlaneEff[key]){
+      AliITSPlaneEffSPD spd; 
+      keyFO = spd.SwitchChipKeyNumbering(key);
+      if(mapFO.TestBitNumber(keyFO))foundFO=kTRUE;
+       keyFO = key + (AliITSPlaneEffSPD::kNModule*AliITSPlaneEffSPD::kNChip)*(phase+1);
+       if(keyFO<AliITSPlaneEffSPD::kNModule*AliITSPlaneEffSPD::kNChip) {
+         AliWarning(Form("UseTrackForPlaneEff: too small keyF0 (= %d), setting it to 999999",keyFO));
+         keyFO=999999;
+       }
+       if(!fPlaneEff->UpDatePlaneEff(foundFO,keyFO))
+          AliWarning(Form("UseTrackForPlaneEff: cannot UpDate PlaneEff for FastOR for key=%d",keyFO));
+     }
+  }
+  
+
+
   if(fPlaneEff->GetCreateHistos()&&  AliITSReconstructor::GetRecoParam()->GetHistoPlaneEff()) {
     Float_t tr[4]={99999.,99999.,9999.,9999.};    // initialize to high values 
     Float_t clu[4]={-99999.,-99999.,9999.,9999.}; // (in some cases GetCov fails) 
     Int_t cltype[2]={-999,-999};
                                                           // and the module
 
-Float_t AngleModTrack[3]={99999.,99999.,99999.}; // angles (phi, z and "absolute angle") between the track and the mormal to the module (see below)
+    Float_t angleModTrack[3]={99999.,99999.,99999.}; // angles (phi, z and "absolute angle") between the track and the mormal to the module (see below)
 
     tr[0]=locx;
     tr[1]=locz;
@@ -4966,14 +5331,65 @@ Float_t AngleModTrack[3]={99999.,99999.,99999.}; // angles (phi, z and "absolute
     if((phiNorm-phiPt)>TMath::Pi()) anglet*=-1.;
     anglet *= 180./TMath::Pi();
 
-     AngleModTrack[2]=(Float_t) angle;
-     AngleModTrack[0]=(Float_t) anglet;
+     angleModTrack[2]=(Float_t) angle;
+     angleModTrack[0]=(Float_t) anglet;
      // now the "angle in z" (much easier, i.e. the angle between the z axis and the track momentum + 90)
-    AngleModTrack[1]=TMath::ACos(tgl/TMath::Sqrt(tgl*tgl+1.));
-    AngleModTrack[1]-=TMath::Pi()/2.; // range of angle is -pi/2 , pi/2
-    AngleModTrack[1]*=180./TMath::Pi(); // in degree
+    angleModTrack[1]=TMath::ACos(tgl/TMath::Sqrt(tgl*tgl+1.));
+    angleModTrack[1]-=TMath::Pi()/2.; // range of angle is -pi/2 , pi/2
+    angleModTrack[1]*=180./TMath::Pi(); // in degree
+
+    fPlaneEff->FillHistos(key,found,tr,clu,cltype,angleModTrack);
 
-      fPlaneEff->FillHistos(key,found,tr,clu,cltype,AngleModTrack);
+    // For FO efficiency studies of SPD 
+    if(ilayer<2 && !fSPDChipIntPlaneEff[key]) fPlaneEff->FillHistos(keyFO,foundFO,tr,clu,cltype,angleModTrack);
   }
+  if(ilayer<2) fSPDChipIntPlaneEff[key]=kTRUE;
 return;
 }
+
+Int_t AliITStrackerMI::FindClusterOfTrack(int label, int lr, int* store) const //RS
+{
+  // find the MC cluster for the label
+  return fgLayers[lr].FindClusterForLabel(label,store);
+}
+
+/*
+Int_t AliITStrackerMI::GetPattern(const AliITStrackMI* track, char* patt)
+{
+  // creates pattarn of hits marking fake/corrects by f/c. Used for debugging (RS) 
+  strncpy(patt,"......",6); 
+  int tpcLabel = 0;
+  if (track->GetESDtrack()) tpcLabel = track->GetESDtrack()->GetTPCLabel();
+  //
+  int nwrong = 0;
+  for (Int_t i=0;i<track->GetNumberOfClusters();i++){
+    Int_t cindex = track->GetClusterIndex(i);
+    Int_t l=(cindex & 0xf0000000) >> 28;
+    AliITSRecPoint *cl = (AliITSRecPoint*)GetCluster(cindex);
+    Int_t isWrong=1;
+    for (Int_t ind=0;ind<3;ind++) if (cl->GetLabel(ind)==TMath::Abs(tpcLabel)) isWrong=0;
+    patt[l] = isWrong ? 'f':'c';
+    nwrong+=isWrong;
+  }
+  return nwrong;
+}
+*/
+//------------------------------------------------------------------------
+Int_t AliITStrackerMI::AliITSlayer::FindClusterForLabel(Int_t label, Int_t *store) const
+{ //RS
+  //--------------------------------------------------------------------
+
+  int nfound = 0;
+  for (int ic=0;ic<fN;ic++) {
+    const AliITSRecPoint *cl = GetCluster(ic);
+    for (int i=0;i<3;i++) if (cl->GetLabel(i)==label) {
+       if (nfound<50) {
+         if (store) store[nfound] = ic;
+         nfound++;
+       }
+       break;
+      }
+  }
+  return nfound;
+}
+