(Marian)
[u/mrichter/AliRoot.git] / TPC / AliTPCtrackerMI.cxx
index c309267..ce18704 100644 (file)
 //
 //   Origin: Marian Ivanov   Marian.Ivanov@cern.ch
 // 
-//  AliTPC parallel tracker - 
-//  How to use?  - 
-//  run AliTPCFindClusters.C macro - clusters neccessary for tracker are founded
-//  run AliTPCFindTracksMI.C macro - to find tracks
-//  tracks are written to AliTPCtracks.root file
-//  for comparison also seeds are written to the same file - to special branch
+//  AliTPC parallel tracker
 //-------------------------------------------------------
 
 
@@ -35,6 +30,7 @@
 #include <TFile.h>
 #include <TObjArray.h>
 #include <TTree.h>
+#include "AliLog.h"
 
 #include "AliComplexCluster.h"
 #include "AliESD.h"
@@ -54,6 +50,9 @@
 #include "AliESDkink.h"
 #include "AliPID.h"
 #include "TTreeStream.h"
+#include "AliAlignObj.h"
+#include "AliTrackPointArray.h"
+
 //
 
 ClassImp(AliTPCtrackerMI)
@@ -125,13 +124,13 @@ Int_t AliTPCtrackerMI::UpdateTrack(AliTPCseed * track, Int_t accept){
   track->fClusterPointer[track->fRow] = c;  
   //
 
-  Float_t angle2 = track->GetSnp()*track->GetSnp();
-  angle2 = TMath::Sqrt(angle2/(1-angle2)); 
+  Double_t angle2 = track->GetSnp()*track->GetSnp();
   //
   //SET NEW Track Point
   //
-  //  if (debug)
+  if (angle2<1) //PH sometimes angle2 is very big. To be investigated...
   {
+    angle2 = TMath::Sqrt(angle2/(1-angle2)); 
     AliTPCTrackerPoint   &point =*(track->GetTrackPoint(track->fRow));
     //
     point.SetSigmaY(c->GetSigmaY2()/track->fCurrentSigmaY2);
@@ -452,6 +451,7 @@ void AliTPCtrackerMI::FillESD(TObjArray* arr)
        Int_t found,foundable,shared;
        pt->GetClusterStatistic(138,158,found, foundable,shared,kFALSE);
        if (found<15) continue;
+       if (foundable<=0) continue;
        if (pt->fNShared/float(pt->GetNumberOfClusters())>0.2) continue;
        if (float(found)/float(foundable)<0.8) continue;
        //
@@ -642,7 +642,7 @@ Double_t AliTPCtrackerMI::ErrY2(AliTPCseed* seed, AliTPCclusterMI * cl){
   Float_t z = TMath::Abs(fParam->GetZLength()-TMath::Abs(seed->GetZ()));
   Int_t ctype = cl->GetType();  
   Float_t padlength= GetPadPitchLength(seed->fRow);
-  Float_t angle2 = seed->GetSnp()*seed->GetSnp();
+  Double_t angle2 = seed->GetSnp()*seed->GetSnp();
   angle2 = angle2/(1-angle2); 
   //
   //cluster "quality"
@@ -777,7 +777,7 @@ Double_t AliTPCtrackerMI::ErrZ2(AliTPCseed* seed, AliTPCclusterMI * cl){
   Int_t ctype = cl->GetType();  
   Float_t padlength= GetPadPitchLength(seed->fRow);
   //
-  Float_t angle2 = seed->GetSnp()*seed->GetSnp();
+  Double_t angle2 = seed->GetSnp()*seed->GetSnp();
   //  if (angle2<0.6) angle2 = 0.6;
   angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2)); 
   //
@@ -1128,6 +1128,9 @@ Int_t  AliTPCtrackerMI::LoadClusters()
     //  
     Int_t sec,row;
     fParam->AdjustSectorRow(clrow->GetID(),sec,row);
+    for (Int_t icl=0; icl<clrow->GetArray()->GetEntriesFast(); icl++){
+      Transform((AliCluster*)(clrow->GetArray()->At(icl)));
+    }
     //
     AliTPCRow * tpcrow=0;
     Int_t left=0;
@@ -1190,6 +1193,21 @@ void AliTPCtrackerMI::UnloadClusters()
   return ;
 }
 
+void   AliTPCtrackerMI::Transform(AliCluster * cluster){
+  //
+  // 
+  //
+  //if (!fParam->IsGeoRead()) fParam->ReadGeoMatrices();
+  TGeoHMatrix  *mat = fParam->GetClusterMatrix(cluster->GetDetector());
+  //TGeoHMatrix  mat;
+  Double_t pos[3]= {cluster->GetX(),cluster->GetY(),cluster->GetZ()};
+  Double_t posC[3];
+  //mat.LocalToMaster(pos,posC);
+  mat->LocalToMaster(pos,posC);
+  cluster->SetX(posC[0]);
+  cluster->SetY(posC[1]);
+  cluster->SetZ(posC[2]);
+}
 
 //_____________________________________________________________________________
 Int_t AliTPCtrackerMI::LoadOuterSectors() {
@@ -1295,6 +1313,7 @@ AliTPCclusterMI *AliTPCtrackerMI::GetClusterMI(Int_t index) const {
   //--------------------------------------------------------------------
   //       Return pointer to a given cluster
   //--------------------------------------------------------------------
+  if (index<0) return 0; // no cluster
   Int_t sec=(index&0xff000000)>>24; 
   Int_t row=(index&0x00ff0000)>>16; 
   Int_t ncl=(index&0x00007fff)>>00;
@@ -1302,6 +1321,11 @@ AliTPCclusterMI *AliTPCtrackerMI::GetClusterMI(Int_t index) const {
   const AliTPCRow * tpcrow=0;
   AliTPCclusterMI * clrow =0;
 
+  if (sec<0 || sec>=fkNIS*4) {
+    AliWarning(Form("Wrong sector %d",sec));
+    return 0x0;
+  }
+
   if (sec<fkNIS*2){
     tpcrow = &(fInnerSec[sec%fkNIS][row]);
     if (tpcrow==0) return 0;
@@ -1367,9 +1391,9 @@ Int_t AliTPCtrackerMI::FollowToNext(AliTPCseed& t, Int_t nr) {
       if (TMath::Abs(angle-t.GetAlpha())>0.001){
        Double_t rotation = angle-t.GetAlpha();
        t.fRelativeSector= relativesector;
-       t.Rotate(rotation);     
+       if (!t.Rotate(rotation)) return 0;      
       }
-      t.PropagateTo(x);
+      if (!t.PropagateTo(x)) return 0;
       //
       t.fCurrentCluster = cl; 
       t.fRow = nr;
@@ -1389,10 +1413,15 @@ Int_t AliTPCtrackerMI::FollowToNext(AliTPCseed& t, Int_t nr) {
       }    
     }
   }
-  if (fIteration>1) return 0;  // not look for new cluster during refitting
+  if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0;  // cut on angle
+  if (fIteration>1){
+    // not look for new cluster during refitting    
+    t.fNFoundable++; 
+    return 0;
+  }
   //
   UInt_t index=0;
-  if (TMath::Abs(t.GetSnp())>0.95 || TMath::Abs(x*t.GetC()-t.GetEta())>0.95) return 0;
+  //  if (TMath::Abs(t.GetSnp())>0.95 || TMath::Abs(x*t.GetC()-t.GetEta())>0.95) return 0;// patch 28 fev 06
   Double_t  y=t.GetYat(x);
   if (TMath::Abs(y)>ymax){
     if (y > ymax) {
@@ -1414,6 +1443,16 @@ Int_t AliTPCtrackerMI::FollowToNext(AliTPCseed& t, Int_t nr) {
   y=t.GetY(); 
   Double_t z=t.GetZ();
   //
+  if (!IsActive(t.fRelativeSector,nr)) {
+    t.fInDead = kTRUE;
+    t.SetClusterIndex2(nr,-1); 
+    return 0;
+  }
+  //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
+  Bool_t isActive  = IsActive(t.fRelativeSector,nr);
+  Bool_t isActive2 = (nr>=fInnerSec->GetNRows()) ? fOuterSec[t.fRelativeSector][nr-fInnerSec->GetNRows()].GetN()>0:fInnerSec[t.fRelativeSector][nr].GetN()>0;
+  
+  if (!isActive || !isActive2) return 0;
   const AliTPCRow &krow=GetRow(t.fRelativeSector,nr);
   if ( (t.GetSigmaY2()<0) || t.GetSigmaZ2()<0) return 0;
   Double_t  roady  =1.;
@@ -1426,7 +1465,8 @@ Int_t AliTPCtrackerMI::FollowToNext(AliTPCseed& t, Int_t nr) {
   } 
   else
     {
-      if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*x+10) && TMath::Abs(z)<fParam->GetZLength() ) t.fNFoundable++;
+      if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*x+10) && TMath::Abs(z)<fParam->GetZLength() && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker())) 
+       t.fNFoundable++;
       else
        return 0;
     }   
@@ -1547,6 +1587,53 @@ Int_t AliTPCtrackerMI::FollowToNextFast(AliTPCseed& t, Int_t nr) {
 
 
 
+//_________________________________________________________________________
+Bool_t AliTPCtrackerMI::GetTrackPoint(Int_t index, AliTrackPoint &p ) const
+{
+  // Get track space point by index
+  // return false in case the cluster doesn't exist
+  AliTPCclusterMI *cl = GetClusterMI(index);
+  if (!cl) return kFALSE;
+  Int_t sector = (index&0xff000000)>>24;
+  //  Int_t row = (index&0x00ff0000)>>16;
+  Float_t xyz[3];
+  //  xyz[0] = fParam->GetPadRowRadii(sector,row);
+  xyz[0] = cl->GetX();
+  xyz[1] = cl->GetY();
+  xyz[2] = cl->GetZ();
+  Float_t sin,cos;
+  fParam->AdjustCosSin(sector,cos,sin);
+  Float_t x = cos*xyz[0]-sin*xyz[1];
+  Float_t y = cos*xyz[1]+sin*xyz[0];
+  Float_t cov[6];
+  Float_t sigmaY2 = 0.027*cl->GetSigmaY2();
+  if (sector < fParam->GetNInnerSector()) sigmaY2 *= 2.07;
+  Float_t sigmaZ2 = 0.066*cl->GetSigmaZ2();
+  if (sector < fParam->GetNInnerSector()) sigmaZ2 *= 1.77;
+  cov[0] = sin*sin*sigmaY2;
+  cov[1] = -sin*cos*sigmaY2;
+  cov[2] = 0.;
+  cov[3] = cos*cos*sigmaY2;
+  cov[4] = 0.;
+  cov[5] = sigmaZ2;
+  p.SetXYZ(x,y,xyz[2],cov);
+  AliAlignObj::ELayerID iLayer;
+  Int_t idet;
+  if (sector < fParam->GetNInnerSector()) {
+    iLayer = AliAlignObj::kTPC1;
+    idet = sector;
+  }
+  else {
+    iLayer = AliAlignObj::kTPC2;
+    idet = sector - fParam->GetNInnerSector();
+  }
+  UShort_t volid = AliAlignObj::LayerToVolUID(iLayer,idet);
+  p.SetVolumeID(volid);
+  return kTRUE;
+}
+
+
+
 Int_t AliTPCtrackerMI::UpdateClusters(AliTPCseed& t,  Int_t nr) {
   //-----------------------------------------------------------------
   // This function tries to find a track prolongation to next pad row
@@ -1559,14 +1646,14 @@ Int_t AliTPCtrackerMI::UpdateClusters(AliTPCseed& t,  Int_t nr) {
   Double_t  ymax= GetMaxY(nr);
 
   if (row < nr) return 1; // don't prolongate if not information until now -
-  if (TMath::Abs(t.GetSnp())>0.9 && t.GetNumberOfClusters()>40. && fIteration!=2) {
-    t.fRemoval =10;
-    return 0;  // not prolongate strongly inclined tracks
-  } 
-  if (TMath::Abs(t.GetSnp())>0.95) {
-    t.fRemoval =10;
-    return 0;  // not prolongate strongly inclined tracks
-  }
+//   if (TMath::Abs(t.GetSnp())>0.9 && t.GetNumberOfClusters()>40. && fIteration!=2) {
+//     t.fRemoval =10;
+//     return 0;  // not prolongate strongly inclined tracks
+//   } 
+//   if (TMath::Abs(t.GetSnp())>0.95) {
+//     t.fRemoval =10;
+//     return 0;  // not prolongate strongly inclined tracks
+//   }// patch 28 fev 06
 
   Double_t x= GetXrow(nr);
   Double_t y,z;
@@ -1596,7 +1683,13 @@ Int_t AliTPCtrackerMI::UpdateClusters(AliTPCseed& t,  Int_t nr) {
     //y = t.GetY();    
   }
   //
-
+  if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0;
+  if (!IsActive(t.fRelativeSector,nr)) {
+    t.fInDead = kTRUE;
+    t.SetClusterIndex2(nr,-1); 
+    return 0;
+  }
+  //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
   AliTPCRow &krow=GetRow(t.fRelativeSector,nr);
 
   if (TMath::Abs(TMath::Abs(y)-ymax)<krow.fDeadZone){
@@ -1606,7 +1699,7 @@ Int_t AliTPCtrackerMI::UpdateClusters(AliTPCseed& t,  Int_t nr) {
   } 
   else
     {
-      if (TMath::Abs(t.GetZ())<(AliTPCReconstructor::GetCtgRange()*t.GetX()+10)) t.fNFoundable++;
+      if (TMath::Abs(t.GetZ())<(AliTPCReconstructor::GetCtgRange()*t.GetX()+10) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker())) t.fNFoundable++;
       else
        return 0;      
     }
@@ -1784,7 +1877,7 @@ Int_t AliTPCtrackerMI::FollowBackProlongation(AliTPCseed& t, Int_t rf) {
   //
   if (first<0) first=0;
   for (Int_t nr=first; nr<=rf; nr++) {
-    if ( (TMath::Abs(t.GetSnp())>0.95)) break;
+    //    if ( (TMath::Abs(t.GetSnp())>0.95)) break;//patch 28 fev 06
     if (t.GetKinkIndexes()[0]<0){
       for (Int_t i=0;i<3;i++){
        Int_t index = t.GetKinkIndexes()[i];
@@ -2186,21 +2279,28 @@ void AliTPCtrackerMI::RemoveUsed2(TObjArray * arr, Float_t factor1,  Float_t fac
     Int_t found,foundable,shared;
     pt->GetClusterStatistic(first,last, found, foundable,shared,kFALSE);
     Float_t sharedfactor = Float_t(shared+1)/Float_t(found+1);
-    //
-    if (Float_t(shared+1)/Float_t(found+1)>factor){
-      if (pt->GetKinkIndexes()[0]!=0) continue;  //don't remove tracks  - part of the kinks
-      delete arr->RemoveAt(trackindex);
-      continue;
+    Bool_t itsgold =kFALSE;
+    if (pt->fEsd){
+      Int_t dummy[12];
+      if (pt->fEsd->GetITSclusters(dummy)>4) itsgold= kTRUE;
     }
-
-    if (pt->GetNumberOfClusters()<50&&(found-0.5*shared)<minimal){  //remove short tracks
-      if (pt->GetKinkIndexes()[0]!=0) continue;  //don't remove tracks  - part of the kinks
-      delete arr->RemoveAt(trackindex);
-      continue;
+    if (!itsgold){
+      //
+      if (Float_t(shared+1)/Float_t(found+1)>factor){
+       if (pt->GetKinkIndexes()[0]!=0) continue;  //don't remove tracks  - part of the kinks
+       delete arr->RemoveAt(trackindex);
+       continue;
+      }      
+      if (pt->GetNumberOfClusters()<50&&(found-0.5*shared)<minimal){  //remove short tracks
+       if (pt->GetKinkIndexes()[0]!=0) continue;  //don't remove tracks  - part of the kinks
+       delete arr->RemoveAt(trackindex);
+       continue;
+      }
     }
 
     good++;
     if (sharedfactor>0.4) continue;
+    if (pt->GetKinkIndexes()[0]>0) continue;
     for (Int_t i=first; i<last; i++) {
       Int_t index=pt->GetClusterIndex2(i);
       // if (index<0 || index&0x8000 ) continue;
@@ -2476,6 +2576,7 @@ Int_t AliTPCtrackerMI::RefitInward(AliESD *event)
   fIteration=2;
   //PrepareForProlongation(fSeeds,1);
   PropagateForward2(fSeeds);
+
   Int_t ntracks=0;
   Int_t nseed = fSeeds->GetEntriesFast();
   for (Int_t i=0;i<nseed;i++){
@@ -2488,9 +2589,29 @@ Int_t AliTPCtrackerMI::RefitInward(AliESD *event)
     AliESDtrack *esd=event->GetTrack(i);
     seed->CookdEdx(0.02,0.6);
     CookLabel(seed,0.1); //For comparison only
+    //
+    if (AliTPCReconstructor::StreamLevel()>0 && seed!=0&&esd!=0) {
+      TTreeSRedirector &cstream = *fDebugStreamer;
+      cstream<<"Crefit"<<
+       "Esd.="<<esd<<
+       "Track.="<<seed<<
+       "\n"; 
+    }
     if (seed->GetNumberOfClusters()>15){
       esd->UpdateTrackParams(seed,AliESDtrack::kTPCrefit); 
       esd->SetTPCPoints(seed->GetPoints());
+      esd->SetTPCPointsF(seed->fNFoundable);
+      Int_t ndedx   = seed->fNCDEDX[0]+seed->fNCDEDX[1]+seed->fNCDEDX[2]+seed->fNCDEDX[3];
+      Float_t sdedx = (seed->fSDEDX[0]+seed->fSDEDX[1]+seed->fSDEDX[2]+seed->fSDEDX[3])*0.25;
+      Float_t dedx  = seed->GetdEdx();
+      esd->SetTPCsignal(dedx, sdedx, ndedx);
+      //
+      // add seed to the esd track in Calib level
+      //
+      if (AliTPCReconstructor::StreamLevel()>0){
+       AliTPCseed * seedCopy = new AliTPCseed(*seed, kTRUE); 
+       esd->AddCalibObject(seedCopy);
+      }
       ntracks++;
     }
     else{
@@ -2513,8 +2634,10 @@ Int_t AliTPCtrackerMI::PropagateBack(AliESD *event)
 
   fEvent = event;
   fIteration = 1;
-  ReadSeeds(event,0);
-  PropagateBack(fSeeds);
+  ReadSeeds(event,1);
+  PropagateBack(fSeeds); 
+  RemoveUsed2(fSeeds,0.4,0.4,20);
+  //
   Int_t nseed = fSeeds->GetEntriesFast();
   Int_t ntracks=0;
   for (Int_t i=0;i<nseed;i++){
@@ -2528,7 +2651,17 @@ Int_t AliTPCtrackerMI::PropagateBack(AliESD *event)
     if (seed->GetNumberOfClusters()>15){
       esd->UpdateTrackParams(seed,AliESDtrack::kTPCout);
       esd->SetTPCPoints(seed->GetPoints());
+      esd->SetTPCPointsF(seed->fNFoundable);
+      Int_t ndedx   = seed->fNCDEDX[0]+seed->fNCDEDX[1]+seed->fNCDEDX[2]+seed->fNCDEDX[3];
+      Float_t sdedx = (seed->fSDEDX[0]+seed->fSDEDX[1]+seed->fSDEDX[2]+seed->fSDEDX[3])*0.25;
+      Float_t dedx  = seed->GetdEdx();
+      esd->SetTPCsignal(dedx, sdedx, ndedx);
       ntracks++;
+      Int_t eventnumber = event->GetEventNumber();// patch 28 fev 06
+      (*fDebugStreamer)<<"Cback"<<
+       "Tr0.="<<seed<<
+       "EventNr="<<eventnumber<<
+       "\n"; // patch 28 fev 06   
     }
   }
   //FindKinks(fSeeds,event);
@@ -2573,6 +2706,7 @@ void AliTPCtrackerMI::ReadSeeds(AliESD *event, Int_t direction)
     ULong_t status=esd->GetStatus();
     if (!(status&AliESDtrack::kTPCin)) continue;
     AliTPCtrack t(*esd);
+    t.SetNumberOfClusters(0);
     //    AliTPCseed *seed = new AliTPCseed(t,t.GetAlpha());
     AliTPCseed *seed = new AliTPCseed(t/*,t.GetAlpha()*/);
     for (Int_t ikink=0;ikink<3;ikink++) {
@@ -2591,7 +2725,7 @@ void AliTPCtrackerMI::ReadSeeds(AliESD *event, Int_t direction)
       }
 
     }
-    if ((status==AliESDtrack::kTPCin)&&(direction==1)) seed->ResetCovariance(); 
+    if (((status&AliESDtrack::kITSout)==0)&&(direction==1)) seed->ResetCovariance(); 
     if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) == 0 ) seed->ResetCovariance();
     if ( direction ==2 && ((status & AliESDtrack::kTPCout) == 0) ) {
       fSeeds->AddAt(0,i);
@@ -2599,8 +2733,8 @@ void AliTPCtrackerMI::ReadSeeds(AliESD *event, Int_t direction)
       continue;    
     }
     if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) > 0 )  {
-      Double_t par0[5],par1[5],x;
-      esd->GetInnerExternalParameters(x,par0);
+      Double_t par0[5],par1[5],alpha,x;
+      esd->GetInnerExternalParameters(alpha,x,par0);
       esd->GetExternalParameters(x,par1);
       Double_t delta1 = TMath::Abs(par0[4]-par1[4])/(0.000000001+TMath::Abs(par0[4]+par1[4]));
       Double_t delta2 = TMath::Abs(par0[3]-par1[3]);
@@ -2630,20 +2764,22 @@ void AliTPCtrackerMI::ReadSeeds(AliESD *event, Int_t direction)
     }
     seed->fEsd = esd;
     // sign clusters
-    for (Int_t irow=0;irow<160;irow++){
-      Int_t index = seed->GetClusterIndex2(irow);    
-      if (index>0){ 
-       //
-       AliTPCclusterMI * cl = GetClusterMI(index);
-       seed->fClusterPointer[irow] = cl;
-       if (cl){
-         if ((index & 0x8000)==0){
-           cl->Use(10);  // accepted cluster     
+    if (esd->GetKinkIndex(0)<=0){
+      for (Int_t irow=0;irow<160;irow++){
+       Int_t index = seed->GetClusterIndex2(irow);    
+       if (index>0){ 
+         //
+         AliTPCclusterMI * cl = GetClusterMI(index);
+         seed->fClusterPointer[irow] = cl;
+         if (cl){
+           if ((index & 0x8000)==0){
+             cl->Use(10);  // accepted cluster   
+           }else{
+             cl->Use(6);   // close cluster not accepted
+           }   
          }else{
-           cl->Use(6);   // close cluster not accepted
-         }     
-       }else{
-          Info("ReadSeeds","Not found cluster");
+           Info("ReadSeeds","Not found cluster");
+         }
        }
       }
     }
@@ -4044,8 +4180,8 @@ void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
            track0->fCircular += 2;
          }
        }               
-       if (sign){        
-         //debug stream
+       if (sign&&AliTPCReconstructor::StreamLevel()>1){          
+         //debug stream          
          cstream<<"Curling"<<
            "lab0="<<track0->fLab<<
            "lab1="<<track1->fLab<<   
@@ -4183,7 +4319,7 @@ void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
       if (TMath::Abs(ktrack0->GetC())>5) continue; // cut on the curvature for mother particle
       AliExternalTrackParam paramm(*ktrack0);
       AliExternalTrackParam paramd(*ktrack1);
-      if (row0>60&&ktrack1->GetReference().X()>90.) new (&paramd) AliExternalTrackParam(ktrack1->GetReference()); 
+      if (row0>60&&ktrack1->GetReference().GetX()>90.) new (&paramd) AliExternalTrackParam(ktrack1->GetReference()); 
       //
       //
       kink->SetMother(paramm);
@@ -4486,6 +4622,7 @@ void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
     }
     if (Float_t(shared+1)/Float_t(nall+1)>0.5) {
       delete array->RemoveAt(i);
+      continue;
     }
     //
     if (track0->fKinkIndexes[0]!=0) continue;
@@ -4659,18 +4796,20 @@ void  AliTPCtrackerMI::FindV0s(TObjArray * array, AliESD *esd)
     if (sign[i]==0) continue;
     AliTPCseed * track0 = (AliTPCseed*)array->At(i);
     if (!track0) continue;
-    cstream<<"Tracks"<<
-      "Tr0.="<<track0<<
-      "dca="<<dca[i]<<
-      "z0="<<z0[i]<<
-      "zvertex="<<zvertex<<
-      "sdcar0="<<sdcar[i]<<
-      "cdcar0="<<cdcar[i]<<
-      "pulldcar0="<<pulldcar[i]<<
-      "pulldcaz0="<<pulldcaz[i]<<
-      "pulldca0="<<pulldca[i]<<
-      "isPrim="<<isPrim[i]<<
-      "\n";
+    if (AliTPCReconstructor::StreamLevel()>0){
+      cstream<<"Tracks"<<
+       "Tr0.="<<track0<<
+       "dca="<<dca[i]<<
+       "z0="<<z0[i]<<
+       "zvertex="<<zvertex<<
+       "sdcar0="<<sdcar[i]<<
+       "cdcar0="<<cdcar[i]<<
+       "pulldcar0="<<pulldcar[i]<<
+       "pulldcaz0="<<pulldcaz[i]<<
+       "pulldca0="<<pulldca[i]<<
+       "isPrim="<<isPrim[i]<<
+       "\n";
+    }
     //
     if (track0->fP4<0) continue;
     if (track0->GetKinkIndex(0)>0||isPrim[i]) continue;   //daughter kink
@@ -4762,7 +4901,8 @@ void  AliTPCtrackerMI::FindV0s(TObjArray * array, AliESD *esd)
        Int_t eventNr = esd->GetEventNumber();
        Double_t radiusm= (delta[0]<delta[1])? TMath::Sqrt(radius[0]):TMath::Sqrt(radius[1]);  
        Double_t deltam= (delta[0]<delta[1])? TMath::Sqrt(delta[0]):TMath::Sqrt(delta[1]);  
-       cstream<<"V0"<<
+       if (AliTPCReconstructor::StreamLevel()>0)
+         cstream<<"V0"<<
          "Event="<<eventNr<<
          "vertex.="<<&vertex<<
          "Tr0.="<<track0<<
@@ -4863,7 +5003,8 @@ void  AliTPCtrackerMI::FindV0s(TObjArray * array, AliESD *esd)
     }
     {
       Int_t eventNr = esd->GetEventNumber();
-      cstream<<"V02"<<
+      if (AliTPCReconstructor::StreamLevel()>0)
+       cstream<<"V02"<<
        "Event="<<eventNr<<
        "vertex.="<<v0<<        
        "vertex2.="<<v02<<
@@ -5318,7 +5459,7 @@ Int_t AliTPCtrackerMI::Clusters2Tracks() {
   }
   //
   RemoveUsed2(fSeeds,0.85,0.85,0);
-  FindKinks(fSeeds,fEvent);
+  if (AliTPCReconstructor::GetRecoParam()->GetDoKinks()) FindKinks(fSeeds,fEvent);
   RemoveUsed2(fSeeds,0.5,0.4,20);
  //  //
 //   // refit short tracks
@@ -5516,6 +5657,7 @@ TObjArray * AliTPCtrackerMI::Tracking()
 {
   //
   //
+  if (AliTPCReconstructor::GetRecoParam()->GetSpecialSeeding()) return TrackingSpecial();
   TStopwatch timer;
   timer.Start();
   Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
@@ -5666,6 +5808,49 @@ TObjArray * AliTPCtrackerMI::Tracking()
 }
 
 
+TObjArray * AliTPCtrackerMI::TrackingSpecial()
+{
+  //
+  // seeding adjusted for laser and cosmic tests - short tracks with big inclination angle
+  // no primary vertex seeding tried
+  //
+  TStopwatch timer;
+  timer.Start();
+  Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
+
+  TObjArray * seeds = new TObjArray;
+  TObjArray * arr=0;
+  
+  Int_t   gap  = 15;
+  Float_t cuts[4];
+  Float_t fnumber  = 3.0;
+  Float_t fdensity = 3.0;
+  
+  // find secondaries
+  cuts[0] = AliTPCReconstructor::GetRecoParam()->GetMaxC();   // max curvature
+  cuts[1] = 3.5;    // max tan(phi) angle for seeding
+  cuts[2] = 3.;     // not used (cut on z primary vertex)     
+  cuts[3] = 3.5;    // max tan(theta) angle for seeding
+
+  for (Int_t delta = 0; nup-delta-gap-1>0; delta+=3){
+    //
+    arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
+    SumTracks(seeds,arr);   
+    SignClusters(seeds,fnumber,fdensity);   
+  } 
+  if (fDebug>0){
+    Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
+    timer.Print();
+    timer.Start();
+  }
+
+  return seeds;
+  //
+      
+}
+
+
 void AliTPCtrackerMI::SumTracks(TObjArray *arr1,TObjArray *arr2) const
 {
   //
@@ -5675,7 +5860,18 @@ void AliTPCtrackerMI::SumTracks(TObjArray *arr1,TObjArray *arr2) const
   for (Int_t i=0;i<nseed;i++){
     AliTPCseed *pt=(AliTPCseed*)arr2->UncheckedAt(i);    
     if (pt){
-      
+      //
+      // remove tracks with too big curvature
+      //
+      if (TMath::Abs(pt->GetC())>AliTPCReconstructor::GetRecoParam()->GetMaxC()){
+       delete arr2->RemoveAt(i);
+       continue;
+      }
+       // REMOVE VERY SHORT  TRACKS
+      if (pt->GetNumberOfClusters()<20){ 
+       delete arr2->RemoveAt(i);
+       continue;
+      }// patch 28 fev06
       // NORMAL ACTIVE TRACK
       if (pt->IsActive()){
        arr1->AddLast(arr2->RemoveAt(i));
@@ -5686,11 +5882,7 @@ void AliTPCtrackerMI::SumTracks(TObjArray *arr1,TObjArray *arr2) const
        delete arr2->RemoveAt(i);
        continue;
       }
-      // REMOVE VERY SHORT  TRACKS
-      if (pt->GetNumberOfClusters()<20){ 
-       delete arr2->RemoveAt(i);
-       continue;
-      }
+     
       // ENABLE ONLY ENOUGH GOOD STOPPED TRACKS
       if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
        arr1->AddLast(arr2->RemoveAt(i));
@@ -5929,7 +6121,7 @@ void  AliTPCtrackerMI::GetShape(AliTPCseed * seed, Int_t row)
   Float_t padlength =  GetPadPitchLength(row);
   //
   Float_t sresy = (seed->fSector < fParam->GetNSector()/2) ? 0.2 :0.3;
-  Float_t angulary  = seed->GetSnp();
+  Double_t angulary  = seed->GetSnp();
   angulary = angulary*angulary/(1-angulary*angulary);
   seed->fCurrentSigmaY2 = sd2+padlength*padlength*angulary/12.+sresy*sresy;  
   //
@@ -5976,10 +6168,11 @@ Float_t  AliTPCtrackerMI::GetSigmaZ(AliTPCseed * seed)
 
 
 //__________________________________________________________________________
-void AliTPCtrackerMI::CookLabel(AliTPCseed *t, Float_t wrong) const {
+void AliTPCtrackerMI::CookLabel(AliKalmanTrack *tk, Float_t wrong) const {
   //--------------------------------------------------------------------
   //This function "cooks" a track label. If label<0, this track is fake.
   //--------------------------------------------------------------------
+  AliTPCseed * t = (AliTPCseed*)tk;
   Int_t noc=t->GetNumberOfClusters();
   if (noc<10){
     //printf("\nnot founded prolongation\n\n\n");
@@ -6303,10 +6496,16 @@ AliTPCclusterMI * AliTPCtrackerMI::AliTPCRow::FindNearest2(Double_t y, Double_t
   // Return the index of the nearest cluster in z y 
   //-----------------------------------------------------------------------
   Float_t maxdistance = roady*roady + roadz*roadz;
-  Int_t iz1 = TMath::Max(fFastCluster[Int_t(z-roadz+254.5)]-1,0);
-  Int_t iz2 = TMath::Min(fFastCluster[Int_t(z+roadz+255.5)]+1,fN);
-
   AliTPCclusterMI *cl =0;
+
+  //PH Check boundaries. 510 is the size of fFastCluster
+  Int_t iz1 = Int_t(z-roadz+254.5);
+  if (iz1<0 || iz1>=510) return cl;
+  iz1 = TMath::Max(fFastCluster[iz1]-1,0);
+  Int_t iz2 = Int_t(z+roadz+255.5);
+  if (iz2<0 || iz2>=510) return cl;
+  iz2 = TMath::Min(fFastCluster[iz2]+1,fN);
+
   //FindNearest3(y,z,roady,roadz,index);
   //  for (Int_t i=Find(z-roadz); i<fN; i++) {
   for (Int_t i=iz1; i<iz2; i++) {